Beispiel #1
0
/**
 * Parse the service description from the service's SCPD URL. Do not call
 * this from user applications.
 * 
 * @param service The service in question
 * @return true if successful; otherwise false
 */
bool mupnp_controlpoint_parsescservicescpd(mUpnpService *service)
{
	mUpnpNetURL *scpdURL;
	bool scpdParseSuccess;
	
	mupnp_log_debug_l4("Entering...\n");

	scpdURL = mupnp_service_getscpdurl(service); 

	if ( NULL == scpdURL )		
		return false;
	
	mupnp_log_debug_s("SCPD URL: %s\n", mupnp_net_url_getrequest(scpdURL));
	scpdParseSuccess = mupnp_service_parsedescriptionurl(service, scpdURL);
	
	mupnp_net_url_delete(scpdURL);
	if (scpdParseSuccess == true)
		return true;

#if defined(MUPNP_USE_STDDCP)
	if (mupnp_service_hasstddcp(service)) {
		char *stdDCP = mupnp_service_getstddcp(service);
		scpdParseSuccess = mupnp_service_parsedescription(service, stdDCP, mupnp_strlen(stdDCP));
	}
#endif

	mupnp_log_debug_l4("Leaving...\n");

	return scpdParseSuccess;
}
Beispiel #2
0
void mupnp_ssdp_packet_print(mUpnpSSDPPacket *ssdpPkt)
{
	mUpnpHttpHeader *header;
	
	mupnp_log_debug_l4("Entering...\n");

	mupnp_log_debug_s("ssdp from %s %d\n",
		mupnp_ssdp_packet_getremoteaddress(ssdpPkt),
		mupnp_ssdp_packet_getremoteport(ssdpPkt));
		
	/**** print headers ****/
	for (header = mupnp_http_headerlist_gets(ssdpPkt->headerList); header != NULL; header = mupnp_http_header_next(header)) {
	mupnp_log_debug_s("%s: %s\n",
			mupnp_http_header_getname(header),
			mupnp_http_header_getvalue(header));
	}


	mupnp_log_debug_l4("Leaving...\n");
}
Beispiel #3
0
void mupnp_http_response_print(mUpnpHttpResponse* httpRes)
{
  mupnp_log_debug_l4("Entering...\n");

  mupnp_log_debug_s("%s %d %s\n",
      mupnp_http_response_getversion(httpRes),
      mupnp_http_response_getstatuscode(httpRes),
      mupnp_http_response_getreasonphrase(httpRes));

  mupnp_http_packet_print((mUpnpHttpPacket*)httpRes);

  mupnp_log_debug_l4("Leaving...\n");
}
Beispiel #4
0
/**
 * Add a listener to the event listener list
 *
 * @param eventListenerList The event listener list
 * @param listener The listener to add
 *
 */
