IEC101_FILE.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987
  1. /******************************************************************************
  2. 版权所有:
  3. 文件名称: IEC101_FILE.c
  4. 文件版本: 01.01
  5. 创建作者: sunxi
  6. 创建日期: 2012-10-10
  7. 功能说明: 101规约文件传输扩展
  8. 其它说明:
  9. 修改记录:
  10. */
  11. /*------------------------------- 头文件 --------------------------------------
  12. */
  13. #include "head.h"
  14. /*------------------------------- 宏定义 --------------------------------------
  15. */
  16. #define IEC101_TYPE_FILE 137
  17. #define IEC101_FILE_ACK 0X80
  18. #define IEC101_FILE_NAK 0X40
  19. #define FILE_ERR_OK 0x00
  20. #define FILE_ERR_NAME 0x01
  21. #define FILE_ERR_TYPE 0x02
  22. #define FILE_ERR_BUSY 0x03
  23. #define FILE_ERR_ADDR 0x04
  24. #define FILE_ERR_SIZE 0x05
  25. #define FILE_ERR_CRC 0x06
  26. #define FILE_ERR_SAVE 0x07
  27. #define FILE_ERR_PHASE 0x08
  28. #define FILE_ERR_MEM 0x09
  29. #define FILE_ERR_STATE 0x0a
  30. #define FILE_ERR_OTHER 0xff
  31. /*------------------------------ 类型结构 -------------------------------------
  32. */
  33. enum fState
  34. {
  35. FS_IDLE = 0,
  36. FS_VERIFY_DOWN,
  37. FS_VERIFY_UP,
  38. FS_INFO_DOWN,
  39. FS_INFO_UP,
  40. FS_DATA_DOWN,
  41. FS_DATA_UP,
  42. FS_RESULT_DOWN,
  43. FS_RESULT_UP,
  44. };
  45. struct file101
  46. {
  47. enum fState state;
  48. s32 file_index;
  49. u16 file_type;
  50. u16 file_crc;
  51. u32 file_length;
  52. u32 file_offset;
  53. u8* file_buf;
  54. };
  55. /*------------------------------ 全局变量 -------------------------------------
  56. */
  57. struct file101 g_file101= {0};
  58. // 通过串口下载的文件,不需要在maintain中再检查文件
  59. u8 g_file_save=0;
  60. /*------------------------------ 函数声明 -------------------------------------
  61. */
  62. static int _file_up_info(int index);
  63. static int _file_save_app(int index);
  64. //static int _file_check(s8 * name,u32 attr);
  65. int printf_file101(void);
  66. struct file_item g_file_item[] =
  67. {
  68. {KO_FILE_NAME_1, "/app/", ATTR_UP | ATTR_DOWN, FILETYPE_MAINAPP, _file_save_app},
  69. {"m", "/app/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  70. {"equ_res.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_BRD, _file_save_app},
  71. {"equ_cfg.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_CFG, _file_save_app},
  72. {"e2prom.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  73. {"brd_res.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  74. {"iectable.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_TABLE, _file_save_app},
  75. {FILE_NAME_PPL_CFG, "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_PPL, _file_save_app},
  76. {"fixset.csv", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app}, // 固定参数文件
  77. {"pcolcfg.ini", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app}, // 级联规约文件
  78. {"vol_status.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  79. {"set_data.bin", "/tmp/", ATTR_UP | ATTR_DOWN, FILETYPE_SET, _file_save_app},
  80. {FILE_NAME_RSC, "/tmp/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  81. {FILE_NAME_PPL_RSC, "/tmp/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  82. {FILE_NAME_SET_DESC, "/tmp/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  83. {"env.dat", "/tmp/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  84. {"instu.bin", "/tmp/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  85. {"log_err.txt", "/app/data/", ATTR_UP, FILETYPE_LOG_APP, _file_save_app},
  86. {"log_operate.txt", "/app/data/", ATTR_UP, FILETYPE_LOG_APP, _file_save_app},
  87. {"log_soe.txt", "/app/data/", ATTR_UP, FILETYPE_LOG_APP, _file_save_app},
  88. {"log_yx.txt", "/app/data/", ATTR_UP, FILETYPE_LOG_APP, _file_save_app},
  89. {"log_fixset.txt", "/app/data/", ATTR_UP, FILETYPE_LOG_GPRS, _file_save_app},
  90. {"log_gprs.txt", "/app/data/", ATTR_UP, FILETYPE_LOG_GPRS, _file_save_app},
  91. {"logcfg.xml", "/app/IEC61850/cfg/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  92. {"osicfg.xml", "/app/IEC61850/cfg/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  93. {"file_list.bin", "/tmp/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  94. #if (0)
  95. {"f306.ko", "/app/", ATTR_UP | ATTR_DOWN, FILETYPE_MAINAPP, _file_save_app},
  96. {"f308.ko", "/app/", ATTR_UP | ATTR_DOWN, FILETYPE_MAINAPP, _file_save_app},
  97. {"u-boot.bin", "/tmp/", ATTR_DOWN, FILETYPE_SYS, _file_save_app}, // 引导程序
  98. {"uImage", "/tmp/", ATTR_DOWN, FILETYPE_SYS, _file_save_app}, // 内核程序
  99. {"app.jffs2", "/tmp/", ATTR_DOWN, FILETYPE_SYS, _file_save_app}, // 应用系统
  100. {"rootfs.jffs2", "/tmp/", ATTR_DOWN, FILETYPE_SYS, _file_save_app}, // 内核系统
  101. {"image_flash.bin", "/tmp/", ATTR_DOWN, FILETYPE_SYS, _file_save_app}, // 烧录系统
  102. {"innergprs.ini", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_INNERGPRS, _file_save_app},
  103. {FILE_NAME_GPRSDRIVER, "/app/", ATTR_UP | ATTR_DOWN, FILETYPE_GPRSDRIVER, _file_save_app},
  104. {"gprs_app", "/app/", ATTR_UP | ATTR_DOWN, FILETYPE_GPRSAPP, _file_save_app},
  105. {"rec_wave.dat", "/tmp/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  106. {"F308_HMI.bin", "/tmp/", ATTR_UP | ATTR_DOWN, FILETYPE_F308_HMI, _file_save_app},
  107. {"DTU-DIDO.elf.bin", "/tmp/", ATTR_UP | ATTR_DOWN, FILETYPE_CHILDPRO, _file_save_app},
  108. {"changelog.txt", "/app/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  109. // {"acfactor.bin", "/app/data/", ATTR_UP, FILETYPE_OTHER, _file_save_app},
  110. // {"dcfactor.bin", "/app/data/", ATTR_UP, FILETYPE_OTHER, _file_save_app},
  111. {"hzk.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  112. {"sm2key0.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  113. {"sm2key1.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  114. {"sm2key2.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  115. {"sm2key3.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  116. {"userid.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  117. {"x509_time0", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  118. {"x509_time1", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  119. {"x509_time2", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  120. {"x509_time3", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  121. {"sysm2_0.cer", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  122. {"sysm2_1.cer", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  123. {"sysm2_2.cer", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  124. {"sysm2_3.cer", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  125. {"master_slave_equ_sync", "/app/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  126. {"factor_modify", "/app/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  127. {"mainImage.lcd", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  128. {"lcd_menu.csv", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  129. {"vir_mix_table.csv", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  130. {wave_name[0], "/app/data/rec_wave/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  131. {wave_name[1], "/app/data/rec_wave/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  132. {wave_name[2], "/app/data/rec_wave/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  133. {wave_name[3], "/app/data/rec_wave/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  134. {wave_name[4], "/app/data/rec_wave/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  135. {wave_name[5], "/app/data/rec_wave/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  136. {wave_name[6], "/app/data/rec_wave/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  137. {wave_name[7], "/app/data/rec_wave/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
  138. #endif
  139. };
  140. const int FILE_LIST_NUM = (sizeof(g_file_item) / sizeof(struct file_item));
  141. #define FILE_ITEM_NUM (sizeof(g_file_item) / sizeof(struct file_item))
  142. struct stat g_file_time[FILE_ITEM_NUM]; // 文件最新修改时间
  143. /*------------------------------ 函数声明 -------------------------------------
  144. */
  145. int file_check(s8 *name, u32 attr);
  146. static void _file_state_reset(void);
  147. static void _file_echo(IEC101_DEF *pt, u8 *cmd_buf, u8 cmd_len);
  148. /*------------------------------ 外部函数 -------------------------------------
  149. 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性.
  150. */
  151. int IEC101_TransFile(IEC101_DEF *pt, unsigned char *buf, int len)
  152. {
  153. u8 cmd_len;
  154. u8 cmd_buf[256];
  155. cmd_len = com_trans_file(buf, len, cmd_buf);
  156. // 按101格式组帧
  157. _file_echo(pt, cmd_buf, cmd_len);
  158. return 0;
  159. }
  160. extern bool g_mt_rs232;
  161. int IEC101_Maintain(IEC101_DEF *pt, unsigned char *buf, int len)
  162. {
  163. u8 cmd_buf[256];
  164. u8 cmd_len;
  165. g_mt_rs232 = 1;
  166. memset(cmd_buf, 0, sizeof(cmd_buf));
  167. cmd_len = Maintain_Manage(buf, len, cmd_buf);
  168. // 按101格式组帧
  169. _file_echo(pt, &cmd_buf[0], cmd_len);
  170. return 0;
  171. }
  172. int com_trans_file(u8 *buf, u32 len, u8 *cmd_buf)
  173. {
  174. u8 cmd_len = 0;
  175. u32 offset;
  176. cmd_buf[0] = IEC101_TYPE_FILE;
  177. cmd_buf[1] = buf[1];
  178. switch (buf[1])
  179. {
  180. case 0x01:
  181. // 下载请求验证
  182. // 复位状态机
  183. _file_state_reset();
  184. sprintf(cmd_buf + 2, szTool);
  185. sprintf(cmd_buf + 21, VER_TIME "CRC:%04XH", m_CodeCrc);
  186. cmd_len = strlen(cmd_buf + 2) + 1 + 2;
  187. #if 0
  188. if(memcmp(buf+2,szTool,19) != 0) // 具体版本号暂时不检查(匹配V1.XX.XX)
  189. {
  190. cmd_buf[1] |= IEC101_FILE_NAK;
  191. break;
  192. }
  193. #endif
  194. cmd_buf[1] |= IEC101_FILE_ACK;
  195. g_file101.state = FS_VERIFY_DOWN;
  196. break;
  197. case 0x02:
  198. // 上传请求验证
  199. // 复位状态机
  200. _file_state_reset();
  201. sprintf(cmd_buf + 2, szTool);
  202. sprintf(cmd_buf + 21, VER_TIME "CRC:%04XH", m_CodeCrc);
  203. cmd_len = strlen(cmd_buf + 2) + 1 + 2;
  204. #if 0
  205. if(memcmp(buf+2,szTool,19) != 0) // 具体版本号暂时不检查(匹配V1.XX.XX)
  206. {
  207. cmd_buf[1] |= IEC101_FILE_NAK;
  208. break;
  209. }
  210. #endif
  211. cmd_buf[1] |= IEC101_FILE_ACK;
  212. g_file101.state = FS_VERIFY_UP;
  213. break;
  214. case 0x03:
  215. // 下载文件信息
  216. memcpy(cmd_buf + 2, buf + 2, 64); // copy file name
  217. cmd_buf[65] = 0;
  218. memcpy(&g_file101.file_type, buf + 66, 2);
  219. swap16(&g_file101.file_type);
  220. memcpy(&g_file101.file_length, buf + 68, 4);
  221. swap32(&g_file101.file_length);
  222. memcpy(&g_file101.file_crc, buf + 72, 2);
  223. swap16(&g_file101.file_crc);
  224. g_file101.file_offset = 0;
  225. // 检查文件阶段
  226. if ((g_file101.state != FS_VERIFY_DOWN) && (g_file101.state != FS_INFO_DOWN))
  227. {
  228. _file_state_reset();
  229. cmd_buf[1] |= IEC101_FILE_NAK;
  230. cmd_buf[22] = FILE_ERR_PHASE;
  231. cmd_len = 23;
  232. break;
  233. }
  234. // 检查文件名
  235. g_file101.file_index = file_check(cmd_buf + 2, ATTR_DOWN);
  236. if (g_file101.file_index < 0)
  237. {
  238. _file_state_reset();
  239. cmd_buf[1] |= IEC101_FILE_NAK;
  240. cmd_buf[66] = FILE_ERR_NAME;
  241. cmd_len = 67;
  242. break;
  243. }
  244. // 检查文件长度
  245. if (g_file101.file_length > 4 * 1024 * 1024)
  246. {
  247. _file_state_reset();
  248. cmd_buf[1] |= IEC101_FILE_NAK;
  249. cmd_buf[66] = FILE_ERR_SIZE;
  250. cmd_len = 67;
  251. break;
  252. }
  253. // 分配内存
  254. g_file101.file_buf = rt_malloc(g_file101.file_length);
  255. if ((g_file101.file_buf) == NULL)
  256. {
  257. _file_state_reset();
  258. cmd_buf[1] |= IEC101_FILE_NAK;
  259. cmd_buf[66] = FILE_ERR_MEM;
  260. cmd_len = 67;
  261. break;
  262. }
  263. // 所有检查通过,应答ACK
  264. cmd_buf[1] |= IEC101_FILE_ACK;
  265. cmd_len = 66;
  266. // printf_file101();
  267. // 修改状态
  268. g_file101.state = FS_INFO_DOWN;
  269. break;
  270. case 0x04:
  271. // 上传文件信息
  272. memcpy(cmd_buf + 2, buf + 2, 64); // copy file name
  273. cmd_buf[65] = 0;
  274. // 检查文件阶段
  275. if ((g_file101.state != FS_VERIFY_UP) && (g_file101.state != FS_INFO_UP))
  276. {
  277. // 阶段不对
  278. _file_state_reset();
  279. cmd_buf[1] |= IEC101_FILE_NAK;
  280. cmd_buf[66] = FILE_ERR_PHASE;
  281. cmd_len = 67;
  282. break;
  283. }
  284. // 检查文件名称
  285. g_file101.file_index = file_check(cmd_buf + 2, ATTR_UP);
  286. if (g_file101.file_index < 0)
  287. {
  288. _file_state_reset();
  289. cmd_buf[1] |= IEC101_FILE_NAK;
  290. cmd_buf[66] = FILE_ERR_NAME;
  291. cmd_len = 67;
  292. break;
  293. }
  294. // 取得文件信息
  295. if (_file_up_info(g_file101.file_index) != 0)
  296. {
  297. _file_state_reset();
  298. cmd_buf[1] |= IEC101_FILE_NAK;
  299. cmd_buf[66] = FILE_ERR_NAME;
  300. cmd_len = 67;
  301. break;
  302. }
  303. // printf_file101();
  304. // 文件准备就绪,应答ACK
  305. memcpy(cmd_buf + 66, &g_file101.file_type, 2);
  306. swap16(cmd_buf + 66);
  307. memcpy(cmd_buf + 68, &g_file101.file_length, 4);
  308. swap32(cmd_buf + 68);
  309. memcpy(cmd_buf + 72, &g_file101.file_crc, 2);
  310. swap16(cmd_buf + 72);
  311. cmd_buf[1] |= IEC101_FILE_ACK;
  312. cmd_len = 74;
  313. // 修改状态
  314. g_file101.state = FS_INFO_UP;
  315. break;
  316. case 0x05:
  317. // 下载文件正文
  318. memcpy(cmd_buf + 2, buf + 2, 4);
  319. memcpy(&offset, buf + 2, 4);
  320. swap32(&offset);
  321. // 检查文件阶段
  322. if ((g_file101.state != FS_INFO_DOWN) && (g_file101.state != FS_DATA_DOWN))
  323. {
  324. _file_state_reset();
  325. cmd_buf[1] |= IEC101_FILE_NAK;
  326. cmd_buf[6] = FILE_ERR_PHASE;
  327. cmd_len = 7;
  328. break;
  329. }
  330. // 检查文件buf
  331. if (g_file101.file_buf == NULL)
  332. {
  333. rt_printf("IEC101_TransFilefile_buf==NULL\r\n");
  334. _file_state_reset();
  335. cmd_buf[1] |= IEC101_FILE_NAK;
  336. cmd_buf[6] = FILE_ERR_STATE;
  337. cmd_len = 7;
  338. break;
  339. }
  340. // 检查文件offset
  341. if (offset == g_file101.file_offset)
  342. {
  343. // 一切正常,获取数据
  344. len -= 2 + 4;
  345. memcpy(g_file101.file_buf + offset, buf + 6, len);
  346. g_file101.file_offset += len;
  347. }
  348. else
  349. {
  350. rt_printf("IEC101_TransFile:offset\r\n");
  351. }
  352. // 发送ACK
  353. cmd_buf[1] |= IEC101_FILE_ACK;
  354. memcpy(cmd_buf + 2, &g_file101.file_offset, 4);
  355. swap32(cmd_buf + 2);
  356. cmd_len = 6;
  357. // 修改状态
  358. g_file101.state = FS_DATA_DOWN;
  359. break;
  360. case 0x06:
  361. // 上传文件正文
  362. memcpy(cmd_buf + 2, buf + 2, 4);
  363. memcpy(&offset, buf + 2, 4);
  364. swap32(&offset);
  365. // 检查文件阶段
  366. if ((g_file101.state != FS_INFO_UP) && (g_file101.state != FS_DATA_UP))
  367. {
  368. _file_state_reset();
  369. cmd_buf[1] |= IEC101_FILE_NAK;
  370. cmd_buf[6] = FILE_ERR_PHASE;
  371. cmd_len = 7;
  372. break;
  373. }
  374. // 检查文件file_buf
  375. if (g_file101.file_buf == NULL)
  376. {
  377. rt_printf("IEC101_TransFilefile_buf==NULL\r\n");
  378. _file_state_reset();
  379. cmd_buf[1] |= IEC101_FILE_NAK;
  380. cmd_buf[6] = FILE_ERR_STATE;
  381. cmd_len = 7;
  382. break;
  383. }
  384. // 检查文件offset
  385. if (offset >= g_file101.file_length)
  386. {
  387. _file_state_reset();
  388. cmd_buf[1] |= IEC101_FILE_NAK;
  389. cmd_buf[6] = FILE_ERR_ADDR;
  390. cmd_len = 7;
  391. break;
  392. }
  393. // 发送ACK
  394. cmd_buf[1] |= IEC101_FILE_ACK;
  395. if (g_file101.file_length - offset > 200)
  396. {
  397. cmd_len = 200;
  398. }
  399. else
  400. {
  401. cmd_len = g_file101.file_length - offset;
  402. }
  403. memcpy(cmd_buf + 6, g_file101.file_buf + offset, cmd_len);
  404. cmd_len += 6;
  405. // 修改状态
  406. g_file101.state = FS_DATA_UP;
  407. break;
  408. break;
  409. case 0x07:
  410. // 下载结果确认
  411. // 检查文件阶段
  412. if ((g_file101.state != FS_DATA_DOWN) && (g_file101.state != FS_RESULT_DOWN))
  413. {
  414. _file_state_reset();
  415. cmd_buf[1] |= IEC101_FILE_NAK;
  416. cmd_buf[2] = FILE_ERR_PHASE;
  417. cmd_len = 3;
  418. break;
  419. }
  420. // 如果是重复报文,继续肯定应答。
  421. if (g_file101.state == FS_RESULT_DOWN)
  422. {
  423. // 判断是否需要复位
  424. if (buf[2] == 1) // 0:不复位;1:复位
  425. {
  426. watchdog_reset_cpu(1);
  427. }
  428. cmd_buf[1] |= IEC101_FILE_ACK;
  429. cmd_len = 2;
  430. break;
  431. }
  432. // 检查文件长度
  433. if (g_file101.file_offset != g_file101.file_length)
  434. {
  435. _file_state_reset();
  436. cmd_buf[1] |= IEC101_FILE_NAK;
  437. cmd_buf[2] = FILE_ERR_SIZE;
  438. cmd_len = 3;
  439. break;
  440. }
  441. // 检查文件CRC
  442. if (CrcStr(g_file101.file_buf, g_file101.file_length) != g_file101.file_crc)
  443. {
  444. _file_state_reset();
  445. cmd_buf[1] |= IEC101_FILE_NAK;
  446. cmd_buf[2] = FILE_ERR_CRC;
  447. cmd_len = 3;
  448. break;
  449. }
  450. // 文件保存
  451. if (g_file_item[g_file101.file_index].file_func(g_file101.file_index) != 0)
  452. {
  453. _file_state_reset();
  454. cmd_buf[1] |= IEC101_FILE_NAK;
  455. cmd_buf[2] = FILE_ERR_SAVE;
  456. cmd_len = 3;
  457. break;
  458. }
  459. // 一切正常,肯定应答
  460. cmd_buf[1] |= IEC101_FILE_ACK;
  461. cmd_len = 2;
  462. // 复位全部状态后,设置状态为FS_RESULT_DOWN,继续应答重发确认帧。
  463. _file_state_reset();
  464. g_file101.state = FS_RESULT_DOWN;
  465. break;
  466. case 0x08:
  467. // 上传结果确认
  468. // 检查文件阶段
  469. if ((g_file101.state != FS_DATA_UP) && (g_file101.state != FS_RESULT_UP))
  470. {
  471. _file_state_reset();
  472. cmd_buf[1] |= IEC101_FILE_NAK;
  473. cmd_buf[2] = FILE_ERR_PHASE;
  474. cmd_len = 3;
  475. break;
  476. }
  477. // 如果是重复报文,继续肯定应答。
  478. if (g_file101.state == FS_RESULT_UP)
  479. {
  480. cmd_buf[1] |= IEC101_FILE_ACK;
  481. cmd_len = 2;
  482. break;
  483. }
  484. // 一切正常,肯定应答
  485. cmd_buf[1] |= IEC101_FILE_ACK;
  486. cmd_len = 2;
  487. // 复位全部状态后,设置状态为FS_RESULT_UP,继续应答重发确认帧。
  488. _file_state_reset();
  489. g_file101.state = FS_RESULT_UP;
  490. break;
  491. break;
  492. default:
  493. rt_printf("IEC101_TransFile:不支持的命令(%d)\r\n", buf[0]);
  494. _file_state_reset();
  495. cmd_buf[1] |= IEC101_FILE_NAK;
  496. cmd_buf[2] = FILE_ERR_OTHER;
  497. cmd_len = 3;
  498. break;
  499. }
  500. return cmd_len;
  501. }
  502. int file_check(s8 *name, u32 attr)
  503. {
  504. int i;
  505. for (i = 0; i < FILE_ITEM_NUM; i++)
  506. {
  507. if (strcmp(name, g_file_item[i].file_name) == 0)
  508. {
  509. if (attr & g_file_item[i].file_attr)
  510. {
  511. return i;
  512. }
  513. }
  514. }
  515. return -1;
  516. }
  517. int file_check_type(s8 *name, u32 attr)
  518. {
  519. int i;
  520. for (i = 0; i < FILE_ITEM_NUM; i++)
  521. {
  522. if (strcmp(name, g_file_item[i].file_name) == 0)
  523. {
  524. return g_file_item[i].file_type;
  525. }
  526. }
  527. return -1;
  528. }
  529. int file_check_info(int index)
  530. {
  531. char file_name[64];
  532. u32 len;
  533. u16 crc;
  534. u8 *buf;
  535. struct cfg_file_head *brh;
  536. unsigned int signature; // 配置文件签名
  537. struct file *pfile;
  538. loff_t pos;
  539. if ((g_file_item[index].file_type == FILETYPE_INNERGPRS) || (g_file_item[index].file_type == FILETYPE_SYS))
  540. {
  541. return 0;
  542. }
  543. sprintf(file_name, "%s%s", "/tmp/", g_file_item[index].file_name);
  544. // 打开文件
  545. pfile = rt_file_open(file_name, O_RDONLY, 0);
  546. if (IS_ERR(pfile))
  547. {
  548. return -1;
  549. }
  550. // 得到文件长度
  551. len = rt_file_getfile_size(pfile);
  552. if (len <= 0)
  553. {
  554. rt_file_close(pfile, 0);
  555. return -11;
  556. }
  557. // 分配内存
  558. buf = rt_malloc(len);
  559. if ((buf) == NULL)
  560. {
  561. rt_file_close(pfile, 0);
  562. return -2;
  563. }
  564. // 读出内容
  565. pos = 0;
  566. if (rt_file_read(pfile, buf, len, &pos) != len)
  567. {
  568. rt_file_close(pfile, 0);
  569. rt_free(buf);
  570. return -3;
  571. }
  572. // 关闭文件
  573. rt_file_close(pfile, 0);
  574. // 检查CRC
  575. crc = CrcStr(buf, len - 2);
  576. if (g_file_item[index].file_type == FILETYPE_CHILDPRO)
  577. {
  578. crc = CrcStr(buf + 64, len - 2 - 64);
  579. // swap16(&crc);
  580. }
  581. if (g_file_item[index].file_type == FILETYPE_F308_HMI)
  582. {
  583. crc = CrcStr(buf + 64, len - 2 - 64);
  584. }
  585. if ((g_file_item[index].file_type == FILETYPE_MAINAPP) || (g_file_item[index].file_type == FILETYPE_CHILDPRO) || (g_file_item[index].file_type == FILETYPE_F308_HMI))
  586. {
  587. // ko,或子板程序
  588. #ifdef MODE_LITTLE_ENDIAN
  589. swap16(&crc);
  590. #endif
  591. }
  592. if (crc != *(u16 *)(buf + len - 2))
  593. {
  594. rt_free(buf);
  595. return -4;
  596. }
  597. // 检查文件签名
  598. brh = (struct cfg_file_head *)buf;
  599. signature = 0;
  600. switch (g_file_item[index].file_type)
  601. {
  602. case FILETYPE_CFG:
  603. signature = SIG_EQU_CFG_FILE;
  604. break;
  605. case FILETYPE_SET:
  606. signature = SIG_SET_DATA_FILE;
  607. break;
  608. case FILETYPE_TABLE:
  609. signature = SIG_TABLE_FILE;
  610. break;
  611. case FILETYPE_BRD:
  612. signature = SIG_EQU_RES_FILE;
  613. break;
  614. case FILETYPE_MAINAPP:
  615. case FILETYPE_FPGA:
  616. case FILETYPE_CHILDPRO:
  617. case FILETYPE_OTHER:
  618. case FILETYPE_GPRSDRIVER:
  619. case FILETYPE_GPRSAPP:
  620. case FILETYPE_F308_HMI:
  621. case FILETYPE_PPL:
  622. rt_free(buf);
  623. return 0;
  624. break;
  625. }
  626. if (brh->signature != signature)
  627. {
  628. rt_free(buf);
  629. return -5;
  630. }
  631. return 0;
  632. }
  633. u32 file_change_time(int index)
  634. {
  635. struct stat s;
  636. char file_name[64];
  637. sprintf(file_name, "%s%s", g_file_item[index].file_dir, g_file_item[index].file_name);
  638. if (sys_newstat((char *)file_name, &s))
  639. {
  640. return -1;
  641. }
  642. return s.st_mtime;
  643. }
  644. /*------------------------------ 内部函数 -------------------------------------
  645. 内部函数以下划线‘_’开头,不需要检查参数的合法性.
  646. */
  647. #if 0
  648. static int _file_check(s8 * name,u32 attr)
  649. {
  650. int i;
  651. char file_name[64];
  652. for(i=0; i< FILE_ITEM_NUM; i++)
  653. {
  654. sprintf(file_name,"%s%s",g_file_item[i].file_dir,g_file_item[i].file_name);
  655. if(strcmp(name,file_name) == 0)
  656. {
  657. if(attr & g_file_item[i].file_attr)
  658. {
  659. return i;
  660. }
  661. }
  662. }
  663. return -1;
  664. }
  665. #endif
  666. static int _file_up_info(int index)
  667. {
  668. char file_name[64];
  669. struct file *pfile;
  670. loff_t pos;
  671. sprintf(file_name, "%s%s", g_file_item[index].file_dir, g_file_item[index].file_name);
  672. // 打开文件
  673. pfile = rt_file_open(file_name, O_RDONLY, 0);
  674. if (IS_ERR(pfile))
  675. {
  676. return -1;
  677. }
  678. // 得到文件长度
  679. g_file101.file_length = rt_file_getfile_size(pfile);
  680. if (g_file101.file_length == 0)
  681. {
  682. rt_file_close(pfile, 0);
  683. return -11;
  684. }
  685. // 分配内存
  686. g_file101.file_buf = rt_malloc(g_file101.file_length);
  687. if ((g_file101.file_buf) == NULL)
  688. {
  689. rt_file_close(pfile, 0);
  690. return -2;
  691. }
  692. // 读出内容
  693. pos = 0;
  694. if (rt_file_read(pfile, g_file101.file_buf, g_file101.file_length, &pos) != g_file101.file_length)
  695. {
  696. rt_file_close(pfile, 0);
  697. rt_free(g_file101.file_buf);
  698. g_file101.file_buf = 0;
  699. return -3;
  700. }
  701. // 关闭文件
  702. rt_file_close(pfile, 0);
  703. // 计算CRC
  704. g_file101.file_crc = CrcStr(g_file101.file_buf, g_file101.file_length - 2);
  705. // offset
  706. g_file101.file_offset = 0;
  707. // 文件类型
  708. g_file101.file_type = 0;
  709. return 0;
  710. }
  711. static int _file_save_app(int index)
  712. {
  713. char file_name[64];
  714. struct file *pfile;
  715. loff_t pos;
  716. char from_file_name[64];
  717. char to_file_name[64];
  718. g_file_save = 0;
  719. // sprintf(file_name,"%s%s.new",g_file_item[index].file_dir,g_file_item[index].file_name);
  720. sprintf(file_name, "%s%s", "/tmp/", g_file_item[index].file_name);
  721. // 创建并打开文件
  722. pfile = rt_file_open(file_name, O_CREAT | O_RDWR | O_TRUNC | O_SYNC, 0);
  723. if (IS_ERR(pfile))
  724. {
  725. return -1;
  726. }
  727. // 写文件
  728. pos = 0;
  729. if (rt_file_write(pfile, g_file101.file_buf, g_file101.file_length, &pos) != g_file101.file_length)
  730. {
  731. rt_file_close(pfile, 0);
  732. return -2;
  733. }
  734. // 关闭文件
  735. rt_file_close(pfile, 0);
  736. if (file_check_info(index) == 0)
  737. {
  738. sprintf(to_file_name, "%s%s", g_file_item[index].file_dir, g_file_item[index].file_name);
  739. sprintf(from_file_name, "%s%s", "/tmp/", g_file_item[index].file_name);
  740. rt_file_mv(from_file_name, to_file_name);
  741. sprintf(file_name, "%s%s%s", "文件更新", g_file_item[index].file_dir, g_file_item[index].file_name);
  742. log_str_time(LOG_OPERATE, file_name, 0, 0);
  743. g_file_save = 1;
  744. }
  745. else
  746. {
  747. sprintf(from_file_name, "%s%s", "/tmp/", g_file_item[index].file_name);
  748. rt_file_del(from_file_name);
  749. }
  750. return 0;
  751. }
  752. static void _file_state_reset(void)
  753. {
  754. g_file101.state = FS_IDLE;
  755. if (g_file101.file_buf)
  756. {
  757. rt_free(g_file101.file_buf);
  758. g_file101.file_buf = 0;
  759. }
  760. }
  761. static void _file_echo(IEC101_DEF *pt, u8 *cmd_buf, u8 cmd_len) // 确认帧
  762. {
  763. BYTE cnt, checksum, len;
  764. BYTE *p;
  765. BYTE AddByte = 0;
  766. p = pt->tx_buf_s;
  767. if (tRunPara.b101Addr2Byte)
  768. {
  769. AddByte = 1;
  770. p[7] = (BYTE)(tRunPara.byAddr >> 8); // 链路地址高地址
  771. }
  772. // 101规约len域的值 +4=控制域、地址 、类型标识 、 文件命令
  773. len = cmd_len + 2 + AddByte;
  774. // 报文帧长度 +6=报文头(4字节)校验和、结束符
  775. p[0] = len + 6;
  776. // 帧头
  777. p[1] = 0x68; // 报文头
  778. p[2] = len;
  779. p[3] = len;
  780. p[4] = 0x68;
  781. p[5] = IEC101_ECHO_DATA; // 控制域
  782. p[6] = (BYTE)tRunPara.byAddr; // 链路地址
  783. // 命令
  784. p = &pt->tx_buf_s[7 + AddByte]; // 调整位置
  785. memcpy(p, cmd_buf, cmd_len);
  786. // 计算检验和
  787. p = &pt->tx_buf_s[5];
  788. checksum = 0;
  789. for (cnt = 0; cnt < len; cnt++)
  790. {
  791. checksum += *p++;
  792. }
  793. *p++ = checksum;
  794. // 帧尾
  795. *p++ = 0x16;
  796. }
  797. /*------------------------------ 测试函数 -------------------------------------
  798. 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中
  799. 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数).
  800. */
  801. int printf_file101(void)
  802. {
  803. rt_printf("g_file101:\t%p\r\n", &g_file101);
  804. rt_printf("state:\t\t%d\r\n", g_file101.state);
  805. rt_printf("file_name:\t%s\r\n", g_file_item[g_file101.file_index].file_name);
  806. rt_printf("file_index:\t%d\r\n", g_file101.file_index);
  807. rt_printf("file_type:\t%d\r\n", g_file101.file_type);
  808. rt_printf("file_crc:\t0x%04x\r\n", g_file101.file_crc);
  809. rt_printf("file_length:\t%d\r\n", g_file101.file_length);
  810. rt_printf("file_offset:\t%d\r\n", g_file101.file_offset);
  811. rt_printf("file_buf:\t%p\r\n", g_file101.file_buf);
  812. return 0;
  813. }
  814. /*------------------------------ 文件结束 -------------------------------------
  815. */