// beware: data field may be re-allocated in size ! int dusb_recv_data(CalcHandle* h, VirtualPacket* vtl) { RawPacket raw = { 0 }; uint8_t buf[64]; int i = 0; long offset = 0; do { TRYF(dusb_recv(h, &raw)); if(raw.type != RPKT_VIRT_DATA && raw.type != RPKT_VIRT_DATA_LAST) return ERR_INVALID_PACKET; if(!i++) { // first packet has a data header vtl->size = (raw.data[0] << 24) | (raw.data[1] << 16) | (raw.data[2] << 8) | (raw.data[3] << 0); vtl->type = (uint16_t)((raw.data[4] << 8) | (raw.data[5] << 0)); vtl->data = realloc(vtl->data, vtl->size); memcpy(vtl->data, &raw.data[DH_SIZE], raw.size - DH_SIZE); offset = raw.size - DH_SIZE; #if (VPKT_DBG == 2) ticalcs_info(" TI->PC: %s\n\t\t(size = %08x, type = %s)", raw.type == RPKT_VIRT_DATA_LAST ? "Virtual Packet Data Final" : "Virtual Packet Data with Continuation", vtl->size, dusb_vpkt_type2name(vtl->type)); #elif (VPKT_DBG == 1) ticalcs_info(" TI->PC: %s", dusb_vpkt_type2name(vtl->type)); #endif if(vtl->type == 0xEE00) ticalcs_info(" Error Code : %04x\n", (vtl->data[0] << 8) | vtl->data[1]); } else { // others have more data memcpy(vtl->data + offset, raw.data, raw.size); offset += raw.size; #if (VPKT_DBG == 2) ticalcs_info(" TI->PC: %s", raw.type == RPKT_VIRT_DATA_LAST ? "Virtual Packet Data Final" : "Virtual Packet Data with Continuation"); #endif h->updat->max1 = vtl->size; h->updat->cnt1 += DATA_SIZE; h->updat->pbar(); } workaround_recv(h, &raw, vtl); TRYF(dusb_send_acknowledge(h)); } while(raw.type != RPKT_VIRT_DATA_LAST); //printf("dusb_recv_data: rpkt.size=%d\n", raw.size); return 0; }
// beware: data field may be re-allocated in size ! TIEXPORT3 int TICALL dusb_recv_data_varsize(CalcHandle* handle, DUSBVirtualPacket* vtl, uint32_t* declared_size, uint32_t est_size) { DUSBRawPacket raw; int i = 0; unsigned long alloc_size; int ret; VALIDATE_HANDLE(handle); VALIDATE_NONNULL(vtl); VALIDATE_NONNULL(declared_size); memset(&raw, 0, sizeof(raw)); do { ret = dusb_recv(handle, &raw); if (ret) { break; } if (raw.type != DUSB_RPKT_VIRT_DATA && raw.type != DUSB_RPKT_VIRT_DATA_LAST) { ticalcs_critical("Unexpected raw packet type"); ret = ERR_INVALID_PACKET; break; } if (!i++) { // first packet has a data header if (raw.size < DUSB_DH_SIZE) { ticalcs_critical("First raw packet is too small"); ret = ERR_INVALID_PACKET; break; } if (raw.size > sizeof(raw.data)) { ticalcs_critical("Raw packet is too large: %u bytes", raw.size); ret = ERR_INVALID_PACKET; break; } *declared_size = (((uint32_t)raw.data[0]) << 24) | (((uint32_t)raw.data[1]) << 16) | (((uint32_t)raw.data[2]) << 8) | (((uint32_t)raw.data[3]) << 0); alloc_size = (*declared_size > 10000 ? 10000 : *declared_size); if (alloc_size < raw.size - DUSB_DH_SIZE) { alloc_size = raw.size - DUSB_DH_SIZE; } vtl->type = (((uint16_t)raw.data[4]) << 8) | (raw.data[5] << 0); vtl->data = g_realloc(vtl->data, alloc_size); if (vtl->data != NULL) { memcpy(vtl->data, &raw.data[DUSB_DH_SIZE], raw.size - DUSB_DH_SIZE); } vtl->size = raw.size - DUSB_DH_SIZE; #if (VPKT_DBG == 2) ticalcs_info(" TI->PC: %s\n\t\t(size = %08x, type = %s)", raw.type == DUSB_RPKT_VIRT_DATA_LAST ? "Virtual Packet Data Final" : "Virtual Packet Data with Continuation", *declared_size, dusb_vpkt_type2name(vtl->type)); #elif (VPKT_DBG == 1) ticalcs_info(" TI->PC: %s", dusb_vpkt_type2name(vtl->type)); #endif if (vtl->data != NULL && vtl->type == 0xEE00) { ticalcs_info(" Error Code : %04x\n", (((int)vtl->data[0]) << 8) | vtl->data[1]); } } else { // others have more data if (vtl->size + raw.size > alloc_size) { if (vtl->size + raw.size <= est_size) { alloc_size = est_size; } else { alloc_size = (vtl->size + raw.size) * 2; } vtl->data = g_realloc(vtl->data, alloc_size); } memcpy(vtl->data + vtl->size, raw.data, raw.size); vtl->size += raw.size; #if (VPKT_DBG == 2) ticalcs_info(" TI->PC: %s", raw.type == DUSB_RPKT_VIRT_DATA_LAST ? "Virtual Packet Data Final" : "Virtual Packet Data with Continuation"); #endif if (raw.type == DUSB_RPKT_VIRT_DATA_LAST) { handle->updat->max1 = vtl->size; } else if (vtl->size < *declared_size) { handle->updat->max1 = *declared_size; } else if (vtl->size < est_size) { handle->updat->max1 = est_size; } else { handle->updat->max1 = vtl->size + raw.size; } handle->updat->cnt1 = vtl->size; handle->updat->pbar(); } workaround_recv(handle, &raw, vtl); ret = dusb_send_acknowledge(handle); if (ret) { break; } } while (raw.type != DUSB_RPKT_VIRT_DATA_LAST); //printf("dusb_recv_data: rpkt.size=%d\n", raw.size); return ret; }
// beware: data field may be re-allocated in size ! TIEXPORT3 int TICALL dusb_recv_data(CalcHandle* h, DUSBVirtualPacket* vtl) { DUSBRawPacket raw; int i = 0; long offset = 0; if (h == NULL) { ticalcs_critical("%s: h is NULL", __FUNCTION__); return ERR_INVALID_HANDLE; } if (vtl == NULL) { ticalcs_critical("%s: vtl is NULL", __FUNCTION__); return ERR_INVALID_PACKET; } memset(&raw, 0, sizeof(raw)); do { TRYF(dusb_recv(h, &raw)); if(raw.type != DUSB_RPKT_VIRT_DATA && raw.type != DUSB_RPKT_VIRT_DATA_LAST) return ERR_INVALID_PACKET; if(!i++) { // first packet has a data header vtl->size = (raw.data[0] << 24) | (raw.data[1] << 16) | (raw.data[2] << 8) | (raw.data[3] << 0); vtl->type = (uint16_t)((raw.data[4] << 8) | (raw.data[5] << 0)); vtl->data = g_realloc(vtl->data, vtl->size); memcpy(vtl->data, &raw.data[DUSB_DH_SIZE], raw.size - DUSB_DH_SIZE); offset = raw.size - DUSB_DH_SIZE; #if (VPKT_DBG == 2) ticalcs_info(" TI->PC: %s\n\t\t(size = %08x, type = %s)", raw.type == DUSB_RPKT_VIRT_DATA_LAST ? "Virtual Packet Data Final" : "Virtual Packet Data with Continuation", vtl->size, dusb_vpkt_type2name(vtl->type)); #elif (VPKT_DBG == 1) ticalcs_info(" TI->PC: %s", dusb_vpkt_type2name(vtl->type)); #endif if(vtl->type == 0xEE00) ticalcs_info(" Error Code : %04x\n", (vtl->data[0] << 8) | vtl->data[1]); } else { // others have more data memcpy(vtl->data + offset, raw.data, raw.size); offset += raw.size; #if (VPKT_DBG == 2) ticalcs_info(" TI->PC: %s", raw.type == DUSB_RPKT_VIRT_DATA_LAST ? "Virtual Packet Data Final" : "Virtual Packet Data with Continuation"); #endif h->updat->max1 = vtl->size; h->updat->cnt1 += DATA_SIZE; h->updat->pbar(); } workaround_recv(h, &raw, vtl); TRYF(dusb_send_acknowledge(h)); } while(raw.type != DUSB_RPKT_VIRT_DATA_LAST); //printf("dusb_recv_data: rpkt.size=%d\n", raw.size); return 0; }