sip.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414
  1. // in Asterisk pjsip.conf, under 1001, set direct_media=no
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include <math.h>
  7. #include "freertos/FreeRTOS.h"
  8. #include "freertos/task.h"
  9. #include "esp_wifi.h"
  10. #include "esp_event.h"
  11. #include "esp_log.h"
  12. #include "nvs_flash.h"
  13. #include "lwip/sockets.h"
  14. #include <stdbool.h>
  15. #include "esp_rom_md5.h"
  16. #include "bsp_board.h"
  17. #include "tca9555_driver.h"
  18. /*
  19. #include "esp_audio_enc_default.h"
  20. #include "esp_audio_enc.h"
  21. #include "esp_audio_dec_default.h"
  22. #include "esp_audio_dec.h"
  23. #include "esp_g711_enc.h"
  24. #include "esp_g711_dec.h"*/
  25. <<<<<<< HEAD
  26. #define ESP32_IP ""
  27. =======
  28. #define ESP32_IP "192.168.68.67"
  29. >>>>>>> 808cdc8 (aec and volume buttons implemented)
  30. #define RTP_PORT 4000
  31. #define WIFI_SSID ""
  32. #define WIFI_PASS ""
  33. #define ASTERISK_IP ""
  34. #define SIP_PORT 5060
  35. #define SIP_LOCAL_IP "0.0.0.0"
  36. #define SIP_LOCAL_PORT 5062
  37. #define SIP_USER "1001"
  38. #define SIP_PASSWORD "secret123"
  39. #define SAMPLE_RATE 8000
  40. #define SAMPLES_PER_PACKET 160 // 20 ms
  41. #define TONE_FREQ 1000
  42. #define MIC_FRAME_SAMPLES 320
  43. #define AEC_MAX_FRAME_SAMPLES 512
  44. #define FAR_END_FIFO_SAMPLES 2048
  45. static int32_t mic_buffer[320];
  46. static int16_t mic_pcm16[SAMPLES_PER_PACKET];
  47. static uint8_t payload[SAMPLES_PER_PACKET];
  48. static uint8_t rx_packet[172];
  49. static int16_t speaker_pcm[160];
  50. static const char *TAG = "SIP";
  51. volatile bool wifi_ready = false;
  52. static int s_rtp_sock = -1;
  53. static struct sockaddr_in s_rtp_peer = {0};
  54. static uint16_t s_rtp_peer_port = 0;
  55. static volatile bool call_active = false;
  56. static volatile bool s_audio_hw_ready = false;
  57. static int16_t far_end_fifo[FAR_END_FIFO_SAMPLES];
  58. static size_t far_end_read = 0;
  59. static size_t far_end_write = 0;
  60. static portMUX_TYPE far_end_mux = portMUX_INITIALIZER_UNLOCKED;
  61. static int16_t aec_mic_pending[AEC_MAX_FRAME_SAMPLES];
  62. static int16_t aec_ref_pending[AEC_MAX_FRAME_SAMPLES];
  63. static size_t aec_pending_samples = 0;
  64. static int16_t aec_output_fifo[FAR_END_FIFO_SAMPLES];
  65. static size_t aec_output_samples = 0;
  66. esp_err_t esp_get_feed_data(
  67. bool is_get_raw_channel,
  68. int16_t *buffer,
  69. int buffer_len);
  70. esp_err_t esp_audio_play(const int16_t *data,
  71. int length,
  72. uint32_t ticks_to_wait);
  73. esp_err_t sip_media_init(void);
  74. static void rtp_tx_task(void *pvParameters);
  75. static void rtp_rx_task(void *pvParameters);
  76. static void far_end_push(const int16_t *samples, size_t count)
  77. {
  78. portENTER_CRITICAL(&far_end_mux);
  79. for (size_t i = 0; i < count; ++i) {
  80. size_t next = (far_end_write + 1) % FAR_END_FIFO_SAMPLES;
  81. if (next == far_end_read) {
  82. far_end_read = (far_end_read + 1) % FAR_END_FIFO_SAMPLES;
  83. }
  84. far_end_fifo[far_end_write] = samples[i];
  85. far_end_write = next;
  86. }
  87. portEXIT_CRITICAL(&far_end_mux);
  88. }
  89. static void far_end_pop(int16_t *samples, size_t count)
  90. {
  91. portENTER_CRITICAL(&far_end_mux);
  92. for (size_t i = 0; i < count; ++i) {
  93. if (far_end_read == far_end_write) {
  94. samples[i] = 0;
  95. } else {
  96. samples[i] = far_end_fifo[far_end_read];
  97. far_end_read = (far_end_read + 1) % FAR_END_FIFO_SAMPLES;
  98. }
  99. }
  100. portEXIT_CRITICAL(&far_end_mux);
  101. }
  102. static bool aec_process_capture(const int16_t *near_end,
  103. const int16_t *far_end,
  104. size_t sample_count)
  105. {
  106. int frame_size = bsp_aec_get_frame_size();
  107. if (frame_size <= 0 || frame_size > AEC_MAX_FRAME_SAMPLES) {
  108. return false;
  109. }
  110. for (size_t i = 0; i < sample_count; ++i) {
  111. if (aec_pending_samples == AEC_MAX_FRAME_SAMPLES) {
  112. return false;
  113. }
  114. aec_mic_pending[aec_pending_samples] = near_end[i];
  115. aec_ref_pending[aec_pending_samples] = far_end[i];
  116. ++aec_pending_samples;
  117. if (aec_pending_samples == (size_t)frame_size) {
  118. int16_t processed[AEC_MAX_FRAME_SAMPLES];
  119. if (bsp_aec_process_frame(aec_mic_pending,
  120. aec_ref_pending,
  121. processed) != ESP_OK) {
  122. return false;
  123. }
  124. /* AEC runs at 16 kHz. The negotiated PCMU stream is 8 kHz,
  125. * so retain every second cleaned sample for RTP encoding. */
  126. for (int sample = 0; sample < frame_size; sample += 2) {
  127. if (aec_output_samples < FAR_END_FIFO_SAMPLES) {
  128. aec_output_fifo[aec_output_samples++] = processed[sample];
  129. }
  130. }
  131. aec_pending_samples = 0;
  132. }
  133. }
  134. return true;
  135. }
  136. static bool aec_output_pop(int16_t *samples, size_t count)
  137. {
  138. if (aec_output_samples < count) {
  139. return false;
  140. }
  141. memcpy(samples, aec_output_fifo, count * sizeof(int16_t));
  142. memmove(aec_output_fifo,
  143. aec_output_fifo + count,
  144. (aec_output_samples - count) * sizeof(int16_t));
  145. aec_output_samples -= count;
  146. return true;
  147. }
  148. /* ================= WIFI ================= */
  149. static void wifi_event_handler(void *arg, esp_event_base_t event_base,
  150. int32_t event_id, void *event_data)
  151. {
  152. if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
  153. esp_wifi_connect();
  154. }
  155. else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
  156. ESP_LOGI(TAG, "WiFi disconnected, retrying...");
  157. wifi_ready = false;
  158. esp_wifi_connect();
  159. }
  160. else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
  161. ESP_LOGI(TAG, "WiFi connected!");
  162. wifi_ready = true;
  163. }
  164. esp_netif_ip_info_t ip;
  165. esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"), &ip);
  166. ESP_LOGI(TAG, "ESP32 IP: " IPSTR, IP2STR(&ip.ip));
  167. }
  168. void wifi_init(void)
  169. {
  170. nvs_flash_init();
  171. esp_netif_init();
  172. esp_event_loop_create_default();
  173. esp_netif_create_default_wifi_sta();
  174. wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  175. esp_wifi_init(&cfg);
  176. esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL);
  177. esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL);
  178. wifi_config_t wifi_config = {
  179. .sta = {
  180. .ssid = WIFI_SSID,
  181. .password = WIFI_PASS,
  182. },
  183. };
  184. esp_wifi_set_mode(WIFI_MODE_STA);
  185. esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
  186. esp_wifi_start();
  187. }
  188. /* ================= MD5 HELPERS ================= */
  189. static void md5_calc(const unsigned char *input, size_t len, unsigned char output[16])
  190. {
  191. md5_context_t ctx;
  192. esp_rom_md5_init(&ctx);
  193. esp_rom_md5_update(&ctx, input, len);
  194. esp_rom_md5_final(output, &ctx);
  195. }
  196. static void md5_to_hex(unsigned char *md5, char *out)
  197. {
  198. for (int i = 0; i < 16; i++) {
  199. sprintf(out + i * 2, "%02x", md5[i]);
  200. }
  201. }
  202. /* ================= SIP DIGEST ================= */
  203. void sip_compute_response(
  204. const char *username,
  205. const char *realm,
  206. const char *password,
  207. const char *nonce,
  208. const char *uri,
  209. char *out_response)
  210. {
  211. unsigned char ha1_md5[16], ha2_md5[16], final_md5[16];
  212. char ha1_hex[64], ha2_hex[64], final_str[256];
  213. char ha1[128], ha2[128];
  214. snprintf(ha1, sizeof(ha1), "%s:%s:%s", username, realm, password);
  215. md5_calc((unsigned char*)ha1, strlen(ha1), ha1_md5);
  216. md5_to_hex(ha1_md5, ha1_hex);
  217. snprintf(ha2, sizeof(ha2), "REGISTER:%s", uri);
  218. md5_calc((unsigned char*)ha2, strlen(ha2), ha2_md5);
  219. md5_to_hex(ha2_md5, ha2_hex);
  220. snprintf(final_str, sizeof(final_str),
  221. "%s:%s:%s", ha1_hex, nonce, ha2_hex);
  222. md5_calc((unsigned char*)final_str, strlen(final_str), final_md5);
  223. md5_to_hex(final_md5, out_response);
  224. }
  225. /* ================= SIP HELPERS ================= */
  226. static bool sip_extract_header(const char *msg, const char *header, char *out, size_t out_len)
  227. {
  228. const char *start = strstr(msg, header);
  229. if (!start) {
  230. return false;
  231. }
  232. start += strlen(header);
  233. while (*start == ' ' || *start == '\t') {
  234. start++;
  235. }
  236. const char *end = start;
  237. while (*end != '\0' && *end != '\r' && *end != '\n') {
  238. end++;
  239. }
  240. size_t len = (size_t)(end - start);
  241. if (len >= out_len) {
  242. len = out_len - 1;
  243. }
  244. memcpy(out, start, len);
  245. out[len] = '\0';
  246. return true;
  247. }
  248. static void sip_send_200_ok(int sock, const struct sockaddr_in *remote, const char *sip_msg,
  249. const char *sdp_body, size_t sdp_len)
  250. {
  251. char via[512] = {0};
  252. char from[256] = {0};
  253. char to[256] = {0};
  254. char callid[256] = {0};
  255. char cseq[128] = {0};
  256. char response[4096];
  257. if (!sip_extract_header(sip_msg, "Via:", via, sizeof(via))) {
  258. snprintf(via, sizeof(via), "SIP/2.0/UDP %s:%d", SIP_LOCAL_IP, SIP_LOCAL_PORT);
  259. }
  260. if (!sip_extract_header(sip_msg, "From:", from, sizeof(from))) {
  261. snprintf(from, sizeof(from), "<sip:%s@%s>", SIP_USER, ASTERISK_IP);
  262. }
  263. if (!sip_extract_header(sip_msg, "To:", to, sizeof(to))) {
  264. snprintf(to, sizeof(to), "<sip:%s@%s>", SIP_USER, ASTERISK_IP);
  265. }
  266. if (!sip_extract_header(sip_msg, "Call-ID:", callid, sizeof(callid))) {
  267. snprintf(callid, sizeof(callid), "esp32-call");
  268. }
  269. if (!sip_extract_header(sip_msg, "CSeq:", cseq, sizeof(cseq))) {
  270. snprintf(cseq, sizeof(cseq), "1 REGISTER");
  271. }
  272. int body_len = sdp_body ? (int)sdp_len : 0;
  273. int written = snprintf(response, sizeof(response),
  274. "SIP/2.0 200 OK\r\n"
  275. "Via: %s\r\n"
  276. "From: %s\r\n"
  277. "To: %s;tag=esp32\r\n"
  278. "Call-ID: %s\r\n"
  279. "CSeq: %s\r\n"
  280. "Contact: <sip:%s@%s:%d>\r\n"
  281. "%s"
  282. "Content-Length: %d\r\n"
  283. "\r\n"
  284. "%s",
  285. via,
  286. from,
  287. to,
  288. callid,
  289. cseq,
  290. SIP_USER,
  291. ESP32_IP,
  292. SIP_LOCAL_PORT,
  293. sdp_body ? "Content-Type: application/sdp\r\n" : "",
  294. body_len,
  295. sdp_body ? sdp_body : "");
  296. if (written < 0 || written >= (int)sizeof(response)) {
  297. ESP_LOGW(TAG, "SIP 200 OK response too large");
  298. return;
  299. }
  300. sendto(sock, response, (size_t)written, 0,
  301. (struct sockaddr *)remote, sizeof(*remote));
  302. }
  303. static void sip_build_sdp(char *out, size_t out_len)
  304. {
  305. snprintf(out, out_len,
  306. "v=0\r\n"
  307. "o=ESP32 1234 1234 IN IP4 %s\r\n"
  308. "s=ESP32 SIP Call\r\n"
  309. "c=IN IP4 %s\r\n"
  310. "t=0 0\r\n"
  311. "m=audio %d RTP/AVP 0\r\n"
  312. "a=rtpmap:0 PCMU/8000\r\n"
  313. "a=ptime:20\r\n"
  314. "a=sendrecv\r\n",
  315. ESP32_IP,
  316. ESP32_IP,
  317. RTP_PORT);
  318. }
  319. static bool sip_extract_rtp_port(const char *msg, uint16_t *out_port)
  320. {
  321. const char *m = strstr(msg, "m=audio ");
  322. if (!m) {
  323. return false;
  324. }
  325. m += strlen("m=audio ");
  326. char port_buf[16] = {0};
  327. size_t i = 0;
  328. while (*m && *m != ' ' && *m != '\r' && *m != '\n' && i < sizeof(port_buf) - 1) {
  329. port_buf[i++] = *m++;
  330. }
  331. port_buf[i] = '\0';
  332. *out_port = (uint16_t)atoi(port_buf);
  333. return *out_port != 0;
  334. }
  335. /* ================= RTP TX ================= */
  336. static bool microphone_read(int16_t *samples, size_t count)
  337. {
  338. // ESP_LOGI(TAG,
  339. // "mic ptr=%p samples=%d bytes=%d",
  340. // samples,
  341. // count,
  342. // count * sizeof(int16_t));
  343. esp_err_t ret = esp_get_feed_data(false, samples, count);
  344. if(ret != ESP_OK)
  345. {
  346. ESP_LOGE(TAG,
  347. "esp_get_feed_data failed: %s",
  348. esp_err_to_name(ret));
  349. return false;
  350. }
  351. return true;
  352. }
  353. static uint8_t linear2ulaw(int16_t pcm)
  354. {
  355. const int16_t BIAS = 0x84;
  356. const int16_t CLIP = 32635;
  357. uint8_t mask;
  358. uint8_t seg;
  359. uint8_t uval;
  360. int16_t sample = pcm;
  361. if (sample < 0)
  362. {
  363. sample = -sample;
  364. mask = 0x7F;
  365. }
  366. else
  367. {
  368. mask = 0xFF;
  369. }
  370. if (sample > CLIP)
  371. sample = CLIP;
  372. sample += BIAS;
  373. if (sample <= 0xFF)
  374. seg = 0;
  375. else if (sample <= 0x1FF)
  376. seg = 1;
  377. else if (sample <= 0x3FF)
  378. seg = 2;
  379. else if (sample <= 0x7FF)
  380. seg = 3;
  381. else if (sample <= 0xFFF)
  382. seg = 4;
  383. else if (sample <= 0x1FFF)
  384. seg = 5;
  385. else if (sample <= 0x3FFF)
  386. seg = 6;
  387. else
  388. seg = 7;
  389. uval = (seg << 4) |
  390. ((sample >> (seg + 3)) & 0x0F);
  391. return uval ^ mask;
  392. }
  393. static int16_t ulaw2linear(uint8_t u_val)
  394. {
  395. u_val = ~u_val;
  396. int t = ((u_val & 0x0F) << 3) + 0x84;
  397. t <<= ((unsigned)u_val & 0x70) >> 4;
  398. if (u_val & 0x80)
  399. return 0x84 - t;
  400. else
  401. return t - 0x84;
  402. }
  403. static void sip_send_rtp_packet(void)
  404. {
  405. static uint32_t call_count = 0;
  406. /*
  407. ESP_LOGI(TAG,
  408. "sip_send_rtp_packet() #%lu",
  409. (unsigned long)call_count++);*/
  410. static uint16_t seq = 0;
  411. static uint32_t timestamp = 0;
  412. if(s_rtp_peer_port == 0)
  413. {
  414. ESP_LOGW(TAG,"No RTP peer");
  415. return;
  416. }
  417. if(s_rtp_peer_port == 0)
  418. {
  419. ESP_LOGW(TAG,
  420. "No RTP peer port set!");
  421. return;
  422. }
  423. <<<<<<< HEAD
  424. =======
  425. >>>>>>> 808cdc8 (aec and volume buttons implemented)
  426. if(s_rtp_sock < 0)
  427. {
  428. s_rtp_sock = socket(AF_INET,
  429. SOCK_DGRAM,
  430. IPPROTO_UDP);
  431. ESP_LOGI(TAG,
  432. "RTP socket=%d",
  433. s_rtp_sock);
  434. struct sockaddr_in local_rtp = {0};
  435. local_rtp.sin_family = AF_INET;
  436. local_rtp.sin_port = htons(RTP_PORT);
  437. local_rtp.sin_addr.s_addr = INADDR_ANY;
  438. if(bind(s_rtp_sock,
  439. (struct sockaddr *)&local_rtp,
  440. sizeof(local_rtp)) < 0)
  441. {
  442. ESP_LOGE(TAG, "RTP bind failed errno=%d", errno);
  443. }
  444. else
  445. {
  446. ESP_LOGI(TAG,
  447. "RTP listening on port %d",
  448. RTP_PORT);
  449. }
  450. if(s_rtp_sock < 0)
  451. {
  452. ESP_LOGE(TAG,
  453. "RTP socket failed");
  454. return;
  455. }
  456. }
  457. uint8_t payload[SAMPLES_PER_PACKET];
  458. // Read one 20 ms stereo capture block (320 mono samples at 16 kHz).
  459. if (!microphone_read((int16_t *)mic_buffer, sizeof(mic_buffer)))
  460. {
  461. return;
  462. }
  463. int16_t *mic16 = (int16_t *)mic_buffer;
  464. int16_t near_end[MIC_FRAME_SAMPLES];
  465. int16_t far_end[MIC_FRAME_SAMPLES];
  466. <<<<<<< HEAD
  467. // Convert 32-bit audio to PCM16
  468. for(int i = 0; i < SAMPLES_PER_PACKET; i++)
  469. {
  470. // Take microphone channel
  471. int32_t s = mic_buffer[i * 2];
  472. // Trying these one at a time
  473. //mic_pcm16[i] = s >> 16;
  474. //mic_pcm16[i] = s >> 15;
  475. mic_pcm16[i] = s >> 14;
  476. }
  477. =======
  478. for (int i = 0; i < MIC_FRAME_SAMPLES; ++i) {
  479. int32_t left = mic16[i * 2];
  480. int32_t right = mic16[i * 2 + 1];
  481. near_end[i] = (int16_t)((left + right) / 2);
  482. }
  483. far_end_pop(far_end, MIC_FRAME_SAMPLES);
  484. if (!aec_process_capture(near_end, far_end, MIC_FRAME_SAMPLES) ||
  485. !aec_output_pop(mic_pcm16, SAMPLES_PER_PACKET)) {
  486. return;
  487. }
  488. >>>>>>> 808cdc8 (aec and volume buttons implemented)
  489. // Debug microphone level
  490. int max = 0;
  491. for(int i = 0; i < SAMPLES_PER_PACKET; i++)
  492. {
  493. int value = abs(mic_pcm16[i]);
  494. if(value > max)
  495. max = value;
  496. }
  497. /*
  498. ESP_LOGI("MIC", "max=%d", max);*/
  499. // PCM16 -> PCMU (G711 u-law)
  500. for(int i = 0; i < SAMPLES_PER_PACKET; i++)
  501. {
  502. payload[i] = linear2ulaw(mic_pcm16[i]);
  503. }
  504. //testing multiple packets
  505. /*
  506. ESP_LOGI("MIC",
  507. "%6d %6d %6d %6d %6d %6d %6d %6d "
  508. "%6d %6d %6d %6d %6d %6d %6d %6d "
  509. "%6d %6d %6d %6d",
  510. mic_pcm16[0], mic_pcm16[1], mic_pcm16[2], mic_pcm16[3],
  511. mic_pcm16[4], mic_pcm16[5], mic_pcm16[6], mic_pcm16[7],
  512. mic_pcm16[8], mic_pcm16[9], mic_pcm16[10], mic_pcm16[11],
  513. mic_pcm16[12], mic_pcm16[13], mic_pcm16[14], mic_pcm16[15],
  514. mic_pcm16[16], mic_pcm16[17], mic_pcm16[18], mic_pcm16[19]);
  515. */
  516. uint8_t packet[12 + SAMPLES_PER_PACKET];
  517. memset(packet,0,sizeof(packet));
  518. packet[0] = 0x80; // RTP version
  519. packet[1] = 0x00; // PCMU
  520. packet[2] = seq >> 8;
  521. packet[3] = seq & 0xff;
  522. packet[4] = timestamp >> 24;
  523. packet[5] = timestamp >> 16;
  524. packet[6] = timestamp >> 8;
  525. packet[7] = timestamp;
  526. uint32_t ssrc = 0x12345678;
  527. packet[8] = (ssrc >> 24) & 0xff;
  528. packet[9] = (ssrc >> 16) & 0xff;
  529. packet[10] = (ssrc >> 8) & 0xff;
  530. packet[11] = ssrc & 0xff;
  531. memcpy(packet+12,
  532. payload,
  533. SAMPLES_PER_PACKET);
  534. struct sockaddr_in peer = s_rtp_peer;
  535. peer.sin_port = htons(s_rtp_peer_port);
  536. /*ESP_LOGI(TAG,
  537. "RTP destination IP: %s",
  538. inet_ntoa(peer.sin_addr));
  539. ESP_LOGI(TAG,
  540. "Sending RTP to %s:%d",
  541. inet_ntoa(peer.sin_addr),
  542. ntohs(peer.sin_port));*/
  543. esp_netif_ip_info_t ip;
  544. esp_netif_t *netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");
  545. esp_netif_get_ip_info(netif, &ip);
  546. /*ESP_LOGI(TAG, "Current IP: " IPSTR, IP2STR(&ip.ip));*/
  547. int ret =
  548. sendto(
  549. s_rtp_sock,
  550. packet,
  551. sizeof(packet),
  552. 0,
  553. (struct sockaddr *)&peer,
  554. sizeof(peer));
  555. if(ret < 0)
  556. {
  557. ESP_LOGE(TAG,
  558. "RTP send failed errno=%d",
  559. errno);
  560. }
  561. else
  562. {
  563. /* ESP_LOGI(TAG,
  564. "RTP sent bytes=%d seq=%d",
  565. ret,
  566. seq);*/
  567. }
  568. /*if(ret > 0)
  569. {
  570. ESP_LOGI(TAG,
  571. "RTP sent seq=%d",
  572. seq);
  573. }*/
  574. seq++;
  575. timestamp += SAMPLES_PER_PACKET;
  576. }
  577. static void rtp_tx_task(void *pvParameters)
  578. {
  579. ESP_LOGI(TAG, "RTP TX started");
  580. TickType_t last_wake = xTaskGetTickCount();
  581. while(call_active)
  582. {/*ESP_LOGI(TAG, "RTP loop");*/
  583. sip_send_rtp_packet();
  584. vTaskDelayUntil(
  585. &last_wake,
  586. pdMS_TO_TICKS(20)
  587. );
  588. }
  589. ESP_LOGI(TAG, "RTP TX stopped");
  590. vTaskDelete(NULL);
  591. }
  592. /*static void rtp_rx_task(void *pvParameters)
  593. {
  594. ESP_LOGI(TAG, "RTP RX started");
  595. // TEMP: create RTP socket for RX-only testing
  596. if (s_rtp_sock < 0)
  597. {
  598. s_rtp_sock = socket(AF_INET,
  599. SOCK_DGRAM,
  600. IPPROTO_UDP);
  601. if (s_rtp_sock < 0)
  602. {
  603. ESP_LOGE(TAG,
  604. "RTP socket failed errno=%d",
  605. errno);
  606. vTaskDelete(NULL);
  607. return;
  608. }
  609. struct sockaddr_in local_rtp = {0};
  610. local_rtp.sin_family = AF_INET;
  611. local_rtp.sin_port = htons(RTP_PORT);
  612. local_rtp.sin_addr.s_addr = INADDR_ANY;
  613. if (bind(s_rtp_sock,
  614. (struct sockaddr *)&local_rtp,
  615. sizeof(local_rtp)) < 0)
  616. {
  617. ESP_LOGE(TAG,
  618. "RTP bind failed errno=%d",
  619. errno);
  620. close(s_rtp_sock);
  621. s_rtp_sock = -1;
  622. vTaskDelete(NULL);
  623. return;
  624. }
  625. ESP_LOGI(TAG,
  626. "RTP RX listening on port %d",
  627. RTP_PORT);
  628. }
  629. while (call_active)
  630. {
  631. struct sockaddr_in src;
  632. socklen_t len = sizeof(src);
  633. int n = recvfrom(
  634. s_rtp_sock,
  635. rx_packet,
  636. sizeof(rx_packet),
  637. 0,
  638. (struct sockaddr *)&src,
  639. &len);*/
  640. //comment this block out for testing rx only
  641. static void rtp_rx_task(void *pvParameters)
  642. {
  643. ESP_LOGI(TAG, "RTP RX started");
  644. while (call_active)
  645. {
  646. struct sockaddr_in src;
  647. socklen_t len = sizeof(src);
  648. int n = recvfrom(
  649. s_rtp_sock,
  650. rx_packet,
  651. sizeof(rx_packet),
  652. 0,
  653. (struct sockaddr *)&src,
  654. &len);//
  655. if (n < 0)
  656. {
  657. ESP_LOGE(TAG, "recvfrom failed errno=%d", errno);
  658. continue;
  659. }
  660. <<<<<<< HEAD
  661. ESP_LOGI(TAG, "Received RTP packet (%d bytes)", n);
  662. =======
  663. if (s_rtp_peer_port != 0 &&
  664. (src.sin_port != htons(s_rtp_peer_port) ||
  665. src.sin_addr.s_addr != s_rtp_peer.sin_addr.s_addr))
  666. {
  667. ESP_LOGW(TAG,
  668. "Ignoring RTP from unexpected peer %s:%d",
  669. inet_ntoa(src.sin_addr),
  670. ntohs(src.sin_port));
  671. continue;
  672. }
  673. /* Ignore packets that are clearly looped back to the local device. */
  674. esp_netif_ip_info_t local_ip;
  675. esp_netif_t *netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");
  676. esp_netif_get_ip_info(netif, &local_ip);
  677. if (src.sin_addr.s_addr == local_ip.ip.addr)
  678. {
  679. ESP_LOGW(TAG, "Ignoring looped RTP packet from local IP");
  680. continue;
  681. }
  682. // ESP_LOGI(TAG, "Received RTP packet (%d bytes)", n);
  683. >>>>>>> 808cdc8 (aec and volume buttons implemented)
  684. if (n <= 12)
  685. {
  686. ESP_LOGW(TAG, "Packet too small");
  687. continue;
  688. }
  689. // ESP_LOGI(TAG,
  690. // "RTP Header: %02X %02X %02X %02X",
  691. // rx_packet[0],
  692. // rx_packet[1],
  693. // rx_packet[2],
  694. // rx_packet[3]);
  695. // ESP_LOGI(TAG,
  696. // "RTP Payload: %02X %02X %02X %02X %02X %02X %02X %02X",
  697. // rx_packet[12],
  698. // rx_packet[13],
  699. // rx_packet[14],
  700. // rx_packet[15],
  701. // rx_packet[16],
  702. // rx_packet[17],
  703. // rx_packet[18],
  704. // rx_packet[19]);
  705. int payload_size = n - 12;
  706. if (payload_size > SAMPLES_PER_PACKET)
  707. {
  708. payload_size = SAMPLES_PER_PACKET;
  709. }
  710. int16_t play_buf[640];
  711. int16_t far_end_ref[320];
  712. for (int i = 0; i < payload_size; i++)
  713. {
  714. int16_t s1 = ulaw2linear(rx_packet[12+i]);
  715. int16_t s2 = s1;
  716. if (i < payload_size - 1)
  717. {
  718. int16_t next = ulaw2linear(rx_packet[12+i+1]);
  719. s2 = (s1 + next) / 2;
  720. }
  721. // sample 1
  722. play_buf[4*i + 0] = s1; // Left
  723. play_buf[4*i + 1] = s1; // Right
  724. // interpolated sample
  725. play_buf[4*i + 2] = s2; // Left
  726. play_buf[4*i + 3] = s2; // Right
  727. far_end_ref[2 * i] = s1;
  728. far_end_ref[2 * i + 1] = s2;
  729. }
  730. // The reference must be the mono 16 kHz signal sent to the speaker,
  731. // before it is duplicated into the codec's stereo output.
  732. far_end_push(far_end_ref, payload_size * 2);
  733. esp_err_t ret = esp_audio_play(
  734. play_buf,
  735. payload_size * 4 * sizeof(int16_t),
  736. portMAX_DELAY);
  737. // ESP_LOGI(TAG,
  738. // "esp_audio_play() = %s",
  739. // esp_err_to_name(ret));
  740. // ESP_LOGI(TAG, "esp_audio_play() returned %s",
  741. // esp_err_to_name(ret));
  742. }
  743. ESP_LOGI(TAG, "RTP RX stopped");
  744. vTaskDelete(NULL);
  745. }
  746. /* ================= SIP TASK ================= */
  747. void sip_register_task(void *pvParameters)
  748. {
  749. struct sockaddr_in server = {0};
  750. server.sin_family = AF_INET;
  751. server.sin_port = htons(SIP_PORT);
  752. server.sin_addr.s_addr = inet_addr(ASTERISK_IP);
  753. int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  754. struct sockaddr_in local_addr = {0};
  755. local_addr.sin_family = AF_INET;
  756. local_addr.sin_port = htons(SIP_LOCAL_PORT);
  757. local_addr.sin_addr.s_addr = INADDR_ANY;
  758. if (bind(sock,
  759. (struct sockaddr *)&local_addr,
  760. sizeof(local_addr)) < 0) {
  761. ESP_LOGE(TAG, "Failed to bind SIP port %d", SIP_LOCAL_PORT);
  762. close(sock);
  763. vTaskDelete(NULL);
  764. return;
  765. }
  766. ESP_LOGI(TAG, "SIP listening on UDP %d", SIP_LOCAL_PORT);
  767. if (sock < 0) {
  768. ESP_LOGE(TAG, "Socket failed");
  769. vTaskDelete(NULL);
  770. return;
  771. }
  772. struct timeval timeout = {
  773. .tv_sec = 300,
  774. .tv_usec = 0
  775. };
  776. setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
  777. /* ================= FIRST REGISTER ================= */
  778. char register_msg[512];
  779. snprintf(register_msg, sizeof(register_msg),
  780. "REGISTER sip:%s SIP/2.0\r\n"
  781. "Via: SIP/2.0/UDP %s:%d\r\n"
  782. "From: <sip:%s@%s>;tag=1234\r\n"
  783. "To: <sip:%s@%s>\r\n"
  784. "Call-ID: esp32-0001\r\n"
  785. "CSeq: 1 REGISTER\r\n"
  786. "Contact: <sip:%s@%s:%d>\r\n"
  787. "Expires: 300\r\n"
  788. "Content-Length: 0\r\n"
  789. "\r\n",
  790. ASTERISK_IP,
  791. SIP_LOCAL_IP,
  792. SIP_LOCAL_PORT,
  793. SIP_USER,
  794. ASTERISK_IP,
  795. SIP_USER,
  796. ASTERISK_IP,
  797. SIP_USER,
  798. SIP_LOCAL_IP,
  799. SIP_LOCAL_PORT);
  800. ESP_LOGI(TAG, "Sending REGISTER...");
  801. sendto(sock, register_msg, strlen(register_msg), 0,
  802. (struct sockaddr*)&server, sizeof(server));
  803. /* ================= RECEIVE 401 / 200 ================= */
  804. char response[1024];
  805. socklen_t addr_len = sizeof(server);
  806. bool registered = false;
  807. while (!registered) {
  808. int len = recvfrom(sock, response, sizeof(response) - 1, 0,
  809. (struct sockaddr *)&server, &addr_len);
  810. if (len <= 0) {
  811. ESP_LOGE(TAG, "No response");
  812. close(sock);
  813. vTaskDelete(NULL);
  814. return;
  815. }
  816. response[len] = '\0';
  817. // printf("SIP RESPONSE:\n%s\n", response);
  818. ESP_LOGI(TAG, "Received SIP response (%d bytes)", len);
  819. if (strstr(response, "SIP/2.0 401")) {
  820. char sip_nonce[256] = {0};
  821. char sip_realm[128] = {0};
  822. char *n = strstr(response, "nonce=\"");
  823. if (n) {
  824. n += 7;
  825. char *end = strchr(n, '"');
  826. if (end) {
  827. size_t nlen = end - n;
  828. if (nlen < sizeof(sip_nonce)) {
  829. strncpy(sip_nonce, n, nlen);
  830. sip_nonce[nlen] = '\0';
  831. }
  832. }
  833. }
  834. char *r = strstr(response, "realm=\"");
  835. if (r) {
  836. r += 7;
  837. char *rend = strchr(r, '"');
  838. if (rend) {
  839. size_t rlen = rend - r;
  840. if (rlen < sizeof(sip_realm)) {
  841. strncpy(sip_realm, r, rlen);
  842. sip_realm[rlen] = '\0';
  843. }
  844. }
  845. }
  846. if (sip_realm[0] == '\0' || sip_nonce[0] == '\0') {
  847. ESP_LOGE(TAG, "Missing realm or nonce in challenge");
  848. close(sock);
  849. vTaskDelete(NULL);
  850. return;
  851. }
  852. ESP_LOGI(TAG, "Nonce: %s", sip_nonce);
  853. ESP_LOGI(TAG, "Realm: %s", sip_realm);
  854. char response_hash[64];
  855. char sip_uri[64];
  856. snprintf(sip_uri, sizeof(sip_uri), "sip:%s", ASTERISK_IP);
  857. sip_compute_response(
  858. SIP_USER,
  859. sip_realm,
  860. SIP_PASSWORD,
  861. sip_nonce,
  862. sip_uri,
  863. response_hash
  864. );
  865. char auth[1024];
  866. snprintf(auth, sizeof(auth),
  867. "REGISTER sip:%s SIP/2.0\r\n"
  868. "Via: SIP/2.0/UDP %s:%d\r\n"
  869. "From: <sip:%s@%s>;tag=1234\r\n"
  870. "To: <sip:%s@%s>\r\n"
  871. "Call-ID: esp32-0001\r\n"
  872. "CSeq: 2 REGISTER\r\n"
  873. "Contact: <sip:%s@%s:%d>\r\n"
  874. "Authorization: Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"sip:%s\", response=\"%s\"\r\n"
  875. "Expires: 300\r\n"
  876. "Content-Length: 0\r\n"
  877. "\r\n",
  878. ASTERISK_IP,
  879. SIP_LOCAL_IP,
  880. SIP_LOCAL_PORT,
  881. SIP_USER,
  882. ASTERISK_IP,
  883. SIP_USER,
  884. ASTERISK_IP,
  885. SIP_USER,
  886. SIP_LOCAL_IP,
  887. SIP_LOCAL_PORT,
  888. SIP_USER,
  889. sip_realm,
  890. sip_nonce,
  891. ASTERISK_IP,
  892. response_hash);
  893. ESP_LOGI(TAG, "Sending AUTH REGISTER...");
  894. sendto(sock, auth, strlen(auth), 0,
  895. (struct sockaddr *)&server, sizeof(server));
  896. }
  897. else if (strstr(response, "SIP/2.0 200")) {
  898. registered = true;
  899. }
  900. else if (strstr(response, "SIP/2.0 486")) {
  901. ESP_LOGW(TAG, "Server returned 486 Busy");
  902. }
  903. else {
  904. ESP_LOGI(TAG, "Ignoring SIP response");
  905. }
  906. }
  907. if (!registered) {
  908. ESP_LOGW(TAG, "Registration was not completed");
  909. close(sock);
  910. vTaskDelete(NULL);
  911. return;
  912. }
  913. ESP_LOGI(TAG, "🎉 SIP REGISTER SUCCESS");
  914. ESP_LOGI(TAG, "stack remaining: %u",
  915. uxTaskGetStackHighWaterMark(NULL));
  916. /* =====================================================
  917. * KEEP SOCKET OPEN AND WAIT FOR SIP REQUESTS
  918. * ===================================================== */
  919. ESP_LOGI(TAG, "Waiting for incoming SIP requests...");
  920. while (1) {
  921. char rx_buf[2048];
  922. int rx_len = recvfrom(sock,
  923. rx_buf,
  924. sizeof(rx_buf) - 1,
  925. 0,
  926. (struct sockaddr *)&server,
  927. &addr_len);
  928. if (rx_len <= 0) {
  929. continue;
  930. }
  931. rx_buf[rx_len] = '\0';
  932. ESP_LOGI(TAG, "\n===== RAW INVITE =====\n%s\n=======================\n", rx_buf);
  933. // printf("\n========================================\n");
  934. // printf("SIP MESSAGE RECEIVED:\n");
  935. // printf("%s\n", rx_buf);
  936. ESP_LOGI(TAG, "Received SIP packet (%d bytes)", rx_len);
  937. // printf("========================================\n");
  938. if (strncmp(rx_buf, "REGISTER ", 9) == 0) {
  939. ESP_LOGI(TAG, "Received REGISTER; sending 200 OK");
  940. sip_send_200_ok(sock, &server, rx_buf, NULL, 0);
  941. continue;
  942. }
  943. else if (strncmp(rx_buf, "INVITE ", 7) == 0) {
  944. ESP_LOGI(TAG, "📞 Incoming INVITE");
  945. char *test = strstr(rx_buf, "m=audio");
  946. if(test)
  947. {
  948. ESP_LOGI(TAG, "Found m=audio SDP:");
  949. ESP_LOGI(TAG, "%s", test);
  950. }
  951. else
  952. {
  953. ESP_LOGE(TAG, "No m=audio found");
  954. }
  955. /* ================= EXTRACT SIP HEADERS ================= */
  956. char via[512] = {0};
  957. char from[256] = {0};
  958. char to[256] = {0};
  959. char callid[256] = {0};
  960. char cseq[128] = {0};
  961. char *header = NULL;
  962. header = strstr(rx_buf, "Via:");
  963. if (header) {
  964. sscanf(header, "Via: %511[^\r\n]", via);
  965. }
  966. header = strstr(rx_buf, "From:");
  967. if (header) {
  968. sscanf(header, "From: %255[^\r\n]", from);
  969. }
  970. header = strstr(rx_buf, "To:");
  971. if (header) {
  972. sscanf(header, "To: %255[^\r\n]", to);
  973. }
  974. header = strstr(rx_buf, "Call-ID:");
  975. if (header) {
  976. sscanf(header, "Call-ID: %255[^\r\n]", callid);
  977. }
  978. header = strstr(rx_buf, "CSeq:");
  979. if (header) {
  980. sscanf(header, "CSeq: %127[^\r\n]", cseq);
  981. }
  982. /* ================= SEND 100 TRYING ================= */
  983. char trying[4096];
  984. snprintf(trying, sizeof(trying),
  985. "SIP/2.0 100 Trying\r\n"
  986. "Via: %s\r\n"
  987. "From: %s\r\n"
  988. "To: %s\r\n"
  989. "Call-ID: %s\r\n"
  990. "CSeq: %s\r\n"
  991. "Content-Length: 0\r\n"
  992. "\r\n",
  993. via,
  994. from,
  995. to,
  996. callid,
  997. cseq);
  998. sendto(sock,
  999. trying,
  1000. strlen(trying),
  1001. 0,
  1002. (struct sockaddr *)&server,
  1003. sizeof(server));
  1004. ESP_LOGI(TAG, "100 Trying sent");
  1005. ESP_LOGI(TAG, "stack remaining: %u",
  1006. uxTaskGetStackHighWaterMark(NULL));
  1007. char ok[4096];
  1008. char sdp[1024];
  1009. sip_build_sdp(sdp, sizeof(sdp));
  1010. if (sip_extract_rtp_port(rx_buf, &s_rtp_peer_port)) {
  1011. s_rtp_peer.sin_family = AF_INET;
  1012. s_rtp_peer.sin_port = htons(s_rtp_peer_port);
  1013. s_rtp_peer.sin_addr.s_addr = inet_addr(ASTERISK_IP);
  1014. ESP_LOGI(TAG,
  1015. "RTP peer port=%d",
  1016. s_rtp_peer_port);
  1017. }
  1018. snprintf(ok, sizeof(ok),
  1019. "SIP/2.0 200 OK\r\n"
  1020. "Via: %s\r\n"
  1021. "From: %s\r\n"
  1022. "To: %s;esp32\r\n"
  1023. "Call-ID: %s\r\n"
  1024. "CSeq: %s\r\n"
  1025. "Contact: <sip:%s@%s:%d>\r\n"
  1026. "Content-Type: application/sdp\r\n"
  1027. "Content-Length: %d\r\n"
  1028. "\r\n"
  1029. "%s",
  1030. via,
  1031. from,
  1032. to,
  1033. callid,
  1034. cseq,
  1035. SIP_USER,
  1036. ESP32_IP,
  1037. SIP_LOCAL_PORT,
  1038. strlen(sdp),
  1039. sdp);
  1040. ESP_LOGI(TAG, "\n========== 200 OK ==========\n%s\n============================\n", ok);
  1041. sendto(sock,
  1042. ok,
  1043. strlen(ok),
  1044. 0,
  1045. (struct sockaddr *)&server,
  1046. sizeof(server));
  1047. ESP_LOGI(TAG, "200 OK sent");
  1048. }
  1049. else if (strncmp(rx_buf, "OPTIONS ", 8) == 0) {
  1050. ESP_LOGI(TAG, "Received OPTIONS");
  1051. }
  1052. else if (strncmp(rx_buf, "ACK ", 4) == 0)
  1053. {
  1054. ESP_LOGI(TAG, "Received ACK");
  1055. uint8_t test_values[] = {0xFF, 0x7F, 0x00, 0x80};
  1056. for(int i = 0; i < 4; i++)
  1057. {
  1058. ESP_LOGI(TAG,
  1059. "ulaw %02X -> %d",
  1060. test_values[i],
  1061. ulaw2linear(test_values[i]));
  1062. }
  1063. if (!call_active)
  1064. {
  1065. call_active = true;
  1066. BaseType_t ret = xTaskCreate(
  1067. rtp_tx_task,
  1068. "rtp_tx",
  1069. 16384,
  1070. NULL,
  1071. 5,
  1072. NULL);
  1073. xTaskCreate(
  1074. rtp_rx_task,
  1075. "rtp_rx",
  1076. 16384,
  1077. NULL,
  1078. 5,
  1079. NULL);
  1080. //temp comment out
  1081. //ESP_LOGI(TAG, "rtp task create result=%d", ret);
  1082. }
  1083. }
  1084. else if (strncmp(rx_buf, "BYE ", 4) == 0)
  1085. {
  1086. ESP_LOGI(TAG, "Received BYE");
  1087. call_active = false;
  1088. sip_send_200_ok(sock, &server, rx_buf, NULL, 0);
  1089. }
  1090. else {
  1091. ESP_LOGI(TAG, "Unknown SIP message");
  1092. }
  1093. }
  1094. close(sock);
  1095. vTaskDelete(NULL);
  1096. }
  1097. esp_err_t sip_media_init(void)
  1098. {
  1099. if (s_audio_hw_ready) {
  1100. return ESP_OK;
  1101. }
  1102. esp_err_t ret = esp_board_init(16000, 2, 32);
  1103. if (ret != ESP_OK) {
  1104. ESP_LOGE(TAG, "esp_board_init failed: %s", esp_err_to_name(ret));
  1105. return ret;
  1106. }
  1107. tca9555_driver_init();
  1108. /*if (!sip_open_audio_media_codecs()) {
  1109. return ESP_FAIL;
  1110. }*/
  1111. s_audio_hw_ready = true;
  1112. ESP_LOGI(TAG, "Audio board initialized for live RTP media");
  1113. return ESP_OK;
  1114. }