diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 512100432..499d3e837 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -920,6 +920,99 @@ static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s, } +extern int wpa_debug_level; +extern int wpa_debug_timestamp; + +static const char * debug_level_str(int level) +{ + switch (level) { + case MSG_EXCESSIVE: + return "EXCESSIVE"; + case MSG_MSGDUMP: + return "MSGDUMP"; + case MSG_DEBUG: + return "DEBUG"; + case MSG_INFO: + return "INFO"; + case MSG_WARNING: + return "WARNING"; + case MSG_ERROR: + return "ERROR"; + default: + return "?"; + } +} + + +static int str_to_debug_level(const char *s) +{ + if (os_strcasecmp(s, "EXCESSIVE") == 0) + return MSG_EXCESSIVE; + if (os_strcasecmp(s, "MSGDUMP") == 0) + return MSG_MSGDUMP; + if (os_strcasecmp(s, "DEBUG") == 0) + return MSG_DEBUG; + if (os_strcasecmp(s, "INFO") == 0) + return MSG_INFO; + if (os_strcasecmp(s, "WARNING") == 0) + return MSG_WARNING; + if (os_strcasecmp(s, "ERROR") == 0) + return MSG_ERROR; + return -1; +} + + +static int wpa_supplicant_ctrl_iface_log_level(struct wpa_supplicant *wpa_s, + char *cmd, char *buf, + size_t buflen) +{ + char *pos, *end, *stamp; + int ret; + + if (cmd == NULL) { + return -1; + } + + /* cmd: "LOG_LEVEL []" */ + if (*cmd == '\0') { + pos = buf; + end = buf + buflen; + ret = os_snprintf(pos, end - pos, "Current level: %s\n" + "Timestamp: %d\n", + debug_level_str(wpa_debug_level), + wpa_debug_timestamp); + if (ret < 0 || ret >= end - pos) + ret = 0; + + return ret; + } + + while (*cmd == ' ') + cmd++; + + stamp = os_strchr(cmd, ' '); + if (stamp) { + *stamp++ = '\0'; + while (*stamp == ' ') { + stamp++; + } + } + + if (cmd && os_strlen(cmd)) { + int level = str_to_debug_level(cmd); + if (level < 0) + return -1; + wpa_debug_level = level; + } + + if (stamp && os_strlen(stamp)) + wpa_debug_timestamp = atoi(stamp); + + os_memcpy(buf, "OK\n", 3); + return 3; +} + + static int wpa_supplicant_ctrl_iface_list_networks( struct wpa_supplicant *wpa_s, char *buf, size_t buflen) { @@ -3309,6 +3402,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, } else if (os_strncmp(buf, "BSSID ", 6) == 0) { if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6)) reply_len = -1; + } else if (os_strncmp(buf, "LOG_LEVEL", 9) == 0) { + reply_len = wpa_supplicant_ctrl_iface_log_level( + wpa_s, buf + 9, reply, reply_size); } else if (os_strcmp(buf, "LIST_NETWORKS") == 0) { reply_len = wpa_supplicant_ctrl_iface_list_networks( wpa_s, reply, reply_size); diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 2089df29e..8461a7479 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -1224,6 +1224,32 @@ static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[]) } +static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + char cmd[256], *pos, *end; + int i, ret; + + end = cmd + sizeof(cmd); + pos = cmd; + ret = os_snprintf(pos, end - pos, "LOG_LEVEL"); + if (ret < 0 || ret >= end - pos) { + printf("Too long LOG_LEVEL command.\n"); + return -1; + } + pos += ret; + for (i = 0; i < argc; i++) { + ret = os_snprintf(pos, end - pos, " %s", argv[i]); + if (ret < 0 || ret >= end - pos) { + printf("Too long LOG_LEVEL command.\n"); + return -1; + } + pos += ret; + } + + return wpa_ctrl_command(ctrl, cmd); +} + + static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc, char *argv[]) { @@ -2471,6 +2497,10 @@ static struct wpa_cli_cmd wpa_cli_commands[] = { { "bssid", wpa_cli_cmd_bssid, cli_cmd_flag_none, " = set preferred BSSID for an SSID" }, + { "log_level", wpa_cli_cmd_log_level, + cli_cmd_flag_none, + " [] = update the log level/timestamp\n" + "log_level = display the current log level and log options" }, { "list_networks", wpa_cli_cmd_list_networks, cli_cmd_flag_none, "= list configured networks" },