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 : #ifndef SIPPRESENCE_H 19 : #define SIPPRESENCE_H 20 : 21 : #include <string> 22 : #include <list> 23 : #include <mutex> 24 : 25 : #include "noncopyable.h" 26 : #include "pjsip/sip_types.h" 27 : #include "pjsip/sip_msg.h" 28 : #include "pjsip/sip_multipart.h" 29 : #include "pjsip-simple/publish.h" 30 : #include "pjsip-simple/presence.h" 31 : #include <pj/pool.h> 32 : 33 : #define PRESENCE_FUNCTION_PUBLISH 0 34 : #define PRESENCE_FUNCTION_SUBSCRIBE 1 35 : #define PRESENCE_LOCK_FLAG 1 36 : #define PRESENCE_CLIENT_LOCK_FLAG 2 37 : 38 : namespace jami { 39 : 40 : struct pres_msg_data 41 : { 42 : /** 43 : * Additional message headers as linked list. Application can add 44 : * headers to the list by creating the header, either from the heap/pool 45 : * or from temporary local variable, and add the header using 46 : * linked list operation. See pjsip_apps.c for some sample codes. 47 : */ 48 : pjsip_hdr hdr_list; 49 : 50 : /** 51 : * MIME type of optional message body. 52 : */ 53 : pj_str_t content_type; 54 : 55 : /** 56 : * Optional message body to be added to the message, only when the 57 : * message doesn't have a body. 58 : */ 59 : pj_str_t msg_body; 60 : 61 : /** 62 : * Content type of the multipart body. If application wants to send 63 : * multipart message bodies, it puts the parts in \a parts and set 64 : * the content type in \a multipart_ctype. If the message already 65 : * contains a body, the body will be added to the multipart bodies. 66 : */ 67 : pjsip_media_type multipart_ctype; 68 : 69 : /** 70 : * List of multipart parts. If application wants to send multipart 71 : * message bodies, it puts the parts in \a parts and set the content 72 : * type in \a multipart_ctype. If the message already contains a body, 73 : * the body will be added to the multipart bodies. 74 : */ 75 : pjsip_multipart_part multipart_parts; 76 : }; 77 : 78 : class SIPAccount; 79 : class PresSubClient; 80 : class PresSubServer; 81 : 82 : /** 83 : * @file sippresence.h 84 : * @brief A SIP Presence manages buddy subscription in both PBX and IP2IP contexts. 85 : */ 86 : 87 : class SIPPresence 88 : { 89 : public: 90 : /** 91 : * Constructor 92 : * @param acc the associated sipaccount 93 : */ 94 : SIPPresence(SIPAccount* acc); 95 : /** 96 : * Destructor 97 : */ 98 : ~SIPPresence(); 99 : 100 : /** 101 : * Return associated sipaccount 102 : */ 103 : SIPAccount* getAccount() const; 104 : /** 105 : * Return presence data. 106 : */ 107 : pjsip_pres_status* getStatus(); 108 : /** 109 : * Return presence module ID which is actually the same as the VOIP link 110 : */ 111 : int getModId() const; 112 : /** 113 : * Return a pool for generic functions. 114 : */ 115 : pj_pool_t* getPool() const; 116 : /** 117 : * Activate the module. 118 : * @param enable Flag 119 : */ 120 : void enable(bool enabled); 121 : /** 122 : * Support the presence function publish/subscribe. 123 : * @param function Publish or subscribe to enable 124 : * @param enable Flag 125 : */ 126 : void support(int function, bool enabled); 127 : /** 128 : * Fill xml document, the header and the body 129 : */ 130 : void fillDoc(pjsip_tx_data* tdata, const pres_msg_data* msg_data); 131 : /** 132 : * Modify the presence data 133 : * @param status is basically "open" or "close" 134 : */ 135 : void updateStatus(bool status, const std::string& note); 136 : /** 137 : * Send the presence data in a PUBLISH to the PBX or in a NOTIFY 138 : * to a remote subscriber (IP2IP) 139 : */ 140 : void sendPresence(bool status, const std::string& note); 141 : /** 142 : * Send a signal to the client on DBus. The signal contain the status 143 : * of a remote user. 144 : */ 145 : void reportPresSubClientNotification(std::string_view uri, pjsip_pres_status* status); 146 : /** 147 : * Send a SUBSCRIBE request to PBX/IP2IP 148 : * @param buddyUri Remote user that we want to subscribe 149 : */ 150 : void subscribeClient(const std::string& uri, bool flag); 151 : /** 152 : * Add a buddy in the buddy list. 153 : * @param b PresSubClient pointer 154 : */ 155 : void addPresSubClient(PresSubClient* b); 156 : /** 157 : * Remove a buddy from the list. 158 : * @param b PresSubClient pointer 159 : */ 160 : void removePresSubClient(PresSubClient* b); 161 : 162 : /** 163 : * IP2IP context. 164 : * Process new subscription based on client decision. 165 : * @param flag client decision. 166 : * @param uri uri of the remote subscriber 167 : */ 168 : void approvePresSubServer(const std::string& uri, bool flag); 169 : /** 170 : * IP2IP context. 171 : * Add a server associated to a subscriber in the list. 172 : * @param s PresenceSubcription pointer. 173 : */ 174 : void addPresSubServer(PresSubServer* s); 175 : /** 176 : * IP2IP context. 177 : * Remove a server associated to a subscriber from the list. 178 : * @param s PresenceSubcription pointer. 179 : */ 180 : void removePresSubServer(PresSubServer* s); 181 : /** 182 : * IP2IP context. 183 : * Iterate through the subscriber list and send NOTIFY to each. 184 : */ 185 : void notifyPresSubServer(); 186 : 187 5 : bool isEnabled() { return enabled_; } 188 : 189 : bool isSupported(int function); 190 : 191 0 : const std::list<PresSubClient*>& getClientSubscriptions() const { return sub_client_list_; } 192 : 193 54 : bool isOnline() { return status_; } 194 : 195 54 : std::string getNote() { return note_; } 196 : 197 : void lock(); 198 : bool tryLock(); 199 : void unlock(); 200 : 201 : private: 202 : NON_COPYABLE(SIPPresence); 203 : 204 : static pj_status_t publish(SIPPresence* pres); 205 : static void publish_cb(struct pjsip_publishc_cbparam* param); 206 : static pj_status_t send_publish(SIPPresence* pres); 207 : 208 : pjsip_publishc* publish_sess_; /**< Client publication session.*/ 209 : pjsip_pres_status status_data_; /**< Presence Data to be published.*/ 210 : 211 : pj_bool_t enabled_; 212 : pj_bool_t publish_supported_; /**< the server allow for status publishing */ 213 : pj_bool_t subscribe_supported_; /**< the server allow for buddy subscription */ 214 : 215 : bool status_; /**< Status received from the server*/ 216 : std::string note_; /**< Note received from the server*/ 217 : SIPAccount* acc_; /**< Associated SIP account. */ 218 : std::list<PresSubServer*> sub_server_list_; /**< Subscribers list.*/ 219 : std::list<PresSubClient*> sub_client_list_; /**< Subcribed buddy list.*/ 220 : 221 : std::recursive_mutex mutex_; 222 : pj_caching_pool cp_; 223 : pj_pool_t* pool_; 224 : }; 225 : 226 : } // namespace jami 227 : 228 : #endif