mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-21 13:08:08 +00:00
Handle versioning of presence list notifications + store information that we have received presence information for a friend.
This commit is contained in:
parent
97f28a65ca
commit
fccaa5e36e
6 changed files with 95 additions and 1 deletions
|
|
@ -396,6 +396,10 @@ void linphone_friend_set_presence_model(LinphoneFriend *lf, LinphonePresenceMode
|
|||
lf->presence = presence;
|
||||
}
|
||||
|
||||
bool_t linphone_friend_is_presence_received(const LinphoneFriend *lf) {
|
||||
return lf->presence_received;
|
||||
}
|
||||
|
||||
BuddyInfo * linphone_friend_get_info(const LinphoneFriend *lf){
|
||||
return lf->info;
|
||||
}
|
||||
|
|
@ -597,6 +601,8 @@ LinphoneFriend * linphone_friend_new_from_config_file(LinphoneCore *lc, int inde
|
|||
}
|
||||
a=lp_config_get_int(config,item,"subscribe",0);
|
||||
linphone_friend_send_subscribe(lf,a);
|
||||
a = lp_config_get_int(config, item, "presence_received", 0);
|
||||
lf->presence_received = (bool_t)a;
|
||||
|
||||
linphone_friend_set_ref_key(lf,lp_config_get_string(config,item,"refkey",NULL));
|
||||
return lf;
|
||||
|
|
@ -639,6 +645,7 @@ void linphone_friend_write_to_config_file(LpConfig *config, LinphoneFriend *lf,
|
|||
}
|
||||
lp_config_set_string(config,key,"pol",__policy_enum_to_str(lf->pol));
|
||||
lp_config_set_int(config,key,"subscribe",lf->subscribe);
|
||||
lp_config_set_int(config, key, "presence_received", lf->presence_received);
|
||||
|
||||
refkey=linphone_friend_get_ref_key(lf);
|
||||
if (refkey){
|
||||
|
|
|
|||
|
|
@ -100,11 +100,47 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList
|
|||
LinphoneFriend *friend;
|
||||
LinphoneContent *presence_part;
|
||||
xmlXPathObjectPtr resource_object;
|
||||
const char *version_str = NULL;
|
||||
const char *full_state_str = NULL;
|
||||
const char *uri = NULL;
|
||||
bool_t full_state = FALSE;
|
||||
int version;
|
||||
int i;
|
||||
|
||||
if (linphone_create_xml_xpath_context(xml_ctx) < 0) goto end;
|
||||
xmlXPathRegisterNs(xml_ctx->xpath_ctx, (const xmlChar *)"rlmi", (const xmlChar *)"urn:ietf:params:xml:ns:rlmi");
|
||||
|
||||
version_str = linphone_get_xml_attribute_text_content(xml_ctx, "/rlmi:list", "version");
|
||||
if (version_str == NULL) {
|
||||
ms_warning("rlmi+xml: No version attribute in list");
|
||||
goto end;
|
||||
}
|
||||
version = atoi(version_str);
|
||||
if (version < list->expected_notification_version) {
|
||||
ms_warning("rlmi+xml: Discarding received notification with version %d because %d was expected", version, list->expected_notification_version);
|
||||
goto end;
|
||||
}
|
||||
|
||||
full_state_str = linphone_get_xml_attribute_text_content(xml_ctx, "/rlmi:list", "fullState");
|
||||
if (full_state_str == NULL) {
|
||||
ms_warning("rlmi+xml: No fullState attribute in list");
|
||||
goto end;
|
||||
}
|
||||
if ((strcmp(full_state_str, "true") == 0) || (strcmp(full_state_str, "1") == 0)) {
|
||||
MSList *l = list->friends;
|
||||
for (; l != NULL; l = l->next) {
|
||||
friend = (LinphoneFriend *)l->data;
|
||||
linphone_friend_set_presence_model(friend, NULL);
|
||||
}
|
||||
full_state = TRUE;
|
||||
}
|
||||
linphone_free_xml_text_content(full_state_str);
|
||||
if ((list->expected_notification_version == 0) && (full_state == FALSE)) {
|
||||
ms_warning("rlmi+xml: Notification with version 0 is not full state, this is not valid");
|
||||
goto end;
|
||||
}
|
||||
list->expected_notification_version = version + 1;
|
||||
|
||||
resource_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/rlmi:list/rlmi:resource");
|
||||
if ((resource_object != NULL) && (resource_object->nodesetval != NULL)) {
|
||||
for (i = 1; i <= resource_object->nodesetval->nodeNr; i++) {
|
||||
|
|
@ -128,8 +164,11 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList
|
|||
SalPresenceModel *presence = NULL;
|
||||
linphone_notify_parse_presence(linphone_content_get_type(presence_part), linphone_content_get_subtype(presence_part), linphone_content_get_string_buffer(presence_part), &presence);
|
||||
if (presence != NULL) {
|
||||
friend->presence_received = TRUE;
|
||||
linphone_friend_set_presence_model(friend, (LinphonePresenceModel *)presence);
|
||||
linphone_core_notify_notify_presence_received(list->lc, friend);
|
||||
if (full_state == FALSE) {
|
||||
linphone_core_notify_notify_presence_received(list->lc, friend);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -141,6 +180,16 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList
|
|||
}
|
||||
}
|
||||
if (resource_object != NULL) xmlXPathFreeObject(resource_object);
|
||||
|
||||
if (full_state == TRUE) {
|
||||
MSList *l = list->friends;
|
||||
for (; l != NULL; l = l->next) {
|
||||
friend = (LinphoneFriend *)l->data;
|
||||
if (linphone_friend_is_presence_received(friend) == TRUE) {
|
||||
linphone_core_notify_notify_presence_received(list->lc, friend);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ms_warning("Wrongly formatted rlmi+xml body: %s", xml_ctx->errorBuffer);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -247,6 +247,13 @@ LINPHONE_PUBLIC const LinphonePresenceModel * linphone_friend_get_presence_model
|
|||
*/
|
||||
LINPHONE_PUBLIC void linphone_friend_set_presence_model(LinphoneFriend *lf, LinphonePresenceModel *presence);
|
||||
|
||||
/**
|
||||
* Tells whether we already received presence information for a friend.
|
||||
* @param[in] lf A #LinphoneFriend object
|
||||
* @return TRUE if presence information has been received for the friend, FALSE otherwise.
|
||||
*/
|
||||
LINPHONE_PUBLIC bool_t linphone_friend_is_presence_received(const LinphoneFriend *lf);
|
||||
|
||||
/**
|
||||
* Store user pointer to friend object.
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -1868,6 +1868,7 @@ void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeStatus ss, Sa
|
|||
if (activity_str != NULL) ms_free(activity_str);
|
||||
linphone_friend_set_presence_model(lf, presence);
|
||||
lf->subscribe_active=TRUE;
|
||||
lf->presence_received = TRUE;
|
||||
linphone_core_notify_notify_presence_received(lc,(LinphoneFriend*)lf);
|
||||
ms_free(tmp);
|
||||
if (op != lf->outsub){
|
||||
|
|
|
|||
|
|
@ -647,6 +647,7 @@ struct _LinphoneFriend{
|
|||
bool_t inc_subscribe_pending;
|
||||
bool_t commit;
|
||||
bool_t initial_subscribes_sent; /*used to know if initial subscribe message was sent or not*/
|
||||
bool_t presence_received;
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneFriend);
|
||||
|
|
@ -659,6 +660,7 @@ struct _LinphoneFriendList {
|
|||
char *display_name;
|
||||
char *rls_uri;
|
||||
MSList *friends;
|
||||
int expected_notification_version;
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneFriendList);
|
||||
|
|
@ -1245,6 +1247,7 @@ void linphone_xmlparsing_context_destroy(xmlparsing_context_t *ctx);
|
|||
void linphone_xmlparsing_genericxml_error(void *ctx, const char *fmt, ...);
|
||||
int linphone_create_xml_xpath_context(xmlparsing_context_t *xml_ctx);
|
||||
char * linphone_get_xml_text_content(xmlparsing_context_t *xml_ctx, const char *xpath_expression);
|
||||
const char * linphone_get_xml_attribute_text_content(xmlparsing_context_t *xml_ctx, const char *xpath_expression, const char *attribute_name);
|
||||
void linphone_free_xml_text_content(const char *text);
|
||||
xmlXPathObjectPtr linphone_get_xml_xpath_object_for_node_list(xmlparsing_context_t *xml_ctx, const char *xpath_expression);
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,33 @@ char * linphone_get_xml_text_content(xmlparsing_context_t *xml_ctx, const char *
|
|||
return (char *)text;
|
||||
}
|
||||
|
||||
const char * linphone_get_xml_attribute_text_content(xmlparsing_context_t *xml_ctx, const char *xpath_expression, const char *attribute_name) {
|
||||
xmlXPathObjectPtr xpath_obj;
|
||||
xmlChar *text = NULL;
|
||||
|
||||
xpath_obj = xmlXPathEvalExpression((const xmlChar *)xpath_expression, xml_ctx->xpath_ctx);
|
||||
if (xpath_obj != NULL) {
|
||||
if (xpath_obj->nodesetval != NULL) {
|
||||
xmlNodeSetPtr nodes = xpath_obj->nodesetval;
|
||||
if ((nodes != NULL) && (nodes->nodeNr >= 1)) {
|
||||
xmlNodePtr node = nodes->nodeTab[0];
|
||||
xmlAttr *attr = node->properties;
|
||||
while (attr) {
|
||||
if (strcmp((char *)attr->name, attribute_name) == 0) {
|
||||
text = xmlStrcat(text, attr->children->content);
|
||||
attr = NULL;
|
||||
} else {
|
||||
attr = attr->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
xmlXPathFreeObject(xpath_obj);
|
||||
}
|
||||
|
||||
return (const char *)text;
|
||||
}
|
||||
|
||||
void linphone_free_xml_text_content(const char *text) {
|
||||
xmlFree((xmlChar *)text);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue