Exemple #1
0
//addr format: xx:xx:xx:xx:xx:xx
void
wrapd_load_vma_list(const char *conf_file, wrapd_hdl_t *handle)
{
    struct wrap_demon *aptr = (struct wrap_demon *)handle;
	FILE *f;
	char buf[256], *pos, *start;
	int line = 0, off =0;

    wrapd_printf("oma conf file(%s)", conf_file);

    f = fopen(conf_file, "r");
    if (f == NULL) {
        wrapd_printf("Cant open oma conf file(%s)", conf_file);
        return;
    }
    
	while ((fgets(buf, sizeof(buf), f)) && (off < WRAP_MAX_PSTA_NUM)) {
        line ++;
		if (buf[0] == '#')
			continue;
        
        pos = buf;
		while (*pos != '\0') {
			if (*pos == '\n') {
				*pos = '\0';
				break;
			}
			pos ++;
		}

        pos = os_strchr(buf, ':');
        if ((pos == NULL) || (pos - buf < 2) || (os_strlen(pos) < 15)) {
            wrapd_printf("Invalid addr in line %d", line);
            continue;
        }

        start = pos - 2;
        start[17] = '\0';
        if((start[5] != ':') ||(start[8] != ':') ||(start[11] != ':')|| (start[14] != ':')){
            wrapd_printf("Invalid addr in line %d", line);
            continue;
        }
        
        if (char2addr(start) != 0) {
            wrapd_printf("Invalid addr in line %d", line);	
            continue;
        }
        
        os_memcpy(aptr->psta[off].vma, start, IEEE80211_ADDR_LEN);
        aptr->psta[off].vma_loaded = 1;
        aptr->psta[off].added = 0;
        aptr->psta[off].connected = 0;

        wrapd_printf("Load VMA(%02x:%02x:%02x:%02x:%02x:%02x) to off(%d) in line %d",
            aptr->psta[off].vma[0], aptr->psta[off].vma[1], aptr->psta[off].vma[2],
            aptr->psta[off].vma[3], aptr->psta[off].vma[4], aptr->psta[off].vma[5],
            off, line); 
        off ++;
    }

    close((int)f);
}
Exemple #2
0
static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
				    struct wpa_ssid *ssid)
{
	struct hostapd_iface *ifmsh;
	struct hostapd_data *bss;
	struct hostapd_config *conf;
	struct mesh_conf *mconf;
	int basic_rates_erp[] = { 10, 20, 55, 60, 110, 120, 240, -1 };
	static int default_groups[] = { 19, 20, 21, 25, 26, -1 };
	size_t len;
	int rate_len;

	if (!wpa_s->conf->user_mpm) {
		/* not much for us to do here */
		wpa_msg(wpa_s, MSG_WARNING,
			"user_mpm is not enabled in configuration");
		return 0;
	}

	wpa_s->ifmsh = ifmsh = os_zalloc(sizeof(*wpa_s->ifmsh));
	if (!ifmsh)
		return -ENOMEM;

	ifmsh->drv_flags = wpa_s->drv_flags;
	ifmsh->num_bss = 1;
	ifmsh->bss = os_calloc(wpa_s->ifmsh->num_bss,
			       sizeof(struct hostapd_data *));
	if (!ifmsh->bss)
		goto out_free;

	ifmsh->bss[0] = bss = os_zalloc(sizeof(struct hostapd_data));
	if (!bss)
		goto out_free;

	os_memcpy(bss->own_addr, wpa_s->own_addr, ETH_ALEN);
	bss->driver = wpa_s->driver;
	bss->drv_priv = wpa_s->drv_priv;
	bss->iface = ifmsh;
	bss->mesh_sta_free_cb = mesh_mpm_free_sta;
	wpa_s->assoc_freq = ssid->frequency;
	wpa_s->current_ssid = ssid;

	/* setup an AP config for auth processing */
	conf = hostapd_config_defaults();
	if (!conf)
		goto out_free;

	bss->conf = *conf->bss;
	bss->conf->start_disabled = 1;
	bss->conf->mesh = MESH_ENABLED;
	bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity;
	bss->iconf = conf;
	ifmsh->conf = conf;

	ifmsh->bss[0]->max_plinks = wpa_s->conf->max_peer_links;
	os_strlcpy(bss->conf->iface, wpa_s->ifname, sizeof(bss->conf->iface));

	mconf = mesh_config_create(ssid);
	if (!mconf)
		goto out_free;
	ifmsh->mconf = mconf;

	/* need conf->hw_mode for supported rates. */
	if (ssid->frequency == 0) {
		conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
		conf->channel = 1;
	} else {
		conf->hw_mode = ieee80211_freq_to_chan(ssid->frequency,
						       &conf->channel);
	}
	if (conf->hw_mode == NUM_HOSTAPD_MODES) {
		wpa_printf(MSG_ERROR, "Unsupported mesh mode frequency: %d MHz",
			   ssid->frequency);
		goto out_free;
	}

	if (ssid->mesh_basic_rates == NULL) {
		/*
		 * XXX: Hack! This is so an MPM which correctly sets the ERP
		 * mandatory rates as BSSBasicRateSet doesn't reject us. We
		 * could add a new hw_mode HOSTAPD_MODE_IEEE80211G_ERP, but
		 * this is way easier. This also makes our BSSBasicRateSet
		 * advertised in beacons match the one in peering frames, sigh.
		 */
		if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G) {
			conf->basic_rates = os_malloc(sizeof(basic_rates_erp));
			if (!conf->basic_rates)
				goto out_free;
			os_memcpy(conf->basic_rates, basic_rates_erp,
				  sizeof(basic_rates_erp));
		}
	} else {
		rate_len = 0;
		while (1) {
			if (ssid->mesh_basic_rates[rate_len] < 1)
				break;
			rate_len++;
		}
		conf->basic_rates = os_calloc(rate_len + 1, sizeof(int));
		if (conf->basic_rates == NULL)
			goto out_free;
		os_memcpy(conf->basic_rates, ssid->mesh_basic_rates,
			  rate_len * sizeof(int));
		conf->basic_rates[rate_len] = -1;
	}

	if (hostapd_setup_interface(ifmsh)) {
		wpa_printf(MSG_ERROR,
			   "Failed to initialize hostapd interface for mesh");
		return -1;
	}

	if (wpa_drv_init_mesh(wpa_s)) {
		wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver");
		return -1;
	}

	if (mconf->security != MESH_CONF_SEC_NONE) {
		if (ssid->passphrase == NULL) {
			wpa_printf(MSG_ERROR,
				   "mesh: Passphrase for SAE not configured");
			goto out_free;
		}

		bss->conf->wpa = ssid->proto;
		bss->conf->wpa_key_mgmt = ssid->key_mgmt;

		if (wpa_s->conf->sae_groups &&
		    wpa_s->conf->sae_groups[0] > 0) {
			wpas_mesh_copy_groups(bss, wpa_s);
		} else {
			bss->conf->sae_groups =
				os_malloc(sizeof(default_groups));
			if (!bss->conf->sae_groups)
				goto out_free;
			os_memcpy(bss->conf->sae_groups, default_groups,
				  sizeof(default_groups));
		}

		len = os_strlen(ssid->passphrase);
		bss->conf->ssid.wpa_passphrase =
			dup_binstr(ssid->passphrase, len);

		wpa_s->mesh_rsn = mesh_rsn_auth_init(wpa_s, mconf);
		if (!wpa_s->mesh_rsn)
			goto out_free;
	}

	wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);

	return 0;
out_free:
	wpa_supplicant_mesh_deinit(wpa_s);
	return -ENOMEM;
}
Exemple #3
0
/* xml_add_tagged_data -- format tagged data as a new xml line.
 *
 * tag must not have any special chars.
 * data may have special chars, which are escaped.
 */
void xml_add_tagged_data(struct wpabuf *buf, const char *tag, const char *data)
{
	wpabuf_printf(buf, "<%s>", tag);
	xml_data_encode(buf, data, os_strlen(data));
	wpabuf_printf(buf, "</%s>\n", tag);
}
static int str_starts(const char *str, const char *start)
{
	return os_strncmp(str, start, os_strlen(start)) == 0;
}
int hostapd_init_wps(struct hostapd_data *hapd,
		     struct hostapd_bss_config *conf)
{
	struct wps_context *wps;
	struct wps_registrar_config cfg;

	if (conf->wps_state == 0) {
		hostapd_wps_clear_ies(hapd);
		return 0;
	}

	wps = os_zalloc(sizeof(*wps));
	if (wps == NULL)
		return -1;

	wps->cred_cb = hostapd_wps_cred_cb;
	wps->event_cb = hostapd_wps_event_cb;
	wps->cb_ctx = hapd;

	os_memset(&cfg, 0, sizeof(cfg));
	wps->wps_state = hapd->conf->wps_state;
	wps->ap_setup_locked = hapd->conf->ap_setup_locked;
	if (is_nil_uuid(hapd->conf->uuid)) {
		const u8 *uuid;
		uuid = get_own_uuid(hapd->iface);
		if (uuid) {
			os_memcpy(wps->uuid, uuid, UUID_LEN);
#if 0								//peter-jc To follow MR0 wpa_hexdump modification	
			wpa_hexdump(MSG_DEBUG, "WPS: Clone UUID from another "
				    "interface", wps->uuid, UUID_LEN);
#endif				    
		} else {
			uuid_gen_mac_addr(hapd->own_addr, wps->uuid);
#if 0								//peter-jc To follow MR0 wpa_hexdump modification				
			wpa_hexdump(MSG_DEBUG, "WPS: UUID based on MAC "
				    "address", wps->uuid, UUID_LEN);
#endif
		}
	} else {
		os_memcpy(wps->uuid, hapd->conf->uuid, UUID_LEN);
#if 0								//peter-jc To follow MR0 wpa_hexdump modification					
		wpa_hexdump(MSG_DEBUG, "WPS: Use configured UUID",
			    wps->uuid, UUID_LEN);
#endif			    
	}
	wps->ssid_len = hapd->conf->ssid.ssid_len;
	os_memcpy(wps->ssid, hapd->conf->ssid.ssid, wps->ssid_len);
	wps->ap = 1;
	os_memcpy(wps->dev.mac_addr, hapd->own_addr, ETH_ALEN);
	wps->dev.device_name = hapd->conf->device_name ?
		os_strdup(hapd->conf->device_name) : NULL;
	wps->dev.manufacturer = hapd->conf->manufacturer ?
		os_strdup(hapd->conf->manufacturer) : NULL;
	wps->dev.model_name = hapd->conf->model_name ?
		os_strdup(hapd->conf->model_name) : NULL;
	wps->dev.model_number = hapd->conf->model_number ?
		os_strdup(hapd->conf->model_number) : NULL;
	wps->dev.serial_number = hapd->conf->serial_number ?
		os_strdup(hapd->conf->serial_number) : NULL;
	wps->config_methods =
		wps_config_methods_str2bin(hapd->conf->config_methods);
#ifdef CONFIG_WPS2
	if ((wps->config_methods &
	     (WPS_CONFIG_DISPLAY | WPS_CONFIG_VIRT_DISPLAY |
	      WPS_CONFIG_PHY_DISPLAY)) == WPS_CONFIG_DISPLAY) {
		wpa_printf(MSG_INFO, "WPS: Converting display to "
			   "virtual_display for WPS 2.0 compliance");
		wps->config_methods |= WPS_CONFIG_VIRT_DISPLAY;
	}
	if ((wps->config_methods &
	     (WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_VIRT_PUSHBUTTON |
	      WPS_CONFIG_PHY_PUSHBUTTON)) == WPS_CONFIG_PUSHBUTTON) {
		wpa_printf(MSG_INFO, "WPS: Converting push_button to "
			   "virtual_push_button for WPS 2.0 compliance");
		wps->config_methods |= WPS_CONFIG_VIRT_PUSHBUTTON;
	}
#endif /* CONFIG_WPS2 */
	os_memcpy(wps->dev.pri_dev_type, hapd->conf->device_type,
		  WPS_DEV_TYPE_LEN);

	if (hostapd_wps_set_vendor_ext(hapd, wps) < 0) {
		os_free(wps);
		return -1;
	}

	wps->dev.os_version = WPA_GET_BE32(hapd->conf->os_version);

	if (conf->wps_rf_bands) {
		wps->dev.rf_bands = conf->wps_rf_bands;
	} else {
		wps->dev.rf_bands =
			hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211A ?
			WPS_RF_50GHZ : WPS_RF_24GHZ; /* FIX: dualband AP */
	}

	if (conf->wpa & WPA_PROTO_RSN) {
		if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK)
			wps->auth_types |= WPS_AUTH_WPA2PSK;
		if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X)
			wps->auth_types |= WPS_AUTH_WPA2;

		if (conf->rsn_pairwise & WPA_CIPHER_CCMP)
			wps->encr_types |= WPS_ENCR_AES;
		if (conf->rsn_pairwise & WPA_CIPHER_TKIP)
			wps->encr_types |= WPS_ENCR_TKIP;
	}

	if (conf->wpa & WPA_PROTO_WPA) {
		if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK)
			wps->auth_types |= WPS_AUTH_WPAPSK;
		if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X)
			wps->auth_types |= WPS_AUTH_WPA;

		if (conf->wpa_pairwise & WPA_CIPHER_CCMP)
			wps->encr_types |= WPS_ENCR_AES;
		if (conf->wpa_pairwise & WPA_CIPHER_TKIP)
			wps->encr_types |= WPS_ENCR_TKIP;
	}

	if (conf->ssid.security_policy == SECURITY_PLAINTEXT) {
		wps->encr_types |= WPS_ENCR_NONE;
		wps->auth_types |= WPS_AUTH_OPEN;
	} else if (conf->ssid.security_policy == SECURITY_STATIC_WEP) {
		wps->encr_types |= WPS_ENCR_WEP;
		if (conf->auth_algs & WPA_AUTH_ALG_OPEN)
			wps->auth_types |= WPS_AUTH_OPEN;
		if (conf->auth_algs & WPA_AUTH_ALG_SHARED)
			wps->auth_types |= WPS_AUTH_SHARED;
	} else if (conf->ssid.security_policy == SECURITY_IEEE_802_1X) {
		wps->auth_types |= WPS_AUTH_OPEN;
		if (conf->default_wep_key_len)
			wps->encr_types |= WPS_ENCR_WEP;
		else
			wps->encr_types |= WPS_ENCR_NONE;
	}

	if (conf->ssid.wpa_psk_file) {
		/* Use per-device PSKs */
	} else if (conf->ssid.wpa_passphrase) {
		wps->network_key = (u8 *) os_strdup(conf->ssid.wpa_passphrase);
		wps->network_key_len = os_strlen(conf->ssid.wpa_passphrase);
	} else if (conf->ssid.wpa_psk) {
		wps->network_key = os_malloc(2 * PMK_LEN + 1);
		if (wps->network_key == NULL) {
			os_free(wps);
			return -1;
		}
		wpa_snprintf_hex((char *) wps->network_key, 2 * PMK_LEN + 1,
				 conf->ssid.wpa_psk->psk, PMK_LEN);
		wps->network_key_len = 2 * PMK_LEN;
	} else if (conf->ssid.wep.keys_set && conf->ssid.wep.key[0]) {
		wps->network_key = os_malloc(conf->ssid.wep.len[0]);
		if (wps->network_key == NULL) {
			os_free(wps);
			return -1;
		}
		os_memcpy(wps->network_key, conf->ssid.wep.key[0],
			  conf->ssid.wep.len[0]);
		wps->network_key_len = conf->ssid.wep.len[0];
	}

	if (conf->ssid.wpa_psk) {
		os_memcpy(wps->psk, conf->ssid.wpa_psk->psk, PMK_LEN);
		wps->psk_set = 1;
	}

	if (conf->wps_state == WPS_STATE_NOT_CONFIGURED) {
		/* Override parameters to enable security by default */
		wps->auth_types = WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK;
		wps->encr_types = WPS_ENCR_AES | WPS_ENCR_TKIP;
	}

	wps->ap_settings = conf->ap_settings;
	wps->ap_settings_len = conf->ap_settings_len;

	cfg.new_psk_cb = hostapd_wps_new_psk_cb;
	cfg.set_ie_cb = hostapd_wps_set_ie_cb;
	cfg.pin_needed_cb = hostapd_wps_pin_needed_cb;
	cfg.reg_success_cb = hostapd_wps_reg_success_cb;
	cfg.enrollee_seen_cb = hostapd_wps_enrollee_seen_cb;
	cfg.cb_ctx = hapd;
	cfg.skip_cred_build = conf->skip_cred_build;
	cfg.extra_cred = conf->extra_cred;
	cfg.extra_cred_len = conf->extra_cred_len;
	cfg.disable_auto_conf = (hapd->conf->wps_cred_processing == 1) &&
		conf->skip_cred_build;
	if (conf->ssid.security_policy == SECURITY_STATIC_WEP)
		cfg.static_wep_only = 1;
	cfg.dualband = interface_count(hapd->iface) > 1;
	if (cfg.dualband)
		wpa_printf(MSG_DEBUG, "WPS: Dualband AP");

	wps->registrar = wps_registrar_init(wps, &cfg);
	if (wps->registrar == NULL) {
		wpa_printf(MSG_ERROR, "Failed to initialize WPS Registrar");
		os_free(wps->network_key);
		os_free(wps);
		return -1;
	}

