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);
	}
Exemple #3
0
/* 
 * 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;
}