/*
 *
 *  Connection Manager
 *
 *  Copyright (C) 2007-2009  Intel Corporation. All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <net/if.h>

#include <glib.h>

#define CONNMAN_API_SUBJECT_TO_CHANGE
#include <connman/device.h>
#include <connman/inet.h>
#include <connman/log.h>

#include <WiMaxAPI.h>
#include <WiMaxAPIEx.h>

#include "iwmx.h"

/* Yes, this is dirty; see above on IWMX_SDK_DEV_MAX*/
static struct wmxsdk g_iwmx_sdk_devs[IWMX_SDK_DEV_MAX];

static struct wmxsdk *deviceid_to_wmxsdk(struct WIMAX_API_DEVICE_ID *device_id)
{
	return container_of(device_id, struct wmxsdk, device_id);
}

static struct WIMAX_API_DEVICE_ID g_api;


/*
 * FIXME: pulled it it out of some hole
 *
 * the cinr to percentage computation comes from the L3/L4 doc
 *
 * But some other places (L4 code) have a more complex, seemingly
 * logarithmical computation.
 *
 * Oh well...
 *
 */
static int cinr_to_percentage(int cinr)
{
	int strength;
	if (cinr <= -5)
		strength = 0;
	else if (cinr >= 25)
		strength = 100;
	else	/* Calc percentage on the value from -5 to 25 */
		strength = ((100UL * (cinr - -5)) / (25 - -5));
	return strength;
}

/*
 * Convert a WiMAX API status to an string.
 */
const char *iwmx_sdk_dev_status_to_str(WIMAX_API_DEVICE_STATUS status)
{
	switch (status) {
	case WIMAX_API_DEVICE_STATUS_UnInitialized:
		return "Uninitialized";
		break;
	case WIMAX_API_DEVICE_STATUS_RF_OFF_HW_SW:
		return "Device RF Off(both H/W and S/W)";
		break;
	case WIMAX_API_DEVICE_STATUS_RF_OFF_HW:
		return "Device RF Off(via H/W switch)";
	case WIMAX_API_DEVICE_STATUS_RF_OFF_SW:
		return "Device RF Off(via S/W switch)";
	case WIMAX_API_DEVICE_STATUS_Ready:
		return "Device is ready";
	case WIMAX_API_DEVICE_STATUS_Scanning:
		return "Device is scanning";
	case WIMAX_API_DEVICE_STATUS_Connecting:
		return "Connection in progress";
	case WIMAX_API_DEVICE_STATUS_Data_Connected:
		return "Layer 2 connected";
	case WIMAX_API_DEVICE_STATUS_Connection_Idle:
		return "Idle connection";
	default:
		return "unknown state";
	}
}

/*
 * Get the device's status from the device
 *
 * Does NOT cache the result
 * Does NOT trigger a state change in connman
 *
 * Returns < 0 errno code on error, status code if ok.
 */
WIMAX_API_DEVICE_STATUS iwmx_sdk_get_device_status(struct wmxsdk *wmxsdk)
{
	WIMAX_API_RET r;
	char errstr[512];
	UINT32 errstr_size = sizeof(errstr);

	WIMAX_API_DEVICE_STATUS dev_status;
	WIMAX_API_CONNECTION_PROGRESS_INFO pi;

	r = GetDeviceStatus(&wmxsdk->device_id, &dev_status, &pi);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
		connman_error("wmxsdk: Cannot read device state: %d (%s)\n",
			r, errstr);
		dev_status = -EIO;
	}
	return dev_status;
}

/*
 * Get the device's status from the device but return a string describing it
 *
 * Same conditions as iwmx_sdk_get_device_status().
 */
static const char *iwmx_sdk_get_device_status_str(struct wmxsdk *wmxsdk)
{
	const char *result;
	WIMAX_API_DEVICE_STATUS dev_status;

	dev_status = iwmx_sdk_get_device_status(wmxsdk);
	if ((int) dev_status < 0)
		result = "cannot read device state";
	else
		result = iwmx_sdk_dev_status_to_str(dev_status);
	return result;
}

/*
 * Translate a WiMAX network type to a readable name.
 */
static const char *iwmx_sdk_network_type_name(enum _WIMAX_API_NETWORK_TYPE network_type)
{
	static char *network_type_name[] = {
		[WIMAX_API_HOME] = "",
		[WIMAX_API_PARTNER] = " (partner network)",
		[WIMAX_API_ROAMING_PARTNER] = " (roaming partner network)",
		[WIMAX_API_UNKNOWN] = " (unknown network)",
	};
	if (network_type > WIMAX_API_UNKNOWN)
		return "(BUG! UNKNOWN NETWORK_TYPE MODE)";
	else
		return network_type_name[network_type];
}

/*
 * If the device is connected but we don't know about the network,
 * create the knowledge of it.
 *
 * Asks the WiMAX API to report which NSP we are connected to and we
 * create/update a network_el in the device's network list. Then
 * return it.
 *
 * Returns NULL on error.
 *
 * NOTE: wmxsdk->network_mutex has to be taken
 */
struct connman_network *__iwmx_sdk_get_connected_network(struct wmxsdk *wmxsdk)
{
	struct connman_network *nw;

	struct WIMAX_API_CONNECTED_NSP_INFO nsp_info;
	WIMAX_API_RET r;
	char errstr[512];
	UINT32 errstr_size = sizeof(errstr);

	/* The device is getting connected due to an external (to
	 * connman) event; find which is the nw we are getting
	 * connected to. if we don't have it, add it */
	r = GetConnectedNSP(&wmxsdk->device_id, &nsp_info);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
		connman_error(
			"wmxsdk: Cannot get connected NSP info: %d (%s)\n",
			r, errstr);
		strcpy((char *) nsp_info.NSPName, "unknown");
		nw = iwmx_cm_network_available(
			wmxsdk, "unknown",
			iwmx_sdk_network_type_name(WIMAX_API_UNKNOWN),
			nsp_info.NSPName, strlen((char *) nsp_info.NSPName) + 1,
			cinr_to_percentage(nsp_info.CINR - 10));
	} else {
		nw = iwmx_cm_network_available(
			wmxsdk, (char *) nsp_info.NSPName,
			iwmx_sdk_network_type_name(nsp_info.networkType),
			nsp_info.NSPName, strlen((char *) nsp_info.NSPName) + 1,
			cinr_to_percentage(nsp_info.CINR - 10));
	}
	return nw;
}

/*
 * Callback for a RF State command
 *
 * Called by the WiMAX API when a command sent to change the RF state
 * is completed. This is just a confirmation of what happened with the
 * command.
 *
 * We don't do anything, as when the device changes state, the state
 * change callback is called and that will fiddle with the connman
 * internals.
 */
static void __iwmx_sdk_rf_state_cb(struct WIMAX_API_DEVICE_ID *device_id,
						WIMAX_API_RF_STATE rf_state)
{
	_DBG_IWMX("rf_state changed to %d\n", rf_state);
}

/*
 * Turn the radio on or off
 *
 * First it checks that we are in the right state before doing
 * anything; there might be no need to do anything.
 *
 * Issue a command to the WiMAX API, wait for a callback confirming it
 * is done. Sometimes the callback is missed -- in that case, do force
 * a state change evaluation.
 *
 * Frustration note:
 *
 *      Geezoos efing Xist, they make difficult even the most simple
 *      of the operations
 *
 *      This thing is definitely a pain. If the radio is ON already
 *      and you switch it on again...well, there is no way to tell
 *      because you don't get a callback saying it basically
 *      suceeded. But on the other hand, if the thing was in a
 *      different state and action needs to be taken, you have to wait
 *      for a callback to confirm it's done. However, there is also an
 *      state change callback, which is almost the same, so now you
 *      have to handle things in two "unrelated" threads of execution.
 *
 *      How the shpx are you expected to tell the difference? Check
 *      status first? On timeout? Nice gap (eighteen wheeler size) for
 *      race conditions.
 */
