/
wl_api.h
1687 lines (1498 loc) · 60.4 KB
/
wl_api.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* Programming interface for wl_api.
* Copyright (C) 2010 HD Wireless AB
*
* You should have received a copy of the license along with this library.
*/
/*! \file wl_api.h *************************************************************
*
* \brief Basic WiFi API
*
* This file provides the wl_api interface.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices:
* \li SPB104 + EVK1100
* \li SPB104 + EVK1101
* \li SPB104 + EVK1104
* \li SPB104 + EVK1105 (SPI)
* \li SPB104 + EVK1105 (SPI + irq)
* \li SPB105 + EVK1105 (SPI)
* - AppNote:
*
* \author H&D Wireless AB: \n
*
*****************************************************************************
*
* \section intro Introduction
* This is the documentation for the generic WiFi Driver API \a wl_api.
*
* \section files Main Files
* - wl_api.h : WiFi driver interface.
* - lib_ucr*_hd_wifi_standalone_v*.*.a - Driver library.
*
*/
/** \mainpage wl_api Reference Manual
\image html images/wl_api_block_diagram_small.png "wl_api Architecture"
(o)WL API © is a programming interface for WiFi (802.11). It aims
to be a complete interface for embedded applications wanting to use
wireless as a communications interface. (o)WL API © is shortened
"wl_api" in this document.
wl_api has been designed to meet the following goals :
\li Simple : The API is as simple as is practicable
to make it easy to use.
\li Minimal size : The API is usable on very resource constrained
platforms.
\li Portable : The API is deployable on any platform with a standards
compliant C compiler.
\li OS independent : The API is deployable on systems using a real time
operating system as well as with applications running on the
"bare metal" of a hardware platform (that is without an operating system).
As a consequence of these design goals wl_api does not allow very fine
grained control of most parameters relating to 802.11 networks. That
would increase the flexibility of the API while also increasing
complexity and code size. When the underlying WiFi hardware can
support a richer feature set the extra features can be offered as a
add-on library if required.
The wl_api is implemented by two libraries. The core library is
compiled for a hardware platform and is independent of operating
system or IP stack. The core library contains all WiFi
functionality. The core library is supported by a suite of transport
libraries. The transport libraries implements the hardware
communication layer and are specific to the type of hardware interface
used to connect the host platform to the WiFi hardware. For example,
there are transport libraries for SPI and for SDIO. Only the core
library has a public interface (wl_api.h) but applications will need
to link with both the core library and a transport library matching
the hardware configuration.
\section wl_api_princ Operation Principles
There are three important properties of wl_api to keep in mind when
programming with it.
The first is that wl_api is \b asynchronous. For instance, when the
\a wl_connect() function is called to attempt connection with an access
point it will trigger a sequence of packets being exchanged with the
access point after which, if everything is okay, a connection has been
established. The \a wl_connect() call is asynchronous (or non-blocking)
which means that you don't know if the connection attempt has
succeeded after the call returns. You only know if the sequence was
successfully started or not. To find out if, and when, the connection
attempt was successful you must register an event handler using the
function \a wl_register_event_cb(). This is true of a number of API calls
(which is indicated in their documentation).
The second important property is that wl_api is \b polled. wl_api
never executes "by itself", since it would then have to support
interrupts, timers, locks and other operating system dependent
features. Instead all asynchronous processes proceed when wl_api is
polled by calling the \a wl_tick() function. When \a wl_tick() is called
wl_api reacts to any received management frames, expires any internal timers and
performs any other tasks necessary for forward progress. After
\a wl_tick() returns nothing will happen unless it or some other wl_api
function is called again. Also, to send and receive data, the \a wl_process_rx()
and \a wl_process_tx() must be invoked upon reception and transmission of data.
The third important property is that wl_api is \b not \b thread \b safe.
All wl_api calls must execute in the same context since the
library has no knowledge of the locking mechanisms available (if any).
\section wl_api_code_examples A note on the code examples
The code examples illustrate how to call the different wl_api functions.
They do not constitute a complete program. Functions with the prefix "app_"
in the code examples are application specific calls that illustrate a
particular action. These functions are not part of the API and will have
to be implemented if needed. For a complete working code example see
one of the H&D Wireless software reference designs, such as the WiFi HTTP
server demo code in the Atmel Software Framework.
The API is structured into these functional groups:
\li \ref wl_api
\li \ref wl_wifi
\li \ref wl_data
\li \ref wl_transport
\li \ref wl_custom
Also documented here is the transport layers for SPI and SDIO.
There interfaces are only necessary when porting the library to
a new hardware platform.
\li \ref wl_spi
\li \ref wl_sdio
* \section contactinfo Contact Information
* For further information, visit
* <A href="http://www.hd-wireless.se/">H&D Wireless</A>.\n
* Support and FAQ: http://www.atmel.com/
*/
#ifndef WL_API_H
#define WL_API_H
#define WL_API_RELEASE_NAME "v2.7.0"
/*! Maximum size of a SSID */
#define WL_SSID_MAX_LENGTH 32
/*! Size of a MAC-address or BSSID */
#define WL_MAC_ADDR_LENGTH 6
/*! Maximum length of a passphrase */
#define WL_MAX_PASS_LEN 64
/*! Indicates that there is no SNR information */
#define WL_SNR_UNKNOWN -128
#define SPB104 104
#define SPB105 105
/*! \ingroup wl_api
* API Error codes */
typedef enum {
WL_FAILURE = -1,
WL_SUCCESS = 1,
WL_NOEFFECT,
WL_OOM,
WL_INVALID_LENGTH,
WL_NOT_SUPPORTED,
WL_ABSORBED,
WL_RESOURCES,
WL_BUSY,
WL_RETRY, /*!< Retry the operation later. The driver is busy
resolving an operation that conflicts with the
request. */
WL_INVALID_ARGS,
WL_AVAIL,
WL_CARD_FAILURE, /*!< Could not detect SPB device */
WL_FIRMWARE_INVALID, /*!< Invalid firmware data */
} wl_err_t;
/*! \ingroup wl_wifi
* Event identifiers */
enum wl_event_id_t {
WL_EVENT_MEDIA_CONNECTED = 0,
WL_EVENT_CONN_FAILURE,
WL_EVENT_MEDIA_DISCONNECTED,
WL_EVENT_SCAN_COMPLETE,
WL_EVENT_FAILURE,
MAX_WL_EVENT
};
/*! \ingroup wl_wifi
* Authentication modes */
enum wl_auth_mode {
AUTH_MODE_INVALID,
AUTH_MODE_AUTO,
AUTH_MODE_OPEN_SYSTEM,
AUTH_MODE_SHARED_KEY,
AUTH_MODE_WPA,
AUTH_MODE_WPA2,
AUTH_MODE_WPA_PSK,
AUTH_MODE_WPA2_PSK
};
/*! \ingroup wl_wifi
* Encryption modes */
enum wl_enc_type { /* Values map to 802.11 encryption suites... */
ENC_TYPE_WEP = 5,
ENC_TYPE_TKIP = 2,
ENC_TYPE_CCMP = 4,
/* ... except these two, 7 and 8 are reserved in 802.11-2007 */
ENC_TYPE_NONE = 7,
ENC_TYPE_AUTO = 8
};
enum wl_host_attention_mode {
WL_HOST_ATTENTION_SDIO = 0x1, /*!< For SDIO or polled SPI */
WL_HOST_ATTENTION_SPI = 0x5a /*!< For SPI with interrupt line */
};
/*! \ingroup wl_wifi
* Event descriptor
*/
struct wl_event_t {
enum wl_event_id_t id; /**< Event identifier. */
};
/*! \ingroup wl_wifi
* Infrastructure (ESS) or Ad-hoc (IBSS) connection modes.
*/
enum wl_conn_type_t {
WL_CONN_TYPE_INFRA, /*!< For infrastructure mode (default) */
WL_CONN_TYPE_ADHOC /*!< For ad-hoc mode */
};
/* Note:
* If your environment does not have stdint.h you will have to
* define the fixed-width integer types specified in that file
* yourself, make sure that those definitions are included
* before any inclusions of wl_api.h, and build with the macro
* WITHOUT_STDINT defined. In this case the wl_api library
* must have been built with the same integer type definitions.
*/
#ifndef WITHOUT_STDINT
#include <stdint.h>
#endif
/* Note:
* If your environment does not have stdio.h you will have to define
* the size_t type yourself, make sure that that definition is
* included before any inclusions of wl_api.h, and build with the
* macro WITHOUT_STDIO defined. In this case the wl_api library must
* have been built with the same size_t type definition.
*/
#ifndef WITHOUT_STDIO
#include <stdio.h>
#endif
/*! \ingroup wl_wifi
*
* \brief SSID representation.
*
* The SSID is a binary string and cannot be treated as a
* C-string safely. An empty SSID is represented by a
* SSID struct with the len field set to 0.
*/
struct wl_ssid_t
{
char ssid[WL_SSID_MAX_LENGTH]; /**< Octet array containing the SSID data. */
uint8_t len; /**< Length of valid data in ssid member.
* Cannot be longer than WL_SSID_MAX_LENGTH. */
};
/*! \ingroup wl_wifi
*
* MAC-address/BSSID representation
*
* A broadcast BSSID is one with all octets set to 0xFF.
*/
struct wl_mac_addr_t
{
uint8_t octet[WL_MAC_ADDR_LENGTH]; /**< Octet array containing the MAC address
* data. This array is always WL_MAC_ADDR_LENGTH bytes.
*/
};
/*! \ingroup wl_wifi
*
* Network representation
*
*/
struct wl_network_t
{
struct wl_ssid_t ssid; /**< The SSID of the network. */
struct wl_mac_addr_t bssid; /**< The BSSID of the network. */
uint8_t channel; /**< The wlan channel which the network uses */
uint32_t beacon_period; /**< Beacon period for the network */
uint16_t dtim_period; /**< DTIM period for the network */
int32_t rssi; /**< Received Signal Strength in dBm (measured on beacons) */
int32_t snr; /**< Received Signal to noise ratio in dBm (measured on beacons) */
uint8_t enc_type; /**< The encryption type used in the network. */
enum wl_conn_type_t net_type; /**< Type of network (Infrastructure or Ad-Hoc */
size_t ie_len; /**< Always 0 unless wl_api has been built with WL_CONFIG_WPA_SUPPLICANT */
uint8_t ie[0]; /**< Not used unless wl_api has been built with WL_CONFIG_WPA_SUPPLICANT */
};
/*! \ingroup wl_wifi
* Network list representation. Array of pointers to wl_network_t entries.
*
*/
struct wl_network_list_t
{
struct wl_network_t **net; /**< The list of pointers to networks */
size_t cnt; /**< Number of networks */
};
#define WL_RATE_1MBIT 2
#define WL_RATE_2MBIT 4
#define WL_RATE_5_5MBIT 11
#define WL_RATE_6MBIT 12
#define WL_RATE_9MBIT 18
#define WL_RATE_11MBIT 22
#define WL_RATE_12MBIT 24
#define WL_RATE_18MBIT 36
#define WL_RATE_22MBIT 44
#define WL_RATE_24MBIT 48
#define WL_RATE_33MBIT 66
#define WL_RATE_36MBIT 72
#define WL_RATE_48MBIT 96
#define WL_RATE_54MBIT 108
#define WL_RATE_NUM_RATES 14
#define WL_RATE_INVALID WL_RATE_NUM_RATES
/*! \ingroup wl_wifi
*
* Rate representation
*
*/
typedef uint8_t wl_rate_t;
/** \defgroup wl_api Library support functions
*
* These functions manage the library in general. They concern initalizing
* the library, downloading firmware to the WiFi chip and handling events
* from the library.
For this example we assume that the application is running stand-alone
without an operating system.
Before the library can do anything it needs to start up the WiFi
hardware by downloading a firmware image. The firmware image is
relatively big (around 144kB) and is therefore not included in the library
it is only needed once. It is up to the application to decide where to
store the firmware image and how to read it into the wl_api library.
Step one is to write a function of the type \a ::wl_fw_read_cb_t
that wl_api will call to retrive the firmware image. Assuming that you
have some spare RAM (or whatever memory type is used for read only
data, such as FLASH memory) on your platform you can simply include
the firmware image from the \a wl_fw.h header file and write a
firmware read function like this
\code
static size_t fw_read_cb(void* ctx,
uint8_t** buf,
size_t offset,
size_t len)
{
if ( NULL == buf ) {
return 0;
}
*buf = ((uint8_t*) fw_buf) + offset;
if ( len > ( fw_len - offset ) ) {
return fw_len - offset;
}
return len;
}
\endcode
If the firmware image is stored in ROM this function may have to read
it back block by block instead.
First, firmware must be downloaded to the device
\code
if ( wl_transport_init(fw_read_cb, NULL, &mode) != WL_SUCCESS ) {
app_error("Firmware download failed");
return 0;
}
\endcode
The wl_api library is then initialized like this
\code
if ( wl_init(NULL, init_complete_cb, mode) != WL_SUCCESS ) {
app_error("Init failed");
return 0;
}
\endcode
The library startup process will now require \a wl_poll() to be called
a number of times before it can complete. In addition, if the
application needs to know when the startup process has completed so
that it can, for example, start up an IP stack it will have to supply
a valid callback function of the type \a ::wl_init_complete_cb_t as a parameter
to the \a wl_init() call and start polling the wl_api library.
The init complete callback will only be executed during a call to \a wl_poll()
or another wl_api function. This simplifies the implementation since no
internal locking is required and the wl_api library becomes OS-independent.
\code
static void init_complete_cb(void* ctx) {
init_ip_stack();
}
\endcode
Registering the event callback is straightforward :
\code
if (wl_register_event_cb(event_cb, NULL) != WL_SUCCESS) {
app_error("Failed to register event handler");
return 0;
}
\endcode
Similar to \a wl_poll(), there is also a \a wl_tick() function that takes a
free running "tick" counter with millisecond resolution as an argument so
that it can trigger internal timers when necessary. Assuming that such a tick
counter is provided by the macro GET_MS_TICK() the wl_api execution loop becomes
\code
while (TRUE) {
wl_tick(GET_MS_TICK());
wl_poll();
}
\endcode
In a stand-alone application this loop would usually be the main application
loop and include application specific calls as well.
After some number of main loop iterations the init_complete_cb will be
invoked and the application can initialize its IP stack.
* @{
*/
/*! \brief WiFi event callback.
*
* This function receives WiFi events that the application
* wants notification of. This function is supplied by the user
* of the API.
*
* @param event Struct describing the type of event and, for some
* events, additional information regarding the
* status of the event. See wl_event_t for additional
* information.
* @param ctx A context handle. This handle is passed
* untouched to the callback and has the same value
* as the context registered with the callback in
* wl_register_event_cb().
*/
typedef void (*wl_event_cb_t) (struct wl_event_t event, void* ctx);
/*! \brief Initialization complete callback function.
*
* Invoked when WiFi initialization is complete.
*
* @param ctx Opaque context pointer as provided to \a wl_init() that will be
* passed back to the callback.
*/
typedef void (wl_init_complete_cb_t)(void* ctx);
/*! \brief Register an event handler.
*
* Register an event handler with the driver. This
* event handler will be called whenever a event
* listed in #wl_event_id_t occurs.
* See #wl_event_cb_t and #wl_event_id_t for more details.
*
* @param cb Event callback function to register.
* @param ctx Opaque context pointer that will be
* passed to the callback when it is
* invoked. This parameter is never
* accessed by the API.
* @return WL_SUCCESS
*/
wl_err_t wl_register_event_cb(wl_event_cb_t cb, void* ctx);
/*! \brief Initialize the wl_api library.
*
* Note that \a wl_poll() must be called for this function to progress
* towards complete init
*
* The startup process will proceed asynchronously and will inkove
* init_complete_cb when completed. The callback will not be invoked if any
* error occurs during initialization.
*
* This function should be called after firmware has been downloaded to the
* device.
*
* @param ctx Opaque context pointer that will be passed to the callback
* when invoked. This parameter is never accessed by the API.
* @param init_complete_cb callback function to invoke when initialization is
* complete.
* @param mode Indicates the host attention mode used by the device. If
* \a wl_transport_init() was used to download the firmware image to the
* device, the proper mode can be obtained from the mode parameter of
* that function.
*
* @return
* - WL_SUCCESS
* - WL_FAILURE
*/
wl_err_t wl_init(void* ctx, wl_init_complete_cb_t init_complete_cb,
enum wl_host_attention_mode mode);
/*! \brief Shutdown the wl_api library and free resources.
*
* \a wl_init() must be invoked to startup the library
* again.
*
* @return
* - WL_SUCCESS on success
* - WL_FAILURE
*
*/
wl_err_t wl_shutdown(void);
/*! \brief WiFi driver timer tick function
*
* Periodic timers are triggered from this function so it should be called as
* often as possible if precision timing is required (traffic timeouts,
* authentication timeouts etc).
*
* @param tick A tick count in us. This is used to expire timers
* in the driver.
*/
void wl_tick(uint32_t tick);
/*! @} */
/** \defgroup wl_wifi Connection Management
*
* These functions access WiFi-specific functionality such as
* scanning, connect/disconnect, authentication and encryption,
* and power save modes.
*
\section scanning Scanning
To scan all channels that are available in the current regulatory
domain
\code
if ( wl_scan() != WL_SUCCESS ) {
// May be busy scanning already, no fatal error
return 0;
}
\endcode
Since wl_scan() only starts the scanning process the application
should add code to the event handler to catch the "scan complete" event
and retrieve the list of seen networks from the library
\code
static void event_cb(struct wl_event_t event, void* ctx) {
switch(event.id) {
case WL_EVENT_SCAN_COMPLETE:
struct wl_network_list_t *netlist;
uint8_t netcnt;
wl_get_network_list(&netlist);
netcnt = netlist->cnt;
while (--netcnt) {
print_network(netlist->net[netcnt]);
}
break;
}
}
\endcode
The function print_network() could display the network name, the SSID, in
a user interface. It is important to keep in mind is that despite the fact
that the SSID is usually presented as a ASCII string, it is
in fact just a byte string and can legally contain all kinds of
non-printable characters, including a 0-byte. This means that it is
easy to end up with buffer overrun bugs if the SSID is ever treated
as a normal string without precautions.
\code
void print_network(struct wl_network_t* wl_network)
{
char ssid[WL_SSID_MAX_LENGTH + 1];
memset(ssid, 0, sizeof(ssid));
memcpy(ssid, wl_network->ssid.ssid, wl_network->ssid.len);
if (app_is_printable(ssid)) {
app_print("\"%s\" ", ssid);
}
else {
app_print("<binary SSID> ");
}
switch (wl_network->enc_type) {
case ENC_TYPE_WEP :
app_print("(WEP encryption)");
break;
case ENC_TYPE_TKIP :
app_print("(TKIP encryption)");
break;
case ENC_TYPE_CCMP :
app_print("(CCMP encryption)");
break;
}
app_print("\n");
}
\endcode
\section connecting Connecting
To connect to an access point (beware binary SSIDs) the connection process
must be started
\code
if ( wl_connect("My AP", strlen("My AP"))
!= WL_SUCCESS ) {
app_error("Connection failed.\n");
return 0;
}
\endcode
and the \a WL_EVENT_MEDIA_CONNECTED and \a WL_EVENT_CONN_FAILURE events should be
caught. To detect that a connection is terminated after it has been successfully established
(such as when the AP goes out of range) the \a WL_EVENT_MEDIA_DISCONNECTED event
must be also be caught
\code
static void event_cb(struct wl_event_t event, void* ctx) {
switch(event.id) {
case WL_EVENT_SCAN_COMPLETE:
struct wl_network_list_t *netlist;
uint8_t netcnt;
wl_get_network_list(&netlist);
netcnt = netlist->cnt;
while (--netcnt) {
print_network(netlist->net[netcnt]);
}
break;
case WL_EVENT_CONN_FAILURE:
app_error("Connection failed\n");
break;
case WL_EVENT_MEDIA_CONNECTED:
app_print("Connected to Access Point\n");
app_ip_interface_up();
break;
case WL_EVENT_MEDIA_DISCONNECTED:
app_print("Disconnected from Access Point\n");
app_ip_interface_down();
break;
}
}
\endcode
\section security Security
To use WEP a WEP key must be added before the connection is initiated.
To set the 40-bit WEP key 0xDEADBEEF00 as default key for key index 0 do
\code
char key[5] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00 };
struct wl_mac_addr_t bssid;
// This means that the bssid is a broadcast bssid and the WEP key will be a default key instead of a key-mapping key.
memset(&bssid.octet, 0xff, sizeof bssid.octet);
if ( wl_add_wep_key(0, sizeof key, key, &bssid)
!= WL_SUCCESS ) {
app_error("Failed to add WEP key.");
return 0;
}
\endcode
To use WPA/WPA2 with a Pre-shared key a passphrase must be associated
with the network before the connection is initiated.
\code
struct wl_network_t net;
char passphrase[] = "MySecretKey";
memset(&net, 0, sizeof net);
memset(net.bssid.octet, 0xFF, sizeof net.bssid.octet);
strncpy(net.ssid.ssid, "My AP", strlen("My AP"));
net.ssid.len = strlen("My AP");
net.enc_type = ENC_TYPE_AUTO;
if (wl_set_passphrase(&net,
passphrase,
strlen(passphrase),
ENC_TYPE_AUTO,
AUTH_MODE_AUTO)
!= WL_SUCCESS) {
app_error("Failed to add passphrase");
}
\endcode
The library supports several passphrase-network associations to be
configured simultaneously. Be aware that the \a wl_connect() call
can take up to 15 seconds longer than normal when using a pre-shared
WPA/WPA2 key since the platform must calculate a temporal encryption
key from the passphrase before the connection attempt can start.
* @{
*/
/*! \brief Scan all channels.
*
* Starts a scan of all WiFi channels allowed in this regulatory
* domain. The list of allowed channels (the domain) is adapted to the
* channels announced as allowed by the first AP heard.
*
* The scan will proceed asynchronously and will raise a
* WL_EVENT_SCAN_COMPLETE event when completed.
*
* Currently, there's a limit on the scan list size that depends on the
* architecture (6 networks for the AVR32 UCR1 architecture 16 networks for
* other architectures. If more network exist, the strongest networks are
* chosen. Note that the limitation on the scan list size does not limit the
* networks which the device can connect to. See wl_connect() for more
* details.
*
* @return
* - WL_SUCCESS
* - WL_FAILURE.
*/
wl_err_t wl_scan(void);
/*! \brief Get the list of currently known networks.
*
* Retrieves the list of currently known networks from
* the driver. To ensure that this list is up-to-date
* a wl_scan() call should be issued and this function
* should be called upon reception of the WL_EVENT_SCAN_COMPLETE
* event. This function can be called at other times
* but the list of networks retrieved then might not
* correspond to the networks actually in range.
*
* Note that a successful scan does not necessarily
* find any networks.
*
* @param network_list Output buffer. The API call returns
* a pointer to allocated memory containing the network list.
* @return
* - WL_SUCCESS
* - WL_FAILURE.
*/
wl_err_t wl_get_network_list(struct wl_network_list_t **network_list);
#ifdef WFE_6_12
/*! \brief Start a Ad-hoc network.
*
* Attempt to start a Ad-hoc (IBSS) network. If a Ad-hoc network
* is successfully started then a WL_EVENT_MEDIA_CONNECTED event
* will be raised once the first peer station connects to the Ad-hoc
* network (and not when the network is announced on the air).
*
* If a Ad-hoc network should be started with encryption
* enabled then \a wl_set_passphrase() should be called before
* \a wl_start_adhoc_net() to configure the security parameters.
* The Ad-hoc network is started with the security parameters
* (if any) that was configured for the specified \a ssid.
*
* @param ssid The SSID of the new network. If there's a network
* already present with this SSID this call will fail.
* @param channel The channel to use. Valid channels are 1-14
* @param auth_mode The authentication mode to use. Supported
* authentication modes for Ad-hoc networks are
* AUTH_MODE_OPEN_SYSTEM and AUTH_MODE_SHARED_KEY.
* Passing other modes will cause a WL_INVALID_ARGS return.
* If AUTH_MODE_SHARED_KEY is used then a valid WEP
* key must be set with a call to \a wl_add_wep_key()
* and the default WEP key index must be set with a
* call to \a wl_set_default_wep_key().
* @return
* - WL_SUCCESS on success.
* - WL_INVALID_ARGS if the ssid is malformed, if
* the channel not valid or if the authentication mode
* is invalid.
* - WL_RETRY if the driver is busy resolving a conflicting
* operation. The operation should be retried after a wait
* (at least one call to wl_poll() for polled implementations).
* - WL_BUSY if the driver is already connected or if a network
* with the same SSID is already known.
*
*/
wl_err_t wl_start_adhoc_net(struct wl_ssid_t ssid,
uint8_t channel,
enum wl_auth_mode auth_mode);
#endif
/*! \brief Connect to a SSID.
*
* Attempt to connect to a given SSID. If the driver is already
* connected to an AP with a different SSID then this call will
* return WL_BUSY and wl_disconnect() should be called before
* trying again.
*
* The connection process will proceed asynchronously and will raise a
* WL_EVENT_MEDIA_CONNECTED event when completed, or a WL_EVENT_CONN_FAILURE
* when failed. After a WL_EVENT_MEDIA_CONNECTED event has been raised
* a WL_EVENT_MEDIA_DISCONNECT event will be raised if the connection is
* terminated. Note that this can be caused by external factors and can
* happen at any time.
*
* If wl_connect() is invoked with a network that is not shown in the
* scan list, the device will probe for that specific network and connect
* to it, if found. This is also the method to use in order to connect to
* "hidden" networks (AP's that doesn't broadcast its SSID).
*
* @param ssid Pointer to the SSID string.
* Freed by caller.
* @param ssid_len Length of the SSID string in octets. Max value is 32.
* @return
* - WL_SUCCESS
* - WL_FAILURE if the network could not be found
* - WL_BUSY if the driver is already connected
* - WL_RETRY if the driver is busy resolving a conflicting operation.
* The operation should be retried after a wait (at least one call to wl_poll()
* for polled implementations).
*/
wl_err_t wl_connect(char* ssid, size_t ssid_len);
/*! \brief Connect to a BSSID
*
* Attempt to connect to a given BSSID. If the driver is already
* connected to an AP with a different BSSID then this call will
* return WL_BUSY and wl_disconnect() should be called before
* trying again.
*
* The connection process will proceed asynchronously and will raise a
* WL_EVENT_MEDIA_CONNECTED event when completed, or a WL_EVENT_CONN_FAILURE
* when failed. After a WL_EVENT_MEDIA_CONNECTED event has been raised
* a WL_EVENT_MEDIA_DISCONNECT event will be raised if the connection is
* terminated. Note that this can be caused by external factors and can
* happen at any time.
*
* If wl_connect_bssid() is invoked with a network that is not shown in the
* scan list, the device will probe for that specific network and connect
* to it, if found.
*
* @param bssid Pointer to the BSSID. Freed by caller.
* @return
* - WL_SUCCESS
* - WL_FAILURE if the network could not be found
* - WL_BUSY if the driver is already connected
* - WL_RETRY if the driver is busy resolving a conflicting operation.
* The operation should be retried after a wait (at least one call to wl_poll()
* for polled implementations).
*/
wl_err_t wl_connect_bssid(struct wl_mac_addr_t bssid);
/*! \brief Disconnect from the network
*
* Disconnect from any currently associated network.
*
* The disconnection process will proceed asynchronously and will raise a
* WL_EVENT_MEDIA_DISCONNECTED event when completed.
* @return
* - WL_SUCCESS if the disconnect process was started
* - WL_FAILURE if the driver was not connected
* - WL_RETRY if the driver is in the process of connecting.
* In this case the disconnect must be retried after
* the connection attempt has completed (resulted in a
* WL_EVENT_MEDIA_CONNECTED or a WL_EVENT_CONN_FAILURE event).
*/
wl_err_t wl_disconnect(void);
/*!
* @brief Add a WEP encryption key to the device.
*
* Configure a key into the device. The key type (WEP-40, WEP-104)
* is determined by the size of the key (5 bytes for WEP-40, 13 bytes for WEP-104).
*
* @param key_idx The key index to set. Valid values are 0-3.
* @param key_len Length of key in bytes. Valid values are 5 and 13.
* @param key Key input buffer.
* @param bssid BSSID that the key applies to. If this is
* the broadcast BSSID then the key is configured
* as one of the default keys (not _the_ default key,
* this must be set by calling set_default_wep_key()
* after adding it). If the BSSID is a valid unicast
* bssid then the key is configured as a key-mapping
* key ( See 802.11-2007 8.2.1.3 ).
* @return
* - WL_SUCCESS on success.
* - WL_INVALID_LENGTH if the key length is bad.
* - WL_FAILURE on failure
*/
wl_err_t wl_add_wep_key(uint8_t key_idx,
size_t key_len,
const void *key,
struct wl_mac_addr_t *bssid);
/*! @brief Set the default WEP key index.
*
* Select which WEP key to use for transmitted packets.
* For this to work correctly you must have added a WEP
* key with \a wl_add_wep_key() as a default key, using the
* same index as the one set in this call.
* @param key_idx Index of the key to make the default key.
* Valid values are 0-3.
* @return WL_SUCCESS or WL_FAILURE.
*/
wl_err_t wl_set_default_wep_key(uint8_t key_idx);
/*! \brief Delete a WEP key.
*
* Deletes a WEP key from the driver.
*
* @param key_idx The index of the key to delete. Valid values are 0-3.
* @param bssid BSSID that the key applies to. If this is
* the broadcast BSSID then the key deleted is a default key.
* If the BSSID is a valid unicast bssid then the deleted
* key is a key-mapping key.
* @return WL_SUCCESS or WL_FAILURE
*/
wl_err_t wl_delete_wep_key(uint8_t key_idx, struct wl_mac_addr_t *bssid);
/*! @brief Set a WPA/WPA2 passphase
*
* Associate a WPA/WPA2/RSN passphrase with a network.
* The number of passphrases that can be stored can
* vary but is always at least one. Passphrases can
* be added until \a wl_add_wpa_passphrase() returns
* WL_RESOURCES.
*
* @param net Network with which to associate the passphrase.
* @param passphrase Passphrase. Valid characters in a passphrase
* must lie between ASCII 32-126 (decimal).
* @param len Length of passphrase. Valid lengths are 8-63.
* @param enc_type Encryption type. If this is set to ENC_TYPE_AUTO
* then the most secure supported mode will be automatically
* selected. Normally you only need to pass something else here
* if you need to enforce picking a certain encryption mode when
* the network supports several modes and you don't want to use
* the best one.
* @param auth_mode Authentication mode. If this is set to AUTH_MODE_AUTO
* then the most secure mode will be automatically selected.
* Normally you only need to pass something else here if the network
* announces support for both WPA and WPA2/RSN and the passphrases are
* different.
* @return
* - WL_SUCCESS
* - WL_INVALID_ARGS if the passphrase length is invalid.
* - WL_RESOURCES if no more passphrases can be added.
*/
wl_err_t wl_set_passphrase(const struct wl_network_t *net,
const char *passphrase,
const size_t len,
const enum wl_enc_type enc_type,
const enum wl_auth_mode auth_mode);
/*! @brief Remove a WPA/WPA2 passphase
*
* Remove a WPA/WPA2/RSN passphrase associated with a network.
*
* @param net Network with which to associate the passphrase.
* If net is NULL then all stored passphrases will be
* cleared.
* @return
* - WL_SUCCESS
* - WL_FAILURE if no passphrase was associated with the net.
*/
wl_err_t wl_clear_passphrase(struct wl_network_t *net);
/*! \brief Enable legacy power save mode
*
* Enable legacy power save mode. In legacy power save mode, the device
* will power down when idle. When connected, the device will wake up to
* receive beacon frames and any buffered data from the AP. The response
* time when legacy power save is enabled might therefore be as long as the
* AP beacon interval (mostly 100 ms). However, the throughput should not
* be affected.
*
* @return WL_SUCCESS or WL_FAILURE.
*/
wl_err_t wl_enable_ps(void);
/*! \brief Disable legacy power save mode
*
* @return WL_SUCCESS or WL_FAILURE.
*/
wl_err_t wl_disable_ps(void);