📄 ilibssdpclient.c
字号:
OK = 0; } } if(strncasecmp(node->Field,"USN",3)==0) { pnode = ILibParseString(node->FieldData, 0, node->FieldDataLength, "::", 2); pnode->FirstResult->data[pnode->FirstResult->datalength] = '\0'; UDN = pnode->FirstResult->data+5; ILibDestructParserResults(pnode); } if(strncasecmp(node->Field,"LOCATION",8)==0) { Location = node->FieldData; Location[node->FieldDataLength] = 0; //Location = (char*)malloc(node->FieldDataLength+1); //memcpy(Location,node->FieldData,node->FieldDataLength); //Location[node->FieldDataLength] = '\0'; }#ifdef UPNP_1_1 if(strncasecmp(node->Field,"BOOTID.UPNP.ORG",15)==0) { node->FieldData[node->FieldDataLength] = '\0'; BootID = atoi(node->FieldData); } if(strncasecmp(node->Field,"CONFIGID.UPNP.ORG",17)==0) { node->FieldData[node->FieldDataLength] = '\0'; ConfigID = atoi(node->FieldData); } if(strncasecmp(node->Field,"SEARCHPORT.UPNP.ORG",19)==0) { node->FieldData[node->FieldDataLength] = '\0'; SearchPort = (unsigned short)atoi(node->FieldData); }#endif if(strncasecmp(node->Field,"CACHE-CONTROL",13)==0) { pnode = ILibParseString(node->FieldData, 0, node->FieldDataLength, ",", 1); prf = pnode->FirstResult; while(prf!=NULL) { pnode2 = ILibParseString(prf->data, 0, prf->datalength, "=", 1); pnode2->FirstResult->datalength = ILibTrimString(&(pnode2->FirstResult->data),pnode2->FirstResult->datalength); pnode2->FirstResult->data[pnode2->FirstResult->datalength]=0; if(strcasecmp(pnode2->FirstResult->data,"max-age")==0) { pnode2->LastResult->datalength = ILibTrimString(&(pnode2->LastResult->data),pnode2->LastResult->datalength); pnode2->LastResult->data[pnode2->LastResult->datalength]=0; Timeout = atoi(pnode2->LastResult->data); ILibDestructParserResults(pnode2); break; } prf = prf->NextResult; ILibDestructParserResults(pnode2); } ILibDestructParserResults(pnode); } node = node->NextField; }#ifdef UPNP_1_1 if((OK!=0 && Alive!=0) || (Alive==0)) // UPnP/1.1 is very tolerant#else if((OK!=0 && Alive!=0) || (rt!=0 && Alive==0)) // UPnP/1.0 is not tolerant#endif { if(Location!=NULL) { ILibParseUri(Location,&IP,&PORT,&PATH); if(addr.sin_addr.s_addr==inet_addr(IP)) { MATCH=1; } else { MATCH=0; } free(IP); free(PATH);#ifdef UPNP_1_1 if(ILibHasEntry(module->HashTable,Location,(int)strlen(Location))==0) { LI = (struct LocationInfo*)malloc(sizeof(struct LocationInfo)); memset(LI,0,sizeof(struct LocationInfo)); LI->ConfigID = ConfigID; LI->LocationURL = (char*)malloc((int)strlen(Location)+1); strcpy(LI->LocationURL,Location); LI->SearchPort = SearchPort; LI->parent = module; LI->IsInteresting = 1; LI->Timeout = Timeout; LI->UDN = (char*)malloc(strlen(UDN)+1); strcpy(LI->UDN,UDN); ILibAddEntry(module->HashTable,Location,(int)strlen(Location),LI); } else { LI = (struct LocationInfo*)ILibGetEntry(module->HashTable,Location,(int)strlen(Location)); if(LI!=NULL) { LI->IsInteresting = 1; LI->Timeout = Timeout; ILibLifeTime_Remove(module->TIMER, LI); } }#endif } if(Alive==0 || MATCH!=0) { if(module->FunctionCallback!=NULL) { module->FunctionCallback(module,UDN,Alive,Location,Timeout,UPnPSSDP_NOTIFY,module->Reserved); } } }#ifdef UPNP_1_1 else if(Location!=NULL) { // Didn't match, lets Unicast search to make sure (1.1) if(ILibHasEntry(module->HashTable,Location,(int)strlen(Location))==0) { LI = (struct LocationInfo*)malloc(sizeof(struct LocationInfo)); memset(LI,0,sizeof(struct LocationInfo)); LI->ConfigID = ConfigID; LI->LocationURL = (char*)malloc((int)strlen(Location)+1); strcpy(LI->LocationURL,Location); LI->parent = module; LI->IsInteresting = 0; LI->Timeout = Timeout; LI->SearchPort = SearchPort; ILibAddEntry(module->HashTable,Location,(int)strlen(Location),LI); ILibLifeTime_Add(module->TIMER,LI,10,&ILibSSDP_LocationSink,NULL); } else { // There is a match, is this an interesting device? LI = (struct LocationInfo*)ILibGetEntry(module->HashTable,Location,(int)strlen(Location)); if(LI!=NULL) { if(LI->IsInteresting!=0) { if(module->FunctionCallback!=NULL) { module->FunctionCallback(module,UDN,Alive,Location,Timeout,UPnPSSDP_MSEARCH,module->Reserved); } } } } }#endif } } ILibDestructPacket(packet); }while(bytesRead>0); free(buffer);}static void ILibSSDPClientModule_PreSelect(void* object,fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime){ struct SSDPClientModule *module = (struct SSDPClientModule*)object; FD_SET(module->SSDPListenSocket,readset); FD_SET(module->MSEARCH_Response_Socket, readset);#ifdef UPNP_1_1 FD_SET(module->UNICAST_Socket,readset);#endif}static void ILibSSDPClientModule_PostSelect(void* object,int slct, fd_set *readset, fd_set *writeset, fd_set *errorset){ struct SSDPClientModule *module = (struct SSDPClientModule*)object; if(slct>0) { if(FD_ISSET(module->SSDPListenSocket,readset)!=0) { ILibReadSSDP(module->SSDPListenSocket,module); } if(FD_ISSET(module->MSEARCH_Response_Socket,readset)!=0) { ILibReadSSDP(module->MSEARCH_Response_Socket,module); }#ifdef UPNP_1_1 if(FD_ISSET(module->UNICAST_Socket,readset)!=0) { ILibReadSSDP(module->UNICAST_Socket,module); }#endif }}static void ILibSSDPClientModule_Destroy(void *object){ struct SSDPClientModule *s = (struct SSDPClientModule*)object; #ifdef UPNP_1_1 char *key; int keyLength; void *data; void *en = ILibHashTree_GetEnumerator(s->HashTable); while(ILibHashTree_MoveNext(en)==0) { ILibHashTree_GetValue(en,&key,&keyLength,&data); free(((struct LocationInfo*)data)->LocationURL); if(((struct LocationInfo*)data)->UDN != NULL) { free(((struct LocationInfo*)data)->UDN); } free(data); } ILibHashTree_DestroyEnumerator(en); ILibDestroyHashTree(s->HashTable);#endif free(s->DeviceURN); if(s->IPAddress!=NULL) { free(s->IPAddress); }}void ILibSSDP_IPAddressListChanged(void *SSDPToken){ struct SSDPClientModule *RetVal = (struct SSDPClientModule*)SSDPToken; int i; struct sockaddr_in dest_addr; struct ip_mreq mreq; char* buffer; int bufferlength; struct in_addr interface_addr; dest_addr.sin_family = AF_INET; dest_addr.sin_addr.s_addr = inet_addr(UPNP_GROUP); dest_addr.sin_port = htons(UPNP_PORT); 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) { } } buffer = (char*)malloc(105+RetVal->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",RetVal->DeviceURN); free(RetVal->IPAddress); RetVal->NumIPAddress = ILibGetLocalIPAddressList(&(RetVal->IPAddress)); for(i=0;i<RetVal->NumIPAddress;++i) { interface_addr.s_addr = RetVal->IPAddress[i]; 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(buffer);}void* ILibCreateSSDPClientModule(void *chain, char* DeviceURN, int DeviceURNLength, void (*CallbackPtr)(void *sender, char* UDN, int Alive, char* LocationURL, int Timeout, UPnPSSDP_MESSAGE m,void *user),void *user){ int i,flags; 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; struct parser_result *pr; 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; // Populate the Prefix portion of the URN, for matching purposes RetVal->DeviceURN_Prefix = RetVal->DeviceURN; pr = ILibParseString(RetVal->DeviceURN,0,RetVal->DeviceURNLength,":",1); RetVal->DeviceURN_PrefixLength = (int)((pr->LastResult->data)-(RetVal->DeviceURN)); pr->LastResult->data[pr->LastResult->datalength]=0; RetVal->BaseDeviceVersionNumber = atoi(pr->LastResult->data); ILibDestructParserResults(pr); RetVal->NumIPAddress = ILibGetLocalIPAddressList(&(RetVal->IPAddress)); RetVal->SSDPListenSocket = socket(AF_INET, SOCK_DGRAM, 0);# if defined(WIN32) || defined(_WIN32_WCE) ILibGetDGramSocket(htonl(INADDR_ANY), (HANDLE*)&(RetVal->MSEARCH_Response_Socket));# else ILibGetDGramSocket(htonl(INADDR_ANY), (int*)&(RetVal->MSEARCH_Response_Socket));# endif 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); }#ifdef UPNP_1_1# if defined(WIN32) || defined(_WIN32_WCE) addr.sin_port = htons(ILibGetDGramSocket(htonl(INADDR_ANY), (HANDLE*)&(RetVal->UNICAST_Socket)));# else addr.sin_port = htons(ILibGetDGramSocket(htonl(INADDR_ANY), (int*)&(RetVal->UNICAST_Socket)));# endif setsockopt(RetVal->UNICAST_Socket, SOL_SOCKET, SO_REUSEADDR,(char*)&ra, sizeof(ra)); bind(RetVal->UNICAST_Socket, (struct sockaddr *) &(addr), sizeof(addr));# if defined(WIN32) || defined(_WIN32_WCE) flags = 1; ioctlsocket(RetVal->UNICAST_Socket,FIONBIO,&flags);# elif defined(_POSIX) flags = fcntl(RetVal->UNICAST_Socket,F_GETFL,0); fcntl(RetVal->UNICAST_Socket,F_SETFL,O_NONBLOCK|flags);# endif#endif /* Setting Sockets to Non-Blocking mode */ #if defined(WIN32) || defined(_WIN32_WCE) flags = 1; ioctlsocket(RetVal->SSDPListenSocket,FIONBIO,&flags); ioctlsocket(RetVal->MSEARCH_Response_Socket,FIONBIO,&flags); #elif defined(_POSIX) flags = fcntl(RetVal->SSDPListenSocket,F_GETFL,0); fcntl(RetVal->SSDPListenSocket,F_SETFL,O_NONBLOCK|flags); fcntl(RetVal->MSEARCH_Response_Socket,F_SETFL,O_NONBLOCK|flags); #endif 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]; 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);#ifdef UPNP_1_1 RetVal->HashTable = ILibInitHashTree(); RetVal->TIMER = ILibCreateLifeTime(chain);#endif return(RetVal);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -