From d89d677926a1232671cd1541267bc7b0a41c1193 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Wed, 6 Nov 2013 17:29:48 +0100 Subject: owfd: wpa: parse GO_NEG_SUCCESS and GROUP_STARTED Both events are needed for proper P2P group setup handling. Parse their parameters so we can deal with them correctly. Signed-off-by: David Herrmann --- src/wpa.h | 14 ++++++++++ src/wpa_parser.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/test_wpa.c | 21 ++++++++++++--- 3 files changed, 112 insertions(+), 3 deletions(-) diff --git a/src/wpa.h b/src/wpa.h index af6c743..7f45974 100644 --- a/src/wpa.h +++ b/src/wpa.h @@ -99,6 +99,11 @@ enum owfd_wpa_event_priority { OWFD_WPA_EVENT_P_COUNT }; +enum owfd_wpa_event_role { + OWFD_WPA_EVENT_ROLE_GO, + OWFD_WPA_EVENT_ROLE_CLIENT, +}; + #define OWFD_WPA_EVENT_MAC_STRLEN 18 struct owfd_wpa_event { @@ -117,6 +122,15 @@ struct owfd_wpa_event { char peer_mac[OWFD_WPA_EVENT_MAC_STRLEN]; char *name; } p2p_device_found; + struct owfd_wpa_event_p2p_go_neg_success { + char peer_mac[OWFD_WPA_EVENT_MAC_STRLEN]; + unsigned int role; + } p2p_go_neg_success; + struct owfd_wpa_event_p2p_group_started { + char go_mac[OWFD_WPA_EVENT_MAC_STRLEN]; + unsigned int role; + char *ifname; + } p2p_group_started; struct owfd_wpa_event_p2p_prov_disc_show_pin { char peer_mac[OWFD_WPA_EVENT_MAC_STRLEN]; char *pin; diff --git a/src/wpa_parser.c b/src/wpa_parser.c index 4789f01..4600776 100644 --- a/src/wpa_parser.c +++ b/src/wpa_parser.c @@ -43,6 +43,9 @@ void owfd_wpa_event_reset(struct owfd_wpa_event *ev) case OWFD_WPA_EVENT_P2P_DEVICE_FOUND: free(ev->p.p2p_device_found.name); break; + case OWFD_WPA_EVENT_P2P_GROUP_STARTED: + free(ev->p.p2p_group_started.ifname); + break; case OWFD_WPA_EVENT_P2P_PROV_DISC_SHOW_PIN: free(ev->p.p2p_prov_disc_show_pin.pin); break; @@ -259,6 +262,77 @@ static int parse_p2p_device_found(struct owfd_wpa_event *ev, return -EINVAL; } +static int parse_p2p_go_neg_success(struct owfd_wpa_event *ev, + char *tokens, size_t num) +{ + int r; + size_t i; + bool has_role = false, has_peer = false; + + if (num < 2) + return -EINVAL; + + for (i = 0; i < num; ++i, tokens += strlen(tokens) + 1) { + if (!strncmp(tokens, "role=", 5)) { + if (!strcmp(&tokens[5], "GO")) + ev->p.p2p_go_neg_success.role = OWFD_WPA_EVENT_ROLE_GO; + else if (!strcmp(&tokens[5], "client")) + ev->p.p2p_go_neg_success.role = OWFD_WPA_EVENT_ROLE_CLIENT; + else + return -EINVAL; + + has_role = true; + } else if (!strncmp(tokens, "peer_dev=", 9)) { + r = parse_mac(ev->p.p2p_go_neg_success.peer_mac, + &tokens[9]); + if (r < 0) + return r; + + has_peer = true; + } + } + + return (has_role && has_peer) ? 0 : -EINVAL; +} + +static int parse_p2p_group_started(struct owfd_wpa_event *ev, + char *tokens, size_t num) +{ + int r; + size_t i; + + if (num < 3) + return -EINVAL; + + ev->p.p2p_group_started.ifname = strdup(tokens); + if (!ev->p.p2p_group_started.ifname) + return -ENOMEM; + + tokens += strlen(tokens) + 1; + + if (!strcmp(tokens, "GO")) + ev->p.p2p_group_started.role = OWFD_WPA_EVENT_ROLE_GO; + else if (!strcmp(tokens, "client")) + ev->p.p2p_group_started.role = OWFD_WPA_EVENT_ROLE_CLIENT; + else + return -EINVAL; + + tokens += strlen(tokens) + 1; + + for (i = 2; i < num; ++i, tokens += strlen(tokens) + 1) { + if (strncmp(tokens, "go_dev_addr=", 12)) + continue; + + r = parse_mac(ev->p.p2p_group_started.go_mac, &tokens[12]); + if (r < 0) + return r; + + return 0; + } + + return -EINVAL; +} + static int parse_p2p_prov_disc_show_pin(struct owfd_wpa_event *ev, char *tokens, size_t num) { @@ -385,6 +459,12 @@ int owfd_wpa_event_parse(struct owfd_wpa_event *ev, const char *event) case OWFD_WPA_EVENT_P2P_DEVICE_FOUND: r = parse_p2p_device_found(ev, tokens, num); break; + case OWFD_WPA_EVENT_P2P_GO_NEG_SUCCESS: + r = parse_p2p_go_neg_success(ev, tokens, num); + break; + case OWFD_WPA_EVENT_P2P_GROUP_STARTED: + r = parse_p2p_group_started(ev, tokens, num); + break; case OWFD_WPA_EVENT_P2P_PROV_DISC_SHOW_PIN: r = parse_p2p_prov_disc_show_pin(ev, tokens, num); break; diff --git a/test/test_wpa.c b/test/test_wpa.c index 68e0c2a..2bf6c23 100644 --- a/test/test_wpa.c +++ b/test/test_wpa.c @@ -31,7 +31,7 @@ static void parse(struct owfd_wpa_event *ev, const char *event) owfd_wpa_event_init(ev); r = owfd_wpa_event_parse(ev, event); - ck_assert(!r); + ck_assert_msg(!r, "cannot parse event %s", event); ck_assert(ev->priority < OWFD_WPA_EVENT_P_COUNT); } @@ -42,11 +42,11 @@ static const char *event_list[] = { [OWFD_WPA_EVENT_P2P_DEVICE_FOUND] = "P2P-DEVICE-FOUND 00:00:00:00:00:00 name=some-name", [OWFD_WPA_EVENT_P2P_FIND_STOPPED] = "P2P-FIND-STOPPED", [OWFD_WPA_EVENT_P2P_GO_NEG_REQUEST] = "P2P-GO-NEG-REQUEST", - [OWFD_WPA_EVENT_P2P_GO_NEG_SUCCESS] = "P2P-GO-NEG-SUCCESS", + [OWFD_WPA_EVENT_P2P_GO_NEG_SUCCESS] = "P2P-GO-NEG-SUCCESS role=GO peer_dev=00:00:00:00:00:00", [OWFD_WPA_EVENT_P2P_GO_NEG_FAILURE] = "P2P-GO-NEG-FAILURE", [OWFD_WPA_EVENT_P2P_GROUP_FORMATION_SUCCESS] = "P2P-GROUP-FORMATION-SUCCESS", [OWFD_WPA_EVENT_P2P_GROUP_FORMATION_FAILURE] = "P2P-GROUP-FORMATION-FAILURE", - [OWFD_WPA_EVENT_P2P_GROUP_STARTED] = "P2P-GROUP-STARTED", + [OWFD_WPA_EVENT_P2P_GROUP_STARTED] = "P2P-GROUP-STARTED p2p-wlan0-0 client go_dev_addr=00:00:00:00:00:00", [OWFD_WPA_EVENT_P2P_GROUP_REMOVED] = "P2P-GROUP-REMOVED", [OWFD_WPA_EVENT_P2P_PROV_DISC_SHOW_PIN] = "P2P-PROV-DISC-SHOW-PIN 00:00:00:00:00:00 pin", [OWFD_WPA_EVENT_P2P_PROV_DISC_ENTER_PIN] = "P2P-PROV-DISC-ENTER-PIN 00:00:00:00:00:00", @@ -130,6 +130,21 @@ START_TEST(test_wpa_parser_payload) ck_assert(ev.raw != NULL); ck_assert(!strcmp(ev.p.p2p_prov_disc_show_pin.peer_mac, "0:0:0:0:0:0")); ck_assert(!strcmp(ev.p.p2p_prov_disc_show_pin.pin, "1234567890")); + + parse(&ev, "<4>P2P-GO-NEG-SUCCESS role=GO peer_dev=0:0:0:0:0:0"); + ck_assert(ev.priority == OWFD_WPA_EVENT_P_ERROR); + ck_assert(ev.type == OWFD_WPA_EVENT_P2P_GO_NEG_SUCCESS); + ck_assert(ev.raw != NULL); + ck_assert(!strcmp(ev.p.p2p_go_neg_success.peer_mac, "0:0:0:0:0:0")); + ck_assert(ev.p.p2p_go_neg_success.role == OWFD_WPA_EVENT_ROLE_GO); + + parse(&ev, "<4>P2P-GROUP-STARTED p2p-wlan0-0 client go_dev_addr=0:0:0:0:0:0"); + ck_assert(ev.priority == OWFD_WPA_EVENT_P_ERROR); + ck_assert(ev.type == OWFD_WPA_EVENT_P2P_GROUP_STARTED); + ck_assert(ev.raw != NULL); + ck_assert(!strcmp(ev.p.p2p_group_started.go_mac, "0:0:0:0:0:0")); + ck_assert(!strcmp(ev.p.p2p_group_started.ifname, "p2p-wlan0-0")); + ck_assert(ev.p.p2p_group_started.role == OWFD_WPA_EVENT_ROLE_CLIENT); } END_TEST -- cgit v1.2.3