~aleteoryx/muditaos

ref: 7f2b7b45dfde24b5afab0919fdbc288dcd9537b0 muditaos/module-cellular/at/Commands.hpp -rw-r--r-- 10.5 KiB
7f2b7b45 — Radoslaw Wicik [EGD-4221] Convert service-time to library 5 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

/// This file goal is to provide one place to store all at commands, with their respectable timeouts if these have

#include "Result.hpp"
#include <log/log.hpp>
#include <map>
#include <memory>
#include <string>

namespace at
{
    inline const uint32_t default_timeout = 5000; /// if unsure - take this
    inline const uint32_t default_doc_timeout =
        300; /// if you've checked it's ok - or it was at least 300 in code somewhere, take this

    /// at::Cmd structure with command, it's timeout and some runtime data
    /// { command, timeout, last : {sent, response, status } }
    struct Cmd
    {
        std::string cmd;                    /// command to run
        uint32_t timeout = default_timeout; /// timeout for this command
        struct
        {
            Result::Code status = Result::Code::NONE; /// last response for that command
            time_t requested    = 0;                  /// last time comand was requested
            time_t response     = 0;                  /// last time command was received
            auto request_time() -> time_t
            {
                return response - requested;
            }   /// time it took to send command and get response
        } last; /// last status of command execution

        Cmd(std::string cmd, uint32_t timeout = default_timeout) : cmd(std::move(cmd)), timeout(timeout)
        {}
        /// not the prettiest, for now it's ok - for commands which modify strings to execute - return copy of command
        /// str
        operator std::string() const
        {
            return cmd;
        }
        auto operator+(const std::string &val) const -> Cmd
        {
            Cmd tmp = *this;
            tmp.cmd += val;
            return tmp;
        }
    };

    /// doc is: per Quectel_EC25&EC21_AT_Commands_Manual_V1.3.pdf
    enum class AT
    {
        AT,
        ECHO_OFF,
        FACTORY_RESET,
        SW_INFO,
        FLOW_CTRL_ON,
        FLOW_CTRL_OFF,
        URC_NOTIF_CHANNEL,          /// Route URCs to second (Notifications) MUX channel
        RI_PIN_AUTO_CALL,           /// Turn on RI pin for incoming calls
        RI_PIN_OFF_CALL,            /// Turn off RI pin for incoming calls
        RI_PIN_PULSE_SMS,           /// Turn on RI pin for incoming sms
        RI_PIN_OFF_SMS,             /// Turn off RI pin for incoming sms
        RI_PIN_OFF_OTHER,           /// Turn off RI pin for other URCs
        URC_DELAY_ON,               /// Enable delay the output of URC indication until ring indicator pulse ends
        URC_UART1,                  /// Route URCs to UART1
        AT_PIN_READY_LOGIC,         /// Configure AP_Ready pin logic ( enable, logic level 1, 200ms )
        URC_NOTIF_SIGNAL,           /// Turn on signal strength change URC
        CRC_ON,                     /// Change incoming call notification from "RING" to "+CRING:type"
        CALLER_NUMBER_PRESENTATION, /// Turn on caller's number presentation
        SMS_TEXT_FORMAT,            /// Set Message format to Text
        SMS_UCSC2,                  /// Set ucs2 message format
        SMS_GSM,                    /// Set gsm message format
        QSCLK_ON,                   /// Configure Whether or Not to Enter into Sleep Mode
        QDAI,                       /// GSM audio initialization check
        QDAI_INIT, /// Audio configuration: custom PCM, 16 bit linear samples, primary mode, 16kHz, master
                   /// Quectel confirmed that during init phase modem sends "ready notification" way before
                   /// audio subsystem is initialized. The only recommended solution for this is to send configuration
                   /// command repetitively until modem responds with OK. Due to our system characteristic we can't use
                   /// here simple while loop with vTaskDelay as this function will be invoked from AudioService
                   /// context. By design service's routines should be as fast as they can and non blocking. Therefore
                   /// there is possibility for audioservice to block for too long waiting in while loop which will
                   /// trigger SystemManager ping/pong failure procedure.
        SET_URC_CHANNEL,
        CSQ,  /// Signal strength query
        CLCC, /// list current calls
        CMGD, /// remove SMS message from GSM memory
        CNUM, /// doc: the command can get the subscribers own number(s) from the (U)SI
        CIMI, /// Its getting IMSI from selected SIM card
        QCMGR,
        ATH,  /// hangup
        ATA,  /// (doc): timeout should be possibly set up to 90s
        ATD,  /// setup call
        IPR,  /// set baudrate
        CMUX, /// setup cmux params
        CFUN, /// set phone functionality
        CMGS, /// sms
        QCMGS,
        CREG,       /// network registration status
        QNWINFO,    /// network informations (band etc)
        COPS,       /// operators scan
        SIM_DET,    /// sim detection on/off status (1,0)
        QSIMSTAT,   /// sim insertion / removal notification in URC
        SIM_DET_ON, /// enable sim detection
        SIMSTAT_ON, /// enable sim stat urc
        SET_SCANMODE,
        GET_SCANMODE,
        QGMR,               /// ditailed firmware revision (as required by Quectel)
        STORE_SETTINGS_ATW, /// required to save in firmware ex SIMSTAT_ON
        CEER,               /// get error description from modem
        QIGETERROR,         /// get tcp/ip error code
        VTS,                /// DTMF and Tone Generation
        QLDTMF,             /// Play Local DTMF
        CUSD_OPEN_SESSION,
        CUSD_CLOSE_SESSION,
        CUSD_SEND,
        SET_SMS_STORAGE,
        CPIN,
        ENABLE_TIME_ZONE_UPDATE,
        SET_TIME_ZONE_REPORTING,
        DISABLE_TIME_ZONE_UPDATE,
        DISABLE_TIME_ZONE_REPORTING,
        ENABLE_NETWORK_REGISTRATION_URC,
        SET_SMS_TEXT_MODE_UCS2,
        CFUN_RESET,
        CFUN_MIN_FUNCTIONALITY,    /// Set minimum functionality
        CFUN_FULL_FUNCTIONALITY,   /// Full functionality
        CFUN_DISABLE_TRANSMITTING, /// Disable the ME from both transmitting and receiving RF signals
        LIST_MESSAGES,             /// List all messages from message storage
        GET_IMEI,
    };

