📄 aqshell.c
字号:
} case AQSHELL_DATA_SEND: { deluge_foot_data* data = (deluge_foot_data*)&pkt->data[0]; if (printPkts) printf("%d<<%d %d ", pkt->data[pkt->head.length-1], data->id, data->type); if (printPkts) printf("%s%3d %3d %3d%s\n", HI_RED, data->version, data->page, data->packet, WHITE); if (recordstats && data->id < DELUGE_STATS_COUNT) packet_counts[data->id][3]++; notquiet = 1; break; } default: if (printing) printf("Unknown packet type: %#02X\n", pkt->head.command); break; } if (allquiet && notquiet) { if (csock != -1) { int ts = htonl((int)timestamp.tv_sec); int tu = htonl((int)timestamp.tv_usec); pkt->head.command = AQSHELL_NOTQUIET; pkt->head.flags = AQSHELL_F_SHELLCTL; //pkt->head.id = htons(node_id); pkt->head.length = 0; if (write(csock, syncbytes, 3) != 3 || write(csock, &ts, 4) != 4 || write(csock, &tu, 4) != 4 || write(csock, pkt, sizeof(pkt->head)) != sizeof(pkt->head)) { perror("sendNotQuiet: write"); } } allquiet = 0; printf("Not quiet.\n"); } if (notquiet) { alarm(30); } com_free_buf(cpkt); }}static const char HANDSHAKE[] = "aqshell Handshake";// Exchange a handshake string so we know we have the right protocolstatic int doHandshake(int csock, int isServer){ char buffer[sizeof(HANDSHAKE)]; short hlen = (short)sizeof(HANDSHAKE)-1; short nlen = htons(hlen); if (isServer) { // server goes first // TODO actually the order doesn't matter, both ends should send, then both check if (send(csock, &nlen, 2, 0) != 2 || send(csock, HANDSHAKE, hlen, 0) != hlen) { perror("doHandshake: send"); return -1; } } if (recv(csock, &nlen, 2, 0) != 2) { perror("doHandshake: recv"); return -1; } hlen = ntohs(nlen); if (hlen != sizeof(HANDSHAKE)-1) { fprintf(stderr, "Bad handshake length %d\n", hlen); return -1; } if (recv(csock, buffer, hlen, 0) != hlen) { perror("doHandshake: recv"); return -1; } buffer[hlen] = 0; if (strcmp(HANDSHAKE, buffer) != 0) { fprintf(stderr, "Bad handshake %.*s\n", hlen, buffer); return -1; } if (!isServer) { // client goes second if (send(csock, &nlen, 2, 0) != 2 || send(csock, HANDSHAKE, hlen, 0) != hlen) { perror("doHandshake: send"); return -1; } // Send our port so ExperServer knows which shells it is listening to int port = htonl(sport); if (send(csock, &port, 4, 0) != 4) { perror("doHandshake: send"); return -1; } } printf("Good handshake.\n"); return 0;}// Handle a command sent from ExperServerstatic void doNetCommand(struct aqshell_pkt* pkt){ if (pkt->head.flags & AQSHELL_F_NODECTL) { // The command is meant for the node, so forward it spkt.size = sizeof(pkt->head)+pkt->head.length; memcpy(spkt.data, pkt, spkt.size); dumpPkt("to node", &spkt); com_send(IFACE_SERIAL, &spkt); } else if (pkt->head.flags & AQSHELL_F_SHELLCTL) { // This command is meant for this shell switch (pkt->head.command) { case AQSHELL_CLEARSTATS: memset(packet_counts, 0, sizeof(packet_counts)); if (printing) printf("Cleared stats.\n"); break; case AQSHELL_STARTSTATS: recordstats = 1; if (printing) printf("Start recording stats.\n"); break; case AQSHELL_STOPSTATS: recordstats = 0; if (printing) printf("Stop recording stats.\n"); break; case AQSHELL_GETSTATS: { if (printing) printf("Sending stats.\n"); pkt->head.id = htons(node_id); pkt->head.length = 2 + 4 * 2 * 4; uint16_t r; for (r = 0; r<DELUGE_STATS_COUNT; ) { uint16_t* data = (uint16_t*)pkt->data; *data++ = htons(r); int i; for (i=0; i<4; i++) { int j; for (j=0; j<4; j++) { *data++ = htons(packet_counts[r][j]); } r++; } int zero = 0; int sendlen = sizeof(pkt->head) + pkt->head.length; if (send(csock, syncbytes, 3, 0) != 3 || send(csock, &zero, 4, 0) != 4 || send(csock, &zero, 4, 0) != 4 || send(csock, pkt, sendlen, 0) != sendlen) { perror("doNetCommand: send"); break; } } break; } case AQSHELL_CLOSE: if (close(csock) == -1) perror("doNetCommand: close"); csock = -1; break; default: if (printing) printf("Unknown packet type: %#02X\n", pkt->head.command); // Don't ACK a bad command pkt->head.flags &= ~AQSHELL_F_PLEASEACK; break; } // Send an ACK if we're supposed to if (pkt->head.flags & AQSHELL_F_PLEASEACK) { pkt->head.flags |= AQSHELL_F_ACK; pkt->head.id = htons(node_id); pkt->head.length = 0; int zero = 0; int sendlen = sizeof(struct aqshell_header); if (send(csock, syncbytes, 3, 0) != 3 || send(csock, &zero, 4, 0) != 4 || send(csock, &zero, 4, 0) != 4 || send(csock, pkt, sendlen, 0) != sendlen) { perror("doNetCommand: send"); } } }}static const char serial_start[] = "/dev/ttyS";static const char usb_start[] = "/dev/ttyUSB";static void sockThread(){ // set up socket for receiving connections from central test server if((ssock = socket(PF_INET, SOCK_STREAM, 0)) == -1) { perror("sockThread: socket"); return; } // Choose the port to listen on based on the name of the serial device // we're monitoring. if (0==strncmp(serial_start, serial_file, sizeof(serial_start)-1)) { sport = SERIAL_PORT + atoi(&serial_file[sizeof(serial_start)-1]); } else if (0==strncmp(usb_start, serial_file, sizeof(usb_start)-1)) { //printf("atoi(%s)\n", &serial_file[sizeof(usb_start)-1]); sport = USB_PORT + atoi(&serial_file[sizeof(usb_start)-1]); } else { return; } struct sockaddr_in addr; addr.sin_family = AF_INET; // host byte order addr.sin_port = htons(sport); // short, network byte order addr.sin_addr.s_addr = INADDR_ANY; memset(&(addr.sin_zero), '\0', 8); // zero the rest of the struct if (bind(ssock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) == -1) { perror("sockThread: bind"); if (close(ssock)) perror("close"); return; } if (listen(ssock, 5) == -1) { perror("sockThread: listen"); if (close(ssock)) perror("sockThread: close"); return; } // attempt to connect to central test server do { if((csock = socket(PF_INET, SOCK_STREAM, 0)) == -1) { perror("sockThread: socket"); break; } addr.sin_family = AF_INET; // host byte order addr.sin_port = htons(TEST_PORT); // short, network byte order struct hostent* entry = gethostbyname(hostname); if (!entry) { herror("sockThread: gethostbyname"); if (close(csock)) perror("sockThread: close"); csock = -1; break; } memcpy(&(addr.sin_addr), entry->h_addr_list[0], entry->h_length); memset(&(addr.sin_zero), '\0', 8); // zero the rest of the struct if (connect(csock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in))) { perror("sockThread: connect"); if (close(csock)) perror("sockThread: close"); csock = -1; break; } if (doHandshake(csock, 0) == -1) { if (close(csock)) perror("sockThread: close"); csock = -1; break; } printf("Connected to test server at %s on port %d.\n", entry->h_name, TEST_PORT); } while(0); char buffer[1024]; struct aqshell_pkt* pkt = (struct aqshell_pkt*)buffer; while (!shutdownMode) { // listen for commands while (csock != -1) { int ret; // make sure we are at the beginning of a command packet ret = dbg_recv(csock, buffer, 1, 0); if (ret <= 0) goto csock_error; if (ret == 1 && buffer[0] != SYNC_BYTE_1) continue; ret = dbg_recv(csock, buffer, 1, 0); if (ret <= 0) goto csock_error; if (ret == 1 && buffer[0] != SYNC_BYTE_2) continue; ret = dbg_recv(csock, buffer, 1, 0); if (ret <= 0) goto csock_error; if (ret == 1 && buffer[0] != SYNC_BYTE_3) continue; // Receive the command ret = dbg_recv(csock, pkt, sizeof(pkt->head), 0); if (ret < sizeof(pkt->head)) goto csock_error; if (pkt->head.length > 0) { ret = dbg_recv(csock, pkt->data, pkt->head.length, 0); if (ret < pkt->head.length) goto csock_error; } // And handle it doNetCommand(pkt); continue; csock_error: if (ret == -1) perror("sockThread: recv"); if (close(csock)) perror("sockThread: close"); csock = -1; } printf("Connection closed.\n"); if (shutdownMode) exit(0); // wait for test server to connect to us printf("Listening for connection on port %d.\n", sport); while (csock == -1) { int namelen = sizeof(struct sockaddr_in); csock = accept(ssock, (struct sockaddr *)&addr, &namelen); if (csock == -1) { perror("sockThread: accept"); continue; } char* name = inet_ntoa(addr.sin_addr); struct hostent* entry = gethostbyaddr(name, strlen(name), AF_INET); if (!entry) { herror("gethostbyaddr"); } else { name = entry->h_name; } if (doHandshake(csock, 1) == -1) { if (close(csock)) perror("sockThread: close"); csock = -1; continue; } printf("Connected to test server at %s on port %d.\n", name, sport); } }}void start(){ char* val = NULL; if (mos_arg_check("--log", (uint8_t**)&val) && val) { log_file = fopen(val, "w"); if (!log_file) perror("start: fopen"); } if (!mos_arg_check("--host", (uint8_t**)&hostname) || !hostname) { hostname = "localhost"; } if (!mos_arg_check("--sdev", (uint8_t**)&serial_file) || !serial_file) { serial_file = "/dev/ttyS0"; } if (mos_arg_check("--nopkts", NULL)) { printPkts = 0; } else { printPkts = 1; } if (mos_arg_check("--noprint", NULL)) { printing = 0; printPkts = 0; } else { printing = 1; } // Set up signal handlers // TODO make sure I did this right struct sigaction sa_old; struct sigaction sa_new; sa_new.sa_handler = sigHandler; sigemptyset(&sa_new.sa_mask); sa_new.sa_flags = 0; sigaction(SIGINT, &sa_new, &sa_old); sigaction(SIGTERM, &sa_new, &sa_old); sigaction(SIGALRM, &sa_new, 0); // Start threads for listening on serial port and TCP socket mos_thread_new(recvThread, 0, PRIORITY_NORMAL); mos_thread_new(sockThread, 0, PRIORITY_NORMAL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -