zaki.wang 5 лет назад
Сommit
99cc5fbf2d
14 измененных файлов с 2348 добавлено и 0 удалено
  1. 504 0
      LICENSE
  2. 56 0
      README.md
  3. 16 0
      SConscript
  4. 56 0
      docs/README.md
  5. 82 0
      docs/api.md
  6. 58 0
      docs/samples.md
  7. 136 0
      docs/user-guide.md
  8. 7 0
      docs/version.md
  9. 41 0
      inc/ntp_client.h
  10. 197 0
      inc/wayz_pos.h
  11. 92 0
      samples/location_client.c
  12. 9 0
      src/SConscript
  13. 305 0
      src/ntp_client.c
  14. 789 0
      src/wayz_pos.c

+ 504 - 0
LICENSE

@@ -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.
+
+    {description}
+    Copyright (C) {year} {fullname}
+
+    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!

+ 56 - 0
README.md

@@ -0,0 +1,56 @@
+# wayz_iotkit
+
+## 1、介绍
+
+wayz_iotkit 是上海图趣信息科技有限公司,针对【硬件名称或型号】开发的能够实现定位功能的物联网组件。在使用传统上定位,如 GPS 等信号的同时,也支持使用基站、Wifi等数据,通过 WAYZ 定位云来进行定位。当前版本以实现支持wifi定位,后期会逐步实现对其他信号源的利用,进一步提升定位效果。
+
+### 1.1 目录结构
+
+| 名称 | 说明 |
+| ---- | ---- |
+| docs  | 文档目录 |
+| examples | 例子目录,并有相应的一些说明 |
+| inc  | 头文件目录 |
+| src  | 源代码目录 |
+
+### 1.2 许可证
+
+wayz_iotkit package 遵循 LGPLv2.1 许可,详见 `LICENSE` 文件。
+
+### 1.3 依赖
+
+- RT-Thread 3.0+
+- RT-Thread 开发 WLAN 框架
+- webclient软件包
+- cJSON软件包
+
+## 2、如何打开 wayz_iotkit
+
+使用 wayz_iotkit package 需要在 RT-Thread 的包管理器中选择它,具体路径如下:
+
+```
+RT-Thread online packages
+    IOT - internet of things --->
+        [*] wayz_iotkit: wayz iot location
+            (wayz123) wifi ssid
+            (wayz1234) wifi password
+            Version (v1.0.0)   --->
+```
+
+- 然后让 RT-Thread 的包管理器自动更新,或者使用 `pkgs --update` 命令更新包到 BSP 中。
+
+## 3、使用 wayz_iotkit
+
+- 如何从零开始使用,请参考 [用户手册](docs/user-guide.md)
+- 完整的 API 文档,请参考 [API 手册](docs/api.md)
+- 详细的示例介绍,请参考 [示例文档](docs/samples.md) 
+
+## 4、注意事项
+
+- 该组件是基于wlan框架上运用的wifi定位,前提条件必须要有wifi芯片
+- 利用该组件时,需要重新开启任务处理,防止内存过小引发错误
+
+## 5、联系方式 & 感谢
+
+* 维护:jianxiong.ye
+* 主页:https://github.com/RT-Thread-packages/hello

+ 16 - 0
SConscript

@@ -0,0 +1,16 @@
+# RT-Thread building script for bridge
+
+import os
+from building import *
+
+cwd = GetCurrentDir()
+objs = []
+list = os.listdir(cwd)
+
+if GetDepend('PKG_USING_WAYZ_IOTKIT'):
+    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')

+ 56 - 0
docs/README.md

@@ -0,0 +1,56 @@
+# wayz_iotkit
+
+## 1、介绍
+
+wayz_iotkit 是上海图趣信息科技有限公司,针对【硬件名称或型号】开发的能够实现定位功能的物联网组件。在使用传统上定位,如 GPS 等信号的同时,也支持使用基站、Wifi等数据,通过 WAYZ 定位云来进行定位。当前版本以实现支持wifi定位,后期会逐步实现对其他信号源的利用,进一步提升定位效果。
+
+### 1.1 目录结构
+
+| 名称 | 说明 |
+| ---- | ---- |
+| docs  | 文档目录 |
+| examples | 例子目录,并有相应的一些说明 |
+| inc  | 头文件目录 |
+| src  | 源代码目录 |
+
+### 1.2 许可证
+
+wayz_iotkit package 遵循 LGPLv2.1 许可,详见 `LICENSE` 文件。
+
+### 1.3 依赖
+
+- RT-Thread 3.0+
+- RT-Thread 开发 WLAN 框架
+- webclient软件包
+- cJSON软件包
+
+## 2、如何打开 wayz_iotkit
+
+使用 wayz_iotkit package 需要在 RT-Thread 的包管理器中选择它,具体路径如下:
+
+```
+RT-Thread online packages
+    IOT - internet of things --->
+        [*] wayz_iotkit: wayz iot location
+            (wayz123) wifi ssid
+            (wayz1234) wifi password
+            Version (v1.0.0)   --->
+```
+
+- 然后让 RT-Thread 的包管理器自动更新,或者使用 `pkgs --update` 命令更新包到 BSP 中。
+
+## 3、使用 wayz_iotkit
+
+- 如何从零开始使用,请参考 [用户手册](docs/user-guide.md)
+- 完整的 API 文档,请参考 [API 手册](docs/api.md)
+- 详细的示例介绍,请参考 [示例文档](docs/samples.md) 
+
+## 4、注意事项
+
+- 该组件是基于wlan框架上运用的wifi定位,前提条件必须要有wifi芯片
+- 利用该组件时,需要重新开启任务处理,防止内存过小引发错误
+
+## 5、联系方式 & 感谢
+
+* 维护:jianxiong.ye
+* 主页:https://github.com/wayz-iot/wayz_iotkit.git

+ 82 - 0
docs/api.md

@@ -0,0 +1,82 @@
+# wayz_iotkit API
+
+
+```c
+/**
+ * Wifi parameter initialized
+ * 
+ * @param ssid: Wifi name
+ * 
+ * @param passwd: Wifi password
+ * 
+ * @return twifi_info: Dynamic allocation wifi info structure
+*/
+twifi_info *wifi_param_init(const char *ssid, const char *passwd);
+
+/**
+ * device parameter initialized
+ * 
+ * @param dev_name: device name
+ * 
+ * @param manufacturer: device manufacturer
+ * 
+ * @param product: product name
+ * 
+ * @param SN: product serial number
+ * 
+ * @param tenant: tenant device
+ * 
+ * @return tdeviec_info: Dynamic allocation device info structure
+*/
+tdeviec_info *dev_para_init(const char *dev_name, const char *manufacturer, const char *product, \
+                const char *SN, const char *tenant);
+
+/**
+ * Wifi station mac address
+ * 
+ * @param data: Wifi station mac address data
+ * 
+ * @return void
+*/
+void get_sta_mac_addr(char *data);
+
+/**
+ * Connected to the Internet to register
+ *
+ * @param wlan_info: wifi name , wifi passwd
+ *
+ * @param dev_info: device info ,(dev_name、manufacturer、SN、product、tenant)
+ * 
+ * @param key: Visiting the website key
+ *
+ * @return =0: wifi connect failure
+ *         =1: device register success
+ *         =2: device register failure
+ */
+char dev_register_init(twifi_info *wlan_info, tdeviec_info *dev_info, char *key);
+
+/**
+ * Get the positioning result function
+ * 
+ * @param wlan_info: Wifi related information
+ * 
+ * @param key: Visiting the website key
+ * 
+ * @param location: get location result
+ * 
+ * @return >0: success
+ *         =0: location failure
+ * 
+*/
+char get_position_info(twifi_info *wlan_info, char *key, tlocation_info *location);
+
+/**
+ * print location result
+ * 
+ * @param location location info
+ * 
+ * @return void:
+ * 
+*/
+void location_print(tlocation_info location);
+```

+ 58 - 0
docs/samples.md

@@ -0,0 +1,58 @@
+# wayz_iotkit 示例程序 #
+
+| 示例程序路径                   | 说明 |
+| ----                          | ---- |
+| samples/location_client.c.c   | wayz_iotkit 测试例程 |
+
+## 运行示例 ##
+
+## 1、申请ACCESS_KEY
+
+- 需要在平台申请ACCESS_KEY,目前只能提供人工申请的方式
+在示例代码中的宏中填写申请的ACCESS_KEY字段,例如:
+```c
+#define  ACCESS_KEY     "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+```
+## 2、填写wifi、设备相关信息
+修改将所要连接网络的AP即用户名、密码等;也可以在选择组件时指定wifi相关信息。例如:
+```c
+#ifdef PKG_WAYZ_IOTKIT_WIFI_SSID
+#define  WAYZ_WIFI_SSID      PKG_WAYZ_IOTKIT_WIFI_SSID
+#else
+#define  WAYZ_WIFI_SSID      "thread"
+#endif
+
+#ifdef PKG_WAYZ_IOTKIT_WIFI_PASSWORD
+#define  WAYZ_WIFI_PWD      PKG_WAYZ_IOTKIT_WIFI_PASSWORD
+#else
+#define  WAYZ_WIFI_PWD      "12345678"
+#endif
+```
+修改设备相关信息,例如:
+```c
+#define  DEV_NAME       "PANDDRA"      // 设备名称
+#define  VENDER         "ALIENTEK"	   // 设备生产商
+#define  PRODUCT        "FINDU01"	   // 设备所属产品
+#define  SN             "1234567"	   // 产品序列号
+#define  TENANT         "WAYZ"		   // 设备所属租户,通常是开放平台的用户 ID
+```
+
+## 3、在`main()`主函数调用例程
+在将下面代码嵌入main()中,即可实现调用:
+```c
+extern int location_client_start(void);
+location_client_start();
+```
+
+
+## 示例结果 ##
+```c
+timestamp: 1606293694990 
+gcj02:
+	latitude:30.515105
+	longitude:114.401555
+wgs84:
+	latitude:30.517407914397
+	longitude:114.396014616712
+POI: {"id": "7SkEZdfXQfS","type": "Residential","name": "中建东湖明珠国际公馆","categories":[{"id": 10200,"name": "住宅"}]}
+```

+ 136 - 0
docs/user-guide.md

@@ -0,0 +1,136 @@
+# 使用指南
+
+这里主要介绍 wayz_iotkit 程序的基本使用流程,并针对使用过程中经常涉及到的结构体和重要 API 进行简要说明。
+
+wayz_iotkit 的基本工作流程如下所示:
+
+- 初始化 wifi、设备相关信息
+- 将设备注册到平台上
+- 获取定位结果(gcj02和wgs84标准)以及POI信息
+
+## menuconfig 配置说明
+
+获取 wayz_iotkit 软件包或者修改用户配置都需要使用 `menuconfig`。需要用户打开 ENV 工具,并将目录切换到您所用的 BSP 目录,使用 `menuconfig` 命令打开配置界面。
+
+在 `RT-Thread online packages → IOT - internet of things` 中选择 **wayz_iotkit** 软件包,操作界面如下图所示:
+
+详细的配置介绍如下所示:
+
+```shell
+RT-Thread online packages
+    IOT - internet of things --->
+        [*] wayz_iotkit: wayz iot location   # 打开 wayz_iotkit 软件包
+            (wayz123) wifi ssid              # wifi 名字
+            (wayz1234) wifi password         # wifi 密码
+            Version (latest)   --->          # 选择软件包版本,默认为最新版本
+```
+
+选择合适的配置项后,使用 `pkgs --update` 命令下载软件包并更新用户配置。
+
+- 注:wifi 名字和密码 供软件包切换模式用
+
+## 工作原理
+设备中wifi模块获取周围环境中的wifi信息,组包通过http方式上传到WAYZ定位云平台,云平台进行分析后将经纬度等其他信息一并返回到软件包,软件包通过处理可以得到gcj02和wgs84标准的经纬度,和POI信息
+
+## wifi、设备相关初始化
+```c
+typedef struct _device_info_            // 设备信息
+{
+    char *dev_name;                     // 设备名称
+    char *manufacturer;                 // 设备制造厂家
+    char *SN;                           // 设备序列号
+    char *product;                      // 设备所属产品
+    char *tenant;                       // 设备所属租户,通常是开放平台的用户 ID
+}tdeviec_info;
+
+typedef struct _wifi_info_              // wifi 相关信息
+{
+    char *ssid;                         // 保存wifi名称
+    char *passwd;                       // 保存wifi密码
+}twifi_info;
+```
+
+`twifi_info` 用于保存建立连接的 wifi相关信息,在设备上传`周围wifi信息`时联网使用。用户在使用 WiFi 建立连接会话前,必须定义一个存储会话内容的结构体,如下所示:
+
+```c
+twifi_info *wlan_info;
+wlan_info = wifi_param_init(WIFI_SSID, WIFI_PWD);
+```
+
+`tdeviec_info` 用于保存注册到平台设备信息,在设备注册使用。用户在使用连接会话前,必须定义一个存储会话内容的结构体,如下所示:
+
+```c
+tdeviec_info *dev_info;
+dev_info = dev_para_init(DEV_NAME, VENDER, PRODUCT, SN, TENANT);
+```
+
+## 设备注册
+
+应用程序使用`dev_register_init`函数注册设备到平台。**其中ACCESS_KEY需要在平台申请**
+
+示例代码如下所示:
+```c
+ret = dev_register_init(wlan_info, dev_info, ACCESS_KEY);
+if (ret != DEV_REGISTER_OK)
+{
+    rt_kprintf("\033[31;22mdevice register failure. \033[0m\n");
+    return ;
+}
+```
+
+## 获取定位结果
+
+应用程序使用`get_position_info`函数从平台端获取位置信息。
+`location_print`函数是打印位置相关信息
+
+示例代码如下所示:
+```c
+tlocation_info location = {0};
+ret = get_position_info(wlan_info, ACCESS_KEY, &location); 
+if (RT_ERROR == ret)
+{
+    rt_kprintf("\033[31;22mthe device failed to obtain latitude and longitude information.\033[0m\n");
+}
+else
+{
+    location_print(location);
+}
+```
+
+**打印位置信息结果**
+```c
+-------------------location result-------------------------------
+timestamp: 1606293694990 
+gcj02:
+	latitude:30.515105
+	longitude:114.401555
+wgs84:
+	latitude:30.517407914397
+	longitude:114.396014616712
+POI: {"id": "7SkEZdfXQfS","type": "Residential","name": "中建东湖明珠国际公馆","categories":[{"id": 10200,"name": "住宅"}]}
+-------------------location result end---------------------------
+```
+
+## 定位轮询频次
+
+该引用可以通过循环的模式来设置定位频次,**其中POINT_FRQ为定位频次的设置**
+
+示例代码如下所示:
+```c
+while (1)
+{
+    ret = get_position_info(wlan_info, ACCESS_KEY, &location); 
+    if (RT_ERROR == ret)
+    {
+        rt_kprintf("\033[31;22mthe device failed to obtain latitude and longitude information.\033[0m\n");
+    }
+    else
+    {
+        location_print(location);
+    }
+    rt_thread_mdelay(POINT_FRQ);
+    rt_memset(&location, 0, sizeof (location));
+}
+```
+
+

+ 7 - 0
docs/version.md

@@ -0,0 +1,7 @@
+# 版本和修订 #
+
+| Date       | Version   |  Author       | Note  |
+| --------   | :-----:   | :----         | :---- |
+| 2020-11-28 | v1.0.0    | jianxiong.ye  | 初始版本 |
+|            |           |               |       |
+|            |           |               |       |

+ 41 - 0
inc/ntp_client.h

@@ -0,0 +1,41 @@
+/*
+ * File      : ntp.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-02-10     armink       the first version
+ */
+#ifndef _NTP_CLIENT_H_
+#define _NTP_CLIENT_H_
+
+#include <time.h>
+
+/**
+ * Get the UTC time from NTP server
+ *
+ * @param host_name NTP server host name, NULL: will using default host name
+ *
+ * @note this function is not reentrant
+ *
+ * @return >0: success, current UTC time
+ *         =0: get failed
+ */
+time_t wayz_get_time_by_ntp(const char *host_name);
+
+#endif /* _NTP_CLIENT_H_ */

+ 197 - 0
inc/wayz_pos.h

@@ -0,0 +1,197 @@
+
+#ifndef  __WAYZ_POS_H__
+#define  __WAYZ_POS_H__
+
+#include <rtthread.h>
+#include <wlan_mgnt.h>
+#include <webclient.h>
+
+#define  VER_H               1
+#define  VER_M               0
+#define  VER_L               0
+
+#define  AP_MAX_NUMBER       100
+#define  PRINT( buf, i )     buf[i + 0], buf[i + 1], buf[i + 2], buf[i + 3], buf[i + 4], buf[i + 5]
+#define  MACPRINT            "%02X:%02X:%02X:%02X:%02X:%02X"
+#define  MACPRINTID          "%02X%02X%02X%02X%02X%02X"
+#define  MAC_LEN             (17)
+
+#define  FREQ_START          2412 // 单位:M
+#define  SEGMEMTATION        5    // 单位:M
+
+#define  DEV_REGISTER_URL    "http://api.newayz.com/location/thing/v1/assets?access_key=%s"
+#define  DEV_QUERY_URL       "http://api.newayz.com/location/thing/v1/assets/%s?access_key=%s"
+#define  DEV_POSTION_URL     "http://api.newayz.com/location/hub/v1/track_points?access_key=%s"
+
+#define  MAC_COUNT           6
+#define  TIMESTAMP_DEL       (1605668910969) // ll
+#define  NAME_LENGTH         32
+#define  SN_LENGTH           32
+#define  KEY_LENGTH          64
+
+#define  STR_ERROR           "1"
+
+#pragma pack(push)
+#pragma pack(1)
+
+enum
+{
+    WIFI_CONNECT_FAIL = 0,
+    DEV_REGISTER_OK,
+    DEV_REGISTER_FAIL
+};
+
+typedef struct _ap_struct_info_
+{
+    rt_uint8_t mac[MAC_COUNT];
+    rt_int8_t rssi;
+    rt_uint8_t channel;
+    // rt_uint8_t ssid[33];
+}tapStructInfo;
+
+typedef struct _ap_info_
+{
+    tapStructInfo tinfoAp[AP_MAX_NUMBER];
+    rt_uint8_t count;
+    rt_uint8_t sta_mac[MAC_COUNT];
+    // rt_int32_t length;
+}tapinfo;
+
+typedef struct _device_info_
+{
+    char *dev_name;
+    char *manufacturer;
+    char *SN;
+    char *product;
+    char *tenant;
+}tdeviec_info;
+
+typedef struct _wifi_info_
+{
+    char *ssid;
+    char *passwd;
+}twifi_info;
+
+typedef struct _gcj02_
+{
+    double longitude;
+    double latitude;
+}tgcj02;
+
+typedef struct _wgs84_
+{
+    double longitude;
+    double latitude;
+}twgs84;
+
+typedef struct _point_info_
+{
+    tgcj02 gcj02;
+    twgs84 wgs84;
+}tpoint_info;
+
+typedef struct _category_info_
+{
+    char id[NAME_LENGTH];
+    char name[NAME_LENGTH];
+}tcategory_info;
+
+
+typedef struct _place_info_
+{
+    char id[NAME_LENGTH];
+    char type[NAME_LENGTH];
+    char name[NAME_LENGTH];
+    tcategory_info category;
+}tplace_info;
+
+typedef struct _location_info_
+{
+    tpoint_info point;
+    tplace_info place;
+    uint64_t timestamp;  // When to locate the result
+}tlocation_info;
+
+
+
+#pragma pack(pop)
+
+/**
+ * Wifi parameter initialized
+ * 
+ * @param ssid Wifi name
+ * 
+ * @param passwd Wifi password
+ * 
+ * @return twifi_info: Dynamic allocation wifi info structure
+*/
+twifi_info *wifi_param_init(const char *ssid, const char *passwd);
+
+/**
+ * device parameter initialized
+ * 
+ * @param dev_name device name
+ * 
+ * @param manufacturer device manufacturer
+ * 
+ * @param product product name
+ * 
+ * @param SN product serial number
+ * 
+ * @param tenant tenant device
+ * 
+ * @return tdeviec_info: Dynamic allocation device info structure
+*/
+tdeviec_info *dev_para_init(const char *dev_name, const char *manufacturer, const char *product, \
+                const char *SN, const char *tenant);
+
+/**
+ * Wifi station mac address
+ * 
+ * @param data Wifi station mac address data
+ * 
+ * @return void
+*/
+void get_sta_mac_addr(char *data);
+
+/**
+ * Connected to the Internet to register
+ *
+ * @param wlan_info wifi name , wifi passwd
+ *
+ * @param dev_info device info ,(dev_name、manufacturer、SN[SN_LENGTH]、product[NAME_LENGTH]、tenant)
+ * 
+ * @param key Visiting the website key
+ *
+ * @return =0: wifi connect failure
+ *         =1: device register success
+ *         =2: device register failure
+ */
+char dev_register_init(twifi_info *wlan_info, tdeviec_info *dev_info, char *key);
+
+/**
+ * Get the positioning result function
+ * 
+ * @param wlan_info Wifi related information
+ * 
+ * @param key Visiting the website key
+ * 
+ * @param location get location result
+ * 
+ * @return >0: success
+ *         =0: location failure
+ * 
+*/
+char get_position_info(twifi_info *wlan_info, char *key, tlocation_info *location);
+
+/**
+ * print location result
+ * 
+ * @param location location info
+ * 
+ * @return void:
+ * 
+*/
+void location_print(tlocation_info location);
+
+#endif

+ 92 - 0
samples/location_client.c

@@ -0,0 +1,92 @@
+#include <rtthread.h>
+#include <wlan_mgnt.h>
+#include <wifi_config.h>
+#include <webclient.h>
+#include <ntp_client.h>
+#include <wayz_pos.h>
+
+
+#ifdef PKG_WAYZ_IOTKIT_WIFI_SSID
+#define  WAYZ_WIFI_SSID      PKG_WAYZ_IOTKIT_WIFI_SSID
+#else
+#define  WAYZ_WIFI_SSID      "thread"
+#endif
+
+#ifdef PKG_WAYZ_IOTKIT_WIFI_PASSWORD
+#define  WAYZ_WIFI_PWD      PKG_WAYZ_IOTKIT_WIFI_PASSWORD
+#else
+#define  WAYZ_WIFI_PWD      "12345678"
+#endif
+
+#define  DEV_NAME       "PANDDRA"
+#define  VENDER         "ALIENTEK"
+#define  PRODUCT        "FINDU01"
+#define  SN             "1234567"
+#define  TENANT         "WAYZ"
+
+#define  POINT_FRQ      3000
+
+#define  ACCESS_KEY     "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" // 需要申请
+
+static void location_client_entry(void *parament)
+{
+    char mac_addr[17] = {0};
+    char ret = 0;
+    get_sta_mac_addr(mac_addr);
+    rt_kprintf("station mac : %s \r\n", mac_addr);
+
+    twifi_info *wlan_info;
+    tdeviec_info *dev_info;
+
+    wlan_info = wifi_param_init(WAYZ_WIFI_SSID, WAYZ_WIFI_PWD);
+    dev_info = dev_para_init(DEV_NAME, VENDER, PRODUCT, SN, TENANT);
+
+    ret = dev_register_init(wlan_info, dev_info, ACCESS_KEY);
+    if (ret != DEV_REGISTER_OK)
+    {
+        rt_kprintf("\033[31;22mdevice register failure. \033[0m\n");
+        return ;
+    }
+
+    tlocation_info location = {0};
+    ret = get_position_info(wlan_info, ACCESS_KEY, &location); // 单词定位结果获取
+    if (RT_ERROR == ret)
+    {
+        rt_kprintf("\033[31;22mthe device failed to obtain latitude and longitude information.\033[0m\n");
+    }
+    else
+    {
+        location_print(location);
+    }
+    
+    while (1)
+    {
+        ret = get_position_info(wlan_info, ACCESS_KEY, &location); // 单词定位结果获取
+        if (RT_ERROR == ret)
+        {
+            rt_kprintf("\033[31;22mthe device failed to obtain latitude and longitude information.\033[0m\n");
+        }
+        else
+        {
+            location_print(location);
+        }
+        rt_thread_mdelay(POINT_FRQ);
+        rt_memset(&location, 0, sizeof (location));
+    }
+    
+}
+
+int location_client_start(void)
+{
+    rt_thread_t tid;
+				//cJsonTask();
+    tid = rt_thread_create("location_client", location_client_entry, RT_NULL, 6 * 1024, RT_THREAD_PRIORITY_MAX / 3 - 1, 5);
+    if (tid)
+    {
+						
+        rt_thread_startup(tid);
+        return RT_EOK;
+    }
+
+    return -RT_ERROR;
+}

+ 9 - 0
src/SConscript

@@ -0,0 +1,9 @@
+from building import *
+
+cwd     = GetCurrentDir()
+src     = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd + '/../inc']
+
+group = DefineGroup('wayz-iotkit', src, depend = ['PKG_USING_WAYZ_IOTKIT'], CPPPATH = CPPPATH)
+
+Return('group')

+ 305 - 0
src/ntp_client.c

@@ -0,0 +1,305 @@
+/*
+ *
+ * (C) 2014 David Lettier.
+ * (C) 2018 Armink (armink.ztl@gmail.com)
+ *
+ * http://www.lettier.com/
+ *
+ * NTP client.
+ *
+ * Compiled with gcc version 4.7.2 20121109 (Red Hat 4.7.2-8) (GCC).
+ *
+ * Tested on Linux 3.8.11-200.fc18.x86_64 #1 SMP Wed May 1 19:44:27 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux.
+ * Tested on RT-Thread 3.0.0+
+ *
+ * To compile: $ gcc main.c -o ntpClient.out
+ *
+ * Usage: $ ./ntpClient.out
+ *
+ */
+
+#include <rtthread.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#ifdef NETUTILS_NTP_TIMEZONE
+#define NTP_TIMEZONE                   NETUTILS_NTP_TIMEZONE
+#endif
+
+#ifdef NETUTILS_NTP_HOSTNAME
+#define NTP_HOSTNAME                   NETUTILS_NTP_HOSTNAME
+#endif
+
+#define NTP_TIMESTAMP_DELTA            2208988800ull
+#define NTP_GET_TIMEOUT                1
+
+#ifndef NTP_TIMEZONE
+#define NTP_TIMEZONE                   8
+#endif
+
+#ifndef NTP_HOSTNAME
+#define NTP_HOSTNAME                   "cn.pool.ntp.org"
+#endif
+
+#define LI(packet)   (uint8_t) ((packet.li_vn_mode & 0xC0) >> 6) // (li   & 11 000 000) >> 6
+#define VN(packet)   (uint8_t) ((packet.li_vn_mode & 0x38) >> 3) // (vn   & 00 111 000) >> 3
+#define MODE(packet) (uint8_t) ((packet.li_vn_mode & 0x07) >> 0) // (mode & 00 000 111) >> 0
+
+// Structure that defines the 48 byte NTP packet protocol.
+typedef struct {
+
+    uint8_t li_vn_mode;      // Eight bits. li, vn, and mode.
+                         // li.   Two bits.   Leap indicator.
+                         // vn.   Three bits. Version number of the protocol.
+                         // mode. Three bits. Client will pick mode 3 for client.
+
+    uint8_t stratum;         // Eight bits. Stratum level of the local clock.
+    uint8_t poll;            // Eight bits. Maximum interval between successive messages.
+    uint8_t precision;       // Eight bits. Precision of the local clock.
+
+    uint32_t rootDelay;      // 32 bits. Total round trip delay time.
+    uint32_t rootDispersion; // 32 bits. Max error aloud from primary clock source.
+    uint32_t refId;          // 32 bits. Reference clock identifier.
+
+    uint32_t refTm_s;        // 32 bits. Reference time-stamp seconds.
+    uint32_t refTm_f;        // 32 bits. Reference time-stamp fraction of a second.
+
+    uint32_t origTm_s;       // 32 bits. Originate time-stamp seconds.
+    uint32_t origTm_f;       // 32 bits. Originate time-stamp fraction of a second.
+
+    uint32_t rxTm_s;         // 32 bits. Received time-stamp seconds.
+    uint32_t rxTm_f;         // 32 bits. Received time-stamp fraction of a second.
+
+    uint32_t txTm_s;         // 32 bits and the most important field the client cares about. Transmit time-stamp seconds.
+    uint32_t txTm_f;         // 32 bits. Transmit time-stamp fraction of a second.
+
+} ntp_packet;              // Total: 384 bits or 48 bytes.
+
+static ntp_packet packet = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+static void ntp_error(char* msg)
+{
+    rt_kprintf("\033[31;22m[E/NTP]: ERROR %s\033[0m\n", msg); // Print the error message to stderr.
+}
+
+/**
+ * Get the UTC time from NTP server
+ *
+ * @param host_name NTP server host name, NULL: will using default host name
+ *
+ * @note this function is not reentrant
+ *
+ * @return >0: success, current UTC time
+ *         =0: get failed
+ */
+time_t wayz_get_time_by_ntp(const char *host_name)
+{
+    int sockfd, n; // Socket file descriptor and the n return result from writing/reading from the socket.
+
+    int portno = 123; // NTP UDP port number.
+
+    time_t new_time = 0;
+
+    fd_set readset;
+    struct timeval timeout;
+
+    // Using default host name when host_name is NULL
+    if (host_name == NULL)
+    {
+        host_name = NTP_HOSTNAME;
+    }
+
+    // Create and zero out the packet. All 48 bytes worth.
+
+    memset(&packet, 0, sizeof(ntp_packet));
+
+    // Set the first byte's bits to 00,011,011 for li = 0, vn = 3, and mode = 3. The rest will be left set to zero.
+
+    *((char *) &packet + 0) = 0x1b; // Represents 27 in base 10 or 00011011 in base 2.
+
+    // Create a UDP socket, convert the host-name to an IP address, set the port number,
+    // connect to the server, send the packet, and then read in the return packet.
+
+    struct sockaddr_in serv_addr; // Server address data structure.
+    struct hostent *server;      // Server data structure.
+
+    sockfd = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Create a UDP socket.
+
+    if (sockfd < 0) {
+        ntp_error("opening socket");
+        return 0;
+    }
+
+    server = gethostbyname(host_name); // Convert URL to IP.
+
+    if (server == NULL) {
+        ntp_error("no such host");
+        goto __exit;
+    }
+
+    // Zero out the server address structure.
+
+    memset((char *) &serv_addr, 0, sizeof(serv_addr));
+
+    serv_addr.sin_family = AF_INET;
+
+    // Copy the server's IP address to the server address structure.
+
+    memcpy((char *) &serv_addr.sin_addr.s_addr, (char *) server->h_addr, server->h_length);
+
+    // Convert the port number integer to network big-endian style and save it to the server address structure.
+
+    serv_addr.sin_port = htons(portno);
+
+    // Call up the server using its IP address and port number.
+
+    if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
+        ntp_error("connecting");
+        goto __exit;
+    }
+
+    // Send it the NTP packet it wants. If n == -1, it failed.
+
+    n = send(sockfd, (char*) &packet, sizeof(ntp_packet), 0);
+
+    if (n < 0) {
+        ntp_error("writing to socket");
+        goto __exit;
+    }
+
+    timeout.tv_sec = NTP_GET_TIMEOUT;
+    timeout.tv_usec = 0;
+
+    FD_ZERO(&readset);
+    FD_SET(sockfd, &readset);
+
+    if (select(sockfd + 1, &readset, RT_NULL, RT_NULL, &timeout) <= 0) {
+        ntp_error("select the socket timeout(5s)");
+        goto __exit;
+    }
+
+    // Wait and receive the packet back from the server. If n == -1, it failed.
+
+    n = recv(sockfd, (char*) &packet, sizeof(ntp_packet), 0);
+
+    if (n < 0) {
+        ntp_error("reading from socket");
+        goto __exit;
+    }
+
+    // These two fields contain the time-stamp seconds as the packet left the NTP server.
+    // The number of seconds correspond to the seconds passed since 1900.
+    // ntohl() converts the bit/byte order from the network's to host's "endianness".
+
+    packet.txTm_s = ntohl(packet.txTm_s); // Time-stamp seconds.
+    packet.txTm_f = ntohl(packet.txTm_f); // Time-stamp fraction of a second.
+
+    // Extract the 32 bits that represent the time-stamp seconds (since NTP epoch) from when the packet left the server.
+    // Subtract 70 years worth of seconds from the seconds since 1900.
+    // This leaves the seconds since the UNIX epoch of 1970.
+    // (1900)------------------(1970)**************************************(Time Packet Left the Server)
+
+    new_time = (time_t) (packet.txTm_s - NTP_TIMESTAMP_DELTA);
+
+__exit:
+
+    closesocket(sockfd);
+
+    return new_time;
+}
+
+/**
+ * Get the local time from NTP server
+ *
+ * @param host_name NTP server host name, NULL: will using default host name
+ *
+ * @return >0: success, current local time, offset timezone by NTP_TIMEZONE
+ *         =0: get failed
+ */
+static time_t ntp_get_local_time(const char *host_name)
+{
+    time_t cur_time = wayz_get_time_by_ntp(host_name);
+
+    if (cur_time)
+    {
+        /* add the timezone offset for set_time/set_date */
+        cur_time += NTP_TIMEZONE * 3600;
+    }
+
+    return cur_time;
+}
+
+/**
+ * Sync current local time to RTC by NTP
+ *
+ * @param host_name NTP server host name, NULL: will using default host name
+ *
+ * @return >0: success, current local time, offset timezone by NTP_TIMEZONE
+ *         =0: sync failed
+ */
+static time_t ntp_sync_to_rtc(const char *host_name)
+{
+#ifdef RT_USING_RTC
+    struct tm *cur_tm;
+#endif
+
+    time_t cur_time = ntp_get_local_time(host_name);
+
+    if (cur_time)
+    {
+
+#ifdef RT_USING_RTC
+        cur_tm = localtime(&cur_time);
+        set_time(cur_tm->tm_hour, cur_tm->tm_min, cur_tm->tm_sec);
+
+        cur_tm = localtime(&cur_time);
+        set_date(cur_tm->tm_year + 1900, cur_tm->tm_mon + 1, cur_tm->tm_mday);
+#endif /* RT_USING_RTC */
+
+    }
+
+    return cur_time;
+}
+
+static void ntp_sync(const char *host_name)
+{
+    time_t cur_time = ntp_sync_to_rtc(host_name);
+
+    if (cur_time)
+    {
+        rt_kprintf("Get local time from NTP server: %s", ctime((const time_t*) &cur_time));
+
+#ifdef RT_USING_RTC
+        rt_kprintf("The system time is updated. Timezone is %d.\n", NTP_TIMEZONE);
+#else
+        rt_kprintf("The system time update failed. Please enable RT_USING_RTC.\n");
+#endif /* RT_USING_RTC */
+
+    }
+}
+
+static void cmd_ntp_sync(int argc, char **argv)
+{
+    char *host_name = NULL;
+
+    if (argc > 1)
+    {
+        host_name = argv[1];
+    }
+
+    ntp_sync(host_name);
+}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+FINSH_FUNCTION_EXPORT(ntp_sync, Update time by NTP(Network Time Protocol): ntp_sync(host_name));
+MSH_CMD_EXPORT_ALIAS(cmd_ntp_sync, ntp_sync, Update time by NTP(Network Time Protocol): ntp_sync [host_name]);
+#endif /* RT_USING_FINSH */

+ 789 - 0
src/wayz_pos.c

@@ -0,0 +1,789 @@
+
+#include "wayz_pos.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "cJSON.h"
+#include <ntp_client.h>
+#include <finsh.h>
+#include <msh.h>
+#include <math.h>
+
+tapinfo aucApInfo = {0};
+static twifi_info aucwlaninfo = {0};
+static struct rt_semaphore net_ready;
+static char access_key[KEY_LENGTH];
+#define NET_READY_TIME_OUT       (rt_tick_from_millisecond(15 * 1000))
+
+const double a = 6378245.0;
+const double ee = 0.00669342162296594323;
+const double pi = 3.14159265358979324;
+
+static unsigned char outOfChina(double lat, double lon)
+{
+    if (lon < 72.004 || lon > 137.8347)
+        return 1;
+    if (lat < 0.8293 || lat > 55.8271)
+        return 1;
+    return 0;
+}
+
+static double transformLat(double x, double y)
+{
+    double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(abs(x));
+    ret += (20.0 * sin(6.0 * x * pi) + 20.0 * sin(2.0 * x * pi)) * 2.0 / 3.0;
+    ret += (20.0 * sin(y * pi) + 40.0 * sin(y / 3.0 * pi)) * 2.0 / 3.0;
+    ret += (160.0 * sin(y / 12.0 * pi) + 320 * sin(y * pi / 30.0)) * 2.0 / 3.0;
+    return ret;
+}
+
+static double transformLon(double x, double y)
+{
+    double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(abs(x));
+    ret += (20.0 * sin(6.0 * x * pi) + 20.0 * sin(2.0 * x * pi)) * 2.0 / 3.0;
+    ret += (20.0 * sin(x * pi) + 40.0 * sin(x / 3.0 * pi)) * 2.0 / 3.0;
+    ret += (150.0 * sin(x / 12.0 * pi) + 300.0 * sin(x / 30.0 * pi)) * 2.0 / 3.0;
+    return ret;
+}
+
+static void gps_transform( double wgLat, double wgLon, double * mgLat, double* mgLon)
+{
+    if (outOfChina(wgLat, wgLon))
+    {
+        *mgLat = wgLat;
+        *mgLon = wgLon;
+        return;
+    }
+    double dLat = transformLat(wgLon - 105.0, wgLat - 35.0);
+    double dLon = transformLon(wgLon - 105.0, wgLat - 35.0);
+    double radLat = wgLat / 180.0 * pi;
+    double magic = sin(radLat);
+    magic = 1 - ee * magic * magic;
+    double sqrtMagic = sqrt(magic);
+    dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
+    dLon = (dLon * 180.0) / (a / sqrtMagic * cos(radLat) * pi);
+    *mgLat = wgLat + dLat;
+    *mgLon = wgLon + dLon;
+};
+
+// static void wgs84togcj02(double wgLat, double wgLon, double * mgLat, double* mgLon)
+// {
+//     gps_transform(wgLat, wgLon, mgLat, mgLon);
+// }
+
+static void gcj02towgs84(double wgLat, double wgLon, double * mgLat, double* mgLon)
+{
+    gps_transform(wgLat, wgLon, mgLat, mgLon);
+    *mgLat = wgLat * 2 - *mgLat;
+    *mgLon = wgLon * 2 - *mgLon;
+}
+
+// static void gcj02tobd09(double wgLat, double wgLon, double * mgLat, double* mgLon)
+// {
+//     double x = wgLon, y = wgLat;
+//     double z = sqrt(x * x + y * y) + 0.00002 * sin(y * pi);
+//     double theta = atan2(y, x) + 0.000003 * cos(x * pi);
+//     *mgLon = z * cos(theta) + 0.0065;
+//     *mgLat = z * sin(theta) + 0.006;
+// }
+
+/**
+ * @param data: get mac address data, eg:XX:XX:XX:XX:XX:XX
+ * 
+ * @return 
+ */
+void get_sta_mac_addr(char *data)
+{
+    rt_uint8_t mac[6] = {0};
+    rt_wlan_get_mac(mac);
+
+    rt_sprintf(data, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+}
+
+static void wayz_error(char* msg)
+{
+    rt_kprintf("\033[31;22m[E/wayz]: ERROR %s\033[0m\n", msg); // Print the error message to stderr.
+}
+
+static void print_scan_result(struct rt_wlan_scan_result *scan_result)
+{
+    int index, num;
+
+    num = scan_result->num;
+    aucApInfo.count = scan_result->num;
+    for (index = 0; index < num; index ++)
+    {
+        aucApInfo.tinfoAp[index].mac[0] = scan_result->info[index].bssid[0];
+        aucApInfo.tinfoAp[index].mac[1] = scan_result->info[index].bssid[1];
+        aucApInfo.tinfoAp[index].mac[2] = scan_result->info[index].bssid[2];
+        aucApInfo.tinfoAp[index].mac[3] = scan_result->info[index].bssid[3];
+        aucApInfo.tinfoAp[index].mac[4] = scan_result->info[index].bssid[4];
+        aucApInfo.tinfoAp[index].mac[5] = scan_result->info[index].bssid[5];
+        aucApInfo.tinfoAp[index].rssi = scan_result->info[index].rssi;
+        aucApInfo.tinfoAp[index].channel = scan_result->info[index].channel;
+    }
+}
+
+static void get_wifi_scan_info()
+{
+    if (RT_TRUE == rt_wlan_is_connected())
+    {
+        wayz_error("ready to disconect from ap ...");
+        rt_wlan_disconnect();
+    }
+    /* wait 500 milliseconds for wifi low level initialize complete */
+    //rt_hw_wlan_wait_init_done(500);
+    /* Configuring WLAN device working mode */
+    rt_wlan_set_mode(RT_WLAN_DEVICE_STA_NAME, RT_WLAN_STATION);
+        /* scan ap */
+    struct rt_wlan_scan_result *scan_result = RT_NULL;
+    rt_kprintf("\nstart to scan ap ...\n");
+    /* execute synchronous scan function */
+    scan_result = rt_wlan_scan_sync();
+    if (scan_result)
+    {
+        rt_kprintf("the scan is complete, results is as follows: \n");
+        /* print scan results */
+        print_scan_result(scan_result);
+        /* clean scan results */
+        rt_wlan_scan_result_clean();
+    }
+    else
+    {
+        wayz_error("not found ap information ");
+    }
+
+
+}
+
+static void wifi_ready_handler(int event, struct rt_wlan_buff *buff, void *parameter)
+{
+    rt_sem_release(&net_ready);
+}
+
+/**
+ * The callback of wlan disconected event
+ */
+static void wifi_station_disconnect_handler(int event, struct rt_wlan_buff *buff, void *parameter)
+{
+    rt_kprintf("disconnect from the network!\n");
+}
+
+// static void print_wlan_information(struct rt_wlan_info *info)
+// {
+//     rt_kprintf("SSID : %-.32s\n", &info->ssid.val[0]);
+//     rt_kprintf("MAC Addr: %02x:%02x:%02x:%02x:%02x:%02x\n", info->bssid[0],
+//                info->bssid[1],
+//                info->bssid[2],
+//                info->bssid[3],
+//                info->bssid[4],
+//                info->bssid[5]);
+//     rt_kprintf("Channel: %d\n", info->channel);
+//     rt_kprintf("DataRate: %dMbps\n", info->datarate / 1000000);
+//     rt_kprintf("RSSI: %d\n", info->rssi);
+// }
+
+twifi_info *wifi_param_init(const char *ssid, const char *passwd)
+{
+    twifi_info *wlan_info = (twifi_info *) rt_calloc(1, sizeof (twifi_info));
+    if (RT_NULL == wlan_info)
+    {
+        wayz_error("wifi param malloc fail.");
+        return RT_NULL;
+    }
+
+    wlan_info->ssid = strdup(ssid);
+    wlan_info->passwd = strdup(passwd);
+
+    return wlan_info;
+}
+
+tdeviec_info * dev_para_init(const char *dev_name, const char *manufacturer, const char *product, \
+                const char *SN, const char *tenant)
+{
+
+    tdeviec_info *dev_info = (tdeviec_info *) rt_calloc(1, sizeof (tdeviec_info));
+    if (RT_NULL == dev_info)
+    {
+        wayz_error("wifi param malloc fail.");
+        return RT_NULL;
+    }
+
+    dev_info->dev_name = strdup(dev_name);
+    dev_info->manufacturer = strdup(manufacturer);
+    dev_info->product = strdup(product);
+    dev_info->SN = strdup(SN);
+    dev_info->tenant = strdup(tenant);
+    return dev_info;
+}
+
+static char wifi_init(const char *ssid, const char *password)
+{
+    struct rt_wlan_info info;
+    int result = RT_EOK;
+    char ret = RT_EOK;
+    rt_wlan_get_mac(aucApInfo.sta_mac);
+
+    rt_memcpy(aucwlaninfo.ssid, ssid, rt_strlen(ssid));
+    rt_memcpy(aucwlaninfo.passwd, password, rt_strlen(password));
+
+    if (RT_TRUE == rt_wlan_is_connected())
+    {
+        ret = RT_EOK;
+        goto _connected;
+    }
+    rt_sem_init(&net_ready, "net_ready", 0, RT_IPC_FLAG_FIFO);
+    /* register network ready event callback */
+    rt_wlan_register_event_handler(RT_WLAN_EVT_READY, wifi_ready_handler, RT_NULL);
+    /* register wlan disconnect event callback */
+    rt_wlan_register_event_handler(RT_WLAN_EVT_STA_DISCONNECTED, wifi_station_disconnect_handler, RT_NULL);
+    result = rt_wlan_connect(ssid, password);
+    if (result == RT_EOK)
+    {
+        rt_memset(&info, 0, sizeof(struct rt_wlan_info));
+        /* Get the information of the current connection AP */
+        rt_wlan_get_info(&info);
+        // rt_kprintf("station information:\n");
+        // print_wlan_information(&info);
+        /* waiting for IP to be got successfully  */
+        result = rt_sem_take(&net_ready, NET_READY_TIME_OUT);
+        if (result == RT_EOK)
+        {
+            rt_kprintf("networking ready!\n");
+        }
+        else
+        {
+            wayz_error("wait ip got timeout!");
+        }
+        /* unregister network ready event */
+        rt_wlan_unregister_event_handler(RT_WLAN_EVT_READY);
+        rt_sem_detach(&net_ready);
+    }
+    else
+    {
+        rt_kprintf("\033[31;22mThe AP(%s) is connect failed!\033[0m\n", ssid);
+        ret = RT_ERROR;
+    }
+
+_connected:
+    rt_wlan_config_autoreconnect(RT_TRUE);
+    return ret;
+}
+
+// static rt_uint16_t chnTofreq(rt_uint8_t channel)
+// {
+//     return (FREQ_START + (channel - 1) * SEGMEMTATION);
+// }
+
+static char *point_cJson_handler(void)
+{
+ /* declare a few. */
+    cJSON *root = NULL;
+    cJSON *fmt = NULL;
+    cJSON *img = NULL;
+    cJSON *thm = NULL;
+    cJSON *fld = NULL;
+    int i = 0, j = 0;
+    char macBuf[MAC_LEN] = {0};
+    char *cJsonBuffer = NULL;
+    char *buffer = NULL;
+
+    root = cJSON_CreateObject();
+
+    time_t cur_time;
+    uint64_t time = 0;
+    static uint64_t pre_time = 0;
+
+    cur_time = wayz_get_time_by_ntp(NULL);
+    if (cur_time)
+    {
+        time = (uint64_t)cur_time * 1000;
+        // rt_kprintf("cur_time: %ld, %ld \r\n", cur_time, time);
+        pre_time = time;
+    }
+    else
+    {
+        time = (pre_time == 0 ? TIMESTAMP_DEL : (pre_time + 5000));
+    }
+    
+    char buftemp[40] = {0};
+    rt_sprintf(buftemp, "38efe26e-bcd8-"MACPRINTID, PRINT(aucApInfo.sta_mac, 0));
+
+    cJSON_AddItemToObject(root, "id", cJSON_CreateString(buftemp));
+    cJSON_AddItemToObject(root, "asset", fmt = cJSON_CreateObject());
+    rt_sprintf(macBuf, ""MACPRINT, PRINT(aucApInfo.sta_mac, 0));
+    cJSON_AddItemToObject(fmt, "id", cJSON_CreateString(macBuf));
+    cJSON_AddItemToObject(root, "location", img = cJSON_CreateObject());
+    cJSON_AddItemToObject(img, "wifis", thm = cJSON_CreateArray());
+
+    for (i = 0, j = 0; i < aucApInfo.count; i++)
+    {
+        rt_sprintf(macBuf, ""MACPRINT, PRINT(aucApInfo.tinfoAp[i].mac, 0));
+        cJSON_AddItemToArray(thm, fld = cJSON_CreateObject());
+        cJSON_AddStringToObject(fld, "macAddress", macBuf);
+        // cJSON_AddStringToObject(fld, "ssid", "");
+        // cJSON_AddNumberToObject(fld, "frequency", chnTofreq(aucApInfo.tinfoAp[i].channel));
+        cJSON_AddNumberToObject(fld, "signalStrength", abs(aucApInfo.tinfoAp[i].rssi));
+        j ++;
+        if (j > 10)
+        {
+            //break;
+        }
+    }
+    
+    cJsonBuffer = cJSON_Print(root);
+    buffer = (char *)rt_malloc(rt_strlen(cJsonBuffer) + 4);
+    if (RT_NULL == buffer)
+    {
+        wayz_error("point_cJson_handler create malloc failure.");
+        return STR_ERROR;
+    }
+
+    rt_sprintf(buffer, "%s", cJsonBuffer);
+    cJSON_Delete(root);
+    rt_free(cJsonBuffer);
+
+    return buffer; // 需要free
+}
+
+/**
+ * @param location: print location info
+ * 
+ * @warning rt_kprintf no print float/double
+ *          printf is ok
+ * 
+*/
+void location_print(tlocation_info location)
+{
+    rt_kprintf("-------------------location result-------------------------------\r\n");
+    rt_kprintf("timestamp: %lld \r\n", location.timestamp);
+    printf("gcj02:\r\n\tlatitude:%f\r\n\tlongitude:%f\r\n", location.point.gcj02.latitude, location.point.gcj02.longitude);
+    printf("wgs84:\r\n\tlatitude:%0.12f\r\n\tlongitude:%0.12f\r\n", location.point.wgs84.latitude, location.point.wgs84.longitude);
+
+    rt_kprintf("POI: {\"id\": %s,\"type\": %s,\"name\": %s,\"categories\":[{\"id\": %s,\"name\": %s}]}\r\n", 
+        location.place.id, location.place.type, location.place.name, location.place.category.id, location.place.category.name);
+    rt_kprintf("-------------------location result end---------------------------\r\n");
+}
+
+/**
+ * parse point cjson handler
+*/
+static void parse_point_cJson_handler(char *data, tlocation_info *location)
+{
+    cJSON *root, *object, *position, *point, *place, *category;
+	cJSON *item;
+	cJSON *temp = RT_NULL;
+    char *buffer = RT_NULL;
+
+    root = cJSON_Parse(data);
+    if (!root) {
+        rt_kprintf("\033[31;22m[E/wayz]Error before: [%s]\033[0m\n", cJSON_GetErrorPtr());
+        goto _root_fail;
+    }
+
+    object = cJSON_GetObjectItem(root, "location");
+    if (!object)
+    {
+        wayz_error("object failure\r\n");
+        goto _root_fail;
+    }
+
+    position = cJSON_GetObjectItem(object, "position");
+    if (!position)
+    {
+        wayz_error("position failure\r\n");
+        goto _root_fail;
+    }
+
+    item = cJSON_GetObjectItem(position, "timestamp");
+    buffer = cJSON_Print(item);
+    location->timestamp = atoll(buffer);
+    rt_free(buffer);
+    buffer = RT_NULL;
+
+    point = cJSON_GetObjectItem(position, "point");
+    if (!point)
+    {
+        wayz_error("point failure\r\n");
+        goto _root_fail;
+    }
+
+    item = cJSON_GetObjectItem(point, "longitude");
+    buffer = cJSON_Print(item);
+    location->point.gcj02.longitude = atof(buffer);
+    rt_free(buffer);
+    buffer = RT_NULL;
+    // printf("longitude: %s, %3.6f\r\n", cJSON_Print(item), location.point.gcj02.longitude);
+    item = cJSON_GetObjectItem(point, "latitude");
+    buffer = cJSON_Print(item);
+    location->point.gcj02.latitude = atof(buffer);
+    rt_free(buffer);
+    buffer = RT_NULL;
+  
+    gcj02towgs84(location->point.gcj02.latitude, location->point.gcj02.longitude, &location->point.wgs84.latitude, &location->point.wgs84.longitude);
+
+    place = cJSON_GetObjectItem(object, "place");
+    if (!place)
+    {
+        wayz_error("place failure\r\n");
+        goto _root_fail;
+    }
+
+    item = cJSON_GetObjectItem(place, "id");
+    buffer = cJSON_Print(item);
+    rt_sprintf(location->place.id , "%s", buffer);
+    rt_free(buffer);
+    buffer = RT_NULL;
+
+    item = cJSON_GetObjectItem(place, "type");
+    buffer = cJSON_Print(item);
+    rt_sprintf(location->place.type , "%s", buffer);
+    rt_free(buffer);
+    buffer = RT_NULL;
+
+    item = cJSON_GetObjectItem(place, "name");
+    buffer = cJSON_Print(item);
+    rt_sprintf(location->place.name , "%s", buffer);
+    rt_free(buffer);
+    buffer = RT_NULL;
+
+    category = cJSON_GetObjectItem(place, "categories");
+    
+    temp = cJSON_GetArrayItem(category, 0);
+    item = cJSON_GetObjectItem(temp, "id");
+    buffer = cJSON_Print(item);
+    rt_sprintf(location->place.category.id , "%s", buffer);
+    rt_free(buffer);
+    buffer = RT_NULL;
+    item = cJSON_GetObjectItem(temp, "name");
+    buffer = cJSON_Print(item);
+    rt_sprintf(location->place.category.name , "%s", buffer);
+    rt_free(buffer);
+    buffer = RT_NULL;
+
+_root_fail:
+    cJSON_Delete(root);
+}
+
+static char * register_dev_cjson_handler(tdeviec_info *dev_info)
+{
+    cJSON *root = NULL;
+    cJSON *fmt = NULL;
+    cJSON *img = NULL;
+    char macBuf[MAC_LEN] = {0};
+    char *cJsonBuffer = NULL;
+    char *buffer = NULL;
+    time_t cur_time;
+    uint64_t time = 0;
+    static uint64_t pre_time = 0;
+    char temp[10] = {0};
+
+    root = cJSON_CreateArray();
+
+    rt_sprintf(temp, "%01d.%01d.%01d", VER_H, VER_M, VER_L);
+    rt_sprintf(macBuf, ""MACPRINT, PRINT(aucApInfo.sta_mac, 0));
+    cJSON_AddItemToArray(root, fmt = cJSON_CreateObject());
+    cJSON_AddStringToObject(fmt, "id", macBuf);
+    cJSON_AddStringToObject(fmt, "name", dev_info->dev_name);
+    cJSON_AddStringToObject(fmt, "manufacturer", dev_info->manufacturer);
+    cJSON_AddStringToObject(fmt, "macAddress", macBuf);
+    cJSON_AddStringToObject(fmt, "serialNumber", dev_info->SN);
+    cJSON_AddItemToObject(fmt, "firmware", img = cJSON_CreateObject());
+    cJSON_AddStringToObject(img, "version", temp);
+
+    cur_time = wayz_get_time_by_ntp(NULL);
+    if (cur_time)
+    {
+        time = (uint64_t)cur_time * 1000;
+        // rt_kprintf("cur_time: %ld, %ld \r\n", cur_time, time);
+        pre_time = time;
+    }
+    else
+    {
+        time = (pre_time == 0 ? TIMESTAMP_DEL : (pre_time + 5000));
+    }
+
+    cJSON_AddNumberToObject(fmt, "createTime", time);
+    cJSON_AddNumberToObject(fmt, "updateTime", time);
+    cJSON_AddNumberToObject(fmt, "manufactureTime", time);
+    cJSON_AddStringToObject(fmt, "product", dev_info->product);
+    cJSON_AddStringToObject(fmt, "tenant", dev_info->tenant);
+
+    cJsonBuffer = cJSON_Print(root);
+    buffer = (char *)rt_malloc(rt_strlen(cJsonBuffer));
+    if (RT_NULL == buffer)
+    {
+        rt_kprintf("create malloc failure.\r\n");
+        return STR_ERROR;
+    }
+
+    rt_sprintf(buffer, "%s", cJsonBuffer);
+
+    cJSON_Delete(root);
+    rt_free(cJsonBuffer);
+
+    return buffer; // free
+}
+
+static unsigned char * wayz_webclient_get_data(const char *URI)
+{
+    unsigned char *buffer = RT_NULL;
+    int length = 0;
+    
+    length = webclient_request(URI, RT_NULL, RT_NULL, &buffer);
+    if (length < 0)
+    {
+        wayz_error("webclient GET request response data error.");
+        web_free(buffer);
+        return STR_ERROR;
+    }
+
+    return buffer;
+}
+
+/* HTTP client upload data to server by POST request */
+static unsigned char * wayz_webclient_post_data(const char *URI, const char *post_data)
+{
+    unsigned char *buffer = RT_NULL;
+    int length = 0;
+
+    length = webclient_request(URI, RT_NULL, post_data, &buffer);
+    if (length < 0)
+    {
+        rt_kprintf("\033[31;22m[E/wayz]:webclient POST request response data error.%s\033[0m\r\n", URI);
+        web_free(buffer);
+        return STR_ERROR;
+    }
+
+    return buffer;
+}
+
+static rt_uint8_t query_device()
+{
+    char *url = RT_NULL;
+    char mac_addr[MAC_LEN] = {0};
+    unsigned char *buffer = RT_NULL;
+    char *temp = RT_NULL;
+    char result = 0;
+    url = (char *)rt_malloc(rt_strlen(DEV_QUERY_URL) + MAC_LEN + rt_strlen(access_key));
+    if (RT_NULL == url)
+    {
+        result = RT_ERROR;
+        goto _malloc_fail;
+    }
+    rt_memset(url, 0, rt_strlen(DEV_QUERY_URL) + MAC_LEN + rt_strlen(access_key));
+    rt_sprintf(mac_addr, ""MACPRINT, PRINT(aucApInfo.sta_mac, 0));
+    rt_sprintf(url, ""DEV_QUERY_URL, mac_addr, access_key);
+    buffer = wayz_webclient_get_data(url);
+    if (rt_memcmp(buffer, STR_ERROR, rt_strlen(STR_ERROR)) == 0)
+    {
+        rt_kprintf("\033[31;22m[E/wayz]: visiting %s failure\033[0m\r\n", url);
+        result = RT_ERROR;
+        goto _url_fail;
+    }
+
+    temp = rt_strstr((char *)buffer, mac_addr);
+    if (RT_NULL == temp)
+    {
+        result = RT_ERROR;
+        goto _query_fail;
+    }
+    result = RT_EOK;
+
+_query_fail:
+    rt_free(buffer);
+_url_fail:
+    rt_free(url);
+    url = RT_NULL;
+_malloc_fail:
+    return result;
+}
+
+static rt_uint8_t register_device(tdeviec_info *dev_info)
+{
+    char *url = RT_NULL;
+    unsigned char *buffer = RT_NULL;
+    char *temp = RT_NULL;
+    char result = 0;
+    char *cJsonBuffer = NULL;
+    char mac_addr[MAC_LEN] = {0};
+    url = (char *)rt_malloc(rt_strlen(DEV_REGISTER_URL) + rt_strlen(access_key));
+    if (RT_NULL == url)
+    {
+        result = RT_ERROR;
+        goto _malloc_fail;
+    }
+    rt_memset(url, 0, rt_strlen(DEV_REGISTER_URL) + rt_strlen(access_key));
+    rt_sprintf(url, ""DEV_REGISTER_URL, access_key);
+    cJsonBuffer = register_dev_cjson_handler(dev_info);
+    buffer = wayz_webclient_post_data(url, cJsonBuffer);
+    if (rt_memcmp(buffer, STR_ERROR, rt_strlen(STR_ERROR)) == 0)
+    {
+        rt_kprintf("\033[31;22m[E/wayz]: visiting %s failure\033[0m\r\n", url);
+        result = RT_ERROR;
+        goto _url_fail;
+    }
+    rt_sprintf(mac_addr, ""MACPRINT, PRINT(aucApInfo.sta_mac, 0));
+    temp = rt_strstr((char *)buffer, mac_addr);
+    if (RT_NULL == temp)
+    {
+        result = RT_ERROR;
+        goto _query_fail;
+    }
+    result = RT_EOK;
+
+_query_fail:
+    rt_free(buffer);
+    buffer = RT_NULL;
+_url_fail:
+    rt_free(url);
+    rt_free(cJsonBuffer);
+    url = RT_NULL;
+    cJsonBuffer = RT_NULL;
+_malloc_fail:
+    return result;
+}
+
+static void dev_free(tdeviec_info *dev_info)
+{
+    rt_free(dev_info->dev_name);
+    rt_free(dev_info->manufacturer);
+    rt_free(dev_info->SN);
+    rt_free(dev_info->product);
+    rt_free(dev_info->tenant);
+}
+
+/**
+ * Connected to the Internet to register
+ *
+ * @param wlan_info wifi name , wifi passwd
+ *
+ * @param dev_info device info ,(dev_name、manufacturer、SN[SN_LENGTH]、product[NAME_LENGTH]、tenant)
+ * 
+ * @param key Visiting the website key
+ *
+ * @return =0: wifi connect failure
+ *         =1: device register success
+ *         =2: device register failure
+ */
+char dev_register_init(twifi_info *wlan_info, tdeviec_info *dev_info, char *key)
+{
+#ifdef FINSH_USING_MSH
+    rt_kprintf("dev_register_init is start:\r\n");
+    msh_exec("free", rt_strlen("free"));
+#endif
+
+    if (RT_NULL == key && 0 == rt_strcmp(key, ""))
+    {
+        wayz_error("Visiting the website key failure");
+    }
+    else
+    {
+        rt_memcpy(access_key, key, rt_strlen(key));
+    }
+    
+    // 1 connected to the Internet 
+    if (RT_ERROR == wifi_init(wlan_info->ssid, wlan_info->passwd))
+    {
+        wayz_error("connect to the internet failure\r\n");
+        return WIFI_CONNECT_FAIL;
+    }
+    // 2 Check whether the device is registered
+    if (RT_EOK == query_device())
+    {
+        wayz_error("the device has been registered, no need to register again");
+        return DEV_REGISTER_OK;
+    }
+    // 3 registered handler
+    if (RT_EOK == register_device(dev_info))
+    {
+        rt_kprintf("register device success.\r\n");
+    }
+    else
+    {
+        wayz_error("register device failure.\r\n");
+        return DEV_REGISTER_FAIL;
+    }
+
+    dev_free(dev_info);
+    return DEV_REGISTER_OK;
+}
+
+/**
+ * Get the positioning result function
+ * 
+ * @param wlan_info Wifi related information
+ * 
+ * @param key Visiting the website key
+ * 
+ * @param location get location result
+ * 
+ * @return >0: success
+ *         =0: location failure
+ * 
+*/
+char get_position_info(twifi_info *wlan_info, char *key, tlocation_info *location)
+{
+    char *url = RT_NULL;
+    unsigned char *buffer = RT_NULL;
+    char result = 0;
+    char *cJsonBuffer = NULL;
+    
+    if (RT_NULL == key && 0 == rt_strcmp(key, ""))
+    {
+        wayz_error("Visiting the website key failure");
+    }
+    else
+    {
+        rt_memcpy(access_key, key, rt_strlen(key));
+    }
+    // 1 scan wifi info 
+    get_wifi_scan_info();
+    // 2 connect to the internet
+    if (RT_ERROR == wifi_init(wlan_info->ssid, wlan_info->passwd))
+    {
+        wayz_error("connect to the internet failure\r\n");
+        result = RT_ERROR;
+        goto _malloc_fail;
+    }
+
+    // 3 Upload data to get positioning results
+    url = (char *)rt_malloc(rt_strlen(DEV_POSTION_URL) + rt_strlen(access_key));
+    if (RT_NULL == url)
+    {
+        result = RT_ERROR;
+        goto _malloc_fail;
+    }
+    rt_memset(url, 0, rt_strlen(DEV_POSTION_URL) + rt_strlen(access_key));
+    rt_sprintf(url, ""DEV_POSTION_URL, access_key);
+    cJsonBuffer = point_cJson_handler();
+    buffer = wayz_webclient_post_data(url, cJsonBuffer);
+    if (rt_memcmp(buffer, STR_ERROR, rt_strlen(STR_ERROR)) == 0)
+    {
+        rt_kprintf("\033[31;22m[E/wayz]: visiting %s failure\033[0m\r\n", url);
+        result = RT_ERROR;
+        goto _url_fail;
+    }
+
+    result = RT_EOK;
+
+    parse_point_cJson_handler((char *)buffer, location);
+
+    rt_free(buffer);
+    buffer = RT_NULL;
+
+_url_fail:
+    rt_free(url);
+    rt_free(cJsonBuffer);
+    url = RT_NULL;
+    cJsonBuffer = RT_NULL;
+_malloc_fail:
+
+#ifdef FINSH_USING_MSH
+    rt_kprintf("get_position_info is end:\r\n");
+    msh_exec("free", rt_strlen("free"));
+#endif
+    return result;
+}
+
+