Exemplo n.º 1
0
void* ILibCreateSSDPClientModule(void *chain, char* DeviceURN, int DeviceURNLength, void (*CallbackPtr)(void *sender, char* UDN, int Alive, char* LocationURL, int Timeout, void *user),void *user)
{
	int i;
	struct sockaddr_in addr;
	struct sockaddr_in dest_addr;
	struct SSDPClientModule *RetVal = (struct SSDPClientModule*)MALLOC(sizeof(struct SSDPClientModule));
	int ra = 1;
	struct ip_mreq mreq;
	char* buffer;
	int bufferlength;
	char* _DeviceURN;
	struct in_addr interface_addr;
	unsigned char TTL = 4;
	
	memset((char *)&addr, 0, sizeof(addr));
	memset((char *)&interface_addr, 0, sizeof(interface_addr));
	memset((char *)&(addr), 0, sizeof(dest_addr));
	
	dest_addr.sin_family = AF_INET;
	dest_addr.sin_addr.s_addr = inet_addr(UPNP_GROUP);
	dest_addr.sin_port = htons(UPNP_PORT);
	
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	addr.sin_port = htons(UPNP_PORT);	
	
	RetVal->Destroy = &ILibSSDPClientModule_Destroy;
	RetVal->PreSelect = &ILibSSDPClientModule_PreSelect;
	RetVal->PostSelect = &ILibSSDPClientModule_PostSelect;
	
	RetVal->Reserved = user;
	RetVal->Terminate = 0;
	RetVal->FunctionCallback = CallbackPtr;
	RetVal->DeviceURN = (char*)MALLOC(DeviceURNLength+1);
	memcpy(RetVal->DeviceURN,DeviceURN,DeviceURNLength);
	RetVal->DeviceURN[DeviceURNLength] = '\0';
	RetVal->DeviceURNLength = DeviceURNLength;
	
	RetVal->NumIPAddress = ILibGetLocalIPAddressList(&(RetVal->IPAddress));
	RetVal->SSDPListenSocket = socket(AF_INET, SOCK_DGRAM, 0);
	ILibGetDGramSocket(htonl(INADDR_ANY), &(RetVal->MSEARCH_Response_Socket));
	
	if (setsockopt(RetVal->MSEARCH_Response_Socket, IPPROTO_IP, IP_MULTICAST_TTL,(char*)&TTL, sizeof(TTL)) < 0)
	{
		/* Ignore this case */
	}
	if (setsockopt(RetVal->SSDPListenSocket, SOL_SOCKET, SO_REUSEADDR,(char*)&ra, sizeof(ra)) < 0)
	{
		DEBUGSTATEMENT(printf("Setting SockOpt SO_REUSEADDR failed\r\n"));
		exit(1);
	}
	if (bind(RetVal->SSDPListenSocket, (struct sockaddr *) &(addr), sizeof(addr)) < 0)
	{
		printf("SSDPListenSocket bind");
		exit(1);
	}
	
	for(i=0;i<RetVal->NumIPAddress;++i)
	{
		mreq.imr_multiaddr.s_addr = inet_addr(UPNP_GROUP);
		mreq.imr_interface.s_addr = RetVal->IPAddress[i];
		if (setsockopt(RetVal->SSDPListenSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,(char*)&mreq, sizeof(mreq)) < 0)
		{
			printf("SSDPListenSocket setsockopt mreq");
			exit(1);
		}
		
	}
	
	ILibAddToChain(chain,RetVal);
	_DeviceURN = (char*)MALLOC(DeviceURNLength+1);
	memcpy(_DeviceURN,DeviceURN,DeviceURNLength);
	_DeviceURN[DeviceURNLength] = '\0';
	buffer = (char*)MALLOC(105+DeviceURNLength);
	bufferlength = sprintf(buffer,"M-SEARCH * HTTP/1.1\r\nMX: 3\r\nST: %s\r\nHOST: 239.255.255.250:1900\r\nMAN: \"ssdp:discover\"\r\n\r\n",_DeviceURN);
	
	for(i=0;i<RetVal->NumIPAddress;++i)
	{
		interface_addr.s_addr = RetVal->IPAddress[i];
		/*  This is commented out, because setting MULTICAST_IF does not work on PPC2002 because of bug in kernal */
		//if (setsockopt(RetVal->MSEARCH_Response_Socket, IPPROTO_IP, IP_MULTICAST_IF,(char*)&interface_addr, sizeof(interface_addr)) == 0)
		//{
			sendto(RetVal->MSEARCH_Response_Socket, buffer, bufferlength, 0, (struct sockaddr *) &dest_addr, sizeof(dest_addr));
			//}
	}
	
	FREE(_DeviceURN);
	FREE(buffer);
	return(RetVal);
}
void ILibMiniWebServerProcessSocket(struct ILibMWSHTTPReaderObject *Reader)
{
	int bytesReceived;
	int i;
	struct packetheader_field_node *node;
	char* CharStar;
	
	if(Reader->BodySize==0)
	{
		/* Still Reading Headers */
		bytesReceived = recv(Reader->ClientSocket,Reader->Header+Reader->HeaderIndex,2048-Reader->HeaderIndex,0);
		if(bytesReceived==0)
		{
			if(Reader->PacketHeader!=NULL) {ILibDestructPacket(Reader->PacketHeader);}
			if(Reader->Body_MallocSize!=0) {FREE(Reader->Body);}
			Reader->Body = NULL;
			Reader->Body_MallocSize = 0;
			Reader->PacketHeader = NULL;
			closesocket(Reader->ClientSocket);
			Reader->ClientSocket = 0xFFFFFFFF;
			return;
		}
		Reader->HeaderIndex += bytesReceived;
		if(Reader->HeaderIndex>4)
		{
			/* Must have read at least 4 bytes to perform check */
			for(i=0;i<(Reader->HeaderIndex - 3);i++)
			{
				if (Reader->Header[i] == '\r' && Reader->Header[i+1] == '\n' && Reader->Header[i+2] == '\r' && Reader->Header[i+3] == '\n')
				{
					/* Finished Header */
					Reader->PacketHeader = ILibParsePacketHeader(Reader->Header,0,i+4);
					Reader->PacketHeader->ReceivingAddress = Reader->LocalIPAddress;
					Reader->BodySize = -1;
					Reader->Body_Read = 0;
					node = Reader->PacketHeader->FirstField;
					while(node!=NULL)
					{
						if(strncasecmp(node->Field,"CONTENT-LENGTH",14)==0)
						{
							CharStar = (char*)MALLOC(1+node->FieldDataLength);
							memcpy(CharStar,node->FieldData,node->FieldDataLength);
							CharStar[node->FieldDataLength] = '\0';
							Reader->BodySize = atoi(CharStar);
							FREE(CharStar);
							break;
						}
						node = node->NextField;
					}
					if(Reader->BodySize!=-1)
					{
						if(Reader->BodySize!=0)
						{
							Reader->Body = (char*)MALLOC(Reader->BodySize);
							Reader->Body_MallocSize = Reader->BodySize;
						}
						else
						{
							Reader->Body = NULL;
							Reader->Body_MallocSize = 0;
						}
					}
					else
					{
						Reader->Body = (char*)MALLOC(4096);
						Reader->Body_MallocSize = 4096;
					}
					
					if(Reader->HeaderIndex>i+4 && Reader->BodySize!=0)
					{
						/* Part of the body is in here */
						memcpy(Reader->Body,Reader->Header+i+4,Reader->HeaderIndex-(&Reader->Header[i+4]-Reader->Header));
						Reader->Body_BeginPointer = 0;
						Reader->Body_EndPointer = Reader->HeaderIndex-(int)(&Reader->Header[i+4]-Reader->Header);
						Reader->Body_Read = Reader->Body_EndPointer;
						
						if(Reader->BodySize==-1 || Reader->Body_Read>=Reader->BodySize)
						{
							DEBUGSTATEMENT(printf("Close\r\n"));
							Reader->FunctionCallback(Reader,Reader->PacketHeader,Reader->Body,&Reader->Body_BeginPointer,Reader->Body_EndPointer - Reader->Body_BeginPointer,-1,Reader->user);
							
							while(Reader->Body_BeginPointer!=Reader->Body_EndPointer && Reader->Body_BeginPointer!=0)
							{
								memcpy(Reader->Body,Reader->Body+Reader->Body_BeginPointer,Reader->Body_EndPointer-Reader->Body_BeginPointer);
								Reader->Body_EndPointer = Reader->Body_EndPointer-Reader->Body_BeginPointer;
								Reader->Body_BeginPointer = 0;
								Reader->FunctionCallback(Reader,Reader->PacketHeader,Reader->Body,&Reader->Body_BeginPointer,Reader->Body_EndPointer,-1,Reader->user);
							}
							
							if(Reader->PacketHeader!=NULL) {ILibDestructPacket(Reader->PacketHeader);}
							if(Reader->Body_MallocSize!=0) {FREE(Reader->Body);}
							Reader->Body = NULL;
							Reader->Body_MallocSize = 0;
							Reader->PacketHeader = NULL;
							closesocket(Reader->ClientSocket);
							Reader->ClientSocket = 0xFFFFFFFF;
						}
						else
						{
							Reader->FunctionCallback(Reader,Reader->PacketHeader,Reader->Body,&Reader->Body_BeginPointer,Reader->Body_EndPointer - Reader->Body_BeginPointer,0,Reader->user);
							while(Reader->Body_BeginPointer!=Reader->Body_EndPointer && Reader->Body_BeginPointer!=0)
							{
								memcpy(Reader->Body,Reader->Body+Reader->Body_BeginPointer,Reader->Body_EndPointer-Reader->Body_BeginPointer);
								Reader->Body_EndPointer = Reader->Body_EndPointer-Reader->Body_BeginPointer;
								Reader->Body_BeginPointer = 0;
								Reader->FunctionCallback(Reader,Reader->PacketHeader,Reader->Body,&Reader->Body_BeginPointer,Reader->Body_EndPointer,0,Reader->user);
							}
						}
					}
					else
					{
						/* There is no body, but the packet is here */
						Reader->Body_BeginPointer = 0;
						Reader->Body_EndPointer = 0;
						
						if(Reader->BodySize<=0)
						{
							Reader->FunctionCallback(Reader,Reader->PacketHeader,NULL,&Reader->Body_BeginPointer,0,-1,Reader->user);
							if(Reader->PacketHeader!=NULL) {ILibDestructPacket(Reader->PacketHeader);}
							if(Reader->Body_MallocSize!=0) {FREE(Reader->Body);}
							Reader->Body = NULL;
							Reader->Body_MallocSize = 0;
							Reader->PacketHeader = NULL;
							closesocket(Reader->ClientSocket);
							Reader->ClientSocket = 0xFFFFFFFF;
						}
						else
						{
							Reader->FunctionCallback(Reader,Reader->PacketHeader,NULL,&Reader->Body_BeginPointer,0,0,Reader->user);
						}
					}
					break;
				}
			}
		}
	}
	else
	{
		/* Reading Body Only */
		if(Reader->Body_BeginPointer == Reader->Body_EndPointer)
		{
			Reader->Body_BeginPointer = 0;
			Reader->Body_EndPointer = 0;
		}
		else
		{
			if(Reader->Body_BeginPointer!=0)
			{
				Reader->Body_EndPointer = Reader->Body_BeginPointer;
			}
		}
		
		
		if(Reader->Body_EndPointer == Reader->Body_MallocSize)
		{
			Reader->Body_MallocSize += 4096;
			Reader->Body = (char*)realloc(Reader->Body,Reader->Body_MallocSize);
		}
		
		bytesReceived = recv(Reader->ClientSocket,Reader->Body+Reader->Body_EndPointer,Reader->Body_MallocSize-Reader->Body_EndPointer,0);
		Reader->Body_EndPointer += bytesReceived;
		Reader->Body_Read += bytesReceived;
		
		Reader->FunctionCallback(Reader, Reader->PacketHeader, Reader->Body+Reader->Body_BeginPointer, &Reader->Body_BeginPointer, Reader->Body_EndPointer - Reader->Body_BeginPointer, 0, Reader->user);
		while(Reader->Body_BeginPointer!=Reader->Body_EndPointer && Reader->Body_BeginPointer!=0)
		{
			memcpy(Reader->Body,Reader->Body+Reader->Body_BeginPointer,Reader->Body_EndPointer-Reader->Body_BeginPointer);
			Reader->Body_EndPointer = Reader->Body_EndPointer-Reader->Body_BeginPointer;
			Reader->Body_BeginPointer = 0;
			Reader->FunctionCallback(Reader,Reader->PacketHeader,Reader->Body,&Reader->Body_BeginPointer,Reader->Body_EndPointer,0,Reader->user);				
		}
		
		if((Reader->BodySize!=-1 && Reader->Body_Read>=Reader->BodySize)||(bytesReceived==0))
		{
			if(Reader->Body_BeginPointer == Reader->Body_EndPointer)
			{
				Reader->Body_BeginPointer = 0;
				Reader->Body_EndPointer = 0;
			}
			Reader->FunctionCallback(Reader, Reader->PacketHeader, Reader->Body, &Reader->Body_BeginPointer, Reader->Body_EndPointer, -1,Reader->user);
			if(Reader->PacketHeader!=NULL) {ILibDestructPacket(Reader->PacketHeader);}
			if(Reader->Body_MallocSize!=0) {FREE(Reader->Body);}
			Reader->Body = NULL;
			Reader->Body_MallocSize = 0;
			Reader->PacketHeader = NULL;
			closesocket(Reader->ClientSocket);
			Reader->ClientSocket = 0xFFFFFFFF;
		}
		
		if(Reader->Body_BeginPointer==Reader->Body_EndPointer)
		{
			Reader->Body_BeginPointer = 0;
			Reader->Body_EndPointer = 0;
		}
	}
}