On 27.07.20 19:08, Andreas Wehrmann wrote: > Am 27.07.2020 um 16:53 schrieb r.b.muller@xxxxxxxxx: >> >> @ Some Dick >> >> Thanks for taking the time to reply. >> >> If this is done at registration, I assume this is where the magic >> should happen, in the account configuration >> >> https://www.pjsip.org/pjsip/docs/html/structpjsua__acc__config.htm#a08473de6401e966d23f34d3a9a05bdd0 >> <https://www.pjsip.org/pjsip/docs/html/structpjsua__acc__config.htm#a08473de6401e966d23f34d3a9a05bdd0> >> >> >> I am unclear as what element of the account struct to set to the >> outgoing spoofed number. >> >> Can you guide me? >> >> Met Vriendelijke Groet, Regards, >> >> Rob Muller >> >> mailto:r.b.muller@xxxxxxxxx >> > I actually implemented setting a custom "From" user and display name > for pjsua_call_make_call(); > however, I had to patch PJ for this. > Not sure right now if I've pushed this to my public repo, I'll check > tomorrow. > If not, I'll just post the changes here on the mailing list. > > Best regards, > > Andreas Okay, not in my repo. I modified pjsua_call_make_call() and the pjsua_call_setting struct in pjsua.h. See the attachement for my versions. All the best, Andreas
/** * Call settings. */ typedef struct pjsua_call_setting { /** * Bitmask of #pjsua_call_flag constants. * * Default: PJSUA_CALL_INCLUDE_DISABLED_MEDIA */ unsigned flag; /** * This flag controls what methods to request keyframe are allowed on * the call. Value is bitmask of #pjsua_vid_req_keyframe_method. * * Default: (PJSUA_VID_REQ_KEYFRAME_SIP_INFO | * PJSUA_VID_REQ_KEYFRAME_RTCP_PLI) */ unsigned req_keyframe_method; /** * Number of simultaneous active audio streams for this call. Setting * this to zero will disable audio in this call. * * Default: 1 */ unsigned aud_cnt; /** * Number of simultaneous active video streams for this call. Setting * this to zero will disable video in this call. * * Default: 1 (if video feature is enabled, otherwise it is zero) */ unsigned vid_cnt; /** * When initially making a call, this can be used to enable the setting * of a custom display name in the From header of the outgoing INVITE. * * Default: Use display name from account id (if any) */ pj_bool_t set_from_display_name; /** * When use_from_display_name is enabled, the string here will be set * as the display name in the From header of the outgoing INVITE. * * Default: Use display name from account id (if any) */ pj_str_t from_display_name; /** * When initially making a call, this can be used to set the user part * of the From header in the outgoing INVITE. * * Default: Use account id */ pj_str_t from_user; } pjsua_call_setting;
/* * Make outgoing call to the specified URI using the specified account. */ PJ_DEF(pj_status_t) pjsua_call_make_call(pjsua_acc_id acc_id, const pj_str_t *dest_uri, const pjsua_call_setting *opt, void *user_data, const pjsua_msg_data *msg_data, pjsua_call_id *p_call_id) { pj_pool_t *tmp_pool = NULL; pjsip_dialog *dlg = NULL; pjsua_acc *acc; pjsua_call *call; int call_id = -1; pj_str_t contact; pj_status_t status; pjsip_sip_uri* from_uri; pjsip_name_addr* from_na; pj_str_t from_header_str; pj_str_t custom_from_user; pj_str_t custom_from_display_name; char new_from_uri[ PJSIP_MAX_URL_SIZE ]; int len; /* Check that account is valid */ PJ_ASSERT_RETURN(acc_id>=0 || acc_id<(int)PJ_ARRAY_SIZE(pjsua_var.acc), PJ_EINVAL); /* Check arguments */ PJ_ASSERT_RETURN(dest_uri, PJ_EINVAL); PJ_LOG(4,(THIS_FILE, "Making call with acc #%d to %.*s", acc_id, (int)dest_uri->slen, dest_uri->ptr)); pj_log_push_indent(); PJSUA_LOCK(); acc = &pjsua_var.acc[acc_id]; if (!acc->valid) { pjsua_perror(THIS_FILE, "Unable to make call because account " "is not valid", PJ_EINVALIDOP); status = PJ_EINVALIDOP; goto on_error; } /* Find free call slot. */ call_id = alloc_call_id(); if (call_id == PJSUA_INVALID_ID) { pjsua_perror(THIS_FILE, "Error making call", PJ_ETOOMANY); status = PJ_ETOOMANY; goto on_error; } /* Clear call descriptor */ reset_call(call_id); call = &pjsua_var.calls[call_id]; /* Associate session with account */ call->acc_id = acc_id; call->call_hold_type = acc->cfg.call_hold_type; /* Generate per-session RTCP CNAME, according to RFC 7022. */ pj_create_random_string(call->cname_buf, call->cname.slen); /* Apply call setting */ status = apply_call_setting(call, opt, NULL); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Failed to apply call setting", status); goto on_error; } /* Create sound port if none is instantiated, to check if sound device * can be used. But only do this with the conference bridge, as with * audio switchboard (i.e. APS-Direct), we can only open the sound * device once the correct format has been known */ if (!pjsua_var.is_mswitch && pjsua_var.snd_port==NULL && pjsua_var.null_snd==NULL && !pjsua_var.no_snd && call->opt.aud_cnt > 0) { status = pjsua_set_snd_dev(pjsua_var.cap_dev, pjsua_var.play_dev); if (status != PJ_SUCCESS) goto on_error; } /* Create temporary pool */ tmp_pool = pjsua_pool_create("tmpcall10", 512, 256); /* Verify that destination URI is valid before calling * pjsua_acc_create_uac_contact, or otherwise there * a misleading "Invalid Contact URI" error will be printed * when pjsua_acc_create_uac_contact() fails. */ if (1) { pjsip_uri *uri; pj_str_t dup; pj_strdup_with_null(tmp_pool, &dup, dest_uri); uri = pjsip_parse_uri(tmp_pool, dup.ptr, dup.slen, 0); if (uri == NULL) { pjsua_perror(THIS_FILE, "Unable to make call", PJSIP_EINVALIDREQURI); status = PJSIP_EINVALIDREQURI; goto on_error; } } /* Mark call start time. */ pj_gettimeofday(&call->start_time); /* Reset first response time */ call->res_time.sec = 0; /* Create suitable Contact header unless a Contact header has been * set in the account. */ if (acc->contact.slen) { contact = acc->contact; } else { status = pjsua_acc_create_uac_contact(tmp_pool, &contact, acc_id, dest_uri); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Unable to generate Contact header", status); goto on_error; } } /* Build From header (if any) */ pj_strassign(&from_header_str, &acc->cfg.id); if(opt) { if( (pj_strlen(&opt->from_user) > 0) || opt->set_from_display_name ) { pj_strdup_with_null(tmp_pool, &from_header_str, &acc->cfg.id); from_na = (pjsip_name_addr*)pjsip_parse_uri(tmp_pool, (char*)pj_strbuf( &from_header_str ), pj_strlen( &from_header_str ), PJSIP_PARSE_URI_AS_NAMEADDR ); if (! from_na) { status = PJSIP_EINVALIDURI; pjsua_perror(THIS_FILE, "Failed to parse account ID", status); goto on_error; } from_uri = pjsip_uri_get_uri(from_na); if(! from_uri) { status = PJSIP_EINVALIDURI; pjsua_perror(THIS_FILE, "Failed to get account URI", status); goto on_error; } if( pj_strlen(&opt->from_user) > 0 ) { pj_strassign( &from_uri->user, (pj_str_t*)&opt->from_user ); } if( opt->set_from_display_name ) { pj_strassign( &from_na->display, (pj_str_t*)&opt->from_display_name ); } /* From name-addr has been updated, print the entire thing now */ len = pjsip_uri_print( PJSIP_URI_IN_FROMTO_HDR, from_na, new_from_uri, PJSIP_MAX_URL_SIZE ); if( len < 0 ) { status = PJSIP_EINVALIDREQURI; pjsua_perror(THIS_FILE, "Failed to print new From URI", status); goto on_error; } pj_strset( &from_header_str, new_from_uri, len ); } } /* Create outgoing dialog: */ status = pjsip_dlg_create_uac( pjsip_ua_instance(), &from_header_str, &contact, dest_uri, (msg_data && msg_data->target_uri.slen? &msg_data->target_uri: dest_uri), &dlg); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Dialog creation failed", status); goto on_error; } /* Increment the dialog's lock otherwise when invite session creation * fails the dialog will be destroyed prematurely. */ pjsip_dlg_inc_lock(dlg); dlg_set_via(dlg, acc); /* Calculate call's secure level */ call->secure_level = get_secure_level(acc_id, dest_uri); /* Attach user data */ call->user_data = user_data; /* Store variables required for the callback after the async * media transport creation is completed. */ if (msg_data) { call->async_call.call_var.out_call.msg_data = pjsua_msg_data_clone( dlg->pool, msg_data); } call->async_call.dlg = dlg; /* Temporarily increment dialog session. Without this, dialog will be * prematurely destroyed if dec_lock() is called on the dialog before * the invite session is created. */ pjsip_dlg_inc_session(dlg, &pjsua_var.mod); if ((call->opt.flag & PJSUA_CALL_NO_SDP_OFFER) == 0) { /* Init media channel */ status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC, call->secure_level, dlg->pool, NULL, NULL, PJ_TRUE, &on_make_call_med_tp_complete); } if (status == PJ_SUCCESS) { status = on_make_call_med_tp_complete(call->index, NULL); if (status != PJ_SUCCESS) goto on_error; } else if (status != PJ_EPENDING) { pjsua_perror(THIS_FILE, "Error initializing media channel", status); pjsip_dlg_dec_session(dlg, &pjsua_var.mod); goto on_error; } /* Done. */ if (p_call_id) *p_call_id = call_id; pjsip_dlg_dec_lock(dlg); pj_pool_release(tmp_pool); PJSUA_UNLOCK(); pj_log_pop_indent(); return PJ_SUCCESS; on_error: if (dlg) { /* This may destroy the dialog */ pjsip_dlg_dec_lock(dlg); } if (call_id != -1) { pjsua_media_channel_deinit(call_id); reset_call(call_id); } pjsua_check_snd_dev_idle(); if (tmp_pool) pj_pool_release(tmp_pool); PJSUA_UNLOCK(); pj_log_pop_indent(); return status; }
_______________________________________________ Visit our blog: http://blog.pjsip.org pjsip mailing list pjsip@xxxxxxxxxxxxxxx http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org