From 4b06e49b2998d0ac1a7edd5792af75ca58311492 Mon Sep 17 00:00:00 2001 From: imagemlt Date: Tue, 22 Oct 2024 21:13:08 +0800 Subject: [PATCH 1/2] Devourer Experimental TX implementation --- CMakeLists.txt | 6 + hal/basic_types.h | 7 +- src/EepromManager.h | 2 + src/FrameParser.cpp | 58 ++- src/FrameParser.h | 505 +++++++++++++++++-- src/RadioManagementModule.cpp | 422 +++++++++++++++- src/RadioManagementModule.h | 3 + src/Radiotap.c | 911 ++++++++++++++++++++++++++++++++++ src/Rtl8812aDevice.cpp | 254 +++++++++- src/Rtl8812aDevice.h | 20 +- src/RtlUsbAdapter.cpp | 62 ++- src/RtlUsbAdapter.h | 17 +- src/ieee80211_radiotap.h | 550 ++++++++++++++++++++ txdemo/main.cpp | 142 ++++++ 14 files changed, 2877 insertions(+), 82 deletions(-) create mode 100644 src/Radiotap.c create mode 100644 src/ieee80211_radiotap.h create mode 100644 txdemo/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ea93fd..4c7b6a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,7 @@ add_library(WiFiDriver hal/rtl8812a_recv.h hal/rtl8812a_spec.h + src/ieee80211_radiotap.h src/EepromManager.cpp src/EepromManager.h src/Firmware.h @@ -39,6 +40,7 @@ add_library(WiFiDriver src/ParsedRadioPacket.cpp src/RadioManagementModule.cpp src/RadioManagementModule.h + src/Radiotap.c src/Rtl8812aDevice.cpp src/Rtl8812aDevice.h src/RtlUsbAdapter.cpp @@ -62,3 +64,7 @@ add_executable(WiFiDriverDemo demo/main.cpp) target_link_libraries(WiFiDriverDemo PUBLIC WiFiDriver) + +add_executable(WiFiDriverTxDemo + txdemo/main.cpp) +target_link_libraries(WiFiDriverTxDemo PUBLIC WiFiDriver) diff --git a/hal/basic_types.h b/hal/basic_types.h index d32d7d6..514b8dc 100644 --- a/hal/basic_types.h +++ b/hal/basic_types.h @@ -18,8 +18,11 @@ #define _FALSE FALSE #endif -#define le16_to_cpu(x) ((uint16_t)(x)) -#define le32_to_cpu(x) ((uint32_t)(x)) +#define cpu_to_le32(x) ((__u32)(x)) +#define le32_to_cpu(x) ((__u32)(x)) +#define cpu_to_le16(x) ((__u16)(x)) +#define le16_to_cpu(x) ((__u16)(x)) + #define LE_BITS_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ ((LE_P4BYTE_TO_HOST_4BYTE(__pStart) >> (__BitOffset)) & \ diff --git a/src/EepromManager.h b/src/EepromManager.h index b963090..0652296 100644 --- a/src/EepromManager.h +++ b/src/EepromManager.h @@ -8,6 +8,8 @@ #include "phydm_pre_define.h" #include "rtl8812a_hal.h" +typedef unsigned short ushort; + class EepromManager { RtlUsbAdapter _device; Logger_t _logger; diff --git a/src/FrameParser.cpp b/src/FrameParser.cpp index b28ece4..381883f 100644 --- a/src/FrameParser.cpp +++ b/src/FrameParser.cpp @@ -118,8 +118,9 @@ std::vector FrameParser::recvbuf2recvframe(std::span ptr) { ret.push_back({pattrib, pbuf.subspan(pattrib.shift_sz + pattrib.drvinfo_sz + RXDESC_SIZE, pattrib.pkt_len)}); - // pre_recv_entry(precvframe, pattrib.physt ? pbuf.Slice(RXDESC_OFFSET) : - // null); + + ret.back().RxAtrib.rssi[0] = pbuf[RXDESC_SIZE]; + ret.back().RxAtrib.rssi[1] = pbuf[RXDESC_SIZE + 1]; } else { /* pkt_rpt_type == TX_REPORT1-CCX, TX_REPORT2-TX RTP,HIS_REPORT-USB HISR * RTP */ @@ -149,3 +150,56 @@ std::vector FrameParser::recvbuf2recvframe(std::span ptr) { return ret; } + +void rtl8812a_cal_txdesc_chksum(uint8_t *ptxdesc) { + u16 *usPtr; + u32 count; + u32 index; + u16 checksum = 0; + + usPtr = (u16 *)ptxdesc; + + /* checksum is always calculated by first 32 bytes, */ + /* and it doesn't depend on TX DESC length. */ + /* Thomas,Lucas@SD4,20130515 */ + count = 16; + + /* Clear first */ + SET_TX_DESC_TX_DESC_CHECKSUM_8812(ptxdesc, 0); + + for (index = 0; index < count; index++) + checksum = checksum ^ le16_to_cpu(*(usPtr + index)); + + SET_TX_DESC_TX_DESC_CHECKSUM_8812(ptxdesc, checksum); +} + +int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8 *category, + u8 *action) { + /*const u8 *frame_body = frame + sizeof(struct rtw_ieee80211_hdr_3addr); + u16 fc; + u8 c; + u8 a = ACT_PUBLIC_MAX; + + fc = le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)frame)->frame_ctl); + + if ((fc & (RTW_IEEE80211_FCTL_FTYPE | RTW_IEEE80211_FCTL_STYPE)) + != (RTW_IEEE80211_FTYPE_MGMT | RTW_IEEE80211_STYPE_ACTION) + ) + return _FALSE; + + c = frame_body[0]; + + switch (c) { + case RTW_WLAN_CATEGORY_P2P: // vendor-specific + break; + default: + a = frame_body[1]; + } + + if (category) + *category = c; + if (action) + *action = a; +*/ + return _TRUE; +} diff --git a/src/FrameParser.h b/src/FrameParser.h index 1e5e2af..172cbbc 100644 --- a/src/FrameParser.h +++ b/src/FrameParser.h @@ -2,52 +2,471 @@ #define FRAMEPARSER_H #include "logger.h" +#include #include #include -enum class RX_PACKET_TYPE { - NORMAL_RX, /* Normal rx packet */ - TX_REPORT1, /* CCX */ - TX_REPORT2, /* TX RPT */ - HIS_REPORT, /* USB HISR RPT */ - C2H_PACKET -}; - -struct rx_pkt_attrib { - uint16_t pkt_len; - bool physt; - uint8_t drvinfo_sz; - uint8_t shift_sz; - bool qos; - uint8_t priority; - bool mdata; - uint16_t seq_num; - uint8_t frag_num; - bool mfrag; - bool bdecrypted; - uint8_t encrypt; /* when 0 indicate no encrypt. when non-zero, indicate the - encrypt algorith */ - bool crc_err; - bool icv_err; - uint8_t data_rate; - uint8_t bw; - uint8_t stbc; - uint8_t ldpc; - uint8_t sgi; - RX_PACKET_TYPE pkt_rpt_type; -}; - -struct Packet { - rx_pkt_attrib RxAtrib; - std::span Data; -}; - -class FrameParser { - Logger_t _logger; - -public: - FrameParser(Logger_t logger); - std::vector recvbuf2recvframe(std::span ptr); +typedef unsigned int __u32; + +#ifndef __u16 +typedef unsigned short __u16; +#endif + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +#define ETH_ALEN 6 +#define TXDESC_SIZE 40 +#define OFFSET_SZ 0 +#define OFFSET_SHT 16 +#define OWN BIT(31) +#define FSG BIT(27) +#define LSG BIT(26) +#define QSEL_SHT 8 + +#define WriteLE4Byte(_ptr, _val) ((*((u32*)(_ptr))) = cpu_to_le32(_val)) +#define WriteLE2Byte(_ptr, _val) ((*((u16*)(_ptr))) = cpu_to_le16(_val)) +#define WriteLE1Byte(_ptr, _val) ((*((u8*)(_ptr))) = ((u8)(_val))) + +#define BIT_LEN_MASK_32(__BitLen) ((u32)(0xFFFFFFFF >> (32 - (__BitLen)))) + +#define LE_P4BYTE_TO_HOST_4BYTE(__pStart) (le32_to_cpu(*((u32*)(__pStart)))) + +#define BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) ((u32)(BIT_LEN_MASK_32(__BitLen) << (__BitOffset))) + +#define LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + (LE_P4BYTE_TO_HOST_4BYTE(__pStart) & (~BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen))) + +#define SET_BITS_TO_LE_4BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + do \ + { \ + if (__BitOffset == 0 && __BitLen == 32) \ + WriteLE4Byte(__pStart, __Value); \ + else \ + { \ + WriteLE4Byte(__pStart, \ + LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) | \ + ((((u32)__Value) & BIT_LEN_MASK_32(__BitLen)) << (__BitOffset))); \ + } \ + } while (0) + +#define SET_TX_DESC_TX_DESC_CHECKSUM_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 28, 0, 16, __Value) + +#define SET_TX_DESC_RATE_ID_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 4, 16, 5, __Value) + +#define SET_TX_DESC_PKT_SIZE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 0, 16, __Value) +#define SET_TX_DESC_OFFSET_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 16, 8, __Value) +#define SET_TX_DESC_BMC_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 24, 1, __Value) +#define SET_TX_DESC_HTC_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 25, 1, __Value) +#define SET_TX_DESC_LAST_SEG_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 26, 1, __Value) +#define SET_TX_DESC_FIRST_SEG_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 27, 1, __Value) +#define SET_TX_DESC_LINIP_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 28, 1, __Value) +#define SET_TX_DESC_NO_ACM_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 29, 1, __Value) +#define SET_TX_DESC_GF_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 30, 1, __Value) +#define SET_TX_DESC_OWN_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 31, 1, __Value) + +/* Dword 1 */ +#define SET_TX_DESC_MACID_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 4, 0, 7, __Value) +#define SET_TX_DESC_QUEUE_SEL_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 4, 8, 5, __Value) +#define SET_TX_DESC_RDG_NAV_EXT_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 4, 13, 1, __Value) +#define SET_TX_DESC_LSIG_TXOP_EN_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 4, 14, 1, __Value) +#define SET_TX_DESC_PIFS_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 4, 15, 1, __Value) +#define SET_TX_DESC_RATE_ID_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 4, 16, 5, __Value) +#define SET_TX_DESC_EN_DESC_ID_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 4, 21, 1, __Value) +#define SET_TX_DESC_SEC_TYPE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 4, 22, 2, __Value) +#define SET_TX_DESC_PKT_OFFSET_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 4, 24, 5, __Value) + +/* Dword 2 */ +#define SET_TX_DESC_PAID_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 8, 0, 9, __Value) +#define SET_TX_DESC_CCA_RTS_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 8, 10, 2, __Value) +#define SET_TX_DESC_AGG_ENABLE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 8, 12, 1, __Value) +#define SET_TX_DESC_RDG_ENABLE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 8, 13, 1, __Value) +#define SET_TX_DESC_AGG_BREAK_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 8, 16, 1, __Value) +#define SET_TX_DESC_MORE_FRAG_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 8, 17, 1, __Value) +#define SET_TX_DESC_RAW_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 8, 18, 1, __Value) +#define SET_TX_DESC_SPE_RPT_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 8, 19, 1, __Value) +#define SET_TX_DESC_AMPDU_DENSITY_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 8, 20, 3, __Value) +#define SET_TX_DESC_BT_INT_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 8, 23, 1, __Value) +#define SET_TX_DESC_GID_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 8, 24, 6, __Value) + +/* Dword 3 */ +#define SET_TX_DESC_WHEADER_LEN_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 12, 0, 4, __Value) +#define SET_TX_DESC_CHK_EN_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 12, 4, 1, __Value) +#define SET_TX_DESC_EARLY_MODE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 12, 5, 1, __Value) +#define SET_TX_DESC_HWSEQ_SEL_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 12, 6, 2, __Value) +#define SET_TX_DESC_USE_RATE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 12, 8, 1, __Value) +#define SET_TX_DESC_DISABLE_RTS_FB_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 12, 9, 1, __Value) +#define SET_TX_DESC_DISABLE_FB_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 12, 10, 1, __Value) +#define SET_TX_DESC_CTS2SELF_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 12, 11, 1, __Value) +#define SET_TX_DESC_RTS_ENABLE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 12, 12, 1, __Value) +#define SET_TX_DESC_HW_RTS_ENABLE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 12, 13, 1, __Value) +#define SET_TX_DESC_NAV_USE_HDR_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 12, 15, 1, __Value) +#define SET_TX_DESC_USE_MAX_LEN_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 12, 16, 1, __Value) +#define SET_TX_DESC_MAX_AGG_NUM_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 12, 17, 5, __Value) +#define SET_TX_DESC_NDPA_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 12, 22, 2, __Value) +#define SET_TX_DESC_AMPDU_MAX_TIME_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 12, 24, 8, __Value) + +/* Dword 4 */ +#define SET_TX_DESC_TX_RATE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 16, 0, 7, __Value) +#define SET_TX_DESC_DATA_RATE_FB_LIMIT_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 16, 8, 5, __Value) +#define SET_TX_DESC_RTS_RATE_FB_LIMIT_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 16, 13, 4, __Value) +#define SET_TX_DESC_RETRY_LIMIT_ENABLE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 16, 17, 1, __Value) +#define SET_TX_DESC_DATA_RETRY_LIMIT_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 16, 18, 6, __Value) +#define SET_TX_DESC_RTS_RATE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 16, 24, 5, __Value) + +/* Dword 5 */ +#define SET_TX_DESC_DATA_SC_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 20, 0, 4, __Value) +#define SET_TX_DESC_DATA_SHORT_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 20, 4, 1, __Value) +#define SET_TX_DESC_DATA_BW_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 20, 5, 2, __Value) +#define SET_TX_DESC_DATA_LDPC_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 20, 7, 1, __Value) +#define SET_TX_DESC_DATA_STBC_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 20, 8, 2, __Value) +#define SET_TX_DESC_CTROL_STBC_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 20, 10, 2, __Value) +#define SET_TX_DESC_RTS_SHORT_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 20, 12, 1, __Value) +#define SET_TX_DESC_RTS_SC_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 20, 13, 4, __Value) +#define SET_TX_DESC_TX_ANT_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 20, 24, 4, __Value) + +/* Dword 6 */ +#define SET_TX_DESC_SW_DEFINE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 24, 0, 12, __Value) +#define SET_TX_DESC_ANTSEL_A_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 24, 16, 3, __Value) +#define SET_TX_DESC_ANTSEL_B_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 24, 19, 3, __Value) +#define SET_TX_DESC_ANTSEL_C_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 24, 22, 3, __Value) +#define SET_TX_DESC_ANTSEL_D_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 24, 25, 3, __Value) +#define SET_TX_DESC_MBSSID_8821(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 24, 12, 4, __Value) + +/* Dword 7 */ +#define SET_TX_DESC_TX_BUFFER_SIZE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 28, 0, 16, __Value) +#define SET_TX_DESC_TX_DESC_CHECKSUM_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 28, 0, 16, __Value) +#define SET_TX_DESC_USB_TXAGG_NUM_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 28, 24, 8, __Value) +#ifdef CONFIG_SDIO_HCI +#define SET_TX_DESC_SDIO_TXSEQ_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 28, 16, 8, __Value) +#endif + +/* Dword 8 */ +#define SET_TX_DESC_HWSEQ_EN_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 32, 15, 1, __Value) + +/* Dword 9 */ +#define SET_TX_DESC_SEQ_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 36, 12, 12, __Value) + +/* Dword 10 */ +#define SET_TX_DESC_TX_BUFFER_ADDRESS_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 40, 0, 32, __Value) +#define GET_TX_DESC_TX_BUFFER_ADDRESS_8812(__pTxDesc) LE_BITS_TO_4BYTE(__pTxDesc + 40, 0, 32) + +/* Dword 11 */ +#define SET_TX_DESC_NEXT_DESC_ADDRESS_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc + 48, 0, 32, __Value) + +#define SET_EARLYMODE_PKTNUM_8812(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 0, 4, __Value) +#define SET_EARLYMODE_LEN0_8812(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 4, 15, __Value) +#define SET_EARLYMODE_LEN1_1_8812(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 19, 13, __Value) +#define SET_EARLYMODE_LEN1_2_8812(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr + 4, 0, 2, __Value) +#define SET_EARLYMODE_LEN2_8812(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr + 4, 2, 15, __Value) +#define SET_EARLYMODE_LEN3_8812(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr + 4, 17, 15, __Value) + +#define RTW_IEEE80211_FCTL_FTYPE 0x000c +#define RTW_IEEE80211_FCTL_STYPE 0x00f0 +#define RTW_IEEE80211_FTYPE_MGMT 0x0000 +#define RTW_IEEE80211_STYPE_ACTION 0x00d0 + +// radiotap +#define MAX_RX_INTERFACES 8 + +// offset of MCS_FLAGS and MCS index +#define MCS_FLAGS_OFF 11 +#define MCS_IDX_OFF 12 + +// offset of VHT information +#define VHT_FLAGS_OFF 12 +#define VHT_BW_OFF 13 +#define VHT_MCSNSS0_OFF 14 +#define VHT_CODING_OFF 18 + +// the last four bytes used for channel_id +#define SRC_MAC_THIRD_BYTE 12 +#define DST_MAC_THIRD_BYTE 18 +#define FRAME_SEQ_LB 22 +#define FRAME_SEQ_HB 23 + +#define FRAME_TYPE_DATA 0x08 +#define FRAME_TYPE_RTS 0xb4 + +#define IEEE80211_RADIOTAP_MCS_HAVE_BW 0x01 +#define IEEE80211_RADIOTAP_MCS_HAVE_MCS 0x02 +#define IEEE80211_RADIOTAP_MCS_HAVE_GI 0x04 +#define IEEE80211_RADIOTAP_MCS_HAVE_FMT 0x08 + +#define IEEE80211_RADIOTAP_MCS_BW_20 0 +#define IEEE80211_RADIOTAP_MCS_BW_40 1 +#define IEEE80211_RADIOTAP_MCS_BW_20L 2 +#define IEEE80211_RADIOTAP_MCS_BW_20U 3 +#define IEEE80211_RADIOTAP_MCS_SGI 0x04 +#define IEEE80211_RADIOTAP_MCS_FMT_GF 0x08 + +#define IEEE80211_RADIOTAP_MCS_HAVE_FEC 0x10 +#define IEEE80211_RADIOTAP_MCS_HAVE_STBC 0x20 +#define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10 +#define IEEE80211_RADIOTAP_MCS_STBC_MASK 0x60 +#define IEEE80211_RADIOTAP_MCS_STBC_1 1 +#define IEEE80211_RADIOTAP_MCS_STBC_2 2 +#define IEEE80211_RADIOTAP_MCS_STBC_3 3 +#define IEEE80211_RADIOTAP_MCS_STBC_SHIFT 5 + +#define IEEE80211_RADIOTAP_VHT_FLAG_STBC 0x01 +#define IEEE80211_RADIOTAP_VHT_FLAG_SGI 0x04 +#define IEEE80211_RADIOTAP_VHT_MCS_MASK 0xF0 +#define IEEE80211_RADIOTAP_VHT_NSS_MASK 0x0F +#define IEEE80211_RADIOTAP_VHT_MCS_SHIFT 4 +#define IEEE80211_RADIOTAP_VHT_NSS_SHIFT 0 +#define IEEE80211_RADIOTAP_VHT_BW_20M 0x00 +#define IEEE80211_RADIOTAP_VHT_BW_40M 0x01 +#define IEEE80211_RADIOTAP_VHT_BW_80M 0x04 +#define IEEE80211_RADIOTAP_VHT_BW_160M 0x0B +#define IEEE80211_RADIOTAP_VHT_CODING_LDPC_USER0 0x01 + +#define IEEE80211_RADIOTAP_MCS_BW_MASK 0x03 + +#define MCS_KNOWN \ + (IEEE80211_RADIOTAP_MCS_HAVE_MCS | IEEE80211_RADIOTAP_MCS_HAVE_BW | IEEE80211_RADIOTAP_MCS_HAVE_GI | \ + IEEE80211_RADIOTAP_MCS_HAVE_STBC | IEEE80211_RADIOTAP_MCS_HAVE_FEC) + +union Keytype +{ + u8 skey[16]; + u32 lkey[4]; +}; +enum _PUBLIC_ACTION +{ + ACT_PUBLIC_BSSCOEXIST = 0, /* 20/40 BSS Coexistence */ + ACT_PUBLIC_DSE_ENABLE = 1, + ACT_PUBLIC_DSE_DEENABLE = 2, + ACT_PUBLIC_DSE_REG_LOCATION = 3, + ACT_PUBLIC_EXT_CHL_SWITCH = 4, + ACT_PUBLIC_DSE_MSR_REQ = 5, + ACT_PUBLIC_DSE_MSR_RPRT = 6, + ACT_PUBLIC_MP = 7, /* Measurement Pilot */ + ACT_PUBLIC_DSE_PWR_CONSTRAINT = 8, + ACT_PUBLIC_VENDOR = 9, /* for WIFI_DIRECT */ + ACT_PUBLIC_GAS_INITIAL_REQ = 10, + ACT_PUBLIC_GAS_INITIAL_RSP = 11, + ACT_PUBLIC_GAS_COMEBACK_REQ = 12, + ACT_PUBLIC_GAS_COMEBACK_RSP = 13, + ACT_PUBLIC_TDLS_DISCOVERY_RSP = 14, + ACT_PUBLIC_LOCATION_TRACK = 15, + ACT_PUBLIC_MAX +}; + +enum class RX_PACKET_TYPE +{ + NORMAL_RX, /* Normal rx packet */ + TX_REPORT1, /* CCX */ + TX_REPORT2, /* TX RPT */ + HIS_REPORT, /* USB HISR RPT */ + C2H_PACKET +}; + +struct rx_pkt_attrib +{ + uint16_t pkt_len; + bool physt; + uint8_t drvinfo_sz; + uint8_t shift_sz; + bool qos; + uint8_t priority; + bool mdata; + uint16_t seq_num; + uint8_t frag_num; + bool mfrag; + bool bdecrypted; + uint8_t encrypt; /* when 0 indicate no encrypt. when non-zero, indicate the + encrypt algorith */ + bool crc_err; + bool icv_err; + uint8_t data_rate; + uint8_t bw; + uint8_t stbc; + uint8_t ldpc; + uint8_t sgi; + uint8_t rssi[2]; + RX_PACKET_TYPE pkt_rpt_type; +}; + +struct Packet +{ + rx_pkt_attrib RxAtrib; + std::span Data; +}; + +class FrameParser +{ + Logger_t _logger; + + public: + FrameParser(Logger_t logger); + std::vector recvbuf2recvframe(std::span ptr); +}; + +struct pkt_attrib +{ + u8 type; + u8 subtype; + u8 bswenc; + u8 dhcp_pkt; + u16 ether_type; + u16 seqnum; + u8 hw_ssn_sel; /* for HW_SEQ0,1,2,3 */ + u16 pkt_hdrlen; /* the original 802.3 pkt header len */ + u16 hdrlen; /* the WLAN Header Len */ + u32 pktlen; /* the original 802.3 pkt raw_data len (not include ether_hdr data) */ + u32 last_txcmdsz; + u8 nr_frags; + u8 encrypt; /* when 0 indicate no encrypt. when non-zero, indicate the encrypt algorith */ + // #if defined(CONFIG_CONCURRENT_MODE) + u8 bmc_camid; + // #endif + u8 iv_len; + u8 icv_len; + u8 iv[18]; + u8 icv[16]; + u8 priority; + u8 ack_policy; + u8 mac_id; + u8 vcs_mode; /* virtual carrier sense method */ + u8 dst[ETH_ALEN]; + u8 src[ETH_ALEN]; + u8 ta[ETH_ALEN]; + u8 ra[ETH_ALEN]; + u8 key_idx; + u8 qos_en; + u8 ht_en; + u8 raid; /* rate adpative id */ + u8 bwmode; + u8 ch_offset; /* PRIME_CHNL_OFFSET */ + u8 sgi; /* short GI */ + u8 ampdu_en; /* tx ampdu enable */ + u8 ampdu_spacing; /* ampdu_min_spacing for peer sta's rx */ + u8 amsdu; + u8 amsdu_ampdu_en; /* tx amsdu in ampdu enable */ + u8 mdata; /* more data bit */ + u8 pctrl; /* per packet txdesc control enable */ + u8 triggered; /* for ap mode handling Power Saving sta */ + u8 qsel; + u8 order; /* order bit */ + u8 eosp; + u8 rate; + u8 intel_proxim; + u8 retry_ctrl; + u8 mbssid; + u8 ldpc; + u8 stbc; + // #ifdef CONFIG_WMMPS_STA + u8 trigger_frame; + // #endif /* CONFIG_WMMPS_STA */ + + struct sta_info* psta; + // #ifdef CONFIG_TCP_CSUM_OFFLOAD_TX + u8 hw_tcp_csum; + // #endif + + u8 rtsen; + u8 cts2self; + union Keytype dot11tkiptxmickey; + /* union Keytype dot11tkiprxmickey; */ + union Keytype dot118021x_UncstKey; + + // #ifdef CONFIG_TDLS + u8 direct_link; + struct sta_info* ptdls_sta; + // #endif /* CONFIG_TDLS */ + u8 key_type; + + u8 icmp_pkt; + + // #ifdef CONFIG_BEAMFORMING + u16 txbf_p_aid; /*beamforming Partial_AID*/ + u16 txbf_g_id; /*beamforming Group ID*/ + + /* + * 2'b00: Unicast NDPA + * 2'b01: Broadcast NDPA + * 2'b10: Beamforming Report Poll + * 2'b11: Final Beamforming Report Poll + */ + u8 bf_pkt_type; + // #endif + u8 inject; /* == a5 if injected */ +}; + +struct rtw_ieee80211_hdr +{ + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u8 addr4[ETH_ALEN]; +} __attribute__((packed)); + +struct rtw_ieee80211_hdr_3addr +{ + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; +} __attribute__((packed)); + +struct rtw_ieee80211_hdr_qos +{ + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u8 addr4[ETH_ALEN]; + u16 qc; +} __attribute__((packed)); + +struct rtw_ieee80211_hdr_3addr_qos +{ + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u16 qc; +} __attribute__((packed)); + +struct eapol +{ + u8 snap[6]; + u16 ethertype; + u8 version; + u8 type; + u16 length; +} __attribute__((packed)); + +struct tx_desc +{ + unsigned int txdw0; // First descriptor field, typically contains packet length and other control information + unsigned int txdw1; // Second descriptor field, possibly includes MAC ID, queue selection, etc. + unsigned int txdw2; // Third descriptor field, reserved or for specific purposes + unsigned int txdw3; // Fourth descriptor field, sequence number, and frame control flags + unsigned int txdw4; // Fifth descriptor field, more control flags such as transmission rate, status, etc. + unsigned int txdw5; // Sixth descriptor field, reserved + unsigned int txdw6; // Seventh descriptor field, possibly used for additional status information + unsigned int txdw7; // Eighth descriptor field, specifies how the packet should be processed + + unsigned int txdw8; // Additional field in a 40-byte descriptor + unsigned int txdw9; // Another additional field }; +void rtl8812a_cal_txdesc_chksum(uint8_t* ptxdesc); #endif /* FRAMEPARSER_H */ diff --git a/src/RadioManagementModule.cpp b/src/RadioManagementModule.cpp index 712fea9..46d29c5 100644 --- a/src/RadioManagementModule.cpp +++ b/src/RadioManagementModule.cpp @@ -206,7 +206,6 @@ void RadioManagementModule::phy_SwChnlAndSetBwMode8812() { phy_PostSetBwMode8812(); _setChannelBw = false; } - PHY_SetTxPowerLevel8812(_currentChannel); _needIQK = false; @@ -1135,12 +1134,17 @@ const static std::vector rates_by_sections[] = { mgn_rates_vht3ss, mgn_rates_vht4ss, }; +void RadioManagementModule::SetTxPower(uint8_t p) { + power = p; + _logger->info("iwconfig wlan0 txpower {}", (int)p); +} + static uint8_t phy_get_tx_power_index() { return 16; } void RadioManagementModule::PHY_SetTxPowerIndexByRateArray( RfPath rfPath, const std::vector &rates) { for (int i = 0; i < rates.size(); ++i) { - auto powerIndex = phy_get_tx_power_index(); + auto powerIndex = power; MGN_RATE rate = rates[i]; PHY_SetTxPowerIndex_8812A(powerIndex, rfPath, rate); } @@ -1149,6 +1153,416 @@ void RadioManagementModule::PHY_SetTxPowerIndexByRateArray( void RadioManagementModule::PHY_SetTxPowerIndex_8812A(uint32_t powerIndex, RfPath rfPath, MGN_RATE rate) { + + _logger->debug("PHY_SetTxPowerIndex {} {} {}", powerIndex, (int)rfPath, rate); + if (powerIndex % 2 == 1) + powerIndex -= 1; + if (rfPath == RF_PATH_A) { + switch (rate) { + case MGN_1M: + _device.phy_set_bb_reg(rTxAGC_A_CCK11_CCK1_JAguar, bMaskByte0, + powerIndex); + break; + case MGN_2M: + _device.phy_set_bb_reg(rTxAGC_A_CCK11_CCK1_JAguar, bMaskByte1, + powerIndex); + break; + case MGN_5_5M: + _device.phy_set_bb_reg(rTxAGC_A_CCK11_CCK1_JAguar, bMaskByte2, + powerIndex); + break; + case MGN_11M: + _device.phy_set_bb_reg(rTxAGC_A_CCK11_CCK1_JAguar, bMaskByte3, + powerIndex); + break; + + case MGN_6M: + _device.phy_set_bb_reg(rTxAGC_A_Ofdm18_Ofdm6_JAguar, bMaskByte0, + powerIndex); + break; + case MGN_9M: + _device.phy_set_bb_reg(rTxAGC_A_Ofdm18_Ofdm6_JAguar, bMaskByte1, + powerIndex); + break; + case MGN_12M: + _device.phy_set_bb_reg(rTxAGC_A_Ofdm18_Ofdm6_JAguar, bMaskByte2, + powerIndex); + break; + case MGN_18M: + _device.phy_set_bb_reg(rTxAGC_A_Ofdm18_Ofdm6_JAguar, bMaskByte3, + powerIndex); + break; + + case MGN_24M: + _device.phy_set_bb_reg(rTxAGC_A_Ofdm54_Ofdm24_JAguar, bMaskByte0, + powerIndex); + break; + case MGN_36M: + _device.phy_set_bb_reg(rTxAGC_A_Ofdm54_Ofdm24_JAguar, bMaskByte1, + powerIndex); + break; + case MGN_48M: + _device.phy_set_bb_reg(rTxAGC_A_Ofdm54_Ofdm24_JAguar, bMaskByte2, + powerIndex); + break; + case MGN_54M: + _device.phy_set_bb_reg(rTxAGC_A_Ofdm54_Ofdm24_JAguar, bMaskByte3, + powerIndex); + break; + + case MGN_MCS0: + _device.phy_set_bb_reg(rTxAGC_A_MCS3_MCS0_JAguar, bMaskByte0, powerIndex); + break; + case MGN_MCS1: + _device.phy_set_bb_reg(rTxAGC_A_MCS3_MCS0_JAguar, bMaskByte1, powerIndex); + break; + case MGN_MCS2: + _device.phy_set_bb_reg(rTxAGC_A_MCS3_MCS0_JAguar, bMaskByte2, powerIndex); + break; + case MGN_MCS3: + _device.phy_set_bb_reg(rTxAGC_A_MCS3_MCS0_JAguar, bMaskByte3, powerIndex); + break; + + case MGN_MCS4: + _device.phy_set_bb_reg(rTxAGC_A_MCS7_MCS4_JAguar, bMaskByte0, powerIndex); + break; + case MGN_MCS5: + _device.phy_set_bb_reg(rTxAGC_A_MCS7_MCS4_JAguar, bMaskByte1, powerIndex); + break; + case MGN_MCS6: + _device.phy_set_bb_reg(rTxAGC_A_MCS7_MCS4_JAguar, bMaskByte2, powerIndex); + break; + case MGN_MCS7: + _device.phy_set_bb_reg(rTxAGC_A_MCS7_MCS4_JAguar, bMaskByte3, powerIndex); + break; + + case MGN_MCS8: + _device.phy_set_bb_reg(rTxAGC_A_MCS11_MCS8_JAguar, bMaskByte0, + powerIndex); + break; + case MGN_MCS9: + _device.phy_set_bb_reg(rTxAGC_A_MCS11_MCS8_JAguar, bMaskByte1, + powerIndex); + break; + case MGN_MCS10: + _device.phy_set_bb_reg(rTxAGC_A_MCS11_MCS8_JAguar, bMaskByte2, + powerIndex); + break; + case MGN_MCS11: + _device.phy_set_bb_reg(rTxAGC_A_MCS11_MCS8_JAguar, bMaskByte3, + powerIndex); + break; + + case MGN_MCS12: + _device.phy_set_bb_reg(rTxAGC_A_MCS15_MCS12_JAguar, bMaskByte0, + powerIndex); + break; + case MGN_MCS13: + _device.phy_set_bb_reg(rTxAGC_A_MCS15_MCS12_JAguar, bMaskByte1, + powerIndex); + break; + case MGN_MCS14: + _device.phy_set_bb_reg(rTxAGC_A_MCS15_MCS12_JAguar, bMaskByte2, + powerIndex); + break; + case MGN_MCS15: + _device.phy_set_bb_reg(rTxAGC_A_MCS15_MCS12_JAguar, bMaskByte3, + powerIndex); + break; + + case MGN_VHT1SS_MCS0: + _device.phy_set_bb_reg(rTxAGC_A_Nss1Index3_Nss1Index0_JAguar, bMaskByte0, + powerIndex); + break; + case MGN_VHT1SS_MCS1: + _device.phy_set_bb_reg(rTxAGC_A_Nss1Index3_Nss1Index0_JAguar, bMaskByte1, + powerIndex); + break; + case MGN_VHT1SS_MCS2: + _device.phy_set_bb_reg(rTxAGC_A_Nss1Index3_Nss1Index0_JAguar, bMaskByte2, + powerIndex); + break; + case MGN_VHT1SS_MCS3: + _device.phy_set_bb_reg(rTxAGC_A_Nss1Index3_Nss1Index0_JAguar, bMaskByte3, + powerIndex); + break; + + case MGN_VHT1SS_MCS4: + _device.phy_set_bb_reg(rTxAGC_A_Nss1Index7_Nss1Index4_JAguar, bMaskByte0, + powerIndex); + break; + case MGN_VHT1SS_MCS5: + _device.phy_set_bb_reg(rTxAGC_A_Nss1Index7_Nss1Index4_JAguar, bMaskByte1, + powerIndex); + break; + case MGN_VHT1SS_MCS6: + _device.phy_set_bb_reg(rTxAGC_A_Nss1Index7_Nss1Index4_JAguar, bMaskByte2, + powerIndex); + break; + case MGN_VHT1SS_MCS7: + _device.phy_set_bb_reg(rTxAGC_A_Nss1Index7_Nss1Index4_JAguar, bMaskByte3, + powerIndex); + break; + + case MGN_VHT1SS_MCS8: + _device.phy_set_bb_reg(rTxAGC_A_Nss2Index1_Nss1Index8_JAguar, bMaskByte0, + powerIndex); + break; + case MGN_VHT1SS_MCS9: + _device.phy_set_bb_reg(rTxAGC_A_Nss2Index1_Nss1Index8_JAguar, bMaskByte1, + powerIndex); + break; + case MGN_VHT2SS_MCS0: + _device.phy_set_bb_reg(rTxAGC_A_Nss2Index1_Nss1Index8_JAguar, bMaskByte2, + powerIndex); + break; + case MGN_VHT2SS_MCS1: + _device.phy_set_bb_reg(rTxAGC_A_Nss2Index1_Nss1Index8_JAguar, bMaskByte3, + powerIndex); + break; + + case MGN_VHT2SS_MCS2: + _device.phy_set_bb_reg(rTxAGC_A_Nss2Index5_Nss2Index2_JAguar, bMaskByte0, + powerIndex); + break; + case MGN_VHT2SS_MCS3: + _device.phy_set_bb_reg(rTxAGC_A_Nss2Index5_Nss2Index2_JAguar, bMaskByte1, + powerIndex); + break; + case MGN_VHT2SS_MCS4: + _device.phy_set_bb_reg(rTxAGC_A_Nss2Index5_Nss2Index2_JAguar, bMaskByte2, + powerIndex); + break; + case MGN_VHT2SS_MCS5: + _device.phy_set_bb_reg(rTxAGC_A_Nss2Index5_Nss2Index2_JAguar, bMaskByte3, + powerIndex); + break; + + case MGN_VHT2SS_MCS6: + _device.phy_set_bb_reg(rTxAGC_A_Nss2Index9_Nss2Index6_JAguar, bMaskByte0, + powerIndex); + break; + case MGN_VHT2SS_MCS7: + _device.phy_set_bb_reg(rTxAGC_A_Nss2Index9_Nss2Index6_JAguar, bMaskByte1, + powerIndex); + break; + case MGN_VHT2SS_MCS8: + _device.phy_set_bb_reg(rTxAGC_A_Nss2Index9_Nss2Index6_JAguar, bMaskByte2, + powerIndex); + break; + case MGN_VHT2SS_MCS9: + _device.phy_set_bb_reg(rTxAGC_A_Nss2Index9_Nss2Index6_JAguar, bMaskByte3, + powerIndex); + break; + + default: + _logger->error("Invalid Rate!!\n"); + break; + } + } else if (rfPath == RF_PATH_B) { + switch (rate) { + case MGN_1M: + _device.phy_set_bb_reg(rTxAGC_B_CCK11_CCK1_JAguar, bMaskByte0, + powerIndex); + break; + case MGN_2M: + _device.phy_set_bb_reg(rTxAGC_B_CCK11_CCK1_JAguar, bMaskByte1, + powerIndex); + break; + case MGN_5_5M: + _device.phy_set_bb_reg(rTxAGC_B_CCK11_CCK1_JAguar, bMaskByte2, + powerIndex); + break; + case MGN_11M: + _device.phy_set_bb_reg(rTxAGC_B_CCK11_CCK1_JAguar, bMaskByte3, + powerIndex); + break; + + case MGN_6M: + _device.phy_set_bb_reg(rTxAGC_B_Ofdm18_Ofdm6_JAguar, bMaskByte0, + powerIndex); + break; + case MGN_9M: + _device.phy_set_bb_reg(rTxAGC_B_Ofdm18_Ofdm6_JAguar, bMaskByte1, + powerIndex); + break; + case MGN_12M: + _device.phy_set_bb_reg(rTxAGC_B_Ofdm18_Ofdm6_JAguar, bMaskByte2, + powerIndex); + break; + case MGN_18M: + _device.phy_set_bb_reg(rTxAGC_B_Ofdm18_Ofdm6_JAguar, bMaskByte3, + powerIndex); + break; + + case MGN_24M: + _device.phy_set_bb_reg(rTxAGC_B_Ofdm54_Ofdm24_JAguar, bMaskByte0, + powerIndex); + break; + case MGN_36M: + _device.phy_set_bb_reg(rTxAGC_B_Ofdm54_Ofdm24_JAguar, bMaskByte1, + powerIndex); + break; + case MGN_48M: + _device.phy_set_bb_reg(rTxAGC_B_Ofdm54_Ofdm24_JAguar, bMaskByte2, + powerIndex); + break; + case MGN_54M: + _device.phy_set_bb_reg(rTxAGC_B_Ofdm54_Ofdm24_JAguar, bMaskByte3, + powerIndex); + break; + + case MGN_MCS0: + _device.phy_set_bb_reg(rTxAGC_B_MCS3_MCS0_JAguar, bMaskByte0, powerIndex); + break; + case MGN_MCS1: + _device.phy_set_bb_reg(rTxAGC_B_MCS3_MCS0_JAguar, bMaskByte1, powerIndex); + break; + case MGN_MCS2: + _device.phy_set_bb_reg(rTxAGC_B_MCS3_MCS0_JAguar, bMaskByte2, powerIndex); + break; + case MGN_MCS3: + _device.phy_set_bb_reg(rTxAGC_B_MCS3_MCS0_JAguar, bMaskByte3, powerIndex); + break; + + case MGN_MCS4: + _device.phy_set_bb_reg(rTxAGC_B_MCS7_MCS4_JAguar, bMaskByte0, powerIndex); + break; + case MGN_MCS5: + _device.phy_set_bb_reg(rTxAGC_B_MCS7_MCS4_JAguar, bMaskByte1, powerIndex); + break; + case MGN_MCS6: + _device.phy_set_bb_reg(rTxAGC_B_MCS7_MCS4_JAguar, bMaskByte2, powerIndex); + break; + case MGN_MCS7: + _device.phy_set_bb_reg(rTxAGC_B_MCS7_MCS4_JAguar, bMaskByte3, powerIndex); + break; + + case MGN_MCS8: + _device.phy_set_bb_reg(rTxAGC_B_MCS11_MCS8_JAguar, bMaskByte0, + powerIndex); + break; + case MGN_MCS9: + _device.phy_set_bb_reg(rTxAGC_B_MCS11_MCS8_JAguar, bMaskByte1, + powerIndex); + break; + case MGN_MCS10: + _device.phy_set_bb_reg(rTxAGC_B_MCS11_MCS8_JAguar, bMaskByte2, + powerIndex); + break; + case MGN_MCS11: + _device.phy_set_bb_reg(rTxAGC_B_MCS11_MCS8_JAguar, bMaskByte3, + powerIndex); + break; + + case MGN_MCS12: + _device.phy_set_bb_reg(rTxAGC_B_MCS15_MCS12_JAguar, bMaskByte0, + powerIndex); + break; + case MGN_MCS13: + _device.phy_set_bb_reg(rTxAGC_B_MCS15_MCS12_JAguar, bMaskByte1, + powerIndex); + break; + case MGN_MCS14: + _device.phy_set_bb_reg(rTxAGC_B_MCS15_MCS12_JAguar, bMaskByte2, + powerIndex); + break; + case MGN_MCS15: + _device.phy_set_bb_reg(rTxAGC_B_MCS15_MCS12_JAguar, bMaskByte3, + powerIndex); + break; + + case MGN_VHT1SS_MCS0: + _device.phy_set_bb_reg(rTxAGC_B_Nss1Index3_Nss1Index0_JAguar, bMaskByte0, + powerIndex); + break; + case MGN_VHT1SS_MCS1: + _device.phy_set_bb_reg(rTxAGC_B_Nss1Index3_Nss1Index0_JAguar, bMaskByte1, + powerIndex); + break; + case MGN_VHT1SS_MCS2: + _device.phy_set_bb_reg(rTxAGC_B_Nss1Index3_Nss1Index0_JAguar, bMaskByte2, + powerIndex); + break; + case MGN_VHT1SS_MCS3: + _device.phy_set_bb_reg(rTxAGC_B_Nss1Index3_Nss1Index0_JAguar, bMaskByte3, + powerIndex); + break; + + case MGN_VHT1SS_MCS4: + _device.phy_set_bb_reg(rTxAGC_B_Nss1Index7_Nss1Index4_JAguar, bMaskByte0, + powerIndex); + break; + case MGN_VHT1SS_MCS5: + _device.phy_set_bb_reg(rTxAGC_B_Nss1Index7_Nss1Index4_JAguar, bMaskByte1, + powerIndex); + break; + case MGN_VHT1SS_MCS6: + _device.phy_set_bb_reg(rTxAGC_B_Nss1Index7_Nss1Index4_JAguar, bMaskByte2, + powerIndex); + break; + case MGN_VHT1SS_MCS7: + _device.phy_set_bb_reg(rTxAGC_B_Nss1Index7_Nss1Index4_JAguar, bMaskByte3, + powerIndex); + break; + + case MGN_VHT1SS_MCS8: + _device.phy_set_bb_reg(rTxAGC_B_Nss2Index1_Nss1Index8_JAguar, bMaskByte0, + powerIndex); + break; + case MGN_VHT1SS_MCS9: + _device.phy_set_bb_reg(rTxAGC_B_Nss2Index1_Nss1Index8_JAguar, bMaskByte1, + powerIndex); + break; + case MGN_VHT2SS_MCS0: + _device.phy_set_bb_reg(rTxAGC_B_Nss2Index1_Nss1Index8_JAguar, bMaskByte2, + powerIndex); + break; + case MGN_VHT2SS_MCS1: + _device.phy_set_bb_reg(rTxAGC_B_Nss2Index1_Nss1Index8_JAguar, bMaskByte3, + powerIndex); + break; + + case MGN_VHT2SS_MCS2: + _device.phy_set_bb_reg(rTxAGC_B_Nss2Index5_Nss2Index2_JAguar, bMaskByte0, + powerIndex); + break; + case MGN_VHT2SS_MCS3: + _device.phy_set_bb_reg(rTxAGC_B_Nss2Index5_Nss2Index2_JAguar, bMaskByte1, + powerIndex); + break; + case MGN_VHT2SS_MCS4: + _device.phy_set_bb_reg(rTxAGC_B_Nss2Index5_Nss2Index2_JAguar, bMaskByte2, + powerIndex); + break; + case MGN_VHT2SS_MCS5: + _device.phy_set_bb_reg(rTxAGC_B_Nss2Index5_Nss2Index2_JAguar, bMaskByte3, + powerIndex); + break; + + case MGN_VHT2SS_MCS6: + _device.phy_set_bb_reg(rTxAGC_B_Nss2Index9_Nss2Index6_JAguar, bMaskByte0, + powerIndex); + break; + case MGN_VHT2SS_MCS7: + _device.phy_set_bb_reg(rTxAGC_B_Nss2Index9_Nss2Index6_JAguar, bMaskByte1, + powerIndex); + break; + case MGN_VHT2SS_MCS8: + _device.phy_set_bb_reg(rTxAGC_B_Nss2Index9_Nss2Index6_JAguar, bMaskByte2, + powerIndex); + break; + case MGN_VHT2SS_MCS9: + _device.phy_set_bb_reg(rTxAGC_B_Nss2Index9_Nss2Index6_JAguar, bMaskByte3, + powerIndex); + break; + + default: + _logger->error("Invalid Rate!!\n"); + break; + } + } else + _logger->error("Invalid RFPath!!\n"); #if 0 if (PowerIndexDescription.SetTable.TryGetValue(rfPath, out var rfTable)) { @@ -1193,11 +1607,11 @@ void RadioManagementModule::PHY_TxPowerTrainingByPath_8812(RfPath rfPath) { uint16_t writeOffset; uint32_t powerLevel; + powerLevel = power; + if (rfPath == RfPath::RF_PATH_A) { - powerLevel = phy_get_tx_power_index(); writeOffset = rA_TxPwrTraing_Jaguar; } else { - powerLevel = phy_get_tx_power_index(); writeOffset = rB_TxPwrTraing_Jaguar; } diff --git a/src/RadioManagementModule.h b/src/RadioManagementModule.h index 0ad6c7b..68a2ea4 100644 --- a/src/RadioManagementModule.h +++ b/src/RadioManagementModule.h @@ -2,6 +2,7 @@ #define RADIOMANAGEMENTMODULE_H #include +#include #include "EepromManager.h" #include "RfPath.h" @@ -148,6 +149,7 @@ class RadioManagementModule { uint8_t _cur40MhzPrimeSc; uint8_t _cur80MhzPrimeSc; uint8_t _currentCenterFrequencyIndex; + uint8_t power = 16; public: RadioManagementModule(RtlUsbAdapter device, @@ -163,6 +165,7 @@ class RadioManagementModule { void rtw_hal_set_chnl_bw(uint8_t channel, ChannelWidth_t Bandwidth, uint8_t Offset40, uint8_t Offset80); void PHY_SwitchWirelessBand8812(BandType Band); + void SetTxPower(uint8_t p); private: void rtw_hal_set_msr(uint8_t net_type); diff --git a/src/Radiotap.c b/src/Radiotap.c new file mode 100644 index 0000000..d042f0c --- /dev/null +++ b/src/Radiotap.c @@ -0,0 +1,911 @@ +/* + * Radiotap parser + * + * Copyright 2007 Andy Green + * Copyright 2009 Johannes Berg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See COPYING for more details. + */ + +#include "ieee80211_radiotap.h" +#include + +enum MGN_RATE { + MGN_1M = 0x02, + MGN_2M = 0x04, + MGN_5_5M = 0x0B, + MGN_6M = 0x0C, + MGN_9M = 0x12, + MGN_11M = 0x16, + MGN_12M = 0x18, + MGN_18M = 0x24, + MGN_24M = 0x30, + MGN_36M = 0x48, + MGN_48M = 0x60, + MGN_54M = 0x6C, + MGN_MCS32 = 0x7F, + MGN_MCS0, + MGN_MCS1, + MGN_MCS2, + MGN_MCS3, + MGN_MCS4, + MGN_MCS5, + MGN_MCS6, + MGN_MCS7, + MGN_MCS8, + MGN_MCS9, + MGN_MCS10, + MGN_MCS11, + MGN_MCS12, + MGN_MCS13, + MGN_MCS14, + MGN_MCS15, + MGN_MCS16, + MGN_MCS17, + MGN_MCS18, + MGN_MCS19, + MGN_MCS20, + MGN_MCS21, + MGN_MCS22, + MGN_MCS23, + MGN_MCS24, + MGN_MCS25, + MGN_MCS26, + MGN_MCS27, + MGN_MCS28, + MGN_MCS29, + MGN_MCS30, + MGN_MCS31, + MGN_VHT1SS_MCS0, + MGN_VHT1SS_MCS1, + MGN_VHT1SS_MCS2, + MGN_VHT1SS_MCS3, + MGN_VHT1SS_MCS4, + MGN_VHT1SS_MCS5, + MGN_VHT1SS_MCS6, + MGN_VHT1SS_MCS7, + MGN_VHT1SS_MCS8, + MGN_VHT1SS_MCS9, + MGN_VHT2SS_MCS0, + MGN_VHT2SS_MCS1, + MGN_VHT2SS_MCS2, + MGN_VHT2SS_MCS3, + MGN_VHT2SS_MCS4, + MGN_VHT2SS_MCS5, + MGN_VHT2SS_MCS6, + MGN_VHT2SS_MCS7, + MGN_VHT2SS_MCS8, + MGN_VHT2SS_MCS9, + MGN_VHT3SS_MCS0, + MGN_VHT3SS_MCS1, + MGN_VHT3SS_MCS2, + MGN_VHT3SS_MCS3, + MGN_VHT3SS_MCS4, + MGN_VHT3SS_MCS5, + MGN_VHT3SS_MCS6, + MGN_VHT3SS_MCS7, + MGN_VHT3SS_MCS8, + MGN_VHT3SS_MCS9, + MGN_VHT4SS_MCS0, + MGN_VHT4SS_MCS1, + MGN_VHT4SS_MCS2, + MGN_VHT4SS_MCS3, + MGN_VHT4SS_MCS4, + MGN_VHT4SS_MCS5, + MGN_VHT4SS_MCS6, + MGN_VHT4SS_MCS7, + MGN_VHT4SS_MCS8, + MGN_VHT4SS_MCS9, + MGN_UNKNOWN +}; +/* function prototypes and related defs are in include/net/cfg80211.h */ + +static const struct radiotap_align_size rtap_namespace_sizes[] = { + [IEEE80211_RADIOTAP_TSFT] = + { + .align = 8, + .size = 8, + }, + [IEEE80211_RADIOTAP_FLAGS] = + { + .align = 1, + .size = 1, + }, + [IEEE80211_RADIOTAP_RATE] = + { + .align = 1, + .size = 1, + }, + [IEEE80211_RADIOTAP_CHANNEL] = + { + .align = 2, + .size = 4, + }, + [IEEE80211_RADIOTAP_FHSS] = + { + .align = 2, + .size = 2, + }, + [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = + { + .align = 1, + .size = 1, + }, + [IEEE80211_RADIOTAP_DBM_ANTNOISE] = + { + .align = 1, + .size = 1, + }, + [IEEE80211_RADIOTAP_LOCK_QUALITY] = + { + .align = 2, + .size = 2, + }, + [IEEE80211_RADIOTAP_TX_ATTENUATION] = + { + .align = 2, + .size = 2, + }, + [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = + { + .align = 2, + .size = 2, + }, + [IEEE80211_RADIOTAP_DBM_TX_POWER] = + { + .align = 1, + .size = 1, + }, + [IEEE80211_RADIOTAP_ANTENNA] = + { + .align = 1, + .size = 1, + }, + [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = + { + .align = 1, + .size = 1, + }, + [IEEE80211_RADIOTAP_DB_ANTNOISE] = + { + .align = 1, + .size = 1, + }, + [IEEE80211_RADIOTAP_RX_FLAGS] = + { + .align = 2, + .size = 2, + }, + [IEEE80211_RADIOTAP_TX_FLAGS] = + { + .align = 2, + .size = 2, + }, + [IEEE80211_RADIOTAP_RTS_RETRIES] = + { + .align = 1, + .size = 1, + }, + [IEEE80211_RADIOTAP_DATA_RETRIES] = + { + .align = 1, + .size = 1, + }, + [IEEE80211_RADIOTAP_MCS] = + { + .align = 1, + .size = 3, + }, + [IEEE80211_RADIOTAP_AMPDU_STATUS] = + { + .align = 4, + .size = 8, + }, + [IEEE80211_RADIOTAP_VHT] = + { + .align = 2, + .size = 12, + }, + [IEEE80211_RADIOTAP_TIMESTAMP] = + { + .align = 8, + .size = 12, + }, + /* + * add more here as they are defined in radiotap.h + */ +}; + +static const struct ieee80211_radiotap_namespace radiotap_ns = { + .n_bits = ARRAY_SIZE(rtap_namespace_sizes), + .align_size = rtap_namespace_sizes, +}; + +/** + * ieee80211_radiotap_iterator_init - radiotap parser iterator initialization + * @iterator: radiotap_iterator to initialize + * @radiotap_header: radiotap header to parse + * @max_length: total length we can parse into (eg, whole packet length) + * + * Returns: 0 or a negative error code if there is a problem. + * + * This function initializes an opaque iterator struct which can then + * be passed to ieee80211_radiotap_iterator_next() to visit every radiotap + * argument which is present in the header. It knows about extended + * present headers and handles them. + * + * How to use: + * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator + * struct ieee80211_radiotap_iterator (no need to init the struct beforehand) + * checking for a good 0 return code. Then loop calling + * __ieee80211_radiotap_iterator_next()... it returns either 0, + * -ENOENT if there are no more args to parse, or -EINVAL if there is a problem. + * The iterator's @this_arg member points to the start of the argument + * associated with the current argument index that is present, which can be + * found in the iterator's @this_arg_index member. This arg index corresponds + * to the IEEE80211_RADIOTAP_... defines. + * + * Radiotap header length: + * You can find the CPU-endian total radiotap header length in + * iterator->max_length after executing ieee80211_radiotap_iterator_init() + * successfully. + * + * Alignment Gotcha: + * You must take care when dereferencing iterator.this_arg + * for multibyte types... the pointer is not aligned. Use + * get_unaligned((type *)iterator.this_arg) to dereference + * iterator.this_arg for type "type" safely on all arches. + * + * Example code: + * See Documentation/networking/radiotap-headers.txt + */ + +int ieee80211_radiotap_iterator_init( + struct ieee80211_radiotap_iterator *iterator, + struct ieee80211_radiotap_header *radiotap_header, int max_length, + const struct ieee80211_radiotap_vendor_namespaces *vns) { + /* check the radiotap header can actually be present */ + if (max_length < (int)sizeof(struct ieee80211_radiotap_header)) + return -EINVAL; + + /* Linux only supports version 0 radiotap format */ + if (radiotap_header->it_version) + return -EINVAL; + + /* sanity check for allowed length and radiotap length field */ + if (max_length < get_unaligned_le16(&radiotap_header->it_len)) + return -EINVAL; + + iterator->_rtheader = radiotap_header; + iterator->_max_length = get_unaligned_le16(&radiotap_header->it_len); + iterator->_arg_index = 0; + iterator->_bitmap_shifter = get_unaligned_le32(&radiotap_header->it_present); + iterator->_arg = (uint8_t *)radiotap_header + sizeof(*radiotap_header); + iterator->_reset_on_ext = 0; + iterator->_next_bitmap = + &radiotap_header + ->it_present; // NOLINT(clang-diagnostic-address-of-packed-member) + iterator->_next_bitmap++; + iterator->_vns = vns; + iterator->current_namespace = &radiotap_ns; + iterator->is_radiotap_ns = 1; + + /* find payload start allowing for extended bitmap(s) */ + + if (iterator->_bitmap_shifter & (1u << IEEE80211_RADIOTAP_EXT)) { + if ((unsigned long)iterator->_arg - (unsigned long)iterator->_rtheader + + sizeof(uint32_t) > + (unsigned long)iterator->_max_length) + return -EINVAL; + while (get_unaligned_le32(iterator->_arg) & + (1u << IEEE80211_RADIOTAP_EXT)) { + iterator->_arg += sizeof(uint32_t); + + /* + * check for insanity where the present bitmaps + * keep claiming to extend up to or even beyond the + * stated radiotap header length + */ + + if ((unsigned long)iterator->_arg - (unsigned long)iterator->_rtheader + + sizeof(uint32_t) > + (unsigned long)iterator->_max_length) + return -EINVAL; + } + + iterator->_arg += sizeof(uint32_t); + + /* + * no need to check again for blowing past stated radiotap + * header length, because ieee80211_radiotap_iterator_next + * checks it before it is dereferenced + */ + } + + iterator->this_arg = iterator->_arg; + + /* we are all initialized happily */ + + return 0; +} + +static void find_ns(struct ieee80211_radiotap_iterator *iterator, uint32_t oui, + uint8_t subns) { + int i; + + iterator->current_namespace = NULL; + + if (!iterator->_vns) + return; + + for (i = 0; i < iterator->_vns->n_ns; i++) { + if (iterator->_vns->ns[i].oui != oui) + continue; + if (iterator->_vns->ns[i].subns != subns) + continue; + + iterator->current_namespace = &iterator->_vns->ns[i]; + break; + } +} + +/** + * ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg + * @iterator: radiotap_iterator to move to next arg (if any) + * + * Returns: 0 if there is an argument to handle, + * -ENOENT if there are no more args or -EINVAL + * if there is something else wrong. + * + * This function provides the next radiotap arg index (IEEE80211_RADIOTAP_*) + * in @this_arg_index and sets @this_arg to point to the + * payload for the field. It takes care of alignment handling and extended + * present fields. @this_arg can be changed by the caller (eg, + * incremented to move inside a compound argument like + * IEEE80211_RADIOTAP_CHANNEL). The args pointed to are in + * little-endian format whatever the endianess of your CPU. + * + * Alignment Gotcha: + * You must take care when dereferencing iterator.this_arg + * for multibyte types... the pointer is not aligned. Use + * get_unaligned((type *)iterator.this_arg) to dereference + * iterator.this_arg for type "type" safely on all arches. + */ + +int ieee80211_radiotap_iterator_next( + struct ieee80211_radiotap_iterator *iterator) { + while (1) { + int hit = 0; + int pad, align, size, subns; + uint32_t oui; + + /* if no more EXT bits, that's it */ + if ((iterator->_arg_index % 32) == IEEE80211_RADIOTAP_EXT && + !(iterator->_bitmap_shifter & 1)) + return -ENOENT; + + if (!(iterator->_bitmap_shifter & 1)) + goto next_entry; /* arg not present */ + + /* get alignment/size of data */ + switch (iterator->_arg_index % 32) { + case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE: + case IEEE80211_RADIOTAP_EXT: + align = 1; + size = 0; + break; + case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: + align = 2; + size = 6; + break; + default: + if (!iterator->current_namespace || + iterator->_arg_index >= iterator->current_namespace->n_bits) { + if (iterator->current_namespace == &radiotap_ns) + return -ENOENT; + align = 0; + } else { + align = + iterator->current_namespace->align_size[iterator->_arg_index].align; + size = + iterator->current_namespace->align_size[iterator->_arg_index].size; + } + if (!align) { + /* skip all subsequent data */ + iterator->_arg = iterator->_next_ns_data; + /* give up on this namespace */ + iterator->current_namespace = NULL; + goto next_entry; + } + break; + } + + /* + * arg is present, account for alignment padding + * + * Note that these alignments are relative to the start + * of the radiotap header. There is no guarantee + * that the radiotap header itself is aligned on any + * kind of boundary. + * + * The above is why get_unaligned() is used to dereference + * multibyte elements from the radiotap area. + */ + + pad = ((unsigned long)iterator->_arg - (unsigned long)iterator->_rtheader) & + (align - 1); + + if (pad) + iterator->_arg += align - pad; + + if (iterator->_arg_index % 32 == IEEE80211_RADIOTAP_VENDOR_NAMESPACE) { + int vnslen; + + if ((unsigned long)iterator->_arg + size - + (unsigned long)iterator->_rtheader > + (unsigned long)iterator->_max_length) + return -EINVAL; + + oui = (*iterator->_arg << 16) | (*(iterator->_arg + 1) << 8) | + *(iterator->_arg + 2); + subns = *(iterator->_arg + 3); + + find_ns(iterator, oui, subns); + + vnslen = get_unaligned_le16(iterator->_arg + 4); + iterator->_next_ns_data = iterator->_arg + size + vnslen; + if (!iterator->current_namespace) + size += vnslen; + } + + /* + * this is what we will return to user, but we need to + * move on first so next call has something fresh to test + */ + iterator->this_arg_index = iterator->_arg_index; + iterator->this_arg = iterator->_arg; + iterator->this_arg_size = size; + + /* internally move on the size of this arg */ + iterator->_arg += size; + + /* + * check for insanity where we are given a bitmap that + * claims to have more arg content than the length of the + * radiotap section. We will normally end up equalling this + * max_length on the last arg, never exceeding it. + */ + + if ((unsigned long)iterator->_arg - (unsigned long)iterator->_rtheader > + (unsigned long)iterator->_max_length) + return -EINVAL; + + /* these special ones are valid in each bitmap word */ + switch (iterator->_arg_index % 32) { + case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: + iterator->_reset_on_ext = 1; + + iterator->is_radiotap_ns = 0; + /* + * If parser didn't register this vendor + * namespace with us, allow it to show it + * as 'raw. Do do that, set argument index + * to vendor namespace. + */ + iterator->this_arg_index = IEEE80211_RADIOTAP_VENDOR_NAMESPACE; + if (!iterator->current_namespace) + hit = 1; + goto next_entry; + case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE: + iterator->_reset_on_ext = 1; + iterator->current_namespace = &radiotap_ns; + iterator->is_radiotap_ns = 1; + goto next_entry; + case IEEE80211_RADIOTAP_EXT: + /* + * bit 31 was set, there is more + * -- move to next u32 bitmap + */ + iterator->_bitmap_shifter = get_unaligned_le32(iterator->_next_bitmap); + iterator->_next_bitmap++; + if (iterator->_reset_on_ext) + iterator->_arg_index = 0; + else + iterator->_arg_index++; + iterator->_reset_on_ext = 0; + break; + default: + /* we've got a hit! */ + hit = 1; + next_entry: + iterator->_bitmap_shifter >>= 1; + iterator->_arg_index++; + } + + /* if we found a valid arg earlier, return it now */ + if (hit) + return 0; + } +} + +u16 GetSequence(const u8 *packet) { + // 假设Sequence Control位于从第22个字节开始的位置,占两个字节 + u16 seqCtrl = (u16)(packet[22]) | (u16)(packet[23] << 8); + // 序列号为seqCtrl的高12位(从0号位开始计数) + u16 seqNum = (seqCtrl >> 4) & 0x0FFF; + return seqNum; +} +u8 MRateToHwRate(u8 rate) { + u8 ret = DESC_RATE1M; + + switch (rate) { + case MGN_1M: + ret = DESC_RATE1M; + break; + case MGN_2M: + ret = DESC_RATE2M; + break; + case MGN_5_5M: + ret = DESC_RATE5_5M; + break; + case MGN_11M: + ret = DESC_RATE11M; + break; + case MGN_6M: + ret = DESC_RATE6M; + break; + case MGN_9M: + ret = DESC_RATE9M; + break; + case MGN_12M: + ret = DESC_RATE12M; + break; + case MGN_18M: + ret = DESC_RATE18M; + break; + case MGN_24M: + ret = DESC_RATE24M; + break; + case MGN_36M: + ret = DESC_RATE36M; + break; + case MGN_48M: + ret = DESC_RATE48M; + break; + case MGN_54M: + ret = DESC_RATE54M; + break; + + case MGN_MCS0: + ret = DESC_RATEMCS0; + break; + case MGN_MCS1: + ret = DESC_RATEMCS1; + break; + case MGN_MCS2: + ret = DESC_RATEMCS2; + break; + case MGN_MCS3: + ret = DESC_RATEMCS3; + break; + case MGN_MCS4: + ret = DESC_RATEMCS4; + break; + case MGN_MCS5: + ret = DESC_RATEMCS5; + break; + case MGN_MCS6: + ret = DESC_RATEMCS6; + break; + case MGN_MCS7: + ret = DESC_RATEMCS7; + break; + case MGN_MCS8: + ret = DESC_RATEMCS8; + break; + case MGN_MCS9: + ret = DESC_RATEMCS9; + break; + case MGN_MCS10: + ret = DESC_RATEMCS10; + break; + case MGN_MCS11: + ret = DESC_RATEMCS11; + break; + case MGN_MCS12: + ret = DESC_RATEMCS12; + break; + case MGN_MCS13: + ret = DESC_RATEMCS13; + break; + case MGN_MCS14: + ret = DESC_RATEMCS14; + break; + case MGN_MCS15: + ret = DESC_RATEMCS15; + break; + case MGN_MCS16: + ret = DESC_RATEMCS16; + break; + case MGN_MCS17: + ret = DESC_RATEMCS17; + break; + case MGN_MCS18: + ret = DESC_RATEMCS18; + break; + case MGN_MCS19: + ret = DESC_RATEMCS19; + break; + case MGN_MCS20: + ret = DESC_RATEMCS20; + break; + case MGN_MCS21: + ret = DESC_RATEMCS21; + break; + case MGN_MCS22: + ret = DESC_RATEMCS22; + break; + case MGN_MCS23: + ret = DESC_RATEMCS23; + break; + case MGN_MCS24: + ret = DESC_RATEMCS24; + break; + case MGN_MCS25: + ret = DESC_RATEMCS25; + break; + case MGN_MCS26: + ret = DESC_RATEMCS26; + break; + case MGN_MCS27: + ret = DESC_RATEMCS27; + break; + case MGN_MCS28: + ret = DESC_RATEMCS28; + break; + case MGN_MCS29: + ret = DESC_RATEMCS29; + break; + case MGN_MCS30: + ret = DESC_RATEMCS30; + break; + case MGN_MCS31: + ret = DESC_RATEMCS31; + break; + + case MGN_VHT1SS_MCS0: + ret = DESC_RATEVHTSS1MCS0; + break; + case MGN_VHT1SS_MCS1: + ret = DESC_RATEVHTSS1MCS1; + break; + case MGN_VHT1SS_MCS2: + ret = DESC_RATEVHTSS1MCS2; + break; + case MGN_VHT1SS_MCS3: + ret = DESC_RATEVHTSS1MCS3; + break; + case MGN_VHT1SS_MCS4: + ret = DESC_RATEVHTSS1MCS4; + break; + case MGN_VHT1SS_MCS5: + ret = DESC_RATEVHTSS1MCS5; + break; + case MGN_VHT1SS_MCS6: + ret = DESC_RATEVHTSS1MCS6; + break; + case MGN_VHT1SS_MCS7: + ret = DESC_RATEVHTSS1MCS7; + break; + case MGN_VHT1SS_MCS8: + ret = DESC_RATEVHTSS1MCS8; + break; + case MGN_VHT1SS_MCS9: + ret = DESC_RATEVHTSS1MCS9; + break; + case MGN_VHT2SS_MCS0: + ret = DESC_RATEVHTSS2MCS0; + break; + case MGN_VHT2SS_MCS1: + ret = DESC_RATEVHTSS2MCS1; + break; + case MGN_VHT2SS_MCS2: + ret = DESC_RATEVHTSS2MCS2; + break; + case MGN_VHT2SS_MCS3: + ret = DESC_RATEVHTSS2MCS3; + break; + case MGN_VHT2SS_MCS4: + ret = DESC_RATEVHTSS2MCS4; + break; + case MGN_VHT2SS_MCS5: + ret = DESC_RATEVHTSS2MCS5; + break; + case MGN_VHT2SS_MCS6: + ret = DESC_RATEVHTSS2MCS6; + break; + case MGN_VHT2SS_MCS7: + ret = DESC_RATEVHTSS2MCS7; + break; + case MGN_VHT2SS_MCS8: + ret = DESC_RATEVHTSS2MCS8; + break; + case MGN_VHT2SS_MCS9: + ret = DESC_RATEVHTSS2MCS9; + break; + case MGN_VHT3SS_MCS0: + ret = DESC_RATEVHTSS3MCS0; + break; + case MGN_VHT3SS_MCS1: + ret = DESC_RATEVHTSS3MCS1; + break; + case MGN_VHT3SS_MCS2: + ret = DESC_RATEVHTSS3MCS2; + break; + case MGN_VHT3SS_MCS3: + ret = DESC_RATEVHTSS3MCS3; + break; + case MGN_VHT3SS_MCS4: + ret = DESC_RATEVHTSS3MCS4; + break; + case MGN_VHT3SS_MCS5: + ret = DESC_RATEVHTSS3MCS5; + break; + case MGN_VHT3SS_MCS6: + ret = DESC_RATEVHTSS3MCS6; + break; + case MGN_VHT3SS_MCS7: + ret = DESC_RATEVHTSS3MCS7; + break; + case MGN_VHT3SS_MCS8: + ret = DESC_RATEVHTSS3MCS8; + break; + case MGN_VHT3SS_MCS9: + ret = DESC_RATEVHTSS3MCS9; + break; + case MGN_VHT4SS_MCS0: + ret = DESC_RATEVHTSS4MCS0; + break; + case MGN_VHT4SS_MCS1: + ret = DESC_RATEVHTSS4MCS1; + break; + case MGN_VHT4SS_MCS2: + ret = DESC_RATEVHTSS4MCS2; + break; + case MGN_VHT4SS_MCS3: + ret = DESC_RATEVHTSS4MCS3; + break; + case MGN_VHT4SS_MCS4: + ret = DESC_RATEVHTSS4MCS4; + break; + case MGN_VHT4SS_MCS5: + ret = DESC_RATEVHTSS4MCS5; + break; + case MGN_VHT4SS_MCS6: + ret = DESC_RATEVHTSS4MCS6; + break; + case MGN_VHT4SS_MCS7: + ret = DESC_RATEVHTSS4MCS7; + break; + case MGN_VHT4SS_MCS8: + ret = DESC_RATEVHTSS4MCS8; + break; + case MGN_VHT4SS_MCS9: + ret = DESC_RATEVHTSS4MCS9; + break; + default: + break; + } + + return ret; +} + +int parse_radiotap() { + int ret = 0; + int rtap_len; + int qos_len = 0; + int dot11_hdr_len = 24; + int snap_len = 6; + unsigned char *pdata; + u16 frame_ctl; + unsigned char src_mac_addr[6]; + unsigned char dst_mac_addr[6]; + u8 fixed_rate = MGN_1M, sgi = 0, bwidth = 0, ldpc = 0, stbc = 0; + u16 txflags = 0; + + uint8_t pkt[] = { + 0x00, 0x00, 0x0d, 0x00, 0x00, 0x80, 0x08, + 0x00, 0x08, 0x00, 0x37, 0x00, 0x01, + }; + struct ieee80211_radiotap_header *rtap_hdr; + rtap_hdr = (struct ieee80211_radiotap_header *)pkt; + struct ieee80211_radiotap_iterator iterator; + ret = ieee80211_radiotap_iterator_init(&iterator, pkt, 0x0d, NULL); + while (!ret) { + ret = ieee80211_radiotap_iterator_next(&iterator); + + if (ret) + continue; + + /* see if this argument is something we can use */ + switch (iterator.this_arg_index) { + + case IEEE80211_RADIOTAP_RATE: /* u8 */ + fixed_rate = *iterator.this_arg; + break; + + case IEEE80211_RADIOTAP_TX_FLAGS: + txflags = get_unaligned_le16(iterator.this_arg); + break; + + case IEEE80211_RADIOTAP_MCS: { /* u8,u8,u8 */ + u8 mcs_have = iterator.this_arg[0]; +// printf("MCS value:%d %d %d\n", iterator.this_arg[0], iterator.this_arg[1], +// iterator.this_arg[2]); +// printf("mcs parse:%d\n", mcs_have); + if (mcs_have & IEEE80211_RADIOTAP_MCS_HAVE_MCS) { + fixed_rate = iterator.this_arg[2] & 0x7f; + if (fixed_rate > 31) + fixed_rate = 0; + fixed_rate += MGN_MCS0; + } +// printf("mcs_have & 4 = %d,%d \n", (mcs_have & 4), +// (iterator.this_arg[1] & 1)); + if ((mcs_have & 4) && (iterator.this_arg[1] & 4)) + sgi = 1; + if ((mcs_have & 1) && (iterator.this_arg[1] & 1)) + bwidth = 1; + if ((mcs_have & 0x10) && (iterator.this_arg[1] & 0x10)) + ldpc = 1; + if ((mcs_have & 0x20)) + stbc = (iterator.this_arg[1] >> 5) & 3; + } break; + + case IEEE80211_RADIOTAP_VHT: { + /* u16 known, u8 flags, u8 bandwidth, u8 mcs_nss[4], u8 coding, u8 + * group_id, u16 partial_aid */ + u8 known = iterator.this_arg[0]; + u8 flags = iterator.this_arg[2]; + unsigned int mcs, nss; + if ((known & 4) && (flags & 4)) + sgi = 1; + if ((known & 1) && (flags & 1)) + stbc = 1; + if (known & 0x40) { + bwidth = iterator.this_arg[3] & 0x1f; + if (bwidth >= 1 && bwidth <= 3) + bwidth = 1; // 40 MHz + else if (bwidth >= 4 && bwidth <= 10) + bwidth = 2; // 80 MHz + else + bwidth = 0; // 20 MHz + } + if (iterator.this_arg[8] & 1) + ldpc = 1; + mcs = (iterator.this_arg[4] >> 4) & 0x0f; + nss = iterator.this_arg[4] & 0x0f; + if (nss > 0) { + if (nss > 4) + nss = 4; + if (mcs > 9) + mcs = 9; + fixed_rate = MGN_VHT1SS_MCS0 + ((nss - 1) * 10 + mcs); + } + } break; + + default: + break; + } + } + + printf("fixed rate:%d\n", fixed_rate); + printf("sgi =%d,bandwdith=%d,ldpc=%d,stbc=%d\n", sgi, bwidth, ldpc, stbc); + return 1; +} diff --git a/src/Rtl8812aDevice.cpp b/src/Rtl8812aDevice.cpp index faf00e9..9ef9201 100644 --- a/src/Rtl8812aDevice.cpp +++ b/src/Rtl8812aDevice.cpp @@ -1,7 +1,6 @@ #include "Rtl8812aDevice.h" #include "EepromManager.h" #include "RadioManagementModule.h" -#include Rtl8812aDevice::Rtl8812aDevice(RtlUsbAdapter device, Logger_t logger) : _device{device}, @@ -11,7 +10,242 @@ Rtl8812aDevice::Rtl8812aDevice(RtlUsbAdapter device, Logger_t logger) _halModule{device, _eepromManager, _radioManagement, logger}, _logger{logger} {} -void Rtl8812aDevice::Init(Action_RadioPacket packetProcessor, +void Rtl8812aDevice::InitWrite(SelectedChannel channel) { + StartWithMonitorMode(channel); + SetMonitorChannel(channel); + _logger->info("In Monitor Mode"); +} + +bool Rtl8812aDevice::send_packet(const uint8_t *packet, size_t length) { + struct tx_desc *ptxdesc; + bool resp; + uint8_t *usb_frame; + // struct ieee80211_radiotap_header *rtap_hdr; + int real_packet_length, usb_frame_length, radiotap_length; + + bool vht = false; + int ret = 0; + int qos_len = 0; + int dot11_hdr_len = 24; + int snap_len = 6; + unsigned char *pdata; + u16 frame_ctl; + unsigned char src_mac_addr[6]; + unsigned char dst_mac_addr[6]; + u8 fixed_rate = MGN_1M, sgi = 0, + bwidth = 0, + ldpc = 0, stbc = 0; + u16 txflags = 0; + int rate_id = 0; + radiotap_length = int(packet[2]); + real_packet_length = length - radiotap_length; + + if (radiotap_length != 0x0d) + vht = true; + + usb_frame_length = real_packet_length + TXDESC_SIZE; + + _logger->info("radiotap length is {}, 80211 length is {}, usb_frame length " + "should be {}", + radiotap_length, real_packet_length, usb_frame_length); + + struct ieee80211_radiotap_header *rtap_hdr; + rtap_hdr = (struct ieee80211_radiotap_header *)packet; + struct ieee80211_radiotap_iterator iterator; + ret = ieee80211_radiotap_iterator_init(&iterator, rtap_hdr, radiotap_length, + NULL); + while (!ret) { + ret = ieee80211_radiotap_iterator_next(&iterator); + + if (ret) + continue; + + /* see if this argument is something we can use */ + switch (iterator.this_arg_index) { + + case IEEE80211_RADIOTAP_RATE: /* u8 */ + fixed_rate = *iterator.this_arg; + break; + + case IEEE80211_RADIOTAP_TX_FLAGS: + txflags = get_unaligned_le16(iterator.this_arg); + break; + + case IEEE80211_RADIOTAP_MCS: { /* u8,u8,u8 */ + u8 mcs_have = iterator.this_arg[0]; + printf("MCS value:%d %d %d\n", iterator.this_arg[0], iterator.this_arg[1], + iterator.this_arg[2]); + printf("mcs parse:%d\n", mcs_have); + if (mcs_have & IEEE80211_RADIOTAP_MCS_HAVE_MCS) { + fixed_rate = iterator.this_arg[2] & 0x7f; + if (fixed_rate > 31) + fixed_rate = 0; + fixed_rate += MGN_MCS0; + } + printf("mcs_have & 4 = %d,%d \n", (mcs_have & 4), + (iterator.this_arg[1] & 1)); + if ((mcs_have & 4) && (iterator.this_arg[1] & 4)) + sgi = 1; + if ((mcs_have & 1) && (iterator.this_arg[1] & 1)) + bwidth = 1; + if ((mcs_have & 0x10) && (iterator.this_arg[1] & 0x10)) + ldpc = 1; + if ((mcs_have & 0x20)) + stbc = (iterator.this_arg[1] >> 5) & 3; + } break; + + case IEEE80211_RADIOTAP_VHT: { + /* u16 known, u8 flags, u8 bandwidth, u8 mcs_nss[4], u8 coding, u8 + * group_id, u16 partial_aid */ + u8 known = iterator.this_arg[0]; + u8 flags = iterator.this_arg[2]; + unsigned int mcs, nss; + if ((known & 4) && (flags & 4)) + sgi = 1; + if ((known & 1) && (flags & 1)) + stbc = 1; + if (known & 0x40) { + auto bw = iterator.this_arg[3] & 0x1f; + if (bw >= 1 && bw <= 3) + bwidth = 40; // 40 MHz + else if (bw >= 4 && bw <= 10) + bwidth = 80; // 80 MHz + else + bwidth = 20; // 20 MHz + } + + if (iterator.this_arg[8] & 1) + ldpc = 1; + mcs = (iterator.this_arg[4] >> 4) & 0x0f; + nss = iterator.this_arg[4] & 0x0f; + if (nss > 0) { + if (nss > 4) + nss = 4; + if (mcs > 9) + mcs = 9; + fixed_rate = MGN_VHT1SS_MCS0 + ((nss - 1) * 10 + mcs); + } + } break; + + default: + break; + } + } + + printf("fixed rate:%d\n", fixed_rate); + printf("sgi =%d,bandwdith=%d,ldpc=%d,stbc=%d\n", sgi, bwidth, ldpc, stbc); + + usb_frame = new uint8_t[usb_frame_length](); + + ptxdesc = (struct tx_desc *)usb_frame; + + SET_TX_DESC_FIRST_SEG_8812(usb_frame, 1); + SET_TX_DESC_LAST_SEG_8812(usb_frame, 1); + SET_TX_DESC_OWN_8812(usb_frame, 1); + + SET_TX_DESC_PKT_SIZE_8812(usb_frame, + static_cast(real_packet_length)); + + SET_TX_DESC_OFFSET_8812(usb_frame, + static_cast(TXDESC_SIZE + OFFSET_SZ)); + + SET_TX_DESC_MACID_8812(usb_frame, static_cast(0x01)); + + if (!vht) { + rate_id = 7; + } else { + rate_id = 9; + } + + SET_TX_DESC_BMC_8812(usb_frame, 1); + SET_TX_DESC_RATE_ID_8812( + usb_frame, + static_cast(rate_id)); // Originally set to 7, need to reconsider + + SET_TX_DESC_QUEUE_SEL_8812(usb_frame, 0x12); + SET_TX_DESC_HWSEQ_EN_8812( + usb_frame, static_cast(0)); /* Hw do not set sequence number */ + SET_TX_DESC_SEQ_8812( + usb_frame, + GetSequence(packet + + radiotap_length)); /* Copy inject sequence number to TxDesc */ + SET_TX_DESC_RETRY_LIMIT_ENABLE_8812(usb_frame, static_cast(1)); + + SET_TX_DESC_DATA_RETRY_LIMIT_8812(usb_frame, static_cast(0)); + if (sgi) { + _logger->info("short gi enabled,set sgi"); + SET_TX_DESC_DATA_SHORT_8812(usb_frame, 1); + } + SET_TX_DESC_DISABLE_FB_8812(usb_frame, 1); + SET_TX_DESC_USE_RATE_8812(usb_frame, 1); + SET_TX_DESC_TX_RATE_8812(usb_frame, + static_cast(MRateToHwRate( + fixed_rate))); // Originally set to 6, also need + // to reconsider how to convert + + if (ldpc) { + SET_TX_DESC_DATA_LDPC_8812(usb_frame, ldpc); + } + + SET_TX_DESC_DATA_STBC_8812(usb_frame, stbc & 3); + + uint8_t BWSettingOfDesc; + if (_channel.ChannelWidth == CHANNEL_WIDTH_80) { + if (bwidth == 80) + BWSettingOfDesc = 2; + else if (bwidth == 40) + BWSettingOfDesc = 1; + else + BWSettingOfDesc = 0; + } else if (_channel.ChannelWidth == CHANNEL_WIDTH_40) { + if ((bwidth == 40) || (bwidth == 80)) + BWSettingOfDesc = 1; + else + BWSettingOfDesc = 0; + } else + BWSettingOfDesc = 0; + + SET_TX_DESC_DATA_BW_8812(usb_frame, BWSettingOfDesc); + + rtl8812a_cal_txdesc_chksum(usb_frame); + _logger->info("tx desc formed"); +#ifdef DEBUG + for (size_t i = 0; i < usb_frame_length; ++i) { + // Print each byte as a two-digit hexadecimal number + std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') + << static_cast(usb_frame[i]); + + // Print a space between bytes, but not after the last byte + if (i < usb_frame_length - 1) { + std::cout << ","; + } + } + std::cout << std::dec << std::endl; // Reset to decimal formatting + // ----- end of fill tx desc ----- +#endif + uint8_t *addr = usb_frame + TXDESC_SIZE; + memcpy(addr, packet + radiotap_length, real_packet_length); + _logger->info("packet formed"); +#ifdef DEBUG + for (size_t i = 0; i < usb_frame_length; ++i) { + // Print each byte as a two-digit hexadecimal number + std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') + << static_cast(usb_frame[i]); + + // Print a space between bytes, but not after the last byte + if (i < usb_frame_length - 1) { + std::cout << ","; + } + } + std::cout << std::dec << std::endl; // Reset to decimal formatting +#endif + resp = _device.send_packet(usb_frame, usb_frame_length); + delete[] usb_frame; + + return resp; +} + +void Rtl8812aDevice::Init(Action_ParsedRadioPacket packetProcessor, SelectedChannel channel) { _packetProcessor = packetProcessor; @@ -19,11 +253,11 @@ void Rtl8812aDevice::Init(Action_RadioPacket packetProcessor, SetMonitorChannel(channel); _logger->info("Listening air..."); - while(!should_stop) { - auto packets = _device.infinite_read(); - for (auto& p : packets) { - _packetProcessor(p); - } + while (!should_stop) { + auto packets = _device.infinite_read(); + for (auto &p : packets) { + _packetProcessor(p); + } } #if 0 @@ -34,7 +268,7 @@ void Rtl8812aDevice::Init(Action_RadioPacket packetProcessor, void Rtl8812aDevice::SetMonitorChannel(SelectedChannel channel) { _radioManagement->set_channel_bwmode(channel.Channel, channel.ChannelOffset, - channel.ChannelWidth); + channel.ChannelWidth); } void Rtl8812aDevice::StartWithMonitorMode(SelectedChannel selectedChannel) { @@ -45,6 +279,10 @@ void Rtl8812aDevice::StartWithMonitorMode(SelectedChannel selectedChannel) { _radioManagement->SetMonitorMode(); } +void Rtl8812aDevice::SetTxPower(uint8_t power) { + _radioManagement->SetTxPower(power); +} + bool Rtl8812aDevice::NetDevOpen(SelectedChannel selectedChannel) { auto status = _halModule.rtw_hal_init(selectedChannel); if (status == false) { diff --git a/src/Rtl8812aDevice.h b/src/Rtl8812aDevice.h index a8c4525..ce5aa9b 100644 --- a/src/Rtl8812aDevice.h +++ b/src/Rtl8812aDevice.h @@ -2,27 +2,41 @@ #define RTL8812ADEVICE_H #include +#include +#include #include "logger.h" #include "HalModule.h" #include "SelectedChannel.h" #include "EepromManager.h" #include "RadioManagementModule.h" +#include "FrameParser.h" -using Action_RadioPacket = std::function; +extern "C" +{ +#include "ieee80211_radiotap.h" +} + +using Action_ParsedRadioPacket = std::function; class Rtl8812aDevice { std::shared_ptr _eepromManager; std::shared_ptr _radioManagement; + SelectedChannel _channel; RtlUsbAdapter _device; HalModule _halModule; Logger_t _logger; - Action_RadioPacket _packetProcessor = nullptr; + uint8_t debug; + Action_ParsedRadioPacket _packetProcessor = nullptr; public: Rtl8812aDevice(RtlUsbAdapter device, Logger_t logger); - void Init(Action_RadioPacket packetProcessor, SelectedChannel channel); + void Init(Action_ParsedRadioPacket packetProcessor, SelectedChannel channel); void SetMonitorChannel(SelectedChannel channel); + void InitWrite(SelectedChannel channel); + void SetTxPower(uint8_t power); + bool send_packet(const uint8_t* packet, size_t length); + SelectedChannel GetSelectedChannel(); bool should_stop = false; private: diff --git a/src/RtlUsbAdapter.cpp b/src/RtlUsbAdapter.cpp index bc756f3..acbe723 100644 --- a/src/RtlUsbAdapter.cpp +++ b/src/RtlUsbAdapter.cpp @@ -1,11 +1,17 @@ #include "RtlUsbAdapter.h" #include -#include - +#ifdef __ANDROID__ +#include +#else +#include +#endif #include "FrameParser.h" #include "Hal8812PhyReg.h" -#include +#include "logger.h" +#include +#include +#include using namespace std::chrono_literals; @@ -62,10 +68,9 @@ std::vector RtlUsbAdapter::infinite_read() { } std::vector packets; - if (actual_length > 1000) { - FrameParser fp{_logger}; - packets = fp.recvbuf2recvframe(std::span{buffer, (size_t)actual_length}); - } + FrameParser fp{_logger}; + packets = + fp.recvbuf2recvframe(std::span{buffer, (size_t)actual_length}); return packets; } @@ -311,8 +316,47 @@ void RtlUsbAdapter::GetChipOutEP8812() { break; } - _logger->info("OutEpQueueSel({}), OutEpNumber({})", (int)OutEpQueueSel, - (int)OutEpNumber); + _logger->info("OutEpQueueSel({}), OutEpNumber({})", OutEpQueueSel, + OutEpNumber); +} + +void transfer_callback(struct libusb_transfer *transfer) { + Logger *_logger = (Logger *)(transfer->user_data); + if (transfer->status == LIBUSB_TRANSFER_COMPLETED && + transfer->actual_length == transfer->length) { + _logger->info("Packet {} sent successfully, length: {}", _logger, + transfer->length); + } else { + _logger->error("Failed to send packet {}, status: {}, actual length: {}", + _logger, transfer->status, transfer->actual_length); + } + libusb_free_transfer(transfer); +} + +bool RtlUsbAdapter::send_packet(uint8_t *packet, size_t length) { + + libusb_transfer *transfer = libusb_alloc_transfer(0); + if (!transfer) { + _logger->error("Failed to allocate transfer"); + return false; + } + + libusb_fill_bulk_transfer(transfer, _dev_handle, 0x02, packet, length, + transfer_callback, (void *)(_logger.get()), + USB_TIMEOUT); + auto start = std::chrono::high_resolution_clock::now(); + int rc = rc = libusb_submit_transfer(transfer); + auto end = std::chrono::high_resolution_clock::now(); + std::chrono::duration elapsed = end - start; + if (rc == LIBUSB_SUCCESS) { + _logger->info("Packet sent successfully, length: {},used time {}ms", length, + elapsed.count()); + return true; + } else { + _logger->error("Failed to send packet, error code: {}", rc); + libusb_free_transfer(transfer); + return false; + } } void RtlUsbAdapter::phy_set_bb_reg(uint16_t regAddr, uint32_t bitMask, diff --git a/src/RtlUsbAdapter.h b/src/RtlUsbAdapter.h index 36a4c48..a36e2d3 100644 --- a/src/RtlUsbAdapter.h +++ b/src/RtlUsbAdapter.h @@ -4,6 +4,7 @@ #include #include +#include #include "FrameParser.h" #include "drv_types.h" @@ -45,28 +46,22 @@ class RtlUsbAdapter { uint8_t OutEpNumber; uint8_t rxagg_usb_size; uint8_t rxagg_usb_timeout; - + bool send_packet(uint8_t* packet, size_t length); std::vector infinite_read(); uint8_t efuse_OneByteRead(uint16_t addr, uint8_t *data); void phy_set_bb_reg(uint16_t regAddr, uint32_t bitMask, uint32_t data); template T rtw_read(uint16_t reg_num) { T data = 0; - - int res = libusb_control_transfer(_dev_handle, REALTEK_USB_VENQT_READ, 5, reg_num, + if (libusb_control_transfer(_dev_handle, REALTEK_USB_VENQT_READ, 5, reg_num, 0, (uint8_t *)&data, sizeof(T), - USB_TIMEOUT); - if (res == sizeof(T)) { + USB_TIMEOUT) == sizeof(T)) { return data; } - _logger->error("rtw_read({:x}), sizeof(T) = {}", reg_num, sizeof(T)); - - if (res < 0) { - _logger->error("libusb error code: {}", res); - } - + _logger->error("rtw_read({:04x}), sizeof(T) = {}", reg_num, sizeof(T)); throw std::ios_base::failure("rtw_read"); + return 0; } template bool rtw_write(uint16_t reg_num, T value) { diff --git a/src/ieee80211_radiotap.h b/src/ieee80211_radiotap.h new file mode 100644 index 0000000..8ac7eef --- /dev/null +++ b/src/ieee80211_radiotap.h @@ -0,0 +1,550 @@ +#ifndef IEEE80211_RADIOTAP_H +#define IEEE80211_RADIOTAP_H + +#include +#include +#include +#include + + +typedef unsigned int u32; +typedef unsigned short u16; +typedef unsigned char u8; +#ifdef _MSC_VER +typedef uint16_t __le16; +typedef uint32_t __le32; +#else +typedef u16 __le16; +typedef u32 __le32; +#endif + +#ifndef le16_to_cpu +#define le16_to_cpu(x) (x) +#endif + +#ifndef le32_to_cpu +#define le32_to_cpu(x) (x) +#endif + +#define unlikely(x) (x) + +/* Are two types/vars the same type (ignoring qualifiers)? */ +#ifndef __same_type +#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) +#endif + +#ifndef BUILD_BUG_ON +/* Force a compilation error if condition is true */ +#define BUILD_BUG_ON(condition) ((void)BUILD_BUG_ON_ZERO(condition)) +/* Force a compilation error if condition is true, but also produce a + result (of value 0 and type size_t), so the expression can be used + e.g. in a structure initializer (or where-ever else comma expressions + aren't permitted). */ +#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int : -!!(e); })) +#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int : -!!(e); })) +#endif + +#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) + +/* Channel flags. */ +#define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */ +#define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */ +#define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */ +#define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */ +#define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */ +#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */ +#define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */ +#define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */ +#define IEEE80211_CHAN_GSM 0x1000 /* GSM (900 MHz) */ +#define IEEE80211_CHAN_STURBO 0x2000 /* Static Turbo */ +#define IEEE80211_CHAN_HALF 0x4000 /* Half channel (10 MHz wide) */ +#define IEEE80211_CHAN_QUARTER 0x8000 /* Quarter channel (5 MHz wide) */ + +/* For IEEE80211_RADIOTAP_FLAGS */ +#define IEEE80211_RADIOTAP_F_CFP \ + 0x01 /* sent/received \ + * during CFP \ + */ +#define IEEE80211_RADIOTAP_F_SHORTPRE \ + 0x02 /* sent/received \ + * with short \ + * preamble \ + */ +#define IEEE80211_RADIOTAP_F_WEP \ + 0x04 /* sent/received \ + * with WEP encryption \ + */ +#define IEEE80211_RADIOTAP_F_FRAG \ + 0x08 /* sent/received \ + * with fragmentation \ + */ +#define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */ +#define IEEE80211_RADIOTAP_F_DATAPAD \ + 0x20 /* frame has padding between \ + * 802.11 header and payload \ + * (to 32-bit boundary) \ + */ +#define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* bad FCS */ + +/* For IEEE80211_RADIOTAP_RX_FLAGS */ +#define IEEE80211_RADIOTAP_F_RX_BADPLCP 0x0002 /* frame has bad PLCP */ + +/* For IEEE80211_RADIOTAP_TX_FLAGS */ +#define IEEE80211_RADIOTAP_F_TX_FAIL \ + 0x0001 /* failed due to excessive \ + * retries */ +#define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 /* used cts 'protection' */ +#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */ +#define IEEE80211_RADIOTAP_F_TX_NOACK 0x0008 /* don't expect an ack */ + +/* For IEEE80211_RADIOTAP_MCS */ +#define IEEE80211_RADIOTAP_MCS_HAVE_BW 0x01 +#define IEEE80211_RADIOTAP_MCS_HAVE_MCS 0x02 +#define IEEE80211_RADIOTAP_MCS_HAVE_GI 0x04 +#define IEEE80211_RADIOTAP_MCS_HAVE_FMT 0x08 +#define IEEE80211_RADIOTAP_MCS_HAVE_FEC 0x10 +#define IEEE80211_RADIOTAP_MCS_HAVE_STBC 0x20 + +#define IEEE80211_RADIOTAP_MCS_BW_MASK 0x03 +#define IEEE80211_RADIOTAP_MCS_BW_20 0 +#define IEEE80211_RADIOTAP_MCS_BW_40 1 +#define IEEE80211_RADIOTAP_MCS_BW_20L 2 +#define IEEE80211_RADIOTAP_MCS_BW_20U 3 +#define IEEE80211_RADIOTAP_MCS_SGI 0x04 +#define IEEE80211_RADIOTAP_MCS_FMT_GF 0x08 +#define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10 +#define IEEE80211_RADIOTAP_MCS_STBC_MASK 0x60 +#define IEEE80211_RADIOTAP_MCS_STBC_1 1 +#define IEEE80211_RADIOTAP_MCS_STBC_2 2 +#define IEEE80211_RADIOTAP_MCS_STBC_3 3 + +#define IEEE80211_RADIOTAP_MCS_STBC_SHIFT 5 + +/* For IEEE80211_RADIOTAP_AMPDU_STATUS */ +#define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN 0x0001 +#define IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN 0x0002 +#define IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN 0x0004 +#define IEEE80211_RADIOTAP_AMPDU_IS_LAST 0x0008 +#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR 0x0010 +#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN 0x0020 + +/* For IEEE80211_RADIOTAP_VHT */ +#define IEEE80211_RADIOTAP_VHT_KNOWN_STBC 0x0001 +#define IEEE80211_RADIOTAP_VHT_KNOWN_TXOP_PS_NA 0x0002 +#define IEEE80211_RADIOTAP_VHT_KNOWN_GI 0x0004 +#define IEEE80211_RADIOTAP_VHT_KNOWN_SGI_NSYM_DIS 0x0008 +#define IEEE80211_RADIOTAP_VHT_KNOWN_LDPC_EXTRA_OFDM_SYM 0x0010 +#define IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED 0x0020 +#define IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH 0x0040 +#define IEEE80211_RADIOTAP_VHT_KNOWN_GROUP_ID 0x0080 +#define IEEE80211_RADIOTAP_VHT_KNOWN_PARTIAL_AID 0x0100 + +#define IEEE80211_RADIOTAP_VHT_FLAG_STBC 0x01 +#define IEEE80211_RADIOTAP_VHT_FLAG_TXOP_PS_NA 0x02 +#define IEEE80211_RADIOTAP_VHT_FLAG_SGI 0x04 +#define IEEE80211_RADIOTAP_VHT_FLAG_SGI_NSYM_M10_9 0x08 +#define IEEE80211_RADIOTAP_VHT_FLAG_LDPC_EXTRA_OFDM_SYM 0x10 +#define IEEE80211_RADIOTAP_VHT_FLAG_BEAMFORMED 0x20 + +#define IEEE80211_RADIOTAP_CODING_LDPC_USER0 0x01 +#define IEEE80211_RADIOTAP_CODING_LDPC_USER1 0x02 +#define IEEE80211_RADIOTAP_CODING_LDPC_USER2 0x04 +#define IEEE80211_RADIOTAP_CODING_LDPC_USER3 0x08 + +/*------------------------------ Tx Desc definition Macro + * ------------------------*/ +/* #pragma mark -- Tx Desc related definition. -- */ +/* ---------------------------------------------------------------------------- + * ----------------------------------------------------------- + * Rate + * ----------------------------------------------------------- + * CCK Rates, TxHT = 0 */ +#define DESC_RATE1M 0x00 +#define DESC_RATE2M 0x01 +#define DESC_RATE5_5M 0x02 +#define DESC_RATE11M 0x03 + +/* OFDM Rates, TxHT = 0 */ +#define DESC_RATE6M 0x04 +#define DESC_RATE9M 0x05 +#define DESC_RATE12M 0x06 +#define DESC_RATE18M 0x07 +#define DESC_RATE24M 0x08 +#define DESC_RATE36M 0x09 +#define DESC_RATE48M 0x0a +#define DESC_RATE54M 0x0b + +/* MCS Rates, TxHT = 1 */ +#define DESC_RATEMCS0 0x0c +#define DESC_RATEMCS1 0x0d +#define DESC_RATEMCS2 0x0e +#define DESC_RATEMCS3 0x0f +#define DESC_RATEMCS4 0x10 +#define DESC_RATEMCS5 0x11 +#define DESC_RATEMCS6 0x12 +#define DESC_RATEMCS7 0x13 +#define DESC_RATEMCS8 0x14 +#define DESC_RATEMCS9 0x15 +#define DESC_RATEMCS10 0x16 +#define DESC_RATEMCS11 0x17 +#define DESC_RATEMCS12 0x18 +#define DESC_RATEMCS13 0x19 +#define DESC_RATEMCS14 0x1a +#define DESC_RATEMCS15 0x1b +#define DESC_RATEMCS16 0x1C +#define DESC_RATEMCS17 0x1D +#define DESC_RATEMCS18 0x1E +#define DESC_RATEMCS19 0x1F +#define DESC_RATEMCS20 0x20 +#define DESC_RATEMCS21 0x21 +#define DESC_RATEMCS22 0x22 +#define DESC_RATEMCS23 0x23 +#define DESC_RATEMCS24 0x24 +#define DESC_RATEMCS25 0x25 +#define DESC_RATEMCS26 0x26 +#define DESC_RATEMCS27 0x27 +#define DESC_RATEMCS28 0x28 +#define DESC_RATEMCS29 0x29 +#define DESC_RATEMCS30 0x2A +#define DESC_RATEMCS31 0x2B +#define DESC_RATEVHTSS1MCS0 0x2C +#define DESC_RATEVHTSS1MCS1 0x2D +#define DESC_RATEVHTSS1MCS2 0x2E +#define DESC_RATEVHTSS1MCS3 0x2F +#define DESC_RATEVHTSS1MCS4 0x30 +#define DESC_RATEVHTSS1MCS5 0x31 +#define DESC_RATEVHTSS1MCS6 0x32 +#define DESC_RATEVHTSS1MCS7 0x33 +#define DESC_RATEVHTSS1MCS8 0x34 +#define DESC_RATEVHTSS1MCS9 0x35 +#define DESC_RATEVHTSS2MCS0 0x36 +#define DESC_RATEVHTSS2MCS1 0x37 +#define DESC_RATEVHTSS2MCS2 0x38 +#define DESC_RATEVHTSS2MCS3 0x39 +#define DESC_RATEVHTSS2MCS4 0x3A +#define DESC_RATEVHTSS2MCS5 0x3B +#define DESC_RATEVHTSS2MCS6 0x3C +#define DESC_RATEVHTSS2MCS7 0x3D +#define DESC_RATEVHTSS2MCS8 0x3E +#define DESC_RATEVHTSS2MCS9 0x3F +#define DESC_RATEVHTSS3MCS0 0x40 +#define DESC_RATEVHTSS3MCS1 0x41 +#define DESC_RATEVHTSS3MCS2 0x42 +#define DESC_RATEVHTSS3MCS3 0x43 +#define DESC_RATEVHTSS3MCS4 0x44 +#define DESC_RATEVHTSS3MCS5 0x45 +#define DESC_RATEVHTSS3MCS6 0x46 +#define DESC_RATEVHTSS3MCS7 0x47 +#define DESC_RATEVHTSS3MCS8 0x48 +#define DESC_RATEVHTSS3MCS9 0x49 +#define DESC_RATEVHTSS4MCS0 0x4A +#define DESC_RATEVHTSS4MCS1 0x4B +#define DESC_RATEVHTSS4MCS2 0x4C +#define DESC_RATEVHTSS4MCS3 0x4D +#define DESC_RATEVHTSS4MCS4 0x4E +#define DESC_RATEVHTSS4MCS5 0x4F +#define DESC_RATEVHTSS4MCS6 0x50 +#define DESC_RATEVHTSS4MCS7 0x51 +#define DESC_RATEVHTSS4MCS8 0x52 +#define DESC_RATEVHTSS4MCS9 0x53 + +/* Base version of the radiotap packet header data */ +#define PKTHDR_RADIOTAP_VERSION 0 + +static inline u16 __get_unaligned_memmove16(const void *p) { + u16 tmp; + memmove(&tmp, p, 2); + return tmp; +} + +static inline u32 __get_unaligned_memmove32(const void *p) { + u32 tmp; + memmove(&tmp, p, 4); + return tmp; +} + +static inline u16 get_unaligned_le16(const void *p) { + u16 tmp = __get_unaligned_memmove16((const u8 *)p); + return le16_to_cpu(tmp); +} + +static inline u32 get_unaligned_le32(const void *p) { + u32 tmp = __get_unaligned_memmove32((const u8 *)p); + return le32_to_cpu(tmp); +} + +/* A generic radio capture format is desirable. There is one for + * Linux, but it is neither rigidly defined (there were not even + * units given for some fields) nor easily extensible. + * + * I suggest the following extensible radio capture format. It is + * based on a bitmap indicating which fields are present. + * + * I am trying to describe precisely what the application programmer + * should expect in the following, and for that reason I tell the + * units and origin of each measurement (where it applies), or else I + * use sufficiently weaselly language ("is a monotonically nondecreasing + * function of...") that I cannot set false expectations for lawyerly + * readers. + */ + +/* + * The radio capture header precedes the 802.11 header. + * All data in the header is little endian on all platforms. + */ +#ifdef _MSC_VER +#pragma pack(push, 1) +#endif +struct ieee80211_radiotap_header { + u8 it_version; /* Version 0. Only increases + * for drastic changes, + * introduction of compatible + * new fields does not count. + */ + u8 it_pad; + __le16 it_len; /* length of the whole + * header in bytes, including + * it_version, it_pad, + * it_len, and data fields. + */ + __le32 it_present; /* A bitmap telling which + * fields are present. Set bit 31 + * (0x80000000) to extend the + * bitmap by another 32 bits. + * Additional extensions are made + * by setting bit 31. + */ +} +#ifdef _MSC_VER +; +#pragma pack(pop) +#else +__attribute__((packed)); +#endif + +/* Name Data type Units + * ---- --------- ----- + * + * IEEE80211_RADIOTAP_TSFT __le64 microseconds + * + * Value in microseconds of the MAC's 64-bit 802.11 Time + * Synchronization Function timer when the first bit of the + * MPDU arrived at the MAC. For received frames, only. + * + * IEEE80211_RADIOTAP_CHANNEL 2 x __le16 MHz, bitmap + * + * Tx/Rx frequency in MHz, followed by flags (see below). + * + * IEEE80211_RADIOTAP_FHSS __le16 see below + * + * For frequency-hopping radios, the hop set (first byte) + * and pattern (second byte). + * + * IEEE80211_RADIOTAP_RATE u8 500kb/s + * + * Tx/Rx data rate + * + * IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from + * one milliwatt (dBm) + * + * RF signal power at the antenna, decibel difference from + * one milliwatt. + * + * IEEE80211_RADIOTAP_DBM_ANTNOISE s8 decibels from + * one milliwatt (dBm) + * + * RF noise power at the antenna, decibel difference from one + * milliwatt. + * + * IEEE80211_RADIOTAP_DB_ANTSIGNAL u8 decibel (dB) + * + * RF signal power at the antenna, decibel difference from an + * arbitrary, fixed reference. + * + * IEEE80211_RADIOTAP_DB_ANTNOISE u8 decibel (dB) + * + * RF noise power at the antenna, decibel difference from an + * arbitrary, fixed reference point. + * + * IEEE80211_RADIOTAP_LOCK_QUALITY __le16 unitless + * + * Quality of Barker code lock. Unitless. Monotonically + * nondecreasing with "better" lock strength. Called "Signal + * Quality" in datasheets. (Is there a standard way to measure + * this?) + * + * IEEE80211_RADIOTAP_TX_ATTENUATION __le16 unitless + * + * Transmit power expressed as unitless distance from max + * power set at factory calibration. 0 is max power. + * Monotonically nondecreasing with lower power levels. + * + * IEEE80211_RADIOTAP_DB_TX_ATTENUATION __le16 decibels (dB) + * + * Transmit power expressed as decibel distance from max power + * set at factory calibration. 0 is max power. Monotonically + * nondecreasing with lower power levels. + * + * IEEE80211_RADIOTAP_DBM_TX_POWER s8 decibels from + * one milliwatt (dBm) + * + * Transmit power expressed as dBm (decibels from a 1 milliwatt + * reference). This is the absolute power level measured at + * the antenna port. + * + * IEEE80211_RADIOTAP_FLAGS u8 bitmap + * + * Properties of transmitted and received frames. See flags + * defined below. + * + * IEEE80211_RADIOTAP_ANTENNA u8 antenna index + * + * Unitless indication of the Rx/Tx antenna for this packet. + * The first antenna is antenna 0. + * + * IEEE80211_RADIOTAP_RX_FLAGS __le16 bitmap + * + * Properties of received frames. See flags defined below. + * + * IEEE80211_RADIOTAP_TX_FLAGS __le16 bitmap + * + * Properties of transmitted frames. See flags defined below. + * + * IEEE80211_RADIOTAP_RTS_RETRIES u8 data + * + * Number of rts retries a transmitted frame used. + * + * IEEE80211_RADIOTAP_DATA_RETRIES u8 data + * + * Number of unicast retries a transmitted frame used. + * + * IEEE80211_RADIOTAP_MCS u8, u8, u8 unitless + * + * Contains a bitmap of known fields/flags, the flags, and + * the MCS index. + * + * IEEE80211_RADIOTAP_AMPDU_STATUS u32, u16, u8, u8 unitless + * + * Contains the AMPDU information for the subframe. + * + * IEEE80211_RADIOTAP_VHT u16, u8, u8, u8[4], u8, u8, u16 + * + * Contains VHT information about this frame. + */ +enum ieee80211_radiotap_type { + IEEE80211_RADIOTAP_TSFT = 0, + IEEE80211_RADIOTAP_FLAGS = 1, + IEEE80211_RADIOTAP_RATE = 2, + IEEE80211_RADIOTAP_CHANNEL = 3, + IEEE80211_RADIOTAP_FHSS = 4, + IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5, + IEEE80211_RADIOTAP_DBM_ANTNOISE = 6, + IEEE80211_RADIOTAP_LOCK_QUALITY = 7, + IEEE80211_RADIOTAP_TX_ATTENUATION = 8, + IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9, + IEEE80211_RADIOTAP_DBM_TX_POWER = 10, + IEEE80211_RADIOTAP_ANTENNA = 11, + IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12, + IEEE80211_RADIOTAP_DB_ANTNOISE = 13, + IEEE80211_RADIOTAP_RX_FLAGS = 14, + IEEE80211_RADIOTAP_TX_FLAGS = 15, + IEEE80211_RADIOTAP_RTS_RETRIES = 16, + IEEE80211_RADIOTAP_DATA_RETRIES = 17, + + IEEE80211_RADIOTAP_MCS = 19, + IEEE80211_RADIOTAP_AMPDU_STATUS = 20, + IEEE80211_RADIOTAP_VHT = 21, + IEEE80211_RADIOTAP_TIMESTAMP = 22, + + /* valid in every it_present bitmap, even vendor namespaces */ + IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29, + IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30, + IEEE80211_RADIOTAP_EXT = 31 +}; + +struct radiotap_align_size { + uint8_t align : 4, size : 4; +}; + +struct ieee80211_radiotap_namespace { + const struct radiotap_align_size *align_size; + int n_bits; + uint32_t oui; + uint8_t subns; +}; + +struct ieee80211_radiotap_vendor_namespaces { + const struct ieee80211_radiotap_namespace *ns; + int n_ns; +}; + +/* helpers */ +static inline int ieee80211_get_radiotap_len(unsigned char *data) { + struct ieee80211_radiotap_header *hdr = + (struct ieee80211_radiotap_header *)data; + + return get_unaligned_le16(&hdr->it_len); +} + +/** + * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args + * @this_arg_index: index of current arg, valid after each successful call + * to ieee80211_radiotap_iterator_next() + * @this_arg: pointer to current radiotap arg; it is valid after each + * call to ieee80211_radiotap_iterator_next() but also after + * ieee80211_radiotap_iterator_init() where it will point to + * the beginning of the actual data portion + * @this_arg_size: length of the current arg, for convenience + * @current_namespace: pointer to the current namespace definition + * (or internally %NULL if the current namespace is unknown) + * @is_radiotap_ns: indicates whether the current namespace is the default + * radiotap namespace or not + * + * @_rtheader: pointer to the radiotap header we are walking through + * @_max_length: length of radiotap header in cpu byte ordering + * @_arg_index: next argument index + * @_arg: next argument pointer + * @_next_bitmap: internal pointer to next present u32 + * @_bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present + * @_vns: vendor namespace definitions + * @_next_ns_data: beginning of the next namespace's data + * @_reset_on_ext: internal; reset the arg index to 0 when going to the + * next bitmap word + * + * Describes the radiotap parser state. Fields prefixed with an underscore + * must not be used by users of the parser, only by the parser internally. + */ + +struct ieee80211_radiotap_iterator { + struct ieee80211_radiotap_header *_rtheader; + const struct ieee80211_radiotap_vendor_namespaces *_vns; + const struct ieee80211_radiotap_namespace *current_namespace; + + unsigned char *_arg, *_next_ns_data; + __le32 *_next_bitmap; + + unsigned char *this_arg; + int this_arg_index; + int this_arg_size; + + int is_radiotap_ns; + + int _max_length; + int _arg_index; + uint32_t _bitmap_shifter; + int _reset_on_ext; +}; + +int ieee80211_radiotap_iterator_init( + struct ieee80211_radiotap_iterator *iterator, + struct ieee80211_radiotap_header *radiotap_header, int max_length, + const struct ieee80211_radiotap_vendor_namespaces *vns); + +int ieee80211_radiotap_iterator_next( + struct ieee80211_radiotap_iterator *iterator); + +u16 GetSequence(const u8 *packet); +u8 MRateToHwRate(u8 rate); + +#endif diff --git a/txdemo/main.cpp b/txdemo/main.cpp new file mode 100644 index 0000000..1618559 --- /dev/null +++ b/txdemo/main.cpp @@ -0,0 +1,142 @@ +#include +#include +#include +#include + +#ifdef __ANDROID__ + #include +#else + #include +#endif + + +#include "FrameParser.h" +#include "RtlUsbAdapter.h" +#include "WiFiDriver.h" +#include "logger.h" + +#include + +// #define USB_VENDOR_ID 0x0bda +// #define USB_PRODUCT_ID 0x8812 + +void printHexArray(const uint8_t *array, size_t length) { + for (size_t i = 0; i < length; ++i) { + // Print each byte as a two-digit hexadecimal number + std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') + << static_cast(array[i]); + + // Print a space between bytes, but not after the last byte + if (i < length - 1) { + std::cout << " "; + } + } + std::cout << std::dec << std::endl; // Reset to decimal formatting +} + +static void packetProcessor(const Packet &packet) {} + +void usb_event_loop(Logger_t _logger,libusb_context* ctx){ + while (true) { + int r = libusb_handle_events(ctx); + if (r < 0) { + _logger->error("Error handling events: {}", r); + break; + } + } +} + +int main(int argc, char **argv) { + libusb_context *context; + libusb_device_handle *handle; + libusb_device *device; + struct libusb_device_descriptor desc; + uint8_t usb_frame[10000]; + unsigned char buffer[256]; + struct tx_desc *ptxdesc; + int fd; + + auto logger = std::make_shared(); + + // fd from argv is provided by termux on Android + // https://wiki.termux.com/wiki/Termux-usb + fd = atoi(argv[1]); + logger->info("got fd {}", fd); + + // libusb_set_option(context, LIBUSB_OPTION_LOG_LEVEL, + // LIBUSB_LOG_LEVEL_DEBUG); + libusb_set_option(NULL, LIBUSB_OPTION_NO_DEVICE_DISCOVERY); + libusb_set_option(NULL, LIBUSB_OPTION_WEAK_AUTHORITY); + + int rc = libusb_init(&context); + + rc = libusb_wrap_sys_device(context, (intptr_t)fd, &handle); + + device = libusb_get_device(handle); + + rc = libusb_get_device_descriptor(device, &desc); + + logger->info("Vendor/Product ID:{:04x}:{:04x}", desc.idVendor, + desc.idProduct); + if (libusb_kernel_driver_active(handle, 0)) { + rc = libusb_detach_kernel_driver(handle, 0); // detach driver + logger->error("libusb_detach_kernel_driver: {}", rc); + } + rc = libusb_claim_interface(handle, 0); + + WiFiDriver wifi_driver{logger}; + auto rtlDevice = wifi_driver.CreateRtlDevice(handle); + pid_t fpid; + fpid = fork(); + rtlDevice->SetTxPower(40); + if (fpid == 0) { + + rtlDevice->Init(packetProcessor, SelectedChannel{ + .Channel = static_cast(161), + .ChannelOffset = 0, + .ChannelWidth = CHANNEL_WIDTH_20, + + }); + + return 1; + } + // Loop for sending packets + + + rtlDevice->InitWrite(SelectedChannel{ + .Channel = static_cast(161), + .ChannelOffset = 0, + .ChannelWidth = CHANNEL_WIDTH_20}); + + + sleep(5); + + // A new thread starts the libusb event loop + std::thread usb_thread(usb_event_loop,logger,context); + uint8_t beacon_frame[] = { + 0x00, 0x00, 0x0d, 0x00, 0x00, 0x80, 0x08, 0x00, 0x08, 0x00, 0x37, + 0x00, 0x01, // radiotap header + 0x08, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x57, + 0x42, 0x75, 0x05, 0xd6, 0x00, 0x57, 0x42, 0x75, 0x05, 0xd6, 0x00, + 0x80, 0x00, // 80211 header + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x24, 0x4f, + 0xa0, 0xc5, 0x4a, 0xbb, 0x6a, 0x55, 0x03, 0x72, 0xf8, 0x4d, 0xc4, + 0x9d, 0x1a, 0x51, 0xb7, 0x3f, 0x98, 0xf1, 0xe7, 0x46, 0x4d, 0x1c, + 0x21, 0x86, 0x15, 0x21, 0x02, 0xf4, 0x88, 0x63, 0xff, 0x51, 0x66, + 0x34, 0xf2, 0x16, 0x71, 0xf5, 0x76, 0x0b, 0x35, 0xc0, 0xe1, 0x44, + 0xcd, 0xce, 0x4e, 0x35, 0xd9, 0x85, 0x9a, 0xcf, 0x4d, 0x48, 0x4c, + 0x8f, 0x28, 0x6f, 0x10, 0xb0, 0xa9, 0x5d, 0xbf, 0xcb, 0x6f}; + + int actual_length = 0; + + while (true) { + rc = rtlDevice->send_packet(beacon_frame, sizeof(beacon_frame)); + } + rc = libusb_release_interface(handle, 0); + assert(rc == 0); + + libusb_close(handle); + + libusb_exit(context); + return 0; +} From 737679c9358abe4fec7d47cf431d9cec85bf0b15 Mon Sep 17 00:00:00 2001 From: Ihor Ivlev Date: Fri, 31 Jan 2025 22:41:30 +0100 Subject: [PATCH 2/2] Windows compatibility fixes --- CMakeLists.txt | 92 +++--- src/FrameParser.h | 63 +++- src/HalModule.cpp | 1 + src/RadioManagementModule.cpp | 1 + src/Radiotap.c | 589 +++++++++------------------------- src/RtlUsbAdapter.cpp | 2 +- txdemo/main.cpp | 11 +- 7 files changed, 271 insertions(+), 488 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c7b6a3..cc25def 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,70 +1,68 @@ cmake_minimum_required(VERSION 3.15) -# This should go before project declaration. -if (WIN32) +# Set the toolchain file for vcpkg on Windows. +if(WIN32) set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake") -endif () +endif() project(Rtl8812auNet) -# the `pkg_check_modules` function is created with this call +# Find pkg-config and then use it to locate libusb. find_package(PkgConfig REQUIRED) - -# this calls create special `PkgConfig::LIBUSB` variables -pkg_check_modules(LIBUSB REQUIRED IMPORTED_TARGET libusb-1.0) +pkg_check_modules(libusb REQUIRED IMPORTED_TARGET libusb-1.0) add_library(WiFiDriver - src/logger.h + src/logger.h - hal/Hal8812PhyReg.h - hal/Hal8812PwrSeq.c - hal/Hal8812PwrSeq.h - hal/basic_types.h - hal/hal8812a_fw.c - hal/hal8812a_fw.h - hal/hal_com_reg.h - hal/rtl8812a_hal.h - hal/rtl8812a_recv.h - hal/rtl8812a_spec.h + hal/Hal8812PhyReg.h + hal/Hal8812PwrSeq.c + hal/Hal8812PwrSeq.h + hal/basic_types.h + hal/hal8812a_fw.c + hal/hal8812a_fw.h + hal/hal_com_reg.h + hal/rtl8812a_hal.h + hal/rtl8812a_recv.h + hal/rtl8812a_spec.h - src/ieee80211_radiotap.h - src/EepromManager.cpp - src/EepromManager.h - src/Firmware.h - src/FirmwareManager.cpp - src/FirmwareManager.h - src/FrameParser.cpp - src/FrameParser.h - src/HalModule.cpp - src/HalModule.h - src/ParsedRadioPacket.cpp - src/RadioManagementModule.cpp - src/RadioManagementModule.h - src/Radiotap.c - src/Rtl8812aDevice.cpp - src/Rtl8812aDevice.h - src/RtlUsbAdapter.cpp - src/RtlUsbAdapter.h - src/SelectedChannel.h - src/WiFiDriver.cpp - src/WiFiDriver.h - src/registry_priv.h + src/ieee80211_radiotap.h + src/EepromManager.cpp + src/EepromManager.h + src/Firmware.h + src/FirmwareManager.cpp + src/FirmwareManager.h + src/FrameParser.cpp + src/FrameParser.h + src/HalModule.cpp + src/HalModule.h + src/ParsedRadioPacket.cpp + src/RadioManagementModule.cpp + src/RadioManagementModule.h + src/Radiotap.c + src/Rtl8812aDevice.cpp + src/Rtl8812aDevice.h + src/RtlUsbAdapter.cpp + src/RtlUsbAdapter.h + src/SelectedChannel.h + src/WiFiDriver.cpp + src/WiFiDriver.h + src/registry_priv.h ) target_compile_features(WiFiDriver PUBLIC cxx_std_20) -target_link_libraries(WiFiDriver PUBLIC - PkgConfig::LIBUSB -) +# Link WiFiDriver with libusb as found via pkg-config. +target_link_libraries(WiFiDriver PUBLIC PkgConfig::libusb) target_include_directories(WiFiDriver PUBLIC hal) target_include_directories(WiFiDriver PUBLIC src) add_executable(WiFiDriverDemo - demo/main.cpp) - + demo/main.cpp +) target_link_libraries(WiFiDriverDemo PUBLIC WiFiDriver) add_executable(WiFiDriverTxDemo - txdemo/main.cpp) -target_link_libraries(WiFiDriverTxDemo PUBLIC WiFiDriver) + txdemo/main.cpp +) +target_link_libraries(WiFiDriverTxDemo PUBLIC WiFiDriver PRIVATE PkgConfig::libusb) diff --git a/src/FrameParser.h b/src/FrameParser.h index 172cbbc..dca57e3 100644 --- a/src/FrameParser.h +++ b/src/FrameParser.h @@ -374,7 +374,7 @@ struct pkt_attrib u8 rtsen; u8 cts2self; union Keytype dot11tkiptxmickey; - /* union Keytype dot11tkiprxmickey; */ + /* union Keytype dot11tkiprxmickey; */ union Keytype dot118021x_UncstKey; // #ifdef CONFIG_TDLS @@ -400,6 +400,9 @@ struct pkt_attrib u8 inject; /* == a5 if injected */ }; +#if defined(_MSC_VER) +#pragma pack(push, 1) +#endif struct rtw_ieee80211_hdr { u16 frame_ctl; @@ -408,9 +411,18 @@ struct rtw_ieee80211_hdr u8 addr2[ETH_ALEN]; u8 addr3[ETH_ALEN]; u16 seq_ctl; - u8 addr4[ETH_ALEN]; -} __attribute__((packed)); +} +#if !defined(_MSC_VER) + __attribute__((packed)) +#endif +; +#if defined(_MSC_VER) +#pragma pack(pop) +#endif +#if defined(_MSC_VER) +#pragma pack(push, 1) +#endif struct rtw_ieee80211_hdr_3addr { u16 frame_ctl; @@ -419,8 +431,18 @@ struct rtw_ieee80211_hdr_3addr u8 addr2[ETH_ALEN]; u8 addr3[ETH_ALEN]; u16 seq_ctl; -} __attribute__((packed)); +} +#if !defined(_MSC_VER) + __attribute__((packed)) +#endif +; +#if defined(_MSC_VER) +#pragma pack(pop) +#endif +#if defined(_MSC_VER) +#pragma pack(push, 1) +#endif struct rtw_ieee80211_hdr_qos { u16 frame_ctl; @@ -431,8 +453,18 @@ struct rtw_ieee80211_hdr_qos u16 seq_ctl; u8 addr4[ETH_ALEN]; u16 qc; -} __attribute__((packed)); +} +#if !defined(_MSC_VER) + __attribute__((packed)) +#endif +; +#if defined(_MSC_VER) +#pragma pack(pop) +#endif +#if defined(_MSC_VER) +#pragma pack(push, 1) +#endif struct rtw_ieee80211_hdr_3addr_qos { u16 frame_ctl; @@ -442,8 +474,18 @@ struct rtw_ieee80211_hdr_3addr_qos u8 addr3[ETH_ALEN]; u16 seq_ctl; u16 qc; -} __attribute__((packed)); +} +#if !defined(_MSC_VER) + __attribute__((packed)) +#endif +; +#if defined(_MSC_VER) +#pragma pack(pop) +#endif +#if defined(_MSC_VER) +#pragma pack(push, 1) +#endif struct eapol { u8 snap[6]; @@ -451,7 +493,14 @@ struct eapol u8 version; u8 type; u16 length; -} __attribute__((packed)); +} +#if !defined(_MSC_VER) + __attribute__((packed)) +#endif +; +#if defined(_MSC_VER) +#pragma pack(pop) +#endif struct tx_desc { diff --git a/src/HalModule.cpp b/src/HalModule.cpp index b67412b..5d2ccef 100644 --- a/src/HalModule.cpp +++ b/src/HalModule.cpp @@ -7,6 +7,7 @@ #include "rtl8812a_hal.h" #include "rtl8812a_spec.h" +#include #include #include diff --git a/src/RadioManagementModule.cpp b/src/RadioManagementModule.cpp index 46d29c5..c4455b1 100644 --- a/src/RadioManagementModule.cpp +++ b/src/RadioManagementModule.cpp @@ -2,6 +2,7 @@ #include "Hal8812PhyReg.h" #include "registry_priv.h" +#include #include #include #include diff --git a/src/Radiotap.c b/src/Radiotap.c index d042f0c..0e3a3ec 100644 --- a/src/Radiotap.c +++ b/src/Radiotap.c @@ -1,8 +1,8 @@ /* * Radiotap parser * - * Copyright 2007 Andy Green - * Copyright 2009 Johannes Berg + * Copyright 2007 Andy Green + * Copyright 2009 Johannes Berg * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -16,6 +16,19 @@ #include "ieee80211_radiotap.h" #include +#include /* for size_t */ +#include /* for uint8_t, uint16_t, etc. */ + +/* if not defined already */ +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +/* Make sure your type definitions for u8, u16 etc are available. + For example: + typedef uint8_t u8; + typedef uint16_t u16; +*/ enum MGN_RATE { MGN_1M = 0x02, @@ -105,127 +118,46 @@ enum MGN_RATE { MGN_VHT4SS_MCS9, MGN_UNKNOWN }; -/* function prototypes and related defs are in include/net/cfg80211.h */ - -static const struct radiotap_align_size rtap_namespace_sizes[] = { - [IEEE80211_RADIOTAP_TSFT] = - { - .align = 8, - .size = 8, - }, - [IEEE80211_RADIOTAP_FLAGS] = - { - .align = 1, - .size = 1, - }, - [IEEE80211_RADIOTAP_RATE] = - { - .align = 1, - .size = 1, - }, - [IEEE80211_RADIOTAP_CHANNEL] = - { - .align = 2, - .size = 4, - }, - [IEEE80211_RADIOTAP_FHSS] = - { - .align = 2, - .size = 2, - }, - [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = - { - .align = 1, - .size = 1, - }, - [IEEE80211_RADIOTAP_DBM_ANTNOISE] = - { - .align = 1, - .size = 1, - }, - [IEEE80211_RADIOTAP_LOCK_QUALITY] = - { - .align = 2, - .size = 2, - }, - [IEEE80211_RADIOTAP_TX_ATTENUATION] = - { - .align = 2, - .size = 2, - }, - [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = - { - .align = 2, - .size = 2, - }, - [IEEE80211_RADIOTAP_DBM_TX_POWER] = - { - .align = 1, - .size = 1, - }, - [IEEE80211_RADIOTAP_ANTENNA] = - { - .align = 1, - .size = 1, - }, - [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = - { - .align = 1, - .size = 1, - }, - [IEEE80211_RADIOTAP_DB_ANTNOISE] = - { - .align = 1, - .size = 1, - }, - [IEEE80211_RADIOTAP_RX_FLAGS] = - { - .align = 2, - .size = 2, - }, - [IEEE80211_RADIOTAP_TX_FLAGS] = - { - .align = 2, - .size = 2, - }, - [IEEE80211_RADIOTAP_RTS_RETRIES] = - { - .align = 1, - .size = 1, - }, - [IEEE80211_RADIOTAP_DATA_RETRIES] = - { - .align = 1, - .size = 1, - }, - [IEEE80211_RADIOTAP_MCS] = - { - .align = 1, - .size = 3, - }, - [IEEE80211_RADIOTAP_AMPDU_STATUS] = - { - .align = 4, - .size = 8, - }, - [IEEE80211_RADIOTAP_VHT] = - { - .align = 2, - .size = 12, - }, - [IEEE80211_RADIOTAP_TIMESTAMP] = - { - .align = 8, - .size = 12, - }, - /* - * add more here as they are defined in radiotap.h - */ + +/* + * In order to support MSVC (which doesn’t support C99 designated + * initializers), we replace the “[index] = { .align = …, .size = … }” + * syntax with positional initializers. Note that the array is defined + * to have 23 entries (0..22) corresponding to indices used in the enum. + * Entries for undefined indices (e.g. 18) are set to {0,0}. + */ + +static const struct radiotap_align_size rtap_namespace_sizes[23] = { + /* 0: IEEE80211_RADIOTAP_TSFT */ { 8, 8 }, + /* 1: IEEE80211_RADIOTAP_FLAGS */ { 1, 1 }, + /* 2: IEEE80211_RADIOTAP_RATE */ { 1, 1 }, + /* 3: IEEE80211_RADIOTAP_CHANNEL */ { 2, 4 }, + /* 4: IEEE80211_RADIOTAP_FHSS */ { 2, 2 }, + /* 5: IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ { 1, 1 }, + /* 6: IEEE80211_RADIOTAP_DBM_ANTNOISE */ { 1, 1 }, + /* 7: IEEE80211_RADIOTAP_LOCK_QUALITY */ { 2, 2 }, + /* 8: IEEE80211_RADIOTAP_TX_ATTENUATION */ { 2, 2 }, + /* 9: IEEE80211_RADIOTAP_DB_TX_ATTENUATION */ { 2, 2 }, + /* 10: IEEE80211_RADIOTAP_DBM_TX_POWER */ { 1, 1 }, + /* 11: IEEE80211_RADIOTAP_ANTENNA */ { 1, 1 }, + /* 12: IEEE80211_RADIOTAP_DB_ANTSIGNAL */ { 1, 1 }, + /* 13: IEEE80211_RADIOTAP_DB_ANTNOISE */ { 1, 1 }, + /* 14: IEEE80211_RADIOTAP_RX_FLAGS */ { 2, 2 }, + /* 15: IEEE80211_RADIOTAP_TX_FLAGS */ { 2, 2 }, + /* 16: IEEE80211_RADIOTAP_RTS_RETRIES */ { 1, 1 }, + /* 17: IEEE80211_RADIOTAP_DATA_RETRIES */ { 1, 1 }, + /* 18: (unused) */ { 0, 0 }, + /* 19: IEEE80211_RADIOTAP_MCS */ { 1, 3 }, + /* 20: IEEE80211_RADIOTAP_AMPDU_STATUS */ { 4, 8 }, + /* 21: IEEE80211_RADIOTAP_VHT */ { 2, 12 }, + /* 22: IEEE80211_RADIOTAP_TIMESTAMP */ { 8, 12 }, }; static const struct ieee80211_radiotap_namespace radiotap_ns = { - .n_bits = ARRAY_SIZE(rtap_namespace_sizes), - .align_size = rtap_namespace_sizes, + rtap_namespace_sizes, + (int)sizeof(rtap_namespace_sizes) / sizeof(rtap_namespace_sizes[0]), + 0, /* oui */ + 0 /* subns */ }; /** @@ -289,9 +221,7 @@ int ieee80211_radiotap_iterator_init( iterator->_bitmap_shifter = get_unaligned_le32(&radiotap_header->it_present); iterator->_arg = (uint8_t *)radiotap_header + sizeof(*radiotap_header); iterator->_reset_on_ext = 0; - iterator->_next_bitmap = - &radiotap_header - ->it_present; // NOLINT(clang-diagnostic-address-of-packed-member) + iterator->_next_bitmap = &radiotap_header->it_present; // NOLINT(clang-diagnostic-address-of-packed-member) iterator->_next_bitmap++; iterator->_vns = vns; iterator->current_namespace = &radiotap_ns; @@ -300,23 +230,14 @@ int ieee80211_radiotap_iterator_init( /* find payload start allowing for extended bitmap(s) */ if (iterator->_bitmap_shifter & (1u << IEEE80211_RADIOTAP_EXT)) { - if ((unsigned long)iterator->_arg - (unsigned long)iterator->_rtheader + - sizeof(uint32_t) > - (unsigned long)iterator->_max_length) + if (((size_t)iterator->_arg - (size_t)iterator->_rtheader) + sizeof(uint32_t) > + (size_t)iterator->_max_length) return -EINVAL; while (get_unaligned_le32(iterator->_arg) & (1u << IEEE80211_RADIOTAP_EXT)) { iterator->_arg += sizeof(uint32_t); - - /* - * check for insanity where the present bitmaps - * keep claiming to extend up to or even beyond the - * stated radiotap header length - */ - - if ((unsigned long)iterator->_arg - (unsigned long)iterator->_rtheader + - sizeof(uint32_t) > - (unsigned long)iterator->_max_length) + if (((size_t)iterator->_arg - (size_t)iterator->_rtheader) + sizeof(uint32_t) > + (size_t)iterator->_max_length) return -EINVAL; } @@ -383,18 +304,16 @@ int ieee80211_radiotap_iterator_next( struct ieee80211_radiotap_iterator *iterator) { while (1) { int hit = 0; - int pad, align, size, subns; + int pad, align = 0, size = 0, subns; uint32_t oui; - /* if no more EXT bits, that's it */ if ((iterator->_arg_index % 32) == IEEE80211_RADIOTAP_EXT && !(iterator->_bitmap_shifter & 1)) return -ENOENT; if (!(iterator->_bitmap_shifter & 1)) - goto next_entry; /* arg not present */ + goto next_entry; - /* get alignment/size of data */ switch (iterator->_arg_index % 32) { case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE: case IEEE80211_RADIOTAP_EXT: @@ -418,47 +337,28 @@ int ieee80211_radiotap_iterator_next( iterator->current_namespace->align_size[iterator->_arg_index].size; } if (!align) { - /* skip all subsequent data */ iterator->_arg = iterator->_next_ns_data; - /* give up on this namespace */ iterator->current_namespace = NULL; goto next_entry; } break; } - /* - * arg is present, account for alignment padding - * - * Note that these alignments are relative to the start - * of the radiotap header. There is no guarantee - * that the radiotap header itself is aligned on any - * kind of boundary. - * - * The above is why get_unaligned() is used to dereference - * multibyte elements from the radiotap area. - */ - - pad = ((unsigned long)iterator->_arg - (unsigned long)iterator->_rtheader) & - (align - 1); - + pad = (((size_t)iterator->_arg - (size_t)iterator->_rtheader) & (align - 1)); if (pad) iterator->_arg += align - pad; if (iterator->_arg_index % 32 == IEEE80211_RADIOTAP_VENDOR_NAMESPACE) { int vnslen; - - if ((unsigned long)iterator->_arg + size - - (unsigned long)iterator->_rtheader > - (unsigned long)iterator->_max_length) + if (((size_t)iterator->_arg + size - (size_t)iterator->_rtheader) > + (size_t)iterator->_max_length) return -EINVAL; - oui = (*iterator->_arg << 16) | (*(iterator->_arg + 1) << 8) | - *(iterator->_arg + 2); - subns = *(iterator->_arg + 3); + oui = (iterator->_arg[0] << 16) | (iterator->_arg[1] << 8) | + iterator->_arg[2]; + subns = iterator->_arg[3]; find_ns(iterator, oui, subns); - vnslen = get_unaligned_le16(iterator->_arg + 4); iterator->_next_ns_data = iterator->_arg + size + vnslen; if (!iterator->current_namespace) @@ -483,11 +383,10 @@ int ieee80211_radiotap_iterator_next( * max_length on the last arg, never exceeding it. */ - if ((unsigned long)iterator->_arg - (unsigned long)iterator->_rtheader > - (unsigned long)iterator->_max_length) + if (((size_t)iterator->_arg - (size_t)iterator->_rtheader) > + (size_t)iterator->_max_length) return -EINVAL; - /* these special ones are valid in each bitmap word */ switch (iterator->_arg_index % 32) { case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: iterator->_reset_on_ext = 1; @@ -536,274 +435,100 @@ int ieee80211_radiotap_iterator_next( } u16 GetSequence(const u8 *packet) { - // 假设Sequence Control位于从第22个字节开始的位置,占两个字节 u16 seqCtrl = (u16)(packet[22]) | (u16)(packet[23] << 8); - // 序列号为seqCtrl的高12位(从0号位开始计数) u16 seqNum = (seqCtrl >> 4) & 0x0FFF; return seqNum; } + u8 MRateToHwRate(u8 rate) { u8 ret = DESC_RATE1M; - switch (rate) { - case MGN_1M: - ret = DESC_RATE1M; - break; - case MGN_2M: - ret = DESC_RATE2M; - break; - case MGN_5_5M: - ret = DESC_RATE5_5M; - break; - case MGN_11M: - ret = DESC_RATE11M; - break; - case MGN_6M: - ret = DESC_RATE6M; - break; - case MGN_9M: - ret = DESC_RATE9M; - break; - case MGN_12M: - ret = DESC_RATE12M; - break; - case MGN_18M: - ret = DESC_RATE18M; - break; - case MGN_24M: - ret = DESC_RATE24M; - break; - case MGN_36M: - ret = DESC_RATE36M; - break; - case MGN_48M: - ret = DESC_RATE48M; - break; - case MGN_54M: - ret = DESC_RATE54M; - break; - - case MGN_MCS0: - ret = DESC_RATEMCS0; - break; - case MGN_MCS1: - ret = DESC_RATEMCS1; - break; - case MGN_MCS2: - ret = DESC_RATEMCS2; - break; - case MGN_MCS3: - ret = DESC_RATEMCS3; - break; - case MGN_MCS4: - ret = DESC_RATEMCS4; - break; - case MGN_MCS5: - ret = DESC_RATEMCS5; - break; - case MGN_MCS6: - ret = DESC_RATEMCS6; - break; - case MGN_MCS7: - ret = DESC_RATEMCS7; - break; - case MGN_MCS8: - ret = DESC_RATEMCS8; - break; - case MGN_MCS9: - ret = DESC_RATEMCS9; - break; - case MGN_MCS10: - ret = DESC_RATEMCS10; - break; - case MGN_MCS11: - ret = DESC_RATEMCS11; - break; - case MGN_MCS12: - ret = DESC_RATEMCS12; - break; - case MGN_MCS13: - ret = DESC_RATEMCS13; - break; - case MGN_MCS14: - ret = DESC_RATEMCS14; - break; - case MGN_MCS15: - ret = DESC_RATEMCS15; - break; - case MGN_MCS16: - ret = DESC_RATEMCS16; - break; - case MGN_MCS17: - ret = DESC_RATEMCS17; - break; - case MGN_MCS18: - ret = DESC_RATEMCS18; - break; - case MGN_MCS19: - ret = DESC_RATEMCS19; - break; - case MGN_MCS20: - ret = DESC_RATEMCS20; - break; - case MGN_MCS21: - ret = DESC_RATEMCS21; - break; - case MGN_MCS22: - ret = DESC_RATEMCS22; - break; - case MGN_MCS23: - ret = DESC_RATEMCS23; - break; - case MGN_MCS24: - ret = DESC_RATEMCS24; - break; - case MGN_MCS25: - ret = DESC_RATEMCS25; - break; - case MGN_MCS26: - ret = DESC_RATEMCS26; - break; - case MGN_MCS27: - ret = DESC_RATEMCS27; - break; - case MGN_MCS28: - ret = DESC_RATEMCS28; - break; - case MGN_MCS29: - ret = DESC_RATEMCS29; - break; - case MGN_MCS30: - ret = DESC_RATEMCS30; - break; - case MGN_MCS31: - ret = DESC_RATEMCS31; - break; - - case MGN_VHT1SS_MCS0: - ret = DESC_RATEVHTSS1MCS0; - break; - case MGN_VHT1SS_MCS1: - ret = DESC_RATEVHTSS1MCS1; - break; - case MGN_VHT1SS_MCS2: - ret = DESC_RATEVHTSS1MCS2; - break; - case MGN_VHT1SS_MCS3: - ret = DESC_RATEVHTSS1MCS3; - break; - case MGN_VHT1SS_MCS4: - ret = DESC_RATEVHTSS1MCS4; - break; - case MGN_VHT1SS_MCS5: - ret = DESC_RATEVHTSS1MCS5; - break; - case MGN_VHT1SS_MCS6: - ret = DESC_RATEVHTSS1MCS6; - break; - case MGN_VHT1SS_MCS7: - ret = DESC_RATEVHTSS1MCS7; - break; - case MGN_VHT1SS_MCS8: - ret = DESC_RATEVHTSS1MCS8; - break; - case MGN_VHT1SS_MCS9: - ret = DESC_RATEVHTSS1MCS9; - break; - case MGN_VHT2SS_MCS0: - ret = DESC_RATEVHTSS2MCS0; - break; - case MGN_VHT2SS_MCS1: - ret = DESC_RATEVHTSS2MCS1; - break; - case MGN_VHT2SS_MCS2: - ret = DESC_RATEVHTSS2MCS2; - break; - case MGN_VHT2SS_MCS3: - ret = DESC_RATEVHTSS2MCS3; - break; - case MGN_VHT2SS_MCS4: - ret = DESC_RATEVHTSS2MCS4; - break; - case MGN_VHT2SS_MCS5: - ret = DESC_RATEVHTSS2MCS5; - break; - case MGN_VHT2SS_MCS6: - ret = DESC_RATEVHTSS2MCS6; - break; - case MGN_VHT2SS_MCS7: - ret = DESC_RATEVHTSS2MCS7; - break; - case MGN_VHT2SS_MCS8: - ret = DESC_RATEVHTSS2MCS8; - break; - case MGN_VHT2SS_MCS9: - ret = DESC_RATEVHTSS2MCS9; - break; - case MGN_VHT3SS_MCS0: - ret = DESC_RATEVHTSS3MCS0; - break; - case MGN_VHT3SS_MCS1: - ret = DESC_RATEVHTSS3MCS1; - break; - case MGN_VHT3SS_MCS2: - ret = DESC_RATEVHTSS3MCS2; - break; - case MGN_VHT3SS_MCS3: - ret = DESC_RATEVHTSS3MCS3; - break; - case MGN_VHT3SS_MCS4: - ret = DESC_RATEVHTSS3MCS4; - break; - case MGN_VHT3SS_MCS5: - ret = DESC_RATEVHTSS3MCS5; - break; - case MGN_VHT3SS_MCS6: - ret = DESC_RATEVHTSS3MCS6; - break; - case MGN_VHT3SS_MCS7: - ret = DESC_RATEVHTSS3MCS7; - break; - case MGN_VHT3SS_MCS8: - ret = DESC_RATEVHTSS3MCS8; - break; - case MGN_VHT3SS_MCS9: - ret = DESC_RATEVHTSS3MCS9; - break; - case MGN_VHT4SS_MCS0: - ret = DESC_RATEVHTSS4MCS0; - break; - case MGN_VHT4SS_MCS1: - ret = DESC_RATEVHTSS4MCS1; - break; - case MGN_VHT4SS_MCS2: - ret = DESC_RATEVHTSS4MCS2; - break; - case MGN_VHT4SS_MCS3: - ret = DESC_RATEVHTSS4MCS3; - break; - case MGN_VHT4SS_MCS4: - ret = DESC_RATEVHTSS4MCS4; - break; - case MGN_VHT4SS_MCS5: - ret = DESC_RATEVHTSS4MCS5; - break; - case MGN_VHT4SS_MCS6: - ret = DESC_RATEVHTSS4MCS6; - break; - case MGN_VHT4SS_MCS7: - ret = DESC_RATEVHTSS4MCS7; - break; - case MGN_VHT4SS_MCS8: - ret = DESC_RATEVHTSS4MCS8; - break; - case MGN_VHT4SS_MCS9: - ret = DESC_RATEVHTSS4MCS9; - break; - default: - break; + case MGN_1M: ret = DESC_RATE1M; break; + case MGN_2M: ret = DESC_RATE2M; break; + case MGN_5_5M: ret = DESC_RATE5_5M; break; + case MGN_11M: ret = DESC_RATE11M; break; + case MGN_6M: ret = DESC_RATE6M; break; + case MGN_9M: ret = DESC_RATE9M; break; + case MGN_12M: ret = DESC_RATE12M; break; + case MGN_18M: ret = DESC_RATE18M; break; + case MGN_24M: ret = DESC_RATE24M; break; + case MGN_36M: ret = DESC_RATE36M; break; + case MGN_48M: ret = DESC_RATE48M; break; + case MGN_54M: ret = DESC_RATE54M; break; + case MGN_MCS0: ret = DESC_RATEMCS0; break; + case MGN_MCS1: ret = DESC_RATEMCS1; break; + case MGN_MCS2: ret = DESC_RATEMCS2; break; + case MGN_MCS3: ret = DESC_RATEMCS3; break; + case MGN_MCS4: ret = DESC_RATEMCS4; break; + case MGN_MCS5: ret = DESC_RATEMCS5; break; + case MGN_MCS6: ret = DESC_RATEMCS6; break; + case MGN_MCS7: ret = DESC_RATEMCS7; break; + case MGN_MCS8: ret = DESC_RATEMCS8; break; + case MGN_MCS9: ret = DESC_RATEMCS9; break; + case MGN_MCS10: ret = DESC_RATEMCS10; break; + case MGN_MCS11: ret = DESC_RATEMCS11; break; + case MGN_MCS12: ret = DESC_RATEMCS12; break; + case MGN_MCS13: ret = DESC_RATEMCS13; break; + case MGN_MCS14: ret = DESC_RATEMCS14; break; + case MGN_MCS15: ret = DESC_RATEMCS15; break; + case MGN_MCS16: ret = DESC_RATEMCS16; break; + case MGN_MCS17: ret = DESC_RATEMCS17; break; + case MGN_MCS18: ret = DESC_RATEMCS18; break; + case MGN_MCS19: ret = DESC_RATEMCS19; break; + case MGN_MCS20: ret = DESC_RATEMCS20; break; + case MGN_MCS21: ret = DESC_RATEMCS21; break; + case MGN_MCS22: ret = DESC_RATEMCS22; break; + case MGN_MCS23: ret = DESC_RATEMCS23; break; + case MGN_MCS24: ret = DESC_RATEMCS24; break; + case MGN_MCS25: ret = DESC_RATEMCS25; break; + case MGN_MCS26: ret = DESC_RATEMCS26; break; + case MGN_MCS27: ret = DESC_RATEMCS27; break; + case MGN_MCS28: ret = DESC_RATEMCS28; break; + case MGN_MCS29: ret = DESC_RATEMCS29; break; + case MGN_MCS30: ret = DESC_RATEMCS30; break; + case MGN_MCS31: ret = DESC_RATEMCS31; break; + case MGN_VHT1SS_MCS0: ret = DESC_RATEVHTSS1MCS0; break; + case MGN_VHT1SS_MCS1: ret = DESC_RATEVHTSS1MCS1; break; + case MGN_VHT1SS_MCS2: ret = DESC_RATEVHTSS1MCS2; break; + case MGN_VHT1SS_MCS3: ret = DESC_RATEVHTSS1MCS3; break; + case MGN_VHT1SS_MCS4: ret = DESC_RATEVHTSS1MCS4; break; + case MGN_VHT1SS_MCS5: ret = DESC_RATEVHTSS1MCS5; break; + case MGN_VHT1SS_MCS6: ret = DESC_RATEVHTSS1MCS6; break; + case MGN_VHT1SS_MCS7: ret = DESC_RATEVHTSS1MCS7; break; + case MGN_VHT1SS_MCS8: ret = DESC_RATEVHTSS1MCS8; break; + case MGN_VHT1SS_MCS9: ret = DESC_RATEVHTSS1MCS9; break; + case MGN_VHT2SS_MCS0: ret = DESC_RATEVHTSS2MCS0; break; + case MGN_VHT2SS_MCS1: ret = DESC_RATEVHTSS2MCS1; break; + case MGN_VHT2SS_MCS2: ret = DESC_RATEVHTSS2MCS2; break; + case MGN_VHT2SS_MCS3: ret = DESC_RATEVHTSS2MCS3; break; + case MGN_VHT2SS_MCS4: ret = DESC_RATEVHTSS2MCS4; break; + case MGN_VHT2SS_MCS5: ret = DESC_RATEVHTSS2MCS5; break; + case MGN_VHT2SS_MCS6: ret = DESC_RATEVHTSS2MCS6; break; + case MGN_VHT2SS_MCS7: ret = DESC_RATEVHTSS2MCS7; break; + case MGN_VHT2SS_MCS8: ret = DESC_RATEVHTSS2MCS8; break; + case MGN_VHT2SS_MCS9: ret = DESC_RATEVHTSS2MCS9; break; + case MGN_VHT3SS_MCS0: ret = DESC_RATEVHTSS3MCS0; break; + case MGN_VHT3SS_MCS1: ret = DESC_RATEVHTSS3MCS1; break; + case MGN_VHT3SS_MCS2: ret = DESC_RATEVHTSS3MCS2; break; + case MGN_VHT3SS_MCS3: ret = DESC_RATEVHTSS3MCS3; break; + case MGN_VHT3SS_MCS4: ret = DESC_RATEVHTSS3MCS4; break; + case MGN_VHT3SS_MCS5: ret = DESC_RATEVHTSS3MCS5; break; + case MGN_VHT3SS_MCS6: ret = DESC_RATEVHTSS3MCS6; break; + case MGN_VHT3SS_MCS7: ret = DESC_RATEVHTSS3MCS7; break; + case MGN_VHT3SS_MCS8: ret = DESC_RATEVHTSS3MCS8; break; + case MGN_VHT3SS_MCS9: ret = DESC_RATEVHTSS3MCS9; break; + case MGN_VHT4SS_MCS0: ret = DESC_RATEVHTSS4MCS0; break; + case MGN_VHT4SS_MCS1: ret = DESC_RATEVHTSS4MCS1; break; + case MGN_VHT4SS_MCS2: ret = DESC_RATEVHTSS4MCS2; break; + case MGN_VHT4SS_MCS3: ret = DESC_RATEVHTSS4MCS3; break; + case MGN_VHT4SS_MCS4: ret = DESC_RATEVHTSS4MCS4; break; + case MGN_VHT4SS_MCS5: ret = DESC_RATEVHTSS4MCS5; break; + case MGN_VHT4SS_MCS6: ret = DESC_RATEVHTSS4MCS6; break; + case MGN_VHT4SS_MCS7: ret = DESC_RATEVHTSS4MCS7; break; + case MGN_VHT4SS_MCS8: ret = DESC_RATEVHTSS4MCS8; break; + case MGN_VHT4SS_MCS9: ret = DESC_RATEVHTSS4MCS9; break; + default: break; } - return ret; } @@ -820,14 +545,16 @@ int parse_radiotap() { u8 fixed_rate = MGN_1M, sgi = 0, bwidth = 0, ldpc = 0, stbc = 0; u16 txflags = 0; + /* This packet is only 13 bytes long. + We add an explicit cast to silence the warning. */ uint8_t pkt[] = { 0x00, 0x00, 0x0d, 0x00, 0x00, 0x80, 0x08, 0x00, 0x08, 0x00, 0x37, 0x00, 0x01, }; struct ieee80211_radiotap_header *rtap_hdr; - rtap_hdr = (struct ieee80211_radiotap_header *)pkt; + rtap_hdr = (struct ieee80211_radiotap_header *)(void *)pkt; struct ieee80211_radiotap_iterator iterator; - ret = ieee80211_radiotap_iterator_init(&iterator, pkt, 0x0d, NULL); + ret = ieee80211_radiotap_iterator_init(&iterator, rtap_hdr, 0x0d, NULL); while (!ret) { ret = ieee80211_radiotap_iterator_next(&iterator); @@ -906,6 +633,6 @@ int parse_radiotap() { } printf("fixed rate:%d\n", fixed_rate); - printf("sgi =%d,bandwdith=%d,ldpc=%d,stbc=%d\n", sgi, bwidth, ldpc, stbc); + printf("sgi =%d, bandwdith=%d, ldpc=%d, stbc=%d\n", sgi, bwidth, ldpc, stbc); return 1; } diff --git a/src/RtlUsbAdapter.cpp b/src/RtlUsbAdapter.cpp index acbe723..2c9211f 100644 --- a/src/RtlUsbAdapter.cpp +++ b/src/RtlUsbAdapter.cpp @@ -1,7 +1,7 @@ #include "RtlUsbAdapter.h" #include -#ifdef __ANDROID__ +#if defined(__ANDROID__) || defined(_MSC_VER) #include #else #include diff --git a/txdemo/main.cpp b/txdemo/main.cpp index 1618559..8333e13 100644 --- a/txdemo/main.cpp +++ b/txdemo/main.cpp @@ -3,13 +3,19 @@ #include #include -#ifdef __ANDROID__ +#if defined(_MSC_VER) + #include + #include + typedef int pid_t; + #define fork() (0) + #define sleep(seconds) Sleep((seconds)*1000) +#elif defined(__ANDROID__) + // On Android, include the libusb header as required. #include #else #include #endif - #include "FrameParser.h" #include "RtlUsbAdapter.h" #include "WiFiDriver.h" @@ -17,6 +23,7 @@ #include + // #define USB_VENDOR_ID 0x0bda // #define USB_PRODUCT_ID 0x8812