Estudiamos el motor VoIP Mediastreamer2. Parte 7

Material del artículo tomado de mi canal zen .



Usando TShark para analizar paquetes RTP


Vista del paquete RTP capturado


En el último artículo, ensamblamos un circuito de control remoto desde un generador y un detector de señales tonales, cuya comunicación se llevó a cabo utilizando un flujo RTP.


RTP-. RTP- .


, RTP, , mstest6.c , , , mstest_common.c, include:


/*  mstest_common.c      . */
#include <mediastreamer2/msfilter.h>
#include <mediastreamer2/msticker.h>
#include <mediastreamer2/msrtp.h>
#include <ortp/rtpsession.h>
#include <ortp/payloadtype.h>

define PCMU 0

/*---------------------------------------------------------*/
/*     . */
void register_payloads(void)
{  
 /*      . ,       
       RTP-          
     ,     . */
  rtp_profile_set_payload (&av_profile, PCMU, &payload_type_pcm8000);
}

/*---------------------------------------------------------*/
/*      create_duplex_rtpsession()  audiostream.c   2. */
 static RtpSession *create_rtpsession (int loc_rtp_port, int loc_rtcp_port,  bool_t ipv6, RtpSessionMode mode)
{  
  RtpSession *rtpr;  rtpr = rtp_session_new ((int) mode);  
  rtp_session_set_scheduling_mode (rtpr, 0);  
  rtp_session_set_blocking_mode (rtpr, 0);
  rtp_session_enable_adaptive_jitter_compensation (rtpr, TRUE);
  rtp_session_set_symmetric_rtp (rtpr, TRUE); 
  rtp_session_set_local_addr (rtpr, ipv6 ? "::" : "0.0.0.0", loc_rtp_port,  loc_rtcp_port); 
  rtp_session_signal_connect (rtpr, "timestamp_jump",  (RtpCallback) rtp_session_resync, 0);
  rtp_session_signal_connect (rtpr, "ssrc_changed",  (RtpCallback) rtp_session_resync, 0);
  rtp_session_set_ssrc_changed_threshold (rtpr, 0);
  rtp_session_set_send_payload_type(rtpr, PCMU);

  /*    RTCP-,        
  . */  
 rtp_session_enable_rtcp (rtpr, FALSE);
 return rtpr;
}

:


/*  mstest6.c    (). */
#include <mediastreamer2/dtmfgen.h>
#include <mediastreamer2/msrtp.h>
#include "mstest_common.c"

/*----------------------------------------------------------*/
int main()
{ 
  ms_init();

/*   . */
  MSFilter *voidsource = ms_filter_new(MS_VOID_SOURCE_ID); 
  MSFilter *dtmfgen = ms_filter_new(MS_DTMF_GEN_ID);

/*   . */
  MSFilter *encoder = ms_filter_create_encoder("PCMU");

/*   . */
  register_payloads();

/*  RTP- . */
  RtpSession *tx_rtp_session = create_rtpsession (8010, 8011, FALSE, RTP_SESSION_SENDONLY);  
 rtp_session_set_remote_addr_and_port(tx_rtp_session,"127.0.0.1", 7010, 7011); 
 rtp_session_set_send_payload_type(tx_rtp_session, PCMU);  
 MSFilter *rtpsend = ms_filter_new(MS_RTP_SEND_ID); 
 ms_filter_call_method(rtpsend, MS_RTP_SEND_SET_SESSION, tx_rtp_session);

/*    - . */ 
 MSTicker *ticker_tx = ms_ticker_new();

/*   . */ 
 ms_filter_link(voidsource, 0, dtmfgen, 0);  
 ms_filter_link(dtmfgen, 0, encoder, 0);
 ms_filter_link(encoder, 0, rtpsend, 0);

/*   . */
  ms_ticker_attach(ticker_tx, voidsource);

/*  ,    . */ 
 MSDtmfGenCustomTone dtmf_cfg; 
 dtmf_cfg.tone_name[0] = 0; 
 dtmf_cfg.duration = 1000; 
 dtmf_cfg.frequencies[0] = 440;

/*    ,      0. */  
 dtmf_cfg.frequencies[1] = 0; 
 dtmf_cfg.amplitude = 1.0; 
 dtmf_cfg.interval = 0.;  
 dtmf_cfg.repeat_count = 0.;

/*     .   
*    . */  
 char key='9'; 
 printf("  ,  .\n"  
"    0.\n");  
while(key != '0')  
{
 key = getchar();   
 if ((key >= 49) && (key <= 54)) 
   {
      printf(" : %c\n", key);
      /*      
       *   . */
      dtmf_cfg.frequencies[0] = 440 + 100*(key-49);

      /*    c  . */
      ms_filter_call_method(dtmfgen, MS_DTMF_GEN_PLAY_CUSTOM,      (void*)&dtmf_cfg); 
   }
   /*      20,    
   *     . */ 
  ms_usleep(20000);
  }
}

, :


/*  mstest7.c  . */
include <mediastreamer2/mssndcard.h>
include <mediastreamer2/mstonedetector.h>
include <mediastreamer2/msrtp.h>

/*         .*/
include <mediastreamer2/mseventqueue.h>
/*    . */
include "mstest_common.c"

/*   ,    ,            . */
static void tone_detected_cb(void *data, MSFilter *f, unsigned int event_id,MSToneDetectorEvent *ev)
{ 
 printf(" : %s\n", ev->tone_name);
}

/*----------------------------------------------------------*/
int main()
{ 
 ms_init();

/*   . */  
 MSSndCard *card_playback =  ms_snd_card_manager_get_default_card(ms_snd_card_manager_get()); 
 MSFilter *snd_card_write = ms_snd_card_create_writer(card_playback); 
 MSFilter *detector = ms_filter_new(MS_TONE_DETECTOR_ID);

/*      ,  
*    .*/
  ms_filter_call_method(detector, MS_TONE_DETECTOR_CLEAR_SCANS, 0);

/*      . */  
ms_filter_set_notify_callback(detector,  (MSFilterNotifyFunc)tone_detected_cb, NULL);

/*  ,     
*   ,   :
 
*  ,   ,   ,
*    0,775. */
  MSToneDetectorDef scan[6]= 
 {   
    {"V+",440, 100, 0.1}, /*  " ". */
    {"V-",540, 100, 0.1}, /*  " ". */
    {"C+",640, 100, 0.1}, /*  "  ". */
    {"C-",740, 100, 0.1}, /*  "  ". */
    {"ON",840, 100, 0.1}, /*  " ". */
    {"OFF", 940, 100, 0.1}/*  " ". */
  };

/*  ""   . */
  int i; 
 for (i = 0; i < 6; i++) 
 { 
   ms_filter_call_method(detector, MS_TONE_DETECTOR_ADD_SCAN,    &scan[i]); 
 }

/*    */
  MSFilter *decoder=ms_filter_create_decoder("PCMU");

/*   . */
  register_payloads();

/*  RTP- . */
  MSFilter *rtprecv = ms_filter_new(MS_RTP_RECV_ID);
  RtpSession *rx_rtp_session = create_rtpsession (7010, 7011, FALSE, RTP_SESSION_RECVONLY);
  ms_filter_call_method(rtprecv, MS_RTP_RECV_SET_SESSION, rx_rtp_session);

/*    - . */ 
 MSTicker *ticker_rx = ms_ticker_new();

/*   . */
  ms_filter_link(rtprecv, 0, decoder, 0);
  ms_filter_link(decoder, 0, detector, 0);
  ms_filter_link(detector, 0, snd_card_write, 0);

/*   . */
  ms_ticker_attach(ticker_rx, rtprecv);
  char key='9';
  printf( "    0.\n");
  while(key != '0') 
 {
    key = getchar();
   /*      20,       *     . */
   ms_usleep(20000); 
 }
}

, , . — 1 6 , . . , — RTP- .


, Wireshrk — TShark. TShark , . Wireshark , Wireshark.


Wireshark, . TShark, VoIP , .


TShark :


sudo apt-get install tshark

, :


tshark --version

.


, tshark . loopback ( ), TShark -i lo:


sudo tshark -i lo

(, , ). , , . , , . Ctrl-C (8010): -f "udp port 8010". :


sudo tshark -i lo -f "udp port 8010"

( 10 ):


 1 0.000000000    127.0.0.1 → 127.0.0.1    UDP 214 8010 → 7010 Len=172 
 2 0.020059705    127.0.0.1 → 127.0.0.1    UDP 214 8010 → 7010 Len=172
 3 0.040044409    127.0.0.1 → 127.0.0.1    UDP 214 8010 → 7010 Len=172 
 4 0.060057104    127.0.0.1 → 127.0.0.1    UDP 214 8010 → 7010 Len=172
 5 0.080082311    127.0.0.1 → 127.0.0.1    UDP 214 8010 → 7010 Len=172  
 6 0.100597153    127.0.0.1 → 127.0.0.1    UDP 214 8010 → 7010 Len=172 
 7 0.120122668    127.0.0.1 → 127.0.0.1    UDP 214 8010 → 7010 Len=172
 8 0.140204789    127.0.0.1 → 127.0.0.1    UDP 214 8010 → 7010 Len=172
 9 0.160719008    127.0.0.1 → 127.0.0.1    UDP 214 8010 → 7010 Len=172
10 0.180673685    127.0.0.1 → 127.0.0.1    UDP 214 8010 → 7010 Len=172

, , , . , , . :


.
.
IP- IP- .
, UDP, RTP- UDP-.
.
.
, , RTP- 172 , , , UDP- 214 .
UDP-, TShark :


sudo tshark -i lo -f "udp port 8010"  -P -V -O rtp -o rtp.heuristic_rtp:TRUE -x

Como resultado, la salida del programa se enriquecerá: se agregará a cada evento un descifrado del contenido interno del paquete que lo causó. Para ver mejor los datos de salida, puede detener TShark presionando Ctrl-C, o duplicar su salida a un archivo agregando una tubería al programa tee con el nombre del archivo, tee <nombre de archivo> al comando de inicio:


sudo tshark -i lo -f "udp port 8010"  -P -V -O rtp -o rtp.heuristic_rtp:TRUE -x | tee  log.txt

Ahora veamos lo que tenemos en el archivo, aquí está el primer paquete de él:


1 0.000000000    127.0.0.1 → 127.0.0.1    RTP 214 PT=ITU-T G.711 PCMU, SSRC=0x6B8B4567, Seq=58366, Time=355368720
Frame 1: 214 bytes on wire (1712 bits), 214 bytes captured (1712 bits) on interface 0
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00 (00:00:00:00:00:00)
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1User Datagram Protocol, Src Port: 8010, Dst Port: 7010
Real-Time Transport Protocol    [Stream setup by HEUR RT (frame 1)]
        [Setup frame: 1] 
       [Setup Method: HEUR RT]
    10.. .... = Version: RFC 1889 Version (2)
    ..0. .... = Padding: False
    ...0 .... = Extension: False
    .... 0000 = Contributing source identifiers count: 0   
   0... .... = Marker: False
    Payload type: ITU-T G.711 PCMU (0)
    Sequence number: 58366    [Extended sequence number: 58366]
    Timestamp: 355368720
    Synchronization Source identifier: 0x6b8b4567 (1804289383)
    Payload: ffffffffffffffffffffffffffffffffffffffffffffffff...

0000  00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00   ..............E.
0010  00 c8 3c 69 40 00 40 11 ff b9 7f 00 00 01 7f 00   ..<i@.@.........
0020  00 01 1f 4a 1b 62 00 b4 fe c7 80 00 e3 fe 15 2e   ...J.b..........
0030  7f 10 6b 8b 45 67 ff ff ff ff ff ff ff ff ff ff   ..k.Eg..........
0040  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0050  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0060  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0070  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0080  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0090  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
00a0  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
00b0  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
00c0  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
00d0  ff ff ff ff ff ff                                  ......

Dedicaremos el siguiente artículo al análisis de la información contenida en este listado e inevitablemente hablaremos sobre la estructura interna del paquete RTP.


All Articles