1509 lines
44 KiB
C
1509 lines
44 KiB
C
#ifndef EC200U_H
|
|
#define EC200U_H
|
|
|
|
#include <Arduino.h>
|
|
#include "Config.h"
|
|
#include "Memory.h"
|
|
|
|
// -------------------- متغیرهای خارجی --------------------
|
|
extern HardwareSerial EC200U;
|
|
extern DeviceConfig config;
|
|
extern SensorData currentData;
|
|
extern bool networkConnected;
|
|
extern bool simConnected;
|
|
extern bool networkRegistered;
|
|
extern int signalStrength;
|
|
extern String lastMessage;
|
|
extern String currentAPN;
|
|
extern String tempPhoneNumber;
|
|
extern String tempTokenCode;
|
|
extern bool awaitingSMS2;
|
|
extern bool isInCall;
|
|
//extern bool calibrationComplete;
|
|
extern unsigned long lastUpload;
|
|
|
|
// Forward declarations
|
|
void initEC200U();
|
|
void updateNetworkStatus();
|
|
|
|
// -------------------- توابع کمکی جدید --------------------
|
|
bool checkAudioPlaybackStatus() {
|
|
Serial1.println("Checking audio playback status...");
|
|
EC200U.println("AT+QVTSTAT?");
|
|
|
|
String response = "";
|
|
unsigned long start = millis();
|
|
while (millis() - start < 2000) {
|
|
while (EC200U.available()) {
|
|
char c = EC200U.read();
|
|
response += c;
|
|
Serial1.write(c);
|
|
}
|
|
}
|
|
|
|
if (response.indexOf("+QVTSTAT: 0,0") != -1) {
|
|
return true; // پخش تمام شده
|
|
} else if (response.indexOf("+QVTSTAT: 0,1") != -1) {
|
|
Serial1.println("Audio is playing");
|
|
return false; // در حال پخش است
|
|
} else {
|
|
Serial1.println("Unknown playback status");
|
|
return false;
|
|
}
|
|
}
|
|
inline bool sendAT(String cmd, uint16_t wait = 2000, bool showResponse = false) {
|
|
if (showResponse) {
|
|
Serial1.print(">> ");
|
|
Serial1.println(cmd);
|
|
}
|
|
EC200U.println(cmd);
|
|
|
|
String response = "";
|
|
unsigned long start = millis();
|
|
|
|
while (millis() - start < wait) {
|
|
while (EC200U.available()) {
|
|
char c = EC200U.read();
|
|
response += c;
|
|
if (showResponse) Serial1.write(c);
|
|
}
|
|
if (response.indexOf("OK") != -1) return true;
|
|
if (response.indexOf("ERROR") != -1) return false;
|
|
}
|
|
return false;
|
|
}
|
|
inline String stringSendAT(String cmd, uint16_t wait = 2000, bool showResponse = false) {
|
|
if (showResponse) {
|
|
Serial1.print(">> ");
|
|
Serial1.println(cmd);
|
|
}
|
|
EC200U.println(cmd);
|
|
|
|
String response = "";
|
|
unsigned long start = millis();
|
|
|
|
while (millis() - start < wait) {
|
|
while (EC200U.available()) {
|
|
char c = EC200U.read();
|
|
response += c;
|
|
if (showResponse) Serial1.write(c);
|
|
}
|
|
|
|
// اگر پاسخ کامل دریافت شده (دارای OK یا ERROR) خاتمه بده
|
|
if (response.indexOf("OK") != -1 ||
|
|
response.indexOf("ERROR") != -1 ||
|
|
response.indexOf("NO CARRIER") != -1 ||
|
|
response.indexOf("CONNECT") != -1) {
|
|
break;
|
|
}
|
|
}
|
|
return response;
|
|
}
|
|
// void initAudioSettings() {
|
|
// Serial1.println("Initializing audio settings...");
|
|
|
|
// // ریست تنظیمات صدا
|
|
// sendAT("AT+CRESET", 3000, true);
|
|
// delay(2000);
|
|
|
|
// // تنظیمات اولیه
|
|
// sendAT("AT+CLVL=5", 2000, true); // سطح صدا متوسط
|
|
// sendAT("AT+CMUT=0", 2000, true); // غیرفعال کردن mute
|
|
// sendAT("AT+QDAI=5", 2000, true); // تنظیم رابط صوتی
|
|
// sendAT("AT+VTD=1", 2000, true); // تنظیم تون DTMF
|
|
|
|
// // تنظیمات کدک صوتی
|
|
// sendAT("AT+QMBNCFG=\"select\",0", 2000, true);
|
|
// sendAT("AT+QCODECCFG=0,2,1", 2000, true); // AMR-NB, 12.2kbps
|
|
|
|
// Serial1.println("✅ Audio settings initialized");
|
|
// }
|
|
|
|
|
|
bool sendSMS(String numbers, String messages) {
|
|
Serial1.println("\n📱 SENDING SMS - FINAL OPTIMIZED VERSION");
|
|
|
|
// تقسیم شمارهها
|
|
int phoneCount = 0;
|
|
String phoneNumbers[10];
|
|
String numbersCopy = numbers;
|
|
|
|
numbersCopy.replace(" ", "");
|
|
|
|
int startIdx = 0;
|
|
int commaIdx = numbersCopy.indexOf(',');
|
|
|
|
while (commaIdx != -1 && phoneCount < 9) {
|
|
phoneNumbers[phoneCount] = numbersCopy.substring(startIdx, commaIdx);
|
|
phoneCount++;
|
|
startIdx = commaIdx + 1;
|
|
commaIdx = numbersCopy.indexOf(',', startIdx);
|
|
}
|
|
|
|
if (startIdx < numbersCopy.length()) {
|
|
phoneNumbers[phoneCount] = numbersCopy.substring(startIdx);
|
|
phoneCount++;
|
|
}
|
|
|
|
if (phoneCount == 0) {
|
|
Serial1.println("❌ No phone numbers");
|
|
return false;
|
|
}
|
|
|
|
// تقسیم پیامها
|
|
int messageCount = 0;
|
|
String messageTexts[10];
|
|
String messagesCopy = messages;
|
|
|
|
startIdx = 0;
|
|
int atIdx = messagesCopy.indexOf('@');
|
|
|
|
while (atIdx != -1 && messageCount < 9) {
|
|
messageTexts[messageCount] = messagesCopy.substring(startIdx, atIdx);
|
|
messageCount++;
|
|
startIdx = atIdx + 1;
|
|
atIdx = messagesCopy.indexOf('@', startIdx);
|
|
}
|
|
|
|
if (startIdx < messagesCopy.length()) {
|
|
messageTexts[messageCount] = messagesCopy.substring(startIdx);
|
|
messageCount++;
|
|
}
|
|
|
|
if (messageCount == 0) {
|
|
Serial1.println("❌ No messages");
|
|
return false;
|
|
}
|
|
|
|
bool allSent = true;
|
|
int totalMessagesSent = 0;
|
|
|
|
// تنظیمات اولیه ماژول (یک بار انجام میشود)
|
|
Serial1.println("📋 Initializing module...");
|
|
while (EC200U.available()) EC200U.read(); // پاکسازی بافر
|
|
|
|
EC200U.println("AT+CMGF=1");
|
|
delay(50);
|
|
EC200U.println("AT+CSMP=17,167,0,8");
|
|
delay(50);
|
|
EC200U.println("AT+CSCS=\"UTF-8\"");
|
|
delay(50);
|
|
|
|
while (EC200U.available()) EC200U.read(); // پاکسازی مجدد
|
|
|
|
// ارسال به همه شمارهها
|
|
for (int i = 0; i < phoneCount; i++) {
|
|
String phone = phoneNumbers[i];
|
|
if (phone.length() < 10) {
|
|
Serial1.print("❌ Invalid number: ");
|
|
Serial1.println(phone);
|
|
allSent = false;
|
|
continue;
|
|
}
|
|
|
|
// انتخاب پیام
|
|
String message;
|
|
if (messageCount == 1) {
|
|
message = messageTexts[0];
|
|
} else if (i < messageCount) {
|
|
message = messageTexts[i];
|
|
} else {
|
|
message = messageTexts[messageCount - 1];
|
|
}
|
|
|
|
if (message.length() == 0) {
|
|
Serial1.print("❌ Empty message for: ");
|
|
Serial1.println(phone);
|
|
allSent = false;
|
|
continue;
|
|
}
|
|
|
|
Serial1.print("📤 To: ");
|
|
Serial1.print(phone);
|
|
Serial1.print(" | Msg: ");
|
|
if (message.length() > 30) {
|
|
Serial1.print(message.substring(0, 30));
|
|
Serial1.print("...");
|
|
} else {
|
|
Serial1.print(message);
|
|
}
|
|
Serial1.println();
|
|
|
|
// پاکسازی بافر قبل از ارسال
|
|
while (EC200U.available()) EC200U.read();
|
|
|
|
// ارسال دستور CMGS
|
|
EC200U.print("AT+CMGS=\"");
|
|
EC200U.print(phone);
|
|
EC200U.println("\"");
|
|
|
|
// منتظر prompt >
|
|
int timeout = 0;
|
|
bool gotPrompt = false;
|
|
while (timeout < 100) {
|
|
if (EC200U.available() && EC200U.read() == '>') {
|
|
gotPrompt = true;
|
|
break;
|
|
}
|
|
delay(50);
|
|
timeout++;
|
|
}
|
|
|
|
if (!gotPrompt) {
|
|
Serial1.println("❌ No prompt received");
|
|
allSent = false;
|
|
continue;
|
|
}
|
|
|
|
// ارسال متن (بدون خط جدید)
|
|
for (int j = 0; j < message.length(); j++) {
|
|
EC200U.write(message.charAt(j));
|
|
}
|
|
|
|
// ارسال Ctrl+Z
|
|
EC200U.write(26);
|
|
|
|
// بررسی نتیجه
|
|
timeout = 0;
|
|
bool sent = false;
|
|
String response = "";
|
|
while (timeout < 80) { // 8 ثانیه (80 * 100ms)
|
|
while (EC200U.available()) {
|
|
char c = EC200U.read();
|
|
response += c;
|
|
if (response.indexOf("+CMGS:") != -1 || response.indexOf("OK") != -1) {
|
|
sent = true;
|
|
break;
|
|
}
|
|
if (response.indexOf("ERROR") != -1 || response.indexOf("CMS ERROR") != -1) {
|
|
sent = false;
|
|
break;
|
|
}
|
|
}
|
|
if (sent || response.indexOf("ERROR") != -1) break;
|
|
delay(100);
|
|
timeout++;
|
|
}
|
|
|
|
if (sent || response.indexOf("ERROR") == -1) { // اگر خطایی نیامد، موفق فرض کن
|
|
totalMessagesSent++;
|
|
Serial1.println("✅ Sent successfully");
|
|
} else {
|
|
Serial1.println("❌ Failed");
|
|
allSent = false;
|
|
}
|
|
|
|
if (sent) {
|
|
Serial1.println("✅ Sent successfully");
|
|
} else {
|
|
Serial1.println("❌ Failed");
|
|
allSent = false;
|
|
}
|
|
|
|
// تاخیر بین ارسالها
|
|
if (i < phoneCount - 1) {
|
|
Serial1.println("⏳ Waiting 2 seconds...");
|
|
delay(2000);
|
|
}
|
|
}
|
|
|
|
Serial1.print("\n📊 Result: ");
|
|
Serial1.print(totalMessagesSent);
|
|
Serial1.print("/");
|
|
Serial1.print(phoneCount);
|
|
Serial1.println(" messages sent");
|
|
|
|
return (totalMessagesSent > 0);
|
|
}
|
|
// {
|
|
// Serial1.println("\n📱 ارسال __ پیامک");
|
|
// Serial1.println("==============");
|
|
|
|
// // 1. تنظیم Text Mode
|
|
// if (!sendAT("AT+CMGF=1")) {
|
|
// Serial1.println("❌ خطا: Text Mode تنظیم نشد");
|
|
// return false;
|
|
// }
|
|
|
|
// // 2. تنظیم charset به UTF-8
|
|
// if (!sendAT("AT+CSCS=\"UTF-8\"")) {
|
|
// Serial1.println("❌ خطا: UTF-8 پشتیبانی نمیشود");
|
|
// return false;
|
|
// }
|
|
|
|
// // 3. تنظیم پارامترهای SMS (اختیاری)
|
|
// sendAT("AT+CSMP=1,167,0,8");
|
|
|
|
// // 4. ارسال دستور CMGS
|
|
// String cmd = "AT+CMGS=\"" + phoneNumber + "\"";
|
|
// EC200U.println(cmd);
|
|
|
|
// // منتظر prompt >
|
|
// delay(100);
|
|
// unsigned long startTime = millis();
|
|
// bool gotPrompt = false;
|
|
|
|
// while (millis() - startTime < 5000) {
|
|
// while (EC200U.available()) {
|
|
// if (EC200U.read() == '>') {
|
|
// gotPrompt = true;
|
|
// break;
|
|
// }
|
|
// }
|
|
// if (gotPrompt) break;
|
|
// }
|
|
|
|
// if (!gotPrompt) {
|
|
// Serial1.println("❌ خطا: Prompt دریافت نشد");
|
|
// return false;
|
|
// }
|
|
|
|
// // 5. ارسال متن UTF-8
|
|
// EC200U.println(message);
|
|
// delay(100);
|
|
|
|
// // 6. ارسال Ctrl+Z
|
|
// EC200U.write(26);
|
|
|
|
// // 7. دریافت پاسخ
|
|
// startTime = millis();
|
|
// String response = "";
|
|
// bool success = false;
|
|
|
|
// while (millis() - startTime < 15000) {
|
|
// while (EC200U.available()) {
|
|
// char c = EC200U.read();
|
|
// response += c;
|
|
|
|
// if (response.indexOf("+CMGS:") != -1) success = true;
|
|
// if (response.indexOf("+CMS ERROR") != -1) return false;
|
|
// }
|
|
|
|
// if (response.indexOf("OK") != -1) break;
|
|
// if (response.indexOf("ERROR") != -1) break;
|
|
// }
|
|
|
|
// if (success) {
|
|
// Serial1.println("✅ پیامک ارسال شد");
|
|
// return true;
|
|
// } else {
|
|
// Serial1.println("❌ ارسال ناموفق");
|
|
// return false;
|
|
// }
|
|
// }
|
|
|
|
// -------------------- پردازش SMS --------------------
|
|
inline void extractNumbersFromSMS2(String message, String numbers[], int &count) {
|
|
count = 0;
|
|
String current = "";
|
|
|
|
for (int i = 0; i < message.length(); i++) {
|
|
char c = message.charAt(i);
|
|
if (c >= '0' && c <= '9') {
|
|
current += c;
|
|
} else {
|
|
if (current.length() > 0) {
|
|
if (count < 10) {
|
|
numbers[count] = current;
|
|
count++;
|
|
}
|
|
current = "";
|
|
}
|
|
}
|
|
}
|
|
|
|
if (current.length() > 0 && count < 10) {
|
|
numbers[count] = current;
|
|
count++;
|
|
}
|
|
}
|
|
|
|
inline void updateNetworkStatus() {
|
|
if (!config.verified) {
|
|
simConnected = false;
|
|
networkRegistered = false;
|
|
signalStrength = 0;
|
|
return;
|
|
}
|
|
|
|
simConnected = sendAT("AT", 1000, false);
|
|
|
|
EC200U.println("AT+CSQ");
|
|
String response = "";
|
|
unsigned long start = millis();
|
|
while (millis() - start < 2000) {
|
|
while (EC200U.available()) {
|
|
char c = EC200U.read();
|
|
response += c;
|
|
}
|
|
if (response.indexOf("OK") != -1 || response.indexOf("ERROR") != -1) break;
|
|
}
|
|
|
|
if (response.indexOf("+CSQ:") != -1) {
|
|
int idx = response.indexOf("+CSQ:");
|
|
int comma = response.indexOf(',', idx);
|
|
if (comma != -1) {
|
|
String rssiStr = response.substring(idx + 6, comma);
|
|
rssiStr.trim();
|
|
signalStrength = rssiStr.toInt();
|
|
if (signalStrength > 31) signalStrength = 0;
|
|
}
|
|
}
|
|
|
|
EC200U.println("AT+CREG?");
|
|
response = "";
|
|
start = millis();
|
|
while (millis() - start < 2000) {
|
|
while (EC200U.available()) {
|
|
char c = EC200U.read();
|
|
response += c;
|
|
}
|
|
if (response.indexOf("OK") != -1 || response.indexOf("ERROR") != -1) break;
|
|
}
|
|
|
|
networkRegistered = (response.indexOf("+CREG:") != -1 &&
|
|
(response.indexOf(",1,") != -1 || response.indexOf(",5,") != -1));
|
|
}
|
|
|
|
inline int detectSMSType(String message) {
|
|
int count = 0;
|
|
String current = "";
|
|
|
|
for (int i = 0; i < message.length(); i++) {
|
|
char c = message.charAt(i);
|
|
if (c >= '0' && c <= '9') {
|
|
current += c;
|
|
} else {
|
|
if (current.length() > 0) {
|
|
count++;
|
|
current = "";
|
|
}
|
|
}
|
|
}
|
|
if (current.length() > 0) {
|
|
count++;
|
|
}
|
|
|
|
return (count >= 5) ? 2 : 1;
|
|
}
|
|
|
|
inline void connectToNetwork() {
|
|
Serial1.println("\n======== NETWORK CONNECTION ========");
|
|
lastMessage = "Connecting";
|
|
|
|
if (!config.verified) {
|
|
Serial1.println("❌ Cannot connect: Device not configured");
|
|
return;
|
|
}
|
|
|
|
currentAPN = simTypeToAPN(config.simType);
|
|
Serial1.print("Setting APN: ");
|
|
Serial1.println(currentAPN);
|
|
String apnCmd = "AT+CGDCONT=1,\"IP\",\"" + currentAPN + "\"";
|
|
sendAT(apnCmd, 2000, false);
|
|
|
|
Serial1.println("Waiting for network registration...");
|
|
bool registered = false;
|
|
for (int attempt = 1; attempt <= 30; attempt++) {
|
|
EC200U.println("AT+CREG?");
|
|
String response = "";
|
|
unsigned long start = millis();
|
|
while (millis() - start < 2000) {
|
|
while (EC200U.available()) {
|
|
char c = EC200U.read();
|
|
response += c;
|
|
}
|
|
if (response.indexOf("OK") != -1) break;
|
|
}
|
|
|
|
if (response.indexOf(",1") != -1 || response.indexOf(",5") != -1) {
|
|
registered = true;
|
|
Serial1.print("✅ Network registered after ");
|
|
Serial1.print(attempt);
|
|
Serial1.println(" seconds");
|
|
break;
|
|
}
|
|
|
|
Serial1.print(" Attempt ");
|
|
Serial1.print(attempt);
|
|
Serial1.println("/30 - Searching...");
|
|
delay(1000);
|
|
}
|
|
|
|
if (!registered) {
|
|
Serial1.println("⚠️ Network registration timeout - continuing anyway");
|
|
}
|
|
|
|
Serial1.println("Deactivating old PDP context...");
|
|
sendAT("AT+QIDEACT=1", 5000, false);
|
|
delay(1000);
|
|
|
|
Serial1.println("Activating PDP context...");
|
|
if (sendAT("AT+QIACT=1", 30000, false)) {
|
|
networkConnected = true;
|
|
lastMessage = "Online";
|
|
Serial1.println("✅ Internet connection established!");
|
|
} else {
|
|
Serial1.println("First attempt failed, retrying...");
|
|
delay(2000);
|
|
if (sendAT("AT+QIACT=1", 30000, false)) {
|
|
networkConnected = true;
|
|
lastMessage = "Online";
|
|
Serial1.println("✅ Internet connection established on retry!");
|
|
} else {
|
|
networkConnected = false;
|
|
lastMessage = "Offline";
|
|
Serial1.println("❌ Failed to connect to internet");
|
|
}
|
|
}
|
|
|
|
if (networkConnected) {
|
|
Serial1.println("Configuring SSL for HTTPS...");
|
|
sendAT("AT+QSSLCFG=\"sslversion\",1,4", 2000, false);
|
|
sendAT("AT+QSSLCFG=\"ciphersuite\",1,0xFFFF", 2000, false);
|
|
sendAT("AT+QSSLCFG=\"seclevel\",1,0", 2000, false);
|
|
sendAT("AT+QHTTPCFG=\"sslctxid\",1", 2000, false);
|
|
Serial1.println("✅ SSL configured for HTTPS");
|
|
}
|
|
|
|
updateNetworkStatus();
|
|
|
|
Serial1.println("--- NETWORK STATUS ---");
|
|
Serial1.print(" SIM: ");
|
|
Serial1.println(simConnected ? "Connected" : "Not detected");
|
|
Serial1.print(" Network: ");
|
|
Serial1.println(networkRegistered ? "Registered" : "Searching");
|
|
Serial1.print(" Signal: ");
|
|
Serial1.print(signalStrength);
|
|
Serial1.println("/31");
|
|
Serial1.print(" Internet: ");
|
|
Serial1.println(networkConnected ? "Online" : "Offline");
|
|
Serial1.println("=================================\n");
|
|
}
|
|
|
|
inline void processSMS1(String message) {
|
|
Serial1.println("\n======== SMS1 RECEIVED ========");
|
|
Serial1.print("Raw Message: ");
|
|
Serial1.println(message);
|
|
|
|
String numbers[10];
|
|
int count = 0;
|
|
extractNumbersFromSMS2(message, numbers, count);
|
|
|
|
String phone = "";
|
|
String token = "";
|
|
|
|
if (count >= 2) {
|
|
phone = numbers[0];
|
|
token = numbers[1];
|
|
}
|
|
|
|
Serial1.print("Phone: ");
|
|
Serial1.println(phone);
|
|
Serial1.print("Token: ");
|
|
Serial1.println(token);
|
|
|
|
if (phone.length() >= 10 && token.length() == 5) {
|
|
tempPhoneNumber = phone;
|
|
tempTokenCode = token;
|
|
|
|
String verifyCode = generateVerificationCode(token);
|
|
String reply = "Code: " + verifyCode;
|
|
|
|
Serial1.print("Generated Verification Code: ");
|
|
Serial1.println(verifyCode);
|
|
Serial1.print("Sending SMS to: ");
|
|
Serial1.println(phone);
|
|
|
|
if (sendSMS(phone, reply)) {
|
|
Serial1.println("✅ SMS1: Verification code sent successfully!");
|
|
awaitingSMS2 = true;
|
|
lastMessage = "Wait SMS2";
|
|
} else {
|
|
Serial1.println("❌ SMS1: Failed to send verification code");
|
|
lastMessage = "SMS1 Failed";
|
|
}
|
|
} else {
|
|
Serial1.println("❌ SMS1: Invalid format - phone or token missing");
|
|
Serial1.print(" Phone length: ");
|
|
Serial1.print(phone.length());
|
|
Serial1.print(", Token length: ");
|
|
Serial1.println(token.length());
|
|
lastMessage = "Invalid SMS1";
|
|
}
|
|
Serial1.println("================================\n");
|
|
}
|
|
|
|
inline void processSMS2(String message) {
|
|
Serial1.println("\n======== SMS2 RECEIVED ========");
|
|
Serial1.print("Raw Message: ");
|
|
Serial1.println(message);
|
|
|
|
String numbers[10];
|
|
int count = 0;
|
|
extractNumbersFromSMS2(message, numbers, count);
|
|
|
|
Serial1.print("Numbers found: ");
|
|
Serial1.println(count);
|
|
for (int i = 0; i < count; i++) {
|
|
Serial1.print(" [");
|
|
Serial1.print(i);
|
|
Serial1.print("]: ");
|
|
Serial1.println(numbers[i]);
|
|
}
|
|
|
|
if (count >= 5) {
|
|
// 1. Device ID
|
|
String deviceId = numbers[0];
|
|
Serial1.print("Original Device ID: ");
|
|
Serial1.println(deviceId);
|
|
if (deviceId.length() > 2) {
|
|
deviceId = deviceId.substring(0, deviceId.length() - 2);
|
|
}
|
|
deviceId.toCharArray(config.deviceId, 16);
|
|
Serial1.print("Parsed Device ID: ");
|
|
Serial1.println(config.deviceId);
|
|
|
|
// 2. Upload Interval
|
|
if (numbers[1].length() > 1) {
|
|
config.uploadInterval = numbers[1].substring(1).toInt();
|
|
} else {
|
|
config.uploadInterval = numbers[1].toInt();
|
|
}
|
|
Serial1.print("Upload Interval: ");
|
|
Serial1.print(config.uploadInterval);
|
|
Serial1.println(" min");
|
|
|
|
// 3. SMS Settings
|
|
if (numbers[2].length() >= 2) {
|
|
config.smsEnabled = (numbers[2].charAt(0) == '1');
|
|
config.smsInterval = numbers[2].substring(1).toInt();
|
|
} else {
|
|
config.smsEnabled = false;
|
|
config.smsInterval = 0;
|
|
}
|
|
Serial1.print("SMS Enabled: ");
|
|
Serial1.println(config.smsEnabled ? "Yes" : "No");
|
|
Serial1.print("SMS Interval: ");
|
|
Serial1.print(config.smsInterval);
|
|
Serial1.println(" min");
|
|
|
|
// 4. SIM Type (index 4 if 6 numbers, else last)
|
|
int simIndex = (count >= 6) ? 4 : (count - 1);
|
|
String simValue = numbers[simIndex];
|
|
Serial1.print("SIM Value (raw): ");
|
|
Serial1.println(simValue);
|
|
|
|
if (simValue.length() >= 2) {
|
|
String simCode = simValue.substring(simValue.length() - 2);
|
|
if (simCode == "21") config.simType = SIM_HAMRAHE_AVAL;
|
|
else if (simCode == "22") config.simType = SIM_IRANCELL;
|
|
else if (simCode == "23") config.simType = SIM_RIGHTEL;
|
|
else if (simCode == "71") config.simType = SIM_HAMRAHE_AVAL;
|
|
else config.simType = SIM_UNKNOWN;
|
|
} else {
|
|
int simInt = simValue.toInt();
|
|
if (simInt == 21 || simInt == 71) config.simType = SIM_HAMRAHE_AVAL;
|
|
else if (simInt == 22) config.simType = SIM_IRANCELL;
|
|
else if (simInt == 23) config.simType = SIM_RIGHTEL;
|
|
else config.simType = SIM_UNKNOWN;
|
|
}
|
|
Serial1.print("SIM Type: ");
|
|
Serial1.println(simTypeToString(config.simType));
|
|
|
|
// 5. Phone number
|
|
if (tempPhoneNumber.length() > 0) {
|
|
tempPhoneNumber.toCharArray(config.serverPhoneNumber, 16);
|
|
} else {
|
|
strcpy(config.serverPhoneNumber, "");
|
|
}
|
|
Serial1.print("Server Phone: ");
|
|
Serial1.println(config.serverPhoneNumber);
|
|
|
|
// 6. Save and connect
|
|
config.verified = true;
|
|
saveConfig();
|
|
|
|
currentAPN = simTypeToAPN(config.simType);
|
|
awaitingSMS2 = false;
|
|
|
|
Serial1.println("\n✅ SMS2: Configuration Complete!");
|
|
Serial1.println("--- FINAL CONFIG ---");
|
|
Serial1.print(" Device ID: ");
|
|
Serial1.println(config.deviceId);
|
|
Serial1.print(" SIM Type: ");
|
|
Serial1.println(simTypeToString(config.simType));
|
|
Serial1.print(" APN: ");
|
|
Serial1.println(currentAPN);
|
|
Serial1.print(" Upload Int: ");
|
|
Serial1.print(config.uploadInterval);
|
|
Serial1.println(" min");
|
|
Serial1.print(" SMS Enabled: ");
|
|
Serial1.println(config.smsEnabled ? "Yes" : "No");
|
|
Serial1.print(" Server Phone: ");
|
|
Serial1.println(config.serverPhoneNumber);
|
|
Serial1.println("--------------------");
|
|
|
|
lastMessage = "Configured";
|
|
Serial1.println("Connecting to network...");
|
|
connectToNetwork();
|
|
} else {
|
|
Serial1.println("❌ SMS2: Invalid format - need at least 5 numbers");
|
|
Serial1.print(" Found only: ");
|
|
Serial1.println(count);
|
|
lastMessage = "Invalid SMS2";
|
|
}
|
|
Serial1.println("================================\n");
|
|
}
|
|
|
|
inline void checkSMS() {
|
|
if (!sendAT("AT", 2000, false)) return;
|
|
|
|
sendAT("AT+CMGF=1", 2000, false);
|
|
delay(100);
|
|
|
|
EC200U.println("AT+CMGL=\"REC UNREAD\"");
|
|
|
|
String response = "";
|
|
unsigned long start = millis();
|
|
while (millis() - start < 5000) {
|
|
while (EC200U.available()) {
|
|
char c = EC200U.read();
|
|
response += c;
|
|
}
|
|
if (response.indexOf("OK") != -1) break;
|
|
}
|
|
|
|
if (response.indexOf("+CMGL:") != -1) {
|
|
int msgIndex = response.indexOf("+CMGL:");
|
|
int comma1 = response.indexOf(',', msgIndex);
|
|
int comma2 = response.indexOf(',', comma1 + 1);
|
|
int quote1 = response.indexOf('\"', comma2 + 1);
|
|
int quote2 = response.indexOf('\"', quote1 + 1);
|
|
|
|
if (quote1 != -1 && quote2 != -1) {
|
|
int msgStart = response.indexOf('\n', quote2) + 1;
|
|
int msgEnd = response.indexOf('\n', msgStart);
|
|
if (msgEnd == -1) msgEnd = response.length();
|
|
|
|
String message = response.substring(msgStart, msgEnd);
|
|
message.trim();
|
|
|
|
Serial1.println("\n📱 SMS received");
|
|
|
|
int smsType = detectSMSType(message);
|
|
|
|
if (config.verified) {
|
|
Serial1.println("⚠️ Already configured - try SMS Proccess2");
|
|
lastMessage = "Already Configured - try sms process 2";
|
|
processSMS2(message);
|
|
} else if (smsType == 1 && !awaitingSMS2) {
|
|
processSMS1(message);
|
|
} else if (smsType == 2 && awaitingSMS2) {
|
|
processSMS2(message);
|
|
} else if (smsType == 2 && !awaitingSMS2 && !config.verified) {
|
|
// این حالت برای زمانی است که مستقیم SMS2 دریافت شود
|
|
processSMS2(message);
|
|
} else {
|
|
Serial1.println("❌ Invalid SMS or wrong state");
|
|
lastMessage = "Invalid SMS";
|
|
}
|
|
|
|
String indexStr = response.substring(msgIndex + 6, comma1);
|
|
indexStr.trim();
|
|
sendAT("AT+CMGD=" + indexStr, 2000, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
// -------------------- توابع مدیریت EC200U --------------------
|
|
inline void powerOffEC200U() {
|
|
Serial1.println("Powering off EC200U...");
|
|
|
|
sendAT("AT+QPOWD", 3000, true);
|
|
delay(3000);
|
|
|
|
digitalWrite(PWRKEY_PIN, HIGH);
|
|
delay(1500);
|
|
digitalWrite(PWRKEY_PIN, LOW);
|
|
|
|
Serial1.println("EC200U powered off");
|
|
networkConnected = false;
|
|
}
|
|
|
|
inline void initEC200U() {
|
|
Serial1.println("\n======== MODEM INITIALIZATION ========");
|
|
lastMessage = "Modem Initializing";
|
|
|
|
Serial1.println("Checking if modem is already running...");
|
|
bool modemAlreadyOn = sendAT("AT", 2000, false);
|
|
|
|
if (modemAlreadyOn) {
|
|
Serial1.println("✅ Modem is already ON");
|
|
lastMessage = "Modem Ready";
|
|
} else {
|
|
Serial1.println("Waiting for modem to boot (8s)...");
|
|
delay(8000);
|
|
|
|
if (!sendAT("AT", 5000, false)) {
|
|
Serial1.println("❌ Modem not responding!");
|
|
lastMessage = "Modem Err";
|
|
Serial1.println("=================================\n");
|
|
return;
|
|
}
|
|
Serial1.println("✅ Modem powered on successfully");
|
|
lastMessage = "Modem Ready";
|
|
}
|
|
|
|
digitalWrite(PWRKEY_PIN, LOW);
|
|
|
|
// تنظیمات اولیه
|
|
sendAT("AT+CMGF=1", 2000, false); // تنظیم فرمت SMS
|
|
sendAT("AT+CNMI=2,1,0,0,0", 2000, false); // اعلان SMS جدید
|
|
|
|
// تنظیمات صوتی
|
|
//initAudioSettings();
|
|
|
|
// فقط اگر config.verified بود به شبکه وصل شود
|
|
if (config.verified) {
|
|
Serial1.println("Device is configured, connecting to network...");
|
|
connectToNetwork();
|
|
} else {
|
|
Serial1.println("⏳ Device not configured. Waiting for configuration SMS...");
|
|
Serial1.println("📱 Send SMS1 format: PHONENUMBER TOKENCODE");
|
|
lastMessage = "Wait SMS1";
|
|
}
|
|
|
|
updateNetworkStatus();
|
|
Serial1.println("=================================\n");
|
|
}
|
|
|
|
// -------------------- توابع SSL و HTTP --------------------
|
|
inline void configureSSL() {
|
|
Serial1.println("Configuring SSL for HTTPS...");
|
|
|
|
sendAT("AT+QSSLCFG=\"sslversion\",1,4", 2000, false);
|
|
sendAT("AT+QSSLCFG=\"ciphersuite\",1,0xFFFF", 2000, false);
|
|
sendAT("AT+QSSLCFG=\"seclevel\",1,0", 2000, false);
|
|
sendAT("AT+QHTTPCFG=\"sslctxid\",1", 2000, false);
|
|
|
|
Serial1.println("✅ SSL configured");
|
|
}
|
|
|
|
inline String readHttpResponse() {
|
|
Serial1.println("Reading HTTP response body...");
|
|
|
|
while (EC200U.available()) {
|
|
EC200U.read();
|
|
}
|
|
|
|
EC200U.println("AT+QHTTPREAD=80");
|
|
|
|
char buffer[600];
|
|
int bufIndex = 0;
|
|
unsigned long start = millis();
|
|
bool gotConnect = false;
|
|
int bodyStart = -1;
|
|
|
|
while (millis() - start < 30000 && bufIndex < 599) {
|
|
if (EC200U.available()) {
|
|
char c = EC200U.read();
|
|
buffer[bufIndex++] = c;
|
|
Serial1.write(c);
|
|
|
|
if (!gotConnect && bufIndex >= 7) {
|
|
if (strncmp(&buffer[bufIndex-7], "CONNECT", 7) == 0) {
|
|
gotConnect = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bufIndex >= 12) {
|
|
buffer[bufIndex] = '\0';
|
|
if (strstr(buffer, "+QHTTPREAD: 0") != NULL) {
|
|
delay(100);
|
|
while (EC200U.available() && bufIndex < 599) {
|
|
buffer[bufIndex++] = EC200U.read();
|
|
}
|
|
break;
|
|
}
|
|
if (strstr(buffer, "ERROR") != NULL) {
|
|
Serial1.println("\n❌ Error reading HTTP response");
|
|
return "";
|
|
}
|
|
}
|
|
}
|
|
|
|
buffer[bufIndex] = '\0';
|
|
|
|
Serial1.println("\n--- Raw buffer ---");
|
|
Serial1.println(buffer);
|
|
Serial1.println("--- End raw ---");
|
|
|
|
String body = "";
|
|
|
|
char* connectPtr = strstr(buffer, "CONNECT");
|
|
if (connectPtr != NULL) {
|
|
char* bodyPtr = strchr(connectPtr, '\n');
|
|
if (bodyPtr != NULL) {
|
|
bodyPtr++;
|
|
|
|
char* endPtr = strstr(bodyPtr, "\r\nOK");
|
|
if (endPtr == NULL) endPtr = strstr(bodyPtr, "\nOK");
|
|
if (endPtr == NULL) endPtr = strstr(bodyPtr, "+QHTTPREAD");
|
|
|
|
if (endPtr != NULL) {
|
|
int len = endPtr - bodyPtr;
|
|
body.reserve(len + 1);
|
|
for (int i = 0; i < len; i++) {
|
|
if (bodyPtr[i] != '\r' && bodyPtr[i] != '\n') {
|
|
body += bodyPtr[i];
|
|
}
|
|
}
|
|
} else {
|
|
body = String(bodyPtr);
|
|
}
|
|
}
|
|
}
|
|
|
|
body.trim();
|
|
|
|
Serial1.print("\n--- Extracted Body (");
|
|
Serial1.print(body.length());
|
|
Serial1.print(" chars) ---\n[");
|
|
Serial1.print(body);
|
|
Serial1.println("]");
|
|
Serial1.println("--- End Body ---");
|
|
|
|
return body;
|
|
}
|
|
|
|
|
|
String extractNumberFromResponse(String response) {
|
|
String result = "";
|
|
for (int i = 0; i < response.length(); i++) {
|
|
char c = response.charAt(i);
|
|
if (c >= '0' && c <= '9') {
|
|
result += c;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
inline bool downloadAMRFile(String url) {
|
|
Serial1.println("\n--- Downloading AMR File ---");
|
|
Serial1.print("URL: ");
|
|
Serial1.println(url);
|
|
|
|
// 1. بررسی اتصال
|
|
if (!sendAT("AT", 2000, true)) {
|
|
Serial1.println("❌ Modem not responding");
|
|
return false;
|
|
}
|
|
|
|
// 2. پاکسازی بافر
|
|
while (EC200U.available()) EC200U.read();
|
|
|
|
// 3. تنظیم URL (روش مستقیم)
|
|
Serial1.println("Setting URL...");
|
|
EC200U.println("AT+QHTTPURL");
|
|
|
|
String response = "";
|
|
unsigned long start = millis();
|
|
bool gotConnect = false;
|
|
|
|
// منتظر CONNECT
|
|
while (millis() - start < 5000) {
|
|
while (EC200U.available()) {
|
|
char c = EC200U.read();
|
|
response += c;
|
|
Serial1.write(c);
|
|
|
|
if (response.indexOf("CONNECT") != -1) {
|
|
gotConnect = true;
|
|
break;
|
|
}
|
|
}
|
|
if (gotConnect) break;
|
|
}
|
|
|
|
if (!gotConnect) {
|
|
Serial1.println("❌ No CONNECT, trying alternative...");
|
|
|
|
// روش جایگزین: استفاده از طول URL
|
|
String cmd = "AT+QHTTPURL=" + String(url.length()) + ",30";
|
|
EC200U.println(cmd);
|
|
|
|
response = "";
|
|
start = millis();
|
|
while (millis() - start < 5000) {
|
|
while (EC200U.available()) {
|
|
char c = EC200U.read();
|
|
response += c;
|
|
if (c == '\n') {
|
|
if (response.indexOf("CONNECT") != -1) {
|
|
gotConnect = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (gotConnect) break;
|
|
}
|
|
}
|
|
|
|
if (!gotConnect) {
|
|
Serial1.println("❌ Could not get CONNECT prompt");
|
|
return false;
|
|
}
|
|
|
|
// 4. ارسال URL
|
|
Serial1.println("Sending URL...");
|
|
EC200U.println(url);
|
|
|
|
// 5. منتظر OK
|
|
response = "";
|
|
start = millis();
|
|
bool urlAccepted = false;
|
|
|
|
while (millis() - start < 5000) {
|
|
while (EC200U.available()) {
|
|
char c = EC200U.read();
|
|
response += c;
|
|
Serial1.write(c);
|
|
|
|
if (response.indexOf("OK") != -1) {
|
|
urlAccepted = true;
|
|
break;
|
|
}
|
|
if (response.indexOf("ERROR") != -1) {
|
|
Serial1.println("❌ URL rejected");
|
|
return false;
|
|
}
|
|
}
|
|
if (urlAccepted) break;
|
|
}
|
|
|
|
if (!urlAccepted) {
|
|
Serial1.println("❌ URL not accepted (timeout)");
|
|
return false;
|
|
}
|
|
|
|
Serial1.println("✅ URL set successfully");
|
|
delay(1000);
|
|
|
|
// 6. ارسال GET request
|
|
Serial1.println("Sending GET request...");
|
|
EC200U.println("AT+QHTTPGET");
|
|
|
|
response = "";
|
|
start = millis();
|
|
bool gotResponse = false;
|
|
|
|
while (millis() - start < 30000) {
|
|
while (EC200U.available()) {
|
|
char c = EC200U.read();
|
|
response += c;
|
|
Serial1.write(c);
|
|
|
|
if (response.indexOf("+QHTTPGET:") != -1) {
|
|
gotResponse = true;
|
|
|
|
// بررسی کد وضعیت
|
|
int idx = response.indexOf("+QHTTPGET:");
|
|
String httpResponse = response.substring(idx);
|
|
Serial1.print("HTTP Response: ");
|
|
Serial1.println(httpResponse);
|
|
|
|
// استخراج کد HTTP
|
|
int comma1 = httpResponse.indexOf(',');
|
|
int comma2 = httpResponse.indexOf(',', comma1 + 1);
|
|
|
|
if (comma1 != -1 && comma2 != -1) {
|
|
int httpCode = httpResponse.substring(comma1 + 1, comma2).toInt();
|
|
Serial1.print("HTTP Code: ");
|
|
Serial1.println(httpCode);
|
|
|
|
if (httpCode != 200) {
|
|
Serial1.println("❌ HTTP error");
|
|
return false;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (gotResponse) break;
|
|
}
|
|
|
|
if (!gotResponse) {
|
|
Serial1.println("❌ GET request timeout");
|
|
return false;
|
|
}
|
|
|
|
Serial1.println("✅ GET successful");
|
|
delay(2000);
|
|
|
|
// 7. ذخیره فایل
|
|
Serial1.println("Saving to file...");
|
|
EC200U.println("AT+QHTTPREADFILE=\"UFS:output.amr\"");
|
|
|
|
response = "";
|
|
start = millis();
|
|
bool fileSaved = false;
|
|
|
|
while (millis() - start < 60000) {
|
|
while (EC200U.available()) {
|
|
char c = EC200U.read();
|
|
response += c;
|
|
|
|
// نمایش پیشرفت
|
|
static int dots = 0;
|
|
if (c == '\n') {
|
|
Serial1.print(".");
|
|
dots++;
|
|
if (dots % 50 == 0) Serial1.println();
|
|
}
|
|
|
|
if (response.indexOf("+QHTTPREADFILE: 0") != -1) {
|
|
fileSaved = true;
|
|
break;
|
|
}
|
|
}
|
|
if (fileSaved) break;
|
|
}
|
|
|
|
if (fileSaved) {
|
|
Serial1.println("\n✅ File saved successfully");
|
|
|
|
// بررسی وجود فایل
|
|
Serial1.println("Verifying file...");
|
|
EC200U.println("AT+QFLST=\"UFS:output.amr\"");
|
|
|
|
response = "";
|
|
start = millis();
|
|
while (millis() - start < 3000) {
|
|
while (EC200U.available()) {
|
|
char c = EC200U.read();
|
|
response += c;
|
|
Serial1.write(c);
|
|
}
|
|
if (response.indexOf("output.amr") != -1) break;
|
|
}
|
|
|
|
if (response.indexOf("output.amr") != -1) {
|
|
Serial1.println("✅ File verified");
|
|
return true;
|
|
} else {
|
|
Serial1.println("⚠️ File not found in listing");
|
|
return true; // باز هم true برگردان چون ذخیره شد
|
|
}
|
|
}
|
|
|
|
Serial1.println("\n❌ Failed to save file");
|
|
return false;
|
|
}
|
|
|
|
|
|
// ==================== تابع نهایی: تماس با DTMF Tones ====================
|
|
// // تابع اصلی که واقعاً باید کار کند
|
|
// inline bool makeVoiceCallWithAudio(String phoneNumber) {
|
|
// return false;
|
|
// }
|
|
|
|
// ==================== تابع اصلاح شده processServerResponse ====================
|
|
inline void processServerResponse(String response) {
|
|
if (response.length() == 0) {
|
|
Serial1.println("Empty response, no action needed");
|
|
return;
|
|
}
|
|
|
|
Serial1.println("\n======== PROCESSING SERVER RESPONSE ========");
|
|
Serial1.print("Response: ");
|
|
Serial1.println(response);
|
|
|
|
if (response.startsWith("tt")) {
|
|
Serial1.println("Response Type: TT (Send SMS)");
|
|
|
|
String data = response.substring(2);
|
|
|
|
int hashIdx = data.indexOf('#');
|
|
if (hashIdx != -1) {
|
|
String phoneNumber = data.substring(0, hashIdx);
|
|
String message = data.substring(hashIdx + 1);
|
|
|
|
phoneNumber.trim();
|
|
message.trim();
|
|
|
|
Serial1.print(" Phone: ");
|
|
Serial1.println(phoneNumber);
|
|
Serial1.print(" Message: ");
|
|
Serial1.println(message);
|
|
|
|
if (phoneNumber.length() >= 10 && message.length() > 0) {
|
|
if (sendSMS(phoneNumber, message)) {
|
|
Serial1.println("✅ SMS sent successfully");
|
|
lastMessage = "TT SMS Sent";
|
|
} else {
|
|
Serial1.println("❌ Failed to send SMS");
|
|
lastMessage = "TT SMS Fail";
|
|
}
|
|
} else {
|
|
Serial1.println("❌ Invalid phone or message");
|
|
lastMessage = "TT Invalid";
|
|
}
|
|
} else {
|
|
Serial1.println("❌ Invalid TT format (no #)");
|
|
lastMessage = "TT Format Err";
|
|
}
|
|
}
|
|
else if (response.startsWith("RST")) {
|
|
NVIC_SystemReset();
|
|
}
|
|
else if (response.startsWith("SHD")) {
|
|
HAL_PWR_EnterSTANDBYMode();
|
|
}
|
|
// else if (response.startsWith("TY")) {
|
|
// Serial1.println("Response Type: TY (Voice Call with Audio/DMTF)");
|
|
|
|
// String data = response.substring(2);
|
|
|
|
// int hashIdx = data.indexOf('#');
|
|
// if (hashIdx != -1) {
|
|
// String phoneNumber = data.substring(0, hashIdx);
|
|
// String audioUrl = data.substring(hashIdx + 1);
|
|
|
|
// phoneNumber.trim();
|
|
// audioUrl.trim();
|
|
|
|
// Serial1.print(" Phone: ");
|
|
// Serial1.println(phoneNumber);
|
|
// Serial1.print(" Audio URL: ");
|
|
// Serial1.println(audioUrl);
|
|
|
|
// if (phoneNumber.length() >= 10) {
|
|
// if (makeVoiceCallWithAudio(phoneNumber)) {
|
|
// Serial1.println("✅ Voice call with DTMF completed");
|
|
// lastMessage = "TY Call Done (DTMF)";
|
|
// } else {
|
|
// Serial1.println("❌ Voice call failed");
|
|
// lastMessage = "TY Call Fail";
|
|
// }
|
|
// } else {
|
|
// Serial1.println("❌ Invalid phone number");
|
|
// lastMessage = "TY Invalid";
|
|
// }
|
|
// } else {
|
|
// Serial1.println("❌ Invalid TY format (no #)");
|
|
// lastMessage = "TY Format Err";
|
|
// }
|
|
// }
|
|
else {
|
|
Serial1.println("Response Type: Numeric or unknown - No action needed");
|
|
}
|
|
|
|
Serial1.println("=============================================\n");
|
|
}
|
|
|
|
// -------------------- ارسال داده به سرور --------------------
|
|
inline void uploadData() {
|
|
Serial1.println("\n======== DATA UPLOAD ========");
|
|
|
|
if (!config.verified) {
|
|
Serial1.println("❌ Upload skipped: Device not verified");
|
|
Serial1.println("==============================\n");
|
|
return;
|
|
}
|
|
if (!networkConnected && config.verified) {
|
|
Serial1.println("⚠️ Not connected, trying to reconnect...");
|
|
connectToNetwork();
|
|
}
|
|
if (!networkConnected) {
|
|
Serial1.println("⚠️ Not connected, trying to reconnect...");
|
|
initEC200U();
|
|
if (!networkConnected) {
|
|
Serial1.println("❌ Upload skipped: No network connection");
|
|
Serial1.println("==============================\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
float coToSend = currentData.coPPM;
|
|
|
|
String data = "deviceId=" + String(config.deviceId) +
|
|
"&temperatureC=" + String(currentData.temperature, 1) +
|
|
"&humidityPercent=" + String(currentData.humidity, 1) +
|
|
"&gasPPM=" + String(coToSend, 0) +
|
|
"&lux=" + String(currentData.lightLux, 1) +
|
|
"&voltage=" + String(currentData.volage, 1) +
|
|
"&power=" + String(currentData.power) +
|
|
"&oldPower=" + String(currentData.oldPower) +
|
|
"&batteryPercent=" + String(currentData.batteryPercent, 1) +
|
|
"&batteryVoltage=" + String(currentData.batteryVoltage, 1);
|
|
|
|
data.replace(" ", "");
|
|
String url = String(config.serverUrl) + "/api/Telemetry/AddData?" + data;
|
|
//url = "https://ghback.nabaksoft.ir/My_StaticFiles/calltest.html";
|
|
Serial1.println("--- REQUEST INFO ---");
|
|
Serial1.print(" Server: ");
|
|
Serial1.println(config.serverUrl);
|
|
Serial1.print(" Device ID: ");
|
|
Serial1.println(config.deviceId);
|
|
Serial1.print(" Temp: ");
|
|
Serial1.print(currentData.temperature, 1);
|
|
Serial1.println(" C");
|
|
Serial1.print(" Hum: ");
|
|
Serial1.print(currentData.humidity, 1);
|
|
Serial1.println(" %");
|
|
Serial1.print(" CO (local): ");
|
|
Serial1.print(currentData.coPPM, 0);
|
|
Serial1.println(" ppm");
|
|
Serial1.print(" CO (to server): ");
|
|
Serial1.print(coToSend, 0);
|
|
Serial1.print(" ppm");
|
|
if (!MQ7sensorPreheated) {
|
|
Serial1.print(" [CALIBRATING]");
|
|
}
|
|
Serial1.println("--- FULL URL ---");
|
|
Serial1.println(url);
|
|
Serial1.print(" URL Length: ");
|
|
Serial1.println(url.length());
|
|
|
|
configureSSL();
|
|
|
|
String cmd = "AT+QHTTPURL=" + String(url.length()) + ",80";
|
|
EC200U.println(cmd);
|
|
|
|
String response = "";
|
|
unsigned long start = millis();
|
|
bool gotConnect = false;
|
|
|
|
while (millis() - start < 5000) {
|
|
while (EC200U.available()) {
|
|
char c = EC200U.read();
|
|
response += c;
|
|
Serial1.write(c);
|
|
}
|
|
if (response.indexOf("CONNECT") != -1) {
|
|
gotConnect = true;
|
|
break;
|
|
}
|
|
if (response.indexOf("ERROR") != -1) {
|
|
Serial1.println("\n❌ Step 1 failed: QHTTPURL error");
|
|
lastMessage = "URL Err";
|
|
Serial1.println("==============================\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (!gotConnect) {
|
|
Serial1.println("❌ Step 1 failed: No CONNECT response");
|
|
lastMessage = "URL Err";
|
|
Serial1.println("==============================\n");
|
|
return;
|
|
}
|
|
|
|
Serial1.println("\n✅ Step 1: Got CONNECT, sending URL...");
|
|
|
|
EC200U.print(url);
|
|
delay(1000);
|
|
|
|
response = "";
|
|
start = millis();
|
|
while (millis() - start < 5000) {
|
|
while (EC200U.available()) {
|
|
char c = EC200U.read();
|
|
response += c;
|
|
Serial1.write(c);
|
|
}
|
|
if (response.indexOf("OK") != -1) break;
|
|
}
|
|
|
|
if (response.indexOf("OK") == -1) {
|
|
Serial1.println("\n❌ Step 1 failed: URL not accepted");
|
|
lastMessage = "URL Err";
|
|
Serial1.println("==============================\n");
|
|
return;
|
|
}
|
|
|
|
Serial1.println("\n✅ Step 1: URL set successfully");
|
|
delay(500);
|
|
|
|
Serial1.println("Step 2: Sending HTTP GET (waiting up to 60 sec)...");
|
|
EC200U.println("AT+QHTTPGET=60");
|
|
|
|
response = "";
|
|
start = millis();
|
|
bool success = false;
|
|
bool gotResponse = false;
|
|
|
|
while (millis() - start < 65000) {
|
|
while (EC200U.available()) {
|
|
char c = EC200U.read();
|
|
response += c;
|
|
Serial1.write(c);
|
|
}
|
|
|
|
if (response.indexOf("+QHTTPGET:") != -1) {
|
|
delay(1000);
|
|
while (EC200U.available()) {
|
|
char c = EC200U.read();
|
|
response += c;
|
|
Serial1.write(c);
|
|
}
|
|
gotResponse = true;
|
|
|
|
int idx = response.indexOf("+QHTTPGET:");
|
|
String httpResult = response.substring(idx);
|
|
Serial1.print("\nHTTP Result: ");
|
|
Serial1.println(httpResult);
|
|
|
|
if (httpResult.indexOf(" 0,200") != -1 || httpResult.indexOf(" 0,201") != -1 ||
|
|
httpResult.indexOf(":0,200") != -1 || httpResult.indexOf(":0,201") != -1) {
|
|
success = true;
|
|
} else if (httpResult.indexOf(",200,") != -1 || httpResult.indexOf(",201,") != -1) {
|
|
success = true;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (response.indexOf("ERROR") != -1) {
|
|
Serial1.println("\n❌ HTTP GET command error");
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (success) {
|
|
lastUpload = millis();
|
|
lastMessage = "Uploaded";
|
|
Serial1.println("\n✅ Step 2: Data uploaded successfully!");
|
|
Serial1.println("--- UPLOAD SUCCESS ---");
|
|
Serial1.print(" Time: ");
|
|
Serial1.print(millis() / 1000);
|
|
Serial1.println(" sec since boot");
|
|
Serial1.println("----------------------");
|
|
|
|
delay(500);
|
|
String serverResponse = readHttpResponse();
|
|
if (serverResponse.length() > 0) {
|
|
processServerResponse(serverResponse);
|
|
}
|
|
} else {
|
|
lastMessage = "Upload Err";
|
|
if (gotResponse) {
|
|
Serial1.println("\n❌ Step 2: Server returned error");
|
|
} else {
|
|
Serial1.println("\n❌ Step 2: Timeout waiting for response");
|
|
}
|
|
|
|
Serial1.println("--- FULL RESPONSE ---");
|
|
Serial1.println(response);
|
|
Serial1.println("---------------------");
|
|
|
|
Serial1.println("Will retry on next interval...");
|
|
networkConnected = false;
|
|
}
|
|
|
|
Serial1.println("==============================\n");
|
|
}
|
|
|
|
#endif // EC200U_H
|