SMS Communication with LinkIt™ Assist 2502 Development Board

Introduction

This project uses the MediaTek LinkIt™ Assist 2502 development board’s 2G (GSM) connectivity to send, receive, read and delete SMS messages.

This tutorial guides you through:

  • Building the prototype, with details of the hardware required and how to put it together to run the project.
  • Creating the software to send, receive, read and then delete any existing SMS.
  • Running your application to verify the result.

At the end of the tutorial there are details on where to go for additional information on the LinkIt Assist 2502 development board and how to create software for it.

Before You Start

If you haven’t built a LinkIt Assist 2502 project before, consult the LinkIt Assist 2502 developer’s guide. There you can get full details on downloading and installing the Eclipse IDE and LinkIt Assist 2502 SDK v2, then configuring the IDE and upgrading the board firmware to set up your development environment.

Building the Hardware

To build your project’s hardware, in addition to LinkIt Assist 2502 development board you need the following components.

ComponentDescription
CableMicro-USB cable
Micro-SIM card2G data plan enabled micro-SIM card

Insert the SIM card, which must support GSM/GPRS communication with a network provider operating in the 850/900/1800/1900 MHz frequency range and be classified as Class 12, as shown below.

Inserting the SIM card

Create The Software

Your project needs software to receive SMS using the GSM connectivity feature on the LinkIt Assist 2502 development board. This section describes the details of the software required with an overview of the source code in C.

LinkIt Assist 2502 project in the Eclipse IDE

Follow the description in section 2.5, “Creating Your First Project” of the guide to create a new project in the Eclipse IDE.

Add the header files for the supporting libraries

Once a new project is created in the IDE, add the supporting libraries. Import the required libraries as follows:

#include "vmtype.h"
#include "vmboard.h"
#include "vmsystem.h"
#include "vmlog.h"
#include "vmgsm_sms.h"

The SMS support is provided in the header file vmgsm_sms.h.

Define the variables

Next, the static variables used in the code are defined, in this case the AT port to send, check and delete a message commands.

#define AT_CMD_PORT 1000

The port number range is from 500 to 65535, you can use any number within that range.

Define the main() function

The LinkIt Assist 2502 application in the Eclipse IDE has a default implementation of the main function vm_main(), as an entry point to the application. It's main purpose is to register system events and callback functions for the input events. The default implementation includes a call to register a system event handler callback function, as shown below.

/* Entry point */
  void vm_main(void){
      /* register system events handler */
      vm_pmng_register_system_event_callback(handle_sysevt);
}

Define the callback function handle_sysevt()

handle_sysevt() is the callback to be invoked by the system engine.

  1. When the vm_main() function is called, the board sends VM_EVENT_CREATE message to the software to open the AT command port by calling the function vm_cmd_open_port().
    • Define a case structure to create an event or to quit the event.
    • When the  vm_main()  function is called, the board sends  VM_EVENT_CREATE  message to the software to create a timer with predefined period of 10 seconds (10000 milliseconds) to read the SMS from a given port.
    • Open the AT command port by calling the function vm_cmd_open_port()vm_at_callback() is then called to delete the message if necessary.

      vm_cmd_open_port(CATCHER_PORT, vm_at_callback, NULL);
    • If the  VM_EVENT_QUIT  event is called, the application stops.  

Define the AT callback function

Apply the AT commands to trigger send, read and delete SMS functions, as shown in a table and source code below.
CommandDescription
SendSMSsms_send_sms()
ReadSMSsms_read_sms()
DeleteSMSvm_gsm_sms_delete_message_list()
void vm_at_callback(vm_cmd_command_t *param, void *user_data){
    VMINT delete_list_res;
    vm_log_info( "cmd = %s", ( char*)param->command_buffer);
 
    if(strcmp("SendSMS" ,(char*)param->command_buffer) == 0){
        sms_send_sms();
    }
 
    if(strcmp("ReadSMS" ,(char*)param->command_buffer) == 0){
        sms_read_sms();
    }
 
    if(strcmp("DeleteSMS" ,(char*)param->command_buffer) == 0){
        delete_list_res = vm_gsm_sms_delete_message_list(VM_GSM_SMS_BOX_INBOX, VM_GSM_SMS_SIM_1, sms_read_sms, NULL);
        if(delete_list_res == -1){
            vm_log_debug( "vm_gsm_sms_delete_message_list Error");
            return;
        }
    }
 
    return;
}

