static void subscribe_test_with_args(bool_t terminated_by_subscriber, RefreshTestType refresh_type) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneContent* content; LinphoneEvent *lev; int expires= refresh_type!=NoRefresh ? 4 : 600; MSList* lcs=ms_list_append(NULL,marie->lc); lcs=ms_list_append(lcs,pauline->lc); if (refresh_type==ManualRefresh){ lp_config_set_int(marie->lc->config,"sip","refresh_generic_subscribe",0); } 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)); lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",expires,content); 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_LinphoneSubscriptionActive,1,3000)); BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionActive,1,1000)); /*make sure marie receives first notification before terminating*/ BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,1,1000)); if (refresh_type==AutoRefresh){ wait_for_list(lcs,NULL,0,6000); BC_ASSERT_EQUAL(linphone_event_get_subscription_state(pauline->lev), LinphoneSubscriptionActive, int, "%d"); }else if (refresh_type==ManualRefresh){
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 subscribe_forking(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* pauline2 = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneContent* content; LinphoneEvent *lev; int expires= 600; MSList* lcs=ms_list_append(NULL,marie->lc); lcs=ms_list_append(lcs,pauline->lc); lcs=ms_list_append(lcs,pauline2->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, liblinphone_tester_get_subscribe_content(), strlen(liblinphone_tester_get_subscribe_content())); lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",expires,content); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline2->stat.number_of_LinphoneSubscriptionIncomingReceived,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,1,1000)); /*make sure marie receives first notification before terminating*/ CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,1,1000)); linphone_event_terminate(lev); linphone_content_unref(content); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(pauline2); ms_list_free(lcs); }
void linphone_subscription_state_change(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) { stats* counters = get_stats(lc); LinphoneCoreManager *mgr=get_manager(lc); LinphoneContent* content; const LinphoneAddress* from_addr = linphone_event_get_from(lev); char* from = linphone_address_as_string(from_addr); content = linphone_core_create_content(lc); linphone_content_set_type(content,"application"); linphone_content_set_subtype(content,"somexml2"); linphone_content_set_buffer(content,notify_content,strlen(notify_content)); ms_message("Subscription state [%s] from [%s]",linphone_subscription_state_to_string(state),from); ms_free(from); switch(state){ case LinphoneSubscriptionNone: break; case LinphoneSubscriptionIncomingReceived: counters->number_of_LinphoneSubscriptionIncomingReceived++; mgr->lev=lev; if (!mgr->decline_subscribe) linphone_event_accept_subscription(lev); else linphone_event_deny_subscription(lev, LinphoneReasonDeclined); break; case LinphoneSubscriptionOutgoingInit: counters->number_of_LinphoneSubscriptionOutgoingInit++; break; case LinphoneSubscriptionPending: counters->number_of_LinphoneSubscriptionPending++; break; case LinphoneSubscriptionActive: counters->number_of_LinphoneSubscriptionActive++; if (linphone_event_get_subscription_dir(lev)==LinphoneSubscriptionIncoming){ mgr->lev=lev; linphone_event_notify(lev,content); } break; case LinphoneSubscriptionTerminated: counters->number_of_LinphoneSubscriptionTerminated++; mgr->lev=NULL; break; case LinphoneSubscriptionError: counters->number_of_LinphoneSubscriptionError++; mgr->lev=NULL; break; case LinphoneSubscriptionExpiring: counters->number_of_LinphoneSubscriptionExpiring++; mgr->lev=NULL; break; } linphone_content_unref(content); }
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)); } }
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; }
static int send_report(LinphoneCall* call, reporting_session_report_t * report, const char * report_event) { LinphoneContent *content = linphone_content_new(); LinphoneAddress *addr; int expires = -1; size_t offset = 0; size_t size = 2048; char * buffer; int ret = 0; /*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; } addr = linphone_address_new(linphone_proxy_config_get_quality_reporting_collector(call->dest_proxy)); if (addr == NULL) { ms_warning("QualityReporting[%p]: Asked to submit reporting statistics but no collector address found" , call); ret = 3; goto end; } buffer = (char *) belle_sip_malloc(size); 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"); } linphone_content_set_buffer(content, buffer, strlen(buffer)); ms_free(buffer); if (call->log->reporting.on_report_sent != NULL){ call->log->reporting.on_report_sent( call, (report==call->log->reporting.reports[0])?LINPHONE_CALL_STATS_AUDIO:LINPHONE_CALL_STATS_VIDEO, content); } if (! linphone_core_publish(call->core, addr, "vq-rtcpxr", expires, content)){ 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(addr); linphone_content_unref(content); end: ms_message("QualityReporting[%p]: Send '%s' with status %d", call, report_event, ret ); return ret; }