mtk android power key 长按8s 关机功能实现

本文介绍了一种实现在任何情况下长按电源键8秒即可直接关机的功能。通过在kernel层面进行修改,利用定时器和中断处理机制,确保了功能的稳定性和可靠性。

该功能是系统启动后,在任何情况下,长按power key 8s都能做到直接关机。因此在kernel中实现。

所有修改都在keypad driver中,如下文件。
mediatek\platform\mt6573\kernel\drivers\keypad\kpd.c :


#define FORCE_POWERKEY_SECONDS   8   //定义power key按键持续时间


struct timer_list timer; 


//定时器timer初始化
static int timer_init() 

    init_timer(&timer); 
    timer.data= 5; 
    timer.expires = jiffies + (FORCE_POWERKEY_SECONDS*HZ);  
    timer.function = timer_function; 
    add_timer(&timer); 
    printk("<0>ziheng add_timer\n"); 
    return 0; 

//定时器timer退出
static void timer_exit() 

    del_timer(&timer); 

//定时器到时事件处理函数
static void timer_function(int para) 

    timer_exit();
    arch_reset(0, "charger");  //kernel强制关机接口


按键时间在kpd_pwrkey_handler中处理,kpd_pwrkey_handler是一个tasklet,用于power key的按键中断下半部处理。

static void kpd_pwrkey_handler(unsigned long data)
{
 bool pressed;

 u8 old_state = kpd_pwrkey_state;

 kpd_pwrkey_state = !kpd_pwrkey_state;
 pressed = (kpd_pwrkey_state == !!KPD_PWRKEY_POLARITY);
 if (kpd_show_hw_keycode) {
  printk(KPD_SAY "(%s) HW keycode = using EINT\n",
         pressed ? "pressed" : "released");
 }
#ifdef  FORCE_POWERKEY
    if(pressed == 1)
     {
     printk("<0> kpd_pwr_handler press 1\n"); 
  timer_init();
     }
    else if(pressed == 0)
     {
     printk("<0> kpd_pwr_handler press 0\n"); 
             timer_exit();
 }
#endif
 kpd_backlight_handler(pressed, KPD_PWRKEY_MAP);
 input_report_key(kpd_input_dev, KPD_PWRKEY_MAP, pressed);
 kpd_print("report Linux keycode = %u\n", KPD_PWRKEY_MAP);

 /* for detecting the return to old_state */
 mt65xx_eint_set_polarity(KPD_PWRKEY_EINT, old_state);
 mt65xx_eint_unmask(KPD_PWRKEY_EINT);
}

 

