| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987 |
- /******************************************************************************
- 版权所有:
- 文件名称: IEC101_FILE.c
- 文件版本: 01.01
- 创建作者: sunxi
- 创建日期: 2012-10-10
- 功能说明: 101规约文件传输扩展
- 其它说明:
- 修改记录:
- */
- /*------------------------------- 头文件 --------------------------------------
- */
- #include "head.h"
- /*------------------------------- 宏定义 --------------------------------------
- */
- #define IEC101_TYPE_FILE 137
- #define IEC101_FILE_ACK 0X80
- #define IEC101_FILE_NAK 0X40
- #define FILE_ERR_OK 0x00
- #define FILE_ERR_NAME 0x01
- #define FILE_ERR_TYPE 0x02
- #define FILE_ERR_BUSY 0x03
- #define FILE_ERR_ADDR 0x04
- #define FILE_ERR_SIZE 0x05
- #define FILE_ERR_CRC 0x06
- #define FILE_ERR_SAVE 0x07
- #define FILE_ERR_PHASE 0x08
- #define FILE_ERR_MEM 0x09
- #define FILE_ERR_STATE 0x0a
- #define FILE_ERR_OTHER 0xff
- /*------------------------------ 类型结构 -------------------------------------
- */
- enum fState
- {
- FS_IDLE = 0,
- FS_VERIFY_DOWN,
- FS_VERIFY_UP,
- FS_INFO_DOWN,
- FS_INFO_UP,
- FS_DATA_DOWN,
- FS_DATA_UP,
- FS_RESULT_DOWN,
- FS_RESULT_UP,
- };
- struct file101
- {
- enum fState state;
- s32 file_index;
- u16 file_type;
- u16 file_crc;
- u32 file_length;
- u32 file_offset;
- u8* file_buf;
- };
- /*------------------------------ 全局变量 -------------------------------------
- */
- struct file101 g_file101= {0};
- // 通过串口下载的文件,不需要在maintain中再检查文件
- u8 g_file_save=0;
- /*------------------------------ 函数声明 -------------------------------------
- */
- static int _file_up_info(int index);
- static int _file_save_app(int index);
- //static int _file_check(s8 * name,u32 attr);
- int printf_file101(void);
- struct file_item g_file_item[] =
- {
- {KO_FILE_NAME_1, "/app/", ATTR_UP | ATTR_DOWN, FILETYPE_MAINAPP, _file_save_app},
- {"m", "/app/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"equ_res.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_BRD, _file_save_app},
- {"equ_cfg.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_CFG, _file_save_app},
- {"e2prom.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"brd_res.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"iectable.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_TABLE, _file_save_app},
- {FILE_NAME_PPL_CFG, "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_PPL, _file_save_app},
- {"fixset.csv", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app}, // 固定参数文件
- {"pcolcfg.ini", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app}, // 级联规约文件
- {"vol_status.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"set_data.bin", "/tmp/", ATTR_UP | ATTR_DOWN, FILETYPE_SET, _file_save_app},
- {FILE_NAME_RSC, "/tmp/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {FILE_NAME_PPL_RSC, "/tmp/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {FILE_NAME_SET_DESC, "/tmp/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"env.dat", "/tmp/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"instu.bin", "/tmp/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"log_err.txt", "/app/data/", ATTR_UP, FILETYPE_LOG_APP, _file_save_app},
- {"log_operate.txt", "/app/data/", ATTR_UP, FILETYPE_LOG_APP, _file_save_app},
- {"log_soe.txt", "/app/data/", ATTR_UP, FILETYPE_LOG_APP, _file_save_app},
- {"log_yx.txt", "/app/data/", ATTR_UP, FILETYPE_LOG_APP, _file_save_app},
- {"log_fixset.txt", "/app/data/", ATTR_UP, FILETYPE_LOG_GPRS, _file_save_app},
- {"log_gprs.txt", "/app/data/", ATTR_UP, FILETYPE_LOG_GPRS, _file_save_app},
- {"logcfg.xml", "/app/IEC61850/cfg/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"osicfg.xml", "/app/IEC61850/cfg/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"file_list.bin", "/tmp/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- #if (0)
- {"f306.ko", "/app/", ATTR_UP | ATTR_DOWN, FILETYPE_MAINAPP, _file_save_app},
- {"f308.ko", "/app/", ATTR_UP | ATTR_DOWN, FILETYPE_MAINAPP, _file_save_app},
- {"u-boot.bin", "/tmp/", ATTR_DOWN, FILETYPE_SYS, _file_save_app}, // 引导程序
- {"uImage", "/tmp/", ATTR_DOWN, FILETYPE_SYS, _file_save_app}, // 内核程序
- {"app.jffs2", "/tmp/", ATTR_DOWN, FILETYPE_SYS, _file_save_app}, // 应用系统
- {"rootfs.jffs2", "/tmp/", ATTR_DOWN, FILETYPE_SYS, _file_save_app}, // 内核系统
- {"image_flash.bin", "/tmp/", ATTR_DOWN, FILETYPE_SYS, _file_save_app}, // 烧录系统
- {"innergprs.ini", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_INNERGPRS, _file_save_app},
- {FILE_NAME_GPRSDRIVER, "/app/", ATTR_UP | ATTR_DOWN, FILETYPE_GPRSDRIVER, _file_save_app},
- {"gprs_app", "/app/", ATTR_UP | ATTR_DOWN, FILETYPE_GPRSAPP, _file_save_app},
- {"rec_wave.dat", "/tmp/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"F308_HMI.bin", "/tmp/", ATTR_UP | ATTR_DOWN, FILETYPE_F308_HMI, _file_save_app},
- {"DTU-DIDO.elf.bin", "/tmp/", ATTR_UP | ATTR_DOWN, FILETYPE_CHILDPRO, _file_save_app},
- {"changelog.txt", "/app/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- // {"acfactor.bin", "/app/data/", ATTR_UP, FILETYPE_OTHER, _file_save_app},
- // {"dcfactor.bin", "/app/data/", ATTR_UP, FILETYPE_OTHER, _file_save_app},
- {"hzk.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"sm2key0.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"sm2key1.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"sm2key2.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"sm2key3.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"userid.bin", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"x509_time0", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"x509_time1", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"x509_time2", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"x509_time3", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"sysm2_0.cer", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"sysm2_1.cer", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"sysm2_2.cer", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"sysm2_3.cer", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"master_slave_equ_sync", "/app/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"factor_modify", "/app/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"mainImage.lcd", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"lcd_menu.csv", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"vir_mix_table.csv", "/app/data/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {wave_name[0], "/app/data/rec_wave/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {wave_name[1], "/app/data/rec_wave/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {wave_name[2], "/app/data/rec_wave/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {wave_name[3], "/app/data/rec_wave/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {wave_name[4], "/app/data/rec_wave/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {wave_name[5], "/app/data/rec_wave/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {wave_name[6], "/app/data/rec_wave/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {wave_name[7], "/app/data/rec_wave/", ATTR_UP | ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- #endif
- };
- const int FILE_LIST_NUM = (sizeof(g_file_item) / sizeof(struct file_item));
- #define FILE_ITEM_NUM (sizeof(g_file_item) / sizeof(struct file_item))
- struct stat g_file_time[FILE_ITEM_NUM]; // 文件最新修改时间
- /*------------------------------ 函数声明 -------------------------------------
- */
- int file_check(s8 *name, u32 attr);
- static void _file_state_reset(void);
- static void _file_echo(IEC101_DEF *pt, u8 *cmd_buf, u8 cmd_len);
- /*------------------------------ 外部函数 -------------------------------------
- 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性.
- */
- int IEC101_TransFile(IEC101_DEF *pt, unsigned char *buf, int len)
- {
- u8 cmd_len;
- u8 cmd_buf[256];
- cmd_len = com_trans_file(buf, len, cmd_buf);
- // 按101格式组帧
- _file_echo(pt, cmd_buf, cmd_len);
- return 0;
- }
- extern bool g_mt_rs232;
- int IEC101_Maintain(IEC101_DEF *pt, unsigned char *buf, int len)
- {
- u8 cmd_buf[256];
- u8 cmd_len;
- g_mt_rs232 = 1;
- memset(cmd_buf, 0, sizeof(cmd_buf));
- cmd_len = Maintain_Manage(buf, len, cmd_buf);
- // 按101格式组帧
- _file_echo(pt, &cmd_buf[0], cmd_len);
- return 0;
- }
- int com_trans_file(u8 *buf, u32 len, u8 *cmd_buf)
- {
- u8 cmd_len = 0;
- u32 offset;
- cmd_buf[0] = IEC101_TYPE_FILE;
- cmd_buf[1] = buf[1];
- switch (buf[1])
- {
- case 0x01:
- // 下载请求验证
- // 复位状态机
- _file_state_reset();
- sprintf(cmd_buf + 2, szTool);
- sprintf(cmd_buf + 21, VER_TIME "CRC:%04XH", m_CodeCrc);
- cmd_len = strlen(cmd_buf + 2) + 1 + 2;
- #if 0
- if(memcmp(buf+2,szTool,19) != 0) // 具体版本号暂时不检查(匹配V1.XX.XX)
- {
- cmd_buf[1] |= IEC101_FILE_NAK;
- break;
- }
- #endif
- cmd_buf[1] |= IEC101_FILE_ACK;
- g_file101.state = FS_VERIFY_DOWN;
- break;
- case 0x02:
- // 上传请求验证
- // 复位状态机
- _file_state_reset();
- sprintf(cmd_buf + 2, szTool);
- sprintf(cmd_buf + 21, VER_TIME "CRC:%04XH", m_CodeCrc);
- cmd_len = strlen(cmd_buf + 2) + 1 + 2;
- #if 0
- if(memcmp(buf+2,szTool,19) != 0) // 具体版本号暂时不检查(匹配V1.XX.XX)
- {
- cmd_buf[1] |= IEC101_FILE_NAK;
- break;
- }
- #endif
- cmd_buf[1] |= IEC101_FILE_ACK;
- g_file101.state = FS_VERIFY_UP;
- break;
- case 0x03:
- // 下载文件信息
- memcpy(cmd_buf + 2, buf + 2, 64); // copy file name
- cmd_buf[65] = 0;
- memcpy(&g_file101.file_type, buf + 66, 2);
- swap16(&g_file101.file_type);
- memcpy(&g_file101.file_length, buf + 68, 4);
- swap32(&g_file101.file_length);
- memcpy(&g_file101.file_crc, buf + 72, 2);
- swap16(&g_file101.file_crc);
- g_file101.file_offset = 0;
- // 检查文件阶段
- if ((g_file101.state != FS_VERIFY_DOWN) && (g_file101.state != FS_INFO_DOWN))
- {
- _file_state_reset();
- cmd_buf[1] |= IEC101_FILE_NAK;
- cmd_buf[22] = FILE_ERR_PHASE;
- cmd_len = 23;
- break;
- }
- // 检查文件名
- g_file101.file_index = file_check(cmd_buf + 2, ATTR_DOWN);
- if (g_file101.file_index < 0)
- {
- _file_state_reset();
- cmd_buf[1] |= IEC101_FILE_NAK;
- cmd_buf[66] = FILE_ERR_NAME;
- cmd_len = 67;
- break;
- }
- // 检查文件长度
- if (g_file101.file_length > 4 * 1024 * 1024)
- {
- _file_state_reset();
- cmd_buf[1] |= IEC101_FILE_NAK;
- cmd_buf[66] = FILE_ERR_SIZE;
- cmd_len = 67;
- break;
- }
- // 分配内存
- g_file101.file_buf = rt_malloc(g_file101.file_length);
- if ((g_file101.file_buf) == NULL)
- {
- _file_state_reset();
- cmd_buf[1] |= IEC101_FILE_NAK;
- cmd_buf[66] = FILE_ERR_MEM;
- cmd_len = 67;
- break;
- }
- // 所有检查通过,应答ACK
- cmd_buf[1] |= IEC101_FILE_ACK;
- cmd_len = 66;
- // printf_file101();
- // 修改状态
- g_file101.state = FS_INFO_DOWN;
- break;
- case 0x04:
- // 上传文件信息
- memcpy(cmd_buf + 2, buf + 2, 64); // copy file name
- cmd_buf[65] = 0;
- // 检查文件阶段
- if ((g_file101.state != FS_VERIFY_UP) && (g_file101.state != FS_INFO_UP))
- {
- // 阶段不对
- _file_state_reset();
- cmd_buf[1] |= IEC101_FILE_NAK;
- cmd_buf[66] = FILE_ERR_PHASE;
- cmd_len = 67;
- break;
- }
- // 检查文件名称
- g_file101.file_index = file_check(cmd_buf + 2, ATTR_UP);
- if (g_file101.file_index < 0)
- {
- _file_state_reset();
- cmd_buf[1] |= IEC101_FILE_NAK;
- cmd_buf[66] = FILE_ERR_NAME;
- cmd_len = 67;
- break;
- }
- // 取得文件信息
- if (_file_up_info(g_file101.file_index) != 0)
- {
- _file_state_reset();
- cmd_buf[1] |= IEC101_FILE_NAK;
- cmd_buf[66] = FILE_ERR_NAME;
- cmd_len = 67;
- break;
- }
- // printf_file101();
- // 文件准备就绪,应答ACK
- memcpy(cmd_buf + 66, &g_file101.file_type, 2);
- swap16(cmd_buf + 66);
- memcpy(cmd_buf + 68, &g_file101.file_length, 4);
- swap32(cmd_buf + 68);
- memcpy(cmd_buf + 72, &g_file101.file_crc, 2);
- swap16(cmd_buf + 72);
- cmd_buf[1] |= IEC101_FILE_ACK;
- cmd_len = 74;
- // 修改状态
- g_file101.state = FS_INFO_UP;
- break;
- case 0x05:
- // 下载文件正文
- memcpy(cmd_buf + 2, buf + 2, 4);
- memcpy(&offset, buf + 2, 4);
- swap32(&offset);
- // 检查文件阶段
- if ((g_file101.state != FS_INFO_DOWN) && (g_file101.state != FS_DATA_DOWN))
- {
- _file_state_reset();
- cmd_buf[1] |= IEC101_FILE_NAK;
- cmd_buf[6] = FILE_ERR_PHASE;
- cmd_len = 7;
- break;
- }
- // 检查文件buf
- if (g_file101.file_buf == NULL)
- {
- rt_printf("IEC101_TransFilefile_buf==NULL\r\n");
- _file_state_reset();
- cmd_buf[1] |= IEC101_FILE_NAK;
- cmd_buf[6] = FILE_ERR_STATE;
- cmd_len = 7;
- break;
- }
- // 检查文件offset
- if (offset == g_file101.file_offset)
- {
- // 一切正常,获取数据
- len -= 2 + 4;
- memcpy(g_file101.file_buf + offset, buf + 6, len);
- g_file101.file_offset += len;
- }
- else
- {
- rt_printf("IEC101_TransFile:offset\r\n");
- }
- // 发送ACK
- cmd_buf[1] |= IEC101_FILE_ACK;
- memcpy(cmd_buf + 2, &g_file101.file_offset, 4);
- swap32(cmd_buf + 2);
- cmd_len = 6;
- // 修改状态
- g_file101.state = FS_DATA_DOWN;
- break;
- case 0x06:
- // 上传文件正文
- memcpy(cmd_buf + 2, buf + 2, 4);
- memcpy(&offset, buf + 2, 4);
- swap32(&offset);
- // 检查文件阶段
- if ((g_file101.state != FS_INFO_UP) && (g_file101.state != FS_DATA_UP))
- {
- _file_state_reset();
- cmd_buf[1] |= IEC101_FILE_NAK;
- cmd_buf[6] = FILE_ERR_PHASE;
- cmd_len = 7;
- break;
- }
- // 检查文件file_buf
- if (g_file101.file_buf == NULL)
- {
- rt_printf("IEC101_TransFilefile_buf==NULL\r\n");
- _file_state_reset();
- cmd_buf[1] |= IEC101_FILE_NAK;
- cmd_buf[6] = FILE_ERR_STATE;
- cmd_len = 7;
- break;
- }
- // 检查文件offset
- if (offset >= g_file101.file_length)
- {
- _file_state_reset();
- cmd_buf[1] |= IEC101_FILE_NAK;
- cmd_buf[6] = FILE_ERR_ADDR;
- cmd_len = 7;
- break;
- }
- // 发送ACK
- cmd_buf[1] |= IEC101_FILE_ACK;
- if (g_file101.file_length - offset > 200)
- {
- cmd_len = 200;
- }
- else
- {
- cmd_len = g_file101.file_length - offset;
- }
- memcpy(cmd_buf + 6, g_file101.file_buf + offset, cmd_len);
- cmd_len += 6;
- // 修改状态
- g_file101.state = FS_DATA_UP;
- break;
- break;
- case 0x07:
- // 下载结果确认
- // 检查文件阶段
- if ((g_file101.state != FS_DATA_DOWN) && (g_file101.state != FS_RESULT_DOWN))
- {
- _file_state_reset();
- cmd_buf[1] |= IEC101_FILE_NAK;
- cmd_buf[2] = FILE_ERR_PHASE;
- cmd_len = 3;
- break;
- }
- // 如果是重复报文,继续肯定应答。
- if (g_file101.state == FS_RESULT_DOWN)
- {
- // 判断是否需要复位
- if (buf[2] == 1) // 0:不复位;1:复位
- {
- watchdog_reset_cpu(1);
- }
- cmd_buf[1] |= IEC101_FILE_ACK;
- cmd_len = 2;
- break;
- }
- // 检查文件长度
- if (g_file101.file_offset != g_file101.file_length)
- {
- _file_state_reset();
- cmd_buf[1] |= IEC101_FILE_NAK;
- cmd_buf[2] = FILE_ERR_SIZE;
- cmd_len = 3;
- break;
- }
- // 检查文件CRC
- if (CrcStr(g_file101.file_buf, g_file101.file_length) != g_file101.file_crc)
- {
- _file_state_reset();
- cmd_buf[1] |= IEC101_FILE_NAK;
- cmd_buf[2] = FILE_ERR_CRC;
- cmd_len = 3;
- break;
- }
- // 文件保存
- if (g_file_item[g_file101.file_index].file_func(g_file101.file_index) != 0)
- {
- _file_state_reset();
- cmd_buf[1] |= IEC101_FILE_NAK;
- cmd_buf[2] = FILE_ERR_SAVE;
- cmd_len = 3;
- break;
- }
- // 一切正常,肯定应答
- cmd_buf[1] |= IEC101_FILE_ACK;
- cmd_len = 2;
- // 复位全部状态后,设置状态为FS_RESULT_DOWN,继续应答重发确认帧。
- _file_state_reset();
- g_file101.state = FS_RESULT_DOWN;
- break;
- case 0x08:
- // 上传结果确认
- // 检查文件阶段
- if ((g_file101.state != FS_DATA_UP) && (g_file101.state != FS_RESULT_UP))
- {
- _file_state_reset();
- cmd_buf[1] |= IEC101_FILE_NAK;
- cmd_buf[2] = FILE_ERR_PHASE;
- cmd_len = 3;
- break;
- }
- // 如果是重复报文,继续肯定应答。
- if (g_file101.state == FS_RESULT_UP)
- {
- cmd_buf[1] |= IEC101_FILE_ACK;
- cmd_len = 2;
- break;
- }
- // 一切正常,肯定应答
- cmd_buf[1] |= IEC101_FILE_ACK;
- cmd_len = 2;
- // 复位全部状态后,设置状态为FS_RESULT_UP,继续应答重发确认帧。
- _file_state_reset();
- g_file101.state = FS_RESULT_UP;
- break;
- break;
- default:
- rt_printf("IEC101_TransFile:不支持的命令(%d)\r\n", buf[0]);
- _file_state_reset();
- cmd_buf[1] |= IEC101_FILE_NAK;
- cmd_buf[2] = FILE_ERR_OTHER;
- cmd_len = 3;
- break;
- }
- return cmd_len;
- }
- int file_check(s8 *name, u32 attr)
- {
- int i;
- for (i = 0; i < FILE_ITEM_NUM; i++)
- {
- if (strcmp(name, g_file_item[i].file_name) == 0)
- {
- if (attr & g_file_item[i].file_attr)
- {
- return i;
- }
- }
- }
- return -1;
- }
- int file_check_type(s8 *name, u32 attr)
- {
- int i;
- for (i = 0; i < FILE_ITEM_NUM; i++)
- {
- if (strcmp(name, g_file_item[i].file_name) == 0)
- {
- return g_file_item[i].file_type;
- }
- }
- return -1;
- }
- int file_check_info(int index)
- {
- char file_name[64];
- u32 len;
- u16 crc;
- u8 *buf;
- struct cfg_file_head *brh;
- unsigned int signature; // 配置文件签名
- struct file *pfile;
- loff_t pos;
- if ((g_file_item[index].file_type == FILETYPE_INNERGPRS) || (g_file_item[index].file_type == FILETYPE_SYS))
- {
- return 0;
- }
- sprintf(file_name, "%s%s", "/tmp/", g_file_item[index].file_name);
- // 打开文件
- pfile = rt_file_open(file_name, O_RDONLY, 0);
- if (IS_ERR(pfile))
- {
- return -1;
- }
- // 得到文件长度
- len = rt_file_getfile_size(pfile);
- if (len <= 0)
- {
- rt_file_close(pfile, 0);
- return -11;
- }
- // 分配内存
- buf = rt_malloc(len);
- if ((buf) == NULL)
- {
- rt_file_close(pfile, 0);
- return -2;
- }
- // 读出内容
- pos = 0;
- if (rt_file_read(pfile, buf, len, &pos) != len)
- {
- rt_file_close(pfile, 0);
- rt_free(buf);
- return -3;
- }
- // 关闭文件
- rt_file_close(pfile, 0);
- // 检查CRC
- crc = CrcStr(buf, len - 2);
- if (g_file_item[index].file_type == FILETYPE_CHILDPRO)
- {
- crc = CrcStr(buf + 64, len - 2 - 64);
- // swap16(&crc);
- }
- if (g_file_item[index].file_type == FILETYPE_F308_HMI)
- {
- crc = CrcStr(buf + 64, len - 2 - 64);
- }
- 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))
- {
- // ko,或子板程序
- #ifdef MODE_LITTLE_ENDIAN
- swap16(&crc);
- #endif
- }
- if (crc != *(u16 *)(buf + len - 2))
- {
- rt_free(buf);
- return -4;
- }
- // 检查文件签名
- brh = (struct cfg_file_head *)buf;
- signature = 0;
- switch (g_file_item[index].file_type)
- {
- case FILETYPE_CFG:
- signature = SIG_EQU_CFG_FILE;
- break;
- case FILETYPE_SET:
- signature = SIG_SET_DATA_FILE;
- break;
- case FILETYPE_TABLE:
- signature = SIG_TABLE_FILE;
- break;
- case FILETYPE_BRD:
- signature = SIG_EQU_RES_FILE;
- break;
- case FILETYPE_MAINAPP:
- case FILETYPE_FPGA:
- case FILETYPE_CHILDPRO:
- case FILETYPE_OTHER:
- case FILETYPE_GPRSDRIVER:
- case FILETYPE_GPRSAPP:
- case FILETYPE_F308_HMI:
- case FILETYPE_PPL:
- rt_free(buf);
- return 0;
- break;
- }
- if (brh->signature != signature)
- {
- rt_free(buf);
- return -5;
- }
- return 0;
- }
- u32 file_change_time(int index)
- {
- struct stat s;
- char file_name[64];
- sprintf(file_name, "%s%s", g_file_item[index].file_dir, g_file_item[index].file_name);
- if (sys_newstat((char *)file_name, &s))
- {
- return -1;
- }
- return s.st_mtime;
- }
- /*------------------------------ 内部函数 -------------------------------------
- 内部函数以下划线‘_’开头,不需要检查参数的合法性.
- */
- #if 0
- static int _file_check(s8 * name,u32 attr)
- {
- int i;
- char file_name[64];
- for(i=0; i< FILE_ITEM_NUM; i++)
- {
- sprintf(file_name,"%s%s",g_file_item[i].file_dir,g_file_item[i].file_name);
- if(strcmp(name,file_name) == 0)
- {
- if(attr & g_file_item[i].file_attr)
- {
- return i;
- }
- }
- }
- return -1;
- }
- #endif
- static int _file_up_info(int index)
- {
- char file_name[64];
- struct file *pfile;
- loff_t pos;
- sprintf(file_name, "%s%s", g_file_item[index].file_dir, g_file_item[index].file_name);
- // 打开文件
- pfile = rt_file_open(file_name, O_RDONLY, 0);
- if (IS_ERR(pfile))
- {
- return -1;
- }
- // 得到文件长度
- g_file101.file_length = rt_file_getfile_size(pfile);
- if (g_file101.file_length == 0)
- {
- rt_file_close(pfile, 0);
- return -11;
- }
- // 分配内存
- g_file101.file_buf = rt_malloc(g_file101.file_length);
- if ((g_file101.file_buf) == NULL)
- {
- rt_file_close(pfile, 0);
- return -2;
- }
- // 读出内容
- pos = 0;
- if (rt_file_read(pfile, g_file101.file_buf, g_file101.file_length, &pos) != g_file101.file_length)
- {
- rt_file_close(pfile, 0);
- rt_free(g_file101.file_buf);
- g_file101.file_buf = 0;
- return -3;
- }
- // 关闭文件
- rt_file_close(pfile, 0);
- // 计算CRC
- g_file101.file_crc = CrcStr(g_file101.file_buf, g_file101.file_length - 2);
- // offset
- g_file101.file_offset = 0;
- // 文件类型
- g_file101.file_type = 0;
- return 0;
- }
- static int _file_save_app(int index)
- {
- char file_name[64];
- struct file *pfile;
- loff_t pos;
- char from_file_name[64];
- char to_file_name[64];
- g_file_save = 0;
- // sprintf(file_name,"%s%s.new",g_file_item[index].file_dir,g_file_item[index].file_name);
- sprintf(file_name, "%s%s", "/tmp/", g_file_item[index].file_name);
- // 创建并打开文件
- pfile = rt_file_open(file_name, O_CREAT | O_RDWR | O_TRUNC | O_SYNC, 0);
- if (IS_ERR(pfile))
- {
- return -1;
- }
- // 写文件
- pos = 0;
- if (rt_file_write(pfile, g_file101.file_buf, g_file101.file_length, &pos) != g_file101.file_length)
- {
- rt_file_close(pfile, 0);
- return -2;
- }
- // 关闭文件
- rt_file_close(pfile, 0);
- if (file_check_info(index) == 0)
- {
- sprintf(to_file_name, "%s%s", g_file_item[index].file_dir, g_file_item[index].file_name);
- sprintf(from_file_name, "%s%s", "/tmp/", g_file_item[index].file_name);
- rt_file_mv(from_file_name, to_file_name);
- sprintf(file_name, "%s%s%s", "文件更新", g_file_item[index].file_dir, g_file_item[index].file_name);
- log_str_time(LOG_OPERATE, file_name, 0, 0);
- g_file_save = 1;
- }
- else
- {
- sprintf(from_file_name, "%s%s", "/tmp/", g_file_item[index].file_name);
- rt_file_del(from_file_name);
- }
- return 0;
- }
- static void _file_state_reset(void)
- {
- g_file101.state = FS_IDLE;
- if (g_file101.file_buf)
- {
- rt_free(g_file101.file_buf);
- g_file101.file_buf = 0;
- }
- }
- static void _file_echo(IEC101_DEF *pt, u8 *cmd_buf, u8 cmd_len) // 确认帧
- {
- BYTE cnt, checksum, len;
- BYTE *p;
- BYTE AddByte = 0;
- p = pt->tx_buf_s;
- if (tRunPara.b101Addr2Byte)
- {
- AddByte = 1;
- p[7] = (BYTE)(tRunPara.byAddr >> 8); // 链路地址高地址
- }
- // 101规约len域的值 +4=控制域、地址 、类型标识 、 文件命令
- len = cmd_len + 2 + AddByte;
- // 报文帧长度 +6=报文头(4字节)校验和、结束符
- p[0] = len + 6;
- // 帧头
- p[1] = 0x68; // 报文头
- p[2] = len;
- p[3] = len;
- p[4] = 0x68;
- p[5] = IEC101_ECHO_DATA; // 控制域
- p[6] = (BYTE)tRunPara.byAddr; // 链路地址
- // 命令
- p = &pt->tx_buf_s[7 + AddByte]; // 调整位置
- memcpy(p, cmd_buf, cmd_len);
- // 计算检验和
- p = &pt->tx_buf_s[5];
- checksum = 0;
- for (cnt = 0; cnt < len; cnt++)
- {
- checksum += *p++;
- }
- *p++ = checksum;
- // 帧尾
- *p++ = 0x16;
- }
- /*------------------------------ 测试函数 -------------------------------------
- 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中
- 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数).
- */
- int printf_file101(void)
- {
- rt_printf("g_file101:\t%p\r\n", &g_file101);
- rt_printf("state:\t\t%d\r\n", g_file101.state);
- rt_printf("file_name:\t%s\r\n", g_file_item[g_file101.file_index].file_name);
- rt_printf("file_index:\t%d\r\n", g_file101.file_index);
- rt_printf("file_type:\t%d\r\n", g_file101.file_type);
- rt_printf("file_crc:\t0x%04x\r\n", g_file101.file_crc);
- rt_printf("file_length:\t%d\r\n", g_file101.file_length);
- rt_printf("file_offset:\t%d\r\n", g_file101.file_offset);
- rt_printf("file_buf:\t%p\r\n", g_file101.file_buf);
- return 0;
- }
- /*------------------------------ 文件结束 -------------------------------------
- */
|