    // below timeouts are defined in Quectel_EC25&EC21_AT_Commands_Manual_V1.3.pdf
    inline auto factory(AT at) -> const Cmd &
    {
        static const std::map<AT, const Cmd> fact{
            {AT::AT, {"AT", 100}},
            {AT::ECHO_OFF, {"ATE0"}},
            {AT::FACTORY_RESET, {"AT&F"}},
            {AT::SW_INFO, {"ATI\r", default_doc_timeout}},
            {AT::FLOW_CTRL_ON, {"AT+IFC=2,2\r\n", 500}},
            {AT::FLOW_CTRL_OFF, {"AT+IFC=0,0", 500}},
            {AT::URC_NOTIF_CHANNEL, {"AT+QCFG=\"cmux/urcport\",1"}},
            {AT::RI_PIN_AUTO_CALL, {"AT+QCFG=\"urc/ri/ring\",\"auto\""}},
            {AT::RI_PIN_OFF_CALL, {"AT+QCFG=\"urc/ri/ring\",\"off\""}},
            {AT::RI_PIN_PULSE_SMS, {"AT+QCFG=\"urc/ri/smsincoming\",\"pulse\",200"}},
            {AT::RI_PIN_OFF_SMS, {"AT+QCFG=\"urc/ri/smsincoming\",\"off\""}},
            {AT::RI_PIN_OFF_OTHER, {"AT+QCFG=\"urc/ri/other\",\"off\""}},
            {AT::URC_DELAY_ON, {"AT+QCFG=\"urc/delay\",1"}},
            {AT::URC_UART1, {"AT+QURCCFG=\"urcport\",\"uart1\""}},
            {AT::AT_PIN_READY_LOGIC, {"AT+QCFG=\"apready\",1,1,200"}},
            {AT::URC_NOTIF_SIGNAL, {"AT+QINDCFG=\"csq\",1"}},
            {AT::CRC_ON, {"AT+CRC=1"}},
            {AT::CALLER_NUMBER_PRESENTATION, {"AT+CLIP=1", 18000}},
            {AT::SMS_TEXT_FORMAT, {"AT+CMGF=1"}},
            {AT::SMS_UCSC2, {"AT+CSCS=\"UCS2\""}},
            {AT::SMS_GSM, {"AT+CSCS=\"GSM\""}},
            {AT::QSCLK_ON, {"AT+QSCLK=1", 3000}},
            {AT::QDAI, {"AT+QDAI?"}},
            {AT::QDAI_INIT, {"AT+QDAI=1,0,0,5,0,1"}},
            {AT::SET_URC_CHANNEL, {"AT+QCFG=\"cmux/urcport\",2", default_doc_timeout}},
            {AT::CSQ, {"AT+CSQ", default_doc_timeout}},
            {AT::CLCC, {"AT+CLCC", default_doc_timeout}},
            {AT::CMGD, {"AT+CMGD=", default_doc_timeout}},
            {AT::CNUM, {"AT+CNUM"}},
            {AT::CIMI, {"AT+CIMI"}},
            {AT::QCMGR, {"AT+QCMGR=", 2000}},
            {AT::ATH, {"ATH"}},
            {AT::ATA, {"ATA", 90000}},
            {AT::ATD, {"ATD"}},
            {AT::IPR, {"AT+IPR="}},
            {AT::CMUX, {"AT+CMUX="}},
            {AT::CFUN, {"AT+CFUN=", 15000}},
            {AT::CFUN_RESET, {"AT+CFUN=1,1", 15000}},
            {AT::CFUN_MIN_FUNCTIONALITY, {"AT+CFUN=0", 15000}},
            {AT::CFUN_FULL_FUNCTIONALITY, {"AT+CFUN=1", 15000}},
            {AT::CFUN_DISABLE_TRANSMITTING, {"AT+CFUN=4", 15000}},
            {AT::CMGS, {"AT+CMGS=\""}},
            {AT::QCMGS, {"AT+QCMGS=\""}},
            {AT::CREG, {"AT+CREG?", default_doc_timeout}},
            {AT::QNWINFO, {"AT+QNWINFO"}},
            {AT::COPS, {"AT+COPS=?", 180000}},
            {AT::QSIMSTAT, {"AT+QSIMSTAT?"}},
            {AT::SIM_DET, {"AT+QSIMDET?"}},
            {AT::SIM_DET_ON, {"AT+QSIMDET=1,0"}},
            {AT::SIMSTAT_ON, {"AT+QSIMSTAT=1"}},
            {AT::SET_SCANMODE, {"AT+QCFG=\"nwscanmode\","}},
            {AT::GET_SCANMODE, {"AT+QCFG=\"nwscanmode\""}},
            {AT::QGMR, {"AT+QGMR"}},
            {AT::STORE_SETTINGS_ATW, {"AT&W"}},
            {AT::CEER, {"AT+CEER"}},
            {AT::QIGETERROR, {"AT+QIGETERROR"}},
            {AT::VTS, {"AT+VTS="}},
            {AT::QLDTMF, {"AT+QLDTMF=1,"}},
            {AT::CUSD_OPEN_SESSION, {"AT+CUSD=1"}},
            {AT::CUSD_CLOSE_SESSION, {"AT+CUSD=2"}},
            {AT::CUSD_SEND, {"AT+CUSD=1,"}},
            {AT::SET_SMS_STORAGE, {"AT+CPMS=\"SM\",\"SM\",\"SM\"", 300}},
            {AT::CPIN, {"AT+CPIN="}},
            {AT::ENABLE_TIME_ZONE_UPDATE, {"AT+CTZU=3"}},
            {AT::SET_TIME_ZONE_REPORTING, {"AT+CTZR=2"}},
            {AT::DISABLE_TIME_ZONE_UPDATE, {"AT+CTZU=0"}},
            {AT::DISABLE_TIME_ZONE_REPORTING, {"AT+CTZR=0"}},
            {AT::ENABLE_NETWORK_REGISTRATION_URC, {"AT+CREG=2"}},
            {AT::SET_SMS_TEXT_MODE_UCS2, {"AT+CSMP=17,167,0,8"}},
            {AT::LIST_MESSAGES, {"AT+CMGL=\"ALL\"", default_doc_timeout}},
            {AT::GET_IMEI, {"AT+GSN", default_doc_timeout}}};

        if (fact.count(at)) {
            return fact.at(at);
        }
        LOG_ERROR("NO SUCH AT COMMAND DEFINED: %d", static_cast<int>(at));
        return fact.at(AT::AT);
    }
    enum class commadsSet
    {
        modemInit,
        simInit,
        smsInit
    };
    std::vector<AT> getCommadsSet(commadsSet set);
}; // namespace at