2 * luci-rpcd - LuCI UBUS RPC server
4 * Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
31 static struct blob_buf buf
;
32 static const struct iwinfo_ops
*iw
;
33 static const char *ifname
;
40 static const struct blobmsg_policy rpc_device_policy
[__RPC_D_MAX
] = {
41 [RPC_D_DEVICE
] = { .name
= "device", .type
= BLOBMSG_TYPE_STRING
},
46 rpc_iwinfo_open(struct blob_attr
*msg
)
48 static struct blob_attr
*tb
[__RPC_D_MAX
];
50 blobmsg_parse(rpc_device_policy
, __RPC_D_MAX
, tb
,
51 blob_data(msg
), blob_len(msg
));
53 if (!tb
[RPC_D_DEVICE
])
54 return UBUS_STATUS_INVALID_ARGUMENT
;
56 ifname
= blobmsg_data(tb
[RPC_D_DEVICE
]);
57 iw
= iwinfo_backend(ifname
);
59 return iw
? UBUS_STATUS_OK
: UBUS_STATUS_NOT_FOUND
;
63 rpc_iwinfo_call_int(const char *name
, int (*func
)(const char *, int *),
68 if (!func(ifname
, &rv
))
71 blobmsg_add_u32(&buf
, name
, rv
);
73 blobmsg_add_string(&buf
, name
, map
[rv
]);
78 rpc_iwinfo_call_hardware_id(const char *name
)
80 struct iwinfo_hardware_id ids
;
83 if (!iw
->hardware_id(ifname
, (char *)&ids
))
85 c
= blobmsg_open_array(&buf
, name
);
87 blobmsg_add_u32(&buf
, NULL
, ids
.vendor_id
);
88 blobmsg_add_u32(&buf
, NULL
, ids
.device_id
);
89 blobmsg_add_u32(&buf
, NULL
, ids
.subsystem_vendor_id
);
90 blobmsg_add_u32(&buf
, NULL
, ids
.subsystem_device_id
);
92 blobmsg_close_array(&buf
, c
);
97 rpc_iwinfo_call_encryption(const char *name
)
99 struct iwinfo_crypto_entry crypto
= { 0 };
103 if (!iw
->encryption(ifname
, (char *)&crypto
))
105 c
= blobmsg_open_table(&buf
, name
);
107 blobmsg_add_u8(&buf
, "enabled", crypto
.enabled
);
111 if (!crypto
.wpa_version
)
113 d
= blobmsg_open_array(&buf
, "wep");
115 if (crypto
.auth_algs
& IWINFO_AUTH_OPEN
)
116 blobmsg_add_string(&buf
, NULL
, "open");
118 if (crypto
.auth_algs
& IWINFO_AUTH_SHARED
)
119 blobmsg_add_string(&buf
, NULL
, "shared");
121 blobmsg_close_array(&buf
, d
);
125 d
= blobmsg_open_array(&buf
, "wpa");
127 if (crypto
.wpa_version
> 2)
129 blobmsg_add_u32(&buf
, NULL
, 1);
130 blobmsg_add_u32(&buf
, NULL
, 2);
134 blobmsg_add_u32(&buf
, NULL
, crypto
.wpa_version
);
137 blobmsg_close_array(&buf
, d
);
140 d
= blobmsg_open_array(&buf
, "authentication");
142 if (crypto
.auth_suites
& IWINFO_KMGMT_PSK
)
143 blobmsg_add_string(&buf
, NULL
, "psk");
145 if (crypto
.auth_suites
& IWINFO_KMGMT_8021x
)
146 blobmsg_add_string(&buf
, NULL
, "802.1x");
148 if (!crypto
.auth_suites
||
149 (crypto
.auth_suites
& IWINFO_KMGMT_NONE
))
150 blobmsg_add_string(&buf
, NULL
, "none");
152 blobmsg_close_array(&buf
, d
);
155 d
= blobmsg_open_array(&buf
, "ciphers");
156 ciph
= crypto
.pair_ciphers
| crypto
.group_ciphers
;
158 if (ciph
& IWINFO_CIPHER_WEP40
)
159 blobmsg_add_string(&buf
, NULL
, "wep-40");
161 if (ciph
& IWINFO_CIPHER_WEP104
)
162 blobmsg_add_string(&buf
, NULL
, "wep-104");
164 if (ciph
& IWINFO_CIPHER_TKIP
)
165 blobmsg_add_string(&buf
, NULL
, "tkip");
167 if (ciph
& IWINFO_CIPHER_CCMP
)
168 blobmsg_add_string(&buf
, NULL
, "ccmp");
170 if (ciph
& IWINFO_CIPHER_WRAP
)
171 blobmsg_add_string(&buf
, NULL
, "wrap");
173 if (ciph
& IWINFO_CIPHER_AESOCB
)
174 blobmsg_add_string(&buf
, NULL
, "aes-ocb");
176 if (ciph
& IWINFO_CIPHER_CKIP
)
177 blobmsg_add_string(&buf
, NULL
, "ckip");
179 if (!ciph
|| (ciph
& IWINFO_CIPHER_NONE
))
180 blobmsg_add_string(&buf
, NULL
, "none");
182 blobmsg_close_array(&buf
, d
);
185 blobmsg_close_table(&buf
, c
);
190 rpc_iwinfo_call_hwmodes(const char *name
)
195 if (!iw
->hwmodelist(ifname
, &modes
))
197 c
= blobmsg_open_array(&buf
, name
);
199 if (modes
& IWINFO_80211_A
);
200 blobmsg_add_string(&buf
, NULL
, "a");
202 if (modes
& IWINFO_80211_B
);
203 blobmsg_add_string(&buf
, NULL
, "b");
205 if (modes
& IWINFO_80211_G
);
206 blobmsg_add_string(&buf
, NULL
, "g");
208 if (modes
& IWINFO_80211_N
);
209 blobmsg_add_string(&buf
, NULL
, "n");
211 blobmsg_close_array(&buf
, c
);
216 rpc_iwinfo_call_str(const char *name
, int (*func
)(const char *, char *))
218 char rv
[IWINFO_BUFSIZE
] = { 0 };
220 if (!func(ifname
, rv
))
221 blobmsg_add_string(&buf
, name
, rv
);
225 rpc_iwinfo_info(struct ubus_context
*ctx
, struct ubus_object
*obj
,
226 struct ubus_request_data
*req
, const char *method
,
227 struct blob_attr
*msg
)
232 rv
= rpc_iwinfo_open(msg
);
237 blob_buf_init(&buf
, 0);
239 rpc_iwinfo_call_str("ssid", iw
->ssid
);
240 rpc_iwinfo_call_str("bssid", iw
->bssid
);
241 rpc_iwinfo_call_str("country", iw
->country
);
243 rpc_iwinfo_call_int("mode", iw
->mode
, IWINFO_OPMODE_NAMES
);
244 rpc_iwinfo_call_int("channel", iw
->channel
, NULL
);
246 rpc_iwinfo_call_int("frequency", iw
->frequency
, NULL
);
247 rpc_iwinfo_call_int("frequency_offset", iw
->frequency_offset
, NULL
);
249 rpc_iwinfo_call_int("txpower", iw
->txpower
, NULL
);
250 rpc_iwinfo_call_int("txpower_offset", iw
->txpower_offset
, NULL
);
252 rpc_iwinfo_call_int("quality", iw
->quality
, NULL
);
253 rpc_iwinfo_call_int("quality_max", iw
->quality_max
, NULL
);
255 rpc_iwinfo_call_int("signal", iw
->signal
, NULL
);
256 rpc_iwinfo_call_int("noise", iw
->noise
, NULL
);
258 rpc_iwinfo_call_int("bitrate", iw
->bitrate
, NULL
);
260 rpc_iwinfo_call_encryption("encryption");
261 rpc_iwinfo_call_hwmodes("hwmodes");
263 c
= blobmsg_open_table(&buf
, "hardware");
264 rpc_iwinfo_call_hardware_id("id");
265 rpc_iwinfo_call_str("name", iw
->hardware_name
);
266 blobmsg_close_table(&buf
, c
);
268 ubus_send_reply(ctx
, req
, buf
.head
);
272 return UBUS_STATUS_OK
;
276 int rpc_iwinfo_api_init(struct ubus_context
*ctx
)
278 static const struct ubus_method iwinfo_methods
[] = {
279 UBUS_METHOD("info", rpc_iwinfo_info
, rpc_device_policy
),
282 static struct ubus_object_type iwinfo_type
=
283 UBUS_OBJECT_TYPE("luci-rpc-iwinfo", iwinfo_methods
);
285 static struct ubus_object obj
= {
287 .type
= &iwinfo_type
,
288 .methods
= iwinfo_methods
,
289 .n_methods
= ARRAY_SIZE(iwinfo_methods
),
292 return ubus_add_object(ctx
, &obj
);