void add_dlg_data_to_contact(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params) { struct impu_data *impu_data; impurecord_t* implicit_impurecord = 0; struct ucontact* ucontact; str callid = {0, 0}; str path = {0, 0}; LM_DBG("dialog [%p] confirmed, lets add dlg data to contact\n", dlg); if(_params && _params->param){ impu_data = (struct impu_data*)*_params->param; if (!impu_data) { LM_ERR("IMPU data object is NULL...... aborting\n"); return; } LM_DBG("IMPU data is present, contact: <%.*s> identity <%.*s>", impu_data->contact.len, impu_data->contact.s, impu_data->identity.len, impu_data->identity.s); LM_DBG("IMPU data domain <%.*s>", impu_data->d->name->len, impu_data->d->name->s); ul.lock_udomain(impu_data->d, &impu_data->identity); if (ul.get_impurecord(impu_data->d, &impu_data->identity, &implicit_impurecord) != 0) { LM_DBG("usrloc does not have imprecord for implicity IMPU, ignore\n"); }else { if (ul.get_ucontact(implicit_impurecord, &impu_data->contact, &callid, &path, 0/*cseq*/, &ucontact) != 0) { //contact does not exist LM_DBG("This contact: <%.*s> is not in usrloc, ignore - NOTE: You need S-CSCF usrloc set to match_mode CONTACT_PORT_IP_ONLY\n", impu_data->contact.len, impu_data->contact.s); } else {//contact exists so add dialog data to it ul.add_dialog_data_to_contact(ucontact, dlg->h_entry, dlg->h_id); } } ul.unlock_udomain(impu_data->d, &impu_data->identity); } }
void remove_dlg_data_from_contact(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params) { struct impu_data *impu_data; impurecord_t* implicit_impurecord = 0; struct ucontact* ucontact; str callid = {0, 0}; str path = {0, 0}; udomain_t* domain_t; LM_DBG("dialog [%p] terminated, lets remove dlg data from contact\n", dlg); if (ul.register_udomain(domain, &domain_t) < 0) { LM_ERR("Unable to register usrloc domain....aborting\n"); return; } if(_params && _params->param){ impu_data = (struct impu_data*)*_params->param; if (!impu_data) { LM_ERR("IMPU data object is NULL...... aborting\n"); return; } LM_DBG("IMPU data is present, contact: <%.*s> identity <%.*s>", impu_data->contact.len, impu_data->contact.s, impu_data->identity.len, impu_data->identity.s); LM_DBG("IMPU data domain <%.*s>", domain_t->name->len, domain_t->name->s); ul.lock_udomain(domain_t, &impu_data->identity); if (ul.get_impurecord(domain_t, &impu_data->identity, &implicit_impurecord) != 0) { LM_DBG("usrloc does not have imprecord for implicity IMPU, ignore\n"); }else { if (ul.get_ucontact(&impu_data->contact, &callid, &path, 0/*cseq*/, &ucontact) != 0) { //contact does not exist LM_DBG("This contact: <%.*s> is not in usrloc, ignore - NOTE: You need S-CSCF usrloc set to match_mode CONTACT_PORT_IP_ONLY\n", impu_data->contact.len, impu_data->contact.s); } else {//contact exists so add dialog data to it ul.remove_dialog_data_from_contact(ucontact, dlg->h_entry, dlg->h_id); ul.release_ucontact(ucontact); } } ul.unlock_udomain(domain_t, &impu_data->identity); free_impu_data(impu_data); } //we referenced the dialog when we registered for callbacks on it... dlgb.release_dlg(dlg); }
AAAMessage* cxdx_process_rtr(AAAMessage *rtr) { LM_DBG("Processing RTR"); AAAMessage *rta_msg; AAA_AVP* avp; str public_id; impurecord_t* r; int res = 0; udomain_t* udomain; impu_contact_t *impucontact; rta_msg = cdpb.AAACreateResponse(rtr);//session ID? if (!rta_msg) return 0; avp = cxdx_get_next_public_identity(rtr,0,AVP_IMS_Public_Identity,IMS_vendor_id_3GPP,__FUNCTION__); if(avp==0){ LM_WARN("RTR received with only IMPI (username AVP) - currently S-CSCF does not support this kind of RTR\n"); return 0; //TODO add support for receiving RTR with IMPI //get all impus related to this impu //get all contacts related to each impu //set the contact expire for each contact to now }else{ public_id=avp->data; LM_DBG("RTR received with IMPU [%.*s] in public identity AVP - this is supported\n", public_id.len, public_id.s); //TODO this should be a configurable module param if (ul.register_udomain(domain, &udomain) < 0) { LM_ERR("Unable to register usrloc domain....aborting\n"); return 0; } ul.lock_udomain(udomain, &public_id); res = ul.get_impurecord(udomain, &public_id, &r); if (res != 0) { LM_WARN("Strange, '%.*s' Not found in usrloc\n", public_id.len, public_id.s); ul.unlock_udomain(udomain, &public_id); //no point in continuing return 0; } impucontact = r->linked_contacts.head; while (impucontact) { LM_DBG("Deleting contact with AOR [%.*s]\n", impucontact->contact->aor.len, impucontact->contact->aor.s); ul.lock_contact_slot_i(impucontact->contact->sl); impucontact->contact->state = CONTACT_DELETE_PENDING; if (r->shead) { //send NOTIFY to all subscribers of this IMPU. notify_subscribers(r, 0, 0); } impucontact->contact->state = CONTACT_DELETED; ul.unlock_contact_slot_i(impucontact->contact->sl); impucontact = impucontact->next; } ul.unlock_udomain(udomain, &public_id); while(cdpb.AAAGetNextAVP(avp) && (avp=cxdx_get_next_public_identity(rtr,cdpb.AAAGetNextAVP(avp),AVP_IMS_Public_Identity,IMS_vendor_id_3GPP,__FUNCTION__))!=0){ public_id=avp->data; LM_DBG("RTR also has public id [%.*s]\n", public_id.len, public_id.s); ul.lock_udomain(udomain, &public_id); res = ul.get_impurecord(udomain, &public_id, &r); if (res != 0) { LM_WARN("Strange, '%.*s' Not found in usrloc\n", public_id.len, public_id.s); ul.unlock_udomain(udomain, &public_id); //no point in continuing return 0; } impucontact = r->linked_contacts.head; while (impucontact) { LM_DBG("Deleting contact with AOR [%.*s]\n", impucontact->contact->aor.len, impucontact->contact->aor.s); ul.lock_contact_slot_i(impucontact->contact->sl); impucontact->contact->state = CONTACT_DELETE_PENDING; if (r->shead) { //send NOTIFY to all subscribers of this IMPU. notify_subscribers(r, 0, 0); } impucontact->contact->state = CONTACT_DELETED; ul.unlock_contact_slot_i(impucontact->contact->sl); impucontact = impucontact->next; } ul.unlock_udomain(udomain, &public_id); } } cxdx_add_vendor_specific_appid(rta_msg,IMS_vendor_id_3GPP,IMS_Cx,0 /*IMS_Cx*/); cxdx_add_auth_session_state(rta_msg,1); /* send an RTA back to the HSS */ cxdx_add_result_code(rta_msg,DIAMETER_SUCCESS); return rta_msg; }
/** * Handle third party registration * @param msg - the SIP REGISTER message * @param m - the isc_match that matched with info about where to forward it * @param mark - the isc_mark that should be used to mark the message * @returns #ISC_RETURN_TRUE if allowed, #ISC_RETURN_FALSE if not */ int isc_third_party_reg(struct sip_msg *msg, isc_match *m, isc_mark *mark, udomain_t* d) { r_third_party_registration r; str path, path_received; int expires = 0; str req_uri = {0, 0}; str to = {0, 0}; str pvni = {0, 0}; str pani = {0, 0}; str cv = {0, 0}; str s = {0, 0}; impurecord_t *p; struct hdr_field *hdr; LM_DBG("isc_third_party_reg: Enter\n"); /* Set Request Uri to IFC matching server name */ req_uri.len = m->server_name.len; req_uri.s = m->server_name.s; /* Get To header*/ to = cscf_get_public_identity(msg); if (cscf_get_originating_user(msg, &s)) { isc_ulb.lock_udomain(d, &s); if ( isc_ulb.get_impurecord(d,&s,&p) != 0) { isc_ulb.unlock_udomain(d, &s); LM_ERR("Failed to get IMPU domain from usrloc\n"); goto no_pai; } if ( build_p_associated_uri(p->s) != 0) { isc_ulb.unlock_udomain(d, &s); LM_ERR("Failed to build P-Associated URI for 3rd party reg\n"); goto no_pai; } isc_ulb.unlock_udomain(d, &s); } /*TODO - check if the min/max expires is in the acceptable limits * this does not work correctly if the user has multiple contacts * and register/deregisters them individually!!! */ no_pai: expires = cscf_get_max_expires(msg, 0); /* Get P-Visited-Network-Id header */ pvni = cscf_get_visited_network_id(msg, &hdr); /* Get P-Access-Network-Info header */ pani = cscf_get_access_network_info(msg, &hdr); if (build_path_vector(msg, &path, &path_received) < 0) { LM_ERR("Failed to parse PATH header for third-party reg\n"); return ISC_RETURN_FALSE; } LM_DBG("PATH header in REGISTER is [%.*s]\n", path.len, path.s); /* Get P-Charging-Vector header */ /* Just forward the charging header received from P-CSCF */ /* Todo: implement also according to TS 24.229, chap 5.4.1.7 */ cv = cscf_get_charging_vector(msg, &hdr); if (req_uri.s) { memset(&r, 0, sizeof (r_third_party_registration)); r.req_uri = req_uri; r.to = to; r.from = isc_my_uri_sip; r.pvni = pvni; r.pani = pani; r.cv = cv; if (m->service_info.s && m->service_info.len) { r.body.content_type = CT_SERVICE_INFO; r.body.content = m->service_info; } else if (m->include_register_request) { r.body.content_type = CT_REGISTER_REQ; r.body.content.s = msg->first_line.u.request.method.s; r.body.content.len = msg->len; } else if (m->include_register_response) { struct bookmark dummy_bm; r.body.content_type = CT_REGISTER_RESP; r.body.content.s = build_res_buf_from_sip_req(200, ®_resp_200OK, 0, msg, (unsigned int*)&r.body.content.len, &dummy_bm); if (!r.body.content.s) { LM_DBG("response building failed for body of third party register request"); r.body.content_type = CT_NONE; } } else { r.body.content_type = CT_NONE; } r.path = path; if (expires <= 0) r_send_third_party_reg(&r, 0); else r_send_third_party_reg(&r, expires + isc_expires_grace); return ISC_RETURN_TRUE; } else { return ISC_RETURN_FALSE; } }