Example #1
0
static void parse_valid_xml_rpc_response(LinphoneXmlRpcRequest *request, const char *response_body) {
    xmlparsing_context_t *xml_ctx = linphone_xmlparsing_context_new();
    xmlSetGenericErrorFunc(xml_ctx, linphone_xmlparsing_genericxml_error);
    request->status = LinphoneXmlRpcStatusFailed;
    xml_ctx->doc = xmlReadDoc((const unsigned char*)response_body, 0, NULL, 0);
    if (xml_ctx->doc != NULL) {
        const char *response_str = NULL;
        if (linphone_create_xml_xpath_context(xml_ctx) < 0) goto end;
        switch (request->response.type) {
        case LinphoneXmlRpcArgInt:
            response_str = linphone_get_xml_text_content(xml_ctx, "/methodResponse/params/param/value/int");
            if (response_str != NULL) {
                request->response.data.i = atoi(response_str);
                request->status = LinphoneXmlRpcStatusOk;
            }
            break;
        case LinphoneXmlRpcArgString:
            response_str = linphone_get_xml_text_content(xml_ctx, "/methodResponse/params/param/value/string");
            if (response_str != NULL) {
                request->response.data.s = belle_sip_strdup(response_str);
                request->status = LinphoneXmlRpcStatusOk;
            }
            break;
        default:
            break;
        }
        if (response_str) linphone_free_xml_text_content(response_str);
    } else {
        ms_warning("Wrongly formatted XML-RPC response: %s", xml_ctx->errorBuffer);
    }
end:
    linphone_xmlparsing_context_destroy(xml_ctx);
    if (request->callbacks->response != NULL) {
        request->callbacks->response(request);
    }
}
Example #2
0
static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList *list, const LinphoneContent *body, const char *first_part_body) {
	xmlparsing_context_t *xml_ctx = linphone_xmlparsing_context_new();
	xmlSetGenericErrorFunc(xml_ctx, linphone_xmlparsing_genericxml_error);
	xml_ctx->doc = xmlReadDoc((const unsigned char*)first_part_body, 0, NULL, 0);
	if (xml_ctx->doc != NULL) {
		char xpath_str[MAX_XPATH_LENGTH];
		LinphoneFriend *lf;
		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);
		linphone_free_xml_text_content(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);
			linphone_friend_list_update_subscriptions(list, NULL, FALSE); /* Refresh subscription to get new full state notify. */
			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)) {
			bctbx_list_t *l = list->friends;
			for (; l != NULL; l = l->next) {
				lf = (LinphoneFriend *)l->data;
				linphone_friend_set_presence_model(lf, 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++) {
				snprintf(xpath_str, sizeof(xpath_str), "/rlmi:list/rlmi:resource[%i]/@uri", i);
				uri = linphone_get_xml_text_content(xml_ctx, xpath_str);
				if (uri == NULL) continue;
				lf = linphone_friend_list_find_friend_by_uri(list, uri);
				if (lf != NULL) {
					const char *state = NULL;
					snprintf(xpath_str, sizeof(xpath_str),"/rlmi:list/rlmi:resource[%i]/rlmi:instance/@state", i);
					state = linphone_get_xml_text_content(xml_ctx, xpath_str);
					if ((state != NULL) && (strcmp(state, "active") == 0)) {
						const char *cid = NULL;
						snprintf(xpath_str, sizeof(xpath_str),"/rlmi:list/rlmi:resource[%i]/rlmi:instance/@cid", i);
						cid = linphone_get_xml_text_content(xml_ctx, xpath_str);
						if (cid != NULL) {
							presence_part = linphone_content_find_part_by_header(body, "Content-Id", cid);
							if (presence_part == NULL) {
								ms_warning("rlmi+xml: Cannot find part with Content-Id: %s", cid);
							} else {
								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) {
									lf->presence_received = TRUE;
									linphone_friend_set_presence_model(lf, (LinphonePresenceModel *)presence);
									if (full_state == FALSE) {
										linphone_core_notify_notify_presence_received(list->lc, lf);
									}
								}
								linphone_content_unref(presence_part);
							}
						}
						if (cid != NULL) linphone_free_xml_text_content(cid);
					}
					if (state != NULL) linphone_free_xml_text_content(state);
					lf->subscribe_active = TRUE;
				}
				linphone_free_xml_text_content(uri);
			}
		}
		if (resource_object != NULL) xmlXPathFreeObject(resource_object);

		if (full_state == TRUE) {
			bctbx_list_t *l = list->friends;
			for (; l != NULL; l = l->next) {
				lf = (LinphoneFriend *)l->data;
				if (linphone_friend_is_presence_received(lf) == TRUE) {
					linphone_core_notify_notify_presence_received(list->lc, lf);
				}
			}
		}
	} else {
		ms_warning("Wrongly formatted rlmi+xml body: %s", xml_ctx->errorBuffer);
	}

end:
	linphone_xmlparsing_context_destroy(xml_ctx);
}