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  */
356  void write_hex_string(const char *str, size_t size);
357 
358  /** Reads as string and converts result to integer. Supports only non-negative integers.
359  *
360  * @return the non-negative integer or -1 in case of error.
361  */
362  int32_t read_int();
363 
364  /** This looks for necessary matches: prefix, OK, ERROR, URCs and sets the correct scope.
365  *
366  * @param prefix string to be matched from receiving buffer. If not NULL and match succeeds, then scope
367  * will be set as information response(info_type)
368  * @param stop flag to indicate if we go to information response scope or not.
369  * (needed when nothing is expected to be received anymore after the prefix match:
370  * sms case: "> ", bc95 reboot case)
371  */
372  void resp_start(const char *prefix = NULL, bool stop = false);
373 
374  /** Ends all scopes starting from current scope.
375  * Consumes everything until the scope's stop tag is found, then
376  * goes to next scope until response scope is ending.
377  * URC match is checked during response scope ending,
378  * for every new line / CRLF.
379  *
380  *
381  * Possible sequence:
382  * element scope -> information response scope -> response scope
383  */
384  void resp_stop();
385 
386  /** Looks for matching the prefix given to resp_start() call.
387  * If needed, it ends the scope of a previous information response.
388  * Sets the information response scope if new prefix is found and response scope if prefix is not found.
389  *
390  * @return true if prefix defined for information response is not empty string and is found,
391  * false otherwise.
392  */
393  bool info_resp();
394 
395  /** Looks for matching the start tag.
396  * If needed, it ends the scope of a previous element.
397  * Sets the element scope if start tag is found and information response scope if start tag is not found.
398  *
399  * @param start_tag tag to be matched to begin parsing an element of an information response
400  * @return true if new element is found, false otherwise
401  */
402  bool info_elem(char start_tag);
403 
404  /** Consumes the received content until current stop tag is found.
405  *
406  * @return true if stop tag is found, false otherwise
407  */
408  bool consume_to_stop_tag();
409 
410  /** Return the last 3GPP error code.
411  * @return last 3GPP error code
412  */
413  int get_3gpp_error();
414 
415 public: // just for debugging
416  /**
417  * AT debugging, when enabled will print all data read and written,
418  * non-printable chars are printed as "[%d]".
419  *
420  * AT debug can be enabled at compile time using MBED_CONF_CELLULAR_DEBUG_AT flag or at runtime
421  * calling set_debug(). Note that MBED_CONF_MBED_TRACE_ENABLE must also be enabled.
422  *
423  * @param debug_on Enable/disable debugging
424  */
425  void set_debug(bool debug_on);
426 
427  /**
428  * Get degug state set by @ref set_debug
429  *
430  * @return current state of debug
431  */
432  bool get_debug() const;
433 
434 private: //Private structs & enums
435  struct tag_t {
436  char tag[7];
437  size_t len;
438  bool found;
439  };
440 
441  struct oob_t {
442  const char *prefix;
443  int prefix_len;
444  Callback<void()> cb;
445  oob_t *next;
446  };
447 
448  // resp_type: the part of the response that doesn't include the information response (+CMD1,+CMD2..)
449  // ends with OK or (CME)(CMS)ERROR
450  // info_type: the information response part of the response: starts with +CMD1 and ends with CRLF
451  // information response contains parameters or subsets of parameters (elements), both separated by comma
452  // elem_type: subsets of parameters that are part of information response, its parameters are separated by comma
453  enum ScopeType {
454  RespType,
455  InfoType,
456  ElemType,
457  NotSet
458  };
459 
460 private: //Private functions
461  void event();
462 
463  /** Increase reference count. Used for counting references to this instance.
464  * Note that this should be used with care, if the ATHandler was taken into use
465  * with get_instance()
466  */
467  void inc_ref_count();
468 
469  /** Decrease reference count. Used for counting references to this instance.
470  * Note that this should be used with care, if the ATHandler was taken into use
471  * with get_instance()
472  */
473  void dec_ref_count();
474 
475  /** Get the current reference count. Used for counting references to this instance.
476  *
477  * @return current reference count
478  */
479  int get_ref_count();
480 
481  /** Remove urc handler from linked list of urc's
482  *
483  * @param prefix Register urc prefix for callback. Urc could be for example "+CMTI: "
484  */
485  void remove_urc_handler(const char *prefix);
486 
487  void set_error(nsapi_error_t err);
488 
489  //Handles the arguments from given variadic list
490  void handle_args(const char *format, std::va_list list);
491 
492  //Starts an AT command based on given parameters
493  void handle_start(const char *cmd, const char *cmd_chr);
494 
495  //Checks that ATHandler does not have a pending error condition and filehandle is usable
496  bool ok_to_proceed();
497 
498  // Gets char from receiving buffer.
499  // Resets and fills the buffer if all are already read (receiving position equals receiving length).
500  // Returns a next char or -1 on failure (also sets error flag)
501  int get_char();
502  // Sets to 0 the reading position, reading length and the whole buffer content.
503  void reset_buffer();
504  // Reading position set to 0 and buffer's unread content moved to beginning
505  void rewind_buffer();
506  // Calculate remaining time for polling based on request start time and AT timeout.
507  // Returns 0 or time in ms for polling.
508  int poll_timeout(bool wait_for_timeout = true);
509  // Reads from serial to receiving buffer.
510  // Returns true on successful read OR false on timeout.
511  bool fill_buffer(bool wait_for_timeout = true);
512 
513  void set_tag(tag_t *tag_dest, const char *tag_seq);
514 
515  // Rewinds the receiving buffer and compares it against given str.
516  bool match(const char *str, size_t size);
517  // Iterates URCs and checks if they match the receiving buffer content.
518  // If URC match sets the scope to information response and after urc's cb returns
519  // finishes the information response scope(consumes to CRLF).
520  bool match_urc();
521  // Checks if any of the error strings are matching the receiving buffer content.
522  bool match_error();
523  // Checks if current char in buffer matches ch and consumes it,
524  // if no match lets the buffer unchanged.
525  bool consume_char(char ch);
526  // Consumes the received content until tag is found.
527  // Consumes the tag only if consume_tag flag is true.
528  bool consume_to_tag(const char *tag, bool consume_tag);
529  // Checks if receiving buffer contains OK, ERROR, URC or given prefix.
530  void resp(const char *prefix, bool check_urc);
531 
532  void set_scope(ScopeType scope_type);
533 
534  ScopeType get_scope();
535 
536  // Consumes to information response stop tag which is CRLF. Sets scope to response.
537  void information_response_stop();
538  // Consumes to element stop tag. Sets scope to information response
539  void information_response_element_stop();
540 
541  // Reads the error code if expected and sets it as last error.
542  void at_error(bool error_code, DeviceErrorType error_type);
543 
544  /** Convert AT error code to 3GPP error codes
545  * @param err AT error code read from CME/CMS ERROR responses
546  * @param error_type error type (CMS/CME/ERROR)
547  */
548  void set_3gpp_error(int err, DeviceErrorType error_type);
549 
550  bool check_cmd_send();
551  size_t write(const void *data, size_t len);
552 
553  /** Finds occurrence of one char buffer inside another char buffer.
554  *
555  * @param dest destination char buffer
556  * @param dest_len length of dest
557  * @param src string to be searched for
558  * @param src_len length of string to be searched for
559  *
560  * @return pointer to first occurrence of src in dest
561  */
562  const char *mem_str(const char *dest, size_t dest_len, const char *src, size_t src_len);
563 
564  // check is urc is already added
565  bool find_urc_handler(const char *prefix);
566 
567  // print contents of a buffer to trace log
568  enum ATType {
569  AT_ERR,
570  AT_RX,
571  AT_TX
572  };
573 
574  void debug_print(const char *p, int len, ATType type);
575 
576 private: //Member variables
577 
578 #if defined AT_HANDLER_MUTEX && defined MBED_CONF_RTOS_PRESENT
579  rtos::Mutex _fileHandleMutex;
581 #endif
582  FileHandle *_fileHandle;
583 
584  events::EventQueue &_queue;
585  nsapi_error_t _last_err;
586  int _last_3gpp_error;
587  device_err_t _last_at_err;
588  uint16_t _oob_string_max_length;
589  char *_output_delimiter;
590 
591  oob_t *_oobs;
592  mbed::chrono::milliseconds_u32 _at_timeout;
593  mbed::chrono::milliseconds_u32 _previous_at_timeout;
594 
595  std::chrono::duration<uint16_t, std::milli> _at_send_delay;
596  rtos::Kernel::Clock::time_point _last_response_stop;
597 
598  int32_t _ref_count;
599  bool _is_fh_usable;
600 
601  // should fit any prefix and int
602  char _recv_buff[MBED_CONF_CELLULAR_AT_HANDLER_BUFFER_SIZE];
603  // reading position
604  size_t _recv_len;
605  // reading length
606  size_t _recv_pos;
607 
608  ScopeType _current_scope;
609 
610  // tag to stop response scope
611  tag_t _resp_stop;
612  // tag to stop information response scope
613  tag_t _info_stop;
614  // tag to stop element scope
615  tag_t _elem_stop;
616  // reference to the stop tag of current scope (resp/info/elem)
617  tag_t *_stop_tag;
618 
619  // delimiter between parameters and also used for delimiting elements of information response
620  char _delimiter;
621  // set true on prefix match -> indicates start of an information response or of an element
622  bool _prefix_matched;
623  // set true on urc match
624  bool _urc_matched;
625  // set true on (CME)(CMS)ERROR
626  bool _error_found;
627  // Max length of OK,(CME)(CMS)ERROR and URCs
628  size_t _max_resp_length;
629 
630  // prefix set during resp_start and used to try matching possible information responses
631  char _info_resp_prefix[MBED_CONF_CELLULAR_AT_HANDLER_BUFFER_SIZE];
632  bool _debug_on;
633  bool _cmd_start;
634  bool _use_delimiter;
635 
636  // time when a command or an URC processing was started
637  rtos::Kernel::Clock::time_point _start_time;
638  // eventqueue event id
639  int _event_id;
640 
641  char _cmd_buffer[MBED_CONF_CELLULAR_AT_HANDLER_BUFFER_SIZE];
642 };
643 
644 } // namespace mbed
645 
646 #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.