📄 mscp_controlpoint.c
字号:
/** INTEL CONFIDENTIAL* Copyright (c) 2002, 2003 Intel Corporation. All rights reserved.* * The source code contained or described herein and all documents* related to the source code ("Material") are owned by Intel* Corporation or its suppliers or licensors. Title to the* Material remains with Intel Corporation or its suppliers and* licensors. The Material contains trade secrets and proprietary* and confidential information of Intel or its suppliers and* licensors. The Material is protected by worldwide copyright and* trade secret laws and treaty provisions. No part of the Material* may be used, copied, reproduced, modified, published, uploaded,* posted, transmitted, distributed, or disclosed in any way without* Intel's prior express written permission.* No license under any patent, copyright, trade secret or other* intellectual property right is granted to or conferred upon you* by disclosure or delivery of the Materials, either expressly, by* implication, inducement, estoppel or otherwise. Any license* under such intellectual property rights must be express and* approved by Intel in writing.* * $Workfile: MSCP_ControlPoint.c* $Revision: #1.0.1799.42459* $Author: Intel Corporation, Intel Device Builder* $Date: Monday, March 21, 2005****/#if defined(WIN32) || defined(_WIN32_WCE)# ifndef MICROSTACK_NO_STDAFX# include "stdafx.h"# endif# define _CRTDBG_MAP_ALLOC# include <winerror.h>char* MSCP_PLATFORM = "WINDOWS, UPnP/1.0, Intel MicroStack/1.0.1799";#elsechar* MSCP_PLATFORM = "POSIX, UPnP/1.0, Intel MicroStack/1.0.1799";#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#if defined(WIN32) || defined(_WIN32_WCE)# include <stddef.h># if defined(WINSOCK2)# include <winsock2.h># include <ws2tcpip.h># elif defined(WINSOCK1)# include <winsock.h># include <wininet.h># endif# include <windows.h># include <winioctl.h># include <winbase.h># include <crtdbg.h># define strncasecmp(x,y,z) _strnicmp(x,y,z)# define gettimeofday(x,y) (x)->tv_sec = GetTickCount()/1000;(x)->tv_usec = 1000*(GetTickCount()%1000)#else# include <sys/types.h># include <sys/socket.h># include <netinet/in.h># include <arpa/inet.h># include <sys/time.h># include <netdb.h># include <sys/ioctl.h># include <net/if.h># include <sys/utsname.h># include <sys/socket.h># include <netinet/in.h># include <unistd.h># include <fcntl.h># include <errno.h># include <semaphore.h>#endif#include "ILibParsers.h"#include "ILibSSDPClient.h"#include "ILibWebServer.h"#include "ILibWebClient.h"#include "ILibAsyncSocket.h"#include "MSCP_ControlPoint.h"#define UPNP_PORT 1900#define UPNP_GROUP "239.255.255.250"#define MSCP_MIN(a,b) (((a)<(b))?(a):(b))#include "ILibParsers.h"#include "ILibSSDPClient.h"#include "ILibWebServer.h"#include "ILibWebClient.h"#include "MSCP_ControlPoint.h"#define INVALID_DATA 0#define DEBUGSTATEMENT(x)#define LVL3DEBUG(x)static const char *UPNPCP_SOAP_Header = "POST %s HTTP/1.1\r\nHost: %s:%d\r\nUser-Agent: %s, UPnP/1.0, Intel MicroStack/1.0.1799\r\nSOAPACTION: \"%s#%s\"\r\nContent-Type: text/xml; charset=\"utf-8\"\r\nContent-Length: %d\r\n\r\n";static const char *UPNPCP_SOAP_BodyHead = "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:";static const char *UPNPCP_SOAP_BodyTail = "></s:Body></s:Envelope>";void MSCP_Renew(void *state);void MSCP_SSDP_Sink(void *sender, char* UDN, int Alive, char* LocationURL, int Timeout,UPnPSSDP_MESSAGE m, void *cp);struct CustomUserData{ int Timeout; char* buffer;};struct MSCP_CP{ void (*PreSelect)(void* object,fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime); void (*PostSelect)(void* object,int slct, fd_set *readset, fd_set *writeset, fd_set *errorset); void (*Destroy)(void* object); void (*DiscoverSink)(struct UPnPDevice *device); void (*RemoveSink)(struct UPnPDevice *device); //ToDo: Check to see if this is necessary void (*EventCallback_DimmingService_LoadLevelStatus)(struct UPnPService* Service,unsigned char value); void (*EventCallback_SwitchPower_Status)(struct UPnPService* Service,int value); struct LifeTimeMonitorStruct *LifeTimeMonitor; void *HTTP; void *SSDP; void *WebServer; void* SIDTable; void* DeviceTable; void *Chain; int RecheckFlag; int AddressListLength; int *AddressList;};void (*MSCP_EventCallback_ContentDirectory_ContainerUpdateIDs)(struct UPnPService* Service,char* value);void (*MSCP_EventCallback_ContentDirectory_SystemUpdateID)(struct UPnPService* Service,unsigned int value);void (*MSCP_EventCallback_ContentDirectory_TransferIDs)(struct UPnPService* Service,char* value);void (*MSCP_EventCallback_Registrar_AuthorizationDeniedUpdateID)(struct UPnPService* Service,unsigned int value);void (*MSCP_EventCallback_Registrar_ValidationSucceededUpdateID)(struct UPnPService* Service,unsigned int value);void (*MSCP_EventCallback_Registrar_ValidationRevokedUpdateID)(struct UPnPService* Service,unsigned int value);void (*MSCP_EventCallback_Registrar_AuthorizationGrantedUpdateID)(struct UPnPService* Service,unsigned int value);struct InvokeStruct{ struct UPnPService *Service; void *CallbackPtr; void *User;};struct UPnPServiceInfo{ char* serviceType; char* SCPDURL; char* controlURL; char* eventSubURL; char* serviceId; struct UPnPServiceInfo *Next;};struct MSCP__Stack{ void *data; struct MSCP__Stack *next;};void MSCP_CP_ProcessDeviceRemoval(struct MSCP_CP* CP, struct UPnPDevice *device);static void MSCP_DestructUPnPService(struct UPnPService *service){ struct UPnPAction *a1,*a2; struct UPnPStateVariable *sv1,*sv2; int i; a1 = service->Actions; while(a1!=NULL) { a2 = a1->Next; free(a1->Name); free(a1); a1 = a2; } sv1 = service->Variables; while(sv1!=NULL) { sv2 = sv1->Next; free(sv1->Name); if(sv1->Min!=NULL) {free(sv1->Min);} if(sv1->Max!=NULL) {free(sv1->Max);} if(sv1->Step!=NULL) {free(sv1->Step);} for(i=0;i<sv1->NumAllowedValues;++i) { free(sv1->AllowedValues[i]); } if(sv1->AllowedValues!=NULL) {free(sv1->AllowedValues);} free(sv1); sv1 = sv2; } if(service->ControlURL!=NULL) {free(service->ControlURL);} if(service->SCPDURL!=NULL) {free(service->SCPDURL);} if(service->ServiceId!=NULL) {free(service->ServiceId);} if(service->ServiceType!=NULL) {free(service->ServiceType);} if(service->SubscriptionURL!=NULL) {free(service->SubscriptionURL);} if(service->SubscriptionID!=NULL) { ILibLifeTime_Remove(((struct MSCP_CP*)service->Parent->CP)->LifeTimeMonitor,service); ILibDeleteEntry(((struct MSCP_CP*)service->Parent->CP)->SIDTable,service->SubscriptionID,(int)strlen(service->SubscriptionID)); free(service->SubscriptionID); service->SubscriptionID = NULL; } free(service);}static void MSCP_DestructUPnPDevice(struct UPnPDevice *device){ struct UPnPDevice *d1,*d2; struct UPnPService *s1,*s2; void *en,*en2; char *key; int keyLen; void *val,*ht2; d1 = device->EmbeddedDevices; while(d1!=NULL) { d2 = d1->Next; MSCP_DestructUPnPDevice(d1); d1 = d2; } s1 = device->Services; while(s1!=NULL) { s2 = s1->Next; MSCP_DestructUPnPService(s1); s1 = s2; } LVL3DEBUG(printf("\r\n\r\nDevice Destructed\r\n");) if(device->PresentationURL!=NULL) {free(device->PresentationURL);} if(device->ManufacturerName!=NULL) {free(device->ManufacturerName);} if(device->ManufacturerURL!=NULL) {free(device->ManufacturerURL);} if(device->ModelName!=NULL) {free(device->ModelName);} if(device->ModelNumber!=NULL) {free(device->ModelNumber);} if(device->ModelURL!=NULL) {free(device->ModelURL);} if(device->ModelDescription!=NULL) {free(device->ModelDescription);} if(device->DeviceType!=NULL) {free(device->DeviceType);} if(device->FriendlyName!=NULL) {free(device->FriendlyName);} if(device->LocationURL!=NULL) {free(device->LocationURL);} if(device->UDN!=NULL) {free(device->UDN);} if(device->InterfaceToHost!=NULL) {free(device->InterfaceToHost);} if(device->Reserved3!=NULL) {free(device->Reserved3);} if(device->CustomTagTable != NULL) { en = ILibHashTree_GetEnumerator(device->CustomTagTable); while(ILibHashTree_MoveNext(en)==0) { ILibHashTree_GetValue(en,&key,&keyLen,&ht2); en2 = ILibHashTree_GetEnumerator(ht2); while(ILibHashTree_MoveNext(en2)==0) { ILibHashTree_GetValue(en2,&key,&keyLen,&val); if(val!=NULL) { free(val); } } ILibHashTree_DestroyEnumerator(en2); ILibDestroyHashTree(ht2); } ILibHashTree_DestroyEnumerator(en); ILibDestroyHashTree(device->CustomTagTable); } free(device);}void MSCP_AddRef(struct UPnPDevice *device){ struct UPnPDevice *d = device; while(d->Parent!=NULL) {d = d->Parent;} ++d->ReferenceCount;}void MSCP_Release(struct UPnPDevice *device){ struct UPnPDevice *d = device; while(d->Parent!=NULL) {d = d->Parent;} --d->ReferenceCount; if(d->ReferenceCount<=0) { MSCP_DestructUPnPDevice(d); }}//void UPnPDeviceDescriptionInterruptSink(void *sender, void *user1, void *user2)//{ // struct CustomUserData *cd = (struct CustomUserData*)user1; // free(cd->buffer); // free(user1); //}#if 0static int MSCP_IsLegacyDevice(struct packetheader *header){ struct packetheader_field_node *f; struct parser_result_field *prf; struct parser_result *r,*r2; int Legacy=1; // Check version of Device f = header->FirstField; while(f!=NULL) { if(f->FieldLength==6 && strncasecmp(f->Field,"SERVER",6)==0) { // Check MSCP_ version of the Control Point which invoked us r = ILibParseString(f->FieldData,0,f->FieldDataLength," ",1); prf = r->FirstResult; while(prf!=NULL) { if(prf->datalength>5 && memcmp(prf->data,"UPnP/",5)==0) { r2 = ILibParseString(prf->data+5,0,prf->datalength-5,".",1); r2->FirstResult->data[r2->FirstResult->datalength]=0; r2->LastResult->data[r2->LastResult->datalength]=0; if(atoi(r2->FirstResult->data)==1 && atoi(r2->LastResult->data)>0) { Legacy=0; } ILibDestructParserResults(r2); } prf = prf->NextResult; } ILibDestructParserResults(r); } if(Legacy) { f = f->NextField; } else { break; } } return(Legacy);}static void MSCP_Push(struct MSCP__Stack **pp_Top, void *data){ struct MSCP__Stack *frame = (struct MSCP__Stack*)malloc(sizeof(struct MSCP__Stack)); frame->data = data; frame->next = *pp_Top; *pp_Top = frame;}static void *MSCP_Pop(struct MSCP__Stack **pp_Top){ struct MSCP__Stack *frame = *pp_Top; void *RetVal = NULL; if(frame!=NULL) { *pp_Top = frame->next; RetVal = frame->data; free(frame); } return(RetVal);}static void *MSCP_Peek(struct MSCP__Stack **pp_Top){ struct MSCP__Stack *frame = *pp_Top; void *RetVal = NULL; if(frame!=NULL) { RetVal = (*pp_Top)->data; } return(RetVal);}static void MSCP_Flush(struct MSCP__Stack **pp_Top){ while(MSCP_Pop(pp_Top)!=NULL) {} *pp_Top = NULL;}#endifstruct UPnPDevice* MSCP_GetDeviceAtUDN(void *v_CP,char* UDN){ struct UPnPDevice *RetVal = NULL; struct MSCP_CP* CP = (struct MSCP_CP*)v_CP; ILibHashTree_Lock(CP->DeviceTable); RetVal = (struct UPnPDevice*)ILibGetEntry(CP->DeviceTable,UDN,(int)strlen(UDN)); ILibHashTree_UnLock(CP->DeviceTable); return(RetVal);}static struct packetheader *MSCP_BuildPacket(char* IP, int Port, char* Path, char* cmd){ struct packetheader *RetVal = ILibCreateEmptyPacket(); char* HostLine = (char*)malloc((int)strlen(IP)+7); int HostLineLength = sprintf(HostLine,"%s:%d",IP,Port); ILibSetVersion(RetVal,"1.1",3); ILibSetDirective(RetVal,cmd,(int)strlen(cmd),Path,(int)strlen(Path)); ILibAddHeaderLine(RetVal,"Host",4,HostLine,HostLineLength); ILibAddHeaderLine(RetVal,"User-Agent",10,MSCP_PLATFORM,(int)strlen(MSCP_PLATFORM)); free(HostLine); return(RetVal);}/*static void MSCP_RemoveServiceFromDevice(struct UPnPDevice *device, struct UPnPService *service){ struct UPnPService *s = device->Services; if(s==service) { device->Services = s->Next; MSCP_DestructUPnPService(service); return; } while(s->Next!=NULL) { if(s->Next == service) { s->Next = s->Next->Next; MSCP_DestructUPnPService(service); return; } s = s->Next; }}*/static void MSCP_ProcessDevice(void *v_cp,struct UPnPDevice *device){ struct MSCP_CP* cp = (struct MSCP_CP*)v_cp; struct UPnPDevice *EmbeddedDevice = device->EmbeddedDevices; while(EmbeddedDevice!=NULL) { MSCP_ProcessDevice(v_cp,EmbeddedDevice); EmbeddedDevice = EmbeddedDevice->Next; } // Create a table entry for each Unique Device Name, for easy mapping // of ssdp:byebye packets. This way any byebye packet from the device // heirarchy will result in the device being removed. ILibHashTree_Lock(cp->DeviceTable); ILibAddEntry(cp->DeviceTable,device->UDN,(int)strlen(device->UDN),device); ILibHashTree_UnLock(cp->DeviceTable);}static void MSCP_PrintUPnPDevice(int indents, struct UPnPDevice *device){ struct UPnPService *s; struct UPnPDevice *d; struct UPnPAction *a; int x=0; for(x=0;x<indents;++x) {printf(" ");} printf("Device: %s\r\n",device->DeviceType); for(x=0;x<indents;++x) {printf(" ");} printf("Friendly: %s\r\n",device->FriendlyName); s = device->Services; while(s!=NULL) { for(x=0;x<indents;++x) {printf(" ");} printf(" Service: %s\r\n",s->ServiceType); a = s->Actions; while(a!=NULL) { for(x=0;x<indents;++x) {printf(" ");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -