Esempio n. 1
0
BOOL cg_socket_setmulticastttl(CgSocket *sock, int ttl)
{
	int sockOptRet;
	int ttl_;
	unsigned int len=0;
	
	cg_log_debug_l4("Entering...\n");

#if defined(BTRON) || (defined(TENGINE) && !defined(CG_TENGINE_NET_KASAGO))
	sockOptRet = so_setsockopt(sock->id, IPPROTO_IP, IP_MULTICAST_TTL, (B *)&ttl, sizeof(ttl));
#elif defined(TENGINE) && defined(CG_TENGINE_NET_KASAGO)
	sockOptRet = ka_setsockopt(sock->id, IPPROTO_IP, IP_MULTICAST_TTL, (const char *)&ttl, sizeof(ttl));
#elif defined (ITRON)
	/**** Not Implemented for NORTi ***/
	sockOptRet = -1;
#elif defined (WIN32)
	sockOptRet = setsockopt(sock->id, IPPROTO_IP, IP_MULTICAST_TTL, (const char *)&ttl, sizeof(ttl));
#else
	cg_log_debug("Setting multicast time to live to %d\n", ttl);
	sockOptRet = setsockopt(sock->id, IPPROTO_IP, IP_MULTICAST_TTL, (const unsigned char *)&ttl, sizeof(ttl));
	if (sockOptRet != 0)
	{
		cg_log_debug("setsockopt() failed with errno %d: %s, fd:%d\n", errno, strerror(errno),sock->id);
	}
	else
	{
		len = sizeof(ttl_);
		getsockopt(sock->id, IPPROTO_IP, IP_MULTICAST_TTL, &ttl_, (socklen_t*)&len);
		cg_log_debug("Multicast time to live is %i\n", ttl_);
	}
#endif
	cg_log_debug_l4("Leaving...\n");

	return (sockOptRet == 0) ? TRUE : FALSE;
}
Esempio n. 2
0
File: curi.c Progetto: Deanzou/DLNA
char *cg_net_uri_getupnpbasepath(CgNetURI *locationURL)
{
        char *path, *c;
        int i;

        path = cg_strdup(cg_net_uri_getpath(locationURL));

	cg_log_debug_s("Mangling url string: %s\n", path);
        
	i = cg_strlen(path);

        if ( 0 >= i )
        {
                cg_log_debug("No base path, doing nothing.\n");
                return NULL;
        }

        /* Truncating out the "file name" from path */
        for ( c=( path + --i); 0<=i; c=( path + --i ))
                if ( '/' == *c )
                {
                        *( path + i + 1 ) = '\0';
			cg_log_debug_s("Truncating string from place %d\n", i);
                        break;
                }

	cg_log_debug_s("url string after mangling: %s\n", path);

        return path;
}
Esempio n. 3
0
/**
 * Do an M-SEARCH to look for devices in the network.
 *
 * @param ctrlPoint The control point in question
 * @param target The Search Target parameter (ex. "ssdp:all")
 */
