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