mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 19:18:06 +00:00
Generate resource-lists SUBSCRIBE for presence.
This commit is contained in:
parent
89aa523d71
commit
96d249c674
5 changed files with 145 additions and 18 deletions
|
|
@ -241,18 +241,21 @@ static void linphone_friend_unsubscribe(LinphoneFriend *lf){
|
|||
}
|
||||
|
||||
void linphone_friend_invalidate_subscription(LinphoneFriend *lf){
|
||||
LinphoneCore *lc=lf->lc;
|
||||
|
||||
if (lf->outsub!=NULL) {
|
||||
LinphoneCore *lc=lf->lc;
|
||||
sal_op_release(lf->outsub);
|
||||
lf->outsub=NULL;
|
||||
lf->subscribe_active=FALSE;
|
||||
/*notify application that we no longer know the presence activity */
|
||||
if (lf->presence != NULL) {
|
||||
linphone_presence_model_unref(lf->presence);
|
||||
}
|
||||
lf->presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityOffline,"unknown activity");
|
||||
linphone_core_notify_notify_presence_received(lc,lf);
|
||||
}
|
||||
|
||||
/* Notify application that we no longer know the presence activity */
|
||||
if (lf->presence != NULL) {
|
||||
linphone_presence_model_unref(lf->presence);
|
||||
}
|
||||
lf->presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityOffline,"unknown activity");
|
||||
linphone_core_notify_notify_presence_received(lc,lf);
|
||||
|
||||
lf->initial_subscribes_sent=FALSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,81 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
|
||||
|
||||
static char * create_resource_list_xml(const LinphoneFriendList *list) {
|
||||
char *xml_content = NULL;
|
||||
MSList *elem;
|
||||
xmlBufferPtr buf;
|
||||
xmlTextWriterPtr writer;
|
||||
int err;
|
||||
|
||||
if (ms_list_size(list->friends) <= 0) return NULL;
|
||||
|
||||
buf = xmlBufferCreate();
|
||||
if (buf == NULL) {
|
||||
ms_error("%s: Error creating the XML buffer", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
writer = xmlNewTextWriterMemory(buf, 0);
|
||||
if (writer == NULL) {
|
||||
ms_error("%s: Error creating the XML writer", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xmlTextWriterSetIndent(writer,1);
|
||||
err = xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL);
|
||||
if (err >= 0) {
|
||||
err = xmlTextWriterStartElementNS(writer, NULL, (const xmlChar *)"resource-lists", (const xmlChar *)"urn:ietf:params:xml:ns:resource-lists");
|
||||
}
|
||||
if (err >= 0) {
|
||||
err = xmlTextWriterWriteAttributeNS(writer, (const xmlChar *)"xmlns", (const xmlChar *)"xsi",
|
||||
NULL, (const xmlChar *)"http://www.w3.org/2001/XMLSchema-instance");
|
||||
}
|
||||
|
||||
if (err>= 0) {
|
||||
err = xmlTextWriterStartElement(writer, (const xmlChar *)"list");
|
||||
}
|
||||
for (elem = list->friends; elem != NULL; elem = elem->next) {
|
||||
LinphoneFriend *friend = (LinphoneFriend *)elem->data;
|
||||
char *uri = linphone_address_as_string_uri_only(friend->uri);
|
||||
if (err >= 0) {
|
||||
err = xmlTextWriterStartElement(writer, (const xmlChar *)"entry");
|
||||
}
|
||||
if (err >= 0) {
|
||||
err = xmlTextWriterWriteAttribute(writer, (const xmlChar *)"uri", (const xmlChar *)uri);
|
||||
}
|
||||
if (err >= 0) {
|
||||
/* Close the "entry" element. */
|
||||
err = xmlTextWriterEndElement(writer);
|
||||
}
|
||||
}
|
||||
if (err >= 0) {
|
||||
/* Close the "list" element. */
|
||||
err = xmlTextWriterEndElement(writer);
|
||||
}
|
||||
|
||||
if (err >= 0) {
|
||||
/* Close the "resource-lists" element. */
|
||||
err = xmlTextWriterEndElement(writer);
|
||||
}
|
||||
if (err >= 0) {
|
||||
err = xmlTextWriterEndDocument(writer);
|
||||
}
|
||||
if (err > 0) {
|
||||
/* xmlTextWriterEndDocument returns the size of the content. */
|
||||
xml_content = ms_strdup((char *)buf->content);
|
||||
}
|
||||
xmlFreeTextWriter(writer);
|
||||
xmlBufferFree(buf);
|
||||
|
||||
return xml_content;
|
||||
}
|
||||
|
||||
static LinphoneFriendList * linphone_friend_list_new(void) {
|
||||
LinphoneFriendList *list = belle_sip_object_new(LinphoneFriendList);
|
||||
belle_sip_object_ref(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
static void linphone_friend_list_destroy(LinphoneFriendList *list) {
|
||||
if (list->display_name != NULL) ms_free(list->display_name);
|
||||
if (list->rls_uri != NULL) ms_free(list->rls_uri);
|
||||
|
|
@ -38,9 +113,9 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneFriendList, belle_sip_object_t,
|
|||
);
|
||||
|
||||
|
||||
LinphoneFriendList * linphone_friend_list_new(void) {
|
||||
LinphoneFriendList *list = belle_sip_object_new(LinphoneFriendList);
|
||||
belle_sip_object_ref(list);
|
||||
LinphoneFriendList * linphone_core_create_friend_list(LinphoneCore *lc) {
|
||||
LinphoneFriendList *list = linphone_friend_list_new();
|
||||
list->lc = lc;
|
||||
return list;
|
||||
}
|
||||
|
||||
|
|
@ -165,9 +240,30 @@ void linphone_friend_list_close_subscriptions(LinphoneFriendList *list) {
|
|||
|
||||
void linphone_friend_list_update_subscriptions(LinphoneFriendList *list, LinphoneProxyConfig *cfg, bool_t only_when_registered) {
|
||||
const MSList *elem;
|
||||
for (elem = list->friends; elem != NULL; elem = elem->next) {
|
||||
LinphoneFriend *friend = (LinphoneFriend *)elem->data;
|
||||
linphone_friend_update_subscribes(friend, cfg, only_when_registered);
|
||||
if (list->rls_uri != NULL) {
|
||||
LinphoneAddress *address = linphone_address_new(list->rls_uri);
|
||||
char *xml_content = create_resource_list_xml(list);
|
||||
if ((address != NULL) && (xml_content != NULL)) {
|
||||
LinphoneEvent *event;
|
||||
LinphoneContent *content;
|
||||
int expires = lp_config_get_int(list->lc->config, "sip", "rls_presence_expires", 3600);
|
||||
event = linphone_core_create_subscribe(list->lc, address, "presence", expires);
|
||||
linphone_event_add_custom_header(event, "Require", "recipient-list-subscribe");
|
||||
linphone_event_add_custom_header(event, "Accept", "multipart/related, application/pidf+xml, application/rlmi+xml");
|
||||
linphone_event_add_custom_header(event, "Content-Disposition", "recipient-list");
|
||||
content = linphone_core_create_content(list->lc);
|
||||
linphone_content_set_type(content, "application");
|
||||
linphone_content_set_subtype(content, "resource-lists+xml");
|
||||
linphone_content_set_string_buffer(content, xml_content);
|
||||
linphone_event_send_subscribe(event, content);
|
||||
}
|
||||
if (address != NULL) linphone_address_unref(address);
|
||||
if (xml_content != NULL) ms_free(xml_content);
|
||||
} else {
|
||||
for (elem = list->friends; elem != NULL; elem = elem->next) {
|
||||
LinphoneFriend *friend = (LinphoneFriend *)elem->data;
|
||||
linphone_friend_update_subscribes(friend, cfg, only_when_registered);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,9 +51,10 @@ typedef struct _LinphoneFriendList LinphoneFriendList;
|
|||
|
||||
/**
|
||||
* Create a new empty LinphoneFriendList object.
|
||||
* @param[in] lc LinphoneCore object.
|
||||
* @return A new LinphoneFriendList object.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneFriendList * linphone_friend_list_new(void);
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneFriendList * linphone_core_create_friend_list(LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* Acquire a reference to the friend list.
|
||||
|
|
@ -126,18 +127,39 @@ LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_add_friend(Linphon
|
|||
**/
|
||||
LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *friend);
|
||||
|
||||
/**
|
||||
* Find a friend in the friend list using a LinphoneAddress.
|
||||
* @param[in] list LinphoneFriendList object.
|
||||
* @param[in] address LinphoneAddress object of the friend we want to search for.
|
||||
* @return A LinphoneFriend if found, NULL otherwise.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneFriend * linphone_friend_list_find_friend_by_address(const LinphoneFriendList *list, const LinphoneAddress *address);
|
||||
|
||||
/**
|
||||
* Find a friend in the friend list using an URI string.
|
||||
* @param[in] list LinphoneFriendList object.
|
||||
* @param[in] uri A string containing the URI of the friend we want to search for.
|
||||
* @return A LinphoneFriend if found, NULL otherwise.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneFriend * linphone_friend_list_find_friend_by_uri(const LinphoneFriendList *list, const char *uri);
|
||||
|
||||
/**
|
||||
* Find a frient in the friend list using a ref key.
|
||||
* @param[in] list LinphoneFriendList object.
|
||||
* @param[in] ref_key The ref key string of the friend we want to search for.
|
||||
* @return A LinphoneFriend if found, NULL otherwise.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneFriend * linphone_friend_list_find_friend_by_ref_key(const LinphoneFriendList *list, const char *ref_key);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_friend_list_close_subscriptions(LinphoneFriendList *list);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_friend_list_update_subscriptions(LinphoneFriendList *list, LinphoneProxyConfig *cfg, bool_t only_when_registered);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_friend_list_invalidate_subscriptions(LinphoneFriendList *list);
|
||||
|
||||
/**
|
||||
* Notify our presence to all the friends in the friend list that have subscribed to our presence directly (not using a RLS).
|
||||
* @param[in] list LinphoneFriendList object.
|
||||
* @param[in] presence LinphonePresenceModel object.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_friend_list_notify_presence(LinphoneFriendList *list, LinphonePresenceModel *presence);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1665,6 +1665,7 @@ static void linphone_core_register_default_codecs(LinphoneCore *lc){
|
|||
}
|
||||
|
||||
static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtable, LpConfig *config, void * userdata){
|
||||
const char *rls_uri = NULL;
|
||||
const char *remote_provisioning_uri = NULL;
|
||||
LinphoneCoreVTable* local_vtable= linphone_core_v_table_new();
|
||||
ms_message("Initializing LinphoneCore %s", linphone_core_get_version());
|
||||
|
|
@ -1672,7 +1673,10 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab
|
|||
lc->config=lp_config_ref(config);
|
||||
lc->data=userdata;
|
||||
lc->ringstream_autorelease=TRUE;
|
||||
lc->friendlist = linphone_friend_list_new();
|
||||
lc->friendlist = linphone_core_create_friend_list(lc);
|
||||
rls_uri = lp_config_get_string(lc->config, "sip", "rls_uri", NULL);
|
||||
if (rls_uri && lp_config_get_int(lc->config, "sip", "use_rls_presence", 0))
|
||||
linphone_friend_list_set_rls_uri(lc->friendlist, rls_uri);
|
||||
linphone_task_list_init(&lc->hooks);
|
||||
|
||||
memcpy(local_vtable,vtable,sizeof(LinphoneCoreVTable));
|
||||
|
|
|
|||
|
|
@ -376,6 +376,7 @@ void _linphone_proxy_config_release(LinphoneProxyConfig *cfg);
|
|||
* */
|
||||
const LinphoneAddress* linphone_proxy_config_get_service_route(const LinphoneProxyConfig* cfg);
|
||||
|
||||
void linphone_friend_list_invalidate_subscriptions(LinphoneFriendList *list);
|
||||
void linphone_friend_invalidate_subscription(LinphoneFriend *lf);
|
||||
void linphone_friend_close_subscriptions(LinphoneFriend *lf);
|
||||
void linphone_friend_update_subscribes(LinphoneFriend *fr, LinphoneProxyConfig *cfg, bool_t only_when_registered);
|
||||
|
|
@ -653,6 +654,7 @@ BELLE_SIP_DECLARE_VPTR(LinphoneFriend);
|
|||
struct _LinphoneFriendList {
|
||||
belle_sip_object_t base;
|
||||
void *user_data;
|
||||
LinphoneCore *lc;
|
||||
char *display_name;
|
||||
char *rls_uri;
|
||||
MSList *friends;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue