int bla_handle_notify(struct sip_msg* msg, char* s1, char* s2) { publ_info_t publ; struct to_body *pto= NULL, TO, *pfrom = NULL; str body; ua_pres_t dialog; unsigned int expires= 0; struct hdr_field* hdr; str subs_state; str extra_headers= {0, 0}; static char buf[255]; str contact; memset(&publ, 0, sizeof(publ_info_t)); memset(&dialog, 0, sizeof(ua_pres_t)); if ( parse_headers(msg,HDR_EOH_F, 0)==-1 ) { LM_ERR("parsing headers\n"); return -1; } if( msg->to==NULL || msg->to->body.s==NULL) { LM_ERR("cannot parse TO header\n"); return -1; } /* examine the to header */ if(msg->to->parsed != NULL) { pto = (struct to_body*)msg->to->parsed; LM_DBG("'To' header ALREADY PARSED: <%.*s>\n", pto->uri.len, pto->uri.s ); } else { parse_to(msg->to->body.s,msg->to->body.s + msg->to->body.len + 1, &TO); if(TO.uri.len <= 0) { LM_DBG("'To' header NOT parsed\n"); return -1; } pto = &TO; } publ.pres_uri= &pto->uri; dialog.watcher_uri= publ.pres_uri; if (pto->tag_value.s==NULL || pto->tag_value.len==0 ) { LM_ERR("NULL to_tag value\n"); return -1; } dialog.from_tag= pto->tag_value; if( msg->callid==NULL || msg->callid->body.s==NULL) { LM_ERR("cannot parse callid header\n"); return -1; } dialog.call_id = msg->callid->body; if (!msg->from || !msg->from->body.s) { LM_ERR("cannot find 'from' header!\n"); return -1; } if (msg->from->parsed == NULL) { LM_DBG(" 'From' header not parsed\n"); /* parsing from header */ if ( parse_from_header( msg )<0 ) { LM_DBG(" ERROR cannot parse From header\n"); return -1; } } pfrom = (struct to_body*)msg->from->parsed; dialog.to_uri= pfrom->uri; if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0) { LM_ERR("no from tag value present\n"); return -1; } if ( get_content_length(msg) == 0 ) { LM_DBG("content length= 0\n"); return 1; } else { body.s=get_body(msg); if (body.s== NULL) { LM_ERR("cannot extract body from msg\n"); return -1; } body.len = get_content_length( msg ); if (!bla_body_is_valid( &body )) { LM_ERR("bad XML body!"); return -1; } } if(msg->contact== NULL || msg->contact->body.s== NULL) { LM_ERR("no contact header found"); return -1; } if( parse_contact(msg->contact) <0 ) { LM_ERR(" cannot parse contact header\n"); return -1; } if(msg->contact->parsed == NULL) { LM_ERR("cannot parse contact header\n"); return -1; } contact = ((contact_body_t* )msg->contact->parsed)->contacts->uri; dialog.to_tag= pfrom->tag_value; dialog.event= BLA_EVENT; dialog.flag= BLA_SUBSCRIBE; if(pua_is_dialog(&dialog)< 0) { LM_ERR("Notify in a non existing dialog\n"); return -2; } /* parse Subscription-State and extract expires if existing */ hdr = get_header_by_static_name( msg, "Subscription-State"); if( hdr==NULL ) { LM_ERR("No Subscription-State header found\n"); return -1; } subs_state= hdr->body; if(strncasecmp(subs_state.s, "terminated", 10)== 0) expires= 0; else { if(strncasecmp(subs_state.s, "active", 6)== 0 || strncasecmp(subs_state.s, "pending", 7)==0 ) { expires = DEFAULT_EXPIRES; char* sep= NULL; str exp= {NULL, 0}; sep= strchr(subs_state.s, ';'); if(sep) { if(strncasecmp(sep+1, "expires=", 8)== 0) { exp.s= sep+ 9; sep= exp.s; while((*sep)>='0' && (*sep)<='9') { sep++; exp.len++; } if( str2int(&exp, &expires)< 0) { LM_ERR("while parsing int\n"); return -1; } } } } else { LM_ERR("unknown Subscription-state token\n"); return -1; } } /* +2 for ": " between header name and value */ if ((header_name.len + 2 + contact.len + CRLF_LEN) >= sizeof(buf)) { LM_ERR("Sender header too large"); return -1; } /* build extra_headers with Sender*/ extra_headers.s= buf; memcpy(extra_headers.s, header_name.s, header_name.len); extra_headers.len= header_name.len; memcpy(extra_headers.s+extra_headers.len,": ",2); extra_headers.len+= 2; memcpy(extra_headers.s+ extra_headers.len, contact.s, contact.len); extra_headers.len+= contact.len; memcpy(extra_headers.s+ extra_headers.len, CRLF, CRLF_LEN); extra_headers.len+= CRLF_LEN; publ.id= contact; publ.body= &body; publ.source_flag= BLA_PUBLISH; publ.expires= expires; publ.event= BLA_EVENT; publ.extra_headers= &extra_headers; publ.outbound_proxy = presence_server; if(pua_send_publish(&publ)< 0) { LM_ERR("failed to send Publish message\n"); return -1; } return 1; }
int bla_handle_notify(struct sip_msg* msg, char* s1, char* s2) { publ_info_t publ; struct to_body *pto = NULL, TO = {0}, *pfrom = NULL; str body; ua_pres_t dialog; unsigned int expires= 0; struct hdr_field* hdr; str subs_state; int found= 0; str extra_headers= {0, 0}; static char buf[255]; str contact; memset(&publ, 0, sizeof(publ_info_t)); memset(&dialog, 0, sizeof(ua_pres_t)); LM_DBG("start\n"); if ( parse_headers(msg,HDR_EOH_F, 0)==-1 ) { LM_ERR("parsing headers\n"); return -1; } if( msg->to==NULL || msg->to->body.s==NULL) { LM_ERR("cannot parse TO header\n"); goto error; } /* examine the to header */ if(msg->to->parsed != NULL) { pto = (struct to_body*)msg->to->parsed; LM_DBG("'To' header ALREADY PARSED: <%.*s>\n", pto->uri.len, pto->uri.s ); } else { parse_to(msg->to->body.s,msg->to->body.s + msg->to->body.len + 1, &TO); if(TO.uri.len <= 0) { LM_DBG("'To' header NOT parsed\n"); goto error; } pto = &TO; } publ.pres_uri= &pto->uri; dialog.watcher_uri= publ.pres_uri; if (pto->tag_value.s==NULL || pto->tag_value.len==0 ) { LM_ERR("NULL to_tag value\n"); goto error; } dialog.from_tag= pto->tag_value; if( msg->callid==NULL || msg->callid->body.s==NULL) { LM_ERR("cannot parse callid header\n"); goto error; } dialog.call_id = msg->callid->body; if (!msg->from || !msg->from->body.s) { LM_ERR("cannot find 'from' header!\n"); goto error; } if (msg->from->parsed == NULL) { LM_DBG(" 'From' header not parsed\n"); /* parsing from header */ if ( parse_from_header( msg )<0 ) { LM_DBG(" ERROR cannot parse From header\n"); goto error; } } pfrom = (struct to_body*)msg->from->parsed; dialog.pres_uri= &pfrom->uri; if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0) { LM_ERR("no from tag value present\n"); goto error; } dialog.to_tag= pfrom->tag_value; dialog.event= BLA_EVENT; dialog.flag= BLA_SUBSCRIBE; if(pua_is_dialog(&dialog)< 0) { LM_ERR("Notify in a non existing dialog\n"); goto error; } LM_DBG("found a matching dialog\n"); /* parse Subscription-State and extract expires if existing */ hdr = msg->headers; while (hdr!= NULL) { if(cmp_hdrname_strzn(&hdr->name, "Subscription-State",18)==0) { found = 1; break; } hdr = hdr->next; } if(found==0 ) { LM_ERR("No Subscription-State header found\n"); goto error; } subs_state= hdr->body; if(strncmp(subs_state.s, "terminated", 10)== 0) expires= 0; else if(strncmp(subs_state.s, "active", 6)== 0 || strncmp(subs_state.s, "pending", 7)==0 ) { char* sep= NULL; str exp= {0, 0}; sep= strchr(subs_state.s, ';'); if(sep== NULL) { LM_ERR("No expires found in Notify\n"); goto error; } if(strncmp(sep+1, "expires=", 8)!= 0) { LM_ERR("No expires found in Notify\n"); goto error; } exp.s= sep+ 9; sep= exp.s; while((*sep)>='0' && (*sep)<='9') { sep++; exp.len++; } if( str2int(&exp, &expires)< 0) { LM_ERR("while parsing int\n"); goto error; } } if ( get_content_length(msg) == 0 ) { LM_ERR("content length= 0\n"); goto error; } else { body.s=get_body(msg); if (body.s== NULL) { LM_ERR("cannot extract body from msg\n"); goto error; } body.len = get_content_length( msg ); } if(msg->contact== NULL || msg->contact->body.s== NULL) { LM_ERR("no contact header found"); goto error; } if( parse_contact(msg->contact) <0 ) { LM_ERR(" cannot parse contact header\n"); goto error; } if(msg->contact->parsed == NULL) { LM_ERR("cannot parse contact header\n"); goto error; } contact = ((contact_body_t* )msg->contact->parsed)->contacts->uri; /* build extra_headers with Sender*/ extra_headers.s= buf; memcpy(extra_headers.s, header_name.s, header_name.len); extra_headers.len= header_name.len; memcpy(extra_headers.s+extra_headers.len,": ",2); extra_headers.len+= 2; memcpy(extra_headers.s+ extra_headers.len, contact.s, contact.len); extra_headers.len+= contact.len; memcpy(extra_headers.s+ extra_headers.len, CRLF, CRLF_LEN); extra_headers.len+= CRLF_LEN; publ.body= &body; publ.source_flag= BLA_PUBLISH; publ.expires= expires; publ.event= BLA_EVENT; publ.extra_headers= &extra_headers; if(pua_send_publish(&publ)< 0) { LM_ERR("while sending Publish\n"); goto error; } xmlCleanupParser(); xmlMemoryDump(); free_to_params(&TO); return 1; error: free_to_params(&TO); return 0; }
int Notify2Xmpp(struct sip_msg* msg, char* s1, char* s2) { struct to_body *pto, *pfrom= NULL; str to_uri; str from_uri={0, 0}; struct hdr_field* hdr= NULL; str body; xmlDocPtr doc= NULL; int is_terminated= 0; str id; ua_pres_t dialog; int event_flag= 0; char buf_to[256]; memset(&dialog, 0, sizeof(ua_pres_t)); LM_DBG("start...\n\n"); if( parse_headers(msg,HDR_EOH_F, 0)==-1 ) { LM_ERR("parsing headers\n"); return -1; } if((!msg->event ) ||(msg->event->body.len<=0)) { LM_ERR("Missing event header field value\n"); return -1; } if( msg->to==NULL || msg->to->body.s==NULL) { LM_ERR("cannot parse TO header\n"); return -1; } pto = get_to(msg); if (pto == NULL || pto->error != PARSE_OK) { LM_ERR("failed to parse TO header\n"); return -1; } dialog.watcher_uri= &pto->uri; URI_ADD_NULL_TERM(to_uri, buf_to, dialog.watcher_uri); if (pto->tag_value.s==NULL || pto->tag_value.len==0 ) { LM_ERR("to tag value not parsed\n"); goto error; } id= pto->tag_value; dialog.from_tag= id; if( msg->callid==NULL || msg->callid->body.s==NULL) { LM_ERR("cannot parse callid header\n"); goto error; } dialog.call_id = msg->callid->body; if (!msg->from || !msg->from->body.s) { LM_ERR("ERROR cannot find 'from' header!\n"); goto error; } if (msg->from->parsed == NULL) { /* parsing from header */ if ( parse_from_header( msg )<0 ) { LM_ERR("ERROR cannot parse From header\n"); goto error; } } pfrom = (struct to_body*)msg->from->parsed; dialog.pres_uri= &pfrom->uri; from_uri.s = xmpp_uri_sip2xmpp(dialog.pres_uri); if(from_uri.s == 0) { LM_ERR("Failed to translate uri from sip to xmpp [%.*s]\n", dialog.pres_uri->len, dialog.pres_uri->s); goto error; } from_uri.len= strlen(from_uri.s); if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0) { LM_ERR("no from tag value present\n"); goto error; } dialog.to_tag= pfrom->tag_value; dialog.flag|= XMPP_SUBSCRIBE; if(msg->event->body.len== 8 && (strncasecmp(msg->event->body.s,"presence",8 )==0)) event_flag|= PRESENCE_EVENT; else if(msg->event->body.len== 14 && (strncasecmp(msg->event->body.s,"presence.winfo",14 )==0)) event_flag|= PWINFO_EVENT; else { LM_ERR("wrong event\n"); goto error; } dialog.event= event_flag; if(pua_is_dialog(&dialog)< 0) // verify if within a stored dialog { LM_ERR("Notify in a non existing dialog\n"); goto error; } /*constructing the xml body*/ if(get_content_length(msg) == 0 ) { body.s= NULL; body.len= 0; } else { if ( get_body(msg,&body)!=0 || body.len==0) { LM_ERR("cannot extract body from msg\n"); goto error; } } /* treat the two cases: event= presence & event=presence.winfo */ if(event_flag & PRESENCE_EVENT) { LM_DBG("PRESENCE\n"); hdr = get_header_by_static_name( msg, "Subscription-State" ); if(hdr && strncasecmp(hdr->body.s,"terminated", 10)== 0) { /* chack if reason timeout => don't send notification */ if(strncasecmp(hdr->body.s+11,"reason=timeout", 14)== 0) { LM_DBG("Received Notification with state" "terminated; reason= timeout=> don't send notification\n"); return 1; } is_terminated= 1; } if(build_xmpp_content(&to_uri, &from_uri, &body, &id, is_terminated)< 0) { LM_ERR("in function build_xmpp_content\n"); goto error; } xmlFreeDoc(doc); } else { if(event_flag & PWINFO_EVENT) { LM_DBG("PRESENCE.WINFO\n"); hdr = get_header_by_static_name( msg, "Subscription-State" ); if(hdr && strncasecmp(hdr->body.s,"terminated", 10)== 0) { LM_DBG("Notify for presence.winfo with" " Subscription-State terminated- should not translate\n"); goto error; } if(winfo2xmpp(&to_uri, &body, &id)< 0) { LM_ERR("while sending subscription\n"); goto error; } } else { LM_ERR("Missing or unsupported event header field value\n"); goto error; } } return 1; error: if(doc) xmlFreeDoc(doc); return 0; }
int Notify2Xmpp(struct sip_msg* msg, char* s1, char* s2) { struct to_body *pto, TO = {0}, *pfrom = NULL; str to_uri; char* uri= NULL; str from_uri; struct hdr_field* hdr= NULL; str body; int is_terminated= 0; str id; ua_pres_t dialog; int event_flag= 0; memset(&dialog, 0, sizeof(ua_pres_t)); LM_DBG("start...\n\n"); if( parse_headers(msg,HDR_EOH_F, 0)==-1 ) { LM_ERR("parsing headers\n"); return -1; } if((!msg->event ) ||(msg->event->body.len<=0)) { LM_ERR("Missing event header field value\n"); return -1; } if( msg->to==NULL || msg->to->body.s==NULL) { LM_ERR("cannot parse TO header\n"); return -1; } if(msg->to->parsed != NULL) { pto = (struct to_body*)msg->to->parsed; LM_DBG("'To' header ALREADY PARSED:<%.*s>\n",pto->uri.len,pto->uri.s); } else { parse_to(msg->to->body.s,msg->to->body.s + msg->to->body.len + 1, &TO); if(TO.uri.len <= 0) { LM_ERR("'To' header NOT parsed\n"); goto error; } pto = &TO; } dialog.watcher_uri= &pto->uri; uri=(char*)pkg_malloc(sizeof(char)*( pto->uri.len+1)); if(uri== NULL) { LM_ERR("no more memory\n"); goto error; } memcpy(uri, pto->uri.s, pto->uri.len); uri[pto->uri.len]= '\0'; to_uri.s= duri_sip_xmpp(uri); if(to_uri.s== NULL) { LM_ERR("while decoding sip uri in xmpp\n"); pkg_free(uri); goto error; } to_uri.len= strlen(to_uri.s); pkg_free(uri); if (pto->tag_value.s==NULL || pto->tag_value.len==0 ) { LM_ERR("to tag value not parsed\n"); goto error; } id= pto->tag_value; dialog.from_tag= id; if( msg->callid==NULL || msg->callid->body.s==NULL) { LM_ERR("cannot parse callid header\n"); goto error; } dialog.call_id = msg->callid->body; if (!msg->from || !msg->from->body.s) { LM_ERR("ERROR cannot find 'from' header!\n"); goto error; } if (msg->from->parsed == NULL) { LM_ERR("'From' header not parsed\n"); /* parsing from header */ if ( parse_from_header( msg )<0 ) { LM_ERR("ERROR cannot parse From header\n"); goto error; } } pfrom = (struct to_body*)msg->from->parsed; dialog.pres_uri= &pfrom->uri; uri=(char*)pkg_malloc(sizeof(char)*( pfrom->uri.len+1)); if(uri== NULL) { LM_ERR("no more memory\n"); goto error; } memcpy(uri, pfrom->uri.s, pfrom->uri.len); uri[pfrom->uri.len]= '\0'; from_uri.s= euri_sip_xmpp(uri); if(from_uri.s== NULL) { LM_ERR("while encoding sip uri in xmpp\n"); pkg_free(uri); goto error; } from_uri.len= strlen(from_uri.s); pkg_free(uri); if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0) { LM_ERR("no from tag value present\n"); goto error; } dialog.to_tag= pfrom->tag_value; dialog.flag|= XMPP_SUBSCRIBE; if(msg->event->body.len== 8 && (strncmp(msg->event->body.s,"presence",8 )==0)) event_flag|= PRESENCE_EVENT; else if(msg->event->body.len== 14 && (strncmp(msg->event->body.s,"presence.winfo",14 )==0)) event_flag|= PWINFO_EVENT; else { LM_ERR("wrong event\n"); goto error; } dialog.event= event_flag; if(pua_is_dialog(&dialog)< 0) // verify if within a stored dialog { LM_ERR("Notify in a non existing dialog\n"); goto error; } /*constructing the xml body*/ if(get_content_length(msg) == 0 ) { body.s= NULL; body.len= 0; } else { body.s=get_body(msg); if (body.s== NULL) { LM_ERR("cannot extract body from msg\n"); goto error; } body.len = get_content_length( msg ); } /* treat the two cases: event= presence & event=presence.winfo */ if(event_flag & PRESENCE_EVENT) { LM_DBG("PRESENCE\n"); hdr = msg->headers; while (hdr!= NULL) { if(cmp_hdrname_strzn(&hdr->name, "Subscription-State", 18)==0) break; hdr = hdr->next; } if(hdr && strncmp(hdr->body.s,"terminated", 10)== 0) { /* chack if reason timeout => don't send notification */ if(strncmp(hdr->body.s+11,"reason=timeout", 14)== 0) { LM_DBG("Received Notification with state" "terminated; reason= timeout=> don't send notification\n"); return 1; } is_terminated= 1; } if(build_xmpp_content(&to_uri, &from_uri, &body, &id, is_terminated)< 0) { LM_ERR("in function build_xmpp_content\n"); goto error; } } else { if(event_flag & PWINFO_EVENT) { LM_DBG("PRESENCE.WINFO\n"); hdr = msg->headers; while (hdr!= NULL) { if(cmp_hdrname_strzn(&hdr->name, "Subscription-State", 18)==0) break; hdr = hdr->next; } if(hdr && strncmp(hdr->body.s,"terminated", 10)== 0) { LM_DBG("Notify for presence.winfo with" " Subscription-State terminated- should not translate\n"); goto error; } if(winfo2xmpp(&to_uri, &body, &id)< 0) { LM_ERR("while sending subscription\n"); goto error; } } else { LM_ERR("Missing or unsupported event header field value\n"); goto error; } } free_to_params(&TO); return 1; error: free_to_params(&TO); return 0; }