Ejemplo n.º 1
0
void
SIPCall::sendSIPInfo(const char *const body, const char *const subtype)
{
    if (not inv or not inv->dlg)
        throw VoipLinkException("Couldn't get invite dialog");

    pj_str_t methodName = CONST_PJ_STR("INFO");
    pjsip_method method;
    pjsip_method_init_np(&method, &methodName);

    /* Create request message. */
    pjsip_tx_data *tdata;

    if (pjsip_dlg_create_request(inv->dlg, &method, -1, &tdata) != PJ_SUCCESS) {
        RING_ERR("[call:%s] Could not create dialog", getCallId().c_str());
        return;
    }

    /* Create "application/<subtype>" message body. */
    pj_str_t content;
    pj_cstr(&content, body);
    const pj_str_t type = CONST_PJ_STR("application");
    pj_str_t pj_subtype;
    pj_cstr(&pj_subtype, subtype);
    tdata->msg->body = pjsip_msg_body_create(tdata->pool, &type, &pj_subtype, &content);

    if (tdata->msg->body == NULL)
        pjsip_tx_data_dec_ref(tdata);
    else
        pjsip_dlg_send_request(inv->dlg, tdata, getSIPVoIPLink()->getModId(), NULL);
}
Ejemplo n.º 2
0
void SIPPresence::fillDoc(pjsip_tx_data *tdata, const pres_msg_data *msg_data)
{

    if (tdata->msg->type == PJSIP_REQUEST_MSG) {
        const pj_str_t STR_USER_AGENT = CONST_PJ_STR("User-Agent");
        std::string useragent(acc_->getUserAgentName());
        pj_str_t pJuseragent = pj_str((char*) useragent.c_str());
        pjsip_hdr *h = (pjsip_hdr*) pjsip_generic_string_hdr_create(tdata->pool, &STR_USER_AGENT, &pJuseragent);
        pjsip_msg_add_hdr(tdata->msg, h);
    }

    if (msg_data == NULL)
        return;

    const pjsip_hdr *hdr;
    hdr = msg_data->hdr_list.next;

    while (hdr && hdr != &msg_data->hdr_list) {
        pjsip_hdr *new_hdr;
        new_hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, hdr);
        DEBUG("adding header", new_hdr->name.ptr);
        pjsip_msg_add_hdr(tdata->msg, new_hdr);
        hdr = hdr->next;
    }

    if (msg_data->content_type.slen && msg_data->msg_body.slen) {
        pjsip_msg_body *body;
        const pj_str_t type = CONST_PJ_STR("application");
        const pj_str_t subtype = CONST_PJ_STR("pidf+xml");
        body = pjsip_msg_body_create(tdata->pool, &type, &subtype, &msg_data->msg_body);
        tdata->msg->body = body;
    }
}
Ejemplo n.º 3
0
pj_status_t InstantMessaging::sip_send (pjsip_inv_session *session, std::string& id, const std::string& text)
{

    pjsip_method msg_method;
    const pj_str_t type =  STR_TEXT;
    const pj_str_t subtype = STR_PLAIN;
    pjsip_tx_data *tdata;
    pj_status_t status;
    pjsip_dialog* dialog;
    pj_str_t message;

    msg_method.id = PJSIP_OTHER_METHOD;
    msg_method.name = METHOD_NAME;

    // Get the dialog associated to the call
    dialog = session->dlg;
    // Convert the text into a format readable by pjsip

    message = pj_str ( (char*) text.c_str ());

    // Must lock dialog
    pjsip_dlg_inc_lock (dialog);

    // Create the message request
    status = pjsip_dlg_create_request (dialog, &msg_method, -1, &tdata);
    PJ_ASSERT_RETURN (status == PJ_SUCCESS, 1);

    // Attach "text/plain" body
    tdata->msg->body = pjsip_msg_body_create (tdata->pool, &type, &subtype, &message);

    // Create the Require header to handle recipient-list Content-Disposition type
    // pjsip_generic_string_hdr reqhdr;
    // pj_str_t reqhname = pj_str ("Require");
    // pj_str_t reqhvalue = pj_str ("recipient-list");

    // Create the Content-Type header to handle multipart/mixed and boundary MIME types
    // pj_str_t ctype = pj_str ("Content-Type");
    // pj_str_t sctype = pj_str ("ctype"); // small version of the header name
    // ctypehdr = pjsip_msg_find_hdr_by_names (tdata->msg, &ctype, &sctype, NULL);
    // pjsip_generic_string_hdr ctypehdr;
    // pj_str_t ctypehname = pj_str ("Content-Type");
    // pj_str_t ctypehvalue = pj_str ("multipart/mixed;boundary=\"boundary\"");

    // Add headers to the message
    // pjsip_generic_string_hdr_init2 (&reqhdr, &reqhname, &reqhvalue);
    // pj_list_push_back (& (tdata->msg->hdr), (pjsip_hdr*) (&reqhdr));
    // pj_list_push_back (& (tdata->msg->hdr), (pjsip_hdr*) (&ctypehdr));

    // Send the request
    status = pjsip_dlg_send_request (dialog, tdata, -1, NULL);
    // PJ_ASSERT_RETURN (status == PJ_SUCCESS, 1);

    // Done
    pjsip_dlg_dec_lock (dialog);

    // Archive the message
    this->saveMessage (text, "Me", id);

    return PJ_SUCCESS;
}
Ejemplo n.º 4
0
/* Send request */
static void send_request(const pjsip_method *method,
			 int cseq,
			 const pj_str_t *branch,
			 pj_bool_t with_offer)
{
    pjsip_tx_data *tdata;
    pj_str_t dummy_sdp_str = 
    {
	"v=0\r\n"
	"o=- 3360842071 3360842071 IN IP4 192.168.0.68\r\n"
	"s=pjmedia\r\n"
	"c=IN IP4 192.168.0.68\r\n"
	"t=0 0\r\n"
	"m=audio 4000 RTP/AVP 0 101\r\n"
	"a=rtcp:4001 IN IP4 192.168.0.68\r\n"
	"a=rtpmap:0 PCMU/8000\r\n"
	"a=sendrecv\r\n"
	"a=rtpmap:101 telephone-event/8000\r\n"
	"a=fmtp:101 0-15\r\n",
	0
    };
    pj_status_t status;

    status = pjsip_dlg_create_request(dlg, method, cseq, &tdata);
    pj_assert(status == PJ_SUCCESS);

    if (branch) {
	pjsip_via_hdr *via;

	via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
	pj_strdup(tdata->pool, &via->branch_param, branch);
    }

    if (with_offer) {
	pjsip_msg_body *body;
	pj_str_t mime_application = { "application", 11};
	pj_str_t mime_sdp = {"sdp", 3};


	dummy_sdp_str.slen = pj_ansi_strlen(dummy_sdp_str.ptr);
	body = pjsip_msg_body_create(tdata->pool, 
				     &mime_application, &mime_sdp, 
				     &dummy_sdp_str);
	tdata->msg->body = body;
    }

    status = pjsip_dlg_send_request(dlg, tdata, -1, NULL);
    pj_assert(status == PJ_SUCCESS);
}
Ejemplo n.º 5
0
static pj_bool_t mod_stateful_on_rx_request(pjsip_rx_data *rdata)
{
    const pj_str_t stateful_user = { "1", 1 };
    pjsip_uri *uri;
    pjsip_sip_uri *sip_uri;

    uri = pjsip_uri_get_uri(rdata->msg_info.msg->line.req.uri);

    /* Only want to receive SIP/SIPS scheme */
    if (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))
	return PJ_FALSE;

    sip_uri = (pjsip_sip_uri*) uri;

    /* Check for matching user part */
    if (pj_strcmp(&sip_uri->user, &stateful_user)!=0)
	return PJ_FALSE;

    /*
     * Yes, this is for us.
     * Respond statefully with 200/OK.
     */
    switch (rdata->msg_info.msg->line.req.method.id) {
    case PJSIP_INVITE_METHOD:
	{
	    pjsip_msg_body *body;

	    if (dummy_sdp_str.slen == 0)
		dummy_sdp_str.slen = pj_ansi_strlen(dummy_sdp_str.ptr);

	    body = pjsip_msg_body_create(rdata->tp_info.pool, 
					 &mime_application, &mime_sdp, 
					 &dummy_sdp_str);
	    pjsip_endpt_respond(app.sip_endpt, &mod_stateful_server, rdata,
				200, NULL, NULL, body, NULL);
	}
	break;
    case PJSIP_ACK_METHOD:
	return PJ_TRUE;
    default:
	pjsip_endpt_respond(app.sip_endpt, &mod_stateful_server, rdata,
			    200, NULL, NULL, NULL, NULL);
	break;
    }

    app.server.cur_state.stateful_cnt++;
    return PJ_TRUE;
}
Ejemplo n.º 6
0
  /*
   * Enable multipart in msg_data and add a dummy body into the
   * multipart bodies.
   */
  void add_multipart(pjsua_msg_data *msg_data)
  {
      static pjsip_multipart_part *alt_part;

      if (!alt_part) {
	  pj_str_t type, subtype, content;

	  alt_part = pjsip_multipart_create_part(app_config.pool);

	  type = pj_str("text");
	  subtype = pj_str("plain");
	  content = pj_str("Sample text body of a multipart bodies");
	  alt_part->body = pjsip_msg_body_create(app_config.pool, &type,
						 &subtype, &content);
      }

      msg_data->multipart_ctype.type = pj_str("multipart");
      msg_data->multipart_ctype.subtype = pj_str("mixed");
      pj_list_push_back(&msg_data->multipart_parts, alt_part);
  }
