• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Chipsea Technologies (Shenzhen) Corp., Ltd. All rights reserved.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*chipsea_ohos proguard begin*/
16 #include "cs_proguard.h"
17 /*chipsea_ohos proguard end*/
18 #include "app_ota_box.h"
19 #if PLF_BT_OTA
20 #include "dbg.h"
21 #include "co_main.h"
22 #include "app_bt_queue.h"
23 #include "flash_api.h"
24 #include "cs_ota.h"
25 #if PLF_PMIC
26 #include "pmic_api.h"
27 #endif
28 
29 #define OTA_PRINT(fmt, ...)       //dbg(fmt, ##__VA_ARGS__)
30 enum APP_OTA_ACCESS app_ota_access;
31 
32 #if APP_SUPPORT_OTA_BOX
33 #include "ff.h"
34 #include "system.h"
35 
36 
37 #define SDCARD_DRIVE_ID         "SD:"
38 #define APP_OTA_SEND_LEN        512
39 #define APP_OTA_SEND_NUM        1
40 #define APP_OTA_READ_LEN        APP_OTA_SEND_LEN*APP_OTA_SEND_NUM
41 #define CS_OTA_ADDR_LIST_NUM   10
42 #define CS_OTA_RESEND_TIME     10
43 
44 static BT_ADDR cs_ota_addr_list[CS_OTA_ADDR_LIST_NUM];
45 static uint8_t cs_ota_addr_num = 0;
46 const BT_ADDR cs_bt_addr = {{00,00,00,0x88,0x88,0x33}};
47 static uint8_t send_buff[APP_OTA_READ_LEN] = {0,};
48 static uint32_t send_len = 0;
49 static uint32_t total_send_len = 0;
50 char *fsid    = SDCARD_DRIVE_ID "/";
51 char *otafile = SDCARD_DRIVE_ID "/otadir/ota.bin";
52 FATFS fs;
53 FIL fh;
54 FILINFO fi;
55 static co_timer *app_ota_resend_timer = NULL;
56 
app_ota_check_cs_addr(BT_ADDR * ota_addr)57 bool app_ota_check_cs_addr(BT_ADDR *ota_addr)
58 {
59     if(ota_addr->addr[5] == cs_bt_addr.addr[5]
60     && ota_addr->addr[4] == cs_bt_addr.addr[4]
61     && ota_addr->addr[3] == cs_bt_addr.addr[3])
62        return TRUE;
63     else
64        return FALSE;
65 }
66 
app_ota_add_addr_list(BT_ADDR * ota_addr)67 void app_ota_add_addr_list(BT_ADDR *ota_addr)
68 {
69     for(uint8_t i=0;i<CS_OTA_ADDR_LIST_NUM;i++){
70         if(memcmp(ota_addr->addr,cs_bt_addr.addr,6) == 0){
71             return;
72         }
73     }
74     memcpy(cs_ota_addr_list[cs_ota_addr_num++].addr,ota_addr->addr,6);
75 }
76 
app_ota_clean_addr_list(void)77 void app_ota_clean_addr_list(void)
78 {
79     memset((uint8_t *)cs_ota_addr_list,0,(CS_OTA_ADDR_LIST_NUM*6));
80 }
81 
app_ota_show_addr_list(void)82 void app_ota_show_addr_list(void)
83 {
84     if(cs_ota_addr_num){
85         TRACE("APP: ota addr list :\n");
86         for(uint8_t i=0;i<cs_ota_addr_num;i++){
87             BT_ADDR *oaddr = &cs_ota_addr_list[i];
88             TRACE("LIST ID %d,addr 0x%x,0x%x,0x%x,0x%x,0x%x,0x%x\n",i,oaddr->addr[5],\
89             oaddr->addr[4],oaddr->addr[3],oaddr->addr[2],oaddr->addr[1],oaddr->addr[0]);
90         }
91     }
92 }
93 
94 
app_ota_connect_device(BT_ADDR * bdaddr)95 void app_ota_connect_device(BT_ADDR * bdaddr)
96 {
97     TRACE("APP:test connect addr 0x%x,0x%x,0x%x,0x%x,0x%x,0x%x\n",bdaddr->addr[0],bdaddr->addr[1],bdaddr->addr[2],bdaddr->addr[3],bdaddr->addr[4],bdaddr->addr[5]);
98     cs_adp_test_connect(bdaddr);
99 }
100 
app_ota_connect_by_list_id(uint8_t id)101 void app_ota_connect_by_list_id(uint8_t id)
102 {
103     app_ota_connect_device(&cs_ota_addr_list[id]);
104 }
105 
app_ota_disconnect_device(void)106 void app_ota_disconnect_device(void)
107 {
108     cs_adp_test_disconnect();
109 }
110 
app_ota_update_bin_init(void)111 int app_ota_update_bin_init(void)
112 {
113     int err;
114 
115     do {
116         uint8_t mode = FA_READ;
117 
118         OTA_PRINT("mount: %s\r\n",fsid);
119         err = f_mount(&fs, fsid, 0);
120         if (err) {
121             OTA_PRINT("Fail to mount, err=%d\r\n", err);
122             break;
123         }
124 
125         OTA_PRINT("stat: %s\r\n",otafile);
126         err = f_stat(otafile, &fi);
127         if (err == FR_NO_FILE) {
128             OTA_PRINT("Not Exist\r\n");
129             break;
130         } else if (err) {
131             OTA_PRINT("Fail to stat, err=%d\r\n", err);
132             break;
133         }
134         OTA_PRINT("stat: file size %d, file name %s, date %d,time %d\r\n",fi.fsize,fi.fname,fi.fdate,fi.ftime);
135         OTA_PRINT("open: %s\r\n",otafile);
136         err = f_open(&fh, otafile, mode);
137         if (err) {
138             OTA_PRINT("Fail to open, err=%d\r\n", err);
139             break;
140         }
141 
142         OTA_PRINT("lseek to 0, cur=%d\r\n",f_tell(&fh));
143         err = f_lseek(&fh, 0);
144         if (err) {
145             OTA_PRINT("Fail to lseek, err=%d\r\n", err);
146             break;
147         }
148         OTA_PRINT("cur=%d\r\n",f_tell(&fh));
149 
150     } while (0);
151 
152     return err;
153 }
154 
app_ota_update_bin_end(void)155 int app_ota_update_bin_end(void)
156 {
157     int err;
158 
159     do {
160         OTA_PRINT("close\r\n");
161         err = f_close(&fh);
162         if (err) {
163             OTA_PRINT("Fail to open, err=%d\r\n", err);
164             break;
165         }
166 
167         OTA_PRINT("unmount: %s\r\n",fsid);
168         err = f_mount(NULL, fsid, 0);
169         if (err) {
170             OTA_PRINT("Fail to unmount, err=%d\r\n", err);
171             break;
172         }
173     } while (0);
174     return err;
175 }
176 
app_ota_update_bin_get_size(void)177 uint32_t app_ota_update_bin_get_size(void)
178 {
179     return fi.fsize;
180 }
181 
app_ota_update_bin_read(char * rd_buff)182 uint32_t app_ota_update_bin_read(char * rd_buff)
183 {
184     int err;
185     uint32_t num = 0;
186 
187     OTA_PRINT("read\r\n");
188     err = f_read(&fh, rd_buff, APP_OTA_READ_LEN, &num);
189     if (err) {
190         OTA_PRINT("Fail to read, err=%d, num=%d\r\n", err, num);
191     }
192     OTA_PRINT("cur=%d,num=%d\r\n",f_tell(&fh),num);
193     #if 0
194     OTA_PRINT("Read text from file: %s\r\n num %d\r\n", otafile,num);
195     for(int i = 0; i <num;i++){
196         OTA_PRINT("%x ",rd_buff[i]);
197     }
198     OTA_PRINT("\r\n");
199     #endif
200     return num;
201 }
202 
app_ota_bin_send_timer(void * cb_param)203 static void app_ota_bin_send_timer(void *cb_param)
204 {
205     uint32_t num = (uint32_t)cb_param;
206     app_bt_ota_send_data(num);
207 }
208 
app_ota_resend_update_bin(uint32_t num)209 void app_ota_resend_update_bin(uint32_t num)
210 {
211     uint8_t ret = 0;
212     TRACE("ota_send_timer len = %x\n",num);
213     app_ota_resend_timer = NULL;
214 
215     ret = app_ota_send_data(send_buff,num,OTA_DATA_HEADER);
216     TRACE("APP:ret t= %x\n",ret);
217     if(ret == BTDEF_PENDING){
218         //send ok
219     }else if(ret == BTDEF_IS_USEING){
220         //buffer is full,delay some time then send it.
221         if(app_ota_resend_timer == NULL){
222             co_timer_start(&app_ota_resend_timer,CS_OTA_RESEND_TIME,(void *)num,app_ota_bin_send_timer,0);
223         }
224     }else{
225         //error occured
226     }
227 }
228 
229 #endif
230 
app_ota_set_access(enum APP_OTA_ACCESS access)231 void app_ota_set_access(enum APP_OTA_ACCESS access)
232 {
233     app_ota_access = access;
234 }
235 
app_ota_get_access(void)236 enum APP_OTA_ACCESS app_ota_get_access(void)
237 {
238     return app_ota_access;
239 }
240 
app_ota_send_data(uint8_t * data,uint16_t len,uint8_t header)241 uint8_t app_ota_send_data(uint8_t *data, uint16_t len, uint8_t header)
242 {
243     return cs_adp_test_send_data(data,len,header);
244 }
245 
app_ota_receive_data(uint8_t * rxbuf,uint16_t len)246 void app_ota_receive_data(uint8_t *rxbuf, uint16_t len)
247 {
248     static uint32_t total_len = 0;
249     static uint32_t received_len = 0;
250 
251     OTA_PRINT("APP:OTA in len = %d,header = 0x%x\n",len,rxbuf[0]);
252     //OTA_PRINT("%x,%x,%x,%x,%x\n",rxbuf[1],rxbuf[2],rxbuf[3],rxbuf[4],rxbuf[5]);
253     switch(app_ota_get_access())
254     {
255         case OTA_BY_SPP:
256             {
257                 received_len +=len;
258                 ota_write((const uint8_t *)rxbuf, len);
259                 if(received_len == total_len){
260                     TRACE("APP: OTA BIN received success\n");
261                     received_len = 0;
262                     total_len = 0;
263                     ota_end();
264                     pmic_chip_reboot();
265                 }
266             }
267             break;
268         case OTA_BY_VENDOR:
269             {
270                 if(rxbuf[0] == OTA_INFO_HEADER){
271                     total_len = (uint32_t)(rxbuf[1]) | ((uint32_t)(rxbuf[2])<<8) | ((uint32_t)(rxbuf[3])<<16) | ((uint32_t)(rxbuf[4])<<24);
272                     TRACE("APP: OTA BIN total len = %d\n",total_len);
273                     ota_start((OTA_ADDR + OTA_INFO_SIZE), total_len);
274                 }else if(rxbuf[0] == OTA_DATA_HEADER){
275                     received_len +=(len-1);
276                     ota_write((const uint8_t *)&rxbuf[1], (len-1));
277                     if(received_len == total_len){
278                         TRACE("APP: OTA BIN received success\n");
279                         received_len = 0;
280                         total_len = 0;
281                         ota_end();
282                         pmic_chip_reboot();
283                     }
284                 }else{
285                     OTA_PRINT("APP:OTA error\n");
286                 }
287             }
288             break;
289         case OTA_BY_BLE:
290             break;
291         default:
292             {
293                 if(rxbuf[0] == OTA_INFO_HEADER){
294                     total_len = (uint32_t)(rxbuf[1]) | ((uint32_t)(rxbuf[2])<<8) | ((uint32_t)(rxbuf[3])<<16) | ((uint32_t)(rxbuf[4])<<24);
295                     TRACE("APP: OTA BIN total len = %d\n",total_len);
296                     ota_start((OTA_ADDR + OTA_INFO_SIZE), total_len);
297                     app_ota_set_access(OTA_BY_SPP);
298                 }
299             }
300             break;
301     }
302 }
303 
app_ota_msg_handle(CS_EVENT * Event)304 void app_ota_msg_handle(CS_EVENT *Event)
305 {
306     CS_ADP_TEST_EVENT *cs_ota_msg = (CS_ADP_TEST_EVENT *)Event->Param;
307 
308     switch(Event->EventId){
309         case CS_ADP_TEST_CONNECTED_CNF:
310             TRACE("APP:ota_connect_cnf reason = %d\n",cs_ota_msg->testparam);
311             app_ota_set_access(OTA_BY_VENDOR);
312             break;
313         case CS_ADP_TEST_DISCONNECTED:
314             TRACE("APP:ota_disconnect reason = %d\n",cs_ota_msg->testparam);
315             app_ota_set_access(OTA_BY_VENDOR);
316             break;
317 #if APP_SUPPORT_OTA_BOX
318         case CS_ADP_TEST_INQUIRY_RESULT:
319             if(app_ota_check_cs_addr(&cs_ota_msg->bdaddr)){
320                 app_ota_add_addr_list(&cs_ota_msg->bdaddr);
321             }
322             break;
323         case CS_ADP_TEST_INQUIRY_COMPLETE:
324             app_ota_show_addr_list();
325             break;
326         case CS_ADP_TEST_INQUIRY_CANCELED:
327             app_ota_show_addr_list();
328             break;
329 #endif
330         case CS_ADP_TEST_L2CAP_CONNECTD:
331             TRACE("APP:ota l2cap connect\n");
332 #if APP_SUPPORT_OTA_BOX
333             uint8_t ret = 0;
334             uint32_t file_size = 0;
335 
336             file_size = app_ota_update_bin_get_size();
337             TRACE("APP:OTA bin size %d\n",file_size);
338             memset(send_buff,0,APP_OTA_READ_LEN);
339             send_len = 0;
340             send_buff[0] = (uint8_t)((0x000000ff&file_size));
341             send_buff[1] = (uint8_t)((0x0000ff00&file_size)>>8);
342             send_buff[2] = (uint8_t)((0x00ff0000&file_size)>>16);
343             send_buff[3] = (uint8_t)((0xff000000&file_size)>>24);
344             ret = app_ota_send_data(send_buff,4,OTA_INFO_HEADER);
345             TRACE("APP:ret = %x\n",ret);
346 #else
347 
348 #endif
349             break;
350         case CS_ADP_TEST_L2CAP_DISCONNECTD:
351             TRACE("APP:ota l2cap disconnect reason = 0x%x\n",cs_ota_msg->testparam);
352 #if APP_SUPPORT_OTA_BOX
353 
354 #else
355 
356 #endif
357             break;
358         case CS_ADP_TEST_L2CAP_DATA_SENT:
359             {
360                 TestTxDone *tx_done = (TestTxDone *)cs_ota_msg->testparam;
361                 OTA_PRINT("APP:OTA out len = %d,data addr = 0x%x\n",tx_done->len,tx_done->txbuf);
362                 //OTA_PRINT("%x,%x,%x,%x,%x\n",tx_done->txbuf[0],tx_done->txbuf[1],tx_done->txbuf[2],tx_done->txbuf[3],tx_done->txbuf[4]);
363 #if APP_SUPPORT_OTA_BOX
364                 uint8_t ret = 0;
365                 uint32_t num = app_ota_update_bin_read(send_buff);
366                 if(num){
367                     if(num == APP_OTA_READ_LEN){
368                         ret = app_ota_send_data(send_buff,APP_OTA_READ_LEN,OTA_DATA_HEADER);
369                         TRACE("APP:ret 0= %x\n",ret);
370                     }else{
371                         ret = app_ota_send_data(send_buff,num,OTA_DATA_HEADER);
372                         TRACE("APP:ret 1= %x\n",ret);
373                     }
374                     if(ret == BTDEF_PENDING){
375                         //send ok
376                         total_send_len+=num;
377                         if(total_send_len == app_ota_update_bin_get_size()){
378                             TRACE("APP:ota update success\n");
379                             app_ota_update_bin_end();
380                             app_ota_disconnect_device();
381                         }
382                     }else if(ret == BTDEF_IS_USEING){
383                         //buffer is full,delay some time then send it.
384                         if(app_ota_resend_timer == NULL){
385                             co_timer_start(&app_ota_resend_timer,CS_OTA_RESEND_TIME,(void *)num,app_ota_bin_send_timer,0);
386                         }
387                     }else{
388                         //error occured
389                     }
390                 }else{
391                     //read error occured or read end
392                 }
393 #endif
394             }
395             break;
396         case CS_ADP_TEST_L2CAP_DATA_IND:
397             {
398                 TestRxDone *rx_done = (TestRxDone *)cs_ota_msg->testparam;
399                 app_ota_receive_data(rx_done->rxbuf,rx_done->len);
400             }
401             break;
402         default:
403             break;
404     }
405 }
406 
app_ota_init(void)407 void app_ota_init(void)
408 {
409 #if APP_SUPPORT_OTA_BOX
410     app_ota_update_bin_init();
411 #endif
412 }
413 #endif
414