/** * init module function */ static int mod_init(void) { bind_pua_t bind_pua; evs_process_body_t* evp=0; bind_pua= (bind_pua_t)find_export("bind_pua", 1,0); if (!bind_pua) { LM_ERR("Can't bind pua\n"); return -1; } if (bind_pua(&pua) < 0) { LM_ERR("Can't bind pua\n"); return -1; } if(pua.send_publish == NULL) { LM_ERR("Could not import send_publish\n"); return -1; } pua_send_publish= pua.send_publish; if (nopublish_flag!= -1 && nopublish_flag > MAX_FLAG) { LM_ERR("invalid nopublish flag %d!!\n", nopublish_flag); return -1; } nopublish_flag = (nopublish_flag!=-1)?(1<<nopublish_flag):0; if(!osips_ps) evp = dialoginfo_process_body; /* add event in pua module */ if(pua.add_event(DIALOG_EVENT, "dialog", "application/dialog-info+xml", evp) < 0) { LM_ERR("failed to add 'dialog' event to pua module\n"); return -1; } /* bind to the dialog API */ if (load_dlg_api(&dlg_api)!=0) { LM_ERR("failed to find dialog API - is dialog module loaded?\n"); return -1; } /* register dialog loading callback */ if (dlg_api.register_dlgcb(NULL, DLGCB_LOADED, __dialog_loaded, NULL, NULL) != 0) { LM_CRIT("cannot register callback for dialogs loaded from the database\n"); } if(presence_server.s) presence_server.len = strlen(presence_server.s); if(caller_spec_param.s) { caller_spec_param.len = strlen(caller_spec_param.s); if(pv_parse_spec(&caller_spec_param, &caller_spec)==NULL) { LM_ERR("failed to parse caller spec\n"); return -2; } switch(caller_spec.type) { case PVT_NONE: case PVT_EMPTY: case PVT_NULL: case PVT_MARKER: case PVT_COLOR: LM_ERR("invalid caller spec\n"); return -3; default: ; } } if(callee_spec_param.s) { callee_spec_param.len = strlen(callee_spec_param.s); if(pv_parse_spec(&callee_spec_param, &callee_spec)==NULL) { LM_ERR("failed to parse callee spec\n"); return -2; } switch(callee_spec.type) { case PVT_NONE: case PVT_EMPTY: case PVT_NULL: case PVT_MARKER: case PVT_COLOR: LM_ERR("invalid callee spec\n"); return -3; default: ; } } return 0; }
/** Module init function */ static int mod_init(void) { unsigned int i; LM_DBG("start\n"); init_db_url( db_url , 0 /*cannot be null*/); /* load tm api */ if(load_tm_api(&tmb)==-1) { LM_ERR("can't load tm functions\n"); return -1; } /* load pua api */ if(load_pua_api(&pua_api) < 0) { LM_ERR("Can't bind pua\n"); return -1; } /* add event in pua module */ if(pua_api.add_event(CALLINFO_EVENT, "call-info", NULL, 0) < 0) { LM_ERR("failed to add 'call-info' event to pua module\n"); return -1; } /* load b2b_logic api */ if(load_b2b_logic_api(&b2bl_api)< 0) { LM_ERR("Failed to load b2b_logic api\n"); return -1; } if(b2b_sca_hsize<1 || b2b_sca_hsize>20) { LM_ERR("Wrong hash size. Needs to be greater than 1" " and smaller than 20. Be aware that you should set the log 2" " value of the real size\n"); return -1; } b2b_sca_hsize = 1<<b2b_sca_hsize; if(presence_server.s) presence_server.len = strlen(presence_server.s); LM_DBG("fix db columns\n"); sca_table_name.len = strlen(sca_table_name.s); shared_line_column.len = strlen(shared_line_column.s); watchers_column.len = strlen(watchers_column.s); for (i=0; i<MAX_APPEARANCE_INDEX; i++) { app_shared_entity_column[i].len = strlen(app_shared_entity_column[i].s); app_call_state_column[i].len = strlen(app_call_state_column[i].s); app_call_info_uri_column[i].len = strlen(app_call_info_uri_column[i].s); app_call_info_appearance_uri_column[i].len = strlen(app_call_info_appearance_uri_column[i].s); app_b2bl_key_column[i].len = strlen(app_b2bl_key_column[i].s); } LM_DBG("fix AVP spec\n"); /* fix AVP spec */ if(watchers_avp_spec.s) { watchers_avp_spec.len = strlen(watchers_avp_spec.s); if(pv_parse_spec(&watchers_avp_spec, &watchers_spec)==NULL || watchers_spec.type != PVT_AVP) { LM_ERR("failed to parse watchers spec [%.*s]\n", watchers_avp_spec.len, watchers_avp_spec.s); return E_CFG; } if(pv_get_avp_name(NULL, &(watchers_spec.pvp), &(watchers_avp_name), &(watchers_avp_type) )!=0) { LM_ERR("[%.*s]- invalid AVP definition for watchers_avp_spec\n", watchers_avp_spec.len, watchers_avp_spec.s); } } else { watchers_avp_name = -1; watchers_avp_type = 0; } if(shared_line_spec_param.s) { shared_line_spec_param.len = strlen(shared_line_spec_param.s); if(pv_parse_spec(&shared_line_spec_param, &shared_line_spec)==NULL) { LM_ERR("failed to parse shared_line spec\n"); return E_CFG; } switch(shared_line_spec.type) { case PVT_NONE: case PVT_EMPTY: case PVT_NULL: case PVT_MARKER: case PVT_COLOR: LM_ERR("invalid shared_line spec\n"); return -3; default: ; } } if(appearance_name_addr_spec_param.s) { appearance_name_addr_spec_param.len = strlen(appearance_name_addr_spec_param.s); if(pv_parse_spec(&appearance_name_addr_spec_param, &appearance_name_addr_spec)==NULL) { LM_ERR("failed to parse appearance_name_addr spec\n"); return E_CFG; } switch(appearance_name_addr_spec.type) { case PVT_NONE: case PVT_EMPTY: case PVT_NULL: case PVT_MARKER: case PVT_COLOR: LM_ERR("invalid appearance_name_addr spec\n"); return -3; default: ; } } if(init_b2b_sca_htable() < 0) { LM_ERR("Failed to initialize b2b_sca hash table\n"); return -1; } if (sca_db_mode==DB_MODE_NONE) { db_url.s = NULL; db_url.len = 0; } else { if (sca_db_mode!=DB_MODE_REALTIME) { LM_ERR("unsupported db_mode %d\n", sca_db_mode); return -1; } if ( !db_url.s || db_url.len==0 ) { LM_ERR("db_url not configured for db_mode %d\n", sca_db_mode); return -1; } if (init_sca_db(&db_url, b2b_sca_hsize)!=0) { LM_ERR("failed to initialize the DB support\n"); return -1; } } return 0; }
/** * init module function */ static int mod_init(void) { load_tm_f load_tm; bind_pua_t bind_pua; bind_xmpp_t bind_xmpp; bind_libxml_t bind_libxml; libxml_api_t libxml_api; /* check if compulsory parameter server_address is set */ if(server_address.s== NULL) { LM_ERR("compulsory 'server_address' parameter not set!"); return -1; } server_address.len= strlen(server_address.s); if(presence_server.s) presence_server.len = strlen(presence_server.s); /* import the TM auto-loading function */ if((load_tm=(load_tm_f)find_export("load_tm", 0, 0))==NULL) { LM_ERR("can't import load_tm\n"); return -1; } /* let the auto-loading function load all TM stuff */ if(load_tm(&tmb)==-1) { LM_ERR("can't load tm functions\n"); return -1; } /* bind libxml wrapper functions */ if((bind_libxml= (bind_libxml_t)find_export("bind_libxml_api", 1, 0))== NULL) { LM_ERR("can't import bind_libxml_api\n"); return -1; } if(bind_libxml(&libxml_api)< 0) { LM_ERR("can not bind libxml api\n"); return -1; } XMLNodeGetAttrContentByName= libxml_api.xmlNodeGetAttrContentByName; XMLDocGetNodeByName= libxml_api.xmlDocGetNodeByName; XMLNodeGetNodeByName= libxml_api.xmlNodeGetNodeByName; XMLNodeGetNodeContentByName= libxml_api.xmlNodeGetNodeContentByName; if(XMLNodeGetAttrContentByName== NULL || XMLDocGetNodeByName== NULL || XMLNodeGetNodeByName== NULL || XMLNodeGetNodeContentByName== NULL) { LM_ERR("libxml wrapper functions could not be bound\n"); return -1; } /* bind xmpp */ bind_xmpp= (bind_xmpp_t)find_export("bind_xmpp", 0,0); if (!bind_xmpp) { LM_ERR("Can't bind xmpp\n"); return -1; } if(bind_xmpp(&xmpp_api)< 0) { LM_ERR("Can't bind xmpp\n"); return -1; } if(xmpp_api.xsubscribe== NULL) { LM_ERR("Could not import xsubscribe from xmpp\n"); return -1; } xmpp_subscribe= xmpp_api.xsubscribe; if(xmpp_api.xnotify== NULL) { LM_ERR("Could not import xnotify from xmpp\n"); return -1; } xmpp_notify= xmpp_api.xnotify; if(xmpp_api.xpacket== NULL) { LM_ERR("Could not import xnotify from xmpp\n"); return -1; } xmpp_packet= xmpp_api.xpacket; xmpp_uri_xmpp2sip = xmpp_api.uri_xmpp2sip; xmpp_uri_sip2xmpp = xmpp_api.uri_sip2xmpp; if(xmpp_api.register_callback== NULL) { LM_ERR("Could not import register_callback" " to xmpp\n"); return -1; } if(xmpp_api.register_callback(XMPP_RCV_PRESENCE, pres_Xmpp2Sip, NULL)< 0) { LM_ERR("ERROR while registering callback" " to xmpp\n"); return -1; } /* bind pua */ bind_pua= (bind_pua_t)find_export("bind_pua", 1,0); if (!bind_pua) { LM_ERR("Can't bind pua\n"); return -1; } if (bind_pua(&pua) < 0) { LM_ERR("Can't bind pua\n"); return -1; } if(pua.send_publish == NULL) { LM_ERR("Could not import send_publish\n"); return -1; } pua_send_publish= pua.send_publish; if(pua.send_subscribe == NULL) { LM_ERR("Could not import send_subscribe\n"); return -1; } pua_send_subscribe= pua.send_subscribe; if(pua.is_dialog == NULL) { LM_ERR("Could not import send_subscribe\n"); return -1; } pua_is_dialog= pua.is_dialog; if(pua.register_puacb(XMPP_INITIAL_SUBS, Sipreply2Xmpp, NULL)< 0) { LM_ERR("Could not register callback\n"); return -1; } return 0; }
/** * init module function */ static int mod_init(void) { bind_pua_t bind_pua; evs_process_body_t* evp=0; bind_pua= (bind_pua_t)find_export("bind_pua", 1,0); if (!bind_pua) { LM_ERR("Can't bind pua\n"); return -1; } if (bind_pua(&pua) < 0) { LM_ERR("Can't bind pua\n"); return -1; } if(pua.send_publish == NULL) { LM_ERR("Could not import send_publish\n"); return -1; } pua_send_publish= pua.send_publish; if(!osips_ps) evp = dialoginfo_process_body; /* add event in pua module */ if(pua.add_event(DIALOG_EVENT, "dialog", "application/dialog-info+xml", evp) < 0) { LM_ERR("failed to add 'dialog' event to pua module\n"); return -1; } /* bind to the dialog API */ if (load_dlg_api(&dlg_api)!=0) { LM_ERR("failed to find dialog API - is dialog module loaded?\n"); return -1; } if(presence_server.s) presence_server.len = strlen(presence_server.s); if(caller_spec_param.s) { caller_spec_param.len = strlen(caller_spec_param.s); if(pv_parse_spec(&caller_spec_param, &caller_spec)==NULL) { LM_ERR("failed to parse caller spec\n"); return -2; } switch(caller_spec.type) { case PVT_NONE: case PVT_EMPTY: case PVT_NULL: case PVT_MARKER: case PVT_COLOR: LM_ERR("invalid caller spec\n"); return -3; default: ; } } if(callee_spec_param.s) { callee_spec_param.len = strlen(callee_spec_param.s); if(pv_parse_spec(&callee_spec_param, &callee_spec)==NULL) { LM_ERR("failed to parse callee spec\n"); return -2; } switch(callee_spec.type) { case PVT_NONE: case PVT_EMPTY: case PVT_NULL: case PVT_MARKER: case PVT_COLOR: LM_ERR("invalid callee spec\n"); return -3; default: ; } } return 0; }
static void pua_rpc_publish(rpc_t* rpc, void* c) { str pres_uri, expires, event, content_type, id, etag, outbound_proxy, extra_headers, body; rpc_delayed_ctx_t* dctx; int exp, sign, ret, err_ret, sip_error; char err_buf[MAX_REASON_LEN]; struct sip_uri uri; publ_info_t publ; body.s = 0; body.len = 0; dctx = 0; LM_DBG("rpc publishing ...\n"); if ((rpc->capabilities == 0) || !(rpc->capabilities(c) & RPC_DELAYED_REPLY)) { rpc->fault(c, 600, "Reply wait/async mode not supported" " by this rpc transport"); return; } ret = rpc->scan(c, "SSSSSSSS*S", &pres_uri, &expires, &event, &content_type, &id, &etag, &outbound_proxy, &extra_headers, &body); if (ret < 8) { rpc->fault(c, 400, "Too few or wrong type of parameters (%d)", ret); return; } if (parse_uri(pres_uri.s, pres_uri.len, &uri) <0) { LM_ERR("bad resentity uri\n"); rpc->fault(c, 400, "Invalid presentity uri '%s'", pres_uri.s); return; } LM_DBG("presentity uri '%.*s'\n", pres_uri.len, pres_uri.s); if (expires.s[0]== '-') { sign= -1; expires.s++; expires.len--; } else { sign = 1; } if (str2int(&expires, (unsigned int*)&exp) < 0) { LM_ERR("invalid expires parameter\n" ); rpc->fault(c, 400, "Invalid expires value '%s'", expires.s); return; } exp = exp * sign; LM_DBG("expires '%d'\n", exp); LM_DBG("event '%.*s'\n", event.len, event.s); LM_DBG("content type '%.*s'\n", content_type.len, content_type.s); LM_DBG("id '%.*s'\n", id.len, id.s); LM_DBG("ETag '%.*s'\n", etag.len, etag.s); LM_DBG("outbound_proxy '%.*s'\n", outbound_proxy.len, outbound_proxy.s); LM_DBG("extra headers '%.*s'\n", extra_headers.len, extra_headers.s); if (body.len > 0) LM_DBG("body '%.*s'\n", body.len, body.s); if ((body.s == 0) && (content_type.len != 1 || content_type.s[0] != '.')) { LM_ERR("body is missing, but content type is not .\n"); rpc->fault(c, 400, "Body is missing"); return; } memset(&publ, 0, sizeof(publ_info_t)); publ.pres_uri= &pres_uri; publ.expires= exp; publ.event= get_event_flag(&event); if (publ.event < 0) { LM_ERR("unknown event '%.*s'\n", event.len, event.s); rpc->fault(c, 400, "Unknown event"); return; } if (content_type.len != 1) { publ.content_type= content_type; } if (!((id.len == 1) && (id.s[0]== '.'))) { publ.id= id; } if (!((etag.len== 1) && (etag.s[0]== '.'))) { publ.etag= &etag; } if (!((outbound_proxy.len == 1) && (outbound_proxy.s[0] == '.'))) { publ.outbound_proxy = &outbound_proxy; } if (!((extra_headers.len == 1) && (extra_headers.s[0] == '.'))) { publ.extra_headers = &extra_headers; } if (body.s != 0) { publ.body= &body; } dctx = rpc->delayed_ctx_new(c); if (dctx == 0) { LM_ERR("internal error: failed to create context\n"); rpc->fault(c, 500, "Internal error: failed to create context"); return; } publ.cb_param = dctx; publ.source_flag = MI_ASYN_PUBLISH; ret = pua_rpc_api.send_publish(&publ); LM_DBG("pua send_publish returned %d\n", ret); if (dctx->reply_ctx != 0) { /* callback was not executed or its execution failed */ rpc = &dctx->rpc; c = dctx->reply_ctx; } else { return; } if (ret < 0) { LM_ERR("pua send_publish failed\n"); err_ret = err2reason_phrase(ret, &sip_error, err_buf, sizeof(err_buf), "RPC/PUBLISH") ; if (err_ret > 0 ) { rpc->fault(c, sip_error, "%s", err_buf); } else { rpc->fault(c, 500, "RPC/PUBLISH error"); } rpc->delayed_ctx_close(dctx); } if (ret == 418) { rpc->fault(c, 500, "Wrong ETag"); rpc->delayed_ctx_close(dctx); } return; }
int send_partial_publish(ppublic_t *impu, struct pcontact *c, int type) { publ_info_t publ; str content_type; int id_buf_len; char id_buf[512]; str p_asserted_identity_header; content_type.s = "application/reginfo+xml"; content_type.len = 23; int len = strlen(P_ASSERTED_IDENTITY_HDR_PREFIX) + pcscf_uri.len + 1 + CRLF_LEN; p_asserted_identity_header.s = (char *)pkg_malloc( len ); if ( p_asserted_identity_header.s == NULL ) { LM_ERR( "insert_asserted_identity: pkg_malloc %d bytes failed", len ); goto error; } memcpy(p_asserted_identity_header.s, P_ASSERTED_IDENTITY_HDR_PREFIX, strlen(P_ASSERTED_IDENTITY_HDR_PREFIX)); p_asserted_identity_header.len = strlen(P_ASSERTED_IDENTITY_HDR_PREFIX); memcpy(p_asserted_identity_header.s + p_asserted_identity_header.len, pcscf_uri.s, pcscf_uri.len); p_asserted_identity_header.len += pcscf_uri.len; *(p_asserted_identity_header.s + p_asserted_identity_header.len) = '>'; p_asserted_identity_header.len ++; memcpy( p_asserted_identity_header.s + p_asserted_identity_header.len, CRLF, CRLF_LEN ); p_asserted_identity_header.len += CRLF_LEN; LM_DBG("p_asserted_identity_header: [%.*s]", p_asserted_identity_header.len, p_asserted_identity_header.s); LM_DBG("Sending publish\n"); str *body = build_reginfo_partial(impu, c, type); if (body == NULL || body->s == NULL) { LM_ERR("Error on creating XML-Body for publish\n"); goto error; } LM_DBG("XML-Body:\n%.*s\n", body->len, body->s); memset(&publ, 0, sizeof(publ_info_t)); publ.pres_uri = &impu->public_identity; publ.body = body; id_buf_len = snprintf(id_buf, sizeof(id_buf), "IMSPCSCF_PUBLISH.%.*s", c->aor.len, c->aor.s); publ.id.s = id_buf; publ.id.len = id_buf_len; publ.content_type = content_type; publ.expires = 3600; /* make UPDATE_TYPE, as if this "publish dialog" is not found by pua it will fallback to INSERT_TYPE anyway */ publ.flag |= UPDATE_TYPE; publ.source_flag |= REGINFO_PUBLISH; publ.event |= REGINFO_EVENT; publ.extra_headers = &p_asserted_identity_header; if (pua.send_publish(&publ) < 0) { LM_ERR("Error while sending publish\n"); } if (p_asserted_identity_header.s) { pkg_free(p_asserted_identity_header.s); } return 1; error: if (p_asserted_identity_header.s) { pkg_free(p_asserted_identity_header.s); } if (body) { if (body->s) xmlFree(body->s); pkg_free(body); } return -1; }