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