Example to read the modem IMEI and eUICC/SIM IMSI

Committer:
RobMeades
Date:
Thu Feb 15 11:48:51 2018 +0000
Revision:
1:63483ec4d0ff
Parent:
0:b51700dcba34
Child:
2:397a4c92da82
Add support for UBLOX_SARA_N211 target and remove unused libraries.

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 float delayToggle = delay;
euygun 0:b51700dcba34 60 while (1){
euygun 0:b51700dcba34 61 if (userButton.read() == 1 ) {
euygun 0:b51700dcba34 62 // User Button is pressed
euygun 0:b51700dcba34 63 delay = 0.1;
euygun 0:b51700dcba34 64 // Indicate with the Yellow LED on Ethernet socket
euygun 0:b51700dcba34 65 ledYellow = 0;
euygun 0:b51700dcba34 66 }
euygun 0:b51700dcba34 67 else {
euygun 0:b51700dcba34 68 // User button is released
euygun 0:b51700dcba34 69 delay = 0.5;
euygun 0:b51700dcba34 70 // Turn off the Yellow LED on Ethernet socket
euygun 0:b51700dcba34 71 ledYellow = 1;
euygun 0:b51700dcba34 72 }
euygun 0:b51700dcba34 73 }
euygun 0:b51700dcba34 74 }
euygun 0:b51700dcba34 75
euygun 0:b51700dcba34 76 // Setup the modem
euygun 0:b51700dcba34 77 bool setup_modem(){
euygun 0:b51700dcba34 78
euygun 0:b51700dcba34 79 bool success = false;
euygun 0:b51700dcba34 80
euygun 0:b51700dcba34 81 /* Initialize GPIO lines */
euygun 0:b51700dcba34 82 onboard_modem_init();
euygun 0:b51700dcba34 83
euygun 0:b51700dcba34 84 /* Give modem a little time to settle down */
euygun 0:b51700dcba34 85 wait_ms(250);
euygun 0:b51700dcba34 86
RobMeades 1:63483ec4d0ff 87 printf("Powering up the modem\r\n");
RobMeades 1:63483ec4d0ff 88 onboard_modem_power_up();
RobMeades 1:63483ec4d0ff 89 #ifdef TARGET_UBLOX_C030_N211
RobMeades 1:63483ec4d0ff 90 wait_ms(5000);
RobMeades 1:63483ec4d0ff 91 #else
RobMeades 1:63483ec4d0ff 92 wait_ms(500);
RobMeades 1:63483ec4d0ff 93 #endif
RobMeades 1:63483ec4d0ff 94
RobMeades 1:63483ec4d0ff 95 // Set AT parser timeout to 1sec for AT OK check
RobMeades 1:63483ec4d0ff 96 at->set_timeout(1000);
RobMeades 1:63483ec4d0ff 97
RobMeades 1:63483ec4d0ff 98 printf("Checking for AT response from the modem\r\n");
euygun 0:b51700dcba34 99 for (int retry_count = 0; !success && (retry_count < 20); retry_count++) {
euygun 0:b51700dcba34 100 printf("...wait\r\n");
RobMeades 1:63483ec4d0ff 101 // The modem tends to sends out some garbage during power up.
euygun 0:b51700dcba34 102 at->flush();
euygun 0:b51700dcba34 103
euygun 0:b51700dcba34 104 // AT OK talk to the modem
euygun 0:b51700dcba34 105 if (at->send("AT")) {
euygun 0:b51700dcba34 106 wait_ms(100);
euygun 0:b51700dcba34 107 if (at->recv("OK")) {
euygun 0:b51700dcba34 108 success = true;
euygun 0:b51700dcba34 109 }
euygun 0:b51700dcba34 110 }
euygun 0:b51700dcba34 111 }
RobMeades 1:63483ec4d0ff 112
RobMeades 1:63483ec4d0ff 113 // Increase the parser time to 8 sec
RobMeades 1:63483ec4d0ff 114 at->set_timeout(8000);
RobMeades 1:63483ec4d0ff 115
euygun 0:b51700dcba34 116 if (success) {
RobMeades 1:63483ec4d0ff 117 printf("Configuring the modem\r\n");
RobMeades 1:63483ec4d0ff 118
RobMeades 1:63483ec4d0ff 119 #ifdef TARGET_UBLOX_C030_N211
RobMeades 1:63483ec4d0ff 120 // Turn off modem echoing and turn on verbose responses
RobMeades 1:63483ec4d0ff 121 success = at->send("AT+CMEE=1");
RobMeades 1:63483ec4d0ff 122 #else
euygun 0:b51700dcba34 123 // Set the final baud rate
euygun 0:b51700dcba34 124 if (at->send("AT+IPR=%d", 115200) && at->recv("OK")) {
euygun 0:b51700dcba34 125 // Need to wait for things to be sorted out on the modem side
euygun 0:b51700dcba34 126 wait_ms(100);
euygun 0:b51700dcba34 127 ((UARTSerial *)fh)->set_baud(115200);
euygun 0:b51700dcba34 128 }
RobMeades 1:63483ec4d0ff 129
euygun 0:b51700dcba34 130 // Turn off modem echoing and turn on verbose responses
euygun 0:b51700dcba34 131 success = at->send("ATE0;+CMEE=2") && at->recv("OK") &&
euygun 0:b51700dcba34 132 // The following commands are best sent separately
euygun 0:b51700dcba34 133 // Turn off RTC/CTS handshaking
RobMeades 1:63483ec4d0ff 134 at->send("AT&K0") && at->recv("OK") &&
euygun 0:b51700dcba34 135 // Set DCD circuit(109), changes in accordance with
euygun 0:b51700dcba34 136 // the carrier detect status
euygun 0:b51700dcba34 137 at->send("AT&C1") && at->recv("OK") &&
euygun 0:b51700dcba34 138 // Set DTR circuit, we ignore the state change of DTR
euygun 0:b51700dcba34 139 at->send("AT&D0") && at->recv("OK");
RobMeades 1:63483ec4d0ff 140 #endif
euygun 0:b51700dcba34 141 }
RobMeades 1:63483ec4d0ff 142
euygun 0:b51700dcba34 143 return success;
euygun 0:b51700dcba34 144 }
euygun 0:b51700dcba34 145 /*
euygun 0:b51700dcba34 146 ** Reading the modem IMEI and eUICC/SIM IMSI
euygun 0:b51700dcba34 147 **
euygun 0:b51700dcba34 148 */
euygun 0:b51700dcba34 149
euygun 0:b51700dcba34 150 int main()
euygun 0:b51700dcba34 151 {
RobMeades 1:63483ec4d0ff 152 bool success = false;
RobMeades 1:63483ec4d0ff 153
RobMeades 1:63483ec4d0ff 154 printf("\n\r\n\ru-blox C030 reading the modem IMEI and eUICC/SIM IMSI\n\r");
euygun 0:b51700dcba34 155 printf("Initialising UART for modem communication");
RobMeades 1:63483ec4d0ff 156 fh = new UARTSerial(MDMTXD, MDMRXD, 9600);
euygun 0:b51700dcba34 157 printf("...DONE\r\n");
euygun 0:b51700dcba34 158
RobMeades 1:63483ec4d0ff 159 // NOTE: if you are experiencing problems with the AT command
RobMeades 1:63483ec4d0ff 160 // exchange, change the "false" below to "true" to get debug output
RobMeades 1:63483ec4d0ff 161 // from the AT command parser
RobMeades 1:63483ec4d0ff 162 printf("Initialising the modem AT command parser");
euygun 0:b51700dcba34 163 at = new ATCmdParser(fh, OUTPUT_ENTER_KEY, AT_PARSER_BUFFER_SIZE,
euygun 0:b51700dcba34 164 AT_PARSER_TIMEOUT, false);
euygun 0:b51700dcba34 165 printf("...DONE\r\n");
euygun 0:b51700dcba34 166
euygun 0:b51700dcba34 167 printf("Initializing the modem\r\n");
RobMeades 1:63483ec4d0ff 168 if (setup_modem()) {
euygun 0:b51700dcba34 169 printf("...DONE\r\nThe modem powered up\r\n");
RobMeades 1:63483ec4d0ff 170 char imei[25+1];
euygun 0:b51700dcba34 171 char imsi[15+1];
euygun 0:b51700dcba34 172 printf("Reading IMEI and IMSI\r\n");
RobMeades 1:63483ec4d0ff 173
RobMeades 1:63483ec4d0ff 174 #ifdef TARGET_UBLOX_C030_N211
RobMeades 1:63483ec4d0ff 175 if (at->send("AT+CGSN=1") && at->recv("\nOK\n%25[^\n]\nOK\n", imei)){
RobMeades 1:63483ec4d0ff 176 printf("IMEI: %s\r\n",imei + 6); // Avoid the "+CGSN:" prefix
RobMeades 1:63483ec4d0ff 177 }
RobMeades 1:63483ec4d0ff 178 #else
euygun 0:b51700dcba34 179 if (at->send("AT+CGSN") && at->recv("%15[^\n]\nOK\n", imei)){
euygun 0:b51700dcba34 180 printf("IMEI: %s\r\n",imei);
euygun 0:b51700dcba34 181 }
RobMeades 1:63483ec4d0ff 182 #endif
RobMeades 1:63483ec4d0ff 183 // Sometimes it takes a little while for the SIM to be initialised,
RobMeades 1:63483ec4d0ff 184 // so retry this until done
RobMeades 1:63483ec4d0ff 185 at->set_timeout(1000);
RobMeades 1:63483ec4d0ff 186 for (int retry_count = 0; !success && (retry_count < 10); retry_count++) {
RobMeades 1:63483ec4d0ff 187 if (at->send("AT+CIMI") && at->recv("%15[^\n]\nOK\n", imsi)){
RobMeades 1:63483ec4d0ff 188 printf("IMSI: %s\r\n",imsi);
RobMeades 1:63483ec4d0ff 189 success = true;
RobMeades 1:63483ec4d0ff 190 }
RobMeades 1:63483ec4d0ff 191 }
RobMeades 1:63483ec4d0ff 192 if (!success) {
RobMeades 1:63483ec4d0ff 193 printf("Unable to read IMSI: has a SIM been inserted?\r\n");
euygun 0:b51700dcba34 194 }
RobMeades 1:63483ec4d0ff 195 } else {
RobMeades 1:63483ec4d0ff 196 printf("Unable to intialize modem\r\n");
euygun 0:b51700dcba34 197 }
euygun 0:b51700dcba34 198
RobMeades 1:63483ec4d0ff 199 printf("FINISHED...\r\n");
euygun 0:b51700dcba34 200
euygun 0:b51700dcba34 201 // Create threadUserButtonCheck thread
euygun 0:b51700dcba34 202 Thread threadUserButtonCheck(threadBodyUserButtonCheck);
euygun 0:b51700dcba34 203
euygun 0:b51700dcba34 204 // Set the LED states
euygun 0:b51700dcba34 205 ledRed = 0;
euygun 0:b51700dcba34 206 ledGreen = 1;
euygun 0:b51700dcba34 207 ledBlue = 1;
euygun 0:b51700dcba34 208
euygun 0:b51700dcba34 209 // Main loop
euygun 0:b51700dcba34 210 while(1) {
euygun 0:b51700dcba34 211 wait(delay);
euygun 0:b51700dcba34 212 // Shift the LED states
euygun 0:b51700dcba34 213 int carry = ledBlue;
euygun 0:b51700dcba34 214 ledBlue = ledRed;
euygun 0:b51700dcba34 215 ledRed = ledGreen;
euygun 0:b51700dcba34 216 ledGreen = carry;
euygun 0:b51700dcba34 217 }
euygun 0:b51700dcba34 218 }
euygun 0:b51700dcba34 219
euygun 0:b51700dcba34 220 // End Of File