6 * Copyright (C) 2010-2017 SIPE Project <http://sipe.sourceforge.net/>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 * Backend -> SIPE Core API - functions called by backend code
27 ***************** !!! IMPORTANT NOTE FOR BACKEND CODERS !!! *****************
29 * The SIPE core assumes atomicity and is *NOT* thread-safe.
31 * It *does not* protect any of its data structures or code paths with locks!
33 * In no circumstances it must be interrupted by another thread calling
34 * sipe_core_xxx() while the first thread has entered the SIPE core through
35 * a sipe_core_xxx() function.
37 ***************** !!! IMPORTANT NOTE FOR BACKEND CODERS !!! *****************
47 #define SIPE_TRANSPORT_AUTO 0
48 #define SIPE_TRANSPORT_TLS 1
49 #define SIPE_TRANSPORT_TCP 2
52 * Transport connection (public part)
54 * The receiver in the backend fills "buffer". The backend has to zero
55 * terminate the buffer before calling the processing function in the core.
57 * The processing function in the core can remove content from the buffer.
58 * It has to update buffer_used accordingly.
61 struct sipe_transport_connection
{
64 gsize buffer_used
; /* 0 < buffer_used < buffer_length */
65 gsize buffer_length
; /* read-only */
66 guint type
; /* read-only */
67 guint client_port
; /* read-only */
71 * Opaque data type for chat session
73 struct sipe_chat_session
;
76 * File transport (public part)
78 struct sipe_file_transfer
{
79 struct sipe_backend_file_transfer
*backend_private
;
81 void (* ft_init
)(struct sipe_file_transfer
*ft
, const gchar
*filename
,
82 gsize size
, const gchar
*who
);
83 void (* ft_start
)(struct sipe_file_transfer
*ft
, gsize total_size
);
84 gssize (* ft_read
)(struct sipe_file_transfer
*ft
, guchar
**buffer
,
85 gsize bytes_remaining
, gsize bytes_available
);
86 gssize (* ft_write
)(struct sipe_file_transfer
*ft
, const guchar
*buffer
,
88 gboolean (* ft_end
)(struct sipe_file_transfer
*ft
);
89 void (* ft_request_denied
)(struct sipe_file_transfer
*ft
);
90 void (* ft_cancelled
)(struct sipe_file_transfer
*ft
);
94 * Opaque data type for backend private data.
95 * The backend is responsible to allocate and free it.
97 struct sipe_backend_private
;
100 * SIP transport authentication scheme
102 #define SIPE_AUTHENTICATION_TYPE_UNSET 0
103 #define SIPE_AUTHENTICATION_TYPE_BASIC 1 /* internal use only */
104 #define SIPE_AUTHENTICATION_TYPE_NTLM 2
105 #define SIPE_AUTHENTICATION_TYPE_KERBEROS 3
106 #define SIPE_AUTHENTICATION_TYPE_NEGOTIATE 4 /* internal use only */
107 #define SIPE_AUTHENTICATION_TYPE_TLS_DSK 5
108 #define SIPE_AUTHENTICATION_TYPE_AUTOMATIC 6 /* always last */
113 /* user disabled calendar information publishing */
114 #define SIPE_CORE_FLAG_DONT_PUBLISH 0x00000001
115 /* user enabled insecure buddy icon download from web */
116 #define SIPE_CORE_FLAG_ALLOW_WEB_PHOTO 0x00000002
118 #define SIPE_CORE_FLAG_IS(flag) \
119 ((sipe_public->flags & SIPE_CORE_FLAG_ ## flag) == SIPE_CORE_FLAG_ ## flag)
120 #define SIPE_CORE_FLAG_SET(flag) \
121 (sipe_public->flags |= SIPE_CORE_FLAG_ ## flag)
122 #define SIPE_CORE_FLAG_UNSET(flag) \
123 (sipe_public->flags &= ~SIPE_CORE_FLAG_ ## flag)
126 * Byte length of cryptographic key for call encryption.
128 #define SIPE_SRTP_KEY_LEN 30
131 * Public part of the Sipe data structure
133 * This part contains the information needed by the core and the backend.
135 struct sipe_core_public
{
137 * This points to the private data for the backend.
138 * The backend is responsible to allocate and free it.
140 struct sipe_backend_private
*backend_private
;
142 /* flags (see above) */
145 /* user information */
149 /* server information */
150 /* currently nothing */
154 * Initialize & destroy functions for the SIPE core
155 * Should be called on loading and unloading of the plugin.
157 void sipe_core_init(const char *locale_dir
);
158 void sipe_core_destroy(void);
160 /** Utility functions exported by the core to backends ***********************/
161 gboolean
sipe_strequal(const gchar
*left
, const gchar
*right
);
162 gboolean
sipe_strcase_equal(const gchar
*left
, const gchar
*right
);
165 sipe_utils_nameval_add(GSList
*list
, const gchar
*name
, const gchar
*value
);
168 sipe_utils_nameval_find(const GSList
*list
, const gchar
*name
);
171 sipe_utils_nameval_find_instance(const GSList
*list
, const gchar
*name
, int which
);
174 sipe_utils_nameval_free(GSList
*list
);
176 gchar
*sip_uri_from_name(const gchar
*name
);
177 gchar
*sip_uri_if_valid(const gchar
*string
);
179 /*****************************************************************************/
182 * Other functions (need to be sorted once structure becomes clear.
185 /* Get translated about string. Must be g_free'd(). */
186 gchar
*sipe_core_about(void);
188 /* Execute a scheduled action */
189 void sipe_core_schedule_execute(gpointer data
);
192 void sipe_core_update_calendar(struct sipe_core_public
*sipe_public
);
193 void sipe_core_reset_status(struct sipe_core_public
*sipe_public
);
196 void sipe_core_change_access_level_from_container(struct sipe_core_public
*sipe_public
,
198 void sipe_core_change_access_level_for_domain(struct sipe_core_public
*sipe_public
,
204 * - core: maps this to OCS protocol values
205 * maps this to translated descriptions
206 * - backend: maps this to backend status values
207 * backend token string can be used as "ID" in protocol
209 * This is passed back-and-forth and therefore defined as list, not as enum.
210 * Can be used as array index
212 #define SIPE_ACTIVITY_UNSET 0
213 #define SIPE_ACTIVITY_AVAILABLE 1
214 #define SIPE_ACTIVITY_ONLINE 2
215 #define SIPE_ACTIVITY_INACTIVE 3
216 #define SIPE_ACTIVITY_BUSY 4
217 #define SIPE_ACTIVITY_BUSYIDLE 5
218 #define SIPE_ACTIVITY_DND 6
219 #define SIPE_ACTIVITY_BRB 7
220 #define SIPE_ACTIVITY_AWAY 8
221 #define SIPE_ACTIVITY_LUNCH 9
222 #define SIPE_ACTIVITY_INVISIBLE 10
223 #define SIPE_ACTIVITY_OFFLINE 11
224 #define SIPE_ACTIVITY_ON_PHONE 12
225 #define SIPE_ACTIVITY_IN_CONF 13
226 #define SIPE_ACTIVITY_IN_MEETING 14
227 #define SIPE_ACTIVITY_OOF 15
228 #define SIPE_ACTIVITY_URGENT_ONLY 16
229 #define SIPE_ACTIVITY_NUM_TYPES 17 /* use to define array size */
231 const gchar
*sipe_core_activity_description(guint type
);
235 * Get status text for buddy.
237 * @param sipe_public Sipe core public data structure.
238 * @param uri SIP URI of the buddy
239 * @param activity activity value for buddy
240 * @param status_text backend-specific buddy status text for activity.
242 * @return HTML status text for the buddy or NULL. Must be g_free()'d.
244 gchar
*sipe_core_buddy_status(struct sipe_core_public
*sipe_public
,
247 const gchar
*status_text
);
249 void sipe_core_buddy_got_status(struct sipe_core_public
*sipe_public
,
254 * Trigger generation of buddy information label/text pairs
256 * @param sipe_public Sipe core public data structure.
257 * @param uri SIP URI of the buddy
258 * @param status_text backend-specific buddy status text for ID.
259 * @param is_online backend considers buddy to be online.
260 * @param tooltip opaque backend identifier for tooltip info. This is the
261 * parameter given to @c sipe_backend_buddy_tooltip_add()
263 struct sipe_backend_buddy_tooltip
;
264 void sipe_core_buddy_tooltip_info(struct sipe_core_public
*sipe_public
,
266 const gchar
*status_name
,
268 struct sipe_backend_buddy_tooltip
*tooltip
);
273 * @param sipe_public Sipe core public data structure
274 * @param uri SIP URI of the buddy
275 * @param group_name backend-specific group name
277 void sipe_core_buddy_add(struct sipe_core_public
*sipe_public
,
279 const gchar
*group_name
);
284 * @param sipe_public Sipe core public data structure
285 * @param uri SIP URI of the buddy
286 * @param group_name backend-specific group name
288 void sipe_core_buddy_remove(struct sipe_core_public
*sipe_public
,
290 const gchar
*group_name
);
292 void sipe_core_contact_allow_deny(struct sipe_core_public
*sipe_public
,
295 void sipe_core_group_set_alias(struct sipe_core_public
*sipe_public
,
302 struct sipe_core_public
*sipe_core_allocate(const gchar
*signin_name
,
304 const gchar
*login_account
,
305 const gchar
*password
,
307 const gchar
*email_url
,
308 const gchar
**errmsg
);
309 void sipe_core_deallocate(struct sipe_core_public
*sipe_public
);
312 * Check if SIP authentication scheme requires a password
314 * NOTE: this can be called *BEFORE* @c sipe_core_allocate()!
316 * @param authentication SIP transport authentication type
317 * @param sso TRUE if user selected Single-Sign On
319 * @return TRUE if password is required
321 gboolean
sipe_core_transport_sip_requires_password(guint authentication
,
325 * Connect to SIP server
327 void sipe_core_transport_sip_connect(struct sipe_core_public
*sipe_public
,
329 guint authentication
,
334 * Get SIP server host name
336 * @param sipe_public Sipe core public data structure
338 * @return server host name (may be @c NULL if not fully connected yet)
340 const gchar
*sipe_core_transport_sip_server_name(struct sipe_core_public
*sipe_public
);
343 * Get chat ID, f.ex. group chat URI
345 const gchar
*sipe_core_chat_id(struct sipe_core_public
*sipe_public
,
346 struct sipe_chat_session
*chat_session
);
349 * Get type of chat session, e.g. group chat
351 #define SIPE_CHAT_TYPE_UNKNOWN 0
352 #define SIPE_CHAT_TYPE_MULTIPARTY 1
353 #define SIPE_CHAT_TYPE_CONFERENCE 2
354 #define SIPE_CHAT_TYPE_GROUPCHAT 3
355 guint
sipe_core_chat_type(struct sipe_chat_session
*chat_session
);
360 void sipe_core_chat_invite(struct sipe_core_public
*sipe_public
,
361 struct sipe_chat_session
*chat_session
,
365 * Rejoin a chat after connection re-establishment
367 void sipe_core_chat_rejoin(struct sipe_core_public
*sipe_public
,
368 struct sipe_chat_session
*chat_session
);
373 void sipe_core_chat_leave(struct sipe_core_public
*sipe_public
,
374 struct sipe_chat_session
*chat_session
);
377 * Send message to chat
379 void sipe_core_chat_send(struct sipe_core_public
*sipe_public
,
380 struct sipe_chat_session
*chat_session
,
384 * Check chat lock status
387 SIPE_CHAT_LOCK_STATUS_NOT_ALLOWED
= 0,
388 SIPE_CHAT_LOCK_STATUS_UNLOCKED
,
389 SIPE_CHAT_LOCK_STATUS_LOCKED
390 } sipe_chat_lock_status
;
391 sipe_chat_lock_status
sipe_core_chat_lock_status(struct sipe_core_public
*sipe_public
,
392 struct sipe_chat_session
*chat_session
);
397 void sipe_core_chat_modify_lock(struct sipe_core_public
*sipe_public
,
398 struct sipe_chat_session
*chat_session
,
399 const gboolean locked
);
402 * Create new session with Focus URI
404 * @param sipe_public (in) SIPE core data.
405 * @param focus_uri (in) focus URI string
407 void sipe_core_conf_create(struct sipe_core_public
*sipe_public
,
408 const gchar
*focus_uri
,
409 const gchar
*organizer
,
410 const gchar
*meeting_id
);
412 /* buddy menu callback: parameter == chat_session */
413 void sipe_core_conf_make_leader(struct sipe_core_public
*sipe_public
,
415 const gchar
*buddy_name
);
416 void sipe_core_conf_remove_from(struct sipe_core_public
*sipe_public
,
418 const gchar
*buddy_name
);
421 sipe_core_conf_entry_info(struct sipe_core_public
*sipe_public
,
422 struct sipe_chat_session
*chat_session
);
425 * Checks if given chat session has an open RDP client window.
427 * @param sipe_public (in) SIPE core data.
428 * @param chat_session (in) chat session structure
430 * @return @c TRUE if RDP session is in progress.
433 sipe_core_conf_is_viewing_appshare(struct sipe_core_public
*sipe_public
,
434 struct sipe_chat_session
*chat_session
);
436 /* call control (CSTA) */
437 void sipe_core_buddy_make_call(struct sipe_core_public
*sipe_public
,
441 void sipe_core_media_initiate_call(struct sipe_core_public
*sipe_public
,
442 const char *participant
,
443 gboolean with_video
);
444 struct sipe_media_call
;
445 struct sipe_media_stream
*
446 sipe_core_media_get_stream_by_id(struct sipe_media_call
*call
, const gchar
*id
);
449 * Called by media backend after a candidate pair for a media stream component
450 * has been established.
452 * @param stream (in) SIPE media stream data.
455 sipe_core_media_stream_candidate_pair_established(struct sipe_media_stream
*stream
);
458 sipe_core_media_stream_readable(struct sipe_media_stream
*stream
);
461 * Called by media backend when a @c SIPE_MEDIA_APPLICATION stream changes its
462 * state between writable and unwritable.
464 * @param stream (in) SIPE media stream data.
465 * @param writable (in) @c TRUE if stream has become writable, otherwise
469 sipe_core_media_stream_writable(struct sipe_media_stream
*stream
,
473 * Called by media backend when @c stream has ended and should be destroyed.
475 * @param stream (in) SIPE media stream data.
478 sipe_core_media_stream_end(struct sipe_media_stream
*stream
);
481 * Connects to a conference call specified by given chat session
483 * @param sipe_public (in) SIPE core data.
484 * @param chat_session (in) chat session structure
486 void sipe_core_media_connect_conference(struct sipe_core_public
*sipe_public
,
487 struct sipe_chat_session
*chat_session
);
490 * Retrieves the media call in progress
492 * The function checks only for voice and video calls, ignoring other types of
495 * @param sipe_public (in) SIPE core data.
497 * @return @c sipe_media_call structure or @c NULL if call is not in progress.
499 struct sipe_media_call
*
500 sipe_core_media_get_call(struct sipe_core_public
*sipe_public
);
503 * Initiates a call with given phone number
505 * @param sipe_public (in) SIPE core data.
506 * @parem phone_number (in) a mobile or landline phone number, i.e. +46123456
508 void sipe_core_media_phone_call(struct sipe_core_public
*sipe_public
,
509 const gchar
*phone_number
);
512 * Checks voice quality by making a call to the test service
514 * @param sipe_public (in) SIPE core data.
516 void sipe_core_media_test_call(struct sipe_core_public
*sipe_public
);
519 struct sipe_file_transfer
*
520 sipe_core_ft_create_outgoing(struct sipe_core_public
*sipe_public
,
524 /* application sharing */
527 * Connects to a meeting's presentation
529 * @param sipe_public (in) SIPE core data.
530 * @param chat_session (in) chat session structure
531 * @param user_must_accept (in) @c TRUE if user should be shown accept/decline
532 * dialog before the action can proceed.
534 void sipe_core_appshare_connect_conference(struct sipe_core_public
*sipe_public
,
535 struct sipe_chat_session
*chat_session
,
536 gboolean user_must_accept
);
539 gboolean
sipe_core_groupchat_query_rooms(struct sipe_core_public
*sipe_public
);
540 void sipe_core_groupchat_join(struct sipe_core_public
*sipe_public
,
544 void sipe_core_im_send(struct sipe_core_public
*sipe_public
,
547 void sipe_core_im_close(struct sipe_core_public
*sipe_public
,
551 void sipe_core_user_feedback_typing(struct sipe_core_public
*sipe_public
,
555 void sipe_core_user_ask_cb(gpointer key
, gboolean accepted
);
558 void sipe_core_group_rename(struct sipe_core_public
*sipe_public
,
559 const gchar
*old_name
,
560 const gchar
*new_name
);
562 void sipe_core_group_remove(struct sipe_core_public
*sipe_public
,
566 void sipe_core_buddy_group(struct sipe_core_public
*sipe_public
,
568 const gchar
*old_group_name
,
569 const gchar
*new_group_name
);
571 struct sipe_backend_search_token
;
572 void sipe_core_buddy_search(struct sipe_core_public
*sipe_public
,
573 struct sipe_backend_search_token
*token
,
574 const gchar
*given_name
,
575 const gchar
*surname
,
578 const gchar
*company
,
579 const gchar
*country
);
581 void sipe_core_buddy_get_info(struct sipe_core_public
*sipe_public
,
584 void sipe_core_buddy_new_chat(struct sipe_core_public
*sipe_public
,
586 void sipe_core_buddy_send_email(struct sipe_core_public
*sipe_public
,
589 struct sipe_backend_buddy_menu
;
590 struct sipe_backend_buddy_menu
*sipe_core_buddy_create_menu(struct sipe_core_public
*sipe_public
,
591 const gchar
*buddy_name
,
592 struct sipe_backend_buddy_menu
*menu
);
594 void sipe_core_buddy_menu_free(struct sipe_core_public
*sipe_public
);
597 * User/Machine has changed the user status
599 * NOTE: must *NEVER* be triggered by @c sipe_backend_status_and_note()!
601 * @param sipe_public The handle representing the protocol instance
602 * @param set_by_user @c TRUE if status has been changed by user
603 * @param activity New activity
604 * @param message New note text
606 void sipe_core_status_set(struct sipe_core_public
*sipe_public
,
607 gboolean set_by_user
,
611 #define SIPE_MSRTP_VSR_HEADER_LEN 20
612 #define SIPE_MSRTP_VSR_ENTRY_LEN 0x44
613 #define SIPE_MSRTP_VSR_FCI_WORDLEN \
614 (SIPE_MSRTP_VSR_HEADER_LEN + SIPE_MSRTP_VSR_ENTRY_LEN) / 4
616 #define SIPE_MSRTP_VSR_SOURCE_ANY 0xFFFFFFFE
617 #define SIPE_MSRTP_VSR_SOURCE_NONE 0xFFFFFFFF
620 * Fills @buffer with Video Source Request described in [MS-RTP] 2.2.12.2.
622 * @param buffer (out) destination the VSR will be written to. The byte length
623 * of @c buffer MUST be at least @c SIPE_MSRTP_VSR_HEADER_LEN +
624 * @c SIPE_MSRTP_VSR_ENTRY_LEN.
625 * @param payload_type (in) payload ID of the codec negotiated with the peer.
627 void sipe_core_msrtp_write_video_source_request(guint8
*buffer
,
628 guint8 payload_type
);
631 * Fills @buffer with customized Payload Content Scalability Information packet
632 * described in [MS-H264PF] consisting of a Stream Layout SEI Message (section
633 * 2.2.5) and a Bitstream Info SEI Message (section 2.2.7).
635 * @param buffer (out) destination the PACSI will be written to.
636 * @param nal_count (in) number of NAL units this packet describes.
638 * @return Byte length of the PACSI packet.
640 gsize
sipe_core_msrtp_write_video_scalability_info(guint8
*buffer
,