Просмотр исходного кода

IN DEVELOP: sniffer mode by default - find packets with valid CRC

vad7 3 лет назад
Родитель
Сommit
48156f11fc
1 измененных файлов с 164 добавлено и 87 удалено
  1. 164 87
      nrf24scan.c

+ 164 - 87
nrf24scan.c

@@ -14,7 +14,7 @@
 #include <u8g2.h>
 
 #define TAG 		"nrf24scan"
-#define VERSION		"1.5"
+#define VERSION		"1.6"
 #define MAX_CHANNEL	125
 #define MAX_ADDR	6
 
@@ -32,12 +32,14 @@
 									// P3: address P3, LSB in hex (1 byte)
 									// P4: address P4, LSB in hex (1 byte)
 									// P5: address P5, LSB in hex (1 byte)
-									// captured data in raw format, first byte = address # 0..5, Payload len if DPL
+									// captured data:
+									//		first byte = { RAW packet flag (0x80/0x00) } + { channel number }
+									//		second byte = { Payload len 5 bits, 0 = 32 } + {{ RAW packet: ESB flag 0x04/0x00 + address size-2 if RAW packet } or { pipe #(0..5) }}, 
 									// ... up to MAX_LOG_RECORDS-1
 #define LOG_FILENAME 		"log"
 #define LOG_FILEEXT	 		".txt"
 #define MAX_LOG_RECORDS		100
-#define LOG_REC_SIZE		33		// max packet size
+#define LOG_REC_SIZE		34		// max packet size
 #define VIEW_LOG_MAX_X		22
 #define VIEW_LOG_WIDTH_B	10		// bytes
 
@@ -51,17 +53,17 @@ char SettingsFld_Addr = 'P';
 
 Nrf24Scan* APP;
 uint8_t what_doing = 0; // 0 - setup, 1 - view log, 2 - view addresses
-uint8_t what_to_do = 1; // 0 - view, 1 - view & scan
+uint8_t what_to_do = 1; // 0 - view, 1 - view & sniff, 2 - view & read
 uint32_t key_press_seq_ok = 0;
 uint8_t save_settings = 0;
 char screen_buf[64];
 char addr_file_name[32];
 uint8_t NRF_rate = 1; 	// 0 - 250Kbps, 1 - 1Mbps, 2 - 2Mbps
 uint8_t NRF_channel = 0;// 0..125
-uint8_t NRF_ESB = 0;	// 0 - ShockBurst, 1 - Enhanced ShockBurst
+uint8_t NRF_ESB = 1;	// 0 - ShockBurst, 1 - Enhanced ShockBurst
 uint8_t NRF_DPL = 0;	// 1 - Dynamic Payload Length
-uint8_t NRF_CRC = 0;	// 1 - No, 1 - CRC 1byte, 2 - CRC 2byte
-uint8_t NRF_Payload = 32;// len in bytes, max 32
+uint8_t NRF_CRC = 2;	// 1 - No, 1 - CRC 1byte, 2 - CRC 2byte
+uint8_t NRF_Payload = 23;// len in bytes, max 32
 uint8_t NRF_AA_OFF = 0;	// Disable Auto Acknowledgement
 bool NRF_ERROR = 0;
 
@@ -229,7 +231,7 @@ void write_to_log_file(Storage* storage, bool f_settings)
 				int i = 0;
 				for(; i < log_arr_idx; i++) {
 					furi_string_reset(str);
-					add_to_furi_str_hex_bytes(str, (char*)APP->log_arr + i * LOG_REC_SIZE, MIN(NRF_Payload + 1, LOG_REC_SIZE));
+					add_to_furi_str_hex_bytes(str, (char*)APP->log_arr + i * LOG_REC_SIZE, LOG_REC_SIZE);
 					furi_string_cat(str, "\n");
 					if(stream_write_string(file_stream, str) != furi_string_size(str)) {
 						FURI_LOG_E(TAG, "Failed to write to file!");
@@ -366,7 +368,7 @@ static uint8_t load_settings_file(Stream* file_stream) {
 					log_loaded = true;
 				}
 				if(log_arr_idx < MAX_LOG_RECORDS - 1) {
-					ConvertHexToArray(line_ptr, APP->log_arr + log_arr_idx * LOG_REC_SIZE, MIN(NRF_Payload + 1, LOG_REC_SIZE));
+					ConvertHexToArray(line_ptr, APP->log_arr + log_arr_idx * LOG_REC_SIZE, LOG_REC_SIZE);
 					log_arr_idx++;
 				}
 			}
@@ -402,36 +404,42 @@ static void prepare_nrf24()
 	uint8_t tmp[5];
 	nrf24_read_reg(nrf24_HANDLE, REG_RX_ADDR_P0, tmp, addrs.addr_len);
 	NRF_ERROR = memcmp(addr, tmp, addrs.addr_len) != 0;
-	nrf24_write_reg(nrf24_HANDLE, RX_PW_P0, NRF_Payload);
+	uint8_t payload = NRF_Payload;
+	if(what_to_do == 1) {
+		payload += 5 + NRF_CRC; // + addr_max + CRC
+		if(NRF_ESB)	payload += 2;
+		if(payload > 32) payload = 32;
+	}
+	nrf24_write_reg(nrf24_HANDLE, RX_PW_P0, payload);
 	if(addrs.addr_count > 0) nrf24_write_reg(nrf24_HANDLE, REG_DYNPD, NRF_DPL ? (1<<0) : 0); // Enable dynamic payload reg
 	if(addrs.addr_count > 1) {
 		for(int i = 0; i < addrs.addr_len; i++) addr[i] = addrs.addr_P1[addrs.addr_len - i - 1];
 		nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P1, addr, addrs.addr_len);
-		nrf24_write_reg(nrf24_HANDLE, RX_PW_P1, NRF_Payload);
+		nrf24_write_reg(nrf24_HANDLE, RX_PW_P1, payload);
 		nrf24_write_reg(nrf24_HANDLE, REG_DYNPD, NRF_DPL ? (1<<1) : 0);
 		erx_addr |= (1<<1); // Enable RX_P1
 	} else nrf24_write_reg(nrf24_HANDLE, RX_PW_P1, 0);
 	if(addrs.addr_count > 2) {
 		nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P2, &addrs.addr_P2, 1);
-		nrf24_write_reg(nrf24_HANDLE, RX_PW_P2, NRF_Payload);
+		nrf24_write_reg(nrf24_HANDLE, RX_PW_P2, payload);
 		nrf24_write_reg(nrf24_HANDLE, REG_DYNPD, NRF_DPL ? (1<<2) : 0);
 		erx_addr |= (1<<2); // Enable RX_P2
 	} else nrf24_write_reg(nrf24_HANDLE, RX_PW_P2, 0);
 	if(addrs.addr_count > 3) {
 		nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P3, &addrs.addr_P3, 1);
-		nrf24_write_reg(nrf24_HANDLE, RX_PW_P3, NRF_Payload);
+		nrf24_write_reg(nrf24_HANDLE, RX_PW_P3, payload);
 		nrf24_write_reg(nrf24_HANDLE, REG_DYNPD, NRF_DPL ? (1<<3) : 0);
 		erx_addr |= (1<<3); // Enable RX_P3
 	} else nrf24_write_reg(nrf24_HANDLE, RX_PW_P3, 0);
 	if(addrs.addr_count > 4) {
 		nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P4, &addrs.addr_P4, 1);
-		nrf24_write_reg(nrf24_HANDLE, RX_PW_P4, NRF_Payload);
+		nrf24_write_reg(nrf24_HANDLE, RX_PW_P4, payload);
 		nrf24_write_reg(nrf24_HANDLE, REG_DYNPD, NRF_DPL ? (1<<4) : 0);
 		erx_addr |= (1<<4); // Enable RX_P4
 	} else nrf24_write_reg(nrf24_HANDLE, RX_PW_P4, 0);
 	if(addrs.addr_count > 5) {
 		nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P5, &addrs.addr_P5, 1);
-		nrf24_write_reg(nrf24_HANDLE, RX_PW_P5, NRF_Payload);
+		nrf24_write_reg(nrf24_HANDLE, RX_PW_P5, payload);
 		nrf24_write_reg(nrf24_HANDLE, REG_DYNPD, NRF_DPL ? (1<<5) : 0);
 		erx_addr |= (1<<5); // Enable RX_P5
 	} else nrf24_write_reg(nrf24_HANDLE, RX_PW_P5, 0);
