blob: a56e73268d3f7385396af7ff3fbdade9b7c281ab [file] [log] [blame]
xf.libdd93d52023-05-12 07:10:14 -07001
2#include <stdio.h>
3#include <unistd.h>
4#include <string.h>
5#include <time.h>
6#include <sys/types.h>
7#include <dirent.h>
8#include <errno.h>
9#include <stdlib.h>
10#include "CSerial.h"
11#include "LogInfo.h"
12#include "download.h"
13#include "devUsb.h"
14
15/*******************************************************************************
16 * 宏定义 *
17 *******************************************************************************/
18// #define OPENLOG 1
19#define KEYCODELENGTH (16)
20#define IDENTIFYCODE 0xdf, 0xf1, 0x13, 0x63, 0x1a, 0x98, 0xcd, 0xa8, 0xa5, 0x19, 0x7c, 0x1b, 0x1a, 0xba, 0x9f, 0xd7
21
22#define TTY_USB0 ("ttyUSB0")
23#define TTY_USB1 ("ttyUSB1")
24#define TTY_USB2 ("ttyUSB2")
25#define TTY_USB3 ("ttyUSB3")
26
27#define PORT_STA_NO (0)
28#define PORT_STA_AT (7)
29#define PORT_STA_DL (3)
30#define PORT_STA_BUSY (12)
31
32#define MAX_PORT_PATH_LENGTH (32)
33#define MAX_CMD_LENGTH (64)
34#define MAX_CHECK_VERSION_TIMES (10)
35#define MAX_OPEN_DL_PORT_TIMES (50)
36
37static int g_atPortInfo[3] = {0x19d2, 0x0582, 4};
38static int g_dlPortInfo[3] = {0x19d2, 0x0256, 0};
39static int g_at_ttyId = -1;
40static int g_dl_ttyId = -1;
41
42/*******************************************************************************
43 * 内部函数声明 *
44 *******************************************************************************/
45// 模块掉电重启
46static void HardWareReset(int type);
47// 校验传入参数的相应bin文件是否合法
48static int FileAnalyse(const char* path);
49// 判断AT命令是否返回相应的子串
50static int ChekATBackString(const char *atstring, const char *findversion);
51// 进入下载流程
52static enERRORCODE OpenDownloadPortAndDownload(const char *softwarepath, const char *RebackString);
53// 参数选项介绍
54static int usage(const char *exe);
55
56/*******************************************************************************
57 * 内部函数定义 *
58 *******************************************************************************/
59 /** Modem(模块)掉电重启
60 * @brief
61 * @param type 入参,重启类型,0:通过AT命令重启,1:DL口reboot重启
62 * @return
63 * @retval
64 * @note
65 * @warning
66 */
67#if 0
68void HardWareReset()
69{ /*
70 system("echo 1 > /sys/class/gpio_sw/PH12/data"); //模块下电
71 usleep(1*1000*1000); //delay
72 system("echo 0 > /sys/class/gpio_sw/PH12/data"); //模块上电
73 */
74 char * AT= "at\r\n";
75 ChekATBackString(AT,"OK");
76 char * AT_SoftwareReset = "at+zsoftreset\r\n";
77 ChekATBackString(AT_SoftwareReset,"OK");//reset
78
79}
80#endif
81static void HardWareReset(int type)
82{
83 char cversion[1024] = {0};
84 char dev_tty[MAX_PORT_PATH_LENGTH] = {0};
85 char AT_Reset[MAX_CMD_LENGTH] = "\r\nat+zsoftreset\r\n";
86 char cmdDevReboot[MAX_CMD_LENGTH] = "echo reboot > /dev/ttyUSB";
87
88 snprintf(dev_tty, MAX_PORT_PATH_LENGTH, "/dev/ttyUSB%d", g_at_ttyId);
89 snprintf(cmdDevReboot, MAX_CMD_LENGTH, "echo reboot > /dev/ttyUSB%d", g_dl_ttyId);
90
91 if (type == 0)
92 {
93 SendATString(dev_tty, AT_Reset, cversion);
94 }
95 else
96 {
97 printf("HardWareReset(1):: %s \r\n", cmdDevReboot);
98 system(cmdDevReboot);
99 }
100}
101
102/**
103 * @brief 校验传入参数的相应bin文件是否合法
104 * @param path 入参,要下载的bin文件路径
105 * @return 成功返回 TRUE,失败返回 FALSE
106 * @retval
107 * @note
108 * @warning
109 */
110static BOOL FileAnalyse(const char* path)
111{
112 FILE *pf;
113 unsigned char keycode[KEYCODELENGTH] = {0};
114 int i = 0;
115 unsigned char standardkeycod[] =
116 {
117 IDENTIFYCODE};
118 if (access(path, F_OK) != 0)
119 {
120 LogInfo("software file path is not exist.");
121 return FALSE;
122 }
123 pf = fopen(path, "rb");
124 if (NULL == pf)
125 {
126 LogInfo("open %s error:%s", path, strerror(errno));
127 return FALSE;
128 }
129
130 int num = fread(keycode, sizeof(char), KEYCODELENGTH, pf);
131 if (KEYCODELENGTH != num)
132 {
133 LogInfo("read %s error", path);
134 return FALSE;
135 }
136
137 for (i = 0; i < KEYCODELENGTH; i++)
138 {
139 if (keycode[i] != standardkeycod[i])
140 {
141 fclose(pf);
142 pf = NULL;
143 return FALSE;
144 }
145 }
146 fclose(pf);
147 pf = NULL;
148 return TRUE;
149}
150
151/**
152 * @brief 判断AT命令是否返回相应的子串
153 * @param AtString 入参,发送的AT命令字符串
154 * @param findversion 入参,要比较的子串
155 * @return 成功返回0,失败返回-1
156 * @retval
157 * @note
158 * @warning
159 */
160static int ChekATBackString(const char *atstring, const char *findversion)
161{
162 char dev_tty[MAX_PORT_PATH_LENGTH] = {0};
163 char cversion[1024] = {0};
164
165 snprintf(dev_tty, MAX_PORT_PATH_LENGTH, "/dev/ttyUSB%d", g_at_ttyId);
166
167 SendATString(dev_tty, atstring, cversion);
168
169 if ((cversion != NULL) && (findversion != NULL))
170 {
171 LogInfo("AT send over , cversion = %s, findversion = %s", cversion, findversion);
172 }
173 else
174 {
175 LogInfo("AT send over , version ptr is error");
176 }
177
178 printf("AT actual return = %s\n", cversion);
179 printf("AT suppose to be = %s\n", findversion);
180
181 if (strstr(cversion, findversion))
182 {
183 return 0;
184 }
185 else
186 {
187 return -1;
188 }
189}
190
191/**
192 * @brief 打开下载口并进行下载流程
193 * @param softwarepath 入参,要下载的bin文件路径
194 * @param RebackString 入参,要校验的bin文件版本号
195 * @return 返回 enERRORCODE 枚举值
196 * @retval
197 * @note
198 * @warning
199 */
200static enERRORCODE OpenDownloadPortAndDownload(const char *softwarepath, const char *RebackString)
201{
202 int ret;
203 // char *diagport = DL_PORT;
204 char dev_dltty[MAX_PORT_PATH_LENGTH] = {0};
205 char *AT_GetVersion = "at+cgmr\r\n";
206 char *AT_OpenDL = "at+zflag=\"BOOT\",0\r\n";
207 char *AT_CloseDL = "at+zflag=\"BOOT\",1\r\n";
208
209 char AtReturnValue[128] = {0};
210 int portState = 0;
211 BOOL SucFlag = FALSE;
212 int i = 0, z = 0;
213
214 printf("DL version = 1.0\n");
215 // 检查是否输入版本号
216 if(RebackString[0] != '\0')
217 {
218 printf("%s:: Bin version = %s\n", __FUNCTION__, RebackString);
219 LogInfo("Bin version = %s", RebackString);
220 }
221 else
222 {
223 printf("%s:: not check version\n", __FUNCTION__);
224 LogInfo("not check version");
225 }
226 // 查找AT口
227 ret = dev_get_device(g_atPortInfo);
228 if(ret == -1)
229 {
230 printf("%s:: get at info failed, please restart module!!!\n", __FUNCTION__);
231 LogInfo("get at info failed, please restart module!!!");
232 return Download_FIND_AT_FAIL;
233 }
234 else
235 {
236 g_at_ttyId = g_usb_dev;
237 printf("%s:: Find AT port.\n", __FUNCTION__);
238 }
239
240
241 int j = 0;
242 while (j < 3)
243 {
244 if (-1 == ChekATBackString(AT_OpenDL, "OK")) // open dl port ,at command
245 {
246 printf("OpenDownloadPortAndDownloadfunc:: AT_OpenDL send fail!, times = %d\n", j + 1);
247 }
248 else
249 {
250 printf("OpenDownloadPortAndDownloadfunc:: AT_OpenDL send ok!, times = %d\n", j + 1);
251 break;
252 }
253 j++;
254 usleep(500 * 1000); // delay
255
256 // if (j >= 3)
257 // {
258 // LogInfo("OpenDownloadPortAndDownloadfunc:: AT_OPENDLPORT FAIL");
259 // return Download_AT_OPENDLPORT_FAIL;
260 // }
261 }
262
263 // 重启,进入下载通道
264 printf("OpenDownloadPortAndDownloadfunc:: HardWare Reset 1, please wait\r\n");
265 HardWareReset(0);
266 usleep(4000 * 1000); // 延时等待DL口枚举
267 // 查找DL口
268 ret = dev_get_device(g_dlPortInfo);
269 if(ret == -1)
270 {
271 printf("get dl info failed\n");
272 return Download_OPENDLPORT_FAIL;
273 }
274 else
275 {
276 g_dl_ttyId = g_usb_dev;
277 snprintf(dev_dltty, MAX_PORT_PATH_LENGTH, "/dev/ttyUSB%d", g_dl_ttyId);
278 }
279
280 i = MAX_OPEN_DL_PORT_TIMES;
281 while (i > 0)
282 {
283 // usleep(200*1000);
284 if (-1 == (Open(dev_dltty)))
285 {
286 printf("OpenDownloadPortAndDownloadfunc:: Diag open Failed, times = %d\r\n", MAX_OPEN_DL_PORT_TIMES - i + 1);
287 --i;
288 continue;
289 }
290 else
291 {
292 printf("OpenDownloadPortAndDownloadfunc:: Diag open ok!\r\n");
293 break;
294 }
295 }
296 if (i <= 0)
297 {
298 LogInfo("OpenDownloadPortAndDownloadfunc:: OPEN DLPORT FAIL");
299 return Download_OPENDLPORT_FAIL;
300 }
301
302 // 进入下载TLoader和TBoot流程
303 if (!DoDownloadBootForDL(FALSE, softwarepath))
304 {
305 LogInfo("DoDownloadBootForDL FAIL...");
306 printf("DoDownloadBootForDL FAIL\r\n");
307 Close();
308 return Download_DOWNLOAD_IMAGE_FAIL;
309 }
310 LogInfo("DoDownloadBootForDL ok...");
311 printf("DoDownloadBootForDL ok\r\n");
312
313#if (ERASENVRW == 1)
314 if (!ExecuteEraseNVRW(softwarepath))
315 {
316 printf("OpenDownloadPortAndDownloadfunc:: ExecuteEraseNVRW Fail\r\n");
317 Close();
318 return Download_DOWNLOAD_IMAGE_FAIL;
319 }
320 printf("OpenDownloadPortAndDownloadfunc:: ExecuteEraseNVRW ok.\r\n");
321#endif
322
323 // 进入下载版本文件流程
324 if (Download_OK != PrimaryDoDownload(softwarepath))
325 {
326 printf("OpenDownloadPortAndDownloadfunc:: PrimaryDoDownload fail return value = %d\r\n", Download_DOWNLOAD_IMAGE_FAIL);
327 Close();
328 return Download_DOWNLOAD_IMAGE_FAIL;
329 }
330 printf("OpenDownloadPortAndDownloadfunc:: PrimaryDoDownload OK\r\n");
331 Close();
332 LogInfo("OpenDownloadPortAndDownloadfunc:: PrimaryDoDownload end");
333
334 // 重启,进行检查版本号流程
335 usleep(100 * 1000); // delay
336 printf("OpenDownloadPortAndDownloadfunc:: HardWare Reset 2, please wait\r\n");
337 HardWareReset(1);
338
339 // 检查是否输入版本号
340 if (RebackString[0] != '\0')
341 {
342 // 延时等待AT口枚举
343 usleep(15 * 1000 * 1000);
344 printf("OpenDownloadPortAndDownloadfunc:: Begin to check version after Downloader.\r\n");
345
346 i = MAX_CHECK_VERSION_TIMES;
347 while (i > 0)
348 {
349 if (-1 == ChekATBackString(AT_GetVersion, RebackString))
350 {
351 printf("OpenDownloadPortAndDownloadfunc:: check version fail, %d!\r\n", MAX_CHECK_VERSION_TIMES - i + 1);
352 }
353 else
354 {
355 printf("OpenDownloadPortAndDownloadfunc:: check version OK.\r\n");
356 break;
357 }
358 i--;
359 usleep(1 * 1000 * 1000); // delay
360 }
361
362 // 检查版本号
363 if (i <= 0)
364 {
365 printf("OpenDownloadPortAndDownloadfunc:: Check version error!\r\n");
366 LogInfo("Check version error!");
367 return Download_CHECK_VERSION_FAIL;
368 }
369 }
370
371 return Download_OK;
372#if 0
373 i=5;
374 while(i > 0)
375 {
376 if(-1 == ChekATBackString(AT_CloseDL,"OK")) //close dl port ,at command
377 {
378 printf("OpenDownloadPortAndDownloadfunc:: close dl port fail!\r\n");
379 //return Download_AT_CLOSE_DL_FAIL;
380 }
381 else
382 {
383 printf("OpenDownloadPortAndDownloadfunc:: close dl port OK.\r\n");
384 return Download_OK;
385 }
386 i--;
387 usleep(1000*1000);//delay
388 }
389 return Download_CLOSE_DL_FAIL;
390#endif
391}
392
393/**
394 * @brief 参数选项介绍
395 * @param exe 入参,应用名
396 * @return 成功返回0
397 * @retval
398 * @note
399 * @warning
400 */
401static int usage(const char *exe)
402{
403 printf("%s -p bin_path -c check_version\n", exe);
404 printf("-h, help\n");
405 printf("-p bin_file_path\n");
406 printf("-c check_version\n");
407 printf("-s save_log_path, default path is (%s)\n", DEFAULT_LOG_PATH);
408 return 0;
409}
410
411/*******************************************************************************
412 * 主函数 *
413 *******************************************************************************/
414int main(int argc, char *argv[])
415{
416 int ch;
417 int ret = -1;
418
419 enERRORCODE DownloadResultMain = Download_OK;
420 // remove(LOG_PATH);
421 char BinPath[FILE_PATH_LENGTH_MAX] = {0}; // BinFile Path
422 char BinVersion[FILE_PATH_LENGTH_MAX] = {0};
423 strncpy(g_log_path, DEFAULT_LOG_PATH, FOLDER_PATH_LENGTH_MAX - 1);
424
425 printf("main:: downloading ...\r\n");
426 LogInfo("Program Start1");
427 if (geteuid() != 0)
428 {
429 fprintf(stderr, "main:: This program must run as root!\n");
430 LogInfo("Program close");
431 DownloadResultMain = Download_NOT_ROOT;
432 LogInfo("return Download_NOT_ROOT");
433 return DownloadResultMain;
434 }
435
436 LogInfo("Program Start2");
437 if (argc == 1)
438 {
439 fprintf(stderr, "main:: The Parameter at least need 1 input, but now is %d, error!\n", argc-1);
440 DownloadResultMain = Download_ERROR_INPUT_ARGC;
441 usage(argv[0]);
442 LogInfo("return Download_ERROR_INPUT_ARGC");
443 return DownloadResultMain;
444 }
445
446 LogInfo("Program Start3");
447 while ((ch = getopt(argc, argv, "hp:c:s:")) != -1)
448 {
449 switch (ch)
450 {
451 case 'h':
452 ret = usage(argv[0]);
453 return ret;
454 case 'p':
455 strncpy(BinPath, optarg, FILE_PATH_LENGTH_MAX - 1);
456 printf("main:: -p, BinPath = %s\n", BinPath);
457 break;
458 case 'c':
459 strncpy(BinVersion, optarg, FILE_PATH_LENGTH_MAX - 1);
460 printf("main:: -c, BinVersion = %s\n", BinVersion);
461 break;
462 case 's':
463 strncpy(g_log_path, optarg, FOLDER_PATH_LENGTH_MAX - 1);
464 printf("main:: -s, g_log_path = %s\n", g_log_path);
465 break;
466 default:
467 usage(argv[0]);
468 break;
469 }
470 }
471 if(BinPath[0] == '\0')
472 {
473 printf("main:: BinPath is NULL, please add -p bin_path\n");
474 LogInfo("BinPath is NULL, please add -p bin_path");
475 return Download_ERROR_INPUT_ARGC;
476 }
477 if(BinVersion[0] == '\0')
478 {
479 printf("main:: BinVersion is NULL, not check\n");
480 LogInfo("BinVersion is NULL, not check");
481 }
482
483 LogInfo("Program Start4");
484 if (!FileAnalyse(BinPath))
485 {
486 LogInfo("FileAnalyse Failed");
487 DownloadResultMain = Download_CHECK_BIN_FAIL;
488 LogInfo("return Download_CHECK_BIN_FAIL");
489 return DownloadResultMain;
490 }
491
492 LogInfo("Program Start5");
493 DownloadResultMain = OpenDownloadPortAndDownload(BinPath, BinVersion);
494 LogInfo("DownloadResultMain = %d", DownloadResultMain);
495
496 if (DownloadResultMain == Download_OK)
497 {
498 LogInfo("download success...................");
499 printf("main:: download success...................\n");
500 }
501 else
502 {
503 LogInfo("download fail...................");
504 printf("main:: download fail...................\n");
505 return DownloadResultMain;
506 }
507
508 return Download_OK;
509}