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