Ejemplo n.º 7
0
void send_register_to_as(pjsip_rx_data *received_register,
                         pjsip_tx_data *ok_response,
                         AsInvocation& as,
                         int expires,
                         const std::string& served_user,
                         SAS::TrailId trail)
{
  pj_status_t status;
  pjsip_tx_data *tdata;
  pjsip_method method;
  pjsip_method_set(&method, PJSIP_REGISTER_METHOD);

  pj_str_t user_uri;
  pj_cstr(&user_uri, served_user.c_str());
  pj_str_t as_uri;
  pj_cstr(&as_uri, as.server_name.c_str());

  status = pjsip_endpt_create_request(stack_data.endpt,
                                      &method,      // Method
                                      &as_uri,      // Target
                                      &stack_data.scscf_uri,   // From
                                      &user_uri,    // To
                                      &stack_data.scscf_uri,   // Contact
                                      NULL,         // Auto-generate Call-ID
                                      1,            // CSeq
                                      NULL,         // No body
                                      &tdata);      // OUT

  if (status != PJ_SUCCESS)
  {
    //LCOV_EXCL_START
    LOG_ERROR("Failed to build third-party REGISTER request for server %s",
              as.server_name.c_str());
    return;
    //LCOV_EXCL_STOP
  }

  // Expires header based on 200 OK response
  pjsip_expires_hdr_create(tdata->pool, expires);
  pjsip_expires_hdr* expires_hdr = pjsip_expires_hdr_create(tdata->pool, expires);
  pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)expires_hdr);

  // TODO: modify orig-ioi of P-Charging-Vector and remove term-ioi

  if (received_register && ok_response)
  {
    // Copy P-Access-Network-Info, P-Visited-Network-Id and P-Charging-Vector
    // from original message
    PJUtils::clone_header(&STR_P_A_N_I, received_register->msg_info.msg, tdata->msg, tdata->pool);
    PJUtils::clone_header(&STR_P_V_N_I, received_register->msg_info.msg, tdata->msg, tdata->pool);
    PJUtils::clone_header(&STR_P_C_V, received_register->msg_info.msg, tdata->msg, tdata->pool);

    // Copy P-Charging-Function-Addresses from the OK response.
    PJUtils::clone_header(&STR_P_C_F_A, ok_response->msg, tdata->msg, tdata->pool);

    // Generate a message body based on Filter Criteria values
    char buf[MAX_SIP_MSG_SIZE];
    pj_str_t sip_type = pj_str("message");
    pj_str_t sip_subtype = pj_str("sip");
    pj_str_t xml_type = pj_str("application");
    pj_str_t xml_subtype = pj_str("3gpp-ims+xml");

    // Build up this multipart body incrementally, based on the ServiceInfo, IncludeRegisterRequest and IncludeRegisterResponse fields
    pjsip_msg_body *final_body = pjsip_multipart_create(tdata->pool, NULL, NULL);

    // If we only have one part, we don't want a multipart MIME body - store the reference to each one here to use instead
    pjsip_msg_body *possible_final_body = NULL;
    int multipart_parts = 0;

    if (!as.service_info.empty())
    {
      pjsip_multipart_part *xml_part = pjsip_multipart_create_part(tdata->pool);
      std::string xml_str = "<ims-3gpp><service-info>"+as.service_info+"</service-info></ims-3gpp>";
      pj_str_t xml_pj_str;
      pj_cstr(&xml_pj_str, xml_str.c_str());
      xml_part->body = pjsip_msg_body_create(tdata->pool, &xml_type, &xml_subtype, &xml_pj_str),
      possible_final_body = xml_part->body;
      multipart_parts++;
      pjsip_multipart_add_part(tdata->pool,
                               final_body,
                               xml_part);
    }

    if (as.include_register_request)
    {
      pjsip_multipart_part *request_part = pjsip_multipart_create_part(tdata->pool);
      pjsip_msg_print(received_register->msg_info.msg, buf, sizeof(buf));
      pj_str_t request_str = pj_str(buf);
      request_part->body = pjsip_msg_body_create(tdata->pool, &sip_type, &sip_subtype, &request_str),
      possible_final_body = request_part->body;
      multipart_parts++;
      pjsip_multipart_add_part(tdata->pool,
                               final_body,
                               request_part);
    }

    if (as.include_register_response)
    {
      pjsip_multipart_part *response_part = pjsip_multipart_create_part(tdata->pool);
      pjsip_msg_print(ok_response->msg, buf, sizeof(buf));
      pj_str_t response_str = pj_str(buf);
      response_part->body = pjsip_msg_body_create(tdata->pool, &sip_type, &sip_subtype, &response_str),
      possible_final_body = response_part->body;
      multipart_parts++;
      pjsip_multipart_add_part(tdata->pool,
                               final_body,
                               response_part);
    }

    if (multipart_parts == 0)
    {
      final_body = NULL;
    }
    else if (multipart_parts == 1)
    {
      final_body = possible_final_body;
    }
    else
    {
      // Just use the multipart MIME body you've built up
    }

    tdata->msg->body = final_body;

  }

  // Set the SAS trail on the request.
  set_trail(tdata, trail);

  // Allocate a temporary structure to record the default handling for this
  // REGISTER, and send it statefully.
  ThirdPartyRegData* tsxdata = new ThirdPartyRegData;
  tsxdata->default_handling = as.default_handling;
  tsxdata->trail = trail;
  tsxdata->public_id = served_user;
  pj_status_t resolv_status = PJUtils::send_request(tdata, 0, tsxdata, &send_register_cb);
  if (resolv_status != PJ_SUCCESS)
  {
    delete tsxdata;                         // LCOV_EXCL_LINE
  }
}
Ejemplo n.º 8
0
/*
 * Send instant messaging outside dialog, using the specified account for
 * route set and authentication.
 */
