Commit 8835e993 authored by Ming Rui Zhang's avatar Ming Rui Zhang Committed by Sébastien Blin

sip: fix send sms messages issue

- fix the problem of sending SMS messages from sip to phone
- add different headers
- enable of handling unauthorized errors form server and resend
  request

Change-Id: Ib1272c5fa3fb2c94dc83bbcf19fdb63957159e38
parent dc78a1c8
......@@ -80,7 +80,7 @@ const char * const Account::ACCOUNT_ENABLE_KEY = "enable";
const char * const Account::ACCOUNT_AUTOANSWER_KEY = "autoAnswer";
const char * const Account::ACCOUNT_ACTIVE_CALL_LIMIT_KEY = "activeCallLimit";
const char * const Account::MAILBOX_KEY = "mailbox";
const char * const Account::DEFAULT_USER_AGENT = PACKAGE_NAME "/" PACKAGE_VERSION;
const char * const Account::DEFAULT_USER_AGENT = PACKAGE_NAME;
const char * const Account::USER_AGENT_KEY = "useragent";
const char * const Account::HAS_CUSTOM_USER_AGENT_KEY = "hasCustomUserAgent";
const char * const Account::PRESENCE_MODULE_ENABLED_KEY = "presenceModuleEnabled";
......
......@@ -72,6 +72,8 @@
#include <sstream>
#include <cstdlib>
#include <thread>
#include <chrono>
#include <ctime>
#ifdef _WIN32
#include <lmcons.h>
......@@ -93,6 +95,14 @@ static const char *const VALID_TLS_PROTOS[] = {"Default", "TLSv1.2", "TLSv1.1",
constexpr const char * const SIPAccount::ACCOUNT_TYPE;
struct ctx {
ctx(pjsip_auth_clt_sess* auth) : auth_sess(auth, &pjsip_auth_clt_deinit) {}
std::weak_ptr<SIPAccount> acc;
std::string to;
uint64_t id;
std::unique_ptr<pjsip_auth_clt_sess, decltype(&pjsip_auth_clt_deinit)> auth_sess;
};
static void
registration_cb(pjsip_regc_cbparam *param)
{
......@@ -2069,39 +2079,126 @@ SIPAccount::sendTextMessage(const std::string& to, const std::map<std::string, s
return;
}
const pjsip_tpselector tp_sel = getTransportSelector();
pjsip_tx_data_set_transport(tdata, &tp_sel);
/* Add Date Header. */
pj_str_t date_str;
constexpr auto key = CONST_PJ_STR("Date");
pjsip_hdr *hdr;
auto time = std::time(nullptr);
auto date = std::ctime(&time);
// the erase-remove idiom for a cstring, removes _all_ new lines with in date
*std::remove(date, date+strlen(date), '\n') = '\0';
im::fillPJSIPMessageBody(*tdata, payloads);
// Add Header
hdr = reinterpret_cast<pjsip_hdr*>(pjsip_date_hdr_create(tdata->pool, &key, pj_cstr(&date_str, date)));
pjsip_msg_add_hdr(tdata->msg, hdr);
struct ctx {
std::weak_ptr<SIPAccount> acc;
std::string to;
uint64_t id;
};
ctx* t = new ctx;
/* Add user agent header. */
pjsip_hdr *hdr_list;
auto pJuseragent = CONST_PJ_STR(getUserAgentName());
constexpr pj_str_t STR_USER_AGENT = CONST_PJ_STR("User-Agent");
// Add Header
hdr_list = reinterpret_cast<pjsip_hdr*>(pjsip_user_agent_hdr_create(tdata->pool, &STR_USER_AGENT, &pJuseragent));
pjsip_msg_add_hdr(tdata->msg, hdr_list);
// Set input token into callback
std::unique_ptr<ctx> t{ new ctx(new pjsip_auth_clt_sess) };
t->acc = shared();
t->to = to;
t->id = id;
status = pjsip_endpt_send_request(link_->getEndpoint(), tdata, -1, t, [](void *token, pjsip_event *e) {
auto c = (ctx*) token;
try {
if (auto acc = c->acc.lock()) {
acc->messageEngine_.onMessageSent(c->to, c->id, e
&& e->body.tsx_state.tsx
&& e->body.tsx_state.tsx->status_code == PJSIP_SC_OK);
}
} catch (const std::exception& e) {
JAMI_ERR("Error calling message callback: %s", e.what());
}
delete c;
});
/* Initialize Auth header. */
auto cred = getCredInfo();
const_cast<pjsip_cred_info*>(cred)->realm = CONST_PJ_STR(hostname_);
status = pjsip_auth_clt_init(t->auth_sess.get(), link_->getEndpoint(), tdata->pool, 0);
if (status != PJ_SUCCESS) {
JAMI_ERR("Unable to initialize auth session: %s", sip_utils::sip_strerror(status).c_str());
messageEngine_.onMessageSent(to, id, false);
return;
}
status = pjsip_auth_clt_set_credentials(t->auth_sess.get(), getCredentialCount(), cred);
if (status != PJ_SUCCESS) {
JAMI_ERR("Unable to set auth session data: %s", sip_utils::sip_strerror(status).c_str());
messageEngine_.onMessageSent(to, id, false);
return;
}
const pjsip_tpselector tp_sel = getTransportSelector();
status = pjsip_tx_data_set_transport(tdata, &tp_sel);
if (status != PJ_SUCCESS) {
JAMI_ERR("Unable to set transport: %s", sip_utils::sip_strerror(status).c_str());
messageEngine_.onMessageSent(to, id, false);
return;
}
im::fillPJSIPMessageBody(*tdata, payloads);
// Send message request with callback onComplete
auto token = t.release();
status = pjsip_endpt_send_request(link_->getEndpoint(), tdata, -1, token, &onComplete);
if (status != PJ_SUCCESS) {
JAMI_ERR("Unable to send request: %s", sip_utils::sip_strerror(status).c_str());
messageEngine_.onMessageSent(to, id, false);
delete token;
return;
}
}
void
SIPAccount::onComplete(void *token, pjsip_event *event)
{
std::unique_ptr<ctx> c{ (ctx*)token };
int code;
pj_status_t status;
pj_assert(event->type == PJSIP_EVENT_TSX_STATE);
code = event->body.tsx_state.tsx->status_code;
auto acc = c->acc.lock();
if (not acc)
return;
//Check if Authorization Header if needed (request rejected by server)
if (code == PJSIP_SC_UNAUTHORIZED || code == PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED) {
JAMI_INFO("Authorization needed for SMS message - Resending");
pjsip_tx_data *new_request;
// Add Authorization Header into msg
status = pjsip_auth_clt_reinit_req( c->auth_sess.get(), event->body.tsx_state.src.rdata, event->body.tsx_state.tsx->last_tx, &new_request);
if (status == PJ_SUCCESS) {
// Increment Cseq number by one manually
pjsip_cseq_hdr *cseq_hdr;
cseq_hdr = (pjsip_cseq_hdr*)pjsip_msg_find_hdr(new_request->msg, PJSIP_H_CSEQ, NULL);
cseq_hdr->cseq += 1;
// Resend request
auto data = c.release();
status = pjsip_endpt_send_request(acc->link_->getEndpoint(), new_request, -1, data, &onComplete);
if (status != PJ_SUCCESS) {
JAMI_ERR("Unable to send request: %s", sip_utils::sip_strerror(status).c_str());
acc->messageEngine_.onMessageSent(c->to, c->id, false);
delete data;
}
return;
}
else {
JAMI_ERR("Unable to add Authorization Header into msg");
acc->messageEngine_.onMessageSent(c->to, c->id, false);
return;
}
}
acc->messageEngine_.onMessageSent(c->to, c->id, event
&& event->body.tsx_state.tsx
&& (event->body.tsx_state.tsx->status_code == PJSIP_SC_OK
|| event->body.tsx_state.tsx->status_code == PJSIP_SC_ACCEPTED));
}
std::string
......
......@@ -685,6 +685,11 @@ class SIPAccount : public SIPAccountBase {
*/
pj_uint16_t tlsListenerPort_ {sip_utils::DEFAULT_SIP_TLS_PORT};
/**
* Send Request Callback
*/
static void onComplete(void *token, pjsip_event *event);
bool tlsEnable_ {false};
std::string tlsMethod_;
std::string tlsCiphers_;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment