1 #include <VP_Com/vp_com_error.h>
2 #include <VP_Com/vp_com_socket.h>
4 #include "vp_com_wifi.h"
5 #include "vp_com_config_itf.h"
7 #include <VP_Os/vp_os_malloc.h>
8 #include <VP_Os/vp_os_print.h>
9 #include <VP_Os/vp_os_delay.h>
11 #define PROC_NET_DEV "/proc/net/dev"
14 #include <sys/socket.h>
15 #include "vp_com_interface.h"
19 #include "vp_com_wlc.h"
27 #include <netinet/in.h>
30 C_RESULT vp_com_wf_init(void)
35 C_RESULT vp_com_wf_shutdown(void)
40 C_RESULT vp_com_wf_network_adapter_lookup(vp_com_network_adapter_lookup_t callback)
44 FILE* fh = fopen( PROC_NET_DEV, "r" );
48 // eat first two lines
49 if( fgets( buff, sizeof(buff), fh ) && fgets( buff, sizeof(buff), fh ) )
51 while( fgets( buff, sizeof(buff), fh ) )
53 // Do parsing here and invoke callback if an interface matches our needs
63 C_RESULT vp_com_wf_inquire(const char* deviceName, vp_com_inquiry_t callback, uint32_t timeout)
69 C_RESULT vp_com_wf_local_config(vp_com_wifi_config_t* cfg)
71 C_RESULT res = VP_COM_ERROR;
74 // wl_scan_results_t* scan_results;
75 // wl_bss_info_t* bss; uint8_t* ptr;
77 // uint32_t channels_load[10], channel_load, next_channel_load;
80 DEBUG_PRINT_SDK("vp_com_wf_local_config\n");
82 vp_com_config_itf( cfg->itfName, cfg->localHost, cfg->broadcast, cfg->netmask );
84 VP_WLC_BEGIN( cfg->itfName )
86 if( vp_wlc_get_magic() == WLC_IOCTL_MAGIC )
89 vp_wlc_set_country( cfg->country );
92 if( vp_wlc_get_radio() != VP_WLC_RADIO_ENABLE )
93 vp_wlc_set_radio(VP_WLC_RADIO_ENABLE);
96 /* for( i = 1; i < 10; i++ )
99 if( vp_wlc_scan() == 0 )
101 vp_com_wait_scan_complete();
102 scan_results = vp_wlc_get_scan_results();
104 PRINT("Wifi scan gave %d results\n", scan_results->count);
106 ptr = (void*)&scan_results->bss_info[0];
107 for(i=0; i < scan_results->count; i++)
109 int32_t index_min, index, index_max;
111 bss = (wl_bss_info_t*) ptr;
112 ptr = (uint8_t*)bss + bss->length;
114 index = bss->chanspec & WL_CHANSPEC_CHAN_MASK;
120 channels_load[index] += 5;
122 channels_load[index_min] += 3;
124 channels_load[index_max] += 3;
127 PRINT("\t-bss %s on channel %d\n", bss->SSID, bss->chanspec & WL_CHANSPEC_CHAN_MASK );
130 channels_load[0] = 1;
131 channel_load = channels_load[1] + channels_load[2];
133 for( i = 2; i < 9; i++ )
135 next_channel_load = channels_load[i-1] + channels_load[i] + channels_load[i+1];
137 if( channel_load > next_channel_load )
139 channel_load = next_channel_load;
140 channels_load[0] = i;
144 next_channel_load = channels_load[8] + channels_load[9];
145 if( channel_load > next_channel_load )
147 channel_load = next_channel_load;
148 channels_load[0] = 9;
151 vp_wlc_set_channel( channels_load[0] );
153 PRINT("Setting channel %d\n", channels_load[0]);
158 vp_wlc_set_infrastructure( (cfg->infrastructure == 1) ? VP_WLC_INFRASTRUCTURE : VP_WLC_ADHOC );
159 vp_wlc_set_authentication( (cfg->secure == 1) ? VP_WLC_AUTH_SHARED : VP_WLC_AUTH_OPEN );
173 C_RESULT vp_com_wf_local_config(vp_com_wifi_config_t* cfg)
177 int16_t key_flags = 0;
178 wireless_config iwconf;
180 // If network is secure, configure it now.
181 if(cfg && cfg->secure==1)
183 vp_com_config_itf( cfg->itfName, cfg->localHost, cfg->broadcast, cfg->netmask );
185 wlsock = iw_sockets_open();
187 res = ( wlsock < 0 ) ? VP_COM_ERROR : VP_COM_OK;
190 iw_get_basic_config( wlsock, cfg->itfName, &iwconf );
196 // After watching Linux/kernel/linux/drivers/parrot/net/wireless/ar6000/ar6000/wireless.ext:1041
197 // it appears we need to clear ssid before setting passkey
198 // if (ar->arSsidLen) {
201 // So we do set passkey in two passes, first clear ssid then set new passkey
203 iwconf.has_essid = 1;
205 vp_os_memset( &iwconf.essid[0], 0, IW_ESSID_MAX_SIZE+1 );
207 res = iw_set_basic_config( wlsock, cfg->itfName, &iwconf ) < 0 ? C_FAIL : C_OK;
210 iwconf.has_essid = 0;
215 iwconf.key_size = iw_in_key_full( wlsock, cfg->itfName, cfg->passkey, (char*)&iwconf.key, &key_flags );
216 iwconf.key_flags = IW_ENCODE_ENABLED | IW_ENCODE_RESTRICTED;
220 vp_os_memset(&iwconf.key[0], 0, IW_ENCODING_TOKEN_MAX);
221 iwconf.key_flags = IW_ENCODE_DISABLED;
224 res = iw_set_basic_config( wlsock, cfg->itfName, &iwconf ) < 0 ? C_FAIL : C_OK;
226 iw_sockets_close(wlsock);
236 C_RESULT vp_com_wf_local_config(vp_com_wifi_config_t* cfg)
244 C_RESULT vp_com_wf_connect(vp_com_t* vp_com, vp_com_wifi_connection_t* connection, int32_t numAttempts)
246 C_RESULT res = VP_COM_ERROR;
247 ///struct bootp* bootp_data = NULL;
248 vp_com_wifi_config_t* config = (vp_com_wifi_config_t*) vp_com->config;
256 DEBUG_PRINT_SDK("vp_com_wf_connect\n");
258 VP_WLC_BEGIN(config->itfName)
267 vp_wlc_set_ssid(connection->networkName);
269 vp_com_wait_set_ssid();
272 while( ((ret = vp_wlc_get_bssid(&bdaddr)) < 0) && attempt < 10 );
282 vp_wlc_disable_roaming();
290 PRINT("STA - Joined essid %s\n", connection->networkName);
292 PRINT("AP - Created essid %s\n", connection->networkName);
297 DEBUG_PRINT_SDK("vp_com_wf_connect failed\n");
304 C_RESULT vp_com_wf_connect(vp_com_t* vp_com, vp_com_wifi_connection_t* connection, int32_t numAttempts)
308 vp_com_wifi_config_t* config = (vp_com_wifi_config_t*)vp_com->config;
309 wireless_config iwconf;
311 wlsock = iw_sockets_open();
313 res = ( wlsock < 0 ) ? VP_COM_ERROR : VP_COM_OK;
316 iw_get_basic_config( wlsock, config->itfName, &iwconf );
323 iwconf.mode = config->infrastructure ? IW_MODE_INFRA : IW_MODE_ADHOC;
325 iwconf.has_essid = 1;
328 // No need to set the network name if it has not change.
329 if(strcmp(&iwconf.essid[0], connection->networkName)!=0)
331 strncpy( &iwconf.essid[0], connection->networkName, IW_ESSID_MAX_SIZE+1 );
333 res = iw_set_basic_config( wlsock, config->itfName, &iwconf ) < 0 ? C_FAIL : C_OK;
345 iw_sockets_close(wlsock);
351 C_RESULT vp_com_wf_connect(vp_com_t* vp_com, vp_com_wifi_connection_t* connection, int32_t numAttempts)
359 C_RESULT vp_com_wf_disconnect(vp_com_wifi_config_t* config, vp_com_wifi_connection_t* connection)
361 VP_WLC_BEGIN( config->itfName )
364 vp_wlc_set_ssid( NULL );
365 // vp_com_wait_set_ssid();
375 C_RESULT vp_com_wf_disconnect(vp_com_wifi_config_t* cfg, vp_com_wifi_connection_t* connection)
379 int16_t key_flags = 0;
380 wireless_config iwconf;
382 wlsock = iw_sockets_open();
384 VP_COM_CHECK( ( wlsock < 0 ) ? VP_COM_ERROR : VP_COM_OK );
386 vp_os_memset( &iwconf, 0, sizeof(iwconf) );
388 iwconf.has_essid = 1;
390 res = iw_set_basic_config( wlsock, cfg->itfName, &iwconf ) < 0 ? C_FAIL : C_OK;
392 iw_sockets_close(wlsock);
398 C_RESULT vp_com_wf_disconnect(vp_com_wifi_config_t* cfg, vp_com_wifi_connection_t* connection)
405 C_RESULT vp_com_wf_get_rssi(vp_com_wifi_config_t* cfg, int32_t* rssi)
411 int wlsock = iw_sockets_open();
413 vp_os_memset(&wrq, 0, sizeof(struct iwreq));
414 iw_get_stats(wlsock, cfg->itfName, &stats, &range, 1);
415 iw_sockets_close(wlsock);*/
417 // struct iw_statistics
419 // __u16 status; // Status * - device dependent for now
420 // struct iw_quality qual; // Quality of the link * (instant/mean/max)
421 // struct iw_discarded discard; // Packet discarded counts
422 // struct iw_missed miss; // Packet missed counts
428 // // Quality of link & SNR stuff */
429 // // Quality range (link, level, noise)
430 // // If the quality is absolute, it will be in the range [0 ; max_qual],
431 // // if the quality is dBm, it will be in the range [max_qual ; 0].
432 // // Don't forget that we use 8 bit arithmetics...
433 // struct iw_quality max_qual; // Quality of the link
434 // // This should contain the average/typical values of the quality
435 // // indicator. This should be the threshold between a "good" and
436 // // a "bad" link (example : monitor going from green to orange).
437 // // Currently, user space apps like quality monitors don't have any
438 // // way to calibrate the measurement. With this, they can split
439 // // the range between 0 and max_qual in different quality level
440 // // (using a geometric subdivision centered on the average).
441 // // I expect that people doing the user space apps will feedback
442 // // us on which value we need to put in each driver...
443 // struct iw_quality avg_qual; // Quality of the link
448 // __u8 qual; // link quality (%retries, SNR, %missed beacons or better...)
449 // __u8 level; // signal level (dBm)
450 // __u8 noise; // noise level (dBm)
451 // __u8 updated; // Flags to know if updated
454 //*rssi = stats.qual.qual;
459 C_RESULT vp_com_wf_wait_connections(vp_com_wifi_connection_t** c, vp_com_socket_t* server, vp_com_socket_t* client, int32_t queueLength)
461 return vp_com_wait_socket(server, client, queueLength);
464 C_RESULT vp_com_wf_open(vp_com_wifi_config_t* config, vp_com_wifi_connection_t* connection, vp_com_socket_t* sck, Read* read, Write* write)
466 return vp_com_open_socket(sck, read, write);
469 C_RESULT vp_com_wf_close(vp_com_socket_t* socket)
471 return vp_com_close_socket(socket);