bool mupnp_ssdpresponse_server_post(mUpnpSSDPResponseServer* server, mUpnpSSDPRequest* ssdpReq) { mUpnpHttpUSocket* httpuSock; char* ifAddr; const char* ssdpAddr; mUpnpString* ssdpMsg; size_t sentLen = 0; mupnp_log_debug_l4("Entering...\n"); httpuSock = mupnp_ssdpresponse_server_getsocket(server); ifAddr = mupnp_socket_getaddress(httpuSock); ssdpAddr = mupnp_ssdp_gethostaddress(ifAddr); mupnp_ssdprequest_sethost(ssdpReq, ssdpAddr, MUPNP_SSDP_PORT); ssdpMsg = mupnp_string_new(); mupnp_ssdprequest_tostring(ssdpReq, ssdpMsg); sentLen = mupnp_socket_sendto(httpuSock, ssdpAddr, MUPNP_SSDP_PORT, mupnp_string_getvalue(ssdpMsg), mupnp_string_length(ssdpMsg)); mupnp_string_delete(ssdpMsg); mupnp_log_debug_l4("Leaving...\n"); return (sentLen > 0); }
void mupnp_control_action_request_setaction(mUpnpActionRequest *actionReq, mUpnpAction *action) { mUpnpService *service; mUpnpSoapRequest *soapReq; mUpnpString *soapAction; mUpnpXmlNode *bodyNode; mUpnpXmlNode *contentNode; mupnp_log_debug_l4("Entering...\n"); service = mupnp_action_getservice(action); soapReq = mupnp_control_action_request_getsoaprequest(actionReq); soapAction = mupnp_string_new(); mupnp_string_addvalue(soapAction, "\""); mupnp_string_addvalue(soapAction, mupnp_service_getservicetype(service)); mupnp_string_addvalue(soapAction, "#"); mupnp_string_addvalue(soapAction, mupnp_action_getname(action)); mupnp_string_addvalue(soapAction, "\""); mupnp_soap_request_setsoapaction(soapReq, mupnp_string_getvalue(soapAction)); mupnp_string_delete(soapAction); mupnp_control_request_sethostfromservice(soapReq, service); mupnp_control_soap_request_initializeenvelopenode(soapReq); bodyNode = mupnp_soap_request_getbodynode(soapReq); contentNode = mupnp_control_action_request_createactionnode(action); mupnp_xml_node_addchildnode(bodyNode, contentNode); mupnp_soap_request_createcontent(soapReq); mupnp_log_debug_l4("Leaving...\n"); }
mUpnpXmlNode *mupnp_control_action_request_createactionnode(mUpnpAction *action) { mUpnpService *service; mUpnpXmlNode *actionNode; mUpnpArgument *arg; mUpnpXmlNode *argNode; mUpnpString *nameWithNamespace; mupnp_log_debug_l4("Entering...\n"); service = mupnp_action_getservice(action); actionNode = mupnp_xml_node_new(); /**** Thanks for Visa Smolander (10/31/2005) ****/ nameWithNamespace = mupnp_string_new(); mupnp_string_addvalue( nameWithNamespace, MUPNP_CONTROL_NS ":" ); mupnp_string_addvalue( nameWithNamespace, mupnp_action_getname(action) ); mupnp_xml_node_setname(actionNode, mupnp_string_getvalue( nameWithNamespace ) ); mupnp_string_delete( nameWithNamespace ); mupnp_xml_node_setnamespace(actionNode, MUPNP_CONTROL_NS, mupnp_service_getservicetype(service)); for (arg = mupnp_action_getarguments(action); arg; arg = mupnp_argument_next(arg)) { if (mupnp_argument_isindirection(arg) == false) continue; argNode = mupnp_xml_node_new(); mupnp_xml_node_setname(argNode, mupnp_argument_getname(arg)); mupnp_xml_node_setvalue(argNode, mupnp_argument_getvalue(arg)); mupnp_xml_node_addchildnode(actionNode, argNode); } mupnp_log_debug_l4("Leaving...\n"); return actionNode; }
char *mupnp_ssdprequest_tostring(mUpnpSSDPRequest *ssdpReq, mUpnpString *ssdpMsg) { mUpnpHttpHeader *header; const char *name; const char *value; mupnp_log_debug_l4("Entering...\n"); mupnp_string_addvalue(ssdpMsg, mupnp_http_request_getmethod(ssdpReq)); mupnp_string_addvalue(ssdpMsg, MUPNP_HTTP_SP); mupnp_string_addvalue(ssdpMsg, mupnp_http_request_geturi(ssdpReq)); mupnp_string_addvalue(ssdpMsg, MUPNP_HTTP_SP); mupnp_string_addvalue(ssdpMsg, mupnp_http_request_getversion(ssdpReq)); mupnp_string_addvalue(ssdpMsg, MUPNP_HTTP_CRLF); for (header = mupnp_http_packet_getheaders((mUpnpHttpPacket *)ssdpReq); header != NULL; header = mupnp_http_header_next(header)) { name = mupnp_http_header_getname(header); value = mupnp_http_header_getvalue(header); mupnp_string_addvalue(ssdpMsg, name); mupnp_string_addvalue(ssdpMsg, MUPNP_HTTP_COLON); mupnp_string_addvalue(ssdpMsg, MUPNP_HTTP_SP); mupnp_string_addvalue(ssdpMsg, value); mupnp_string_addvalue(ssdpMsg, MUPNP_HTTP_CRLF); } mupnp_string_addvalue(ssdpMsg, MUPNP_HTTP_CRLF); return mupnp_string_getvalue(ssdpMsg); mupnp_log_debug_l4("Leaving...\n"); }
void mupnp_xml_node_print(mUpnpXmlNode *node) { mUpnpString *str = mupnp_string_new(); mupnp_xml_node_tostring(node, true, str); printf("%s", mupnp_string_getvalue(str)); mupnp_string_delete(str); }
const char* mupnp_http_header_getvalue(mUpnpHttpHeader* header) { mupnp_log_debug_l4("Entering...\n"); return mupnp_string_getvalue(header->value); mupnp_log_debug_l4("Leaving...\n"); }
char* mupnp_http_response_getversion(mUpnpHttpResponse* httpRes) { mupnp_log_debug_l4("Entering...\n"); return mupnp_string_getvalue(httpRes->version); mupnp_log_debug_l4("Leaving...\n"); }
char *mupnp_net_interface_getnetmask(mUpnpNetworkInterface *netIf) { mupnp_log_debug_l4("Entering...\n"); return mupnp_string_getvalue(netIf->netmask); mupnp_log_debug_l4("Leaving...\n"); }
char* mupnp_http_response_getreasonphrase(mUpnpHttpResponse* httpRes) { mupnp_log_debug_l4("Entering...\n"); return mupnp_string_getvalue(httpRes->reasonPhrase); mupnp_log_debug_l4("Leaving...\n"); }
static char *mupnp_xml_node_attribute_tostring(mUpnpXmlNode *node, mUpnpString *str) { mUpnpXmlAttribute *attr; const char *name; const char *value; mUpnpString *valueStr; mupnp_log_debug_l4("Entering...\n"); valueStr = mupnp_string_new(); if (valueStr == NULL) return NULL; for (attr = mupnp_xml_node_getattributes(node); attr != NULL; attr = mupnp_xml_attribute_next(attr)) { name = mupnp_xml_attribute_getname(attr); value = mupnp_xml_attribute_getvalue(attr); mupnp_string_setvalue(valueStr, value); mupnp_xml_escapechars(valueStr); /* All the following functions return NULL only when memory allocation fails, so we can check them all */ if (!mupnp_string_naddvalue(str, " ", 1) || !mupnp_string_addvalue(str, name) || !mupnp_string_naddvalue(str, "=\"", 2) || !mupnp_string_addvalue(str, mupnp_string_getvalue(valueStr)) || !mupnp_string_naddvalue(str, "\"", 1)) { /* Memory allocation failed */ mupnp_string_delete(valueStr); return NULL; } } mupnp_string_delete(valueStr); mupnp_log_debug_l4("Leaving...\n"); return mupnp_string_getvalue(str); }
const char* mupnp_event_subscription_totimeoutheaderstring(mUpnpTime time, mUpnpString* buf) { char timeBuf[MUPNP_STRING_LONG_BUFLEN]; mupnp_log_debug_l4("Entering...\n"); if (time != MUPNP_SUBSCRIPTION_INFINITE_VALUE) { mupnp_string_setvalue(buf, MUPNP_SUBSCRIPTION_TIMEOUT_HEADER); mupnp_string_addvalue(buf, mupnp_long2str(time, timeBuf, sizeof(timeBuf))); } else mupnp_string_setvalue(buf, MUPNP_SUBSCRIPTION_INFINITE_STRING); return mupnp_string_getvalue(buf); mupnp_log_debug_l4("Leaving...\n"); }
void mupnp_event_subscription_response_setsid(mUpnpSubscriptionResponse* subRes, const char* sid) { mUpnpString* headerSID; ssize_t uuidIdx; mupnp_log_debug_l4("Entering...\n"); headerSID = mupnp_string_new(); uuidIdx = mupnp_strstr(sid, MUPNP_ST_UUID_DEVICE); if (uuidIdx < 0) mupnp_string_addvalue(headerSID, MUPNP_ST_UUID_DEVICE ":"); mupnp_string_addvalue(headerSID, sid); mupnp_http_packet_setheadervalue(((mUpnpHttpPacket*)subRes), MUPNP_HTTP_SID, mupnp_string_getvalue(headerSID)); mupnp_string_delete(headerSID); mupnp_log_debug_l4("Leaving...\n"); }
char *mupnp_upnpav_protocolinfo_getstring(mUpnpAvProtocolInfo *info) { char protocolInfoBuf[CG_UPNPAV_PROTOCOLINFO_MAXSIZE]; #if defined(WIN32) _snprintf( #else snprintf( #endif protocolInfoBuf, sizeof(protocolInfoBuf), "%s:%s:%s:%s", mupnp_upnpav_protocolinfo_getprotocol(info), mupnp_upnpav_protocolinfo_getnetwork(info), mupnp_upnpav_protocolinfo_getmimetype(info), mupnp_upnpav_protocolinfo_getadditionainfo(info)); mupnp_string_setvalue(info->string, protocolInfoBuf); return mupnp_string_getvalue(info->string); }
void mupnp_upnpav_dmr_addprotocolinfo(mUpnpAvRenderer *dmr, mUpnpAvProtocolInfo *info) { mUpnpString *protocolInfos; mUpnpAvProtocolInfo *protocolInfo; mUpnpService *service; mUpnpStateVariable *stateVar; mupnp_upnpav_protocolinfolist_add(dmr->protocolInfoList, info); protocolInfos = mupnp_string_new(); for (protocolInfo = mupnp_upnpav_dmr_getprotocolinfos(dmr); protocolInfo; protocolInfo = mupnp_upnpav_protocolinfo_next(protocolInfo)) { if (0 < mupnp_string_length(protocolInfos)) mupnp_string_addvalue(protocolInfos, ","); mupnp_string_addvalue(protocolInfos, mupnp_upnpav_protocolinfo_getstring(protocolInfo)); } service = mupnp_device_getservicebyexacttype(dmr->dev, CG_UPNPAV_DMR_CONNECTIONMANAGER_SERVICE_TYPE); stateVar = mupnp_service_getstatevariablebyname(service, CG_UPNPAV_DMR_CONNECTIONMANAGER_SINKPROTOCOLINFO); mupnp_statevariable_setvalue(stateVar, mupnp_string_getvalue(protocolInfos)); mupnp_string_delete(protocolInfos); }
void mupnp_device_ssdpmessagereceived(mUpnpDevice *dev, mUpnpSSDPPacket *ssdpPkt, int filter) { BOOL isRootDev; const char *ssdpST; const char *devUDN, *devType; char ssdpMsg[MUPNP_SSDP_HEADER_LINE_MAXSIZE]; char deviceUSN[MUPNP_SSDP_HEADER_LINE_MAXSIZE]; #if defined WINCE size_t n; #else int n; #endif mUpnpService *service; mUpnpDevice *childDev; const char *ssdpMXString; int ssdpMX; const char *ssdpTargetAddr; mupnp_log_debug_l4("Entering...\n"); ssdpMXString = mupnp_http_headerlist_getvalue(ssdpPkt->headerList, CG_HTTP_MX); ssdpST = mupnp_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 (mupnp_strstr(mupnp_string_getvalue(ssdpPkt->dgmPkt->data), CG_HTTP_MSEARCH) < 0) return; /**** check for * and return if not found ****/ if (mupnp_strstr(mupnp_string_getvalue(ssdpPkt->dgmPkt->data), "*") < 0) return; /**** check HTTP version and return if not found ****/ if (mupnp_strstr(mupnp_string_getvalue(ssdpPkt->dgmPkt->data), CG_HTTP_VER11) < 0) return; /**************************************** * check HOST header, should always be 239.255.255.250:1900, return if incorrect ***************************************/ ssdpTargetAddr = mupnp_ssdp_packet_gethost(ssdpPkt); if (mupnp_strcmp(ssdpTargetAddr, MUPNP_SSDP_MULTICAST_ADDRESS) != 0 && !mupnp_net_isipv6address(ssdpTargetAddr) ) return; /**************************************** * check MAN header, return if incorrect ***************************************/ if (mupnp_ssdp_packet_isdiscover(ssdpPkt) == FALSE) return; /**************************************** * check MX header, return if incorrect ***************************************/ if (ssdpMXString == NULL || mupnp_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 (mupnp_strlen(ssdpST) <= 0) return; /* Check if we have received this search recently * and ignore duplicates. */ if ( filter_duplicate_m_search(ssdpPkt) ) return; ssdpMX = mupnp_ssdp_packet_getmx(ssdpPkt); mupnp_log_debug("Sleeping for a while... (MX:%d)\n", ssdpMX); mupnp_waitrandom((ssdpMX*1000)/4); } isRootDev = mupnp_device_isrootdevice(dev); if (mupnp_st_isalldevice(ssdpST) == TRUE) { /* for root device only */ if (isRootDev == TRUE) { mupnp_device_getnotifydevicent(dev, ssdpMsg, sizeof(ssdpMsg)); mupnp_device_getnotifydeviceusn(dev, deviceUSN, sizeof(deviceUSN)); mupnp_device_postsearchresponse(dev, ssdpPkt, ssdpMsg, deviceUSN); } /* for all devices send */ /* device type : device version */ mupnp_device_getnotifydevicetypent(dev, ssdpMsg, sizeof(ssdpMsg)); mupnp_device_getnotifydevicetypeusn(dev, deviceUSN, sizeof(deviceUSN)); mupnp_device_postsearchresponse(dev, ssdpPkt, ssdpMsg, deviceUSN); /* device UUID */ mupnp_device_postsearchresponse(dev, ssdpPkt, mupnp_device_getudn(dev), mupnp_device_getudn(dev)); } else if (mupnp_st_isrootdevice(ssdpST) == TRUE) { if (isRootDev == TRUE) { mupnp_device_getnotifydeviceusn(dev, deviceUSN, sizeof(deviceUSN)); mupnp_device_postsearchresponse(dev, ssdpPkt, MUPNP_ST_ROOT_DEVICE, deviceUSN); } } else if (mupnp_st_isuuiddevice(ssdpST) == TRUE) { devUDN = mupnp_device_getudn(dev); if (mupnp_streq(ssdpST, devUDN) == TRUE) mupnp_device_postsearchresponse(dev, ssdpPkt, devUDN, devUDN); } else if (mupnp_st_isurn(ssdpST) == TRUE) { devType = mupnp_device_getdevicetype(dev); if (mupnp_streq(ssdpST, devType) == TRUE) { mupnp_device_getnotifydevicetypeusn(dev, deviceUSN, sizeof(deviceUSN)); mupnp_device_postsearchresponse(dev, ssdpPkt, devType, deviceUSN); } } for (service=mupnp_device_getservices(dev); service != NULL; service = mupnp_service_next(service)) mupnp_service_ssdpmessagereceived(service, ssdpPkt); for (childDev = mupnp_device_getdevices(dev); childDev != NULL; childDev = mupnp_device_next(childDev)) mupnp_device_ssdpmessagereceived(childDev, ssdpPkt, FALSE); 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"); }
static char *mupnp_xml_node_tostring_indent(mUpnpXmlNode *node, int indentLevel, bool withChildNode, mUpnpString *str) { char *name; char *value; mUpnpString *valueStr; mUpnpXmlNode *childNode; mupnp_log_debug_l4("Entering...\n"); name = mupnp_xml_node_getname(node); value = mupnp_xml_node_getvalue(node); if (mupnp_xml_node_haschildnodes(node) == false || withChildNode == false) { mupnp_string_addrepvalue(str, MUPNP_XML_INDENT_STRING, indentLevel); if (!mupnp_string_naddvalue(str, "<", 1) || !mupnp_string_addvalue(str, name) || !mupnp_xml_node_attribute_tostring(node, str)) /* Memory allocation failed */ return NULL; valueStr = mupnp_string_new(); if (!valueStr) /* Memory allocation failed */ return NULL; mupnp_string_setvalue(valueStr, value); mupnp_xml_escapechars(valueStr); if (!mupnp_string_naddvalue(str, ">", 1) || !mupnp_string_addvalue(str, mupnp_string_getvalue(valueStr)) || !mupnp_string_naddvalue(str, "</", 2) || !mupnp_string_addvalue(str, name) || !mupnp_string_naddvalue(str, ">", 1) || !mupnp_string_addvalue(str, "\n")) { /* Memory allocation failed */ mupnp_string_delete(valueStr); return NULL; } mupnp_string_delete(valueStr); return mupnp_string_getvalue(str); } mupnp_string_addrepvalue(str, MUPNP_XML_INDENT_STRING, indentLevel); if (!mupnp_string_naddvalue(str, "<", 1) || !mupnp_string_addvalue(str, name) || !mupnp_xml_node_attribute_tostring(node, str) || !mupnp_string_naddvalue(str, ">", 1) || !mupnp_string_addvalue(str, "\n")) /* Memory allocation failed */ return NULL; for (childNode = mupnp_xml_node_getchildnodes(node); childNode != NULL; childNode = mupnp_xml_node_next(childNode)) if (!mupnp_xml_node_tostring_indent(childNode, indentLevel+1, true, str)) /* Memory allocation failed */ return NULL; mupnp_string_addrepvalue(str, MUPNP_XML_INDENT_STRING, indentLevel); if (!mupnp_string_naddvalue(str, "</", 2) || !mupnp_string_addvalue(str, name) || !mupnp_string_naddvalue(str, ">", 1) || !mupnp_string_addvalue(str, "\n")) /* Memory allocation failed */ return NULL; mupnp_log_debug_l4("Leaving...\n"); return mupnp_string_getvalue(str); }
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"); }
/**************************************** * mupnp_upnpav_dms_condir_browsemetadata ****************************************/ static bool mupnp_upnpav_dms_condir_browsemetadata(mUpnpAvServer *dms, mUpnpAction *action) { char *objectID; mUpnpAvContent *objectContent; mUpnpXmlNode *didlNode; mUpnpString *resultStr; char intBuf[MUPNP_STRING_INTEGER_BUFLEN]; mUpnpAvContent *copyContent; objectID = mupnp_action_getargumentvaluebyname(action, CG_UPNPAV_DMS_CONTENTDIRECTORY_BROWSE_OBJECT_ID); if (mupnp_strlen(objectID) <= 0) return false; objectContent = mupnp_upnpav_dms_findcontentbyid(dms, objectID); if (!objectContent) return false; didlNode = mupnp_upnpav_didl_node_new(); copyContent = mupnp_upnpav_content_new(); mupnp_upnpav_content_copy(copyContent, objectContent); mupnp_xml_node_addchildnode(didlNode, copyContent); resultStr = mupnp_string_new(); mupnp_upnpav_didl_node_tostring(didlNode, resultStr); mupnp_action_setargumentvaluebyname(action, CG_UPNPAV_DMS_CONTENTDIRECTORY_BROWSE_RESULT, mupnp_string_getvalue(resultStr)); mupnp_action_setargumentvaluebyname(action, CG_UPNPAV_DMS_CONTENTDIRECTORY_BROWSE_NUMBER_RETURNED, "1"); mupnp_action_setargumentvaluebyname(action, CG_UPNPAV_DMS_CONTENTDIRECTORY_BROWSE_TOTAL_MACHES, "1"); mupnp_action_setargumentvaluebyname(action, CG_UPNPAV_DMS_CONTENTDIRECTORY_BROWSE_UPDATE_ID, (char*)mupnp_int2str(mupnp_upnpav_dms_condir_getsystemupdateid(dms), intBuf, sizeof(intBuf))); /* printf("browsemetadata reply: '%s'\n", mupnp_string_getvalue(resultStr)); */ mupnp_string_delete(resultStr); mupnp_upnpav_didl_node_delete(didlNode); return true; }
static bool mupnp_upnpav_dms_condir_browsedirectchildren(mUpnpAvServer *dms, mUpnpAction *action) { char *objectID; mUpnpAvContent *objectContent; mUpnpAvContent *content; mUpnpAvContent *copyContent; mUpnpAvContentList *sortedContentList; mUpnpAvContent **sortedContentArray; int startingIndex; int requestedCount; int numberReturned; int totalMachesCnt; char intBuf[MUPNP_STRING_INTEGER_BUFLEN]; int n; mUpnpXmlNode *didlNode; mUpnpString *resultStr; objectID = mupnp_action_getargumentvaluebyname(action, CG_UPNPAV_DMS_CONTENTDIRECTORY_BROWSE_OBJECT_ID); if (mupnp_strlen(objectID) <= 0) return false; objectContent = mupnp_upnpav_dms_findcontentbyid(dms, objectID); if (!objectContent) return false; totalMachesCnt = 0; sortedContentList = mupnp_upnpav_contentlist_new(); for (content=mupnp_upnpav_content_getchildcontents(objectContent); content; content=mupnp_upnpav_content_next(content)) { copyContent = mupnp_upnpav_content_new(); mupnp_upnpav_content_copy(copyContent, content); mupnp_upnpav_contentlist_add(sortedContentList, copyContent); totalMachesCnt++; } /* Not Implemented // Sort Content Node Lists string sortCriteria = action->getSortCriteria(); ContentNodeList sortedContentNodeBufList(false); ContentNodeList *sortedContentNodeList = sortContentNodeList(&contentNodeList, sortCriteria.c_str(), sortedContentNodeBufList); */ startingIndex = mupnp_str2int(mupnp_action_getargumentvaluebyname(action, CG_UPNPAV_DMS_CONTENTDIRECTORY_BROWSE_STARTING_INDEX)); if (startingIndex <= 0) startingIndex = 0; requestedCount = mupnp_str2int(mupnp_action_getargumentvaluebyname(action, CG_UPNPAV_DMS_CONTENTDIRECTORY_BROWSE_REQUESTED_COUNT)); if (requestedCount <= 0) requestedCount = mupnp_upnpav_contentlist_size(sortedContentList); numberReturned = 0; didlNode = mupnp_upnpav_didl_node_new(); sortedContentArray = (mUpnpAvContent **)malloc(sizeof(mUpnpAvContent*) * totalMachesCnt); n = 0; for (content=mupnp_upnpav_contentlist_gets(sortedContentList); content; content=mupnp_upnpav_content_next(content)) { sortedContentArray[n] = content; n++; } for (n=startingIndex; (n<totalMachesCnt && numberReturned<requestedCount); n++) { content = sortedContentArray[n]; mupnp_upnpav_content_remove(content); mupnp_upnpav_content_addchildcontent(didlNode, content); mupnp_upnpav_content_setparentid(content, objectID); numberReturned++; } resultStr = mupnp_string_new(); mupnp_upnpav_didl_node_tostring(didlNode, resultStr); mupnp_action_setargumentvaluebyname(action, CG_UPNPAV_DMS_CONTENTDIRECTORY_BROWSE_RESULT, mupnp_string_getvalue(resultStr)); mupnp_action_setargumentvaluebyname(action, CG_UPNPAV_DMS_CONTENTDIRECTORY_BROWSE_NUMBER_RETURNED, (char*)mupnp_int2str(numberReturned, intBuf, sizeof(intBuf))); mupnp_action_setargumentvaluebyname(action, CG_UPNPAV_DMS_CONTENTDIRECTORY_BROWSE_TOTAL_MACHES, (char*)mupnp_int2str(totalMachesCnt, intBuf, sizeof(intBuf))); mupnp_action_setargumentvaluebyname(action, CG_UPNPAV_DMS_CONTENTDIRECTORY_BROWSE_UPDATE_ID, (char*)mupnp_int2str(mupnp_upnpav_dms_condir_getsystemupdateid(dms), intBuf, sizeof(intBuf))); mupnp_string_delete(resultStr); free(sortedContentArray); mupnp_upnpav_didl_node_delete(didlNode); mupnp_upnpav_contentlist_delete(sortedContentList); return true; }
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"); }
mUpnpMediaContent* mupnp_http_getrsscontents(char* rssURL) { mUpnpString* content_str; char* content_string; mUpnpXmlParser* xmlParser; mUpnpXmlNodeList* nodeList; mUpnpXmlNode* rootNode; mUpnpXmlNode* channelNode; mUpnpXmlNode* node; mUpnpXmlNode* childNode; char* container_title; char* content_title; char* contentURL; char containerID[CG_MD5_STRING_BUF_SIZE]; char contentID[CG_MD5_STRING_BUF_SIZE]; long contentSize; int nContentent; char* contentMimeType; mUpnpMediaContent* content; mUpnpMediaContent* container; mUpnpMediaResource* res; content_str = mupnp_string_new(); if (!mupnp_http_getrestresponse(rssURL, content_str)) { mupnp_string_delete(content_str); return NULL; } content_string = mupnp_string_getvalue(content_str); if (mupnp_strlen(content_string) <= 0) { mupnp_string_delete(content_str); return NULL; } nodeList = mupnp_xml_nodelist_new(); xmlParser = mupnp_xml_parser_new(); if (mupnp_xml_parse(xmlParser, nodeList, content_string, mupnp_strlen(content_string)) == FALSE) { mupnp_string_delete(content_str); mupnp_xml_parser_delete(xmlParser); mupnp_xml_nodelist_delete(nodeList); return NULL; } mupnp_string_delete(content_str); mupnp_xml_parser_delete(xmlParser); nContentent = 0; rootNode = mupnp_xml_nodelist_gets(nodeList); if (rootNode == NULL) { mupnp_xml_nodelist_delete(rootNode); return NULL; } channelNode = mupnp_xml_node_getchildnode(rootNode, "channel"); if (channelNode == NULL) { mupnp_xml_nodelist_delete(rootNode); return NULL; } /**** container ****/ // Title container_title = ""; childNode = mupnp_xml_node_getchildnode(channelNode, "title"); if (childNode) { if (mupnp_xml_node_getvalue(childNode)) container_title = mupnp_xml_node_getvalue(childNode); } if (mupnp_strlen(container_title) <= 0) { mupnp_xml_nodelist_delete(rootNode); return NULL; } container = mupnp_media_content_new(); mupnp_media_content_settype(container, MUPNP_MEDIA_CONTENT_CONTAINER); mupnp_media_content_settitle(container, container_title); mupnp_str2md5(container_title, containerID); mupnp_media_content_setid(container, containerID); /**** item ****/ for (node = mupnp_xml_node_getchildnodes(channelNode); node; node = mupnp_xml_node_next(node)) { if (!mupnp_xml_node_isname(node, "item")) continue; content_title = ""; contentURL = ""; contentSize = 0; // Title childNode = mupnp_xml_node_getchildnode(node, "title"); if (childNode) { if (mupnp_xml_node_getvalue(childNode)) content_title = mupnp_xml_node_getvalue(childNode); } // Enclosure childNode = mupnp_xml_node_getchildnode(node, "enclosure"); if (childNode) { // url if (mupnp_xml_node_getattributevalue(childNode, "url")) contentURL = mupnp_xml_node_getattributevalue(childNode, "url"); // type if (mupnp_xml_node_getattributevalue(childNode, "type")) contentMimeType = mupnp_xml_node_getattributevalue(childNode, "type"); // type if (mupnp_xml_node_getattributevalue(childNode, "length")) contentSize = atol(mupnp_xml_node_getattributevalue(childNode, "length")); } if (mupnp_strlen(content_title) <= 0 || mupnp_strlen(contentURL) <= 0) continue; content = mupnp_media_content_new(); mupnp_media_content_settype(content, MUPNP_MEDIA_CONTENT_ITEM); /**** content name ****/ content_title = mupnp_strtrim(content_title, " ", 1); if (mupnp_strlen(content_title) <= 0) { continue; } mupnp_media_content_settitle(content, content_title); /**** content id ****/ mupnp_str2md5(contentURL, contentID); mupnp_media_content_setid(content, contentID); mupnp_media_content_addchildcontent(container, content); res = mupnp_media_resource_new(); mupnp_media_resource_setmimetype(res, contentMimeType); mupnp_media_resource_seturl(res, contentURL); mupnp_media_resource_setsize(res, contentSize); mupnp_media_content_addresource(content, res); nContentent++; } mupnp_xml_nodelist_delete(nodeList); return container; }
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"); }