// Called by the UPnP Remote I/O Microstack
// Implements the RegisterChannel call, lets the CP un-register a RIO channel.
void UpnpRemoteIOClient_ChannelManager_UnregisterChannel(void* upnptoken,char* PeerConnection)
{
	// Scan the channel list for an existing channel
	struct RemoteIOChannel* channelprevious = NULL;
	struct RemoteIOChannel* channelindex = RIO->ChannelList;

	printf("UnRegisterChannel: %s\r\n",PeerConnection);

	if (PeerConnection == NULL)
	{
		if (upnptoken != NULL) UpnpResponse_Error(upnptoken,800,"Invalid PeerConnection URI");
		return;
	}

	sem_wait(&RemoteIOLock);
	while (channelindex != NULL)
	{
		// Look for a match
		if (strcmp(channelindex->uri,PeerConnection) == 0) break;
		channelprevious = channelindex;
		channelindex = channelindex->next;
	}

	// Delete the channel from the list, and free the channel struct
	if (channelindex != NULL)
	{
		ILibLifeTime_Remove(RIO->RIOLifeTime,channelindex);

		if (channelprevious == NULL)
		{
			RIO->ChannelList = channelindex->next;
		}
		else
		{
			channelprevious->next = channelindex->next;
		}
		free(channelindex->name);
		free(channelindex->uri);
		free(channelindex);

		// Set the channels to be evented
		if (RIO->EventModerationSet == 0)
		{
			ILibLifeTime_Add(RIO->RIOLifeTime,NULL,2,&RemoteIO_EventChannelList, NULL);
			RIO->EventModerationSet = 1;
		}
	}
	
	if (upnptoken != NULL) UpnpResponse_RemoteIOClient_ChannelManager_UnregisterChannel(upnptoken);

	sem_post(&RemoteIOLock);
}
void ILibMiniWebServerModule_PostSelect(void *WebServerModule, int slct, fd_set *readset, fd_set *writeset, fd_set *errorset)
{
	unsigned long flags=0;
	int i;
	struct MiniWebServerObject *module = (struct MiniWebServerObject*)WebServerModule;
	struct sockaddr_in addr;
	int addrlen = sizeof(struct sockaddr_in);
	
	
	/* Select Connected Sockets*/
	for(i=0;i<module->MaxConnections;++i)
	{
		if(module->Readers[i].ClientSocket!=0xFFFFFFFF)
		{
			if(FD_ISSET(module->Readers[i].ClientSocket,errorset)!=0)
			{
				module->Readers[i].ClientSocket = 0xFFFFFFFF;
				module->Readers[i].BodySize = 0;
				//ToDo: cleanup
			}
			if(FD_ISSET(module->Readers[i].ClientSocket,readset)!=0)
			{
				ILibMiniWebServerProcessSocket(&(module->Readers[i]));
			}
			if(module->Readers[i].ClientSocket==~0 || module->Readers[i].Body!=NULL)
			{
				ILibLifeTime_Remove(module->TimerObject,&(module->Readers[i]));
			}
		}
	}
	
	/* Select Listen Socket */
	if(FD_ISSET(module->ListenSocket,readset)!=0)
	{
		for(i=0;i<module->MaxConnections;++i)
		{
			if(module->Readers[i].ClientSocket==0xFFFFFFFF)
			{
				module->Readers[i].ClientSocket = accept(module->ListenSocket,(struct sockaddr*)&addr,&addrlen);
				ioctlsocket(module->Readers[i].ClientSocket,FIONBIO,&flags);
				ILibLifeTime_Add(module->TimerObject,&(module->Readers[i]),3,&ILibMWS_TimerSink,NULL);
				module->Readers[i].HeaderIndex = 0;
				module->Readers[i].Body_BeginPointer = 0;
				module->Readers[i].Body_EndPointer = 0;
				module->Readers[i].Body_MallocSize = 0;
				module->Readers[i].Body_Read = 0;
				break;
			}
		}
	}
}
void ILibWebServer_OnDisconnect(void *AsyncServerSocketModule, void *ConnectionToken, void *user)
{
	struct ILibWebServer_Session *ws = (struct ILibWebServer_Session*)user;

	if(ws->Reserved4!=0 || ws->Reserved5==0)
	{
		ILibLifeTime_Remove(((struct ILibWebServer_StateModule*)ws->Parent)->LifeTime,ws);
		ws->Reserved4=0;
	}

	if(ws->OnDisconnect!=NULL)
	{
		ws->OnDisconnect(ws);
	}
	ILibWebClient_DestroyWebClientDataObject(ws->Reserved3);
	FREE(user);
}
示例#4
0
		__declspec(dllexport) void ILibWrapper_LifeTimeRemove(void *LifeTimeToken, void *data)
	{
		ILibLifeTime_Remove(LifeTimeToken, data);
	}