BOOL cg_upnp_controlpoint_search(CgUpnpControlPoint *ctrlPoint, const char *target)
{
	CgUpnpSSDPRequest *ssdpReq;
	CgUpnpSSDPResponseServerList *ssdpResServerList;
	int i = 0;
	BOOL retval = FALSE;
	
	cg_log_debug_l4("Entering...\n");

	ssdpReq = cg_upnp_ssdprequest_new();
	cg_upnp_ssdprequest_setmethod(ssdpReq, CG_HTTP_MSEARCH);
	cg_upnp_ssdprequest_setst(ssdpReq, target);
	cg_upnp_ssdprequest_setmx(ssdpReq, cg_upnp_controlpoint_getssdpsearchmx(ctrlPoint));
	cg_upnp_ssdprequest_setman(ssdpReq, CG_UPNP_MAN_DISCOVER);
	
	cg_log_debug("Announcing %d times.\n", cg_upnp_ssdp_getannouncecount());
	cg_upnp_ssdprequest_print(ssdpReq);
	
	for (i = 0; i < cg_upnp_ssdp_getannouncecount(); i++)
	{
		ssdpResServerList = cg_upnp_controlpoint_getssdpresponseserverlist(ctrlPoint);
		retval = ( cg_upnp_ssdpresponse_serverlist_post(ssdpResServerList, ssdpReq ) || retval );
		cg_wait(CG_UPNP_CONTROLPOINT_SSDP_MIN_DELAY);
	}
	
	cg_upnp_ssdprequest_delete(ssdpReq);

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

	return retval;
}
Esempio n. 4
0
BOOL cg_socket_tosockaddrinfo(int sockType, char *addr, int port, struct addrinfo **addrInfo, BOOL isBindAddr)
{
#if defined(TENGINE) && defined(CG_TENGINE_NET_KASAGO)
	struct addrinfo hints;
	char portStr[32];
#else
	struct addrinfo hints;
	char portStr[32];
	int errorn;
#endif

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

	cg_socket_startup();

#if defined(TENGINE) && defined(CG_TENGINE_NET_KASAGO)
	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_socktype = sockType;
	hints.ai_flags= 0; /*AI_NUMERICHOST | AI_PASSIVE*/;
	sprintf(portStr, "%d", port);
	if (ka_getaddrinfo(addr, portStr, &hints, addrInfo) != 0)
		return FALSE;
	if (isBindAddr == TRUE)
		return TRUE;
	hints.ai_family = (*addrInfo)->ai_family;
	ka_freeaddrinfo(*addrInfo);
	if (ka_getaddrinfo(NULL, portStr, &hints, addrInfo) != 0)
		return FALSE;
	return TRUE;
#else
	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_socktype = sockType;
	hints.ai_flags= /*AI_NUMERICHOST | */AI_PASSIVE;
	sprintf(portStr, "%d", port);
	cg_log_debug("Address: %s, port: %s\n", addr, portStr);
	if ( (errorn = getaddrinfo(addr, portStr, &hints, addrInfo)) != 0) {
#if !defined(WINCE)
		cg_log_debug_s("ERROR: %s\n", gai_strerror(errorn));
		cg_log_debug_s("SERROR: %s\n", strerror(errno));
#endif
		return FALSE;
	}
	if (isBindAddr == TRUE)
		return TRUE;
	hints.ai_family = (*addrInfo)->ai_family;
	freeaddrinfo(*addrInfo);
	if ((errorn = getaddrinfo(NULL, portStr, &hints, addrInfo)) != 0) {
#if !defined(WINCE)
		cg_log_debug_s("ERROR: %s\n", gai_strerror(errorn));
		cg_log_debug_s("SERROR: %s\n", strerror(errno));
#endif
		return FALSE;
	}
	return TRUE;
#endif
 }
static int simple_string_hash(char *str, int table_size)
{
    int sum=0;

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

    if (str==NULL) return -1;

    cg_log_debug("Calculating hash from string |%s|, table size: %d\n", str, table_size);

    /* Sum up all the characters in the string */
    for( ; *str; str++) sum += *str;

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

    return sum % table_size;
}
char *cg_upnp_usn_getudn(char *usn, char *udnBuf, int udnBufLen)
{
	int idx;
	
	cg_log_debug_l4("Entering...\n");

	if (usn == NULL) {
		udnBuf[0] = '\0';
		return udnBuf;
	}
	
	idx = cg_strstr(usn, "::");
	if (idx < 0) {
		cg_strncpy(udnBuf, usn, udnBufLen);
		udnBuf[udnBufLen-1] = '\0';
		cg_strtrim(udnBuf, " ", 1);
		return udnBuf;
	}
	
	if ( idx < udnBufLen ) {
		cg_strncpy(udnBuf, usn, (idx));
		udnBuf[idx] = '\0';
	}
	else {
		cg_strncpy(udnBuf, usn, udnBufLen);
		udnBuf[udnBufLen-1] = '\0';
	}
	
	cg_strtrim(udnBuf, " ", 1);

	cg_log_debug("UDN: %s\n", udnBuf);
	
	return udnBuf;

	cg_log_debug_l4("Leaving...\n");
}
void cg_upnp_device_ssdpmessagereceived(CgUpnpDevice *dev, CgUpnpSSDPPacket *ssdpPkt, int filter)
{
    BOOL isRootDev;
    char *ssdpST;
    char *devUDN, *devType;
    char ssdpMsg[CG_UPNP_SSDP_HEADER_LINE_MAXSIZE];
    char deviceUSN[CG_UPNP_SSDP_HEADER_LINE_MAXSIZE];
#if defined WINCE
    size_t n;
#else
    int n;
#endif
    CgUpnpService *service;
    CgUpnpDevice *childDev;
    char *ssdpMXString;
    int ssdpMX;

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

    ssdpMXString = cg_http_headerlist_getvalue(ssdpPkt->headerList, CG_HTTP_MX);
    ssdpST = cg_upnp_ssdp_packet_getst(ssdpPkt);

    /* Check if this ssdp packet has already been checked + filtered */
    if (filter)
    {

        /****************************************
         * Request line
         * Check the request line for errors, this is not ideal as it currently only
         * checks for the presence of the strings and not the order.
         ***************************************/
        /**** check for M-SEARCH and return if not found ****/
        if (cg_strstr(cg_string_getvalue(ssdpPkt->dgmPkt->data), CG_HTTP_MSEARCH) < 0)
            return;
        /**** check for * and return if not found ****/
        if (cg_strstr(cg_string_getvalue(ssdpPkt->dgmPkt->data), "*") < 0)
            return;
        /**** check HTTP version and return if not found ****/
        if (cg_strstr(cg_string_getvalue(ssdpPkt->dgmPkt->data),  CG_HTTP_VER11) < 0)
            return;

        /****************************************
         * check HOST header, should always be 239.255.255.250:1900, return if incorrect
         ***************************************/
        if (cg_strcmp(cg_upnp_ssdp_packet_gethost(ssdpPkt), CG_UPNP_SSDP_MULTICAST_ADDRESS) != 0)
            return;

        /****************************************
         * check MAN header, return if incorrect
         ***************************************/
        if (cg_upnp_ssdp_packet_isdiscover(ssdpPkt) == FALSE)
            return;

        /****************************************
         * check MX header, return if incorrect
         ***************************************/
        if (ssdpMXString == NULL || cg_strlen(ssdpMXString)==0)
            /* return if the MX value does not exist or is empty */
            return;
        /* check if MX value is not an integer */
        for (n=0; n<strlen(ssdpMXString); n++) {
            if (isdigit(ssdpMXString[n]) == 0)
                /* MX value contains a non-digit so is invalid */
                return;
        }

        /****************************************
         * check ST header and if empty return
         ***************************************/
        if (cg_strlen(ssdpST) <= 0)
            return;

        /* Check if we have received this search recently
         * and ignore duplicates. */
        if ( filter_duplicate_m_search(ssdpPkt) )
            return;

        ssdpMX = cg_upnp_ssdp_packet_getmx(ssdpPkt);
        cg_log_debug("Sleeping for a while... (MX:%d)\n", ssdpMX);
        cg_waitrandom((ssdpMX*1000)/4);
    }

    isRootDev = cg_upnp_device_isrootdevice(dev);

    if (cg_upnp_st_isalldevice(ssdpST) == TRUE) {
        /* for root device only */
        if (isRootDev == TRUE) {
            cg_upnp_device_getnotifydevicent(dev, ssdpMsg, sizeof(ssdpMsg));
            cg_upnp_device_getnotifydeviceusn(dev, deviceUSN, sizeof(deviceUSN));
            cg_upnp_device_postsearchresponse(dev, ssdpPkt, ssdpMsg, deviceUSN);
        }
        /* for all devices send */
        /* device type : device version */
        cg_upnp_device_getnotifydevicetypent(dev, ssdpMsg, sizeof(ssdpMsg));
        cg_upnp_device_getnotifydevicetypeusn(dev, deviceUSN, sizeof(deviceUSN));
        cg_upnp_device_postsearchresponse(dev, ssdpPkt, ssdpMsg, deviceUSN);
        /* device UUID */
        cg_upnp_device_postsearchresponse(dev, ssdpPkt, cg_upnp_device_getudn(dev), cg_upnp_device_getudn(dev));
    }
    else if (cg_upnp_st_isrootdevice(ssdpST)  == TRUE) {
        if (isRootDev == TRUE) {
            cg_upnp_device_getnotifydeviceusn(dev, deviceUSN, sizeof(deviceUSN));
            cg_upnp_device_postsearchresponse(dev, ssdpPkt, CG_UPNP_ST_ROOT_DEVICE, deviceUSN);
        }
    }
    else if (cg_upnp_st_isuuiddevice(ssdpST)  == TRUE) {
        devUDN = cg_upnp_device_getudn(dev);
        if (cg_streq(ssdpST, devUDN) == TRUE)
            cg_upnp_device_postsearchresponse(dev, ssdpPkt, devUDN, devUDN);
    }
    else if (cg_upnp_st_isurn(ssdpST)  == TRUE) {
        devType = cg_upnp_device_getdevicetype(dev);
        if (cg_streq(ssdpST, devType) == TRUE) {
            cg_upnp_device_getnotifydevicetypeusn(dev, deviceUSN, sizeof(deviceUSN));
            cg_upnp_device_postsearchresponse(dev, ssdpPkt, devType, deviceUSN);
        }
    }

    for (service=cg_upnp_device_getservices(dev); service != NULL; service = cg_upnp_service_next(service))
        cg_upnp_service_ssdpmessagereceived(service, ssdpPkt);

    for (childDev = cg_upnp_device_getdevices(dev); childDev != NULL; childDev = cg_upnp_device_next(childDev))
        cg_upnp_device_ssdpmessagereceived(childDev, ssdpPkt, FALSE);


    cg_log_debug_l4("Leaving...\n");
}
static int filter_duplicate_m_search(CgUpnpSSDPPacket *ssdpPkt)
{
    CgSysTime *timestamps = ssdpPkt->timestamps;
    int loc, s_length;
    char *id_string, *r_address, *st, port[6];
    CgSysTime curr_time;

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

    /* Initializing hash table to zero */
    if (!ssdpPkt->initialized) {
        ssdpPkt->initialized = 1;
        memset(timestamps, '\0', CG_UPNP_SSDP_FILTER_TABLE_SIZE * sizeof( CgSysTime ));
    }

    r_address = cg_string_getvalue(ssdpPkt->dgmPkt->remoteAddress);
    st = cg_upnp_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 )
    {
        cg_log_debug_s("Memory allocation problem!\n");
        return FALSE;
    }

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

    cg_strcat(id_string, r_address );
    cg_strcat(id_string, port);
    cg_strcat(id_string, st );

    loc = simple_string_hash(id_string, CG_UPNP_SSDP_FILTER_TABLE_SIZE);

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

    free(id_string);

    curr_time = cg_getcurrentsystemtime();

    if ( 0 == timestamps[loc] ) {
        timestamps[loc] = curr_time;
        cg_log_debug("First packet... Updating hash table.\n");
        return FALSE;
    }
    else if ( ( curr_time - timestamps[loc] ) < CG_UPNP_DEVICE_M_SEARCH_FILTER_INTERVAL ) {
        cg_log_debug("Filtering packet!\n");
        timestamps[loc] = curr_time;
        return TRUE;
    }
    else {
        timestamps[loc] = curr_time;
        cg_log_debug("Old timestamp found, just updating it.\n");
        return FALSE;
    }

    cg_log_debug_l4("Leaving...\n");
}
BOOL cg_http_persistentconnection_put(char *host, int port, void *data)
{
       CgHttpPersistentConnection *new_node = NULL, *node = NULL;

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

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

       /* Check if we already have this one cached */
       for (node = (CgHttpPersistentConnection*)cg_list_gets((CgList*)cache);
            node != NULL;
            node = (CgHttpPersistentConnection*)cg_list_next((CgList*)node))
       {
               if (cg_strcmp(cg_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 = cg_getcurrentsystemtime();
                               return TRUE;
                       }

		      cg_log_debug_s("Found cached persistent connection for %s:%d\n",
			      cg_string_getvalue(node->host), node->port);
                       new_node = node;
                       cg_list_remove((CgList*)new_node);
                       break;
               }
       }

       /* We didn't find it */
       if (new_node == NULL)
       {
               /* Check if we have already too many cached things */
               if (cg_list_size((CgList*)cache) >= CG_HTTP_PERSISTENT_CACHE_SIZE)
               {
                       /* Take last node (not refreshed for a long time) */
                       new_node = (CgHttpPersistentConnection *)cg_list_next((CgList *)cache);
                       cg_list_remove((CgList*)new_node);
                       cg_http_persistentconnection_delete(new_node);
                       new_node = NULL;

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

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

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

		      cg_log_debug_s("Adding persistent HTTP Connection %s:%d to cache\n",
			       host, port);
		      cg_log_debug_s("Persistent connections: %d\n", cg_list_size((CgList*)cache));
               }
       }

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

               cg_list_add((CgList*)cache, (CgList*)new_node);
       } else {
               /* remove and delete node */
               cg_http_persistentconnection_delete(new_node);
       }

       return TRUE;

	cg_log_debug_l4("Leaving...\n");
}
void *cg_http_persistentconnection_get(char *host, int port)
{
       CgHttpPersistentConnection *node;
       CgSysTime sys_time = cg_getcurrentsystemtime();
       BOOL iterate;

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

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

       /* Clear all expired nodes */
       do {
               iterate = FALSE;
               for (node = (CgHttpPersistentConnection*)cg_list_gets((CgList*)cache);
                    node != NULL;
                    node = (CgHttpPersistentConnection*)cg_list_next((CgList*)node))
               {
                       if (sys_time > node->timestamp + CG_HTTP_PERSISTENT_TIMEOUT_PERIOD)
                       {
			      cg_log_debug_s("Timeout for persistent HTTP Connection to %s:%d "
				       "(timestamp: %d)\n",
				      cg_string_getvalue(node->host), node->port,
				      node->timestamp);
                               cg_list_remove((CgList*)node);
                               cg_http_persistentconnection_delete(node);
                               iterate = TRUE;
                               break;
                       }
               }
       } while (iterate);

       /* Get persistent node */
       for (node = (CgHttpPersistentConnection*)cg_list_gets((CgList*)cache);
            node != NULL;
            node = (CgHttpPersistentConnection*)cg_list_next((CgList*)node))
       {
               if (cg_strcmp(cg_string_getvalue(node->host), host) == 0 &&
                   node->port == port)
               {
                       /* Node was required, remove and add again to refresh
                          cache */
                       cg_list_remove((CgList*)node);
                       cg_list_add((CgList*)cache, (CgList*)node);

                       node->timestamp = cg_getcurrentsystemtime();

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

                       return node->cacheData;
               }
       }

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

       return NULL;

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