LOCAL void ICACHE_FLASH_ATTR scan_done_cb (void *arg, STATUS status) {
	char buff[80];
	int i;
	if(dhserial_get_mode() == SM_OUTPUT_MODE) {
		if(status != OK) {
			uart_send_line("scan failed");
			return;
		}
		struct bss_info *link = (struct bss_info *)arg;
		link = link->next.stqe_next; //ignore first according to the sdk manual
		if(link)
			uart_send_line("SSID                             Rssi      Channel  Auth      BSSID");
		else
			uart_send_line("No wireless networks found.");
		while(link) {
			char * auth;
			switch(link->authmode) {
			case AUTH_OPEN:
				auth = "open";
				break;
		    case AUTH_WEP:
		    	auth = "WEB";
		    	break;
		    case AUTH_WPA_PSK:
		    	auth = "WPA";
		    	break;
		    case AUTH_WPA2_PSK:
		    	auth = "WPA2";
		    	break;
		    case AUTH_WPA_WPA2_PSK:
		    	auth = "WPA/WPA2";
		    	break;
		    case AUTH_MAX:
		    	auth = "MAX";
		    	break;
			}
			os_memset(&buff, 0, sizeof(buff));
			snprintf(buff, 32, "%s", link->is_hidden ? "<HIDDEN NETWORK>" : (char *)link->ssid);
			snprintf(&buff[33], 9,  "%d dBm", link->rssi);
			snprintf(&buff[43], 8,  "%d", link->channel);
			snprintf(&buff[52], 10,  "%s", auth);
			sprintMac(&buff[62], link->bssid);
			buff[sizeof(buff) - 1] = 0;
			for(i=0; i < sizeof(buff) - 1; i++) {
				if(buff[i] == 0)
					buff[i] = ' ';
			}
			uart_send_line(buff);
			link = link->next.stqe_next;
		}
		dhserial_set_mode(SM_NORMAL_MODE, 0, 0);
	}
	mIsCommandWorking = 0;
}
void ICACHE_FLASH_ATTR dhserial_commands_status(const char *args) {
	uint8 mac[6];
	char digitBuff[32];
	if(!wifi_get_macaddr(STATION_IF, mac)) {
		uart_send_line("Failed to get mac address");
	} else {
		struct station_config stationConfig;
		system_print_meminfo();
		if(!wifi_station_get_config(&stationConfig)) {
			uart_send_line("Could not get station config");
			os_memset(&stationConfig, 0, sizeof(stationConfig));
		}
		uart_send_str("Network adapter ");
		sprintMac(digitBuff, mac);
		uart_send_str(digitBuff);
		switch(wifi_station_get_connect_status()) {
		case STATION_IDLE:
			uart_send_line(" is in idle");
			break;
		case STATION_CONNECTING:
			uart_send_str(" is connecting to ");
			uart_send_line(stationConfig.ssid);
			break;
		case STATION_WRONG_PASSWORD:
			uart_send_str(" has wrong password for ");
			uart_send_line(stationConfig.ssid);
			break;
		case STATION_NO_AP_FOUND:
			uart_send_str(" can not find AP with SSID ");
			uart_send_line(stationConfig.ssid);
			break;
		case STATION_CONNECT_FAIL:
			uart_send_str(" has fail while connecting to ");
			uart_send_line(stationConfig.ssid);
			break;
		case STATION_GOT_IP:
		{
			uart_send_str(" is connected to ");
			uart_send_line(stationConfig.ssid);
			struct ip_info info;
			if(!wifi_get_ip_info(STATION_IF, &info)) {
				uart_send_line("Failed to get ip info");
			} else {
				uart_send_str("IP: ");
				sprintIp(digitBuff, &info.ip);
				uart_send_str(digitBuff);
				uart_send_str(", netmask: ");
				sprintIp(digitBuff, &info.netmask);
				uart_send_str(digitBuff);
				uart_send_str(", gateway: ");
				sprintIp(digitBuff, &info.gw);
				uart_send_line(digitBuff);
			}
			break;
		}
		default:
			uart_send_line("is in unknown state");
			break;
		}
		uart_send_str("DeviceHive: ");
		switch(dhconnector_get_state()) {
		case CS_DISCONNECT:
			uart_send_line("connection is not established.");
			break;
		case CS_GETINFO:
			uart_send_line("getting info from server.");
			break;
		case CS_REGISTER:
			uart_send_line("registering device.");
			break;
		case CS_POLL:
			uart_send_line("successfully connected to server.");
			break;
		default:
			uart_send_line("unknown state");
			break;
		}
	}
	uart_send_str("Free heap size: ");
	snprintf(digitBuff, sizeof(digitBuff), "%d", system_get_free_heap_size());
	uart_send_str(digitBuff);
	uart_send_line(" bytes.");
}
void ICACHE_FLASH_ATTR dhterminal_commands_status(const char *args) {
	uint8 mac[6];
	char digitBuff[32];
	struct station_config stationConfig;

	dhuart_send_str("Network adapter ");
	if(!wifi_get_macaddr(STATION_IF, mac)) {
		dhuart_send_str("[Failed to get mac address]");
	} else {
		sprintMac(digitBuff, mac);
		dhuart_send_str(digitBuff);
	}

	if(!wifi_station_get_config(&stationConfig)) {
		os_memset(&stationConfig, 0, sizeof(stationConfig));
		os_strcpy(stationConfig.ssid, "[Can not get SSID]");
	}
	switch(wifi_station_get_connect_status()) {
	case STATION_IDLE:
		dhuart_send_line(" is in idle");
		break;
	case STATION_CONNECTING:
		dhuart_send_str(" is connecting to ");
		dhuart_send_line(stationConfig.ssid);
		break;
	case STATION_WRONG_PASSWORD:
		dhuart_send_str(" has wrong password for ");
		dhuart_send_line(stationConfig.ssid);
		break;
	case STATION_NO_AP_FOUND:
		dhuart_send_str(" can not find AP with SSID ");
		dhuart_send_line(stationConfig.ssid);
		break;
	case STATION_CONNECT_FAIL:
		dhuart_send_str(" has fail while connecting to ");
		dhuart_send_line(stationConfig.ssid);
		break;
	case STATION_GOT_IP:
	{
		dhuart_send_str(" is connected to ");
		dhuart_send_line(stationConfig.ssid);
		struct ip_info info;
		if(!wifi_get_ip_info(STATION_IF, &info)) {
			dhuart_send_line("Failed to get ip info");
		} else {
			dhuart_send_str("IP: ");
			sprintIp(digitBuff, &info.ip);
			dhuart_send_str(digitBuff);
			dhuart_send_str(", netmask: ");
			sprintIp(digitBuff, &info.netmask);
			dhuart_send_str(digitBuff);
			dhuart_send_str(", gateway: ");
			sprintIp(digitBuff, &info.gw);
			dhuart_send_line(digitBuff);
		}
		break;
	}
	default:
		dhuart_send_line("is in unknown state");
		break;
	}
	const DHSTATISTIC *stat = dhstatistic_get_statistic();
	dhuart_send_str("Wi-Fi disconnect count: ");
	snprintf(digitBuff, sizeof(digitBuff), "%u", stat->wifiLosts);
	dhuart_send_line(digitBuff);

	dhuart_send_str("Bytes received: ");
	printBytes(digitBuff, stat->bytesReceived);
	dhuart_send_str(digitBuff);
	dhuart_send_str(", sent: ");
	printBytes(digitBuff, stat->bytesSent);
	dhuart_send_str(digitBuff);
	dhuart_send_str(", errors: ");
	snprintf(digitBuff, sizeof(digitBuff), "%u", stat->networkErrors);
	dhuart_send_line(digitBuff);

	dhuart_send_str("Httpd requests received: ");
	snprintf(digitBuff, sizeof(digitBuff), "%u", stat->httpdRequestsCount);
	dhuart_send_str(digitBuff);
	dhuart_send_str(", errors: ");
	snprintf(digitBuff, sizeof(digitBuff), "%u", stat->httpdErrorsCount);
	dhuart_send_line(digitBuff);

	dhuart_send_str("DeviceHive: ");
	switch(dhconnector_get_state()) {
	case CS_DISCONNECT:
		dhuart_send_str("connection is not established");
		break;
	case CS_GETINFO:
		dhuart_send_str("getting info from server");
		break;
	case CS_REGISTER:
		dhuart_send_str("registering device");
		break;
	case CS_POLL:
	case CS_CUSTOM:
		dhuart_send_str("successfully connected to server");
		break;
	default:
		dhuart_send_str("unknown state");
		break;
	}
	dhuart_send_str(", errors count: ");
	snprintf(digitBuff, sizeof(digitBuff), "%u", stat->serverErrors);
	dhuart_send_line(digitBuff);

	dhuart_send_str("Responses created/dropped: ");
	snprintf(digitBuff, sizeof(digitBuff), "%u/%u", stat->responcesTotal, stat->responcesDroppedCount);
	dhuart_send_str(digitBuff);
	dhuart_send_str(", notification created/dropped: ");
	snprintf(digitBuff, sizeof(digitBuff), "%u/%u", stat->notificationsTotal, stat->notificationsDroppedCount);
	dhuart_send_line(digitBuff);


	dhuart_send_str("Free heap size: ");
	snprintf(digitBuff, sizeof(digitBuff), "%d", system_get_free_heap_size());
	dhuart_send_str(digitBuff);
	dhuart_send_str(" bytes");

	dhuart_send_str(", request queue size: ");
	snprintf(digitBuff, sizeof(digitBuff), "%d", dhsender_queue_length());
	dhuart_send_line(digitBuff);

}