UNPKG

@babblevoice/projectrtp

Version:
1,293 lines (1,014 loc) 49 kB
const expect = require( "chai" ).expect const projectrtp = require( "../../index" ).projectrtp const dgram = require( "dgram" ) const pcap = require( "./pcap" ) const pkcountperdtmfdigit = 14 /* defined in projectrtpchannel::senddtmf */ const pausebetweendtmfdigits = 200 /* mS 10 pks ref projectrtpchannel::senddtmf */ const timeperdtmfdigit = ( pkcountperdtmfdigit * 20 /* mS */ ) + pausebetweendtmfdigits const dtmfeventduration = ( ( pkcountperdtmfdigit - 2) * 160 ) /* i.e. the RTP payload str = "80 e5 03 b5 00 02 44 a0 1e e3 61 fb 03 0a 00 a0 4c d1" returns Buffer.from( [ 0x80, ... ] ) */ function fromstr( str ) { const retval = [] str.split( " " ).forEach( v => retval.push ( parseInt( v, 16 ) ) ) return Buffer.from( retval ) } function sendpayload( sendtime, pk, dstport, server ) { return setTimeout( () => { server.send( pk, dstport, "localhost" ) }, sendtime ) } /** * Limitation of not parsing ccrc. * @param { Buffer } packet * @return { object } */ function parsepk( packet ) { return { sn: packet.readUInt16BE( 2 ), ts: packet.readUInt32BE( 4 ), pt: packet.readUInt8( 1 ) & 0x7f, ssrc: packet.readUInt32BE( 8 ), payload: new Uint8Array( packet.slice( 12 ) ) } } /** * Limitation of not parsing ccrc. * @param { Buffer } packet * @return { object } */ function parse2833pk( packet ) { return { sn: packet.readUInt16BE( 2 ), ts: packet.readUInt32BE( 4 ), pt: packet.readUInt8( 1 ) & 0x7f, ssrc: packet.readUInt32BE( 8 ), event: { id: packet.readUInt8( 12 ), eoe: ( packet.readUInt8( 13 ) & 0x80 ) == 0x80, volume: packet.readUInt8( 13 ) & 0x7f, duration: packet.readUInt16BE( 14 ), } } } /* helper functions */ function sendpk( sn, ts, sendtime, dstport, server, pt = 0, ssrc ) { if( !ssrc ) ssrc = 25 const pklength = 172 return setTimeout( () => { const payload = Buffer.alloc( pklength - 12 ).fill( projectrtp.codecx.linear162pcmu( sn ) & 0xff ) const subheader = Buffer.alloc( 10 ) subheader.writeUInt8( pt, 1 ) // payload type subheader.writeUInt16BE( ( sn ) % ( 2**16 ) ) subheader.writeUInt32BE( ts, 2 ) subheader.writeUInt32BE( ssrc, 6 ) const rtppacket = Buffer.concat( [ Buffer.from( [ 0x80, 0x00 ] ), subheader, payload ] ) server.send( rtppacket, dstport, "localhost" ) }, sendtime ) } /* */ function senddtmf( sn, ts, sendtime, dstport, server, endofevent, ev, pt = 101 ) { return setTimeout( () => { const ssrc = 25 const pklength = 16 const header = Buffer.alloc( pklength ) header.writeUInt8( 0x80 ) header.writeUInt8( pt, 1 ) // payload type header.writeUInt16BE( ( sn ) % ( 2**16 ), 2 ) header.writeUInt32BE( ts, 4 ) header.writeUInt32BE( ssrc, 8 ) /* DTMF data */ header.writeUInt8( ev, 12 ) let eoerv = 10 if( endofevent ) { eoerv = eoerv | 0x80 } header.writeUInt8( eoerv, 13 ) /* End of Event, Reserved, Volume */ header.writeUInt16BE( 160, 14 ) /* Duration */ server.send( header, dstport, "localhost" ) }, sendtime ) } /* Tests */ describe( "dtmf", function() { it( "Send 2833 DTMF and check event", function( done ) { /* create our RTP/UDP endpoint */ const server = dgram.createSocket( "udp4" ) server.on( "message", function() {} ) this.timeout( 3000 ) this.slow( 2500 ) server.bind() server.on( "listening", async function() { const ourport = server.address().port let expectedmessagecount = 0 const expectedmessages = [ { action: "telephone-event", event: "4" }, { action: "close" } ] const channel = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": ourport, "codec": 0 } }, function( d ) { expect( d ).to.deep.include( expectedmessages[ expectedmessagecount ] ) expectedmessagecount++ if( "close" === d.action ) { server.close() done() } } ) expect( channel.echo() ).to.be.true /* send a packet every 20mS x 50 */ for( let i = 0; 23 > i; i ++ ) { sendpk( i, i*160, i*20, channel.local.port, server ) } senddtmf( 23, 22*160, 23*20, channel.local.port, server, false, "4" ) senddtmf( 24, 22*160, 24*20, channel.local.port, server, false, "4" ) senddtmf( 25, 22*160, 25*20, channel.local.port, server, true, "4" ) for( let i = 26; 40 > i; i ++ ) { sendpk( i, i*160, (i-3)*20, channel.local.port, server ) } setTimeout( () => channel.close(), 1000 ) } ) } ) it( "single channel and request rtp server to send 2833", async function() { /* TODO - check tre fuller structure of an RTP event (duration, volume, etc) */ /* create our RTP/UDP endpoint */ let done const finished = new Promise( resolve => done = resolve ) const server = dgram.createSocket( "udp4" ) let dtmfpkcount = 0 server.on( "message", function( msg ) { if( 101 == ( 0x7f & msg [ 1 ] ) ) { dtmfpkcount++ } else { expect( msg.length ).to.equal( 172 ) expect( 0x7f & msg [ 1 ] ).to.equal( 0 ) } } ) this.timeout( 5000 ) this.slow( 4000 ) server.bind() await new Promise( resolve => server.on( "listening", resolve ) ) const ourport = server.address().port let expectedmessagecount = 0 const expectedmessages = [ { action: "close" } ] const channel = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": ourport, "codec": 0 } }, function( d ) { expect( d ).to.deep.include( expectedmessages[ expectedmessagecount ] ) expectedmessagecount++ if( "close" === d.action ) { server.close() done() } } ) expect( channel.echo() ).to.be.true /* send a packet every 20mS x 50 */ for( let i = 0; 50 > i; i ++ ) { sendpk( i, i*160, i*20, channel.local.port, server ) } await new Promise( resolve => setTimeout( resolve, 400 ) ) channel.dtmf( "#1" ) await new Promise( resolve => setTimeout( resolve, 1000 ) ) channel.close() await finished expect( dtmfpkcount ).to.equal( 2*pkcountperdtmfdigit ) } ) it( "2 channels mixing and request rtp server to send 2833 to one", async function() { /* create our RTP/UDP endpoint */ const clienta = dgram.createSocket( "udp4" ) const clientb = dgram.createSocket( "udp4" ) const dtmfpks = [] clienta.on( "message", function( msg ) { if( 101 == ( 0x7f & msg [ 1 ] ) ) { dtmfpks.push( parse2833pk( msg ) ) } else { expect( msg.length ).to.equal( 172 ) expect( 0x7f & msg [ 1 ] ).to.equal( 0 ) } } ) clientb.on( "message", function( msg ) { if( 101 == ( 0x7f & msg [ 1 ] ) ) { expect( true ).to.equal( false ) //here = bad } clientb.send( msg, channelb.local.port, "localhost" ) } ) this.timeout( 3000 ) this.slow( 2500 ) clienta.bind() await new Promise( ( resolve ) => { clienta.on( "listening", () => resolve() ) } ) clientb.bind() await new Promise( ( resolve ) => { clientb.on( "listening", () => resolve() ) } ) const ouraport = clienta.address().port const ourbport = clientb.address().port let done const finished = new Promise( ( r ) => { done = r } ) const channela = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": ouraport, "codec": 0 } }, function( d ) { if( "close" === d.action ) channelb.close() } ) const channelb = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": ourbport, "codec": 0 } }, function( d ) { if( "close" === d.action ) done() } ) expect( channela.mix( channelb ) ).to.be.true /* send a packet every 20mS x 70 */ for( let i = 0; 50 > i; i ++ ) { sendpk( i, i*160, i*20, channela.local.port, clienta ) } await new Promise( ( resolve ) => { setTimeout( () => resolve(), 400 ) } ) channela.dtmf( "*9F" ) await new Promise( ( resolve ) => { setTimeout( () => resolve(), 3 * timeperdtmfdigit ) } ) channela.close() await finished clienta.close() clientb.close() expect( dtmfpks.length ).to.equal( 3*pkcountperdtmfdigit ) expect( dtmfpks[ 0 ].event.id ).to.equal( 10 ) expect( dtmfpks[ 0 ].event.duration ).to.equal( 160 ) expect( dtmfpks[ 0 ].event.eoe ).to.be.false expect( dtmfpks[ pkcountperdtmfdigit - 3 ].event.id ).to.equal( 10 ) expect( dtmfpks[ pkcountperdtmfdigit - 3 ].event.duration ).to.equal( dtmfeventduration ) expect( dtmfpks[ pkcountperdtmfdigit - 3 ].event.eoe ).to.be.true } ) it( "2 channels mixing and request rtp server to send 2833 to one with dynamic payloadtype", async function() { /* create our RTP/UDP endpoint */ const clienta = dgram.createSocket( "udp4" ) const clientb = dgram.createSocket( "udp4" ) const rfc2833pt = 44 let dtmfpkcount = 0 clienta.on( "message", function( msg ) { if( rfc2833pt == ( 0x7f & msg [ 1 ] ) ) { dtmfpkcount++ } else { expect( msg.length ).to.equal( 172 ) expect( 0x7f & msg [ 1 ] ).to.equal( 0 ) } } ) clientb.on( "message", function( msg ) { if( 101 == ( 0x7f & msg [ 1 ] ) ) { expect( true ).to.equal( false ) //here = bad dtmfpkcount++ } clientb.send( msg, channelb.local.port, "localhost" ) } ) this.timeout( 3000 ) this.slow( 2500 ) clienta.bind() await new Promise( ( resolve ) => { clienta.on( "listening", () => resolve() ) } ) clientb.bind() await new Promise( ( resolve ) => { clientb.on( "listening", () => resolve() ) } ) const ouraport = clienta.address().port const ourbport = clientb.address().port let done const finished = new Promise( ( r ) => { done = r } ) const channela = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": ouraport, "codec": 0, rfc2833pt } }, function( d ) { if( "close" === d.action ) channelb.close() } ) const channelb = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": ourbport, "codec": 0 } }, function( d ) { if( "close" === d.action ) done() } ) expect( channela.mix( channelb ) ).to.be.true /* send a packet every 20mS x 70 */ for( let i = 0; 50 > i; i ++ ) { sendpk( i, i*160, i*20, channela.local.port, clienta ) } await new Promise( ( resolve ) => { setTimeout( () => resolve(), 400 ) } ) channela.dtmf( "*9F" ) await new Promise( ( resolve ) => { setTimeout( () => resolve(), 3 * timeperdtmfdigit ) } ) channela.close() await finished clienta.close() clientb.close() expect( dtmfpkcount ).to.equal( 3*pkcountperdtmfdigit ) } ) it( "3 channels mixing and request rtp server to send 2833 to one", async function() { /* create our RTP/UDP endpoint */ const clienta = dgram.createSocket( "udp4" ) const clientb = dgram.createSocket( "udp4" ) const clientc = dgram.createSocket( "udp4" ) let dtmfpks = [] clienta.on( "message", function( msg ) { const pk = parsepk( msg ) if( 101 == pk.pt ) { dtmfpks.push( parse2833pk( msg ) ) } else { expect( msg.length ).to.equal( 172 ) expect( pk.pt ).to.equal( 0 ) } } ) clientb.on( "message", function( msg ) { if( 101 == ( 0x7f & msg [ 1 ] ) ) { expect( true ).to.equal( false ) //here = bad } clientb.send( msg, channelb.local.port, "localhost" ) } ) clientc.on( "message", function( msg ) { if( 101 == ( 0x7f & msg [ 1 ] ) ) { expect( true ).to.equal( false ) //here = bad } clientb.send( msg, channelb.local.port, "localhost" ) } ) this.timeout( 3000 ) this.slow( 2500 ) clienta.bind() await new Promise( ( resolve ) => { clienta.on( "listening", () => resolve() ) } ) clientb.bind() await new Promise( ( resolve ) => { clientb.on( "listening", () => resolve() ) } ) clientc.bind() await new Promise( ( resolve ) => { clientc.on( "listening", () => resolve() ) } ) const ouraport = clienta.address().port const ourbport = clientb.address().port const ourcport = clientc.address().port let done const finished = new Promise( ( r ) => { done = r } ) const channela = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": ouraport, "codec": 0 } }, function( d ) { if( "close" === d.action ) channelb.close() } ) const channelb = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": ourbport, "codec": 0 } }, function( d ) { if( "close" === d.action ) channelc.close() } ) const channelc = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": ourcport, "codec": 0 } }, function( d ) { if( "close" === d.action ) done() } ) expect( channela.mix( channelb ) ).to.be.true expect( channela.mix( channelc ) ).to.be.true /* send a packet every 20mS x 50 */ for( let i = 0; 50 > i; i ++ ) { sendpk( i, i*160, i*20, channela.local.port, clienta ) } await new Promise( ( resolve ) => { setTimeout( () => resolve(), 100 ) } ) channela.dtmf( "*9ABD" ) await new Promise( ( resolve ) => { setTimeout( () => resolve(), 5 * timeperdtmfdigit ) } ) channela.close() clienta.close() clientb.close() clientc.close() expect( dtmfpks.length ).to.equal( 5*pkcountperdtmfdigit ) await finished } ) it( "Send multiple 2833 DTMF and check event", async function() { /* create our RTP/UDP endpoint */ const server = dgram.createSocket( "udp4" ) server.on( "message", function() {} ) this.timeout( 3000 ) this.slow( 2500 ) server.bind() await new Promise( ( resolve ) => { server.on( "listening", () => resolve() ) } ) const ourport = server.address().port const receivedmessages = [] const channel = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": ourport, "codec": 0 } }, function( d ) { receivedmessages.push( d ) if( "close" === d.action ) { server.close() } } ) expect( channel.echo() ).to.be.true /* send a packet every 20mS x 50 */ for( let i = 0; 13 > i; i ++ ) { sendpk( i, i*160, i*20, channel.local.port, server ) } /* DTMF every 50mS */ senddtmf( 13, 12*160, 13*20, channel.local.port, server, false, "4" ) sendpk( 14, 13*160, 13*20, channel.local.port, server ) sendpk( 15, 14*160, 14*20, channel.local.port, server ) senddtmf( 16, 14*160, (13*20)+50, channel.local.port, server, false, "4" ) // Packet loss // senddtmf( 15, 12 * 160, 15*20, channel.port, server, true, "4" ) for( let i = 17; 30 > i; i ++ ) { sendpk( i, (i-2)*160, (i-2)*20, channel.local.port, server ) } senddtmf( 31, 29*160, 29*20, channel.local.port, server, false, "5" ) sendpk( 32, 29*160, 29*20, channel.local.port, server ) sendpk( 33, 30*160, 30*20, channel.local.port, server ) senddtmf( 34, 30*160, (29*20)+50, channel.local.port, server, false, "5" ) sendpk( 35, 31*160, 31*20, channel.local.port, server ) sendpk( 36, 32*160, 32*20, channel.local.port, server ) senddtmf( 37, 32*160, (29*20)+100, channel.local.port, server, true, "5" ) for( let i = 37; 45 > i; i ++ ) { sendpk( i, i*160, (i-6)*20, channel.local.port, server ) } setTimeout( () => channel.close(), 1100 ) await new Promise( resolve => { server.on( "close", resolve ) } ) expect( receivedmessages[ 0 ].action ).to.equal( "telephone-event" ) expect( receivedmessages[ 0 ].event ).to.equal( "4" ) expect( receivedmessages[ 1 ].action ).to.equal( "telephone-event" ) expect( receivedmessages[ 1 ].event ).to.equal( "5" ) expect( receivedmessages[ 2 ].action ).to.equal( "close" ) } ) it( "Lose end packet", async function() { /* create our RTP/UDP endpoint */ const server = dgram.createSocket( "udp4" ) const receivedmessages = [] let receviedpkcount = 0 server.on( "message", function() { receviedpkcount++ } ) let done const finished = new Promise( r => done = r ) this.timeout( 3000 ) this.slow( 2500 ) server.bind() server.on( "listening", async function() { const ourport = server.address().port const channel = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": ourport, "codec": 0 } }, function( d ) { receivedmessages.push( d ) if( "close" === d.action ) { server.close() done() } } ) expect( channel.echo() ).to.be.true /* send a packet every 20mS x 50 */ sendpk( 0, 160, 0, channel.local.port, server ) sendpk( 1, 1*160, 1*20, channel.local.port, server ) sendpk( 2, 2*160, 2*20, channel.local.port, server ) sendpk( 3, 3*160, 3*20, channel.local.port, server ) sendpk( 4, 4*160, 4*20, channel.local.port, server ) sendpk( 5, 5*160, 5*20, channel.local.port, server ) sendpk( 6, 6*160, 6*20, channel.local.port, server ) sendpk( 7, 7*160, 7*20, channel.local.port, server ) sendpk( 8, 8*160, 8*20, channel.local.port, server ) sendpk( 9, 9*160, 9*20, channel.local.port, server ) sendpk( 10, 10*160, 10*20, channel.local.port, server ) sendpk( 11, 11*160, 11*20, channel.local.port, server ) sendpk( 12, 12*160, 12*20, channel.local.port, server ) senddtmf( 13, 13*160, 13*20, channel.local.port, server, false, "4" ) sendpk( 14, 13*160, 13*20, channel.local.port, server, 0 ) sendpk( 15, 14*160, 14*20, channel.local.port, server, 0 ) senddtmf( 16, (15*160)+10, (15*20)+10, channel.local.port, server, false, "4" ) sendpk( 17, 15*160, 15*20, channel.local.port, server, 0 ) sendpk( 18, 16*160, 16*20, channel.local.port, server, 0 ) // Packet loss // senddtmf( 19, (16*160)+20, (16*20)+20, channel.local.port, server, true, "4" ) sendpk( 20, 17*160, 17*20, channel.local.port, server, 0 ) sendpk( 21, 18*160, 18*20, channel.local.port, server, 0 ) sendpk( 22, 19*160, 19*20, channel.local.port, server, 0 ) sendpk( 23, 20*160, 20*20, channel.local.port, server, 0 ) sendpk( 24, 21*160, 21*20, channel.local.port, server, 0 ) sendpk( 25, 22*160, 22*20, channel.local.port, server, 0 ) sendpk( 26, 23*160, 23*20, channel.local.port, server, 0 ) sendpk( 27, 24*160, 24*20, channel.local.port, server, 0 ) sendpk( 28, 25*160, 25*20, channel.local.port, server, 0 ) sendpk( 29, 26*160, 26*20, channel.local.port, server, 0 ) sendpk( 30, 27*160, 27*20, channel.local.port, server, 0 ) setTimeout( () => channel.close(), 1000 ) } ) await finished const expectedmessages = [ { action: "telephone-event", event: "4" }, { action: "close" } ] expect( receviedpkcount ).to.be.above( 15 ) expect( receivedmessages.length ).to.equal( 2 ) expect( receivedmessages[ 0 ] ).to.deep.include( expectedmessages[ 0 ] ) expect( receivedmessages[ 1 ] ).to.deep.include( expectedmessages[ 1 ] ) } ) it( "mix 2 channels - pcmu <-> pcma and send DTMF", async function() { /* When mixing 2 channels, we expect the second leg to receive the 2833 packets and our server to emit events indicating the DTMF on the first channel. */ this.timeout( 3000 ) this.slow( 2000 ) const endpointa = dgram.createSocket( "udp4" ) const endpointb = dgram.createSocket( "udp4" ) const receivedmessages = [] let endpointapkcount = 0 let endpointbpkcount = 0 let dtmfpkcount = 0 endpointa.on( "message", function( msg ) { endpointapkcount++ expect( msg.length ).to.equal( 172 ) expect( 0x7f & msg [ 1 ] ).to.equal( 0 ) } ) endpointb.on( "message", function( msg ) { endpointbpkcount++ if( 101 == ( 0x7f & msg [ 1 ] ) ) { dtmfpkcount++ } else { expect( msg.length ).to.equal( 172 ) expect( 0x7f & msg [ 1 ] ).to.equal( 8 ) endpointb.send( msg, channelb.local.port, "localhost" ) } } ) endpointa.bind() await new Promise( ( resolve ) => { endpointa.on( "listening", function() { resolve() } ) } ) endpointb.bind() await new Promise( ( resolve ) => { endpointb.on( "listening", function() { resolve() } ) } ) let done const finished = new Promise( ( r ) => { done = r } ) const channela = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": endpointa.address().port, "codec": 0 } }, function( d ) { receivedmessages.push( d ) if( "close" === d.action ) channelb.close() } ) const channelb = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": endpointb.address().port, "codec": 8 } }, function( d ) { if( "close" === d.action ) done() } ) /* mix */ expect( channela.mix( channelb ) ).to.be.true /* send a packet every 20mS x 50 */ sendpk( 0, 0, 0, channela.local.port, endpointa ) sendpk( 1, 1*160, 1*20, channela.local.port, endpointa ) sendpk( 2, 2*160, 2*20, channela.local.port, endpointa ) sendpk( 3, 3*160, 3*20, channela.local.port, endpointa ) sendpk( 4, 4*160, 4*20, channela.local.port, endpointa ) sendpk( 5, 5*160, 5*20, channela.local.port, endpointa ) sendpk( 6, 6*160, 6*20, channela.local.port, endpointa ) sendpk( 7, 7*160, 7*20, channela.local.port, endpointa ) sendpk( 8, 8*160, 8*20, channela.local.port, endpointa ) sendpk( 9, 9*160, 9*20, channela.local.port, endpointa ) sendpk( 10, 10*160, 10*20, channela.local.port, endpointa ) sendpk( 11, 11*160, 11*20, channela.local.port, endpointa ) sendpk( 12, 12*160, 12*20, channela.local.port, endpointa ) senddtmf( 13, 13*160, 13*20, channela.local.port, endpointa, false, "4" ) sendpk( 14, 13*160, 13*20, channela.local.port, endpointa, 0 ) sendpk( 15, 14*160, 14*20, channela.local.port, endpointa, 0 ) senddtmf( 16, (15*160)+10, (15*20)+10, channela.local.port, endpointa, false, "4" ) sendpk( 17, 15*160, 15*20, channela.local.port, endpointa, 0 ) sendpk( 18, 16*160, 16*20, channela.local.port, endpointa, 0 ) senddtmf( 19, (17*160)+20, (17*20)+20, channela.local.port, endpointa, true, "4" ) sendpk( 20, 17*160, 17*20, channela.local.port, endpointa, 0 ) sendpk( 21, 18*160, 18*20, channela.local.port, endpointa, 0 ) senddtmf( 22, (18*160)+30, (18*20)+30, channela.local.port, endpointa, true, "4" ) sendpk( 23, 19*160, 19*20, channela.local.port, endpointa, 0 ) sendpk( 24, 20*160, 20*20, channela.local.port, endpointa, 0 ) sendpk( 25, 21*160, 21*20, channela.local.port, endpointa, 0 ) sendpk( 26, 22*160, 22*20, channela.local.port, endpointa, 0 ) sendpk( 27, 23*160, 23*20, channela.local.port, endpointa, 0 ) sendpk( 28, 24*160, 24*20, channela.local.port, endpointa, 0 ) sendpk( 29, 25*160, 25*20, channela.local.port, endpointa, 0 ) senddtmf( 30, 26*160, 26*20, channela.local.port, endpointa, false, "5" ) sendpk( 31, 26*160, 26*20, channela.local.port, endpointa, 0 ) sendpk( 32, 27*160, 27*20, channela.local.port, endpointa, 0 ) senddtmf( 33, (27*160)+10, (27*20)+10, channela.local.port, endpointa, false, "5" ) sendpk( 34, 28*160, 28*20, channela.local.port, endpointa, 0 ) sendpk( 35, 29*160, 28*20, channela.local.port, endpointa, 0 ) senddtmf( 36, (28*160)+20, (28*20)+20, channela.local.port, endpointa, true, "5" ) sendpk( 37, 30*160, 29*20, channela.local.port, endpointa, 0 ) sendpk( 38, 31*160, 30*20, channela.local.port, endpointa, 0 ) senddtmf( 39, (38*160)+30, (30*20)+30, channela.local.port, endpointa, true, "5" ) sendpk( 40, 32*160, 31*20, channela.local.port, endpointa, 0 ) sendpk( 41, 33*160, 32*20, channela.local.port, endpointa, 0 ) sendpk( 42, 34*160, 33*20, channela.local.port, endpointa, 0 ) sendpk( 43, 35*160, 34*20, channela.local.port, endpointa, 0 ) sendpk( 44, 36*160, 35*20, channela.local.port, endpointa, 0 ) sendpk( 45, 37*160, 36*20, channela.local.port, endpointa, 0 ) sendpk( 46, 38*160, 37*20, channela.local.port, endpointa, 0 ) sendpk( 47, 39*160, 38*20, channela.local.port, endpointa, 0 ) sendpk( 48, 40*160, 39*20, channela.local.port, endpointa, 0 ) sendpk( 49, 51*160, 40*20, channela.local.port, endpointa, 0 ) await new Promise( ( r ) => { setTimeout( () => r(), 1400 ) } ) channela.close() endpointa.close() endpointb.close() await finished expect( dtmfpkcount ).to.be.within( ( pkcountperdtmfdigit * 2 ) - 4 , pkcountperdtmfdigit * 2 ) /* allow loss */ expect( endpointapkcount ).to.be.within( 30, 51 ) expect( endpointbpkcount - dtmfpkcount ).to.be.within( 30, 51 ) expect( receivedmessages.length ).to.equal( 5 ) expect( receivedmessages[ 0 ].action ).to.equal( "mix" ) expect( receivedmessages[ 1 ].action ).to.equal( "telephone-event" ) expect( receivedmessages[ 2 ].action ).to.equal( "telephone-event" ) expect( receivedmessages[ 3 ].action ).to.equal( "mix" ) expect( receivedmessages[ 3 ].event ).to.equal( "finished" ) expect( receivedmessages[ 4 ].action ).to.equal( "close" ) expect( receivedmessages[ 0 ].event ).to.equal( "start" ) expect( receivedmessages[ 1 ].event ).to.equal( "4" ) expect( receivedmessages[ 2 ].event ).to.equal( "5" ) expect( receivedmessages[ 3 ].event ).to.equal( "finished" ) } ) it( "wefwef mix 2 channels - pcmu <-> pcma and send DTMF different 2833 pt", async function() { /* When mixing 2 channels, we expect the second leg to receive the 2833 packets and our server to emit events indicating the DTMF on the first channel. */ this.timeout( 3000 ) this.slow( 2000 ) const endpointa = dgram.createSocket( "udp4" ) const endpointb = dgram.createSocket( "udp4" ) const receivedmessages = [] let endpointapkcount = 0 let endpointbpkcount = 0 let dtmfpkcount = 0 endpointa.on( "message", function( msg ) { endpointapkcount++ expect( msg.length ).to.equal( 172 ) expect( 0x7f & msg [ 1 ] ).to.equal( 0 ) } ) endpointb.on( "message", function( msg ) { endpointbpkcount++ if( 101 == ( 0x7f & msg [ 1 ] ) ) { dtmfpkcount++ } else { expect( msg.length ).to.equal( 172 ) expect( 0x7f & msg [ 1 ] ).to.equal( 8 ) endpointb.send( msg, channelb.local.port, "localhost" ) } } ) endpointa.bind() await new Promise( ( resolve ) => { endpointa.on( "listening", function() { resolve() } ) } ) endpointb.bind() await new Promise( ( resolve ) => { endpointb.on( "listening", function() { resolve() } ) } ) let done const finished = new Promise( ( r ) => { done = r } ) const channela = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": endpointa.address().port, "codec": 0, "rfc2833pt": 127 } }, function( d ) { receivedmessages.push( d ) if( "close" === d.action ) channelb.close() } ) const channelb = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": endpointb.address().port, "codec": 8, "rfc2833pt": 101 } }, function( d ) { if( "close" === d.action ) done() } ) /* mix */ expect( channela.mix( channelb ) ).to.be.true /* send a packet every 20mS x 50 */ sendpk( 0, 0, 0, channela.local.port, endpointa ) sendpk( 1, 1*160, 1*20, channela.local.port, endpointa ) sendpk( 2, 2*160, 2*20, channela.local.port, endpointa ) sendpk( 3, 3*160, 3*20, channela.local.port, endpointa ) sendpk( 4, 4*160, 4*20, channela.local.port, endpointa ) sendpk( 5, 5*160, 5*20, channela.local.port, endpointa ) sendpk( 6, 6*160, 6*20, channela.local.port, endpointa ) sendpk( 7, 7*160, 7*20, channela.local.port, endpointa ) sendpk( 8, 8*160, 8*20, channela.local.port, endpointa ) sendpk( 9, 9*160, 9*20, channela.local.port, endpointa ) sendpk( 10, 10*160, 10*20, channela.local.port, endpointa ) sendpk( 11, 11*160, 11*20, channela.local.port, endpointa ) sendpk( 12, 12*160, 12*20, channela.local.port, endpointa ) senddtmf( 13, 13*160, 13*20, channela.local.port, endpointa, false, "4", 127 ) sendpk( 14, 13*160, 13*20, channela.local.port, endpointa, 0 ) sendpk( 15, 14*160, 14*20, channela.local.port, endpointa, 0 ) senddtmf( 16, (15*160)+10, (15*20)+10, channela.local.port, endpointa, false, "4", 127 ) sendpk( 17, 15*160, 15*20, channela.local.port, endpointa, 0 ) sendpk( 18, 16*160, 16*20, channela.local.port, endpointa, 0 ) senddtmf( 19, (17*160)+20, (17*20)+20, channela.local.port, endpointa, true, "4", 127 ) sendpk( 20, 17*160, 17*20, channela.local.port, endpointa, 0 ) sendpk( 21, 18*160, 18*20, channela.local.port, endpointa, 0 ) senddtmf( 22, (18*160)+30, (18*20)+30, channela.local.port, endpointa, true, "4", 127 ) sendpk( 23, 19*160, 19*20, channela.local.port, endpointa, 0 ) sendpk( 24, 20*160, 20*20, channela.local.port, endpointa, 0 ) sendpk( 25, 21*160, 21*20, channela.local.port, endpointa, 0 ) sendpk( 26, 22*160, 22*20, channela.local.port, endpointa, 0 ) sendpk( 27, 23*160, 23*20, channela.local.port, endpointa, 0 ) sendpk( 28, 24*160, 24*20, channela.local.port, endpointa, 0 ) sendpk( 29, 25*160, 25*20, channela.local.port, endpointa, 0 ) senddtmf( 30, 26*160, 26*20, channela.local.port, endpointa, false, "5", 127 ) sendpk( 31, 26*160, 26*20, channela.local.port, endpointa, 0 ) sendpk( 32, 27*160, 27*20, channela.local.port, endpointa, 0 ) senddtmf( 33, (27*160)+10, (27*20)+10, channela.local.port, endpointa, false, "5", 127 ) sendpk( 34, 28*160, 28*20, channela.local.port, endpointa, 0 ) sendpk( 35, 29*160, 28*20, channela.local.port, endpointa, 0 ) senddtmf( 36, (28*160)+20, (28*20)+20, channela.local.port, endpointa, true, "5", 127 ) sendpk( 37, 30*160, 29*20, channela.local.port, endpointa, 0 ) sendpk( 38, 31*160, 30*20, channela.local.port, endpointa, 0 ) senddtmf( 39, (38*160)+30, (30*20)+30, channela.local.port, endpointa, true, "5", 127 ) sendpk( 40, 32*160, 31*20, channela.local.port, endpointa, 0 ) sendpk( 41, 33*160, 32*20, channela.local.port, endpointa, 0 ) sendpk( 42, 34*160, 33*20, channela.local.port, endpointa, 0 ) sendpk( 43, 35*160, 34*20, channela.local.port, endpointa, 0 ) sendpk( 44, 36*160, 35*20, channela.local.port, endpointa, 0 ) sendpk( 45, 37*160, 36*20, channela.local.port, endpointa, 0 ) sendpk( 46, 38*160, 37*20, channela.local.port, endpointa, 0 ) sendpk( 47, 39*160, 38*20, channela.local.port, endpointa, 0 ) sendpk( 48, 40*160, 39*20, channela.local.port, endpointa, 0 ) sendpk( 49, 51*160, 40*20, channela.local.port, endpointa, 0 ) await new Promise( ( r ) => { setTimeout( () => r(), 1400 ) } ) channela.close() endpointa.close() endpointb.close() await finished expect( endpointapkcount ).to.be.within( 30, 51 ) expect( endpointbpkcount - dtmfpkcount ).to.be.within( 30, 51 ) expect( receivedmessages.length ).to.equal( 5 ) expect( dtmfpkcount ).to.be.within( ( pkcountperdtmfdigit * 2 ) - 4 , pkcountperdtmfdigit * 2 ) /* allow loss */ expect( receivedmessages[ 0 ].action ).to.equal( "mix" ) expect( receivedmessages[ 1 ].action ).to.equal( "telephone-event" ) expect( receivedmessages[ 2 ].action ).to.equal( "telephone-event" ) expect( receivedmessages[ 3 ].action ).to.equal( "mix" ) expect( receivedmessages[ 3 ].event ).to.equal( "finished" ) expect( receivedmessages[ 4 ].action ).to.equal( "close" ) expect( receivedmessages[ 0 ].event ).to.equal( "start" ) expect( receivedmessages[ 1 ].event ).to.equal( "4" ) expect( receivedmessages[ 2 ].event ).to.equal( "5" ) expect( receivedmessages[ 3 ].event ).to.equal( "finished" ) } ) it( "mix 3 channels - pcmu <-> pcma and ilbc and send DTMF", async function() { this.timeout( 3000 ) this.slow( 2000 ) const endpointa = dgram.createSocket( "udp4" ) const endpointb = dgram.createSocket( "udp4" ) const endpointc = dgram.createSocket( "udp4" ) let endpointapkcount = 0 let endpointbpkcount = 0 let endpointcpkcount = 0 let dtmfapkcount = 0 let dtmfbpkcount = 0 let dtmfcpkcount = 0 endpointa.on( "message", function( msg ) { endpointapkcount++ if( 101 == ( 0x7f & msg [ 1 ] ) ) { dtmfapkcount++ } else { expect( msg.length ).to.equal( 172 ) expect( 0x7f & msg [ 1 ] ).to.equal( 0 ) endpointb.send( msg, channelb.local.port, "localhost" ) } } ) endpointb.on( "message", function( msg ) { endpointbpkcount++ if( 101 == ( 0x7f & msg [ 1 ] ) ) { dtmfbpkcount++ } else { expect( msg.length ).to.equal( 172 ) expect( 0x7f & msg [ 1 ] ).to.equal( 8 ) endpointb.send( msg, channelb.local.port, "localhost" ) } } ) endpointc.on( "message", function( msg ) { endpointcpkcount++ if( 101 == ( 0x7f & msg [ 1 ] ) ) { dtmfcpkcount++ } else { expect( msg.length ).to.equal( 50 ) expect( 0x7f & msg [ 1 ] ).to.equal( 97 ) endpointb.send( msg, channelb.local.port, "localhost" ) } } ) endpointa.bind() await new Promise( ( resolve ) => { endpointa.on( "listening", function() { resolve() } ) } ) endpointb.bind() await new Promise( ( resolve ) => { endpointb.on( "listening", function() { resolve() } ) } ) endpointc.bind() await new Promise( ( resolve ) => { endpointc.on( "listening", function() { resolve() } ) } ) const receveiedmessages = [] const channela = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": endpointa.address().port, "codec": 0 } }, function( d ) { receveiedmessages.push( d ) if( "close" === d.action ) channelb.close() } ) const channelb = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": endpointb.address().port, "codec": 8 } }, function( d ) { expect( d.action).to.not.equal( "telephone-event" ) if( "close" === d.action ) channelc.close() } ) const channelc = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": endpointc.address().port, "codec": 97 } }, function( d ) { expect( d.action).to.not.equal( "telephone-event" ) if( "close" === d.action ) { endpointa.close() endpointb.close() endpointc.close() } } ) /* mix */ expect( channela.mix( channelb ) ).to.be.true expect( channela.mix( channelc ) ).to.be.true /* send a packet every 20mS x 50 */ /* NO FOR LOOPS for explicit readablity of the test */ sendpk( 0, 0, 0, channela.local.port, endpointa ) sendpk( 1, 1*160, 20, channela.local.port, endpointa ) sendpk( 2, 2*160, 2*20, channela.local.port, endpointa ) sendpk( 3, 3*160, 3*20, channela.local.port, endpointa ) sendpk( 4, 4*160, 4*20, channela.local.port, endpointa ) sendpk( 5, 5*160, 5*20, channela.local.port, endpointa ) sendpk( 6, 6*160, 6*20, channela.local.port, endpointa ) sendpk( 7, 7*160, 7*20, channela.local.port, endpointa ) sendpk( 8, 8*160, 8*20, channela.local.port, endpointa ) sendpk( 9, 9*160, 9*20, channela.local.port, endpointa ) sendpk( 10, 10*160, 10*20, channela.local.port, endpointa ) sendpk( 11, 11*160, 11*20, channela.local.port, endpointa ) sendpk( 12, 12*160, 12*20, channela.local.port, endpointa ) /* rfc2833 - 3.6: An audio source SHOULD start transmitting event packets as soon as it recognizes an event and every 50 ms thereafter or the packet interval for the audio codec used for this session, if known. This means our ts will not stay in sync with our sequence number - which increments with every packet. senddtmf( sn, ts, sendtime, port, socket, endofevent, event ) sendpk( sn, sendtime, port, socket, pt, ts, ssrc ) */ senddtmf( 13, 13*160, 13*20, channela.local.port, endpointa, false, "4" ) sendpk( 14, 13*160, 13*20, channela.local.port, endpointa, 0 ) sendpk( 15, 14*160, 14*20, channela.local.port, endpointa, 0 ) sendpk( 16, 15*160, 15*20, channela.local.port, endpointa, 0 ) senddtmf( 17, (15*160), (13*20)+50, channela.local.port, endpointa, false, "4" ) sendpk( 18, 16*160, 16*20, channela.local.port, endpointa, 0 ) sendpk( 19, 17*160, 17*20, channela.local.port, endpointa, 0 ) senddtmf( 20, (17*160), (13*20)+100, channela.local.port, endpointa, true, "4" ) sendpk( 21, 18*160, 18*20, channela.local.port, endpointa, 0 ) sendpk( 22, 19*160, 19*20, channela.local.port, endpointa, 0 ) sendpk( 23, 20*160, 20*20, channela.local.port, endpointa, 0 ) senddtmf( 24, (20*160), (13*20)+150, channela.local.port, endpointa, true, "4" ) sendpk( 25, 21*160, 21*20, channela.local.port, endpointa, 0 ) sendpk( 26, 22*160, 22*20, channela.local.port, endpointa, 0 ) sendpk( 27, 23*160, 23*20, channela.local.port, endpointa, 0 ) sendpk( 28, 24*160, 24*20, channela.local.port, endpointa, 0 ) sendpk( 29, 25*160, 25*20, channela.local.port, endpointa, 0 ) senddtmf( 30, 25*160, 25*20, channela.local.port, endpointa, false, "5" ) sendpk( 31, 26*160, 26*20, channela.local.port, endpointa, 0 ) sendpk( 32, 27*160, 27*20, channela.local.port, endpointa, 0 ) senddtmf( 33, (27*160), (25*20)+50, channela.local.port, endpointa, false, "5" ) sendpk( 34, 28*160, 28*20, channela.local.port, endpointa, 0 ) sendpk( 35, 29*160, 29*20, channela.local.port, endpointa, 0 ) senddtmf( 36, (29*160), (25*20)+100, channela.local.port, endpointa, true, "5" ) sendpk( 37, 30*160, 30*20, channela.local.port, endpointa, 0 ) sendpk( 38, 31*160, 31*20, channela.local.port, endpointa, 0 ) sendpk( 39, 32*160, 32*20, channela.local.port, endpointa, 0 ) senddtmf( 40, (32*160), (25*20)+150, channela.local.port, endpointa, true, "5" ) sendpk( 41, 33*160, 33*20, channela.local.port, endpointa, 0 ) sendpk( 42, 34*160, 34*20, channela.local.port, endpointa, 0 ) sendpk( 43, 35*160, 35*20, channela.local.port, endpointa, 0 ) sendpk( 44, 36*160, 36*20, channela.local.port, endpointa, 0 ) sendpk( 45, 37*160, 37*20, channela.local.port, endpointa, 0 ) sendpk( 46, 38*160, 38*20, channela.local.port, endpointa, 0 ) sendpk( 47, 39*160, 39*20, channela.local.port, endpointa, 0 ) sendpk( 48, 40*160, 40*20, channela.local.port, endpointa, 0 ) sendpk( 49, 41*160, 41*20, channela.local.port, endpointa, 0 ) sendpk( 50, 42*160, 42*20, channela.local.port, endpointa, 0 ) sendpk( 51, 43*160, 43*20, channela.local.port, endpointa, 0 ) sendpk( 52, 44*160, 44*20, channela.local.port, endpointa, 0 ) sendpk( 53, 45*160, 45*20, channela.local.port, endpointa, 0 ) sendpk( 54, 46*160, 46*20, channela.local.port, endpointa, 0 ) sendpk( 55, 47*160, 47*20, channela.local.port, endpointa, 0 ) sendpk( 56, 48*160, 48*20, channela.local.port, endpointa, 0 ) sendpk( 57, 49*160, 49*20, channela.local.port, endpointa, 0 ) sendpk( 58, 50*160, 50*20, channela.local.port, endpointa, 0 ) sendpk( 59, 52*160, 51*20, channela.local.port, endpointa, 0 ) await new Promise( ( resolve ) => { setTimeout( () => resolve(), 1200 ) } ) channela.close() await Promise.all( [ new Promise( resolve => { endpointa.on( "close", resolve ) } ), new Promise( resolve => { endpointb.on( "close", resolve ) } ), new Promise( resolve => { endpointc.on( "close", resolve ) } ) ] ) expect( endpointapkcount ).to.be.within( 59, 70 ) expect( endpointbpkcount - dtmfbpkcount ).to.be.within( 59, 70 ) expect( endpointcpkcount - dtmfcpkcount ).to.be.within( 59, 70 ) // 3 after we return to the event loop and enter the callback with close event. expect( dtmfapkcount ).to.equal( 0 ) expect( dtmfbpkcount ).to.be.within( ( pkcountperdtmfdigit * 2 ) - 4, pkcountperdtmfdigit * 2 ) expect( dtmfcpkcount ).to.be.within( ( pkcountperdtmfdigit * 2 ) - 4, pkcountperdtmfdigit * 2 ) expect( receveiedmessages[ 0 ].action ).to.equal( "mix" ) expect( receveiedmessages[ 1 ].action ).to.equal( "mix" ) expect( receveiedmessages[ 2 ].action ).to.equal( "telephone-event" ) expect( receveiedmessages[ 3 ].action ).to.equal( "telephone-event" ) expect( receveiedmessages[ 4 ].action ).to.equal( "mix" ) expect( receveiedmessages[ 5 ].action ).to.equal( "close" ) expect( receveiedmessages[ 0 ].event ).to.equal( "start" ) expect( receveiedmessages[ 1 ].event ).to.equal( "start" ) expect( receveiedmessages[ 2 ].event ).to.equal( "4" ) expect( receveiedmessages[ 3 ].event ).to.equal( "5" ) expect( receveiedmessages[ 4 ].event ).to.equal( "finished" ) } ) it( "DTMF captured not working", async function() { /* create our RTP/UDP endpoint */ const server = dgram.createSocket( "udp4" ) server.on( "message", function() {} ) this.timeout( 3000 ) this.slow( 2500 ) let done const finished = new Promise( ( r ) => { done = r } ) server.bind() server.on( "listening", async function() { const ourport = server.address().port let expectedmessagecount = 0 const expectedmessages = [ { action: "telephone-event", event: "3" }, { action: "close" } ] const channel = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": ourport, "codec": 0 } }, function( d ) { expect( d ).to.deep.include( expectedmessages[ expectedmessagecount ] ) expectedmessagecount++ if( "close" === d.action ) { server.close() done() } } ) expect( channel.echo() ).to.be.true // Event "3" const dstport = channel.local.port sendpk( 948, 148480, 0, dstport, server, 0, 518218235 ) sendpayload( 20, fromstr( "80 e5 03 b5 00 02 44 a0 1e e3 61 fb 03 0a 00 a0 4c d1" ), dstport, server ) sendpk( 950, 148800, 40, dstport, server, 0, 518218235 ) sendpayload( 60, fromstr( "80 65 03 b7 00 02 44 a0 1e e3 61 fb 03 0a 01 40 25 b8" ), dstport, server ) sendpk( 952, 149120, 80, dstport, server, 0, 518218235 ) sendpayload( 100, fromstr( "80 65 03 b9 00 02 44 a0 1e e3 61 fb 03 0a 01 e0 e8 81" ), dstport, server ) sendpk( 954, 149440,120, dstport, server, 0, 518218235 ) sendpayload( 140, fromstr( "80 65 03 bb 00 02 44 a0 1e e3 61 fb 03 0a 02 80 e2 74" ), dstport, server ) sendpk( 956, 149760, 160, dstport, server, 0, 518218235 ) sendpayload( 180, fromstr( "80 65 03 bd 00 02 44 a0 1e e3 61 fb 03 0a 03 20 1f bb" ), dstport, server ) sendpk( 958, 150080, 200, dstport, server, 0, 518218235 ) sendpayload( 220, fromstr( "80 65 03 bf 00 02 44 a0 1e e3 61 fb 03 0a 03 c0 13 0c" ), dstport, server ) sendpk( 960, 150400,240, dstport, server, 0, 518218235 ) sendpayload( 260, fromstr( "80 65 03 c1 00 02 44 a0 1e e3 61 fb 03 0a 04 60 2e bf" ), dstport, server ) sendpk( 962, 150720, 280, dstport, server, 0, 518218235 ) sendpayload( 300, fromstr( "80 65 03 c3 00 02 44 a0 1e e3 61 fb 03 8a 04 60 05 c1" ), dstport, server ) sendpayload( 320 ,fromstr( "80 65 03 c4 00 02 44 a0 1e e3 61 fb 03 8a 04 60 bb 69" ), dstport, server ) sendpk( 965, 151200, 340, dstport, server, 0, 518218235 ) sendpayload( 360, fromstr( "80 65 03 c6 00 02 44 a0 1e e3 61 fb 03 8a 04 60 1e 27" ), dstport, server ) sendpk( 967, 151520, 380, dstport, server, 0, 518218235 ) sendpk( 968, 151680, 400, dstport, server, 0, 518218235 ) sendpk( 969, 151840, 420, dstport, server, 0, 518218235 ) sendpk( 970, 152000, 440, dstport, server, 0, 518218235 ) setTimeout( () => channel.close(), 25*20 ) } ) await finished } ) it( "DTMF PCAP playback test 1", async function() { this.timeout( 21000 ) this.slow( 20000 ) let done const finished = new Promise( ( r ) => { done = r } ) const receivedmessages = [] /* create our RTP/UDP endpoint */ const server = dgram.createSocket( "udp4" ) server.on( "message", function() {} ) server.bind() server.on( "listening", async function() { const ourport = server.address().port const channel = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": ourport, "codec": 0 } }, function( d ) { receivedmessages.push( d ) if( "close" === d.action ) { server.close() done() } } ) setTimeout( () => channel.close(), 1000 * 17 ) const dstport = channel.local.port channel.play( { "interupt":true, "files": [ { "wav": "test/interface/pcaps/180fa1ac-08e5-11ed-bd4d-02dba5b5aad6.wav" } ] } ) const ourpcap = await pcap.readpcap( "test/interface/pcaps/dtmfcapture1.pcap" ) const offset = 4700 ourpcap.forEach( ( packet ) => { if( packet.ipv4 && packet.ipv4.udp && 10230 == packet.ipv4.udp.dstport ) { //console.dir( packet, { depth: null } ) //console.log(packet.ipv4.udp.data.readUInt16BE( 2 ) ) //const sn = packet.ipv4.udp.data.readUInt16BE( 2 ) sendpayload( ( 1000 * packet.ts_sec_offset ) - offset, packet.ipv4.udp.data, dstport, server ) } } ) } ) await finished const expectedmessages = [ { action: "play", event: "start", reason: "new" }, { action: "play", event: "end", reason: "telephone-event" }, { action: "telephone-event", event: "2" }, { action: "close" } ] expect( receivedmessages.length ).to.equal( 4 ) expect( receivedmessages[ 0 ] ).to.deep.include( expectedmessages[ 0 ] ) expect( receivedmessages[ 1 ] ).to.deep.include( expectedmessages[ 1 ] ) expect( receivedmessages[ 2 ] ).to.deep.include( expectedmessages[ 2 ] ) expect( receivedmessages[ 3 ] ).to.deep.include( expectedmessages[ 3 ] ) } ) it( "DTMF PCAP playback test 2", async function() { this.timeout( 21000 ) this.slow( 20000 ) let done const finished = new Promise( ( r ) => { done = r } ) const receivedmessages = [] /* create our RTP/UDP endpoint */ const server = dgram.createSocket( "udp4" ) server.on( "message", function() {} ) server.bind() server.on( "listening", async function() { const ourport = server.address().port const channel = await projectrtp.openchannel( { "remote": { "address": "localhost", "port": ourport, "codec": 0 } }, function( d ) { receivedmessages.push( d ) if( "close" === d.action ) { server.close() done() } } ) setTimeout( () => channel.close(), 1000 * 17 ) const dstport = channel.local.port channel.play( { "interupt":true, "files": [ { "wav": "test/interface/pcaps/180fa1ac-08e5-11ed-bd4d-02dba5b5aad6.wav" } ] } ) const ourpcap = await pcap.readpcap( "test/interface/pcaps/dtmf3presses.pcap" ) const offset = 17 * 1000 ourpcap.forEach( ( packet ) => { if( packet.ipv4 && packet.ipv4.udp && 10298 == packet.ipv4.udp.dstport ) { //console.dir( packet, { depth: null } ) //console.log(packet.ipv4.udp.data.readUInt16BE( 2 ) ) //const sn = packet.ipv4.udp.data.readUInt16BE( 2 ) const sendat = ( 1000 * packet.ts_sec_offset ) - offset if ( 0 < sendat ) { //console.log(sn, sendat) sendpayload( sendat, packet.ipv4.udp.data, dstport, server ) } } } ) } ) await finished const expectedmessages = [ { action: "play", event: "start", reason: "new" }, { action: "play", event: "end", reason: "telephone-event" }, { action: "telephone-event", event: "1" }, { action: "telephone-event", event: "1" }, { action: "telephone-event", event: "1" }, { action: "close" } ] expect( receivedmessages.length ).to.equal( 6 ) expect( receivedmessages[ 0 ] ).to.deep.include( expectedmessages[ 0 ] ) expect( receivedmessages[ 1 ] ).to.deep.include( expectedmessages[ 1 ] ) expect( receivedmessages[ 2 ] ).to.deep.include( expectedmessages[ 2 ] ) expect( receivedmessages[ 3 ] ).to.deep.include( expectedmessages[ 3 ] ) expect( receivedmessages[ 4 ] ).to.deep.include( expectedmessages[ 4 ] ) expect( receivedmessages[ 5 ] ).to.deep.include( expectedmessages[ 5 ] ) } ) } )