對接說明
1. 整體架構
2. 業務流程
智能識別業務鏈路
二維碼業務鏈路
3. 對接LinkKit-SDK
C語言SDK
完整SDK手冊:https://code.aliyun.com/edward.yangx/public-docs/wikis/user-guide/linkkit/Archived/V230_Snapshot_Index
交叉編譯手冊:https://code.aliyun.com/edward.yangx/public-docs/wikis/user-guide/linkkit/Archived/V230_Snapshot/porting/Make_Usage
Android版SDK手冊
創建門禁產品
訪問地址:https://iot.console.aliyun.com/product,創建產品(創建多功能門禁產品)。
所屬品類選擇多功能門禁。
前往定義物模型。
添加設備的多功能門禁功能,點擊編輯草稿。
點擊添加標準功能。
進入功能頁,勾選所有功能項,點擊確認。
創建門禁設備
選擇多功能門禁產品
復制多功能門禁證書
下載的證書,請參照一下文檔,將設備證書(ProductKey、DeviceName、DeviceSecret)設置到linkkitsdk中,正常運行后,可以查看到該設備的狀態變更為上線,本案例采用一機一密模式進行。
C語言設備認證地址:https://code.aliyun.com/edward.yangx/public-docs/wikis/user-guide/linkkit/Archived/V230_Snapshot/programme/Auth_Connect#%E4%B8%80%E6%9C%BA%E4%B8%80%E5%AF%86%E7%BC%96%E7%A8%8B
Android設備認證地址:認證與連接
設備開發,設備物模型開發手冊,您可以通過這個文檔內容學習怎么通過SDK完成物模型中的服務和事件的實現,針對門禁對接中您需要實現syncPermissions、remoteOpen兩個服務、passEvent一個事件、RSAPublicKey一個屬性。
C語言SDK設備開發說明:https://code.aliyun.com/edward.yangx/public-docs/wikis/user-guide/linkkit/Archived/V230_Snapshot/programme/DeviceModel_Prog
Android版SDK設備開發說明:物模型開發
RSA公鑰(RSAPublicKey):二維碼加密公鑰,云端會在設備上電并設備綁定后觸發下發的公鑰信息,用于后續通過攝像頭獲取用戶二維碼之后的解密校驗。
同步門禁權限(syncPermissions):云端下發使用二維碼的用戶權限配置信息到設備端。參數:權限URL(permissionUrl)為權限配置文件下載地址,通過HTTP下載。
字段
類型
備注
qrCodePermissionList
JSONArray
二維碼的權限配置內容
tradCardPermissionList
JSONArray
傳統卡的權限配置內容
bleCardPermissionList
JSONArray
藍牙卡的權限配置內容
passwordPermissionList
JSONArray
密碼的權限配置內容
二維碼的權限配置定義
字段
類型
備注
type
Integer
操作類型。
取值范圍:1-增加,2-刪除,3-修改。
qrCode
String
用戶信息內容。樣例:ALI24DD9END8CD3F,表示一個人的唯一id
startTime
String
生效時間(UTC)單位精確到毫秒。
endTime
String
生效時間(UTC)單位精確到毫秒。
maxScanTimes
String
最大刷碼限制次數。-1 表示無限制。
maxScanScope
Integer
表明二維碼刷碼次數限制是多個設備共享還是單個設備維度,默認設備維度。如果不限制刷碼次數,無需指定該值。
取值范圍:SHARE 或 DEVICE,默認DEVICE。
二維碼校驗機制,用戶在設備前展示二維碼,設備獲取二維碼后進行RSA解密,解密后的數據格式為:code:timestamp(樣例:ALI24DD9END8CD3:1589369696)。
字段
語義
備注
code
下發二維碼權限中的qrCode
需要和本地存儲的qrCode列表做對比,對比成功表示當前人是有效的
timestamp
秒級時間戳,表示當前碼的有效期
需要和本地設備時間進行對比,如果這個時間戳<當前時間則提示“二維碼已過期”
遠程開門(remoteOpen):云端下發對設備的開門命令,設備端執行開門動作。
通行事件(passEvent):使用二維碼、傳統卡、藍牙卡、密碼進行通行時,將通行結果及認證信息發到云端。
字段
類型
備注
code
Int
錯誤編碼,成功為0,其他值為失敗。格式定義見下面code列表。
message
String
錯誤信息,成功(success),或者失敗的原因。格式定義見下面code列表。
type
String
認證類型,二維碼(qrCode)、傳統卡(tradCard)、藍牙卡(bleCard)、密碼(password)、智能(face)
content
String
認證內容(content):二維碼字符串、卡號、藍牙卡號、密碼字符串。
extInfo
String
擴展信息(extInfo):內容為string格式,先構造JSON對象,再將JSON對象轉成string格式放入其中,詳見下面示例。
{ "code": 0, // "message": "success", // "type": "qrCode", // "content": "ALI7af81cfad5df1", // "extInfo": "{\"type\":\"qrCode\",\"qrCode\":\"ALI7af81cfad5df1 \",\"userID\":\"508072501fea93ae39fc8737a2fb2a2424f88787\",\"event Time\":\"1597821579\"}" 7}
通行結果(code)
結果說明(message)
0
成功
success
101
二維碼未生效
QR code does not take effect
102
二維碼已過期
QR code has expired
103
二維碼不存在
QR code does not exist
104
二維碼刷碼次數用盡
QR code have be used up
設備SDK下載
文件目錄介紹
tree -L 3 . ├── CMakeLists.txt ├── LinkFace │ ├── samples │ │ ├── 1.jpg │ │ ├── database.c │ │ ├── database.h │ │ ├── linkface_demo.c │ │ ├── linkface_demo_v2.c │ │ ├── linkkit_adapter.c │ │ ├── link_visual_face_demo │ │ ├── link_visual_face_demo_v2 //對接Demo可執行文件 │ │ └── list.h //鏈表頭文件 │ └── sdk │ ├── liblinkface.a │ ├── liblinkface.so │ ├── liblinkface_v2.a //linkface靜態庫 │ ├── liblinkface_v2.so //linkface動態庫 │ ├── linkface_sdk.h │ └── linkface_sdk_v2.h //linkface頭文件 └── third_party //以靜態庫方式對接時,在此目錄下獲取需要的三方.a文件 ├── cJSON │ ├── cJSON.h │ ├── libcjson.a │ ├── libcjson.so │ ├── libcjson.so.1 │ └── libcjson.so.1.7.7 ├── cJSON-1.7.7.tar.gz ├── linkkit-sdk-c │ ├── exports │ ├── imports │ ├── iot_export.h │ ├── iot_import.h │ ├── libiot_hal.a │ ├── libiot_sdk.a │ └── libiot_tls.a ├── linkkit-sdk-c.tar.gz ├── release //以靜態庫方式對接時,在此目錄下獲取需要的三方.a文件 │ ├── apr │ ├── apr_util │ ├── curl │ ├── expat │ ├── iconv │ ├── mxml │ ├── openssl │ ├── oss_c_sdk │ └── zlib ├── sqlite │ ├── libsqlite3.a │ ├── libsqlite3.so │ └── sqlite3.h └── sqlite-amalgamation-3310100.zip sdk集成方式: 1.集成動態庫:鏈接liblinkface_v2.so libiot_sdk.a libiot_tls.a libiot_hal.a 2.集成靜態庫:鏈接liblinkface_v2.a libiot_sdk.a libiot_tls.a libiot_hal.a libcjson.a liboss_c_sdk_static.a libaprutil-1.a libapr-1.a libmxml.a libcurl.a libcrypto.a libssl.a 2.集成靜態庫:鏈接liblinkface_v2.a libcjson.a liboss_c_sdk_static.a libaprutil-1.a libapr-1.a libmxml.a libcurl.a libiconv.a libssl.a libcrypto.a m
頭文件說明
#ifndef __LINKFACE_SDK_V2_H__ #define __LINKFACE_SDK_V2_H__ #include "utils/list.h" #ifdef __cplusplus extern "C" { #endif #define LENGTH_PERSON_ID 65 #define LENGTH_PERSON_NAME 128 #define LENGTH_FACE_MD5 33 #define LENGTH_GROUP_ID 64 #define LENGTH_EVENTLIST 1024 //事件隊列長度 #define MAX_COUNT_GROUP_ID 16 #define MAX_LENGTH_EXTRA_INFO 2048 /* 錯誤碼枚舉值 */ typedef enum { LF_ERR_SUCCESS = 0, //成功 // 添加底庫錯誤碼表 LF_ERR_IMAGE_PARSEPIC_FAIL = 16001, //圖片解析失敗 LF_ERR_IMAGE_PIC_TOOBIG = 16002, //圖片過大 LF_ERR_IMAGE_PIC_TOOSMALL = 16003, //圖片過小 LF_ERR_IMAGE_NO_FACE = 16004, //圖片中未檢測到人 LF_ERR_IMAGE_MULTI_FACES = 16005, //圖片中檢測到多人 LF_ERR_IMAGE_FACE_EXIST = 16006, //已存在 LF_ERR_IMAGE_PIC_FORMATE_ERR = 16007, //不支持的圖片格式 LF_ERR_IMAGE_PIX_ERR = 16008, //不支持的像素 LF_ERR_IMAGE_UNKNOWN_ERR = 16009, //其他未知錯誤 LF_ERR_IMAGE_ALG_ERR = 16010, //算法異常,無法提特征 LF_ERR_IMAGE_FACE_DB_FULL = 16011, //底庫達到最大值 // 文件下載錯誤碼列表 LF_ERR_URL_DOWNLOAD_FAILED = 17001 //下載失敗 } LINKFACE_ERROR_CODE_E; /*新增底庫需要的字段*/ typedef struct { /*! 人員ID: 可能是身份證號碼,也可能是其他身份唯一標示。 */ char person_id[LENGTH_PERSON_ID]; /*! 數據md5值。*/ char faceimg_md5[LENGTH_FACE_MD5]; /*! 圖片數據大小。單位:字節。僅在注冊時有效。 */ int faceimg_size; /*! 圖像原始數據。*/ char* faceimg; /*! 新增本次數據時的時間戳, 單位為ms。*/ long long timestamp_ms; } linkface_image_info; /* * 照片添加隊列 */ typedef struct __tag_add_face_image_list{ struct list_head face_list; linkface_image_info face_image_info; }LINKFACE_ADD_FACE_IMAGE_LIST_ST; typedef struct { /*! 人員ID: 可能是身份證號碼,也可能是其他身份唯一標示。 */ char person_id[LENGTH_PERSON_ID]; /*! 人員姓名,可能為空。*/ char name[LENGTH_PERSON_NAME]; /*! 該人員所在的組ID,一個人可能存在于多個組中*/ char group_ids[MAX_COUNT_GROUP_ID][LENGTH_GROUP_ID]; int group_id_count; /*! 新增該人員信息時的時間戳,單位為ms。*/ long long timestamp_ms; /*! 注冊時的其他信息。 */ char *extra_info; } linkface_user_info; /// 比對狀態。 typedef enum { /*! 比對失敗。 */ LINKFACE_MATCH_STATUS_FAILED = -1, /*! 未進行比對。 */ LINKFACE_MATCH_STATUS_NULL = 0, /*! 比對成功。 */ LINKFACE_MATCH_STATUS_SUCCESS = 1, }linkface_match_status_t; // 增量事件類型 typedef enum { //用戶信息 LINKFACE_SYNC_EVENT_USERINFO = 1, //用戶圖片 LINKFACE_SYNC_EVENT_USERPIC = 2, //用戶特征 LINKFACE_SYNC_EVENT_USERFEATURE = 3, //用戶快速刪除 LINKFACE_SYNC_EVENT_USERFASTDEL = 4, //刪除用戶組 LINKFACE_SYNC_EVENT_GROUPDEL = 5, //清空所有數據 LINKFACE_SYNC_EVENT_DELTOTAL = 21 }LINKFACE_SYNC_EVENT_E; /*對比上報*/ /*注冊需要的字段*/ typedef struct { /*! 比對狀態。 */ linkface_match_status_t match_status; //對比成功才會有(即person_id,match_score)的值才有意義 /*! 比對到的人員ID。 抓拍成功時,必要字段。*/ char person_id[64]; /*! 對比相似度。 抓拍成功時,必要字段。范圍為[1, 100]*/ int match_score; /*! 全景圖大小。單位為Byte,不能超過10MByte. */ int panorama_img_size; //大小大于0時全景圖的數據才有意義,否則全景圖所有數據全部置空 /*! 全景圖原始數據。必要字段。 */ char *panorama_img; /*! 全景圖名稱。 必要字段。 */ char *panorama_img_name; /*! 事件產生utc時間。 必要字段。 */ long long timestamp_ms; }linkface_match_result; /* * 事件上報隊列 */ typedef struct __tag_event_list{ struct list_head event_list; linkface_match_result match_result; }LINKFACE_EVENT_LIST_ST; /** 云端下發底庫同步請求時,sdk先緩存圖片,再調用該接口將圖片批量入庫。 * @brief 批量注冊數據接收回調函數。 * @param[IN] pImageInfoList,圖片信息列表。 * @param[IN] num,該值為pImageInfoList、pErrorCode的個數。 * @param[OUT] pErrorCode,每張圖片的入庫結果 * @ret void * * 注意: * 1. 該接口為同步調用,接口不宜耗時過久。 * 2. 該接口不會在多線程中并發調用。 * 3. 每張圖片的添加結果,都要返回到pErrorCode中 * 4. 錯誤碼請嚴格按照 @LINKFACE_ERROR_CODE_IMAGE_E 中的定義. */ typedef int (*linkface_add_image_batch_cb)(const struct list_head *pImageInfoList, int num, int *pErrorCode); /* * 添加用戶信息,成功返回0,失敗返回其他值. */ typedef int (*linkface_add_user_cb)(const linkface_user_info *info, void *user); /** 云端需要刪除某個底庫時,sdk會調用該接口將信息逐個傳遞給廠商,廠商需要將該從算法數據庫中刪除. * @brief 刪除數據接收回調函數格式定義。 * @param id。 * @param user 用戶參數,用戶設置回調時指定的參數通過該參數再次回傳給用戶。 * @ret 如果刪除成功,則返回0,否則返回其他值。 * * 注意: * 1. 只有數據真實存在時(person_id/faceimg_md5組合校驗),才返回成功。 * 2. person_id 不存在返回-1。 * 3. person_id 存在而 faceimg_md5 不存在,返回-2。 * */ typedef int (*linkface_del_image_cb)(const linkface_image_info *info, void *user); /* * 刪除用戶信息, 成功返回0,失敗返回其他值. * */ typedef int (*linkface_del_user_cb)(const linkface_user_info *info, void *user); /* * 基于入庫的時間戳,輪詢底庫信息。 * */ typedef void (*linkface_polling_image_cb)(long long timestamp_ms, void *user, void (*cb_sdk)(const linkface_image_info *info, void *user), void *user_sdk); /* * 基于入庫的時間戳,輪詢人員庫信息。 * */ typedef void (*linkface_polling_user_info_cb)(long long timestamp_ms, void *user, void (*cb_sdk)(const linkface_user_info *info, void *user), void *user_sdk); /* * 基于人員id,查詢底庫信息。 * 廠商實現,結構體內存由sdk釋放。 * */ typedef linkface_image_info* (*linkface_query_image_info_cb)(char *person_id, void *user); /* * 基于人員id,查詢人員信息. * */ typedef linkface_user_info* (*linkface_query_user_info_cb)(char *person_id, void *user); /* * 查詢端側圖片總數 * */ typedef int (*linkface_querey_image_count_cb)(void *user); /* * @brief 清除用戶分組下的所有用戶信息 * @param[IN] group_id, 用戶組ID * @ret 如果刪除成功,則返回0,否則返回具體錯誤碼 */ typedef int (*linkface_clear_usergroup_cb)(const char *group_id); /* * 清空庫回調函數,由設備廠商實現 * * */ typedef int (*linkface_clearall_cb)(); /** 當門禁機檢測到后,無論是否能正確識別出該,均需要調用本接口將識別結果上報到云端。 * @param result 識別結果,如果識別成功,需要包含已識別的人的基本信息。 * * @return 成功返回0,失敗返回其他值。 * * 注意: * 1. 該接口為同步接口,請勿并發調用。 * 2. 若接口返回失敗,建議最多重試3次。 */ int linkface_upload_match_result(const linkface_match_result *result); /* 產品三元組長度限制 */ #define LINKFACE_PRODUCT_KEY_LEN (20) #define LINKFACE_DEVICE_NAME_LEN (32) #define LINKFACE_DEVICE_SECRET_LEN (64) typedef struct { char product_key[LINKFACE_PRODUCT_KEY_LEN + 1]; /* 三元組之一,由平臺頒發的產品唯一標識,11位長度的英文數字隨機組合 */ char device_name[LINKFACE_DEVICE_NAME_LEN + 1]; /* 三元組之一,在注冊設備時,自定義的或自動生成的設備名稱,具備產品維度內的唯一性 */ char device_secret[LINKFACE_DEVICE_SECRET_LEN + 1]; /* 三元組之一,物聯網平臺為設備頒發的設備密鑰*/ } linkface_device_triple_t; /* 物聯網平臺上分發的三元組信息。 */ /* SDK日志等級 */ typedef enum { LF_LOG_DEBUG = 0, LF_LOG_INFO = 1, LF_LOG_WARN = 2, LF_LOG_ERROR = 3, } linkface_log_level_e; typedef enum { LF_STDOUT = 0, LF_FILE = 1 } linkface_log_dest_e; typedef struct { linkface_log_level_e lvl; linkface_log_dest_e dst; } linkface_log_cfg_t; typedef struct { char *logpath; //日志文件保存路徑 char *picpath; //照片保存路徑 char *eventpath; //告警事件文件保存路徑 int max_size_log_mb; //日志存儲目錄大小Mb int max_size_cache_mb; //照片存儲目錄大小Mb int max_size_event_mb; //告警事件存儲目錄大小Mb } linkface_cache_cfg_t; typedef struct { int addFaceBatchSize; //每次批量添加的人數,范圍為1~15 linkface_device_triple_t triple; linkface_log_cfg_t cfg_log; linkface_cache_cfg_t cfg_cache; /* 批量增加底庫圖片*/ struct { linkface_add_image_batch_cb cb; void *user; } config_batch_add_image; /* 刪除一個底庫圖片*/ struct { linkface_del_image_cb cb; void *user; } config_del_image; /* 基于id查詢底庫圖片信息*/ struct { linkface_query_image_info_cb cb; void *user; } config_query_image_info; /* 遍歷所有底庫圖片信息*/ struct { linkface_polling_image_cb cb; void *user; } config_polling_image_info; /* 增加人員信息. */ struct { linkface_add_user_cb cb; void *user; } config_add_user; /* 刪除人員信息. */ struct { linkface_del_user_cb cb; void *user; } config_del_user; /* 查詢人員信息. */ struct { linkface_query_user_info_cb cb; void *user; } config_query_user_info; /* 輪詢所有人員信息. */ struct { linkface_polling_user_info_cb cb; void *user; } config_polling_user_info; /*聚合接口:查詢端側總數. */ struct { linkface_querey_image_count_cb cb; void *user; } config_query_image_count; /* 聚合接口: 清空所有和底庫圖片信息. */ struct { linkface_clearall_cb cb; } config_clearall; /* 清空指定分組. */ struct { linkface_clear_usergroup_cb cb; } config_clear_usergroup; } linkface_config_t; /* * SDK 初始化接口. */ int linkface_init(linkface_config_t *cfg); /* * 消息路由接口,源碼開放. */ int linkface_message_router(const char *service_name, const int service_name_len, const char *request, const int request_len, char **response, int *response_len); /** 進程退出前,釋放sdk資源。 */ void linkface_destroy(); #ifdef __cplusplus } #endif #endif
對接DEMO源碼
#include <unistd.h> #include <signal.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <time.h> //填寫.h文件的實際路徑 #include "../src/v2/utils/list.h" #include "linkface_sdk_v2.h" // 固定失敗一些入庫圖片 #define FAILED_SOME_PIC extern int linkkit_destroy(); extern int linkkit_init(const char *product_key, const char *device_name, const char *device_secret); int g_flag_is_running = 1; void sig_handler(int signo) { printf("catch the signal SIGINT %d\n",signo); g_flag_is_running = 0; exit(0); } /* 批量入庫回調函數 */ static int _add_user_batch(const struct list_head *pImageInfoList, int num, int *pErrorCode, void *arg) { if (!list_empty(pImageInfoList)) { LINKFACE_ADD_FACE_IMAGE_LIST_ST *node = NULL; LINKFACE_ADD_FACE_IMAGE_LIST_ST *next = NULL; int cur_index = 0; list_for_each_entry_safe(node, next, pImageInfoList, face_list, LINKFACE_ADD_FACE_IMAGE_LIST_ST) { #ifdef FAILED_SOME_PIC // 固定第二個錯誤 if (++cur_index == 1){ *(pErrorCode + cur_index) = -1; continue; } #endif add_image_info((const char *)(&(node->face_image_info))); //add_image_info由設備廠商實現 printf("add_image person_id:{%s}, md5:{%s}\n", node->face_image_info.person_id, node->face_image_info.faceimg_md5); } } return 0; } /* * 用戶照片刪除 */ static int _del_image(const linkface_image_info *person, void *arg) { printf("del face from local database: %s\n", person->person_id); return del_image_info((const char *)person->person_id); //del_image_info由設備廠商實現 } /* * 用戶信息添加 */ static int _add_user(const linkface_user_info *person, void *arg) { printf("add user to local database: %s, name: %s\n", person->person_id, person->name); return add_user_info((const linkface_user_info*)person); //add_user_info由設備廠商實現 } /* * 用戶信息刪除 */ static int _del_user(const linkface_user_info *person, void *arg) { printf("del user from local database: %s\n", person->person_id); return del_user_info((const char *)person->person_id); //del_user_info由設備廠商實現 } /* * 清空庫 */ static int _clear_all() { clear_data(); //clear_data由設備廠商實現 return 0; } /* * 清除指定用戶分組 */ static int _clear_gourp(char * groupid) { printf("del group face from local database: %s\n", groupid); return clear_gourp_face(groupid); //clear_gourp_face由設備廠商實現 } /* * 底庫照片總數查詢回調函數 */ static int _query_image_base_count(void *arg) { int count = 0; count = query_image_count(); //clear_gourp_face由設備廠商實現 printf("query facebase count : %d\n", count); return count; } /* * 用戶信息查詢回調函數 */ static linkface_user_info *_query_user_info(char *person_id, void *arg) { linkface_user_info *tmp = NULL; int len = sizeof(linkface_user_info); tmp = (linkface_user_info*)malloc(len); if (tmp == NULL) { return NULL; } memset(tmp, 0, len); query_user_info((const char *)person_id, &tmp); //query_user_info由設備廠商實現 printf("query user info: %s, name: %s\n", person_id, tmp->name); if(tmp->timestamp_ms == 0) { free(tmp); tmp = NULL; } return tmp; } /* * 用戶照片查詢回調函數 */ static linkface_image_info *_query_image_info(char *person_id, void *arg) { linkface_image_info *tmp = NULL; int len = sizeof(linkface_image_info); tmp = (linkface_image_info *)malloc(len); if (tmp == NULL) { return NULL; } memset(tmp, 0, len); query_image_info((const char *)person_id, &tmp); //query_image_info由設備廠商實現 printf("query face info: %s, md5: %s\n", person_id, tmp->faceimg_md5); if(strlen(tmp->faceimg_md5) == 0) { free(tmp); tmp = NULL; } return tmp; } /* * 用戶照片遍歷回調函數 */ static void _polling_image_base (long long timestamp, void *arg, void (*cb_sdk)(const linkface_image_info *person, void *user), void *user_sdk) { printf("polling_image_base\n"); polling_image_info(timestamp, cb_sdk, user_sdk); //polling_image_info由設備廠商實現 } /* * 用戶信息遍歷回調函數 */ static void _polling_userinfo_base (long long timestamp, void *arg, void (*cb_sdk)(const linkface_user_info *person, void *user), void *user_sdk) { printf("polling_userinfo_base\n"); polling_user_info(timestamp, cb_sdk, user_sdk); //polling_user_info由設備廠商實現 } #define PRODUCT_KEY "" #define DEVICE_NAME "" #define DEVICE_SECRET "" int main(int argc, char **argv) { int ret = 0; const char *pk = NULL; const char *dn = NULL; const char *ds = NULL; const char *dir = NULL; /* alarm_interval < 0 直接退出 alarm_interval = 0 不上報事件 alarm_interval > 0 代表上報事件間隔 */ int alarm_interval = 0; if(argc < 5) { printf("use default triples, you can modify it by: ./xxx_demo $pk $dn $ds $path \n"); pk = PRODUCT_KEY; dn = DEVICE_NAME; ds = DEVICE_SECRET; dir = "./"; } else { pk = argv[1]; dn = argv[2]; ds = argv[3]; dir = argv[4]; alarm_interval = atoi(argv[5]); } if (signal(SIGINT,sig_handler) == SIG_ERR) { perror("signal errror"); exit(EXIT_FAILURE); } /* 初始化linkface配置參數。 */ linkface_config_t cfg; memset(&cfg, 0, sizeof(linkface_config_t)); /* 物聯網平臺三元組信息. */ strncpy(cfg.triple.product_key, pk, LINKFACE_PRODUCT_KEY_LEN); strncpy(cfg.triple.device_name, dn, LINKFACE_DEVICE_NAME_LEN); strncpy(cfg.triple.device_secret, ds, LINKFACE_DEVICE_SECRET_LEN); /* 日志輸出配置信息. */ cfg.cfg_log.lvl = LF_LOG_DEBUG; cfg.cfg_log.dst = LF_FILE; /* 緩存配置信息. */ cfg.addFaceBatchSize = 10; cfg.cfg_cache.logpath = dir; cfg.cfg_cache.picpath = dir; cfg.cfg_cache.eventpath = dir; cfg.cfg_cache.max_size_log_mb = 30; //日志文件目錄100M cfg.cfg_cache.max_size_cache_mb = 50; //緩存圖片 500M cfg.cfg_cache.max_size_event_mb = 50; /* 用戶需要實現的接口: 增加底庫信息. */ cfg.config_batch_add_image.cb = _add_user_batch; /* 用戶需要實現的接口: 刪除底庫信息. */ cfg.config_del_image.cb = _del_image; /* 用戶需要實現的接口: 通過id查詢某個底庫信息*/ cfg.config_query_image_info.cb = _query_image_info; /* 用戶需要實現的接口: 輪詢底庫信息*/ cfg.config_polling_image_info.cb = _polling_image_base; /* 用戶需要實現的接口: 查詢底庫總數*/ cfg.config_query_image_count.cb = _query_image_base_count; /* 用戶需要實現的接口: 增加用戶信息 */ cfg.config_add_user.cb = _add_user; /* 用戶需要實現的接口: 刪除用戶信息 */ cfg.config_del_user.cb = _del_user; /* 用戶需要實現的接口: 通過id查詢用戶信息*/ cfg.config_query_user_info.cb = _query_user_info; /* 用戶需要實現的接口: 輪詢用戶信息*/ cfg.config_polling_user_info.cb = _polling_userinfo_base; /* 用戶需要實現的接口: 清空底庫. */ cfg.config_clearall.cb = _clear_all; cfg.config_clear_usergroup.cb = _clear_gourp; /* 確保linkface + linkkit 初始化完成.*/ while (1) { ret = linkkit_init(pk, dn, ds); if (ret < 0) { printf("linkkit sdk init failed, retry 1s later.\n"); sleep(1); if(g_flag_is_running == 0) { return 0; } continue; } ret = linkface_init(&cfg); if (ret < 0) { printf("linkface sdk init failed, retry 1s later.\n"); linkkit_destroy(); sleep(1); if (g_flag_is_running == 0) { return 0; } continue; } } return 0; }
設備自測,進入設備在線調試界面
選擇同步數據服務
新增
{"FaceDataUrl":"https://linkface-doc.oss-cn-shanghai.aliyuncs.com/logdpx-add-2.json"}
刪除
{"FaceDataUrl":"https://linkface-doc.oss-cn-shanghai.aliyuncs.com/logdpx-del.json"}
清空
{"FaceDataUrl":"https://face-biz-2-online.oss-cn-shanghai.aliyuncs.com/05A19AEFC200431B9E1F7C371B754B48/a103B6PNtuKdx2Fr/a15qAuXknvo_lfv_4_MAIN_CURSOR_0_1597213340164.json?Expires=1599805340&OSSAccessKeyId=*************&Signature=hgFXz%2FMr9lOr6CtfoNzVth8Jmko%3D"}
選擇RSA公鑰服務
{ "RSAPublicKey": "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAI6zQY57YYUh1xDOk9ZOXQapFpSGmZIukTtJkvM5rf43b4H6tmzH27anYW8csBKmFAdJir9ZaJY1GhZO6FY/8d0CAwEAAQ=="}
以下二維碼是私鑰加密的測試二維碼
有效期至:2022年的二維碼(明文:ALIF24DD9END8CD3:1661011200, 密文:Pd3fZ3VDviUjZ6dREW1wIeITxKQBAmmxJ1ZRL6kmAfq2RmXGiZBiv8wh39ySPODojwPCpYwsF4Ken5znf/sGtQ==)
已過期的二維碼(明文:ALIF24DD9END8CD3:1597939200,密文:XW5qDO45+wJe31/q5mMkx6EZDKf754yg2pg3QhUoSL6VBtwIzUlkKW+NilPC5tXpdlRlI92PNLhjtFlU707l2w==)
選擇同步門禁權限服務
{"permissionUrl":"https://product-info.oss-cn-shanghai.aliyuncs.com/test.json"}
URL為您上傳文件在互聯網上可直接下載的URL地址,文件demo文件內容見下方
{ "qrCodePermissionList":[ { "type":1, "qrCode":"ALIF24DD9END8CD3", "startTime":"1568270392000", "endTime":"1599892792000", "maxScanTimes":600, "maxScanScope":"SHARE" }, { "type":2, "qrCode":"ALIF24DD9END8CD3" }, { "type":3, "qrCode":"ALIF24DD9END8CD3", "startTime":"1568270392000", "endTime":"1599892792000", "maxScanTimes":600, "maxScanScope":"SHARE" } ] }
二維碼通行事件
在物聯網平臺中,查看設備的物模型數據,可以通過passEvent來進行過濾檢索,檢查上報的內容和下面的JSON數據一致
{"code":0,"message":"success","type":"qrCode","content":"ALIF24DD9END8CD3"}
4. 對接LinkFaceSDK
本章將以C版本SDK為例著重介紹,如過您使用的是Android版本,請查看LinkFace Android設備端開發指南。
5. 單元測試方法