2016-09-23 2 views
1

私はsim800lを使ってarduino UNOとAT commandsで通話しています。この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; 
} 
のリターンをチェックdoesntの

ソフトウェアのシリアル通信のATDnumberhere;のリターンがある:なしクレジット

`MO CONNECTED //instant response 

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

    OK` 

がない場合

数は ERROR

間違っている場合電話で無回答の場合

MO RING //instant response, it is ringing 

NO ANSWER // after some sec 

それは、呼び出し元の答えと

MO RING 

MO CONNECTED 

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

OK 

NO CARRIER 

をハングアップされている場合は、受信機がキャリア

ATD6985952400; 

NO CARRIER 

をしていない場合は、呼び出し元と

MO RING //instant response 

NO CARRIER // after some sec 

をハングアップされている場合質問は異なる返品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; 

にヒント変更:V.250仕様でチャプター5のすべてを読んで、それはほとんどすべてあなたをお教えしますがコマンドライン、結果コード、および応答処理について知る必要があります。以下のようなコマンドラインはまた\ronly、ない\r\nで終了されるべきであること、例えば -


CONNECTは、それが中間結果コード最終結果コードではないので、名前isFinalResponseSuccessである。なお厳密には100%正しいとは言えません。

関連する問題