Selaa lähdekoodia

修改文档说明

zaki.wang 5 vuotta sitten
vanhempi
sitoutus
287c237e66
8 muutettua tiedostoa jossa 210 lisäystä ja 39 poistoa
  1. 3 3
      README.md
  2. 3 3
      docs/README.md
  3. 6 4
      docs/api.md
  4. 23 1
      docs/samples.md
  5. 29 4
      docs/user-guide.md
  6. 42 1
      inc/wayz_pos.h
  7. 3 2
      samples/location_client.c
  8. 101 21
      src/wayz_pos.c

+ 3 - 3
README.md

@@ -2,7 +2,7 @@
 
 ## 1、介绍
 
-wayz_iotkit 是上海图趣信息科技有限公司,针对【硬件名称或型号】开发的能够实现定位功能的物联网组件。在使用传统上定位,如 GPS 等信号的同时,也支持使用基站、Wifi等数据,通过 WAYZ 定位云来进行定位。当前版本以实现支持wifi定位,后期会逐步实现对其他信号源的利用,进一步提升定位效果。
+wayz_iotkit 是上海图趣信息科技有限公司,针对RT-thread开发的能够实现定位功能的物联网组件。在使用传统上定位,如 GPS 等信号的同时,也支持使用基站、Wifi等数据,通过 WAYZ 定位云来进行定位。当前版本以实现支持wifi、gnss、基站定位,其中wifi定位为自动获取定位数据,gnss和基站需要开发者手动填写相关信息,后期会逐步实现对其他信号源的自动采集,进一步提升定位效果。
 
 ### 1.1 目录结构
 
@@ -48,9 +48,9 @@ RT-Thread online packages
 ## 4、注意事项
 
 - 该组件是基于wlan框架上运用的wifi定位,前提条件必须要有wifi芯片
-- 利用该组件时,需要重新开启任务处理,防止内存过小引发错误
+- 利用该组件时,需要重新开启任务处理,防止内存过小引发堆栈溢出错误
 
 ## 5、联系方式 & 感谢
 
 * 维护:jianxiong.ye
-* 主页:https://github.com/RT-Thread-packages/hello
+* 主页:https://github.com/wayz-iot/wayz_iotkit

+ 3 - 3
docs/README.md

@@ -2,7 +2,7 @@
 
 ## 1、介绍
 
-wayz_iotkit 是上海图趣信息科技有限公司,针对【硬件名称或型号】开发的能够实现定位功能的物联网组件。在使用传统上定位,如 GPS 等信号的同时,也支持使用基站、Wifi等数据,通过 WAYZ 定位云来进行定位。当前版本以实现支持wifi定位,后期会逐步实现对其他信号源的利用,进一步提升定位效果。
+wayz_iotkit 是上海图趣信息科技有限公司,针对RT-thread开发的能够实现定位功能的物联网组件。在使用传统上定位,如 GPS 等信号的同时,也支持使用基站、Wifi等数据,通过 WAYZ 定位云来进行定位。当前版本以实现支持wifi、gnss、基站定位,其中wifi定位为自动获取定位数据,gnss和基站需要开发者手动填写相关信息,后期会逐步实现对其他信号源的自动采集,进一步提升定位效果。
 
 ### 1.1 目录结构
 
@@ -48,9 +48,9 @@ RT-Thread online packages
 ## 4、注意事项
 
 - 该组件是基于wlan框架上运用的wifi定位,前提条件必须要有wifi芯片
-- 利用该组件时,需要重新开启任务处理,防止内存过小引发错误
+- 利用该组件时,需要重新开启任务处理,防止内存过小引发堆栈溢出错误
 
 ## 5、联系方式 & 感谢
 
 * 维护:jianxiong.ye
-* 主页:https://github.com/wayz-iot/wayz_iotkit.git
+* 主页:https://github.com/wayz-iot/wayz_iotkit

+ 6 - 4
docs/api.md

@@ -58,17 +58,19 @@ 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 wlan_info Wifi related information
  * 
- * @param key: Visiting the website key
+ * @param key Visiting the website key
+ * 
+ * @param post_data post gnss and cellulars data, obtain positioning results
  * 
- * @param location: get location result
+ * @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 get_position_info(twifi_info *wlan_info, char *key, tpost_data *post_data, tlocation_info *location);
 
 /**
  * print location result

+ 23 - 1
docs/samples.md

@@ -37,7 +37,29 @@
 #define  TENANT         "WAYZ"		   // 设备所属租户,通常是开放平台的用户 ID
 ```
 
-## 3、在`main()`主函数调用例程
+## 3、GNSS、基站数据的填充
+
+```c
+tpost_data post_data = {0};					// 定义上传数据结构体
+
+post_data.gnss.timestamp = 1606729066000;
+post_data.gnss.lng = 114.39583641301239;
+post_data.gnss.lat = 30.51769862171484;
+post_data.gnss.accuracy = 8;
+
+post_data.cellulars.count = 1;
+post_data.cellulars.cell[0].timestamp = 1515743846504;
+post_data.cellulars.cell[0].cellId = 149833211;
+rt_sprintf(post_data.cellulars.cell[0].radio_type, "%s", "gsm");
+post_data.cellulars.cell[0].mcc = 460;
+post_data.cellulars.cell[0].mnc = 11;
+post_data.cellulars.cell[0].lac = 36558;
+
+// 传入获取定位函数中
+get_position_info(wlan_info, ACCESS_KEY, &post_data, &location); 
+```
+
+## 4、在`main()`主函数调用例程
 在将下面代码嵌入main()中,即可实现调用:
 ```c
 extern int location_client_start(void);

+ 29 - 4
docs/user-guide.md

@@ -30,7 +30,7 @@ RT-Thread online packages
 - 注:wifi 名字和密码 供软件包切换模式用
 
 ## 工作原理
-设备中wifi模块获取周围环境中的wifi信息,组包通过http方式上传到WAYZ定位云平台,云平台进行分析后将经纬度等其他信息一并返回到软件包,软件包通过处理可以得到gcj02和wgs84标准的经纬度,和POI信息
+设备中wifi模块获取周围环境中的wifi信息,组包通过http方式上传到WAYZ定位云平台,云平台进行分析后将经纬度等其他信息一并返回到软件包,软件包通过处理可以得到gcj02和wgs84标准的经纬度,和POI信息。也可以通过传入gnss、基站等相关数据获取定位结果及其POI信息
 
 ## wifi、设备相关初始化
 ```c
@@ -78,15 +78,39 @@ if (ret != DEV_REGISTER_OK)
 }
 ```
 
+## 填充GNSS、基站信息定位
+```c
+typedef struct _gnss_unit_
+{
+    uint64_t timestamp;         // 数据收集的时间戳(UTC 时间,单位:毫秒)
+    double lng;                 // 经度
+    double lat;                 // 纬度 
+    float accuracy;             // 卫星定位水平精度,单位:米
+}tgnss_unit;
+
+typedef struct _cell_unit_
+{
+    uint64_t timestamp;         // 数据收集的时间戳(UTC 时间,单位:毫秒)
+    uint32_t cellId;            // 小区 ID,当 CDMA 时,为 BID(Base Station ID)
+    char radio_type[7];         // 基站类型,只能是以下值:gsm, wcdma, lte, cdma
+    uint32_t mcc;               // mobileCountryCode:MCC 码
+    uint32_t mnc;               // mobileNetworkCode:当 CDMA 时,为 SID(System ID)码
+    uint32_t lac;               // locationAreaCode:当 CDMA 时,为 NID(Network ID);
+                                                     当 LTE 时,为 TAC(Tracking Area code)
+}tcell_unit;
+```
+通过填充GNSS、基站等数据,传入定位接口即可获取定位结果信息
+
+
 ## 获取定位结果
 
-应用程序使用`get_position_info`函数从平台端获取位置信息。
+应用程序使用`get_position_info`函数从平台端获取位置信息。**其中ACCESS_KEY需要在平台上申请**
 `location_print`函数是打印位置相关信息
 
 示例代码如下所示:
 ```c
 tlocation_info location = {0};
-ret = get_position_info(wlan_info, ACCESS_KEY, &location); 
+ret = get_position_info(wlan_info, ACCESS_KEY, RT_NULL, &location); 
 if (RT_ERROR == ret)
 {
     rt_kprintf("\033[31;22mthe device failed to obtain latitude and longitude information.\033[0m\n");
@@ -96,6 +120,7 @@ else
     location_print(location);
 }
 ```
+- 其中`get_position_info`函数第三个参数为填充的`GNSS和基站数据`,相关操作可以参照[示例文档](docs/samples.md)
 
 **打印位置信息结果**
 ```c
@@ -119,7 +144,7 @@ POI: {"id": "7SkEZdfXQfS","type": "Residential","name": "中建东湖明珠国
 ```c
 while (1)
 {
-    ret = get_position_info(wlan_info, ACCESS_KEY, &location); 
+    ret = get_position_info(wlan_info, ACCESS_KEY, RT_NULL, &location); 
     if (RT_ERROR == ret)
     {
         rt_kprintf("\033[31;22mthe device failed to obtain latitude and longitude information.\033[0m\n");

+ 42 - 1
inc/wayz_pos.h

@@ -31,6 +31,8 @@
 
 #define  STR_ERROR           "1"
 
+#define  CELL_COUNT          32
+
 #pragma pack(push)
 #pragma pack(1)
 
@@ -41,6 +43,14 @@ enum
     DEV_REGISTER_FAIL
 };
 
+enum rd_type
+{
+    GSM = 0,
+    WCDMA,
+    LTE,
+    CDMA
+};
+
 typedef struct _ap_struct_info_
 {
     rt_uint8_t mac[MAC_COUNT];
@@ -112,6 +122,35 @@ typedef struct _location_info_
     uint64_t timestamp;  // When to locate the result
 }tlocation_info;
 
+typedef struct _gnss_unit_
+{
+    uint64_t timestamp;
+    double lng; // longitude
+    double lat; // latitude 
+    float accuracy; // Horizontal accuracy of satellite positioning, unit: meter
+}tgnss_unit;
+
+typedef struct _cell_unit_
+{
+    uint64_t timestamp;
+    uint32_t cellId;
+    char radio_type[7]; // Base station type, can only be the following values: GSM, WCDMA, LTE, CDMA
+    uint32_t mcc; // mobileCountryCode
+    uint32_t mnc; // mobileNetworkCode
+    uint32_t lac; // locationAreaCode
+}tcell_unit;
+
+typedef struct _cell_
+{
+    tcell_unit cell[CELL_COUNT];
+    uint8_t count;
+}tcell;
+
+typedef struct _post_data_
+{
+    tgnss_unit gnss;
+    tcell cellulars;
+}tpost_data;
 
 
 #pragma pack(pop)
@@ -176,13 +215,15 @@ char dev_register_init(twifi_info *wlan_info, tdeviec_info *dev_info, char *key)
  * 
  * @param key Visiting the website key
  * 
+ * @param post_data post gnss and cellulars data, obtain positioning results
+ * 
  * @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 get_position_info(twifi_info *wlan_info, char *key, tpost_data *post_data, tlocation_info *location);
 
 /**
  * print location result

+ 3 - 2
samples/location_client.c

@@ -49,7 +49,8 @@ static void location_client_entry(void *parament)
     }
 
     tlocation_info location = {0};
-    ret = get_position_info(wlan_info, ACCESS_KEY, &location); // 单词定位结果获取
+
+    ret = get_position_info(wlan_info, ACCESS_KEY, RT_NULL, &location); 
     if (RT_ERROR == ret)
     {
         rt_kprintf("\033[31;22mthe device failed to obtain latitude and longitude information.\033[0m\n");
@@ -61,7 +62,7 @@ static void location_client_entry(void *parament)
     
     while (1)
     {
-        ret = get_position_info(wlan_info, ACCESS_KEY, &location); // 单词定位结果获取
+        ret = get_position_info(wlan_info, ACCESS_KEY, RT_NULL, &location); 
         if (RT_ERROR == ret)
         {
             rt_kprintf("\033[31;22mthe device failed to obtain latitude and longitude information.\033[0m\n");

+ 101 - 21
src/wayz_pos.c

@@ -19,6 +19,33 @@ const double a = 6378245.0;
 const double ee = 0.00669342162296594323;
 const double pi = 3.14159265358979324;
 
+#define  FLOAT_EPS      1e-6
+#define  DOUBLE_EPS     1e-15
+
+static unsigned char check_double_equal_zero(double f)
+{
+    if(fabs(f) <= DOUBLE_EPS)
+    {
+        return RT_EOK;
+    }
+    else
+    {
+        return RT_ERROR;
+    }
+}
+
+static unsigned char check_float_equal_zero(float f)
+{
+    if(fabs(f) <= FLOAT_EPS)
+    {
+        return RT_EOK;
+    }
+    else
+    {
+        return RT_ERROR;
+    }
+}
+
 static unsigned char _outOfChina(double lat, double lon)
 {
     if (lon < 72.004 || lon > 137.8347)
@@ -275,7 +302,7 @@ _connected:
 //     return (FREQ_START + (channel - 1) * SEGMEMTATION);
 // }
 
-static char *point_cJson_handler(void)
+static char *point_cJson_handler(tpost_data *post_data)
 {
  /* declare a few. */
     cJSON *root = NULL;
