How to edit the SIM800l library to make sure the call is set up

I use SIM800l to make calls using arduino UNO with AT commands . Using this library , I make calls using the gprsTest.callUp(number) function. The problem is that it returns true , even the number is incorrect, or there is no credit.

For this part of the code, it is clear that this comes from the GPRS_Shield_Arduino.cpp library . It does not check the return of ATDnumberhere;

 bool GPRS::callUp(char *number) { //char cmd[24]; if(!sim900_check_with_cmd("AT+COLP=1\r\n","OK\r\n",CMD)) { return false; } delay(1000); //HACERR quitar SPRINTF para ahorar memoria ??? //sprintf(cmd,"ATD%s;\r\n", number); //sim900_send_cmd(cmd); sim900_send_cmd("ATD"); sim900_send_cmd(number); sim900_send_cmd(";\r\n"); return true; } 

Return ATDnumberhere; for serial communication software:

If the number is incorrect ERROR

If there is no loan

  `MO CONNECTED //instant response +COLP: "003069XXXXXXXX",129,"",0,"" // after 3 sec OK` 

If he calls and does not answer

 MO RING //instant response, it is ringing NO ANSWER // after some sec 

If he calls and hangs up

 MO RING //instant response NO CARRIER // after some sec 

If the receiver does not have a carrier

 ATD6985952400; NO CARRIER 

If it's a call, answer and hang up

 MO RING MO CONNECTED +COLP: "69XXXXXXXX",129,"",0,"" OK NO CARRIER 

The question is how to use different returns for each case with this function gprsTest.callUp(number) or at least how to return true if it calls?

+1
c ++ arduino at-command
source share
1 answer

This library code seems to be better than the worst that I saw at first glance, but it still has some problems. The most serious is the processing of the final result code.

The sim900_check_with_cmd function sim900_check_with_cmd conceptually exists, however just checking for OK not acceptable. He must check every possible final result code that the modem can send. From your output examples, you have the following end result codes

  • Ok
  • MISTAKE
  • NO CARRIER
  • NO ANSWERS

but there are a few more. You can see the atinout code for an example of the is_final_result_code function (you can also compare with isFinalResponseError and isFinalResponseSuccess 1 in the ST-Ericsson U300 RIL ).

Unconditional return true; at the end of GPRS::callUp is an error, but this may be deliberate due to a lack of ideas for implementing a better API so that the calling client can check the intermediate result codes. But this is the wrong way to do it. The library really has to make all the command line calls and process the final result without any exceptions. Just doing parts of this in the library and leaving some of them to the client is just a bad design.

When customers want to check or act on intermediate result codes or information text that is between the command line and the final result code, the right way to do this is to let the library β€œdefragment” everything that it receives from the modem into separate full lines and for everything, which is not the final result code, provide this to the client through a callback function.

The following is an incomplete update to my atinout program:

 bool send_commandline( const char *cmdline, const char *prefix, void (*handler)(const char *response_line, void *ptr), void *ptr, FILE *modem) { int res; char response_line[1024]; DEBUG(DEBUG_MODEM_WRITE, ">%s\n", cmdline); res = fputs(cmdline, modem); if (res < 0) { error(ERR "failed to send '%s' to modem (res = %d)", cmdline, res); return false; } /* * Adding a tiny delay here to avoid losing input data which * sometimes happens when immediately jumping into reading * responses from the modem. */ sleep_milliseconds(200); do { const char *line; line = fgets(response_line, (int)sizeof(response_line), modem); if (line == NULL) { error(ERR "EOF from modem"); return false; } DEBUG(DEBUG_MODEM_READ, "<%s\n", line); if (prefix[0] == '\0') { handler(response_line, ptr); } else if (STARTS_WITH(response_line, prefix)) { handler(response_line + strlen(prefix) + strlen(" "), ptr); } } while (! is_final_result(response_line)); return strcmp(response_line, "OK\r\n") == 0; } 

You can use this as a basis for proper processing. If you want to get error answers from a function, add an additional callback argument and change to

  success = strcmp(response_line, "OK\r\n") == 0; if (!success) { error_handler(response_line, ptr); } return success; 

Tip. Read the entire chapter 5 in V.250 , it will teach you almost everything you need to know about command lines, result codes, and response handling. For example, so that the command line is also interrupted with \r rather than \r\n -


1 Note that CONNECT not the final result code, it is an intermediate result code, therefore the name isFinalResponseSuccess is strictly not 100% correct.

+1
source share

All Articles