Пример #1
0
static struct wpa_bss * wpa_bss_add(struct wpa_supplicant *wpa_s,
				    const u8 *ssid, size_t ssid_len,
				    struct wpa_scan_res *res,
				    struct os_reltime *fetch_time)
{
	struct wpa_bss *bss;

	bss = os_zalloc(sizeof(*bss) + res->ie_len + res->beacon_ie_len);
	if (bss == NULL)
		return NULL;
	bss->id = wpa_s->bss_next_id++;
	bss->last_update_idx = wpa_s->bss_update_idx;
	wpa_bss_copy_res(bss, res, fetch_time);
	os_memcpy(bss->ssid, ssid, ssid_len);
	bss->ssid_len = ssid_len;
	bss->ie_len = res->ie_len;
	bss->beacon_ie_len = res->beacon_ie_len;
	os_memcpy(bss + 1, res + 1, res->ie_len + res->beacon_ie_len);
	wpa_bss_set_hessid(bss);

	if (wpa_s->num_bss + 1 > wpa_s->conf->bss_max_count &&
	    wpa_bss_remove_oldest(wpa_s) != 0) {
		wpa_printf(MSG_ERROR, "Increasing the MAX BSS count to %d "
			   "because all BSSes are in use. We should normally "
			   "not get here!", (int) wpa_s->num_bss + 1);
		wpa_s->conf->bss_max_count = wpa_s->num_bss + 1;
	}

	dl_list_add_tail(&wpa_s->bss, &bss->list);
	dl_list_add_tail(&wpa_s->bss_id, &bss->list_id);
	wpa_s->num_bss++;
	wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Add new id %u BSSID " MACSTR
		" SSID '%s'",
		bss->id, MAC2STR(bss->bssid), wpa_ssid_txt(ssid, ssid_len));
	wpas_notify_bss_added(wpa_s, bss->bssid, bss->id);
	return bss;
}
Пример #2
0
int eloop_register_timeout(unsigned int secs, unsigned int usecs,
			   eloop_timeout_handler handler,
			   void *eloop_data, void *user_data)
{
	struct eloop_timeout *timeout, *tmp;
	os_time_t now_sec;

	timeout = os_zalloc(sizeof(*timeout));
	if (timeout == NULL)
		return -1;
	if (os_get_reltime(&timeout->time) < 0) {
		os_free(timeout);
		return -1;
	}
	now_sec = timeout->time.sec;
	timeout->time.sec += secs;
	if (timeout->time.sec < now_sec) {
		/*
		 * Integer overflow - assume long enough timeout to be assumed
		 * to be infinite, i.e., the timeout would never happen.
		 */
		wpa_printf(MSG_DEBUG, "ELOOP: Too long timeout (secs=%u) to "
			   "ever happen - ignore it", secs);
		os_free(timeout);
		return 0;
	}
	timeout->time.usec += usecs;
	while (timeout->time.usec >= 1000000) {
		timeout->time.sec++;
		timeout->time.usec -= 1000000;
	}
	timeout->eloop_data = eloop_data;
	timeout->user_data = user_data;
	timeout->handler = handler;
	wpa_trace_add_ref(timeout, eloop, eloop_data);
	wpa_trace_add_ref(timeout, user, user_data);
	wpa_trace_record(timeout);

	/* Maintain timeouts in order of increasing time */
	dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
		if (os_reltime_before(&timeout->time, &tmp->time)) {
			dl_list_add(tmp->list.prev, &timeout->list);
			return 0;
		}
	}
	dl_list_add_tail(&eloop.timeout, &timeout->list);

	return 0;
}
Пример #3
0
/**
 * event_add - Add a new event to a queue
 * @s: Subscription
 * @data: Event data (is copied; caller retains ownership)
 * @probereq: Whether this is a Probe Request event
 * Returns: 0 on success, -1 on error, 1 on max event queue limit reached
 */
