1- // Query WiFi HAL for chip info and AP interface state .
1+ // Query WiFi information from the wificond system service .
22//
3- // This example shows how to interact with the WiFi HAL to query chip
4- // capabilities, list AP interfaces, and get AP interface details.
5- // The WiFi HAL controls the low-level WiFi driver and is the foundation
6- // for both STA (client) and AP (hotspot) modes.
7- //
8- // The generated code returns typed interfaces (IWifiChip, IWifiApIface)
9- // directly from method calls — no manual proxy construction needed for
10- // sub-objects.
11- //
12- // Note: The WiFi HAL is only available on devices with real WiFi hardware.
3+ // Uses IWificond via the "wifinl80211" service to list WiFi interfaces,
4+ // available channels per band, and PHY capabilities.
135//
146// Build:
157//
16- // GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o build/softap_wifi_hal ./examples/softap_wifi_hal/
8+ // GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o build/softap_wifi_hal ./examples/softap_wifi_hal/
179// adb push softap_wifi_hal /data/local/tmp/ && adb shell /data/local/tmp/softap_wifi_hal
1810package main
1911
@@ -22,15 +14,13 @@ import (
2214 "fmt"
2315 "os"
2416
17+ "github.com/xaionaro-go/binder/android/net/wifi/nl80211"
2518 "github.com/xaionaro-go/binder/binder"
2619 "github.com/xaionaro-go/binder/binder/versionaware"
27- "github.com/xaionaro-go/binder/android/hardware/wifi"
2820 "github.com/xaionaro-go/binder/kernelbinder"
2921 "github.com/xaionaro-go/binder/servicemanager"
3022)
3123
32- const wifiHalService = servicemanager .ServiceName ("android.hardware.wifi.IWifi/default" )
33-
3424func main () {
3525 ctx := context .Background ()
3626
@@ -49,116 +39,88 @@ func main() {
4939
5040 sm := servicemanager .New (transport )
5141
52- svc , err := sm .GetService (ctx , wifiHalService )
42+ svc , err := sm .GetService (ctx , servicemanager . WifiNl80211Service )
5343 if err != nil {
54- fmt .Fprintf (os .Stderr , "get WiFi HAL : %v\n " , err )
55- fmt .Fprintf (os .Stderr , "(WiFi HAL not available — no WiFi hardware or SELinux denial )\n " )
44+ fmt .Fprintf (os .Stderr , "get wifinl80211 service : %v\n " , err )
45+ fmt .Fprintf (os .Stderr , "(wificond not available or access denied by SELinux)\n " )
5646 os .Exit (1 )
5747 }
5848
59- wifiHal := wifi . NewWifiProxy (svc )
49+ wificond := nl80211 . NewWificondProxy (svc )
6050
61- // Check if WiFi is started .
62- started , err := wifiHal . IsStarted (ctx )
51+ // List client (STA) interfaces .
52+ clientIfaces , err := wificond . GetClientInterfaces (ctx )
6353 if err != nil {
64- fmt .Fprintf (os .Stderr , "IsStarted: %v\n " , err )
65- fmt .Fprintf (os .Stderr , "(WiFi HAL may have died or access may be restricted by SELinux)\n " )
54+ fmt .Fprintf (os .Stderr , "GetClientInterfaces: %v\n " , err )
6655 } else {
67- fmt .Printf ("WiFi HAL started: %v\n " , started )
56+ fmt .Printf ("Client interfaces: %d\n " , len (clientIfaces ))
57+ for i , iface := range clientIfaces {
58+ fmt .Printf (" [%d] binder handle present\n " , i )
59+ _ = iface // IBinder handles
60+ }
6861 }
6962
70- // List available WiFi chips .
71- chipIds , err := wifiHal . GetChipIds (ctx )
63+ // List AP interfaces .
64+ apIfaces , err := wificond . GetApInterfaces (ctx )
7265 if err != nil {
73- fmt .Fprintf (os .Stderr , "GetChipIds: %v (WiFi HAL may have died or access may be restricted by SELinux)\n " , err )
74- return
75- }
76-
77- fmt .Printf ("WiFi chips: %v\n \n " , chipIds )
78-
79- for _ , chipId := range chipIds {
80- printChipInfo (ctx , wifiHal , chipId )
66+ fmt .Fprintf (os .Stderr , "GetApInterfaces: %v\n " , err )
67+ } else {
68+ fmt .Printf ("AP interfaces: %d\n " , len (apIfaces ))
69+ for i , iface := range apIfaces {
70+ fmt .Printf (" [%d] binder handle present\n " , i )
71+ _ = iface
72+ }
8173 }
82- }
83-
84- func printChipInfo (
85- ctx context.Context ,
86- wifiHal wifi.IWifi ,
87- chipId int32 ,
88- ) {
89- fmt .Printf ("=== Chip %d ===\n " , chipId )
9074
91- // GetChip returns IWifiChip directly — the generated proxy
92- // handles binder handle acquisition internally.
93- chip , err := wifiHal . GetChip (ctx , chipId )
75+ // Available 2.4 GHz channels.
76+ fmt . Println ()
77+ ch2g , err := wificond . GetAvailable2gChannels (ctx )
9478 if err != nil {
95- fmt .Fprintf (os .Stderr , " GetChip(%d): %v\n " , chipId , err )
96- return
79+ fmt .Fprintf (os .Stderr , "GetAvailable2gChannels: %v\n " , err )
80+ } else {
81+ fmt .Printf ("Available 2.4 GHz channels: %v\n " , ch2g )
9782 }
9883
99- // Get feature set bitmask .
100- features , err := chip . GetFeatureSet (ctx )
84+ // Available 5 GHz non-DFS channels .
85+ ch5g , err := wificond . GetAvailable5gNonDFSChannels (ctx )
10186 if err != nil {
102- fmt .Fprintf (os .Stderr , " GetFeatureSet : %v\n " , err )
87+ fmt .Fprintf (os .Stderr , "GetAvailable5gNonDFSChannels : %v\n " , err )
10388 } else {
104- fmt .Printf (" Feature set: 0x%x \n " , features )
89+ fmt .Printf ("Available 5 GHz (non-DFS) channels: %v \n " , ch5g )
10590 }
10691
107- chipId2 , err := chip .GetId (ctx )
92+ // Available DFS channels.
93+ chDFS , err := wificond .GetAvailableDFSChannels (ctx )
10894 if err != nil {
109- fmt .Fprintf (os .Stderr , " GetId : %v\n " , err )
95+ fmt .Fprintf (os .Stderr , "GetAvailableDFSChannels : %v\n " , err )
11096 } else {
111- fmt .Printf (" Chip ID : %d \n " , chipId2 )
97+ fmt .Printf ("Available DFS channels : %v \n " , chDFS )
11298 }
11399
114- // List AP interfaces — these are the SoftAP interfaces.
115- apNames , err := chip .GetApIfaceNames (ctx )
116- switch {
117- case err != nil :
118- fmt .Fprintf (os .Stderr , " GetApIfaceNames: %v\n " , err )
119- case len (apNames ) == 0 :
120- fmt .Printf (" AP interfaces: (none — no hotspot active)\n " )
121- default :
122- fmt .Printf (" AP interfaces:\n " )
123- for _ , name := range apNames {
124- printApIfaceInfo (ctx , chip , name )
125- }
126- }
127-
128- // List STA interfaces for context.
129- staNames , err := chip .GetStaIfaceNames (ctx )
100+ // Available 6 GHz channels.
101+ ch6g , err := wificond .GetAvailable6gChannels (ctx )
130102 if err != nil {
131- fmt .Fprintf (os .Stderr , " GetStaIfaceNames : %v\n " , err )
103+ fmt .Fprintf (os .Stderr , "GetAvailable6gChannels : %v\n " , err )
132104 } else {
133- fmt .Printf (" STA interfaces : %v\n " , staNames )
105+ fmt .Printf ("Available 6 GHz channels : %v\n " , ch6g )
134106 }
135- }
136-
137- func printApIfaceInfo (
138- ctx context.Context ,
139- chip wifi.IWifiChip ,
140- name string ,
141- ) {
142- fmt .Printf (" - %s\n " , name )
143107
144- // GetApIface returns IWifiApIface directly .
145- apIface , err := chip . GetApIface (ctx , name )
108+ // Available 60 GHz channels .
109+ ch60g , err := wificond . GetAvailable60gChannels (ctx )
146110 if err != nil {
147- fmt .Fprintf (os .Stderr , " GetApIface(%s): %v\n " , name , err )
148- return
149- }
150-
151- ifName , _ := apIface .GetName (ctx )
152- fmt .Printf (" Name: %s\n " , ifName )
153-
154- mac , err := apIface .GetFactoryMacAddress (ctx )
155- if err == nil {
156- fmt .Printf (" Factory MAC: %x\n " , mac )
111+ fmt .Fprintf (os .Stderr , "GetAvailable60gChannels: %v\n " , err )
112+ } else {
113+ fmt .Printf ("Available 60 GHz channels: %v\n " , ch60g )
157114 }
158115
159- bridged , err := apIface .GetBridgedInstances (ctx )
160- if err == nil && len (bridged ) > 0 {
161- fmt .Printf (" Bridged instances: %v\n " , bridged )
116+ // PHY capabilities for common interface names.
117+ fmt .Println ()
118+ for _ , ifName := range []string {"wlan0" , "wlan1" , "wlan2" } {
119+ caps , err := wificond .GetDeviceWiphyCapabilities (ctx , ifName )
120+ if err != nil {
121+ fmt .Fprintf (os .Stderr , "GetDeviceWiphyCapabilities(%s): %v\n " , ifName , err )
122+ continue
123+ }
124+ fmt .Printf ("PHY capabilities for %s: %+v\n " , ifName , caps )
162125 }
163-
164126}
0 commit comments