Mediastreamer2 VoIP рдЗрдиреНрдЬрд┐рди рдЕрдиреНрд╡реЗрд╖рдг рдЧрд░реНрджреИред рднрд╛рдЧ рео

рд▓реЗрдЦрдХреЛ рд╕рд╛рдордЧреНрд░реА рдореЗрд░реЛ рдмрд╛рдЯ рд▓рд┐рдЗрдПрдХреЛ рд╣реЛ zen рдЪреНрдпрд╛рдирд▓.

рдбреБрдкреНрд▓реЗрдХреНрд╕ рдЗрдиреНрдЯрд░рдХреЙрдо

Mediastreamer2 VoIP рдЗрдиреНрдЬрд┐рди рдЕрдиреНрд╡реЗрд╖рдг рдЧрд░реНрджреИред рднрд╛рдЧ рео

рд╡рд┐рдЧрддрдорд╛ рд▓реЗрдЦ рдПрдХ рдбреБрдкреНрд▓реЗрдХреНрд╕ рдЗрдиреНрдЯрд░рдХрдо рдШреЛрд╖рдгрд╛ рдЧрд░рд┐рдПрдХреЛ рдерд┐рдпреЛ, рд░ рдпрд╕рдорд╛ рд╣рд╛рдореА рдпрд╕рд▓рд╛рдИ рдмрдирд╛рдЙрдиреЗрдЫреМрдВред

рд░реЗрдЦрд╛рдЪрд┐рддреНрд░ рд╢реАрд░реНрд╖рдХ рдЪрд┐рддреНрд░рдорд╛ рджреЗрдЦрд╛рдЗрдПрдХреЛ рдЫред рдлрд┐рд▓реНрдЯрд░рд╣рд░реВрдХреЛ рддрд▓реНрд▓реЛ рд╢реНрд░реГрдВрдЦрд▓рд╛рд▓реЗ рдкреНрд░рд╕рд╛рд░рдг рдорд╛рд░реНрдЧ рдмрдирд╛рдЙрдБрдЫ, рдЬреБрди рдзреНрд╡рдирд┐ рдХрд╛рд░реНрдбрдмрд╛рдЯ рд╕реБрд░реБ рд╣реБрдиреНрдЫред рдпрд╕рд▓реЗ рдорд╛рдЗрдХреНрд░реЛрдлреЛрдирдмрд╛рдЯ рд╕рдВрдХреЗрдд рдирдореВрдирд╛рд╣рд░реВ рдкреНрд░рджрд╛рди рдЧрд░реНрджрдЫред рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд░реВрдкрдорд╛, рдпреЛ рдкреНрд░рддрд┐ рд╕реЗрдХреЗрдиреНрдб 8000 рдирдореВрдирд╛рд╣рд░реВрдХреЛ рджрд░рдорд╛ рд╣реБрдиреНрдЫред рдорд┐рдбрд┐рдпрд╛ рд╕реНрдЯреНрд░рд┐рдорд░ рдЕрдбрд┐рдпреЛ рдлрд┐рд▓реНрдЯрд░рд╣рд░реВрд▓реЗ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреЗ рдбреЗрдЯрд╛ рдмрд┐рдЯ рдЧрд╣рд┐рд░рд╛рдИ 16 рдмрд┐рдЯ рд╣реЛ (рдпреЛ рдорд╣рддреНрддреНрд╡рдкреВрд░реНрдг рдЫреИрди; рдпрджрд┐ рддрдкрд╛рдЗрдБ рдЪрд╛рд╣рдиреБрд╣реБрдиреНрдЫ рднрдиреЗ, рддрдкрд╛рдЗрдБ рдлрд┐рд▓реНрдЯрд░рд╣рд░реВ рд▓реЗрдЦреНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рдЬреБрди рдЙрдЪреНрдЪ рдмрд┐рдЯ рдЧрд╣рд┐рд░рд╛рдЗрд╕рдБрдЧ рдХрд╛рдо рдЧрд░реНрджрдЫ)ред рдбрд╛рдЯрд╛ 160 рдирдореВрдирд╛рд╣рд░реВрдХреЛ рдмреНрд▓рдХрд╣рд░реВрдорд╛ рд╕рдореВрд╣рдмрджреНрдз рдЧрд░рд┐рдПрдХреЛ рдЫред рдпрд╕рд░реА, рдкреНрд░рддреНрдпреЗрдХ рдмреНрд▓рдХ рдЖрдХрд╛рд░рдорд╛ 320 рдмрд╛рдЗрдЯреНрд╕ рдЫред рдЕрд░реНрдХреЛ, рд╣рд╛рдореА рдЬреЗрдирд░реЗрдЯрд░рдХреЛ рдЗрдирдкреБрдЯрдорд╛ рдбрд╛рдЯрд╛ рдлрд┐рдб рдЧрд░реНрдЫреМрдВ, рдЬреБрди, рдЬрдм рдмрдиреНрдж рд╣реБрдиреНрдЫ, рдбрд╛рдЯрд╛рдорд╛ "рдкрд╛рд░рджрд░реНрд╢реА" рд╣реБрдиреНрдЫред рддрдкрд╛рдИрдВрд▓реЗ рдбрд┐рдмрдЧрд┐рдЩрдХреЛ рдХреНрд░рдордорд╛ рдорд╛рдЗрдХреНрд░реЛрдлреЛрдирдорд╛ рдХреБрд░рд╛ рдЧрд░реНрджрд╛ рдерд╛рдХреЗрдХреЛ рдЕрд╡рд╕реНрдерд╛рдорд╛ рдореИрд▓реЗ рдпрд╕рд▓рд╛рдИ рдердкреЗрдХреЛ рдЫреБ - рддрдкрд╛рдИрдВрд▓реЗ рдЯреЛрди рд╕рд┐рдЧреНрдирд▓рдХреЛ рд╕рд╛рде рдорд╛рд░реНрдЧ "рд╢реВрдЯ" рдЧрд░реНрди рдЬрдирд░реЗрдЯрд░ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫред

рдЬреЗрдиреЗрд░реЗрдЯрд░ рдкрдЫрд┐, рд╕рдВрдХреЗрдд рдПрдиреНрдХреЛрдбрд░рдорд╛ рдЬрд╛рдиреНрдЫ, рдЬрд╕рд▓реЗ рд╣рд╛рдореНрд░рд╛ резрем-рдмрд┐рдЯ рдирдореВрдирд╛рд╣рд░реВрд▓рд╛рдИ ┬╡-рдХрд╛рдиреВрди (G.16 рдорд╛рдирдХ) рдЕрдиреБрд╕рд╛рд░ рдЖрда-рдмрд┐рдЯрдорд╛ рд░реВрдкрд╛рдиреНрддрд░рдг рдЧрд░реНрдЫред рдПрдиреНрдХреЛрдбрд░рдХреЛ рдЖрдЙрдЯрдкреБрдЯрдорд╛, рд╣рд╛рдореАрд╕рдБрдЧ рдкрд╣рд┐рд▓реЗ рдиреИ рдбрд╛рдЯрд╛ рдмреНрд▓рдХ рдЖрдзрд╛ рд╕рд╛рдЗрдЬ рдЫред рд╕рд╛рдорд╛рдиреНрдпрддрдпрд╛, рдпрджрд┐ рд╣рд╛рдореАрд▓реЗ рдЯреНрд░рд╛рдлрд┐рдХ рдмрдЪрдд рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫреИрди рднрдиреЗ рд╣рд╛рдореА рдХрдореНрдкреНрд░реЗрд╕рди рдмрд┐рдирд╛ рдбрд╛рдЯрд╛ рдкреНрд░рд╕рд╛рд░рдг рдЧрд░реНрди рд╕рдХреНрдЫреМрдВред рддрд░ рдпрд╣рд╛рдБ рдпреЛ рдПрдиреНрдХреЛрдбрд░ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рдЙрдкрдпреЛрдЧреА рдЫ, рдХрд┐рдирдХрд┐ Wireshark рд▓реЗ RTP рд╕реНрдЯреНрд░рд┐рдордмрд╛рдЯ рдЕрдбрд┐рдпреЛ рдкреБрди: рдЙрддреНрдкрд╛рджрди рдЧрд░реНрди рд╕рдХреНрдЫ рдЬрдм рдпреЛ ┬╡-law рд╡рд╛ a-law рдЕрдиреБрд╕рд╛рд░ рд╕рдВрдХреБрдЪрд┐рдд рд╣реБрдиреНрдЫред

рдПрдиреНрдХреЛрдбрд░ рдкрдЫрд┐, рдбреЗрдЯрд╛рдХреЛ рд╣рд▓реНрдХрд╛ рдмреНрд▓рдХрд╣рд░реВ rtpsend рдлрд┐рд▓реНрдЯрд░рдорд╛ рдкрдард╛рдЗрдиреНрдЫ, рдЬрд╕рд▓реЗ рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ RTP рдкреНрдпрд╛рдХреЗрдЯрдорд╛ рд░рд╛рдЦреНрдЫ, рдЖрд╡рд╢реНрдпрдХ рдЭрдгреНрдбрд╛рд╣рд░реВ рд╕реЗрдЯ рдЧрд░реНрджрдЫ рд░ рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ UDP рдкреНрдпрд╛рдХреЗрдЯрдХреЛ рд░реВрдкрдорд╛ рдиреЗрдЯрд╡рд░реНрдХрдорд╛ рдкреНрд░рд╕рд╛рд░рдгрдХреЛ рд▓рд╛рдЧрд┐ рдорд┐рдбрд┐рдпрд╛ рд╕реНрдЯреНрд░рд┐рдорд░рд▓рд╛рдИ рджрд┐рдиреНрдЫред

