Страница 1 из 1

обработка трансфера по rfc5589

Добавлено: 19 апр 2020, 15:22
niksun
Доброго времени!
Подскажите как перехватить/обработать в диалплан управляемый трансфер, произведенный клиентом согласно rfc558.
Спасибо.

Re: обработка трансфера по rfc5589

Добавлено: 19 апр 2020, 16:07
zzuz
Начините с простого. При трансфере в контексте перевода вызывайте DumpChan . По наличию системных переменных можно будет выявлять признак перевода. Например , по переменной ${SIPTRANSFER_REFERER} .

Re: обработка трансфера по rfc5589

Добавлено: 19 апр 2020, 16:19
niksun
"в контексте перевода вызывайте" в том то и вопрос.
TRANSFER_CONTEXT не обрабатывается, полагаю по причине
Asterisk has built into it a bit of an optimization to avoid unnecessary SIP traffic by looking up the dialog referred to by the Replaces header. If the dialog is found in the Asterisk system, then Asterisk simply performs a local attended transfer. This involves internal operations such as moving a channel from one bridge to another, or creating a local channel to link two bridges together.
https://wiki.asterisk.org/wiki/display/ ... +Transfers

Re: обработка трансфера по rfc5589

Добавлено: 20 апр 2020, 12:39
Zavr2008
конкретику в студию - кто кому звонит, кто переадресует, какие настройки..

Re: обработка трансфера по rfc5589

Добавлено: 20 апр 2020, 16:02
niksun
Входящий от провайдера => Вызов клиента №1 (3999) => холд входящего от провайдера => 3999 инвайтит на 888 => РЕФЕР входящего на 888
Старался по возможности оптимально подчистить конфиги и дебаг.
PRIME_BBCODE_SPOILER_SHOW PRIME_BBCODE_SPOILER: pjsip.conf

Код: Выделить всё

[global]
type=global
user_agent=qt-tc

;=============Transport Sections Start==============
[localNet](!)
local_net=172.20.0.0/255.255.0.0
local_net=10.0.0.0/255.255.254.0

[transport-office-udp](localNet)
type=transport
protocol=udp
bind=0.0.0.0
external_media_address=external_ip
external_signaling_address=external_ip

[transport-wss](localNet)
type=transport
protocol=wss
bind=10.0.0.13
;=============Transport Sections End==============

;=============Auth Sections Start==============
[userpassAuthWebrtc](!)
type=auth
auth_type=userpass
password=xxxxxxxxxxxxxxx

[authOffice](!)
type=auth
auth_type=userpass
password=xxxxxxxxxxxx

[auth3999](userpassAuthWebrtc)
username=3999

[auth888](authOffice)
username=888
;=============Auth Sections End==============

;=============AOR Sections Start==============
[aorConnection](!)
type=aor
max_contacts=10
qualify_frequency=60

[3999](aorConnection)
[888](aorConnection)
;=============AOR Sections End==============

;=============Endpoints Sections Start==============
[epWebrtc](!)
type=endpoint
context=from-internal
direct_media=no
disallow=all
allow=alaw
sdp_session=qt-tc
dtls_auto_generate_cert=yes
webrtc=yes

[epOffice](!)
type=endpoint
context=from-internal
disallow=all
allow=alaw
allow=ulaw
transport=transport-office-udp
direct_media=no

[3999](epWebrtc)
auth=auth3999
aors=3999

[888](epOffice)
auth=auth888
aors=888
;=============Endpoints Sections End==============

;===============SP START=================
[ISP]
type=registration
transport=transport-office-udp
outbound_auth=authISP
server_uri=sip:sip.isp.ua
client_uri=sip:10000000@sip.isp.ua
contact_user= 0449999999
retry_interval=60
line=yes
endpoint=ISP

[ISP]
type=aor
contact=sip:sip.isp.ua
qualify_frequency=60

[ISP]
type=endpoint
transport=transport-office-udp
context=from-ISP
disallow=all
allow=alaw,ulaw,g729
aors=ISP
direct_media=no
from_domain=sip.isp.ua
outbound_auth=authISP
from_user=10000000
rtp_symmetric=yes

[authISP]
type=auth
auth_type=userpass
username= 10000000
password=xxxxxxxxxxxxx
;===============SP END=================
PRIME_BBCODE_SPOILER_SHOW PRIME_BBCODE_SPOILER: extensions.ael

Код: Выделить всё

globals {
	TRANSFER_CONTEXT=transfer_ctx;
};

context transfer_ctx {
    _X.=> {
        NoOp(==== TRANSFER ====);
    };
    external_replaces => {
        NoOp(==== TRANSFER EXT ==== );
    };
};

context from-pstn {
    _X. => {
        &define-presets(${EXTEN});
        Answer;
        jump ${FROM_DID}@from-trunk;
    };
};

context from-ISP {
    includes {
        from-pstn;
    };
};

context from-trunk {
    _0449999999 => {
        &dial(PJSIP/3999,1);
    };
};

context ext-local {
    hint(PJSIP/3999) 3999 => {
        &dial(${HINT},0);
    };
    hint(PJSIP/888) 888 => {
        &dial(${HINT},0);
    };                                                        
};

context from-internal {
    includes {
        ext-local;
    };
};

macro dial(exten,setMonitor) {
    Dial(${exten},,rb(predial^s^1(""^${MASTER_UNIQUEID})));
};

context predial {
    s => {
        Set(PJSIP_HEADER(add,X-monitor-file)=${ARG1});
        Set(PJSIP_HEADER(add,X-uniqueid)=${ARG2});
        Return;
    }
};
PRIME_BBCODE_SPOILER_SHOW PRIME_BBCODE_SPOILER: SIP DEBUG

Код: Выделить всё

tc*CLI> pjsip show  history
No.   Timestamp  (Dir) Address                  SIP Message
===== ========== ============================== ===================================
00014 1587383107 * <== sip.isp.ua:5060      INVITE sip:0449999999@external_ip:5060;line=nydhqkm SIP/2.0 // ИНВАЙТ ОТ ПРОВАЙДЕРА
00015 1587383107 * ==> sip.isp.ua:5060      SIP/2.0 100 Trying
00016 1587383107 * ==> sip.isp.ua:5060      SIP/2.0 180 Ringing
00023 1587383109 * ==> sip.isp.ua:5060      SIP/2.0 200 OK
00024 1587383109 * <== sip.isp.ua:5060      ACK sip:external_ip:5060 SIP/2.0
00025 1587383109 * ==> CLIENT-IP:13436     INVITE sip:3999@CLIENT-IP:13436;transport=ws SIP/2.0 // ИНВАЙТ КЛИЕНТА №1 
00026 1587383109 * <== CLIENT-IP:13436     SIP/2.0 100 Trying
00027 1587383109 * <== CLIENT-IP:13436     SIP/2.0 180 Ringing
00030 1587383110 * <== CLIENT-IP:13436     SIP/2.0 200 OK
00031 1587383110 * ==> CLIENT-IP:13436     ACK sip:3999@CLIENT-IP:13436;transport=ws SIP/2.0
00042 1587383113 * <== CLIENT-IP:13436     INVITE sip:asterisk@pbx-pbx-localhost-name:5060;transport=ws SIP/2.0 //ХОЛД ПОХОЖЕ
00043 1587383113 * ==> CLIENT-IP:13436     SIP/2.0 200 OK
00044 1587383113 * <== CLIENT-IP:13436     ACK sip:asterisk@pbx-localhost-name:5060;transport=ws SIP/2.0
00045 1587383113 * <== CLIENT-IP:13436     INVITE sip:888@PBX-DOMAIN-NAME SIP/2.0 //ИНВАЙТ КЛИЕНТА №2 КЛИЕНТОМ №1
00046 1587383113 * ==> CLIENT-IP:13436     SIP/2.0 401 Unauthorized
00047 1587383113 * <== CLIENT-IP:13436     ACK sip:888@PBX-DOMAIN-NAME SIP/2.0
00048 1587383113 * <== CLIENT-IP:13436     INVITE sip:888@PBX-DOMAIN-NAME SIP/2.0
00049 1587383113 * ==> CLIENT-IP:13436     SIP/2.0 100 Trying
00050 1587383113 * ==> CLIENT-IP:13436     SIP/2.0 180 Ringing
00051 1587383113 * ==> CLIENT-IP:54250     INVITE sip:888@CLIENT-IP:54250;ob SIP/2.0 // КЛИЕНТЫ 1 И 2 НА ОДНОМ ХОСТЕ
00052 1587383113 * <== CLIENT-IP:54250     SIP/2.0 100 Trying
00053 1587383113 * <== CLIENT-IP:54250     SIP/2.0 180 Ringing
00054 1587383113 * ==> CLIENT-IP:13436     SIP/2.0 180 Ringing
00055 1587383114 * <== CLIENT-IP:54250     SIP/2.0 200 OK
00056 1587383114 * ==> CLIENT-IP:54250     ACK sip:888@CLIENT-IP:54250;ob SIP/2.0
00057 1587383114 * ==> CLIENT-IP:13436     SIP/2.0 200 OK
00058 1587383114 * <== CLIENT-IP:13436     ACK sip:PBX-LOCAL-IP:8089;transport=ws SIP/2.0
00063 1587383116 * <== CLIENT-IP:13436     REFER sip:asterisk@pbx-localhost-name:5060;transport=ws SIP/2.0 // РЕФЕР ВХОДЯЩЕЙ СЕССИИ НА КЛИЕНТА 2
00064 1587383116 * ==> CLIENT-IP:13436     SIP/2.0 202 Accepted
00065 1587383116 * ==> CLIENT-IP:13436     NOTIFY sip:3999@CLIENT-IP:13436;transport=ws SIP/2.0
00066 1587383116 * ==> CLIENT-IP:13436     NOTIFY sip:3999@CLIENT-IP:13436;transport=ws SIP/2.0
00067 1587383116 * ==> CLIENT-IP:13436     BYE sip:3999@CLIENT-IP:13436;transport=ws;ob SIP/2.0
00068 1587383116 * <== CLIENT-IP:13436     SIP/2.0 200 OK
00069 1587383116 * <== CLIENT-IP:13436     BYE sip:asterisk@pbx-localhost-name:5060;transport=ws SIP/2.0
00070 1587383116 * ==> CLIENT-IP:13436     SIP/2.0 200 OK
00071 1587383116 * <== CLIENT-IP:13436     SIP/2.0 200 OK
00072 1587383116 * <== CLIENT-IP:13436     SIP/2.0 200 OK
00086 1587383117 * ==> CLIENT-IP:13436     OPTIONS sip:3999@CLIENT-IP:13436;transport=ws SIP/2.0
00087 1587383117 * <== CLIENT-IP:13436     SIP/2.0 200 OK
00107 1587383121 * <== sip.isp.ua:5060      BYE sip:external_ip:5060 SIP/2.0
00108 1587383121 * ==> sip.isp.ua:5060      SIP/2.0 200 OK
00109 1587383121 * ==> CLIENT-IP:54250     BYE sip:888@CLIENT-IP:54250;ob SIP/2.0
00110 1587383121 * <== CLIENT-IP:54250     SIP/2.0 200 OK

PRIME_BBCODE_SPOILER_SHOW PRIME_BBCODE_SPOILER: както так бриджует при рефере

Код: Выделить всё

Called PJSIP/888
    -- PJSIP/888-000001e1 is ringing
    -- PJSIP/888-000001e1 is ringing
    -- PJSIP/888-000001e1 answered PJSIP/3999-000001e0
    -- Channel PJSIP/888-000001e1 joined 'simple_bridge' basic-bridge <265336b7-a3ee-4cc3-aa72-f53edd6aa5bd>
    -- Channel PJSIP/3999-000001e0 joined 'simple_bridge' basic-bridge <265336b7-a3ee-4cc3-aa72-f53edd6aa5bd>
    -- Channel PJSIP/ISP-000001de left 'simple_bridge' basic-bridge <5b8b3698-53b2-402a-8f19-f5a9283150b7>
    -- Stopped music on hold on PJSIP/ISP-000001de
    -- Channel PJSIP/3999-000001e0 left 'simple_bridge' basic-bridge <265336b7-a3ee-4cc3-aa72-f53edd6aa5bd>
    -- Channel PJSIP/ISP-000001de swapped with PJSIP/3999-000001e0 into 'simple_bridge' basic-bridge <265336b7-a3ee-4cc3-aa72-f53edd6aa5bd>
    -- Channel PJSIP/3999-000001df left 'simple_bridge' basic-bridge <5b8b3698-53b2-402a-8f19-f5a9283150b7>