PJ_DEF(pj_status_t) pjsua_im_send( pjsua_acc_id acc_id, 
				   const pj_str_t *to,
				   const pj_str_t *mime_type,
				   const pj_str_t *content,
				   const pjsua_msg_data *msg_data,
				   void *user_data)
{
    pjsip_tx_data *tdata;
    const pj_str_t mime_text_plain = pj_str("text/plain");
    pjsip_media_type media_type;
    pjsua_im_data *im_data;
    pjsua_acc *acc;
    pj_status_t status;

    /* To and message body must be specified. */
    PJ_ASSERT_RETURN(to && content, PJ_EINVAL);

    acc = &pjsua_var.acc[acc_id];

    /* Create request. */
    status = pjsip_endpt_create_request(pjsua_var.endpt, 
					&pjsip_message_method,
                                        (msg_data && msg_data->target_uri.slen? 
                                         &msg_data->target_uri: to),
					&acc->cfg.id,
					to, NULL, NULL, -1, NULL, &tdata);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to create request", status);
	return status;
    }

    /* If account is locked to specific transport, then set transport to
     * the request.
     */
    if (acc->cfg.transport_id != PJSUA_INVALID_ID) {
	pjsip_tpselector tp_sel;

	pjsua_init_tpselector(acc->cfg.transport_id, &tp_sel);
	pjsip_tx_data_set_transport(tdata, &tp_sel);
    }

    /* Add accept header. */
    pjsip_msg_add_hdr( tdata->msg, 
		       (pjsip_hdr*)pjsua_im_create_accept(tdata->pool));

    /* Create suitable Contact header unless a Contact header has been
     * set in the account.
     */
    /* Ticket #1632: According to RFC 3428:
     * MESSAGE requests do not initiate dialogs.
     * User Agents MUST NOT insert Contact header fields into MESSAGE requests
     */
    /*
    if (acc->contact.slen) {
	contact = acc->contact;
    } else {
	status = pjsua_acc_create_uac_contact(tdata->pool, &contact, acc_id, to);
	if (status != PJ_SUCCESS) {
	    pjsua_perror(THIS_FILE, "Unable to generate Contact header", status);
	    pjsip_tx_data_dec_ref(tdata);
	    return status;
	}
    }

    pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)
	pjsip_generic_string_hdr_create(tdata->pool, 
					&STR_CONTACT, &contact));
    */

    /* Create IM data to keep message details and give it back to
     * application on the callback
     */
    im_data = PJ_POOL_ZALLOC_T(tdata->pool, pjsua_im_data);
    im_data->acc_id = acc_id;
    im_data->call_id = PJSUA_INVALID_ID;
    pj_strdup_with_null(tdata->pool, &im_data->to, to);
    pj_strdup_with_null(tdata->pool, &im_data->body, content);
    im_data->user_data = user_data;


    /* Set default media type if none is specified */
    if (mime_type == NULL) {
	mime_type = &mime_text_plain;
    }

    /* Parse MIME type */
    pjsua_parse_media_type(tdata->pool, mime_type, &media_type);

    /* Add message body */
    tdata->msg->body = pjsip_msg_body_create( tdata->pool, &media_type.type,
					      &media_type.subtype, 
					      &im_data->body);
    if (tdata->msg->body == NULL) {
	pjsua_perror(THIS_FILE, "Unable to create msg body", PJ_ENOMEM);
	pjsip_tx_data_dec_ref(tdata);
	return PJ_ENOMEM;
    }

    /* Add additional headers etc. */
    pjsua_process_msg_data(tdata, msg_data);

    /* Add route set */
    pjsua_set_msg_route_set(tdata, &acc->route_set);

    /* If via_addr is set, use this address for the Via header. */
    if (acc->cfg.allow_via_rewrite && acc->via_addr.host.slen > 0) {
        tdata->via_addr = acc->via_addr;
        tdata->via_tp = acc->via_tp;
    }

    /* Send request (statefully) */
    status = pjsip_endpt_send_request( pjsua_var.endpt, tdata, -1, 
				       im_data, &im_callback);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to send request", status);
	return status;
    }

    return PJ_SUCCESS;
}
Ejemplo n.º 9
0
/*
 * Send instant messaging outside dialog, using the specified account for
 * route set and authentication.
 */
