/* #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include */ #include #include #include #include #include #include #include #include #include #include #define False -1 #define True 0 #define BuffSize 256 typedef struct { int year, month, day, hour, minute, second; } Time; const int TimeSize = sizeof(Time *); Time *Now_Time() { Time *now = (Time *)malloc(TimeSize); time_t currentTime = time(NULL); struct tm *localTime = localtime(¤tTime); now->year = localTime->tm_year + 1900; now->month = localTime->tm_mon + 1; now->day = localTime->tm_mday; now->hour = localTime->tm_hour; now->minute = localTime->tm_min; now->second = localTime->tm_sec; return now; } int Str_Split(char *str, char c, char ***res) { int count = 1, i = 0, len; char *temp = str, *start, **arr; while (*temp != 0) { if (*temp == c) count++; temp++; } arr = (char **)malloc(count * sizeof(char *)); temp = str; while (*temp != 0) { start = temp; while (*temp != c && *temp != 0) temp++; len = temp - start; arr[i] = (char *)malloc((len + 1) * sizeof(char)); strncpy(arr[i], start, len); arr[i][len] = 0; if (*temp == c) temp++; i++; } *res = arr; return count; } void Free_Strings(char **list, int count) { do { free(list[--count]); } while (count); } int Uart_Open(char *location) { int fd = open(location, O_RDWR | O_NOCTTY | O_NDELAY); if (fd == False) return False; // 恢复串口为阻塞状态 if (fcntl(fd, F_SETFL, 0) < 0) return False; // 测试是否为终端设备 if (0 == isatty(STDIN_FILENO)) return False; return fd; } int Uart_Set(int fd, int speed, int flow_ctrl, int data_bits, int stop_bits, int parity) { int i, status; int speed_arr[] = {B115200, B19200, B9600, B4800, B2400, B1200, B300}; int name_arr[] = {115200, 19200, 9600, 4800, 2400, 1200, 300}; struct termios options; if (tcgetattr(fd, &options) != 0) { printf("Error: SetupSerial 1"); return False; } // 设置串口输入波特率和输出波特率 for (i = 0; i < sizeof(speed_arr) / sizeof(int); i++) { if (speed == name_arr[i]) { cfsetispeed(&options, speed_arr[i]); cfsetospeed(&options, speed_arr[i]); } } // 修改控制模式,保证程序不会占用串口 options.c_cflag |= CLOCAL; // 修改控制模式,使得能够从串口中读取输入数据 options.c_cflag |= CREAD; // 设置数据流控制 switch (flow_ctrl) { case 0: // 不使用流控制 options.c_cflag &= ~CRTSCTS; break; case 1: // 使用硬件流控制 options.c_cflag |= CRTSCTS; break; case 2: // 使用软件流控制 options.c_cflag |= IXON | IXOFF | IXANY; break; } // 设置数据位 // 屏蔽其他标志位 options.c_cflag &= ~CSIZE; switch (data_bits) { case 5: options.c_cflag |= CS5; break; case 6: options.c_cflag |= CS6; break; case 7: options.c_cflag |= CS7; break; case 8: options.c_cflag |= CS8; break; default: printf("Error: Unsupported data size\n"); return False; } // 设置校验位 switch (parity) { case 'n': case 'N': // 无奇偶校验位。 options.c_cflag &= ~PARENB; options.c_iflag &= ~INPCK; break; case 'o': case 'O': // 设置为奇校验 options.c_cflag |= (PARODD | PARENB); options.c_iflag |= INPCK; break; case 'e': case 'E': // 设置为偶校验 options.c_cflag |= PARENB; options.c_cflag &= ~PARODD; options.c_iflag |= INPCK; break; case 's': case 'S': // 设置为空格 options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; break; default: printf("Error: Unsupported parity\n"); return False; } // 设置停止位 switch (stop_bits) { case 1: options.c_cflag &= ~CSTOPB; break; case 2: options.c_cflag |= CSTOPB; break; default: printf("Error: Unsupported stop bits\n"); return False; } // 修改输出模式,原始数据输出 options.c_oflag &= ~OPOST; options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // 设置等待时间和最小接收字符 options.c_cc[VTIME] = 1; /* 读取一个字符等待1*(1/10)s */ options.c_cc[VMIN] = 1; /* 读取字符的最少个数为1 */ // 如果发生数据溢出,接收数据,但是不再读取 刷新收到的数据但是不读 tcflush(fd, TCIFLUSH); // 激活配置 (将修改后的termios数据设置到串口中) if (tcsetattr(fd, TCSANOW, &options) != 0) { printf("Error: com set error!\n"); return False; } return True; } int Uart_Recv(int fd, char *rcv_buf, int data_len) { fd_set fs_read; FD_ZERO(&fs_read); FD_SET(fd, &fs_read); return read(fd, rcv_buf, data_len); } int Get_Mac(char *mac, int limit) { struct ifreq ifreq; int sock; if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) return False; strcpy(ifreq.ifr_name, "eth0"); // Current eth0 only if (ioctl(sock, SIOCGIFHWADDR, &ifreq) < 0) return False; return snprintf( mac, limit, "%X%X%X%X%X%X", (unsigned char)ifreq.ifr_hwaddr.sa_data[0], (unsigned char)ifreq.ifr_hwaddr.sa_data[1], (unsigned char)ifreq.ifr_hwaddr.sa_data[2], (unsigned char)ifreq.ifr_hwaddr.sa_data[3], (unsigned char)ifreq.ifr_hwaddr.sa_data[4], (unsigned char)ifreq.ifr_hwaddr.sa_data[5] ); } int main(void) { int ErrNo, UartFd, UartReadSize, SocketFd, SockReadSize, SockSendSize, tmp_; char MacAddr[18], SockReadBuff[BuffSize], SockSendBuff[BuffSize], UartRecvBuff[BuffSize], **SplitList, DeviceId[32]; // 打开串口Uart UartFd = Uart_Open("/dev/ttyS0"); if (UartFd == False) { printf("Error: Failed To Open Uart.\n"); return False; } do { ErrNo = Uart_Set(UartFd, 115200, 0, 8, 1, 'N'); } while (ErrNo == False || UartFd == False); // 阻塞式连接TCP struct sockaddr_in sin; bzero(&sin, sizeof(sin)); sin.sin_family = AF_INET; inet_pton(AF_INET, "119.3.44.183", &sin.sin_addr); sin.sin_port = htons(8012); SocketFd = socket(AF_INET, SOCK_STREAM, 0); connect(SocketFd, (const struct sockaddr *)&sin, sizeof(sin)); // init message exchange if (Get_Mac(MacAddr, 18) > 0) printf("Mac Addr: %s\n", MacAddr); else { printf("Error: Failed To Get Mac Addr.\n"); close(UartFd); return False; } memset(SockSendBuff, 0, BuffSize); SockSendSize = sprintf(SockSendBuff, "hm+%s+1+7+end", MacAddr); write(SocketFd, SockSendBuff, SockSendSize); SockReadSize = read(SocketFd, SockReadBuff, BuffSize); SockReadBuff[SockReadSize] = 0; tmp_ = Str_Split(SockReadBuff, '+', &SplitList); strcpy(DeviceId, SplitList[3]); Free_Strings(SplitList, tmp_); // 循环读串口数据 memset(SockSendBuff, 0, BuffSize); while (1) { UartReadSize = Uart_Recv(UartFd, UartRecvBuff, BuffSize); if (UartReadSize > 0) { UartRecvBuff[UartReadSize] = 0; strcat(SockSendBuff, UartRecvBuff); if (strstr(UartRecvBuff, "end")) { tmp_ = Str_Split(SockSendBuff, '+', &SplitList); Time *now = Now_Time(); SockSendSize = sprintf( SockSendBuff, "%s+%s+%s+%s+0+0+%s+%s+%d%02d%02d%02d%02d%02d+1.0#%s#%s+%s+%s", SplitList[0], DeviceId, SplitList[2], SplitList[4], SplitList[5], SplitList[6], now->year, now->month, now->day, now->hour, now->minute, now->second, SplitList[7], SplitList[3], SplitList[8], SplitList[9] ); SockSendBuff[SockSendSize] = 0; write(SocketFd, SockSendBuff, SockSendSize); free(now); Free_Strings(SplitList, tmp_); memset(SockSendBuff, 0, BuffSize); } } } close(UartFd); }