C++/Delphi/VB6.X SDK接入指引

版本更新

[v1.0.6.36] - 2022/03/20
  • 处理在某些语言环境下心跳异常的情况。
[v1.0.6.34] - 2021/12/15
  • 处理在某些语言环境下心跳异常的情况。
[v1.0.6.32] - 2021/04/03
  • 优化日志处理逻辑;
  • 须先调用PYunAPILevel并判断返回值后才允许启动SDK。
[v1.0.6.30] - 2020/09/26
  • 业务处理默认开辟新线程
  • 修复并发情况下请求数据异常的情况

开发环境

属性
IDE VS2010
平台工具集 v100

文件清单

  • 4pyun-api.dll
  • 4pyun-api.h

方法

1. 选项设置

/**
 * 设置API选项值
 * optname 参考 PYUNAPI_OPT_* 的定义
 * 返回值:
 * 0  设置成功
 * -1 不支持选项
 */
int __stdcall PYunAPISetOpt(int optname, void *optval);
选项定义 说明 类型 默认值
PYUNAPI_OPT_IDLE_TIME 0xffff TCP心跳间隔时间, 单位ms int 300000
PYUNAPI_OPT_READ_KEY 0xfffe 读数据密钥 string -
PYUNAPI_OPT_WRITE_KEY 0xfffd 写数据密钥 string -
PYUNAPI_OPT_AUTH_TIME 0xfffc 认证超时时间, 单位ms int 20000
PYUNAPI_OPT_LOGGER 0xfffb 指定API日志文件路径 string ./4pyun-api.log
PYUNAPI_OPT_CHARSET 0xfffa 开发编码设置 string UTF-8
PYUNAPI_OPT_DEV_MODE 0xfff9 开发者模式: 1是, 0否 int 0
PYUNAPI_OPT_DEVICE 0xfff8 多设备模式下设置当前设备ID string NULL
PYUNAPI_OPT_HOST_NAME 0xfff7 当前设备名称 string NULL
PYUNAPI_OPT_HOST_ADDR 0xfff6 当前设备本地IP string NULL
PYUNAPI_OPT_VENDOR 0xfff5 当前设备供应商 string NULL
PYUNAPI_OPT_FINGERPRINT 0xfff4 当前硬件指纹 string NULL

示例

int idle_time = 60000 * 10;  // 10分钟
int auth_time = 1000 * 30;   // 30秒
int dev_mode = 0;            // 开启开发者模式
// [必须]设置当前项目工程编码, 底层默认UTF-8编码
PYunAPISetOpt(PYUNAPI_OPT_CHARSET,   (void *)"GBK");
// [可选]激活开发者模式, 激活后默认在当前执行目录生成日志文件
PYunAPISetOpt(PYUNAPI_OPT_DEV_MODE,   (void *)&dev_mode);
// [可选]设置心跳间隔时间, ms
PYunAPISetOpt(PYUNAPI_OPT_IDLE_TIME, (void *)&idle_time);
// [可选]设置授权超时时间, ms
PYunAPISetOpt(PYUNAPI_OPT_AUTH_TIME, (void *)&auth_time);
// [可选]设置日志文件
PYunAPISetOpt(PYUNAPI_OPT_LOGGER, (void *)"C:/4pyun-api.log");

2. 事件拦截

/**
 * 参数:
 * event_type 参考 `PYUNAPI_EVENT_*` 的定义。
 * msg        针对目前event_type的描述说明。
 */
typedef void (__stdcall *event_callback)(int event_type, char *msg);

/**
 * 设置事件回调函数
 */
void __stdcall PYunAPIHookEvent(event_callback p_callback);
选项定义 说明
PYUNAPI_EVENT_ACCESS_GRANTED 1 API授权成功
PYUNAPI_EVENT_ACCESS_DENIED -1 API授权失败
PYUNAPI_EVENT_CHANNEL_ERROR -2 TCP连接异常
PYUNAPI_EVENT_CHANNEL_CLOSED -3 TCP链接关闭

示例

/**
 * API事件回调函数实现
 */
void __stdcall PYunAPIEventCallback(int event_type, char *msg){  
    switch (event_type) {
        case PYUNAPI_EVENT_ACCESS_GRANTED:
            printf("\nAccessGranted\n\n");
            break;
        case PYUNAPI_EVENT_ACCESS_DENIED:
            printf("\nAccessDenied %s\n\n", msg == NULL ? "" : msg);
            break;
        case PYUNAPI_EVENT_CHANNEL_ERROR:
            printf("\nChannelError %s\n\n", msg == NULL ? "" : msg);
            break;
        case PYUNAPI_EVENT_CHANNEL_CLOSED:
            printf("\nChannelClosed %s\n\n", msg == NULL ? "" : msg);
            break;
    }
    return;
}

// 设置事件拦截回调函数
PYunAPIHookEvent(PYunAPIEventCallback);

3. 拦截请求回调

通过该方法拦截后将不再通过函数触发请求回调, 所有的请求解析和数据返回由开发者自行处理, 请求处理成功需要调用PYunAPIReply返回数据。

/**
 * 请求回调函数
 * 参数:
 * seqno   请求序号, 需原样返回
 * payload 请求JSON数据
*
 * 返回值:
 * 1 请求已受理
 * 0 请求未受理
 */
typedef int (__stdcall *request_callback)(int seqno, char *payload);

/**
 * 设置请求拦截回调函数
 */
void __stdcall PYunAPIHookRequest(request_callback p_callback);

示例

int __stdcall PYunAPIRequestCallback(int seqno, char *payload) {
    // 根据JSON中的service判断是否处理, 如果没处理将ret设置为-1。
    int ret = 0;
    printf("RECV: %d, %s\n", seqno, payload);
    char *reply = "{\"service\":\"service.parking.detail\",\"version\":\"1.0\",\"charset\":\"UTF-8\",\"result_code\":\"1001\",\"message\":\"处理OK\",\"sign\":\"722059C5CC1B3FF5CDF8F8A4CF3B31CC\"}";
    // Reply的时候必须原样返回seqno!
    PYunAPIReply(seqno, reply);
    return ret;
}

// 设置请求回调函数
PYunAPIHookRequest(PYunAPIRequestCallback);

4. 发送请求结果响应

/**
 * 发送请求结果响应, 线程安全, 该方法会自动为发送的payload计算签名。
 * 参数:
 * seqno   请求序号
 * payload 应答JSON数据
 *
 * 返回值:
 * 0  发送成功
 * -1 发送失败
 */
int __stdcall PYunAPIReply(int seqno, char *payload);

5. 初始化API

在所有设置完成后需要调用该方法完成API初始化, 底层会开启一个线程和云端保持TCP长链接, 链接的状态可通过PYunAPIHookEvent注册的回调方法异步触发。

注: 每次重新设置后需要PYunAPIDestory后重新调用PYunAPIStart完成初始化。

/**
 * 初始化API
 * 参数:
 * host 云平台域名
 * port 云平台端口
 * type 客户端类型
 * uuid 客户端UUID, 一个UUID只能运行一个实例
 * sign_mac 接口通信JSON签名计算密钥
 *
 * 返回值:
 * 0 初始化完成
 */
int __stdcall PYunAPIStart(char *host, unsigned int port, char *type, char *uuid, char *sign_mac);

示例

int idle_time = 1000 * 30;
int auth_time = 1000 * 30;
int dev_mode = 0;
char *host = "sandbox.gate.4pyun.com";
unsigned int port = 8661;
char *type = "public:parking:agent";
char *uuid = "49f0cc52-e8c7-41e3-b54d-af666b8cc11a";
char *sign_mac = "22D42dSdae2";

// 获取SDK API等级, 必须执行这个步骤
int sdk_level = PYunAPILevel();
if (sdk_level < 10) {
    // 过低的SDK版本
    return -1;
}

// 1.1 设置事件拦截回调函数
PYunAPIHookEvent(PYunAPIEventCallback);
// 1.2 拦截请求回调
PYunAPIHookRequest(PYunAPIRequestCallback);

