1459 lines
40 KiB
C
1459 lines
40 KiB
C
/**
|
|
* Copyright (2017) Baidu Inc. All rights reserved.
|
|
*
|
|
* 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.
|
|
*/
|
|
// Author: Su Hao (suhao@baidu.com)
|
|
//
|
|
// Description: Provide the API for external applications.
|
|
|
|
#include "lightduer_ca.h"
|
|
#include "lightduer_timestamp.h"
|
|
#include "lightduer_lib.h"
|
|
#include "lightduer_coap_trace.h"
|
|
#include "lightduer_coap.h"
|
|
#include "lightduer_ca_conf.h"
|
|
#include "lightduer_mutex.h"
|
|
#include "lightduer_memory.h"
|
|
#include "lightduer_log.h"
|
|
#include "lightduer_ds_log_ca.h"
|
|
#include "lightduer_timestamp.h"
|
|
#include "baidu_json.h"
|
|
|
|
#define DUER_CONF_KEY_UUID "uuid"
|
|
#define DUER_CONF_KEY_TOKEN "token"
|
|
#define DUER_CONF_KEY_BINDTOKEN "bindToken"
|
|
#define DUER_CONF_KEY_HOST "serverAddr"
|
|
#define DUER_CONF_KEY_PORT_REG "lwm2mPort"
|
|
#define DUER_CONF_KEY_PORT_RPT "coapPort"
|
|
#define DUER_CONF_KEY_CERT "rsaCaCrt"
|
|
#define DUER_CONF_KEY_CUID "cuid"
|
|
#define DUER_CONF_KEY_BDUSS "bduss"
|
|
#define DUER_CONF_KEY_CLIENT_ID "clientId"
|
|
#define DUER_CONF_KEY_USER_AGENT "userAgent"
|
|
|
|
#define DUER_COAP_LIFETIME "3600"
|
|
|
|
#define DUER_SR_REG_PATH "reg_for_control"
|
|
#define DUER_REPORT_PATH "v1/device/data"
|
|
|
|
#define DUER_RPT_QUERY_UUID "deviceUuid="
|
|
#define DUER_RPT_QUERY_TOKEN "token="
|
|
|
|
#define SR_TAG_UUID "deviceUUID"
|
|
#define SR_TAG_TOKEN "token"
|
|
#define SR_TAG_CUID "cuid"
|
|
#define SR_TAG_BDUSS "bduss"
|
|
#define SR_TAG_CLIENT_ID "clientId"
|
|
#define SR_TAG_USER_AGENT "userAgent"
|
|
|
|
#if defined(DUER_UDP_REPORTER)
|
|
#define SR_HOST "117.185.17.43"
|
|
#define SR_PORT 8899
|
|
#endif
|
|
|
|
#define DUER_READ_TIMEOUT (0)
|
|
|
|
#define DUER_RES_INC_COUNT (5)
|
|
|
|
typedef enum _baidu_ca_start_state_enum {
|
|
DUER_ST_STOPED,
|
|
DUER_ST_UNREGISTERED,
|
|
DUER_ST_REGISTER_CONNECTED,
|
|
DUER_ST_REGISTERED,
|
|
DUER_ST_SR_CONNECTING,
|
|
DUER_ST_SR_DATA_SENDING,
|
|
DUER_ST_SR_DATA_RECEIVING,
|
|
DUER_ST_SR_INITIALIZED,
|
|
DUER_ST_RPT_CONNECTED,
|
|
DUER_ST_RPT_INITIALIZED,
|
|
DUER_ST_STARTED,
|
|
DUER_ST_REPORTING,
|
|
DUER_ST_REPORTED,
|
|
DUER_ST_REGISTER_FAIL
|
|
} duer_state_e;
|
|
|
|
typedef struct _baidu_ca_s {
|
|
// Start state
|
|
volatile duer_u8_t state;
|
|
|
|
// register message id
|
|
#if defined(DUER_LWM2M_REGISTER)
|
|
duer_u16_t msg_id_reg;
|
|
duer_u16_t msg_id_unreg;
|
|
#endif
|
|
|
|
// Configuation
|
|
duer_conf_handler conf;
|
|
|
|
// mutex
|
|
duer_mutex_t mutex;
|
|
|
|
// Configuration
|
|
char *uuid;
|
|
char *token;
|
|
char *bindToken;
|
|
// If cuid is not null, deviceUuid will be binded to cuid on IoT cloud
|
|
char *cuid;
|
|
// If bduss is not null, auth by bduss on IoT cloud
|
|
char *bduss;
|
|
char *client_id;
|
|
char *user_agent;
|
|
char *serverAddr;
|
|
char *report_query;
|
|
duer_size_t report_query_len;
|
|
|
|
const char *cert;
|
|
duer_size_t cert_length;
|
|
|
|
// Token generator
|
|
duer_u16_t gen_token;
|
|
|
|
// Coap handler
|
|
#if defined(DUER_LWM2M_REGISTER)
|
|
duer_coap_handler reg;
|
|
#endif
|
|
duer_coap_handler sr;
|
|
#if defined(DUER_UDP_REPORTER)
|
|
duer_coap_handler rpt;
|
|
#endif
|
|
|
|
// Resource list
|
|
duer_res_t *res_list;
|
|
duer_u32_t res_size;
|
|
duer_u32_t res_capa;
|
|
|
|
// Response callback
|
|
duer_notify_f f_response;
|
|
duer_context ctx_response;
|
|
|
|
// Response callback
|
|
duer_transmit_f f_transmit;
|
|
|
|
// Socket context
|
|
duer_transevt_func ctx_socket;
|
|
|
|
// Remote address
|
|
#if defined(DUER_LWM2M_REGISTER)
|
|
duer_addr_t addr_reg;
|
|
#endif
|
|
duer_addr_t addr_sr;
|
|
#if defined(DUER_UDP_REPORTER)
|
|
duer_addr_t addr_rpt;
|
|
#endif
|
|
duer_u32_t start_connect_time;
|
|
} baidu_ca_t;
|
|
|
|
static volatile duer_u32_t s_max_connect_time_ms = 0;
|
|
static volatile duer_u32_t s_count_connect = 0;
|
|
static volatile duer_u32_t s_total_connect_time_ms = 0;
|
|
|
|
void baidu_ca_get_statistic(duer_u32_t *connect_avg_time,
|
|
duer_u32_t *max_connect_time,
|
|
duer_u32_t *count_connect)
|
|
{
|
|
*max_connect_time = s_max_connect_time_ms / 1000; // unit is ms
|
|
*count_connect = s_count_connect;
|
|
|
|
if (s_count_connect > 0) {
|
|
*connect_avg_time =
|
|
(s_total_connect_time_ms * 0.001) / s_count_connect; // unit is ms
|
|
} else {
|
|
*connect_avg_time = 0;
|
|
}
|
|
}
|
|
|
|
DUER_EXT_IMPL const char *baidu_ca_get_uuid(duer_handler hdlr)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
|
|
if (ctx) {
|
|
return (char *)ctx->uuid;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
DUER_EXT_IMPL const char *baidu_ca_get_client_id(duer_handler hdlr)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
|
|
if (ctx) {
|
|
return (char *)ctx->client_id;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
DUER_EXT_IMPL const char *baidu_ca_get_bduss(duer_handler hdlr)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
|
|
if (ctx) {
|
|
return (char *)ctx->bduss;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
DUER_EXT_IMPL const char *baidu_ca_get_user_agent(duer_handler hdlr)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
|
|
if (ctx) {
|
|
return (char *)ctx->user_agent;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
DUER_EXT_IMPL const char *baidu_ca_get_bind_token(duer_handler hdlr)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
|
|
if (ctx) {
|
|
return ctx->bindToken;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
DUER_EXT_IMPL const char *baidu_ca_get_rsa_cacrt(duer_handler hdlr)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
|
|
if (ctx) {
|
|
return ctx->cert;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
DUER_LOC_IMPL duer_status_t duer_engine_coap_handler(duer_context ctx,
|
|
duer_coap_handler coap,
|
|
const duer_msg_t *msg,
|
|
const duer_addr_t *addr)
|
|
{
|
|
duer_status_t rs = DUER_ERR_FAILED;
|
|
baidu_ca_t *ptr = (baidu_ca_t *)ctx;
|
|
|
|
if (ptr && msg && addr) {
|
|
rs = DUER_OK;
|
|
DUER_LOGV("==> duer_engine_coap_handler: state = %d", ptr->state);
|
|
#if defined(DUER_LWM2M_REGISTER)
|
|
if (ptr->reg == coap) {
|
|
if (ptr->state == DUER_ST_REGISTER_CONNECTED && ptr->msg_id_reg == msg->msg_id) {
|
|
ptr->msg_id_reg = 0;
|
|
|
|
if (msg->msg_code == DUER_MSG_RSP_CREATED) {
|
|
ptr->state = DUER_ST_REGISTERED;
|
|
}
|
|
} else if (ptr->state == DUER_ST_STOPED && ptr->msg_id_unreg == msg->msg_id) {
|
|
ptr->msg_id_unreg = 0;
|
|
}
|
|
} else
|
|
#endif
|
|
if (ptr->sr == coap) {
|
|
if (ptr->state == DUER_ST_SR_DATA_RECEIVING) {
|
|
if (msg->msg_code == DUER_MSG_RSP_CONTENT) {
|
|
DUER_LOGD("ca status: DUER_ST_SR_INITIALIZED");
|
|
ptr->state = DUER_ST_SR_INITIALIZED;
|
|
duer_ds_log_ca_start_state_change(DUER_ST_SR_DATA_RECEIVING, DUER_ST_SR_INITIALIZED);
|
|
// for debug
|
|
// char *payload = (char *)DUER_MALLOC(msg->payload_len + 1);
|
|
// DUER_MEMCPY(payload, msg->payload, msg->payload_len);
|
|
// payload[msg->payload_len] = '\0';
|
|
// DUER_LOGI("register ack payload: %s", payload);
|
|
// DUER_LOGI("register ack msg_id: %d", msg->msg_id);
|
|
} else {
|
|
ptr->state = DUER_ST_REGISTER_FAIL;
|
|
duer_ds_log_ca_start_state_change(DUER_ST_SR_DATA_RECEIVING, DUER_ST_REGISTER_FAIL);
|
|
DUER_LOGE("register fail, code: %d", msg->msg_code);
|
|
duer_ds_log_ca_cache_error(DUER_DS_LOG_CA_START_STATE_REG_FAIL);
|
|
}
|
|
}
|
|
if (ptr->f_response) {
|
|
ptr->f_response(ptr->ctx_response, (duer_msg_t *)msg, NULL);
|
|
}
|
|
}
|
|
#if defined(DUER_UDP_REPORTER)
|
|
else if (ptr->rpt == coap) {
|
|
if (ptr->f_response) {
|
|
ptr->f_response(ptr->ctx_response, (duer_msg_t *)msg, NULL);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
DUER_LOGV("<== duer_engine_coap_handler: rs = %d", rs);
|
|
}
|
|
|
|
return rs;
|
|
}
|
|
|
|
#if defined(DUER_UDP_REPORTER) || defined(DUER_LWM2M_REGISTER)
|
|
DUER_LOC_IMPL duer_bool baidu_ca_match_address(const duer_addr_t *l,
|
|
const duer_addr_t *r)
|
|
{
|
|
if (l) {
|
|
DUER_LOGV("baidu_ca_match_address: l = {ip:%s, port:%d, type:%d, length:%d}",
|
|
l->host, l->port, l->type, l->host_size);
|
|
}
|
|
|
|
if (r) {
|
|
DUER_LOGV("baidu_ca_match_address: r = {ip:%s, port:%d, type:%d, length:%d}",
|
|
r->host, r->port, r->type, r->host_size);
|
|
}
|
|
|
|
if (l == r || (l && r && l->port == r->port && l->type == r->type
|
|
&& l->host_size == r->host_size
|
|
&& DUER_MEMCMP(r->host, l->host, r->host_size) == 0)) {
|
|
return DUER_TRUE;
|
|
}
|
|
|
|
return DUER_FALSE;
|
|
}
|
|
#endif
|
|
|
|
#if defined(DUER_LWM2M_REGISTER)
|
|
DUER_LOC_IMPL duer_status_t baidu_ca_register(baidu_ca_t *ctx)
|
|
{
|
|
duer_status_t rs = DUER_ERR_FAILED;
|
|
duer_coap_ep_t ep;
|
|
DUER_LOGV("==> baidu_ca_register");
|
|
|
|
if (!ctx) {
|
|
goto exit;
|
|
}
|
|
|
|
if (!ctx->reg) {
|
|
if (!(ctx->reg = duer_coap_acquire(duer_engine_coap_handler, ctx,
|
|
ctx->ctx_socket, ctx->uuid))) {
|
|
goto exit;
|
|
}
|
|
duer_coap_set_tx_callback(ctx->reg, ctx->f_transmit);
|
|
}
|
|
|
|
if (ctx->state == DUER_ST_UNREGISTERED) {
|
|
rs = duer_coap_connect(ctx->reg, &ctx->addr_reg, ctx->cert, ctx->cert_length);
|
|
|
|
if (rs == DUER_OK) {
|
|
ctx->state = DUER_ST_REGISTER_CONNECTED;
|
|
}
|
|
}
|
|
|
|
if (ctx->state != DUER_ST_REGISTER_CONNECTED) {
|
|
goto exit;
|
|
}
|
|
|
|
// Send register message
|
|
if (ctx->msg_id_reg == 0) {
|
|
DUER_MEMSET(&ep, 0, sizeof(ep));
|
|
ep.name_ptr = (char *)ctx->uuid;
|
|
ep.name_len = DUER_STRLEN(ctx->uuid);
|
|
ep.type_ptr = (char *)ctx->token;
|
|
ep.type_len = DUER_STRLEN(ctx->token);
|
|
ep.lifetime_ptr = DUER_COAP_LIFETIME;
|
|
ep.lifetime_len = DUER_STRLEN(DUER_COAP_LIFETIME);
|
|
rs = duer_coap_register(ctx->reg, &ep);
|
|
|
|
if (rs == 0) {
|
|
rs = DUER_ERR_FAILED;
|
|
}
|
|
|
|
if (rs > 0) {
|
|
ctx->msg_id_reg = (duer_u16_t)rs;
|
|
} else {
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
rs = duer_coap_data_available(ctx->reg);
|
|
exit:
|
|
DUER_LOGV("<== baidu_ca_register: rs = %d", rs);
|
|
return rs;
|
|
}
|
|
#endif
|
|
|
|
DUER_LOC_IMPL char *baidu_ca_get_service_router_payload(
|
|
const char *uuid, const char *token, const char *cuid,
|
|
const char *bduss, const char *client_id, const char *user_agent)
|
|
{
|
|
char *rs = NULL;
|
|
baidu_json *item = baidu_json_CreateObject();
|
|
|
|
if (item) {
|
|
baidu_json_AddStringToObject(item, SR_TAG_UUID, uuid);
|
|
baidu_json_AddStringToObject(item, SR_TAG_TOKEN, token);
|
|
if (cuid != NULL) {
|
|
baidu_json_AddStringToObject(item, SR_TAG_CUID, cuid);
|
|
}
|
|
if (bduss != NULL) {
|
|
baidu_json_AddStringToObject(item, SR_TAG_BDUSS, bduss);
|
|
}
|
|
if (client_id != NULL) {
|
|
baidu_json_AddStringToObject(item, SR_TAG_CLIENT_ID, client_id);
|
|
}
|
|
if (user_agent != NULL) {
|
|
baidu_json_AddStringToObject(item, SR_TAG_USER_AGENT, user_agent);
|
|
}
|
|
rs = baidu_json_PrintUnformatted(item);
|
|
baidu_json_Delete(item);
|
|
}
|
|
|
|
return rs;
|
|
}
|
|
|
|
DUER_LOC_IMPL duer_status_t baidu_ca_create_service_router(baidu_ca_t *ctx)
|
|
{
|
|
duer_status_t rs = DUER_ERR_FAILED;
|
|
duer_msg_t msg_reg;
|
|
DUER_LOGV("==> baidu_ca_create_service_router");
|
|
|
|
if (!ctx) {
|
|
goto exit;
|
|
}
|
|
|
|
if (!ctx->sr) {
|
|
ctx->sr = duer_coap_acquire(duer_engine_coap_handler, ctx, ctx->ctx_socket, ctx->uuid);
|
|
if (!ctx->sr) {
|
|
goto exit;
|
|
}
|
|
duer_coap_set_tx_callback(ctx->sr, ctx->f_transmit);
|
|
}
|
|
|
|
if (ctx->state == DUER_ST_SR_CONNECTING) {
|
|
//record the start connect time
|
|
if (ctx->start_connect_time == 0) {
|
|
ctx->start_connect_time = duer_timestamp();
|
|
}
|
|
duer_ds_log_ca_start_connect(ctx->addr_sr.host, ctx->addr_sr.port);
|
|
#ifndef NET_TRANS_ENCRYPTED_BY_AES_CBC
|
|
rs = duer_coap_connect(ctx->sr, &ctx->addr_sr, ctx->cert, ctx->cert_length);
|
|
#else
|
|
// bindToken is the key for AES encryption
|
|
rs = duer_coap_connect(ctx->sr, &ctx->addr_sr, ctx->bindToken, DUER_STRLEN(ctx->bindToken));
|
|
#endif // NET_TRANS_ENCRYPTED_BY_AES_CBC
|
|
|
|
// baidu_ca_unload_configuration(ctx); //release the bjson format of the profile to save memory
|
|
|
|
DUER_LOGD("ca state: DUER_ST_SR_CONNECTING, rs:%d", rs);
|
|
if (rs == DUER_OK) {
|
|
ctx->state = DUER_ST_SR_DATA_SENDING;
|
|
//after success connect, calculate the connect time
|
|
int time_end = duer_timestamp();
|
|
int time_cost = time_end - ctx->start_connect_time;
|
|
|
|
if (time_cost > s_max_connect_time_ms) {
|
|
s_max_connect_time_ms = time_cost;
|
|
}
|
|
|
|
++s_count_connect;
|
|
s_total_connect_time_ms += time_cost;
|
|
ctx->start_connect_time = 0;
|
|
}
|
|
}
|
|
|
|
if (ctx->state == DUER_ST_SR_DATA_SENDING) {
|
|
DUER_MEMSET(&msg_reg, 0, sizeof(msg_reg));
|
|
msg_reg.msg_type = DUER_MSG_TYPE_CONFIRMABLE;
|
|
msg_reg.msg_code = DUER_MSG_REQ_POST;
|
|
msg_reg.path = (duer_u8_t *)DUER_SR_REG_PATH;
|
|
msg_reg.path_len = DUER_STRLEN(DUER_SR_REG_PATH);
|
|
msg_reg.payload = (duer_u8_t *)baidu_ca_get_service_router_payload(
|
|
ctx->uuid, ctx->token, ctx->cuid, ctx->bduss, ctx->client_id, ctx->user_agent);
|
|
msg_reg.payload_len = DUER_STRLEN((char *)msg_reg.payload);
|
|
rs = duer_coap_send(ctx->sr, &msg_reg);
|
|
baidu_json_release(msg_reg.payload);
|
|
DUER_LOGD("ca state: DUER_ST_SR_DATA_SENDING, rs:%d", rs);
|
|
|
|
if (rs < DUER_OK) {
|
|
goto exit;
|
|
}
|
|
ctx->state = DUER_ST_SR_DATA_RECEIVING;
|
|
duer_ds_log_ca_start_state_change(DUER_ST_SR_DATA_SENDING, DUER_ST_SR_DATA_RECEIVING);
|
|
}
|
|
|
|
if (ctx->state == DUER_ST_SR_DATA_RECEIVING) {
|
|
rs = duer_coap_data_available(ctx->sr);
|
|
DUER_LOGD("ca state: DUER_ST_SR_DATA_RECEIVING, rs:%d", rs);
|
|
if (rs < DUER_OK) {
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
if (ctx->state == DUER_ST_SR_INITIALIZED) {
|
|
DUER_LOGD("ca state: DUER_ST_SR_INITIALIZED");
|
|
baidu_ca_add_resources(ctx, ctx->res_list, ctx->res_size);
|
|
if (ctx->res_list) {
|
|
DUER_FREE(ctx->res_list);
|
|
ctx->res_list = NULL;
|
|
ctx->res_size = 0;
|
|
ctx->res_capa = 0;
|
|
}
|
|
}
|
|
|
|
if (ctx->state == DUER_ST_REGISTER_FAIL) {
|
|
rs = DUER_ERR_REG_FAIL;
|
|
}
|
|
|
|
exit:
|
|
DUER_LOGV("<== baidu_ca_create_service_router: rs = %d", rs);
|
|
return rs;
|
|
}
|
|
|
|
#if defined(DUER_UDP_REPORTER)
|
|
DUER_LOC_IMPL duer_status_t baidu_ca_create_reporter(baidu_ca_t *ctx)
|
|
{
|
|
duer_status_t rs = DUER_ERR_FAILED;
|
|
DUER_LOGV("==> baidu_ca_create_reporter");
|
|
|
|
if (!ctx) {
|
|
goto exit;
|
|
}
|
|
|
|
if (!ctx->rpt) {
|
|
ctx->rpt = duer_coap_acquire(duer_engine_coap_handler, ctx, ctx->ctx_socket, ctx->uuid);
|
|
if (!ctx->rpt) {
|
|
goto exit;
|
|
}
|
|
duer_coap_set_tx_callback(ctx->rpt, ctx->f_transmit);
|
|
}
|
|
|
|
if (ctx->state == DUER_ST_SR_INITIALIZED) {
|
|
rs = duer_coap_connect(ctx->rpt, &ctx->addr_rpt, ctx->cert, ctx->cert_length);
|
|
|
|
if (rs == DUER_OK) {
|
|
ctx->state = DUER_ST_RPT_CONNECTED;
|
|
}
|
|
}
|
|
|
|
if (ctx->state == DUER_ST_RPT_CONNECTED) {
|
|
#if defined(DUER_READ_TIMEOUT) && (DUER_READ_TIMEOUT > 0)
|
|
duer_coap_set_read_timeout(ctx->rpt, DUER_READ_TIMEOUT);
|
|
#endif
|
|
ctx->state = DUER_ST_RPT_INITIALIZED;
|
|
rs = DUER_OK;
|
|
}
|
|
|
|
exit:
|
|
DUER_LOGV("<== baidu_ca_create_reporter: rs = %d", rs);
|
|
return rs;
|
|
}
|
|
#endif
|
|
|
|
DUER_LOC_IMPL duer_status_t baidu_ca_run(baidu_ca_t *ctx)
|
|
{
|
|
duer_status_t rs = DUER_ERR_FAILED;
|
|
|
|
if (!ctx) {
|
|
goto exit;
|
|
}
|
|
|
|
DUER_LOGV("==> baidu_ca_run: ctx = %p, state = %d", ctx, ctx->state);
|
|
|
|
switch (ctx->state) {
|
|
case DUER_ST_UNREGISTERED:
|
|
DUER_LOGD("ca status: %d", ctx->state);
|
|
ctx->state = DUER_ST_REGISTER_CONNECTED;
|
|
rs = DUER_OK;
|
|
break;
|
|
case DUER_ST_REGISTER_CONNECTED:
|
|
#if defined(DUER_LWM2M_REGISTER)
|
|
rs = baidu_ca_register(ctx);
|
|
break;
|
|
#else
|
|
DUER_LOGD("ca status: %d", ctx->state);
|
|
ctx->state = DUER_ST_REGISTERED;
|
|
rs = DUER_OK;
|
|
break;
|
|
#endif
|
|
|
|
case DUER_ST_REGISTERED:
|
|
DUER_LOGD("ca status: %d", ctx->state);
|
|
ctx->state = DUER_ST_SR_CONNECTING;
|
|
rs = DUER_OK;
|
|
break;
|
|
|
|
case DUER_ST_SR_CONNECTING:
|
|
case DUER_ST_SR_DATA_SENDING:
|
|
case DUER_ST_SR_DATA_RECEIVING:
|
|
DUER_LOGD("ca status: %d", ctx->state);
|
|
rs = baidu_ca_create_service_router(ctx);
|
|
break;
|
|
|
|
case DUER_ST_SR_INITIALIZED:
|
|
#if defined(DUER_UDP_REPORTER)
|
|
rs = baidu_ca_create_reporter(ctx);
|
|
break;
|
|
#endif
|
|
|
|
case DUER_ST_RPT_INITIALIZED:
|
|
DUER_LOGD("ca status: DUER_ST_RPT_INITIALIZED -> DUER_ST_STARTED");
|
|
ctx->state = DUER_ST_STARTED;
|
|
duer_ds_log_ca_start_state_change(DUER_ST_RPT_INITIALIZED, DUER_ST_STARTED);
|
|
rs = DUER_OK;
|
|
break;
|
|
case DUER_ST_STOPED:
|
|
rs = DUER_ERR_FAILED;
|
|
break;
|
|
case DUER_ST_STARTED:
|
|
rs = DUER_OK;
|
|
break;
|
|
|
|
default:
|
|
// do noting
|
|
break;
|
|
}
|
|
|
|
DUER_LOGV("<== baidu_ca_run: rs = %d", rs);
|
|
exit:
|
|
return rs;
|
|
}
|
|
|
|
DUER_EXT_IMPL duer_handler baidu_ca_acquire(duer_transevt_func soc_ctx)
|
|
{
|
|
baidu_ca_t *hdlr = NULL;
|
|
DUER_LOGV("==> baidu_ca_acquire");
|
|
DUER_MEMDBG_USAGE();
|
|
hdlr = DUER_MALLOC(sizeof(baidu_ca_t));
|
|
|
|
if (!hdlr) {
|
|
DUER_LOGE("alloc failed...");
|
|
DUER_DS_LOG_CA_MEMORY_OVERFLOW();
|
|
baidu_ca_release(hdlr);
|
|
return NULL;
|
|
}
|
|
|
|
duer_coap_trace_enable();
|
|
DUER_MEMSET(hdlr, 0, sizeof(baidu_ca_t));
|
|
|
|
hdlr->state = DUER_ST_STOPED;
|
|
hdlr->mutex = duer_mutex_create();
|
|
hdlr->gen_token = 0xC000;
|
|
hdlr->ctx_socket = soc_ctx;
|
|
|
|
DUER_LOGV("<== baidu_ca_acquire: hdlr = %p", hdlr);
|
|
return hdlr;
|
|
}
|
|
|
|
DUER_EXT duer_status_t baidu_ca_add_resources(duer_handler hdlr,
|
|
const duer_res_t list_res[], duer_size_t list_res_size)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
duer_status_t rs = DUER_ERR_FAILED;
|
|
|
|
if (ctx->state >= DUER_ST_SR_INITIALIZED) {
|
|
duer_u8_t i = 0;
|
|
|
|
while (i < list_res_size) {
|
|
duer_coap_resource_add(ctx->sr, list_res + i);
|
|
i++;
|
|
}
|
|
|
|
rs = DUER_OK;
|
|
goto exit;
|
|
}
|
|
//Note: if exccute here, the path/static data should be something with long-time life
|
|
// e.g. static chars; or try to add resource after the CA started.
|
|
DUER_LOGW("add_resource at CA not started, all the content(static_data, path)should be static!");
|
|
if (ctx->res_list == NULL) {
|
|
ctx->res_capa = (list_res_size / DUER_RES_INC_COUNT + 1) * DUER_RES_INC_COUNT;
|
|
ctx->res_list = DUER_MALLOC(sizeof(duer_res_t) * ctx->res_capa);
|
|
ctx->res_size = 0;
|
|
} else if (ctx->res_capa < ctx->res_size + list_res_size) {
|
|
ctx->res_capa =
|
|
((ctx->res_size + list_res_size) / DUER_RES_INC_COUNT + 1) * DUER_RES_INC_COUNT;
|
|
ctx->res_list = (duer_res_t *)DUER_REALLOC(ctx->res_list,
|
|
sizeof(duer_res_t) * ctx->res_capa);
|
|
}
|
|
|
|
if (ctx->res_list == NULL) {
|
|
DUER_LOGE(" stored the resource failed...");
|
|
DUER_DS_LOG_CA_MEMORY_OVERFLOW();
|
|
goto exit;
|
|
}
|
|
|
|
DUER_MEMCPY(ctx->res_list + ctx->res_size, list_res,
|
|
sizeof(duer_res_t) * list_res_size);
|
|
ctx->res_size += list_res_size;
|
|
rs = DUER_OK;
|
|
exit:
|
|
return rs;
|
|
}
|
|
|
|
duer_status_t baidu_ca_unload_configuration(duer_handler hdlr)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
ctx->cert = NULL;
|
|
ctx->cert_length = 0;
|
|
|
|
if (ctx->conf) {
|
|
duer_conf_destroy(ctx->conf);
|
|
ctx->conf = NULL;
|
|
}
|
|
return DUER_OK;
|
|
}
|
|
|
|
DUER_EXT_IMPL duer_status_t baidu_ca_load_configuration(duer_handler hdlr, const void *data, duer_size_t size)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
duer_status_t rs = DUER_ERR_FAILED;
|
|
const char *string_addr = NULL;
|
|
|
|
if (!ctx) {
|
|
DUER_LOGE("invalid handler with null");
|
|
goto error;
|
|
}
|
|
|
|
if (ctx->conf) {
|
|
duer_conf_destroy(ctx->conf);
|
|
ctx->conf = NULL;
|
|
}
|
|
|
|
ctx->conf = duer_conf_create(data, size);
|
|
if (!ctx->conf) {
|
|
DUER_LOGE(" create the configuation failed...");
|
|
goto error;
|
|
}
|
|
|
|
string_addr = duer_conf_get_string(ctx->conf, DUER_CONF_KEY_UUID);
|
|
if (ctx->uuid) {
|
|
DUER_FREE(ctx->uuid);
|
|
ctx->uuid = NULL;
|
|
}
|
|
if (string_addr) {
|
|
ctx->uuid = DUER_MALLOC(DUER_STRLEN(string_addr) + 1);
|
|
}
|
|
if (!string_addr || !ctx->uuid) {
|
|
DUER_LOGE(" obtain the uuid failed...");
|
|
goto error;
|
|
} else {
|
|
DUER_MEMCPY(ctx->uuid, string_addr, DUER_STRLEN(string_addr) + 1);
|
|
}
|
|
|
|
string_addr = duer_conf_get_string(ctx->conf, DUER_CONF_KEY_TOKEN);
|
|
if (ctx->token) {
|
|
DUER_FREE(ctx->token);
|
|
ctx->token = NULL;
|
|
}
|
|
if (string_addr) {
|
|
ctx->token = DUER_MALLOC(DUER_STRLEN(string_addr) + 1);
|
|
}
|
|
if (!string_addr || !ctx->token) {
|
|
DUER_LOGE(" obtain the token failed...");
|
|
goto error;
|
|
} else {
|
|
DUER_MEMCPY(ctx->token, string_addr, DUER_STRLEN(string_addr) + 1);
|
|
}
|
|
|
|
string_addr = duer_conf_get_string(ctx->conf, DUER_CONF_KEY_BINDTOKEN);
|
|
if (ctx->bindToken) {
|
|
DUER_FREE(ctx->bindToken);
|
|
ctx->bindToken = NULL;
|
|
}
|
|
if (string_addr) {
|
|
ctx->bindToken = DUER_MALLOC(DUER_STRLEN(string_addr) + 1);
|
|
}
|
|
if (!string_addr || !ctx->bindToken) {
|
|
// DUER_LOGE(" obtain the bindToken failed...");
|
|
// goto error;
|
|
} else {
|
|
DUER_MEMCPY(ctx->bindToken, string_addr, DUER_STRLEN(string_addr) + 1);
|
|
}
|
|
|
|
ctx->cert = duer_conf_get_string(ctx->conf, DUER_CONF_KEY_CERT);
|
|
if (!ctx->cert) {
|
|
DUER_LOGE(" obtain the cert failed...");
|
|
goto error;
|
|
}
|
|
ctx->cert_length = DUER_STRLEN(ctx->cert) + 1;
|
|
|
|
|
|
string_addr = duer_conf_get_string(ctx->conf, DUER_CONF_KEY_HOST);
|
|
if (ctx->serverAddr) {
|
|
DUER_FREE(ctx->serverAddr);
|
|
ctx->serverAddr = NULL;
|
|
}
|
|
if (string_addr) {
|
|
ctx->serverAddr = DUER_MALLOC(DUER_STRLEN(string_addr) + 1);
|
|
}
|
|
if (!string_addr || !ctx->serverAddr) {
|
|
DUER_LOGE(" obtain the hostname failed...");
|
|
goto error;
|
|
} else {
|
|
DUER_MEMCPY(ctx->serverAddr, string_addr, DUER_STRLEN(string_addr) + 1);
|
|
}
|
|
|
|
// cuid may be not exist
|
|
string_addr = (char *)duer_conf_get_string(ctx->conf, DUER_CONF_KEY_CUID);
|
|
if (ctx->cuid) {
|
|
DUER_FREE(ctx->cuid);
|
|
ctx->cuid = NULL;
|
|
}
|
|
if (string_addr) {
|
|
ctx->cuid = DUER_MALLOC(DUER_STRLEN(string_addr) + 1);
|
|
}
|
|
if (string_addr && !ctx->cuid) {
|
|
DUER_LOGE(" malloc the cuid failed...");
|
|
goto error;
|
|
} else {
|
|
if (ctx->cuid) {
|
|
DUER_MEMCPY(ctx->cuid, string_addr, DUER_STRLEN(string_addr) + 1);
|
|
DUER_LOGI("profile include cuid:%s", ctx->cuid);
|
|
}
|
|
}
|
|
|
|
// bduss may be not exist
|
|
string_addr = (char *)duer_conf_get_string(ctx->conf, DUER_CONF_KEY_BDUSS);
|
|
if (ctx->bduss) {
|
|
DUER_FREE(ctx->bduss);
|
|
ctx->bduss = NULL;
|
|
}
|
|
if (string_addr) {
|
|
ctx->bduss = DUER_MALLOC(DUER_STRLEN(string_addr) + 1);
|
|
}
|
|
if (string_addr && !ctx->bduss) {
|
|
DUER_LOGE(" malloc the bduss failed...");
|
|
goto error;
|
|
} else {
|
|
if (ctx->bduss) {
|
|
DUER_MEMCPY(ctx->bduss, string_addr, DUER_STRLEN(string_addr) + 1);
|
|
DUER_LOGI("profile include bduss:%s", ctx->bduss);
|
|
}
|
|
}
|
|
|
|
// client_id may be not exist
|
|
string_addr = (char *)duer_conf_get_string(ctx->conf, DUER_CONF_KEY_CLIENT_ID);
|
|
if (ctx->client_id) {
|
|
DUER_FREE(ctx->client_id);
|
|
ctx->client_id = NULL;
|
|
}
|
|
if (string_addr) {
|
|
ctx->client_id = DUER_MALLOC(DUER_STRLEN(string_addr) + 1);
|
|
}
|
|
if (string_addr && !ctx->client_id) {
|
|
DUER_LOGE(" malloc the client_id failed...");
|
|
goto error;
|
|
} else {
|
|
if (ctx->client_id) {
|
|
DUER_MEMCPY(ctx->client_id, string_addr, DUER_STRLEN(string_addr) + 1);
|
|
DUER_LOGI("profile include client_id:%s", ctx->client_id);
|
|
}
|
|
}
|
|
|
|
// user_agent may be not exist
|
|
string_addr = (char *)duer_conf_get_string(ctx->conf, DUER_CONF_KEY_USER_AGENT);
|
|
if (ctx->user_agent) {
|
|
DUER_FREE(ctx->user_agent);
|
|
ctx->user_agent = NULL;
|
|
}
|
|
if (string_addr) {
|
|
ctx->user_agent = DUER_MALLOC(DUER_STRLEN(string_addr) + 1);
|
|
}
|
|
if (string_addr && !ctx->user_agent) {
|
|
DUER_LOGE(" malloc the user_agent failed...");
|
|
goto error;
|
|
} else {
|
|
if (ctx->user_agent) {
|
|
DUER_MEMCPY(ctx->user_agent, string_addr, DUER_STRLEN(string_addr) + 1);
|
|
DUER_LOGI("profile include user_agent:%s", ctx->user_agent);
|
|
}
|
|
}
|
|
|
|
#if defined(DUER_LWM2M_REGISTER)
|
|
ctx->addr_reg.host = ctx->serverAddr;
|
|
ctx->addr_reg.host_size = DUER_STRLEN(ctx->serverAddr);
|
|
ctx->addr_reg.port = duer_conf_get_ushort(ctx->conf, DUER_CONF_KEY_PORT_REG);
|
|
ctx->addr_reg.type = DUER_PROTO_UDP;
|
|
#endif
|
|
|
|
#if defined(DUER_UDP_REPORTER)
|
|
ctx->addr_sr.host = SR_HOST;
|
|
ctx->addr_sr.host_size = DUER_STRLEN(SR_HOST);
|
|
ctx->addr_sr.port = SR_PORT;
|
|
#else
|
|
ctx->addr_sr.host = ctx->serverAddr;
|
|
ctx->addr_sr.host_size = DUER_STRLEN(ctx->serverAddr);
|
|
ctx->addr_sr.port = duer_conf_get_ushort(ctx->conf, DUER_CONF_KEY_PORT_RPT);
|
|
#endif
|
|
ctx->addr_sr.type = DUER_PROTO_TCP;
|
|
|
|
#if defined(DUER_UDP_REPORTER)
|
|
ctx->addr_rpt.host = ctx->serverAddr;
|
|
ctx->addr_rpt.host_size = DUER_STRLEN(ctx->serverAddr);
|
|
ctx->addr_rpt.port = duer_conf_get_ushort(ctx->conf, DUER_CONF_KEY_PORT_RPT);
|
|
ctx->addr_rpt.type = DUER_PROTO_UDP;
|
|
#endif
|
|
|
|
if (ctx->report_query) {
|
|
DUER_FREE(ctx->report_query);
|
|
ctx->report_query = NULL;
|
|
}
|
|
|
|
ctx->report_query_len = DUER_STRLEN(DUER_RPT_QUERY_UUID)
|
|
+ DUER_STRLEN(ctx->uuid)
|
|
+ 1 // '&'
|
|
+ DUER_STRLEN(DUER_RPT_QUERY_TOKEN)
|
|
+ DUER_STRLEN(ctx->token);
|
|
ctx->report_query = DUER_MALLOC(ctx->report_query_len + 1);
|
|
if (!ctx->report_query) {
|
|
DUER_DS_LOG_CA_MEMORY_OVERFLOW();
|
|
goto error;
|
|
}
|
|
DUER_SNPRINTF(
|
|
ctx->report_query,
|
|
ctx->report_query_len + 1,
|
|
DUER_RPT_QUERY_UUID"%s&"DUER_RPT_QUERY_TOKEN"%s",
|
|
ctx->uuid,
|
|
ctx->token);
|
|
|
|
rs = DUER_OK;
|
|
|
|
error:
|
|
|
|
return rs;
|
|
}
|
|
|
|
DUER_EXT_IMPL duer_status_t baidu_ca_do_start(duer_handler hdlr)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
duer_status_t rs = DUER_ERR_FAILED;
|
|
DUER_LOGV("==> baidu_ca_do_start");
|
|
|
|
if (!ctx) {
|
|
goto exit;
|
|
}
|
|
|
|
duer_mutex_lock(ctx->mutex);
|
|
rs = DUER_OK;
|
|
|
|
while (ctx->state != DUER_ST_STARTED && rs == DUER_OK) {
|
|
DUER_LOGD("ca status: %d", ctx->state);
|
|
rs = baidu_ca_run(ctx);
|
|
}
|
|
|
|
duer_mutex_unlock(ctx->mutex);
|
|
exit:
|
|
DUER_LOGV("<== baidu_ca_do_start: rs = %d", rs);
|
|
return rs;
|
|
}
|
|
|
|
DUER_EXT_IMPL duer_status_t baidu_ca_start(duer_handler hdlr)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
duer_status_t rs = DUER_ERR_FAILED;
|
|
DUER_LOGV("==> baidu_ca_start");
|
|
|
|
if (!ctx) {
|
|
goto exit;
|
|
}
|
|
|
|
if (ctx->state == DUER_ST_STOPED) {
|
|
DUER_LOGD("ca status: DUER_ST_STOPED -> DUER_ST_UNREGISTERED");
|
|
ctx->state = DUER_ST_UNREGISTERED;
|
|
}
|
|
|
|
if (ctx->state == DUER_ST_REGISTER_FAIL) {
|
|
rs = DUER_ERR_REG_FAIL;
|
|
} else {
|
|
rs = baidu_ca_do_start(hdlr);
|
|
}
|
|
|
|
exit:
|
|
DUER_LOGV("<== baidu_ca_start: rs = %d", rs);
|
|
return rs;
|
|
}
|
|
|
|
DUER_EXT_IMPL duer_bool baidu_ca_is_started(duer_handler hdlr)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
return (ctx != NULL && ctx->state == DUER_ST_STARTED) ? DUER_TRUE : DUER_FALSE;
|
|
}
|
|
|
|
DUER_EXT_IMPL duer_bool baidu_ca_is_stopped(duer_handler hdlr)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
return (ctx == NULL || ctx->state == DUER_ST_STOPED) ? DUER_TRUE : DUER_FALSE;
|
|
}
|
|
|
|
DUER_EXT_IMPL duer_status_t baidu_ca_report_set_response_callback(
|
|
duer_handler hdlr, duer_notify_f f_response, duer_context context)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
|
|
if (ctx) {
|
|
ctx->f_response = f_response;
|
|
ctx->ctx_response = context;
|
|
return DUER_OK;
|
|
}
|
|
|
|
return DUER_ERR_FAILED;
|
|
}
|
|
|
|
DUER_EXT duer_status_t baidu_ca_report_set_data_tx_callback(duer_handler hdlr, duer_transmit_f f_transmit)
|
|
{
|
|
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
|
|
if (ctx) {
|
|
ctx->f_transmit = f_transmit;
|
|
return DUER_OK;
|
|
}
|
|
|
|
return DUER_ERR_FAILED;
|
|
}
|
|
|
|
static duer_msg_t *baidu_ca_build_coap_message()
|
|
{
|
|
duer_msg_t *msg = DUER_MALLOC(sizeof(duer_msg_t)); // ~= 36
|
|
|
|
if (msg) {
|
|
DUER_MEMSET(msg, 0, sizeof(duer_msg_t));
|
|
|
|
msg->create_timestamp = duer_timestamp();
|
|
}
|
|
return msg;
|
|
}
|
|
|
|
DUER_EXT duer_msg_t *baidu_ca_build_report_message(duer_handler hdlr,
|
|
duer_bool confirmable)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
duer_msg_t *msg = NULL;
|
|
|
|
do {
|
|
if (!ctx) {
|
|
break;
|
|
}
|
|
msg = baidu_ca_build_coap_message();
|
|
|
|
if (!msg) {
|
|
DUER_DS_LOG_CA_MEMORY_OVERFLOW();
|
|
break;
|
|
}
|
|
|
|
msg->msg_type =
|
|
confirmable == DUER_FALSE ? DUER_MSG_TYPE_NON_CONFIRMABLE : DUER_MSG_TYPE_CONFIRMABLE;
|
|
msg->msg_code = DUER_MSG_REQ_POST;
|
|
msg->path = (duer_u8_t *)DUER_REPORT_PATH;
|
|
msg->path_len = DUER_STRLEN(DUER_REPORT_PATH);
|
|
msg->query = (duer_u8_t *)ctx->report_query;
|
|
msg->query_len = ctx->report_query_len;
|
|
|
|
msg->token_len = sizeof(ctx->gen_token);
|
|
msg->token = DUER_MALLOC(msg->token_len);
|
|
|
|
if (msg->token) {
|
|
DUER_MEMCPY(msg->token, &ctx->gen_token, msg->token_len);
|
|
} else {
|
|
DUER_DS_LOG_CA_MEMORY_OVERFLOW();
|
|
}
|
|
|
|
ctx->gen_token++;
|
|
|
|
} while (0);
|
|
|
|
return msg;
|
|
}
|
|
|
|
DUER_EXT duer_msg_t *baidu_ca_build_response_message(duer_handler hdlr,
|
|
const duer_msg_t *msg, duer_u8_t msg_code)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
duer_msg_t *rs = NULL;
|
|
const char *token = NULL;
|
|
|
|
do {
|
|
if (!ctx || !msg) {
|
|
DUER_LOGE("paramter error: ctx = %p, msg = %p", ctx, msg);
|
|
break;
|
|
}
|
|
|
|
if (msg_code != DUER_MSG_EMPTY_MESSAGE) { // empty message don't need token
|
|
if (msg->token_len > 0 && msg->token) {
|
|
token = DUER_MALLOC(msg->token_len);
|
|
if (!token) {
|
|
DUER_DS_LOG_CA_MEMORY_OVERFLOW();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
rs = baidu_ca_build_coap_message();
|
|
if (!rs) {
|
|
DUER_DS_LOG_CA_MEMORY_OVERFLOW();
|
|
break;
|
|
}
|
|
|
|
if (msg->msg_type == DUER_MSG_TYPE_CONFIRMABLE) {
|
|
rs->msg_type = DUER_MSG_TYPE_ACKNOWLEDGEMENT;
|
|
rs->msg_id = msg->msg_id;
|
|
} else {
|
|
rs->msg_type = msg->msg_type;
|
|
}
|
|
|
|
// DUER_MSG_RSP_INVALID means a seperate response
|
|
if (msg_code != DUER_MSG_RSP_INVALID) {
|
|
rs->msg_code = msg_code;
|
|
|
|
if (token) {
|
|
rs->token_len = msg->token_len;
|
|
rs->token = (duer_u8_t *)token;
|
|
|
|
DUER_MEMCPY(rs->token, msg->token, rs->token_len);
|
|
}
|
|
}
|
|
|
|
} while (0);
|
|
|
|
if (!rs) {
|
|
if (token) {
|
|
DUER_FREE((char *)token);
|
|
token = NULL;
|
|
}
|
|
}
|
|
|
|
return rs;
|
|
}
|
|
|
|
DUER_EXT duer_msg_t *baidu_ca_build_seperate_response_message(duer_handler hdlr,
|
|
const char *ptoken,
|
|
duer_size_t token_len,
|
|
int msg_code,
|
|
duer_bool confirmable)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
duer_msg_t *rs = NULL;
|
|
const char *token = NULL;
|
|
|
|
do {
|
|
if (!ctx) {
|
|
DUER_LOGE("paramter error: ctx = %p", ctx);
|
|
break;
|
|
}
|
|
|
|
if (token_len > 0 && ptoken) {
|
|
token = DUER_MALLOC(token_len);
|
|
if (!token) {
|
|
DUER_DS_LOG_CA_MEMORY_OVERFLOW();
|
|
break;
|
|
}
|
|
} else {
|
|
DUER_LOGI("token should not be null!!");
|
|
break;
|
|
}
|
|
|
|
rs = baidu_ca_build_coap_message();
|
|
if (!rs) {
|
|
DUER_DS_LOG_CA_MEMORY_OVERFLOW();
|
|
break;
|
|
}
|
|
|
|
rs->msg_type =
|
|
confirmable == DUER_FALSE ? DUER_MSG_TYPE_NON_CONFIRMABLE : DUER_MSG_TYPE_CONFIRMABLE;
|
|
|
|
rs->msg_code = msg_code;
|
|
|
|
if (token) {
|
|
rs->token_len = token_len;
|
|
rs->token = (duer_u8_t *)token;
|
|
|
|
DUER_MEMCPY(rs->token, ptoken, rs->token_len);
|
|
}
|
|
|
|
} while (0);
|
|
|
|
if (!rs) {
|
|
if (token) {
|
|
DUER_FREE((char *)token);
|
|
token = NULL;
|
|
}
|
|
}
|
|
|
|
return rs;
|
|
}
|
|
|
|
/*
|
|
* Release the message that generated by baidu_ca_build_XXXX_message.
|
|
*
|
|
* @Param hdlr, in, the handler will be operated
|
|
* @Param msg, in, the message that remote requested
|
|
*/
|
|
DUER_EXT void baidu_ca_release_message(duer_handler hdlr, duer_msg_t *msg)
|
|
{
|
|
if (msg) {
|
|
if (msg->token) {
|
|
DUER_FREE(msg->token);
|
|
msg->token = NULL;
|
|
}
|
|
|
|
DUER_FREE(msg);
|
|
}
|
|
}
|
|
|
|
DUER_EXT duer_status_t baidu_ca_send_data(duer_handler hdlr, const duer_msg_t *msg,
|
|
const duer_addr_t *addr)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
duer_status_t rs = DUER_ERR_FAILED;
|
|
DUER_LOGV("==> baidu_ca_send_data");
|
|
#if defined(DUER_UDP_REPORTER)
|
|
|
|
if (ctx->state >= DUER_ST_SR_INITIALIZED
|
|
&& baidu_ca_match_address(&(ctx->addr_sr), addr))
|
|
#endif
|
|
{
|
|
DUER_LOGV(" ctx->sr matched: %p", addr);
|
|
rs = duer_coap_send(ctx->sr, msg);
|
|
goto exit;
|
|
}
|
|
|
|
#if defined(DUER_UDP_REPORTER)
|
|
|
|
if (ctx->state >= DUER_ST_RPT_INITIALIZED
|
|
&& (!addr || baidu_ca_match_address(&(ctx->addr_rpt), addr))) {
|
|
duer_mutex_lock(ctx->mutex);
|
|
DUER_LOGV(" ctx->rpt matched: %p", addr);
|
|
rs = duer_coap_send(ctx->rpt, msg);
|
|
duer_mutex_unlock(ctx->mutex);
|
|
goto exit;
|
|
}
|
|
|
|
|
|
rs = baidu_ca_do_start(hdlr);
|
|
|
|
if (rs < DUER_OK) {
|
|
DUER_LOGD(" start failed...");
|
|
goto exit;
|
|
}
|
|
#endif
|
|
exit:
|
|
DUER_LOGV("<== baidu_ca_send_data: rs = %d", rs);
|
|
DUER_MEMDBG_USAGE();
|
|
return rs;
|
|
}
|
|
|
|
DUER_EXT duer_status_t baidu_ca_send_data_directly(duer_handler hdlr, const void *data,
|
|
duer_size_t size, const duer_addr_t *addr)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
duer_status_t rs = DUER_ERR_FAILED;
|
|
DUER_LOGV("==> baidu_ca_send_data");
|
|
#if defined(DUER_UDP_REPORTER)
|
|
|
|
if (ctx->state >= DUER_ST_SR_INITIALIZED
|
|
&& baidu_ca_match_address(&(ctx->addr_sr), addr))
|
|
#endif
|
|
{
|
|
DUER_LOGV(" ctx->sr matched: %p", addr);
|
|
rs = duer_coap_send_data(ctx->sr, data, size);
|
|
goto exit;
|
|
}
|
|
|
|
#if defined(DUER_UDP_REPORTER)
|
|
|
|
if (ctx->state >= DUER_ST_RPT_INITIALIZED
|
|
&& (!addr || baidu_ca_match_address(&(ctx->addr_rpt), addr))) {
|
|
duer_mutex_lock(ctx->mutex);
|
|
DUER_LOGV(" ctx->rpt matched: %p", addr);
|
|
rs = duer_coap_send_data(ctx->rpt, data, size);
|
|
duer_mutex_unlock(ctx->mutex);
|
|
goto exit;
|
|
}
|
|
|
|
rs = baidu_ca_do_start(hdlr);
|
|
|
|
if (rs < DUER_OK) {
|
|
DUER_LOGD(" start failed...");
|
|
goto exit;
|
|
}
|
|
#endif
|
|
exit:
|
|
DUER_LOGV("<== baidu_ca_send_data: rs = %d", rs);
|
|
//DUER_MEMDBG_USAGE();
|
|
return rs;
|
|
}
|
|
|
|
DUER_EXT_IMPL duer_status_t baidu_ca_data_available(duer_handler hdlr,
|
|
const duer_addr_t *addr)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
duer_status_t rs = DUER_ERR_FAILED;
|
|
DUER_LOGV("==> baidu_ca_data_available");
|
|
|
|
if (ctx->state >= DUER_ST_SR_INITIALIZED
|
|
#if defined(DUER_UDP_REPORTER)
|
|
&& baidu_ca_match_address(&(ctx->addr_sr), addr)
|
|
#endif
|
|
) {
|
|
DUER_LOGV(" ctx->sr matched: %p", addr);
|
|
rs = duer_coap_data_available(ctx->sr);
|
|
}
|
|
|
|
#if defined(DUER_UDP_REPORTER)
|
|
|
|
if (ctx->state >= DUER_ST_RPT_INITIALIZED && (!addr
|
|
|| baidu_ca_match_address(&(ctx->addr_rpt), addr))) {
|
|
duer_mutex_lock(ctx->mutex);
|
|
DUER_LOGV(" ctx->rpt matched: %p", addr);
|
|
rs = duer_coap_data_available(ctx->rpt);
|
|
duer_mutex_unlock(ctx->mutex);
|
|
}
|
|
|
|
#endif
|
|
|
|
if (ctx->state < DUER_ST_STARTED) {
|
|
rs = baidu_ca_do_start(hdlr);
|
|
|
|
if (rs < DUER_OK && rs != DUER_ERR_TRANS_WOULD_BLOCK) {
|
|
DUER_LOGW(" start failed...");
|
|
}
|
|
}
|
|
|
|
DUER_LOGV("<== baidu_ca_data_available: rs = %d", rs);
|
|
return rs;
|
|
}
|
|
|
|
DUER_EXT duer_status_t baidu_ca_exec(duer_handler hdlr)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
duer_status_t rs = DUER_OK;
|
|
duer_u32_t timestamp = duer_timestamp() / 1000;
|
|
DUER_LOGV("==> baidu_ca_exec");
|
|
|
|
if (ctx) {
|
|
#if defined(DUER_LWM2M_REGISTER)
|
|
duer_coap_exec(ctx->reg, timestamp);
|
|
#endif
|
|
#if defined(DUER_UDP_REPORTER)
|
|
duer_coap_exec(ctx->rpt, timestamp);
|
|
#endif
|
|
duer_coap_exec(ctx->sr, timestamp);
|
|
}
|
|
|
|
DUER_LOGV("<== baidu_ca_exec: rs = %d", rs);
|
|
return rs;
|
|
}
|
|
|
|
DUER_EXT_IMPL duer_status_t baidu_ca_stop(duer_handler hdlr)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
duer_status_t rs = DUER_OK;
|
|
DUER_LOGV("==> baidu_ca_stop");
|
|
|
|
if (ctx->state > DUER_ST_STOPED) {
|
|
ctx->state = DUER_ST_STOPED;
|
|
|
|
if (ctx->sr) {
|
|
duer_coap_release(ctx->sr);
|
|
ctx->sr = NULL;
|
|
}
|
|
|
|
#if defined(DUER_UDP_REPORTER)
|
|
|
|
if (ctx->rpt) {
|
|
duer_coap_release(ctx->rpt);
|
|
ctx->rpt = NULL;
|
|
}
|
|
|
|
#endif
|
|
#if defined(DUER_LWM2M_REGISTER)
|
|
|
|
if (ctx->reg) {
|
|
duer_coap_unregister(ctx->reg);
|
|
duer_coap_release(ctx->reg);
|
|
ctx->reg = NULL;
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
DUER_LOGV("<== baidu_ca_stop: rs = %d", rs);
|
|
return rs;
|
|
}
|
|
|
|
DUER_EXT_IMPL duer_status_t baidu_ca_release(duer_handler hdlr)
|
|
{
|
|
baidu_ca_t *ctx = (baidu_ca_t *)hdlr;
|
|
DUER_LOGV("==> baidu_ca_release");
|
|
|
|
if (ctx) {
|
|
if (ctx->conf) {
|
|
duer_conf_destroy(ctx->conf);
|
|
ctx->conf = NULL;
|
|
}
|
|
|
|
baidu_ca_stop(ctx);
|
|
|
|
if (ctx->report_query) {
|
|
DUER_FREE(ctx->report_query);
|
|
ctx->report_query = NULL;
|
|
}
|
|
|
|
if (ctx->uuid) {
|
|
DUER_FREE(ctx->uuid);
|
|
ctx->uuid = NULL;
|
|
}
|
|
|
|
if (ctx->token) {
|
|
DUER_FREE(ctx->token);
|
|
ctx->token = NULL;
|
|
}
|
|
|
|
if (ctx->bindToken) {
|
|
DUER_FREE(ctx->bindToken);
|
|
ctx->bindToken = NULL;
|
|
}
|
|
|
|
if (ctx->cuid) {
|
|
DUER_FREE(ctx->cuid);
|
|
ctx->cuid = NULL;
|
|
}
|
|
|
|
if (ctx->bduss) {
|
|
DUER_FREE(ctx->bduss);
|
|
ctx->bduss = NULL;
|
|
}
|
|
|
|
if (ctx->client_id) {
|
|
DUER_FREE(ctx->client_id);
|
|
ctx->client_id = NULL;
|
|
}
|
|
|
|
if (ctx->user_agent) {
|
|
DUER_FREE(ctx->user_agent);
|
|
ctx->user_agent = NULL;
|
|
}
|
|
|
|
if (ctx->serverAddr) {
|
|
DUER_FREE(ctx->serverAddr);
|
|
ctx->serverAddr = NULL;
|
|
}
|
|
|
|
if (ctx->res_list) {
|
|
DUER_FREE(ctx->res_list);
|
|
ctx->res_list = NULL;
|
|
}
|
|
|
|
duer_coap_trace_disable();
|
|
duer_mutex_destroy(ctx->mutex);
|
|
ctx->mutex = NULL;
|
|
DUER_FREE(ctx);
|
|
}
|
|
|
|
DUER_MEMDBG_USAGE();
|
|
DUER_LOGV("<== baidu_ca_release");
|
|
return DUER_OK;
|
|
}
|