mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-10-25 07:58:29 -04:00
WiP: Added URC support to ATParser
This commit is contained in:
1 parent
f543aee9a6
commit
fb2c58f0c2
6 files changed
+107
-31
No files matched your search
@@ -100,6 +100,9 @@ namespace bsp {
|
||||
if ((ret == -1) && (errno == EINTR)) {
|
||||
goto retry;
|
||||
}
|
||||
else if(errno){
|
||||
LOG_DEBUG("Read errno: %s",strerror(errno));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "bsp/cellular/bsp_cellular.hpp"
|
||||
#include "ticks.hpp"
|
||||
#include "InOutSerialWorker.hpp"
|
||||
#include "MuxDaemon.hpp"
|
||||
|
||||
std::optional<std::unique_ptr<ATParser>>
|
||||
ATParser::Create(MuxDaemon *mux, InOutSerialWorker *inOutSerial, bsp::Cellular *cellular) {
|
||||
@@ -25,10 +26,61 @@ ATParser::Create(MuxDaemon *mux, InOutSerialWorker *inOutSerial, bsp::Cellular *
|
||||
}
|
||||
}
|
||||
|
||||
ATParser::ATParser(MuxDaemon *mux, InOutSerialWorker *inOutSerial, bsp::Cellular *cellular) : mux(mux),inOutSerialWorker(inOutSerial),cellular(cellular) {
|
||||
ATParser::ATParser(MuxDaemon *mux, InOutSerialWorker *inOutSerial, bsp::Cellular *cellular) : mux(mux),
|
||||
inOutSerialWorker(
|
||||
inOutSerial),
|
||||
cellular(cellular) {
|
||||
isInitialized = true;
|
||||
}
|
||||
|
||||
std::vector<ATParser::Urc> ATParser::ParseURC() {
|
||||
|
||||
std::vector<ATParser::Urc> resp;
|
||||
size_t maxPos = 0;
|
||||
|
||||
cpp_freertos::LockGuard lock(mutex);
|
||||
|
||||
|
||||
auto pos = responseBuffer.find("RDY");
|
||||
if (pos != std::string::npos) {
|
||||
resp.push_back(ATParser::Urc::MeInitializationSuccessful);
|
||||
maxPos = std::max(pos + strlen("RDY"), maxPos);
|
||||
}
|
||||
|
||||
pos = responseBuffer.find("+CFUN: 1");
|
||||
if (pos != std::string::npos) {
|
||||
resp.push_back(ATParser::Urc::FullFuncionalityAvailable);
|
||||
maxPos = std::max(pos + strlen("+CFUN: 1"), maxPos);
|
||||
}
|
||||
pos = responseBuffer.find("+CPIN: READY");
|
||||
if (pos != std::string::npos) {
|
||||
resp.push_back(ATParser::Urc::SimCardReady);
|
||||
maxPos = std::max(pos + strlen("+CPIN: READY"), maxPos);
|
||||
}
|
||||
|
||||
pos = responseBuffer.find("+QIND: SMS DONE");
|
||||
if (pos != std::string::npos) {
|
||||
resp.push_back(ATParser::Urc::SMSInitializationComplete);
|
||||
maxPos = std::max(pos + strlen("+QIND: SMS DONE"), maxPos);
|
||||
}
|
||||
|
||||
pos = responseBuffer.find("+QIND: PB DONE");
|
||||
if (pos != std::string::npos) {
|
||||
resp.push_back(ATParser::Urc::PhonebookInitializationComplete);
|
||||
maxPos = std::max(pos + strlen("+QIND: PB DONE"), maxPos);
|
||||
}
|
||||
|
||||
// manage string buffer
|
||||
if(responseBuffer.size() >= maxPos){
|
||||
responseBuffer.erase();
|
||||
}
|
||||
else{
|
||||
responseBuffer = responseBuffer.substr(maxPos);
|
||||
}
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
int ATParser::ProcessNewData() {
|
||||
char rawBuffer[256] = {0};
|
||||
|
||||
@@ -41,8 +93,17 @@ int ATParser::ProcessNewData() {
|
||||
}
|
||||
// Received response data without active request, drop it
|
||||
else {
|
||||
responseBuffer.erase();
|
||||
LOG_INFO("Received unneeded data");
|
||||
urcs = ParseURC();
|
||||
// GSM modem is considered as fully operational when it outputs URCs specified below:
|
||||
// 1) RDY
|
||||
// 2) +CFUN: 1
|
||||
// 3) +CPIN: READY
|
||||
// 4) +QIND: SMS DONE
|
||||
// 5) +QIND: PB DONE
|
||||
if(urcs.size() == 5){
|
||||
mux->StartMultiplexer();
|
||||
}
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -79,13 +140,12 @@ std::vector<std::string> ATParser::SendCommand(const char *cmd, size_t rxCount,
|
||||
if (tokens.size() < rxCount) {
|
||||
goto wait_for_data;
|
||||
}
|
||||
blockedTaskHandle = nullptr;
|
||||
return tokens;
|
||||
} else {
|
||||
//timeout
|
||||
blockedTaskHandle = nullptr;
|
||||
return tokens;
|
||||
|
||||
}
|
||||
|
||||
blockedTaskHandle = nullptr;
|
||||
responseBuffer.erase(); // TODO:M.P is it okay to flush buffer here ?
|
||||
return tokens;
|
||||
}
|
||||
|
||||
std::vector<std::string> ATParser::Tokenizer(std::string &input, uint32_t maxTokenCount,
|
||||
|
||||
@@ -31,6 +31,16 @@ class InOutSerialWorker;
|
||||
|
||||
class ATParser {
|
||||
public:
|
||||
|
||||
enum class Urc{
|
||||
MeInitializationSuccessful,
|
||||
FullFuncionalityAvailable,
|
||||
SimCardReady,
|
||||
SMSInitializationComplete,
|
||||
PhonebookInitializationComplete
|
||||
|
||||
};
|
||||
|
||||
static std::optional<std::unique_ptr<ATParser>> Create(MuxDaemon* mux,InOutSerialWorker* inOutSerial,bsp::Cellular* cellular);
|
||||
|
||||
ATParser(MuxDaemon* mux,InOutSerialWorker* inOutSerial,bsp::Cellular* cellular);
|
||||
@@ -43,6 +53,8 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
std::vector<Urc> ParseURC();
|
||||
|
||||
MuxDaemon* mux = nullptr;
|
||||
InOutSerialWorker* inOutSerialWorker = nullptr;
|
||||
bsp::Cellular* cellular = nullptr;
|
||||
@@ -52,6 +64,8 @@ private:
|
||||
TaskHandle_t blockedTaskHandle = nullptr;
|
||||
cpp_freertos::MutexStandard mutex;
|
||||
|
||||
std::vector<ATParser::Urc> urcs;
|
||||
|
||||
bool isInitialized = false;
|
||||
|
||||
|
||||
|
||||
@@ -71,7 +71,10 @@ void workerTaskFunction(void *ptr) {
|
||||
InOutSerialWorker *inst = reinterpret_cast<InOutSerialWorker *>(ptr);
|
||||
|
||||
while (1) {
|
||||
inst->cellular->Wait(UINT32_MAX);
|
||||
auto ret = inst->cellular->Wait(UINT32_MAX);
|
||||
if(ret == 0){
|
||||
continue;
|
||||
}
|
||||
|
||||
// AT mode is used only during initialization phase
|
||||
if (inst->mode == InOutSerialWorker::Mode::AT) {
|
||||
|
||||
@@ -83,7 +83,7 @@ MuxDaemon::MuxDaemon(NotificationMuxChannel::NotificationCallback_t callback) :
|
||||
}
|
||||
|
||||
MuxDaemon::~MuxDaemon() {
|
||||
CloseMux();
|
||||
CloseMultiplexer();
|
||||
}
|
||||
|
||||
std::unique_ptr<MuxDaemon> MuxDaemon::Create(NotificationMuxChannel::NotificationCallback_t callback) {
|
||||
@@ -127,39 +127,32 @@ bool MuxDaemon::Start() {
|
||||
inOutSerialDataWorker->SendFrame(0, closeChannelCmd, sizeof(closeChannelCmd),
|
||||
static_cast<unsigned char>(MuxDefines::GSM0710_TYPE_UIH));
|
||||
|
||||
vTaskDelay(500); // give modem some time to establish mux
|
||||
|
||||
// Try sending AT command once again
|
||||
ret = inOutSerialDataWorker->SendATCommand("AT\r",2, 500);
|
||||
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 StartMultiplexer();
|
||||
}
|
||||
else{
|
||||
LOG_INFO("Starting power up procedure...");
|
||||
// If no response, power up modem and try again
|
||||
//TODO:M.P implement it cellular->PowerUp();
|
||||
uint32_t retries = 20;
|
||||
while (--retries) {
|
||||
ret = inOutSerialDataWorker->SendATCommand("AT\r", 500);
|
||||
if ( ret.size() == 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (retries == 0) {
|
||||
LOG_FATAL("No communication with GSM modem");
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if ((ret.size() == 1 && ret[0] == "OK\r\n") || (ret.size() == 2 && ret[0] == "AT\r\n" && ret[1] == "OK\r\n")){
|
||||
return StartMultiplexer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool MuxDaemon::StartMultiplexer() {
|
||||
|
||||
// Factory reset
|
||||
inOutSerialDataWorker->SendATCommand("AT&F\r", 1);
|
||||
|
||||
// Turn off local echo
|
||||
inOutSerialDataWorker->SendATCommand("ATE0\r", 2);
|
||||
|
||||
// Factory reset
|
||||
inOutSerialDataWorker->SendATCommand("AT&F\r", 1);
|
||||
|
||||
// Set up modem configuration
|
||||
if (hardwareControlFlowEnable) {
|
||||
@@ -225,7 +218,7 @@ bool MuxDaemon::Start() {
|
||||
}
|
||||
|
||||
|
||||
int MuxDaemon::CloseMux() {
|
||||
int MuxDaemon::CloseMultiplexer() {
|
||||
|
||||
// Virtual channels need to be deinitialized in reversed order i.e control channel should be closed at the end
|
||||
for (auto w = channels.size(); --w;) {
|
||||
|
||||
@@ -38,6 +38,7 @@ public:
|
||||
* Multiplexer states
|
||||
*/
|
||||
enum class States {
|
||||
MUX_STATE_POWERUP,
|
||||
MUX_STATE_OPENING,
|
||||
MUX_STATE_INITILIZING,
|
||||
MUX_STATE_MUXING,
|
||||
@@ -62,6 +63,8 @@ public:
|
||||
void RemoveMuxChannel(MuxChannel::MuxChannelType chan);
|
||||
|
||||
|
||||
bool StartMultiplexer();
|
||||
|
||||
int uihPfBitReceived = 0;
|
||||
|
||||
private:
|
||||
@@ -70,7 +73,7 @@ private:
|
||||
|
||||
bool Start();
|
||||
|
||||
int CloseMux();
|
||||
int CloseMultiplexer();
|
||||
|
||||
|
||||
constexpr static unsigned char closeChannelCmd[] = {
|
||||
|
||||
Reference in new issue
Block a user