Przeglądaj źródła

Merge pull request #1 from danielchen01/master

RT-thread qxwz application software package
yqiu 6 lat temu
rodzic
commit
164ca37ed2

+ 52 - 0
.gitignore

@@ -0,0 +1,52 @@
+# Prerequisites
+*.d
+
+# Object files
+*.o
+*.ko
+*.obj
+*.elf
+
+# Linker output
+*.ilk
+*.map
+*.exp
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Libraries
+*.lib
+*.a
+*.la
+*.lo
+
+# Shared objects (inc. Windows DLLs)
+*.dll
+*.so
+*.so.*
+*.dylib
+
+# Executables
+*.exe
+*.out
+*.app
+*.i*86
+*.x86_64
+*.hex
+
+# Debug files
+*.dSYM/
+*.su
+*.idb
+*.pdb
+
+# Kernel Module Compile Results
+*.mod*
+*.cmd
+.tmp_versions/
+modules.order
+Module.symvers
+Mkfile.old
+dkms.conf

+ 201 - 0
LICENSE

@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 66 - 1
README.md

@@ -1 +1,66 @@
-# qianxun
+# qxwz_application
+## 1、介绍
+- 本软件包是集成千寻位置差分sdk的集成软件包,通过该软件包,可以快速集成sdk,实现千寻高精度定位。
+
+
+### 1.1 目录结构
+
+`qxwz_application` 软件包目录结构如下所示:
+
+``` 
+qxwz
+├───docs 
+│   └───figures                                            // 文档使用图片
+│   │   api.md                                             // API 使用说明
+│   │   README.md                                          // 文档结构说明  
+│   │   samples.md                                         // 软件包示例
+│   │   差分数据嵌入式SDK开发指南_V2.0.4.pdf                 // 使用说明
+│   └───version.md                                         // 版本
+├───qxwz_sdk                                               // 集成源代码
+├───qxwz_lib                                               // 差分SDK库
+├───samples                                                // 示例代码
+│       qxwz_application.c                                 // 软件包应用示例代码
+│   LICENSE                                                // 软件包许可证
+└───README.md                                              // 软件包使用说明
+```
+
+### 1.2 许可证
+
+`qxwz_application` package 遵循 Apache 2.0 许可,详见 `LICENSE` 文件。
+
+### 1.3 依赖
+
+- RT-Thread 3.0+
+- 需要网络系统(wifi或4G/3G/2G网络)与千寻服务器交互获取差分数据
+- 需要读写串口,读取GPS芯片输出数据
+- 需要文件系统,保存高精度定位结果
+
+
+## 2、获取软件包
+
+使用 `qxwz` 软件包需要在 BSP 目录下使用 menuconfig 命令打开 Env 配置界面,在 `RT-Thread online packages → IoT - internet of things`  中选择 QXWZ 软件包,操作界面如下图所示:
+
+![menuconfig 中开启 QXWZ 支持](figures/qx.png)
+
+
+选择合适的配置项后,使用 `pkgs --update` 命令下载软件包并添加到工程中即可。
+
+## 3、使用 qxwz_application
+
+* 如何从零开始使用,请参考 [用户开发指南](docs/差分数据嵌入式SDK开发指南_V2.0.4.pdf)。
+* 完整的 API 文档,请参考 [API 手册](docs/api.md)。
+* 详细的示例介绍,请参考 [示例文档](docs/samples.md) 。
+* 更多**详细介绍文档**位于 [`/docs`](/docs) 文件夹下,**使用软件包进行开发前请务必查看**。
+
+## 4、注意事项
+
+- 正确填写千寻的账号信息
+
+    如果账号信息填写错误,将无法正确连接到千寻服务器。
+
+
+## 5、联系方式 & 感谢
+
+* 维护:RT-Thread 开发团队
+* 主页:https://github.com/RT-Thread-packages/qianxun
+

+ 15 - 0
docs/README.md

@@ -0,0 +1,15 @@
+# 文档
+
+## 软件包地址
+
+- https://github.com/RT-Thread-packages/qianxun
+
+## 文档列表
+
+|**文件名**                                                                                           |**描述**|
+|:-----                                                                                               |:----|
+|[version.md](version.md)                                                                             |版本信息|
+|[差分数据嵌入式SDK开发指南_V2.0.4.pdf](差分数据嵌入式SDK开发指南_V2.0.4.pdf)                         |使用指南|
+|[api.md](api.md)                                                                                     |API 说明|
+|[samples.md](samples.md)                                                                             |示例说明|
+

+ 130 - 0
docs/api.md

@@ -0,0 +1,130 @@
+# QXWZ_SDK API 介绍
+
+##  int start_uart(char* uart,char* file,uart_cb uart_rsp)
+|**参数**                           |**描述**|
+|:-----                             |:----|
+|uart                               |串口信息,采用哪个串口和MC110M连接,该参数就采用哪个串口,例如"uart3"|
+|file                               |表示高精度定位输出数据文件,高精度定位输出除了在屏幕显示以外,还保存在该文件中,确保该文件可读可写,例如"/qxwz_report.txt"|
+|uart_rsp                           |表示串口输出回调函数指针,SDK将通过该回调接口上报原始GGA数据给用户。用户通过该接口获取到原始GGA后,需要将该数据上报给千寻服务器,获取差分数据下发。格式参考qxwz_api.h头文件|
+|return                             |0 : 成功; 其他 : 失败|
+
+
+
+函数功能:启动读取串口数据
+
+   
+
+##  int stop_uart(void)
+|**参数**                           |**描述**|
+|:-----                             |:----|
+|无                                 |     |
+|return                             |0 : 成功; 其他 : 失败|
+
+
+函数功能:停止读取串口数据
+
+
+   
+##  int write_to_uart(void* data,int len)
+|**参数**                           |**描述**|
+|:-----                             |:----|
+|data                               |表示需要写入串口数据,即为将差分RTCM二进制数据流通过串口写入M110M,进行差分纠偏处理|
+|len                                |表示需要写入串口数据长度|
+|return                             |0 : 成功; 其他 : 失败|
+
+
+函数功能:写入串口数据
+
+
+
+   
+##  int qxwz_printf(const char *fmt, ...)
+|**参数**                           |**描述**|
+|:-----                             |:----|
+|fmt                                |表示格式化字符串|
+|return                             |0 : 成功; -1 : 失败|
+
+
+函数功能:打印千寻log函数
+
+
+   
+##  qxwz_s32_t qxwz_setting(const qxwz_usr_config_t* config, qxwz_bool_t isRealtime)
+|**参数**                           |**描述**|
+|:-----                             |:----|
+|config                             |qxwz_usr_config_t结构体指针,用来保存用户账号信息,应指向一个静态存储区,生命周期与程序同始终|
+|isRealtime                         |表示时间模式,如果可以提供系统时间也就是绝对时间,参数isRealtime设置为TRUE,
+   如果不能提供系统时间,可以提供相对时间给SDK,参数isRealtime设置为FALSE|
+|return                             |0 : 成功; -1 : 失败|
+
+ 
+函数功能:配置用户账号信息
+
+   
+##  qxwz_s32_t qxwz_start(qxwz_data_response_t * data_rsp, qxwz_status_response_t * status_rsp)
+|**参数**                           |**描述**|
+|:-----                             |:----|
+|data_rsp                           |表示数据回调指针结构体|
+|status_rsp                         |表示状态码回调指针结构体|
+|return                             |0 : 成功; -1 : 失败|
+
+
+函数功能:用户启动SDK服务
+
+
+
+   
+##  qxwz_s32_t qxwz_tick(qxwz_u32_t system_time)
+|**参数**                           |**描述**|
+|:-----                             |:----|
+|system_time                        |可以是UTC时间(计于1970年1月1号0零时),也可以是相对时间节拍,一节拍对应1秒时间|
+|return                             | >0 : 运行中; 0 : 状态机停止运行|
+
+
+函数功能:SDK驱动函数,用户可将之置于线程环境或while(1)中
+
+
+
+   
+##  qxwz_s32_t qxwz_send_data(const void *data, qxwz_u32_t size, qxwz_udata_type_e type)
+|**参数**                           |**描述**|
+|:-----                             |:----|
+|data                               |无符号指针,指向需要传递数据的首地址|
+|len                                |表示传递数据长度|
+|type                               |type表示数据类型,一般客户仅支持UDATA_GGA|
+|return                             |0 : 成功; -1 : 失败|
+
+函数功能: 传递数据给千寻服务器
+   
+##  qxwz_void_t qxwz_stop(void)
+|**参数**                           |**描述**|
+|:-----                             |:----|
+|无                                 |     |
+|return                             |无|
+
+
+函数功能:停止/释放SDK资源
+
+
+   
+##  qxwz_void_t qxwz_release(void)
+|**参数**                           |**描述**|
+|:-----                             |:----|
+|无                                 |     |
+|return                             |无|
+
+
+函数功能:释放用户账号信息
+
+
+   
+##  const qxwz_account_info* getqxwzAccount(void)
+|**参数**                           |**描述**|
+|:-----                             |:----|
+|无                                 |     |
+|return                             |返回qxwz_account_info结构体指针,指向sdk保存的用户账号信息|
+
+
+函数功能:获取用户账户信息
+
+   

+ 146 - 0
docs/samples.md

@@ -0,0 +1,146 @@
+#  QXWZ_SDK 示例程序
+
+## 示例代码讲解
+
+下面讲解 RT-Thread 提供的  QXWZ_SDK 示例代码,功能示例代码如下:
+
+```c
+#include <rtthread.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <rtdbg.h>
+#include <board.h>
+#include "qxwz_types.h"
+#include "qxwz_sdk.h"
+#include "qxwz_api.h"
+
+/*连接M110M串口信息*/
+#define SAMPLE_UART_NAME       "uart3"
+
+/*输出gga信息文件路径*/
+static char* file = "/qxwz_report.txt";
+
+/*上报SDK GGA标志*/
+static int report_flag = 0;
+
+
+static rt_mutex_t dynamic_mutex = RT_NULL;
+static struct rt_semaphore net_ready;
+
+static const qxwz_usr_config_t s_config;
+static char s_gga[256] = {0};
+static int report_flag;
+static int stopflag;
+
+static void report_gga(char *gga, qxwz_u32_t len);
+
+/*注册到SDK的数据回调函数,sdk会将差分rtcm数据通过该回调函数上报*/
+static void receive_iprtcm(qxwz_void_t *rtcm, qxwz_u32_t len, qxwz_data_type_e type)
+{
+    static unsigned int rtcmcouter = 0;
+    /*将上报的差分rtcm数据通过该函数写入M110M芯片进行差分纠偏解算*/
+    write_to_uart(rtcm,len);
+    rtcmcouter++;
+    if(rtcmcouter >300){
+        stopflag = 1;
+    }
+}
+
+/*注册到SDK的状态码回调函数,sdk会将运行状态或错误信息通过该回调函数上报*/
+static void receive_status(qxwz_s32_t status)
+{
+    rt_kprintf("got rtcm status=%d\n",status);
+    /*收到1007状态码,证明鉴权通过,可以上报GGA启动差分数据下发*/
+    if(1007 == status)
+    {
+        report_flag =1;
+        /*读取串口数据*/
+        start_uart(SAMPLE_UART_NAME,file,report_gga);
+    }
+}
+
+/*GGA上报回调函数,会将串口读取的GGA数据保存在本地*/
+static void report_gga(char *gga, qxwz_u32_t len)
+{
+    rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);
+    memcpy(s_gga,gga,len);
+    rt_mutex_release(dynamic_mutex);
+}
+
+qxwz_data_response_t data_res = {
+    receive_iprtcm,
+    NULL
+};
+
+qxwz_status_response_t status_res = {
+    receive_status
+};
+
+/*用户账号信息*/
+static const qxwz_usr_config_t s_config = {
+    "",
+    "",
+    "",
+    ""
+};
+
+/*应用入口函数*/
+int qxwz_appliction(void)
+{  
+    int result = RT_EOK;
+    /* 初始化文件系统 */
+
+    /* 初始化网络连接功能 */
+
+    dynamic_mutex = rt_mutex_create("dmutex", RT_IPC_FLAG_FIFO);
+    if (dynamic_mutex == RT_NULL)
+    {
+        rt_kprintf("create dynamic mutex failed.\n");
+        return -1;
+    }
+
+    static int s_current_time = 0;
+    qxwz_s32_t ret = 0;
+
+    /*获取当前系统时间*/
+    s_current_time = time(NULL);
+
+    /*配置用户账号信息*/
+    qxwz_setting(&s_config,QXWZ_FALSE);
+    /*启动SDK服务,注册数据回调,状态码回调函数到sdk*/
+    ret = qxwz_start(&data_res,&status_res);
+    if(0 != ret)
+        return 0;
+    int j = 0;
+    while(1){
+        if(stopflag){
+            /*停止读取串口信息,关闭串口*/
+            stop_uart();
+            /*停止/释放SDK资源*/
+            qxwz_stop();
+        }
+        /*时间节拍函数,驱动sdk运行*/
+        ret = qxwz_tick(s_current_time);
+        /*时间节拍函数返回为0,表示sdk处于空转状态,可以退出*/
+        if(ret == 0)
+        { 
+            break;
+        }
+        rt_thread_mdelay(1000);
+        s_current_time += 1;
+        if((report_flag)&&(j>5)){
+            rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);
+            /*通过此函数向SDK注入GGA数据*/
+            qxwz_send_data(s_gga, strlen(s_gga), UDATA_GGA);
+            rt_mutex_release(dynamic_mutex);
+            j = 0;
+        }
+        j++;
+    }
+    /*释放用户账号信息*/
+    qxwz_release();
+    return 0;
+}
+
+```

+ 29 - 0
docs/version.md

