add realtek_ameba package

This commit is contained in:
flyingcys 2018-06-01 12:24:02 +08:00
commit d401464b75
3406 changed files with 1112851 additions and 0 deletions

0
.gitignore vendored Normal file
View file

504
LICENSE Normal file
View file

@ -0,0 +1,504 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random
Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

2
README.md Normal file
View file

@ -0,0 +1,2 @@
# realtek_ameba
realtek_ameba package on RT-Thread

15
SConscript Normal file
View file

@ -0,0 +1,15 @@
# RT-Thread building script for bridge
import os
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')

19
rtthread_patch/SConscript Normal file
View file

@ -0,0 +1,19 @@
import rtconfig
from building import *
cwd = GetCurrentDir()
src = Split('''
os/rtthread_service.c
realtek/8711b/rtl8710b_startup.c
realtek/8711b/app_start.c
realtek/common/wifi/wifi_conf.c
''')
path = [cwd,
cwd + '/os',
cwd + '/realtek/8711b/include']
group = DefineGroup('rtt_patch', src, depend = [''], CPPPATH = path)
Return('group')

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,258 @@
#ifndef _FREERTOS_SERVICE_H_
#define _FREERTOS_SERVICE_H_
//----- ------------------------------------------------------------------
// Include Files
//----- ------------------------------------------------------------------
//#include "wireless.h"
#include "dlist.h"
// --------------------------------------------
// Platform dependent include file
// --------------------------------------------
#if defined(CONFIG_PLATFORM_8195A)
#include "platform/platform_stdlib.h"
extern VOID RtlUdelayOS(u32 us);
#elif defined(CONFIG_PLATFORM_8711B)
#include "platform/platform_stdlib.h"
#else
// other MCU may use standard library
#include <string.h>
#endif
#if (defined CONFIG_GSPI_HCI || defined CONFIG_SDIO_HCI) || defined(CONFIG_LX_HCI)
/* For SPI interface transfer and us delay implementation */
#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B)
#include <rtwlan_bsp.h>
#endif
#endif
// --------------------------------------------
// Platform dependent type define
// --------------------------------------------
#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B)
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef signed char s8;
typedef signed short s16;
typedef signed int s32;
typedef signed long long s64;
typedef unsigned long long u64;
typedef unsigned int uint;
typedef signed int sint;
#ifndef bool
typedef int bool;
#define true 1
#define false 0
#endif
#define IN
#define OUT
#define VOID void
#define NDIS_OID uint
#define NDIS_STATUS uint
#ifndef PVOID
typedef void * PVOID;
#endif
typedef unsigned int __kernel_size_t;
typedef int __kernel_ssize_t;
typedef __kernel_size_t SIZE_T;
typedef __kernel_ssize_t SSIZE_T;
#endif //CONFIG_PLATFORM_8195A
#define FIELD_OFFSET(s,field) ((SSIZE_T)&((s*)(0))->field)
// os types
typedef char osdepCHAR;
typedef float osdepFLOAT;
typedef double osdepDOUBLE;
typedef long osdepLONG;
typedef short osdepSHORT;
typedef unsigned long osdepSTACK_TYPE;
typedef long osdepBASE_TYPE;
typedef unsigned long osdepTickType;
typedef void* _timerHandle;
typedef void* _sema;
typedef void* _mutex;
typedef void* _lock;
typedef void* _queueHandle;
typedef void* _xqueue;
typedef struct timer_list _timer;
typedef struct sk_buff _pkt;
typedef unsigned char _buffer;
#ifndef __LIST_H
#warning "DLIST_NOT_DEFINE!!!!!!"
struct list_head {
struct list_head *next, *prev;
};
#endif
struct __queue {
struct list_head queue;
_lock lock;
};
typedef struct __queue _queue;
typedef struct list_head _list;
typedef unsigned long _irqL;
typedef void* _thread_hdl_;
typedef void thread_return;
typedef void* thread_context;
#define ATOMIC_T atomic_t
#define HZ configTICK_RATE_HZ
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
/* emulate a modern version */
#define LINUX_VERSION_CODE KERNEL_VERSION(2, 6, 17)
static __inline _list *get_next(_list *list)
{
return list->next;
}
static __inline _list *get_list_head(_queue *queue)
{
return (&(queue->queue));
}
#define LIST_CONTAINOR(ptr, type, member) \
((type *)((char *)(ptr)-(SIZE_T)((char *)&((type *)ptr)->member - (char *)ptr)))
//#define container_of(p,t,n) (t*)((p)-&(((t*)0)->n))
#define container_of(ptr, type, member) \
((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member)))
#define TASK_PRORITY_LOW 1
#define TASK_PRORITY_MIDDLE 2
#define TASK_PRORITY_HIGH 3
#define TASK_PRORITY_SUPER 4
#define TIMER_MAX_DELAY 0xFFFFFFFF
void save_and_cli(void);
void restore_flags(void);
void cli(void);
#ifndef mdelay
#define mdelay(t) ((t/portTICK_RATE_MS)>0)?(vTaskDelay(t/portTICK_RATE_MS)):(vTaskDelay(1))
#endif
#ifndef udelay
#define udelay(t) ((t/(portTICK_RATE_MS*1000))>0)?vTaskDelay(t/(portTICK_RATE_MS*1000)):(vTaskDelay(1))
#endif
//----- ------------------------------------------------------------------
// Common Definition
//----- ------------------------------------------------------------------
#define __init
#define __exit
#define __devinit
#define __devexit
#define KERN_ERR
#define KERN_INFO
#define KERN_NOTICE
#undef GFP_KERNEL
#define GFP_KERNEL 1
#define GFP_ATOMIC 1
#define SET_MODULE_OWNER(some_struct) do { } while (0)
#define SET_NETDEV_DEV(dev, obj) do { } while (0)
#define register_netdev(dev) (0)
#define unregister_netdev(dev) do { } while (0)
#define netif_queue_stopped(dev) (0)
#define netif_wake_queue(dev) do { } while (0)
#define printk printf
#define DBG_ERR(fmt, args...) printf("\n\r[%s] " fmt, __FUNCTION__, ## args)
#if WLAN_INTF_DBG
#define DBG_TRACE(fmt, args...) printf("\n\r[%s] " fmt, __FUNCTION__, ## args)
#define DBG_INFO(fmt, args...) printf("\n\r[%s] " fmt, __FUNCTION__, ## args)
#else
#define DBG_TRACE(fmt, args...)
#define DBG_INFO(fmt, args...)
#endif
#define HALT() do { cli(); for(;;);} while(0)
#undef ASSERT
#define ASSERT(x) do { \
if((x) == 0) \
printf("\n\rAssert(" #x ") failed on line %d in file %s", __LINE__, __FILE__); \
HALT(); \
} while(0)
#undef DBG_ASSERT
#define DBG_ASSERT(x, msg) do { \
if((x) == 0) \
printf("\n\r%s, Assert(" #x ") failed on line %d in file %s", msg, __LINE__, __FILE__); \
} while(0)
//----- ------------------------------------------------------------------
// Atomic Operation
//----- ------------------------------------------------------------------
#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B) // for 8195A, it is defined in ..system../basic_types.h
typedef struct { volatile int counter; } atomic_t;
#endif
/*
* atomic_read - read atomic variable
* @v: pointer of type atomic_t
*
* Atomically reads the value of @v. Note that the guaranteed
* useful range of an atomic_t is only 24 bits.
*/
#undef atomic_read
#define atomic_read(v) ((v)->counter)
/*
* atomic_set - set atomic variable
* @v: pointer of type atomic_t
* @i: required value
*
* Atomically sets the value of @v to @i. Note that the guaranteed
* useful range of an atomic_t is only 24 bits.
*/
#undef atomic_set
#define atomic_set(v,i) ((v)->counter = (i))
/*
* These inlines deal with timer wrapping correctly. You are
* strongly encouraged to use them
* 1. Because people otherwise forget
* 2. Because if the timer wrap changes in future you wont have to
* alter your driver code.
*
* time_after(a,b) returns true if the time a is after time b.
*
* Do this with "<0" and ">=0" to only test the sign of the result. A
* good compiler would generate better code (and a really good compiler
* wouldn't care). Gcc is currently neither.
*/
#define time_after(a,b) ((long)(b) - (long)(a) < 0)
#define time_before(a,b) time_after(b,a)
#define time_after_eq(a,b) ((long)(a) - (long)(b) >= 0)
#define time_before_eq(a,b) time_after_eq(b,a)
extern void rtw_init_listhead(_list *list);
extern u32 rtw_is_list_empty(_list *phead);
extern void rtw_list_insert_head(_list *plist, _list *phead);
extern void rtw_list_insert_tail(_list *plist, _list *phead);
extern void rtw_list_delete(_list *plist);
#if CONFIG_PLATFORM_8711B
extern u32 random_seed;
#endif
#endif /* _FREERTOS_SERVICE_H_ */

View file

@ -0,0 +1,135 @@
/*
* Routines to access hardware
*
* Copyright (c) 2013 Realtek Semiconductor Corp.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*/
#include "ameba_soc.h"
#include "build_info.h"
#include <rtthread.h>
#ifndef RT_MAIN_THREAD_STACK_SIZE
#define RT_MAIN_THREAD_STACK_SIZE 2048
#endif
#ifndef RT_USING_HEAP
/* if there is not enable heap, we should use static thread and stack. */
ALIGN(8)
static rt_uint8_t main_stack[RT_MAIN_THREAD_STACK_SIZE];
struct rt_thread main_thread;
#endif
/* the system main thread */
void main_thread_entry(void *parameter)
{
extern int main(void);
extern int $Super$$main(void);
/* RT-Thread components initialization */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_init();
#endif
/* invoke system main function */
#if defined (__CC_ARM)
$Super$$main(); /* for ARMCC. */
#elif defined(__ICCARM__) || defined(__GNUC__)
main();
#endif
}
void rt_application_init(void)
{
rt_thread_t tid;
#ifdef RT_USING_HEAP
tid = rt_thread_create("main", main_thread_entry, RT_NULL,
RT_MAIN_THREAD_STACK_SIZE, RT_THREAD_PRIORITY_MAX / 3, 20);
RT_ASSERT(tid != RT_NULL);
#else
rt_err_t result;
tid = &main_thread;
result = rt_thread_init(tid, "main", main_thread_entry, RT_NULL,
main_stack, sizeof(main_stack), RT_THREAD_PRIORITY_MAX / 3, 20);
RT_ASSERT(result == RT_EOK);
/* if not define RT_USING_HEAP, using to eliminate the warning */
(void)result;
#endif
rt_thread_startup(tid);
}
int rtthread_startup(void)
{
rt_hw_interrupt_disable();
/* board level initalization
* NOTE: please initialize heap inside board initialization.
*/
rt_hw_board_init();
/* show RT-Thread version */
rt_show_version();
/* timer system initialization */
rt_system_timer_init();
/* scheduler system initialization */
rt_system_scheduler_init();
#ifdef RT_USING_SIGNALS
/* signal system initialization */
rt_system_signal_init();
#endif
/* create init_thread */
rt_application_init();
/* timer thread initialization */
rt_system_timer_thread_init();
/* idle thread initialization */
rt_thread_idle_init();
/* start scheduler */
rt_system_scheduler_start();
/* never reach here */
return 0;
}
void APP_Start(void)
{
#if CONFIG_SOC_PS_MODULE
SOCPS_InitSYSIRQ();
#endif
extern void PendSV_Handler(void);
extern void SysTick_Handler(void);
InterruptForOSInit((VOID*)NULL,
(VOID*)PendSV_Handler,
(VOID*)SysTick_Handler);
#if defined ( __ICCARM__ )
__iar_cstart_call_ctors(NULL);
#endif
// force SP align to 8 byte not 4 byte (initial SP is 4 byte align)
__asm(
"mov r0, sp\n"
"bic r0, r0, #7\n"
"mov sp, r0\n"
);
/* disable interrupt first */
rt_hw_interrupt_disable();
/* startup RT-Thread RTOS */
rtthread_startup();
}

View file

@ -0,0 +1,207 @@
/*
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong?" *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest versions, license
and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
#include <stdint.h>
extern uint32_t SystemCoreClock;
#endif
#include "platform_autoconf.h"
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*
* See http://www.freertos.org/a00110.html.
*----------------------------------------------------------*/
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ( ( uint32_t ) 1000 )
#define configSYSTICK_CLOCK_HZ 32768
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 512 )
#ifdef CONFIG_WIFI_EN
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 100 * 1024 ) )
#else
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 20 * 1024 ) )
#endif
#define configMAX_TASK_NAME_LEN ( 10 )
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 0
#define configUSE_CO_ROUTINES 1
#define configUSE_MUTEXES 1
#define configUSE_TIMERS 1
#define configMAX_PRIORITIES ( 11 )
#define PRIORITIE_OFFSET ( 4 )
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_ALTERNATIVE_API 0
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_RECURSIVE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 0
#define configGENERATE_RUN_TIME_STATS 0
#if configGENERATE_RUN_TIME_STATS
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() //( ulHighFrequencyTimerTicks = 0UL )
#define portGET_RUN_TIME_COUNTER_VALUE() xTickCount //ulHighFrequencyTimerTicks
#undef configUSE_TRACE_FACILITY
#define configUSE_TRACE_FACILITY 1
#define portCONFIGURE_STATS_PEROID_VALUE 1000 //unit Ticks
#endif
#define configTIMER_TASK_PRIORITY ( 1 )
#define configTIMER_QUEUE_LENGTH ( 10 )
#define configTIMER_TASK_STACK_DEPTH ( 512 ) //USE_MIN_STACK_SIZE modify from 512 to 256
#if (__IASMARM__ != 1)
extern void freertos_pre_sleep_processing(unsigned int *expected_idle_time);
extern void freertos_post_sleep_processing(unsigned int *expected_idle_time);
extern int freertos_ready_to_sleep();
/* Enable tickless power saving. */
#define configUSE_TICKLESS_IDLE 1
/* In wlan usage, this value is suggested to use value less than 80 milliseconds */
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2
/* It's magic trick that let us can use our own sleep function */
#define configPRE_SLEEP_PROCESSING( x ) ( freertos_pre_sleep_processing(&x) )
#define configPOST_SLEEP_PROCESSING( x ) ( freertos_post_sleep_processing(&x) )
/* It's magic trick that let us can enable/disable tickless dynamically */
#define traceLOW_POWER_IDLE_BEGIN(); do { \
if (!freertos_ready_to_sleep()) { \
mtCOVERAGE_TEST_MARKER(); \
break; \
}
// portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime );
#define traceLOW_POWER_IDLE_END(); } while (0);
/* It's FreeRTOS related feature but it's not included in FreeRTOS design. */
#define configUSE_WAKELOCK_PMU 1
#endif // #if (__IASMARM__ != 1)
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_pcTaskGetTaskName 1
#define INCLUDE_xTimerPendFunctionCall 1
/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4 /* 15 priority levels */
#endif
/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x0f
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
//#define RTK_MODE_TIMER
#endif /* FREERTOS_CONFIG_H */

View file

@ -0,0 +1,7 @@
#define UTS_VERSION "2017/06/23-15:35:37"
#define RTL8195AFW_COMPILE_TIME "2017/06/23-15:35:37"
#define RTL8195AFW_COMPILE_DATE "20170623"
#define RTL8195AFW_COMPILE_BY "root"
#define RTL8195AFW_COMPILE_HOST ""
#define RTL8195AFW_COMPILE_DOMAIN
#define RTL195AFW_COMPILER "gcc 4.8.4"

View file

@ -0,0 +1,122 @@
#ifndef MAIN_H
#define MAIN_H
#include <autoconf.h>
#ifndef CONFIG_WLAN
#define CONFIG_WLAN 1
#endif
/* Header file declaration*/
void wlan_network();
/* Interactive Mode */
#define SERIAL_DEBUG_RX 1
/* WLAN and Netork */
#define STA_MODE_SSID "ap" /* Set SSID here */
#define AP_MODE_SSID "wlan_ap_ssid" /* Set SSID here */
#define AP_DEFAULT_CH 6
#define WLAN0_NAME "wlan0"
#define WLAN1_NAME "wlan1"
#define WPA_PASSPHRASE "1234567890" /* Max 32 cahracters */
#define WEP40_KEY {0x12, 0x34, 0x56, 0x78, 0x90}
#define ATVER_1 1 // For First AT command
#define ATVER_2 2 // For UART Module AT command
#if CONFIG_EXAMPLE_UART_ATCMD
#define ATCMD_VER ATVER_2
#else
#define ATCMD_VER ATVER_1
#endif
#if ATCMD_VER == ATVER_2
#undef CONFIG_EXAMPLE_WLAN_FAST_CONNECT
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 1
extern unsigned char sta_ip[4], sta_netmask[4], sta_gw[4];
extern unsigned char ap_ip[4], ap_netmask[4], ap_gw[4];
/*Static IP ADDRESS*/
#define IP_ADDR0 sta_ip[0]
#define IP_ADDR1 sta_ip[1]
#define IP_ADDR2 sta_ip[2]
#define IP_ADDR3 sta_ip[3]
/*NETMASK*/
#define NETMASK_ADDR0 sta_netmask[0]
#define NETMASK_ADDR1 sta_netmask[1]
#define NETMASK_ADDR2 sta_netmask[2]
#define NETMASK_ADDR3 sta_netmask[3]
/*Gateway Address*/
#define GW_ADDR0 sta_gw[0]
#define GW_ADDR1 sta_gw[1]
#define GW_ADDR2 sta_gw[2]
#define GW_ADDR3 sta_gw[3]
/*******************************************/
/*Static IP ADDRESS*/
#define AP_IP_ADDR0 ap_ip[0]
#define AP_IP_ADDR1 ap_ip[1]
#define AP_IP_ADDR2 ap_ip[2]
#define AP_IP_ADDR3 ap_ip[3]
/*NETMASK*/
#define AP_NETMASK_ADDR0 ap_netmask[0]
#define AP_NETMASK_ADDR1 ap_netmask[1]
#define AP_NETMASK_ADDR2 ap_netmask[2]
#define AP_NETMASK_ADDR3 ap_netmask[3]
/*Gateway Address*/
#define AP_GW_ADDR0 ap_gw[0]
#define AP_GW_ADDR1 ap_gw[1]
#define AP_GW_ADDR2 ap_gw[2]
#define AP_GW_ADDR3 ap_gw[3]
#else
/*Static IP ADDRESS*/
#define IP_ADDR0 192
#define IP_ADDR1 168
#define IP_ADDR2 1
#define IP_ADDR3 80
/*NETMASK*/
#define NETMASK_ADDR0 255
#define NETMASK_ADDR1 255
#define NETMASK_ADDR2 255
#define NETMASK_ADDR3 0
/*Gateway Address*/
#define GW_ADDR0 192
#define GW_ADDR1 168
#define GW_ADDR2 1
#define GW_ADDR3 1
/*******************************************/
/*Static IP ADDRESS*/
#define AP_IP_ADDR0 192
#define AP_IP_ADDR1 168
#define AP_IP_ADDR2 43
#define AP_IP_ADDR3 1
/*NETMASK*/
#define AP_NETMASK_ADDR0 255
#define AP_NETMASK_ADDR1 255
#define AP_NETMASK_ADDR2 255
#define AP_NETMASK_ADDR3 0
/*Gateway Address*/
#define AP_GW_ADDR0 192
#define AP_GW_ADDR1 168
#define AP_GW_ADDR2 43
#define AP_GW_ADDR3 1
#endif //#if ATCMD_VER == ATVER_2
#endif

View file

@ -0,0 +1,241 @@
/*
* Automatically generated by make menuconfig: don't edit
*/
#define AUTOCONF_INCLUDED
/*
* < MENUCONFIG FOR CHIP CONFIG
*/
/*
* < CONFIG CHIP
*/
#define CONFIG_RTL8711B 1
#undef ARM_CORE_CM3
#define ARM_CORE_CM4 1
#define CONFIG_CHIP_A_CUT 1
#undef CONFIG_FPGA
/*
* < CONFIG CPU CLK
*/
#define CONFIG_CPU_CLK 1
#define CONFIG_CPU_125MHZ 1
#undef CONFIG_CPU_62_5MHZ
#undef CONFIG_CPU_31_25MHZ
#undef CONFIG_CPU_15_625MHZ
#undef CONFIG_CPU_7_8125MHZ
#undef CONFIG_CPU_4MHZ
#undef CONFIG_FPGA_CLK
#define PLATFORM_CLOCK (125000000)
#define CPU_CLOCK_SEL_VALUE (0)
/*
* < CONFIG OSC8M CLK
*/
#define CONFIG_OSC8M_CLK 1
#define CONFIG_OSC8M_8388608HZ 1
#undef CONFIG_OSC8M_8192000HZ
#undef CONFIG_OSC8M_8000000HZ
#undef CONFIG_OSC8M_16777216HZ
#define OSC8M_CLOCK (8388608)
/*
* < CONFIG TEST MODE
*/
#undef CONFIG_MP
#undef CONFIG_CP
#undef CONFIG_FT
#undef CONFIG_EQC
#undef CONFIG_RTL_SIM
#undef CONFIG_POST_SIM
/*
* < CONFIG OS
*/
#define CONFIG_KERNEL 1
#define PLATFORM_FREERTOS 1
#undef PLATFORM_UCOSII
#undef PLATFORM_ECOS
#undef CONFIG_TASK_SCHEDUL_DIS
#define TASK_SCHEDULER_DISABLED (0)
/*
* < CONFIG GTIMER
*/
#define CONFIG_TIMER_EN 1
#define CONFIG_TIMER_MODULE 1
/*
* < CONFIG WDG
*/
#define CONFIG_WDG 1
#define CONFIG_WDG_MODULE 1
/*
* < CONFIG GDMA
*/
#define CONFIG_GDMA_EN 1
#define CONFIG_GDMA_MODULE 1
/*
* < CONFIG GPIO
*/
#define CONFIG_GPIO_EN 1
#define CONFIG_GPIO_MODULE 1
/*
* < CONFIG SPI
*/
#define CONFIG_SPI_COM_EN 1
#define CONFIG_SPI_COM_MODULE 1
/*
* < CONFIG UART
*/
#define CONFIG_UART_EN 1
#define CONFIG_UART_MODULE 1
/*
* < CONFIG I2C
*/
#define CONFIG_I2C_EN 1
#define CONFIG_I2C_MODULE 1
/*
* < CONFIG I2S
*/
#define CONFIG_I2S_EN 1
#define CONFIG_I2S_MODULE 1
/*
* < CONFIG SOC PS
*/
#define CONFIG_SOC_PS_EN 1
#define CONFIG_SOC_PS_MODULE 1
/*
* < CONFIG CRYPTO
*/
#define CONFIG_CRYPTO_EN 1
#define CONFIG_CRYPTO_MODULE 1
/*
* < CONFIG PWM
*/
#define CONFIG_PWM_EN 1
/*
* < CONFIG EFUSE
*/
#define CONFIG_EFUSE_EN 1
#define CONFIG_EFUSE_MODULE 1
/*
* < CONFIG SPIC
*/
#define CONFIG_SPIC_EN 1
#define CONFIG_SPIC_MODULE 1
#define CONFIG_SPIC_PHASE_CALIBATION 1
#undef CONFIG_SPIC_4BYTES_ADDRESS
/*
* < CONFIG ADC
*/
#define CONFIG_ADC_EN 1
#define CONFIG_ADC_MODULE 1
/*
* < CONFIG SDIO Device
*/
#define CONFIG_SDIO_DEVICE_EN 1
#define CONFIG_SDIO_DEVICE_NORMAL 1
#define CONFIG_SDIO_DEVICE_MODULE 1
/*
* < CONFIG USB
*/
#define CONFIG_USB_EN 1
#define CONFIG_USB_MODULE 1
/*
* < CONFIG RDP
*/
#define CONFIG_RDP_ENABLE 1
/*
* < CONFIG PINMUX
*/
#undef CONFIG_PINMAP_ENABLE
/*
* < CONFIG PER TEST
*/
#undef CONFIG_PER_TEST
/*
* < CONFIG WIFI
*/
#define CONFIG_WIFI_EN 1
#define CONFIG_WIFI_NORMAL 1
#undef CONFIG_WIFI_TEST
#define CONFIG_WIFI_MODULE 1
/*
* < CONFIG NETWORK
*/
#define CONFIG_NETWORK 1
/*
* < CONFIG INIC
*/
#undef CONFIG_INIC_EN
/*
* < CONFIG USB_NIC
*/
#undef CONFIG_USB_DONGLE_NIC_EN
/*
* < RTK STD lib
*/
#define CONFIG_RTLIB_EN 1
#define CONFIG_RTLIB_MODULE 1
#undef CONFIG_RTLIB_VERIFY
/*
* < Add MBED SDK
*/
#undef CONFIG_MBED_ENABLED
/*
* < Build App Demo
*/
#undef CONFIG_APP_DEMO
/*
* < Dhrystone
*/
#undef CONFIG_DHRYSTONE_TEST
/*
* < SSL
*/
#undef CONFIG_SSL_ROM_TEST
/*
* < System Debug Message Config
*/
#define CONFIG_UART_LOG_HISTORY 1
#define CONFIG_DEBUG_LOG 1
#define CONFIG_DEBUG_ERR_MSG 1
#undef CONFIG_DEBUG_WARN_MSG
#undef CONFIG_DEBUG_INFO_MSG
/*
* < Build Option
*/
#define CONFIG_TOOLCHAIN_ASDK 1
#undef CONFIG_TOOLCHAIN_ARM_GCC
#define CONFIG_LINK_ROM_LIB 1
#undef CONFIG_LINK_ROM_SYMB

View file

@ -0,0 +1,335 @@
/**
******************************************************************************
*This file contains general configurations for ameba platform
******************************************************************************
*/
#ifndef __PLATFORM_OPTS_H__
#define __PLATFORM_OPTS_H__
#include "platform_autoconf.h"
/*For MP mode setting*/
//#define SUPPORT_MP_MODE 1
/**
* For AT cmd Log service configurations
*/
#define SUPPORT_LOG_SERVICE 1
#if SUPPORT_LOG_SERVICE
#define LOG_SERVICE_BUFLEN 100 //can't larger than UART_LOG_CMD_BUFLEN(127)
#define CONFIG_LOG_HISTORY 0
#if CONFIG_LOG_HISTORY
#define LOG_HISTORY_LEN 5
#endif
#define SUPPORT_INTERACTIVE_MODE 0//on/off wifi_interactive_mode
#define CONFIG_LOG_SERVICE_LOCK 0
#endif
/* For DCT example*/
#define CONFIG_EXAMPLE_DCT 0
/**
* For interactive mode configurations, depents on log service
*/
#if SUPPORT_INTERACTIVE_MODE
#define CONFIG_INTERACTIVE_MODE 1
#define CONFIG_INTERACTIVE_EXT 0
#else
#define CONFIG_INTERACTIVE_MODE 0
#define CONFIG_INTERACTIVE_EXT 0
#endif
/**
* For FreeRTOS tickless configurations
*/
#define FREERTOS_PMU_TICKLESS_SUSPEND_SDRAM 1 // In sleep mode, 1: suspend SDRAM, 0: no act
/******************************************************************************/
/**
* For common flash usage
*/
#define AP_SETTING_SECTOR 0x000FE000
#define UART_SETTING_SECTOR 0x000FC000
#define SPI_SETTING_SECTOR 0x000FC000
#define FAST_RECONNECT_DATA (0x80000 - 0x1000)
#define FLASH_SECTOR_SIZE 0x1000
#define CONFIG_ENABLE_RDP 0
/**
* For Wlan configurations
*/
#define CONFIG_WLAN 1
#if CONFIG_WLAN
#define CONFIG_LWIP_LAYER 1
#define CONFIG_INIT_NET 1 //init lwip layer when start up
#define CONFIG_WIFI_IND_USE_THREAD 0 // wifi indicate worker thread
//on/off relative commands in log service
#define CONFIG_SSL_CLIENT 0
#define CONFIG_WEBSERVER 0
#define CONFIG_OTA_UPDATE 1
#define CONFIG_BSD_TCP 1//NOTE : Enable CONFIG_BSD_TCP will increase about 11KB code size
#define CONFIG_AIRKISS 0//on or off tencent airkiss
#define CONFIG_UART_SOCKET 0
#define CONFIG_UART_XMODEM 0//support uart xmodem upgrade or not
#define CONFIG_TRANSPORT 0//on or off the at command for transport socket
/* For WPS and P2P */
#define CONFIG_ENABLE_WPS 0
#define CONFIG_ENABLE_WPS_DISCOVERY 0
#if CONFIG_ENABLE_P2P
#define CONFIG_ENABLE_WPS_AP 1
#undef CONFIG_WIFI_IND_USE_THREAD
#define CONFIG_WIFI_IND_USE_THREAD 1
#endif
#if (CONFIG_ENABLE_P2P && ((CONFIG_ENABLE_WPS_AP == 0) || (CONFIG_ENABLE_WPS == 0)))
#error "If CONFIG_ENABLE_P2P, need to define CONFIG_ENABLE_WPS_AP 1"
#endif
/* For SSL/TLS */
#define CONFIG_USE_POLARSSL 1
#define CONFIG_USE_MBEDTLS 0
#if ((CONFIG_USE_POLARSSL == 0) && (CONFIG_USE_MBEDTLS == 0)) || ((CONFIG_USE_POLARSSL == 1) && (CONFIG_USE_MBEDTLS == 1))
#undef CONFIG_USE_POLARSSL
#define CONFIG_USE_POLARSSL 1
#undef CONFIG_USE_MBEDTLS
#define CONFIG_USE_MBEDTLS 0
#endif
/* For Simple Link */
#define CONFIG_INCLUDE_SIMPLE_CONFIG 1
/*For fast reconnection*/
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 0
#define CONFIG_GAGENT 0
/*Disable CONFIG_EXAMPLE_WLAN_FAST_CONNECT when CONFIG_GAGENT is enabled,because
reconnect to previous AP is not suitable when re-configuration.
*/
#if CONFIG_GAGENT
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 0
#endif
#endif //end of #if CONFIG_WLAN
/*******************************************************************************/
/**
* For Ethernet configurations
*/
#define CONFIG_ETHERNET 0
#if CONFIG_ETHERNET
#define CONFIG_LWIP_LAYER 1
#define CONFIG_INIT_NET 1 //init lwip layer when start up
//on/off relative commands in log service
#define CONFIG_SSL_CLIENT 0
#define CONFIG_BSD_TCP 0//NOTE : Enable CONFIG_BSD_TCP will increase about 11KB code size
#endif
/**
* For user to adjust SLEEP_INTERVAL
*/
#define CONFIG_DYNAMIC_TICKLESS 1
/*******************************************************************************/
/**
* For iNIC configurations
*/
//#define CONFIG_INIC_EN 0//enable iNIC mode
#if CONFIG_INIC_EN
#ifndef CONFIG_LWIP_LAYER
#define CONFIG_LWIP_LAYER 0
#endif
#ifndef CONFIG_INIC_SDIO_HCI
#define CONFIG_INIC_SDIO_HCI 0 //for SDIO or USB iNIC
#endif
#ifndef CONFIG_INIC_CMD_RSP
#define CONFIG_INIC_CMD_RSP 0
#endif
#ifndef CONFIG_INIC_USB_HCI
#define CONFIG_INIC_USB_HCI 0
#endif
#endif
/******************End of iNIC configurations*******************/
/* For WIFI GET BEACON FRAME example */
#define CONFIG_EXAMPLE_GET_BEACON_FRAME 0
/* For WIFI MAC MONITOR example */
#define CONFIG_EXAMPLE_WIFI_MAC_MONITOR 0
/* For HTTP CLIENT example */
#define CONFIG_EXAMPLE_HTTP_CLIENT 0
/* For MQTT example */
#define CONFIG_EXAMPLE_MQTT 0
/* For mDNS example */
#define CONFIG_EXAMPLE_MDNS 0
/* For multicast example */
#define CONFIG_EXAMPLE_MCAST 0
/* For XML example */
#define CONFIG_EXAMPLE_XML 0
/* For socket select example */
#define CONFIG_EXAMPLE_SOCKET_SELECT 0
/* For socket nonblocking connect example */
#define CONFIG_EXAMPLE_NONBLOCK_CONNECT 0
/* For socket TCP bidirectional transmission example */
#define CONFIG_EXAMPLE_SOCKET_TCP_TRX 0
/* For ssl download example */
#define CONFIG_EXAMPLE_SSL_DOWNLOAD 0
/* For http download example */
#define CONFIG_EXAMPLE_HTTP_DOWNLOAD 0
/* For httpc example */
#define CONFIG_EXAMPLE_HTTPC 0
/* For httpd example */
#define CONFIG_EXAMPLE_HTTPD 0
/* For tcp keepalive example */
#define CONFIG_EXAMPLE_TCP_KEEPALIVE 0
/* For sntp show time example */
#define CONFIG_EXAMPLE_SNTP_SHOWTIME 0
/* For websocket client example */
#define CONFIG_EXAMPLE_WEBSOCKET 0
/* For UART Module AT command example */
#define CONFIG_EXAMPLE_UART_ATCMD 0
#if CONFIG_EXAMPLE_UART_ATCMD
#undef CONFIG_OTA_UPDATE
#define CONFIG_OTA_UPDATE 1
#undef CONFIG_TRANSPORT
#define CONFIG_TRANSPORT 1
#undef LOG_SERVICE_BUFLEN
#define LOG_SERVICE_BUFLEN 1600
#undef CONFIG_LOG_SERVICE_LOCK
#define CONFIG_LOG_SERVICE_LOCK 1
#undef CONFIG_EXAMPLE_WLAN_FAST_CONNECT
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 0
#endif
/****************** For EAP method example *******************/
#define CONFIG_EXAMPLE_EAP 0
// on/off specified eap method
#define CONFIG_ENABLE_PEAP 0
#define CONFIG_ENABLE_TLS 0
#define CONFIG_ENABLE_TTLS 0
// optional feature: whether to verify the cert of radius server
#define ENABLE_EAP_SSL_VERIFY_SERVER 0
#if CONFIG_ENABLE_PEAP || CONFIG_ENABLE_TLS || CONFIG_ENABLE_TTLS
#define CONFIG_ENABLE_EAP
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 0
#endif
#if CONFIG_ENABLE_TLS
#define ENABLE_EAP_SSL_VERIFY_CLIENT 1
#else
#define ENABLE_EAP_SSL_VERIFY_CLIENT 0
#endif
/******************End of EAP configurations*******************/
/* For iNIC host example*/
#ifdef CONFIG_INIC_GSPI_HOST //this flag is defined in IAR project
#define CONFIG_EXAMPLE_INIC_GSPI_HOST 1
#if CONFIG_EXAMPLE_INIC_GSPI_HOST
#define CONFIG_INIC_HOST 1
#undef CONFIG_WLAN
#define CONFIG_WLAN 0
#undef CONFIG_INCLUDE_SIMPLE_CONFIG
#define CONFIG_INCLUDE_SIMPLE_CONFIG 0
#undef CONFIG_EXAMPLE_WLAN_FAST_CONNECT
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 0
#undef CONFIG_LWIP_LAYER
#define CONFIG_LWIP_LAYER 1
#undef CONFIG_BSD_TCP
#define CONFIG_BSD_TCP 1
#endif
#endif
/*For uart update example*/
#define CONFIG_UART_UPDATE 0
#if CONFIG_UART_UPDATE
#undef CONFIG_EXAMPLE_WLAN_FAST_CONNECT
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 0
#endif
/* For uart adapter example */
/* Please also configure LWIP_UART_ADAPTER to 1
in lwip_opt.h for support uart adapter*/
#define CONFIG_EXAMPLE_UART_ADAPTER 0
#if CONFIG_EXAMPLE_UART_ADAPTER
#undef CONFIG_EXAMPLE_WLAN_FAST_CONNECT
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 1
#undef CONFIG_EXAMPLE_MDNS
#define CONFIG_EXAMPLE_MDNS 1
#endif
/* For wifi scenarios example (Wi-Fi, WPS enrollee, P2P GO) */
// also need to enable WPS and P2P
#define CONFIG_EXAMPLE_WLAN_SCENARIO 0
/* For broadcast example */
#define CONFIG_EXAMPLE_BCAST 0
/* For high-load memory use case memory usage */
#define CONFIG_EXAMPLE_HIGH_LOAD_MEMORY_USE 0
/* For rarp example */
#define CONFIG_EXAMPLE_RARP 0
/* For ssl server example */
#define CONFIG_EXAMPLE_SSL_SERVER 0
#if CONFIG_QQ_LINK
#define FATFS_R_10C
#define FATFS_DISK_USB 0
#define FATFS_DISK_SD 1
#endif
#if CONFIG_ENABLE_WPS
#define WPS_CONNECT_RETRY_COUNT 4
#define WPS_CONNECT_RETRY_INTERVAL 5000 // in ms
#endif
#define AUTO_RECONNECT_COUNT 8
#define AUTO_RECONNECT_INTERVAL 5 // in sec
#if CONFIG_INIC_EN
#undef CONFIG_INCLUDE_SIMPLE_CONFIG
#define CONFIG_INCLUDE_SIMPLE_CONFIG 0
#define SUPPORT_INTERACTIVE_MODE 0
#define CONFIG_INTERACTIVE_MODE 0
#define CONFIG_INTERACTIVE_EXT 0
#define CONFIG_OTA_UPDATE 0
#endif
#endif

View file

@ -0,0 +1,279 @@
/*
* Routines to access hardware
*
* Copyright (c) 2013 Realtek Semiconductor Corp.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*/
#include "ameba_soc.h"
#include "build_info.h"
#include "strproc.h"
#include "system_8195a.h"
u32 random_seed;
#if defined ( __ICCARM__ )
#pragma section=".ram_image2.bss"
#pragma section=".ram_image2.skb.bss"
#pragma section=".rom.bss"
#pragma section=".ram.start.table"
#pragma section=".ram_image1.bss"
#pragma section=".image2.start.table1"
#pragma section=".image2.start.table2"
u8* __bss_start__;
u8* __bss_end__;
void __iar_data_init_app(void)
{
__bss_start__ = (u8*)__section_begin(".ram_image2.bss");
__bss_end__ = (u8*)__section_end(".ram_image2.skb.bss");
}
#endif
extern VOID SOCPS_WakeFromPG(VOID);
#if defined ( __ICCARM__ )
VOID
HalHardFaultHandler_user_define(u32 HardDefaultArg)
{
}
VOID
HalHardFaultHandler_Patch_c(u32 HardDefaultArg)
{
HalHardFaultHandler_user_define(HardDefaultArg);
INT_HardFault(HardDefaultArg);
}
VOID
HalHardFaultHandler_Patch_asm(void)
{
asm("TST LR, #4\n"
"ITE EQ\n"
"MRSEQ R0, MSP\n"
"MRSNE R0, PSP\n"
"B HalHardFaultHandler_Patch_c");
}
#endif
// Override original Interrupt Vector Table
VOID BOOT_VectorTableOverride(u32 StackP)
{
// Override NMI Handler
//4 Initial NMI
//NewVectorTable[2] = (HAL_VECTOR_FUN)HalNMIHandler_Patch;
#if 0//defined ( __ICCARM__ )
//Redefine Hardfault Handler
NewVectorTable[3] = (HAL_VECTOR_FUN)HalHardFaultHandler_Patch_asm;
#endif
}
void BOOT_Reason(void)
{
u32 backup_reg0 = BKUP_Read(BKUP_REG0);
DBG_8195A("boot reason: %x \n", backup_reg0);
}
extern u32 GlobalDebugEnable;
VOID BOOT_InitDebugFlg(VOID)
{
SYSTEM_DATA *SysData = (SYSTEM_DATA *)(SPI_FLASH_BASE + FLASH_SYSTEM_DATA_ADDR);
/* reset */
ConfigDebugErr = 0;
ConfigDebugWarn = 0;
ConfigDebugInfo = 0;
#if (defined(CONFIG_POST_SIM) || defined(CONFIG_CP))
return;
#endif
/* to initial ROM code using global variable */
#ifdef CONFIG_DEBUG_ERR_MSG
ConfigDebugErr = 0xFFFFFFFF;//_DBG_MISC_;]
#endif
#ifdef CONFIG_DEBUG_WARN_MSG
ConfigDebugWarn = 0xFFFFFFFF;
#endif
#ifdef CONFIG_DEBUG_INFO_MSG
ConfigDebugInfo = 0xFFFFFFFF;
#endif
if (SysData->UlogDbgEn == 0x0) {
ConfigDebugErr = 0;
ConfigDebugWarn = 0;
ConfigDebugInfo = 0;
GlobalDebugEnable = 0;
}
}
VOID BOOT_RTC_Init(VOID)
{
RTC_InitTypeDef RTC_InitStruct_temp;
RTC_AlarmTypeDef RTC_AlarmStruct_temp;
RTC_TimeTypeDef RTC_TimeStruct;
/* for 32K more stable */
NCO32K_Init(32768, XTAL_ClkGet(), 15, 2);
RTC_ClokSource(0);
RTC_StructInit(&RTC_InitStruct_temp);
RTC_Init(&RTC_InitStruct_temp);
/* 32760 need add need add 15 cycles (256Hz) every 4 min*/
//RTC_SmoothCalibConfig(RTC_CalibSign_Positive, 15,
// RTC_CalibPeriod_4MIN, RTC_Calib_Enable);
/* set time when power on */
RTC_GetTime(RTC_Format_BIN, &RTC_TimeStruct);
if (RTC_TimeStruct.RTC_Seconds == 0 && RTC_TimeStruct.RTC_Minutes == 0) {
RTC_TimeStructInit(&RTC_TimeStruct);
RTC_SetTime(RTC_Format_BIN, &RTC_TimeStruct);
}
/* set alarm */
RTC_AlarmStructInit(&RTC_AlarmStruct_temp);
RTC_AlarmStruct_temp.RTC_AlarmTime.RTC_Days = 1;
RTC_AlarmStruct_temp.RTC_AlarmTime.RTC_Hours = 1;
RTC_AlarmStruct_temp.RTC_AlarmTime.RTC_Minutes = 1;
RTC_AlarmStruct_temp.RTC_AlarmTime.RTC_Seconds = 30;
RTC_AlarmStruct_temp.RTC_AlarmMask = RTC_AlarmMask_Hours | RTC_AlarmMask_Minutes;
RTC_AlarmStruct_temp.RTC_Alarm2Mask = RTC_Alarm2Mask_Days;
RTC_SetAlarm(RTC_Format_BIN, &RTC_AlarmStruct_temp);
RTC_AlarmCmd(DISABLE);
/* RTC interrupt hander is reserved for user */
//InterruptRegister((IRQ_FUN)BOOT_RTC_Handler, RTC_IRQ, NULL, 4);
//InterruptEn(RTC_IRQ, 4);
}
VOID BOOT_PlatformInit(VOID)
{
u32 Temp = 0;
/* Set SPS lower voltage */
//Temp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_SYSCFG0)&0xf0ffffff)|0x6000000);
//HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_SYSCFG0, Temp);
/* Driving control of RF1 clock buffer, 11:large current, 00: small current */
Temp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_XTAL_CTRL1);
Temp &= ~(BIT_SYS_XTAL_DRV_RF1(3));
Temp |= BIT_SYS_XTAL_DRV_RF1(1);
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_XTAL_CTRL1, Temp);
}
//3 Imgae 2
VOID BOOT_Image2(VOID)
{
int ret = 0;
#ifdef CONFIG_FPGA
MPU->RNR = 0; //0xE000ED00, 0x98 MPU Region RNRber Register
MPU->RBAR = 0; //0xE000ED00, 0x9C MPU Region Base Address Register
MPU->RASR = 0x6000027; //0xE000ED00, 0xA0 MPU Region Attribute and Size Register
MPU->CTRL = 7; //0xE000ED00, 0x94 MPU Control Register
#endif
#if defined ( __ICCARM__ )
__iar_data_init_app();
#endif
BOOT_InitDebugFlg();
BOOT_VectorTableOverride(0x1003EFFC);
/* set CPU clock if needed, default is 125MHz */
//CPU_ClkSet((u8)(CPU_CLOCK_SEL_VALUE));
//DelayUs(10);
#if (defined(CONFIG_CP))
CPTest_EnterImg2Ok();
#endif
DBG_8195A("===== Enter Image 2 ====\n");
//3 0) Vendor Config function
//4 Ram Bss Iitial
u32 BssLen = (__bss_end__ - __bss_start__);
_memset((void *) __bss_start__, 0, BssLen);
SystemCoreClockUpdate();
ret = boot_export_symbol.boot_system_init1();
//BOOT_PlatformInit();
#if (!defined(CONFIG_FPGA) && !defined(CONFIG_POST_SIM))
#if defined(CONFIG_OSC8M_8388608HZ)
OSC8M_Calibration(DISABLE, OSC32K_CALI_32KCYC_064, OSC8M_8388608HZ);
#elif defined(CONFIG_OSC8M_8192000HZ)
OSC8M_Calibration(DISABLE, OSC32K_CALI_32KCYC_064, OSC8M_8192000HZ);
#elif defined(CONFIG_OSC8M_8000000HZ)
OSC8M_Calibration(DISABLE, OSC32K_CALI_32KCYC_064, OSC8M_8000000HZ);
#elif defined(CONFIG_OSC8M_16777216HZ)
OSC8M_Calibration(DISABLE, OSC32K_CALI_32KCYC_064, OSC8M_16777216HZ);
#endif
DelayUs(90);
DelayUs(90);
#endif //CONFIG_FPGA
#ifdef CONFIG_CP
CPTest_OSCCalibrationOk();
#endif
/* Workaround for the GPIOA_7 didn't pull high: it may cause the
SDIO Device hardware be enabled automatically at power on and then
GPIOA[7:0] will be used for SDIO device */
#ifndef CONFIG_SDIO_DEVICE_EN
// SDIO Pin Mux off
SDIOD_PIN_FCTRL(OFF);
#endif
DBG_8195A("OSC8M: %x \n", OSC8M_Get());
BOOT_Reason();
BOOT_RTC_Init();
#if (!defined(CONFIG_FPGA))
random_seed = Gen_RandomSeed();
#endif
#if defined(CONFIG_WIFI_NORMAL) && defined(CONFIG_NETWORK)
rtw_efuse_boot_write();
#endif
ret = boot_export_symbol.boot_system_init2();
APP_Start();
#if defined ( __ICCARM__ )
// it is dummy code, but IAR linker need this
__iar_data_init3();
#endif
}
IMAGE2_VALID_PATTEN_SECTION
const u8 RAM_IMG2_VALID_PATTEN[20] = {
'R', 'T', 'K', 'W', 'i', 'n', 0x0, 0xff,
(FW_VERSION&0xff), ((FW_VERSION >> 8)&0xff),
(FW_SUBVERSION&0xff), ((FW_SUBVERSION >> 8)&0xff),
(FW_CHIP_ID&0xff), ((FW_CHIP_ID >> 8)&0xff),
(FW_CHIP_VER),
(FW_BUS_TYPE),
(FW_INFO_RSV1),
(FW_INFO_RSV2),
(FW_INFO_RSV3),
(FW_INFO_RSV4)
};
IMAGE2_ENTRY_SECTION
RAM_START_FUNCTION gImage2EntryFun0 = {
BOOT_Image2,
SOCPS_WakeFromPG
};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
# RT-Thread building script for bridge
import os
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')

View file

@ -0,0 +1,15 @@
# RT-Thread building script for bridge
import os
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')

View file

@ -0,0 +1,15 @@
# RT-Thread building script for bridge
import os
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')

View file

@ -0,0 +1,36 @@
import rtconfig
Import('RTT_ROOT')
from building import *
# get current directory
cwd = GetCurrentDir()
# The set of source files associated with this SConscript file.
path =[cwd + '/platform',
cwd + '/']
src = []
if GetDepend(['RT_USING_LWIP']):
src += Split('''
wifi/wifi_ind.c
wifi/wifi_util.c
wifi/wifi_promisc.c
wifi/rtw_wpa_supplicant/wpa_supplicant/wifi_eap_config.c
''')
path += [cwd + '/wifi',
cwd + '/wifi/rtw_wpa_supplicant/src',
cwd + '/../drivers/wlan/realtek/include',
cwd + '/../drivers/wlan/realtek/src/osdep',
cwd + '/../drivers/wlan/realtek/wlan_ram_map/rom',
cwd + '/../network/ssl/polarssl-1.3.8/include',
cwd + '/../network/ssl/ssl_ram_map/rom']
if GetDepend('RT_USING_LWIP141'):
path += [RTT_ROOT + '/components/net/lwip-1.4.1/src/include/lwip']
elif GetDepend('RT_USING_LWIP202'):
path += [RTT_ROOT + '/components/net/lwip-2.0.2/src/include/lwip']
group = DefineGroup('ameba_wifi', src, depend = [], CPPPATH = path)
Return('group')

View file

@ -0,0 +1,175 @@
#include <stdio.h>
#include "log_service.h"
#include "cmsis_os.h"
#include <platform/platform_stdlib.h>
#if CONFIG_JOYLINK
#if 1
void fATCJ(void *arg)
{
extern void joylink_erase(void);
printf("\r\n[ATCJ] Erase wifi and joylink info.");
if(arg){
printf("\r\n[ATCJ]Usage : ATCJ");
return;
}
joylink_erase();
}
#else
void fATCJ(void *arg)
{
extern void cmd_jd_smart(int argc, char **argv);
int argc;
char *argv[MAX_ARGC] = {0};
printf("[ATCJ]:simple config command for jdsmart\n\r");
if(!arg){
printf("[ATCJ]Usage: ATCJ=simple_config\n\r");
return;
}
argv[0] = "simple_config";
if((argc = parse_param(arg, argv)) > 1){
cmd_jd_smart(argc, argv);
}
else
printf("[ATCJ]Usage: ATCJ=simple_config\n\r");
}
#endif
#endif
#if CONFIG_GAGENT
void fATCG(void *arg)
{
example_gagent();
}
void fATCE(void *arg)
{//Erase gagent config flash
extern int GAgent_DevEraseConfigData();
GAgent_DevEraseConfigData();
}
#endif
#if CONFIG_QQ_LINK
void fATCQ(void *arg)
{
int argc;
unsigned char *argv[MAX_ARGC] = {0};
extern void device_write_sn_license(int argc, unsigned char **argv);
extern void device_erase_all(int argc, unsigned char **argv);
if(!arg)
{
printf("\r\n[ATCQ] Write sn/license into flash or Erase all info\r\n");
printf("\r\n[ATCQ] Usage: ATCQ=erase");
printf("\r\n[ATCQ] Usage: ATCQ=sn,xxxxxxxx\r\n ATCQ=licensepart1,xxxxxxxx\r\n ATCQ=licensepart2,xxxxxxxx");
return;
}
argv[0] = "sn&&license&&erase";
argc = parse_param(arg, argv);
if(argc == 3) // Write sn&&license
{
device_write_sn_license(argc, argv);
}
else if(argc == 2) // Erase all info : ATCQ=erase
{
device_erase_all(argc, argv);
}
else
{
printf("\r\n[ATCQ] Usage: ATCQ=erase");
printf("\r\n[ATCQ]Usage: ATCQ=sn,xxxxxxxx\r\n ATCQ=licensepart1,xxxxxxxx\r\n ATCQ=licensepart2,xxxxxxxx");
}
}
#endif
#if CONFIG_AIRKISS_CLOUD
void fATCW(void *arg)
{
int argc;
unsigned char *argv[MAX_ARGC] = {0};
extern void airkiss_cloud_write_device_info(int argc, unsigned char **argv);
extern void airkiss_cloud_erase_ap_profile(int argc, unsigned char **argv);
if(!arg) goto USAGE;
argv[0] = "type/id/licese/erase";
argc = parse_param(arg, argv);
if(argc == 3) // Write typw/id/license
{
airkiss_cloud_write_device_info(argc, argv);
return;
}
else if(argc == 2) // Erase wifi profile : ATCW=erase
{
airkiss_cloud_erase_ap_profile(argc, argv);
return;
}
else
goto USAGE;
USAGE:
printf("\r\n[ATCW] Write ORDERLY device's type/id/license into flash or Erase wifi profile");
printf("\r\n[ATCW] Usage: ATCW=type,xxxxxxxx");
printf("\r\n[ATCW] Usage: ATCW=id,xxxxxxxx");
printf("\r\n[ATCW] Usage: ATCW=licensepart1,xxxxxxxx\t(80-Byte long)");
printf("\r\n[ATCW] Usage: ATCW=licensepart2,xxxxxxxx\t(80-Byte long)");
printf("\r\n[ATCW] Usage: ATCW=erase");
return;
}
#endif
#if CONFIG_ALINK
extern void example_alink(void);
extern int alink_erase_wifi_config();
extern void alink_reset_to_factory(void *arg);
void fATCA(void *arg)
{
example_alink();
}
void fATCZ(void *arg)
{
//Erase alink config flash
alink_erase_wifi_config();
}
void fATCT(void *arg)
{
alink_reset_to_factory(NULL);
}
#endif
void fATCx(void *arg)
{
}
log_item_t at_cloud_items[ ] = {
#if CONFIG_JOYLINK
{"ATCJ", fATCJ,},
#endif
#if CONFIG_GAGENT
{"ATCG", fATCG,},
{"ATCE", fATCE,},
#endif
#if CONFIG_QQ_LINK
{"ATCQ", fATCQ,},
#endif
#if CONFIG_AIRKISS_CLOUD
{"ATCW", fATCW},
#endif
#if CONFIG_ALINK
{"ATCA", fATCA,},
{"ATCZ", fATCZ,},
{"ATCT", fATCT,},
#endif
{"ATC?", fATCx,},
};
void at_cloud_init(void)
{
log_service_add_table(at_cloud_items, sizeof(at_cloud_items)/sizeof(at_cloud_items[0]));
}
#if SUPPORT_LOG_SERVICE
log_module_init(at_cloud_init);
#endif

View file

@ -0,0 +1,91 @@
#include <stdio.h>
#include "log_service.h"
#include "platform_opts.h"
#include <lwip_netconf.h>
#include "cmsis_os.h"
#include <platform/platform_stdlib.h>
#include <lwip/sockets.h>
#include <lwip/tcpip.h>
#define _AT_DHCP_ETHERNET_MII_ "ATE0"
#define _AT_SET_DEFAULT_INTERFACE "ATE1"
#if CONFIG_ETHERNET
extern int dhcp_ethernet_mii;
extern int ethernet_if_default;
extern struct netif xnetif[NET_IF_NUM];
void fATE0(void *arg)
{
int argc;
char *argv[MAX_ARGC] = {0};
printf("[ATE0]:DHCP configure for ethernet\n\r");
if(!arg){
printf("[ATE0]Usage to disable DHCP: ATE0=0\n");
printf("[ATE0]Usage to enable DHCP: ATE0=1\n");
return;
}
if('0' == *(char *)arg)
{
dhcp_ethernet_mii = 0;
}
else if('1' == *(char *)arg)
{
dhcp_ethernet_mii = 1;
LwIP_DHCP(NET_IF_NUM - 1, DHCP_START);
}
else
{
printf("[ATE0]Usage to disable DHCP: ATE0=0\n");
printf("[ATE0]Usage to enable DHCP: ATE0=1\n");
}
}
void fATE1(void *arg)
{
int argc;
char *argv[MAX_ARGC] = {0};
printf("[ATE1]:Set/check the default interface\n\r");
if(!arg){
if(ethernet_if_default)
printf("Ethernet is the default interface\n");
else
printf("wlan is the default interface\n");
return;
}
if('0' == *(char *)arg)
{
ethernet_if_default = 0;
printf("wlan is set to the default interface\n");
}
else if('1' == *(char *)arg)
{
ethernet_if_default = 1;
printf("ethernet is set to the default interface\n");
}
else
{
printf("[ATE0]Usage to check the default interface: ATE1\n");
printf("[ATE0]Usage to set ethernet as default interface: ATE1=1\n");
printf("[ATE0]Usage to set wlan as default interface: ATE1=0\n");
}
}
log_item_t at_ethernet_items[ ] = {
{"ATE0", fATE0,},
{"ATE1", fATE1,}
};
void at_ethernet_init(void)
{
log_service_add_table(at_ethernet_items, sizeof(at_ethernet_items)/sizeof(at_ethernet_items[0]));
}
log_module_init(at_ethernet_init);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,105 @@
#ifndef __ATCMD_LWIP_H__
#define __ATCMD_LWIP_H__
#include "main.h"
#include "osdep_service.h"
#include <lwip/opt.h>
#include "lwip/sockets.h"
#include "lwip/api.h"
#include "lwip/sys.h"
#include "lwip/igmp.h"
#include "lwip/inet.h"
#include "lwip/tcp.h"
#include "lwip/raw.h"
#include "lwip/udp.h"
#include "lwip/tcpip.h"
#include "lwip/pbuf.h"
#include "lwip/netdb.h"
#include "lwip_netconf.h"
#define _AT_TRANSPORT_MODE_ "ATP1"
#define _AT_TRANSPORT_LOCAL_PORT_ "ATP2"
#define _AT_TRANSPORT_REMOTE_IP_ "ATP3"
#define _AT_TRANSPORT_REMOTE_PORT_ "ATP4"
#define _AT_TRANSPORT_START_SERVER_ "ATP5"
#define _AT_TRANSPORT_START_CLIENT_ "ATP6"
#define _AT_TRANSPORT_SHOW_SETTING_ "ATP?"
#define _AT_TRANSPORT_RECEIVE_DATA_ "ATR0"
#define _AT_TRANSPORT_RECEIVE_PACKET_SIZE_ "ATR1"
#define _AT_TRANSPORT_WRITE_DATA_ "ATRA"
#define _AT_TRANSPORT_WRITE_PACKET_SIZE_ "ATRB"
#define NODE_MODE_TCP 0
#define NODE_MODE_UDP 1
#define NODE_MODE_SSL 2
#define NODE_ROLE_SERVER 0
#define NODE_ROLE_CLIENT 1
#define NODE_ROLE_SEED 2
#define INVALID_SOCKET_ID (-1)
//parameters
#ifndef NET_IF_NUM
#define NET_IF_NUM 2
#endif
#define ATCMD_LWIP_TASK_PRIORITY (tskIDLE_PRIORITY + 1)
#if ATCMD_VER == ATVER_2
#ifndef ATCMD_SUPPORT_SSL
#define ATCMD_SUPPORT_SSL 0
#endif
#define SERVER "127.0.0.1"
#define NUM_NS (MEMP_NUM_NETCONN) //maximum number of node and seed, same as NUM_SOCKETS
#define ETH_MAX_MTU 1500
#define INVALID_CON_ID (-1)
#define RECV_SELECT_TIMEOUT_SEC (0)
#define RECV_SELECT_TIMEOUT_USEC (20000) //20ms
typedef struct ns
{
int con_id;
int sockfd;
s8_t role;
int protocol;
u32_t addr;
u16_t port;
u32_t local_addr;
u16_t local_port;
xTaskHandle handletask;
struct ns* next;
struct ns* nextseed;
#if (ATCMD_VER == ATVER_2) && ATCMD_SUPPORT_SSL
void *context;
#endif
} node;
extern xTaskHandle atcmd_lwip_tt_task;
extern _sema atcmd_lwip_tt_sema;
extern volatile int atcmd_lwip_tt_datasize;
extern volatile int atcmd_lwip_tt_lasttickcnt;
#define ATCMD_LWIP_TT_MAX_DELAY_TIME_MS (20) //transparent transmission interval
extern int atcmd_lwip_is_tt_mode(void);
extern void atcmd_lwip_set_tt_mode(int enable);
int atcmd_lwip_send_data(node *curnode, u8 *data, u16 data_sz, struct sockaddr_in cli_addr);
int atcmd_lwip_receive_data(node *curnode, u8 *buffer, u16 buffer_size, int *recv_size,
u8_t *udp_clientaddr, u16_t *udp_clientport);
node* create_node(int mode, s8_t role);
void init_node_pool(void);
void delete_node(node *n);
int hang_node(node* insert_node);
int hang_seednode(node* main_node ,node* insert_node);
node *seek_node(int con_id);
node *tryget_node(int n);
#endif
#endif //#ifndef __ATCMD_LWIP_H__

View file

@ -0,0 +1,195 @@
#include <platform_stdlib.h>
#include <platform_opts.h>
#include <gpio_api.h>
#include "log_service.h"
#include "atcmd_mp.h"
#if CONFIG_ATCMD_MP_EXT0
extern void fATM0(void *arg); // MP ext0 AT command
#endif
#if CONFIG_ATCMD_MP
//-------- AT MP commands ---------------------------------------------------------------
void fATMG(void *arg)
{
gpio_t gpio_test;
int argc = 0, val, cnts, i, write=0, data=0;
char *argv[MAX_ARGC] = {0}, port, num;
PinName pin = NC;
u32 tConfigDebugInfo = ConfigDebugInfo;
AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATMG]: _AT_MP_GPIO_TEST_");
if(!arg){
AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATMG] Usage: ATSG=w,PINNAMES(ex:A0B1C2...),VALUE(0/1)");
AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATMG] Usage: ATSG=r,PINNAMES(ex:A0B1C2...)");
return;
}
argc = parse_param(arg, argv);
cnts = strlen(argv[2]);
if(cnts % 2) return;
cnts /= 2;
if(cnts == 0) return;
if(strcmp(argv[1], "w") == 0){
write = 1;
if(strcmp(argv[3], "1") == 0)
data = 1;
}
// Remove debug info massage
_AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATMG] %s: ", argv[1]);
ConfigDebugInfo = 0;
for(i=0; i<(cnts*2); i+=2){
pin = NC;
port = argv[2][i];
num = argv[2][i+1];
if(port >= 'a' && port <= 'z')
port -= ('a' - 'A');
if(num >= 'a' && num <= 'z')
num -= ('a' - 'A');
switch(port){
case 'A':
switch(num){
case '0': pin = PA_0; break; case '1': pin = PA_1; break; case '2': pin = PA_2; break; case '3': pin = PA_3; break;
case '4': pin = PA_4; break; case '5': pin = PA_5; break; case '6': pin = PA_6; break; case '7': pin = PA_7; break;
}
break;
case 'B':
switch(num){
case '0': pin = PB_0; break; case '1': pin = PB_1; break; case '2': pin = PB_2; break; case '3': pin = PB_3; break;
case '4': pin = PB_4; break; case '5': pin = PB_5; break; case '6': pin = PB_6; break; case '7': pin = PB_7; break;
}
break;
case 'C':
switch(num){
case '0': pin = PC_0; break; case '1': pin = PC_1; break; case '2': pin = PC_2; break; case '3': pin = PC_3; break;
case '4': pin = PC_4; break; case '5': pin = PC_5; break; case '6': pin = PC_6; break; case '7': pin = PC_7; break;
case '8': pin = PC_8; break; case '9': pin = PC_9; break;
}
break;
case 'D':
switch(num){
case '0': pin = PD_0; break; case '1': pin = PD_1; break; case '2': pin = PD_2; break; case '3': pin = PD_3; break;
case '4': pin = PD_4; break; case '5': pin = PD_5; break; case '6': pin = PD_6; break; case '7': pin = PD_7; break;
case '8': pin = PD_8; break; case '9': pin = PD_9; break;
}
break;
case 'E':
switch(num){
case '0': pin = PE_0; break; case '1': pin = PE_1; break; case '2': pin = PE_2; break; case '3': pin = PE_3; break;
case '4': pin = PE_4; break; case '5': pin = PE_5; break; case '6': pin = PE_6; break; case '7': pin = PE_7; break;
case '8': pin = PE_8; break; case '9': pin = PE_9; break; case 'A': pin = PE_A; break;
}
break;
case 'F':
switch(num){
case '0': pin = PF_0; break; case '1': pin = PF_1; break; case '2': pin = PF_2; break; case '3': pin = PF_3; break;
case '4': pin = PF_4; break; case '5': pin = PF_5; break;
}
break;
case 'G':
switch(num){
case '0': pin = PG_0; break; case '1': pin = PG_1; break; case '2': pin = PG_2; break; case '3': pin = PG_3; break;
case '4': pin = PG_4; break; case '5': pin = PG_5; break; case '6': pin = PG_6; break; case '7': pin = PG_7; break;
}
break;
case 'H':
switch(num){
case '0': pin = PH_0; break; case '1': pin = PH_1; break; case '2': pin = PH_2; break; case '3': pin = PH_3; break;
case '4': pin = PH_4; break; case '5': pin = PH_5; break; case '6': pin = PH_6; break; case '7': pin = PH_7; break;
}
break;
case 'I':
switch(num){
case '0': pin = PI_0; break; case '1': pin = PI_1; break; case '2': pin = PI_2; break; case '3': pin = PI_3; break;
case '4': pin = PI_4; break; case '5': pin = PI_5; break; case '6': pin = PI_6; break; case '7': pin = PI_7; break;
}
break;
case 'J':
switch(num){
case '0': pin = PJ_0; break; case '1': pin = PJ_1; break; case '2': pin = PJ_2; break; case '3': pin = PJ_3; break;
case '4': pin = PJ_4; break; case '5': pin = PJ_5; break; case '6': pin = PJ_6; break;
}
break;
case 'K':
switch(num){
case '0': pin = PK_0; break; case '1': pin = PK_1; break; case '2': pin = PK_2; break; case '3': pin = PK_3; break;
case '4': pin = PK_4; break; case '5': pin = PK_5; break; case '6': pin = PK_6; break;
}
break;
}
if(pin == NC){
_AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "X,");
continue;
}
// Initial input control pin
gpio_init(&gpio_test, pin);
if(write){
gpio_dir(&gpio_test, PIN_OUTPUT); // Direction: Output
gpio_mode(&gpio_test, PullNone); // No pull
gpio_write(&gpio_test, data);
_AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "%d,", data);
}else{
gpio_dir(&gpio_test, PIN_INPUT); // Direction: Input
gpio_mode(&gpio_test, PullUp); // Pull-High
val = gpio_read(&gpio_test);
_AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "%d,", val);
}
}
_AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "\n");
// Recover debug info massage
ConfigDebugInfo = tConfigDebugInfo;
}
void fATMR(void *arg)
{
u32 idx;
AT_PRINTK("[ATMR]: _AT_MP_SDR_TEST_");
#ifdef CONFIG_SDR_EN
for (idx = 0; idx < 0x200000; idx = idx+4){
HAL_WRITE32(0x30000000, idx, 0x12345678);
if (HAL_READ32(0x30000000, idx) != 0x12345678) {
AT_PRINTK("[ATMR]: SDR test fail addr 0x08x, value 0x08%x",(0x30000000+idx),HAL_READ32(0x30000000, idx));
return;
}
}
AT_PRINTK("[ATMR]: SDR test success");
#endif
}
void fATMt(void *arg)
{
int argc = 0;
char *argv[MAX_ARGC] = {0};
AT_PRINTK("[ATM#]: _AT_MP_TEST_");
argc = parse_param(arg, argv);
}
void fATMx(void *arg)
{
AT_PRINTK("[ATM?]: _AT_MP_HELP_");
}
log_item_t at_mp_items[] = {
{"ATMG", fATMG,}, // MP GPIO test
{"ATMR", fATMR,}, // MP SDR test
{"ATM#", fATMt,}, // test command
{"ATM?", fATMx,}, // Help
#if CONFIG_ATCMD_MP_EXT0
{"ATM0", fATM0,}, // MP ext0 AT command
#endif
};
void at_mp_init(void)
{
log_service_add_table(at_mp_items, sizeof(at_mp_items)/sizeof(at_mp_items[0]));
}
#if SUPPORT_LOG_SERVICE
log_module_init(at_mp_init);
#endif
#endif // #if CONFIG_ATCMD_MP

View file

@ -0,0 +1,12 @@
#ifndef __ATCMD_MP_H__
#define __ATCMD_MP_H__
#define CONFIG_ATCMD_MP_EXT0 0 //support MP ext0 AT command
typedef struct _at_command_mp_ext_item_{
char *mp_ext_cmd;
int (*mp_ext_fun)(void **argv, int argc);
char *mp_ext_usage;
}at_mp_ext_item_t;
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,5 @@
#ifndef __ATCMD_SYS_H__
#define __ATCMD_SYS_H__
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,161 @@
#ifndef __ATCMD_WIFI_H__
#define __ATCMD_WIFI_H__
#include "main.h"
#include "lwip_netconf.h"
#ifndef WLAN0_NAME
#define WLAN0_NAME "wlan0"
#endif
#ifndef WLAN1_NAME
#define WLAN1_NAME "wlan1"
#endif
/* Give default value if not defined */
#ifndef NET_IF_NUM
#ifdef CONFIG_CONCURRENT_MODE
#define NET_IF_NUM ((CONFIG_ETHERNET) + (CONFIG_WLAN) + 1)
#else
#define NET_IF_NUM ((CONFIG_ETHERNET) + (CONFIG_WLAN))
#endif // end of CONFIG_CONCURRENT_MODE
#endif // end of NET_IF_NUM
/*Static IP ADDRESS*/
#ifndef IP_ADDR0
#define IP_ADDR0 192
#define IP_ADDR1 168
#define IP_ADDR2 1
#define IP_ADDR3 80
#endif
/*NETMASK*/
#ifndef NETMASK_ADDR0
#define NETMASK_ADDR0 255
#define NETMASK_ADDR1 255
#define NETMASK_ADDR2 255
#define NETMASK_ADDR3 0
#endif
/*Gateway Address*/
#ifndef GW_ADDR0
#define GW_ADDR0 192
#define GW_ADDR1 168
#define GW_ADDR2 1
#define GW_ADDR3 1
#endif
/*Static IP ADDRESS*/
#ifndef AP_IP_ADDR0
#define AP_IP_ADDR0 192
#define AP_IP_ADDR1 168
#define AP_IP_ADDR2 43
#define AP_IP_ADDR3 1
#endif
/*NETMASK*/
#ifndef AP_NETMASK_ADDR0
#define AP_NETMASK_ADDR0 255
#define AP_NETMASK_ADDR1 255
#define AP_NETMASK_ADDR2 255
#define AP_NETMASK_ADDR3 0
#endif
/*Gateway Address*/
#ifndef AP_GW_ADDR0
#define AP_GW_ADDR0 192
#define AP_GW_ADDR1 168
#define AP_GW_ADDR2 43
#define AP_GW_ADDR3 1
#endif
#if CONFIG_EXAMPLE_UART_ATCMD
#include "wifi_structures.h"
#include <wlan_fast_connect/example_wlan_fast_connect.h>
typedef struct _UART_LOG_CONF_{
u32 BaudRate;
u8 DataBits;
u8 StopBits;
u8 Parity;
u8 FlowControl;
}UART_LOG_CONF, *PUART_LOG_CONF;
#define ATCMD_WIFI_CONN_STORE_MAX_NUM (1)
struct atcmd_wifi_conf{
int32_t auto_enable;
rtw_wifi_setting_t setting;
int32_t reconn_num;
int32_t reconn_last_index;
struct wlan_fast_reconnect reconn[ATCMD_WIFI_CONN_STORE_MAX_NUM];
};
#define ATCMD_LWIP_CONN_STORE_MAX_NUM (1)
struct atcmd_lwip_conn_info{
int32_t role; //client, server or seed
uint32_t protocol; //tcp or udp
uint32_t remote_addr; //remote ip
uint32_t remote_port; //remote port
uint32_t local_addr; //locale ip, not used yet
uint32_t local_port; //locale port, not used yet
uint32_t reserved; //reserve for further use
};
struct atcmd_lwip_conf {
int32_t enable; //enable or not
int32_t conn_num;
int32_t last_index;
int32_t reserved; //reserve for further use
struct atcmd_lwip_conn_info conn[ATCMD_LWIP_CONN_STORE_MAX_NUM];
};
typedef enum {
AT_PARTITION_ALL = 0,
AT_PARTITION_UART = 1,
AT_PARTITION_WIFI = 2,
AT_PARTITION_LWIP = 3
} AT_PARTITION;
typedef enum {
AT_PARTITION_READ = 0,
AT_PARTITION_WRITE = 1,
AT_PARTITION_ERASE = 2
} AT_PARTITION_OP;
//first segment for uart
#define UART_SETTING_BACKUP_SECTOR (0x8000)
#define UART_CONF_DATA_OFFSET (0)
#define UART_CONF_DATA_SIZE ((((sizeof(UART_LOG_CONF)-1)>>2) + 1)<<2)
//second segment for wifi config
#define WIFI_CONF_DATA_OFFSET (UART_CONF_DATA_OFFSET+UART_CONF_DATA_SIZE)
#define WIFI_CONF_DATA_SIZE ((((sizeof(struct atcmd_wifi_conf)-1)>>2) + 1)<<2)
//fouth segment for lwip config
#define LWIP_CONF_DATA_OFFSET (WIFI_CONF_DATA_OFFSET+WIFI_CONF_DATA_SIZE)
#define LWIP_CONF_DATA_SIZE ((((sizeof(struct atcmd_lwip_conf)-1)>>2) + 1)<<2)
extern void atcmd_update_partition_info(AT_PARTITION id, AT_PARTITION_OP ops, u8 *data, u16 len);
#define ATSTRING_LEN (LOG_SERVICE_BUFLEN)
extern char at_string[ATSTRING_LEN];
extern unsigned char gAT_Echo; // default echo on
//extern void uart_at_lock(void);
//extern void uart_at_unlock(void);
extern void uart_at_send_string(char *str);
extern void uart_at_send_buf(u8 *buf, u32 len);
#define at_printf(fmt, args...) do{\
/*uart_at_lock();*/\
snprintf(at_string, ATSTRING_LEN, fmt, ##args); \
uart_at_send_string(at_string);\
/*uart_at_unlock();*/\
}while(0)
#define at_print_data(data, size) do{\
/*uart_at_lock();*/\
uart_at_send_buf(data, size);\
/*uart_at_unlock();*/\
}while(0)
#else
#define at_printf(fmt, args...) do{printf(fmt, ##args);}while(0)
#define at_print_data(data, size) do{__rtl_memDump(data, size, NULL);}while(0)
#endif//#if CONFIG_EXAMPLE_UART_ATCMD
#endif

View file

@ -0,0 +1,482 @@
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include "FreeRTOS.h"
#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1)
#include "freertos_pmu.h"
#endif
#include "log_service.h"
#include "task.h"
#include "semphr.h"
#include "main.h"
//#include "wifi_util.h"
#include "atcmd_wifi.h"
#if CONFIG_EXAMPLE_UART_ATCMD || CONFIG_EXAMPLE_SPI_ATCMD
#include "atcmd_lwip.h"
#endif
#if SUPPORT_LOG_SERVICE
//======================================================
struct list_head log_hash[ATC_INDEX_NUM];
extern void at_wifi_init(void);
extern void at_fs_init(void);
extern void at_sys_init(void);
extern void at_ethernet_init(void);
extern void at_google_init(void);
extern void at_transport_init(void);
//extern void at_app_init(void);
extern void at_mp_init(void);
void at_log_init(void);
char log_buf[LOG_SERVICE_BUFLEN];
#if CONFIG_LOG_HISTORY
char log_history[LOG_HISTORY_LEN][LOG_SERVICE_BUFLEN];
static unsigned int log_history_count = 0;
#endif
xSemaphoreHandle log_rx_interrupt_sema = NULL;
#if CONFIG_LOG_SERVICE_LOCK
xSemaphoreHandle log_service_sema = NULL;
#endif
extern xSemaphoreHandle uart_rx_interrupt_sema;
#if CONFIG_INIC_EN
extern unsigned char inic_cmd_ioctl;
#endif
//#if defined (__ICCARM__)
//#pragma section=".data.log_init"
//
//unsigned int __log_init_begin__;
//unsigned int __log_init_end__;
//#elif defined ( __CC_ARM ) || defined(__GNUC__)
#if defined (__ICCARM__) || defined ( __CC_ARM ) || defined(__GNUC__)
//#pragma section=".data.log_init"
log_init_t* __log_init_begin__;
log_init_t* __log_init_end__;
log_init_t log_init_table[] = {
at_wifi_init,
// at_fs_init,
at_sys_init,
at_log_init,
// at_app_init,
#if CONFIG_ETHERNET
at_ethernet_init,
#endif
#if CONFIG_GOOGLE_NEST
at_google_init,
#endif
#if CONFIG_TRANSPORT
at_transport_init,
#endif
#if CONFIG_ATCMD_MP
at_mp_init,
#endif
};
#else
#error "not implement, add to linker script"
extern unsigned int __log_init_begin__;
extern unsigned int __log_init_end__;
#endif
#if defined(__GNUC__)
#define USE_STRSEP
#endif
//======================================================
int hash_index(char *str)
{
unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
unsigned int hash = 0;
while (*str)
{
hash = hash * seed + (*str++);
}
return (hash & 0x7FFFFFFF);
}
void log_add_new_command(log_item_t *new)
{
int index = hash_index(new->log_cmd)%ATC_INDEX_NUM;
list_add(&new->node, &log_hash[index]);
}
void start_log_service(void);
void log_service_init(void)
{
int i;
//#if defined (__ICCARM__)
// log_init_t *log_init_table;
// __log_init_begin__ = (unsigned int)__section_begin(".data.log_init");
// __log_init_end__ = (unsigned int)__section_end(".data.log_init");
// log_init_table = (log_init_t *)__log_init_begin__;
//#elif defined(__CC_ARM) || defined(__GNUC__)
#if defined (__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
__log_init_begin__ = log_init_table;
__log_init_end__ = __log_init_begin__ + sizeof(log_init_table);
#else
#error "not implement"
#endif
for(i=0;i<ATC_INDEX_NUM;i++)
INIT_LIST_HEAD(&log_hash[i]);
for(i=0;i<(__log_init_end__-__log_init_begin__)/sizeof(log_init_t); i++)
log_init_table[i]();
/* Initial uart rx swmaphore*/
vSemaphoreCreateBinary(log_rx_interrupt_sema);
xSemaphoreTake(log_rx_interrupt_sema, 1/portTICK_RATE_MS);
#if CONFIG_LOG_SERVICE_LOCK
log_service_lock_init();
#endif
start_log_service();
}
//sizeof(log_items)/sizeof(log_items[0])
void log_service_add_table(log_item_t *tbl, int len)
{
int i;
for(i=0;i<len;i++)
log_add_new_command(&tbl[i]);
}
void* log_action(char *cmd)
{
int search_cnt=0;
int index = hash_index(cmd)%ATC_INDEX_NUM;
struct list_head *head = &log_hash[index];
struct list_head *iterator;
log_item_t *item;
void *act = NULL;
list_for_each(iterator, head) {
item = list_entry(iterator, log_item_t, node);
search_cnt++;
if( strcmp(item->log_cmd, cmd) == 0){
//printf("%s match %s, search cnt %d\n\r", cmd, item->log_cmd, search_cnt);
act = (void*)item->at_act;
break;
}
}
return act;
}
void* log_handler(char *cmd)
{
log_act_t action=NULL;
char buf[LOG_SERVICE_BUFLEN];
memset(buf, 0, LOG_SERVICE_BUFLEN);
char *copy=buf;
char *token = NULL;
char *param = NULL;
char tok[5] = {0};//'\0'
#if CONFIG_LOG_HISTORY
strcpy(log_history[((log_history_count++)%LOG_HISTORY_LEN)], log_buf);
#endif
strncpy(copy, cmd,LOG_SERVICE_BUFLEN-1);
#if defined(USE_STRSEP)
token = _strsep(&copy, "=");
param = copy;
#else
token = strtok(copy, "=");
param = strtok(NULL, NULL);
#endif
if(token && (strlen(token) <= 4))
strcpy(tok, token);
else{
//printf("\n\rAT Cmd format error!\n");
return NULL;
};
//printf(" Command %s \n\r ", tok);
//printf(" Param %s \n\r", param);
action = (log_act_t)log_action(tok);
if(action){
action(param);
}
return (void*)action;
}
int parse_param(char *buf, char **argv)
{
int argc = 1;
char str_buf[LOG_SERVICE_BUFLEN];
memset(str_buf, 0, LOG_SERVICE_BUFLEN);
int str_count = 0;
int buf_cnt = 0;
if(buf == NULL)
goto exit;
while((argc < MAX_ARGC) && (*buf != '\0')) {
while((*buf == ',') || (*buf == '[') || (*buf == ']')){
if((*buf == ',') && (*(buf+1) == ',')){
argv[argc] = NULL;
argc++;
}
*buf = '\0';
buf++;
}
if(*buf == '\0')
break;
else if(*buf == '"'){
memset(str_buf,'\0',LOG_SERVICE_BUFLEN);
str_count = 0;
buf_cnt = 0;
*buf = '\0';
buf ++;
if(*buf == '\0')
break;
argv[argc] = buf;
while((*buf != '"')&&(*buf != '\0')){
if(*buf == '\\'){
buf ++;
buf_cnt++;
}
str_buf[str_count] = *buf;
str_count++;
buf_cnt++;
buf ++;
}
*buf = '\0';
memcpy(buf-buf_cnt,str_buf,buf_cnt);
}
else{
argv[argc] = buf;
}
argc++;
buf++;
while( (*buf != ',')&&(*buf != '\0')&&(*buf != '[')&&(*buf != ']') )
buf++;
}
exit:
return argc;
}
unsigned char gDbgLevel = AT_DBG_ERROR;
unsigned int gDbgFlag = 0xFFFFFFFF;
void at_set_debug_level(unsigned char newDbgLevel)
{
gDbgLevel = newDbgLevel;
}
void at_set_debug_mask(unsigned int newDbgFlag)
{
gDbgFlag = newDbgFlag;
}
#if SUPPORT_INTERACTIVE_MODE
extern char uart_buf[64];
void legency_interactive_handler(unsigned char argc, unsigned char **argv)
{
#if 0 //defined(CONFIG_PLATFORM_8195A)
if(argc<1)
{
DiagPrintf("Wrong argument number!\r\n");
return;
}
DiagPrintf("Wlan Normal Mode\n");
WlanNormal( argc, argv);
#else
strncpy(uart_buf, log_buf, 63);//uart_buf[64]
xSemaphoreGive(uart_rx_interrupt_sema);
#endif
}
#endif
#if CONFIG_WLAN
#ifndef WLAN0_NAME
#define WLAN0_NAME "wlan0"
#endif
#ifndef WLAN1_NAME
#define WLAN1_NAME "wlan1"
#endif
int mp_commnad_handler(char *cmd)
{
char buf[64];
char *token = NULL;
memset(buf, 0, 64);
//strcpy(buf, cmd);
strncpy(buf, cmd, (64-1));
token = strtok(buf, " ");
if(token && (strcmp(buf, "iwpriv") == 0)){
token = strtok(NULL, "");
wext_private_command(WLAN0_NAME, token, 1);
return 0;
}
return -1;
}
#endif
void print_help_msg(void){
#if CONFIG_WLAN
extern void print_wlan_help(void);
print_wlan_help();
#endif
//add other help message print here
}
int print_help_handler(char *cmd){
if(strcmp(cmd, "help") == 0){
print_help_msg();
return 0;
}
return -1;
}
#if CONFIG_LOG_SERVICE_LOCK
void log_service_lock(void)
{
rtw_down_sema(&log_service_sema);
}
u32 log_service_lock_timeout(u32 ms)
{
return rtw_down_timeout_sema(&log_service_sema, ms);
}
void log_service_unlock(void)
{
rtw_up_sema(&log_service_sema);
}
void log_service_lock_init(void){
rtw_init_sema(&log_service_sema, 1);
}
#endif
void log_service(void *param)
{
_AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ALWAYS, "\n\rStart LOG SERVICE MODE\n\r");
_AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ALWAYS, "\n\r# ");
while(1){
while(xSemaphoreTake(log_rx_interrupt_sema, portMAX_DELAY) != pdTRUE);
#if CONFIG_LOG_SERVICE_LOCK
log_service_lock();
#endif
if(log_handler((char *)log_buf) == NULL){
#if CONFIG_WLAN
if(mp_commnad_handler((char *)log_buf) < 0)
#endif
{
#if SUPPORT_INTERACTIVE_MODE
print_help_handler((char *)log_buf);
legency_interactive_handler(NULL, NULL);
#else
if(print_help_handler((char *)log_buf) < 0){
at_printf("\r\nunknown command '%s'", log_buf);
}
#endif
}
}
log_buf[0] = '\0';
#if CONFIG_INIC_EN
inic_cmd_ioctl = 0;
#endif
_AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ALWAYS, "\n\r[MEM] After do cmd, available heap %d\n\r", xPortGetFreeHeapSize());
_AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ALWAYS, "\r\n\n# "); //"#" is needed for mp tool
#if CONFIG_EXAMPLE_UART_ATCMD
if(atcmd_lwip_is_tt_mode())
at_printf(STR_END_OF_ATDATA_RET);
else
at_printf(STR_END_OF_ATCMD_RET);
#endif
#if CONFIG_LOG_SERVICE_LOCK
log_service_unlock();
#endif
#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1)
pmu_release_wakelock(BIT(PMU_LOGUART_DEVICE));
#endif
}
}
#define STACKSIZE 1280
void start_log_service(void)
{
xTaskHandle CreatedTask;
int result;
#if CONFIG_USE_TCM_HEAP
/*********************************************************************
*
* ATCMD V2 supports commands for SSL
* It will cause problems while doing SSL operations if the stack is placed in TCM region
*
*********************************************************************/
void *stack_addr = NULL;
#if (ATCMD_VER == ATVER_1) || ((ATCMD_VER == ATVER_2)&&(ATCMD_SUPPORT_SSL == 0))
extern void *tcm_heap_malloc(int size);
stack_addr = tcm_heap_malloc(STACKSIZE * sizeof(int));
if(stack_addr == NULL){
}
#endif
result = xTaskGenericCreate(
log_service,
( signed portCHAR * ) "log_service",
STACKSIZE,
NULL,
tskIDLE_PRIORITY + 5,
&CreatedTask,
stack_addr,
NULL);
#else
result = xTaskCreate( log_service, ( signed portCHAR * ) "log_service", STACKSIZE, NULL, tskIDLE_PRIORITY + 5, &CreatedTask );
#endif
if(result != pdPASS) {
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
}
}
void fAT_exit(void *arg){
printf("\n\rLeave LOG SERVICE");
vTaskDelete(NULL);
}
#if CONFIG_LOG_HISTORY
void fAT_log(void *arg){
int i = 0;
printf("[AT]log history:\n\n\r");
if(log_history_count > LOG_HISTORY_LEN){
for(i=0; i<4; i++)
printf(" %s\n\r", log_history[((log_history_count+i)%LOG_HISTORY_LEN)]);
}
else{
for(i=0; i<(log_history_count-1); i++)
printf(" %s\n\r", log_history[i]);
}
}
#endif
log_item_t at_log_items[ ] = {
{"AT--", fAT_exit,},
#if CONFIG_LOG_HISTORY
{"AT??", fAT_log,},
#endif
{"ATxx", fAT_exit,}
};
void at_log_init(void)
{
log_service_add_table(at_log_items, sizeof(at_log_items)/sizeof(at_log_items[0]));
}
log_module_init(at_log_init);
#endif

View file

@ -0,0 +1,127 @@
#ifndef LOG_SERVICE_H
#define LOG_SERVICE_H
#include "dlist.h"
/*
* Include user defined options first. Anything not defined in these files
* will be set to standard values. Override anything you dont like!
*/
#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B)
#include "platform_opts.h"
#include "platform_stdlib.h"
#endif
//#ifdef __ICCARM__
//#define STRINGIFY(s) #s
//#define SECTION(_name) _Pragma( STRINGIFY(location=_name))
//#define log_module_init(fn) \
// SECTION(".data.log_init") __root static void* log_##fn = (void*)fn
//#elif defined(__CC_ARM)
//#define log_module_init(fn) \
//static void* log_##fn __attribute__((section(".data.log_init"))) = (void*)fn;
//#define DiagPrintf printf
//#elif defined(__GNUC__)
//#define log_module_init(fn) \
//static void* log_##fn __attribute__((section(".data.log_init"))) = (void*)fn;
//#else
//#error "not implement"
//#endif
#define log_module_init(fn)
#define ATC_INDEX_NUM 32
#ifndef SUPPORT_LOG_SERVICE
#define SUPPORT_LOG_SERVICE 1
#endif
//LOG_SERVICE_BUFLEN: default, only 63 bytes could be used for keeping input
// cmd, the last byte is for string end ('\0').
#ifndef LOG_SERVICE_BUFLEN
#define LOG_SERVICE_BUFLEN 64
#endif
#ifndef CONFIG_LOG_HISTORY
#define CONFIG_LOG_HISTORY 0
#if CONFIG_LOG_HISTORY
#define LOG_HISTORY_LEN 5
#endif
#endif //#ifndef CONFIG_LOG_HISTORY
#ifndef MAX_ARGC
#define MAX_ARGC 12
#endif
#ifndef CONFIG_LOG_SERVICE_LOCK
#define CONFIG_LOG_SERVICE_LOCK 0 // //to protect log_buf[], only one command processed per time
#endif
#define AT_BIT(n) (1<<n)
#define AT_FLAG_DUMP AT_BIT(0)
#define AT_FLAG_EDIT AT_BIT(1)
#define AT_FLAG_ADC AT_BIT(2)
#define AT_FLAG_GPIO AT_BIT(3)
#define AT_FLAG_OTA AT_BIT(4)
#define AT_FLAG_NFC AT_BIT(5)
#define AT_FLAG_OS AT_BIT(6)
#define AT_FLAG_LWIP AT_BIT(7)
#define AT_FLAG_COMMON AT_BIT(8)
#define AT_FLAG_WIFI AT_BIT(9)
#define AT_FLAG_RDP AT_BIT(10)
enum{
AT_DBG_OFF = 0,
AT_DBG_ALWAYS,
AT_DBG_ERROR,
AT_DBG_WARNING,
AT_DBG_INFO
};
extern unsigned char gDbgLevel;
extern unsigned int gDbgFlag;
#define AT_PRINTK(...) \
do{ \
printf(__VA_ARGS__); \
printf("\r\n"); \
}while(0)
#define _AT_PRINTK(...) printf(__VA_ARGS__)
#define AT_DBG_MSG(flag, level, ...) \
do{ \
if(((flag) & gDbgFlag) && (level <= gDbgLevel)){ \
AT_PRINTK(__VA_ARGS__); \
} \
}while(0)
#define _AT_DBG_MSG(flag, level, ...) \
do{ \
if(((flag) & gDbgFlag) && (level <= gDbgLevel)){ \
_AT_PRINTK(__VA_ARGS__); \
} \
}while(0)
#ifndef SUPPORT_INTERACTIVE_MODE
#define SUPPORT_INTERACTIVE_MODE 0
#endif //#ifndef SUPPORT_INTERACTIVE_MODE
typedef void (*log_init_t)(void);
typedef void (*log_act_t)(void*);
typedef struct _at_command_item_{
char *log_cmd;
log_act_t at_act;
struct list_head node;
}log_item_t;
void log_service_add_table(log_item_t *tbl, int len);
int parse_param(char *buf, char **argv);
#if CONFIG_LOG_SERVICE_LOCK
void log_service_lock_init(void);
void log_service_lock(void);
u32 log_service_lock_timeout(u32 ms);
void log_service_unlock(void);
#endif
#define C_NUM_AT_CMD 4 //"ATxx", 4 characters
#define C_NUM_AT_CMD_DLT 1 //"=", 1 charater
#define STR_END_OF_ATCMD_RET "\r\n\n# " //each AT command response will end with this string
#define STR_END_OF_ATDATA_RET "\r\n\n> " //data transparent transmission indicator
#endif

View file

@ -0,0 +1,454 @@
/* Includes ------------------------------------------------------------------*/
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/dhcp.h"
#include "lwip/dns.h"
#include "ethernetif.h"
#include "main.h"
#include "lwip_netconf.h"
#if CONFIG_WLAN
#include "wifi_ind.h"
#endif
#if defined(STM32F2XX)
#include "stm322xg_eval_lcd.h"
#elif defined(STM32F4XX)
#include "stm324xg_eval_lcd.h"
#endif
#include <platform/platform_stdlib.h>
/*Static IP ADDRESS*/
#ifndef IP_ADDR0
#define IP_ADDR0 192
#define IP_ADDR1 168
#define IP_ADDR2 1
#define IP_ADDR3 80
#endif
/*NETMASK*/
#ifndef NETMASK_ADDR0
#define NETMASK_ADDR0 255
#define NETMASK_ADDR1 255
#define NETMASK_ADDR2 255
#define NETMASK_ADDR3 0
#endif
/*Gateway Address*/
#ifndef GW_ADDR0
#define GW_ADDR0 192
#define GW_ADDR1 168
#define GW_ADDR2 1
#define GW_ADDR3 1
#endif
/*Static IP ADDRESS*/
#ifndef AP_IP_ADDR0
#define AP_IP_ADDR0 192
#define AP_IP_ADDR1 168
#define AP_IP_ADDR2 43
#define AP_IP_ADDR3 1
#endif
/*NETMASK*/
#ifndef AP_NETMASK_ADDR0
#define AP_NETMASK_ADDR0 255
#define AP_NETMASK_ADDR1 255
#define AP_NETMASK_ADDR2 255
#define AP_NETMASK_ADDR3 0
#endif
/*Gateway Address*/
#ifndef AP_GW_ADDR0
#define AP_GW_ADDR0 192
#define AP_GW_ADDR1 168
#define AP_GW_ADDR2 43
#define AP_GW_ADDR3 1
#endif
/*Static IP ADDRESS FOR ETHERNET*/
#ifndef ETH_IP_ADDR0
#define ETH_IP_ADDR0 192
#define ETH_IP_ADDR1 168
#define ETH_IP_ADDR2 0
#define ETH_IP_ADDR3 80
#endif
/*NETMASK FOR ETHERNET*/
#ifndef ETH_NETMASK_ADDR0
#define ETH_NETMASK_ADDR0 255
#define ETH_NETMASK_ADDR1 255
#define ETH_NETMASK_ADDR2 255
#define ETH_NETMASK_ADDR3 0
#endif
/*Gateway address for ethernet*/
#ifndef ETH_GW_ADDR0
#define ETH_GW_ADDR0 192
#define ETH_GW_ADDR1 168
#define ETH_GW_ADDR2 0
#define ETH_GW_ADDR3 1
#endif
/* Private define ------------------------------------------------------------*/
#define MAX_DHCP_TRIES 5
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
struct netif xnetif[NET_IF_NUM]; /* network interface structure */
/* Private functions ---------------------------------------------------------*/
/**
* @brief Initializes the lwIP stack
* @param None
* @retval None
*/
#if CONFIG_WLAN
extern int error_flag;
extern rtw_mode_t wifi_mode;
#endif
int lwip_init_done = 0;
void LwIP_Init(void)
{
struct ip_addr ipaddr;
struct ip_addr netmask;
struct ip_addr gw;
int8_t idx = 0;
/* Create tcp_ip stack thread */
tcpip_init( NULL, NULL );
/* - netif_add(struct netif *netif, struct ip_addr *ipaddr,
struct ip_addr *netmask, struct ip_addr *gw,
void *state, err_t (* init)(struct netif *netif),
err_t (* input)(struct pbuf *p, struct netif *netif))
Adds your network interface to the netif_list. Allocate a struct
netif and pass a pointer to this structure as the first argument.
Give pointers to cleared ip_addr structures when using DHCP,
or fill them with sane numbers otherwise. The state pointer may be NULL.
The init function pointer must point to a initialization function for
your ethernet netif interface. The following code illustrates it's use.*/
//printf("NET_IF_NUM:%d\n\r",NET_IF_NUM);
for(idx=0;idx<NET_IF_NUM;idx++){
if(idx==0){
IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3);
IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
}
else{
IP4_ADDR(&ipaddr, AP_IP_ADDR0, AP_IP_ADDR1, AP_IP_ADDR2, AP_IP_ADDR3);
IP4_ADDR(&netmask, AP_NETMASK_ADDR0, AP_NETMASK_ADDR1 , AP_NETMASK_ADDR2, AP_NETMASK_ADDR3);
IP4_ADDR(&gw, AP_GW_ADDR0, AP_GW_ADDR1, AP_GW_ADDR2, AP_GW_ADDR3);
}
#if CONFIG_ETHERNET
if(idx == NET_IF_NUM - 1)
{
IP4_ADDR(&ipaddr, ETH_IP_ADDR0, ETH_IP_ADDR1, ETH_IP_ADDR2, ETH_IP_ADDR3);
IP4_ADDR(&netmask, ETH_NETMASK_ADDR0, ETH_NETMASK_ADDR1 , ETH_NETMASK_ADDR2, ETH_NETMASK_ADDR3);
IP4_ADDR(&gw, ETH_GW_ADDR0, ETH_GW_ADDR1, ETH_GW_ADDR2, ETH_GW_ADDR3);
}
#endif
xnetif[idx].name[0] = 'r';
xnetif[idx].name[1] = '0'+idx;
#if CONFIG_ETHERNET
if(idx == NET_IF_NUM - 1)
netif_add(&xnetif[idx], &ipaddr, &netmask, &gw, NULL, &ethernetif_mii_init, &tcpip_input);
else
netif_add(&xnetif[idx], &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &tcpip_input);
#else
netif_add(&xnetif[idx], &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &tcpip_input);
#endif
printf("interface %d is initialized\n", idx);
}
/* Registers the default network interface. */
netif_set_default(&xnetif[0]);
/*move these operations to wifi_on/wifi_off*/
#if 0
/* When the netif is fully configured this function must be called.*/
for(idx = 0;idx < NET_IF_NUM;idx++)
netif_set_up(&xnetif[idx]);
#endif
lwip_init_done = 1;
}
/**
* @brief LwIP_DHCP_Process_Handle
* @param None
* @retval None
*/
uint8_t LwIP_DHCP(uint8_t idx, uint8_t dhcp_state)
{
struct ip_addr ipaddr;
struct ip_addr netmask;
struct ip_addr gw;
uint32_t IPaddress;
uint8_t iptab[4];
uint8_t DHCP_state;
int mscnt = 0;
struct netif *pnetif = NULL;
DHCP_state = dhcp_state;
#if !CONFIG_ETHERNET
if(idx > 1)
idx = 1;
#endif
pnetif = &xnetif[idx];
if(DHCP_state == 0){
pnetif->ip_addr.addr = 0;
pnetif->netmask.addr = 0;
pnetif->gw.addr = 0;
}
for (;;)
{
//printf("\n\r ========DHCP_state:%d============\n\r",DHCP_state);
switch (DHCP_state)
{
case DHCP_START:
{
#if CONFIG_WLAN
wifi_unreg_event_handler(WIFI_EVENT_BEACON_AFTER_DHCP, wifi_rx_beacon_hdl);
#endif
dhcp_start(pnetif);
IPaddress = 0;
DHCP_state = DHCP_WAIT_ADDRESS;
}
break;
case DHCP_WAIT_ADDRESS:
{
/* If DHCP stopped by wifi_disconn_hdl*/
if(pnetif->dhcp->state == 0)
{
IP4_ADDR(&ipaddr, IP_ADDR0 ,IP_ADDR1 , IP_ADDR2 , IP_ADDR3 );
IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
netif_set_addr(pnetif, &ipaddr , &netmask, &gw);
printf("\n\rLwIP_DHCP: dhcp stop.");
return DHCP_STOP;
}
/* Read the new IP address */
IPaddress = pnetif->ip_addr.addr;
if (IPaddress!=0)
{
DHCP_state = DHCP_ADDRESS_ASSIGNED;
#if CONFIG_WLAN
wifi_reg_event_handler(WIFI_EVENT_BEACON_AFTER_DHCP, wifi_rx_beacon_hdl, NULL);
#endif
/* Stop DHCP */
// dhcp_stop(pnetif); /* can not stop, need to renew, Robbie*/
iptab[0] = (uint8_t)(IPaddress >> 24);
iptab[1] = (uint8_t)(IPaddress >> 16);
iptab[2] = (uint8_t)(IPaddress >> 8);
iptab[3] = (uint8_t)(IPaddress);
printf("\n\rInterface %d IP address : %d.%d.%d.%d", idx, iptab[3], iptab[2], iptab[1], iptab[0]);
#if CONFIG_WLAN
error_flag = RTW_NO_ERROR;
#endif
return DHCP_ADDRESS_ASSIGNED;
}
else
{
/* DHCP timeout */
if (pnetif->dhcp->tries > MAX_DHCP_TRIES)
{
DHCP_state = DHCP_TIMEOUT;
/* Stop DHCP */
dhcp_stop(pnetif);
/* Static address used */
IP4_ADDR(&ipaddr, IP_ADDR0 ,IP_ADDR1 , IP_ADDR2 , IP_ADDR3 );
IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
netif_set_addr(pnetif, &ipaddr , &netmask, &gw);
iptab[0] = IP_ADDR3;
iptab[1] = IP_ADDR2;
iptab[2] = IP_ADDR1;
iptab[3] = IP_ADDR0;
printf("\n\rInterface %d DHCP timeout",idx);
printf("\n\rStatic IP address : %d.%d.%d.%d", iptab[3], iptab[2], iptab[1], iptab[0]);
#if CONFIG_WLAN
error_flag = RTW_DHCP_FAIL;
#endif
#if CONFIG_ETHERNET
if(idx == NET_IF_NUM -1) // This is the ethernet interface, set it up for static ip address
netif_set_up(pnetif);
#endif
return DHCP_TIMEOUT;
}else
{
//sys_msleep(DHCP_FINE_TIMER_MSECS);
vTaskDelay(DHCP_FINE_TIMER_MSECS);
dhcp_fine_tmr();
mscnt += DHCP_FINE_TIMER_MSECS;
if (mscnt >= DHCP_COARSE_TIMER_SECS*1000)
{
dhcp_coarse_tmr();
mscnt = 0;
}
}
}
}
break;
case DHCP_RELEASE_IP:
#if CONFIG_WLAN
wifi_unreg_event_handler(WIFI_EVENT_BEACON_AFTER_DHCP, wifi_rx_beacon_hdl);
#endif
printf("\n\rLwIP_DHCP: Release ip");
dhcp_release_unicast(pnetif);
return DHCP_RELEASE_IP;
case DHCP_STOP:
#if CONFIG_WLAN
wifi_unreg_event_handler(WIFI_EVENT_BEACON_AFTER_DHCP, wifi_rx_beacon_hdl);
#endif
printf("\n\rLwIP_DHCP: dhcp stop.");
dhcp_stop(pnetif);
return DHCP_STOP;
default:
break;
}
}
}
void LwIP_ReleaseIP(uint8_t idx)
{
struct ip_addr ipaddr;
struct ip_addr netmask;
struct ip_addr gw;
struct netif *pnetif = &xnetif[idx];
IP4_ADDR(&ipaddr, 0, 0, 0, 0);
IP4_ADDR(&netmask, 255, 255, 255, 0);
IP4_ADDR(&gw, 0, 0, 0, 0);
netif_set_addr(pnetif, &ipaddr , &netmask, &gw);
}
uint8_t* LwIP_GetMAC(struct netif *pnetif)
{
return (uint8_t *) (pnetif->hwaddr);
}
uint8_t* LwIP_GetIP(struct netif *pnetif)
{
return (uint8_t *) &(pnetif->ip_addr);
}
uint8_t* LwIP_GetGW(struct netif *pnetif)
{
return (uint8_t *) &(pnetif->gw);
}
uint8_t* LwIP_GetMASK(struct netif *pnetif)
{
return (uint8_t *) &(pnetif->netmask);
}
uint8_t* LwIP_GetBC(struct netif *pnetif)
{
return (uint8_t *) &(pnetif->dhcp->offered_bc_addr);
}
#if LWIP_DNS
void LwIP_GetDNS(struct ip_addr* dns)
{
*dns = dns_getserver(0);
}
void LwIP_SetDNS(struct ip_addr* dns)
{
dns_setserver(0, dns);
}
#endif
void LwIP_UseStaticIP(struct netif *pnetif)
{
struct ip_addr ipaddr;
struct ip_addr netmask;
struct ip_addr gw;
/* Static address used */
if(pnetif->name[1] == '0'){
#if CONFIG_WLAN
if(wifi_mode == RTW_MODE_STA){
IP4_ADDR(&ipaddr, IP_ADDR0 ,IP_ADDR1 , IP_ADDR2 , IP_ADDR3 );
IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
}
else if(wifi_mode == RTW_MODE_AP){
IP4_ADDR(&ipaddr, AP_IP_ADDR0, AP_IP_ADDR1, AP_IP_ADDR2, AP_IP_ADDR3);
IP4_ADDR(&netmask, AP_NETMASK_ADDR0, AP_NETMASK_ADDR1 , AP_NETMASK_ADDR2, AP_NETMASK_ADDR3);
IP4_ADDR(&gw, AP_GW_ADDR0, AP_GW_ADDR1, AP_GW_ADDR2, AP_GW_ADDR3);
}
#endif
}else{
IP4_ADDR(&ipaddr, AP_IP_ADDR0, AP_IP_ADDR1, AP_IP_ADDR2, AP_IP_ADDR3);
IP4_ADDR(&netmask, AP_NETMASK_ADDR0, AP_NETMASK_ADDR1 , AP_NETMASK_ADDR2, AP_NETMASK_ADDR3);
IP4_ADDR(&gw, AP_GW_ADDR0, AP_GW_ADDR1, AP_GW_ADDR2, AP_GW_ADDR3);
}
netif_set_addr(pnetif, &ipaddr , &netmask, &gw);
}
#if LWIP_AUTOIP
#include <lwip/autoip.h>
void LwIP_AUTOIP(struct netif *pnetif)
{
uint8_t *ip = LwIP_GetIP(pnetif);
autoip_start(pnetif);
while((pnetif->autoip->state == AUTOIP_STATE_PROBING) || (pnetif->autoip->state == AUTOIP_STATE_ANNOUNCING)) {
vTaskDelay(1000);
}
if(*((uint32_t *) ip) == 0) {
struct ip_addr ipaddr;
struct ip_addr netmask;
struct ip_addr gw;
printf("AUTOIP timeout\n");
/* Static address used */
IP4_ADDR(&ipaddr, IP_ADDR0 ,IP_ADDR1 , IP_ADDR2 , IP_ADDR3 );
IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
netif_set_addr(pnetif, &ipaddr , &netmask, &gw);
printf("Static IP address : %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
}
else {
printf("\nLink-local address: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
}
}
#endif
#if LWIP_IPV6
/* Get IPv6 address with lwip 1.5.0 */
void LwIP_AUTOIP_IPv6(struct netif *pnetif)
{
uint8_t *ipv6 = (uint8_t *) &(pnetif->ip6_addr[0].addr[0]);
netif_create_ip6_linklocal_address(pnetif, 1);
printf("\nIPv6 link-local address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
ipv6[0], ipv6[1], ipv6[2], ipv6[3], ipv6[4], ipv6[5], ipv6[6], ipv6[7],
ipv6[8], ipv6[9], ipv6[10], ipv6[11], ipv6[12], ipv6[13], ipv6[14], ipv6[15]);
}
#endif

View file

@ -0,0 +1,91 @@
/**
******************************************************************************
* @file netconf.h
* @author MCD Application Team
* @version V1.1.0
* @date 07-October-2011
* @brief This file contains all the functions prototypes for the netconf.c
* file.
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __NETCONF_H
#define __NETCONF_H
#ifdef __cplusplus
extern "C" {
#endif
#include "tcpip.h"
/* Includes ------------------------------------------------------------------*/
#include <platform/platform_stdlib.h>
#include "platform_opts.h"
#include "autoconf.h"
// macros
/* Give default value if not defined */
#ifndef NET_IF_NUM
#ifdef CONFIG_CONCURRENT_MODE
#define NET_IF_NUM ((CONFIG_ETHERNET) + (CONFIG_WLAN) + 1)
#else
#define NET_IF_NUM ((CONFIG_ETHERNET) + (CONFIG_WLAN))
#endif // end of CONFIG_CONCURRENT_MODE
#endif // end of NET_IF_NUM
/* Private typedef -----------------------------------------------------------*/
typedef enum
{
DHCP_START=0,
DHCP_WAIT_ADDRESS,
DHCP_ADDRESS_ASSIGNED,
DHCP_RELEASE_IP,
DHCP_STOP,
DHCP_TIMEOUT
} DHCP_State_TypeDef;
/* Extern functions ------------------------------------------------------------*/
void wifi_rx_beacon_hdl( char* buf, int buf_len, int flags, void* userdata);
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void LwIP_Init(void);
uint8_t LwIP_DHCP(uint8_t idx, uint8_t dhcp_state);
unsigned char* LwIP_GetMAC(struct netif *pnetif);
unsigned char* LwIP_GetIP(struct netif *pnetif);
unsigned char* LwIP_GetGW(struct netif *pnetif);
uint8_t* LwIP_GetMASK(struct netif *pnetif);
uint8_t* LwIP_GetBC(struct netif *pnetif);
#if LWIP_DNS
void LwIP_GetDNS(struct ip_addr* dns);
void LwIP_SetDNS(struct ip_addr* dns);
#endif
void LwIP_UseStaticIP(struct netif *pnetif);
#if LWIP_AUTOIP
void LwIP_AUTOIP(struct netif *pnetif);
#endif
#if LWIP_IPV6
void LwIP_AUTOIP_IPv6(struct netif *pnetif);
#endif
#ifdef __cplusplus
}
#endif
#endif /* __NETCONF_H */
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

View file

@ -0,0 +1,318 @@
/**
******************************************************************************
* @file lwipopts.h
* @author MCD Application Team
* @version V1.1.0
* @date 07-October-2011
* @brief lwIP Options Configuration.
* This file is based on Utilities\lwip_v1.3.2\src\include\lwip\opt.h
* and contains the lwIP configuration for the STM32F2x7 demonstration.
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
#ifndef __LWIPOPTS_H__
#define __LWIPOPTS_H__
#include <platform/platform_stdlib.h>
#include "platform_opts.h"
#define WIFI_LOGO_CERTIFICATION_CONFIG 0 //for ping 10k test buffer setting
/**
* SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
* critical regions during buffer allocation, deallocation and memory
* allocation and deallocation.
*/
#define SYS_LIGHTWEIGHT_PROT 1
/* Define LWIP_COMPAT_MUTEX if the port has no mutexes and binary semaphores
should be used instead */
#define LWIP_COMPAT_MUTEX 1
#define ETHARP_TRUST_IP_MAC 0
#define IP_REASSEMBLY 1
#define IP_FRAG 1
#define ARP_QUEUEING 0
/**
* NO_SYS==1: Provides VERY minimal functionality. Otherwise,
* use lwIP facilities.
*/
#define NO_SYS 0
#ifndef CONFIG_DYNAMIC_TICKLESS
#define CONFIG_DYNAMIC_TICKLESS 0
#endif
/* ---------- Memory options ---------- */
/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
byte alignment -> define MEM_ALIGNMENT to 2. */
#define MEM_ALIGNMENT 4
/* MEM_SIZE: the size of the heap memory. If the application will send
a lot of data that needs to be copied, this should be set high. */
#if WIFI_LOGO_CERTIFICATION_CONFIG
#define MEM_SIZE (10*1024) //for ping 10k test
#elif CONFIG_ETHERNET
#define MEM_SIZE (6*1024) //for iperf test
#else
#define MEM_SIZE (5*1024)
#endif
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
sends a lot of data out of ROM (or other static memory), this
should be set high. */
#define MEMP_NUM_PBUF 100
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
per active UDP "connection". */
#define MEMP_NUM_UDP_PCB 6
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
connections. */
#define MEMP_NUM_TCP_PCB 10
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
connections. */
#define MEMP_NUM_TCP_PCB_LISTEN 5
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
segments. */
#define MEMP_NUM_TCP_SEG 20
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
timeouts. */
#define MEMP_NUM_SYS_TIMEOUT 10
/* ---------- Pbuf options ---------- */
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
#if WIFI_LOGO_CERTIFICATION_CONFIG
#define PBUF_POOL_SIZE 30 //for ping 10k test
#else
#define PBUF_POOL_SIZE 20
#endif
/* IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled.*/
#if WIFI_LOGO_CERTIFICATION_CONFIG
#define IP_REASS_MAX_PBUFS 30 //for ping 10k test
#else
#define IP_REASS_MAX_PBUFS 10
#endif
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
#define PBUF_POOL_BUFSIZE 500
/* ---------- TCP options ---------- */
#define LWIP_TCP 1
#define TCP_TTL 255
/* Controls if TCP should queue segments that arrive out of
order. Define to 0 if your device is low on memory. */
#define TCP_QUEUE_OOSEQ 1
/* TCP Maximum segment size. */
#define TCP_MSS (1500 - 40) /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */
/* TCP sender buffer space (bytes). */
#define TCP_SND_BUF (5*TCP_MSS)
/* TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least
as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. */
#define TCP_SND_QUEUELEN (4* TCP_SND_BUF/TCP_MSS)
/* TCP receive window. */
#define TCP_WND (2*TCP_MSS)
/* ---------- ICMP options ---------- */
#define LWIP_ICMP 1
/* ---------- ARP options ----------- */
#define LWIP_ARP 1
/* ---------- DHCP options ---------- */
/* Define LWIP_DHCP to 1 if you want DHCP configuration of
interfaces. DHCP is not implemented in lwIP 0.5.1, however, so
turning this on does currently not work. */
#define LWIP_DHCP 1
/* ---------- UDP options ---------- */
#define LWIP_UDP 1
#define UDP_TTL 255
/* ---------- DNS options ---------- */
#define LWIP_DNS 1
/* ---------- UPNP options --------- */
#define LWIP_UPNP 0
/* Support Multicast */
#define LWIP_IGMP 1
#define LWIP_RAND() rand()
#define LWIP_SRAND() srand(sys_now())
/* Support TCP Keepalive */
#define LWIP_TCP_KEEPALIVE 1
/*LWIP_UART_ADAPTER==1: Enable LWIP_UART_ADAPTER when CONFIG_GAGENT is enabled,
because some GAGENT functions denpond on the following macro definitions.*/
#define LWIP_UART_ADAPTER 0
#if LWIP_UART_ADAPTER || CONFIG_ETHERNET
#undef LWIP_SO_SNDTIMEO
#define LWIP_SO_SNDTIMEO 1
#undef SO_REUSE
#define SO_REUSE 1
#undef MEMP_NUM_NETCONN
#define MEMP_NUM_NETCONN 10
#undef TCP_WND
#define TCP_WND (4*TCP_MSS)
#define TCP_KEEPIDLE_DEFAULT 10000UL
#define TCP_KEEPINTVL_DEFAULT 1000UL
#define TCP_KEEPCNT_DEFAULT 10U
#endif
#if CONFIG_EXAMPLE_UART_ATCMD || CONFIG_EXAMPLE_SPI_ATCMD
#undef LWIP_SO_SNDTIMEO
#define LWIP_SO_SNDTIMEO 1
#undef SO_REUSE
#define SO_REUSE 1
#undef SO_REUSE_RXTOALL
#define SO_REUSE_RXTOALL 1
#undef MEMP_NUM_NETCONN
#define MEMP_NUM_NETCONN 10
#undef MEMP_NUM_TCP_PCB
#define MEMP_NUM_TCP_PCB (MEMP_NUM_NETCONN)
#undef MEMP_NUM_UDP_PCB
#define MEMP_NUM_UDP_PCB (MEMP_NUM_NETCONN)
#undef TCP_WND
#define TCP_WND (4*TCP_MSS)
#define TCP_KEEPIDLE_DEFAULT 10000UL
#define TCP_KEEPINTVL_DEFAULT 1000UL
#define TCP_KEEPCNT_DEFAULT 10U
#define ERRNO 1
#endif
/* ---------- Statistics options ---------- */
#define LWIP_STATS 0
#define LWIP_PROVIDE_ERRNO 1
/*
--------------------------------------
---------- Checksum options ----------
--------------------------------------
*/
/*
The STM32F2x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums by hardware:
- To use this feature let the following define uncommented.
- To disable it and process by CPU comment the the checksum.
*/
//Do checksum by lwip - WLAN nic does not support Checksum offload
//#define CHECKSUM_BY_HARDWARE
#ifdef CHECKSUM_BY_HARDWARE
/* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/
#define CHECKSUM_GEN_IP 0
/* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/
#define CHECKSUM_GEN_UDP 0
/* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/
#define CHECKSUM_GEN_TCP 0
/* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/
#define CHECKSUM_CHECK_IP 0
/* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/
#define CHECKSUM_CHECK_UDP 0
/* CHECKSUM_CHECK_TCP==0: Check checksums by hardware for incoming TCP packets.*/
#define CHECKSUM_CHECK_TCP 0
#else
/* CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.*/
#define CHECKSUM_GEN_IP 1
/* CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.*/
#define CHECKSUM_GEN_UDP 1
/* CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.*/
#define CHECKSUM_GEN_TCP 1
/* CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.*/
#define CHECKSUM_CHECK_IP 1
/* CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.*/
#define CHECKSUM_CHECK_UDP 1
/* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/
#define CHECKSUM_CHECK_TCP 1
#endif
/*
----------------------------------------------
---------- Sequential layer options ----------
----------------------------------------------
*/
/**
* LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
*/
#define LWIP_NETCONN 1
/*
------------------------------------
---------- Socket options ----------
------------------------------------
*/
/**
* LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
*/
#define LWIP_SOCKET 1
/*
-----------------------------------
---------- DEBUG options ----------
-----------------------------------
*/
#define LWIP_DEBUG 0
/*
---------------------------------
---------- OS options ----------
---------------------------------
*/
#define TCPIP_THREAD_STACKSIZE 1000
#define TCPIP_MBOX_SIZE 6
#define DEFAULT_UDP_RECVMBOX_SIZE 6
#define DEFAULT_TCP_RECVMBOX_SIZE 6
#define DEFAULT_RAW_RECVMBOX_SIZE 6
#define DEFAULT_ACCEPTMBOX_SIZE 6
#define DEFAULT_THREAD_STACKSIZE 500
#define TCPIP_THREAD_PRIO (configMAX_PRIORITIES - 2)
/* Added by Realtek */
#ifndef DNS_IGNORE_REPLY_ERR
#define DNS_IGNORE_REPLY_ERR 1
#endif /* DNS_IGNORE_REPLY_ERR */
#endif /* __LWIPOPTS_H__ */
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

View file

@ -0,0 +1,68 @@
#ifndef MAIN_H
#define MAIN_H
#include <autoconf.h>
#define CONFIG_WLAN 1
/* Header file declaration*/
void wlan_network();
/* Interactive Mode */
#define SERIAL_DEBUG_RX 1
#if defined(__ICCARM__)
static
#endif
char uart_buf[64];
/* WLAN and Netork */
#define STA_MODE_SSID "ap" /* Set SSID here */
#define AP_MODE_SSID "wlan_ap_ssid" /* Set SSID here */
#define AP_DEFAULT_CH 6
#define WLAN0_NAME "wlan0"
#define WLAN1_NAME "wlan1"
#define WPA_PASSPHRASE "1234567890" /* Max 32 cahracters */
#define WEP40_KEY {0x12, 0x34, 0x56, 0x78, 0x90}
/*Static IP ADDRESS*/
#define IP_ADDR0 192
#define IP_ADDR1 168
#define IP_ADDR2 1
#define IP_ADDR3 80
/*NETMASK*/
#define NETMASK_ADDR0 255
#define NETMASK_ADDR1 255
#define NETMASK_ADDR2 255
#define NETMASK_ADDR3 0
/*Gateway Address*/
#define GW_ADDR0 192
#define GW_ADDR1 168
#define GW_ADDR2 1
#define GW_ADDR3 1
/*******************************************/
/*Static IP ADDRESS*/
#define AP_IP_ADDR0 192
#define AP_IP_ADDR1 168
#define AP_IP_ADDR2 43
#define AP_IP_ADDR3 1
/*NETMASK*/
#define AP_NETMASK_ADDR0 255
#define AP_NETMASK_ADDR1 255
#define AP_NETMASK_ADDR2 255
#define AP_NETMASK_ADDR3 0
/*Gateway Address*/
#define AP_GW_ADDR0 192
#define AP_GW_ADDR1 168
#define AP_GW_ADDR2 43
#define AP_GW_ADDR3 1
#endif

View file

@ -0,0 +1,21 @@
//----------------------------------------------------------------------------//
#ifndef __MAIN_TEST_H
#define __MAIN_TEST_H
#ifdef __cplusplus
extern "C" {
#endif
/* Exported test functions ------------------------------------------------------- */
void do_ping_test(char *ip, int size, int count, int interval);
void do_ping_call(char *ip, int loop, int count);
void interactive_question(char *question, char *choice, char *buf, int buf_size);
void start_interactive_mode(void);
#ifdef __cplusplus
}
#endif
#endif // __MAIN_TEST_H
//----------------------------------------------------------------------------//

View file

@ -0,0 +1,50 @@
/**
******************************************************************************
* @file netconf.h
* @author MCD Application Team
* @version V1.1.0
* @date 07-October-2011
* @brief This file contains all the functions prototypes for the netconf.c
* file.
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __NETCONF_H
#define __NETCONF_H
#ifdef __cplusplus
extern "C" {
#endif
// TODO: remove this file
#include "lwip_netconf.h"
#if 0
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void LwIP_Init(void);
void LwIP_DHCP(void);
#endif
#ifdef __cplusplus
}
#endif
#endif /* __NETCONF_H */
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

View file

@ -0,0 +1,8 @@
#ifndef __RTL8195A_IT_H_
#define __RTL8195A_IT_H_
int irq_alloc_wlan(void *contex);
#endif //__RTL8195A_IT_H_

View file

@ -0,0 +1,46 @@
#ifndef _UTIL_H
#define _UTIL_H
#include <wireless.h>
#include <wlan_intf.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "wifi_util.h"
#if 0
typedef enum _WIFI_EVENT_INDICATE{
WIFI_EVENT_CONNECT = 0,
WIFI_EVENT_DISCONNECT = 1,
WIFI_EVENT_FOURWAY_HANDSHAKE_DONE = 2,
}WIFI_EVENT_INDICATE;
int wext_get_ssid(const char *ifname, __u8 *ssid);
int wext_set_ssid(const char *ifname, const __u8 *ssid, __u16 ssid_len);
int wext_set_auth_param(const char *ifname, __u16 idx, __u32 value);
int wext_set_key_ext(const char *ifname, __u16 alg, const __u8 *addr, int key_idx, int set_tx, const __u8 *seq, __u16 seq_len, __u8 *key, __u16 key_len);
int wext_get_enc_ext(const char *ifname, __u16 *alg);
int wext_set_passphrase(const char *ifname, const __u8 *passphrase, __u16 passphrase_len);
int wext_get_passphrase(const char *ifname, __u8 *passphrase);
int wext_set_mode(const char *ifname, int mode);
int wext_get_mode(const char *ifname, int *mode);
int wext_set_ap_ssid(const char *ifname, const __u8 *ssid, __u16 ssid_len);
int wext_set_country(const char *ifname, char *country_code);
int wext_get_rssi(const char *ifname, int *rssi);
int wext_set_channel(const char *ifname, __u8 ch);
int wext_get_channel(const char *ifname, __u8 *ch);
int wext_set_scan(const char *ifname, char *buf, __u16 buf_len);
int wext_get_scan(const char *ifname, char *buf, __u16 buf_len);
int wext_mp_command(const char *ifname, char *cmd, int show_msg);
int wext_wifi_priv(const char *ifname, int argc, char **argv);
void wext_wlan_indicate(unsigned int cmd, union iwreq_data *wrqu, char *extra);
#endif
#define wext_handshake_done rltk_wlan_handshake_done
#ifdef __cplusplus
}
#endif
#endif /* _UTIL_H */

View file

@ -0,0 +1,262 @@
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include <lwip/sockets.h>
#include <lwip/raw.h>
#include <lwip/icmp.h>
#include <lwip/inet_chksum.h>
#include <lwip/netdb.h>
#include <platform/platform_stdlib.h>
#define PING_IP "192.168.159.1"
#define PING_TO 1000
#define PING_ID 0xABCD
#define BUF_SIZE 10000
#define STACKSIZE 1024
static unsigned short ping_seq = 0;
static int infinite_loop, ping_count, data_size, ping_interval, ping_call;
static int ping_total_time = 0, ping_received_count = 0;
static void generate_ping_echo(unsigned char *buf, int size)
{
int i;
struct icmp_echo_hdr *pecho;
for(i = 0; i < size; i ++) {
buf[sizeof(struct icmp_echo_hdr) + i] = (unsigned char) i;
}
pecho = (struct icmp_echo_hdr *) buf;
ICMPH_TYPE_SET(pecho, ICMP_ECHO);
ICMPH_CODE_SET(pecho, 0);
pecho->chksum = 0;
pecho->id = PING_ID;
pecho->seqno = htons(++ ping_seq);
//Checksum includes icmp header and data. Need to calculate after fill up icmp header
pecho->chksum = inet_chksum(pecho, sizeof(struct icmp_echo_hdr) + size);
}
void ping_test(void *param)
{
int i, ping_socket;
int pint_timeout = PING_TO;
struct sockaddr_in to_addr, from_addr;
int from_addr_len = sizeof(struct sockaddr);
int ping_size, reply_size;
unsigned char *ping_buf, *reply_buf;
unsigned int ping_time, reply_time;
struct ip_hdr *iphdr;
struct icmp_echo_hdr *pecho;
unsigned int min_time = 1000, max_time = 0;
struct hostent *server_host;
char *host = param;
ping_total_time = 0;
ping_received_count = 0;
if(data_size > BUF_SIZE){
printf("\n\r[ERROR] %s: data size error, can't exceed %d",__func__,BUF_SIZE);
return;
}
//Ping size = icmp header(8 bytes) + data size
ping_size = sizeof(struct icmp_echo_hdr) + data_size;
ping_buf = pvPortMalloc(ping_size);
if(NULL == ping_buf){
printf("\n\r[ERROR] %s: Allocate ping_buf failed",__func__);
return;
}
reply_buf = pvPortMalloc(ping_size);
if(NULL == reply_buf){
vPortFree(ping_buf);
printf("\n\r[ERROR] %s: Allocate reply_buf failed",__func__);
return;
}
printf("\n\r[%s] PING %s %d(%d) bytes of data\n", __FUNCTION__, host, data_size, sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr) + data_size);
for(i = 0; (i < ping_count) || (infinite_loop == 1); i ++) {
ping_socket = socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP);
#if defined(LWIP_SO_SNDRCVTIMEO_NONSTANDARD) && (LWIP_SO_SNDRCVTIMEO_NONSTANDARD == 0) // lwip 1.5.0
struct timeval timeout;
timeout.tv_sec = pint_timeout / 1000;
timeout.tv_usec = pint_timeout % 1000 * 1000;
setsockopt(ping_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
#else // lwip 1.4.1
setsockopt(ping_socket, SOL_SOCKET, SO_RCVTIMEO, &pint_timeout, sizeof(pint_timeout));
#endif
to_addr.sin_len = sizeof(to_addr);
to_addr.sin_family = AF_INET;
if (inet_aton(host, &to_addr.sin_addr) == 0) {
server_host = gethostbyname(host);
if(server_host == NULL){
printf("\n\r[%s] Get host name failed in the %d ping test\n", __FUNCTION__, (i + 1));
close(ping_socket);
vTaskDelay(ping_interval * configTICK_RATE_HZ);
continue;
}
memcpy((void *) &to_addr.sin_addr, (void *) server_host->h_addr, server_host->h_length);
}
else
to_addr.sin_addr.s_addr = inet_addr(host);
generate_ping_echo(ping_buf, data_size);
sendto(ping_socket, ping_buf, ping_size, 0, (struct sockaddr *) &to_addr, sizeof(to_addr));
ping_time = xTaskGetTickCount();
if((reply_size = recvfrom(ping_socket, reply_buf, ping_size, 0, (struct sockaddr *) &from_addr, (socklen_t *) &from_addr_len))
>= (int)(sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr)) && (from_addr.sin_addr.s_addr == to_addr.sin_addr.s_addr)) {
reply_time = xTaskGetTickCount();
iphdr = (struct ip_hdr *)reply_buf;
pecho = (struct icmp_echo_hdr *)(reply_buf + (IPH_HL(iphdr) * 4));
if((pecho->id == PING_ID) && (pecho->seqno == htons(ping_seq))) {
printf("\n\r[%s] %d bytes from %s: icmp_seq=%d time=%d ms", __FUNCTION__, reply_size - sizeof(struct icmp_echo_hdr), inet_ntoa(from_addr.sin_addr), htons(pecho->seqno), (reply_time - ping_time) * portTICK_RATE_MS);
ping_received_count++;
ping_total_time += (reply_time - ping_time) * portTICK_RATE_MS;
if((reply_time - ping_time) > max_time) max_time = (reply_time - ping_time);
if((reply_time - ping_time) < min_time) min_time = (reply_time - ping_time);
}
}
else
printf("\n\r[%s] Request timeout for icmp_seq %d\n", __FUNCTION__, ping_seq);
close(ping_socket);
vTaskDelay(ping_interval * configTICK_RATE_HZ);
}
printf("\n\r[%s] %d packets transmitted, %d received, %d%% packet loss, average %d ms", __FUNCTION__, ping_count, ping_received_count, (ping_count-ping_received_count)*100/ping_count, ping_total_time/ping_received_count);
printf("\n\r[%s] min: %d ms, max: %d ms\n\r", __FUNCTION__, min_time, max_time);
vPortFree(ping_buf);
vPortFree(reply_buf);
vPortFree(host);
if(!ping_call)
vTaskDelete(NULL);
}
void do_ping_call(char *ip, int loop, int count)
{
ping_call = 1;
ping_seq = 0;
data_size = 120;
ping_interval = 1;
infinite_loop = loop;
ping_count = count;
char * host;
host = pvPortMalloc(strlen(ip) + 1);
memset(host, 0, (strlen(ip) + 1));
memcpy(host, ip, strlen(ip));
ping_test(host);
}
int get_ping_report(int *ping_lost){
*ping_lost = ping_count - ping_received_count;
return 0;
}
void cmd_ping(int argc, char **argv)
{
int argv_count = 2;
char * host;
if(argc < 2)
goto Exit;
//ping cmd default value
infinite_loop = 0;
ping_count = 4;
data_size = 32;
ping_interval = 1;
ping_call = 1;
ping_seq = 0;
while(argv_count<=argc){
//first operation
if(argv_count == 2){
host = pvPortMalloc(strlen(argv[argv_count-1]) + 1);
memset(host, 0, (strlen(argv[argv_count-1]) + 1));
strncpy(host, argv[argv_count-1], strlen(argv[argv_count-1]));
argv_count++;
}
else{
if(strcmp(argv[argv_count-1], "-t") == 0){
infinite_loop = 1;
argv_count++;
}
else if(strcmp(argv[argv_count-1], "-n") == 0){
if(argc < (argv_count+1))
goto Exit;
ping_count = (int) atoi(argv[argv_count]);
argv_count+=2;
}
else if(strcmp(argv[argv_count-1], "-l") == 0){
if(argc < (argv_count+1))
goto Exit;
data_size = (int) atoi(argv[argv_count]);
argv_count+=2;
}
else{
goto Exit;
}
}
}
ping_test(host);
return;
Exit:
printf("\n\r[ATWI] Usage: ATWI=[host],[options]\n");
printf("\n\r -t Ping the specified host until stopped\n");
printf(" \r -n # Number of echo requests to send (default 4 times)\n");
printf(" \r -l # Send buffer size (default 32 bytes)\n");
printf("\n\r Example:\n");
printf(" \r ATWI=192.168.1.2,-n,100,-l,5000\n");
return;
}
void do_ping_test(char *ip, int size, int count, int interval)
{
char *host;
if((sizeof(struct icmp_echo_hdr) + size) > BUF_SIZE) {
printf("\n\r%s BUF_SIZE(%d) is too small", __FUNCTION__, BUF_SIZE);
return;
}
if(ip == NULL){
host = pvPortMalloc(strlen(PING_IP) + 1);
memset(host, 0, (strlen(PING_IP) + 1));
strcpy(host, PING_IP);
}
else{
host = pvPortMalloc(strlen(ip) + 1);
memset(host, 0, (strlen(ip) + 1));
strcpy(host, ip);
}
ping_call = 0;
ping_seq = 0;
data_size = size;
ping_interval = interval;
if(count == 0) {
infinite_loop = 1;
ping_count = 0;
}
else {
infinite_loop = 0;
ping_count = count;
}
if(xTaskCreate(ping_test, ((const signed char*)"ping_test"), STACKSIZE, host, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
}

View file

@ -0,0 +1,71 @@
/*
* Hello World
*
* Copyright (c) 2013 Realtek Semiconductor Corp.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*/
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "main.h"
#include "main_test.h"
#if CONFIG_WLAN
#include "wifi_conf.h"
#include "wlan_intf.h"
#include "wifi_constants.h"
#endif
#include "lwip_netconf.h"
#include <platform/platform_stdlib.h>
#ifndef CONFIG_INIT_NET
#define CONFIG_INIT_NET 1
#endif
#ifndef CONFIG_INTERACTIVE_MODE
#define CONFIG_INTERACTIVE_MODE 1
#endif
#define STACKSIZE (512 + 768)
xSemaphoreHandle uart_rx_interrupt_sema = NULL;
void init_thread(void *param)
{
#if CONFIG_INIT_NET
#if CONFIG_LWIP_LAYER
/* Initilaize the LwIP stack */
LwIP_Init();
#endif
#endif
#if CONFIG_WIFI_IND_USE_THREAD
wifi_manager_init();
#endif
#if CONFIG_WLAN
wifi_on(RTW_MODE_STA);
#if CONFIG_AUTO_RECONNECT
//setup reconnection flag
wifi_set_autoreconnect(1);
#endif
printf("\n\r%s(%d), Available heap 0x%x", __FUNCTION__, __LINE__, xPortGetFreeHeapSize());
#endif
#if CONFIG_INTERACTIVE_MODE
/* Initial uart rx swmaphore*/
vSemaphoreCreateBinary(uart_rx_interrupt_sema);
xSemaphoreTake(uart_rx_interrupt_sema, 1/portTICK_RATE_MS);
start_interactive_mode();
#endif
/* Kill init thread after all init tasks done */
vTaskDelete(NULL);
}
void wlan_network()
{
if(xTaskCreate(init_thread, ((const char*)"init"), STACKSIZE, NULL, tskIDLE_PRIORITY + 3 + PRIORITIE_OFFSET, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__);
}

View file

@ -0,0 +1,262 @@
#ifndef __LIST_H
#define __LIST_H
#if defined ( __CC_ARM )
#ifndef inline
#define inline __inline
#endif
#endif
/* This file is from Linux Kernel (include/linux/list.h)
* and modified by simply removing hardware prefetching of list items.
* Here by copyright, credits attributed to wherever they belong.
* Kulesh Shanmugasundaram (kulesh [squiggly] isis.poly.edu)
*/
/*
* Simple doubly linked list implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
struct list_head {
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *newitem,
struct list_head *prev,
struct list_head *next)
{
next->prev = newitem;
newitem->next = next;
newitem->prev = prev;
prev->next = newitem;
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *newitem, struct list_head *head)
{
__list_add(newitem, head, head->next);
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *newitem, struct list_head *head)
{
__list_add(newitem, head->prev, head);
}
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head *prev, struct list_head *next)
{
next->prev = prev;
prev->next = next;
}
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty on entry does not return true after this, the entry is in an undefined state.
*/
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = (struct list_head *) 0;
entry->prev = (struct list_head *) 0;
}
/**
* list_del_init - deletes entry from list and reinitialize it.
* @entry: the element to delete from the list.
*/
static inline void list_del_init(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}
/**
* list_move - delete from one list and add as another's head
* @list: the entry to move
* @head: the head that will precede our entry
*/
static inline void list_move(struct list_head *list, struct list_head *head)
{
__list_del(list->prev, list->next);
list_add(list, head);
}
/**
* list_move_tail - delete from one list and add as another's tail
* @list: the entry to move
* @head: the head that will follow our entry
*/
static inline void list_move_tail(struct list_head *list,
struct list_head *head)
{
__list_del(list->prev, list->next);
list_add_tail(list, head);
}
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(struct list_head *head)
{
return head->next == head;
}
static inline void __list_splice(struct list_head *list,
struct list_head *head)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
struct list_head *at = head->next;
first->prev = head;
head->next = first;
last->next = at;
at->prev = last;
}
/**
* list_splice - join two lists
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice(struct list_head *list, struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head);
}
/**
* list_splice_init - join two lists and reinitialise the emptied list.
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* The list at @list is reinitialised
*/
static inline void list_splice_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head);
INIT_LIST_HEAD(list);
}
}
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
/**
* list_first_entry - get the first element from a list
* @ptr: the list head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_head within the struct.
*
* Note, that list is expected to be not empty.
*/
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); \
pos = pos->next)
/**
* list_for_each_prev - iterate over a list backwards
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; pos != (head); \
pos = pos->prev)
/**
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop counter.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry(pos, head, member, type) \
for (pos = list_entry((head)->next, type, member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, type, member))
/**
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop counter.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member, type) \
for (pos = list_entry((head)->next, type, member), \
n = list_entry(pos->member.next, type, member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, type, member))
#endif

View file

@ -0,0 +1,261 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2014 Realtek Corporation. All rights reserved.
*
*
******************************************************************************/
#ifndef __PLATFORM_STDLIB_H__
#define __PLATFORM_STDLIB_H__
#define USE_CLIB_PATCH 0
#if defined (__GNUC__)
/* build rom should set USE_RTL_ROM_CLIB=0 */
#include <rt_lib_rom.h>
#endif
#ifdef CONFIG_BUILD_ROM
#define USE_RTL_ROM_CLIB 0
#else
#define BUFFERED_PRINTF 0
#define USE_RTL_ROM_CLIB 1
#endif
#if defined(CONFIG_PLATFORM_8195A)
#if defined (__IARSTDLIB__)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "diag.h"
#define strsep(str, delim) _strsep(str, delim)
#else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "diag.h"
#include "strproc.h"
#include "basic_types.h"
#include "hal_misc.h"
#if USE_RTL_ROM_CLIB
#include "rtl_lib.h"
#endif
#undef printf
#undef sprintf
#undef snprintf
#undef atoi
#undef memcmp
#undef memcpy
#undef memset
#undef strcmp
#undef strcpy
#undef strlen
#undef strncmp
#undef strncpy
#undef strsep
#undef strtok
#if USE_RTL_ROM_CLIB
#undef memchr
#undef memmove
#undef strcat
#undef strchr
#undef strncat
#undef strstr
#endif
#if USE_RTL_ROM_CLIB
#if BUFFERED_PRINTF
extern int buffered_printf(const char* fmt, ...);
#define printf buffered_printf
#else
#define printf rtl_printf
#endif
#define sprintf rtl_sprintf
#define snprintf rtl_snprintf
#define memchr rtl_memchr
#define memcmp rtl_memcmp
#define memcpy rtl_memcpy
#define memmove rtl_memmove
#define memset rtl_memset
#define strcat rtl_strcat
#define strchr rtl_strchr
#define strcmp(s1, s2) rtl_strcmp((const char *)s1, (const char *)s2)
#define strcpy rtl_strcpy
#define strlen(str) rtl_strlen((const char *)str)
#define strncat rtl_strncat
#define strncmp(s1, s2, n) rtl_strncmp((const char *)s1, (const char *)s2, n)
#define strncpy rtl_strncpy
#define strstr rtl_strstr
#define strsep rtl_strsep
#define strtok rtl_strtok
#else
#if USE_CLIB_PATCH
extern int DiagSscanfPatch(const char *buf, const char *fmt, ...);
extern char* DiagStrtokPatch(char *str, const char* delim);
extern char* DiagStrstrPatch(char *string, char *substring);
extern int DiagSnPrintfPatch(char *buf, size_t size, const char *fmt, ...);
extern u32 DiagPrintfPatch(const char *fmt, ...);
extern u32 DiagSPrintfPatch(u8 *buf, const char *fmt, ...);
#define printf DiagPrintfPatch
#define sprintf DiagSPrintfPatch
#define snprintf DiagSnPrintfPatch
#define strstr(a, b) DiagStrstrPatch((char *)(a), (char *)(b))
#define strtok DiagStrtokPatch
#else
#define printf DiagPrintf
#define sprintf(fmt, arg...) DiagSPrintf((u8*)fmt, ##arg)
#if defined (__GNUC__)
#define snprintf DiagSnPrintf // NULL function
#define strstr(str1, str2) prvStrStr(str1, str2) // NULL function
#endif
#define strtok(str, delim) _strsep(str, delim)
#endif
#define memcmp(dst, src, sz) _memcmp(dst, src, sz)
#define memcpy(dst, src, sz) _memcpy(dst, src, sz)
#define memset(dst, val, sz) _memset(dst, val, sz)
#define strchr(s, c) _strchr(s, c) // for B-cut ROM
#define strcmp(str1, str2) prvStrCmp((const unsigned char *) str1, (const unsigned char *) str2)
#define strcpy(dest, src) _strcpy(dest, src)
#define strlen(str) prvStrLen((const unsigned char *) str)
#define strncmp(str1, str2, cnt) _strncmp(str1, str2, cnt)
#define strncpy(dest, src, count) _strncpy(dest, src, count)
#define strsep(str, delim) _strsep(str, delim)
#endif
#define atoi(str) prvAtoi(str)
#define strpbrk(cs, ct) _strpbrk(cs, ct) // for B-cut ROM
#if USE_CLIB_PATCH
#undef sscanf
#define sscanf DiagSscanfPatch
#else
#if defined (__GNUC__)
#undef sscanf //_sscanf
//extern int DiagSscanfPatch(const char *buf, const char *fmt, ...);
//#define sscanf DiagSscanfPatch
#define sscanf sscanf // use libc sscanf
#endif
#endif
#endif // defined (__IARSTDLIB__)
//
// memory management
//
extern void *pvPortMalloc( size_t xWantedSize );
extern void vPortFree( void *pv );
#define malloc pvPortMalloc
#define free vPortFree
#elif defined (CONFIG_PLATFORM_8711B)
#if defined (__IARSTDLIB__)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdarg.h> /* va_list */
#include "diag.h"
#define strsep(str, delim) _strsep(str, delim)
#else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h> /* va_list */
#include "diag.h"
#include "strproc.h"
#include "memproc.h"
#include "basic_types.h"
#if USE_RTL_ROM_CLIB
#include "rtl_lib.h"
#include "rom_libc_string.h"
#endif
#undef printf
#undef sprintf
#undef snprintf
#undef memchr
#undef memcmp
#undef memcpy
#undef memset
#undef memmove
#undef strcmp
#undef strcpy
#undef strlen
#undef strncmp
#undef strncpy
#undef strsep
#undef strtok
#undef strcat
#undef strchr
#undef strncat
#undef strstr
#undef atol
#undef atoi
#undef strpbrk
#if USE_RTL_ROM_CLIB
#if BUFFERED_PRINTF
extern int buffered_printf(const char* fmt, ...);
#define printf buffered_printf
#else
#define printf rtl_printf
#endif
#define sprintf rtl_sprintf
#define snprintf rtl_snprintf
#define vsnprintf rtl_vsnprintf
#else
#define printf DiagPrintf
#define sprintf(fmt, arg...) DiagSPrintf((u8*)fmt, ##arg)
#define snprintf DiagSnPrintf // NULL function
#define vsnprintf(buf, size, fmt, ap) VSprintf(buf, fmt, ap)
#endif
#define memchr __rtl_memchr_v1_00
#define memcmp(dst, src, sz) _memcmp(dst, src, sz)
#define memcpy(dst, src, sz) _memcpy(dst, src, sz)
#define memmove __rtl_memmove_v1_00
#define memset(dst, val, sz) _memset(dst, val, sz)
#define strchr(s, c) _strchr(s, c) // for B-cut ROM
#define strcmp(str1, str2) prvStrCmp((const unsigned char *) str1, (const unsigned char *) str2)
#define strcpy(dest, src) _strcpy(dest, src)
#define strlen(str) prvStrLen((const unsigned char *) str)
#define strsep(str, delim) _strsep(str, delim)
#define strstr(str1, str2) prvStrStr(str1, str2) // NULL function
#define strtok(str, delim) prvStrtok(str, delim)//_strsep(str, delim)
#define strcat __rtl_strcat_v1_00
#define strncmp(str1, str2, cnt) _strncmp(str1, str2, cnt)
#define strncpy(dest, src, count) _strncpy(dest, src, count)
#define strncat __rtl_strncat_v1_00
#define atol(str) strtol(str,NULL,10)
#define atoi(str) prvAtoi(str)
#define strpbrk(cs, ct) _strpbrk(cs, ct) // for B-cut ROM
#if defined (__GNUC__)
#undef sscanf
#define sscanf _sscanf_patch
#define rand Rand
#endif
//extern int _sscanf_patch(const char *buf, const char *fmt, ...);
//#define sscanf _sscanf_patch
#endif // defined (__IARSTDLIB__)
//
// memory management
//
extern void *pvPortMalloc( size_t xWantedSize );
extern void vPortFree( void *pv );
#define malloc pvPortMalloc
#define free vPortFree
#elif defined(USE_STM322xG_EVAL) || defined(USE_STM324xG_EVAL) || defined(STM32F10X_XL)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#endif
#endif //__PLATFORM_STDLIB_H__

View file

@ -0,0 +1,918 @@
/*
this is the c lib patch, It can help when the clib provided by IAR
does not work well.
How to use this:
1.You must include platform_stdlib.h in you source file
2.There is a macro USE_CLIB_PATCH in platform_stdlib.h should be opened.
If there is some problems using this patch,
You'd better check if you code runs into these functions:
DiagSscanfPatch
DiagStrtokPatch
DiagStrstrPatch
DiagSnPrintfPatch
DiagPrintfPatch
DiagSPrintfPatch
DiagPrintfPatch
DiagSPrintfPatch
DiagSnPrintfPatch
DiagStrstrPatch
DiagStrtokPatch
*/
#ifndef CONFIG_PLATFORM_8711B
#include <stdarg.h>
#define DiagPutChar HalSerialPutcRtl8195a
#define IN
#define NULL 0
typedef unsigned int size_t;
typedef unsigned int SIZE_T;
typedef unsigned long long u64;
typedef unsigned int u32;
typedef unsigned short int u16;
typedef unsigned char u8;
typedef signed long long s64;
typedef signed int s32;
typedef signed short int s16;
typedef unsigned char bool;
#define in_range(c, lo, up) ((u8)c >= lo && (u8)c <= up)
#define isprint(c) in_range(c, 0x20, 0x7f)
#define isdigit(c) in_range(c, '0', '9')
#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F'))
#define islower(c) in_range(c, 'a', 'z')
#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v' || c == ',')
#define ULLONG_MAX (~0ULL)
#define USHRT_MAX ((u16)(~0U))
#define KSTRTOX_OVERFLOW (1U << 31)
#define SHRT_MAX ((s16)(USHRT_MAX>>1))
static inline char _tolower(const char c)
{
return c | 0x20;
}
extern s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder);
extern s64 div_s64(s64 dividend, s32 divisor);
extern inline char _tolower(const char c);
extern u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder);
extern u64 div_u64(u64 dividend, u32 divisor);
extern unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *p);
extern const char *_parse_integer_fixup_radix(const char *s, unsigned int *base);
extern char *skip_spaces(const char *str);
extern int skip_atoi(const char **s);
extern void HalSerialPutcRtl8195a(u8 c);
static unsigned long long simple_strtoull_patch(const char *cp, char **endp, unsigned int base)
{
unsigned long long result;
unsigned int rv;
cp = _parse_integer_fixup_radix(cp, &base);
rv = _parse_integer(cp, base, &result);
return result;
}
static long long simple_strtoll_patch(const char *cp, char **endp, unsigned int base)
{
if(*cp == '-')
return -simple_strtoull_patch(cp + 1, endp, base);
return simple_strtoull_patch(cp, endp, base);
}
static unsigned long simple_strtoul_patch(const char *cp, char **endp, unsigned int base)
{
return simple_strtoull_patch(cp, endp, base);
}
static long simple_strtol_patch(const char *cp, char **endp, unsigned int base)
{
if(*cp == '-')
return -simple_strtoul_patch(cp + 1, endp, base);
return simple_strtoul_patch(cp, endp, base);
}
static int judge_digit_width(const char *str)
{
int width = 0;
while(isdigit(*str)) {
width++;
str++;
}
return width;
}
static int _vsscanf_patch(const char *buf, const char *fmt, va_list args)
{
const char *str = buf;
char *next;
char digit;
int num = 0;
int i =0;
u8 qualifier;
unsigned int base;
union {
long long s;
unsigned long long u;
} val;
s16 field_width;
bool is_sign;
char str_store[20] = {0};
while(*fmt) {
/* skip any white space in format */
/* white space in format matchs any amount of
* white space, including none, in the input.
*/
if(isspace(*fmt)) {
fmt = skip_spaces(++fmt);
str = skip_spaces(str);
}
/* anything that is not a conversion must match exactly */
if(*fmt != '%' && *fmt) {
if(*fmt++ != *str++) {
break;
}
continue;
}
if(!*fmt) {
break;
}
++fmt;
/* skip this conversion.
* advance both strings to next white space
*/
if(*fmt == '*') {
if(!*str) {
break;
}
while(!isspace(*fmt) && *fmt != '%' && *fmt)
fmt++;
while(!isspace(*str) && *str)
str++;
continue;
}
/* get field width */
field_width = -1;
if(isdigit(*fmt)) {
field_width = skip_atoi(&fmt);
if(field_width <= 0) {
break;
}
}
/* get conversion qualifier */
qualifier = -1;
if(*fmt == 'h' || _tolower(*fmt) == 'l' ||
_tolower(*fmt) == 'z') {
qualifier = *fmt++;
if(qualifier == *fmt) {
if(qualifier == 'h') {
qualifier = 'H';
fmt++;
} else if(qualifier == 'l') {
qualifier = 'L';
fmt++;
}
}
}
if(!*fmt) {
break;
}
if(*fmt == 'n') {
/* return number of characters read so far */
*va_arg(args, int *) = str - buf;
++fmt;
continue;
}
if(!*str) {
break;
}
base = 10;
is_sign = 0;
switch(*fmt++) {
case 'c': {
char *s = (char *)va_arg(args, char*);
if(field_width == -1)
field_width = 1;
do {
*s++ = *str++;
} while(--field_width > 0 && *str);
num++;
}
continue;
case 's': {
char *s = (char *)va_arg(args, char *);
if(field_width == -1)
field_width = SHRT_MAX;
/* first, skip leading white space in buffer */
str = skip_spaces(str);
/* now copy until next white space */
while(*str && !isspace(*str) && field_width--) {
*s++ = *str++;
}
*s = '\0';
num++;
}
continue;
case 'o':
base = 8;
break;
case 'x':
case 'X':
base = 16;
break;
case 'i':
base = 0;
case 'd':
is_sign = 1;
case 'u':
break;
case '%':
/* looking for '%' in str */
if(*str++ != '%') {
return num;
}
continue;
default:
/* invalid format; stop here */
return num;
}
/* have some sort of integer conversion.
* first, skip white space in buffer.
*/
str = skip_spaces(str);
digit = *str;
if(is_sign && digit == '-')
digit = *(str + 1);
if(!digit
|| (base == 16 && !isxdigit(digit))
|| (base == 10 && !isdigit(digit))
|| (base == 8 && (!isdigit(digit) || digit > '7'))
|| (base == 0 && !isdigit(digit))) {
break;
}
//here problem *******************************************
//troy add ,fix support %2d, but not support %d
if(field_width <= 0) {
field_width = judge_digit_width(str);
}
/////troy add, fix str passed inwidth wrong
for(i = 0; i<field_width ; i++)
str_store[i] = str[i];
next = (char*)str + field_width;
if(is_sign) {
val.s = qualifier != 'L' ?
simple_strtol_patch(str_store, &next, base) :
simple_strtoll_patch(str_store, &next, base);
} else {
val.u = qualifier != 'L' ?
simple_strtoul_patch(str_store, &next, base) :
simple_strtoull_patch(str_store, &next, base);
}
////troy add
for(i = 0; i<20 ; i++)
str_store[i] = 0;
//判断转换的字符串的宽度是否大于 %2d
if(field_width > 0 && next - str > field_width) {
if(base == 0)
_parse_integer_fixup_radix(str, &base);
while(next - str > field_width) {
if(is_sign) {
val.s = div_s64(val.s, base);
} else {
val.u = div_u64(val.u, base);
}
--next;
}
}
switch(qualifier) {
case 'H': /* that's 'hh' in format */
if(is_sign)
*va_arg(args, signed char *) = val.s;
else
*va_arg(args, unsigned char *) = val.u;
break;
case 'h':
if(is_sign)
*va_arg(args, short *) = val.s;
else
*va_arg(args, unsigned short *) = val.u;
break;
case 'l':
if(is_sign)
*va_arg(args, long *) = val.s;
else
*va_arg(args, unsigned long *) = val.u;
break;
case 'L':
if(is_sign)
*va_arg(args, long long *) = val.s;
else
*va_arg(args, unsigned long long *) = val.u;
break;
case 'Z':
case 'z':
*va_arg(args, size_t *) = val.u;
break;
default:
if(is_sign)
*va_arg(args, int *) = val.s;
else
*va_arg(args, unsigned int *) = val.u;
break;
}
num++;
if(!next) {
break;
}
str = next;
}
return num;
}
int DiagSscanfPatch(const char *buf, const char *fmt, ...)
{
va_list args;
int i;
va_start(args, fmt);
i = _vsscanf_patch(buf, fmt, args);
va_end(args);
return i;
}
/*********************************************************/
char* DiagStrtokPatch(char *str, const char* delim) {
static char* _buffer;
if(str != NULL) _buffer = str;
if(_buffer[0] == '\0') return NULL;
char *ret = _buffer, *b;
const char *d;
for(b = _buffer; *b !='\0'; b++) {
for(d = delim; *d != '\0'; d++) {
if(*b == *d) {
*b = '\0';
_buffer = b+1;
// skip the beginning delimiters
if(b == ret) {
ret++;
continue;
}
return ret;
}
}
}
return ret;
}
/*********************************************************/
char *DiagStrstrPatch(char *string, char *substring)
{
register char *a, *b;
/* First scan quickly through the two strings looking for a
* single-character match. When it's found, then compare the
* rest of the substring.
*/
b = substring;
if(*b == 0) {
return string;
}
for(; *string != 0; string += 1) {
if(*string != *b) {
continue;
}
a = string;
while(1) {
if(*b == 0) {
return string;
}
if(*a++ != *b++) {
break;
}
}
b = substring;
}
return (char *) 0;
}
/*********************************************************/
int DiagSnPrintfPatch(char *buf, size_t size, const char *fmt, ...)
{
va_list ap;
char *p, *s, *buf_end = NULL;
const int *dp = ((const int *)&fmt)+1;
if(buf == NULL)
return 0;
va_start(ap, fmt);
s = buf;
buf_end = size? (buf + size):(char*)~0;
for(; *fmt != '\0'; ++fmt) {
if(*fmt != '%') {
*s++ = *fmt;
if(s >= buf_end) {
goto Exit;
}
continue;
}
if(*++fmt == 's') {
for(p = (char *)*dp++; *p != '\0'; p++) {
*s++ = *p;
if(s >= buf_end) {
goto Exit;
}
}
}
else { /* Length of item is bounded */
char tmp[20], *q = tmp;
int alt = 0;
int shift = 0;// = 12;
const long *lpforchk = (const long *)dp;
if((*lpforchk) < 0x10) {
shift = 0;
}
else if(((*lpforchk) >= 0x10) && ((*lpforchk) < 0x100)) {
shift = 4;
}
else if(((*lpforchk) >= 0x100) && ((*lpforchk) < 0x1000)) {
shift = 8;
}
else if(((*lpforchk) >= 0x1000) && ((*lpforchk) < 0x10000)) {
shift = 12;
}
else if(((*lpforchk) >= 0x10000) && ((*lpforchk) < 0x100000)) {
shift = 16;
}
else if(((*lpforchk) >= 0x100000) && ((*lpforchk) < 0x1000000)) {
shift = 20;
}
else if(((*lpforchk) >= 0x1000000) && ((*lpforchk) < 0x10000000)) {
shift = 24;
}
else if((*lpforchk) >= 0x10000000) {
shift = 28;
}
else {
shift = 28;
}
if((*fmt >= '0') && (*fmt <= '9'))
{
int width;
unsigned char fch = *fmt;
for(width=0; (fch>='0') && (fch<='9'); fch=*++fmt)
{ width = width * 10 + fch - '0';
}
shift=(width-1)*4;
}
/*
* Before each format q points to tmp buffer
* After each format q points past end of item
*/
if((*fmt == 'x')||(*fmt == 'X') || (*fmt == 'p') || (*fmt == 'P')) {
/* With x86 gcc, sizeof(long) == sizeof(int) */
const long *lp = (const long *)dp;
long h = *lp++;
int hex_count = 0;
unsigned long h_back = h;
int ncase = (*fmt & 0x20);
dp = (const int *)lp;
if((*fmt == 'p') || (*fmt == 'P'))
alt=1;
if(alt) {
*q++ = '0';
*q++ = 'X' | ncase;
}
while(h_back) {
hex_count += (h_back & 0xF) ? 1 : 0;
h_back = h_back >> 4;
}
if(shift < (hex_count - 1)*4)
shift = (hex_count - 1)*4;
for(; shift >= 0; shift -= 4)
*q++ = "0123456789ABCDEF"[(h >> shift) & 0xF] | ncase;
}
else if(*fmt == 'd') {
int i = *dp++;
char *r;
int digit_space = 0;
if(i < 0) {
*q++ = '-';
i = -i;
digit_space++;
}
p = q; /* save beginning of digits */
do {
*q++ = '0' + (i % 10);
i /= 10;
digit_space++;
} while(i);
for(; shift >= 0; shift -= 4) {
if(digit_space-- > 0) {
; //do nothing
} else {
*q++ = '0';
}
}
/* reverse digits, stop in middle */
r = q; /* don't alter q */
while(--r > p) {
i = *r;
*r = *p;
*p++ = i;
}
}
else if(*fmt == 'c')
*q++ = *dp++;
else
*q++ = *fmt;
/* now output the saved string */
for(p = tmp; p < q; ++p) {
*s++ = *p;
if(s >= buf_end) {
goto Exit;
}
}
}
}
Exit:
if(buf)
*s = '\0';
va_end(ap);
return(s-buf);
}
/*********************************************************/
static int VSprintfPatch(char *buf, const char *fmt, const int *dp)
{
char *p, *s;
s = buf;
for(; *fmt != '\0'; ++fmt) {
if(*fmt != '%') {
if(buf) {
*s++ = *fmt;
} else {
DiagPutChar(*fmt);
}
continue;
}
if(*++fmt == 's') {
for(p = (char *)*dp++; *p != '\0'; p++) {
if(buf) {
*s++ = *p;
} else {
DiagPutChar(*p);
}
}
}
else { /* Length of item is bounded */
char tmp[20], *q = tmp;
int alt = 0;
int shift = 0;// = 12;
const long *lpforchk = (const long *)dp;
if((*lpforchk) < 0x10) {
shift = 0;
}
else if(((*lpforchk) >= 0x10) && ((*lpforchk) < 0x100)) {
shift = 4;
}
else if(((*lpforchk) >= 0x100) && ((*lpforchk) < 0x1000)) {
shift = 8;
}
else if(((*lpforchk) >= 0x1000) && ((*lpforchk) < 0x10000)) {
shift = 12;
}
else if(((*lpforchk) >= 0x10000) && ((*lpforchk) < 0x100000)) {
shift = 16;
}
else if(((*lpforchk) >= 0x100000) && ((*lpforchk) < 0x1000000)) {
shift = 20;
}
else if(((*lpforchk) >= 0x1000000) && ((*lpforchk) < 0x10000000)) {
shift = 24;
}
else if((*lpforchk) >= 0x10000000) {
shift = 28;
}
else {
shift = 28;
}
#if 1 //wei patch for %02x
if((*fmt >= '0') && (*fmt <= '9'))
{
int width;
unsigned char fch = *fmt;
for(width=0; (fch>='0') && (fch<='9'); fch=*++fmt)
{ width = width * 10 + fch - '0';
}
shift=(width-1)*4;
}
#endif
/*
* Before each format q points to tmp buffer
* After each format q points past end of item
*/
if((*fmt == 'x')||(*fmt == 'X') || (*fmt == 'p') || (*fmt == 'P')) {
/* With x86 gcc, sizeof(long) == sizeof(int) */
const long *lp = (const long *)dp;
long h = *lp++;
int hex_count = 0;
unsigned long h_back = h;
int ncase = (*fmt & 0x20);
dp = (const int *)lp;
if((*fmt == 'p') || (*fmt == 'P'))
alt=1;
if(alt) {
*q++ = '0';
*q++ = 'X' | ncase;
}
//hback 是实际得到的数据hex_count是统计数据的HEX字符个数
while(h_back) {
hex_count += (h_back & 0xF) ? 1 : 0;
h_back = h_back >> 4;
}
//这里修复 example 字符有4个但是用了%02x导致字符被截断的情况
if(shift < (hex_count - 1)*4)
shift = (hex_count - 1)*4;
//printf("(%d,%d)", hex_count, shift);
for(; shift >= 0; shift -= 4) {
*q++ = "0123456789ABCDEF"[(h >> shift) & 0xF] | ncase;
}
}
else if(*fmt == 'd') {
int i = *dp++;
char *r;
int digit_space = 0;
if(i < 0) {
*q++ = '-';
i = -i;
digit_space++;
}
p = q; /* save beginning of digits */
do {
*q++ = '0' + (i % 10);
i /= 10;
digit_space++;
} while(i);
//这里修复 example用了%08d后在数字前面没有0的情况
for(; shift >= 0; shift -= 4) {
if(digit_space-- > 0) {
; //do nothing
} else {
*q++ = '0';
}
}
/* reverse digits, stop in middle */
r = q; /* don't alter q */
while(--r > p) {
i = *r;
*r = *p;
*p++ = i;
}
}
else if(*fmt == 'c')
*q++ = *dp++;
else
*q++ = *fmt;
/* now output the saved string */
for(p = tmp; p < q; ++p) {
if(buf) {
*s++ = *p;
} else {
DiagPutChar(*p);
}
if((*p) == '\n') {
DiagPutChar('\r');
}
}
}
}
if(buf)
*s = '\0';
return (s - buf);
}
u32 DiagPrintfPatch(
IN const char *fmt, ...
)
{
(void)VSprintfPatch(0, fmt, ((const int *)&fmt)+1);
return 1;
}
u32 DiagSPrintfPatch(
IN u8 *buf,
IN const char *fmt, ...
)
{
(void)VSprintfPatch((char*)buf, fmt, ((const int *)&fmt)+1);
return 1;
}
#endif

View file

@ -0,0 +1,149 @@
#include <PinNames.h>
#include <pinmap.h>
#include <gpio_api.h>
#include <wifi_wowlan.h>
#include <freertos_pmu.h>
#include <wifi_conf.h>
#define CONFIG_WOWLAN_DEV_NT96658 //build for Nova NT96658
//#define CONFIG_WOWLAN_DEV_OV788 //build for OmniVision OV788
#if defined(CONFIG_WOWLAN_DEV_NT96658) && defined(CONFIG_WOWLAN_DEV_OV788)
#error "CONFIG_WOWLAN_DEV_NT96658 and CONFIG_WOWLAN_DEV_OV788 are mutually exclusive. "
#endif
#ifdef CONFIG_WOWLAN_DEV_NT96658
#define WOW_WIFI_IN_PIN PE_4 //JTAG pin, so JTAG must be disable before using this pin as wakeup pin
#define WOW_TRIGGER_INTERVAL 500
#elif defined(CONFIG_WOWLAN_DEV_OV788)
#define WOW_WIFI_IN_PIN PD_5
#define WOW_WLAN_ON_PIN PB_3
#define WOW_TRIGGER_INTERVAL 200
#else
#error "Either CONFIG_WOWLAN_DEV_NT96658 or CONFIG_WOWLAN_DEV_OV788 should be defined, but not both. "
#endif
//pin assignment for SDIO, default pull high
#define SD_D2 PA_0
#define SD_D3 PA_1
#define SD_CMD PA_2
#define SD_CLK PA_3
#define SD_D0 PA_4
#define SD_D1 PA_5
#define SD_CD PA_6
gpio_t wow_gpio_wifi_in; //WOWLAN WAKEUP TRIGGER PORT
gpio_t wow_gpio_wlan_on; //RECORD WOWLAN STATUS: 1:OFF, 0:ON
int dev_wowlan_init(void){
WOWLAN_PRINTK("WOWLAN: device init!");
#ifdef CONFIG_WOWLAN_DEV_OV788
// Initial WLAN_ON pin
gpio_init(&wow_gpio_wlan_on, WOW_WLAN_ON_PIN);
gpio_dir(&wow_gpio_wlan_on, PIN_OUTPUT);
gpio_mode(&wow_gpio_wlan_on, PullNone);
gpio_write(&wow_gpio_wlan_on, 1);
#endif
return 0;
}
int dev_wowlan_enable(void){
WOWLAN_PRINTK("WOWLAN: device enable!");
// Init WIFI_IN pin (wakeup pin)
gpio_init(&wow_gpio_wifi_in, WOW_WIFI_IN_PIN);
gpio_dir(&wow_gpio_wifi_in, PIN_OUTPUT);
gpio_mode(&wow_gpio_wifi_in, PullNone);
gpio_write(&wow_gpio_wifi_in, 0);
#ifdef CONFIG_WOWLAN_DEV_OV788
gpio_write(&wow_gpio_wlan_on, 0);
#endif
#if CONFIG_WLAN
wifi_set_power_mode(0xff, 1);
#endif
return 0;
}
int dev_wowlan_wakeup_process(void){
WOWLAN_PRINTK("WOWLAN: device wake up!");
#if defined(CONFIG_WOWLAN_DEV_NT96658) || defined(CONFIG_WOWLAN_DEV_OV788)
#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1)
//acquire wakelock to keep system awake
pmu_acquire_wakelock(PMU_SDIO_DEVICE);
#endif
#endif
#ifdef CONFIG_WOWLAN_DEV_OV788
//record wowlan status
gpio_write(&wow_gpio_wlan_on, 1);
#endif
#if defined(CONFIG_WOWLAN_DEV_NT96658)
//restore SDIO pin status for bus communication
pin_mode(SD_D0, PullUp);
pin_mode(SD_D1, PullUp);
pin_mode(SD_D2, PullUp);
pin_mode(SD_D3, PullUp);
pin_mode(SD_CMD, PullUp);
pin_mode(SD_CLK, PullDown);
#endif
//send signal to awake host
gpio_write(&wow_gpio_wifi_in, 0);
wowlan_mdelay_os(WOW_TRIGGER_INTERVAL);
gpio_write(&wow_gpio_wifi_in, 1);
wowlan_mdelay_os(WOW_TRIGGER_INTERVAL);
gpio_write(&wow_gpio_wifi_in, 0);
wowlan_mdelay_os(WOW_TRIGGER_INTERVAL);
return 0;
}
int dev_wowlan_sleep_process(void){
#if defined(CONFIG_WOWLAN_DEV_NT96658)
//pull control for SDIO pin only when host is already power off
if(rtw_wowlan_is_enabled() && (rtw_wowlan_get_wk_reason() == 0)){
WOWLAN_PRINTK("pull control");
//configure SDIO pin status for avoiding current leakage
pin_mode(SD_D0, PullNone);
pin_mode(SD_D1, PullNone);
pin_mode(SD_D2, PullNone);
pin_mode(SD_D3, PullNone);
pin_mode(SD_CMD, PullNone);
pin_mode(SD_CLK, PullNone);
}
#endif
return 0;
}
int dev_wowlan_disable(void){
WOWLAN_PRINTK("WOWLAN: device disable!");
#if CONFIG_WLAN
wifi_set_power_mode(0xff, 0);
#endif
#ifdef CONFIG_WOWLAN_DEV_OV788
gpio_write(&wow_gpio_wlan_on, 1);
#endif
return 0;
}
void dev_wowlan_ops_init(void *dev_ops){
struct rtw_wowlan_ops *ops = (struct rtw_wowlan_ops *)dev_ops;
WOWLAN_PRINTK("WOWLAN: device ops init!");
ops->DevWowlanInit = dev_wowlan_init;
ops->DevWowlanEnable = dev_wowlan_enable;
ops->DevWowlanDisable = dev_wowlan_disable;
ops->DevWowlanWakeUp = dev_wowlan_wakeup_process;
ops->DevWowlanSleep = dev_wowlan_sleep_process;
}

View file

@ -0,0 +1,385 @@
#ifndef _WIFI_WOWLAN_H_
#define _WIFI_WOWLAN_H_
#include <platform_stdlib.h>
#include <osdep_service.h>
#define WOWLAN_DBG 1
enum{
WOWLAN_DBG_OFF = 0,
WOWLAN_DBG_ALWAYS,
WOWLAN_DBG_ERROR,
WOWLAN_DBG_WARNING,
WOWLAN_DBG_INFO
};
#if WOWLAN_DBG
//#define WOWLAN_DUMP_MSG
#define WOWLAN_DUMP_MSG_1 //dump packet when setting
static unsigned char gWowlanDbgLevel = WOWLAN_DBG_ERROR;
#define WOWLAN_PRINTK(fmt, args...) printf(fmt"\r\n",## args)
#define _WOWLAN_PRINTK(fmt, args...) printf(fmt,## args)
#define WOWLAN_DBG_MSG(level, fmt, args...) \
do{ \
if(level <= gWowlanDbgLevel){ \
WOWLAN_PRINTK(fmt,## args); \
} \
}while(0)
#else
#define WOWLAN_PRINTK(fmt, args...)
#define WOWLAN_DBG_MSG(level, fmt, args...)
#endif
#ifndef u8
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
#endif
#ifndef BIT
#define BIT(x) ((u32)1 << (x))
#endif
#ifndef le16_to_cpu //need a general definition for the whole system
#define cpu_to_le32(x) ((u32)(x))
#define le32_to_cpu(x) ((u32)(x))
#define cpu_to_le16(x) ((u16)(x))
#define le16_to_cpu(x) ((u16)(x))
#endif
#ifndef IP_FMT
#define IP_FMT "%d.%d.%d.%d"
#endif
#ifndef IP_ARG
#define IP_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3]
#endif
#ifndef MAC_FMT
#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
#endif
#ifndef MAC_ARG
#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
#endif
#ifndef ETH_ALEN
#define ETH_ALEN 6
#endif
#ifndef ethhdr
struct ethhdr
{
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
unsigned short h_proto; /* packet type ID field */
};
#endif
#ifndef wowlan_memcpy
#define wowlan_memcpy(d, s, n) rtw_memcpy((void*)(d), ((void*)(s)), (n))
#endif
#ifndef wowlan_malloc
#define wowlan_malloc(sz) rtw_malloc(sz)
#endif
#ifndef wowlan_zmalloc
#define wowlan_zmalloc(sz) rtw_zmalloc(sz)
#endif
#ifndef wowlan_memset
#define wowlan_memset(pbuf, c, sz) rtw_memset(pbuf, c, sz)
#endif
#ifndef wowlan_mfree
#define wowlan_mfree(p, sz) rtw_mfree(((u8*)(p)), (sz))
#endif
#ifndef wowlan_memcmp
#define wowlan_memcmp(s1, s2, n) rtw_memcmp(((void*)(s1)), ((void*)(s2)), (n))
#endif
#ifndef wowlan_mdelay_os
#define wowlan_mdelay_os(ms) rtw_mdelay_os(ms)
#endif
/*Mutex services*/
typedef _mutex _wowlock;
__inline static void _init_wowlock(_wowlock *plock)
{
rtw_mutex_init(plock);
}
__inline static void _free_wowlock(_wowlock *plock)
{
rtw_mutex_free(plock);
}
__inline static void _enter_wowlock(_wowlock *plock)
{
rtw_mutex_get(plock);
}
__inline static void _exit_wowlock(_wowlock *plock)
{
rtw_mutex_put(plock);
}
/*Timer services*/
typedef _timerHandle _wowTimer;
#define TMR_AUTO_RELOAD_EN _TRUE
#define TMR_AUTO_RELOAD_DIS _FALSE
__inline static void
_wowlan_init_timer(_wowTimer *ptimer, void *adapter, TIMER_FUN pfunc,void* cntx, const char *name, u32 auto_reload)
{
*ptimer = rtw_timerCreate(
(signed const char *)name, // Just a text name, not used by the RTOS kernel.
TIMER_MAX_DELAY, // Timer Period, not 0
auto_reload, // Whether timer will auto-load themselves when expires
cntx, // Uniq id used to identify which timer expire..
pfunc // Timer callback
);
}
__inline static void
_wowlan_set_timer(_wowTimer *ptimer, u32 delay_time_ms)
{
if(rtw_timerChangePeriod(*ptimer, rtw_ms_to_systime(delay_time_ms), TIMER_MAX_DELAY) == _FAIL)
WOWLAN_PRINTK("Fail to set timer period");
}
__inline static void
_wowlan_cancel_timer(_wowTimer *ptimer)
{
rtw_timerStop(*ptimer, TIMER_MAX_DELAY);
}
__inline static void
_wowlan_del_timer(_wowTimer *ptimer)
{
rtw_timerDelete(*ptimer, TIMER_MAX_DELAY);
}
__inline static void *
_wowlan_get_timer_cntx(_wowTimer timer)
{
#ifdef PLATFORM_FREERTOS
#include <FreeRTOS.h>
#include <timers.h>
return pvTimerGetTimerID(timer);
#else
#error "_wowlan_get_timer_cntx is not defined"
#endif
}
enum rtw_wowlan_wakeup_reason {
RTW_WOWLAN_WAKEUP_BY_PATTERN = BIT(0),
RTW_WOWLAN_WAKEUP_BY_DISCONNECTION = BIT(1),
RTW_WOWLAN_WAKEUP_MAX = 0x7FFFFFFF
};
enum rtw_wowlan_cmd_id{
RTW_WOWLAN_CMD_ENABLE = 0x01, // enable wowlan service
RTW_WOWLAN_CMD_PATTERNS = 0x02, // wowlan pattern setting
RTW_WOWLAN_CMD_PROT_OFFLOAD_CONFIG = 0x03, //ARP offload setting
RTW_WOWLAN_CMD_GET_STATUS = 0x04, // get rtw_wowlan_status
RTW_WOWLAN_CMD_CLEAR_ALL = 0x05, //clear wowlan content
RTW_WOWLAN_CMD_KEEPALIVE = 0x06, //for keep alive packet setting
RTW_WOWLAN_CMD_MAX = 0xff
};
#define RTW_WOWLAN_MAX_RX_FILTERS (5)
#define RTW_WOWLAN_RX_FILTER_MAX_FIELDS (8)
#define RTW_WOWLAN_ID_OFFSET (100) //to match some application, ID starts from 100
#define RTW_WOWLAN_MIN_FILTERS_ID (RTW_WOWLAN_ID_OFFSET)
#define RTW_WOWLAN_MAX_FILTERS_ID (RTW_WOWLAN_ID_OFFSET+RTW_WOWLAN_MAX_RX_FILTERS-1)
struct rtw_wowlan_rx_filter_field {
u16 offset;
u8 len;
u8 flags;
u8 *mask;
u8 *pattern;
};
struct rtw_wowlan_rx_filter {
u8 action;
u8 offset;
u8 num_fields;
struct rtw_wowlan_rx_filter_field fields[RTW_WOWLAN_RX_FILTER_MAX_FIELDS];
};
#if defined(__IAR_SYSTEMS_ICC__)|| defined (__GNUC__)
#pragma pack(1)
#else
#error "this structure needs to be packed!"
#endif
struct rtw_wowlan_status {
u32 wakeup_reasons; //record wake up reason
u32 filter_id; //record which pattern is matched
};
#if defined(__IAR_SYSTEMS_ICC__)|| defined (__GNUC__)
#pragma pack()
#else
#error "this structure needs to be packed!"
#endif
/**
* struct rtw_wowlan_keepalive_packet
*
* @payload_len: data payload length
* @payload: data payload buffer
* @data_interval: interval at which to send data packets
**/
#define RTW_WOWLAN_MAX_KPALIVE_PKT 3
#define RTW_WOWLAN_MAX_KPALIVE_PKT_SZ 512
struct rtw_wowlan_keepalive_packet{
u8 packet_id;
int payload_len;
u8 *payload;
u32 data_interval;
_wowTimer keepalive_tmr;
};
struct rtw_wowlan_ops {
int (*DevWowlanInit)(void);
int (*DevWowlanEnable)(void);
int (*DevWowlanDisable)(void);
int (*DevWowlanWakeUp)(void);
int (*DevWowlanSleep)(void);
};
/**
* enum rtw_wowlan_proto_offloads - enabled protocol offloads
* @RTW_WOWLAN_PROTO_OFFLOAD_ARP: ARP data is enabled
*/
enum rtw_wowlan_proto_offloads {
RTW_WOWLAN_PROTO_OFFLOAD_ARP = BIT(0),
RTW_WOWLAN_PROTO_OFFLOAD_MAX = 0x7FFFFFFF
};
/**
* struct rtw_wowlan_proto_offload_common - ARP/NS offload common part
* @enabled: enable flags
* @remote_ipv4_addr: remote address to answer to (or zero if all)
* @host_ipv4_addr: our IPv4 address to respond to queries for
* @arp_mac_addr: our MAC address for ARP responses
* @reserved: unused
*/
struct rtw_wowlan_proto_offload_common{
int proto_enabled;
u32 remote_ipv4_addr;
u32 host_ipv4_addr;
u8 host_mac_addr[ETH_ALEN];
u16 reserved;
};
struct rtw_wowlan {
_wowlock wow_mutex;
bool enabled;
struct rtw_wowlan_status status;
struct rtw_wowlan_ops ops;
struct rtw_wowlan_proto_offload_common proto;
bool proto_offload_enabled;
struct rtw_wowlan_rx_filter *rx_filter[RTW_WOWLAN_MAX_RX_FILTERS];
bool rx_filter_enabled[RTW_WOWLAN_MAX_RX_FILTERS];/* RX Data filter rule state - enabled/disabled */
struct rtw_wowlan_keepalive_packet *tx_keepalive[RTW_WOWLAN_MAX_KPALIVE_PKT];
bool tx_keepalive_enabled[RTW_WOWLAN_MAX_KPALIVE_PKT];/* TX keep avlive rule state - enabled/disabled */
};
#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
#define cpIpAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3])
#define RTW_WOWLAN_GET_ARP_PKT_OPERATION(__pHeader) ReadEF2Byte( ((u8*)(__pHeader)) + 6)
#define RTW_WOWLAN_GET_ARP_PKT_SENDER_MAC_ADDR(__pHeader, _val) cpMacAddr((u8*)(_val), ((u8*)(__pHeader))+8)
#define RTW_WOWLAN_GET_ARP_PKT_SENDER_IP_ADDR(__pHeader, _val) cpIpAddr((u8*)(_val), ((u8*)(__pHeader))+14)
#define RTW_WOWLAN_GET_ARP_PKT_TARGET_MAC_ADDR(__pHeader, _val) cpMacAddr((u8*)(_val), ((u8*)(__pHeader))+18)
#define RTW_WOWLAN_GET_ARP_PKT_TARGET_IP_ADDR(__pHeader, _val) cpIpAddr((u8*)(_val), ((u8*)(__pHeader))+24)
#define RTW_WOWLAN_SET_ARP_PKT_HW(__pHeader, __Value) WriteEF2Byte( ((u8*)(__pHeader)) + 0, __Value)
#define RTW_WOWLAN_SET_ARP_PKT_PROTOCOL(__pHeader, __Value) WriteEF2Byte( ((u8*)(__pHeader)) + 2, __Value)
#define RTW_WOWLAN_SET_ARP_PKT_HW_ADDR_LEN(__pHeader, __Value) WriteEF1Byte( ((u8*)(__pHeader)) + 4, __Value)
#define RTW_WOWLAN_SET_ARP_PKT_PROTOCOL_ADDR_LEN(__pHeader, __Value) WriteEF1Byte( ((u8*)(__pHeader)) + 5, __Value)
#define RTW_WOWLAN_SET_ARP_PKT_OPERATION(__pHeader, __Value) WriteEF2Byte( ((u8*)(__pHeader)) + 6, __Value)
#define RTW_WOWLAN_SET_ARP_PKT_SENDER_MAC_ADDR(__pHeader, _val) cpMacAddr(((u8*)(__pHeader))+8, (u8*)(_val))
#define RTW_WOWLAN_SET_ARP_PKT_SENDER_IP_ADDR(__pHeader, _val) cpIpAddr(((u8*)(__pHeader))+14, (u8*)(_val))
#define RTW_WOWLAN_SET_ARP_PKT_TARGET_MAC_ADDR(__pHeader, _val) cpMacAddr(((u8*)(__pHeader))+18, (u8*)(_val))
#define RTW_WOWLAN_SET_ARP_PKT_TARGET_IP_ADDR(__pHeader, _val) cpIpAddr(((u8*)(__pHeader))+24, (u8*)(_val))
#define RTW_WOWLAN_ARP_PKT_LEN 0x2A
#define RTW_WOWLAN_ARP_PKT_OPERATION_REQ 0x0100 //arp request
#define RTW_WOWLAN_ARP_PKT_OPERATION_RSP 0x0200 //arp response
extern u8 key_2char2num(u8 hch, u8 lch);
extern _LONG_CALL_ void __rtl_memDump_v1_00(const u8 *start, u32 size, char * strHeader);
#define rtw_wowlan_DumpForBytes(pData, Len) __rtl_memDump_v1_00(pData, Len, NULL)
#define PWOWLAN_TO_STATUS(pwowlan) (&pwowlan->status)
#define PWOWLAN_TO_OPS(pwowlan) (&pwowlan->ops)
#define PWOWLAN_TO_PROTO(pwowlan) (&pwowlan->proto)
#define PWOWLAN_TO_RX_FILTER(pwowlan) (pwowlan->rx_filter)
#define PWOWLAN_TO_TX_KEEPALIVE(pwowlan) (pwowlan->tx_keepalive)
/**
* rtw_wowlan_init: initialize wowlan service
* arg: None
* return: _SUCCESS or _FAIL
*/
extern int rtw_wowlan_init(void);
/**
* cmd_wowlan_service: input commands to configure wowlan service
* arg:
* @argc: number of input parameter
* @argv: content of input string
* return: None
*/
extern void cmd_wowlan_service(int argc, char **argv);
/**
* rtw_wowlan_process_rx_packet: entry for packet process in wowlan service once it starts
* arg:
* @rx_pkt: receive packet from wlan/ethernet
* @pkt_len: receive packet length
* return: _SUCCESS or _FAIL
*/
extern int rtw_wowlan_process_rx_packet(char *rx_pkt, u16 pkt_len);
/**
* rtw_wowlan_wakeup_process: wake up process once the reasons are matched,
* refer to enum rtw_wowlan_wakeup_reason
* arg:
* @reason: wake up reason, refer to enum rtw_wowlan_wakeup_reason
* return: None
*/
extern void rtw_wowlan_wakeup_process(int reason);
/**
* rtw_wowlan_is_enabled: if wowlan service is already enabled
* this function is called in rx path and wifi_inidication when wowlan service is running
* arg: None
* return: _True if enable or _False if disable
*/
extern int rtw_wowlan_is_enabled(void);
/**
* rtw_wowlan_get_wk_reason: query wake up reason, refer to enum rtw_wowlan_wakeup_reason
* arg: None
* return: wakeup_reason
*/
extern int rtw_wowlan_get_wk_reason(void);
/**
* rtw_wowlan_dev_sleep: sleep process on Ameba side, pull control for example
* this function is linked to dev_wowlan_sleep_process() in dev_wowlan.c
* arg: None
* return: None
*/
extern void rtw_wowlan_dev_sleep(void);
#endif

View file

@ -0,0 +1,589 @@
/*
* SSL/TLS interface definition
* Copyright (c) 2004-2013, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef TLS_H
#define TLS_H
struct tls_connection;
struct tls_random {
const u8 *client_random;
size_t client_random_len;
const u8 *server_random;
size_t server_random_len;
};
enum tls_event {
TLS_CERT_CHAIN_SUCCESS,
TLS_CERT_CHAIN_FAILURE,
TLS_PEER_CERTIFICATE,
TLS_ALERT
};
/*
* Note: These are used as identifier with external programs and as such, the
* values must not be changed.
*/
enum tls_fail_reason {
TLS_FAIL_UNSPECIFIED = 0,
TLS_FAIL_UNTRUSTED = 1,
TLS_FAIL_REVOKED = 2,
TLS_FAIL_NOT_YET_VALID = 3,
TLS_FAIL_EXPIRED = 4,
TLS_FAIL_SUBJECT_MISMATCH = 5,
TLS_FAIL_ALTSUBJECT_MISMATCH = 6,
TLS_FAIL_BAD_CERTIFICATE = 7,
TLS_FAIL_SERVER_CHAIN_PROBE = 8,
TLS_FAIL_DOMAIN_SUFFIX_MISMATCH = 9,
TLS_FAIL_DOMAIN_MISMATCH = 10,
};
#define TLS_MAX_ALT_SUBJECT 10
union tls_event_data {
struct {
int depth;
const char *subject;
enum tls_fail_reason reason;
const char *reason_txt;
const struct wpabuf *cert;
} cert_fail;
struct {
int depth;
const char *subject;
const struct wpabuf *cert;
const u8 *hash;
size_t hash_len;
const char *altsubject[TLS_MAX_ALT_SUBJECT];
int num_altsubject;
} peer_cert;
struct {
int is_local;
const char *type;
const char *description;
} alert;
};
struct tls_config {
const char *opensc_engine_path;
const char *pkcs11_engine_path;
const char *pkcs11_module_path;
int fips_mode;
int cert_in_cb;
const char *openssl_ciphers;
unsigned int tls_session_lifetime;
void (*event_cb)(void *ctx, enum tls_event ev,
union tls_event_data *data);
void *cb_ctx;
};
#define TLS_CONN_ALLOW_SIGN_RSA_MD5 BIT(0)
#define TLS_CONN_DISABLE_TIME_CHECKS BIT(1)
#define TLS_CONN_DISABLE_SESSION_TICKET BIT(2)
#define TLS_CONN_REQUEST_OCSP BIT(3)
#define TLS_CONN_REQUIRE_OCSP BIT(4)
#define TLS_CONN_DISABLE_TLSv1_1 BIT(5)
#define TLS_CONN_DISABLE_TLSv1_2 BIT(6)
#define TLS_CONN_EAP_FAST BIT(7)
#define TLS_CONN_DISABLE_TLSv1_0 BIT(8)
/**
* struct tls_connection_params - Parameters for TLS connection
* @ca_cert: File or reference name for CA X.509 certificate in PEM or DER
* format
* @ca_cert_blob: ca_cert as inlined data or %NULL if not used
* @ca_cert_blob_len: ca_cert_blob length
* @ca_path: Path to CA certificates (OpenSSL specific)
* @subject_match: String to match in the subject of the peer certificate or
* %NULL to allow all subjects
* @altsubject_match: String to match in the alternative subject of the peer
* certificate or %NULL to allow all alternative subjects
* @suffix_match: String to suffix match in the dNSName or CN of the peer
* certificate or %NULL to allow all domain names. This may allow subdomains an
* wildcard certificates. Each domain name label must have a full match.
* @domain_match: String to match in the dNSName or CN of the peer
* certificate or %NULL to allow all domain names. This requires a full,
* case-insensitive match.
* @client_cert: File or reference name for client X.509 certificate in PEM or
* DER format
* @client_cert_blob: client_cert as inlined data or %NULL if not used
* @client_cert_blob_len: client_cert_blob length
* @private_key: File or reference name for client private key in PEM or DER
* format (traditional format (RSA PRIVATE KEY) or PKCS#8 (PRIVATE KEY)
* @private_key_blob: private_key as inlined data or %NULL if not used
* @private_key_blob_len: private_key_blob length
* @private_key_passwd: Passphrase for decrypted private key, %NULL if no
* passphrase is used.
* @dh_file: File name for DH/DSA data in PEM format, or %NULL if not used
* @dh_blob: dh_file as inlined data or %NULL if not used
* @dh_blob_len: dh_blob length
* @engine: 1 = use engine (e.g., a smartcard) for private key operations
* (this is OpenSSL specific for now)
* @engine_id: engine id string (this is OpenSSL specific for now)
* @ppin: pointer to the pin variable in the configuration
* (this is OpenSSL specific for now)
* @key_id: the private key's id when using engine (this is OpenSSL
* specific for now)
* @cert_id: the certificate's id when using engine
* @ca_cert_id: the CA certificate's id when using engine
* @openssl_ciphers: OpenSSL cipher configuration
* @flags: Parameter options (TLS_CONN_*)
* @ocsp_stapling_response: DER encoded file with cached OCSP stapling response
* or %NULL if OCSP is not enabled
*
* TLS connection parameters to be configured with tls_connection_set_params()
* and tls_global_set_params().
*
* Certificates and private key can be configured either as a reference name
* (file path or reference to certificate store) or by providing the same data
* as a pointer to the data in memory. Only one option will be used for each
* field.
*/
struct tls_connection_params {
const char *ca_cert;
const u8 *ca_cert_blob;
size_t ca_cert_blob_len;
const char *ca_path;
const char *subject_match;
const char *altsubject_match;
const char *suffix_match;
const char *domain_match;
const char *client_cert;
const u8 *client_cert_blob;
size_t client_cert_blob_len;
const char *private_key;
const u8 *private_key_blob;
size_t private_key_blob_len;
const char *private_key_passwd;
const char *dh_file;
const u8 *dh_blob;
size_t dh_blob_len;
/* OpenSSL specific variables */
int engine;
const char *engine_id;
const char *pin;
const char *key_id;
const char *cert_id;
const char *ca_cert_id;
const char *openssl_ciphers;
unsigned int flags;
const char *ocsp_stapling_response;
};
/**
* tls_init - Initialize TLS library
* @conf: Configuration data for TLS library
* Returns: Context data to be used as tls_ctx in calls to other functions,
* or %NULL on failure.
*
* Called once during program startup and once for each RSN pre-authentication
* session. In other words, there can be two concurrent TLS contexts. If global
* library initialization is needed (i.e., one that is shared between both
* authentication types), the TLS library wrapper should maintain a reference
* counter and do global initialization only when moving from 0 to 1 reference.
*/
//ssl_context * tls_init(const struct tls_config *conf);
void * tls_init(const struct tls_config *conf);
/**
* tls_deinit - Deinitialize TLS library
* @tls_ctx: TLS context data from tls_init()
*
* Called once during program shutdown and once for each RSN pre-authentication
* session. If global library deinitialization is needed (i.e., one that is
* shared between both authentication types), the TLS library wrapper should
* maintain a reference counter and do global deinitialization only when moving
* from 1 to 0 references.
*/
void tls_deinit(void *tls_ctx);
/**
* tls_get_errors - Process pending errors
* @tls_ctx: TLS context data from tls_init()
* Returns: Number of found error, 0 if no errors detected.
*
* Process all pending TLS errors.
*/
int tls_get_errors(void *tls_ctx);
/**
* tls_connection_init - Initialize a new TLS connection
* @tls_ctx: TLS context data from tls_init()
* Returns: Connection context data, conn for other function calls
*/
struct tls_connection * tls_connection_init(void *tls_ctx);
/**
* tls_connection_deinit - Free TLS connection data
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
*
* Release all resources allocated for TLS connection.
*/
void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn);
/**
* tls_connection_established - Has the TLS connection been completed?
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* Returns: 1 if TLS connection has been completed, 0 if not.
*/
int tls_connection_established(void *tls_ctx, struct tls_connection *conn);
/**
* tls_connection_shutdown - Shutdown TLS connection
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* Returns: 0 on success, -1 on failure
*
* Shutdown current TLS connection without releasing all resources. New
* connection can be started by using the same conn without having to call
* tls_connection_init() or setting certificates etc. again. The new
* connection should try to use session resumption.
*/
int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn);
enum {
TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN = -4,
TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED = -3,
TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED = -2
};
/**
* tls_connection_set_params - Set TLS connection parameters
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @params: Connection parameters
* Returns: 0 on success, -1 on failure,
* TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED (-2) on error causing PKCS#11 engine
* failure, or
* TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED (-3) on failure to verify the
* PKCS#11 engine private key, or
* TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN (-4) on PIN error causing PKCS#11 engine
* failure.
*/
int __must_check
tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
const struct tls_connection_params *params);
/**
* tls_global_set_params - Set TLS parameters for all TLS connection
* @tls_ctx: TLS context data from tls_init()
* @params: Global TLS parameters
* Returns: 0 on success, -1 on failure,
* TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED (-2) on error causing PKCS#11 engine
* failure, or
* TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED (-3) on failure to verify the
* PKCS#11 engine private key, or
* TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN (-4) on PIN error causing PKCS#11 engine
* failure.
*/
int __must_check tls_global_set_params(
void *tls_ctx, const struct tls_connection_params *params);
/**
* tls_global_set_verify - Set global certificate verification options
* @tls_ctx: TLS context data from tls_init()
* @check_crl: 0 = do not verify CRLs, 1 = verify CRL for the user certificate,
* 2 = verify CRL for all certificates
* Returns: 0 on success, -1 on failure
*/
int __must_check tls_global_set_verify(void *tls_ctx, int check_crl);
/**
* tls_connection_set_verify - Set certificate verification options
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @verify_peer: 1 = verify peer certificate
* @flags: Connection flags (TLS_CONN_*)
* @session_ctx: Session caching context or %NULL to use default
* @session_ctx_len: Length of @session_ctx in bytes.
* Returns: 0 on success, -1 on failure
*/
int __must_check tls_connection_set_verify(void *tls_ctx,
struct tls_connection *conn,
int verify_peer,
unsigned int flags,
const u8 *session_ctx,
size_t session_ctx_len);
/**
* tls_connection_get_random - Get random data from TLS connection
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @data: Structure of client/server random data (filled on success)
* Returns: 0 on success, -1 on failure
*/
int __must_check tls_connection_get_random(void *tls_ctx,
struct tls_connection *conn,
struct tls_random *data);
/**
* tls_connection_prf - Use TLS-PRF to derive keying material
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @label: Label (e.g., description of the key) for PRF
* @server_random_first: seed is 0 = client_random|server_random,
* 1 = server_random|client_random
* @skip_keyblock: Skip TLS key block from the beginning of PRF output
* @out: Buffer for output data from TLS-PRF
* @out_len: Length of the output buffer
* Returns: 0 on success, -1 on failure
*
* tls_connection_prf() is required so that further keying material can be
* derived from the master secret. Example implementation of this function is in
* tls_prf_sha1_md5() when it is called with seed set to
* client_random|server_random (or server_random|client_random). For TLSv1.2 and
* newer, a different PRF is needed, though.
*/
int __must_check tls_connection_prf(void *tls_ctx,
struct tls_connection *conn,
const char *label,
int server_random_first,
int skip_keyblock,
u8 *out, size_t out_len);
/**
* tls_connection_handshake - Process TLS handshake (client side)
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @in_data: Input data from TLS server
* @appl_data: Pointer to application data pointer, or %NULL if dropped
* Returns: Output data, %NULL on failure
*
* The caller is responsible for freeing the returned output data. If the final
* handshake message includes application data, this is decrypted and
* appl_data (if not %NULL) is set to point this data. The caller is
* responsible for freeing appl_data.
*
* This function is used during TLS handshake. The first call is done with
* in_data == %NULL and the library is expected to return ClientHello packet.
* This packet is then send to the server and a response from server is given
* to TLS library by calling this function again with in_data pointing to the
* TLS message from the server.
*
* If the TLS handshake fails, this function may return %NULL. However, if the
* TLS library has a TLS alert to send out, that should be returned as the
* output data. In this case, tls_connection_get_failed() must return failure
* (> 0).
*
* tls_connection_established() should return 1 once the TLS handshake has been
* completed successfully.
*/
struct wpabuf * tls_connection_handshake(void *tls_ctx,
struct tls_connection *conn,
const struct wpabuf *in_data,
struct wpabuf **appl_data);
struct wpabuf * tls_connection_handshake2(void *tls_ctx,
struct tls_connection *conn,
const struct wpabuf *in_data,
struct wpabuf **appl_data,
int *more_data_needed);
/**
* tls_connection_server_handshake - Process TLS handshake (server side)
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @in_data: Input data from TLS peer
* @appl_data: Pointer to application data pointer, or %NULL if dropped
* Returns: Output data, %NULL on failure
*
* The caller is responsible for freeing the returned output data.
*/
struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
struct tls_connection *conn,
const struct wpabuf *in_data,
struct wpabuf **appl_data);
/**
* tls_connection_encrypt - Encrypt data into TLS tunnel
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @in_data: Plaintext data to be encrypted
* Returns: Encrypted TLS data or %NULL on failure
*
* This function is used after TLS handshake has been completed successfully to
* send data in the encrypted tunnel. The caller is responsible for freeing the
* returned output data.
*/
struct wpabuf * tls_connection_encrypt(void *tls_ctx,
struct tls_connection *conn,
const struct wpabuf *in_data);
/**
* tls_connection_decrypt - Decrypt data from TLS tunnel
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @in_data: Encrypted TLS data
* Returns: Decrypted TLS data or %NULL on failure
*
* This function is used after TLS handshake has been completed successfully to
* receive data from the encrypted tunnel. The caller is responsible for
* freeing the returned output data.
*/
struct wpabuf * tls_connection_decrypt(void *tls_ctx,
struct tls_connection *conn,
const struct wpabuf *in_data);
struct wpabuf * tls_connection_decrypt2(void *tls_ctx,
struct tls_connection *conn,
const struct wpabuf *in_data,
int *more_data_needed);
/**
* tls_connection_resumed - Was session resumption used
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* Returns: 1 if current session used session resumption, 0 if not
*/
int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn);
enum {
TLS_CIPHER_NONE,
TLS_CIPHER_RC4_SHA /* 0x0005 */,
TLS_CIPHER_AES128_SHA /* 0x002f */,
TLS_CIPHER_RSA_DHE_AES128_SHA /* 0x0031 */,
TLS_CIPHER_ANON_DH_AES128_SHA /* 0x0034 */
};
/**
* tls_connection_set_cipher_list - Configure acceptable cipher suites
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @ciphers: Zero (TLS_CIPHER_NONE) terminated list of allowed ciphers
* (TLS_CIPHER_*).
* Returns: 0 on success, -1 on failure
*/
int __must_check tls_connection_set_cipher_list(void *tls_ctx,
struct tls_connection *conn,
u8 *ciphers);
/**
* tls_get_version - Get the current TLS version number
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @buf: Buffer for returning the TLS version number
* @buflen: buf size
* Returns: 0 on success, -1 on failure
*
* Get the currently used TLS version number.
*/
int __must_check tls_get_version(void *tls_ctx, struct tls_connection *conn,
char *buf, size_t buflen);
/**
* tls_get_cipher - Get current cipher name
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @buf: Buffer for the cipher name
* @buflen: buf size
* Returns: 0 on success, -1 on failure
*
* Get the name of the currently used cipher.
*/
int __must_check tls_get_cipher(void *tls_ctx, struct tls_connection *conn,
char *buf, size_t buflen);
/**
* tls_connection_enable_workaround - Enable TLS workaround options
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* Returns: 0 on success, -1 on failure
*
* This function is used to enable connection-specific workaround options for
* buffer SSL/TLS implementations.
*/
int __must_check tls_connection_enable_workaround(void *tls_ctx,
struct tls_connection *conn);
/**
* tls_connection_client_hello_ext - Set TLS extension for ClientHello
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @ext_type: Extension type
* @data: Extension payload (%NULL to remove extension)
* @data_len: Extension payload length
* Returns: 0 on success, -1 on failure
*/
int __must_check tls_connection_client_hello_ext(void *tls_ctx,
struct tls_connection *conn,
int ext_type, const u8 *data,
size_t data_len);
/**
* tls_connection_get_failed - Get connection failure status
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
*
* Returns >0 if connection has failed, 0 if not.
*/
int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn);
/**
* tls_connection_get_read_alerts - Get connection read alert status
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* Returns: Number of times a fatal read (remote end reported error) has
* happened during this connection.
*/
int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn);
/**
* tls_connection_get_write_alerts - Get connection write alert status
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* Returns: Number of times a fatal write (locally detected error) has happened
* during this connection.
*/
int tls_connection_get_write_alerts(void *tls_ctx,
struct tls_connection *conn);
typedef int (*tls_session_ticket_cb)
(void *ctx, const u8 *ticket, size_t len, const u8 *client_random,
const u8 *server_random, u8 *master_secret);
int __must_check tls_connection_set_session_ticket_cb(
void *tls_ctx, struct tls_connection *conn,
tls_session_ticket_cb cb, void *ctx);
void tls_connection_set_log_cb(struct tls_connection *conn,
void (*log_cb)(void *ctx, const char *msg),
void *ctx);
#define TLS_BREAK_VERIFY_DATA BIT(0)
#define TLS_BREAK_SRV_KEY_X_HASH BIT(1)
#define TLS_BREAK_SRV_KEY_X_SIGNATURE BIT(2)
#define TLS_DHE_PRIME_511B BIT(3)
#define TLS_DHE_PRIME_767B BIT(4)
#define TLS_DHE_PRIME_15 BIT(5)
#define TLS_DHE_PRIME_58B BIT(6)
#define TLS_DHE_NON_PRIME BIT(7)
void tls_connection_set_test_flags(struct tls_connection *conn, u32 flags);
int tls_get_library_version(char *buf, size_t buf_len);
void tls_connection_set_success_data(struct tls_connection *conn,
struct wpabuf *data);
void tls_connection_set_success_data_resumed(struct tls_connection *conn);
const struct wpabuf *
tls_connection_get_success_data(struct tls_connection *conn);
void tls_connection_remove_session(struct tls_connection *conn);
#endif /* TLS_H */

View file

@ -0,0 +1,548 @@
/*
* wpa_supplicant/hostapd / common helper functions, etc.
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef COMMON_H
#define COMMON_H
#include "utils/os.h"
#define TO_TEST_WPS 0
#define ETH_ALEN 6
#if defined(__linux__) || defined(__GLIBC__)
#include <endian.h>
#include <byteswap.h>
#endif /* __linux__ */
#if defined(PLATFORM_FREERTOS)
//#include "little_endian.h"
//#include "basic_types.h"
#endif /* PLATFORM_FREERTOS */
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \
defined(__OpenBSD__)
#include <sys/types.h>
#include <sys/endian.h>
#define __BYTE_ORDER _BYTE_ORDER
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#define __BIG_ENDIAN _BIG_ENDIAN
#ifdef __OpenBSD__
#define bswap_16 swap16
#define bswap_32 swap32
#define bswap_64 swap64
#else /* __OpenBSD__ */
#define bswap_16 bswap16
#define bswap_32 bswap32
#define bswap_64 bswap64
#endif /* __OpenBSD__ */
#endif /* defined(__FreeBSD__) || defined(__NetBSD__) || * defined(__DragonFly__) || defined(__OpenBSD__) */
#ifdef __APPLE__
#include <sys/types.h>
#include <machine/endian.h>
#define __BYTE_ORDER _BYTE_ORDER
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#define __BIG_ENDIAN _BIG_ENDIAN
static inline unsigned short bswap_16(unsigned short v)
{
return ((v & 0xff) << 8) | (v >> 8);
}
static inline unsigned int bswap_32(unsigned int v)
{
return ((v & 0xff) << 24) | ((v & 0xff00) << 8) |
((v & 0xff0000) >> 8) | (v >> 24);
}
#endif /* __APPLE__ */
#ifdef CONFIG_TI_COMPILER
#define __BIG_ENDIAN 4321
#define __LITTLE_ENDIAN 1234
#ifdef __big_endian__
#define __BYTE_ORDER __BIG_ENDIAN
#else
#define __BYTE_ORDER __LITTLE_ENDIAN
#endif
#endif /* CONFIG_TI_COMPILER */
#ifdef CONFIG_NATIVE_WINDOWS
#include <winsock.h>
typedef int socklen_t;
#ifndef MSG_DONTWAIT
#define MSG_DONTWAIT 0 /* not supported */
#endif
#endif /* CONFIG_NATIVE_WINDOWS */
#ifdef _MSC_VER
#define inline __inline
#undef vsnprintf
#define vsnprintf _vsnprintf
#undef close
#define close closesocket
#endif /* _MSC_VER */
/* Define platform specific integer types */
#ifdef _MSC_VER
typedef UINT64 u64;
typedef UINT32 u32;
typedef UINT16 u16;
typedef UINT8 u8;
typedef INT64 s64;
typedef INT32 s32;
typedef INT16 s16;
typedef INT8 s8;
#define WPA_TYPES_DEFINED
#endif /* _MSC_VER */
#ifdef __vxworks
typedef unsigned long long u64;
typedef UINT32 u32;
typedef UINT16 u16;
typedef UINT8 u8;
typedef long long s64;
typedef INT32 s32;
typedef INT16 s16;
typedef INT8 s8;
#define WPA_TYPES_DEFINED
#endif /* __vxworks */
#ifdef CONFIG_TI_COMPILER
#ifdef _LLONG_AVAILABLE
typedef unsigned long long u64;
#else
/*
* TODO: 64-bit variable not available. Using long as a workaround to test the
* build, but this will likely not work for all operations.
*/
typedef unsigned long u64;
#endif
typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;
#define WPA_TYPES_DEFINED
#endif /* CONFIG_TI_COMPILER */
#ifndef WPA_TYPES_DEFINED
#ifdef CONFIG_USE_INTTYPES_H
#include <inttypes.h>
#else
//#include <stdint.h>
#endif
#if 0
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
typedef int64_t s64;
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;
#endif
#define WPA_TYPES_DEFINED
#endif /* !WPA_TYPES_DEFINED */
/* Define platform specific byte swapping macros */
#if defined(__CYGWIN__) || defined(CONFIG_NATIVE_WINDOWS)
static inline unsigned short wpa_swap_16(unsigned short v)
{
return ((v & 0xff) << 8) | (v >> 8);
}
static inline unsigned int wpa_swap_32(unsigned int v)
{
return ((v & 0xff) << 24) | ((v & 0xff00) << 8) |
((v & 0xff0000) >> 8) | (v >> 24);
}
#define le_to_host16(n) (n)
#define host_to_le16(n) (n)
#define be_to_host16(n) wpa_swap_16(n)
#define host_to_be16(n) wpa_swap_16(n)
#define le_to_host32(n) (n)
#define be_to_host32(n) wpa_swap_32(n)
#define host_to_be32(n) wpa_swap_32(n)
#define WPA_BYTE_SWAP_DEFINED
#endif /* __CYGWIN__ || CONFIG_NATIVE_WINDOWS */
#ifndef WPA_BYTE_SWAP_DEFINED
#if 0
#ifndef __BYTE_ORDER
#ifndef __LITTLE_ENDIAN
#ifndef __BIG_ENDIAN
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#if defined(sparc)
#define __BYTE_ORDER __BIG_ENDIAN
#endif
#endif /* __BIG_ENDIAN */
#endif /* __LITTLE_ENDIAN */
#endif /* __BYTE_ORDER */
#else
#ifndef __LITTLE_ENDIAN
#define __LITTLE_ENDIAN 1234
#endif
#ifndef __BIG_ENDIAN
#define __BIG_ENDIAN 4321
#endif
#ifndef __BYTE_ORDER
#define __BYTE_ORDER __LITTLE_ENDIAN
#endif
#endif
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define le_to_host16(n) ((__force u16) (le16) (n))
#define host_to_le16(n) ((__force le16) (u16) (n))
#define be_to_host16(n) bswap_16((__force u16) (be16) (n))
#define host_to_be16(n) ((__force be16) bswap_16((n)))
#define le_to_host32(n) ((__force u32) (le32) (n))
#define host_to_le32(n) ((__force le32) (u32) (n))
#define be_to_host32(n) bswap_32((__force u32) (be32) (n))
#define host_to_be32(n) ((__force be32) bswap_32((n)))
#define le_to_host64(n) ((__force u64) (le64) (n))
#define host_to_le64(n) ((__force le64) (u64) (n))
#define be_to_host64(n) bswap_64((__force u64) (be64) (n))
#define host_to_be64(n) ((__force be64) bswap_64((n)))
#elif __BYTE_ORDER == __BIG_ENDIAN
#define le_to_host16(n) bswap_16(n)
#define host_to_le16(n) bswap_16(n)
#define be_to_host16(n) (n)
#define host_to_be16(n) (n)
#define le_to_host32(n) bswap_32(n)
#define be_to_host32(n) (n)
#define host_to_be32(n) (n)
#define le_to_host64(n) bswap_64(n)
#define host_to_le64(n) bswap_64(n)
#define be_to_host64(n) (n)
#define host_to_be64(n) (n)
#ifndef WORDS_BIGENDIAN
#define WORDS_BIGENDIAN
#endif
#else
//#error Could not determine CPU byte order
#endif
#define WPA_BYTE_SWAP_DEFINED
#endif /* !WPA_BYTE_SWAP_DEFINED */
/* Macros for handling unaligned memory accesses */
#define WPA_GET_BE16(a) ((u16) (((a)[0] << 8) | (a)[1]))
#define WPA_PUT_BE16(a, val) \
do { \
(a)[0] = ((u16) (val)) >> 8; \
(a)[1] = ((u16) (val)) & 0xff; \
} while (0)
#define WPA_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0]))
#define WPA_PUT_LE16(a, val) \
do { \
(a)[1] = ((u16) (val)) >> 8; \
(a)[0] = ((u16) (val)) & 0xff; \
} while (0)
#define WPA_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \
((u32) (a)[2]))
#define WPA_PUT_BE24(a, val) \
do { \
(a)[0] = (u8) ((((u32) (val)) >> 16) & 0xff); \
(a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \
(a)[2] = (u8) (((u32) (val)) & 0xff); \
} while (0)
#define WPA_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \
(((u32) (a)[2]) << 8) | ((u32) (a)[3]))
#define WPA_PUT_BE32(a, val) \
do { \
(a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \
(a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \
(a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \
(a)[3] = (u8) (((u32) (val)) & 0xff); \
} while (0)
#define WPA_GET_LE32(a) ((((u32) (a)[3]) << 24) | (((u32) (a)[2]) << 16) | \
(((u32) (a)[1]) << 8) | ((u32) (a)[0]))
#define WPA_PUT_LE32(a, val) \
do { \
(a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff); \
(a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff); \
(a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \
(a)[0] = (u8) (((u32) (val)) & 0xff); \
} while (0)
#define WPA_GET_BE64(a) ((((u64) (a)[0]) << 56) | (((u64) (a)[1]) << 48) | \
(((u64) (a)[2]) << 40) | (((u64) (a)[3]) << 32) | \
(((u64) (a)[4]) << 24) | (((u64) (a)[5]) << 16) | \
(((u64) (a)[6]) << 8) | ((u64) (a)[7]))
#define WPA_PUT_BE64(a, val) \
do { \
(a)[0] = (u8) (((u64) (val)) >> 56); \
(a)[1] = (u8) (((u64) (val)) >> 48); \
(a)[2] = (u8) (((u64) (val)) >> 40); \
(a)[3] = (u8) (((u64) (val)) >> 32); \
(a)[4] = (u8) (((u64) (val)) >> 24); \
(a)[5] = (u8) (((u64) (val)) >> 16); \
(a)[6] = (u8) (((u64) (val)) >> 8); \
(a)[7] = (u8) (((u64) (val)) & 0xff); \
} while (0)
#define WPA_GET_LE64(a) ((((u64) (a)[7]) << 56) | (((u64) (a)[6]) << 48) | \
(((u64) (a)[5]) << 40) | (((u64) (a)[4]) << 32) | \
(((u64) (a)[3]) << 24) | (((u64) (a)[2]) << 16) | \
(((u64) (a)[1]) << 8) | ((u64) (a)[0]))
#ifndef ETH_ALEN
#define ETH_ALEN 6
#endif
#ifndef IFNAMSIZ
#define IFNAMSIZ 16
#endif
#ifndef ETH_P_ALL
#define ETH_P_ALL 0x0003
#endif
#ifndef ETH_P_80211_ENCAP
#define ETH_P_80211_ENCAP 0x890d /* TDLS comes under this category */
#endif
#ifndef ETH_P_PAE
#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
#endif /* ETH_P_PAE */
#ifndef ETH_P_EAPOL
#define ETH_P_EAPOL ETH_P_PAE
#endif /* ETH_P_EAPOL */
#ifndef ETH_P_RSN_PREAUTH
#define ETH_P_RSN_PREAUTH 0x88c7
#endif /* ETH_P_RSN_PREAUTH */
#ifndef ETH_P_RRB
#define ETH_P_RRB 0x890D
#endif /* ETH_P_RRB */
#if 0 //#ifdef __GNUC__
#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b))))
#define STRUCT_PACKED __attribute__ ((packed))
#else
#define PRINTF_FORMAT(a,b)
#define STRUCT_PACKED
#endif
#ifdef CONFIG_ANSI_C_EXTRA
#if !defined(_MSC_VER) || _MSC_VER < 1400
/* snprintf - used in number of places; sprintf() is _not_ a good replacement
* due to possible buffer overflow; see, e.g.,
* http://www.ijs.si/software/snprintf/ for portable implementation of
* snprintf. */
int snprintf(char *str, size_t size, const char *format, ...);
/* vsnprintf - only used for wpa_msg() in wpa_supplicant.c */
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
#endif /* !defined(_MSC_VER) || _MSC_VER < 1400 */
/* getopt - only used in main.c */
int getopt(int argc, char *const argv[], const char *optstring);
extern char *optarg;
extern int optind;
#ifndef CONFIG_NO_SOCKLEN_T_TYPEDEF
#ifndef __socklen_t_defined
typedef int socklen_t;
#endif
#endif
/* inline - define as __inline or just define it to be empty, if needed */
#ifdef CONFIG_NO_INLINE
#define inline
#else
#define inline __inline
#endif
#ifndef __func__
#define __func__ "__func__ not defined"
#endif
#ifndef bswap_16
#define bswap_16(a) ((((u16) (a) << 8) & 0xff00) | (((u16) (a) >> 8) & 0xff))
#endif
#ifndef bswap_32
#define bswap_32(a) ((((u32) (a) << 24) & 0xff000000) | \
(((u32) (a) << 8) & 0xff0000) | \
(((u32) (a) >> 8) & 0xff00) | \
(((u32) (a) >> 24) & 0xff))
#endif
#ifndef MSG_DONTWAIT
#define MSG_DONTWAIT 0
#endif
#ifdef _WIN32_WCE
void perror(const char *s);
#endif /* _WIN32_WCE */
#endif /* CONFIG_ANSI_C_EXTRA */
#ifndef MAC2STR
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
/*
* Compact form for string representation of MAC address
* To be used, e.g., for constructing dbus paths for P2P Devices
*/
#define COMPACT_MACSTR "%02x%02x%02x%02x%02x%02x"
#endif
#ifndef BIT
#define BIT(x) (1 << (x))
#endif
/*
* Definitions for sparse validation
* (http://kernel.org/pub/linux/kernel/people/josh/sparse/)
*/
#ifdef __CHECKER__
#define __force __attribute__((force))
#define __bitwise __attribute__((bitwise))
#else
#define __force
#define __bitwise
#endif
typedef u16 __bitwise be16;
typedef u16 __bitwise le16;
typedef u32 __bitwise be32;
typedef u32 __bitwise le32;
typedef u64 __bitwise be64;
typedef u64 __bitwise le64;
#ifndef __must_check
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#define __must_check __attribute__((__warn_unused_result__))
#else
#define __must_check
#endif /* __GNUC__ */
#endif /* __must_check */
//int hwaddr_aton(const char *txt, u8 *addr);
int hwaddr_compact_aton(const char *txt, u8 *addr);
int hwaddr_aton2(const char *txt, u8 *addr);
int hex2byte(const char *hex);
int hexstr2bin(const char *hex, u8 *buf, size_t len);
void inc_byte_array(u8 *counter, size_t len);
void wpa_get_ntp_timestamp(u8 *buf);
//int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len);
int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
size_t len);
#ifdef CONFIG_NATIVE_WINDOWS
void wpa_unicode2ascii_inplace(TCHAR *str);
TCHAR * wpa_strdup_tchar(const char *str);
#else /* CONFIG_NATIVE_WINDOWS */
#define wpa_unicode2ascii_inplace(s) do { } while (0)
#define wpa_strdup_tchar(s) strdup((s))
#endif /* CONFIG_NATIVE_WINDOWS */
void printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len);
size_t printf_decode(u8 *buf, size_t maxlen, const char *str);
const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len);
char * wpa_config_parse_string(const char *value, size_t *len);
int is_hex(const u8 *data, size_t len);
size_t merge_byte_arrays(u8 *res, size_t res_len,
const u8 *src1, size_t src1_len,
const u8 *src2, size_t src2_len);
static inline int is_zero_ether_addr(const u8 *a)
{
return !(a[0] | a[1] | a[2] | a[3] | a[4] | a[5]);
}
static inline int is_broadcast_ether_addr(const u8 *a)
{
return (a[0] & a[1] & a[2] & a[3] & a[4] & a[5]) == 0xff;
}
#define broadcast_ether_addr (const u8 *) "\xff\xff\xff\xff\xff\xff"
#include "wpa_debug.h"
char * dup_binstr(const void *src, size_t len);
struct wpa_freq_range_list {
struct wpa_freq_range {
unsigned int min;
unsigned int max;
} *range;
unsigned int num;
};
int freq_range_list_parse(struct wpa_freq_range_list *res, const char *value);
int freq_range_list_includes(const struct wpa_freq_range_list *list,
unsigned int freq);
char * freq_range_list_str(const struct wpa_freq_range_list *list);
int int_array_len(const int *a);
void int_array_concat(int **res, const int *a);
void int_array_sort_unique(int *a);
void int_array_add_unique(int **res, int a);
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
void str_clear_free(char *str);
void bin_clear_free(void *bin, size_t len);
int random_mac_addr(u8 *addr);
int random_mac_addr_keep_oui(u8 *addr);
const char * cstr_token(const char *str, const char *delim, const char **last);
char * str_token(char *str, const char *delim, char **context);
size_t utf8_escape(const char *inp, size_t in_size,
char *outp, size_t out_size);
size_t utf8_unescape(const char *inp, size_t in_size,
char *outp, size_t out_size);
int is_ctrl_char(char c);
#ifndef bswap_16
#define bswap_16(a) ((((u16) (a) << 8) & 0xff00) | (((u16) (a) >> 8) & 0xff))
#endif
/*
* gcc 4.4 ends up generating strict-aliasing warnings about some very common
* networking socket uses that do not really result in a real problem and
* cannot be easily avoided with union-based type-punning due to struct
* definitions including another struct in system header files. To avoid having
* to fully disable strict-aliasing warnings, provide a mechanism to hide the
* typecast from aliasing for now. A cleaner solution will hopefully be found
* in the future to handle these cases.
*/
void * __hide_aliasing_typecast(void *foo);
#define aliasing_hide_typecast(a,t) (t *) __hide_aliasing_typecast((a))
#ifdef CONFIG_VALGRIND
#include <valgrind/memcheck.h>
#define WPA_MEM_DEFINED(ptr, len) VALGRIND_MAKE_MEM_DEFINED((ptr), (len))
#else /* CONFIG_VALGRIND */
#define WPA_MEM_DEFINED(ptr, len) do { } while (0)
#endif /* CONFIG_VALGRIND */
#endif /* COMMON_H */

View file

@ -0,0 +1,119 @@
#ifndef INCLUDES_H
#define INCLUDES_H
#define CONFIG_NO_STDOUT_DEBUG
#ifndef CONFIG_NO_STDOUT_DEBUG
/* Event messages with fixed prefix */
/** Authentication completed successfully and data connection enabled */
#define WPA_EVENT_CONNECTED "CTRL-EVENT-CONNECTED "
/** Disconnected, data connection is not available */
#define WPA_EVENT_DISCONNECTED "CTRL-EVENT-DISCONNECTED "
/** Association rejected during connection attempt */
#define WPA_EVENT_ASSOC_REJECT "CTRL-EVENT-ASSOC-REJECT "
/** Authentication rejected during connection attempt */
#define WPA_EVENT_AUTH_REJECT "CTRL-EVENT-AUTH-REJECT "
/** wpa_supplicant is exiting */
#define WPA_EVENT_TERMINATING "CTRL-EVENT-TERMINATING "
/** Password change was completed successfully */
#define WPA_EVENT_PASSWORD_CHANGED "CTRL-EVENT-PASSWORD-CHANGED "
/** EAP-Request/Notification received */
#define WPA_EVENT_EAP_NOTIFICATION "CTRL-EVENT-EAP-NOTIFICATION "
/** EAP authentication started (EAP-Request/Identity received) */
#define WPA_EVENT_EAP_STARTED "CTRL-EVENT-EAP-STARTED "
/** EAP method proposed by the server */
#define WPA_EVENT_EAP_PROPOSED_METHOD "CTRL-EVENT-EAP-PROPOSED-METHOD "
/** EAP method selected */
#define WPA_EVENT_EAP_METHOD "CTRL-EVENT-EAP-METHOD "
/** EAP peer certificate from TLS */
#define WPA_EVENT_EAP_PEER_CERT "CTRL-EVENT-EAP-PEER-CERT "
/** EAP peer certificate alternative subject name component from TLS */
#define WPA_EVENT_EAP_PEER_ALT "CTRL-EVENT-EAP-PEER-ALT "
/** EAP TLS certificate chain validation error */
#define WPA_EVENT_EAP_TLS_CERT_ERROR "CTRL-EVENT-EAP-TLS-CERT-ERROR "
/** EAP status */
#define WPA_EVENT_EAP_STATUS "CTRL-EVENT-EAP-STATUS "
/** EAP authentication completed successfully */
#define WPA_EVENT_EAP_SUCCESS "CTRL-EVENT-EAP-SUCCESS "
/** EAP authentication failed (EAP-Failure received) */
#define WPA_EVENT_EAP_FAILURE "CTRL-EVENT-EAP-FAILURE "
/** Network block temporarily disabled (e.g., due to authentication failure) */
#define WPA_EVENT_TEMP_DISABLED "CTRL-EVENT-SSID-TEMP-DISABLED "
/** Temporarily disabled network block re-enabled */
#define WPA_EVENT_REENABLED "CTRL-EVENT-SSID-REENABLED "
/** New scan started */
#define WPA_EVENT_SCAN_STARTED "CTRL-EVENT-SCAN-STARTED "
/** New scan results available */
#define WPA_EVENT_SCAN_RESULTS "CTRL-EVENT-SCAN-RESULTS "
/** Scan command failed */
#define WPA_EVENT_SCAN_FAILED "CTRL-EVENT-SCAN-FAILED "
/** wpa_supplicant state change */
#define WPA_EVENT_STATE_CHANGE "CTRL-EVENT-STATE-CHANGE "
/** A new BSS entry was added (followed by BSS entry id and BSSID) */
#define WPA_EVENT_BSS_ADDED "CTRL-EVENT-BSS-ADDED "
/** A BSS entry was removed (followed by BSS entry id and BSSID) */
#define WPA_EVENT_BSS_REMOVED "CTRL-EVENT-BSS-REMOVED "
/** No suitable network was found */
#define WPA_EVENT_NETWORK_NOT_FOUND "CTRL-EVENT-NETWORK-NOT-FOUND "
/** Change in the signal level was reported by the driver */
#define WPA_EVENT_SIGNAL_CHANGE "CTRL-EVENT-SIGNAL-CHANGE "
/** Regulatory domain channel */
#define WPA_EVENT_REGDOM_CHANGE "CTRL-EVENT-REGDOM-CHANGE "
/** RSN IBSS 4-way handshakes completed with specified peer */
#define IBSS_RSN_COMPLETED "IBSS-RSN-COMPLETED "
/** Notification of frequency conflict due to a concurrent operation.
*
* The indicated network is disabled and needs to be re-enabled before it can
* be used again.
*/
#define WPA_EVENT_FREQ_CONFLICT "CTRL-EVENT-FREQ-CONFLICT "
/** Frequency ranges that the driver recommends to avoid */
#define WPA_EVENT_AVOID_FREQ "CTRL-EVENT-AVOID-FREQ "
/** WPS overlap detected in PBC mode */
#define WPS_EVENT_OVERLAP "WPS-OVERLAP-DETECTED "
/** Available WPS AP with active PBC found in scan results */
#define WPS_EVENT_AP_AVAILABLE_PBC "WPS-AP-AVAILABLE-PBC "
/** Available WPS AP with our address as authorized in scan results */
#define WPS_EVENT_AP_AVAILABLE_AUTH "WPS-AP-AVAILABLE-AUTH "
/** Available WPS AP with recently selected PIN registrar found in scan results
*/
#define WPS_EVENT_AP_AVAILABLE_PIN "WPS-AP-AVAILABLE-PIN "
/** Available WPS AP found in scan results */
#define WPS_EVENT_AP_AVAILABLE "WPS-AP-AVAILABLE "
/** A new credential received */
#define WPS_EVENT_CRED_RECEIVED "WPS-CRED-RECEIVED "
/** M2D received */
#define WPS_EVENT_M2D "WPS-M2D "
/** WPS registration failed after M2/M2D */
#define WPS_EVENT_FAIL "WPS-FAIL "
/** WPS registration completed successfully */
#define WPS_EVENT_SUCCESS "WPS-SUCCESS "
/** WPS enrollment attempt timed out and was terminated */
#define WPS_EVENT_TIMEOUT "WPS-TIMEOUT "
/* PBC mode was activated */
#define WPS_EVENT_ACTIVE "WPS-PBC-ACTIVE "
/* PBC mode was disabled */
#define WPS_EVENT_DISABLE "WPS-PBC-DISABLE "
#define WPS_EVENT_ENROLLEE_SEEN "WPS-ENROLLEE-SEEN "
#define WPS_EVENT_OPEN_NETWORK "WPS-OPEN-NETWORK "
/* WPS ER events */
#define WPS_EVENT_ER_AP_ADD "WPS-ER-AP-ADD "
#define WPS_EVENT_ER_AP_REMOVE "WPS-ER-AP-REMOVE "
#define WPS_EVENT_ER_ENROLLEE_ADD "WPS-ER-ENROLLEE-ADD "
#define WPS_EVENT_ER_ENROLLEE_REMOVE "WPS-ER-ENROLLEE-REMOVE "
#define WPS_EVENT_ER_AP_SETTINGS "WPS-ER-AP-SETTINGS "
#define WPS_EVENT_ER_SET_SEL_REG "WPS-ER-AP-SET-SEL-REG "
#endif /* CONFIG_NO_STDOUT_DEBUG */
//#define DBG_871X(...) vTaskDelay(100)
//DBG_871X_LEVEL(_drv_always_, "no beacon for a long time, disconnect or roaming\n");
//#define DBG_871X(...) DBG_871X_LEVEL(_drv_always_,...)
#endif /* INCLUDES_H */

View file

@ -0,0 +1,594 @@
/*
* OS specific functions
* Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef OS_H
#define OS_H
//#include "basic_types.h"
#include <autoconf.h>
#include "osdep_service.h"
#include "freertos/wrapper.h"
#include "utils/rom/rom_wps_os.h"
typedef void* xqueue_handle_t;
typedef long os_time_t;
typedef _timer os_timer;
/**
* os_sleep - Sleep (sec, usec)
* @sec: Number of seconds to sleep
* @usec: Number of microseconds to sleep
*/
void os_sleep(os_time_t sec, os_time_t usec);
struct os_time {
os_time_t sec;
os_time_t usec;
};
struct os_reltime {
os_time_t sec;
os_time_t usec;
};
/**
* os_get_time - Get current time (sec, usec)
* @t: Pointer to buffer for the time
* Returns: 0 on success, -1 on failure
*/
int os_get_time(struct os_time *t);
int os_get_reltime(struct os_reltime *t);
/* Helper macros for handling struct os_time */
/* (&timeout->time, &tmp->time) */
#define os_time_before(a, b) \
((a)->sec < (b)->sec || \
((a)->sec == (b)->sec && (a)->usec < (b)->usec))
#define os_time_sub(a, b, res) do { \
(res)->sec = (a)->sec - (b)->sec; \
(res)->usec = (a)->usec - (b)->usec; \
if ((res)->usec < 0) { \
(res)->sec--; \
(res)->usec += 1000000; \
} \
} while (0)
/**
* os_mktime - Convert broken-down time into seconds since 1970-01-01
* @year: Four digit year
* @month: Month (1 .. 12)
* @day: Day of month (1 .. 31)
* @hour: Hour (0 .. 23)
* @min: Minute (0 .. 59)
* @sec: Second (0 .. 60)
* @t: Buffer for returning calendar time representation (seconds since
* 1970-01-01 00:00:00)
* Returns: 0 on success, -1 on failure
*
* Note: The result is in seconds from Epoch, i.e., in UTC, not in local time
* which is used by POSIX mktime().
*/
int os_mktime(int year, int month, int day, int hour, int min, int sec,
os_time_t *t);
struct os_tm {
int sec; /* 0..59 or 60 for leap seconds */
int min; /* 0..59 */
int hour; /* 0..23 */
int day; /* 1..31 */
int month; /* 1..12 */
int year; /* Four digit year */
};
int os_gmtime(os_time_t t, struct os_tm *tm);
/* Helpers for handling struct os_time */
/* Helpers for handling struct os_reltime */
static inline int os_reltime_before(struct os_reltime *a,
struct os_reltime *b)
{
return os_time_before(a,b);
}
static inline void os_reltime_sub(struct os_reltime *a, struct os_reltime *b,
struct os_reltime *res)
{
os_time_sub(a,b,res);
}
static inline void os_reltime_age(struct os_reltime *start,
struct os_reltime *age)
{
struct os_reltime now;
os_get_time((struct os_time *)&now);
os_reltime_sub(&now, start, age);
}
static inline int os_reltime_expired(struct os_reltime *now,
struct os_reltime *ts,
os_time_t timeout_secs)
{
struct os_reltime age;
os_reltime_sub(now, ts, &age);
return (age.sec > timeout_secs) ||
(age.sec == timeout_secs && age.usec > 0);
}
/**
* os_daemonize - Run in the background (detach from the controlling terminal)
* @pid_file: File name to write the process ID to or %NULL to skip this
* Returns: 0 on success, -1 on failure
*/
int os_daemonize(const char *pid_file);
/**
* os_daemonize_terminate - Stop running in the background (remove pid file)
* @pid_file: File name to write the process ID to or %NULL to skip this
*/
void os_daemonize_terminate(const char *pid_file);
/**
* os_get_random - Get cryptographically strong pseudo random data
* @buf: Buffer for pseudo random data
* @len: Length of the buffer
* Returns: 0 on success, -1 on failure
*/
int os_get_random(unsigned char *buf, size_t len);
/**
* os_random - Get pseudo random value (not necessarily very strong)
* Returns: Pseudo random value
*/
unsigned long os_random(void);
/**
* os_rel2abs_path - Get an absolute path for a file
* @rel_path: Relative path to a file
* Returns: Absolute path for the file or %NULL on failure
*
* This function tries to convert a relative path of a file to an absolute path
* in order for the file to be found even if current working directory has
* changed. The returned value is allocated and caller is responsible for
* freeing it. It is acceptable to just return the same path in an allocated
* buffer, e.g., return strdup(rel_path). This function is only used to find
* configuration files when os_daemonize() may have changed the current working
* directory and relative path would be pointing to a different location.
*/
char * os_rel2abs_path(const char *rel_path);
/**
* os_program_init - Program initialization (called at start)
* Returns: 0 on success, -1 on failure
*
* This function is called when a programs starts. If there are any OS specific
* processing that is needed, it can be placed here. It is also acceptable to
* just return 0 if not special processing is needed.
*/
int os_program_init(void);
/**
* os_program_deinit - Program deinitialization (called just before exit)
*
* This function is called just before a program exists. If there are any OS
* specific processing, e.g., freeing resourced allocated in os_program_init(),
* it should be done here. It is also acceptable for this function to do
* nothing.
*/
void os_program_deinit(void);
/**
* os_setenv - Set environment variable
* @name: Name of the variable
* @value: Value to set to the variable
* @overwrite: Whether existing variable should be overwritten
* Returns: 0 on success, -1 on error
*
* This function is only used for wpa_cli action scripts. OS wrapper does not
* need to implement this if such functionality is not needed.
*/
int os_setenv(const char *name, const char *value, int overwrite);
/**
* os_unsetenv - Delete environent variable
* @name: Name of the variable
* Returns: 0 on success, -1 on error
*
* This function is only used for wpa_cli action scripts. OS wrapper does not
* need to implement this if such functionality is not needed.
*/
int os_unsetenv(const char *name);
/**
* os_readfile - Read a file to an allocated memory buffer
* @name: Name of the file to read
* @len: For returning the length of the allocated buffer
* Returns: Pointer to the allocated buffer or %NULL on failure
*
* This function allocates memory and reads the given file to this buffer. Both
* binary and text files can be read with this function. The caller is
* responsible for freeing the returned buffer with os_free().
*/
char * os_readfile(const char *name, size_t *len);
//#if 0
/**
* os_zalloc - Allocate and zero memory
* @size: Number of bytes to allocate
* Returns: Pointer to allocated and zeroed memory or %NULL on failure
*
* Caller is responsible for freeing the returned buffer with os_free().
*/
void * os_zalloc(size_t size);
/**
* os_calloc - Allocate and zero memory for an array
* @nmemb: Number of members in the array
* @size: Number of bytes in each member
* Returns: Pointer to allocated and zeroed memory or %NULL on failure
*
* This function can be used as a wrapper for os_zalloc(nmemb * size) when an
* allocation is used for an array. The main benefit over os_zalloc() is in
* having an extra check to catch integer overflows in multiplication.
*
* Caller is responsible for freeing the returned buffer with os_free().
*/
static inline void * os_calloc(size_t nmemb, size_t size)
{
if (size && nmemb > (~(size_t) 0) / size)
return NULL;
return os_zalloc(nmemb * size);
}
//#endif
static inline int os_memcmp_const(const void *a, const void *b, size_t len)
{
const u8 *aa = a;
const u8 *bb = b;
size_t i;
u8 res;
for (res = 0, i = 0; i < len; i++)
res |= aa[i] ^ bb[i];
return res;
}
/*
* The following functions are wrapper for standard ANSI C or POSIX functions.
* By default, they are just defined to use the standard function name and no
* os_*.c implementation is needed for them. This avoids extra function calls
* by allowing the C pre-processor take care of the function name mapping.
*
* If the target system uses a C library that does not provide these functions,
* build_config.h can be used to define the wrappers to use a different
* function name. This can be done on function-by-function basis since the
* defines here are only used if build_config.h does not define the os_* name.
* If needed, os_*.c file can be used to implement the functions that are not
* included in the C library on the target system. Alternatively,
* OS_NO_C_LIB_DEFINES can be defined to skip all defines here in which case
* these functions need to be implemented in os_*.c file for the target system.
*/
#ifdef OS_NO_C_LIB_DEFINES
/**
* os_malloc - Allocate dynamic memory
* @size: Size of the buffer to allocate
* Returns: Allocated buffer or %NULL on failure
*
* Caller is responsible for freeing the returned buffer with os_free().
*/
void * os_malloc(size_t size);
/**
* os_realloc - Re-allocate dynamic memory
* @ptr: Old buffer from os_malloc() or os_realloc()
* @size: Size of the new buffer
* Returns: Allocated buffer or %NULL on failure
*
* Caller is responsible for freeing the returned buffer with os_free().
* If re-allocation fails, %NULL is returned and the original buffer (ptr) is
* not freed and caller is still responsible for freeing it.
*/
void * os_realloc(void *ptr, size_t size);
/**
* os_free - Free dynamic memory
* @ptr: Old buffer from os_malloc() or os_realloc(); can be %NULL
*/
void os_free(void *ptr);
/**
* os_memcpy - Copy memory area
* @dest: Destination
* @src: Source
* @n: Number of bytes to copy
* Returns: dest
*
* The memory areas src and dst must not overlap. os_memmove() can be used with
* overlapping memory.
*/
void * os_memcpy(void *dest, const void *src, size_t n);
/**
* os_memmove - Copy memory area
* @dest: Destination
* @src: Source
* @n: Number of bytes to copy
* Returns: dest
*
* The memory areas src and dst may overlap.
*/
void *os_memmove(void *dest, const void *src, size_t n);
/**
* os_memset - Fill memory with a constant byte
* @s: Memory area to be filled
* @c: Constant byte
* @n: Number of bytes started from s to fill with c
* Returns: s
*/
void *os_memset(void *s, int c, size_t n);
/**
* os_memcmp - Compare memory areas
* @s1: First buffer
* @s2: Second buffer
* @n: Maximum numbers of octets to compare
* Returns: An integer less than, equal to, or greater than zero if s1 is
* found to be less than, to match, or be greater than s2. Only first n
* characters will be compared.
*/
int os_memcmp(const void *s1, const void *s2, size_t n);
/**
* os_strdup - Duplicate a string
* @s: Source string
* Returns: Allocated buffer with the string copied into it or %NULL on failure
*
* Caller is responsible for freeing the returned buffer with os_free().
*/
char *os_strdup(const char *s);
/**
* os_strlen - Calculate the length of a string
* @s: '\0' terminated string
* Returns: Number of characters in s (not counting the '\0' terminator)
*/
size_t os_strlen(const char *s);
/**
* os_strcasecmp - Compare two strings ignoring case
* @s1: First string
* @s2: Second string
* Returns: An integer less than, equal to, or greater than zero if s1 is
* found to be less than, to match, or be greatred than s2
*/
int os_strcasecmp(const char *s1, const char *s2);
/**
* os_strncasecmp - Compare two strings ignoring case
* @s1: First string
* @s2: Second string
* @n: Maximum numbers of characters to compare
* Returns: An integer less than, equal to, or greater than zero if s1 is
* found to be less than, to match, or be greater than s2. Only first n
* characters will be compared.
*/
int os_strncasecmp(const char *s1, const char *s2, size_t n);
/**
* os_strchr - Locate the first occurrence of a character in string
* @s: String
* @c: Character to search for
* Returns: Pointer to the matched character or %NULL if not found
*/
char *os_strchr(const char *s, int c);
/**
* os_strrchr - Locate the last occurrence of a character in string
* @s: String
* @c: Character to search for
* Returns: Pointer to the matched character or %NULL if not found
*/
char *os_strrchr(const char *s, int c);
/**
* os_strcmp - Compare two strings
* @s1: First string
* @s2: Second string
* Returns: An integer less than, equal to, or greater than zero if s1 is
* found to be less than, to match, or be greatred than s2
*/
int os_strcmp(const char *s1, const char *s2);
/**
* os_strncmp - Compare two strings
* @s1: First string
* @s2: Second string
* @n: Maximum numbers of characters to compare
* Returns: An integer less than, equal to, or greater than zero if s1 is
* found to be less than, to match, or be greater than s2. Only first n
* characters will be compared.
*/
int os_strncmp(const char *s1, const char *s2, size_t n);
/**
* os_strncpy - Copy a string
* @dest: Destination
* @src: Source
* @n: Maximum number of characters to copy
* Returns: dest
*/
char *os_strncpy(char *dest, const char *src, size_t n);
/**
* os_strstr - Locate a substring
* @haystack: String (haystack) to search from
* @needle: Needle to search from haystack
* Returns: Pointer to the beginning of the substring or %NULL if not found
*/
char *os_strstr(const char *haystack, const char *needle);
/**
* os_snprintf - Print to a memory buffer
* @str: Memory buffer to print into
* @size: Maximum length of the str buffer
* @format: printf format
* Returns: Number of characters printed (not including trailing '\0').
*
* If the output buffer is truncated, number of characters which would have
* been written is returned. Since some C libraries return -1 in such a case,
* the caller must be prepared on that value, too, to indicate truncation.
*
* Note: Some C library implementations of snprintf() may not guarantee null
* termination in case the output is truncated. The OS wrapper function of
* os_snprintf() should provide this guarantee, i.e., to null terminate the
* output buffer if a C library version of the function is used and if that
* function does not guarantee null termination.
*
* If the target system does not include snprintf(), see, e.g.,
* http://www.ijs.si/software/snprintf/ for an example of a portable
* implementation of snprintf.
*/
int os_snprintf(char *str, size_t size, const char *format, ...);
#else /* OS_NO_C_LIB_DEFINES */
#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B)
#ifdef CONFIG_MEM_MONITOR
u8* os_malloc(u32 sz);
void os_mfree(u8 *pbuf, u32 sz);
#ifndef os_free
#define os_free(p, sz) os_mfree(((u8*)(p)), (sz))
#endif
#else
#ifndef os_malloc
#define os_malloc(sz) _rtw_malloc(sz)
#endif
#ifndef os_free
#define os_free(p, sz) _rtw_mfree(((u8*)(p)), (sz))
#endif
#endif
#endif
extern void *os_zalloc(size_t size);
extern char *os_strdup(const char *string_copy_from);
#ifndef os_sleep
#define os_sleep(s, us) rtw_mdelay_os((s)*1000 + (us)/1000)
#endif
#ifndef os_memcpy
#define os_memcpy(d, s, n) rtw_memcpy((void*)(d), ((void*)(s)), (n))
#endif
#ifndef os_memmove
#define os_memmove(d, s, n) memmove((d), (s), (n))
#endif
#ifndef os_memset
#define os_memset(pbuf, c, sz) rtw_memset(pbuf, c, sz)
#endif
#ifndef os_memcmp
#define os_memcmp(s1, s2, n) rtw_memcmp(((void*)(s1)), ((void*)(s2)), (n))
#endif
#ifndef os_memcmp_p2p
#define os_memcmp_p2p(s1, s2, n) memcmp((s1), (s2), (n))
#endif
#ifndef os_get_random_bytes
#define os_get_random_bytes(d,sz) rtw_get_random_bytes(((void*)(d)), (sz))
#endif
#ifndef os_strlen
#define os_strlen(s) strlen(s)
#endif
#ifndef os_strcasecmp
#ifdef _MSC_VER
#define os_strcasecmp(s1, s2) _stricmp((s1), (s2))
#else
#define os_strcasecmp(s1, s2) strcasecmp((s1), (s2))
#endif
#endif
#ifndef os_strncasecmp
#ifdef _MSC_VER
#define os_strncasecmp(s1, s2, n) _strnicmp((s1), (s2), (n))
#else
#define os_strncasecmp(s1, s2, n) strncasecmp((s1), (s2), (n))
#endif
#endif
#ifndef os_init_timer
#define os_init_timer(t, p, f, x, n) rtw_init_timer((t), (p), (f), (x), (n))
#endif
#ifndef os_set_timer
#define os_set_timer(t, d) rtw_set_timer((t), (d))
#endif
#ifndef os_cancel_timer
#define os_cancel_timer(t) rtw_cancel_timer(t)
#endif
#ifndef os_del_timer
#define os_del_timer(t) rtw_del_timer(t)
#endif
#ifndef os_atoi
#define os_atoi(s) rtw_atoi(s)
#endif
#ifndef os_strchr
#define os_strchr(s, c) strchr((s), (c))
#endif
#ifndef os_strcmp
#define os_strcmp(s1, s2) strcmp((s1), (s2))
#endif
#ifndef os_strncmp
#define os_strncmp(s1, s2, n) strncmp((s1), (s2), (n))
#endif
#ifndef os_strncpy
#define os_strncpy(d, s, n) strncpy((d), (s), (n))
#endif
#ifndef os_strrchr
#define os_strrchr(s, c) strrchr((s), (c))
#endif
#ifndef os_strstr
#define os_strstr(h, n) strstr((h), (n))
#endif
#ifndef os_snprintf
#ifdef _MSC_VER
#define os_snprintf _snprintf
#else
#define os_snprintf snprintf
#endif
#endif
#endif /* OS_NO_C_LIB_DEFINES */
static inline void * os_realloc_array(void *ptr, size_t nmemb, size_t size)
{
if (size && nmemb > (~(size_t) 0) / size)
return NULL;
return os_realloc(ptr, nmemb * size, nmemb * size);
}
void *os_xqueue_create(unsigned long uxQueueLength, unsigned long uxItemSize) ;
int os_xqueue_receive(xqueue_handle_t xQueue, void * const pvBuffer, unsigned long xSecsToWait);
void os_xqueue_delete(xqueue_handle_t xQueue );
int os_xqueue_send(xqueue_handle_t xQueue, const void * const pvItemToQueue, unsigned long xSecsToWait);
#endif /* OS_H */

View file

@ -0,0 +1,119 @@
/*
* OS specific functions for UNIX/POSIX systems
* Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "utils/os.h"
//#ifdef CONFIG_WPS
#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B)
#ifdef CONFIG_MEM_MONITOR
#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK
_list wpa_mem_table;
int wpa_mem_used_num;
//int wpa_mem_used_size;
#endif
extern int min_free_heap_size;
u8* os_malloc(u32 sz)
{
int free_heap_size = rtw_getFreeHeapSize();
u8 *pbuf = _rtw_malloc(sz);
#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK
add_mem_usage(&wpa_mem_table, pbuf, sz, &wpa_mem_used_num, MEM_MONITOR_FLAG_WPAS);
#else
add_mem_usage(NULL, pbuf, sz, NULL, MEM_MONITOR_FLAG_WPAS);
#endif
if(min_free_heap_size > free_heap_size)
min_free_heap_size = free_heap_size;
return pbuf;
}
void os_mfree(u8 *pbuf, u32 sz)
{
_rtw_mfree(pbuf, sz);
#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK
del_mem_usage(&wpa_mem_table, pbuf, &wpa_mem_used_num, MEM_MONITOR_FLAG_WPAS);
#else
del_mem_usage(NULL, pbuf, NULL, MEM_MONITOR_FLAG_WPAS);
#endif
}
#endif//CONFIG_MEM_MONITOR
#endif// !defined(CONFIG_PLATFORM_8195A)
#ifndef OS_NO_C_LIB_DEFINES
char *os_strdup(const char *string_copy_from)
{
char *string_copy_to = NULL;
string_copy_to = os_zalloc(strlen(string_copy_from) + 1);
os_memcpy((void *)string_copy_to, string_copy_from, strlen(string_copy_from));
string_copy_to[strlen(string_copy_from)] = '\0';
return string_copy_to;
}
#endif
int os_get_random(unsigned char *buf, size_t len)
{
//TODO implement it
rtw_get_random_bytes(buf, len);
return 0;
}
int os_get_time(struct os_time *t){
unsigned int tt = rtw_get_current_time();
t->sec = (os_time_t) (tt / 1000);
t->usec = (os_time_t) (tt % 1000)*1000;
return 0;
}
int os_get_reltime(struct os_reltime *t){
os_get_time((struct os_time *)t);
return 0;
}
#if 0
void *os_xqueue_create(unsigned long uxQueueLength, unsigned long uxItemSize)
{
return xQueueCreate( uxQueueLength, uxItemSize );
}
int os_xqueue_receive(xqueue_handle_t xQueue, void * const pvBuffer, unsigned long xSecsToWait)
{
return xQueueReceive((xQueueHandle)xQueue, pvBuffer, (portTickType)(xSecsToWait*configTICK_RATE_HZ));
}
void os_xqueue_delete(xqueue_handle_t xQueue )
{
vQueueDelete((xQueueHandle)xQueue);
}
int os_xqueue_send(xqueue_handle_t xQueue, const void * const pvItemToQueue, unsigned long xSecsToWait)
{
return xQueueSendToBack((xQueueHandle)xQueue, pvItemToQueue, (portTickType)(xSecsToWait*configTICK_RATE_HZ));
}
#else
void *os_xqueue_create(unsigned long uxQueueLength, unsigned long uxItemSize)
{
void* xQueue = NULL;
rtw_init_xqueue(&xQueue, "queue", uxItemSize, uxQueueLength);
return xQueue;
}
int os_xqueue_receive(xqueue_handle_t xQueue, void * const pvBuffer, unsigned long xSecsToWait)
{
return rtw_pop_from_xqueue(&xQueue, pvBuffer, xSecsToWait*1000);
}
void os_xqueue_delete(xqueue_handle_t xQueue )
{
rtw_deinit_xqueue(&xQueue);
}
int os_xqueue_send(xqueue_handle_t xQueue, const void * const pvItemToQueue, unsigned long xSecsToWait)
{
return rtw_push_to_xqueue(&xQueue, (void*)pvItemToQueue, xSecsToWait*1000);
}
#endif
//#endif

View file

@ -0,0 +1,24 @@
/*
* OS specific functions
* Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef ROM_WPS_OS_H
#define ROM_WPS_OS_H
#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B)
#include <rom_wlan_ram_map.h>
extern struct _rom_wlan_ram_map rom_wlan_ram_map;
#define os_malloc(sz) rom_wlan_ram_map.rtw_malloc(sz)
#define os_free(p, sz) rom_wlan_ram_map.rtw_mfree(((u8*)(p)), (sz))
#endif
extern u8 *WPS_realloc(u8 *old_buf, u32 old_sz, u32 new_sz);
#define os_realloc(p, os, ns) WPS_realloc(((u8*)(p)),(os),(ns))
#endif /* ROM_WPS_OS_H */

View file

@ -0,0 +1,31 @@
/*
* Universally Unique IDentifier (UUID)
* Copyright (c) 2008, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef UUID_H
#define UUID_H
#include <platform/platform_stdlib.h>
#define UUID_LEN 16
int uuid_str2bin(const char *str, u8 *bin);
static int uuid_bin2str(const u8 *bin, char *str, size_t max_len)
{
int len;
len = os_snprintf(str, max_len, "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
"%02x%02x-%02x%02x%02x%02x%02x%02x",
bin[0], bin[1], bin[2], bin[3],
bin[4], bin[5], bin[6], bin[7],
bin[8], bin[9], bin[10], bin[11],
bin[12], bin[13], bin[14], bin[15]);
if (len < 0 || (size_t) len >= max_len)
return -1;
return 0;
}
int is_nil_uuid(const u8 *uuid);
#endif /* UUID_H */

View file

@ -0,0 +1,79 @@
/*
* wpa_supplicant/hostapd / Debug prints
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef WPA_DEBUG_H
#define WPA_DEBUG_H
#include "utils/wpabuf.h"
/* Debugging function - conditional printf and hex dump. Driver wrappers can
* use these for debugging purposes. */
enum {
MSG_EXCESSIVE, MSG_MSGDUMP, MSG_DEBUG, MSG_INFO, MSG_ALWAYS, MSG_WARNING, MSG_ERROR
};
#define wpa_debug_print_timestamp() do { } while (0)
#define wpa_hexdump(l,t,b,le) do { } while (0)
#define wpa_hexdump_buf_key(l,t,b) do { } while (0)
#define wpa_hexdump_ascii_key(l,t,b,le) do { } while (0)
#define wpa_debug_open_file(p) do { } while (0)
#define wpa_debug_close_file() do { } while (0)
#define wpa_dbg(args...) do { } while (0)
#define wpa_msg_ctrl(args...) do { } while (0)
#define wpa_msg_register_cb(f) do { } while (0)
#define wpa_msg_register_ifname_cb(f) do { } while (0)
static inline int wpa_debug_reopen_file(void)
{
return 0;
}
#define wprintf(fmt, arg...) printf("[%d] "fmt, rtw_get_current_time(),##arg)
#ifdef CONFIG_NO_STDOUT_DEBUG
#define wpa_printf(args...) do { } while (0)
#define wpa_hexdump_buf(l,t,b) do { } while (0)
#define wpa_hexdump_key(l,t,b,le) do { } while (0)
#define wpa_hexdump_ascii(l,t,b,le) do { } while (0)
#define wpa_msg(args...) do { } while (0)
#else
//void wpa_printf(int level, const char *fmt, ...);
#define wpa_printf(level, fmt, arg...) \
do {\
if (level >= MSG_INFO) {\
{\
printf("\r\n%d:", rtw_get_current_time());\
printf(fmt, ##arg);\
printf("\n\r");\
} \
}\
}while(0)
#define wpa_msg(ctx,level,fmt,arg...) wpa_printf((level),(fmt), ##arg)
void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len);
void wpa_hexdump_buf(int level, const char *title,
const struct wpabuf *buf);
void wpa_hexdump_ascii(int level, const char *title, const void *buf,
size_t len);
#ifdef EAPOL_TEST
#define WPA_ASSERT(a) \
do { \
if (!(a)) { \
printf("WPA_ASSERT FAILED '" #a "' " \
"%s %s:%d\n", \
__FUNCTION__, __FILE__, __LINE__); \
exit(1); \
} \
} while (0)
#else
#define WPA_ASSERT(a) do { } while (0)
#endif
#endif //CONFIG_NO_STDOUT_DEBUG
#endif /* WPA_DEBUG_H */

View file

@ -0,0 +1,188 @@
/*
* Dynamic data buffer
* Copyright (c) 2007-2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef WPABUF_H
#define WPABUF_H
/* wpabuf::buf is a pointer to external data */
#define WPABUF_FLAG_EXT_DATA BIT(0)
/*
* Internal data structure for wpabuf. Please do not touch this directly from
* elsewhere. This is only defined in header file to allow inline functions
* from this file to access data.
*/
struct wpabuf {
size_t size; /* total size of the allocated buffer (i.e allocated buffer size)*/
size_t used; /* length of data in the buffer (i.e data length) */
u8 *buf; /* pointer to the head of the buffer (i.e buffer address) */
unsigned int flags;
/* optionally followed by the allocated buffer */
};
int wpabuf_resize(struct wpabuf **buf, size_t add_len);
struct wpabuf * wpabuf_alloc(size_t len);
struct wpabuf * wpabuf_alloc_ext_data(u8 *data, size_t len);
struct wpabuf * wpabuf_alloc_copy(const void *data, size_t len);
struct wpabuf * wpabuf_dup(const struct wpabuf *src);
void wpabuf_free(struct wpabuf *buf);
void * wpabuf_put(struct wpabuf *buf, size_t len);
struct wpabuf * wpabuf_concat(struct wpabuf *a, struct wpabuf *b);
struct wpabuf * wpabuf_zeropad(struct wpabuf *buf, size_t len);
void wpabuf_printf(struct wpabuf *buf, char *fmt, ...) PRINTF_FORMAT(2, 3);
/**
* wpabuf_size - Get the currently allocated size of a wpabuf buffer
* @buf: wpabuf buffer
* Returns: Currently allocated size of the buffer
*/
static inline size_t wpabuf_size(const struct wpabuf *buf)
{
return buf->size;
}
/**
* wpabuf_len - Get the current length of a wpabuf buffer data
* @buf: wpabuf buffer
* Returns: Currently used length of the buffer
*/
static inline size_t wpabuf_len(const struct wpabuf *buf)
{
return buf->used;
}
/**
* wpabuf_tailroom - Get size of available tail room in the end of the buffer
* @buf: wpabuf buffer
* Returns: Tail room (in bytes) of available space in the end of the buffer
*/
static inline size_t wpabuf_tailroom(const struct wpabuf *buf)
{
return buf->size - buf->used;
}
/**
* wpabuf_head - Get pointer to the head of the buffer data
* @buf: wpabuf buffer
* Returns: Pointer to the head of the buffer data
*/
static inline const void *wpabuf_head(const struct wpabuf *buf)
{
return buf->buf;
}
static inline const u8 *wpabuf_head_u8(const struct wpabuf *buf)
{
return wpabuf_head(buf);
}
/**
* wpabuf_mhead - Get modifiable pointer to the head of the buffer data
* @buf: wpabuf buffer
* Returns: Pointer to the head of the buffer data
*/
static inline void *wpabuf_mhead(struct wpabuf *buf)
{
return buf->buf;
}
static inline u8 *wpabuf_mhead_u8(struct wpabuf *buf)
{
return wpabuf_mhead(buf);
}
static inline void wpabuf_put_u8(struct wpabuf *buf, u8 data)
{
u8 *pos = NULL;
if ( buf == NULL)
return;
pos = wpabuf_put(buf, 1);
*pos = data;
}
static inline void wpabuf_put_le16(struct wpabuf *buf, u16 data)
{
u8 *pos = NULL;
if ( buf == NULL)
return;
pos = wpabuf_put(buf, 2);
WPA_PUT_LE16(pos, data);
}
static inline void wpabuf_put_le32(struct wpabuf *buf, u32 data)
{
u8 *pos = NULL;
if ( buf == NULL)
return;
pos = wpabuf_put(buf, 4);
WPA_PUT_LE32(pos, data);
}
static inline void wpabuf_put_be16(struct wpabuf *buf, u16 data)
{
u8 *pos = NULL;
if ( buf == NULL)
return;
pos = wpabuf_put(buf, 2);
WPA_PUT_BE16(pos, data);
}
static inline void wpabuf_put_be24(struct wpabuf *buf, u32 data)
{
u8 *pos = NULL;
if ( buf == NULL)
return;
pos = wpabuf_put(buf, 3);
WPA_PUT_BE24(pos, data);
}
static inline void wpabuf_put_be32(struct wpabuf *buf, u32 data)
{
u8 *pos = NULL;
if ( buf == NULL)
return;
pos = wpabuf_put(buf, 4);
WPA_PUT_BE32(pos, data);
}
// encr >> 16 B 64 - 16 = 48
static inline void wpabuf_put_data(struct wpabuf *buf, const void *data, size_t len)
{
if ( buf == NULL)
return;
if (data)
os_memcpy(wpabuf_put(buf, len), data, len);
}
static inline void wpabuf_put_buf(struct wpabuf *dst,
const struct wpabuf *src)
{
if ( dst == NULL)
return;
wpabuf_put_data(dst, wpabuf_head(src), wpabuf_len(src));
}
static inline void wpabuf_set(struct wpabuf *buf, const void *data, size_t len)
{
if ( buf == NULL)
return;
buf->buf = (u8 *) data;
buf->flags = WPABUF_FLAG_EXT_DATA;
buf->size = buf->used = len;
}
static inline void wpabuf_put_str(struct wpabuf *dst, const char *str)
{
if ( dst == NULL)
return;
wpabuf_put_data(dst, str, os_strlen(str));
}
#endif /* WPABUF_H */

View file

@ -0,0 +1,324 @@
/*
* Wi-Fi Protected Setup - message definitions
* Copyright (c) 2008, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef WPS_DEFS_H
#define WPS_DEFS_H
#ifdef CONFIG_WPS2
#define WPS_VERSION 0x20
#else /* CONFIG_WPS2 */
#define WPS_VERSION 0x10
#endif /* CONFIG_WPS2 */
/* Diffie-Hellman 1536-bit MODP Group; RFC 3526, Group 5 */
#define WPS_DH_GROUP (5)
#define WPS_UUID_LEN (16)
#define WPS_NONCE_LEN (16)
#define WPS_AUTHENTICATOR_LEN (8)
#define WPS_AUTHKEY_LEN (32)
#define WPS_KEYWRAPKEY_LEN (16)
#define WPS_EMSK_LEN (32)
#define WPS_PSK_LEN (16)
#define WPS_SECRET_NONCE_LEN (16)
#define WPS_HASH_LEN (32)
#define WPS_KWA_LEN (8)
#define WPS_MGMTAUTHKEY_LEN (32)
#define WPS_MGMTENCKEY_LEN (16)
#define WPS_MGMT_KEY_ID_LEN (16)
#define WPS_OOB_DEVICE_PASSWORD_MIN_LEN (16)
#define WPS_OOB_DEVICE_PASSWORD_LEN (32)
#define WPS_OOB_PUBKEY_HASH_LEN (20)
/* Attribute Types */
enum wps_attribute {
ATTR_AP_CHANNEL = 0x1001,
ATTR_ASSOC_STATE = 0x1002,
ATTR_AUTH_TYPE = 0x1003,
ATTR_AUTH_TYPE_FLAGS = 0x1004,
ATTR_AUTHENTICATOR = 0x1005,
ATTR_CONFIG_METHODS = 0x1008,
ATTR_CONFIG_ERROR = 0x1009,
ATTR_CONFIRM_URL4 = 0x100a,
ATTR_CONFIRM_URL6 = 0x100b,
ATTR_CONN_TYPE = 0x100c,
ATTR_CONN_TYPE_FLAGS = 0x100d,
ATTR_CRED = 0x100e,
ATTR_ENCR_TYPE = 0x100f,
ATTR_ENCR_TYPE_FLAGS = 0x1010,
ATTR_DEV_NAME = 0x1011,
ATTR_DEV_PASSWORD_ID = 0x1012,
ATTR_E_HASH1 = 0x1014,
ATTR_E_HASH2 = 0x1015,
ATTR_E_SNONCE1 = 0x1016,
ATTR_E_SNONCE2 = 0x1017,
ATTR_ENCR_SETTINGS = 0x1018,
ATTR_ENROLLEE_NONCE = 0x101a,
ATTR_FEATURE_ID = 0x101b,
ATTR_IDENTITY = 0x101c,
ATTR_IDENTITY_PROOF = 0x101d,
ATTR_KEY_WRAP_AUTH = 0x101e,
ATTR_KEY_ID = 0x101f,
ATTR_MAC_ADDR = 0x1020,
ATTR_MANUFACTURER = 0x1021,
ATTR_MSG_TYPE = 0x1022,
ATTR_MODEL_NAME = 0x1023,
ATTR_MODEL_NUMBER = 0x1024,
ATTR_NETWORK_INDEX = 0x1026,
ATTR_NETWORK_KEY = 0x1027,
ATTR_NETWORK_KEY_INDEX = 0x1028,
ATTR_NEW_DEVICE_NAME = 0x1029,
ATTR_NEW_PASSWORD = 0x102a,
ATTR_OOB_DEVICE_PASSWORD = 0x102c,
ATTR_OS_VERSION = 0x102d,
ATTR_POWER_LEVEL = 0x102f,
ATTR_PSK_CURRENT = 0x1030,
ATTR_PSK_MAX = 0x1031,
ATTR_PUBLIC_KEY = 0x1032,
ATTR_RADIO_ENABLE = 0x1033,
ATTR_REBOOT = 0x1034,
ATTR_REGISTRAR_CURRENT = 0x1035,
ATTR_REGISTRAR_ESTABLISHED = 0x1036,
ATTR_REGISTRAR_LIST = 0x1037,
ATTR_REGISTRAR_MAX = 0x1038,
ATTR_REGISTRAR_NONCE = 0x1039,
ATTR_REQUEST_TYPE = 0x103a,
ATTR_RESPONSE_TYPE = 0x103b,
ATTR_RF_BANDS = 0x103c,
ATTR_R_HASH1 = 0x103d,
ATTR_R_HASH2 = 0x103e,
ATTR_R_SNONCE1 = 0x103f,
ATTR_R_SNONCE2 = 0x1040,
ATTR_SELECTED_REGISTRAR = 0x1041,
ATTR_SERIAL_NUMBER = 0x1042,
ATTR_WPS_STATE = 0x1044,
ATTR_SSID = 0x1045,
ATTR_TOTAL_NETWORKS = 0x1046,
ATTR_UUID_E = 0x1047,
ATTR_UUID_R = 0x1048,
ATTR_VENDOR_EXT = 0x1049,
ATTR_VERSION = 0x104a,
ATTR_X509_CERT_REQ = 0x104b,
ATTR_X509_CERT = 0x104c,
ATTR_EAP_IDENTITY = 0x104d,
ATTR_MSG_COUNTER = 0x104e,
ATTR_PUBKEY_HASH = 0x104f,
ATTR_REKEY_KEY = 0x1050,
ATTR_KEY_LIFETIME = 0x1051,
ATTR_PERMITTED_CFG_METHODS = 0x1052,
ATTR_SELECTED_REGISTRAR_CONFIG_METHODS = 0x1053,
ATTR_PRIMARY_DEV_TYPE = 0x1054,
ATTR_SECONDARY_DEV_TYPE_LIST = 0x1055,
ATTR_PORTABLE_DEV = 0x1056,
ATTR_AP_SETUP_LOCKED = 0x1057,
ATTR_APPLICATION_EXT = 0x1058,
ATTR_EAP_TYPE = 0x1059,
ATTR_IV = 0x1060,
ATTR_KEY_PROVIDED_AUTO = 0x1061,
ATTR_802_1X_ENABLED = 0x1062,
ATTR_APPSESSIONKEY = 0x1063,
ATTR_WEPTRANSMITKEY = 0x1064,
ATTR_REQUESTED_DEV_TYPE = 0x106a,
ATTR_EXTENSIBILITY_TEST = 0x10fa /* _NOT_ defined in the spec */
};
#define WPS_VENDOR_ID_WFA 14122
/* WFA Vendor Extension subelements */
enum {
WFA_ELEM_VERSION2 = 0x00,
WFA_ELEM_AUTHORIZEDMACS = 0x01,
WFA_ELEM_NETWORK_KEY_SHAREABLE = 0x02,
WFA_ELEM_REQUEST_TO_ENROLL = 0x03,
WFA_ELEM_SETTINGS_DELAY_TIME = 0x04
};
/* Device Password ID */
enum wps_dev_password_id {
DEV_PW_DEFAULT = 0x0000,
DEV_PW_USER_SPECIFIED = 0x0001,
DEV_PW_MACHINE_SPECIFIED = 0x0002,
DEV_PW_REKEY = 0x0003,
DEV_PW_PUSHBUTTON = 0x0004,
DEV_PW_REGISTRAR_SPECIFIED = 0x0005
};
/* Message Type */
enum wps_msg_type {
WPS_START = 0x00,
WPS_Beacon = 0x01,
WPS_ProbeRequest = 0x02,
WPS_ProbeResponse = 0x03,
WPS_M1 = 0x04,
WPS_M2 = 0x05,
WPS_M2D = 0x06,
WPS_M3 = 0x07,
WPS_M4 = 0x08,
WPS_M5 = 0x09,
WPS_M6 = 0x0a,
WPS_M7 = 0x0b,
WPS_M8 = 0x0c,
WPS_WSC_ACK = 0x0d,
WPS_WSC_NACK = 0x0e,
WPS_WSC_DONE = 0x0f
};
/* Authentication Type Flags */
#define WPS_AUTH_OPEN 0x0001
#define WPS_AUTH_WPAPSK 0x0002
#define WPS_AUTH_SHARED 0x0004
#define WPS_AUTH_WPA 0x0008
#define WPS_AUTH_WPA2 0x0010
#define WPS_AUTH_WPA2PSK 0x0020
#define WPS_AUTH_TYPES (WPS_AUTH_OPEN | WPS_AUTH_WPAPSK | WPS_AUTH_SHARED | \
WPS_AUTH_WPA | WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK)
/* Encryption Type Flags */
#define WPS_ENCR_NONE 0x0001
#define WPS_ENCR_WEP 0x0002
#define WPS_ENCR_TKIP 0x0004
#define WPS_ENCR_AES 0x0008
#define WPS_ENCR_TYPES (WPS_ENCR_NONE | WPS_ENCR_WEP | WPS_ENCR_TKIP | \
WPS_ENCR_AES)
/* Configuration Error */
enum wps_config_error {
WPS_CFG_NO_ERROR = 0,
WPS_CFG_OOB_IFACE_READ_ERROR = 1,
WPS_CFG_DECRYPTION_CRC_FAILURE = 2,
WPS_CFG_24_CHAN_NOT_SUPPORTED = 3,
WPS_CFG_50_CHAN_NOT_SUPPORTED = 4,
WPS_CFG_SIGNAL_TOO_WEAK = 5,
WPS_CFG_NETWORK_AUTH_FAILURE = 6,
WPS_CFG_NETWORK_ASSOC_FAILURE = 7,
WPS_CFG_NO_DHCP_RESPONSE = 8,
WPS_CFG_FAILED_DHCP_CONFIG = 9,
WPS_CFG_IP_ADDR_CONFLICT = 10,
WPS_CFG_NO_CONN_TO_REGISTRAR = 11,
WPS_CFG_MULTIPLE_PBC_DETECTED = 12,
WPS_CFG_ROGUE_SUSPECTED = 13,
WPS_CFG_DEVICE_BUSY = 14,
WPS_CFG_SETUP_LOCKED = 15,
WPS_CFG_MSG_TIMEOUT = 16,
WPS_CFG_REG_SESS_TIMEOUT = 17,
WPS_CFG_DEV_PASSWORD_AUTH_FAILURE = 18
};
/* RF Bands */
#define WPS_RF_24GHZ (0x01)
#define WPS_RF_50GHZ (0x02)
/* Config Methods */
#define WPS_CONFIG_USBA (0x0001)
#define WPS_CONFIG_ETHERNET (0x0002)
#define WPS_CONFIG_LABEL (0x0004)
#define WPS_CONFIG_DISPLAY (0x0008)
#define WPS_CONFIG_EXT_NFC_TOKEN (0x0010)
#define WPS_CONFIG_INT_NFC_TOKEN (0x0020)
#define WPS_CONFIG_NFC_INTERFACE (0x0040)
#define WPS_CONFIG_PUSHBUTTON (0x0080)
#define WPS_CONFIG_KEYPAD (0x0100)
#ifdef CONFIG_WPS2
#define WPS_CONFIG_VIRT_PUSHBUTTON (0x0280)
#define WPS_CONFIG_PHY_PUSHBUTTON (0x0480)
#define WPS_CONFIG_VIRT_DISPLAY (0x2008)
#define WPS_CONFIG_PHY_DISPLAY (0x4008)
#endif /* CONFIG_WPS2 */
/* Connection Type Flags */
#define WPS_CONN_ESS (0x01)
#define WPS_CONN_IBSS (0x02)
/* Wi-Fi Protected Setup State */
enum wps_state {
WPS_STATE_NOT_CONFIGURED = 1,
WPS_STATE_CONFIGURED = 2
};
/* Association State */
enum wps_assoc_state {
WPS_ASSOC_NOT_ASSOC = 0,
WPS_ASSOC_CONN_SUCCESS = 1,
WPS_ASSOC_CFG_FAILURE = 2,
WPS_ASSOC_FAILURE = 3,
WPS_ASSOC_IP_FAILURE = 4
};
#define WPS_DEV_OUI_WFA (0x0050f204)
enum wps_dev_categ {
WPS_DEV_COMPUTER = 1,
WPS_DEV_INPUT = 2,
WPS_DEV_PRINTER = 3,
WPS_DEV_CAMERA = 4,
WPS_DEV_STORAGE = 5,
WPS_DEV_NETWORK_INFRA = 6,
WPS_DEV_DISPLAY = 7,
WPS_DEV_MULTIMEDIA = 8,
WPS_DEV_GAMING = 9,
WPS_DEV_PHONE = 10
};
enum wps_dev_subcateg {
WPS_DEV_COMPUTER_PC = 1,
WPS_DEV_COMPUTER_SERVER = 2,
WPS_DEV_COMPUTER_MEDIA_CENTER = 3,
WPS_DEV_PRINTER_PRINTER = 1,
WPS_DEV_PRINTER_SCANNER = 2,
WPS_DEV_CAMERA_DIGITAL_STILL_CAMERA = 1,
WPS_DEV_STORAGE_NAS = 1,
WPS_DEV_NETWORK_INFRA_AP = 1,
WPS_DEV_NETWORK_INFRA_ROUTER = 2,
WPS_DEV_NETWORK_INFRA_SWITCH = 3,
WPS_DEV_DISPLAY_TV = 1,
WPS_DEV_DISPLAY_PICTURE_FRAME = 2,
WPS_DEV_DISPLAY_PROJECTOR = 3,
WPS_DEV_MULTIMEDIA_DAR = 1,
WPS_DEV_MULTIMEDIA_PVR = 2,
WPS_DEV_MULTIMEDIA_MCX = 3,
WPS_DEV_GAMING_XBOX = 1,
WPS_DEV_GAMING_XBOX360 = 2,
WPS_DEV_GAMING_PLAYSTATION = 3,
WPS_DEV_PHONE_WINDOWS_MOBILE = 1
};
/* Request Type */
enum wps_request_type {
WPS_REQ_ENROLLEE_INFO = 0,
WPS_REQ_ENROLLEE = 1,
WPS_REQ_REGISTRAR = 2,
WPS_REQ_WLAN_MANAGER_REGISTRAR = 3
};
/* Response Type */
enum wps_response_type {
WPS_RESP_ENROLLEE_INFO = 0,
WPS_RESP_ENROLLEE = 1,
WPS_RESP_REGISTRAR = 2,
WPS_RESP_AP = 3
};
/* Walk Time for push button configuration (in seconds) */
#define WPS_PBC_WALK_TIME (120)
#define WPS_MAX_AUTHORIZED_MACS (5)
#endif /* WPS_DEFS_H */

View file

@ -0,0 +1,606 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "queue.h"
#include "utils/os.h"
#include <lwip_netconf.h>
#include <lwip/netif.h>
#include "wifi/wifi_conf.h"
#include <platform/platform_stdlib.h>
#define WLAN0_NAME "wlan0"
#ifndef ENABLE
#define ENABLE (1)
#endif
#ifndef DISABLE
#define DISABLE (0)
#endif
u8 eap_phase = 0;
u8 eap_method = 0;
// eap config arguments
char *eap_target_ssid = NULL;
char *eap_identity = NULL;
char *eap_password = NULL;
// if set eap_ca_cert and defined(EAP_SSL_VERIFY_SERVER), client will verify server's cert
const unsigned char *eap_ca_cert = NULL;
// if set eap_client_cert, eap_client_key, and defined(EAP_SSL_VERIFY_CLIENT), client will send its cert to server
const unsigned char *eap_client_cert = NULL;
const unsigned char *eap_client_key = NULL;
char *eap_client_key_pwd = NULL;
void eap_eapol_recvd_hdl(char *buf, int buf_len, int flags, void* handler_user_data);
void eap_eapol_start_hdl(char *buf, int buf_len, int flags, void* handler_user_data);
static int connect_by_open_system(char *target_ssid);
void set_eap_phase(unsigned char is_trigger_eap){
eap_phase = is_trigger_eap;
}
int get_eap_phase(void){
return eap_phase;
}
int get_eap_method(void){
return eap_method;
}
void reset_config(void){
eap_target_ssid = NULL;
eap_identity = NULL;
eap_password = NULL;
eap_ca_cert = NULL;
eap_client_cert = NULL;
eap_client_key = NULL;
eap_client_key_pwd = NULL;
}
void judge_station_disconnect(void)
{
int mode = 0;
unsigned char ssid[33];
wext_get_mode(WLAN0_NAME, &mode);
switch(mode) {
case IW_MODE_MASTER: //In AP mode
wifi_off();
vTaskDelay(20);
wifi_on(RTW_MODE_STA);
break;
case IW_MODE_INFRA: //In STA mode
if(wext_get_ssid(WLAN0_NAME, ssid) > 0)
wifi_disconnect();
}
}
void eap_disconnected_hdl(char *buf, int buf_len, int flags, void* handler_user_data){
// printf("disconnected\n");
wifi_unreg_event_handler(WIFI_EVENT_EAPOL_RECVD, eap_eapol_recvd_hdl);
wifi_unreg_event_handler(WIFI_EVENT_DISCONNECT, eap_disconnected_hdl);
eap_peer_unregister_methods();
eap_sm_deinit();
//reset_config();
}
/*
void eap_config(void){
eap_target_ssid = "Test_eap";
eap_identity = "guest2";
eap_password = "test2";
eap_client_cert = \
"-----BEGIN CERTIFICATE-----\r\n" \
"MIIC9zCCAd8CAQMwDQYJKoZIhvcNAQEEBQAwgZMxCzAJBgNVBAYTAkZSMQ8wDQYD\r\n" \
"VQQIEwZSYWRpdXMxEjAQBgNVBAcTCVNvbWV3aGVyZTEVMBMGA1UEChMMRXhhbXBs\r\n" \
"ZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTEmMCQGA1UE\r\n" \
"AxMdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTYwMzE1MDgwNzEx\r\n" \
"WhcNMTcwMzE1MDgwNzExWjBzMQswCQYDVQQGEwJGUjEPMA0GA1UECBMGUmFkaXVz\r\n" \
"MRUwEwYDVQQKEwxFeGFtcGxlIEluYy4xGjAYBgNVBAMUEXVzZXIyQGV4YW1wbGUu\r\n" \
"Y29tMSAwHgYJKoZIhvcNAQkBFhF1c2VyMkBleGFtcGxlLmNvbTCBnzANBgkqhkiG\r\n" \
"9w0BAQEFAAOBjQAwgYkCgYEAqESlV4OYfBcIgZ+Cs8mWpiBjhvKoa0/kIe7saqhC\r\n" \
"e5q4snox0jdkUpLcc4vOs3vQ7ZGnimqTltA9oF6XNUzTWW4vlJTKEfrCWK085l7c\r\n" \
"DHFvHavH3E6vuP71lI7jq4PLXbo2TvZK+uBul4ozjzVWihaZBtz8eLHq446h/D/p\r\n" \
"kzkCAwEAATANBgkqhkiG9w0BAQQFAAOCAQEAAfhVAIkNdeeUNJud720uUHVnIcxz\r\n" \
"GXWI+Svi1qchuTEnRNhLwXmnE+A0WWSHyfdR6FvzdT3xtz3K50iOif8jY2gCGkSK\r\n" \
"8RjKr97228SwbrGO9y9+dYIjH1uz9cBpoVKcpzdsWpKObrDPDYyReHSWo99jM2+O\r\n" \
"vfJxnBw4PLiBj7Q0/dpd6o4JXyp7Cxa0mB4/+cZqjCzzuKfuK3WP7j6laMCV6mg4\r\n" \
"wRZ528IdwDqB7OOqsDm1PVQM8vzny9PM6ikWUCRTVNQJN8RDLkrHR3FRjy15YLdt\r\n" \
"yOfDqVnT/z0wGBaxnNziSJjqPGHPpRi4bJFGXwXOhtknKmciKzfj9/npoQ==\r\n" \
"-----END CERTIFICATE-----\r\n";
eap_client_key = \
"-----BEGIN RSA PRIVATE KEY-----\r\n" \
"MIICXQIBAAKBgQCoRKVXg5h8FwiBn4KzyZamIGOG8qhrT+Qh7uxqqEJ7mriyejHS\r\n" \
"N2RSktxzi86ze9DtkaeKapOW0D2gXpc1TNNZbi+UlMoR+sJYrTzmXtwMcW8dq8fc\r\n" \
"Tq+4/vWUjuOrg8tdujZO9kr64G6XijOPNVaKFpkG3Px4serjjqH8P+mTOQIDAQAB\r\n" \
"AoGARI+LyweshssfxSkIKVc3EcNaqi6PHwJzUrw2ChM624AkR1xwllXJg7ehKVdK\r\n" \
"xmjprRLO8CASuL1qjsBb3fTKnBl+sIVxIFS0AI4Y3ri8VUKbangvSsI7pCzAFry7\r\n" \
"p1gmy9WWRV2ZEa+dV8xcrjb3bloT7hcdeLehgBCvExJIQM0CQQDXlSAKdW3AhYyj\r\n" \
"1A+pfyBSGxJbpSwNyyWgwHIHHjxendxmdUbrc8EbAu1eNKbP58TLgdCZsKcMonAv\r\n" \
"MY1Y2/nnAkEAx9CrUaCU8pJqXTRypM5JtexLKnYMJhpnA9uUILBQOq4Oe0eruyF5\r\n" \
"SaSxhyJYXY491ahWYPF0PTb3jkUhoN+l3wJBAJZthjgGDJlEFwjSFkOtYz4nib3N\r\n" \
"GVpeoFj1MBvrazCScpJDz0LIOLzCZCNSFfwIu3dNk+NKMqZMSn+D0h9pD40CQQC5\r\n" \
"K9n4NXaTLbjAU2CC9mE85JPr76XmkcUxwAWQHZTcLH1jJdIyAx1hb+zNLLjzSmRn\r\n" \
"Yi9ae6ibKhtUjyBQ87HFAkA2Bb3z7NUx+AA2g2HZocFZFShBxylACyQkl8FAFZtf\r\n" \
"osudmKdFQHyAWuBMex4tpz/OLTqJ1ecL1JQeC7OvlpEX\r\n" \
"-----END RSA PRIVATE KEY-----\r\n";
eap_ca_cert = \
"-----BEGIN CERTIFICATE-----\r\n" \
"MIIEpzCCA4+gAwIBAgIJAPvZaozpdfjkMA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD\r\n" \
"VQQGEwJGUjEPMA0GA1UECBMGUmFkaXVzMRIwEAYDVQQHEwlTb21ld2hlcmUxFTAT\r\n" \
"BgNVBAoTDEV4YW1wbGUgSW5jLjEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBs\r\n" \
"ZS5jb20xJjAkBgNVBAMTHUV4YW1wbGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4X\r\n" \
"DTE2MDMxNDExMjU0OVoXDTE2MDQxMzExMjU0OVowgZMxCzAJBgNVBAYTAkZSMQ8w\r\n" \
"DQYDVQQIEwZSYWRpdXMxEjAQBgNVBAcTCVNvbWV3aGVyZTEVMBMGA1UEChMMRXhh\r\n" \
"bXBsZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTEmMCQG\r\n" \
"A1UEAxMdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqGSIb3\r\n" \
"DQEBAQUAA4IBDwAwggEKAoIBAQC9pireu0aCDLNfMaGv3vId7RXjUhQwSK0jV2Oc\r\n" \
"SyvlKWH3P/N+5kLrP2iL6SCzyETVDXZ0vOsAMjcBF0zHp16prXV0d51cTUqeWBb0\r\n" \
"I5UnGxleIuuOfSg8zLUJoBWZPqLv++eZ5WgOKHt7SXocjvg7TU5t/TMB0Y8OCz3H\r\n" \
"CW2vJ/XKMgMA9HDUu4g57cJu88i1JPRpyFaz/HIQBc7+UNb9z+q09uTZKWTmEMqi\r\n" \
"E2U0EEIs7EtbxnOze1/8C4XNlmztrEdwvu6UEBU/TFkUoh9M646NkkBK7wP9n9pv\r\n" \
"T0nPQRJiiCrICzVqUtlEi9lIKpbBSMbQ0KzrGF7lGTgm4rz9AgMBAAGjgfswgfgw\r\n" \
"HQYDVR0OBBYEFIVyecka74kvOKIW0BjlTc/B+a2NMIHIBgNVHSMEgcAwgb2AFIVy\r\n" \
"ecka74kvOKIW0BjlTc/B+a2NoYGZpIGWMIGTMQswCQYDVQQGEwJGUjEPMA0GA1UE\r\n" \
"CBMGUmFkaXVzMRIwEAYDVQQHEwlTb21ld2hlcmUxFTATBgNVBAoTDEV4YW1wbGUg\r\n" \
"SW5jLjEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBsZS5jb20xJjAkBgNVBAMT\r\n" \
"HUV4YW1wbGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5ggkA+9lqjOl1+OQwDAYDVR0T\r\n" \
"BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAZYHM26sxbKOckVqJJ1QY0U2QFlGP\r\n" \
"1GYd8v27znxdnRmSonDvv3GjFfhwoyDk0JUuxkK/33ikCxihrgoO/EQTY9BV2OpW\r\n" \
"qkB1PDtb3i5ZRNvfjmW0pVA4p+GmdTGaEE5pTlcVnorzVrUeFKaZakb+IDFYzmeF\r\n" \
"xp8B3Bb5wvinDligLOaJnSlgS8QeeIab9HZfaVTTuPmVK6zE6D54Y0dJPnykvDdE\r\n" \
"cGN0FC+migfilFjJgkDJ0r78nwes55L8zjoofiZuO03rrHww6ARc3v1jYzAufddk\r\n" \
"QTiZHgjlMQb2XXMmXLn8kBgoDnqkXFNe8j0h8uxIJSrjOoIyn1h1wvX5/w==\r\n" \
"-----END CERTIFICATE-----\r\n";
}
*/
int eap_start(char *method){
#ifdef CONFIG_ENABLE_EAP
int ret = -1;
//unsigned long tick1 = xTaskGetTickCount();
//unsigned long tick2;
if(rltk_wlan_running(WLAN1_IDX)){
printf("\n\rNot support con-current mode!\n\r");
return -1;
}
judge_station_disconnect();
#if CONFIG_ENABLE_PEAP
if(strcmp(method,"peap") == 0){
ret = set_eap_peap_method();
}
#endif
#if CONFIG_ENABLE_TLS
if(strcmp(method,"tls") == 0){
ret = set_eap_tls_method();
}
#endif
#if CONFIG_ENABLE_TTLS
if(strcmp(method,"ttls") == 0){
ret = set_eap_ttls_method();
}
#endif
if(ret == -1){
printf("\r\neap method %s not supported\r\n", method);
return -1;
}
eap_method = get_eap_ctx_method();
printf("\n==================== %s_start ====================\n", method);
//eap_config();
set_eap_phase(ENABLE);
wifi_reg_event_handler(WIFI_EVENT_EAPOL_START, eap_eapol_start_hdl, NULL);
wifi_reg_event_handler(WIFI_EVENT_EAPOL_RECVD, eap_eapol_recvd_hdl, NULL);
ret = connect_by_open_system(eap_target_ssid);
#if CONFIG_LWIP_LAYER
/* Start DHCPClient */
if(ret == 0)
LwIP_DHCP(0, DHCP_START);
#endif
wifi_unreg_event_handler(WIFI_EVENT_EAPOL_START, eap_eapol_start_hdl);
// for re-authentication when session timeout
wifi_reg_event_handler(WIFI_EVENT_DISCONNECT, eap_disconnected_hdl, NULL);
//wifi_unreg_event_handler(WIFI_EVENT_EAPOL_RECVD, eap_eapol_recvd_hdl);
set_eap_phase(DISABLE);
// eap failed, disconnect
if(ret != 0){
judge_station_disconnect();
eap_disconnected_hdl(NULL, 0, 0, NULL);
rtw_msleep_os(200); //wait handler done
printf("\r\nERROR: connect to AP by %s failed\n", method);
}
eap_sm_deinit();
printf("\n==================== %s_finish ====================\n", method);
//tick2 = xTaskGetTickCount();
//printf("\r\nConnected after %dms.\n", (tick2-tick1));
return ret;
#else
return -1;
#endif
}
static int connect_by_open_system(char *target_ssid)
{
int retry_count = 0, ret;
if (target_ssid != NULL) {
while (1) {
rtw_msleep_os(500); //wait scan complete.
ret = wifi_connect(target_ssid,
RTW_SECURITY_OPEN,
NULL,
strlen(target_ssid),
0,
0,
NULL);
if (ret == RTW_SUCCESS) {
//printf("\r\n[EAP]Associate with AP success\n");
break;
}
if (retry_count == 0) {
//printf("\r\n[EAP]Associate with AP failed %d\n", ret);
return -1;
}
retry_count --;
printf("Retry connection...\n");
judge_station_disconnect();
set_eap_phase(ENABLE);
}
} else {
printf("\r\n[EAP]Target SSID is NULL\n");
return -1;
}
return 0;
}
static void eap_autoreconnect_thread(void *method)
{
eap_start((char*)method);
vTaskDelete(NULL);
}
void eap_autoreconnect_hdl(u8 method_id){
#ifdef CONFIG_ENABLE_EAP
char *method;
switch(method_id){
case 25: // EAP_TYPE_PEAP
method = "peap";
break;
case 13: // EAP_TYPE_TLS
method = "tls";
break;
case 21: // EAP_TYPE_TTLS
method = "ttls";
break;
default:
printf("invalid eap method\n");
return;
}
if(xTaskCreate(eap_autoreconnect_thread, ((const char*)"eap_autoreconnect_thread"), 1024, (void*) method, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed\n", __FUNCTION__);
#endif
}
// copy from ssl_client_ext.c
#if CONFIG_USE_POLARSSL
#include <polarssl/ssl.h>
#include <polarssl/memory.h>
int max_buf_bio_size = SSL_BUFFER_LEN;
#if ENABLE_EAP_SSL_VERIFY_CLIENT
static x509_crt* _cli_crt = NULL;
static pk_context* _clikey_rsa = NULL;
#endif
#if ENABLE_EAP_SSL_VERIFY_SERVER
static x509_crt* _ca_crt = NULL;
static int eap_verify(void *data, x509_crt *crt, int depth, int *flags)
{
//char buf[1024];
((void) data);
printf("\nVerify requested for (Depth %d):\n", depth);
//x509_crt_info(buf, sizeof(buf) - 1, "", crt);
//printf("%s", buf);
if(((*flags) & BADCERT_EXPIRED) != 0)
printf("server certificate has expired\n");
if(((*flags) & BADCERT_REVOKED) != 0)
printf(" ! server certificate has been revoked\n");
if(((*flags) & BADCERT_CN_MISMATCH) != 0)
printf(" ! CN mismatch\n");
if(((*flags) & BADCERT_NOT_TRUSTED) != 0)
printf(" ! self-signed or not signed by a trusted CA\n");
if(((*flags) & BADCRL_NOT_TRUSTED) != 0)
printf(" ! CRL not trusted\n");
if(((*flags) & BADCRL_EXPIRED) != 0)
printf(" ! CRL expired\n");
if(((*flags) & BADCERT_OTHER) != 0)
printf(" ! other (unknown) flag\n");
if((*flags) == 0)
printf(" Certificate verified without error flags\n");
return(0);
}
#endif
int eap_cert_init(void)
{
#if ENABLE_EAP_SSL_VERIFY_CLIENT
if(eap_client_cert != NULL && eap_client_key != NULL){
_cli_crt = polarssl_malloc(sizeof(x509_crt));
if(_cli_crt)
x509_crt_init(_cli_crt);
else
return -1;
_clikey_rsa = polarssl_malloc(sizeof(pk_context));
if(_clikey_rsa)
pk_init(_clikey_rsa);
else
return -1;
}
#endif
#if ENABLE_EAP_SSL_VERIFY_SERVER
if(eap_ca_cert != NULL){
_ca_crt = polarssl_malloc(sizeof(x509_crt));
if(_ca_crt)
x509_crt_init(_ca_crt);
else
return -1;
}
#endif
return 0;
}
void eap_client_cert_free(void)
{
#if ENABLE_EAP_SSL_VERIFY_CLIENT
if(eap_client_cert != NULL && eap_client_key != NULL){
if(_cli_crt) {
x509_crt_free(_cli_crt);
polarssl_free(_cli_crt);
_cli_crt = NULL;
}
if(_clikey_rsa) {
pk_free(_clikey_rsa);
polarssl_free(_clikey_rsa);
_clikey_rsa = NULL;
}
}
#endif
}
void eap_server_cert_free(void)
{
#if ENABLE_EAP_SSL_VERIFY_SERVER
if(eap_ca_cert != NULL){
if(_ca_crt) {
x509_crt_free(_ca_crt);
polarssl_free(_ca_crt);
_ca_crt = NULL;
}
}
#endif
}
int eap_cert_setup(ssl_context *ssl)
{
#if ENABLE_EAP_SSL_VERIFY_CLIENT
if(eap_client_cert != NULL && eap_client_key != NULL){
if(x509_crt_parse(_cli_crt, eap_client_cert, strlen(eap_client_cert)) != 0)
return -1;
if(pk_parse_key(_clikey_rsa, eap_client_key, strlen(eap_client_key), eap_client_key_pwd, strlen(eap_client_key_pwd)) != 0)
return -1;
ssl_set_own_cert(ssl, _cli_crt, _clikey_rsa);
}
#endif
#if ENABLE_EAP_SSL_VERIFY_SERVER
if(eap_ca_cert != NULL){
if(x509_crt_parse(_ca_crt, eap_ca_cert, strlen(eap_ca_cert)) != 0)
return -1;
ssl_set_ca_chain(ssl, _ca_crt, NULL, NULL);
ssl_set_authmode(ssl, SSL_VERIFY_REQUIRED);
ssl_set_verify(ssl, eap_verify, NULL);
}
#endif
return 0;
}
#elif CONFIG_USE_MBEDTLS
#include <mbedtls/config.h>
#include <mbedtls/platform.h>
#include <mbedtls/ssl.h>
#include <mbedtls/ssl_internal.h>
int max_buf_bio_size = MBEDTLS_SSL_BUFFER_LEN;
struct eap_tls{
void *ssl;
void *conf;
void *fd;
};
#if ENABLE_EAP_SSL_VERIFY_CLIENT
static mbedtls_x509_crt* _cli_crt = NULL;
static mbedtls_pk_context* _clikey_rsa = NULL;
#endif
#if ENABLE_EAP_SSL_VERIFY_SERVER
static mbedtls_x509_crt* _ca_crt = NULL;
static int eap_verify(void *data, mbedtls_x509_crt *crt, int depth, int *flags)
{
//char buf[1024];
((void) data);
printf("\nVerify requested for (Depth %d):\n", depth);
//mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt);
//printf("%s", buf);
if(((*flags) & MBEDTLS_X509_BADCERT_EXPIRED) != 0)
printf("server certificate has expired\n");
if(((*flags) & MBEDTLS_X509_BADCERT_REVOKED) != 0)
printf(" ! server certificate has been revoked\n");
if(((*flags) & MBEDTLS_X509_BADCERT_CN_MISMATCH) != 0)
printf(" ! CN mismatch\n");
if(((*flags) & MBEDTLS_X509_BADCERT_NOT_TRUSTED) != 0)
printf(" ! self-signed or not signed by a trusted CA\n");
if(((*flags) & MBEDTLS_X509_BADCRL_NOT_TRUSTED) != 0)
printf(" ! CRL not trusted\n");
if(((*flags) & MBEDTLS_X509_BADCRL_EXPIRED) != 0)
printf(" ! CRL expired\n");
if(((*flags) & MBEDTLS_X509_BADCERT_OTHER) != 0)
printf(" ! other (unknown) flag\n");
if((*flags) == 0)
printf(" Certificate verified without error flags\n");
return(0);
}
#endif
int eap_cert_init(void)
{
#if ENABLE_EAP_SSL_VERIFY_CLIENT
if(eap_client_cert != NULL && eap_client_key != NULL){
_cli_crt = mbedtls_calloc(1, sizeof(mbedtls_x509_crt));
if(_cli_crt)
mbedtls_x509_crt_init(_cli_crt);
else
return -1;
_clikey_rsa = mbedtls_calloc(1, sizeof(mbedtls_pk_context));
if(_clikey_rsa)
mbedtls_pk_init(_clikey_rsa);
else
return -1;
}
#endif
#if ENABLE_EAP_SSL_VERIFY_SERVER
if(eap_ca_cert != NULL){
_ca_crt = mbedtls_calloc(1, sizeof(mbedtls_x509_crt));
if(_ca_crt)
mbedtls_x509_crt_init(_ca_crt);
else
return -1;
}
#endif
return 0;
}
void eap_client_cert_free(void)
{
#if ENABLE_EAP_SSL_VERIFY_CLIENT
if(eap_client_cert != NULL && eap_client_key != NULL){
if(_cli_crt) {
mbedtls_x509_crt_free(_cli_crt);
mbedtls_free(_cli_crt);
_cli_crt = NULL;
}
if(_clikey_rsa) {
mbedtls_pk_free(_clikey_rsa);
mbedtls_free(_clikey_rsa);
_clikey_rsa = NULL;
}
}
#endif
}
void eap_server_cert_free(void)
{
#if ENABLE_EAP_SSL_VERIFY_SERVER
if(eap_ca_cert != NULL){
if(_ca_crt) {
mbedtls_x509_crt_free(_ca_crt);
mbedtls_free(_ca_crt);
_ca_crt = NULL;
}
}
#endif
}
int eap_cert_setup(struct eap_tls *tls_context)
{
#if ENABLE_EAP_SSL_VERIFY_CLIENT
if(eap_client_cert != NULL && eap_client_key != NULL){
if(mbedtls_x509_crt_parse(_cli_crt, eap_client_cert, strlen(eap_client_cert)+1) != 0)
return -1;
if(mbedtls_pk_parse_key(_clikey_rsa, eap_client_key, strlen(eap_client_key)+1, eap_client_key_pwd, strlen(eap_client_key_pwd)+1) != 0)
return -1;
mbedtls_ssl_conf_own_cert(tls_context->conf, _cli_crt, _clikey_rsa);
}
#endif
#if ENABLE_EAP_SSL_VERIFY_SERVER
if(eap_ca_cert != NULL){
if(mbedtls_x509_crt_parse(_ca_crt, eap_ca_cert, strlen(eap_ca_cert)+1) != 0)
return -1;
mbedtls_ssl_conf_ca_chain(tls_context->conf, _ca_crt, NULL);
mbedtls_ssl_conf_authmode(tls_context->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
mbedtls_ssl_conf_verify(tls_context->conf, eap_verify, NULL);
}
#endif
return 0;
}
#endif /*CONFIG_USE_MBEDTLS*/

View file

@ -0,0 +1,269 @@
#include "FreeRTOS.h"
#include "task.h"
#include "utils/os.h"
#include <lwip/netif.h>
#include <wifi/wifi_conf.h>
#include "wps/wps_defs.h"
#if CONFIG_ENABLE_P2P
enum p2p_wps_method {
WPS_NOT_READY, WPS_PIN_DISPLAY, WPS_PIN_KEYPAD, WPS_PBC
};
/*NETMASK*/
#define P2P_NETMASK_ADDR0 255
#define P2P_NETMASK_ADDR1 255
#define P2P_NETMASK_ADDR2 255
#define P2P_NETMASK_ADDR3 0
/*Gateway Address*/
#define P2P_GW_ADDR0 192
#define P2P_GW_ADDR1 168
#define P2P_GW_ADDR2 42
#define P2P_GW_ADDR3 1
#define P2P_GO_NEGO_RESULT_SIZE 376//256
xqueue_handle_t queue_for_p2p_nego;
extern void dhcps_init(struct netif * pnetif);
static int hex2num(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
return -1;
}
/**
* hwaddr_aton - Convert ASCII string to MAC address (colon-delimited format)
* @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
* @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
* Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
*/
int hwaddr_aton(const char *txt, u8 *addr)
{
int i;
for (i = 0; i < 6; i++) {
int a, b;
a = hex2num(*txt++);
if (a < 0)
return -1;
b = hex2num(*txt++);
if (b < 0)
return -1;
*addr++ = (a << 4) | b;
if (i < 5 && *txt++ != ':')
return -1;
}
return 0;
}
int wifi_start_p2p_go(char *ssid, char *passphrase, u8 channel)
{
extern struct netif xnetif[NET_IF_NUM];
struct netif * pnetif = &xnetif[0];
struct ip_addr ipaddr;
struct ip_addr netmask;
struct ip_addr gw;
IP4_ADDR(&ipaddr, P2P_GW_ADDR0, P2P_GW_ADDR1, P2P_GW_ADDR2, P2P_GW_ADDR3);
IP4_ADDR(&netmask, P2P_NETMASK_ADDR0, P2P_NETMASK_ADDR1 , P2P_NETMASK_ADDR2, P2P_NETMASK_ADDR3);
IP4_ADDR(&gw, P2P_GW_ADDR0, P2P_GW_ADDR1, P2P_GW_ADDR2, P2P_GW_ADDR3);
netif_set_addr(pnetif, &ipaddr, &netmask,&gw);
// start ap
if(wifi_start_ap(ssid,
RTW_SECURITY_WPA2_AES_PSK,
passphrase,
strlen(ssid),
strlen(passphrase),
channel
) != RTW_SUCCESS) {
printf("\n\rERROR: Operation failed!");
return -1;
}
netif_set_default(pnetif);
// start dhcp server
dhcps_init(pnetif);
return 0;
}
void app_callback(char *msg)
{
//From Application
}
void cmd_wifi_p2p_start(int argc, char **argv)
{
extern struct netif xnetif[NET_IF_NUM];
int listen_ch = 1;
int op_ch = 5;
int go_intent = 1;
#if 1
u32 r = 0;
os_get_random((u8 *) &r, sizeof(r));
go_intent = r%15+1; /*1-15*/
os_get_random((u8 *) &r, sizeof(r));
listen_ch = 1 + (r % 3) * 5;
os_get_random((u8 *) &r, sizeof(r));
op_ch = 1 + (r % 3) * 5;
#endif
wifi_off();
os_sleep(0, 20000);
wifi_on(RTW_MODE_P2P);
wifi_p2p_init(xnetif[0].hwaddr, go_intent, listen_ch, op_ch);
}
int cmd_wifi_p2p_auto_go_start(int argc, char **argv)
{
u8 *passphrase = "12345678";
u8 channel = 6; // 1, 6, 11
const char *ssid_in = "DIRECT-34-Ameba";
const char *dev_name = "Ameba1234"; // max strlen 32
const char *manufacturer = "by customer"; // max strlen 64
const char *model_name = "customer"; // max strlen 32
const char *model_number = "v2.0"; // max strlen 32
const char *serial_number = "9"; // max strlen 32
const u8 pri_dev_type[8] = {0x00,0x0A,0x00,0x50,0xF2,0x04,0x00,0x01}; // category ID:0x00,0x0A; sub category ID:0x00,0x01
u8 res[P2P_GO_NEGO_RESULT_SIZE];
u16 config_methods = WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD | WPS_CONFIG_PUSHBUTTON;
if(!is_wifi_p2p_initialized())
return -1;
wifi_p2p_set_dev_name(dev_name);
wifi_p2p_set_manufacturer(manufacturer);
wifi_p2p_set_model_name(model_name);
wifi_p2p_set_model_number(model_number);
wifi_p2p_set_serial_number(serial_number);
wifi_p2p_set_pri_dev_type(pri_dev_type);
wifi_p2p_set_ssid(ssid_in);
wifi_p2p_set_config_methods(config_methods);
wifi_p2p_init_auto_go_params(res, passphrase, channel);
wifi_p2p_start_auto_go(res);
return 0;
}
void cmd_wifi_p2p_stop(int argc, char **argv)
{
wifi_p2p_deinit();
wifi_off();
}
void cmd_p2p_listen(int argc, char **argv)
{
u32 timeout = 0;
if(argc == 2){
timeout = os_atoi((u8*)argv[1]);
printf("\r\n%s(): timeout=%d\n", __func__, timeout);
if(timeout > 3600)
timeout = 3600;
}
wifi_cmd_p2p_listen(timeout);
}
void cmd_p2p_find(int argc, char **argv)
{
wifi_cmd_p2p_find();
}
void cmd_p2p_peers(int argc, char **argv)
{
wifi_cmd_p2p_peers();
}
void cmd_p2p_info(int argc, char **argv)
{
wifi_cmd_p2p_info();
}
void cmd_p2p_disconnect(int argc, char **argv)
{
wifi_cmd_p2p_disconnect();
}
void cmd_p2p_connect(int argc, char **argv)
{
enum p2p_wps_method config_method = WPS_PBC;
char *pin = NULL;
u8 dest[ETH_ALEN] = {0x44, 0x6d, 0x57, 0xd7, 0xce, 0x41};
u8 res[P2P_GO_NEGO_RESULT_SIZE];
int ret = 0, result = 0;
#if 1
if((argc != 2) && (argc != 3) && (argc != 4)) {
printf("\n\rUsage: p2p_connect DEST_ADDR [pbc|pin] [pin code]\n");
printf("\n\rExample: p2p_connect 00:e0:4c:87:00:15 pin 12345678\n");
return;
}
if (hwaddr_aton(argv[1], dest)){
printf("\r\nP2P_CONNECT: dest address is not correct!\n");
return;
}
//printf("\r\nDEST: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", dest[0], dest[1], dest[2], dest[3], dest[4], dest[5]);
config_method = WPS_PBC;
if(argc == 3) {
if(os_strncmp(argv[2], "pbc", 3) == 0)
config_method = WPS_PBC;
else if(os_strncmp(argv[2], "pin", 3) == 0){
config_method = WPS_PIN_DISPLAY;
}else{
printf("\n\rUnknown config method!\n");
printf("\n\rUsage: p2p_connect DEST_ADDR [pbc|pin] \n");
printf("\n\rExample: p2p_connect 00:e0:4c:87:00:15 pin\n");
return;
}
}
else if(argc == 4) {
if(os_strncmp(argv[2], "pin", 3) == 0){
config_method = WPS_PIN_KEYPAD;
pin = argv[3];
}else{
printf("\n\rUnknown config method!\n");
printf("\n\rUsage: p2p_connect DEST_ADDR [pbc|pin] [pin code]\n");
printf("\n\rExample: p2p_connect 00:e0:4c:87:00:15 pin 12345678\n");
return;
}
}
#else //For test
u8 dest1[ETH_ALEN] = {0xea, 0x92, 0xa4, 0x9b, 0x61, 0xd6}; //NEXUS 4
//u8 dest1[ETH_ALEN] = {0x0e, 0x37, 0xdc, 0xfc, 0xc4, 0x12}; //HUAWEI U9508_c001
//u8 dest1[ETH_ALEN] = {0x42, 0xcb, 0xa8, 0xd3, 0x2c, 0x50}; //HUAWEI G610-T00
os_memcpy(dest, dest1, ETH_ALEN);
config_method = WPS_PBC;
#endif
if (queue_for_p2p_nego!= NULL) {
os_xqueue_delete(queue_for_p2p_nego);
queue_for_p2p_nego = NULL;
}
queue_for_p2p_nego = os_xqueue_create(1, P2P_GO_NEGO_RESULT_SIZE);
if(queue_for_p2p_nego != NULL) {
ret = wifi_cmd_p2p_connect(dest, config_method, pin);
if(ret == 0)
result = os_xqueue_receive(queue_for_p2p_nego, res, 15);
os_xqueue_delete(queue_for_p2p_nego);
queue_for_p2p_nego = NULL;
if((ret == 0) || (result == 0))
wifi_p2p_start_wps(res);
}
}
#endif //CONFIG_ENABLE_P2P

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,877 @@
//----------------------------------------------------------------------------//
/**
******************************************************************************
* @file wifi_conf.h
* @author
* @version
* @brief This file provides user interface for Wi-Fi station and AP mode configuration
* base on the functionalities provided by Realtek Wi-Fi driver.
******************************************************************************
* @attention
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*
* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
******************************************************************************
*/
#ifndef __WIFI_API_H
#define __WIFI_API_H
/** @addtogroup nic NIC
* @ingroup wlan
* @brief NIC functions
* @{
*/
#include "FreeRTOS.h"
#include "wifi_constants.h"
#include "wifi_structures.h"
#include "wifi_util.h"
#include "wifi_ind.h"
#include <platform/platform_stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************
* Macros
******************************************************/
#define RTW_ENABLE_API_INFO
#ifdef RTW_ENABLE_API_INFO
#define RTW_API_INFO(args) do {printf args;} while(0)
#else
#define RTW_API_INFO(args)
#endif
#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
#define CMP_MAC( a, b ) (((a[0])==(b[0]))&& \
((a[1])==(b[1]))&& \
((a[2])==(b[2]))&& \
((a[3])==(b[3]))&& \
((a[4])==(b[4]))&& \
((a[5])==(b[5])))
/******************************************************
* Constants
******************************************************/
#define SCAN_LONGEST_WAIT_TIME (4500)
#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
#define PSCAN_ENABLE 0x01 //enable for partial channel scan
#define PSCAN_FAST_SURVEY 0x02 //set to select scan time to FAST_SURVEY_TO, otherwise SURVEY_TO
#define PSCAN_SIMPLE_CONFIG 0x04 //set to select scan time to FAST_SURVEY_TO and resend probe request
/******************************************************
* Type Definitions
******************************************************/
/** Scan result callback function pointer type
*
* @param result_ptr : A pointer to the pointer that indicates where to put the next scan result
* @param user_data : User provided data
*/
typedef void (*rtw_scan_result_callback_t)( rtw_scan_result_t** result_ptr, void* user_data );
typedef rtw_result_t (*rtw_scan_result_handler_t)( rtw_scan_handler_result_t* malloced_scan_result );
/******************************************************
* Structures
******************************************************/
typedef struct {
char *buf;
int buf_len;
} scan_buf_arg;
/******************************************************
* Structures
******************************************************/
typedef struct internal_scan_handler{
rtw_scan_result_t** pap_details;
rtw_scan_result_t * ap_details;
int scan_cnt;
rtw_bool_t scan_complete;
unsigned char max_ap_size;
rtw_scan_result_handler_t gscan_result_handler;
#if SCAN_USE_SEMAPHORE
void *scan_semaphore;
#else
int scan_running;
#endif
void* user_data;
unsigned int scan_start_time;
} internal_scan_handler_t;
typedef struct {
rtw_network_info_t network_info;
void *join_sema;
} internal_join_result_t;
/******************************************************
* Function Declarations
******************************************************/
/**
* @brief Initialize Realtek WiFi API System.
* - Initialize the required parts of the software platform.
* i.e. worker, event registering, semaphore, etc.
* - Initialize the RTW API thread which handles the asynchronous event.
* @return RTW_SUCCESS if initialization is successful, RTW_ERROR otherwise
*/
int wifi_manager_init(void);
/**
* @brief Join a Wi-Fi network.
* Scan for, associate and authenticate with a Wi-Fi network.
* On successful return, the system is ready to send data packets.
*
* @param[in] ssid: A null terminated string containing the SSID name of the network to join.
* @param[in] security_type: Authentication type:
* - RTW_SECURITY_OPEN - Open Security
* - RTW_SECURITY_WEP_PSK - WEP Security with open authentication
* - RTW_SECURITY_WEP_SHARED - WEP Security with shared authentication
* - RTW_SECURITY_WPA_TKIP_PSK - WPA Security
* - RTW_SECURITY_WPA2_AES_PSK - WPA2 Security using AES cipher
* - RTW_SECURITY_WPA2_TKIP_PSK - WPA2 Security using TKIP cipher
* - RTW_SECURITY_WPA2_MIXED_PSK - WPA2 Security using AES and/or TKIP ciphers
* @param[in] password: A byte array containing either the cleartext security key for WPA/WPA2
* secured networks, or a pointer to an array of rtw_wep_key_t
* structures for WEP secured networks.
* @param[in] ssid_len: The length of the SSID in bytes.
* @param[in] password_len: The length of the security_key in bytes.
* @param[in] key_id: The index of the wep key (0, 1, 2, or 3). If not using it, leave it with value -1.
* @param[in] semaphore: A user provided semaphore that is flagged when the join is complete. If not using it, leave it with NULL value.
* @return RTW_SUCCESS: when the system is joined and ready to send data packets.
* @return RTW_ERROR: if an error occurred.
* @note Please make sure the Wi-Fi is enabled before invoking this function. (@ref wifi_on())
*/
int wifi_connect(
char *ssid,
rtw_security_t security_type,
char *password,
int ssid_len,
int password_len,
int key_id,
void *semaphore);
/**
* @brief Join a Wi-Fi network with specified BSSID.
* Scan for, associate and authenticate with a Wi-Fi network.
* On successful return, the system is ready to send data packets.
* @param[in] bssid: The specified BSSID to connect.
* @param[in] ssid: A null terminated string containing the SSID name of the network to join.
* @param[in] security_type: Authentication type:
* - RTW_SECURITY_OPEN - Open Security
* - RTW_SECURITY_WEP_PSK - WEP Security with open authentication
* - RTW_SECURITY_WEP_SHARED - WEP Security with shared authentication
* - RTW_SECURITY_WPA_TKIP_PSK - WPA Security
* - RTW_SECURITY_WPA2_AES_PSK - WPA2 Security using AES cipher
* - RTW_SECURITY_WPA2_TKIP_PSK - WPA2 Security using TKIP cipher
* - RTW_SECURITY_WPA2_MIXED_PSK - WPA2 Security using AES and/or TKIP ciphers
* @param[in] password: A byte array containing either the cleartext security key for WPA/WPA2
* secured networks, or a pointer to an array of rtw_wep_key_t
* structures for WEP secured networks.
* @param[in] ssid_len: The length of the SSID in bytes.
* @param[in] password_len: The length of the security_key in bytes.
* @param[in] key_id: The index of the wep key.
* @param[in] semaphore: A user provided semaphore that is flagged when the join is complete.
* @return RTW_SUCCESS: when the system is joined and ready to send data packets.
* @return RTW_ERROR: if an error occurred.
* @note Please make sure the Wi-Fi is enabled before invoking this function. (@ref wifi_on())
* @note The difference between @ref wifi_connect_bssid() and @ref wifi_connect() is that BSSID has higher priority as the basis of connection in @ref wifi_connect_bssid.
*/
int wifi_connect_bssid(
unsigned char bssid[ETH_ALEN],
char *ssid,
rtw_security_t security_type,
char *password,
int bssid_len,
int ssid_len,
int password_len,
int key_id,
void *semaphore);
/**
* @brief Disassociates from current Wi-Fi network.
* @param None
* @return RTW_SUCCESS: On successful disassociation from the AP.
* @return RTW_ERROR: If an error occurred.
*/
int wifi_disconnect(void);
/**
* @brief Check if Wi-Fi has connected to AP before dhcp.
* @param None
* @return RTW_SUCCESS: If conneced.
* @return RTW_ERROR: If not connect.
*/
int wifi_is_connected_to_ap(void);
/**
* @brief Check if the specified interface is up.
* @param[in] interface: The interface can be set as RTW_STA_INTERFACE or RTW_AP_INTERFACE. (@ref rtw_interface_t)
* @return If the function succeeds, the return value is 1. Otherwise, return 0.
*/
int wifi_is_up(rtw_interface_t interface);
/** Determines if a particular interface is ready to transceive ethernet packets
*
* @param Radio interface to check, options are
* RTW_STA_INTERFACE, RTW_AP_INTERFACE
* @return RTW_SUCCESS : if the interface is ready to
* transceive ethernet packets
* @return RTW_NOTFOUND : no AP with a matching SSID was
* found
* @return RTW_NOT_AUTHENTICATED: a matching AP was found but
* it won't let you
* authenticate. This can
* occur if this device is
* in the block list on the
* AP.
* @return RTW_NOT_KEYED: the device has authenticated and
* associated but has not completed
* the key exchange. This can occur
* if the passphrase is incorrect.
* @return RTW_ERROR : if the interface is not ready to
* transceive ethernet packets
*/
int wifi_is_ready_to_transceive(rtw_interface_t interface);
/**
* @brief This function sets the current Media Access Control (MAC) address of the 802.11 device.
* @param[in] mac: Wi-Fi MAC address.
* @return RTW_SUCCESS or RTW_ERROR
*/
int wifi_set_mac_address(char * mac);
/**
* @brief Retrieves the current Media Access Control (MAC) address
* (or Ethernet hardware address) of the 802.11 device.
* @param[in] mac: Point to the result of the mac address will be get.
* @return RTW_SUCCESS or RTW_ERROR
*/
int wifi_get_mac_address(char * mac);
/**
* @brief Enable Wi-Fi powersave mode.
* @param None
* @return RTW_SUCCESS or RTW_ERROR.
*/
int wifi_enable_powersave(void);
/**
* @brief Disable Wi-Fi powersave mode.
* @param None
* @return RTW_SUCCESS or RTW_ERROR.
*/
int wifi_disable_powersave(void);
/** Gets the tx power in index units
*
* @param dbm : The variable to receive the tx power in index.
*
* @return RTW_SUCCESS : if successful
* RTW_ERROR : if not successful
*/
int wifi_get_txpower(int *poweridx);
/**
* @brief Set the tx power in index units.
* @param[in] poweridx: The desired tx power in index.
* @return RTW_SUCCESS: if tx power is successfully set
* @return RTW_ERROR: if tx power is not successfully set
*/
int wifi_set_txpower(int poweridx);
/**
* @brief Get the associated clients with SoftAP.
* @param[out] client_list_buffer: The location where the client list will be stored.
* @param[in] buffer_length: The buffer length.
* @return RTW_SUCCESS: The result is successfully got.
* @return RTW_ERROR: The result is not successfully got.
*/
int wifi_get_associated_client_list(void * client_list_buffer, unsigned short buffer_length);
/**
* @brief Get the SoftAP information.
* @param[out] ap_info: The location where the AP info will be stored.
* @param[out] security: The security type.
* @return RTW_SUCCESS: The result is successfully got.
* @return RTW_ERROR: The result is not successfully got.
*/
int wifi_get_ap_info(rtw_bss_info_t * ap_info, rtw_security_t* security);
/**
* @brief Set the country code to driver to determine the channel set.
* @param[in] country_code: Specify the country code.
* @return RTW_SUCCESS: If result is successfully set.
* @return RTW_ERROR: If result is not successfully set.
*/
int wifi_set_country(rtw_country_code_t country_code);
/**
* @brief Retrieve the latest RSSI value.
* @param[out] pRSSI: Points to the integer to store the RSSI value gotten from driver.
* @return RTW_SUCCESS: If the RSSI is succesfully retrieved.
* @return RTW_ERROR: If the RSSI is not retrieved.
*/
int wifi_get_rssi(int *pRSSI);
/**
* @brief Set the listening channel for promiscuous mode.
* @param[in] channel: The desired channel.
* @return RTW_SUCCESS: If the channel is successfully set.
* @return RTW_ERROR: If the channel is not successfully set.
* @note Do NOT need to call this function for STA mode wifi driver, since it will determine the channel from received beacon.
*/
int wifi_set_channel(int channel);
/**
* @brief Get the current channel on STA interface.
* @param[out] channel: A pointer to the variable where the
* channel value will be written
* @return RTW_SUCCESS: If the channel is successfully read.
* @return RTW_ERROR: If the channel is not successfully read.
*/
int wifi_get_channel(int *channel);
/**
* @brief Register interest in a multicast address.\n
* Once a multicast address has been registered, all packets detected on the
* medium destined for that address are forwarded to the host.
* Otherwise they are ignored.
* @param[in] mac: Ethernet MAC address
* @return RTW_SUCCESS: If the address is registered successfully.
* @return RTW_ERROR: If the address is not registered.
*/
int wifi_register_multicast_address(rtw_mac_t *mac);
/**
* @brief Unregister interest in a multicast address.\n
* Once a multicast address has been unregistered, all packets detected on the
* medium destined for that address are ignored.
* @param[in] mac: Ethernet MAC address
* @return RTW_SUCCESS: If the address is unregistered successfully.
* @return RTW_ERROR: If the address is not unregistered.
*/
int wifi_unregister_multicast_address(rtw_mac_t *mac);
/**
* @brief Setup the adaptivity mode.
* You can replace this weak function by the same name funcation to setup adaptivity mode you want.
* @param None
* @return If the function succeeds, the return value is 0.
*/
_WEAK void wifi_set_mib(void);
/**
* @brief Setup country code.
* You can replace this weak function by the same name funcation to setup country code you want.
* @param None
* @return If the function succeeds, the return value is 0.
*/
//----------------------------------------------------------------------------//
_WEAK void wifi_set_country_code(void);
/**
* @brief Enable Wi-Fi RF.
* @param None
* @return If the function succeeds, the return value is 0.
* @note The difference between @ref wifi_rf_on() and @ref wifi_on() is that @ref wifi_rf_on() simply enable RF HAL, it does not enable the driver or allocate memory.
*/
int wifi_rf_on(void);
/**
* @brief Disable Wi-Fi RF.
* @param None
* @return If the function succeeds, the return value is 0.
* @note The difference between @ref wifi_rf_off() and @ref wifi_off() is that @ref wifi_rf_off() simply disable RF HAL, the driver and used heap memory will NOT be released.
*/
int wifi_rf_off(void);
/**
* @brief Enable Wi-Fi.
* - Bring the Wireless interface "Up"
* - Initialize the driver thread which arbitrates access
* to the SDIO/SPI bus
*
* @param[in] mode: Decide to enable WiFi in which mode. The optional modes are enumerated in @ref rtw_mode_t.
* @return RTW_SUCCESS: if the WiFi chip was initialized successfully.
* @return RTW_ERROR: if the WiFi chip was not initialized successfully.
*/
int wifi_on(rtw_mode_t mode);
/**
* @brief Disable Wi-Fi.
*
* @param None
* @return RTW_SUCCESS: if deinitialization is successful.
* @return RTW_ERROR: otherwise.
*/
int wifi_off(void);
/**
* Turn off the Wi-Fi device
*
* - Bring the Wireless interface "Down"
* - De-Initialises the driver thread which arbitrates access
* to the SDIO/SPI bus
*
* @return RTW_SUCCESS if deinitialization is successful,
* RTW_ERROR otherwise
*/
int wifi_off_fastly(void);
/**
* @brief Set IPS/LPS mode.
* @param[in] ips_mode: The desired IPS mode. It becomes effective when wlan enter ips.\n
* @ref ips_mode is inactive power save mode. Wi-Fi automatically turns RF off if it is not associated to AP. Set 1 to enable inactive power save mode.
* @param[in] lps_mode: The desired LPS mode. It becomes effective when wlan enter lps.\n
* @ref lps_mode is leisure power save mode. Wi-Fi automatically turns RF off during the association to AP is traffic is not busy while it also automatically turns RF on to listen to beacon. Set 1 to enable leisure power save mode.
* @return RTW_SUCCESS if setting LPS mode successful.
* @return RTW_ERROR otherwise.
*/
int wifi_set_power_mode(unsigned char ips_mode, unsigned char lps_mode);
/**
* Set TDMA parameters
*
* @param[in] slot_period : We separate TBTT into 2 or 3 slots.
* If we separate TBTT into 2 slots, then slot_period should be larger or equal to 50ms.
* It means 2 slot period is
* slot_period, 100-slot_period
* If we separate TBTT into 3 slots, then slot_period should be less or equal to 33ms.
* It means 3 slot period is
* 100 - 2 * slot_period, slot_period, slot_period
* @param[in] rfon_period_len_1: rf on period of slot 1
* @param[in] rfon_period_len_2: rf on period of slot 2
* @param[in] rfon_period_len_3: rf on period of slot 3
*
* @return RTW_SUCCESS if setting TDMA parameters successful
* RTW_ERROR otherwise
*/
int wifi_set_tdma_param(unsigned char slot_period, unsigned char rfon_period_len_1, unsigned char rfon_period_len_2, unsigned char rfon_period_len_3);
/**
* @brief Set LPS DTIM.
* @param[in] dtim: In LPS, the package can be buffered at AP side.
* STA leave LPS until dtim count of packages buffered at AP side.
* @return RTW_SUCCESS if setting LPS dtim successful.
* @return RTW_ERROR otherwise
*/
int wifi_set_lps_dtim(unsigned char dtim);
/**
* @brief Get LPS DTIM.
* @param[out] dtim: In LPS, the package can be buffered at AP side.
* STA leave LPS until dtim count of packages buffered at AP side.
* @return RTW_SUCCESS if getting LPS dtim successful.
* @return RTW_ERROR otherwise.
*/
int wifi_get_lps_dtim(unsigned char *dtim);
/**
* @brief Trigger Wi-Fi driver to start an infrastructure Wi-Fi network.
* @warning If a STA interface is active when this function is called, the softAP will
* start on the same channel as the STA. It will NOT use the channel provided!
* @param[in] ssid: A null terminated string containing the SSID name of the network.
* @param[in] security_type:
* - RTW_SECURITY_OPEN - Open Security
* - RTW_SECURITY_WPA_TKIP_PSK - WPA Security
* - RTW_SECURITY_WPA2_AES_PSK - WPA2 Security using AES cipher
* - RTW_SECURITY_WPA2_MIXED_PSK - WPA2 Security using AES and/or TKIP ciphers
* - WEP security is NOT IMPLEMENTED. It is NOT SECURE!
* @param[in] password: A byte array containing the cleartext security key for the network.
* @param[in] ssid_len: The length of the SSID in bytes.
* @param[in] password_len: The length of the security_key in bytes.
* @param[in] channel: 802.11 channel number.
* @return RTW_SUCCESS: If successfully creates an AP.
* @return RTW_ERROR: If an error occurred.
* @note Please make sure the Wi-Fi is enabled before invoking this function. (@ref wifi_on())
*/
int wifi_start_ap(
char *ssid,
rtw_security_t security_type,
char *password,
int ssid_len,
int password_len,
int channel);
/**
* @brief Start an infrastructure Wi-Fi network with hidden SSID.
* @warning If a STA interface is active when this function is called, the softAP will
* start on the same channel as the STA. It will NOT use the channel provided!
*
* @param[in] ssid: A null terminated string containing
* the SSID name of the network to join.
* @param[in] security_type: Authentication type: \n
* - RTW_SECURITY_OPEN - Open Security
* - RTW_SECURITY_WPA_TKIP_PSK - WPA Security
* - RTW_SECURITY_WPA2_AES_PSK - WPA2 Security using AES cipher
* - RTW_SECURITY_WPA2_MIXED_PSK - WPA2 Security using AES and/or TKIP ciphers
* - WEP security is NOT IMPLEMENTED. It is NOT SECURE!
* @param[in] password: A byte array containing the cleartext
* security key for the network.
* @param[in] ssid_len: The length of the SSID in bytes.
* @param[in] password_len: The length of the security_key in bytes.
* @param[in] channel: 802.11 channel number
*
* @return RTW_SUCCESS: If successfully creates an AP.
* @return RTW_ERROR: If an error occurred.
*/
int wifi_start_ap_with_hidden_ssid(
char *ssid,
rtw_security_t security_type,
char *password,
int ssid_len,
int password_len,
int channel);
/**
* @brief Initiate a scan to search for 802.11 networks.
*
* @param[in] scan_type: Specifies whether the scan should
* be Active, Passive or scan
* Prohibited channels
* @param[in] bss_type: Specifies whether the scan should
* search for Infrastructure
* networks (those using an Access
* Point), Ad-hoc networks, or both
* types.
* @param[in] result_ptr: Scan specific ssid. The first 4
* bytes is ssid lenth, and ssid name
* append after it.
* If no specific ssid need to scan,
* PLEASE CLEAN result_ptr before pass
* it into parameter.
* @param[out] result_ptr: a pointer to a pointer to a result
* storage structure.
* @return RTW_SUCCESS or RTW_ERROR
* @note The scan progressively accumulates results over time, and
* may take between 1 and 3 seconds to complete. The results of
* the scan will be individually provided to the callback
* function. Note: The callback function will be executed in
* the context of the RTW thread.
* @note When scanning specific channels, devices with a
* strong signal strength on nearby channels may be
* detected
*/
int wifi_scan(rtw_scan_type_t scan_type,
rtw_bss_type_t bss_type,
void* result_ptr);
/**
* @brief Initiate a scan to search for 802.11 networks, a higher level API based on wifi_scan
* to simplify the scan operation.
* @param[in] results_handler: The callback function which will receive and process the result data.
* @param[in] user_data: User specified data that will be passed directly to the callback function.
* @return RTW_SUCCESS or RTW_ERROR
* @note Callback must not use blocking functions, since it is called from the context of the RTW thread.
* The callback, user_data variables will be referenced after the function returns.
* Those variables must remain valid until the scan is completed.
* The usage of this api can reference ATWS in atcmd_wifi.c.
*/
int wifi_scan_networks(rtw_scan_result_handler_t results_handler, void* user_data);
/**
* @brief Initiate a scan to search for 802.11 networks with specified SSID.
* @param[in] results_handler: The callback function which will receive and process the result data.
* @param[in] user_data: User specified data that will be passed directly to the callback function.
* @param[in] scan_buflen: The length of the result storage structure.
* @param[in] ssid: The SSID of target network.
* @param[in] ssid_len: The length of the target network SSID.
* @return RTW_SUCCESS or RTW_ERROR
* @note Callback must not use blocking functions, since it is called from the context of the RTW thread.
* The callback, user_data variables will be referenced after the function returns.
* Those variables must remain valid until the scan is completed.
*/
int wifi_scan_networks_with_ssid(int (results_handler)(char*, int, char *, void *), void* user_data, int scan_buflen, char* ssid, int ssid_len);
/**
* @brief Set the channel used to be partial scanned.
* @param[in] channel_list: An array stores the channel list.
* @param[in] pscan_config: the pscan_config of the channel set.
* @param[in] length: The length of the channel_list.
* @return RTW_SUCCESS or RTW_ERROR.
* @note This function should be used with wifi_scan function. First, use @ref wifi_set_pscan_chan to
* indicate which channel will be scanned, and then use @ref wifi_scan to get scanned results.
*/
int wifi_set_pscan_chan(__u8 * channel_list,__u8 * pscan_config, __u8 length);
/**
* @brief Get current Wi-Fi setting from driver.
* @param[in] ifname: the wlan interface name, can be WLAN0_NAME or WLAN1_NAME.
* @param[out] pSetting: Points to the rtw_wifi_setting_t structure to store the WIFI setting gotten from driver.
* @return RTW_SUCCESS or RTW_ERROR.
*/
int wifi_get_setting(const char *ifname,rtw_wifi_setting_t *pSetting);
/**
* @brief Show the network information stored in a rtw_wifi_setting_t structure.
* @param[in] ifname: the wlan interface name, can be WLAN0_NAME or WLAN1_NAME.
* @param[in] pSetting: Points to the rtw_wifi_setting_t structure which information is gotten by @ref wifi_get_setting().
* @return RTW_SUCCESS or RTW_ERROR.
*/
int wifi_show_setting(const char *ifname,rtw_wifi_setting_t *pSetting);
/**
* @brief
Set the network mode according to the data rate its supported.
* Driver works in BGN mode in default after driver initialization. This function is used to
* change wireless network mode for station mode before connecting to AP.
* @param[in] mode: Network mode to set. The value can be RTW_NETWORK_B/RTW_NETWORK_BG/RTW_NETWORK_BGN.
* @return RTW_SUCCESS or RTW_ERROR.
*/
int wifi_set_network_mode(rtw_network_mode_t mode);
/**
* @brief Set the chip to start or stop the promiscuous mode.
* @param[in] enabled: enabled can be set 0, 1 and 2. if enabled is zero, disable the promisc, else enable the promisc.
* - 0 means disable the promisc.
* - 1 means enable the promisc.
* - 2 means enable the promisc special for length is used.
* @param[in] callback: the callback function which will
* receive and process the netowork data.
* @param[in] len_used: specify if the the promisc length is used.
* If len_used set to 1, packet length will be saved and transferred to callback function.
*
* @return RTW_SUCCESS or RTW_ERROR
* @note This function can be used to implement vendor specified simple configure.
*/
int wifi_set_promisc(rtw_rcr_level_t enabled, void (*callback)(unsigned char*, unsigned int, void*), unsigned char len_used);
/**
* @brief Let Wi-Fi enter promiscuous mode.
* @param[in] None
* @return None
*/
void wifi_enter_promisc_mode(void);
/** Set the wps phase
*
* @param is_trigger_wps[in] : to trigger wps function or not
*
* @return RTW_SUCCESS or RTW_ERROR
*/
int wifi_set_wps_phase(unsigned char is_trigger_wps);
/**
* @brief Trigger Wi-Fi driver to restart an infrastructure Wi-Fi network.
* @warning If a STA interface is active when this function is called, the softAP will
* start on the same channel as the STA. It will NOT use the channel provided!
* @param[in] ssid: A null terminated string containing the SSID name of the network.
* @param[in] security_type:
* - RTW_SECURITY_OPEN - Open Security
* - RTW_SECURITY_WPA_TKIP_PSK - WPA Security
* - RTW_SECURITY_WPA2_AES_PSK - WPA2 Security using AES cipher
* - RTW_SECURITY_WPA2_MIXED_PSK - WPA2 Security using AES and/or TKIP ciphers
* - WEP security is NOT IMPLEMENTED. It is NOT SECURE!
* @param[in] password: A byte array containing the cleartext security key for the network.
* @param[in] ssid_len: The length of the SSID in bytes.
* @param[in] password_len: The length of the security_key in bytes.
* @param[in] channel: 802.11 channel number.
* @return RTW_SUCCESS: If successfully creates an AP.
* @return RTW_ERROR: If an error occurred.
* @note Please make sure the Wi-Fi is enabled before invoking this function. (@ref wifi_on())
*/
int wifi_restart_ap(
unsigned char *ssid,
rtw_security_t security_type,
unsigned char *password,
int ssid_len,
int password_len,
int channel);
/**
* @brief Set reconnection mode with configuration.
* @param[in] mode: Set 1/0 to enalbe/disable the reconnection mode.
* @param[in] retry_times: The number of retry limit.
* @param[in] timeout: The timeout value (in seconds).
* @return 0 if success, otherwise return -1.
* @note Defining CONFIG_AUTO_RECONNECT in "autoconf.h" needs to be done before compiling,
* or this API won't be effective.
* @note The difference between @ref wifi_config_autoreconnect() and @ref wifi_set_autoreconnect() is that
* user can specify the retry times and timeout value in @ref wifi_config_autoreconnect().
* But in @ref wifi_set_autoreconnect() these values are set with 3 retry limit and 5 seconds timeout as default.
*/
int wifi_config_autoreconnect(__u8 mode, __u8 retry_times, __u16 timeout);
/**
* @brief Set reconnection mode with 3 retry limit and 5 seconds timeout as default.
* @param[in] mode: Set 1/0 to enalbe/disable the reconnection mode.
* @return 0 if success, otherwise return -1.
* @note Defining CONFIG_AUTO_RECONNECT in "autoconf.h" needs to be done before compiling,
* or this API won't be effective.
* @note The difference between @ref wifi_config_autoreconnect() and @ref wifi_set_autoreconnect() is that
* user can specify the retry times and timeout value in @ref wifi_config_autoreconnect().
* But in @ref wifi_set_autoreconnect() these values are set with 3 retry limit and 5 seconds timeout as default.
*/
int wifi_set_autoreconnect(__u8 mode);
/**
* @brief Get the result of setting reconnection mode.
* @param[out] mode: Point to the result of setting reconnection mode.
* @return 0 if success, otherwise return -1.
* @note Defining CONFIG_AUTO_RECONNECT in "autoconf.h" needs to be done before compiling,
* or this API won't be effective.
*/
int wifi_get_autoreconnect(__u8 *mode);
/**
* @brief Present the device disconnect reason while connecting.
* @param None
* @return @ref rtw_connect_error_flag_t
* - 0: RTW_NO_ERROR
* - 1: RTW_NONE_NETWORK
* - 2: RTW_CONNECT_FAIL
* - 3: RTW_WRONG_PASSWORD
* - 4: RTW_DHCP_FAIL
* - 5: RTW_UNKNOWN (initial status)
*/
int wifi_get_last_error(void);
#ifdef CONFIG_CUSTOM_IE
#ifndef BIT
#define BIT(x) ((__u32)1 << (x))
#endif
#ifndef _CUSTOM_IE_TYPE_
#define _CUSTOM_IE_TYPE_
/**
* @brief The enumeration is transmission type for wifi custom ie.
*/
typedef enum CUSTOM_IE_TYPE{
PROBE_REQ = BIT(0),
PROBE_RSP = BIT(1),
BEACON = BIT(2),
}rtw_custom_ie_type_t;
#endif /* _CUSTOM_IE_TYPE_ */
/* ie format
* +-----------+--------+-----------------------+
* |element ID | length | content in length byte|
* +-----------+--------+-----------------------+
*
* type: refer to CUSTOM_IE_TYPE
*/
#ifndef _CUS_IE_
#define _CUS_IE_
/**
* @brief The structure is used to set WIFI custom ie list, and type match CUSTOM_IE_TYPE.\n
* The ie will be transmitted according to the type.
*/
typedef struct _cus_ie{
__u8 *ie;
__u8 type;
}rtw_custom_ie_t, *p_rtw_custom_ie_t;
#endif /* _CUS_IE_ */
/**
* @brief Setup custom ie list.
* @warning This API can't be executed twice before deleting the previous custom ie list.
* @param[in] cus_ie: Pointer to WIFI CUSTOM IE list.
* @param[in] ie_num: The number of WIFI CUSTOM IE list.
* @return 0 if success, otherwise return -1.
* @note Defininig CONFIG_CUSTOM_IE in "autoconf.h" needs to be done before compiling,
* or this API won't be effective.
*/
int wifi_add_custom_ie(void *cus_ie, int ie_num);
/**
* @brief Update the item in WIFI CUSTOM IE list.
* @param[in] cus_ie: Pointer to WIFI CUSTOM IE address.
* @param[in] ie_index: Index of WIFI CUSTOM IE list.
* @return 0 if success, otherwise return -1.
* @note Defininig CONFIG_CUSTOM_IE in "autoconf.h" needs to be done before compiling,
* or this API won't be effective.
*/
int wifi_update_custom_ie(void *cus_ie, int ie_index);
/**
* @brief Delete WIFI CUSTOM IE list.
* @param None
* @return 0 if success, otherwise return -1.
* @note Defininig CONFIG_CUSTOM_IE in "autoconf.h" needs to be done before compiling,
* or this API won't be effective.
*/
int wifi_del_custom_ie(void);
#endif
#ifdef CONFIG_PROMISC
/**
* @brief Initialize packet filter related data.
* @param None
* @return None
*/
void wifi_init_packet_filter(void);
/**
* @brief Add packet filter.
* @param[in] filter_id: The filter id.
* @param[in] patt: Point to the filter pattern.
* @param[in] rule: Point to the filter rule.
* @return 0 if success, otherwise return -1.
* @note For now, the maximum number of filters is 5.
*/
int wifi_add_packet_filter(unsigned char filter_id, rtw_packet_filter_pattern_t *patt, rtw_packet_filter_rule_t rule);
/**
* @brief Enable the packet filter.
* @param[in] filter_id: The filter id.
* @return 0 if success, otherwise return -1.
* @note The filter can be used only if it has been enabled.
*/
int wifi_enable_packet_filter(unsigned char filter_id);
/**
* @brief Disable the packet filter.
* @param[in] filter_id: The filter id.
* @return 0 if success, otherwise return -1.
*/
int wifi_disable_packet_filter(unsigned char filter_id);
/**
* @brief Remove the packet filter.
* @param[in] filter_id: The filter id.
* @return 0 if success, otherwise return -1.
*/
int wifi_remove_packet_filter(unsigned char filter_id);
#endif
/**
* @brief Get antenna infomation.
* @param[in] antenna: Points to store the antenna value gotten from driver, 0: main, 1: aux.
* @return 0 if success, otherwise return -1.
*/
#ifdef CONFIG_ANTENNA_DIVERSITY
int wifi_get_antenna_info(unsigned char *antenna);
#endif // #ifdef CONFIG_ANTENNA_DIVERSITY
void wifi_set_indicate_mgnt(int enable);
///@name Ameba1 Only
///@{
/**
* @brief enable AP sending QoS Null0 Data to poll Sta be alive
* @param[in] enabled: enabled can be set to 0,1.
* - 0 means enable.
* - 1 means disable.
* @return None
*/
void wifi_set_ap_polling_sta(__u8 enabled);
///@}
#ifdef __cplusplus
}
#endif
/*\@}*/
#endif // __WIFI_API_H
//----------------------------------------------------------------------------//

View file

@ -0,0 +1,258 @@
//----------------------------------------------------------------------------//
#include "wifi/wifi_ind.h"
#include "wifi/wifi_conf.h"
#include "osdep_service.h"
#include "platform_stdlib.h"
/******************************************************
* Constants
******************************************************/
#define WIFI_INDICATE_MSG 0
#define WIFI_MANAGER_STACKSIZE 1300
#define WIFI_MANAGER_PRIORITY (0) //Actual priority is 4 since calling rtw_create_task
#define WIFI_MANAGER_Q_SZ 8
#define WIFI_EVENT_MAX_ROW 3
/******************************************************
* Globals
******************************************************/
static event_list_elem_t event_callback_list[WIFI_EVENT_MAX][WIFI_EVENT_MAX_ROW];
#if CONFIG_WIFI_IND_USE_THREAD
static rtw_worker_thread_t wifi_worker_thread;
#endif
//----------------------------------------------------------------------------//
#if CONFIG_WIFI_IND_USE_THREAD
static rtw_result_t rtw_send_event_to_worker(int event_cmd, char *buf, int buf_len, int flags)
{
rtw_event_message_t message;
int i;
rtw_result_t ret = RTW_SUCCESS;
char *local_buf = NULL;
if(event_cmd >= WIFI_EVENT_MAX)
return RTW_BADARG;
for(i = 0; i < WIFI_EVENT_MAX_ROW; i++){
if(event_callback_list[event_cmd][i].handler == NULL)
continue;
message.function = (event_handler_t)event_callback_list[event_cmd][i].handler;
message.buf_len = buf_len;
if(buf_len){
local_buf = (char*)pvPortMalloc(buf_len);
if(local_buf == NULL)
return RTW_NOMEM;
memcpy(local_buf, buf, buf_len);
//printf("\n!!!!!Allocate %p(%d) for evcmd %d\n", local_buf, buf_len, event_cmd);
}
message.buf = local_buf;
message.flags = flags;
message.user_data = event_callback_list[event_cmd][i].handler_user_data;
ret = rtw_push_to_xqueue(&wifi_worker_thread.event_queue, &message, 0);
if(ret != RTW_SUCCESS){
if(local_buf){
printf("\r\nrtw_send_event_to_worker: enqueue cmd %d failed and free %p(%d)\n", event_cmd, local_buf, buf_len);
vPortFree(local_buf);
}
break;
}
}
return ret;
}
#else
static rtw_result_t rtw_indicate_event_handle(int event_cmd, char *buf, int buf_len, int flags)
{
rtw_event_handler_t handle = NULL;
int i;
if(event_cmd >= WIFI_EVENT_MAX)
return RTW_BADARG;
for(i = 0; i < WIFI_EVENT_MAX_ROW; i++){
handle = event_callback_list[event_cmd][i].handler;
if(handle == NULL)
continue;
handle(buf, buf_len, flags, event_callback_list[event_cmd][i].handler_user_data);
}
return RTW_SUCCESS;
}
#endif
void wifi_indication( rtw_event_indicate_t event, char *buf, int buf_len, int flags)
{
//
// If upper layer application triggers additional operations on receiving of wext_wlan_indicate,
// please strictly check current stack size usage (by using uxTaskGetStackHighWaterMark() )
// , and tries not to share the same stack with wlan driver if remaining stack space is
// not available for the following operations.
// ex: using semaphore to notice another thread.
switch(event)
{
case WIFI_EVENT_DISCONNECT:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r %s():Disconnection indication received", __FUNCTION__);
#endif
break;
case WIFI_EVENT_CONNECT:
// For WPA/WPA2 mode, indication of connection does not mean data can be
// correctly transmitted or received. Data can be correctly transmitted or
// received only when 4-way handshake is done.
// Please check WIFI_EVENT_FOURWAY_HANDSHAKE_DONE event
#if(WIFI_INDICATE_MSG==1)
// Sample: return mac address
if(buf != NULL && buf_len == 6)
{
printf("\n\r%s():Connect indication received: %02x:%02x:%02x:%02x:%02x:%02x", __FUNCTION__,
buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]);
}
#endif
break;
case WIFI_EVENT_FOURWAY_HANDSHAKE_DONE:
#if(WIFI_INDICATE_MSG==1)
if(buf != NULL)
{
if(buf_len == strlen(IW_EXT_STR_FOURWAY_DONE))
printf("\n\r%s():%s", __FUNCTION__, buf);
}
#endif
break;
case WIFI_EVENT_SCAN_RESULT_REPORT:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_SCAN_RESULT_REPORT\n", __func__);
#endif
break;
case WIFI_EVENT_SCAN_DONE:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_SCAN_DONE\n", __func__);
#endif
break;
case WIFI_EVENT_RECONNECTION_FAIL:
#if(WIFI_INDICATE_MSG==1)
if(buf != NULL){
if(buf_len == strlen(IW_EXT_STR_RECONNECTION_FAIL))
printf("\n\r%s", buf);
}
#endif
break;
case WIFI_EVENT_NO_NETWORK:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_NO_NETWORK\n", __func__);
#endif
break;
case WIFI_EVENT_RX_MGNT:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_RX_MGNT\n", __func__);
#endif
break;
#if CONFIG_ENABLE_P2P
case WIFI_EVENT_SEND_ACTION_DONE:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_SEND_ACTION_DONE\n", __func__);
#endif
break;
#endif //CONFIG_ENABLE_P2P
case WIFI_EVENT_STA_ASSOC:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_STA_ASSOC\n", __func__);
#endif
break;
case WIFI_EVENT_STA_DISASSOC:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_STA_DISASSOC\n", __func__);
#endif
break;
#ifdef CONFIG_WPS
case WIFI_EVENT_STA_WPS_START:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_STA_WPS_START\n", __func__);
#endif
break;
case WIFI_EVENT_WPS_FINISH:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_WPS_FINISH\n", __func__);
#endif
break;
case WIFI_EVENT_EAPOL_RECVD:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_EAPOL_RECVD\n", __func__);
#endif
break;
#endif
case WIFI_EVENT_BEACON_AFTER_DHCP:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_BEACON_AFTER_DHCP\n", __func__);
#endif
break;
}
#if CONFIG_INIC_EN
inic_indicate_event(event, buf, buf_len, flags);
#endif//CONFIG_INIC_EN
#if CONFIG_WIFI_IND_USE_THREAD
rtw_send_event_to_worker(event, buf, buf_len, flags);
#else
rtw_indicate_event_handle(event, buf, buf_len, flags);
#endif
}
void wifi_reg_event_handler(unsigned int event_cmds, rtw_event_handler_t handler_func, void *handler_user_data)
{
int i = 0, j = 0;
if(event_cmds < WIFI_EVENT_MAX){
for(i=0; i < WIFI_EVENT_MAX_ROW; i++){
if(event_callback_list[event_cmds][i].handler == NULL){
for(j=0; j<WIFI_EVENT_MAX_ROW; j++){
if(event_callback_list[event_cmds][j].handler == handler_func){
return;
}
}
event_callback_list[event_cmds][i].handler = handler_func;
event_callback_list[event_cmds][i].handler_user_data = handler_user_data;
return;
}
}
}
}
void wifi_unreg_event_handler(unsigned int event_cmds, rtw_event_handler_t handler_func)
{
int i;
if(event_cmds < WIFI_EVENT_MAX){
for(i = 0; i < WIFI_EVENT_MAX_ROW; i++){
if(event_callback_list[event_cmds][i].handler == handler_func){
event_callback_list[event_cmds][i].handler = NULL;
event_callback_list[event_cmds][i].handler_user_data = NULL;
return;
}
}
}
}
void init_event_callback_list(){
memset(event_callback_list, 0, sizeof(event_callback_list));
}
int wifi_manager_init()
{
#if CONFIG_WIFI_IND_USE_THREAD
rtw_create_worker_thread(&wifi_worker_thread,
WIFI_MANAGER_PRIORITY,
WIFI_MANAGER_STACKSIZE,
WIFI_MANAGER_Q_SZ);
#endif
return 0;
}
void rtw_wifi_manager_deinit()
{
#if CONFIG_WIFI_IND_USE_THREAD
rtw_delete_worker_thread(&wifi_worker_thread);
#endif
}

View file

@ -0,0 +1,89 @@
/**
******************************************************************************
* @file wifi_ind.h
* @author
* @version
* @brief This file provides the functions related to event handler mechanism.
******************************************************************************
* @attention
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*
* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
******************************************************************************
*/
#ifndef _WIFI_INDICATE_H
#define _WIFI_INDICATE_H
/** @addtogroup nic NIC
* @ingroup wlan
* @brief NIC functions
* @{
*/
#include "wifi_conf.h"
typedef void (*rtw_event_handler_t)(char *buf, int buf_len, int flags, void* handler_user_data );
typedef struct
{
// rtw_event_indicate_t event_cmd;
rtw_event_handler_t handler;
void* handler_user_data;
} event_list_elem_t;
/**
* @brief Initialize the event callback list.
* @warning Please make sure this function has been invoked before
* using the event handler related mechanism.
* @param None
* @return None
*/
void init_event_callback_list(void);
/**
* @brief Wlan driver indicate event to upper layer through wifi_indication.
* @param[in] event: An event reported from driver to upper layer application. Please refer to rtw_event_indicate_t enum.
* @param[in] buf: If it is not NUL, buf is a pointer to the buffer for message string.
* @param[in] buf_len: The length of the buffer.
* @param[in] flags: Indicate some extra information, sometimes it is 0.
* @retval None
* @note If upper layer application triggers additional operations on receiving of wext_wlan_indicate,
* please strictly check current stack size usage (by using uxTaskGetStackHighWaterMark() ),
* and tries not to share the same stack with wlan driver if remaining stack space is not available
* for the following operations.
* ex: using semaphore to notice another thread instead of handing event directly in wifi_indication().
*/
extern void wifi_indication( rtw_event_indicate_t event, char *buf, int buf_len, int flags);
/**
* @brief Register the event listener.
* @param[in] event_cmds : The event command number indicated.
* @param[in] handler_func : the callback function which will
* receive and process the event.
* @param[in] handler_user_data : user specific data that will be
* passed directly to the callback function.
* @return RTW_SUCCESS : if successfully registers the event.
* @return RTW_ERROR : if an error occurred.
* @note Set the same event_cmds with empty handler_func will
* unregister the event_cmds.
*/
extern void wifi_reg_event_handler(unsigned int event_cmds, rtw_event_handler_t handler_func, void *handler_user_data);
/**
* @brief Un-register the event listener.
* @param[in] event_cmds : The event command number indicated.
* @param[in] handler_func : the callback function which will
* receive and process the event.
*
* @return RTW_SUCCESS : if successfully un-registers the event .
* @return RTW_ERROR : if an error occurred.
*/
extern void wifi_unreg_event_handler(unsigned int event_cmds, rtw_event_handler_t handler_func);
/*\@}*/
#endif //_WIFI_INDICATE_H

View file

@ -0,0 +1,461 @@
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "tcpip.h"
#include "wifi/wifi_conf.h"
#ifndef CONFIG_WLAN
#define CONFIG_WLAN 1
#endif
#if CONFIG_WLAN
#include <platform/platform_stdlib.h>
// Add extra interfaces to make release sdk able to determine promisc API linking
void promisc_deinit(void *padapter)
{
#ifdef CONFIG_PROMISC
_promisc_deinit(padapter);
#endif
}
int promisc_recv_func(void *padapter, void *rframe)
{
// Never reach here if not define CONFIG_PROMISC
#ifdef CONFIG_PROMISC
return _promisc_recv_func(padapter, rframe);
#else
return 0;
#endif
}
int promisc_set(rtw_rcr_level_t enabled, void (*callback)(unsigned char*, unsigned int, void*), unsigned char len_used)
{
#ifdef CONFIG_PROMISC
return _promisc_set(enabled, callback, len_used);
#else
return -1;
#endif
}
unsigned char is_promisc_enabled(void)
{
#ifdef CONFIG_PROMISC
return _is_promisc_enabled();
#else
return 0;
#endif
}
int promisc_get_fixed_channel(void *fixed_bssid, u8 *ssid, int *ssid_length)
{
#ifdef CONFIG_PROMISC
return _promisc_get_fixed_channel(fixed_bssid, ssid, ssid_length);
#else
return 0;
#endif
}
// End of Add extra interfaces
struct eth_frame {
struct eth_frame *prev;
struct eth_frame *next;
unsigned char da[6];
unsigned char sa[6];
unsigned int len;
unsigned char type;
signed char rssi;
};
#if CONFIG_INIC_CMD_RSP
#if defined(__IAR_SYSTEMS_ICC__)||defined (__GNUC__)
#pragma pack(1)
#endif
struct inic_eth_frame {
unsigned char da[6];
unsigned char sa[6];
unsigned int len;
unsigned char type;
};
#if defined(__IAR_SYSTEMS_ICC__)||defined (__GNUC__)
#pragma pack()
#endif
static struct inic_eth_frame *inic_frame, *inic_frame_tail = NULL;
static int inic_frame_cnt = 0;
#define MAX_INIC_FRAME_NUM 50 //maximum packets for each channel
extern void inic_c2h_msg(const char *atcmd, char status, char *msg, u16 msg_len);
#endif
struct eth_buffer {
struct eth_frame *head;
struct eth_frame *tail;
};
static struct eth_buffer eth_buffer;
#ifdef CONFIG_PROMISC
#define MAX_PACKET_FILTER_INFO 5
#define FILTER_ID_INIT_VALUE 10
rtw_packet_filter_info_t paff_array[MAX_PACKET_FILTER_INFO]={0, 0, 0, 0, 0};
static u8 packet_filter_enable_num = 0;
void promisc_init_packet_filter()
{
int i = 0;
for(i=0; i<MAX_PACKET_FILTER_INFO; i++){
paff_array[i].filter_id = FILTER_ID_INIT_VALUE;
paff_array[i].enable = 0;
paff_array[i].patt.mask_size = 0;
paff_array[i].rule = RTW_POSITIVE_MATCHING;
paff_array[i].patt.mask = NULL;
paff_array[i].patt.pattern = NULL;
}
packet_filter_enable_num = 0;
}
int promisc_add_packet_filter(u8 filter_id, rtw_packet_filter_pattern_t *patt, rtw_packet_filter_rule_t rule)
{
int i = 0;
while(i < MAX_PACKET_FILTER_INFO){
if(paff_array[i].filter_id == FILTER_ID_INIT_VALUE){
break;
}
i++;
}
if(i == MAX_PACKET_FILTER_INFO)
return -1;
paff_array[i].filter_id = filter_id;
paff_array[i].patt.offset= patt->offset;
paff_array[i].patt.mask_size = patt->mask_size;
paff_array[i].patt.mask = pvPortMalloc(patt->mask_size);
memcpy(paff_array[i].patt.mask, patt->mask, patt->mask_size);
paff_array[i].patt.pattern= pvPortMalloc(patt->mask_size);
memcpy(paff_array[i].patt.pattern, patt->pattern, patt->mask_size);
paff_array[i].rule = rule;
paff_array[i].enable = 0;
return 0;
}
int promisc_enable_packet_filter(u8 filter_id)
{
int i = 0;
while(i < MAX_PACKET_FILTER_INFO){
if(paff_array[i].filter_id == filter_id)
break;
i++;
}
if(i == MAX_PACKET_FILTER_INFO)
return -1;
paff_array[i].enable = 1;
packet_filter_enable_num++;
return 0;
}
int promisc_disable_packet_filter(u8 filter_id)
{
int i = 0;
while(i < MAX_PACKET_FILTER_INFO){
if(paff_array[i].filter_id == filter_id)
break;
i++;
}
if(i == MAX_PACKET_FILTER_INFO)
return -1;
paff_array[i].enable = 0;
packet_filter_enable_num--;
return 0;
}
int promisc_remove_packet_filter(u8 filter_id)
{
int i = 0;
while(i < MAX_PACKET_FILTER_INFO){
if(paff_array[i].filter_id == filter_id)
break;
i++;
}
if(i == MAX_PACKET_FILTER_INFO)
return -1;
paff_array[i].filter_id = FILTER_ID_INIT_VALUE;
paff_array[i].enable = 0;
paff_array[i].patt.mask_size = 0;
paff_array[i].rule = 0;
if(paff_array[i].patt.mask){
vPortFree(paff_array[i].patt.mask);
paff_array[i].patt.mask = NULL;
}
if(paff_array[i].patt.pattern){
vPortFree(paff_array[i].patt.pattern);
paff_array[i].patt.pattern = NULL;
}
return 0;
}
#endif
/* Make callback simple to prevent latency to wlan rx when promiscuous mode */
static void promisc_callback(unsigned char *buf, unsigned int len, void* userdata)
{
struct eth_frame *frame = (struct eth_frame *) pvPortMalloc(sizeof(struct eth_frame));
if(frame) {
frame->prev = NULL;
frame->next = NULL;
memcpy(frame->da, buf, 6);
memcpy(frame->sa, buf+6, 6);
frame->len = len;
frame->rssi = ((ieee80211_frame_info_t *)userdata)->rssi;
taskENTER_CRITICAL();
if(eth_buffer.tail) {
eth_buffer.tail->next = frame;
frame->prev = eth_buffer.tail;
eth_buffer.tail = frame;
}
else {
eth_buffer.head = frame;
eth_buffer.tail = frame;
}
taskEXIT_CRITICAL();
}
}
struct eth_frame* retrieve_frame(void)
{
struct eth_frame *frame = NULL;
taskENTER_CRITICAL();
if(eth_buffer.head) {
frame = eth_buffer.head;
if(eth_buffer.head->next) {
eth_buffer.head = eth_buffer.head->next;
eth_buffer.head->prev = NULL;
}
else {
eth_buffer.head = NULL;
eth_buffer.tail = NULL;
}
}
taskEXIT_CRITICAL();
return frame;
}
static void promisc_test(int duration, unsigned char len_used)
{
int ch;
unsigned int start_time;
struct eth_frame *frame;
eth_buffer.head = NULL;
eth_buffer.tail = NULL;
wifi_enter_promisc_mode();
wifi_set_promisc(RTW_PROMISC_ENABLE, promisc_callback, len_used);
for(ch = 1; ch <= 13; ch ++) {
if(wifi_set_channel(ch) == 0)
printf("\n\n\rSwitch to channel(%d)", ch);
start_time = xTaskGetTickCount();
while(1) {
unsigned int current_time = xTaskGetTickCount();
if((current_time - start_time) < (duration * configTICK_RATE_HZ)) {
frame = retrieve_frame();
if(frame) {
int i;
printf("\n\rDA:");
for(i = 0; i < 6; i ++)
printf(" %02x", frame->da[i]);
printf(", SA:");
for(i = 0; i < 6; i ++)
printf(" %02x", frame->sa[i]);
printf(", len=%d", frame->len);
printf(", RSSI=%d", frame->rssi);
#if CONFIG_INIC_CMD_RSP
if(inic_frame_tail){
if(inic_frame_cnt < MAX_INIC_FRAME_NUM){
memcpy(inic_frame_tail->da, frame->da, 6);
memcpy(inic_frame_tail->sa, frame->sa, 6);
inic_frame_tail->len = frame->len;
inic_frame_tail++;
inic_frame_cnt++;
}
}
#endif
vPortFree((void *) frame);
}
else
vTaskDelay(1); //delay 1 tick
}
else
break;
}
#if CONFIG_INIC_CMD_RSP
if(inic_frame){
inic_c2h_msg("ATWM", RTW_SUCCESS, (char *)inic_frame, sizeof(struct inic_eth_frame)*inic_frame_cnt);
memset(inic_frame, '\0', sizeof(struct inic_eth_frame)*MAX_INIC_FRAME_NUM);
inic_frame_tail = inic_frame;
inic_frame_cnt = 0;
rtw_msleep_os(10);
}
#endif
}
wifi_set_promisc(RTW_PROMISC_DISABLE, NULL, 0);
while((frame = retrieve_frame()) != NULL)
vPortFree((void *) frame);
}
static void promisc_callback_all(unsigned char *buf, unsigned int len, void* userdata)
{
struct eth_frame *frame = (struct eth_frame *) pvPortMalloc(sizeof(struct eth_frame));
if(frame) {
frame->prev = NULL;
frame->next = NULL;
memcpy(frame->da, buf+4, 6);
memcpy(frame->sa, buf+10, 6);
frame->len = len;
/*
* type is the first byte of Frame Control Field of 802.11 frame
* If the from/to ds information is needed, type could be reused as follows:
* frame->type = ((((ieee80211_frame_info_t *)userdata)->i_fc & 0x0100) == 0x0100) ? 2 : 1;
* 1: from ds; 2: to ds
*/
frame->type = *buf;
frame->rssi = ((ieee80211_frame_info_t *)userdata)->rssi;
taskENTER_CRITICAL();
if(eth_buffer.tail) {
eth_buffer.tail->next = frame;
frame->prev = eth_buffer.tail;
eth_buffer.tail = frame;
}
else {
eth_buffer.head = frame;
eth_buffer.tail = frame;
}
taskEXIT_CRITICAL();
}
}
static void promisc_test_all(int duration, unsigned char len_used)
{
int ch;
unsigned int start_time;
struct eth_frame *frame;
eth_buffer.head = NULL;
eth_buffer.tail = NULL;
wifi_enter_promisc_mode();
wifi_set_promisc(RTW_PROMISC_ENABLE_2, promisc_callback_all, len_used);
for(ch = 1; ch <= 13; ch ++) {
if(wifi_set_channel(ch) == 0)
printf("\n\n\rSwitch to channel(%d)", ch);
start_time = xTaskGetTickCount();
while(1) {
unsigned int current_time = xTaskGetTickCount();
if((current_time - start_time) < (duration * configTICK_RATE_HZ)) {
frame = retrieve_frame();
if(frame) {
int i;
printf("\n\rTYPE: 0x%x, ", frame->type);
printf("DA:");
for(i = 0; i < 6; i ++)
printf(" %02x", frame->da[i]);
printf(", SA:");
for(i = 0; i < 6; i ++)
printf(" %02x", frame->sa[i]);
printf(", len=%d", frame->len);
printf(", RSSI=%d", frame->rssi);
#if CONFIG_INIC_CMD_RSP
if(inic_frame_tail){
if(inic_frame_cnt < MAX_INIC_FRAME_NUM){
memcpy(inic_frame_tail->da, frame->da, 6);
memcpy(inic_frame_tail->sa, frame->sa, 6);
inic_frame_tail->len = frame->len;
inic_frame_tail->type = frame->type;
inic_frame_tail++;
inic_frame_cnt++;
}
}
#endif
vPortFree((void *) frame);
}
else
vTaskDelay(1); //delay 1 tick
}
else
break;
}
#if CONFIG_INIC_CMD_RSP
if(inic_frame){
inic_c2h_msg("ATWM", RTW_SUCCESS, (char *)inic_frame, sizeof(struct inic_eth_frame)*inic_frame_cnt);
memset(inic_frame, '\0', sizeof(struct inic_eth_frame)*MAX_INIC_FRAME_NUM);
inic_frame_tail = inic_frame;
inic_frame_cnt = 0;
rtw_msleep_os(10);
}
#endif
}
wifi_set_promisc(RTW_PROMISC_DISABLE, NULL, 0);
while((frame = retrieve_frame()) != NULL)
vPortFree((void *) frame);
}
void cmd_promisc(int argc, char **argv)
{
int duration;
#if CONFIG_INIC_CMD_RSP
inic_frame_tail = inic_frame = pvPortMalloc(sizeof(struct inic_eth_frame)*MAX_INIC_FRAME_NUM);
if(inic_frame == NULL){
inic_c2h_msg("ATWM", RTW_BUFFER_UNAVAILABLE_TEMPORARY, NULL, 0);
return;
}
#endif
#ifdef CONFIG_PROMISC
wifi_init_packet_filter();
#endif
if((argc == 2) && ((duration = atoi(argv[1])) > 0))
//promisc_test(duration, 0);
promisc_test_all(duration, 0);
else if((argc == 3) && ((duration = atoi(argv[1])) > 0) && (strcmp(argv[2], "with_len") == 0))
promisc_test(duration, 1);
else
printf("\n\rUsage: %s DURATION_SECONDS [with_len]", argv[0]);
#if CONFIG_INIC_CMD_RSP
if(inic_frame)
vPortFree(inic_frame);
inic_frame_tail = NULL;
inic_frame_cnt = 0;
#endif
}
#endif //#if CONFIG_WLAN

View file

@ -0,0 +1,20 @@
#ifndef __WIFI_SIMPLE_CONFIG_H
#define __WIFI_SIMPLE_CONFIG_H
/*****************************wifi_simple_config.h****************************/
enum sc_result {
SC_ERROR = -1, /* default error code*/
SC_NO_CONTROLLER_FOUND = 1, /* cannot get sta(controller) in the air which starts a simple config session */
SC_CONTROLLER_INFO_PARSE_FAIL, /* cannot parse the sta's info */
SC_TARGET_CHANNEL_SCAN_FAIL, /* cannot scan the target channel */
SC_JOIN_BSS_FAIL, /* fail to connect to target ap */
SC_DHCP_FAIL, /* fail to get ip address from target ap */
/* fail to create udp socket to send info to controller. note that client isolation
must be turned off in ap. we cannot know if ap has configured this */
SC_UDP_SOCKET_CREATE_FAIL,
SC_TERMINATE,
SC_SUCCESS, /* default success code */
};
int SC_send_simple_config_ack(u8 round);
#endif //__WIFI_SIMPLE_CONFIG_H

View file

@ -0,0 +1,117 @@
#ifndef __SIMPLE_CONFIG_H__
#define __SIMPLE_CONFIG_H__
#ifdef __cplusplus
extern "C" {
#endif
/* This macro means user take simple config
* lib to another platform such as linux, and
* have no rom crypto libs of simple config,
* so we take simple_config_crypto as a sw lib
* This macro is used by Realtek internal to generate simple config lib
* Please delete this macro after generation.
*/
#define SIMPLE_CONFIG_PLATFORM_LIB 0
#include "platform_opts.h"
#include "autoconf.h"
/* platform related settings */
#if (defined(CONFIG_PLATFORM_8195A)|| defined(CONFIG_PLATFORM_8711B))
#undef u32
#undef s32
#undef u8
#undef s8
#undef u16
#undef s16
typedef unsigned int u32;
typedef signed int s32;
typedef unsigned char u8;
typedef char s8;
typedef unsigned short int u16;
typedef signed short int s16;
#else
#include "osdep_service.h"
#endif
typedef int (*simple_config_printf_fn) (char const * fmt, ...);
typedef void* (*simple_config_memset_fn) (void *dst0, s32 Val, u32 length);
typedef void* (*simple_config_memcpy_fn) ( void *s1, const void *s2, u32 n );
typedef u32 (*simple_config_strlen_fn) (const char *s);
typedef char * (*simple_config_strcpy_fn) (char *dest, const char *src);
typedef void (*simple_config_free_fn) (u8 *pbuf, u32 sz);
typedef u8* (*simple_config_zmalloc_fn) (u32 sz);
typedef u8* (*simple_config_malloc_fn) (u32 sz);
typedef int (*simple_config_memcmp_fn) (const void *av, const void *bv, u32 len);
typedef u32 (*simple_config_ntohl_fn)(u32 x);
struct simple_config_lib_config {
simple_config_printf_fn printf;
simple_config_memset_fn memset;
simple_config_memcpy_fn memcpy;
simple_config_strlen_fn strlen;
simple_config_strcpy_fn strcpy;
simple_config_free_fn free;
simple_config_zmalloc_fn zmalloc;
simple_config_malloc_fn malloc;
simple_config_memcmp_fn memcmp;
simple_config_ntohl_fn _ntohl;
int *is_promisc_callback_unlock;
};
#pragma pack(1)
struct rtk_test_sc {
/* API exposed to user */
unsigned char ssid[32];
unsigned char password[65];
unsigned int ip_addr;
};
// for softAP mode
typedef enum {
SOFTAP_ERROR = -1,
SOFTAP_INIT,
SOFTAP_RECV_A,
SOFTAP_HANDSHAKE_DONE,
SOFTAP_DECODE_SUCCESS,
} SC_softAP_status;
#pragma pack(1)
typedef struct _SC_softAP_decode_ctx {
u8 nonceA[16];
u8 nonceB[32];
u8 mac[6];
SC_softAP_status softAP_decode_status;
} SC_softAP_decode_ctx;
/* expose data */
extern s32 is_promisc_callback_unlock;
extern u8 g_bssid[6];
extern u8 get_channel_flag;
extern u8 g_security_mode;
/* expose API */
extern s32 rtk_sc_init(char *custom_pin_code, struct simple_config_lib_config* config);
extern int rtl_pre_parse(u8 *mac_addr, u8 *buf, void *userdata, u8 **da, u8 **sa, unsigned int *len);
extern s32 rtk_start_parse_packet(u8 *da, u8 *sa, s32 len, void * user_data, void *backup_sc);
extern SC_softAP_status softAP_simpleConfig_parse(unsigned char *buf, int len, void *backup_sc_ctx, void *psoftAP_ctx);
extern void rtk_restart_simple_config(void);
extern void rtk_sc_deinit();
extern void wifi_enter_promisc_mode();
extern void whc_fix_channel();
extern void whc_unfix_channel();
#ifdef __cplusplus
}
#endif
#endif /* __SIMPLE_CONFIG_H__*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,77 @@
#ifndef _UTIL_H
#define _UTIL_H
#include <wireless.h>
#include <wlan_intf.h>
#include <wifi_constants.h>
#include "wifi_structures.h"
#ifdef __cplusplus
extern "C" {
#endif
int wext_get_ssid(const char *ifname, __u8 *ssid);
int wext_set_ssid(const char *ifname, const __u8 *ssid, __u16 ssid_len);
int wext_set_bssid(const char *ifname, const __u8 *bssid);
int wext_get_bssid(const char *ifname, __u8 *bssid);
int wext_set_auth_param(const char *ifname, __u16 idx, __u32 value);
int wext_set_key_ext(const char *ifname, __u16 alg, const __u8 *addr, int key_idx, int set_tx, const __u8 *seq, __u16 seq_len, __u8 *key, __u16 key_len);
int wext_get_enc_ext(const char *ifname, __u16 *alg, __u8 *key_idx, __u8 *passphrase);
int wext_set_passphrase(const char *ifname, const __u8 *passphrase, __u16 passphrase_len);
int wext_get_passphrase(const char *ifname, __u8 *passphrase);
int wext_set_mode(const char *ifname, int mode);
int wext_get_mode(const char *ifname, int *mode);
int wext_set_ap_ssid(const char *ifname, const __u8 *ssid, __u16 ssid_len);
int wext_set_country(const char *ifname, rtw_country_code_t country_code);
int wext_get_rssi(const char *ifname, int *rssi);
int wext_set_channel(const char *ifname, __u8 ch);
int wext_get_channel(const char *ifname, __u8 *ch);
int wext_register_multicast_address(const char *ifname, rtw_mac_t *mac);
int wext_unregister_multicast_address(const char *ifname, rtw_mac_t *mac);
int wext_set_scan(const char *ifname, char *buf, __u16 buf_len, __u16 flags);
int wext_get_scan(const char *ifname, char *buf, __u16 buf_len);
int wext_set_mac_address(const char *ifname, char * mac);
int wext_get_mac_address(const char *ifname, char * mac);
int wext_enable_powersave(const char *ifname, __u8 lps_mode, __u8 ips_mode);
int wext_disable_powersave(const char *ifname);
int wext_set_tdma_param(const char *ifname, __u8 slot_period, __u8 rfon_period_len_1, __u8 rfon_period_len_2, __u8 rfon_period_len_3);
int wext_set_lps_dtim(const char *ifname, __u8 lps_dtim);
int wext_get_lps_dtim(const char *ifname, __u8 *lps_dtim);
int wext_get_tx_power(const char *ifname, __u8 *poweridx);
int wext_set_txpower(const char *ifname, int poweridx);
int wext_get_associated_client_list(const char *ifname, void * client_list_buffer, __u16 buffer_length);
int wext_get_ap_info(const char *ifname, rtw_bss_info_t * ap_info, rtw_security_t* security);
int wext_mp_command(const char *ifname, char *cmd, int show_msg);
int wext_private_command(const char *ifname, char *cmd, int show_msg);
int wext_private_command_with_retval(const char *ifname, char *cmd, char *ret_buf, int ret_len);
void wext_wlan_indicate(unsigned int cmd, union iwreq_data *wrqu, char *extra);
int wext_set_pscan_channel(const char *ifname, __u8 *ch, __u8 *pscan_config, __u8 length);
int wext_set_autoreconnect(const char *ifname, __u8 mode, __u8 retry_times, __u16 timeout);
int wext_get_autoreconnect(const char *ifname, __u8 *mode);
int wext_set_adaptivity(rtw_adaptivity_mode_t adaptivity_mode);
int wext_set_adaptivity_th_l2h_ini(__u8 l2h_threshold);
int wext_get_auto_chl(const char *ifname, unsigned char *channel_set, unsigned char channel_num);
int wext_set_sta_num(unsigned char ap_sta_num);
int wext_del_station(const char *ifname, unsigned char* hwaddr);
int wext_init_mac_filter(void);
int wext_deinit_mac_filter(void);
int wext_add_mac_filter(unsigned char* hwaddr);
int wext_del_mac_filter(unsigned char* hwaddr);
void wext_set_indicate_mgnt(int enable);
#ifdef CONFIG_CUSTOM_IE
int wext_add_custom_ie(const char *ifname, void * cus_ie, int ie_num);
int wext_update_custom_ie(const char *ifname, void * cus_ie, int ie_index);
int wext_del_custom_ie(const char *ifname);
#endif
#define wext_handshake_done rltk_wlan_handshake_done
int wext_send_mgnt(const char *ifname, char *buf, __u16 buf_len, __u16 flags);
int wext_send_eapol(const char *ifname, char *buf, __u16 buf_len, __u16 flags);
int wext_set_gen_ie(const char *ifname, char *buf, __u16 buf_len, __u16 flags);
#ifdef __cplusplus
}
#endif
#endif /* _UTIL_H */

View file

@ -0,0 +1,852 @@
/*******************************************************************************
* Copyright (c) 2014, 2015 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Allan Stockdill-Mander/Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "MQTTClient.h"
const char * const msg_types_str[]=
{
"Reserved",
"CONNECT",
"CONNACK",
"PUBLISH",
"PUBACK",
"PUBREC",
"PUBREL",
"PUBCOMP",
"SUBSCRIBE",
"SUBACK",
"UNSUBSCRIBE",
"UNSUBACK",
"PINGREQ",
"PINGRESP",
"DISCONNECT",
"Reserved"
};
const char * const mqtt_status_str[]=
{
"MQTT_START",
"MQTT_CONNECT",
"MQTT_SUBTOPIC",
"MQTT_RUNNING"
};
static void NewMessageData(MessageData* md, MQTTString* aTopicName, MQTTMessage* aMessage) {
md->topicName = aTopicName;
md->message = aMessage;
}
static int getNextPacketId(MQTTClient *c) {
return c->next_packetid = (c->next_packetid == MAX_PACKET_ID) ? 1 : c->next_packetid + 1;
}
static int sendPacket(MQTTClient* c, int length, Timer* timer)
{
int rc = FAILURE,
sent = 0;
while (sent < length && !TimerIsExpired(timer))
{
rc = c->ipstack->mqttwrite(c->ipstack, &c->buf[sent], length, TimerLeftMS(timer));
if (rc < 0) // there was an error writing the data
break;
sent += rc;
}
if (sent == length)
{
TimerCountdown(&c->ping_timer, c->keepAliveInterval); // record the fact that we have successfully sent the packet
rc = SUCCESS;
}
else{
rc = FAILURE;
mqtt_printf(MQTT_DEBUG, "Send packet failed");
}
if (c->ipstack->my_socket < 0) {
c->isconnected = 0;
}
return rc;
}
void MQTTClientInit(MQTTClient* c, Network* network, unsigned int command_timeout_ms,
unsigned char* sendbuf, size_t sendbuf_size, unsigned char* readbuf, size_t readbuf_size)
{
int i;
c->ipstack = network;
for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
c->messageHandlers[i].topicFilter = 0;
c->command_timeout_ms = command_timeout_ms;
c->buf = sendbuf;
c->buf_size = sendbuf_size;
c->readbuf = readbuf;
c->readbuf_size = readbuf_size;
c->isconnected = 0;
c->ping_outstanding = 0;
c->defaultMessageHandler = NULL;
c->next_packetid = 1;
c->ipstack->m2m_rxevent = 0;
c->mqttstatus = MQTT_START;
TimerInit(&c->cmd_timer);
TimerInit(&c->ping_timer);
}
static int decodePacket(MQTTClient* c, int* value, int timeout)
{
unsigned char i;
int multiplier = 1;
int len = 0;
const int MAX_NO_OF_REMAINING_LENGTH_BYTES = 4;
*value = 0;
do
{
int rc = MQTTPACKET_READ_ERROR;
if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)
{
rc = MQTTPACKET_READ_ERROR; /* bad data */
goto exit;
}
rc = c->ipstack->mqttread(c->ipstack, &i, 1, timeout);
if (rc != 1)
goto exit;
*value += (i & 127) * multiplier;
multiplier *= 128;
} while ((i & 128) != 0);
exit:
return len;
}
static int readPacket(MQTTClient* c, Timer* timer)
{
int rc = FAILURE;
MQTTHeader header = {0};
int len = 0;
int rem_len = 0;
/* 1. read the header byte. This has the packet type in it */
if (c->ipstack->mqttread(c->ipstack, c->readbuf, 1, TimerLeftMS(timer)) != 1){
mqtt_printf(MQTT_MSGDUMP, "read packet header failed");
goto exit;
}
len = 1;
/* 2. read the remaining length. This is variable in itself */
decodePacket(c, &rem_len, TimerLeftMS(timer));
len += MQTTPacket_encode(c->readbuf + 1, rem_len); /* put the original remaining length back into the buffer */
if(len + rem_len > c->readbuf_size){
mqtt_printf(MQTT_WARNING, "rem_len = %d, read buffer will overflow", rem_len);
rc = BUFFER_OVERFLOW;
goto exit;
}
/* 3. read the rest of the buffer using a callback to supply the rest of the data */
if (rem_len > 0 && (c->ipstack->mqttread(c->ipstack, c->readbuf + len, rem_len, TimerLeftMS(timer)) != rem_len)){
mqtt_printf(MQTT_MSGDUMP, "read the rest of the data failed");
goto exit;
}
header.byte = c->readbuf[0];
rc = header.bits.type;
exit:
if (c->ipstack->my_socket < 0) {
c->isconnected = 0;
}
return rc;
}
// assume topic filter and name is in correct format
// # can only be at end
// + and # can only be next to separator
static char isTopicMatched(char* topicFilter, MQTTString* topicName)
{
char* curf = topicFilter;
char* curn = topicName->lenstring.data;
char* curn_end = curn + topicName->lenstring.len;
while (*curf && curn < curn_end)
{
if (*curn == '/' && *curf != '/')
break;
if (*curf != '+' && *curf != '#' && *curf != *curn)
break;
if (*curf == '+')
{ // skip until we meet the next separator, or end of string
char* nextpos = curn + 1;
while (nextpos < curn_end && *nextpos != '/')
nextpos = ++curn + 1;
}
else if (*curf == '#')
curn = curn_end - 1; // skip until end of string
curf++;
curn++;
};
return (curn == curn_end) && (*curf == '\0');
}
int deliverMessage(MQTTClient* c, MQTTString* topicName, MQTTMessage* message)
{
int i;
int rc = FAILURE;
// we have to find the right message handler - indexed by topic
for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
{
if (c->messageHandlers[i].topicFilter != 0 && (MQTTPacket_equals(topicName, (char*)c->messageHandlers[i].topicFilter) ||
isTopicMatched((char*)c->messageHandlers[i].topicFilter, topicName)))
{
if (c->messageHandlers[i].fp != NULL)
{
MessageData md;
NewMessageData(&md, topicName, message);
c->messageHandlers[i].fp(&md);
rc = SUCCESS;
}
}
}
if (rc == FAILURE && c->defaultMessageHandler != NULL)
{
MessageData md;
NewMessageData(&md, topicName, message);
c->defaultMessageHandler(&md);
rc = SUCCESS;
}
return rc;
}
int keepalive(MQTTClient* c)
{
int rc = FAILURE;
if (c->keepAliveInterval == 0)
{
rc = SUCCESS;
goto exit;
}
if (TimerIsExpired(&c->ping_timer))
{
if (!c->ping_outstanding)
{
Timer timer;
TimerInit(&timer);
TimerCountdownMS(&timer, 1000);
int len = MQTTSerialize_pingreq(c->buf, c->buf_size);
if (len > 0 && (rc = sendPacket(c, len, &timer)) == SUCCESS) // send the ping packet
c->ping_outstanding = 1;
}
}
exit:
return rc;
}
int cycle(MQTTClient* c, Timer* timer)
{
// read the socket, see what work is due
unsigned short packet_type = readPacket(c, timer);
int len = 0, rc = SUCCESS;
if (packet_type == (unsigned short)BUFFER_OVERFLOW || packet_type == (unsigned short)FAILURE) {
rc = FAILURE;
goto exit;
}
mqtt_printf(MQTT_DEBUG, "Read packet type: %d", packet_type);
switch (packet_type)
{
case CONNACK:
case PUBACK:
case SUBACK:
break;
case PUBLISH:
{
MQTTString topicName;
MQTTMessage msg;
int intQoS;
if (MQTTDeserialize_publish(&msg.dup, &intQoS, &msg.retained, &msg.id, &topicName,
(unsigned char**)&msg.payload, (int*)&msg.payloadlen, c->readbuf, c->readbuf_size) != 1)
goto exit;
msg.qos = (enum QoS)intQoS;
deliverMessage(c, &topicName, &msg);
if (msg.qos != QOS0)
{
if (msg.qos == QOS1)
len = MQTTSerialize_ack(c->buf, c->buf_size, PUBACK, 0, msg.id);
else if (msg.qos == QOS2)
len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREC, 0, msg.id);
if (len <= 0)
rc = FAILURE;
else {
#if 1
sendPacket(c, len, timer);
#else
// it's odd that ACK PUB also need success
rc = sendPacket(c, len, timer);
#endif
}
if (rc == FAILURE)
goto exit; // there was a problem
}
break;
}
case PUBREC:
{
unsigned short mypacketid;
unsigned char dup, type;
if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
rc = FAILURE;
else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREL, 0, mypacketid)) <= 0)
rc = FAILURE;
else if ((rc = sendPacket(c, len, timer)) != SUCCESS) // send the PUBREL packet
rc = FAILURE; // there was a problem
if (rc == FAILURE)
goto exit; // there was a problem
break;
}
case PUBREL:
{
unsigned short mypacketid;
unsigned char dup, type;
if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
rc = FAILURE;
else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBCOMP, 0, mypacketid)) <= 0)
rc = FAILURE;
else if ((rc = sendPacket(c, len, timer)) != SUCCESS) // send the PUBREL packet
rc = FAILURE; // there was a problem
if (rc == FAILURE)
goto exit; // there was a problem
break;
}
case PUBCOMP:
break;
case PINGRESP:
c->ping_outstanding = 0;
break;
}
exit:
keepalive(c);
if (rc == SUCCESS)
rc = packet_type;
return rc;
}
int MQTTYield(MQTTClient* c, int timeout_ms)
{
int rc = SUCCESS;
Timer timer;
TimerInit(&timer);
TimerCountdownMS(&timer, timeout_ms);
do
{
if (cycle(c, &timer) == FAILURE)
{
rc = FAILURE;
break;
}
} while (!TimerIsExpired(&timer));
return rc;
}
int waitfor(MQTTClient* c, int packet_type, Timer* timer)
{
int rc = FAILURE;
do
{
if (TimerIsExpired(timer))
break; // we timed out
}
while ((rc = cycle(c, timer)) != packet_type);
return rc;
}
int MQTTConnect(MQTTClient* c, MQTTPacket_connectData* options)
{
Timer connect_timer;
int rc = FAILURE;
MQTTPacket_connectData default_options = MQTTPacket_connectData_initializer;
int len = 0;
if (c->isconnected) /* don't send connect packet again if we are already connected */
goto exit;
TimerInit(&connect_timer);
TimerCountdownMS(&connect_timer, c->command_timeout_ms);
if (options == 0)
options = &default_options; /* set default options if none were supplied */
c->keepAliveInterval = options->keepAliveInterval;
TimerCountdown(&c->ping_timer, c->keepAliveInterval);
if ((len = MQTTSerialize_connect(c->buf, c->buf_size, options)) <= 0)
goto exit;
if ((rc = sendPacket(c, len, &connect_timer)) != SUCCESS) // send the connect packet
goto exit; // there was a problem
#if defined(WAIT_FOR_ACK)
// this will be a blocking call, wait for the connack
if (waitfor(c, CONNACK, &connect_timer) == CONNACK)
{
unsigned char connack_rc = 255;
unsigned char sessionPresent = 0;
if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, c->readbuf, c->readbuf_size) == 1)
rc = connack_rc;
else
rc = FAILURE;
}
else{
mqtt_printf(MQTT_DEBUG, "Not received CONNACK");
rc = FAILURE;
}
#endif
exit:
if (rc == SUCCESS)
c->isconnected = 1;
return rc;
}
int MQTTSubscribe(MQTTClient* c, const char* topicFilter, enum QoS qos, messageHandler messageHandler)
{
int rc = FAILURE;
Timer timer;
int len = 0;
MQTTString topic = MQTTString_initializer;
topic.cstring = (char *)topicFilter;
if (!c->isconnected)
goto exit;
TimerInit(&timer);
TimerCountdownMS(&timer, c->command_timeout_ms);
len = MQTTSerialize_subscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic, (int*)&qos);
if (len <= 0)
goto exit;
if ((rc = sendPacket(c, len, &timer)) != SUCCESS) // send the subscribe packet
goto exit; // there was a problem
#if defined(WAIT_FOR_ACK)
if (waitfor(c, SUBACK, &timer) == SUBACK) // wait for suback
{
int count = 0, grantedQoS = -1;
unsigned short mypacketid;
if (MQTTDeserialize_suback(&mypacketid, 1, &count, &grantedQoS, c->readbuf, c->readbuf_size) == 1)
rc = grantedQoS; // 0, 1, 2 or 0x80
if (rc != 0x80)
{
int i;
for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
{
if (c->messageHandlers[i].topicFilter == topicFilter)
{
rc = 0;
goto exit; //already subscribed
}
}
for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
{
if (c->messageHandlers[i].topicFilter == 0)
{
c->messageHandlers[i].topicFilter = topicFilter;
c->messageHandlers[i].fp = messageHandler;
rc = 0;
break;
}
}
}
}
else
rc = FAILURE;
#endif
exit:
return rc;
}
int MQTTUnsubscribe(MQTTClient* c, const char* topicFilter)
{
int rc = FAILURE;
Timer timer;
MQTTString topic = MQTTString_initializer;
topic.cstring = (char *)topicFilter;
int len = 0;
if (!c->isconnected)
goto exit;
TimerInit(&timer);
TimerCountdownMS(&timer, c->command_timeout_ms);
if ((len = MQTTSerialize_unsubscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic)) <= 0)
goto exit;
if ((rc = sendPacket(c, len, &timer)) != SUCCESS) // send the subscribe packet
goto exit; // there was a problem
#if defined(WAIT_FOR_ACK)
if (waitfor(c, UNSUBACK, &timer) == UNSUBACK)
{
unsigned short mypacketid; // should be the same as the packetid above
if (MQTTDeserialize_unsuback(&mypacketid, c->readbuf, c->readbuf_size) == 1)
rc = 0;
int i;
for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
{
if (c->messageHandlers[i].topicFilter == topicFilter)
{
c->messageHandlers[i].topicFilter = 0;
c->messageHandlers[i].fp = NULL;
}
}
}
else
rc = FAILURE;
#endif
exit:
return rc;
}
int MQTTPublish(MQTTClient* c, const char* topicName, MQTTMessage* message)
{
int rc = FAILURE;
Timer timer;
MQTTString topic = MQTTString_initializer;
topic.cstring = (char *)topicName;
int len = 0;
if (!c->isconnected)
goto exit;
TimerInit(&timer);
TimerCountdownMS(&timer, c->command_timeout_ms);
if (message->qos == QOS1 || message->qos == QOS2)
message->id = getNextPacketId(c);
len = MQTTSerialize_publish(c->buf, c->buf_size, 0, message->qos, message->retained, message->id,
topic, (unsigned char*)message->payload, message->payloadlen);
if (len <= 0)
goto exit;
if ((rc = sendPacket(c, len, &timer)) != SUCCESS) // send the subscribe packet
goto exit; // there was a problem
#if defined(WAIT_FOR_ACK)
if (message->qos == QOS1)
{
if (waitfor(c, PUBACK, &timer) == PUBACK)
{
unsigned short mypacketid;
unsigned char dup, type;
if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
rc = FAILURE;
}
else{
rc = FAILURE;
mqtt_printf(MQTT_DEBUG, "Not received PUBACK");
}
}
else if (message->qos == QOS2)
{
if (waitfor(c, PUBCOMP, &timer) == PUBCOMP)
{
unsigned short mypacketid;
unsigned char dup, type;
if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
rc = FAILURE;
}
else{
rc = FAILURE;
mqtt_printf(MQTT_DEBUG, "Not received PUBCOMP");
}
}
#endif
exit:
return rc;
}
int MQTTDisconnect(MQTTClient* c)
{
int rc = FAILURE;
Timer timer; // we might wait for incomplete incoming publishes to complete
int len = 0;
TimerInit(&timer);
TimerCountdownMS(&timer, c->command_timeout_ms);
len = MQTTSerialize_disconnect(c->buf, c->buf_size);
if (len > 0)
rc = sendPacket(c, len, &timer); // send the disconnect packet
c->isconnected = 0;
return rc;
}
#if defined(MQTT_TASK)
void MQTTSetStatus(MQTTClient* c, int mqttstatus)
{
c->mqttstatus = mqttstatus;
mqtt_printf(MQTT_INFO, "Set mqtt status to %s", mqtt_status_str[mqttstatus]);
}
int MQTTDataHandle(MQTTClient* c, fd_set *readfd, MQTTPacket_connectData *connectData, messageHandler messageHandler, char* address, char* topic)
{
short packet_type = 0;
int rc = 0;
int mqttstatus = c->mqttstatus;
int mqtt_rxevent = 0;
int mqtt_fd = c->ipstack->my_socket;
mqtt_rxevent = (mqtt_fd >= 0) ? FD_ISSET( mqtt_fd, readfd) : 0;
if(mqttstatus == MQTT_START) {
mqtt_printf(MQTT_INFO, "MQTT start");
if(c->isconnected){
c->isconnected = 0;
}
mqtt_printf(MQTT_INFO, "Connect Network \"%s\"", address);
if((rc = NetworkConnect(c->ipstack, address, 1883)) != 0){
mqtt_printf(MQTT_INFO, "Return code from network connect is %d\n", rc);
goto exit;
}
mqtt_printf(MQTT_INFO, "\"%s\" Connected", address);
mqtt_printf(MQTT_INFO, "Start MQTT connection");
TimerInit(&c->cmd_timer);
TimerCountdownMS(&c->cmd_timer, c->command_timeout_ms);
if ((rc = MQTTConnect(c, connectData)) != 0){
mqtt_printf(MQTT_INFO, "Return code from MQTT connect is %d\n", rc);
goto exit;
}
MQTTSetStatus(c, MQTT_CONNECT);
goto exit;
}
if(mqtt_rxevent){
c->ipstack->m2m_rxevent = 0;
Timer timer;
TimerInit(&timer);
TimerCountdownMS(&timer, 1000);
packet_type = readPacket(c, &timer);
if(packet_type > 0 && packet_type < 15)
mqtt_printf(MQTT_DEBUG, "Read packet type is %s", msg_types_str[packet_type]);
else{
mqtt_printf(MQTT_DEBUG, "Read packet type is %d", packet_type);
MQTTSetStatus(c, MQTT_START);
c->ipstack->disconnect(c->ipstack);
rc = FAILURE;
goto exit;
}
}
switch(mqttstatus){
case MQTT_CONNECT:
if (packet_type == CONNACK)
{
unsigned char connack_rc = 255;
unsigned char sessionPresent = 0;
if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, c->readbuf, c->readbuf_size) == 1){
rc = connack_rc;
mqtt_printf(MQTT_INFO, "MQTT Connected");
TimerInit(&c->cmd_timer);
TimerCountdownMS(&c->cmd_timer, c->command_timeout_ms);
if ((rc = MQTTSubscribe(c, topic, QOS2, messageHandler)) != 0){
mqtt_printf(MQTT_INFO, "Return code from MQTT subscribe is %d\n", rc);
}else{
mqtt_printf(MQTT_INFO, "Subscribe to Topic: %s", topic);
MQTTSetStatus(c, MQTT_SUBTOPIC);
}
}else{
mqtt_printf(MQTT_DEBUG, "Deserialize CONNACK failed");
rc = FAILURE;
}
}else if(TimerIsExpired(&c->cmd_timer)){
mqtt_printf(MQTT_DEBUG, "Not received CONNACK");
rc = FAILURE;
}
if(rc == FAILURE){
MQTTSetStatus(c, MQTT_START);
}
break;
case MQTT_SUBTOPIC:
if(packet_type == SUBACK){
int count = 0, grantedQoS = -1;
unsigned short mypacketid;
int isSubscribed = 0;
if (MQTTDeserialize_suback(&mypacketid, 1, &count, &grantedQoS, c->readbuf, c->readbuf_size) == 1){
rc = grantedQoS; // 0, 1, 2 or 0x80
mqtt_printf(MQTT_DEBUG, "grantedQoS: %d", grantedQoS);
}
if (rc != 0x80)
{
int i;
for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
{
if (c->messageHandlers[i].topicFilter == topic)
{
isSubscribed = 1;
break;
}
}
if(!isSubscribed)
for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
{
if (c->messageHandlers[i].topicFilter == 0)
{
c->messageHandlers[i].topicFilter = topic;
c->messageHandlers[i].fp = messageHandler;
break;
}
}
rc = 0;
MQTTSetStatus(c, MQTT_RUNNING);
}
}else if(TimerIsExpired(&c->cmd_timer)){
mqtt_printf(MQTT_DEBUG, "Not received SUBACK");
rc = FAILURE;
}
if(rc == FAILURE){
MQTTSetStatus(c, MQTT_START);
}
break;
case MQTT_RUNNING:
if(packet_type>0){
int len = 0;
Timer timer;
TimerInit(&timer);
TimerCountdownMS(&timer, 10000);
switch(packet_type){
case CONNACK:
break;
case PUBACK:
{
unsigned short mypacketid;
unsigned char dup, type;
if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
rc = FAILURE;
break;
}
case SUBACK:
break;
case UNSUBACK:
break;
case PUBLISH:
{
MQTTString topicName;
MQTTMessage msg;
int intQoS;
if (MQTTDeserialize_publish(&msg.dup, &intQoS, &msg.retained, &msg.id, &topicName,
(unsigned char**)&msg.payload, (int*)&msg.payloadlen, c->readbuf, c->readbuf_size) != 1)
{
rc = FAILURE;
mqtt_printf(MQTT_DEBUG, "Deserialize PUBLISH failed");
goto exit;
}
msg.qos = (enum QoS)intQoS;
deliverMessage(c, &topicName, &msg);
if (msg.qos != QOS0)
{
if (msg.qos == QOS1){
len = MQTTSerialize_ack(c->buf, c->buf_size, PUBACK, 0, msg.id);
mqtt_printf(MQTT_DEBUG, "send PUBACK");
}else if (msg.qos == QOS2){
len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREC, 0, msg.id);
mqtt_printf(MQTT_DEBUG, "send PUBREC");
}else{
mqtt_printf(MQTT_DEBUG, "invalid QoS: %d", msg.qos);
}
if (len <= 0){
rc = FAILURE;
mqtt_printf(MQTT_DEBUG, "Serialize_ack failed");
goto exit;
}else{
if((rc = sendPacket(c, len, &timer)) == FAILURE){
MQTTSetStatus(c, MQTT_START);
goto exit; // there was a problem
}
}
}
break;
}
case PUBREC:
{
unsigned short mypacketid;
unsigned char dup, type;
if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1){
mqtt_printf(MQTT_DEBUG, "Deserialize PUBREC failed");
rc = FAILURE;
}else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREL, 0, mypacketid)) <= 0){
mqtt_printf(MQTT_DEBUG, "Serialize PUBREL failed");
rc = FAILURE;
}else if ((rc = sendPacket(c, len, &timer)) != SUCCESS){ // send the PUBREL packet
rc = FAILURE; // there was a problem
MQTTSetStatus(c, MQTT_START);
}
break;
}
case PUBREL:
{
unsigned short mypacketid;
unsigned char dup, type;
if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1){
mqtt_printf(MQTT_DEBUG, "Deserialize PUBREL failed");
rc = FAILURE;
}else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBCOMP, 0, mypacketid)) <= 0){
mqtt_printf(MQTT_DEBUG, "Serialize PUBCOMP failed");
rc = FAILURE;
}else if ((rc = sendPacket(c, len, &timer)) != SUCCESS){ // send the PUBCOMP packet
rc = FAILURE; // there was a problem
MQTTSetStatus(c, MQTT_START);
}
break;
}
case PUBCOMP:
break;
case PINGRESP:
c->ping_outstanding = 0;
break;
}
}
keepalive(c);
break;
default:
break;
}
exit:
return rc;
}
#endif

View file

@ -0,0 +1,202 @@
/*******************************************************************************
* Copyright (c) 2014, 2015 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Allan Stockdill-Mander/Ian Craggs - initial API and implementation and/or initial documentation
* Ian Craggs - documentation and platform specific header
*******************************************************************************/
#if !defined(__MQTT_CLIENT_C_)
#define __MQTT_CLIENT_C_
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(WIN32_DLL) || defined(WIN64_DLL)
#define DLLImport __declspec(dllimport)
#define DLLExport __declspec(dllexport)
#elif defined(LINUX_SO)
#define DLLImport extern
#define DLLExport __attribute__ ((visibility ("default")))
#else
#define DLLImport
#define DLLExport
#endif
#include "../MQTTPacket/MQTTPacket.h"
#include "stdio.h"
#include "MQTTFreertos.h"
#define MQTT_TASK
#if !defined(MQTT_TASK)
#define WAIT_FOR_ACK
#endif
#define MQTT_SENDBUF_LEN 1024
#define MQTT_READBUF_LEN 1024
enum mqtt_status{
MQTT_START = 0,
MQTT_CONNECT = 1,
MQTT_SUBTOPIC = 2,
MQTT_RUNNING = 3
};
#if defined(MQTTCLIENT_PLATFORM_HEADER)
/* The following sequence of macros converts the MQTTCLIENT_PLATFORM_HEADER value
* into a string constant suitable for use with include.
*/
#define xstr(s) str(s)
#define str(s) #s
#include xstr(MQTTCLIENT_PLATFORM_HEADER)
#endif
#define MAX_PACKET_ID 65535 /* according to the MQTT specification - do not change! */
#if !defined(MAX_MESSAGE_HANDLERS)
#define MAX_MESSAGE_HANDLERS 5 /* redefinable - how many subscriptions do you want? */
#endif
enum QoS { QOS0, QOS1, QOS2 };
/* all failure return codes must be negative */
enum returnCode { BUFFER_OVERFLOW = -2, FAILURE = -1 };//, SUCCESS = 0
/* The Platform specific header must define the Network and Timer structures and functions
* which operate on them.
*
typedef struct Network
{
int (*mqttread)(Network*, unsigned char* read_buffer, int, int);
int (*mqttwrite)(Network*, unsigned char* send_buffer, int, int);
} Network;*/
/* The Timer structure must be defined in the platform specific header,
* and have the following functions to operate on it. */
extern void TimerInit(Timer*);
extern char TimerIsExpired(Timer*);
extern void TimerCountdownMS(Timer*, unsigned int);
extern void TimerCountdown(Timer*, unsigned int);
extern int TimerLeftMS(Timer*);
typedef struct MQTTMessage
{
enum QoS qos;
unsigned char retained;
unsigned char dup;
unsigned short id;
void *payload;
size_t payloadlen;
} MQTTMessage;
typedef struct MessageData
{
MQTTMessage* message;
MQTTString* topicName;
} MessageData;
typedef void (*messageHandler)(MessageData*);
typedef struct MQTTClient
{
unsigned int next_packetid,
command_timeout_ms;
size_t buf_size,
readbuf_size;
unsigned char *buf,
*readbuf;
unsigned int keepAliveInterval;
char ping_outstanding;
int isconnected;
struct MessageHandlers
{
const char* topicFilter;
void (*fp) (MessageData*);
} messageHandlers[MAX_MESSAGE_HANDLERS]; /* Message handlers are indexed by subscription topic */
void (*defaultMessageHandler) (MessageData*);
Network* ipstack;
Timer ping_timer;
Timer cmd_timer;
int mqttstatus;
} MQTTClient;
#define DefaultClient {0, 0, 0, 0, NULL, NULL, 0, 0, 0}
/**
* Create an MQTT client object
* @param client
* @param network
* @param command_timeout_ms
* @param
*/
DLLExport void MQTTClientInit(MQTTClient* client, Network* network, unsigned int command_timeout_ms,
unsigned char* sendbuf, size_t sendbuf_size, unsigned char* readbuf, size_t readbuf_size);
/** MQTT Connect - send an MQTT connect packet down the network and wait for a Connack
* The nework object must be connected to the network endpoint before calling this
* @param options - connect options
* @return success code
*/
DLLExport int MQTTConnect(MQTTClient* client, MQTTPacket_connectData* options);
/** MQTT Publish - send an MQTT publish packet and wait for all acks to complete for all QoSs
* @param client - the client object to use
* @param topic - the topic to publish to
* @param message - the message to send
* @return success code
*/
DLLExport int MQTTPublish(MQTTClient* client, const char*, MQTTMessage*);
/** MQTT Subscribe - send an MQTT subscribe packet and wait for suback before returning.
* @param client - the client object to use
* @param topicFilter - the topic filter to subscribe to
* @param message - the message to send
* @return success code
*/
DLLExport int MQTTSubscribe(MQTTClient* client, const char* topicFilter, enum QoS, messageHandler);
/** MQTT Subscribe - send an MQTT unsubscribe packet and wait for unsuback before returning.
* @param client - the client object to use
* @param topicFilter - the topic filter to unsubscribe from
* @return success code
*/
DLLExport int MQTTUnsubscribe(MQTTClient* client, const char* topicFilter);
/** MQTT Disconnect - send an MQTT disconnect packet and close the connection
* @param client - the client object to use
* @return success code
*/
DLLExport int MQTTDisconnect(MQTTClient* client);
/** MQTT Yield - MQTT background
* @param client - the client object to use
* @param time - the time, in milliseconds, to yield for
* @return success code
*/
DLLExport int MQTTYield(MQTTClient* client, int time);
#if defined(MQTT_TASK)
void MQTTSetStatus(MQTTClient* c, int mqttstatus);
int MQTTDataHandle(MQTTClient* c, fd_set *readfd, MQTTPacket_connectData *connectData, messageHandler messageHandler, char* address, char* topic);
#endif
#if defined(__cplusplus)
}
#endif
#endif

View file

@ -0,0 +1,881 @@
/*******************************************************************************
* Copyright (c) 2014, 2015 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Allan Stockdill-Mander - initial API and implementation and/or initial documentation
* Ian Craggs - convert to FreeRTOS
*******************************************************************************/
#include "MQTTFreertos.h"
#include "netdb.h"
#define LWIP_IPV6 0
#if LWIP_IPV6
#define inet_ntop(af,src,dst,size) \
(((af) == AF_INET6) ? ip6addr_ntoa_r((src),(dst),(size)) \
: (((af) == AF_INET) ? ipaddr_ntoa_r((src),(dst),(size)) : NULL))
#define inet_pton(af,src,dst) \
(((af) == AF_INET6) ? inet6_aton((src),(dst)) \
: (((af) == AF_INET) ? inet_aton((src),(dst)) : 0))
#else /* LWIP_IPV6 */
#define inet_ntop(af,src,dst,size) \
(((af) == AF_INET) ? ipaddr_ntoa_r((src),(dst),(size)) : NULL)
#define inet_pton(af,src,dst) \
(((af) == AF_INET) ? inet_aton((src),(dst)) : 0)
#endif /* LWIP_IPV6 */
int ThreadStart(Thread* thread, void (*fn)(void*), void* arg)
{
int rc = 0;
uint16_t usTaskStackSize = (configMINIMAL_STACK_SIZE * 5);
UBaseType_t uxTaskPriority = uxTaskPriorityGet(NULL); /* set the priority as the same as the calling task*/
rc = xTaskCreate(fn, /* The function that implements the task. */
"MQTTTask", /* Just a text name for the task to aid debugging. */
usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */
arg, /* The task parameter, not used in this case. */
uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */
&thread->task); /* The task handle is not used. */
return rc;
}
void MutexInit(Mutex* mutex)
{
mutex->sem = xSemaphoreCreateMutex();
}
int MutexLock(Mutex* mutex)
{
return xSemaphoreTake(mutex->sem, portMAX_DELAY);
}
int MutexUnlock(Mutex* mutex)
{
return xSemaphoreGive(mutex->sem);
}
void TimerCountdownMS(Timer* timer, unsigned int timeout_ms)
{
timer->xTicksToWait = timeout_ms / portTICK_PERIOD_MS; /* convert milliseconds to ticks */
vTaskSetTimeOutState(&timer->xTimeOut); /* Record the time at which this function was entered. */
}
void TimerCountdown(Timer* timer, unsigned int timeout)
{
TimerCountdownMS(timer, timeout * 1000);
}
int TimerLeftMS(Timer* timer)
{
xTaskCheckForTimeOut(&timer->xTimeOut, &timer->xTicksToWait); /* updates xTicksToWait to the number left */
return (timer->xTicksToWait * portTICK_PERIOD_MS);
}
char TimerIsExpired(Timer* timer)
{
return xTaskCheckForTimeOut(&timer->xTimeOut, &timer->xTicksToWait) == pdTRUE;
}
void TimerInit(Timer* timer)
{
timer->xTicksToWait = 0;
memset(&timer->xTimeOut, '\0', sizeof(timer->xTimeOut));
}
#if CONFIG_USE_POLARSSL
int FreeRTOS_read(Network* n, unsigned char* buffer, int len, int timeout_ms)
{
TickType_t xTicksToWait = timeout_ms / portTICK_PERIOD_MS; /* convert milliseconds to ticks */
TimeOut_t xTimeOut;
int recvLen = 0;
int so_error;
socklen_t errlen = sizeof(so_error);
vTaskSetTimeOutState(&xTimeOut); /* Record the time at which this function was entered. */
do
{
int rc = 0;
#if defined(LWIP_SO_SNDRCVTIMEO_NONSTANDARD) && (LWIP_SO_SNDRCVTIMEO_NONSTANDARD == 0)
// timeout format is changed in lwip 1.5.0
struct timeval timeout;
timeout.tv_sec = xTicksToWait / 1000;
timeout.tv_usec = ( xTicksToWait % 1000 ) * 1000;
setsockopt(n->my_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval));
#else
setsockopt(n->my_socket, SOL_SOCKET, SO_RCVTIMEO, &xTicksToWait, sizeof(xTicksToWait));
#endif
#if (MQTT_OVER_SSL)
if (n->use_ssl) {
rc = ssl_read(n->ssl, buffer + recvLen, len - recvLen);
getsockopt(n->my_socket, SOL_SOCKET, SO_ERROR, &so_error, &errlen);
if (so_error && so_error != EAGAIN) {
n->disconnect(n);
}
} else
#endif
rc = recv(n->my_socket, buffer + recvLen, len - recvLen, 0);
if (rc > 0)
recvLen += rc;
else if (rc < 0)
{
getsockopt(n->my_socket, SOL_SOCKET, SO_ERROR, &so_error, &errlen);
if (so_error != EAGAIN) {
n->disconnect(n);
}
recvLen = rc;
break;
}
} while (recvLen < len && xTaskCheckForTimeOut(&xTimeOut, &xTicksToWait) == pdFALSE);
return recvLen;
}
int FreeRTOS_write(Network* n, unsigned char* buffer, int len, int timeout_ms)
{
TickType_t xTicksToWait = timeout_ms / portTICK_PERIOD_MS; /* convert milliseconds to ticks */
TimeOut_t xTimeOut;
int sentLen = 0;
int so_error;
socklen_t errlen = sizeof(so_error);
vTaskSetTimeOutState(&xTimeOut); /* Record the time at which this function was entered. */
do
{
int rc = 0;
#if defined(LWIP_SO_SNDRCVTIMEO_NONSTANDARD) && (LWIP_SO_SNDRCVTIMEO_NONSTANDARD == 0)
// timeout format is changed in lwip 1.5.0
struct timeval timeout;
timeout.tv_sec = xTicksToWait / 1000;
timeout.tv_usec = ( xTicksToWait % 1000 ) * 1000;
setsockopt(n->my_socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval));
#else
setsockopt(n->my_socket, SOL_SOCKET, SO_SNDTIMEO, &xTicksToWait, sizeof(xTicksToWait));
#endif
#if (MQTT_OVER_SSL)
if (n->use_ssl) {
rc = ssl_write(n->ssl, buffer + sentLen, len - sentLen);
getsockopt(n->my_socket, SOL_SOCKET, SO_ERROR, &so_error, &errlen);
if (so_error && so_error != EAGAIN) {
n->disconnect(n);
}
} else
#endif
rc = send(n->my_socket, buffer + sentLen, len - sentLen, 0);
if (rc > 0)
sentLen += rc;
else if (rc < 0)
{
getsockopt(n->my_socket, SOL_SOCKET, SO_ERROR, &so_error, &len);
if (so_error != EAGAIN) {
n->disconnect(n);
}
sentLen = rc;
break;
}
} while (sentLen < len && xTaskCheckForTimeOut(&xTimeOut, &xTicksToWait) == pdFALSE);
return sentLen;
}
void FreeRTOS_disconnect(Network* n)
{
shutdown(n->my_socket, SHUT_RDWR);
close(n->my_socket);
n->my_socket = -1;
#if (MQTT_OVER_SSL)
if (n->use_ssl) {
ssl_free(n->ssl);
free(n->ssl);
n->ssl = NULL;
}
#endif
}
void NetworkInit(Network* n)
{
n->my_socket = -1;
n->mqttread = FreeRTOS_read;
n->mqttwrite = FreeRTOS_write;
n->disconnect = FreeRTOS_disconnect;
#if (MQTT_OVER_SSL)
n->use_ssl = 0;
n->ssl = NULL;
n->rootCA = NULL;
n->clientCA = NULL;
n->private_key = NULL;
#endif
}
#if (MQTT_OVER_SSL)
static int mqtt_tls_verify( void *data, x509_crt *crt, int depth, int *flags )
{
char buf[1024];
mqtt_printf(MQTT_DEBUG, "\nVerify requested for (Depth %d):\n", depth );
x509_crt_info( buf, sizeof( buf ) - 1, "", crt );
mqtt_printf(MQTT_DEBUG, "%s", buf );
if( ( (*flags) & BADCERT_EXPIRED ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! server certificate has expired\n" );
if( ( (*flags) & BADCERT_REVOKED ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! server certificate has been revoked\n" );
if( ( (*flags) & BADCERT_CN_MISMATCH ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! CN mismatch\n" );
if( ( (*flags) & BADCERT_NOT_TRUSTED ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! self-signed or not signed by a trusted CA\n" );
if( ( (*flags) & BADCRL_NOT_TRUSTED ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! CRL not trusted\n" );
if( ( (*flags) & BADCRL_EXPIRED ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! CRL expired\n" );
if( ( (*flags) & BADCERT_OTHER ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! other (unknown) flag\n" );
if ( ( *flags ) == 0 )
mqtt_printf(MQTT_DEBUG, " This certificate has no flags\n" );
return( 0 );
}
static int my_random(void *p_rng, unsigned char *output, size_t output_len)
{
rtw_get_random_bytes(output, output_len);
return 0;
}
#endif // #if (MQTT_OVER_SSL)
int NetworkConnect(Network* n, char* addr, int port)
{
struct sockaddr_in sAddr;
int retVal = -1;
struct hostent *hptr;
char **pptr;
char str[32];
int keepalive_enable = 1;
int keep_idle = 30;
if(n->my_socket >= 0){
n->disconnect(n);
}
if ((hptr = gethostbyname(addr)) == 0)
{
mqtt_printf(MQTT_DEBUG, "gethostbyname failed!");
goto exit;
}
pptr = hptr->h_addr_list;
for(; *pptr!=NULL; pptr++)
{
inet_ntop(hptr->h_addrtype, (const ip_addr_t *)*pptr, str, sizeof(str));
}
inet_ntop(hptr->h_addrtype, (const ip_addr_t *)hptr->h_addr, str, sizeof(str));
sAddr.sin_family = AF_INET;
sAddr.sin_port = htons(port);
sAddr.sin_addr.s_addr = inet_addr(str);
mqtt_printf(MQTT_DEBUG, "addr = %s", str);
if ((n->my_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
goto exit;
}
setsockopt( n->my_socket, SOL_SOCKET, SO_KEEPALIVE,
(const char *) &keepalive_enable, sizeof( keepalive_enable ) );
setsockopt( n->my_socket, IPPROTO_TCP, TCP_KEEPIDLE,
(const char *) &keep_idle, sizeof( keep_idle ) );
if ((retVal = connect(n->my_socket, (struct sockaddr*)&sAddr, sizeof(sAddr))) < 0)
{
close(n->my_socket);
mqtt_printf(MQTT_DEBUG, "Connect failed!!");
goto exit;
}
#if (MQTT_OVER_SSL)
x509_crt *root_crt;
x509_crt *client_crt;
pk_context *client_rsa;
root_crt = NULL;
client_crt = NULL;
client_rsa = NULL;
if ( n->use_ssl != 0 ) {
memory_set_own(pvPortMalloc, vPortFree);
n->ssl = (ssl_context *) malloc( sizeof(ssl_context) );
if ( n->ssl == NULL ) {
mqtt_printf(MQTT_DEBUG, "malloc ssl failed!");
goto err;
}
memset(n->ssl, 0, sizeof(ssl_context));
if ( ssl_init(n->ssl) != 0 ) {
mqtt_printf(MQTT_DEBUG, "init ssl failed!");
goto err;
}
ssl_set_endpoint(n->ssl, SSL_IS_CLIENT);
if (n->rootCA != NULL) {
root_crt = (x509_crt *) polarssl_malloc( sizeof(x509_crt) );
if ( root_crt == NULL ) {
mqtt_printf(MQTT_DEBUG, "malloc root_crt failed!");
goto err;
}
memset(root_crt, 0, sizeof(x509_crt));
ssl_set_authmode( n->ssl, SSL_VERIFY_REQUIRED );
if (x509_crt_parse( root_crt, n->rootCA, strlen(n->rootCA) ) != 0) {
mqtt_printf(MQTT_DEBUG, "parse root_crt failed!");
goto err;
}
ssl_set_ca_chain( n->ssl, root_crt, NULL, NULL );
ssl_set_verify( n->ssl, mqtt_tls_verify, NULL );
mqtt_printf(MQTT_DEBUG, "root_crt parse done");
} else {
ssl_set_authmode(n->ssl, SSL_VERIFY_NONE);
}
if (n->clientCA != NULL && n->private_key != NULL) {
client_crt = (x509_crt *) polarssl_malloc( sizeof(x509_crt) );
if ( client_crt == NULL ) {
mqtt_printf(MQTT_DEBUG, "malloc client_crt failed!");
goto err;
}
memset(client_crt, 0, sizeof(x509_crt));
x509_crt_init(client_crt);
client_rsa = (pk_context *) polarssl_malloc( sizeof(pk_context) );
if ( client_rsa == NULL ) {
mqtt_printf(MQTT_DEBUG, "malloc client_rsa failed!");
goto err;
}
memset(client_rsa, 0, sizeof(pk_context));
pk_init(client_rsa);
if ( x509_crt_parse(client_crt, n->clientCA, strlen(n->clientCA)) != 0 ) {
mqtt_printf(MQTT_DEBUG, "parse client_crt failed!");
goto err;
}
if ( pk_parse_key(client_rsa, n->private_key, strlen(n->private_key), NULL, 0) != 0 ) {
mqtt_printf(MQTT_DEBUG, "parse client_rsa failed!");
goto err;
}
ssl_set_own_cert(n->ssl, client_crt, client_rsa);
mqtt_printf(MQTT_DEBUG, "client_crt parse done");
}
ssl_set_rng(n->ssl, my_random, NULL);
ssl_set_bio(n->ssl, net_recv, &n->my_socket, net_send, &n->my_socket);
retVal = ssl_handshake(n->ssl);
if (retVal < 0) {
mqtt_printf(MQTT_DEBUG, "ssl handshake failed err:-0x%04X", -retVal);
goto err;
} else {
mqtt_printf(MQTT_DEBUG, "ssl handshake success");
}
}
if (client_rsa) {
pk_free(client_rsa);
polarssl_free(client_rsa);
}
if (client_crt) {
x509_crt_free(client_crt);
polarssl_free(client_crt);
}
if (root_crt) {
x509_crt_free(root_crt);
polarssl_free(root_crt);
}
goto exit;
err:
if (client_rsa) {
pk_free(client_rsa);
polarssl_free(client_rsa);
}
if (client_crt) {
x509_crt_free(client_crt);
polarssl_free(client_crt);
}
if (root_crt) {
x509_crt_free(root_crt);
polarssl_free(root_crt);
}
net_close(n->my_socket);
ssl_free(n->ssl);
free(n->ssl);
retVal = -1;
#endif // #if (MQTT_OVER_SSL)
exit:
return retVal;
}
#elif CONFIG_USE_MBEDTLS /* CONFIG_USE_POLARSSL */
int FreeRTOS_read(Network* n, unsigned char* buffer, int len, int timeout_ms)
{
TickType_t xTicksToWait = timeout_ms / portTICK_PERIOD_MS; /* convert milliseconds to ticks */
TimeOut_t xTimeOut;
int recvLen = 0;
int so_error;
socklen_t errlen = sizeof(so_error);
vTaskSetTimeOutState(&xTimeOut); /* Record the time at which this function was entered. */
do
{
int rc = 0;
#if defined(LWIP_SO_SNDRCVTIMEO_NONSTANDARD) && (LWIP_SO_SNDRCVTIMEO_NONSTANDARD == 0)
// timeout format is changed in lwip 1.5.0
struct timeval timeout;
timeout.tv_sec = xTicksToWait / 1000;
timeout.tv_usec = ( xTicksToWait % 1000 ) * 1000;
setsockopt(n->my_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval));
#else
setsockopt(n->my_socket, SOL_SOCKET, SO_RCVTIMEO, &xTicksToWait, sizeof(xTicksToWait));
#endif
#if (MQTT_OVER_SSL)
if (n->use_ssl) {
rc = mbedtls_ssl_read(n->ssl, buffer + recvLen, len - recvLen);
getsockopt(n->my_socket, SOL_SOCKET, SO_ERROR, &so_error, &errlen);
if (so_error && so_error != EAGAIN) {
n->disconnect(n);
}
} else
#endif
rc = recv(n->my_socket, buffer + recvLen, len - recvLen, 0);
if (rc > 0)
recvLen += rc;
else if (rc < 0)
{
getsockopt(n->my_socket, SOL_SOCKET, SO_ERROR, &so_error, &errlen);
if (so_error != EAGAIN) {
n->disconnect(n);
}
recvLen = rc;
break;
}
} while (recvLen < len && xTaskCheckForTimeOut(&xTimeOut, &xTicksToWait) == pdFALSE);
return recvLen;
}
int FreeRTOS_write(Network* n, unsigned char* buffer, int len, int timeout_ms)
{
TickType_t xTicksToWait = timeout_ms / portTICK_PERIOD_MS; /* convert milliseconds to ticks */
TimeOut_t xTimeOut;
int sentLen = 0;
int so_error;
socklen_t errlen = sizeof(so_error);
vTaskSetTimeOutState(&xTimeOut); /* Record the time at which this function was entered. */
do
{
int rc = 0;
#if defined(LWIP_SO_SNDRCVTIMEO_NONSTANDARD) && (LWIP_SO_SNDRCVTIMEO_NONSTANDARD == 0)
// timeout format is changed in lwip 1.5.0
struct timeval timeout;
timeout.tv_sec = xTicksToWait / 1000;
timeout.tv_usec = ( xTicksToWait % 1000 ) * 1000;
setsockopt(n->my_socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval));
#else
setsockopt(n->my_socket, SOL_SOCKET, SO_SNDTIMEO, &xTicksToWait, sizeof(xTicksToWait));
#endif
#if (MQTT_OVER_SSL)
if (n->use_ssl) {
rc = mbedtls_ssl_write(n->ssl, buffer + sentLen, len - sentLen);
getsockopt(n->my_socket, SOL_SOCKET, SO_ERROR, &so_error, &errlen);
if (so_error && so_error != EAGAIN) {
n->disconnect(n);
}
} else
#endif
rc = send(n->my_socket, buffer + sentLen, len - sentLen, 0);
if (rc > 0)
sentLen += rc;
else if (rc < 0)
{
getsockopt(n->my_socket, SOL_SOCKET, SO_ERROR, &so_error, &len);
if (so_error != EAGAIN) {
n->disconnect(n);
}
sentLen = rc;
break;
}
} while (sentLen < len && xTaskCheckForTimeOut(&xTimeOut, &xTicksToWait) == pdFALSE);
return sentLen;
}
void FreeRTOS_disconnect(Network* n)
{
shutdown(n->my_socket, SHUT_RDWR);
close(n->my_socket);
n->my_socket = -1;
#if (MQTT_OVER_SSL)
if (n->use_ssl) {
mbedtls_ssl_free(n->ssl);
mbedtls_ssl_config_free(n->conf);
free(n->ssl);
free(n->conf);
n->ssl = NULL;
n->conf = NULL;
}
#endif
}
void NetworkInit(Network* n)
{
n->my_socket = -1;
n->mqttread = FreeRTOS_read;
n->mqttwrite = FreeRTOS_write;
n->disconnect = FreeRTOS_disconnect;
#if (MQTT_OVER_SSL)
n->use_ssl = 0;
n->ssl = NULL;
n->conf = NULL;
n->rootCA = NULL;
n->clientCA = NULL;
n->private_key = NULL;
#endif
}
#if (MQTT_OVER_SSL)
static int mqtt_tls_verify( void *data, mbedtls_x509_crt *crt, int depth, int *flags )
{
char buf[1024];
mqtt_printf(MQTT_DEBUG, "\nVerify requested for (Depth %d):\n", depth );
mbedtls_x509_crt_info( buf, sizeof( buf ) - 1, "", crt );
mqtt_printf(MQTT_DEBUG, "%s", buf );
if( ( (*flags) & MBEDTLS_X509_BADCERT_EXPIRED ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! server certificate has expired\n" );
if( ( (*flags) & MBEDTLS_X509_BADCERT_REVOKED ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! server certificate has been revoked\n" );
if( ( (*flags) & MBEDTLS_X509_BADCERT_CN_MISMATCH ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! CN mismatch\n" );
if( ( (*flags) & MBEDTLS_X509_BADCERT_NOT_TRUSTED ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! self-signed or not signed by a trusted CA\n" );
if( ( (*flags) & MBEDTLS_X509_BADCRL_NOT_TRUSTED ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! CRL not trusted\n" );
if( ( (*flags) & MBEDTLS_X509_BADCRL_EXPIRED ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! CRL expired\n" );
if( ( (*flags) & MBEDTLS_X509_BADCERT_OTHER ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! other (unknown) flag\n" );
if ( ( *flags ) == 0 )
mqtt_printf(MQTT_DEBUG, " This certificate has no flags\n" );
return( 0 );
}
static void* my_calloc(size_t nelements, size_t elementSize)
{
size_t size;
void *ptr = NULL;
size = nelements * elementSize;
ptr = pvPortMalloc(size);
if(ptr)
memset(ptr, 0, size);
return ptr;
}
static int my_random(void *p_rng, unsigned char *output, size_t output_len)
{
rtw_get_random_bytes(output, output_len);
return 0;
}
#endif // #if (MQTT_OVER_SSL)
int NetworkConnect(Network* n, char* addr, int port)
{
struct sockaddr_in sAddr;
int retVal = -1;
struct hostent *hptr;
char **pptr;
char str[32];
int keepalive_enable = 1;
int keep_idle = 30;
if(n->my_socket >= 0){
n->disconnect(n);
}
if ((hptr = gethostbyname(addr)) == 0)
{
mqtt_printf(MQTT_DEBUG, "gethostbyname failed!");
goto exit;
}
pptr = hptr->h_addr_list;
for(; *pptr!=NULL; pptr++)
{
inet_ntop(hptr->h_addrtype, (const ip_addr_t *)*pptr, str, sizeof(str));
}
inet_ntop(hptr->h_addrtype, (const ip_addr_t *)hptr->h_addr, str, sizeof(str));
sAddr.sin_family = AF_INET;
sAddr.sin_port = htons(port);
sAddr.sin_addr.s_addr = inet_addr(str);
mqtt_printf(MQTT_DEBUG, "addr = %s", str);
if ((n->my_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
goto exit;
}
setsockopt( n->my_socket, SOL_SOCKET, SO_KEEPALIVE,
(const char *) &keepalive_enable, sizeof( keepalive_enable ) );
setsockopt( n->my_socket, IPPROTO_TCP, TCP_KEEPIDLE,
(const char *) &keep_idle, sizeof( keep_idle ) );
if ((retVal = connect(n->my_socket, (struct sockaddr*)&sAddr, sizeof(sAddr))) < 0)
{
close(n->my_socket);
mqtt_printf(MQTT_DEBUG, "Connect failed!!");
goto exit;
}
#if (MQTT_OVER_SSL)
mbedtls_x509_crt *root_crt;
mbedtls_x509_crt *client_crt;
mbedtls_pk_context *client_rsa;
root_crt = NULL;
client_crt = NULL;
client_rsa = NULL;
if ( n->use_ssl != 0 ) {
mbedtls_platform_set_calloc_free(my_calloc, vPortFree);
n->ssl = (mbedtls_ssl_context *) malloc( sizeof(mbedtls_ssl_context) );
n->conf = (mbedtls_ssl_config *) malloc( sizeof(mbedtls_ssl_config) );
if (( n->ssl == NULL )||( n->conf == NULL )) {
mqtt_printf(MQTT_DEBUG, "malloc ssl failed!");
goto err;
}
mbedtls_ssl_init(n->ssl);
mbedtls_ssl_config_init(n->conf);
if (n->rootCA != NULL) {
root_crt = (mbedtls_x509_crt *) mbedtls_calloc( sizeof(mbedtls_x509_crt), 1);
if ( root_crt == NULL ) {
mqtt_printf(MQTT_DEBUG, "malloc root_crt failed!");
goto err;
}
mbedtls_x509_crt_init(root_crt);
if (mbedtls_x509_crt_parse( root_crt, n->rootCA, strlen(n->rootCA)+1 ) != 0) {
mqtt_printf(MQTT_DEBUG, "parse root_crt failed!");
goto err;
}
mbedtls_ssl_conf_ca_chain( n->conf, root_crt, NULL);
mbedtls_ssl_conf_authmode(n->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
mbedtls_ssl_conf_verify( n->conf, mqtt_tls_verify, NULL );
mqtt_printf(MQTT_DEBUG, "root_crt parse done");
} else {
mbedtls_ssl_conf_authmode(n->conf, MBEDTLS_SSL_VERIFY_NONE);
}
if (n->clientCA != NULL && n->private_key != NULL) {
client_crt = (mbedtls_x509_crt *) mbedtls_calloc( sizeof(mbedtls_x509_crt), 1);
if ( client_crt == NULL ) {
mqtt_printf(MQTT_DEBUG, "malloc client_crt failed!");
goto err;
}
mbedtls_x509_crt_init(client_crt);
client_rsa = (mbedtls_pk_context *) mbedtls_calloc( sizeof(mbedtls_pk_context), 1);
if ( client_rsa == NULL ) {
mqtt_printf(MQTT_DEBUG, "malloc client_rsa failed!");
goto err;
}
mbedtls_pk_init(client_rsa);
if ( mbedtls_x509_crt_parse(client_crt, n->clientCA, strlen(n->clientCA)+1) != 0 ) {
mqtt_printf(MQTT_DEBUG, "parse client_crt failed!");
goto err;
}
if ( mbedtls_pk_parse_key(client_rsa, n->private_key, strlen(n->private_key)+1, NULL, 0) != 0 ) {
mqtt_printf(MQTT_DEBUG, "parse client_rsa failed!");
goto err;
}
}
mbedtls_ssl_conf_own_cert(n->conf, client_crt, client_rsa);
mbedtls_ssl_set_bio(n->ssl, &n->my_socket, mbedtls_net_send, mbedtls_net_recv, NULL);
mbedtls_ssl_conf_rng(n->conf, my_random, NULL);
if((mbedtls_ssl_config_defaults(n->conf,
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
mqtt_printf(MQTT_DEBUG, "ssl config defaults failed!");
goto err;
}
if((mbedtls_ssl_setup(n->ssl, n->conf)) != 0) {
mqtt_printf(MQTT_DEBUG,"mbedtls_ssl_setup failed!");
goto err;
}
retVal = mbedtls_ssl_handshake(n->ssl);
if (retVal < 0) {
mqtt_printf(MQTT_DEBUG, "ssl handshake failed err:-0x%04X", -retVal);
goto err;
} else {
mqtt_printf(MQTT_DEBUG, "ssl handshake success");
}
}
if (client_rsa) {
mbedtls_pk_free(client_rsa);
mbedtls_free(client_rsa);
}
if (client_crt) {
mbedtls_x509_crt_free(client_crt);
mbedtls_free(client_crt);
}
if (root_crt) {
mbedtls_x509_crt_free(root_crt);
mbedtls_free(root_crt);
}
goto exit;
err:
if (client_rsa) {
mbedtls_pk_free(client_rsa);
mbedtls_free(client_rsa);
}
if (client_crt) {
mbedtls_x509_crt_free(client_crt);
mbedtls_free(client_crt);
}
if (root_crt) {
mbedtls_x509_crt_free(root_crt);
mbedtls_free(root_crt);
}
mbedtls_net_free(&n->my_socket);
mbedtls_ssl_free(n->ssl);
mbedtls_ssl_config_free(n->conf);
free(n->ssl);
free(n->conf);
retVal = -1;
#endif // #if (MQTT_OVER_SSL)
exit:
return retVal;
}
#endif /* CONFIG_USE_POLARSSL */
#if 0
int NetworkConnectTLS(Network *n, char* addr, int port, SlSockSecureFiles_t* certificates, unsigned char sec_method, unsigned int cipher, char server_verify)
{
SlSockAddrIn_t sAddr;
int addrSize;
int retVal;
unsigned long ipAddress;
retVal = sl_NetAppDnsGetHostByName(addr, strlen(addr), &ipAddress, AF_INET);
if (retVal < 0) {
return -1;
}
sAddr.sin_family = AF_INET;
sAddr.sin_port = sl_Htons((unsigned short)port);
sAddr.sin_addr.s_addr = sl_Htonl(ipAddress);
addrSize = sizeof(SlSockAddrIn_t);
n->my_socket = sl_Socket(SL_AF_INET, SL_SOCK_STREAM, SL_SEC_SOCKET);
if (n->my_socket < 0) {
return -1;
}
SlSockSecureMethod method;
method.secureMethod = sec_method;
retVal = sl_SetSockOpt(n->my_socket, SL_SOL_SOCKET, SL_SO_SECMETHOD, &method, sizeof(method));
if (retVal < 0) {
return retVal;
}
SlSockSecureMask mask;
mask.secureMask = cipher;
retVal = sl_SetSockOpt(n->my_socket, SL_SOL_SOCKET, SL_SO_SECURE_MASK, &mask, sizeof(mask));
if (retVal < 0) {
return retVal;
}
if (certificates != NULL) {
retVal = sl_SetSockOpt(n->my_socket, SL_SOL_SOCKET, SL_SO_SECURE_FILES, certificates->secureFiles, sizeof(SlSockSecureFiles_t));
if (retVal < 0)
{
return retVal;
}
}
retVal = sl_Connect(n->my_socket, (SlSockAddr_t *)&sAddr, addrSize);
if (retVal < 0) {
if (server_verify || retVal != -453) {
sl_Close(n->my_socket);
return retVal;
}
}
SysTickIntRegister(SysTickIntHandler);
SysTickPeriodSet(80000);
SysTickEnable();
return retVal;
}
#endif

View file

@ -0,0 +1,122 @@
/*******************************************************************************
* Copyright (c) 2014, 2015 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Allan Stockdill-Mander - initial API and implementation and/or initial documentation
*******************************************************************************/
#if !defined(MQTTFreeRTOS_H)
#define MQTTFreeRTOS_H
#include "FreeRTOS.h"
#include "semphr.h"
#include "task.h"
#include "lwip/sockets.h"
#include "osdep_service.h"
#define MQTT_OVER_SSL (1)
#if (MQTT_OVER_SSL)
#if CONFIG_USE_POLARSSL
#include "polarssl/config.h"
#include "polarssl/net.h"
#include "polarssl/ssl.h"
#include "polarssl/error.h"
#include "polarssl/memory.h"
#elif CONFIG_USE_MBEDTLS
#include "mbedtls/config.h"
#include "mbedtls/platform.h"
#include "mbedtls/net_sockets.h"
#include "mbedtls/ssl.h"
#include "mbedtls/error.h"
#include "mbedtls/debug.h"
#endif
#endif
enum {
MQTT_EXCESSIVE, MQTT_MSGDUMP, MQTT_DEBUG, MQTT_INFO, MQTT_ALWAYS, MQTT_WARNING, MQTT_ERROR
};
#define FreeRTOS_Select select
#define mqtt_printf(level, fmt, arg...) \
do {\
if (level >= MQTT_DEBUG) {\
{\
printf("\r\n[%d]mqtt:", rtw_get_current_time());\
printf(fmt, ##arg);\
printf("\n\r");\
} \
}\
}while(0)
typedef struct Timer
{
TickType_t xTicksToWait;
TimeOut_t xTimeOut;
} Timer;
typedef struct Network Network;
struct Network
{
int my_socket;
int (*mqttread) (Network*, unsigned char*, int, int);
int (*mqttwrite) (Network*, unsigned char*, int, int);
void (*disconnect) (Network*);
int m2m_rxevent;
#if (MQTT_OVER_SSL)
unsigned char use_ssl;
#if CONFIG_USE_POLARSSL
ssl_context *ssl;
#elif CONFIG_USE_MBEDTLS
mbedtls_ssl_context *ssl;
mbedtls_ssl_config *conf;
#endif
char *rootCA;
char *clientCA;
char *private_key;
#endif
};
void TimerInit(Timer*);
char TimerIsExpired(Timer*);
void TimerCountdownMS(Timer*, unsigned int);
void TimerCountdown(Timer*, unsigned int);
int TimerLeftMS(Timer*);
typedef struct Mutex
{
SemaphoreHandle_t sem;
} Mutex;
void MutexInit(Mutex*);
int MutexLock(Mutex*);
int MutexUnlock(Mutex*);
typedef struct Thread
{
TaskHandle_t task;
} Thread;
int ThreadStart(Thread*, void (*fn)(void*), void* arg);
int FreeRTOS_read(Network*, unsigned char*, int, int);
int FreeRTOS_write(Network*, unsigned char*, int, int);
void FreeRTOS_disconnect(Network*);
void NetworkInit(Network*);
int NetworkConnect(Network*, char*, int);
/*int NetworkConnectTLS(Network*, char*, int, SlSockSecureFiles_t*, unsigned char, unsigned int, char);*/
#endif

View file

@ -0,0 +1,139 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Xiang Rong - 442039 Add makefile to Embedded C client
*******************************************************************************/
#ifndef MQTTCONNECT_H_
#define MQTTCONNECT_H_
#if !defined(DLLImport)
#define DLLImport
#endif
#if !defined(DLLExport)
#define DLLExport
#endif
typedef union
{
unsigned char all; /**< all connect flags */
#if defined(REVERSED)
struct
{
unsigned int username : 1; /**< 3.1 user name */
unsigned int password : 1; /**< 3.1 password */
unsigned int willRetain : 1; /**< will retain setting */
unsigned int willQoS : 2; /**< will QoS value */
unsigned int will : 1; /**< will flag */
unsigned int cleansession : 1; /**< clean session flag */
unsigned int : 1; /**< unused */
} bits;
#else
struct
{
unsigned int : 1; /**< unused */
unsigned int cleansession : 1; /**< cleansession flag */
unsigned int will : 1; /**< will flag */
unsigned int willQoS : 2; /**< will QoS value */
unsigned int willRetain : 1; /**< will retain setting */
unsigned int password : 1; /**< 3.1 password */
unsigned int username : 1; /**< 3.1 user name */
} bits;
#endif
} MQTTConnectFlags; /**< connect flags byte */
/**
* Defines the MQTT "Last Will and Testament" (LWT) settings for
* the connect packet.
*/
typedef struct
{
/** The eyecatcher for this structure. must be MQTW. */
char struct_id[4];
/** The version number of this structure. Must be 0 */
int struct_version;
/** The LWT topic to which the LWT message will be published. */
MQTTString topicName;
/** The LWT payload. */
MQTTString message;
/**
* The retained flag for the LWT message (see MQTTAsync_message.retained).
*/
unsigned char retained;
/**
* The quality of service setting for the LWT message (see
* MQTTAsync_message.qos and @ref qos).
*/
char qos;
} MQTTPacket_willOptions;
#define MQTTPacket_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 0, {NULL, {0, NULL}}, {NULL, {0, NULL}}, 0, 0 }
typedef struct
{
/** The eyecatcher for this structure. must be MQTC. */
char struct_id[4];
/** The version number of this structure. Must be 0 */
int struct_version;
/** Version of MQTT to be used. 3 = 3.1 4 = 3.1.1
*/
unsigned char MQTTVersion;
MQTTString clientID;
unsigned short keepAliveInterval;
unsigned char cleansession;
unsigned char willFlag;
MQTTPacket_willOptions will;
MQTTString username;
MQTTString password;
} MQTTPacket_connectData;
typedef union
{
unsigned char all; /**< all connack flags */
#if defined(REVERSED)
struct
{
unsigned int sessionpresent : 1; /**< session present flag */
unsigned int : 7; /**< unused */
} bits;
#else
struct
{
unsigned int : 7; /**< unused */
unsigned int sessionpresent : 1; /**< session present flag */
} bits;
#endif
} MQTTConnackFlags; /**< connack flags byte */
#define MQTTPacket_connectData_initializer { {'M', 'Q', 'T', 'C'}, 0, 4, {NULL, {0, NULL}}, 60, 1, 0, \
MQTTPacket_willOptions_initializer, {NULL, {0, NULL}}, {NULL, {0, NULL}} }
DLLExport int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options);
DLLExport int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int len);
DLLExport int MQTTSerialize_connack(unsigned char* buf, int buflen, unsigned char connack_rc, unsigned char sessionPresent);
DLLExport int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen);
DLLExport int MQTTSerialize_disconnect(unsigned char* buf, int buflen);
DLLExport int MQTTSerialize_pingreq(unsigned char* buf, int buflen);
#endif /* MQTTCONNECT_H_ */

View file

@ -0,0 +1,214 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "MQTTPacket.h"
#include "StackTrace.h"
#include <string.h>
/**
* Determines the length of the MQTT connect packet that would be produced using the supplied connect options.
* @param options the options to be used to build the connect packet
* @return the length of buffer needed to contain the serialized version of the packet
*/
int MQTTSerialize_connectLength(MQTTPacket_connectData* options)
{
int len = 0;
FUNC_ENTRY;
if (options->MQTTVersion == 3)
len = 12; /* variable depending on MQTT or MQIsdp */
else if (options->MQTTVersion == 4)
len = 10;
len += MQTTstrlen(options->clientID)+2;
if (options->willFlag)
len += MQTTstrlen(options->will.topicName)+2 + MQTTstrlen(options->will.message)+2;
if (options->username.cstring || options->username.lenstring.data)
len += MQTTstrlen(options->username)+2;
if (options->password.cstring || options->password.lenstring.data)
len += MQTTstrlen(options->password)+2;
FUNC_EXIT_RC(len);
return len;
}
/**
* Serializes the connect options into the buffer.
* @param buf the buffer into which the packet will be serialized
* @param len the length in bytes of the supplied buffer
* @param options the options to be used to build the connect packet
* @return serialized length, or error if 0
*/
int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options)
{
unsigned char *ptr = buf;
MQTTHeader header = {0};
MQTTConnectFlags flags = {0};
int len = 0;
int rc = -1;
FUNC_ENTRY;
if (MQTTPacket_len(len = MQTTSerialize_connectLength(options)) > buflen)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = CONNECT;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, len); /* write remaining length */
if (options->MQTTVersion == 4)
{
writeCString(&ptr, "MQTT");
writeChar(&ptr, (char) 4);
}
else
{
writeCString(&ptr, "MQIsdp");
writeChar(&ptr, (char) 3);
}
flags.all = 0;
flags.bits.cleansession = options->cleansession;
flags.bits.will = (options->willFlag) ? 1 : 0;
if (flags.bits.will)
{
flags.bits.willQoS = options->will.qos;
flags.bits.willRetain = options->will.retained;
}
if (options->username.cstring || options->username.lenstring.data)
flags.bits.username = 1;
if (options->password.cstring || options->password.lenstring.data)
flags.bits.password = 1;
writeChar(&ptr, flags.all);
writeInt(&ptr, options->keepAliveInterval);
writeMQTTString(&ptr, options->clientID);
if (options->willFlag)
{
writeMQTTString(&ptr, options->will.topicName);
writeMQTTString(&ptr, options->will.message);
}
if (flags.bits.username)
writeMQTTString(&ptr, options->username);
if (flags.bits.password)
writeMQTTString(&ptr, options->password);
rc = ptr - buf;
exit: FUNC_EXIT_RC(rc);
return rc;
}
/**
* Deserializes the supplied (wire) buffer into connack data - return code
* @param sessionPresent the session present flag returned (only for MQTT 3.1.1)
* @param connack_rc returned integer value of the connack return code
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param len the length in bytes of the data in the supplied buffer
* @return error code. 1 is success, 0 is failure
*/
int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen)
{
MQTTHeader header = {0};
unsigned char* curdata = buf;
unsigned char* enddata = NULL;
int rc = 0;
int mylen;
MQTTConnackFlags flags = {0};
FUNC_ENTRY;
header.byte = readChar(&curdata);
if (header.bits.type != CONNACK)
goto exit;
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
enddata = curdata + mylen;
if (enddata - curdata < 2)
goto exit;
flags.all = readChar(&curdata);
*sessionPresent = flags.bits.sessionpresent;
*connack_rc = readChar(&curdata);
rc = 1;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes a 0-length packet into the supplied buffer, ready for writing to a socket
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer, to avoid overruns
* @param packettype the message type
* @return serialized length, or error if 0
*/
int MQTTSerialize_zero(unsigned char* buf, int buflen, unsigned char packettype)
{
MQTTHeader header = {0};
int rc = -1;
unsigned char *ptr = buf;
FUNC_ENTRY;
if (buflen < 2)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = packettype;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, 0); /* write remaining length */
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes a disconnect packet into the supplied buffer, ready for writing to a socket
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer, to avoid overruns
* @return serialized length, or error if 0
*/
int MQTTSerialize_disconnect(unsigned char* buf, int buflen)
{
return MQTTSerialize_zero(buf, buflen, DISCONNECT);
}
/**
* Serializes a disconnect packet into the supplied buffer, ready for writing to a socket
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer, to avoid overruns
* @return serialized length, or error if 0
*/
int MQTTSerialize_pingreq(unsigned char* buf, int buflen)
{
return MQTTSerialize_zero(buf, buflen, PINGREQ);
}

View file

@ -0,0 +1,147 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "StackTrace.h"
#include "MQTTPacket.h"
#include <string.h>
#define min(a, b) ((a < b) ? a : b)
/**
* Validates MQTT protocol name and version combinations
* @param protocol the MQTT protocol name as an MQTTString
* @param version the MQTT protocol version number, as in the connect packet
* @return correct MQTT combination? 1 is true, 0 is false
*/
int MQTTPacket_checkVersion(MQTTString* protocol, int version)
{
int rc = 0;
if (version == 3 && memcmp(protocol->lenstring.data, "MQIsdp",
min(6, protocol->lenstring.len)) == 0)
rc = 1;
else if (version == 4 && memcmp(protocol->lenstring.data, "MQTT",
min(4, protocol->lenstring.len)) == 0)
rc = 1;
return rc;
}
/**
* Deserializes the supplied (wire) buffer into connect data structure
* @param data the connect data structure to be filled out
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param len the length in bytes of the data in the supplied buffer
* @return error code. 1 is success, 0 is failure
*/
int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int len)
{
MQTTHeader header = {0};
MQTTConnectFlags flags = {0};
unsigned char* curdata = buf;
unsigned char* enddata = &buf[len];
int rc = 0;
MQTTString Protocol;
int version;
int mylen = 0;
FUNC_ENTRY;
header.byte = readChar(&curdata);
if (header.bits.type != CONNECT)
goto exit;
curdata += MQTTPacket_decodeBuf(curdata, &mylen); /* read remaining length */
if (!readMQTTLenString(&Protocol, &curdata, enddata) ||
enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */
goto exit;
version = (int)readChar(&curdata); /* Protocol version */
/* If we don't recognize the protocol version, we don't parse the connect packet on the
* basis that we don't know what the format will be.
*/
if (MQTTPacket_checkVersion(&Protocol, version))
{
flags.all = readChar(&curdata);
data->cleansession = flags.bits.cleansession;
data->keepAliveInterval = readInt(&curdata);
if (!readMQTTLenString(&data->clientID, &curdata, enddata))
goto exit;
data->willFlag = flags.bits.will;
if (flags.bits.will)
{
data->will.qos = flags.bits.willQoS;
data->will.retained = flags.bits.willRetain;
if (!readMQTTLenString(&data->will.topicName, &curdata, enddata) ||
!readMQTTLenString(&data->will.message, &curdata, enddata))
goto exit;
}
if (flags.bits.username)
{
if (enddata - curdata < 3 || !readMQTTLenString(&data->username, &curdata, enddata))
goto exit; /* username flag set, but no username supplied - invalid */
if (flags.bits.password &&
(enddata - curdata < 3 || !readMQTTLenString(&data->password, &curdata, enddata)))
goto exit; /* password flag set, but no password supplied - invalid */
}
else if (flags.bits.password)
goto exit; /* password flag set without username - invalid */
rc = 1;
}
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes the connack packet into the supplied buffer.
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param connack_rc the integer connack return code to be used
* @param sessionPresent the MQTT 3.1.1 sessionPresent flag
* @return serialized length, or error if 0
*/
int MQTTSerialize_connack(unsigned char* buf, int buflen, unsigned char connack_rc, unsigned char sessionPresent)
{
MQTTHeader header = {0};
int rc = 0;
unsigned char *ptr = buf;
MQTTConnackFlags flags = {0};
FUNC_ENTRY;
if (buflen < 2)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = CONNACK;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */
flags.all = 0;
flags.bits.sessionpresent = sessionPresent;
writeChar(&ptr, flags.all);
writeChar(&ptr, connack_rc);
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}

View file

@ -0,0 +1,105 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "StackTrace.h"
#include "MQTTPacket.h"
#include <string.h>
#define min(a, b) ((a < b) ? 1 : 0)
/**
* Deserializes the supplied (wire) buffer into publish data
* @param dup returned integer - the MQTT dup flag
* @param qos returned integer - the MQTT QoS value
* @param retained returned integer - the MQTT retained flag
* @param packetid returned integer - the MQTT packet identifier
* @param topicName returned MQTTString - the MQTT topic in the publish
* @param payload returned byte buffer - the MQTT publish payload
* @param payloadlen returned integer - the length of the MQTT payload
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @return error code. 1 is success
*/
int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName,
unsigned char** payload, int* payloadlen, unsigned char* buf, int buflen)
{
MQTTHeader header = {0};
unsigned char* curdata = buf;
unsigned char* enddata = NULL;
int rc = 0;
int mylen = 0;
FUNC_ENTRY;
header.byte = readChar(&curdata);
if (header.bits.type != PUBLISH)
goto exit;
*dup = header.bits.dup;
*qos = header.bits.qos;
*retained = header.bits.retain;
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
enddata = curdata + mylen;
if (!readMQTTLenString(topicName, &curdata, enddata) ||
enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */
goto exit;
if (*qos > 0)
*packetid = readInt(&curdata);
*payloadlen = enddata - curdata;
*payload = curdata;
rc = 1;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Deserializes the supplied (wire) buffer into an ack
* @param packettype returned integer - the MQTT packet type
* @param dup returned integer - the MQTT dup flag
* @param packetid returned integer - the MQTT packet identifier
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @return error code. 1 is success, 0 is failure
*/
int MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int buflen)
{
MQTTHeader header = {0};
unsigned char* curdata = buf;
unsigned char* enddata = NULL;
int rc = 0;
int mylen;
FUNC_ENTRY;
header.byte = readChar(&curdata);
*dup = header.bits.dup;
*packettype = header.bits.type;
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
enddata = curdata + mylen;
if (enddata - curdata < 2)
goto exit;
*packetid = readInt(&curdata);
rc = 1;
exit:
FUNC_EXIT_RC(rc);
return rc;
}

View file

@ -0,0 +1,255 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "StackTrace.h"
#include "MQTTPacket.h"
#include <string.h>
const char* MQTTPacket_names[] =
{
"RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL",
"PUBCOMP", "SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK",
"PINGREQ", "PINGRESP", "DISCONNECT"
};
const char* MQTTPacket_getName(unsigned short packetid)
{
return MQTTPacket_names[packetid];
}
int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data)
{
int strindex = 0;
strindex = snprintf(strbuf, strbuflen,
"CONNECT MQTT version %d, client id %.*s, clean session %d, keep alive %d",
(int)data->MQTTVersion, data->clientID.lenstring.len, data->clientID.lenstring.data,
(int)data->cleansession, data->keepAliveInterval);
if (data->willFlag)
strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
", will QoS %d, will retain %d, will topic %.*s, will message %.*s",
data->will.qos, data->will.retained,
data->will.topicName.lenstring.len, data->will.topicName.lenstring.data,
data->will.message.lenstring.len, data->will.message.lenstring.data);
if (data->username.lenstring.data && data->username.lenstring.len > 0)
strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
", user name %.*s", data->username.lenstring.len, data->username.lenstring.data);
if (data->password.lenstring.data && data->password.lenstring.len > 0)
strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
", password %.*s", data->password.lenstring.len, data->password.lenstring.data);
return strindex;
}
int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent)
{
int strindex = snprintf(strbuf, strbuflen, "CONNACK session present %d, rc %d", sessionPresent, connack_rc);
return strindex;
}
int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained,
unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen)
{
int strindex = snprintf(strbuf, strbuflen,
"PUBLISH dup %d, QoS %d, retained %d, packet id %d, topic %.*s, payload length %d, payload %.*s",
dup, qos, retained, packetid,
(topicName.lenstring.len < 20) ? topicName.lenstring.len : 20, topicName.lenstring.data,
payloadlen, (payloadlen < 20) ? payloadlen : 20, payload);
return strindex;
}
int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid)
{
int strindex = snprintf(strbuf, strbuflen, "%s, packet id %d", MQTTPacket_names[packettype], packetid);
if (dup)
strindex += snprintf(strbuf + strindex, strbuflen - strindex, ", dup %d", dup);
return strindex;
}
int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count,
MQTTString topicFilters[], int requestedQoSs[])
{
return snprintf(strbuf, strbuflen,
"SUBSCRIBE dup %d, packet id %d count %d topic %.*s qos %d",
dup, packetid, count,
topicFilters[0].lenstring.len, topicFilters[0].lenstring.data,
requestedQoSs[0]);
}
int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs)
{
return snprintf(strbuf, strbuflen,
"SUBACK packet id %d count %d granted qos %d", packetid, count, grantedQoSs[0]);
}
int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid,
int count, MQTTString topicFilters[])
{
return snprintf(strbuf, strbuflen,
"UNSUBSCRIBE dup %d, packet id %d count %d topic %.*s",
dup, packetid, count,
topicFilters[0].lenstring.len, topicFilters[0].lenstring.data);
}
char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen)
{
int index = 0;
int rem_length = 0;
MQTTHeader header = {0};
header.byte = buf[index++];
index += MQTTPacket_decodeBuf(&buf[index], &rem_length);
switch (header.bits.type)
{
case CONNACK:
{
unsigned char sessionPresent, connack_rc;
if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) == 1)
MQTTStringFormat_connack(strbuf, strbuflen, connack_rc, sessionPresent);
}
break;
case PUBLISH:
{
unsigned char dup, retained, *payload;
unsigned short packetid;
int qos, payloadlen;
MQTTString topicName = MQTTString_initializer;
if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName,
&payload, &payloadlen, buf, buflen) == 1)
MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid,
topicName, payload, payloadlen);
}
break;
case PUBACK:
case PUBREC:
case PUBREL:
case PUBCOMP:
{
unsigned char packettype, dup;
unsigned short packetid;
if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1)
MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid);
}
break;
case SUBACK:
{
unsigned short packetid;
int maxcount = 1, count = 0;
int grantedQoSs[1];
if (MQTTDeserialize_suback(&packetid, maxcount, &count, grantedQoSs, buf, buflen) == 1)
MQTTStringFormat_suback(strbuf, strbuflen, packetid, count, grantedQoSs);
}
break;
case UNSUBACK:
{
unsigned short packetid;
if (MQTTDeserialize_unsuback(&packetid, buf, buflen) == 1)
MQTTStringFormat_ack(strbuf, strbuflen, UNSUBACK, 0, packetid);
}
break;
case PINGREQ:
case PINGRESP:
case DISCONNECT:
snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]);
break;
}
return strbuf;
}
char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen)
{
int index = 0;
int rem_length = 0;
MQTTHeader header = {0};
header.byte = buf[index++];
index += MQTTPacket_decodeBuf(&buf[index], &rem_length);
switch (header.bits.type)
{
case CONNECT:
{
MQTTPacket_connectData data;
if ((MQTTDeserialize_connect(&data, buf, buflen)) == 1)
MQTTStringFormat_connect(strbuf, strbuflen, &data);
}
break;
case PUBLISH:
{
unsigned char dup, retained, *payload;
unsigned short packetid;
int qos, payloadlen;
MQTTString topicName = MQTTString_initializer;
if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName,
&payload, &payloadlen, buf, buflen) == 1)
MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid,
topicName, payload, payloadlen);
}
break;
case PUBACK:
case PUBREC:
case PUBREL:
case PUBCOMP:
{
unsigned char packettype, dup;
unsigned short packetid;
if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1)
MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid);
}
break;
case SUBSCRIBE:
{
unsigned char dup;
unsigned short packetid;
int maxcount = 1, count = 0;
MQTTString topicFilters[1];
int requestedQoSs[1];
if (MQTTDeserialize_subscribe(&dup, &packetid, maxcount, &count,
topicFilters, requestedQoSs, buf, buflen) == 1)
MQTTStringFormat_subscribe(strbuf, strbuflen, dup, packetid, count, topicFilters, requestedQoSs);;
}
break;
case UNSUBSCRIBE:
{
unsigned char dup;
unsigned short packetid;
int maxcount = 1, count = 0;
MQTTString topicFilters[1];
if (MQTTDeserialize_unsubscribe(&dup, &packetid, maxcount, &count, topicFilters, buf, buflen) == 1)
MQTTStringFormat_unsubscribe(strbuf, strbuflen, dup, packetid, count, topicFilters);
}
break;
case PINGREQ:
case PINGRESP:
case DISCONNECT:
snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]);
break;
}
strbuf[strbuflen] = '\0';
return strbuf;
}

View file

@ -0,0 +1,37 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#if !defined(MQTTFORMAT_H)
#define MQTTFORMAT_H
#include "StackTrace.h"
#include "MQTTPacket.h"
const char* MQTTPacket_getName(unsigned short packetid);
int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data);
int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent);
int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained,
unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen);
int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid);
int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count,
MQTTString topicFilters[], int requestedQoSs[]);
int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs);
int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid,
int count, MQTTString topicFilters[]);
char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen);
char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen);
#endif

View file

@ -0,0 +1,410 @@
/****************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Sergio R. Caprile - non-blocking packet read functions for stream transport
*******************************************************************************/
#include "StackTrace.h"
#include "MQTTPacket.h"
#include <string.h>
/**
* Encodes the message length according to the MQTT algorithm
* @param buf the buffer into which the encoded data is written
* @param length the length to be encoded
* @return the number of bytes written to buffer
*/
int MQTTPacket_encode(unsigned char* buf, int length)
{
int rc = 0;
FUNC_ENTRY;
do
{
char d = length % 128;
length /= 128;
/* if there are more digits to encode, set the top bit of this digit */
if (length > 0)
d |= 0x80;
buf[rc++] = d;
} while (length > 0);
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Decodes the message length according to the MQTT algorithm
* @param getcharfn pointer to function to read the next character from the data source
* @param value the decoded length returned
* @return the number of bytes read from the socket
*/
int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value)
{
unsigned char c;
int multiplier = 1;
int len = 0;
#define MAX_NO_OF_REMAINING_LENGTH_BYTES 4
FUNC_ENTRY;
*value = 0;
do
{
int rc = MQTTPACKET_READ_ERROR;
if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)
{
rc = MQTTPACKET_READ_ERROR; /* bad data */
goto exit;
}
rc = (*getcharfn)(&c, 1);
if (rc != 1)
goto exit;
*value += (c & 127) * multiplier;
multiplier *= 128;
} while ((c & 128) != 0);
exit:
FUNC_EXIT_RC(len);
return len;
}
int MQTTPacket_len(int rem_len)
{
rem_len += 1; /* header byte */
/* now remaining_length field */
if (rem_len < 128)
rem_len += 1;
else if (rem_len < 16384)
rem_len += 2;
else if (rem_len < 2097151)
rem_len += 3;
else
rem_len += 4;
return rem_len;
}
static unsigned char* bufptr;
int bufchar(unsigned char* c, int count)
{
int i;
for (i = 0; i < count; ++i)
*c = *bufptr++;
return count;
}
int MQTTPacket_decodeBuf(unsigned char* buf, int* value)
{
bufptr = buf;
return MQTTPacket_decode(bufchar, value);
}
/**
* Calculates an integer from two bytes read from the input buffer
* @param pptr pointer to the input buffer - incremented by the number of bytes used & returned
* @return the integer value calculated
*/
int readInt(unsigned char** pptr)
{
unsigned char* ptr = *pptr;
int len = 256*(*ptr) + (*(ptr+1));
*pptr += 2;
return len;
}
/**
* Reads one character from the input buffer.
* @param pptr pointer to the input buffer - incremented by the number of bytes used & returned
* @return the character read
*/
char readChar(unsigned char** pptr)
{
char c = **pptr;
(*pptr)++;
return c;
}
/**
* Writes one character to an output buffer.
* @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
* @param c the character to write
*/
void writeChar(unsigned char** pptr, char c)
{
**pptr = c;
(*pptr)++;
}
/**
* Writes an integer as 2 bytes to an output buffer.
* @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
* @param anInt the integer to write
*/
void writeInt(unsigned char** pptr, int anInt)
{
**pptr = (unsigned char)(anInt / 256);
(*pptr)++;
**pptr = (unsigned char)(anInt % 256);
(*pptr)++;
}
/**
* Writes a "UTF" string to an output buffer. Converts C string to length-delimited.
* @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
* @param string the C string to write
*/
void writeCString(unsigned char** pptr, const char* string)
{
int len = strlen(string);
writeInt(pptr, len);
memcpy(*pptr, string, len);
*pptr += len;
}
int getLenStringLen(char* ptr)
{
int len = 256*((unsigned char)(*ptr)) + (unsigned char)(*(ptr+1));
return len;
}
void writeMQTTString(unsigned char** pptr, MQTTString mqttstring)
{
if (mqttstring.lenstring.len > 0)
{
writeInt(pptr, mqttstring.lenstring.len);
memcpy(*pptr, mqttstring.lenstring.data, mqttstring.lenstring.len);
*pptr += mqttstring.lenstring.len;
}
else if (mqttstring.cstring)
writeCString(pptr, mqttstring.cstring);
else
writeInt(pptr, 0);
}
/**
* @param mqttstring the MQTTString structure into which the data is to be read
* @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
* @param enddata pointer to the end of the data: do not read beyond
* @return 1 if successful, 0 if not
*/
int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata)
{
int rc = 0;
FUNC_ENTRY;
/* the first two bytes are the length of the string */
if (enddata - (*pptr) > 1) /* enough length to read the integer? */
{
mqttstring->lenstring.len = readInt(pptr); /* increments pptr to point past length */
if (&(*pptr)[mqttstring->lenstring.len] <= enddata)
{
mqttstring->lenstring.data = (char*)*pptr;
*pptr += mqttstring->lenstring.len;
rc = 1;
}
}
mqttstring->cstring = NULL;
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Return the length of the MQTTstring - C string if there is one, otherwise the length delimited string
* @param mqttstring the string to return the length of
* @return the length of the string
*/
int MQTTstrlen(MQTTString mqttstring)
{
int rc = 0;
if (mqttstring.cstring)
rc = strlen(mqttstring.cstring);
else
rc = mqttstring.lenstring.len;
return rc;
}
/**
* Compares an MQTTString to a C string
* @param a the MQTTString to compare
* @param bptr the C string to compare
* @return boolean - equal or not
*/
int MQTTPacket_equals(MQTTString* a, char* bptr)
{
int alen = 0,
blen = 0;
char *aptr;
if (a->cstring)
{
aptr = a->cstring;
alen = strlen(a->cstring);
}
else
{
aptr = a->lenstring.data;
alen = a->lenstring.len;
}
blen = strlen(bptr);
return (alen == blen) && (strncmp(aptr, bptr, alen) == 0);
}
/**
* Helper function to read packet data from some source into a buffer
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param getfn pointer to a function which will read any number of bytes from the needed source
* @return integer MQTT packet type, or -1 on error
* @note the whole message must fit into the caller's buffer
*/
int MQTTPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int))
{
int rc = -1;
MQTTHeader header = {0};
int len = 0;
int rem_len = 0;
/* 1. read the header byte. This has the packet type in it */
if ((*getfn)(buf, 1) != 1)
goto exit;
len = 1;
/* 2. read the remaining length. This is variable in itself */
MQTTPacket_decode(getfn, &rem_len);
len += MQTTPacket_encode(buf + 1, rem_len); /* put the original remaining length back into the buffer */
/* 3. read the rest of the buffer using a callback to supply the rest of the data */
if((rem_len + len) > buflen)
goto exit;
if ((*getfn)(buf + len, rem_len) != rem_len)
goto exit;
header.byte = buf[0];
rc = header.bits.type;
exit:
return rc;
}
/**
* Decodes the message length according to the MQTT algorithm, non-blocking
* @param trp pointer to a transport structure holding what is needed to solve getting data from it
* @param value the decoded length returned
* @return integer the number of bytes read from the socket, 0 for call again, or -1 on error
*/
static int MQTTPacket_decodenb(MQTTTransport *trp)
{
unsigned char c;
int rc = MQTTPACKET_READ_ERROR;
FUNC_ENTRY;
if(trp->len == 0){ /* initialize on first call */
trp->multiplier = 1;
trp->rem_len = 0;
}
do {
int frc;
if (++(trp->len) > MAX_NO_OF_REMAINING_LENGTH_BYTES)
goto exit;
if ((frc=(*trp->getfn)(trp->sck, &c, 1)) == -1)
goto exit;
if (frc == 0){
rc = 0;
goto exit;
}
trp->rem_len += (c & 127) * trp->multiplier;
trp->multiplier *= 128;
} while ((c & 128) != 0);
rc = trp->len;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Helper function to read packet data from some source into a buffer, non-blocking
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param trp pointer to a transport structure holding what is needed to solve getting data from it
* @return integer MQTT packet type, 0 for call again, or -1 on error
* @note the whole message must fit into the caller's buffer
*/
int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport *trp)
{
int rc = -1, frc;
MQTTHeader header = {0};
switch(trp->state){
default:
trp->state = 0;
/*FALLTHROUGH*/
case 0:
/* read the header byte. This has the packet type in it */
if ((frc=(*trp->getfn)(trp->sck, buf, 1)) == -1)
goto exit;
if (frc == 0)
return 0;
trp->len = 0;
++trp->state;
/*FALLTHROUGH*/
/* read the remaining length. This is variable in itself */
case 1:
if((frc=MQTTPacket_decodenb(trp)) == MQTTPACKET_READ_ERROR)
goto exit;
if(frc == 0)
return 0;
trp->len = 1 + MQTTPacket_encode(buf + 1, trp->rem_len); /* put the original remaining length back into the buffer */
if((trp->rem_len + trp->len) > buflen)
goto exit;
++trp->state;
/*FALLTHROUGH*/
case 2:
/* read the rest of the buffer using a callback to supply the rest of the data */
if ((frc=(*trp->getfn)(trp->sck, buf + trp->len, trp->rem_len)) == -1)
goto exit;
if (frc == 0)
return 0;
trp->rem_len -= frc;
trp->len += frc;
if(trp->rem_len)
return 0;
header.byte = buf[0];
rc = header.bits.type;
break;
}
exit:
trp->state = 0;
return rc;
}

View file

@ -0,0 +1,133 @@
/*******************************************************************************
/ * Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Xiang Rong - 442039 Add makefile to Embedded C client
*******************************************************************************/
#ifndef MQTTPACKET_H_
#define MQTTPACKET_H_
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
extern "C" {
#endif
#if defined(WIN32_DLL) || defined(WIN64_DLL)
#define DLLImport __declspec(dllimport)
#define DLLExport __declspec(dllexport)
#elif defined(LINUX_SO)
#define DLLImport extern
#define DLLExport __attribute__ ((visibility ("default")))
#else
#define DLLImport
#define DLLExport
#endif
enum errors
{
MQTTPACKET_BUFFER_TOO_SHORT = -2,
MQTTPACKET_READ_ERROR = -1,
MQTTPACKET_READ_COMPLETE
};
enum msgTypes
{
CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL,
PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK,
PINGREQ, PINGRESP, DISCONNECT
};
/**
* Bitfields for the MQTT header byte.
*/
typedef union
{
unsigned char byte; /**< the whole byte */
#if defined(REVERSED)
struct
{
unsigned int type : 4; /**< message type nibble */
unsigned int dup : 1; /**< DUP flag bit */
unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */
unsigned int retain : 1; /**< retained flag bit */
} bits;
#else
struct
{
unsigned int retain : 1; /**< retained flag bit */
unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */
unsigned int dup : 1; /**< DUP flag bit */
unsigned int type : 4; /**< message type nibble */
} bits;
#endif
} MQTTHeader;
typedef struct
{
int len;
char* data;
} MQTTLenString;
typedef struct
{
char* cstring;
MQTTLenString lenstring;
} MQTTString;
#define MQTTString_initializer {NULL, {0, NULL}}
int MQTTstrlen(MQTTString mqttstring);
#include "MQTTConnect.h"
#include "MQTTPublish.h"
#include "MQTTSubscribe.h"
#include "MQTTUnsubscribe.h"
#include "MQTTFormat.h"
int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char type, unsigned char dup, unsigned short packetid);
int MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int buflen);
int MQTTPacket_len(int rem_len);
int MQTTPacket_equals(MQTTString* a, char* b);
int MQTTPacket_encode(unsigned char* buf, int length);
int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value);
int MQTTPacket_decodeBuf(unsigned char* buf, int* value);
int readInt(unsigned char** pptr);
char readChar(unsigned char** pptr);
void writeChar(unsigned char** pptr, char c);
void writeInt(unsigned char** pptr, int anInt);
int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata);
void writeCString(unsigned char** pptr, const char* string);
void writeMQTTString(unsigned char** pptr, MQTTString mqttstring);
DLLExport int MQTTPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int));
typedef struct {
int (*getfn)(void *, unsigned char*, int); /* must return -1 for error, 0 for call again, or the number of bytes read */
void *sck; /* pointer to whatever the system may use to identify the transport */
int multiplier;
int rem_len;
int len;
char state;
}MQTTTransport;
int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport *trp);
#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */
}
#endif
#endif /* MQTTPACKET_H_ */

View file

@ -0,0 +1,38 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Xiang Rong - 442039 Add makefile to Embedded C client
*******************************************************************************/
#ifndef MQTTPUBLISH_H_
#define MQTTPUBLISH_H_
#if !defined(DLLImport)
#define DLLImport
#endif
#if !defined(DLLExport)
#define DLLExport
#endif
DLLExport int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid,
MQTTString topicName, unsigned char* payload, int payloadlen);
DLLExport int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName,
unsigned char** payload, int* payloadlen, unsigned char* buf, int len);
DLLExport int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid);
DLLExport int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid);
DLLExport int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid);
#endif /* MQTTPUBLISH_H_ */

View file

@ -0,0 +1,169 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Ian Craggs - fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=453144
*******************************************************************************/
#include "MQTTPacket.h"
#include "StackTrace.h"
#include <string.h>
/**
* Determines the length of the MQTT publish packet that would be produced using the supplied parameters
* @param qos the MQTT QoS of the publish (packetid is omitted for QoS 0)
* @param topicName the topic name to be used in the publish
* @param payloadlen the length of the payload to be sent
* @return the length of buffer needed to contain the serialized version of the packet
*/
int MQTTSerialize_publishLength(int qos, MQTTString topicName, int payloadlen)
{
int len = 0;
len += 2 + MQTTstrlen(topicName) + payloadlen;
if (qos > 0)
len += 2; /* packetid */
return len;
}
/**
* Serializes the supplied publish data into the supplied buffer, ready for sending
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param dup integer - the MQTT dup flag
* @param qos integer - the MQTT QoS value
* @param retained integer - the MQTT retained flag
* @param packetid integer - the MQTT packet identifier
* @param topicName MQTTString - the MQTT topic in the publish
* @param payload byte buffer - the MQTT publish payload
* @param payloadlen integer - the length of the MQTT payload
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid,
MQTTString topicName, unsigned char* payload, int payloadlen)
{
unsigned char *ptr = buf;
MQTTHeader header = {0};
int rem_len = 0;
int rc = 0;
FUNC_ENTRY;
if (MQTTPacket_len(rem_len = MQTTSerialize_publishLength(qos, topicName, payloadlen)) > buflen)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.bits.type = PUBLISH;
header.bits.dup = dup;
header.bits.qos = qos;
header.bits.retain = retained;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;
writeMQTTString(&ptr, topicName);
if (qos > 0)
writeInt(&ptr, packetid);
memcpy(ptr, payload, payloadlen);
ptr += payloadlen;
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes the ack packet into the supplied buffer.
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param type the MQTT packet type
* @param dup the MQTT dup flag
* @param packetid the MQTT packet identifier
* @return serialized length, or error if 0
*/
int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char packettype, unsigned char dup, unsigned short packetid)
{
MQTTHeader header = {0};
int rc = 0;
unsigned char *ptr = buf;
FUNC_ENTRY;
if (buflen < 4)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.bits.type = packettype;
header.bits.dup = dup;
header.bits.qos = (packettype == PUBREL) ? 1 : 0;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */
writeInt(&ptr, packetid);
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes a puback packet into the supplied buffer.
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param packetid integer - the MQTT packet identifier
* @return serialized length, or error if 0
*/
int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid)
{
return MQTTSerialize_ack(buf, buflen, PUBACK, 0, packetid);
}
/**
* Serializes a pubrel packet into the supplied buffer.
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param dup integer - the MQTT dup flag
* @param packetid integer - the MQTT packet identifier
* @return serialized length, or error if 0
*/
int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid)
{
return MQTTSerialize_ack(buf, buflen, PUBREL, dup, packetid);
}
/**
* Serializes a pubrel packet into the supplied buffer.
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param packetid integer - the MQTT packet identifier
* @return serialized length, or error if 0
*/
int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid)
{
return MQTTSerialize_ack(buf, buflen, PUBCOMP, 0, packetid);
}

View file

@ -0,0 +1,39 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Xiang Rong - 442039 Add makefile to Embedded C client
*******************************************************************************/
#ifndef MQTTSUBSCRIBE_H_
#define MQTTSUBSCRIBE_H_
#if !defined(DLLImport)
#define DLLImport
#endif
#if !defined(DLLExport)
#define DLLExport
#endif
DLLExport int MQTTSerialize_subscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,
int count, MQTTString topicFilters[], int requestedQoSs[]);
DLLExport int MQTTDeserialize_subscribe(unsigned char* dup, unsigned short* packetid,
int maxcount, int* count, MQTTString topicFilters[], int requestedQoSs[], unsigned char* buf, int len);
DLLExport int MQTTSerialize_suback(unsigned char* buf, int buflen, unsigned short packetid, int count, int* grantedQoSs);
DLLExport int MQTTDeserialize_suback(unsigned short* packetid, int maxcount, int* count, int grantedQoSs[], unsigned char* buf, int len);
#endif /* MQTTSUBSCRIBE_H_ */

View file

@ -0,0 +1,135 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "MQTTPacket.h"
#include "StackTrace.h"
#include <string.h>
/**
* Determines the length of the MQTT subscribe packet that would be produced using the supplied parameters
* @param count the number of topic filter strings in topicFilters
* @param topicFilters the array of topic filter strings to be used in the publish
* @return the length of buffer needed to contain the serialized version of the packet
*/
int MQTTSerialize_subscribeLength(int count, MQTTString topicFilters[])
{
int i;
int len = 2; /* packetid */
for (i = 0; i < count; ++i)
len += 2 + MQTTstrlen(topicFilters[i]) + 1; /* length + topic + req_qos */
return len;
}
/**
* Serializes the supplied subscribe data into the supplied buffer, ready for sending
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied bufferr
* @param dup integer - the MQTT dup flag
* @param packetid integer - the MQTT packet identifier
* @param count - number of members in the topicFilters and reqQos arrays
* @param topicFilters - array of topic filter names
* @param requestedQoSs - array of requested QoS
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTSerialize_subscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid, int count,
MQTTString topicFilters[], int requestedQoSs[])
{
unsigned char *ptr = buf;
MQTTHeader header = {0};
int rem_len = 0;
int rc = 0;
int i = 0;
FUNC_ENTRY;
if (MQTTPacket_len(rem_len = MQTTSerialize_subscribeLength(count, topicFilters)) > buflen)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = SUBSCRIBE;
header.bits.dup = dup;
header.bits.qos = 1;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;
writeInt(&ptr, packetid);
for (i = 0; i < count; ++i)
{
writeMQTTString(&ptr, topicFilters[i]);
writeChar(&ptr, requestedQoSs[i]);
}
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Deserializes the supplied (wire) buffer into suback data
* @param packetid returned integer - the MQTT packet identifier
* @param maxcount - the maximum number of members allowed in the grantedQoSs array
* @param count returned integer - number of members in the grantedQoSs array
* @param grantedQoSs returned array of integers - the granted qualities of service
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @return error code. 1 is success, 0 is failure
*/
int MQTTDeserialize_suback(unsigned short* packetid, int maxcount, int* count, int grantedQoSs[], unsigned char* buf, int buflen)
{
MQTTHeader header = {0};
unsigned char* curdata = buf;
unsigned char* enddata = NULL;
int rc = 0;
int mylen;
FUNC_ENTRY;
header.byte = readChar(&curdata);
if (header.bits.type != SUBACK)
goto exit;
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
enddata = curdata + mylen;
if (enddata - curdata < 2)
goto exit;
*packetid = readInt(&curdata);
*count = 0;
while (curdata < enddata)
{
if (*count > maxcount)
{
rc = -1;
goto exit;
}
grantedQoSs[(*count)++] = readChar(&curdata);
}
rc = 1;
exit:
FUNC_EXIT_RC(rc);
return rc;
}

View file

@ -0,0 +1,110 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "MQTTPacket.h"
#include "StackTrace.h"
#include <string.h>
/**
* Deserializes the supplied (wire) buffer into subscribe data
* @param dup integer returned - the MQTT dup flag
* @param packetid integer returned - the MQTT packet identifier
* @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays
* @param count - number of members in the topicFilters and requestedQoSs arrays
* @param topicFilters - array of topic filter names
* @param requestedQoSs - array of requested QoS
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTDeserialize_subscribe(unsigned char* dup, unsigned short* packetid, int maxcount, int* count, MQTTString topicFilters[],
int requestedQoSs[], unsigned char* buf, int buflen)
{
MQTTHeader header = {0};
unsigned char* curdata = buf;
unsigned char* enddata = NULL;
int rc = -1;
int mylen = 0;
FUNC_ENTRY;
header.byte = readChar(&curdata);
if (header.bits.type != SUBSCRIBE)
goto exit;
*dup = header.bits.dup;
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
enddata = curdata + mylen;
*packetid = readInt(&curdata);
*count = 0;
while (curdata < enddata)
{
if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata))
goto exit;
if (curdata >= enddata) /* do we have enough data to read the req_qos version byte? */
goto exit;
requestedQoSs[*count] = readChar(&curdata);
(*count)++;
}
rc = 1;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes the supplied suback data into the supplied buffer, ready for sending
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param packetid integer - the MQTT packet identifier
* @param count - number of members in the grantedQoSs array
* @param grantedQoSs - array of granted QoS
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTSerialize_suback(unsigned char* buf, int buflen, unsigned short packetid, int count, int* grantedQoSs)
{
MQTTHeader header = {0};
int rc = -1;
unsigned char *ptr = buf;
int i;
FUNC_ENTRY;
if (buflen < 2 + count)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = SUBACK;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, 2 + count); /* write remaining length */
writeInt(&ptr, packetid);
for (i = 0; i < count; ++i)
writeChar(&ptr, grantedQoSs[i]);
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}

View file

@ -0,0 +1,38 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Xiang Rong - 442039 Add makefile to Embedded C client
*******************************************************************************/
#ifndef MQTTUNSUBSCRIBE_H_
#define MQTTUNSUBSCRIBE_H_
#if !defined(DLLImport)
#define DLLImport
#endif
#if !defined(DLLExport)
#define DLLExport
#endif
DLLExport int MQTTSerialize_unsubscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,
int count, MQTTString topicFilters[]);
DLLExport int MQTTDeserialize_unsubscribe(unsigned char* dup, unsigned short* packetid, int max_count, int* count, MQTTString topicFilters[],
unsigned char* buf, int len);
DLLExport int MQTTSerialize_unsuback(unsigned char* buf, int buflen, unsigned short packetid);
DLLExport int MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int len);
#endif /* MQTTUNSUBSCRIBE_H_ */

View file

@ -0,0 +1,104 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "MQTTPacket.h"
#include "StackTrace.h"
#include <string.h>
/**
* Determines the length of the MQTT unsubscribe packet that would be produced using the supplied parameters
* @param count the number of topic filter strings in topicFilters
* @param topicFilters the array of topic filter strings to be used in the publish
* @return the length of buffer needed to contain the serialized version of the packet
*/
int MQTTSerialize_unsubscribeLength(int count, MQTTString topicFilters[])
{
int i;
int len = 2; /* packetid */
for (i = 0; i < count; ++i)
len += 2 + MQTTstrlen(topicFilters[i]); /* length + topic*/
return len;
}
/**
* Serializes the supplied unsubscribe data into the supplied buffer, ready for sending
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @param dup integer - the MQTT dup flag
* @param packetid integer - the MQTT packet identifier
* @param count - number of members in the topicFilters array
* @param topicFilters - array of topic filter names
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTSerialize_unsubscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,
int count, MQTTString topicFilters[])
{
unsigned char *ptr = buf;
MQTTHeader header = {0};
int rem_len = 0;
int rc = -1;
int i = 0;
FUNC_ENTRY;
if (MQTTPacket_len(rem_len = MQTTSerialize_unsubscribeLength(count, topicFilters)) > buflen)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = UNSUBSCRIBE;
header.bits.dup = dup;
header.bits.qos = 1;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;
writeInt(&ptr, packetid);
for (i = 0; i < count; ++i)
writeMQTTString(&ptr, topicFilters[i]);
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Deserializes the supplied (wire) buffer into unsuback data
* @param packetid returned integer - the MQTT packet identifier
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @return error code. 1 is success, 0 is failure
*/
int MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int buflen)
{
unsigned char type = 0;
unsigned char dup = 0;
int rc = 0;
FUNC_ENTRY;
rc = MQTTDeserialize_ack(&type, &dup, packetid, buf, buflen);
if (type == UNSUBACK)
rc = 1;
FUNC_EXIT_RC(rc);
return rc;
}

View file

@ -0,0 +1,100 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "MQTTPacket.h"
#include "StackTrace.h"
#include <string.h>
/**
* Deserializes the supplied (wire) buffer into unsubscribe data
* @param dup integer returned - the MQTT dup flag
* @param packetid integer returned - the MQTT packet identifier
* @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays
* @param count - number of members in the topicFilters and requestedQoSs arrays
* @param topicFilters - array of topic filter names
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTDeserialize_unsubscribe(unsigned char* dup, unsigned short* packetid, int maxcount, int* count, MQTTString topicFilters[],
unsigned char* buf, int len)
{
MQTTHeader header = {0};
unsigned char* curdata = buf;
unsigned char* enddata = NULL;
int rc = 0;
int mylen = 0;
FUNC_ENTRY;
header.byte = readChar(&curdata);
if (header.bits.type != UNSUBSCRIBE)
goto exit;
*dup = header.bits.dup;
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
enddata = curdata + mylen;
*packetid = readInt(&curdata);
*count = 0;
while (curdata < enddata)
{
if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata))
goto exit;
(*count)++;
}
rc = 1;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes the supplied unsuback data into the supplied buffer, ready for sending
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param packetid integer - the MQTT packet identifier
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTSerialize_unsuback(unsigned char* buf, int buflen, unsigned short packetid)
{
MQTTHeader header = {0};
int rc = 0;
unsigned char *ptr = buf;
FUNC_ENTRY;
if (buflen < 2)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = UNSUBACK;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */
writeInt(&ptr, packetid);
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}

View file

@ -0,0 +1,78 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Ian Craggs - fix for bug #434081
*******************************************************************************/
#ifndef STACKTRACE_H_
#define STACKTRACE_H_
#include <stdio.h>
#define NOSTACKTRACE 1
#if defined(NOSTACKTRACE)
#define FUNC_ENTRY
#define FUNC_ENTRY_NOLOG
#define FUNC_ENTRY_MED
#define FUNC_ENTRY_MAX
#define FUNC_EXIT
#define FUNC_EXIT_NOLOG
#define FUNC_EXIT_MED
#define FUNC_EXIT_MAX
#define FUNC_EXIT_RC(x)
#define FUNC_EXIT_MED_RC(x)
#define FUNC_EXIT_MAX_RC(x)
#else
#if defined(WIN32)
#define inline __inline
#define FUNC_ENTRY StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MINIMUM)
#define FUNC_ENTRY_NOLOG StackTrace_entry(__FUNCTION__, __LINE__, -1)
#define FUNC_ENTRY_MED StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MEDIUM)
#define FUNC_ENTRY_MAX StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MAXIMUM)
#define FUNC_EXIT StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MINIMUM)
#define FUNC_EXIT_NOLOG StackTrace_exit(__FUNCTION__, __LINE__, -1)
#define FUNC_EXIT_MED StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MEDIUM)
#define FUNC_EXIT_MAX StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MAXIMUM)
#define FUNC_EXIT_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MINIMUM)
#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MEDIUM)
#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MAXIMUM)
#else
#define FUNC_ENTRY StackTrace_entry(__func__, __LINE__, TRACE_MINIMUM)
#define FUNC_ENTRY_NOLOG StackTrace_entry(__func__, __LINE__, -1)
#define FUNC_ENTRY_MED StackTrace_entry(__func__, __LINE__, TRACE_MEDIUM)
#define FUNC_ENTRY_MAX StackTrace_entry(__func__, __LINE__, TRACE_MAXIMUM)
#define FUNC_EXIT StackTrace_exit(__func__, __LINE__, NULL, TRACE_MINIMUM)
#define FUNC_EXIT_NOLOG StackTrace_exit(__func__, __LINE__, NULL, -1)
#define FUNC_EXIT_MED StackTrace_exit(__func__, __LINE__, NULL, TRACE_MEDIUM)
#define FUNC_EXIT_MAX StackTrace_exit(__func__, __LINE__, NULL, TRACE_MAXIMUM)
#define FUNC_EXIT_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MINIMUM)
#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MEDIUM)
#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MAXIMUM)
void StackTrace_entry(const char* name, int line, int trace);
void StackTrace_exit(const char* name, int line, void* return_value, int trace);
void StackTrace_printStack(FILE* dest);
char* StackTrace_get(unsigned long);
#endif
#endif
#endif /* STACKTRACE_H_ */

View file

@ -0,0 +1,271 @@
#include "osdep_service.h"
#include "serial_api.h"
#include <timer_api.h>
#include "freertos_pmu.h"
#include <mDNS/mDNS.h>
#include "gpio_api.h"
#include "gpio_irq_api.h"
#include "PinNames.h"
/******************************************************
* Macros
******************************************************/
#define UA_ERROR 0
#define UA_WARNING 1
#define UA_INFO 2
#define UA_DEBUG 3
#define UA_NONE 0xFF
#define UA_DEBUG_LEVEL UA_INFO
#define UA_UART_THREAD_PRIORITY 5
#define UA_UART_THREAD_STACKSIZE 512
#define UA_TCP_SERVER_FD_NUM 1
#define UA_TCP_CLIENT_FD_NUM 1
#define UA_UART_RECV_BUFFER_LEN 8196
#define UA_UART_FRAME_LEN 1400
#define UA_UART_MAX_DELAY_TIME 100
#define UA_CHAT_SOCKET_PORT 5001
#define UA_CONTROL_SOCKET_PORT 6001
#define UA_SC_SOFTAP_EN 1
#ifdef CONFIG_PLATFORM_8195A
#define UA_UART_TX_PIN PA_7
#define UA_UART_RX_PIN PA_6
#define UA_GPIO_LED_PIN PC_5
#define UA_GPIO_IRQ_PIN PC_4
#define UA_GPIO_TIMER TIMER0
#define UA_GPIO_WAKEUP_PIN PC_3
#endif
#ifdef CONFIG_PLATFORM_8711B
#define UA_UART_TX_PIN PA_23
#define UA_UART_RX_PIN PA_18
#define UA_GPIO_LED_PIN PA_5
#define UA_GPIO_IRQ_PIN PA_12
#define UA_GPIO_TIMER TIMER2
#define UA_GPIO_WAKEUP_PIN PA_0
#endif
#define UA_CONTROL_PREFIX "AMEBA_UART"
#define UA_PS_ENABLE 0
#define UA_WAKELOCK PMU_DEV_USER_BASE
#define UA_FAST_RECONNECT_TCP_DATA (0xF5000 + 0x1000)
#if (UA_DEBUG_LEVEL== UA_NONE)
#define ua_printf(level, fmt, arg...)
#else
#define ua_printf(level, fmt, arg...) \
do {\
if (level <= UA_DEBUG_LEVEL) {\
if (level <= UA_ERROR) {\
rtw_down_sema(&ua_print_sema);\
printf("\r\nERROR: " fmt, ##arg);\
rtw_up_sema(&ua_print_sema);\
} \
else {\
rtw_down_sema(&ua_print_sema);\
printf("\r\n"fmt, ##arg);\
rtw_up_sema(&ua_print_sema);\
} \
}\
}while(0)
#endif
#define UA_PRINT_DATA(_HexData, _HexDataLen) \
if(UA_DEBUG_LEVEL == UA_DEBUG) \
{ \
int __i; \
u8 *ptr = (u8 *)_HexData; \
printf("--------Len=%d\n\r", _HexDataLen); \
for( __i=0; __i<(int)_HexDataLen; __i++ ) \
{ \
printf("%02X%s", ptr[__i], (((__i + 1) % 4) == 0)?" ":" "); \
if (((__i + 1) % 16) == 0) printf("\n\r"); \
} \
printf("\n\r"); \
}
#define UA_SOCKET_CHECK(_ua_socket) \
if(_ua_socket == NULL) \
{ \
printf("ERROR: ua_socket = NULL\n\r"); \
return; \
}
#define UA_SOCKET_CHECK_2(_ua_socket) \
if(_ua_socket == NULL) \
{ \
printf("ERROR: ua_socket = NULL\n\r"); \
return -1; \
}
/******************************************************
* Constants
******************************************************/
typedef enum
{
UART_ADAPTER_LED_ON = 0,
UART_ADAPTER_LED_OFF = 1,
UART_ADAPTER_LED_FAST_TWINKLE = 2,
UART_ADAPTER_LED_SLOW_TWINKLE = 3,
}ua_led_mode_t;
typedef enum
{
UART_CTRL_MODE_SET_REQ = 0,
UART_CTRL_MODE_SET_RSP = 1,
UART_CTRL_MODE_GET_REQ = 2,
UART_CTRL_MODE_GET_RSP = 3,
}ua_ctrl_mode_t;
typedef enum
{
UART_CTRL_TYPE_BAUD_RATE = 0x01,
UART_CTRL_TYPE_WORD_LEN = 0x02,
UART_CTRL_TYPE_PARITY = 0x04,
UART_CTRL_TYPE_STOP_BIT = 0x08,
UART_CTRL_TYPE_TCP_SERVER_CREATE = 0x10,
UART_CTRL_TYPE_TCP_SERVER_DELETE = 0x20,
UART_CTRL_TYPE_TCP_CLIENT_CONNECT = 0x40,
UART_CTRL_TYPE_TCP_CLIENT_DISCONNECT = 0x80,
UART_CTRL_TYPE_TCP_GROUP_ID = 0x100,
}ua_ctrl_type_t;
/******************************************************
* Structures
******************************************************/
typedef struct _ua_uart_param_t
{
u8 WordLen;
u8 Parity;
u8 StopBit;
u8 FlowControl;
int BaudRate;
}ua_uart_param_t;
typedef struct _ua_uart_socket_t
{
int fd;
char rcv_ch;
volatile char overlap;
int recv_bytes;
volatile int pread;
volatile int pwrite;
volatile unsigned int tick_last_update;
unsigned int tick_current;
volatile int tx_busy;
volatile int uart_ps;
volatile int uart_ps_cnt;
char recv_buf[UA_UART_RECV_BUFFER_LEN];
long rx_cnt;
long miss_cnt;
serial_t uart_sobj;
ua_uart_param_t uart_param;
_sema action_sema;
_sema tcp_tx_rx_sema;
_sema dma_tx;
}ua_uart_socket_t;
typedef struct _ua_tcp_socket_t
{
int chat_socket;
int control_socket;
int chat_server_listen_socket;
int control_server_listen_socket;
int transmit_recv_socket;
int transmit_send_socket;
int transmit_server_listen_socket;
int group_id;
u32 server_port;
u32 client_port;
char client_ip[16];
int send_flag;
int recv_flag;
long rx_cnt;
long tx_cnt;
volatile int tcp_ps;
volatile int tcp_ps_cnt;
}ua_tcp_socket_t;
typedef struct _ua_gpio_t
{
gpio_t gpio_led;
gpio_t gpio_btn;
gpio_irq_t gpio_btn_irq;
gtimer_t gpio_timer;
}ua_gpio_t;
typedef struct _ua_socket_t
{
ua_uart_socket_t uart;
ua_tcp_socket_t tcp;
ua_gpio_t gpio;
ip_addr_t ip;
DNSServiceRef dnsServiceRef;
DNSServiceRef dnsServiceRef2;
}ua_socket_t;
typedef struct _ua_mbox_buffer
{
char data[UA_UART_FRAME_LEN];
int data_len;
}ua_mbox_buffer_t;
//Save Uart Settings when get uart information
typedef struct _ua_uart_get_str
{
int BaudRate; //The baud rate
char number; //The number of data bits
char parity; //The parity(0: none, 1:odd, 2:evn, default:0)
char StopBits; //The number of stop bits
char FlowControl; //support flow control is 1
}ua_uart_get_str;
//Uart Setting information
typedef struct _ua_uart_set_str
{
char UartName[8]; // the name of uart
int BaudRate; //The baud rate
char number; //The number of data bits
char parity; //The parity(default NONE)
char StopBits; //The number of stop bits
char FlowControl; //support flow control is 1
}ua_uart_set_str;
int uartadapter_init();
void uartadapter_tcp_send_data(ua_socket_t *ua_socket, char *buffer, int size);
void uartadapter_tcp_send_control(ua_socket_t *ua_socket, char *buffer, int size);
void uartadapter_tcp_transmit_server_thread(void *param);
void uartadapter_tcp_transmit_client_thread(void *param);
int uartadapter_tcpclient(ua_socket_t *ua_socket, const char *host_ip, unsigned short usPort);
void uartadapter_tcp_transmit_client_forever_thread(void *param);
void example_uart_adapter_init();
void cmd_uart_adapter(int argc, char **argv);
void uartadapter_tcp_transmit_socket_handler(ua_socket_t *ua_socket, char *tcp_rxbuf);

View file

@ -0,0 +1,82 @@
#include "FreeRTOS.h"
#include "task.h"
#include "wifi_conf.h"
#include "wifi_ind.h"
#include "google/google_nest.h"
#include "flash_api.h"
#include "wigadget.h"
#include <lwip/netif.h>
#include "shtc1.h"
#define CLOUD_PORT 443
extern struct netif xnetif[NET_IF_NUM];
void cloud_link_task(void *param){
googlenest_context googlenest;
unsigned char URI[64];
unsigned char data[97] = {0};
unsigned char host_addr[64] = {0};
flash_t cloud_flash;
u8 *mac = (u8 *)LwIP_GetMAC(&xnetif[0]);
char i[16], j[16];
float temperature = 1.123f;
float humidity = 2.456f;
int ret = 0;
vTaskDelay(2000);
sprintf(URI, "ht_sensor/%02x%02x%02x%02x%02x%02x.json", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
memset(host_addr, 0, sizeof(host_addr));
if(flash_stream_read(&cloud_flash, FLASH_IOT_DATA, 97, (uint8_t *) data) == 1){
memset(host_addr, 0 , 64);
memcpy(host_addr, data+33, 64);
while(1) {
printf("\r\n\r\n\r\n\r\n\r\n\r\n=====>START CLOUD LINKING\r\n\r\n");
memset(i, 0, 16);
memset(j, 0, 16);
#if PSEUDO_DATA
sprintf(i,"%.2f", temperature++);
sprintf(j, "%.2f", humidity++);
if(temperature > 60)
temperature = 1.123f;
if(humidity > 98)
humidity = 2.456f;
#else
ret = SHTC_GetTempAndHumi(&temperature, &humidity);
sprintf(i, "%.2f", temperature);
sprintf(j, "%.2f", humidity);
#endif
if(ret < 0)
printf("\r\n\r\n<-----LOCAL LINK FAILED!!(get infor failed)\r\n\r\n");
else{
gen_json_data(i, j, data);
printf("\r\nCLOUD-LINK--Sending data : \r\n%s\r\n", data);
memset(&googlenest, 0, sizeof(googlenest_context));
if(gn_connect(&googlenest, host_addr, CLOUD_PORT) == 0) {
if(gn_put(&googlenest, URI, data) != 0)
printf("\r\n\r\nPUT data failed!\r\n\r\n");
gn_close(&googlenest);
printf("\r\n\r\n<=====CLOUD LINK OK!!\r\n\r\n");
}
else{
printf("\r\n\r\n<=====CLOUD LINK FAILED!!(google nest connecting)\r\n\r\n");
}
free(data);
vTaskDelay(10000);
}
}
}
else
printf("\r\n\r\n<=====CLOUD LINK FAILED!!(flash reading)\r\n\r\n");
}
void start_cloud_link(void)
{
if(xTaskCreate(cloud_link_task, ((const char*)"cloud_link_task"), 3584, NULL, tskIDLE_PRIORITY + 4, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
}

View file

@ -0,0 +1,11 @@
#ifndef CLOUD_LINK_H
#define CLOUD_LINK_THREAD_H
#include "wigadget.h"
void start_cloud_link(void);
void cloud_link_task(void *param);
#endif

View file

@ -0,0 +1,25 @@
#ifndef _WI_ENCRYPT_H_
#define _WI_ENCRYPT_H_
#include "rom_aes.h"
typedef union
{ unsigned int l;
unsigned char b[4];
} aes_inf;
typedef struct
{
aes_context ctx;
aes_inf inf;
} aes_encrypt_ctx;
typedef struct
{
aes_context ctx;
aes_inf inf;
} aes_decrypt_ctx;
#endif

View file

@ -0,0 +1,195 @@
#include "FreeRTOS.h"
#include "task.h"
#include "device.h"
#include "PinNames.h"
#include "basic_types.h"
#include "diag.h"
#include "osdep_service.h"
#include "i2c_api.h"
#include "pinmap.h"
#include "shtc1.h"
#ifdef CONFIG_PLATFORM_8195A
#define MBED_I2C_MTR_SDA PB_3
#define MBED_I2C_MTR_SCL PB_2
#endif
#ifdef CONFIG_PLATFORM_8711B
#define MBED_I2C_MTR_SDA PA_19
#define MBED_I2C_MTR_SCL PA_22
#endif
#define MBED_I2C_SLAVE_ADDR0 0x70
#define POLYNOMIAL 0x131 // P(x) = x^8 + x^5 + x^4 + 1 = 100110001
#define MBED_I2C_BUS_CLK 100000 //hz
#define I2C_DATA_MAX_LENGTH 16
static uint8_t i2cdata_write[I2C_DATA_MAX_LENGTH];
static uint8_t i2cdata_read[I2C_DATA_MAX_LENGTH];
static int i2cdata_read_pos;
static i2c_t i2cmaster;
// Sensor Commands
#define READ_ID 0xEFC8 // command: read ID register
#define SOFT_RESET 0x805D // soft resetSample Code for SHTC1
#define MEAS_T_RH_POLLING 0x7866 // meas. read T first, clock stretching disabled
#define MEAS_T_RH_CLOCKSTR 0x7CA2 // meas. read T first, clock stretching enabled
#define MEAS_RH_T_POLLING 0x58E0 // meas. read RH first, clock stretching disabled
#define MEAS_RH_T_CLOCKSTR 0x5C24 // meas. read RH first, clock stretching enabled
static int SHTC1_GetID(uint16_t *id);
static void SHTC1_WriteCommand(uint16_t cmd);
static int SHTC1_Read2BytesAndCrc(uint16_t *data);
static int SHTC1_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum);
static float SHTC1_CalcTemperature(uint16_t rawValue);
static float SHTC1_CalcHumidity(uint16_t rawValue);
int SHTC_Init(uint16_t *pID)
{
int error = NO_ERROR;
DiagPrintf("SHTC1_Init \r\n");
i2c_init((i2c_t*)&i2cmaster, MBED_I2C_MTR_SDA ,MBED_I2C_MTR_SCL);
i2c_frequency((i2c_t*)&i2cmaster,MBED_I2C_BUS_CLK);
if (pID == NULL )
return NULL_ERROR;
error = SHTC1_GetID(pID);
return error;
}
static int SHTC1_GetID(uint16_t *id)
{
int error = NO_ERROR;
uint8_t bytes[2];
uint8_t checksum;
SHTC1_WriteCommand(READ_ID);
i2c_read((i2c_t*)&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[0], 3, 1);
i2cdata_read_pos = 0;
error = SHTC1_Read2BytesAndCrc(id);
return error;
}
static int SHTC1_Read2BytesAndCrc(uint16_t *data)
{
int error;
int readed;
uint8_t bytes[2];
uint8_t checksum;
bytes[0] = i2cdata_read[i2cdata_read_pos++];
bytes[1] = i2cdata_read[i2cdata_read_pos++];
checksum = i2cdata_read[i2cdata_read_pos++];
error = SHTC1_CheckCrc(bytes, 2, checksum);
*data = (bytes[0] << 8) | bytes[1];
return error;
}
static int SHTC1_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum)
{
uint8_t bit; // bit mask
uint8_t crc = 0xFF; // calculated checksum
uint8_t byteCtr; // byte counter
for(byteCtr = 0; byteCtr < nbrOfBytes; byteCtr++){
crc ^= (data[byteCtr]);
for(bit = 8; bit > 0; --bit){
if(crc & 0x80)
crc = (crc << 1) ^ POLYNOMIAL;
else
crc = (crc << 1);
}
}
if(crc != checksum)
return CHECKSUM_ERROR;
else
return NO_ERROR;
}
static void SHTC1_WriteCommand(uint16_t cmd)
{
int writebytes;
i2cdata_write[0] = (uint8_t)(cmd >>8);
i2cdata_write[1] = (uint8_t)(cmd&0xFF);
i2c_write((i2c_t*)&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdata_write[0], 2, 1);
}
static float SHTC1_CalcTemperature(uint16_t rawValue)
{
return 175.0 * (float)rawValue / 65536.0 - 45.0;
}
static float SHTC1_CalcHumidity(uint16_t rawValue)
{
return 100.0 * (float)rawValue / 65536.0;
}
int SHTC_GetTempAndHumi(float *temp, float *humi)
{
int error;
uint16_t rawValueTemp;
uint16_t rawValueHumi;
SHTC1_WriteCommand(MEAS_T_RH_CLOCKSTR);
i2c_read((i2c_t*)&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[0], 6, 1);
i2cdata_read_pos = 0;
error = NO_ERROR;
error |= SHTC1_Read2BytesAndCrc(&rawValueTemp);
error |= SHTC1_Read2BytesAndCrc(&rawValueHumi);
if ( error == NO_ERROR ) {
*temp = SHTC1_CalcTemperature(rawValueTemp);
*humi = SHTC1_CalcHumidity(rawValueHumi);
}
return error;
}
static void example_shtc1_thread(void *param)
{
int error;
uint16_t shtc1_id;
float temperature = 1.123f;
float humidity = 2.456f;
DBG_8195A("sleep 10 sec. to wait for UART console\n");
rtw_msleep_os(10000);
DBG_8195A("start i2c example - SHTC1\n");
error = SHTC_Init(&shtc1_id);
if ( error == NO_ERROR )
DiagPrintf("SHTC1 init ok, id=0x%x\r\n", shtc1_id);
else {
DiagPrintf("SHTC1 init FAILED! \r\n");
for(;;);
}
while(1){
error = SHTC_GetTempAndHumi(&temperature, &humidity);
rtl_printf("temp=%f, humidity=%f, error=%d\n", temperature, humidity, error);
rtw_msleep_os(1000);
}
}
void example_shtc1(void)
{
if(xTaskCreate(example_shtc1_thread, ((const char*)"example_shtc1_thread"), 512, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__);
}

View file

@ -0,0 +1,13 @@
#ifndef SHTC1_H
#define SHTC1_H
#define NO_ERROR 0x00
#define ACK_ERROR 0x01
#define CHECKSUM_ERROR 0x02
#define NULL_ERROR 0x03
int SHTC_GetTempAndHumi(float *temp, float *humi);
int SHTC_Init(uint16_t *pID);
void example_shtc1(void);
#endif

View file

@ -0,0 +1,732 @@
#include "FreeRTOS.h"
#include "task.h"
#include "wifi_conf.h"
#include "wifi_ind.h"
#include "sockets.h"
#include <mDNS/mDNS.h>
#include <lwip_netconf.h>
#include <lwip/netif.h>
#include "flash_api.h"
#include "encrypt.h"
#include "gpio_api.h"
#include "gpio_irq_api.h"
#include "cJSON.h"
#include "cloud_link.h"
#include "wigadget.h"
#include "shtc1.h"
#define PORT 6866
#define MAX_BUFFER_SIZE 256
#define ENC_SIZE 64
#define CONTROL_TYPE 1
#ifdef CONFIG_PLATFORM_8195A
#define GPIO_SOFTAP_RESET_PIN PC_4
#endif
#ifdef CONFIG_PLATFORM_8711B
#define GPIO_SOFTAP_RESET_PIN PA_0
#endif
flash_t iot_flash;
uint8_t aes_key[16];
static unsigned char tx_buffer[MAX_BUFFER_SIZE];
static unsigned char rx_buffer[MAX_BUFFER_SIZE];
extern struct netif xnetif[NET_IF_NUM];
#define DEBUG_IOT 1
#define IOT_LOG(level, fmt, ...) printf("\n\r[IOT %s] %s: " fmt "\n", level, __FUNCTION__, ##__VA_ARGS__)
#if DEBUG_IOT == 2
#define IOT_DEBUG(fmt, ...) IOT_LOG("DEBUG", fmt, ##__VA_ARGS__)
#else
#define IOT_DEBUG(fmt, ...)
#endif
#if DEBUG_IOT
#define IOT_ERROR(fmt, ...) IOT_LOG("ERROR", fmt, ##__VA_ARGS__)
#else
#define IOT_ERROR(fmt, ...)
#endif
void encrypt_data_aes(unsigned char *plaint_text, unsigned char *enc_data);
void decrypt_data_aes(unsigned char *enc_data, unsigned char *dec_data, int data_len);
static unsigned int arc4random(void)
{
unsigned int res = xTaskGetTickCount();
static unsigned int seed = 0xDEADB00B;
seed = ((seed & 0x007F00FF) << 7) ^
((seed & 0x0F80FF00) >> 8) ^ // be sure to stir those low bits
(res << 13) ^ (res >> 9); // using the clock too!
return seed;
}
static char *iot_itoa(int value)
{
char *val_str;
int tmp = value, len = 1;
while((tmp /= 10) > 0)
len ++;
val_str = (char *) malloc(len + 1);
sprintf(val_str, "%d", value);
return val_str;
}
void gen_json_data(char *i, char *j, unsigned char *json_data)
{
cJSON_Hooks memoryHook;
memoryHook.malloc_fn = malloc;
memoryHook.free_fn = free;
cJSON_InitHooks(&memoryHook);
memset(json_data, 0, ENC_SIZE);
cJSON *IOTJSObject = NULL;
char *data;
if((IOTJSObject = cJSON_CreateObject()) != NULL) {
cJSON_AddItemToObject(IOTJSObject, "TEM", cJSON_CreateString(i));
cJSON_AddItemToObject(IOTJSObject, "HUM", cJSON_CreateString(j));
data = cJSON_Print(IOTJSObject);
memcpy(json_data, data, strlen(data));
cJSON_Delete(IOTJSObject);
free(data);
}
}
void encrypt_data_aes(unsigned char *plaint_text, unsigned char *enc_data)
{
unsigned char iv[16] = {0};
unsigned char* iv_bak = "AAAAAAAAAAAAAAAA";
aes_encrypt_ctx enc_ctx;
memset(&enc_ctx, 0, sizeof(enc_ctx));
memset(iv, 0, sizeof(iv));
memcpy(iv, iv_bak, sizeof(iv));
memset(enc_data, 0, sizeof(enc_data));
aes_init();
aes_encrypt_key(aes_key, 16, &enc_ctx);
aes_cbc_encrypt(plaint_text, enc_data, ENC_SIZE, iv, &enc_ctx);
}
void decrypt_data_aes(unsigned char *enc_data, unsigned char *dec_data, int data_len)
{
unsigned char iv[16] = {0};
unsigned char* iv_bak = "AAAAAAAAAAAAAAAA";
aes_decrypt_ctx dec_ctx;
memset(&dec_ctx, 0, sizeof(dec_ctx));
memset(iv, 0, sizeof(iv));
memcpy(iv, iv_bak, sizeof(iv));
memset(dec_data, 0, sizeof(dec_data));
aes_init();
aes_decrypt_key(aes_key, 16, &dec_ctx);
aes_cbc_decrypt(enc_data, dec_data, data_len, iv, &dec_ctx);
IOT_DEBUG("Decrypt data: %s\r\n",dec_data);
}
void iotapp_platform_reset(void)
{
HAL_WRITE32(SYSTEM_CTRL_BASE, 0x14, 0x00000021);
osDelay(100);
HAL_WRITE32(0xE000ED00, 0x0C, (0x5FA << 16) |
(HAL_READ32(0xE000ED00, 0x0C) & (7 << 8)) |
(1 << 2));
while(1) osDelay(1000);
}
void iotapp_reset_irq_handler(uint32_t id, gpio_irq_event event)
{
printf("\n\r\n\r\n\r\n\r<<<<<<Reset the device>>>>>>>\n\r\n\r\n\r\n\r");
flash_erase_sector(&iot_flash, FLASH_IOT_DATA);
iotapp_platform_reset();
}
int local_link(unsigned char *tx_data)
{
int sockfd, newsockfd;
socklen_t client;
struct sockaddr_in serv_addr, cli_addr;
uint8_t rx_data[ENC_SIZE];
unsigned char enc_data[ENC_SIZE];
unsigned char dec_data[ENC_SIZE];
int ret = 0, opt = 1, k = 1, j;
char *result = NULL, *backup = NULL;
unsigned char *data = NULL;
char *delims = ", ";
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
IOT_ERROR("ERROR opening socket");
ret = -1;
goto exit2;
}
if((setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt))) < 0){
IOT_ERROR("ERROR on setting socket option");
ret = -1;
goto exit2;
}
memset((char *)&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(PORT);
if (bind(sockfd, (struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) {
IOT_ERROR("ERROR on binding");
ret = -1;
goto exit2;
}
if(listen(sockfd , 20) < 0){
IOT_ERROR("ERROR on listening");
ret = -1;
goto exit2;
}
client = sizeof(cli_addr);
if((newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr,&client)) < 0){
IOT_ERROR("ERROR on accept");
ret = -1;
goto exit;
}
if ((ret = read(newsockfd,rx_buffer,sizeof(rx_buffer))) < 0){
IOT_ERROR("ERROR reading from socket");
ret = -1;
goto exit;
}
IOT_DEBUG("cmd received: %s, length: %d\r\n",rx_buffer, ret);
//Changing received data to string
if (!strncmp(rx_buffer, "[", strlen("["))){
data = rx_buffer + strlen("[");
for(j = 1; j < 5; j++){
if (data[ret - j] == ']')
data[ret -j] = '\0';
}
}
else
strcpy(data, rx_buffer);
memset(rx_data, 0, sizeof(rx_data));
result = strtok_r(data, delims, &backup);
rx_data[0]=(uint8_t)atoi(result);
while((result = strtok_r(NULL, delims, &backup)) != NULL)
rx_data[k++]=(uint8_t)atoi(result);
memset(dec_data, 0, sizeof(dec_data));
//Decrpyt the received data
decrypt_data_aes(rx_data, dec_data, 16);
if(strncmp(dec_data, "request", strlen("request")) == 0){
//Encrypt the sending data
memset(enc_data, 0, strlen(enc_data));
encrypt_data_aes(tx_data, enc_data);
//Changing encrpyt data to JAVA type string
for (j = 0; j < ENC_SIZE; j++){
char *temp;
temp = iot_itoa(enc_data[j]);
if(j == 0)
strcpy(tx_buffer, "[");
strcat(tx_buffer,temp);
if (j == (ENC_SIZE - 1))
strcat(tx_buffer,"]");
else
strcat(tx_buffer,",");
free(temp);
temp = NULL;
}
IOT_DEBUG("Data reply to APP: %s\r\nLength of data: %d\r\n", tx_buffer, strlen(tx_buffer));
if ((ret = write(newsockfd,tx_buffer,strlen(tx_buffer))) < 0){
IOT_ERROR("ERROR writing to socket");
ret = -1;
goto exit;
}
else
IOT_DEBUG("Sending %d bytes data OK!\r\n", ret);
}
else if(strncmp(dec_data, "remove", strlen("remove")) == 0){
printf("\n\r\n\r\n\r\n\r<<<<<<Reset the device >>>>>>>\n\r\n\r\n\r\n\r");
flash_erase_sector(&iot_flash, FLASH_IOT_DATA);
write(newsockfd,"Remove OK",strlen("Remove OK"));
close(newsockfd);
close(sockfd);
iotapp_platform_reset();
}
else{
IOT_ERROR("ERROR wrong KEY or wrong request!");
write(newsockfd,"The KEY or the request is not correct!",strlen("The KEY or the request is not correct!"));
ret = -1;
goto exit;
}
exit:
if(close(newsockfd) != 0)
goto exit;
exit2:
if(close(sockfd) != 0)
goto exit2;
return ret;
}
static void local_link_task(void *param)
{
unsigned char data[ENC_SIZE] = {0};
vTaskDelay(1000);
char i[16], j[16];
float temperature = 1.123f;
float humidity = 2.456f;
int ret = 0;
while(1){
memset(i, 0, 16);
memset(j, 0, 16);
#if PSEUDO_DATA
sprintf(i,"%.2f", temperature++);
sprintf(j, "%.2f", humidity++);
if(temperature > 60)
temperature = 1.123f;
if(humidity > 98)
humidity = 2.456f;
#else
ret = SHTC_GetTempAndHumi(&temperature, &humidity);
sprintf(i,"%.2f", temperature);
sprintf(j, "%.2f", humidity);
#endif
if(ret < 0)
printf("\r\n\r\n<-----LOCAL LINK FAILED!!(get infor failed)\r\n\r\n");
else{
printf("\r\n\r\n----->START LOCAL LINKING\r\n\r\n");
gen_json_data(i, j, data);
printf("Sending data : %s\r\n", data);
if (local_link(data) < 0)
printf("\r\n\r\n<-----LOCAL LINK FAILED!!\r\n\r\n");
else
printf("\r\n\r\n<-----LOCAL LINK OK!!\r\n\r\n");
vTaskDelay(1000);
}
}
}
void start_local_link(void)
{
if(xTaskCreate(local_link_task, ((const char*)"local_link_task"), 5376, NULL, tskIDLE_PRIORITY + 4, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
}
int pair_device(unsigned char *tx_buffer, unsigned char *rx_buffer, int handshake)
{
int sockfd, newsockfd;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
int ret = 0;
int opt = 1;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
IOT_ERROR("ERROR opening socket");
ret = -1;
goto exit;
}
if((setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt))) < 0){
IOT_ERROR("ERROR on setting socket option");
ret = -1;
goto exit;
}
memset((char *)&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_len = sizeof(serv_addr);
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(PORT);
if ((bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) < 0) {
IOT_ERROR("ERROR on binding");
ret = -1;
goto exit;
}
if ((listen(sockfd, 5)) < 0){
IOT_ERROR("ERROR on listening tcp server socket fd");
ret = -1;
goto exit;
}
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t*)&clilen);
if (newsockfd < 0) {
IOT_ERROR("ERROR on accept");
ret = -1;
goto exit2;
}
ret = read(newsockfd, rx_buffer, MAX_BUFFER_SIZE);
if (ret <= 0){
IOT_ERROR("ERROR reading from socket");
ret = -1;
goto exit2;
}
IOT_DEBUG("Request received: %s, byte: %d\r\n",rx_buffer, ret);
if(handshake == 1){
if(strncmp(rx_buffer,"PAIR", strlen("PAIR")) != 0){
write(newsockfd, "ERROR", strlen("ERROR"));
IOT_ERROR("ERROR on first handshake!");
ret = -1;
goto exit2;
}
}
else if(handshake == 2){
if((rx_buffer == NULL) ||(strlen(rx_buffer) < 32)){
write(newsockfd, "ERROR", strlen("ERROR"));
IOT_ERROR("ERROR on second handshake!");
ret = -1;
goto exit2;
}
}
else if(handshake == 3){
unsigned char account[64];
unsigned char enc_acc[64];
char *result = NULL, *backup = NULL;
unsigned char *data = NULL;
char *delims = ", ";
int j, k = 1;
if (!strncmp(rx_buffer, "[", strlen("["))){
data = rx_buffer + strlen("[");
for(j = 1; j < 5; j++){
if (data[ret - j] == ']')
data[ret -j] = '\0';
}
}
else
strcpy(data, rx_buffer);
memset(enc_acc, 0, sizeof(enc_acc));
result = strtok_r(data, delims, &backup);
enc_acc[0]=(uint8_t)atoi(result);
while((result = strtok_r(NULL, delims, &backup)) != NULL)
enc_acc[k++]=(uint8_t)atoi(result);
IOT_DEBUG("The value of k: %d", k);
memset(account, 0, sizeof(account));
decrypt_data_aes(enc_acc, account, k);
if((strncmp(account,"https://", strlen("https://"))) != 0){
write(newsockfd, "ERROR", strlen("ERROR"));
IOT_ERROR("ERROR on third handshake!");
ret = -1;
goto exit2;
}
else{
IOT_DEBUG("The received Firebase URL:%s", account);
memset(rx_buffer, 0, strlen(rx_buffer));
memcpy(rx_buffer, (account+strlen("https://")), (strlen(account) + strlen("https://")));
}
}
ret = write(newsockfd, tx_buffer, strlen(tx_buffer));
IOT_DEBUG("Data send: %s\r\n",tx_buffer);
if (ret < 0){
IOT_ERROR("ERROR writing to socket");
}
exit:
if(close(newsockfd) != 0)
goto exit;
exit2:
if(close(sockfd) != 0)
goto exit2;
return ret;
}
static void pair_device_task(void)
{
int i, j, k, HANDSHAKE;
uint8_t PAIR_STATE[1] = {0};
if(CONTROL_TYPE == 1){
printf("\r\n\r\n<<<<<<CONTROL_TYPE = 1 Need 3 times handshake>>>>>>\r\n\r\n");
HANDSHAKE = 3;
}
else{
printf("\r\n\r\n<<<<<<CONTROL_TYPE = 0 Need 2 times handshake>>>>>>\r\n\r\n");
HANDSHAKE = 2;
}
printf("\r\n\r\n=========>PAIR_STATE = 0 Start to pair\r\n\r\n");
for(i = 0; i < HANDSHAKE; i++){
static const uint8_t basepoint[32] = {9};
uint8_t mysecret[32];
uint8_t mypublic[32];
uint8_t theirpublic[32] = {0};
uint8_t shared_key[32];
//First handshake
if(i == 0){
printf("\r\n\r\n===>Start the first handshake\r\n\r\n");
memset(tx_buffer, 0, sizeof(tx_buffer));
memset(rx_buffer, 0, sizeof(rx_buffer));
for(j = 0; j < 32; j ++)
mysecret[j] = (uint8_t) arc4random();
mysecret[j] = '\0';
curve25519_donna(mypublic, mysecret, basepoint);
for (j = 0; j < 32; j++){
char *temp;
temp = iot_itoa(mypublic[j]);
if(j == 0)
strcpy(tx_buffer, "[");
strcat(tx_buffer,temp);
if (j == 31)
strcat(tx_buffer,"]");
else
strcat(tx_buffer,",");
free(temp);
temp = NULL;
}
if(pair_device(tx_buffer, rx_buffer, 1) >= 0)
printf("\r\n\r\n<===First handshake OK!!\r\n\r\n");
else{
i--;
printf("\r\n\r\n<===First handshake FAILED!!\r\n\r\n");
}
}
//Second handshake
if(i == 1){
printf("\r\n\r\n=====>Start the second handshake\r\n\r\n");
vTaskDelay(200);
memset(tx_buffer, 0, sizeof(tx_buffer));
if(CONTROL_TYPE == 1)
memcpy(tx_buffer, "FIREBASE URL", sizeof("FIREBASE URL"));
else
memcpy(tx_buffer, "PAIR OK", sizeof("PAIR OK"));
memset(rx_buffer, 0, sizeof(rx_buffer));
if(pair_device(tx_buffer, rx_buffer, 2) >= 0){
char *result = NULL, *backup = NULL;
unsigned char *data = NULL;
char *delims = ", ";
k = 1;
if (!strncmp(rx_buffer, "[", strlen("["))){
data = rx_buffer + strlen("[");
int len;
len = strlen(data);
for(j = 1; j < 5; j++){
if (data[len - j] == ']')
data[len -j] = '\0';
}
}
else
strcpy(data, rx_buffer);
memset(theirpublic, 0, sizeof(theirpublic));
result = strtok_r(data, delims, &backup);
theirpublic[0]=(uint8_t)atoi(result);
while((result = strtok_r(NULL, delims, &backup)) != NULL)
theirpublic[k++] = (uint8_t)atoi(result);
curve25519_donna(shared_key, mysecret, theirpublic);
for(j = 0; j < 16; j ++)
aes_key[j] = shared_key[j];
//Store the KEY in FLASH
if(CONTROL_TYPE == 0){
PAIR_STATE[0] = 1;
uint8_t data[33];
memset(data, 0, 33);
memcpy(data, PAIR_STATE, 1);
memcpy(data+1, shared_key, 32);
flash_erase_sector(&iot_flash, FLASH_IOT_DATA);
flash_stream_write(&iot_flash, FLASH_IOT_DATA, 33, (uint8_t *) data);
IOT_DEBUG("PAIR_STATE: %d\r\n", PAIR_STATE[0]);
}
printf("\r\n\r\n<=====Second handshake OK!!\r\n\r\n");
}
else{
i = i - 2;
printf("\r\n\r\n<=====Second handshake FAILED!!\r\n\r\n");
}
}
//Third handshake
if(i == 2){
printf("\r\n\r\n=======>Start the third handshake\r\n\r\n");
vTaskDelay(200);
memset(tx_buffer, 0, sizeof(tx_buffer));
memcpy(tx_buffer, "PAIR OK", sizeof("PAIR OK"));
memset(rx_buffer, 0, sizeof(rx_buffer));
if(pair_device(tx_buffer, rx_buffer, 3) >= 0){
IOT_DEBUG("rx_buffer: %s, sizeof rx_buffer:%d\r\n", rx_buffer, sizeof(rx_buffer));
PAIR_STATE[0] = 1;
uint8_t data[97];
memset(data, 0, 97);
memcpy(data, PAIR_STATE, 1);
memcpy(data+1, shared_key, 32);
memcpy(data+33, rx_buffer, 64);
flash_erase_sector(&iot_flash, FLASH_IOT_DATA);
flash_stream_write(&iot_flash, FLASH_IOT_DATA, 97, (uint8_t *) data);
IOT_DEBUG("PAIR_STATE: %d\r\n", PAIR_STATE[0]);
printf("\r\n\r\n<=======Third handshake OK!!\r\n\r\n");
}
else{
i = i - 3;
printf("\r\n\r\n<=======Third handshake FAILED!!\r\n\r\n");
}
}
}
printf("\r\n\r\n<=========Pairing OK!!\r\n\r\n");
}
static void mdns_task(void *param)
{
DNSServiceRef dnsServiceRef = NULL;
TXTRecordRef txtRecord;
unsigned char txt_buf[128];
uint8_t *mac, *ip;
int j, ret = 0;
uint8_t *flash_data;
uint8_t PAIR_STATE[1] = {0};
static unsigned char MAC_ADD[21];
static unsigned char IP[16];
static unsigned char port[6];
uint16_t shtc1_id;
// Delay to wait for IP by DHCP and get the information of IP and MAC
printf("\n\r\n\r\n\r\n\r<<<<<<Waiting for 20 seconds to connect Wi-Fi>>>>>>>\n\r\n\r\n\r\n\r");
vTaskDelay(20000);
ip = LwIP_GetIP(&xnetif[0]);
mac = LwIP_GetMAC(&xnetif[0]);
sprintf(MAC_ADD, "%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
sprintf(IP, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
sprintf(port, "%d", PORT);
IOT_DEBUG("MAC => %s\r\n", MAC_ADD) ;
IOT_DEBUG("IP => %s\r\n", IP);
IOT_DEBUG("PORT => %s\r\n", port);
//Get the value of PAIR_STATE and the AES key in flash
flash_data = (uint8_t *)malloc(33);
flash_stream_read(&iot_flash, FLASH_IOT_DATA, 33, (uint8_t *)flash_data);
memcpy(PAIR_STATE, flash_data, 1);
if(PAIR_STATE[0] != 0x1)
PAIR_STATE[0] = 0;
else{
for(j = 0;j < 16; j++){
aes_key[j] = flash_data[j+1];
}
}
free(flash_data);
IOT_DEBUG("PAIR_STATE now: %d\r\n", PAIR_STATE[0]);
IOT_DEBUG("=>mDNS Init\r\n");
if(mDNSResponderInit() == 0) {
printf("\r\n\r\n========>Start to register mDNS service\r\n\r\n");
//The device not paired before
if(PAIR_STATE[0] == 0){
TXTRecordCreate(&txtRecord, sizeof(txt_buf), txt_buf);
TXTRecordSetValue(&txtRecord, "IP", strlen(IP), IP);
TXTRecordSetValue(&txtRecord, "PORT", strlen(port), port);
TXTRecordSetValue(&txtRecord, "MAC_ADDR", strlen(MAC_ADD), MAC_ADD);
TXTRecordSetValue(&txtRecord, "PAIR_STATE", strlen("0"), "0");
TXTRecordSetValue(&txtRecord, "SERVICE_NAME", strlen("ht_sensor"), "ht_sensor");
if(CONTROL_TYPE == 1)
TXTRecordSetValue(&txtRecord, "CONTROL_TYPE", strlen("1"), "1");
else
TXTRecordSetValue(&txtRecord, "CONTROL_TYPE", strlen("0"), "0");
dnsServiceRef = mDNSRegisterService("ht_sensor", "_Ameba._tcp", "local", PORT, &txtRecord);
TXTRecordDeallocate(&txtRecord);
printf("\r\n\r\n<========Registering mDNS service OK!!\r\n\r\n");
pair_device_task();
}
//The device was paired
else if(PAIR_STATE[0] == 0x1){
TXTRecordCreate(&txtRecord, sizeof(txt_buf), txt_buf);
TXTRecordSetValue(&txtRecord, "IP", strlen(ip), ip);
TXTRecordSetValue(&txtRecord, "PORT", strlen(port), port);
TXTRecordSetValue(&txtRecord, "MAC_ADDR", strlen(MAC_ADD), MAC_ADD);
TXTRecordSetValue(&txtRecord, "PAIR_STATE", strlen("1"), "1");
TXTRecordSetValue(&txtRecord, "SERVICE_NAME", strlen("ht_sensor"), "ht_sensor");
if(CONTROL_TYPE == 1)
TXTRecordSetValue(&txtRecord, "CONTROL_TYPE", strlen("1"), "1");
else
TXTRecordSetValue(&txtRecord, "CONTROL_TYPE", strlen("0"), "0");
dnsServiceRef = mDNSRegisterService("ht_sensor", "_Ameba._tcp", "local", PORT, &txtRecord);
TXTRecordDeallocate(&txtRecord);
printf("\r\n\r\n<========Registering mDNS service OK!! PAIR_STATE = 1\r\n\r\n");
}
#if PSEUDO_DATA
printf("\r\n\r\n========>Using the speudo data\r\n\r\n");
if(CONTROL_TYPE == 1) start_cloud_link();
start_local_link();
#else
//Init the shtc1 sensor
printf("\r\n\r\n========>Init the temperature and humidity sensor\r\n\r\n");
ret = SHTC_Init(&shtc1_id);
if ( ret == NO_ERROR ){
printf("\r\n\r\n<========Senser init OK! ID = 0x%x \r\n\r\n", shtc1_id);
if(CONTROL_TYPE == 1) start_cloud_link();
start_local_link();
}
else {
printf("\r\n\r\n<========Senser init FAILED! ID = 0x%x \r\n\r\n", shtc1_id);
ret = -1;
}
#endif
}
else
ret = -1;
if(ret == 0){
while(1){
IOT_DEBUG("Update the mDNS textrecord!\r\n");
TXTRecordCreate(&txtRecord, sizeof(txt_buf), txt_buf);
TXTRecordSetValue(&txtRecord, "IP", strlen(IP), IP);
TXTRecordSetValue(&txtRecord, "PORT", strlen(port), port);
TXTRecordSetValue(&txtRecord, "MAC_ADDR", strlen(MAC_ADD), MAC_ADD);
TXTRecordSetValue(&txtRecord, "PAIR_STATE", strlen("1"), "1");
if(CONTROL_TYPE == 1)
TXTRecordSetValue(&txtRecord, "CONTROL_TYPE", strlen("1"), "1");
else
TXTRecordSetValue(&txtRecord, "CONTROL_TYPE", strlen("0"), "0");
TXTRecordSetValue(&txtRecord, "SERVICE_NAME", strlen("ht_sensor"), "ht_sensor");
mDNSUpdateService(dnsServiceRef, &txtRecord, 0);
TXTRecordDeallocate(&txtRecord);
vTaskDelay(2*60*1000);
}
}
else{
if(dnsServiceRef)
mDNSDeregisterService(dnsServiceRef);
IOT_DEBUG("<=mDNS Deinit\r\n\r\n");
mDNSResponderDeinit();
}
}
void example_wigadget(void)
{
if(xTaskCreate(mdns_task, ((const char*)"mdns_task"), 3072, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
gpio_t gpio_softap_reset_button;
gpio_irq_t gpioirq_softap_reset_button;
gpio_irq_init(&gpioirq_softap_reset_button, GPIO_SOFTAP_RESET_PIN, iotapp_reset_irq_handler, (uint32_t)(&gpio_softap_reset_button));
gpio_irq_set(&gpioirq_softap_reset_button, IRQ_FALL, 1);
gpio_irq_enable(&gpioirq_softap_reset_button);
}

View file

@ -0,0 +1,11 @@
#ifndef WIGADGET_H
#define WIGADGET_H
#define FLASH_IOT_DATA (0x0007E000)
#define PSEUDO_DATA 1
void example_wigadget(void);
void gen_json_data(char *i, char *j, unsigned char *json_data);
#endif /* WIGADGET_H */

Some files were not shown because too many files have changed in this diff Show more