#ifdef CONFIG_WPS_UPNP
	wps->friendly_name = hapd->conf->friendly_name;
	wps->manufacturer_url = hapd->conf->manufacturer_url;
	wps->model_description = hapd->conf->model_description;
	wps->model_url = hapd->conf->model_url;
	wps->upc = hapd->conf->upc;
#endif /* CONFIG_WPS_UPNP */

	hostapd_register_probereq_cb(hapd, hostapd_wps_probe_req_rx, hapd);

	hapd->wps = wps;

	return 0;
}
//***********************************************************************
void ICACHE_FLASH_ATTR webSocketRecvCb(void *arg, char *data, unsigned short len) {
  espconn *esp_connection = (espconn*)arg;

  //received some data from webSocket connection
  //webSocketDebug("In webSocketRecvCb\n");
  //  webSocketDebug("webSocket recv--->%s<----\n", data);

  WSConnection *wsConnection = getWsConnection(esp_connection);
  if (wsConnection == NULL) {
    webSocketDebug("webSocket Heh?\n");
    return;
  }

  //get the first occurrence of the key identifier
  char *key = os_strstr(data, WS_KEY_IDENTIFIER);

  //  webSocketDebug("key-->%s<--\n", key );

  if (key != NULL) {
    // ------------------------ Handle the Handshake ------------------------
    //    webSocketDebug("In Handle the Handshake\n");
    //Skip the identifier (that contains the space already)
    key += os_strlen(WS_KEY_IDENTIFIER);

    //   webSocketDebug("keynow-->%s<--\n", key);

    //the key ends at the newline
    char *endSequence = os_strstr(key, HTML_HEADER_LINEEND);
    //    webSocketDebug("endSequency-->%s<--\n", endSequence);

    if (endSequence != NULL) {
      int keyLastChar = endSequence - key;
      //we can throw away all the other data, only the key is interesting
      key[keyLastChar] = '\0';
      //      webSocketDebug("keyTrimmed-->%s<--\n", key);

      char acceptKey[100];
      createWsAcceptKey(key, acceptKey, 100);

      //     webSocketDebug("acceptKey-->%s<--\n", acceptKey);

      //now construct our message and send it back to the client
      char responseMessage[strlen(WS_RESPONSE) + 100];
      os_sprintf(responseMessage, WS_RESPONSE, acceptKey);

      //      webSocketDebug("responseMessage-->%s<--\n", responseMessage);

      //send the response
      espconn_sent(esp_connection, (uint8_t *)responseMessage, strlen(responseMessage));
      wsConnection->status = STATUS_OPEN;

      //call the connection callback
      if (wsOnConnectionCallback != NULL) {
        //       webSocketDebug("Handle the Handshake 5\n");
        wsOnConnectionCallback();
      }
    }
  } else {
    // ------------------------ Handle a Frame ------------------------
    //    webSocketDebug("In Handle a Frame\n");

    WSFrame frame;
    parseWsFrame(data, &frame);

    if (frame.isMasked) {
      unmaskWsPayload(frame.payloadData, frame.payloadLength, frame.maskingKey);
    } else {
      //we are the server, and need to shut down the connection
      //if we receive an unmasked packet
      //      webSocketDebug("frame.isMasked=false closing connection\n");
      closeWsConnection(wsConnection);
      return;
    }

//    webSocketDebug("frame.payloadData-->%s<--\n", frame.payloadData);

    if (frame.opcode == OPCODE_PING) {
      //      webSocketDebug("frame.opcode=OPCODE_PING\n");
      sendWsMessage(wsConnection, frame.payloadData, frame.payloadLength, FLAG_FIN | OPCODE_PONG);
      return;
    }

    if (frame.opcode == OPCODE_CLOSE) {
      //gracefully shut down the connection
      //      webSocketDebug("frame.opcode=OPCODE_CLOSE, closeing connection\n");
      closeWsConnection(wsConnection);
      return;
    }

    if (wsConnection->onMessage != NULL) {
      wsConnection->onMessage(frame.payloadData);
    }
  }
  //  webSocketDebug("Leaving webSocketRecvCb\n");
}
/*The main working flow of this demo:
  a. start mesh function, searching for existing mesh network
  b. if there is no mesh network, search AP cache to connect to a recorded router.
  c. If we still failed to establish a connection, start ESP-TOUCH wait for configure.
  d. If ESP-TOUCH time out, re-search mesh network and AP CACHE.
  e. During the whole procedure,we can control and configure the light via a restful webserver.
  f. ESP-NOW is the recently released function to control the light without any WiFi connection.You can find it in app_switch
*/
void ICACHE_FLASH_ATTR
    light_main_flow()
{
    UART_WaitTxFifoEmpty(0,50000);
    uart_init(74880,74880);
    user_DispAppInfo();

    wifi_set_opmode(STATIONAP_MODE);
#if ESP_MESH_SUPPORT
        wifi_station_set_auto_connect(0);
        wifi_station_disconnect();
#else
        wifi_station_set_auto_connect(1);
#endif
    os_printf("SDK version:%s\n", system_get_sdk_version());

#if AP_CACHE
    wifi_station_ap_number_set(AP_CACHE_NUMBER);
#endif


#if ESP_NOW_SUPPORT
    /*We have added esp-now feature in the light project */
    /*So that the lights in a certain MAC group can be easily controlled by an ESP-NOW controller*/
    /*The sample code is in APP_CONTROLLER/APP_SWITCH*/
    sp_MacInit();//csc add button Mac add and delet
    light_EspnowInit();
#endif

#if 1

#if ESP_PLATFORM
    /*Initialization of the peripheral drivers*/
    /*For light demo , it is user_light_init();*/
    /* Also check whether assigned ip addr by the router.If so, connect to ESP-server  */
    user_esp_platform_init_peripheral();
    disp_heap(5);

#endif
    /*Establish a udp socket to receive local device detect info.*/
    /*Listen to the port 1025, as well as udp broadcast.
    /*If receive a string of device_find_request, it reply its IP address and MAC.*/
    user_devicefind_init();
    disp_heap(6);
    /*Establish a TCP server for http(with JSON) POST or GET command to communicate with the device.*/
    /*You can find the command in "2B-SDK-Espressif IoT Demo.pdf" to see the details.*/
    /*the JSON command for curl is like:*/
    /*3 Channel mode: curl -X POST -H "Content-Type:application/json" -d "{\"period\":1000,\"rgb\":{\"red\":16000,\"green\":16000,\"blue\":16000}}" http://192.168.4.1/config?command=light      */
    /*5 Channel mode: curl -X POST -H "Content-Type:application/json" -d "{\"period\":1000,\"rgb\":{\"red\":16000,\"green\":16000,\"blue\":16000,\"cwhite\":3000,\"wwhite\",3000}}" http://192.168.4.1/config?command=light      */
    /***********NOTE!!**************/
    /*in MESH mode, you need to add "sip","sport" and "mdev_mac" fields to send command to the desired device*/
    /*see details in MESH documentation*/
    /*MESH INTERFACE IS AT PORT 8000*/
#if ESP_WEB_SUPPORT
    //Initialize DNS server for captive portal
    captdnsInit();
    //Initialize espfs containing static webpages
    espFsInit((void*)(webpages_espfs_start));
    //Initialize webserver
    httpdInit(builtInUrls, SERVER_PORT);
    //user_webserver_init(SERVER_PORT);

#else
    #ifdef SERVER_SSL_ENABLE
    user_webserver_init(SERVER_SSL_PORT);
    #else
    user_webserver_init(SERVER_PORT);
    #endif
#endif

#endif

//In debug mode, if you restart the light within 2 seconds, it will get into softap mode and wait for local upgrading firmware.
//Restart again, it will clear the system param and set to default status.
#if ESP_DEBUG_MODE
    extern struct esp_platform_saved_param esp_param;
    if(esp_param.reset_flg == MODE_APMODE){
        os_printf("==================\r\n");
        os_printf("RESET FLG==2,STATIONAP_MODE \r\n");
        os_printf("==================\r\n");
        #if ESP_MESH_SUPPORT
        user_DeviceFindRespSet(false);
        #endif
        
        struct softap_config config_softap;
        char ssid[33]={0};
        
        wifi_softap_get_config(&config_softap);
        os_memset(config_softap.password, 0, sizeof(config_softap.password));
        os_memset(config_softap.ssid, 0, sizeof(config_softap.ssid));
        os_sprintf(ssid,"ESP_%06X",system_get_chip_id());
        os_memcpy(config_softap.ssid, ssid, os_strlen(ssid));
        config_softap.ssid_len = os_strlen(ssid);
        config_softap.authmode = AUTH_OPEN;
        wifi_softap_set_config(&config_softap);
        
        os_printf("SET STATION-AP MODE\r\n");
        wifi_set_opmode(STATIONAP_MODE);
        user_esp_platform_set_reset_flg(MODE_RESET);

        
        #if ESP_WEB_SUPPORT
		    os_printf("WEBSERVER INIT...");
            //Initialize DNS server for captive portal
            captdnsInit();
            //Initialize espfs containing static webpages
            espFsInit((void*)(webpages_espfs_start));
            //Initialize webserver
            httpdInit(builtInUrls, SERVER_PORT);   
        #endif

        os_timer_disarm(&reset_flg_t);
        os_timer_setfn(&reset_flg_t,user_esp_platform_set_reset_flg,MODE_NORMAL);
        os_timer_arm(&reset_flg_t,2000,0);
        user_light_set_duty(0, LIGHT_RED);
        user_light_set_duty(0, LIGHT_GREEN);
        user_light_set_duty(0, LIGHT_BLUE);
        user_light_set_duty(22222, LIGHT_WARM_WHITE);
        user_light_set_duty(22222, LIGHT_COLD_WHITE);
        os_delay_us(5000);
        light_ShowDevLevel(5);
        return;
    }
    
    #if ESP_RESET_DEBUG_EN
    else if(esp_param.reset_flg == MODE_RESET){
        os_printf("==================\r\n");
        os_printf("RESET FLG==1,RESET IN 200 MS \r\n");
        os_printf("==================\r\n");
        user_esp_platform_set_reset_flg(MODE_APMODE);
        os_timer_disarm(&reset_flg_t);
        os_timer_setfn(&reset_flg_t,user_esp_platform_reset_default,0);
        os_timer_arm(&reset_flg_t,200,0);
    }
    else{
        os_printf("==================\r\n");
        os_printf("RESET FLG==0,NORMAL MODE \r\n");
        os_printf("==================\r\n");
        user_esp_platform_set_reset_flg(MODE_APMODE);
        os_timer_disarm(&reset_flg_t);
        os_timer_setfn(&reset_flg_t,user_esp_platform_set_reset_flg,0);
        os_timer_arm(&reset_flg_t,2000,0);
    }
    #endif
#endif

#if ESP_MESH_SUPPORT
    /*initialize mesh network.
      1. search for existing mesh.
      2. if failed , try connecting recorded router.
    */
    user_MeshParamInit();
    user_MeshStart();
#elif ESP_TOUCH_SUPPORT
    esptouch_FlowStart();
#endif
}
Exemple #8
0
/**
 * eap_peer_select_phase2_methods - Select phase 2 EAP method
 * @config: Pointer to the network configuration
 * @prefix: 'phase2' configuration prefix, e.g., "auth="
 * @types: Buffer for returning allocated list of allowed EAP methods
 * @num_types: Buffer for returning number of allocated EAP methods
 * Returns: 0 on success, -1 on failure
 *
 * This function is used to parse EAP method list and select allowed methods
 * for Phase2 authentication.
 */
