xref: /OK3568_Linux_fs/external/rktoolkit/vendor_storage.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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