/** * fields * 1byte: block number * 1byte: check sum for blocl number * 128byte: data * 1byte: check sum for data */ static int xmodem_read_block(unsigned char block_number, char *buf) { unsigned char c, block_num, check_sum; int i; /* block number */ block_num = serial_recv_byte(SERIAL_DEFAULT_DEVICE); if (block_num != block_number) return -1; /* block number & checksum = 0xff */ block_num ^= serial_recv_byte(SERIAL_DEFAULT_DEVICE); if (block_num != 0xff) return -1; check_sum = 0; for (i = 0; i < XMODEM_BLOCK_SIZE; i++) { c = serial_recv_byte(SERIAL_DEFAULT_DEVICE); *(buf++) = c; check_sum += c; } check_sum ^= serial_recv_byte(SERIAL_DEFAULT_DEVICE); if (check_sum) return -1; return i; }
/* get a single character */ unsigned char getc(void) { unsigned char c = serial_recv_byte(SERIAL_DEFAULT_DEVICE); c = (c == '\r') ? '\n' : c; /* convert a new line code */ putc(c); /* echo-back */ return c; }
long xmodem_recv(char *buf) { int r, receiving = 0; long size = 0; unsigned char c, block_number = 1; while (1) { if (!receiving) xmodem_wait(); c = serial_recv_byte(SERIAL_DEFAULT_DEVICE); if (c == XMODEM_EOT) { serial_send_byte(SERIAL_DEFAULT_DEVICE, XMODEM_ACK); break; } else if (c == XMODEM_CAN) { return -1; } else if (c == XMODEM_SOH) { receiving++; r = xmodem_read_block(block_number, buf); if (r < 0) { serial_send_byte(SERIAL_DEFAULT_DEVICE, XMODEM_NAK); } else { block_number++; size += r; buf += r; serial_send_byte(SERIAL_DEFAULT_DEVICE, XMODEM_ACK); } } else { if (receiving) return -1; } } return size; }
static int consdrv_intrproc(struct consreg *cons) { unsigned char c; char *p; if(serial_is_recv_enable(cons->index)) { c = serial_recv_byte(cons->index); if(c == '\r') c = '\n'; send_string(cons, &c, 1); if(cons->id) { if(c != '\n') cons->recv_buf[cons->recv_len++] = c; else { p = svc_memalloc(CONS_BUF_SIZE); memcpy(p, cons->recv_buf, cons->recv_len); svc_send(MLBOX_ID_CONSINPUT, cons->recv_len, p); cons->recv_len = 0; } } } if(serial_is_send_enable(cons->index)) { if(!cons->id || !cons->send_len) serial_intr_send_disable(cons->index); else send_char(cons); } return 0; }
unsigned char getc(void) { unsigned char c = serial_recv_byte(SERIAL_DEFAULT_DEVICE); c = (c == '\r') ? '\n' : c; putc(c); return c; }
/******************************************************************//** * @brief getc * @param * @return *********************************************************************/ uint8_t kz_getc(void) { uint8_t c = serial_recv_byte(); c = (c == '\r') ? '\n' : c; kz_putc(c); return c; }
/* * 以下は割込みハンドラから呼ばれる割込み処理であり,非同期で * 呼ばれるので,ライブラリ関数などを呼び出す場合には注意が必要. * 基本として,以下のいずれかに当てはまる関数しか呼び出してはいけない. * ・再入可能である. * ・スレッドから呼ばれることは無い関数である. * ・スレッドから呼ばれることがあるが,割込み禁止で呼び出している. * また非コンテキスト状態で呼ばれるため,システム・コールは利用してはいけない. * (サービス・コールを利用すること) */ static int consdrv_intrproc(struct consreg *cons) { unsigned char c; char *p; if (serial_is_recv_enable(cons->index)) { /* 受信割込み */ c = serial_recv_byte(cons->index); if (c == 0x03) { force_break(); return 0; } if (c == '\r') /* 改行コード変換(\r→\n) */ c = '\n'; send_string(cons, &c, 1); /* エコーバック処理 */ if (cons->id) { if (c != '\n') { /* 改行でないなら,受信バッファにバッファリングする */ cons->recv_buf[cons->recv_len++] = c; } else { /* * Enterが押されたら,バッファの内容を * コマンド処理スレッドに通知する. * (割込みハンドラなので,サービス・コールを利用する) */ p = kx_kmalloc(CONS_BUFFER_SIZE); memcpy(p, cons->recv_buf, cons->recv_len); kx_send(MSGBOX_ID_CONSINPUT, cons->recv_len, p); cons->recv_len = 0; } } } if (serial_is_send_enable(cons->index)) { /* 送信割込み */ if (!cons->id || !cons->send_len) { /* 送信データが無いならば,送信処理終了 */ serial_intr_send_disable(cons->index); } else { /* 送信データがあるならば,引続き送信する */ send_char(cons); } } return 0; }
/* * 以下は割り込みハンドラから呼ばれる割り込み処理であり、 * 非同期で呼ばれるので、ライブラリ関数などを呼び出す場合は注意が必要。 * 基本として、以下のいずれかに当てはまる関数しか呼び出してはいけない。 * ・再入可能である * ・スレッドから呼ばれることは無い関数である * ・スレッドから呼ばれることがあるが、割り込み禁止で呼び出している * また非コンテキスト状態でよばれるため、システムコールは利用してはいけない。 * (サービスコールを利用すること) */ static int consdrv_intrproc(struct consreg *cons) { unsigned char c; char *p; /* 受信割り込みが発生している場合 */ if (serial_is_recv_enable(cons->index)) { c = serial_recv_byte(cons->index); if (c == '\r') c = '\n'; /* エコーバック */ send_string(cons, &c, 1); if (cons->id) { if (c != '\n') { /* 改行でなければ受信バッファにバッファリングする */ cons->recv_buf[cons->recv_len++] = c; } else { /* Enterが押されたら、バッファの内容をコマンド処理スレッドに通知 */ p = kx_kmalloc(CONS_BUFFER_SIZE); memcpy(p, cons->recv_buf, cons->recv_len); kx_send(MSGBOX_ID_CONSINPUT, cons->recv_len, p); cons->recv_len = 0; } } } /* 送信割り込みが発生している場合 */ if (serial_intr_is_send_enable(cons->index)) { if (!cons->id || !cons->send_len) { /* 送信データがないなら送信処理終了 */ serial_intr_send_disable(cons->index); } else { /* 送信データあるなら引き続き送信 */ send_char(cons); } } return 0; }
long xmodem_recv(char *buf) { int r, receiving = 0; long size = 0; unsigned char c, block_number = 1; while (1) { if (!receiving) xmodem_wait(); /* 受信開始されるまで送信要求を出す */ c = serial_recv_byte(SERIAL_DEFAULT_DEVICE); if (c == XMODEM_EOT) { /* 受信終了 */ serial_send_byte(SERIAL_DEFAULT_DEVICE, XMODEM_ACK); break; } else if (c == XMODEM_CAN) { /* 受信中断 */ return -1; } else if (c == XMODEM_SOH) { /* 受信開始 */ receiving++; r = xmodem_read_block(block_number, buf); /* ブロック単位での受信 */ if (r < 0) { /* 受信エラー */ serial_send_byte(SERIAL_DEFAULT_DEVICE, XMODEM_NAK); } else { /* 正常受信 */ block_number++; size += r; buf += r; serial_send_byte(SERIAL_DEFAULT_DEVICE, XMODEM_ACK); } } else { if (receiving) return -1; } } return size; }
void *network_start_thread(void *args) { utils_log("Starting network thread\n"); /* open socket sending broadcast messages */ network_sock_broad = socket(AF_INET, SOCK_DGRAM, 0); /* exit on error */ if (network_sock_broad < 1) { utils_log("Error opening broadcast socket"); return NULL; } /* open socket sending/receiving serial cable data */ network_sock_bound = socket(AF_INET, SOCK_DGRAM, 0); /* exit on error */ if (network_sock_bound < 1) { utils_log("Error opening serial-link socket"); close (network_sock_broad); return NULL; } /* enable to broadcast */ int enable=1; setsockopt(network_sock_broad, SOL_SOCKET, SO_BROADCAST, &enable, sizeof(enable)); /* prepare dest stuff */ struct sockaddr_in broadcast_addr; struct sockaddr_in bound_addr; struct sockaddr_in addr_from; socklen_t addr_from_len = sizeof(addr_from); memset(&broadcast_addr, 0, sizeof(broadcast_addr)); broadcast_addr.sin_family = AF_INET; broadcast_addr.sin_addr.s_addr = INADDR_BROADCAST; // inet_aton("239.255.0.37", // (struct in_addr *) &broadcast_addr.sin_addr.s_addr); //inet_aton("192.168.10.168", // (struct in_addr *) &broadcast_addr.sin_addr.s_addr); broadcast_addr.sin_port = htons(64333); /* setup listening socket */ memset(&bound_addr, 0, sizeof(bound_addr)); bound_addr.sin_family = AF_INET; bound_addr.sin_addr.s_addr = INADDR_ANY; bound_addr.sin_port = htons(64333); /* bind to selected port */ if (bind(network_sock_bound, (struct sockaddr *) &bound_addr, sizeof(bound_addr))) { utils_log("Error binding to port 64333"); /* close sockets and exit */ close(network_sock_broad); close(network_sock_bound); return NULL; } /* assign it to our multicast group */ /* struct ip_mreq mreq; mreq.imr_multiaddr.s_addr=inet_addr("239.255.0.37"); mreq.imr_interface.s_addr=htonl(INADDR_ANY); if (setsockopt(network_sock_bound, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { utils_log("Error joining multicast network"); close(network_sock_broad); close(network_sock_bound); return NULL; }*/ fd_set rfds; char buf[64]; int ret; ssize_t recv_ret; struct timeval tv; int timeouts = 4; unsigned int v, clock, prog; // uint16_t prog; /* message parts */ char msg_type; unsigned int msg_uuid; char msg_content[64]; /* generate a random uuid */ srand(time(NULL)); network_uuid = rand() & 0xFFFFFFFF; /* set callback in case of data to send */ serial_set_send_cb(&network_send_data); /* declare network is running */ network_running = 1; utils_log("Network thread started\n"); /* loop forever */ while (network_running) { FD_ZERO(&rfds); FD_SET(network_sock_bound, &rfds); /* wait one second */ tv.tv_sec = 1; tv.tv_usec = 0; /* one second timeout OR something received */ ret = select(network_sock_bound + 1, &rfds, NULL, NULL, &tv); // utils_log_urgent("SELECT RET: %d\n", ret); /* error! */ if (ret == -1) break; /* ret 0 = timeout */ if (ret == 0) { if (++timeouts == 5) { /* build output message */ sprintf(buf, "B%08x%s", network_uuid, global_cart_name); /* send broadcast message */ sendto(network_sock_broad, buf, strlen(buf), 0, (struct sockaddr *) &broadcast_addr, sizeof(broadcast_addr)); timeouts = 0; } } else { /* reset message content */ bzero(buf, sizeof(buf)); bzero(msg_content, sizeof(msg_content)); /* exit if an error occour */ if ((recv_ret = recvfrom(network_sock_bound, buf, 64, 0, (struct sockaddr *) &addr_from, (socklen_t *) &addr_from_len)) < 1) break; /* dissect message */ if (sscanf(buf, "%c%08x%s", &msg_type, &msg_uuid, msg_content) == 3) { /* was it send by myself? */ if (msg_uuid != network_uuid) { /* is it a serial message? */ if (msg_type == 'M') { /* extract value from hex string */ sscanf(msg_content, "%02x%02x%02x", &v, &clock, &prog); /* tell serial module something has arrived */ serial_recv_byte((uint8_t) v, (uint8_t) clock); /*if (clock == 0) { utils_ts_log("SEM POST\n"); network_sem_post(&network_sem); } */ } else if (msg_type == 'B') { /* someone is claiming is playing with the same game? */ if (strcmp(msg_content, global_cart_name) == 0 && serial.peer_connected == 0) { /* save sender */ memcpy(&network_peer_addr, &addr_from, sizeof(struct sockaddr_in)); /* just change dst port */ network_peer_addr.sin_port = htons(64333); /* notify the other peer by sending a b message */ sprintf(buf, "B%08x%s", network_uuid, global_cart_name); /* send broadcast message */ sendto(network_sock_broad, buf, strlen(buf), 0, (struct sockaddr *) &network_peer_addr, sizeof(network_peer_addr)); /* log that peer is connected */ utils_log("Peer connected: %s\n", inet_ntoa(network_peer_addr.sin_addr)); /* YEAH */ serial.peer_connected = 1; } } } } } } /* free serial */ serial.peer_connected = 0; /* close sockets */ close(network_sock_broad); close(network_sock_bound); return NULL; }
static int getDebugChar() { return serial_recv_byte(SERIAL_DEFAULT_DEVICE); }