38 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <inttypes.h> 42 #include <unistd.h> 43 #include <fcntl.h> 44 #include <dlfcn.h> 45 #include <sys/types.h> 46 #include <sys/stat.h> 47 #include <sys/mman.h> 48 #include <sys/vfs.h> 49 #include <limits.h> 50 #include <errno.h> 51 #include <string.h> 52 #include <dirent.h> 53 #include <wchar.h> 54 #include <linux/ioctl.h> 55 #include <ctype.h> 56 #include "sysenv_utils.h" 57 58 //#include <cutils/properties.h> 59 #include "hardware/ccci_intf.h" 60 //#include <hardware_legacy/power.h> 61 #include <assert.h> 62 //#define RPC_WAKE_LOCK_NAME "ccci_rpc" 63 //#define RPC_WAKE_LOCK() acquire_wake_lock(PARTIAL_WAKE_LOCK, RPC_WAKE_LOCK_NAME) 64 //#define RPC_WAKE_UNLOCK() release_wake_lock(RPC_WAKE_LOCK_NAME) 65 66 //#include <cutils/log.h> 67 #include "ccci_rpcd_platform.h" 68 #include "ccci_rpcd.h" 69 70 71 //#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, "ccci_rpcd",__VA_ARGS__) 72 //#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , "ccci_rpcd",__VA_ARGS__) 73 //#define LOGI(...) __android_log_print(ANDROID_LOG_INFO , "ccci_rpcd",__VA_ARGS__) 74 //#define LOGW(...) __android_log_print(ANDROID_LOG_WARN , "ccci_rpcd",__VA_ARGS__) 75 //#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , "ccci_rpcd",__VA_ARGS__) 76 77 static int stream_support = 0; 78 static int DeviceFd = 0; 79 static unsigned int RPC_MAX_BUF_SIZE = 2048; 80 static unsigned int RPC_MAX_ARG_NUM = 6; 81 static int md_id = 0; 82 static RPC_INFO g_RpcInfo; 83 84 85 static int RPC_GetPackInfo(RPC_PACKET_INFO* pPackInfo, unsigned char* pData) 86 { 87 unsigned int PackNum = *((unsigned int*)pData); 88 unsigned int Index = 0; 89 unsigned int i; 90 91 if(PackNum > RPC_MAX_ARG_NUM) 92 return false; 93 94 Index = sizeof(unsigned int); 95 for(i = 0; i < PackNum; i++) 96 { 97 pPackInfo[i].Length = *((unsigned int*)(pData + Index)); 98 Index += sizeof(unsigned int); 99 pPackInfo[i].pData = (pData + Index); 100 //4 byte alignment 101 Index += ((pPackInfo[i].Length+3)>>2)<<2; 102 } 103 104 if(Index > RPC_MAX_BUF_SIZE) 105 return false; 106 107 return true; 108 } 109 110 // 5 = CCCI header + Operation ID 111 unsigned int g_bak[5]; 112 113 /* 114 * @brief Prepare a packet buffer for sending to MD 115 * @param 116 * pData [in] A pointer to argument data for sending 117 * data_to_send [in] Size in bytes of argument data to send 118 * ccci_src [in] The pointer to the CCCI header for every sub-packet 119 * op_id [in] Operation ID currently used 120 * again [in] A flag means if we need to set "send again indicator" 121 * @return 122 * On success, a pointer to arguments data is returned. 123 * On error, NULL is returned. 124 */ 125 void *RPC_PreparePktEx(unsigned char *pData, unsigned int data_to_send, CCCI_BUFF_T *ccci_src, unsigned int op_id, unsigned int again) 126 { 127 char *bak_ptr = NULL; 128 STREAM_DATA *stream = NULL; 129 130 assert(data_to_send <= MAX_RPC_PKT_BYTE); 131 assert(pData != NULL && ccci_src != NULL); 132 assert(pData - (sizeof(CCCI_BUFF_T) + sizeof(unsigned int)) >= ccci_src); 133 assert(sizeof(g_bak) == (sizeof(CCCI_BUFF_T) + sizeof(unsigned int))); 134 // move pointer forward to fill in CCCI header, this will replace orignal data there, so we backup them first 135 bak_ptr = (char *)(pData - (sizeof(CCCI_BUFF_T) + sizeof(unsigned int))); 136 // backup partial data 137 memcpy((void*)g_bak, bak_ptr, sizeof(g_bak)); 138 stream = (STREAM_DATA *)bak_ptr; 139 // copy CCCI header from the very fist header of all sub-packets 140 if (again) 141 stream->header.data[0] = ccci_src->data[0] | CCCI_RPC_REQ_SEND_AGAIN; 142 else 143 stream->header.data[0] = ccci_src->data[0] & ~CCCI_RPC_REQ_SEND_AGAIN; 144 stream->header.data[1] = data_to_send + sizeof(CCCI_BUFF_T) + sizeof(unsigned int);; 145 stream->header.channel = ccci_src->channel; 146 stream->header.reserved = ccci_src->reserved; 147 stream->payload.rpc_ops_id = op_id; 148 149 //LOGD("RPC_PreparePktEx() CCCI_H(0x%X)(0x%X)(0x%X)(0x%X), OP ID = 0x%X", 150 // stream->header.data[0], stream->header.data[1], stream->header.channel, stream->header.reserved, 151 // stream->payload.OperateID); 152 153 return (void*)stream; 154 } 155 156 /* 157 * @brief Determine the prepare data has done 158 * @param 159 * pStream [in] A pointer returned from RPC_PreparePktEx() 160 * @return 161 * None 162 */ 163 void RPC_PreparePktDone(void *pStream) 164 { 165 assert(pStream != NULL); 166 // Restore backuped data 167 memcpy(pStream, (void*)g_bak, sizeof(g_bak)); 168 } 169 170 static bool RPC_WriteToMD(int DeviceFd, int BufIndex, RPC_PACKET_INFO* pPacketSrc, unsigned int PacketNum) 171 { 172 bool bRet = false; 173 int ret = 0; 174 unsigned char* pData = NULL; 175 unsigned int DataLength = 0, AlignLength; 176 unsigned int i; 177 rpc_stream_buffer_t *pRpcBuf = NULL; 178 rpc_stream_msg_t stream_msg; 179 180 int data_len = 0; 181 int data_sent = 0; 182 STREAM_DATA *buffer_slot = NULL; 183 CCCI_BUFF_T *ccci_h = NULL; 184 void *pkt_ptr = NULL; 185 int pkt_size = 0; 186 int data_to_send = 0; 187 if(!stream_support) { 188 pRpcBuf = (rpc_stream_buffer_t *)((char *)g_RpcInfo.pRpcBuf + (RPC_MAX_BUF_SIZE + sizeof(rpc_stream_msg_t))*BufIndex); 189 } else { 190 buffer_slot = (STREAM_DATA *)((char *)g_RpcInfo.pRpcBuf + (RPC_MAX_BUF_SIZE + sizeof(STREAM_DATA))*BufIndex); 191 pRpcBuf = &buffer_slot->payload; 192 DataLength += sizeof(CCCI_BUFF_T); 193 DataLength += sizeof(unsigned int); // size of operate ID field 194 } 195 pRpcBuf->rpc_ops_id = RPC_API_RESP_ID | pRpcBuf->rpc_ops_id; 196 pData = (unsigned char* )pRpcBuf->buffer; 197 198 *((unsigned int*)pData) = PacketNum; 199 200 pData += sizeof(unsigned int); 201 DataLength += sizeof(unsigned int); 202 203 for(i = 0; i < PacketNum; i++) 204 { 205 if((DataLength + 2*sizeof(unsigned int) + pPacketSrc[i].Length) > RPC_MAX_BUF_SIZE) 206 { 207 LOGE("RPCD_WriteToMD: Stream buffer full!!\r\n"); 208 goto _Exit; 209 } 210 *((unsigned int*)pData) = pPacketSrc[i].Length; 211 pData += sizeof(unsigned int); 212 DataLength += sizeof(unsigned int); 213 214 //4 byte aligned 215 AlignLength = ((pPacketSrc[i].Length + 3) >> 2) << 2; 216 DataLength += AlignLength; 217 218 if(pData != pPacketSrc[i].pData) 219 memcpy(pData, pPacketSrc[i].pData, pPacketSrc[i].Length); 220 221 pData += AlignLength; 222 } 223 224 stream_msg.length = DataLength; 225 stream_msg.index = BufIndex; 226 227 if(!stream_support) { 228 msync(pRpcBuf, RPC_MAX_BUF_SIZE, MS_SYNC); 229 ret = ioctl(DeviceFd, CCCI_RPC_IOCTL_SEND, &stream_msg); 230 if(ret < 0) { 231 LOGE("WriteToMD: [error]fail send RPC stream: %d \n", errno); 232 return bRet; 233 } 234 } else { 235 // data length excluding CCCI header and OP ID 236 data_len = DataLength - sizeof(CCCI_BUFF_T) - sizeof(unsigned int); 237 ccci_h = &buffer_slot->header; 238 ccci_h->channel++; //Rx->Tx 239 240 /* No fragment is needed */ 241 if (data_len <= MAX_RPC_PKT_BYTE) { 242 pData = (unsigned char *)buffer_slot; 243 // Clear "send again indicator" 244 ccci_h->data[0] = ccci_h->data[0] & ~CCCI_RPC_REQ_SEND_AGAIN; 245 ccci_h->data[1] = DataLength; 246 ret = write(DeviceFd, pData, DataLength); 247 if (ret != (int)DataLength) { 248 LOGE("Failed to write only one RPC packet(%d)!! (%d/%d)\n", DataLength, ret, errno); 249 return bRet; 250 } 251 //LOGD("Write %d bytes to slot %d, CCCI_H(0x%X)(0x%X)(0x%X)(0x%X)\n", 252 //ret, BufIndex, ccci_h->data[0], ccci_h->data[1], ccci_h->channel, ccci_h->reserved); 253 } else { 254 /* Data fragment is needed */ 255 //LOGD("Big packet, need fragment."); 256 pData = (unsigned char *)(&buffer_slot->payload.buffer); 257 while ((unsigned int)(data_sent + sizeof(CCCI_BUFF_T) + sizeof(unsigned int)) < DataLength) { 258 /* Moret than 2 packets to send */ 259 /* Each packet includes CCCI header, OP id, and data */ 260 if ((data_len - data_sent) > MAX_RPC_PKT_BYTE) { 261 data_to_send = MAX_RPC_PKT_BYTE; 262 pkt_ptr = RPC_PreparePktEx(pData, data_to_send, ccci_h, pRpcBuf->rpc_ops_id, 1); 263 } else { 264 /* The last packet */ 265 data_to_send = data_len - data_sent; 266 pkt_ptr = RPC_PreparePktEx(pData, data_to_send, ccci_h, pRpcBuf->rpc_ops_id, 0); 267 } 268 // Add CCCI header and operation ID size to packet size, be aware of that OP_ID is not cosindered as payload, so not counted in MAX_RPC_PKT_BYTE 269 pkt_size = data_to_send + sizeof(CCCI_BUFF_T) + sizeof(unsigned int); 270 // write size = data + CCCI header + OP ID 271 ret = write(DeviceFd, pkt_ptr, pkt_size); 272 if (ret != pkt_size) { 273 LOGE("Failed to write RPC packet !! (%d)\n", errno); 274 break; 275 } else { 276 CCCI_BUFF_T *dst_ccci_h = (CCCI_BUFF_T *)pkt_ptr; 277 LOGD("Write %d bytes to slot %d, CCCI_H(0x%X)(0x%X)(0x%X)(0x%X)\n", 278 ret, BufIndex, 279 dst_ccci_h->data[0], dst_ccci_h->data[1], dst_ccci_h->channel, dst_ccci_h->reserved); 280 } 281 RPC_PreparePktDone(pkt_ptr); 282 data_sent += data_to_send; 283 pData += data_to_send; 284 }; 285 } 286 if (ret < 0) { 287 LOGE("WriteToMD: [error]fail send RPC stream: %d \n", ret); 288 return bRet; 289 } 290 //LOGD("write to MD %d\n", DataLength); 291 } 292 bRet = true; 293 294 _Exit: 295 return bRet; 296 } 297 298 /*************************************************************************** 299 * Support lib Section 300 ***************************************************************************/ 301 302 /* tc1 lib --------------------------------------------------------------------------------------- */ 303 #define TC1_SUPPORT_LIB_PATH "/vendor/lib/libccci_tc1_srv.so" 304 static void *tc1_support_lib = NULL; 305 static int tc1_lib_ready = 0; 306 int (*tc1_rpc_srv_entry)(int ops_id, RPC_PACKET_INFO *packet_info, int *packet_num, int buf[]); 307 int (*tc_lib_init)(void); 308 309 int load_support_lib(void) 310 { 311 const char *error = NULL; 312 313 /* Tc1 section */ 314 tc1_support_lib = dlopen(TC1_SUPPORT_LIB_PATH, RTLD_NOW); 315 if(NULL == tc1_support_lib){ 316 LOGD("TC1 lib not support for current project!(%s)\n", dlerror()); 317 return -1; 318 } 319 error = dlerror(); /* to clear previous error msg */ 320 tc_lib_init = dlsym(tc1_support_lib, "tc1_lib_init"); 321 error = dlerror(); 322 if (NULL != error) { 323 LOGE("Load tc1_lib_init api fail!!(%s)\n", error); 324 dlclose(tc1_support_lib); 325 return -1; 326 } 327 tc1_rpc_srv_entry = dlsym(tc1_support_lib, "tc1_rpc_srv_entry"); 328 error = dlerror(); 329 if (NULL != error) { 330 LOGE("Load tc1_rpc_srv_entry api fail!!(%s)\n", error); 331 dlclose(tc1_support_lib); 332 return -1; 333 } 334 if (tc_lib_init() < 0) { 335 LOGE("tc1_rpc_lib init fail!!\n"); 336 dlclose(tc1_support_lib); 337 return -1; 338 } 339 tc1_lib_ready = 1; 340 341 return 0; 342 } 343 344 static int tc1_srv_check(int ops_id, RPC_PACKET_INFO *packet_info, int *packet_num, int buf[]) 345 { 346 if (tc1_lib_ready) 347 return tc1_rpc_srv_entry(ops_id, packet_info, packet_num, buf); 348 349 return -1; 350 } 351 352 353 static int exit_signal = 0; 354 void signal_treatment(int param) 355 { 356 /* 357 * this signal catching design does NOT work... 358 * set property ctl.stop will send SIGKILL to ccci_rpcd(check service_stop_or_reset() in init.c), 359 * but SIGKILL is not catchable. 360 * kill pid will send SIGTERM to ccci_rpcd, we can catch this signal, but the process is just 361 * terminated, and no time for us to check exit_signal in main(). 362 * per system team's comment, kernel will free all resource (memory get from malloc, etc.), 363 * so we do NOT need to take care of these. 364 */ 365 LOGD("signal number=%d\n", param); 366 switch (param) { 367 case SIGPIPE: 368 case SIGHUP: 369 case SIGINT: 370 case SIGTERM: 371 case SIGUSR1: 372 case SIGUSR2: 373 case SIGALRM: 374 case SIGKILL: 375 default: 376 exit_signal = param; 377 break; 378 } 379 } 380 381 /* amms new feature */ 382 static unsigned char *drdi_addr; 383 static int drdi_img_offset, drdi_img_size; 384 static int drdi_info_ready = -1; 385 static unsigned int set_total_num; 386 #define IMG_NODE_SIZE 2 387 static const char *mdimg_node[IMG_NODE_SIZE] = { 388 "/dev/block/by-name/modem", 389 "/dev/block/by-name/md1img" 390 }; 391 392 /* bank4 smem size */ 393 #define BANK4_DRDI_SMEM_SIZE (64*1024) 394 395 /* copy status */ 396 static unsigned int all_set_copy_done = COPY_FAIL; 397 398 /* find md1drdi img offset and size, mmap 512KB memory */ 399 static int ccci_prepare_drdi_info() 400 { 401 const char *img_name = "md1drdi"; 402 int md_img_fd = -1; 403 404 /* find offset of md1drdi in md image */ 405 md_img_fd = find_image_from_pt(img_name, &drdi_img_offset, &drdi_img_size); 406 if (md_img_fd < 0) { 407 LOGE("not find %s in partition\n", img_name); 408 return -1; 409 } 410 if ((drdi_img_size > 512*1024*1024) || (drdi_img_size <= 0)) { 411 LOGE("MD image size abnormal %d\n", drdi_img_size); 412 return -2; 413 } 414 LOGD("find img %s (size 0x%x) at 0x%x in partition\n", img_name, drdi_img_size, drdi_img_offset); 415 416 if (DeviceFd < 0) { 417 LOGE("%s:DeviceFd(%d) error\n", __func__, DeviceFd); 418 return -ENODEV; 419 } 420 421 drdi_addr = (unsigned char *)mmap(NULL, BANK4_DRDI_SMEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, DeviceFd, 0); 422 if (drdi_addr == MAP_FAILED) { 423 LOGE("%s:mmap failed, errno=%d\n", __func__, errno); 424 return -EFAULT; 425 } 426 LOGD("%s:drdi_addr=0x%p\n", __func__, drdi_addr); 427 428 drdi_info_ready = 0; 429 return 0; 430 } 431 432 static int amms_cmd_init_handler(struct amms_msg_request *request, 433 struct amms_msg_response *reply) 434 { 435 unsigned int i; 436 437 if (!request || !reply) { 438 LOGE("%s: invalid input or output\n", __func__); 439 return -1; 440 } 441 if (drdi_info_ready != 0) { 442 LOGE("%s: prepare drdi_info fail\n", __func__); 443 goto fail; 444 } 445 446 reply->seq_id = request->seq_id; 447 LOGD("%s:reply seq_id(%d)\n", __func__, reply->seq_id); 448 449 /* check version valid */ 450 if (request->u_req.init_request_cmd.version == AMMS_V3) 451 reply->u_resp.init_reply.version = AMMS_V3; 452 else { 453 LOGE("%s:version(%d) error, goto fail\n", 454 __func__, request->u_req.init_request_cmd.version); 455 goto fail; 456 } 457 458 /* get set_total_num */ 459 if (request->u_req.init_request_cmd.set_total_num > DRDI_SET_NUM_TOTAL_SET) { 460 LOGE("%s:set_total_num error\n", __func__); 461 goto fail; 462 } 463 set_total_num = request->u_req.init_request_cmd.set_total_num; 464 465 for (i = 0; i < set_total_num; i++) { 466 /* check start_addr or length exceed */ 467 if (request->u_req.init_request_cmd.drdi_info[i].start_address + request->u_req.init_request_cmd.drdi_info[i].length > drdi_img_size) { 468 LOGE("%s: cmd invalid: start_addr=0x%x, size=0x%x\n", 469 __func__, request->u_req.init_request_cmd.drdi_info[i].start_address, request->u_req.init_request_cmd.drdi_info[i].length); 470 reply->u_resp.init_reply.drdi_info_status = -1; 471 reply->status = AMMS_STATUS_INVALID; 472 return -1; 473 } 474 } 475 476 /* first boot and copy success --> status no need */ 477 reply->u_resp.init_reply.drdi_info_status = 0; 478 reply->status = AMMS_STATUS_SUCCESS; 479 480 all_set_copy_done = COPY_FAIL; 481 reply->u_resp.init_reply.copy_status = 0; 482 483 LOGD("stats=%d, seqid=%d, coypstat=%d, ver=%d,drdiinfostat=%d\n", 484 reply->status, reply->seq_id, reply->u_resp.init_reply.copy_status, 485 reply->u_resp.init_reply.version, reply->u_resp.init_reply.drdi_info_status); 486 487 return 0; 488 489 fail: 490 reply->status = AMMS_STATUS_FAIL; 491 reply->u_resp.init_reply.version = AMMS_V3; 492 reply->u_resp.init_reply.copy_status = 0; 493 reply->u_resp.init_reply.drdi_info_status = -1; 494 LOGE("%s:init cmd fail\n", __func__); 495 return -1; 496 } 497 498 static int amms_cmd_drdi_copy_handler(struct amms_msg_request *request, 499 struct amms_msg_response *reply) 500 { 501 int ret, i, has_write = 0; 502 int drdi_fd = -1; 503 char partition_path[128] = { 0 }; 504 char buf[128] = { 0 }; 505 506 if (!request || !reply) { 507 LOGE("%s: invalid input or output\n", __func__); 508 return -1; 509 } 510 511 reply->seq_id = request->seq_id; 512 //LOGD("%s:reply seq_id(%d)\n", __func__, reply->seq_id); 513 514 for (i = 0; i < set_total_num; i++) { 515 if (request->u_req.drdi_cpy_cmd.copy_info[i].length == 0) 516 continue; 517 if (request->u_req.drdi_cpy_cmd.copy_info[i].length > BANK4_DRDI_SMEM_SIZE || 518 request->u_req.drdi_cpy_cmd.copy_info[i].src_offset + request->u_req.drdi_cpy_cmd.copy_info[i].length > drdi_img_size) { 519 LOGD("set(%d) error,src=0x%x,dst=0x%x,len=0x%x\n", i, request->u_req.drdi_cpy_cmd.copy_info[i].src_offset, 520 request->u_req.drdi_cpy_cmd.copy_info[i].dst_offset, request->u_req.drdi_cpy_cmd.copy_info[i].length); 521 goto fail; 522 } 523 } 524 525 if (all_set_copy_done == COPY_DONE) { 526 LOGD("%s:already copy success, no need copy\n", __func__); 527 reply->status = AMMS_STATUS_SUCCESS; 528 return 0; 529 } 530 531 AB_image_get(buf); 532 for (i = 0; i < IMG_NODE_SIZE; i++) { 533 has_write = snprintf(partition_path, 128, "%s%s", mdimg_node[i], buf); 534 if (has_write < 0 || has_write >= 128) { 535 LOGE("[%s] %d:get mdimg node[%d] fail,has_write = %d\n", 536 __func__, __LINE__, i, has_write); 537 continue; 538 } 539 drdi_fd = open(partition_path, O_RDONLY); 540 if (drdi_fd < 0) { 541 LOGE("%s:open drdi img(%s) fail\n", __func__, partition_path); 542 continue; 543 } else 544 break; 545 } 546 if ( i >= IMG_NODE_SIZE) { 547 LOGE("[%s] %d:open drdi imgfail, cmd exit\n", __func__, __LINE__); 548 goto fail; 549 } 550 551 reply->u_resp.cpy_reply.last_cpy_status = 552 request->u_req.drdi_cpy_cmd.last_cpy == 1 ? 0 : -1; 553 554 for (i = 0; i < set_total_num; i++) { 555 if (request->u_req.drdi_cpy_cmd.copy_info[i].length == 0) 556 continue; 557 if (lseek(drdi_fd, (off_t)request->u_req.drdi_cpy_cmd.copy_info[i].src_offset + drdi_img_offset, SEEK_SET) != -1) { 558 ret = read(drdi_fd, drdi_addr + request->u_req.drdi_cpy_cmd.copy_info[i].dst_offset, 559 (size_t)request->u_req.drdi_cpy_cmd.copy_info[i].length); 560 if (ret < 0) { 561 LOGE("read set(%d)fail,err=%d,ret=%d,src=0x%x,dst=0x%x,len=0x%x\n", i, errno, ret, request->u_req.drdi_cpy_cmd.copy_info[i].src_offset, 562 request->u_req.drdi_cpy_cmd.copy_info[i].dst_offset, request->u_req.drdi_cpy_cmd.copy_info[i].length); 563 close(drdi_fd); 564 goto fail; 565 } 566 all_set_copy_done = request->u_req.drdi_cpy_cmd.last_cpy == 1 ? COPY_DONE : COPY_GOING; 567 LOGD("copy set(%d) from 0x%x to 0x%x,len=0x%x success\n", i, request->u_req.drdi_cpy_cmd.copy_info[i].src_offset, 568 (unsigned int)(drdi_addr + request->u_req.drdi_cpy_cmd.copy_info[i].dst_offset), request->u_req.drdi_cpy_cmd.copy_info[i].length); 569 } else { 570 all_set_copy_done = COPY_FAIL; 571 LOGE("lseek set(%d) fail,err=%d,src=0x%x,dst=0x%x,len=0x%x\n", i, errno, request->u_req.drdi_cpy_cmd.copy_info[i].src_offset, 572 request->u_req.drdi_cpy_cmd.copy_info[i].dst_offset, request->u_req.drdi_cpy_cmd.copy_info[i].length); 573 close(drdi_fd); 574 goto fail; 575 } 576 } 577 578 /* lseek fail, copy fail or all copy_info.length==0, must reply fail and close fd */ 579 reply->status = (all_set_copy_done == COPY_FAIL) ? AMMS_STATUS_FAIL : AMMS_STATUS_SUCCESS; 580 close(drdi_fd); 581 582 return 0; 583 584 fail: 585 all_set_copy_done = COPY_FAIL; 586 LOGE("%s:copy fail\n", __func__); 587 reply->status = AMMS_STATUS_FAIL; 588 return -1; 589 } 590 591 int ccci_rpc_amms_drdi_ctl(struct amms_msg_request *request, 592 struct amms_msg_response *reply) 593 { 594 int ret; 595 596 switch (request->cmd) { 597 case AMMS_CMD_INIT: 598 ret = amms_cmd_init_handler(request, reply); 599 break; 600 case AMMS_CMD_DRDI_COPY: 601 ret = amms_cmd_drdi_copy_handler(request, reply); 602 break; 603 default: 604 ret = -1; 605 reply->status = AMMS_STATUS_FAIL; 606 reply->seq_id = request->seq_id; 607 LOGE("%s:%d unknown cmd:%u\n", __func__, __LINE__, request->cmd); 608 break; 609 } 610 611 //LOGD("%s:req:%u done, ret=%d\n", __func__, request->cmd, ret); 612 613 return ret; 614 } 615 616 #define CCCI_SIG "CCCIRPC" 617 #define MISC_PART "dev/block/by-name/para" 618 #define MISC_PART_DATA_OFFSET (0x28000) 619 620 struct ccci_rpc_s { 621 char sign[8]; // "CCCIRPC" 622 unsigned int md_capid; 623 unsigned int md_aac; 624 char sign_1[8]; //"CCCIRPC" 625 }; 626 627 int ccci_rpc_mdcap_aac_ctl(struct Md_Rpc_Capid_Aac *input, 628 int *reply) 629 { 630 int ret, fd; 631 struct ccci_rpc_s ccci_data = {0}; 632 633 if (input == NULL || reply == NULL) 634 return -1; 635 636 *reply = -1; 637 638 strncpy(ccci_data.sign, CCCI_SIG, sizeof(CCCI_SIG)); 639 strncpy(ccci_data.sign_1, CCCI_SIG, sizeof(CCCI_SIG)); 640 641 ccci_data.md_capid = input->capid; 642 ccci_data.md_aac = input->aac; 643 LOGD("%s:md_capid 0x%x md_aac 0x%x\n", __func__, ccci_data.md_capid, ccci_data.md_aac); 644 645 fd = open(MISC_PART, O_RDWR); 646 if (fd < 0) { 647 LOGE("failed to get device path by mount point %s fd=%d, errno: %s\n", 648 MISC_PART, fd, strerror(errno)); 649 return -1; 650 } 651 652 if (lseek(fd, MISC_PART_DATA_OFFSET, SEEK_SET) != MISC_PART_DATA_OFFSET) { 653 LOGE("seek to %ld fail: %s\n", MISC_PART_DATA_OFFSET, strerror(errno)); 654 goto fail; 655 } 656 657 ret = write(fd, (char *)&ccci_data, sizeof(struct ccci_rpc_s)); 658 if (ret < 0 || ret != sizeof(struct ccci_rpc_s)) { 659 LOGE("write fail ret=%d, err=%s\n", ret, strerror(errno)); 660 goto fail; 661 } 662 663 *reply = 0; 664 665 fail: 666 close(fd); 667 668 return 0; 669 } 670 671 #define MAX_RETRY_CNT (800) //800 * unit 10ms -> 8s 672 static void ccci_file_open_fail_debug(char *dev_node, int retry_time) 673 { 674 if ((retry_time != 0) && (retry_time != 50) && (retry_time != (MAX_RETRY_CNT/2))) 675 return; 676 // 0 or 500ms or 1/2 timeout: print 677 LOGE("%s open fail (%d)\n", dev_node, errno); 678 if (access(dev_node, F_OK) == 0) { 679 LOGE("%s exists..\n", dev_node); 680 681 if (access(dev_node, R_OK) != 0) 682 LOGE("%s read denied..\n", dev_node); 683 if (access(dev_node, W_OK) != 0) 684 LOGE("%s write denied..\n", dev_node); 685 } else 686 LOGE("%s not exists..\n", dev_node); 687 } 688 689 int open_rpc_device(const char *dev_node, int flag) 690 { 691 int dev_fd = -1, retry_time = 0; 692 693 if (dev_node == NULL) 694 return -1; 695 696 LOGI("[%s] dev_name: %s\n", __func__, dev_node); 697 698 while(retry_time < MAX_RETRY_CNT) { 699 dev_fd = open(dev_node, flag); 700 if (dev_fd < 0) { 701 702 ccci_file_open_fail_debug(dev_node, retry_time); 703 704 usleep(10 * 1000); 705 retry_time++; 706 } else { 707 LOGI("%s opened,cost %d ms.\n", dev_node, retry_time * 10); 708 break; 709 } 710 } 711 712 return dev_fd; 713 714 } 715 716 int main(int argc, char *argv[]) 717 { 718 int ReqBufIndex = 0; 719 rpc_stream_buffer_t *pRpcBuf = NULL; 720 int PacketNum = 0; 721 int RetVal; 722 char dev_node[32]; 723 RPC_PACKET_INFO *PackInfo = NULL; 724 CCCI_BUFF_T *ccci_h = NULL; 725 char pkt_buff[MAX_RPC_BUF_BYTE] = {0}; 726 STREAM_DATA *stream = NULL; // data packet received from MD 727 STREAM_DATA *buffer_slot = NULL; // local buffer slot 728 char *p_rpc_buff = NULL; 729 char property_val[PROPERTY_VALUE_MAX] = {0}; 730 int tmp_buff[2]; 731 int sar_tbl_idx = 0; 732 unsigned int cpy_size = 0; 733 struct amms_msg_request *input = NULL; 734 struct amms_msg_response *output = NULL; 735 struct Md_Rpc_Capid_Aac *md_cap_aac = NULL; 736 int md_cap_aac_ret = -1; 737 738 LOGD("ccci_rpcd Ver:v2.00, CCCI Ver:%d", ccci_get_version()); 739 //Check if input parameter is valid 740 if(argc != 2) { 741 md_id = 0; 742 LOGE("[Warning]Parameter number not correct,use old version!\n"); 743 snprintf(dev_node, 32, "/dev/ccci_rpc"); 744 } else { 745 if(strcmp(argv[1],"0")==0) { 746 snprintf(dev_node, 32, "%s", ccci_get_node_name(USR_CCCI_RPC, MD_SYS1)); 747 md_id = 0; 748 } else if(strcmp(argv[1],"1")==0) { 749 snprintf(dev_node, 32, "%s", ccci_get_node_name(USR_CCCI_RPC, MD_SYS2)); 750 md_id =1; 751 } else if(strcmp(argv[1],"4")==0) { 752 snprintf(dev_node, 32, "%s", ccci_get_node_name(USR_CCCI_RPC, MD_SYS5)); 753 md_id =4; 754 } else { 755 LOGD("Invalid md sys id(%d)!\n", md_id); 756 return -1; 757 } 758 } 759 if(md_id==0 || md_id==1) { 760 if(ccci_get_version() == ECCCI || ccci_get_version() == EDSDA || ccci_get_version() == ECCCI_FSM) 761 stream_support = 1; 762 else 763 stream_support = 0; 764 } else if(md_id == 4) { 765 stream_support = 1; 766 } 767 768 DeviceFd = open_rpc_device(dev_node, O_RDWR); 769 if(DeviceFd < 0) 770 { 771 LOGE("Main: open ccci_rpc fail\r\n"); 772 return -1; 773 } 774 LOGD("%s:dev_node=%s,devicefd= %d\n", __func__, dev_node, DeviceFd); 775 776 if(!stream_support) { 777 g_RpcInfo.pRpcBuf = mmap(NULL, sizeof(rpc_stream_buffer_t), PROT_READ | PROT_WRITE, MAP_SHARED, DeviceFd, 0); 778 } else { 779 int alloc_length = (sizeof(STREAM_DATA) + RPC_MAX_BUF_SIZE) * RPC_BUFFER_SLOT_NUM; 780 g_RpcInfo.pRpcBuf = malloc(alloc_length); 781 if(g_RpcInfo.pRpcBuf == NULL) 782 { 783 LOGE("Main: malloc buffer fail\r\n"); 784 return -1; 785 } 786 memset(g_RpcInfo.pRpcBuf, 0, alloc_length); 787 } 788 PackInfo = malloc(sizeof(RPC_PACKET_INFO) * RPC_MAX_ARG_NUM); 789 if (PackInfo == NULL) { 790 LOGE("Main: PackInfo fail\r\n"); 791 return -1; 792 } 793 794 /* move from while loop, only malloc once */ 795 output = malloc(sizeof(struct amms_msg_response)); 796 if (output == NULL) { 797 LOGE("Main: amms_msg_response fail\r\n"); 798 free(PackInfo); 799 return -1; 800 } 801 802 LOGD("register signal hadler\n"); 803 if(signal(SIGHUP, signal_treatment)==SIG_ERR) 804 LOGE("can't catch SIGHUP\n"); 805 if(signal(SIGPIPE, signal_treatment)==SIG_ERR) 806 LOGE("can't catch SIGPIPE\n"); 807 if(signal(SIGINT, signal_treatment)==SIG_ERR) 808 LOGE("can't catch SIGINT\n"); 809 if(signal(SIGUSR1, signal_treatment)==SIG_ERR) 810 LOGE("can't catch SIGUSR1\n"); 811 if(signal(SIGUSR2, signal_treatment)==SIG_ERR) 812 LOGE("can't catch SIGUSR2\n"); 813 if(signal(SIGTERM, signal_treatment)==SIG_ERR) 814 LOGE("can't catch SIGTERM\n"); 815 if(signal(SIGALRM, signal_treatment)==SIG_ERR) 816 LOGE("can't catch SIGALRM\n"); 817 818 load_support_lib(); 819 820 LOGD("%s:start find md1drdi image\n", __func__); 821 ccci_prepare_drdi_info(); 822 823 while(exit_signal == 0) 824 { 825 PacketNum = 0; 826 retry: 827 if(!stream_support) { 828 ReqBufIndex = ioctl(DeviceFd, CCCI_RPC_IOCTL_GET_INDEX, 0); 829 RPC_WAKE_LOCK(); 830 831 if(ReqBufIndex < 0 || ReqBufIndex > RPC_REQ_BUFFER_MUN) 832 { 833 LOGE("Main: [error]fail get CCCI_RPC buffer index: %d \n", errno); 834 RetVal = RPC_PARAM_ERROR; 835 PackInfo[PacketNum].Length = sizeof(unsigned int); 836 PackInfo[PacketNum++].pData = (void*) &RetVal; 837 goto _Next; 838 } 839 840 pRpcBuf = (rpc_stream_buffer_t *)((char *)g_RpcInfo.pRpcBuf + (RPC_MAX_BUF_SIZE + sizeof(rpc_stream_buffer_t))*ReqBufIndex); 841 } else { 842 while (1) { 843 memset(pkt_buff, 0, MAX_RPC_BUF_BYTE); 844 // add an extra integer as MD consider OP_ID as not part of the "payload" 845 RetVal = read(DeviceFd, pkt_buff, (MAX_RPC_PKT_BYTE+sizeof(CCCI_BUFF_T)+sizeof(unsigned int))); 846 if (RetVal <= 0) { 847 LOGE("Failed to read from RPC device (%d) !! errno = %d", RetVal, errno); 848 goto retry; 849 } 850 851 //LOGD("Read %d bytes from RPC device", RetVal); 852 853 RPC_WAKE_LOCK(); 854 stream = (STREAM_DATA *)pkt_buff; 855 ccci_h = (CCCI_BUFF_T *)&stream->header; 856 ReqBufIndex = ccci_h->reserved; 857 if (ReqBufIndex >= RPC_BUFFER_SLOT_NUM || ReqBufIndex < 0){ 858 LOGD("invalid ReqBufIndex:%d\n", ReqBufIndex); 859 RPC_WAKE_UNLOCK(); 860 free(PackInfo); 861 free(output); 862 return -1; 863 } 864 865 //LOGD("Read %d bytes from slot %d, CCCI_H(0x%X)(0x%X)(0x%X)(0x%X)", 866 //RetVal, ReqBufIndex, ccci_h->data[0], ccci_h->data[1], ccci_h->channel, ccci_h->reserved); 867 868 buffer_slot = (STREAM_DATA *)((char *)g_RpcInfo.pRpcBuf + (RPC_MAX_BUF_SIZE + sizeof(STREAM_DATA))*ReqBufIndex); 869 p_rpc_buff = (char *)buffer_slot; 870 /****************************************** 871 * 872 * FSM description for re-sent mechanism 873 * (ccci_rpc_buff_state == CCCI_RPC_BUFF_IDLE) ==> initial status & end status 874 * (ccci_rpc_buff_state == CCCI_RPC_BUFF_WAIT) ==> need to receive again 875 * 876 ******************************************/ 877 if (!CCCI_RPC_PEER_REQ_SEND_AGAIN(ccci_h)) { 878 if (g_RpcInfo.rpc_buff_state[ReqBufIndex] == RPC_BUFF_IDLE) { 879 /* copy data memory and CCCI header */ 880 LOGD("0 Read %d bytes from slot %d, CCCI_H(0x%X)(0x%X)(0x%X)(0x%X), copy from %p to %p(%p, %p)\n", 881 RetVal, ReqBufIndex, ccci_h->data[0], ccci_h->data[1], ccci_h->channel, 882 ccci_h->reserved, ccci_h, p_rpc_buff, g_RpcInfo, g_RpcInfo.pRpcBuf); 883 memcpy(p_rpc_buff, ccci_h, ccci_h->data[1]); 884 /* don't need to update FS_Address */ 885 } else if (g_RpcInfo.rpc_buff_state[ReqBufIndex] == RPC_BUFF_WAIT) { 886 /* copy data memory and NULL, excluding CCCI header, OP id */ 887 if (ccci_h->data[1] < (sizeof(CCCI_BUFF_T) + sizeof(unsigned int))) { 888 /* data send from modem abnormal */ 889 assert(0); 890 } else { 891 cpy_size = ccci_h->data[1] - sizeof(CCCI_BUFF_T) - sizeof(unsigned int); 892 LOGD("0 Read %d bytes from slot %d, CCCI_H(0x%X)(0x%X)(0x%X)(0x%X), copy from %p/%p to %p(%p, %p)\n", 893 RetVal, ReqBufIndex, ccci_h->data[0], ccci_h->data[1], ccci_h->channel, 894 ccci_h->reserved, ccci_h, stream->payload.buffer, p_rpc_buff, g_RpcInfo, g_RpcInfo.pRpcBuf); 895 896 memcpy(p_rpc_buff + g_RpcInfo.rpc_buff_offset[ReqBufIndex], 897 stream->payload.buffer, cpy_size); 898 /* update CCCI header info */ 899 memcpy(p_rpc_buff, ccci_h, sizeof(CCCI_BUFF_T)); 900 } 901 } else { 902 /* No such rpc_buff_state state */ 903 assert(0); 904 } 905 g_RpcInfo.rpc_buff_state[ReqBufIndex] = RPC_BUFF_IDLE; 906 g_RpcInfo.rpc_buff_offset[ReqBufIndex] = 0; 907 } else { 908 if (g_RpcInfo.rpc_buff_state[ReqBufIndex] == RPC_BUFF_IDLE) { 909 /* only "OP id" and "data" size and "CCCI header" */ 910 unsigned int length = ccci_h->data[1]; 911 LOGD("1 Read %d bytes from slot %d, CCCI_H(0x%X)(0x%X)(0x%X)(0x%X), copy from %p to %p(%p, %p)\n", 912 RetVal, ReqBufIndex, ccci_h->data[0], ccci_h->data[1], ccci_h->channel, 913 ccci_h->reserved, ccci_h, p_rpc_buff, g_RpcInfo, g_RpcInfo.pRpcBuf); 914 915 memcpy(p_rpc_buff, ccci_h, length); 916 g_RpcInfo.rpc_buff_offset[ReqBufIndex] += length; 917 } else if (g_RpcInfo.rpc_buff_state[ReqBufIndex] == RPC_BUFF_WAIT) { 918 /* only "data" size, excluding CCCI header and OP id */ 919 unsigned int length = ccci_h->data[1] - sizeof(CCCI_BUFF_T) - sizeof(unsigned int); 920 LOGD("1 Read %d bytes from slot %d, CCCI_H(0x%X)(0x%X)(0x%X)(0x%X), copy from %p/%p to %p(%p, %p)\n", 921 RetVal, ReqBufIndex, ccci_h->data[0], ccci_h->data[1], ccci_h->channel, 922 ccci_h->reserved, ccci_h, stream->payload.buffer, p_rpc_buff, g_RpcInfo, g_RpcInfo.pRpcBuf); 923 924 memcpy(p_rpc_buff + g_RpcInfo.rpc_buff_offset[ReqBufIndex], 925 stream->payload.buffer, 926 length); /* CCCI_HEADER + RPC_OP_ID */ 927 g_RpcInfo.rpc_buff_offset[ReqBufIndex] += length; 928 } else { 929 /* No such ccci_rpc_buff_state state */ 930 assert(0); 931 } 932 g_RpcInfo.rpc_buff_state[ReqBufIndex] = RPC_BUFF_WAIT; 933 } 934 if (g_RpcInfo.rpc_buff_state[ReqBufIndex] == RPC_BUFF_IDLE) 935 break; 936 RPC_WAKE_UNLOCK(); 937 } 938 pRpcBuf = &buffer_slot->payload; 939 } 940 //LOGD("Main: operation ID = %x\n", pRpcBuf->OperateID); 941 if(!RPC_GetPackInfo(PackInfo, pRpcBuf->buffer)) 942 { 943 LOGE("Main: Fail to get packet info!! \r\n"); 944 RetVal = RPC_PARAM_ERROR; 945 PackInfo[PacketNum].Length = sizeof(unsigned int); 946 PackInfo[PacketNum++].pData = (void*) &RetVal; 947 goto _Next; 948 } 949 950 switch(pRpcBuf->rpc_ops_id) 951 { 952 case IPC_RPC_QUERY_AP_SYS_PROPERTY: 953 { 954 int property_len; 955 char *property_name = (char*)PackInfo[0].pData; 956 957 property_name[PackInfo[0].Length] = 0; 958 RetVal = mtk_property_get(property_name, property_val, NULL); 959 //#ifdef OPLUS_BUG_COMPATIBILITY 960 //Baozhu.Yu@NETWORK.REG.7594487 modify for remove logs print for Sensitive 961 //LOGD("Main: IPC_RPC_QUERY_AP_SYS_PROPERTY, key<%s>, value<%s>, %d\n", property_name, property_val, RetVal); 962 //#endif /*OPLUS_BUG_COMPATIBILITY*/ 963 property_len = strlen(property_val) + 1; 964 PackInfo[PacketNum].Length = sizeof(int); 965 PackInfo[PacketNum++].pData = (void*) &RetVal; 966 PackInfo[PacketNum].Length = property_len; 967 PackInfo[PacketNum++].pData = &property_val; 968 } 969 break; 970 case IPC_RPC_SAR_TABLE_IDX_QUERY_OP: 971 { 972 RetVal = mtk_sar_table_id_get(&sar_tbl_idx); 973 if (!RetVal) 974 LOGE("Main: IPC_RPC_SAR_TABLE_IDX_QUERY_OP:mtk_sar_table_id_get fail\n"); 975 LOGD("Main: IPC_RPC_SAR_TABLE_IDX_QUERY_OP, value: %d, ret: %d\n",sar_tbl_idx, RetVal); 976 PackInfo[PacketNum].Length = sizeof(int); 977 PackInfo[PacketNum++].pData = (void*) &RetVal; 978 PackInfo[PacketNum].Length = sizeof(int); 979 PackInfo[PacketNum++].pData = (void*) &sar_tbl_idx; 980 } 981 break; 982 case IPC_RPC_AMMS_DRDI_CONTROL: 983 { 984 unsigned int pkt_size; 985 986 memset(output, 0x0, sizeof(struct amms_msg_response)); 987 pkt_size = PackInfo[0].Length; 988 989 if (pkt_size == sizeof(struct amms_msg_request)) { 990 input = (struct amms_msg_request *)(PackInfo[0].pData); 991 RetVal = ccci_rpc_amms_drdi_ctl(input, output); 992 } else { 993 LOGE("Main:can't recognize rpc pkt size:%d!\n", pkt_size); 994 RetVal = -1; 995 } 996 PackInfo[PacketNum].Length = sizeof(int); 997 PackInfo[PacketNum++].pData = (void*) &RetVal; 998 PackInfo[PacketNum].Length = sizeof(struct amms_msg_response); 999 PackInfo[PacketNum++].pData = output; 1000 } 1001 break; 1002 case IPC_RPC_SAVE_MD_CAPID: 1003 { 1004 unsigned int pkt_size; 1005 1006 pkt_size = PackInfo[0].Length; 1007 1008 if (pkt_size == sizeof(struct Md_Rpc_Capid_Aac)) { 1009 md_cap_aac = (struct Md_Rpc_Capid_Aac *)(PackInfo[0].pData); 1010 RetVal = ccci_rpc_mdcap_aac_ctl(md_cap_aac, &md_cap_aac_ret); 1011 } else { 1012 LOGE("Main:can't recognize rpc pkt size:%d!\n", pkt_size); 1013 RetVal = -1; 1014 } 1015 PackInfo[PacketNum].Length = sizeof(int); 1016 PackInfo[PacketNum++].pData = (void*) &RetVal; 1017 PackInfo[PacketNum].Length = sizeof(int); 1018 PackInfo[PacketNum++].pData = (void*) &md_cap_aac_ret; 1019 } 1020 break; 1021 default: 1022 if (tc1_srv_check(pRpcBuf->rpc_ops_id, PackInfo, &PacketNum, tmp_buff) == 0) 1023 break; 1024 else { 1025 LOGE("Main: Unknow RPC Operation ID (0x%x)\n", pRpcBuf->rpc_ops_id); 1026 RetVal = RPC_PARAM_ERROR; 1027 PackInfo[PacketNum].Length = sizeof(int); 1028 PackInfo[PacketNum++].pData = (void*) &RetVal; 1029 break; 1030 } 1031 } 1032 _Next: 1033 if(!RPC_WriteToMD(DeviceFd, ReqBufIndex, PackInfo, PacketNum)) 1034 { 1035 LOGE("Main: fail to write packet!!\r\n"); 1036 // return -1; 1037 } 1038 RPC_WAKE_UNLOCK(); 1039 } 1040 LOGD("ccci_rpcd exit, free buffer\n"); 1041 close(DeviceFd); 1042 free(PackInfo); 1043 if(stream_support) 1044 free(g_RpcInfo.pRpcBuf); 1045 dlclose(tc1_support_lib); 1046 if (output != NULL) 1047 free(output); 1048 return 0; 这里面PackInfo是干嘛的
08-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值