Π˜Π·ΡƒΡ‡Π°Π΅ΠΌ VoIP-Π΄Π²ΠΈΠΆΠΎΠΊ Mediastreamer2. Π§Π°ΡΡ‚ΡŒ 9

ΠœΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π» ΡΡ‚Π°Ρ‚ΡŒΠΈ взят с ΠΌΠΎΠ΅Π³ΠΎ Π΄Π·Π΅Π½-ΠΊΠ°Π½Π°Π»Π°.

ДуплСксноС ΠΏΠ΅Ρ€Π΅Π³ΠΎΠ²ΠΎΡ€Π½ΠΎΠ΅ устройство

Π˜Π·ΡƒΡ‡Π°Π΅ΠΌ VoIP-Π΄Π²ΠΈΠΆΠΎΠΊ Mediastreamer2. Π§Π°ΡΡ‚ΡŒ 9

Π’ ΠΏΡ€ΠΎΡˆΠ»ΠΎΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ Π±Ρ‹Π»ΠΎ анонсировано дуплСксноС ΠΏΠ΅Ρ€Π΅Π³ΠΎΠ²ΠΎΡ€Π½ΠΎΠ΅ устройство, Π° Π² этой ΠΌΡ‹ Π΅Π³ΠΎ сдСлаСм.

Π‘Ρ…Π΅ΠΌΠ° ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½Π° Π½Π° Π·Π°Π³Π»Π°Π²Π½ΠΎΠΌ рисункС. НиТняя Ρ†Π΅ΠΏΡŒ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ² ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‰ΠΈΠΉ Ρ‚Ρ€Π°ΠΊΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ начинаСтся со Π·Π²ΡƒΠΊΠΎΠ²ΠΎΠΉ ΠΊΠ°Ρ€Ρ‚Ρ‹. Она Π²Ρ‹Π΄Π°Π΅Ρ‚ отсчСты сигнала с ΠΌΠΈΠΊΡ€ΠΎΡ„ΠΎΠ½Π°. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ это происходит Π² Ρ‚Π΅ΠΌΠΏΠ΅ 8000 отсчСтов Π² сСкунду. Π Π°Π·Ρ€ΡΠ΄Π½ΠΎΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Π·Π²ΡƒΠΊΠΎΠ²Ρ‹Π΅ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Ρ‹ мСдиастримСра β€” 16 Π±ΠΈΡ‚ ( это Π½Π΅ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠΈΠ°Π»ΡŒΠ½ΠΎ, ΠΏΡ€ΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Ρ‹ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с большСй Ρ€Π°Π·Ρ€ΡΠ΄Π½ΠΎΡΡ‚ΡŒΡŽ). Π”Π°Π½Π½Ρ‹Π΅ сгруппированы Π² Π±Π»ΠΎΠΊΠΈ ΠΏΠΎ 160 отсчСтов. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π±Π»ΠΎΠΊ ΠΈΠΌΠ΅Π΅Ρ‚ Ρ€Π°Π·ΠΌΠ΅Ρ€ 320 Π±Π°ΠΉΡ‚. Π”Π°Π»Π΅Π΅ ΠΌΡ‹ ΠΏΠΎΠ΄Π°Π΅ΠΌ Π΄Π°Π½Π½Ρ‹Π΅ Π½Π° Π²Ρ…ΠΎΠ΄ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π² Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Π½ΠΎΠΌ состоянии "ΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π΅Π½" для Π΄Π°Π½Π½Ρ‹Ρ…. Π― Π΅Π³ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΠ» Π½Π° Ρ‚ΠΎΡ‚ случай, ΠΊΠΎΠ³Π΄Π° Π²Π°ΠΌ ΠΏΡ€ΠΈ ΠΎΡ‚Π»Π°Π΄ΠΊΠ΅ надоСст Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ΡŒ Π² ΠΌΠΈΠΊΡ€ΠΎΡ„ΠΎΠ½ β€” Π²Ρ‹ смоТСтС Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ "ΠΏΡ€ΠΎΡΡ‚Ρ€Π΅Π»ΠΈΡ‚ΡŒ" Ρ‚Ρ€Π°ΠΊΡ‚ Ρ‚ΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΌ сигналом.

