1d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/* 2d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * FST module - Control Interface implementation 3d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * Copyright (c) 2014, Qualcomm Atheros, Inc. 4d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * 5d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * See README for more details. 7d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */ 8d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 9d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include "utils/includes.h" 10d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include "utils/common.h" 11d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include "common/defs.h" 12d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include "list.h" 13d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include "fst/fst.h" 14d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include "fst/fst_internal.h" 15d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include "fst_ctrl_defs.h" 16d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include "fst_ctrl_iface.h" 17d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 18d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 19d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic struct fst_group * get_fst_group_by_id(const char *id) 20d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 21d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_group *g; 22d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 23d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt foreach_fst_group(g) { 24d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *group_id = fst_group_get_id(g); 25d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 26d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (os_strncmp(group_id, id, os_strlen(group_id)) == 0) 27d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return g; 28d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 29d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 30d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return NULL; 31d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 32d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 33d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 34d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/* notifications */ 35d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic Boolean format_session_state_extra(const union fst_event_extra *extra, 36d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt char *buffer, size_t size) 37d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 38d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int len; 39d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt char reject_str[32] = FST_CTRL_PVAL_NONE; 40d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *initiator = FST_CTRL_PVAL_NONE; 41d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const struct fst_event_extra_session_state *ss; 42d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 43d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ss = &extra->session_state; 44d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (ss->new_state != FST_SESSION_STATE_INITIAL) 45d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return TRUE; 46d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 47d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt switch (ss->extra.to_initial.reason) { 48d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case REASON_REJECT: 49d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (ss->extra.to_initial.reject_code != WLAN_STATUS_SUCCESS) 50d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_snprintf(reject_str, sizeof(reject_str), "%u", 51d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ss->extra.to_initial.reject_code); 52d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* no break */ 53d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case REASON_TEARDOWN: 54d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case REASON_SWITCH: 55d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt switch (ss->extra.to_initial.initiator) { 56d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case FST_INITIATOR_LOCAL: 57d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt initiator = FST_CS_PVAL_INITIATOR_LOCAL; 58d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 59d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case FST_INITIATOR_REMOTE: 60d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt initiator = FST_CS_PVAL_INITIATOR_REMOTE; 61d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 62d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt default: 63d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 64d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 65d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 66d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt default: 67d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 68d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 69d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 70d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt len = os_snprintf(buffer, size, 71d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CES_PNAME_REASON "=%s " 72d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CES_PNAME_REJECT_CODE "=%s " 73d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CES_PNAME_INITIATOR "=%s", 74d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_reason_name(ss->extra.to_initial.reason), 75d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt reject_str, initiator); 76d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 77d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return !os_snprintf_error(size, len); 78d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 79d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 80d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 81d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void fst_ctrl_iface_notify(struct fst_iface *f, u32 session_id, 82d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt enum fst_event_type event_type, 83d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const union fst_event_extra *extra) 84d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 85d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_group *g; 86d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt char extra_str[128] = ""; 87d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const struct fst_event_extra_session_state *ss; 88d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const struct fst_event_extra_iface_state *is; 89d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const struct fst_event_extra_peer_state *ps; 90d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 91d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* 92d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * FST can use any of interface objects as it only sends messages 93d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * on global Control Interface, so we just pick the 1st one. 94d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */ 95d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 96d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!f) { 97d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt foreach_fst_group(g) { 98d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt f = fst_group_first_iface(g); 99d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (f) 100d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 101d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 102d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!f) 103d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return; 104d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 105d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 106d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt WPA_ASSERT(f->iface_obj.ctx); 107d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 108d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt switch (event_type) { 109d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case EVENT_FST_IFACE_STATE_CHANGED: 110d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!extra) 111d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return; 112d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt is = &extra->iface_state; 113d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_msg_global_only(f->iface_obj.ctx, MSG_INFO, 114d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CTRL_EVENT_IFACE " %s " 115d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CEI_PNAME_IFNAME "=%s " 116d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CEI_PNAME_GROUP "=%s", 117d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt is->attached ? FST_CEI_PNAME_ATTACHED : 118d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CEI_PNAME_DETACHED, 119d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt is->ifname, is->group_id); 120d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 121d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case EVENT_PEER_STATE_CHANGED: 122d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!extra) 123d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return; 124d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ps = &extra->peer_state; 125d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_msg_global_only(fst_iface_get_wpa_obj_ctx(f), MSG_INFO, 126d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CTRL_EVENT_PEER " %s " 127d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CEP_PNAME_IFNAME "=%s " 128d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CEP_PNAME_ADDR "=" MACSTR, 129d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ps->connected ? FST_CEP_PNAME_CONNECTED : 130d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CEP_PNAME_DISCONNECTED, 131d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ps->ifname, MAC2STR(ps->addr)); 132d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 133d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case EVENT_FST_SESSION_STATE_CHANGED: 134d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!extra) 135d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return; 136d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!format_session_state_extra(extra, extra_str, 137d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sizeof(extra_str))) { 138d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_ERROR, 139d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "CTRL: Cannot format STATE_CHANGE extra"); 140d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt extra_str[0] = 0; 141d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 142d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ss = &extra->session_state; 143d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_msg_global_only(fst_iface_get_wpa_obj_ctx(f), MSG_INFO, 144d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CTRL_EVENT_SESSION " " 145d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CES_PNAME_SESSION_ID "=%u " 146d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CES_PNAME_EVT_TYPE "=%s " 147d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CES_PNAME_OLD_STATE "=%s " 148d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CES_PNAME_NEW_STATE "=%s %s", 149d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt session_id, 150d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_session_event_type_name(event_type), 151d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_session_state_name(ss->old_state), 152d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_session_state_name(ss->new_state), 153d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt extra_str); 154d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 155d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case EVENT_FST_ESTABLISHED: 156d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case EVENT_FST_SETUP: 157d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_msg_global_only(fst_iface_get_wpa_obj_ctx(f), MSG_INFO, 158d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CTRL_EVENT_SESSION " " 159d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CES_PNAME_SESSION_ID "=%u " 160d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CES_PNAME_EVT_TYPE "=%s", 161d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt session_id, 162d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_session_event_type_name(event_type)); 163d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 164d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 165d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 166d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 167d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 168d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/* command processors */ 169d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 170d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/* fst session_get */ 171d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int session_get(const char *session_id, char *buf, size_t buflen) 172d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 173d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_session *s; 174d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_iface *new_iface, *old_iface; 175d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const u8 *old_peer_addr, *new_peer_addr; 176d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u32 id; 177d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 178d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt id = strtoul(session_id, NULL, 0); 179d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 180d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt s = fst_session_get_by_id(id); 181d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!s) { 182d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_WARNING, "CTRL: Cannot find session %u", id); 183d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 184d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 185d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 186d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt old_peer_addr = fst_session_get_peer_addr(s, TRUE); 187d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt new_peer_addr = fst_session_get_peer_addr(s, FALSE); 188d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt new_iface = fst_session_get_iface(s, FALSE); 189d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt old_iface = fst_session_get_iface(s, TRUE); 190d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 191d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, 192d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CSG_PNAME_OLD_PEER_ADDR "=" MACSTR "\n" 193d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CSG_PNAME_NEW_PEER_ADDR "=" MACSTR "\n" 194d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CSG_PNAME_NEW_IFNAME "=%s\n" 195d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CSG_PNAME_OLD_IFNAME "=%s\n" 196d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CSG_PNAME_LLT "=%u\n" 197d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CSG_PNAME_STATE "=%s\n", 198d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt MAC2STR(old_peer_addr), 199d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt MAC2STR(new_peer_addr), 200d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt new_iface ? fst_iface_get_name(new_iface) : 201d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CTRL_PVAL_NONE, 202d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt old_iface ? fst_iface_get_name(old_iface) : 203d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt FST_CTRL_PVAL_NONE, 204d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_session_get_llt(s), 205d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_session_state_name(fst_session_get_state(s))); 206d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 207d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 208d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 209d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/* fst session_set */ 210d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int session_set(const char *session_id, char *buf, size_t buflen) 211d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 212d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_session *s; 213d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt char *p, *q; 214d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u32 id; 215d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int ret; 216d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 217d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt id = strtoul(session_id, &p, 0); 218d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 219d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt s = fst_session_get_by_id(id); 220d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!s) { 221d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_WARNING, "CTRL: Cannot find session %u", id); 222d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 223d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 224d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 225d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (*p != ' ' || !(q = os_strchr(p + 1, '='))) 226d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 227d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p++; 228d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 229d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (os_strncasecmp(p, FST_CSS_PNAME_OLD_IFNAME, q - p) == 0) { 230d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret = fst_session_set_str_ifname(s, q + 1, TRUE); 231d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (os_strncasecmp(p, FST_CSS_PNAME_NEW_IFNAME, q - p) == 0) { 232d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret = fst_session_set_str_ifname(s, q + 1, FALSE); 233d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (os_strncasecmp(p, FST_CSS_PNAME_OLD_PEER_ADDR, q - p) == 0) { 234d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret = fst_session_set_str_peer_addr(s, q + 1, TRUE); 235d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (os_strncasecmp(p, FST_CSS_PNAME_NEW_PEER_ADDR, q - p) == 0) { 236d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret = fst_session_set_str_peer_addr(s, q + 1, FALSE); 237d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (os_strncasecmp(p, FST_CSS_PNAME_LLT, q - p) == 0) { 238d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret = fst_session_set_str_llt(s, q + 1); 239d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else { 240d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_ERROR, "CTRL: Unknown parameter: %s", p); 241d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 242d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 243d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 244d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "%s\n", ret ? "FAIL" : "OK"); 245d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 246d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 247d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 248d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/* fst session_add/remove */ 249d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int session_add(const char *group_id, char *buf, size_t buflen) 250d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 251d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_group *g; 252d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_session *s; 253d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 254d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt g = get_fst_group_by_id(group_id); 255d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!g) { 256d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_WARNING, "CTRL: Cannot find group '%s'", 257d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt group_id); 258d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 259d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 260d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 261d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt s = fst_session_create(g); 262d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!s) { 263d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_ERROR, 264d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "CTRL: Cannot create session for group '%s'", 265d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt group_id); 266d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 267d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 268d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 269d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "%u\n", fst_session_get_id(s)); 270d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 271d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 272d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 273d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int session_remove(const char *session_id, char *buf, size_t buflen) 274d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 275d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_session *s; 276d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_group *g; 277d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u32 id; 278d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 279d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt id = strtoul(session_id, NULL, 0); 280d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 281d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt s = fst_session_get_by_id(id); 282d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!s) { 283d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_WARNING, "CTRL: Cannot find session %u", id); 284d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 285d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 286d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 287d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt g = fst_session_get_group(s); 288d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_session_reset(s); 289d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_session_delete(s); 290d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_group_delete_if_empty(g); 291d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 292d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "OK\n"); 293d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 294d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 295d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 296d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/* fst session_initiate */ 297d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int session_initiate(const char *session_id, char *buf, size_t buflen) 298d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 299d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_session *s; 300d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u32 id; 301d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 302d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt id = strtoul(session_id, NULL, 0); 303d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 304d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt s = fst_session_get_by_id(id); 305d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!s) { 306d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_WARNING, "CTRL: Cannot find session %u", id); 307d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 308d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 309d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 310d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (fst_session_initiate_setup(s)) { 311d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_WARNING, "CTRL: Cannot initiate session %u", id); 312d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 313d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 314d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 315d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "OK\n"); 316d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 317d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 318d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 319d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/* fst session_respond */ 320d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int session_respond(const char *session_id, char *buf, size_t buflen) 321d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 322d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_session *s; 323d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt char *p; 324d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u32 id; 325d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u8 status_code; 326d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 327d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt id = strtoul(session_id, &p, 0); 328d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 329d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt s = fst_session_get_by_id(id); 330d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!s) { 331d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_WARNING, "CTRL: Cannot find session %u", id); 332d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 333d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 334d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 335d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (*p != ' ') 336d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 337d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p++; 338d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 339d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!os_strcasecmp(p, FST_CS_PVAL_RESPONSE_ACCEPT)) { 340d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt status_code = WLAN_STATUS_SUCCESS; 341d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (!os_strcasecmp(p, FST_CS_PVAL_RESPONSE_REJECT)) { 342d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt status_code = WLAN_STATUS_PENDING_ADMITTING_FST_SESSION; 343d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else { 344d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_WARNING, 345d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "CTRL: session %u: unknown response status: %s", 346d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt id, p); 347d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 348d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 349d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 350d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (fst_session_respond(s, status_code)) { 351d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_WARNING, "CTRL: Cannot respond to session %u", 352d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt id); 353d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 354d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 355d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 356d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_INFO, "CTRL: session %u responded", id); 357d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 358d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "OK\n"); 359d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 360d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 361d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 362d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/* fst session_transfer */ 363d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int session_transfer(const char *session_id, char *buf, size_t buflen) 364d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 365d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_session *s; 366d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u32 id; 367d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 368d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt id = strtoul(session_id, NULL, 0); 369d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 370d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt s = fst_session_get_by_id(id); 371d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!s) { 372d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_WARNING, "CTRL: Cannot find session %u", id); 373d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 374d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 375d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 376d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (fst_session_initiate_switch(s)) { 377d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_WARNING, 378d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "CTRL: Cannot initiate ST for session %u", id); 379d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 380d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 381d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 382d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "OK\n"); 383d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 384d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 385d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 386d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/* fst session_teardown */ 387d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int session_teardown(const char *session_id, char *buf, size_t buflen) 388d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 389d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_session *s; 390d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u32 id; 391d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 392d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt id = strtoul(session_id, NULL, 0); 393d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 394d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt s = fst_session_get_by_id(id); 395d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!s) { 396d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_WARNING, "CTRL: Cannot find session %u", id); 397d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 398d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 399d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 400d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (fst_session_tear_down_setup(s)) { 401d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_WARNING, "CTRL: Cannot tear down session %u", 402d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt id); 403d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 404d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 405d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 406d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "OK\n"); 407d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 408d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 409d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 410d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef CONFIG_FST_TEST 411d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/* fst test_request */ 412d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int test_request(const char *request, char *buf, size_t buflen) 413d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 414d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *p = request; 415d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int ret; 416d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 417d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!os_strncasecmp(p, FST_CTR_SEND_SETUP_REQUEST, 418d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_strlen(FST_CTR_SEND_SETUP_REQUEST))) { 419d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret = fst_test_req_send_fst_request( 420d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p + os_strlen(FST_CTR_SEND_SETUP_REQUEST)); 421d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (!os_strncasecmp(p, FST_CTR_SEND_SETUP_RESPONSE, 422d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_strlen(FST_CTR_SEND_SETUP_RESPONSE))) { 423d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret = fst_test_req_send_fst_response( 424d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p + os_strlen(FST_CTR_SEND_SETUP_RESPONSE)); 425d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (!os_strncasecmp(p, FST_CTR_SEND_ACK_REQUEST, 426d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_strlen(FST_CTR_SEND_ACK_REQUEST))) { 427d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret = fst_test_req_send_ack_request( 428d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p + os_strlen(FST_CTR_SEND_ACK_REQUEST)); 429d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (!os_strncasecmp(p, FST_CTR_SEND_ACK_RESPONSE, 430d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_strlen(FST_CTR_SEND_ACK_RESPONSE))) { 431d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret = fst_test_req_send_ack_response( 432d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p + os_strlen(FST_CTR_SEND_ACK_RESPONSE)); 433d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (!os_strncasecmp(p, FST_CTR_SEND_TEAR_DOWN, 434d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_strlen(FST_CTR_SEND_TEAR_DOWN))) { 435d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret = fst_test_req_send_tear_down( 436d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p + os_strlen(FST_CTR_SEND_TEAR_DOWN)); 437d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (!os_strncasecmp(p, FST_CTR_GET_FSTS_ID, 438d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_strlen(FST_CTR_GET_FSTS_ID))) { 439d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u32 fsts_id = fst_test_req_get_fsts_id( 440d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p + os_strlen(FST_CTR_GET_FSTS_ID)); 441d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (fsts_id != FST_FSTS_ID_NOT_FOUND) 442d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "%u\n", fsts_id); 443d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 444d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (!os_strncasecmp(p, FST_CTR_GET_LOCAL_MBIES, 445d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_strlen(FST_CTR_GET_LOCAL_MBIES))) { 446d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return fst_test_req_get_local_mbies( 447d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p + os_strlen(FST_CTR_GET_LOCAL_MBIES), buf, buflen); 448d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (!os_strncasecmp(p, FST_CTR_IS_SUPPORTED, 449d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_strlen(FST_CTR_IS_SUPPORTED))) { 450d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret = 0; 451d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else { 452d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_ERROR, "CTRL: Unknown parameter: %s", p); 453d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 454d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 455d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 456d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "%s\n", ret ? "FAIL" : "OK"); 457d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 458d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* CONFIG_FST_TEST */ 459d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 460d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 461d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/* fst list_sessions */ 462d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstruct list_sessions_cb_ctx { 463d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt char *buf; 464d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt size_t buflen; 465d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt size_t reply_len; 466d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt}; 467d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 468d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 469d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void list_session_enum_cb(struct fst_group *g, struct fst_session *s, 470d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt void *ctx) 471d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 472d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct list_sessions_cb_ctx *c = ctx; 473d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int ret; 474d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 475d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret = os_snprintf(c->buf, c->buflen, " %u", fst_session_get_id(s)); 476d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 477d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt c->buf += ret; 478d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt c->buflen -= ret; 479d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt c->reply_len += ret; 480d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 481d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 482d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 483d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int list_sessions(const char *group_id, char *buf, size_t buflen) 484d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 485d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct list_sessions_cb_ctx ctx; 486d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_group *g; 487d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 488d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt g = get_fst_group_by_id(group_id); 489d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!g) { 490d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_WARNING, "CTRL: Cannot find group '%s'", 491d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt group_id); 492d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 493d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 494d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 495d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ctx.buf = buf; 496d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ctx.buflen = buflen; 497d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ctx.reply_len = 0; 498d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 499d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_session_enum(g, list_session_enum_cb, &ctx); 500d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 501d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ctx.reply_len += os_snprintf(buf + ctx.reply_len, ctx.buflen, "\n"); 502d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 503d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return ctx.reply_len; 504d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 505d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 506d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 507d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/* fst iface_peers */ 508d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int iface_peers(const char *group_id, char *buf, size_t buflen) 509d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 510d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *ifname; 511d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_group *g; 512d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_iface *f; 513d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_get_peer_ctx *ctx; 514d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const u8 *addr; 515d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned found = 0; 516d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int ret = 0; 517d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 518d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt g = get_fst_group_by_id(group_id); 519d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!g) { 520d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_WARNING, "CTRL: Cannot find group '%s'", 521d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt group_id); 522d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 523d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 524d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 525d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ifname = os_strchr(group_id, ' '); 526d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!ifname) 527d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 528d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ifname++; 529d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 530d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt foreach_fst_group_iface(g, f) { 531d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *in = fst_iface_get_name(f); 532d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 533d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (os_strncmp(ifname, in, os_strlen(in)) == 0) { 534d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt found = 1; 535d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 536d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 537d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 538d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 539d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!found) 540d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 541d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 542d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt addr = fst_iface_get_peer_first(f, &ctx, FALSE); 543d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (; addr != NULL; addr = fst_iface_get_peer_next(f, &ctx, FALSE)) { 544d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int res; 545d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 546d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt res = os_snprintf(buf + ret, buflen - ret, MACSTR "\n", 547d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt MAC2STR(addr)); 548d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (os_snprintf_error(buflen - ret, res)) 549d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 550d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret += res; 551d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 552d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 553d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return ret; 554d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 555d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 556d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 557d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int get_peer_mbies(const char *params, char *buf, size_t buflen) 558d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 559d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt char *endp; 560d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt char ifname[FST_MAX_INTERFACE_SIZE]; 561d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u8 peer_addr[ETH_ALEN]; 562d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_group *g; 563d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_iface *iface = NULL; 564d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const struct wpabuf *mbies; 565d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 566d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (fst_read_next_text_param(params, ifname, sizeof(ifname), &endp) || 567d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt !*ifname) 568d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt goto problem; 569d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 570d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt while (isspace(*endp)) 571d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt endp++; 572d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (fst_read_peer_addr(endp, peer_addr)) 573d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt goto problem; 574d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 575d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt foreach_fst_group(g) { 576d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface = fst_group_get_iface_by_name(g, ifname); 577d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (iface) 578d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 579d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 580d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!iface) 581d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt goto problem; 582d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 583d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt mbies = fst_iface_get_peer_mb_ie(iface, peer_addr); 584d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!mbies) 585d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt goto problem; 586d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 587d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return wpa_snprintf_hex(buf, buflen, wpabuf_head(mbies), 588d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpabuf_len(mbies)); 589d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 590d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtproblem: 591d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 592d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 593d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 594d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 595d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/* fst list_ifaces */ 596d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int list_ifaces(const char *group_id, char *buf, size_t buflen) 597d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 598d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_group *g; 599d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_iface *f; 600d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int ret = 0; 601d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 602d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt g = get_fst_group_by_id(group_id); 603d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!g) { 604d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_WARNING, "CTRL: Cannot find group '%s'", 605d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt group_id); 606d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(buf, buflen, "FAIL\n"); 607d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 608d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 609d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt foreach_fst_group_iface(g, f) { 610d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int res; 611d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const u8 *iface_addr = fst_iface_get_addr(f); 612d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 613d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt res = os_snprintf(buf + ret, buflen - ret, 614d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "%s|" MACSTR "|%u|%u\n", 615d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_iface_get_name(f), 616d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt MAC2STR(iface_addr), 617d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_iface_get_priority(f), 618d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_iface_get_llt(f)); 619d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (os_snprintf_error(buflen - ret, res)) 620d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 621d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret += res; 622d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 623d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 624d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return ret; 625d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 626d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 627d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 628d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/* fst list_groups */ 629d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int list_groups(const char *cmd, char *buf, size_t buflen) 630d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 631d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_group *g; 632d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int ret = 0; 633d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 634d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt foreach_fst_group(g) { 635d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int res; 636d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 637d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt res = os_snprintf(buf + ret, buflen - ret, "%s\n", 638d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_group_get_id(g)); 639d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (os_snprintf_error(buflen - ret, res)) 640d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 641d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret += res; 642d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 643d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 644d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return ret; 645d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 646d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 647d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 648d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic const char * band_freq(enum mb_band_id band) 649d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 650d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt static const char *band_names[] = { 6511d6bf427f4769edb60865a3999d01eeb8f8fcb19Dmitry Shmidt [MB_BAND_ID_WIFI_2_4GHZ] = "2.4GHZ", 6521d6bf427f4769edb60865a3999d01eeb8f8fcb19Dmitry Shmidt [MB_BAND_ID_WIFI_5GHZ] = "5GHZ", 6531d6bf427f4769edb60865a3999d01eeb8f8fcb19Dmitry Shmidt [MB_BAND_ID_WIFI_60GHZ] = "60GHZ", 654d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt }; 655d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 656d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return fst_get_str_name(band, band_names, ARRAY_SIZE(band_names)); 657d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 658d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 659d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 660d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int print_band(unsigned num, struct fst_iface *iface, const u8 *addr, 661d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt char *buf, size_t buflen) 662d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 663d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const struct wpabuf *wpabuf; 664d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt enum hostapd_hw_mode hw_mode; 665d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u8 channel; 666d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int ret = 0; 667d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 668d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_iface_get_channel_info(iface, &hw_mode, &channel); 669d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 670d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret += os_snprintf(buf + ret, buflen - ret, "band%u_frequency=%s\n", 671d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt num, band_freq(fst_hw_mode_to_band(hw_mode))); 672d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret += os_snprintf(buf + ret, buflen - ret, "band%u_iface=%s\n", 673d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt num, fst_iface_get_name(iface)); 674d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpabuf = fst_iface_get_peer_mb_ie(iface, addr); 675d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (wpabuf) { 676d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret += os_snprintf(buf + ret, buflen - ret, "band%u_mb_ies=", 677d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt num); 678d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret += wpa_snprintf_hex(buf + ret, buflen - ret, 679d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpabuf_head(wpabuf), 680d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpabuf_len(wpabuf)); 681d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret += os_snprintf(buf + ret, buflen - ret, "\n"); 682d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 683d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret += os_snprintf(buf + ret, buflen - ret, "band%u_fst_group_id=%s\n", 684d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt num, fst_iface_get_group_id(iface)); 685d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret += os_snprintf(buf + ret, buflen - ret, "band%u_fst_priority=%u\n", 686d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt num, fst_iface_get_priority(iface)); 687d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret += os_snprintf(buf + ret, buflen - ret, "band%u_fst_llt=%u\n", 688d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt num, fst_iface_get_llt(iface)); 689d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 690d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return ret; 691d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 692d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 693d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 694d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void fst_ctrl_iface_on_iface_state_changed(struct fst_iface *i, 695d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt Boolean attached) 696d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 697d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt union fst_event_extra extra; 698d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 699d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_memset(&extra, 0, sizeof(extra)); 700d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt extra.iface_state.attached = attached; 701d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_strlcpy(extra.iface_state.ifname, fst_iface_get_name(i), 702d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sizeof(extra.iface_state.ifname)); 703d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_strlcpy(extra.iface_state.group_id, fst_iface_get_group_id(i), 704d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sizeof(extra.iface_state.group_id)); 705d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 706d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_ctrl_iface_notify(i, FST_INVALID_SESSION_ID, 707d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt EVENT_FST_IFACE_STATE_CHANGED, &extra); 708d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 709d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 710d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 711d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int fst_ctrl_iface_on_iface_added(struct fst_iface *i) 712d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 713d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_ctrl_iface_on_iface_state_changed(i, TRUE); 714d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return 0; 715d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 716d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 717d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 718d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void fst_ctrl_iface_on_iface_removed(struct fst_iface *i) 719d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 720d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_ctrl_iface_on_iface_state_changed(i, FALSE); 721d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 722d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 723d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 724d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void fst_ctrl_iface_on_event(enum fst_event_type event_type, 725d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_iface *i, struct fst_session *s, 726d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const union fst_event_extra *extra) 727d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 728d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u32 session_id = s ? fst_session_get_id(s) : FST_INVALID_SESSION_ID; 729d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 730d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_ctrl_iface_notify(i, session_id, event_type, extra); 731d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 732d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 733d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 734d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic const struct fst_ctrl ctrl_cli = { 735d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt .on_iface_added = fst_ctrl_iface_on_iface_added, 736d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt .on_iface_removed = fst_ctrl_iface_on_iface_removed, 737d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt .on_event = fst_ctrl_iface_on_event, 738d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt}; 739d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 740d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtconst struct fst_ctrl *fst_ctrl_cli = &ctrl_cli; 741d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 742d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 743d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtint fst_ctrl_iface_mb_info(const u8 *addr, char *buf, size_t buflen) 744d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 745d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_group *g; 746d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_iface *f; 747d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned num = 0; 748d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int ret = 0; 749d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 750d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt foreach_fst_group(g) { 751d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt foreach_fst_group_iface(g, f) { 752d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt if (fst_iface_is_connected(f, addr, TRUE)) { 753d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret += print_band(num++, f, addr, 754d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt buf + ret, buflen - ret); 755d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 756d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 757d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 758d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 759d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return ret; 760d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 761d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 762d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 763d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/* fst ctrl processor */ 764d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtint fst_ctrl_iface_receive(const char *cmd, char *reply, size_t reply_size) 765d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 766d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt static const struct fst_command { 767d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *name; 768d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned has_param; 769d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int (*process)(const char *group_id, char *buf, size_t buflen); 770d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } commands[] = { 771d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt { FST_CMD_LIST_GROUPS, 0, list_groups}, 772d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt { FST_CMD_LIST_IFACES, 1, list_ifaces}, 773d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt { FST_CMD_IFACE_PEERS, 1, iface_peers}, 774d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt { FST_CMD_GET_PEER_MBIES, 1, get_peer_mbies}, 775d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt { FST_CMD_LIST_SESSIONS, 1, list_sessions}, 776d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt { FST_CMD_SESSION_ADD, 1, session_add}, 777d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt { FST_CMD_SESSION_REMOVE, 1, session_remove}, 778d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt { FST_CMD_SESSION_GET, 1, session_get}, 779d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt { FST_CMD_SESSION_SET, 1, session_set}, 780d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt { FST_CMD_SESSION_INITIATE, 1, session_initiate}, 781d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt { FST_CMD_SESSION_RESPOND, 1, session_respond}, 782d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt { FST_CMD_SESSION_TRANSFER, 1, session_transfer}, 783d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt { FST_CMD_SESSION_TEARDOWN, 1, session_teardown}, 784d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef CONFIG_FST_TEST 785d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt { FST_CMD_TEST_REQUEST, 1, test_request }, 786d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* CONFIG_FST_TEST */ 787d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt { NULL, 0, NULL } 788d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt }; 789d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const struct fst_command *c; 790d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *p; 791d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *temp; 792d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt Boolean non_spaces_found; 793d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 794d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (c = commands; c->name; c++) { 795d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (os_strncasecmp(cmd, c->name, os_strlen(c->name)) != 0) 796d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt continue; 797d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p = cmd + os_strlen(c->name); 798d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (c->has_param) { 799d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!isspace(p[0])) 800d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(reply, reply_size, "FAIL\n"); 801d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p++; 802d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt temp = p; 803d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt non_spaces_found = FALSE; 804d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt while (*temp) { 805d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!isspace(*temp)) { 806d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt non_spaces_found = TRUE; 807d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 808d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 809d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt temp++; 810d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 811d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!non_spaces_found) 812d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(reply, reply_size, "FAIL\n"); 813d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 814d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return c->process(p, reply, reply_size); 815d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 816d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 817d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return os_snprintf(reply, reply_size, "UNKNOWN FST COMMAND\n"); 818d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 819d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 820d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 821d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtint fst_read_next_int_param(const char *params, Boolean *valid, char **endp) 822d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 823d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int ret = -1; 824d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *curp; 825d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 826d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *valid = FALSE; 827d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *endp = (char *) params; 828d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt curp = params; 829d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (*curp) { 830d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret = (int) strtol(curp, endp, 0); 831d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!**endp || isspace(**endp)) 832d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *valid = TRUE; 833d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 834d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 835d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return ret; 836d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 837d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 838d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 839d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtint fst_read_next_text_param(const char *params, char *buf, size_t buflen, 840d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt char **endp) 841d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 842d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt size_t max_chars_to_copy; 843d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt char *cur_dest; 844d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 845d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *endp = (char *) params; 846d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt while (isspace(**endp)) 847d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt (*endp)++; 848d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!**endp || buflen <= 1) 849d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -EINVAL; 850d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 851d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt max_chars_to_copy = buflen - 1; 852d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* We need 1 byte for the terminating zero */ 853d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt cur_dest = buf; 854d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt while (**endp && !isspace(**endp) && max_chars_to_copy > 0) { 855d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *cur_dest = **endp; 856d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt (*endp)++; 857d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt cur_dest++; 858d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt max_chars_to_copy--; 859d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 860d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *cur_dest = 0; 861d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 862d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return 0; 863d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 864d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 865d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 866d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtint fst_read_peer_addr(const char *mac, u8 *peer_addr) 867d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 868d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (hwaddr_aton(mac, peer_addr)) { 869d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_WARNING, "Bad peer_mac %s: invalid addr string", 870d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt mac); 871d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 872d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 873d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 874d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (is_zero_ether_addr(peer_addr) || 875d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt is_multicast_ether_addr(peer_addr)) { 876d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_printf(MSG_WARNING, "Bad peer_mac %s: not a unicast addr", 877d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt mac); 878d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 879d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 880d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 881d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return 0; 882d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 883d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 884d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 885d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtint fst_parse_attach_command(const char *cmd, char *ifname, size_t ifname_size, 886d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_iface_cfg *cfg) 887d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 888d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt char *pos; 889d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt char *endp; 890d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt Boolean is_valid; 891d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int val; 892d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 893d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (fst_read_next_text_param(cmd, ifname, ifname_size, &endp) || 894d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_read_next_text_param(endp, cfg->group_id, sizeof(cfg->group_id), 895d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt &endp)) 896d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -EINVAL; 897d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 898d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt cfg->llt = FST_DEFAULT_LLT_CFG_VALUE; 899d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt cfg->priority = 0; 900d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt pos = os_strstr(endp, FST_ATTACH_CMD_PNAME_LLT); 901d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (pos) { 902d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt pos += os_strlen(FST_ATTACH_CMD_PNAME_LLT); 903d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (*pos == '=') { 904d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt val = fst_read_next_int_param(pos + 1, &is_valid, 905d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt &endp); 906d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (is_valid) 907d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt cfg->llt = val; 908d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 909d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 910d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt pos = os_strstr(endp, FST_ATTACH_CMD_PNAME_PRIORITY); 911d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (pos) { 912d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt pos += os_strlen(FST_ATTACH_CMD_PNAME_PRIORITY); 913d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (*pos == '=') { 914d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt val = fst_read_next_int_param(pos + 1, &is_valid, 915d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt &endp); 916d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (is_valid) 917d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt cfg->priority = (u8) val; 918d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 919d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 920d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 921d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return 0; 922d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 923d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 924d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 925d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtint fst_parse_detach_command(const char *cmd, char *ifname, size_t ifname_size) 926d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 927d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt char *endp; 928d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 929d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return fst_read_next_text_param(cmd, ifname, ifname_size, &endp); 930d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 931d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 932d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 933d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtint fst_iface_detach(const char *ifname) 934d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 935d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_group *g; 936d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 937d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt foreach_fst_group(g) { 938d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_iface *f; 939d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 940d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt f = fst_group_get_iface_by_name(g, ifname); 941d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (f) { 942d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_detach(f); 943d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return 0; 944d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 945d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 946d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 947d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -EINVAL; 948d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 949