void mupnp_eventlistenerlist_add(mUpnpEventListenerList* eventListenerList, MUPNP_EVENT_LISTENER listener)
{
  mUpnpEventListenerList* list_node;

  mupnp_log_debug_l4("Entering...\n");

  if (listener == NULL)
    return;

  list_node = (mUpnpEventListenerList*)malloc(sizeof(mUpnpEventListenerList));

  if (NULL != list_node) {
    memset(list_node, 0, sizeof(mUpnpEventListenerList));
    list_node->listener = listener;
    mupnp_list_node_init((mUpnpList*)list_node);
    mupnp_list_add((mUpnpList*)eventListenerList, (mUpnpList*)list_node);
  }
  else
    mupnp_log_debug_s("Memory allocation failure!\n");

  mupnp_log_debug_l4("Leaving...\n");
}
Beispiel #5
0
mUpnpXmlNode *mupnp_soap_request_getbodynode(mUpnpSoapRequest *soapReq)
{
	mUpnpXmlNode *envNode;
	mUpnpXmlNode *bodyNode = NULL;
  mUpnpXmlAttribute *attr;
  char *name;
  mUpnpStringTokenizer *tok;
  char *nsPrefix;
  size_t bodyLen;
  char *body;

	mupnp_log_debug_l4("Entering...\n");

	envNode = mupnp_soap_request_getenvelopenode(soapReq);
	if (envNode == NULL)
		return NULL;
	if (mupnp_xml_node_haschildnodes(envNode) == false)
		return NULL;

        /* We cannot assume the namespace prefix for Body is 's'. 
           According to spec, it could be anything... */
        for (attr = mupnp_xml_node_getattributes(envNode); attr != NULL; 
             attr = mupnp_xml_attribute_next(attr)) {
                /* First, find the namespace declaration attribute. */
                /* Note: We must take a copy of the attr name. 
                   Tokenizer doesn't do it (by default) */
                name = mupnp_strdup( mupnp_xml_attribute_getname(attr) );
                tok = mupnp_string_tokenizer_new(name, ":");

                nsPrefix = mupnp_string_tokenizer_nexttoken(tok);
                if ( -1 != mupnp_strstr(nsPrefix, "xmlns")) {
                        /* This attribute is a namespace declaration. Check is 
                           it the one defined for SOAP. */
                        if (mupnp_strcmp(mupnp_xml_attribute_getvalue(attr), MUPNP_SOAP_XMLNS_URL) == 0) {
                                /* This namespace declaration is correct. 
                                   Use it to find the body node... */
                                if (mupnp_string_tokenizer_hasmoretoken(tok)) {
                                        /* There is a prefix */
                                        nsPrefix = mupnp_string_tokenizer_nexttoken(tok);
                                        bodyLen = mupnp_strlen(nsPrefix) + 
                                                mupnp_strlen(MUPNP_SOAP_DELIM) + 
                                                mupnp_strlen(MUPNP_SOAP_BODY) + 1; /* +1 for trailing '\0'*/
                                        body = (char*)malloc(bodyLen);

					if ( NULL == body )
					{
						mupnp_log_debug_s("Memory allocation failure!\n");
						return NULL;
					}
#if defined(HAVE_SNPRINTF)
                                        snprintf(body, bodyLen, "%s%s%s", nsPrefix, 
                                                 MUPNP_SOAP_DELIM, MUPNP_SOAP_BODY);
#else
                                        sprintf(body, "%s%s%s", nsPrefix, MUPNP_SOAP_DELIM, MUPNP_SOAP_BODY);
#endif
                                        bodyNode = mupnp_xml_node_getchildnode(envNode, body);
                                        free(body);
                                }
                                else {
                                        /* No prefix */
                                        bodyNode = mupnp_xml_node_getchildnode(envNode, MUPNP_SOAP_BODY);
                                }
                                /* Free memory before leaving the loop */
                                mupnp_string_tokenizer_delete(tok);
                                free(name);
                                break;
                        }
                }
                mupnp_string_tokenizer_delete(tok);
                free(name);
        }

	mupnp_log_debug_l4("Leaving...\n");
	
	return bodyNode;
}
Beispiel #6
0
static bool mupnp_service_notifymain(mUpnpService* service, mUpnpStateVariable* statVar)
{
  mUpnpSubscriber* sub;
  mUpnpSubscriber** subArray;
  int subArrayCnt;
  int n;

  mupnp_log_debug_l4("Entering...\n");

  mupnp_service_lock(service);

  /**** Remove expired subscribers ****/
  subArrayCnt = mupnp_service_getnsubscribers(service);
  subArray = (mUpnpSubscriber**)malloc(sizeof(mUpnpSubscriber*) * subArrayCnt);

  if (NULL == subArray) {
    mupnp_log_debug_s("Memory allocation problem!\n");
    mupnp_service_unlock(service);
    return false;
  }

  sub = mupnp_service_getsubscribers(service);
  for (n = 0; n < subArrayCnt; n++) {
    subArray[n] = sub;
    sub = mupnp_subscriber_next(sub);
  }
  for (n = 0; n < subArrayCnt; n++) {
    sub = subArray[n];
    if (sub == NULL)
      continue;
    if (mupnp_subscriber_isexpired(sub) == true)
      mupnp_service_removesubscriber(service, sub);
  }
  free(subArray);

  /**** Notify to subscribers ****/
  subArrayCnt = mupnp_service_getnsubscribers(service);
  subArray = (mUpnpSubscriber**)malloc(sizeof(mUpnpSubscriber*) * subArrayCnt);

  if (NULL == subArray) {
    mupnp_log_debug_s("Memory allocation problem!\n");
    mupnp_service_unlock(service);
    return false;
  }

  sub = mupnp_service_getsubscribers(service);
  for (n = 0; n < subArrayCnt; n++) {
    subArray[n] = sub;
    sub = mupnp_subscriber_next(sub);
  }
  for (n = 0; n < subArrayCnt; n++) {
    sub = subArray[n];
    if (sub == NULL)
      continue;
    if (statVar) {
      if (mupnp_subscriber_notify(sub, statVar) == false) {
        /**** remove invalid the subscriber but don't remove in NMPR specification ****/
        mupnp_service_removesubscriber(service, sub);
      }
    }
    else {
      if (mupnp_subscriber_notifyall(sub, service) == false) {
        /**** remove invalid the subscriber but don't remove in NMPR specification ****/
        mupnp_service_removesubscriber(service, sub);
      }
    }
  }
  free(subArray);

  mupnp_service_unlock(service);

  mupnp_log_debug_l4("Leaving...\n");

  return true;
}
Beispiel #7
0
static void mupnp_http_server_clientthread(mUpnpThread *thread)
{
	mUpnpHttpServerClientData *clientData;
	mUpnpHttpServer *httpServer;
	mUpnpSocket *clientSock;
	void *httpServerUserData;
	mUpnpHttpRequest *httpReq;
	char *version = NULL;

	mupnp_log_debug_l4("Entering...\n");

	clientData = (mUpnpHttpServerClientData *)mupnp_thread_getuserdata(thread);
	httpServer = clientData->httpServer;
	clientSock = clientData->clientSock;
	httpServerUserData = mupnp_http_server_getuserdata(httpServer);

	httpReq = mupnp_http_request_new();
	mupnp_http_request_setsocket(httpReq, clientSock);

	/**** Thanks for Makela Aapo (10/31/05) ****/
	while (mupnp_http_request_read(httpReq, clientSock) == true && mupnp_thread_isrunnable(thread) == true) {
		/* Check some validity of the request */
		version = mupnp_http_request_getversion(httpReq);
		if (mupnp_strcmp(version, MUPNP_HTTP_VER11) == 0)
		{
			/* According to HTTP/1.1 spec, we must not tolerate
			   HTTP/1.1 request without HOST-header */
			if (mupnp_http_request_gethost(httpReq) == NULL)
			{
				mupnp_http_request_postbadrequest(httpReq);
				continue;
			}
		}

		if (httpServer->listener != NULL) {
            mupnp_http_request_setuserdata(httpReq, httpServerUserData);
			httpServer->listener(httpReq);
		}

		/* Close connection according to HTTP version and headers */
		if (mupnp_strcmp(version, MUPNP_HTTP_VER10) == 0)
		{
			/* Terminate connection after HTTP/1.0 request */
			break;
		}

		/* We are having HTTP/1.1 or better => terminate, if requested */
		if (mupnp_http_request_iskeepaliveconnection(httpReq) == false)
		{
			break;
		}
	}

	mupnp_log_debug_s("Dropping HTTP client\n");
	mupnp_http_request_delete(httpReq);

	mupnp_socket_close(clientSock);
	mupnp_socket_delete(clientSock);

	mupnp_http_server_clientdata_delete(clientData);
	mupnp_thread_setuserdata(thread, NULL);

    // This code frequently crashes. mutex lock referencing free'd memory.
	mupnp_http_server_lock(httpServer);
	mupnp_thread_remove(thread);
	mupnp_http_server_unlock(httpServer);

	mupnp_log_debug_l4("Leaving...\n");

	mupnp_thread_delete(thread);
}
Beispiel #8
0
/**
 * Stop the control point. Stops sending/receiveing/responding to any messages.
 *
 * @param ctrlPoint The control point to stop
 *
 * @return true if successful; otherwise false
 *
 */
