NodeLinkSlave.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #include "NodeLinkSlave.h"
  2. #include "NodeLinkCommon.h"
  3. #include "encrypt_xxtea.h"
  4. #include <string.h>
  5. static unsigned char native_data_in_buffer[NATIVE_DATA_BUFFER_SIZE];
  6. /**
  7. * 设置本地输入缓冲
  8. *
  9. * @author lxz (041620 15:46:10)
  10. *
  11. * @param slave 从站对象
  12. * @param buffer 缓冲
  13. * @param total 总数
  14. */
  15. void nodelink_slave_set_native_in_buffer(nodelink_slave_t *slave,
  16. unsigned char *buffer,
  17. int total) {
  18. dh_fifo_init(&slave->native_data_in, buffer, total);
  19. }
  20. /**
  21. * 初始化了整个从站信息,并设置类型
  22. *
  23. * @author lxz (041620 15:28:37)
  24. *
  25. * @param slave 从站对象
  26. * @param type 从站设备类型
  27. * @param ops 从站对应操作函数
  28. */
  29. void nodelink_slave_init(nodelink_slave_t *slave, unsigned char model, nodelink_slave_ops *ops) {
  30. memset(slave, 0, sizeof(nodelink_slave_t));
  31. slave->model = model;
  32. slave->ops = ops;
  33. nodelink_slave_set_native_in_buffer(slave, &native_data_in_buffer[0], sizeof(native_data_in_buffer));
  34. }
  35. /**
  36. * 从站运行处理函数
  37. *
  38. * @author lxz (041620 16:08:23)
  39. *
  40. * @param slave 从站对象
  41. */
  42. void nodelink_slave_run(nodelink_slave_t *slave) {
  43. //判断接收是否完成
  44. if (slave->recv_ok) {
  45. if (slave->data_in_count > 0) { //有数据进入
  46. //解码
  47. unsigned char id;
  48. int len = nodelink_decode(&id, slave->data_in, slave->data_in, slave->data_in_count);
  49. if (len > 0) {
  50. len = 0;
  51. //通过判断ID执行对应处理
  52. if (id == 0x00) {
  53. //分配ID
  54. if (slave->data_in[0] == 0xA0 && slave->id == 0) { //当ID为0时会响应0xA0指令
  55. //校验附带的校验码
  56. uint32_t key[4] = { 0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF };
  57. uint32_t code[4];
  58. code[0] = (slave->data_in[1]) | (slave->data_in[2] << 8) | (slave->data_in[3] << 16) | (slave->data_in[4] << 24);
  59. code[1] = (slave->data_in[5]) | (slave->data_in[6] << 8) | (slave->data_in[7] << 16) | (slave->data_in[8] << 24);
  60. code[2] = (slave->data_in[9]) | (slave->data_in[10] << 8) | (slave->data_in[11] << 16) | (slave->data_in[12] << 24);
  61. code[3] = (slave->data_in[13]) | (slave->data_in[14] << 8) | (slave->data_in[15] << 16) | (slave->data_in[16] << 24);
  62. xxtea_uint_decrypt(code, 4, key);
  63. //申请进入分配ID模式
  64. slave->status = 0xA0;
  65. slave->data_out[len++] = 0xA0;
  66. //将发送的数据进行解码回发
  67. memcpy(&slave->data_out[len], code, 16);
  68. len += 16;
  69. }
  70. else if (slave->data_in[0] == 0xA1) { //当进入分配ID指令时并且ID为0时或者ID为指定ID时响应指令
  71. if ((slave->status == 0xA0 && slave->id == 0) || slave->id == slave->data_in[1]) {
  72. //允许ID配置模式或ID相同的模式下,才响应该包
  73. slave->status = 0;
  74. slave->id = slave->data_in[1];
  75. slave->data_out[len++] = slave->data_in[0];
  76. slave->data_out[len++] = slave->model;
  77. slave->ops->event_handle(NL_SLAVE_EVENT_SETID,slave->id);
  78. }
  79. }
  80. }
  81. else if (id == 0xf0) {
  82. //复位总线,不需要应答
  83. slave->id = 0;
  84. slave->status = 0x00;
  85. slave->ops->event_handle(NL_SLAVE_EVENT_RESET,0);
  86. }
  87. else if (id == slave->id) {
  88. //设备命令
  89. len = slave->ops->on_deal(&slave->data_out[0], &slave->data_in[0], len);
  90. }
  91. if (len > 0) {
  92. //避免中断造成的异常,需要先赋值
  93. slave->data_in_count = 0;
  94. slave->data_out_posi = 0;
  95. slave->data_out_count = nodelink_encode(slave->id, &slave->data_out[0], &slave->data_out[0], len);
  96. }
  97. }
  98. else
  99. {
  100. slave->ops->event_handle(NL_SLAVE_EVENT_CRCERROR, 0);
  101. }
  102. slave->data_in_count = 0;
  103. }
  104. slave->recv_ok = 0;
  105. }
  106. //发送缓冲数据,这里是为了触发发送,但是外部还是需要在中断中调用
  107. nodelink_slave_native_out(slave);
  108. }
  109. /**
  110. * 本地接收一个数据
  111. *
  112. * @author lxz (041620 16:10:12)
  113. *
  114. * @param slave 从站对象
  115. * @param dat 接收的数据
  116. */
  117. void nodelink_slave_master_in(nodelink_slave_t *slave, unsigned char dat) {
  118. //当本地有ID的情况下不会将高位为0的数据转发
  119. id = dat & 0xf0;
  120. if (id != 0 || slave->id != 0) {
  121. slave->ops->slave_port_down(dat);
  122. }
  123. if (slave->id == id || id == 0xf0 || id == 0x00) {
  124. //属于自己ID的并且与自己当前ID相同的,才会进行接收
  125. slave->data_in[slave->data_in_count++] = dat;
  126. }
  127. }
  128. /**
  129. * 从从站接收到一个字节
  130. *
  131. * @author lxz (041720 19:00:08)
  132. *
  133. * @param slave
  134. * @param dat
  135. */
  136. void nodelink_slave_slave_in(nodelink_slave_t *slave, unsigned char dat) {
  137. //所有经过从站进来的数据需要先进入fifo
  138. slave->ops->slave_port_up(dat);
  139. }
  140. /**
  141. * 本地数据输出函数
  142. *
  143. * @author lxz (041820 12:07:32)
  144. *
  145. * @param slave
  146. */
  147. void nodelink_slave_native_out(nodelink_slave_t *slave) {
  148. //执行本地数据输出
  149. unsigned char dat = 0;
  150. while (slave->data_out_count > 0) { //发送本地数据
  151. dat = slave->data_out[slave->data_out_posi++];
  152. slave->ops->slave_port_up(dat);
  153. slave->data_out_count--;
  154. }
  155. }
  156. /**
  157. * 通知从站接收完毕
  158. *
  159. * @author lxz (070120 15:04:27)
  160. *
  161. * @param slave
  162. */
  163. void nodelink_slave_recv_ok(nodelink_slave_t *slave) {
  164. slave->recv_ok = 1;
  165. }