рдлрд┐рд▓реНрдЯрд░рд╣рд░реВрдХреЛ рдорд╛рдерд┐рд▓реНрд▓реЛ рд╢реНрд░реГрдВрдЦрд▓рд╛рд▓реЗ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрдиреЗ рдорд╛рд░реНрдЧ рдмрдирд╛рдЙрдБрдЫ; рдиреЗрдЯрд╡рд░реНрдХрдмрд╛рдЯ рдорд┐рдбрд┐рдпрд╛ рд╕реНрдЯреНрд░рд┐рдорд░рд▓реЗ рдкреНрд░рд╛рдкреНрдд рдЧрд░реЗрдХреЛ RTP рдкреНрдпрд╛рдХреЗрдЯрд╣рд░реВ rtprecv рдлрд┐рд▓реНрдЯрд░рдорд╛ рдкреНрд░рд╡реЗрд╢ рдЧрд░реНрдЫрдиреН, рдЬрд╕рдХреЛ рдЖрдЙрдЯрдкреБрдЯрдорд╛ рддрд┐рдиреАрд╣рд░реВ рдбреЗрдЯрд╛ рдмреНрд▓рдХрд╣рд░реВрдХреЛ рд░реВрдкрдорд╛ рджреЗрдЦрд╛ рдкрд░реНрджрдЫ, рдЬрд╕рдордзреНрдпреЗ рдкреНрд░рддреНрдпреЗрдХ рдПрдХ рдкреНрд░рд╛рдкреНрдд рдкреНрдпрд╛рдХреЗрдЯрд╕рдБрдЧ рдореЗрд▓ рдЦрд╛рдиреНрдЫред рдмреНрд▓рдХрд▓реЗ рдкреЗрд▓реЛрдб рдбреЗрдЯрд╛ рдорд╛рддреНрд░ рд╕рдорд╛рд╡реЗрд╢ рдЧрд░реНрджрдЫ; рдЕрдШрд┐рд▓реНрд▓реЛ рд▓реЗрдЦрдорд╛ рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ рдЪрд┐рддреНрд░рдгрдорд╛ рд╣рд░рд┐рдпреЛрдорд╛ рджреЗрдЦрд╛рдЗрдПрдХреЛ рдерд┐рдпреЛред

рдЕрд░реНрдХреЛ, рдмреНрд▓рдХрд╣рд░реВ рдбрд┐рдХреЛрдбрд░ рдлрд┐рд▓реНрдЯрд░рдорд╛ рдкрдард╛рдЗрдиреНрдЫ, рдЬрд╕рд▓реЗ рддрд┐рдиреАрд╣рд░реВрдорд╛ рд╕рдорд╛рд╡реЗрд╢ рдПрдХрд▓-рдмрд╛рдЗрдЯ рдирдореВрдирд╛рд╣рд░реВрд▓рд╛рдИ рд░реИрдЦрд┐рдХ, 16-рдмрд┐рдЯрдорд╛ рд░реВрдкрд╛рдиреНрддрд░рдг рдЧрд░реНрджрдЫред рдЬреБрди рдкрд╣рд┐рд▓реЗ рдиреИ рдорд┐рдбрд┐рдпрд╛ рд╕реНрдЯреНрд░рд┐рдорд░ рдлрд┐рд▓реНрдЯрд░рд╣рд░реВ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╢реЛрдзрди рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫред рд╣рд╛рдореНрд░реЛ рдЕрд╡рд╕реНрдерд╛рдорд╛, рд╣рд╛рдореА рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ рддрдкрд╛рдИрдВрдХреЛ рд╣реЗрдбрд╕реЗрдЯрдХреЛ рд╕реНрдкрд┐рдХрд░рд╣рд░реВрдорд╛ рдкреНрд▓реЗрдмреНрдпрд╛рдХрдХреЛ рд▓рд╛рдЧрд┐ рд╕рд╛рдЙрдиреНрдб рдХрд╛рд░реНрдбрдорд╛ рдкрдард╛рдЙрдБрдЫреМрдВред

