1+ /* *
2+ * @brief This example demonstrates how to use the SequansController to send AT
3+ * commands to the Sequans GM02S modem.
4+ */
5+
6+ #include < log.h>
7+ #include < lte.h>
8+ #include < sequans_controller.h>
9+
10+ #include < string.h>
11+
12+ static char ping_response[512 ] = " " ;
13+
14+ static volatile size_t ping_response_index = 0 ;
15+
16+ static volatile size_t ping_messages_received = 0 ;
17+
18+ static void ping_callback (char * message) {
19+ // We don't want to include a whitespace at the start of the string, so we
20+ // remove one from the length and move the pointer by one
21+ const size_t message_length = strlen (message) - 1 ;
22+ message = message + 1 ;
23+
24+ // We store all the notification messsage data in a buffer where we adjust
25+ // the index of the data according to the length of the message
26+ //
27+ // We do messsage + 1 here to move the pointer so we don't include a
28+ // whitespace.
29+ memcpy (ping_response + ping_response_index, message, message_length);
30+
31+ ping_response_index += message_length;
32+
33+ // Append new line for every retrieved message
34+ ping_response[ping_response_index++] = ' \r ' ;
35+ ping_response[ping_response_index++] = ' \n ' ;
36+
37+ ping_messages_received++;
38+ }
39+
40+ void setup () {
41+ Log.begin (115200 );
42+
43+ Log.info (" Starting up example for custom AT commands" );
44+
45+ // If we didn't want to connect to the network, we could start the
46+ // SequansController directly by: SequansController.begin();
47+ // Lte.begin() will start the SequansController in its begin()
48+ Lte.begin ();
49+
50+ // Here we enable verbose error messages
51+ SequansController.writeCommand (" AT+CMEE=2" );
52+
53+ // Here we perform a ping with incorrect parameter in order to trigger the
54+ // error message. Note that if the modem returns an error with the command,
55+ // the SequansController will retry 5 times with an interval of 2 seconds,
56+ // so this will take 10 seconds
57+ //
58+ // Here we also pass an optional response buffer to the function which will
59+ // be filled with the response from the command
60+ char response[128 ] = " " ;
61+ ResponseResult response_result =
62+ SequansController.writeCommand (" AT+PING=0" , response, sizeof (response));
63+
64+ if (response_result == ResponseResult::OK) {
65+ Log.infof (" Command written successfully, this should not happen" );
66+ } else {
67+ Log.errorf (" Error writing command, the response was: %s\r\n " , response);
68+ }
69+
70+ // --------------------- Notifications & Commands -------------------------
71+
72+ // Now we're going to perform a ping to google in a slighly different way
73+ // and set up a notification so that we can inspect the result
74+
75+ // First we set up a callback when the modem sends back an URC (unsolicited
76+ // response code), which can be though of as a notification.
77+ //
78+ // The different URCs are documented in Sequans' AT command reference.
79+ SequansController.registerCallback (" PING" , ping_callback);
80+
81+ // Instead of writing a command, we use the writeBytes function here. It
82+ // will simply write the bytes we provide and not check whether the command
83+ // was written successfully. We do it this way for this example as we want
84+ // to utilise notifications and the ping command is blocking. This is thus
85+ // purely an example.
86+ const char * command = " AT+PING=\" www.google.com\" " ;
87+ SequansController.writeBytes ((uint8_t *)command, strlen (command), true );
88+
89+ // The default ping will retrieve four responses, so wait for them
90+ while (ping_messages_received < 4 ) {}
91+
92+ Log.infof (" Received the following ping response:\r\n %s\r\n " , ping_response);
93+
94+ // -------------- Extracting Parameters from Responses --------------------
95+
96+ // Here we will utilise AT+CEREG?, which returns data about the current
97+ // connection. We can use it to check if we are connected to the network.
98+ response_result =
99+ SequansController.writeCommand (" AT+CEREG?" , response, sizeof (response));
100+
101+ if (response_result == ResponseResult::OK) {
102+
103+ Log.infof (" Command written successfully, the response was: %s\r\n " ,
104+ response);
105+
106+ char value_buffer[8 ] = " " ;
107+
108+ // Extract the 1st index (zero indexed), which tells us about the
109+ // connection status
110+ if (SequansController.extractValueFromCommandResponse (
111+ response,
112+ 1 ,
113+ value_buffer,
114+ sizeof (value_buffer))) {
115+ Log.infof (" The value was: %s\r\n " , value_buffer);
116+ } else {
117+ Log.error (" Failed to extract value" );
118+ }
119+ } else {
120+ Log.errorf (" Error writing command, the response was: %s\r\n " , response);
121+ }
122+
123+ Lte.end ();
124+ }
125+
126+ void loop () {}
0 commit comments