2016-09-23 48 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%正確的。