bool mupnp_controlpoint_stop(mUpnpControlPoint *ctrlPoint)
{
	mUpnpDevice *dev = NULL;
	mUpnpSSDPServerList *ssdpServerList;
	mUpnpSSDPResponseServerList *ssdpResServerList;
	mUpnpHttpServerList *httpServerList;
	const char *udn = NULL;
	MUPNP_DEVICE_LISTENER listener = mupnp_controlpoint_getdevicelistener(ctrlPoint);
	
	mupnp_log_debug_l4("Entering...\n");

	/* Stop expiration handling */
	mupnp_thread_stop_with_cond(ctrlPoint->expThread, ctrlPoint->expCond);
	mupnp_log_debug_s("Expiration thread stopped.\n");
	
	/**** SSDP Server ****/
	ssdpServerList = mupnp_controlpoint_getssdpserverlist(ctrlPoint);
	mupnp_log_debug_s("Stopping ssdp servers.\n");
  mupnp_ssdp_serverlist_setlistener(ssdpServerList, NULL);
  mupnp_ssdp_serverlist_setuserdata(ssdpServerList, NULL);
	mupnp_ssdp_serverlist_stop(ssdpServerList);
	mupnp_log_debug_s("Done\n");
	mupnp_ssdp_serverlist_close(ssdpServerList);
	mupnp_ssdp_serverlist_clear(ssdpServerList);
	
	/**** SSDP Response Server ****/
	ssdpResServerList = mupnp_controlpoint_getssdpresponseserverlist(ctrlPoint);
	mupnp_log_debug_s("Stopping ssdp response servers.\n");
  mupnp_ssdpresponse_serverlist_setlistener(ssdpResServerList, NULL);
  mupnp_ssdpresponse_serverlist_setuserdata(ssdpResServerList, NULL);
	mupnp_ssdpresponse_serverlist_stop(ssdpResServerList);
	mupnp_log_debug_s("Done\n");
	mupnp_ssdpresponse_serverlist_close(ssdpResServerList);
	mupnp_ssdpresponse_serverlist_clear(ssdpResServerList);
	
	/**** HTTP Server ****/
	httpServerList = mupnp_controlpoint_gethttpserverlist(ctrlPoint);
	mupnp_log_debug_s("Stopping http servers.\n");
  mupnp_http_serverlist_setlistener(httpServerList, NULL);
	mupnp_http_serverlist_stop(httpServerList);
	mupnp_log_debug_s("Done\n");
	mupnp_http_serverlist_close(httpServerList);
	mupnp_http_serverlist_clear(httpServerList);

	mupnp_controlpoint_lock(ctrlPoint);

	mupnp_log_debug_s("Got controlpoint lock.\n");
	
	/* Unsubscribe from all services */

	for (dev = mupnp_controlpoint_getdevices(ctrlPoint); 
	     dev != NULL;
	     dev = mupnp_device_next(dev))
	{
		udn = mupnp_device_getudn(dev);
		
		/* Call device listener for each device */
		if (udn != NULL && listener != NULL)
		{
			mupnp_controlpoint_unlock(ctrlPoint);
			listener(ctrlPoint, udn, mUpnpDeviceStatusRemoved);
			mupnp_controlpoint_lock(ctrlPoint);
		}
	}
	/* Empty device cache */
	mupnp_devicelist_clear(ctrlPoint->deviceList);
	mupnp_log_debug_s("Device list cleared.\n");

	mupnp_controlpoint_unlock(ctrlPoint);
		
	mupnp_log_debug_l4("Leaving...\n");

	return true;
}
Beispiel #9
0
static int filter_duplicate_m_search(mUpnpSSDPPacket *ssdpPkt)
{
	mUpnpTime *timestamps = ssdpPkt->timestamps;
	size_t s_length;
	int loc;
  const char *st;
	char *id_string, *r_address, port[6];
	mUpnpTime curr_time;

	mupnp_log_debug_l4("Entering...\n");
	
	/* Initializing hash table to zero */
	if (!ssdpPkt->initialized) {
		ssdpPkt->initialized = 1;
		memset(timestamps, '\0', MUPNP_SSDP_FILTER_TABLE_SIZE * sizeof( mUpnpTime ));
	}

	r_address = mupnp_string_getvalue(ssdpPkt->dgmPkt->remoteAddress);
	st = mupnp_ssdp_packet_getst(ssdpPkt);
	sprintf(port, "%d", ssdpPkt->dgmPkt->remotePort); 

	/* Catenating remote address string with ssdp ST header field. */
	s_length = strlen( r_address ) + strlen( st ) + strlen( port );
	id_string = (char *)malloc( s_length + 1 );

	if ( NULL == id_string )
	{
		mupnp_log_debug_s("Memory allocation problem!\n");
		return FALSE;
	}

	memset(id_string, '\0', s_length + 1);

	mupnp_strcat(id_string, r_address );
	mupnp_strcat(id_string, port);
	mupnp_strcat(id_string, st );
	
	loc = simple_string_hash(id_string, MUPNP_SSDP_FILTER_TABLE_SIZE);

	mupnp_log_debug("Calculated hash: %d\n", loc);

	free(id_string);

	curr_time = mupnp_getcurrentsystemtime();

	if ( 0 == timestamps[loc] ) {
		timestamps[loc] = curr_time;
		mupnp_log_debug("First packet... Updating hash table.\n");
		return FALSE;
	}	
	else if ( ( curr_time - timestamps[loc] ) < MUPNP_DEVICE_M_SEARCH_FILTER_INTERVAL ) {
		mupnp_log_debug("Filtering packet!\n");
		timestamps[loc] = curr_time;
		return TRUE;
	}
	else {
		timestamps[loc] = curr_time;
		mupnp_log_debug("Old timestamp found, just updating it.\n");
		return FALSE;
	}
	
	mupnp_log_debug_l4("Leaving...\n");
}
Beispiel #10
0
char* mupnp_net_selectaddr(struct sockaddr* remoteaddr)
{
  struct ifaddrs *ifaddrs, *ifaddr;
  uint32_t laddr, lmask, raddr;
  char *address_candidate = NULL, *auto_ip_address_candidate = NULL;

  raddr = ntohl(((struct sockaddr_in*)remoteaddr)->sin_addr.s_addr);

  if (0 != getifaddrs(&ifaddrs)) {
    return NULL;
  }

  for (ifaddr = ifaddrs; NULL != ifaddr; ifaddr = ifaddr->ifa_next) {
    if (ifaddr->ifa_addr == NULL)
      continue;
    if (!(ifaddr->ifa_flags & IFF_UP))
      continue;
    if (ifaddr->ifa_flags & IFF_LOOPBACK)
      continue;
    if (ifaddr->ifa_flags & IFF_POINTOPOINT)
      continue;

    laddr = ntohl(((struct sockaddr_in*)ifaddr->ifa_addr)->sin_addr.s_addr);
    if (NULL != (struct sockaddr_in*)ifaddr->ifa_netmask)
      lmask = ntohl(((struct sockaddr_in*)ifaddr->ifa_netmask)->sin_addr.s_addr);
    else {
      mupnp_log_debug_s("No netmask for address %u!\n", laddr);
      continue;
    }

    /* Checking if we have an exact subnet match */
    if ((laddr & lmask) == (raddr & lmask)) {
      if (NULL != address_candidate)
        free(address_candidate);
      address_candidate = mupnp_strdup(
          inet_ntoa((struct in_addr)((struct sockaddr_in*)ifaddr->ifa_addr)->sin_addr));
      mupnp_log_debug_s("Address match! Selecting local address (%u)\n", laddr);
      break;
    }

    /* Checking if we have and auto ip address */
    if ((laddr & lmask) == MUPNP_NET_SOCKET_AUTO_IP_NET) {
      mupnp_log_debug_s("Found auto ip address. Selecting it for second address candidate (%u)\n", laddr);
      if (NULL != auto_ip_address_candidate)
        free(auto_ip_address_candidate);
      auto_ip_address_candidate = mupnp_strdup(
          inet_ntoa((struct in_addr)((struct sockaddr_in*)ifaddr->ifa_addr)->sin_addr));
    }
    /* Good. We have others than auto ips present. */
    else {
      mupnp_log_debug_s("Didn't have an exact subnet match, but non auto ip address anyway... (%u)\n", laddr);
      if (NULL != address_candidate)
        free(address_candidate);
      address_candidate = mupnp_strdup(
          inet_ntoa((struct in_addr)((struct sockaddr_in*)ifaddr->ifa_addr)->sin_addr));
    }
  }

  freeifaddrs(ifaddrs);

  if (NULL != address_candidate) {
    if (NULL != auto_ip_address_candidate)
      free(auto_ip_address_candidate);
    return address_candidate;
  }

  if (NULL != auto_ip_address_candidate) {
    if (NULL != address_candidate)
      free(address_candidate);
    return auto_ip_address_candidate;
  }

  /* Starting to feel desperate and returning local address.*/

  return mupnp_strdup("127.0.0.1");
}
BOOL mupnp_http_persistentconnection_put(char *host, int port, void *data)
{
       mUpnpHttpPersistentConnection *new_node = NULL, *node = NULL;

	mupnp_log_debug_l4("Entering...\n");

       /* If we dont have cache, then just exit */
       if (cache == NULL) {
	       mupnp_log_debug("(put) No cache! Persistent connections not initialized?\n");
	       return FALSE;
       }

       /* Check if we already have this one cached */
       for (node = (mUpnpHttpPersistentConnection*)mupnp_list_gets((mUpnpList*)cache);
            node != NULL;
            node = (mUpnpHttpPersistentConnection*)mupnp_list_next((mUpnpList*)node))
       {
               if (mupnp_strcmp(mupnp_string_getvalue(node->host), host) == 0 &&
                   node->port == port)
               {
                       /* If also data is the same, then update just
                          timestamp */
                       if (node->cacheData == data)
                       {
                               node->timestamp = mupnp_getcurrentsystemtime();
                               return TRUE;
                       }

		      mupnp_log_debug_s("Found cached persistent connection for %s:%d\n",
			      mupnp_string_getvalue(node->host), node->port);
                       new_node = node;
                       mupnp_list_remove((mUpnpList*)new_node);
                       break;
               }
       }

       /* We didn't find it */
       if (new_node == NULL)
       {
               /* Check if we have already too many cached things */
               if (mupnp_list_size((mUpnpList*)cache) >= CG_HTTP_PERSISTENT_CACHE_SIZE)
               {
                       /* Take last node (not refreshed for a long time) */
                       new_node = (mUpnpHttpPersistentConnection *)mupnp_list_next((mUpnpList *)cache);
                       mupnp_list_remove((mUpnpList*)new_node);
                       mupnp_http_persistentconnection_delete(new_node);
                       new_node = NULL;

		      mupnp_log_debug_s("Max persistent HTTP connection cache reached.\n");
               }

               if (new_node == NULL)
               {
                       if (data == NULL) return TRUE;

                       new_node = mupnp_http_persistentconnection_new();
                       if (new_node == NULL) return FALSE;

		      mupnp_log_debug_s("Adding persistent HTTP Connection %s:%d to cache\n",
			       host, port);
		      mupnp_log_debug_s("Persistent connections: %d\n", mupnp_list_size((mUpnpList*)cache));
               }
       }

       if (data != NULL)
       {
               /* Set appropriate values for the node */
               mupnp_string_setvalue(new_node->host, host);
               new_node->port = port;
               new_node->cacheData = data;
               new_node->timestamp = mupnp_getcurrentsystemtime();

               mupnp_list_add((mUpnpList*)cache, (mUpnpList*)new_node);
       } else {
               /* remove and delete node */
               mupnp_http_persistentconnection_delete(new_node);
       }

       return TRUE;

	mupnp_log_debug_l4("Leaving...\n");
}
void *mupnp_http_persistentconnection_get(char *host, int port)
{
       mUpnpHttpPersistentConnection *node;
       mUpnpTime sys_time = mupnp_getcurrentsystemtime();
       BOOL iterate;

mupnp_log_debug_l4("Entering...\n");

       /* If we dont have cache, then just exit */
       if (cache == NULL) { 
	       mupnp_log_debug("(get) No cache! Persistent connections not initialized?\n");
	       return NULL;
	}

       /* Clear all expired nodes */
       do {
               iterate = FALSE;
               for (node = (mUpnpHttpPersistentConnection*)mupnp_list_gets((mUpnpList*)cache);
                    node != NULL;
                    node = (mUpnpHttpPersistentConnection*)mupnp_list_next((mUpnpList*)node))
               {
                       if (sys_time > node->timestamp + CG_HTTP_PERSISTENT_TIMEOUT_PERIOD)
                       {
			      mupnp_log_debug_s("Timeout for persistent HTTP Connection to %s:%d "
				       "(timestamp: %d)\n",
				      mupnp_string_getvalue(node->host), node->port,
				      node->timestamp);
                               mupnp_list_remove((mUpnpList*)node);
                               mupnp_http_persistentconnection_delete(node);
                               iterate = TRUE;
                               break;
                       }
               }
       } while (iterate);

       /* Get persistent node */
       for (node = (mUpnpHttpPersistentConnection*)mupnp_list_gets((mUpnpList*)cache);
            node != NULL;
            node = (mUpnpHttpPersistentConnection*)mupnp_list_next((mUpnpList*)node))
       {
               if (mupnp_strcmp(mupnp_string_getvalue(node->host), host) == 0 &&
                   node->port == port)
               {
                       /* Node was required, remove and add again to refresh
                          cache */
                       mupnp_list_remove((mUpnpList*)node);
                       mupnp_list_add((mUpnpList*)cache, (mUpnpList*)node);

                       node->timestamp = mupnp_getcurrentsystemtime();

		      mupnp_log_debug_s("Persistent HTTP Connection cache HIT for %s:%d\n",
			       host, port);

                       return node->cacheData;
               }
       }

      mupnp_log_debug_s("Persistent HTTP Connection cache MISS for %s:%d\n",
	      host, port);

       return NULL;

	mupnp_log_debug_l4("Leaving...\n");
}
Beispiel #13
0
bool mupnp_xml_parse(mUpnpXmlParser* parser, mUpnpXmlNodeList* nodeList, const char* data, size_t len)
{
#if defined DEBUG_XML_RESULT
  mUpnpString* resdata = NULL;
#endif
  XML_Parser p;
  mUpnpExpatData expatData;
#ifdef MUPNP_SHOW_TIMINGS
  struct timeval start_time, end_time, elapsed_time;
#endif

  mupnp_log_debug_l4("Entering...\n");

#ifdef MUPNP_SHOW_TIMINGS
  gettimeofday(&start_time, NULL);
#endif

  if (!data || len <= 0)
    return false;

  p = XML_ParserCreate(NULL);
  if (!p)
    return false;
  /* Fix to get expat parser to work with DLink-routers */
  if (data[len - 1] == 0)
    len--;

  expatData.rootNode = NULL;
  expatData.currNode = NULL;
  XML_SetUserData(p, &expatData);
  XML_SetElementHandler(p, mupnp_expat_element_start, mupnp_expat_element_end);
  XML_SetCharacterDataHandler(p, mupnp_expat_character_data);

  parser->parseResult = XML_Parse(p, data, len, 1);
  XML_ParserFree(p);

  if (parser->parseResult == 0 /*XML_STATUS_ERROR*/) {
    if (expatData.rootNode != NULL)
      mupnp_xml_node_delete(expatData.rootNode);
#if defined DEBUG_XML_RESULT
    resdata = mupnp_string_new();
    mupnp_string_naddvalue(resdata, data, len);
    printf("XML parse Error on data %s\n time used = %ds\n",
        mupnp_string_getvalue(resdata),
        time(NULL) - startTime);
    mupnp_string_delete(resdata);
#endif
    return false;
  }

  mupnp_xml_nodelist_add(nodeList, expatData.rootNode);

#ifdef MUPNP_SHOW_TIMINGS
  gettimeofday(&end_time, NULL);
  timersub(&end_time, &start_time, &elapsed_time);
  mupnp_log_debug_s("Parsing XML completed. Elapsed time: "
                    "%ld msec\n",
      ((elapsed_time.tv_sec * 1000) + (elapsed_time.tv_usec / 1000)));
  mupnp_total_elapsed_time += (elapsed_time.tv_sec * 1000000) + (elapsed_time.tv_usec);
  mupnp_log_debug_s("Total elapsed time: %ld msec\n", mupnp_total_elapsed_time / 1000);
#endif

#if defined DEBUG_XML_RESULT
  resdata = mupnp_string_new();
  mupnp_string_naddvalue(resdata, data, len);
  printf("XML parse success - time used %ds\n", time(NULL) - startTime);
  mupnp_string_delete(resdata);
#endif

  return true;

  mupnp_log_debug_l4("Leaving...\n");
}