рдЕрдм рд╕рдлреНрдЯрд╡реЗрдпрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдирдорд╛ рдЬрд╛рдФрдВред рдпреЛ рдЧрд░реНрдирдХреЛ рд▓рд╛рдЧрд┐, рд╣рд╛рдореАрд▓реЗ рдкрд╣рд┐рд▓реЗ рдЫреБрдЯреНрдпрд╛рдПрдХрд╛ рд░рд┐рд╕реАрднрд░ рд░ рдЯреНрд░рд╛рдиреНрд╕рдорд┐рдЯрд░ рдлрд╛рдЗрд▓рд╣рд░реВ рд╕рдВрдпреЛрдЬрди рдЧрд░реНрдиреЗрдЫреМрдВред рдпреЛ рднрдиреНрджрд╛ рдкрд╣рд┐рд▓реЗ, рд╣рд╛рдореАрд▓реЗ рдкреЛрд░реНрдЯ рд░ рдареЗрдЧрд╛рдирд╛рд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рдирд┐рд╢реНрдЪрд┐рдд рд╕реЗрдЯрд┐рдЩрд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдпреМрдВ, рддрд░ рдЕрдм рд╣рд╛рдореАрд▓реЗ рд╕реНрдЯрд╛рд░реНрдЯрдЕрдкрдорд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЧрд░реНрдиреЗ рд╕реЗрдЯрд┐рдЩрд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХреНрд╖рдо рд╣реБрдирдХреЛ рд▓рд╛рдЧрд┐ рд╣рд╛рдореАрд▓рд╛рдИ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЪрд╛рд╣рд┐рдиреНрдЫред рдпреЛ рдЧрд░реНрдирдХреЛ рд▓рд╛рдЧрд┐, рд╣рд╛рдореА рдХрдорд╛рдгреНрдб рд▓рд╛рдЗрди рддрд░реНрдХрд╣рд░реВ рдкреНрд░рд╢реЛрдзрди рдЧрд░реНрдирдХрд╛ рд▓рд╛рдЧрд┐ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдердкреНрдиреЗрдЫреМрдВред рдЬрд╕ рдкрдЫрд┐ рд╣рд╛рдореА рдЖрдИрдкреА рдареЗрдЧрд╛рдирд╛ рд░ рдЗрдиреНрдЯрд░рдХрдордХреЛ рдкреЛрд░реНрдЯ рд╕реЗрдЯ рдЧрд░реНрди рд╕рдХреНрд╖рдо рд╣реБрдиреЗрдЫреМрдВ рдЬрд╕рдХреЛ рд╕рд╛рде рд╣рд╛рдореА рдЬрдбрд╛рди рд╕реНрдерд╛рдкрдирд╛ рдЧрд░реНрди рдЪрд╛рд╣рдиреНрдЫреМрдВред

рдкрд╣рд┐рд▓реЗ, рдХрд╛рд░реНрдпрдХреНрд░рдордорд╛ рд╕рдВрд░рдЪрдирд╛ рдердкреМрдВ рдЬрд╕рд▓реЗ рдпрд╕рдХреЛ рд╕реЗрдЯрд┐рдЩрд╣рд░реВ рднрдгреНрдбрд╛рд░ рдЧрд░реНрдиреЗрдЫ:

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 рдареЗрдЧрд╛рдирд╛рд╣рд░реВрдХреЛ рдмрд╛рд░реЗрдорд╛ рднреНрд░рдорд┐рдд рд╣реБрдиреБрднрдПрди рднрдиреЗ, рддреНрдпрд╣реА рдкрд░рд┐рдгрд╛рдорд▓реЗ рддрдкрд╛рдИрдВрд▓рд╛рдИ рдкрд░реНрдЦрд┐рд░рд╣реЗрдХреЛ рдЫ - рджреБрдИ-рддрд░реНрдлреА рдбрд┐рдЬрд┐рдЯрд▓ рдЧреБрдгрд╕реНрддрд░ рдЖрд╡рд╛рдЬ рд╕рдВрдЪрд╛рд░ред

рдЕрд░реНрдХреЛ рд▓реЗрдЦрдорд╛ рд╣рд╛рдореА рд╣рд╛рдореНрд░рд╛ рдЖрдлреНрдиреИ рдлрд┐рд▓реНрдЯрд░рд╣рд░реВ - рдкреНрд▓рдЧрдЗрдирд╣рд░реВ рдХрд╕рд░реА рд▓реЗрдЦреНрдиреЗ рднрдиреЗрд░ рд╕рд┐рдХреНрдиреЗрдЫреМрдВ, рдпреЛ рд╕реАрдкрдХреЛ рд▓рд╛рдЧрд┐ рдзрдиреНрдпрд╡рд╛рдж, рддрдкрд╛рдИрдВрд▓реЗ рдорд┐рдбрд┐рдпрд╛ рд╕реНрдЯреНрд░рд┐рдорд░рд▓рд╛рдИ рдЕрдбрд┐рдпреЛ рд░ рднрд┐рдбрд┐рдпреЛрдХреЛ рд▓рд╛рдЧрд┐ рдорд╛рддреНрд░ рд╣реЛрдЗрди, рддрд░ рдХреЗрд╣реА рдЕрдиреНрдп рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреНрд╖реЗрддреНрд░рдорд╛ рдкрдирд┐ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреЗрдЫред

рд╕реНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдердкреНрди