};
enum {
- RPC_OC_CONFIG,
- __RPC_OC_MAX
+ RPC_UPGRADE_KEEP,
+ __RPC_UPGRADE_MAX
};
-static const struct blobmsg_policy rpc_opkg_config_policy[__RPC_OC_MAX] = {
- [RPC_OC_CONFIG] = { .name = "config", .type = BLOBMSG_TYPE_STRING },
+static const struct blobmsg_policy rpc_upgrade_policy[__RPC_UPGRADE_MAX] = {
+ [RPC_UPGRADE_KEEP] = { .name = "keep", .type = BLOBMSG_TYPE_BOOL },
};
}
}
+static int
+rpc_luci2_led_list(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ DIR *d;
+ FILE *f;
+ void *list, *led, *trigger;
+ char *p, *active_trigger, line[512];
+ struct dirent *e;
+
+ if (!(d = opendir("/sys/class/leds")))
+ return rpc_errno_status();
+
+ blob_buf_init(&buf, 0);
+ list = blobmsg_open_array(&buf, "leds");
+
+ while ((e = readdir(d)) != NULL)
+ {
+ snprintf(line, sizeof(line) - 1, "/sys/class/leds/%s/trigger",
+ e->d_name);
+
+ if (!(f = fopen(line, "r")))
+ continue;
+
+ led = blobmsg_open_table(&buf, NULL);
+
+ blobmsg_add_string(&buf, "name", e->d_name);
+
+ if (fgets(line, sizeof(line) - 1, f))
+ {
+ trigger = blobmsg_open_array(&buf, "triggers");
+
+ for (p = strtok(line, " \n"), active_trigger = NULL;
+ p != NULL;
+ p = strtok(NULL, " \n"))
+ {
+ if (*p == '[')
+ {
+ *(p + strlen(p) - 1) = 0;
+ *p++ = 0;
+ active_trigger = p;
+ }
+
+ blobmsg_add_string(&buf, NULL, p);
+ }
+
+ blobmsg_close_array(&buf, trigger);
+
+ if (active_trigger)
+ blobmsg_add_string(&buf, "active_trigger", active_trigger);
+ }
+
+ fclose(f);
+
+ snprintf(line, sizeof(line) - 1, "/sys/class/leds/%s/brightness",
+ e->d_name);
+
+ if ((f = fopen(line, "r")) != NULL)
+ {
+ if (fgets(line, sizeof(line) - 1, f))
+ blobmsg_add_u32(&buf, "brightness", atoi(line));
+
+ fclose(f);
+ }
+
+ snprintf(line, sizeof(line) - 1, "/sys/class/leds/%s/max_brightness",
+ e->d_name);
+
+ if ((f = fopen(line, "r")) != NULL)
+ {
+ if (fgets(line, sizeof(line) - 1, f))
+ blobmsg_add_u32(&buf, "max_brightness", atoi(line));
+
+ fclose(f);
+ }
+
+ blobmsg_close_table(&buf, led);
+ }
+
+ closedir(d);
+
+ blobmsg_close_array(&buf, list);
+ ubus_send_reply(ctx, req, buf.head);
+
+ return 0;
+}
+
+static int
+rpc_luci2_usb_list(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ DIR *d;
+ FILE *f;
+ int i;
+ void *list, *device;
+ char *p, line[512];
+ struct stat s;
+ struct dirent *e;
+
+ const char *attributes[] = {
+ "manufacturer", "vendor_name", "s",
+ "product", "product_name", "s",
+ "idVendor", "vendor_id", "x",
+ "idProduct", "product_id", "x",
+ "serial", "serial", "s",
+ "speed", "speed", "d",
+ };
+
+ if (!(d = opendir("/sys/bus/usb/devices")))
+ return rpc_errno_status();
+
+ blob_buf_init(&buf, 0);
+ list = blobmsg_open_array(&buf, "devices");
+
+ while ((e = readdir(d)) != NULL)
+ {
+ if (e->d_name[0] < '0' || e->d_name[0] > '9')
+ continue;
+
+ snprintf(line, sizeof(line) - 1,
+ "/sys/bus/usb/devices/%s/%s", e->d_name, attributes[0]);
+
+ if (stat(line, &s))
+ continue;
+
+ device = blobmsg_open_table(&buf, NULL);
+
+ blobmsg_add_string(&buf, "name", e->d_name);
+
+ for (i = 0; i < sizeof(attributes) / sizeof(attributes[0]); i += 3)
+ {
+ snprintf(line, sizeof(line) - 1,
+ "/sys/bus/usb/devices/%s/%s", e->d_name, attributes[i]);
+
+ if (!(f = fopen(line, "r")))
+ continue;
+
+ if (fgets(line, sizeof(line) - 1, f))
+ {
+ switch (*attributes[i+2])
+ {
+ case 'x':
+ blobmsg_add_u32(&buf, attributes[i+1],
+ strtoul(line, NULL, 16));
+ break;
+
+ case 'd':
+ blobmsg_add_u32(&buf, attributes[i+1],
+ strtoul(line, NULL, 10));
+ break;
+
+ default:
+ if ((p = strchr(line, '\n')) != NULL)
+ while (p > line && isspace(*p))
+ *p-- = 0;
+
+ blobmsg_add_string(&buf, attributes[i+1], line);
+ break;
+ }
+ }
+
+ fclose(f);
+ }
+
+ blobmsg_close_table(&buf, device);
+ }
+
+ closedir(d);
+
+ blobmsg_close_array(&buf, list);
+ ubus_send_reply(ctx, req, buf.head);
+
+ return 0;
+}
+
+static int
+rpc_luci2_upgrade_test(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ const char *cmd[4] = { "sysupgrade", "--test", "/tmp/firmware.bin", NULL };
+ return rpc_exec(cmd, NULL, NULL, NULL, NULL, ctx, req);
+}
+
+static int
+rpc_luci2_upgrade_start(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ return 0;
+}
+
+static int
+rpc_luci2_upgrade_clean(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ if (unlink("/tmp/firmware.bin"))
+ return rpc_errno_status();
+
+ return 0;
+}
+
+static int
+rpc_luci2_backup_restore(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ const char *cmd[4] = { "sysupgrade", "--restore-backup",
+ "/tmp/backup.tar.gz", NULL };
+
+ return rpc_exec(cmd, NULL, NULL, NULL, NULL, ctx, req);
+}
+
+static int
+rpc_luci2_backup_clean(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ if (unlink("/tmp/backup.tar.gz"))
+ return rpc_errno_status();
+
+ return 0;
+}
+
static FILE *
dnsmasq_leasefile(void)
struct blob_attr *msg)
{
FILE *f;
- struct blob_attr *tb[__RPC_OC_MAX];
+ struct blob_attr *tb[__RPC_D_MAX];
- blobmsg_parse(rpc_opkg_package_policy, __RPC_OC_MAX, tb,
+ blobmsg_parse(rpc_data_policy, __RPC_D_MAX, tb,
blob_data(msg), blob_len(msg));
- if (!tb[RPC_OC_CONFIG])
- return UBUS_STATUS_INVALID_ARGUMENT;
-
- if (blobmsg_type(tb[RPC_OC_CONFIG]) != BLOBMSG_TYPE_STRING)
+ if (!tb[RPC_D_DATA])
return UBUS_STATUS_INVALID_ARGUMENT;
- if (blobmsg_data_len(tb[RPC_OC_CONFIG]) >= 2048)
+ if (blobmsg_data_len(tb[RPC_D_DATA]) >= 2048)
return UBUS_STATUS_NOT_SUPPORTED;
if (!(f = fopen("/etc/opkg.conf", "w")))
return rpc_errno_status();
- fwrite(blobmsg_data(tb[RPC_OC_CONFIG]),
- blobmsg_data_len(tb[RPC_OC_CONFIG]), 1, f);
+ fwrite(blobmsg_data(tb[RPC_D_DATA]),
+ blobmsg_data_len(tb[RPC_D_DATA]), 1, f);
fclose(f);
return 0;
UBUS_METHOD("sshkeys_set", rpc_luci2_sshkeys_set,
rpc_sshkey_policy),
UBUS_METHOD("password_set", rpc_luci2_password_set,
- rpc_password_policy)
+ rpc_password_policy),
+ UBUS_METHOD_NOARG("led_list", rpc_luci2_led_list),
+ UBUS_METHOD_NOARG("usb_list", rpc_luci2_usb_list),
+ UBUS_METHOD_NOARG("upgrade_test", rpc_luci2_upgrade_test),
+ UBUS_METHOD("upgrade_start", rpc_luci2_upgrade_start,
+ rpc_upgrade_policy),
+ UBUS_METHOD_NOARG("upgrade_clean", rpc_luci2_upgrade_clean),
+ UBUS_METHOD_NOARG("backup_restore", rpc_luci2_backup_restore),
+ UBUS_METHOD_NOARG("backup_clean", rpc_luci2_backup_clean)
};
static struct ubus_object_type luci2_system_type =
UBUS_METHOD_NOARG("update", rpc_luci2_opkg_update),
UBUS_METHOD_NOARG("config_get", rpc_luci2_opkg_config_get),
UBUS_METHOD("config_set", rpc_luci2_opkg_config_set,
- rpc_opkg_config_policy)
+ rpc_data_policy)
};
static struct ubus_object_type luci2_opkg_type =