Commit cd420593 authored by Adrien Béraud's avatar Adrien Béraud

sip: add out-of-call text message support

Change-Id: I71fecc3943c0dcf1df7c2e7873f235ce2cf74e8b
parent a9b306e7
...@@ -86,6 +86,12 @@ constexpr static const char STATE_DESC [] = "Transport.statusDesc ...@@ -86,6 +86,12 @@ constexpr static const char STATE_DESC [] = "Transport.statusDesc
} //namespace DRing::VolatileProperties::Transport } //namespace DRing::VolatileProperties::Transport
namespace InstantMessaging {
constexpr static const char OFF_CALL [] = "IM.offCall";
}
} //namespace DRing::Account::VolatileProperties } //namespace DRing::Account::VolatileProperties
namespace ConfProperties { namespace ConfProperties {
......
...@@ -667,6 +667,7 @@ SIPAccount::getVolatileAccountDetails() const ...@@ -667,6 +667,7 @@ SIPAccount::getVolatileAccountDetails() const
auto a = SIPAccountBase::getVolatileAccountDetails(); auto a = SIPAccountBase::getVolatileAccountDetails();
a.emplace(Conf::CONFIG_ACCOUNT_REGISTRATION_STATE_CODE, ring::to_string(registrationStateDetailed_.first)); a.emplace(Conf::CONFIG_ACCOUNT_REGISTRATION_STATE_CODE, ring::to_string(registrationStateDetailed_.first));
a.emplace(Conf::CONFIG_ACCOUNT_REGISTRATION_STATE_DESC, registrationStateDetailed_.second); a.emplace(Conf::CONFIG_ACCOUNT_REGISTRATION_STATE_DESC, registrationStateDetailed_.second);
a.emplace(DRing::Account::VolatileProperties::InstantMessaging::OFF_CALL, TRUE_STR);
if (presence_) { if (presence_) {
a.emplace(Conf::CONFIG_PRESENCE_STATUS, presence_->isOnline() ? TRUE_STR : FALSE_STR); a.emplace(Conf::CONFIG_PRESENCE_STATUS, presence_->isOnline() ? TRUE_STR : FALSE_STR);
...@@ -2113,4 +2114,79 @@ void SIPAccount::updateDialogViaSentBy(pjsip_dialog *dlg) ...@@ -2113,4 +2114,79 @@ void SIPAccount::updateDialogViaSentBy(pjsip_dialog *dlg)
pjsip_dlg_set_via_sent_by(dlg, &via_addr_, via_tp_); pjsip_dlg_set_via_sent_by(dlg, &via_addr_, via_tp_);
} }
/**
* Create Accept header for MESSAGE.
*/
static pjsip_accept_hdr* im_create_accept(pj_pool_t *pool)
{
/* Create Accept header. */
pjsip_accept_hdr *accept;
accept = pjsip_accept_hdr_create(pool);
accept->values[0] = CONST_PJ_STR("text/plain");
accept->values[1] = CONST_PJ_STR("application/im-iscomposing+xml");
accept->count = 2;
return accept;
}
void
SIPAccount::sendTextMessage(const std::string& to, const std::string& msg)
{
if (to.empty() or msg.empty())
return;
std::string toUri;
if (to.find("sip:") != std::string::npos or
to.find("sips:") != std::string::npos)
toUri = to;
else
toUri = getToUri(to);
const pjsip_method msg_method = { PJSIP_OTHER_METHOD, CONST_PJ_STR("MESSAGE") };
std::string from(getFromUri());
pj_str_t pjFrom = pj_str((char*) from.c_str());
pj_str_t pjTo = pj_str((char*) toUri.c_str());
/* Create request. */
pjsip_tx_data *tdata;
pj_status_t status = pjsip_endpt_create_request(link_->getEndpoint(), &msg_method,
&pjTo, &pjFrom, &pjTo, NULL, NULL, -1, NULL, &tdata);
if (status != PJ_SUCCESS) {
char err_msg[128];
err_msg[0] = '\0';
pj_str_t descr = pj_strerror(status, err_msg, sizeof(err_msg));
RING_ERR("Unable to create request: %.*s", descr.slen, descr.ptr);
return;
}
const pjsip_tpselector tp_sel = getTransportSelector();
pjsip_tx_data_set_transport(tdata, &tp_sel);
/* Add accept header. */
pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)im_create_accept(tdata->pool));
/* Set default media type if none is specified */
static const constexpr pj_str_t type = CONST_PJ_STR("text");
static const constexpr pj_str_t subtype = CONST_PJ_STR("plain");
pj_str_t message = pj_str((char*) msg.c_str());
tdata->msg->body = pjsip_msg_body_create(tdata->pool, &type, &subtype, &message);
if (tdata->msg->body == NULL) {
RING_ERR("Unable to create msg body");
pjsip_tx_data_dec_ref(tdata);
return;
}
status = pjsip_endpt_send_request(link_->getEndpoint(), tdata, -1, nullptr, nullptr);
if (status != PJ_SUCCESS) {
char err_msg[128];
err_msg[0] = '\0';
pj_str_t descr = pj_strerror(status, err_msg, sizeof(err_msg));
RING_ERR("Unable to send request: %.*s", descr.slen, descr.ptr);
return;
}
}
} // namespace ring } // namespace ring
...@@ -513,6 +513,8 @@ class SIPAccount : public SIPAccountBase { ...@@ -513,6 +513,8 @@ class SIPAccount : public SIPAccountBase {
void onRegister(pjsip_regc_cbparam *param); void onRegister(pjsip_regc_cbparam *param);
virtual void sendTextMessage(const std::string& /* to */, const std::string& /* message */);
private: private:
void doRegister1_(); void doRegister1_();
void doRegister2_(); void doRegister2_();
......
...@@ -328,4 +328,11 @@ SIPAccountBase::getIceOptions() const noexcept ...@@ -328,4 +328,11 @@ SIPAccountBase::getIceOptions() const noexcept
return opts; return opts;
} }
void
SIPAccountBase::onTextMessage(const std::string& from, const std::string& msg)
{
RING_WARN("Text message received ! %s -> %s", from.c_str(), msg.c_str());
emitSignal<DRing::ConfigurationSignal::IncomingAccountMessage>(accountID_, from, msg);
}
} // namespace ring } // namespace ring
...@@ -244,6 +244,8 @@ public: ...@@ -244,6 +244,8 @@ public:
const IceTransportOptions getIceOptions() const noexcept override; const IceTransportOptions getIceOptions() const noexcept override;
void onTextMessage(const std::string& from, const std::string& msg);
protected: protected:
virtual void serialize(YAML::Emitter &out); virtual void serialize(YAML::Emitter &out);
virtual void serializeTls(YAML::Emitter &out); virtual void serializeTls(YAML::Emitter &out);
......
...@@ -63,8 +63,6 @@ ...@@ -63,8 +63,6 @@
#include "client/videomanager.h" #include "client/videomanager.h"
#endif #endif
#include "client/ring_signal.h"
#include "pres_sub_server.h" #include "pres_sub_server.h"
#include "array_size.h" #include "array_size.h"
...@@ -223,6 +221,10 @@ transaction_request_cb(pjsip_rx_data *rdata) ...@@ -223,6 +221,10 @@ transaction_request_cb(pjsip_rx_data *rdata)
std::string viaHostname(sip_via.host.ptr, sip_via.host.slen); std::string viaHostname(sip_via.host.ptr, sip_via.host.slen);
const std::string remote_user(sip_from_uri->user.ptr, sip_from_uri->user.slen); const std::string remote_user(sip_from_uri->user.ptr, sip_from_uri->user.slen);
const std::string remote_hostname(sip_from_uri->host.ptr, sip_from_uri->host.slen); const std::string remote_hostname(sip_from_uri->host.ptr, sip_from_uri->host.slen);
char tmp[PJSIP_MAX_URL_SIZE];
size_t length = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, sip_from_uri, tmp, PJSIP_MAX_URL_SIZE);
std::string peerNumber(tmp, length);
sip_utils::stripSipUriPrefix(peerNumber);
auto link = getSIPVoIPLink(); auto link = getSIPVoIPLink();
if (not link) { if (not link) {
...@@ -252,6 +254,13 @@ transaction_request_cb(pjsip_rx_data *rdata) ...@@ -252,6 +254,13 @@ transaction_request_cb(pjsip_rx_data *rdata)
if (ret == 1 and voicemail != 0) if (ret == 1 and voicemail != 0)
Manager::instance().startVoiceMessageNotification(account_id, voicemail); Manager::instance().startVoiceMessageNotification(account_id, voicemail);
} }
} else if (request.find("MESSAGE") != std::string::npos) {
if (body) {
pjsip_endpt_respond( endpt_, NULL, rdata, PJSIP_SC_OK, NULL, NULL, NULL, NULL);
std::string text {(char*)body->data, (char*)body->data+body->len};
account->onTextMessage(peerNumber, text);
return PJ_FALSE;
}
} }
try_respond_stateless(endpt_, rdata, PJSIP_SC_OK, NULL, NULL, NULL); try_respond_stateless(endpt_, rdata, PJSIP_SC_OK, NULL, NULL, NULL);
...@@ -291,10 +300,6 @@ transaction_request_cb(pjsip_rx_data *rdata) ...@@ -291,10 +300,6 @@ transaction_request_cb(pjsip_rx_data *rdata)
return PJ_FALSE; return PJ_FALSE;
} }
char tmp[PJSIP_MAX_URL_SIZE];
size_t length = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, sip_from_uri, tmp, PJSIP_MAX_URL_SIZE);
std::string peerNumber(tmp, length);
sip_utils::stripSipUriPrefix(peerNumber);
if (not remote_user.empty() and not remote_hostname.empty()) if (not remote_user.empty() and not remote_hostname.empty())
peerNumber = remote_user + "@" + remote_hostname; peerNumber = remote_user + "@" + remote_hostname;
...@@ -581,6 +586,9 @@ SIPVoIPLink::SIPVoIPLink() ...@@ -581,6 +586,9 @@ SIPVoIPLink::SIPVoIPLink()
static const pj_str_t accepted = CONST_PJ_STR("application/sdp"); static const pj_str_t accepted = CONST_PJ_STR("application/sdp");
pjsip_endpt_add_capability(endpt_, &mod_ua_, PJSIP_H_ACCEPT, nullptr, 1, &accepted); pjsip_endpt_add_capability(endpt_, &mod_ua_, PJSIP_H_ACCEPT, nullptr, 1, &accepted);
static const pj_str_t iscomposing = CONST_PJ_STR("application/im-iscomposing+xml");
pjsip_endpt_add_capability(endpt_, &mod_ua_, PJSIP_H_ACCEPT, nullptr, 1, &iscomposing);
TRY(pjsip_replaces_init_module(endpt_)); TRY(pjsip_replaces_init_module(endpt_));
#undef TRY #undef TRY
......
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