#include "NodeLinkSlave.h" #include "NodeLinkCommon.h" #include "encrypt_xxtea.h" #include static unsigned char native_data_in_buffer[NATIVE_DATA_BUFFER_SIZE]; /** * 设置本地输入缓冲 * * @author lxz (041620 15:46:10) * * @param slave 从站对象 * @param buffer 缓冲 * @param total 总数 */ void nodelink_slave_set_native_in_buffer(nodelink_slave_t *slave, unsigned char *buffer, int total) { dh_fifo_init(&slave->native_data_in, buffer, total); } /** * 初始化了整个从站信息,并设置类型 * * @author lxz (041620 15:28:37) * * @param slave 从站对象 * @param type 从站设备类型 * @param ops 从站对应操作函数 */ void nodelink_slave_init(nodelink_slave_t *slave, unsigned char model, nodelink_slave_ops *ops) { memset(slave, 0, sizeof(nodelink_slave_t)); slave->model = model; slave->ops = ops; nodelink_slave_set_native_in_buffer(slave, &native_data_in_buffer[0], sizeof(native_data_in_buffer)); } /** * 从站运行处理函数 * * @author lxz (041620 16:08:23) * * @param slave 从站对象 */ void nodelink_slave_run(nodelink_slave_t *slave) { //判断接收是否完成 if (slave->recv_ok) { if (slave->data_in_count > 0) { //有数据进入 //解码 unsigned char id; int len = nodelink_decode(&id, slave->data_in, slave->data_in, slave->data_in_count); if (len > 0) { len = 0; //通过判断ID执行对应处理 if (id == 0x00) { //分配ID if (slave->data_in[0] == 0xA0 && slave->id == 0) { //当ID为0时会响应0xA0指令 //校验附带的校验码 uint32_t key[4] = { 0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF }; uint32_t code[4]; code[0] = (slave->data_in[1]) | (slave->data_in[2] << 8) | (slave->data_in[3] << 16) | (slave->data_in[4] << 24); code[1] = (slave->data_in[5]) | (slave->data_in[6] << 8) | (slave->data_in[7] << 16) | (slave->data_in[8] << 24); code[2] = (slave->data_in[9]) | (slave->data_in[10] << 8) | (slave->data_in[11] << 16) | (slave->data_in[12] << 24); code[3] = (slave->data_in[13]) | (slave->data_in[14] << 8) | (slave->data_in[15] << 16) | (slave->data_in[16] << 24); xxtea_uint_decrypt(code, 4, key); //申请进入分配ID模式 slave->status = 0xA0; slave->data_out[len++] = 0xA0; //将发送的数据进行解码回发 memcpy(&slave->data_out[len], code, 16); len += 16; } else if (slave->data_in[0] == 0xA1) { //当进入分配ID指令时并且ID为0时或者ID为指定ID时响应指令 if ((slave->status == 0xA0 && slave->id == 0) || slave->id == slave->data_in[1]) { //允许ID配置模式或ID相同的模式下,才响应该包 slave->status = 0; slave->id = slave->data_in[1]; slave->data_out[len++] = slave->data_in[0]; slave->data_out[len++] = slave->model; slave->ops->event_handle(NL_SLAVE_EVENT_SETID,slave->id); } } } else if (id == 0xf0) { //复位总线,不需要应答 slave->id = 0; slave->status = 0x00; slave->ops->event_handle(NL_SLAVE_EVENT_RESET,0); } else if (id == slave->id) { //设备命令 len = slave->ops->on_deal(&slave->data_out[0], &slave->data_in[0], len); } if (len > 0) { //避免中断造成的异常,需要先赋值 slave->data_in_count = 0; slave->data_out_posi = 0; slave->data_out_count = nodelink_encode(slave->id, &slave->data_out[0], &slave->data_out[0], len); } } else { slave->ops->event_handle(NL_SLAVE_EVENT_CRCERROR, 0); } slave->data_in_count = 0; } slave->recv_ok = 0; } //发送缓冲数据,这里是为了触发发送,但是外部还是需要在中断中调用 nodelink_slave_native_out(slave); } /** * 本地接收一个数据 * * @author lxz (041620 16:10:12) * * @param slave 从站对象 * @param dat 接收的数据 */ void nodelink_slave_master_in(nodelink_slave_t *slave, unsigned char dat) { //当本地有ID的情况下不会将高位为0的数据转发 id = dat & 0xf0; if (id != 0 || slave->id != 0) { slave->ops->slave_port_down(dat); } if (slave->id == id || id == 0xf0 || id == 0x00) { //属于自己ID的并且与自己当前ID相同的,才会进行接收 slave->data_in[slave->data_in_count++] = dat; } } /** * 从从站接收到一个字节 * * @author lxz (041720 19:00:08) * * @param slave * @param dat */ void nodelink_slave_slave_in(nodelink_slave_t *slave, unsigned char dat) { //所有经过从站进来的数据需要先进入fifo slave->ops->slave_port_up(dat); } /** * 本地数据输出函数 * * @author lxz (041820 12:07:32) * * @param slave */ void nodelink_slave_native_out(nodelink_slave_t *slave) { //执行本地数据输出 unsigned char dat = 0; while (slave->data_out_count > 0) { //发送本地数据 dat = slave->data_out[slave->data_out_posi++]; slave->ops->slave_port_up(dat); slave->data_out_count--; } } /** * 通知从站接收完毕 * * @author lxz (070120 15:04:27) * * @param slave */ void nodelink_slave_recv_ok(nodelink_slave_t *slave) { slave->recv_ok = 1; }