void linphone_friend_list_notify_presence_received(LinphoneFriendList *list, LinphoneEvent *lev, const LinphoneContent *body) { if (linphone_content_is_multipart(body)) { LinphoneContent *first_part; const char *type = linphone_content_get_type(body); const char *subtype = linphone_content_get_subtype(body); if ((strcmp(type, "multipart") != 0) || (strcmp(subtype, "related") != 0)) { ms_warning("multipart presence notified but it is not 'multipart/related'"); return; } first_part = linphone_content_get_part(body, 0); if (first_part == NULL) { ms_warning("'multipart/related' presence notified but it doesn't contain any part"); return; } type = linphone_content_get_type(first_part); subtype = linphone_content_get_subtype(first_part); if ((strcmp(type, "application") != 0) || (strcmp(subtype, "rlmi+xml") != 0)) { ms_warning("multipart presence notified but first part is not 'application/rlmi+xml'"); linphone_content_unref(first_part); return; } linphone_friend_list_parse_multipart_related_body(list, body, linphone_content_get_string_buffer(first_part)); linphone_content_unref(first_part); } }
static void info_message_with_args(bool_t with_content) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); LinphoneInfoMessage *info; const LinphoneContent *content; const char *hvalue; CU_ASSERT_TRUE(call(pauline,marie)); info=linphone_core_create_info_message(marie->lc); linphone_info_message_add_header(info,"Weather","still bad"); if (with_content) { LinphoneContent* ct=linphone_core_create_content(marie->lc); linphone_content_set_type(ct,"application"); linphone_content_set_subtype(ct,"somexml"); linphone_content_set_buffer(ct,info_content,strlen(info_content)); linphone_info_message_set_content(info,ct); linphone_content_unref(ct); } { int dummy=0; wait_for_until(marie->lc,pauline->lc,&dummy,1,100); /*just to have time to purge message stored in the server*/ reset_counters(&marie->stat); reset_counters(&pauline->stat); } linphone_call_send_info_message(linphone_core_get_current_call(marie->lc),info); linphone_info_message_destroy(info); CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_inforeceived,1)); CU_ASSERT_PTR_NOT_NULL(pauline->stat.last_received_info_message); hvalue=linphone_info_message_get_header(pauline->stat.last_received_info_message, "Weather"); content=linphone_info_message_get_content(pauline->stat.last_received_info_message); CU_ASSERT_PTR_NOT_NULL(hvalue); if (hvalue) CU_ASSERT_TRUE(strcmp(hvalue,"still bad")==0); if (with_content){ CU_ASSERT_PTR_NOT_NULL(content); if (content) { CU_ASSERT_PTR_NOT_NULL(linphone_content_get_buffer(content)); CU_ASSERT_PTR_NOT_NULL(linphone_content_get_type(content)); CU_ASSERT_PTR_NOT_NULL(linphone_content_get_subtype(content)); if (linphone_content_get_type(content)) CU_ASSERT_TRUE(strcmp(linphone_content_get_type(content),"application")==0); if (linphone_content_get_subtype(content)) CU_ASSERT_TRUE(strcmp(linphone_content_get_subtype(content),"somexml")==0); if (linphone_content_get_buffer(content))CU_ASSERT_TRUE(strcmp((const char*)linphone_content_get_buffer(content),info_content)==0); CU_ASSERT_EQUAL(linphone_content_get_size(content),strlen(info_content)); } } linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); }
static void linphone_content_clone(LinphoneContent *obj, const LinphoneContent *ref) { obj->owned_fields = TRUE; linphone_content_set_sal_body_handler(obj, sal_body_handler_new()); if ((linphone_content_get_type(ref) != NULL) || (linphone_content_get_subtype(ref) != NULL)) { linphone_content_set_type(obj, linphone_content_get_type(ref)); linphone_content_set_subtype(obj, linphone_content_get_subtype(ref)); } if (linphone_content_get_encoding(ref) != NULL) { linphone_content_set_encoding(obj, linphone_content_get_encoding(ref)); } linphone_content_set_name(obj, linphone_content_get_name(ref)); linphone_content_set_key(obj, linphone_content_get_key(ref), linphone_content_get_key_size(ref)); if (linphone_content_get_buffer(ref) != NULL) { linphone_content_set_buffer(obj, linphone_content_get_buffer(ref), linphone_content_get_size(ref)); } else { linphone_content_set_size(obj, linphone_content_get_size(ref)); } }
/** * function invoked to report file transfer progress. * */ static void file_transfer_progress_indication(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total) { const LinphoneAddress* from_address = linphone_chat_message_get_from(message); const LinphoneAddress* to_address = linphone_chat_message_get_to(message); char *address = linphone_chat_message_is_outgoing(message)?linphone_address_as_string(to_address):linphone_address_as_string(from_address); printf(" File transfer [%d%%] %s of type [%s/%s] %s [%s] \n", (int)((offset *100)/total) ,(linphone_chat_message_is_outgoing(message)?"sent":"received") , linphone_content_get_type(content) , linphone_content_get_subtype(content) ,(linphone_chat_message_is_outgoing(message)?"to":"from") , address); free(address); }
/** * function invoked to report file transfer progress. * */ void file_transfer_progress_indication(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total) { LinphoneChatRoom *cr = linphone_chat_message_get_chat_room(message); LinphoneCore *lc = linphone_chat_room_get_core(cr); const LinphoneAddress* from_address = linphone_chat_message_get_from(message); const LinphoneAddress* to_address = linphone_chat_message_get_to(message); char *address = linphone_chat_message_is_outgoing(message)?linphone_address_as_string(to_address):linphone_address_as_string(from_address); stats* counters = get_stats(lc); int progress = (int)((offset * 100)/total); ms_message(" File transfer [%d%%] %s of type [%s/%s] %s [%s] \n", progress ,(linphone_chat_message_is_outgoing(message)?"sent":"received") , linphone_content_get_type(content) , linphone_content_get_subtype(content) ,(linphone_chat_message_is_outgoing(message)?"to":"from") , address); counters->progress_of_LinphoneFileTransfer = progress; free(address); }
static int linphone_chat_message_store_content(LinphoneChatMessage *msg) { LinphoneCore *lc = linphone_chat_room_get_core(msg->chat_room); int id = -1; if (lc->db) { LinphoneContent *content = msg->file_transfer_information; char *buf = sqlite3_mprintf("INSERT INTO content VALUES(NULL,%Q,%Q,%Q,%Q,%i,%Q);", linphone_content_get_type(content), linphone_content_get_subtype(content), linphone_content_get_name(content), linphone_content_get_encoding(content), linphone_content_get_size(content), NULL ); linphone_sql_request(lc->db, buf); sqlite3_free(buf); id = (unsigned int) sqlite3_last_insert_rowid (lc->db); } return id; }
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); }
/** * Returns the info message's content as a #LinphoneContent structure. **/ const LinphoneContent * linphone_info_message_get_content(const LinphoneInfoMessage *im){ return (im->content && linphone_content_get_type(im->content)) ? im->content : NULL; }