/****************************************************************************** * UpnpUtil_ResolveURL *****************************************************************************/ char* UpnpUtil_ResolveURL (void* talloc_context, const char* base, const char* rel) { // Warning : must add +2 (and not +1) to have a large enough buffer, // to be consistent with resolve_rel_url() in // libupnp/upnp/src/genlib/net/uri/uri.c ! char resolved [(base ? strlen(base):0) + (rel ? strlen(rel):0) + 2]; resolved[0] = '\0'; if (rel && *rel) { int rc = UpnpResolveURL (base, rel, resolved); if (rc != UPNP_E_SUCCESS) { Log_Printf (LOG_ERROR, "Error generating URL from '%s' + '%s'", NN(base), NN(rel)); resolved[0] = '\0'; } } return talloc_strdup (talloc_context, resolved); }
/******************************************************************************** * upnp_igd_add_device * * Description: * If the device is not already included in the global device list, * add it. Otherwise, update its advertisement expiration timeout. * * Parameters: * igd_ctxt -- The upnp igd context * desc_doc -- The description document for the device * d_event -- event associated with the new device * ********************************************************************************/ void upnp_igd_add_device(upnp_igd_context *igd_ctxt, IXML_Document *desc_doc, struct Upnp_Discovery *d_event) { upnp_igd_device_node *deviceNode, *tmpdevnode; int found = 0; int ret; int service, var; char presURL[200]; char *serviceId; char *event_url; char *controlURL; Upnp_SID eventSID; char *deviceType = NULL; char *friendlyName = NULL; char *modelName = NULL; char *modelNumber = NULL; char *baseURL = NULL; char *relURL = NULL; char *UDN = NULL; UDN = upnp_igd_get_first_document_item(igd_ctxt, desc_doc, "UDN"); deviceType = upnp_igd_get_first_document_item(igd_ctxt, desc_doc, "deviceType"); friendlyName = upnp_igd_get_first_document_item(igd_ctxt, desc_doc, "friendlyName"); modelName = upnp_igd_get_first_document_item(igd_ctxt, desc_doc, "modelName"); modelNumber = upnp_igd_get_first_document_item(igd_ctxt, desc_doc, "modelNumber"); baseURL = upnp_igd_get_first_document_item(igd_ctxt, desc_doc, "URLBase"); relURL = upnp_igd_get_first_document_item(igd_ctxt, desc_doc, "presentationURL"); ret = UpnpResolveURL((baseURL ? baseURL : d_event->Location), relURL, presURL); if (UPNP_E_SUCCESS != ret) { upnp_igd_print(igd_ctxt, UPNP_IGD_ERROR, "Error generating presURL from %s + %s", baseURL, relURL); } ithread_mutex_lock(&igd_ctxt->devices_mutex); if (strcmp(deviceType, IGDDeviceType) == 0) { /* Check if this device is already in the list */ tmpdevnode = igd_ctxt->devices; 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.advr_time_out = d_event->Expires; upnp_igd_print(igd_ctxt, UPNP_IGD_DEBUG, "IGD device: %s[%s] | Update expires(%d)", friendlyName, UDN, tmpdevnode->device.advr_time_out); } else { upnp_igd_print(igd_ctxt, UPNP_IGD_MESSAGE, "Add IGD device: %s[%s]", friendlyName, UDN); /* Create a new device node */ deviceNode = (upnp_igd_device_node *) malloc(sizeof(upnp_igd_device_node)); memset(deviceNode->device.services, '\0', sizeof(upnp_igd_service) * IGD_SERVICE_SERVCOUNT); strncpy(deviceNode->device.udn, UDN, sizeof(deviceNode->device.udn)); strncpy(deviceNode->device.desc_doc_url, d_event->Location, sizeof(deviceNode->device.desc_doc_url)); strncpy(deviceNode->device.friendly_name, friendlyName, sizeof(deviceNode->device.friendly_name)); strncpy(deviceNode->device.model_name, modelName, sizeof(deviceNode->device.model_name)); strncpy(deviceNode->device.model_number, modelNumber, sizeof(deviceNode->device.model_number)); strncpy(deviceNode->device.pres_url, presURL, sizeof(deviceNode->device.pres_url)); deviceNode->device.advr_time_out = d_event->Expires; // Reset values serviceId = NULL; event_url = NULL; controlURL = NULL; eventSID[0] = '\0'; for (service = 0; service < IGD_SERVICE_SERVCOUNT; service++) { if (upnp_igd_get_find_and_parse_service(igd_ctxt, desc_doc, d_event->Location, IGDServiceType[service], &serviceId, &event_url, &controlURL)) { upnp_igd_print(igd_ctxt, UPNP_IGD_DEBUG, "Subscribing to EventURL %s...",event_url); ret = UpnpSubscribe(igd_ctxt->upnp_handle, event_url, &IGDTimeOut[service], eventSID); if (ret == UPNP_E_SUCCESS) { upnp_igd_print(igd_ctxt, UPNP_IGD_DEBUG, "Subscribed to EventURL with SID=%s", eventSID); } else { upnp_igd_print(igd_ctxt, UPNP_IGD_ERROR, "Error Subscribing to EventURL -- %d", ret); strcpy(eventSID, ""); } } else { upnp_igd_print(igd_ctxt, UPNP_IGD_ERROR, "Could not find Service: %s", IGDServiceType[service]); } if(serviceId != NULL) { upnp_igd_strncpy(deviceNode->device.services[service].service_id, serviceId, sizeof(deviceNode->device.services[service].service_id)); } upnp_igd_strncpy(deviceNode->device.services[service].service_type, IGDServiceName[service], sizeof(deviceNode->device.services[service].service_type)); if(controlURL != NULL) { upnp_igd_strncpy(deviceNode->device.services[service].control_url, controlURL, sizeof(deviceNode->device.services[service].control_url)); } if(event_url != NULL) { upnp_igd_strncpy(deviceNode->device.services[service].event_url, event_url, sizeof(deviceNode->device.services[service].event_url)); } if(eventSID != NULL) { upnp_igd_strncpy(deviceNode->device.services[service].sid, eventSID, sizeof(deviceNode->device.services[service].sid)); } for (var = 0; var < IGDVarCount[service]; var++) { deviceNode->device.services[service].variables[var] = (char *)malloc(IGD_MAX_VAL_LEN); strcpy(deviceNode->device.services[service].variables[var], ""); } } deviceNode->next = NULL; /* Insert the new device node in the list */ if ((tmpdevnode = igd_ctxt->devices)) { while (tmpdevnode) { if (tmpdevnode->next) { tmpdevnode = tmpdevnode->next; } else { tmpdevnode->next = deviceNode; break; } } } else { igd_ctxt->devices = deviceNode; } // Ask some details upnp_igd_send_action(igd_ctxt, deviceNode, IGD_SERVICE_WANIPCONNECTION, "GetNATRSIPStatus", NULL, NULL, 0, upnp_igd_callback, igd_ctxt); // Usefull on some router upnp_igd_send_action(igd_ctxt, deviceNode, IGD_SERVICE_WANIPCONNECTION, "GetStatusInfo", NULL, NULL, 0, upnp_igd_callback, igd_ctxt); upnp_igd_send_action(igd_ctxt, deviceNode, IGD_SERVICE_WANIPCONNECTION, "GetExternalIPAddress", NULL, NULL, 0, upnp_igd_callback, igd_ctxt); upnp_context_add_callback(igd_ctxt, UPNP_IGD_DEVICE_ADDED, NULL); if (serviceId) free(serviceId); if (controlURL) free(controlURL); if (event_url) free(event_url); } } ithread_mutex_unlock(&igd_ctxt->devices_mutex); if (deviceType) free(deviceType); if (friendlyName) free(friendlyName); if (modelName) free(modelName); if (modelNumber) free(modelNumber); if (UDN) free(UDN); if (baseURL) free(baseURL); if (relURL) free(relURL); }
/******************************************************************************** * SampleUtil_FindAndParseService * * Description: * This routine finds the first occurance of a service in a DOM representation * of a description document and parses it. * * Parameters: * DescDoc -- The DOM description document * location -- The location of the description document * serviceSearchType -- The type of service to search for * serviceId -- OUT -- The service ID * eventURL -- OUT -- The event URL for the service * controlURL -- OUT -- The control URL for the service * ********************************************************************************/ int SampleUtil_FindAndParseService( IN IXML_Document * DescDoc, IN char *location, IN char *serviceType, OUT char **serviceId, OUT char **eventURL, OUT char **controlURL ) { int i, length, found = 0; int ret; char *tempServiceType = NULL; char *baseURL = NULL; char *base; char *relcontrolURL = NULL, *releventURL = NULL; IXML_NodeList *serviceList = NULL; IXML_Element *service = NULL; baseURL = SampleUtil_GetFirstDocumentItem( DescDoc, "URLBase" ); if( baseURL ) base = baseURL; else base = location; serviceList = SampleUtil_GetFirstServiceList( DescDoc ); length = ixmlNodeList_length( serviceList ); for( i = 0; i < length; i++ ) { service = ( IXML_Element * ) ixmlNodeList_item( serviceList, i ); tempServiceType = SampleUtil_GetFirstElementItem( ( IXML_Element * ) service, "serviceType" ); if( strcmp( tempServiceType, serviceType ) == 0 ) { SampleUtil_Print( "Found service: %s\n", serviceType ); *serviceId = SampleUtil_GetFirstElementItem( service, "serviceId" ); SampleUtil_Print( "serviceId: %s\n", ( *serviceId ) ); relcontrolURL = SampleUtil_GetFirstElementItem( service, "controlURL" ); releventURL = SampleUtil_GetFirstElementItem( service, "eventSubURL" ); *controlURL = malloc( strlen( base ) + strlen( relcontrolURL ) + 1 ); if( *controlURL ) { ret = UpnpResolveURL( base, relcontrolURL, *controlURL ); if( ret != UPNP_E_SUCCESS ) SampleUtil_Print ( "Error generating controlURL from %s + %s\n", base, relcontrolURL ); } *eventURL = malloc( strlen( base ) + strlen( releventURL ) + 1 ); if( *eventURL ) { ret = UpnpResolveURL( base, releventURL, *eventURL ); if( ret != UPNP_E_SUCCESS ) SampleUtil_Print ( "Error generating eventURL from %s + %s\n", base, releventURL ); } if( relcontrolURL ) free( relcontrolURL ); if( releventURL ) free( releventURL ); relcontrolURL = releventURL = NULL; found = 1; break; } if( tempServiceType ) free( tempServiceType ); tempServiceType = NULL; } if( tempServiceType ) free( tempServiceType ); if( serviceList ) ixmlNodeList_free( serviceList ); if( baseURL ) free( baseURL ); return ( found ); }
void MediaServer::parseDeviceDescription( IXML_Document* doc, const char* location, services_discovery_t* p_sd ) { if ( !doc ) { msg_Dbg( p_sd, "%s:%d: NULL", __FILE__, __LINE__ ); return; } if ( !location ) { msg_Dbg( p_sd, "%s:%d: NULL", __FILE__, __LINE__ ); return; } const char* baseURL = location; // Try to extract baseURL IXML_NodeList* urlList = ixmlDocument_getElementsByTagName( doc, "baseURL" ); if ( !urlList ) { if ( IXML_Node* urlNode = ixmlNodeList_item( urlList, 0 ) ) { IXML_Node* textNode = ixmlNode_getFirstChild( urlNode ); if ( textNode ) baseURL = ixmlNode_getNodeValue( textNode ); } ixmlNodeList_free( urlList ); } // Get devices IXML_NodeList* deviceList = ixmlDocument_getElementsByTagName( doc, "device" ); if ( deviceList ) { for ( unsigned int i = 0; i < ixmlNodeList_length( deviceList ); i++ ) { IXML_Element* deviceElement = ( IXML_Element* ) ixmlNodeList_item( deviceList, i ); const char* deviceType = xml_getChildElementValue( deviceElement, "deviceType" ); if ( !deviceType ) { msg_Dbg( p_sd, "%s:%d: no deviceType!", __FILE__, __LINE__ ); continue; } if ( strcmp( MEDIA_SERVER_DEVICE_TYPE, deviceType ) != 0 ) continue; const char* UDN = xml_getChildElementValue( deviceElement, "UDN" ); if ( !UDN ) { msg_Dbg( p_sd, "%s:%d: no UDN!", __FILE__, __LINE__ ); continue; } if ( p_sd->p_sys->serverList->getServer( UDN ) != 0 ) continue; const char* friendlyName = xml_getChildElementValue( deviceElement, "friendlyName" ); if ( !friendlyName ) { msg_Dbg( p_sd, "%s:%d: no friendlyName!", __FILE__, __LINE__ ); continue; } MediaServer* server = new MediaServer( UDN, friendlyName, p_sd ); if ( !p_sd->p_sys->serverList->addServer( server ) ) { delete server; server = 0; continue; } // Check for ContentDirectory service... IXML_NodeList* serviceList = ixmlElement_getElementsByTagName( deviceElement, "service" ); if ( serviceList ) { for ( unsigned int j = 0; j < ixmlNodeList_length( serviceList ); j++ ) { IXML_Element* serviceElement = ( IXML_Element* ) ixmlNodeList_item( serviceList, j ); const char* serviceType = xml_getChildElementValue( serviceElement, "serviceType" ); if ( !serviceType ) continue; if ( strcmp( CONTENT_DIRECTORY_SERVICE_TYPE, serviceType ) != 0 ) continue; const char* eventSubURL = xml_getChildElementValue( serviceElement, "eventSubURL" ); if ( !eventSubURL ) continue; const char* controlURL = xml_getChildElementValue( serviceElement, "controlURL" ); if ( !controlURL ) continue; // Try to subscribe to ContentDirectory service char* url = ( char* ) malloc( strlen( baseURL ) + strlen( eventSubURL ) + 1 ); if ( url ) { char* s1 = strdup( baseURL ); char* s2 = strdup( eventSubURL ); if ( UpnpResolveURL( s1, s2, url ) == UPNP_E_SUCCESS ) { server->setContentDirectoryEventURL( url ); server->subscribeToContentDirectory(); } free( s1 ); free( s2 ); free( url ); } // Try to browse content directory... url = ( char* ) malloc( strlen( baseURL ) + strlen( controlURL ) + 1 ); if ( url ) { char* s1 = strdup( baseURL ); char* s2 = strdup( controlURL ); if ( UpnpResolveURL( s1, s2, url ) == UPNP_E_SUCCESS ) { server->setContentDirectoryControlURL( url ); server->fetchContents(); } free( s1 ); free( s2 ); free( url ); } } ixmlNodeList_free( serviceList ); } } ixmlNodeList_free( deviceList ); } }
CUPnPService::CUPnPService( const CUPnPControlPoint &upnpControlPoint, CUPnPLib &upnpLib, IXML_Element *service, const std::string &URLBase) : m_UPnPControlPoint(upnpControlPoint), m_upnpLib(upnpLib), m_serviceType(upnpLib.Element_GetChildValueByTag(service, "serviceType")), m_serviceId (upnpLib.Element_GetChildValueByTag(service, "serviceId")), m_SCPDURL (upnpLib.Element_GetChildValueByTag(service, "SCPDURL")), m_controlURL (upnpLib.Element_GetChildValueByTag(service, "controlURL")), m_eventSubURL(upnpLib.Element_GetChildValueByTag(service, "eventSubURL")), m_timeout(1801), m_SCPD(NULL) { std::ostringstream msg; int errcode; std::vector<char> vscpdURL(URLBase.length() + m_SCPDURL.length() + 1); char *scpdURL = &vscpdURL[0]; errcode = UpnpResolveURL( URLBase.c_str(), m_SCPDURL.c_str(), scpdURL); if( errcode != UPNP_E_SUCCESS ) { msg << "Error generating scpdURL from " << "|" << URLBase << "|" << m_SCPDURL << "|."; AddDebugLogLineM(false, logUPnP, msg); } else { m_absSCPDURL = scpdURL; } std::vector<char> vcontrolURL( URLBase.length() + m_controlURL.length() + 1); char *controlURL = &vcontrolURL[0]; errcode = UpnpResolveURL( URLBase.c_str(), m_controlURL.c_str(), controlURL); if( errcode != UPNP_E_SUCCESS ) { msg << "Error generating controlURL from " << "|" << URLBase << "|" << m_controlURL << "|."; AddDebugLogLineM(false, logUPnP, msg); } else { m_absControlURL = controlURL; } std::vector<char> veventURL( URLBase.length() + m_eventSubURL.length() + 1); char *eventURL = &veventURL[0]; errcode = UpnpResolveURL( URLBase.c_str(), m_eventSubURL.c_str(), eventURL); if( errcode != UPNP_E_SUCCESS ) { msg << "Error generating eventURL from " << "|" << URLBase << "|" << m_eventSubURL << "|."; AddDebugLogLineM(false, logUPnP, msg); } else { m_absEventSubURL = eventURL; } msg << "\n Service:" << "\n serviceType: " << m_serviceType << "\n serviceId: " << m_serviceId << "\n SCPDURL: " << m_SCPDURL << "\n absSCPDURL: " << m_absSCPDURL << "\n controlURL: " << m_controlURL << "\n absControlURL: " << m_absControlURL << "\n eventSubURL: " << m_eventSubURL << "\n absEventSubURL: " << m_absEventSubURL; AddDebugLogLineM(false, logUPnP, msg); if (m_serviceType == upnpLib.UPNP_SERVICE_WAN_IP_CONNECTION || m_serviceType == upnpLib.UPNP_SERVICE_WAN_PPP_CONNECTION) { #if 0 m_serviceType == upnpLib.UPNP_SERVICE_WAN_PPP_CONNECTION || m_serviceType == upnpLib.UPNP_SERVICE_WAN_COMMON_INTERFACE_CONFIG || m_serviceType == upnpLib.UPNP_SERVICE_LAYER3_FORWARDING) { #endif #if 0 //#warning Delete this code on release. if (!upnpLib.m_ctrlPoint.WanServiceDetected()) { // This condition can be used to suspend the parse // of the XML tree. #endif //#warning Delete this code when m_WanService is no longer used. upnpLib.m_ctrlPoint.SetWanService(this); // Log it msg.str(""); msg << "WAN Service Detected: '" << m_serviceType << "'."; AddDebugLogLineM(true, logUPnP, msg); // Subscribe upnpLib.m_ctrlPoint.Subscribe(*this); #if 0 //#warning Delete this code on release. } else { msg.str(""); msg << "WAN service detected again: '" << m_serviceType << "'. Will only use the first instance."; AddDebugLogLineM(true, logUPnP, msg); } #endif } else {
void MediaServerList::parseNewServer( IXML_Document *doc, const std::string &location ) { if ( !doc ) { msg_Err( m_sd, "Null IXML_Document" ); return; } if ( location.empty() ) { msg_Err( m_sd, "Empty location" ); return; } const char* psz_base_url = location.c_str(); /* Try to extract baseURL */ IXML_NodeList* p_url_list = ixmlDocument_getElementsByTagName( doc, "URLBase" ); if ( p_url_list ) { if ( IXML_Node* p_url_node = ixmlNodeList_item( p_url_list, 0 ) ) { IXML_Node* p_text_node = ixmlNode_getFirstChild( p_url_node ); if ( p_text_node ) psz_base_url = ixmlNode_getNodeValue( p_text_node ); } ixmlNodeList_free( p_url_list ); } /* Get devices */ IXML_NodeList* p_device_list = ixmlDocument_getElementsByTagName( doc, "device" ); if ( !p_device_list ) return; for ( unsigned int i = 0; i < ixmlNodeList_length( p_device_list ); i++ ) { IXML_Element* p_device_element = ( IXML_Element* ) ixmlNodeList_item( p_device_list, i ); if( !p_device_element ) continue; const char* psz_device_type = xml_getChildElementValue( p_device_element, "deviceType" ); if ( !psz_device_type ) { msg_Warn( m_sd, "No deviceType found!" ); continue; } if ( strncmp( MEDIA_SERVER_DEVICE_TYPE, psz_device_type, strlen( MEDIA_SERVER_DEVICE_TYPE ) - 1 ) && strncmp( SATIP_SERVER_DEVICE_TYPE, psz_device_type, strlen( SATIP_SERVER_DEVICE_TYPE ) - 1 ) ) continue; const char* psz_udn = xml_getChildElementValue( p_device_element, "UDN" ); if ( !psz_udn ) { msg_Warn( m_sd, "No UDN!" ); continue; } /* Check if server is already added */ if ( getServer( psz_udn ) ) { msg_Warn( m_sd, "Server with uuid '%s' already exists.", psz_udn ); continue; } const char* psz_friendly_name = xml_getChildElementValue( p_device_element, "friendlyName" ); if ( !psz_friendly_name ) { msg_Dbg( m_sd, "No friendlyName!" ); continue; } std::string iconUrl = getIconURL( p_device_element, psz_base_url ); // We now have basic info, we need to get the content browsing url // so the access module can browse without fetching the manifest again if ( !strncmp( SATIP_SERVER_DEVICE_TYPE, psz_device_type, strlen( SATIP_SERVER_DEVICE_TYPE ) - 1 ) ) { SD::MediaServerDesc* p_server = NULL; vlc_url_t url; vlc_UrlParse( &url, psz_base_url ); char *psz_satip_channellist = config_GetPsz(m_sd, "satip-channelist"); if( !psz_satip_channellist ) { break; } /* a user may have provided a custom playlist url */ if (strncmp(psz_satip_channellist, "CustomList", 10) == 0) { char *psz_satip_playlist_url = config_GetPsz( m_sd, "satip-channellist-url" ); if ( psz_satip_playlist_url ) { p_server = new(std::nothrow) SD::MediaServerDesc( psz_udn, psz_friendly_name, psz_satip_playlist_url, iconUrl ); if( likely( p_server ) ) { p_server->satIpHost = url.psz_host; p_server->isSatIp = true; if( !addServer( p_server ) ) { delete p_server; } } /* to comply with the SAT>IP specification, we don't fall back on another channel list if this path failed */ free( psz_satip_playlist_url ); vlc_UrlClean( &url ); continue; } } /* If requested by the user, check for a SAT>IP m3u list, which may be provided by some rare devices */ if (strncmp(psz_satip_channellist, "ServerList", 10) == 0) { const char* psz_m3u_url = xml_getChildElementValue( p_device_element, "satip:X_SATIPM3U" ); if ( psz_m3u_url ) { if ( strncmp( "http", psz_m3u_url, 4) ) { char* psz_url = NULL; if ( UpnpResolveURL2( psz_base_url, psz_m3u_url, &psz_url ) == UPNP_E_SUCCESS ) { p_server = new(std::nothrow) SD::MediaServerDesc( psz_udn, psz_friendly_name, psz_url, iconUrl ); free(psz_url); } } else { p_server = new(std::nothrow) SD::MediaServerDesc( psz_udn, psz_friendly_name, psz_m3u_url, iconUrl ); } if ( unlikely( !p_server ) ) break; p_server->satIpHost = url.psz_host; p_server->isSatIp = true; if ( !addServer( p_server ) ) delete p_server; free(psz_satip_channellist); } else { msg_Warn( m_sd, "SAT>IP server '%s' did not provide a playlist", url.psz_host); } /* to comply with the SAT>IP specifications, we don't fallback on another channel list if this path failed */ vlc_UrlClean( &url ); continue; } /* Normally, fetch a playlist from the web, * which will be processed by a lua script a bit later */ char *psz_url; if (asprintf( &psz_url, "http://www.satip.info/Playlists/%s.m3u", psz_satip_channellist ) < 0 ) { vlc_UrlClean( &url ); free( psz_satip_channellist ); continue; } p_server = new(std::nothrow) SD::MediaServerDesc( psz_udn, psz_friendly_name, psz_url, iconUrl ); if( likely( p_server ) ) { p_server->satIpHost = url.psz_host; p_server->isSatIp = true; if( !addServer( p_server ) ) { delete p_server; } } free( psz_url ); free( psz_satip_channellist ); vlc_UrlClean( &url ); continue; } /* Check for ContentDirectory service. */ IXML_NodeList* p_service_list = ixmlElement_getElementsByTagName( p_device_element, "service" ); if ( !p_service_list ) continue; for ( unsigned int j = 0; j < ixmlNodeList_length( p_service_list ); j++ ) { IXML_Element* p_service_element = (IXML_Element*)ixmlNodeList_item( p_service_list, j ); const char* psz_service_type = xml_getChildElementValue( p_service_element, "serviceType" ); if ( !psz_service_type ) { msg_Warn( m_sd, "No service type found." ); continue; } int k = strlen( CONTENT_DIRECTORY_SERVICE_TYPE ) - 1; if ( strncmp( CONTENT_DIRECTORY_SERVICE_TYPE, psz_service_type, k ) ) continue; const char* psz_control_url = xml_getChildElementValue( p_service_element, "controlURL" ); if ( !psz_control_url ) { msg_Warn( m_sd, "No control url found." ); continue; } /* Try to browse content directory. */ char* psz_url = ( char* ) malloc( strlen( psz_base_url ) + strlen( psz_control_url ) + 1 ); if ( psz_url ) { if ( UpnpResolveURL( psz_base_url, psz_control_url, psz_url ) == UPNP_E_SUCCESS ) { SD::MediaServerDesc* p_server = new(std::nothrow) SD::MediaServerDesc( psz_udn, psz_friendly_name, psz_url, iconUrl ); free( psz_url ); if ( unlikely( !p_server ) ) break; if ( !addServer( p_server ) ) { delete p_server; continue; } } else free( psz_url ); } } ixmlNodeList_free( p_service_list ); } ixmlNodeList_free( p_device_list ); }
/******************************************************************************** * 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]); } }
void MediaServer::parseDeviceDescription( IXML_Document* p_doc, const char* p_location, services_discovery_t* p_sd ) { if ( !p_doc ) { msg_Err( p_sd, "Null IXML_Document" ); return; } if ( !p_location ) { msg_Err( p_sd, "Null location" ); return; } const char* psz_base_url = p_location; /* Try to extract baseURL */ IXML_NodeList* p_url_list = ixmlDocument_getElementsByTagName( p_doc, "URLBase" ); if ( p_url_list ) { if ( IXML_Node* p_url_node = ixmlNodeList_item( p_url_list, 0 ) ) { IXML_Node* p_text_node = ixmlNode_getFirstChild( p_url_node ); if ( p_text_node ) psz_base_url = ixmlNode_getNodeValue( p_text_node ); } ixmlNodeList_free( p_url_list ); } /* Get devices */ IXML_NodeList* p_device_list = ixmlDocument_getElementsByTagName( p_doc, "device" ); if ( p_device_list ) { for ( unsigned int i = 0; i < ixmlNodeList_length( p_device_list ); i++ ) { IXML_Element* p_device_element = ( IXML_Element* ) ixmlNodeList_item( p_device_list, i ); const char* psz_device_type = xml_getChildElementValue( p_device_element, "deviceType" ); if ( !psz_device_type ) { msg_Warn( p_sd, "No deviceType found!" ); continue; } if ( strncmp( MEDIA_SERVER_DEVICE_TYPE, psz_device_type, strlen( MEDIA_SERVER_DEVICE_TYPE ) - 1 ) != 0 ) continue; const char* psz_udn = xml_getChildElementValue( p_device_element, "UDN" ); if ( !psz_udn ) { msg_Warn( p_sd, "No UDN!" ); continue; } /* Check if server is already added */ if ( p_sd->p_sys->p_server_list->getServer( psz_udn ) != 0 ) { msg_Warn( p_sd, "Server with uuid '%s' already exists.", psz_udn ); continue; } const char* psz_friendly_name = xml_getChildElementValue( p_device_element, "friendlyName" ); if ( !psz_friendly_name ) { msg_Dbg( p_sd, "No friendlyName!" ); continue; } MediaServer* p_server = new MediaServer( psz_udn, psz_friendly_name, p_sd ); if ( !p_sd->p_sys->p_server_list->addServer( p_server ) ) { delete p_server; p_server = 0; continue; } /* Check for ContentDirectory service. */ IXML_NodeList* p_service_list = ixmlElement_getElementsByTagName( p_device_element, "service" ); if ( p_service_list ) { for ( unsigned int j = 0; j < ixmlNodeList_length( p_service_list ); j++ ) { IXML_Element* p_service_element = ( IXML_Element* ) ixmlNodeList_item( p_service_list, j ); const char* psz_service_type = xml_getChildElementValue( p_service_element, "serviceType" ); if ( !psz_service_type ) { msg_Warn( p_sd, "No service type found." ); continue; } int k = strlen( CONTENT_DIRECTORY_SERVICE_TYPE ) - 1; if ( strncmp( CONTENT_DIRECTORY_SERVICE_TYPE, psz_service_type, k ) != 0 ) continue; p_server->_i_content_directory_service_version = psz_service_type[k]; const char* psz_event_sub_url = xml_getChildElementValue( p_service_element, "eventSubURL" ); if ( !psz_event_sub_url ) { msg_Warn( p_sd, "No event subscription url found." ); continue; } const char* psz_control_url = xml_getChildElementValue( p_service_element, "controlURL" ); if ( !psz_control_url ) { msg_Warn( p_sd, "No control url found." ); continue; } /* Try to subscribe to ContentDirectory service */ char* psz_url = ( char* ) malloc( strlen( psz_base_url ) + strlen( psz_event_sub_url ) + 1 ); if ( psz_url ) { if ( UpnpResolveURL( psz_base_url, psz_event_sub_url, psz_url ) == UPNP_E_SUCCESS ) { p_server->setContentDirectoryEventURL( psz_url ); p_server->subscribeToContentDirectory(); } free( psz_url ); } /* Try to browse content directory. */ psz_url = ( char* ) malloc( strlen( psz_base_url ) + strlen( psz_control_url ) + 1 ); if ( psz_url ) { if ( UpnpResolveURL( psz_base_url, psz_control_url, psz_url ) == UPNP_E_SUCCESS ) { p_server->setContentDirectoryControlURL( psz_url ); p_server->fetchContents(); } free( psz_url ); } } ixmlNodeList_free( p_service_list ); } } ixmlNodeList_free( p_device_list ); } }
int SampleUtil_FindAndParseService(IXML_Document *DescDoc, const char *location, const char *serviceType, char **serviceId, char **eventURL, char **controlURL) { unsigned int i; unsigned long length; int found = 0; int ret; #ifdef OLD_FIND_SERVICE_CODE #else /* OLD_FIND_SERVICE_CODE */ unsigned int sindex = 0; #endif /* OLD_FIND_SERVICE_CODE */ char *tempServiceType = NULL; char *baseURL = NULL; const char *base = NULL; char *relcontrolURL = NULL; char *releventURL = NULL; IXML_NodeList *serviceList = NULL; IXML_Element *service = NULL; baseURL = SampleUtil_GetFirstDocumentItem(DescDoc, "URLBase"); if (baseURL) base = baseURL; else base = location; #ifdef OLD_FIND_SERVICE_CODE serviceList = SampleUtil_GetFirstServiceList(DescDoc); #else /* OLD_FIND_SERVICE_CODE */ for (sindex = 0; (serviceList = SampleUtil_GetNthServiceList(DescDoc , sindex)) != NULL; sindex++) { tempServiceType = NULL; relcontrolURL = NULL; releventURL = NULL; service = NULL; #endif /* OLD_FIND_SERVICE_CODE */ length = ixmlNodeList_length(serviceList); for (i = 0; i < length; i++) { service = (IXML_Element *)ixmlNodeList_item(serviceList, i); tempServiceType = SampleUtil_GetFirstElementItem( (IXML_Element *)service, "serviceType"); if (tempServiceType && strcmp(tempServiceType, serviceType) == 0) { SampleUtil_Print("Found service: %s\n", serviceType); *serviceId = SampleUtil_GetFirstElementItem(service, "serviceId"); SampleUtil_Print("serviceId: %s\n", *serviceId); relcontrolURL = SampleUtil_GetFirstElementItem(service, "controlURL"); releventURL = SampleUtil_GetFirstElementItem(service, "eventSubURL"); *controlURL = (char *)malloc(strlen(base) + strlen(relcontrolURL) + 1); if (*controlURL) { ret = UpnpResolveURL(base, relcontrolURL, *controlURL); if (ret != UPNP_E_SUCCESS) SampleUtil_Print("Error generating controlURL from %s + %s\n", base, relcontrolURL); } *eventURL = (char *)malloc(strlen(base) + strlen(releventURL) + 1); if (*eventURL) { ret = UpnpResolveURL(base, releventURL, *eventURL); if (ret != UPNP_E_SUCCESS) SampleUtil_Print("Error generating eventURL from %s + %s\n", base, releventURL); } free(relcontrolURL); free(releventURL); relcontrolURL = NULL; releventURL = NULL; found = 1; break; } free(tempServiceType); tempServiceType = NULL; } free(tempServiceType); tempServiceType = NULL; if (serviceList) ixmlNodeList_free(serviceList); serviceList = NULL; #ifdef OLD_FIND_SERVICE_CODE #else /* OLD_FIND_SERVICE_CODE */ } #endif /* OLD_FIND_SERVICE_CODE */ free(baseURL); return found; }
void MediaServerList::parseNewServer( IXML_Document *doc, const std::string &location ) { if ( !doc ) { msg_Err( p_sd_, "Null IXML_Document" ); return; } if ( location.empty() ) { msg_Err( p_sd_, "Empty location" ); return; } const char* psz_base_url = location.c_str(); /* Try to extract baseURL */ IXML_NodeList* p_url_list = ixmlDocument_getElementsByTagName( doc, "URLBase" ); if ( p_url_list ) { if ( IXML_Node* p_url_node = ixmlNodeList_item( p_url_list, 0 ) ) { IXML_Node* p_text_node = ixmlNode_getFirstChild( p_url_node ); if ( p_text_node ) psz_base_url = ixmlNode_getNodeValue( p_text_node ); } ixmlNodeList_free( p_url_list ); } /* Get devices */ IXML_NodeList* p_device_list = ixmlDocument_getElementsByTagName( doc, "device" ); if ( !p_device_list ) return; for ( unsigned int i = 0; i < ixmlNodeList_length( p_device_list ); i++ ) { IXML_Element* p_device_element = ( IXML_Element* ) ixmlNodeList_item( p_device_list, i ); if( !p_device_element ) continue; const char* psz_device_type = xml_getChildElementValue( p_device_element, "deviceType" ); if ( !psz_device_type ) { msg_Warn( p_sd_, "No deviceType found!" ); continue; } if ( strncmp( MEDIA_SERVER_DEVICE_TYPE, psz_device_type, strlen( MEDIA_SERVER_DEVICE_TYPE ) - 1 ) ) continue; const char* psz_udn = xml_getChildElementValue( p_device_element, "UDN" ); if ( !psz_udn ) { msg_Warn( p_sd_, "No UDN!" ); continue; } /* Check if server is already added */ if ( p_sd_->p_sys->p_server_list->getServer( psz_udn ) ) { msg_Warn( p_sd_, "Server with uuid '%s' already exists.", psz_udn ); continue; } const char* psz_friendly_name = xml_getChildElementValue( p_device_element, "friendlyName" ); if ( !psz_friendly_name ) { msg_Dbg( p_sd_, "No friendlyName!" ); continue; } // We now have basic info, we need to get the content browsing url // so the access module can browse without fetching the manifest again /* Check for ContentDirectory service. */ IXML_NodeList* p_service_list = ixmlElement_getElementsByTagName( p_device_element, "service" ); if ( !p_service_list ) continue; for ( unsigned int j = 0; j < ixmlNodeList_length( p_service_list ); j++ ) { IXML_Element* p_service_element = (IXML_Element*)ixmlNodeList_item( p_service_list, j ); const char* psz_service_type = xml_getChildElementValue( p_service_element, "serviceType" ); if ( !psz_service_type ) { msg_Warn( p_sd_, "No service type found." ); continue; } int k = strlen( CONTENT_DIRECTORY_SERVICE_TYPE ) - 1; if ( strncmp( CONTENT_DIRECTORY_SERVICE_TYPE, psz_service_type, k ) ) continue; const char* psz_control_url = xml_getChildElementValue( p_service_element, "controlURL" ); if ( !psz_control_url ) { msg_Warn( p_sd_, "No control url found." ); continue; } /* Try to browse content directory. */ char* psz_url = ( char* ) malloc( strlen( psz_base_url ) + strlen( psz_control_url ) + 1 ); if ( psz_url ) { if ( UpnpResolveURL( psz_base_url, psz_control_url, psz_url ) == UPNP_E_SUCCESS ) { SD::MediaServerDesc* p_server = new(std::nothrow) SD::MediaServerDesc( psz_udn, psz_friendly_name, psz_url ); free( psz_url ); if ( unlikely( !p_server ) ) break; if ( !addServer( p_server ) ) { delete p_server; continue; } } else free( psz_url ); } } ixmlNodeList_free( p_service_list ); } ixmlNodeList_free( p_device_list ); }
int upnp_igd_get_find_and_parse_service(upnp_igd_context *igd_ctxt, IXML_Document *DescDoc, const char *location, const char *serviceType, char **serviceId, char **eventURL, char **controlURL) { unsigned int i; unsigned long length; int found = 0; int ret; unsigned int sindex = 0; char *tempServiceType = NULL; char *baseURL = NULL; const char *base = NULL; char *relcontrolURL = NULL; char *releventURL = NULL; IXML_NodeList *serviceList = NULL; IXML_Element *service = NULL; baseURL = upnp_igd_get_first_document_item(igd_ctxt, DescDoc, "URLBase"); if (baseURL) base = baseURL; else base = location; for (sindex = 0; (serviceList = upnp_igd_get_nth_service_list(igd_ctxt, DescDoc , sindex)) != NULL; sindex++) { tempServiceType = NULL; relcontrolURL = NULL; releventURL = NULL; service = NULL; length = ixmlNodeList_length(serviceList); for (i = 0; i < length; i++) { service = (IXML_Element *)ixmlNodeList_item(serviceList, i); tempServiceType = upnp_igd_get_first_element_item(igd_ctxt, (IXML_Element *)service, "serviceType"); if (tempServiceType && strcmp(tempServiceType, serviceType) == 0) { upnp_igd_print(igd_ctxt, UPNP_IGD_DEBUG, "Found service: %s", serviceType); *serviceId = upnp_igd_get_first_element_item(igd_ctxt, service, "serviceId"); upnp_igd_print(igd_ctxt, UPNP_IGD_DEBUG, "serviceId: %s", *serviceId); relcontrolURL = upnp_igd_get_first_element_item(igd_ctxt, service, "controlURL"); releventURL = upnp_igd_get_first_element_item(igd_ctxt, service, "eventSubURL"); *controlURL = malloc(strlen(base) + strlen(relcontrolURL) + 1); if (*controlURL) { ret = UpnpResolveURL(base, relcontrolURL, *controlURL); if (ret != UPNP_E_SUCCESS) upnp_igd_print(igd_ctxt, UPNP_IGD_ERROR, "Error generating controlURL from %s + %s", base, relcontrolURL); } *eventURL = malloc(strlen(base) + strlen(releventURL) + 1); if (*eventURL) { ret = UpnpResolveURL(base, releventURL, *eventURL); if (ret != UPNP_E_SUCCESS) upnp_igd_print(igd_ctxt, UPNP_IGD_ERROR, "Error generating eventURL from %s + %s", base, releventURL); } free(relcontrolURL); free(releventURL); relcontrolURL = NULL; releventURL = NULL; found = 1; break; } free(tempServiceType); tempServiceType = NULL; } free(tempServiceType); tempServiceType = NULL; if (serviceList) ixmlNodeList_free(serviceList); serviceList = NULL; } free(baseURL); return found; }
/******************************************************************************** * 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; }