Define the SMS send function 

To send an SMS, you'll need to provide the recipient's phone number and the content to send.

  1. Call the function vm_chset_ascii_to_ucs2() to convert the SMS content from ASCII string to a UCS-2 string, as shown below.

    /* Reads the SMS */
    void sms_read_sms_sample( void){
        VMINT16 message_id;
        vm_gsm_sms_read_message_data_t* message_data = NULL;
        VMWCHAR* content_buff;
        VMINT res;  
  2. Get the message ID based on the message box type by calling the function vm_gsm_sms_get_message_id(). The message box type could be inbox, outbox, unsent, etc. The message doesn’t exist if the message ID is “-1”, so print an error message using the function vm_log_debug(), as shown below.

    /* Gets the message ID of the first message in the SMS inbox */
        message_id = vm_gsm_sms_get_message_id(VM_GSM_SMS_BOX_INBOX, 0); //0 is the latest SMS.
        if(message_id == -1){
            vm_log_debug( "sms read message id error");
            return;
        }
  3. Allocate a dynamic memory buffer to read the message content. Read the content by calling the API vm_gsm_sms_read_message(). The SMS received will be stored on the SIM card.

    /* Allocates memory for the message data */
        message_data = (vm_gsm_sms_read_message_data_t*)vm_calloc(sizeof(vm_gsm_sms_read_message_data_t));
        if(message_data == NULL){
            vm_log_debug( "sms read malloc message data fail" );
            return;
        }
    
        /* Allocates memory for the content buffer of the message */
        content_buff = (VMWCHAR*)vm_calloc((500+1)* sizeof(VMWCHAR));
        if(content_buff == NULL){
            vm_free(message_data);
            vm_log_debug( "sms read malloc content fail" );
            return;
    
        }
        message_data->content_buffer = content_buff;
        message_data->content_buffer_size = 500;
    
        /* Reads the message */
        res = vm_gsm_sms_read_message(message_id, VM_TRUE, message_data, sms_read_sms_sample_callback, NULL);
        if(res != VM_GSM_SMS_RESULT_OK){
            vm_free(content_buff);
            vm_free(message_data);
            vm_log_debug( "Registering a read callback has failed");
        }
    }
  4. The function vm_gsm_sms_read_message() applies a callback sms_read_sms_callback() to translate the message from Unicode to ASCII in order to print it on the screen, most short messages are represented in Unicode. For the implementation details, see the Full Source Code.

Define the SMS read function 

  1. Define the parameters required for the implementation of the read function.

    /* Reads the SMS */
    void sms_read_sms_sample( void){
        VMINT16 message_id;
        vm_gsm_sms_read_message_data_t* message_data = NULL;
        VMWCHAR* content_buff;
        VMINT res;  
  2. Get the message ID based on the message box type by calling the function vm_gsm_sms_get_message_id(). The message box type could be inbox, outbox, unsent, etc. The message doesn’t exist if the message ID is “-1”, so print an error message using the function vm_log_debug(), as shown below.

    /* Gets the message ID of the first message in the SMS inbox */
        message_id = vm_gsm_sms_get_message_id(VM_GSM_SMS_BOX_INBOX, 0); //0 is the latest SMS.
        if(message_id == -1){
            vm_log_debug( "sms read message id error");
            return;
        }    
  3. Allocate a dynamic memory buffer to read the message content. Read the content by calling the API vm_gsm_sms_read_message(). The SMS received will be stored on the SIM card.

    /* Allocates memory for the message data */
        message_data = (vm_gsm_sms_read_message_data_t*)vm_calloc(sizeof(vm_gsm_sms_read_message_data_t));
        if(message_data == NULL){
            vm_log_debug( "sms read malloc message data fail" );
            return;
        }
     
        /* Allocates memory for the content buffer of the message */
        content_buff = (VMWCHAR*)vm_calloc((500+1)* sizeof(VMWCHAR));
        if(content_buff == NULL){
            vm_free(message_data);
            vm_log_debug( "sms read malloc content fail" );
            return;
     
        }
        message_data->content_buffer = content_buff;
        message_data->content_buffer_size = 500;
     
        /* Reads the message */
        res = vm_gsm_sms_read_message(message_id, VM_TRUE, message_data, sms_read_sms_sample_callback, NULL);
        if(res != VM_GSM_SMS_RESULT_OK){
            vm_free(content_buff);
            vm_free(message_data);
            vm_log_debug( "Registering a read callback has failed");
        }
    }
  4. The function vm_gsm_sms_read_message() applies a callback sms_read_sms_callback() to translate the message from Unicode to ASCII in order to print it on the screen, most short messages are represented in Unicode. For the implementation details, see the full source code.

Define the SMS delete function 

The SMS delete function is implemented in the AT command callback vm_at_callback(). Call the API vm_gsm_sms_delete_message_list() to delete the message.

void vm_at_callback(vm_cmd_command_t *param, void *user_data)
{
    ...
    if(strcmp("DeleteSMS" ,(char*)param->command_buffer) == 0){
        delete_list_res = vm_gsm_sms_delete_message_list(VM_GSM_SMS_BOX_INBOX, VM_GSM_SMS_SIM_1, sms_read_sms, NULL);
        if(delete_list_res == -1){
            vm_log_debug( "vm_gsm_sms_delete_message_list Error");
            return;
        }
    }
    return;
}

Note, that the SIM card number parameter should be  "VM_GSM_SMS_SIM_1" . It’s a fixed setting for Assist 2502 board.

Full Source Code 

#include "vmtype.h"
#include "vmboard.h"
#include "vmsystem.h"
#include "vmlog.h"
#include "vmgsm_sms.h"
#include "vmcmd.h"
 
#define AT_CMD_PORT 1000
 
/* Reads SMS callback */
void sms_read_sms_callback(vm_gsm_sms_callback_t* callback_data){
    VMUINT8 content[100];
    VMUINT8 sms_number[50];
    vm_gsm_sms_read_message_data_callback_t* read_msg;
    /* Checks if it is an SMS read event */
    if(callback_data->action == VM_GSM_SMS_ACTION_READ){
        if(callback_data->cause == VM_GSM_SMS_CAUSE_NO_ERROR){
            if(!callback_data->action_data){
                return;
            }
            /* Analyses the data */
            read_msg = (vm_gsm_sms_read_message_data_callback_t*)callback_data->action_data;
 
            /* Gets the content of the SMS message */
            vm_chset_ucs2_to_ascii(content, 100, (VMWSTR)(read_msg->message_data->content_buffer));
            vm_log_debug( "The message content is %s.",content);
 
            /* Frees the memory allocated by the malloc() */
            vm_free(read_msg->message_data->content_buffer);
            vm_free(read_msg->message_data);
        }
        else{
            vm_log_debug( "Reading the SMS has failed");
        }
    }
}
 
/* Reads the SMS */
void sms_read_sms(void){
    VMINT16 message_id;
    vm_gsm_sms_read_message_data_t* message_data = NULL;
    VMWCHAR* content_buff;
    VMINT res;
    /* Gets the message ID of the first message in the SMS inbox */
    message_id = vm_gsm_sms_get_message_id(VM_GSM_SMS_BOX_INBOX, 0); //0 is the latest SMS.
    if(message_id == -1){
        vm_log_debug( "SMS read message ID - error occurred");
        return;
    }
 
    /* Allocates memory for the message data */
    message_data = (vm_gsm_sms_read_message_data_t*)vm_calloc(sizeof(vm_gsm_sms_read_message_data_t));
    if(message_data == NULL){
        vm_log_debug( "SMS read malloc message data has failed." );
        return;
    }
 
    /* Allocates memory for the content buffer of the message */
    content_buff = (VMWCHAR*)vm_calloc((500+1)* sizeof(VMWCHAR));
    if(content_buff == NULL){
        vm_free(message_data);
        vm_log_debug( "SMS read malloc content has failed." );
        return;
    }
    message_data->content_buffer = content_buff;
    message_data->content_buffer_size = 500;
 
    /* Reads the message */
    res = vm_gsm_sms_read_message(message_id, VM_TRUE, message_data, sms_read_sms_callback, NULL);
    if(res != VM_GSM_SMS_RESULT_OK){
        vm_free(content_buff);
        vm_free(message_data);
        vm_log_debug( "Registering read callback has failed.");
    }
}
 
 
/* The callback of sending SMS, for checking if an SMS is sent successfully. */
void sms_send_callback(vm_gsm_sms_callback_t* callback_data){
    if(callback_data->action == VM_GSM_SMS_ACTION_SEND){
        vm_log_debug("Send SMS callback, result = %d", callback_data->result);
    }
}
 