ПослС Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° сигнал ΠΏΠΎΠΏΠ°Π΄Π°Π΅Ρ‚ Π½Π° ΠΊΠΎΠ΄Π΅Ρ€, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ наши 16-Π±ΠΈΡ‚Π½Ρ‹Π΅ отсчСты ΠΏΠΎ Β΅-Π·Π°ΠΊΠΎΠ½Ρƒ (стандарт G.711) Π² Π²ΠΎΡΡŒΠΌΠΈΠ±ΠΈΡ‚Π½Ρ‹Π΅. На Π²Ρ‹Ρ…ΠΎΠ΄Π΅ ΠΊΠΎΠ΄Π΅Ρ€Π° ΠΌΡ‹ ΡƒΠΆΠ΅ ΠΈΠΌΠ΅Π΅ΠΌ Π±Π»ΠΎΠΊ Π΄Π°Π½Π½Ρ‹Ρ… Π² Π΄Π²Π° Ρ€Π°Π·Π° мСньшСго Ρ€Π°Π·ΠΌΠ΅Ρ€Π°. Π’ ΠΎΠ±Ρ‰Π΅ΠΌ случаС, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ Π±Π΅Π· сТатия, Ссли Π½Π°ΠΌ Π½Π΅ трСбуСтся ΡΠΊΠΎΠ½ΠΎΠΌΠΈΡ‚ΡŒ Ρ‚Ρ€Π°Ρ„ΠΈΠΊ. Но здСсь ΠΏΠΎΠ»Π΅Π·Π½ΠΎ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΊΠΎΠ΄Π΅Ρ€ΠΎΠΌ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Wireshark ΠΌΠΎΠΆΠ΅Ρ‚ Π²ΠΎΡΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ΡŒ Π·Π²ΡƒΠΊ ΠΈΠ· RTP-ΠΏΠΎΡ‚ΠΎΠΊΠ° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎΠ³Π΄Π° ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ сТат ΠΏΠΎ Β΅-Π·Π°ΠΊΠΎΠ½Ρƒ ΠΈΠ»ΠΈ Π°-Π·Π°ΠΊΠΎΠ½Ρƒ.

ПослС ΠΊΠΎΠ΄Π΅Ρ€Π°, ΠΏΠΎΠ»Π΅Π³Ρ‡Π°Π²ΡˆΠΈΠ΅ Π±Π»ΠΎΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠΎΡΡ‚ΡƒΠΏΠ°ΡŽΡ‚ Π½Π° Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ rtpsend, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚ ΠΈΡ… Π² RTP-ΠΏΠ°ΠΊΠ΅Ρ‚, установит Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ Ρ„Π»Π°Π³ΠΈ ΠΈ отдаст ΠΈΡ… мСдиастримСру для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΏΠΎ сСти Π² Π²ΠΈΠ΄Π΅ UDP-ΠΏΠ°ΠΊΠ΅Ρ‚Π°.

ВСрхняя Ρ†Π΅ΠΏΡŒ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ² ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ ΠΏΡ€ΠΈΠ΅ΠΌΠ½Ρ‹ΠΉ Ρ‚Ρ€Π°ΠΊΡ‚, RTP-ΠΏΠ°ΠΊΠ΅Ρ‚Ρ‹, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ мСдиастримСром ΠΈΠ· сСти, ΠΏΠΎΡΡ‚ΡƒΠΏΠ°ΡŽΡ‚ Π² Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ rtprecv, Π½Π° Π²Ρ‹Ρ…ΠΎΠ΄Π΅ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ, ΠΎΠ½ΠΈ ΠΏΠΎΡΠ²Π»ΡΡŽΡ‚ΡΡ ΡƒΠΆΠ΅ Π² Π²ΠΈΠ΄Π΅ Π±Π»ΠΎΠΊΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… соотвСтствуСт ΠΎΠ΄Π½ΠΎΠΌΡƒ принятому ΠΏΠ°ΠΊΠ΅Ρ‚Ρƒ. Π‘Π»ΠΎΠΊ содСрТит Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ, Π² ΠΏΡ€ΠΎΡˆΠ»ΠΎΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ Π½Π° ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΠΈ ΠΎΠ½ΠΈ Π±Ρ‹Π»ΠΈ ΠΏΠΎΠΊΠ°Π·Π°Π½Ρ‹ Π·Π΅Π»Π΅Π½Ρ‹ΠΌ Ρ†Π²Π΅Ρ‚ΠΎΠΌ.

