CW_THREAD_RETURN_TYPE CWSTARoamingOP(void * arg){ wid_pid_write_v2("CWSTARoamingOP",0,vrrid); int nIndex = 0; unsigned char WLANID; char *command = NULL; command = (char*)WID_MALLOC(128); if (NULL == command) { return NULL; } //============================================= //printf("created roaming thread\n"); while(1){ CWThreadMutexLock(&(gSTARoamingMutex)); CWWaitThreadCondition(&gSTARoamingWait, &gSTARoamingMutex); CWThreadMutexUnlock(&gSTARoamingMutex); CWThreadMutexLock(&(gSTARoamingMutex)); memset(command, 0, 128); if(STA_ROAM.STAOP == 0){ sprintf(command,"iwpriv ath%d addmac %02X:%02X:%02X:%02X:%02X:%02X\n",STA_ROAM.WLANDomain,STA_ROAM.STAMAC[0],STA_ROAM.STAMAC[1],STA_ROAM.STAMAC[2],STA_ROAM.STAMAC[3],STA_ROAM.STAMAC[4],STA_ROAM.STAMAC[5]); }else{ sprintf(command,"iwpriv ath%d delmac %02X:%02X:%02X:%02X:%02X:%02X\n",STA_ROAM.WLANDomain,STA_ROAM.STAMAC[0],STA_ROAM.STAMAC[1],STA_ROAM.STAMAC[2],STA_ROAM.STAMAC[3],STA_ROAM.STAMAC[4],STA_ROAM.STAMAC[5]); } // printf("CWSTARoamingOP :%s\n",command); WLANID = STA_ROAM.WLANDomain; for(nIndex=0;nIndex<WTP_NUM;nIndex++){ if((AC_WTP[nIndex] != NULL)&&(AC_WLAN[WLANID] != NULL)&&(AC_WLAN[WLANID]->S_WTP_BSS_List[nIndex][0] > 0)) wid_radio_set_extension_command(nIndex,command); } CWThreadMutexUnlock(&gSTARoamingMutex); } }
void CWWTP_get_WTP_Rates(unsigned char *buf){ CWThreadMutexLock(&mutext_info); memcpy( buf, WTP_Rates, 8 ); CWThreadMutexUnlock(&mutext_info); }
void CW80211ManagementFrameEvent(struct nl_handle **handleMgmt, cw_sock_handler handler, void * cb, struct WTPBSSInfo * BSSInfo) { //Set file descriptor of socket to non-blocking state nl_socket_set_nonblocking(*handleMgmt); int nlSocketFDmgmt = nl_socket_get_fd(*handleMgmt); CWBool exitThread=CW_FALSE; while(1) { //On delete BSS CWThreadMutexLock(&(BSSInfo->bssMutex)); exitThread = BSSInfo->destroyBSS; CWThreadMutexUnlock(&(BSSInfo->bssMutex)); if(exitThread == CW_TRUE) CWExitThread(); int result; fd_set readset; do { FD_ZERO(&readset); FD_SET(nlSocketFDmgmt, &readset); result = select(nlSocketFDmgmt + 1, &readset, NULL, NULL, NULL); } while (result == -1 && errno == EINTR); if (result > 0) { if (FD_ISSET(nlSocketFDmgmt, &readset)) { handler(cb, (*handleMgmt)); } } else if (result < 0) { CWLog("Error on select(): %s", strerror(errno)); } } }
__inline__ int CWACGetActiveWTPs() { int tmp; if(!CWErr(CWThreadMutexLock(&gActiveWTPsMutex))) return 0; tmp = gActiveWTPs; CWThreadMutexUnlock(&gActiveWTPsMutex); return tmp; }
unsigned char CWTP_get_WTP_Radio_Information(){ unsigned char tmp_info; CWThreadMutexLock(&mutext_info); tmp_info = WTP_Radio_Information; CWThreadMutexUnlock(&mutext_info); return tmp_info; }
static void CWSslLockingFunc(int mode, int n, const char *file, int line) { if (mode & CRYPTO_LOCK) CWThreadMutexLock(&mutexOpensslBuf[n]); else CWThreadMutexUnlock(&mutexOpensslBuf[n]); return; }
CW_THREAD_RETURN_TYPE CWDynamicChannelSelection(void * arg) { wid_pid_write_v2("CWDynamicChannelSelection",0,vrrid); int ret; int i; /*int num = WTP_NUM;*/ WTP_RRM_INFO **WTP; //gCOUNTRYCODE = 2; WTP = WID_MALLOC(WTP_NUM*sizeof(WTP_RRM_INFO *)); if (NULL == WTP) return NULL; for(i = 0; i < WTP_NUM; i++){ WTP[i] = NULL; } while(1){ //int ok = 0; //printf("1\n"); CWThreadMutexLock(&(gACChannelMutex)); CWWaitThreadCondition(&gACChannelWait, &gACChannelMutex); CWThreadMutexUnlock(&gACChannelMutex); //CWThreadMutexLock(&(gACChannelMutex)); /*if(num < WTP_NUM){ WTP = realloc(WTP,WTP_NUM*(sizeof(WTP_RRM_INFO *))); if (NULL == WTP) { return NULL; } for(i=num;i<WTP_NUM;i++) WTP[i] = NULL; num = WTP_NUM; }*//*无效代码,不会执行*/ //printf("2\n"); if(channel_state){ gCOUNTRYCODE = 2; //printf("3\n"); ret = get_wtps_info(WTP); //printf("4\n"); if(ret) Dynamic_Channel_Selection(WTP); } //CWThreadMutexUnlock(&gACChannelMutex); //int i; for(i=0;i<WTP_NUM;i++){ if((WTP[i] != NULL)&&(AC_WTP[i] != NULL)){ //CWThreadMutexLock(&(gACChannelMutex)); WID_RADIO_SET_CHAN(AC_WTP[i]->WFR_Index, WTP[i]->channel); //CWThreadMutexUnlock(&gACChannelMutex); wid_syslog_debug_debug(WID_WTPINFO,"WTP %d Channel %d\n",i,WTP[i]->channel); memset(WTP[i],0,sizeof(WTP_RRM_INFO)); WID_FREE(WTP[i]); WTP[i] = NULL; } } } }
__inline__ int CWACGetActiveWTPs() { int tmp; if(!CWErr(CWThreadMutexLock(&gActiveWTPsMutex))) { CWLog("F:%s L:%d Error locking mutex",__FILE__,__LINE__); return 0; } tmp = gActiveWTPs; CWThreadMutexUnlock(&gActiveWTPsMutex); return tmp; }
int get_wtps_info(WTP_RRM_INFO ** WTP){ int i = 0; unsigned char channel_list[4]; #if 0 unsigned char channel_list_1[4] = {1, 5, 9, 13}; unsigned char channel_list_2[4] = {1, 6, 11, 0}; if(gCOUNTRYCODE == 0) memcpy(channel_list, channel_list_1, 4); else memcpy(channel_list, channel_list_2, 4); #endif memcpy(channel_list, channelRange, 4); for(i = 0; i < WTP_NUM; i++){ if((AC_WTP[i] != NULL)&&(AC_WTP[i]->WTPStat == 5)) { if(WTP[i] == NULL){ WTP[i] = WID_MALLOC(sizeof(WTP_RRM_INFO)); if(WTP[i] == NULL){ //perror(malloc); return 0; } } CWThreadMutexLock(&(gWTPs[i].RRMThreadMutex)); memset(WTP[i],0,sizeof(WTP_RRM_INFO)); WTP[i]->WTPID = i; WTP[i]->channel = AC_WTP[i]->WTP_Radio[0]->Radio_Chan; WTP[i]->flags = 0; WTP[i]->txpower = AC_WTP[i]->WTP_Radio[0]->Radio_TXP; if(WTP[i] != NULL){ memcpy(WTP[i]->H_channel_list, channel_list, 4); } else { wid_syslog_err("%s %d pointer is NULL\n",__FUNCTION__,__LINE__); } get_neighbor_wtps_info(WTP[i]); CWThreadMutexUnlock(&(gWTPs[i].RRMThreadMutex)); //printf("%d,%d,%d\n",WTP[i]->WTPID_List[0],WTP[i]->WTPID_List[1],WTP[i]->WTPID_List[2]); } } return 1; }
int CWGetFragmentID() { static int fragID = 0; int r; if (!CWThreadMutexLock(&gCreateIDMutex)) { CWDebugLog("Error Locking a mutex"); } r = fragID; if (fragID == CW_MAX_FRAGMENT_ID) fragID = 0; else fragID++; CWThreadMutexUnlock(&gCreateIDMutex); return r; }
unsigned int CWGetSeqNum() { static unsigned int seqNum = 0; unsigned int r; if (!CWThreadMutexLock(&gCreateIDMutex)) { CWDebugLog("Error Locking a mutex"); } r = seqNum; if (seqNum == CW_MAX_SEQ_NUM) seqNum = 0; else seqNum++; CWThreadMutexUnlock(&gCreateIDMutex); return r; }
CWBool ACEnterRun(int WTPIndex, CWProtocolMessage *msgPtr, CWBool dataFlag) { CWBool toSend = CW_FALSE, timerSet = CW_TRUE; CWControlHeaderValues controlVal; CWProtocolMessage* messages = NULL; int messagesCount = 0; unsigned char StationMacAddr[MAC_ADDR_LEN]; char string[10]; char socketctl_path_name[50]; char socketserv_path_name[50]; msgPtr->offset = 0; // cancel NeighborDeadTimer timer CWStopNeighborDeadTimer(WTPIndex); timerSet = CW_FALSE; if (dataFlag) { /* We have received a Data Message... now just log this event and do actions by the dataType */ CWLog("--> Received a DATA Message"); if (msgPtr->data_msgType == CW_DATA_MSG_FRAME_TYPE) { /*Retrive mac address station from msg*/ memset(StationMacAddr, 0, MAC_ADDR_LEN); memcpy(StationMacAddr, msgPtr->msg + SOURCE_ADDR_START, MAC_ADDR_LEN); int seqNum = CWGetSeqNum(); //Send a Station Configuration Request if (CWAssembleStationConfigurationRequest(&(gWTPs[WTPIndex].messages), &(gWTPs[WTPIndex].messagesCount), gWTPs[WTPIndex].pathMTU, seqNum, StationMacAddr)) { if (CWACSendAcknowledgedPacket(WTPIndex, CW_MSG_TYPE_VALUE_STATION_CONFIGURATION_RESPONSE, seqNum)) return CW_TRUE; else CWACStopRetransmission(WTPIndex); } } else { /************************************************************ * Update 2009: * * Manage special data packets with frequency * * statistics informations. * ************************************************************/ if (msgPtr->data_msgType == CW_DATA_MSG_FREQ_STATS_TYPE) { int cells; /* How many cell are heard */ int isAck; char * freqPayload; int socketIndex, indexToSend = htonl(WTPIndex); int sizeofAckInfoUnit = CW_FREQ_ACK_SIZE; int sizeofFreqInfoUnit = CW_FREQ_CELL_INFO_PAYLOAD_SIZE; int sizeOfPayload = 0, payload_offset = 0; /*----------------------------------------------------------------------------------------------- * Payload Management ( infos for frequency application) : * Ack Structure : | WTPIndex | Ack Value | * Freq Info Structure : | WTPIndex | Number of cells | Frequecies Info Payload | *-----------------------------------------------------------------------------------------------*/ memcpy(&isAck, msgPtr->msg, sizeof(int)); isAck = ntohl(isAck); if (isAck == 0) { /* isnt an ack message */ memcpy(&cells, msgPtr->msg + sizeof(int), sizeof(int)); cells = ntohl(cells); sizeOfPayload = (cells * sizeofFreqInfoUnit) + (2 * sizeof(int)); } else { sizeOfPayload = sizeofAckInfoUnit; } if ((freqPayload = malloc(sizeOfPayload)) != NULL) { memset(freqPayload, 0, sizeOfPayload); memcpy(freqPayload, &indexToSend, sizeof(int)); payload_offset += sizeof(int); if (isAck == 0) { memcpy(freqPayload + payload_offset, msgPtr->msg + sizeof(int), sizeOfPayload - payload_offset); } else { memcpy(freqPayload + payload_offset, msgPtr->msg + sizeof(int), sizeOfPayload - payload_offset); } socketIndex = gWTPs[WTPIndex].applicationIndex; /**************************************************** * Forward payload to correct application * ****************************************************/ if (!CWErr(CWThreadMutexLock(&appsManager.socketMutex[socketIndex]))) { CWLog("[ACrunState]:: Error locking socket Application Mutex"); free(freqPayload); return CW_FALSE; } if (Writen(appsManager.appSocket[socketIndex], freqPayload, sizeOfPayload) < 0) { CWThreadMutexUnlock(&appsManager.socketMutex[socketIndex]); free(freqPayload); CWLog("[ACrunState]:: Error writing Message To Application"); return CW_FALSE; } CWThreadMutexUnlock(&appsManager.socketMutex[socketIndex]); free(freqPayload); } else CWLog("[ACrunState]:: Malloc error (payload to frequency application"); } if (msgPtr->data_msgType == CW_DATA_MSG_STATS_TYPE) { if (!UnixSocksArray[WTPIndex].data_stats_sock) { //Init Socket only the first time when the function is called if ((UnixSocksArray[WTPIndex].data_stats_sock = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) { CWDebugLog("Error creating socket for data send"); return CW_FALSE; } memset(&(UnixSocksArray[WTPIndex].clntaddr), (int) NULL, sizeof(UnixSocksArray[WTPIndex].clntaddr)); UnixSocksArray[WTPIndex].clntaddr.sun_family = AF_UNIX; //make unix socket client path name by index i snprintf(string, sizeof(string), "%d", WTPIndex); string[sizeof(string) - 1] = 0; strcpy(socketctl_path_name, SOCKET_PATH_AC); strcat(socketctl_path_name, string); strcpy(UnixSocksArray[WTPIndex].clntaddr.sun_path, socketctl_path_name); unlink(socketctl_path_name); memset(&(UnixSocksArray[WTPIndex].servaddr), (int) NULL, sizeof(UnixSocksArray[WTPIndex].servaddr)); UnixSocksArray[WTPIndex].servaddr.sun_family = AF_UNIX; //make unix socket server path name by index i strcpy(socketserv_path_name, SOCKET_PATH_RECV_AGENT); strcat(socketserv_path_name, string); strcpy(UnixSocksArray[WTPIndex].servaddr.sun_path, socketserv_path_name); CWDebugLog("%s\t%s", socketserv_path_name, socketctl_path_name); //fflush(stdout); } int nbytes; int totalBytesToSend = 0; bcopy((char*) msgPtr->msg, (char*) &totalBytesToSend, sizeof(unsigned int)); totalBytesToSend = ntohl(totalBytesToSend); int pDataLen = totalBytesToSend; //len of Monitoring Data //CWDebugLog("\n%s\t%s", socketserv_path_name, socketctl_path_name); CWDebugLog("Total bytes to send %d", totalBytesToSend); //Send data stats from AC thread to monitor client over unix socket nbytes = sendto(UnixSocksArray[WTPIndex].data_stats_sock, msgPtr->msg, pDataLen, 0, (struct sockaddr *) &(UnixSocksArray[WTPIndex].servaddr), sizeof(UnixSocksArray[WTPIndex].servaddr)); if (nbytes < 0) { CWDebugLog("Error sending data over socket"); perror("send error"); return CW_FALSE; } } } return CW_TRUE; } if (!(CWACParseGenericRunMessage(WTPIndex, msgPtr, &controlVal))) { /* Two possible errors: WRONG_ARG and INVALID_FORMAT * In the second case we have an unexpected response: ignore the * message and log the event. */ return CW_FALSE; } switch (controlVal.messageTypeValue) { case CW_MSG_TYPE_VALUE_CONFIGURE_UPDATE_RESPONSE: { CWProtocolResultCode resultCode; /*Update 2009: Store Protocol specific response data*/ CWProtocolVendorSpecificValues* protocolValues = NULL; if (!(CWParseConfigurationUpdateResponseMessage(msgPtr, controlVal.msgElemsLen, &resultCode, &protocolValues))) return CW_FALSE; CWACStopRetransmission(WTPIndex); if (timerSet) { if (!CWRestartNeighborDeadTimer(WTPIndex)) { CWDebugLog("CWRestartNeighborDeadTimer returned false"); CWCloseThread(); } } else { if (!CWStartNeighborDeadTimer(WTPIndex)) { CWDebugLog("CWStartNeighborDeadTimer returned false"); CWCloseThread(); } } //CWSaveConfigurationUpdateResponseMessage(resultCode, WTPIndex, protocolValues); if (resultCode == CW_PROTOCOL_SUCCESS) { CWDebugLog("Result Success for Configuration update!!"); //gWTPs[WTPIndex].isRequestClose = CW_TRUE; //CWSignalThreadCondition(&gWTPs[WTPIndex].interfaceWait); } /*if (gWTPs[WTPIndex].interfaceCommandProgress == CW_TRUE) { CWThreadMutexLock(&gWTPs[WTPIndex].interfaceMutex); gWTPs[WTPIndex].interfaceResult = 1; gWTPs[WTPIndex].interfaceCommandProgress = CW_FALSE; CWSignalThreadCondition(&gWTPs[WTPIndex].interfaceComplete); CWThreadMutexUnlock(&gWTPs[WTPIndex].interfaceMutex); }*/ break; } case CW_MSG_TYPE_VALUE_CHANGE_STATE_EVENT_REQUEST: { CWProtocolChangeStateEventRequestValues *valuesPtr; if (!(CWParseChangeStateEventRequestMessage2(msgPtr, controlVal.msgElemsLen, &valuesPtr))) return CW_FALSE; if (timerSet) { if (!CWRestartNeighborDeadTimer(WTPIndex)) { CWCloseThread(); } } else { if (!CWStartNeighborDeadTimer(WTPIndex)) { CWCloseThread(); } } if (!(CWSaveChangeStateEventRequestMessage(valuesPtr, &(gWTPs[WTPIndex].WTPProtocolManager)))) return CW_FALSE; if (!(CWAssembleChangeStateEventResponse(&messages, &messagesCount, gWTPs[WTPIndex].pathMTU, controlVal.seqNum))) return CW_FALSE; toSend = CW_TRUE; break; } case CW_MSG_TYPE_VALUE_ECHO_REQUEST: { if (!(CWParseEchoRequestMessage(msgPtr, controlVal.msgElemsLen))) return CW_FALSE; if (timerSet) { if (!CWRestartNeighborDeadTimer(WTPIndex)) { CWCloseThread(); } } else { if (!CWStartNeighborDeadTimer(WTPIndex)) { CWCloseThread(); } } if (!(CWAssembleEchoResponse(&messages, &messagesCount, gWTPs[WTPIndex].pathMTU, controlVal.seqNum))) return CW_FALSE; toSend = CW_TRUE; break; } case CW_MSG_TYPE_VALUE_STATION_CONFIGURATION_RESPONSE: { CWProtocolResultCode resultCode; if (!(CWParseStationConfigurationResponseMessage(msgPtr, controlVal.msgElemsLen, &resultCode))) return CW_FALSE; CWACStopRetransmission(WTPIndex); if (timerSet) { if (!CWRestartNeighborDeadTimer(WTPIndex)) { CWCloseThread(); } } else { if (!CWStartNeighborDeadTimer(WTPIndex)) { CWCloseThread(); } } //CWSaveStationConfigurationResponseMessage(resultCode, WTPIndex); <-- Must be Implemented ???? break; } case CW_MSG_TYPE_VALUE_CLEAR_CONFIGURATION_RESPONSE: { CWProtocolResultCode resultCode; if (!(CWParseClearConfigurationResponseMessage(msgPtr, controlVal.msgElemsLen, &resultCode))) return CW_FALSE; CWACStopRetransmission(WTPIndex); if (timerSet) { if (!CWRestartNeighborDeadTimer(WTPIndex)) { CWCloseThread(); } } else { if (!CWStartNeighborDeadTimer(WTPIndex)) { CWCloseThread(); } } if (gWTPs[WTPIndex].interfaceCommandProgress == CW_TRUE) { CWThreadMutexLock(&gWTPs[WTPIndex].interfaceMutex); gWTPs[WTPIndex].interfaceResult = 1; gWTPs[WTPIndex].interfaceCommandProgress = CW_FALSE; CWSignalThreadCondition(&gWTPs[WTPIndex].interfaceComplete); CWThreadMutexUnlock(&gWTPs[WTPIndex].interfaceMutex); } break; } case CW_MSG_TYPE_VALUE_DATA_TRANSFER_REQUEST: { CWProtocolWTPDataTransferRequestValues valuesPtr; if (!(CWParseWTPDataTransferRequestMessage(msgPtr, controlVal.msgElemsLen, &valuesPtr))) return CW_FALSE; if (timerSet) { if (!CWRestartNeighborDeadTimer(WTPIndex)) { CWCloseThread(); } } else { if (!CWStartNeighborDeadTimer(WTPIndex)) { CWCloseThread(); } } if (!(CWAssembleWTPDataTransferResponse(&messages, &messagesCount, gWTPs[WTPIndex].pathMTU, controlVal.seqNum))) return CW_FALSE; toSend = CW_TRUE; break; } case CW_MSG_TYPE_VALUE_WTP_EVENT_REQUEST: { CWProtocolWTPEventRequestValues valuesPtr; if (!(CWParseWTPEventRequestMessage(msgPtr, controlVal.msgElemsLen, &valuesPtr))) return CW_FALSE; if (timerSet) { if (!CWRestartNeighborDeadTimer(WTPIndex)) { CWCloseThread(); } } else { if (!CWStartNeighborDeadTimer(WTPIndex)) { CWCloseThread(); } } if (!(CWSaveWTPEventRequestMessage(&valuesPtr, &(gWTPs[WTPIndex].WTPProtocolManager)))) return CW_FALSE; if (!(CWAssembleWTPEventResponse(&messages, &messagesCount, gWTPs[WTPIndex].pathMTU, controlVal.seqNum))) return CW_FALSE; toSend = CW_TRUE; break; } default: /* * We have an unexpected request and we have to send * a corresponding response containing a failure result code */ CWLog("--> Not valid Request in Run State... we send a failure Response"); if (timerSet) { if (!CWRestartNeighborDeadTimer(WTPIndex)) { CWCloseThread(); } } else { if (!CWStartNeighborDeadTimer(WTPIndex)) { CWCloseThread(); } } if (!(CWAssembleUnrecognizedMessageResponse(&messages, &messagesCount, gWTPs[WTPIndex].pathMTU, controlVal.seqNum, controlVal.messageTypeValue + 1))) return CW_FALSE; toSend = CW_TRUE; /*return CWErrorRaise(CW_ERROR_INVALID_FORMAT, "Message not valid in Run State");*/ } if (toSend) { int i; CWDebugLog("There is something so send..."); if (messages == NULL) return CWErrorRaise(CW_ERROR_WRONG_ARG, NULL); for (i = 0; i < messagesCount; i++) { #ifdef CW_NO_DTLS if(!CWNetworkSendUnsafeUnconnected(gWTPs[WTPIndex].socket, &gWTPs[WTPIndex].address, messages[i].msg, messages[i].offset) ) { #else if (!(CWSecuritySend(gWTPs[WTPIndex].session, messages[i].msg, messages[i].offset))) { #endif CWFreeMessageFragments(messages, messagesCount); CW_FREE_OBJECT(messages); return CW_FALSE; } } CWFreeMessageFragments(messages, messagesCount); CW_FREE_OBJECT(messages); } gWTPs[WTPIndex].currentState = CW_ENTER_RUN; gWTPs[WTPIndex].subState = CW_WAITING_REQUEST; CWDebugLog("Coming out of ACEnterRun.."); return CW_TRUE; } CWBool CWACParseGenericRunMessage(int WTPIndex, CWProtocolMessage *msg, CWControlHeaderValues* controlVal) { if (msg == NULL || controlVal == NULL) return CWErrorRaise(CW_ERROR_WRONG_ARG, NULL); if (!(CWParseControlHeader(msg, controlVal))) /* will be handled by the caller */ return CW_FALSE; /* skip timestamp */ controlVal->msgElemsLen -= CW_CONTROL_HEADER_OFFSET_FOR_MSG_ELEMS; /* Check if it is a request */ if (controlVal->messageTypeValue % 2 == 1) { return CW_TRUE; } if ((gWTPs[WTPIndex].responseSeqNum != controlVal->seqNum) || (gWTPs[WTPIndex].responseType != controlVal->messageTypeValue)) { CWDebugLog("gWTPs: %d\n", gWTPs[WTPIndex].responseSeqNum); CWDebugLog("controlVal: %d\n", controlVal->seqNum); CWErrorRaise(CW_ERROR_INVALID_FORMAT, "Seq Num or Msg Type not valid!"); return CW_FALSE; } return CW_TRUE; } /*Update 2009: Added vendValues to include a response payload (to pass response data)*/ CWBool CWParseConfigurationUpdateResponseMessage(CWProtocolMessage* msgPtr, int len, CWProtocolResultCode* resultCode, CWProtocolVendorSpecificValues** vendValues) { int offsetTillMessages; if (msgPtr == NULL || resultCode == NULL) return CWErrorRaise(CW_ERROR_WRONG_ARG, NULL); if ((msgPtr->msg) == NULL) return CWErrorRaise(CW_ERROR_WRONG_ARG, NULL); offsetTillMessages = msgPtr->offset; CWLog("Parsing Configuration Update Response..."); /* parse message elements */ while ((msgPtr->offset - offsetTillMessages) < len) { unsigned short int elemType = 0; unsigned short int elemLen = 0; CWParseFormatMsgElem(msgPtr, &elemType, &elemLen); switch (elemType) { case CW_MSG_ELEMENT_RESULT_CODE_CW_TYPE: *resultCode = CWProtocolRetrieve32(msgPtr); break; /*Update 2009: Added case to implement conf update response with payload*/ case CW_MSG_ELEMENT_RESULT_CODE_CW_TYPE_WITH_PAYLOAD: { int payloadSize = 0; CW_CREATE_OBJECT_ERR(*vendValues, CWProtocolVendorSpecificValues, return CWErrorRaise(CW_ERROR_OUT_OF_MEMORY, NULL);); *resultCode = CWProtocolRetrieve32(msgPtr); if (CWProtocolRetrieve16(msgPtr) != CW_MSG_ELEMENT_VENDOR_SPEC_PAYLOAD_CW_TYPE) /*For now, we only have UCI payloads, so we will accept only vendor payloads for protocol data*/ return CWErrorRaise(CW_ERROR_INVALID_FORMAT, "Unrecognized Message Element in Configuration Update Response"); (*vendValues)->vendorPayloadType = CWProtocolRetrieve16(msgPtr); switch ((*vendValues)->vendorPayloadType) { case CW_MSG_ELEMENT_VENDOR_SPEC_PAYLOAD_UCI: payloadSize = CWProtocolRetrieve32(msgPtr); if (payloadSize != 0) { (*vendValues)->payload = (void *) CWProtocolRetrieveStr(msgPtr, payloadSize); } else (*vendValues)->payload = NULL; break; case CW_MSG_ELEMENT_VENDOR_SPEC_PAYLOAD_WUM: payloadSize = CWProtocolRetrieve32(msgPtr); if (payloadSize <= 0) { /* Payload can't be zero here, * at least the message type must be specified */ return CWErrorRaise(CW_ERROR_INVALID_FORMAT, "Unrecognized Message Element in Configuration Update Response"); } (*vendValues)->payload = (void *) CWProtocolRetrieveRawBytes(msgPtr, payloadSize); break; default: return CWErrorRaise(CW_ERROR_INVALID_FORMAT, "Unrecognized Message Element in Configuration Update Response"); break; } } break; default: return CWErrorRaise(CW_ERROR_INVALID_FORMAT, "Unrecognized Message Element in Configuration Update Response"); break; } }
CWBool CWWTPSendAcknowledgedPacket(int seqNum, CWList msgElemlist, CWBool (assembleFunc)(CWProtocolMessage **, int *, int, int, CWList), CWBool (parseFunc)(char*, int, int, void*), CWBool (saveFunc)(void*), void *valuesPtr) { CWProtocolMessage *messages = NULL; CWProtocolMessage msg; int fragmentsNum = 0, i; struct timespec timewait; int gTimeToSleep = gCWRetransmitTimer; int gMaxTimeToSleep = CW_ECHO_INTERVAL_DEFAULT/2; msg.msg = NULL; if(!(assembleFunc(&messages, &fragmentsNum, gWTPPathMTU, seqNum, msgElemlist))) { goto cw_failure; } gWTPRetransmissionCount= 0; while(gWTPRetransmissionCount < gCWMaxRetransmit) { CWDebugLog("Transmission Num:%d", gWTPRetransmissionCount); for(i = 0; i < fragmentsNum; i++) { #ifdef CW_NO_DTLS if(!CWNetworkSendUnsafeConnected(gWTPSocket, messages[i].msg, messages[i].offset)) #else if(!CWSecuritySend(gWTPSession, messages[i].msg, messages[i].offset)) #endif { CWDebugLog("Failure sending Request"); goto cw_failure; } } timewait.tv_sec = time(0) + gTimeToSleep; timewait.tv_nsec = 0; CW_REPEAT_FOREVER { CWThreadMutexLock(&gInterfaceMutex); if (CWGetCountElementFromSafeList(gPacketReceiveList) > 0) CWErrorRaise(CW_ERROR_SUCCESS, NULL); else { if (CWErr(CWWaitThreadConditionTimeout(&gInterfaceWait, &gInterfaceMutex, &timewait))) CWErrorRaise(CW_ERROR_SUCCESS, NULL); } CWThreadMutexUnlock(&gInterfaceMutex); switch(CWErrorGetLastErrorCode()) { case CW_ERROR_TIME_EXPIRED: { gWTPRetransmissionCount++; goto cw_continue_external_loop; break; } case CW_ERROR_SUCCESS: { /* there's something to read */ if(!(CWReceiveMessage(&msg))) { CW_FREE_PROTOCOL_MESSAGE(msg); CWDebugLog("Failure Receiving Response"); goto cw_failure; } if(!(parseFunc(msg.msg, msg.offset, seqNum, valuesPtr))) { if(CWErrorGetLastErrorCode() != CW_ERROR_INVALID_FORMAT) { CW_FREE_PROTOCOL_MESSAGE(msg); CWDebugLog("Failure Parsing Response"); goto cw_failure; } else { CWErrorHandleLast(); { gWTPRetransmissionCount++; goto cw_continue_external_loop; } break; } } if((saveFunc(valuesPtr))) { goto cw_success; } else { if(CWErrorGetLastErrorCode() != CW_ERROR_INVALID_FORMAT) { CW_FREE_PROTOCOL_MESSAGE(msg); CWDebugLog("Failure Saving Response"); goto cw_failure; } } break; } case CW_ERROR_INTERRUPTED: { gWTPRetransmissionCount++; goto cw_continue_external_loop; break; } default: { CWErrorHandleLast(); CWDebugLog("Failure"); goto cw_failure; break; } } } cw_continue_external_loop: CWDebugLog("Retransmission time is over"); gTimeToSleep<<=1; if ( gTimeToSleep > gMaxTimeToSleep ) gTimeToSleep = gMaxTimeToSleep; } /* too many retransmissions */ return CWErrorRaise(CW_ERROR_NEED_RESOURCE, "Peer Dead"); cw_success: for(i = 0; i < fragmentsNum; i++) { CW_FREE_PROTOCOL_MESSAGE(messages[i]); } CW_FREE_OBJECT(messages); CW_FREE_PROTOCOL_MESSAGE(msg); return CW_TRUE; cw_failure: if(messages != NULL) { for(i = 0; i < fragmentsNum; i++) { CW_FREE_PROTOCOL_MESSAGE(messages[i]); } CW_FREE_OBJECT(messages); } CWDebugLog("Failure"); return CW_FALSE; }
int CWConvertDataFrame_8023_to_80211(unsigned char *frameReceived, int frameLen, unsigned char *outbuffer, int * WTPIndex){ //CWLog("Ricevuto frame, devo convertire"); int offset=0; unsigned char * hdr80211; unsigned char SA[ETH_ALEN]; unsigned char DA[ETH_ALEN]; unsigned char BSSID[ETH_ALEN]; int sizeEncapsHdr=0, skipBytes=0; nodeAVL* tmpNode=NULL; CW_COPY_MEMORY(DA, frameReceived, ETH_ALEN); CW_COPY_MEMORY(SA, frameReceived+ETH_ALEN, ETH_ALEN); if(checkAddressBroadcast(DA)) { memset(BSSID, 0xff, ETH_ALEN); *(WTPIndex) = -1; } else { //---- Search AVL node CWThreadMutexLock(&mutexAvlTree); tmpNode = AVLfind(DA, avlTree); //AVLdisplay_avl(avlTree); CWThreadMutexUnlock(&mutexAvlTree); if(tmpNode == NULL) { //CWLog("STA[%02x:%02x:%02x:%02x:%02x:%02x] non associata. Ignoro", (int) DA[0], (int) DA[1], (int) DA[2], (int) DA[3], (int) DA[4], (int) DA[5]); return -1; } else { //CWLog("STA trovata[%02x:%02x:%02x:%02x:%02x:%02x]", (int) DA[0], (int) DA[1], (int) DA[2], (int) DA[3], (int) DA[4], (int) DA[5]); CW_COPY_MEMORY(BSSID, tmpNode->BSSID, ETH_ALEN); // CWLog("Trovato BSSID[%02x:%02x:%02x:%02x:%02x:%02x]", (int) BSSID[0], (int) BSSID[1], (int) BSSID[2], (int) BSSID[3], (int) BSSID[4], (int) BSSID[5]); *(WTPIndex) = tmpNode->index; } //---- } /* CWLog("FRAME ETHERNET RICEVUTO"); CWLog("DA[%02x:%02x:%02x:%02x:%02x:%02x]", (int) DA[0], (int) DA[1], (int) DA[2], (int) DA[3], (int) DA[4], (int) DA[5]); CWLog("SA[%02x:%02x:%02x:%02x:%02x:%02x]", (int) SA[0], (int) SA[1], (int) SA[2], (int) SA[3], (int) SA[4], (int) SA[5]); */ hdr80211 = CW80211AssembleDataFrameHdr(SA, DA, BSSID, 0, &(offset), 0, 1); // CWLog("Byte dopo eth addr: %02x %02x", (int)(frameReceived+ETH_ALEN+ETH_ALEN)[0], (int)(frameReceived+ETH_ALEN+ETH_ALEN)[1]); int ethertype = (frameReceived[12] << 8) | frameReceived[13]; CW_COPY_MEMORY(outbuffer, hdr80211, HLEN_80211); //Encaps header // CWLog("ETHERTYPE: %02x", ethertype); if (ethertype == ETH_P_AARP || ethertype == ETH_P_IPX) { CW_COPY_MEMORY((outbuffer+HLEN_80211), bridge_tunnel_header, sizeof(bridge_tunnel_header)); skipBytes=2; sizeEncapsHdr=sizeof(bridge_tunnel_header); // CW_COPY_MEMORY((outbuffer+HLEN_80211+sizeof(bridge_tunnel_header)), &(sizeEncapsHdr), 2); } else if (ethertype >= ETH_P_802_3_MIN) { CW_COPY_MEMORY((outbuffer+HLEN_80211), rfc1042_header, sizeof(rfc1042_header)); skipBytes=2; sizeEncapsHdr=sizeof(rfc1042_header); //CW_COPY_MEMORY((outbuffer+HLEN_80211+sizeof(rfc1042_header)), &(sizeEncapsHdr), 2); } else sizeEncapsHdr=0; CW_COPY_MEMORY((outbuffer+HLEN_80211+sizeEncapsHdr), (frameReceived+ETH_HLEN-skipBytes), frameLen-ETH_HLEN+skipBytes); // CWLog("Byte dopo llc: %02x %02x", (int)(outbuffer+HLEN_80211+sizeEncapsHdr)[0], (int)(outbuffer+HLEN_80211+sizeEncapsHdr)[1]); // CWLog("DIMENSIONE NUOVO 80211 frame: %d WTPIndex: %d", (frameLen-ETH_HLEN+skipBytes+HLEN_80211+sizeEncapsHdr), *(WTPIndex)); return (frameLen-ETH_HLEN+skipBytes+HLEN_80211+sizeEncapsHdr); }