mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-01-24 13:58:00 -05:00
121 lines
3.6 KiB
C++
121 lines
3.6 KiB
C++
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
|
|
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
|
|
|
#include "ATCommon.hpp"
|
|
#include <functional>
|
|
#include <log/log.hpp>
|
|
#include <string>
|
|
#include <ticks.hpp>
|
|
#include <vector>
|
|
|
|
using namespace at;
|
|
|
|
const std::string Chanel::OK = "OK";
|
|
const std::string Chanel::ERROR = "ERROR";
|
|
const std::string Chanel::NO_CARRIER = "NO CARRIER";
|
|
const std::string Chanel::BUSY = "BUSY";
|
|
const std::string Chanel::NO_ANSWER = "NO ANSWER";
|
|
// const std::string Chanel::CONNECT = "CONNECT";
|
|
// const std::string Chanel::RING = "RING";
|
|
// const std::string Chanel::NO_DIALTONE = "NO DIALTONE";
|
|
|
|
Result::Code Chanel::at_check(const std::vector<std::string> &arr)
|
|
{
|
|
if (arr.size()) {
|
|
for (auto el : arr) {
|
|
if (el.compare(0, OK.length(), OK) == 0) {
|
|
return Result::Code::OK;
|
|
}
|
|
else if (el.compare(0, ERROR.length(), ERROR) == 0) {
|
|
return Result::Code::ERROR;
|
|
}
|
|
}
|
|
}
|
|
return Result::Code::NONE;
|
|
}
|
|
|
|
void Chanel::cmd_log(std::string cmd, const Result &result, uint32_t timeout)
|
|
{
|
|
|
|
cmd.erase(std::remove(cmd.begin(), cmd.end(), '\r'), cmd.end());
|
|
cmd.erase(std::remove(cmd.begin(), cmd.end(), '\n'), cmd.end());
|
|
switch (result.code) {
|
|
case Result::Code::TIMEOUT: {
|
|
LOG_ERROR("[AT]: >%s<, timeout %" PRIu32
|
|
" - please check the value with Quectel_EC25&EC21_AT_Commands_Manual_V1.3.pdf",
|
|
cmd.c_str(),
|
|
timeout);
|
|
} break;
|
|
case Result::Code::ERROR: {
|
|
|
|
LOG_ERROR("[AT]: >%s<, >%s<", cmd.c_str(), result.response.size() ? result.response.back().c_str() : "");
|
|
} break;
|
|
default:
|
|
LOG_DEBUG("[AT]: >%s<, >%s<", cmd.c_str(), result.response.size() ? result.response.back().c_str() : "");
|
|
break;
|
|
}
|
|
#if DEBUG_MODEM_OUTPUT_RESPONSE
|
|
for (auto s : result.response) {
|
|
LOG_DEBUG("[AT] > %s", s.c_str());
|
|
}
|
|
#endif
|
|
}
|
|
|
|
class Result Chanel::cmd(const std::string cmd, uint32_t timeout, size_t rxCount)
|
|
{
|
|
Result result;
|
|
blockedTaskHandle = xTaskGetCurrentTaskHandle();
|
|
|
|
cmd_init();
|
|
cmd_send(cmd);
|
|
|
|
uint32_t currentTime = cpp_freertos::Ticks::GetTicks();
|
|
uint32_t timeoutNeeded = ((timeout == UINT32_MAX) ? UINT32_MAX : currentTime + timeout);
|
|
uint32_t timeElapsed = currentTime;
|
|
|
|
while (1) {
|
|
if (timeoutNeeded != UINT32_MAX && timeElapsed >= timeoutNeeded) {
|
|
result.code = Result::Code::TIMEOUT;
|
|
break;
|
|
}
|
|
|
|
auto ret = ulTaskNotifyTake(pdTRUE, timeoutNeeded - timeElapsed);
|
|
timeElapsed = cpp_freertos::Ticks::GetTicks();
|
|
if (ret) {
|
|
std::vector<std::string> ret = cmd_receive();
|
|
|
|
result.response.insert(std::end(result.response), std::begin(ret), std::end(ret));
|
|
|
|
result.code = at_check(ret);
|
|
if (result.code != Result::Code::NONE) {
|
|
break;
|
|
}
|
|
if (rxCount != 0 && result.response.size() >= rxCount) {
|
|
result.code = Result::Code::TOKENS;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
blockedTaskHandle = nullptr;
|
|
cmd_post();
|
|
cmd_log(cmd, result, timeout);
|
|
|
|
return result;
|
|
}
|
|
|
|
auto Chanel::cmd(at::Cmd &at) -> Result
|
|
{
|
|
at.last.requested = cpp_freertos::Ticks::GetTicks();
|
|
Result result = this->cmd(at.cmd, at.timeout);
|
|
at.last.response = cpp_freertos::Ticks::GetTicks();
|
|
at.last.status = result.code;
|
|
return result;
|
|
}
|
|
|
|
auto Chanel::cmd(const at::AT at) -> Result
|
|
{
|
|
auto cmd = at::factory(at);
|
|
return this->cmd(cmd);
|
|
}
|