esp-knx-ip-send.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /**
  2. * esp-knx-ip library for KNX/IP communication on an ESP8266
  3. * Author: Nico Weichbrodt <envy>
  4. * License: MIT
  5. */
  6. #include "esp-knx-ip.h"
  7. /**
  8. * Send functions
  9. */
  10. void ESPKNXIP::send(address_t const &receiver, knx_command_type_t ct, uint8_t data_len, uint8_t *data)
  11. {
  12. if (receiver.value == 0)
  13. return;
  14. #if SEND_CHECKSUM
  15. uint32_t len = 6 + 2 + 8 + data_len + 1; // knx_pkt + cemi_msg + cemi_service + data + checksum
  16. #else
  17. uint32_t len = 6 + 2 + 8 + data_len; // knx_pkt + cemi_msg + cemi_service + data
  18. #endif
  19. DEBUG_PRINT(F("Creating packet with len "));
  20. DEBUG_PRINTLN(len)
  21. uint8_t buf[len];
  22. knx_ip_pkt_t *knx_pkt = (knx_ip_pkt_t *)buf;
  23. knx_pkt->header_len = 0x06;
  24. knx_pkt->protocol_version = 0x10;
  25. knx_pkt->service_type = __ntohs(KNX_ST_ROUTING_INDICATION);
  26. knx_pkt->total_len.len = __ntohs(len);
  27. cemi_msg_t *cemi_msg = (cemi_msg_t *)knx_pkt->pkt_data;
  28. cemi_msg->message_code = KNX_MT_L_DATA_IND;
  29. cemi_msg->additional_info_len = 0;
  30. cemi_service_t *cemi_data = &cemi_msg->data.service_information;
  31. cemi_data->control_1.bits.confirm = 0;
  32. //cemi_data->control_1.bits.ack = 1;
  33. cemi_data->control_1.bits.ack = 0; // ask for ACK? 0-no 1-yes
  34. cemi_data->control_1.bits.priority = B11;
  35. cemi_data->control_1.bits.system_broadcast = 0x01;
  36. cemi_data->control_1.bits.repeat = 0x01; // 0 = repeated telegram, 1 = not repeated telegram
  37. cemi_data->control_1.bits.reserved = 0;
  38. cemi_data->control_1.bits.frame_type = 0x01;
  39. cemi_data->control_2.bits.extended_frame_format = 0x00;
  40. cemi_data->control_2.bits.hop_count = 0x06;
  41. cemi_data->control_2.bits.dest_addr_type = 0x01;
  42. cemi_data->source = physaddr;
  43. cemi_data->destination = receiver;
  44. //cemi_data->destination.bytes.high = (area << 3) | line;
  45. //cemi_data->destination.bytes.low = member;
  46. cemi_data->data_len = data_len;
  47. cemi_data->pci.apci = (ct & 0x0C) >> 2;
  48. //cemi_data->pci.apci = KNX_COT_NCD_ACK;
  49. cemi_data->pci.tpci_seq_number = 0x00;
  50. cemi_data->pci.tpci_comm_type = KNX_COT_UDP; // Type of communication: DATA PACKAGE or CONTROL DATA
  51. //cemi_data->pci.tpci_comm_type = KNX_COT_NCD; // Type of communication: DATA PACKAGE or CONTROL DATA
  52. memcpy(cemi_data->data, data, data_len);
  53. //cemi_data->data[0] = (cemi_data->data[0] & 0x3F) | ((KNX_COT_NCD_ACK & 0x03) << 6);
  54. cemi_data->data[0] = (cemi_data->data[0] & 0x3F) | ((ct & 0x03) << 6);
  55. #if SEND_CHECKSUM
  56. // Calculate checksum, which is just XOR of all bytes
  57. uint8_t cs = buf[0] ^ buf[1];
  58. for (uint32_t i = 2; i < len - 1; ++i)
  59. {
  60. cs ^= buf[i];
  61. }
  62. buf[len - 1] = cs;
  63. #endif
  64. #ifdef ESP_KNX_DEBUG
  65. DEBUG_PRINT(F("Sending packet:"));
  66. for (int i = 0; i < len; ++i)
  67. {
  68. DEBUG_PRINT(F(" 0x"));
  69. DEBUG_PRINT(buf[i], 16);
  70. }
  71. DEBUG_PRINTLN(F(""));
  72. #endif
  73. udp.beginPacketMulticast(MULTICAST_IP, MULTICAST_PORT, WiFi.localIP());
  74. udp.write(buf, len);
  75. udp.endPacket();
  76. }
  77. void ESPKNXIP::send_1bit(address_t const &receiver, knx_command_type_t ct, uint8_t bit)
  78. {
  79. uint8_t buf[] = {(uint8_t)(bit & 0b00000001)};
  80. send(receiver, ct, 1, buf);
  81. }
  82. void ESPKNXIP::send_2bit(address_t const &receiver, knx_command_type_t ct, uint8_t twobit)
  83. {
  84. uint8_t buf[] = {(uint8_t)(twobit & 0b00000011)};
  85. send(receiver, ct, 1, buf);
  86. }
  87. void ESPKNXIP::send_4bit(address_t const &receiver, knx_command_type_t ct, uint8_t fourbit)
  88. {
  89. uint8_t buf[] = {(uint8_t)(fourbit & 0b00001111)};
  90. send(receiver, ct, 1, buf);
  91. }
  92. void ESPKNXIP::send_1byte_int(address_t const &receiver, knx_command_type_t ct, int8_t val)
  93. {
  94. uint8_t buf[] = {0x00, (uint8_t)val};
  95. send(receiver, ct, 2, buf);
  96. }
  97. void ESPKNXIP::send_1byte_uint(address_t const &receiver, knx_command_type_t ct, uint8_t val)
  98. {
  99. uint8_t buf[] = {0x00, val};
  100. send(receiver, ct, 2, buf);
  101. }
  102. void ESPKNXIP::send_2byte_int(address_t const &receiver, knx_command_type_t ct, int16_t val)
  103. {
  104. uint8_t buf[] = {0x00, (uint8_t)(val >> 8), (uint8_t)(val & 0x00FF)};
  105. send(receiver, ct, 3, buf);
  106. }
  107. void ESPKNXIP::send_2byte_uint(address_t const &receiver, knx_command_type_t ct, uint16_t val)
  108. {
  109. uint8_t buf[] = {0x00, (uint8_t)(val >> 8), (uint8_t)(val & 0x00FF)};
  110. send(receiver, ct, 3, buf);
  111. }
  112. void ESPKNXIP::send_2byte_float(address_t const &receiver, knx_command_type_t ct, float val)
  113. {
  114. float v = val * 100.0f;
  115. int e = 0;
  116. for (; v < -2048.0f; v /= 2)
  117. ++e;
  118. for (; v > 2047.0f; v /= 2)
  119. ++e;
  120. long m = (long)round(v) & 0x7FF;
  121. short msb = (short) (e << 3 | m >> 8);
  122. if (val < 0.0f)
  123. msb |= 0x80;
  124. uint8_t buf[] = {0x00, (uint8_t)msb, (uint8_t)m};
  125. send(receiver, ct, 3, buf);
  126. }
  127. void ESPKNXIP::send_3byte_time(address_t const &receiver, knx_command_type_t ct, uint8_t weekday, uint8_t hours, uint8_t minutes, uint8_t seconds)
  128. {
  129. weekday <<= 5;
  130. uint8_t buf[] = {0x00, (uint8_t)(((weekday << 5) & 0xE0) | (hours & 0x1F)), (uint8_t)(minutes & 0x3F), (uint8_t)(seconds & 0x3F)};
  131. send(receiver, ct, 4, buf);
  132. }
  133. void ESPKNXIP::send_3byte_date(address_t const &receiver, knx_command_type_t ct, uint8_t day, uint8_t month, uint8_t year)
  134. {
  135. uint8_t buf[] = {0x00, (uint8_t)(day & 0x1F), (uint8_t)(month & 0x0F), year};
  136. send(receiver, ct, 4, buf);
  137. }
  138. void ESPKNXIP::send_3byte_color(address_t const &receiver, knx_command_type_t ct, uint8_t red, uint8_t green, uint8_t blue)
  139. {
  140. uint8_t buf[] = {0x00, red, green, blue};
  141. send(receiver, ct, 4, buf);
  142. }
  143. void ESPKNXIP::send_4byte_int(address_t const &receiver, knx_command_type_t ct, int32_t val)
  144. {
  145. uint8_t buf[] = {0x00,
  146. (uint8_t)((val & 0xFF000000) >> 24),
  147. (uint8_t)((val & 0x00FF0000) >> 16),
  148. (uint8_t)((val & 0x0000FF00) >> 8),
  149. (uint8_t)((val & 0x000000FF) >> 0)};
  150. send(receiver, ct, 5, buf);
  151. }
  152. void ESPKNXIP::send_4byte_uint(address_t const &receiver, knx_command_type_t ct, uint32_t val)
  153. {
  154. uint8_t buf[] = {0x00,
  155. (uint8_t)((val & 0xFF000000) >> 24),
  156. (uint8_t)((val & 0x00FF0000) >> 16),
  157. (uint8_t)((val & 0x0000FF00) >> 8),
  158. (uint8_t)((val & 0x000000FF) >> 0)};
  159. send(receiver, ct, 5, buf);
  160. }
  161. void ESPKNXIP::send_4byte_float(address_t const &receiver, knx_command_type_t ct, float val)
  162. {
  163. uint8_t buf[] = {0x00, ((uint8_t *)&val)[3], ((uint8_t *)&val)[2], ((uint8_t *)&val)[1], ((uint8_t *)&val)[0]};
  164. send(receiver, ct, 5, buf);
  165. }