@@ -287,6 +314,7 @@ static char *point_cJson_handler(void)
     char macBuf[MAC_LEN] = {0};
     char *cJsonBuffer = NULL;
     char *buffer = NULL;
+    unsigned char state = 0;
 
     root = cJSON_CreateObject();
 
@@ -314,25 +342,64 @@ static char *point_cJson_handler(void)
     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)
+
+    // add wifis
+    if (aucApInfo.count >= 4)
+    {
+        cJSON_AddItemToObject(img, "wifis", thm = cJSON_CreateArray());
+        for (i = 0, j = 0; i < aucApInfo.count; i++)
         {
-            //break;
+            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;
+            }
         }
+        state = 1;
     }
-    
+
+    if (RT_NULL != post_data)
+    {
+        // add gnss
+        if (RT_EOK != check_double_equal_zero(post_data->gnss.lng) && 
+            RT_EOK != check_double_equal_zero(post_data->gnss.lat) &&
+            RT_EOK != check_float_equal_zero(post_data->gnss.accuracy))
+        {
+            cJSON_AddItemToObject(img, "gnss", thm = cJSON_CreateObject());
+            cJSON_AddNumberToObject(thm, "timestamp", post_data->gnss.timestamp);
+            cJSON_AddItemToObject(thm, "point", fld = cJSON_CreateObject());
+            cJSON_AddNumberToObject(fld, "longitude", post_data->gnss.lng);
+            cJSON_AddNumberToObject(fld, "latitude", post_data->gnss.lat);
+            cJSON_AddNumberToObject(thm, "accuracy", post_data->gnss.accuracy);
+            state = 1;
+        }
+        // add cellulars
+        if (0 != post_data->cellulars.count)
+        {
+            cJSON_AddItemToObject(img, "cellulars", thm = cJSON_CreateArray());
+
+            for (i = 0; i < post_data->cellulars.count; i ++)
+            {
+                cJSON_AddItemToArray(thm, fld = cJSON_CreateObject());
+                cJSON_AddNumberToObject(fld, "timestamp", post_data->cellulars.cell[i].timestamp);
+                cJSON_AddNumberToObject(fld, "cellId", post_data->cellulars.cell[i].cellId);
+                cJSON_AddStringToObject(fld, "radioType", post_data->cellulars.cell[i].radio_type);
+                cJSON_AddNumberToObject(fld, "mobileCountryCode", post_data->cellulars.cell[i].mcc);
+                cJSON_AddNumberToObject(fld, "mobileNetworkCode", post_data->cellulars.cell[i].mnc);
+                cJSON_AddNumberToObject(fld, "locationAreaCode", post_data->cellulars.cell[i].lac);
+            }
+            state = 1;
+        }
+    }
+
     cJsonBuffer = cJSON_Print(root);
-    buffer = (char *)rt_malloc(rt_strlen(cJsonBuffer) + 4);
+    buffer = (char *)rt_malloc(rt_strlen(cJsonBuffer));
     if (RT_NULL == buffer)
     {
         wayz_error("point_cJson_handler create malloc failure.");
@@ -343,6 +410,11 @@ static char *point_cJson_handler(void)
     cJSON_Delete(root);
     rt_free(cJsonBuffer);
 
+    if (1 != state)
+    {
+        wayz_error("location No wifi, GNSS, cellulars signal data");
+        return STR_ERROR;
+    }
     return buffer; // 需要free
 }
 
@@ -725,7 +797,7 @@ char dev_register_init(twifi_info *wlan_info, tdeviec_info *dev_info, char *key)
  *         =0: location failure
  * 
 */
-char get_position_info(twifi_info *wlan_info, char *key, tlocation_info *location)
+char get_position_info(twifi_info *wlan_info, char *key, tpost_data *post_data, tlocation_info *location)
 {
     char *url = RT_NULL;
     unsigned char *buffer = RT_NULL;
@@ -759,13 +831,20 @@ char get_position_info(twifi_info *wlan_info, char *key, tlocation_info *locatio
     }
     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();
+    cJsonBuffer = point_cJson_handler(post_data);
+    if (rt_memcmp(cJsonBuffer, STR_ERROR, rt_strlen(STR_ERROR)) == 0)
+    {
+        wayz_error("location No wifi, GNSS, cellulars signal data");
+        result = RT_ERROR;
+        goto _url_fail;
+    }
+
     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;
+        goto _visit_fail;
     }
 
     result = RT_EOK;
@@ -775,11 +854,12 @@ char get_position_info(twifi_info *wlan_info, char *key, tlocation_info *locatio
     rt_free(buffer);
     buffer = RT_NULL;
 
+_visit_fail:
+    rt_free(cJsonBuffer);
+    cJsonBuffer = RT_NULL;
 _url_fail:
     rt_free(url);
-    rt_free(cJsonBuffer);
     url = RT_NULL;
-    cJsonBuffer = RT_NULL;
 _malloc_fail:
 
 #ifdef FINSH_USING_MSH