@@ -0,0 +1,29 @@
+1. 版本历史: 
+*千寻SDK Version
+---------------
+v1.2.2, 2019.08.02.17:36 
+
+v1.2.1, 2018.11.02.17:36 
+
+v1.2.0, 2017.12.10.17:41 
+
+v1.1.0, 2017.12.05.15:33 
+
+v1.0.0, 2017.11.25.16:28
+
+*千寻change list
+----------------
+v1.2.2
+-代码优化。
+
+v1.2.1
+-代码优化。
+
+v1.2.0
+-优化内存,减少内存到5K左右。
+
+v1.1.0
+-增加版本信息。
+
+2. 服务类型:RTCM32, RTK,坐标系 8002
+3. SDK消耗资源情况:占用ROM18K左右,占用RAM5K左右.

BIN
docs/差分数据嵌入式SDK开发指南_V2.0.4.pdf


BIN
figures/qx.png


+ 13 - 0
qxwz_sdk/qxwz_api.h

@@ -0,0 +1,13 @@
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+typedef void (*uart_cb)(char *, unsigned int len);
+
+int qxwz_printf(const char *fmt, ...);
+
+int start_uart(char* uart,char* file,uart_cb uart_rsp);
+
+int stop_uart(void);
+
+int write_to_uart(void* data,int len);

+ 278 - 0
qxwz_sdk/qxwz_app.c

@@ -0,0 +1,278 @@
+#include <rtthread.h>
+#include <drv_lcd.h>
+#include <dfs_fs.h>
+#include <dfs_posix.h>
+#include "qxwz_types.h"
+#include "qxwz_sdk.h"
+#include "qxwz_api.h"
+
+static struct rt_semaphore rx_sem;
+static rt_device_t serial;
+static int qxwz_stop_flag = 0;
+
+static rt_mutex_t dynamic_mutex = RT_NULL;
+
+static char report_gga[256] = {0};
+static char gga[256] = {0};
+
+static uart_cb s_uart_rsp = NULL;
+
+typedef enum  {
+    NONE,
+    SYNC,
+    SYNC1,
+    SYNC2,
+    SYNC3,
+    SYNC4,
+    GET_DATA,
+    END_CR,
+    END_NL
+} qxState;
+
+static int print2lcd(char* input_buf);
+
+static int filter_report_gga(char s_gga[],int len)
+{
+   int i = 0;
+   int ret = -1;
+   static int j = 0;
+   char data = 0;
+   static qxState cur_state =NONE;
+    for (i = 0; i < len; i++) {
+        data = s_gga[i];
+        switch (cur_state) {
+        case NONE:
+             if('$' == data){
+                cur_state = SYNC;
+                report_gga[j] = data;
+                j++;
+             }
+             break;
+        case SYNC:
+             if('G' == data){
+                cur_state = SYNC1;
+                report_gga[j] = data;
+                j++;
+             }
+             break;
+        case SYNC1:
+             if('N' == data){
+                cur_state = SYNC2; 
+                report_gga[j] = data;
+                j++;
+             }
+             break;
+        case SYNC2:
+             if('G' == data){
+                cur_state = SYNC3; 
+                report_gga[j] = data;
+                j++;
+             }
+             break;
+        case SYNC3:
+             if('G' == data){
+                cur_state = SYNC4; 
+                report_gga[j] = data;
+                j++;
+             }
+             break;
+        case SYNC4:
+             if('A' == data){
+                cur_state = GET_DATA; 
+                report_gga[j] = data;
+                j++;
+             }
+             break;
+        case GET_DATA:
+             if('\r' != data){ 
+                report_gga[j] = data;
+                j++;
+                break;
+             }
+             else{
+                cur_state = END_CR; 
+             }
+        case END_CR:
+             if('\r' == data){
+                cur_state = END_NL; 
+                report_gga[j] = data;
+                j++;
+             }
+             break;
+        case END_NL:
+             if('\n' == data){
+                cur_state = NONE; 
+                report_gga[j] = data;
+                j=0;
+                ret = 0;
+             }
+             break;
+        }
+    }
+    return ret;
+}
+
+static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
+{
+    rt_sem_release(&rx_sem);
+    return RT_EOK;
+}
+
+static void serial_thread_entry(void *parameter)
+{
+    int  recv,ret = -1;
+    int  fd;
+    int  ret_w = 0;
+    char buffer[512];
+    char* before = NULL;
+    char* after = NULL;
+    char* file = (char*)parameter;
+    rt_kprintf("serial_thread_entry\n");
+    fd = open(file, O_WRONLY | O_CREAT);
+    rt_kprintf("open fd %d\n",fd);
+    while (1)
+    {
+        if(qxwz_stop_flag){
+            break;            
+        }
+        while ((recv = rt_device_read(serial, -1, buffer,sizeof(buffer))) > 0)
+        {
+            ret = filter_report_gga(buffer,recv);
+            if(0 == ret){
+                before = strstr(report_gga, "E,");
+                after = strstr(before+2, ",");
+                if(1 == after-(before+2)){
+                    rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);
+                    memcpy(gga,report_gga,256);
+                    rt_mutex_release(dynamic_mutex);
+                    s_uart_rsp(gga,strlen(gga));
+                    ret_w = write(fd, gga,strlen(gga));
+                    print2lcd(gga);
+                    rt_sem_take(&rx_sem, RT_WAITING_FOREVER);                            
+                }
+                ret = -1;
+            }
+            memset(buffer,0,sizeof(buffer));
+        }
+    }
+    close(fd);
+}
+
+static int print2lcd(char* input_buf)
+{
+    int i = 0;
+    char* p_for =NULL;
+    char* p_tmp =NULL;
+    char* p_lati =NULL;
+    char* p_long =NULL;
+    char* p_loc_accu =NULL;
+    char buf[10];
+    char outbuf[100];
+    lcd_clear(WHITE);
+
+    lcd_set_color(WHITE, BLACK);
+
+    lcd_show_string(10, 69, 16, input_buf);
+    p_lati = strstr(strstr(gga,",")+1,",")+1;
+    p_tmp = strstr(p_lati,",");
+    memset(buf,0,10);
+    p_for = p_lati;
+    for(i = 0;i<p_tmp-p_lati;i++){      
+        buf[i] =*p_for;
+        p_for++;
+    }
+    memset(outbuf,0,100);
+    sprintf(outbuf,"latitude:%s",buf);
+    lcd_show_string(10, 69+16+8+16+24, 16, outbuf);
+    p_long = strstr(p_lati,"N,")+2;
+    p_tmp = strstr(p_long,",");
+    memset(buf,0,10);
+    p_for = p_long;
+    for(i = 0;i<p_tmp-p_long;i++){      
+        buf[i] =*p_for;
+        p_for++;
+    }
+    memset(outbuf,0,100);
+    sprintf(outbuf,"longitude:%s",buf);
+    lcd_show_string(10, 69+8+16+16+24+24, 16, outbuf);
+    p_loc_accu = strstr(p_long,"E,")+2;
+    p_tmp = strstr(p_loc_accu,",");
+    memset(buf,0,10);
+    p_for = p_loc_accu;
+    for(i = 0;i<p_tmp-p_loc_accu;i++){      
+        buf[i] =*p_for;
+        p_for++;
+    }
+    memset(outbuf,0,100);
+    sprintf(outbuf,"qx_loca_accuracy:%s",buf);
+    lcd_show_string(10, 69+8+16+16+24+24+24, 16, outbuf);
+    return 0;
+}
+
+int start_uart(char* uart,char* file,uart_cb uart_rsp)
+{
+    rt_err_t ret = RT_EOK;
+    if ((NULL == uart)||(NULL == file)||(NULL == uart_rsp))
+    {
+        rt_kprintf("start_uart para uart or file or uart_rsp is NULL\n");
+        return RT_ERROR;
+    }
+    char* uart_name = uart;
+    rt_kprintf("find uart_name %s \n", uart_name);
+    serial = rt_device_find(uart_name);
+    if (!serial)
+    {
+        rt_kprintf("find %s failed!\n", uart_name);
+        return RT_ERROR;
+    }
+    s_uart_rsp = uart_rsp;
+    rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
+
+    rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);
+
+    rt_device_set_rx_indicate(serial, uart_input);
+        
+    dynamic_mutex = rt_mutex_create("dmutex", RT_IPC_FLAG_FIFO);
+    if (dynamic_mutex == RT_NULL)
+    {
+        rt_kprintf("create dynamic mutex failed.\n");
+        return -1;
+    }
+
+    rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, file, 2048, 24, 10);
+
+    if (thread != RT_NULL)
+    {
+        rt_thread_startup(thread);
+    }
+    else
+    {
+        ret = RT_ERROR;
+    }
+    return ret;
+}
+
+int stop_uart(void)
+{
+    qxwz_stop_flag = 0;
+    return 0;
+}
+
+int write_to_uart(void* data, int len)
+{
+    rt_device_write(serial, 0, data, len);
+    return 0;
+}
+
+int qxwz_printf(const char *fmt, ...)
+{
+    char buf[1024] = {0};
+
+    va_list val;
+    va_start(val, fmt);
+    _vsnprintf(buf, 1024, fmt, val);
+    va_end(val);
+
+    rt_kprintf("%s\n", buf);
+    return 0;
+}

