ZG2100 Network interface source
Diff: drv/zg2100/zg_if.c
- Revision:
- 0:b802fc31f1db
- Child:
- 1:3a7c15057192
diff -r 000000000000 -r b802fc31f1db drv/zg2100/zg_if.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drv/zg2100/zg_if.c Fri Jul 09 15:37:23 2010 +0000 @@ -0,0 +1,266 @@ + +/* +Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "netCfg.h" +#if NET_ZG2100 + +#include "zg_defs.h" +#include "zg_drv.h" +#include "zg_if.h" + +//#define __DEBUG +#include "dbg/dbg.h" + +#include "string.h" + +char m_ssid[ZG_SSID_LEN+1] = {0}; +zg_err connection_result = (zg_err)0; //Disc + +#ifdef __DEBUG +/*inline*/ void hexdump(byte* buffer, int size) { + for(int i = 0; i < size; ++i) { + if((i%16)!=0) { + DBG(" "); + } else { + DBG("%04X: ", (i)); + } + printf("%02hhx", buffer[i]); + if((i%16) == 7) { + DBG(" "); + } + if((i%16) == 15) { + DBG("\n"); + } + } + printf("\n\n\n"); +} +#else +#define hexdump(a,b) +#endif + +void zg_scan(byte channel) +{ + //Prepare request + ZG_SCAN_REQ* req = (ZG_SCAN_REQ*)fifo_buf; + memset((void*)req, 0, sizeof(ZG_SCAN_REQ)); + + req->probe_delay = HTODS(ZG_SCAN_PROBE_DELAY); + + req->min_chan_time = HTODS(ZG_SCAN_MIN_CHAN_TIME); + req->max_chan_time = HTODS(ZG_SCAN_MAX_CHAN_TIME); + + memset(req->bssid_mask, 0xFF, ZG_MACADDR_LEN); //Broadcast + + req->bss_type = ZG_BSS_ANY; + req->probe_req = ZG_PROBE_ACTIVE; + + req->ssid_len = 0; //Do not filter by SSID + + req->channels_count = 1; //Scan on all ETSI channels (1~13) + req->channels[0] = channel; + + //hexdump(fifo_buf, sizeof(ZG_SCAN_REQ)); + + DBG("\r\n\r\n"); + + //Send request + zg_mgmt_req(ZG_FIFO_MGMT_SCAN, fifo_buf, sizeof(ZG_SCAN_REQ)); +} + +void zg_on_scan_results(byte* buf, int len) +{ + int i; + int j; + uint32_t rate; + char ssid[ZG_SSID_LEN + 1]; + ZG_SCAN_ITEM* it; + //Get result header + ZG_SCAN_RES* res = (ZG_SCAN_RES*)buf; + + //hexdump(buf, len); + + DBG("\r\nScan result %d, with %d networks found\r\n", + res->result, res->results_count); + + if( res->result != 1 ) + { + return; //Error + } + it = (ZG_SCAN_ITEM*)(buf + sizeof(ZG_SCAN_RES)); + for( i = 0; i < res->results_count; i++ ) + { + //Display info + DBG("\r\n---Result #%2d---\r\n",i+1); + + memset(ssid, 0, ZG_SSID_LEN + 1); + memcpy(ssid, it->ssid, it->ssid_len); + DBG("SSID : %s\r\n", ssid); + + DBG("BSSID : %02x:%02x:%02x:%02x:%02x:%02x\r\n", + it->bssid[0], it->bssid[1], it->bssid[2], + it->bssid[3], it->bssid[4], it->bssid[5]); + + DBG("Supported rates : "); + for( j = 0; j < it->supported_rates_count; j++ ) + { + rate = it->supported_rates[j]; + rate = rate * 500; + DBG("%u Kbps; ", rate); + } + DBG("\r\n"); + + DBG("RSSI : %d\r\n", it->rssi); + DBG("Channel : %d\r\n", it->channel); + DBG("Type : %d\r\n", it->bss_type); + + DBG("---------------\r\n"); + + it++; //Next result + } +} + +void zg_set_ssid(const char* ssid) +{ + strcpy(m_ssid, ssid); +} + +void zg_set_wep_key(const byte* key, int len) +{ + //Write 4 wep keys + ZG_WEP_REQ* req = (ZG_WEP_REQ*)fifo_buf; + memset((void*)req, 0, sizeof(ZG_WEP_REQ)); + + req->slot = 3; //WEP key slot + + req->key_size = len; //FIXME: Assert 5 or 13 bytes long + req->default_key = 0; + + strncpy(req->ssid, m_ssid, ZG_SSID_LEN); + req->ssid_len = strlen(m_ssid); + + memcpy((void*)req->keys, key, len); + + //Send request + zg_mgmt_req(ZG_FIFO_MGMT_WEP_KEY, fifo_buf, sizeof(ZG_WEP_REQ)); +} + +void zg_set_wpa_pass(const char* pass) +{ + //Compute PNK key with this passphrase + //On completion, zg_on_psk_key will be called + ZG_PSK_CALC_REQ* req = (ZG_PSK_CALC_REQ*)fifo_buf; + memset((void*)req, 0, sizeof(ZG_PSK_CALC_REQ)); + + req->config = 0; + + req->phrase_len = strlen(pass); + + strncpy(req->ssid, m_ssid, ZG_SSID_LEN); + req->ssid_len = strlen(m_ssid); + + strncpy(req->pass_phrase, pass, ZG_WPA_PASS_LEN); + + //Send request + zg_mgmt_req(ZG_FIFO_MGMT_PSK_CALC, fifo_buf, sizeof(ZG_PSK_CALC_REQ)); +} + +void zg_on_psk_key(byte* buf, int len) +{ + //Now the key has been computed and we can write it + ZG_PSK_CALC_RES* res = (ZG_PSK_CALC_RES*) buf; + if( (res->result != 1) || (res->key_returned != 1) ) + { + DBG("\r\nCould not compute key, error %d\r\n", res->result); + return; //Error + } + + DBG("\r\nPMK key is :\r\n"); + hexdump(res->key, ZG_PMK_LEN); + + byte key[ZG_PMK_LEN]; + memcpy(key, res->key, ZG_PMK_LEN); + + //Send next request + zg_set_psk_key(key, ZG_PMK_LEN); +} + +void zg_set_psk_key(const byte* key, int len) +{ + ZG_PMK_REQ* req = (ZG_PMK_REQ*)fifo_buf; + memset((void*)req, 0, sizeof(ZG_PMK_REQ)); + + req->slot = 0; //WPA/WPA2 PSK slot + + strncpy(req->ssid, m_ssid, ZG_SSID_LEN); + req->ssid_len = strlen(m_ssid); + + memcpy(req->key, key, ZG_PMK_LEN); + + //Send request + zg_mgmt_req(ZG_FIFO_MGMT_PMK_KEY, fifo_buf, sizeof(ZG_FIFO_MGMT_PMK_KEY)); +} + +void zg_connect(ZG_BSS_TYPE type, ZG_SECURITY security) +{ + ZG_CONNECT_REQ* req = (ZG_CONNECT_REQ*)fifo_buf; + memset((void*)req, 0, sizeof(ZG_CONNECT_REQ)); + + req->security = security; + + strncpy(req->ssid, m_ssid, ZG_SSID_LEN); + req->ssid_len = strlen(m_ssid); + + req->sleep_duration = HTODS( 0 ); + + req->bss_type = type; + + //Send request + zg_mgmt_req(ZG_FIFO_MGMT_CONNECT, fifo_buf, sizeof(ZG_CONNECT_REQ)); +} + +void zg_on_connect(zg_err result) +{ + connection_result = result; +} + +zg_err zg_get_connection_result() +{ + return connection_result; +} + +void zg_disconnect() +{ + ZG_DISCONNECT_REQ* req = (ZG_DISCONNECT_REQ*)fifo_buf; + memset((void*)req, 0, sizeof(ZG_DISCONNECT_REQ)); + + req->reason_code = HTODS( 0 ); + req->disconnect = true; + req->deauth_frame = true; + + //Send request + zg_mgmt_req(ZG_FIFO_MGMT_DISC, fifo_buf, sizeof(ZG_DISCONNECT_REQ)); + + connection_result = (zg_err)0; +} + +#endif