const char* mupnp_event_subscription_tosidheaderstring(const char* sid, char* buf, size_t bufSize) { ssize_t colonIdx; mupnp_log_debug_l4("Entering...\n"); colonIdx = mupnp_strstr(sid, MUPNP_SUBSCRIPTION_UUID); if (0 <= colonIdx) { mupnp_strncpy(buf, sid, bufSize); buf[bufSize - 1] = '\0'; return buf; } #if defined(HAVE_SNPRINTF) snprintf(buf, bufSize, #else sprintf(buf, #endif "%s%s", MUPNP_SUBSCRIPTION_UUID, sid); return buf; mupnp_log_debug_l4("Leaving...\n"); }
long mupnp_ssdp_packet_getmaxage(mUpnpSSDPPacket *ssdpPkt) { const char *cachecontrol = NULL; ssize_t maxageIdx = 0; mupnp_log_debug_l4("Entering...\n"); cachecontrol = mupnp_ssdp_packet_getcachecontrol(ssdpPkt); if (cachecontrol == NULL) return 0; maxageIdx = mupnp_strstr(cachecontrol, MUPNP_HTTP_MAX_AGE); if (maxageIdx < 0) return 0; maxageIdx = mupnp_strstr(cachecontrol+maxageIdx, "="); if (maxageIdx <= 0) return 0; maxageIdx++; return mupnp_str2long(cachecontrol+maxageIdx); mupnp_log_debug_l4("Leaving...\n"); }
const char* mupnp_event_subscription_getsid(const char* headerValue) { ssize_t colonIdx; mupnp_log_debug_l4("Entering...\n"); colonIdx = mupnp_strstr(headerValue, ":"); if (colonIdx < 0) return headerValue; mupnp_log_debug_l4("Leaving...\n"); return (headerValue + colonIdx + 1); }
mUpnpTime mupnp_event_subscription_gettimeout(const char* headerValue) { ssize_t minusIdx; long timeout; mupnp_log_debug_l4("Entering...\n"); minusIdx = mupnp_strstr(headerValue, "-"); if (minusIdx < 0) return MUPNP_SUBSCRIPTION_INFINITE_VALUE; timeout = mupnp_str2long(headerValue + minusIdx + 1); if (timeout == 0) return MUPNP_SUBSCRIPTION_INFINITE_VALUE; if (timeout < 0) timeout = -timeout; return timeout; 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_control_action_request_getactionname(mUpnpActionRequest *actionReq) { mUpnpXmlNode *node; char *name; ssize_t urnDelimIdx; mupnp_log_debug_l4("Entering...\n"); node = mupnp_control_action_request_getactionnode(actionReq); if (node == NULL) return ""; name = mupnp_xml_node_getname(node); if (name == NULL) return ""; urnDelimIdx = mupnp_strstr(name, MUPNP_HTTP_SOAP_URN_DELIM); if (urnDelimIdx < 0) return ""; mupnp_log_debug_l4("Leaving...\n"); return (name + urnDelimIdx + 1); }
mUpnpXmlNode *mupnp_xml_node_getchildnodewithnamespace(mUpnpXmlNode *node, const char *name, const char *ns, bool ignoreNs) { char *nameWithPrefix = NULL; size_t nameLen = 0; ssize_t nameIdx; mUpnpXmlNode *result = NULL; mUpnpXmlNode *child = NULL; char *nodeName = NULL; mupnp_log_debug_l4("Entering...\n"); if (node == NULL) return NULL; if (name == NULL) return NULL; if (ignoreNs == true) { for (child = mupnp_xml_node_getchildnodelist(node); child != NULL; child = mupnp_xml_node_next(child)) { nodeName = mupnp_xml_node_getname(child); if (nodeName == NULL) continue; nameIdx = mupnp_strstr(nodeName, ":"); if (nameIdx < 0) { /* No prefix (no ':') */ if (mupnp_strcasecmp(nodeName, name) == 0) return child; } else { if (mupnp_strcasecmp(&(nodeName[nameIdx+1]), name) == 0) return child; } } return NULL; } else { if (ns == NULL) { /* When ns is NULL, this works like normal ..._getchildnode */ return mupnp_xml_node_getchildnode(node, name); } nameLen = mupnp_strlen(name) + mupnp_strlen(ns) + 1; /* Not including the terminating \0 */ nameWithPrefix = (char*) malloc(nameLen + 1); if (nameWithPrefix == NULL) return NULL; #if defined(HAVE_SNPRINTF) snprintf(nameWithPrefix, nameLen + 1, "%s:%s", ns, name); #else sprintf(nameWithPrefix, "%s:%s", ns, name); #endif result = mupnp_xml_node_getchildnode(node, nameWithPrefix); free(nameWithPrefix); return result; } mupnp_log_debug_l4("Leaving...\n"); }
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; }
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"); }