예제 #1
0
파일: sip_reg.c 프로젝트: iamroger/voip
static void schedule_registration ( pjsip_regc *regc, pj_int32_t expiration )
{
    if (regc->auto_reg && expiration > 0) {
        pj_time_val delay = { 0, 0};

        pj_timer_heap_cancel_if_active(pjsip_endpt_get_timer_heap(regc->endpt),
                                       &regc->timer, 0);

        delay.sec = expiration - regc->delay_before_refresh;
        if (regc->expires != PJSIP_REGC_EXPIRATION_NOT_SPECIFIED && 
            delay.sec > (pj_int32_t)regc->expires) 
        {
            delay.sec = regc->expires;
        }
        if (delay.sec < DELAY_BEFORE_REFRESH) 
            delay.sec = DELAY_BEFORE_REFRESH;
        regc->timer.cb = &regc_refresh_timer_cb;
        regc->timer.id = REFRESH_TIMER;
        regc->timer.user_data = regc;
        pjsip_endpt_schedule_timer( regc->endpt, &regc->timer, &delay);
        pj_gettimeofday(&regc->last_reg);
        regc->next_reg = regc->last_reg;
        regc->next_reg.sec += delay.sec;
    }
}
예제 #2
0
/*
 * Create the ZRTP transport.
 */
PJ_DEF(pj_status_t) pjmedia_transport_zrtp_create(pjmedia_endpt *endpt,
        const char *name,
        pjmedia_transport *transport,
        pjmedia_transport **p_tp,
        pj_bool_t close_slave)
{
    pj_pool_t *pool;
    struct tp_zrtp *zrtp;
    pj_status_t rc;

    if (name == NULL)
        name = "tzrtp%p";

    /* Create the pool and initialize the adapter structure */
    pool = pjmedia_endpt_create_pool(endpt, name, 5*1024, 512);
    zrtp = PJ_POOL_ZALLOC_T(pool, struct tp_zrtp);
    zrtp->pool = pool;
    pj_ansi_strncpy(zrtp->base.name, pool->obj_name,
                    sizeof(zrtp->base.name));
    zrtp->base.type = (pjmedia_transport_type)
                      (PJMEDIA_TRANSPORT_TYPE_USER + 2);
    zrtp->base.op = &tp_zrtp_op;

#ifndef DYNAMIC_TIMER
    if (timer_pool == NULL)
    {
        timer_pool = pjmedia_endpt_create_pool(endpt, "zrtp_timer", 256, 256);
        rc = timer_initialize();
        if (rc != PJ_SUCCESS)
        {
            pj_pool_release(timer_pool);
            pj_pool_release(zrtp->pool);
            return rc;
        }
    }
#else
    zrtp->timer_heap = pjsip_endpt_get_timer_heap(pjsua_var.endpt);
#endif

    /* Create the empty wrapper */
    zrtp->zrtpCtx = zrtp_CreateWrapper();

    /* Initialize standard values */
    zrtp->clientIdString = clientId;    /* Set standard name */
    zrtp->zrtpSeq = 1;                  /* TODO: randomize */
    rc = pj_mutex_create_simple(zrtp->pool, "zrtp", &zrtp->zrtpMutex);
    zrtp->zrtpBuffer = pj_pool_zalloc(pool, MAX_ZRTP_SIZE);
    zrtp->sendBuffer = pj_pool_zalloc(pool, MAX_RTP_BUFFER_LEN);
    zrtp->sendBufferCtrl = pj_pool_zalloc(pool, MAX_RTCP_BUFFER_LEN);

    zrtp->slave_tp = transport;
    zrtp->close_slave = close_slave;
    zrtp->mitmMode = PJ_FALSE;

    /* Done */
    zrtp->refcount++;
    *p_tp = &zrtp->base;
    return PJ_SUCCESS;
}
예제 #3
0
/*! \brief Helper function for changing the T.38 state */
static void t38_change_state(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
	struct t38_state *state, enum ast_sip_session_t38state new_state)
{
	enum ast_sip_session_t38state old_state = session->t38state;
	struct ast_control_t38_parameters parameters = { .request_response = 0, };
	pj_time_val delay = { .sec = T38_AUTOMATIC_REJECTION_SECONDS };

	if (old_state == new_state) {
		return;
	}

	session->t38state = new_state;
	ast_debug(2, "T.38 state changed to '%u' from '%u' on channel '%s'\n",
		new_state, old_state,
		session->channel ? ast_channel_name(session->channel) : "<gone>");

	if (pj_timer_heap_cancel(pjsip_endpt_get_timer_heap(ast_sip_get_pjsip_endpoint()), &state->timer)) {
		ast_debug(2, "Automatic T.38 rejection on channel '%s' terminated\n",
			session->channel ? ast_channel_name(session->channel) : "<gone>");
		ao2_ref(session, -1);
	}

	if (!session->channel) {
		return;
	}

	switch (new_state) {
	case T38_PEER_REINVITE:
		ao2_ref(session, +1);
		if (pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(), &state->timer, &delay) != PJ_SUCCESS) {
			ast_log(LOG_WARNING, "Scheduling of automatic T.38 rejection for channel '%s' failed\n",
				ast_channel_name(session->channel));
			ao2_ref(session, -1);
		}
		parameters = state->their_parms;
		parameters.max_ifp = ast_udptl_get_far_max_ifp(session_media->udptl);
		parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
		ast_udptl_set_tag(session_media->udptl, "%s", ast_channel_name(session->channel));
		break;
	case T38_ENABLED:
		parameters = state->their_parms;
		parameters.max_ifp = ast_udptl_get_far_max_ifp(session_media->udptl);
		parameters.request_response = AST_T38_NEGOTIATED;
		ast_udptl_set_tag(session_media->udptl, "%s", ast_channel_name(session->channel));
		break;
	case T38_REJECTED:
	case T38_DISABLED:
		if (old_state == T38_ENABLED) {
			parameters.request_response = AST_T38_TERMINATED;
		} else if (old_state == T38_LOCAL_REINVITE) {
			parameters.request_response = AST_T38_REFUSED;
		}
		break;
	case T38_LOCAL_REINVITE:
		/* wait until we get a peer response before responding to local reinvite */
		break;
	case T38_MAX_ENUM:
		/* Well, that shouldn't happen */
		ast_assert(0);
		break;
	}

	if (parameters.request_response) {
		ast_queue_control_data(session->channel, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
	}
}

/*! \brief Task function which rejects a T.38 re-invite and resumes handling it */
static int t38_automatic_reject(void *obj)
{
	RAII_VAR(struct ast_sip_session *, session, obj, ao2_cleanup);
	RAII_VAR(struct ast_datastore *, datastore, ast_sip_session_get_datastore(session, "t38"), ao2_cleanup);
	RAII_VAR(struct ast_sip_session_media *, session_media, ao2_find(session->media, "image", OBJ_KEY), ao2_cleanup);

	if (!datastore) {
		return 0;
	}

	ast_debug(2, "Automatically rejecting T.38 request on channel '%s'\n",
		session->channel ? ast_channel_name(session->channel) : "<gone>");

	t38_change_state(session, session_media, datastore->data, T38_REJECTED);
	ast_sip_session_resume_reinvite(session);

	return 0;
}
예제 #4
0
static int uas_tsx_bench(unsigned working_set, pj_timestamp *p_elapsed)
{
    unsigned i;
    pjsip_tx_data *request;
    pjsip_via_hdr *via;
    pjsip_rx_data rdata;
    pj_sockaddr_in remote;
    pjsip_transaction **tsx;
    pj_timestamp t1, t2, elapsed;
    char branch_buf[80] = PJSIP_RFC3261_BRANCH_ID "0000000000";
    pj_status_t status;

    /* Create the request first. */
    pj_str_t str_target = pj_str("sip:[email protected]");
    pj_str_t str_from = pj_str("\"Local User\" <sip:[email protected]>");
    pj_str_t str_to = pj_str("\"Remote User\" <sip:[email protected]>");
    pj_str_t str_contact = str_from;

    status = pjsip_endpt_create_request(endpt, &pjsip_invite_method,
					&str_target, &str_from, &str_to,
					&str_contact, NULL, -1, NULL,
					&request);
    if (status != PJ_SUCCESS) {
	app_perror("    error: unable to create request", status);
	return status;
    }

    /* Create  Via */
    via = pjsip_via_hdr_create(request->pool);
    via->sent_by.host = pj_str("192.168.0.7");
    via->sent_by.port = 5061;
    via->transport = pj_str("udp");
    via->rport_param = 1;
    via->recvd_param = pj_str("192.168.0.7");
    pjsip_msg_insert_first_hdr(request->msg, (pjsip_hdr*)via);
    

    /* Create "dummy" rdata from the tdata */
    pj_bzero(&rdata, sizeof(pjsip_rx_data));
    rdata.tp_info.pool = request->pool;
    rdata.msg_info.msg = request->msg;
    rdata.msg_info.from = (pjsip_from_hdr*) pjsip_msg_find_hdr(request->msg, PJSIP_H_FROM, NULL);
    rdata.msg_info.to = (pjsip_to_hdr*) pjsip_msg_find_hdr(request->msg, PJSIP_H_TO, NULL);
    rdata.msg_info.cseq = (pjsip_cseq_hdr*) pjsip_msg_find_hdr(request->msg, PJSIP_H_CSEQ, NULL);
    rdata.msg_info.cid = (pjsip_cid_hdr*) pjsip_msg_find_hdr(request->msg, PJSIP_H_FROM, NULL);
    rdata.msg_info.via = via;
    
    pj_sockaddr_in_init(&remote, 0, 0);
    status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_LOOP_DGRAM, 
					   &remote, sizeof(pj_sockaddr_in),
					   NULL, &rdata.tp_info.transport);
    if (status != PJ_SUCCESS) {
	app_perror("    error: unable to get loop transport", status);
	return status;
    }


    /* Create transaction array */
    tsx = (pjsip_transaction**) pj_pool_zalloc(request->pool, working_set * sizeof(pj_pool_t*));

    pj_bzero(&mod_tsx_user, sizeof(mod_tsx_user));
    mod_tsx_user.id = -1;


    /* Benchmark */
    elapsed.u64 = 0;
    pj_get_timestamp(&t1);
    for (i=0; i<working_set; ++i) {
	via->branch_param.ptr = branch_buf;
	via->branch_param.slen = PJSIP_RFC3261_BRANCH_LEN + 
				    pj_ansi_sprintf(branch_buf+PJSIP_RFC3261_BRANCH_LEN,
						    "-%d", i);
	status = pjsip_tsx_create_uas(&mod_tsx_user, &rdata, &tsx[i]);
	if (status != PJ_SUCCESS)
	    goto on_error;

    }
    pj_get_timestamp(&t2);
    pj_sub_timestamp(&t2, &t1);
    pj_add_timestamp(&elapsed, &t2);

    p_elapsed->u64 = elapsed.u64;
    status = PJ_SUCCESS;
    
