如何编辑SIM800l库以确保建立通话 [英] How to edit SIM800l library to ensure that a call is established

查看:22
本文介绍了如何编辑SIM800l库以确保建立通话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 SIM800l 通过 AT 命令与 arduino UNO 进行通话.通过使用这个,我可以使用 gprsTest.callUp(number) 拨打电话功能.问题是它返回 true 即使数字错误或没有信用.

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

GPRS_Shield_Arduino.cpp库 为什么会这样.它不检查 ATDnumberhere;

It is clear on this part code from GPRS_Shield_Arduino.cpp library why it is happening. It doesnt 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;
}

ATDnumberhere;在软件串口通信中的返回为:

The return of ATDnumberhere; on software serial communication is:

如果号码错误错误

如果没有信用

 `MO CONNECTED  //instant response

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

  OK`

如果它正在呼叫而无人接听

If it is calling and no answer

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

问题是如何通过此函数 gprsTest.callUp(number) 为每种情况使用不同的返回值,或者至少如何在振铃时返回 true ?

The question is how to use different returns for every case by this function gprsTest.callUp(number) , or at least how to return true if it is ringing ?

推荐答案

这个库代码乍一看似乎比我见过的最糟糕的要好,但它仍然存在一些问题.最严重的是它的最终结果代码处理.

This library code seems better than the worst I have seen at first glance, but it still have some issues. The most severe is its Final result code handling.

sim900_check_with_cmd 函数在概念上几乎已经存在,但是仅检查 OK 绝不是可接受的.它应该检查调制解调器可能发送的每个可能的最终结果代码.从您的输出示例中,您有以下最终结果代码

The sim900_check_with_cmd function is conceptually almost there, however only checking for OK is in no way acceptable. It should check for every single possible final result code the modem might send. From your output examples you have the following final result codes

  • 好的
  • 错误
  • 无载体
  • 没有答案

但还有一些.您可以查看 atinout 的代码以获得is_final_result_code 函数的示例(您还可以与 ST-Ericsson 的 U300 RIL).

but there exists a few more as well. You can look at the code for atinout for an example of a is_final_result_code function (you can also compare to isFinalResponseError and isFinalResponseSuccess1 in ST-Ericsson's U300 RIL).

GPRS::callUp 末尾的无条件 return true; 是一个错误,但由于缺乏实现更好 API 的想法,因此可能是故意的调用客户端可以检查中间结果代码.但这是一种错误的做法.该库确实应该毫无例外地执行所有有状态的命令行调用和最终结果代码解析.只是在库中完成部分工作,而将一部分留给客户是糟糕的设计.

The unconditional return true; at the end of GPRS::callUp is an error, but it might be deliberate due to lack of ideas for implementing a better API so that the calling client could check the intermediate result codes. But that is such a wrong way to do it. The library really should do all the stateful command line invocation and final result code parsing with no exceptions. Just doing parts of that in the library and leaving some of it up to the client is just bad design.

当客户端想要检查或处理命令行和最终结果代码之间的中间结果代码或信息文本时,正确的做法是让库将其从调制解调器接收的所有内容解构"为单独的完整行,对于不是最终结果代码的所有内容,通过回调函数将其提供给客户端.

When clients want to inspect or act on intermediate result codes or information text that comes between the command line and the final result code, the correct way to do it is to let the library "deframe" everything it receives from the modem into individual complete lines, and for everything that is not a final result code provide this to the client through a callback function.

以下内容来自对我的 atinout 程序的未完成更新:

The following is from an unfinished 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 that as a basis for implementing proper handling. If you want to get error responses out of the 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;

<小时>

提示:阅读第 5 章的全部内容V.250 规范,它将教你几乎所有你需要知道的关于命令行、结果代码和响应处理的知识.例如,命令行也应该以 \r only 结束,而不是 \r\n-


Tip: Read all of chapter 5 in the V.250 specification, it will teach you almost everything you need to know about command lines, result codes and response handling. Like for instance that a command line should also be terminated with \r only, not \r\n-

1 注意CONNECT不是最终结果码,是中间结果码,所以严格来说isFinalResponseSuccess这个名字不是100%正确的.

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

这篇关于如何编辑SIM800l库以确保建立通话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