diff --git a/module-cellular/Modem/ATParser.cpp b/module-cellular/Modem/ATParser.cpp index 1d8842c69..6048e33f9 100644 --- a/module-cellular/Modem/ATParser.cpp +++ b/module-cellular/Modem/ATParser.cpp @@ -109,6 +109,7 @@ int ATParser::ProcessNewData() { // 4) +QIND: SMS DONE // 5) +QIND: PB DONE if (urcs.size() == 5) { + cpp_freertos::LockGuard lock(mutex); mux->callback(NotificationType ::PowerUpProcedureComplete,""); responseBuffer.erase(); urcs.clear(); @@ -121,6 +122,11 @@ int ATParser::ProcessNewData() { std::vector ATParser::SendCommand(const char *cmd, size_t rxCount, uint32_t timeout) { std::vector tokens; + { + cpp_freertos::LockGuard lock(mutex); + responseBuffer.erase(); + } + blockedTaskHandle = xTaskGetCurrentTaskHandle(); auto cmdSigned = const_cast(cmd); inOutSerialWorker->WriteData(reinterpret_cast(cmdSigned), strlen(cmd)); diff --git a/module-cellular/Modem/MuxDaemon.cpp b/module-cellular/Modem/MuxDaemon.cpp index 2680dd501..11f09c04f 100644 --- a/module-cellular/Modem/MuxDaemon.cpp +++ b/module-cellular/Modem/MuxDaemon.cpp @@ -132,7 +132,7 @@ MuxDaemon::ConfState MuxDaemon::PowerUpProcedure() { // At first send AT command to check if modem is turned on auto ret = inOutSerialDataWorker->SendATCommand("AT\r", 2); if ((ret.size() == 1 && ret[0] == "OK") || (ret.size() == 2 && ret[0] == "AT\r" && ret[1] == "OK")) { - return ConfProcedure(); + return ConfState ::Success; } else { LOG_INFO("Modem does not respond to AT commands, trying close mux mode"); @@ -146,12 +146,12 @@ MuxDaemon::ConfState MuxDaemon::PowerUpProcedure() { ret = inOutSerialDataWorker->SendATCommand("AT\r", 2); if (ret.size() == 1 || ret.size() == 2) { // Modem can send echo response or not, in either case it means that modem is operating in AT mode - return ConfProcedure(); + return ConfState ::Success; } else { LOG_INFO("Starting power up procedure..."); // If no response, power up modem and try again cellular->PowerUp(); - return ConfState ::Success; + return ConfState::PowerUp; } } } @@ -200,22 +200,31 @@ MuxDaemon::ConfState MuxDaemon::ConfProcedure() { // Set SMS received report format SendAT("AT+CNMI=1,2,0,1,0\r", 500);*/ - // Audio configuraton, custom PCM, 16bit linear samples, primary mode, 16kHz, master, - /* - * M.P: Quectel confirmed that during init phase of modem sends 'ready notification" way before audio subsystem is initialized - * hence in order to properly configure audio we have literally ping modem with conf command until it responds with success ret code... - */ + return ConfState ::Success; +} - auto audioConfRet = inOutSerialDataWorker->SendATCommand("AT+QDAI?\r",2); - if(audioConfRet.size() == 2 && !audioConfRet[0].compare("AT+QDAI=1,0,0,5,0,1")){ - // GSM modem is configured properly, skip audio configuration - return StartMultiplexer(); +MuxDaemon::ConfState MuxDaemon::AudioConfProcedure() { + + + auto audioConfRet = inOutSerialDataWorker->SendATCommand("AT+QDAI?\r", 1); + + + if(audioConfRet[0].compare(0,strlen("+QDAI:"),"+QDAI:",strlen("+QDAI:")) != 0){ + return ConfState ::Failure; } - else{ - CheckATCommandResponse(inOutSerialDataWorker->SendATCommand("AT+QDAI=1,0,0,5,0,1\r", 1)); - cellular->Restart(); - LOG_DEBUG("GSM module first run, performing reset..."); - return ConfState ::ModemNeedsReset; + else if(audioConfRet[0].compare("+QDAI: 1,0,0,5,0,1,1,1") == 0){ + return ConfState ::Success; + } + else { + if(!CheckATCommandResponse(inOutSerialDataWorker->SendATCommand("AT+QDAI=1,0,0,5,0,1\r", 1)) ){ + vTaskDelay(1000); + return ConfState ::Failure; + }else{ + cellular->Restart(); + LOG_DEBUG("GSM module first run, performing reset..."); + return ConfState::ModemNeedsReset; + } + } } @@ -253,7 +262,7 @@ MuxDaemon::ConfState MuxDaemon::StartMultiplexer() { vTaskDelay(200); } - return ConfState ::Success; + return ConfState::Success; } diff --git a/module-cellular/Modem/MuxDaemon.hpp b/module-cellular/Modem/MuxDaemon.hpp index e38a5bbc3..3ec151f8e 100644 --- a/module-cellular/Modem/MuxDaemon.hpp +++ b/module-cellular/Modem/MuxDaemon.hpp @@ -54,7 +54,8 @@ public: enum class ConfState{ Success, Failure, - ModemNeedsReset + ModemNeedsReset, + PowerUp }; static std::unique_ptr Create(NotificationMuxChannel::NotificationCallback_t callback); @@ -74,7 +75,8 @@ public: ConfState PowerUpProcedure(); ConfState ConfProcedure(); - + ConfState AudioConfProcedure(); + ConfState StartMultiplexer(); int uihPfBitReceived = 0; @@ -84,8 +86,6 @@ private: friend void workerTaskFunction(void *ptr); - ConfState StartMultiplexer(); - bool Start(); int CloseMultiplexer(); diff --git a/module-services/service-cellular/ServiceCellular.cpp b/module-services/service-cellular/ServiceCellular.cpp index 3dfbe4791..ea0eb821f 100644 --- a/module-services/service-cellular/ServiceCellular.cpp +++ b/module-services/service-cellular/ServiceCellular.cpp @@ -152,18 +152,42 @@ sys::Message_t ServiceCellular::DataReceivedHandler(sys::DataMessage *msgl) { break; case MessageType::CellularStartPowerUpProcedure: { - if (muxdaemon->PowerUpProcedure() != MuxDaemon::ConfState::Success) { + auto powerRet = muxdaemon->PowerUpProcedure(); + if (powerRet == MuxDaemon::ConfState::Success) { + sys::Bus::SendUnicast(std::make_shared(MessageType::CellularStartConfProcedure), + GetName(), this); + } + else if(powerRet == MuxDaemon::ConfState::PowerUp){ + state = State::PowerUpInProgress; + } + else{ LOG_FATAL("[ServiceCellular] PowerUp procedure failed"); state = State::Failed; - }else{ - state = State::PowerUpInProgress; } } break; case MessageType::CellularStartConfProcedure: { // Start configuration procedure, if it's first run modem will be restarted - if (muxdaemon->ConfProcedure() == MuxDaemon::ConfState::Success) { + auto confRet = muxdaemon->ConfProcedure(); + if (confRet == MuxDaemon::ConfState::Success) { + sys::Bus::SendUnicast(std::make_shared(MessageType::CellularStartAudioConfProcedure), + GetName(), this); + state = State::AudioConfigurationInProgress; + } + else { + LOG_FATAL("[ServiceCellular] Initialization failed, not ready"); + state = State::Failed; + } + } + break; + + case MessageType ::CellularStartAudioConfProcedure: + { + auto audioRet = muxdaemon->AudioConfProcedure(); + if(audioRet == MuxDaemon::ConfState::Success){ + + muxdaemon->StartMultiplexer(); LOG_DEBUG("[ServiceCellular] Modem is fully operational"); state = State::Ready; @@ -171,13 +195,17 @@ sys::Message_t ServiceCellular::DataReceivedHandler(sys::DataMessage *msgl) { sys::Bus::SendMulticast(std::make_shared( static_cast(NotificationType::ServiceReady)), sys::BusChannels::ServiceCellularNotifications, this); - - }else { - LOG_FATAL("[ServiceCellular] Initialization failed, not ready"); - state = State::Failed; + } + else if(audioRet == MuxDaemon::ConfState::Failure){ + sys::Bus::SendUnicast(std::make_shared(MessageType::CellularStartAudioConfProcedure), + GetName(), this); + } + else{ + // Reset procedure started, do nothing here + state = State::PowerUpInProgress; } } - break; + break; case MessageType::CellularListCurrentCalls: { auto ret = muxdaemon->SendCommandResponse(MuxChannel::MuxChannelType::Communication, "AT+CLCC\r", 3); diff --git a/module-services/service-cellular/ServiceCellular.hpp b/module-services/service-cellular/ServiceCellular.hpp index f91de66ab..6023514cb 100644 --- a/module-services/service-cellular/ServiceCellular.hpp +++ b/module-services/service-cellular/ServiceCellular.hpp @@ -25,6 +25,7 @@ public: Idle, PowerUpInProgress, ModemConfigurationInProgress, + AudioConfigurationInProgress, Ready, Failed }; diff --git a/source/MessageType.hpp b/source/MessageType.hpp index 4276bd3b3..20403d553 100644 --- a/source/MessageType.hpp +++ b/source/MessageType.hpp @@ -54,6 +54,7 @@ enum class MessageType { CellularListCurrentCalls, CellularStartPowerUpProcedure, CellularStartConfProcedure, + CellularStartAudioConfProcedure, //Audio service messages AudioNotification,