Compare commits

...

55 Commits

Author SHA1 Message Date
7u83 5423709dda Removed libwifi dependencies 2022-09-20 10:35:23 +02:00
7u83 e974b3ae2d Work on wifi implemntation 2022-09-20 08:31:04 +02:00
7u83 07257f51fe Removed 2022-09-18 23:36:34 +02:00
7u83 dec1cf2003 Fixed missing hexdum for elems with "elem_dmp" 2022-09-18 23:14:22 +02:00
7u83 40427b3816 Use correct len for last fragmented packet 2022-09-18 18:06:53 +02:00
7u83 435b3f823e Correct fragment handling when sendig fragmented packets 2022-09-18 08:53:49 +02:00
7u83 ae686f4634 new funtion to send CAPWAP packets 2022-09-18 08:04:49 +02:00
7u83 b292b88d49 More dot11 stuff added 2022-09-15 07:47:41 +02:00
7u83 97533f67cc some stuff for dot11 handling added 2022-09-13 08:18:05 +02:00
7u83 259c6c5e66 Work on data channel 2022-09-12 00:28:58 +02:00
7u83 bc5dea6016 script to download and extract hostapd 2022-09-07 16:40:24 +02:00
7u83 ec6809b552 Work on data channel 2022-09-06 09:16:10 +02:00
7u83 1297c46a15 Removed netcon 2022-09-04 21:41:23 +02:00
7u83 cc257ed27f Fragman preserves packet header 2022-09-04 21:40:08 +02:00
7u83 059c0e542e Added verbosity for ap-mode 2022-09-04 21:38:22 +02:00
7u83 9d3fa452aa Fix: Add brackets around defined value 2022-09-04 18:43:17 +02:00
7u83 300b737efd Better formatting 2022-09-04 14:00:43 +02:00
7u83 085e657c76 Updated what you can do so far 2022-09-04 13:47:51 +02:00
7u83 f62b1c56e1 Added some (test) macros to git 2022-09-04 13:29:15 +02:00
7u83 acc7b692ee Deleted out-commented and unused code 2022-09-04 13:23:27 +02:00
7u83 8a8381731f fixed typo 2022-09-04 12:31:19 +02:00
7u83 6f4ba62080 actube -h shows some help about debug levels 2022-09-04 12:30:08 +02:00
7u83 0eb3e16932 Moved debug options into a mavl object
So there is an unlimited number of debug options, instead of 32 as
before.
2022-09-04 11:13:12 +02:00
7u83 ca4a6b9996 Ununsed stuff 2022-09-04 08:29:37 +02:00
7u83 66db979fdb New type cw_type_bits 2022-09-03 17:27:19 +02:00
7u83 0078c07e58 'CFG atcher' in wtpman 2022-09-02 12:03:38 +02:00
7u83 20bd835f63 Fixed size of led state config >= v7.3 2022-09-02 02:15:32 +02:00
7u83 1e8b52fd03 Moved Cisco ssl cfg stuff to mod/cisco 2022-09-02 02:00:43 +02:00
7u83 2f1985b821 Example WLAN definition 2022-09-02 01:51:38 +02:00
7u83 27506fa788 We can join an 1131 AP, and bring up a WLAN
data channel is currently missing
2022-09-01 23:09:33 +02:00
7u83 5ed35979cd Moved Callbacks to mods 2022-09-01 10:24:40 +02:00
7u83 2064f7dba1 put out a correct WTP Descriptor, even if no data is available 2022-08-30 22:13:22 +02:00
7u83 190c94ded4 Work on wtp descriptor CAPWAP 2022-08-30 20:25:55 +02:00
7u83 4fe2bae7f7 Deleted unused .ktv 2022-08-30 14:56:26 +02:00
7u83 89e7e61e1d Fixed some bugs, added more Cisco elements
Almost able to create a WLAN
2022-08-30 08:52:18 +02:00
7u83 2b055175c7 Uses DTLS_timer_cb to work with old APs 2022-08-29 21:29:11 +02:00
7u83 0ebac6c98e Cisco ht-caps can be parsed 2022-08-28 21:21:21 +02:00
7u83 15e363f34e Read SIG Payload and more cisco elements 2022-08-28 16:19:49 +02:00
7u83 2b6dc68ee5 Some macros added 2022-08-28 13:14:35 +02:00
7u83 e39f4eb097 load and save cmds are added 2022-08-28 13:10:36 +02:00
7u83 4ef1b69f83 Fixes in RPC 2022-08-28 11:42:11 +02:00
7u83 a77023165b Added lots of RPC cmds added. send is possible. 2022-08-28 09:06:15 +02:00
7u83 62616b5e7b New array type 2022-08-27 21:05:34 +02:00
7u83 79b688c38e Fixed seg fault when mods for some reason fail fail to load. 2022-08-27 10:40:13 +02:00
7u83 4995cac9b8 WTP reads two configs no
It read 1st the file startup.ckv, wich will
never be overwritten.
And then config.ckv, wich will saved when
ever config cahnges ar made.
2022-08-27 10:16:49 +02:00
7u83 d7c826fac6 Removed 2022-08-27 10:16:35 +02:00
7u83 d668e0e5a7 Initial commit 2022-08-27 10:15:36 +02:00
7u83 63cb0b928f Added comments 2022-08-27 10:05:02 +02:00
7u83 361e9dd1aa Removed radioinfo.h 2022-08-27 01:03:33 +02:00
7u83 3f69dbf67e More clean-up 2022-08-27 00:50:59 +02:00
7u83 43b75502f7 Fix: removed cw_in_generic_struct from Makefile 2022-08-27 00:45:08 +02:00
7u83 4a565efff1 Removed a lot of old stuff, compiles almost w/o warnings 2022-08-27 00:41:47 +02:00
7u83 54955daff4 More Cisco Elements decoded 2022-08-27 00:24:20 +02:00
7u83 4047707fa8 Unused files 2022-08-26 21:22:18 +02:00
7u83 5b1690bfbf Cisco RRM element implemented 2022-08-26 21:12:39 +02:00
145 changed files with 4440 additions and 5490 deletions

View File

@ -15,7 +15,6 @@ cd ..
make
Ubuntu
------

View File