int eap_peer_select_phase2_methods(struct eap_peer_config *config,
				   const char *prefix,
				   struct eap_method_type **types,
				   size_t *num_types)
{
	char *start, *pos, *buf;
	struct eap_method_type *methods = NULL, *_methods;
	u8 method;
	size_t num_methods = 0, prefix_len;

	if (config == NULL || config->phase2 == NULL)
		goto get_defaults;

	start = buf = os_strdup(config->phase2);
	if (buf == NULL)
		return -1;

	prefix_len = os_strlen(prefix);

	while (start && *start != '\0') {
		int vendor;
		pos = os_strstr(start, prefix);
		if (pos == NULL)
			break;
		if (start != pos && *(pos - 1) != ' ') {
			start = pos + prefix_len;
			continue;
		}

		start = pos + prefix_len;
		pos = os_strchr(start, ' ');
		if (pos)
			*pos++ = '\0';
		method = eap_get_phase2_type(start, &vendor);
		if (vendor == EAP_VENDOR_IETF && method == EAP_TYPE_NONE) {
			wpa_printf(MSG_ERROR, "TLS: Unsupported Phase2 EAP "
				   "method '%s'", start);
		} else {
			num_methods++;
			_methods = os_realloc(methods,
					      num_methods * sizeof(*methods));
			if (_methods == NULL) {
				os_free(methods);
				os_free(buf);
				return -1;
			}
			methods = _methods;
			methods[num_methods - 1].vendor = vendor;
			methods[num_methods - 1].method = method;
		}

		start = pos;
	}

	os_free(buf);

get_defaults:
	if (methods == NULL)
		methods = eap_get_phase2_types(config, &num_methods);

	if (methods == NULL) {
		wpa_printf(MSG_ERROR, "TLS: No Phase2 EAP methods available");
		return -1;
	}
	wpa_hexdump(MSG_DEBUG, "TLS: Phase2 EAP types",
		    (u8 *) methods,
		    num_methods * sizeof(struct eap_method_type));

	*types = methods;
	*num_types = num_methods;

	return 0;
}
/******************************************************************************
 * FunctionName : user_platform_timer_first_start
 * Description  : calculate the wait time of each timer
 * Parameters   : count -- The number of timers given by server
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_platform_timer_first_start(uint16 count)
{
    int i = 0;
    struct esp_platform_wait_timer_param timer_wait_param[100] = {0};

    ESP_DBG("current timestamp= %ds\n", timestamp);

    timestamp = timestamp + min_wait_second;

    for (i = 0 ; i < count ; i++) {
        char *str = timer_splits[i];

        if (indexof(str, "f", 0) == 0) {
            char *fixed_wait[2];

            ESP_DBG("timer is fixed mode\n");

            split(str, "=", fixed_wait);
            os_memcpy(timer_wait_param[i].wait_time_param, fixed_wait[0] + 1, os_strlen(fixed_wait[0]) - 1);
            os_memcpy(timer_wait_param[i].wait_action, fixed_wait[1], os_strlen(fixed_wait[1]));
            timer_wait_param[i].wait_time_second = atoi(timer_wait_param[i].wait_time_param) - timestamp;
            os_free(fixed_wait[0]);
            os_free(fixed_wait[1]);
        }

        else if (indexof(str, "l", 0) == 0) {
            char *loop_wait[2];

            ESP_DBG("timer is loop mode\n");

            split(str, "=", loop_wait);
            os_memcpy(timer_wait_param[i].wait_time_param, loop_wait[0] + 1, os_strlen(loop_wait[0]) - 1);
            os_memcpy(timer_wait_param[i].wait_action, loop_wait[1], os_strlen(loop_wait[1]));
            timer_wait_param[i].wait_time_second = atoi(timer_wait_param[i].wait_time_param) - (timestamp % atoi(timer_wait_param[i].wait_time_param));
            os_free(loop_wait[0]);
            os_free(loop_wait[1]);
        } else if (indexof(str, "w", 0) == 0) {
            char *week_wait[2];
            int monday_wait_time = 0;

            ESP_DBG("timer is weekend mode\n");

            split(str, "=", week_wait);
            os_memcpy(timer_wait_param[i].wait_time_param, week_wait[0] + 1, os_strlen(week_wait[0]) - 1);
            os_memcpy(timer_wait_param[i].wait_action, week_wait[1], os_strlen(week_wait[1]));
            monday_wait_time = (timestamp - 1388937600) % (7 * 24 * 3600);

            ESP_DBG("monday_wait_time == %d", monday_wait_time);

            if (atoi(timer_wait_param[i].wait_time_param) > monday_wait_time) {
                timer_wait_param[i].wait_time_second = atoi(timer_wait_param[i].wait_time_param) - monday_wait_time;
            } else {
                timer_wait_param[i].wait_time_second = 7 * 24 * 3600 - monday_wait_time + atoi(timer_wait_param[i].wait_time_param);
            }

            os_free(week_wait[0]);
            os_free(week_wait[1]);
        }
    }

    esp_platform_find_min_time(timer_wait_param, count);
    if(min_wait_second == 0) {
    	return;
    }

    esp_platform_timer_action(timer_wait_param, count);
}
Exemple #10
0
void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint16_t port) {
	int i;
	if (replyMask == 0) return;

#ifdef MDNS_DEBUG_TX
	Serial.printf("TX: mask:%01X, service:%s, proto:%s, port:%u\n", replyMask, service, proto, port);
#endif


	String instanceName = _instanceName;
	size_t instanceNameLen = instanceName.length();

	String hostName = _hostName;
	size_t hostNameLen = hostName.length();

	char underscore[] = "_";

	// build service name with _
	char serviceName[os_strlen(service) + 2];
	os_strcpy(serviceName, underscore);
	os_strcat(serviceName, service);
	size_t serviceNameLen = os_strlen(serviceName);

	//build proto name with _
	char protoName[5];
	os_strcpy(protoName, underscore);
	os_strcat(protoName, proto);
	size_t protoNameLen = 4;

	//local string
	char localName[] = "local";
	size_t localNameLen = 5;

	//terminator
	char terminator[] = "\0";

	uint8_t answerCount = 0;
	for (i = 0; i<4; i++) {
		if (replyMask & (1 << i)) answerCount++;
	}


	//Write the header
	_conn->flush();
	uint8_t head[12] = {
		0x00, 0x00, //ID = 0
		0x84, 0x00, //Flags = response + authoritative answer
		0x00, 0x00, //Question count
		0x00, answerCount, //Answer count
		0x00, 0x00, //Name server records
		0x00, 0x00, //Additional records
	};
	_conn->append(reinterpret_cast<const char*>(head), 12);

	// PTR Response
	if (replyMask & 0x8) {
		// Send the Name field (ie. "_http._tcp.local")
		_conn->append(reinterpret_cast<const char*>(&serviceNameLen), 1);          // lenght of "_http"
		_conn->append(reinterpret_cast<const char*>(serviceName), serviceNameLen); // "_http"
		_conn->append(reinterpret_cast<const char*>(&protoNameLen), 1);            // lenght of "_tcp"
		_conn->append(reinterpret_cast<const char*>(protoName), protoNameLen);     // "_tcp"
		_conn->append(reinterpret_cast<const char*>(&localNameLen), 1);            // lenght "local"
		_conn->append(reinterpret_cast<const char*>(localName), localNameLen);     // "local"
		_conn->append(reinterpret_cast<const char*>(&terminator), 1);              // terminator

																				   //Send the type, class, ttl and rdata length
		uint8_t ptrDataLen = instanceNameLen + serviceNameLen + protoNameLen + localNameLen + 5; // 5 is four label sizes and the terminator
		uint8_t ptrAttrs[10] = {
			0x00, 0x0c,             //PTR record query
			0x00, 0x01,             //Class IN
			0x00, 0x00, 0x11, 0x94, //TTL 4500
			0x00, ptrDataLen,       //RData length
		};
		_conn->append(reinterpret_cast<const char*>(ptrAttrs), 10);

		//Send the RData (ie. "My IOT device._http._tcp.local")
		_conn->append(reinterpret_cast<const char*>(&instanceNameLen), 1);         // lenght of "My IOT device"
		_conn->append(reinterpret_cast<const char*>(instanceName.c_str()), instanceNameLen);// "My IOT device"
		_conn->append(reinterpret_cast<const char*>(&serviceNameLen), 1);          // lenght of "_http"
		_conn->append(reinterpret_cast<const char*>(serviceName), serviceNameLen); // "_http"
		_conn->append(reinterpret_cast<const char*>(&protoNameLen), 1);            // lenght of "_tcp"
		_conn->append(reinterpret_cast<const char*>(protoName), protoNameLen);     // "_tcp"
		_conn->append(reinterpret_cast<const char*>(&localNameLen), 1);            // lenght "local"
		_conn->append(reinterpret_cast<const char*>(localName), localNameLen);     // "local"
		_conn->append(reinterpret_cast<const char*>(&terminator), 1);              // terminator
	}

	//TXT Responce
	if (replyMask & 0x4) {
		//Send the name field (ie. "My IOT device._http._tcp.local")
		_conn->append(reinterpret_cast<const char*>(&instanceNameLen), 1);         // lenght of "My IOT device"
		_conn->append(reinterpret_cast<const char*>(instanceName.c_str()), instanceNameLen);// "My IOT device"
		_conn->append(reinterpret_cast<const char*>(&serviceNameLen), 1);          // lenght of "_http"
		_conn->append(reinterpret_cast<const char*>(serviceName), serviceNameLen); // "_http"
		_conn->append(reinterpret_cast<const char*>(&protoNameLen), 1);            // lenght of "_tcp"
		_conn->append(reinterpret_cast<const char*>(protoName), protoNameLen);     // "_tcp"
		_conn->append(reinterpret_cast<const char*>(&localNameLen), 1);            // lenght "local"
		_conn->append(reinterpret_cast<const char*>(localName), localNameLen);     // "local"
		_conn->append(reinterpret_cast<const char*>(&terminator), 1);              // terminator

																				   //Send the type, class, ttl and rdata length
		uint8_t txtDataLen = _getServiceTxtLen(service, proto);
		uint8_t txtAttrs[10] = {
			0x00, 0x10,             //TXT record query
			0x00, 0x01,             //Class IN
			0x00, 0x00, 0x11, 0x94, //TTL 4500
			0x00, txtDataLen,       //RData length
		};
		_conn->append(reinterpret_cast<const char*>(txtAttrs), 10);

		//Send the RData
		MDNSTxt * txtPtr = _getServiceTxt(service, proto);
		while (txtPtr != 0) {
			uint8_t txtLen = txtPtr->_txt.length();
			_conn->append(reinterpret_cast<const char*>(&txtLen), 1);                  // lenght of txt
			_conn->append(reinterpret_cast<const char*>(txtPtr->_txt.c_str()), txtLen);// the txt
			txtPtr = txtPtr->_next;
		}
	}


	//SRV Responce
	if (replyMask & 0x2) {
		//Send the name field (ie. "My IOT device._http._tcp.local")
		_conn->append(reinterpret_cast<const char*>(&instanceNameLen), 1);         // lenght of "My IOT device"
		_conn->append(reinterpret_cast<const char*>(instanceName.c_str()), instanceNameLen);// "My IOT device"
		_conn->append(reinterpret_cast<const char*>(&serviceNameLen), 1);          // lenght of "_http"
		_conn->append(reinterpret_cast<const char*>(serviceName), serviceNameLen); // "_http"
		_conn->append(reinterpret_cast<const char*>(&protoNameLen), 1);            // lenght of "_tcp"
		_conn->append(reinterpret_cast<const char*>(protoName), protoNameLen);     // "_tcp"
		_conn->append(reinterpret_cast<const char*>(&localNameLen), 1);            // lenght "local"
		_conn->append(reinterpret_cast<const char*>(localName), localNameLen);     // "local"
		_conn->append(reinterpret_cast<const char*>(&terminator), 1);              // terminator

																				   //Send the type, class, ttl, rdata length, priority and weight
		uint8_t srvDataSize = hostNameLen + localNameLen + 3; // 3 is 2 lable size bytes and the terminator
		srvDataSize += 6; // Size of Priority, weight and port
		uint8_t srvAttrs[10] = {
			0x00, 0x21,             //Type SRV
			0x80, 0x01,             //Class IN, with cache flush
			0x00, 0x00, 0x00, 0x78, //TTL 120
			0x00, srvDataSize,      //RData length
		};
		_conn->append(reinterpret_cast<const char*>(srvAttrs), 10);

		//Send the RData Priority weight and port
		uint8_t srvRData[6] = {
			0x00, 0x00,             //Priority 0
			0x00, 0x00,             //Weight 0
			(uint8_t)((port >> 8) & 0xFF), (uint8_t)(port & 0xFF)
		};
		_conn->append(reinterpret_cast<const char*>(srvRData), 6);
		//Send the RData (ie. "esp8266.local")
		_conn->append(reinterpret_cast<const char*>(&hostNameLen), 1);             // lenght of "esp8266"
		_conn->append(reinterpret_cast<const char*>(hostName.c_str()), hostNameLen);// "esp8266"
		_conn->append(reinterpret_cast<const char*>(&localNameLen), 1);            // lenght "local"
		_conn->append(reinterpret_cast<const char*>(localName), localNameLen);     // "local"
		_conn->append(reinterpret_cast<const char*>(&terminator), 1);              // terminator

	}

	// A Response
	if (replyMask & 0x1) {
		//Send the RData (ie. "esp8266.local")
		_conn->append(reinterpret_cast<const char*>(&hostNameLen), 1);             // lenght of "esp8266"
		_conn->append(reinterpret_cast<const char*>(hostName.c_str()), hostNameLen);// "esp8266"
		_conn->append(reinterpret_cast<const char*>(&localNameLen), 1);            // lenght "local"
		_conn->append(reinterpret_cast<const char*>(localName), localNameLen);     // "local"
		_conn->append(reinterpret_cast<const char*>(&terminator), 1);              // terminator

		uint32_t ip = _getOurIp();
		uint8_t aaaAttrs[10] = {
			0x00, 0x01,             //TYPE A
			0x80, 0x01,             //Class IN, with cache flush
			0x00, 0x00, 0x00, 0x78, //TTL 120
			0x00, 0x04,             //DATA LEN
		};
		_conn->append(reinterpret_cast<const char*>(aaaAttrs), 10);

		// Send RData
		uint8_t aaaRData[4] = {
			(uint8_t)(ip & 0xFF),         //IP first octet 
			(uint8_t)((ip >> 8) & 0xFF),  //IP second octet
			(uint8_t)((ip >> 16) & 0xFF), //IP third octet
			(uint8_t)((ip >> 24) & 0xFF)  //IP fourth octet
		};
		_conn->append(reinterpret_cast<const char*>(aaaRData), 4);
	}
static int hostapd_config_read_wpa_psk(const char *fname,
				       struct hostapd_ssid *ssid)
{
	FILE *f;
	char buf[128], *pos;
	int line = 0, ret = 0, len, ok;
	u8 addr[ETH_ALEN];
	struct hostapd_wpa_psk *psk;

	if (!fname)
		return 0;

	f = fopen(fname, "r");
	if (!f) {
		wpa_printf(MSG_ERROR, "WPA PSK file '%s' not found.", fname);
		return -1;
	}

	while (fgets(buf, sizeof(buf), f)) {
		line++;

		if (buf[0] == '#')
			continue;
		pos = buf;
		while (*pos != '\0') {
			if (*pos == '\n') {
				*pos = '\0';
				break;
			}
			pos++;
		}
		if (buf[0] == '\0')
			continue;

		if (hwaddr_aton(buf, addr)) {
			wpa_printf(MSG_ERROR, "Invalid MAC address '%s' on "
				   "line %d in '%s'", buf, line, fname);
			ret = -1;
			break;
		}

		psk = os_zalloc(sizeof(*psk));
		if (psk == NULL) {
			wpa_printf(MSG_ERROR, "WPA PSK allocation failed");
			ret = -1;
			break;
		}
		if (is_zero_ether_addr(addr))
			psk->group = 1;
		else
			os_memcpy(psk->addr, addr, ETH_ALEN);

		pos = buf + 17;
		if (*pos == '\0') {
			wpa_printf(MSG_ERROR, "No PSK on line %d in '%s'",
				   line, fname);
			os_free(psk);
			ret = -1;
			break;
		}
		pos++;

		ok = 0;
		len = os_strlen(pos);
		if (len == 64 && hexstr2bin(pos, psk->psk, PMK_LEN) == 0)
			ok = 1;
		else if (len >= 8 && len < 64) {
			pbkdf2_sha1(pos, ssid->ssid, ssid->ssid_len,
				    4096, psk->psk, PMK_LEN);
			ok = 1;
		}
		if (!ok) {
			wpa_printf(MSG_ERROR, "Invalid PSK '%s' on line %d in "
				   "'%s'", pos, line, fname);
			os_free(psk);
			ret = -1;
			break;
		}

		psk->next = ssid->wpa_psk;
		ssid->wpa_psk = psk;
	}

	fclose(f);

	return ret;
}
Exemple #12
0
int MDNSResponder::queryService(char *service, char *proto) {
#ifdef MDNS_DEBUG_TX
	Serial.printf("queryService %s %s\n", service, proto);
#endif  

	if (_query != 0) {
		os_free(_query);
		_query = 0;
	}
	_query = (struct MDNSQuery*)(os_malloc(sizeof(struct MDNSQuery)));
	os_strcpy(_query->_service, service);
	os_strcpy(_query->_proto, proto);
	_newQuery = true;

	char underscore[] = "_";

	// build service name with _
	char serviceName[os_strlen(service) + 2];
	os_strcpy(serviceName, underscore);
	os_strcat(serviceName, service);
	size_t serviceNameLen = os_strlen(serviceName);

	//build proto name with _
	char protoName[5];
	os_strcpy(protoName, underscore);
	os_strcat(protoName, proto);
	size_t protoNameLen = 4;

	//local string
	char localName[] = "local";
	size_t localNameLen = 5;

	//terminator
	char terminator[] = "\0";

	// Only supports sending one PTR query
	uint8_t questionCount = 1;

	// Write the header
	_conn->flush();
	uint8_t head[12] = {
		0x00, 0x00, //ID = 0
		0x00, 0x00, //Flags = response + authoritative answer
		0x00, questionCount, //Question count
		0x00, 0x00, //Answer count
		0x00, 0x00, //Name server records
		0x00, 0x00 //Additional records
	};
	_conn->append(reinterpret_cast<const char*>(head), 12);

	// Only supports sending one PTR query
	// Send the Name field (eg. "_http._tcp.local")
	_conn->append(reinterpret_cast<const char*>(&serviceNameLen), 1);          // lenght of "_" + service
	_conn->append(reinterpret_cast<const char*>(serviceName), serviceNameLen); // "_" + service
	_conn->append(reinterpret_cast<const char*>(&protoNameLen), 1);            // lenght of "_" + proto
	_conn->append(reinterpret_cast<const char*>(protoName), protoNameLen);     // "_" + proto
	_conn->append(reinterpret_cast<const char*>(&localNameLen), 1);            // lenght of "local"
	_conn->append(reinterpret_cast<const char*>(localName), localNameLen);     // "local"
	_conn->append(reinterpret_cast<const char*>(&terminator), 1);              // terminator

																			   //Send the type and class
	uint8_t ptrAttrs[4] = {
		0x00, 0x0c, //PTR record query
		0x00, 0x01 //Class IN
	};
	_conn->append(reinterpret_cast<const char*>(ptrAttrs), 4);
	_waitingForAnswers = true;
	_conn->send();

#ifdef MDNS_DEBUG_TX
	Serial.println("Waiting for answers..");
#endif
	delay(1000);

	_waitingForAnswers = false;

	return _getNumAnswers();
}
Exemple #13
0
static void eap_sim_db_aka_resp_auth(struct eap_sim_db_data *data,
				     const char *imsi, char *buf)
{
	char *start, *end;
	struct eap_sim_db_pending *entry;

	/*
	 * AKA-RESP-AUTH <IMSI> <RAND> <AUTN> <IK> <CK> <RES>
	 * AKA-RESP-AUTH <IMSI> FAILURE
	 * (IMSI = ASCII string, RAND/AUTN/IK/CK/RES = hex string)
	 */

	entry = eap_sim_db_get_pending(data, (u8 *) imsi, os_strlen(imsi), 1);
	if (entry == NULL) {
		asd_printf(ASD_DEFAULT,MSG_DEBUG, "EAP-SIM DB: No pending entry for the "
			   "received message found");
		return;
	}

	start = buf;
	if (os_strncmp(start, "FAILURE", 7) == 0) {
		asd_printf(ASD_DEFAULT,MSG_DEBUG, "EAP-SIM DB: External server reported "
			   "failure");
		entry->state = FAILURE;
		eap_sim_db_add_pending(data, entry);
		data->get_complete_cb(data->ctx, entry->cb_session_ctx);
		return;
	}

	end = os_strchr(start, ' ');
	if (end == NULL)
		goto parse_fail;
	*end = '\0';
	if (hexstr2bin(start, entry->u.aka.rand, EAP_AKA_RAND_LEN))
		goto parse_fail;

	start = end + 1;
	end = os_strchr(start, ' ');
	if (end == NULL)
		goto parse_fail;
	*end = '\0';
	if (hexstr2bin(start, entry->u.aka.autn, EAP_AKA_AUTN_LEN))
		goto parse_fail;

	start = end + 1;
	end = os_strchr(start, ' ');
	if (end == NULL)
		goto parse_fail;
	*end = '\0';
	if (hexstr2bin(start, entry->u.aka.ik, EAP_AKA_IK_LEN))
		goto parse_fail;

	start = end + 1;
	end = os_strchr(start, ' ');
	if (end == NULL)
		goto parse_fail;
	*end = '\0';
	if (hexstr2bin(start, entry->u.aka.ck, EAP_AKA_CK_LEN))
		goto parse_fail;

	start = end + 1;
	end = os_strchr(start, ' ');
	if (end)
		*end = '\0';
	else {
		end = start;
		while (*end)
			end++;
	}
	entry->u.aka.res_len = (end - start) / 2;
	if (entry->u.aka.res_len > EAP_AKA_RES_MAX_LEN) {
		asd_printf(ASD_DEFAULT,MSG_DEBUG, "EAP-SIM DB: Too long RES");
		entry->u.aka.res_len = 0;
		goto parse_fail;
	}
	if (hexstr2bin(start, entry->u.aka.res, entry->u.aka.res_len))
		goto parse_fail;

	entry->state = SUCCESS;
	asd_printf(ASD_DEFAULT,MSG_DEBUG, "EAP-SIM DB: Authentication data parsed "
		   "successfully - callback");
	eap_sim_db_add_pending(data, entry);
	data->get_complete_cb(data->ctx, entry->cb_session_ctx);
	return;

