Files
Arduino/14041130/TestProgram/TestEcu/EC200U-Call.h
2026-02-19 06:17:44 +03:30

475 lines
15 KiB
C

#ifndef EC200U_AUDIOCALL_H
#define EC200U_AUDIOCALL_H
#include <Arduino.h>
// -------------------- تعریف USART3 --------------------
HardwareSerial EC200U(USART3);
// -------------------- تنظیمات --------------------
const char* AUDIO_FILE_PATH = "UFS:output.amr";
String APN = "mcinet"; // اگر نیاز است تنظیم شود
// -------------------- تابع ارسال AT --------------------
String sendATCommand(String cmd, uint16_t timeout = 5000, bool showCmd = false, bool showResponse = false) {
if (showCmd) {
Serial1.print(">> ");
Serial1.println(cmd);
}
EC200U.println(cmd);
String response = "";
unsigned long start = millis();
bool gotOk = false;
bool gotError = false;
while (millis() - start < timeout) {
while (EC200U.available()) {
char c = EC200U.read();
response += c;
if (showResponse) Serial1.write(c);
}
if (response.indexOf("OK") != -1) gotOk = true;
if (response.indexOf("ERROR") != -1) gotError = true;
// برای دستورات خاص، منتظر نشانه‌های دیگر هم باشیم
if (response.indexOf("CONNECT") != -1) break;
if (response.indexOf("+QHTTPGET:") != -1) break;
if (response.indexOf("+QHTTPREADFILE:") != -1) break;
if (gotOk || gotError) break;
}
return response;
}
// -------------------- راه‌اندازی اینترنت --------------------
bool setupInternet() {
Serial1.println("\n🌐 راه‌اندازی اتصال اینترنت");
Serial1.println("==========================");
// 1. تنظیم APN (اگر نیاز است)
if (APN.length() > 0) {
Serial1.print("[1] تنظیم APN... ");
String cmd = "AT+QICSGP=1,1,\"" + APN + "\",\"\",\"\",1";
if (sendATCommand(cmd, 5000, false).indexOf("OK") == -1) {
Serial1.println("FAIL");
return false;
}
Serial1.println("OK");
}
// 2. فعال‌سازی زمینه PDP
Serial1.print("[2] فعال‌سازی PDP... ");
if (sendATCommand("AT+QIACT=1", 30000, false).indexOf("OK") == -1) {
Serial1.println("FAIL - سعی می‌کنیم از حالت فعلی استفاده کنیم");
} else {
Serial1.println("OK");
}
// 3. بررسی وضعیت اتصال
Serial1.print("[3] بررسی اتصال... ");
String resp = sendATCommand("AT+QIACT?", 2000, false);
if (resp.indexOf("+QIACT:") != -1) {
Serial1.println("CONNECTED");
return true;
} else {
Serial1.println("NO CONNECTION");
return false;
}
}
// -------------------- دانلود فایل صوتی از URL --------------------
// -------------------- دانلود فایل صوتی از URL --------------------
bool downloadAudioFile(String url) {
Serial1.println("\n📥 دانلود فایل صوتی");
Serial1.println("===================");
// 1. پاک کردن فایل قدیمی اگر وجود دارد
Serial1.print("[1] پاک کردن فایل قدیمی... ");
sendATCommand("AT+QFDEL=\"UFS:audio.amr\"", 2000, false);
Serial1.println("OK");
delay(100);
// 2. تنظیم URL
Serial1.print("[2] تنظیم URL... ");
int urlLen = url.length();
String cmd = "AT+QHTTPURL=" + String(urlLen) + ",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;
}
if (response.indexOf("CONNECT") != -1) {
gotConnect = true;
break;
}
if (response.indexOf("ERROR") != -1) {
Serial1.println("FAIL - خطای QHTTPURL");
return false;
}
}
if (!gotConnect) {
Serial1.println("FAIL - CONNECT دریافت نشد");
return false;
}
// ارسال URL
EC200U.print(url);
delay(1000);
response = "";
start = millis();
while (millis() - start < 3000) {
while (EC200U.available()) {
char c = EC200U.read();
response += c;
}
if (response.indexOf("OK") != -1) break;
}
if (response.indexOf("OK") == -1) {
Serial1.println("FAIL - URL پذیرفته نشد");
return false;
}
Serial1.println("OK");
// 3. دانلود فایل
Serial1.print("[3] دانلود فایل... ");
EC200U.println("AT+QHTTPGET=60"); // 60 ثانیه تایم‌اوت
response = "";
start = millis();
bool httpSuccess = false;
int httpCode = 0;
while (millis() - start < 65000) {
while (EC200U.available()) {
char c = EC200U.read();
response += c;
Serial1.write(c);
}
int qhttpIdx = response.indexOf("+QHTTPGET:");
if (qhttpIdx != -1) {
String afterQhttp = response.substring(qhttpIdx);
int firstComma = afterQhttp.indexOf(',');
int secondComma = afterQhttp.indexOf(',', firstComma + 1);
if (firstComma != -1 && secondComma != -1) {
int errorCode = afterQhttp.substring(11, firstComma).toInt();
httpCode = afterQhttp.substring(firstComma + 1, secondComma).toInt();
Serial1.print("کد خطا: ");
Serial1.print(errorCode);
Serial1.print(", کد HTTP: ");
Serial1.print(httpCode);
if (errorCode == 0 && httpCode >= 200 && httpCode < 300) {
httpSuccess = true;
}
break;
}
}
if (response.indexOf("ERROR") != -1) {
Serial1.println("\n❌ HTTP GET ناموفق");
return false;
}
}
if (!httpSuccess) {
Serial1.println("FAIL");
Serial1.print(" کد HTTP: ");
Serial1.println(httpCode);
return false;
}
Serial1.println("OK");
delay(500);
// پاک کردن بافر
while (EC200U.available()) EC200U.read();
// 4. ذخیره فایل
Serial1.print("[4] ذخیره فایل... ");
EC200U.println("AT+QHTTPREADFILE=\"UFS:audio.amr\",80");
response = "";
start = millis();
bool saveSuccess = false;
while (millis() - start < 60000) {
while (EC200U.available()) {
char c = EC200U.read();
response += c;
Serial1.write(c);
}
if (response.indexOf("+QHTTPREADFILE: 0") != -1) {
saveSuccess = true;
break;
}
if (response.indexOf("ERROR") != -1) {
break;
}
}
if (saveSuccess) {
Serial1.println("OK");
Serial1.println("✅ فایل صوتی دانلود و ذخیره شد");
return true;
} else {
Serial1.println("FAIL");
Serial1.println("❌ ذخیره فایل ناموفق");
return false;
}
}
// -------------------- بررسی وضعیت تماس --------------------
int getCallState() {
EC200U.println("AT+CLCC");
delay(300);
String response = "";
unsigned long start = millis();
while (millis() - start < 2000) {
while (EC200U.available()) {
char c = EC200U.read();
response += c;
}
}
if (response.indexOf("+CLCC: 0,0,0,0,0") != -1) return 0; // Active
if (response.indexOf("+CLCC: 0,0,2,0,0") != -1) return 2; // Dialing
if (response.indexOf("+CLCC: 0,0,3,0,0") != -1) return 3; // Ringing
if (response.indexOf("NO CARRIER") != -1) return -2; // Disconnected
if (response.indexOf("BUSY") != -1) return -3; // Busy
return -1; // Unknown
}
// -------------------- تابع اصلی تماس و پخش --------------------
bool callAndPlayAudio(String phoneNumber) {
Serial1.println("\n📞 تماس و پخش فایل صوتی");
Serial1.println("========================");
// 1. برقراری تماس
Serial1.print("[1] برقراری تماس... ");
String dialCmd = "ATD" + phoneNumber + ";";
String resp = sendATCommand(dialCmd, 10000, false, true);
if (resp.indexOf("OK") == -1 && resp.indexOf("ERROR") != -1) {
Serial1.println("FAIL");
return false;
}
Serial1.println("OK");
// 2. منتظر پاسخ
Serial1.print("[2] منتظر پاسخ تماس... ");
unsigned long start = millis();
bool callConnected = false;
while (millis() - start < 45000) { // 45 ثانیه منتظر بمان
int callState = getCallState();
switch (callState) {
case 0: // Active
callConnected = true;
Serial1.println("CONNECTED");
break;
case 2: // Dialing
Serial1.print(".");
break;
case 3: // Ringing
Serial1.print("R");
break;
case -2: // Disconnected
Serial1.println("DISCONNECTED");
return false;
case -3: // Busy
Serial1.println("BUSY");
return false;
}
if (callConnected) break;
delay(2000);
}
if (!callConnected) {
Serial1.println("NO ANSWER");
sendATCommand("ATH", 2000, false);
return false;
}
delay(1000); // کمی صبر بعد از اتصال
// 3. پخش فایل صوتی
Serial1.print("[3] شروع پخش صدا... ");
// ابتدا حالت پخش را تنظیم کن
resp = sendATCommand("AT+QVTCMD=1,0,\"UFS:output.amr\"", 5000, false, true);
if (resp.indexOf("OK") == -1) {
Serial1.println("FAIL - تنظیم پخش");
Serial1.println(" پاسخ: " + resp);
sendATCommand("ATH", 2000, false);
return false;
}
// شروع پخش
resp = sendATCommand("AT+QVTCMD=3,0", 3000, false, true);
if (resp.indexOf("OK") == -1) {
Serial1.println("FAIL - شروع پخش");
sendATCommand("ATH", 2000, false);
return false;
}
Serial1.println("OK");
// 4. منتظر اتمام پخش
Serial1.println("[4] در حال پخش... ");
bool playbackComplete = false;
start = millis();
while (millis() - start < 120000) { // حداکثر 2 دقیقه
// بررسی وضعیت پخش
EC200U.println("AT+QVTSTAT?");
delay(500);
String statusResp = "";
unsigned long statusStart = millis();
while (millis() - statusStart < 2000) {
while (EC200U.available()) {
char c = EC200U.read();
statusResp += c;
}
}
// اگر پخش تمام شده
if (statusResp.indexOf("+QVTSTAT: 0,0") != -1) {
playbackComplete = true;
break;
}
// بررسی وضعیت تماس
if (getCallState() != 0) {
Serial1.println(" تماس قطع شد");
break;
}
Serial1.print(".");
delay(1000);
}
if (playbackComplete) {
Serial1.println(" COMPLETE");
} else {
Serial1.println(" INCOMPLETE");
}
// 5. قطع تماس
Serial1.print("[5] پایان تماس... ");
resp = sendATCommand("ATH", 3000, false, true);
if (resp.indexOf("OK") != -1) {
Serial1.println("OK");
Serial1.println("✅ عملیات کامل شد");
return true;
} else {
Serial1.println("FAIL");
return false;
}
}
// -------------------- تابع اصلی یکپارچه --------------------
bool downloadAndCall(String phoneNumber, String audioUrl) {
Serial1.println("\n🎯 شروع عملیات کامل");
Serial1.println("====================");
Serial1.println("📞 شماره: " + phoneNumber);
Serial1.println("🔗 URL: " + audioUrl);
// 1. راه‌اندازی اینترنت
if (!setupInternet()) {
Serial1.println("❌ اتصال اینترنت ناموفق");
return false;
}
// 2. دانلود فایل صوتی
if (!downloadAudioFile(audioUrl)) {
Serial1.println("❌ دانلود فایل ناموفق");
return false;
}
delay(2000);
// 3. تماس و پخش
return callAndPlayAudio(phoneNumber);
}
// -------------------- تابع تست سریع --------------------
void testAudioCall() {
Serial1.println("\n🧪 تست سریع عملیات تماس صوتی");
Serial1.println("==============================");
// اطلاعات تست (تغییر دهید)
String testPhone = "09192530212";
String testUrl = "http://ghback.nabaksoft.ir/My_staticFiles/output.amr"; // URL فایل صوتی AMR
Serial1.println("⚠️ توجه: لطفاً اطلاعات زیر را تنظیم کنید:");
Serial1.println(" 1. شماره تلفن: " + testPhone);
Serial1.println(" 2. URL فایل صوتی: " + testUrl);
Serial1.println(" 3. APN (اگر نیاز است) در کد تنظیم شود");
// در اینجا می‌توانید تست را فعال کنید
// bool result = downloadAndCall(testPhone, testUrl);
Serial1.println("\n📋 دستورات تست دستی:");
Serial1.println(" 1. initModule() - راه‌اندازی ماژول");
Serial1.println(" 2. setupInternet() - اتصال اینترنت");
Serial1.println(" 3. downloadAudioFile(\"URL\") - دانلود فایل");
Serial1.println(" 4. callAndPlayAudio(\"PHONE\") - تماس و پخش");
}
// -------------------- راه‌اندازی اولیه ماژول --------------------
void initModule() {
Serial1.begin(115200);
EC200U.begin(115200);
delay(3000);
Serial1.println("\n🔧 راه‌اندازی ماژول EC200U");
Serial1.println("==========================");
// تست AT
Serial1.print("AT... ");
if (sendATCommand("AT", 2000, false).indexOf("OK") != -1) {
Serial1.println("OK");
} else {
Serial1.println("FAIL");
return;
}
// غیرفعال کردن اکو
sendATCommand("ATE0", 1000, false);
// تنظیمات صدا
sendATCommand("AT+CLVL=5", 1000, false); // سطح صدا
sendATCommand("AT+CMUT=0", 1000, false); // غیرفعال کردن mute
Serial1.println("✅ ماژول آماده است");
}
#endif // EC200U_AUDIOCALL_H