@ -2,6 +2,62 @@ AC-Tube
=======
Open Source CAPWAP WLC + WTP
Current status: early development.
Current status: development.
See also http://7u83.cauwersin.com/?cat=28
What you can do so far ...
Read INSTALL and compile actube.
Then ...
Create certificates:
cd ssl
sh all.sh
cd ..
Edit src/actube/config.ckv and set your IP in
capwap/control-ip-address/address.0
Start actube with some debug options:
cd src/ac
./actube -d std -d mod -d elem\_detail -d elem\_dmp
If you have an AP with IOS 7.3x it should connect. Others
might connect, too.
Make sure on the AP you heve made
clear capwap private-config.
In another terminal window connect to the RPC interface:
cd src/ac
./act -s 127.0.0.1:5000
Send some commands to bring up a WLAN:
list # list all connected APs
select <apname> # set <apname> to the name of AP you want to select
status # show status of selected AP
# the following sequence activates a WLAN called actube on AP
load wlan1
send
clear
load activate
send
status # This should display now oper status for
# interface 0 enabled
CWAPWAP data layer is still not finished, so you can't use the WLAN

View File

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<CodeLite_Workspace Name="actube" Database="">
<Project Name="ac" Path="ac.project" Active="No"/>
<Project Name="wtp" Path="wtp.project" Active="No"/>
<Project Name="mod_cipwap" Path="mod_cipwap.project" Active="No"/>
<Project Name="mod_capwap" Path="mod_capwap.project" Active="No"/>
<Project Name="mod_cisco" Path="mod_cisco.project" Active="Yes"/>
<Project Name="libcw" Path="libcw.project" Active="No"/>
<Project Name="mod_capwap80211" Path="mod_capwap80211.project" Active="No"/>
<Project Name="mod_fortinet" Path="mod_fortinet.project" Active="No"/>
<BuildMatrix>
<WorkspaceConfiguration Name="Debug" Selected="yes">
<Environment/>
<Project Name="ac" ConfigName="Debug"/>
<Project Name="wtp" ConfigName="Debug"/>
<Project Name="mod_cipwap" ConfigName="Debug"/>
<Project Name="mod_capwap" ConfigName="Debug"/>
<Project Name="mod_cisco" ConfigName="Debug"/>
<Project Name="libcw" ConfigName="Debug"/>
<Project Name="mod_capwap80211" ConfigName="Debug"/>
<Project Name="mod_fortinet" ConfigName="Debug"/>
</WorkspaceConfiguration>
<WorkspaceConfiguration Name="Release" Selected="yes">
<Environment/>
<Project Name="ac" ConfigName="Release"/>
<Project Name="wtp" ConfigName="Release"/>
<Project Name="mod_cipwap" ConfigName="Release"/>
<Project Name="mod_capwap" ConfigName="Release"/>
<Project Name="mod_cisco" ConfigName="Release"/>
<Project Name="libcw" ConfigName="Release"/>
<Project Name="mod_capwap80211" ConfigName="Release"/>
<Project Name="mod_fortinet" ConfigName="Release"/>
</WorkspaceConfiguration>
</BuildMatrix>
</CodeLite_Workspace>

View File

@ -9,6 +9,7 @@ OBJS = \
discovery_cache.o\
rpc.o\
statemachine.o\
#hapd.o
ACTOBJS = \
act.o
@ -26,13 +27,18 @@ LIBS+=-lnettle
LIBS+=-lssl
LIBS+=-lcrypto
LIBS+=-ledit
#LIBS+=-l:libhapd.a
INCL_DIRS=-I../ -I/usr/local/include -I./ -I../../include
INCL_DIRS=-I../ -I/usr/local/include -I./ -I../../include -I../../include/hostapd -I../../include/hostapd/utils
#FLAGS=-DWITH_IPV6 -DWITH_OPENSSL -DSYS_ARCH="$(ARCH)" -DSYS_ARCH="XXX"
FLAGS=-DWITH_IPV6 -DUSE_OPENSSL -DSYS_ARCH='"$(KERNEL)/$(ARCH)"'
all: act actube
act: act.c
$(CC) act.c $(INCL_DIRS) $(LIBPATH) -DSYS_ARCH='"$(KERNEL)/$(ARCH)"' -o act -l:libcw.a -lasan -lcrypto -ledit
.c.o:
@echo " $(CC) "$<
@ -43,8 +49,9 @@ all: $(PRG) $(ACTPRG)
$(PRG): $(OBJS)
$(CC) $(OBJS) -o $(PRG) $(LIBPATH) $(LDFLAGS) $(LIBS)
$(ACTPRG): $(ACTOBJS)
$(CC) $(ACTOBJS) -o $(ACTPRG) $(LIBPATH) $(LDFLAGS) $(LIBS) -ledit
#$(ACTPRG): $(ACTOBJS)
# $(CC) $(ACTOBJS) -o $(ACTPRG) $(LIBPATH) $(LIBS) -ledit
#$(CC) $(ACTOBJS) $(ACTPRG) $(LIBPATH) $(LDFLAGS) $(LIBS) -ledit

View File

@ -20,6 +20,7 @@ enum {
int start_rpc(cw_Cfg_t *global_cfg);
int test_shell();
void hapd_run();
#endif

View File

@ -124,10 +124,21 @@ static int parse_args (int argc, char *argv[], struct bootcfg * bootcfg)
case '?':
exit(EXIT_FAILURE);
default:
case 'h':
printf("%s: -vcmh\n",argv[0]);
case 'h':
{
FILE *out = stdout;
fprintf(out, "Usage:");
fprintf(out, "%s [ options ] ",argv[0]);
fprintf(out, "\nOptions are:\n");
fprintf(out, " -c <file>: specify a config file\n");
fprintf(out, " -p <path>: specify a path where to search for modules\n");
fprintf(out, " -v: print version information\n");
fprintf(out, " -d <level>: set debug level, multiple -d's are possible\n");
fprintf(out, " <level> can be one of these:\n");
cw_dbg_print_help(out," ");
exit(EXIT_SUCCESS);
break;
}
}
}
return 0;
@ -200,6 +211,7 @@ return 0;
*/
static cw_Cfg_t * global_cfg = NULL;
void process_wtp_packet (int index, struct sockaddr *addr, uint8_t * buffer, int len, int dta);
int main (int argc, char *argv[])
@ -225,6 +237,12 @@ int main (int argc, char *argv[])
goto errX;
};
//hapd_run(); // init
//stop();
//const char *ttt = cw_cfg_get(global_cfg,"cisco/ssl-cipher",NULL);
//printf("CFG: %s\n",ttt);
//stop();
cw_log_name = "AC-Tube";
/*
@ -440,7 +458,7 @@ int ac_run(cw_Cfg_t * cfg)
(struct sockaddr *) &srcaddr,
&srcaddrlen);
process_cw_data_packet (i, (struct sockaddr *) &srcaddr, buffer, len);
process_wtp_packet (i, (struct sockaddr *) &srcaddr, buffer, len,1);
}
@ -453,7 +471,7 @@ int ac_run(cw_Cfg_t * cfg)
(struct sockaddr *) &srcaddr,
&srcaddrlen);
process_ctrl_packet (i, (struct sockaddr *) &srcaddr, buffer, len);
process_wtp_packet (i, (struct sockaddr *) &srcaddr, buffer, len,0);
}
}
@ -467,14 +485,14 @@ int ac_run(cw_Cfg_t * cfg)
void process_cw_data_packet (int index, struct sockaddr *addr, uint8_t * buffer, int len)
{
char sock_buf[SOCK_ADDR_BUFSIZE];
cw_dbg (DBG_X, "There is a data packet now");
// cw_dbg (DBG_X, "There is a data packet now");
dataman_list_lock();
cw_dbg (DBG_X, "Dataman list locked, now getting");
// cw_dbg (DBG_X, "Dataman list locked, now getting");
struct dataman * dm = dataman_list_get (socklist[index].data_sockfd, addr);
cw_dbg (DBG_X, "Dataman list locked, now gotted");
// cw_dbg (DBG_X, "Dataman list locked, now gotted");
cw_dbg (DBG_INFO, "Packet for dataman %s,%d", sock_addr2str_p (addr, sock_buf), socklist[index].data_sockfd);
// cw_dbg (DBG_INFO, "Packet for dataman %s,%d", sock_addr2str_p (addr, sock_buf), socklist[index].data_sockfd);
if (!dm) {
cw_dbg (DBG_INFO, "No dataman %s,%d", sock_addr2str_p (addr, sock_buf), socklist[index].data_sockfd);
@ -486,15 +504,12 @@ void process_cw_data_packet (int index, struct sockaddr *addr, uint8_t * buffer,
}
dataman_list_add (dm);
dataman_start (dm);
}
dataman_list_unlock();
//dataman_add_packet (dm, buffer, len);
dataman_add_packet (dm, buffer, len);
return;
@ -517,7 +532,7 @@ void process_cw_data_packet (int index, struct sockaddr *addr, uint8_t * buffer,
}
void process_cw_ctrl_packet (int index, struct sockaddr *addr, uint8_t * buffer, int len)
void process_wtp_packet (int index, struct sockaddr *addr, uint8_t * buffer, int len, int dta)
{
char sock_buf[SOCK_ADDR_BUFSIZE];
@ -537,6 +552,10 @@ void process_cw_ctrl_packet (int index, struct sockaddr *addr, uint8_t * buffer,
if (!wtpman) {
if (dta){
cw_dbg(DBG_PKT_ERR,"Data packet w/o wtpman received, ignoring");
return;
}
wtpman = wtpman_create (index, addr, preamble & 0xf, global_cfg);
@ -558,9 +577,12 @@ void process_cw_ctrl_packet (int index, struct sockaddr *addr, uint8_t * buffer,
wtpman_start (wtpman, preamble & 0xf);
}
//printf("Got Packet with len: %d\n",len);
wtpman_addpacket (wtpman, buffer, len);
if(!dta)
wtpman_addpacket (wtpman, buffer, len);
else{
// cw_dbg(DBG_X,"Data packet received");
wtpman_datapacket (wtpman, buffer, len);
}
wtplist_unlock();
}
@ -631,7 +653,7 @@ void process_ctrl_packet (int index, struct sockaddr *addr, uint8_t * buffer, in
{
switch (socklist[index].ac_proto) {
case AC_PROTO_CAPWAP:
process_cw_ctrl_packet (index, addr, buffer, len);
// process_cw_ctrl_packet (index, addr, buffer, len);
return;
/*case AC_PROTO_LWAPP:

View File

@ -15,10 +15,18 @@ capwap/ssl-dhbits: 1024
capwap/ssl-keyfile: "../../ssl/intermediate-ca/int-ca.key"
capwap/ssl-certfile: "../../ssl/intermediate-ca/int-ca.crt"
cisco/ssl-keyfile: "../../ssl/intermediate-ca/int-ca.key"
cisco/ssl-certfile: "../../ssl/intermediate-ca/int-ca.crt"
cisco/ssl-cipher: DEFAULT
cisco/ssl-dhbits: 2048
#mod/cisco/ssl-keyfile: "../../ssl/intermediate-ca/int-ca.key"
#mod/cisco/ssl-certfile: "../../ssl/intermediate-ca/int-ca.crt"
#
mod/cisco/ssl-keyfile: "../../ssl/certs/ac-cisco.key"
mod/cisco/ssl-certfile: "../../ssl/certs/ac-cisco.pem"
#cisco/ssl-cipher: DEFAULT
mod/cisco/ssl-cipher: RSA
mod/cisco/ssl-dhbits: 2048
#
@ -43,7 +51,15 @@ actube/mod.2: capwap80211
#actube/rpc/listen: unix:/tmp/actube
actube/rpc/listen: tcp:127.0.0.1:5000
actube/rpc/enable: true
actube/rpc/macros-dir: ./rpc-macros
#
# This catches the initial config af a connecting WTP
# From Discovery to CFG Update
# The config is saved to a file named
# wtp-<wtpname-or-ip>.cfg
#
actube/save-initial-wtp-config: true
capwap/ac-descriptor/dtls-policy: 1
capwap/ac-descriptor/hardware/vendor: 4232704
@ -59,17 +75,100 @@ capwap/ac-descriptor/station-limit: 1000
capwap/ac-descriptor/stations: 0
capwap/control-ip-address/address.0: 192.168.0.24
capwap/control-ip-address/address.0: 192.168.0.14
wlan.0/capwap80211/capability: 0
wlan.0/capwap80211/key-index: 0
wlan.0/capwap80211/key-status: 0
wlan.0/capwap80211/key: 1234
wlan.0/capwap80211/group-tcs: 123
wlan.0/capwap80211/qos: 0
wlan.0/capwap80211/auth-type: 1
wlan.0/capwap80211/mac-mode: 1
wlan.0/capwap80211/tunnel-mode: 1
wlan.0/capwap80211/suppress-ssid: false
wlan.0/capwap80211/ssid: ssid
#
# CAPWAP Timers
#
capwap/timers/change-state-pending-timer: Word: 3
capwap/timers/data-check-timer: Word: 10
capwap/timers/echo-interval :Byte: 30
capwap/timers/max-discovery-interval :Byte: 10
capwap/timers/change-state-pending-timer: 3
capwap/timers/data-check-timer: 10
capwap/timers/echo-interval: 30
capwap/timers/max-discovery-interval: 10
capwap/decryption-error-report-period: 120
capwap/idle-timeout: 300
radio-cfg-a/capwap80211/wtp-radio-config/beacon-period: 100
radio-cfg-a/capwap80211/wtp-radio-config/bssid: .x003a9902fac0
radio-cfg-a/capwap80211/wtp-radio-config/cfg-period: 4
radio-cfg-a/capwap80211/wtp-radio-config/beacon-period: 100
radio-cfg-a/capwap80211/wtp-radio-config/bssid: .x003a9902fac0
radio-cfg-a/capwap80211/wtp-radio-config/cfg-period: 4
radio-cfg-a/capwap80211/wtp-radio-config/cfg-type: 1
radio-cfg-a/capwap80211/wtp-radio-config/cfp-maximum-duration: 60
radio-cfg-a/capwap80211/wtp-radio-config/country-str1: "DE "
radio-cfg-a/capwap80211/wtp-radio-config/country-str2: "DE "
radio-cfg-a/capwap80211/wtp-radio-config/occupancy-limit: 100
radio-cfg-a/capwap80211/wtp-radio-config/reg: 167772416
radio-cfg-a/cisco/direct-sequence-control/cfg-type: 1 - global
radio-cfg-a/cisco/direct-sequence-control/current-cca-mode: 0
radio-cfg-a/cisco/direct-sequence-control/current-channel: 1
radio-cfg-a/cisco/direct-sequence-control/energy-detect-threshold: -50
#mode-802.11g support
#radio-cfg-a/cisco/direct-sequence-control/unknown: 1
radio-cfg-a/cisco/mac-operation/fragmentation-threshold: 2346
radio-cfg-a/cisco/mac-operation/long-retry: 4
radio-cfg-a/cisco/mac-operation/reserved: 1
radio-cfg-a/cisco/mac-operation/rts-threshold: 2347
radio-cfg-a/cisco/mac-operation/rx-msdu-lifetime: 512
radio-cfg-a/cisco/mac-operation/short-retry: 7
radio-cfg-a/cisco/mac-operation/tx-msdu-lifetime: 512
radio-cfg-a/cisco/multi-domain-capability/first-channel: 1
radio-cfg-a/cisco/multi-domain-capability/max-tx-power-level: 65535
radio-cfg-a/cisco/multi-domain-capability/number-of-channels: 13
radio-cfg-a/cisco/multi-domain-capability/reserved: 1
radio-cfg-a/capwap80211/rate-set: .x82848b960c1218243048606c
radio-cfg-a/cisco/antenna-payload/802-11n-rx-antennas: 3
radio-cfg-a/cisco/antenna-payload/802-11n-tx-antennas: 7
radio-cfg-a/cisco/antenna-payload/antenna-cnt: 2
radio-cfg-a/cisco/antenna-payload/antenna-mode: 3
radio-cfg-a/cisco/antenna-payload/antenna.0: 1 - Internal Antenna
radio-cfg-a/cisco/antenna-payload/antenna.1: 1 - Internal Antenna
radio-cfg-a/cisco/antenna-payload/diversity-selection: 255
radio-cfg-a/cisco/antenna-payload/unknown: 0
radio-cfg-b/capwap80211/wtp-radio-config/beacon-period: 100
radio-cfg-b/capwap80211/wtp-radio-config/bssid: .x003a9902fac0
radio-cfg-b/capwap80211/wtp-radio-config/cfg-period: 4
radio-cfg-b/capwap80211/wtp-radio-config/beacon-period: 100
radio-cfg-b/capwap80211/wtp-radio-config/bssid: .x003a9902fac0
radio-cfg-b/capwap80211/wtp-radio-config/cfg-period: 4
radio-cfg-b/capwap80211/wtp-radio-config/cfg-type: 1
radio-cfg-b/capwap80211/wtp-radio-config/cfp-maximum-duration: 60
radio-cfg-b/capwap80211/wtp-radio-config/country-str1: "DE "
radio-cfg-b/capwap80211/wtp-radio-config/country-str2: "DE "
radio-cfg-b/capwap80211/wtp-radio-config/occupancy-limit: 100
radio-cfg-b/capwap80211/wtp-radio-config/reg: 167772416

View File

@ -5,10 +5,12 @@
#include "cw/timer.h"
#include "cw/cw.h"
#include "cw/format.h"
#include "cw/netconn.h"
#include "cw/conn.h"
#include "cw/log.h"
#include "cw/dbg.h"
#include "cw/file.h"
#include "cw/dot11.h"
#include "wtplist.h"
#include "dataman.h"
@ -19,8 +21,8 @@ pthread_mutex_t dataman_list_mutex;
static int cmp(const void *d1, const void *d2)
{
struct netconn *nc1 = ((struct dataman *) d1)->nc;
struct netconn *nc2 = ((struct dataman *) d1)->nc;
struct cw_Conn *nc1 = ((struct dataman *) d1)->nc;
struct cw_Conn *nc2 = ((struct dataman *) d1)->nc;
int r = nc1->sock - nc2->sock;
if (r != 0)
@ -52,7 +54,7 @@ void dataman_destroy(struct dataman *dm)
{
if (!dm)
return;
netconn_destroy(dm->nc);
conn_destroy(dm->nc);
}
struct dataman *dataman_create(int sock, struct sockaddr *addr)
@ -60,15 +62,15 @@ struct dataman *dataman_create(int sock, struct sockaddr *addr)
struct dataman *dm = malloc(sizeof(struct dataman));
if (!dm)
return NULL;
dm->nc = netconn_create(sock, addr, 100);
memset(dm,0,sizeof(struct dataman));
dm->nc = cw_conn_create(sock, addr, 100);
return dm;
}
struct dataman *dataman_list_get(int sock, struct sockaddr *addr)
{
struct netconn search_nc;
struct cw_Conn search_nc;
struct dataman search_dm;
search_nc.sock = sock;
@ -78,7 +80,7 @@ struct dataman *dataman_list_get(int sock, struct sockaddr *addr)
struct dataman *dm = mavl_get(dataman_list, &search_dm);
cw_dbg(DBG_X,"Getting dataman %p",dm);
// cw_dbg(DBG_X,"Getting dataman %p",dm);
return dm;
}
@ -91,7 +93,7 @@ struct dataman *dataman_list_add(struct dataman *dm)
int dataman_process_keep_alive(struct netconn *nc, uint8_t *rawmsg, int len)
int dataman_process_keep_alive(struct cw_Conn *nc, uint8_t *rawmsg, int len)
{
struct dataman * dm = (struct dataman *)(nc->data);
@ -133,7 +135,7 @@ int dataman_process_keep_alive(struct netconn *nc, uint8_t *rawmsg, int len)
printf("len len %d\n",l);
printf("Total len = %d\n",total_len);
netconn_send_capwap_msg(nc,buffer,total_len);
cw_send_msg(nc,buffer,total_len);
return len;
@ -167,26 +169,87 @@ int dataman_process_keep_alive(struct netconn *nc, uint8_t *rawmsg, int len)
return -1;
}
int dataman_process_message0(struct netconn *nc, uint8_t * rawmsg, int len,
int dataman_process_message0(struct cw_Conn *nc, uint8_t * rawmsg, int len,
struct sockaddr *from)
{
static int c=0;
char fn[100];
sprintf(fn,"wificap-%03d",c++);
/// cw_save_file(fn,(char*)rawmsg,len);
/// cw_dbg(DBG_X,"saving %d bytes",len);
int offs = cw_get_hdr_msg_offset(rawmsg);
int rc;
uint8_t * dot11frame = rawmsg + offs;
int dot11len = len-offs;
// cw_dbg(DBG_X,"802.11 - %s",dot11_get_frame_name(dot11frame));
// extern void ppacket(uint8_t * p, int len);
// ppacket (dot11frame,len-cw_get_hdr_msg_offset(rawmsg));
// cw_dbg(DBG_X,"802.11 - %s",dot11_get_frame_name(dot11frame));
// cw_dbg(DBG_X,"802.11 - T&S: %d %d",dot11_get_type(dot11frame),dot11_get_subtype(dot11frame));
// cw_dbg(DBG_X,"Frame CTL:%d,%d",frame.frame_control.type, frame.frame_control.subtype);
// cw_dbg(DBG_X,"CMP???CTL:%d,%d (%d,%d)",frame.frame_control.type, frame.frame_control.subtype,
// TYPE_MANAGEMENT,SUBTYPE_ASSOC_REQ);
// char ffr[1024];
// cw_format_dot11_hdr(ffr,dot11frame,dot11len);
// cw_dbg(DBG_X,ffr);
//
//
/* The very first data message MUST be a keep-alive message */
if (!cw_get_hdr_flag_k(rawmsg)){
// cw_dbg(DBG_X,"No K Flag founde");
errno = EAGAIN;
return -1;
}
// cw_dbg(DBG_X, "Goto Keep Alive Pack");
return dataman_process_keep_alive(nc,rawmsg,len);
}
int dataman_process_message(struct netconn *nc, uint8_t * rawmsg, int len,
int dataman_process_message(struct cw_Conn *nc, uint8_t * rawmsg, int len,
struct sockaddr *from)
{
if (cw_get_hdr_flag_k(rawmsg)){
return dataman_process_keep_alive(nc,rawmsg,len);
}
static int c=0;
char fn[100];
sprintf(fn,"wificap-%03d",c++);
cw_save_file(fn,(char*)rawmsg,len);
extern void ppacket(uint8_t * p, int len);
// ppacket (rawmsg,len);
cw_dbg(DBG_X,"There was someting else than dataman");
return 1;
}
@ -195,12 +258,22 @@ void dataman_run(struct dataman *dm)
{
time_t timer = cw_timer_start(2);
dm->nc->process_packet=netconn_process_packet;
dm->nc->process_packet=conn_process_packet;
dm->nc->process_message=dataman_process_message0;
dm->nc->data = dm;
while (1){
time_t timer = cw_timer_start(2);
while (!cw_timer_timeout(timer)){
cw_read_messages(dm->nc);
}
}
while (!cw_timer_timeout(timer)){
netconn_read_messages(dm->nc);
cw_read_messages(dm->nc);
}
if (!dm->wtpman){
@ -215,7 +288,7 @@ void dataman_run(struct dataman *dm)
while (1){
time_t timer = cw_timer_start(2);
while (!cw_timer_timeout(timer)){
netconn_read_messages(dm->nc);
cw_read_messages(dm->nc);
}
}

View File

@ -3,12 +3,11 @@
#include <pthread.h>
/*#include "cw/netconn.h"*/
#include "wtpman.h"
struct dataman {
struct netconn *nc;
struct cw_Conn *nc;
pthread_t thread;
struct wtpman * wtpman;
@ -28,6 +27,6 @@ extern pthread_mutex_t dataman_list_mutex;
#define dataman_list_lock() pthread_mutex_lock(&dataman_list_mutex)
#define dataman_list_unlock() pthread_mutex_unlock(&dataman_list_mutex)
#define dataman_add_packet(dm,data,len) (netconn_q_add_packet(dm->nc,data,len))
#define dataman_add_packet(dm,data,len) (conn_q_add_packet(dm->nc,data,len))
#endif

View File

@ -1,487 +0,0 @@
#include <sqlite3.h>
#include "cw/log.h"
#include "cw/dbg.h"
#include "cw/conn.h"
#include "conf.h"
static sqlite3 *handle;
static const char * init_tables = "\
CREATE TABLE IF NOT EXISTS acs (acid TEXT PRIMARY KEY, acname TEXT, lastseen TIMESTAMP); \
CREATE TABLE IF NOT EXISTS radios (\
wtpid TEXT,\
rid TEXT,\
key TEXT,\
sub_key,\
val TEXT, \
upd INTEGER, \
PRIMARY KEY (wtpid,rid,key,sub_key)\
);\
CREATE TABLE IF NOT EXISTS acips (acid TEXT,ip TEXT); \
CREATE TABLE IF NOT EXISTS wtps (wtpid TEXT PRIMARY KEY, acid TEXT,lastseen TIMESTAMP); \
CREATE TABLE IF NOT EXISTS wtpprops (\
wtpid TEXT NOT NULL,\
id TEXT NOT NULL,\
sub_id TEXT NOT NULL,\
val TEXT,\
upd INTEGER,\
PRIMARY KEY(wtpid,id,sub_id)\
);\
CREATE TABLE IF NOT EXISTS wlans (wlanid INTEGER PRIMARY KEY);\
CREATE TABLE IF NOT EXISTS wlanprops (wlanid INTEGER, id TEXT NOT NULL, val TEXT, PRIMARY KEY(wlanid,id));\
";
int db_init()
{
int rc;
const char * filename="ac.sqlite3";
cw_dbg(DBG_INFO,"Initializing Sqlite3 DB: %s, SQLite3 Version %s",filename,SQLITE_VERSION);
rc = sqlite3_config(SQLITE_CONFIG_SERIALIZED);
if (rc!=SQLITE_OK){
cw_log(LOG_ERR,"Error configuring SQLite3: %s",sqlite3_errmsg(handle));
return 0;
}
rc = sqlite3_initialize();
if (rc!=SQLITE_OK){
cw_log(LOG_ERR,"Error initializing SQLite3 DB : %s",sqlite3_errmsg(handle));
return 0;
}
rc = sqlite3_open(filename,&handle);
if (rc != SQLITE_OK)
{
cw_log(LOG_ERR,"Error opening SQLite3 DB %s: %s",filename,sqlite3_errmsg(handle));
return 0;
}
const char * cmd = init_tables;
rc = sqlite3_exec(handle,cmd,0,0,0);
if (rc)
{
const char *em = sqlite3_errmsg(handle);
cw_log(LOG_ERR,"Error executing SQL \"%s\"\nSQL Error Message: %s",cmd, em);
return 0;
}
return 1;
}
static sqlite3_stmt * ping_stmt;
static sqlite3_stmt * put_wtp_prop_stmt;
static sqlite3_stmt * get_tasks_stmt;
static sqlite3_stmt * stmt_get_radio_tasks;
static sqlite3_stmt * stmt_ping_wtp;
static sqlite3_stmt * stmt_put_radio_prop;
int db_start()
{
cw_dbg(DBG_INFO,"Starting Sqlite3 DB");
const char *sql="";
sqlite3_stmt *stmt;
int rc = sqlite3_prepare_v2(handle, "INSERT OR REPLACE INTO acs (acid,acname) VALUES (?,?);",-1,&stmt,0);
if (rc)
goto errX;
rc = sqlite3_bind_text(stmt,1,conf_acid,-1,SQLITE_STATIC);
rc = sqlite3_bind_text(stmt,2,conf_acname,-1,SQLITE_STATIC);
sqlite3_step(stmt);
rc = sqlite3_prepare_v2(handle, "UPDATE acs SET lastseen=datetime('now') WHERE acid=?;",-1,&ping_stmt,0);
rc = sqlite3_bind_text(ping_stmt,1,conf_acid,-1,SQLITE_STATIC);
/* Prepare statement to update a WTP property */
sql = "INSERT OR REPLACE INTO wtpprops\
(wtpid,id,sub_id,val,upd)\
VALUES (?,?,?,?,?)";
rc = sqlite3_prepare_v2(handle, sql,-1, &put_wtp_prop_stmt,0);
if (rc)
goto errX;
sql = "INSERT OR REPLACE INTO radios\
(wtpid,rid,key,sub_key,val,upd)\
VALUES (?,?,?,?,?,0)";
rc = sqlite3_prepare_v2(handle, sql,-1, &stmt_put_radio_prop,0);
if (rc)
goto errX;
/* Prepare WTP ping statement */
sql = "INSERT OR REPLACE INTO wtps (wtpid,acid,lastseen) VALUES(?,?,datetime('now'))";
rc = sqlite3_prepare_v2(handle, sql,-1, &stmt_ping_wtp,0);
if (rc)
goto errX;
sql = "SELECT wtpid,id,sub_id,val FROM wtpprops WHERE upd>0 AND wtpid=?";
rc = sqlite3_prepare_v2(handle, sql,-1, &get_tasks_stmt,0);
if (rc)
goto errX;
sql = "SELECT wtpid,rid,key,sub_key,val FROM radios WHERE upd>0 AND wtpid=?";
rc = sqlite3_prepare_v2(handle, sql,-1, &stmt_get_radio_tasks,0);
if (rc)
goto errX;
return 1;
errX:
cw_log(LOG_ERR,"Fatal: Can't start Sqlite3 DB, Error while executing '%s' - %d - %s",sql,rc,sqlite3_errmsg(handle));
return 0;
}
void db_put_radio_prop(const char *wtp_id,const char *rid, const char * key,const char *sub_key,const char * val)
{
int rc=0;
/*// DBGX("Putting %s/%s:%s",id,sub_id,val);
// (wtpid,rid,key,sub_key,val,upd)
*/
sqlite3_reset(stmt_put_radio_prop);
sqlite3_clear_bindings(stmt_put_radio_prop);
if(sqlite3_bind_text(stmt_put_radio_prop,1,wtp_id,-1,SQLITE_STATIC))
goto errX;
if(sqlite3_bind_text(stmt_put_radio_prop,2,rid,-1,SQLITE_STATIC))
goto errX;
if (sqlite3_bind_text(stmt_put_radio_prop,3,key,-1,SQLITE_STATIC))
goto errX;
/* if (!sub_key)
sub_key=CW_ITEM_NONE;
*/
if (sqlite3_bind_text(stmt_put_radio_prop,4,sub_key,-1,SQLITE_STATIC))
goto errX;
if (sqlite3_bind_text(stmt_put_radio_prop,5,val,-1,SQLITE_STATIC))
goto errX;
/*
// if (sqlite3_bind_int(put_wtp_prop_stmt,5,0))
// goto errX;
// cw_dbg(DBG_X,"Her I am already, next is step");
*/
rc = sqlite3_step(stmt_put_radio_prop);
if (rc != SQLITE_DONE)
goto errX;
/*
// cw_dbg(DBG_X,"SQL schould be fine");
*/
return;
errX:
/*// cw_dbg (DBG_X, "Iam on err %d\n",rc);*/
if (rc) {
cw_log(LOG_ERR,"Can't update database with WTP props: %d - %s",
rc,sqlite3_errmsg(handle));
}
}
void db_ping()
{
int rc = sqlite3_step(ping_stmt);
if (rc!=SQLITE_DONE){
cw_log(LOG_ERR,"Error: Can't ping database, error code %d - %s",rc,sqlite3_errmsg(handle));
}
}
void db_ping_wtp(const char *wtpid,const char *acid)
{
int rc=0;
sqlite3_reset(stmt_ping_wtp);
sqlite3_clear_bindings(stmt_ping_wtp);
if(sqlite3_bind_text(stmt_ping_wtp,1,wtpid,-1,SQLITE_STATIC))
goto errX;
if(sqlite3_bind_text(stmt_ping_wtp,2,acid,-1,SQLITE_STATIC))
goto errX;
rc = sqlite3_step(stmt_ping_wtp);
errX:
if (rc!=SQLITE_DONE) {
cw_log(LOG_ERR,"Can't ping database for WTP: %d - %s",
rc,sqlite3_errmsg(handle));
}
}
void db_put_wtp_prop(const char *wtp_id,const char * id,const char *sub_id,const char * val)
{
int rc=0;
/*// DBGX("Putting %s/%s:%s",id,sub_id,val);
*/
sqlite3_reset(put_wtp_prop_stmt);
sqlite3_clear_bindings(put_wtp_prop_stmt);
if(sqlite3_bind_text(put_wtp_prop_stmt,1,wtp_id,-1,SQLITE_STATIC))
goto errX;
if(sqlite3_bind_text(put_wtp_prop_stmt,2,id,-1,SQLITE_STATIC))
goto errX;
/* if (!sub_id)
sub_id=CW_ITEM_NONE;
*/
if (sqlite3_bind_text(put_wtp_prop_stmt,3,sub_id,-1,SQLITE_STATIC))
goto errX;
if (sqlite3_bind_text(put_wtp_prop_stmt,4,val,-1,SQLITE_STATIC))
goto errX;
if (sqlite3_bind_int(put_wtp_prop_stmt,5,0))
goto errX;
/*// cw_dbg(DBG_X,"Her I am already, next is step");
*/
rc = sqlite3_step(put_wtp_prop_stmt);
if (rc != SQLITE_DONE)
goto errX;
/*
// cw_dbg(DBG_X,"SQL schould be fine");
*/
return;
errX:
/*// cw_dbg (DBG_X, "Iam on err %d\n",rc);*/
if (rc) {
cw_log(LOG_ERR,"Can't update database with WTP props: %d - %s",
rc,sqlite3_errmsg(handle));
}
}
/*// TODO XXXX*/
mavl_t db_get_update_tasks(struct conn * conn,const char * wtpid)
{
/*
sqlite3_reset(get_tasks_stmt);
sqlite3_clear_bindings(get_tasks_stmt);
mavl_conststr_t r = mavl_create_conststr();
if (!r)
return NULL;
int rc=0;
if(sqlite3_bind_text(get_tasks_stmt,1,wtpid,-1,SQLITE_STATIC))
goto errX;
while (SQLITE_ROW == sqlite3_step(get_tasks_stmt)) {
int ii;
//DBGX("-----------------------------------------------------","");
for (ii=0; ii<5; ii++){
//DBGX("CVALL: %s",(const char*)sqlite3_column_text(get_tasks_stmt,ii));
}
const char *id = (const char*)sqlite3_column_text(get_tasks_stmt,1);
if (!id) {
continue;
}
const char *sub_id = (const char*)sqlite3_column_text(get_tasks_stmt,2);
const char *val = (const char*)sqlite3_column_text(get_tasks_stmt,3);
//DBGX("ID: (%s), SubID (%s), Val (%s)",id,sub_id,val);
const struct cw_itemdef * cwi = cw_itemdef_get(conn->actions->items,id,sub_id);
if (!cwi) {
//DBGX("Not item definition found for: %s/%s",id,sub_id);
continue;
}
//uint8_t data[2048];
if (!cwi->type->from_str) {
cw_log(LOG_ERR,"Can't convert from string %s/%s - No method defined.",id,sub_id);
continue;
}
mbag_item_t * i = cwi->type->from_str(val);
i->id=cwi->id;
mbag_set(conn->outgoing,i);
mavl_add(r,(void*)cwi->id);
}
if (r->count)
return r;
mavl_destroy(r);
return NULL;
errX:
if (rc) {
cw_log(LOG_ERR,"Can't get tasks: %d - %s",
rc,sqlite3_errmsg(handle));
}
if (r)
mavl_destroy(r);
return NULL;
*/
}
mavl_t db_get_radio_tasks(struct conn * conn,const char * wtpid)
{
/*
//cw_dbg(DBG_X,"Get Radio Tasks for %s",wtpid);
sqlite3_reset(stmt_get_radio_tasks);
sqlite3_clear_bindings(stmt_get_radio_tasks);
mavl_conststr_t r = mavl_create_conststr();
if (!r)
return NULL;
int rc=0;
if(sqlite3_bind_text(stmt_get_radio_tasks,1,wtpid,-1,SQLITE_STATIC))
goto errX;
while (SQLITE_ROW == sqlite3_step(stmt_get_radio_tasks)) {
int ii;
//DBGX("-----------------------------------------------------","");
for (ii=0; ii<6; ii++){
DBGX("CVALL: %s",(const char*)sqlite3_column_text(stmt_get_radio_tasks,ii));
}
const char *strrid= (const char*)sqlite3_column_text(stmt_get_radio_tasks,1);
const char *id = (const char*)sqlite3_column_text(stmt_get_radio_tasks,2);
if (!id) {
continue;
}
const char *sub_id = (const char*)sqlite3_column_text(stmt_get_radio_tasks,3);
const char *val = (const char*)sqlite3_column_text(stmt_get_radio_tasks,4);
//DBGX("ID: (%s), SubID (%s), Val (%s)",id,sub_id,val);
const struct cw_itemdef * cwi = cw_itemdef_get(conn->actions->radioitems,id,sub_id);
if (!cwi) {
DBGX("No item definition found for: %s/%s",id,sub_id);
continue;
}
if (!cwi->type->from_str) {
cw_log(LOG_ERR,"Can't convert from string %s/%s - No method defined.",id,sub_id);
continue;
}
mbag_item_t * i = cwi->type->from_str(val);
i->id=cwi->id;
int rid = atoi(strrid);
cw_dbg(DBG_X,"RID: %d",rid);
mbag_t radio = mbag_i_get_mbag_c(conn->radios_upd,rid,mbag_create);
mbag_set(radio,i);
//mbag_set(conn->outgoing,i);
mavl_add(r,(void*)cwi->id);
}
if (r->count)
return r;
mavl_destroy(r);
return NULL;
errX:
if (rc) {
cw_log(LOG_ERR,"Can't get tasks: %d - %s",
rc,sqlite3_errmsg(handle));
}
if (r)
mavl_destroy(r);
return NULL;
*/
}

View File

@ -1,21 +0,0 @@
#ifndef CW_MAVL_H
#define CW_MAVL_H
#include "mavl.h"
extern void db_ping();
extern void db_ping_wtp(const char *wtpid,const char *acid);
extern int db_init();
int db_start();
int db_get_tasks(struct conn * conn,const char * wtpid);
void db_put_wtp_prop(const char *wtp_id,const char * id,const char *sub_id,const char * val);
mavl_t db_get_update_tasks(struct conn * conn,const char * wtpid);
void db_put_radio_prop(const char *wtp_id,const char *rid, const char * key,const char *sub_key,const char * val);
extern mavl_t db_get_radio_tasks(struct conn * conn,const char * wtpid);
#endif

View File

@ -1,29 +0,0 @@
#include "module.h"
static int init()
{
// regn = cw_register_actions_cipwap_ac(&capwap_actions);
return 1;
}
static struct ac_module module = {
.name="Cipwap",
.init= init,
.detect_by_discovery = 0
};
struct ac_module * mod_cipwap()
{
return &module;
}

View File

@ -1,13 +0,0 @@
#ifndef __MODULE_H
#define __MODULE_H
struct ac_module
{
const char *name;
int (*init)();
int (*detect_by_raw)(const char *msg, int len);
int (*detect_by_discovery)(const char*);
};
#endif

View File

@ -0,0 +1,5 @@
radio.255/capwap/operational-state/state: enabled
radio.255/capwap/admin-state: 1
radio.0/capwap/operational-state/state: enabled
radio.0/capwap/admin-state: 1

View File

@ -0,0 +1,5 @@
#
# Managed by acTube
#
radio.0/capwap/admin-state: 1

60
src/ac/rpc-macros/all.ckv Normal file
View File

@ -0,0 +1,60 @@
radio.0/cisco/air-space-capability: 0
radio.0/cisco/antenna-payload/802-11n-rx-antennas: 3
radio.0/cisco/antenna-payload/802-11n-tx-antennas: 7
radio.0/cisco/antenna-payload/antenna-cnt: 2
radio.0/cisco/antenna-payload/antenna-mode: 3
radio.0/cisco/antenna-payload/antenna.0: 1 - Internal Antenna
radio.0/cisco/antenna-payload/antenna.1: 1 - Internal Antenna
radio.0/cisco/antenna-payload/diversity-selection: 255
radio.0/cisco/antenna-payload/unknown: 0
radio.0/cisco/channel-power: .x08080d0108221c16100a04fefe0208221c16100a04fefe0308221c16100a04fefe0408221c16100a04fefe0508221c16100a04fefe0608221c16100a04fefe0708221c16100a04fefe0808221c16100a04fefe0908221c16100a04fefe0a08221c16100a04fefe0b08221c16100a04fefe0c08221c16100a04fefe0d08221c16100a04fefe
radio.0/capwap80211/rate-set: .x82848b960c1218243048606c
radio.0/capwap80211/tx-power/@cisco/cfg-type: 1 - global
radio.0/capwap80211/tx-power/current-tx-power: 1
radio.0/capwap80211/wtp-radio-config/beacon-period: 100
radio.0/capwap80211/wtp-radio-config/bssid: .x04fe7f499b90
radio.0/capwap80211/wtp-radio-config/cfg-period: 4
radio.0/capwap80211/wtp-radio-config/cfg-type: 1
radio.0/capwap80211/wtp-radio-config/cfp-maximum-duration: 60
radio.0/capwap80211/wtp-radio-config/country-str1: "DE "
radio.0/capwap80211/wtp-radio-config/country-str2: "DE "
radio.0/capwap80211/wtp-radio-config/occupancy-limit: 100
radio.0/capwap80211/wtp-radio-config/reg: 167772416
radio.0/capwap80211/wtp-radio-information: 1
radio.0/cisco/mac-operation/long-retry: 4
radio.0/cisco/mac-operation/reserved: 1
radio.0/cisco/mac-operation/rts-threshold: 2347
radio.0/cisco/mac-operation/rx-msdu-lifetime: 512
radio.0/cisco/mac-operation/short-retry: 7
radio.0/cisco/mac-operation/tx-msdu-lifetime: 512
radio.0/cisco/multi-domain-capability/first-channel: 1
radio.0/cisco/multi-domain-capability/max-tx-power-level: 65535
radio.0/cisco/multi-domain-capability/number-of-channels: 13
radio.0/cisco/multi-domain-capability/reserved: 1
radio.0/cisco/phy-ht-cap/asel-cap: 0
radio.0/cisco/phy-ht-cap/extended-ht-cap-info: .x0000
radio.0/cisco/phy-ht-cap/ht-cap-info: 6
radio.0/cisco/phy-ht-cap/mcsrates-1: .x00000000
radio.0/cisco/phy-ht-cap/mcsrates-2: .x00000000
radio.0/cisco/phy-ht-cap/mcsrates-3: .x00000000
radio.0/cisco/phy-ht-cap/mcsrates-4: .x0000ffff
radio.0/cisco/phy-ht-cap/tx-bf-cap: .x00000000
radio.0/cisco/phy-ht-control/cfg-type: 1 - global
radio.0/cisco/phy-ht-control/channel-width: 20
radio.0/cisco/phy-ht-control/cur-freq-is-dfs-channel: 0
radio.0/cisco/phy-ht-control/current-freq: 1
radio.0/cisco/phy-ht-control/enable-ht: 3
radio.0/cisco/phy-ht-control/ext-channel: 0
radio.0/cisco/phy-ht-control/flash-commit: 0
radio.0/cisco/phy-ht-control/frequency-bands-support: 206
radio.0/cisco/phy-ht-control/rest: .x00ffffff
radio.0/cisco/phy-ht-control/ti-threshold: 0

View File

@ -0,0 +1,10 @@
radio.0/cisco/air-space-capability: 0
radio.0/cisco/antenna-payload/802-11n-rx-antennas: 3
radio.0/cisco/antenna-payload/802-11n-tx-antennas: 7
radio.0/cisco/antenna-payload/antenna-cnt: 2
radio.0/cisco/antenna-payload/antenna-mode: 3
radio.0/cisco/antenna-payload/antenna.0: 1 - Internal Antenna
radio.0/cisco/antenna-payload/antenna.1: 1 - Internal Antenna