void ILibWebServer_OnResponse(void *WebReaderToken,
								int InterruptFlag,
								struct packetheader *header,
								char *bodyBuffer,
								int *beginPointer,
								int endPointer,
								int done,
								void *user1,
								void *user2,
								int *PAUSE)
{
	struct ILibWebServer_Session *ws = (struct ILibWebServer_Session*)user2;
	struct ILibWebServer_StateModule *wsm = (struct ILibWebServer_StateModule*)ws->Parent;
	
	char *tmp;
	int tmpLength;
	struct parser_result *pr;
	int PreSlash=0;

	if(ws->Reserved4!=0 || ws->Reserved5==0)
	{
		// Not Idle anymore
		ws->Reserved4 = 0;
		ws->Reserved5 = 1;
		ws->Reserved8 = 0;
		ILibLifeTime_Remove(((struct ILibWebServer_StateModule*)ws->Parent)->LifeTime,ws);
	}


	//Check Virtual Directory
	if(wsm->VirtualDirectoryTable!=NULL)
	{
		if(ws->Reserved7==NULL)
		{
			pr = ILibParseString(header->DirectiveObj,0,header->DirectiveObjLength,"/",1);
			if(pr->FirstResult->datalength==0)
			{
				// Does not start with '/'
				tmp = pr->FirstResult->NextResult->data;
				tmpLength = pr->FirstResult->NextResult->datalength;
			}
			else
			{
				// Starts with '/'
				tmp = pr->FirstResult->data;
				tmpLength = pr->FirstResult->datalength;
				PreSlash=1;
			}
			ILibDestructParserResults(pr);
			if(ILibHasEntry(wsm->VirtualDirectoryTable,tmp,tmpLength)!=0)
			{
				// Virtual Directory Defined
				header->DirectiveObj = tmp+tmpLength;
				header->DirectiveObjLength -= (tmpLength+PreSlash);
				ws->Reserved7 = ILibGetEntry(wsm->VirtualDirectoryTable,tmp,tmpLength);

				((ILibWebServer_VirtualDirectory)((struct ILibWebServer_VirDir_Data*)ws->Reserved7)->callback)(ws,header,bodyBuffer,beginPointer,endPointer,done,((struct ILibWebServer_VirDir_Data*)ws->Reserved7)->user);
			}
			else if(ws->OnReceive!=NULL)
			{
				ws->OnReceive(ws,InterruptFlag,header,bodyBuffer,beginPointer,endPointer,done);
			}
		}
		else
		{
			((ILibWebServer_VirtualDirectory)((struct ILibWebServer_VirDir_Data*)ws->Reserved7)->callback)(ws,header,bodyBuffer,beginPointer,endPointer,done,((struct ILibWebServer_VirDir_Data*)ws->Reserved7)->user);
		}
	}
	else if(ws->OnReceive!=NULL)
	{
		ws->OnReceive(ws,InterruptFlag,header,bodyBuffer,beginPointer,endPointer,done);
	}


	if(done!=0 && InterruptFlag==0 && header!=NULL && ws->Reserved8==0)
	{
		*PAUSE=1;
	}
}
// Called by the UPnP Remote I/O Microstack
// Implements the RegisterChannel call, lets the CP register a new RIO channels for a
// certain amont of time. The CP must re-register the channel from time-to-time to
// prevent the channel from expiring.
void UpnpRemoteIOClient_ChannelManager_RegisterChannel(void* upnptoken,char* Name,char* PeerConnection,int Timeout)
{
	// Scan the channel list for an existing channel
	struct RemoteIOChannel* channelindex = RIO->ChannelList;
	struct RemoteIOChannel* newchannel;

	printf("RegisterChannel[%s] (%d): %s\r\n",PeerConnection,Timeout,Name);

	if (PeerConnection == NULL)
	{
		if (upnptoken != NULL) UpnpResponse_Error(upnptoken,800,"Invalid PeerConnection URI");
		return;
	}

	sem_wait(&RemoteIOLock);

	while (channelindex != NULL)
	{
		// Look for a match
		if (strcmp(channelindex->uri,PeerConnection) == 0) break;
		channelindex = channelindex->next;
	}

	if (channelindex != NULL)
	{
		// Update the expiration time
		ILibLifeTime_Remove(RIO->RIOLifeTime,channelindex);
		#ifdef _WIN32_WCE
			channelindex->expiration = (GetTickCount() / 1000) + Timeout;
			ILibLifeTime_Add(RIO->RIOLifeTime,channelindex,Timeout,&RemoteIO_ChannelExpireSink, NULL);
		#elif WIN32
			channelindex->expiration = (GetTickCount() / 1000) + Timeout;
			ILibLifeTime_Add(RIO->RIOLifeTime,channelindex,Timeout,&RemoteIO_ChannelExpireSink, NULL);
		#elif _POSIX
			gettimeofday(&(channelindex->expiration),NULL);
			(channelindex->expiration).tv_sec += (int)Timeout;
			ILibLifeTime_Add(RIO->RIOLifeTime,channelindex,Timeout,&RemoteIO_ChannelExpireSink, NULL);
		#endif
	}
	else
	{
		// Add a new channel to the channel list
		newchannel = (struct RemoteIOChannel*)malloc(sizeof(struct RemoteIOChannel));
		newchannel->name = (char*)malloc(strlen(Name)+1);
		strcpy(newchannel->name,Name);
		newchannel->uri = (char*)malloc(strlen(PeerConnection)+1);
		strcpy(newchannel->uri,PeerConnection);
		#ifdef _WIN32_WCE
			newchannel->expiration = (GetTickCount() / 1000) + Timeout;
			ILibLifeTime_Add(RIO->RIOLifeTime,newchannel,Timeout,&RemoteIO_ChannelExpireSink, NULL);
		#elif WIN32
			newchannel->expiration = (GetTickCount() / 1000) + Timeout;
			ILibLifeTime_Add(RIO->RIOLifeTime,newchannel,Timeout,&RemoteIO_ChannelExpireSink, NULL);
		#elif _POSIX
			gettimeofday(&(newchannel->expiration),NULL);
			(newchannel->expiration).tv_sec += (int)Timeout;
			ILibLifeTime_Add(RIO->RIOLifeTime,newchannel,Timeout,&RemoteIO_ChannelExpireSink, NULL);
		#endif
		newchannel->next = RIO->ChannelList;
		RIO->ChannelList = newchannel;

		// Set the channels to be evented
		if (RIO->EventModerationSet == 0)
		{
			ILibLifeTime_Add(RIO->RIOLifeTime,NULL,2,&RemoteIO_EventChannelList, NULL);
			RIO->EventModerationSet = 1;
		}
	}

	UpnpResponse_RemoteIOClient_ChannelManager_RegisterChannel(upnptoken);

	sem_post(&RemoteIOLock);
}