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
|