[Xiaomi Redmi Note 3 Guides, News, & Discussion] cerg2010cerg2010:
OK, I don't think this thread will get any attention, but I want to document it anyway. All this should work on other devices with qcom WiFi drivers.

TL;DR:

Grab iwpriv binary somewhere (i've got my here: https://github.com/kriswebdev/android_wireless_tools/tree/master/bin)

adb push iwpriv /data/local/tmp/

adb shell su -c chmod +x /data/local/tmp/iwpriv

#!/system/bin/sh
ip link set wlan0 down
sleep 1
echo 4 > /sys/module/wlan/parameters/con_mode
sleep 2
ip link set wlan0 up
/data/local/tmp/iwpriv wlan0 monitor 1
/data/local/tmp/iwpriv wlan0 MonitorModeConf 9 40 1 111 0

And enjoy your airodump output ;)

NO PACKET INJECTION! (stubbed out in driver, removed previously?)

If you don't receive any packets, issue "/data/local/tmp/iwpriv wlan0 monitor 1" again.

How does this all work?

Some time ago I discovered these strings in wlan_hal_msg.h: (they appeared in google):

...
/* Monitor Mode */
WLAN_HAL_ENABLE_MONITOR_MODE_REQ = 302,
WLAN_HAL_ENABLE_MONITOR_MODE_RSP = 303,

WLAN_HAL_DISABLE_MONITOR_MODE_REQ = 304,
WLAN_HAL_DISABLE_MONITOR_MODE_RSP = 305,
...

Then I unscrambled some indirections:

WLAN_HAL_ENABLE_MONITOR_MODE_REQ to WDI_MON_START_REQ in WDI_2_HAL_REQ_TYPE

WDI_MON_START_REQ sent in WDI_ProcessMonStartReq <— actual message sents here!

Called from "Request Processing Array" in function WDI_MonStartReq

Wrapped in WDA_ProcessMonStartReq, which is called in WDA_McProcessMsg by message WDA_MON_START_REQ

Which message is posted by wlan_hdd_mon_postMsg if (MON_MODE_START == pMonCtx->state)

Which is called in __iw_setint_getnone with sub_cmd = WE_SET_MONITOR_STATE

Which is set by iw_priv cmd "monitor"

And then figured out that driver works in different modes:

(vos_types.h)

/// Concurrency role. These are generic IDs that identify the various roles
/// in the software system.
typedef enum
{ /*ON linux maintain 1-1 corespondence with device_mode_t in hdd*/
VOS_STA_MODE=0,
VOS_STA_SAP_MODE=1, //to support softAp mode . This is misleading. It means AP MODE only.
//The constant name has historical reason
VOS_P2P_CLIENT_MODE,
VOS_P2P_GO_MODE,
VOS_MONITOR_MODE,
VOS_FTM_MODE = 5,
VOS_IBSS_MODE,
VOS_P2P_DEVICE,
VOS_MAX_NO_OF_MODE
} tVOS_CON_MODE;

Mode can be changed by "con_mode" module parameter.

(idk why they reinvented the wheel and not used the default "iw dev wlan0 set mode monitor")

Combined all this and... got a kernel panic. You may get it too. Main reasons are:

- You have not disabled WiFi before changing the mode

- The sleep time after disabling interface is short

- Driver is old. Yes, you can get crashes on some kernels. If you are, flash AGNi.

After successful switching you'll get a working monitor (check this with tcpdump -i wlan0), but with ethernet packets instead of radiotap, so airodump will not work. Luckily, this giant crappy driver can work with radiotap, but you need to configure it. This is done by another iwpriv call:

MonitorModeConf: <channel> <bandwidth> <crccheck> <filter> <conversion_required>

Filter: 3 decimal numbers

least to most: management packets, control packets, data packets

Conversion: 1 - ARPHRD_ETHER (802.3 packets), 0 - ARPHRD_IEEE80211_RADIOTAP (802.11 packets)

(again don't know why they implemented these calls instead of default ioctl's for channel switch, etc. This makes airodump unable to switch channels)

As a result you may get something like on a screenshot :)

Happy sniffing!