int _scan_exit(struct osmocom_ms *ms)
{
	/* in case there is a lockup during exit */
	signal(SIGINT, SIG_DFL);
	signal(SIGHUP, SIG_DFL);
	signal(SIGTERM, SIG_DFL);
	signal(SIGPIPE, SIG_DFL);

	scan_exit();

	return 0;
}
/**
 * wpa_driver_tista_deinit - Deinitialize WE driver interface
 * @priv: Pointer to private wext data from wpa_driver_tista_init()
 *
 * Shut down driver interface and processing of driver events. Free
 * private data buffer if one was allocated in wpa_driver_tista_init().
 */
void wpa_driver_tista_deinit(void *priv)
{
    struct wpa_driver_ti_data *drv = priv;

    wpa_driver_wext_deinit(drv->wext);
    close(drv->ioctl_sock);
    scan_exit(drv);
#ifdef CONFIG_WPS
    wpabuf_free(drv->probe_req_ie);
    drv->probe_req_ie = NULL;
#endif
    os_free(drv);
}
int scan_init(struct osmocom_ms *_ms)
{
	ms = _ms;
	osmo_signal_register_handler(SS_L1CTL, &signal_cb, NULL);
	memset(&timer, 0, sizeof(timer));
	lapdm_channel_set_l3(&ms->lapdm_channel, &rcv_rsl, ms);
	g.enable = 1;
	osmo_gps_init();
	if (osmo_gps_open())
		g.enable = 0;

	if (!strcmp(logname, "-"))
		logfp = stdout;
	else
		logfp = fopen(logname, "a");
	if (!logfp) {
		fprintf(stderr, "Failed to open logfile '%s'\n", logname);
		scan_exit();
		return -errno;
	}
	LOGP(DSUM, LOGL_INFO, "Scanner initialized\n");

	return 0;
}
/*-----------------------------------------------------------------------------
Routine Name: wpa_driver_tista_driver_cmd
Routine Description: executes driver-specific commands
Arguments:
   priv - pointer to private data structure
   cmd - command
   buf - return buffer
   buf_len - buffer length
Return Value: actual buffer length - success, -1 - failure
-----------------------------------------------------------------------------*/
static int wpa_driver_tista_driver_cmd( void *priv, char *cmd, char *buf, size_t buf_len )
{
    struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
    int ret = -1, prev_events, flags;

    wpa_printf(MSG_DEBUG, "%s %s", __func__, cmd);

    if( os_strcasecmp(cmd, "start") == 0 ) {
        wpa_printf(MSG_DEBUG,"Start command");
        scan_exit(drv); /* Clear scan cache */
        ret = wpa_driver_tista_driver_start(priv);
        if( ret == 0 ) {
            drv->driver_is_loaded = TRUE;
            wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
        }
        return( TI2WPA_STATUS(ret) );
    }

    TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );

    if( os_strcasecmp(cmd, "stop") == 0 ) {
        wpa_printf(MSG_DEBUG,"Stop command");
        if ((wpa_driver_wext_get_ifflags(drv->wext, &flags) == 0) &&
                (flags & IFF_UP)) {
            wpa_printf(MSG_ERROR, "TI: %s when iface is UP", cmd);
            wpa_driver_wext_set_ifflags(drv->wext, flags & ~IFF_UP);
        }
        ret = wpa_driver_tista_driver_stop(priv);
        if( ret == 0 ) {
            scan_exit(drv); /* Clear scan cache */
            drv->driver_is_loaded = FALSE;
            wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
        }
    }
    if( os_strcasecmp(cmd, "reload") == 0 ) {
        wpa_printf(MSG_DEBUG,"Reload command");
        ret = 0;
        wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
    }
    else if( os_strcasecmp(cmd, "macaddr") == 0 ) {
        wpa_driver_tista_get_mac_addr(priv);
        wpa_printf(MSG_DEBUG, "Macaddr command");
        ret = sprintf(buf, "Macaddr = " MACSTR "\n", MAC2STR(drv->own_addr));
        wpa_printf(MSG_DEBUG, "buf %s", buf);
    }
    else if( os_strcasecmp(cmd, "scan-passive") == 0 ) {
        wpa_printf(MSG_DEBUG,"Scan Passive command");
        drv->scan_type =  SCAN_TYPE_NORMAL_PASSIVE;
        ret = 0;
    }
    else if( os_strcasecmp(cmd, "scan-active") == 0 ) {
        wpa_printf(MSG_DEBUG,"Scan Active command");
        drv->scan_type =  SCAN_TYPE_NORMAL_ACTIVE;
        ret = 0;
    }
    else if( os_strcasecmp(cmd, "scan-mode") == 0 ) {
        wpa_printf(MSG_DEBUG,"Scan Mode command");
        ret = snprintf(buf, buf_len, "ScanMode = %u\n", drv->scan_type);
        if (ret < (int)buf_len) {
            return( ret );
        }
    }
    else if( os_strcasecmp(cmd, "linkspeed") == 0 ) {
        struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);

        wpa_printf(MSG_DEBUG,"Link Speed command");
        drv->link_speed = wpa_s->link_speed / 1000000;
        ret = sprintf(buf,"LinkSpeed %u\n", drv->link_speed);
        wpa_printf(MSG_DEBUG, "buf %s", buf);
    }
    else if( os_strncasecmp(cmd, "scan-channels", 13) == 0 ) {
        int noOfChan;

        noOfChan = atoi(cmd + 13);
        wpa_printf(MSG_DEBUG,"Scan Channels command = %d", noOfChan);
        if( (noOfChan > 0) && (noOfChan <= MAX_NUMBER_OF_CHANNELS_PER_SCAN) )
            drv->scan_channels = noOfChan;
        ret = sprintf(buf,"Scan-Channels = %d\n", drv->scan_channels);
        wpa_printf(MSG_DEBUG, "buf %s", buf);
    }
    else if( os_strcasecmp(cmd, "rssi-approx") == 0 ) {
        scan_result_t *cur_res;
        struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
        scan_ssid_t *p_ssid;
        int rssi, len;

        wpa_printf(MSG_DEBUG,"rssi-approx command");

        if( !wpa_s )
            return( ret );
        cur_res = scan_get_by_bssid(drv, wpa_s->bssid);
        if( cur_res ) {
            p_ssid = scan_get_ssid(cur_res);
            if( p_ssid ) {
                len = (int)(p_ssid->ssid_len);
                rssi = cur_res->level;
                if( (len > 0) && (len <= MAX_SSID_LEN) && (len < (int)buf_len)) {
                    os_memcpy((void *)buf, (void *)(p_ssid->ssid), len);
                    ret = len;
                    ret += snprintf(&buf[ret], buf_len-len, " rssi %d\n", rssi);
                }
            }
        }
    }
    else if( os_strcasecmp(cmd, "rssi") == 0 ) {
        u8 ssid[MAX_SSID_LEN];
        scan_result_t *cur_res;
        struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
        int rssi_data, rssi_beacon, len;

        wpa_printf(MSG_DEBUG,"rssi command");

        ret = wpa_driver_tista_get_rssi(priv, &rssi_data, &rssi_beacon);
        if( ret == 0 ) {
            len = wpa_driver_tista_get_ssid(priv, (u8 *)ssid);
            wpa_printf(MSG_DEBUG,"rssi_data %d rssi_beacon %d", rssi_data, rssi_beacon);
            if( (len > 0) && (len <= MAX_SSID_LEN) ) {
                os_memcpy((void *)buf, (void *)ssid, len);
                ret = len;
                ret += sprintf(&buf[ret], " rssi %d\n", rssi_beacon);
                wpa_printf(MSG_DEBUG, "buf %s", buf);
                /* Update cached value */
                if( !wpa_s )
                    return( ret );
                cur_res = scan_get_by_bssid(drv, wpa_s->bssid);
                if( cur_res )
                    cur_res->level = rssi_beacon;
            }
            else
            {
                wpa_printf(MSG_DEBUG, "Fail to get ssid when reporting rssi");
                ret = -1;
            }
        }
    }
    else if( os_strncasecmp(cmd, "powermode", 9) == 0 ) {
        u32 mode;
        TPowerMgr_PowerMode tMode;

        mode = (u32)atoi(cmd + 9);
        wpa_printf(MSG_DEBUG,"Power Mode command = %u", mode);
        if( mode < POWER_MODE_MAX )
        {
            tMode.PowerMode = (PowerMgr_PowerMode_e)mode;
            tMode.PowerMngPriority = POWER_MANAGER_USER_PRIORITY;
            ret = wpa_driver_tista_config_power_management( priv, &tMode, 1 );
        }
    }
    else if (os_strncasecmp(cmd, "getpower", 8) == 0 ) {
        u32 mode;
        TPowerMgr_PowerMode tMode;

        os_memset(&tMode, 0, sizeof(TPowerMgr_PowerMode));
        ret = wpa_driver_tista_config_power_management( priv, &tMode, 0 );
        if( ret == 0 ) {
            ret = sprintf(buf, "powermode = %u\n", tMode.PowerMode);
            wpa_printf(MSG_DEBUG, "buf %s", buf);
        }
    }
    else if( os_strncasecmp(cmd, "btcoexmode", 10) == 0 ) {
        u32 mode;

        mode = (u32)atoi(cmd + 10);
        wpa_printf(MSG_DEBUG,"BtCoex Mode command = %u", mode);
        ret = wpa_driver_tista_enable_bt_coe( priv, mode );
        if( ret == 0 ) {
            drv->btcoex_mode = mode;
        }
    }
    else if( os_strcasecmp(cmd, "btcoexstat") == 0 ) {
        u32 status = drv->btcoex_mode;

        wpa_printf(MSG_DEBUG,"BtCoex Status");
        ret = wpa_driver_tista_get_bt_coe_status( priv, &status );
        if( ret == 0 ) {
            ret = sprintf(buf, "btcoexstatus = 0x%x\n", status);
            wpa_printf(MSG_DEBUG, "buf %s", buf);
        }
    }
    else if( os_strcasecmp(cmd, "rxfilter-start") == 0 ) {
        wpa_printf(MSG_DEBUG,"Rx Data Filter Start command");
        ret = wpa_driver_tista_driver_enable_rx_data_filter( priv );
    }
    else if( os_strcasecmp(cmd, "rxfilter-stop") == 0 ) {
        wpa_printf(MSG_DEBUG,"Rx Data Filter Stop command");
        ret = wpa_driver_tista_driver_disable_rx_data_filter( priv );
    }
    else if( os_strcasecmp(cmd, "rxfilter-statistics") == 0 ) {
        TCuCommon_RxDataFilteringStatistics stats;
        int len, i;

        os_memset(&stats, 0, sizeof(TCuCommon_RxDataFilteringStatistics));
        wpa_printf(MSG_DEBUG,"Rx Data Filter Statistics command");
        ret = wpa_driver_tista_driver_rx_data_filter_statistics( priv, &stats );
        if( ret == 0 ) {
            ret = snprintf(buf, buf_len, "RxFilterStat: %u", (u32)stats.unmatchedPacketsCount);
            for(i=0; ( i < MAX_DATA_FILTERS ); i++) {
                ret += snprintf(&buf[ret], buf_len-ret, " %u", (u32)stats.matchedPacketsCount[i]);
            }
            ret += snprintf(&buf[ret], buf_len-ret, "\n");
            if (ret >= (int)buf_len) {
                ret = -1;
            }
        }
    }
    else if( os_strncasecmp(cmd, "rxfilter-add", 12) == 0 ) {
        TRxDataFilterRequest dfreq;
        char *cp = cmd + 12;
        char *endp;
        int type;

        if (*cp != '\0') {
            type = (int)strtol(cp, &endp, 0);
            if (endp != cp) {
                wpa_printf(MSG_DEBUG,"Rx Data Filter Add [%d] command", type);
                ret = prepare_filter_struct( priv, type, &dfreq );
                if( ret == 0 ) {
                    ret = wpa_driver_tista_driver_rx_data_filter( priv, &dfreq, 1 );
                }
            }
        }
    }
    else if( os_strncasecmp(cmd, "rxfilter-remove",15) == 0 ) {
        TRxDataFilterRequest dfreq;
        char *cp = cmd + 15;
        char *endp;
        int type;

        if (*cp != '\0') {
            type = (int)strtol(cp, &endp, 0);
            if (endp != cp) {
                wpa_printf(MSG_DEBUG,"Rx Data Filter remove [%d] command", type);
                ret = prepare_filter_struct( priv, type, &dfreq );
                if( ret == 0 ) {
                    ret = wpa_driver_tista_driver_rx_data_filter( priv, &dfreq, 0 );
                }
            }
        }
    }
    else {
        wpa_printf(MSG_DEBUG,"Unsupported command");
    }
    return ret;
}