static int memory_read(BIO *b, char *out, int outl) { int ret = -1; char* buf; int size; BIO_memory_data* pData = (BIO_memory_data*)b->ptr; // //BIO_clear_retry_flags(b); // CWLockSafeList(pData->pRecvAddress); // Used only in DTLS handshake while (CWGetCountElementFromSafeList(pData->pRecvAddress) == 0){ CWWaitElementFromSafeList(pData->pRecvAddress); } buf = (char*)CWRemoveHeadElementFromSafeList(pData->pRecvAddress, &size); CWUnlockSafeList(pData->pRecvAddress); if ((buf == NULL) || (size <= 0)) CWLog("Warning empty buffer"); else { ret = ((size < outl) ? size : outl) - 4; memcpy(out, buf + 4, ret); CW_FREE_OBJECT(buf); } return ret; }
/* * Manage DTLS packets. */ CW_THREAD_RETURN_TYPE CWWTPReceiveDtlsPacket(void *arg) { int readBytes; unsigned char buf[CW_BUFFER_SIZE]; CWSocket sockDTLS = (long) arg; CWNetworkLev4Address addr; char *pData; CW_REPEAT_FOREVER { if (!CWErr(CWNetworkReceiveUnsafe(sockDTLS, buf, CW_BUFFER_SIZE - 1, 0, &addr, &readBytes))) { if (CWErrorGetLastErrorCode() == CW_ERROR_INTERRUPTED) continue; break; } /* Clone data packet */ CW_CREATE_OBJECT_SIZE_ERR(pData, readBytes, { CWLog("Out Of Memory"); return NULL; } ); memcpy(pData, buf, readBytes); CWLockSafeList(gPacketReceiveList); CWAddElementToSafeListTailwitDataFlag(gPacketReceiveList, pData, readBytes, CW_FALSE); CWUnlockSafeList(gPacketReceiveList); }
/* * Receive a message, that can be fragmented. This is useful not only for the Join State */ CWBool CWReceiveMessage(CWProtocolMessage *msgPtr) { CWList fragments = NULL; int readBytes; char buf[CW_BUFFER_SIZE]; CWBool dataFlag = CW_FALSE; CW_REPEAT_FOREVER { CW_ZERO_MEMORY(buf, CW_BUFFER_SIZE); #ifdef CW_NO_DTLS char *pkt_buffer = NULL; CWLockSafeList(gPacketReceiveList); while (CWGetCountElementFromSafeList(gPacketReceiveList) == 0) CWWaitElementFromSafeList(gPacketReceiveList); pkt_buffer = (char*)CWRemoveHeadElementFromSafeListwithDataFlag(gPacketReceiveList, &readBytes,&dataFlag); CWUnlockSafeList(gPacketReceiveList); CW_COPY_MEMORY(buf, pkt_buffer, readBytes); CW_FREE_OBJECT(pkt_buffer); #else if(!CWSecurityReceive(gWTPSession, buf, CW_BUFFER_SIZE, &readBytes)) {return CW_FALSE;} #endif if(!CWProtocolParseFragment(buf, readBytes, &fragments, msgPtr, &dataFlag, NULL)) { if(CWErrorGetLastErrorCode() == CW_ERROR_NEED_RESOURCE) { // we need at least one more fragment continue; } else { // error CWErrorCode error; error=CWErrorGetLastErrorCode(); switch(error) { case CW_ERROR_SUCCESS: {CWDebugLog("ERROR: Success"); break;} case CW_ERROR_OUT_OF_MEMORY: {CWDebugLog("ERROR: Out of Memory"); break;} case CW_ERROR_WRONG_ARG: {CWDebugLog("ERROR: Wrong Argument"); break;} case CW_ERROR_INTERRUPTED: {CWDebugLog("ERROR: Interrupted"); break;} case CW_ERROR_NEED_RESOURCE: {CWDebugLog("ERROR: Need Resource"); break;} case CW_ERROR_COMUNICATING: {CWDebugLog("ERROR: Comunicating"); break;} case CW_ERROR_CREATING: {CWDebugLog("ERROR: Creating"); break;} case CW_ERROR_GENERAL: {CWDebugLog("ERROR: General"); break;} case CW_ERROR_OPERATION_ABORTED: {CWDebugLog("ERROR: Operation Aborted"); break;} case CW_ERROR_SENDING: {CWDebugLog("ERROR: Sending"); break;} case CW_ERROR_RECEIVING: {CWDebugLog("ERROR: Receiving"); break;} case CW_ERROR_INVALID_FORMAT: {CWDebugLog("ERROR: Invalid Format"); break;} case CW_ERROR_TIME_EXPIRED: {CWDebugLog("ERROR: Time Expired"); break;} case CW_ERROR_NONE: {CWDebugLog("ERROR: None"); break;} } CWDebugLog("~~~~~~"); return CW_FALSE; } } else break; // the message is fully reassembled } return CW_TRUE; }
CW_THREAD_RETURN_TYPE CWWTPThread_read_data_from_hostapd(void *arg) { /* CWThreadMutexLock(&gRADIO_MAC_mutex); gRADIO_MAC[0]=0xAA; gRADIO_MAC[1]=0xBB; gRADIO_MAC[2]=0xCC; gRADIO_MAC[3]=0xDD; gRADIO_MAC[4]=0xEE; gRADIO_MAC[5]=0xFF; CWThreadMutexUnlock(&gRADIO_MAC_mutex); */ int len; #if defined(LOCALUDP) struct sockaddr_un server; #else #if defined(USEIPV6) struct sockaddr_in6 server; #else struct sockaddr_in server; #endif #endif unsigned char buffer[CW_BUFFER_SIZE]; int connect_ret; unsigned char cmd[10]; CWProtocolMessage *frame = NULL; CWBindingDataListElement *listElement = NULL; CWThreadSetSignals(SIG_BLOCK, 1, SIGALRM); #if defined(LOCALUDP) sock = socket(AF_UNIX, SOCK_DGRAM, 0); #elif defined(NETUDP) #if defined(USEIPV6) bzero(&server, sizeof(server)); sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); #else memset(&server, 0, sizeof(server)); sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); #endif #else #if defined(USEIPV6) bzero(&server, sizeof(server)); sock = socket(AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP); #else memset(&server, 0, sizeof(server)); sock = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); #endif #endif if (sock < 0) { CWDebugLog("WTP ipc HOSTAPD: Error creating socket"); EXIT_FRAME_THREAD(sock); } CWDebugLog("WTP ipc HOSTAPD: Trying to connect to hostapd (wtp)..."); #if defined(LOCALUDP) server.sun_family = AF_UNIX; strcpy(server.sun_path, gHostapd_unix_path); unlink(server.sun_path); connect_ret = bind(sock, (struct sockaddr *)&server, strlen(server.sun_path) + sizeof(server.sun_family)); client.sun_family = AF_UNIX; #else #if defined(USEIPV6) server.sin6_family = AF_INET6; server.sin6_port = gHostapd_port; server.sin6_addr = in6addr_any; #else server.sin_family = AF_INET; server.sin_port = gHostapd_port; server.sin_addr.s_addr = INADDR_ANY; #endif connect_ret = bind(sock, (struct sockaddr *)&server, sizeof(server)); #endif if (connect_ret == -1) { CWDebugLog("WTP ipc HOSTAPD: Error connect/bind to socket"); EXIT_FRAME_THREAD(sock); } #if defined(LOCALUDP) #elif defined(NETUDP) #else /* 1: Only one daemon Hostapd_WTP at time */ if (listen(sock, 1) < 0) { CWDebugLog("WTP ipc HOSTAPD: Error listen "); EXIT_FRAME_THREAD(sock); } #endif #if defined(LOCALUDP) CWDebugLog("Waiting packet from Hostapd_WTP at Pipe:%s", gHostapd_unix_path); #else CWDebugLog("Waiting packet from Hostapd_WTP at Port:%d", gHostapd_port); #endif client.sin_family = AF_INET; client.sin_addr.s_addr = inet_addr("127.0.0.1"); client.sin_port = htons(6444); address_size = sizeof(client); int sig_byte = 1; #if defined(LOCALUDP) sig_byte += 5; #endif CWDebugLog("Checking if hostapd is started already"); cmd[0] = CONNECT_R; sendto(sock, cmd, 1, 0, (struct sockaddr *)&client, address_size); cmd[0] = WTPRINFO; //Next info to get sendto(sock, cmd, 1, 0, (struct sockaddr *)&client, address_size); CW_REPEAT_FOREVER { len = recvfrom(sock, buffer, sizeof(buffer), 0, (struct sockaddr *)&client, &address_size); #if defined(LOCALUDP) sprintf(client.sun_path, "%s%c%c%c%c%c", server.sun_path, buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); #endif if (len <= 0) { EXIT_FRAME_THREAD(sock) } if (connected == 0 && buffer[0] != CONNECT && buffer[0] != WTPRINFO_R) { CWDebugLog("IPC packet - WTP is not in RUN state"); CWWTPsend_command_to_hostapd_CLOSE(cmd, 10); continue; } if (buffer[0] == DATE_TO_AC) { if (!wtpInRunState) continue; if (!extract802_11_Frame(&frame, buffer + sig_byte, len - sig_byte)) { CWLog("THR FRAME: Error extracting a frame"); EXIT_FRAME_THREAD(sock); } CWDebugLog("Send 802.11 management(len:%d) to AC", len - 1); CW_CREATE_OBJECT_ERR(listElement, CWBindingDataListElement, EXIT_FRAME_THREAD(sock); ); listElement->frame = frame; listElement->bindingValues = NULL; listElement->frame->data_msgType = CW_IEEE_802_11_FRAME_TYPE; CWLockSafeList(gFrameList); CWAddElementToSafeListTail(gFrameList, listElement, sizeof(CWBindingDataListElement)); CWUnlockSafeList(gFrameList); } else if (buffer[0] == CONNECT) {
CWBool CWWTPCheckForBindingFrame() { // CWLockSafeList(gFrameList); while (CWGetCountElementFromSafeList(gFrameList) > 0) { CWBindingDataListElement* dataFirstElem = CWRemoveHeadElementFromSafeList(gFrameList, NULL); if (dataFirstElem) { int k; int fragmentsNum = 0; CWProtocolMessage *completeMsgPtr = NULL; if (!CWAssembleDataMessage(&completeMsgPtr, &fragmentsNum, gWTPPathMTU, dataFirstElem->frame, dataFirstElem->bindingValues, #ifdef CW_NO_DTLS CW_PACKET_PLAIN #else (gDtlsSecurity == 1)?CW_PACKET_CRYPT:CW_PACKET_PLAIN /* 0-CW_PACKET_PLAIN, 1-CW_PACKET_CRYPT */ #endif )) { for(k = 0; k < fragmentsNum; k++) { CW_FREE_PROTOCOL_MESSAGE(completeMsgPtr[k]); } CW_FREE_OBJECT(completeMsgPtr); CW_FREE_PROTOCOL_MESSAGE(*(dataFirstElem->frame)); CW_FREE_OBJECT(dataFirstElem->frame); CW_FREE_OBJECT(dataFirstElem->bindingValues); CW_FREE_OBJECT(dataFirstElem); continue; } for (k = 0; k < fragmentsNum; k++) { #ifndef CW_NO_DTLS if(gDtlsSecurity == 1) { if (!CWSecuritySend(gWTPSession, completeMsgPtr[k].msg, completeMsgPtr[k].offset)) { CWDebugLog("Failure sending Request"); break; //gzm break don't unlockSafeList ??? } } else #endif { if (!CWNetworkSendUnsafeUnconnected(gWTPSocket, &(gACInfoPtr->preferredAddress), completeMsgPtr[k].msg, completeMsgPtr[k].offset)) { CWDebugLog("Failure sending Request"); break; //gzm break don't unlockSafeList ??? } } } for (k = 0; k < fragmentsNum; k++) { CW_FREE_PROTOCOL_MESSAGE(completeMsgPtr[k]); } CW_FREE_OBJECT(completeMsgPtr); CW_FREE_PROTOCOL_MESSAGE(*(dataFirstElem->frame)); CW_FREE_OBJECT(dataFirstElem->frame); CW_FREE_OBJECT(dataFirstElem->bindingValues); CW_FREE_OBJECT(dataFirstElem); } } CWUnlockSafeList(gFrameList); return CW_TRUE; }