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