/******************************************************************************** * TvCtrlPointAddDevice * * Description: * If the device is not already included in the global device list, * add it. Otherwise, update its advertisement expiration timeout. * * Parameters: * DescDoc -- The description document for the device * location -- The location of the description document URL * expires -- The expiration time for this advertisement * ********************************************************************************/ void TvCtrlPointAddDevice( IXML_Document *DescDoc, const char *location, int expires) { char *deviceType = NULL; char *friendlyName = NULL; char presURL[200]; char *baseURL = NULL; char *relURL = NULL; char *UDN = NULL; char *serviceId[TV_SERVICE_SERVCOUNT] = { NULL, NULL }; char *eventURL[TV_SERVICE_SERVCOUNT] = { NULL, NULL }; char *controlURL[TV_SERVICE_SERVCOUNT] = { NULL, NULL }; Upnp_SID eventSID[TV_SERVICE_SERVCOUNT]; int TimeOut[TV_SERVICE_SERVCOUNT] = { default_timeout, default_timeout }; struct TvDeviceNode *deviceNode; struct TvDeviceNode *tmpdevnode; int ret = 1; int found = 0; int service; int var; ithread_mutex_lock(&DeviceListMutex); /* Read key elements from description document */ UDN = SampleUtil_GetFirstDocumentItem(DescDoc, "UDN"); deviceType = SampleUtil_GetFirstDocumentItem(DescDoc, "deviceType"); friendlyName = SampleUtil_GetFirstDocumentItem(DescDoc, "friendlyName"); baseURL = SampleUtil_GetFirstDocumentItem(DescDoc, "URLBase"); relURL = SampleUtil_GetFirstDocumentItem(DescDoc, "presentationURL"); ret = UpnpResolveURL((baseURL ? baseURL : location), relURL, presURL); if (UPNP_E_SUCCESS != ret) SampleUtil_Print("Error generating presURL from %s + %s\n", baseURL, relURL); if (strcmp(deviceType, TvDeviceType) == 0) { SampleUtil_Print("Found Tv device\n"); /* Check if this device is already in the list */ tmpdevnode = GlobalDeviceList; while (tmpdevnode) { if (strcmp(tmpdevnode->device.UDN, UDN) == 0) { found = 1; break; } tmpdevnode = tmpdevnode->next; } if (found) { /* The device is already there, so just update */ /* the advertisement timeout field */ tmpdevnode->device.AdvrTimeOut = expires; } else { for (service = 0; service < TV_SERVICE_SERVCOUNT; service++) { if (SampleUtil_FindAndParseService (DescDoc, location, TvServiceType[service], &serviceId[service], &eventURL[service], &controlURL[service])) { SampleUtil_Print ("Subscribing to EventURL %s...\n", eventURL[service]); ret = UpnpSubscribe(ctrlpt_handle, eventURL[service], &TimeOut[service], eventSID[service]); if (ret == UPNP_E_SUCCESS) { SampleUtil_Print ("Subscribed to EventURL with SID=%s\n", eventSID[service]); } else { SampleUtil_Print ("Error Subscribing to EventURL -- %d\n", ret); strcpy(eventSID[service], ""); } } else { SampleUtil_Print ("Error: Could not find Service: %s\n", TvServiceType[service]); } } /* Create a new device node */ deviceNode = (struct TvDeviceNode *) malloc(sizeof(struct TvDeviceNode)); strcpy(deviceNode->device.UDN, UDN); strcpy(deviceNode->device.DescDocURL, location); strcpy(deviceNode->device.FriendlyName, friendlyName); strcpy(deviceNode->device.PresURL, presURL); deviceNode->device.AdvrTimeOut = expires; for (service = 0; service < TV_SERVICE_SERVCOUNT; service++) { strcpy(deviceNode->device.TvService[service]. ServiceId, serviceId[service]); strcpy(deviceNode->device.TvService[service]. ServiceType, TvServiceType[service]); strcpy(deviceNode->device.TvService[service]. ControlURL, controlURL[service]); strcpy(deviceNode->device.TvService[service]. EventURL, eventURL[service]); strcpy(deviceNode->device.TvService[service]. SID, eventSID[service]); for (var = 0; var < TvVarCount[service]; var++) { deviceNode->device. TvService[service].VariableStrVal [var] = (char *)malloc(TV_MAX_VAL_LEN); strcpy(deviceNode->device. TvService[service].VariableStrVal [var], ""); } } deviceNode->next = NULL; /* Insert the new device node in the list */ if ((tmpdevnode = GlobalDeviceList)) { while (tmpdevnode) { if (tmpdevnode->next) { tmpdevnode = tmpdevnode->next; } else { tmpdevnode->next = deviceNode; break; } } } else { GlobalDeviceList = deviceNode; } /*Notify New Device Added */ SampleUtil_StateUpdate(NULL, NULL, deviceNode->device.UDN, DEVICE_ADDED); } } ithread_mutex_unlock(&DeviceListMutex); if (deviceType) free(deviceType); if (friendlyName) free(friendlyName); if (UDN) free(UDN); if (baseURL) free(baseURL); if (relURL) free(relURL); for (service = 0; service < TV_SERVICE_SERVCOUNT; service++) { if (serviceId[service]) free(serviceId[service]); if (controlURL[service]) free(controlURL[service]); if (eventURL[service]) free(eventURL[service]); } }
int TvDeviceStateTableInit(char *DescDocURL) { IXML_Document *DescDoc = NULL; int ret = UPNP_E_SUCCESS; char *servid_ctrl = NULL; char *evnturl_ctrl = NULL; char *ctrlurl_ctrl = NULL; char *servid_pict = NULL; char *evnturl_pict = NULL; char *ctrlurl_pict = NULL; char *udn = NULL; /*Download description document */ if (UpnpDownloadXmlDoc(DescDocURL, &DescDoc) != UPNP_E_SUCCESS) { SampleUtil_Print("TvDeviceStateTableInit -- Error Parsing %s\n", DescDocURL); ret = UPNP_E_INVALID_DESC; goto error_handler; } udn = SampleUtil_GetFirstDocumentItem(DescDoc, "UDN"); /* Find the Tv Control Service identifiers */ if (!SampleUtil_FindAndParseService(DescDoc, DescDocURL, TvServiceType[TV_SERVICE_CONTROL], &servid_ctrl, &evnturl_ctrl, &ctrlurl_ctrl)) { SampleUtil_Print("TvDeviceStateTableInit -- Error: Could not find Service: %s\n", TvServiceType[TV_SERVICE_CONTROL]); ret = UPNP_E_INVALID_DESC; goto error_handler; } /* set control service table */ SetServiceTable(TV_SERVICE_CONTROL, udn, servid_ctrl, TvServiceType[TV_SERVICE_CONTROL], &tv_service_table[TV_SERVICE_CONTROL]); /* Find the Tv Picture Service identifiers */ if (!SampleUtil_FindAndParseService(DescDoc, DescDocURL, TvServiceType[TV_SERVICE_PICTURE], &servid_pict, &evnturl_pict, &ctrlurl_pict)) { SampleUtil_Print("TvDeviceStateTableInit -- Error: Could not find Service: %s\n", TvServiceType[TV_SERVICE_PICTURE]); ret = UPNP_E_INVALID_DESC; goto error_handler; } /* set picture service table */ SetServiceTable(TV_SERVICE_PICTURE, udn, servid_pict, TvServiceType[TV_SERVICE_PICTURE], &tv_service_table[TV_SERVICE_PICTURE]); error_handler: /* clean up */ if (udn) free(udn); if (servid_ctrl) free(servid_ctrl); if (evnturl_ctrl) free(evnturl_ctrl); if (ctrlurl_ctrl) free(ctrlurl_ctrl); if (servid_pict) free(servid_pict); if (evnturl_pict) free(evnturl_pict); if (ctrlurl_pict) free(ctrlurl_pict); if (DescDoc) ixmlDocument_free(DescDoc); return (ret); }
/******************************************************************************** * WscUPnPCPAddDevice * * Description: * Add a new Wsc device into the wsc device list or just update its advertisement * expiration timeout if it alreay exists in the list. * * Parameters: * deviceType -- The device type want to add to the Device List * d_event -- The "Upnp_Discovery" data * * Return: * WSC_SYS_SUCCESS - if success * other value - if failure ********************************************************************************/ int WscUPnPCPAddDevice( IN char *deviceType, IN struct Upnp_Discovery *d_event, OUT unsigned int *outIPAddr) { IXML_Document *DescDoc = NULL, *scpdDescDoc = NULL; char *deviceTypeStr = NULL, *friendlyName = NULL, *baseURL = NULL, *relURL = NULL, *UDN = NULL; char presURL[200] = {0}; char *serviceId = NULL, *SCPDURL = NULL, *eventURL = NULL, *controlURL = NULL; Upnp_SID eventSID; struct upnpDeviceNode *newDeviceNode, *devNodePtr; int ret = WSC_SYS_ERROR; int found = 0; int TimeOut = DEF_SUBSCRIPTION_TIMEOUT; unsigned int ipAddr = 0; unsigned short port = 0; if(d_event->DestAddr != NULL) { ipAddr = (unsigned int)d_event->DestAddr->sin_addr.s_addr; port = (unsigned short)d_event->DestAddr->sin_port; *outIPAddr = ipAddr; } printf("%s():outIPAddr=0x%x!\n", __FUNCTION__, *outIPAddr); if( !(strcmp(&HostDescURL[0], &d_event->Location[0]))) { // DBGPRINTF(RT_DBG_INFO, "%s():Adver from LocalDev, ignore it!\n", __FUNCTION__); goto done; } // Check if this device is already in the list devNodePtr = WscDeviceList; while (devNodePtr) { if((strcmp(devNodePtr->device.UDN, d_event->DeviceId) == 0) && (strcmp(devNodePtr->device.DescDocURL, d_event->Location) == 0)) { found = 1; break; } devNodePtr = devNodePtr->next; } if (found) { // Update the advertisement timeout field // DBGPRINTF(RT_DBG_INFO, "Old device, just update the expires!\n"); devNodePtr->device.AdvrTimeOut = d_event->Expires; devNodePtr->device.timeCount = 0; } else { DBGPRINTF(RT_DBG_INFO, "Adver from a new device!\n"); if((ret = UpnpDownloadXmlDoc(d_event->Location, &DescDoc)) != UPNP_E_SUCCESS){ DBGPRINTF(RT_DBG_ERROR, "Get device description failed from %s -- err=%d\n", d_event->Location, ret); goto done; } /* Read key elements from description document */ UDN = SampleUtil_GetFirstDocumentItem(DescDoc, "UDN"); deviceTypeStr = SampleUtil_GetFirstDocumentItem(DescDoc, "deviceType"); friendlyName = SampleUtil_GetFirstDocumentItem(DescDoc, "friendlyName"); baseURL = SampleUtil_GetFirstDocumentItem(DescDoc, "URLBase"); relURL = SampleUtil_GetFirstDocumentItem(DescDoc, "presentationURL"); if((UDN == NULL) || (deviceTypeStr == NULL) || (friendlyName == NULL)) { DBGPRINTF(RT_DBG_ERROR, "%s(): Get UDN failed!\n", __FUNCTION__); goto done; } UpnpResolveURL((baseURL ? baseURL : d_event->Location), relURL, presURL); if (SampleUtil_FindAndParseService(DescDoc, d_event->Location, WscServiceTypeStr, &serviceId, &SCPDURL, &eventURL,&controlURL)) { if (SCPDURL != NULL) { if ((ret = UpnpDownloadXmlDoc(SCPDURL, &scpdDescDoc)) != UPNP_E_SUCCESS) { DBGPRINTF(RT_DBG_ERROR, "Get service description failed from %s -- err=%d\n", SCPDURL, ret); } else { WscUPnPCPCheckService(scpdDescDoc); free(scpdDescDoc); } } if ((ret = UpnpSubscribe(WscCPHandle, eventURL, &TimeOut, eventSID)) != UPNP_E_SUCCESS) { DBGPRINTF(RT_DBG_ERROR, "Error Subscribing to EventURL(%s) -- %d\n", eventURL, ret); goto done; } /* Create a new device node */ newDeviceNode = (struct upnpDeviceNode *)malloc(sizeof(struct upnpDeviceNode)); if (newDeviceNode == NULL) { DBGPRINTF(RT_DBG_ERROR, "%s: create new wsc Device Node failed!\n", __FUNCTION__); goto done; } memset(newDeviceNode, 0, sizeof(newDeviceNode)); newDeviceNode->device.services.StateVarVal[WSC_EVENT_WLANEVENT] = NULL; newDeviceNode->device.services.StateVarVal[WSC_EVENT_APSTATUS] = NULL; newDeviceNode->device.services.StateVarVal[WSC_EVENT_STASTATUS] = NULL; strncpy(newDeviceNode->device.UDN, UDN, NAME_SIZE-1); strncpy(newDeviceNode->device.DescDocURL, d_event->Location, NAME_SIZE-1); strncpy(newDeviceNode->device.FriendlyName, friendlyName, NAME_SIZE-1); strncpy(newDeviceNode->device.PresURL, presURL, NAME_SIZE-1); newDeviceNode->device.AdvrTimeOut = d_event->Expires; newDeviceNode->device.timeCount = 0; newDeviceNode->device.ipAddr = ipAddr; strncpy(newDeviceNode->device.services.ServiceType, WscServiceTypeStr, NAME_SIZE-1); if (serviceId) strncpy(newDeviceNode->device.services.ServiceId, serviceId, NAME_SIZE-1); if (SCPDURL) strncpy(newDeviceNode->device.services.SCPDURL, SCPDURL, NAME_SIZE-1); if (eventURL) strncpy(newDeviceNode->device.services.EventURL, eventURL, NAME_SIZE-1); if (controlURL) strncpy(newDeviceNode->device.services.ControlURL, controlURL, NAME_SIZE-1); if (eventSID) strncpy(newDeviceNode->device.services.SID, eventSID, NAME_SIZE-1); newDeviceNode->next = NULL; #if 0 for (var = 0; var < WSC_STATE_VAR_COUNT; var++) { deviceNode->device.services.serviceList.stateVarVals[var] = (char *)malloc(WSC_STATE_VAR_MAX_STR_LEN); strcpy(deviceNode->device.services.serviceList.stateVarVals[var], ""); } #endif // Insert the new device node in the list if(WscDeviceList) { newDeviceNode->next = WscDeviceList->next; WscDeviceList->next = newDeviceNode; } else { WscDeviceList = newDeviceNode; } ret = WSC_SYS_SUCCESS; // TODO:Notify New Device Added //WscCPDevUpdate(NULL, NULL, deviceNode->device.UDN, DEVICE_ADDED); } else { DBGPRINTF(RT_DBG_ERROR, "Error: Could not find Service: %s\n", WscServiceTypeStr); } } done: if (DescDoc) ixmlDocument_free(DescDoc); if (UDN) free(UDN); if (deviceTypeStr) free(deviceTypeStr); if (friendlyName) free(friendlyName); if (baseURL) free(baseURL); if (relURL) free(relURL); if (serviceId) free(serviceId); if (controlURL) free(controlURL); if (eventURL) free(eventURL); return ret; }