| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005 |
- /******************************************************************************
- 版权所有:
- 文件名称: 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[] =
- {
- {"equ_cfg.bin", "/app/data/", ATTR_UP|ATTR_DOWN, FILETYPE_CFG, _file_save_app},
- {"set_data.bin", "/tmp/", ATTR_UP|ATTR_DOWN, FILETYPE_SET, _file_save_app},
- {"iectable.bin", "/app/data/", ATTR_UP|ATTR_DOWN, FILETYPE_TABLE, _file_save_app},
- {"equ_res.bin", "/app/data/", ATTR_UP|ATTR_DOWN, FILETYPE_BRD, _file_save_app},
- {"f306.ko", "/app/", ATTR_UP|ATTR_DOWN, FILETYPE_MAINAPP, _file_save_app},
- {"f308.ko", "/app/", ATTR_UP|ATTR_DOWN, FILETYPE_MAINAPP, _file_save_app},
- {KO_FILE_NAME_1, "/app/", ATTR_UP|ATTR_DOWN, FILETYPE_MAINAPP, _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_PPL_CFG, "/app/data/", ATTR_UP|ATTR_DOWN, FILETYPE_PPL, _file_save_app},
- {FILE_NAME_SET_DESC,"/tmp/", ATTR_UP|ATTR_DOWN, FILETYPE_OTHER, _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},
- {"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},
- {"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_gprs.txt", "/app/data/", ATTR_UP, FILETYPE_LOG_GPRS, _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},
- #ifdef CPU_AM335X
- {"335x_m", "/app/", ATTR_UP|ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- #else
- {"m", "/app/", ATTR_UP|ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- #endif
- // {"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},
- {"vol_status.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},
- {"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}, // 级联规约文件
- {"env.dat", "/tmp/", ATTR_UP|ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"instu.bin", "/tmp/", ATTR_UP|ATTR_DOWN, FILETYPE_OTHER, _file_save_app},
- {"file_list.bin", "/tmp/", 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},
- {"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},
- {"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},
- };
- 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;
- }
- /*------------------------------ 文件结束 -------------------------------------
- */
|