X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fuqmi.git;a=blobdiff_plain;f=commands.c;h=f9545a9c58438df5f58f21883de280eea084836f;hp=152b1bc30cc1e4143337b27167d2a3e968f7caf1;hb=HEAD;hpb=b29e4d756726e9685ad812210c5f2e5298100140 diff --git a/commands.c b/commands.c index 152b1bc..f9545a9 100644 --- a/commands.c +++ b/commands.c @@ -1,11 +1,39 @@ +/* + * uqmi -- tiny QMI support implementation + * + * Copyright (C) 2014-2015 Felix Fietkau + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + #include #include #include #include #include + +#include +#include + #include "uqmi.h" #include "commands.h" +static struct blob_buf status; +bool single_line = false; + static void no_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg) { } @@ -13,22 +41,20 @@ static void no_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg * static void cmd_version_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg) { struct qmi_ctl_get_version_info_response res; + void *c; + char name_buf[16]; int i; - if (!msg) { - printf("Request version failed: %d\n", req->ret); - return; - } - qmi_parse_ctl_get_version_info_response(msg, &res); - printf("Found %d: services:\n", res.data.service_list_n); + c = blobmsg_open_table(&status, NULL); for (i = 0; i < res.data.service_list_n; i++) { - printf("Service %d, version: %d.%d\n", - res.data.service_list[i].service, + sprintf(name_buf, "service_%d", res.data.service_list[i].service); + blobmsg_printf(&status, name_buf, "%d,%d", res.data.service_list[i].major_version, res.data.service_list[i].minor_version); } + blobmsg_close_table(&status, c); } static enum qmi_cmd_result @@ -38,6 +64,14 @@ cmd_version_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg return QMI_CMD_REQUEST; } +#define cmd_sync_cb no_cb +static enum qmi_cmd_result +cmd_sync_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg) +{ + qmi_set_ctl_sync_request(msg); + return QMI_CMD_REQUEST; +} + #define cmd_get_client_id_cb no_cb static enum qmi_cmd_result cmd_get_client_id_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg) @@ -94,8 +128,48 @@ cmd_set_client_id_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct q return QMI_CMD_DONE; } +static int +qmi_get_array_idx(const char **array, int size, const char *str) +{ + int i; + + for (i = 0; i < size; i++) { + if (!array[i]) + continue; + + if (!strcmp(array[i], str)) + return i; + } + + return -1; +} + +#define cmd_ctl_set_data_format_cb no_cb +static enum qmi_cmd_result +cmd_ctl_set_data_format_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg) +{ + struct qmi_ctl_set_data_format_request sreq = {}; + const char *modes[] = { + [QMI_CTL_DATA_LINK_PROTOCOL_802_3] = "802.3", + [QMI_CTL_DATA_LINK_PROTOCOL_RAW_IP] = "raw-ip", + }; + int mode = qmi_get_array_idx(modes, ARRAY_SIZE(modes), arg); + + if (mode < 0) { + uqmi_add_error("Invalid mode (modes: 802.3, raw-ip)"); + return QMI_CMD_EXIT; + } + + qmi_set_ctl_set_data_format_request(msg, &sreq); + return QMI_CMD_DONE; +} + #include "commands-wds.c" #include "commands-dms.c" +#include "commands-nas.c" +#include "commands-wms.c" +#include "commands-wda.c" +#include "commands-uim.c" #define __uqmi_command(_name, _optname, _arg, _type) \ [__UQMI_COMMAND_##_name] = { \ @@ -122,46 +196,78 @@ void uqmi_add_command(char *arg, int cmd) cmds[idx].arg = optarg; } +static void uqmi_print_result(struct blob_attr *data) +{ + char *str; + + if (!blob_len(data)) + return; + + str = blobmsg_format_json_indent(blob_data(data), false, single_line ? -1 : 0); + if (!str) + return; + + printf("%s\n", str); + free(str); +} + static bool __uqmi_run_commands(struct qmi_dev *qmi, bool option) { - static char buf[2048]; static struct qmi_request req; + char *buf = qmi->buf; int i; for (i = 0; i < n_cmds; i++) { enum qmi_cmd_result res; bool cmd_option = cmds[i].handler->type == CMD_TYPE_OPTION; + bool do_break = false; if (cmd_option != option) continue; + blob_buf_init(&status, 0); if (cmds[i].handler->type > QMI_SERVICE_CTL && qmi_service_connect(qmi, cmds[i].handler->type, -1)) { - fprintf(stderr, "Error in command '%s': failed to connect to service\n", - cmds[i].handler->name); - return false; + uqmi_add_error("Failed to connect to service"); + res = QMI_CMD_EXIT; + } else { + res = cmds[i].handler->prepare(qmi, &req, (void *) buf, cmds[i].arg); } - res = cmds[i].handler->prepare(qmi, &req, (void *) buf, cmds[i].arg); - switch(res) { - case QMI_CMD_REQUEST: - qmi_request_start(qmi, &req, (void *) buf, cmds[i].handler->cb); - qmi_request_wait(qmi, &req); - break; - case QMI_CMD_EXIT: - return false; - case QMI_CMD_DONE: - default: - continue; + + if (res == QMI_CMD_REQUEST) { + qmi_request_start(qmi, &req, cmds[i].handler->cb); + req.no_error_cb = true; + if (qmi_request_wait(qmi, &req)) { + uqmi_add_error(qmi_get_error_str(req.ret)); + do_break = true; + } + } else if (res == QMI_CMD_EXIT) { + do_break = true; } + + uqmi_print_result(status.head); + if (do_break) + return false; } return true; } -void uqmi_run_commands(struct qmi_dev *qmi) +int uqmi_add_error(const char *msg) { - if (__uqmi_run_commands(qmi, true)) - __uqmi_run_commands(qmi, false); + blobmsg_add_string(&status, NULL, msg); + return QMI_CMD_EXIT; +} + +bool uqmi_run_commands(struct qmi_dev *qmi) +{ + bool ret; + + ret = __uqmi_run_commands(qmi, true) && + __uqmi_run_commands(qmi, false); + free(cmds); cmds = NULL; n_cmds = 0; + + return ret; }