Example #1
0
/*
 * Called from hip_esp_output()
 */
int endbox_ipv4_packet_check(struct ip *iph, struct sockaddr *lsi,
                             int *packet_count)
{
  __u32 dst;

  if (!IN_MULTICAST(ntohl(iph->ip_dst.s_addr)) &&
      (((ntohl(iph->ip_dst.s_addr)) & 0x000000FF) != 0x000000FF))
    {
      dst = iph->ip_dst.s_addr;
    }
  else
    {
      dst = 0;
    }
  if (!is_valid_packet(iph->ip_src.s_addr, dst, lsi))
    {
      return(-1);
    }
  (*packet_count)++;
  return(0);
}
Example #2
0
/*
 * Called from hip_esp_output()
 */
int endbox_arp_packet_check(struct arp_hdr *arph, struct sockaddr *lsi,
                            int *packet_count)
{
  struct arp_req_data *arp_req;

  if ((ntohs(arph->ar_hrd) == 0x01) &&           /* Ethernet */
      (ntohs(arph->ar_pro) == 0x0800) &&         /* IPv4 */
      (arph->ar_hln == 6) && (arph->ar_pln == 4))
    {
      arp_req = (struct arp_req_data*)(arph + 1);
      if (!is_valid_packet(arp_req->src_ip, arp_req->dst_ip, lsi))
        {
          return(-1);
        }
    }
  else
    {
      return(-1);
    }
  (*packet_count)++;
  return(0);
}
Example #3
0
// New data available event handler
void rs485_serial_data_available_handler(void* opaque) {
	(void)opaque;

    if(!send_verify_flag) {
        disable_all_timers();
    }

    int bytes_received = 0;
    uint32_t uid_from_packet = 0;
    int add_recipient_opaque;
    Packet empty_packet;
    Packet data_packet;
    uint64_t dummy_read_buffer;
    
    // Merge or simply save the received bytes
    if(partial_receive_flag) {
        bytes_received = read(_rs485_serial_fd,
                              &receive_buffer[partial_receive_merge_index],
                              (RECEIVE_BUFFER_SIZE - partial_receive_merge_index));

        
        printf("bytes_received %d\n", bytes_received);

        partial_receive_merge_index = partial_receive_merge_index + bytes_received;
    }
    else {
        partial_receive_merge_index = read(_rs485_serial_fd, receive_buffer, RECEIVE_BUFFER_SIZE);

    if (partial_receive_merge_index != 13)
        printf("partial_receive_merge_index %d\n", partial_receive_merge_index);
    }
    //log_info("PARTIAL_RECEIVE_MERGE_INDEX = %d", partial_receive_merge_index);
    // Checks at least 13 bytes is available in the receive buffer
    if(partial_receive_merge_index >= 13) {
        int packet_validation_code =
        is_valid_packet(receive_buffer, partial_receive_merge_index);
        
        switch(packet_validation_code) {
            case PACKET_SEND_VERIFY_OK:
                // Stop send verify timer
                if (read(_send_verify_event, &dummy_read_buffer, sizeof(uint64_t))) {}
                setup_timer(&send_verify_timer, TIME_UNIT_NSEC, 0);
                timerfd_settime(_send_verify_event, 0, &send_verify_timer, NULL);
                // Disabling TX
                gpio_output_clear(_tx_pin);
                end = microseconds();
                // Clearing send verify flag
                send_verify_flag = 0;
                // Clearing partial receive flag
                partial_receive_flag = 0;
                
                if(sent_ack_of_data_packet) {
                    sent_ack_of_data_packet = 0;
                    master_current_request_processed = 1;
                    master_poll_slave_timeout_handler(NULL);
                }
                log_debug("RS485: Send verified");
                return;
            
            case PACKET_EMPTY_OK:
                // Proper empty packet
                log_debug("RS485: Empty packet received");
                
                if(sent_current_request_from_queue){
                    queue_pop(&_rs485_extension.packet_to_modbus_queue, NULL);
                    sent_current_request_from_queue = 0;
                }
                // Updating recipient in the routing table
                memcpy(&uid_from_packet, &receive_buffer[3], sizeof(uint32_t));
                stack_add_recipient(&_rs485_extension.base, uid_from_packet, receive_buffer[0]);
                
                partial_receive_flag = 0;
                master_current_request_processed = 1;
                if(sent_ack_of_data_packet) {
                    sent_ack_of_data_packet = 0;
                }
                master_poll_slave_timeout_handler(NULL);
                return;
            
            case PACKET_DATA_OK:
                // Proper data packet
                log_info("RS485: Data packet received");
                
                // Send message into brickd dispatcher
                memset(&data_packet, 0, sizeof(Packet));
                memcpy(&data_packet, &receive_buffer[3], partial_receive_merge_index - MODBUS_PACKET_OVERHEAD);
                network_dispatch_response(&data_packet);
                log_debug("RS485: Dispatched packet to network subsystem");
                
                if(sent_current_request_from_queue){
                    queue_pop(&_rs485_extension.packet_to_modbus_queue, NULL);
                    sent_current_request_from_queue = 0;
                }
                
                // Updating recipient in the routing table
                memcpy(&uid_from_packet, &receive_buffer[3], sizeof(uint32_t));
                add_recipient_opaque = receive_buffer[0];
                stack_add_recipient(&_rs485_extension.base, uid_from_packet, add_recipient_opaque);
                
                // Send ACK to the slave
                memset(&empty_packet, 0, sizeof(PacketHeader));
                empty_packet.header.length = 8;
                send_modbus_packet(_rs485_extension.slaves[master_current_slave_to_process],
                                   current_sequence_number,
                                   &empty_packet);
                sent_ack_of_data_packet = 1;
                return;
            
            case PACKET_ERROR_SEND_VERIFY:
                // Retry the current request
                log_error("RS485: Send verify failed");
                partial_receive_flag = 0;
                master_current_retry = MASTER_RETRIES;
                master_retry_timeout_handler(NULL);
                return;
                
            case PACKET_ERROR_ADDRESS:
                // Retry the current request
                log_error("RS485: Wrong address in packet");
                partial_receive_flag = 0;
                master_current_retry = MASTER_RETRIES;
                master_retry_timeout_handler(NULL);
                return;
                
            case PACKET_ERROR_FUNCTION_CODE:
                log_error("RS485: Wrong function code in packet");
                partial_receive_flag = 0;
                master_current_retry = MASTER_RETRIES;
                master_retry_timeout_handler(NULL);
                return;
                
            case PACKET_ERROR_SEQUENCE_NUMBER:
                // Retry the current request
                log_info("RS485: Wrong sequence number in packet");
                partial_receive_flag = 0;
                master_current_retry = MASTER_RETRIES;
                master_retry_timeout_handler(NULL);
                return;
                
            case PACKET_ERROR_LENGTH:
                // Retry the current request
                log_error("RS485: Wrong length in packet");
                partial_receive_flag = 0;
                master_current_retry = MASTER_RETRIES;
                master_retry_timeout_handler(NULL);
                return;
            
            case PACKET_ERROR_LENGTH_PARTIAL:
                log_debug("RS485: Partial data packet recieved");
                handle_partial_receive();
                return;
            
            case PACKET_ERROR_CRC16:
                // Retry the current request
                log_error("RS485: Wrong CRC16 in packet");
                partial_receive_flag = 0;
                master_current_retry = MASTER_RETRIES;
                master_retry_timeout_handler(NULL);
                return;
            
            default:
                return;
        }
    }
    else {
        log_debug("RS485: Partial packet recieved");
        handle_partial_receive();
        return;
    }
    if(send_verify_flag) {
        // Disabling TX
        gpio_output_clear(_tx_pin);
        end = microseconds();
        // Stop send verify timer
        if (read(_send_verify_event, &dummy_read_buffer, sizeof(uint64_t))) {}
        setup_timer(&send_verify_timer, TIME_UNIT_NSEC, 0);
        timerfd_settime(_send_verify_event, 0, &send_verify_timer, NULL);
        // Clearing send verify flag
        send_verify_flag = 0;
    }
    abort_current_request();
    return;
}