예제 #1
0
/* Outgoing typing indication callback.
 * (used to reauthenticate request)
 */
static void typing_callback(void *token, pjsip_event *e)
{
    pjsua_im_data *im_data = (pjsua_im_data*) token;
    pjsua_inst_id inst_id = im_data->inst_id;

    if (e->type == PJSIP_EVENT_TSX_STATE) {

        pjsip_transaction *tsx = e->body.tsx_state.tsx;

        /* Ignore provisional response, if any */
        if (tsx->status_code < 200)
            return;

        /* Handle authentication challenges */
        if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG &&
                (tsx->status_code == 401 || tsx->status_code == 407))
        {
            pjsip_rx_data *rdata = e->body.tsx_state.src.rdata;
            pjsip_tx_data *tdata;
            pjsip_auth_clt_sess auth;
            pj_status_t status;

            PJ_LOG(4,(THIS_FILE, "Resending IM with authentication"));

            /* Create temporary authentication session */
            pjsip_auth_clt_init(&auth,pjsua_var[inst_id].endpt,rdata->tp_info.pool, 0);

            pjsip_auth_clt_set_credentials(&auth,
                                           pjsua_var[inst_id].acc[im_data->acc_id].cred_cnt,
                                           pjsua_var[inst_id].acc[im_data->acc_id].cred);

            pjsip_auth_clt_set_prefs(&auth,
                                     &pjsua_var[inst_id].acc[im_data->acc_id].cfg.auth_pref);

            status = pjsip_auth_clt_reinit_req(&auth, rdata, tsx->last_tx,
                                               &tdata);
            if (status == PJ_SUCCESS) {
                pjsua_im_data *im_data2;

                /* Must duplicate im_data */
                im_data2 = pjsua_im_data_dup(tdata->pool, im_data);

                /* Increment CSeq */
                PJSIP_MSG_CSEQ_HDR(tdata->msg)->cseq++;

                /* Re-send request */
                status = pjsip_endpt_send_request( pjsua_var[inst_id].endpt, tdata, -1,
                                                   im_data2, &typing_callback);
                if (status == PJ_SUCCESS) {
                    /* Done */
                    return;
                }
            }
        }

    }
}
static pj_status_t process_on_tx_msg(pjsip_tx_data* tdata)
{
  if ((health_checker != NULL) &&
      (PJSIP_MSG_CSEQ_HDR(tdata->msg)->method.id == PJSIP_INVITE_METHOD) &&
      (tdata->msg->line.status.code == 200))
  {
    // 200 OK to an INVITE - meets S-CSCF health check criteria
    health_checker->health_check_passed();
  }

  // Do logging.
  local_log_tx_msg(tdata);
  sas_log_tx_msg(tdata);

  // Return success so the message gets transmitted.
  return PJ_SUCCESS;
}
예제 #3
0
void SessionExpiresHelper::process_response(pjsip_msg* rsp,
                                            pj_pool_t* pool,
                                            SAS::TrailId trail)
{
  // Session expires is only allowed on INVITE and UPDATE methods.
  pjsip_method* method = &PJSIP_MSG_CSEQ_HDR(rsp)->method;

  if ((pjsip_method_cmp(method, pjsip_get_invite_method()) != 0) &&
      (pjsip_method_cmp(method, &METHOD_UPDATE) != 0))
  {
    return;
  }

  // We only need to process successful final responses.
  if (!PJSIP_IS_STATUS_IN_CLASS(rsp->line.status.code, 200))
  {
    return;
  }

  pjsip_session_expires_hdr* se_hdr = (pjsip_session_expires_hdr*)
    pjsip_msg_find_hdr_by_name(rsp, &STR_SESSION_EXPIRES, NULL);

  if (se_hdr == NULL)
  {
    // There is no session-expires header. This means we are most downstream
    // device that supports session timers, and in particular the UAS does not
    // support them.
    //
    // If the UAC does not support session timers, there's nothing more we can
    // do - session timers will not be used for this dialog.
    //
    // If the UAC *does* support session timers, re-add a session-expires header
    // that instructs the UAC to be the refresher.
    if (_uac_supports_timer)
    {
      se_hdr = pjsip_session_expires_hdr_create(pool);
      pjsip_msg_add_hdr(rsp, (pjsip_hdr*)se_hdr);
      se_hdr->expires = _se_on_req;
      se_hdr->refresher = SESSION_REFRESHER_UAC;

      // Also update (or add) the require header to force the UAC to do session
      // refreshes.
      pjsip_require_hdr* require_hdr = (pjsip_require_hdr*)
        pjsip_msg_find_hdr(rsp, PJSIP_H_REQUIRE, NULL);

      if (require_hdr == NULL)
      {
        require_hdr = (pjsip_require_hdr*)pjsip_require_hdr_create(pool);
        pjsip_msg_add_hdr(rsp, (pjsip_hdr*)require_hdr);
      }

      pj_strdup(pool, &require_hdr->values[require_hdr->count], &STR_TIMER);
      require_hdr->count++;
    }
  }

  if (_initial_request)
  {
    if (se_hdr == NULL)
    {
      SAS::Event event(trail, SASEvent::SESS_TIMER_NO_UA_SUPPORT, 0);
      SAS::report_event(event);
    }
    else if (se_hdr->expires > _target_se)
    {
      SAS::Event event(trail, SASEvent::SESS_TIMER_INTERVAL_TOO_LONG, 0);
      event.add_static_param(_target_se);
      event.add_static_param(se_hdr->expires);
      SAS::report_event(event);
    }
  }
}
예제 #4
0
/* Outgoing IM callback. */
static void im_callback(void *token, pjsip_event *e)
{
    pjsua_im_data *im_data = (pjsua_im_data*) token;

    if (e->type == PJSIP_EVENT_TSX_STATE) {

	pjsip_transaction *tsx = e->body.tsx_state.tsx;

	/* Ignore provisional response, if any */
	if (tsx->status_code < 200)
	    return;


	/* Handle authentication challenges */
	if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG &&
	    (tsx->status_code == 401 || tsx->status_code == 407)) 
	{
	    pjsip_rx_data *rdata = e->body.tsx_state.src.rdata;
	    pjsip_tx_data *tdata;
	    pjsip_auth_clt_sess auth;
	    pj_status_t status;

	    PJ_LOG(4,(THIS_FILE, "Resending IM with authentication"));

	    /* Create temporary authentication session */
	    pjsip_auth_clt_init(&auth,pjsua_var.endpt,rdata->tp_info.pool, 0);
    
	    pjsip_auth_clt_set_credentials(&auth, 
		pjsua_var.acc[im_data->acc_id].cred_cnt,
		pjsua_var.acc[im_data->acc_id].cred);

	    pjsip_auth_clt_set_prefs(&auth, 
				     &pjsua_var.acc[im_data->acc_id].cfg.auth_pref);

	    status = pjsip_auth_clt_reinit_req(&auth, rdata, tsx->last_tx,
					       &tdata);
	    if (status == PJ_SUCCESS) {
		pjsua_im_data *im_data2;

		/* Must duplicate im_data */
		im_data2 = pjsua_im_data_dup(tdata->pool, im_data);

		/* Increment CSeq */
		PJSIP_MSG_CSEQ_HDR(tdata->msg)->cseq++;

		/* Re-send request */
		status = pjsip_endpt_send_request( pjsua_var.endpt, tdata, -1,
						   im_data2, &im_callback);
		if (status == PJ_SUCCESS) {
		    /* Done */
		    return;
		}
	    }
	}

	if (tsx->status_code/100 == 2) {
	    PJ_LOG(4,(THIS_FILE, 
		      "Message \'%s\' delivered successfully",
		      im_data->body.ptr));
	} else {
	    PJ_LOG(3,(THIS_FILE, 
		      "Failed to deliver message \'%s\': %d/%.*s",
		      im_data->body.ptr,
		      tsx->status_code,
		      (int)tsx->status_text.slen,
		      tsx->status_text.ptr));
	}

	if (pjsua_var.ua_cfg.cb.on_pager_status) {
	    pjsua_var.ua_cfg.cb.on_pager_status(im_data->call_id, 
					        &im_data->to,
						&im_data->body,
						im_data->user_data,
						(pjsip_status_code) 
						    tsx->status_code,
						&tsx->status_text);
	}

	if (pjsua_var.ua_cfg.cb.on_pager_status2) {
	    pjsip_rx_data *rdata;

	    if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG)
		rdata = e->body.tsx_state.src.rdata;
	    else
		rdata = NULL;

	    pjsua_var.ua_cfg.cb.on_pager_status2(im_data->call_id, 
					         &im_data->to,
					 	 &im_data->body,
						 im_data->user_data,
						 (pjsip_status_code) 
						    tsx->status_code,
						 &tsx->status_text,
						 tsx->last_tx,
						 rdata, im_data->acc_id);
	}
    }
}