📄 pidf.c
字号:
xmlXPathObjectPtr result; xmlNodeSetPtr nodeset; xmlNodePtr node; context = xmlXPathNewContext(doc); result = xmlXPathEvalExpression((unsigned char*)xpath, context); if(xmlXPathNodeSetIsEmpty(result->nodesetval)){ fprintf(stderr, "xpath_get_node: no result for xpath=%s\n", xpath); return NULL; } nodeset = result->nodesetval; node = nodeset->nodeTab[0]; xmlXPathFreeContext(context); return node;}xmlAttrPtr xmlNodeGetAttrByName(xmlNodePtr node, const char *name){ xmlAttrPtr attr = node->properties; while (attr) { if (xmlStrcasecmp(attr->name, (unsigned char*)name) == 0) return attr; attr = attr->next; } return NULL;}char *xmlNodeGetAttrContentByName(xmlNodePtr node, const char *name){ xmlAttrPtr attr = xmlNodeGetAttrByName(node, name); if (attr) return (char*)xmlNodeGetContent(attr->children); else return NULL;}xmlNodePtr xmlNodeGetChildByName(xmlNodePtr node, const char *name){ xmlNodePtr cur = node->children; while (cur) { if (xmlStrcasecmp(cur->name, (unsigned char*)name) == 0) return cur; cur = cur->next; } return NULL;}xmlNodePtr xmlNodeGetNodeByName(xmlNodePtr node, const char *name, const char *ns){ xmlNodePtr cur = node; while (cur) { xmlNodePtr match = NULL; if (xmlStrcasecmp(cur->name, (unsigned char*)name) == 0) { if (!ns || (cur->ns && xmlStrcasecmp(cur->ns->prefix, (unsigned char*)ns) == 0)) return cur; } match = xmlNodeGetNodeByName(cur->children, name, ns); if (match) return match; cur = cur->next; } return NULL;}char *xmlNodeGetNodeContentByName(xmlNodePtr root, const char *name, const char *ns){ xmlNodePtr node = xmlNodeGetNodeByName(root, name, ns); if (node) return (char*)xmlNodeGetContent(node->children); else return NULL;}xmlNodePtr xmlDocGetNodeByName(xmlDocPtr doc, const char *name, const char *ns){ xmlNodePtr cur = doc->children; return xmlNodeGetNodeByName(cur, name, ns);}char *xmlDocGetNodeContentByName(xmlDocPtr doc, const char *name, const char *ns){ xmlNodePtr node = xmlDocGetNodeByName(doc, name, ns); if (node) return (char*)xmlNodeGetContent(node->children); else return NULL;}void xmlNodeMapByName(xmlNodePtr node, const char *name, const char *ns, void (f)(xmlNodePtr, void*), void *data){ xmlNodePtr cur = node; if (!f) return; while (cur) { if (xmlStrcasecmp(cur->name, (unsigned char*)name) == 0) { if (!ns || (cur->ns && xmlStrcasecmp(cur->ns->prefix, (unsigned char*)ns) == 0)) f(cur, data); } /* visit children */ xmlNodeMapByName(cur->children, name, ns, f, data); cur = cur->next; }}void xmlDocMapByName(xmlDocPtr doc, const char *name, const char *ns, void (f)(xmlNodePtr, void*), void *data ){ xmlNodePtr cur = doc->children; xmlNodeMapByName(cur, name, ns, f, data);}int parse_pidf(char *pidf_body, str *contact_str, str *basic_str, str *status_str, str *location_str, str *site_str, str *floor_str, str *room_str, double *xp, double *yp, double *radiusp, str *packet_loss_str, double *priorityp, time_t *expiresp, int *prescapsp){ int flags = 0; xmlDocPtr doc = NULL; xmlNodePtr presenceNode = NULL; xmlNodePtr prescapsNode = NULL; char *presence = NULL; char *sipuri = NULL; char *contact = NULL; char *basic = NULL; char *status = NULL; char *location = NULL; char *site = NULL; char *floor = NULL; char *room = NULL; char *x = NULL; char *y = NULL; char *radius = NULL; char *packet_loss = NULL; char *priority_str = NULL; char *expires_str = NULL; int prescaps = 0; doc = event_body_parse(pidf_body); if (!doc) { return flags; } presenceNode = xmlDocGetNodeByName(doc, "presence", NULL); presence = xmlDocGetNodeContentByName(doc, "presence", NULL); contact = xmlDocGetNodeContentByName(doc, "contact", NULL); basic = xmlDocGetNodeContentByName(doc, "basic", NULL); status = xmlDocGetNodeContentByName(doc, "status", NULL); location = xmlDocGetNodeContentByName(doc, "loc", NULL); site = xmlDocGetNodeContentByName(doc, "site", NULL); floor = xmlDocGetNodeContentByName(doc, "floor", NULL); room = xmlDocGetNodeContentByName(doc, "room", NULL); x = xmlDocGetNodeContentByName(doc, "x", NULL); y = xmlDocGetNodeContentByName(doc, "y", NULL); radius = xmlDocGetNodeContentByName(doc, "radius", NULL); packet_loss = xmlDocGetNodeContentByName(doc, "packet-loss", NULL); priority_str = xmlDocGetNodeContentByName(doc, "priority", NULL); expires_str = xmlDocGetNodeContentByName(doc, "expires", NULL); prescapsNode = xmlDocGetNodeByName(doc, "prescaps", NULL); if (presenceNode) sipuri = xmlNodeGetAttrContentByName(presenceNode, "entity"); LOG(L_INFO, "parse_pidf: sipuri=%p:%s contact=%p:%s basic=%p:%s location=%p:%s\n", sipuri, sipuri, contact, contact, basic, basic, location, location); LOG(L_INFO, "parse_pidf: site=%p:%s floor=%p:%s room=%p:%s\n", site, site, floor, floor, room, room); LOG(L_INFO, "parse_pidf: x=%p:%s y=%p:%s radius=%p:%s\n", x, x, y, y, radius, radius); if (packet_loss) LOG(L_INFO, "packet_loss=%p:%s\n", packet_loss, packet_loss); if (contact_str && contact) { contact_str->len = strlen(contact); contact_str->s = strdup(contact); flags |= PARSE_PIDF_CONTACT; } if (basic_str && basic) { basic_str->len = strlen(basic); basic_str->s = strdup(basic); flags |= PARSE_PIDF_BASIC; } if (status_str && status) { status_str->len = strlen(status); status_str->s = strdup(status); flags |= PARSE_PIDF_STATUS; } if (location_str && location) { location_str->len = strlen(location); location_str->s = strdup(location); flags |= PARSE_PIDF_LOC; } if (site_str && site) { site_str->len = strlen(site); site_str->s = strdup(site); flags |= PARSE_PIDF_SITE; } if (floor_str && floor) { floor_str->len = strlen(floor); floor_str->s = strdup(floor); flags |= PARSE_PIDF_FLOOR; } if (room_str && room) { room_str->len = strlen(room); room_str->s = strdup(room); flags |= PARSE_PIDF_ROOM; } if (xp && x) { *xp = strtod(x, NULL); flags |= PARSE_PIDF_X; } if (yp && y) { *yp = strtod(y, NULL); flags |= PARSE_PIDF_Y; } if (radiusp && radius) { *radiusp = strtod(radius, NULL); flags |= PARSE_PIDF_RADIUS; } if (packet_loss_str && packet_loss) { packet_loss_str->len = strlen(packet_loss); packet_loss_str->s = strdup(packet_loss); flags |= PARSE_PIDF_PACKET_LOSS; } if (expiresp && expires_str) { *expiresp = act_time + strtod(expires_str, NULL); flags |= PARSE_PIDF_EXPIRES; } if (priorityp && priority_str) { *priorityp = strtod(priority_str, NULL); flags |= PARSE_PIDF_PRIORITY; } if (prescapsNode) { int i; for (i = 0; i < 4; i++) { const char *prescap_name = prescap_names[i]; xmlNodePtr prescap_node = xmlNodeGetNodeByName(prescapsNode, prescap_name, NULL); const char *prescap_str = xmlNodeGetNodeContentByName(prescapsNode, prescap_name, NULL); if (prescap_str && (strcasecmp(prescap_str, "true") == 0)) prescaps |= (1 << i); LOG(L_INFO, "parse_pidf: prescap=%s node=%p value=%s\n", prescap_name, prescap_node, prescap_str); } LOG(L_INFO, "parse_pidf: prescaps=%x\n", prescaps); } if (prescapsp) { *prescapsp = prescaps; flags |= PARSE_PIDF_PRESCAPS; } return flags;}/* from modules/mangler/utils.c: */intpatch_msg (struct sip_msg *msg, char *oldstr, unsigned int oldlen, char *newstr, unsigned int newlen){ int off; struct lump *anchor; if (oldstr == NULL) return -1; if (newstr == NULL) return -2; off = oldstr - msg->buf; if (off < 0) return -3; if ((anchor = del_lump (msg, off, oldlen, 0)) == 0) { LOG (L_ERR, "ERROR: patch: error lumping with del_lump\n"); return -4; } if ((insert_new_lump_after (anchor, newstr, newlen, 0)) == 0) { LOG (L_ERR, "ERROR: patch: error lumping with insert_new_lump_after\n"); return -5; } return 0;}int mangle_pidf(struct sip_msg* _msg, char* _domain, char* _s2){ char *body = get_body(_msg); int body_len = strlen(body); xmlDocPtr doc = NULL; xmlNodePtr presenceNode = NULL; xmlNodePtr personNode = NULL; xmlNodePtr noteNode = NULL; xmlNodePtr wav3substatusNode = NULL; doc = event_body_parse(body); if (!doc) { return 1; } presenceNode = xmlDocGetNodeByName(doc, "presence", NULL); personNode = xmlDocGetNodeByName(doc, "person", NULL); noteNode = xmlDocGetNodeByName(doc, "note", NULL); wav3substatusNode = xmlDocGetNodeByName(doc, "wav3substatus", NULL); if (presenceNode) { xmlNsPtr ns = presenceNode->ns; int patch = 0; //LOG(L_ERR, "mangle_pidf -1-\n"); if (wav3substatusNode) { // add note node for Eyebeam with copy of contents of wav3substatus //LOG(L_ERR, "mangle_pidf -2-\n"); noteNode = xmlNewNode(ns, (unsigned char*)"note"); xmlAddChild(presenceNode, noteNode); xmlNodeSetContent(noteNode, (unsigned char*) strdup((char*)xmlNodeGetContent(wav3substatusNode))); LOG(L_ERR, "mangle_pidf -3-\n"); patch = 1; } else if (noteNode) { //LOG(L_ERR, "mangle_pidf -4-\n"); wav3substatusNode = xmlNewNode(ns,(unsigned char*)"wav3substatus"); xmlNodeSetContent(wav3substatusNode, (unsigned char*) strdup((char*)xmlNodeGetContent(noteNode))); xmlAddChild(presenceNode, wav3substatusNode); LOG(L_ERR, "mangle_pidf -5-\n"); patch = 1; } if (patch) { xmlChar *new_body = NULL; char *nbp; int new_body_len = 0; //LOG(L_ERR, "mangle_pidf -6-\n"); xmlDocDumpMemory(doc, &new_body, &new_body_len); if (new_body && new_body_len > 0) { nbp = pkg_malloc(new_body_len+1); strncpy(nbp, (char*)new_body, new_body_len+1); if (1) LOG(L_ERR, "mangle_pidf -7- old_body_len=%d new_body_len=%d new_body=%s\n", body_len, new_body_len, nbp); if (0) LOG(L_ERR, "mangle_pidf -7a- body_lumps=%p\n", _msg->body_lumps); patch_msg(_msg, body, body_len, nbp, new_body_len); } } } LOG(L_ERR, "mangle_pidf -8-\n"); return 1;}int mangle_message_cpim(struct sip_msg* _msg, char* _s1, char* _s2){ char *body = get_body(_msg); int parsed_content_type; struct hdr_field *content_type = _msg->content_type; int body_len = 0; parse_headers(_msg, HDR_CONTENTLENGTH_F|HDR_CONTENTTYPE_F, 0); parsed_content_type = parse_content_type_hdr(_msg); body_len = get_content_length(_msg); LOG(L_ERR, "mangle_message_cpim -1- content_type==%.*s %x (patching %x) bodylen=%d\n", content_type->body.len, content_type->body.s, parsed_content_type, MIMETYPE(MESSAGE,CPIM), body_len); if (body && (parsed_content_type == MIMETYPE(MESSAGE,CPIM))) { char *ptr = strstr(body, "\r\n\r\n"); char *new_content_type_str = strstr(body, "Content-Type: "); int new_content_type_len = 0; char *new_content_type_body; if (new_content_type_str) { char *new_content_type_end = strstr(new_content_type_str, "\r\n"); if (new_content_type_end) { new_content_type_str += 14; new_content_type_len = new_content_type_end - new_content_type_str; } else { new_content_type_len = 10; new_content_type_str = "text/plain"; } } else { new_content_type_len = 10; new_content_type_str = "text/plain"; } if (strncmp(new_content_type_str, "application/sip-iscomposing+xml", 31) == 0) { new_content_type_len = 30; new_content_type_str = "application/im-iscomposing+xml"; } new_content_type_body = pkg_malloc(new_content_type_len); strncpy(new_content_type_body, new_content_type_str, new_content_type_len); //LOG(L_ERR, "mangle_message_cpim -1- oldbody=%.*s\n", body_len, body); patch_msg(_msg, content_type->body.s, content_type->body.len, new_content_type_body, new_content_type_len); LOG(L_ERR, "mangle_message_cpim -1b- patched content-type=%.*s\n", new_content_type_len, new_content_type_str); if (ptr) { char *new_body = NULL; int new_body_len = body_len - (ptr + 4 - body); //LOG(L_ERR, "mangle_message_cpim -2- old_body_len=%d new_body_len=%d\n", body_len, new_body_len); new_body = pkg_malloc(new_body_len+1); strncpy(new_body, ptr+4, new_body_len+1); patch_msg(_msg, body, body_len, new_body, new_body_len); } } LOG(L_ERR, "mangle_message_cpim -3-\n"); return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -