Binciko injin Mediastreamer2 VoIP. Kashi na 7

An ɗauko kayan labarin daga nawa zen channel.

Binciko injin Mediastreamer2 VoIP. Kashi na 7

Amfani da TShark don nazarin fakitin RTP

Binciko injin Mediastreamer2 VoIP. Kashi na 7

A karshe labarin Mun hada na'ura mai sarrafa nesa daga na'urar samar da sautin sauti da na'urar gano sauti, sadarwa tsakanin wacce aka gudanar ta hanyar amfani da rafin RTP.

A cikin wannan labarin, muna ci gaba da nazarin watsa siginar sauti ta amfani da ka'idar RTP. Da farko, bari mu raba aikace-aikacen gwajin mu zuwa mai watsawa da mai karɓa kuma mu koyi yadda ake bincika rafin RTP ta amfani da na'urar tantance zirga-zirgar hanyar sadarwa.

Don haka, ta yadda za mu iya ƙara fahimtar abubuwan shirin ke da alhakin watsa RTP kuma waɗanda ke da alhakin karɓa, za mu raba fayil ɗin mstest6.c zuwa shirye-shirye masu zaman kansu guda biyu don mai watsawa da mai karɓa; za mu sanya ayyukan gama gari waɗanda duka biyu suke amfani da su. a cikin fayil na uku , wanda za mu kira mstest_common.c, za a haɗa shi ta hanyar watsawa da mai karɓa ta amfani da umarnin sun haɗa da:

/* Файл 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;
}

Yanzu fayil ɗin watsawa daban:

/* Файл 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("Отправлена команда: %cn", 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);
  }
}

Kuma a ƙarshe, fayil ɗin mai karɓa:

/* Файл 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("Принята команда: %sn", 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); 
 }
}

Muna tattara na'urar watsawa da mai karɓa, sannan mu ƙaddamar da kowanne a cikin na'urar na'urar sa. Sa'an nan kuma ya kamata ya yi aiki kamar da - kawai ya kamata mu shigar da lambobi daga 1 zuwa 6 a cikin na'ura mai watsawa, kuma amsa gare su ya kamata ya bayyana a cikin na'ura mai karɓa. Sautuna ya kamata a ji a cikin lasifikar. Idan komai ya kasance, to, mun kafa haɗin kai tsakanin mai karɓa da mai watsawa - akwai ci gaba da watsa fakitin RTP daga mai aikawa zuwa mai karɓa.

Yanzu ne lokacin da za a shigar da mai nazarin zirga-zirga; don wannan za mu shigar da nau'in wasan bidiyo na kyakkyawan shirin Wireshark - ana kiransa TShark. Na zaɓi TShark don ƙarin tattaunawa don sauƙaƙe bayanin sarrafa shirin. Tare da Wireshark, Ina buƙatar teku na hotunan kariyar kwamfuta, wanda zai iya zama da sauri lokacin da aka fitar da sabon sigar Wireshark.

Idan kun san yadda ake amfani da Wireshark, zaku iya amfani da shi don nazarin misalan mu. Amma ko da a wannan yanayin, Ina ba da shawarar ku ƙware TShark, saboda zai taimaka muku sarrafa sarrafa aikace-aikacen VoIP ɗin ku, da kuma yin kama daga nesa.

Shigar TShark tare da umarni:

$ sudo apt-get install tshark

A al'ada, muna duba sakamakon shigarwa ta hanyar neman sigar shirin:

$ tshark --version

Idan an sami isasshiyar amsa, za mu ci gaba.

Tun da fakitinmu kawai ke shiga cikin kwamfutar a yanzu, za mu iya gaya wa tshark ya nuna irin waɗannan fakitin kawai. Don yin wannan, kuna buƙatar zaɓar ɗaukar fakiti daga mahaɗin madaukai (loopback) ta hanyar wucewa TShark zaɓi -ilo:

$ sudo tshark -i lo

Saƙonni game da fakitin da mai watsa mu ya aiko nan take za su fara zubowa cikin na'ura mai kwakwalwa (ci gaba, ko da mun danna maballin a kan ramut ko a'a). Wataƙila akwai shirye-shirye a kan kwamfutarka waɗanda suma suna aika fakiti ta hanyar madauki na gida, wanda a cikin wannan yanayin za mu karɓi cakuɗen fakiti na mu da sauran mutane. Don tabbatar da cewa a cikin jerin muna ganin fakiti ne kawai da aka aika ta hanyar remut ɗin mu, za mu ƙara tace ta lambar tashar jiragen ruwa. Ta latsa Ctrl-C za mu dakatar da mai nazari kuma mu shigar da tace don lambar tashar jiragen ruwa da na'urar ramut ke amfani da ita azaman tashar tashar tashar don watsawa (8010): -f "udp tashar jiragen ruwa 8010". Yanzu layin umarni namu zai yi kama da haka:

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

Fitowar mai zuwa zata bayyana a cikin na'ura wasan bidiyo (layi 10 na farko):

 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

A yanzu, waɗannan ba fakiti ba ne, amma jerin abubuwan da suka faru ne masu ƙididdigewa, inda kowane layi saƙo ne game da fakiti na gaba wanda aka lura akan mahaɗin. Tun da mun riga mun kula da tace fakiti, muna gani a cikin jeri kawai saƙonnin game da fakiti daga masu watsa mu. Na gaba, bari mu decipher wannan tebur ta lambobi shafi:

Lambar taron.
Lokacin faruwarsa.
Adireshin IP na tushen fakitin da adireshin IP na fakitin.
Ana nuna ƙa'idar fakitin azaman UDP saboda ana aika fakitin RTP azaman kaya a cikin fakitin UDP.
Girman fakiti a cikin bytes.
Lambar tushen fakitin tashar jiragen ruwa da lambar tashar tashar tashar fakitin.
Girman nauyin fakitin, daga nan za mu iya yanke cewa mai watsa mu yana samar da fakitin RTP masu girman 172 bytes, wanda, kamar duck a cikin kirji, yana cikin fakitin UDP na 214 bytes a girman.
Yanzu lokaci ya yi da za a duba cikin fakitin UDP, don wannan za mu ƙaddamar da TShark tare da faɗaɗa maɓalli:

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

Sakamakon haka, fitowar shirin za a arzuta - ɓarna abubuwan ciki na fakitin da ya haifar da shi za a ƙara shi zuwa kowane taron. Don ƙarin kallon fitarwa, zaku iya dakatar da TShark ta latsa Ctrl-C, ko kwafin fitowar sa zuwa fayil ta ƙara bututun zuwa shirin tee zuwa umarnin gudu, ƙididdige sunan fayil, tee <filename>:

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

Yanzu bari mu ga abin da muka samu a cikin fayil ɗin, ga kunshin farko daga gare ta:

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                                  ......

Za mu sadaukar da labarin na gaba don nazarin bayanan da ke cikin wannan jeri kuma ba makawa za mu yi magana game da tsarin ciki na kunshin RTP.

source: www.habr.com

Add a comment