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是干嘛的