blob: 5a7563f73994d9c3d7ec1418dfe1cd5328afae5a
1 | #include <stdio.h> |
2 | #include <stdlib.h> |
3 | #include <string.h> |
4 | #include <unistd.h> |
5 | #include <fcntl.h> |
6 | #include <errno.h> |
7 | #include <sys/stat.h> |
8 | #include <sys/wait.h> |
9 | #include <cutils/properties.h> |
10 | |
11 | #include <netinet/ether.h> |
12 | #include <netinet/if_ether.h> |
13 | |
14 | #include <netutils/ifc.h> |
15 | #include <netutils/dhcp.h> |
16 | |
17 | #include "tvconfig/tvconfig.h" |
18 | #include "CTvSettingCfg.h" |
19 | #include "TvKeyData.h" |
20 | |
21 | #define CC_MAX_KEY_DATA_SIZE (2048) |
22 | #define CC_MAX_FILE_PATH (256) |
23 | |
24 | #define CC_MAC_LEN (6) |
25 | #define CC_HDCP_KEY_TOTAL_SIZE (368) |
26 | #define CC_HDCP_KEY_HEAD_SIZE (40) |
27 | #define CC_HDCP_KEY_CONTENT_SIZE (CC_HDCP_KEY_TOTAL_SIZE - CC_HDCP_KEY_HEAD_SIZE) |
28 | |
29 | #define CC_CUSTOMER_HDMI_EDID_TOTAL_SIZE (SSM_HDMI_EDID_SIZE + 4) |
30 | |
31 | #define CS_MAC_ADDRESS_STARTWRK_EN_CFG "ssm.macaddr.startwork.en" |
32 | #define CS_BARCODE_LEN_CFG "ssm.barcode.len" |
33 | |
34 | #define CS_HDCP_KEY_EN_CFG "ssm.handle.hdcpkey.en" |
35 | #define CS_HDCP_KEY_DEMO_EN_CFG "ssm.handle.hdcpkey.demo.en" |
36 | #define CS_HDCP_KEY_FILE_PATH_CFG "ssm.handle.hdcpkey.file.path" |
37 | #define CS_HDCP_KEY_FILE_OFFSET_CFG "ssm.handle.hdcpkey.file.offset" |
38 | #define CS_HDCP_KEY_HEADER_EN_CFG "ssm.handle.hdcpkey.header.en" |
39 | |
40 | |
41 | #define CS_HDMI_EDID_EN_CFG "ssm.handle.hdmi.edid.en" |
42 | #define CS_HDMI_EDID_USE_CFG "ssm.handle.hdmi.edid.use" |
43 | #define CS_HDMI_EDID_FILE_PATH_CFG "ssm.handle.hdmi.edid.file.path" |
44 | #define CS_HDMI_PORT1_EDID_FILE_PATH_CFG "ssm.handle.hdmi.port1.edid.file.path" |
45 | #define CS_HDMI_PORT2_EDID_FILE_PATH_CFG "ssm.handle.hdmi.port2.edid.file.path" |
46 | #define CS_HDMI_PORT3_EDID_FILE_PATH_CFG "ssm.handle.hdmi.port3.edid.file.path" |
47 | #define CS_HDMI_EDID_FILE_OFFSET_CFG "ssm.handle.hdmi.edid.file.offset" |
48 | |
49 | #define CS_RGBOGO_FILE_PATH_CFG "ssm.rgbogo.file.path" |
50 | #define CS_RGBOGO_FILE_OFFSET_CFG "ssm.rgbogo.file.offset" |
51 | |
52 | #define CS_AUDIO_NOLINEPOINTS_FILE_PATH_CFG "ssm.audio.nolinepoints.file.path" |
53 | #define CS_AUDIO_NOLINEPOINTS_FILE_OFFSET_CFG "ssm.audio.nolinepoints.file.offset" |
54 | |
55 | static unsigned char mHDCPKeyDefHeaderBuf[CC_HDCP_KEY_HEAD_SIZE] = { |
56 | //40 bytes |
57 | 0x53, 0x4B, 0x59, 0x01, 0x00, 0x10, 0x0D, 0x15, 0x3A, 0x8E, // 000~009 |
58 | 0x99, 0xEE, 0x2A, 0x55, 0x58, 0xEE, 0xED, 0x4B, 0xBE, 0x00, // 010~019 |
59 | 0x74, 0xA9, 0x00, 0x10, 0x0A, 0x21, 0xE3, 0x30, 0x66, 0x34, // 020~029 |
60 | 0xCE, 0x9C, 0xC7, 0x8B, 0x51, 0x27, 0xF9, 0x0B, 0xAD, 0x09, // 030~039 |
61 | }; |
62 | |
63 | static unsigned char mDefHDCPKeyContentBuf[CC_HDCP_KEY_CONTENT_SIZE] = { |
64 | //328 bytes |
65 | 0x5F, 0x4D, 0xC2, 0xCA, 0xA2, 0x13, 0x06, 0x18, 0x8D, 0x34, // 000~009 |
66 | 0x82, 0x46, 0x2D, 0xC9, 0x4B, 0xB0, 0x1C, 0xDE, 0x3D, 0x49, // 010~019 |
67 | 0x39, 0x58, 0xEF, 0x2B, 0x68, 0x39, 0x71, 0xC9, 0x4D, 0x25, // 020~029 |
68 | 0xE9, 0x75, 0x4D, 0xAC, 0x62, 0xF5, 0xF5, 0x87, 0xA0, 0xB2, // 030~039 |
69 | 0x4A, 0x60, 0xD3, 0xF1, 0x09, 0x3A, 0xB2, 0x3E, 0x19, 0x4F, // 040~049 |
70 | 0x3B, 0x1B, 0x2F, 0x85, 0x14, 0x28, 0x44, 0xFC, 0x69, 0x6F, // 050~059 |
71 | 0x50, 0x42, 0x81, 0xBF, 0x7C, 0x2B, 0x3A, 0x17, 0x2C, 0x15, // 060~069 |
72 | 0xE4, 0x93, 0x77, 0x74, 0xE8, 0x1F, 0x1C, 0x38, 0x54, 0x49, // 070~079 |
73 | 0x10, 0x64, 0x5B, 0x7D, 0x90, 0x3D, 0xA0, 0xE1, 0x8B, 0x67, // 080~089 |
74 | 0x5C, 0x19, 0xE6, 0xCA, 0x9D, 0xE9, 0x68, 0x5A, 0xB5, 0x62, // 090~099 |
75 | 0xDF, 0xA1, 0x28, 0xBC, 0x68, 0x82, 0x9A, 0x22, 0xC4, 0xDC, // 100~109 |
76 | 0x48, 0x85, 0x0F, 0xF1, 0x3E, 0x05, 0xDD, 0x1B, 0x2D, 0xF5, // 120~119 |
77 | 0x49, 0x3A, 0x15, 0x29, 0xE7, 0xB6, 0x0B, 0x2A, 0x40, 0xE3, // 120~129 |
78 | 0xB0, 0x89, 0xD5, 0x75, 0x84, 0x2E, 0x76, 0xE7, 0xBC, 0x63, // 130~139 |
79 | 0x67, 0xE3, 0x57, 0x67, 0x86, 0x81, 0xF4, 0xD7, 0xEA, 0x4D, // 140~149 |
80 | 0x89, 0x8E, 0x37, 0x95, 0x59, 0x1C, 0x8A, 0xCD, 0x79, 0xF8, // 150~159 |
81 | 0x4F, 0x82, 0xF2, 0x6C, 0x7E, 0x7F, 0x79, 0x8A, 0x6B, 0x90, // 160~169 |
82 | 0xC0, 0xAF, 0x4C, 0x8D, 0x43, 0x47, 0x1F, 0x9A, 0xF1, 0xBB, // 170~179 |
83 | 0x88, 0x64, 0x49, 0x14, 0x50, 0xD1, 0xC3, 0xDF, 0xA6, 0x87, // 180~189 |
84 | 0xA0, 0x15, 0x98, 0x51, 0x81, 0xF5, 0x97, 0x55, 0x10, 0x4A, // 190~199 |
85 | 0x99, 0x30, 0x54, 0xA4, 0xFC, 0xDA, 0x0E, 0xAC, 0x6A, 0xFA, // 200~209 |
86 | 0x90, 0xEE, 0x12, 0x70, 0x69, 0x74, 0x63, 0x46, 0x63, 0xFB, // 210~219 |
87 | 0xE6, 0x1F, 0x72, 0xEC, 0x43, 0x5D, 0x50, 0xFF, 0x03, 0x4F, // 220~229 |
88 | 0x05, 0x33, 0x88, 0x36, 0x93, 0xE4, 0x72, 0xD5, 0xCC, 0x34, // 230~239 |
89 | 0x52, 0x96, 0x15, 0xCE, 0xD0, 0x32, 0x52, 0x41, 0x4F, 0xBC, // 240~249 |
90 | 0x2D, 0xDF, 0xC5, 0xD6, 0x7F, 0xD5, 0x74, 0xCE, 0x51, 0xDC, // 250~259 |
91 | 0x10, 0x5E, 0xF7, 0xAA, 0x4A, 0x2D, 0x20, 0x9A, 0x17, 0xDD, // 260~269 |
92 | 0x30, 0x89, 0x71, 0x82, 0x36, 0x50, 0x09, 0x1F, 0x7C, 0xF3, // 270~279 |
93 | 0x12, 0xE9, 0x43, 0x10, 0x5F, 0x51, 0xBF, 0xB8, 0x45, 0xA8, // 280~289 |
94 | 0x5A, 0x8D, 0x3F, 0x77, 0xE5, 0x96, 0x73, 0x68, 0xAB, 0x73, // 290~299 |
95 | 0xE5, 0x4C, 0xFB, 0xE5, 0x98, 0xB9, 0xAE, 0x74, 0xEB, 0x51, // 300~309 |
96 | 0xDB, 0x91, 0x07, 0x7B, 0x66, 0x02, 0x9B, 0x79, 0x03, 0xC5, // 310~319 |
97 | 0x34, 0x1C, 0x58, 0x13, 0x31, 0xD2, 0x4A, 0xEC, // 320~327 |
98 | }; |
99 | |
100 | static int CreateMacAddressStartWorkThread(); |
101 | |
102 | static int GetSSMHandleHDCPKeyEnableCFG(); |
103 | static int GetSSMHandleHDCPKeyHeaderEnableCFG(); |
104 | static int GetSSMHandleHDCPKeyDemoEnableCFG(); |
105 | static int SSMSetDefaultHDCPKey(unsigned char hdcp_key_buf[]); |
106 | static int RealHandleHDCPKey(unsigned char hdcp_key_buf[]); |
107 | static int GetHDCPKeyFromFile(int rd_off, int rd_size, |
108 | unsigned char data_buf[]); |
109 | static int SaveHDCPKeyToFile(int wr_off, int wr_size, unsigned char data_buf[]); |
110 | |
111 | static int GetHDMIEdidFromFile(int rd_off, int rd_size, int port, |
112 | unsigned char data_buf[]); |
113 | static int RealHandleHDMIEdid(unsigned char hdmi_edid_buf[]); |
114 | static int GetSSMHandleHDMIEdidByCustomerEnableCFG(); |
115 | static int AppendEdidPrefixCode(unsigned char customer_hdmi_edid_buf[], |
116 | unsigned char hdmi_edid_buf[]); |
117 | |
118 | static int GetRGBOGOFromFile(int rd_off, int rd_size, unsigned char data_buf[]); |
119 | static int SaveRGBOGOToFile(int wr_off, int wr_size, unsigned char data_buf[]); |
120 | |
121 | static int GetAudioNoLinePointsDataFromFile(int offset, int size, |
122 | unsigned char data_buf[]); |
123 | static int SaveAudioNoLinePointsDataToFile(int offset, int size, |
124 | unsigned char data_buf[]); |
125 | |
126 | static int TransStringToHex(int data_cnt, char data_buf[], |
127 | unsigned char hex_buf[]) |
128 | { |
129 | int i = 0, j = 0, tmp_val = 0; |
130 | char tmp_buf[3] = { 0, 0, 0 }; |
131 | |
132 | while (i < data_cnt) { |
133 | tmp_val = 0; |
134 | tmp_buf[0] = data_buf[i]; |
135 | tmp_buf[1] = data_buf[i + 1]; |
136 | tmp_val = strtoul(tmp_buf, NULL, 16); |
137 | hex_buf[j] = tmp_val; |
138 | //LOGD("%s, hex_buf[%d] = 0x%x\n", __FUNCTION__, j, hex_buf[j]); |
139 | i += 2; |
140 | j += 1; |
141 | } |
142 | |
143 | return j; |
144 | } |
145 | |
146 | static int TransToHexString(int hex_cnt, char data_buf[], |
147 | unsigned char hex_buf[]) |
148 | { |
149 | int i = 0, j = 0; |
150 | char tmp_buf[17] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; |
151 | |
152 | data_buf[0] = 0; |
153 | for (i = 0; i < hex_cnt; i++) { |
154 | sprintf(tmp_buf, "%02X", (unsigned char) hex_buf[i]); |
155 | strcat(data_buf, tmp_buf); |
156 | } |
157 | |
158 | return 2 * hex_cnt; |
159 | } |
160 | |
161 | int ReadKeyData(const char *key_name, unsigned int rd_data_len, unsigned char data_buf[]) |
162 | { |
163 | FILE *dev_fp = NULL; |
164 | int i = 0, rd_cnt = 0; |
165 | char tmp_ori_buf[CC_MAX_KEY_DATA_SIZE]; |
166 | unsigned char tmp_tran_buf[CC_MAX_KEY_DATA_SIZE]; |
167 | |
168 | dev_fp = fopen(CS_KEY_DATA_NAME_DEV_PATH, "w"); |
169 | if (dev_fp == NULL) { |
170 | LOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__, |
171 | CS_KEY_DATA_NAME_DEV_PATH, strerror(errno)); |
172 | return -1; |
173 | } |
174 | |
175 | fprintf(dev_fp, "%s", key_name); |
176 | |
177 | fclose(dev_fp); |
178 | dev_fp = NULL; |
179 | |
180 | dev_fp = fopen(CS_KEY_DATA_READ_DEV_PATH, "r"); |
181 | if (dev_fp == NULL) { |
182 | LOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__, |
183 | CS_KEY_DATA_READ_DEV_PATH, strerror(errno)); |
184 | return -1; |
185 | } |
186 | |
187 | memset((void *)tmp_ori_buf, 0, CC_MAX_KEY_DATA_SIZE); |
188 | memset((void *)tmp_tran_buf, 0, CC_MAX_KEY_DATA_SIZE); |
189 | fscanf(dev_fp, "%s", tmp_ori_buf); |
190 | |
191 | rd_cnt = strlen(tmp_ori_buf); |
192 | rd_cnt = TransStringToHex(rd_cnt, tmp_ori_buf, tmp_tran_buf); |
193 | |
194 | fclose(dev_fp); |
195 | dev_fp = NULL; |
196 | |
197 | if (rd_cnt != rd_data_len) { |
198 | return 0; |
199 | } |
200 | |
201 | memcpy(data_buf, tmp_tran_buf, rd_cnt); |
202 | return rd_cnt; |
203 | } |
204 | |
205 | int WriteKeyData(const char *key_name, int wr_size, char data_buf[]) |
206 | { |
207 | FILE *dev_fp = NULL; |
208 | int wr_cnt = 0; |
209 | |
210 | dev_fp = fopen(CS_KEY_DATA_NAME_DEV_PATH, "w"); |
211 | if (dev_fp == NULL) { |
212 | LOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__, |
213 | CS_KEY_DATA_NAME_DEV_PATH, strerror(errno)); |
214 | return -1; |
215 | } |
216 | |
217 | fprintf(dev_fp, "%s", key_name); |
218 | |
219 | fclose(dev_fp); |
220 | dev_fp = NULL; |
221 | |
222 | dev_fp = fopen(CS_KEY_DATA_WRITE_DEV_PATH, "w"); |
223 | if (dev_fp == NULL) { |
224 | LOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__, |
225 | CS_KEY_DATA_WRITE_DEV_PATH, strerror(errno)); |
226 | return -1; |
227 | } |
228 | |
229 | wr_cnt = fwrite(data_buf, 1, wr_size, dev_fp); |
230 | |
231 | fclose(dev_fp); |
232 | dev_fp = NULL; |
233 | |
234 | return wr_cnt; |
235 | } |
236 | |
237 | int KeyData_GetMacAddressDataLen() |
238 | { |
239 | return CC_MAC_LEN; |
240 | } |
241 | |
242 | int KeyData_ReadMacAddress(unsigned char data_buf[]) |
243 | { |
244 | int i = 0, rd_size = 0; |
245 | int data_i_buf[CC_MAC_LEN] = { 0, 0, 0, 0, 0, 0 }; |
246 | unsigned char tmp_buf[128] = { 0 }; |
247 | |
248 | rd_size = ReadKeyData(CS_MAC_KEY_NAME, 17, tmp_buf); |
249 | if (rd_size == 17) { |
250 | sscanf((char *) tmp_buf, "%02x:%02x:%02x:%02x:%02x:%02x", |
251 | &data_i_buf[0], &data_i_buf[1], &data_i_buf[2], &data_i_buf[3], |
252 | &data_i_buf[4], &data_i_buf[5]); |
253 | for (i = 0; i < sizeof(data_i_buf); i++) { |
254 | data_buf[i] = data_i_buf[i] & 0xFF; |
255 | } |
256 | } |
257 | |
258 | return KeyData_GetMacAddressDataLen(); |
259 | } |
260 | |
261 | int KeyData_SaveMacAddress(unsigned char data_buf[]) |
262 | { |
263 | int tmp_ret = 0, wr_size = 0; |
264 | unsigned char hex_buf[128] = { 0 }; |
265 | char tmp_buf[128] = { 0 }; |
266 | |
267 | sprintf((char *) hex_buf, "%02x:%02x:%02x:%02x:%02x:%02x", data_buf[0], |
268 | data_buf[1], data_buf[2], data_buf[3], data_buf[4], data_buf[5]); |
269 | |
270 | TransToHexString(strlen((char *) hex_buf), tmp_buf, hex_buf); |
271 | |
272 | wr_size = strlen(tmp_buf); |
273 | tmp_ret = WriteKeyData(CS_MAC_KEY_NAME, wr_size, tmp_buf); |
274 | if (tmp_ret != wr_size) { |
275 | return -1; |
276 | } |
277 | |
278 | CreateMacAddressStartWorkThread(); |
279 | |
280 | return 0; |
281 | } |
282 | |
283 | static int gSSMBarCodeLen = -1; |
284 | int KeyData_GetBarCodeDataLen() |
285 | { |
286 | const char *config_value; |
287 | |
288 | if (gSSMBarCodeLen <= 0) { |
289 | config_value = config_get_str("TV", CS_BARCODE_LEN_CFG, "null"); |
290 | if (strcmp(config_value, "null") == 0) { |
291 | gSSMBarCodeLen = 32; |
292 | } else { |
293 | gSSMBarCodeLen = strtol(config_value, NULL, 10); |
294 | } |
295 | } |
296 | |
297 | return gSSMBarCodeLen; |
298 | } |
299 | |
300 | int KeyData_ReadBarCode(unsigned char data_buf[]) |
301 | { |
302 | int rd_size = 0, tmp_len = 0; |
303 | unsigned char tmp_buf[CC_MAX_KEY_DATA_SIZE] = { 0 }; |
304 | |
305 | tmp_len = KeyData_GetBarCodeDataLen(); |
306 | rd_size = ReadKeyData(CS_BARCODE_KEY_NAME, tmp_len, tmp_buf); |
307 | LOGD("%s, rd_size = %d\n", __FUNCTION__, rd_size); |
308 | if (rd_size == tmp_len) { |
309 | memcpy(data_buf, tmp_buf, tmp_len); |
310 | } |
311 | |
312 | return rd_size; |
313 | } |
314 | |
315 | int KeyData_SaveBarCode(unsigned char data_buf[]) |
316 | { |
317 | int tmp_len = 0, wr_size = 0; |
318 | char tmp_buf[512] = { 0 }; |
319 | |
320 | tmp_len = KeyData_GetBarCodeDataLen(); |
321 | |
322 | TransToHexString(tmp_len, tmp_buf, data_buf); |
323 | |
324 | wr_size = strlen(tmp_buf); |
325 | tmp_len = WriteKeyData(CS_BARCODE_KEY_NAME, wr_size, tmp_buf); |
326 | if (tmp_len != wr_size) { |
327 | return -1; |
328 | } |
329 | |
330 | return 0; |
331 | } |
332 | |
333 | int SSMReadHDCPKey(unsigned char hdcp_key_buf[]) |
334 | { |
335 | int tmp_ret = 0, rd_size = 0; |
336 | unsigned char tmp_buf[CC_HDCP_KEY_TOTAL_SIZE] = { 0 }; |
337 | |
338 | tmp_ret = GetHDCPKeyFromFile(0, CC_HDCP_KEY_TOTAL_SIZE, hdcp_key_buf); |
339 | if (tmp_ret < 0) { |
340 | rd_size = ReadKeyData(CS_RX_HDCP_KEY_NAME, CC_HDCP_KEY_TOTAL_SIZE, tmp_buf); |
341 | LOGD("%s, rd_size = %d\n", __FUNCTION__, rd_size); |
342 | if (rd_size == CC_HDCP_KEY_TOTAL_SIZE) { |
343 | memcpy(hdcp_key_buf, tmp_buf, CC_HDCP_KEY_TOTAL_SIZE); |
344 | } |
345 | |
346 | return rd_size; |
347 | } |
348 | |
349 | return CC_HDCP_KEY_TOTAL_SIZE; |
350 | } |
351 | |
352 | int SSMReadHDCPKeyExcludingHeader(unsigned char hdcp_key_buf[]) |
353 | { |
354 | int tmp_ret = 0, rd_size = 0; |
355 | unsigned char tmp_buf[CC_HDCP_KEY_CONTENT_SIZE] = { 0 }; |
356 | |
357 | tmp_ret = GetHDCPKeyFromFile(0, CC_HDCP_KEY_CONTENT_SIZE, hdcp_key_buf); |
358 | if (tmp_ret < 0) { |
359 | LOGD("%s, GetHDCPKeyFromFile error = %d\n", __FUNCTION__, tmp_ret); |
360 | return tmp_ret; |
361 | } |
362 | |
363 | return CC_HDCP_KEY_CONTENT_SIZE; |
364 | } |
365 | |
366 | |
367 | int SSMSaveHDCPKey(unsigned char hdcp_key_buf[]) |
368 | { |
369 | int tmp_ret = 0, wr_size = 0; |
370 | char tmp_buf[CC_MAX_KEY_DATA_SIZE] = { 0 }; |
371 | |
372 | tmp_ret = SaveHDCPKeyToFile(0, CC_HDCP_KEY_TOTAL_SIZE, hdcp_key_buf); |
373 | if (tmp_ret < 0) { |
374 | TransToHexString(CC_HDCP_KEY_TOTAL_SIZE, tmp_buf, hdcp_key_buf); |
375 | |
376 | wr_size = strlen(tmp_buf); |
377 | tmp_ret = WriteKeyData(CS_RX_HDCP_KEY_NAME, wr_size, tmp_buf); |
378 | if (tmp_ret != wr_size) { |
379 | tmp_ret = -1; |
380 | } |
381 | } |
382 | |
383 | return tmp_ret; |
384 | } |
385 | |
386 | int SSMSetHDCPKey() |
387 | { |
388 | int i = 0; |
389 | unsigned char hdcp_key_buf[CC_HDCP_KEY_TOTAL_SIZE]; |
390 | unsigned char *hdcp_key_head_ptr = NULL; |
391 | |
392 | if (GetSSMHandleHDCPKeyEnableCFG() == 1) { |
393 | if (GetSSMHandleHDCPKeyDemoEnableCFG() == 1) { |
394 | return SSMSetDefaultHDCPKey(hdcp_key_buf); |
395 | } else if (GetSSMHandleHDCPKeyHeaderEnableCFG() == 1) { |
396 | LOGD("%s, handle hdcp key excluding header.\n", __FUNCTION__); |
397 | //copy header |
398 | hdcp_key_head_ptr = mHDCPKeyDefHeaderBuf; |
399 | memcpy(hdcp_key_buf, hdcp_key_head_ptr, CC_HDCP_KEY_HEAD_SIZE); |
400 | //load content and copy, then set |
401 | unsigned char hdcp_key_content_buf[CC_HDCP_KEY_CONTENT_SIZE]; |
402 | if (SSMReadHDCPKeyExcludingHeader(hdcp_key_content_buf) == CC_HDCP_KEY_CONTENT_SIZE) { |
403 | memcpy(hdcp_key_buf + 40, hdcp_key_content_buf, CC_HDCP_KEY_CONTENT_SIZE); |
404 | LOGD("%s, using ssm's hdcp key.\n", __FUNCTION__); |
405 | return RealHandleHDCPKey(hdcp_key_buf); |
406 | } |
407 | } else { |
408 | if (SSMReadHDCPKey(hdcp_key_buf) == CC_HDCP_KEY_TOTAL_SIZE) { |
409 | LOGD("%s, using ssm's hdcp key.\n", __FUNCTION__); |
410 | return RealHandleHDCPKey(hdcp_key_buf); |
411 | } |
412 | } |
413 | } |
414 | |
415 | return -1; |
416 | } |
417 | |
418 | int SSMRefreshHDCPKey() |
419 | { |
420 | int ret = -1; |
421 | ret = SSMSetHDCPKey(); |
422 | system ( "/system/bin/dec" ); |
423 | return ret; |
424 | } |
425 | |
426 | int SSMGetHDCPKeyDataLen() |
427 | { |
428 | return CC_HDCP_KEY_TOTAL_SIZE; |
429 | } |
430 | |
431 | //hdmi edid |
432 | int SSMSetHDMIEdid(int port) |
433 | { |
434 | int i = 0; |
435 | unsigned char customer_hdmi_edid_buf[CC_CUSTOMER_HDMI_EDID_TOTAL_SIZE]; |
436 | unsigned char hdmi_edid_buf[SSM_HDMI_EDID_SIZE]; |
437 | |
438 | if (port < 1 && port > SSM_HDMI_PORT_MAX) { |
439 | LOGD("%s, hdmi port error.%d\n", __FUNCTION__, port); |
440 | return -1; |
441 | } |
442 | |
443 | if (GetSSMHandleHDMIEdidByCustomerEnableCFG() == 1) { |
444 | if (SSMReadHDMIEdid(port, hdmi_edid_buf) == 0) { |
445 | LOGD("%s, using ssm's hdmi edid.\n", __FUNCTION__); |
446 | LOGD("%s, begin to write hdmi edid:0x%x, 0x%x, 0x%x, 0x%x.\n", |
447 | __FUNCTION__, hdmi_edid_buf[8], hdmi_edid_buf[9], |
448 | hdmi_edid_buf[10], hdmi_edid_buf[255]); |
449 | if (AppendEdidPrefixCode(customer_hdmi_edid_buf, hdmi_edid_buf) |
450 | == 0) |
451 | ; |
452 | return RealHandleHDMIEdid(customer_hdmi_edid_buf); |
453 | } |
454 | } |
455 | |
456 | return -1; |
457 | } |
458 | |
459 | int SSMReadHDMIEdid(int port, unsigned char hdmi_edid_buf[]) |
460 | { |
461 | int tmp_ret = 0; |
462 | LOGD("%s, read hdmi edid from bin file.\n", __FUNCTION__); |
463 | tmp_ret = GetHDMIEdidFromFile(0, SSM_HDMI_EDID_SIZE, port, hdmi_edid_buf); |
464 | if (tmp_ret < 0) { |
465 | LOGD("%s, read hdmi edid error.\n", __FUNCTION__); |
466 | } else { |
467 | LOGD("%s, 0x%x, 0x%x, 0x%x, 0x%x.\n", __FUNCTION__, hdmi_edid_buf[8], |
468 | hdmi_edid_buf[9], hdmi_edid_buf[10], hdmi_edid_buf[255]); |
469 | } |
470 | return tmp_ret; |
471 | } |
472 | |
473 | int KeyData_SaveProjectID(int rw_val) |
474 | { |
475 | int tmp_ret = 0, wr_size = 0; |
476 | char tmp_buf[64] = { 0 }; |
477 | |
478 | sprintf(tmp_buf, "%08X", rw_val); |
479 | |
480 | wr_size = strlen(tmp_buf); |
481 | tmp_ret = WriteKeyData(CS_PROJECT_ID_KEY_NAME, wr_size, tmp_buf); |
482 | if (tmp_ret != wr_size) { |
483 | return -1; |
484 | } |
485 | |
486 | return 0; |
487 | } |
488 | |
489 | int KeyData_ReadProjectID() |
490 | { |
491 | int rd_size = 0, tmp_val = 0; |
492 | unsigned char tmp_buf[64] = { 0 }; |
493 | |
494 | rd_size = ReadKeyData(CS_PROJECT_ID_KEY_NAME, 4, tmp_buf); |
495 | LOGD("%s, rd_size = %d\n", __FUNCTION__, rd_size); |
496 | if (rd_size == 4) { |
497 | tmp_val = 0; |
498 | tmp_val |= tmp_buf[0] << 24; |
499 | tmp_val |= tmp_buf[1] << 16; |
500 | tmp_val |= tmp_buf[2] << 8; |
501 | tmp_val |= tmp_buf[3] << 0; |
502 | } |
503 | |
504 | return tmp_val; |
505 | } |
506 | |
507 | int SSMSaveRGBOGOValue(int offset, int size, unsigned char data_buf[]) |
508 | { |
509 | return SaveRGBOGOToFile(offset, size, data_buf); |
510 | } |
511 | |
512 | int SSMReadRGBOGOValue(int offset, int size, unsigned char data_buf[]) |
513 | { |
514 | return GetRGBOGOFromFile(offset, size, data_buf); |
515 | } |
516 | |
517 | int SSMSaveAudioNoLinePoints(int offset, int size, unsigned char tmp_buf[]) |
518 | { |
519 | return SaveAudioNoLinePointsDataToFile(offset, size, tmp_buf); |
520 | } |
521 | |
522 | int SSMReadAudioNoLinePoints(int offset, int size, unsigned char tmp_buf[]) |
523 | { |
524 | return GetAudioNoLinePointsDataFromFile(offset, size, tmp_buf); |
525 | } |
526 | |
527 | /**************************** start mac address static functions ****************************/ |
528 | #define CC_ERR_THREAD_ID (0) |
529 | |
530 | static pthread_t mMacAddressStartWorkThreadID = CC_ERR_THREAD_ID; |
531 | |
532 | static volatile unsigned int mMacAddressLow = -1; |
533 | static volatile unsigned int mMacAddressHigh = -1; |
534 | static volatile int mMacAddressStartWorkThreadExecFlag = -1; |
535 | static volatile int mMacAddressStartWorkThreadTurnOnFlag = -1; |
536 | |
537 | static pthread_mutex_t mac_address_low_mutex = PTHREAD_MUTEX_INITIALIZER; |
538 | static pthread_mutex_t mac_address_high_mutex = PTHREAD_MUTEX_INITIALIZER; |
539 | static pthread_mutex_t mac_address_exec_mutex = PTHREAD_MUTEX_INITIALIZER; |
540 | static pthread_mutex_t mac_address_turnon_mutex = PTHREAD_MUTEX_INITIALIZER; |
541 | |
542 | static int GetSSMMacAddressStartWorkEnableCFG() |
543 | { |
544 | const char *config_value; |
545 | |
546 | config_value = config_get_str("TV", CS_MAC_ADDRESS_STARTWRK_EN_CFG, "null"); |
547 | if (strcmp(config_value, "null") == 0) { |
548 | LOGD( |
549 | "%s, get config is \"%s\", return 0 to not enable mac address start work.\n", |
550 | __FUNCTION__, config_value); |
551 | return 0; |
552 | } |
553 | |
554 | return strtoul(config_value, NULL, 10); |
555 | } |
556 | |
557 | static unsigned int SetMacAddressLow(unsigned int low_val) |
558 | { |
559 | unsigned int tmp_val; |
560 | |
561 | pthread_mutex_lock(&mac_address_low_mutex); |
562 | |
563 | tmp_val = mMacAddressLow; |
564 | |
565 | mMacAddressLow = low_val; |
566 | |
567 | pthread_mutex_unlock(&mac_address_low_mutex); |
568 | |
569 | return tmp_val; |
570 | } |
571 | |
572 | static unsigned int GetMacAddressLow() |
573 | { |
574 | unsigned int tmp_val = 0; |
575 | |
576 | pthread_mutex_lock(&mac_address_low_mutex); |
577 | |
578 | tmp_val = mMacAddressLow; |
579 | |
580 | pthread_mutex_unlock(&mac_address_low_mutex); |
581 | |
582 | return tmp_val; |
583 | } |
584 | |
585 | static unsigned int SetMacAddressHigh(unsigned int high_val) |
586 | { |
587 | unsigned int tmp_val; |
588 | |
589 | pthread_mutex_lock(&mac_address_high_mutex); |
590 | |
591 | tmp_val = mMacAddressHigh; |
592 | |
593 | mMacAddressHigh = high_val; |
594 | |
595 | pthread_mutex_unlock(&mac_address_high_mutex); |
596 | |
597 | return tmp_val; |
598 | } |
599 | |
600 | static unsigned int GetMacAddressHigh() |
601 | { |
602 | int tmp_val = 0; |
603 | |
604 | pthread_mutex_lock(&mac_address_high_mutex); |
605 | |
606 | tmp_val = mMacAddressHigh; |
607 | |
608 | pthread_mutex_unlock(&mac_address_high_mutex); |
609 | |
610 | return tmp_val; |
611 | } |
612 | |
613 | static int SetMacAddressStartWorkThreadExecFlag(int tmp_flag) |
614 | { |
615 | int tmp_val; |
616 | |
617 | pthread_mutex_lock(&mac_address_exec_mutex); |
618 | |
619 | tmp_val = mMacAddressStartWorkThreadExecFlag; |
620 | |
621 | mMacAddressStartWorkThreadExecFlag = tmp_flag; |
622 | |
623 | pthread_mutex_unlock(&mac_address_exec_mutex); |
624 | |
625 | return tmp_val; |
626 | } |
627 | |
628 | static int GetMacAddressStartWorkThreadExecFlag() |
629 | { |
630 | int tmp_val = 0; |
631 | |
632 | pthread_mutex_lock(&mac_address_exec_mutex); |
633 | |
634 | tmp_val = mMacAddressStartWorkThreadExecFlag; |
635 | |
636 | pthread_mutex_unlock(&mac_address_exec_mutex); |
637 | |
638 | return tmp_val; |
639 | } |
640 | |
641 | static int SetMacAddressStartWorkThreadTurnOnFlag(int tmp_flag) |
642 | { |
643 | int tmp_val; |
644 | |
645 | pthread_mutex_lock(&mac_address_turnon_mutex); |
646 | |
647 | tmp_val = mMacAddressStartWorkThreadTurnOnFlag; |
648 | |
649 | mMacAddressStartWorkThreadTurnOnFlag = tmp_flag; |
650 | |
651 | pthread_mutex_unlock(&mac_address_turnon_mutex); |
652 | |
653 | return tmp_val; |
654 | } |
655 | |
656 | static int GetMacAddressStartWorkThreadTurnOnFlag() |
657 | { |
658 | int tmp_val = 0; |
659 | |
660 | pthread_mutex_lock(&mac_address_turnon_mutex); |
661 | |
662 | tmp_val = mMacAddressStartWorkThreadTurnOnFlag; |
663 | |
664 | pthread_mutex_unlock(&mac_address_turnon_mutex); |
665 | |
666 | return tmp_val; |
667 | } |
668 | |
669 | static void *SSMMacAddressStartWorkMainApp(void *data) |
670 | { |
671 | unsigned int curMacAddrLow = 0, curMacAddrHigh = 0; |
672 | int p_status; |
673 | char ssm_addr_str[128]; |
674 | const char *iname = "eth0"; |
675 | pid_t pid; |
676 | |
677 | LOGD("%s, entering...\n", __FUNCTION__); |
678 | |
679 | if (GetSSMMacAddressStartWorkEnableCFG() == 0) { |
680 | LOGE("%s, ssm mac address start work is not enable.\n", "TV"); |
681 | return NULL; |
682 | } |
683 | |
684 | curMacAddrLow = GetMacAddressLow(); |
685 | curMacAddrHigh = GetMacAddressHigh(); |
686 | |
687 | while (GetMacAddressStartWorkThreadTurnOnFlag() == 1) { |
688 | pid = fork(); |
689 | if (pid == 0) { |
690 | if (execl("/system/bin/stop", "stop_eth_dhcpcd", "eth_dhcpcd", NULL) |
691 | < 0) { |
692 | _exit(-1); |
693 | } |
694 | _exit(0); |
695 | } |
696 | waitpid(pid, &p_status, 0); |
697 | |
698 | ifc_init(); |
699 | |
700 | ifc_down(iname); |
701 | |
702 | sprintf(ssm_addr_str, "%02x:%02x:%02x:%02x:%02x:%02x", |
703 | ((curMacAddrLow >> 0) & 0xFF), ((curMacAddrLow >> 8) & 0xFF), |
704 | ((curMacAddrLow >> 16) & 0xFF), ((curMacAddrLow >> 24) & 0xFF), |
705 | ((curMacAddrHigh >> 0) & 0xFF), ((curMacAddrHigh >> 8) & 0xFF)); |
706 | struct ether_addr *addr = ether_aton(ssm_addr_str); |
707 | if (addr) { |
708 | ifc_set_hwaddr(iname, addr->ether_addr_octet); |
709 | } |
710 | |
711 | ifc_up(iname); |
712 | |
713 | ifc_close(); |
714 | |
715 | if (curMacAddrLow == GetMacAddressLow() |
716 | && curMacAddrHigh == GetMacAddressHigh()) { |
717 | break; |
718 | } |
719 | |
720 | curMacAddrLow = GetMacAddressLow(); |
721 | curMacAddrHigh = GetMacAddressHigh(); |
722 | } |
723 | |
724 | return NULL; |
725 | } |
726 | |
727 | static void *SSMMacAddressStartWorkThreadMain(void *data) |
728 | { |
729 | void *tmp_ret = NULL; |
730 | |
731 | SetMacAddressStartWorkThreadExecFlag(1); |
732 | |
733 | tmp_ret = SSMMacAddressStartWorkMainApp(NULL); |
734 | |
735 | SetMacAddressStartWorkThreadExecFlag(0); |
736 | |
737 | return tmp_ret; |
738 | } |
739 | |
740 | static int KillMacAddressStartWorkThread() |
741 | { |
742 | int i = 0, tmp_timeout_count = 600; |
743 | |
744 | SetMacAddressStartWorkThreadTurnOnFlag(0); |
745 | while (1) { |
746 | if (GetMacAddressStartWorkThreadExecFlag() == 0) { |
747 | break; |
748 | } |
749 | |
750 | if (i >= tmp_timeout_count) { |
751 | break; |
752 | } |
753 | |
754 | i++; |
755 | |
756 | usleep(100 * 1000); |
757 | } |
758 | |
759 | if (i == tmp_timeout_count) { |
760 | LOGE( |
761 | "%s, we have try %d times, but the mac address start work thread's exec flag is still(%d)!!!\n", |
762 | "TV", tmp_timeout_count, |
763 | GetMacAddressStartWorkThreadExecFlag()); |
764 | return -1; |
765 | } |
766 | |
767 | pthread_join(mMacAddressStartWorkThreadID, NULL); |
768 | mMacAddressStartWorkThreadID = CC_ERR_THREAD_ID; |
769 | |
770 | LOGD("%s, kill the mac address start work thread sucess.\n", __FUNCTION__); |
771 | |
772 | return 0; |
773 | } |
774 | |
775 | static int CreateMacAddressStartWorkThread() |
776 | { |
777 | unsigned int macAddrLow = 0, macAddrHigh = 0; |
778 | pthread_attr_t attr; |
779 | struct sched_param param; |
780 | unsigned char ssm_addr_buf[16] = { 0, 0, 0, 0, 0, 0 }; |
781 | |
782 | if (KeyData_ReadMacAddress(ssm_addr_buf) < 0) { |
783 | return -1; |
784 | } |
785 | |
786 | macAddrLow = 0; |
787 | macAddrLow |= ((ssm_addr_buf[0] & 0xFF) << 0); |
788 | macAddrLow |= ((ssm_addr_buf[1] & 0xFF) << 8); |
789 | macAddrLow |= ((ssm_addr_buf[2] & 0xFF) << 16); |
790 | macAddrLow |= ((ssm_addr_buf[3] & 0xFF) << 24); |
791 | |
792 | macAddrHigh = 0; |
793 | macAddrHigh |= ((ssm_addr_buf[4] & 0xFF) << 0); |
794 | macAddrHigh |= ((ssm_addr_buf[5] & 0xFF) << 8); |
795 | |
796 | if (mMacAddressStartWorkThreadID != CC_ERR_THREAD_ID) { |
797 | if (GetMacAddressStartWorkThreadExecFlag() == 1) { |
798 | SetMacAddressLow(macAddrLow); |
799 | SetMacAddressHigh(macAddrHigh); |
800 | return 0; |
801 | } else { |
802 | KillMacAddressStartWorkThread(); |
803 | } |
804 | } |
805 | |
806 | SetMacAddressLow(macAddrLow); |
807 | SetMacAddressHigh(macAddrHigh); |
808 | SetMacAddressStartWorkThreadTurnOnFlag(1); |
809 | |
810 | pthread_attr_init(&attr); |
811 | pthread_attr_setschedpolicy(&attr, SCHED_RR); |
812 | param.sched_priority = 20; |
813 | pthread_attr_setschedparam(&attr, ¶m); |
814 | |
815 | if (pthread_create(&mMacAddressStartWorkThreadID, &attr, |
816 | SSMMacAddressStartWorkThreadMain, NULL) < 0) { |
817 | pthread_attr_destroy(&attr); |
818 | mMacAddressStartWorkThreadID = CC_ERR_THREAD_ID; |
819 | return -1; |
820 | } |
821 | |
822 | pthread_attr_destroy(&attr); |
823 | |
824 | LOGD("%s, create channel select thread sucess.\n", __FUNCTION__); |
825 | |
826 | return 0; |
827 | } |
828 | /**************************** end mac address static functions ****************************/ |
829 | |
830 | /**************************** start hdcp key static functions ****************************/ |
831 | static int GetSSMHandleHDCPKeyEnableCFG() |
832 | { |
833 | const char *config_value; |
834 | |
835 | config_value = config_get_str("TV", CS_HDCP_KEY_EN_CFG, "null"); |
836 | #if 0 |
837 | LOGD("%s, get \"%s\" is \"%s\".\n", __FUNCTION__, CS_HDCP_KEY_EN_CFG, |
838 | config_value); |
839 | #endif |
840 | if (strcmp(config_value, "null") == 0) { |
841 | LOGD( |
842 | "%s, get config \"%s\" is \"%s\", return 0 to not enable handle hdcp key.\n", |
843 | __FUNCTION__, CS_HDCP_KEY_EN_CFG, config_value); |
844 | return 0; |
845 | } |
846 | |
847 | return strtoul(config_value, NULL, 10); |
848 | } |
849 | |
850 | static int GetSSMHandleHDCPKeyDemoEnableCFG() |
851 | { |
852 | const char *config_value; |
853 | |
854 | config_value = config_get_str("TV", CS_HDCP_KEY_DEMO_EN_CFG, "null"); |
855 | #if 0 |
856 | LOGD("%s, get \"%s\" is \"%s\".\n", __FUNCTION__, CS_HDCP_KEY_DEMO_EN_CFG, |
857 | config_value); |
858 | #endif |
859 | if (strcmp(config_value, "null") == 0) { |
860 | LOGD( |
861 | "%s, get config \"%s\" is \"%s\", return 0 to not enable handle hdcp key demo.\n", |
862 | __FUNCTION__, CS_HDCP_KEY_DEMO_EN_CFG, config_value); |
863 | return 0; |
864 | } |
865 | |
866 | return strtoul(config_value, NULL, 10); |
867 | } |
868 | |
869 | static int GetSSMHandleHDCPKeyHeaderEnableCFG() |
870 | { |
871 | const char *config_value; |
872 | |
873 | config_value = config_get_str("TV", CS_HDCP_KEY_HEADER_EN_CFG, "null"); |
874 | #if 1 |
875 | LOGD("%s, get \"%s\" is \"%s\".\n", __FUNCTION__, CS_HDCP_KEY_HEADER_EN_CFG, |
876 | config_value); |
877 | #endif |
878 | if (strcmp(config_value, "null") == 0) { |
879 | LOGD( |
880 | "%s, get config \"%s\" is \"%s\", return 0 to not enable handle hdcp key header.\n", |
881 | __FUNCTION__, CS_HDCP_KEY_HEADER_EN_CFG, config_value); |
882 | return 0; |
883 | } |
884 | |
885 | return strtoul(config_value, NULL, 10); |
886 | } |
887 | |
888 | |
889 | static int SSMSetDefaultHDCPKey(unsigned char hdcp_key_buf[]) |
890 | { |
891 | int i = 0; |
892 | |
893 | for (i = 0; i < CC_HDCP_KEY_HEAD_SIZE; i++) { |
894 | hdcp_key_buf[i] = mHDCPKeyDefHeaderBuf[i]; |
895 | } |
896 | |
897 | for (i = 0; i < CC_HDCP_KEY_CONTENT_SIZE; i++) { |
898 | hdcp_key_buf[i + CC_HDCP_KEY_HEAD_SIZE] = mDefHDCPKeyContentBuf[i]; |
899 | } |
900 | |
901 | LOGD("%s, using default hdcp key.\n", __FUNCTION__); |
902 | |
903 | return RealHandleHDCPKey(hdcp_key_buf); |
904 | } |
905 | |
906 | static int RealHandleHDCPKey(unsigned char hdcp_key_buf[]) |
907 | { |
908 | int i = 0, dev_fd = -1; |
909 | |
910 | if (hdcp_key_buf == NULL) { |
911 | return -1; |
912 | } |
913 | |
914 | dev_fd = open("/sys/class/hdmirx/hdmirx0/edid", O_RDWR); |
915 | if (dev_fd < 0) { |
916 | LOGE("%s, open edid file ERROR(%s)!!\n", "TV", strerror(errno)); |
917 | return -1; |
918 | } |
919 | |
920 | if (write(dev_fd, hdcp_key_buf, CC_HDCP_KEY_TOTAL_SIZE) < 0) { |
921 | close(dev_fd); |
922 | dev_fd = -1; |
923 | LOGE("%s, write edid file ERROR(%s)!!\n", "TV", strerror(errno)); |
924 | |
925 | return -1; |
926 | } |
927 | |
928 | close(dev_fd); |
929 | dev_fd = -1; |
930 | return 0; |
931 | } |
932 | |
933 | /**************************** end hdcp key static functions ****************************/ |
934 | |
935 | /**************************** start hdmi edid static functions ****************************/ |
936 | static int GetSSMHandleHDMIEdidByCustomerEnableCFG() |
937 | { |
938 | const char *config_value; |
939 | |
940 | config_value = config_get_str("TV", CS_HDMI_EDID_EN_CFG, "null"); |
941 | #if 0 |
942 | LOGD("%s, get \"%s\" is \"%s\".\n", __FUNCTION__, CS_HDMI_EDID_EN_CFG, |
943 | config_value); |
944 | #endif |
945 | if (strcmp(config_value, "null") == 0) { |
946 | LOGD( |
947 | "%s, get config \"%s\" is \"%s\", return 0 to not enable handle hdmi edid by customer.\n", |
948 | __FUNCTION__, CS_HDMI_EDID_EN_CFG, config_value); |
949 | return 0; |
950 | } |
951 | |
952 | return strtoul(config_value, NULL, 10); |
953 | } |
954 | static int RealHandleHDMIEdid(unsigned char customer_hdmi_edid_buf[]) |
955 | { |
956 | int i = 0, dev_fd = -1; |
957 | |
958 | if (customer_hdmi_edid_buf == NULL) { |
959 | return -1; |
960 | } |
961 | |
962 | dev_fd = open("/sys/class/hdmirx/hdmirx0/edid", O_RDWR); |
963 | if (dev_fd < 0) { |
964 | LOGE("%s, open edid file ERROR(%s)!!\n", "TV", strerror(errno)); |
965 | return -1; |
966 | } |
967 | |
968 | if (write(dev_fd, customer_hdmi_edid_buf, CC_CUSTOMER_HDMI_EDID_TOTAL_SIZE) |
969 | < 0) { |
970 | close(dev_fd); |
971 | dev_fd = -1; |
972 | LOGE("%s, write edid file ERROR(%s)!!\n", "TV", strerror(errno)); |
973 | |
974 | return -1; |
975 | } |
976 | |
977 | close(dev_fd); |
978 | dev_fd = -1; |
979 | return 0; |
980 | } |
981 | |
982 | static int AppendEdidPrefixCode(unsigned char customer_hdmi_edid_buf[], |
983 | unsigned char hdmi_edid_buf[]) |
984 | { |
985 | if (customer_hdmi_edid_buf == NULL || hdmi_edid_buf == NULL) { |
986 | LOGE("%s, Append hdmi edid's prefixCode ERROR(%s)!!\n", "TV", |
987 | strerror(errno)); |
988 | return -1; |
989 | } |
990 | memset(customer_hdmi_edid_buf, 0, |
991 | sizeof(char) * CC_CUSTOMER_HDMI_EDID_TOTAL_SIZE); |
992 | customer_hdmi_edid_buf[0] = 'E'; |
993 | customer_hdmi_edid_buf[1] = 'D'; |
994 | customer_hdmi_edid_buf[2] = 'I'; |
995 | customer_hdmi_edid_buf[3] = 'D'; |
996 | memcpy(customer_hdmi_edid_buf + 4, hdmi_edid_buf, |
997 | CC_CUSTOMER_HDMI_EDID_TOTAL_SIZE - 4); |
998 | /* |
999 | LOGD("%s, customer_hdmi_edid_buf: %c,%c,%c,%c,%x,%x,%x,%x.\n", __FUNCTION__, |
1000 | customer_hdmi_edid_buf[0],customer_hdmi_edid_buf[1],customer_hdmi_edid_buf[2],customer_hdmi_edid_buf[3], |
1001 | customer_hdmi_edid_buf[12],customer_hdmi_edid_buf[13],customer_hdmi_edid_buf[14],customer_hdmi_edid_buf[15]);*/ |
1002 | /* |
1003 | LOGD("%s, customer_hdmi_edid_buf: \n", __FUNCTION__); |
1004 | int i, j; |
1005 | for (i = 0; i < 16; i++) { |
1006 | LOGD("[%2d] ", i); |
1007 | for (j = 0; j < 16; j++) { |
1008 | LOGD("0x%02lx, ", customer_hdmi_edid_buf[4 + (i*16 + j)]); |
1009 | } |
1010 | LOGD("\n"); |
1011 | }*/ |
1012 | return 0; |
1013 | } |
1014 | |
1015 | /**************************** end hdmi edid static functions ****************************/ |
1016 | |
1017 | /**************************** start critical data op functions ****************************/ |
1018 | #define CC_OP_TYPE_READ (0) |
1019 | #define CC_OP_TYPE_SAVE (1) |
1020 | #define CC_DATA_TYPE_CHAR (0) |
1021 | #define CC_DATA_TYPE_INT (1) |
1022 | |
1023 | typedef int (*op_fun_ptr)(char *, int, int, unsigned char *); |
1024 | |
1025 | typedef struct tagRWDataInfo { |
1026 | int op_type; |
1027 | int data_type; |
1028 | int max_size; |
1029 | int rw_off; |
1030 | int rw_size; |
1031 | void *data_buf; |
1032 | char *path_cfg_name; |
1033 | char *off_cfg_name; |
1034 | op_fun_ptr op_cb; |
1035 | } RWDataInfo; |
1036 | |
1037 | static int GetFilePathCFG(char *key_str, char path_buf[]) |
1038 | { |
1039 | int tmp_ret = 0; |
1040 | const char *cfg_value; |
1041 | |
1042 | path_buf[0] = '\0'; |
1043 | cfg_value = config_get_str("TV", key_str, ""); |
1044 | strcpy(path_buf, cfg_value); |
1045 | #if 0 |
1046 | LOGD("%s, get \"%s\" is \"%s\".\n", "TV", key_str, path_buf); |
1047 | #endif |
1048 | return tmp_ret; |
1049 | } |
1050 | |
1051 | static int GetFileOffsetCFG(char *key_str) |
1052 | { |
1053 | const char *cfg_value; |
1054 | |
1055 | cfg_value = config_get_str("TV", key_str, "null"); |
1056 | #if 0 |
1057 | LOGD("%s, get \"%s\" is \"%s\".\n", "TV", key_str, cfg_value); |
1058 | #endif |
1059 | if (strcmp(cfg_value, "null") == 0) { |
1060 | LOGD("%s, get config \"%s\" is \"%s\", return 0 for default.\n", "TV", |
1061 | key_str, cfg_value); |
1062 | return 0; |
1063 | } |
1064 | |
1065 | return strtol(cfg_value, NULL, 10); |
1066 | } |
1067 | |
1068 | static int handleDataFilePath(char *file_name, int offset, int nsize, |
1069 | char file_path[]) |
1070 | { |
1071 | if (file_name == NULL) { |
1072 | LOGE("%s, file_name is NULL!!!\n", "TV"); |
1073 | return -1; |
1074 | } |
1075 | |
1076 | return 0; |
1077 | } |
1078 | |
1079 | static int ReadDataFromFile(char *file_name, int offset, int nsize, |
1080 | unsigned char data_buf[]) |
1081 | { |
1082 | int device_fd = -1; |
1083 | int tmp_ret = 0; |
1084 | char *tmp_ptr = NULL; |
1085 | char file_path[512] = { '\0' }; |
1086 | |
1087 | if (data_buf == NULL) { |
1088 | LOGE("%s, data_buf is NULL!!!\n", "TV"); |
1089 | return -1; |
1090 | } |
1091 | |
1092 | tmp_ret = handleDataFilePath(file_name, offset, nsize, file_path); |
1093 | if (tmp_ret < 0) { |
1094 | tmp_ptr = NULL; |
1095 | } else if (tmp_ret == 0) { |
1096 | tmp_ptr = file_name; |
1097 | } else if (tmp_ret == 1) { |
1098 | tmp_ptr = file_path; |
1099 | } |
1100 | |
1101 | if (tmp_ptr == NULL) { |
1102 | return -1; |
1103 | } |
1104 | |
1105 | device_fd = open(tmp_ptr, O_RDONLY); |
1106 | if (device_fd < 0) { |
1107 | LOGE("%s: open file \"%s\" error(%s).\n", "TV", file_name, |
1108 | strerror(errno)); |
1109 | return -1; |
1110 | } |
1111 | |
1112 | lseek(device_fd, offset, SEEK_SET); |
1113 | read(device_fd, data_buf, nsize); |
1114 | |
1115 | close(device_fd); |
1116 | device_fd = -1; |
1117 | |
1118 | return 0; |
1119 | } |
1120 | |
1121 | static int SaveDataToFile(char *file_name, int offset, int nsize, |
1122 | unsigned char data_buf[]) |
1123 | { |
1124 | int device_fd = -1; |
1125 | int i = 0, tmp_ret = 0; |
1126 | char *tmp_ptr = NULL; |
1127 | char file_path[512] = { '\0' }; |
1128 | |
1129 | if (data_buf == NULL) { |
1130 | LOGE("%s, data_buf is NULL!!!\n", "TV"); |
1131 | return -1; |
1132 | } |
1133 | |
1134 | tmp_ret = handleDataFilePath(file_name, offset, nsize, file_path); |
1135 | if (tmp_ret < 0) { |
1136 | tmp_ptr = NULL; |
1137 | } else if (tmp_ret == 0) { |
1138 | tmp_ptr = file_name; |
1139 | } else if (tmp_ret == 1) { |
1140 | tmp_ptr = file_path; |
1141 | } |
1142 | |
1143 | if (tmp_ptr == NULL) { |
1144 | return -1; |
1145 | } |
1146 | |
1147 | device_fd = open(tmp_ptr, O_RDWR | O_SYNC); |
1148 | if (device_fd < 0) { |
1149 | LOGE("%s: open file \"%s\" error(%s).\n", "TV", file_name, |
1150 | strerror(errno)); |
1151 | return -1; |
1152 | } |
1153 | |
1154 | lseek(device_fd, offset, SEEK_SET); |
1155 | write(device_fd, data_buf, nsize); |
1156 | fsync(device_fd); |
1157 | |
1158 | close(device_fd); |
1159 | device_fd = -1; |
1160 | |
1161 | return 0; |
1162 | } |
1163 | |
1164 | static int RealRWData(RWDataInfo *data_info) |
1165 | { |
1166 | int i = 0, file_off = 0; |
1167 | char file_name[256] = { '\0' }; |
1168 | |
1169 | memset(file_name, '\0', 256); |
1170 | GetFilePathCFG(data_info->path_cfg_name, file_name); |
1171 | #if 0 |
1172 | LOGD("%s, file_name is %s.\n", __FUNCTION__, file_name); |
1173 | #endif |
1174 | if (strlen(file_name) == 0) { |
1175 | LOGE("%s, length of file_name is 0!!!\n", "TV"); |
1176 | return -2; |
1177 | } |
1178 | |
1179 | if (data_info->rw_off < 0) { |
1180 | LOGE("%s, data_info->rw_off (%d) is less than 0!!!\n", "TV", |
1181 | data_info->rw_off); |
1182 | return -1; |
1183 | } |
1184 | |
1185 | if (data_info->rw_off + data_info->rw_size > data_info->max_size) { |
1186 | LOGE( |
1187 | "%s, data_info->rw_off + data_info->rw_size (%d) is more than data_info->max_size(%d) !!!\n", |
1188 | "TV", data_info->rw_off + data_info->rw_size, |
1189 | data_info->max_size); |
1190 | return -1; |
1191 | } |
1192 | |
1193 | file_off = GetFileOffsetCFG(data_info->off_cfg_name); |
1194 | if (file_off < 0) { |
1195 | LOGE("%s, file_off (%d) is less than 0!!!\n", "TV", file_off); |
1196 | return -1; |
1197 | } |
1198 | |
1199 | file_off += data_info->rw_off; |
1200 | |
1201 | if (data_info->op_cb(file_name, file_off, data_info->rw_size, |
1202 | (unsigned char *) data_info->data_buf) < 0) { |
1203 | return -1; |
1204 | } |
1205 | |
1206 | return 0; |
1207 | } |
1208 | |
1209 | static int HandleRWData(RWDataInfo *data_info) |
1210 | { |
1211 | int i = 0, tmp_ret = 0; |
1212 | int *tmp_iptr = NULL; |
1213 | unsigned char *tmp_cptr = NULL; |
1214 | RWDataInfo tmpInfo; |
1215 | |
1216 | if (data_info == NULL) { |
1217 | return -1; |
1218 | } |
1219 | |
1220 | tmpInfo = *data_info; |
1221 | |
1222 | if (data_info->data_type == CC_DATA_TYPE_INT) { |
1223 | tmp_cptr = new unsigned char[data_info->rw_size]; |
1224 | if (tmp_cptr != NULL) { |
1225 | tmpInfo.data_buf = tmp_cptr; |
1226 | |
1227 | if (tmpInfo.op_type == CC_OP_TYPE_SAVE) { |
1228 | tmp_iptr = (int *) data_info->data_buf; |
1229 | for (i = 0; i < data_info->rw_size; i++) { |
1230 | tmp_cptr[i] = tmp_iptr[i]; |
1231 | } |
1232 | |
1233 | tmp_ret |= RealRWData(&tmpInfo); |
1234 | } else { |
1235 | tmp_ret |= RealRWData(&tmpInfo); |
1236 | |
1237 | tmp_iptr = (int *) data_info->data_buf; |
1238 | for (i = 0; i < data_info->rw_size; i++) { |
1239 | tmp_iptr[i] = tmp_cptr[i]; |
1240 | } |
1241 | } |
1242 | |
1243 | delete tmp_cptr; |
1244 | tmp_cptr = NULL; |
1245 | |
1246 | return tmp_ret; |
1247 | } |
1248 | } |
1249 | |
1250 | return RealRWData(&tmpInfo); |
1251 | } |
1252 | |
1253 | static int GetRGBOGOFromFile(int rd_off, int rd_size, |
1254 | unsigned char data_buf[]) |
1255 | { |
1256 | RWDataInfo tmpInfo; |
1257 | |
1258 | tmpInfo.op_type = CC_OP_TYPE_READ; |
1259 | tmpInfo.data_type = CC_DATA_TYPE_CHAR; |
1260 | tmpInfo.max_size = SSM_CR_RGBOGO_LEN + SSM_CR_RGBOGO_CHKSUM_LEN; |
1261 | tmpInfo.rw_off = rd_off; |
1262 | tmpInfo.rw_size = rd_size; |
1263 | tmpInfo.data_buf = data_buf; |
1264 | tmpInfo.path_cfg_name = (char *) CS_RGBOGO_FILE_PATH_CFG; |
1265 | tmpInfo.off_cfg_name = (char *) CS_RGBOGO_FILE_OFFSET_CFG; |
1266 | tmpInfo.op_cb = ReadDataFromFile; |
1267 | |
1268 | return HandleRWData(&tmpInfo); |
1269 | } |
1270 | |
1271 | static int SaveRGBOGOToFile(int wr_off, int wr_size, unsigned char data_buf[]) |
1272 | { |
1273 | RWDataInfo tmpInfo; |
1274 | |
1275 | tmpInfo.op_type = CC_OP_TYPE_SAVE; |
1276 | tmpInfo.data_type = CC_DATA_TYPE_CHAR; |
1277 | tmpInfo.max_size = SSM_CR_RGBOGO_LEN + SSM_CR_RGBOGO_CHKSUM_LEN; |
1278 | tmpInfo.rw_off = wr_off; |
1279 | tmpInfo.rw_size = wr_size; |
1280 | tmpInfo.data_buf = data_buf; |
1281 | tmpInfo.path_cfg_name = (char *) CS_RGBOGO_FILE_PATH_CFG; |
1282 | tmpInfo.off_cfg_name = (char *) CS_RGBOGO_FILE_OFFSET_CFG; |
1283 | tmpInfo.op_cb = SaveDataToFile; |
1284 | |
1285 | return HandleRWData(&tmpInfo); |
1286 | } |
1287 | |
1288 | static int GetAudioNoLinePointsDataFromFile(int rd_off, int rd_size, |
1289 | unsigned char data_buf[]) |
1290 | { |
1291 | RWDataInfo tmpInfo; |
1292 | |
1293 | tmpInfo.op_type = CC_OP_TYPE_READ; |
1294 | tmpInfo.data_type = CC_DATA_TYPE_CHAR; |
1295 | tmpInfo.max_size = 256; |
1296 | tmpInfo.rw_off = rd_off; |
1297 | tmpInfo.rw_size = rd_size; |
1298 | tmpInfo.data_buf = data_buf; |
1299 | tmpInfo.path_cfg_name = (char *) CS_AUDIO_NOLINEPOINTS_FILE_PATH_CFG; |
1300 | tmpInfo.off_cfg_name = (char *) CS_AUDIO_NOLINEPOINTS_FILE_OFFSET_CFG; |
1301 | tmpInfo.op_cb = ReadDataFromFile; |
1302 | |
1303 | return HandleRWData(&tmpInfo); |
1304 | } |
1305 | |
1306 | static int SaveAudioNoLinePointsDataToFile(int wr_off, int wr_size, |
1307 | unsigned char data_buf[]) |
1308 | { |
1309 | RWDataInfo tmpInfo; |
1310 | |
1311 | tmpInfo.op_type = CC_OP_TYPE_SAVE; |
1312 | tmpInfo.data_type = CC_DATA_TYPE_CHAR; |
1313 | tmpInfo.max_size = 256; |
1314 | tmpInfo.rw_off = wr_off; |
1315 | tmpInfo.rw_size = wr_size; |
1316 | tmpInfo.data_buf = data_buf; |
1317 | tmpInfo.path_cfg_name = (char *) CS_AUDIO_NOLINEPOINTS_FILE_PATH_CFG; |
1318 | tmpInfo.off_cfg_name = (char *) CS_AUDIO_NOLINEPOINTS_FILE_OFFSET_CFG; |
1319 | tmpInfo.op_cb = SaveDataToFile; |
1320 | |
1321 | return HandleRWData(&tmpInfo); |
1322 | } |
1323 | |
1324 | static int GetHDCPKeyFromFile(int rd_off, int rd_size, |
1325 | unsigned char data_buf[]) |
1326 | { |
1327 | RWDataInfo tmpInfo; |
1328 | |
1329 | tmpInfo.op_type = CC_OP_TYPE_READ; |
1330 | tmpInfo.data_type = CC_DATA_TYPE_CHAR; |
1331 | tmpInfo.max_size = CC_HDCP_KEY_TOTAL_SIZE; |
1332 | tmpInfo.rw_off = rd_off; |
1333 | tmpInfo.rw_size = rd_size; |
1334 | tmpInfo.data_buf = data_buf; |
1335 | tmpInfo.path_cfg_name = (char *) CS_HDCP_KEY_FILE_PATH_CFG; |
1336 | tmpInfo.off_cfg_name = (char *) CS_HDCP_KEY_FILE_OFFSET_CFG; |
1337 | tmpInfo.op_cb = ReadDataFromFile; |
1338 | |
1339 | return HandleRWData(&tmpInfo); |
1340 | } |
1341 | |
1342 | static int SaveHDCPKeyToFile(int wr_off, int wr_size, |
1343 | unsigned char data_buf[]) |
1344 | { |
1345 | RWDataInfo tmpInfo; |
1346 | |
1347 | tmpInfo.op_type = CC_OP_TYPE_SAVE; |
1348 | tmpInfo.data_type = CC_DATA_TYPE_CHAR; |
1349 | tmpInfo.max_size = CC_HDCP_KEY_TOTAL_SIZE; |
1350 | tmpInfo.rw_off = wr_off; |
1351 | tmpInfo.rw_size = wr_size; |
1352 | tmpInfo.data_buf = data_buf; |
1353 | tmpInfo.path_cfg_name = (char *) CS_HDCP_KEY_FILE_PATH_CFG; |
1354 | tmpInfo.off_cfg_name = (char *) CS_HDCP_KEY_FILE_OFFSET_CFG; |
1355 | tmpInfo.op_cb = SaveDataToFile; |
1356 | |
1357 | return HandleRWData(&tmpInfo); |
1358 | } |
1359 | |
1360 | static int GetHDMIEdidFromFile(int rd_off, int rd_size, int port, |
1361 | unsigned char data_buf[]) |
1362 | { |
1363 | RWDataInfo tmpInfo; |
1364 | |
1365 | tmpInfo.op_type = CC_OP_TYPE_READ; |
1366 | tmpInfo.data_type = CC_DATA_TYPE_CHAR; |
1367 | tmpInfo.max_size = SSM_HDMI_EDID_SIZE; |
1368 | tmpInfo.rw_off = rd_off; |
1369 | tmpInfo.rw_size = rd_size; |
1370 | tmpInfo.data_buf = data_buf; |
1371 | switch (port) { |
1372 | case 1: |
1373 | tmpInfo.path_cfg_name = (char *) CS_HDMI_PORT1_EDID_FILE_PATH_CFG; |
1374 | break; |
1375 | case 2: |
1376 | tmpInfo.path_cfg_name = (char *) CS_HDMI_PORT2_EDID_FILE_PATH_CFG; |
1377 | break; |
1378 | case 3: |
1379 | tmpInfo.path_cfg_name = (char *) CS_HDMI_PORT3_EDID_FILE_PATH_CFG; |
1380 | break; |
1381 | default: |
1382 | LOGE("%s, port is error, =%d\n", "TV", port); |
1383 | tmpInfo.path_cfg_name = (char *) CS_HDMI_EDID_FILE_PATH_CFG; |
1384 | break; |
1385 | } |
1386 | tmpInfo.off_cfg_name = (char *) CS_HDMI_EDID_FILE_OFFSET_CFG; |
1387 | tmpInfo.op_cb = ReadDataFromFile; |
1388 | |
1389 | return HandleRWData(&tmpInfo); |
1390 | } |
1391 | |
1392 | /**************************** end critical data op functions ****************************/ |
1393 |