// Used in project GZFG-138 #include #include #include #include #include #include #include #include #include #include #define DEBUG_PRINTF #ifdef DEBUG_PRINTF #define DEBUGFMT "%s(%d)-%s: " #define DEBUGARGS __FILE__,__LINE__,__FUNCTION__ #define SERIALDBG(format, ...) \ printf(DEBUGFMT "debug: " format, DEBUGARGS, ## __VA_ARGS__) #else /* DEBUG_PRINTF */ #define SERIALDBG(format, ...) #endif static struct termios uartsave; static struct termios uartset; static struct termios uartnew; static int open_serial(char *dev) { int fd; fd = open(dev, O_RDWR|O_NOCTTY|O_NDELAY, 0); if ( fd < 1 ) { fprintf(stderr, "open <%s> error %s\n", dev, strerror(errno)); return -1; } return fd; } static void close_serial(int pf) { /* restore original terminal settings on exit */ tcsetattr(pf, TCSANOW, &uartset); close(pf); } static void termios_setup(int pf,speed_t speed_param) { tcgetattr(pf, &uartsave); uartset = uartsave; cfsetospeed(&uartset, speed_param); cfsetispeed(&uartset, speed_param); // Space calibration uartset.c_cflag &= ~ CSIZE; // Countless according to a bit mask uartset.c_cflag |= CS8; // 8 bits of data uartset.c_cflag &= ~ CSTOPB; // If set CSTOPB, 2 stop bits (do not set is a stop bits) uartset.c_cflag &= ~ PARODD; // even parity is used uartset.c_cflag |= PARENB; // enable calibration //uartset.c_cflag &= ~ PARENB; // no calibration uartset.c_cflag &= ~ CRTSCTS; // No flow control //uartset.c_cflag |= CRTSCTS; // if not development, just like serial port terminal, // without the need for data transmission serial port to handle, // then use the original Mode (Raw Mode) way to communication, // setting as follows: // will CR mapped to litton precision; // Start exports hardware flow control; // Start entrance software flow control; // Allow characters restart flow control uartset.c_iflag &= ~ ( ICRNL | IXON | IXOFF | IXANY ); uartset.c_lflag &= ~ ( ICANON | ECHO | ECHOE | ISIG ); uartset.c_cc[VMIN] = 0; uartset.c_cc[VQUIT] = 0; uartset.c_cflag |= CREAD; // enable receiving tcsetattr(pf, TCSANOW, &uartset); tcgetattr(pf, &uartnew); } /* send len bytes data in buffer */ static int serial_write(int fd, const void *buf, int len, struct timeval *write_tv) { int count; int ret; fd_set output; struct timeval timeout; ret = 0; count = 0; timeout.tv_sec = write_tv->tv_sec; timeout.tv_usec = write_tv->tv_usec; FD_ZERO(&output); FD_SET(fd, &output); do{ /* listen */ ret = select(fd + 1, NULL, &output, NULL, &timeout); if (ret == -1) { /* error */ perror("select()"); return -1; } else if (ret) { /* write buffer */ ret = write(fd, (char *) buf + count, len); if (ret < 1) { fprintf(stderr, "write error %s\n", strerror(errno)); return -1; } count += ret; len -= ret; } else { /* timeout */ SERIALDBG("time out.\n"); return -EAGAIN; } } while (len > 0); SERIALDBG("write count=%d\n",count); return count; } /* read one char from serial */ int serial_read_ch(int fd, char *c, struct timeval *read_tv) { int ret; fd_set input; struct timeval timeout; ret = 0; timeout.tv_sec = read_tv->tv_sec; timeout.tv_usec = read_tv->tv_usec; FD_ZERO(&input); FD_SET(fd, &input); /* listen */ ret = select(fd + 1, &input, NULL, NULL, &timeout); if (ret == -1) { /* error */ perror("select()"); return -1; } else if (ret) { /* read */ ret = read(fd, c, sizeof(char)); if (ret < 1) { fprintf(stderr, "read error %s\n", strerror(errno)); return -2; } } else { /* timeout */ SERIALDBG("time out.\n"); return -3; } return 0; } /* wait until the first "OK" string come from serial */ static int wait_ok_string(int fd, int timeout_sec) { int i; int ret = 0; char ch = '?'; char last = '?'; struct timeval timeout; timeout.tv_sec = timeout_sec; timeout.tv_usec = 0; for (i = 0; i < 1024; i++) { /* read one char */ ret = serial_read_ch(fd, &ch, &timeout); if (ret < 0) break; /* display the char */ putchar(ch); /* check "ok" */ if (last == 'O' && ch == 'K') { ret = 1; break; } last = ch; } return ret; } int main(int argc, char **argv) { int fd; char sms[128]; char data[128]; struct timeval tv; /* command line */ if (argc != 4) { printf("usage: ./send_sms <> <> <> \n" "eg: ./send_sms /dev/ttyUSB1 13712345678 message \n"); return -1; } /* open serial */ fd = open_serial(argv[1]); if(fd < 1) return -1; termios_setup(fd, B115200); tcflush(fd, TCIOFLUSH); tv.tv_sec = 5; tv.tv_usec = 0; // set as text mode const char *text_mode = "AT+CMGF=1\r"; serial_write(fd, text_mode, strlen(text_mode), &tv); if (wait_ok_string(fd, 5) != 1) { printf("something error while setting text mode. exit!\n"); goto err; } /* send sms */ snprintf(sms, sizeof(sms), "AT+CMGS=\"%s\"\r", argv[2]); serial_write(fd, sms, strlen(sms), &tv); sleep(2); snprintf(data, sizeof(data), "%s\x1A", argv[3]); serial_write(fd, data, strlen(data), &tv); sleep(10); /* release */ close_serial(fd); return 0; err: close_serial(fd); return -1; }