void session_widget::check_mail() try { INVARIANT(_messages); INVARIANT(_session); INVARIANT(_session_service); INVARIANT(_session_service->user_service()); INVARIANT(_session->mail()); m::message m; while(_session->mail()->pop_inbox(m)) { //for now show encoded message //TODO: use factory class to create gui from messages if(m.meta.type == ms::NEW_APP) { _messages->add_new_app(m); } else if(m.meta.type == s::event::SESSION_SYNCED) { update_contacts(); } else if(m.meta.type == s::event::CONTACT_REMOVED) { update_contacts(); s::event::contact_removed r; s::event::convert(m, r); auto c = _session_service->user_service()->by_id(r.contact_id); if(!c) continue; add(contact_alert(c, "quit session")); } else if(m.meta.type == us::event::CONTACT_CONNECTED) { update_contacts(); } else if(m.meta.type == us::event::CONTACT_DISCONNECTED) { update_contacts(); } else { std::stringstream s; s << m; _messages->add(new unknown_message{s.str()}); } } } catch(std::exception& e) { std::cerr << "session: error in check_mail. " << e.what() << std::endl; } catch(...) { std::cerr << "session: unexpected error in check_mail." << std::endl; }
/*! \brief * This function will process request that * contained some contact header fields */ static inline int add_contacts(struct sip_msg* _m, contact_t* _c, udomain_t* _d, struct save_ctx *_sctx) { int res; urecord_t* r; ul.lock_udomain(_d, &_sctx->aor); res = ul.get_urecord(_d, &_sctx->aor, &r); if (res < 0) { rerrno = R_UL_GET_R; LM_ERR("failed to retrieve record from usrloc\n"); ul.unlock_udomain(_d, &_sctx->aor); return -2; } if (res == 0) { /* Contacts found */ if (update_contacts(_m, r, _c, _sctx) < 0) { build_contact(r->contacts); ul.release_urecord(r); ul.unlock_udomain(_d, &_sctx->aor); return -3; } build_contact(r->contacts); ul.release_urecord(r); } else { if (insert_contacts(_m, _c, _d, &_sctx->aor, _sctx) < 0) { ul.unlock_udomain(_d, &_sctx->aor); return -4; } } ul.unlock_udomain(_d, &_sctx->aor); return 0; }
void contact_list_dialog::update() { size_t contacts = _service->user().contacts().size(); if(contacts == _prev_contacts) { for(auto ui : _ui) { CHECK(ui); //don't update action here because we want to be able to //delete contacts even when they are offline ui->update(false); } return; } update_contacts(); _prev_contacts = contacts; }
/*! \brief * This function will process request that * contained some contact header fields */ static inline int add_contacts(struct sip_msg* _m, udomain_t* _d, str* _a, int _mode, int _use_regid) { int res; int ret; urecord_t* r; sip_uri_t *u; u = parse_to_uri(_m); if(u==NULL) return -2; ret = 0; ul.lock_udomain(_d, _a); res = ul.get_urecord(_d, _a, &r); if (res < 0) { rerrno = R_UL_GET_R; LM_ERR("failed to retrieve record from usrloc\n"); ul.unlock_udomain(_d, _a); return -2; } if (res == 0) { /* Contacts found */ if ((ret=update_contacts(_m, r, _mode, _use_regid)) < 0) { build_contact(_m, r->contacts, &u->host); ul.release_urecord(r); ul.unlock_udomain(_d, _a); return -3; } build_contact(_m, r->contacts, &u->host); ul.release_urecord(r); } else { if (insert_contacts(_m, _d, _a, _use_regid) < 0) { ul.unlock_udomain(_d, _a); return -4; } ret = 1; } ul.unlock_udomain(_d, _a); return ret; }
void contact_list_dialog::init_contacts_tab(QWidget* tab, QGridLayout* layout) { REQUIRE(tab); REQUIRE(layout); INVARIANT(_service); //create contact list _list = new list; layout->addWidget(_list, 0, 0, 2, 3); //create add button auto add_new = new QPushButton; make_add_contact(*add_new); add_new->setToolTip(tr("add someone using their invite file")); layout->addWidget(add_new, 2, 0, 1, 3); connect(add_new, SIGNAL(clicked()), this, SLOT(new_contact())); update_contacts(); //setup updated timer auto *t = new QTimer(this); connect(t, SIGNAL(timeout()), this, SLOT(update())); t->start(TIMER_SLEEP); }
void async_cdp_callback(int is_timeout, void *param, AAAMessage *saa, long elapsed_msecs) { struct cell *t = 0; int rc = -1, experimental_rc = -1; int result = CSCF_RETURN_TRUE; saved_transaction_t* data = 0; struct sip_msg* req; str xml_data = {0, 0}, ccf1 = {0, 0}, ccf2 = {0, 0}, ecf1 = {0, 0}, ecf2 = {0, 0}; ims_subscription* s = 0; rerrno = R_FINE; if (!param) { LM_DBG("No transaction data this must have been called from usrloc cb impu deleted - just log result code and then exit"); cxdx_get_result_code(saa, &rc); cxdx_get_experimental_result_code(saa, &experimental_rc); if (saa) cdpb.AAAFreeMessage(&saa); if (!rc && !experimental_rc) { LM_ERR("bad SAA result code\n"); return; } switch (rc) { case -1: LM_DBG("Received Diameter error\n"); return; case AAA_UNABLE_TO_COMPLY: LM_DBG("Unable to comply\n"); return; case AAA_SUCCESS: LM_DBG("received AAA success\n"); return; default: LM_ERR("Unknown error\n"); return; } } else { LM_DBG("There is transaction data this must have been called from save or assign server unreg"); data = (saved_transaction_t*) param; if (tmb.t_lookup_ident(&t, data->tindex, data->tlabel) < 0) { LM_ERR("t_continue: transaction not found and t is now pointing to %p and will be set to NULL\n", t); t = NULL; rerrno = R_SAR_FAILED; goto error_no_send; } set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, &t->uri_avps_from); set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, &t->uri_avps_to); set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, &t->user_avps_from); set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, &t->user_avps_to); set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, &t->domain_avps_from); set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, &t->domain_avps_to); get_act_time(); req = get_request_from_tx(t); if (!req) { LM_ERR("Failed to get SIP Request from Transaction\n"); goto error_no_send; } if (is_timeout) { update_stat(stat_sar_timeouts, 1); LM_ERR("Transaction timeout - did not get SAA\n"); rerrno = R_SAR_FAILED; goto error; } if (!saa) { LM_ERR("Error sending message via CDP\n"); rerrno = R_SAR_FAILED; goto error; } update_stat(sar_replies_received, 1); update_stat(sar_replies_response_time, elapsed_msecs); /* check and see that all the required headers are available and can be parsed */ if (parse_message_for_register(req) < 0) { LM_ERR("Unable to parse register message correctly\n"); rerrno = R_SAR_FAILED; goto error; } cxdx_get_result_code(saa, &rc); cxdx_get_experimental_result_code(saa, &experimental_rc); cxdx_get_charging_info(saa, &ccf1, &ccf2, &ecf1, &ecf2); if (!rc && !experimental_rc) { LM_ERR("bad SAA result code\n"); rerrno = R_SAR_FAILED; goto error; } switch (rc) { case -1: LM_DBG("Received Diameter error\n"); rerrno = R_SAR_FAILED; goto error; case AAA_UNABLE_TO_COMPLY: LM_DBG("Unable to comply\n"); rerrno = R_SAR_FAILED; goto error; case AAA_SUCCESS: LM_DBG("received AAA success for SAR - SAA\n"); break; default: LM_ERR("Unknown error\n"); rerrno = R_SAR_FAILED; goto error; } //success //if this is from a save (not a server assign unreg) and expires is zero we don't update usrloc as this is a dereg and usrloc was updated previously if (data->sar_assignment_type != AVP_IMS_SAR_UNREGISTERED_USER && data->expires == 0) { LM_DBG("no need to update usrloc - already done for de-reg\n"); result = CSCF_RETURN_TRUE; goto success; } xml_data = cxdx_get_user_data(saa); /*If there is XML user data we must be able to parse it*/ if (xml_data.s && xml_data.len > 0) { LM_DBG("Parsing user data string from SAA\n"); s = parse_user_data(xml_data); if (!s) { LM_ERR("Unable to parse user data XML string\n"); rerrno = R_SAR_FAILED; goto error; } LM_DBG("Successfully parse user data XML setting ref to 1 (we are referencing it)\n"); s->ref_count = 1; //no need to lock as nobody else will be referencing this piece of memory just yet } else { if (data->require_user_data) { LM_ERR("We require User data for this assignment/register and none was supplied\n"); rerrno = R_SAR_FAILED; result = CSCF_RETURN_FALSE; goto done; } } if (data->sar_assignment_type == AVP_IMS_SAR_REGISTRATION || data->sar_assignment_type == AVP_IMS_SAR_RE_REGISTRATION) { if (s) { if (build_p_associated_uri(s) != 0) { LM_ERR("Unable to build p_associated_uri\n"); rerrno = R_SAR_FAILED; goto error; } } } if (s) { //here we update the contacts and also build the new contact header for the 200 OK reply if (update_contacts(req, data->domain, &data->public_identity, data->sar_assignment_type, &s, &ccf1, &ccf2, &ecf1, &ecf2, &data->contact_header) <= 0) { LM_ERR("Error processing REGISTER\n"); rerrno = R_SAR_FAILED; goto error; } } if (data->contact_header) { LM_DBG("Updated contacts: %.*s\n", data->contact_header->data_len, data->contact_header->buf); } else { LM_DBG("Updated unreg contact\n"); } } success: update_stat(accepted_registrations, 1); done: if (data->sar_assignment_type != AVP_IMS_SAR_UNREGISTERED_USER) reg_send_reply_transactional(req, data->contact_header, t); LM_DBG("DBG:SAR Async CDP callback: ... Done resuming transaction\n"); create_return_code(result); //release our reference on subscription (s) if (s) ul.unref_subscription(s); //free memory if (saa) cdpb.AAAFreeMessage(&saa); if (t) { // del_nonshm_lump_rpl(&req->reply_lump); tmb.unref_cell(t); } //free path vector pkg memory // reset_path_vector(req); tmb.t_continue(data->tindex, data->tlabel, data->act); free_saved_transaction_data(data); return; error: create_return_code(-2); if (data->sar_assignment_type != AVP_IMS_SAR_UNREGISTERED_USER) reg_send_reply_transactional(req, data->contact_header, t); error_no_send: //if we don't have the transaction then we can't send a transaction response update_stat(rejected_registrations, 1); //free memory if (saa) cdpb.AAAFreeMessage(&saa); if (t) { // del_nonshm_lump_rpl(&req->reply_lump); tmb.unref_cell(t); } tmb.t_continue(data->tindex, data->tlabel, data->act); free_saved_transaction_data(data); return; }
/** * Save the contacts and their associated public ids. * @param rpl - the SIP Register 200 OK response that contains the Expire and Contact and P-associated-uri headers * @param _d - domain * @param _cflags - flags * @returns #CSCF_RETURN_TRUE if OK, #CSCF_RETURN_ERROR on error */ int save(struct sip_msg* _m, udomain_t* _d, int _cflags) { struct sip_msg* req; int expires_hdr = 0; contact_body_t* cb = 0; str *public_ids=0; int num_public_ids = 0; str *service_routes=0; int num_service_routes = 0; pv_elem_t *presentity_uri_pv; //get request from reply req = get_request_from_reply(_m); if (!req) { LM_ERR("Unable to get request from reply for REGISTER. No transaction\n"); goto error; } expires_hdr = cscf_get_expires_hdr(_m, 0); cb = cscf_parse_contacts(_m); if (!cb || (!cb->contacts && !cb->star)) { LM_DBG("No contact headers and not *\n"); goto error; } cscf_get_p_associated_uri(_m, &public_ids, &num_public_ids, 1); service_routes = cscf_get_service_route(_m, &num_service_routes, 1); //update contacts if (!update_contacts(req, _m, _d, cb->star, expires_hdr, public_ids, num_public_ids, service_routes, num_service_routes, 0)) { LM_ERR("failed to update pcontact\n"); goto error; } if(subscribe_to_reginfo == 1){ //use the first p_associated_uri - i.e. the default IMPU LM_DBG("Subscribe to reg event for primary p_associated_uri"); if(num_public_ids > 0){ //find the first routable (not a tel: URI and use that that presentity) //if you can not find one then exit int i = 0; int found_presentity_uri=0; while (i < num_public_ids && found_presentity_uri == 0) { //check if public_id[i] is NOT a tel URI - if it isn't then concert to pv format and set found presentity_uri to 1 if (strncasecmp(public_ids[i].s,"tel:",4)==0) { LM_DBG("This is a tel URI - it is not routable so we don't use it to subscribe"); i++; } else { //convert primary p_associated_uri to pv_elem_t if(pv_parse_format(&public_ids[i], &presentity_uri_pv)<0) { LM_ERR("wrong format[%.*s]\n",public_ids[i].len, public_ids[i].s); goto error; } found_presentity_uri=1; } } if(found_presentity_uri!=1){ LM_ERR("Could not find routable URI in p_assoiated_uri list - failed to subscribe"); goto error; } }else{ //Now some how check if there is a pua record and what the presentity uri is from there - if nothing there LM_DBG("No p_associated_uri in 200 OK this must be a de-register - we ignore this - will unsubscribe when the notify is received"); goto done; } reginfo_subscribe_real(_m, presentity_uri_pv, service_routes, subscription_expires); pv_elem_free_all(presentity_uri_pv); } done: if (public_ids && public_ids->s) pkg_free(public_ids); if (service_routes && service_routes->s) pkg_free(service_routes); return 1; error: if (public_ids && public_ids->s) pkg_free(public_ids); if (service_routes && service_routes->s) pkg_free(service_routes); return -1; }