parse_fail:
	asd_printf(ASD_DEFAULT,MSG_DEBUG, "EAP-SIM DB: Failed to parse response string");
	os_free(entry);
}
Exemple #14
0
static void eap_sim_db_sim_resp_auth(struct eap_sim_db_data *data,
				     const char *imsi, char *buf)
{
	char *start, *end, *pos;
	struct eap_sim_db_pending *entry;
	int num_chal;

	/*
	 * SIM-RESP-AUTH <IMSI> Kc(i):SRES(i):RAND(i) ...
	 * SIM-RESP-AUTH <IMSI> FAILURE
	 * (IMSI = ASCII string, Kc/SRES/RAND = hex string)
	 */

	entry = eap_sim_db_get_pending(data, (u8 *) imsi, os_strlen(imsi), 0);
	if (entry == NULL) {
		asd_printf(ASD_DEFAULT,MSG_DEBUG, "EAP-SIM DB: No pending entry for the "
			   "received message found");
		return;
	}

	start = buf;
	if (os_strncmp(start, "FAILURE", 7) == 0) {
		asd_printf(ASD_DEFAULT,MSG_DEBUG, "EAP-SIM DB: External server reported "
			   "failure");
		entry->state = FAILURE;
		eap_sim_db_add_pending(data, entry);
		data->get_complete_cb(data->ctx, entry->cb_session_ctx);
		return;
	}

	num_chal = 0;
	while (num_chal < EAP_SIM_MAX_CHAL) {
		end = os_strchr(start, ' ');
		if (end)
			*end = '\0';

		pos = os_strchr(start, ':');
		if (pos == NULL)
			goto parse_fail;
		*pos = '\0';
		if (hexstr2bin(start, entry->u.sim.kc[num_chal],
			       EAP_SIM_KC_LEN))
			goto parse_fail;

		start = pos + 1;
		pos = os_strchr(start, ':');
		if (pos == NULL)
			goto parse_fail;
		*pos = '\0';
		if (hexstr2bin(start, entry->u.sim.sres[num_chal],
			       EAP_SIM_SRES_LEN))
			goto parse_fail;

		start = pos + 1;
		if (hexstr2bin(start, entry->u.sim.rand[num_chal],
			       GSM_RAND_LEN))
			goto parse_fail;

		num_chal++;
		if (end == NULL)
			break;
		else
			start = end + 1;
	}
	entry->u.sim.num_chal = num_chal;

	entry->state = SUCCESS;
	asd_printf(ASD_DEFAULT,MSG_DEBUG, "EAP-SIM DB: Authentication data parsed "
		   "successfully - callback");
	eap_sim_db_add_pending(data, entry);
	data->get_complete_cb(data->ctx, entry->cb_session_ctx);
	return;

parse_fail:
	asd_printf(ASD_DEFAULT,MSG_DEBUG, "EAP-SIM DB: Failed to parse response string");
	os_free(entry);
}
/**
 * eap_sim_db_get_aka_auth - Get AKA authentication values
 * @data: Private data pointer from eap_sim_db_init()
 * @username: Permanent username (prefix | IMSI)
 * @_rand: Buffer for RAND value
 * @autn: Buffer for AUTN value
 * @ik: Buffer for IK value
 * @ck: Buffer for CK value
 * @res: Buffer for RES value
 * @res_len: Buffer for RES length
 * @cb_session_ctx: Session callback context for get_complete_cb()
 * Returns: 0 on success, -1 (EAP_SIM_DB_FAILURE) on error (e.g., user not
 * found), or -2 (EAP_SIM_DB_PENDING) if results are not yet available. In this
 * case, the callback function registered with eap_sim_db_init() will be
 * called once the results become available.
 *
 * When using an external server for AKA authentication, this function can
 * always start a request and return EAP_SIM_DB_PENDING immediately if
 * authentication triplets are not available. Once the authentication data are
 * received, callback function registered with eap_sim_db_init() is called to
 * notify EAP state machine to reprocess the message. This
 * eap_sim_db_get_aka_auth() function will then be called again and the newly
 * received triplets will then be given to the caller.
 */
int eap_sim_db_get_aka_auth(struct eap_sim_db_data *data, const char *username,
                            u8 *_rand, u8 *autn, u8 *ik, u8 *ck,
                            u8 *res, size_t *res_len, void *cb_session_ctx)
{
    struct eap_sim_db_pending *entry;
    int len;
    char msg[40];
    const char *imsi;
    size_t imsi_len;

    if (username == NULL ||
            (username[0] != EAP_AKA_PERMANENT_PREFIX &&
             username[0] != EAP_AKA_PRIME_PERMANENT_PREFIX) ||
            username[1] == '\0' || os_strlen(username) > sizeof(entry->imsi)) {
        wpa_printf(MSG_DEBUG, "EAP-SIM DB: unexpected username '%s'",
                   username);
        return EAP_SIM_DB_FAILURE;
    }
    imsi = username + 1;
    wpa_printf(MSG_DEBUG, "EAP-SIM DB: Get AKA auth for IMSI '%s'",
               imsi);

    entry = eap_sim_db_get_pending(data, imsi, 1);
    if (entry) {
        if (entry->state == FAILURE) {
            os_free(entry);
            wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failure");
            return EAP_SIM_DB_FAILURE;
        }

        if (entry->state == PENDING) {
            eap_sim_db_add_pending(data, entry);
            wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending");
            return EAP_SIM_DB_PENDING;
        }

        wpa_printf(MSG_DEBUG, "EAP-SIM DB: Returning successfully "
                   "received authentication data");
        os_memcpy(_rand, entry->u.aka.rand, EAP_AKA_RAND_LEN);
        os_memcpy(autn, entry->u.aka.autn, EAP_AKA_AUTN_LEN);
        os_memcpy(ik, entry->u.aka.ik, EAP_AKA_IK_LEN);
        os_memcpy(ck, entry->u.aka.ck, EAP_AKA_CK_LEN);
        os_memcpy(res, entry->u.aka.res, EAP_AKA_RES_MAX_LEN);
        *res_len = entry->u.aka.res_len;
        os_free(entry);
        return 0;
    }

    if (data->sock < 0) {
        if (eap_sim_db_open_socket(data) < 0)
            return EAP_SIM_DB_FAILURE;
    }

    imsi_len = os_strlen(imsi);
    len = os_snprintf(msg, sizeof(msg), "AKA-REQ-AUTH ");
    if (len < 0 || len + imsi_len >= sizeof(msg))
        return EAP_SIM_DB_FAILURE;
    os_memcpy(msg + len, imsi, imsi_len);
    len += imsi_len;

    wpa_printf(MSG_DEBUG, "EAP-SIM DB: requesting AKA authentication "
               "data for IMSI '%s'", imsi);
    if (eap_sim_db_send(data, msg, len) < 0)
        return EAP_SIM_DB_FAILURE;

    entry = os_zalloc(sizeof(*entry));
    if (entry == NULL)
        return EAP_SIM_DB_FAILURE;

    os_get_time(&entry->timestamp);
    entry->aka = 1;
    os_strlcpy(entry->imsi, imsi, sizeof(entry->imsi));
    entry->cb_session_ctx = cb_session_ctx;
    entry->state = PENDING;
    eap_sim_db_add_pending(data, entry);
    eap_sim_db_expire_pending(data);

    return EAP_SIM_DB_PENDING;
}
/******************************************************************************
 * FunctionName : user_platform_timer_start
 * Description  : Processing the message about timer from the server
 * Parameters   : timer_wait_param -- The received data from the server
 *                count -- the espconn used to connetion with the host
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
esp_platform_timer_action(struct esp_platform_wait_timer_param *timer_wait_param, uint16 count)
{
    uint16 i = 0;
    uint16 action_number;
    struct wait_param pwait_action = {0};

    pwait_action.count = count;
    action_number = 0;

    for (i = 0; i < count ; i++) {
        if (timer_wait_param[i].wait_time_second == min_wait_second) {
            os_memcpy(pwait_action.action[action_number], timer_wait_param[i].wait_action, os_strlen(timer_wait_param[i].wait_action));
            ESP_DBG("*****%s*****\n", timer_wait_param[i].wait_action);
            action_number++;
        }
    }

    pwait_action.action_number = action_number;
    pwait_action.min_time_backup = min_wait_second;
    user_esp_platform_wait_time_overflow_check(&pwait_action);
}
/**
 * eap_sim_db_get_gsm_triplets - Get GSM triplets
 * @data: Private data pointer from eap_sim_db_init()
 * @username: Permanent username (prefix | IMSI)
 * @max_chal: Maximum number of triplets
 * @_rand: Buffer for RAND values
 * @kc: Buffer for Kc values
 * @sres: Buffer for SRES values
 * @cb_session_ctx: Session callback context for get_complete_cb()
 * Returns: Number of triplets received (has to be less than or equal to
 * max_chal), -1 (EAP_SIM_DB_FAILURE) on error (e.g., user not found), or
 * -2 (EAP_SIM_DB_PENDING) if results are not yet available. In this case, the
 * callback function registered with eap_sim_db_init() will be called once the
 * results become available.
 *
 * When using an external server for GSM triplets, this function can always
 * start a request and return EAP_SIM_DB_PENDING immediately if authentication
 * triplets are not available. Once the triplets are received, callback
 * function registered with eap_sim_db_init() is called to notify EAP state
 * machine to reprocess the message. This eap_sim_db_get_gsm_triplets()
 * function will then be called again and the newly received triplets will then
 * be given to the caller.
 */
int eap_sim_db_get_gsm_triplets(struct eap_sim_db_data *data,
                                const char *username, int max_chal,
                                u8 *_rand, u8 *kc, u8 *sres,
                                void *cb_session_ctx)
{
    struct eap_sim_db_pending *entry;
    int len, ret;
    char msg[40];
    const char *imsi;
    size_t imsi_len;

    if (username == NULL || username[0] != EAP_SIM_PERMANENT_PREFIX ||
            username[1] == '\0' || os_strlen(username) > sizeof(entry->imsi)) {
        wpa_printf(MSG_DEBUG, "EAP-SIM DB: unexpected username '%s'",
                   username);
        return EAP_SIM_DB_FAILURE;
    }
    imsi = username + 1;
    wpa_printf(MSG_DEBUG, "EAP-SIM DB: Get GSM triplets for IMSI '%s'",
               imsi);

    entry = eap_sim_db_get_pending(data, imsi, 0);
    if (entry) {
        int num_chal;
        if (entry->state == FAILURE) {
            wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> "
                       "failure");
            os_free(entry);
            return EAP_SIM_DB_FAILURE;
        }

        if (entry->state == PENDING) {
            wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> "
                       "still pending");
            eap_sim_db_add_pending(data, entry);
            return EAP_SIM_DB_PENDING;
        }

        wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> "
                   "%d challenges", entry->u.sim.num_chal);
        num_chal = entry->u.sim.num_chal;
        if (num_chal > max_chal)
            num_chal = max_chal;
        os_memcpy(_rand, entry->u.sim.rand, num_chal * GSM_RAND_LEN);
        os_memcpy(sres, entry->u.sim.sres,
                  num_chal * EAP_SIM_SRES_LEN);
        os_memcpy(kc, entry->u.sim.kc, num_chal * EAP_SIM_KC_LEN);
        os_free(entry);
        return num_chal;
    }

    if (data->sock < 0) {
        if (eap_sim_db_open_socket(data) < 0)
            return EAP_SIM_DB_FAILURE;
    }

    imsi_len = os_strlen(imsi);
    len = os_snprintf(msg, sizeof(msg), "SIM-REQ-AUTH ");
    if (len < 0 || len + imsi_len >= sizeof(msg))
        return EAP_SIM_DB_FAILURE;
    os_memcpy(msg + len, imsi, imsi_len);
    len += imsi_len;
    ret = os_snprintf(msg + len, sizeof(msg) - len, " %d", max_chal);
    if (ret < 0 || (size_t) ret >= sizeof(msg) - len)
        return EAP_SIM_DB_FAILURE;
    len += ret;

    wpa_printf(MSG_DEBUG, "EAP-SIM DB: requesting SIM authentication "
               "data for IMSI '%s'", imsi);
    if (eap_sim_db_send(data, msg, len) < 0)
        return EAP_SIM_DB_FAILURE;

    entry = os_zalloc(sizeof(*entry));
    if (entry == NULL)
        return EAP_SIM_DB_FAILURE;

    os_get_time(&entry->timestamp);
    os_strlcpy(entry->imsi, imsi, sizeof(entry->imsi));
    entry->cb_session_ctx = cb_session_ctx;
    entry->state = PENDING;
    eap_sim_db_add_pending(data, entry);
    eap_sim_db_expire_pending(data);

    return EAP_SIM_DB_PENDING;
}
Exemple #18
0
LOCAL ICACHE_FLASH_ATTR
char *save_data(char *precv, uint16 length) {
	LOCAL char *precvbuffer;
	LOCAL uint32 dat_sumlength = 0;
	LOCAL uint32 totallength = 0;

	bool flag = false;
	char length_buf[10] = {0};
	char *ptemp = NULL;
	char *pdata = NULL;
	uint16 headlength = 0;

	ptemp = (char *)os_strstr(precv, "\r\n\r\n");

	if (ptemp != NULL) {
		length -= ptemp - precv;
		length -= 4;
		totallength += length;
		headlength = ptemp - precv + 4;
		pdata = (char *)os_strstr(precv, "Content-Length: ");

		if (pdata != NULL) {
			pdata += 16;
			precvbuffer = (char *)os_strstr(pdata, "\r\n");

			if (precvbuffer != NULL) {
				os_memcpy(length_buf, pdata, precvbuffer - pdata);
				dat_sumlength = atoi(length_buf);
			}
		} else {
			if (totallength != 0x00) {
				totallength = 0;
				dat_sumlength = 0;
				return NULL;
			}
		}
		if ((dat_sumlength + headlength) >= 1024) {
			precvbuffer = (char *)os_zalloc(headlength + 1);
			os_memcpy(precvbuffer, precv, headlength + 1);
		} else {
			precvbuffer = (char *)os_zalloc(dat_sumlength + headlength + 1);
			os_memcpy(precvbuffer, precv, os_strlen(precv));
		}
	} else {
		if (precvbuffer != NULL) {
			totallength += length;
			os_memcpy(precvbuffer + os_strlen(precvbuffer), precv, length);
		} else {
			totallength = 0;
			dat_sumlength = 0;
			return NULL;
		}
	}

	if (totallength == dat_sumlength) {
		totallength = 0;
		dat_sumlength = 0;
		return precvbuffer;
	} else {
		return NULL;
	}
}
Exemple #19
0
static VOID IpcEvent_SendMessageToChild(IpcEvent_t* pIpcEvent, PS8 msg)
{
    write(pIpcEvent->pipe_to_child, msg, os_strlen(msg));
}
static int wpa_driver_privsep_set_param(void *priv, const char *param)
{
	struct wpa_driver_privsep_data *drv = priv;
	const char *pos;
	char *own_dir, *priv_dir;
	static unsigned int counter = 0;
	size_t len;
	struct sockaddr_un addr;

	wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param);
	if (param == NULL)
		pos = NULL;
	else
		pos = os_strstr(param, "own_dir=");
	if (pos) {
		char *end;
		own_dir = os_strdup(pos + 8);
		if (own_dir == NULL)
			return -1;
		end = os_strchr(own_dir, ' ');
		if (end)
			*end = '\0';
	} else {
		own_dir = os_strdup("/tmp");
		if (own_dir == NULL)
			return -1;
	}

	if (param == NULL)
		pos = NULL;
	else
		pos = os_strstr(param, "priv_dir=");
	if (pos) {
		char *end;
		priv_dir = os_strdup(pos + 9);
		if (priv_dir == NULL) {
			os_free(own_dir);
			return -1;
		}
		end = os_strchr(priv_dir, ' ');
		if (end)
			*end = '\0';
	} else {
		priv_dir = os_strdup("/var/run/wpa_priv");
		if (priv_dir == NULL) {
			os_free(own_dir);
			return -1;
		}
	}

	len = os_strlen(own_dir) + 50;
	drv->own_socket_path = os_malloc(len);
	if (drv->own_socket_path == NULL) {
		os_free(priv_dir);
		os_free(own_dir);
		return -1;
	}
	os_snprintf(drv->own_socket_path, len, "%s/wpa_privsep-%d-%d",
		    own_dir, getpid(), counter++);

	len = os_strlen(own_dir) + 50;
	drv->own_cmd_path = os_malloc(len);
	if (drv->own_cmd_path == NULL) {
		os_free(drv->own_socket_path);
		drv->own_socket_path = NULL;
		os_free(priv_dir);
		os_free(own_dir);
		return -1;
	}
	os_snprintf(drv->own_cmd_path, len, "%s/wpa_privsep-%d-%d",
		    own_dir, getpid(), counter++);

	os_free(own_dir);

	drv->priv_addr.sun_family = AF_UNIX;
	os_snprintf(drv->priv_addr.sun_path, sizeof(drv->priv_addr.sun_path),
		    "%s/%s", priv_dir, drv->ifname);
	os_free(priv_dir);

	drv->priv_socket = socket(PF_UNIX, SOCK_DGRAM, 0);
	if (drv->priv_socket < 0) {
		perror("socket(PF_UNIX)");
		os_free(drv->own_socket_path);
		drv->own_socket_path = NULL;
		return -1;
	}

	os_memset(&addr, 0, sizeof(addr));
	addr.sun_family = AF_UNIX;
	os_strlcpy(addr.sun_path, drv->own_socket_path, sizeof(addr.sun_path));
	if (bind(drv->priv_socket, (struct sockaddr *) &addr, sizeof(addr)) <
	    0) {
		perror("bind(PF_UNIX)");
		close(drv->priv_socket);
		drv->priv_socket = -1;
		unlink(drv->own_socket_path);
		os_free(drv->own_socket_path);
		drv->own_socket_path = NULL;
		return -1;
	}

	eloop_register_read_sock(drv->priv_socket, wpa_driver_privsep_receive,
				 drv, NULL);

	drv->cmd_socket = socket(PF_UNIX, SOCK_DGRAM, 0);
	if (drv->cmd_socket < 0) {
		perror("socket(PF_UNIX)");
		os_free(drv->own_cmd_path);
		drv->own_cmd_path = NULL;
		return -1;
	}

	os_memset(&addr, 0, sizeof(addr));
	addr.sun_family = AF_UNIX;
	os_strlcpy(addr.sun_path, drv->own_cmd_path, sizeof(addr.sun_path));
	if (bind(drv->cmd_socket, (struct sockaddr *) &addr, sizeof(addr)) < 0)
	{
		perror("bind(PF_UNIX)");
		close(drv->cmd_socket);
		drv->cmd_socket = -1;
		unlink(drv->own_cmd_path);
		os_free(drv->own_cmd_path);
		drv->own_cmd_path = NULL;
		return -1;
	}

	if (wpa_priv_reg_cmd(drv, PRIVSEP_CMD_REGISTER) < 0) {
		wpa_printf(MSG_ERROR, "Failed to register with wpa_priv");
		return -1;
	}

	return 0;
}
Exemple #21
0
static struct wpa_priv_interface *
wpa_priv_interface_init(void *ctx, const char *dir, const char *params)
{
	struct wpa_priv_interface *iface;
	char *pos;
	size_t len;
	struct sockaddr_un addr;
	int i;

	pos = os_strchr(params, ':');
	if (pos == NULL)
		return NULL;

	iface = os_zalloc(sizeof(*iface));
	if (iface == NULL)
		return NULL;
	iface->fd = -1;
	iface->ctx = ctx;

	len = pos - params;
	iface->driver_name = dup_binstr(params, len);
	if (iface->driver_name == NULL) {
		wpa_priv_interface_deinit(iface);
		return NULL;
	}

	for (i = 0; wpa_drivers[i]; i++) {
		if (os_strcmp(iface->driver_name,
			      wpa_drivers[i]->name) == 0) {
			iface->driver = wpa_drivers[i];
			break;
		}
	}
	if (iface->driver == NULL) {
		wpa_printf(MSG_ERROR, "Unsupported driver '%s'",
			   iface->driver_name);
		wpa_priv_interface_deinit(iface);
		return NULL;
	}

	pos++;
	iface->ifname = os_strdup(pos);
	if (iface->ifname == NULL) {
		wpa_priv_interface_deinit(iface);
		return NULL;
	}

	len = os_strlen(dir) + 1 + os_strlen(iface->ifname);
	iface->sock_name = os_malloc(len + 1);
	if (iface->sock_name == NULL) {
		wpa_priv_interface_deinit(iface);
		return NULL;
	}

	os_snprintf(iface->sock_name, len + 1, "%s/%s", dir, iface->ifname);
	if (os_strlen(iface->sock_name) >= sizeof(addr.sun_path)) {
		wpa_priv_interface_deinit(iface);
		return NULL;
	}

	iface->fd = socket(PF_UNIX, SOCK_DGRAM, 0);
	if (iface->fd < 0) {
		wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno));
		wpa_priv_interface_deinit(iface);
		return NULL;
	}

	os_memset(&addr, 0, sizeof(addr));
	addr.sun_family = AF_UNIX;
	os_strlcpy(addr.sun_path, iface->sock_name, sizeof(addr.sun_path));

	if (bind(iface->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		wpa_printf(MSG_DEBUG, "bind(PF_UNIX) failed: %s",
			   strerror(errno));
		if (connect(iface->fd, (struct sockaddr *) &addr,
			    sizeof(addr)) < 0) {
			wpa_printf(MSG_DEBUG, "Socket exists, but does not "
				   "allow connections - assuming it was "
				   "leftover from forced program termination");
			if (unlink(iface->sock_name) < 0) {
				wpa_printf(MSG_ERROR,
					   "Could not unlink existing ctrl_iface socket '%s': %s",
					   iface->sock_name, strerror(errno));
				goto fail;
			}
			if (bind(iface->fd, (struct sockaddr *) &addr,
				 sizeof(addr)) < 0) {
				wpa_printf(MSG_ERROR,
					   "wpa-priv-iface-init: bind(PF_UNIX): %s",
					   strerror(errno));
				goto fail;
			}
			wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
				   "socket '%s'", iface->sock_name);
		} else {
			wpa_printf(MSG_INFO, "Socket exists and seems to be "
				   "in use - cannot override it");
			wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
				   "not used anymore", iface->sock_name);
			goto fail;
		}
	}

	if (chmod(iface->sock_name, S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
		wpa_printf(MSG_ERROR, "chmod: %s", strerror(errno));
		goto fail;
	}

	eloop_register_read_sock(iface->fd, wpa_priv_receive, iface, NULL);

	return iface;

fail:
	wpa_priv_interface_deinit(iface);
	return NULL;
}
S32 WpaCore_SetSsid(THandle hWpaCore, OS_802_11_SSID* ssid, TMacAddr bssid)
{
	TWpaCore* pWpaCore = (TWpaCore*)hWpaCore;
    S8  cmd[256];
    S8  Resp[IPC_WPA_RESP_MAX_LEN];
    PS8 pRespTemp;
	U32 RespLen;
	U32 NetworkID;
	U32 SendCommand;
    U8  Len;
   
#define WPACORE_SETSSID_FAIL \
	os_error_printf(CU_MSG_ERROR, (PS8)"Failed to connect to %s\n", ssid->Ssid); \
    return ECUERR_WPA_CORE_ERROR_FAILED_CONNECT_SSID;

    /* First Add a new network block*/
	os_sprintf(cmd, (PS8)"ADD_NETWORK");
	if (IpcWpa_CommandWithResp(pWpaCore->hIpcWpa, cmd, TRUE, Resp, &RespLen))
	{
		WPACORE_SETSSID_FAIL;
	}
	NetworkID = os_strtoul(Resp, &pRespTemp, 0);

	/* Set the parameters in the new new network block*/

	/* Set the BSSID */
	if(!((bssid[0] == 0xFF) && 
		(bssid[1] == 0xFF) &&
		(bssid[2] == 0xFF) &&
		(bssid[3] == 0xFF) &&
		(bssid[4] == 0xFF) &&
		(bssid[5] == 0xFF)))
	{
		/* set th ebssid only if the bssid doesn't mean any bssid */	
        S8 temp[20];
		os_sprintf(temp, (PS8)"%02x", bssid[0]);
		os_sprintf(temp, (PS8)"%s:%02x", temp, bssid[1]);
		os_sprintf(temp, (PS8)"%s:%02x", temp, bssid[2]);
		os_sprintf(temp, (PS8)"%s:%02x", temp, bssid[3]);
		os_sprintf(temp, (PS8)"%s:%02x", temp, bssid[4]);
		os_sprintf(temp, (PS8)"%s:%02x", temp, bssid[5]);
		os_sprintf(cmd, (PS8)"SET_NETWORK %d bssid %s", NetworkID, temp);
		
		if (IpcWpa_Command(pWpaCore->hIpcWpa, cmd, FALSE))
		{
			WPACORE_SETSSID_FAIL;
		}
	}

   /* Set the SSID */
	os_sprintf(cmd, (PS8)"SET_NETWORK %d ssid \"%s\"", NetworkID, ssid->Ssid);
	if (IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
	{
		WPACORE_SETSSID_FAIL;
	}

	/* set mode of the new network block */
	os_sprintf(cmd, (PS8)"SET_NETWORK %d mode %d", NetworkID, pWpaCore->WpaSupplParams.mode);
	if (IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
	{
		WPACORE_SETSSID_FAIL;		
	}

    /* set proto of the new network block */
	SendCommand = TRUE;
	if (pWpaCore->WpaSupplParams.proto == WPA_PROTO_WPA)
	{
		os_sprintf(cmd, (PS8)"SET_NETWORK %d proto WPA", NetworkID);
	}
	else if (pWpaCore->WpaSupplParams.proto == WPA_PROTO_RSN)
	{
		os_sprintf(cmd, (PS8)"SET_NETWORK %d proto RSN", NetworkID);
	}
	else
	{
		SendCommand = FALSE;
	}
	
	if (SendCommand && IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
	{
		WPACORE_SETSSID_FAIL;		
	}

	/* set key management of the new network block */
	SendCommand = TRUE;
	if (pWpaCore->WpaSupplParams.key_mgmt == WPA_KEY_MGMT_NONE)
	{
		if ((pWpaCore->WpaSupplParams.eap == OS_EAP_TYPE_LEAP) ||
			(pWpaCore->WpaSupplParams.eap == OS_EAP_TYPE_PEAP) ||
			(pWpaCore->WpaSupplParams.eap == OS_EAP_TYPE_FAST))
        {
         os_sprintf(cmd, (PS8)"SET_NETWORK %d key_mgmt IEEE8021X", NetworkID);
        }
		else
			os_sprintf(cmd, (PS8)"SET_NETWORK %d key_mgmt NONE", NetworkID);
	}
	else if (pWpaCore->WpaSupplParams.key_mgmt == WPA_KEY_MGMT_PSK)
		os_sprintf(cmd, (PS8)"SET_NETWORK %d key_mgmt WPA-PSK", NetworkID);
	else if (pWpaCore->WpaSupplParams.key_mgmt == WPA_KEY_MGMT_IEEE8021X)
#ifdef XCC_MODULE_INCLUDED
       if((pWpaCore->WpaSupplParams.XCC == OS_XCC_CONFIGURATION_ENABLE_CCKM)||(pWpaCore->WpaSupplParams.XCC == OS_XCC_CONFIGURATION_ENABLE_ALL))
       {
        os_sprintf(cmd, (PS8)"SET_NETWORK %d key_mgmt WPA-EAP CCKM", NetworkID);
       }
       else
#endif
       os_sprintf(cmd, (PS8)"SET_NETWORK %d key_mgmt WPA-EAP", NetworkID);
   else if (pWpaCore->WpaSupplParams.key_mgmt == WPA_KEY_MGMT_WPA_NONE)
		os_sprintf(cmd, (PS8)"SET_NETWORK %d key_mgmt WPA-NONE", NetworkID);
	else
	{
		SendCommand = FALSE;
	}
	
	if (SendCommand && IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
	{
		WPACORE_SETSSID_FAIL;		
	}

   
	/* set authentication alog of the new network block */
	SendCommand = TRUE;
	if (pWpaCore->WpaSupplParams.auth_alg == WPA_AUTH_ALG_OPEN)
		os_sprintf(cmd, (PS8)"SET_NETWORK %d auth_alg OPEN", NetworkID);
	else if (pWpaCore->WpaSupplParams.auth_alg == WPA_AUTH_ALG_SHARED)
		os_sprintf(cmd, (PS8)"SET_NETWORK %d auth_alg SHARED", NetworkID);
	else if (pWpaCore->WpaSupplParams.auth_alg == WPA_AUTH_ALG_LEAP)
		os_sprintf(cmd, (PS8)"SET_NETWORK %d auth_alg LEAP", NetworkID);
	else
	{
		SendCommand = FALSE;
	}
	
	if (SendCommand && IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
	{
		WPACORE_SETSSID_FAIL;		
	}


    /* set pairwise encryption of the new network block */
	SendCommand = TRUE;
	if (pWpaCore->WpaSupplParams.pair_wise == WPA_CIPHER_NONE)
		os_sprintf(cmd, (PS8)"SET_NETWORK %d pairwise NONE", NetworkID);
	else if (pWpaCore->WpaSupplParams.pair_wise == WPA_CIPHER_WEP40)
		os_sprintf(cmd, (PS8)"SET_NETWORK %d pairwise NONE", NetworkID);
	else if (pWpaCore->WpaSupplParams.pair_wise == WPA_CIPHER_TKIP)
		os_sprintf(cmd, (PS8)"SET_NETWORK %d pairwise TKIP", NetworkID);
	else if ((pWpaCore->WpaSupplParams.pair_wise == WPA_CIPHER_CCMP)&& (pWpaCore->WpaSupplParams.anyWpaMode == 0))
		os_sprintf(cmd, (PS8)"SET_NETWORK %d pairwise CCMP", NetworkID);
    else if ((pWpaCore->WpaSupplParams.pair_wise == WPA_CIPHER_CCMP)&& (pWpaCore->WpaSupplParams.anyWpaMode == 1))
		os_sprintf(cmd, (PS8)"SET_NETWORK %d pairwise CCMP TKIP", NetworkID);
	else
	{
		SendCommand = FALSE;
	}
	   
	if (SendCommand && IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
	{
		WPACORE_SETSSID_FAIL;		 
	}

   /* set group encryption of the new network block */
	SendCommand = TRUE;
	if (pWpaCore->WpaSupplParams.group == WPA_CIPHER_WEP40)
		os_sprintf(cmd, (PS8)"SET_NETWORK %d group WEP40", NetworkID);
	else if (pWpaCore->WpaSupplParams.group == WPA_CIPHER_TKIP)
		os_sprintf(cmd, (PS8)"SET_NETWORK %d group TKIP", NetworkID);
	else if ((pWpaCore->WpaSupplParams.group == WPA_CIPHER_CCMP)&& (pWpaCore->WpaSupplParams.anyWpaMode == 0))
		os_sprintf(cmd, (PS8)"SET_NETWORK %d group CCMP", NetworkID);
    else if ((pWpaCore->WpaSupplParams.group == WPA_CIPHER_CCMP)&& (pWpaCore->WpaSupplParams.anyWpaMode == 1))
		os_sprintf(cmd, (PS8)"SET_NETWORK %d group CCMP TKIP", NetworkID);
	else
	{
		SendCommand = FALSE;
	}
	
	if (SendCommand && IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
	{
		WPACORE_SETSSID_FAIL;		
	}

   
   /* set eap of the new network block */
    if (pWpaCore->WpaSupplParams.eap == OS_EAP_TYPE_NONE)
        SendCommand = FALSE;
    else
    {
      SendCommand = TRUE;
      if (pWpaCore->WpaSupplParams.eap == OS_EAP_TYPE_MD5_CHALLENGE)
        os_sprintf(cmd, (PS8)"SET_NETWORK %d eap MD5", NetworkID);
      else if (pWpaCore->WpaSupplParams.eap == OS_EAP_TYPE_GENERIC_TOKEN_CARD)
        os_sprintf(cmd, (PS8)"SET_NETWORK %d eap GTC", NetworkID);
      else if (pWpaCore->WpaSupplParams.eap == OS_EAP_TYPE_TLS)
        os_sprintf(cmd, (PS8)"SET_NETWORK %d eap TLS", NetworkID);
      else if (pWpaCore->WpaSupplParams.eap == OS_EAP_TYPE_TTLS)
        os_sprintf(cmd, (PS8)"SET_NETWORK %d eap TTLS", NetworkID);
      else if (pWpaCore->WpaSupplParams.eap == OS_EAP_TYPE_PEAP)
        os_sprintf(cmd, (PS8)"SET_NETWORK %d eap PEAP", NetworkID);
      else if (pWpaCore->WpaSupplParams.eap == OS_EAP_TYPE_MS_CHAP_V2)
        os_sprintf(cmd, (PS8)"SET_NETWORK %d eap MSCHAPV2", NetworkID);
#ifdef XCC_MODULE_INCLUDED
      else if (pWpaCore->WpaSupplParams.eap == OS_EAP_TYPE_LEAP)
        os_sprintf(cmd, (PS8)"SET_NETWORK %d eap LEAP", NetworkID);
      else if (pWpaCore->WpaSupplParams.eap == OS_EAP_TYPE_FAST) 
        os_sprintf(cmd, (PS8)"SET_NETWORK %d eap FAST", NetworkID);
#endif
      else
       SendCommand = FALSE;
    }

   
    if (SendCommand && IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
    {
        WPACORE_SETSSID_FAIL;		
    }

     if (pWpaCore->WpaSupplParams.Identity[0]) 
	 {
       os_sprintf(cmd, (PS8)"SET_NETWORK %d identity \"%s\"", NetworkID,pWpaCore->WpaSupplParams.Identity);
       if (IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
	   {
          WPACORE_SETSSID_FAIL;  
	   }
     }
     
     if (pWpaCore->WpaSupplParams.client_cert[0])
	 {
       os_sprintf(cmd, (PS8)"SET_NETWORK %d client_cert \"%s\"", NetworkID,pWpaCore->WpaSupplParams.client_cert);
       
      if (IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
      {
       WPACORE_SETSSID_FAIL; 
      }
       
	 }

    
	 if (pWpaCore->WpaSupplParams.client_cert[0])
	 {

      Len = os_strlen ((PS8)pWpaCore->WpaSupplParams.client_cert);
      os_memcpy(pWpaCore->WpaSupplParams.private_key,pWpaCore->WpaSupplParams.client_cert,Len);
      os_memcpy(&pWpaCore->WpaSupplParams.private_key[Len-3],"pem",3);
    
      os_sprintf(cmd, (PS8)"SET_NETWORK %d private_key \"%s\"", NetworkID,pWpaCore->WpaSupplParams.private_key);
      if (IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
      {
        WPACORE_SETSSID_FAIL; 
      }
	 }
    
    if (pWpaCore->WpaSupplParams.private_key_passwd[0] ) 
	{
      os_sprintf(cmd, (PS8)"SET_NETWORK %d private_key_passwd \"%s\"", NetworkID,pWpaCore->WpaSupplParams.private_key_passwd);
       if (IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
        {
         WPACORE_SETSSID_FAIL; 
        }
	}
    
    if (pWpaCore->WpaSupplParams.password[0] ) 
    {
      os_sprintf(cmd, (PS8)"SET_NETWORK %d password \"%s\"", NetworkID,pWpaCore->WpaSupplParams.password);
       if (IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
        {
         WPACORE_SETSSID_FAIL; 
        }
      
    }


    if (pWpaCore->WpaSupplParams.eap == OS_EAP_TYPE_FAST) 
    {
      os_sprintf(cmd, (PS8)"SET_NETWORK %d phase1 \"fast_provisioning=3\"", NetworkID);
       if (IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
          {
           WPACORE_SETSSID_FAIL; 
          }

     os_sprintf(cmd, (PS8)"SET_NETWORK %d pac_file \"/etc/wpa_supplicant.eap-fast-pac\"", NetworkID);
       if (IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
          {
           WPACORE_SETSSID_FAIL; 
          }

     os_sprintf(cmd, (PS8)"SET_NETWORK %d anonymous_identity \"anonymous\"", NetworkID);
       if (IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
          {
           WPACORE_SETSSID_FAIL; 
          }

    }
        
    if (pWpaCore->WpaSupplParams.pair_wise == WPA_CIPHER_WEP40)	
	{
        S32 idx, idx2;
		
		for (idx=0; idx<4; idx++)
		{
            S8 TempBuf[3];
			os_sprintf(cmd, (PS8)"SET_NETWORK %d wep_key%d ", NetworkID, idx);
			for (idx2=0; idx2 < pWpaCore->WpaSupplParams.wep_key_length; idx2++)
			{
				os_sprintf(TempBuf, (PS8)"%02x", pWpaCore->WpaSupplParams.wep_key[idx][idx2]);
				os_strcat (cmd, TempBuf);
			}
			if (IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
			{
				WPACORE_SETSSID_FAIL;				
			}
		}
		os_sprintf(cmd, (PS8)"SET_NETWORK %d wep_tx_keyidx %d", NetworkID, pWpaCore->WpaSupplParams.default_wep_key-1);
		if (IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
		{
			WPACORE_SETSSID_FAIL;			
		}
	}

	if (pWpaCore->WpaSupplParams.key_mgmt == WPA_KEY_MGMT_PSK)
	{
		os_sprintf(cmd, (PS8)"SET_NETWORK %d psk \"%s\"", NetworkID, pWpaCore->WpaSupplParams.pass_phrase);
		if (IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
		{
			WPACORE_SETSSID_FAIL;			
		}
	}

   
#ifdef CONFIG_WPS
	if (pWpaCore->WpaSupplParams.WscMode)
	{
		os_sprintf(cmd, (PS8)"SET_NETWORK %d wsc_mode %d", NetworkID, pWpaCore->WpaSupplParams.WscMode);
		if (IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
		{
			WPACORE_SETSSID_FAIL;			
		}
	}
	if (pWpaCore->WpaSupplParams.pWscPin)
	{
		os_sprintf(cmd, (PS8)"SET_NETWORK %d wsc_pin \"%s\"", NetworkID, pWpaCore->WpaSupplParams.pWscPin);
		if (IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
		{
			WPACORE_SETSSID_FAIL;			
		}
	}
#endif

	/* Finaly Connect to the new network block */
	os_sprintf(cmd, (PS8)"SELECT_NETWORK %d", NetworkID);
	if (IpcWpa_Command(pWpaCore->hIpcWpa, cmd, 0))
	{
		WPACORE_SETSSID_FAIL;
	}

	pWpaCore->CurrentNetwork = NetworkID;	
	IpcWpa_Command(pWpaCore->hIpcWpa, (PS8)"SAVE_CONFIG", 1);

   /* 
	init the connection params thus the next time we connect we will by default 
	connect to an open 
	*/
	WpaCore_InitWpaParams(pWpaCore);

	return OK;
}
static int hapd_wps_cred_cb(struct hostapd_data *hapd, void *ctx)
{
	const struct wps_credential *cred = ctx;
	FILE *oconf, *nconf;
	size_t len, i;
	char *tmp_fname;
	char buf[1024];
	int multi_bss;
	int wpa;

	if (hapd->wps == NULL)
		return 0;

	wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute",
			cred->cred_attr, cred->cred_attr_len);

	wpa_printf(MSG_DEBUG, "WPS: Received new AP Settings");
	wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID", cred->ssid, cred->ssid_len);
	wpa_printf(MSG_DEBUG, "WPS: Authentication Type 0x%x",
		   cred->auth_type);
	wpa_printf(MSG_DEBUG, "WPS: Encryption Type 0x%x", cred->encr_type);
	wpa_printf(MSG_DEBUG, "WPS: Network Key Index %d", cred->key_idx);
	wpa_hexdump_key(MSG_DEBUG, "WPS: Network Key",
			cred->key, cred->key_len);
	wpa_printf(MSG_DEBUG, "WPS: MAC Address " MACSTR,
		   MAC2STR(cred->mac_addr));

	if ((hapd->conf->wps_cred_processing == 1 ||
	     hapd->conf->wps_cred_processing == 2) && cred->cred_attr) {
		hapd_new_ap_event(hapd, cred->cred_attr, cred->cred_attr_len);
	} else if (hapd->conf->wps_cred_processing == 1 ||
		   hapd->conf->wps_cred_processing == 2) {
		struct wpabuf *attr;
		attr = wpabuf_alloc(200);
		if (attr && wps_build_credential_wrap(attr, cred) == 0)
			hapd_new_ap_event(hapd, wpabuf_head_u8(attr),
					  wpabuf_len(attr));
		wpabuf_free(attr);
	} else
		wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_NEW_AP_SETTINGS);

	if (hapd->conf->wps_cred_processing == 1)
		return 0;

	os_memcpy(hapd->wps->ssid, cred->ssid, cred->ssid_len);
	hapd->wps->ssid_len = cred->ssid_len;
	hapd->wps->encr_types = cred->encr_type;
	hapd->wps->auth_types = cred->auth_type;
	if (cred->key_len == 0) {
		os_free(hapd->wps->network_key);
		hapd->wps->network_key = NULL;
		hapd->wps->network_key_len = 0;
	} else {
		if (hapd->wps->network_key == NULL ||
		    hapd->wps->network_key_len < cred->key_len) {
			hapd->wps->network_key_len = 0;
			os_free(hapd->wps->network_key);
			hapd->wps->network_key = os_malloc(cred->key_len);
			if (hapd->wps->network_key == NULL)
				return -1;
		}
		hapd->wps->network_key_len = cred->key_len;
		os_memcpy(hapd->wps->network_key, cred->key, cred->key_len);
	}
	hapd->wps->wps_state = WPS_STATE_CONFIGURED;

	if (hapd->iface->config_fname == NULL)
		return 0;
	len = os_strlen(hapd->iface->config_fname) + 5;
	tmp_fname = os_malloc(len);
	if (tmp_fname == NULL)
		return -1;
	os_snprintf(tmp_fname, len, "%s-new", hapd->iface->config_fname);

	oconf = fopen(hapd->iface->config_fname, "r");
	if (oconf == NULL) {
		wpa_printf(MSG_WARNING, "WPS: Could not open current "
			   "configuration file");
		os_free(tmp_fname);
		return -1;
	}

	nconf = fopen(tmp_fname, "w");
	if (nconf == NULL) {
		wpa_printf(MSG_WARNING, "WPS: Could not write updated "
			   "configuration file");
		os_free(tmp_fname);
		fclose(oconf);
		return -1;
	}

	fprintf(nconf, "# WPS configuration - START\n");

	fprintf(nconf, "wps_state=2\n");

	if (is_hex(cred->ssid, cred->ssid_len)) {
		fprintf(nconf, "ssid2=");
		for (i = 0; i < cred->ssid_len; i++)
			fprintf(nconf, "%02x", cred->ssid[i]);
		fprintf(nconf, "\n");
	} else {
		fprintf(nconf, "ssid=");
		for (i = 0; i < cred->ssid_len; i++)
			fputc(cred->ssid[i], nconf);
		fprintf(nconf, "\n");
	}

	if ((cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK)) &&
	    (cred->auth_type & (WPS_AUTH_WPA | WPS_AUTH_WPAPSK)))
		wpa = 3;
	else if (cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK))
		wpa = 2;
	else if (cred->auth_type & (WPS_AUTH_WPA | WPS_AUTH_WPAPSK))
		wpa = 1;
	else
		wpa = 0;

	if (wpa) {
		char *prefix;
		fprintf(nconf, "wpa=%d\n", wpa);

		fprintf(nconf, "wpa_key_mgmt=");
		prefix = "";
		if (cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA)) {
			fprintf(nconf, "WPA-EAP");
			prefix = " ";
		}
		if (cred->auth_type & (WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK))
			fprintf(nconf, "%sWPA-PSK", prefix);
		fprintf(nconf, "\n");

		fprintf(nconf, "wpa_pairwise=");
		prefix = "";
		if (cred->encr_type & WPS_ENCR_AES) {
			fprintf(nconf, "CCMP");
			prefix = " ";
		}
		if (cred->encr_type & WPS_ENCR_TKIP) {
			fprintf(nconf, "%sTKIP", prefix);
		}
		fprintf(nconf, "\n");

		if (cred->key_len >= 8 && cred->key_len < 64) {
			fprintf(nconf, "wpa_passphrase=");
			for (i = 0; i < cred->key_len; i++)
				fputc(cred->key[i], nconf);
			fprintf(nconf, "\n");
		} else if (cred->key_len == 64) {
			fprintf(nconf, "wpa_psk=");
			for (i = 0; i < cred->key_len; i++)
				fputc(cred->key[i], nconf);
			fprintf(nconf, "\n");
		} else {
			wpa_printf(MSG_WARNING, "WPS: Invalid key length %lu "
				   "for WPA/WPA2",
				   (unsigned long) cred->key_len);
		}

		fprintf(nconf, "auth_algs=1\n");
	} else {
		if ((cred->auth_type & WPS_AUTH_OPEN) &&
		    (cred->auth_type & WPS_AUTH_SHARED))
			fprintf(nconf, "auth_algs=3\n");
		else if (cred->auth_type & WPS_AUTH_SHARED)
			fprintf(nconf, "auth_algs=2\n");
		else
			fprintf(nconf, "auth_algs=1\n");

		if (cred->encr_type & WPS_ENCR_WEP && cred->key_idx <= 4) {
			int key_idx = cred->key_idx;
			if (key_idx)
				key_idx--;
			fprintf(nconf, "wep_default_key=%d\n", key_idx);
			fprintf(nconf, "wep_key%d=", key_idx);
			if (cred->key_len == 10 || cred->key_len == 26) {
				/* WEP key as a hex string */
				for (i = 0; i < cred->key_len; i++)
					fputc(cred->key[i], nconf);
			} else {
				/* Raw WEP key; convert to hex */
				for (i = 0; i < cred->key_len; i++)
					fprintf(nconf, "%02x", cred->key[i]);
			}
			fprintf(nconf, "\n");
		}
	}

	fprintf(nconf, "# WPS configuration - END\n");

	multi_bss = 0;
	while (fgets(buf, sizeof(buf), oconf)) {
		if (os_strncmp(buf, "bss=", 4) == 0)
			multi_bss = 1;
		if (!multi_bss &&
		    (str_starts(buf, "ssid=") ||
		     str_starts(buf, "ssid2=") ||
		     str_starts(buf, "auth_algs=") ||
		     str_starts(buf, "wep_default_key=") ||
		     str_starts(buf, "wep_key") ||
		     str_starts(buf, "wps_state=") ||
		     str_starts(buf, "wpa=") ||
		     str_starts(buf, "wpa_psk=") ||
		     str_starts(buf, "wpa_pairwise=") ||
		     str_starts(buf, "rsn_pairwise=") ||
		     str_starts(buf, "wpa_key_mgmt=") ||
		     str_starts(buf, "wpa_passphrase="))) {
			fprintf(nconf, "#WPS# %s", buf);
		} else
			fprintf(nconf, "%s", buf);
	}

	fclose(nconf);
	fclose(oconf);

	if (rename(tmp_fname, hapd->iface->config_fname) < 0) {
		wpa_printf(MSG_WARNING, "WPS: Failed to rename the updated "
			   "configuration file: %s", strerror(errno));
		os_free(tmp_fname);
		return -1;
	}

	os_free(tmp_fname);

	/* Schedule configuration reload after short period of time to allow
	 * EAP-WSC to be finished.
	 */
	eloop_register_timeout(0, 100000, wps_reload_config, hapd->iface,
			       NULL);

	wpa_printf(MSG_DEBUG, "WPS: AP configuration updated");

	return 0;
}
Exemple #24
0
/* subscr_addr_add_url -- add address(es) for one url to subscription */
static void subscr_addr_add_url(struct subscription *s, const char *url,
				size_t url_len)
{
	int alloc_len;
	char *scratch_mem = NULL;
	char *mem;
	char *host;
	char *delim;
	char *path;
	int port = 80;  /* port to send to (default is port 80) */
	struct addrinfo hints;
	struct addrinfo *result = NULL;
	struct addrinfo *rp;
	int rerr;
	size_t host_len, path_len;

	/* url MUST begin with http: */
	if (url_len < 7 || os_strncasecmp(url, "http://", 7))
		goto fail;
	url += 7;
	url_len -= 7;

	/* Make a copy of the string to allow modification during parsing */
	scratch_mem = dup_binstr(url, url_len);
	if (scratch_mem == NULL)
		goto fail;
	wpa_printf(MSG_DEBUG, "WPS UPnP: Adding URL '%s'", scratch_mem);
	host = scratch_mem;
	path = os_strchr(host, '/');
	if (path)
		*path++ = '\0'; /* null terminate host */

	/* Process and remove optional port component */
	delim = os_strchr(host, ':');
	if (delim) {
		*delim = '\0'; /* null terminate host name for now */
		if (isdigit(delim[1]))
			port = atol(delim + 1);
	}

	/*
	 * getaddrinfo does the right thing with dotted decimal notations, or
	 * will resolve domain names. Resolving domain names will unfortunately
	 * hang the entire program until it is resolved or it times out
	 * internal to getaddrinfo; fortunately we think that the use of actual
	 * domain names (vs. dotted decimal notations) should be uncommon.
	 */
	os_memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_INET;      /* IPv4 */
	hints.ai_socktype = SOCK_STREAM;
#if NO_DOMAIN_NAME_RESOLUTION
	/* Suppress domain name resolutions that would halt
	 * the program for periods of time
	 */
	hints.ai_flags = AI_NUMERICHOST;
#else
	/* Allow domain name resolution. */
	hints.ai_flags = 0;
#endif
	hints.ai_protocol = 0;          /* Any protocol? */
	rerr = getaddrinfo(host, NULL /* fill in port ourselves */,
			   &hints, &result);
	if (rerr) {
		wpa_printf(MSG_INFO, "WPS UPnP: Resolve error %d (%s) on: %s",
			   rerr, gai_strerror(rerr), host);
		goto fail;
	}

	if (delim)
		*delim = ':'; /* Restore port */

	host_len = os_strlen(host);
	path_len = path ? os_strlen(path) : 0;
	alloc_len = host_len + 1 + 1 + path_len + 1;

	for (rp = result; rp; rp = rp->ai_next) {
		struct subscr_addr *a;

		/* Limit no. of address to avoid denial of service attack */
		if (dl_list_len(&s->addr_list) >= MAX_ADDR_PER_SUBSCRIPTION) {
			wpa_printf(MSG_INFO, "WPS UPnP: subscr_addr_add_url: "
				   "Ignoring excessive addresses");
			break;
		}

		a = os_zalloc(sizeof(*a) + alloc_len);
		if (a == NULL)
			break;
		mem = (char *) (a + 1);
		a->domain_and_port = mem;
		os_memcpy(mem, host, host_len);
		mem += host_len + 1;
		a->path = mem;
		if (path == NULL || path[0] != '/')
			*mem++ = '/';
		if (path)
			os_memcpy(mem, path, path_len);
		os_memcpy(&a->saddr, rp->ai_addr, sizeof(a->saddr));
		a->saddr.sin_port = htons(port);

		dl_list_add(&s->addr_list, &a->list);
	}

fail:
	if (result)
		freeaddrinfo(result);
	os_free(scratch_mem);
}
Exemple #25
0
/**
  * @brief  MQTT initialization mqtt client function
  * @param  client:   MQTT_Client reference
  * @param  clientid:   MQTT client id
  * @param  client_user:MQTT client user
  * @param  client_pass:MQTT client password
  * @param  client_pass:MQTT keep alive timer, in second
  * @retval None
  */
BOOL ICACHE_FLASH_ATTR
MQTT_InitClient(MQTT_Client * mqttClient, uint8_t * client_id, uint8_t * client_user, uint8_t * client_pass,
		uint32_t keepAliveTime, uint8_t cleanSession) {
    uint32_t temp;
    MQTT_INFO("MQTT:InitClient\r\n");

    os_memset(&mqttClient->connect_info, 0, sizeof(mqtt_connect_info_t));

    if (!client_id) {
	/* Should be allowed by broker, but clean session flag must be set. */
#ifdef PROTOCOL_NAMEv311
	if (cleanSession) {
	    mqttClient->connect_info.client_id = zero_len_id;
	} else {
	    MQTT_INFO("cleanSession must be set to use 0 length client_id\r\n");
	    return false;
	}
	/* Not supported. Return. */
#else
	MQTT_INFO("Client ID required for MQTT < 3.1.1!\r\n");
	return false;
#endif
    }

    /* If connect_info's client_id is still NULL and we get here, we can        *
     * assume the passed client_id is non-NULL.                                 */
    if (!(mqttClient->connect_info.client_id)) {
	temp = os_strlen(client_id);
	mqttClient->connect_info.client_id = (uint8_t *) os_zalloc(temp + 1);
	os_strcpy(mqttClient->connect_info.client_id, client_id);
	mqttClient->connect_info.client_id[temp] = 0;
    }

    if (client_user) {
	temp = os_strlen(client_user);
	mqttClient->connect_info.username = (uint8_t *) os_zalloc(temp + 1);
	os_strcpy(mqttClient->connect_info.username, client_user);
	mqttClient->connect_info.username[temp] = 0;
    }

    if (client_pass) {
	temp = os_strlen(client_pass);
	mqttClient->connect_info.password = (uint8_t *) os_zalloc(temp + 1);
	os_strcpy(mqttClient->connect_info.password, client_pass);
	mqttClient->connect_info.password[temp] = 0;
    }

    mqttClient->connect_info.keepalive = keepAliveTime;
    mqttClient->connect_info.clean_session = cleanSession;

    mqttClient->mqtt_state.in_buffer = (uint8_t *) os_zalloc(MQTT_BUF_SIZE);
    mqttClient->mqtt_state.in_buffer_length = MQTT_BUF_SIZE;
    mqttClient->mqtt_state.out_buffer = (uint8_t *) os_zalloc(MQTT_BUF_SIZE);
    mqttClient->mqtt_state.out_buffer_length = MQTT_BUF_SIZE;
    mqttClient->mqtt_state.connect_info = &mqttClient->connect_info;

    mqtt_msg_init(&mqttClient->mqtt_state.mqtt_connection, mqttClient->mqtt_state.out_buffer,
		  mqttClient->mqtt_state.out_buffer_length);

    QUEUE_Init(&mqttClient->msgQueue, QUEUE_BUFFER_SIZE);

    system_os_task(MQTT_Task, MQTT_TASK_PRIO, mqtt_procTaskQueue, MQTT_TASK_QUEUE_SIZE);
    system_os_post(MQTT_TASK_PRIO, 0, (os_param_t) mqttClient);
    return true;
}
Exemple #26
0
/**
 * upnp_wps_device_send_event - Queue event messages for subscribers
 * @sm: WPS UPnP state machine from upnp_wps_device_init()
 *
 * This function queues the last WLANEvent to be sent for all currently
 * subscribed UPnP control points. sm->wlanevent must have been set with the
 * encoded data before calling this function.
 */
static void upnp_wps_device_send_event(struct upnp_wps_device_sm *sm)
{
	/* Enqueue event message for all subscribers */
	struct wpabuf *buf; /* holds event message */
	int buf_size = 0;
	struct subscription *s, *tmp;
	/* Actually, utf-8 is the default, but it doesn't hurt to specify it */
	const char *format_head =
		"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
		"<e:propertyset xmlns:e=\"urn:schemas-upnp-org:event-1-0\">\n";
	const char *format_tail = "</e:propertyset>\n";
	struct os_reltime now;

	if (dl_list_empty(&sm->subscriptions)) {
		/* optimize */
		return;
	}

	if (os_get_reltime(&now) == 0) {
		if (now.sec != sm->last_event_sec) {
			sm->last_event_sec = now.sec;
			sm->num_events_in_sec = 1;
		} else {
			sm->num_events_in_sec++;
			/*
			 * In theory, this should apply to all WLANEvent
			 * notifications, but EAP messages are of much higher
			 * priority and Probe Request notifications should not
			 * be allowed to drop EAP messages, so only throttle
			 * Probe Request notifications.
			 */
			if (sm->num_events_in_sec > MAX_EVENTS_PER_SEC &&
			    sm->wlanevent_type ==
			    UPNP_WPS_WLANEVENT_TYPE_PROBE) {
				wpa_printf(MSG_DEBUG, "WPS UPnP: Throttle "
					   "event notifications (%u seen "
					   "during one second)",
					   sm->num_events_in_sec);
				return;
			}
		}
	}

	/* Determine buffer size needed first */
	buf_size += os_strlen(format_head);
	buf_size += 50 + 2 * os_strlen("WLANEvent");
	if (sm->wlanevent)
		buf_size += os_strlen(sm->wlanevent);
	buf_size += os_strlen(format_tail);

	buf = wpabuf_alloc(buf_size);
	if (buf == NULL)
		return;
	wpabuf_put_str(buf, format_head);
	wpabuf_put_property(buf, "WLANEvent", sm->wlanevent);
	wpabuf_put_str(buf, format_tail);

	wpa_printf(MSG_MSGDUMP, "WPS UPnP: WLANEvent message:\n%s",
		   (char *) wpabuf_head(buf));

	dl_list_for_each_safe(s, tmp, &sm->subscriptions, struct subscription,
			      list) {
		event_add(s, buf,
			  sm->wlanevent_type == UPNP_WPS_WLANEVENT_TYPE_PROBE);
	}

	wpabuf_free(buf);
}
int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
                  size_t buf_len )
{
    struct i802_bss *bss = priv;
    struct wpa_driver_nl80211_data *drv = bss->drv;
    struct ifreq ifr;
    struct wpa_supplicant *wpa_s;
    struct hostapd_data *hapd;
    int handled = 0;
    int cmd_len = 0;
    union wpa_event_data event;
    static int user_force_band = 0;
    int ret = -1;

    if (drv == NULL) {
        wpa_printf(MSG_ERROR, "%s: drv is NULL. Exiting", __func__);
        return -1;
    }
    if (drv->ctx == NULL) {
        wpa_printf(MSG_ERROR, "%s: drv->ctx is NULL. Exiting", __func__);
        return -1;
    }

    if (os_strcmp(bss->ifname, "ap0") == 0) {
        hapd = (struct hostapd_data *)(drv->ctx);
    }
    else {
        wpa_s = (struct wpa_supplicant *)(drv->ctx);
        if (wpa_s->conf == NULL) {
            wpa_printf(MSG_ERROR, "%s: wpa_s->conf is NULL. Exiting", __func__);
            return -1;
        }
    }

    wpa_printf(MSG_DEBUG, "iface %s recv cmd %s", bss->ifname, cmd);
    handled = 1;

    if (os_strncasecmp(cmd, "POWERMODE ", 10) == 0) {
        int state;
        state = atoi(cmd + 10);
        wpa_printf(MSG_DEBUG, "POWERMODE=%d", state);
    }  else if (os_strncmp(cmd, "MACADDR", os_strlen("MACADDR")) == 0) {
        u8 macaddr[ETH_ALEN] = {};
        os_memcpy(&macaddr, wpa_s->own_addr, ETH_ALEN);
        ret = snprintf(buf, buf_len, "Macaddr = " MACSTR "\n", MAC2STR(macaddr));
        wpa_printf(MSG_DEBUG, "%s", buf);
    } else if(os_strncasecmp(cmd, "COUNTRY", os_strlen("COUNTRY"))==0) {
        if (os_strlen(cmd) != os_strlen("COUNTRY") + 3) {
            wpa_printf(MSG_DEBUG, "Ignore COUNTRY cmd %s", cmd);
            ret = 0;
        } else {
            wpa_printf(MSG_INFO, "set country: %s", cmd+8);
            // ret = wpa_drv_set_country(wpa_s, cmd+8);
            ret = wpa_driver_mediatek_set_country(priv, cmd+8);
            if (ret == 0) {
                wpa_printf(MSG_DEBUG, "Update channel list after country code changed");
                wpa_driver_notify_country_change(wpa_s, cmd);
            }
        }
    } else if (os_strcasecmp(cmd, "start") == 0) {
        if (ret = linux_set_iface_flags(drv->global->ioctl_sock,
            drv->first_bss->ifname, 1)) {
            wpa_printf(MSG_INFO, "nl80211: Could not set interface UP, ret=%d \n", ret);
        } else {
            wpa_msg(drv->ctx, MSG_INFO, "CTRL-EVENT-DRIVER-STATE STARTED");
        }
    } else if (os_strcasecmp(cmd, "stop") == 0) {
        if (drv->associated) {
            ret = wpa_drv_deauthenticate(wpa_s, drv->bssid, WLAN_REASON_DEAUTH_LEAVING);
            if (ret != 0)
                wpa_printf(MSG_DEBUG, "DRIVER-STOP error, ret=%d", ret);
        } else {
            wpa_printf(MSG_INFO, "nl80211: not associated, no need to deauthenticate \n");
        }

        if (ret = linux_set_iface_flags(drv->global->ioctl_sock,
            drv->first_bss->ifname, 0)) {
            wpa_printf(MSG_INFO, "nl80211: Could not set interface Down, ret=%d \n", ret);
        } else {
            wpa_msg(drv->ctx, MSG_INFO, "CTRL-EVENT-DRIVER-STATE STOPPED");
        }
    } else if (os_strncasecmp(cmd, "getpower", 8) == 0) {
        u32 mode;
        // ret = wpa_driver_wext_driver_get_power(drv, &mode);
        if (ret == 0) {
            ret = snprintf(buf, buf_len, "powermode = %u\n", mode);
            wpa_printf(MSG_DEBUG, "%s", buf);
            if (ret < (int)buf_len)
                return ret;
        }
    } else if (os_strncasecmp(cmd, "get-rts-threshold", 17) == 0) {
        u32 thd;
        // ret = wpa_driver_wext_driver_get_rts(drv, &thd);
        if (ret == 0) {
            ret = snprintf(buf, buf_len, "rts-threshold = %u\n", thd);
            wpa_printf(MSG_DEBUG, "%s", buf);
            if (ret < (int)buf_len)
                return ret;
        }
    } else if (os_strncasecmp(cmd, "set-rts-threshold", 17) == 0) {
        u32 thd = 0;
        char *cp = cmd + 17;
        char *endp;
        if (*cp != '\0') {
            thd = (u32)strtol(cp, &endp, 0);
            // if (endp != cp)
                // ret = wpa_driver_wext_driver_set_rts(drv, thd);
        }
    } else if (os_strcasecmp(cmd, "btcoexscan-start") == 0) {
        ret = 0; /* mt5921 linux driver not implement yet */
    } else if (os_strcasecmp(cmd, "btcoexscan-stop") == 0) {
        ret = 0; /* mt5921 linux driver not implement yet */
    } else if (os_strncasecmp(cmd, "btcoexmode", 10) == 0) {
        ret = 0; /* mt5921 linux driver not implement yet */
    } else {
        handled = 0;
        wpa_printf(MSG_INFO, "Unsupported command");
    }

    return ret;
}
Exemple #28
0
/* subscription_first_event -- send format/queue event that is automatically
 * sent on a new subscription.
 */
static int subscription_first_event(struct subscription *s)
{
	/*
	 * Actually, utf-8 is the default, but it doesn't hurt to specify it.
	 *
	 * APStatus is apparently a bit set,
	 * 0x1 = configuration change (but is always set?)
	 * 0x10 = ap is locked
	 *
	 * Per UPnP spec, we send out the last value of each variable, even
	 * for WLANEvent, whatever it was.
	 */
	char *wlan_event;
	struct wpabuf *buf;
	int ap_status = 1;      /* TODO: add 0x10 if access point is locked */
	const char *head =
		"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
		"<e:propertyset xmlns:e=\"urn:schemas-upnp-org:event-1-0\">\n";
	const char *tail = "</e:propertyset>\n";
	char txt[10];
	int ret;

	if (s->sm->wlanevent == NULL) {
		/*
		 * There has been no events before the subscription. However,
		 * UPnP device architecture specification requires all the
		 * evented variables to be included, so generate a dummy event
		 * for this particular case using a WSC_ACK and all-zeros
		 * nonces. The ER (UPnP control point) will ignore this, but at
		 * least it will learn that WLANEvent variable will be used in
		 * event notifications in the future.
		 */
		struct wpabuf *msg;
		wpa_printf(MSG_DEBUG, "WPS UPnP: Use a fake WSC_ACK as the "
			   "initial WLANEvent");
		msg = build_fake_wsc_ack();
		if (msg) {
			s->sm->wlanevent = (char *)
				base64_encode(wpabuf_head(msg),
					      wpabuf_len(msg), NULL);
			wpabuf_free(msg);
		}
	}

	wlan_event = s->sm->wlanevent;
	if (wlan_event == NULL || *wlan_event == '\0') {
		wpa_printf(MSG_DEBUG, "WPS UPnP: WLANEvent not known for "
			   "initial event message");
		wlan_event = "";
	}
	buf = wpabuf_alloc(500 + os_strlen(wlan_event));
	if (buf == NULL)
		return -1;

	wpabuf_put_str(buf, head);
	wpabuf_put_property(buf, "STAStatus", "1");
	os_snprintf(txt, sizeof(txt), "%d", ap_status);
	wpabuf_put_property(buf, "APStatus", txt);
	if (*wlan_event)
		wpabuf_put_property(buf, "WLANEvent", wlan_event);
	wpabuf_put_str(buf, tail);

	ret = event_add(s, buf, 0);
	if (ret) {
		wpabuf_free(buf);
		return ret;
	}
	wpabuf_free(buf);

	return 0;
}
Exemple #29
0
static int wps_attr_parse_tests(void)
{
	struct wps_parse_attr attr;
	unsigned int i;
	int ret = 0;

	wpa_printf(MSG_INFO, "WPS attribute parsing tests");

	for (i = 0; i < ARRAY_SIZE(wps_attr_parse_test_cases); i++) {
		struct wpabuf *buf;
		size_t len;
		const struct wps_attr_parse_test *test =
			&wps_attr_parse_test_cases[i];

		len = os_strlen(test->data) / 2;
		buf = wpabuf_alloc(len);
		if (buf == NULL)
			return -1;
		if (hexstr2bin(test->data, wpabuf_put(buf, len), len) < 0) {
			wpabuf_free(buf);
			return -1;
		}
		if (wps_parse_msg(buf, &attr) != test->result) {
			wpa_printf(MSG_ERROR, "WPS attribute parsing test %u failed: %s",
				   i, test->data);
			ret = -1;
		}
		switch (test->extra) {
		case 1:
			if (!attr.network_key || !attr.ap_setup_locked)
				ret = -1;
			break;
		case 2:
			if (attr.num_cred != MAX_CRED_COUNT)
				ret = -1;
			break;
		case 3:
			if (!attr.network_key_idx)
				ret = -1;
			break;
		case 4:
			if (attr.num_req_dev_type != MAX_REQ_DEV_TYPE_COUNT)
				ret = -1;
			break;
		case 5:
			if (attr.num_vendor_ext != MAX_WPS_PARSE_VENDOR_EXT)
				ret = -1;
			break;
		case 6:
			if (!attr.version2 ||
			    !attr.authorized_macs ||
			    !attr.network_key_shareable ||
			    !attr.request_to_enroll ||
			    !attr.settings_delay_time)
				ret = -1;
			break;
		}
		wpabuf_free(buf);
	}

	return ret;
}
int ICACHE_FLASH_ATTR http_ws_handle_connect(http_connection *c) {	

	NODE_DBG("http_ws_handle_connect c =%p",c);

	if(c->state == HTTPD_STATE_ON_URL){
		http_set_save_header(c,HTTP_ORIGIN);	
		http_set_save_header(c,HTTP_CONNECTION);	
		http_set_save_header(c,HTTP_UPGRADE);		
		http_set_save_header(c,HTTP_SEC_WEBSOCKET_KEY);
		http_set_save_header(c,HTTP_SEC_WEBSOCKET_PROTOCOL);
		http_set_save_header(c,HTTP_SEC_WEBSOCKET_VERSION);

		return HTTP_WS_CGI_MORE;
	}

	//wait handshake request complete
	if(c->state != HTTPD_STATE_BODY_END)
		return HTTP_WS_CGI_MORE;


	header * upgrade_header = http_get_header(c,HTTP_UPGRADE);
	header * connection_header = http_get_header(c,HTTP_CONNECTION);
	header * origin_header = http_get_header(c,HTTP_ORIGIN);
	header * key_header = http_get_header(c,HTTP_SEC_WEBSOCKET_KEY);

	if(upgrade_header==NULL) goto badrequest;
	if(connection_header==NULL) goto badrequest;
	if(origin_header==NULL) goto badrequest;
	if(key_header==NULL) goto badrequest;

	NODE_DBG("headers ok");

	if(os_strcasecmp(upgrade_header->value,"websocket")!=0) goto badrequest;

	// Following (https://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17)
	//calculate sha1 of concatenetion key+uuid
	uint8_t digest[20]; //sha1 is always 20 byte long
	SHA1_CTX ctx;
	SHA1_Init(&ctx);
	SHA1_Update(&ctx,key_header->value,os_strlen(key_header->value));
	SHA1_Update(&ctx,ws_uuid,os_strlen(ws_uuid));
	SHA1_Final(digest,&ctx);
		
	char base64Digest[31]; // 
	Base64encode(base64Digest,(const char*)digest,20);

	//accept the handshake
	http_SET_HEADER(c,HTTP_UPGRADE,"websocket");
	http_SET_HEADER(c,HTTP_CONNECTION,"Upgrade");
	
	http_SET_HEADER(c,HTTP_WEBSOCKET_ACCEPT,base64Digest);

	http_websocket_HANDSHAKE(c);
	c->handshake_ok=1;

	if(client_connected_callback!=NULL)
		client_connected_callback(c);

	return HTTP_WS_CGI_MORE;

badrequest:
	http_response_BAD_REQUEST(c);
	return HTTP_WS_CGI_DONE;

}