Example to read the modem IMEI and eUICC/SIM IMSI

main.cpp

Committer:
fahimalavi
Date:
2019-06-11
Revision:
3:7fb46e218f53
Parent:
2:397a4c92da82

File content as of revision 3:7fb46e218f53:

/* mbed Microcontroller Library
 * Copyright (c) 2017 u-blox
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "mbed.h"
#include "ATCmdParser.h"
#include "FileHandle.h"
#include "onboard_modem_api.h"

/* Definitions */
#define OUTPUT_ENTER_KEY  "\r"
#define AT_PARSER_BUFFER_SIZE   256
#define AT_PARSER_TIMEOUT       8*1000 // Milliseconds

/* The example program for the u-blox C030 boards. It sets up the Cellular Module then read out the IMSI of the eUICC/SIM.  
 * The Uer LEDs (RGB) and User Button are utilised to show the activity on the board.
 * When GNSS has a location fix, the Red Timepulse LED, next to the User LEDs, blinks every 1 second.  
 */

/* File handler */
FileHandle *fh;

/* AT Command  Parser handle */
ATCmdParser *at;

// User LEDs
DigitalOut ledRed(LED1, 1);
DigitalOut ledGreen(LED2, 1);
DigitalOut ledBlue(LED3, 1);

// Ethernet socket LED 
DigitalOut ledYellow(LED4,1);

// User Button
#ifdef TARGET_UBLOX_C027
    // No user button on C027
    InterruptIn userButton(NC);
#else
    InterruptIn userButton(SW0);
#endif
   
// Delay between LED changes in second
volatile float delay = 0.5;

// To check if the user pressed the User Button or not
void threadBodyUserButtonCheck(void const *args){
    while (1){
        if (userButton.read() == 1 ) {
        // User Button is pressed 
            delay = 0.1;
            // Indicate with the Yellow LED on Ethernet socket 
            ledYellow = 0;
        }
        else { 
        // User button is released
            delay = 0.5;
            // Turn off the Yellow LED on Ethernet socket
            ledYellow = 1;
        }
    }
}

// Setup the modem
bool setup_modem(){

    bool success = false;
    
    /* Initialize GPIO lines */
    onboard_modem_init();
    
    /* Give modem a little time to settle down */
    wait_ms(250);

    printf("Powering up the modem\r\n");
    onboard_modem_power_up();
#ifdef TARGET_UBLOX_C030_N211
    wait_ms(5000);
#else
    wait_ms(500);
#endif

    // Set AT parser timeout to 1sec for AT OK check
    at->set_timeout(1000);
    
    printf("Checking for AT response from the modem\r\n");
    for (int retry_count = 0; !success && (retry_count < 20); retry_count++) {
        printf("...wait\r\n");
        // The modem tends to sends out some garbage during power up.
        at->flush();
        
        // AT OK talk to the modem
        if (at->send("AT")) {
            wait_ms(100);
            if (at->recv("OK")) {
                success = true;
            }
        }
    }
    
    // Increase the parser time to 8 sec
    at->set_timeout(8000);
    
    if (success) {
        printf("Configuring the modem\r\n");

#ifdef TARGET_UBLOX_C030_N211
        // Turn off modem echoing and turn on verbose responses
        success = at->send("AT+CMEE=1");
#else
        // Set the final baud rate
        if (at->send("AT+IPR=%d", 115200) && at->recv("OK")) {
            // Need to wait for things to be sorted out on the modem side
            wait_ms(100);
            ((UARTSerial *)fh)->set_baud(115200);
        }
        
        // Turn off modem echoing and turn on verbose responses
        success = at->send("ATE0;+CMEE=2") && at->recv("OK") &&
                  // The following commands are best sent separately
                  // Turn off RTC/CTS handshaking
                  at->send("AT&K0") && at->recv("OK") &&
                  // Set DCD circuit(109), changes in accordance with 
                  // the carrier detect status
                  at->send("AT&C1") && at->recv("OK") &&
                  // Set DTR circuit, we ignore the state change of DTR 
                  at->send("AT&D0") && at->recv("OK"); 
#endif                  
    }
    
    return success;
}
/*
** Reading the modem IMEI and eUICC/SIM IMSI
** 
*/

int main()
{
    bool success = false;
    
    printf("\n\r\n\ru-blox C030 reading the modem IMEI and eUICC/SIM IMSI\n\r");
    printf("Initialising UART for modem communication");
    fh = new UARTSerial(MDMTXD, MDMRXD, 115200);
    printf("...DONE\r\n");
    
    // NOTE: if you are experiencing problems with the AT command
    // exchange, change the "false" below to "true" to get debug output
    // from the AT command parser
    printf("Initialising the modem AT command parser");
    at = new ATCmdParser(fh, OUTPUT_ENTER_KEY, AT_PARSER_BUFFER_SIZE,
                         AT_PARSER_TIMEOUT, false);
    printf("...DONE\r\n");
    
    printf("Initializing the modem\r\n");
    if (setup_modem()) {
        printf("...DONE\r\nThe modem powered up\r\n");
        char imei[25+1];
        char imsi[15+1];
        printf("Reading IMEI and IMSI\r\n");
        
#ifdef TARGET_UBLOX_C030_N211
        if (at->send("AT+CGSN=1") && at->recv("\nOK\n%25[^\n]\nOK\n", imei)){
            printf("IMEI: %s\r\n",imei + 6); // Avoid the "+CGSN:" prefix
        }
#else
        if (at->send("AT+CGSN") && at->recv("%15[^\n]\nOK\n", imei)){
            printf("IMEI: %s\r\n",imei);
        }
#endif
        // Sometimes it takes a little while for the SIM to be initialised,
        // so retry this until done
        at->set_timeout(1000);
        for (int retry_count = 0; !success && (retry_count < 10); retry_count++) {
            if (at->send("AT+CIMI") && at->recv("%15[^\n]\nOK\n", imsi)){
                printf("IMSI: %s\r\n",imsi);
                success = true;
            }
        }        
        if (!success) {
            printf("Unable to read IMSI: has a SIM been inserted?\r\n");
        }
    } else {
        printf("Unable to intialize modem\r\n");
    }
    
    printf("FINISHED...\r\n");
    
    // Create threadUserButtonCheck thread
    Thread threadUserButtonCheck(threadBodyUserButtonCheck);

    // Set the LED states
    ledRed = 0;
    ledGreen = 1;
    ledBlue = 1;
    
    // Main loop
    while(1) {
        wait(delay);
        // Shift the LED states
        int carry = ledBlue;
        ledBlue = ledRed;
        ledRed = ledGreen;
        ledGreen = carry;
    }
}

// End Of File