使用osip开发的sip server对接avaya sip trunk,基本流程可以跑通,但是没有办法传递UUI数据(通过AES server采集到uui数据)。
研究发现avaya支持RFC7433( Mechanism for Transporting User-to-User Call Control Information in SIP).
通过在Invite消息中增加User-to-User字段来实现,并且avaya PBX可以正确识别。
INVITE sips:alice@example.com SIP/2.0
Via: SIP/2.0/TLS lab.example.com:5061
;branch=z9hG4bKnashds9
To: Bob
From: Carol ;tag=323sf33k2
Call-ID: dfaosidfoiwe83ifkdf
Max-Forwards: 70
Contact:
Supported: histinfo
User-to-User: 342342ef34;encoding=hex
History-Info: ;index=1
History-Info:
&User-to-User=342342ef34;encoding=hex>;index=1.1;rc=1
其中User-to-User: 342342ef34;encoding=hex表示UUI数据,数据已经通过base16进行编码,将特殊字符转换为10进制数据进行传输,avaya pbx可以正确解析。
下面是base16的编码算法。
static const size_t BASE16_ENCODE_INPUT = 1;
static const size_t BASE16_ENCODE_OUTPUT = 2;
static const char* const BASE16_ENCODE_TABLE = "0123456789ABCDEF";
size_t base16Encode( char* dest, const void* src, size_t size )
{
if (dest && src)
{
unsigned char* pSrc = (unsigned char*)src;
size_t dwSrcSize = size;
size_t dwDestSize = 0;
unsigned char ch;
while (dwSrcSize >= 1)
{
ch = *pSrc++;
dwSrcSize -= BASE16_ENCODE_INPUT;
*dest++ = BASE16_ENCODE_TABLE[ (unsigned char)(ch & 0xf0) >> 4 ];
*dest++ = BASE16_ENCODE_TABLE[ (ch & 0x0f) ];
dwDestSize += BASE16_ENCODE_OUTPUT;
}
*dest++ = '\x0';
return dwDestSize;
}
else
return 0;
}
通过此方法传递的uui数据,在avaya aes中还原会吃掉头一个字符,可以人为的前面加个空格,实现正确的数据传递。