Exemplo 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;
}
Exemplo n.º 2
0
static void
__dialog_ended(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
{
    if ((int)(long)*_params->param == CCActive) {
        call_control_stop(_params->msg, dlg->callid);
        *_params->param = (void *)CCInactive;
    }
}
Exemplo n.º 3
0
static void
__dialog_ended(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
{
    if ((int)(long)*_params->param == CCActive) {
        struct sip_msg* msg = _params->rpl;
        if( !msg || msg == FAKED_REPLY)
            msg = _params->req;
        call_control_stop(msg, dlg->callid);
        *_params->param = NULL;
    }
}
Exemplo n.º 4
0
// Postprocess a request after the main script route is done.
//
// After all script processing is done, check if the dialog was actually
// created to take care of call control. If the FL_USE_CALL_CONTROL flag
// is still set, then the dialog creation callback was not called which
// means that there was a failure relaying the message and we have to
// tell the call control application to discard the call, otherwise it
// would remain dangling until it expires.
//
static int
postprocess_request(struct sip_msg *msg, unsigned int flags, void *_param)
{
    CallInfo *call;

    if ((msg->msg_flags & FL_USE_CALL_CONTROL) == 0)
        return 1;

    // the FL_USE_CALL_CONTROL flag is still set => the dialog was not created

    LOG(L_WARN, "dialog to trace controlled call was not created. discarding callcontrol.");

    call = get_call_info(msg, CAStop);
    if (!call) {
        LOG(L_ERR, "can't retrieve call info\n");
        return -1;
    }
    call_control_stop(msg, call->callid);

    return 1;
}