summaryrefslogtreecommitdiff
path: root/tvapi/libtv/tvutils/tvutils.cpp (plain)
blob: e6879caba9f9f863748f373dc67b6fe435fc8cda
1#include <unistd.h>
2#include <stdio.h>
3#include <string.h>
4#include <errno.h>
5#include <unistd.h>
6#include <sys/ioctl.h>
7#include <sys/types.h>
8#include <sys/stat.h>
9#include <sys/socket.h>
10#include <sys/un.h>
11#include <fcntl.h>
12#include <ctype.h>
13#include <sys/prctl.h>
14#include <stdlib.h>
15#include <android/log.h>
16#include <cutils/android_reboot.h>
17#include "../tvconfig/tvconfig.h"
18#include "../tvsetting/CTvSetting.h"
19#include <cutils/properties.h>
20#include <dirent.h>
21using namespace android;
22
23#include "tvutils.h"
24
25#define LOG_TAG "LibTvMISC"
26#include "CTvLog.h"
27
28#define CS_I2C_1_DEV_PATH "/dev/i2c-1"
29#define CS_I2C_2_DEV_PATH "/dev/i2c-2"
30
31/* number of times a device address should be polled when not acknowledging */
32#define I2C_RETRIES 0x0701
33
34/* set timeout in units of 10 ms */
35#define I2C_TIMEOUT 0x0702
36
37/* NOTE: Slave address is 7 or 10 bits, but 10-bit addresses
38 * are NOT supported! (due to code brokenness)
39 */
40
41/* Use this slave address */
42#define I2C_SLAVE 0x0703
43
44/* Use this slave address, even if it is already in use by a driver! */
45#define I2C_SLAVE_FORCE 0x0706
46
47#define I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */
48#define I2C_FUNCS 0x0705 /* Get the adapter functionality mask */
49#define I2C_RDWR 0x0707 /* Combined R/W transfer (one STOP only) */
50#define I2C_PEC 0x0708 /* != 0 to use PEC with SMBus */
51#define I2C_SMBUS 0x0720 /* SMBus transfer */
52
53struct i2c_msg {
54 unsigned short addr; /* slave address */
55 unsigned short flags;
56#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
57#define I2C_M_WR 0x0000 /* write data, from master to slave */
58#define I2C_M_RD 0x0001 /* read data, from slave to master */
59#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */
60#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
61#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
62#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
63#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
64
65 unsigned short len; /* msg length */
66 unsigned char *buf; /* pointer to msg data */
67};
68
69struct i2c_rdwr_ioctl_data {
70 struct i2c_msg *msgs;
71 unsigned int nmsgs;
72};
73
74static volatile int mDreamPanelResumeLastBLFlag = 0;
75static volatile int mDreamPanelDemoFlag = 0;
76
77static pthread_mutex_t dream_panel_resume_last_bl_flag_mutex = PTHREAD_MUTEX_INITIALIZER;
78static pthread_mutex_t dream_panel_demo_flag_mutex = PTHREAD_MUTEX_INITIALIZER;
79static pthread_mutex_t file_attr_control_flag_mutex = PTHREAD_MUTEX_INITIALIZER;
80
81static pthread_t UserPet_ThreadId = 0;
82static unsigned char is_turnon_user_pet_thread = false;
83static unsigned char is_user_pet_thread_start = false;
84static unsigned int user_counter = 0;
85static unsigned int user_pet_terminal = 1;
86
87static int iw_duty = 0;
88
89static int Miscioctl(const char *file_path, int request, ...)
90{
91 int fd = -1, tmp_ret = -1;
92 int bus_status = 0;
93 va_list ap;
94 void *arg;
95
96 if (file_path == NULL) {
97 LOGE("%s, file path is NULL!!!\n", CFG_SECTION_TV);
98 return -1;
99 }
100
101 fd = open(file_path, O_RDWR);
102 if (fd < 0) {
103 LOGE("%s, Open %s ERROR(%s)!!\n", CFG_SECTION_TV, file_path, strerror(errno));
104 return -1;
105 }
106
107 va_start(ap, request);
108 arg = va_arg(ap, void *);
109 va_end(ap);
110
111 tmp_ret = ioctl(fd, request, arg);
112
113 close(fd);
114 fd = -1;
115
116 return tmp_ret;
117}
118
119int cfg_get_one_item(const char *key_str, const char *strDelimit, int item_index, char cfg_str[])
120{
121 int cfg_item_ind = 0;
122 char *token = NULL;
123 const char *config_value;
124 char data_str[CC_CFG_VALUE_STR_MAX_LEN] = { 0 };
125
126 if (key_str == NULL) {
127 LOGE("%s, key_str's pointer is NULL.\n", CFG_SECTION_TV);
128 return -1;
129 }
130
131 if (cfg_str == NULL) {
132 LOGE("%s, cfg_str's pointer is NULL.\n", CFG_SECTION_TV);
133 return -1;
134 }
135
136 if (item_index < 0) {
137 LOGE("%s, item_index can't be less than 0.\n", CFG_SECTION_TV);
138 return -1;
139 }
140
141 config_value = config_get_str(CFG_SECTION_TV, key_str, "null");
142 if (strcasecmp(config_value, "null") == 0) {
143 cfg_str[0] = '\0';
144 LOGE("%s, can't get config \"%s\"!!!\n", CFG_SECTION_TV, key_str);
145 return -1;
146 }
147
148 cfg_item_ind = 0;
149
150 memset((void *)data_str, 0, sizeof(data_str));
151 strncpy(data_str, config_value, sizeof(data_str) - 1);
152
153 token = strtok(data_str, strDelimit);
154 while (token != NULL) {
155 if (cfg_item_ind == item_index) {
156 strcpy(cfg_str, token);
157 break;
158 }
159
160 token = strtok(NULL, strDelimit);
161 cfg_item_ind += 1;
162 }
163
164 if (token == NULL) {
165 cfg_str[0] = '\0';
166 return -1;
167 }
168
169 return 0;
170}
171
172int cfg_split(char *line_data, char *strDelimit, int *item_cnt, char **item_bufs)
173{
174 int i = 0, tmp_cnt = 0;
175 char *token = NULL;
176
177 if (line_data == NULL) {
178 LOGE("%s, line_data is NULL", CFG_SECTION_TV);
179 return -1;
180 }
181
182 if (strDelimit == NULL) {
183 LOGE("%s, strDelimit is NULL", CFG_SECTION_TV);
184 return -1;
185 }
186
187 if (item_cnt == NULL) {
188 LOGE("%s, item_cnt is NULL", CFG_SECTION_TV);
189 return -1;
190 }
191
192 if (item_bufs == NULL) {
193 LOGE("%s, item_bufs is NULL", CFG_SECTION_TV);
194 return -1;
195 }
196
197 for (i = 0; i < *item_cnt; i++) {
198 item_bufs[i] = NULL;
199 }
200
201 token = strtok(line_data, strDelimit);
202
203 while (token != NULL) {
204 item_bufs[tmp_cnt] = token;
205
206 token = strtok(NULL, strDelimit);
207
208 tmp_cnt += 1;
209 if (tmp_cnt >= *item_cnt) {
210 break;
211 }
212 }
213
214 *item_cnt = tmp_cnt;
215
216 return 0;
217}
218
219int ReadADCSpecialChannelValue(int adc_channel_num)
220{
221 FILE *fp = NULL;
222 int rd_data = 0;
223 char ch_sysfs_path[256] = { 0 };
224
225 if (adc_channel_num < CC_MIN_ADC_CHANNEL_VAL || adc_channel_num > CC_MAX_ADC_CHANNEL_VAL) {
226 LOGD("adc channel num must between %d and %d.", CC_MIN_ADC_CHANNEL_VAL, CC_MAX_ADC_CHANNEL_VAL);
227 return 0;
228 }
229
230 sprintf(ch_sysfs_path, "/sys/class/saradc/saradc_ch%d", adc_channel_num);
231
232 fp = fopen(ch_sysfs_path, "r");
233
234 if (fp == NULL) {
235 LOGE("open %s ERROR(%s)!!\n", ch_sysfs_path, strerror(errno));
236 return 0;
237 }
238
239 fscanf(fp, "%d", &rd_data);
240
241 fclose(fp);
242
243 return rd_data;
244}
245
246int Tv_MiscRegs(const char *cmd)
247{
248 //#ifdef BRING_UP_DEBUG
249 FILE *fp = NULL;
250 fp = fopen("/sys/class/register/reg", "w");
251
252 if (fp != NULL && cmd != NULL) {
253 fprintf(fp, "%s", cmd);
254 } else {
255 LOGE("Open /sys/class/register/reg ERROR(%s)!!\n", strerror(errno));
256 fclose(fp);
257 return -1;
258 }
259 fclose(fp);
260 //#endif
261
262 return 0;
263}
264
265int TvMisc_SetLVDSSSC(int val)
266{
267 FILE *fp;
268
269 fp = fopen("/sys/class/lcd/ss", "w");
270
271 if (fp != NULL) {
272 fprintf(fp, "%d", val);
273 fclose(fp);
274 } else {
275 LOGE("open /sys/class/lcd/ss ERROR(%s)!!\n", strerror(errno));
276 return -1;
277 }
278 return 0;
279}
280
281int TvMisc_SetUserCounterTimeOut(int timeout)
282{
283 FILE *fp;
284
285 fp = fopen("/sys/devices/platform/aml_wdt/user_pet_timeout", "w");
286
287 if (fp != NULL) {
288 fprintf(fp, "%d", timeout);
289 fclose(fp);
290 } else {
291 LOGE("=OSD CPP=> open /sys/devices/platform/aml_wdt/user_pet_timeout ERROR(%s)!!\n", strerror(errno));
292 return -1;
293 }
294 return 0;
295}
296
297int TvMisc_SetUserCounter(int count)
298{
299 FILE *fp;
300
301 fp = fopen("/sys/module/aml_wdt/parameters/user_pet", "w");
302
303 if (fp != NULL) {
304 fprintf(fp, "%d", count);
305 fclose(fp);
306 } else {
307 LOGE("=OSD CPP=> open /sys/devices/platform/aml_wdt/user_pet ERROR(%s)!!\n", strerror(errno));
308 return -1;
309 }
310
311 fclose(fp);
312
313 return 0;
314}
315
316int TvMisc_SetUserPetResetEnable(int enable)
317{
318 FILE *fp;
319
320 fp = fopen("/sys/module/aml_wdt/parameters/user_pet_reset_enable", "w");
321
322 if (fp != NULL) {
323 fprintf(fp, "%d", enable);
324 fclose(fp);
325 } else {
326 LOGE("=OSD CPP=> open /sys/devices/platform/aml_wdt/user_pet_reset_enable ERROR(%s)!!\n", strerror(errno));
327 return -1;
328 }
329
330 fclose(fp);
331
332 return 0;
333}
334
335int TvMisc_SetSystemPetResetEnable(int enable)
336{
337 FILE *fp;
338
339 fp = fopen("/sys/devices/platform/aml_wdt/reset_enable", "w");
340
341 if (fp != NULL) {
342 fprintf(fp, "%d", enable);
343 fclose(fp);
344 } else {
345 LOGE("=OSD CPP=> open /sys/devices/platform/aml_wdt/reset_enable ERROR(%s)!!\n", strerror(errno));
346 return -1;
347 }
348
349 fclose(fp);
350
351 return 0;
352}
353
354int TvMisc_SetSystemPetEnable(int enable)
355{
356 FILE *fp;
357
358 fp = fopen("/sys/devices/platform/aml_wdt/ping_enable", "w");
359
360 if (fp != NULL) {
361 fprintf(fp, "%d", enable);
362 fclose(fp);
363 } else {
364 LOGE("=OSD CPP=> open /sys/devices/platform/aml_wdt/ping_enable ERROR(%s)!!\n", strerror(errno));
365 return -1;
366 }
367
368 fclose(fp);
369
370 return 0;
371}
372
373int TvMisc_SetSystemPetCounterTimeOut(int timeout)
374{
375 FILE *fp;
376
377 fp = fopen("/sys/devices/platform/aml_wdt/wdt_timeout", "w");
378
379 if (fp != NULL) {
380 fprintf(fp, "%d", timeout);
381 fclose(fp);
382 } else {
383 LOGE("=OSD CPP=> open /sys/devices/platform/aml_wdt/wdt_timeout ERROR(%s)!!\n", strerror(errno));
384 return -1;
385 }
386
387 fclose(fp);
388
389 return 0;
390}
391
392#define MEMERASE _IOW('M', 2, struct erase_info_user)
393static int memerase(int fd, struct erase_info_user *erase)
394{
395 return (ioctl (fd, MEMERASE, erase));
396}
397
398#define CS_ATV_SOCKET_FILE_NAME "/dev/socket/datv_sock"
399
400static int setServer(const char *fileName)
401{
402 int ret = -1, sock = -1;
403 struct sockaddr_un srv_addr;
404
405 sock = socket(PF_UNIX, SOCK_STREAM, 0);
406 if (sock < 0) {
407 LOGE("%s, socket create failed (errno = %d: %s).\n", CFG_SECTION_TV, errno, strerror(errno));
408 return -1;
409 }
410
411 //set server addr_param
412 srv_addr.sun_family = AF_UNIX;
413 strncpy(srv_addr.sun_path, CS_ATV_SOCKET_FILE_NAME, sizeof(srv_addr.sun_path) - 1);
414 unlink(CS_ATV_SOCKET_FILE_NAME);
415
416 //bind sockfd & addr
417 ret = bind(sock, (struct sockaddr *) &srv_addr, sizeof(srv_addr));
418 if (ret == -1) {
419 LOGE("%s, cannot bind server socket.\n", CFG_SECTION_TV);
420 close(sock);
421 unlink(CS_ATV_SOCKET_FILE_NAME);
422 return -1;
423 }
424
425 //listen sockfd
426 ret = listen(sock, 1);
427 if (ret == -1) {
428 LOGE("%s, cannot listen the client connect request.\n", CFG_SECTION_TV);
429 close(sock);
430 unlink(CS_ATV_SOCKET_FILE_NAME);
431 return -1;
432 }
433
434 return sock;
435}
436
437static int acceptMessage(int listen_fd)
438{
439 int ret, com_fd;
440 socklen_t len;
441 struct sockaddr_un clt_addr;
442
443 //have connect request use accept
444 len = sizeof(clt_addr);
445 com_fd = accept(listen_fd, (struct sockaddr *) &clt_addr, &len);
446 if (com_fd < 0) {
447 LOGE("%s, cannot accept client connect request.\n", CFG_SECTION_TV);
448 close(listen_fd);
449 unlink(CS_ATV_SOCKET_FILE_NAME);
450 return -1;
451 }
452
453 LOGD("%s, com_fd = %d\n", CFG_SECTION_TV, com_fd);
454
455 return com_fd;
456}
457
458static int parse_socket_message(char *msg_str, int *para_cnt, int para_buf[])
459{
460 int para_count = 0, set_mode = 0;
461 char *token = NULL;
462
463 set_mode = -1;
464
465 token = strtok(msg_str, ",");
466 if (token != NULL) {
467 if (strcasecmp(token, "quit") == 0) {
468 set_mode = 0;
469 } else if (strcasecmp(token, "SetAudioVolumeCompensationVal") == 0) {
470 set_mode = 1;
471 } else if (strcasecmp(token, "set3dmode") == 0) {
472 set_mode = 2;
473 } else if (strcasecmp(token, "setdisplaymode") == 0) {
474 set_mode = 3;
475 }
476 }
477
478 if (set_mode != 1 && set_mode != 2 && set_mode != 3) {
479 return set_mode;
480 }
481
482 para_count = 0;
483
484 token = strtok(NULL, ",");
485 while (token != NULL) {
486 para_buf[para_count] = strtol(token, NULL, 10);
487 para_count += 1;
488
489 token = strtok(NULL, ",");
490 }
491
492 *para_cnt = para_count;
493
494 return set_mode;
495}
496
497/*static void* socket_thread_entry(void *arg)
498{
499 int ret = 0, listen_fd = -1, com_fd = -1, rd_len = 0;
500 int para_count = 0, set_mode = 0;
501 int tmp_val = 0;
502 int para_buf[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
503 static char recv_buf[1024];
504
505 listen_fd = setServer(CS_ATV_SOCKET_FILE_NAME);
506 chmod(CS_ATV_SOCKET_FILE_NAME, 0666);
507 prctl(PR_SET_NAME, (unsigned long) "datv.sock.thread");
508
509 if (listen_fd < 0) {
510 return NULL;
511 }
512
513 while (1) {
514 com_fd = acceptMessage(listen_fd);
515
516 if (com_fd >= 0) {
517 //read message from client
518 memset((void *) recv_buf, 0, sizeof(recv_buf));
519 rd_len = read(com_fd, recv_buf, sizeof(recv_buf));
520 LOGD("%s, message from client (%d)) : %s\n", CFG_SECTION_TV, rd_len, recv_buf);
521
522 set_mode = parse_socket_message(recv_buf, &para_count, para_buf);
523 if (set_mode == 0) {
524 LOGD("%s, receive quit message, starting to quit.\n", CFG_SECTION_TV);
525 sprintf(recv_buf, "%s", "quiting now...");
526 write(com_fd, recv_buf, strlen(recv_buf) + 1);
527 break;
528 } else if (set_mode == 1) {
529 ret = -1;
530
531 if (para_count == 1) {
532 LOGD("%s, SetAudioVolumeCompensationVal value = %d\n", CFG_SECTION_TV, para_buf[0]);
533
534 ret = SetAudioVolumeCompensationVal(para_buf[0]);
535 } else if (para_count == 2) {
536 LOGD("%s, SetAudioVolumeCompensationVal value = %d, type = %d\n", CFG_SECTION_TV, para_buf[0], para_buf[1]);
537
538 ret = SetAudioVolumeCompensationVal(para_buf[0]);
539
540 if (para_buf[1] == 1) {
541 tmp_val = GetAudioMasterVolume();
542 ret |= SetAudioMasterVolume(tmp_val);
543 }
544 }
545
546 sprintf(recv_buf, "%d", ret);
547 write(com_fd, recv_buf, strlen(recv_buf) + 1);
548 } else if (set_mode == 2) {
549 ret = -1;
550
551 if (para_count == 1) {
552 LOGE("%s, mode = %d ------->\n", CFG_SECTION_TV, para_buf[0]);
553
554 switch (para_buf[0]) {
555 case 4: //BT
556 ret = Tvin_Set3DFunction(MODE3D_BT);
557 break;
558 case 5: //LR
559 ret = Tvin_Set3DFunction(MODE3D_LR);
560 break;
561 case 8: //
562 ret = Tvin_Set3DFunction(MODE3D_DISABLE);
563 break;
564 case 0:
565 ret = Tvin_Set3DFunction(MODE3D_DISABLE);
566 break;
567 case 9: //
568 ret = Tvin_Set3DFunction(MODE3D_L_3D_TO_2D);
569 break;
570 }
571 if (ret == 0) {
572 LOGE("%s, sk_hdi_av_set_3d_mode return sucess.\n", CFG_SECTION_TV);
573 } else {
574 LOGE("%s, sk_hdi_av_set_3d_mode return error(%d).\n", CFG_SECTION_TV, ret);
575 }
576 }
577
578 sprintf(recv_buf, "%d", ret);
579 write(com_fd, recv_buf, strlen(recv_buf) + 1);
580
581 }
582
583 close(com_fd);
584 com_fd = -1;
585 }
586 }
587
588 if (com_fd >= 0) {
589 close(com_fd);
590 com_fd = -1;
591 }
592
593 if (listen_fd >= 0) {
594 close(listen_fd);
595 listen_fd = -1;
596 }
597
598 unlink(CS_ATV_SOCKET_FILE_NAME);
599
600 return NULL;
601}*/
602
603#if !defined(SUN_LEN)
604#define SUN_LEN(su) (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
605#endif
606
607static int connectToServer(char *file_name)
608{
609 int tmp_ret = 0, sock = -1;
610 struct sockaddr_un addr;
611
612 if (file_name == NULL) {
613 LOGE("%s, file name is NULL\n", CFG_SECTION_TV);
614 return -1;
615 }
616
617 sock = socket(AF_UNIX, SOCK_STREAM, 0);
618 if (sock < 0) {
619 LOGE("%s, socket create failed (errno = %d: %s)\n", CFG_SECTION_TV, errno, strerror(errno));
620 return -1;
621 }
622
623 /* connect to socket; fails if file doesn't exist */
624 strcpy(addr.sun_path, file_name); // max 108 bytes
625 addr.sun_family = AF_UNIX;
626 tmp_ret = connect(sock, (struct sockaddr *) &addr, SUN_LEN(&addr));
627 if (tmp_ret < 0) {
628 // ENOENT means socket file doesn't exist
629 // ECONNREFUSED means socket exists but nobody is listening
630 LOGE("%s, AF_UNIX connect failed for '%s': %s\n", CFG_SECTION_TV, file_name, strerror(errno));
631 close(sock);
632 return -1;
633 }
634
635 return sock;
636}
637
638static int realSendSocketMsg(char *file_name, char *msg_str, char recv_buf[])
639{
640 int sock = -1, rd_len = 0;
641 char tmp_buf[1024];
642
643 if (file_name == NULL) {
644 LOGE("%s, file name is NULL\n", CFG_SECTION_TV);
645 return -1;
646 }
647
648 if (msg_str == NULL) {
649 LOGE("%s, msg string is NULL\n", CFG_SECTION_TV);
650 return -1;
651 }
652
653 LOGD("%s, message to server (%d)) : %s\n", CFG_SECTION_TV, strlen(msg_str), msg_str);
654
655 sock = connectToServer(file_name);
656
657 if (sock >= 0) {
658 write(sock, msg_str, strlen(msg_str) + 1);
659
660 if (recv_buf == NULL) {
661 memset((void *) tmp_buf, 0, sizeof(tmp_buf));
662 rd_len = read(sock, tmp_buf, sizeof(tmp_buf));
663 LOGD("%s, message from server (%d)) : %s\n", CFG_SECTION_TV, rd_len, tmp_buf);
664 } else {
665 rd_len = read(sock, recv_buf, 1024);
666 LOGD("%s, message from server (%d)) : %s\n", CFG_SECTION_TV, rd_len, recv_buf);
667 }
668
669 close(sock);
670 sock = -1;
671
672 return 0;
673 }
674
675 return -1;
676}
677
678int I2C_WriteNbyte(int i2c_no, int dev_addr, int slave_addr, int len, unsigned char data_buf[])
679{
680 int tmp_ret = 0;
681 struct i2c_rdwr_ioctl_data ctl_data;
682 struct i2c_msg msg;
683 unsigned char msg_buf[52];
684 int device_fd = -1;
685
686 memset((void *) msg_buf, 0, 52);
687
688 msg_buf[0] = (unsigned char) (slave_addr >> 8);
689 msg_buf[1] = (unsigned char) (slave_addr & 0x00ff);
690
691 if (data_buf == NULL) {
692 return -1;
693 }
694
695 if (len < 50) {
696 memcpy((void *) &msg_buf[2], data_buf, len);
697 } else {
698 LOGE("I2C_WriteNbyte len(%d) > 50, error!\n", len);
699 return -1;
700 }
701
702 msg.addr = dev_addr;
703 msg.flags = I2C_M_WR;
704 msg.len = 2 + len;
705 msg.buf = msg_buf;
706 ctl_data.nmsgs = 1;
707 ctl_data.msgs = &msg;
708
709 if (i2c_no == 1) {
710 device_fd = open(CS_I2C_1_DEV_PATH, O_RDWR);
711 if (device_fd < 0) {
712 LOGE("%s, Open device file %S error: %s.\n", CFG_SECTION_TV, CS_I2C_1_DEV_PATH, strerror(errno));
713 return -1;
714 }
715 } else if (i2c_no == 2) {
716 device_fd = open(CS_I2C_2_DEV_PATH, O_RDWR);
717 if (device_fd < 0) {
718 LOGE("%s, Open device file %S error: %s.\n", CFG_SECTION_TV, CS_I2C_2_DEV_PATH, strerror(errno));
719 return -1;
720 }
721 } else {
722 LOGE("%s, invalid i2c no (%d).\n", CFG_SECTION_TV, i2c_no);
723 return -1;
724 }
725
726 tmp_ret = ioctl(device_fd, I2C_RDWR, &ctl_data);
727
728 usleep(10 * 1000);
729 if (device_fd >= 0) {
730 close(device_fd);
731 device_fd = -1;
732 }
733 return tmp_ret;
734}
735
736int I2C_ReadNbyte(int i2c_no, int dev_addr, int slave_addr, int len, unsigned char data_buf[])
737{
738 int tmp_ret = 0;
739 struct i2c_rdwr_ioctl_data ctl_data;
740 struct i2c_msg msg;
741 unsigned char msg_buf[52];
742 int device_fd = -1;
743
744 memset((void *) msg_buf, 0, 52);
745
746 if (data_buf == NULL) {
747 return -1;
748 }
749
750 if (len < 50) {
751 memcpy((void *) &msg_buf[2], data_buf, len);
752 } else {
753 LOGE("I2C_WriteNbyte len(%d) > 50, error!\n", len);
754 return -1;
755 }
756
757 msg_buf[0] = (unsigned char) (slave_addr >> 8);
758 msg_buf[1] = (unsigned char) (slave_addr & 0x00ff);
759 msg.addr = dev_addr;
760 msg.flags = I2C_M_WR;
761 msg.len = 2;
762 msg.buf = msg_buf;
763 ctl_data.nmsgs = 1;
764 ctl_data.msgs = &msg;
765
766 if (i2c_no == 1) {
767 device_fd = open(CS_I2C_1_DEV_PATH, O_RDWR);
768 if (device_fd < 0) {
769 LOGE("%s, Open device file %S error: %s.\n", CFG_SECTION_TV, CS_I2C_1_DEV_PATH, strerror(errno));
770 return -1;
771 }
772 } else if (i2c_no == 2) {
773 device_fd = open(CS_I2C_2_DEV_PATH, O_RDWR);
774 if (device_fd < 0) {
775 LOGE("%s, Open device file %S error: %s.\n", CFG_SECTION_TV, CS_I2C_2_DEV_PATH, strerror(errno));
776 return -1;
777 }
778 } else {
779 LOGE("%s, invalid i2c no (%d).\n", CFG_SECTION_TV, i2c_no);
780 return -1;
781 }
782
783 tmp_ret = ioctl(device_fd, I2C_RDWR, &ctl_data);
784
785 msg.addr = dev_addr;
786 msg.flags |= I2C_M_RD;
787 msg.len = len;
788 msg.buf = data_buf;
789 ctl_data.nmsgs = 1;
790 ctl_data.msgs = &msg;
791
792 tmp_ret = ioctl(device_fd, I2C_RDWR, &ctl_data);
793
794 usleep(10 * 1000);
795
796 if (device_fd >= 0) {
797 close(device_fd);
798 device_fd = -1;
799 }
800 return tmp_ret;
801}
802
803int SetFileAttrValue(const char *fp, const char value[])
804{
805 int fd = -1, ret = -1;
806
807 pthread_mutex_lock(&file_attr_control_flag_mutex);
808
809 fd = open(fp, O_RDWR);
810
811 if (fd < 0) {
812 LOGE("open %s ERROR(%s)!!\n", fp, strerror(errno));
813 pthread_mutex_unlock(&file_attr_control_flag_mutex);
814 return -1;
815 }
816
817 ret = write(fd, value, strlen(value));
818 close(fd);
819
820 pthread_mutex_unlock(&file_attr_control_flag_mutex);
821 return ret;
822}
823
824int GetFileAttrIntValue(const char *fp)
825{
826 int fd = -1, ret = -1;
827 int temp = -1;
828 char temp_str[32];
829
830 memset(temp_str, 0, 32);
831
832 fd = open(fp, O_RDWR);
833
834 if (fd <= 0) {
835 LOGE("open %s ERROR(%s)!!\n", fp, strerror(errno));
836 return -1;
837 }
838
839 if (read(fd, temp_str, sizeof(temp_str)) > 0) {
840 if (sscanf(temp_str, "%d", &temp) >= 0) {
841 LOGD("%s -> get %s value =%d!\n", CFG_SECTION_TV, fp, temp);
842 close(fd);
843 return temp;
844 } else {
845 LOGE("%s -> get %s value error(%s)\n", CFG_SECTION_TV, fp, strerror(errno));
846 close(fd);
847 return -1;
848 }
849 }
850
851 close(fd);
852 return -1;
853}
854
855int *GetFileAttrIntValueStr(const char *fp)
856{
857 int fd = -1, ret = -1;
858 static int temp[4];
859 char temp_str[32];
860 int i = 0;
861 char *p = NULL;
862
863 memset(temp_str, 0, 32);
864
865 fd = open(fp, O_RDWR);
866
867 if (fd <= 0) {
868 LOGE("open %s ERROR(%s)!!\n", fp, strerror(errno));
869 return NULL;
870 }
871
872 if (read(fd, temp_str, sizeof(temp_str)) > 0) {
873 LOGD("%s,temp_str = %s\n", CFG_SECTION_TV, temp_str);
874 p = strtok(temp_str, " ");
875 while (p != NULL) {
876 sscanf(p, "%d", &temp[i]);
877 p = strtok(NULL, " ");
878 i = i + 1;
879 }
880 close(fd);
881 return temp;
882 }
883
884 close(fd);
885 return NULL;
886}
887
888int Get_Fixed_NonStandard(void)
889{
890 return GetFileAttrIntValue("/sys/module/tvin_afe/parameters/force_nostd");
891}
892
893//0-turn off
894//1-force non-standard
895//2-force normal
896int Set_Fixed_NonStandard(int value)
897{
898 int fd = -1, ret = -1;
899 char set_vale[32];
900 memset(set_vale, '\0', 32);
901
902 sprintf(set_vale, "%d", value);
903
904 fd = open("/sys/module/tvin_afe/parameters/force_nostd", O_RDWR);
905
906 if (fd >= 0) {
907 ret = write(fd, set_vale, strlen(set_vale));
908 }
909
910 if (ret <= 0) {
911 LOGE("%s -> set /sys/module/tvin_afe/parameters/force_nostd error(%s)!\n", CFG_SECTION_TV, strerror(errno));
912 }
913
914 close(fd);
915
916 return ret;
917}
918
919static void *UserPet_TreadRun(void *data)
920{
921 while (is_turnon_user_pet_thread == true) {
922 if (is_user_pet_thread_start == true) {
923 usleep(1000 * 1000);
924 if (++user_counter == 0xffffffff)
925 user_counter = 1;
926 TvMisc_SetUserCounter(user_counter);
927 } else {
928 usleep(10000 * 1000);
929 }
930 }
931 if (user_pet_terminal == 1) {
932 user_counter = 0;
933 } else {
934 user_counter = 1;
935 }
936 TvMisc_SetUserCounter(user_counter);
937 return ((void *) 0);
938}
939
940static int UserPet_CreateThread(void)
941{
942 int ret = 0;
943 pthread_attr_t attr;
944 struct sched_param param;
945
946 is_turnon_user_pet_thread = true;
947 is_user_pet_thread_start = true;
948
949 pthread_attr_init(&attr);
950 pthread_attr_setschedpolicy(&attr, SCHED_RR);
951 param.sched_priority = 1;
952 pthread_attr_setschedparam(&attr, &param);
953 ret = pthread_create(&UserPet_ThreadId, &attr, &UserPet_TreadRun, NULL);
954 pthread_attr_destroy(&attr);
955 return ret;
956}
957
958static void UserPet_KillThread(void)
959{
960 int i = 0, dly = 600;
961 is_turnon_user_pet_thread = false;
962 is_user_pet_thread_start = false;
963 for (i = 0; i < 2; i++) {
964 usleep(dly * 1000);
965 }
966 pthread_join(UserPet_ThreadId, NULL);
967 UserPet_ThreadId = 0;
968 LOGD("%s, done.", CFG_SECTION_TV);
969}
970
971void TvMisc_EnableWDT(bool kernelpet_disable, unsigned int userpet_enable, unsigned int kernelpet_timeout, unsigned int userpet_timeout, unsigned int userpet_reset)
972{
973 TvMisc_SetSystemPetCounterTimeOut(kernelpet_timeout);
974 TvMisc_SetSystemPetEnable(1);
975 if (kernelpet_disable) {
976 TvMisc_SetSystemPetResetEnable(0);
977 } else {
978 TvMisc_SetSystemPetResetEnable(1);
979 }
980 if (userpet_enable) {
981 TvMisc_SetUserCounterTimeOut(userpet_timeout);
982 TvMisc_SetUserPetResetEnable(userpet_reset);
983 UserPet_CreateThread();
984 } else {
985 TvMisc_SetUserCounter(0);
986 TvMisc_SetUserPetResetEnable(0);
987 }
988}
989
990void TvMisc_DisableWDT(unsigned int userpet_enable)
991{
992 if (userpet_enable) {
993 user_pet_terminal = 0;
994 UserPet_KillThread();
995 }
996}
997
998static int get_hardware_info(char *hardware, unsigned int *revision)
999{
1000 char data[1024];
1001 int fd, n;
1002 char *x, *hw, *rev;
1003
1004 fd = open("/proc/cpuinfo", O_RDONLY);
1005 if (fd < 0) {
1006 return -1;
1007 }
1008
1009 n = read(fd, data, 1023);
1010 close(fd);
1011 if (n < 0) {
1012 return -1;
1013 }
1014
1015 data[n] = 0;
1016
1017 if (hardware != NULL) {
1018 hw = strstr(data, "\nHardware");
1019
1020 if (hw) {
1021 x = strstr(hw, ": ");
1022 if (x) {
1023 x += 2;
1024 n = 0;
1025 while (*x && *x != '\n' && !isspace(*x)) {
1026 hardware[n++] = tolower(*x);
1027 x++;
1028 if (n == 31) {
1029 break;
1030 }
1031 }
1032
1033 hardware[n] = 0;
1034 }
1035 }
1036 }
1037
1038 if (revision != NULL) {
1039 rev = strstr(data, "\nRevision");
1040
1041 if (rev) {
1042 x = strstr(rev, ": ");
1043 if (x) {
1044 *revision = strtoul(x + 2, 0, 16);
1045 }
1046 }
1047 }
1048
1049 return 0;
1050}
1051
1052int get_hardware_name(char *hardware)
1053{
1054 int tmp_ret = 0;
1055
1056 if (hardware == NULL) {
1057 return -1;
1058 }
1059
1060 tmp_ret = get_hardware_info(hardware, NULL);
1061 if (tmp_ret < 0) {
1062 hardware[0] = '\0';
1063 }
1064
1065 return 0;
1066}
1067
1068/*---------------delete dir---------------*/
1069int TvMisc_DeleteDirFiles(const char *strPath, int flag)
1070{
1071 int status;
1072 char tmp[256];
1073 switch (flag) {
1074 case 0:
1075 sprintf(tmp, "rm -f %s", strPath);
1076 LOGE("%s", tmp);
1077 system(tmp);
1078 break;
1079 case 1:
1080 sprintf(tmp, "cd %s", strPath);
1081 LOGE("%s", tmp);
1082 status = system(tmp);
1083 if (status > 0 || status < 0)
1084 return -1;
1085 sprintf(tmp, "cd %s;rm -rf *", strPath);
1086 system(tmp);
1087 LOGE("%s", tmp);
1088 break;
1089 case 2:
1090 sprintf(tmp, "rm -rf %s", strPath);
1091 LOGE("%s", tmp);
1092 system(tmp);
1093 break;
1094 }
1095 return 0;
1096}
1097/*---------------delete dir end-----------*/
1098
1099#ifndef NELEM
1100# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
1101#endif
1102
1103
1104int Tv_Utils_CheckFs(void)
1105{
1106 FILE *f;
1107 char mount_dev[256];
1108 char mount_dir[256];
1109 char mount_type[256];
1110 char mount_opts[256];
1111 int mount_freq;
1112 int mount_passno;
1113 int match;
1114 int found_ro_fs = 0;
1115 int data_status = 0;
1116 int cache_status = 0;
1117 int atv_status = 0;
1118 int dtv_status = 0;
1119 int param_status = 0;
1120 int cool_reboot = 0;
1121 int recovery_reboot = 0;
1122
1123 f = fopen("/proc/mounts", "r");
1124 if (! f) {
1125 /* If we can't read /proc/mounts, just give up */
1126 return 1;
1127 }
1128
1129 do {
1130 match = fscanf(f, "%255s %255s %255s %255s %d %d\n",
1131 mount_dev, mount_dir, mount_type,
1132 mount_opts, &mount_freq, &mount_passno);
1133 mount_dev[255] = 0;
1134 mount_dir[255] = 0;
1135 mount_type[255] = 0;
1136 mount_opts[255] = 0;
1137 if ((match == 6) && (!strncmp(mount_dev, "/dev/block", 10))) {
1138 LOGD("%s, %s %s %s %s %d %d!", CFG_SECTION_TV, mount_dev, mount_dir, mount_type, mount_opts, mount_freq, mount_passno);
1139 if (!strncmp(mount_dir, "/param", 6)) {
1140 param_status |= 0x01;
1141 } else if (!strncmp(mount_dir, "/atv", 4)) {
1142 atv_status |= 0x01;
1143 } else if (!strncmp(mount_dir, "/dtv", 4)) {
1144 dtv_status |= 0x01;
1145 } else if (!strncmp(mount_dir, "/data", 5)) {
1146 data_status |= 0x01;
1147 } else if (!strncmp(mount_dir, "/cache", 6)) {
1148 cache_status |= 0x01;
1149 }
1150 if (strstr(mount_opts, "ro")) {
1151 found_ro_fs += 1;
1152 if (!strncmp(mount_dir, "/param", 6)) {
1153 param_status |= 0x02;
1154 } else if (!strncmp(mount_dir, "/atv", 4)) {
1155 atv_status |= 0x02;
1156 } else if (!strncmp(mount_dir, "/dtv", 4)) {
1157 dtv_status |= 0x02;
1158 } else if (!strncmp(mount_dir, "/data", 5)) {
1159 data_status |= 0x02;
1160 } else if (!strncmp(mount_dir, "/cache", 6)) {
1161 cache_status |= 0x02;
1162 }
1163 }
1164 }
1165 } while (match != EOF);
1166
1167 fclose(f);
1168
1169 switch (param_status) {
1170 case 0x03:
1171 LOGW("%s, param partition is read-only!", CFG_SECTION_TV);
1172 break;
1173 case 0x00:
1174 LOGW("%s, param partition can not be mounted!", CFG_SECTION_TV);
1175 break;
1176 default:
1177 break;
1178 }
1179 switch (atv_status) {
1180 case 0x03:
1181 LOGW("%s, atv partition is read-only!", CFG_SECTION_TV);
1182 cool_reboot = 1;
1183 //android_reboot(ANDROID_RB_RESTART2, 0, "cool_reboot");
1184 break;
1185 case 0x00:
1186 LOGW("%s, atv partition can not be mounted!", CFG_SECTION_TV);
1187 recovery_reboot = 1;
1188 //android_reboot(ANDROID_RB_RESTART2, 0, "recovery");
1189 default:
1190 break;
1191 }
1192 switch (dtv_status) {
1193 case 0x03:
1194 LOGW("%s, dtv partition is read-only!", CFG_SECTION_TV);
1195 //android_reboot(ANDROID_RB_RESTART2, 0, "cool_reboot");
1196 break;
1197 case 0x00:
1198 LOGW("%s, dtv partition can not be mounted!", CFG_SECTION_TV);
1199 //android_reboot(ANDROID_RB_RESTART2, 0, "recovery");
1200 default:
1201 break;
1202 }
1203 switch (data_status) {
1204 case 0x03:
1205 LOGW("%s, data partition is read-only!", CFG_SECTION_TV);
1206 cool_reboot = 1;
1207 //android_reboot(ANDROID_RB_RESTART2, 0, "cool_reboot");
1208 break;
1209 case 0x00:
1210 LOGW("%s, data partition can not be mounted!", CFG_SECTION_TV);
1211 recovery_reboot = 1;
1212 //android_reboot(ANDROID_RB_RESTART2, 0, "recovery");
1213 break;
1214 default:
1215 break;
1216 }
1217 switch (cache_status) {
1218 case 0x03:
1219 LOGW("%s, cache partition is read-only!", CFG_SECTION_TV);
1220 cool_reboot = 1;
1221 //android_reboot(ANDROID_RB_RESTART2, 0, "cool_reboot");
1222 break;
1223 case 0x00:
1224 LOGW("%s, cache partition can not be mounted!", CFG_SECTION_TV);
1225 recovery_reboot = 1;
1226 //android_reboot(ANDROID_RB_RESTART2, 0, "recovery");
1227 break;
1228 default:
1229 break;
1230 }
1231 if (cool_reboot == 1) {
1232 android_reboot(ANDROID_RB_RESTART2, 0, "cool_reboot");
1233 }
1234 if (recovery_reboot == 1) {
1235 android_reboot(ANDROID_RB_RESTART2, 0, "recovery");
1236 }
1237 return found_ro_fs;
1238}
1239
1240
1241int Tv_Utils_SetFileAttrStr(const char *file_path, char val_str_buf[])
1242{
1243 FILE *tmpfp = NULL;
1244
1245 tmpfp = fopen(file_path, "w");
1246 if (tmpfp == NULL) {
1247 LOGE("%s, write open file %s error(%s)!!!\n", CFG_SECTION_TV, file_path, strerror(errno));
1248 return -1;
1249 }
1250
1251 fputs(val_str_buf, tmpfp);
1252
1253 fclose(tmpfp);
1254 tmpfp = NULL;
1255
1256 return 0;
1257}
1258
1259int Tv_Utils_GetFileAttrStr(const char *file_path, int buf_size, char val_str_buf[])
1260{
1261 FILE *tmpfp = NULL;
1262
1263 tmpfp = fopen(file_path, "r");
1264 if (tmpfp == NULL) {
1265 LOGE("%s, read open file %s error(%s)!!!\n", CFG_SECTION_TV, file_path, strerror(errno));
1266 val_str_buf[0] = '\0';
1267 return -1;
1268 }
1269
1270 fgets(val_str_buf, buf_size, tmpfp);
1271
1272 fclose(tmpfp);
1273 tmpfp = NULL;
1274
1275 return 0;
1276}
1277
1278//check file exist or not
1279bool Tv_Utils_IsFileExist(const char *file_name)
1280{
1281 struct stat tmp_st;
1282
1283 return stat(file_name, &tmp_st) == 0;
1284}
1285
1286#define CC_EDID_SIZE (256)
1287#define CS_VGA_EDID_BUF_DATA_CFG_NAME "ssm.vga.edidbuf.data"
1288/*
1289static unsigned char customer_edid_buf[CC_EDID_SIZE + 4];
1290
1291static unsigned char mDefHDMIEdidBuf[CC_EDID_SIZE] = {
1292 //256 bytes
1293 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x4d, 0x79, 0x02, 0x2c, 0x01, 0x01, 0x01, 0x01, //0x00~0x0F
1294 0x01, 0x15, 0x01, 0x03, 0x80, 0x85, 0x4b, 0x78, 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27, //0x10~0x1F
1295 0x12, 0x48, 0x4c, 0x21, 0x08, 0x00, 0x81, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, //0x20~0x2F
1296 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c, //0x30~0x3F
1297 0x45, 0x00, 0x30, 0xeb, 0x52, 0x00, 0x00, 0x1e, 0x01, 0x1d, 0x00, 0x72, 0x51, 0xd0, 0x1e, 0x20, //0x40~0x4F
1298 0x6e, 0x28, 0x55, 0x00, 0x30, 0xeb, 0x52, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x53, //0x50~0x5F
1299 0x6b, 0x79, 0x77, 0x6f, 0x72, 0x74, 0x68, 0x20, 0x54, 0x56, 0x0a, 0x20, 0x00, 0x00, 0x00, 0xfd, //0x60~0x6F
1300 0x00, 0x30, 0x3e, 0x0e, 0x46, 0x0f, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x3e, //0x70~0x7F
1301 0x02, 0x03, 0x38, 0xf0, 0x53, 0x1f, 0x10, 0x14, 0x05, 0x13, 0x04, 0x20, 0x22, 0x3c, 0x3e, 0x12, //0x80~0x8F
1302 0x16, 0x03, 0x07, 0x11, 0x15, 0x02, 0x06, 0x01, 0x23, 0x09, 0x07, 0x01, 0x83, 0x01, 0x00, 0x00, //0x90~0x9F
1303 0x78, 0x03, 0x0c, 0x00, 0x10, 0x00, 0x88, 0x3c, 0x2f, 0xd0, 0x8a, 0x01, 0x02, 0x03, 0x04, 0x01, //0xA0~0xAF
1304 0x40, 0x00, 0x7f, 0x20, 0x30, 0x70, 0x80, 0x90, 0x76, 0xe2, 0x00, 0xfb, 0x02, 0x3a, 0x80, 0xd0, //0xB0~0xBF
1305 0x72, 0x38, 0x2d, 0x40, 0x10, 0x2c, 0x45, 0x80, 0x30, 0xeb, 0x52, 0x00, 0x00, 0x1e, 0x01, 0x1d, //0xC0~0xCF
1306 0x00, 0xbc, 0x52, 0xd0, 0x1e, 0x20, 0xb8, 0x28, 0x55, 0x40, 0x30, 0xeb, 0x52, 0x00, 0x00, 0x1e, //0xD0~0xDF
1307 0x01, 0x1d, 0x80, 0xd0, 0x72, 0x1c, 0x16, 0x20, 0x10, 0x2c, 0x25, 0x80, 0x30, 0xeb, 0x52, 0x00, //0xE0~0xEF
1308 0x00, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, //0xF0~0xFF
1309};
1310*/
1311static unsigned char mVGAEdidDataBuf[CC_EDID_SIZE];
1312void monitor_info_set_date ( unsigned char *edidbuf )
1313{
1314 char prop_value[PROPERTY_VALUE_MAX];
1315 char tmp[4];
1316 struct tm *p;
1317 int week = 0;
1318
1319 memset ( prop_value, '\0', PROPERTY_VALUE_MAX );
1320
1321 property_get ( "ro.build.date.utc", prop_value, "VERSION_ERROR" );
1322
1323 time_t timep = atoi ( prop_value );
1324
1325 p = localtime ( &timep );
1326
1327 mktime ( p );
1328
1329 strftime ( prop_value, PROPERTY_VALUE_MAX, "%W.", p );
1330
1331 week = atoi ( prop_value );
1332
1333 edidbuf[16] = week;
1334 edidbuf[17] = ( 1900 + p->tm_year ) - 1990;
1335
1336 LOGD ( "###############%s##############", CFG_SECTION_TV );
1337 LOGD ( "Week number is %d", week );
1338 LOGD ( "%d %02d %02d", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday );
1339 LOGD ( "###############%s##############", CFG_SECTION_TV );
1340}
1341
1342
1343void monitor_info_set_imagesize ( unsigned char *edidbuf )
1344{
1345 //panel size info for edid:
1346 //39' : max_horizontal = 86; max_vertical = 48;
1347 //42' : max_horizontal = 93; max_vertical = 52;
1348 //47' : max_horizontal = 104; max_vertical = 60;
1349 //50' : max_horizontal = 110; max_vertical = 62;
1350 //55' : max_horizontal = 121; max_vertical = 71;
1351 int max_horizontal = 104; //47'
1352 int max_vertical = 60; //47'
1353
1354 edidbuf[21] = max_horizontal;
1355 edidbuf[22] = max_vertical;
1356
1357 LOGD ( "imagesize max_horizontal %d max_vertical %d", max_horizontal, max_vertical );
1358}
1359
1360
1361
1362void monitor_info_name_init ( unsigned char *edidbuf )
1363{
1364 int i = 0;
1365
1366 for ( i = 90; i < 108; i++ ) {
1367 edidbuf[i] = 0;
1368 }
1369
1370 edidbuf[93] = 252;
1371}
1372
1373void monitor_info_set_name ( unsigned char *edidbuf )
1374{
1375 int i = 0;
1376 int config_value_len;
1377 const char *config_value;
1378 unsigned char str_manufacturer_name[14];
1379 config_value = config_get_str ( CFG_SECTION_TV, "tvin.hdmiedid.name", "null" );
1380
1381 if ( strcmp ( config_value, "null" ) != 0 ) {
1382 config_value_len = strlen ( config_value );
1383
1384 if ( config_value_len < 13 ) {
1385 for ( i = 0; i < config_value_len; ++i ) {
1386 str_manufacturer_name[i] = config_value[i];
1387 }
1388
1389 for ( i = config_value_len; i < 13; ++i ) {
1390 str_manufacturer_name[i] = ' ';
1391 }
1392 } else {
1393 for ( i = 0; i < 13; ++i ) {
1394 str_manufacturer_name[i] = config_value[i];
1395 }
1396 }
1397
1398 }
1399
1400 for ( i = 0; i < 13; i++ ) {
1401 edidbuf[95 + i] = str_manufacturer_name[i];
1402 }
1403}
1404
1405void monitor_info_edid_checksum ( unsigned char *edidbuf )
1406{
1407 int sum = 0, i = 0;
1408
1409 for ( i = 0; i < 127; i++ ) {
1410 sum += edidbuf[i];
1411 }
1412
1413 sum = ( 256 - ( sum % 256 ) ) % 256;
1414 edidbuf[127] = sum;
1415
1416 LOGD ( "checksum is 0x%x,so testBuf[127] = 0x%x", sum, edidbuf[127] );
1417}
1418
1419int reboot_sys_by_fbc_edid_info()
1420{
1421 int ret = -1;
1422 int fd = -1;
1423 int edid_info_len = 256;
1424 unsigned char fbc_edid_info[edid_info_len];
1425 int env_different_as_cur = 0;
1426 char outputmode_prop_value[256];
1427 char lcd_reverse_prop_value[256];
1428
1429 LOGD("get edid info from fbc!");
1430 memset(outputmode_prop_value, '\0', 256);
1431 memset(lcd_reverse_prop_value, '\0', 256);
1432 property_get("ubootenv.var.outputmode", outputmode_prop_value, "null" );
1433 property_get("ubootenv.var.lcd_reverse", lcd_reverse_prop_value, "null" );
1434
1435 fd = open("/sys/class/amhdmitx/amhdmitx0/edid_info", O_RDWR);
1436 if (fd < 0) {
1437 LOGW("open edid node error\n");
1438 return -1;
1439 }
1440 ret = read(fd, fbc_edid_info, edid_info_len);
1441 if (ret < 0) {
1442 LOGW("read edid node error\n");
1443 return -1;
1444 }
1445
1446 if ((0xfb == fbc_edid_info[250]) && (0x0c == fbc_edid_info[251])) {
1447 LOGD("RX is FBC!");
1448 // set outputmode env
1449 ret = 0;//is Fbc
1450 switch (fbc_edid_info[252] & 0x0f) {
1451 case 0x0:
1452 if (0 != strcmp(outputmode_prop_value, "1080p") &&
1453 0 != strcmp(outputmode_prop_value, "1080p50hz")
1454 ) {
1455 if (0 == env_different_as_cur) {
1456 env_different_as_cur = 1;
1457 }
1458 property_set("ubootenv.var.outputmode", "1080p");
1459 }
1460 break;
1461 case 0x1:
1462 if (0 != strcmp(outputmode_prop_value, "4k2k60hz420") &&
1463 0 != strcmp(outputmode_prop_value, "4k2k50hz420")
1464 ) {
1465 if (0 == env_different_as_cur) {
1466 env_different_as_cur = 1;
1467 }
1468 property_set("ubootenv.var.outputmode", "4k2k60hz420");
1469 }
1470 break;
1471 case 0x2:
1472 if (0 != strcmp(outputmode_prop_value, "1366*768")) {
1473 if (0 == env_different_as_cur) {
1474 env_different_as_cur = 1;
1475 }
1476 property_set("ubootenv.var.outputmode", "1366*768");
1477 }
1478 break;
1479 default:
1480 break;
1481 }
1482
1483 // set RX 3D Info
1484 //switch((fbc_edid_info[252]>>4)&0x0f)
1485
1486 // set lcd_reverse env
1487 switch (fbc_edid_info[253]) {
1488 case 0x0:
1489 if (0 != strcmp(lcd_reverse_prop_value, "0")) {
1490 if (0 == env_different_as_cur) {
1491 env_different_as_cur = 1;
1492 }
1493 property_set("ubootenv.var.lcd_reverse", "0");
1494 }
1495 break;
1496 case 0x1:
1497 if (0 != strcmp(lcd_reverse_prop_value, "1")) {
1498 if (0 == env_different_as_cur) {
1499 env_different_as_cur = 1;
1500 }
1501 property_set("ubootenv.var.lcd_reverse", "1");
1502 }
1503 break;
1504 default:
1505 break;
1506 }
1507 }
1508 close(fd);
1509 fd = -1;
1510 //ret = -1;
1511 if (1 == env_different_as_cur) {
1512 LOGW("env change , reboot system\n");
1513 system("reboot");
1514 }
1515 return ret;
1516}
1517
1518int reboot_sys_by_fbc_uart_panel_info(CFbcCommunication *fbc)
1519{
1520 int ret = -1;
1521 char outputmode_prop_value[256];
1522 char lcd_reverse_prop_value[256];
1523 int env_different_as_cur = 0;
1524 int panel_reverse = -1;
1525 int panel_outputmode = -1;
1526
1527
1528 char panel_model[64] = {0};
1529
1530 if (fbc == NULL) {
1531 LOGE("there is no fbc!!!\n");
1532 return -1;
1533 }
1534
1535 fbc->cfbc_Get_FBC_Get_PANel_INFO(COMM_DEV_SERIAL, panel_model);
1536 if (0 == panel_model[0]) {
1537 LOGD("device is not fbc\n");
1538 return -1;
1539 }
1540 LOGD("device is fbc, get panel info from fbc!\n");
1541 memset(outputmode_prop_value, '\0', 256);
1542 memset(lcd_reverse_prop_value, '\0', 256);
1543 property_get("ubootenv.var.outputmode", outputmode_prop_value, "null" );
1544 property_get("ubootenv.var.lcd_reverse", lcd_reverse_prop_value, "null" );
1545
1546 fbc->cfbc_Get_FBC_PANEL_REVERSE(COMM_DEV_SERIAL, &panel_reverse);
1547 fbc->cfbc_Get_FBC_PANEL_OUTPUT(COMM_DEV_SERIAL, &panel_outputmode);
1548 LOGD("panel_reverse = %d, panel_outputmode = %d\n", panel_reverse, panel_outputmode);
1549 LOGD("panel_output prop = %s, panel reverse prop = %s\n", outputmode_prop_value, lcd_reverse_prop_value);
1550 switch (panel_outputmode) {
1551 case 0x0:
1552 if (0 != strcmp(outputmode_prop_value, "1080p") &&
1553 0 != strcmp(outputmode_prop_value, "1080p50hz")
1554 ) {
1555 LOGD("panel_output changed to 1080p\n");
1556 if (0 == env_different_as_cur) {
1557 env_different_as_cur = 1;
1558 }
1559 property_set("ubootenv.var.outputmode", "1080p");
1560 }
1561 break;
1562 case 0x1:
1563 if (0 != strcmp(outputmode_prop_value, "4k2k60hz420") &&
1564 0 != strcmp(outputmode_prop_value, "4k2k50hz420")
1565 ) {
1566 if (0 == env_different_as_cur) {
1567 env_different_as_cur = 1;
1568 }
1569 property_set("ubootenv.var.outputmode", "4k2k60hz420");
1570 }
1571 break;
1572 case 0x2:
1573 if (0 != strcmp(outputmode_prop_value, "1366*768")) {
1574 if (0 == env_different_as_cur) {
1575 env_different_as_cur = 1;
1576 }
1577 property_set("ubootenv.var.outputmode", "1366*768");
1578 }
1579 break;
1580 default:
1581 break;
1582 }
1583
1584 // set RX 3D Info
1585 //switch((fbc_edid_info[252]>>4)&0x0f)
1586
1587 // set lcd_reverse env
1588 switch (panel_reverse) {
1589 case 0x0:
1590 if (0 != strcmp(lcd_reverse_prop_value, "0")) {
1591 LOGD("panel_reverse changed to 0\n");
1592 if (0 == env_different_as_cur) {
1593 env_different_as_cur = 1;
1594 }
1595 property_set("ubootenv.var.lcd_reverse", "0");
1596 }
1597 break;
1598 case 0x1:
1599 if (0 != strcmp(lcd_reverse_prop_value, "1")) {
1600 if (0 == env_different_as_cur) {
1601 env_different_as_cur = 1;
1602 }
1603 property_set("ubootenv.var.lcd_reverse", "1");
1604 }
1605 break;
1606 default:
1607 break;
1608 }
1609
1610 ret = -1;
1611 if (1 == env_different_as_cur) {
1612 LOGW("env change , reboot system\n");
1613 system("reboot");
1614 }
1615 return 0;
1616}
1617
1618static pid_t pidof(const char *name)
1619{
1620 DIR *dir;
1621 struct dirent *ent;
1622 char *endptr;
1623 char tmp_buf[512];
1624
1625 if (!(dir = opendir("/proc"))) {
1626 LOGE("%s, can't open /proc", __FUNCTION__, strerror(errno));
1627 return -1;
1628 }
1629
1630 while ((ent = readdir(dir)) != NULL) {
1631 /* if endptr is not a null character, the directory is not
1632 * entirely numeric, so ignore it */
1633 long lpid = strtol(ent->d_name, &endptr, 10);
1634 if (*endptr != '\0') {
1635 continue;
1636 }
1637
1638 /* try to open the cmdline file */
1639 snprintf(tmp_buf, sizeof(tmp_buf), "/proc/%ld/cmdline", lpid);
1640 FILE *fp = fopen(tmp_buf, "r");
1641
1642 if (fp) {
1643 if (fgets(tmp_buf, sizeof(tmp_buf), fp) != NULL) {
1644 /* check the first token in the file, the program name */
1645 char *first = strtok(tmp_buf, " ");
1646 if (!strcmp(first, name)) {
1647 fclose(fp);
1648 closedir(dir);
1649 return (pid_t) lpid;
1650 }
1651 }
1652 fclose(fp);
1653 }
1654 }
1655
1656 closedir(dir);
1657 return -1;
1658}
1659
1660
1661
1662int GetPlatformHaveDDFlag()
1663{
1664 const char *config_value;
1665
1666 config_value = config_get_str(CFG_SECTION_TV, "platform.havedd", "null");
1667 if (strcmp(config_value, "true") == 0 || strcmp(config_value, "1") == 0) {
1668 return 1;
1669 }
1670
1671 return 0;
1672}
1673
1674int GetPlatformProjectInfoSrc()
1675{
1676 const char *config_value;
1677
1678 config_value = config_get_str(CFG_SECTION_TV, "platform.projectinfo.src", "null");
1679 if (strcmp(config_value, "null") == 0 || strcmp(config_value, "prop") == 0) {
1680 return 0;
1681 } else if (strcmp(config_value, "emmckey") == 0) {
1682 return 1;
1683 } else if (strcmp(config_value, "fbc_ver") == 0) {
1684 return 2;
1685 }
1686
1687 return 0;
1688}
1689
1690static unsigned int mCrc32Table[256];
1691
1692static void initCrc32Table()
1693{
1694 int i, j;
1695 unsigned int Crc;
1696 for (i = 0; i < 256; i++) {
1697 Crc = i;
1698 for (j = 0; j < 8; j++) {
1699 if (Crc & 1)
1700 Crc = (Crc >> 1) ^ 0xEDB88320;
1701 else
1702 Crc >>= 1;
1703 }
1704 mCrc32Table[i] = Crc;
1705 }
1706}
1707
1708unsigned int CalCRC32(unsigned int crc, const unsigned char *ptr, unsigned int buf_len)
1709{
1710 static const unsigned int s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
1711 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
1712 };
1713 unsigned int crcu32 = crc;
1714 if (buf_len < 0)
1715 return 0;
1716 if (!ptr) return 0;
1717 crcu32 = ~crcu32;
1718 while (buf_len--) {
1719 unsigned char b = *ptr++;
1720 crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)];
1721 crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)];
1722 }
1723 return ~crcu32;
1724}
1725
1726#define CC_HEAD_CHKSUM_LEN (9)
1727#define CC_VERSION_LEN (5)
1728
1729static int check_projectinfo_data_valid(char *data_str, int chksum_head_len, int ver_len)
1730{
1731 int tmp_len = 0, tmp_ver = 0;
1732 char *endp = NULL;
1733 unsigned long src_chksum = 0, cal_chksum = 0;
1734 char tmp_buf[129] = { 0 };
1735
1736 if (data_str != NULL) {
1737 tmp_len = strlen(data_str);
1738 if (tmp_len > chksum_head_len + ver_len) {
1739 cal_chksum = CalCRC32(0, (unsigned char *)(data_str + chksum_head_len), tmp_len - chksum_head_len);
1740 memcpy(tmp_buf, data_str, chksum_head_len);
1741 tmp_buf[chksum_head_len] = 0;
1742 src_chksum = strtoul(tmp_buf, &endp, 16);
1743 if (cal_chksum == src_chksum) {
1744 memcpy(tmp_buf, data_str + chksum_head_len, ver_len);
1745 if ((tmp_buf[0] == 'v' || tmp_buf[0] == 'V') && isxdigit(tmp_buf[1]) && isxdigit(tmp_buf[2]) && isxdigit(tmp_buf[3])) {
1746 tmp_ver = strtoul(tmp_buf + 1, &endp, 16);
1747 if (tmp_ver <= 0) {
1748 LOGD("%s, project_info data version error!!!\n", __FUNCTION__);
1749 return -1;
1750 }
1751 } else {
1752 LOGD("%s, project_info data version error!!!\n", __FUNCTION__);
1753 return -1;
1754 }
1755
1756 return tmp_ver;
1757 } else {
1758 LOGD("%s, cal_chksum = %x\n", __FUNCTION__, (unsigned int)cal_chksum);
1759 LOGD("%s, src_chksum = %x\n", __FUNCTION__, (unsigned int)src_chksum);
1760 }
1761 }
1762
1763 LOGD("%s, project_info data error!!!\n", __FUNCTION__);
1764 return -1;
1765 }
1766
1767 LOGD("%s, project_info data is NULL!!!\n", __FUNCTION__);
1768 return -1;
1769}
1770
1771static int gFBCPrjInfoRDPass = 0;
1772static char gFBCPrjInfoBuf[1024] = {0};
1773
1774static int GetProjectInfoOriData(char data_str[], CFbcCommunication *fbcIns)
1775{
1776 int tmp_val = 0;
1777 int src_type = GetPlatformProjectInfoSrc();
1778
1779 if (src_type == 0) {
1780 memset(data_str, '\0', sizeof(data_str));
1781 getBootEnv("ubootenv.var.project_info", data_str, "null");
1782 if (strcmp(data_str, "null") == 0) {
1783 LOGE("%s, get project info data error!!!\n", __FUNCTION__);
1784 return -1;
1785 }
1786
1787 return 0;
1788 } else if (src_type == 1) {
1789 return -1;
1790 } else if (src_type == 2) {
1791 int i = 0, tmp_len = 0, tmp_val = 0, item_cnt = 0;
1792 int tmp_rd_fail_flag = 0;
1793 unsigned int cal_chksum = 0;
1794 char sw_version[64];
1795 char build_time[64];
1796 char git_version[64];
1797 char git_branch[64];
1798 char build_name[64];
1799 char tmp_buf[512] = {0};
1800
1801 if (fbcIns != NULL) {
1802 if (gFBCPrjInfoRDPass == 0) {
1803 memset((void *)gFBCPrjInfoBuf, 0, sizeof(gFBCPrjInfoBuf));
1804 }
1805
1806 if (gFBCPrjInfoRDPass == 1) {
1807 strcpy(data_str, gFBCPrjInfoBuf);
1808 LOGD("%s, rd once just return, data_str = %s\n", __FUNCTION__, data_str);
1809 return 0;
1810 }
1811
1812 if (fbcIns->cfbc_Get_FBC_MAINCODE_Version(COMM_DEV_SERIAL, sw_version, build_time, git_version, git_branch, build_name) == 0) {
1813 if (sw_version[0] == '1' || sw_version[0] == '2') {
1814 strcpy(build_name, "2");
1815
1816 strcpy(tmp_buf, "v001,fbc_");
1817 strcat(tmp_buf, build_name);
1818 strcat(tmp_buf, ",4k2k60hz420,no_rev,");
1819 strcat(tmp_buf, "HV550QU2-305");
1820 strcat(tmp_buf, ",8o8w,0,0");
1821 cal_chksum = CalCRC32(0, (unsigned char *)tmp_buf, strlen(tmp_buf));
1822 sprintf(data_str, "%08x,%s", cal_chksum, tmp_buf);
1823 LOGD("%s, data_str = %s\n", __FUNCTION__, data_str);
1824 } else {
1825 tmp_val = 0;
1826 if (fbcIns->cfbc_Get_FBC_project_id(COMM_DEV_SERIAL, &tmp_val) == 0) {
1827 sprintf(build_name, "fbc_%d", tmp_val);
1828 } else {
1829 tmp_rd_fail_flag = 1;
1830 strcpy(build_name, "fbc_0");
1831 LOGD("%s, get project id from fbc error!!!\n", __FUNCTION__);
1832 }
1833
1834 strcpy(tmp_buf, "v001,");
1835 strcat(tmp_buf, build_name);
1836 strcat(tmp_buf, ",4k2k60hz420,no_rev,");
1837
1838 memset(git_branch, 0, sizeof(git_branch));
1839 if (fbcIns->cfbc_Get_FBC_Get_PANel_INFO(COMM_DEV_SERIAL, git_branch) == 0) {
1840 strcat(tmp_buf, git_branch);
1841 } else {
1842 tmp_rd_fail_flag = 1;
1843 strcat(tmp_buf, build_name);
1844 LOGD("%s, get panel info from fbc error!!!\n", __FUNCTION__);
1845 }
1846
1847 strcat(tmp_buf, ",8o8w,0,0");
1848 cal_chksum = CalCRC32(0, (unsigned char *)tmp_buf, strlen(tmp_buf));
1849 sprintf(data_str, "%08x,%s", cal_chksum, tmp_buf);
1850 LOGD("%s, data_str = %s\n", __FUNCTION__, data_str);
1851
1852 if (tmp_rd_fail_flag == 0) {
1853 gFBCPrjInfoRDPass = 1;
1854 strcpy(gFBCPrjInfoBuf, data_str);
1855 }
1856 }
1857
1858 return 0;
1859 }
1860
1861 return -1;
1862 }
1863 }
1864
1865 return -1;
1866}
1867
1868static int handle_prj_info_by_ver(int ver, int item_ind, char *item_str, project_info_t *proj_info_ptr)
1869{
1870 if (ver == 1) {
1871 if (item_ind == 0) {
1872 strncpy(proj_info_ptr->version, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1);
1873 } else if (item_ind == 1) {
1874 strncpy(proj_info_ptr->panel_type, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1);
1875 } else if (item_ind == 2) {
1876 strncpy(proj_info_ptr->panel_outputmode, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1);
1877 } else if (item_ind == 3) {
1878 strncpy(proj_info_ptr->panel_rev, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1);
1879 } else if (item_ind == 4) {
1880 strncpy(proj_info_ptr->panel_name, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1);
1881 } else if (item_ind == 5) {
1882 strncpy(proj_info_ptr->amp_curve_name, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1);
1883 }
1884 } else {
1885 if (item_ind == 0) {
1886 strncpy(proj_info_ptr->version, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1);
1887 } else if (item_ind == 1) {
1888 strncpy(proj_info_ptr->panel_type, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1);
1889 } else if (item_ind == 2) {
1890 strncpy(proj_info_ptr->panel_name, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1);
1891 } else if (item_ind == 3) {
1892 strncpy(proj_info_ptr->panel_outputmode, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1);
1893 } else if (item_ind == 4) {
1894 strncpy(proj_info_ptr->panel_rev, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1);
1895 } else if (item_ind == 5) {
1896 strncpy(proj_info_ptr->amp_curve_name, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1);
1897 }
1898 }
1899
1900 return 0;
1901}
1902
1903int GetProjectInfo(project_info_t *proj_info_ptr, CFbcCommunication *fbcIns)
1904{
1905 int i = 0, tmp_ret = 0, tmp_val = 0, tmp_len = 0;
1906 int item_cnt = 0, handle_prj_info_data_flag = 0;
1907 char *token = NULL;
1908 const char *strDelimit = ",";
1909 char tmp_buf[1024] = { 0 };
1910 char data_str[1024] = { 0 };
1911
1912 if (GetProjectInfoOriData(data_str, fbcIns) < 0) {
1913 return -1;
1914 }
1915
1916 memset((void *)proj_info_ptr->version, 0, CC_PROJECT_INFO_ITEM_MAX_LEN);
1917 memset((void *)proj_info_ptr->panel_type, 0, CC_PROJECT_INFO_ITEM_MAX_LEN);
1918 memset((void *)proj_info_ptr->panel_outputmode, 0, CC_PROJECT_INFO_ITEM_MAX_LEN);
1919 memset((void *)proj_info_ptr->panel_rev, 0, CC_PROJECT_INFO_ITEM_MAX_LEN);
1920 memset((void *)proj_info_ptr->panel_name, 0, CC_PROJECT_INFO_ITEM_MAX_LEN);
1921 memset((void *)proj_info_ptr->amp_curve_name, 0, CC_PROJECT_INFO_ITEM_MAX_LEN);
1922
1923 //check project info data is valid
1924 handle_prj_info_data_flag = check_projectinfo_data_valid(data_str, CC_HEAD_CHKSUM_LEN, CC_VERSION_LEN);
1925
1926 //handle project info data
1927 if (handle_prj_info_data_flag > 0) {
1928 item_cnt = 0;
1929 memset((void *)tmp_buf, 0, sizeof(tmp_buf));
1930 strncpy(tmp_buf, data_str + CC_HEAD_CHKSUM_LEN, sizeof(tmp_buf) - 1);
1931 token = strtok(tmp_buf, strDelimit);
1932 while (token != NULL) {
1933 handle_prj_info_by_ver(handle_prj_info_data_flag, item_cnt, token, proj_info_ptr);
1934
1935 token = strtok(NULL, strDelimit);
1936 item_cnt += 1;
1937 }
1938
1939 return 0;
1940 }
1941
1942 return -1;
1943}
1944
1945#if ANDROID_PLATFORM_SDK_VERSION == 19
1946int getBootEnv(const char *key, char *value, char *def_val)
1947{
1948 return property_get(key, value, def_val);
1949}
1950
1951void setBootEnv(const char *key, const char *value)
1952{
1953 return property_set(key, value);
1954}
1955#endif
1956
1957#if ANDROID_PLATFORM_SDK_VERSION >= 21
1958
1959#include <binder/IServiceManager.h>
1960#include <utils/threads.h>
1961#include <systemcontrol/ISystemControlService.h>
1962
1963class DeathNotifier: public IBinder::DeathRecipient {
1964public:
1965 DeathNotifier()
1966 {
1967 }
1968
1969 void binderDied(const wp<IBinder> &who)
1970 {
1971 ALOGW("system_control died!");
1972 }
1973};
1974
1975static sp<ISystemControlService> amSystemControlService;
1976static sp<DeathNotifier> amDeathNotifier;
1977static Mutex amLock;
1978
1979static const sp<ISystemControlService> &getSystemControlService()
1980{
1981 Mutex::Autolock _l(amLock);
1982 if (amSystemControlService.get() == 0) {
1983 sp<IServiceManager> sm = defaultServiceManager();
1984
1985 sp<IBinder> binder;
1986 do {
1987 binder = sm->getService(String16("system_control"));
1988 if (binder != 0)
1989 break;
1990 ALOGW("SystemControlService not published, waiting...");
1991 usleep(500000); // 0.5 s
1992 } while(true);
1993 if (amDeathNotifier == NULL) {
1994 amDeathNotifier = new DeathNotifier();
1995 }
1996 binder->linkToDeath(amDeathNotifier);
1997 amSystemControlService = interface_cast<ISystemControlService>(binder);
1998 }
1999 ALOGE_IF(amSystemControlService == 0, "no System Control Service!?");
2000
2001 return amSystemControlService;
2002}
2003
2004int getBootEnv(const char *key, char *value, char *def_val)
2005{
2006 const sp<ISystemControlService> &sws = getSystemControlService();
2007 if (sws != 0) {
2008 String16 v;
2009 if (sws->getBootEnv(String16(key), v)) {
2010 strcpy(value, String8(v).string());
2011 return 0;
2012 }
2013 }
2014
2015 strcpy(value, def_val);
2016 return -1;
2017}
2018
2019void setBootEnv(const char *key, const char *value)
2020{
2021 const sp<ISystemControlService> &sws = getSystemControlService();
2022 if (sws != 0) {
2023 sws->setBootEnv(String16(key), String16(value));
2024 }
2025}
2026#endif
2027