I have an Asterisk server on cloud and I want ESP32 devices to register as SIP clients and make a VoIP call over GPRS via SIM800 module. AT commands of SIM800 module allows me to make a GPRS connection and I can send http request and send MQTT messages. However, I couldn't find a way to connect to VoIP server, if possible.
My current code establises MQTT connection over GPRS and make calls over GSM but cannot connect to Asterisk:
// ESP32 Configuration
#define TINY_GSM_MODEM_SIM800
#define SerialMon Serial
#define SerialAT Serial2
#define TINY_GSM_DEBUG SerialMon
#define GSM_AUTOBAUD_MIN 9600 /
#define GSM_AUTOBAUD_MAX 38400
#define TINY_GSM_USE_GPRS true
#define PhoneNumber "xxxxxxxxxxxxxxx"
#define rcSwitchInterruptPin 35
#define ENABLE_SIM800C 22
#define BUTTON_PIN 33
#define SOS_BUTTON_ID0 4236140
#define SOS_BUTTON_ID1 4236132
#define SOS_BUTTON_PIN 27
// GPRS internet settings, specific to your SIM card
const char apn[] = "internet";
const char gprsUser[] = "";
const char gprsPass[] = "";
// MQTT settings
const char *broker = "broker.emqx.io";
const int mqttPort = 1883;
const char * clientID = "esp32-client";
const char * mqttUser = "acido";
const char * mqttPassword = "12345678";
#include <TinyGsmClient.h>
#include <PubSubClient.h>
#include <SPI.h>
#include <Wire.h>
#include <PubSubClient.h>
#include <elapsedMillis.h>
#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
TinyGsm modem(SerialAT);
TinyGsmClient client(modem);
PubSubClient mqtt(client);
uint32_t lastReconnectAttempt = 0;
void mqttCallback(char *, byte *, unsigned int);
boolean mqttConnect();
void DRE_switch();
elapsedSeconds serialLogSeconds;
unsigned int serialLog_Interval = 3;
elapsedSeconds sinyalBekletme;
unsigned int sinyalBekletme_Interval = 3;
elapsedSeconds sosDelay;
unsigned int sosDelay_Interval = 3;
elapsedSeconds kapiacikDelay;
unsigned int kapiacikDelay_Interval = 3;
elapsedSeconds kapiKapaliDelay;
unsigned int kapiKapaliDelay_Interval = 3;
elapsedSeconds gazDelay;
unsigned int gazDelay_Interval = 3;
elapsedSeconds pirDelay;
unsigned int pirDelay_Interval = 3;
elapsedSeconds dumanDelay;
unsigned int dumanDelay_Interval = 3;
void setup()
{
mqtt.setKeepAlive(60);
// Set console baud rate
SerialMon.begin(9600);
while (!SerialMon)
delay(10);
// !!!!!!!!!!!
mySwitch.enableReceive(35);
pinMode(BUTTON_PIN, INPUT_PULLDOWN);
pinMode(ENABLE_SIM800C, OUTPUT);
digitalWrite(ENABLE_SIM800C, HIGH);
delay(3000);
digitalWrite(ENABLE_SIM800C, LOW);
// !!!!!!!!!!!
TinyGsmAutoBaud(SerialAT, GSM_AUTOBAUD_MIN, GSM_AUTOBAUD_MAX);
delay(6000);
// Restart takes quite some time
// To skip it, call init() instead of restart()
// if (!modem.restart()) {
if (!modem.init()) {
DBG("Failed to restart modem, delaying 10s and retrying");
// restart autobaud in case GSM just rebooted
TinyGsmAutoBaud(SerialAT, GSM_AUTOBAUD_MIN, GSM_AUTOBAUD_MAX);
return;
}
String modemInfo = modem.getModemInfo();
SerialMon.print("setup: Modem Info: ");
SerialMon.println(modemInfo);
SerialMon.print("setup: Waiting for network...");
if (!modem.waitForNetwork())
{
SerialMon.println("setup: fail, wait 5 seconds");
delay(5000);
return;
}
SerialMon.println("setup: success");
if (modem.isNetworkConnected())
SerialMon.println("setup: Network connected");
#if TINY_GSM_USE_GPRS
// GPRS connection parameters are usually set after network registration
SerialMon.print(F("setup: Connecting to apn: "));
SerialMon.print(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass))
{
SerialMon.println("setup: GPRS Connecting fail, wait 5 seconds");
delay(5000);
return;
}
SerialMon.println("setup: GPRS success");
if (modem.isGprsConnected())
{
SerialMon.println("setup: GPRS connected");
}
#endif
// MQTT Broker setup
mqtt.setServer(broker, mqttPort);
mqtt.setCallback(mqttCallback);
}
void loop()
{
bool result;
// check if we're connected to network
if (!modem.isNetworkConnected())
{
SerialMon.println("loop: modem disconnected");
if (!modem.waitForNetwork(180000L, true))
{
SerialMon.println("loop: modem fail, wait 10 sec");
delay(10000);
return;
}
if (modem.isNetworkConnected())
{
SerialMon.println("loop: Modem re-connected");
}
// And make sure GPRS/EPS is still connected
if (!modem.isGprsConnected())
{
SerialMon.println("loop: GPRS disconnected!");
SerialMon.print(F("loop: Connecting to apn:"));
SerialMon.print(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass))
{
SerialMon.println("loop: GPRS fail, wait 10 sec");
delay(10000);
return;
}
if (modem.isGprsConnected())
{
SerialMon.println("loop: GPRS reconnected");
}
}
}
// check if we're connected to MQTT
if (!mqtt.connected())
{
SerialMon.println("loop: === mqtt not connected ===");
// Reconnect every 10 seconds
uint32_t t = millis();
if (t - lastReconnectAttempt > 10000L)
{
lastReconnectAttempt = t;
if (mqttConnect())
{
lastReconnectAttempt = 0;
}
}
return;
}
if (digitalRead(BUTTON_PIN) == HIGH)
{
Serial.println("BUTONA BASILDI");
result = modem.callNumber(PhoneNumber);
DBG("Call:", result ? "OK" : "fail");
}
// Check RF signals and publish to MQTT
if (mySwitch.available())
{
int num = mySwitch.getReceivedValue();
Serial.print("Num: ");
Serial.print(num);
Serial.print(" Protocol: ");
Serial.println(mySwitch.getReceivedProtocol());
if (sosDelay >= sosDelay_Interval)
{
if (num == 4236132) // SOS
{
Serial.println("SOS Butonuna Basıldı.");
DRE_switch();
mqtt.publish("CMR/ESP32s/SENSOR/SOS", "SOS"); // Publish message.
result = modem.callNumber(PhoneNumber);
DBG("Call:", result ? "OK" : "fail");
}
else
{
mqtt.publish("CMR/ESP32s/SENSOR/SOS", "0"); // Publish message.
}
sosDelay = 0;
}
if (pirDelay >= pirDelay_Interval)
{
if (num == 8330345)
{
DRE_switch();
Serial.println("HAREKET ALGILANDI.");
mqtt.publish("CMR/ESP32s/SENSOR/PIR", "HAREKET ALGILANDI"); // Publish message.
}
else
{
mqtt.publish("CMR/ESP32s/SENSOR/PIR", "0"); // Publish message
}
pirDelay = 0;
}
if (kapiacikDelay >= kapiacikDelay_Interval)
{
if (num == 5729285) // Kapi acilinca gelen sinyal
{
DRE_switch();
Serial.println("KAPI AÇILDI.");
mqtt.publish("CMR/ESP32s/SENSOR/KAPIACIK", "1"); // Publish message.
}
else
{
mqtt.publish("CMR/ESP32s/SENSOR/KAPIACIK", "0"); // Publish message
}
kapiacikDelay = 0;
}
if (kapiKapaliDelay >= kapiKapaliDelay_Interval)
{
if (num == 5729294) // Kapi kapaninca gelen sinyal
{
DRE_switch();
Serial.println("KAPI KAPANDI.");
mqtt.publish("CMR/ESP32s/SENSOR/KAPIKAPALI", "1"); // Publish message.
}
else
{
mqtt.publish("CMR/ESP32s/SENSOR/KAPIKAPALI", "0"); // Publish message
}
kapiKapaliDelay = 0;
}
if (gazDelay >= gazDelay_Interval)
{
if (num == 12607491)
{
DRE_switch();
Serial.println("Gas Algılandı.");
mqtt.publish("CMR/ESP32s/SENSOR/GAS", "GAS ALGILANDI"); // Publish message.
}
else
{
mqtt.publish("CMR/ESP32s/SENSOR/GAS", "0"); // Publish message
}
gazDelay = 0;
}
if (dumanDelay >= dumanDelay_Interval)
{
if (num == 79974)
{
DRE_switch();
Serial.println("Duman Algılandı .");
mqtt.publish("CMR/ESP32s/SENSOR/DUMAN", "DUMAN ALGILANDI"); // Publish message.
}
else
{
mqtt.publish("CMR/ESP32s/SENSOR/DUMAN", "0"); // Publish message
}
dumanDelay = 0;
}
} // end if mySwitch.available
modem.maintain();
mqtt.loop(); // Handling MQTT on the background.
} // end of loop
boolean mqttConnect()
{
// Connect to MQTT Broker
SerialMon.print("mqttConnect: MQTT trying to connect: ");
SerialMon.print(broker);
// Connect to MQTT Broker with password protected
boolean status = mqtt.connect(clientID, mqttUser, mqttPassword);
// boolean status = mqtt.connect(clientID); // without password
if (status == false)
{
SerialMon.println("mqttConnect: MQTT Connection Fail");
return false;
}
SerialMon.println("mqttConnect: *** MQTT CONNECTED *** ");
mqtt.publish("topic/akes", "Client connection started");
mqtt.subscribe("topic/akes"); // subscribe to topic
return mqtt.connected();
}
void mqttCallback(char *topic, byte *payload, unsigned int len)
{
// Handle message arrived
SerialMon.print("mqttCallback: Message arrived [");
SerialMon.print(topic);
SerialMon.print("]: ");
SerialMon.write(payload, len);
SerialMon.println();
}
void DRE_switch()
{
// Disable Reset Enable function for RF module
mySwitch.disableReceive();
mySwitch.resetAvailable();
mySwitch.enableReceive(rcSwitchInterruptPin);
}