[MTK] 如何发送AT命令
文摘 射频 Android MediaTek 2020-12-9 阅读:16482[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
- 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
实测效果:
以上在MT8765 android 8.1 32bit系统运行正常。
源码收费下载:
ttjluivwfr
《黄飞鸿系列之一代宗师》动作片高清在线免费观看:https://www.jgz518.com/xingkong/24922.html
游客 Windows10 25 天前回复
hrdigsqpgu
《西京故事》国产剧高清在线免费观看:https://www.jgz518.com/xingkong/31366.html
游客 Windows10 38 天前回复