+ 127 - 0
qxwz_sdk/qxwz_sdk.h

@@ -0,0 +1,127 @@
+/*------------------------------------------------------------------------------
+* qxwz_sdk.h : sdk interface 
+*          Copyright (C) 2015-2017 by QXSI, All rights reserved.
+*/
+#ifndef __QXWZ_SDK_H__
+#define __QXWZ_SDK_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <time.h>
+#include "qxwz_types.h"
+#include "qxwz_status.h"
+
+
+/**
+ * Data
+ */
+typedef struct qxwz_usr_config{
+    qxwz_s8_t *appkey;
+    qxwz_s8_t *appsecret;
+    qxwz_s8_t *device_ID;
+    qxwz_s8_t *device_Type;
+} qxwz_usr_config_t;
+
+typedef struct {
+        char *appkey;
+        char *deviceID;
+        char *deviceType;
+        time_t expire_time;
+        char *NtripUserName;
+} qxwz_account_info;
+
+typedef qxwz_void_t (*qxwz_sdk_data_response)(qxwz_void_t *data, qxwz_u32_t length, qxwz_data_type_e type);
+typedef qxwz_void_t (*qxwz_sdk_status_response)(qxwz_s32_t status);
+
+typedef struct qxwz_data_response{
+    qxwz_sdk_data_response  cb_ipdata;
+    qxwz_sdk_data_response  cb_stdata;
+}qxwz_data_response_t;
+
+typedef struct qxwz_status_response{
+    qxwz_sdk_status_response  cb_status;
+}qxwz_status_response_t;
+
+/**
+ * @param[in]  config: usr config.
+ *
+ * @return:
+ *   0 if success
+ *  -1 if fail
+ */
+qxwz_s32_t qxwz_setting(const qxwz_usr_config_t* config, qxwz_bool_t isRealtime);
+
+/**
+ * @param[in]  data_rsp: callback for returning rtcm data.
+ * @param[in]  status_rsp: callback for returnning sdk stataus.
+ *
+ * @return:
+ *   0 if success
+ *  -1 if fail
+ */
+qxwz_s32_t qxwz_start(qxwz_data_response_t * data_rsp, qxwz_status_response_t * status_rsp);
+
+/**
+ * @brief sdk tick, trigger sdk to check status 
+ * @param[in]  time: current time(s)
+ *
+ * @return:
+ *   >0 if sdk provide the service
+ *    0 if sdk stop the service
+ */
+qxwz_s32_t qxwz_tick(qxwz_u32_t system_time);
+
+/**
+ * @param[in]  data: data to send
+ * @param[in]  size: the size of data in bytes
+ * @param[in]  type: the data type sent by user
+ *
+ * @return:
+ *   0 if success
+ *  -1 if fail
+ */
+qxwz_s32_t qxwz_send_data(const void *data, qxwz_u32_t size, qxwz_udata_type_e type);
+
+/**
+ * @brief qxwz_release release sdk resources
+ *
+ * @return:
+ *   NULL
+ */
+qxwz_void_t qxwz_release(void);
+
+
+/**
+ * @brief qxwz_stop stop sdk state machine run
+ *
+ * @return:
+ *   NULL
+ */
+qxwz_void_t qxwz_stop(void) ;
+
+
+/**
+*
+* @brief get user account info
+*
+* @return  qxwz_account_info* 
+*
+*/
+const qxwz_account_info* getqxwzAccount(void);
+
+/**
+ * @brief qxwz_sdk_version get SDK version
+ *
+ * @return:
+ *   a pointer to version
+ */
+qxwz_u8_t* qxwz_sdk_version(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 240 - 0
qxwz_sdk/qxwz_socket.c

@@ -0,0 +1,240 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <rtthread.h>
+#include <rthw.h>
+#include <stdarg.h>
+#include <sys/socket.h>
+#include "qxwz_socket.h"
+#include "qxwz_types.h"
+
+#include <dfs.h>
+#include <dfs_fs.h>
+#include <dfs_posix.h>
+
+#include <dfs_poll.h>
+#include <dfs_select.h>
+
+#define THREAD_PRIORITY         25
+#define THREAD_STACK_SIZE       2048
+#define BUFFER_SIZE             2048
+#define THREAD_TIMESLICE        5
+
+typedef enum {
+    SOC_FAIL = -1,
+    SOC_OK = 0,
+    SOC_BLOCK
+}SOC_STATUS;
+
+static soc_cb_t g_soc_funtion;
+static host_info_t g_host;
+static qxwz_s8_t g_soc_buf[BUFFER_SIZE] = {0};
+static qxwz_s32_t g_soc;
+
+static rt_thread_t pid_recv = RT_NULL;
+static rt_thread_t pid_con = RT_NULL;
+
+static void soc_connect_cb(void *param)
+{
+    struct addrinfo hints;
+    struct addrinfo *result, *rp;
+    qxwz_s32_t ret = -1;
+    qxwz_s32_t soc = g_soc;
+    qxwz_s8_t port[10] = {0};
+
+    sprintf(port,"%d",g_host.port);
+    memset(&hints, 0, sizeof(struct addrinfo));
+    hints.ai_family = AF_INET;    /* Allow IPv4*/
+    hints.ai_socktype = SOCK_STREAM; /* Datagram socket */
+    hints.ai_flags = 0;
+    hints.ai_protocol = 0;          /* Any protocol */
+
+    rt_kprintf("soc=%d, host = %s\n",soc,g_host.hostName);
+
+    ret = getaddrinfo(g_host.hostName, port, &hints, &result);
+    if (ret == -1) {
+        rt_kprintf("dns fail\n");
+        perror("dns");
+        g_soc_funtion.cb_status(soc,SOC_FAIL);
+        g_soc_funtion.cb_connect(soc);
+        freeaddrinfo(result);       
+        return;
+    }
+    
+    for (rp = result; rp != NULL; rp = rp->ai_next) {
+        rt_kprintf("rp = %p\n",rp);
+        if (connect(soc, rp->ai_addr, rp->ai_addrlen) != -1){
+            g_soc_funtion.cb_status(soc,SOC_OK);
+            g_soc_funtion.cb_connect(soc);
+            freeaddrinfo(result);
+            return;
+         }
+    }
+    
+    perror("connect");
+
+    if(NULL == rp){
+        rt_kprintf("no invalid host\n");
+        g_soc_funtion.cb_status(soc,SOC_FAIL);
+    }
+    freeaddrinfo(result);
+    return;
+}
+
+static void soc_recv_cb_1(void *param)
+{
+    qxwz_s32_t ret = 0;
+    qxwz_s32_t soc = g_soc;
+    struct timeval timeout = {2,0};
+
+    setsockopt(soc,SOL_SOCKET,SO_RCVTIMEO, (char *)&timeout,sizeof(struct timeval)); 
+    rt_kprintf("%s,%d,soc=%d\n",__func__,__LINE__,soc);
+    while(1){
+        memset(g_soc_buf,0,sizeof(g_soc_buf));
+        ret = recv(soc, g_soc_buf, sizeof(g_soc_buf), MSG_WAITALL);
+        if(ret < 0){
+            rt_kprintf("%s,%d\n",__func__,__LINE__);
+            perror("recv");
+            g_soc_funtion.cb_status(soc,SOC_FAIL);
+            break;
+        }else if(ret == 0){
+            rt_kprintf("FIN received[%s,%d]\n",__func__,__LINE__);
+            g_soc_funtion.cb_status(soc,SOC_FAIL);
+            break;
+        }else{
+            g_soc_funtion.cb_recv(soc,g_soc_buf, ret);
+            return;
+        }
+    }
+}
+
+static void soc_recv_cb_2(void *param)
+{
+    struct timeval timeout = {2,0};
+    qxwz_s32_t counter,ret = 0;
+    qxwz_s32_t soc = g_soc;
+    setsockopt(soc,SOL_SOCKET,SO_RCVTIMEO, (char *)&timeout,sizeof(struct timeval));
+    rt_kprintf("%s,%d,soc=%d\n",__func__,__LINE__,soc);
+    while(1){
+        memset(g_soc_buf,0,sizeof(g_soc_buf));
+        ret = recv(soc, g_soc_buf, sizeof(g_soc_buf), MSG_WAITALL);
+        if(ret < 0){
+            counter++;
+            if(counter>5){
+                g_soc_funtion.cb_status(soc,SOC_FAIL);
+                return;
+            }
+            continue;
+        }else if(ret == 0){
+            rt_kprintf("FIN received[%s,%d]\n",__func__,__LINE__);
+            g_soc_funtion.cb_status(soc,SOC_FAIL);
+            return;
+        }else{
+            g_soc_funtion.cb_recv(soc,g_soc_buf, ret);
+        }
+    }
+}
+
+qxwz_s32_t qxwz_soc_create(qxwz_u32_t nwk_id)
+{
+    qxwz_s32_t sock_fd;
+    sock_fd = socket(AF_INET, SOCK_STREAM, 0);
+    if(sock_fd<= 0){
+        return -1;
+    }
+    rt_kprintf("qxwz_soc_create=%d\n",sock_fd);
+    g_soc = sock_fd;
+
+    rt_kprintf("%s,%d\n",__func__,__LINE__);
+     
+   return sock_fd;
+}
+
+
+/**
+ * @param[in]  soc: socket number.
+ * @param[in]  host: the server info @see host_info_t.
+ * @param[in]  cbs: the callbacks for async @see soc_cb_t.
+ *
+ * @return:
+ *   0 if success
+ *  -1 if fail
+ *  -2 if async occurs
+ */
+qxwz_s32_t qxwz_soc_connect(qxwz_s32_t soc, host_info_t *host, soc_cb_t *cbs)
+{
+    g_host = *host;
+    g_soc_funtion = *cbs;
+    if(8000 == host->port){
+        pid_recv = rt_thread_create("soc_recv1",
+                            soc_recv_cb_1, RT_NULL,
+                            THREAD_STACK_SIZE,
+                            THREAD_PRIORITY, THREAD_TIMESLICE);
+        }else {
+                pid_recv = rt_thread_create("soc_recv2",
+                            soc_recv_cb_2, RT_NULL,
+                            THREAD_STACK_SIZE,
+                            24, THREAD_TIMESLICE);
+    }
+    if (pid_recv != RT_NULL){
+        rt_kprintf("start recv\n");
+        rt_thread_startup(pid_recv);
+    }
+    rt_kprintf("qxwz_soc_connect=%d\n",soc);
+    pid_con = rt_thread_create("soc_connect",
+                            soc_connect_cb, (void *)&soc,
+                            THREAD_STACK_SIZE,
+                            THREAD_PRIORITY, THREAD_TIMESLICE);
+                            
+   if (pid_con != RT_NULL)
+        rt_thread_startup(pid_con);
+ 
+    return -2;
+}
+
+
+/**
+ * @param[in]  soc: socket number.
+ * @param[in]  buf: the data buffer which will be sent.
+ * @param[in]  len: the data buffer length.
+ *
+ * @return:
+ *  >=0 if success
+ *   -1 if fail for any reason
+ *   -2 if buffer not available, async occurs
+ */
+qxwz_s32_t qxwz_soc_send(qxwz_s32_t soc, const qxwz_s8_t *buf, qxwz_s32_t len)
+{
+    return send(soc, buf, len, 0);
+}
+
+/**
+ * @param[in]  soc: socket number.
+ * @param[out] buf: the data buffer which will be filled by received data.
+ * @param[in]  len: the maxium lenght of data buffer.
+ *
+ * @return:
+ *  >0 if success
+ *  -1 if fail for any reason, or receive the FIN from the server
+ *  -2 if no data available, async occurs
+ */
+qxwz_s32_t qxwz_soc_recv(qxwz_s32_t soc, qxwz_s8_t *buf, qxwz_s32_t len)
+{
+    return 0;
+}
+
+/**
+ * @param[in]  soc: socket number.
+ *
+ * @return:
+ *   0 if success
+ *  -1 if fail
+ *  -2 if async occurs
+ */
+qxwz_s32_t qxwz_soc_close(qxwz_s32_t soc)
+{
+    return closesocket(soc);
+}
+

+ 100 - 0
qxwz_sdk/qxwz_socket.h

@@ -0,0 +1,100 @@
+/*------------------------------------------------------------------------------
+* qxwz_socket.h : socket interface that clients should realize
+*          Copyright (C) 2015-2017 by QXSI, All rights reserved.
+*/
+#ifndef __QXWZ_SOC_H_
+#define __QXWZ_SOC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "qxwz_types.h"
+
+typedef qxwz_s32_t qxwz_soc;
+
+typedef struct _host_info_{
+    qxwz_s8_t *hostName;
+    qxwz_u16_t port;
+}host_info_t;
+
+typedef struct _soc_cb_{
+    qxwz_s32_t ( *cb_connect )   (qxwz_s32_t soc);
+    qxwz_s32_t ( *cb_send    )   (qxwz_s32_t soc);
+    qxwz_s32_t ( *cb_recv    )   (qxwz_s32_t soc, const qxwz_s8_t *buf, qxwz_u32_t len);
+    qxwz_s32_t ( *cb_close   )   (qxwz_s32_t soc);
+    qxwz_s32_t ( *cb_status  )   (qxwz_s32_t soc, qxwz_s32_t status);/*status: <0 means error occurs in low-level tcp/ip stack*/
+}soc_cb_t;
+
+/**
+ * @param[in]  nwk_id: network identifier.
+ *                     0, By default, then depends on user to choose.
+ *                     1, China telecom cellular system
+ *                     2, China mobile cellular system
+ *                     3, China unicom cellular system 
+ *                     4, Wi-Fi
+ *                     5, Wired
+ *                     6, Others
+ *
+ * @return:
+ *    -1 if fail
+ *    socket number if okay
+ */
+qxwz_s32_t qxwz_soc_create(qxwz_u32_t nwk_id);
+
+
+/**
+ * @param[in]  soc: socket number.
+ * @param[in]  host: the server info @see host_info_t.
+ * @param[in]  cbs: the callbacks for async @see soc_cb_t.
+ *
+ * @return:
+ *   0 if success
+ *  -1 if fail
+ *  -2 if async occurs
+ */
+qxwz_s32_t qxwz_soc_connect(qxwz_s32_t soc, host_info_t *host, soc_cb_t *cbs);
+
+
+/**
+ * @param[in]  soc: socket number.
+ * @param[in]  buf: the data buffer which will be sent.
+ * @param[in]  len: the data buffer length.
+ *
+ * @return:
+ *  >=0 if success
+ *   -1 if fail for any reason
+ *   -2 if buffer not available, async occurs
+ */
+qxwz_s32_t qxwz_soc_send(qxwz_s32_t soc, const qxwz_s8_t *buf, qxwz_s32_t len);
+
+/**
+ * @param[in]  soc: socket number.
+ * @param[out] buf: the data buffer which will be filled by received data.
+ * @param[in]  len: the maxium lenght of data buffer.
+ *
+ * @return:
+ * >=0 if success
+ *  -1 if fail for any reason, or receive the FIN from the server
+ *  -2 if no data available, async occurs
+ */
+qxwz_s32_t qxwz_soc_recv(qxwz_s32_t soc, qxwz_s8_t *buf, qxwz_s32_t len);
+
+/**
+ * @param[in]  soc: socket number.
+ *
+ * @return:
+ *   0 if success
+ *  -1 if fail
+ *  -2 if async occurs
+ */
+qxwz_s32_t qxwz_soc_close(qxwz_s32_t soc);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /*__QXWZ_SOC_H_*/
+

+ 139 - 0
qxwz_sdk/qxwz_status.h

@@ -0,0 +1,139 @@
+/*------------------------------------------------------------------------------
+* qxwz_status.h : SDK status codes 
+*          Copyright (C) 2015-2017 by QXSI, All rights reserved.
+*/
+#ifndef __QXWZ_STATUS_CODES_H__
+#define __QXWZ_STATUS_CODES_H__
+
+enum _status_{
+    QXWZ_MRTK_STATUS_NONE = -1,
+     
+    QXWZ_MRTK_STATUS_SUCCESS = 100,
+    QXWZ_MRTK_STATUS_START = 101,
+    QXWZ_MRTK_STATUS_STOP = 102,
+
+    QXWZ_STATUS_AUTH_SUCCESS = 200,
+    QXWZ_STATUS_AUTH_LOCAL_FAIL,
+    QXWZ_STATUS_AUTH_NETWORK_FAIL,
+    QXWZ_STATUS_AUTH_ACCOUNT_ERROR,
+    QXWZ_STATUS_AUTH_TIMESTAMP_TIMEOUT,
+
+    QXWZ_STATUS_NTRIP_CONNECTED = 1000, //已连接到ntrip服务器
+    QXWZ_STATUS_NTRIP_DISCONNECTED = 1001, //已断开与ntrip服务器的连接
+    QXWZ_STATUS_APPKEY_IDENTIFY_FAILURE = 1002, //APP KEY认证失败
+    QXWZ_STATUS_APPKEY_IDENTIFY_SUCCESS = 1003, //APP KEY认证成功
+    QXWZ_STATUS_NETWORK_UNAVAILABLE = 1004, //网络异常
+    QXWZ_STATUS_NTRIP_USER_MAX = 1005, //APP KEY用户已经达到上限
+    QXWZ_STATUS_NTRIP_USER_NOT_EXIST = 1006, //Ntrip用户不存在
+    QXWZ_STATUS_NTRIP_USER_IDENTIFY_SUCCESS = 1007, //Ntrip认证成功
+    QXWZ_STATUS_ILLEGAL_GGA = 1011,      //非法GGA
+    QXWZ_STATUS_GGA_SEND_TIMEOUT = 1012, //发送GGA超时
+    QXWZ_STATUS_NTRIP_CONNECTING = 1013, //正在连接ntrip服务器
+    QXWZ_STATUS_NTRIP_RECEIVING_DATA = 1014, //正在接收ntrip服务器数据
+    QXWZ_STATUS_ILLEGAL_APP_KEY = 1015, //非法APP KEY
+    QXWZ_STATUS_ILLEGAL_APP_SECRET = 1016, //非法APP SECRET
+    QXWZ_STATUS_ILLEGAL_DEVICE_TYPE = 1017, //非法Device type
+    QXWZ_STATUS_ILLEGAL_DEVICE_ID = 1018, //非法Device id
+    QXWZ_STATUS_ACQUIRE_NTRIP_USER_FAILURE = 1019, //无法获取差分用户
+
+
+    QXWZ_STATUS_SDK_INTERNAL_ERROR = 1020,      // SDK内部错误
+    QXWZ_STATUS_NTRIP_RTCM_SUCCESS = 1021,      // Ntrip播发数据正常
+    QXWZ_STATUS_NTRIP_UNAUTHORIZED = 1022,      // Ntrip认证失败
+    QXWZ_STATUS_NULL_APP_KEY = 1023,            //APP KEY不能为空
+    QXWZ_STATUS_NULL_APP_SECRET =1024,          //APP SECRET不能为空
+    QXWZ_STATUS_NULL_DEVICE_TYPE = 1025,        //Device type不能为空
+    QXWZ_STATUS_NULL_DEVICE_ID = 1026,          //Device id不能为空
+
+    QXWZ_STATUS_CONFIG_NULL = 1035,                //Config为空
+    QXWZ_STATUS_NO_SETTING_INIT_FUNCTION = 1036,   //开发者没有调用setting函数
+
+    QXWZ_STATUS_OPENAPI_PARAM_MISSING = 2001, //缺少参数
+    QXWZ_STATUS_OPENAPI_ACCOUNT_NOT_EXIST = 2002, //账号不存在
+    QXWZ_STATUS_OPENAPI_DUPLICATE_ACCOUNT = 2003, //账号重复
+    QXWZ_STATUS_OPENAPI_INCORRECT_PASSWORD = 2004, //错误密码
+    QXWZ_STATUS_OPENAPI_DISABLED_ACCOUNT = 2005, //账号未激活
+    QXWZ_STATUS_OPENAPI_NO_AVAILABLE_ACCOUNT = 2006, //没有有效的账号
+    QXWZ_STATUS_OPENAPI_NO_RELATED_POPUSER = 2007, //POPUser不存在
+    QXWZ_STATUS_OPENAPI_SYSTEM_ERROR = 2008, //服务端内部错误
+    QXWZ_STATUS_NTRIP_SERVER_DISCONNECTED = 2009,//Ntrip服务器断开Socket连接
+    QXWZ_STATUS_OPENAPI_ACCOUNT_EXPIRED = 2010, //账号已过期,需续费
+    QXWZ_STATUS_OPENAPI_ACCOUNT_TOEXPIRE = 2011, //账号即将过期
+    QXWZ_STATUS_OPENAPI_BINDMODEMISMATCH_EXPIRE = 2012, //当前账号无法自动绑定
+    QXWZ_STATUS_OPENAPI_PARAMETER_ERROR,
+    QXWZ_STATUS_OPENAPI_UNKNOWN_ERROR,
+
+
+
+    QXWZ_MRTK_STATUS_WORK = 10000,
+    //SOCKET 
+    QXWZ_SOC_ACCOUNT_ID_NOT_VAILD = 10001,
+    QXWZ_SOC_GET_ACCOUNT_ID_ERROR = 10002,
+    QXWZ_SOC_CREATE_ERROR = 10003,
+    QXWZ_SOC_CONNECT_ERROR = 10004,
+    QXWZ_SOC_SEND_ERROR = 10005,
+    QXWZ_SOC_CLOSE_ERROR = 10006,
+    QXWZ_SOC_GPRS_TIMEOUT = 10007,
+    QXWZ_SOC_CONNECT_TIMEOUT = 10008,
+    QXWZ_SOC_SEND_TIMEOUT = 10009,
+    QXWZ_SOC_RECV_TIMEOUT = 10010,
+    QXWZ_SOC_RESPONSE_TIMEOUT = 10011,
+    QXWZ_SOC_PACKET_NOT_COMPLETE = 10012,
+    QXWZ_SOC_PACKET_TOO_BIG = 10013,
+    QXWZ_SOC_SESSION_REQUEST_TOO_LONG = 10014,
+    QXWZ_SOC_CLOSE_TIMEOUT = 10015,
+    QXWZ_SOC_GET_HOST_NAME_ERROR = 10016,
+
+    //RESOURCES
+    QXWZ_MEM_POOL_CREATE_ERROR = 20001,   //ABORT
+    QXWZ_MEM_ALLOC_ERROR = 20002,         //ABORT
+    QXWZ_TIMER_CREATE_ERROR = 20003,      //ABORT
+    QXWZ_EVENT_SCHEDULER_NULL_PTR = 20004,
+    QXWZ_TIMER_ID_NOT_IN_RANGE = 20005,
+    QXWZ_TAKE_MUTEX_ERROR = 20006,
+    QXWZ_GIVE_MUTEX_ERROR = 20007,
+
+    //RTK Algo
+    QXWZ_RTK_MEM_ALLOC_FAILED = 30001, //ABORT
+    QXWZ_RTK_OPEN_FILE_FAILED = 30002,
+    QXWZ_RTK_NULL_PTR = 30003,
+    QXWZ_RTK_REF_DATA_REPEATED = 30004,
+    QXWZ_RTK_ROV_DATA_REPEATED = 30005,
+    QXWZ_RTK_ROV_OBS_DATA_NULL = 30006,
+    QXWZ_RTK_REF_OBS_DATA_NULL = 30007,
+    QXWZ_RTK_EPOCH_DATA_ALREADY_PROCESSED = 30008,
+    QXWZ_RTK_ROV_SAT_NUM_NOT_ENOUGH = 30009,
+    QXWZ_RTK_REF_SAT_NUM_NOT_ENOUGH = 30010,
+    QXWZ_RTK_BRDC_EPH_NOT_ENOUGH_FOR_REF = 30011,
+    QXWZ_RTK_BRDC_EPH_NOT_ENOUGH_FOR_ROV = 30012,
+    QXWZ_RTK_BRDC_EPH_EMPTY = 30013,
+    QXWZ_RTK_BRDC_GEPH_EMPTY = 30014,
+    QXWZ_RTK_SAME_SAT_NOT_ENOUGH = 30015,
+    QXWZ_RTK_NOT_ENOUGH_VALID_GEO_DATA = 30016,
+    QXWZ_RTK_EPOCH_TIMESTAMP_INVALID = 30017,    
+    QXWZ_RTK_SPP_FAILED = 30018,
+    QXWZ_RTK_SPP_OBS_DATA_NULL = 30019,
+    QXWZ_RTK_SPP_SAT_NUM_NOT_ENOUGH = 30020,
+    QXWZ_RTK_MATRIX_NULL = 30021,
+    QXWZ_RTK_MATRIX_IDX_OUT_OF_RANGE = 30022,
+    QXWZ_RTK_SAT_NOT_FOUND_OR_DISABLED = 30023,
+
+    //AGNSS
+    QXWZ_GET_IMSI_ERROR = 40001,
+    QXWZ_GET_CELLID_ERROR = 40002,
+    QXWZ_AGNSS_DECODE_ERROR = 40003,
+    QXWZ_AGNSS_EPH_ERROR = 40004,
+
+    //RAW DATA
+    QXWZ_GNSS_UART_INIT_ERROR = 50001,
+    QXWZ_GNSS_UART_SHUTDOWN_ERROR = 50002,
+    QXWZ_GNSS_UART_RAW_DATA_NOT_AVAIL = 50003,
+    QXWZ_GNSS_UART_NEMA_BROKEN = 50004,
+    QXWZ_GNSS_UART_CHECKSUM_ERROR = 50005,
+    QXWZ_GNSS_NO_GNSS_SIGNAL = 50006,
+
+    //RTCM 
+    QXWZ_RTCM_DECODE_ERROR = 60001,
+};
+
+#endif /*__QXWZ_STATUS_CODES_H__*/

+ 96 - 0
qxwz_sdk/qxwz_types.h

@@ -0,0 +1,96 @@
+/*------------------------------------------------------------------------------
+* qxwz_typdes.h : type definitions
+*          Copyright (C) 2015-2017 by QXSI, All rights reserved.
+*/
+#ifndef __QXWZ_TYPES_H__
+#define __QXWZ_TYPES_H__
+
+/*******************************************************************************
+ * Type Definitions
+ *******************************************************************************/
+
+/** Signed 8bit integer. */
+typedef /*signed*/ char                   qxwz_s8_t;
+
+/** Unsigned 8bit integer. */
+typedef unsigned char                      qxwz_u8_t;
+
+/** Signed 16bit integer. */
+typedef signed short                      qxwz_s16_t;
+
+/** Unsigned 16bit integer. */
+typedef unsigned short                      qxwz_u16_t;
+
+/** Signed 32bit integer. */
+typedef signed int                          qxwz_s32_t;
+
+/** Unsigned 32bit integer. */
+typedef unsigned int                      qxwz_u32_t;
+
+/** Large signed integer. */
+typedef signed long long                  qxwz_s64_t;
+
+/** unsigned 64 bit integer */
+typedef unsigned long long                qxwz_u64_t;
+
+/** single precision float number */
+typedef float                             qxwz_flt_t;
+
+/** double precision float number */
+typedef double                            qxwz_dbl_t;
+
+/** double precision float number */
+typedef void                              qxwz_void_t;
+
+
+/* boolean representation */
+typedef enum
+{
+    /* FALSE value */
+    QXWZ_FALSE,
+    /* TRUE value */
+    QXWZ_TRUE
+} qxwz_bool_t;
+
+/* MISRA-C[pm098] */
+#if !defined(NULL)
+#define NULL    ((void*)0)
+#endif 
+
+/*output data type*/
+typedef enum{
+    /*rtcm*/
+    RTCM_TYPE_RAW,
+    
+    RTCM_TYPE_EPO,
+    RTCM_TYPE_REF,
+    RTCM_TYPE_EPH,
+    RTCM_TYPE_GEPO,
+
+    RTCM_TYPE_SSR1_ORBIT,
+    RTCM_TYPE_SSR1_CLOCK,
+    RTCM_TYPE_SSR1_ORBCLK,
+    RTCM_TYPE_SSR1_CBIAS,
+    RTCM_TYPE_SSR1_URA,
+    
+    RTCM_TYPE_SSR2_PBIAS,
+    RTCM_TYPE_SSR2_VTEC,
+
+    RTCM_TYPE_SSR2_COMBBIAS,    /*combined Code bias and Phase bias, just satellite's packet supports this type*/
+    
+    /*test*/
+    SSR_TYPE_TEST,
+    
+    /*other*/
+    /*...*/
+}qxwz_data_type_e;
+
+/*intput data type*/
+typedef enum{
+    UDATA_GGA,
+    UDATA_IP,
+    UDATA_SAT,
+}qxwz_udata_type_e;
+
+#endif /*__QXWZ_TYPES_H__*/
+

+ 116 - 0
samples/qxwz_application.c

@@ -0,0 +1,116 @@
+#include <rtthread.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <rtdbg.h>
+#include <board.h>
+#include "qxwz_types.h"
+#include "qxwz_sdk.h"
+#include "qxwz_api.h"
+
+#define SAMPLE_UART_NAME       "uart3"
+
+static int report_flag = 0;
+static char* file = "/qxwz_report.txt";
+
+static rt_mutex_t dynamic_mutex = RT_NULL;
+static struct rt_semaphore net_ready;
+
+static const qxwz_usr_config_t s_config;
+static char s_gga[256] = {0};
+static int report_flag;
+static int stopflag;
+
+static void report_gga(char *gga, qxwz_u32_t len);
+
+static void receive_iprtcm(qxwz_void_t *rtcm, qxwz_u32_t len, qxwz_data_type_e type)
+{
+    static unsigned int rtcmcouter = 0;
+    write_to_uart(rtcm,len);
+    rtcmcouter++;
+    if(rtcmcouter >300){
+        stopflag = 1;
+    }
+}
+
+static void receive_status(qxwz_s32_t status)
+{
+    rt_kprintf("got rtcm status=%d\n",status);
+    if(1007 == status)
+    {
+        report_flag =1;
+        start_uart(SAMPLE_UART_NAME,file,report_gga);
+    }
+}
+
+static void report_gga(char *gga, qxwz_u32_t len)
+{
+    rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);
+    memcpy(s_gga,gga,len);
+    rt_mutex_release(dynamic_mutex);
+}
+
+qxwz_data_response_t data_res = {
+    receive_iprtcm,
+    NULL
+};
+
+qxwz_status_response_t status_res = {
+    receive_status
+};
+
+static const qxwz_usr_config_t s_config = {
+    "",
+    "",
+    "",
+    ""
+};
+
+int qxwz_application(void)
+{  
+    int result = RT_EOK;
+    /* 初始化文件系统 */
+
+    /* 初始化网络连接功能 */
+
+    // The sdk current time
+    dynamic_mutex = rt_mutex_create("dmutex", RT_IPC_FLAG_FIFO);
+    if (dynamic_mutex == RT_NULL)
+    {
+        rt_kprintf("create dynamic mutex failed.\n");
+        return -1;
+    }
+
+    static int s_current_time = 0;
+    qxwz_s32_t ret = 0;
+
+    s_current_time = time(NULL);
+
+    qxwz_setting(&s_config,QXWZ_FALSE);
+    ret = qxwz_start(&data_res,&status_res);
+    if(0 != ret)
+        return 0;
+    int j = 0;
+    while(1){
+        if(stopflag){
+            stop_uart();
+            qxwz_stop();
+        }
+        ret = qxwz_tick(s_current_time);
+        if(ret == 0)
+        { 
+            break;
+        }
+        rt_thread_mdelay(1000);
+        s_current_time += 1;
+        if((report_flag)&&(j>5)){
+            rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);
+            qxwz_send_data(s_gga, strlen(s_gga), UDATA_GGA);
+            rt_mutex_release(dynamic_mutex);
+            j = 0;
+        }
+        j++;
+    }
+    qxwz_release();
+    return 0;
+}