void linphone_event_set_publish_state(LinphoneEvent *lev, LinphonePublishState state){ LinphoneCore *lc=lev->lc; if (lev->publish_state!=state){ ms_message("LinphoneEvent [%p] moving to publish state %s",lev,linphone_publish_state_to_string(state)); lev->publish_state=state; if (lc->vtable.publish_state_changed){ lc->vtable.publish_state_changed(lev->lc,lev,state); } switch(state){ case LinphonePublishCleared: linphone_event_unref(lev); break; case LinphonePublishOk: case LinphonePublishError: if (lev->expires==-1) linphone_event_unref(lev); break; case LinphonePublishNone: case LinphonePublishProgress: case LinphonePublishExpiring: /*nothing special to do*/ break; } } }
static void subscribe_test_declined(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneContent* content; LinphoneEvent *lev; const LinphoneErrorInfo *ei; MSList* lcs=ms_list_append(NULL,marie->lc); lcs=ms_list_append(lcs,pauline->lc); content = linphone_core_create_content(marie->lc); linphone_content_set_type(content,"application"); linphone_content_set_subtype(content,"somexml"); linphone_content_set_buffer(content,subscribe_content,strlen(subscribe_content)); pauline->decline_subscribe=TRUE; lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",600,content); linphone_event_ref(lev); BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000)); BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000)); BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionError,1,21000));/*yes flexisip may wait 20 secs in case of forking*/ ei=linphone_event_get_error_info(lev); BC_ASSERT_PTR_NOT_NULL(ei); if (ei){ BC_ASSERT_EQUAL(linphone_error_info_get_protocol_code(ei),603, int, "%d"); BC_ASSERT_PTR_NOT_NULL(linphone_error_info_get_phrase(ei)); } BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,1000)); linphone_content_unref(content); linphone_event_unref(lev); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); }
static void linphone_friend_list_close_subscriptions(LinphoneFriendList *list) { /* FIXME we should wait until subscription to complete. */ if (list->event) { linphone_event_terminate(list->event); linphone_event_unref(list->event); list->event = NULL; } bctbx_list_for_each(list->friends, (void (*)(void *))linphone_friend_close_subscriptions); }
void linphone_event_set_state(LinphoneEvent *lev, LinphoneSubscriptionState state){ if (lev->subscription_state!=state){ ms_message("LinphoneEvent [%p] moving to subscription state %s",lev,linphone_subscription_state_to_string(state)); lev->subscription_state=state; linphone_core_notify_subscription_state_changed(lev->lc,lev,state); if (state==LinphoneSubscriptionTerminated){ linphone_event_unref(lev); } } }
LinphoneEvent *linphone_core_publish(LinphoneCore *lc, const LinphoneAddress *resource, const char *event, int expires, const LinphoneContent *body){ int err; LinphoneEvent *lev=linphone_core_create_publish(lc,resource,event,expires); err=_linphone_event_send_publish(lev,body,FALSE); if (err==-1){ linphone_event_unref(lev); lev=NULL; } return lev; }
void linphone_friend_list_update_subscriptions(LinphoneFriendList *list, LinphoneProxyConfig *cfg, bool_t only_when_registered) { const bctbx_list_t *elem; if (list->rls_uri != NULL) { if (list->enable_subscriptions) { LinphoneAddress *address = linphone_address_new(list->rls_uri); char *xml_content = create_resource_list_xml(list); if ((address != NULL) && (xml_content != NULL) && (linphone_friend_list_has_subscribe_inactive(list) == TRUE)) { unsigned char digest[16]; bctbx_md5((unsigned char *)xml_content, strlen(xml_content), digest); if ((list->event != NULL) && (list->content_digest != NULL) && (memcmp(list->content_digest, digest, sizeof(digest)) == 0)) { /* The content has not changed, only refresh the event. */ linphone_event_refresh_subscribe(list->event); } else { LinphoneContent *content; int expires = lp_config_get_int(list->lc->config, "sip", "rls_presence_expires", 3600); list->expected_notification_version = 0; if (list->content_digest != NULL) ms_free(list->content_digest); list->content_digest = ms_malloc(sizeof(digest)); memcpy(list->content_digest, digest, sizeof(digest)); if (list->event != NULL) { linphone_event_terminate(list->event); linphone_event_unref(list->event); } list->event = linphone_core_create_subscribe(list->lc, address, "presence", expires); linphone_event_ref(list->event); linphone_event_set_internal(list->event, TRUE); linphone_event_add_custom_header(list->event, "Require", "recipient-list-subscribe"); linphone_event_add_custom_header(list->event, "Supported", "eventlist"); linphone_event_add_custom_header(list->event, "Accept", "multipart/related, application/pidf+xml, application/rlmi+xml"); linphone_event_add_custom_header(list->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); if (linphone_core_content_encoding_supported(list->lc, "deflate")) { linphone_content_set_encoding(content, "deflate"); linphone_event_add_custom_header(list->event, "Accept-Encoding", "deflate"); } linphone_event_send_subscribe(list->event, content); linphone_content_unref(content); linphone_event_set_user_data(list->event, list); } } if (address != NULL) linphone_address_unref(address); if (xml_content != NULL) ms_free(xml_content); } else { ms_message("Friends list [%p] subscription update skipped since subscriptions not enabled yet", list); } } else if (list->enable_subscriptions) { for (elem = list->friends; elem != NULL; elem = elem->next) { LinphoneFriend *lf = (LinphoneFriend *)elem->data; linphone_friend_update_subscribes(lf, cfg, only_when_registered); } } }
void linphone_event_set_state(LinphoneEvent *lev, LinphoneSubscriptionState state){ LinphoneCore *lc=lev->lc; if (lev->subscription_state!=state){ ms_message("LinphoneEvent [%p] moving to subscription state %s",lev,linphone_subscription_state_to_string(state)); lev->subscription_state=state; if (lc->vtable.subscription_state_changed){ lc->vtable.subscription_state_changed(lev->lc,lev,state); } if (state==LinphoneSubscriptionTerminated){ linphone_event_unref(lev); } } }
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); if (list->content_digest != NULL) ms_free(list->content_digest); if (list->event != NULL) { linphone_event_terminate(list->event); linphone_event_unref(list->event); list->event = NULL; } if (list->uri != NULL) ms_free(list->uri); if (list->cbs) linphone_friend_list_cbs_unref(list->cbs); if (list->dirty_friends_to_update) list->dirty_friends_to_update = bctbx_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))linphone_friend_unref); if (list->friends) list->friends = bctbx_list_free_with_data(list->friends, (void (*)(void *))_linphone_friend_release); }
LinphoneEvent *linphone_core_publish(LinphoneCore *lc, const LinphoneAddress *resource, const char *event, int expires, const LinphoneContent *body){ SalBody salbody; int err; LinphoneEvent *lev=linphone_event_new(lc,LinphoneSubscriptionInvalidDir, event); linphone_configure_op(lc,lev->op,resource,NULL,lp_config_get_int(lc->config,"sip","publish_msg_with_contact",0)); sal_op_set_manual_refresher_mode(lev->op,!lp_config_get_int(lc->config,"sip","refresh_generic_publish",1)); err=sal_publish(lev->op,NULL,NULL,event,expires,sal_body_from_content(&salbody,body)); if (err==0){ linphone_event_set_publish_state(lev,LinphonePublishProgress); }else{ linphone_event_unref(lev); lev=NULL; } return lev; }
static void subscription_state_changed(LinphoneCore *lc, LinphoneEvent *ev, LinphoneSubscriptionState state){ MyAppData *data=(MyAppData*)linphone_core_get_user_data(lc); if (state==LinphoneSubscriptionIncomingReceived){ printf("Receiving new subscription for event %s\n",linphone_event_get_name(ev)); if (data->ev==NULL) { linphone_event_accept_subscription(ev); data->ev=linphone_event_ref(ev); }else{ linphone_event_deny_subscription(ev,LinphoneReasonBusy); } }else if (state==LinphoneSubscriptionTerminated){ if (data->ev==ev){ linphone_event_unref(data->ev); data->ev=NULL; } } }
void _linphone_friend_list_release(LinphoneFriendList *list){ /*drops all references to core and unref*/ list->lc = NULL; if (list->event != NULL) { linphone_event_unref(list->event); list->event = NULL; } if (list->cbs) { linphone_friend_list_cbs_unref(list->cbs); list->cbs = NULL; } if (list->dirty_friends_to_update) { list->dirty_friends_to_update = bctbx_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))linphone_friend_unref); } if (list->friends) { list->friends = bctbx_list_free_with_data(list->friends, (void (*)(void *))_linphone_friend_release); } linphone_friend_list_unref(list); }
static void publish_test_with_args(bool_t refresh){ LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); LinphoneContent content; LinphoneEvent *lev; MSList* lcs=ms_list_append(NULL,marie->lc); lcs=ms_list_append(lcs,pauline->lc); content.type="application"; content.subtype="somexml"; content.data=(char*)subscribe_content; content.size=strlen(subscribe_content); lp_config_set_int(marie->lc->config,"sip","refresh_generic_publish",!refresh); lev=linphone_core_publish(marie->lc,pauline->identity,"dodo",5,&content); linphone_event_ref(lev); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishProgress,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishOk,1,1000)); if (!refresh){ CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishExpiring,1,5000)); linphone_event_update_publish(lev,&content); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishProgress,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishOk,1,1000)); }else{ } linphone_event_terminate(lev); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishCleared,1,1000)); linphone_event_unref(lev); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); }
static int send_report(LinphoneCall* call, reporting_session_report_t * report, const char * report_event) { LinphoneContent *content; int expires = -1; size_t offset = 0; size_t size = 2048; char * buffer; int ret = 0; LinphoneEvent *lev; LinphoneAddress *request_uri; char * domain; const char* route; /*if we are on a low bandwidth network, do not send reports to not overload it*/ if (linphone_call_params_low_bandwidth_enabled(linphone_call_get_current_params(call))){ ms_warning("QualityReporting[%p]: Avoid sending reports on low bandwidth network", call); ret = 1; goto end; } /*if the call was hung up too early, we might have invalid IPs information in that case, we abort the report since it's not useful data*/ if (report->info.local_addr.ip == NULL || strlen(report->info.local_addr.ip) == 0 || report->info.remote_addr.ip == NULL || strlen(report->info.remote_addr.ip) == 0) { ms_warning("QualityReporting[%p]: Trying to submit a %s too early (call duration: %d sec) but %s IP could " "not be retrieved so dropping this report" , call , report_event , linphone_call_get_duration(call) , (report->info.local_addr.ip == NULL || strlen(report->info.local_addr.ip) == 0) ? "local" : "remote"); ret = 2; goto end; } buffer = (char *) belle_sip_malloc(size); content = linphone_content_new(); linphone_content_set_type(content, "application"); linphone_content_set_subtype(content, "vq-rtcpxr"); append_to_buffer(&buffer, &size, &offset, "%s\r\n", report_event); append_to_buffer(&buffer, &size, &offset, "CallID: %s\r\n", report->info.call_id); append_to_buffer(&buffer, &size, &offset, "LocalID: %s\r\n", report->info.local_addr.id); append_to_buffer(&buffer, &size, &offset, "RemoteID: %s\r\n", report->info.remote_addr.id); append_to_buffer(&buffer, &size, &offset, "OrigID: %s\r\n", report->info.orig_id); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "LocalGroup: %s\r\n", report->info.local_addr.group); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "RemoteGroup: %s\r\n", report->info.remote_addr.group); append_to_buffer(&buffer, &size, &offset, "LocalAddr: IP=%s PORT=%d SSRC=%u\r\n", report->info.local_addr.ip, report->info.local_addr.port, report->info.local_addr.ssrc); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "LocalMAC: %s\r\n", report->info.local_addr.mac); append_to_buffer(&buffer, &size, &offset, "RemoteAddr: IP=%s PORT=%d SSRC=%u\r\n", report->info.remote_addr.ip, report->info.remote_addr.port, report->info.remote_addr.ssrc); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "RemoteMAC: %s\r\n", report->info.remote_addr.mac); append_to_buffer(&buffer, &size, &offset, "LocalMetrics:\r\n"); append_metrics_to_buffer(&buffer, &size, &offset, report->local_metrics); if (are_metrics_filled(report->remote_metrics)!=0) { append_to_buffer(&buffer, &size, &offset, "RemoteMetrics:\r\n"); append_metrics_to_buffer(&buffer, &size, &offset, report->remote_metrics); } APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "DialogID: %s\r\n", report->dialog_id); if (report->qos_analyzer.timestamp!=NULL){ append_to_buffer(&buffer, &size, &offset, "AdaptiveAlg:"); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " NAME=\"%s\"", report->qos_analyzer.name); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " TS=\"%s\"", report->qos_analyzer.timestamp); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " IN_LEG=\"%s\"", report->qos_analyzer.input_leg); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " IN=\"%s\"", report->qos_analyzer.input); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " OUT_LEG=\"%s\"", report->qos_analyzer.output_leg); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " OUT=\"%s\"", report->qos_analyzer.output); append_to_buffer(&buffer, &size, &offset, "\r\n"); } #if TARGET_OS_IPHONE { size_t namesize; char *machine; sysctlbyname("hw.machine", NULL, &namesize, NULL, 0); machine = malloc(namesize); sysctlbyname("hw.machine", machine, &namesize, NULL, 0); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "Device: %s\r\n", machine); } #endif linphone_content_set_buffer(content, buffer, strlen(buffer)); ms_free(buffer); if (call->log->reporting.on_report_sent != NULL) { SalStreamType type = report == call->log->reporting.reports[0] ? LINPHONE_CALL_STATS_AUDIO : report == call->log->reporting.reports[1] ? LINPHONE_CALL_STATS_VIDEO : LINPHONE_CALL_STATS_TEXT; call->log->reporting.on_report_sent(call, type, content); } route = linphone_proxy_config_get_quality_reporting_collector(call->dest_proxy); domain = ms_strdup_printf("sip:%s", linphone_proxy_config_get_domain(call->dest_proxy)); request_uri = linphone_address_new(route ? route : domain); ms_free(domain); lev=linphone_core_create_publish(call->core, request_uri, "vq-rtcpxr", expires); if (route) { ms_message("Publishing report with custom route %s", route); sal_op_set_route(lev->op, route); } if (linphone_event_send_publish(lev, content) != 0){ linphone_event_unref(lev); lev=NULL; ret=4; } else { reset_avg_metrics(report); STR_REASSIGN(report->qos_analyzer.timestamp, NULL); STR_REASSIGN(report->qos_analyzer.input_leg, NULL); STR_REASSIGN(report->qos_analyzer.input, NULL); STR_REASSIGN(report->qos_analyzer.output_leg, NULL); STR_REASSIGN(report->qos_analyzer.output, NULL); } linphone_address_destroy(request_uri); linphone_content_unref(content); end: ms_message("QualityReporting[%p]: Send '%s' with status %d", call, report_event, ret ); return ret; }