Π”Π°Π»Π΅Π΅ Π±Π»ΠΎΠΊΠΈ ΠΏΠΎΡΡ‚ΡƒΠΏΠ°ΡŽΡ‚ Π½Π° Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ Π΄Π΅ΠΊΠΎΠ΄Π΅Ρ€Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ находящиСся Π² Π½ΠΈΡ… ΠΎΠ΄Π½ΠΎΠ±Π°ΠΉΡ‚Π½Ρ‹Π΅ отсчСты, Π² Π»ΠΈΠ½Π΅ΠΉΠ½Ρ‹Π΅, 16-Π±ΠΈΡ‚Π½Ρ‹Π΅. ΠšΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°ΠΌΠΈ мСдиастримСра. Π’ нашСм случаС ΠΌΡ‹ просто ΠΎΡ‚Π΄Π°Π΅ΠΌ ΠΈΡ… Π½Π° Π·Π²ΡƒΠΊΠΎΠ²ΡƒΡŽ ΠΊΠ°Ρ€Ρ‚Ρƒ, для воспроизвСдСния Π½Π° Π΄ΠΈΠ½Π°ΠΌΠΈΠΊΠ°Ρ… вашСй Π³Π°Ρ€Π½ΠΈΡ‚ΡƒΡ€Ρ‹.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΠ΅Ρ€Π΅ΠΉΠ΄Π΅ΠΌ ΠΊ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠΉ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ. Для этого ΠΌΡ‹ объСдиним Ρ„Π°ΠΉΠ»Ρ‹ ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊΠ° ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚Ρ‡ΠΈΠΊΠ°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΡ‹ Ρ€Π°Π·ΠΌΠ΅ΠΆΠ΅Π²Π°Π»ΠΈ Π΄ΠΎ этого. Π”ΠΎ этого ΠΌΡ‹ использовали фиксированныС настройки ΠΏΠΎΡ€Ρ‚ΠΎΠ² ΠΈ адрСсов, Π½ΠΎ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΌΠΎΠ³Π»Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Π΅ настройки, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΡ‹ ΡƒΠΊΠ°ΠΆΠ΅ΠΌ ΠΏΡ€ΠΈ запускС. Для этого Π±Ρ‹ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π» ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки. ПослС Ρ‡Π΅Π³ΠΎ ΠΌΡ‹ смоТСм Π·Π°Π΄Π°Π²Π°Ρ‚ΡŒ IP-адрСс ΠΈ ΠΏΠΎΡ€Ρ‚ ΠΏΠ΅Ρ€Π΅Π³ΠΎΠ²ΠΎΡ€Π½ΠΎΠ³ΠΎ устройства, с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ связь.

Π‘Π½Π°Ρ‡Π°Π»Π° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π² Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ структуру, которая Π±ΡƒΠ΄Π΅Ρ‚ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π΅Ρ‘ настройки:

struct _app_vars
{
  int  local_port;              /* Π›ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠΎΡ€Ρ‚. */
  int  remote_port;             /* ΠŸΠΎΡ€Ρ‚ ΠΏΠ΅Ρ€Π΅Π³ΠΎΠ²ΠΎΡ€Π½ΠΎΠ³ΠΎ устройства Π½Π° ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠΌ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π΅. */
  char remote_addr[128];        /* IP-адрСс ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π°. */
  MSDtmfGenCustomTone dtmf_cfg; /* Настройки тСстового сигнала Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π°. */
};

typedef struct _app_vars app_vars;

Π’ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ объявлСна структура этого Ρ‚ΠΈΠΏΠ° с ΠΈΠΌΠ΅Π½Π΅ΠΌ vars.
Π—Π°Ρ‚Π΅ΠΌ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Ρ€Π°Π·Π±ΠΎΡ€Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки:

/* Ѐункция прСобразования Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки Π²
* настройки ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. */
void  scan_args(int argc, char *argv[], app_vars *v)
{
    char i;
    for (i=0; i<argc; i++)
    {
        if (!strcmp(argv[i], "--help"))
        {
            char *p=argv[0]; p=p + 2;
            printf("  %s walkie talkienn", p);
            printf("--help      List of options.n");
            printf("--version   Version of application.n");
            printf("--addr      Remote abonent IP address string.n");
            printf("--port      Remote abonent port number.n");
            printf("--lport     Local port number.n");
            printf("--gen       Generator frequency.n");
            exit(0);
        }

        if (!strcmp(argv[i], "--version"))
        {
            printf("0.1n");
            exit(0);
        }

        if (!strcmp(argv[i], "--addr"))
        {
            strncpy(v->remote_addr, argv[i+1], 16);
            v->remote_addr[16]=0;
            printf("remote addr: %sn", v->remote_addr);
        }

        if (!strcmp(argv[i], "--port"))
        {
            v->remote_port=atoi(argv[i+1]);
            printf("remote port: %in", v->remote_port);
        }

        if (!strcmp(argv[i], "--lport"))
        {
            v->local_port=atoi(argv[i+1]);
            printf("local port : %in", v->local_port);
        }

        if (!strcmp(argv[i], "--gen"))
        {
            v -> dtmf_cfg.frequencies[0] = atoi(argv[i+1]);
                printf("gen freq : %in", v -> dtmf_cfg.frequencies[0]);
        }
    }
}

Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ Ρ€Π°Π·Π±ΠΎΡ€Π°, Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠΎΠΌΠ΅Ρ‰Π΅Π½Ρ‹ Π² поля структуры vars. Главная функция прилоТСния Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠ±ΠΈΡ€Π°Ρ‚ΡŒ ΠΈΠ· Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ² ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‰ΠΈΠΉ ΠΈ ΠΏΡ€ΠΈΠ΅ΠΌΠ½Ρ‹ΠΉ Ρ‚Ρ€Π°ΠΊΡ‚Ρ‹, послС ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Ρ‚ΠΈΠΊΠ΅Ρ€Π° ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½ΠΎ бСсконСчному Ρ†ΠΈΠΊΠ»Ρƒ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ, Ссли частота Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° Π±Ρ‹Π»Π° Π·Π°Π΄Π°Π½Π° Π½Π΅Π½ΡƒΠ»Π΅Π²ΠΎΠΉ, Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ тСстовый Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ β€” Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ Ρ€Π°Π±ΠΎΡ‚Π°Π» Π±Π΅Π· остановки.

Π­Ρ‚ΠΈ пСрСзапуски Π±ΡƒΠ΄ΡƒΡ‚ Π½ΡƒΠΆΠ½Ρ‹ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρƒ ΠΈΠ·-Π·Π° Π΅Π³ΠΎ особСнности построСния, ΠΏΠΎΡ‡Π΅ΠΌΡƒ-Ρ‚ΠΎ ΠΎΠ½ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π΄Π°Π²Π°Ρ‚ΡŒ сигнал Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒΡŽ Π±ΠΎΠ»Π΅Π΅ 16 сСкунд. ΠŸΡ€ΠΈ этом слСдуСт Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ Ρƒ Π½Π΅Π³ΠΎ задаСтся 32-Π±ΠΈΡ‚Π½Ρ‹ΠΌ числом.

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Ρ†Π΅Π»ΠΈΠΊΠΎΠΌ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ Ρ‚Π°ΠΊ:

/* Π€Π°ΠΉΠ» mstest8.c Π˜ΠΌΠΈΡ‚Π°Ρ‚ΠΎΡ€ ΠΏΠ΅Ρ€Π΅Π³ΠΎΠ²ΠΎΡ€Π½ΠΎΠ³ΠΎ устройства. */

#include <mediastreamer2/mssndcard.h>
#include <mediastreamer2/dtmfgen.h>
#include <mediastreamer2/msrtp.h>

/* ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ Ρ„Π°ΠΉΠ» ΠΎΠ±Ρ‰ΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ. */
#include "mstest_common.c"

/*----------------------------------------------------------*/
struct _app_vars
{
    int  local_port;              /* Π›ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠΎΡ€Ρ‚. */
    int  remote_port;             /* ΠŸΠΎΡ€Ρ‚ ΠΏΠ΅Ρ€Π΅Π³ΠΎΠ²ΠΎΡ€Π½ΠΎΠ³ΠΎ устройства Π½Π° ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠΌ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π΅. */
    char remote_addr[128];        /* IP-адрСс ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π°. */
    MSDtmfGenCustomTone dtmf_cfg; /* Настройки тСстового сигнала Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π°. */
};

typedef struct _app_vars app_vars;

