Beispiel #1
0
/// This provides function similar to the pjsip_endpt_send_request method
/// but includes setting the SAS trail.  It does not support the timeout, token
/// or callback options.
pj_status_t PJUtils::send_request(pjsip_endpoint* endpt,
                                  pjsip_tx_data* tdata)
{
  pjsip_transaction* tsx;
  pj_status_t status;

  status = pjsip_tsx_create_uac(&mod_sprout_util, tdata, &tsx);
  if (status != PJ_SUCCESS)
  {
    pjsip_tx_data_dec_ref(tdata);
    return status;
  }

  pjsip_tsx_set_transport(tsx, &tdata->tp_sel);

  // Set the trail ID in the transaction from the message.
  set_trail(tsx, get_trail(tdata));

  status = pjsip_tsx_send_msg(tsx, NULL);
  if (status != PJ_SUCCESS)
  {
    pjsip_tx_data_dec_ref(tdata);
  }

  return status;
}
Beispiel #2
0
PJ_DEF(pj_status_t) pjsip_endpt_send_request(  pjsip_endpoint *endpt,
					       pjsip_tx_data *tdata,
					       pj_int32_t timeout,
					       void *token,
					       pjsip_endpt_send_callback cb)
{
    pjsip_transaction *tsx;
    struct tsx_data *tsx_data;
    pj_status_t status;

    PJ_ASSERT_RETURN(endpt && tdata && (timeout==-1 || timeout>0), PJ_EINVAL);

    /* Check that transaction layer module is registered to endpoint */
    PJ_ASSERT_RETURN(mod_stateful_util.id != -1, PJ_EINVALIDOP);

    PJ_UNUSED_ARG(timeout);

    status = pjsip_tsx_create_uac(&mod_stateful_util, tdata, &tsx);
    if (status != PJ_SUCCESS) {
	pjsip_tx_data_dec_ref(tdata);
	return status;
    }

    pjsip_tsx_set_transport(tsx, &tdata->tp_sel);

    tsx_data = PJ_POOL_ALLOC_T(tsx->pool, struct tsx_data);
    tsx_data->token = token;
    tsx_data->cb = cb;

    tsx->mod_data[mod_stateful_util.id] = tsx_data;

    status = pjsip_tsx_send_msg(tsx, NULL);
    if (status != PJ_SUCCESS)
	pjsip_tx_data_dec_ref(tdata);

    return status;
}
Beispiel #3
0
/// This provides function similar to the pjsip_endpt_send_request method
/// but includes setting the SAS trail.
pj_status_t PJUtils::send_request(pjsip_tx_data* tdata,
                                  int retries,
                                  void* token,
                                  pjsip_endpt_send_callback cb)
{
  pjsip_transaction* tsx;
  pj_status_t status = PJ_SUCCESS;

  LOG_DEBUG("Sending standalone request statefully");

  // Allocate temporary storage for the request.
  StatefulSendState* sss = new StatefulSendState;

  // Store the user supplied callback and token.
  sss->user_token = token;
  sss->user_cb = cb;

  if (tdata->tp_sel.type != PJSIP_TPSELECTOR_TRANSPORT)
  {
    // No transport determined, so resolve the next hop for the message.
    resolve_next_hop(tdata, retries, sss->servers, get_trail(tdata));

    if (!sss->servers.empty())
    {
      // Set up the destination information for the first server.
      sss->current_server = 0;
      set_dest_info(tdata, sss->servers[sss->current_server]);
    }
    else
    {
      // No servers found.
      status = PJ_ENOTFOUND;
    }
  }

  if (status == PJ_SUCCESS)
  {
    // We have servers to send the request to, so allocate a transaction.
    status = pjsip_tsx_create_uac(&mod_sprout_util, tdata, &tsx);

    if (status == PJ_SUCCESS)
    {
      // Set the trail ID in the transaction from the message.
      set_trail(tsx, get_trail(tdata));

      // Set up the module data for the new transaction to reference
      // the state information.
      tsx->mod_data[mod_sprout_util.id] = sss;

      if (tdata->tp_sel.type == PJSIP_TPSELECTOR_TRANSPORT)
      {
        // Transport has already been determined, so copy it across to the
        // transaction.
        LOG_DEBUG("Transport already determined");
        pjsip_tsx_set_transport(tsx, &tdata->tp_sel);
      }

      // Store the message and add a reference to prevent the transaction layer
      // freeing it.
      sss->tdata = tdata;
      pjsip_tx_data_add_ref(tdata);

      LOG_DEBUG("Sending request");
      status = pjsip_tsx_send_msg(tsx, tdata);
    }
  }

  if (status != PJ_SUCCESS)
  {
    // The assumption here is that, if pjsip_tsx_send_msg returns an error
    // the on_tsx_state callback will not get called, so it is safe to free
    // off the state data and request here.  Also, this is an unexpected
    // error rather than an indication that the destination server is down,
    // so we don't blacklist.
    LOG_ERROR("Failed to send request to %s",
              PJUtils::uri_to_string(PJSIP_URI_IN_ROUTING_HDR,
                                     PJUtils::next_hop(tdata->msg)).c_str());

    // Only free the state data if there are no more references to it
    pj_status_t dec_status = pjsip_tx_data_dec_ref(tdata);

    if (dec_status == PJSIP_EBUFDESTROYED)
    {
      delete sss;
    }
  }

  return status;
}
Beispiel #4
0
int UE::send_message(std::string dest, std::string contents)
{
  timeval before;
  timeval after;
  pthread_mutex_lock(&_msg_mutex);
  pj_str_t to;
  stra(&to, dest.c_str());
  pj_str_t data;
  stra(&data, contents.c_str());
  pj_str_t message;
  stra(&message, "MESSAGE");
  pjsip_tx_data* tdata;
  pjsip_method msg_method;
  pjsip_method_init(&msg_method, _pool, &message);

  pjsip_endpt_create_request(get_global_endpoint(),
      &msg_method,
      &to,
      &_my_uri,
      &to,
      &_contact,
      NULL,
      -1,
      &data,
      &tdata);


  pjsip_tsx_create_uac(ua_module(), tdata, &_msg_tsx);

  pjsip_tpselector sel;
  sel.type = PJSIP_TPSELECTOR_TRANSPORT;
  sel.u.transport = _transport;
  pjsip_tsx_set_transport(_msg_tsx, &sel);
  
  pjsip_route_hdr* rt_hdr = pjsip_route_hdr_create(tdata->pool);
  rt_hdr->name_addr.uri = _server_uri;
  pjsip_msg_insert_first_hdr(tdata->msg, (pjsip_hdr*)rt_hdr);

  _msg_tsx->mod_data[ua_module()->id] = this;

  pj_grp_lock_add_ref(_msg_tsx->grp_lock);
  gettimeofday(&before, NULL);
  pj_status_t status = pjsip_tsx_send_msg(_msg_tsx, NULL);
  if (status != PJ_SUCCESS)
  {
    pthread_mutex_unlock(&_msg_mutex);
    return -1;
  }
  while (_msg_tsx->state < PJSIP_TSX_STATE_COMPLETED)
  {
    pthread_cond_wait(&_msg_cond, &_msg_mutex);
  }
  gettimeofday(&after, NULL);
  //unsigned long latency = ((after.tv_sec - before.tv_sec) * 1000000) + (after.tv_usec - before.tv_usec);
  //printf("Message latency is %lu\n", latency);
  int ret = _msg_tsx->status_code;
  pj_grp_lock_dec_ref(_msg_tsx->grp_lock);
  _msg_tsx = NULL;
  pthread_mutex_unlock(&_msg_mutex);
  return ret;
}