[MTK] 如何发送AT命令

文摘 射频 Android MediaTek 2020-12-9 阅读:16343

[DESCRIPTION]

 本FAQ说明三种情况下如何发送AT命令:

1. 在Phone进程发送AT命令

2. 在其他Java进程发送AT命令

3. 在Native进程发送AT命令

[SOLUTION]

1.在Phone进程发送AT命令

  参考FAQ02918  [AT]如何在java层直接下发at cmd

2.其他Java进程发送AT命令

AT命令只需要发送给卡1:

  调用TelephonyManager.invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp);

AT命令需要发送给卡1/卡2:

Step 1:

  /vendor/mediatek/proprietary/frameworks/base/telephony/java/com/mediatek/telephony/TelephonyManagerEx.java

  //添加函数:add-start

  public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp, int slotId){

        try {

            ITelephonyEx telephony = getITelephonyEx();

            if (telephony != null)

                return telephony.invokeOemRilRequestRaw(oemReq, oemResp, slotId);

        } catch (RemoteException ex) {

        } catch (NullPointerException ex) {

        }

        return -1;

  }//add-end

Step 2:

  /frameworks/base/telephony/java/com/mediatek/internal/telephony/ITelephonyEx.aidl

  添加接口:  int invokeOemRilRequestRaw(in byte[] oemReq, out byte[] oemResp, int slotId);

Step 3:

  在/packages/services/Telephony/src/com/mediatek/phone/PhoneInterfaceManagerEx.java

  //增加常量定义 add-start

  private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = **;

  private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = **;

  //add-end

 //增加函数 add-start

  public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp, int slotId) {

    enforceModifyPermission();

    int returnValue = 0;

        try {

                                    Phone phone=PhoneFactory.getPhone(slotId);

            AsyncResult result = (AsyncResult)sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, phone, oemReq);

            if(result.exception == null) {

                if (result.result != null) {

                    byte[] responseData = (byte[])(result.result);

                    if(responseData.length > oemResp.length) {

                        Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +

                                responseData.length +  "bytes. Buffer Size is " +

                                oemResp.length + "bytes.");

                    }

                    System.arraycopy(responseData, 0, oemResp, 0, responseData.length);

                    returnValue = responseData.length;

                }

            } else {

                CommandException ex = (CommandException) result.exception;

                returnValue = ex.getCommandError().ordinal();

                if(returnValue > 0) returnValue *= -1;

            }

        } catch (RuntimeException e) {

            Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");

            returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());

            if(returnValue > 0) returnValue *= -1;

        }

        return returnValue;

    } //add-end

  在MainThreadHandler.handleMessage()中添加:

  // add-start

                    case CMD_INVOKE_OEM_RIL_REQUEST_RAW:

                    request = (MainThreadRequest)msg.obj;

                    onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);

                                                                                final Phone phone = (Phone) request.argument;

                    phone.invokeOemRilRequestRaw((byte[])request.argument2, onCompleted);

                    break;

                                                                                case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:

                    ar = (AsyncResult)msg.obj;

                    request = (MainThreadRequest)ar.userObj;

                    request.result = ar;

                    synchronized (request) {

                        request.notifyAll();

                    }

                    break;

// add-end
  1. Native进程发送AT命令

  Step 1:

  /vendor/mediatek/proprietary/hardware/ril/gsm/librilmtk/ril.cpp

  static int handleSpecialRequestWithArgs(int argCount, char** args){

  //在函数最后添加 add-start

  else if (strcmp(cmd, "YOUR_CUSTOM_CMD_SEND_TO_RIL") == 0) { //YOUR_CUSTOM_CMD_SEND_TO_RIL修改为自定义名称

            memset(org_args, 0, sizeof(org_args));

            sprintf(org_args, "AT_COMMAND_YOU_WANT_TO_SEND"); //这里替换成为想要发送的AT命令

                                                int targetSim = 0;// 0发送给卡1,1发送给卡2

                                                issueLocalRequestForResponse(RIL_LOCAL_REQUEST_SEND_COMMAND, org_args, strlen(org_args), (RIL_SOCKET_ID)targetSim);

            close(s_fdOem_command);

            s_fdOem_command = -1;

            return 1;

                                } else {

            // invalid request

            LOGD("invalid request");

            goto error;

        }

//在函数最后添加 add-end                      

Step 2:

  //在需要发送AT命令的文件中添加下面代码,然后调用send_to_ril()

  //add-start                      

  #define YOUR_CUSTOM_SOCKET_NAME "rild-oem"

  //add-end

  //add-start

  static int connect_socket() {

    int fd = socket_local_client(YOUR_CUSTOM_SOCKET_NAME,

                  ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);

    if(fd < 0) {

                //这里表示socket连接不成功,建议在这里处理。比如延迟1s再调用上面的函数连接socket,尝试几次。从log看,rild会比audio晚3s。

        //KLOG_ERROR(LOG_TAG, "Fail to connect to socket rild-ocm. return code: %d", fd);

        return -1;

    }

    return fd;

}

//cmd: YOUR_CUSTOM_CMD_SEND_TO_RIL 自定义命令

static int send_to_ril(char *cmd) {

    int ret = 0;

    int command_len = strlen(cmd);

    char *command = NULL;

    int fd = connect_socket();

    if (fd < 0) {

        ret = -1;

        goto error;

    }

    command_len = command_len + 1;

    command = (char *)malloc(sizeof(char) * command_len);

    memset(command, 0, sizeof(char) * command_len);

    strcpy(command,cmd)

    ret = send_data(fd, 1, command_len, command);

  error:

    if (command != NULL) {

        free(command);

    }

    if (fd >= 0) {

        disconnect_socket(fd);

    }

    return ret;

 }

  static int send_data(int fd, int arg_count, uint32_t data_length, const void *data) {

    int ret = 0;

    //(send-1)send argCount

    if(send(fd, (const void*)&arg_count, sizeof(int), 0) != sizeof(int)) {

        ret = -1;

        goto error;

    }

    //(send-2)send data length

    if(send(fd, (const void*)&data_length, sizeof(int), 0) != sizeof(int)) {

        ret = -1;

        goto error;

    }

    //KLOG_INFO(LOG_TAG, "(send-3). data: %s", (char *)data);

    if(send(fd, (const void*)data, data_length, 0) != (int)data_length) {

        ret = -1;

        goto error;

    }

   error:

    KLOG_INFO(LOG_TAG, "[send_data] Ret:%d.", ret);

    return ret;

  }

  int disconnect_socket(int fd) {

    if(fd < 0) {

        //KLOG_ERROR(LOG_TAG, "[disconnect_socket] Invalid fd: %d", fd);

        return -1;

    }

   return close(fd);

  }

//add-end

实测效果:

readme.png

以上在MT8765 android 8.1 32bit系统运行正常。
源码收费下载:

0条评论

    hrdigsqpgu

    《西京故事》国产剧高清在线免费观看:https://www.jgz518.com/xingkong/31366.html

    游客 Windows10 8 天前回复

© 2024 芯缘异码. Powered by Typecho