ATCommand not working for checking airtime

Hey, I have been using third party sim in Boron for a project in Kigali, Because the default particle’s sim didn’t work there. Now, We have been using third party sim and want to track our usage. So the only way to do it was using ATCommands and check the remaining airtime. We’ve been using this code but it won’t work. Can anyone tell what went wrong in here ?
Thank .

/*
 * Project CreditCheck
 * Description:
 * Author:
 * Date:
 */

SYSTEM_MODE(AUTOMATIC);

//NNNNNNNNNNNNNNNNNNNNNN
int CUSD_CallBack(int type, const char* CUSD_RESPONSE, int len, char* RAW_RESPONSE);
void Check_Remaining_Credit(void);

// setup() runs once, when the device is first turned on.
void setup() {
  char* buff;
  
  int flag=Cellular.command(buff, 10000, "AT+CUSD=1,*131#,15\r\n");
  
   if(RESP_OK==flag)
  {
    //Log.info("SIM ICCID = %s\r\n", iccid);
    Particle.publish(buff);
  }
  else
  {
    //Log.info("SIM ICCID NOT FOUND!");
    Particle.publish("FAIL");
    //Particle.publish(flag);
  }

}

// loop() runs over and over again, as quickly as it can execute.
void loop() {
  // The core of your code will likely live here.

}

int CUSD_CallBack(int type, const char* CUSD_RESPONSE, int len, char* RAW_RESPONSE){

/*
  if ((type == TYPE_PLUS) && CUSD_RESPONSE) {

    if (sscanf(AT_CMD_RESPONSE, "\r\n+CCID: \r\n", CUSD_RESPONSE) == 1)
      //nothing
  }

  *13 different enumerated AT command responses passed by the system into the Cellular.command()
   callback as type
    TYPE_UNKNOWN = 0x000000
    TYPE_OK = 0x110000
    TYPE_ERROR = 0x120000
    TYPE_RING = 0x210000
    TYPE_CONNECT = 0x220000
    TYPE_NOCARRIER = 0x230000
    TYPE_NODIALTONE = 0x240000
    TYPE_BUSY = 0x250000
    TYPE_NOANSWER = 0x260000
    TYPE_PROMPT = 0x300000
    TYPE_PLUS = 0x400000
    TYPE_TEXT = 0x500000
    TYPE_ABORTED = 0x600000

*/

   CUSD_RESPONSE=RAW_RESPONSE;

    //printf("%s\n",CUSD_RESPONSE);

  // Particle.publish("Credit=",CUSD_RESPONSE);

  return WAIT; 

  /*
  Cellular.command() returns an int with one of the following 6 enumerated AT command responses:

    NOT_FOUND = 0
    WAIT = -1 // TIMEOUT  //Currently being used
    RESP_OK = -2
    RESP_ERROR = -3
    RESP_PROMPT = -4
    RESP_ABORTED = -5
*/


}

/*********************AT+CUSD command for Ublox Modem******************

>syntx

*set
AT+CUSD=[<n>[,<str>[,<dcs>]]]

*Response
[+CUSD: <m>[,<str>,<dcs>]]OK


*The parameter <n> disables/enables the URC presentation.
*Value <n>=2 is used to cancel an ongoing USSD session.
*When <str> is given, a mobile initiated USSD-string
or a response USSD-string to a network initiated operation is sent to
the network. The response USSD-string from the network is returned in
the URC +CUSD format. 

URC+CUSD: <m>[,<str>,<dcs>]

NOTE: *Command respond: up to 3 min (timeout)
      *error reference : +CME Error


>for example

//Set AT command for checking credit
  AT+CUSD=1,"*100#",15

//Response
  +CUSD: 2,"Residual credit: 7,87Euro",15OK
  OK

*/

void Check_Remaining_Credit(void){

  char RAW_RESPONSE[255] = "";
  
  int flag;

   flag=Cellular.command(CUSD_CallBack,RAW_RESPONSE, 10000, "AT+CUSD=1,*131#,15\r\n");
  

  if(RESP_OK == flag){
      
        strcmp(RAW_RESPONSE,"");
        
        Particle.publish("CUSD_CMD_SUCCESS");
        Particle.publish(RAW_RESPONSE);
    }
    else{
         Particle.publish("CUSD_CMD_FAILED");
    }

}

1 Like

That’s not the right syntax for Cellular.command. You need to provide a function to extract the data from the response. The AT+CUSD command is a + response when use with the first parameter 1, so it should be like the ICCID example in the docs:

Can you tell that according to my code ?
The documentation is a bit confusing.

You didn’t specify the callback. It should look like:

int flag=Cellular.command(CUSD_CallBack, buff, 10000, "AT+CUSD=1,*131#,15\r\n");

Also the callback is searching for the wrong response. It should be:

if (sscanf(AT_CMD_RESPONSE, "\r\n+CUSD: \r\n", CUSD_RESPONSE) == 1)
1 Like

Hi I am working on this problem with @hannanmustajab. I followed your suggested solution on this issue (see code) but we are still failing to get the response… We would like to ask more support. Thank you…

SYSTEM_MODE(AUTOMATIC);

SerialLogHandler logHandler;

//NNNNNNNNNNNNNNNNNNNNNN- Call back function prototype
int CUSD_CallBack(int type, const char* CUSD_RESPONSE, int len, char* RAW_RESPONSE);
//NNNNNNNNNNNNNNNNNNNNNN-- Check credit  prototype
void Check_Remaining_Credit(void);
//-------------------------------------------------------------------------------------

void setup() {
    Check_Remaining_Credit();
}

void loop() {
    // your loop code
}
//buff                        //iccid
int CUSD_CallBack(int type, const char* CUSD_RESPONSE, int len, char* RAW_RESPONSE){
    if ((type == TYPE_PLUS) && RAW_RESPONSE) {
        if (sscanf(CUSD_RESPONSE,"\r\n+CUSD: %[^\r] \r\n", RAW_RESPONSE) == 1)
            /*nothing*/;
    }
    return WAIT;
}

void Check_Remaining_Credit(void) {
    char RAW_RESPONSE[255] = "";
    if ((RESP_OK == Cellular.command(CUSD_CallBack, RAW_RESPONSE, 10000, "AT+CUSD=1,*131#,15\r\n"))
        && (strcmp(RAW_RESPONSE,"") != 0))
    {
        Log.info("SIM CUSD = %s\r\n", RAW_RESPONSE);
        Particle.publish(RAW_RESPONSE);
        Particle.publish("CUSD_CMD_SUCCESS");
    }
    else
    {
        Log.info("CUSD CMD FAILED!");
        Particle.publish("CUSD_CMD_FAILED");
    }
}
if (sscanf(CUSD_RESPONSE,"\r\n+CUSD: %[^\r] \r\n", RAW_RESPONSE) == 1)
                                           ^ you have an extra space here

Thank you a lot… let me test this. Your valuable assistance is appreciate

@rickkas7 Still doesnt work. We would like to ask more support. Thank you…

You’ll have to add more debugging code to figure out what’s failing. Are you getting a response at all? Does it just not match the pattern? Is it something other than +CUSD? Is it a different format?