void send_data(int soc, int event, int len) { int i; __builtin_quad tmp; static int tx_index; static char buffer[4][TX_BUF_SIZE]; switch (event) { case TCP_EVENT_DATA: while (link_available() && (tx_index < TX_BUF_SIZE - 128)) { link_recv(&tmp); if (tx_index < 0 || tx_index >= TX_BUF_SIZE) { tx_index = 0; tx_error_counter++; } link_quad2char(&tmp, 1, &txbuf[tx_index]); tx_index += 16; if (tx_index >= TX_BUF_SIZE) { tx_index = 0; tx_error_counter++; } } break; case TCP_EVENT_REGENERATE: puts("regenerate"); if ((tcp_checksend(socket[soc]) != -1) && (len > 0) && (len < TX_BUF_SIZE)) { memcpy(&net_buf[TCP_APP_OFFSET], buffer[soc], len); tcp_send(socket[soc], &net_buf[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, len); } break; } if (tx_index > 0) { for (i = 0; i < 4; ++i) { if (tcp_checksend(socket[i]) != -1) { memcpy(&net_buf[TCP_APP_OFFSET], txbuf, tx_index); memcpy(buffer[i], txbuf, tx_index); tcp_send(socket[i], &net_buf[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, tx_index); tx_index = 0; return; } } } }
/* Receive a TI packet over the virtual link (blocking) * On error: Throws a Packet Exception */ void link_recv_pkt(CPU_t *cpu, TI_PKTHDR *hdr, u_char *data) { int err; switch (err = setjmp(exc_byte)) { case 0: memset(hdr, 0, sizeof(TI_PKTHDR)); // Receive the packet header hdr->machine_ID = link_recv(cpu); hdr->command_ID = link_recv(cpu); hdr->data_len = link_recv(cpu) + (link_recv(cpu) << 8); #ifdef _DEBUG printf("RECV %02x: ", hdr->machine_ID); print_command_ID(hdr->command_ID); putchar('\n'); #endif switch (hdr->command_ID) { case CID_VAR: case CID_DEL: case CID_REQ: case CID_RTS: { link_recv_bytes(cpu, data, 3); uint8_t type_ID = data[2]; if (type_ID == BackupObj) hdr->data_len = sizeof(TI_BACKUPHDR); else if (type_ID >= 0x22 && type_ID <= 0x28) hdr->data_len = sizeof(TI_FLASHHDR); else hdr->data_len = sizeof(TI_VARHDR); link_recv_bytes(cpu, &data[3], hdr->data_len - 3); break; // Do checksum } case CID_DATA: case 0: // Receive the data link_recv_bytes(cpu, data, hdr->data_len); break; // Do checksum default: return; } break; default: return longjmp(exc_pkt, err); } uint16_t chksum = link_recv(cpu) + (link_recv(cpu) << 8); if (chksum != link_chksum(data, hdr->data_len)) longjmp(exc_pkt, LERR_CHKSUM); }
/* * Receive a sequence of bytes over the virtual link * On error: Throws a Byte Exception */ void link_recv_bytes(CPU_t *cpu, void *data, size_t length) { size_t i; for (i = 0; i < length; i++) ((u_char*) data)[i] = link_recv(cpu); }