📄 mscp_controlpoint.c
字号:
ILibDestructXMLNodeList(rootXML);}static void MSCP_OnEventSink(struct ILibWebServer_Session *sender,int InterruptFlag,struct packetheader *header,char *buffer,int *BeginPointer,int BufferSize,int done){ int type_length; char* sid = NULL; void* value = NULL; struct UPnPService *service = NULL; struct packetheader_field_node *field = NULL; struct packetheader *resp; if(done!=0) { resp = ILibCreateEmptyPacket(); ILibSetVersion(resp,"1.1",3); ILibAddHeaderLine(resp,"Server",6,MSCP_PLATFORM,(int)strlen(MSCP_PLATFORM)); ILibAddHeaderLine(resp,"Content-Length",14,"0",1); field = header->FirstField; while(field!=NULL) { if(field->FieldLength==3) { if(strncasecmp(field->Field,"SID",3)==0) { sid = (char*)malloc(field->FieldDataLength+1); sprintf(sid,"%s",field->FieldData); value = ILibGetEntry(((struct MSCP_CP*)sender->User)->SIDTable,field->FieldData,field->FieldDataLength); break; } } field = field->NextField; } if(value==NULL) { /* Not a valid SID */ ILibSetStatusCode(resp,412,"Failed",6); } else { ILibSetStatusCode(resp,200,"OK",2); service = (struct UPnPService*)value; type_length = (int)strlen(service->ServiceType); if(type_length>46 && strncmp("urn:schemas-upnp-org:service:ContentDirectory:",service->ServiceType,46)==0) { MSCP_ContentDirectory_EventSink(buffer, BufferSize, service); } else if(type_length>54 && strncmp("urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:",service->ServiceType,54)==0) { MSCP_urn_microsoft_com_service_X_MS_MediaReceiverRegistrar_EventSink(buffer, BufferSize, service); } } ILibWebServer_Send(sender,resp); if(sid!=NULL){free(sid);} }}static void MSCP_OnUnSubscribeSink(void *WebReaderToken,int IsInterrupt,struct packetheader *header,char *buffer,int *BeginPointer,int BufferSize,int done,void *user,void *vcp,int *PAUSE){ struct UPnPService *s; //struct MSCP_CP *cp = (struct MSCP_CP*)vcp; if(done!=0) { s = (struct UPnPService*)user; if(header!=NULL) { if(header->StatusCode==200) { /* Successful */ } } MSCP_Release(s->Parent); }}static void MSCP_OnSubscribeSink(void *WebReaderToken,int IsInterrupt,struct packetheader *header,char *buffer,int *BeginPointer,int BufferSize,int done,void *user,void *vcp,int *PAUSE){ struct UPnPService *s; struct UPnPDevice *d; struct packetheader_field_node *field; struct parser_result *p; struct MSCP_CP *cp = (struct MSCP_CP*)vcp; if(done!=0) { s = (struct UPnPService*)user; if(header!=NULL) { if(header->StatusCode==200) { /* Successful */ field = header->FirstField; while(field!=NULL) { if(field->FieldLength==3 && strncasecmp(field->Field,"SID",3)==0 && s->SubscriptionID==NULL) { s->SubscriptionID = (char*)malloc(1+field->FieldDataLength); strcpy(s->SubscriptionID,field->FieldData); ILibAddEntry(cp->SIDTable,field->FieldData,field->FieldDataLength,s); } else if(field->FieldLength==7 && strncasecmp(field->Field,"TIMEOUT",7)==0) { p = ILibParseString(field->FieldData,0,field->FieldDataLength,"-",1); p->LastResult->data[p->LastResult->datalength] = '\0'; MSCP_AddRef(s->Parent); d = s->Parent; while(d->Parent!=NULL) {d = d->Parent;} ++d->ReferenceTiedToEvents; ILibLifeTime_Add(cp->LifeTimeMonitor,s,atoi(p->LastResult->data)/2,&MSCP_Renew,NULL); ILibDestructParserResults(p); } field = field->NextField; } } } MSCP_Release(s->Parent); }}void MSCP_Renew(void *state){ struct UPnPService *service = (struct UPnPService*)state; struct UPnPDevice *d = service->Parent; char *IP; char *Path; unsigned short Port; struct packetheader *p; char* TempString; struct sockaddr_in destaddr; ILibParseUri(service->SubscriptionURL,&IP,&Port,&Path); p = ILibCreateEmptyPacket(); ILibSetVersion(p,"1.1",3); ILibSetDirective(p,"SUBSCRIBE",9,Path,(int)strlen(Path)); TempString = (char*)malloc((int)strlen(IP)+7); sprintf(TempString,"%s:%d",IP,Port); ILibAddHeaderLine(p,"HOST",4,TempString,(int)strlen(TempString)); free(TempString); ILibAddHeaderLine(p,"SID",3,service->SubscriptionID,(int)strlen(service->SubscriptionID)); ILibAddHeaderLine(p,"TIMEOUT",7,"Second-180",10); ILibAddHeaderLine(p,"User-Agent",10,MSCP_PLATFORM,(int)strlen(MSCP_PLATFORM)); memset((char *)&destaddr, 0,sizeof(destaddr)); destaddr.sin_family = AF_INET; destaddr.sin_addr.s_addr = inet_addr(IP); destaddr.sin_port = htons(Port); ILibWebClient_PipelineRequest( ((struct MSCP_CP*)service->Parent->CP)->HTTP, &destaddr, p, &MSCP_OnSubscribeSink, (void*)service, service->Parent->CP); while(d->Parent!=NULL) {d = d->Parent;} --d->ReferenceTiedToEvents; free(IP); free(Path);}struct UPnPDevice* MSCP_GetDeviceEx(struct UPnPDevice *device, char* DeviceType, int counter, int number){ struct UPnPDevice *RetVal = NULL; struct UPnPDevice *d = device->EmbeddedDevices; struct parser_result *pr,*pr2; int DeviceTypeLength = (int)strlen(DeviceType); int TempLength = (int)strlen(device->DeviceType); while(d != NULL && RetVal==NULL) { RetVal = MSCP_GetDeviceEx(d,DeviceType,counter,number); d = d->Next; } if(RetVal==NULL) { pr = ILibParseString(DeviceType,0,DeviceTypeLength,":",1); pr2 = ILibParseString(device->DeviceType,0,TempLength,":",1); if(DeviceTypeLength-pr->LastResult->datalength == TempLength - pr2->LastResult->datalength && atoi(pr->LastResult->data) >= atoi(pr2->LastResult->data) && memcmp(DeviceType,device->DeviceType,DeviceTypeLength-pr->LastResult->datalength)==0) { ILibDestructParserResults(pr); ILibDestructParserResults(pr2); if(number == (++counter)) return(device); } ILibDestructParserResults(pr); ILibDestructParserResults(pr2); return(NULL); } else { return(RetVal); }}int MSCP_HasAction(struct UPnPService *s, char* action){ struct UPnPAction *a = s->Actions; while(a!=NULL) { if(strcmp(action,a->Name)==0) return(-1); a = a->Next; } return(0);}static void MSCP_StopCP(void *v_CP){ int i; struct UPnPDevice *Device; struct MSCP_CP *CP= (struct MSCP_CP*)v_CP; void *en; char *key; int keyLength; void *data; en = ILibHashTree_GetEnumerator(CP->DeviceTable); while(ILibHashTree_MoveNext(en)==0) { ILibHashTree_GetValue(en,&key,&keyLength,&data); if(data!=NULL) { // This is a UPnPDevice Device = (struct UPnPDevice*)data; if(Device->Parent==NULL) { // This is the Root Device (Which is only in the table once) MSCP_CP_RecursiveReleaseAndEventDevice(CP,Device); i = Device->ReferenceTiedToEvents; while(i!=0) { MSCP_Release(Device); --i; } MSCP_Release(Device); } } } ILibHashTree_DestroyEnumerator(en); ILibDestroyHashTree(CP->SIDTable); ILibDestroyHashTree(CP->DeviceTable); free(CP->AddressList);}void MSCP__CP_IPAddressListChanged(void *CPToken){ if(ILibIsChainBeingDestroyed(((struct MSCP_CP*)CPToken)->Chain)==0) { ((struct MSCP_CP*)CPToken)->RecheckFlag = 1; ILibForceUnBlockChain(((struct MSCP_CP*)CPToken)->Chain); }}static void MSCP_CP_PreSelect(void *CPToken,fd_set *readset, fd_set *writeset, fd_set *errorset, int *blocktime){ struct MSCP_CP *CP= (struct MSCP_CP*)CPToken; void *en; struct UPnPDevice *device; char *key; int keyLength; void *data; void *q; int *IPAddressList; int NumAddressList; int i; int found; if(CP->RecheckFlag!=0) { CP->RecheckFlag = 0; NumAddressList = ILibGetLocalIPAddressList(&IPAddressList); q = ILibQueue_Create(); ILibHashTree_Lock(CP->DeviceTable); en = ILibHashTree_GetEnumerator(CP->DeviceTable); while(ILibHashTree_MoveNext(en)==0) { ILibHashTree_GetValue(en,&key,&keyLength,&data); if(data!=NULL) { // This is a MSCP_ Device device = (struct UPnPDevice*)data; if(device->Parent==NULL) { // This is the root device, which is in the table exactly once found = 0; for(i=0;i<NumAddressList;++i) { if((unsigned int)IPAddressList[i]==inet_addr(device->InterfaceToHost)) { found = 1; break; } } if(found==0) { // Queue Device to be removed, so we can process it // outside of the lock ILibQueue_EnQueue(q,device); } } } } ILibHashTree_DestroyEnumerator(en); ILibHashTree_UnLock(CP->DeviceTable); while(ILibQueue_PeekQueue(q)!=NULL) { device = ILibQueue_DeQueue(q); MSCP_CP_ProcessDeviceRemoval(CP,device); MSCP_Release(device); } ILibQueue_Destroy(q); ILibSSDP_IPAddressListChanged(CP->SSDP); free(CP->AddressList); CP->AddressListLength = NumAddressList; CP->AddressList = IPAddressList; }}static void MSCP_OnSessionSink(struct ILibWebServer_Session *session, void *User){ session->OnReceive = &MSCP_OnEventSink; session->User = User;}void *MSCP_CreateControlPoint(void *Chain, void(*A)(struct UPnPDevice*),void(*R)(struct UPnPDevice*)){ struct MSCP_CP *cp = (struct MSCP_CP*)malloc(sizeof(struct MSCP_CP)); cp->Destroy = &MSCP_StopCP; cp->PostSelect = NULL; cp->PreSelect = &MSCP_CP_PreSelect; cp->DiscoverSink = A; cp->RemoveSink = R; cp->WebServer = ILibWebServer_Create(Chain,5,0,&MSCP_OnSessionSink,cp); cp->SIDTable = ILibInitHashTree(); cp->DeviceTable = ILibInitHashTree(); cp->SSDP = ILibCreateSSDPClientModule(Chain,"urn:schemas-upnp-org:device:MediaServer:1", 41, &MSCP_SSDP_Sink,cp); cp->HTTP = ILibCreateWebClient(5,Chain); ILibAddToChain(Chain,cp); cp->LifeTimeMonitor = ILibCreateLifeTime(Chain); cp->Chain = Chain; cp->RecheckFlag = 0; cp->AddressListLength = ILibGetLocalIPAddressList(&(cp->AddressList)); return((void*)cp);}static void MSCP_Invoke_ContentDirectory_Browse_Sink(void *WebReaderToken,int IsInterrupt,struct packetheader *header,char *buffer,int *p_BeginPointer,int EndPointer,int done,void *_service,void *state,int *PAUSE){ struct UPnPService *Service = (struct UPnPService*)_service; struct InvokeStruct *_InvokeData = (struct InvokeStruct*)state; int ArgLeft = 4; struct ILibXMLNode *xml; struct ILibXMLNode *__xml; char *tempBuffer; int tempBufferLength; unsigned long TempULong; char* Result = NULL; unsigned int NumberReturned = 0; unsigned int TotalMatches = 0; unsigned int UpdateID = 0; LVL3DEBUG(char *DebugBuffer;) if(done==0){return;} LVL3DEBUG(DebugBuffer = (char*)malloc(EndPointer+1);) LVL3DEBUG(memcpy(DebugBuffer,buffer,EndPointer);) LVL3DEBUG(DebugBuffer[EndPointer]=0;) LVL3DEBUG(printf("\r\n SOAP Recieved:\r\n%s\r\n",DebugBuffer);) LVL3DEBUG(free(DebugBuffer);) if(_InvokeData->CallbackPtr==NULL) { MSCP_Release(Service->Parent); free(_InvokeData); return; } else { if(header==NULL) { /* Connection Failed */ ((void (*)(struct UPnPService*,int,void*,char*,unsigned int,unsigned int,unsigned int))_InvokeData->CallbackPtr)(Service,IsInterrupt==0?-1:IsInterrupt,_InvokeData->User,INVALID_DATA,INVALID_DATA,INVALID_DATA,INVALID_DATA); MSCP_Release(Service->Parent); free(_InvokeData); return; } else if(header->StatusCode!=200) { /* SOAP Fault */ ((void (*)(struct UPnPService*,int,void*,char*,unsigned int,unsigned int,unsigned int))_InvokeData->CallbackPtr)(Service,MSCP_GetErrorCode(buffer,EndPointer-(*p_BeginPointer)),_InvokeData->User,INVALID_DATA,INVALID_DATA,INVALID_DATA,INVALID_DATA); MSCP_Release(Service->Parent); free(_InvokeData); return; } } __xml = xml = ILibParseXML(buffer,0,EndPointer-(*p_BeginPointer)); ILibProcessXMLNodeList(xml); while(xml!=NULL) { if(xml->NameLength==14 && memcmp(xml->Name,"BrowseResponse",14)==0) { xml = xml->Next; while(xml!=NULL) { if(xml->NameLength==6 && memcmp(xml->Name,"Result",6) == 0) { --ArgLeft; tempBufferLength = ILibReadInnerXML(xml,&tempBuffer); if(tempBufferLength!=0) { tempBuffer[tempBufferLength] = '\0'; Result = tempBuffer; ILibInPlaceXmlUnEscape(Result); } } else if(xml->NameLength==14 && memcmp(xml->Name,"NumberReturned",14) == 0) { --ArgLeft; tempBufferLength = ILibReadInnerXML(xml,&tempBuffer); if(ILibGetULong(tempBuffer,tempBufferLength,&TempULong)==0) { NumberReturned = (unsigned int) TempULong; } } else if(xml->NameLength==12 && memcmp(xml->Name,"TotalMatches",12) == 0) { --ArgLeft; tempBufferLength = ILibReadInnerXML(xml,&tempBuffer)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -