1d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt/*
2d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * wpa_supplicant ctrl_iface helpers
3d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * Copyright (c) 2010-2011, Atheros Communications, Inc.
4d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * Copyright (c) 2011-2012, Qualcomm Atheros, Inc.
5d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt *
6d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * This software may be distributed under the terms of the BSD license.
7d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * See README for more details.
8d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt */
9d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
10d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "includes.h"
11d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include <time.h>
12d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
13d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "common.h"
14d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "wpa_ctrl.h"
15d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "wpa_helpers.h"
16d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
17d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
18d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtchar *wpas_ctrl_path = "/var/run/wpa_supplicant/";
19d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int default_timeout = 60;
20d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
21d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
22d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic struct wpa_ctrl * wpa_open_ctrl(const char *ifname)
23d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
24d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char buf[128];
25d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	struct wpa_ctrl *ctrl;
26d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
27d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	os_snprintf(buf, sizeof(buf), "%s%s", wpas_ctrl_path, ifname);
28d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	ctrl = wpa_ctrl_open(buf);
29d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (ctrl == NULL)
30d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		printf("wpa_command: wpa_ctrl_open(%s) failed\n", buf);
31d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return ctrl;
32d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
33d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
34d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
35d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtint wpa_command(const char *ifname, const char *cmd)
36d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
37d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	struct wpa_ctrl *ctrl;
38d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char buf[128];
39d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	size_t len;
40d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
41d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	printf("wpa_command(ifname='%s', cmd='%s')\n", ifname, cmd);
42d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	ctrl = wpa_open_ctrl(ifname);
43d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (ctrl == NULL)
44d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return -1;
45d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	len = sizeof(buf);
46d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, NULL) < 0) {
47d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		printf("wpa_command: wpa_ctrl_request failed\n");
48d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_ctrl_close(ctrl);
49d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return -1;
50d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
51d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_ctrl_close(ctrl);
52d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	buf[len] = '\0';
53d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (strncmp(buf, "FAIL", 4) == 0) {
54d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		printf("wpa_command: Command failed (FAIL received)\n");
55d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return -1;
56d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
57d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return 0;
58d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
59d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
60d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
61d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtint wpa_command_resp(const char *ifname, const char *cmd,
62d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		     char *resp, size_t resp_size)
63d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
64d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	struct wpa_ctrl *ctrl;
65d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	size_t len;
66d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
67d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	printf("wpa_command(ifname='%s', cmd='%s')\n", ifname, cmd);
68d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	ctrl = wpa_open_ctrl(ifname);
69d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (ctrl == NULL)
70d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return -1;
71d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	len = resp_size;
72d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), resp, &len, NULL) < 0) {
73d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		printf("wpa_command: wpa_ctrl_request failed\n");
74d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_ctrl_close(ctrl);
75d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return -1;
76d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
77d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_ctrl_close(ctrl);
78d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	resp[len] = '\0';
79d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return 0;
80d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
81d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
82d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
83d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstruct wpa_ctrl * open_wpa_mon(const char *ifname)
84d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
85d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	struct wpa_ctrl *ctrl;
86d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
87d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	ctrl = wpa_open_ctrl(ifname);
88d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (ctrl == NULL)
89d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return NULL;
90d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (wpa_ctrl_attach(ctrl) < 0) {
91d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_ctrl_close(ctrl);
92d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return NULL;
93d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
94d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
95d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return ctrl;
96d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
97d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
98d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
99d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtint get_wpa_cli_event2(struct wpa_ctrl *mon,
100d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		       const char *event, const char *event2,
101d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		       char *buf, size_t buf_size)
102d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
103d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int fd, ret;
104d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	fd_set rfd;
105d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *pos;
106d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	struct timeval tv;
107d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	time_t start, now;
108d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
109d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	printf("Waiting for wpa_cli event %s\n", event);
110d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	fd = wpa_ctrl_get_fd(mon);
111d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (fd < 0)
112d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return -1;
113d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
114d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	time(&start);
115d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	while (1) {
116d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		size_t len;
117d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
118d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		FD_ZERO(&rfd);
119d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		FD_SET(fd, &rfd);
120d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		tv.tv_sec = default_timeout;
121d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		tv.tv_usec = 0;
122d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		ret = select(fd + 1, &rfd, NULL, NULL, &tv);
123d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (ret == 0) {
124d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			printf("Timeout on waiting for event %s\n", event);
125d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			return -1;
126d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		}
127d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (ret < 0) {
128d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			printf("select: %s\n", strerror(errno));
129d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			return -1;
130d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		}
131d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		len = buf_size;
132d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (wpa_ctrl_recv(mon, buf, &len) < 0) {
133d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			printf("Failure while waiting for event %s\n", event);
134d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			return -1;
135d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		}
136d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (len == buf_size)
137d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			len--;
138d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		buf[len] = '\0';
139d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
140d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		pos = strchr(buf, '>');
141d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (pos &&
142d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		    (strncmp(pos + 1, event, strlen(event)) == 0 ||
143d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		     (event2 &&
144d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		      strncmp(pos + 1, event2, strlen(event2)) == 0)))
145d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			return 0; /* Event found */
146d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
147d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		time(&now);
148d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if ((int) (now - start) > default_timeout) {
149d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			printf("Timeout on waiting for event %s\n", event);
150d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			return -1;
151d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		}
152d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
153d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
154d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
155d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
156d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtint get_wpa_cli_event(struct wpa_ctrl *mon,
157d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		      const char *event, char *buf, size_t buf_size)
158d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
159d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return get_wpa_cli_event2(mon, event, NULL, buf, buf_size);
160d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
161d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
162d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
163d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtint get_wpa_status(const char *ifname, const char *field, char *obuf,
164d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		   size_t obuf_size)
165d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
166d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	struct wpa_ctrl *ctrl;
167d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char buf[4096];
168d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *pos, *end;
169d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	size_t len, flen;
170d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
171d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	ctrl = wpa_open_ctrl(ifname);
172d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (ctrl == NULL)
173d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return -1;
174d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	len = sizeof(buf);
175d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (wpa_ctrl_request(ctrl, "STATUS", 6, buf, &len, NULL) < 0) {
176d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_ctrl_close(ctrl);
177d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return -1;
178d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
179d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_ctrl_close(ctrl);
180d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	buf[len] = '\0';
181d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
182d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	flen = strlen(field);
183d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	pos = buf;
184d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	while (pos + flen < buf + len) {
185d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (pos > buf) {
186d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			if (*pos != '\n') {
187d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				pos++;
188d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				continue;
189d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			}
190d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			pos++;
191d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		}
192d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (strncmp(pos, field, flen) != 0 || pos[flen] != '=') {
193d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			pos++;
194d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			continue;
195d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		}
196d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		pos += flen + 1;
197d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		end = strchr(pos, '\n');
198d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (end == NULL)
199d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			return -1;
200d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		*end++ = '\0';
201d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (end - pos > (int) obuf_size)
202d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			return -1;
203d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		memcpy(obuf, pos, end - pos);
204d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return 0;
205d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
206d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
207d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return -1;
208d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
209d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
210d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
211d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtint wait_ip_addr(const char *ifname, int timeout)
212d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
213d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char ip[30];
214d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int count = timeout;
215d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	struct wpa_ctrl *ctrl;
216d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
217d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	while (count > 0) {
218d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		printf("%s: ifname='%s' - %d seconds remaining\n",
219d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		       __func__, ifname, count);
220d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		count--;
221d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (get_wpa_status(ifname, "ip_address", ip, sizeof(ip)) == 0
222d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		    && strlen(ip) > 0) {
223d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			printf("IP address found: '%s'\n", ip);
224d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			return 0;
225d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		}
226d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		ctrl = wpa_open_ctrl(ifname);
227d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (ctrl == NULL)
228d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			return -1;
229d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_ctrl_close(ctrl);
230d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		sleep(1);
231d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
232d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	printf("%s: Could not get IP address for ifname='%s'", __func__,
233d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	       ifname);
234d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return -1;
235d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
236d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
237d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
238d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtint add_network(const char *ifname)
239d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
240d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char res[30];
241d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
242d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (wpa_command_resp(ifname, "ADD_NETWORK", res, sizeof(res)) < 0)
243d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return -1;
244d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return atoi(res);
245d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
246d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
247d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
248d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtint set_network(const char *ifname, int id, const char *field,
249d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		const char *value)
250d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
251d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char buf[200];
252d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	snprintf(buf, sizeof(buf), "SET_NETWORK %d %s %s", id, field, value);
253d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return wpa_command(ifname, buf);
254d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
255d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
256d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
257d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtint set_network_quoted(const char *ifname, int id, const char *field,
258d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		       const char *value)
259d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
260d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char buf[200];
261d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	snprintf(buf, sizeof(buf), "SET_NETWORK %d %s \"%s\"",
262d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		 id, field, value);
263d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return wpa_command(ifname, buf);
264d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
265d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
266d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
267d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtint add_cred(const char *ifname)
268d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
269d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char res[30];
270d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
271d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (wpa_command_resp(ifname, "ADD_CRED", res, sizeof(res)) < 0)
272d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return -1;
273d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return atoi(res);
274d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
275d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
276d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
277d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtint set_cred(const char *ifname, int id, const char *field, const char *value)
278d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
279d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char buf[200];
280d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	snprintf(buf, sizeof(buf), "SET_CRED %d %s %s", id, field, value);
281d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return wpa_command(ifname, buf);
282d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
283d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
284d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
285d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtint set_cred_quoted(const char *ifname, int id, const char *field,
286d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		    const char *value)
287d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
288d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char buf[200];
289d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	snprintf(buf, sizeof(buf), "SET_CRED %d %s \"%s\"",
290d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		 id, field, value);
291d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return wpa_command(ifname, buf);
292d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
293