1*4882a593Smuzhiyun /* V2.1:
2*4882a593Smuzhiyun * 1. remove VENDOR_SN_ID len limit
3*4882a593Smuzhiyun * 2. add custom id
4*4882a593Smuzhiyun * 3. exten max vendor string len to 1024
5*4882a593Smuzhiyun * 4. support file read/write
6*4882a593Smuzhiyun * 5. support build a library
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #include <fcntl.h>
10*4882a593Smuzhiyun #include <sys/ioctl.h>
11*4882a593Smuzhiyun #include <stdio.h>
12*4882a593Smuzhiyun #include <string.h>
13*4882a593Smuzhiyun #include <unistd.h>
14*4882a593Smuzhiyun #include <stdlib.h>
15*4882a593Smuzhiyun #include <stdbool.h>
16*4882a593Smuzhiyun #include "vendor_storage.h"
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun #define VENDOR_STORAGE_DEBUG
19*4882a593Smuzhiyun #ifdef VENDOR_STORAGE_DEBUG
20*4882a593Smuzhiyun #define DEBUG(fmt, args...) fprintf(stdout, "[Debug] "fmt, ##args)
21*4882a593Smuzhiyun #else
22*4882a593Smuzhiyun #define DEBUG(fmt, args...)
23*4882a593Smuzhiyun #endif
24*4882a593Smuzhiyun #define INFO(fmt, args...) fprintf(stdout, "[INFO] "fmt, ##args)
25*4882a593Smuzhiyun #define ERROR(fmt, args...) fprintf(stderr, "[ERROR] "fmt, ##args)
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun typedef unsigned short uint16;
28*4882a593Smuzhiyun typedef unsigned int uint32;
29*4882a593Smuzhiyun typedef unsigned char uint8;
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #define VENDOR_MAX_SIZE 1024
32*4882a593Smuzhiyun #define VENDOR_REQ_TAG 0x56524551
33*4882a593Smuzhiyun #define VENDOR_READ_IO _IOW('v', 0x01, unsigned int)
34*4882a593Smuzhiyun #define VENDOR_WRITE_IO _IOW('v', 0x02, unsigned int)
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun #define VENDOR_ID_MAX 16
37*4882a593Smuzhiyun #define VENDOR_CMD_CUSTOM_LEN sizeof("VENDOR_CUSTOM_ID")
38*4882a593Smuzhiyun static char *vendor_id_table[] = {
39*4882a593Smuzhiyun "VENDOR_SN_ID",
40*4882a593Smuzhiyun "VENDOR_WIFI_MAC_ID",
41*4882a593Smuzhiyun "VENDOR_LAN_MAC_ID",
42*4882a593Smuzhiyun "VENDOR_BT_MAC_ID",
43*4882a593Smuzhiyun "VENDOR_HDCP_14_HDMI_ID",
44*4882a593Smuzhiyun "VENDOR_HDCP_14_DP_ID",
45*4882a593Smuzhiyun "VENDOR_HDCP_2x_ID",
46*4882a593Smuzhiyun "VENDOR_DRM_KEY_ID",
47*4882a593Smuzhiyun "VENDOR_PLAYREADY_Cert_ID",
48*4882a593Smuzhiyun "VENDOR_ATTENTION_KEY_ID",
49*4882a593Smuzhiyun "VENDOR_PLAYREADY_ROOT_KEY_0_ID",
50*4882a593Smuzhiyun "VENDOR_PLAYREADY_ROOT_KEY_1_ID",
51*4882a593Smuzhiyun "VENDOR_SENSOR_CALIBRATION_ID",
52*4882a593Smuzhiyun "VENODR_RESERVE_ID_14",
53*4882a593Smuzhiyun "VENDOR_IMEI_ID",
54*4882a593Smuzhiyun "VENDOR_CUSTOM_ID" /* CUSTOM_ID must be last one */
55*4882a593Smuzhiyun };
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun #define VENDOR_PR_HEX 0
58*4882a593Smuzhiyun #define VENDOR_PR_STRING 1
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun /* Set custom_id to hex print default */
61*4882a593Smuzhiyun #define GET_PR_FORMAT(ID, FORMAT) \
62*4882a593Smuzhiyun if ((ID) == VENDOR_IMEI_ID || (ID) == VENDOR_SN_ID) \
63*4882a593Smuzhiyun FORMAT = VENDOR_PR_STRING; \
64*4882a593Smuzhiyun else \
65*4882a593Smuzhiyun FORMAT = VENDOR_PR_HEX;
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun struct rk_vendor_req {
68*4882a593Smuzhiyun uint32 tag;
69*4882a593Smuzhiyun uint16 id;
70*4882a593Smuzhiyun uint16 len;
71*4882a593Smuzhiyun uint8 data[1024];
72*4882a593Smuzhiyun };
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun #ifndef BUILD_LIB_VENDOR_STORAGE
75*4882a593Smuzhiyun static char *argv0;
76*4882a593Smuzhiyun
rknand_print_string_data(uint8 * s,struct rk_vendor_req * buf,uint32 len)77*4882a593Smuzhiyun static void rknand_print_string_data(uint8 *s, struct rk_vendor_req *buf, uint32 len)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun unsigned int i;
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun for (i = 0; i < len; i++)
82*4882a593Smuzhiyun printf("%c", buf->data[i]);
83*4882a593Smuzhiyun fprintf(stdout, "\n");
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun
rknand_print_hex_data(uint8 * s,struct rk_vendor_req * buf,uint32 len)86*4882a593Smuzhiyun static void rknand_print_hex_data(uint8 *s, struct rk_vendor_req *buf, uint32 len)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun unsigned int i, line;
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun line = 0;
91*4882a593Smuzhiyun for (i = 0; i < len; i++) {
92*4882a593Smuzhiyun if (i & 0x000f) {
93*4882a593Smuzhiyun printf(" %02x", buf->data[i]);
94*4882a593Smuzhiyun } else {
95*4882a593Smuzhiyun printf("\n %04x-%04x: %02x",
96*4882a593Smuzhiyun line << 4,
97*4882a593Smuzhiyun (line << 4) | 0xf,
98*4882a593Smuzhiyun buf->data[i]);
99*4882a593Smuzhiyun line++;
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun fprintf(stdout, "\n");
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
rknand_print_data(uint8 * s,struct rk_vendor_req * buf,uint32 len,int pr_type)106*4882a593Smuzhiyun static void rknand_print_data(uint8 *s, struct rk_vendor_req *buf,
107*4882a593Smuzhiyun uint32 len, int pr_type)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun DEBUG("%s\n",s);
110*4882a593Smuzhiyun DEBUG("tag = %d // id = %d // len = %d // data = %p\n", buf->tag, buf->id, buf->len, buf->data);
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun INFO("%s:", (buf->id > VENDOR_ID_MAX) ?
113*4882a593Smuzhiyun "VENDOR_CUSTOM_ID" : vendor_id_table[buf->id - 1]);
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun if (pr_type)
116*4882a593Smuzhiyun rknand_print_string_data(s, buf, len);
117*4882a593Smuzhiyun else
118*4882a593Smuzhiyun rknand_print_hex_data(s, buf, len);
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun
vendor_storage_read(int cmd,int pr_type,char * output)121*4882a593Smuzhiyun static int vendor_storage_read(int cmd, int pr_type, char *output)
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun uint32 i;
124*4882a593Smuzhiyun int ret ;
125*4882a593Smuzhiyun uint8 p_buf[sizeof(struct rk_vendor_req)]; /* malloc req buffer or used extern buffer */
126*4882a593Smuzhiyun struct rk_vendor_req *req;
127*4882a593Smuzhiyun FILE *foutput = NULL;
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun DEBUG("%s id = %d\n", __func__, cmd);
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun req = (struct rk_vendor_req *)p_buf;
132*4882a593Smuzhiyun memset(p_buf, 0, 100);
133*4882a593Smuzhiyun int sys_fd = open("/dev/vendor_storage", O_RDWR, 0);
134*4882a593Smuzhiyun if(sys_fd < 0){
135*4882a593Smuzhiyun ERROR("vendor_storage open fail\n");
136*4882a593Smuzhiyun return -1;
137*4882a593Smuzhiyun }
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun req->tag = VENDOR_REQ_TAG;
140*4882a593Smuzhiyun req->id = cmd;
141*4882a593Smuzhiyun req->len = VENDOR_MAX_SIZE;
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun ret = ioctl(sys_fd, VENDOR_READ_IO, req);
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun if(ret){
146*4882a593Smuzhiyun ERROR("vendor read error %d\n", ret);
147*4882a593Smuzhiyun return -1;
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun close(sys_fd);
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun rknand_print_data("vendor read:", req, req->len, pr_type);
152*4882a593Smuzhiyun if (output) {
153*4882a593Smuzhiyun foutput=fopen(output,"wb");
154*4882a593Smuzhiyun if (!foutput) {
155*4882a593Smuzhiyun ERROR("failed to save %s\n", output);
156*4882a593Smuzhiyun return 0;
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun fwrite(req->data, req->len, 1, foutput);
159*4882a593Smuzhiyun fclose(foutput);
160*4882a593Smuzhiyun INFO("save output to %s\n", output);
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun return 0;
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun
vendor_storage_write(int cmd,char * num,int pr_type,int len)166*4882a593Smuzhiyun static int vendor_storage_write(int cmd, char *num, int pr_type, int len)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun uint32 i;
169*4882a593Smuzhiyun int ret ;
170*4882a593Smuzhiyun uint8 p_buf[sizeof(struct rk_vendor_req)]; /* malloc req buffer or used extern buffer */
171*4882a593Smuzhiyun struct rk_vendor_req *req;
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun DEBUG("%s id = %d\n", __func__, cmd);
174*4882a593Smuzhiyun req = (struct rk_vendor_req *)p_buf;
175*4882a593Smuzhiyun int sys_fd = open("/dev/vendor_storage",O_RDWR,0);
176*4882a593Smuzhiyun if(sys_fd < 0){
177*4882a593Smuzhiyun ERROR("vendor_storage open fail\n");
178*4882a593Smuzhiyun return -1;
179*4882a593Smuzhiyun }
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun req->tag = VENDOR_REQ_TAG;
182*4882a593Smuzhiyun req->id = cmd;
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun req->len = len;
185*4882a593Smuzhiyun DEBUG("%s: strlen = %d\n", __func__, req->len);
186*4882a593Smuzhiyun memcpy(req->data, num, req->len);
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun ret = ioctl(sys_fd, VENDOR_WRITE_IO, req);
189*4882a593Smuzhiyun if(ret){
190*4882a593Smuzhiyun ERROR("vendor write error\n");
191*4882a593Smuzhiyun return -1;
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun rknand_print_data("vendor write:", req, req->len, pr_type);
195*4882a593Smuzhiyun return 0;
196*4882a593Smuzhiyun }
197*4882a593Smuzhiyun
usage(void)198*4882a593Smuzhiyun static void usage(void)
199*4882a593Smuzhiyun {
200*4882a593Smuzhiyun int i;
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun fprintf(stderr,
203*4882a593Smuzhiyun "vendor storage tool - Revision: 2.0 \n\n"
204*4882a593Smuzhiyun "%s [-r/w <vendor_id> -t <pr_type> -i <input>] [-R]\n"
205*4882a593Smuzhiyun " -r Read specify vendor_id\n"
206*4882a593Smuzhiyun " -R Read common vendor_id\n"
207*4882a593Smuzhiyun " -w Write specify vendor_id\n"
208*4882a593Smuzhiyun " -t print type\n"
209*4882a593Smuzhiyun " -i input string\n"
210*4882a593Smuzhiyun " <vendor_id> There are %d types\n",
211*4882a593Smuzhiyun argv0, VENDOR_ID_MAX);
212*4882a593Smuzhiyun for (i = 0; i < VENDOR_ID_MAX; i++)
213*4882a593Smuzhiyun fprintf(stderr,
214*4882a593Smuzhiyun " \"%s\"\n",
215*4882a593Smuzhiyun vendor_id_table[i]);
216*4882a593Smuzhiyun fprintf(stderr,
217*4882a593Smuzhiyun " And custom can define other id like\n"
218*4882a593Smuzhiyun " VENDOR_CUSTOM_ID_1A (define ID = 26)\n");
219*4882a593Smuzhiyun fprintf(stderr,
220*4882a593Smuzhiyun " <pr_type> In write case, used with -i <input>\n"
221*4882a593Smuzhiyun " There are 3 types\n"
222*4882a593Smuzhiyun " \"hex\": <input> must be hex form like 0123\n"
223*4882a593Smuzhiyun " \"string\": <input> must be ASCII string\n"
224*4882a593Smuzhiyun " \"file\": <input> must be path to file\n"
225*4882a593Smuzhiyun " Note: If use \"file\" and -i with read, it means save storage to file\n"
226*4882a593Smuzhiyun "Examples:\n"
227*4882a593Smuzhiyun " %s -w VENDOR_CUSTOM_ID_1A -t file -i /userdata/test.bin\n"
228*4882a593Smuzhiyun " write userdata/test.bin to storage\n"
229*4882a593Smuzhiyun " Or -t string -i test_storage\n"
230*4882a593Smuzhiyun " write string \"test_storage\" to storage\n"
231*4882a593Smuzhiyun " ID = 26\n"
232*4882a593Smuzhiyun " %s -r VENDOR_CUSTOM_ID_1A -t file -i /userdata/read.bin\n"
233*4882a593Smuzhiyun " read storage(ID=26) to userdata/read.bin\n"
234*4882a593Smuzhiyun " Or -t string\n"
235*4882a593Smuzhiyun " print storage(ID=26) with ASCII string\n",
236*4882a593Smuzhiyun argv0, argv0);
237*4882a593Smuzhiyun exit(1);
238*4882a593Smuzhiyun }
239*4882a593Smuzhiyun
vendor_len_mask(int cmd,int len,int cnt)240*4882a593Smuzhiyun static int vendor_len_mask(int cmd, int len, int cnt)
241*4882a593Smuzhiyun {
242*4882a593Smuzhiyun if (cnt != len) {
243*4882a593Smuzhiyun ERROR("%s must be %d bytes!!!\n",
244*4882a593Smuzhiyun vendor_id_table[cmd - 1], len);
245*4882a593Smuzhiyun return -1;
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun return 0;
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun
is_hex(char c)250*4882a593Smuzhiyun static bool is_hex(char c)
251*4882a593Smuzhiyun {
252*4882a593Smuzhiyun if (c < '0' || (c > '9' && c < 'A') ||
253*4882a593Smuzhiyun (c > 'F' && c < 'a') || c > 'f')
254*4882a593Smuzhiyun return false;
255*4882a593Smuzhiyun return true;
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun
char_to_hex(char c)258*4882a593Smuzhiyun static char char_to_hex(char c)
259*4882a593Smuzhiyun {
260*4882a593Smuzhiyun if (c >= '0' && c <= '9')
261*4882a593Smuzhiyun return c - '0';
262*4882a593Smuzhiyun else if (c >= 'a' && c <= 'f')
263*4882a593Smuzhiyun return c - ('a' - 10);
264*4882a593Smuzhiyun else
265*4882a593Smuzhiyun return c - ('A' - 10);
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun
hex_string_format(char * str,char * hex_str)268*4882a593Smuzhiyun static int hex_string_format(char *str, char *hex_str)
269*4882a593Smuzhiyun {
270*4882a593Smuzhiyun int i, tmp;
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun tmp = strlen(str);
273*4882a593Smuzhiyun if (tmp & 1)
274*4882a593Smuzhiyun return 0;
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun for (i = 0; i < tmp; i++) {
277*4882a593Smuzhiyun if (!is_hex(str[i])) {
278*4882a593Smuzhiyun ERROR("[%s] must be HEX input\n", __func__);
279*4882a593Smuzhiyun return 0;
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun /* string to hex */
283*4882a593Smuzhiyun str[i] = char_to_hex(str[i]);
284*4882a593Smuzhiyun if (i & 1)
285*4882a593Smuzhiyun hex_str[(i - 1) >> 1] = (str[i - 1] << 4) | str[i];
286*4882a593Smuzhiyun }
287*4882a593Smuzhiyun hex_str[i >> 1] = 0;
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun return i >> 1;
290*4882a593Smuzhiyun }
291*4882a593Smuzhiyun
vendor_get_custom_id(char * cmd)292*4882a593Smuzhiyun static int vendor_get_custom_id(char *cmd)
293*4882a593Smuzhiyun {
294*4882a593Smuzhiyun int id;
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun /* Check vendor_custom_id */
297*4882a593Smuzhiyun if (cmd[VENDOR_CMD_CUSTOM_LEN - 1] != '_' ||
298*4882a593Smuzhiyun !is_hex(cmd[VENDOR_CMD_CUSTOM_LEN]) ||
299*4882a593Smuzhiyun !is_hex(cmd[VENDOR_CMD_CUSTOM_LEN + 1])) {
300*4882a593Smuzhiyun goto head_error;
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun id = (char_to_hex(cmd[VENDOR_CMD_CUSTOM_LEN]) << 4) |
304*4882a593Smuzhiyun char_to_hex(cmd[VENDOR_CMD_CUSTOM_LEN + 1]);
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun return id;
307*4882a593Smuzhiyun head_error:
308*4882a593Smuzhiyun return -1;
309*4882a593Smuzhiyun }
310*4882a593Smuzhiyun
vendor_storage_get_id(char * cmd)311*4882a593Smuzhiyun static int vendor_storage_get_id(char *cmd)
312*4882a593Smuzhiyun {
313*4882a593Smuzhiyun int i, id;
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun for (i = 0; i < VENDOR_ID_MAX; i++) {
316*4882a593Smuzhiyun if (!memcmp(optarg, vendor_id_table[i], strlen(vendor_id_table[i]))) {
317*4882a593Smuzhiyun if (i == (VENDOR_CUSTOM_ID - 1)) {
318*4882a593Smuzhiyun id = vendor_get_custom_id(optarg);
319*4882a593Smuzhiyun if (id < 0) {
320*4882a593Smuzhiyun usage();
321*4882a593Smuzhiyun return -1;
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun } else {
324*4882a593Smuzhiyun id = i + 1;
325*4882a593Smuzhiyun }
326*4882a593Smuzhiyun break;
327*4882a593Smuzhiyun }
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun if (i == VENDOR_ID_MAX)
331*4882a593Smuzhiyun return -1;
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun return id;
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun #define OPTION_FLAG_R (0)
337*4882a593Smuzhiyun #define OPTION_FLAG_W (!0)
main(int argc,char ** argv)338*4882a593Smuzhiyun int main(int argc, char **argv)
339*4882a593Smuzhiyun {
340*4882a593Smuzhiyun int opt, i;
341*4882a593Smuzhiyun int id = -1;
342*4882a593Smuzhiyun int pr_type = -1;
343*4882a593Smuzhiyun int flag_rw, flag_file = 0;
344*4882a593Smuzhiyun unsigned char *vendor_hex = NULL;
345*4882a593Smuzhiyun FILE *finput = NULL;
346*4882a593Smuzhiyun long int size;
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun argv0 = argv[0];
349*4882a593Smuzhiyun while ((opt = getopt(argc, argv, "hRr:w:t:i:")) > 0) {
350*4882a593Smuzhiyun switch (opt) {
351*4882a593Smuzhiyun case 'r':
352*4882a593Smuzhiyun id = vendor_storage_get_id(optarg);
353*4882a593Smuzhiyun if (id < 0) {
354*4882a593Smuzhiyun ERROR("form_error, check cmd with -h\n");
355*4882a593Smuzhiyun return -1;
356*4882a593Smuzhiyun }
357*4882a593Smuzhiyun flag_rw = OPTION_FLAG_R;
358*4882a593Smuzhiyun break;
359*4882a593Smuzhiyun case 'R':
360*4882a593Smuzhiyun /* Read Common Vendor ID */
361*4882a593Smuzhiyun for (i = 0; i < VENDOR_HDCP_2x_ID; i++) {
362*4882a593Smuzhiyun GET_PR_FORMAT(i + 1, pr_type);
363*4882a593Smuzhiyun vendor_storage_read(i + 1, pr_type, NULL);
364*4882a593Smuzhiyun }
365*4882a593Smuzhiyun return 0;
366*4882a593Smuzhiyun break;
367*4882a593Smuzhiyun case 'w':
368*4882a593Smuzhiyun id = vendor_storage_get_id(optarg);
369*4882a593Smuzhiyun if (id < 0) {
370*4882a593Smuzhiyun ERROR("form_error, check cmd with -h\n");
371*4882a593Smuzhiyun return -1;
372*4882a593Smuzhiyun }
373*4882a593Smuzhiyun flag_rw = OPTION_FLAG_W;
374*4882a593Smuzhiyun break;
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun case 't':
377*4882a593Smuzhiyun if (!memcmp(optarg, "string", strlen("string"))) {
378*4882a593Smuzhiyun pr_type = VENDOR_PR_STRING;
379*4882a593Smuzhiyun } else if (!memcmp(optarg, "hex", strlen("hex"))) {
380*4882a593Smuzhiyun pr_type = VENDOR_PR_HEX;
381*4882a593Smuzhiyun } else {
382*4882a593Smuzhiyun pr_type = VENDOR_PR_HEX;
383*4882a593Smuzhiyun flag_file = 1;
384*4882a593Smuzhiyun }
385*4882a593Smuzhiyun break;
386*4882a593Smuzhiyun case 'i':
387*4882a593Smuzhiyun vendor_hex = strdup(optarg);
388*4882a593Smuzhiyun DEBUG("intput = %s\n", vendor_hex);
389*4882a593Smuzhiyun break;
390*4882a593Smuzhiyun case 'h':
391*4882a593Smuzhiyun usage();
392*4882a593Smuzhiyun break;
393*4882a593Smuzhiyun default:
394*4882a593Smuzhiyun ERROR("Unknown option: %c\n", opt);
395*4882a593Smuzhiyun usage();
396*4882a593Smuzhiyun break;
397*4882a593Smuzhiyun }
398*4882a593Smuzhiyun }
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun if (id < 0) {
401*4882a593Smuzhiyun ERROR("Set id first\n");
402*4882a593Smuzhiyun goto error;
403*4882a593Smuzhiyun }
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun if (id <= VENDOR_HDCP_2x_ID) {
406*4882a593Smuzhiyun GET_PR_FORMAT(id, pr_type);
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun if (pr_type < 0) {
410*4882a593Smuzhiyun INFO("Set hex output default\n");
411*4882a593Smuzhiyun pr_type = VENDOR_PR_HEX;
412*4882a593Smuzhiyun }
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun if (!vendor_hex && (flag_rw & OPTION_FLAG_W)) {
415*4882a593Smuzhiyun ERROR("No input\n");
416*4882a593Smuzhiyun goto error;
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun if (flag_rw == OPTION_FLAG_R) {
420*4882a593Smuzhiyun vendor_storage_read(id, pr_type,
421*4882a593Smuzhiyun flag_file ? vendor_hex: NULL);
422*4882a593Smuzhiyun } else {
423*4882a593Smuzhiyun if (flag_file) {
424*4882a593Smuzhiyun finput = fopen(vendor_hex, "rb");
425*4882a593Smuzhiyun if (!finput) {
426*4882a593Smuzhiyun ERROR("Can't open %s\n", vendor_hex);
427*4882a593Smuzhiyun goto error;
428*4882a593Smuzhiyun }
429*4882a593Smuzhiyun free(vendor_hex);
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun fseek(finput, 0, SEEK_END);
432*4882a593Smuzhiyun size = ftell(finput);
433*4882a593Smuzhiyun DEBUG("size = %d\n", size);
434*4882a593Smuzhiyun fseek(finput, 0, SEEK_SET);
435*4882a593Smuzhiyun vendor_hex = malloc(size + 1);
436*4882a593Smuzhiyun fread(vendor_hex, 1, size, finput);
437*4882a593Smuzhiyun } else if (pr_type == VENDOR_PR_HEX) {
438*4882a593Smuzhiyun size = hex_string_format(vendor_hex, vendor_hex);
439*4882a593Smuzhiyun if (!size) {
440*4882a593Smuzhiyun ERROR("input is not hex form\n");
441*4882a593Smuzhiyun goto error;
442*4882a593Smuzhiyun }
443*4882a593Smuzhiyun } else if (pr_type == VENDOR_PR_STRING) {
444*4882a593Smuzhiyun size = strlen(vendor_hex);
445*4882a593Smuzhiyun }
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun vendor_storage_write(id, vendor_hex, pr_type, size);
448*4882a593Smuzhiyun }
449*4882a593Smuzhiyun
450*4882a593Smuzhiyun if (finput)
451*4882a593Smuzhiyun fclose(finput);
452*4882a593Smuzhiyun if (vendor_hex)
453*4882a593Smuzhiyun free(vendor_hex);
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun return 0;
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun error_file:
458*4882a593Smuzhiyun if (finput)
459*4882a593Smuzhiyun fclose(finput);
460*4882a593Smuzhiyun error:
461*4882a593Smuzhiyun if (vendor_hex)
462*4882a593Smuzhiyun free(vendor_hex);
463*4882a593Smuzhiyun return -1;
464*4882a593Smuzhiyun }
465*4882a593Smuzhiyun #endif
466*4882a593Smuzhiyun
467*4882a593Smuzhiyun #ifdef BUILD_LIB_VENDOR_STORAGE
rkvendor_read(int vendor_id,char * data,int size)468*4882a593Smuzhiyun int rkvendor_read(int vendor_id, char *data, int size)
469*4882a593Smuzhiyun {
470*4882a593Smuzhiyun int ret ;
471*4882a593Smuzhiyun uint8 p_buf[sizeof(struct rk_vendor_req)]; /* malloc req buffer or used extern buffer */
472*4882a593Smuzhiyun struct rk_vendor_req *req;
473*4882a593Smuzhiyun
474*4882a593Smuzhiyun req = (struct rk_vendor_req *)p_buf;
475*4882a593Smuzhiyun memset(p_buf, 0, sizeof(struct rk_vendor_req));
476*4882a593Smuzhiyun int sys_fd = open("/dev/vendor_storage", O_RDONLY);
477*4882a593Smuzhiyun if(sys_fd < 0){
478*4882a593Smuzhiyun fprintf(stderr, "vendor_storage open fail\n");
479*4882a593Smuzhiyun return -1;
480*4882a593Smuzhiyun }
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun req->tag = VENDOR_REQ_TAG;
483*4882a593Smuzhiyun req->id = vendor_id;
484*4882a593Smuzhiyun req->len = VENDOR_MAX_SIZE;
485*4882a593Smuzhiyun
486*4882a593Smuzhiyun ret = ioctl(sys_fd, VENDOR_READ_IO, req);
487*4882a593Smuzhiyun close(sys_fd);
488*4882a593Smuzhiyun if (ret) {
489*4882a593Smuzhiyun fprintf(stderr, "vendor read error %d\n", ret);
490*4882a593Smuzhiyun return -1;
491*4882a593Smuzhiyun }
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun if ( size < req->len ) {
494*4882a593Smuzhiyun fprintf(stderr, "vendor storage: param size is lower then read size %d\n", strlen(req->data) );
495*4882a593Smuzhiyun return -1;
496*4882a593Smuzhiyun }
497*4882a593Smuzhiyun
498*4882a593Smuzhiyun memcpy(data, req->data, req->len);
499*4882a593Smuzhiyun return 0;
500*4882a593Smuzhiyun }
501*4882a593Smuzhiyun
rkvendor_write(int vendor_id,const char * data,int size)502*4882a593Smuzhiyun int rkvendor_write(int vendor_id, const char *data, int size)
503*4882a593Smuzhiyun {
504*4882a593Smuzhiyun int ret ;
505*4882a593Smuzhiyun uint8 p_buf[sizeof(struct rk_vendor_req)]; /* malloc req buffer or used extern buffer */
506*4882a593Smuzhiyun struct rk_vendor_req *req;
507*4882a593Smuzhiyun
508*4882a593Smuzhiyun if (size > VENDOR_MAX_SIZE) {
509*4882a593Smuzhiyun fprintf(stderr, "vendor storage input data overflow\n");
510*4882a593Smuzhiyun return -1;
511*4882a593Smuzhiyun }
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun req = (struct rk_vendor_req *)p_buf;
514*4882a593Smuzhiyun int sys_fd = open("/dev/vendor_storage",O_RDWR,0);
515*4882a593Smuzhiyun if (sys_fd < 0) {
516*4882a593Smuzhiyun fprintf(stderr, "vendor storage open fail\n");
517*4882a593Smuzhiyun return -1;
518*4882a593Smuzhiyun }
519*4882a593Smuzhiyun
520*4882a593Smuzhiyun req->tag = VENDOR_REQ_TAG;
521*4882a593Smuzhiyun req->id = vendor_id;
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun req->len = size;
524*4882a593Smuzhiyun memcpy(req->data, data, req->len);
525*4882a593Smuzhiyun
526*4882a593Smuzhiyun ret = ioctl(sys_fd, VENDOR_WRITE_IO, req);
527*4882a593Smuzhiyun close(sys_fd);
528*4882a593Smuzhiyun if (ret) {
529*4882a593Smuzhiyun fprintf(stderr, "vendor write error\n");
530*4882a593Smuzhiyun return -1;
531*4882a593Smuzhiyun }
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun return 0;
534*4882a593Smuzhiyun }
535*4882a593Smuzhiyun #endif
536