IEC101_FILE.c 23 KB

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