Example to read the modem IMEI and eUICC/SIM IMSI

Committer:
RobMeades
Date:
Wed Jun 05 13:42:44 2019 +0100
Revision:
2:397a4c92da82
Parent:
1:63483ec4d0ff
Set initial modem interface rate to 115,200 (from 9600) as SARA-R4xx series modems default to this rate and do not auto-baud.  Remove unused variable delayToggle.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
euygun 0:b51700dcba34 1 /* mbed Microcontroller Library
euygun 0:b51700dcba34 2 * Copyright (c) 2017 u-blox
euygun 0:b51700dcba34 3 *
euygun 0:b51700dcba34 4 * Licensed under the Apache License, Version 2.0 (the "License");
euygun 0:b51700dcba34 5 * you may not use this file except in compliance with the License.
euygun 0:b51700dcba34 6 * You may obtain a copy of the License at
euygun 0:b51700dcba34 7 *
euygun 0:b51700dcba34 8 * http://www.apache.org/licenses/LICENSE-2.0
euygun 0:b51700dcba34 9 *
euygun 0:b51700dcba34 10 * Unless required by applicable law or agreed to in writing, software
euygun 0:b51700dcba34 11 * distributed under the License is distributed on an "AS IS" BASIS,
euygun 0:b51700dcba34 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
euygun 0:b51700dcba34 13 * See the License for the specific language governing permissions and
euygun 0:b51700dcba34 14 * limitations under the License.
euygun 0:b51700dcba34 15 */
euygun 0:b51700dcba34 16
euygun 0:b51700dcba34 17 #include "mbed.h"
euygun 0:b51700dcba34 18 #include "ATCmdParser.h"
euygun 0:b51700dcba34 19 #include "FileHandle.h"
euygun 0:b51700dcba34 20 #include "onboard_modem_api.h"
euygun 0:b51700dcba34 21
euygun 0:b51700dcba34 22 /* Definitions */
euygun 0:b51700dcba34 23 #define OUTPUT_ENTER_KEY "\r"
euygun 0:b51700dcba34 24 #define AT_PARSER_BUFFER_SIZE 256
euygun 0:b51700dcba34 25 #define AT_PARSER_TIMEOUT 8*1000 // Milliseconds
euygun 0:b51700dcba34 26
euygun 0:b51700dcba34 27 /* The example program for the u-blox C030 boards. It sets up the Cellular Module then read out the IMSI of the eUICC/SIM.
euygun 0:b51700dcba34 28 * The Uer LEDs (RGB) and User Button are utilised to show the activity on the board.
euygun 0:b51700dcba34 29 * When GNSS has a location fix, the Red Timepulse LED, next to the User LEDs, blinks every 1 second.
euygun 0:b51700dcba34 30 */
euygun 0:b51700dcba34 31
euygun 0:b51700dcba34 32 /* File handler */
euygun 0:b51700dcba34 33 FileHandle *fh;
euygun 0:b51700dcba34 34
euygun 0:b51700dcba34 35 /* AT Command Parser handle */
euygun 0:b51700dcba34 36 ATCmdParser *at;
euygun 0:b51700dcba34 37
euygun 0:b51700dcba34 38 // User LEDs
euygun 0:b51700dcba34 39 DigitalOut ledRed(LED1, 1);
euygun 0:b51700dcba34 40 DigitalOut ledGreen(LED2, 1);
euygun 0:b51700dcba34 41 DigitalOut ledBlue(LED3, 1);
euygun 0:b51700dcba34 42
euygun 0:b51700dcba34 43 // Ethernet socket LED
euygun 0:b51700dcba34 44 DigitalOut ledYellow(LED4,1);
euygun 0:b51700dcba34 45
euygun 0:b51700dcba34 46 // User Button
euygun 0:b51700dcba34 47 #ifdef TARGET_UBLOX_C027
euygun 0:b51700dcba34 48 // No user button on C027
euygun 0:b51700dcba34 49 InterruptIn userButton(NC);
euygun 0:b51700dcba34 50 #else
euygun 0:b51700dcba34 51 InterruptIn userButton(SW0);
euygun 0:b51700dcba34 52 #endif
euygun 0:b51700dcba34 53
euygun 0:b51700dcba34 54 // Delay between LED changes in second
euygun 0:b51700dcba34 55 volatile float delay = 0.5;
euygun 0:b51700dcba34 56
euygun 0:b51700dcba34 57 // To check if the user pressed the User Button or not
euygun 0:b51700dcba34 58 void threadBodyUserButtonCheck(void const *args){
euygun 0:b51700dcba34 59 while (1){
euygun 0:b51700dcba34 60 if (userButton.read() == 1 ) {
euygun 0:b51700dcba34 61 // User Button is pressed
euygun 0:b51700dcba34 62 delay = 0.1;
euygun 0:b51700dcba34 63 // Indicate with the Yellow LED on Ethernet socket
euygun 0:b51700dcba34 64 ledYellow = 0;
euygun 0:b51700dcba34 65 }
euygun 0:b51700dcba34 66 else {
euygun 0:b51700dcba34 67 // User button is released
euygun 0:b51700dcba34 68 delay = 0.5;
euygun 0:b51700dcba34 69 // Turn off the Yellow LED on Ethernet socket
euygun 0:b51700dcba34 70 ledYellow = 1;
euygun 0:b51700dcba34 71 }
euygun 0:b51700dcba34 72 }
euygun 0:b51700dcba34 73 }
euygun 0:b51700dcba34 74
euygun 0:b51700dcba34 75 // Setup the modem
euygun 0:b51700dcba34 76 bool setup_modem(){
euygun 0:b51700dcba34 77
euygun 0:b51700dcba34 78 bool success = false;
euygun 0:b51700dcba34 79
euygun 0:b51700dcba34 80 /* Initialize GPIO lines */
euygun 0:b51700dcba34 81 onboard_modem_init();
euygun 0:b51700dcba34 82
euygun 0:b51700dcba34 83 /* Give modem a little time to settle down */
euygun 0:b51700dcba34 84 wait_ms(250);
euygun 0:b51700dcba34 85
RobMeades 1:63483ec4d0ff 86 printf("Powering up the modem\r\n");
RobMeades 1:63483ec4d0ff 87 onboard_modem_power_up();
RobMeades 1:63483ec4d0ff 88 #ifdef TARGET_UBLOX_C030_N211
RobMeades 1:63483ec4d0ff 89 wait_ms(5000);
RobMeades 1:63483ec4d0ff 90 #else
RobMeades 1:63483ec4d0ff 91 wait_ms(500);
RobMeades 1:63483ec4d0ff 92 #endif
RobMeades 1:63483ec4d0ff 93
RobMeades 1:63483ec4d0ff 94 // Set AT parser timeout to 1sec for AT OK check
RobMeades 1:63483ec4d0ff 95 at->set_timeout(1000);
RobMeades 1:63483ec4d0ff 96
RobMeades 1:63483ec4d0ff 97 printf("Checking for AT response from the modem\r\n");
euygun 0:b51700dcba34 98 for (int retry_count = 0; !success && (retry_count < 20); retry_count++) {
euygun 0:b51700dcba34 99 printf("...wait\r\n");
RobMeades 1:63483ec4d0ff 100 // The modem tends to sends out some garbage during power up.
euygun 0:b51700dcba34 101 at->flush();
euygun 0:b51700dcba34 102
euygun 0:b51700dcba34 103 // AT OK talk to the modem
euygun 0:b51700dcba34 104 if (at->send("AT")) {
euygun 0:b51700dcba34 105 wait_ms(100);
euygun 0:b51700dcba34 106 if (at->recv("OK")) {
euygun 0:b51700dcba34 107 success = true;
euygun 0:b51700dcba34 108 }
euygun 0:b51700dcba34 109 }
euygun 0:b51700dcba34 110 }
RobMeades 1:63483ec4d0ff 111
RobMeades 1:63483ec4d0ff 112 // Increase the parser time to 8 sec
RobMeades 1:63483ec4d0ff 113 at->set_timeout(8000);
RobMeades 1:63483ec4d0ff 114
euygun 0:b51700dcba34 115 if (success) {
RobMeades 1:63483ec4d0ff 116 printf("Configuring the modem\r\n");
RobMeades 1:63483ec4d0ff 117
RobMeades 1:63483ec4d0ff 118 #ifdef TARGET_UBLOX_C030_N211
RobMeades 1:63483ec4d0ff 119 // Turn off modem echoing and turn on verbose responses
RobMeades 1:63483ec4d0ff 120 success = at->send("AT+CMEE=1");
RobMeades 1:63483ec4d0ff 121 #else
euygun 0:b51700dcba34 122 // Set the final baud rate
euygun 0:b51700dcba34 123 if (at->send("AT+IPR=%d", 115200) && at->recv("OK")) {
euygun 0:b51700dcba34 124 // Need to wait for things to be sorted out on the modem side
euygun 0:b51700dcba34 125 wait_ms(100);
euygun 0:b51700dcba34 126 ((UARTSerial *)fh)->set_baud(115200);
euygun 0:b51700dcba34 127 }
RobMeades 1:63483ec4d0ff 128
euygun 0:b51700dcba34 129 // Turn off modem echoing and turn on verbose responses
euygun 0:b51700dcba34 130 success = at->send("ATE0;+CMEE=2") && at->recv("OK") &&
euygun 0:b51700dcba34 131 // The following commands are best sent separately
euygun 0:b51700dcba34 132 // Turn off RTC/CTS handshaking
RobMeades 1:63483ec4d0ff 133 at->send("AT&K0") && at->recv("OK") &&
euygun 0:b51700dcba34 134 // Set DCD circuit(109), changes in accordance with
euygun 0:b51700dcba34 135 // the carrier detect status
euygun 0:b51700dcba34 136 at->send("AT&C1") && at->recv("OK") &&
euygun 0:b51700dcba34 137 // Set DTR circuit, we ignore the state change of DTR
euygun 0:b51700dcba34 138 at->send("AT&D0") && at->recv("OK");
RobMeades 1:63483ec4d0ff 139 #endif
euygun 0:b51700dcba34 140 }
RobMeades 1:63483ec4d0ff 141
euygun 0:b51700dcba34 142 return success;
euygun 0:b51700dcba34 143 }
euygun 0:b51700dcba34 144 /*
euygun 0:b51700dcba34 145 ** Reading the modem IMEI and eUICC/SIM IMSI
euygun 0:b51700dcba34 146 **
euygun 0:b51700dcba34 147 */
euygun 0:b51700dcba34 148
euygun 0:b51700dcba34 149 int main()
euygun 0:b51700dcba34 150 {
RobMeades 1:63483ec4d0ff 151 bool success = false;
RobMeades 1:63483ec4d0ff 152
RobMeades 1:63483ec4d0ff 153 printf("\n\r\n\ru-blox C030 reading the modem IMEI and eUICC/SIM IMSI\n\r");
euygun 0:b51700dcba34 154 printf("Initialising UART for modem communication");
RobMeades 2:397a4c92da82 155 fh = new UARTSerial(MDMTXD, MDMRXD, 115200);
euygun 0:b51700dcba34 156 printf("...DONE\r\n");
euygun 0:b51700dcba34 157
RobMeades 1:63483ec4d0ff 158 // NOTE: if you are experiencing problems with the AT command
RobMeades 1:63483ec4d0ff 159 // exchange, change the "false" below to "true" to get debug output
RobMeades 1:63483ec4d0ff 160 // from the AT command parser
RobMeades 1:63483ec4d0ff 161 printf("Initialising the modem AT command parser");
euygun 0:b51700dcba34 162 at = new ATCmdParser(fh, OUTPUT_ENTER_KEY, AT_PARSER_BUFFER_SIZE,
RobMeades 2:397a4c92da82 163 AT_PARSER_TIMEOUT, false);
euygun 0:b51700dcba34 164 printf("...DONE\r\n");
euygun 0:b51700dcba34 165
euygun 0:b51700dcba34 166 printf("Initializing the modem\r\n");
RobMeades 1:63483ec4d0ff 167 if (setup_modem()) {
euygun 0:b51700dcba34 168 printf("...DONE\r\nThe modem powered up\r\n");
RobMeades 1:63483ec4d0ff 169 char imei[25+1];
euygun 0:b51700dcba34 170 char imsi[15+1];
euygun 0:b51700dcba34 171 printf("Reading IMEI and IMSI\r\n");
RobMeades 1:63483ec4d0ff 172
RobMeades 1:63483ec4d0ff 173 #ifdef TARGET_UBLOX_C030_N211
RobMeades 1:63483ec4d0ff 174 if (at->send("AT+CGSN=1") && at->recv("\nOK\n%25[^\n]\nOK\n", imei)){
RobMeades 1:63483ec4d0ff 175 printf("IMEI: %s\r\n",imei + 6); // Avoid the "+CGSN:" prefix
RobMeades 1:63483ec4d0ff 176 }
RobMeades 1:63483ec4d0ff 177 #else
euygun 0:b51700dcba34 178 if (at->send("AT+CGSN") && at->recv("%15[^\n]\nOK\n", imei)){
euygun 0:b51700dcba34 179 printf("IMEI: %s\r\n",imei);
euygun 0:b51700dcba34 180 }
RobMeades 1:63483ec4d0ff 181 #endif
RobMeades 1:63483ec4d0ff 182 // Sometimes it takes a little while for the SIM to be initialised,
RobMeades 1:63483ec4d0ff 183 // so retry this until done
RobMeades 1:63483ec4d0ff 184 at->set_timeout(1000);
RobMeades 1:63483ec4d0ff 185 for (int retry_count = 0; !success && (retry_count < 10); retry_count++) {
RobMeades 1:63483ec4d0ff 186 if (at->send("AT+CIMI") && at->recv("%15[^\n]\nOK\n", imsi)){
RobMeades 1:63483ec4d0ff 187 printf("IMSI: %s\r\n",imsi);
RobMeades 1:63483ec4d0ff 188 success = true;
RobMeades 1:63483ec4d0ff 189 }
RobMeades 1:63483ec4d0ff 190 }
RobMeades 1:63483ec4d0ff 191 if (!success) {
RobMeades 1:63483ec4d0ff 192 printf("Unable to read IMSI: has a SIM been inserted?\r\n");
euygun 0:b51700dcba34 193 }
RobMeades 1:63483ec4d0ff 194 } else {
RobMeades 1:63483ec4d0ff 195 printf("Unable to intialize modem\r\n");
euygun 0:b51700dcba34 196 }
euygun 0:b51700dcba34 197
RobMeades 1:63483ec4d0ff 198 printf("FINISHED...\r\n");
euygun 0:b51700dcba34 199
euygun 0:b51700dcba34 200 // Create threadUserButtonCheck thread
euygun 0:b51700dcba34 201 Thread threadUserButtonCheck(threadBodyUserButtonCheck);
euygun 0:b51700dcba34 202
euygun 0:b51700dcba34 203 // Set the LED states
euygun 0:b51700dcba34 204 ledRed = 0;
euygun 0:b51700dcba34 205 ledGreen = 1;
euygun 0:b51700dcba34 206 ledBlue = 1;
euygun 0:b51700dcba34 207
euygun 0:b51700dcba34 208 // Main loop
euygun 0:b51700dcba34 209 while(1) {
euygun 0:b51700dcba34 210 wait(delay);
euygun 0:b51700dcba34 211 // Shift the LED states
euygun 0:b51700dcba34 212 int carry = ledBlue;
euygun 0:b51700dcba34 213 ledBlue = ledRed;
euygun 0:b51700dcba34 214 ledRed = ledGreen;
euygun 0:b51700dcba34 215 ledGreen = carry;
euygun 0:b51700dcba34 216 }
euygun 0:b51700dcba34 217 }
euygun 0:b51700dcba34 218
euygun 0:b51700dcba34 219 // End Of File