// Master polling slave event handler void master_poll_slave_timeout_handler(void* opaque) { (void)opaque; // Turning off the timers disable_all_timers(); // Basically for situation when just after sending packet from this //function nothing comes back and master_poll_slave_timer times out if (!master_current_request_processed) { master_current_retry = MASTER_RETRIES; master_retry_timeout_handler(NULL); return; } // Check out going queue if nothing to send from there then // send modbus packet without payload to current slave RS485ExtensionPacket* packet_to_modbus; packet_to_modbus = queue_peek(&_rs485_extension.packet_to_modbus_queue); if(packet_to_modbus == NULL) { // Incase there are no slaves configured for this master if(_rs485_extension.slave_num == 0) { // Re-enabling the timer partial_receive_flag = 0; master_current_request_processed = 1; //setup_timer(&master_poll_slave_timer, TIME_UNIT_NSEC, MASTER_POLL_SLAVE_TIMEOUT); return; } // Since there are no packets to be sent from the queue // we poll current slave with an empty message Packet empty_packet; memset(&empty_packet, 0, sizeof(PacketHeader)); empty_packet.header.length = 8; // Update current request which is being sent current_request = empty_packet; // Update current sequence number update_sequence_number(); // Update current slave to process update_slave_to_process(); int bytes_sent = send_modbus_packet(_rs485_extension.slaves[master_current_slave_to_process], current_sequence_number, &empty_packet); log_debug("RS485: Sending empty packet to slave ID = %d, Sequence number = %d, Bytes sent = %d", _rs485_extension.slaves[master_current_slave_to_process], current_sequence_number, bytes_sent); } else { // Update current request which is being sent current_request = packet_to_modbus->packet; // Update current sequence number update_sequence_number(); // Update current slave to process update_slave_to_process(); int bytes_sent = send_modbus_packet(packet_to_modbus->slave_address, current_sequence_number, &packet_to_modbus->packet); log_debug("RS485: Sending packet from queue to slave ID = %d, Sequence number = %d, Bytes sent = %d", packet_to_modbus->slave_address, current_sequence_number, bytes_sent); sent_current_request_from_queue = 1; } partial_receive_flag = 0; master_current_request_processed = 0; // Re-enabling the timer setup_timer(&master_poll_slave_timer, TIME_UNIT_NSEC, MASTER_POLL_SLAVE_TIMEOUT); timerfd_settime(_master_poll_slave_event, 0, &master_poll_slave_timer, NULL); }
/**************************************************************************//** * Extract the fields of an RTP packet and validate it. * * @param p_ctx The reader context. * @param t_module The track module. * @return True if successful, false if there were not enough bits in the * packet or the packet was invalid. */ static void decode_rtp_packet_header(VC_CONTAINER_T *p_ctx, VC_CONTAINER_TRACK_MODULE_T *t_module) { VC_CONTAINER_BITS_T *payload = &t_module->payload; uint32_t version, has_padding, has_extension, csrc_count, has_marker; uint32_t payload_type, ssrc; uint16_t seq_num; /* Break down fixed header area into component parts */ version = BITS_READ_U32(p_ctx, payload, 2, "Version"); has_padding = BITS_READ_U32(p_ctx, payload, 1, "Has padding"); has_extension = BITS_READ_U32(p_ctx, payload, 1, "Has extension"); csrc_count = BITS_READ_U32(p_ctx, payload, 4, "CSRC count"); has_marker = BITS_READ_U32(p_ctx, payload, 1, "Has marker"); payload_type = BITS_READ_U32(p_ctx, payload, 7, "Payload type"); seq_num = BITS_READ_U16(p_ctx, payload, 16, "Sequence number"); t_module->timestamp = BITS_READ_U32(p_ctx, payload, 32, "Timestamp"); ssrc = BITS_READ_U32(p_ctx, payload, 32, "SSRC"); /* If there was only a partial header, abort immediately */ if (!BITS_VALID(p_ctx, payload)) return; /* Validate version, payload type, sequence number and SSRC, if set */ if (version != 2 || payload_type != t_module->payload_type) { BITS_INVALIDATE(p_ctx, payload); return; } if (BIT_IS_SET(t_module->flags, TRACK_SSRC_SET) && (ssrc != t_module->expected_ssrc)) { LOG_DEBUG(p_ctx, "RTP: Unexpected SSRC (0x%8.8X)", ssrc); BITS_INVALIDATE(p_ctx, payload); return; } /* Check sequence number indicates packet is usable */ if (!update_sequence_number(t_module, seq_num)) { BITS_INVALIDATE(p_ctx, payload); return; } /* Adjust to account for padding, CSRCs and extension */ if (has_padding) { VC_CONTAINER_BITS_T bit_stream; uint32_t available = BITS_BYTES_AVAILABLE(p_ctx, payload); uint8_t padding; BITS_COPY_STREAM(p_ctx, &bit_stream, payload); /* The last byte of the payload is the number of padding bytes, including itself */ BITS_SKIP_BYTES(p_ctx, &bit_stream, available - 1, "Skip to padding length"); padding = BITS_READ_U8(p_ctx, &bit_stream, 8, "Padding length"); BITS_REDUCE_BYTES(p_ctx, payload, padding, "Remove padding"); } /* Each CSRC is 32 bits, so shift count up to skip the right number of bits */ BITS_SKIP(p_ctx, payload, csrc_count << 5, "CSRC section"); if (has_extension) { uint32_t extension_bits; /* Extension header is 16-bit ID (which isn't needed), then 16-bit length in 32-bit words */ BITS_SKIP(p_ctx, payload, 16, "Extension ID"); extension_bits = BITS_READ_U32(p_ctx, payload, 16, "Extension length") << 5; BITS_SKIP(p_ctx, payload, extension_bits, "Extension data"); } /* Record whether or not this RTP packet had the marker bit set */ if (has_marker) SET_BIT(t_module->flags, TRACK_HAS_MARKER); else CLEAR_BIT(t_module->flags, TRACK_HAS_MARKER); /* If it hasn't been set independently, use the first timestamp as a baseline */ if (!t_module->timestamp_base) t_module->timestamp_base = t_module->timestamp; t_module->timestamp -= t_module->timestamp_base; }