// 1.3 设置可选项
// [必须]设置当前项目工程编码, 底层默认UTF-8编码
PYunAPISetOpt(PYUNAPI_OPT_CHARSET,   (void *)"GBK");
// [可选]设置厂商代码, 用于区分设备厂商, 接入联系P云分配!
PYunAPISetOpt(PYUNAPI_OPT_VENDOR,   (void *)"PYUN");
// [可选]激活开发者模式, 默认在当前执行目录生成日志文件
PYunAPISetOpt(PYUNAPI_OPT_DEV_MODE,   (void *)&dev_mode);
// [可选]设置心跳间隔时间, ms
PYunAPISetOpt(PYUNAPI_OPT_IDLE_TIME, (void *)&idle_time);
// [可选]设置授权超时时间, ms
PYunAPISetOpt(PYUNAPI_OPT_AUTH_TIME, (void *)&auth_time);
// [可选]设置日志文件
PYunAPISetOpt(PYUNAPI_OPT_LOGGER, (void *)"C:/4pyun-api.log");

// 2. 启动API, 底层会开启线程和云端保持TCP长连接
PYunAPIStart(host, port, type, uuid, sign_mac);
// 3. 销毁API, 断开TCP长连接
getchar();
PYunAPIDestroy();
getchar();

6. 销毁API

当程序关闭时调用该方法可以主动关闭和云端链接并释放资源。

/**
 * 销毁API, 主动关闭和云端链接并释放资源。
 */
void __stdcall PYunAPIDestroy();

7. 获取SDK版本及API版本

上层应用可通过调用该方法获取当前SDK版本信息。

/**
 * 获取当前SDK版本号
 */
char* __stdcall PYunAPIVersion();
/**
 * 获取当前SDK API等级, 版本越新值越大
 */
char* __stdcall PYunAPILevel();

8. 内存拷贝

VB中要处理回调函数中的char *比较麻烦, SDK中方法实现如下:

int __stdcall PYunAPIMemcpy(char *src, char *dst) {
    memcpy(dst, src, strlen(src) + 1);    
    log_trace("[PYunAPI][Memcpy] - %p => %p, STR: %s", src, dst, src);
    return 0;
}

在VB中可

' 引入DLL方法, 这里将内存地址设置为long传递
Public Declare Function PYunAPIMemcpy Lib "4pyun-api.dll" (ByVal src As Long, ByVal dst As Long) As Integer

Public Sub ApiEventCallback(ByVal event_type As Long, ByVal pMsg As Long)
    Dim buf(2048) As Byte
    If pMsg > 0 Then PYunAPIMemcpy pMsg, VarPtr(buf(0))
    Dim msg As String
    msg = Utf8BytesToString(buf)
End Sub

附录

A. 多终端设置

默认P云一个项目只允许保持一个有效TCP连接用于数据通信, 为兼容部分系统厂商暂时提供多终端的解决方案, 该方案允许各个终端设置自己的device用于区分不同的终端。

在停车场景, device需设置为当前通道口ID, 设置方法如下:

// 只控制通道A
char *device = "A";
// 同时控制通道A、B、C
char *device = "A,B,C";

// [可选]设置设备ID, 仅在多终端模式下设置
PYunAPISetOpt(PYUNAPI_OPT_DEVICE, (void *)device);t

B. 设备信息设置

为便于排查多终端链接情况, SDK已提供支持设置设备信息便于查看当前具体连接到平台到终端信息例如: 主机名称、本地IP:

// 主机名称
char *hostname = "PC-1-1";
// 本地IP
char *local_ip = "192.168.1.66";

// [可选]设置当前本地主机名称
PYunAPISetOpt(PYUNAPI_OPT_HOST_NAME, (void *)hostname);
// [可选]设置当前本地主机IP
PYunAPISetOpt(PYUNAPI_OPT_HOST_ADDR, (void *)host_address);

C. SDK日志说明

由于SDK不会自动按日归档, 建议你可以隔日调用以下方法设置新的文件路径:

PYunAPISetOpt(PYUNAPI_OPT_LOGGER, (void *)"C:/4pyun-api-20210401.log");
© 2024 Shenzhen ChinaRoad Technology Co., Ltd. © All Rights Reserved            UPDATED 2024/12/05 13:26:22

results matching ""

    No results matching ""