static void sniff_switch_channel(handler_arg_t arg) { phy_idle(platform_phy); // Select next channel do { radio.current_channel++; if (radio.current_channel > PHY_2400_MAX_CHANNEL) { radio.current_channel = PHY_2400_MIN_CHANNEL; } } while ((radio.channels & (1 << radio.current_channel)) == 0); // Enter RX on new channel phy_set_channel(platform_phy, radio.current_channel); phy_status_t ret = phy_rx(platform_phy, 0, soft_timer_time() + soft_timer_ms_to_ticks(500), radio.sniff.pkt_buf + radio.sniff.pkt_index, sniff_rx); if (ret != PHY_SUCCESS) { log_error("PHY RX Failed"); } log_debug("Sniff RX on channel %u", radio.current_channel); }
static void restore_state(void) { // Reset old state switch (old_state) { case RX: phy_rx(); break; case IDLE: default: phy_idle(); break; } }
static void sniff_rx(phy_status_t status) { // Switch packets phy_packet_t *rx_packet = radio.sniff.pkt_buf + radio.sniff.pkt_index; radio.sniff.pkt_index = (radio.sniff.pkt_index + 1) % 2; // Enter RX again phy_status_t ret = phy_rx(platform_phy, 0, soft_timer_time() + soft_timer_ms_to_ticks(500), radio.sniff.pkt_buf + radio.sniff.pkt_index, sniff_rx); if (ret != PHY_SUCCESS) { log_error("PHY RX Failed"); } if (status == PHY_SUCCESS) { // Send packet to serial packet_t *serial_pkt = packet_alloc(IOTLAB_SERIAL_PACKET_OFFSET); if (serial_pkt == NULL) { log_error("Failed to get a packet for sniffed RX"); return; } uint8_t *data = serial_pkt->data; // Place timestamp, channel, RSSI, LQI, captured length, as header data = packer_uint32_pack(data, packer_uint32_hton( iotlab_control_convert_time(rx_packet->timestamp))); *data++ = radio.current_channel; *data++ = rx_packet->rssi; *data++ = rx_packet->lqi; *data++ = rx_packet->length; memcpy(data, rx_packet->data, rx_packet->length); data += rx_packet->length; serial_pkt->length = data - serial_pkt->data; event_post(EVENT_QUEUE_APPLI, sniff_send_to_serial, serial_pkt); } }
static int32_t radio_sniffer(uint8_t cmd_type, packet_t *pkt) { // Stop all proper_stop(); /* * Expected packet format is (length:6B): * * channels bitmap [4B] * * time per channel (1/100s) [2B] */ if (pkt->length != 6) { log_warning("Bad Packet length: %u", pkt->length); pkt->length = 0; return 0; } /** GET values, system endian */ uint16_t time_per_channel; const uint8_t *data = pkt->data; memcpy(&radio.channels, data, 4); data += 4; memcpy(&time_per_channel, data, 2); data += 2; // Check validity of channels if ((radio.channels & PHY_MAP_CHANNEL_2400_ALL) == 0) { log_warning("Bad Channels, none selected: %u", radio.channels); pkt->length = 0; return 0; } radio.channels &= PHY_MAP_CHANNEL_2400_ALL; log_info("Radio Sniffer channels %08x, period %u", radio.channels, time_per_channel); // Select first channel for (radio.current_channel = 0; (radio.channels & (1 << radio.current_channel)) == 0; radio.current_channel++) { } // Select first packet radio.sniff.pkt_index = 0; phy_prepare_packet(radio.sniff.pkt_buf + radio.sniff.pkt_index); // Start listening phy_set_channel(platform_phy, radio.current_channel); phy_status_t ret = phy_rx(platform_phy, 0, soft_timer_time() + soft_timer_ms_to_ticks(500), radio.sniff.pkt_buf + radio.sniff.pkt_index, sniff_rx); if (ret != PHY_SUCCESS) { log_error("PHY RX Failed"); } log_debug("Sniff RX on channel %u", radio.current_channel); // Start channel switch timer if (time_per_channel != 0) { soft_timer_set_handler(&radio.period_tim, sniff_switch_channel, NULL); soft_timer_start(&radio.period_tim, soft_timer_ms_to_ticks(10 * time_per_channel), 1); } // OK pkt->length = 0; return 1; }
void start_rx(void) { phy_rx(&rx_cfg); }