@@ -446,6 +454,17 @@ static void prepare_nrf24()
 
 static void start_scanning() 
 {
+	if(what_to_do == 1) { // sniff
+		addrs.addr_P0[0] = 0;
+		addrs.addr_P0[1] = 0x55;
+		addrs.addr_P1[0] = 0;
+		addrs.addr_P1[1] = 0xAA;
+		addrs.addr_len = 2;
+		addrs.addr_count = 2;
+		view_log_decode_CRC = NRF_CRC;
+		uint8_t pmax = 32 - 5 - (NRF_ESB ? 2 : 0) - NRF_CRC;
+		if(NRF_Payload > pmax) NRF_Payload = pmax;
+	}
 	prepare_nrf24();
 	if(NRF_ERROR) {
 		FURI_LOG_E(TAG, "NRF R/W ERROR!");
@@ -456,14 +475,89 @@ static void start_scanning()
 	FURI_LOG_D(TAG, "Start scan: Ch=%d Rate=%d", NRF_channel, NRF_rate);
 }
 
+// start bitnum = 7
+uint16_t calc_crc(uint32_t crc, uint8_t *ptr, uint8_t bitnum, uint16_t bits)
+{
+	//uint8_t bitnum = 7;
+	uint32_t crc_high, polynom;
+	if(view_log_decode_CRC == 2) {
+		crc_high = (1<<16);
+		polynom = 0x11021;	// X^16+X^12+X^5+1
+	} else {
+		crc_high = (1<<8);
+		polynom = 0x107;	// x^8+x^2+x^1+1 
+	}
+	while(bits--) {
+		crc <<= 1;
+		if(((crc & crc_high) != 0) ^ ((*ptr >> bitnum) & 1)) crc ^= polynom;
+		if(bitnum == 0) {
+			ptr++; 
+			bitnum = 7;
+		} else bitnum--;
+	}
+	return crc & (view_log_decode_CRC == 2 ? 0xFFFF : 0xFF);
+}
+
+// shifted 1 bit right
+uint16_t get_shifted_crc(uint8_t *pcrc)
+{
+	uint16_t crc = ((uint8_t)(*pcrc << 1)) | (*(pcrc+1) >> 7);
+	if(view_log_decode_CRC == 2) {
+		crc = (crc << 8) | (((uint8_t)(*(pcrc+1) << 1))) | (*(pcrc+2) >> 7);
+	}
+	return crc;
+}
+
+bool check_packet(uint8_t *pkt, uint8_t size)
+{
+	for(uint8_t addr_size = 3; addr_size <= 5; addr_size++) {
+		if(NRF_ESB){
+			uint8_t b = *(pkt + addr_size) >> 2;
+			if((b > 32 && b != 0x33)) continue;
+			if(b != 0x33) { // DPL
+				uint16_t crc = view_log_decode_CRC == 2 ? 0xFFFF : 0xFF;
+				if(calc_crc(crc, pkt, 7, 9 + b * 8) == get_shifted_crc(pkt + b + 1)) {
+					*(pkt - 1) = ((b & 0x1F) << 3) + 0b000 + (addr_size - 2);
+					return true;
+				}
+			} else {
+				for(uint8_t i = 0; i < size - view_log_decode_CRC; i++) {
+					uint16_t crc = view_log_decode_CRC == 2 ? 0xFFFF : 0xFF;
+					crc = calc_crc(crc, pkt, 7, 9 + i * 8);
+					if(crc == get_shifted_crc(pkt + i + 1)) {
+						*(pkt - 1) = ((i & 0x1F) << 3) + 0b100 + (addr_size - 2);
+						return true;
+					} 
+				}
+			}
+		} else {
+			for(uint8_t i = 0; i < size - view_log_decode_CRC; i++) {
+				uint16_t crc = view_log_decode_CRC == 2 ? 0xFFFF : 0xFF;
+				crc = calc_crc(crc, pkt, 7, i * 8);
+				if((view_log_decode_CRC == 1 && crc == *(pkt + i + 1)) || (view_log_decode_CRC == 2 && crc == ((*(pkt + i + 1)<<8) | *(pkt + i + 2)))) {
+					*(pkt - 1) = ((i & 0x1F) << 3) + 0b000 + (addr_size - 2);
+					return true;
+				} 
+			}
+		}
+	}
+	return false;
+}
+
 bool nrf24_read_newpacket() {
 	if(APP->log_arr == NULL) return false;
 	bool found = false;
 	uint8_t packetsize;
 	uint8_t *ptr = APP->log_arr + log_arr_idx * LOG_REC_SIZE;
-	uint8_t status = nrf24_rxpacket(nrf24_HANDLE, ptr + 1, &packetsize, !NRF_DPL);
+	uint8_t status = nrf24_rxpacket(nrf24_HANDLE, ptr + 2, &packetsize, !NRF_DPL);
 	if(status & RX_DR) {
-		*ptr = ((packetsize & 0x1F) << 3) | ((status >> 1) & 7); // payload size + pipe #
+		if(what_to_do == 1) {
+			*ptr++ = NRF_channel | 0x80;
+			if(!check_packet(ptr + 2, packetsize)) return false;
+		} else {
+			*ptr++ = NRF_channel;
+			*ptr = ((packetsize & 0x1F) << 3) | ((status >> 1) & 7); // payload size + pipe #
+		}
 		if(packetsize < 32) memset(ptr + packetsize + 1, 0, 32 - packetsize);
 		if(log_arr_idx < MAX_LOG_RECORDS - 1) {
 			log_arr_idx++;
@@ -486,45 +580,15 @@ bool nrf24_send_packet()
 {
 	if(log_arr_idx == 0) return false;
 	if(!what_to_do) prepare_nrf24();
-	last_packet_send_st = nrf24_txpacket(nrf24_HANDLE, APP->log_arr + view_log_arr_idx * LOG_REC_SIZE + 1, 32, false);
+	//nrf24_write_reg(nrf24_HANDLE, REG_RF_CH, NRF_channel);
+	// todo: Ch + ESB
+	last_packet_send_st = nrf24_txpacket(nrf24_HANDLE, APP->log_arr + view_log_arr_idx * LOG_REC_SIZE + 2, 32, false);
 	last_packet_send = view_log_arr_idx;
 	notification_message(APP->notification, last_packet_send_st ? &sequence_blink_blue_100 : &sequence_blink_red_100);
 	if(what_to_do) start_scanning();
 	return last_packet_send_st;
 }
 
-uint16_t calc_crc(uint32_t crc, uint8_t *ptr, uint8_t bitnum, uint16_t bits)
-{
-	//uint8_t bitnum = 7;
-	uint32_t crc_high, polynom;
-	if(view_log_decode_CRC == 2) {
-		crc_high = (1<<16);
-		polynom = 0x11021;	// X^16+X^12+X^5+1
-	} else {
-		crc_high = (1<<8);
-		polynom = 0x107;	// x^8+x^2+x^1+1 
-	}
-	while(bits--) {
-		crc <<= 1;
-		if(((crc & crc_high) != 0) ^ ((*ptr >> bitnum) & 1)) crc ^= polynom;
-		if(bitnum == 0) {
-			ptr++; 
-			bitnum = 7;
-		} else bitnum--;
-	}
-	return crc & (view_log_decode_CRC == 2 ? 0xFFFF : 0xFF);
-}
-
-// shifted 1 bit right
-uint16_t get_shifted_crc(uint8_t *pcrc)
-{
-	uint16_t crc = ((uint8_t)(*pcrc << 1)) | (*(pcrc+1) >> 7);
-	if(view_log_decode_CRC == 2) {
-		crc = (crc << 8) | (((uint8_t)(*(pcrc+1) << 1))) | (*(pcrc+2) >> 7);
-	}
-	return crc;
-}
-
 static void render_callback(Canvas* const canvas, void* ctx) {
 	const PluginState* plugin_state = acquire_mutex((ValueMutex*)ctx, 25);
 	if(plugin_state == NULL) return;
@@ -532,7 +596,7 @@ static void render_callback(Canvas* const canvas, void* ctx) {
 	if(what_doing == 0) {
 		canvas_set_font(canvas, FontSecondary); // 8x10 font
 		if(save_settings) snprintf(screen_buf, sizeof(screen_buf), "Save: %s", SETTINGS_FILENAME);						// menu_selected = 0
-		else snprintf(screen_buf, sizeof(screen_buf), "Load: %s", addr_file_name);
+		else snprintf(screen_buf, sizeof(screen_buf), "Load: %s", what_to_do == 1 ? "SNIFF" : addr_file_name);
 		canvas_draw_str(canvas, 10, 10, screen_buf);
 		snprintf(screen_buf, sizeof(screen_buf), "Ch: %d", NRF_channel); 												// menu_selected = 1
 		canvas_draw_str(canvas, 10, 20, screen_buf);
@@ -568,7 +632,7 @@ static void render_callback(Canvas* const canvas, void* ctx) {
 			snprintf(screen_buf, sizeof(screen_buf), "<%d", view_log_arr_x);
 			if(view_log_arr_x < VIEW_LOG_MAX_X) ch2 = true;
 		} 
-		snprintf(screen_buf + strlen(screen_buf), sizeof(screen_buf), " %s ch: %d - %d.", what_to_do ? "Read" : "View", NRF_channel, log_arr_idx);
+		snprintf(screen_buf + strlen(screen_buf), sizeof(screen_buf), " %s ch: %d - %d.", what_to_do == 1 ? "Sniff" : what_to_do == 2 ? "Read" : "View", NRF_channel, log_arr_idx);
 		canvas_draw_str(canvas, 0, 7, screen_buf);
 		if(ch2) canvas_draw_str(canvas, 121, 7, ">");
 		if(log_arr_idx) {
@@ -578,6 +642,7 @@ static void render_callback(Canvas* const canvas, void* ctx) {
 				screen_buf[0] = (view_log_arr_idx & 7) != i ? ' ' : last_packet_send != view_log_arr_idx ? '>' : last_packet_send_st ? '*' : '!';
 				screen_buf[1] = '\0';
 				char *ptr = (char*)APP->log_arr + (page + i) * LOG_REC_SIZE;
+				uint8_t channel = *ptr++; 
 				uint8_t dpl = *ptr++;
 				uint8_t pipe = dpl & 7;
 				dpl >>= 3;
@@ -586,50 +651,58 @@ static void render_callback(Canvas* const canvas, void* ctx) {
 				if(view_log_decode_PCF) count--;
 				uint8_t max_width = VIEW_LOG_WIDTH_B;
 				if(view_log_arr_x == 0) {
-					if(addrs.addr_count > 1) max_width--;
-					if(view_log_decode_PCF) max_width -= 2; 
+					if(channel & 0x80) { // RAW packet
+						max_width -= 5;
+					} else {
+						if(addrs.addr_count > 1) max_width--;
+						if(view_log_decode_PCF) max_width -= 2; 
+					}
 				}
 				if(count > max_width) count = max_width;
 				ptr += view_log_arr_x;
 				uint8_t *crcptr = NULL;
 				uint8_t pre = 0;
 				if(count > 0) {
-					if(view_log_decode_CRC) {
-						static uint16_t prev_addr_CRC;
-						static int8_t prev_pipe = -1;
-						uint8_t *pcrc = APP->log_arr + (page + i) * LOG_REC_SIZE + 1;
-						uint16_t crc;
-						if(prev_pipe == pipe) { crc = prev_addr_CRC;
-						} else {
-							crc = view_log_decode_CRC == 2 ? 0xFFFF : 0xFF;
-							if(pipe <= 1) { crc = calc_crc(crc, pipe == 0 ? addrs.addr_P0 : addrs.addr_P1, 7, addrs.addr_len * 8);
+					if(channel & 0x80) { // RAW packet
+							
+					} else {
+						if(view_log_decode_CRC) {
+							static uint16_t prev_addr_CRC;
+							static int8_t prev_pipe = -1;
+							uint8_t *pcrc = APP->log_arr + (page + i) * LOG_REC_SIZE + 1;
+							uint16_t crc;
+							if(prev_pipe == pipe) { crc = prev_addr_CRC;
 							} else {
-								crc = calc_crc(crc, addrs.addr_P1, 7, (addrs.addr_len - 1) * 8);
-								crc = calc_crc(crc, pipe == 2 ? &addrs.addr_P2 : pipe == 3 ? &addrs.addr_P3 : pipe == 4 ? &addrs.addr_P4 : &addrs.addr_P5, 7, 8);
+								crc = view_log_decode_CRC == 2 ? 0xFFFF : 0xFF;
+								if(pipe <= 1) { crc = calc_crc(crc, pipe == 0 ? addrs.addr_P0 : addrs.addr_P1, 7, addrs.addr_len * 8);
+								} else {
+									crc = calc_crc(crc, addrs.addr_P1, 7, (addrs.addr_len - 1) * 8);
+									crc = calc_crc(crc, pipe == 2 ? &addrs.addr_P2 : pipe == 3 ? &addrs.addr_P3 : pipe == 4 ? &addrs.addr_P4 : &addrs.addr_P5, 7, 8);
+								}
+								prev_addr_CRC = crc;
+								prev_pipe = pipe;
 							}
-							prev_addr_CRC = crc;
-							prev_pipe = pipe;
-						}
-						if(view_log_decode_PCF) {
-							crc = calc_crc(crc, pcrc++, 7, 9);
-							if(crc == get_shifted_crc(pcrc)) crcptr = pcrc;
-							if(crcptr == NULL) {
-								for(int8_t j = 0; j < (int8_t)dpl - view_log_decode_CRC - 1; j++) {
-									crc = calc_crc(crc, pcrc++, 6, 8);
-									if(crc == get_shifted_crc(pcrc)) {
+							if(view_log_decode_PCF) {
+								crc = calc_crc(crc, pcrc++, 7, 9);
+								if(crc == get_shifted_crc(pcrc)) crcptr = pcrc;
+								if(crcptr == NULL) {
+									for(int8_t j = 0; j < (int8_t)dpl - view_log_decode_CRC - 1; j++) {
+										crc = calc_crc(crc, pcrc++, 6, 8);
+										if(crc == get_shifted_crc(pcrc)) {
+											crcptr = pcrc;
+											break;
+										}
+									}
+								}
+							} else {
+								for(int8_t j = 0; j < (int8_t)dpl - view_log_decode_CRC; j++) {
+									crc = calc_crc(crc, pcrc++, 7, 8);
+									if((view_log_decode_CRC == 1 && crc == *pcrc) || (view_log_decode_CRC == 2 && crc == ((*pcrc<<8) | *(pcrc+1)))) {
 										crcptr = pcrc;
 										break;
 									}
 								}
 							}
-						} else {
-							for(int8_t j = 0; j < (int8_t)dpl - view_log_decode_CRC; j++) {
-								crc = calc_crc(crc, pcrc++, 7, 8);
-								if((view_log_decode_CRC == 1 && crc == *pcrc) || (view_log_decode_CRC == 2 && crc == ((*pcrc<<8) | *(pcrc+1)))) {
-									crcptr = pcrc;
-									break;
-								}
-							}
 						}
 					}
 					if(max_width < VIEW_LOG_WIDTH_B) {
@@ -665,7 +738,7 @@ static void render_callback(Canvas* const canvas, void* ctx) {
 			}
 		}
 	} else {
-		canvas_set_font(canvas, FontBatteryPercent); // 5x7 font
+		canvas_set_font(canvas, FontBatteryPercent); // 5x7 font, 9 lines
 		if(addrs.addr_count > 0) {
 			snprintf(screen_buf, sizeof(screen_buf), "P0: ");
 			add_to_str_hex_bytes(screen_buf, (char*)addrs.addr_P0, addrs.addr_len);
@@ -696,6 +769,10 @@ static void render_callback(Canvas* const canvas, void* ctx) {
 			snprintf(screen_buf, sizeof(screen_buf), "%02X", addrs.addr_P5); 
 			canvas_draw_str(canvas, (4 + (addrs.addr_len - 1) * 2) * 5, 6 * 7, screen_buf);
 		}
+		if(log_arr_idx && view_log_arr_idx) {
+			snprintf(screen_buf, sizeof(screen_buf), "Current Ch: %d", *(APP->log_arr + view_log_arr_idx * LOG_REC_SIZE) & 0x7F); 
+			canvas_draw_str(canvas, 0, 7 * 7, screen_buf);
+		}
 		screen_buf[0] = 'v';
 		strcpy(screen_buf + 1, VERSION);
 		canvas_draw_str(canvas, 108, 7, screen_buf);
@@ -802,7 +879,7 @@ int32_t nrf24scan_app(void* p) {
 									if(--log_to_file < -1) log_to_file = 2;
 									break;
 								case Menu_ok:
-									what_to_do = !what_to_do;
+									if(++what_to_do > 2) what_to_do = 0;
 									break;
 							}
 						} else if(what_doing == 1) {
@@ -835,7 +912,7 @@ int32_t nrf24scan_app(void* p) {
 									if(++log_to_file > 2) log_to_file = -1;
 									break;
 								case Menu_ok:
-									what_to_do = !what_to_do;
+									if(++what_to_do > 2) what_to_do = 0;
 									break;
 							}
 						} else if(what_doing == 1) {
@@ -867,7 +944,7 @@ int32_t nrf24scan_app(void* p) {
 									if(NRF_rate > 2) NRF_rate = 0;
 									break;
 								case Menu_enter_scan_period:
-									if(++NRF_CRC > 2) NRF_CRC = 0;
+									if(++NRF_CRC > 2) NRF_CRC = what_to_do == 1 ? 1 : 0;
 									break;
 								case Menu_ok:
 									if(what_to_do) {