int iwmx_sdk_rf_state_set(struct wmxsdk *wmxsdk, WIMAX_API_RF_STATE rf_state)
{
	int result;

	WIMAX_API_RET r;
	char errstr[512];
	UINT32 errstr_size = sizeof(errstr);
	WIMAX_API_DEVICE_STATUS dev_status;

	g_assert(rf_state == WIMAX_API_RF_ON || rf_state == WIMAX_API_RF_OFF);

	/* Guess what the current radio state is; if it is ON
	 * already, don't redo it. */
	dev_status = iwmx_sdk_get_device_status(wmxsdk);
	if ((int) dev_status < 0) {
		result = dev_status;
		goto error_get_status;
	}
	switch (dev_status) {
	case WIMAX_API_DEVICE_STATUS_UnInitialized:
		result = -EINVAL;
		goto error_cant_do;
	case WIMAX_API_DEVICE_STATUS_RF_OFF_HW_SW:
	case WIMAX_API_DEVICE_STATUS_RF_OFF_HW:
		connman_error(
			"wmxsdk: cannot turn on radio: hw switch is off\n");
		result = -EPERM;
		goto error_cant_do;
		break;
	case WIMAX_API_DEVICE_STATUS_RF_OFF_SW:
		if (rf_state == WIMAX_API_RF_OFF) {
			result = 0;
			_DBG_IWMX("radio is already off\n");
			goto out_done;
		}
		break;
	case WIMAX_API_DEVICE_STATUS_Ready:
	case WIMAX_API_DEVICE_STATUS_Scanning:
	case WIMAX_API_DEVICE_STATUS_Connecting:
	case WIMAX_API_DEVICE_STATUS_Data_Connected:
	case WIMAX_API_DEVICE_STATUS_Connection_Idle:
		if (rf_state == WIMAX_API_RF_ON) {
			result = 0;
			_DBG_IWMX("radio is already on\n");
			goto out_done;
		}
		break;
	default:
		g_assert(1);
	}
	/* Ok, flip the radio */
	r = CmdControlPowerManagement(&wmxsdk->device_id, rf_state);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
		connman_error("wmxsdk: Cannot flip radio to %d: %d (%s) "
			      "[device is in state %s]\n",
			      rf_state, r, errstr,
			      iwmx_sdk_get_device_status_str(wmxsdk));
		result = -EIO;
	} else
		result = -EINPROGRESS;
out_done:
error_cant_do:
error_get_status:
	return result;
}

/*
 * Callback for a Connect command
 *
 * Called by the WiMAX API when a command sent to connect is
 * completed. This is just a confirmation of what happened with the
 * command.
 *
 * WE DON'T DO MUCH HERE -- the real meat happens when a state change
 * callback is sent, where we detect we move to connected state (or
 * from disconnecting to something else); the state change callback is
 * called and that will fiddle with the connman internals.
 */
static void __iwmx_sdk_connect_cb(struct WIMAX_API_DEVICE_ID *device_id,
					WIMAX_API_NETWORK_CONNECTION_RESP resp)
{
	WIMAX_API_DEVICE_STATUS status;
	struct wmxsdk *wmxsdk = deviceid_to_wmxsdk(device_id);

	status = iwmx_cm_status_get(wmxsdk);
	if (resp == WIMAX_API_CONNECTION_SUCCESS) {
		if (status != WIMAX_API_DEVICE_STATUS_Data_Connected
		    && status != WIMAX_API_DEVICE_STATUS_Connection_Idle)
			connman_error("wmxsdk: error: connect worked, but state"
				      " didn't change (now it is %d [%s])\n",
				      status,
				      iwmx_sdk_dev_status_to_str(status));
	} else
		connman_error("wmxsdk: failed to connect (status %d: %s)\n",
			      status, iwmx_sdk_dev_status_to_str(status));
}

/*
 * Connect to a network
 *
 * This function starts the connection process to a given network;
 * when the device changes status, the status change callback will
 * tell connman if the network is finally connected or not.
 *
 * One of the reasons it is done like that is to allow external tools
 * to control the device and the plugin just passing the status so
 * connman displays the right info.
 */
int iwmx_sdk_connect(struct wmxsdk *wmxsdk, struct connman_network *nw)
{
	int result;

	WIMAX_API_RET r;
	char errstr[512];
	UINT32 errstr_size = sizeof(errstr);
	WIMAX_API_DEVICE_STATUS dev_status;
	const char *station_name = connman_network_get_identifier(nw);
	const void *sdk_nspname;
	unsigned int sdk_nspname_size;

	g_mutex_lock(wmxsdk->connect_mutex);
	/* Guess what the current radio state is; if it is ON
	 * already, don't redo it. */
	dev_status = iwmx_cm_status_get(wmxsdk);
	if ((int) dev_status < 0) {
		result = dev_status;
		goto error_get_status;
	}
	switch (dev_status) {
	case WIMAX_API_DEVICE_STATUS_UnInitialized:
		connman_error("wmxsdk: SW BUG? HW is uninitialized\n");
		result = -EINVAL;
		goto error_cant_do;
	case WIMAX_API_DEVICE_STATUS_RF_OFF_HW_SW:
	case WIMAX_API_DEVICE_STATUS_RF_OFF_HW:
	case WIMAX_API_DEVICE_STATUS_RF_OFF_SW:
		connman_error("wmxsdk: Cannot connect: radio is off\n");
		result = -EPERM;
		goto error_cant_do;
	case WIMAX_API_DEVICE_STATUS_Ready:
	case WIMAX_API_DEVICE_STATUS_Scanning:
		break;
	case WIMAX_API_DEVICE_STATUS_Connecting:
		_DBG_IWMX("Connect already pending, waiting for it\n");
		result = -EINPROGRESS;
		goto error_cant_do;
	case WIMAX_API_DEVICE_STATUS_Data_Connected:
	case WIMAX_API_DEVICE_STATUS_Connection_Idle:
		connman_error("wmxsdk: BUG? need to disconnect?\n");
		result = -EINVAL;
		goto error_cant_do;
	default:
		g_assert(1);
	}

	/* Ok, do the connection, wait for a callback */
	wmxsdk->connecting_nw = connman_network_ref(nw);
	sdk_nspname = connman_network_get_blob(nw, "WiMAX.NSP.name",
							&sdk_nspname_size);
	g_assert(sdk_nspname != NULL);
	r = CmdConnectToNetwork(&wmxsdk->device_id, (void *) sdk_nspname, 0, 0);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
		connman_error("wmxsdk: Cannot connect to network %s: %d (%s)"
			      " - device is in state '%s'\n",
			      station_name, r, errstr,
			      iwmx_sdk_get_device_status_str(wmxsdk));
		result = -EIO;
		connman_network_unref(nw);
		wmxsdk->connecting_nw = NULL;
	} else
		result = -EINPROGRESS;
error_cant_do:
error_get_status:
	g_mutex_unlock(wmxsdk->connect_mutex);
	return result;
}

/*
 * Callback for a Disconnect command
 *
 * Called by the WiMAX API when a command sent to connect is
 * completed. This is just a confirmation of what happened with the
 * command.
 *
 * When the device changes state, the state change callback is called
 * and that will fiddle with the connman internals.
 *
 * We just update the result of the command and wake up anybody who is
 * waiting for this conditional variable.
 */
static void __iwmx_sdk_disconnect_cb(struct WIMAX_API_DEVICE_ID *device_id,
					WIMAX_API_NETWORK_CONNECTION_RESP resp)
{
	struct wmxsdk *wmxsdk = deviceid_to_wmxsdk(device_id);
	WIMAX_API_DEVICE_STATUS status;

	status = iwmx_cm_status_get(wmxsdk);
	if (resp == WIMAX_API_CONNECTION_SUCCESS) {
		if (status == WIMAX_API_DEVICE_STATUS_Data_Connected
		    || status == WIMAX_API_DEVICE_STATUS_Connection_Idle)
			connman_error("wmxsdk: error: disconnect worked, "
				      "but state didn't change (now it is "
				      "%d [%s])\n", status,
				      iwmx_sdk_dev_status_to_str(status));
	} else
		connman_error("wmxsdk: failed to disconnect (status %d: %s)\n",
			      status, iwmx_sdk_dev_status_to_str(status));
}

/*
 * Disconnect from a network
 *
 * This function tells the device to disconnect; the state change
 * callback will take care of inform connman's internals.
 */
int iwmx_sdk_disconnect(struct wmxsdk *wmxsdk)
{
	int result;

	WIMAX_API_RET r;
	char errstr[512];
	UINT32 errstr_size = sizeof(errstr);
	WIMAX_API_DEVICE_STATUS dev_status;

	g_mutex_lock(wmxsdk->connect_mutex);
	/* Guess what the current radio state is; if it is ON
	 * already, don't redo it. */
	dev_status = iwmx_sdk_get_device_status(wmxsdk);
	if ((int) dev_status < 0) {
		result = dev_status;
		goto error_get_status;
	}
	switch (dev_status) {
	case WIMAX_API_DEVICE_STATUS_UnInitialized:
		connman_error("wmxsdk: SW BUG? HW is uninitialized\n");
		result = -EINVAL;
		goto error_cant_do;
	case WIMAX_API_DEVICE_STATUS_RF_OFF_HW_SW:
	case WIMAX_API_DEVICE_STATUS_RF_OFF_HW:
	case WIMAX_API_DEVICE_STATUS_RF_OFF_SW:
		_DBG_IWMX("Cannot disconnect, radio is off; ignoring\n");
		result = 0;
		goto error_cant_do;
	case WIMAX_API_DEVICE_STATUS_Ready:
	case WIMAX_API_DEVICE_STATUS_Scanning:
		_DBG_IWMX("Cannot disconnect, already disconnected; ignoring\n");
		result = 0;
		goto error_cant_do;
	case WIMAX_API_DEVICE_STATUS_Connecting:
	case WIMAX_API_DEVICE_STATUS_Data_Connected:
	case WIMAX_API_DEVICE_STATUS_Connection_Idle:
		break;
	default:
		g_assert(1);
	}
	/* Ok, flip the radio */
	r = CmdDisconnectFromNetwork(&wmxsdk->device_id);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
		connman_error("wmxsdk: Cannot disconnect from network: "
			      "%d (%s)\n", r, errstr);
		result = -EIO;
	} else
		result = -EINPROGRESS;
error_cant_do:
error_get_status:
	g_mutex_unlock(wmxsdk->connect_mutex);
	return result;
}

/*
 * Callback for state change messages
 *
 * Just pass them to the state transition handler
 */
static void __iwmx_sdk_state_change_cb(struct WIMAX_API_DEVICE_ID *device_id,
					WIMAX_API_DEVICE_STATUS status,
					WIMAX_API_STATUS_REASON reason,
					WIMAX_API_CONNECTION_PROGRESS_INFO pi)
{
	struct wmxsdk *wmxsdk = deviceid_to_wmxsdk(device_id);
	iwmx_cm_state_change(wmxsdk, status);
}

/*
 * Called by _iwmx_sdk_*scan_cb() when [wide or preferred] scan results
 * are available.
 *
 * From here we update the connman core idea of which networks are
 * available.
 */
static void __iwmx_sdk_scan_common_cb(struct WIMAX_API_DEVICE_ID *device_id,
					struct WIMAX_API_NSP_INFO_EX *nsp_list,
							UINT32 nsp_list_size)
{
	struct wmxsdk *wmxsdk = deviceid_to_wmxsdk(device_id);
	unsigned itr;
	char station_name[256];

	g_static_mutex_lock(&wmxsdk->network_mutex);
	for (itr = 0; itr < nsp_list_size; itr++) {
		int strength;
		struct WIMAX_API_NSP_INFO_EX *nsp_info = &nsp_list[itr];
		snprintf(station_name, sizeof(station_name),
			 "%s", (char *)nsp_info->NSPName);
		/* CAPI is reporing link quality as zero -- if it is
		 * zero, check if it is a bug by computing it based on
		 * CINR. If it is different, use the computed one. */
		strength = nsp_info->linkQuality;
		if (strength == 0) {	/* huh */
			int linkq_expected =
				cinr_to_percentage(nsp_info->CINR - 10);
			if (linkq_expected != strength)
				strength = linkq_expected;
		}

		__iwmx_cm_network_available(
			wmxsdk, station_name,
			iwmx_sdk_network_type_name(nsp_info->networkType),
			nsp_info->NSPName,
			strlen((char *) nsp_info->NSPName) + 1,
			strength);
	}
	g_static_mutex_unlock(&wmxsdk->network_mutex);
}

/*
 * Called by the WiMAX API when we get a wide scan result
 *
 * We treat them same as wide, so we just call that.
 */
static void __iwmx_sdk_wide_scan_cb(struct WIMAX_API_DEVICE_ID *device_id,
				struct WIMAX_API_NSP_INFO_EX *nsp_list,
							UINT32 nsp_list_size)
{
	__iwmx_sdk_scan_common_cb(device_id, nsp_list, nsp_list_size);
}

/*
 * Called by the WiMAX API when we get a normal (non wide) scan result
 *
 * We treat them same as wide, so we just call that.
 */
static void __iwmx_sdk_scan_cb(struct WIMAX_API_DEVICE_ID *device_id,
				struct WIMAX_API_NSP_INFO_EX *nsp_list,
				UINT32 nsp_list_size, UINT32 searchProgress)
{
	__iwmx_sdk_scan_common_cb(device_id, nsp_list, nsp_list_size);
}

/*
 * Called to ask the device to scan for networks
 *
 * We don't really scan as the WiMAX SDK daemon scans in the
 * background for us. We just get the results. See iwmx_sdk_setup().
 */
int iwmx_sdk_scan(struct wmxsdk *wmxsdk)
{
	int result;

	UINT32 nsp_list_length = 10;
	struct WIMAX_API_NSP_INFO_EX nsp_list[10];	/* FIXME: up to 32? */

	WIMAX_API_RET r;
	char errstr[512];
	UINT32 errstr_size = sizeof(errstr);

	r = GetNetworkListEx(&wmxsdk->device_id, nsp_list, &nsp_list_length);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
		connman_error("wmxsdk: Cannot get network list: %d (%s)\n",
			      r, errstr);
		result = -EIO;
		goto error_scan;
	}

	if (nsp_list_length == 0)
		_DBG_IWMX("no networks\n");
	else
		__iwmx_sdk_scan_common_cb(&wmxsdk->device_id, nsp_list,
					nsp_list_length);
	result = 0;
error_scan:
	return result;
}

/*
 * Initialize the WiMAX API, register with it, setup callbacks
 *
 * Called through
 *
 * iwmx_sdk_dev_add
 *   connman_inet_create_device
 *      connman_register
 *         iwmx_cm_probe()
 */
int iwmx_sdk_setup(struct wmxsdk *wmxsdk)
{
	int result;

	WIMAX_API_RET r;

	char errstr[512];
	UINT32 errstr_size = sizeof(errstr);

	result = -ENFILE;

	/* device_id initialized by iwmx_sdk_dev_add */

	r = WiMaxDeviceOpen(&wmxsdk->device_id);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
		connman_error("wmxsdk: Cannot open device: %d (%s)\n",
			      r, errstr);
		goto error_wimaxdeviceopen;
	}

	/*
	 * We scan in auto mode (in the background)
	 *
	 * Otherwise is messy -- if we have connman triggering a scan
	 * when we call iwmx_cm_scan() -> iwmx_sdk_scan(), most of the
	 * times that causes a race condition when the UI asks for a
	 * scan right before displaying the network menu. As there is
	 * no way to cancel an ongoing scan before connecting, we are
	 * stuck. So we do auto bg and have iwmx_sdk_scan() just return
	 * the current network list.
	 */
	r = SetConnectionMode(&wmxsdk->device_id,
			      WIMAX_API_CONNECTION_AUTO_SCAN_MANUAL_CONNECT);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
		connman_error("wmxsdk: Cannot set connectin mode to manual: "
			      "%d (%s)\n", r, errstr);
		goto error_connection_mode;
	}

	r = SubscribeControlPowerManagement(&wmxsdk->device_id,
					    __iwmx_sdk_rf_state_cb);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
		connman_error("wmxsdk: Cannot subscribe to radio change "
			      "events: %u (%s)\n", r, errstr);
		result = -EIO;
		goto error_subscribe_rf_state;
	}

	r = SubscribeDeviceStatusChange(&wmxsdk->device_id,
					__iwmx_sdk_state_change_cb);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
		connman_error("wmxsdk: Cannot subscribe to state chaneg events:"
			      "%d (%s)\n", r, errstr);
		goto error_subscribe_state_change;
	}

	r = SubscribeNetworkSearchWideScanEx(&wmxsdk->device_id,
					     __iwmx_sdk_wide_scan_cb);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
		connman_error("wmxsdk: Cannot subscribe to wide scan events: "
			      "%d (%s)\n", r, errstr);
		goto error_subscribe_wide_scan;
	}
	r = SubscribeNetworkSearchEx(&wmxsdk->device_id, __iwmx_sdk_scan_cb);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
		connman_error("wmxsdk: Cannot subscribe to scan events: "
			      "%d (%s)\n", r, errstr);
		goto error_subscribe_scan;
	}

	r = SubscribeConnectToNetwork(&wmxsdk->device_id,
				      __iwmx_sdk_connect_cb);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
		connman_error("wmxsdk: Cannot subscribe to connect events: "
			      "%d (%s)\n", r, errstr);
		goto error_subscribe_connect;
	}

	r = SubscribeDisconnectToNetwork(&wmxsdk->device_id,
					 __iwmx_sdk_disconnect_cb);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
		connman_error("wmxsdk: Cannot subscribe to disconnect events: "
			      "%d (%s)\n", r, errstr);
		goto error_subscribe_disconnect;
	}
	result = 0;
out:
	return result;

	UnsubscribeDisconnectToNetwork(&wmxsdk->device_id);
error_subscribe_disconnect:
	UnsubscribeConnectToNetwork(&wmxsdk->device_id);
error_subscribe_connect:
	UnsubscribeNetworkSearchEx(&wmxsdk->device_id);
error_subscribe_scan:
	UnsubscribeNetworkSearchWideScanEx(&wmxsdk->device_id);
error_subscribe_wide_scan:
	UnsubscribeDeviceStatusChange(&wmxsdk->device_id);
error_subscribe_state_change:
	UnsubscribeControlPowerManagement(&wmxsdk->device_id);
error_subscribe_rf_state:
error_connection_mode:
	WiMaxDeviceClose(&wmxsdk->device_id);
error_wimaxdeviceopen:
	goto out;
}

/*
 * Called when a device is removed from connman
 *
 * Cleanup all that is done in iwmx_sdk_setup(). Remove callbacks,
 * unregister from the WiMAX API.
 */
void iwmx_sdk_remove(struct wmxsdk *wmxsdk)
{
	UnsubscribeDisconnectToNetwork(&wmxsdk->device_id);
	UnsubscribeConnectToNetwork(&wmxsdk->device_id);
	UnsubscribeNetworkSearchEx(&wmxsdk->device_id);
	UnsubscribeNetworkSearchWideScanEx(&wmxsdk->device_id);
	UnsubscribeDeviceStatusChange(&wmxsdk->device_id);
	UnsubscribeControlPowerManagement(&wmxsdk->device_id);
	WiMaxDeviceClose(&wmxsdk->device_id);
}

static void iwmx_sdk_dev_add(unsigned idx, unsigned api_idx, const char *name)
{
	int result, ifindex;
	struct wmxsdk *wmxsdk;
	const char *s;

	if (idx >= IWMX_SDK_DEV_MAX) {
		connman_error("BUG! idx (%u) >= IWMX_SDK_DEV_MAX (%u)\n",
			      idx, IWMX_SDK_DEV_MAX);
		goto error_bug;
	}
	wmxsdk = &g_iwmx_sdk_devs[idx];
	if (wmxsdk->dev != NULL) {
		connman_error("BUG! device index %u already enumerated?\n",
			      idx);
		goto error_bug;
	}

	memset(wmxsdk, 0, sizeof(*wmxsdk));
	wmxsdk_init(wmxsdk);
	/*
	 * This depends on a hack in the WiMAX Network Service; it has
	 * to return, as part of the device name, a string "if:IFNAME"
	 * where the OS's device name is stored.
	 */
	s = strstr(name, "if:");
	if (s == NULL
	    || sscanf(s, "if:%15[^ \f\n\r\t\v]", wmxsdk->ifname) != 1) {
		connman_error("Cannot extract network interface name off '%s'",
			      name);
		goto error_noifname;
	}
	_DBG_IWMX("network interface name: '%s'", wmxsdk->ifname);

	ifindex = if_nametoindex(wmxsdk->ifname);
	if (ifindex <= 0) {
		result = -ENFILE;
		connman_error("wxmsdk: %s: cannot find interface index\n",
			      wmxsdk->ifname);
		goto error_noifname;
	}

	wmxsdk->dev = connman_inet_create_device(ifindex);
	if (wmxsdk->dev == NULL) {
		connman_error("wmxsdk: %s: failed to create connman_device\n",
			      name);
		goto error_create;
	}
	strncpy(wmxsdk->name, name, sizeof(wmxsdk->name));
	connman_device_set_data(wmxsdk->dev, wmxsdk);

	wmxsdk->device_id.privilege = WIMAX_API_PRIVILEGE_READ_WRITE;
	wmxsdk->device_id.deviceIndex = api_idx;

	result = connman_device_register(wmxsdk->dev);
	if (result < 0) {
		connman_error("wmxsdk: %s: failed to register: %d\n",
			      wmxsdk->ifname, result);
		goto error_dev_add;
	}
	return;

error_dev_add:
	wmxsdk->name[0] = 0;
	connman_device_unref(wmxsdk->dev);
	wmxsdk->dev = NULL;
error_noifname:
error_create:
error_bug:
	return;
}

static void iwmx_sdk_dev_rm(unsigned idx)
{
	struct wmxsdk *wmxsdk;

	if (idx >= IWMX_SDK_DEV_MAX) {
		connman_error("BUG! idx (%u) >= IWMX_SDK_DEV_MAX (%u)\n",
			      idx, IWMX_SDK_DEV_MAX);
		goto error_bug;
	}
	wmxsdk = &g_iwmx_sdk_devs[idx];
	if (wmxsdk->dev == NULL) {
		_DBG_IWMX("device index %u not enumerated? ignoring\n", idx);
		goto error_bug;
	}

	connman_device_unregister(wmxsdk->dev);
	wmxsdk->name[0] = 0;
	connman_device_unref(wmxsdk->dev);
	memset(wmxsdk, 0, sizeof(*wmxsdk));
error_bug:
	return;
}

static void iwmx_sdk_addremove_cb(struct WIMAX_API_DEVICE_ID *devid,
								BOOL presence)
{
	unsigned int cnt;
	WIMAX_API_RET r;
	struct WIMAX_API_HW_DEVICE_ID device_id_list[5];
	UINT32 device_id_list_size = ARRAY_SIZE(device_id_list);

	char errstr[512];
	UINT32 errstr_size = sizeof(errstr);

	_DBG_IWMX("cb: handle %u index #%u is %d\n", devid->sdkHandle,
	    devid->deviceIndex, presence);

	r = GetListDevice(devid, device_id_list, &device_id_list_size);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(devid, r, errstr, &errstr_size);
		connman_error("wmxsdk: Cannot obtain list "
			      "of devices: %d (%s)\n", r, errstr);
		return;
	}

	if (device_id_list_size == 0)
		_DBG_IWMX("No WiMAX devices reported\n");
	else
		for (cnt = 0; cnt < device_id_list_size; cnt++) {
			struct WIMAX_API_HW_DEVICE_ID *dev =
				device_id_list + cnt;
			_DBG_IWMX("#%u index #%u device %s\n",
			    cnt, dev->deviceIndex, dev->deviceName);
		}
	if (device_id_list_size < devid->deviceIndex) {
		connman_error("wmxsdk: changed device (%u) not in the list? "
			      "(%u items)\n",
			      devid->deviceIndex, device_id_list_size);
		return;
	}

	if (presence) {
		struct WIMAX_API_HW_DEVICE_ID *dev =
			device_id_list + devid->deviceIndex;
		iwmx_sdk_dev_add(devid->deviceIndex, dev->deviceIndex,
			       dev->deviceName);
	} else {
		iwmx_sdk_dev_rm(devid->deviceIndex);
	}
}

/*
 * Initialize the WiMAX API, register with it, setup callbacks for
 * device coming up / dissapearing
 */
int iwmx_sdk_api_init(void)
{
	int result;
	unsigned int cnt;
	WIMAX_API_RET r;
	char errstr[512];
	UINT32 errstr_size = sizeof(errstr);

	struct WIMAX_API_HW_DEVICE_ID device_id_list[5];
	UINT32 device_id_list_size = ARRAY_SIZE(device_id_list);

	memset(&g_api, 0, sizeof(g_api));
	g_api.privilege = WIMAX_API_PRIVILEGE_READ_WRITE;

	result = -EIO;
	r = WiMaxAPIOpen(&g_api);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&g_api, r, errstr, &errstr_size);
		connman_error("wmxsdk: WiMaxAPIOpen failed with %d (%s)\n",
			      r, errstr);
		goto error_wimaxapiopen;
	}

	r = SubscribeDeviceInsertRemove(&g_api, iwmx_sdk_addremove_cb);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&g_api, r, errstr, &errstr_size);
		connman_error("wmxsdk: insert/remove subscribe failed with "
			      "%d (%s)\n", r, errstr);
		goto error_close;
	}

	r = GetListDevice(&g_api, device_id_list, &device_id_list_size);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&g_api, r, errstr, &errstr_size);
		connman_error("wmxsdk: Cannot obtain list "
			      "of devices: %d (%s)\n", r, errstr);
		goto error_close;
	}
	if (device_id_list_size < g_api.deviceIndex) {
		connman_error("wmxsdk: changed device (%u) not in the list? "
			      "(%u items)\n",
			      g_api.deviceIndex, device_id_list_size);
	}

	if (device_id_list_size == 0)
		_DBG_IWMX("No WiMAX devices reported\n");
	else
		for (cnt = 0; cnt < device_id_list_size; cnt++) {
			struct WIMAX_API_HW_DEVICE_ID *dev =
				device_id_list + cnt;
			_DBG_IWMX("#%u index #%u device %s\n",
			    cnt, dev->deviceIndex, dev->deviceName);
			iwmx_sdk_dev_add(cnt, dev->deviceIndex,
					 dev->deviceName);
		}
	return 0;

error_close:
	WiMaxAPIClose(&g_api);
error_wimaxapiopen:
	return result;
}

void iwmx_sdk_api_exit(void)
{
	WIMAX_API_RET r;

	char errstr[512];
	UINT32 errstr_size = sizeof(errstr);

	r = WiMaxAPIClose(&g_api);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&g_api, r, errstr, &errstr_size);
		connman_error("wmxsdk: WiMaxAPIClose failed with %d (%s)\n",
			      r, errstr);
	}
	return;
}
