ZG2100 Network interface source

Revision:
0:b802fc31f1db
Child:
1:3a7c15057192
--- /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