Mistake on this page?
Report an issue in GitHub or email us
ATHandler.h
1 /*
2  * Copyright (c) 2017, Arm Limited and affiliates.
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef AT_HANDLER_H_
19 #define AT_HANDLER_H_
20 
21 #include "platform/mbed_retarget.h"
22 #include "platform/mbed_chrono.h"
23 
24 #include "events/EventQueue.h"
25 #include "netsocket/nsapi_types.h"
26 
27 #include "Callback.h"
28 #include "rtos/Kernel.h"
29 
30 #include <cstdarg>
31 
32 #include "drivers/BufferedSerial.h"
33 
34 /**
35  * If application calls associated FileHandle only from single thread context
36  * then locking between AT command and response is not needed. However,
37  * note that many cellular functions are called indirectly, for example with the socket API.
38  * If you are unsure, then AT_HANDLER_MUTEX must be defined.
39  */
40 #define AT_HANDLER_MUTEX
41 
42 #if defined AT_HANDLER_MUTEX && defined MBED_CONF_RTOS_PRESENT
43 #include "rtos/ConditionVariable.h"
44 #endif
45 
46 namespace mbed {
47 
48 class FileHandle;
49 
50 extern const char *OK;
51 extern const char *CRLF;
52 
53 /* AT Error types enumeration */
54 enum DeviceErrorType {
55  DeviceErrorTypeNoError = 0,
56  DeviceErrorTypeError, // AT ERROR
57  DeviceErrorTypeErrorCMS, // AT ERROR CMS
58  DeviceErrorTypeErrorCME // AT ERROR CME
59 };
60 
61 /** AT response error with error code and type */
62 struct device_err_t {
63  DeviceErrorType errType;
64  int errCode;
65 };
66 
67 /// Class for sending AT commands and parsing AT responses.
68 class ATHandler {
69 
70 public:
71  /** Constructor
72  *
73  * @param fh file handle used for reading AT responses and writing AT commands
74  * @param queue Event queue used to transfer sigio events to this thread
75  * @param timeout Timeout when reading for AT response
76  * @param output_delimiter delimiter used when parsing at responses, "\r" should be used as output_delimiter
77  * @param send_delay the minimum delay in ms between the end of last response and the beginning of a new command
78  */
79  ATHandler(FileHandle *fh, events::EventQueue &queue, uint32_t timeout, const char *output_delimiter, uint16_t send_delay = 0);
80 
81  /** Constructor
82  *
83  * @param fh file handle used for reading AT responses and writing AT commands
84  * @param queue Event queue used to transfer sigio events to this thread
85  * @param timeout Timeout when reading for AT response
86  * @param output_delimiter delimiter used when parsing at responses, "\r" should be used as output_delimiter
87  * @param send_delay the minimum delay in ms between the end of last response and the beginning of a new command
88  */
89  ATHandler(FileHandle *fh, events::EventQueue &queue, mbed::chrono::milliseconds_u32 timeout, const char *output_delimiter, std::chrono::duration<uint16_t, std::milli> send_delay = std::chrono::milliseconds(0));
90 
91  ~ATHandler();
92 
93  /** Return used file handle.
94  *
95  * @return used file handle
96  */
97  FileHandle *get_file_handle();
98 
99  /** Locks the mutex for file handle if AT_HANDLER_MUTEX is defined.
100  */
101  void lock();
102 
103  /** Unlocks the mutex for file handle if AT_HANDLER_MUTEX is defined.
104  */
105  void unlock();
106 
107  /** Locks the mutex for file handle if AT_HANDLER_MUTEX is defined and returns the last error.
108  *
109  * @return last error that happened when parsing AT responses
110  */
111  nsapi_error_t unlock_return_error();
112 
113  /** Set callback function for URC
114  *
115  * @param prefix URC text to look for, e.g. "+CMTI:". Maximum length is MBED_CONF_CELLULAR_AT_HANDLER_BUFFER_SIZE.
116  * @param callback function to call on prefix, or 0 to remove callback
117  */
118  void set_urc_handler(const char *prefix, Callback<void()> callback);
119 
120  /** returns the last error while parsing AT responses.
121  *
122  * @return last error
123  */
124  nsapi_error_t get_last_error() const;
125 
126  /** returns the last device error while parsing AT responses. Actually AT error (CME/CMS).
127  *
128  * @return last error struct device_err_t
129  */
130  device_err_t get_last_device_error() const;
131 
132  /** Set timeout in milliseconds for AT commands
133  *
134  * @param timeout_milliseconds Timeout in milliseconds
135  * @param default_timeout Store as default timeout
136  */
137  void set_at_timeout(uint32_t timeout_milliseconds, bool default_timeout = false);
138 
139  /** Set timeout in milliseconds for AT commands
140  *
141  * @param timeout Timeout in milliseconds
142  * @param default_timeout Store as default timeout
143  */
144  void set_at_timeout(mbed::chrono::milliseconds_u32 timeout, bool default_timeout = false);
145 
146  /** Restore timeout to previous timeout. Handy if there is a need to change timeout temporarily.
147  */
148  void restore_at_timeout();
149 
150  /** Clear pending error flag. By default, error is cleared only in lock().
151  */
152  void clear_error();
153 
154  /**
155  * Flushes the underlying stream
156  */
157  void flush();
158 
159  /** Tries to find oob's from the AT response. Call the urc callback if one is found.
160  */
161  void process_oob();
162 
163  /** Set is file handle usable. Some situations like after going to data mode, file handle is not usable anymore.
164  * Any items in queue are not to be processed.
165  *
166  * @param usable true for usable filehandle
167  */
168  void set_is_filehandle_usable(bool usable);
169 
170  /** Synchronize AT command and response handling to modem.
171  *
172  * @param timeout_ms ATHandler timeout when trying to sync. Will be restored when function returns.
173  * @return true is synchronization was successful, false in case of failure
174  */
175  bool sync(int timeout_ms);
176 
177  /** Synchronize AT command and response handling to modem.
178  *
179  * @param timeout ATHandler timeout when trying to sync. Will be restored when function returns.
180  * @return true is synchronization was successful, false in case of failure
181  */
182  bool sync(std::chrono::duration<int, std::milli> timeout);
183 
184  /** Sets the delay to be applied before sending any AT command.
185  *
186  * @param send_delay the minimum delay in ms between the end of last response and the beginning of a new command
187  */
188  void set_send_delay(uint16_t send_delay);
189 
190  /** Sets BufferedSerial filehandle to given baud rate
191  *
192  * @param baud_rate
193  */
194  void set_baud(int baud_rate);
195 
196  /** Starts the command writing by clearing the last error and writing the given command.
197  * In case of failure when writing, the last error is set to NSAPI_ERROR_DEVICE_ERROR.
198  *
199  * @param cmd AT command to be written to modem
200  */
201  void cmd_start(const char *cmd);
202 
203  /**
204  * @brief cmd_start_stop Starts an AT command, writes given variadic arguments and stops the command. Use this
205  * command when you need multiple response parameters to be handled.
206  * NOTE: Does not lock ATHandler for process!
207  *
208  * @param cmd AT command in form +<CMD> (will be used also in response reading, no extra chars allowed)
209  * @param cmd_chr Char to be added to specific AT command: '?', '=' or ''. Will be used as such so '=1' is valid as well.
210  * @param format Format string for variadic arguments to be added to AT command; No separator needed.
211  * Use %d for integer, %s for string and %b for byte string (requires 2 arguments: string and length)
212  */
213  void cmd_start_stop(const char *cmd, const char *cmd_chr, const char *format = "", ...);
214 
215  /**
216  * @brief at_cmd_str Send an AT command and read a single string response. Locks and unlocks ATHandler for operation
217  * @param cmd AT command in form +<CMD> (will be used also in response reading, no extra chars allowed)
218  * @param cmd_chr Char to be added to specific AT command: '?', '=' or ''. Will be used as such so '=1' is valid as well.
219  * @param resp_buf Response buffer
220  * @param resp_buf_size Response buffer size
221  * @param format Format string for variadic arguments to be added to AT command; No separator needed.
222  * Use %d for integer, %s for string and %b for byte string (requires 2 arguments: string and length)
223  * @return last error that happened when parsing AT responses
224  */
225  nsapi_error_t at_cmd_str(const char *cmd, const char *cmd_chr, char *resp_buf, size_t resp_buf_size, const char *format = "", ...);
226 
227  /**
228  * @brief at_cmd_int Send an AT command and read a single integer response. Locks and unlocks ATHandler for operation
229  * @param cmd AT command in form +<CMD> (will be used also in response reading, no extra chars allowed)
230  * @param cmd_chr Char to be added to specific AT command: '?', '=' or ''. Will be used as such so '=1' is valid as well.
231  * @param resp Integer to hold response
232  * @param format Format string for variadic arguments to be added to AT command; No separator needed.
233  * Use %d for integer, %s for string and %b for byte string (requires 2 arguments: string and length)
234  * @return last error that happened when parsing AT responses
235  */
236  nsapi_error_t at_cmd_int(const char *cmd, const char *cmd_chr, int &resp, const char *format = "", ...);
237 
238  /**
239  * @brief at_cmd_discard Send an AT command and read and discard a response. Locks and unlocks ATHandler for operation
240  * @param cmd AT command in form +<CMD> (will be used also in response reading, no extra chars allowed)
241  * @param cmd_chr Char to be added to specific AT command: '?', '=' or ''. Will be used as such so '=1' is valid as well.
242  * @param format Format string for variadic arguments to be added to AT command; No separator needed.
243  * Use %d for integer, %s for string and %b for byte string (requires 2 arguments: string and length)
244  * @return last error that happened when parsing AT responses
245  */
246  nsapi_error_t at_cmd_discard(const char *cmd, const char *cmd_chr, const char *format = "", ...);
247 
248  /** Writes integer type AT command subparameter. Starts with the delimiter if not the first param after cmd_start.
249  * In case of failure when writing, the last error is set to NSAPI_ERROR_DEVICE_ERROR.
250  *
251  * @param param int to be written to modem as AT command subparameter
252  */
253  void write_int(int32_t param);
254 
255  /** Writes string type AT command subparamater. Quotes are added to surround the given string.
256  * Starts with the delimiter if not the first param after cmd_start.
257  * In case of failure when writing, the last error is set to NSAPI_ERROR_DEVICE_ERROR.
258  *
259  * @param param string to be written to modem as AT command subparameter
260  * @param useQuotations flag indicating whether the string should be included in quotation marks
261  */
262  void write_string(const char *param, bool useQuotations = true);
263 
264  /** Stops the AT command by writing command-line terminator CR to mark command as finished.
265  */
266  void cmd_stop();
267 
268  /** Stops the AT command by writing command-line terminator CR to mark command as finished and reads the OK/ERROR response.
269  *
270  */
271  void cmd_stop_read_resp();
272 
273  /** Write bytes without any subparameter delimiters, such as comma.
274  * In case of failure when writing, the last error is set to NSAPI_ERROR_DEVICE_ERROR.
275  *
276  * @param data bytes to be written to modem
277  * @param len length of data string
278  *
279  * @return number of characters successfully written
280  */
281  size_t write_bytes(const uint8_t *data, size_t len);
282 
283  /** Sets the stop tag for the current scope (response/information response/element)
284  * Parameter's reading routines will stop the reading when such tag is found and will set the found flag.
285  * Consume routines will read everything until such tag is found.
286  *
287  * @param stop_tag_seq string to be set as stop tag
288  */
289  void set_stop_tag(const char *stop_tag_seq);
290 
291  /** Sets the delimiter between parameters or between elements of the information response.
292  * Parameter's reading routines will stop when such char is read.
293  *
294  * @param delimiter char to be set as _delimiter
295  */
296  void set_delimiter(char delimiter);
297 
298  /** Sets the delimiter to default value defined by DEFAULT_DELIMITER.
299  */
300  void set_default_delimiter();
301 
302  /** Defines behaviour for using or ignoring the delimiter within an AT command
303  *
304  * @param use_delimiter indicating if delimiter should be used or not
305  */
306  void use_delimiter(bool use_delimiter);
307 
308  /** Consumes the reading buffer up to the delimiter or stop_tag
309  *
310  * @param count number of parameters to be skipped
311  */
312  void skip_param(uint32_t count = 1);
313 
314  /** Consumes the given length from the reading buffer
315  *
316  * @param len length to be consumed from reading buffer
317  * @param count number of parameters to be skipped
318  */
319  void skip_param(ssize_t len, uint32_t count);
320 
321  /** Reads given number of bytes from receiving buffer without checking any subparameter delimiters, such as comma.
322  *
323  * @param buf output buffer for the read
324  * @param len maximum number of bytes to read
325  * @return number of successfully read bytes or -1 in case of error
326  */
327  ssize_t read_bytes(uint8_t *buf, size_t len);
328 
329  /** Reads chars from reading buffer. Terminates with null. Skips the quotation marks.
330  * Stops on delimiter or stop tag.
331  *
332  * @param str output buffer for the read
333  * @param size maximum number of chars to output including NULL
334  * @param read_even_stop_tag if true then try to read even if the stop tag was found previously
335  * @return length of output string or -1 in case of read timeout before delimiter or stop tag is found
336  */
337  ssize_t read_string(char *str, size_t size, bool read_even_stop_tag = false);
338 
339  /** Reads chars representing hex ascii values and converts them to the corresponding chars.
340  * For example: "4156" to "AV".
341  * Terminates with null. Skips the quotation marks.
342  * Stops on delimiter or stop tag.
343  *
344  * @param str output buffer for the read
345  * @param size maximum number of chars to output
346  * @return length of output string or -1 in case of read timeout before delimiter or stop tag is found
347  */
348  ssize_t read_hex_string(char *str, size_t size);
349 
350  /** Converts contained chars to their hex ascii value and writes the resulting string to the file handle
351  * For example: "AV" to "4156".
352  *
353  * @param str input buffer to be converted to hex ascii
354  * @param size of the input param str
355  * @param quote_string if true it will add the double-quote character at beginning and end of string
356  */
357  void write_hex_string(const char *str, size_t size, bool quote_string = true);
358 
359  /** Reads as string and converts result to integer. Supports only non-negative integers.
360  *
361  * @return the non-negative integer or -1 in case of error.
362  */
363  int32_t read_int();
364 
365  /** This looks for necessary matches: prefix, OK, ERROR, URCs and sets the correct scope.
366  *
367  * @param prefix string to be matched from receiving buffer. If not NULL and match succeeds, then scope
368  * will be set as information response(info_type)
369  * @param stop flag to indicate if we go to information response scope or not.
370  * (needed when nothing is expected to be received anymore after the prefix match:
371  * sms case: "> ", bc95 reboot case)
372  */
373  void resp_start(const char *prefix = NULL, bool stop = false);
374 
375  /** Ends all scopes starting from current scope.
376  * Consumes everything until the scope's stop tag is found, then
377  * goes to next scope until response scope is ending.
378  * URC match is checked during response scope ending,
379  * for every new line / CRLF.
380  *
381  *
382  * Possible sequence:
383  * element scope -> information response scope -> response scope
384  */
385  void resp_stop();
386 
387  /** Looks for matching the prefix given to resp_start() call.
388  * If needed, it ends the scope of a previous information response.
389  * Sets the information response scope if new prefix is found and response scope if prefix is not found.
390  *
391  * @return true if prefix defined for information response is not empty string and is found,
392  * false otherwise.
393  */
394  bool info_resp();
395 
396  /** Looks for matching the start tag.
397  * If needed, it ends the scope of a previous element.
398  * Sets the element scope if start tag is found and information response scope if start tag is not found.
399  *
400  * @param start_tag tag to be matched to begin parsing an element of an information response
401  * @return true if new element is found, false otherwise
402  */
403  bool info_elem(char start_tag);
404 
405  /** Consumes the received content until current stop tag is found.
406  *
407  * @return true if stop tag is found, false otherwise
408  */
409  bool consume_to_stop_tag();
410 
411  /** Return the last 3GPP error code.
412  * @return last 3GPP error code
413  */
414  int get_3gpp_error();
415 
416 public: // just for debugging
417  /**
418  * AT debugging, when enabled will print all data read and written,
419  * non-printable chars are printed as "[%d]".
420  *
421  * AT debug can be enabled at compile time using MBED_CONF_CELLULAR_DEBUG_AT flag or at runtime
422  * calling set_debug(). Note that MBED_CONF_MBED_TRACE_ENABLE must also be enabled.
423  *
424  * @param debug_on Enable/disable debugging
425  */
426  void set_debug(bool debug_on);
427 
428  /**
429  * Get degug state set by @ref set_debug
430  *
431  * @return current state of debug
432  */
433  bool get_debug() const;
434 
435 private: //Private structs & enums
436  struct tag_t {
437  char tag[7];
438  size_t len;
439  bool found;
440  };
441 
442  struct oob_t {
443  const char *prefix;
444  int prefix_len;
445  Callback<void()> cb;
446  oob_t *next;
447  };
448 
449  // resp_type: the part of the response that doesn't include the information response (+CMD1,+CMD2..)
450  // ends with OK or (CME)(CMS)ERROR
451  // info_type: the information response part of the response: starts with +CMD1 and ends with CRLF
452  // information response contains parameters or subsets of parameters (elements), both separated by comma
453  // elem_type: subsets of parameters that are part of information response, its parameters are separated by comma
454  enum ScopeType {
455  RespType,
456  InfoType,
457  ElemType,
458  NotSet
459  };
460 
461 private: //Private functions
462  void event();
463 
464  /** Increase reference count. Used for counting references to this instance.
465  * Note that this should be used with care, if the ATHandler was taken into use
466  * with get_instance()
467  */
468  void inc_ref_count();
469 
470  /** Decrease reference count. Used for counting references to this instance.
471  * Note that this should be used with care, if the ATHandler was taken into use
472  * with get_instance()
473  */
474  void dec_ref_count();
475 
476  /** Get the current reference count. Used for counting references to this instance.
477  *
478  * @return current reference count
479  */
480  int get_ref_count();
481 
482  /** Remove urc handler from linked list of urc's
483  *
484  * @param prefix Register urc prefix for callback. Urc could be for example "+CMTI: "
485  */
486  void remove_urc_handler(const char *prefix);
487 
488  void set_error(nsapi_error_t err);
489 
490  //Handles the arguments from given variadic list
491  void handle_args(const char *format, std::va_list list);
492 
493  //Starts an AT command based on given parameters
494  void handle_start(const char *cmd, const char *cmd_chr);
495 
496  //Checks that ATHandler does not have a pending error condition and filehandle is usable
497  bool ok_to_proceed();
498 
499  // Gets char from receiving buffer.
500  // Resets and fills the buffer if all are already read (receiving position equals receiving length).
501  // Returns a next char or -1 on failure (also sets error flag)
502  int get_char();
503  // Sets to 0 the reading position, reading length and the whole buffer content.
504  void reset_buffer();
505  // Reading position set to 0 and buffer's unread content moved to beginning
506  void rewind_buffer();
507  // Calculate remaining time for polling based on request start time and AT timeout.
508  // Returns 0 or time in ms for polling.
509  int poll_timeout(bool wait_for_timeout = true);
510  // Reads from serial to receiving buffer.
511  // Returns true on successful read OR false on timeout.
512  bool fill_buffer(bool wait_for_timeout = true);
513 
514  void set_tag(tag_t *tag_dest, const char *tag_seq);
515 
516  // Rewinds the receiving buffer and compares it against given str.
517  bool match(const char *str, size_t size);
518  // Iterates URCs and checks if they match the receiving buffer content.
519  // If URC match sets the scope to information response and after urc's cb returns
520  // finishes the information response scope(consumes to CRLF).
521  bool match_urc();
522  // Checks if any of the error strings are matching the receiving buffer content.
523  bool match_error();
524  // Checks if current char in buffer matches ch and consumes it,
525  // if no match lets the buffer unchanged.
526  bool consume_char(char ch);
527  // Consumes the received content until tag is found.
528  // Consumes the tag only if consume_tag flag is true.
529  bool consume_to_tag(const char *tag, bool consume_tag);
530  // Checks if receiving buffer contains OK, ERROR, URC or given prefix.
531  void resp(const char *prefix, bool check_urc);
532 
533  void set_scope(ScopeType scope_type);
534 
535  ScopeType get_scope();
536 
537  // Consumes to information response stop tag which is CRLF. Sets scope to response.
538  void information_response_stop();
539  // Consumes to element stop tag. Sets scope to information response
540  void information_response_element_stop();
541 
542  // Reads the error code if expected and sets it as last error.
543  void at_error(bool error_code, DeviceErrorType error_type);
544 
545  /** Convert AT error code to 3GPP error codes
546  * @param err AT error code read from CME/CMS ERROR responses
547  * @param error_type error type (CMS/CME/ERROR)
548  */
549  void set_3gpp_error(int err, DeviceErrorType error_type);
550 
551  bool check_cmd_send();
552  size_t write(const void *data, size_t len);
553 
554  /** Finds occurrence of one char buffer inside another char buffer.
555  *
556  * @param dest destination char buffer
557  * @param dest_len length of dest
558  * @param src string to be searched for
559  * @param src_len length of string to be searched for
560  *
561  * @return pointer to first occurrence of src in dest
562  */
563  const char *mem_str(const char *dest, size_t dest_len, const char *src, size_t src_len);
564 
565  // check is urc is already added
566  bool find_urc_handler(const char *prefix);
567 
568  // print contents of a buffer to trace log
569  enum ATType {
570  AT_ERR,
571  AT_RX,
572  AT_TX
573  };
574 
575  void debug_print(const char *p, int len, ATType type);
576 
577 private: //Member variables
578 
579 #if defined AT_HANDLER_MUTEX && defined MBED_CONF_RTOS_PRESENT
580  rtos::Mutex _fileHandleMutex;
582 #endif
583  FileHandle *_fileHandle;
584 
585  events::EventQueue &_queue;
586  nsapi_error_t _last_err;
587  int _last_3gpp_error;
588  device_err_t _last_at_err;
589  uint16_t _oob_string_max_length;
590  char *_output_delimiter;
591 
592  oob_t *_oobs;
593  mbed::chrono::milliseconds_u32 _at_timeout;
594  mbed::chrono::milliseconds_u32 _previous_at_timeout;
595 
596  std::chrono::duration<uint16_t, std::milli> _at_send_delay;
597  rtos::Kernel::Clock::time_point _last_response_stop;
598 
599  int32_t _ref_count;
600  bool _is_fh_usable;
601 
602  // should fit any prefix and int
603  char _recv_buff[MBED_CONF_CELLULAR_AT_HANDLER_BUFFER_SIZE];
604  // reading position
605  size_t _recv_len;
606  // reading length
607  size_t _recv_pos;
608 
609  ScopeType _current_scope;
610 
611  // tag to stop response scope
612  tag_t _resp_stop;
613  // tag to stop information response scope
614  tag_t _info_stop;
615  // tag to stop element scope
616  tag_t _elem_stop;
617  // reference to the stop tag of current scope (resp/info/elem)
618  tag_t *_stop_tag;
619 
620  // delimiter between parameters and also used for delimiting elements of information response
621  char _delimiter;
622  // set true on prefix match -> indicates start of an information response or of an element
623  bool _prefix_matched;
624  // set true on urc match
625  bool _urc_matched;
626  // set true on (CME)(CMS)ERROR
627  bool _error_found;
628  // Max length of OK,(CME)(CMS)ERROR and URCs
629  size_t _max_resp_length;
630 
631  // prefix set during resp_start and used to try matching possible information responses
632  char _info_resp_prefix[MBED_CONF_CELLULAR_AT_HANDLER_BUFFER_SIZE];
633  bool _debug_on;
634  bool _cmd_start;
635  bool _use_delimiter;
636 
637  // time when a command or an URC processing was started
638  rtos::Kernel::Clock::time_point _start_time;
639  // eventqueue event id
640  int _event_id;
641 
642  char _cmd_buffer[MBED_CONF_CELLULAR_AT_HANDLER_BUFFER_SIZE];
643 };
644 
645 } // namespace mbed
646 
647 #endif //AT_HANDLER_H_
EventQueue.
Definition: EventQueue.h:62
signed int nsapi_error_t
Type used to represent error codes.
Definition: nsapi_types.h:140
Class FileHandle.
Definition: FileHandle.h:46
Callback< R(ArgTs...)> callback(R(*func)(ArgTs...)=nullptr) noexcept
Create a callback class with type inferred from the arguments.
Definition: Callback.h:678
The Mutex class is used to synchronize the execution of threads.
Definition: Mutex.h:70
AT response error with error code and type.
Definition: ATHandler.h:62
The ConditionVariable class is a synchronization primitive that allows threads to wait until a partic...
Connected isochronous stream linked list.
Definition: lctr_int_cis.h:306
Callback class based on template specialization.
Definition: Callback.h:53
Definition: ATHandler.h:46
Class for sending AT commands and parsing AT responses.
Definition: ATHandler.h:68
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.