Ejemplo n.º 1
0
// Return codes:
//   2 - No limit
//   1 - Limited
//  -1 - No credit
//  -2 - Locked
//  -3 - Duplicated callid
//  -4 - Call limit reached
//  -5 - Internal error (message parsing, communication, ...)
static int
CallControl(struct sip_msg *msg, char *str1, char *str2)
{
    int result;
    struct dlg_cell *dlg;
    CallInfo *call;

    if (disable)
        return 2;

    if (msg->first_line.type!=SIP_REQUEST || msg->REQ_METHOD!=METHOD_INVITE || has_to_tag(msg)) {
        LM_WARN("call_control should only be called for the first INVITE\n");
        return -5;
    }

    result = call_control_initialize(msg);
    if (result == 1) {
        // A call with a time limit that will be traced by callcontrol

        if (dlg_api.create_dlg(msg, 0) < 0) {
            LM_ERR("could not create new dialog\n");
            call = get_call_info(msg, CAStop);
            if (!call) {
                LM_ERR("can't retrieve call info\n");
                return -5;
            }
            call_control_stop(msg, call->callid);
            return -5;
        }

        dlg = dlg_api.get_dlg();
        if (!dlg) {
            LM_CRIT("error getting dialog\n");
            call = get_call_info(msg, CAStop);
            if (!call) {
                LM_ERR("can't retrieve call info\n");
                return -5;
            }
            call_control_stop(msg, call->callid);
            return -5;
        }

        if (dlg_api.register_dlgcb(dlg, DLGCB_RESPONSE_FWDED, __dialog_replies, NULL, NULL) != 0) {
            LM_ERR("cannot register callback for dialog confirmation\n");
            call_control_stop(msg, dlg->callid);
            return -5;
        }

        if (dlg_api.register_dlgcb(dlg, DLGCB_TERMINATED | DLGCB_FAILED | DLGCB_EXPIRED | DLGCB_DESTROY, __dialog_ended, (void*)CCActive, NULL) != 0) {
            LM_ERR("cannot register callback for dialog termination\n");
            call_control_stop(msg, dlg->callid);
            return -5;
        }

    }

    return result;
}
Ejemplo n.º 2
0
/*
 * Do loose routing as defined in RFC3621
 */
int loose_route(struct sip_msg* _m, char* _s1, char* _s2)
{
	struct hdr_field* hdr;
	struct sip_uri puri;
	rr_t* rt;
	int ret;
	str* uri;

	if (find_first_route(_m) != 0) {
		DBG("loose_route: There is no Route HF\n");
		return -1;
	}

	if (parse_sip_msg_uri(_m) == -1) {
		LOG(L_ERR, "loose_route: Error while parsing Request URI\n");
		return -1;
	}

	hdr = _m->route;
	rt = (rr_t*)hdr->parsed;
	uri = &rt->nameaddr.uri;

	if (parse_uri(uri->s, uri->len, &puri) < 0) {
		LOG(L_ERR, "loose_route: Error while parsing the first route URI\n");
		return -1;
	}

	if (is_myself(&_m->parsed_uri.host, _m->parsed_uri.port_no)||
			_m->parsed_uri.type == TEL_URI_T ||
			_m->parsed_uri.type == TELS_URI_T) {
		DBG("loose_route: RURI is myself (or tel URI)\n");
		if ((ret = is_myself(&puri.host, puri.port_no)) == 1 &&
			!(enable_double_rr && is_2rr(&puri.params))) {
			DBG("loose_route: found preloaded loose route\n");
			return after_loose(_m, &puri, ret, 1);
		} else {
			if (has_to_tag(_m) == 1) {
				return after_strict(_m, &puri, ret);
			} else {
				LOG(L_WARN, "loose_route: pre-loaded strict routing?!\n");
				return -1;
			}
		}
	} else {
		DBG("loose_route: RURI is NOT myself\n");
		if (is_myself(&puri.host, puri.port_no)) {
			return after_loose(_m, &puri, 1, 0);
		} else {
			store_next_route_in_avps(uri);
			//LOG(L_WARN, "loose_route: no routing target is local\n");
			//return -1;
			return after_loose(_m, &puri, 0, 0);
		}
	}
}
Ejemplo n.º 3
0
// Return codes:
//   2 - No limit
//   1 - Limited
//  -1 - No credit
//  -2 - Locked
//  -3 - No provider
//  -5 - Internal error (message parsing, communication, ...)
static int
CallControl(struct sip_msg *msg, char *str1, char *str2)
{
    int result;

    if (disable)
        return 2;

    if (msg->first_line.type!=SIP_REQUEST || msg->REQ_METHOD!=METHOD_INVITE || has_to_tag(msg)) {
        LOG(L_WARN, "call_control should only be called for the first INVITE\n");
        return -5;
    }

    result = call_control_initialize(msg);
    if (result == 1) {
        // A call with a time limit that will be traced by callcontrol
        msg->msg_flags |= FL_USE_CALL_CONTROL;
        setflag(msg, dialog_flag); // have the dialog module trace this dialog
    }

    return result;
}