/*----------------------------------------------------------*/
/* Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π΄ΡƒΠΏΠ»Π΅ΠΊΡΠ½ΡƒΡŽ RTP-сСссию. */
RtpSession* create_duplex_rtp_session(app_vars v)
{
    RtpSession *session = create_rtpsession (v.local_port, v.local_port + 1, FALSE, RTP_SESSION_SENDRECV);
    rtp_session_set_remote_addr_and_port(session, v.remote_addr, v.remote_port, v.remote_port + 1);
    rtp_session_set_send_payload_type(session, PCMU);
    return session;
}

/*----------------------------------------------------------*/
/* Ѐункция прСобразования Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки Π²
* настройки ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. */
void  scan_args(int argc, char *argv[], app_vars *v)
{
    char i;
    for (i=0; i<argc; i++)
    {
        if (!strcmp(argv[i], "--help"))
        {
            char *p=argv[0]; p=p + 2;
            printf("  %s walkie talkienn", p);
            printf("--help      List of options.n");
            printf("--version   Version of application.n");
            printf("--addr      Remote abonent IP address string.n");
            printf("--port      Remote abonent port number.n");
            printf("--lport     Local port number.n");
            printf("--gen       Generator frequency.n");
            exit(0);
        }

        if (!strcmp(argv[i], "--version"))
        {
            printf("0.1n");
            exit(0);
        }

        if (!strcmp(argv[i], "--addr"))
        {
            strncpy(v->remote_addr, argv[i+1], 16);
            v->remote_addr[16]=0;
            printf("remote addr: %sn", v->remote_addr);
        }

        if (!strcmp(argv[i], "--port"))
        {
            v->remote_port=atoi(argv[i+1]);
            printf("remote port: %in", v->remote_port);
        }

        if (!strcmp(argv[i], "--lport"))
        {
            v->local_port=atoi(argv[i+1]);
            printf("local port : %in", v->local_port);
        }

        if (!strcmp(argv[i], "--gen"))
        {
            v -> dtmf_cfg.frequencies[0] = atoi(argv[i+1]);
                printf("gen freq : %in", v -> dtmf_cfg.frequencies[0]);
        }
    }
}