/* Sends SMS */
void sms_send_sms(void){
    VMWCHAR content[100];
    VMWCHAR num[100];
    VMINT res = 0;
    /* Sets SMS content */
    vm_chset_ascii_to_ucs2(content, 100*2, "Hello, LinkIt SMS!");
    /* Sets recipient's mobile number */
    vm_chset_ascii_to_ucs2(num, 100*2, "4088001111");
    res = vm_gsm_sms_send(num, content, sms_send_callback, NULL);
    if(res != 0){
        vm_log_debug("Sending SMS has failed!");
    }
}
 
void vm_at_callback(vm_cmd_command_t *param, void *user_data){
    VMINT delete_list_res;
    vm_log_info( "cmd = %s", ( char*)param->command_buffer);
 
    if(strcmp("SendSMS" ,(char*)param->command_buffer) == 0){
        sms_send_sms();
    }
 
    if(strcmp("ReadSMS" ,(char*)param->command_buffer) == 0){
        sms_read_sms();
    }
 
    if(strcmp("DeleteSMS" ,(char*)param->command_buffer) == 0){
        delete_list_res = vm_gsm_sms_delete_message_list(VM_GSM_SMS_BOX_INBOX, VM_GSM_SMS_SIM_1, sms_read_sms, NULL);
        if(delete_list_res == -1){
            vm_log_debug( "vm_gsm_sms_delete_message_list Error.");
            return;
        }
    }
 
    return;
}
 
/* The callback to be invoked by the system engine. */
void handle_sysevt(VMINT message, VMINT param){
    switch (message) {
        case VM_EVENT_CREATE:
            vm_cmd_open_port(AT_CMD_PORT, vm_at_callback, NULL);
            break;
        case VM_EVENT_QUIT:
            break;
    }
}
 
/* Entry point */
void vm_main( void){
    vm_pmng_register_system_event_callback(handle_sysevt);
}

Run Your Application

To run your code on the LinkIt Assist development board, follow the instructions in sections 2.6, "Compiling and Uploading to the Hardware" and 2.7, "Running your Project" of the LinkIt Assist 2502 developer’s guide.

Once the project is successfully built and compiled, in the Eclipse IDE click Monitor to send commands and view the results of their execution in the monitor. For more information on using the Monitor see section 2.9.4, "Monitor" of the LinkIt Assist 2502 developer’s guide. To exercise the application:

  1. Click Send Command on the main menu of the Monitor, as shown below.
  2. To send a SMS (see Define the SMS send function), provide the port and the command SendSMS. The SMS callback returns 1 to indicate the message was sent. Verify on the recipient's phone that the SMS was received.

  3. To verify the read SMS operation (see Define the SMS read function), send a SMS from your cell phone to the SIM in your LinkIt Assist 2502 board, then send the AT ReadSMS. The text content of the SMS will be returned.
  4. To verify the delete SMS operation (see Define the SMS delete function) send the AT command DeleteSMS. The message ID returns "sms read message id error" that indicates no SMS is present (and therefore the SMS has been deleted).

Conclusion

You’ve now successfully communicated and performed read and delete operations on the SMS data on your LinkIt Assist 2502 device using its GSM communications feature. For more information on prototyping with the MediaTek LinkIt Assist 2502 development board refer to LinkIt Assist 2502 developer’s guide.