PJ_DEF(pj_status_t) pjsua_im_send( pjsua_acc_id acc_id, 
				   const pj_str_t *to,
				   const pj_str_t *mime_type,
				   const pj_str_t *content,
				   const pjsua_msg_data *msg_data,
				   void *user_data)
{
    pjsip_tx_data *tdata;
    const pj_str_t mime_text_plain = pj_str("text/plain");
    const pj_str_t STR_CONTACT = { "Contact", 7 };
    pjsip_media_type media_type;
    pjsua_im_data *im_data;
    pj_str_t contact;
    pj_status_t status;

    /* To and message body must be specified. */
    PJ_ASSERT_RETURN(to && content, PJ_EINVAL);

    /* Create request. */
    status = pjsip_endpt_create_request(pjsua_var.endpt, 
					&pjsip_message_method, to, 
					&pjsua_var.acc[acc_id].cfg.id,
					to, NULL, NULL, -1, NULL, &tdata);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to create request", status);
	return status;
    }

    /* If account is locked to specific transport, then set transport to
     * the request.
     */
    if (pjsua_var.acc[acc_id].cfg.transport_id != PJSUA_INVALID_ID) {
	pjsip_tpselector tp_sel;

	pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel);
	pjsip_tx_data_set_transport(tdata, &tp_sel);
    }

    /* Add accept header. */
    pjsip_msg_add_hdr( tdata->msg, 
		       (pjsip_hdr*)pjsua_im_create_accept(tdata->pool));

    /* Add contact. */
    status = pjsua_acc_create_uac_contact(tdata->pool, &contact, acc_id, to);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to generate Contact header", status);
	pjsip_tx_data_dec_ref(tdata);
	return status;
    }

    pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)
	pjsip_generic_string_hdr_create(tdata->pool, 
					&STR_CONTACT, &contact));

    /* Create IM data to keep message details and give it back to
     * application on the callback
     */
    im_data = PJ_POOL_ZALLOC_T(tdata->pool, pjsua_im_data);
    im_data->acc_id = acc_id;
    im_data->call_id = PJSUA_INVALID_ID;
    pj_strdup_with_null(tdata->pool, &im_data->to, to);
    pj_strdup_with_null(tdata->pool, &im_data->body, content);
    im_data->user_data = user_data;


    /* Set default media type if none is specified */
    if (mime_type == NULL) {
	mime_type = &mime_text_plain;
    }

    /* Parse MIME type */
    pjsua_parse_media_type(tdata->pool, mime_type, &media_type);

    /* Add message body */
    tdata->msg->body = pjsip_msg_body_create( tdata->pool, &media_type.type,
					      &media_type.subtype, 
					      &im_data->body);
    if (tdata->msg->body == NULL) {
	pjsua_perror(THIS_FILE, "Unable to create msg body", PJ_ENOMEM);
	pjsip_tx_data_dec_ref(tdata);
	return PJ_ENOMEM;
    }

    /* Add additional headers etc. */
    pjsua_process_msg_data(tdata, msg_data);

    /* Add route set */
    pjsua_set_msg_route_set(tdata, &pjsua_var.acc[acc_id].route_set);

    /* Send request (statefully) */
    status = pjsip_endpt_send_request( pjsua_var.endpt, tdata, -1, 
				       im_data, &im_callback);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to send request", status);
	return status;
    }

    return PJ_SUCCESS;
}