static void process_uart_rx_fifo()
{
    if(fifo_get_size(&uart_rx_fifo) >= COMMAND_SIZE)
    {
        uint8_t received_cmd[COMMAND_SIZE];
        fifo_pop(&uart_rx_fifo, received_cmd, COMMAND_SIZE);
        if(strncmp(received_cmd, COMMAND_CHAN, COMMAND_SIZE) == 0)
        {
            process_command_chan();
        }
        else if(strncmp(received_cmd, COMMAND_TRAN, COMMAND_SIZE) == 0)
        {
            while(fifo_get_size(&uart_rx_fifo) < COMMAND_TRAN_PARAM_SIZE);

            char param[COMMAND_TRAN_PARAM_SIZE];
            fifo_pop(&uart_rx_fifo, param, COMMAND_TRAN_PARAM_SIZE);
            tx_packet_delay_s = atoi(param);
            DPRINT("performing TRAN command with %d tx_packet_delay_s\r\n",
                   tx_packet_delay_s);

            stop();
            is_mode_rx = false;
            current_state = STATE_RUNNING;
            sched_post_task(&start);
        }
        else if(strncmp(received_cmd, COMMAND_RECV, COMMAND_SIZE) == 0)
        {
            DPRINT("entering RECV mode\r\n");
            stop();
            is_mode_rx = true;
            current_state = STATE_RUNNING;
            sched_post_task(&start);
        }
        else if(strncmp(received_cmd, COMMAND_RSET, COMMAND_SIZE) == 0)
        {
            DPRINT("resetting...\r\n");
            hw_reset();
        }
        else
        {
            char err[40];
            DPRINT("ERROR invalid command %.4s\n\r", received_cmd);
        }

        fifo_clear(&uart_rx_fifo);
    }

    timer_post_task_delay(&process_uart_rx_fifo, TIMER_TICKS_PER_SEC);
}
void process_uart_rx_fifo()
{
    if(fifo_get_size(&uart_rx_fifo) >= COMMAND_SIZE)
    {
        uint8_t received_cmd[COMMAND_SIZE];
        fifo_pop(&uart_rx_fifo, received_cmd, COMMAND_SIZE);
        if(strncmp(received_cmd, COMMAND_CHAN, COMMAND_SIZE) == 0)
        {
            process_command_chan();
        }
        else if(strncmp(received_cmd, COMMAND_LOOP, COMMAND_SIZE) == 0)
        {
            process_command_loop();
        }
        else if(strncmp(received_cmd, COMMAND_RSET, COMMAND_SIZE) == 0)
        {
            hw_reset();
        }
        else
        {
            char err[40];
            snprintf(err, sizeof(err), "ERROR invalid command %.4s\n", received_cmd);
            console_print(err);
        }

        fifo_clear(&uart_rx_fifo);
    }
}
Exemplo n.º 3
0
static void process_uart_rx_fifo()
{
    if(fifo_get_size(&uart_rx_fifo) >= COMMAND_SIZE)
    {
        uint8_t received_cmd[COMMAND_SIZE];
        fifo_pop(&uart_rx_fifo, received_cmd, COMMAND_SIZE);
        if(strncmp(received_cmd, COMMAND_CHAN, COMMAND_SIZE) == 0)
        {
            process_command_chan();
        }
        else if(strncmp(received_cmd, COMMAND_TRAN, COMMAND_SIZE) == 0)
        {
            while(fifo_get_size(&uart_rx_fifo) < COMMAND_TRAN_PARAM_SIZE);

            char param[COMMAND_TRAN_PARAM_SIZE];
            fifo_pop(&uart_rx_fifo, param, COMMAND_TRAN_PARAM_SIZE);
            tx_packet_delay_s = atoi(param);

            stop();
            is_mode_rx = false;
            current_state = STATE_RUNNING;
            sched_post_task(&start);
        }
        else if(strncmp(received_cmd, COMMAND_RECV, COMMAND_SIZE) == 0)
        {
            stop();
            is_mode_rx = true;
            current_state = STATE_RUNNING;
            sched_post_task(&start);
        }
        else if(strncmp(received_cmd, COMMAND_RSET, COMMAND_SIZE) == 0)
        {
            hw_reset();
        }
        else
        {
            char err[40];
            snprintf(err, sizeof(err), "ERROR invalid command %.4s\n", received_cmd);
            uart_transmit_string(err);
        }

        fifo_clear(&uart_rx_fifo);
    }

    timer_post_task_delay(&process_uart_rx_fifo, TIMER_TICKS_PER_SEC);
}
static void process_serial_frame(fifo_t* fifo) {
  bool command_completed = false;
  bool completed_with_error = false;
  while(fifo_get_size(fifo)) {
    alp_action_t action;
    alp_parse_action(fifo, &action);

    switch(action.operation) {
      case ALP_OP_RETURN_TAG:
        if(action.tag_response.tag_id == command.tag_id) {
          command_completed = action.tag_response.completed;
          completed_with_error = action.tag_response.error;
        } else {
          DPRINT("received resp with unexpected tag_id (%i vs %i)", action.tag_response.tag_id, command.tag_id);
          // TODO unsolicited responses
        }
        break;
      case ALP_OP_WRITE_FILE_DATA:
        if(callbacks->write_file_data_callback)
          callbacks->write_file_data_callback(action.file_data_operand.file_offset.file_id,
                                               action.file_data_operand.file_offset.offset,
                                               action.file_data_operand.provided_data_length,
                                               action.file_data_operand.data);
        break;
      case ALP_OP_RETURN_FILE_DATA:
        if(callbacks->return_file_data_callback)
          callbacks->return_file_data_callback(action.file_data_operand.file_offset.file_id,
                                               action.file_data_operand.file_offset.offset,
                                               action.file_data_operand.provided_data_length,
                                               action.file_data_operand.data);
        break;
      case ALP_OP_RETURN_STATUS:
        if(action.status.type==ALP_ITF_ID_D7ASP)
        {
          d7ap_session_result_t interface_status = *((d7ap_session_result_t*)action.status.data);
          uint8_t addressee_len = d7ap_addressee_id_length(interface_status.addressee.ctrl.id_type);
          DPRINT("received resp from: ");
          DPRINT_DATA(interface_status.addressee.id, addressee_len);
        }
        if(callbacks->modem_interface_status_callback)
          callbacks->modem_interface_status_callback(action.status.type,&action.status.data);
        break;
      default:
        assert(false);
    }
  }


  if(command_completed) {
    DPRINT("command with tag %i completed @ %i", command.tag_id, timer_get_counter_value());
    if(callbacks->command_completed_callback)
      callbacks->command_completed_callback(completed_with_error,command.tag_id);

    command.is_active = false;
  }

}
Exemplo n.º 5
0
// TODO code duplication with noise_test, refactor later
static void process_command_chan()
{
    while(fifo_get_size(&uart_rx_fifo) < COMMAND_CHAN_PARAM_SIZE);

    char param[COMMAND_CHAN_PARAM_SIZE];
    fifo_pop(&uart_rx_fifo, param, COMMAND_CHAN_PARAM_SIZE);

    channel_id_t new_channel;

    if(strncmp(param, "433", 3) == 0)
        new_channel.channel_header.ch_freq_band = PHY_BAND_433;
    else if(strncmp(param, "868", 3) == 0)
        new_channel.channel_header.ch_freq_band = PHY_BAND_868;
    else if(strncmp(param, "915", 3) == 0)
        new_channel.channel_header.ch_freq_band = PHY_BAND_915;
    else
        goto error;

    char channel_class = param[3];
    if(channel_class == 'L')
        new_channel.channel_header.ch_class = PHY_CLASS_LO_RATE;
    else if(channel_class == 'N')
        new_channel.channel_header.ch_class = PHY_CLASS_NORMAL_RATE;
    else if(channel_class == 'H')
        new_channel.channel_header.ch_class = PHY_CLASS_HI_RATE;
    else
        goto error;

    uint16_t center_freq_index = atoi((const char*)(param + 5));
    new_channel.center_freq_index = center_freq_index;

    // validate
    if(new_channel.channel_header.ch_freq_band == PHY_BAND_433)
    {
        if(new_channel.channel_header.ch_class == PHY_CLASS_NORMAL_RATE
                && (new_channel.center_freq_index % 8 != 0 || new_channel.center_freq_index > 56))
            goto error;
        else if(new_channel.channel_header.ch_class == PHY_CLASS_LO_RATE && new_channel.center_freq_index > 68)
            goto error;
        else if(new_channel.channel_header.ch_class == PHY_CLASS_HI_RATE)
            goto error;
    } // TODO validate PHY_BAND_868

    // valid band, apply ...
    current_channel_id = new_channel;

    char str[20];
    channel_id_to_string(&current_channel_id, str, sizeof(str));
    uart_transmit_string(str);
    // change channel and restart
    // TODOsched_post_task(&start_rx);
    return;

    error:
        uart_transmit_string("Error parsing CHAN command. Expected format example: '433L001'\n");
        fifo_clear(&uart_rx_fifo);
}
bool modem_write_file(uint8_t file_id, uint32_t offset, uint32_t size, uint8_t* data) {
  if(!alloc_command())
    return false;

  alp_append_write_file_data_action(&command.fifo, file_id, offset, size, data, true, false);

  modem_interface_transfer_bytes(command.buffer, fifo_get_size(&command.fifo), SERIAL_MESSAGE_TYPE_ALP_DATA);

  return true;
}
static void process_rx_fifo(void *arg) {
  if(!parsed_header) {
    // <sync byte (0xC0)><version (0x00)><length of ALP command (1 byte)><ALP command> // TODO CRC
    if(fifo_get_size(&rx_fifo) > SERIAL_ALP_FRAME_HEADER_SIZE) {
        uint8_t header[SERIAL_ALP_FRAME_HEADER_SIZE];
        fifo_peek(&rx_fifo, header, 0, SERIAL_ALP_FRAME_HEADER_SIZE);
        DPRINT_DATA(header, 3); // TODO tmp

        if(header[0] != SERIAL_ALP_FRAME_SYNC_BYTE || header[1] != SERIAL_ALP_FRAME_VERSION) {
          fifo_skip(&rx_fifo, 1);
          DPRINT("skip");
          parsed_header = false;
          payload_len = 0;
          if(fifo_get_size(&rx_fifo) > SERIAL_ALP_FRAME_HEADER_SIZE)
            sched_post_task(&process_rx_fifo);

          return;
        }

        parsed_header = true;
        fifo_skip(&rx_fifo, SERIAL_ALP_FRAME_HEADER_SIZE);
        payload_len = header[2];
        DPRINT("found header, payload size = %i", payload_len);
        sched_post_task(&process_rx_fifo);
    }
  } else {
    if(fifo_get_size(&rx_fifo) < payload_len) {
      DPRINT("payload not complete yet");
      return;
    }

    // payload complete, start parsing
    // rx_fifo can be bigger than the current serial packet, init a subview fifo
    // which is restricted to payload_len so we can't parse past this packet.
    fifo_t payload_fifo;
    fifo_init_subview(&payload_fifo, &rx_fifo, 0, payload_len);
    process_serial_frame(&payload_fifo);

    // pop parsed bytes from original fifo
    fifo_skip(&rx_fifo, payload_len - fifo_get_size(&payload_fifo));
    parsed_header = false;
  }
}
Exemplo n.º 8
0
// TODO doc
// ATx\r : shell command, where x is a char which maps to a command.
// List of supported commands:
// - R: reboot device
// AT$<command handler id> : command to be handled by the command handler specified. The command handler id is a byte < 65 (non ASCII)
// The handlers are passed the command fifo (including the header) and are responsible for pop()-ing the bytes which are processed by the handler.
// When the fifo does not yet contain a full command which can be processed by the specific handler nothing should be popped and the handler will
// called again later when more data is received.
static void process_cmd_fifo()
{
    if(fifo_get_size(&cmd_fifo) >= SHELL_CMD_HEADER_SIZE)
    {
        uint8_t cmd_header[SHELL_CMD_HEADER_SIZE];
        fifo_peek(&cmd_fifo, cmd_header, 0, SHELL_CMD_HEADER_SIZE);
        if(cmd_header[0] != 'A' || cmd_header[1] != 'T')
        {
            // unexpected data, pop and return
            // TODO log?
            fifo_pop(&cmd_fifo, cmd_header, 1);
            sched_post_task(&process_cmd_fifo);
            return;
        }

        if(cmd_header[2] != '$')
        {
            process_shell_cmd(cmd_header[2]);
            fifo_pop(&cmd_fifo, cmd_header, SHELL_CMD_HEADER_SIZE);
        }
        else
        {
            get_cmd_handler_callback(cmd_header[3])(&cmd_fifo);
        }

        sched_post_task(&process_cmd_fifo);
    } else if(fifo_get_size(&cmd_fifo) >= 3) {
      // AT[\r|\n]
      uint8_t cmd_header[3];
      fifo_peek(&cmd_fifo, cmd_header, 0, 3);
      if( cmd_header[0] == 'A' && cmd_header[1] == 'T'
          && ( cmd_header[2] == '\r' || cmd_header[2] == '\n' ) )
      {
        console_print("OK\r\n");
        fifo_pop(&cmd_fifo, cmd_header, 3);
      }
    }
}
Exemplo n.º 9
0
uint8_t alp_get_expected_response_length(uint8_t* alp_command, uint8_t alp_command_length) {
  uint8_t expected_response_length = 0;
  fifo_t fifo;
  fifo_init_filled(&fifo, alp_command, alp_command_length, alp_command_length + 1);

  while(fifo_get_size(&fifo) > 0) {
    alp_control_t control;
    fifo_pop(&fifo, (uint8_t*)&control.raw, 1);
    switch(control.operation) {
      case ALP_OP_READ_FILE_DATA:
        fifo_skip(&fifo, 1); // skip file ID
        alp_parse_length_operand(&fifo); // offset
        expected_response_length += alp_parse_length_operand(&fifo);;
        break;
      case ALP_OP_REQUEST_TAG:
        fifo_skip(&fifo, 1); // skip tag ID operand
        break;
      case ALP_OP_RETURN_FILE_DATA:
      case ALP_OP_WRITE_FILE_DATA:
        fifo_skip(&fifo, 1); // skip file ID
        alp_parse_length_operand(&fifo); // offset
        fifo_skip(&fifo, alp_parse_length_operand(&fifo));
        break;
      case ALP_OP_FORWARD: ;
        uint8_t itf_id;
        fifo_pop(&fifo, &itf_id, 1);
        if(itf_id == ALP_ITF_ID_D7ASP) {
          fifo_skip(&fifo, 1); // skip QoS, dormant timeout
          d7ap_addressee_ctrl_t addressee_ctrl;
          fifo_pop(&fifo, (uint8_t*)&addressee_ctrl.raw, 1);
          fifo_skip(&fifo, 2 + alp_addressee_id_length(addressee_ctrl.id_type)); // skip addressee ctrl, access class
          // TODO refactor to reuse same logic for parsing and response length counting
        }
        // other ITFs have no configuration
        break;
      case ALP_OP_WRITE_FILE_PROPERTIES:
        fifo_skip(&fifo, 1 + sizeof(fs_file_header_t)); // skip file ID & header
        break;
      // TODO other operations
      default:
        DPRINT("op %i not implemented", control.operation);
        assert(false);
    }
  }

  DPRINT("Expected ALP response length=%i", expected_response_length);
  return expected_response_length;
}
Exemplo n.º 10
0
bool modem_send_raw_unsolicited_response(uint8_t* alp_command, uint32_t length,
                                         session_config_t* session_config) {
  if(!alloc_command())
    return false;

   if(session_config->interface_type==DASH7)
    alp_append_forward_action(&command.fifo, ALP_ITF_ID_D7ASP, (uint8_t *) &session_config->d7ap_session_config, sizeof(d7ap_session_config_t));
  else if(session_config->interface_type==LORAWAN_OTAA)
    alp_append_forward_action(&command.fifo, ALP_ITF_ID_LORAWAN_OTAA, (uint8_t *) &session_config->lorawan_session_config_otaa, sizeof(lorawan_session_config_otaa_t));
  else if(session_config->interface_type==LORAWAN_ABP)
    alp_append_forward_action(&command.fifo, ALP_ITF_ID_LORAWAN_ABP, (uint8_t *) &session_config->lorawan_session_config_abp, sizeof(lorawan_session_config_abp_t));

  fifo_put(&command.fifo, alp_command, length);

  modem_interface_transfer_bytes(command.buffer, fifo_get_size(&command.fifo), SERIAL_MESSAGE_TYPE_ALP_DATA);
  return true;
}
Exemplo n.º 11
0
void degenerator_compute (Degenerator_t * degenerator){
	int cur_iter;
	

	pDEBUG("Iterating %d times\n", degenerator->_iterations);
	for (cur_iter = 0; cur_iter < degenerator->_iterations; cur_iter++){
		if ((cur_iter % degenerator->_iterations_offset) == 0){
			// faire des calculs (nombre de composantes connexes)
			store_reset (degenerator->_store, STORE_RESET_ALL ^ STORE_RESET_DEGREE);

			Fifo_t * fifo_idx = fifo_create(degenerator->_size);
			store_connexity (degenerator->_store, fifo_idx);

			fprintf(degenerator->_io->output, "%d %ld\n", cur_iter, fifo_get_size (fifo_idx));
			fifo_destroy(fifo_idx);
			// afficher la courbe...
		}
		// Choisir un noeud selon une certaine méthode...
		nodeindex_t selected_node = (degenerator_select_mode_table[degenerator->_select_mode])(degenerator);
		printf("Node %ld\n", selected_node);

		store_del_node(degenerator->_store, selected_node);
	}
}
void process_command_chan()
{
    while(fifo_get_size(&uart_rx_fifo) < COMMAND_CHAN_PARAM_SIZE);

    char param[COMMAND_CHAN_PARAM_SIZE];
    fifo_pop(&uart_rx_fifo, param, COMMAND_CHAN_PARAM_SIZE);

    channel_id_t new_channel = {
		.channel_header.ch_coding = PHY_CODING_PN9
    };

    if(strncmp(param, "433", 3) == 0)
        new_channel.channel_header.ch_freq_band = PHY_BAND_433;
    else if(strncmp(param, "868", 3) == 0)
        new_channel.channel_header.ch_freq_band = PHY_BAND_868;
    else if(strncmp(param, "915", 3) == 0)
        new_channel.channel_header.ch_freq_band = PHY_BAND_915;
    else
        goto error;

    char channel_class = param[3];
    if(channel_class == 'L')
        new_channel.channel_header.ch_class = PHY_CLASS_LO_RATE;
    else if(channel_class == 'N')
        new_channel.channel_header.ch_class = PHY_CLASS_NORMAL_RATE;
    else if(channel_class == 'H')
        new_channel.channel_header.ch_class = PHY_CLASS_HI_RATE;
    else
        goto error;

    uint16_t center_freq_index = atoi((const char*)(param + 4));
    new_channel.center_freq_index = center_freq_index;

    // validate
    if(new_channel.channel_header.ch_freq_band == PHY_BAND_433)
    {
        if(new_channel.channel_header.ch_class == PHY_CLASS_NORMAL_RATE
                && (new_channel.center_freq_index % 8 != 0 || new_channel.center_freq_index > 56))
            goto error;
        else if(new_channel.channel_header.ch_class == PHY_CLASS_LO_RATE && new_channel.center_freq_index > 68)
            goto error;
        else if(new_channel.channel_header.ch_class == PHY_CLASS_HI_RATE)
            goto error;
    } // TODO validate PHY_BAND_868

    // valid band, apply ...
    rx_cfg.channel_id = new_channel;

    // change channel and restart
    prepare_channel_indexes();
    current_channel_indexes_index = 0;
    sched_post_task(&start_rx);
    return;

    error:
        console_print("Error parsing CHAN command. Expected format example: '433L001'\n");
        fifo_clear(&uart_rx_fifo);
}


void process_command_loop()
{
    use_manual_channel_switching = false;
    sched_post_task(&start_rx);
}