static int ioctl_socket = -1;
+struct uci_context *uci_ctx = NULL;
static int iwinfo_ioctl_socket(void)
{
/* Prepare socket */
- if( ioctl_socket == -1 )
+ if (ioctl_socket == -1)
{
ioctl_socket = socket(AF_INET, SOCK_DGRAM, 0);
fcntl(ioctl_socket, F_SETFD, fcntl(ioctl_socket, F_GETFD) | FD_CLOEXEC);
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
- if( iwinfo_ioctl(SIOCGIFFLAGS, &ifr) )
+ if (iwinfo_ioctl(SIOCGIFFLAGS, &ifr))
return 0;
ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
- if( iwinfo_ioctl(SIOCGIFFLAGS, &ifr) )
+ if (iwinfo_ioctl(SIOCGIFFLAGS, &ifr))
return 0;
ifr.ifr_flags &= ~(IFF_UP | IFF_RUNNING);
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
- if( iwinfo_ioctl(SIOCGIFHWADDR, &ifr) )
+ if (iwinfo_ioctl(SIOCGIFHWADDR, &ifr))
return 0;
+ ifr.ifr_hwaddr.sa_data[0] |= 0x02;
ifr.ifr_hwaddr.sa_data[1]++;
ifr.ifr_hwaddr.sa_data[2]++;
void iwinfo_close(void)
{
- if( ioctl_socket > -1 )
+ if (ioctl_socket > -1)
close(ioctl_socket);
+
+ ioctl_socket = -1;
}
struct iwinfo_hardware_entry * iwinfo_hardware(struct iwinfo_hardware_id *id)
{
- const struct iwinfo_hardware_entry *e;
+ FILE *db;
+ char buf[256] = { 0 };
+ static struct iwinfo_hardware_entry e;
+ struct iwinfo_hardware_entry *rv = NULL;
+
+ if (!(db = fopen(IWINFO_HARDWARE_FILE, "r")))
+ return NULL;
- for (e = IWINFO_HARDWARE_ENTRIES; e->vendor_name; e++)
+ while (fgets(buf, sizeof(buf) - 1, db) != NULL)
{
- if ((e->vendor_id != 0xffff) && (e->vendor_id != id->vendor_id))
+ memset(&e, 0, sizeof(e));
+
+ if (sscanf(buf, "%hx %hx %hx %hx %hd %hd \"%63[^\"]\" \"%63[^\"]\"",
+ &e.vendor_id, &e.device_id,
+ &e.subsystem_vendor_id, &e.subsystem_device_id,
+ &e.txpower_offset, &e.frequency_offset,
+ e.vendor_name, e.device_name) < 8)
+ continue;
+
+ if ((e.vendor_id != 0xffff) && (e.vendor_id != id->vendor_id))
continue;
- if ((e->device_id != 0xffff) && (e->device_id != id->device_id))
+ if ((e.device_id != 0xffff) && (e.device_id != id->device_id))
continue;
- if ((e->subsystem_vendor_id != 0xffff) &&
- (e->subsystem_vendor_id != id->subsystem_vendor_id))
+ if ((e.subsystem_vendor_id != 0xffff) &&
+ (e.subsystem_vendor_id != id->subsystem_vendor_id))
continue;
- if ((e->subsystem_device_id != 0xffff) &&
- (e->subsystem_device_id != id->subsystem_device_id))
+ if ((e.subsystem_device_id != 0xffff) &&
+ (e.subsystem_device_id != id->subsystem_device_id))
continue;
- return (struct iwinfo_hardware_entry *)e;
+ rv = &e;
+ break;
}
- return NULL;
+ fclose(db);
+ return rv;
}
int iwinfo_hardware_id_from_mtd(struct iwinfo_hardware_id *id)
while (fgets(buf, sizeof(buf), mtd) > 0)
{
- if (fscanf(mtd, "mtd%d: %*x %x %127s", &off, &len, buf) < 3 ||
+ if (fscanf(mtd, "mtd%d: %x %*x %127s", &off, &len, buf) < 3 ||
(strcmp(buf, "\"boardconfig\"") && strcmp(buf, "\"EEPROM\"") &&
strcmp(buf, "\"factory\"")))
{
data += 2 + (count * 4);
len -= 2 + (count * 4);
}
+
+struct uci_section *iwinfo_uci_get_radio(const char *name, const char *type)
+{
+ struct uci_ptr ptr = {
+ .package = "wireless",
+ .section = name,
+ };
+ const char *opt;
+
+ if (!uci_ctx) {
+ uci_ctx = uci_alloc_context();
+ if (!uci_ctx)
+ return NULL;
+ }
+
+ memset(&ptr, 0, sizeof(ptr));
+ ptr.package = "wireless";
+ ptr.section = name;
+
+ if (uci_lookup_ptr(uci_ctx, &ptr, NULL, false))
+ return NULL;
+
+ if (!ptr.s || strcmp(ptr.s->type, "wifi-device") != 0)
+ return NULL;
+
+ opt = uci_lookup_option_string(uci_ctx, ptr.s, "type");
+ if (!opt || strcmp(opt, type) != 0)
+ return NULL;
+
+ return ptr.s;
+}
+
+void iwinfo_uci_free(void)
+{
+ if (!uci_ctx)
+ return;
+
+ uci_free_context(uci_ctx);
+ uci_ctx = NULL;
+}