int event_add(struct subscription *s, const struct wpabuf *data, int probereq)
{
	struct wps_event_ *e;
	unsigned int len;

	len = dl_list_len(&s->event_queue);
	if (len >= MAX_EVENTS_QUEUED) {
		wpa_printf(MSG_DEBUG, "WPS UPnP: Too many events queued for "
			   "subscriber %p", s);
		if (probereq)
			return 1;

		/* Drop oldest entry to allow EAP event to be stored. */
		e = event_dequeue(s);
		if (!e)
			return 1;
		event_delete(e);
	}

	if (s->last_event_failed && probereq && len > 0) {
		/*
		 * Avoid queuing frames for subscribers that may have left
		 * without unsubscribing.
		 */
		wpa_printf(MSG_DEBUG, "WPS UPnP: Do not queue more Probe "
			   "Request frames for subscription %p since last "
			   "delivery failed", s);
		return -1;
	}

	e = os_zalloc(sizeof(*e));
	if (e == NULL)
		return -1;
	dl_list_init(&e->list);
	e->s = s;
	e->data = wpabuf_dup(data);
	if (e->data == NULL) {
		os_free(e);
		return -1;
	}
	e->subscriber_sequence = s->next_subscriber_sequence++;
	if (s->next_subscriber_sequence == 0)
		s->next_subscriber_sequence++;
	wpa_printf(MSG_DEBUG, "WPS UPnP: Queue event %p for subscriber %p "
		   "(queue len %u)", e, s, len + 1);
	dl_list_add_tail(&s->event_queue, &e->list);
	event_send_all_later(s->sm);
	return 0;
}
Пример #4
0
err_t tls_netif_add_status_event(tls_netif_status_event_fn event_fn)
{
    u32 cpu_sr;
    struct tls_netif_status_event *evt;
    //if exist, remove from event list first.
    tls_netif_remove_status_event(event_fn);
    evt = tls_mem_alloc(sizeof(struct tls_netif_status_event));
    if(evt==NULL)
        return -1;
    memset(evt, 0, sizeof(struct tls_netif_status_event));
    evt->status_callback = event_fn;
    cpu_sr = tls_os_set_critical();
    dl_list_add_tail(&netif_status_event.list, &evt->list);
    tls_os_release_critical(cpu_sr);

    return 0;
}
Пример #5
0
static void wpas_ctrl_msg_queue(struct dl_list *queue,
				struct wpa_supplicant *wpa_s, int level,
				enum wpa_msg_type type,
				const char *txt, size_t len)
{
	struct ctrl_iface_msg *msg;

	msg = os_zalloc(sizeof(*msg) + len);
	if (!msg)
		return;

	msg->wpa_s = wpa_s;
	msg->level = level;
	msg->type = type;
	os_memcpy(msg + 1, txt, len);
	msg->txt = (const char *) (msg + 1);
	msg->len = len;
	dl_list_add_tail(queue, &msg->list);
	eloop_cancel_timeout(wpas_ctrl_msg_queue_timeout, wpa_s, NULL);
	eloop_register_timeout(0, 0, wpas_ctrl_msg_queue_timeout, wpa_s, NULL);
}
Пример #6
0
struct fst_ctrl_handle * fst_global_add_ctrl(const struct fst_ctrl *ctrl)
{
	struct fst_ctrl_handle *h;

	if (!ctrl)
		return NULL;

	h = os_zalloc(sizeof(*h));
	if (!h)
		return NULL;

	if (ctrl->init && ctrl->init()) {
		os_free(h);
		return NULL;
	}

	h->ctrl = *ctrl;
	dl_list_add_tail(&fst_global_ctrls_list, &h->global_ctrls_lentry);