/*----------------------------------------------------------*/
int main(int argc, char *argv[])
{
    /* УстанавливаСм настройки ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ. */
    app_vars vars={5004, 7010, "127.0.0.1", {0}};

    /* УстанавливаСм настройки настройки ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π²
     * соотвСтствии с Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки. */
    scan_args(argc, argv, &vars);

    ms_init();

    /* Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ экзСмпляры Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ² ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‰Π΅Π³ΠΎ Ρ‚Ρ€Π°ΠΊΡ‚Π°. */
    MSSndCard *snd_card =
        ms_snd_card_manager_get_default_card(ms_snd_card_manager_get());
    MSFilter *snd_card_read = ms_snd_card_create_reader(snd_card);
    MSFilter *dtmfgen = ms_filter_new(MS_DTMF_GEN_ID);
    MSFilter *rtpsend = ms_filter_new(MS_RTP_SEND_ID);

    /* Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ ΠΊΠΎΠ΄Π΅Ρ€Π°. */
    MSFilter *encoder = ms_filter_create_encoder("PCMU");

    /* РСгистрируСм Ρ‚ΠΈΠΏΡ‹ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ. */
    register_payloads();

    /* Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π΄ΡƒΠΏΠ»Π΅ΠΊΡΠ½ΡƒΡŽ RTP-сСссию. */
    RtpSession* rtp_session= create_duplex_rtp_session(vars);
    ms_filter_call_method(rtpsend, MS_RTP_SEND_SET_SESSION, rtp_session);

    /* БоСдиняСм Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚Ρ‡ΠΈΠΊΠ°. */
    ms_filter_link(snd_card_read, 0, dtmfgen, 0);
    ms_filter_link(dtmfgen, 0, encoder, 0);
    ms_filter_link(encoder, 0, rtpsend, 0);

    /* Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Ρ‹ ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΎΠ³ΠΎ Ρ‚Ρ€Π°ΠΊΡ‚Π°. */
    MSFilter *rtprecv = ms_filter_new(MS_RTP_RECV_ID);
    ms_filter_call_method(rtprecv, MS_RTP_RECV_SET_SESSION, rtp_session);

    /* Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ Π΄Π΅ΠΊΠΎΠ΄Π΅Ρ€Π°, */
    MSFilter *decoder=ms_filter_create_decoder("PCMU");

    /* Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ Π·Π²ΡƒΠΊΠΎΠ²ΠΎΠΉ ΠΊΠ°Ρ€Ρ‚Ρ‹. */
    MSFilter *snd_card_write = ms_snd_card_create_writer(snd_card);

    /* БоСдиняСм Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Ρ‹ ΠΏΡ€ΠΈΡ‘ΠΌΠ½ΠΎΠ³ΠΎ Ρ‚Ρ€Π°ΠΊΡ‚Π°. */
    ms_filter_link(rtprecv, 0, decoder, 0);
    ms_filter_link(decoder, 0,  snd_card_write, 0);

    /* Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ источник Ρ‚Π°ΠΊΡ‚ΠΎΠ² - Ρ‚ΠΈΠΊΠ΅Ρ€. */
    MSTicker *ticker = ms_ticker_new();

    /* ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ источник Ρ‚Π°ΠΊΡ‚ΠΎΠ². */
    ms_ticker_attach(ticker, snd_card_read);
    ms_ticker_attach(ticker, rtprecv);

    /* Если настройка частоты Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° ΠΎΡ‚Π»ΠΈΡ‡Π½Π° ΠΎΡ‚ нуля, Ρ‚ΠΎ запускаСм Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€. */   
    if (vars.dtmf_cfg.frequencies[0])
    {
        /* НастраиваСм структуру, ΡƒΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΡƒΡŽ Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹ΠΌ сигналом Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π°. */
        vars.dtmf_cfg.duration = 10000;
        vars.dtmf_cfg.amplitude = 1.0;
    }

    /* ΠžΡ€Π³Π°Π½ΠΈΠ·ΡƒΠ΅ΠΌ Ρ†ΠΈΠΊΠ» пСрСзапуска Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π°. */
    while(TRUE)
    {
        if(vars.dtmf_cfg.frequencies[0])
        {
            /* Π’ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ Π·Π²ΡƒΠΊΠΎΠ²ΠΎΠΉ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€. */
            ms_filter_call_method(dtmfgen, MS_DTMF_GEN_PLAY_CUSTOM,
                    (void*)&vars.dtmf_cfg);
        }
        /* Π£ΠΊΠ»Π°Π΄Ρ‹Π²Π°Π΅ΠΌ Ρ‚Ρ€Π΅Π΄ Π² спячку Π½Π° 20мс, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Ρ‚Ρ€Π΅Π΄Ρ‹
         * прилоТСния ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ врСмя Π½Π° Ρ€Π°Π±ΠΎΡ‚Ρƒ. */
        ms_usleep(20000);
    }
}

ΠšΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΠ΅ΠΌ. Π”Π°Π»Π΅Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ Π½Π° Π΄Π²ΡƒΡ… ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π°Ρ…. Или Π½Π° ΠΎΠ΄Π½ΠΎΠΌ, ΠΊΠ°ΠΊ я Π±ΡƒΠ΄Ρƒ Π΄Π΅Π»Π°Ρ‚ΡŒ сСйчас. ЗапускаСм TShark со ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌΠΈ:

$ sudo tshark -i lo -f "udp dst port 7010" -P -V -O RTP -o rtp.heuristic_rtp:TRUE -x

Если ΠΏΠΎΠ»Π΅ запуска Π² консоли появится Ρ‚ΠΎΠ»ΡŒΠΊΠΎ сообщСниС ΠΎ Π½Π°Ρ‡Π°Π»Π΅ Π·Π°Ρ…Π²Π°Ρ‚Π°, Ρ‚ΠΎ это Π΄ΠΎΠ±Ρ€Ρ‹ΠΉ Π·Π½Π°ΠΊ -Π·Π½Π°Ρ‡ΠΈΡ‚ наш ΠΏΠΎΡ€Ρ‚ скорСС всСго Π½Π΅ занят Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°ΠΌΠΈ. Π’ Π΄Ρ€ΡƒΠ³ΠΎΠΌ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π΅ запускаСм экзСмпляр ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠΌΠΈΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ "ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠ΅" ΠΏΠ΅Ρ€Π΅Π³ΠΎΠ²ΠΎΡ€Π½ΠΎΠ΅ устройство ΡƒΠΊΠ°Π·Π°Π² Π΅ΠΌΡƒ этот Π½ΠΎΠΌΠ΅Ρ€ ΠΏΠΎΡ€Ρ‚Π°:

$ ./mstest8 --port 9010 --lport 7010

Как Π²ΠΈΠ΄Π½ΠΎ ΠΈΠ· тСкста ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ IP-адрСс 127.0.0.1 (локальная пСтля).

Π•Ρ‰Π΅ Π² ΠΎΠ΄Π½ΠΎΠΌ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π΅ запускаСм Π²Ρ‚ΠΎΡ€ΠΎΠΉ экзСмпляр ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΠΌΠΈΡ‚ΠΈΡ€ΡƒΠ΅Ρ‚ локальноС устройство. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ встроСнного тСстового Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π°:

$ ./mstest8  --port 7010 --lport 9010 --gen 440

Π’ этот ΠΌΠΎΠΌΠ΅Π½Ρ‚, Π² консоли с TShark Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π½Π°Ρ‡Π°Ρ‚ΡŒ ΠΌΠ΅Π»ΡŒΠΊΠ°Ρ‚ΡŒ ΠΏΠ°ΠΊΠ΅Ρ‚Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Π΅ Π² сторону "ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠ³ΠΎ" устройства, Π° ΠΈΠ· Π΄ΠΈΠ½Π°ΠΌΠΈΠΊΠ° ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π° раздастся Π½Π΅ΠΏΡ€Π΅Ρ€Ρ‹Π²Π½Ρ‹ΠΉ Ρ‚ΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ сигнал.

Если всС ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»ΠΎ ΠΊΠ°ΠΊ ΠΏΠΎ писанному, Ρ‚ΠΎ пСрСзапускаСм Π²Ρ‚ΠΎΡ€ΠΎΠΉ экзСмпляр ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, Π½ΠΎ ΡƒΠΆΠ΅ Π±Π΅Π· ΠΊΠ»ΡŽΡ‡Π° ΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° "—gen 440". Роль Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Π±ΡƒΠ΄Π΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»Π½ΡΡ‚ΡŒ Π²Ρ‹. ПослС этого ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡˆΡƒΠΌΠ΅Ρ‚ΡŒ Π² ΠΌΠΈΠΊΡ€ΠΎΡ„ΠΎΠ½, Π² Π΄ΠΈΠ½Π°ΠΌΠΈΠΊΠ΅ ΠΈΠ»ΠΈ Π½Π°ΡƒΡˆΠ½ΠΈΠΊΠ°Ρ… Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡƒΡΠ»Ρ‹ΡˆΠ°Ρ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Π·Π²ΡƒΠΊ. Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π΄Π°ΠΆΠ΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ½Π΅Ρ‚ акустичСскоС самовозбуТдСниС, ΡƒΠ±Π°Π²ΡŒΡ‚Π΅ Π³Ρ€ΠΎΠΌΠΊΠΎΡΡ‚ΡŒ Π΄ΠΈΠ½Π°ΠΌΠΈΠΊΠ° ΠΈ эффСкт ΠΏΡ€ΠΎΠΏΠ°Π΄Π΅Ρ‚.

Если Ρƒ Π²Ρ‹ запускали Π½Π° Π΄Π²ΡƒΡ… ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π°Ρ… ΠΈ Π½Π΅ Π·Π°ΠΏΡƒΡ‚Π°Π»ΠΈΡΡŒ Π² IP-адрСсах, Ρ‚ΠΎ вас ΠΆΠ΄Π΅Ρ‚ Ρ‚ΠΎΡ‚ ΠΆΠ΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ β€” двусторонняя рСчСвая связь Ρ†ΠΈΡ„Ρ€ΠΎΠ²ΠΎΠ³ΠΎ качСства.

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ научимся ΠΏΠΈΡΠ°Ρ‚ΡŒ свои собствСнныС Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Ρ‹ β€” ΠΏΠ»Π°Π³ΠΈΠ½Ρ‹, благодаря этому Π½Π°Π²Ρ‹ΠΊΡƒ Π²Ρ‹ смоТСтС ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ мСдиастримСр Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для Π·Π²ΡƒΠΊΠ° ΠΈ Π²ΠΈΠ΄Π΅ΠΎ, Π½ΠΎ ΠΈ Π² ΠΊΠ°ΠΊΠΎΠΉ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ ΠΈΠ½ΠΎΠΉ спСцифичСской области.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com