예제 #1
0
파일: upnp_util.c 프로젝트: Boxee/djmount
/******************************************************************************
 * 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);
}
예제 #2
0
/********************************************************************************
 * 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);
}
예제 #3
0
/********************************************************************************
 * 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 );
}
예제 #4
0
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 );
    }
}
예제 #5
0
파일: UPnPBase.cpp 프로젝트: dreamerc/amule
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 {
예제 #6
0
파일: upnp.cpp 프로젝트: videolan/vlc
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 );
}
예제 #7
0
파일: tv_ctrlpt.c 프로젝트: Tieske/pupnp
/********************************************************************************
 * 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]);
	}
}
예제 #8
0
파일: upnp.cpp 프로젝트: Flameeyes/vlc
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 );
    }
}
예제 #9
0
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;
}
예제 #10
0
파일: upnp.cpp 프로젝트: ZMacer/vlc
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 );
}
예제 #11
0
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;
}
예제 #12
0
/********************************************************************************
 * 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;
}