	return h;
}
Пример #7
0
int eloop_register_timeout(unsigned int secs, unsigned int usecs,
						   eloop_timeout_handler handler, void *eloop_data, void *user_data)
{
	struct eloop_timeout *timeout, *tmp;
	os_time_t now_sec;

	timeout = os_zalloc(sizeof(*timeout));
	if (timeout == NULL)
		return -1;
	if (os_get_reltime(&timeout->time) < 0) {
		os_free(timeout);
		return -1;
	}
	now_sec = timeout->time.sec;
	timeout->time.sec += secs;
	if (timeout->time.sec < now_sec) {
		fprintf(stderr, "ELOOP: Too long timeout (secs=%u) to " "ever happen - ignore it", secs);
		os_free(timeout);
		return 0;
	}
	timeout->time.usec += usecs;
	while (timeout->time.usec >= 1000000) {
		timeout->time.sec++;
		timeout->time.usec -= 1000000;
	}
	timeout->eloop_data = eloop_data;
	timeout->user_data = user_data;
	timeout->handler = handler;

	dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
		if (os_reltime_before(&timeout->time, &tmp->time)) {
			dl_list_add(tmp->list.prev, &timeout->list);
			return 0;
		}
	}
	dl_list_add_tail(&eloop.timeout, &timeout->list);

	return 0;
}
Пример #8
0
int eloop_register_timeout(unsigned int secs, unsigned int usecs,
			   eloop_timeout_handler handler,
			   void *eloop_data, void *user_data)
{
	struct eloop_timeout *timeout, *tmp;

	timeout = os_zalloc(sizeof(*timeout));
	if (timeout == NULL)
		return -1;
	if (os_get_time(&timeout->time) < 0) {
		os_free(timeout);
		return -1;
	}
	timeout->time.sec += secs;
	timeout->time.usec += usecs;
	while (timeout->time.usec >= 1000000) {
		timeout->time.sec++;
		timeout->time.usec -= 1000000;
	}
	timeout->eloop_data = eloop_data;
	timeout->user_data = user_data;
	timeout->handler = handler;
	wpa_trace_add_ref(timeout, eloop, eloop_data);
	wpa_trace_add_ref(timeout, user, user_data);
	wpa_trace_record(timeout);

	/* Maintain timeouts in order of increasing time */
	dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
		if (os_time_before(&timeout->time, &tmp->time)) {
			dl_list_add(tmp->list.prev, &timeout->list);
			return 0;
		}
	}
	dl_list_add_tail(&eloop.timeout, &timeout->list);

	return 0;
}
Пример #9
0
static enum http_reply_code
web_process_get_device_info(struct upnp_wps_device_sm *sm,
			    struct wpabuf **reply, const char **replyname)
{
	static const char *name = "NewDeviceInfo";
	struct wps_config cfg;
	struct upnp_wps_device_interface *iface;
	struct upnp_wps_peer *peer;

	iface = dl_list_first(&sm->interfaces,
			      struct upnp_wps_device_interface, list);

	wpa_printf(MSG_DEBUG, "WPS UPnP: GetDeviceInfo");

	if (!iface || iface->ctx->ap_pin == NULL)
		return HTTP_INTERNAL_SERVER_ERROR;

	peer = os_zalloc(sizeof(*peer));
	if (!peer)
		return HTTP_INTERNAL_SERVER_ERROR;

	/*
	 * Request for DeviceInfo, i.e., M1 TLVs. This is a start of WPS
	 * registration over UPnP with the AP acting as an Enrollee. It should
	 * be noted that this is frequently used just to get the device data,
	 * i.e., there may not be any intent to actually complete the
	 * registration.
	 */

	os_memset(&cfg, 0, sizeof(cfg));
	cfg.wps = iface->wps;
	cfg.pin = (u8 *) iface->ctx->ap_pin;
	cfg.pin_len = os_strlen(iface->ctx->ap_pin);
	peer->wps = wps_init(&cfg);
	if (peer->wps) {
		enum wsc_op_code op_code;
		*reply = wps_get_msg(peer->wps, &op_code);
		if (*reply == NULL) {
			wps_deinit(peer->wps);
			peer->wps = NULL;
		}
	} else
		*reply = NULL;
	if (*reply == NULL) {
		wpa_printf(MSG_INFO, "WPS UPnP: Failed to get DeviceInfo");
		os_free(peer);
		return HTTP_INTERNAL_SERVER_ERROR;
	}

	if (dl_list_len(&iface->peers) > 3) {
		struct upnp_wps_peer *old;

		old = dl_list_first(&iface->peers, struct upnp_wps_peer, list);
		if (old) {
			wpa_printf(MSG_DEBUG, "WPS UPnP: Drop oldest active session");
			wps_upnp_peer_del(old);
		}
	}
	dl_list_add_tail(&iface->peers, &peer->list);
	/* TODO: Could schedule a timeout to free the entry */

	*replyname = name;
	return HTTP_OK;
}
Пример #10
0
/**
 * Accept callback function for TCP netconns.
 */
static err_t net_tcp_accept_cb(void *arg, 
        struct tcp_pcb *newpcb, err_t err)
{
    err_t err_ret = ERR_OK;
    struct tls_netconn *conn = (struct tls_netconn *)arg;
    struct tls_netconn *newconn;
    struct tcp_pcb *pcb;
    u32 cpu_sr;

    //TLS_DBGPRT_INFO("=====>\n");
#if 0
    if (conn->tcp_connect_cnt >= TLS_MAX_SOCKET_NUM) {
        return ERR_ABRT;
    }
#endif

    newconn = net_alloc_socket(conn);

    if (!newconn) {
        /* connection aborted */
        /* not happen */
		tcp_abort(newpcb);
		//printf("\r\nnet_tcp_accept_cb err\r\n");
        return ERR_ABRT;
    }

	if (conn){
		tcp_accepted(conn->pcb.tcp);
	}