on_error:
    for (i=0; i<working_set; ++i) {
	if (tsx[i]) {
	    pj_timer_heap_t *th;

	    pjsip_tsx_terminate(tsx[i], 601);
	    tsx[i] = NULL;

	    th = pjsip_endpt_get_timer_heap(endpt);
	    pj_timer_heap_poll(th, NULL);

	}
    }
    pjsip_tx_data_dec_ref(request);
    flush_events(2000);
    return status;
}
예제 #5
0
static int uac_tsx_bench(unsigned working_set, pj_timestamp *p_elapsed)
{
    unsigned i;
    pjsip_tx_data *request;
    pjsip_transaction **tsx;
    pj_timestamp t1, t2, elapsed;
    pjsip_via_hdr *via;
    pj_status_t status;

    /* Create the request first. */
    pj_str_t str_target = pj_str("sip:[email protected]");
    pj_str_t str_from = pj_str("\"Local User\" <sip:[email protected]>");
    pj_str_t str_to = pj_str("\"Remote User\" <sip:[email protected]>");
    pj_str_t str_contact = str_from;

    status = pjsip_endpt_create_request(endpt, &pjsip_invite_method,
					&str_target, &str_from, &str_to,
					&str_contact, NULL, -1, NULL,
					&request);
    if (status != PJ_SUCCESS) {
	app_perror("    error: unable to create request", status);
	return status;
    }

    via = (pjsip_via_hdr*) pjsip_msg_find_hdr(request->msg, PJSIP_H_VIA,
					      NULL);

    /* Create transaction array */
    tsx = (pjsip_transaction**) pj_pool_zalloc(request->pool, working_set * sizeof(pj_pool_t*));

    pj_bzero(&mod_tsx_user, sizeof(mod_tsx_user));
    mod_tsx_user.id = -1;

    /* Benchmark */
    elapsed.u64 = 0;
    pj_get_timestamp(&t1);
    for (i=0; i<working_set; ++i) {
	status = pjsip_tsx_create_uac(&mod_tsx_user, request, &tsx[i]);
	if (status != PJ_SUCCESS)
	    goto on_error;
	/* Reset branch param */
	via->branch_param.slen = 0;
    }
    pj_get_timestamp(&t2);
    pj_sub_timestamp(&t2, &t1);
    pj_add_timestamp(&elapsed, &t2);

    p_elapsed->u64 = elapsed.u64;
    status = PJ_SUCCESS;
    
on_error:
    for (i=0; i<working_set; ++i) {
	if (tsx[i]) {
	    pj_timer_heap_t *th;

	    pjsip_tsx_terminate(tsx[i], 601);
	    tsx[i] = NULL;

	    th = pjsip_endpt_get_timer_heap(endpt);
	    pj_timer_heap_poll(th, NULL);
	}
    }
    pjsip_tx_data_dec_ref(request);
    flush_events(2000);
    return status;
}