// ubus call test_ubus helloworld '{"id":1,"msg":"hello","array":["a","b"]}' static int test_hello(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) { struct blob_attr *tb[__HELLO_MAX]; int tmp_id; char *tmp_msg = NULL; int len; struct blob_attr *attr; void *arr; blobmsg_parse(hello_policy, __HELLO_MAX, tb, blob_data(msg), blob_len(msg)); blob_buf_init(&b, 0); if(tb[HELLO_ID]) { tmp_id = blobmsg_get_u32(tb[HELLO_ID]); blobmsg_add_u32(&b, "id", tmp_id); } if(tb[HELLO_MSG]) { tmp_msg = blobmsg_get_string(tb[HELLO_MSG]); blobmsg_add_string(&b, "msg", tmp_msg); } if(tb[HELLO_ARRAY] && blobmsg_type(tb[HELLO_ARRAY]) == BLOBMSG_TYPE_ARRAY) { arr = blobmsg_open_array(&b, "array"); len = blobmsg_data_len(tb[HELLO_ARRAY]); __blob_for_each_attr(attr, blobmsg_data(tb[HELLO_ARRAY]), len) { if (blobmsg_type(attr) == BLOBMSG_TYPE_STRING) { char *tmp = blobmsg_get_string(attr); blobmsg_add_blob(&b, attr); printf("array=%s\n", tmp); } } blobmsg_close_array(&b, arr); }
static void cmd_nas_get_serving_system_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg) { struct qmi_nas_get_serving_system_response res; static const char *reg_states[] = { [QMI_NAS_REGISTRATION_STATE_NOT_REGISTERED] = "not_registered", [QMI_NAS_REGISTRATION_STATE_REGISTERED] = "registered", [QMI_NAS_REGISTRATION_STATE_NOT_REGISTERED_SEARCHING] = "searching", [QMI_NAS_REGISTRATION_STATE_REGISTRATION_DENIED] = "registering_denied", [QMI_NAS_REGISTRATION_STATE_UNKNOWN] = "unknown", }; qmi_parse_nas_get_serving_system_response(msg, &res); if (res.set.serving_system) { int state = res.data.serving_system.registration_state; if (state > QMI_NAS_REGISTRATION_STATE_UNKNOWN) state = QMI_NAS_REGISTRATION_STATE_UNKNOWN; blobmsg_add_string(&status, "registration", reg_states[state]); } if (res.set.current_plmn) { blobmsg_add_u32(&status, "plmn_mcc", res.data.current_plmn.mcc); blobmsg_add_u32(&status, "plmn_mnc", res.data.current_plmn.mnc); if (res.data.current_plmn.description) blobmsg_add_string(&status, "plmn_description", res.data.current_plmn.description); } if (res.set.roaming_indicator) blobmsg_add_u8(&status, "roaming", !res.data.roaming_indicator); }
int igmp_rpc(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) { struct blob_buf bb; IGMPtable table[MAX_IGMP_ENTRY]; FILE *snptable; char line[256]; int idx = 0; void *t, *a; if ((snptable = fopen("/proc/net/igmp_snooping", "r"))) { while(fgets(line, sizeof(line), snptable) != NULL) { remove_newline(line); table[idx].exists = false; if(sscanf(single_space(line),"%s %s %s %s %x %x %x %s %x %x %x %d %x %d", table[idx].bridge, table[idx].device, table[idx].srcdev, table[idx].tags, &(table[idx].lantci), &(table[idx].wantci), &(table[idx].group), table[idx].mode, &(table[idx].RxGroup), &(table[idx].source), &(table[idx].reporter), &(table[idx].timeout), &(table[idx].Index), &(table[idx].ExcludPt)) == 14) { table[idx].exists = true; idx++; } } fclose(snptable); } else return UBUS_STATUS_NOT_FOUND; blob_buf_init(&bb, 0); a = blobmsg_open_array(&bb, "table"); for (idx = 0; idx < MAX_IGMP_ENTRY; idx++) { if (!table[idx].exists) break; t = blobmsg_open_table(&bb, NULL); blobmsg_add_string(&bb,"bridge", table[idx].bridge); blobmsg_add_string(&bb,"device", table[idx].device); blobmsg_add_string(&bb,"srcdev", table[idx].srcdev); blobmsg_add_string(&bb,"tags", table[idx].tags); blobmsg_add_u32(&bb,"lantci", table[idx].lantci); blobmsg_add_u32(&bb,"wantci", table[idx].wantci); blobmsg_add_string(&bb,"group", convert_to_ipaddr(table[idx].group)); blobmsg_add_string(&bb,"mode", table[idx].mode); blobmsg_add_string(&bb,"rxgroup", convert_to_ipaddr(table[idx].RxGroup)); blobmsg_add_string(&bb,"source", convert_to_ipaddr(table[idx].source)); blobmsg_add_string(&bb,"reporter", convert_to_ipaddr(table[idx].reporter)); blobmsg_add_u32(&bb,"timeout", table[idx].timeout); blobmsg_add_u32(&bb,"index", table[idx].Index); blobmsg_add_u32(&bb,"excludpt", table[idx].ExcludPt); blobmsg_close_table(&bb, t); } blobmsg_close_array(&bb, a); ubus_send_reply(ctx, req, bb.head); return 0; }
static int easycwmpd_handle_command(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) { struct blob_attr *tb[__COMMAND_MAX]; blobmsg_parse(command_policy, ARRAY_SIZE(command_policy), tb, blob_data(msg), blob_len(msg)); if (!tb[COMMAND_NAME]) return UBUS_STATUS_INVALID_ARGUMENT; blob_buf_init(&b, 0); char *cmd = blobmsg_data(tb[COMMAND_NAME]); char *info; if (!strcmp("reload", cmd)) { log_message(NAME, L_NOTICE, "triggered ubus reload\n"); easycwmp_reload(); blobmsg_add_u32(&b, "status", 0); if (asprintf(&info, "easycwmpd reloaded") == -1) goto error; } else if (!strcmp("stop", cmd)) { log_message(NAME, L_NOTICE, "triggered ubus stop\n"); ubus_timer.cb = ubus_easycwmpd_stop_callback; uloop_timeout_set(&ubus_timer, 1000); blobmsg_add_u32(&b, "status", 0); if (asprintf(&info, "easycwmpd stopped") == -1) goto error; } else { blobmsg_add_u32(&b, "status", -1); if (asprintf(&info, "%s command is not supported", cmd) == -1) goto error; } blobmsg_add_string(&b, "info", info); free(info); ubus_send_reply(ctx, req, b.head); blob_buf_free(&b); return 0; error: blob_buf_free(&b); return -1; }
static int gps_info(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) { struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); blob_buf_init(&b, 0); if (!stamp.tv_sec) { blobmsg_add_u8(&b, "signal", 0); } else { blobmsg_add_u32(&b, "age", now.tv_sec - stamp.tv_sec); blobmsg_add_string(&b, "latitude", latitude); blobmsg_add_string(&b, "longitude", longitude); blobmsg_add_string(&b, "elevation", elevation); blobmsg_add_string(&b, "course", course); blobmsg_add_string(&b, "speed", speed); } ubus_send_reply(ctx, req, b.head); return UBUS_STATUS_OK; }
static void cmd_wds_start_network_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg) { struct qmi_wds_start_network_response res; qmi_parse_wds_start_network_response(msg, &res); if (res.set.packet_data_handle) blobmsg_add_u32(&status, NULL, res.data.packet_data_handle); }
static int system_info(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) { void *c; time_t now; struct tm *tm; struct sysinfo info; now = time(NULL); if (!(tm = localtime(&now))) return UBUS_STATUS_UNKNOWN_ERROR; if (sysinfo(&info)) return UBUS_STATUS_UNKNOWN_ERROR; blob_buf_init(&b, 0); blobmsg_add_u32(&b, "uptime", info.uptime); blobmsg_add_u32(&b, "localtime", mktime(tm)); c = blobmsg_open_array(&b, "load"); blobmsg_add_u32(&b, NULL, info.loads[0]); blobmsg_add_u32(&b, NULL, info.loads[1]); blobmsg_add_u32(&b, NULL, info.loads[2]); blobmsg_close_array(&b, c); c = blobmsg_open_table(&b, "memory"); blobmsg_add_u64(&b, "total", info.mem_unit * info.totalram); blobmsg_add_u64(&b, "free", info.mem_unit * info.freeram); blobmsg_add_u64(&b, "shared", info.mem_unit * info.sharedram); blobmsg_add_u64(&b, "buffered", info.mem_unit * info.bufferram); blobmsg_close_table(&b, c); c = blobmsg_open_table(&b, "swap"); blobmsg_add_u64(&b, "total", info.mem_unit * info.totalswap); blobmsg_add_u64(&b, "free", info.mem_unit * info.freeswap); blobmsg_close_table(&b, c); ubus_send_reply(ctx, req, b.head); return UBUS_STATUS_OK; }
static void cmd_wds_start_network_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg) { struct qmi_wds_start_network_response res; qmi_parse_wds_start_network_response(msg, &res); if (res.set.packet_data_handle) { FILE *fp = fopen("/tmp/qmi-handle", "w+"); if (fp) { fprintf(fp, "%u", res.data.packet_data_handle); fclose(fp); } blobmsg_add_u32(&status, "handle", res.data.packet_data_handle); } }
static void ubus_push_method_data(const struct ubus_method *m) { void *mtbl; int i; mtbl = blobmsg_open_table(&b, m->name); for (i = 0; i < m->n_policy; i++) { if (m->mask && !(m->mask & (1 << i))) continue; blobmsg_add_u32(&b, m->policy[i].name, m->policy[i].type); } blobmsg_close_table(&b, mtbl); }
static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) { int i; (void)obj; (void)method; (void)msg; blob_buf_init(&b, BLOBMSG_TYPE_TABLE); for (i=0; i < __METRIC_MAX; i++) blobmsg_add_u32(&b, get_metric_name(i), daemon->metrics[i]); return ubus_send_reply(ctx, req, b.head); }
static void print_syscalls(int policy, const char *json) { void *c; int i; set_syscall("rt_sigaction", 1); set_syscall("sigreturn", 1); set_syscall("rt_sigreturn", 1); set_syscall("exit_group", 1); set_syscall("exit", 1); blob_buf_init(&b, 0); c = blobmsg_open_array(&b, "whitelist"); for (i = 0; i < ARRAY_SIZE(syscall_names); i++) { if (!syscall_count[i]) continue; if (syscall_names[i]) { if (debug) printf("syscall %d (%s) was called %d times\n", i, syscall_names[i], syscall_count[i]); blobmsg_add_string(&b, NULL, syscall_names[i]); } else { ERROR("no name found for syscall(%d)\n", i); } } blobmsg_close_array(&b, c); blobmsg_add_u32(&b, "policy", policy); if (json) { FILE *fp = fopen(json, "w"); if (fp) { fprintf(fp, "%s", blobmsg_format_json_indent(b.head, true, 0)); fclose(fp); INFO("saving syscall trace to %s\n", json); } else { ERROR("failed to open %s\n", json); } } else { printf("%s\n", blobmsg_format_json_indent(b.head, true, 0)); } }
static void cmd_nas_get_signal_info_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg) { struct qmi_nas_get_signal_info_response res; qmi_parse_nas_get_signal_info_response(msg, &res); if (res.set.cdma_signal_strength) { blobmsg_add_string(&status, "type", "cdma"); blobmsg_add_u32(&status, "rssi", (int32_t) res.data.cdma_signal_strength.rssi); blobmsg_add_u32(&status, "ecio", (int32_t) res.data.cdma_signal_strength.ecio); } if (res.set.hdr_signal_strength) { blobmsg_add_string(&status, "type", "hdr"); blobmsg_add_u32(&status, "rssi", (int32_t) res.data.hdr_signal_strength.rssi); blobmsg_add_u32(&status, "ecio", (int32_t) res.data.hdr_signal_strength.ecio); blobmsg_add_u32(&status, "io", res.data.hdr_signal_strength.io); } if (res.set.gsm_signal_strength) { blobmsg_add_string(&status, "type", "gsm"); blobmsg_add_u32(&status, "signal", (int32_t) res.data.gsm_signal_strength); } if (res.set.wcdma_signal_strength) { blobmsg_add_string(&status, "type", "wcdma"); blobmsg_add_u32(&status, "rssi", (int32_t) res.data.wcdma_signal_strength.rssi); blobmsg_add_u32(&status, "ecio", (int32_t) res.data.wcdma_signal_strength.ecio); } if (res.set.lte_signal_strength) { blobmsg_add_string(&status, "type", "lte"); blobmsg_add_u32(&status, "rssi", (int32_t) res.data.lte_signal_strength.rssi); blobmsg_add_u32(&status, "rsrq", (int32_t) res.data.lte_signal_strength.rsrq); blobmsg_add_u32(&status, "rsrp", (int32_t) res.data.lte_signal_strength.rsrp); blobmsg_add_u32(&status, "snr", (int32_t) res.data.lte_signal_strength.snr); } }
static void cmd_wds_get_current_settings_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg) { void *v4, *v6, *d, *t; struct qmi_wds_get_current_settings_response res; const char *pdptypes[] = { [QMI_WDS_PDP_TYPE_IPV4] = "ipv4", [QMI_WDS_PDP_TYPE_PPP] = "ppp", [QMI_WDS_PDP_TYPE_IPV6] = "ipv6", [QMI_WDS_PDP_TYPE_IPV4_OR_IPV6] = "ipv4-or-ipv6", }; const struct ip_modes { const char *name; const QmiWdsIpFamily mode; } modes[] = { { "ipv4", QMI_WDS_IP_FAMILY_IPV4 }, { "ipv6", QMI_WDS_IP_FAMILY_IPV6 }, { "unspecified", QMI_WDS_IP_FAMILY_UNSPECIFIED }, }; int i; qmi_parse_wds_get_current_settings_response(msg, &res); t = blobmsg_open_table(&status, NULL); if (res.set.pdp_type && res.data.pdp_type < ARRAY_SIZE(pdptypes)) blobmsg_add_string(&status, "pdp-type", pdptypes[res.data.pdp_type]); if (res.set.ip_family) { for (i = 0; i < ARRAY_SIZE(modes); i++) { if (modes[i].mode != res.data.ip_family) continue; blobmsg_add_string(&status, "ip-family", modes[i].name); break; } } if (res.set.mtu) blobmsg_add_u32(&status, "mtu", res.data.mtu); /* IPV4 */ v4 = blobmsg_open_table(&status, "ipv4"); if (res.set.ipv4_address) wds_to_ipv4("ip", res.data.ipv4_address); if (res.set.primary_ipv4_dns_address) wds_to_ipv4("dns1", res.data.primary_ipv4_dns_address); if (res.set.secondary_ipv4_dns_address) wds_to_ipv4("dns2", res.data.secondary_ipv4_dns_address); if (res.set.ipv4_gateway_address) wds_to_ipv4("gateway", res.data.ipv4_gateway_address); if (res.set.ipv4_gateway_subnet_mask) wds_to_ipv4("subnet", res.data.ipv4_gateway_subnet_mask); blobmsg_close_table(&status, v4); /* IPV6 */ v6 = blobmsg_open_table(&status, "ipv6"); if (res.set.ipv6_address) { wds_to_ipv6("ip", res.data.ipv6_address.address); blobmsg_add_u32(&status, "ip-prefix-length", res.data.ipv6_address.prefix_length); } if (res.set.ipv6_gateway_address) { wds_to_ipv6("gateway", res.data.ipv6_gateway_address.address); blobmsg_add_u32(&status, "gw-prefix-length", res.data.ipv6_gateway_address.prefix_length); } if (res.set.ipv6_primary_dns_address) wds_to_ipv6("dns1", res.data.ipv6_primary_dns_address); if (res.set.ipv6_secondary_dns_address) wds_to_ipv6("dns2", res.data.ipv6_secondary_dns_address); blobmsg_close_table(&status, v6); d = blobmsg_open_table(&status, "domain-names"); for (i = 0; i < res.data.domain_name_list_n; i++) { blobmsg_add_string(&status, NULL, res.data.domain_name_list[i]); } blobmsg_close_table(&status, d); blobmsg_close_table(&status, t); }
int main(int argc, char **argv) { static struct ubus_request req; struct ubus_context *ctx; uint32_t id; const char *ubus_socket = NULL; int ch, ret, lines = 0; static struct blob_buf b; int tries = 5; signal(SIGPIPE, SIG_IGN); while ((ch = getopt(argc, argv, "u0fcs:l:r:F:p:S:P:h:")) != -1) { switch (ch) { case 'u': log_udp = 1; break; case '0': log_trailer_null = 1; break; case 's': ubus_socket = optarg; break; case 'r': log_ip = optarg++; log_port = argv[optind++]; break; case 'F': log_file = optarg; break; case 'p': pid_file = optarg; break; case 'P': log_prefix = optarg; break; case 'f': log_follow = 1; break; case 'l': lines = atoi(optarg); break; case 'S': log_size = atoi(optarg); if (log_size < 1) log_size = 1; log_size *= 1024; break; case 'h': hostname = optarg; break; default: return usage(*argv); } } uloop_init(); ctx = ubus_connect(ubus_socket); if (!ctx) { fprintf(stderr, "Failed to connect to ubus\n"); return -1; } ubus_add_uloop(ctx); /* ugly ugly ugly ... we need a real reconnect logic */ do { ret = ubus_lookup_id(ctx, "log", &id); if (ret) { fprintf(stderr, "Failed to find log object: %s\n", ubus_strerror(ret)); sleep(1); continue; } blob_buf_init(&b, 0); if (lines) blobmsg_add_u32(&b, "lines", lines); else if (log_follow) blobmsg_add_u32(&b, "lines", 0); if (log_follow) { if (pid_file) { FILE *fp = fopen(pid_file, "w+"); if (fp) { fprintf(fp, "%d", getpid()); fclose(fp); } } } if (log_ip && log_port) { openlog("logread", LOG_PID, LOG_DAEMON); log_type = LOG_NET; sender.cb = log_handle_fd; retry.cb = log_handle_reconnect; uloop_timeout_set(&retry, 1000); } else if (log_file) { log_type = LOG_FILE; sender.fd = open(log_file, O_CREAT | O_WRONLY| O_APPEND, 0600); if (sender.fd < 0) { fprintf(stderr, "failed to open %s: %s\n", log_file, strerror(errno)); exit(-1); } } else { sender.fd = STDOUT_FILENO; } ubus_invoke_async(ctx, id, "read", b.head, &req); req.fd_cb = logread_fd_cb; ubus_complete_request_async(ctx, &req); uloop_run(); ubus_free(ctx); uloop_done(); } while (ret && tries--); return ret; }
static int watchdog_set(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) { struct blob_attr *tb[__WDT_MAX]; const char *status; if (!msg) return UBUS_STATUS_INVALID_ARGUMENT; blobmsg_parse(watchdog_policy, __WDT_MAX, tb, blob_data(msg), blob_len(msg)); if (tb[WDT_FREQUENCY]) { unsigned int timeout = watchdog_timeout(0); unsigned int freq = blobmsg_get_u32(tb[WDT_FREQUENCY]); if (freq) { if (freq > timeout / 2) freq = timeout / 2; watchdog_frequency(freq); } } if (tb[WDT_TIMEOUT]) { unsigned int timeout = blobmsg_get_u32(tb[WDT_TIMEOUT]); unsigned int frequency = watchdog_frequency(0); if (timeout <= frequency) timeout = frequency * 2; watchdog_timeout(timeout); } if (tb[WDT_STOP]) watchdog_set_stopped(blobmsg_get_bool(tb[WDT_STOP])); if (watchdog_fd() == NULL) status = "offline"; else if (watchdog_get_stopped()) status = "stopped"; else status = "running"; blob_buf_init(&b, 0); blobmsg_add_string(&b, "status", status); blobmsg_add_u32(&b, "timeout", watchdog_timeout(0)); blobmsg_add_u32(&b, "frequency", watchdog_frequency(0)); ubus_send_reply(ctx, req, b.head); return 0; }