2016-09-23 51 views
1

我使用SIM800l通过使用AT commands的arduino UNO拨打电话。通过使用这个library我使用gprsTest.callUp(number)功能拨打电话。问题是它返回true即使数字是错误的或没有信用。如何编辑SIM800l库以确保呼叫建立

这部分代码清楚地表明GPRS_Shield_Arduino.cpp library为什么会发生。它不检查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; 
} 
返回

ATDnumberhere;软件串行通信的回报是:

如果号码有误 ERROR

如果没有信用

`MO CONNECTED //instant response 

    +COLP: "003069XXXXXXXX",129,"",0,"" // after 3 sec 

    OK` 

如果是通话而没有回答

MO RING //instant response, it is ringing 

NO ANSWER // after some sec 

如果通话和挂断

MO RING //instant response 

NO CARRIER // after some sec 

如果接收机没有载体

ATD6985952400; 

NO CARRIER 

如果呼叫,接听和挂断

MO RING 

MO CONNECTED 

+COLP: "69XXXXXXXX",129,"",0,"" 

OK 

NO CARRIER 

问题是如何使用不同的回报f或通过这个函数gprsTest.callUp(number),或至少如何返回true,如果它正在振铃?

回答

1

这个库代码看起来比我乍看之下看到的最差,但它仍然有一些问题。最严重的是其最终结果代码处理。

sim900_check_with_cmd功能在概念上几乎就在那里,但只有检查OK是不可接受的。它应该检查调制解调器可能发送的每个可能的最终结果代码。 从你的输出例子有以下最终结果代码

  • OK
  • ERROR
  • NO CARRIER
  • NO ANSWER

,但存在一些的还有很多。您可以查看atinout的代码,查看is_final_result_code函数的示例(您也可以与isFinalResponseErrorisFinalResponseSuccessST-Ericsson's U300 RIL进行比较)。

GPRS::callUp末尾的无条件return true;是一个错误,但由于缺少实现更好的API的想法,因此调用客户端可以检查中间结果代码,这可能是故意的。但那是一种错误的做法。 库实际上应该做所有有状态的命令行调用和最终结果代码解析,没有例外。只是在图书馆做部分内容,而把部分内容留给客户是不好的设计。

当客户端想要检查或操作中间结果代码或在命令行和最终结果代码之间的信息文本时,正确的方法是让库“去除”从调制解调器接收的所有内容分成单独的完整行,并且不是最终结果代码的所有内容都通过回调函数将其提供给客户端。

下面是一个未完成的更新到我的atinout程序:

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; 
} 

您可以使用它作为实施妥善处理的基础。如果你想 得到错误的反应出来的功能,添加一个额外的回调参数,并切换到

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

提示:阅读所有的第5章中V.250规范,它会教你几乎所有你需要了解命令行,结果代码和响应处理。像例如,一个命令行应也与\ronly,不\r\n终止 -


注意CONNECT不是最终结果的代码,它是一个中间结果的代码,所以名称isFinalResponseSuccess是严格来说不是100%正确的。