LCOV - code coverage report
Current view: top level - foo/src/sip - pres_sub_server.cpp (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 3 40 7.5 %
Date: 2026-04-01 09:29:43 Functions: 1 9 11.1 %

          Line data    Source code
       1             : /*
       2             :  *  Copyright (C) 2004-2026 Savoir-faire Linux Inc.
       3             :  *
       4             :  *  This program is free software: you can redistribute it and/or modify
       5             :  *  it under the terms of the GNU General Public License as published by
       6             :  *  the Free Software Foundation, either version 3 of the License, or
       7             :  *  (at your option) any later version.
       8             :  *
       9             :  *  This program is distributed in the hope that it will be useful,
      10             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      12             :  *  GNU General Public License for more details.
      13             :  *
      14             :  *  You should have received a copy of the GNU General Public License
      15             :  *  along with this program. If not, see <https://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : #include "sip/sipaccount.h"
      19             : #include "sip/sippresence.h"
      20             : #include "logger.h"
      21             : #include "pres_sub_server.h"
      22             : #include "connectivity/sip_utils.h"
      23             : #include "compiler_intrinsics.h"
      24             : 
      25             : namespace jami {
      26             : 
      27             : using sip_utils::CONST_PJ_STR;
      28             : 
      29             : /* Callback called when *server* subscription state has changed. */
      30             : void
      31           0 : PresSubServer::pres_evsub_on_srv_state(UNUSED pjsip_evsub* sub, UNUSED pjsip_event* event)
      32             : {
      33           0 :     JAMI_ERR("PresSubServer::pres_evsub_on_srv_state() is deprecated and does nothing");
      34           0 :     return;
      35             : 
      36             : #if 0 // DISABLED: removed IP2IP support, tuleap: #448
      37             :     pjsip_rx_data *rdata = event->body.rx_msg.rdata;
      38             : 
      39             :     if (!rdata) {
      40             :         JAMI_DBG("Presence_subscription_server estate has changed but no rdata.");
      41             :         return;
      42             :     }
      43             : 
      44             :     auto account = Manager::instance().getIP2IPAccount();
      45             :     auto sipaccount = static_cast<SIPAccount *>(account.get());
      46             :     if (!sipaccount) {
      47             :         JAMI_ERR("Unable to find account IP2IP");
      48             :         return;
      49             :     }
      50             : 
      51             :     auto pres = sipaccount->getPresence();
      52             : 
      53             :     if (!pres) {
      54             :         JAMI_ERR("Presence not initialized");
      55             :         return;
      56             :     }
      57             : 
      58             :     pres->lock();
      59             :     PresSubServer *presSubServer = static_cast<PresSubServer *>(pjsip_evsub_get_mod_data(sub, pres->getModId()));
      60             : 
      61             :     if (presSubServer) {
      62             :         JAMI_DBG("Presence_subscription_server to %s is %s",
      63             :               presSubServer->remote_, pjsip_evsub_get_state_name(sub));
      64             :         pjsip_evsub_state state;
      65             : 
      66             :         state = pjsip_evsub_get_state(sub);
      67             : 
      68             :         if (state == PJSIP_EVSUB_STATE_TERMINATED) {
      69             :             pjsip_evsub_set_mod_data(sub, pres->getModId(), NULL);
      70             :             pres->removePresSubServer(presSubServer);
      71             :         }
      72             : 
      73             :         /* TODO check if other cases should be handled*/
      74             :     }
      75             : 
      76             :     pres->unlock();
      77             : #endif
      78             : }
      79             : 
      80             : pj_bool_t
      81         105 : PresSubServer::pres_on_rx_subscribe_request(pjsip_rx_data* rdata)
      82             : {
      83             :     /* Only hande incoming subscribe messages should be processed here.
      84             :      * Otherwise we return FALSE to let other modules handle it */
      85         105 :     if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, pjsip_get_subscribe_method()) != 0)
      86         105 :         return PJ_FALSE;
      87             : 
      88           0 :     JAMI_ERR("PresSubServer::pres_evsub_on_srv_state() is deprecated and does nothing");
      89           0 :     return PJ_FALSE;
      90             : }
      91             : 
      92             : pjsip_module PresSubServer::mod_presence_server = {
      93             :     NULL,
      94             :     NULL,                                /* prev, next.        */
      95             :     CONST_PJ_STR("mod-presence-server"), /* Name.        */
      96             :     -1,                                  /* Id            */
      97             :     PJSIP_MOD_PRIORITY_DIALOG_USAGE,
      98             :     NULL,                          /* load()        */
      99             :     NULL,                          /* start()        */
     100             :     NULL,                          /* stop()        */
     101             :     NULL,                          /* unload()        */
     102             :     &pres_on_rx_subscribe_request, /* on_rx_request()    */
     103             :     NULL,                          /* on_rx_response()    */
     104             :     NULL,                          /* on_tx_request.    */
     105             :     NULL,                          /* on_tx_response()    */
     106             :     NULL,                          /* on_tsx_state()    */
     107             : 
     108             : };
     109             : 
     110           0 : PresSubServer::PresSubServer(SIPPresence* pres, pjsip_evsub* evsub, const char* remote, pjsip_dialog* d)
     111           0 :     : remote_(remote)
     112           0 :     , pres_(pres)
     113           0 :     , sub_(evsub)
     114           0 :     , dlg_(d)
     115           0 :     , expires_(-1)
     116           0 :     , approved_(false)
     117           0 : {}
     118             : 
     119           0 : PresSubServer::~PresSubServer()
     120             : {
     121             :     // TODO: check if evsub needs to be forced TERMINATED.
     122           0 : }
     123             : 
     124             : void
     125           0 : PresSubServer::setExpires(int ms)
     126             : {
     127           0 :     expires_ = ms;
     128           0 : }
     129             : 
     130             : int
     131           0 : PresSubServer::getExpires() const
     132             : {
     133           0 :     return expires_;
     134             : }
     135             : 
     136             : bool
     137           0 : PresSubServer::matches(const char* s) const
     138             : {
     139             :     // servers match if they have the same remote uri and the account ID.
     140           0 :     return (!(strcmp(remote_, s)));
     141             : }
     142             : 
     143             : void
     144           0 : PresSubServer::approve(bool flag)
     145             : {
     146           0 :     approved_ = flag;
     147           0 :     JAMI_DBG("Approve Presence_subscription_server for %s: %s.", remote_, flag ? "true" : "false");
     148             :     // attach the real status data
     149           0 :     pjsip_pres_set_status(sub_, pres_->getStatus());
     150           0 : }
     151             : 
     152             : void
     153           0 : PresSubServer::notify()
     154             : {
     155             :     /* Only send NOTIFY once subscription is active. Some subscriptions
     156             :      * may still be in NULL (when app is adding a new buddy while in the
     157             :      * on_incoming_subscribe() callback) or PENDING (when user approval is
     158             :      * being requested) state and we don't send NOTIFY to these subs until
     159             :      * the user accepted the request.
     160             :      */
     161           0 :     if ((pjsip_evsub_get_state(sub_) == PJSIP_EVSUB_STATE_ACTIVE) && (approved_)) {
     162           0 :         JAMI_DBG("Notifying %s.", remote_);
     163             : 
     164             :         pjsip_tx_data* tdata;
     165           0 :         pjsip_pres_set_status(sub_, pres_->getStatus());
     166             : 
     167           0 :         if (pjsip_pres_current_notify(sub_, &tdata) == PJ_SUCCESS) {
     168             :             // add msg header and send
     169           0 :             pres_->fillDoc(tdata, NULL);
     170           0 :             pjsip_pres_send_request(sub_, tdata);
     171             :         } else {
     172           0 :             JAMI_WARN("Unable to create/send NOTIFY");
     173           0 :             pjsip_pres_terminate(sub_, PJ_FALSE);
     174             :         }
     175             :     }
     176           0 : }
     177             : 
     178             : } // namespace jami

Generated by: LCOV version 1.14