/*
 * Copyright (C) 2009 Joshua Oreman <oremanj@rwcr.net>.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

FILE_LICENCE ( GPL2_OR_LATER );

#include <stdio.h>
#include <console.h>
#include <string.h>
#include <errno.h>
#include <gpxe/net80211.h>
#include <gpxe/ethernet.h>
#include <usr/ifmgmt.h>
#include <usr/iwmgmt.h>
#include <gpxe/errortab.h>

/** @file
 *
 * Wireless network interface management
 *
 */

/**
 * Print status of 802.11 device
 *
 * @v dev	802.11 device
 */
void iwstat ( struct net80211_device *dev ) {

	ifstat ( dev->netdev );

	printf ( "  [802.11 ");
	if ( dev->state & NET80211_ASSOCIATED ) {
		printf ( "SSID '%s', ", dev->essid );
	} else {
		printf ( "not associated, " );
	}
	if ( dev->channel < dev->nr_channels && dev->rate < dev->nr_rates ) {
		printf ( "Ch:%d Sig:%d", dev->channels[dev->channel].channel_nr,
			 dev->last_signal );
		switch ( dev->hw->signal_type ) {
		case NET80211_SIGNAL_NONE:
			printf ( "?" );
			break;
		case NET80211_SIGNAL_ARBITRARY:
			printf ( "/%d", dev->hw->signal_max );
			break;
		case NET80211_SIGNAL_DB:
			printf ( "/%d dB", dev->hw->signal_max );
			break;
		case NET80211_SIGNAL_DBM:
			printf ( " dBm" );
			break;
		}
		printf ( ", Qual:%d%% Rate:%d Mbps]\n",
			 ( dev->rx_beacon_interval == 0 ? 0 :
			   100 * dev->tx_beacon_interval /
			   dev->rx_beacon_interval ),
			 dev->rates[dev->rate] / 10 );
	} else {
		printf ( "antenna off]\n" );
	}

	if ( dev->state & NET80211_WORKING ) {
		printf ( "  [associating" );
		if ( dev->associating )
			printf ( " to '%s'", dev->associating->essid );
		printf ( "...]\n" );
	}
}

/** Identifiers for 802.11 cryptography types, indexed by type number */
static const char *crypto_types[] = {
	[NET80211_CRYPT_NONE] = "Open",
	[NET80211_CRYPT_WEP] = "WEP ",
	[NET80211_CRYPT_TKIP] = "WPA ",
	[NET80211_CRYPT_CCMP] = "WPA2",
	[NET80211_CRYPT_UNKNOWN] = "UNK ",
};

/** Number of 802.11 cryptography types defined */
#define NR_CRYPTO_TYPES ( sizeof ( crypto_types ) / sizeof ( crypto_types[0] ) )

/** Identifiers for 802.11 authentication types, indexed by type number */
static const char *auth_types[] = {
	[NET80211_SECPROT_NONE] = "",
	[NET80211_SECPROT_PSK] = "PSK",
	[NET80211_SECPROT_EAP] = "802.1X",
	[NET80211_SECPROT_UNKNOWN] = "UNK",
};

/** Number of 802.11 authentication types defined */
#define NR_AUTH_TYPES ( sizeof ( auth_types ) / sizeof ( auth_types[0] ) )

/**
 * Scan for wireless networks using 802.11 device
 *
 * @v dev	802.11 device
 * @v active	Whether to use active scanning
 *
 * The list of networks found will be printed in tabular format.
 *
 * This function is safe to call at all times, whether the 802.11
 * device is open or not, but if called while the auto-association
 * task is running it will return an error indication.
 */
int iwlist ( struct net80211_device *dev ) {
	struct net80211_probe_ctx *ctx;
	struct list_head *networks;
	struct net80211_wlan *wlan;
	char ssid_buf[22];
	int rc;
	unsigned i;
	int was_opened = dev->netdev->state & NETDEV_OPEN;
	int was_channel = dev->channels[dev->channel].channel_nr;

	if ( ! was_opened ) {
		dev->state |= NET80211_NO_ASSOC;
		rc = netdev_open ( dev->netdev );
		if ( rc < 0 )
			goto err;
	}

	if ( dev->state & NET80211_WORKING ) {
		rc = -EINVAL;
		goto err_close_netdev;
	}

	if ( ! was_opened ) {
		rc = net80211_prepare_probe ( dev, dev->hw->bands, 0 );
		if ( rc < 0 )
			goto err_close_netdev;
	}

	ctx = net80211_probe_start ( dev, "", 0 );
	if ( ! ctx ) {
		rc = -ENOMEM;
		goto err_close_netdev;
	}

	while ( ! ( rc = net80211_probe_step ( ctx ) ) ) {
		step();
	}

	networks = net80211_probe_finish_all ( ctx );

	if ( list_empty ( networks ) ) {
		goto err_free_networks;
	}

	rc = 0;

	printf ( "Networks on %s:\n\n", dev->netdev->name );

	/* Output format:
	 * 0         1         2         3         4         5         6
	 * 0123456789012345678901234567890123456789012345678901234567890
	 * [Sig] SSID                  BSSID              Ch  Crypt/Auth
	 * -------------------------------------------------------------
	 * [ 15] abcdefghijklmnopqrst> 00:00:00:00:00:00  11  Open
	 *                                             ... or WPA   PSK etc.
	 */

	/* Quoting the dashes and spaces verbatim uses less code space
	   than generating them programmatically. */
	printf ( "[Sig] SSID                  BSSID              Ch  Crypt/Auth\n"
		 "-------------------------------------------------------------\n" );

	list_for_each_entry ( wlan, networks, list ) {

		/* Format SSID into 22-character string, space-padded,
		   with '>' indicating truncation */

		snprintf ( ssid_buf, sizeof ( ssid_buf ), "%s", wlan->essid );
		for ( i = strlen ( ssid_buf ); i < sizeof ( ssid_buf ) - 1;
		      i++ )
			ssid_buf[i] = ' ';
		if ( ssid_buf[sizeof ( ssid_buf ) - 2] != ' ' )
			ssid_buf[sizeof ( ssid_buf ) - 2] = '>';
		ssid_buf[sizeof ( ssid_buf ) - 1] = 0;

		/* Sanity check */
		if ( wlan->crypto >= NR_CRYPTO_TYPES ||
		     wlan->handshaking >= NR_AUTH_TYPES )
			continue;

		printf ( "[%3d] %s %s  %2d  %s  %s\n",
			 wlan->signal < 0 ? 100 + wlan->signal : wlan->signal,
			 ssid_buf, eth_ntoa ( wlan->bssid ), wlan->channel,
			 crypto_types[wlan->crypto],
			 auth_types[wlan->handshaking] );
	}
	printf ( "\n" );

 err_free_networks:
	net80211_free_wlanlist ( networks );

 err_close_netdev:
	if ( ! was_opened ) {
		dev->state &= ~NET80211_NO_ASSOC;
		netdev_close ( dev->netdev );
	} else {
		net80211_change_channel ( dev, was_channel );
	}

	if ( ! rc )
		return 0;

 err:
	printf ( "Scanning for networks on %s: %s\n",
		 dev->netdev->name, strerror ( rc ) );
	return rc;
}


/* Record error codes as though they come from the 802.11 stack */
#undef ERRFILE
#define ERRFILE ERRFILE_net80211

/** Common 802.11 errors */
struct errortab common_wireless_errors[] __errortab = {
	{ EINVAL | EUNIQ_06, "Packet decryption error" },
	{ ECONNRESET | EUNIQ_01, "Unspecified reason" },
	{ ECONNRESET | EUNIQ_04, "Disassociated due to inactivity" },
	{ ECONNRESET | EUNIQ_0F, "4-Way Handshake timeout" },
	{ ECONNRESET | EUNIQ_17, "IEEE 802.1X authentication failed" },
	{ ECONNREFUSED | EUNIQ_01, "Unspecified failure" },
	{ ECONNREFUSED | EUNIQ_0C, "Association denied" },
	{ ECONNREFUSED | EUNIQ_0D, "Authentication method not supported" },
};
