Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
liblinphone
Commits
220c4713
Commit
220c4713
authored
Jun 12, 2013
by
Ghislain MARY
Browse files
Use xml parser to get presence status.
parent
79c72fc8
Changes
10
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
998 additions
and
81 deletions
+998
-81
coreapi/Makefile.am
coreapi/Makefile.am
+1
-1
coreapi/bellesip_sal/sal_impl.c
coreapi/bellesip_sal/sal_impl.c
+2
-0
coreapi/bellesip_sal/sal_op_presence.c
coreapi/bellesip_sal/sal_op_presence.c
+36
-35
coreapi/callbacks.c
coreapi/callbacks.c
+7
-2
coreapi/friend.c
coreapi/friend.c
+87
-3
coreapi/linphonefriend.h
coreapi/linphonefriend.h
+8
-0
coreapi/linphonepresence.h
coreapi/linphonepresence.h
+80
-0
coreapi/presence.c
coreapi/presence.c
+768
-37
coreapi/private.h
coreapi/private.h
+3
-2
include/sal/sal.h
include/sal/sal.h
+6
-1
No files found.
coreapi/Makefile.am
View file @
220c4713
...
...
@@ -16,7 +16,7 @@ CLEANFILES=$(GITVERSION_FILE)
## Process this file with automake to produce Makefile.in
linphone_includedir
=
$(includedir)
/linphone
linphone_include_HEADERS
=
linphonecore.h linphonefriend.h linphonecore_utils.h lpconfig.h sipsetup.h
event.h
linphone_include_HEADERS
=
linphonecore.h linphonefriend.h
linphonepresence.h
linphonecore_utils.h lpconfig.h sipsetup.h event.h
if
BUILD_TUNNEL
linphone_include_HEADERS
+=
linphone_tunnel.h
...
...
coreapi/bellesip_sal/sal_impl.c
View file @
220c4713
...
...
@@ -486,6 +486,8 @@ void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
ctx
->
callbacks
.
subscribe_received
=
(
SalOnSubscribeReceived
)
unimplemented_stub
;
if
(
ctx
->
callbacks
.
subscribe_closed
==
NULL
)
ctx
->
callbacks
.
subscribe_closed
=
(
SalOnSubscribeClosed
)
unimplemented_stub
;
if
(
ctx
->
callbacks
.
parse_presence_requested
==
NULL
)
ctx
->
callbacks
.
parse_presence_requested
=
(
SalOnParsePresenceRequested
)
unimplemented_stub
;
if
(
ctx
->
callbacks
.
notify_presence
==
NULL
)
ctx
->
callbacks
.
notify_presence
=
(
SalOnNotifyPresence
)
unimplemented_stub
;
if
(
ctx
->
callbacks
.
subscribe_presence_received
==
NULL
)
...
...
coreapi/bellesip_sal/sal_op_presence.c
View file @
220c4713
...
...
@@ -497,6 +497,26 @@ static void presence_process_transaction_terminated(void *user_ctx, const belle_
ms_message
(
"presence_process_transaction_terminated not implemented yet"
);
}
static
SalPresenceModel
*
process_presence_notification
(
SalOp
*
op
,
belle_sip_request_t
*
req
)
{
belle_sip_header_content_type_t
*
content_type
=
belle_sip_message_get_header_by_type
(
BELLE_SIP_MESSAGE
(
req
),
belle_sip_header_content_type_t
);
belle_sip_header_content_length_t
*
content_length
=
belle_sip_message_get_header_by_type
(
BELLE_SIP_MESSAGE
(
req
),
belle_sip_header_content_length_t
);
const
char
*
body
=
belle_sip_message_get_body
(
BELLE_SIP_MESSAGE
(
req
));
SalPresenceModel
*
result
=
NULL
;
if
((
content_type
==
NULL
)
||
(
content_length
==
NULL
))
return
NULL
;
if
(
belle_sip_header_content_length_get_content_length
(
content_length
)
==
0
)
return
NULL
;
op
->
base
.
root
->
callbacks
.
parse_presence_requested
(
op
,
belle_sip_header_content_type_get_type
(
content_type
),
belle_sip_header_content_type_get_subtype
(
content_type
),
body
,
&
result
);
return
result
;
}
static
void
presence_process_request_event
(
void
*
op_base
,
const
belle_sip_request_event_t
*
event
)
{
SalOp
*
op
=
(
SalOp
*
)
op_base
;
belle_sip_server_transaction_t
*
server_transaction
=
belle_sip_provider_create_server_transaction
(
op
->
base
.
root
->
prov
,
belle_sip_request_event_get_request
(
event
));
...
...
@@ -505,7 +525,7 @@ static void presence_process_request_event(void *op_base, const belle_sip_reques
belle_sip_header_subscription_state_t
*
subscription_state_header
=
belle_sip_message_get_header_by_type
(
req
,
belle_sip_header_subscription_state_t
);
belle_sip_header_expires_t
*
expires
=
belle_sip_message_get_header_by_type
(
req
,
belle_sip_header_expires_t
);
const
char
*
body
=
belle_sip_message_get_body
(
BELLE_SIP_MESSAGE
(
req
));
SalPresence
Status
estatus
=
SalPresenceOffline
;
SalPresence
Model
*
presence_model
=
NULL
;
SalSubscribeStatus
sub_state
;
belle_sip_response_t
*
resp
;
belle_sip_object_ref
(
server_transaction
);
...
...
@@ -536,41 +556,22 @@ static void presence_process_request_event(void *op_base, const belle_sip_reques
ms_error
(
"No body in NOTIFY received from [%s]"
,
sal_op_get_from
(
op
));
return
;
}
if
(
strstr
(
body
,
"pending"
)
!=
NULL
){
estatus
=
SalPresenceOffline
;
}
else
if
(
strstr
(
body
,
"busy"
)
!=
NULL
){
estatus
=
SalPresenceBusy
;
}
else
if
(
strstr
(
body
,
"berightback"
)
!=
NULL
||
strstr
(
body
,
"in-transit"
)
!=
NULL
){
estatus
=
SalPresenceBerightback
;
}
else
if
(
strstr
(
body
,
"away"
)
!=
NULL
||
strstr
(
body
,
"idle"
)){
estatus
=
SalPresenceAway
;
}
else
if
(
strstr
(
body
,
"onthephone"
)
!=
NULL
||
strstr
(
body
,
"on-the-phone"
)
!=
NULL
){
estatus
=
SalPresenceOnthephone
;
}
else
if
(
strstr
(
body
,
"outtolunch"
)
!=
NULL
||
strstr
(
body
,
"lunch"
)
!=
NULL
||
strstr
(
body
,
"meal"
)
!=
NULL
){
estatus
=
SalPresenceOuttolunch
;
}
else
if
(
strstr
(
body
,
"closed"
)
!=
NULL
){
estatus
=
SalPresenceOffline
;
}
else
if
((
strstr
(
body
,
"online"
)
!=
NULL
)
||
(
strstr
(
body
,
"open"
)
!=
NULL
))
{
estatus
=
SalPresenceOnline
;
}
else
if
((
strstr
(
body
,
"vacation"
)
!=
NULL
))
{
estatus
=
SalPresenceOnVacation
;
}
else
{
estatus
=
SalPresenceOffline
;
}
ms_message
(
"We are notified that [%s] has online status [%s]"
,
sal_op_get_to
(
op
),
sal_presence_status_to_string
(
estatus
));
presence_model
=
process_presence_notification
(
op
,
req
);
if
(
presence_model
!=
NULL
)
{
/* Presence notification body parsed successfully. */
if
(
!
subscription_state_header
||
strcasecmp
(
BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED
,
belle_sip_header_subscription_state_get_state
(
subscription_state_header
))
==
0
)
{
sub_state
=
SalSubscribeTerminated
;
ms_message
(
"
And o
utgoing subscription terminated by remote [%s]"
,
sal_op_get_to
(
op
));
}
else
ms_message
(
"
O
utgoing subscription terminated by remote [%s]"
,
sal_op_get_to
(
op
));
}
else
{
sub_state
=
SalSubscribeActive
;
op
->
base
.
root
->
callbacks
.
notify_presence
(
op
,
sub_state
,
estatus
,
NULL
);
resp
=
sal_op_create_response_from_request
(
op
,
req
,
200
);
}
op
->
base
.
root
->
callbacks
.
notify_presence
(
op
,
sub_state
,
presence_model
,
NULL
);
resp
=
sal_op_create_response_from_request
(
op
,
req
,
200
);
}
else
{
/* Formatting error in presence notification body. */
ms_error
(
"Wrongly formatted presence notification received"
);
resp
=
sal_op_create_response_from_request
(
op
,
req
,
400
);
}
belle_sip_server_transaction_send_response
(
server_transaction
,
resp
);
}
else
if
(
strcmp
(
"SUBSCRIBE"
,
belle_sip_request_get_method
(
req
))
==
0
)
{
/*either a refresh of an unsubscribe*/
...
...
coreapi/callbacks.c
View file @
220c4713
...
...
@@ -877,9 +877,13 @@ static void text_received(SalOp *op, const SalMessage *msg){
}
}
static
void
notify_presence
(
SalOp
*
op
,
SalSubscribeStatus
ss
,
SalPresenceStatus
status
,
const
char
*
msg
){
static
void
parse_presence_requested
(
SalOp
*
op
,
const
char
*
content_type
,
const
char
*
content_subtype
,
const
char
*
body
,
SalPresenceModel
**
result
)
{
linphone_notify_parse_presence
(
op
,
content_type
,
content_subtype
,
body
,
result
);
}
static
void
notify_presence
(
SalOp
*
op
,
SalSubscribeStatus
ss
,
SalPresenceModel
*
model
,
const
char
*
msg
){
LinphoneCore
*
lc
=
(
LinphoneCore
*
)
sal_get_user_pointer
(
sal_op_get_sal
(
op
));
linphone_notify_recv
(
lc
,
op
,
ss
,
status
);
linphone_notify_recv
(
lc
,
op
,
ss
,
model
);
}
static
void
subscribe_presence_received
(
SalOp
*
op
,
const
char
*
from
){
...
...
@@ -1085,6 +1089,7 @@ SalCallbacks linphone_sal_callbacks={
notify
,
subscribe_presence_received
,
subscribe_presence_closed
,
parse_presence_requested
,
notify_presence
,
ping_reply
,
auth_requested
,
...
...
coreapi/friend.c
View file @
220c4713
...
...
@@ -119,7 +119,7 @@ void __linphone_friend_do_subscribe(LinphoneFriend *fr){
if
(
fr
->
outsub
==
NULL
){
/* people for which we don't have yet an answer should appear as offline */
fr
->
status
=
LinphoneStatusOffline
;
fr
->
presence
=
NULL
;
/*
if (fr->lc->vtable.notify_recv)
fr->lc->vtable.notify_recv(fr->lc,(LinphoneFriend*)fr);
...
...
@@ -138,7 +138,7 @@ void __linphone_friend_do_subscribe(LinphoneFriend *fr){
LinphoneFriend
*
linphone_friend_new
(){
LinphoneFriend
*
obj
=
ms_new0
(
LinphoneFriend
,
1
);
obj
->
pol
=
LinphoneSPAccept
;
obj
->
status
=
LinphoneStatusOffline
;
obj
->
presence
=
NULL
;
obj
->
subscribe
=
TRUE
;
return
obj
;
}
...
...
@@ -304,6 +304,7 @@ void linphone_friend_destroy(LinphoneFriend *lf){
sal_op_release
(
lf
->
outsub
);
lf
->
outsub
=
NULL
;
}
if
(
lf
->
presence
!=
NULL
)
linphone_presence_model_delete
(
lf
->
presence
);
if
(
lf
->
uri
!=
NULL
)
linphone_address_destroy
(
lf
->
uri
);
if
(
lf
->
info
!=
NULL
)
buddy_info_free
(
lf
->
info
);
ms_free
(
lf
);
...
...
@@ -322,7 +323,90 @@ LinphoneSubscribePolicy linphone_friend_get_inc_subscribe_policy(const LinphoneF
}
LinphoneOnlineStatus
linphone_friend_get_status
(
const
LinphoneFriend
*
lf
){
return
lf
->
status
;
LinphoneOnlineStatus
online_status
=
LinphoneStatusOffline
;
LinphonePresenceBasicStatus
basic_status
=
LinphonePresenceBasicStatusClosed
;
LinphonePresenceActivity
activity
=
LinphonePresenceActivityUnknown
;
char
*
activity_description
=
NULL
;
unsigned
int
nb_activities
=
0
;
int
err
=
0
;
if
(
lf
->
presence
!=
NULL
)
{
basic_status
=
linphone_presence_model_get_basic_status
(
lf
->
presence
);
nb_activities
=
linphone_presence_model_nb_activities
(
lf
->
presence
);
online_status
=
(
basic_status
==
LinphonePresenceBasicStatusOpen
)
?
LinphoneStatusOnline
:
LinphoneStatusOffline
;
if
(
nb_activities
>
1
)
{
char
*
tmp
=
NULL
;
const
LinphoneAddress
*
addr
=
linphone_friend_get_address
(
lf
);
if
(
addr
)
tmp
=
linphone_address_as_string
(
addr
);
ms_warning
(
"Friend %s has several activities, get status from the first one"
,
tmp
?
tmp
:
"unknown"
);
if
(
tmp
)
ms_free
(
tmp
);
nb_activities
=
1
;
}
if
(
nb_activities
==
1
)
{
err
=
linphone_presence_model_get_activity
(
lf
->
presence
,
0
,
&
activity
,
&
activity_description
);
if
(
err
==
0
)
{
switch
(
activity
)
{
case
LinphonePresenceActivityBreakfast
:
case
LinphonePresenceActivityDinner
:
case
LinphonePresenceActivityLunch
:
case
LinphonePresenceActivityMeal
:
online_status
=
LinphoneStatusOutToLunch
;
break
;
case
LinphonePresenceActivityAppointment
:
case
LinphonePresenceActivityMeeting
:
case
LinphonePresenceActivityPerformance
:
case
LinphonePresenceActivityPresentation
:
case
LinphonePresenceActivitySpectator
:
case
LinphonePresenceActivityWorking
:
case
LinphonePresenceActivityWorship
:
online_status
=
LinphoneStatusDoNotDisturb
;
break
;
case
LinphonePresenceActivityAway
:
case
LinphonePresenceActivitySleeping
:
online_status
=
LinphoneStatusAway
;
break
;
case
LinphonePresenceActivityHoliday
:
case
LinphonePresenceActivityTravel
:
case
LinphonePresenceActivityVacation
:
online_status
=
LinphoneStatusVacation
;
break
;
case
LinphonePresenceActivityBusy
:
case
LinphonePresenceActivityLookingForWork
:
case
LinphonePresenceActivityPlaying
:
case
LinphonePresenceActivityShopping
:
case
LinphonePresenceActivityTV
:
online_status
=
LinphoneStatusBusy
;
break
;
case
LinphonePresenceActivityInTransit
:
case
LinphonePresenceActivitySteering
:
online_status
=
LinphoneStatusBeRightBack
;
break
;
case
LinphonePresenceActivityOnThePhone
:
online_status
=
LinphoneStatusOnThePhone
;
break
;
case
LinphonePresenceActivityOther
:
case
LinphonePresenceActivityPermanentAbsence
:
online_status
=
LinphoneStatusMoved
;
break
;
case
LinphonePresenceActivityUnknown
:
break
;
}
}
}
}
return
online_status
;
}
LinphonePresenceModel
*
linphone_friend_get_presence
(
LinphoneFriend
*
lf
)
{
return
lf
->
presence
;
}
void
linphone_friend_set_presence
(
LinphoneFriend
*
lf
,
LinphonePresenceModel
*
model
)
{
if
(
lf
->
presence
!=
NULL
)
{
linphone_presence_model_delete
(
lf
->
presence
);
}
lf
->
presence
=
model
;
}
BuddyInfo
*
linphone_friend_get_info
(
const
LinphoneFriend
*
lf
){
...
...
coreapi/linphonefriend.h
View file @
220c4713
...
...
@@ -19,9 +19,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef LINPHONEFRIEND_H_
#define LINPHONEFRIEND_H_
#include "linphonepresence.h"
#ifdef __cplusplus
extern
"C"
{
#endif
/**
* @addtogroup buddy_list
* @{
...
...
@@ -206,6 +210,10 @@ LINPHONE_PUBLIC void linphone_friend_done(LinphoneFriend *fr);
* @return #LinphoneOnlineStatus
*/
LinphoneOnlineStatus
linphone_friend_get_status
(
const
LinphoneFriend
*
lf
);
LinphonePresenceModel
*
linphone_friend_get_presence
(
LinphoneFriend
*
lf
);
void
linphone_friend_set_presence
(
LinphoneFriend
*
lf
,
LinphonePresenceModel
*
presence
);
BuddyInfo
*
linphone_friend_get_info
(
const
LinphoneFriend
*
lf
);
void
linphone_friend_set_ref_key
(
LinphoneFriend
*
lf
,
const
char
*
key
);
const
char
*
linphone_friend_get_ref_key
(
const
LinphoneFriend
*
lf
);
...
...
coreapi/linphonepresence.h
0 → 100644
View file @
220c4713
/*
linphonepresence.h
Copyright (C) 2010-2013 Belledonne Communications SARL
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef LINPHONEPRESENCE_H_
#define LINPHONEPRESENCE_H_
#ifdef __cplusplus
extern
"C"
{
#endif
/** Basic status as defined in section 4.1.4 of RFC 3863 */
typedef
enum
LinphonePresenceBasicStatus
{
LinphonePresenceBasicStatusOpen
,
LinphonePresenceBasicStatusClosed
}
LinphonePresenceBasicStatus
;
/** Activities as defined in section 3.2 of RFC 4480 */
typedef
enum
LinphonePresenceActivity
{
LinphonePresenceActivityAppointment
,
LinphonePresenceActivityAway
,
LinphonePresenceActivityBreakfast
,
LinphonePresenceActivityBusy
,
LinphonePresenceActivityDinner
,
LinphonePresenceActivityHoliday
,
LinphonePresenceActivityInTransit
,
LinphonePresenceActivityLookingForWork
,
LinphonePresenceActivityLunch
,
LinphonePresenceActivityMeal
,
LinphonePresenceActivityMeeting
,
LinphonePresenceActivityOnThePhone
,
LinphonePresenceActivityOther
,
LinphonePresenceActivityPerformance
,
LinphonePresenceActivityPermanentAbsence
,
LinphonePresenceActivityPlaying
,
LinphonePresenceActivityPresentation
,
LinphonePresenceActivityShopping
,
LinphonePresenceActivitySleeping
,
LinphonePresenceActivitySpectator
,
LinphonePresenceActivitySteering
,
LinphonePresenceActivityTravel
,
LinphonePresenceActivityTV
,
LinphonePresenceActivityUnknown
,
LinphonePresenceActivityVacation
,
LinphonePresenceActivityWorking
,
LinphonePresenceActivityWorship
}
LinphonePresenceActivity
;
struct
_LinphonePresenceModel
;
typedef
struct
_LinphonePresenceModel
LinphonePresenceModel
;
LINPHONE_PUBLIC
LinphonePresenceModel
*
linphone_presence_model_new
(
void
);
LINPHONE_PUBLIC
void
linphone_presence_model_delete
(
LinphonePresenceModel
*
model
);
LINPHONE_PUBLIC
LinphonePresenceBasicStatus
linphone_presence_model_get_basic_status
(
const
LinphonePresenceModel
*
model
);
LINPHONE_PUBLIC
unsigned
int
linphone_presence_model_nb_activities
(
const
LinphonePresenceModel
*
model
);
LINPHONE_PUBLIC
int
linphone_presence_model_get_activity
(
const
LinphonePresenceModel
*
model
,
unsigned
int
idx
,
LinphonePresenceActivity
*
activity
,
char
**
description
);
#ifdef __cplusplus
}
#endif
#endif
/* LINPHONEPRESENCE_H_ */
coreapi/presence.c
View file @
220c4713
This diff is collapsed.
Click to expand it.
coreapi/private.h
View file @
220c4713
...
...
@@ -290,7 +290,8 @@ SalPresenceStatus linphone_online_status_to_sal(LinphoneOnlineStatus os);
void
linphone_process_authentication
(
LinphoneCore
*
lc
,
SalOp
*
op
);
void
linphone_authentication_ok
(
LinphoneCore
*
lc
,
SalOp
*
op
);
void
linphone_subscription_new
(
LinphoneCore
*
lc
,
SalOp
*
op
,
const
char
*
from
);
void
linphone_notify_recv
(
LinphoneCore
*
lc
,
SalOp
*
op
,
SalSubscribeStatus
ss
,
SalPresenceStatus
status
);
void
linphone_notify_parse_presence
(
SalOp
*
op
,
const
char
*
content_type
,
const
char
*
content_subtype
,
const
char
*
body
,
SalPresenceModel
**
result
);
void
linphone_notify_recv
(
LinphoneCore
*
lc
,
SalOp
*
op
,
SalSubscribeStatus
ss
,
SalPresenceModel
*
model
);
void
linphone_proxy_config_process_authentication_failure
(
LinphoneCore
*
lc
,
SalOp
*
op
);
void
linphone_subscription_answered
(
LinphoneCore
*
lc
,
SalOp
*
op
);
...
...
@@ -427,7 +428,7 @@ struct _LinphoneFriend{
SalOp
*
insub
;
SalOp
*
outsub
;
LinphoneSubscribePolicy
pol
;
Linphone
OnlineStatus
status
;
Linphone
PresenceModel
*
presence
;
struct
_LinphoneCore
*
lc
;
BuddyInfo
*
info
;
char
*
refkey
;
...
...
include/sal/sal.h
View file @
220c4713
...
...
@@ -292,6 +292,9 @@ typedef enum SalPresenceStatus{
SalPresenceOnVacation
}
SalPresenceStatus
;
struct
_SalPresenceModel
;
typedef
struct
_SalPresenceModel
SalPresenceModel
;
const
char
*
sal_presence_status_to_string
(
const
SalPresenceStatus
status
);
typedef
enum
SalReferStatus
{
...
...
@@ -355,7 +358,8 @@ typedef void (*SalOnSubscribeResponse)(SalOp *op, SalSubscribeStatus status, Sal
typedef
void
(
*
SalOnNotify
)(
SalOp
*
op
,
SalSubscribeStatus
status
,
const
char
*
event
,
const
SalBody
*
body
);
typedef
void
(
*
SalOnSubscribeReceived
)(
SalOp
*
salop
,
const
char
*
event
,
const
SalBody
*
body
);
typedef
void
(
*
SalOnSubscribeClosed
)(
SalOp
*
salop
);
typedef
void
(
*
SalOnNotifyPresence
)(
SalOp
*
op
,
SalSubscribeStatus
ss
,
SalPresenceStatus
status
,
const
char
*
msg
);
typedef
void
(
*
SalOnParsePresenceRequested
)(
SalOp
*
salop
,
const
char
*
content_type
,
const
char
*
content_subtype
,
const
char
*
content
,
SalPresenceModel
**
result
);
typedef
void
(
*
SalOnNotifyPresence
)(
SalOp
*
op
,
SalSubscribeStatus
ss
,
SalPresenceModel
*
model
,
const
char
*
msg
);
typedef
void
(
*
SalOnSubscribePresenceReceived
)(
SalOp
*
salop
,
const
char
*
from
);
typedef
void
(
*
SalOnSubscribePresenceClosed
)(
SalOp
*
salop
,
const
char
*
from
);
typedef
void
(
*
SalOnPingReply
)(
SalOp
*
salop
);
...
...
@@ -393,6 +397,7 @@ typedef struct SalCallbacks{
SalOnNotify
notify
;
SalOnSubscribePresenceReceived
subscribe_presence_received
;
SalOnSubscribePresenceClosed
subscribe_presence_closed
;
SalOnParsePresenceRequested
parse_presence_requested
;
SalOnNotifyPresence
notify_presence
;
SalOnPingReply
ping_reply
;
SalOnAuthRequested
auth_requested
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment