4
4
#include " setting.h"
5
5
#include " usb_configuration.h"
6
6
#include " HSLink_Pro_expansion.h"
7
+ #include " fal.h"
8
+ #include " fal_cfg.h"
9
+ #include < b64.h>
10
+ #include " crc32.h"
11
+
12
+ #define LOG_TAG " HID_COMM"
13
+ #include " elog.h"
7
14
8
15
#ifdef CONFIG_USE_HID_CONFIG
9
16
13
20
14
21
using namespace rapidjson ;
15
22
16
- #include < unordered_map>
17
23
#include < functional>
24
+ #include < unordered_map>
18
25
19
26
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t HID_read_buffer[HID_PACKET_SIZE];
20
27
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t HID_write_buffer[HID_PACKET_SIZE];
@@ -34,6 +41,8 @@ const char *response_str[] = {
34
41
" failed"
35
42
};
36
43
44
+ std::string_view filed_miss_msg = " Some fields are missing" ;
45
+
37
46
static volatile HID_State_t HID_ReadState = HID_STATE_BUSY;
38
47
39
48
/* !< custom hid report descriptor */
@@ -93,6 +102,26 @@ struct usbd_endpoint hid_custom_out_ep = {
93
102
.ep_cb = usbd_hid_custom_out_callback,
94
103
};
95
104
105
+ static bool CheckField (const Value &object, std::pair<std::string_view, Type> field) {
106
+ auto &[field_name, field_type] = field;
107
+ if (!object.HasMember (field_name.data ())) {
108
+ return false ;
109
+ }
110
+ if (object[field_name.data ()].GetType () != field_type) {
111
+ return false ;
112
+ }
113
+ return true ;
114
+ }
115
+
116
+ static bool CheckFields (const Value &object, std::vector<std::pair<std::string_view, Type>> fields) {
117
+ for (auto &field: fields) {
118
+ if (!CheckField (object, field)) {
119
+ return false ;
120
+ }
121
+ }
122
+ return true ;
123
+ }
124
+
96
125
static void FillStatus (HID_Response_t status, char *res, const char *message) {
97
126
StringBuffer buffer;
98
127
Writer writer (buffer);
@@ -105,6 +134,10 @@ static void FillStatus(HID_Response_t status, char *res, const char *message) {
105
134
std::strcpy (res, buffer.GetString ());
106
135
}
107
136
137
+ static void FillStatus (HID_Response_t status, char *res, std::string_view message) {
138
+ FillStatus (status, res, message.data ());
139
+ }
140
+
108
141
static void FillStatus (HID_Response_t status, char *res) {
109
142
FillStatus (status, res, " " );
110
143
}
@@ -327,6 +360,151 @@ static void get_setting(Document &root, char *res) {
327
360
std::strcpy (res, buffer.GetString ());
328
361
}
329
362
363
+ static void erase_bl_b (Document &root, char *res) {
364
+ fal_partition_erase (bl_b_part,0 , bl_b_part->len );
365
+ FillStatus (HID_RESPONSE_SUCCESS, res);
366
+ }
367
+
368
+ static void write_bl_b (Document &root, char *res) {
369
+ #define PACK_SIZE 512
370
+ if (!CheckFields (root,
371
+ {{" addr" , Type::kNumberType },
372
+ {" len" , Type::kNumberType },
373
+ {" data" , Type::kStringType }})) {
374
+ FillStatus (HID_RESPONSE_FAILED, res, filed_miss_msg);
375
+ return ;
376
+ }
377
+ auto addr = root[" addr" ].GetInt ();
378
+ auto len = root[" len" ].GetInt ();
379
+ auto data_b64 = root[" data" ].GetString ();
380
+ auto data_b64_len = root[" data" ].GetStringLength ();
381
+ log_d (" addr: 0x%X, len: %d, data_len: %d" , addr, len, data_b64_len);
382
+ // elog_hexdump("b64", 16, data_b64, data_b64_len);
383
+ if (addr + len > bl_b_part->len ) {
384
+ const char *message = " addr out of range" ;
385
+ USB_LOG_WRN (" %s\n " , message);
386
+ FillStatus (HID_RESPONSE_FAILED, res, message);
387
+ return ;
388
+ }
389
+ if (len % 4 != 0 ) {
390
+ char msg[64 ];
391
+ snprintf (msg, sizeof (msg), " len %d not multiple of 4" , len);
392
+ log_w (msg);
393
+ FillStatus (HID_RESPONSE_FAILED, res, msg);
394
+ return ;
395
+ }
396
+ if (addr % 512 != 0 ) {
397
+ log_w (" addr %d not multiple of 512" , addr);
398
+ return ;
399
+ }
400
+ log_i (" addr: 0x%X, len: %d" , addr, len);
401
+ size_t data_len = 0 ;
402
+ uint8_t *data = b64_decode_ex (data_b64, data_b64_len, &data_len);
403
+ log_d (" solve b64 data_len: %d" , data_len);
404
+ // elog_hexdump(LOG_TAG, 16, data, data_len);
405
+ if (data_len != len) {
406
+ log_w (" data_len != len" );
407
+ FillStatus (HID_RESPONSE_FAILED, res, " data_len != len" );
408
+ return ;
409
+ }
410
+ if (data_len > PACK_SIZE) {
411
+ char msg[64 ];
412
+ snprintf (msg, sizeof (msg), " data_len %d > %d" , data_len, PACK_SIZE);
413
+ log_w (msg);
414
+ FillStatus (HID_RESPONSE_FAILED, res, msg);
415
+ return ;
416
+ }
417
+ fal_partition_write (bl_b_part, addr, data, len);
418
+ log_i (" write %d bytes to 0x%X done" , len, addr + bl_b_part->offset );
419
+ FillStatus (HID_RESPONSE_SUCCESS, res);
420
+ free (data);
421
+ }
422
+
423
+ static void upgrade_bl (Document &root, char *res) {
424
+ if (!CheckFields (root,
425
+ {{" len" , Type::kNumberType },
426
+ {" crc" , Type::kStringType }})) {
427
+ FillStatus (HID_RESPONSE_FAILED, res, filed_miss_msg);
428
+ return ;
429
+ }
430
+ auto len = root[" len" ].GetInt ();
431
+ auto crc_str = root[" crc" ].GetString ();
432
+ auto crc = strtoul (crc_str + 2 , nullptr , 16 );
433
+ if (len > bl_b_part->len ) {
434
+ char msg[64 ];
435
+ snprintf (msg, sizeof (msg), " len %d > %d" , len, bl_b_part->len );
436
+ log_w (msg);
437
+ FillStatus (HID_RESPONSE_FAILED, res, msg);
438
+ return ;
439
+ }
440
+ if (len % 4 ) {
441
+ log_w (" len %% 4 != 0" );
442
+ FillStatus (HID_RESPONSE_FAILED, res, " len %% 4 != 0" );
443
+ return ;
444
+ }
445
+
446
+ {
447
+ uint32_t crc_calc = 0xFFFFFFFF ;
448
+ const uint32_t CRC_CALC_LEN = 8 * 1024 ;
449
+ auto buf = std::make_unique<uint8_t []>(CRC_CALC_LEN);
450
+ for (uint32_t i = 0 ; i < len; i += CRC_CALC_LEN) {
451
+ auto calc_len = std::min (CRC_CALC_LEN, len - i);
452
+ fal_partition_read (bl_b_part, i, buf.get (), calc_len);
453
+ crc_calc = CRC_CalcArray_Software (buf.get (), calc_len, crc_calc);
454
+ // log_d("crc calc 0x%x", crc_calc);
455
+ }
456
+ if (crc != crc_calc) {
457
+ log_w (" crc != crc_calc recv 0x%x calc 0x%x" , crc, crc_calc);
458
+ FillStatus (HID_RESPONSE_FAILED, res, " crc != crc_calc" );
459
+ return ;
460
+ }
461
+ }
462
+
463
+ log_d (" crc check pass, start copy..." );
464
+ {
465
+ constexpr uint32_t COPY_LEN = 4 * 1024 ;
466
+ auto buf = std::make_unique<uint8_t []>(COPY_LEN);
467
+ fal_partition_erase (bl_part, 0 , bl_part->len );
468
+ for (size_t i = 0 ; i < bl_part->len ; i += COPY_LEN) {
469
+ auto copy_len = std::min (COPY_LEN, (uint32_t )(bl_part->len - i));
470
+ log_d (" copy from 0x%X to 0x%X, size 0x%X" ,
471
+ i + bl_b_part->offset ,
472
+ i + bl_part->offset ,
473
+ copy_len);
474
+ fal_partition_read (bl_b_part, i, buf.get (), copy_len);
475
+ fal_partition_write (bl_part, i, buf.get (), copy_len);
476
+ }
477
+ }
478
+ log_d (" copy done" );
479
+ {
480
+ const uint32_t COMP_LEN = 1024 ;
481
+ auto buf_1 = std::make_unique<uint8_t []>(COMP_LEN);
482
+ auto buf_2 = std::make_unique<uint8_t []>(COMP_LEN);
483
+ for (size_t i = 0 ; i < bl_part->len ; i += COMP_LEN) {
484
+ auto comp_len = std::min (COMP_LEN, (uint32_t )(bl_part->len - i));
485
+ fal_partition_read (bl_b_part, i, buf_1.get (), comp_len);
486
+ fal_partition_read (bl_part, i, buf_2.get (), comp_len);
487
+ if (memcmp (buf_1.get (), buf_2.get (), comp_len) != 0 ) {
488
+ log_w (" copy fail at 0x%X" , i);
489
+ FillStatus (HID_RESPONSE_FAILED, res, " copy done check failed" );
490
+ log_d (" in b slot" );
491
+ elog_hexdump (LOG_TAG, 16 , buf_1.get (), comp_len);
492
+ log_d (" in bl" );
493
+ elog_hexdump (LOG_TAG, 16 , buf_2.get (), comp_len);
494
+ // TODO should we roll back bl? or copy it again?
495
+ }
496
+ }
497
+ }
498
+
499
+ log_d (" check done" );
500
+
501
+ FillStatus (HID_RESPONSE_SUCCESS, res);
502
+
503
+ board_delay_ms (1000 );
504
+
505
+ HSP_Reboot ();
506
+ }
507
+
330
508
static void HID_Write (const std::string &res) {
331
509
std::strcpy (reinterpret_cast <char *>(HID_write_buffer + 1 ), res.c_str ());
332
510
}
@@ -351,7 +529,10 @@ void HID_Handle() {
351
529
{" upgrade" , upgrade},
352
530
{" entry_sys_bl" , entry_sys_bl},
353
531
{" entry_hslink_bl" , entry_hslink_bl},
354
- {" set_hw_ver" , set_hw_ver}
532
+ {" set_hw_ver" , set_hw_ver},
533
+ {" erase_bl_b" , erase_bl_b},
534
+ {" write_bl_b" , write_bl_b},
535
+ {" upgrade_bl" , upgrade_bl}
355
536
};
356
537
357
538
Document root;
0 commit comments