Ejemplo n.º 1
0
        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;
        }
Ejemplo n.º 2
0
/*! \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;
}
Ejemplo n.º 3
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;
        }
Ejemplo n.º 4
0
/*! \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;
}
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
/**
 * 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;

}