AJ_Status AJ_Net_RecvFrom(AJ_IOBuffer* buf, uint32_t len, uint32_t timeout) { AJ_InfoPrintf(("AJ_Net_RecvFrom(buf=0x%p, len=%d., timeout=%d.)\n", buf, len, timeout)); AJ_Status status = AJ_OK; int ret; uint32_t rx = AJ_IO_BUF_SPACE(buf); unsigned long Recv_lastCall = millis(); AJ_InfoPrintf(("AJ_Net_RecvFrom(): len %d, rx %d, timeout %d\n", len, rx, timeout)); rx = min(rx, len); while ((g_clientUDP.parsePacket() == 0) && (millis() - Recv_lastCall < timeout)) { delay(10); // wait for data or timeout } AJ_InfoPrintf(("AJ_Net_RecvFrom(): millis %d, Last_call %d, timeout %d, Avail %d\n", millis(), Recv_lastCall, timeout, g_clientUDP.available())); ret = g_clientUDP.read(buf->writePtr, rx); AJ_InfoPrintf(("AJ_Net_RecvFrom(): read() returns %d, rx %d\n", ret, rx)); if (ret == -1) { AJ_InfoPrintf(("AJ_Net_RecvFrom(): read() fails. status=AJ_ERR_READ\n")); status = AJ_ERR_READ; } else { if (ret != -1) { AJ_DumpBytes("AJ_Net_RecvFrom", buf->writePtr, ret); } buf->writePtr += ret; AJ_InfoPrintf(("AJ_Net_RecvFrom(): status=AJ_OK\n")); status = AJ_OK; } AJ_InfoPrintf(("AJ_Net_RecvFrom(): status=%s\n", AJ_StatusText(status))); return status; }
AJ_Status AJ_Net_RecvFrom(AJ_IOBuffer* buf, uint32_t len, uint32_t timeout) { //AJ_InfoPrintf(("AJ_Net_RecvFrom(buf=0x%p, len=%d., timeout=%d.)\n", buf, len, timeout)); AJ_Status status = AJ_OK; int ret; uint32_t rx = AJ_IO_BUF_SPACE(buf); unsigned long Recv_lastCall = millis(); // printf("AJ_Net_RecvFrom(): len %d, rx %d, timeout %d\n", len, rx, timeout); // rx = min(rx, len); while ((sock_rx_state==0) && (millis() - Recv_lastCall < timeout)) { //printf("millis() - Recv_lastCall = %d \n", (millis() - Recv_lastCall)); recv(rx_socket, udp_data_rx, MAIN_WIFI_M2M_BUFFER_SIZE, 0); m2m_wifi_handle_events(NULL); } ret=sock_rx_state; // printf("AJ_Net_RecvFrom(): millis %d, Last_call %d, timeout %d, Avail %d\n", millis(), Recv_lastCall, timeout, g_clientUDP.available()); //ret = g_clientUDP.read(buf->writePtr, rx); //AJ_InfoPrintf(("AJ_Net_RecvFrom(): read() returns %d, rx %d\n", ret, rx)); if (ret == -1) { printf("AJ_Net_RecvFrom(): read() fails. status=AJ_ERR_READ\n"); status = AJ_ERR_READ; } else { if (ret != -1) { AJ_DumpBytes("AJ_Net_RecvFrom", buf->writePtr, ret); } buf->writePtr += ret; // printf("AJ_Net_RecvFrom(): status=AJ_OK\n"); status = AJ_OK; } printf("AJ_Net_RecvFrom(): status=%s\n", AJ_StatusText(status)); return /*sock_rx_state;*/status; }
int AJ_Main() { AJ_Status status; memset(&txBuffer, 'T', sizeof(txBuffer)); memset(&rxBuffer, 'R', sizeof(rxBuffer)); int blocks; int blocksize = LOCAL_DATA_PACKET_SIZE; for (blocks = 0; blocks < 16; blocks++) { memset(txBuffer + (blocks * blocksize), 0x41 + (uint8_t)blocks, blocksize); } #ifdef READTEST status = AJ_SerialInit("/dev/ttyUSB0", BITRATE, AJ_SERIAL_WINDOW_SIZE, AJ_SERIAL_PACKET_SIZE); #else status = AJ_SerialInit("/dev/ttyUSB1", BITRATE, AJ_SERIAL_WINDOW_SIZE, AJ_SERIAL_PACKET_SIZE); #endif AJ_AlwaysPrintf(("serial init was %u\n", status)); #ifdef READTEST AJ_Sleep(2000); // wait for the writing side to be running, this should test the queuing of data. // try to read everything at once int i = 0; //for ( ; i < 10000; ++i) { while (1) { AJ_SerialRecv(rxBuffer, sizeof(rxBuffer), 50000, NULL); } /* //Read small chunks of a packet at one time. for (blocks = 0 ; blocks < 16*4; blocks++) { AJ_SerialRecv(rxBuffer+(blocks*blocksize/4), blocksize/4, 2000, NULL); // AJ_Sleep(200); } */ AJ_DumpBytes("Post serial recv", rxBuffer, sizeof(rxBuffer)); AJ_Sleep(500); #else AJ_Sleep(5000); int i = 0; while (1) { AJ_SerialSend(txBuffer, sizeof(txBuffer)); ++i; if (i % 500 == 0) { AJ_AlwaysPrintf(("Hit iteration %d\n", i)); } } AJ_AlwaysPrintf(("post serial send\n")); #endif while (1) { AJ_StateMachine(); } return(0); }
void AJ_WSL_WMI_ProcessWMIEvent(AJ_BufNode* pNodeHTCBody) { uint16_t eventID; uint16_t info1; uint16_t reserved; int32_t dataUnmarshaled; dataUnmarshaled = WMI_Unmarshal(pNodeHTCBody->buffer, "qqq", &eventID, &info1, &reserved); switch (eventID) { case WSL_WMI_READY_EVENTID: { uint8_t capability; dataUnmarshaled += WMI_Unmarshal(pNodeHTCBody->buffer + dataUnmarshaled, "uuMy", &AJ_WSL_TargetFirmware.target_ver, &AJ_WSL_TargetFirmware.abi_ver, &deviceMAC, &capability); AJ_InfoPrintf(("WMI_READY, version A %08lx, version B %08lx capability %x\n", AJ_WSL_TargetFirmware.target_ver, AJ_WSL_TargetFirmware.abi_ver, capability)); AJ_InfoPrintf(("Device MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", deviceMAC[0], deviceMAC[1], deviceMAC[2], deviceMAC[3], deviceMAC[4], deviceMAC[5])); AJ_WSL_HTC_Global.started = TRUE; break; } case WSL_BSS_INFO_EVENTID: { extern void AJ_WSL_BSSINFO_Recv(AJ_BufNode* node); AJ_WSL_BSSINFO_Recv(pNodeHTCBody); break; } case WSL_CMDERROR_EVENTID: { uint16_t commandId; uint8_t error; dataUnmarshaled += WMI_Unmarshal(pNodeHTCBody->buffer + dataUnmarshaled, "qy", &commandId, &error); AJ_InfoPrintf(("WMI_CMDERROR, last command %04x, error code %02x \n", commandId, error)); break; } case WSL_WMI_SCAN_COMPLETE_EVENTID: { // now signal the waiting code that the scan has completed // we can do this by posting an item to the global socket context recv queue // the client will pull off a scan complete event and then continue. wsl_work_item* scanCompleteResponse; wsl_work_item** pItem; scanCompleteResponse = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(scanCompleteResponse, 0, sizeof(wsl_work_item)); scanCompleteResponse->itemType = WSL_NET_SCAN; scanCompleteResponse->node = AJ_BufNodeCreateAndTakeOwnership(pNodeHTCBody); pItem = &scanCompleteResponse; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[0].workRxQueue, pItem, AJ_TIMER_FOREVER); break; } case WSL_WMI_DISCONNECT_EVENTID: { uint16_t protocolReason; uint8_t bssid[6]; uint16_t disconnectReason; WMI_Unmarshal(pNodeHTCBody->buffer + dataUnmarshaled, "qMq", &protocolReason, &bssid, &disconnectReason); AJ_InfoPrintf(("WMI_DISCONNECT event: protocolReason %x, disconnectReason %x\n", protocolReason, disconnectReason)); if (AJ_WSL_WifiConnectCallback) { (AJ_WSL_WifiConnectCallback)(0); } // now signal the waiting code that the scan has completed // we can do this by posting an item to the global socket context recv queue // the client will pull off a scan complete event and then continue. wsl_work_item* disconnectResponse; wsl_work_item** pItem; disconnectResponse = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(disconnectResponse, 0, sizeof(wsl_work_item)); disconnectResponse->itemType = WSL_NET_DISCONNECT; disconnectResponse->node = AJ_BufNodeCreateAndTakeOwnership(pNodeHTCBody); pItem = &disconnectResponse; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[0].workRxQueue, pItem, AJ_TIMER_FOREVER); break; } case WSL_WMI_CONNECT_EVENTID: { // now signal the waiting code that the scan has completed // we can do this by posting an item to the global socket context recv queue // the client will pull off a scan complete event and then continue. wsl_work_item* connectResponse; wsl_work_item** pItem; connectResponse = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(connectResponse, 0, sizeof(wsl_work_item)); connectResponse->itemType = WSL_NET_CONNECT; connectResponse->node = AJ_BufNodeCreateAndTakeOwnership(pNodeHTCBody); pItem = &connectResponse; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[0].workRxQueue, pItem, AJ_TIMER_FOREVER); if (AJ_WSL_WifiConnectCallback) { (AJ_WSL_WifiConnectCallback)(1); } break; } case WSL_WMI_SOCKET_RESPONSE_EVENTID: { uint32_t responseType; uint32_t socketHandle; uint32_t error; WMI_Unmarshal(pNodeHTCBody->buffer + dataUnmarshaled, "uuu", &responseType, &socketHandle, &error); int8_t socketIndex; //AJ_BufListNodePrintDump(pNodeHTCBody, NULL); /* look for the matching handle in the global context then mark it invalid */ switch (responseType) { // some of the commands operate on the global socket context case WSL_SOCK_OPEN: case WSL_SOCK_IPCONFIG: case WSL_SOCK_IP6CONFIG: case WSL_SOCK_STACK_INIT: case WSL_SOCK_IP_HOST_NAME: socketIndex = 0; break; default: { socketIndex = AJ_WSL_FindSocketContext(socketHandle); if (socketIndex == INVALID_SOCKET) { AJ_DumpBytes("INVALID SOCKET DUMP", pNodeHTCBody->buffer, pNodeHTCBody->length); AJ_WarnPrintf(("SOCKET_PING response for invalid socket!\n")); break; } } } if (socketIndex != INVALID_SOCKET) { AJ_Status status = AJ_OK; //push a work item into the Read queue if (status == AJ_OK) { wsl_work_item** ppWork; wsl_work_item* sockResp; sockResp = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(sockResp, 0, sizeof(wsl_work_item)); sockResp->itemType = AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, responseType); //sockResp->size = payloadSize; sockResp->node = AJ_BufNodeCreateAndTakeOwnership(pNodeHTCBody); ppWork = &sockResp; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[socketIndex].workRxQueue, ppWork, AJ_TIMER_FOREVER); } if ((responseType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CLOSE)) && (socketIndex != INVALID_SOCKET)) { AJ_WSL_SOCKET_CONTEXT[socketIndex].targetHandle = UINT32_MAX; AJ_WSL_SOCKET_CONTEXT[socketIndex].valid = FALSE; } } break; } case WSL_WMI_PEER_NODE_EVENTID: { uint8_t reason; WMI_Unmarshal(pNodeHTCBody->buffer + dataUnmarshaled, "q", &reason); if ((reason == 0) /*&& (AJ_WSL_connectState == AJ_WIFI_CONNECTING)*/) { /* * The 4-way handshake is complete, indicate the state has changed */ if (AJ_WSL_WifiConnectCallback) { (AJ_WSL_WifiConnectCallback)(16 /*RSNA_AUTH_SUCCESS*/); } } break; } // There are several WMI events that aren't parsed. case WSL_REGDOMAIN_EVENTID: case WSL_UNKNOWN2_EVENTID: case WSL_UNKNOWN1_EVENTID: break; default: { AJ_InfoPrintf(("Unknown WMI Event %x\n", eventID)); return; } } AJ_InfoPrintf(("Processed WMI Event: %s\n", WSL_WorkItemText(eventID))); }
int main() { AJ_Status status; memset(&txBuffer, 'T', sizeof(txBuffer)); memset(&rxBuffer, 'R', sizeof(rxBuffer)); int blocks; int blocksize = LOCAL_DATA_PACKET_SIZE; for (blocks = 0; blocks < 16; blocks++) { memset(txBuffer + (blocks * blocksize), 0x41 + (uint8_t)blocks, blocksize); } #ifdef READTEST status = AJ_SerialInit("/tmp/COM0", BITRATE, AJ_SERIAL_WINDOW_SIZE, AJ_SERIAL_ENABLE_CRC, AJ_SERIAL_PACKET_SIZE); #else status = AJ_SerialInit("/tmp/COM1", BITRATE, AJ_SERIAL_WINDOW_SIZE, AJ_SERIAL_ENABLE_CRC, AJ_SERIAL_PACKET_SIZE); #endif AJ_Printf("serial init was %u\n", status); uint32_t timerEndProc = 9999; status = AJ_TimerRegister(100000, &TimerCallbackEndProc, NULL, &timerEndProc); AJ_Printf("Added id %u\n", timerEndProc); int iter; int i; #ifdef READTEST AJ_Sleep(2000); // wait for the writing side to be running, this should test the queuing of data. for (iter = 0; iter < 10; iter++) { AJ_Printf("iteration %d\n########################################################################\n", iter); AJ_SerialRecv(rxBuffer, sizeof(rxBuffer), 10000, NULL); if (0 == memcmp(txBuffer, rxBuffer, sizeof(rxBuffer))) { AJ_Printf("Passed#: buffers match.\n"); } else { AJ_Printf("FAILED#: buffers mismatch.\n"); AJ_DumpBytes("RXBUFFER:", rxBuffer, sizeof(rxBuffer)); AJ_DumpBytes("TXBUFFER:", txBuffer, sizeof(txBuffer)); exit(-1); } //AJ_SerialSend(txBuffer, sizeof(txBuffer)); } AJ_Printf("post serial recv\n"); AJ_Sleep(4000); #else AJ_Sleep(500); for (iter = 0; iter < 10; iter++) { printf("iteration %d\n########################################################################\n", iter); AJ_SerialSend(txBuffer, sizeof(txBuffer)); /*AJ_SerialRecv(rxBuffer, sizeof(rxBuffer), 10000, NULL); if (0 == memcmp(txBuffer, rxBuffer, sizeof(rxBuffer))) { AJ_Printf("Passed##: buffers match.\n"); } else { AJ_Printf("FAILED##: buffers mismatch.\n"); AJ_DumpBytes("RXBUFFER:", rxBuffer, sizeof(rxBuffer)); AJ_DumpBytes("TXBUFFER:", txBuffer, sizeof(txBuffer)); exit(-1); }*/ } AJ_Printf("post serial send\n"); AJ_Sleep(4000); #endif /*while (1) { usleep(4000); }*/ return(0); }
AJ_Status AJ_Net_Recv(AJ_IOBuffer* buf, uint32_t len, uint32_t timeout) { AJ_Status status = AJ_ERR_READ; uint32_t ret; uint32_t rx = AJ_IO_BUF_SPACE(buf); uint32_t recvd = 0; unsigned long Recv_lastCall = millis(); // first we need to clear out our buffer uint32_t M = 0; //printf("AJ_Net_Recv(buf=0x%p, len=%d., timeout=%d.)\n", buf, len, timeout); if (rxLeftover != 0) { // there was something leftover from before, // printf("AJ_NetRecv(): leftover was: %d\n", rxLeftover); M = min(rx, rxLeftover); memcpy(buf->writePtr, rxDataStash, M); // copy leftover into buffer. buf->writePtr += M; // move the data pointer over memmove(rxDataStash, rxDataStash + M, rxLeftover - M); // shift left-overs toward the start. rxLeftover -= M; recvd += M; // we have read as many bytes as we can // higher level isn't requesting any more if (recvd == rx) { // printf("AJ_Net_Recv(): status=AJ_OK\n"); return AJ_OK; } } if ((M != 0) && (rxLeftover != 0)) { printf("AJ_Net_REcv(): M was: %d, rxLeftover was: %d\n", M, rxLeftover); } //printf("NetRecv before while: tcp_data_rx[0]= %d\n", tcp_data_rx[0]); while ((tcp_rx_ready==0) && (millis() - Recv_lastCall < timeout)) { // recv(tcp_client_socket, gau8SocketTestBuffer, sizeof(gau8SocketTestBuffer), 0); recv(tcp_client_socket, tcp_data_rx, sizeof(tcp_data_rx), 0); // recv(tcp_client_socket, buf->writePtr, sizeof(tcp_data_rx), 0); m2m_wifi_handle_events(NULL); } // printf("NetRecv: tcp_data_rx[0]= %d\n", tcp_data_rx[0]); if (tcp_rx_ready==0) { printf("AJ_Net_Recv(): timeout. status=AJ_ERR_TIMEOUT\n"); status = AJ_ERR_TIMEOUT; } else { memcpy(AJ_in_data_tcp, tcp_data_rx,tcp_rx_ready); uint32_t askFor = rx; askFor -= M; ret=tcp_rx_ready; // printf("AJ_Net_Recv(): ask for: %d\n", askFor); if (askFor < ret) { printf("AJ_Net_Recv(): BUFFER OVERRUN: askFor=%u, ret=%u\n", askFor, ret); } if (ret == -1) { printf("AJ_Net_Recv(): read() failed. status=AJ_ERR_READ\n"); status = AJ_ERR_READ; } else { // printf("AJ_Net_Recv(): ret now %d\n", ret); AJ_DumpBytes("Recv", buf->writePtr, ret); if (ret > askFor) { printf("AJ_Net_Recv(): new leftover %d\n", ret - askFor); // now shove the extra into the stash memcpy(rxDataStash + rxLeftover, buf->writePtr + askFor, ret - askFor); rxLeftover += (ret - askFor); buf->writePtr += rx; } else { buf->writePtr += ret; } status = AJ_OK; } } // printf("!!!!!!!!!!!!!!!buf->writePtr=%x\n",buf->writePtr); tcp_rx_ready=0; return status; }
int AJ_Main() { AJ_Status status; while (1) { int windows = 1 << (rand() % 3); // randomize window width 1,2,4 int blocksize = 50 + (rand() % 1000); // randomize packet size 50 - 1050 AJ_AlwaysPrintf(("Windows:%i Blocksize:%i\n", windows, blocksize)); txBuffer = (uint8_t*) AJ_Malloc(blocksize); rxBuffer = (uint8_t*) AJ_Malloc(blocksize); memset(txBuffer, 0x41, blocksize); memset(rxBuffer, 'r', blocksize); #ifdef READTEST status = AJ_SerialInit("/dev/ttyUSB0", BITRATE, windows, blocksize); #else status = AJ_SerialInit("/dev/ttyUSB1", BITRATE, windows, blocksize); #endif AJ_AlwaysPrintf(("serial init was %u\n", status)); if (status != AJ_OK) { continue; // init failed perhaps from bad parameters, start the loop again } // Change the buffer transmission function to one that fuzzes the output. AJ_SetTxSerialTransmit(&FuzzBuffer); #ifdef READTEST AJ_Sleep(2000); // wait for the writing side to be running, this should test the queuing of data. // try to read everything at once int i = 0; while (1) { AJ_SerialRecv(rxBuffer, blocksize, 50000, NULL); } AJ_DumpBytes("Post serial recv", rxBuffer, blocksize); AJ_Sleep(500); #else AJ_Sleep(5000); int i = 0; while (1) { // change the packet to be sent every time through the loop. memset(txBuffer, 0x41 + (i % 26), blocksize); memset(rxBuffer, 0x41 + (i % 26), blocksize); AJ_SerialSend(txBuffer, blocksize); ++i; if (i % 20 == 0) { AJ_AlwaysPrintf(("Hit iteration %d\n", i)); break; } AJ_SerialRecv(rxBuffer, blocksize, 5000, NULL); } AJ_AlwaysPrintf(("post serial send\n")); #endif // clean up and start again AJ_SerialShutdown(); AJ_Free(txBuffer); AJ_Free(rxBuffer); } return(0); }
AJ_Status AJ_Net_Recv(AJ_IOBuffer* buf, uint32_t len, uint32_t timeout) { AJ_Status status = AJ_ERR_READ; uint32_t ret; uint32_t rx = AJ_IO_BUF_SPACE(buf); uint32_t recvd = 0; unsigned long Recv_lastCall = millis(); // first we need to clear out our buffer uint32_t M = 0; AJ_InfoPrintf(("AJ_Net_Recv(buf=0x%p, len=%d., timeout=%d.)\n", buf, len, timeout)); if (rxLeftover != 0) { // there was something leftover from before, AJ_InfoPrintf(("AJ_NetRecv(): leftover was: %d\n", rxLeftover)); M = min(rx, rxLeftover); memcpy(buf->writePtr, rxDataStash, M); // copy leftover into buffer. buf->writePtr += M; // move the data pointer over memmove(rxDataStash, rxDataStash + M, rxLeftover - M); // shift left-overs toward the start. rxLeftover -= M; recvd += M; // we have read as many bytes as we can // higher level isn't requesting any more if (recvd == rx) { AJ_InfoPrintf(("AJ_Net_Recv(): status=AJ_OK\n")); return AJ_OK; } } if ((M != 0) && (rxLeftover != 0)) { AJ_InfoPrintf(("AJ_Net_REcv(): M was: %d, rxLeftover was: %d\n", M, rxLeftover)); } // wait for data to become available // time out if nothing arrives while (g_client.connected() && g_client.available() == 0 && (millis() - Recv_lastCall < timeout)) { delay(50); // wait for data or timeout } // return timeout if nothing is available AJ_InfoPrintf(("AJ_Net_Recv(): millis %d, Last_call %d timeout %d Avail: %d\n", millis(), Recv_lastCall, timeout, g_client.available())); if (g_client.connected() && (millis() - Recv_lastCall >= timeout) && (g_client.available() == 0)) { AJ_InfoPrintf(("AJ_Net_Recv(): timeout. status=AJ_ERR_TIMEOUT\n")); return AJ_ERR_TIMEOUT; } if (g_client.connected()) { uint32_t askFor = rx; askFor -= M; AJ_InfoPrintf(("AJ_Net_Recv(): ask for: %d\n", askFor)); ret = g_client.read(buf->writePtr, askFor); AJ_InfoPrintf(("AJ_Net_Recv(): read(): ret %d askfor %d\n", ret, askFor)); if (askFor < ret) { AJ_InfoPrintf(("AJ_Net_Recv(): BUFFER OVERRUN: askFor=%u, ret=%u\n", askFor, ret)); } if (ret == -1) { AJ_ErrPrintf(("AJ_Net_Recv(): read() failed. status=AJ_ERR_READ\n")); status = AJ_ERR_READ; } else { AJ_InfoPrintf(("AJ_Net_Recv(): ret now %d\n", ret)); AJ_DumpBytes("Recv", buf->writePtr, ret); if (ret > askFor) { AJ_InfoPrintf(("AJ_Net_Recv(): new leftover %d\n", ret - askFor)); // now shove the extra into the stash memcpy(rxDataStash + rxLeftover, buf->writePtr + askFor, ret - askFor); rxLeftover += (ret - askFor); buf->writePtr += rx; } else { buf->writePtr += ret; } status = AJ_OK; } } return status; }
static AJ_Status AuthListenerCallback(uint32_t authmechanism, uint32_t command, AJ_Credential* cred) { AJ_Status status = AJ_ERR_INVALID; X509CertificateChain* node; AJ_AlwaysPrintf(("AuthListenerCallback authmechanism %08X command %d\n", authmechanism, command)); switch (authmechanism) { case AUTH_SUITE_ECDHE_NULL: cred->expiration = keyexpiration; status = AJ_OK; break; case AUTH_SUITE_ECDHE_PSK: switch (command) { case AJ_CRED_PUB_KEY: cred->data = (uint8_t*) psk_hint; cred->len = strlen(psk_hint); cred->expiration = keyexpiration; status = AJ_OK; break; case AJ_CRED_PRV_KEY: cred->data = (uint8_t*) psk_char; cred->len = strlen(psk_char); cred->expiration = keyexpiration; status = AJ_OK; break; } break; case AUTH_SUITE_ECDHE_ECDSA: switch (command) { case AJ_CRED_PRV_KEY: AJ_ASSERT(sizeof (AJ_ECCPrivateKey) == cred->len); status = AJ_DecodePrivateKeyPEM((AJ_ECCPrivateKey*) cred->data, pem_prv); cred->expiration = keyexpiration; break; case AJ_CRED_CERT_CHAIN: switch (cred->direction) { case AJ_CRED_REQUEST: // Free previous certificate chain AJ_X509FreeDecodedCertificateChain(chain); chain = AJ_X509DecodeCertificateChainPEM(pem_x509); if (NULL == chain) { return AJ_ERR_INVALID; } cred->data = (uint8_t*) chain; cred->expiration = keyexpiration; status = AJ_OK; break; case AJ_CRED_RESPONSE: node = (X509CertificateChain*) cred->data; while (node) { AJ_DumpBytes("CERTIFICATE", node->certificate.der.data, node->certificate.der.size); node = node->next; } status = AJ_OK; break; } break; } break; default: break; } return status; }
/* * read from the mailbox and do something useful with the HTC message. */ void AJ_WSL_HTC_ProcessIncoming(void) { uint16_t lenRead; uint8_t* bufRead; AJ_BufNode* pNodeHTCBody; uint8_t endpointID; uint8_t flags; uint16_t payloadLength; uint8_t controlBytes[2]; AJ_Status status; status = AJ_WSL_ReadFromMBox(AJ_WSL_SPI_MBOX_0, &lenRead, &bufRead); AJ_ASSERT(status == AJ_OK); // now create a AJ_BufList from the data we read pNodeHTCBody = AJ_BufListCreateNodeExternalZero(bufRead, lenRead, FALSE); pNodeHTCBody->flags = 0; // reset the AJ_BUFNODE_EXTERNAL_BUFFER flag, because I own this now. WMI_Unmarshal(pNodeHTCBody->buffer, "yyqyy", &endpointID, &flags, &payloadLength, &controlBytes[0], &controlBytes[1]); AJ_BufNodePullBytes(pNodeHTCBody, 6); //AJ_WSL_WMI_PrintMessage(pNodeHTCBody); AJ_DumpBytes("HTC_CONTROL", pNodeHTCBody->buffer, pNodeHTCBody->length); /* examine the endpoint of the HTC message*/ if ((flags & AJ_WSL_HTC_RECV_TRAILER_PRESENT) && ((payloadLength - controlBytes[0]) > 0)) { switch (endpointID) { case AJ_WSL_HTC_CONTROL_ENDPOINT: { uint16_t* messageID = (uint16_t*)pNodeHTCBody->buffer; AJ_InfoPrintf(("Read HTC control endpoint, messageID %x\n", *messageID)); switch (*messageID) { case AJ_WSL_HTC_MSG_READY_ID: { /* process the message and change state */ uint16_t readyMessageID; WMI_Unmarshal(pNodeHTCBody->buffer, "qqqyyy", &readyMessageID, &AJ_WSL_HTC_Global.creditCount, &AJ_WSL_HTC_Global.creditSize, &AJ_WSL_HTC_Global.maxEndpoints, &AJ_WSL_HTC_Global.HTCVersion, &AJ_WSL_HTC_Global.maxMessagesPerBundle); /* SIDE EFFECT */ AJ_WarnPrintf(("MSG_READY, credit count %x, credit size:%d\n", AJ_WSL_HTC_Global.creditCount, AJ_WSL_HTC_Global.creditSize)); AJ_WSL_HTC_Global.endpoints[AJ_WSL_HTC_CONTROL_ENDPOINT].state = AJ_WSL_HTC_UNINITIALIZED_RECV_READY; break; } case AJ_WSL_HTC_SERVICE_CONNECT_RESPONSE_ID: { AJ_WarnPrintf(("HTC MSG AJ_WSL_HTC_SERVICE_CONNECT_RESPONSE_ID\n")); break; } default: AJ_WarnPrintf(("HTC MSG ID unknown\n")); AJ_DumpBytes("WMI_SOCKET_RESPONSE", pNodeHTCBody->buffer, pNodeHTCBody->length); break; } break; } case AJ_WSL_HTC_DATA_ENDPOINT1: { // AJ_DumpBytes("DATA ENDPOINT WMI ", pNodeHTCBody->buffer, pNodeHTCBody->length); AJ_WSL_WMI_ProcessWMIEvent(pNodeHTCBody); break; } case AJ_WSL_HTC_DATA_ENDPOINT2: case AJ_WSL_HTC_DATA_ENDPOINT3: case AJ_WSL_HTC_DATA_ENDPOINT4: { AJ_DumpBytes("DATA ENDPOINT WMI_SOCKET_RESPONSE", pNodeHTCBody->bufferStart, pNodeHTCBody->length); AJ_WSL_WMI_ProcessSocketDataResponse(pNodeHTCBody); //AJ_InfoPrintf(("Read HTC data endpoint %d\n", htcHdr.endpointID)); // TODO send the data up to the next API level //AJ_WSL_WMI_PrintMessage(pNodeHTCBody); break; } default: AJ_ErrPrintf(("UNKNOWN Endpoint %d", endpointID)); AJ_ASSERT(FALSE); break; } } /* * Trailers can come on any packet */ if (flags & AJ_WSL_HTC_RECV_TRAILER_PRESENT) { uint16_t packetLength; uint8_t trailerLength = controlBytes[0]; packetLength = payloadLength - trailerLength; //AJ_InfoPrintf(("Read HTC RX trailer, length %d\n", htcHdr.controlBytes[0])); AJ_BufNodePullBytes(pNodeHTCBody, packetLength); // consume the packet, leave the trailer /* * handle multiple trailers per HTC message */ while (trailerLength) { uint8_t trailerType; uint8_t length; //AJ_BufListNodePrintDump(pNodeHTCBody, NULL); WMI_Unmarshal(pNodeHTCBody->buffer, "yy", &trailerType, &length); AJ_BufNodePullBytes(pNodeHTCBody, 2); // consume the trailer trailerLength -= 2; switch (trailerType) { case AJ_WSL_HTC_RXTRAILER_CREDIT_REPORT: { uint8_t credits; uint8_t endpoint; WMI_Unmarshal(pNodeHTCBody->buffer, "yy", &endpoint, &credits); AJ_InfoPrintf(("Add %d credits to endpoint %d\n", credits, endpoint)); AJ_WSL_HTC_Global.endpoints[endpoint].txCredits += credits; break; } default: { AJ_InfoPrintf(("HTC trailer: type not handled %d\n", trailerType)); } } trailerLength -= length; AJ_BufNodePullBytes(pNodeHTCBody, length); // consume the trailer } } //intentionally freeing the buffer here AJ_BufListFreeNodeAndBuffer(pNodeHTCBody, NULL); }
static AJ_Status DecodeCertificateExt(X509Certificate* certificate, DER_Element* der) { AJ_Status status; DER_Element tmp; DER_Element seq; DER_Element oid; DER_Element oct; uint8_t tags[] = { ASN_OID, ASN_OCTETS }; certificate->type = UNKNOWN_CERTIFICATE; status = AJ_ASN1DecodeElement(der, ASN_SEQ, &tmp); if (AJ_OK != status) { return status; } der->size = tmp.size; der->data = tmp.data; while ((AJ_OK == status) && (der->size)) { status = AJ_ASN1DecodeElement(der, ASN_SEQ, &seq); if (AJ_OK != status) { return status; } status = AJ_ASN1DecodeElements(&seq, tags, sizeof (tags), &oid, &oct); if (AJ_OK != status) { return status; } if (CompareOID(&oid, OID_BASIC_CONSTRAINTS, sizeof (OID_BASIC_CONSTRAINTS))) { status = AJ_ASN1DecodeElement(&oct, ASN_SEQ, &seq); if (AJ_OK != status) { return status; } status = AJ_ASN1DecodeElement(&seq, ASN_BOOLEAN, &tmp); if (AJ_OK != status) { return status; } } else if (CompareOID(&oid, OID_CUSTOM_CERT_TYPE, sizeof (OID_CUSTOM_CERT_TYPE))) { status = AJ_ASN1DecodeElement(&oct, ASN_SEQ, &seq); if (AJ_OK != status) { return status; } status = AJ_ASN1DecodeElement(&seq, ASN_INTEGER, &tmp); if (AJ_OK != status) { return status; } if (sizeof (uint32_t) < tmp.size) { return AJ_ERR_INVALID; } certificate->type = 0; while (tmp.size--) { certificate->type <<= 8; certificate->type |= *tmp.data++; } } else if (CompareOID(&oid, OID_SUB_ALTNAME, sizeof (OID_SUB_ALTNAME))) { certificate->alias.size = oct.size; certificate->alias.data = oct.data; } else if (CompareOID(&oid, OID_CUSTOM_DIGEST, sizeof (OID_CUSTOM_DIGEST))) { status = AJ_ASN1DecodeElement(&oct, ASN_SEQ, &seq); if (AJ_OK != status) { return status; } status = AJ_ASN1DecodeElements(&seq, tags, sizeof (tags), &oid, &oct); if (AJ_OK != status) { return status; } if (!CompareOID(&oid, OID_DIG_SHA256, sizeof (OID_DIG_SHA256))) { return AJ_ERR_INVALID; } if (SHA256_DIGEST_LENGTH != oct.size) { return AJ_ERR_INVALID; } memcpy(certificate->digest, oct.data, SHA256_DIGEST_LENGTH); } else { // Ignore extensions we don't know AJ_DumpBytes("UNKNOWN", oid.data, oid.size); AJ_DumpBytes("UNKNOWN", oct.data, oct.size); } } return status; }
/* * This test builds a ping response in a simulated wire buffer, and then parses the response */ static void run_wsl_simulate_state_machine(const struct test_case* test) { AJ_Status status = AJ_OK; uint16_t i; AJ_AlwaysPrintf(("\n\n**************\nTEST: %s\n\n", __FUNCTION__)); /* * reset the state of the simulated wire buffers */ memset(toTarget.fakeWireBuffer, 0, sizeof(toTarget.fakeWireBuffer)); toTarget.fakeWireCurr = toTarget.fakeWireBuffer; memset(fromTarget.fakeWireBuffer, 0, sizeof(fromTarget.fakeWireBuffer)); fromTarget.fakeWireCurr = fromTarget.fakeWireBuffer; ResetFakeWireBuffers(); /* * reset the state of the HTC endpoints */ memset(&AJ_WSL_HTC_Global, 0, sizeof(AJ_WSL_HTC_Global)); /* * TODO: prime the state machine by creating a HTC Ready packet and adding it to the simulated wirebufer */ { wsl_htc_hdr readyHdr; wsl_htc_msg_ready readyMsg; readyMsg.msg.messageID = AJ_WSL_HTC_MSG_READY_ID; readyMsg.creditCount = 20; readyMsg.creditSize = 512; readyMsg.HTCVersion = 0; readyMsg.maxEndpoints = 5; readyMsg.maxMessagesPerBundle = 1; AJ_WSL_HTC_MSG_READY_TO_WIRE(&readyMsg); readyHdr.endpointID = 0; readyHdr.flags = 0; readyHdr.controlBytes[0] = 0; readyHdr.controlBytes[1] = 0; readyHdr.payloadLength = sizeof(wsl_htc_msg_ready); AJ_WSL_HTC_HDR_TO_WIRE(&readyHdr); memcpy(fromTarget.fakeWireBuffer, &readyHdr, sizeof(readyHdr)); memcpy(fromTarget.fakeWireBuffer + sizeof(readyHdr), &readyMsg, sizeof(readyMsg)); } for (i = 0; i < 5; ++i) { switch (i) { case 0: case 1: case 2: { AJ_AlwaysPrintf(("Case %d send\n", i)); AJ_WSL_HTC_StateMachine(&AJ_WSL_HTC_Global.endpoints[0]); if (status != AJ_OK) { break; } break; } default: break; } // now send the thing. // now process the other side of the thing switch (i) { case 0: case 1: case 2: { AJ_AlwaysPrintf(("Case %d response\n", i)); AJ_WSL_HTC_StateMachine(&AJ_WSL_HTC_Global.endpoints[0]); if (status != AJ_OK) { break; } break; } default: break; } } AJ_DumpBytes(__FUNCTION__, fromTarget.fakeWireBuffer, sizeof(fromTarget.fakeWireBuffer)); }