如下的demo实现中,处理响应的token、type、error是否正确?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <fcntl.h>
#include <cutils/log.h>
#include <time.h>
#include <sys/stat.h>
#include <dirent.h>
#include <arpa/inet.h>
#include <poll.h>
#include <netinet/in.h>
// 使用本地LOG_TAG定义
#undef LOG_TAG
#define LOG_TAG "RilDataDemo"
// RIL常量定义
#define RIL_REQUEST_SETUP_DATA_CALL 27
#define RIL_E_SUCCESS 0
#define RIL_E_RADIO_NOT_AVAILABLE 1
#define RIL_E_GENERIC_FAILURE 2
#define RIL_E_PASSWORD_INCORRECT 3
#define RIL_E_SIM_PIN2 4
#define RIL_E_SIM_PUK2 5
#define RIL_E_REQUEST_NOT_SUPPORTED 6
#define RIL_E_CANCELLED 7
#define RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL 8
#define RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW 9
#define RIL_E_SMS_SEND_FAIL_RETRY 10
#define RIL_E_SIM_ABSENT 11
#define RIL_E_SUBSCRIPTION_NOT_AVAILABLE 12
#define RIL_E_MODE_NOT_SUPPORTED 13
#define SOCKET_PATH "/dev/socket/qcrild/rild0"
#define MAX_PAYLOAD 4096
#define RETRY_DELAY 2
#define MAX_RETRIES 3
#define RESPONSE_TIMEOUT_MS 15000
// 字符串序列化宏
#define SERIALIZE_STRING(str) \
do { \
size_t len = str ? strlen(str) + 1 : 0; \
uint32_t net_len = htonl(len); \
if (written + sizeof(net_len) + len > max_size) goto overflow; \
memcpy(p, &net_len, sizeof(net_len)); p += sizeof(net_len); written += sizeof(net_len); \
if (str && len > 0) { \
memcpy(p, str, len); p += len; written += len; \
} \
} while(0)
// 枚举定义
typedef enum {
RIL_RADIO_ACCESS_NETWORK_UNKNOWN = 0,
RIL_RADIO_ACCESS_NETWORK_GPRS,
RIL_RADIO_ACCESS_NETWORK_EDGE,
RIL_RADIO_ACCESS_NETWORK_UMTS,
RIL_RADIO_ACCESS_NETWORK_IS95A,
RIL_RADIO_ACCESS_NETWORK_IS95B,
RIL_RADIO_ACCESS_NETWORK_1xRTT,
RIL_RADIO_ACCESS_NETWORK_EVDO_0,
RIL_RADIO_ACCESS_NETWORK_EVDO_A,
RIL_RADIO_ACCESS_NETWORK_HSDPA,
RIL_RADIO_ACCESS_NETWORK_HSUPA,
RIL_RADIO_ACCESS_NETWORK_HSPA,
RIL_RADIO_ACCESS_NETWORK_EVDO_B,
RIL_RADIO_ACCESS_NETWORK_EHRPD,
RIL_RADIO_ACCESS_NETWORK_LTE,
RIL_RADIO_ACCESS_NETWORK_NR
} RIL_RadioAccessNetworks;
typedef enum {
RIL_RADIO_DATA_REQUEST_REASON_NORMAL = 0,
RIL_RADIO_DATA_REQUEST_REASON_HANDOVER
} RIL_RadioDataRequestReasons;
// 数据结构定义
typedef struct {
int profileId;
char* apn;
char* protocol;
char* roamingProtocol;
int authType;
char* user;
char* password;
int type;
int maxConnsTime;
int maxConns;
int waitTime;
int enabled;
int supportedTypesBitmask;
int bearerBitmask;
int mtu;
int preferred;
int persistent;
} RIL_DataProfileInfo_IRadio_1_4;
typedef struct {
RIL_RadioAccessNetworks accessNetwork;
RIL_DataProfileInfo_IRadio_1_4 profileInfo;
uint8_t roamingAllowed;
RIL_RadioDataRequestReasons reason;
char* addresses;
char* dnses;
} RIL_SetUpDataCallParams;
typedef struct {
int status;
int suggestedRetryTime;
int cid;
int active;
char* type;
char* ifname;
char* addresses;
char* dnses;
char* gateways;
char* pcscf;
int mtu;
} RIL_Data_Call_Response_v11;
// typedef struct {
// uint32_t request_id; // 大端序
// uint32_t token; // 大端序
// } RIL_RequestHeader;
typedef struct {
uint32_t length; // 大端序(整个消息长度)
uint32_t request_id; // 大端序
uint32_t token; // 大端序
} RIL_RequestHeader;
// typedef struct {
// uint32_t token; // 大端序
// uint32_t error; // 大端序
// // 可变长度payload
// } RIL_ResponseHeader;
// 检查调制解调器状态
int is_modem_ready() {
DIR *dir = opendir("/sys/class/net");
if (!dir) {
ALOGE("Cannot open /sys/class/net");
return 0;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
if (strstr(entry->d_name, "rmnet") || strstr(entry->d_name, "wwan")) {
closedir(dir);
return 1;
}
}
closedir(dir);
return 0;
}
// 序列化DataCall请求
size_t serialize_setup_data_call_request(
RIL_SetUpDataCallParams *req,
uint8_t *buffer,
size_t max_size
) {
uint8_t *p = buffer;
size_t written = 0;
// 1. accessNetwork (4 bytes)
uint32_t net_access = htonl(req->accessNetwork);
memcpy(p, &net_access, 4);
p += 4; written += 4;
// 2. profileInfo 结构体
RIL_DataProfileInfo_IRadio_1_4 *profile = &req->profileInfo;
// profileId (4 bytes)
uint32_t net_profileId = htonl(profile->profileId);
memcpy(p, &net_profileId, 4);
p += 4; written += 4;
// apn (string)
SERIALIZE_STRING(profile->apn);
// protocol (string)
SERIALIZE_STRING(profile->protocol);
// roamingProtocol (string)
SERIALIZE_STRING(profile->roamingProtocol);
// authType (4 bytes)
uint32_t net_authType = htonl(profile->authType);
memcpy(p, &net_authType, 4);
p += 4; written += 4;
// user (string)
SERIALIZE_STRING(profile->user);
// password (string)
SERIALIZE_STRING(profile->password);
// type (4 bytes)
uint32_t net_type = htonl(profile->type);
memcpy(p, &net_type, 4);
p += 4; written += 4;
// maxConnsTime (4 bytes)
uint32_t net_maxConnsTime = htonl(profile->maxConnsTime);
memcpy(p, &net_maxConnsTime, 4);
p += 4; written += 4;
// maxConns (4 bytes)
uint32_t net_maxConns = htonl(profile->maxConns);
memcpy(p, &net_maxConns, 4);
p += 4; written += 4;
// waitTime (4 bytes)
uint32_t net_waitTime = htonl(profile->waitTime);
memcpy(p, &net_waitTime, 4);
p += 4; written += 4;
// enabled (4 bytes)
uint32_t net_enabled = htonl(profile->enabled);
memcpy(p, &net_enabled, 4);
p += 4; written += 4;
// supportedTypesBitmask (4 bytes)
uint32_t net_supportedTypes = htonl(profile->supportedTypesBitmask);
memcpy(p, &net_supportedTypes, 4);
p += 4; written += 4;
// bearerBitmask (4 bytes)
uint32_t net_bearerBitmap = htonl(profile->bearerBitmask);
memcpy(p, &net_bearerBitmap, 4);
p += 4; written += 4;
// mtu (4 bytes)
uint32_t net_mtu = htonl(profile->mtu);
memcpy(p, &net_mtu, 4);
p += 4; written += 4;
// preferred (4 bytes) - 必须包含
uint32_t net_preferred = htonl(profile->preferred);
memcpy(p, &net_preferred, 4);
p += 4; written += 4;
// persistent (4 bytes) - 必须包含
uint32_t net_persistent = htonl(profile->persistent);
memcpy(p, &net_persistent, 4);
p += 4; written += 4;
// 3. roamingAllowed (4 bytes)
uint32_t net_roaming = htonl(req->roamingAllowed ? 1 : 0);
memcpy(p, &net_roaming, 4);
p += 4; written += 4;
// 4. reason (4 bytes)
uint32_t net_reason = htonl(req->reason);
memcpy(p, &net_reason, 4);
p += 4; written += 4;
// 修改:addresses改为字符串数组(非单个字符串)
uint32_t addr_count = req->addresses ? 1 : 0;
uint32_t net_addr_count = htonl(addr_count);
memcpy(p, &net_addr_count, 4); p += 4; written += 4;
if (addr_count > 0) {
SERIALIZE_STRING(req->addresses);
}
// 修改:dnses改为字符串数组
uint32_t dns_count = req->dnses ? 1 : 0;
uint32_t net_dns_count = htonl(dns_count);
memcpy(p, &net_dns_count, 4); p += 4; written += 4;
if (dns_count > 0) {
SERIALIZE_STRING(req->dnses);
}
// // 5. addresses (string) - 使用空字符串而不是NULL
// const char *addresses = req->addresses ? req->addresses : "";
// SERIALIZE_STRING(addresses);
// // 6. dnses (string) - 使用空字符串而不是NULL
// const char *dnses = req->dnses ? req->dnses : "";
// SERIALIZE_STRING(dnses);
// 调试:打印完整payload
ALOGD("Serialized payload content (hex, %zu bytes):", written);
for (size_t i = 0; i < written; i++) {
if (i % 16 == 0 && i > 0) ALOGD("");
ALOGD("%02X ", buffer[i]);
}
ALOGD("");
return written;
overflow:
ALOGE("Buffer overflow in serialization");
return 0;
}
// 完整读取数据(带超时)
ssize_t read_full(int fd, void *buf, size_t count, int timeout_ms) {
size_t total_read = 0;
uint8_t *ptr = (uint8_t *)buf;
struct pollfd pfd = {
.fd = fd,
.events = POLLIN,
.revents = 0
};
while (total_read < count) {
int ret = poll(&pfd, 1, timeout_ms);
if (ret <= 0) {
if (ret == 0) {
ALOGE("Poll timeout during read");
return -1;
}
ALOGE("Poll error during read: %s", strerror(errno));
return -1;
}
ssize_t n = read(fd, ptr + total_read, count - total_read);
if (n <= 0) {
if (n == 0) {
ALOGE("Peer closed connection");
return -1;
}
if (errno == EAGAIN || errno == EWOULDBLOCK) {
continue;
}
ALOGE("Read error: %s", strerror(errno));
return -1;
}
total_read += n;
}
return total_read;
}
// 连接到RILD (带重试)
int connect_to_rild() {
int retries = 5;
int sock_fd = -1;
while (retries-- > 0) {
if (!is_modem_ready()) {
ALOGW("Modem not ready, waiting...");
sleep(RETRY_DELAY);
continue;
}
sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock_fd < 0) {
ALOGE("socket creation failed: %s", strerror(errno));
sleep(1);
continue;
}
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1);
if (connect(sock_fd, (struct sockaddr*)&addr, sizeof(addr))) {
// 获取socket属性
struct stat st;
if (stat(SOCKET_PATH, &st) == 0) {
ALOGE("Socket exists! Permissions: %o, UID:%d GID:%d",
st.st_mode & 0777, st.st_uid, st.st_gid);
char cmd[128];
sprintf(cmd, "ls -l %s", SOCKET_PATH);
system(cmd);
}
ALOGE("connect to %s failed (retry %d): %s",
SOCKET_PATH, 5 - retries, strerror(errno));
close(sock_fd);
sleep(1);
continue;
}
// 设置非阻塞模式
int flags = fcntl(sock_fd, F_GETFL, 0);
if (flags == -1) {
ALOGE("fcntl F_GETFL failed: %s", strerror(errno));
close(sock_fd);
sleep(1);
continue;
}
if (fcntl(sock_fd, F_SETFL, flags | O_NONBLOCK) == -1) {
ALOGE("fcntl F_SETFL failed: %s", strerror(errno));
close(sock_fd);
sleep(1);
continue;
}
return sock_fd;
}
if (sock_fd < 0) {
// 新增 RILD 进程检查
if (system("ps -A | grep -q qcrilNrd") != 0) {
ALOGE("RILD process not running!");
} else {
ALOGE("Socket exists but connection refused. Check RILD permissions");
}
}
return -1;
}
// 连接成功后
int negotiate_version(int sock_fd) {
uint32_t version = htonl(12);
uint8_t buffer[4]; // 改为只发送4字节
memcpy(buffer, &version, 4);
ssize_t sent = write(sock_fd, buffer, 4); // 只发送4字节
if (sent != 4) {
ALOGE("Version negotiation failed: %s", strerror(errno));
return -1;
}
// 读取响应(应为4字节)
uint32_t response;
if (read_full(sock_fd, &response, 4, 2000) != 4) {
ALOGE("Version response read failed");
return -1;
}
response = ntohl(response);
ALOGD("Version negotiation response: 0x%X", response);
return (response == 12) ? 0 : -1; // 成功响应应为协商的版本号
}
// int negotiate_version(int sock_fd) {
// uint32_t version = htonl(12); // 修改为RILD报告的版本12
// ssize_t sent = write(sock_fd, &version, sizeof(version));
// if (sent != sizeof(version)) {
// ALOGE("Version negotiation failed: %s", strerror(errno));
// return -1;
// }
// uint32_t response;
// if (read_full(sock_fd, &response, sizeof(response), 2000) != sizeof(response)) {
// ALOGE("Version response read failed");
// return -1;
// }
// response = ntohl(response);
// ALOGD("Version negotiation response: 0x%X", response);
// // 接受版本12或0(兼容模式)
// return (response == 12 || response == 0) ? 0 : -1;
// }
// 检查接口是否存在
int check_interface_exists(const char *ifname) {
if (!ifname || ifname[0] == '\0') {
return 0;
}
DIR *dir = opendir("/sys/class/net");
if (!dir) {
ALOGW("Cannot open /sys/class/net to check interface");
return 0;
}
struct dirent *entry;
int found = 0;
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ifname) == 0) {
found = 1;
break;
}
}
closedir(dir);
return found;
}
// 错误代码转字符串
const char *ril_error_to_string(uint32_t error) {
switch (error) {
case RIL_E_SUCCESS: return "Success";
case RIL_E_RADIO_NOT_AVAILABLE: return "Radio not available";
case RIL_E_GENERIC_FAILURE: return "Generic failure";
case RIL_E_PASSWORD_INCORRECT: return "Password incorrect";
case RIL_E_SIM_PIN2: return "SIM PIN2 required";
case RIL_E_SIM_PUK2: return "SIM PUK2 required";
case RIL_E_REQUEST_NOT_SUPPORTED: return "Request not supported";
case RIL_E_CANCELLED: return "Cancelled";
case RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL: return "Not allowed during voice call";
case RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW: return "Not allowed before network registration";
case RIL_E_SMS_SEND_FAIL_RETRY: return "SMS send failed, retry";
case RIL_E_SIM_ABSENT: return "SIM absent";
case RIL_E_SUBSCRIPTION_NOT_AVAILABLE: return "Subscription not available";
case RIL_E_MODE_NOT_SUPPORTED: return "Mode not supported";
default: return "Unknown error";
}
}
// 解析DataCall响应 (v11格式)
void parse_data_call_response_v11(uint8_t *payload, size_t payload_len, RIL_Data_Call_Response_v11 *resp) {
if (payload_len < 16) {
ALOGW("Response payload too short: %zu bytes", payload_len);
return;
}
uint8_t *p = payload;
// 1. 解析基本字段
resp->status = ntohl(*(int32_t*)p); p += 4;
resp->suggestedRetryTime = ntohl(*(int32_t*)p); p += 4;
resp->cid = ntohl(*(int32_t*)p); p += 4;
resp->active = ntohl(*(int32_t*)p); p += 4;
// 2. 解析字符串字段
#define PARSE_STRING(dest) \
do { \
uint32_t len = ntohl(*(uint32_t*)p); p += 4; \
if (len > 0 && (size_t)(p - payload + len) <= payload_len) { \
dest = strndup((char*)p, len); \
p += len; \
} else { \
dest = NULL; \
} \
} while(0)
PARSE_STRING(resp->type);
PARSE_STRING(resp->ifname);
PARSE_STRING(resp->addresses);
PARSE_STRING(resp->dnses);
PARSE_STRING(resp->gateways);
PARSE_STRING(resp->pcscf);
// 3. 解析MTU字段
if ((size_t)(p - payload + sizeof(int32_t)) <= payload_len) {
resp->mtu = ntohl(*(int32_t*)p);
p += 4;
} else {
resp->mtu = -1;
}
// 4. 记录结果
ALOGI("Data call response: status=%d, cid=%d, iface=%s",
resp->status, resp->cid, resp->ifname ? resp->ifname : "N/A");
ALOGD("Type: %s", resp->type ? resp->type : "N/A");
ALOGD("Addresses: %s", resp->addresses ? resp->addresses : "N/A");
ALOGD("MTU: %d", resp->mtu);
}
// 释放响应资源
void free_data_call_response(RIL_Data_Call_Response_v11 *resp) {
if (resp->type) free(resp->type);
if (resp->ifname) free(resp->ifname);
if (resp->addresses) free(resp->addresses);
if (resp->dnses) free(resp->dnses);
if (resp->gateways) free(resp->gateways);
if (resp->pcscf) free(resp->pcscf);
}
// 主函数
int main() {
ALOGD("Starting RIL Data Call Demo...");
// 诊断信息
ALOGD("Checking modem status...");
DIR *dir = opendir("/sys/class/net");
if (dir) {
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
if (strstr(entry->d_name, "rmnet") || strstr(entry->d_name, "wwan")) {
ALOGI("Found data interface: %s", entry->d_name);
}
}
closedir(dir);
}
// 检查RILD socket
struct stat st;
if (stat(SOCKET_PATH, &st) == 0) {
ALOGD("RILD socket exists, size: %ld, mode: %o", st.st_size, st.st_mode);
} else {
ALOGW("RILD socket not found: %s", strerror(errno));
}
// 1. 连接到RILD
int ril_fd = connect_to_rild();
if (ril_fd < 0) {
ALOGE("Failed to connect to RILD");
return EXIT_FAILURE;
}
ALOGD("Connected to RILD socket: %s", SOCKET_PATH);
// 在连接后调用
if (negotiate_version(ril_fd) < 0) {
ALOGE("Version negotiation failed");
close(ril_fd);
return EXIT_FAILURE;
}
// 2. 准备数据连接请求
RIL_SetUpDataCallParams data_call_req = {
.accessNetwork = 20,
.roamingAllowed = 1,
.reason = RIL_RADIO_DATA_REQUEST_REASON_NORMAL,
.addresses = "",
.dnses = ""
};
RIL_DataProfileInfo_IRadio_1_4 profile = {
.profileId = 0,
.apn = "ctnet",
.protocol = "IPV4V6",
.roamingProtocol = "IPV4V6",
.authType = 0,
.user = "",
.password = "",
.type = 1,
.maxConnsTime = 0,
.maxConns = 0,
.waitTime = 0,
.enabled = 1,
.supportedTypesBitmask = 0,
.bearerBitmask = 0,
.mtu = 1500,
.preferred = 1,
.persistent = 0
};
// // 更新为RIL 1.2参数格式
// RIL_SetUpDataCallParams data_call_req = {
// .accessNetwork = 20,
// .roamingAllowed = 1,
// .reason = RIL_RADIO_DATA_REQUEST_REASON_NORMAL,
// // .addresses = "192.168.1.100", // 示例IP
// // .dnses = "8.8.8.8" // 示例DNS
// // 配置实际获取的 IP 地址
// .addresses = "10.117.38.103,240e:46d:3b10:f6:a898:9cff:fefb:f6d2",
// // 配置公共 DNS 服务器
// .dnses = "114.114.114.114,2001:4860:4860::8888"
// };
// // 使用RIL 1.2标准APN类型
// RIL_DataProfileInfo_IRadio_1_4 profile = {
// .profileId = 0,
// .apn = "ctnet",
// .protocol = "IP",
// .roamingProtocol = "IP",
// .authType = 0,
// .user = "",
// .password = "",
// .type = 1,
// .maxConnsTime = 0,
// .maxConns = 0,
// .waitTime = 0,
// .enabled = 1,
// .supportedTypesBitmask = (1 << 0), // DEFAULT类型
// .bearerBitmask = 0,
// .mtu = 1500,
// .preferred = 1,
// .persistent = 0
// };
data_call_req.profileInfo = profile;
// 3. 序列化请求
uint8_t payload[MAX_PAYLOAD];
size_t payload_len = serialize_setup_data_call_request(&data_call_req, payload, sizeof(payload));
if (payload_len == 0) {
ALOGE("Payload serialization failed");
close(ril_fd);
return EXIT_FAILURE;
}
ALOGD("Serialized payload size: %zu", payload_len);
// 4. 构建请求(无长度头)
// RIL_RequestHeader header = {
// .request_id = htonl(RIL_REQUEST_SETUP_DATA_CALL),
// .token = htonl(1)
// };
// size_t full_msg_size = sizeof(RIL_RequestHeader) + payload_len - sizeof(uint32_t);
// uint8_t *full_msg = malloc(full_msg_size);
// // 复制请求头和payload
// memcpy(full_msg, &header, sizeof(header));
// memcpy(full_msg + sizeof(header), payload, payload_len);
// 填充请求头
// RIL_RequestHeader header = {
// // .length = htonl(full_msg_size), // 包含头部自身
// .request_id = htonl(RIL_REQUEST_SETUP_DATA_CALL),
// .token = htonl(1)
// };
RIL_RequestHeader header = {
.length = htonl(sizeof(RIL_RequestHeader) + payload_len),
.request_id = htonl(RIL_REQUEST_SETUP_DATA_CALL),
.token = htonl(1)
};
size_t full_msg_size = sizeof(header) + payload_len;
uint8_t *full_msg = malloc(full_msg_size);
// 复制请求头(不含长度字段)
memcpy(full_msg, &header, sizeof(header));
// 复制payload
memcpy(full_msg + sizeof(header), payload, payload_len);
// 调试日志
ALOGD("RIL 1.2+ Header: len=%u, req_id=%u, token=%u",
ntohl(header.length), ntohl(header.request_id), ntohl(header.token));
// 5. 发送请求
ssize_t sent = write(ril_fd, full_msg, full_msg_size);
// 打印完整请求内容
ALOGD("Full request content (%zu bytes):", full_msg_size);
for (size_t i = 0; i < full_msg_size; i++) {
if (i % 16 == 0) ALOGD("");
ALOGD("%02X ", full_msg[i]);
}
ALOGD("");
free(full_msg);
if (sent != (ssize_t)full_msg_size) {
ALOGE("Failed to send request: %zd/%zu bytes sent: %s",
sent, full_msg_size, strerror(errno));
close(ril_fd);
return EXIT_FAILURE;
}
ALOGD("Sent complete request to RILD (%zu bytes)", full_msg_size);
// 6. 使用poll等待响应
struct pollfd pfd = {
.fd = ril_fd,
.events = POLLIN,
.revents = 0
};
int ret = poll(&pfd, 1, RESPONSE_TIMEOUT_MS);
if (ret <= 0) {
if (ret == 0) {
ALOGE("Poll timeout waiting for response");
} else {
ALOGE("Poll error: %s", strerror(errno));
}
close(ril_fd);
return EXIT_FAILURE;
}
// 7. 接收响应长度
uint32_t response_length;
ssize_t n = read(ril_fd, &response_length, sizeof(response_length));
if (n != sizeof(response_length)) {
ALOGE("Failed to read response length: %zd (%s)",
n, n<0?strerror(errno):"short read");
close(ril_fd);
return EXIT_FAILURE;
}
response_length = ntohl(response_length);
ALOGD("Response total length: %u bytes", response_length);
if (response_length < 4) {
ALOGE("Invalid response length: %u < 4", response_length);
// 尝试读取错误信息
uint8_t error_buf[128];
ssize_t n = read(ril_fd, error_buf, sizeof(error_buf) - 1);
if (n > 0) {
error_buf[n] = '\0';
ALOGE("RILD error message: %s", error_buf);
}
close(ril_fd);
return EXIT_FAILURE;
}
// 8. 读取完整响应体
uint8_t *response_buf = malloc(response_length);
if (!response_buf) {
ALOGE("Failed to allocate response buffer");
close(ril_fd);
return EXIT_FAILURE;
}
if (read_full(ril_fd, response_buf, response_length, RESPONSE_TIMEOUT_MS) != (ssize_t)response_length) {
ALOGE("Failed to read response body");
free(response_buf);
close(ril_fd);
return EXIT_FAILURE;
}
// // 9. 解析响应头
// if (response_length < 16) {
// ALOGE("Response too short for header: %u < 16 bytes", response_length);
// free(response_buf);
// close(ril_fd);
// return EXIT_FAILURE;
// }
// uint32_t token = ntohl(*(uint32_t*)(response_buf));
// uint32_t type = ntohl(*(uint32_t*)(response_buf + 4));
// uint32_t resp_serial = ntohl(*(uint32_t*)(response_buf + 8));
// uint32_t error = ntohl(*(uint32_t*)(response_buf + 12));
// ALOGD("Received response: token=%u, type=%u, serial=%u, error=0x%X",
// token, type, resp_serial, error);
// // 10. 处理响应
if (response_length >= 12) {
uint32_t token = ntohl(*(uint32_t*)(response_buf));
uint32_t type = ntohl(*(uint32_t*)(response_buf + 4));
uint32_t error = ntohl(*(uint32_t*)(response_buf + 8));
ALOGI("Response header: token=0x%X, type=%u, error=0x%X (%s)",
token, type, error, ril_error_to_string(error));
ALOGD("Response header: token=0x%08X, type=%u, error=0x%08X",
token, type, error);
// if (error == RIL_E_SUCCESS) {
// RIL_Data_Call_Response_v11 data_resp = {0};
// parse_data_call_response_v11(response_buf + 12, response_length - 12, &data_resp);
// // 检查接口是否存在
// if (data_resp.ifname) {
// if (check_interface_exists(data_resp.ifname)) {
// ALOGI("Interface %s exists in system", data_resp.ifname);
// } else {
// ALOGW("Interface %s not found in /sys/class/net", data_resp.ifname);
// }
// }
// free_data_call_response(&data_resp);
// // 打印详细响应
// } else {
// // 错误处理
// ALOGE("Data call setup failed with error: 0x%X (%s)", error, ril_error_to_string(error));
// // 如果有额外错误信息,打印前32字节
// if (response_length > 16) {
// size_t error_len = response_length - 16;
// size_t log_len = error_len < 32 ? error_len : 32;
// ALOGD("Error details (hex):");
// for (size_t i = 0; i < log_len; i++) {
// ALOGD("%02X ", response_buf[16 + i]);
// }
// ALOGD("\n");
// }
}
if (response_length > 0) {
// 直接打印整个响应体(十六进制格式)
ALOGI("Raw response body (%u bytes):", response_length);
for (uint32_t i = 0; i < response_length; i++) {
if (i % 16 == 0) ALOGI(""); // 每16字节换行
ALOGI("%02X ", response_buf[i]);
}
ALOGI("\n");
} else {
ALOGE("Empty response body");
}
free(response_buf);
close(ril_fd);
ALOGD("Demo completed");
return EXIT_SUCCESS;
}
最新发布