WiP: Added URC support to ATParser

This commit is contained in:
Mati committed 2019-07-17 16:26:59 +02:00
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;
}
+69 -9
View File
@@ -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,
+14
View File
@@ -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;
+4 -1
View File
@@ -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) {
+13 -20
View File
@@ -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;) {
+4 -1
View File
@@ -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[] = {