Re: обработка трансфера по rfc5589

Добавлено: 21 апр 2020, 03:46
zzuz
Чтобы оставить вызов на сервере поставьте опции t в Dial (либо любую другую , заставляющую проксировать голос на сервере ) .

Re: обработка трансфера по rfc5589

Добавлено: 21 апр 2020, 08:15
niksun
Спасибо за совет. Я попробую. Точнее пробовал (но повторю еще). Хотя без указания данных опций, тот же DTMF метод, прекрасно производит трансфер и попадает в трансфер_контекст...хм...
Только вот при чем DTMF к SIP REFER....
t - Allow the called party to transfer the calling party by sending the DTMF sequence defined in features.conf. This setting does not perform policy enforcement on transfers initiated by other methods.
T - Allow the calling party to transfer the called party by sending the DTMF sequence defined in features.conf. This setting does not perform policy enforcement on transfers initiated by other methods.
https://wiki.asterisk.org/wiki/display/ ... ation_Dial

Re: обработка трансфера по rfc5589

Добавлено: 22 апр 2020, 15:08
Zavr2008
Что за устройства 3999 и 888? телепаты отдыхают.
По кастрированной SIP отладке можно лечить с результатом "как по фотографии".

Мы подобное делаем в chan_sip - там давно уже всё устаканилось, но там нужно обязательно на телефонах выставлять верные опции чтобы PAI везде было, также rpid_update=yes в general.

Re: обработка трансфера по rfc5589

Добавлено: 23 апр 2020, 09:40
niksun
Что за устройства 3999 и 888? телепаты отдыхают.
3999 - webrtc client (web browser)
888 - micro sip soft client
По кастрированной SIP отладке можно лечить с результатом "как по фотографии".
По "По кастрированной SIP отладке" видно что трансфер проходит без проблем. Если возможно уточните, какая именно часть сип диалога могла бы прояснить проблему.
Мы подобное делаем в chan_sip
Я бы тоже им пользовался, но у меня не получилось заставить работать NOTIFY в диалоге трансфера.
И у вас трансферы методом REFER на локальных, уже существующих диалогах попадают в TRANSFER_CONTEXT?
Вот REFER без replaces попадает в контекст

не в отсутствии ли DETERMINE_TRANSFER_CONTEXT, при трансфере на локальных диалогах проблема...
PRIME_BBCODE_SPOILER_SHOW PRIME_BBCODE_SPOILER: res_pjsip_refer.c

Код: Выделить всё

#define DETERMINE_TRANSFER_CONTEXT(context, session)									\
	do {																				\
		ast_channel_lock((session)->channel);											\
		context = pbx_builtin_getvar_helper((session)->channel, "TRANSFER_CONTEXT");	\
		if (ast_strlen_zero(context)) {													\
			context = (session)->endpoint->context;										\
		} else {																		\
			context = ast_strdupa(context);												\
		}																				\
		ast_channel_unlock((session)->channel);											\
	} while (0)																			\

static int refer_incoming_attended_request(struct ast_sip_session *session, pjsip_rx_data *rdata, pjsip_sip_uri *target_uri,
	pjsip_param *replaces_param, struct refer_progress *progress)
{

...............

	/* See if the dialog is local, or remote */
	if ((dlg = pjsip_ua_find_dialog(&replaces->call_id, &replaces->to_tag, &replaces->from_tag, PJ_TRUE))) {
		RAII_VAR(struct ast_sip_session *, other_session, ast_sip_dialog_get_session(dlg), ao2_cleanup);
		struct refer_attended *attended;

................		

		return 200;
	} else {
................
		DETERMINE_TRANSFER_CONTEXT(context, session);
		
................