int main(int ac, char *av[]) { //TODO extract the serial port codes into another source file, this is too ugly! uint16_t i, j, len; int16_t res=0, result=0; uint8_t destination_ip[32]; uint8_t outbuf[512]; uint8_t linebuf[32]; uint8_t local_filename[32]="\0"; FILE* sptr; if(ac == 1) usage(); //for(i=0; i<ac; i++) // printf("%s\n",av[i]); if(!strcmp("uhf", av[1])) { mode=RADIOTFTP_MODE_UHF; preamble_length=RADIOTFTP_BIM2A_PREAMBLE_LENGTH; baud=RADIOTFTP_BIM2A_BAUD_RATE; printf("Running with UHF band 19200 baud version\n"); openLogFile(RADIOTFTP_BIM2A_EVENTLOG); } else if(!strcmp("vhf", av[1])) { mode=RADIOTFTP_MODE_VHF; preamble_length=RADIOTFTP_UHX1_PREAMBLE_LENGTH; baud=RADIOTFTP_UHX1_BAUD_RATE; printf("Running with VHF band 2400 baud version\n"); openLogFile(RADIOTFTP_UHX1_EVENTLOG); } else if(!strcmp("serial", av[1])) { mode=RADIOTFTP_MODE_SERIAL; preamble_length=RADIOTFTP_SERIAL_PREAMBLE_LENGTH; baud=RADIOTFTP_SERIAL_BAUD_RATE; printf("Couldn't understand the uhf/vhf mode: using %d mode\n", mode); printf("Running with NO BAND %d baud version\n", baud); printf("Opening file %s for logging\n",RADIOTFTP_SERIAL_EVENTLOG); openLogFile(RADIOTFTP_SERIAL_EVENTLOG); } else { printf("Mode not entered, exiting...\n"); return 0; } //setting defaults udp_get_broadcast_ip(destination_ip); strcpy(dial_tty, "/dev/ttyUSB0"); //scanning command line parameters for(i=2; (i < ac) && (av[i][0] == '-'); i++) { if(strcmp(av[i], "-b") == 0) { background=1; } else if(strncmp(av[i], "-f", 2) == 0) { strncpy(local_filename, av[i] + 2, 32); printf("different filename = '%s'\n", local_filename); } else if(strncmp(av[i], "-dst", 4) == 0) { memset(destination_ip, 0, 32); memcpy(destination_ip, av[i] + 4, strlen(av[i]) - 4); /*! convert text ip to numerical */ text_to_ip(destination_ip, strlen(av[i]) - 4 + 1); printf("Destination: "); print_addr_dec(destination_ip); } else { printf("unknown parameter: %s\n", av[i]); usage(); } } res=0; result=0; strncpy(dial_tty, devtag_get(av[i]), sizeof(dial_tty)); while(!get_lock(dial_tty)) { if(decrementLockRetries() == 0) exit(-1); sleep(1); } if((serialportFd=open(devtag_get(av[i]), O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) { perror("bad terminal device, try another"); exit(-1); } signal(SIGIO, SIG_IGN); signal(SIGINT, sigINT_handler); // Make the file descriptor asynchronous (the manual page says only // O_APPEND and O_NONBLOCK, will work with F_SETFL...) fcntl(serialportFd, F_GETFL); fcntl(serialportFd, F_SETFL, O_RDWR | O_SYNC); if(tcgetattr(serialportFd, &tp) < 0) { perror("Couldn't get term attributes"); exit(-1); } old=tp; /* SANE is a composite flag that sets the following parameters from termio(M): CREAD BRKINT IGNPAR ISTRIP ICRNL IXON ISIG ICANON ECHO ECHOK OPOST ONLCR SANE also clears the following modes: CLOCAL IGNBRK PARMRK INPCK INLCR IUCLC IXOFF XCASE ECHOE ECHONL NOFLSH OLCUC OCRNL ONOCR ONLRET OFILL OFDEL NLDLY CRDLY TABDLY BSDLY VTDLY FFDLY */ /* 8 bits + baud rate + local control */ tp.c_cflag=baud | CS8 | CLOCAL | CREAD; tp.c_cflag&=~PARENB; tp.c_cflag&=~CSTOPB; tp.c_cflag&=~CSIZE; tp.c_cflag|=CS8; tp.c_cflag|=CRTSCTS; tp.c_oflag=0; /* Raw Input */ tp.c_lflag=0; /* No conoical */ tp.c_cc[VTIME]=0; tp.c_cc[VMIN]=1; /* ignore CR, ignore parity */ //ISTRIP is a dangerous flag, it strips the 8th bit of bytes //tp.c_iflag= ~( ISTRIP ) | IGNPAR | IGNBRK; tp.c_iflag=~(IGNBRK | PARMRK | INPCK | ISTRIP | INLCR | IUCLC | IXOFF) | BRKINT | IGNPAR | ICRNL | IXON | ISIG | ICANON; /* set output and input baud rates */ cfsetospeed(&tp, baud); cfsetispeed(&tp, baud); tcflush(serialportFd, TCIFLUSH); tcflush(serialportFd, TCOFLUSH); if(tcsetattr(serialportFd, TCSANOW, &tp) < 0) { perror("Couldn't set term attributes"); goto error; } restore=1; //TODO go over the background codes if(background) { int i; if(getppid() == 1) return 0; /* Already a daemon */ i=fork(); if(i < 0) exit(1); /* error */ if(i > 0) _exit(0); /* parent exits */ /* child */ setsid(); /* obtain a new process group */ for(i=getdtablesize(); i >= 0; --i) { if(i == serialportFd) continue; if(i == 1) continue; close(i); /* close all descriptors */ } i=open("/dev/null", O_RDWR); dup(i); dup(i); /* handle standard I/O */ umask(027); /* set newly created file permissions */ chdir("/"); /* change running directory */ } srand((unsigned) time(NULL)); j=0; i++; for(; i < ac; i++) { len=strlen(av[i]); memcpy(command_buffer + j, av[i], len); j+=len; if(i != ac - 1) { command_buffer[j++]=' '; } } //process the escape characters for(i=0; i < j; i++) { if(command_buffer[i] == '\\') { if(i + 1 < j) { if(command_buffer[i + 1] == 'n') { command_buffer[i]='\r'; command_buffer[i + 1]='\n'; } } } } timers_initialize(&sigRTALRM_handler); /*! read settings from radiotftp.conf file */ sptr=fopen("radiotftp.conf", "r"); if(sptr != NULL) { readnline(sptr, linebuf, 32); linebuf[6]=atoi(linebuf + 6); linebuf[8]=0; printf("AX.25 Callsign: "); print_callsign(linebuf); #if AX25_ENABLED==1 ax25_initialize_network(linebuf); printf("USING AX25 LINK LAYER!!!\n"); #else AX25_ENABLED==0 printf("NOT USING ANY LINK LAYER!!!\n"); #endif readnline(sptr, linebuf, 32); text_to_ip(linebuf, strlen(linebuf)); printf("IPv4 Address: "); print_addr_dec(linebuf); udp_initialize_ip_network(linebuf, &queueSerialData); } else { #if AX25_ENABLED==1 ax25_initialize_network(my_ax25_callsign); printf("AX.25 CALLSIGN = "); print_callsign(ax25_get_local_callsign(NULL)); #endif udp_initialize_ip_network(my_ip_address, &queueSerialData); printf("IPv4 Address = "); print_addr_dec(udp_get_localhost_ip(NULL)); } switch(mode) { case RADIOTFTP_MODE_UHF: tftp_initialize(udp_get_data_queuer_fptr(), RADIOTFTP_BIM2A_ACK_TIMEOUT_MIN, RADIOTFTP_BIM2A_ACK_TIMEOUT_MAX, RADIOTFTP_BIM2A_READ_TIMEOUT); break; case RADIOTFTP_MODE_VHF: tftp_initialize(udp_get_data_queuer_fptr(), RADIOTFTP_UHX1_ACK_TIMEOUT_MIN, RADIOTFTP_UHX1_ACK_TIMEOUT_MAX, RADIOTFTP_UHX1_READ_TIMEOUT); break; case RADIOTFTP_MODE_SERIAL: tftp_initialize(udp_get_data_queuer_fptr(), RADIOTFTP_SERIAL_ACK_TIMEOUT_MIN, RADIOTFTP_SERIAL_ACK_TIMEOUT_MAX, RADIOTFTP_SERIAL_READ_TIMEOUT); break; default: perror("unknown baud rate"); safe_exit(-1); break; } if(!strncasecmp(RADIOTFTP_COMMAND_PUT, command_buffer, strlen(RADIOTFTP_COMMAND_PUT))) { printf(RADIOTFTP_COMMAND_PUT"\n"); registerEvent(RADIOTFTP_COMMAND_PUT, command_buffer + strlen(RADIOTFTP_COMMAND_PUT) + 1); if((res=tftp_sendRequest(TFTP_OPCODE_WRQ, destination_ip, local_filename, command_buffer + strlen(RADIOTFTP_COMMAND_PUT) + 1, j - strlen(RADIOTFTP_COMMAND_PUT) - 1, 0))) { printf("%d\n", res); perror("tftp request fail"); goto error; } } else if(!strncasecmp(RADIOTFTP_COMMAND_BEACON, command_buffer, strlen(RADIOTFTP_COMMAND_BEACON))) { printf(RADIOTFTP_COMMAND_BEACON"\n"); registerEvent(RADIOTFTP_COMMAND_BEACON, command_buffer + strlen(RADIOTFTP_COMMAND_BEACON) + 1); if((res=tftp_sendSingleBlockData(destination_ip, command_buffer + strlen(RADIOTFTP_COMMAND_BEACON) + 1, j - strlen(RADIOTFTP_COMMAND_BEACON) - 1, local_filename))) { printf("%d\n", res); perror("tftp request fail"); goto error; } } else if(!strncasecmp(RADIOTFTP_COMMAND_APPEND_LINE, command_buffer, strlen(RADIOTFTP_COMMAND_APPEND_LINE))) { printf(RADIOTFTP_COMMAND_APPEND_LINE"\n"); registerEvent(RADIOTFTP_COMMAND_APPEND_LINE, command_buffer + strlen(RADIOTFTP_COMMAND_APPEND_LINE) + 1); i=createTempFile(TEMPFILE_PREFIX, TEMPFILE_POSTFIX); if(tempFile == NULL) { perror("couldn't create temp file to store the line feed"); goto error; } fwrite(command_buffer + strlen(RADIOTFTP_COMMAND_APPEND_LINE) + 1, 1, j - strlen(RADIOTFTP_COMMAND_APPEND_LINE) - 1, tempFile); fflush(tempFile); fclose(tempFile); printf("tempfileName=%s\nlocal_filename=%s\n", tempFileName, local_filename); if((res=tftp_sendRequest(TFTP_OPCODE_WRQ, destination_ip, tempFileName, local_filename, strlen(local_filename), 1))) { printf("%d\n", res); perror("tftp request fail"); goto error; } } else if(!strncasecmp(RADIOTFTP_COMMAND_APPEND_FILE, command_buffer, strlen(RADIOTFTP_COMMAND_APPEND_FILE))) { printf(RADIOTFTP_COMMAND_APPEND_FILE"\n"); registerEvent(RADIOTFTP_COMMAND_APPEND_FILE, command_buffer + strlen(RADIOTFTP_COMMAND_APPEND_FILE) + 1); if((res=tftp_sendRequest(TFTP_OPCODE_WRQ, destination_ip, local_filename, command_buffer + strlen(RADIOTFTP_COMMAND_APPEND_FILE) + 1, j - strlen(RADIOTFTP_COMMAND_APPEND_FILE) - 1, 1))) { printf("%d\n", res); perror("tftp request fail"); goto error; } } else if(!strncasecmp(RADIOTFTP_COMMAND_GET, command_buffer, strlen(RADIOTFTP_COMMAND_GET))) { printf(RADIOTFTP_COMMAND_GET"\n"); registerEvent(RADIOTFTP_COMMAND_GET, command_buffer + strlen(RADIOTFTP_COMMAND_GET) + 1); if((res=tftp_sendRequest(TFTP_OPCODE_RRQ, destination_ip, local_filename, command_buffer + strlen(RADIOTFTP_COMMAND_GET) + 1, j - strlen(RADIOTFTP_COMMAND_GET) - 1, 0))) { printf("%d\n", res); perror("tftp request fail"); goto error; } } else { printf("hello radio world!\n"); registerEvent("helloWorld", ""); if((res=queueSerialData(udp_get_localhost_ip(NULL), HELLO_WORLD_PORT, udp_get_broadcast_ip(NULL), HELLO_WORLD_PORT, "hello world\n\0x00", strlen("hello world\n\0x00")))) { printf("%d\n", res); perror("tftp request fail"); goto error; } } int sync_counter=0; int sync_passed=0; int save_index=0; //entering the main while loop printf("started listening...\n"); while(1) { if(timer_flag) { idle_timer_handler(); tftp_timer_handler(); timer_flag=0; } if(idle_flag) { //print_time("System Idle"); idle_flag=0; } if(queue_flag) { // printf("queue flag\n"); if(!sync_passed && sync_counter < 1) { //wait_some switch(mode) { case RADIOTFTP_MODE_UHF: usleep(RADIOTFTP_BIM2A_TX_MESSAGE_INTERVAL); break; case RADIOTFTP_MODE_VHF: usleep(RADIOTFTP_UHX1_TX_MESSAGE_INTERVAL); break; case RADIOTFTP_MODE_SERIAL: usleep(RADIOTFTP_SERIAL_TX_MESSAGE_INTERVAL); break; default: perror("unknown baud rate"); safe_exit(-1); break; } transmitSerialData(); queue_flag=0; } } if((res=read(serialportFd, io, IO_BUFSIZE)) > 0) { io_index=0; //printf("# of bytes read = %d\n", res); for(i=0; i < res; i++) { //putchar(io[i]); //printf("%\n",io[i]); if(sync_counter < SYNC_LENGTH && io[i] == syncword[sync_counter]) { sync_counter++; /* sync continued */ //printf("sync counting %d\n",sync_counter); } else { //printf("sync reset %d\n",sync_counter); sync_counter=0; /* not a preamble, reset counter */ } if(sync_counter >= SYNC_LENGTH && sync_passed == 0) { /* preamble passed */ sync_passed=1; } if(sync_passed) { //printf("getting data '%c'\n", io[i]); if(io[i] == END_OF_FILE && !isManchester_encoded(io[i])) { // printf("non-manchester character received\n"); outbuf[0]=0; result=manchester_decode(buf + 1, manchester_buffer, save_index); #if AX25_ENABLED==1 result=ax25_open_ui_packet(NULL, NULL, ax25_buffer, manchester_buffer, result); #else result=1; #endif if(result) { // printf("opened link-layer packet\n"); #if AX25_ENABLED==1 result=udp_open_packet(udp_src, &udp_src_prt, udp_dst, &udp_dst_prt, udp_buffer, ax25_buffer); #else result = udp_open_packet(udp_src, &udp_src_prt, udp_dst, &udp_dst_prt, udp_buffer, manchester_buffer); #endif if(result) { // printf("opened transport-layer packet\n"); udp_packet_demultiplexer(udp_src, udp_src_prt, udp_dst, udp_dst_prt, udp_buffer, result); } else { strcat(outbuf, "!udp discarded!"); if(write(1, outbuf, strlen(outbuf)) <= 0) { fputs("couldn't write to tty\n", stderr); } if(write(1, "\n", 1) <= 0) { fputs("couldn't write to tty\n", stderr); } } } else { strcat(outbuf, "!ax25 discarded!"); if(write(1, outbuf, strlen(outbuf)) <= 0) { fputs("couldn't write to tty\n", stderr); } if(write(1, "\n", 1) <= 0) { fputs("couldn't write to tty\n", stderr); } } sync_passed=0; sync_counter=0; save_index=0; } else { // printf("saved data '%c'\n", io[i]); // printf("save_index=%d/%d\n",save_index, sizeof(buf)); if(save_index >= sizeof(buf)) { sync_passed=0; sync_counter=0; save_index=0; } buf[save_index++]=io[i]; buf[save_index + 1]=0; // printf("-\n%s\n-\n", buf); } } } io_flag=0; } } safe_exit(0); error: safe_exit(-1); return -2; }
int main(int ac, char *av[]) { struct termios tp, old; int usb_fd; int file_fd; char io[BUFSIZ]; char buf[2*BUFSIZ]; char *filename = NULL; char *reportpath = NULL; int res; int i, done, len; char *prog = basename (av[0]); int rc, on = 1; int listen_sd = -1, new_sd = -1; int compress_array = FALSE; int close_conn; char buffer[1024]; struct sockaddr_in addr; int timeout; struct pollfd fds[200]; int nfds = 2, current_size = 0, j; int send_2_listners; unsigned short port = SERVER_PORT; unsigned short cmd = 0, report = 0; if (strcmp(prog, "sensd") == 0) { baud = B38400; background = 1; date = 1; utime = 1; utc = 0; filename = "/var/log/sensors.dat"; } if(ac == 1) usage(); for(i = 1; (i < ac) && (av[i][0] == '-'); i++) { if (strcmp(av[i], "-300") == 0) baud = B300; else if (strcmp(av[i], "-600") == 0) baud = B600; else if (strcmp(av[i], "-1200") == 0) baud = B1200; else if (strcmp(av[i], "-2400") == 0) baud = B2400; else if (strcmp(av[i], "-4800") == 0) baud = B4800; else if (strcmp(av[i], "-9600") == 0) baud = B9600; else if (strcmp(av[i], "-19200") == 0) baud = B19200; else if (strcmp(av[i], "-38400") == 0) baud = B38400; else if (strcmp(av[i], "-utime") == 0) utime = 1; else if (strcmp(av[i], "-utc") == 0) utc = 1; else if (strcmp(av[i], "-b") == 0) background = 1; else if (strncmp(av[i], "-f", 2) == 0) filename = av[i]+2; else if (strncmp(av[i], "-R", 2) == 0) { reportpath = av[i]+2; if(!*reportpath) reportpath = "/var/lib/sensd"; } else if (strncmp(av[i], "-p", 2) == 0) { port = atoi(av[i]+2); } else if (strcmp(av[i], "-report") == 0) report = 1; else if (strcmp(av[i], "-cmd") == 0) cmd = 1; else usage(); } if(reportpath) { struct stat statb; if(stat(reportpath, &statb)) { fprintf(stderr, "Failed to open '%s'\n", reportpath); exit(2); } } if(filename) { file_fd = open(filename, O_CREAT|O_RDWR|O_APPEND, 0644); if(file_fd < 0) { fprintf(stderr, "Failed to open '%s'\n", filename); exit(2); } } strncpy(dial_tty, devtag_get(av[i]), sizeof(dial_tty)); while (! get_lock()) { if(--retry == 0) exit(-1); sleep(1); } if ((usb_fd = open(devtag_get(av[i]), O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) { perror("bad terminal device, try another"); exit(-1); } fcntl(usb_fd, F_GETFL); fcntl(usb_fd, F_SETFL, O_RDWR); if (tcgetattr(usb_fd, &tp) < 0) { perror("Couldn't get term attributes"); exit(-1); } old = tp; /* SANE is a composite flag that sets the following parameters from termio(M): CREAD BRKINT IGNPAR ICRNL IXON ISIG ICANON ECHO ECHOK OPOST ONLCR SANE also clears the following modes: CLOCAL IGNBRK PARMRK INPCK INLCR IUCLC IXOFF XCASE ECHOE ECHONL NOFLSH OLCUC OCRNL ONOCR ONLRET OFILL OFDEL NLDLY CRDLY TABDLY BSDLY VTDLY FFDLY */ /* 8 bits + baud rate + local control */ tp.c_cflag = baud | CS8 | CLOCAL | CREAD; tp.c_oflag = 0; /* Raw Input */ tp.c_lflag = 0; /* No conoical */ tp.c_oflag &= ~(OLCUC|OCRNL|ONOCR|ONLRET|OFILL|OFDEL|NLDLY|CRDLY); /* ignore CR, ignore parity */ tp.c_iflag = ~(IGNBRK|PARMRK|INPCK|INLCR|IUCLC|IXOFF) | BRKINT|IGNPAR|ICRNL|IXON|ISIG|ICANON; tp.c_lflag &= ~(ECHO | ECHONL); tcflush(usb_fd, TCIFLUSH); /* set output and input baud rates */ cfsetospeed(&tp, baud); cfsetispeed(&tp, baud); if (tcsetattr(usb_fd, TCSANOW, &tp) < 0) { perror("Couldn't set term attributes"); goto error; } /* Term ok deal w. text to send */ if(background) { int i; if(getppid() == 1) return 0; /* Already a daemon */ i = fork(); if (i < 0) exit(1); /* error */ if (i > 0) _exit(0); /* parent exits */ /* child */ setsid(); /* obtain a new process group */ for (i = getdtablesize(); i >= 0; --i) { if(i == usb_fd) continue; if(i == file_fd) continue; close(i); /* close all descriptors */ } i = open("/dev/null",O_RDWR); dup(i); dup(i); /* handle standard I/O */ umask(027); /* set newly created file permissions */ chdir("/"); /* change running directory */ #if 0 lfp = open(LOCK_FILE,O_RDWR|O_CREAT,0640); if (lfp < 0) exit(1); /* can not open */ if (lockf(lfp, F_TLOCK,0) <0 ) exit(0); /* can not lock */ /* first instance continues */ sprintf(str,"%d\n",getpid()); write(lfp,str,strlen(str)); /* record pid to lockfile */ signal(SIGCHLD,SIG_IGN); /* ignore child */ signal(SIGTSTP,SIG_IGN); /* ignore tty signals */ signal(SIGTTOU,SIG_IGN); signal(SIGTTIN,SIG_IGN); signal(SIGHUP,signal_handler); /* catch hangup signal */ signal(SIGTERM,signal_handler); /* catch kill signal */ #endif } if(reportpath) umask(0); listen_sd = socket(AF_INET, SOCK_STREAM, 0); if (listen_sd < 0) { perror("socket() failed"); exit(-1); } /* Allow socket descriptor to be reuseable */ rc = setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); if (rc < 0) { perror("setsockopt() failed"); close(listen_sd); exit(-1); } /* Set socket to be nonblocking. All of the sockets for the incoming connections will also be nonblocking since they will inherit that state from the listening socket. */ rc = ioctl(listen_sd, FIONBIO, (char *)&on); if (rc < 0) { perror("ioctl() failed"); close(listen_sd); exit(-1); } memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(port); rc = bind(listen_sd, (struct sockaddr *)&addr, sizeof(addr)); if (rc < 0) { perror("bind() failed"); close(listen_sd); exit(-1); } /* Set the listen back log */ rc = listen(listen_sd, 32); if (rc < 0) { perror("listen() failed"); close(listen_sd); exit(-1); } memset(fds, 0 , sizeof(fds)); /* Add initial listening sockets */ fds[0].fd = listen_sd; fds[0].events = POLLIN; fds[1].fd = usb_fd; fds[1].events = POLLIN; nfds = 2; timeout = (10 * 1000); done = 0; j = 0; while (!done) { int i, ii; char outbuf[512]; timeout = (10 * 1000); rc = poll(fds, nfds, timeout); send_2_listners = 0; if (rc < 0) { //perror(" poll() failed"); break; } if (rc == 0) { /* Timeout placeholder */ continue; } current_size = nfds; for (i = 0; i < current_size; i++) { if(fds[i].revents == 0) continue; send_2_listners = 0; if (fds[i].fd == usb_fd && fds[i].revents & POLLIN) { res = read(usb_fd, io, BUFSIZ); if(res > 0) ; else done = 0; for(ii=0; !done && ii < res; ii++, j++) { if(io[ii] == END_OF_FILE) { outbuf[0] = 0; if(buf[0] == '&' && buf[1] == ':' && (date || utime)) print_date(outbuf); buf[j] = 0; strcat(outbuf, buf); write(file_fd, outbuf, strlen(outbuf)); if(reportpath) do_report(buf, reportpath); if(report) send_2_listners = 1; j = -1; } else { buf[j] = io[ii]; } } fds[i].revents &= ~POLLIN; } if (fds[i].fd == listen_sd && fds[i].revents & POLLIN) { new_sd = accept(listen_sd, NULL, NULL); if (new_sd != -1) { // printf(" New incoming connection - %d\n", new_sd); fds[nfds].fd = new_sd; fds[nfds].events = POLLIN; nfds++; } fds[i].revents &= ~POLLIN; } if (fds[i].revents & POLLIN) { close_conn = FALSE; rc = recv(fds[i].fd, buffer, sizeof(buffer), 0); if (rc < 0) { if (errno != EWOULDBLOCK) { close_conn = TRUE; } break; } if (rc == 0) close_conn = TRUE; if(rc > 0) { len = rc; buffer[len-1] = 0xd; if(cmd) rc = write(usb_fd, &buffer, len); else rc = send(fds[i].fd, buffer, len, 0); } if (rc < 0) close_conn = TRUE; if (close_conn) { close(fds[i].fd); fds[i].fd = -1; compress_array = TRUE; } } /* End of existing connection */ fds[i].revents = 0; } /* Loop pollable descriptors */ /* Squeeze the array and decrement the number of file descriptors. We do not need to move back the events and revents fields because the events will always be POLLIN in this case, and revents is output. */ if (compress_array) { compress_array = FALSE; for (i = 0; i < nfds; i++) { if (fds[i].fd == -1) { for(j = i; j < nfds; j++) { fds[j].fd = fds[j+1].fd; } nfds--; } } } if(send_2_listners) { static int cnt; cnt++; current_size = nfds; for (i = 0; i < current_size; i++) { if (fds[i].fd == usb_fd) continue; if (fds[i].fd == listen_sd) continue; len = strlen(outbuf); rc = send(fds[i].fd, outbuf, len, 0); if (rc < 0) { close_conn = TRUE; break; } } } } if (tcsetattr(usb_fd, TCSANOW, &old) < 0) { perror("Couldn't restore term attributes"); exit(-1); } lockfile_remove(); exit(0); error: if (tcsetattr(usb_fd, TCSANOW, &old) < 0) { perror("Couldn't restore term attributes"); } exit(-1); }
int main(int ac, char *av[]) { struct termios tp, old; int fd; char io[BUFSIZ]; int res; long baud; int i, done, len, idx; if(ac == 1) usage(); if (strcmp(av[1], "-4800") == 0) { baud = B4800; av++; ac--; } else if (strcmp(av[1], "-9600") == 0) { baud = B9600; av++; ac--; } else if (strcmp(av[1], "-19200") == 0) { baud = B19200; av++; ac--; } else if (strcmp(av[1], "-38400") == 0) { baud = B38400; av++; ac--; } else baud = B9600; if(ac < 3) usage(); strncpy(dial_tty, devtag_get(av[1]), sizeof(dial_tty)); while (! get_lock()) { if(--retry == 0) exit(-1); sleep(1); } if ((fd = open(devtag_get(av[1]), O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) { perror("bad terminal device, try another"); exit(-1); } fcntl(fd, F_GETFL); fcntl(fd, F_SETFL, O_RDWR); if (tcgetattr(fd, &tp) < 0) { perror("Couldn't get term attributes"); exit(-1); } old = tp; /* SANE is a composite flag that sets the following parameters from termio(M): CREAD BRKINT IGNPAR ISTRIP ICRNL IXON ISIG ICANON ECHO ECHOK OPOST ONLCR SANE also clears the following modes: CLOCAL IGNBRK PARMRK INPCK INLCR IUCLC IXOFF XCASE ECHOE ECHONL NOFLSH OLCUC OCRNL ONOCR ONLRET OFILL OFDEL NLDLY CRDLY TABDLY BSDLY VTDLY FFDLY */ /* 8 bits + baud rate + local control */ tp.c_cflag = baud | CS8 | CLOCAL | CREAD; tp.c_oflag = 0; /* Raw Input */ tp.c_lflag = 0; /* No conoical */ tp.c_oflag &= ~(OLCUC|OCRNL|ONOCR|ONLRET|OFILL|OFDEL|NLDLY|CRDLY); /* ignore CR, ignore parity */ tp.c_iflag = ~(IGNBRK|PARMRK|INPCK|INLCR|IUCLC|IXOFF) | BRKINT|ISTRIP|IGNPAR|ICRNL|IXON|ISIG|ICANON; tp.c_lflag &= ~(ECHO | ECHONL); tcflush(fd, TCIFLUSH); /* set output and input baud rates */ cfsetospeed(&tp, baud); cfsetispeed(&tp, baud); if (tcsetattr(fd, TCSANOW, &tp) < 0) { perror("Couldn't set term attributes"); goto error; } for(idx = 0, i = 2; i < ac; i++) { len = strlen(av[i]); strncpy(&io[idx], av[i], len); idx += len; io[idx++] = '\r'; } res = write(fd, io, idx); if(res < 0 ) { perror("write faild"); goto error; } done = 0; while (!done && (res = read(fd, io, BUFSIZ)) > 0) { int i; for(i=0; !done && i < res; i++) { if(io[i] == END_OF_FILE) done = 1; else printf("%c", io[i]); } } if (tcsetattr(fd, TCSANOW, &old) < 0) { perror("Couldn't restore term attributes"); exit(-1); } lockfile_remove(); exit(0); error: if (tcsetattr(fd, TCSANOW, &old) < 0) { perror("Couldn't restore term attributes"); } exit(-1); }