71 #include "interfaces/PJON_Interfaces.h"
72 #include "PJONDefines.h"
74 template<
typename Strategy>
79 uint8_t
config = PJON_TX_INFO_BIT | PJON_ACK_REQ_BIT;
81 #if(PJON_INCLUDE_PACKET_ID)
85 #if(PJON_INCLUDE_PORT)
86 uint16_t port = PJON_BROADCAST;
94 _device_id = PJON_NOT_ASSIGNED;
101 PJONLocal(uint8_t device_id) : strategy(Strategy())
103 _device_id = device_id;
111 strategy.begin(_device_id);
112 #if(PJON_INCLUDE_ASYNC_ACK || PJON_INCLUDE_PACKET_ID)
113 _packet_id_seed = PJON_RANDOM(65535) + _device_id;
119 uint16_t compose_packet(
124 uint8_t header = PJON_NO_HEADER,
125 uint16_t packet_id = 0,
126 uint16_t rx_port = PJON_BROADCAST
131 info.tx.id = _device_id;
132 info.header = (header == PJON_NO_HEADER) ?
config : header;
133 #if(PJON_INCLUDE_PACKET_ID)
134 if(!packet_id && (info.header & PJON_PACKET_ID_BIT)) {
135 info.id = PJONTools::new_packet_id(_packet_id_seed++);
142 #if(PJON_INCLUDE_PORT)
143 info.port = (rx_port == PJON_BROADCAST) ? port : rx_port;
148 PJONTools::compose_packet(info,
destination, source, length);
154 uint8_t device_id()
const
161 uint8_t *get_payload(uint8_t *buffer)
164 PJONTools::packet_overhead(buffer[1]) -
165 PJONTools::crc_overhead(buffer[1])
171 uint8_t packet_overhead(uint8_t header = 0)
const
173 return PJONTools::packet_overhead(header);
180 PJONTools::parse_header(packet, packet_info);
187 uint16_t length = PJON_PACKET_MAX_LENGTH;
188 uint16_t batch_length = 0;
189 uint8_t overhead = 0;
190 bool extended_length =
false;
191 for(uint16_t i = 0; i < length; i++) {
193 batch_length = strategy.receive_frame(buffer + i, length - i);
194 if(batch_length == PJON_FAIL || batch_length == 0) {
201 if((buffer[i] != _device_id) && (buffer[i] != PJON_BROADCAST)) {
207 (buffer[1] & PJON_MODE_BIT) ||
208 (buffer[1] & PJON_MAC_BIT) || (
209 (buffer[0] == PJON_BROADCAST) && (buffer[1] & PJON_ACK_REQ_BIT)
211 (buffer[1] & PJON_EXT_LEN_BIT) && !(buffer[1] & PJON_CRC_BIT)
213 !PJON_INCLUDE_PACKET_ID && (buffer[1] & PJON_PACKET_ID_BIT)
218 extended_length = buffer[i] & PJON_EXT_LEN_BIT;
219 overhead = packet_overhead(buffer[i]);
222 if((i == 2) && !extended_length) {
224 if((length < overhead) || (length >= PJON_PACKET_MAX_LENGTH)) {
227 if((length > 15) && !(buffer[1] & PJON_CRC_BIT)) {
232 if((i == 3) && extended_length) {
233 length = (buffer[i - 1] << 8) | (buffer[i] & 0xFF);
234 if((length < overhead) || (length >= PJON_PACKET_MAX_LENGTH)) {
237 if((length > 15) && !(buffer[1] & PJON_CRC_BIT)) {
244 PJON_crc8::compute(buffer, 3 + extended_length) !=
245 buffer[3 + extended_length]
250 if(buffer[1] & PJON_CRC_BIT) {
252 !PJON_crc32::compare(
253 PJON_crc32::compute(buffer, length - 4), buffer + (length - 4)
258 }
else if(PJON_crc8::compute(buffer, length - 1) != buffer[length - 1]) {
261 if(buffer[1] & PJON_ACK_REQ_BIT && buffer[0] != PJON_BROADCAST)
262 if((_mode != PJON_SIMPLEX) && !_router) {
263 strategy.send_response(PJON_ACK);
266 #if(PJON_INCLUDE_PACKET_ID)
268 (info.header & PJON_PACKET_ID_BIT) &&
269 known_packet_id(info) && !_router
274 #if(PJON_INCLUDE_PORT)
275 if((port != PJON_BROADCAST) && (port != info.port)) {
279 return length - overhead;
289 (uint32_t)(PJON_MICROS() - _last_send) >
290 (uint32_t)(strategy.back_off(_retries))
294 return strategy.can_start();
301 uint16_t send_packet(
const uint8_t *payload, uint16_t length)
303 _last_send = PJON_MICROS();
304 strategy.send_frame((uint8_t *)payload, length);
306 payload[0] == PJON_BROADCAST || !(payload[1] & PJON_ACK_REQ_BIT) ||
307 _mode == PJON_SIMPLEX
312 uint16_t response = strategy.receive_response();
313 if(response == PJON_ACK) {
317 if(_retries < strategy.get_max_attempts()) {
322 if(response == PJON_FAIL) {
331 uint16_t send_packet(
336 uint8_t header = PJON_NO_HEADER,
337 uint16_t packet_id = 0,
338 uint16_t rx_port = PJON_BROADCAST
341 if(!(length = compose_packet(
342 id, buffer, payload, length, header, packet_id, rx_port
346 return send_packet(buffer, length);
352 void send_acknowledge()
354 strategy.send_response(PJON_ACK);
359 void set_config_bit(
bool new_state, uint8_t bit)
372 void set_acknowledge(
bool state)
374 set_config_bit(state, PJON_ACK_REQ_BIT);
381 void set_crc_32(
bool state)
383 set_config_bit(state, PJON_CRC_BIT);
390 void set_communication_mode(uint8_t mode)
399 _mode = PJON_HALF_DUPLEX;
404 void set_id(uint8_t
id)
416 void include_sender_info(
bool state)
418 set_config_bit(state, PJON_TX_INFO_BIT);
425 void set_router(
bool state)
430 #if(PJON_INCLUDE_PACKET_ID)
437 for(uint8_t i = 0; i < PJON_MAX_RECENT_PACKET_IDS; i++)
439 info.id == recent_packet_ids[i].id &&
440 info.sender_id == recent_packet_ids[i].sender_id
444 save_packet_id(info);
452 for(uint8_t i = PJON_MAX_RECENT_PACKET_IDS - 1; i > 0; i--) {
453 recent_packet_ids[i] = recent_packet_ids[i - 1];
455 recent_packet_ids[0].id = info.id;
456 recent_packet_ids[0].header = info.header;
457 recent_packet_ids[0].sender_id = info.sender_id;
463 void set_packet_id(
bool state)
465 set_config_bit(state, PJON_PACKET_ID_BIT);
470 #if(PJON_INCLUDE_PORT)
476 void include_port(uint16_t p)
478 set_config_bit((p != 0) ? 1 : 0, PJON_PORT_BIT);
486 uint32_t _last_send = 0;
488 uint16_t _packet_id_seed = 0;
489 bool _router =
false;
490 uint8_t _retries = 0;