    //conn->tcp_connect_cnt++;

    newconn->used = true;
    newconn->pcb.tcp = newpcb;
    newconn->client = true;
    newconn->idle_time = conn->idle_time;
    newconn->proto = TLS_NETCONN_TCP;
    newconn->state = NETCONN_STATE_CONNECTED;
    pcb = newconn->pcb.tcp;
    ip_set_option(newconn->pcb.tcp, SOF_KEEPALIVE);
    newconn->skd = conn->skd;
    tcp_arg(pcb, newconn);
    tcp_recv(pcb, net_tcp_recv_cb);
    //tcp_sent(pcb, net_tcp_sent_cb);
    tcp_poll(pcb, net_tcp_poll_cb, 2);
    tcp_err(pcb, net_tcp_err_cb);
	cpu_sr = tls_os_set_critical();
	dl_list_add_tail(&conn->list, &newconn->list);
	tls_os_release_critical(cpu_sr);
    newconn->port = host_to_le16(pcb->remote_port);
    newconn->localport = conn->localport;
    ip_addr_set(&newconn->addr, &pcb->remote_ip);
    net_send_event_to_hostif(newconn, NET_EVENT_TCP_JOINED);
    if(conn->skd->acceptf != NULL)
	{
		err_ret =conn->skd->acceptf(newconn->skt_num, err);
		if(err_ret == ERR_ABRT)
		{
			tcp_abort(pcb);
		}
	} 
    //conn->state = NETCONN_STATE_CONNECTED;

    return err_ret;
}
Пример #11
0
static struct wpa_bss *
wpa_bss_update(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
	       struct wpa_scan_res *res, struct os_reltime *fetch_time)
{
	u32 changes;

	changes = wpa_bss_compare_res(bss, res);
	if (changes & WPA_BSS_FREQ_CHANGED_FLAG)
		wpa_printf(MSG_DEBUG, "BSS: " MACSTR " changed freq %d --> %d",
			   MAC2STR(bss->bssid), bss->freq, res->freq);
	bss->scan_miss_count = 0;
	bss->last_update_idx = wpa_s->bss_update_idx;
	wpa_bss_copy_res(bss, res, fetch_time);
	/* Move the entry to the end of the list */
	dl_list_del(&bss->list);
#ifdef CONFIG_P2P
	if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) &&
	    !wpa_scan_get_vendor_ie(res, P2P_IE_VENDOR_TYPE)) {
		/*
		 * This can happen when non-P2P station interface runs a scan
		 * without P2P IE in the Probe Request frame. P2P GO would reply
		 * to that with a Probe Response that does not include P2P IE.
		 * Do not update the IEs in this BSS entry to avoid such loss of
		 * information that may be needed for P2P operations to
		 * determine group information.
		 */
		wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Do not update scan IEs for "
			MACSTR " since that would remove P2P IE information",
			MAC2STR(bss->bssid));
	} else
#endif /* CONFIG_P2P */
	if (bss->ie_len + bss->beacon_ie_len >=
	    res->ie_len + res->beacon_ie_len) {
		os_memcpy(bss + 1, res + 1, res->ie_len + res->beacon_ie_len);
		bss->ie_len = res->ie_len;
		bss->beacon_ie_len = res->beacon_ie_len;
	} else {
		struct wpa_bss *nbss;
		struct dl_list *prev = bss->list_id.prev;
		dl_list_del(&bss->list_id);
		nbss = os_realloc(bss, sizeof(*bss) + res->ie_len +
				  res->beacon_ie_len);
		if (nbss) {
			unsigned int i;
			for (i = 0; i < wpa_s->last_scan_res_used; i++) {
				if (wpa_s->last_scan_res[i] == bss) {
					wpa_s->last_scan_res[i] = nbss;
					break;
				}
			}
			if (wpa_s->current_bss == bss)
				wpa_s->current_bss = nbss;
			wpa_bss_update_pending_connect(wpa_s, bss, nbss);
			bss = nbss;
			os_memcpy(bss + 1, res + 1,
				  res->ie_len + res->beacon_ie_len);
			bss->ie_len = res->ie_len;
			bss->beacon_ie_len = res->beacon_ie_len;
		}
		dl_list_add(prev, &bss->list_id);
	}
	if (changes & WPA_BSS_IES_CHANGED_FLAG)
		wpa_bss_set_hessid(bss);
	dl_list_add_tail(&wpa_s->bss, &bss->list);

	notify_bss_changes(wpa_s, changes, bss);

	return bss;
}