// 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); }
__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); }