|
@@ -1,7 +1,4 @@
|
|
|
-//replace IP on line 262 with ASTERISK_IP
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
|
|
+//replace IP on line 283 with ASTERISK_IP
|
|
|
#include <stdio.h>
|
|
#include <stdio.h>
|
|
|
#include <string.h>
|
|
#include <string.h>
|
|
|
#include <unistd.h>
|
|
#include <unistd.h>
|
|
@@ -19,10 +16,13 @@
|
|
|
#include <stdbool.h>
|
|
#include <stdbool.h>
|
|
|
#include "mbedtls/md5.h"
|
|
#include "mbedtls/md5.h"
|
|
|
|
|
|
|
|
-#define WIFI_SSID " "
|
|
|
|
|
-#define WIFI_PASS " "
|
|
|
|
|
|
|
+#define ESP32_IP "10.0.0.15"
|
|
|
|
|
+#define RTP_PORT 4000
|
|
|
|
|
+
|
|
|
|
|
+#define WIFI_SSID "TOCHTECH"
|
|
|
|
|
+#define WIFI_PASS "Smarturns2017"
|
|
|
|
|
|
|
|
-#define ASTERISK_IP " "
|
|
|
|
|
|
|
+#define ASTERISK_IP "192.168.68.64"
|
|
|
#define SIP_PORT 5060
|
|
#define SIP_PORT 5060
|
|
|
|
|
|
|
|
static const char *TAG = "SIP";
|
|
static const char *TAG = "SIP";
|
|
@@ -130,6 +130,23 @@ void sip_register_task(void *pvParameters)
|
|
|
server.sin_addr.s_addr = inet_addr(ASTERISK_IP);
|
|
server.sin_addr.s_addr = inet_addr(ASTERISK_IP);
|
|
|
|
|
|
|
|
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
|
|
|
+ struct sockaddr_in local_addr = {0};
|
|
|
|
|
+
|
|
|
|
|
+local_addr.sin_family = AF_INET;
|
|
|
|
|
+local_addr.sin_port = htons(5062);
|
|
|
|
|
+local_addr.sin_addr.s_addr = INADDR_ANY;
|
|
|
|
|
+
|
|
|
|
|
+if (bind(sock,
|
|
|
|
|
+ (struct sockaddr *)&local_addr,
|
|
|
|
|
+ sizeof(local_addr)) < 0) {
|
|
|
|
|
+
|
|
|
|
|
+ ESP_LOGE(TAG, "Failed to bind SIP port 5062");
|
|
|
|
|
+ close(sock);
|
|
|
|
|
+ vTaskDelete(NULL);
|
|
|
|
|
+ return;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+ESP_LOGI(TAG, "SIP listening on UDP 5062");
|
|
|
|
|
|
|
|
if (sock < 0) {
|
|
if (sock < 0) {
|
|
|
ESP_LOGE(TAG, "Socket failed");
|
|
ESP_LOGE(TAG, "Socket failed");
|
|
@@ -138,7 +155,7 @@ void sip_register_task(void *pvParameters)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
struct timeval timeout = {
|
|
struct timeval timeout = {
|
|
|
- .tv_sec = 3,
|
|
|
|
|
|
|
+ .tv_sec = 300,
|
|
|
.tv_usec = 0
|
|
.tv_usec = 0
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -263,7 +280,7 @@ void sip_register_task(void *pvParameters)
|
|
|
sip_realm,
|
|
sip_realm,
|
|
|
"secret123",
|
|
"secret123",
|
|
|
sip_nonce,
|
|
sip_nonce,
|
|
|
- "sip:10.0.0.xxx",// replace this 10.0.0.xxx with ASTERISK_IP
|
|
|
|
|
|
|
+ "sip:192.168.68.64", // replace this 192.168.68.64 with ASTERISK_IP
|
|
|
response_hash
|
|
response_hash
|
|
|
);
|
|
);
|
|
|
|
|
|
|
@@ -297,26 +314,214 @@ void sip_register_task(void *pvParameters)
|
|
|
|
|
|
|
|
/* ================= FINAL RESPONSE ================= */
|
|
/* ================= FINAL RESPONSE ================= */
|
|
|
|
|
|
|
|
|
|
+ /* ================= FINAL RESPONSE ================= */
|
|
|
|
|
+
|
|
|
char final_resp[1024];
|
|
char final_resp[1024];
|
|
|
|
|
|
|
|
int len2 = recvfrom(sock,
|
|
int len2 = recvfrom(sock,
|
|
|
final_resp,
|
|
final_resp,
|
|
|
sizeof(final_resp) - 1,
|
|
sizeof(final_resp) - 1,
|
|
|
0,
|
|
0,
|
|
|
- (struct sockaddr*)&server,
|
|
|
|
|
|
|
+ (struct sockaddr *)&server,
|
|
|
&addr_len);
|
|
&addr_len);
|
|
|
|
|
|
|
|
- if (len2 > 0) {
|
|
|
|
|
- final_resp[len2] = '\0';
|
|
|
|
|
- printf("FINAL RESPONSE:\n%s\n", final_resp);
|
|
|
|
|
|
|
+ if (len2 <= 0) {
|
|
|
|
|
+ ESP_LOGW(TAG, "No final response");
|
|
|
|
|
+ close(sock);
|
|
|
|
|
+ vTaskDelete(NULL);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ final_resp[len2] = '\0';
|
|
|
|
|
+
|
|
|
|
|
+ printf("FINAL RESPONSE:\n%s\n", final_resp);
|
|
|
|
|
+
|
|
|
|
|
+ if (!strstr(final_resp, "200 OK")) {
|
|
|
|
|
+ ESP_LOGW(TAG, "REGISTER FAILED");
|
|
|
|
|
+ close(sock);
|
|
|
|
|
+ vTaskDelete(NULL);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ESP_LOGI(TAG, "🎉 SIP REGISTER SUCCESS");
|
|
|
|
|
+
|
|
|
|
|
+ /* =====================================================
|
|
|
|
|
+ * KEEP SOCKET OPEN AND WAIT FOR SIP REQUESTS
|
|
|
|
|
+ * ===================================================== */
|
|
|
|
|
+
|
|
|
|
|
+ ESP_LOGI(TAG, "Waiting for incoming SIP requests...");
|
|
|
|
|
+
|
|
|
|
|
+ while (1) {
|
|
|
|
|
|
|
|
- if (strstr(final_resp, "200 OK")) {
|
|
|
|
|
- ESP_LOGI(TAG, "🎉 SIP REGISTER SUCCESS");
|
|
|
|
|
- } else {
|
|
|
|
|
- ESP_LOGW(TAG, "REGISTER FAILED");
|
|
|
|
|
|
|
+ char rx_buf[2048];
|
|
|
|
|
+
|
|
|
|
|
+ int rx_len = recvfrom(sock,
|
|
|
|
|
+ rx_buf,
|
|
|
|
|
+ sizeof(rx_buf) - 1,
|
|
|
|
|
+ 0,
|
|
|
|
|
+ (struct sockaddr *)&server,
|
|
|
|
|
+ &addr_len);
|
|
|
|
|
+
|
|
|
|
|
+ if (rx_len <= 0) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ rx_buf[rx_len] = '\0';
|
|
|
|
|
+
|
|
|
|
|
+ printf("\n========================================\n");
|
|
|
|
|
+ printf("SIP MESSAGE RECEIVED:\n");
|
|
|
|
|
+ printf("%s\n", rx_buf);
|
|
|
|
|
+ printf("========================================\n");
|
|
|
|
|
+
|
|
|
|
|
+ if (strstr(rx_buf, "INVITE")) {
|
|
|
|
|
+
|
|
|
|
|
+ ESP_LOGI(TAG, "📞 Incoming INVITE");
|
|
|
|
|
+
|
|
|
|
|
+ /* ================= EXTRACT SIP HEADERS ================= */
|
|
|
|
|
+
|
|
|
|
|
+ char via[512] = {0};
|
|
|
|
|
+ char from[256] = {0};
|
|
|
|
|
+ char to[256] = {0};
|
|
|
|
|
+ char callid[256] = {0};
|
|
|
|
|
+ char cseq[128] = {0};
|
|
|
|
|
+
|
|
|
|
|
+ sscanf(strstr(rx_buf, "Via:"),
|
|
|
|
|
+ "Via: %[^\r\n]",
|
|
|
|
|
+ via);
|
|
|
|
|
+
|
|
|
|
|
+ sscanf(strstr(rx_buf, "From:"),
|
|
|
|
|
+ "From: %[^\r\n]",
|
|
|
|
|
+ from);
|
|
|
|
|
+
|
|
|
|
|
+ sscanf(strstr(rx_buf, "To:"),
|
|
|
|
|
+ "To: %[^\r\n]",
|
|
|
|
|
+ to);
|
|
|
|
|
+
|
|
|
|
|
+ sscanf(strstr(rx_buf, "Call-ID:"),
|
|
|
|
|
+ "Call-ID: %[^\r\n]",
|
|
|
|
|
+ callid);
|
|
|
|
|
+
|
|
|
|
|
+ sscanf(strstr(rx_buf, "CSeq:"),
|
|
|
|
|
+ "CSeq: %[^\r\n]",
|
|
|
|
|
+ cseq);
|
|
|
|
|
+
|
|
|
|
|
+ /* ================= SEND 100 TRYING ================= */
|
|
|
|
|
+
|
|
|
|
|
+ char trying[4096];
|
|
|
|
|
+
|
|
|
|
|
+ snprintf(trying, sizeof(trying),
|
|
|
|
|
+ "SIP/2.0 100 Trying\r\n"
|
|
|
|
|
+ "Via: %s\r\n"
|
|
|
|
|
+ "From: %s\r\n"
|
|
|
|
|
+ "To: %s\r\n"
|
|
|
|
|
+ "Call-ID: %s\r\n"
|
|
|
|
|
+ "CSeq: %s\r\n"
|
|
|
|
|
+ "Content-Length: 0\r\n"
|
|
|
|
|
+ "\r\n",
|
|
|
|
|
+ via,
|
|
|
|
|
+ from,
|
|
|
|
|
+ to,
|
|
|
|
|
+ callid,
|
|
|
|
|
+ cseq);
|
|
|
|
|
+
|
|
|
|
|
+ sendto(sock,
|
|
|
|
|
+ trying,
|
|
|
|
|
+ strlen(trying),
|
|
|
|
|
+ 0,
|
|
|
|
|
+ (struct sockaddr *)&server,
|
|
|
|
|
+ sizeof(server));
|
|
|
|
|
+
|
|
|
|
|
+ ESP_LOGI(TAG, "100 Trying sent");
|
|
|
|
|
+
|
|
|
|
|
+ char ringing[2048];
|
|
|
|
|
+
|
|
|
|
|
+snprintf(ringing, sizeof(ringing),
|
|
|
|
|
+ "SIP/2.0 180 Ringing\r\n"
|
|
|
|
|
+ "Via: %s\r\n"
|
|
|
|
|
+ "From: %s\r\n"
|
|
|
|
|
+ "To: %s\r\n"
|
|
|
|
|
+ "Call-ID: %s\r\n"
|
|
|
|
|
+ "CSeq: %s\r\n"
|
|
|
|
|
+ "Contact: <sip:1001@10.0.0.15:5062>\r\n"
|
|
|
|
|
+ "Content-Length: 0\r\n"
|
|
|
|
|
+ "\r\n",
|
|
|
|
|
+ via,
|
|
|
|
|
+ from,
|
|
|
|
|
+ to,
|
|
|
|
|
+ callid,
|
|
|
|
|
+ cseq);
|
|
|
|
|
+
|
|
|
|
|
+sendto(sock,
|
|
|
|
|
+ ringing,
|
|
|
|
|
+ strlen(ringing),
|
|
|
|
|
+ 0,
|
|
|
|
|
+ (struct sockaddr *)&server,
|
|
|
|
|
+ sizeof(server));
|
|
|
|
|
+
|
|
|
|
|
+ESP_LOGI(TAG, "180 Ringing sent");
|
|
|
|
|
+
|
|
|
|
|
+char ok[2048];
|
|
|
|
|
+
|
|
|
|
|
+const char *sdp =
|
|
|
|
|
+"v=0\r\n"
|
|
|
|
|
+"o=ESP32 1234 1234 IN IP4 " ESP32_IP "\r\n"
|
|
|
|
|
+"s=ESP32 SIP Call\r\n"
|
|
|
|
|
+"c=IN IP4 " ESP32_IP "\r\n"
|
|
|
|
|
+"t=0 0\r\n"
|
|
|
|
|
+"m=audio 4000 RTP/AVP 0 101\r\n"
|
|
|
|
|
+"a=rtpmap:0 PCMU/8000\r\n"
|
|
|
|
|
+"a=rtpmap:101 telephone-event/8000\r\n"
|
|
|
|
|
+"a=fmtp:101 0-16\r\n"
|
|
|
|
|
+"a=ptime:20\r\n"
|
|
|
|
|
+"a=sendrecv\r\n";
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+snprintf(ok, sizeof(ok),
|
|
|
|
|
+ "SIP/2.0 200 OK\r\n"
|
|
|
|
|
+ "Via: %s\r\n"
|
|
|
|
|
+ "From: %s\r\n"
|
|
|
|
|
+ "To: %s;tag=esp32\r\n"
|
|
|
|
|
+ "Call-ID: %s\r\n"
|
|
|
|
|
+ "CSeq: %s\r\n"
|
|
|
|
|
+ "Contact: <sip:1001@" ESP32_IP ":5062>\r\n"
|
|
|
|
|
+ "Content-Type: application/sdp\r\n"
|
|
|
|
|
+ "Content-Length: %d\r\n"
|
|
|
|
|
+ "\r\n"
|
|
|
|
|
+ "%s",
|
|
|
|
|
+ via,
|
|
|
|
|
+ from,
|
|
|
|
|
+ to,
|
|
|
|
|
+ callid,
|
|
|
|
|
+ cseq,
|
|
|
|
|
+ strlen(sdp),
|
|
|
|
|
+ sdp);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+sendto(sock,
|
|
|
|
|
+ ok,
|
|
|
|
|
+ strlen(ok),
|
|
|
|
|
+ 0,
|
|
|
|
|
+ (struct sockaddr *)&server,
|
|
|
|
|
+ sizeof(server));
|
|
|
|
|
+
|
|
|
|
|
+ESP_LOGI(TAG, "200 OK sent");
|
|
|
|
|
+}
|
|
|
|
|
+ else if (strstr(rx_buf, "OPTIONS")) {
|
|
|
|
|
+
|
|
|
|
|
+ ESP_LOGI(TAG, "Received OPTIONS");
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (strstr(rx_buf, "ACK")) {
|
|
|
|
|
+
|
|
|
|
|
+ ESP_LOGI(TAG, "Received ACK");
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (strstr(rx_buf, "BYE")) {
|
|
|
|
|
+
|
|
|
|
|
+ ESP_LOGI(TAG, "Received BYE");
|
|
|
|
|
+ }
|
|
|
|
|
+ else {
|
|
|
|
|
+
|
|
|
|
|
+ ESP_LOGI(TAG, "Unknown SIP message");
|
|
|
}
|
|
}
|
|
|
- } else {
|
|
|
|
|
- ESP_LOGW(TAG, "No final response");
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
close(sock);
|
|
close(sock);
|
|
@@ -337,7 +542,7 @@ void app_main(void)
|
|
|
|
|
|
|
|
xTaskCreate(sip_register_task,
|
|
xTaskCreate(sip_register_task,
|
|
|
"sip_register",
|
|
"sip_register",
|
|
|
- 12288,
|
|
|
|
|
|
|
+ 20480,
|
|
|
NULL,
|
|
NULL,
|
|
|
5,
|
|
5,
|
|
|
NULL);
|
|
NULL);
|