blob: c51dbb1227d7d6ae697bf252473e02873368a61a [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/* Copyright Statement:
2 *
3 * This software/firmware and related documentation ("MediaTek Software") are
4 * protected under relevant copyright laws. The information contained herein is
5 * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
6 * the prior written permission of MediaTek inc. and/or its licensors, any
7 * reproduction, modification, use or disclosure of MediaTek Software, and
8 * information contained herein, in whole or in part, shall be strictly
9 * prohibited.
10 *
11 * MediaTek Inc. (C) 2016~2017. All rights reserved.
12 *
13 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
14 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
15 * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
16 * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
17 * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
19 * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
20 * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
21 * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
22 * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
23 * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
24 * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
25 * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
26 * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
27 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
28 * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
29 * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
30 * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
31 * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
32 *
33 * The following software/firmware and/or related documentation ("MediaTek
34 * Software") have been modified by MediaTek Inc. All revisions are subject to
35 * any receiver's applicable license agreements with MediaTek Inc.
36 */
37
38//- vim: set ts=4 sts=4 sw=4 et: --------------------------------------------
39#include <sys/types.h>
40#include <sys/stat.h>
41#include <fcntl.h>
42#include <stdarg.h>
43#include <errno.h>
44
45#include "boots_pkt.h"
46
47//---------------------------------------------------------------------------
48#define LOG_TAG "boots_script"
49
50#define LINESIZE 8192
51#define LINEVALUESIZE 4096
52
53#define SCRIPTLINE(name) {#name, SCRIPT_##name, sizeof(#name)-1, FUN_##name}
54
55//---------------------------------------------------------------------------
56typedef struct per_cmd_info {
57 char *name;
58 uint8_t scriptType;
59 int nameLen;
60 void* (*func_cmd)(int, char*, uint8_t*, void **, int *); // reserved.now, only print log, if needed to preprocess cmd, please register for each one
61} S_per_cmd_info;
62
63//---------------------------------------------------------------------------
64static void* FUN_TITLE(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen);
65static void* FUN_PROC(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen);
66static void* FUN_TX(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen);
67static void* FUN_RX(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen);
68static void* FUN_WAITRX(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen);
69static void* FUN_LOOP(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen);
70static void* FUN_LOOPEND(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen);
71static void* FUN_TIMEOUT(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen);
72static void* FUN_WAIT(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen);
73static void* FUN_USBALT(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen);
74static void* FUN_CMD(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen);
75static void* FUN_END(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen);
76
77//---------------------------------------------------------------------------
78static S_per_cmd_info script_line_s[] = {
79 SCRIPTLINE(TITLE),
80 SCRIPTLINE(PROC),
81 SCRIPTLINE(TX),
82 SCRIPTLINE(RX),
83 SCRIPTLINE(WAITRX),
84 SCRIPTLINE(LOOPEND), /* should be ahead of LOOP */
85 SCRIPTLINE(LOOP),
86 SCRIPTLINE(WAIT),
87 SCRIPTLINE(TIMEOUT),
88 SCRIPTLINE(USBALT),
89 SCRIPTLINE(TIMEOUT),
90 SCRIPTLINE(CMD),
91 SCRIPTLINE(END)
92};
93
94static int script_line_num = sizeof(script_line_s)/sizeof(S_per_cmd_info);
95
96static uint8_t packet_value_array[LINEVALUESIZE];
97static int paramValue = 0;
98
99static char *line = NULL;
100
101//---------------------------------------------------------------------------
102#if 0
103static char hextoascii(int i)
104{
105 i &= 0x0F;
106
107 if (i >= 0 && i <= 9)
108 return i + '0';
109 else
110 return i + ('A' - 0x0A);
111}
112
113static int print_hexes(char *hex, int len)
114{
115 int i;
116 printf("\tFormat in HEX -- ");
117 for (i = 0; i < len; i++, hex++) {
118 putchar(hextoascii(*hex >> 4));
119 putchar(hextoascii(*hex & 0x0f));
120 putchar(' ');
121 }
122 putchar('\r');
123 putchar('\n');
124 return 0;
125}
126
127static char* xitoa(int val, int base)
128{
129 static char sbuf[32] = {0};
130 int i = 30;
131 for(; val && i; --i, val /= base)
132 {
133 sbuf[i]="0123456789abcdef"[val % base];
134 }
135 return &sbuf[i+1];
136}
137#endif
138
139static uint8_t xatoi(char *p, int len)
140{
141 int n= 0;
142 uint8_t v = 0;
143
144 for(n=0; n<len; n++){
145 if((*p>='0')&&(*p<='9')) v = v*16 + (*p-'0');
146 else if((*p>='A')&&(*p<='F')) v = v*16 + (10+*p-'A');
147 else if((*p>='a')&&(*p<='f')) v = v*16 + (10+*p-'a');
148 else return(-1);
149 p++;
150 }
151 return v;
152}
153
154static void filter_space_c(char** ppStr, int head_filter, int tail_filter)
155{
156 char* str;
157 int start, end, strLen;
158
159 if (ppStr != NULL && *ppStr != NULL){
160 str = *ppStr;
161 //1. head fliter
162 if ((head_filter == 1) && (*str != '\0')){
163 for (start=0; *str==' '; start++){
164 str++;
165 }
166 }
167 //2. tail filter
168 if ((tail_filter == 1) && (*str != '\0')){
169 strLen = strlen(str);
170 for (end = strLen - 1; end >= 0 && str[end]==' '; end--){
171 str[end] = '\0';
172 }
173 }
174 *ppStr = str;
175 }
176}
177
178static int packet_safe_atoi(char valueStr[], uint8_t value[], int size)
179{
180 char *token = NULL, *savepStr=NULL;
181 uint8_t *valueIs = value;
182 int i = 0, repeat = 0, split_num = 0, len = 0;
183 int num = 0;
184 int ret = 0;
185
186 if (size > LINEVALUESIZE) {
187 BPRINT_W("Incorrect size %d", size);
188 size = LINEVALUESIZE;
189 }
190
191 memset(valueIs, 0, size);
192
193 token=strtok_r(valueStr, " ", &savepStr);
194 while(token != NULL){
195 len = strlen(token);
196 repeat = len/2 + len%2;
197 do{
198 split_num = ((len >= 2)?(2):(1));
199 ret = xatoi((token + i * 2), split_num);
200 if (ret < 0) {
201 BPRINT_E("Illegal string(%s), abort <\n", token + i*2);
202 num = 0;
203 break;
204 } else {
205 valueIs[num] = ret;
206 }
207 ++num;
208 ++i;
209 len -= i*2;
210 }while((--repeat) > 0);
211
212 if(num > 0){
213 token=strtok_r(NULL, " ", &savepStr);
214 i = 0;
215 }
216 else{
217 break;
218 }
219 }
220/*
221 if(num != 0){
222 int i = 0, tmpN = num;
223 printf("packet[num==%d]>", num);
224 while(tmpN){
225 printf("%02x", valueIs[i]);
226 printf(" ");
227 --tmpN;
228 ++i;
229 }
230 printf("\n");
231 }
232*/
233 return num;
234}
235
236static void* FUN_TITLE(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen)
237{
238 *opktType = 0;
239 *oLen = ((Invalue == NULL)?0:(strlen(Invalue) + 1));
240 *oValue = (void*)((*oLen == 0)?NULL:Invalue);
241
242 BPRINT_D("lineName>%s<Type>0x%02x-0x%02x<",
243 script_line_s[InfoundIndex].name, script_line_s[InfoundIndex].scriptType, *opktType);
244
245 return (void*)NULL;
246}
247
248
249static void* FUN_PROC(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen)
250{
251 *opktType = 0;
252 *oLen = ((Invalue == NULL)?0:(strlen(Invalue) + 1));
253 *oValue = (void*)((*oLen == 0)?NULL:Invalue);
254
255 BPRINT_D("lineName>%s<Type>0x%02x-0x%02x<",
256 script_line_s[InfoundIndex].name, script_line_s[InfoundIndex].scriptType, *opktType);
257
258 return (void*)NULL;
259}
260
261static void* FUN_TX(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen)
262{
263 *opktType = ((Invalue != NULL)?(xatoi(Invalue, 2)):(0));
264 *oLen = 0;
265 *oValue = NULL;
266
267 if((Invalue != NULL)){
268 *oLen = packet_safe_atoi(Invalue, packet_value_array, sizeof(packet_value_array));
269 if (*oLen > 0){
270 *oValue = packet_value_array;
271 }
272 else{
273 *oLen = 0;
274 *oValue = NULL;
275 }
276 }
277
278 BPRINT_D("lineName>%s<Type>0x%02x-0x%02x<",
279 script_line_s[InfoundIndex].name, script_line_s[InfoundIndex].scriptType, *opktType);
280
281 return (void*)NULL;
282}
283
284static void* FUN_RX(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen)
285{
286 *opktType = ((Invalue != NULL)?(xatoi(Invalue, 2)):(0));
287 *oLen = 0;
288 *oValue = NULL;
289
290 if((Invalue != NULL)){
291 *oLen = packet_safe_atoi(Invalue, packet_value_array, sizeof(packet_value_array));
292 if (*oLen > 0){
293 *oValue = packet_value_array;
294 }
295 else{
296 *oLen = 0;
297 *oValue = NULL;
298 }
299 }
300
301 BPRINT_D("lineName>%s<Type>0x%02x-0x%02x<",
302 script_line_s[InfoundIndex].name, script_line_s[InfoundIndex].scriptType, *opktType);
303
304 return (void*)NULL;
305}
306
307static void* FUN_WAITRX(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen)
308{
309 *opktType = ((Invalue != NULL)?(xatoi(Invalue, 2)):(0));
310 *oLen = 0;
311 *oValue = NULL;
312
313 if((Invalue != NULL)){
314 *oLen = packet_safe_atoi(Invalue, packet_value_array, sizeof(packet_value_array));
315 if (*oLen > 0){
316 *oValue = packet_value_array;
317 }
318 else{
319 *oLen = 0;
320 *oValue = NULL;
321 }
322 }
323
324 BPRINT_D("lineName>%s<Type>0x%02x-0x%02x<",
325 script_line_s[InfoundIndex].name, script_line_s[InfoundIndex].scriptType, *opktType);
326
327 return (void*)NULL;
328}
329
330
331static void* FUN_LOOP(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen)
332{
333 *opktType = 0;
334 *oLen = 1;
335 paramValue = ((*oLen == 0)?(0):(atoi(Invalue)));
336 *oValue = &paramValue;
337
338 BPRINT_D("lineName>%s<Type>0x%02x-0x%02x<LOOP Count>%d",
339 script_line_s[InfoundIndex].name, script_line_s[InfoundIndex].scriptType, *opktType, *((int*)(*oValue)));
340
341 return (void*)NULL;
342}
343
344
345static void* FUN_LOOPEND(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen)
346{
347 *opktType = 0;
348 *oLen = 0;
349 *oValue = NULL;
350 UNUSED(Invalue);
351
352 BPRINT_D("lineName>%s<Type>0x%02x-0x%02x<",
353 script_line_s[InfoundIndex].name, script_line_s[InfoundIndex].scriptType, *opktType);
354
355 return (void*)NULL;
356}
357
358
359static void* FUN_TIMEOUT(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen)
360{
361 *opktType = 0;
362 *oLen = 1;
363 paramValue = ((*oLen == 0)?(0):(atoi(Invalue)));
364 *oValue = &paramValue;
365
366 BPRINT_D("lineName>%s<Type>0x%02x-0x%02x<TIMEOUT>%d",
367 script_line_s[InfoundIndex].name, script_line_s[InfoundIndex].scriptType, *opktType, *((int*)(*oValue)));
368
369 return (void*)NULL;
370}
371
372
373static void* FUN_WAIT(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen)
374{
375 *opktType = 0;
376 *oLen = ((Invalue == NULL)?0:(strlen(Invalue) + 1));
377 paramValue = ((*oLen == 0)?(0):(atoi(Invalue)));
378 *oValue = &paramValue;
379
380 BPRINT_D("lineName>%s<Type>0x%02x-0x%02x<WAIT>%d",
381 script_line_s[InfoundIndex].name, script_line_s[InfoundIndex].scriptType, *opktType, *((int*)(*oValue)));
382
383 return (void*)NULL;
384}
385
386
387static void* FUN_USBALT(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen)
388{
389 *opktType = 0;
390 *oLen = 1;
391 paramValue = ((*oLen == 0)?(0):(atoi(Invalue)));
392 *oValue = &paramValue;
393
394 BPRINT_D("lineName>%s<Type>0x%02x-0x%02x<USBALT>%d",
395 script_line_s[InfoundIndex].name, script_line_s[InfoundIndex].scriptType, *opktType, *((int*)(*oValue)));
396
397 return (void*)NULL;
398}
399
400
401static void* FUN_CMD(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen)
402{
403 *opktType = 0x01;
404 *oLen = 0;
405 *oValue = NULL;
406
407 if((Invalue != NULL)){
408 *oLen = packet_safe_atoi(Invalue, &(packet_value_array[1]), sizeof(packet_value_array) - 1);
409 if (*oLen > 0){
410 packet_value_array[0] = 0x01;
411 *oLen += 1;
412 *oValue = packet_value_array;
413 }
414 else{
415 *oLen = 0;
416 *oValue = NULL;
417 }
418 }
419
420 BPRINT_D("lineName>%s<packetType>0x%02x<", script_line_s[InfoundIndex].name, script_line_s[InfoundIndex].scriptType);
421 return (void*)NULL;
422}
423
424static void* FUN_END(int InfoundIndex, char* Invalue, uint8_t* opktType, void** oValue, int* oLen)
425{
426 *opktType = 0;
427 *oLen = 0;
428 *oValue = NULL;
429 UNUSED(Invalue);
430
431 BPRINT_D("lineName>%s<packetType>0x%02x<", script_line_s[InfoundIndex].name, script_line_s[InfoundIndex].scriptType);
432 return (void*)NULL;
433}
434
435
436static pkt_list_s *script_line_handle(char *lineName, char *lineValue)
437{
438 int i;
439 uint8_t pktType = 0;
440 void *value = NULL;
441 int valueLen;
442 UNUSED(boots_btif);
443
444 for(i = 0 ;i < script_line_num; i++){
445 if(!strncmp(lineName, script_line_s[i].name, script_line_s[i].nameLen)){
446 script_line_s[i].func_cmd(i, lineValue, &pktType, &value, &valueLen);
447#if 0
448 int num;
449 switch (script_line_s[i].scriptType) {
450 case SCRIPT_TX:
451 case SCRIPT_RX:
452 case SCRIPT_WAITRX:
453 case SCRIPT_CMD:
454 num = 0;
455 printf("[boots_script:D] TYPE = %02x < ", script_line_s[i].scriptType);
456 while(num < valueLen){
457 printf("%02x ", *((uint8_t*)value + num));
458 ++num;
459 }
460 printf("\n");
461 break;
462 case SCRIPT_TITLE:
463 case SCRIPT_PROC:
464 BPRINT_D("TYPE = %02x < %s", script_line_s[i].scriptType, (char*)value);
465 break;
466 case SCRIPT_LOOP:
467 BPRINT_D("TYPE = %02x < %d", script_line_s[i].scriptType, *((int*)value));
468 break;
469 case SCRIPT_TIMEOUT:
470 BPRINT_D("TYPE = %02x < %d", script_line_s[i].scriptType, *((int*)value));
471 break;
472 case SCRIPT_WAIT:
473 BPRINT_D("TYPE = %02x < %d", script_line_s[i].scriptType, *((int*)value));
474 break;
475 case SCRIPT_USBALT:
476 BPRINT_D("TYPE = %02x < %d", script_line_s[i].scriptType, *((int*)value));
477 break;
478 default:
479 break;
480 }
481#endif
482 return boots_pkt_node_push(script_line_s[i].scriptType, pktType, value, valueLen, NULL, NULL);
483 }
484
485 }
486 return NULL;
487}
488
489static pkt_list_s *script_line_parse(char *line)
490{
491 char *tmpStr = line;
492 char *delimStr = ":=";
493 char *subdelimStr = "//";
494 char *lineName, *lineValue;//, *lineAnno;
495 char *saveptr;
496 int slen;
497
498 // 1. filter out space until found out a char
499 filter_space_c(&tmpStr, 1, 0);
500
501 // 2. filter out annotation line
502 if ((*tmpStr == '#') || (strncmp(tmpStr, "//", 2) == 0)) {
503 // do nothing, just ignore
504
505 } else {
506 slen = strlen(tmpStr);
507 // 3. filter out new line('\n' 0A) & carriage ret ('\r' 0D)
508 if (tmpStr[slen - 1] == 0x0A) {
509 tmpStr[slen - 1] = '\0';
510 if (tmpStr[slen - 2] == 0x0D) {
511 tmpStr[slen - 2] = '\0';
512 }
513 }
514 slen = strlen(tmpStr);
515
516 if (slen == 0) {
517 // do nothing--only ignore
518 } else {
519 //BPRINT_D("line <%s>", tmpStr);
520 // 4. parse
521 lineName = strtok_r(tmpStr, delimStr, &saveptr);
522 if (lineName != NULL) {
523 lineValue = strtok_r(saveptr, subdelimStr, &lineValue);
524 } else {
525 return NULL;
526 }
527 //BPRINT_D("orgName <%s>", lineName);
528 //BPRINT_D("orgValue <%s>", lineValue);
529 //BPRINT_D("filter out space ...");
530
531 // 5. filter out space
532 filter_space_c(&lineName, 1, 1);
533 filter_space_c(&lineValue, 1, 1);
534
535 //BPRINT_D("newName <%s>", lineName);
536 //BPRINT_D("newValue <%s>", lineValue);
537
538 // 6. map Type and create node
539 return script_line_handle(lineName, lineValue);
540 }
541 }
542 return NULL;
543}
544
545//---------------------------------------------------------------------------
546FILE *boots_script_open(char *file)
547{
548 BPRINT_D("%s: %s", __func__, file);
549 return fopen(file, "r");
550}
551
552//---------------------------------------------------------------------------
553void boots_script_close(FILE *fd)
554{
555 if (line) {
556 free(line);
557 line = NULL;
558 }
559 if (fd) fclose(fd);
560}
561
562//---------------------------------------------------------------------------
563pkt_list_s *boots_script_get(FILE *fd)
564{
565 pkt_list_s *n = NULL;
566 char *buf = NULL;
567 size_t buf_size = 0;
568 ssize_t nread;
569
570 if (!fd) return NULL;
571
572 do {
573 if ((nread = getline(&buf, &buf_size, fd)) < 0)
574 break;
575 n = script_line_parse(buf);
576
577 } while (!n || nread == 0);
578
579 free(buf);
580
581 return n;
582}
583
584//---------------------------------------------------------------------------
585void boots_script_loop(FILE * fd, long size)
586{
587 (void)fseek(fd, size, SEEK_SET);
588}
589
590//---------------------------------------------------------------------------