Commit 96d249c6 authored by Ghislain MARY's avatar Ghislain MARY

Generate resource-lists SUBSCRIBE for presence.

parent 89aa523d
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment