Cannot mimic the action of 'echo' with C


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Cannot mimic the action of 'echo' with C
# 1  
Old 02-20-2015
Cannot mimic the action of 'echo' with C

I realise this is not entirely a shell question because it involves the C language but it centers around a Bash script I have written.

I have written a couple of bash script files that communicate via two serial ports. One script can be thought of as a receiver and the other as a transmitter. The receiving script reads and displays data line by line until it reads the character sequence <break>. It then stops listening, and sends a character sequence of either one or two back to the transmitter. The script is thus:

Code:
#!/bin/bash

# Read and reply bash script.

exec 3<> /dev/ttyS4
while true; do
    #cat -v /dev/ttyS4 | while read -r input; do
    while read -r -u 3 input; do
        if [ "$input" = "<break>" ]
        then
            echo "break command received."
            break
        else
            echo -e "${input}"
        fi
    done 

    echo "Sending selection"
    if [ "$selection" = "one" ]
    then
        selection="two"
    else
        selection="one"
    fi
    echo "$selection" >&3

done



The transmitter script transmits some character data and then waits for the reply of one or two from the receiver script above:

Code:
exec 4<> /dev/ttyS0
selection="one"
while true; do
    echo "************************************" > /dev/ttyS0
    echo "       Selection: ${selection}" > /dev/ttyS0
    echo "************************************" > /dev/ttyS0
    echo "<break>" > /dev/ttyS0
    read -r -t 3 -u 4 input
    if [ -z "$input" ]
    then
        echo "Response from remote timed out."
    elif [ "$input" = "one" ]
    then
        selection=$input
    elif [ "$input" = "two" ]
    then
        selection=$input
        colour=$RED
    else
        echo "Unknown selection: $input"
    fi

    sleep 1 
done




The above two scripts work fine and the receiver script correctly identifies the <break> character sequence.

I wish to replace the 'transmitter' script with a small C program however I find that when I send the character sequence <break> the receiver script this time does NOT identify is as the 'end-of-transmission', is simple echos <break> to stdout, and NOT break command received. I have tried several things such as adding escape characters but there is obviously something different about the way Bash echo works and how I send the data in my C code:

Code:
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>

#define TRUE 1
#define FALSE 0

int main(int argc, char *argv[]) {
    int selected_tool = DEFAULT_TOOL_SELECTION;
    FILE *ser2_fd_write, *ser2_fdrw;
    struct termios tios, tios_w;        // ser 2 termios structure
    int ser2_fd, ser2_fdw;
    char read_buffer[BUFFER_SIZE];
    struct timespec tdelay;

    bzero(&tdelay, sizeof(tdelay));
    tdelay.tv_sec = 1;
    tdelay.tv_nsec = 5000;

    if ((ser2_fd = open("/dev/ttyS0", O_RDWR)) == -1){
        printf("Unable to open ttyS0 as read-write only.\n");
        return EXIT_FAILURE;
    }

    bzero(&tios, sizeof(tios));
    cfsetispeed(&tios, B38400);
    cfsetospeed(&tios, B38400);


    tios.c_cflag = B38400 | CS8 | CLOCAL | CREAD | CRTSCTS;
    tios.c_iflag = IGNPAR;
    tios.c_oflag = 0;
    tios.c_lflag = ICANON; //0
    tios.c_cc[VTIME] = 0;
    tios.c_cc[VMIN] = 10;

    tcflush(ser2_fd, TCIFLUSH);
    if (tcsetattr(ser2_fd, TCSANOW, &tios) == -1){
        printf("Could not set ser 2 attributes.\n");
        return -1;
    }

    if ((ser2_fdrw = fdopen(ser2_fd, "awr")) == NULL){
        printf("Unable to open file descriptor.\n");
        return EXIT_FAILURE;
    }

while(1){

    push_to_ser2(ser2_fdrw, selected_tool);
    /*
     * This is where sending <break> differs from echo
     */

    //fputs("break", ser2_fdrw);
    fprintf(ser2_fdrw, "break\r\n");
    //fprintf(ser2_fdrw, "\r\n");
    //write(ser2_fd,"break\r\n", 9);
    fflush(ser2_fdrw);
    int c = 0;

    nanosleep(&tdelay, NULL);
    tcflush(ser2_fd, TCIOFLUSH);
    tcdrain(ser2_fd);
    fcntl(ser2_fd, F_SETFL, 0);

    if ( (c = read(ser2_fd, read_buffer, BUFFER_SIZE)) > 0){
        read_buffer[c] = 0;
        if (strcmp(read_buffer, "one\r\n") == 0){
            selected_tool = 1;
        } else if (strcmp(read_buffer, "two\r\n") == 0){
            selected_tool = 2;
        }
    }else{

    }
}
    return EXIT_SUCCESS;
}


/*
 * Convenience function to push data to ser 2
 * *c_data      pointer to the card data
 * *t_data      pointer to the tool data
 */
void push_to_ser2(FILE * fd, int tool){

    fprintf(fd, "**********************************************************\n");
    fprintf(fd, "*                                                        *\n");
    fprintf(fd, "*                     Tool %d Data                       *\n", tool);
    fprintf(fd, "*                                                        *\n");
    fprintf(fd, "**********************************************************\n");


    fprintf(fd,"\r\n");
    fflush(fd);
}



I've tried various alterations to the termios struct too but it makes no difference and I also wonder it the re-direct may have something to do with it. Any suggestions?
# 2  
Old 02-20-2015
One difference seems to be that the C transmitter writes:
Code:
BREAK<CR>

where <CR> stands for a CR character,

whereas the bash script tests for
Code:
<BREAK>


Last edited by Scrutinizer; 02-20-2015 at 10:24 PM..
# 3  
Old 02-22-2015
I realised that the C code didn't quite match what I was trying to achieve in that it was sending "break" and not <break>. This was as a result of me trying various things and the bash script I pasted was out-of-sync with the C code.

It did turn out to be a carriage-return and line-feed issue and was to do with the way I had set up the serial ports. Issue is now resolved.
# 4  
Old 02-23-2015
Thanks for updating us.
Login or Register to Ask a Question

Previous Thread | Next Thread

7 More Discussions You Might Find Interesting

1. IP Networking

Add trusted sites / "Mimic" the IE Security tab on Linux Ubuntu

Hello, I'm new here and although I have used Linux environments here and there for many years (mainly at college) I'm far from being a "pro". I spent hours searching this question, so I hope I won't repeat threads (chances are low though). The question is: how can I mimic or replicate the... (0 Replies)
Discussion started by: AirieFenix
0 Replies

2. Shell Programming and Scripting

multiple action!

lets explain it easy by showing the initial file and desired file: I've a file such this that contains: initial_file: 31/12/2011 23:46:08 38.6762 43.689 14.16 Ml 3.1 ... (1 Reply)
Discussion started by: oreka18
1 Replies

3. Shell Programming and Scripting

Need help with find its action

I am writing a shell script that takes at least 2 arguments. The first is an octal representation of file permissions, the second is a command that is executed on all the files found with that permission. #!/bin/sh find . -perm $1 -exec $2 $3 $4 {} \; invoked: ./script.sh 543 ls -la what... (3 Replies)
Discussion started by: computethis
3 Replies

4. Shell Programming and Scripting

same action in then as in else: explanation?

in /etc/init.d/networking of an ubuntu computer, I found this code: if ifdown -a --exclude=lo; then log_action_end_msg $? else log_action_end_msg $? fi Shouldn't it be replace by ifdown -a --exclude=lo ... (0 Replies)
Discussion started by: raphinou
0 Replies

5. UNIX for Dummies Questions & Answers

How to correctly use an echo inside an echo?

Bit of a weird one i suppose, i want to use an echo inside an echo... For example... i have a script that i want to use to take users input and create another script. Inside this script it creates it also needs to use echos... echo "echo "hello"" >$file echo "echo "goodbye"" >$file ... (3 Replies)
Discussion started by: mokachoka
3 Replies

6. Shell Programming and Scripting

Mimic bash history behavior

Does anyone know of a way to mimic the up arrow/down arrow type bash behavior within a shell script? Say I have a scripted menu, and would like to be able to up arrow to bring up the last X number of lines of user input? Thanks to anybody with a suggestion. :) (0 Replies)
Discussion started by: sysera
0 Replies

7. Shell Programming and Scripting

action command

Hi.. When i refered the script /etc/rc.sysinit... i found the "action commands" like But this is not working in my shells.. the following error is coming... Please anybody help Thanks in advance esham (5 Replies)
Discussion started by: esham
5 Replies
Login or Register to Ask a Question