support aliyun sdk on TencentOS tiny
sample: examples\aliyun_iotkit_csdk_mqtt project: board\TencentOS_tiny_EVB_MX_Plus\KEIL\aliyun_iotkit_csdk_mqtt
This commit is contained in:
945
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/atm/at_mqtt/mqtt_ica.c
vendored
Normal file
945
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/atm/at_mqtt/mqtt_ica.c
vendored
Normal file
@@ -0,0 +1,945 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "infra_config.h"
|
||||
#include "mqtt_api.h"
|
||||
|
||||
#include "at_wrapper.h"
|
||||
#include "at_parser.h"
|
||||
#include "at_api.h"
|
||||
#include "at_mqtt.h"
|
||||
|
||||
#define AT_ICA_MQTT_MQTTMODE "AT+IMQTTMODE"
|
||||
#define AT_ICA_MQTT_MQTTOPEN "AT+IMQTTOPEN"
|
||||
#define AT_ICA_MQTT_MQTTAUTH "AT+IMQTTAUTH"
|
||||
#define AT_ICA_MQTT_MQTTPARA "AT+IMQTTPARA"
|
||||
#define AT_ICA_MQTT_MQTTCONN "AT+IMQTTCONN"
|
||||
#define AT_ICA_MQTT_MQTTPUB "AT+IMQTTPUB"
|
||||
#define AT_ICA_MQTT_MQTTPUBIN "AT+IMQTTPUBIN"
|
||||
#define AT_ICA_MQTT_MQTTSUB "AT+IMQTTSUB"
|
||||
#define AT_ICA_MQTT_MQTTUNSUB "AT+IMQTTUNSUB"
|
||||
#define AT_ICA_MQTT_MQTTSTATE "AT+IMQTTSTATE"
|
||||
#define AT_ICA_MQTT_MQTTDISCONN "AT+IMQTTDISCONN"
|
||||
#define AT_ICA_MQTT_MQTTDBG "AT+IMQTTDBG"
|
||||
|
||||
#define AT_ICA_MQTT_MQTTRCV "+IMQTT"
|
||||
#define AT_ICA_MQTT_MQTTERROR "+CME"
|
||||
#define AT_ICA_MQTT_MQTTOK "OK"
|
||||
#define AT_ICA_MQTT_MQTTRCVPUB "+IMQTTRCVPUB"
|
||||
#define AT_ICA_MQTT_MQTTRCVPUBIN "+IMQTTRCVPUBIN"
|
||||
#define AT_ICA_MQTT_MQTTPINGRSP "+IMQTTPINGRSP"
|
||||
#define AT_ICA_MQTT_MQTTAUTHRSP "+IMQTTAUTH"
|
||||
#define AT_ICA_MQTT_MQTTPUBRSP "+IMQTTPUB"
|
||||
#define AT_ICA_MQTT_MQTTSUBRSP "+IMQTTSUB"
|
||||
#define AT_ICA_MQTT_MQTTUNSUBRSP "+IMQTTUNSUB"
|
||||
#define AT_ICA_MQTT_MQTTSTATERSP "+IMQTTSTATE"
|
||||
|
||||
#define AT_ICA_MQTT_POSTFIX "\r\n"
|
||||
|
||||
#define AT_MQTT_WAIT_FOREVER 0xffffffffu
|
||||
|
||||
#define AT_MQTT_CMD_MAX_LEN 400
|
||||
#define AT_MQTT_CMD_SUCCESS_RSP "OK"
|
||||
#define AT_MQTT_CMD_FAIL_RSP "FAIL"
|
||||
#define AT_MQTT_CMD_ERROR_RSP "ERROR"
|
||||
#define AT_MQTT_SUBSCRIBE_FAIL 128
|
||||
#define AT_MQTT_RSP_MAX_LEN (CONFIG_MQTT_MESSAGE_MAXLEN + CONFIG_MQTT_TOPIC_MAXLEN + 20)
|
||||
|
||||
#define AT_MQTT_WAIT_TIMEOUT 10*1000
|
||||
|
||||
#define mal_err(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
|
||||
#ifdef INFRA_MEM_STATS
|
||||
#include "infra_mem_stats.h"
|
||||
#define AT_MQTT_ICA_MALLOC(size) LITE_malloc(size, MEM_MAGIC, "mal.ica")
|
||||
#define AT_MQTT_ICA_FREE(ptr) LITE_free(ptr)
|
||||
#else
|
||||
#define AT_MQTT_ICA_MALLOC(size) HAL_Malloc(size)
|
||||
#define AT_MQTT_ICA_FREE(ptr) {HAL_Free((void *)ptr);ptr = NULL;}
|
||||
#endif
|
||||
|
||||
char at_recv_rsp_buf[AT_MQTT_CMD_MAX_LEN];
|
||||
|
||||
typedef enum {
|
||||
AT_MQTT_IDLE = 0,
|
||||
AT_MQTT_SEND_TYPE_SIMPLE,
|
||||
AT_MQTT_AUTH,
|
||||
AT_MQTT_SUB,
|
||||
AT_MQTT_UNSUB,
|
||||
AT_MQTT_PUB,
|
||||
} at_mqtt_send_type_t;
|
||||
|
||||
int at_ica_mqtt_atsend(char *at_cmd, int timeout_ms);
|
||||
int at_ica_mqtt_client_deinit(void);
|
||||
int at_ica_mqtt_client_init(void);
|
||||
int at_ica_mqtt_client_state(void);
|
||||
int at_ica_mqtt_client_publish(const char *topic, int qos, const char *message);
|
||||
int at_ica_mqtt_client_unsubscribe(const char *topic,
|
||||
unsigned int *mqtt_packet_id,
|
||||
int *mqtt_status);
|
||||
int at_ica_mqtt_client_subscribe(const char *topic,
|
||||
int qos,
|
||||
unsigned int *mqtt_packet_id,
|
||||
int *mqtt_status,
|
||||
int timeout_ms);
|
||||
int at_ica_mqtt_client_conn(char *proKey, char *devName, char *devSecret, int tlsEnable);
|
||||
int at_ica_mqtt_client_auth(char *proKey, char *devName, char *devSecret, int tlsEnable);
|
||||
int at_ica_mqtt_client_disconn(void);
|
||||
|
||||
int HAL_AT_MQTT_Init(iotx_mqtt_param_t *pInitParams)
|
||||
{
|
||||
return at_ica_mqtt_client_init();
|
||||
}
|
||||
|
||||
int HAL_AT_MQTT_Deinit()
|
||||
{
|
||||
return at_ica_mqtt_client_deinit();
|
||||
}
|
||||
|
||||
int HAL_AT_MQTT_Connect(char *proKey, char *devName, char *devSecret)
|
||||
{
|
||||
return at_ica_mqtt_client_conn(proKey, devName, devSecret, 0);
|
||||
}
|
||||
|
||||
int HAL_AT_MQTT_Disconnect(void)
|
||||
{
|
||||
return at_ica_mqtt_client_disconn();
|
||||
}
|
||||
|
||||
int HAL_AT_MQTT_Subscribe(const char *topic, int qos, unsigned int *mqtt_packet_id, int *mqtt_status, int timeout_ms)
|
||||
{
|
||||
return at_ica_mqtt_client_subscribe(topic, qos, mqtt_packet_id, mqtt_status, timeout_ms);
|
||||
}
|
||||
|
||||
int HAL_AT_MQTT_Unsubscribe(const char *topic, unsigned int *mqtt_packet_id, int *mqtt_status)
|
||||
{
|
||||
return at_ica_mqtt_client_unsubscribe(topic, mqtt_packet_id, mqtt_status);
|
||||
}
|
||||
|
||||
int HAL_AT_MQTT_Publish(const char *topic, int qos, const char *message, unsigned int msg_len)
|
||||
{
|
||||
return at_ica_mqtt_client_publish(topic, qos, message);
|
||||
}
|
||||
|
||||
int HAL_AT_MQTT_State(void)
|
||||
{
|
||||
return at_ica_mqtt_client_state();
|
||||
}
|
||||
|
||||
int HAL_AT_MQTT_Connectwifi(char *at_conn_wifi)
|
||||
{
|
||||
#ifdef MAL_ICA_ENABLED
|
||||
char at_cmd[64];
|
||||
/* disconnect before connect to the network */
|
||||
if (at_ica_mqtt_client_disconn() != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(at_cmd, at_conn_wifi, 64);
|
||||
/* connect to the network */
|
||||
if (at_ica_mqtt_atsend(at_cmd, AT_MQTT_WAIT_FOREVER) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
#ifndef PLATFORM_HAS_OS
|
||||
char g_ica_rsp_buff[AT_MQTT_RSP_MAX_LEN];
|
||||
#else
|
||||
static char *g_ica_rsp_buff = NULL;
|
||||
#endif
|
||||
static volatile int g_mqtt_connect_state = IOTX_MC_STATE_INVALID;
|
||||
static volatile at_mqtt_send_type_t g_ica_at_response = AT_MQTT_IDLE;
|
||||
static volatile int g_at_response_result = 0;
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
static void *g_sem_response;
|
||||
#else
|
||||
int g_at_response = 0;
|
||||
#endif
|
||||
static volatile int g_response_msg_number = 0;
|
||||
static int g_response_packetid = 0;
|
||||
static int g_response_status = 0;
|
||||
static int g_public_qos = 0;
|
||||
|
||||
int at_ica_mqtt_atsend(char *at_cmd, int timeout_ms);
|
||||
|
||||
static void at_err_callback(char *at_rsp)
|
||||
{
|
||||
char *temp;
|
||||
int data;
|
||||
|
||||
temp = strtok(at_rsp, ":");
|
||||
temp = strtok(NULL, ":");
|
||||
if ((data = strtol(temp, NULL, 0)) == 3) {
|
||||
g_at_response_result = 0;
|
||||
} else {
|
||||
g_at_response_result = -1;
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
/* notify the sender error; */
|
||||
HAL_SemaphorePost(g_sem_response);
|
||||
#else
|
||||
g_at_response ++;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
static void at_succ_callback(void)
|
||||
{
|
||||
g_at_response_result = 0;
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
/* notify the sender ok; */
|
||||
HAL_SemaphorePost(g_sem_response);
|
||||
#else
|
||||
g_at_response ++;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
static void sub_callback(char *at_rsp)
|
||||
{
|
||||
char *temp;
|
||||
|
||||
if (strstr(at_rsp, AT_MQTT_CMD_ERROR_RSP)) {
|
||||
g_at_response_result = -1;
|
||||
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
/* notify the sender fail; */
|
||||
HAL_SemaphorePost(g_sem_response);
|
||||
#else
|
||||
g_at_response ++;
|
||||
#endif
|
||||
return;
|
||||
} else if (NULL != strstr(at_rsp, AT_ICA_MQTT_MQTTSUBRSP)) {
|
||||
/* get status/packet_id */
|
||||
if (NULL != strstr(at_rsp, ",")) {
|
||||
g_at_response_result = 0;
|
||||
|
||||
temp = strtok(at_rsp, ":");
|
||||
|
||||
if (temp != NULL) {
|
||||
temp = strtok(NULL, ",");
|
||||
} else {
|
||||
mal_err("subscribe rsp param invalid 1");
|
||||
g_at_response_result = -1;
|
||||
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
HAL_SemaphorePost(g_sem_response);
|
||||
#else
|
||||
g_at_response ++;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (temp != NULL) {
|
||||
g_response_packetid = strtol(temp, NULL, 0);
|
||||
|
||||
temp = strtok(NULL, "\r\n");
|
||||
} else {
|
||||
mal_err("subscribe rsp param invalid 2");
|
||||
g_at_response_result = -1;
|
||||
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
HAL_SemaphorePost(g_sem_response);
|
||||
#else
|
||||
g_at_response ++;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (temp != NULL) {
|
||||
g_response_status = strtol(temp, NULL, 0);
|
||||
} else {
|
||||
mal_err("subscribe rsp param invalid 3");
|
||||
g_at_response_result = -1;
|
||||
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
HAL_SemaphorePost(g_sem_response);
|
||||
#else
|
||||
g_at_response ++;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
/* notify the sender ok; */
|
||||
HAL_SemaphorePost(g_sem_response);
|
||||
#else
|
||||
g_at_response ++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void unsub_callback(char *at_rsp)
|
||||
{
|
||||
char *temp;
|
||||
if (strstr(at_rsp, AT_MQTT_CMD_ERROR_RSP)) {
|
||||
g_at_response_result = -1;
|
||||
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
/* notify the sender fail; */
|
||||
HAL_SemaphorePost(g_sem_response);
|
||||
#else
|
||||
g_at_response ++;
|
||||
#endif
|
||||
|
||||
return;
|
||||
} else if (NULL != strstr(at_rsp, AT_ICA_MQTT_MQTTUNSUBRSP)) {
|
||||
/* get status/packet_id */
|
||||
if (NULL != strstr(at_rsp, ",")) {
|
||||
g_at_response_result = 0;
|
||||
|
||||
temp = strtok(at_rsp, ":");
|
||||
|
||||
if (temp != NULL) {
|
||||
temp = strtok(NULL, ",");
|
||||
} else {
|
||||
mal_err("subscribe rsp param invalid 1");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (temp != NULL) {
|
||||
g_response_packetid = strtol(temp, NULL, 0);
|
||||
|
||||
temp = strtok(NULL, "\r\n");
|
||||
} else {
|
||||
mal_err("subscribe rsp param invalid 2");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (temp != NULL) {
|
||||
g_response_status = strtol(temp, NULL, 0);
|
||||
} else {
|
||||
mal_err("subscribe rsp param invalid 3");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
mal_err("unsub: %s", g_ica_rsp_buff);
|
||||
mal_err("unsub packetid: %d, sta: %d", g_response_packetid, g_response_status);
|
||||
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
/* notify the sender ok; */
|
||||
HAL_SemaphorePost(g_sem_response);
|
||||
#else
|
||||
g_at_response ++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void pub_callback(char *at_rsp)
|
||||
{
|
||||
char *temp;
|
||||
if (strstr(at_rsp, AT_MQTT_CMD_ERROR_RSP)) {
|
||||
g_at_response_result = -1;
|
||||
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
/* notify the sender fail; */
|
||||
HAL_SemaphorePost(g_sem_response);
|
||||
#else
|
||||
g_at_response ++;
|
||||
#endif
|
||||
|
||||
return;
|
||||
} else if (NULL != strstr(at_rsp, AT_ICA_MQTT_MQTTPUBRSP)) {
|
||||
/* get status/packet_id */
|
||||
if ((NULL != strstr(at_rsp, ","))
|
||||
|| (0 == g_public_qos)) {
|
||||
|
||||
temp = strtok(at_rsp, ":");
|
||||
|
||||
if (temp != NULL) {
|
||||
if (0 == g_public_qos) {
|
||||
temp = strtok(NULL, "\r\n");
|
||||
} else {
|
||||
temp = strtok(NULL, ",");
|
||||
}
|
||||
} else {
|
||||
mal_err("public get packetid error");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (temp != NULL) {
|
||||
g_response_packetid = strtol(temp, NULL, 0);
|
||||
} else {
|
||||
mal_err("public parse packetid error");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (0 != g_public_qos) {
|
||||
temp = strtok(NULL, "\r\n");
|
||||
|
||||
if (temp != NULL) {
|
||||
g_response_status = strtol(temp, NULL, 0);
|
||||
} else {
|
||||
mal_err("public parse status error");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_at_response_result = 0;
|
||||
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
/* notify the sender ok; */
|
||||
HAL_SemaphorePost(g_sem_response);
|
||||
#else
|
||||
g_at_response ++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void state_change_callback(char *at_rsp)
|
||||
{
|
||||
char *temp;
|
||||
|
||||
if (NULL == at_rsp) {
|
||||
return;
|
||||
}
|
||||
|
||||
temp = strtok(at_rsp, ":");
|
||||
|
||||
if (temp != NULL) {
|
||||
temp = strtok(NULL, "\r\n");
|
||||
|
||||
if (temp != NULL) {
|
||||
g_mqtt_connect_state = strtol(temp, NULL, 0);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void recv_data_callback(char *at_rsp)
|
||||
{
|
||||
char *temp = NULL;
|
||||
char *topic_ptr = NULL;
|
||||
char *msg_ptr = NULL;
|
||||
unsigned int msg_len = 0;
|
||||
struct at_mqtt_input param;
|
||||
|
||||
if (NULL == at_rsp) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* try to get msg id */
|
||||
temp = strtok(g_ica_rsp_buff, ":");
|
||||
|
||||
if (temp != NULL) {
|
||||
temp = strtok(NULL, ",");
|
||||
|
||||
if (temp != NULL) {
|
||||
/* packet_id = strtol(temp, NULL, 0); */
|
||||
} else {
|
||||
mal_err("packet id error");
|
||||
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
mal_err("packet id not found");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* try to get topic string */
|
||||
temp = strtok(NULL, "\"");
|
||||
|
||||
if (temp != NULL) {
|
||||
temp[strlen(temp)] = '\0';
|
||||
|
||||
topic_ptr = temp;
|
||||
} else {
|
||||
mal_err("publish topic not found");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* try to get payload string */
|
||||
temp = strtok(NULL, ",");
|
||||
|
||||
if (temp != NULL) {
|
||||
msg_len = strtol(temp, NULL, 0);
|
||||
|
||||
while (*temp++ != '\"');
|
||||
|
||||
msg_ptr = temp;
|
||||
|
||||
msg_ptr[msg_len] = '\0';
|
||||
|
||||
param.topic = topic_ptr;
|
||||
param.topic_len = strlen(topic_ptr);
|
||||
param.message = msg_ptr;
|
||||
param.msg_len = strlen(msg_ptr);
|
||||
|
||||
if (IOT_ATM_Input(¶m) != 0) {
|
||||
mal_err("hand data to uplayer fail!\n");
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
mal_err("publish data not found");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void at_ica_mqtt_client_rsp_callback(void *arg, char *rspinfo, int rsplen)
|
||||
{
|
||||
if (NULL == rspinfo || rsplen == 0) {
|
||||
mal_err("invalid input of rsp callback");
|
||||
return;
|
||||
}
|
||||
if (NULL == g_ica_rsp_buff) {
|
||||
mal_err("g_ica_rsp_buff rsp is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
if (rsplen > AT_MQTT_RSP_MAX_LEN) {
|
||||
mal_err("rsp len(%d) exceed max len", rsplen);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(g_ica_rsp_buff, rspinfo, rsplen);
|
||||
g_ica_rsp_buff[rsplen] = '\0';
|
||||
|
||||
if (0 == memcmp(g_ica_rsp_buff,
|
||||
AT_ICA_MQTT_MQTTERROR,
|
||||
strlen(AT_ICA_MQTT_MQTTERROR))) {
|
||||
|
||||
at_err_callback(g_ica_rsp_buff);
|
||||
} else if (0 == memcmp(g_ica_rsp_buff,
|
||||
AT_ICA_MQTT_MQTTRCVPUB,
|
||||
strlen(AT_ICA_MQTT_MQTTRCVPUB))) { /* Receive Publish Data */
|
||||
|
||||
recv_data_callback(g_ica_rsp_buff);
|
||||
} else if (0 == memcmp(g_ica_rsp_buff,
|
||||
AT_ICA_MQTT_MQTTSTATERSP,
|
||||
strlen(AT_ICA_MQTT_MQTTSTATERSP))) { /* Receive Mqtt Status Change */
|
||||
|
||||
state_change_callback(g_ica_rsp_buff);
|
||||
} else {
|
||||
switch (g_ica_at_response) { /* nothing to process */
|
||||
|
||||
case AT_MQTT_IDLE:
|
||||
|
||||
break;
|
||||
|
||||
case AT_MQTT_SEND_TYPE_SIMPLE:
|
||||
|
||||
if (0 == memcmp(g_ica_rsp_buff,
|
||||
AT_MQTT_CMD_SUCCESS_RSP,
|
||||
strlen(AT_MQTT_CMD_SUCCESS_RSP))) {
|
||||
|
||||
at_succ_callback();
|
||||
} else {
|
||||
|
||||
mal_err("invalid success type %s", g_ica_rsp_buff);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AT_MQTT_AUTH:
|
||||
|
||||
if (0 == memcmp(g_ica_rsp_buff,
|
||||
AT_ICA_MQTT_MQTTAUTHRSP,
|
||||
strlen(AT_ICA_MQTT_MQTTAUTHRSP))) {
|
||||
|
||||
if (NULL != strstr(g_ica_rsp_buff, AT_MQTT_CMD_SUCCESS_RSP)) {
|
||||
at_succ_callback();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AT_MQTT_SUB:
|
||||
sub_callback(g_ica_rsp_buff);
|
||||
break;
|
||||
|
||||
case AT_MQTT_UNSUB:
|
||||
unsub_callback(g_ica_rsp_buff);
|
||||
break;
|
||||
|
||||
case AT_MQTT_PUB:
|
||||
pub_callback(g_ica_rsp_buff);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int at_ica_mqtt_client_disconn(void)
|
||||
{
|
||||
char at_cmd[64];
|
||||
|
||||
memset(at_cmd, 0, 64);
|
||||
|
||||
/* connect to the network */
|
||||
HAL_Snprintf(at_cmd,
|
||||
64,
|
||||
"%s\r\n",
|
||||
AT_ICA_MQTT_MQTTDISCONN);
|
||||
|
||||
/* disconnect from server */
|
||||
if (0 != at_ica_mqtt_atsend(at_cmd, AT_MQTT_WAIT_TIMEOUT)) {
|
||||
mal_err("disconnect at command fail");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at_ica_mqtt_client_auth(char *proKey, char *devName, char *devSecret, int tlsEnable)
|
||||
{
|
||||
char at_cmd[AT_MQTT_CMD_MAX_LEN];
|
||||
|
||||
if ((proKey == NULL) || (devName == NULL) || (devSecret == NULL)) {
|
||||
|
||||
mal_err("auth param should not be NULL");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set tls mode before auth */
|
||||
if (tlsEnable) {
|
||||
memset(at_cmd, 0, AT_MQTT_CMD_MAX_LEN);
|
||||
|
||||
HAL_Snprintf(at_cmd,
|
||||
AT_MQTT_CMD_MAX_LEN - 1,
|
||||
"%s=%d\r\n",
|
||||
AT_ICA_MQTT_MQTTMODE,
|
||||
1);
|
||||
|
||||
if (0 != at_ica_mqtt_atsend(at_cmd, AT_MQTT_WAIT_TIMEOUT)) {
|
||||
|
||||
mal_err("tls at command fail");
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* submit auth */
|
||||
memset(at_cmd, 0, AT_MQTT_CMD_MAX_LEN);
|
||||
|
||||
HAL_Snprintf(at_cmd,
|
||||
AT_MQTT_CMD_MAX_LEN - 1,
|
||||
"%s=\"%s\",\"%s\",\"%s\"\r\n",
|
||||
AT_ICA_MQTT_MQTTAUTH,
|
||||
proKey, devName, devSecret);
|
||||
|
||||
if (0 != at_ica_mqtt_atsend(at_cmd, AT_MQTT_WAIT_TIMEOUT)) {
|
||||
|
||||
mal_err("auth at command fail");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at_ica_mqtt_client_conn(char *proKey, char *devName, char *devSecret, int tlsEnable)
|
||||
{
|
||||
char at_cmd[64];
|
||||
|
||||
if ((proKey == NULL) || (devName == NULL) || (devSecret == NULL)) {
|
||||
|
||||
mal_err("conn param should not be NULL");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 != at_ica_mqtt_client_auth(proKey, devName, devSecret, tlsEnable)) {
|
||||
|
||||
mal_err("authen fail");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* connect to mqtt server */
|
||||
memset(at_cmd, 0, 64);
|
||||
|
||||
HAL_Snprintf(at_cmd,
|
||||
64,
|
||||
"%s\r\n",
|
||||
AT_ICA_MQTT_MQTTCONN);
|
||||
|
||||
if (0 != at_ica_mqtt_atsend(at_cmd, AT_MQTT_WAIT_TIMEOUT)) {
|
||||
|
||||
mal_err("conn at command fail");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at_ica_mqtt_client_subscribe(const char *topic,
|
||||
int qos,
|
||||
unsigned int *mqtt_packet_id,
|
||||
int *mqtt_status,
|
||||
int timeout_ms)
|
||||
{
|
||||
char at_cmd[AT_MQTT_CMD_MAX_LEN];
|
||||
|
||||
if ((topic == NULL) || (mqtt_packet_id == NULL) || (mqtt_status == NULL)) {
|
||||
|
||||
mal_err("subscribe param should not be NULL");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(at_cmd, 0, AT_MQTT_CMD_MAX_LEN);
|
||||
|
||||
HAL_Snprintf(at_cmd,
|
||||
AT_MQTT_CMD_MAX_LEN - 1,
|
||||
"%s=\"%s\",%d\r\n",
|
||||
AT_ICA_MQTT_MQTTSUB,
|
||||
topic,
|
||||
qos);
|
||||
|
||||
if (0 != at_ica_mqtt_atsend(at_cmd, timeout_ms)) {
|
||||
mal_err("sub at command fail");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at_ica_mqtt_client_unsubscribe(const char *topic,
|
||||
unsigned int *mqtt_packet_id,
|
||||
int *mqtt_status)
|
||||
{
|
||||
char at_cmd[AT_MQTT_CMD_MAX_LEN];
|
||||
if ((topic == NULL) || (mqtt_packet_id == NULL) || (mqtt_status == NULL)) {
|
||||
|
||||
mal_err("unsubscribe param should not be NULL");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(at_cmd, 0, AT_MQTT_CMD_MAX_LEN);
|
||||
|
||||
HAL_Snprintf(at_cmd,
|
||||
AT_MQTT_CMD_MAX_LEN - 1,
|
||||
"%s=\"%s\"\r\n",
|
||||
AT_ICA_MQTT_MQTTUNSUB,
|
||||
topic);
|
||||
|
||||
if (0 != at_ica_mqtt_atsend(at_cmd, AT_MQTT_WAIT_TIMEOUT)) {
|
||||
|
||||
mal_err("unsub at command fail");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at_ica_mqtt_client_publish(const char *topic, int qos, const char *message)
|
||||
{
|
||||
char at_cmd[AT_MQTT_CMD_MAX_LEN] = {0};
|
||||
char msg_convert[AT_MQTT_CMD_MAX_LEN] = {0};
|
||||
char *temp;
|
||||
if ((topic == NULL) || (message == NULL)) {
|
||||
|
||||
mal_err("publish param should not be NULL");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
temp = msg_convert;
|
||||
|
||||
/* for the case of " appeared in the string */
|
||||
while (*message) {
|
||||
if (*message == '\"') {
|
||||
*temp++ = '\\';
|
||||
}
|
||||
|
||||
*temp++ = *message++;
|
||||
}
|
||||
|
||||
HAL_Snprintf(at_cmd,
|
||||
AT_MQTT_CMD_MAX_LEN - 1,
|
||||
"%s=\"%s\",%d,\"%s\"\r\n",
|
||||
AT_ICA_MQTT_MQTTPUB,
|
||||
topic,
|
||||
qos,
|
||||
msg_convert);
|
||||
|
||||
g_public_qos = qos;
|
||||
if (0 != at_ica_mqtt_atsend(at_cmd, AT_MQTT_WAIT_TIMEOUT)) {
|
||||
|
||||
mal_err("pub at command fail");
|
||||
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int at_ica_mqtt_client_state(void)
|
||||
{
|
||||
int state;
|
||||
|
||||
switch(g_mqtt_connect_state){
|
||||
case 0:
|
||||
state = IOTX_MC_STATE_DISCONNECTED;
|
||||
break;
|
||||
case 1:
|
||||
state = IOTX_MC_STATE_CONNECTED;
|
||||
break;
|
||||
default:
|
||||
state = IOTX_MC_STATE_INVALID;
|
||||
break;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
int at_ica_mqtt_client_init(void)
|
||||
{
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
g_ica_rsp_buff = AT_MQTT_ICA_MALLOC(AT_MQTT_RSP_MAX_LEN);
|
||||
if (NULL == g_ica_rsp_buff) {
|
||||
mal_err("at ica mqtt client malloc buff failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == (g_sem_response = HAL_SemaphoreCreate())) {
|
||||
if (NULL != g_ica_rsp_buff) {
|
||||
AT_MQTT_ICA_FREE(g_ica_rsp_buff);
|
||||
|
||||
g_ica_rsp_buff = NULL;
|
||||
}
|
||||
mal_err("at ica mqtt client create sem failed");
|
||||
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
memset(g_ica_rsp_buff, 0, AT_MQTT_RSP_MAX_LEN);
|
||||
g_at_response = 0;
|
||||
#endif
|
||||
|
||||
g_mqtt_connect_state = IOTX_MC_STATE_INVALID;
|
||||
|
||||
at_register_callback(AT_ICA_MQTT_MQTTRCV,
|
||||
AT_ICA_MQTT_POSTFIX,
|
||||
at_recv_rsp_buf,
|
||||
AT_MQTT_CMD_MAX_LEN,
|
||||
at_ica_mqtt_client_rsp_callback,
|
||||
NULL);
|
||||
|
||||
at_register_callback(AT_ICA_MQTT_MQTTERROR,
|
||||
AT_ICA_MQTT_POSTFIX,
|
||||
at_recv_rsp_buf,
|
||||
AT_MQTT_CMD_MAX_LEN,
|
||||
at_ica_mqtt_client_rsp_callback,
|
||||
NULL);
|
||||
|
||||
at_register_callback(AT_ICA_MQTT_MQTTOK,
|
||||
AT_ICA_MQTT_POSTFIX,
|
||||
at_recv_rsp_buf,
|
||||
AT_MQTT_CMD_MAX_LEN,
|
||||
at_ica_mqtt_client_rsp_callback,
|
||||
NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at_ica_mqtt_client_deinit(void)
|
||||
{
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
if (NULL != g_ica_rsp_buff) {
|
||||
AT_MQTT_ICA_FREE(g_ica_rsp_buff);
|
||||
g_ica_rsp_buff = NULL;
|
||||
}
|
||||
HAL_SemaphoreDestroy(g_sem_response);
|
||||
#else
|
||||
memset(g_ica_rsp_buff, 0, AT_MQTT_RSP_MAX_LEN);
|
||||
g_at_response = 0;
|
||||
#endif
|
||||
|
||||
g_mqtt_connect_state = IOTX_MC_STATE_INVALID;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at_ica_mqtt_atsend(char *at_cmd, int timeout_ms)
|
||||
{
|
||||
if (at_cmd == NULL) {
|
||||
return -1;
|
||||
}
|
||||
/* state error */
|
||||
if (g_ica_at_response != AT_MQTT_IDLE) {
|
||||
|
||||
mal_err("at send state is not idle (%d)", g_ica_at_response);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
mal_err("send: %s", at_cmd);
|
||||
|
||||
if (NULL != strstr(at_cmd, AT_ICA_MQTT_MQTTAUTH)) {
|
||||
g_ica_at_response = AT_MQTT_AUTH;
|
||||
} else if (NULL != strstr(at_cmd, AT_ICA_MQTT_MQTTSUB)) {
|
||||
g_ica_at_response = AT_MQTT_SUB;
|
||||
} else if (NULL != strstr(at_cmd, AT_ICA_MQTT_MQTTUNSUB)) {
|
||||
g_ica_at_response = AT_MQTT_UNSUB;
|
||||
} else if (NULL != strstr(at_cmd, AT_ICA_MQTT_MQTTPUB)) {
|
||||
g_ica_at_response = AT_MQTT_PUB;
|
||||
} else {
|
||||
g_ica_at_response = AT_MQTT_SEND_TYPE_SIMPLE;
|
||||
}
|
||||
|
||||
if (0 != at_send_no_reply(at_cmd, strlen(at_cmd), false)) {
|
||||
|
||||
mal_err("at send raw api fail");
|
||||
|
||||
g_ica_at_response = AT_MQTT_IDLE;
|
||||
|
||||
return -1;
|
||||
}
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
HAL_SemaphoreWait(g_sem_response, timeout_ms);
|
||||
#else
|
||||
if(!g_at_response)
|
||||
{
|
||||
at_yield(NULL, 0, NULL, 500);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_at_response --;
|
||||
}
|
||||
#endif
|
||||
|
||||
g_ica_at_response = AT_MQTT_IDLE;
|
||||
|
||||
return g_at_response_result;
|
||||
}
|
1348
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/atm/at_mqtt/mqtt_sim800.c
vendored
Normal file
1348
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/atm/at_mqtt/mqtt_sim800.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
747
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/atm/at_tcp/mk3060.c
vendored
Normal file
747
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/atm/at_tcp/mk3060.c
vendored
Normal file
@@ -0,0 +1,747 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "infra_config.h"
|
||||
#include "mqtt_api.h"
|
||||
|
||||
#include "at_wrapper.h"
|
||||
#include "at_parser.h"
|
||||
#include "at_api.h"
|
||||
|
||||
#define TAG "at_mk3060_wifi"
|
||||
|
||||
#define CMD_FAIL_RSP "ERROR"
|
||||
|
||||
#define MAX_DATA_LEN 4096
|
||||
#define MAX_DOMAIN_LEN 256
|
||||
#define DATA_LEN_MAX 10
|
||||
#define LINK_ID_MAX 5
|
||||
#define SEM_WAIT_DURATION 5000
|
||||
|
||||
#define AT_CMD_EHCO_OFF "AT+UARTE=OFF"
|
||||
#define STOP_CMD "AT+CIPSTOP"
|
||||
#define STOP_CMD_LEN (sizeof(STOP_CMD)+1+1+5+1)
|
||||
|
||||
#define STOP_AUTOCONN_CMD "AT+CIPAUTOCONN"
|
||||
#define STOP_AUTOCONN_CMD_LEN (sizeof(STOP_AUTOCONN_CMD)+1+1+5+1)
|
||||
|
||||
#ifdef AT_DEBUG_MODE
|
||||
#define at_conn_hal_err(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#define at_conn_hal_warning(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#define at_conn_hal_info(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#define at_conn_hal_debug(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#else
|
||||
#define at_conn_hal_err(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#define at_conn_hal_warning(...)
|
||||
#define at_conn_hal_info(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#define at_conn_hal_debug(...)
|
||||
#endif
|
||||
|
||||
void *HAL_SemaphoreCreate(void);
|
||||
void HAL_SemaphoreDestroy(void *sem);
|
||||
void HAL_SemaphorePost(void *sem);
|
||||
int HAL_SemaphoreWait(void *sem, uint32_t timeout_ms);
|
||||
typedef int (*at_data_check_cb_t)(char data);
|
||||
|
||||
/* Change to include data slink for each link id respectively. <TODO> */
|
||||
typedef struct link_s {
|
||||
int fd;
|
||||
void* sem_start;
|
||||
void* sem_close;
|
||||
} link_t;
|
||||
|
||||
static link_t g_link[LINK_ID_MAX];
|
||||
static void* g_link_mutex;
|
||||
|
||||
static char localipaddr[16];
|
||||
|
||||
static int socket_data_info_get(char *buf, uint32_t buflen, at_data_check_cb_t valuecheck);
|
||||
static int socket_data_len_check(char data);
|
||||
|
||||
#define WIFI_SSID "Yuemewifi-3766"
|
||||
#define WIFI_PWD "aos12345"
|
||||
#define WIFI_TIMEOUT 20000
|
||||
static uint8_t gotip = 0;
|
||||
|
||||
#define MK3080_MAX_PAYLOAD_SIZE (CONFIG_MQTT_MESSAGE_MAXLEN + CONFIG_MQTT_TOPIC_MAXLEN + 20)
|
||||
|
||||
#ifndef PLATFORM_HAS_DYNMEM
|
||||
static uint8_t payload[MK3080_MAX_PAYLOAD_SIZE] = {0};
|
||||
#endif
|
||||
|
||||
static uint64_t _get_time_ms(void)
|
||||
{
|
||||
return HAL_UptimeMs();
|
||||
}
|
||||
|
||||
static uint64_t _time_left(uint64_t t_end, uint64_t t_now)
|
||||
{
|
||||
uint64_t t_left;
|
||||
|
||||
if (t_end > t_now) {
|
||||
t_left = t_end - t_now;
|
||||
} else {
|
||||
t_left = 0;
|
||||
}
|
||||
|
||||
return t_left;
|
||||
}
|
||||
|
||||
static int at_connect_wifi(char *ssid, char *pwd, uint32_t timeout_ms)
|
||||
{
|
||||
char conn_str[100]= {0};
|
||||
char out[20] = {0};
|
||||
uint64_t t_end, t_left;
|
||||
|
||||
t_end = _get_time_ms() + timeout_ms;
|
||||
|
||||
HAL_Snprintf(conn_str, 100, "AT+WJAP=%s,%s", ssid, pwd);
|
||||
|
||||
if (at_send_wait_reply(conn_str, strlen(conn_str), true, NULL,
|
||||
0, out, sizeof(out), NULL) < 0){
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strstr(out, "ERROR") != NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while(0 == gotip) {
|
||||
HAL_SleepMs(50);
|
||||
|
||||
t_left = _time_left(t_end, _get_time_ms());
|
||||
if (0 == t_left) {
|
||||
at_conn_hal_err("wifi connect timeout!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_HAS_OS
|
||||
at_yield(NULL, 0, NULL, 100);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void handle_tcp_udp_client_conn_state(uint8_t link_id)
|
||||
{
|
||||
char s[32] = {0};
|
||||
|
||||
at_read(s, 6);
|
||||
if (strstr(s, "CLOSED") != NULL) {
|
||||
at_conn_hal_info("Server closed event.");
|
||||
if (g_link[link_id].sem_close) {
|
||||
at_conn_hal_debug(TAG, "sem is going to be waked up: 0x%x", &g_link[link_id].sem_close);
|
||||
HAL_SemaphorePost(g_link[link_id].sem_close); /* wakeup send task */
|
||||
}
|
||||
at_conn_hal_info("Server conn (%d) closed.", link_id);
|
||||
} else if (strstr(s, "CONNEC") != NULL) {
|
||||
at_conn_hal_info("Server conn (%d) successful.", link_id);
|
||||
at_read(s, 3);
|
||||
if (g_link[link_id].sem_start) {
|
||||
at_conn_hal_debug("sem is going to be waked up: 0x%x", &g_link[link_id].sem_start);
|
||||
HAL_SemaphorePost(g_link[link_id].sem_start); /* wakeup send task */
|
||||
}
|
||||
} else if (strstr(s, "DISCON") != NULL) {
|
||||
at_conn_hal_info("Server conn (%d) disconnected.", link_id);
|
||||
at_read(s, 6);
|
||||
} else {
|
||||
at_conn_hal_warning("No one handle this unkown event!!!");
|
||||
}
|
||||
}
|
||||
|
||||
static int socket_data_len_check(char data)
|
||||
{
|
||||
if (data > '9' || data < '0') {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int socket_data_info_get(char *buf, uint32_t buflen, at_data_check_cb_t valuecheck)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
|
||||
if (NULL == buf || 0 == buflen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
at_read(&buf[i], 1);
|
||||
if (buf[i] == ',') {
|
||||
buf[i] = 0;
|
||||
break;
|
||||
}
|
||||
if (i >= buflen) {
|
||||
at_conn_hal_err("Too long length of data.reader is %s \r\n", buf);
|
||||
return -1;
|
||||
}
|
||||
if (NULL != valuecheck) {
|
||||
if (valuecheck(buf[i])) {
|
||||
at_conn_hal_err("Invalid string!!!, reader is %s \r\n", buf);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
} while (1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void handle_socket_data()
|
||||
{
|
||||
int link_id = 0;
|
||||
int ret = 0;
|
||||
uint32_t len = 0;
|
||||
char reader[16] = {0};
|
||||
char *recvdata = NULL;
|
||||
struct at_conn_input param;
|
||||
|
||||
/* Eat the "OCKET," */
|
||||
at_read(reader, 6);
|
||||
if (memcmp(reader, "OCKET,", strlen("OCKET,")) != 0) {
|
||||
at_conn_hal_err("0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x invalid event format!!!\r\n",
|
||||
reader[0], reader[1], reader[2], reader[3], reader[4], reader[5]);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(reader, 0, sizeof(reader));
|
||||
ret = socket_data_info_get(reader, 1, &socket_data_len_check);
|
||||
if (ret) {
|
||||
at_conn_hal_err("Invalid link id 0x%02x !!!\r\n", reader[0]);
|
||||
return;
|
||||
}
|
||||
link_id = reader[0] - '0';
|
||||
|
||||
memset(reader, 0, sizeof(reader));
|
||||
/* len */
|
||||
ret = socket_data_info_get(reader, sizeof(reader), &socket_data_len_check);
|
||||
if (ret) {
|
||||
at_conn_hal_err("Invalid datalen %s !!!\r\n", reader);
|
||||
return;
|
||||
}
|
||||
|
||||
len = atoi(reader);
|
||||
if (len > MAX_DATA_LEN) {
|
||||
at_conn_hal_err("invalid input socket data len %d \r\n", len);
|
||||
return;
|
||||
}
|
||||
/* Prepare socket data */
|
||||
#ifdef PLATFORM_HAS_DYNMEM
|
||||
recvdata = (char *)HAL_Malloc(len);
|
||||
#else
|
||||
if (len <= MK3080_MAX_PAYLOAD_SIZE) {
|
||||
recvdata = (char *)payload;
|
||||
}
|
||||
#endif
|
||||
if (!recvdata) {
|
||||
at_conn_hal_err("Error: %s %d out of memory, len is %d. \r\n", __func__, __LINE__, len);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = at_read(recvdata, len);
|
||||
if (ret != len) {
|
||||
at_conn_hal_err("at read error recv %d want %d!\n", ret, len);
|
||||
goto err;
|
||||
}
|
||||
|
||||
memset(reader, 0, sizeof(reader));
|
||||
at_read(reader, 2);
|
||||
if (strncmp(reader, AT_RECV_PREFIX, 2) != 0) {
|
||||
at_conn_hal_err("at fail to read delimiter %s after data %s!\n", AT_RECV_PREFIX, reader);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (g_link[link_id].fd >= 0) {
|
||||
param.fd = g_link[link_id].fd;
|
||||
param.data = recvdata;
|
||||
param.datalen = len;
|
||||
param.remote_ip = NULL;
|
||||
param.remote_port = 0;
|
||||
|
||||
/* TODO get recv data src ip and port*/
|
||||
if (IOT_ATM_Input(¶m) != 0) {
|
||||
at_conn_hal_err(" %s socket %d get data len %d fail to post to at_conn, drop it\n",
|
||||
__func__, g_link[link_id].fd, len);
|
||||
}
|
||||
}
|
||||
|
||||
at_conn_hal_debug("%s socket data on link %d with length %d posted to at_conn\n",
|
||||
__func__, link_id, len);
|
||||
|
||||
err:
|
||||
#ifdef PLATFORM_HAS_DYNMEM
|
||||
HAL_Free(recvdata);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wifi station event handler. include:
|
||||
* +WEVENT:AP_UP
|
||||
* +WEVENT:AP_DOWN
|
||||
* +WEVENT:STATION_UP
|
||||
* +WEVENT:STATION_DOWN
|
||||
*/
|
||||
static void mk3060wifi_event_handler(void *arg, char *buf, int buflen)
|
||||
{
|
||||
char eventhead[4] = {0};
|
||||
char eventotal[16] = {0};
|
||||
|
||||
at_read(eventhead, 3);
|
||||
if (strcmp(eventhead, "AP_") == 0) {
|
||||
at_read(eventotal, 2);
|
||||
if (strcmp(eventotal, "UP") == 0) {
|
||||
|
||||
} else if (strcmp(eventotal, "DO") == 0) {
|
||||
/*eat WN*/
|
||||
at_read(eventotal, 2);
|
||||
} else {
|
||||
at_conn_hal_err("!!!Error: wrong WEVENT AP string received. %s\r\n", eventotal);
|
||||
return;
|
||||
}
|
||||
} else if (strcmp(eventhead, "STA") == 0) {
|
||||
at_read(eventotal, 7);
|
||||
if (strcmp(eventotal, "TION_UP") == 0) {
|
||||
gotip = 1;
|
||||
} else if (strcmp(eventotal, "TION_DO") == 0) {
|
||||
/*eat WN*/
|
||||
at_read(eventotal, 2);
|
||||
memset(localipaddr, 0, sizeof(localipaddr));
|
||||
gotip = 0;
|
||||
} else {
|
||||
at_conn_hal_err("!!!Error: wrong WEVENT STATION string received. %s\r\n", eventotal);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
at_conn_hal_err("!!!Error: wrong WEVENT string received. %s\r\n", eventhead);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Network connection state event handler. Events includes:
|
||||
* 1. +CIPEVENT:id,SERVER,CONNECTED
|
||||
* 2. +CIPEVENT:id,SERVER,CLOSED
|
||||
* 3. +CIPEVENT:CLIENT,CONNECTED,ip,port
|
||||
* 4. +CIPEVENT:CLIENT,CLOSED,ip,port
|
||||
* 5. +CIPEVENT:id,UDP,CONNECTED
|
||||
* 6. +CIPEVENT:id,UDP,CLOSED
|
||||
* 7. +CIPEVENT:SOCKET,id,len,data
|
||||
* 8. +CIPEVENT:UDP_BROADCAST,ip,port,id,len,data
|
||||
*/
|
||||
static void net_event_handler(void *arg, char *buf, int buflen)
|
||||
{
|
||||
char c;
|
||||
char s[32] = {0};
|
||||
|
||||
at_read(&c, 1);
|
||||
if (c >= '0' && c < ('0' + LINK_ID_MAX)) {
|
||||
int link_id = c - '0';
|
||||
at_read(&c, 1);
|
||||
if (c != ',') {
|
||||
at_conn_hal_err("!!!Error: wrong CIPEVENT string. 0x%02x\r\n", c);
|
||||
return;
|
||||
}
|
||||
at_read(&c, 1);
|
||||
if (c == 'S') {
|
||||
at_conn_hal_debug("%s server conn state event, linkid: %d.", __func__, link_id);
|
||||
/* Eat the "ERVER," */
|
||||
at_read(s, 6);
|
||||
if (memcmp(s, "ERVER,", strlen("ERVER,")) != 0) {
|
||||
at_conn_hal_err("invalid event format 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
|
||||
s[0], s[1], s[2], s[3], s[4], s[5]);
|
||||
return;
|
||||
}
|
||||
handle_tcp_udp_client_conn_state(link_id);
|
||||
} else if (c == 'U') {
|
||||
at_conn_hal_debug("%s UDP conn state event.", __func__);
|
||||
/* Eat the "DP," */
|
||||
at_read(s, 3);
|
||||
if (memcmp(s, "DP,", strlen("DP,")) != 0) {
|
||||
at_conn_hal_err("%s invalid event format 0x%02x 0x%02x 0x%02x \r\n", __FUNCTION__, s[0], s[1], s[2]);
|
||||
return;
|
||||
}
|
||||
handle_tcp_udp_client_conn_state(link_id);
|
||||
} else {
|
||||
at_conn_hal_err( "!!!Error: wrong CIPEVENT string 0x%02x at line %d\r\n", c, __LINE__);
|
||||
return ;
|
||||
}
|
||||
} else if (c == 'S') {
|
||||
at_conn_hal_debug("%s socket data event.", __func__);
|
||||
handle_socket_data();
|
||||
} else {
|
||||
at_conn_hal_err("!!!Error: wrong CIPEVENT string received. 0x%02x\r\n", c);
|
||||
return;
|
||||
}
|
||||
|
||||
at_conn_hal_debug("%s exit.", __func__);
|
||||
}
|
||||
|
||||
static void mk3060_uart_echo_off()
|
||||
{
|
||||
char *at_echo_str = AT_CMD_EHCO_OFF;
|
||||
char out[64] = {0};
|
||||
|
||||
at_send_wait_reply(at_echo_str, strlen(AT_CMD_EHCO_OFF), true,
|
||||
NULL, 0, out, sizeof(out), NULL);
|
||||
at_conn_hal_debug("The AT response is: %s", out);
|
||||
if (strstr(out, CMD_FAIL_RSP) != NULL) {
|
||||
at_conn_hal_err("%s %d failed", __func__, __LINE__);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static uint8_t inited = 0;
|
||||
|
||||
#define NET_OOB_PREFIX "+CIPEVENT:"
|
||||
#define WIFIEVENT_OOB_PREFIX "+WEVENT:"
|
||||
int HAL_AT_CONN_Init(void)
|
||||
{
|
||||
int link;
|
||||
char cmd[STOP_AUTOCONN_CMD_LEN] = {0};
|
||||
char out[64] = {0};
|
||||
|
||||
if (inited) {
|
||||
at_conn_hal_warning("at_conn component is already initialized");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (NULL == (g_link_mutex = HAL_MutexCreate())) {
|
||||
at_conn_hal_err("Creating link mutex failed (%s %d).", __func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mk3060_uart_echo_off();
|
||||
|
||||
memset(g_link, 0, sizeof(g_link));
|
||||
for (link = 0; link < LINK_ID_MAX; link++) {
|
||||
g_link[link].fd = -1;
|
||||
/*close all link */
|
||||
HAL_Snprintf(cmd, STOP_CMD_LEN - 1, "%s=%d", STOP_CMD, link);
|
||||
at_conn_hal_debug("%s %d - AT cmd to run: %s", __func__, __LINE__, cmd);
|
||||
|
||||
at_send_wait_reply(cmd, strlen(cmd), true, NULL, 0, out,
|
||||
sizeof(out), NULL);
|
||||
at_conn_hal_debug("The AT response is: %s", out);
|
||||
if (strstr(out, CMD_FAIL_RSP) != NULL) {
|
||||
at_conn_hal_debug("%s %d failed", __func__, __LINE__);
|
||||
}
|
||||
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
|
||||
/*close all link auto reconnect */
|
||||
HAL_Snprintf(cmd, STOP_AUTOCONN_CMD_LEN - 1, "%s=%d,0", STOP_AUTOCONN_CMD, link);
|
||||
at_conn_hal_debug("%s %d - AT cmd to run: %s", __func__, __LINE__, cmd);
|
||||
|
||||
at_send_wait_reply(cmd, strlen(cmd), true, NULL, 0, out,
|
||||
sizeof(out), NULL);
|
||||
at_conn_hal_debug("The AT response is: %s", out);
|
||||
if (strstr(out, CMD_FAIL_RSP) != NULL) {
|
||||
at_conn_hal_err("%s %d failed", __func__, __LINE__);
|
||||
}
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
}
|
||||
|
||||
at_register_callback(NET_OOB_PREFIX, NULL, NULL, 0, net_event_handler, NULL);
|
||||
at_register_callback(WIFIEVENT_OOB_PREFIX, NULL, NULL, 0, mk3060wifi_event_handler, NULL);
|
||||
|
||||
if (at_connect_wifi(WIFI_SSID, WIFI_PWD, WIFI_TIMEOUT) < 0) {
|
||||
at_conn_hal_err("%s %d failed", __func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
inited = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HAL_AT_CONN_Deinit(void)
|
||||
{
|
||||
if (!inited) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
HAL_MutexDestroy(g_link_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define START_CMD "AT+CIPSTART"
|
||||
#define START_CMD_LEN (sizeof(START_CMD)+1+1+13+1+MAX_DOMAIN_LEN+1+5+1+5+1)
|
||||
static char *start_cmd_type_str[] = {"tcp_server", "tcp_client", \
|
||||
"ssl_client", "udp_broadcast", "udp_unicast"
|
||||
};
|
||||
|
||||
int HAL_AT_CONN_Start(at_conn_t *c)
|
||||
{
|
||||
int link_id;
|
||||
char cmd[START_CMD_LEN] = {0};
|
||||
char out[256] = {0};
|
||||
|
||||
if (!c || !c->addr) {
|
||||
at_conn_hal_err("%s %d - invalid argument", __func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
HAL_MutexLock(g_link_mutex);
|
||||
for (link_id = 0; link_id < LINK_ID_MAX; link_id++) {
|
||||
if (g_link[link_id].fd >= 0) {
|
||||
continue;
|
||||
} else {
|
||||
g_link[link_id].fd = c->fd;
|
||||
if (NULL == (g_link[link_id].sem_start = HAL_SemaphoreCreate())) {
|
||||
at_conn_hal_err("failed to allocate semaphore %s", __func__);
|
||||
g_link[link_id].fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == (g_link[link_id].sem_close = HAL_SemaphoreCreate())) {
|
||||
at_conn_hal_err("failed to allocate semaphore %s", __func__);
|
||||
HAL_SemaphoreDestroy(g_link[link_id].sem_start);
|
||||
g_link[link_id].fd = -1;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HAL_MutexUnlock(g_link_mutex);
|
||||
|
||||
/* The caller should deal with this failure */
|
||||
if (link_id >= LINK_ID_MAX) {
|
||||
at_conn_hal_info("No link available for now, %s failed.", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
at_conn_hal_debug("Creating %s connection ...", start_cmd_type_str[c->type]);
|
||||
|
||||
switch (c->type) {
|
||||
case TCP_CLIENT:
|
||||
HAL_Snprintf(cmd, START_CMD_LEN - 5 - 1, "%s=%d,%s,%s,%d",
|
||||
START_CMD, link_id, start_cmd_type_str[c->type],
|
||||
c->addr, c->r_port);
|
||||
if (c->l_port >= 0) {
|
||||
HAL_Snprintf(cmd + strlen(cmd), 7, ",%d", c->l_port);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
at_conn_hal_err("Invalid connection type.");
|
||||
goto err;
|
||||
}
|
||||
|
||||
at_conn_hal_debug("\r\n%s %d - AT cmd to run: %s \r\n", __func__, __LINE__, cmd);
|
||||
|
||||
at_send_wait_reply(cmd, strlen(cmd), true, NULL, 0, out,
|
||||
sizeof(out), NULL);
|
||||
at_conn_hal_debug("The AT response is: %s", out);
|
||||
if (strstr(out, CMD_FAIL_RSP) != NULL) {
|
||||
at_conn_hal_err("%s %d failed", __func__, __LINE__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (HAL_SemaphoreWait(g_link[link_id].sem_start, SEM_WAIT_DURATION) != 0) {
|
||||
at_conn_hal_err("%s sem_wait failed", __func__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
at_conn_hal_debug("%s sem_wait succeed.", __func__);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
HAL_MutexLock(g_link_mutex);
|
||||
if (g_link[link_id].sem_start) {
|
||||
HAL_SemaphoreDestroy(g_link[link_id].sem_start);
|
||||
}
|
||||
|
||||
if (g_link[link_id].sem_close) {
|
||||
HAL_SemaphoreDestroy(g_link[link_id].sem_close);
|
||||
}
|
||||
g_link[link_id].fd = -1;
|
||||
HAL_MutexUnlock(g_link_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int fd_to_linkid(int fd)
|
||||
{
|
||||
int link_id;
|
||||
|
||||
HAL_MutexLock(g_link_mutex);
|
||||
for (link_id = 0; link_id < LINK_ID_MAX; link_id++) {
|
||||
if (g_link[link_id].fd == fd) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HAL_MutexUnlock(g_link_mutex);
|
||||
|
||||
return link_id;
|
||||
}
|
||||
|
||||
#define SEND_CMD "AT+CIPSEND"
|
||||
#define SEND_CMD_LEN (sizeof(SEND_CMD)+1+1+5+1+DATA_LEN_MAX+1)
|
||||
int HAL_AT_CONN_Send(int fd,
|
||||
uint8_t *data,
|
||||
uint32_t len,
|
||||
char remote_ip[16],
|
||||
int32_t remote_port,
|
||||
int32_t timeout)
|
||||
{
|
||||
int link_id;
|
||||
char cmd[SEND_CMD_LEN] = {0}, out[128] = {0};
|
||||
|
||||
if (!data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
at_conn_hal_debug("%s on fd %d", __func__, fd);
|
||||
|
||||
link_id = fd_to_linkid(fd);
|
||||
if (link_id < 0 || link_id >= LINK_ID_MAX) {
|
||||
at_conn_hal_err("No connection found for fd (%d) in %s", fd, __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* AT+CIPSEND=id, */
|
||||
HAL_Snprintf(cmd, SEND_CMD_LEN - 1, "%s=%d,", SEND_CMD, link_id);
|
||||
/* [remote_port,] */
|
||||
if (remote_port >= 0) {
|
||||
HAL_Snprintf(cmd + strlen(cmd), 7, "%d,", remote_port);
|
||||
}
|
||||
/* data_length */
|
||||
HAL_Snprintf(cmd + strlen(cmd), DATA_LEN_MAX + 1, "%d", len);
|
||||
at_conn_hal_debug("\r\n%s %d - AT cmd to run: %s\r\n", __func__, __LINE__, cmd);
|
||||
|
||||
at_send_wait_reply((const char *)cmd, strlen(cmd), true, (const char *)data, len,
|
||||
out, sizeof(out), NULL);
|
||||
|
||||
at_conn_hal_debug("\r\nThe AT response is: %s\r\n", out);
|
||||
|
||||
if (strstr(out, CMD_FAIL_RSP) != NULL) {
|
||||
at_conn_hal_debug("%s %d failed", __func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DOMAIN_RSP "+CIPDOMAIN:"
|
||||
#define DOMAIN_CMD "AT+CIPDOMAIN"
|
||||
#define DOMAIN_CMD_LEN (sizeof(DOMAIN_CMD)+MAX_DOMAIN_LEN+1)
|
||||
/* Return the first IP if multiple found. */
|
||||
int HAL_AT_CONN_DomainToIp(char *domain,
|
||||
char ip[16])
|
||||
{
|
||||
char cmd[DOMAIN_CMD_LEN] = {0}, out[256] = {0}, *head, *end;
|
||||
|
||||
HAL_Snprintf(cmd, DOMAIN_CMD_LEN - 1, "%s=%s", DOMAIN_CMD, domain);
|
||||
at_conn_hal_debug("%s %d - AT cmd to run: %s", __func__, __LINE__, cmd);
|
||||
|
||||
at_send_wait_reply(cmd, strlen(cmd), true, NULL, 0, out,
|
||||
sizeof(out), NULL);
|
||||
at_conn_hal_debug("The AT response is: %s", out);
|
||||
if (strstr(out, AT_RECV_SUCCESS_POSTFIX) == NULL) {
|
||||
at_conn_hal_err("%s %d failed", __func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* +CIPDOMAIN:1\r\n
|
||||
* 180.97.33.108\r\n
|
||||
*
|
||||
* OK\r\n
|
||||
*/
|
||||
if ((head = strstr(out, DOMAIN_RSP)) == NULL) {
|
||||
at_conn_hal_err("No IP info found in result string %s \r\n.", out);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check the format */
|
||||
head += strlen(DOMAIN_RSP);
|
||||
if (head[0] < '0' && head[0] >= ('0' + LINK_ID_MAX)) {
|
||||
at_conn_hal_err("%s %d failed", __func__, __LINE__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
head++;
|
||||
if (memcmp(head, AT_RECV_PREFIX, strlen(AT_RECV_PREFIX)) != 0) {
|
||||
at_conn_hal_err("%s %d failed", __func__, __LINE__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* We find the IP head */
|
||||
head += strlen(AT_RECV_PREFIX);
|
||||
|
||||
end = head;
|
||||
while (((end - head) < 15) && (*end != '\r')) {
|
||||
end++;
|
||||
}
|
||||
if (((end - head) < 6) || ((end - head) > 15)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* We find a good IP, save it. */
|
||||
memcpy(ip, head, end - head);
|
||||
ip[end - head] = '\0';
|
||||
at_conn_hal_debug("get domain %s ip %s \r\n", domain, ip);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
at_conn_hal_err("Failed to get IP due to unexpected result string %s \r\n.", out);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int HAL_AT_CONN_Close(int fd,
|
||||
int32_t remote_port)
|
||||
{
|
||||
int link_id;
|
||||
char cmd[STOP_CMD_LEN] = {0}, out[64];
|
||||
|
||||
link_id = fd_to_linkid(fd);
|
||||
if (link_id < 0 || link_id >= LINK_ID_MAX) {
|
||||
at_conn_hal_err("No connection found for fd (%d) in %s", fd, __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
HAL_Snprintf(cmd, STOP_CMD_LEN - 1, "%s=%d", STOP_CMD, link_id);
|
||||
at_conn_hal_debug("%s %d - AT cmd to run: %s", __func__, __LINE__, cmd);
|
||||
|
||||
at_send_wait_reply(cmd, strlen(cmd), true, NULL, 0, out,
|
||||
sizeof(out), NULL);
|
||||
at_conn_hal_debug("The AT response is: %s", out);
|
||||
if (strstr(out, CMD_FAIL_RSP) != NULL) {
|
||||
at_conn_hal_err("%s %d failed", __func__, __LINE__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (HAL_SemaphoreWait(g_link[link_id].sem_close, SEM_WAIT_DURATION) != 0) {
|
||||
at_conn_hal_err("%s sem_wait failed", __func__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
at_conn_hal_debug("%s sem_wait succeed.", __func__);
|
||||
err:
|
||||
HAL_MutexLock(g_link_mutex);
|
||||
|
||||
if (g_link[link_id].sem_start) {
|
||||
HAL_SemaphoreDestroy(g_link[link_id].sem_start);
|
||||
}
|
||||
|
||||
if (g_link[link_id].sem_close) {
|
||||
HAL_SemaphoreDestroy(g_link[link_id].sem_close);
|
||||
}
|
||||
g_link[link_id].fd = -1;
|
||||
HAL_MutexUnlock(g_link_mutex);
|
||||
return -1;
|
||||
|
||||
}
|
870
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/atm/at_tcp/sim800.c
vendored
Normal file
870
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/atm/at_tcp/sim800.c
vendored
Normal file
@@ -0,0 +1,870 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "infra_config.h"
|
||||
#include "mqtt_api.h"
|
||||
|
||||
#include "at_wrapper.h"
|
||||
#include "at_parser.h"
|
||||
#include "at_api.h"
|
||||
|
||||
#define TAG "sim800_gprs_module"
|
||||
|
||||
#define SIM800_AT_CMD_SUCCESS_RSP "OK"
|
||||
#define SIM800_AT_CMD_FAIL_RSP "ERROR"
|
||||
#define AT_CMD_TEST "AT"
|
||||
#define AT_CMD_TEST_RESULT "OK\r\n"
|
||||
|
||||
#define AT_CMD_ECHO_OFF "ATE0"
|
||||
#define AT_CMD_BAUDRATE_SET "AT+IPR"
|
||||
#define AT_CMD_FLOW_CONTROL "AT+IFC"
|
||||
|
||||
#define AT_CMD_SAVE_CONFIG "AT&W"
|
||||
|
||||
#define AT_CMD_SIM_PIN_CHECK "AT+CPIN?"
|
||||
#define AT_CMD_SIGNAL_QUALITY_CHECK "AT+CSQ"
|
||||
#define AT_CMD_NETWORK_REG_CHECK "AT+CREG?"
|
||||
#define AT_CMD_GPRS_ATTACH_CHECK "AT+CGATT?"
|
||||
|
||||
#define AT_CMD_GPRS_PDP_DEACTIVE "AT+CIPSHUT"
|
||||
#define AT_CMD_MULTI_IP_CONNECTION "AT+CIPMUX"
|
||||
#define AT_CMD_SEND_DATA_PROMPT_SET "AT+CIPSPRT"
|
||||
#define AT_CMD_RECV_DATA_FORMAT_SET "AT+CIPSRIP"
|
||||
|
||||
#define AT_CMD_DOMAIN_TO_IP "AT+CDNSGIP"
|
||||
#define AT_CMD_DOMAIN_RSP "\r\n+CDNSGIP: "
|
||||
|
||||
#define AT_CMD_START_TASK "AT+CSTT"
|
||||
#define AT_CMD_BRING_UP_GPRS_CONNECT "AT+CIICR"
|
||||
#define AT_CMD_GOT_LOCAL_IP "AT+CIFSR"
|
||||
|
||||
#define AT_CMD_START_CLIENT_CONN "AT+CIPSTART"
|
||||
|
||||
#define AT_CMD_CLIENT_CONNECT_OK "CONNECT OK\r\n"
|
||||
#define AT_CMD_CLIENT_CONNECT_FAIL "CONNECT FAIL\r\n"
|
||||
|
||||
#define AT_CMD_STOP_CONN "AT+CIPCLOSE"
|
||||
|
||||
#define AT_CMD_SEND_DATA "AT+CIPSEND"
|
||||
|
||||
#define AT_CMD_DATA_RECV "\r\n+RECEIVE,"
|
||||
|
||||
#define SIM800_DEFAULT_CMD_LEN 64
|
||||
#define SIM800_DEFAULT_RSP_LEN 64
|
||||
|
||||
#define SIM800_MAX_LINK_NUM 6
|
||||
|
||||
#define SIM800_DOMAIN_MAX_LEN 64
|
||||
#define SIM800_DOMAIN_RSP_MAX_LEN 128
|
||||
#define SIM800_DOMAIN_CMD_LEN (sizeof(AT_CMD_DOMAIN_TO_IP) + SIM800_DOMAIN_MAX_LEN + 1)
|
||||
|
||||
#define SIM800_CONN_CMD_LEN (SIM800_DOMAIN_MAX_LEN + SIM800_DEFAULT_CMD_LEN)
|
||||
|
||||
#define SIM800_RETRY_MAX 50
|
||||
#define SIM800_WAIT_MAX_MS 10000
|
||||
|
||||
#ifdef AT_DEBUG_MODE
|
||||
#define at_conn_hal_err(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#define at_conn_hal_info(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#define at_conn_hal_debug(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#else
|
||||
#define at_conn_hal_err(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#define at_conn_hal_info(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#define at_conn_hal_debug(...)
|
||||
#endif
|
||||
|
||||
#define SIM800_MAX_PAYLOAD_SIZE (CONFIG_MQTT_MESSAGE_MAXLEN + CONFIG_MQTT_TOPIC_MAXLEN + 20)
|
||||
|
||||
#ifndef PLATFORM_HAS_DYNMEM
|
||||
static uint8_t payload[SIM800_MAX_PAYLOAD_SIZE] = {0};
|
||||
#endif
|
||||
|
||||
/* Change to include data slink for each link id respectively. <TODO> */
|
||||
typedef struct link_s {
|
||||
int fd;
|
||||
void* sem_start;
|
||||
void* sem_close;
|
||||
} link_t;
|
||||
|
||||
static uint8_t inited = 0;
|
||||
static link_t g_link[SIM800_MAX_LINK_NUM];
|
||||
static void *g_link_mutex;
|
||||
static void *g_domain_mutex;
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
static void *g_domain_sem;
|
||||
#else
|
||||
static int g_domain_mark = 0;
|
||||
#endif
|
||||
static char g_pcdomain_buf[SIM800_DOMAIN_RSP_MAX_LEN];
|
||||
static char g_pcdomain_rsp[SIM800_DOMAIN_RSP_MAX_LEN];
|
||||
static char g_pccmd[SIM800_CONN_CMD_LEN];
|
||||
static char g_cmd[SIM800_DEFAULT_CMD_LEN];
|
||||
static char g_rsp[SIM800_DEFAULT_RSP_LEN];
|
||||
|
||||
static int fd_to_linkid(int fd)
|
||||
{
|
||||
int link_id;
|
||||
|
||||
HAL_MutexLock(g_link_mutex);
|
||||
for (link_id = 0; link_id < SIM800_MAX_LINK_NUM; link_id++) {
|
||||
if (g_link[link_id].fd == fd) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HAL_MutexUnlock(g_link_mutex);
|
||||
|
||||
return link_id;
|
||||
}
|
||||
|
||||
static void sim800_gprs_domain_rsp_callback(void *arg, char *rspinfo, int rsplen)
|
||||
{
|
||||
if (NULL == rspinfo || rsplen == 0) {
|
||||
at_conn_hal_err( "invalid input at %s \r\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(g_pcdomain_rsp, rspinfo, rsplen);
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
HAL_SemaphorePost(g_domain_sem);
|
||||
#else
|
||||
g_domain_mark = 1;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
static void sim800_gprs_module_socket_data_handle(void *arg, char *rspinfo, int rsplen)
|
||||
{
|
||||
unsigned char uclinkid = 0;
|
||||
unsigned char unusesymbol = 0;
|
||||
unsigned char datalen[6] = {0};
|
||||
unsigned char ipaddr[16] = {0};
|
||||
unsigned char port[6] = {0};
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int len = 0;
|
||||
int remoteport = 0;
|
||||
int linkid = 0;
|
||||
char *recvdata = NULL;
|
||||
struct at_conn_input param;
|
||||
|
||||
at_read((char *)&uclinkid, 1);
|
||||
linkid = uclinkid - '0';
|
||||
if (linkid < 0 || linkid >= SIM800_MAX_LINK_NUM) {
|
||||
at_conn_hal_err( "Invalid link id 0x%02x !!!\r\n", linkid);
|
||||
return;
|
||||
}
|
||||
|
||||
/*eat , char*/
|
||||
at_read((char *)&unusesymbol, 1);
|
||||
|
||||
/* get data len */
|
||||
i = 0;
|
||||
do {
|
||||
at_read((char *)&datalen[i], 1);
|
||||
if (datalen[i] == ',') {
|
||||
break;
|
||||
}
|
||||
if (i >= sizeof(datalen)) {
|
||||
at_conn_hal_err( "Too long length of data.datalen is %s \r\n", datalen);
|
||||
return;
|
||||
}
|
||||
if (datalen[i] > '9' || datalen[i] < '0') {
|
||||
at_conn_hal_err( "Invalid len string!!!, datalen is %s \r\n", datalen);
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
} while (1);
|
||||
|
||||
/* len: string to number */
|
||||
for (j = 0; j < i; j++) {
|
||||
len = len * 10 + datalen[j] - '0';
|
||||
}
|
||||
|
||||
/*get ip addr and port*/
|
||||
i = 0;
|
||||
do {
|
||||
at_read((char *)&ipaddr[i], 1);
|
||||
if (ipaddr[i] == ':') {
|
||||
break;
|
||||
}
|
||||
if (i >= sizeof(ipaddr)) {
|
||||
at_conn_hal_err( "Too long length of ipaddr.ipaddr is %s \r\n", ipaddr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!((ipaddr[i] <= '9' && ipaddr[i] >= '0') || ipaddr[i] == '.')) {
|
||||
at_conn_hal_err( "Invalid ipaddr string!!!, ipaddr is %s \r\n", ipaddr);
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
} while (1);
|
||||
|
||||
ipaddr[i] = 0;
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
at_read((char *)&port[i], 1);
|
||||
if (port[i] == '\r') {
|
||||
break;
|
||||
}
|
||||
if (i >= sizeof(port)) {
|
||||
at_conn_hal_err( "Too long length of remote port.port is %s \r\n", port);
|
||||
return;
|
||||
}
|
||||
|
||||
if (port[i] > '9' || port[i] < '0') {
|
||||
at_conn_hal_err( "Invalid ipaddr string!!!, port is %s \r\n", port);
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
} while (1);
|
||||
|
||||
port[i] = 0;
|
||||
|
||||
/*eat \n char*/
|
||||
at_read((char *)&unusesymbol, 1);
|
||||
|
||||
for (j = 0; j < i; j++) {
|
||||
remoteport = remoteport * 10 + port[j] - '0';
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_HAS_DYNMEM
|
||||
/* Prepare socket data */
|
||||
recvdata = (char *)HAL_Malloc(len);
|
||||
#else
|
||||
if (len <= SIM800_MAX_PAYLOAD_SIZE) {
|
||||
recvdata = (char *)payload;
|
||||
}
|
||||
#endif
|
||||
if (!recvdata) {
|
||||
at_conn_hal_err( "Error: %s %d out of memory.", __func__, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(recvdata, 0, len);
|
||||
|
||||
at_read(recvdata, len);
|
||||
|
||||
if (g_link[linkid].fd >= 0) {
|
||||
param.fd = g_link[linkid].fd;
|
||||
param.data = recvdata;
|
||||
param.datalen = len;
|
||||
param.remote_ip = (char *)ipaddr;
|
||||
param.remote_port = remoteport;
|
||||
|
||||
/* TODO get recv data src ip and port*/
|
||||
if (IOT_ATM_Input(¶m) != 0) {
|
||||
at_conn_hal_err( " %s socket %d get data len %d fail to post to at_conn, drop it\n",
|
||||
__func__, g_link[linkid].fd, len);
|
||||
}
|
||||
}
|
||||
at_conn_hal_debug( "%s socket data on link %d with length %d posted to at_conn\n",
|
||||
__func__, linkid, len);
|
||||
#ifdef PLATFORM_HAS_DYNMEM
|
||||
HAL_Free(recvdata);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
static int sim800_send_with_retry(const char *cmd, int cmdlen, bool delimiter, const char *data,
|
||||
int datalen, char *rspbuf, int buflen, const char *expectrsp)
|
||||
{
|
||||
int retry = 0;
|
||||
|
||||
if (NULL == cmd || 0 == cmdlen || NULL == rspbuf ||
|
||||
0 == buflen || NULL == expectrsp) {
|
||||
at_conn_hal_err("Invalid input %s %d\r\n", __func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while(true) {
|
||||
retry++;
|
||||
memset(rspbuf, 0, buflen);
|
||||
at_send_wait_reply(cmd, cmdlen, delimiter, data, datalen, rspbuf, buflen, NULL);
|
||||
if (strstr(rspbuf, expectrsp) == NULL) {
|
||||
if (retry > SIM800_RETRY_MAX) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
at_conn_hal_err("%s %d cmd %s failed rsp %s retry count %d\r\n", __func__, __LINE__, cmd,rspbuf, retry);
|
||||
HAL_SleepMs(50);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sim800_uart_selfadaption(const char *command, const char *rsp, uint32_t rsplen)
|
||||
{
|
||||
char *buffer = g_rsp;
|
||||
|
||||
if (NULL == command || NULL == rsp || 0 == rsplen) {
|
||||
at_conn_hal_err( "invalid input %s %d\r\n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sim800_send_with_retry(command, strlen(command), true, NULL, 0,
|
||||
buffer, SIM800_DEFAULT_RSP_LEN, rsp) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sim800_uart_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
char *cmd = g_cmd;
|
||||
char *rsp = g_rsp;
|
||||
|
||||
/* uart baudrate self adaption*/
|
||||
ret = sim800_uart_selfadaption(AT_CMD_TEST, AT_CMD_TEST_RESULT, strlen(AT_CMD_TEST_RESULT));
|
||||
if (ret) {
|
||||
at_conn_hal_err( "sim800_uart_selfadaption fail \r\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
memset(rsp, 0, SIM800_DEFAULT_RSP_LEN);
|
||||
/*turn off echo*/
|
||||
at_send_wait_reply(AT_CMD_ECHO_OFF, strlen(AT_CMD_ECHO_OFF), true, NULL, 0,
|
||||
rsp, SIM800_DEFAULT_RSP_LEN, NULL);
|
||||
if (strstr(rsp, SIM800_AT_CMD_SUCCESS_RSP) == NULL) {
|
||||
at_conn_hal_err( "%s %d failed rsp %s\r\n", __func__, __LINE__, rsp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(cmd, 0, SIM800_DEFAULT_CMD_LEN);
|
||||
memset(rsp, 0, SIM800_DEFAULT_RSP_LEN);
|
||||
/*set baudrate 115200*/
|
||||
HAL_Snprintf(cmd, SIM800_DEFAULT_CMD_LEN - 1, "%s=%d", AT_CMD_BAUDRATE_SET, AT_UART_BAUDRATE);
|
||||
at_send_wait_reply(cmd, strlen(cmd), true, NULL, 0, rsp, SIM800_DEFAULT_RSP_LEN, NULL);
|
||||
if (strstr(rsp, SIM800_AT_CMD_SUCCESS_RSP) == NULL) {
|
||||
at_conn_hal_err( "%s %d failed rsp %s\r\n", __func__, __LINE__, rsp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(cmd, 0, SIM800_DEFAULT_CMD_LEN);
|
||||
memset(rsp, 0, SIM800_DEFAULT_RSP_LEN);
|
||||
/*turn off flow control*/
|
||||
HAL_Snprintf(cmd, SIM800_DEFAULT_CMD_LEN - 1, "%s=%d,%d", AT_CMD_FLOW_CONTROL, 0, 0);
|
||||
at_send_wait_reply(cmd, strlen(cmd), true, NULL, 0, rsp, SIM800_DEFAULT_RSP_LEN, NULL);
|
||||
if (strstr(rsp, SIM800_AT_CMD_SUCCESS_RSP) == NULL) {
|
||||
at_conn_hal_err( "%s %d failed rsp %s\r\n", __func__, __LINE__, rsp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(rsp, 0, SIM800_DEFAULT_RSP_LEN);
|
||||
/*save configuration */
|
||||
at_send_wait_reply(AT_CMD_SAVE_CONFIG, strlen(AT_CMD_SAVE_CONFIG), true, NULL, 0,
|
||||
rsp, SIM800_DEFAULT_RSP_LEN, NULL);
|
||||
if (strstr(rsp, SIM800_AT_CMD_SUCCESS_RSP) == NULL) {
|
||||
at_conn_hal_err( "%s %d failed rsp %s\r\n", __func__, __LINE__, rsp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sim800_gprs_status_check(void)
|
||||
{
|
||||
char *rsp = g_rsp;
|
||||
|
||||
/*sim card status check*/
|
||||
if (sim800_send_with_retry(AT_CMD_SIM_PIN_CHECK, strlen(AT_CMD_SIM_PIN_CHECK), true,
|
||||
NULL, 0, rsp, SIM800_DEFAULT_RSP_LEN, SIM800_AT_CMD_SUCCESS_RSP) < 0) {
|
||||
at_conn_hal_err("sim card status check failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(rsp, 0, SIM800_DEFAULT_RSP_LEN);
|
||||
/*Signal quaility check*/
|
||||
at_send_wait_reply(AT_CMD_SIGNAL_QUALITY_CHECK, strlen(AT_CMD_SIGNAL_QUALITY_CHECK), true,
|
||||
NULL, 0, rsp, SIM800_DEFAULT_RSP_LEN, NULL);
|
||||
if (strstr(rsp, SIM800_AT_CMD_SUCCESS_RSP) == NULL) {
|
||||
at_conn_hal_err( "%s %d failed rsp %s\r\n", __func__, __LINE__, rsp);
|
||||
return -1;
|
||||
}
|
||||
at_conn_hal_info( "signal quality is %s \r\n", rsp);
|
||||
|
||||
memset(rsp, 0, SIM800_DEFAULT_RSP_LEN);
|
||||
/*network registration check*/
|
||||
at_send_wait_reply(AT_CMD_NETWORK_REG_CHECK, strlen(AT_CMD_NETWORK_REG_CHECK), true,
|
||||
NULL, 0, rsp, SIM800_DEFAULT_RSP_LEN, NULL);
|
||||
if (strstr(rsp, SIM800_AT_CMD_SUCCESS_RSP) == NULL) {
|
||||
at_conn_hal_err( "%s %d failed rsp %s\r\n", __func__, __LINE__, rsp);
|
||||
return -1;
|
||||
}
|
||||
at_conn_hal_info( "network registration is %s \r\n", rsp);
|
||||
|
||||
|
||||
memset(rsp, 0, SIM800_DEFAULT_RSP_LEN);
|
||||
/*GPRS attach check*/
|
||||
at_send_wait_reply(AT_CMD_GPRS_ATTACH_CHECK, strlen(AT_CMD_GPRS_ATTACH_CHECK),true,
|
||||
NULL, 0, rsp, SIM800_DEFAULT_RSP_LEN, NULL);
|
||||
if (strstr(rsp, SIM800_AT_CMD_SUCCESS_RSP) == NULL) {
|
||||
at_conn_hal_err( "%s %d failed rsp %s\r\n", __func__, __LINE__, rsp);
|
||||
return -1;
|
||||
}
|
||||
at_conn_hal_info( "gprs attach check %s \r\n", rsp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sim800_gprs_ip_init(void)
|
||||
{
|
||||
char *cmd = g_cmd;
|
||||
char *rsp = g_rsp;
|
||||
|
||||
/*Deactivate GPRS PDP Context*/
|
||||
if (sim800_send_with_retry(AT_CMD_GPRS_PDP_DEACTIVE, strlen(AT_CMD_GPRS_PDP_DEACTIVE), true,
|
||||
NULL, 0, rsp, SIM800_DEFAULT_RSP_LEN, SIM800_AT_CMD_SUCCESS_RSP) < 0) {
|
||||
at_conn_hal_err("Deactivate GPRS PDP Context failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*set multi ip connection mode*/
|
||||
memset(cmd, 0, SIM800_DEFAULT_CMD_LEN);
|
||||
memset(rsp, 0, SIM800_DEFAULT_RSP_LEN);
|
||||
HAL_Snprintf(cmd, SIM800_DEFAULT_CMD_LEN - 1, "%s=%d", AT_CMD_MULTI_IP_CONNECTION, 1);
|
||||
at_send_wait_reply(cmd, strlen(cmd), true, NULL, 0,
|
||||
rsp, SIM800_DEFAULT_RSP_LEN, NULL);
|
||||
if (strstr(rsp, SIM800_AT_CMD_SUCCESS_RSP) == NULL) {
|
||||
at_conn_hal_err( "%s %d failed rsp %s\r\n", __func__, __LINE__, rsp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*not prompt echo > when sending data*/
|
||||
memset(rsp, 0, SIM800_DEFAULT_RSP_LEN);
|
||||
memset(cmd, 0, SIM800_DEFAULT_CMD_LEN);
|
||||
HAL_Snprintf(cmd, SIM800_DEFAULT_CMD_LEN - 1, "%s=%d", AT_CMD_SEND_DATA_PROMPT_SET, 0);
|
||||
at_send_wait_reply(cmd, strlen(cmd), true, NULL, 0,
|
||||
rsp, SIM800_DEFAULT_RSP_LEN, NULL);
|
||||
if (strstr(rsp, SIM800_AT_CMD_SUCCESS_RSP) == NULL) {
|
||||
at_conn_hal_err( "%s %d failed rsp %s\r\n", __func__, __LINE__, rsp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*Show Remote ip and port when receive data*/
|
||||
memset(rsp, 0, SIM800_DEFAULT_RSP_LEN);
|
||||
memset(cmd, 0, SIM800_DEFAULT_CMD_LEN);
|
||||
HAL_Snprintf(cmd, SIM800_DEFAULT_CMD_LEN - 1, "%s=%d", AT_CMD_RECV_DATA_FORMAT_SET, 1);
|
||||
at_send_wait_reply(cmd, strlen(cmd), true, NULL, 0, rsp, SIM800_DEFAULT_RSP_LEN, NULL);
|
||||
if (strstr(rsp, SIM800_AT_CMD_SUCCESS_RSP) == NULL) {
|
||||
at_conn_hal_err( "%s %d failed rsp %s\r\n", __func__, __LINE__, rsp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sim800_gprs_got_ip(void)
|
||||
{
|
||||
char *rsp = g_rsp;
|
||||
atcmd_config_t atcmd_config = {NULL, AT_RECV_PREFIX, NULL};
|
||||
|
||||
/*start gprs stask*/
|
||||
if (sim800_send_with_retry(AT_CMD_START_TASK, strlen(AT_CMD_START_TASK), true,
|
||||
NULL, 0, rsp, SIM800_DEFAULT_RSP_LEN, SIM800_AT_CMD_SUCCESS_RSP) < 0) {
|
||||
at_conn_hal_err("%s %d failed rsp %s\r\n", __func__, __LINE__, rsp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*bring up wireless connectiong with gprs*/
|
||||
memset(rsp, 0, SIM800_DEFAULT_RSP_LEN);
|
||||
at_send_wait_reply(AT_CMD_BRING_UP_GPRS_CONNECT, strlen(AT_CMD_BRING_UP_GPRS_CONNECT), true,
|
||||
NULL, 0, rsp, SIM800_DEFAULT_RSP_LEN, NULL);
|
||||
if (strstr(rsp, SIM800_AT_CMD_SUCCESS_RSP) == NULL) {
|
||||
at_conn_hal_err( "%s %d failed rsp %s\r\n", __func__, __LINE__, rsp);
|
||||
}
|
||||
|
||||
/*try to got ip*/
|
||||
memset(rsp, 0, SIM800_DEFAULT_RSP_LEN);
|
||||
at_send_wait_reply(AT_CMD_GOT_LOCAL_IP, strlen(AT_CMD_GOT_LOCAL_IP), true, NULL, 0,
|
||||
rsp, SIM800_DEFAULT_RSP_LEN, &atcmd_config);
|
||||
if (strstr(rsp, SIM800_AT_CMD_FAIL_RSP) != NULL) {
|
||||
at_conn_hal_err( "%s %d failed rsp %s\r\n", __func__, __LINE__, rsp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sim800_gprs_get_ip_only()
|
||||
{
|
||||
char *rsp = g_rsp;
|
||||
atcmd_config_t atcmd_config = {NULL, AT_RECV_PREFIX, NULL};
|
||||
|
||||
memset(rsp, 0, SIM800_DEFAULT_RSP_LEN);
|
||||
at_send_wait_reply(AT_CMD_GOT_LOCAL_IP, strlen(AT_CMD_GOT_LOCAL_IP), true,
|
||||
NULL, 0, rsp, SIM800_DEFAULT_RSP_LEN, &atcmd_config);
|
||||
if (strstr(rsp, SIM800_AT_CMD_FAIL_RSP) != NULL) {
|
||||
at_conn_hal_err( "%s %d failed rsp %s\r\n", __func__, __LINE__, rsp);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HAL_AT_CONN_Init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t linknum = 0;
|
||||
|
||||
if (inited) {
|
||||
at_conn_hal_info( "sim800 gprs module have already inited \r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(g_pcdomain_rsp , 0, SIM800_DOMAIN_RSP_MAX_LEN);
|
||||
|
||||
if (NULL == (g_link_mutex = HAL_MutexCreate())) {
|
||||
at_conn_hal_err( "Creating link mutex failed (%s %d).", __func__, __LINE__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (NULL == (g_domain_mutex = HAL_MutexCreate())) {
|
||||
at_conn_hal_err( "Creating link mutex failed (%s %d).", __func__, __LINE__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
if (NULL == (g_domain_sem = HAL_SemaphoreCreate())) {
|
||||
at_conn_hal_err( "Creating domain mutex failed (%s %d).", __func__, __LINE__);
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(g_link, 0, sizeof(g_link));
|
||||
|
||||
for (linknum = 0; linknum < SIM800_MAX_LINK_NUM; linknum++) {
|
||||
g_link[linknum].fd = -1;
|
||||
}
|
||||
|
||||
ret = sim800_uart_init();
|
||||
if (ret) {
|
||||
at_conn_hal_err( "%s %d failed \r\n", __func__, __LINE__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = sim800_gprs_status_check();
|
||||
if (ret) {
|
||||
at_conn_hal_err( "%s %d failed \r\n", __func__, __LINE__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = sim800_gprs_ip_init();
|
||||
if (ret) {
|
||||
at_conn_hal_err( "%s %d failed \r\n", __func__, __LINE__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* reg oob for domain and packet input*/
|
||||
at_register_callback(AT_CMD_DOMAIN_RSP, AT_RECV_PREFIX, g_pcdomain_buf, SIM800_DOMAIN_RSP_MAX_LEN,
|
||||
sim800_gprs_domain_rsp_callback, NULL);
|
||||
at_register_callback(AT_CMD_DATA_RECV, NULL, NULL, 0, sim800_gprs_module_socket_data_handle, NULL);
|
||||
ret = sim800_gprs_got_ip();
|
||||
if (ret) {
|
||||
at_conn_hal_err( "%s %d failed \r\n", __func__, __LINE__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
inited = 1;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
if (g_link_mutex != NULL) {
|
||||
HAL_MutexDestroy(g_link_mutex);
|
||||
}
|
||||
|
||||
if (g_domain_mutex != NULL) {
|
||||
HAL_MutexDestroy(g_domain_mutex);
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
if (g_domain_sem != NULL) {
|
||||
HAL_SemaphoreDestroy(g_domain_sem);
|
||||
}
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int HAL_AT_CONN_Deinit()
|
||||
{
|
||||
if (!inited) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
HAL_MutexDestroy(g_link_mutex);
|
||||
inited = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_HAS_OS
|
||||
static uint64_t _get_time_ms(void)
|
||||
{
|
||||
return HAL_UptimeMs();
|
||||
}
|
||||
|
||||
static uint64_t _time_left(uint64_t t_end, uint64_t t_now)
|
||||
{
|
||||
uint64_t t_left;
|
||||
|
||||
if (t_end > t_now) {
|
||||
t_left = t_end - t_now;
|
||||
} else {
|
||||
t_left = 0;
|
||||
}
|
||||
|
||||
return t_left;
|
||||
}
|
||||
#endif
|
||||
|
||||
int HAL_AT_CONN_DomainToIp(char *domain, char ip[16])
|
||||
{
|
||||
char *pccmd = NULL;
|
||||
char *head = NULL;
|
||||
char *end = NULL;
|
||||
char *rsp = g_rsp;
|
||||
int count = 0;
|
||||
#ifndef PLATFORM_HAS_OS
|
||||
uint64_t t_end, t_left;
|
||||
#endif
|
||||
|
||||
if (!inited) {
|
||||
at_conn_hal_err( "%s sim800 gprs module haven't init yet \r\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == domain || NULL == ip) {
|
||||
at_conn_hal_err( "invalid input at %s \r\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strlen(domain) > SIM800_DOMAIN_MAX_LEN) {
|
||||
at_conn_hal_err( "domain length oversize at %s \r\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pccmd = g_pccmd;
|
||||
if (NULL == pccmd) {
|
||||
at_conn_hal_err( "fail to malloc memory %d at %s \r\n", SIM800_DOMAIN_CMD_LEN, __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(pccmd, 0, SIM800_DOMAIN_CMD_LEN);
|
||||
HAL_Snprintf(pccmd, SIM800_DOMAIN_CMD_LEN - 1, "%s=%s", AT_CMD_DOMAIN_TO_IP, domain);
|
||||
|
||||
HAL_MutexLock(g_domain_mutex);
|
||||
restart:
|
||||
count++;
|
||||
if (count > SIM800_RETRY_MAX) {
|
||||
at_conn_hal_err( "domain to ip retry failed!\r\n");
|
||||
HAL_MutexUnlock(g_domain_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(rsp, 0, SIM800_DEFAULT_RSP_LEN);
|
||||
at_send_wait_reply(pccmd, strlen(pccmd), true, NULL, 0, rsp,
|
||||
SIM800_DEFAULT_RSP_LEN, NULL);
|
||||
if (strstr(rsp, SIM800_AT_CMD_SUCCESS_RSP) == NULL) {
|
||||
at_conn_hal_err( "%s %d failed rsp %s\r\n", __func__, __LINE__, rsp);
|
||||
goto err;
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_HAS_OS
|
||||
HAL_SemaphoreWait(g_domain_sem, SIM800_WAIT_MAX_MS);
|
||||
#else
|
||||
t_end = _get_time_ms() + SIM800_WAIT_MAX_MS;
|
||||
while(!g_domain_mark) {
|
||||
at_yield(NULL, 0, NULL, 100);
|
||||
|
||||
t_left = _time_left(t_end, _get_time_ms());
|
||||
if (0 == t_left) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_domain_mark = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* formate is :
|
||||
+CDNSGIP: 1,"www.baidu.com","183.232.231.173","183.232.231.172"
|
||||
or :
|
||||
+CDNSGIP: 0,8
|
||||
*/
|
||||
if ((head = strstr(g_pcdomain_rsp, domain)) == NULL) {
|
||||
at_conn_hal_err( "invalid domain rsp %s at %d\r\n", g_pcdomain_rsp, __LINE__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
head += (strlen(domain) + 3);
|
||||
if ((end = strstr(head, "\"")) == NULL) {
|
||||
at_conn_hal_err( "invalid domain rsp head is %s at %d\r\n", head, __LINE__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((end - head) > 15 || (end - head) < 7) {
|
||||
at_conn_hal_err( "invalid domain rsp head is %s at %d\r\n", head, __LINE__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* We find a good IP, save it. */
|
||||
memcpy(ip, head, end - head);
|
||||
ip[end - head] = '\0';
|
||||
memset(g_pcdomain_rsp, 0, SIM800_DOMAIN_RSP_MAX_LEN);
|
||||
HAL_MutexUnlock(g_domain_mutex);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
if (sim800_gprs_get_ip_only() != 0) {
|
||||
sim800_gprs_ip_init();
|
||||
sim800_gprs_got_ip();
|
||||
goto restart;
|
||||
}
|
||||
|
||||
memset(g_pcdomain_rsp, 0, SIM800_DOMAIN_RSP_MAX_LEN);
|
||||
HAL_MutexUnlock(g_domain_mutex);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int HAL_AT_CONN_Start(at_conn_t *conn)
|
||||
{
|
||||
int linkid = 0;
|
||||
char *pccmd = NULL;
|
||||
char *rsp = g_rsp;
|
||||
atcmd_config_t atcmd_config_client = { NULL, AT_CMD_CLIENT_CONNECT_OK, AT_CMD_CLIENT_CONNECT_FAIL};
|
||||
|
||||
if (!inited) {
|
||||
at_conn_hal_err( "%s sim800 gprs module haven't init yet \r\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!conn || !conn->addr) {
|
||||
at_conn_hal_err( "%s %d - invalid input \r\n", __func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
HAL_MutexLock(g_link_mutex);
|
||||
for (linkid = 0; linkid < SIM800_MAX_LINK_NUM; linkid++) {
|
||||
if (g_link[linkid].fd >= 0) {
|
||||
continue;
|
||||
}
|
||||
g_link[linkid].fd = conn->fd;
|
||||
break;
|
||||
}
|
||||
HAL_MutexUnlock(g_link_mutex);
|
||||
|
||||
if (linkid >= SIM800_MAX_LINK_NUM) {
|
||||
at_conn_hal_err( "No link available for now, %s failed. \r\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pccmd = g_pccmd;
|
||||
if (NULL == pccmd) {
|
||||
at_conn_hal_err( "fail to malloc %d at %s \r\n", SIM800_CONN_CMD_LEN, __func__);
|
||||
goto err;
|
||||
}
|
||||
memset(pccmd, 0, SIM800_CONN_CMD_LEN);
|
||||
memset(rsp, 0, SIM800_DEFAULT_RSP_LEN);
|
||||
|
||||
switch (conn->type) {
|
||||
case TCP_CLIENT:
|
||||
HAL_Snprintf(pccmd, SIM800_CONN_CMD_LEN - 1, "%s=%d,\"TCP\",\"%s\",%d", AT_CMD_START_CLIENT_CONN, linkid, conn->addr,
|
||||
conn->r_port);
|
||||
|
||||
at_send_wait_reply(pccmd, strlen(pccmd), true, NULL, 0, rsp, SIM800_DEFAULT_RSP_LEN,
|
||||
&atcmd_config_client);
|
||||
if (strstr(rsp, AT_CMD_CLIENT_CONNECT_FAIL) != NULL) {
|
||||
at_conn_hal_err( "pccmd %s fail, rsp %s \r\n", pccmd, rsp);
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
at_conn_hal_err( "sim800 gprs module connect type %d not support \r\n", conn->type);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
HAL_MutexLock(g_link_mutex);
|
||||
g_link[linkid].fd = -1;
|
||||
HAL_MutexUnlock(g_link_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int HAL_AT_CONN_Close(int fd, int32_t remote_port)
|
||||
{
|
||||
int linkid = 0;
|
||||
int ret = 0;
|
||||
char *cmd = g_cmd;
|
||||
char *rsp = g_rsp;
|
||||
|
||||
if (!inited) {
|
||||
at_conn_hal_err( "%s sim800 gprs module haven't init yet \r\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
linkid = fd_to_linkid(fd);
|
||||
if (linkid < 0 || linkid >= SIM800_MAX_LINK_NUM) {
|
||||
at_conn_hal_err( "No connection found for fd (%d) in %s \r\n", fd, __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(cmd, 0, SIM800_DEFAULT_CMD_LEN);
|
||||
memset(rsp, 0, SIM800_DEFAULT_RSP_LEN);
|
||||
HAL_Snprintf(cmd, SIM800_DEFAULT_CMD_LEN - 1, "%s=%d", AT_CMD_STOP_CONN, linkid);
|
||||
at_send_wait_reply(cmd, strlen(cmd), true, NULL, 0,
|
||||
rsp, SIM800_DEFAULT_RSP_LEN, NULL);
|
||||
if (strstr(rsp, SIM800_AT_CMD_SUCCESS_RSP) == NULL) {
|
||||
at_conn_hal_err( "cmd %s rsp is %s \r\n", cmd, rsp);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
HAL_MutexLock(g_link_mutex);
|
||||
g_link[linkid].fd = -1;
|
||||
HAL_MutexUnlock(g_link_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int HAL_AT_CONN_Send(int fd,
|
||||
uint8_t *data,
|
||||
uint32_t len,
|
||||
char remote_ip[16],
|
||||
int32_t remote_port,
|
||||
int32_t timeout)
|
||||
{
|
||||
int linkid;
|
||||
char *cmd = g_cmd;
|
||||
char *rsp = g_rsp;
|
||||
|
||||
if (!inited) {
|
||||
at_conn_hal_err( "%s sim800 gprs module haven't init yet \r\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
linkid = fd_to_linkid(fd);
|
||||
if (linkid < 0 || linkid >= SIM800_MAX_LINK_NUM) {
|
||||
at_conn_hal_err( "No connection found for fd (%d) in %s \r\n", fd, __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(cmd, 0, SIM800_DEFAULT_CMD_LEN);
|
||||
HAL_Snprintf(cmd, SIM800_DEFAULT_CMD_LEN - 1, "%s=%d,%d", AT_CMD_SEND_DATA, linkid, len);
|
||||
|
||||
if (sim800_send_with_retry((const char *)cmd, strlen(cmd), true, (const char *)data, len,
|
||||
rsp, SIM800_DEFAULT_RSP_LEN, SIM800_AT_CMD_SUCCESS_RSP) < 0) {
|
||||
at_conn_hal_err("cmd %s rsp %s at %s %d failed \r\n", cmd, rsp, __func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
12
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/iot.mk
vendored
Normal file
12
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/iot.mk
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
LIBA_TARGET := libiot_hal.a
|
||||
CFLAGS := $(filter-out -ansi,$(CFLAGS))
|
||||
|
||||
LIB_SRCS_PATTERN += os/$(CONFIG_VENDOR)/*.c
|
||||
|
||||
$(call Append_Conditional, LIB_SRCS_PATTERN, tls/*.c, _PLATFORM_IS_LINUX_ SUPPORT_TLS)
|
||||
$(call Append_Conditional, LIB_SRCS_PATTERN, tls/*.c, _PLATFORM_IS_LINUX_ COAP_DTLS_SUPPORT)
|
||||
$(call Append_Conditional, LIB_SRCS_PATTERN, atm/at_tcp/mk3060.c, AT_TCP_ENABLED AT_TCP_HAL_MK3060)
|
||||
$(call Append_Conditional, LIB_SRCS_PATTERN, atm/at_tcp/sim800.c, AT_TCP_ENABLED AT_TCP_HAL_SIM800)
|
||||
$(call Append_Conditional, LIB_SRCS_PATTERN, atm/at_mqtt/mqtt_ica.c, AT_MQTT_ENABLED AT_MQTT_HAL_ICA)
|
||||
$(call Append_Conditional, LIB_SRCS_PATTERN, atm/at_mqtt/mqtt_sim800.c, AT_MQTT_ENABLED AT_MQTT_HAL_SIM800)
|
||||
$(call Append_Conditional, LIB_SRCS_EXCLUDE, os/ubuntu/HAL_UART_linux.c, , AT_PARSER_ENABLED)
|
19
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/iotx_hal_internal.h
vendored
Normal file
19
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/iotx_hal_internal.h
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef __PLATFORM_DEBUG_H__
|
||||
#define __PLATFORM_DEBUG_H__
|
||||
|
||||
#include "iotx_log.h"
|
||||
|
||||
#define hal_emerg(...) HAL_Printf("[prt] "), HAL_Printf(__VA_ARGS__), HAL_Printf("\r\n")
|
||||
#define hal_crit(...) HAL_Printf("[prt] "), HAL_Printf(__VA_ARGS__), HAL_Printf("\r\n")
|
||||
#define hal_err(...) HAL_Printf("[prt] "), HAL_Printf(__VA_ARGS__), HAL_Printf("\r\n")
|
||||
#define hal_warning(...) HAL_Printf("[prt] "), HAL_Printf(__VA_ARGS__), HAL_Printf("\r\n")
|
||||
#define hal_info(...) HAL_Printf("[prt] "), HAL_Printf(__VA_ARGS__), HAL_Printf("\r\n")
|
||||
#define hal_debug(...) HAL_Printf("[prt] "), HAL_Printf(__VA_ARGS__), HAL_Printf("\r\n")
|
||||
|
||||
#endif /* __PLATFORM_DEBUG_H__ */
|
||||
|
||||
|
354
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/freertos/HAL_OS_Freertos.c
vendored
Normal file
354
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/freertos/HAL_OS_Freertos.c
vendored
Normal file
@@ -0,0 +1,354 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "infra_types.h"
|
||||
#include "infra_defs.h"
|
||||
#include "wrappers_defs.h"
|
||||
|
||||
#define HAL_SEM_MAX_COUNT (10)
|
||||
#define HAL_SEM_INIT_COUNT (0)
|
||||
|
||||
#define DEFAULT_THREAD_NAME "linkkit_task"
|
||||
#define DEFAULT_THREAD_SIZE (256)
|
||||
#define TASK_STACK_ALIGN_SIZE (4)
|
||||
|
||||
/**
|
||||
* @brief Deallocate memory block
|
||||
*
|
||||
* @param[in] ptr @n Pointer to a memory block previously allocated with platform_malloc.
|
||||
* @return None.
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
void HAL_Free(void *ptr)
|
||||
{
|
||||
vPortFree(ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocates a block of size bytes of memory, returning a pointer to the beginning of the block.
|
||||
*
|
||||
* @param [in] size @n specify block size in bytes.
|
||||
* @return A pointer to the beginning of the block.
|
||||
* @see None.
|
||||
* @note Block value is indeterminate.
|
||||
*/
|
||||
void *HAL_Malloc(uint32_t size)
|
||||
{
|
||||
return pvPortMalloc(size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a mutex.
|
||||
*
|
||||
* @retval NULL : Initialize mutex failed.
|
||||
* @retval NOT_NULL : The mutex handle.
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
void *HAL_MutexCreate(void)
|
||||
{
|
||||
QueueHandle_t sem;
|
||||
|
||||
sem = xSemaphoreCreateMutex();
|
||||
if (0 == sem) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sem;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destroy the specified mutex object, it will release related resource.
|
||||
*
|
||||
* @param [in] mutex @n The specified mutex.
|
||||
* @return None.
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
void HAL_MutexDestroy(void *mutex)
|
||||
{
|
||||
QueueHandle_t sem;
|
||||
if (mutex == NULL) {
|
||||
return;
|
||||
}
|
||||
sem = (QueueHandle_t)mutex;
|
||||
vSemaphoreDelete(sem);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Waits until the specified mutex is in the signaled state.
|
||||
*
|
||||
* @param [in] mutex @n the specified mutex.
|
||||
* @return None.
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
void HAL_MutexLock(void *mutex)
|
||||
{
|
||||
BaseType_t ret;
|
||||
QueueHandle_t sem;
|
||||
if (mutex == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
sem = (QueueHandle_t)mutex;
|
||||
ret = xSemaphoreTake(sem, 0xffffffff);
|
||||
while (pdPASS != ret) {
|
||||
ret = xSemaphoreTake(sem, 0xffffffff);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Releases ownership of the specified mutex object..
|
||||
*
|
||||
* @param [in] mutex @n the specified mutex.
|
||||
* @return None.
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
void HAL_MutexUnlock(void *mutex)
|
||||
{
|
||||
QueueHandle_t sem;
|
||||
if (mutex == NULL) {
|
||||
return;
|
||||
}
|
||||
sem = (QueueHandle_t)mutex;
|
||||
(void)xSemaphoreGive(sem);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes formatted data to stream.
|
||||
*
|
||||
* @param [in] fmt: @n String that contains the text to be written, it can optionally contain embedded format specifiers
|
||||
that specifies how subsequent arguments are converted for output.
|
||||
* @param [in] ...: @n the variable argument list, for formatted and inserted in the resulting string replacing their respective specifiers.
|
||||
* @return None.
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
void HAL_Printf(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief create a semaphore
|
||||
*
|
||||
* @return semaphore handle.
|
||||
* @see None.
|
||||
* @note The recommended value of maximum count of the semaphore is 255.
|
||||
*/
|
||||
void *HAL_SemaphoreCreate(void)
|
||||
{
|
||||
QueueHandle_t sem = 0;
|
||||
sem = xSemaphoreCreateCounting(HAL_SEM_MAX_COUNT, HAL_SEM_INIT_COUNT);
|
||||
if (0 == sem) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sem;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief destory a semaphore
|
||||
*
|
||||
* @param[in] sem @n the specified sem.
|
||||
* @return None.
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
void HAL_SemaphoreDestroy(void *sem)
|
||||
{
|
||||
QueueHandle_t queue;
|
||||
|
||||
if (sem == NULL) {
|
||||
return;
|
||||
}
|
||||
queue = (QueueHandle_t)sem;
|
||||
|
||||
vSemaphoreDelete(queue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief signal thread wait on a semaphore
|
||||
*
|
||||
* @param[in] sem @n the specified semaphore.
|
||||
* @return None.
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
void HAL_SemaphorePost(void *sem)
|
||||
{
|
||||
QueueHandle_t queue;
|
||||
if (sem == NULL) {
|
||||
return;
|
||||
}
|
||||
queue = (QueueHandle_t)sem;
|
||||
(void)xSemaphoreGive(queue);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief wait on a semaphore
|
||||
*
|
||||
* @param[in] sem @n the specified semaphore.
|
||||
* @param[in] timeout_ms @n timeout interval in millisecond.
|
||||
If timeout_ms is PLATFORM_WAIT_INFINITE, the function will return only when the semaphore is signaled.
|
||||
* @return
|
||||
@verbatim
|
||||
= 0: The state of the specified object is signaled.
|
||||
= -1: The time-out interval elapsed, and the object's state is nonsignaled.
|
||||
@endverbatim
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
int HAL_SemaphoreWait(void *sem, uint32_t timeout_ms)
|
||||
{
|
||||
BaseType_t ret = 0;
|
||||
QueueHandle_t queue;
|
||||
if (sem == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
queue = (QueueHandle_t)sem;
|
||||
ret = xSemaphoreTake(queue, timeout_ms);
|
||||
if (pdPASS != ret) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sleep thread itself.
|
||||
*
|
||||
* @param [in] ms @n the time interval for which execution is to be suspended, in milliseconds.
|
||||
* @return None.
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
void HAL_SleepMs(uint32_t ms)
|
||||
{
|
||||
osDelay(ms);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes formatted data to string.
|
||||
*
|
||||
* @param [out] str: @n String that holds written text.
|
||||
* @param [in] len: @n Maximum length of character will be written
|
||||
* @param [in] fmt: @n Format that contains the text to be written, it can optionally contain embedded format specifiers
|
||||
that specifies how subsequent arguments are converted for output.
|
||||
* @param [in] ...: @n the variable argument list, for formatted and inserted in the resulting string replacing their respective specifiers.
|
||||
* @return bytes of character successfully written into string.
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
int HAL_Snprintf(char *str, const int len, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int rc;
|
||||
|
||||
va_start(args, fmt);
|
||||
rc = vsnprintf(str, len, fmt, args);
|
||||
va_end(args);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief create a thread
|
||||
*
|
||||
* @param[out] thread_handle @n The new thread handle, memory allocated before thread created and return it, free it after thread joined or exit.
|
||||
* @param[in] start_routine @n A pointer to the application-defined function to be executed by the thread.
|
||||
This pointer represents the starting address of the thread.
|
||||
* @param[in] arg @n A pointer to a variable to be passed to the start_routine.
|
||||
* @param[in] hal_os_thread_param @n A pointer to stack params.
|
||||
* @param[out] stack_used @n if platform used stack buffer, set stack_used to 1, otherwise set it to 0.
|
||||
* @return
|
||||
@verbatim
|
||||
= 0: on success.
|
||||
= -1: error occur.
|
||||
@endverbatim
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
int HAL_ThreadCreate(
|
||||
void **thread_handle,
|
||||
void *(*work_routine)(void *),
|
||||
void *arg,
|
||||
hal_os_thread_param_t *hal_os_thread_param,
|
||||
int *stack_used)
|
||||
{
|
||||
char *name;
|
||||
size_t stacksize;
|
||||
osThreadDef_t thread_def;
|
||||
|
||||
osThreadId handle;
|
||||
|
||||
if (thread_handle == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (work_routine == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hal_os_thread_param == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (stack_used == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stack_used != NULL) {
|
||||
*stack_used = 0;
|
||||
}
|
||||
|
||||
if (!hal_os_thread_param->name) {
|
||||
name = DEFAULT_THREAD_NAME;
|
||||
} else {
|
||||
name = hal_os_thread_param->name;
|
||||
}
|
||||
|
||||
if (hal_os_thread_param->stack_size == 0) {
|
||||
stacksize = DEFAULT_THREAD_SIZE;
|
||||
} else {
|
||||
stacksize = hal_os_thread_param->stack_size;
|
||||
}
|
||||
|
||||
thread_def.name = name;
|
||||
thread_def.pthread = (os_pthread)work_routine;
|
||||
thread_def.tpriority = (osPriority)hal_os_thread_param->priority;
|
||||
thread_def.instances = 0;
|
||||
thread_def.stacksize = (stacksize + TASK_STACK_ALIGN_SIZE - 1) / TASK_STACK_ALIGN_SIZE;
|
||||
|
||||
handle = osThreadCreate(&thread_def, arg);
|
||||
if (NULL == handle) {
|
||||
return -1;
|
||||
}
|
||||
*thread_handle = (void *)handle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves the number of milliseconds that have elapsed since the system was boot.
|
||||
*
|
||||
* @return the number of milliseconds.
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
uint64_t HAL_UptimeMs(void)
|
||||
{
|
||||
return (uint64_t)xTaskGetTickCount();
|
||||
}
|
||||
|
135
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/nos/HAL_Nos.c
vendored
Normal file
135
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/nos/HAL_Nos.c
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include "infra_types.h"
|
||||
#include "infra_defs.h"
|
||||
#include "wrappers_defs.h"
|
||||
|
||||
/**
|
||||
* @brief Deallocate memory block
|
||||
*
|
||||
* @param[in] ptr @n Pointer to a memory block previously allocated with platform_malloc.
|
||||
* @return None.
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
void HAL_Free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocates a block of size bytes of memory, returning a pointer to the beginning of the block.
|
||||
*
|
||||
* @param [in] size @n specify block size in bytes.
|
||||
* @return A pointer to the beginning of the block.
|
||||
* @see None.
|
||||
* @note Block value is indeterminate.
|
||||
*/
|
||||
void *HAL_Malloc(uint32_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a mutex.
|
||||
*
|
||||
* @retval NULL : Initialize mutex failed.
|
||||
* @retval NOT_NULL : The mutex handle.
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
void *HAL_MutexCreate(void)
|
||||
{
|
||||
return (void *)1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Destroy the specified mutex object, it will release related resource.
|
||||
*
|
||||
* @param [in] mutex @n The specified mutex.
|
||||
* @return None.
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
void HAL_MutexDestroy(void *mutex)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Waits until the specified mutex is in the signaled state.
|
||||
*
|
||||
* @param [in] mutex @n the specified mutex.
|
||||
* @return None.
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
void HAL_MutexLock(void *mutex)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Releases ownership of the specified mutex object..
|
||||
*
|
||||
* @param [in] mutex @n the specified mutex.
|
||||
* @return None.
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
void HAL_MutexUnlock(void *mutex)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Writes formatted data to stream.
|
||||
*
|
||||
* @param [in] fmt: @n String that contains the text to be written, it can optionally contain embedded format specifiers
|
||||
that specifies how subsequent arguments are converted for output.
|
||||
* @param [in] ...: @n the variable argument list, for formatted and inserted in the resulting string replacing their respective specifiers.
|
||||
* @return None.
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
void HAL_Printf(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes formatted data to string.
|
||||
*
|
||||
* @param [out] str: @n String that holds written text.
|
||||
* @param [in] len: @n Maximum length of character will be written
|
||||
* @param [in] fmt: @n Format that contains the text to be written, it can optionally contain embedded format specifiers
|
||||
that specifies how subsequent arguments are converted for output.
|
||||
* @param [in] ...: @n the variable argument list, for formatted and inserted in the resulting string replacing their respective specifiers.
|
||||
* @return bytes of character successfully written into string.
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
int HAL_Snprintf(char *str, const int len, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int rc;
|
||||
|
||||
va_start(args, fmt);
|
||||
rc = vsnprintf(str, len, fmt, args);
|
||||
va_end(args);
|
||||
return rc;
|
||||
}
|
||||
|
92
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/nucleus/HAL_OS_nucleus.c
vendored
Normal file
92
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/nucleus/HAL_OS_nucleus.c
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
#include "infra_types.h"
|
||||
#include "infra_defs.h"
|
||||
|
||||
#include "kal_public_defs.h"
|
||||
#include "kal_public_api.h"
|
||||
#include "kal_general_types.h"
|
||||
#include "soc_api.h"
|
||||
|
||||
#define HAL_MEM_SIZE (30 * 1024)
|
||||
static KAL_ADM_ID hal_heap_adm_id =NULL;
|
||||
|
||||
#if defined(WIN32)
|
||||
static kal_uint8 my_heap[HAL_MEM_SIZE];
|
||||
#else
|
||||
static __align(32) kal_uint8 hal_heap[HAL_MEM_SIZE];
|
||||
#endif
|
||||
|
||||
void hal_mem_init(void)
|
||||
{
|
||||
hal_heap_adm_id = kal_adm_create2(hal_heap, HAL_MEM_SIZE, NULL, KAL_FALSE, 0);
|
||||
}
|
||||
|
||||
uint64_t HAL_UptimeMs(void)
|
||||
{
|
||||
unsigned int tick, cur_time;
|
||||
kal_get_time(&tick);
|
||||
cur_time = kal_ticks_to_milli_secs(tick);
|
||||
return (uint64_t)cur_time;
|
||||
}
|
||||
|
||||
int HAL_Snprintf(char *str, const int len, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int rc;
|
||||
|
||||
va_start(args, fmt);
|
||||
rc = vsnprintf(str, len, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void HAL_Printf(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void *HAL_Malloc(uint32_t size)
|
||||
{
|
||||
if(hal_heap_adm_id == NULL)
|
||||
{
|
||||
hal_mem_init();
|
||||
if(hal_heap_adm_id ==NULL){
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return (void *)kal_adm_alloc(hal_heap_adm_id, size);
|
||||
}
|
||||
|
||||
void HAL_Free(void *ptr)
|
||||
{
|
||||
if(hal_heap_adm_id ==NULL || ptr ==NULL){
|
||||
return;
|
||||
}
|
||||
kal_adm_free(hal_heap_adm_id, ptr);
|
||||
}
|
||||
|
||||
int HAL_GetProductKey(char product_key[IOTX_PRODUCT_KEY_LEN])
|
||||
{
|
||||
return (int)1;
|
||||
}
|
||||
|
||||
int HAL_GetFirmwareVersion(char *version)
|
||||
{
|
||||
return (int)1;
|
||||
}
|
||||
|
||||
int HAL_GetDeviceSecret(char device_secret[IOTX_DEVICE_SECRET_LEN])
|
||||
{
|
||||
return (int)1;
|
||||
}
|
||||
|
||||
int HAL_GetDeviceName(char device_name[IOTX_DEVICE_NAME_LEN])
|
||||
{
|
||||
return (int)1;
|
||||
}
|
219
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/nucleus/HAL_TCP_nucleus.c
vendored
Normal file
219
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/nucleus/HAL_TCP_nucleus.c
vendored
Normal file
@@ -0,0 +1,219 @@
|
||||
#include "infra_types.h"
|
||||
#include "soc_api.h"
|
||||
|
||||
#include "kal_public_defs.h"
|
||||
#include "kal_public_api.h"
|
||||
#include "kal_general_types.h"
|
||||
#include "soc_api.h"
|
||||
|
||||
extern kal_uint32 g_ali_nwk_account_id;
|
||||
|
||||
unsigned int get_cur_time(void)
|
||||
{
|
||||
unsigned int tick, cur_time;
|
||||
kal_get_time(&tick);
|
||||
cur_time = kal_ticks_to_milli_secs(tick);
|
||||
return cur_time;
|
||||
}
|
||||
|
||||
void InitTimer(OsTimer* timer)
|
||||
{
|
||||
timer->end_time = 0;
|
||||
timer->over_flow = FALSE;
|
||||
}
|
||||
|
||||
void countdown_ms(OsTimer* timer, unsigned int timeout)
|
||||
{
|
||||
unsigned int current_time = get_cur_time();
|
||||
timer->end_time = current_time + timeout;
|
||||
if(timer->end_time < current_time) {
|
||||
timer->over_flow = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
char expired(OsTimer* timer)
|
||||
{
|
||||
int left = 0;
|
||||
if (timer->over_flow) {
|
||||
left = 0xFFFFFFFF - get_cur_time() + timer->end_time;
|
||||
}
|
||||
else {
|
||||
left = timer->end_time - get_cur_time();
|
||||
}
|
||||
return (left < 0);
|
||||
}
|
||||
|
||||
int HAL_TCP_Destroy(uintptr_t fd)
|
||||
{
|
||||
HAL_Printf("tcp destroy,sock: %d\n",fd);
|
||||
if(-1 != fd)
|
||||
soc_close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uintptr_t HAL_TCP_Establish(const char *host, uint16_t port)
|
||||
{
|
||||
int rc = -1, sock = 0;
|
||||
/*set the socket as no blocking*/
|
||||
kal_bool option = KAL_TRUE;
|
||||
kal_uint8 socket_opt = 1;
|
||||
sockaddr_struct addr;
|
||||
char * p;
|
||||
kal_uint8 idx = 0;
|
||||
kal_uint8 tmp = 0;
|
||||
|
||||
p = (char *)host;
|
||||
/* parse ip addr string */
|
||||
while(*p != '\0')
|
||||
{
|
||||
tmp = 0;
|
||||
while((*p >= '0') && (*p <= '9'))
|
||||
{
|
||||
tmp = tmp*10 + *p - '0';
|
||||
p++;
|
||||
}
|
||||
|
||||
if((*p != '.') && (*p != '\0'))
|
||||
{
|
||||
ERROR_TRACE("init_socket.hostname error:%s", host);
|
||||
return -1;
|
||||
}
|
||||
|
||||
addr.addr[idx++] = tmp;
|
||||
|
||||
if((*p == '\0') || (idx > 3))
|
||||
break;
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
addr.addr_len = 4;
|
||||
addr.port = port;
|
||||
addr.sock_type = SOC_SOCK_STREAM;
|
||||
|
||||
DEBUG_TRACE("[SOCKET]hostname:%s[%d.%d.%d.%d],port:%d,addr_len=%d", host, addr.addr[0], addr.addr[1], addr.addr[2], addr.addr[3], addr.port, addr.addr_len);
|
||||
|
||||
sock = soc_create(SOC_PF_INET, SOC_SOCK_STREAM, 0, MOD_MQTT, g_ali_nwk_account_id);
|
||||
|
||||
ERROR_TRACE("soc_create: %d\n",sock);
|
||||
|
||||
if (sock >= 0)
|
||||
{
|
||||
|
||||
rc=soc_setsockopt(sock, SOC_NBIO, &option, sizeof(option));
|
||||
ERROR_TRACE("soc_setsockopt1 return %d\n",rc);
|
||||
|
||||
socket_opt = SOC_READ | SOC_WRITE | SOC_ACCEPT | SOC_CONNECT | SOC_CLOSE;
|
||||
rc = soc_setsockopt(sock, SOC_ASYNC, &socket_opt, sizeof(kal_uint8));
|
||||
if (rc < 0)
|
||||
{
|
||||
ERROR_TRACE("soc_setsockopt async return %d\n",rc);
|
||||
return -1;
|
||||
}
|
||||
ERROR_TRACE("soc_setsockopt2 return %d\n",rc);
|
||||
|
||||
rc = soc_connect(sock, &addr);
|
||||
if (rc == SOC_SUCCESS) {
|
||||
ERROR_TRACE("soc_connect succcess");
|
||||
}else if (rc == SOC_WOULDBLOCK) {
|
||||
ERROR_TRACE("soc_connect block");
|
||||
}else{
|
||||
ERROR_TRACE("soc_connect failed, rc: %d",rc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else{
|
||||
ERROR_TRACE("cmns create sock failed %d\n",sock);
|
||||
rc = -1;
|
||||
}
|
||||
return (uintptr_t)sock;
|
||||
}
|
||||
|
||||
int32_t HAL_TCP_Read(uintptr_t fd, char *buf, uint32_t len, uint32_t timeout_ms)
|
||||
{
|
||||
soc_fd_set readfds;
|
||||
OsTimer rtimer;
|
||||
int bytes = 0;
|
||||
int rc = 0;
|
||||
soc_timeval_struct tv;
|
||||
int slectrc=0;
|
||||
kal_bool is_ready = 0;
|
||||
|
||||
if(0 == timeout_ms){
|
||||
timeout_ms = 10;
|
||||
}
|
||||
tv.tv_sec = timeout_ms / 1000;
|
||||
tv.tv_usec = (timeout_ms % 1000) * 1000;
|
||||
InitTimer(&rtimer);
|
||||
countdown_ms(&rtimer, timeout_ms);
|
||||
|
||||
do{
|
||||
SOC_FD_ZERO(&readfds);
|
||||
SOC_FD_SET(fd, &readfds);
|
||||
|
||||
slectrc = soc_select(fd+1, &readfds, NULL, NULL, &tv);
|
||||
if(slectrc>=1 && SOC_FD_ISSET(fd, &readfds)){
|
||||
do{
|
||||
rc = soc_recv(fd, buf+bytes, len-bytes, 0);
|
||||
if(rc > 0){
|
||||
bytes += rc;
|
||||
}
|
||||
else if(rc < 0){
|
||||
// SOC_WOULDBLOCK should be continue?
|
||||
if(SOC_WOULDBLOCK != rc){
|
||||
rc = -1;
|
||||
}
|
||||
else if(SOC_WOULDBLOCK == rc){
|
||||
if(bytes>0 && bytes<len){
|
||||
tv.tv_sec = timeout_ms / 1000;
|
||||
tv.tv_usec = (timeout_ms % 1000) * 1000;
|
||||
countdown_ms(&rtimer, timeout_ms);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else {// FIN from the peer side
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
}while((bytes<len) && !expired(&rtimer));
|
||||
}
|
||||
else if(0 == slectrc){
|
||||
if(bytes>0 && bytes<len){
|
||||
tv.tv_sec = timeout_ms / 1000;
|
||||
tv.tv_usec = (timeout_ms % 1000) * 1000;
|
||||
countdown_ms(&rtimer, timeout_ms);
|
||||
}
|
||||
}
|
||||
else{
|
||||
//soc_select return value < 0, it means connect is broken
|
||||
bytes = 0;
|
||||
break;
|
||||
}
|
||||
//DEBUG_TRACE("linkit_read soc already read %d\n", bytes);
|
||||
|
||||
tv.tv_sec = timeout_ms / 1000;
|
||||
tv.tv_usec = (timeout_ms % 1000) * 1000;
|
||||
}while(!expired(&rtimer) && !(rc==-1) && (bytes<len));
|
||||
return bytes;
|
||||
}
|
||||
|
||||
int32_t HAL_TCP_Write(uintptr_t fd, const char *buf, uint32_t len, uint32_t timeout_ms)
|
||||
{
|
||||
int rc = 0;
|
||||
soc_timeval_struct tv;
|
||||
soc_fd_set writefds;
|
||||
|
||||
tv.tv_sec = 0; /* 30 Secs Timeout */
|
||||
tv.tv_usec = timeout_ms * 1000; // Not init'ing this can cause strange errors
|
||||
|
||||
SOC_FD_ZERO(&writefds);
|
||||
SOC_FD_SET(fd, &writefds);
|
||||
if(soc_select(fd+1, NULL, &writefds, NULL, &tv) >= 0){
|
||||
if(SOC_FD_ISSET(fd, &writefds)){
|
||||
rc = soc_send(fd, buf, len, 0);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
239
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/ubuntu/HAL_AWSS_linux.c
vendored
Normal file
239
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/ubuntu/HAL_AWSS_linux.c
vendored
Normal file
@@ -0,0 +1,239 @@
|
||||
|
||||
#ifdef DEV_BIND_ENABLED
|
||||
#include "infra_config.h"
|
||||
#include <string.h>
|
||||
#include "infra_defs.h"
|
||||
#include "dev_bind_wrapper.h"
|
||||
#endif
|
||||
|
||||
#if defined(WIFI_PROVISION_ENABLED)
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include "iot_import_awss.h"
|
||||
|
||||
/**
|
||||
* @brief 获取配网服务(`AWSS`)的超时时间长度, 单位是毫秒
|
||||
*
|
||||
* @return 超时时长, 单位是毫秒
|
||||
* @note 推荐时长是60,0000毫秒
|
||||
*/
|
||||
int HAL_Awss_Get_Timeout_Interval_Ms(void)
|
||||
{
|
||||
return 30 * 60 * 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取在每个信道(`channel`)上扫描的时间长度, 单位是毫秒
|
||||
*
|
||||
* @return 时间长度, 单位是毫秒
|
||||
* @note 推荐时长是200毫秒到400毫秒
|
||||
*/
|
||||
int HAL_Awss_Get_Channelscan_Interval_Ms(void)
|
||||
{
|
||||
return 250;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置Wi-Fi网卡工作在监听(Monitor)模式, 并在收到802.11帧的时候调用被传入的回调函数
|
||||
*
|
||||
* @param[in] cb @n A function pointer, called back when wifi receive a frame.
|
||||
*/
|
||||
void HAL_Awss_Open_Monitor(_IN_ awss_recv_80211_frame_cb_t cb)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置Wi-Fi网卡离开监听(Monitor)模式, 并开始以站点(Station)模式工作
|
||||
*/
|
||||
void HAL_Awss_Close_Monitor(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置Wi-Fi网卡切换到指定的信道(channel)上
|
||||
*
|
||||
* @param[in] primary_channel @n Primary channel.
|
||||
* @param[in] secondary_channel @n Auxiliary channel if 40Mhz channel is supported, currently
|
||||
* this param is always 0.
|
||||
* @param[in] bssid @n A pointer to wifi BSSID on which awss lock the channel, most HAL
|
||||
* may ignore it.
|
||||
*/
|
||||
void HAL_Awss_Switch_Channel(
|
||||
_IN_ char primary_channel,
|
||||
_IN_OPT_ char secondary_channel,
|
||||
_IN_OPT_ uint8_t bssid[ETH_ALEN])
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 要求Wi-Fi网卡连接指定热点(Access Point)的函数
|
||||
*
|
||||
* @param[in] connection_timeout_ms @n AP connection timeout in ms or HAL_WAIT_INFINITE
|
||||
* @param[in] ssid @n AP ssid
|
||||
* @param[in] passwd @n AP passwd
|
||||
* @param[in] auth @n optional(AWSS_AUTH_TYPE_INVALID), AP auth info
|
||||
* @param[in] encry @n optional(AWSS_ENC_TYPE_INVALID), AP encry info
|
||||
* @param[in] bssid @n optional(NULL or zero mac address), AP bssid info
|
||||
* @param[in] channel @n optional, AP channel info
|
||||
* @return
|
||||
@verbatim
|
||||
= 0: connect AP & DHCP success
|
||||
= -1: connect AP or DHCP fail/timeout
|
||||
@endverbatim
|
||||
* @see None.
|
||||
* @note
|
||||
* If the STA connects the old AP, HAL should disconnect from the old AP firstly.
|
||||
* If bssid specifies the dest AP, HAL should use bssid to connect dest AP.
|
||||
*/
|
||||
int HAL_Awss_Connect_Ap(
|
||||
_IN_ uint32_t connection_timeout_ms,
|
||||
_IN_ char ssid[HAL_MAX_SSID_LEN],
|
||||
_IN_ char passwd[HAL_MAX_PASSWD_LEN],
|
||||
_IN_OPT_ enum AWSS_AUTH_TYPE auth,
|
||||
_IN_OPT_ enum AWSS_ENC_TYPE encry,
|
||||
_IN_OPT_ uint8_t bssid[ETH_ALEN],
|
||||
_IN_OPT_ uint8_t channel)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief check system network is ready(get ip address) or not.
|
||||
*
|
||||
* @param None.
|
||||
* @return 0, net is not ready; 1, net is ready.
|
||||
* @see None.
|
||||
* @note None.
|
||||
*/
|
||||
int HAL_Sys_Net_Is_Ready()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 在当前信道(channel)上以基本数据速率(1Mbps)发送裸的802.11帧(raw 802.11 frame)
|
||||
*
|
||||
* @param[in] type @n see enum HAL_Awss_frame_type, currently only FRAME_BEACON
|
||||
* FRAME_PROBE_REQ is used
|
||||
* @param[in] buffer @n 80211 raw frame, include complete mac header & FCS field
|
||||
* @param[in] len @n 80211 raw frame length
|
||||
* @return
|
||||
@verbatim
|
||||
= 0, send success.
|
||||
= -1, send failure.
|
||||
= -2, unsupported.
|
||||
@endverbatim
|
||||
* @see None.
|
||||
* @note awss use this API send raw frame in wifi monitor mode & station mode
|
||||
*/
|
||||
int HAL_Wifi_Send_80211_Raw_Frame(_IN_ enum HAL_Awss_Frame_Type type,
|
||||
_IN_ uint8_t *buffer, _IN_ int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief 在站点(Station)模式下使能或禁用对管理帧的过滤
|
||||
*
|
||||
* @param[in] filter_mask @n see mask macro in enum HAL_Awss_frame_type,
|
||||
* currently only FRAME_PROBE_REQ_MASK & FRAME_BEACON_MASK is used
|
||||
* @param[in] vendor_oui @n oui can be used for precise frame match, optional
|
||||
* @param[in] callback @n see awss_wifi_mgmt_frame_cb_t, passing 80211
|
||||
* frame or ie to callback. when callback is NULL
|
||||
* disable sniffer feature, otherwise enable it.
|
||||
* @return
|
||||
@verbatim
|
||||
= 0, success
|
||||
= -1, fail
|
||||
= -2, unsupported.
|
||||
@endverbatim
|
||||
* @see None.
|
||||
* @note awss use this API to filter specific mgnt frame in wifi station mode
|
||||
*/
|
||||
int HAL_Wifi_Enable_Mgmt_Frame_Filter(
|
||||
_IN_ uint32_t filter_mask,
|
||||
_IN_OPT_ uint8_t vendor_oui[3],
|
||||
_IN_ awss_wifi_mgmt_frame_cb_t callback)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 启动一次Wi-Fi的空中扫描(Scan)
|
||||
*
|
||||
* @param[in] cb @n pass ssid info(scan result) to this callback one by one
|
||||
* @return 0 for wifi scan is done, otherwise return -1
|
||||
* @see None.
|
||||
* @note
|
||||
* This API should NOT exit before the invoking for cb is finished.
|
||||
* This rule is something like the following :
|
||||
* HAL_Wifi_Scan() is invoked...
|
||||
* ...
|
||||
* for (ap = first_ap; ap <= last_ap; ap = next_ap){
|
||||
* cb(ap)
|
||||
* }
|
||||
* ...
|
||||
* HAL_Wifi_Scan() exit...
|
||||
*/
|
||||
int HAL_Wifi_Scan(awss_wifi_scan_result_cb_t cb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取所连接的热点(Access Point)的信息
|
||||
*
|
||||
* @param[out] ssid: array to store ap ssid. It will be null if ssid is not required.
|
||||
* @param[out] passwd: array to store ap password. It will be null if ap password is not required.
|
||||
* @param[out] bssid: array to store ap bssid. It will be null if bssid is not required.
|
||||
* @return
|
||||
@verbatim
|
||||
= 0: succeeded
|
||||
= -1: failed
|
||||
@endverbatim
|
||||
* @see None.
|
||||
* @note
|
||||
* If the STA dosen't connect AP successfully, HAL should return -1 and not touch the ssid/passwd/bssid buffer.
|
||||
*/
|
||||
int HAL_Wifi_Get_Ap_Info(
|
||||
_OU_ char ssid[HAL_MAX_SSID_LEN],
|
||||
_OU_ char passwd[HAL_MAX_PASSWD_LEN],
|
||||
_OU_ uint8_t bssid[ETH_ALEN])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* @brief 打开当前设备热点,并把设备由SoftAP模式切换到AP模式
|
||||
*/
|
||||
int HAL_Awss_Open_Ap(const char *ssid, const char *passwd, int beacon_interval, int hide)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* @brief 关闭当前设备热点,并把设备由SoftAP模式切换到Station模式
|
||||
*/
|
||||
int HAL_Awss_Close_Ap()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* #if defined(HAL_AWSS) */
|
||||
|
||||
#ifdef DEV_BIND_ENABLED
|
||||
|
||||
/**
|
||||
* @brief 获取Wi-Fi网口的MAC地址, 格式应当是"XX:XX:XX:XX:XX:XX"
|
||||
*
|
||||
* @param mac_str : 用于存放MAC地址字符串的缓冲区数组
|
||||
* @return 指向缓冲区数组起始位置的字符指针
|
||||
*/
|
||||
char *HAL_Wifi_Get_Mac(_OU_ char mac_str[HAL_MAC_LEN])
|
||||
{
|
||||
strcpy(mac_str, "18:FE:34:12:33:44");
|
||||
return mac_str;
|
||||
}
|
||||
#endif
|
||||
|
149
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/ubuntu/HAL_Crypt_Linux.c
vendored
Normal file
149
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/ubuntu/HAL_Crypt_Linux.c
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
#include "infra_config.h"
|
||||
|
||||
#if defined(HAL_CRYPTO)
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "infra_compat.h"
|
||||
#include "mbedtls/aes.h"
|
||||
|
||||
#define AES_BLOCK_SIZE 16
|
||||
|
||||
typedef struct {
|
||||
mbedtls_aes_context ctx;
|
||||
uint8_t iv[16];
|
||||
uint8_t key[16];
|
||||
} platform_aes_t;
|
||||
|
||||
p_HAL_Aes128_t HAL_Aes128_Init(
|
||||
const uint8_t *key,
|
||||
const uint8_t *iv,
|
||||
AES_DIR_t dir)
|
||||
{
|
||||
int ret = 0;
|
||||
platform_aes_t *p_aes128 = NULL;
|
||||
|
||||
if (!key || !iv) return p_aes128;
|
||||
|
||||
p_aes128 = (platform_aes_t *)calloc(1, sizeof(platform_aes_t));
|
||||
if (!p_aes128) return p_aes128;
|
||||
|
||||
mbedtls_aes_init(&p_aes128->ctx);
|
||||
|
||||
if (dir == HAL_AES_ENCRYPTION) {
|
||||
ret = mbedtls_aes_setkey_enc(&p_aes128->ctx, key, 128);
|
||||
} else {
|
||||
ret = mbedtls_aes_setkey_dec(&p_aes128->ctx, key, 128);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
memcpy(p_aes128->iv, iv, 16);
|
||||
memcpy(p_aes128->key, key, 16);
|
||||
} else {
|
||||
free(p_aes128);
|
||||
p_aes128 = NULL;
|
||||
}
|
||||
|
||||
return (p_HAL_Aes128_t *)p_aes128;
|
||||
}
|
||||
|
||||
int HAL_Aes128_Destroy(p_HAL_Aes128_t aes)
|
||||
{
|
||||
if (!aes) return -1;
|
||||
|
||||
mbedtls_aes_free(&((platform_aes_t *)aes)->ctx);
|
||||
free(aes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HAL_Aes128_Cbc_Encrypt(
|
||||
p_HAL_Aes128_t aes,
|
||||
const void *src,
|
||||
size_t blockNum,
|
||||
void *dst)
|
||||
{
|
||||
int i = 0;
|
||||
int ret = ret;
|
||||
platform_aes_t *p_aes128 = (platform_aes_t *)aes;
|
||||
|
||||
if (!aes || !src || !dst) return -1;
|
||||
|
||||
for (i = 0; i < blockNum; ++i) {
|
||||
ret = mbedtls_aes_crypt_cbc(&p_aes128->ctx, MBEDTLS_AES_ENCRYPT, AES_BLOCK_SIZE,
|
||||
p_aes128->iv, src, dst);
|
||||
src += 16;
|
||||
dst += 16;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int HAL_Aes128_Cbc_Decrypt(
|
||||
p_HAL_Aes128_t aes,
|
||||
const void *src,
|
||||
size_t blockNum,
|
||||
void *dst)
|
||||
{
|
||||
int i = 0;
|
||||
int ret = -1;
|
||||
platform_aes_t *p_aes128 = (platform_aes_t *)aes;
|
||||
|
||||
if (!aes || !src || !dst) return ret;
|
||||
|
||||
for (i = 0; i < blockNum; ++i) {
|
||||
ret = mbedtls_aes_crypt_cbc(&p_aes128->ctx, MBEDTLS_AES_DECRYPT, AES_BLOCK_SIZE,
|
||||
p_aes128->iv, src, dst);
|
||||
src += 16;
|
||||
dst += 16;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
||||
int HAL_Aes128_Cfb_Encrypt(
|
||||
p_HAL_Aes128_t aes,
|
||||
const void *src,
|
||||
size_t length,
|
||||
void *dst)
|
||||
{
|
||||
size_t offset = 0;
|
||||
int ret = -1;
|
||||
platform_aes_t *p_aes128 = (platform_aes_t *)aes;
|
||||
|
||||
if (!aes || !src || !dst) return ret;
|
||||
|
||||
ret = mbedtls_aes_crypt_cfb128(&p_aes128->ctx, MBEDTLS_AES_ENCRYPT, length,
|
||||
&offset, p_aes128->iv, src, dst);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
||||
int HAL_Aes128_Cfb_Decrypt(
|
||||
p_HAL_Aes128_t aes,
|
||||
const void *src,
|
||||
size_t length,
|
||||
void *dst)
|
||||
{
|
||||
size_t offset = 0;
|
||||
int ret = -1;
|
||||
platform_aes_t *p_aes128 = (platform_aes_t *)aes;
|
||||
|
||||
if (!aes || !src || !dst) return ret;
|
||||
|
||||
ret = mbedtls_aes_setkey_enc(&p_aes128->ctx, p_aes128->key, 128);
|
||||
ret = mbedtls_aes_crypt_cfb128(&p_aes128->ctx, MBEDTLS_AES_DECRYPT, length,
|
||||
&offset, p_aes128->iv, src, dst);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* #if defined(HAL_CRYPTO) */
|
||||
|
||||
|
||||
|
41
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/ubuntu/HAL_FS_Linux.c
vendored
Normal file
41
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/ubuntu/HAL_FS_Linux.c
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
#include "infra_config.h"
|
||||
|
||||
#ifdef FS_ENABLED
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
void *HAL_Fopen(const char *path, const char *mode)
|
||||
{
|
||||
return (void *)fopen(path, mode);
|
||||
}
|
||||
|
||||
uint32_t HAL_Fread(void *buff, uint32_t size, uint32_t count, void *stream)
|
||||
{
|
||||
return fread(buff, (size_t)size, (size_t)count, (FILE *)stream);
|
||||
}
|
||||
uint32_t HAL_Fwrite(const void *ptr, uint32_t size, uint32_t count, void *stream)
|
||||
{
|
||||
return (uint32_t)fwrite(ptr, (size_t)size, (size_t)count, (FILE *)stream);
|
||||
}
|
||||
|
||||
int HAL_Fseek(void *stream, long offset, int framewhere)
|
||||
{
|
||||
return fseek((FILE *)stream, offset, framewhere);
|
||||
}
|
||||
|
||||
int HAL_Fclose(void *stream)
|
||||
{
|
||||
return fclose((FILE *)stream);
|
||||
}
|
||||
|
||||
long HAL_Ftell(void *stream)
|
||||
{
|
||||
return ftell((FILE *)stream);
|
||||
}
|
||||
#endif
|
||||
|
471
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/ubuntu/HAL_KV_linux.c
vendored
Normal file
471
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/ubuntu/HAL_KV_linux.c
vendored
Normal file
@@ -0,0 +1,471 @@
|
||||
#include "infra_config.h"
|
||||
|
||||
#if defined(HAL_KV)
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "stdint.h"
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include "infra_defs.h"
|
||||
|
||||
#define TABLE_COL_SIZE (384)
|
||||
#define TABLE_ROW_SIZE (2)
|
||||
|
||||
#define ITEM_MAX_KEY_LEN 128 /* The max key length for key-value item */
|
||||
#define ITEM_MAX_VAL_LEN 512 /* The max value length for key-value item */
|
||||
#define ITEM_MAX_LEN sizeof(kv_item_t)
|
||||
|
||||
#define KV_FILE_NAME "linkkit_kv.bin"
|
||||
|
||||
#define kv_err(...) do{printf(__VA_ARGS__);printf("\r\n");}while(0)
|
||||
|
||||
typedef struct kv {
|
||||
char key[ITEM_MAX_KEY_LEN];
|
||||
uint8_t value[ITEM_MAX_VAL_LEN];
|
||||
int value_len;
|
||||
} kv_item_t;
|
||||
|
||||
typedef struct kv_file_s {
|
||||
const char *filename;
|
||||
pthread_mutex_t lock;
|
||||
} kv_file_t;
|
||||
|
||||
static int kv_get(const char *key, void *value, int *value_len);
|
||||
static int kv_set(const char *key, void *value, int value_len);
|
||||
static int kv_del(const char *key);
|
||||
static unsigned int hash_gen(const char *key);
|
||||
static int hash_table_put(kv_file_t *file, const char *key, void *value, int value_len);
|
||||
static int hash_table_get(kv_file_t *file, const char *key, void *value, int *len);
|
||||
static int hash_table_rm(kv_file_t *file, const char *key);
|
||||
static kv_file_t *kv_open(const char *filename);
|
||||
static int read_kv_item(const char *filename, void *buf, int location);
|
||||
static int write_kv_item(const char *filename, void *data, int location);
|
||||
|
||||
static void free_kv(struct kv *kv)
|
||||
{
|
||||
if (kv) {
|
||||
kv->value_len = 0;
|
||||
free(kv);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int hash_gen(const char *key)
|
||||
{
|
||||
unsigned int hash = 0;
|
||||
while (*key) {
|
||||
hash = (hash << 5) + hash + *key++;
|
||||
}
|
||||
return hash % TABLE_COL_SIZE;
|
||||
}
|
||||
|
||||
/* insert or update a value indexed by key */
|
||||
static int hash_table_put(kv_file_t *file, const char *key, void *value, int value_len)
|
||||
{
|
||||
int i;
|
||||
int read_size;
|
||||
kv_item_t *kv;
|
||||
int j = 0;
|
||||
kv_item_t *p;
|
||||
if (!file || !file->filename || !key || !value || value_len <= 0) {
|
||||
kv_err("paras err");
|
||||
return -1;
|
||||
}
|
||||
|
||||
value_len = value_len > ITEM_MAX_VAL_LEN ? ITEM_MAX_VAL_LEN : value_len;
|
||||
i = hash_gen(key);
|
||||
kv_err("hash i= %d", i);
|
||||
read_size = ITEM_MAX_LEN * TABLE_ROW_SIZE;
|
||||
kv = malloc(read_size);
|
||||
if (kv == NULL) {
|
||||
kv_err("malloc kv err");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(kv, 0, read_size);
|
||||
if (read_kv_item(file->filename, kv, i) != 0) {
|
||||
kv_err("read kv err");
|
||||
free_kv(kv);
|
||||
return -1;
|
||||
}
|
||||
p = &kv[j];
|
||||
|
||||
while (p && p->value_len) { /* if key is already stroed, update its value */
|
||||
|
||||
if (strcmp(p->key, key) == 0) {
|
||||
memset(p->value, 0, ITEM_MAX_VAL_LEN);
|
||||
memcpy(p->value, value, value_len);
|
||||
p->value_len = value_len;
|
||||
break;
|
||||
}
|
||||
|
||||
if (++j == TABLE_ROW_SIZE) {
|
||||
kv_err("hash row full");
|
||||
free(kv);
|
||||
return -1;
|
||||
}
|
||||
p = &kv[j];
|
||||
}
|
||||
|
||||
p = &kv[j];
|
||||
if (p && !p->value_len) {/* if key has not been stored, then add it */
|
||||
//p->next = NULL;
|
||||
strncpy(p->key, key, ITEM_MAX_KEY_LEN - 1);
|
||||
memcpy(p->value, value, value_len);
|
||||
p->value_len = value_len;
|
||||
}
|
||||
|
||||
if (write_kv_item(file->filename, kv, i) < 0) {
|
||||
kv_err("write_kv_item err");
|
||||
free(kv);
|
||||
return -1;
|
||||
}
|
||||
free(kv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get a value indexed by key */
|
||||
static int hash_table_get(kv_file_t *file, const char *key, void *value, int *len)
|
||||
{
|
||||
int i;
|
||||
int read_size;
|
||||
kv_item_t *kv;
|
||||
int j = 0;
|
||||
struct kv *p;
|
||||
if (!file || !file->filename || !key || !value || !len || *len <= 0) {
|
||||
kv_err("paras err");
|
||||
return -1;
|
||||
}
|
||||
|
||||
i = hash_gen(key);
|
||||
|
||||
read_size = sizeof(kv_item_t) * TABLE_ROW_SIZE;
|
||||
kv = malloc(read_size);
|
||||
if (kv == NULL) {
|
||||
kv_err("malloc kv err");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(kv, 0, read_size);
|
||||
if (read_kv_item(file->filename, kv, i) != 0) {
|
||||
kv_err("read kv err");
|
||||
free_kv(kv);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// struct kv *p = ht->table[i];
|
||||
p = &kv[j];
|
||||
|
||||
while (p && p->value_len) {
|
||||
if (strcmp(key, p->key) == 0) {
|
||||
*len = p->value_len < *len ? p->value_len : *len;
|
||||
memcpy(value, p->value, *len);
|
||||
free_kv(kv);
|
||||
return 0;
|
||||
}
|
||||
if (++j == TABLE_ROW_SIZE) {
|
||||
break;
|
||||
}
|
||||
p = &kv[j];
|
||||
}
|
||||
free_kv(kv);
|
||||
kv_err("not found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* remove a value indexed by key */
|
||||
static int hash_table_rm(kv_file_t *file, const char *key)
|
||||
{
|
||||
int i;
|
||||
int read_size;
|
||||
kv_item_t *kv;
|
||||
int j = 0;
|
||||
struct kv *p;
|
||||
if (!file || !file->filename || !key) {
|
||||
return -1;
|
||||
}
|
||||
i = hash_gen(key) % TABLE_COL_SIZE;
|
||||
read_size = sizeof(kv_item_t) * TABLE_ROW_SIZE;
|
||||
kv = malloc(read_size);
|
||||
if (kv == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(kv, 0, read_size);
|
||||
if (read_kv_item(file->filename, kv, i) != 0) {
|
||||
free_kv(kv);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = &kv[j];
|
||||
|
||||
while (p && p->value_len) {
|
||||
if (strcmp(key, p->key) == 0) {
|
||||
memset(p, 0, ITEM_MAX_LEN);
|
||||
}
|
||||
if (++j == TABLE_ROW_SIZE) {
|
||||
break;
|
||||
}
|
||||
p = &kv[j];
|
||||
}
|
||||
|
||||
if (write_kv_item(file->filename, kv, i) < 0) {
|
||||
free_kv(kv);
|
||||
return -1;
|
||||
}
|
||||
free_kv(kv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_kv_item(const char *filename, void *buf, int location)
|
||||
{
|
||||
struct stat st;
|
||||
int ret = 0;
|
||||
int offset;
|
||||
int fd = open(filename, O_RDONLY);
|
||||
|
||||
if (fd < 0) {
|
||||
kv_err("open err");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fstat(fd, &st) < 0) {
|
||||
kv_err("fstat err");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (st.st_size < (location + 1) *ITEM_MAX_LEN * TABLE_ROW_SIZE) {
|
||||
kv_err("read overstep");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
offset = location * ITEM_MAX_LEN * TABLE_ROW_SIZE;
|
||||
ret = lseek(fd, offset, SEEK_SET);
|
||||
if (ret < 0) {
|
||||
kv_err("lseek err");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (read(fd, buf, ITEM_MAX_LEN * TABLE_ROW_SIZE) != ITEM_MAX_LEN * TABLE_ROW_SIZE) {
|
||||
kv_err("read err");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int write_kv_item(const char *filename, void *data, int location)
|
||||
{
|
||||
struct stat st;
|
||||
int offset;
|
||||
int ret;
|
||||
int fd = open(filename, O_WRONLY);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fstat(fd, &st) < 0) {
|
||||
kv_err("fstat err");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (st.st_size < (location + 1) *ITEM_MAX_LEN * TABLE_ROW_SIZE) {
|
||||
kv_err("overstep st.st_size = %d location =%d cur loc=%d",
|
||||
(int)st.st_size,
|
||||
(int)location,
|
||||
(int)((location + 1) *ITEM_MAX_LEN * TABLE_ROW_SIZE));
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
offset = (location) * ITEM_MAX_LEN * TABLE_ROW_SIZE;
|
||||
ret = lseek(fd, offset, SEEK_SET);
|
||||
if (ret < 0) {
|
||||
kv_err("lseek err");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (write(fd, data, ITEM_MAX_LEN * TABLE_ROW_SIZE) != ITEM_MAX_LEN * TABLE_ROW_SIZE) {
|
||||
kv_err("kv write failed");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fsync(fd);
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int create_hash_file(kv_file_t *hash_kv)
|
||||
{
|
||||
int i;
|
||||
int fd;
|
||||
char init_data[ITEM_MAX_LEN * TABLE_ROW_SIZE] = {0};
|
||||
if (hash_kv == NULL) {
|
||||
return -1;
|
||||
}
|
||||
fd = open(hash_kv->filename, O_CREAT | O_RDWR, 0644);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < TABLE_COL_SIZE ; i++) {
|
||||
|
||||
if (write(fd, init_data, ITEM_MAX_LEN * TABLE_ROW_SIZE) != ITEM_MAX_LEN *
|
||||
TABLE_ROW_SIZE) { /* 3 = '{}' + null terminator */
|
||||
kv_err("write err");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (fsync(fd) < 0) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static kv_file_t *kv_open(const char *filename)
|
||||
{
|
||||
kv_file_t *file = malloc(sizeof(kv_file_t));
|
||||
if (!file) {
|
||||
return NULL;
|
||||
}
|
||||
memset(file, 0, sizeof(kv_file_t));
|
||||
|
||||
file->filename = filename;
|
||||
pthread_mutex_init(&file->lock, NULL);
|
||||
pthread_mutex_lock(&file->lock);
|
||||
|
||||
if (access(file->filename, F_OK) < 0) {
|
||||
/* create KV file when not exist */
|
||||
if (create_hash_file(file) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&file->lock);
|
||||
return file;
|
||||
fail:
|
||||
pthread_mutex_unlock(&file->lock);
|
||||
free(file);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int __kv_get(kv_file_t *file, const char *key, void *value, int *value_len)
|
||||
{
|
||||
int ret;
|
||||
if (!file || !key || !value || !value_len || *value_len <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&file->lock);
|
||||
ret = hash_table_get(file, key, value, value_len);
|
||||
pthread_mutex_unlock(&file->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __kv_set(kv_file_t *file, const char *key, void *value, int value_len)
|
||||
{
|
||||
int ret;
|
||||
if (!file || !key || !value || value_len <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&file->lock);
|
||||
ret = hash_table_put(file, key, value, value_len);
|
||||
pthread_mutex_unlock(&file->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __kv_del(kv_file_t *file, const char *key)
|
||||
{
|
||||
int ret;
|
||||
if (!file || !key) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* remove old value if exist */
|
||||
pthread_mutex_lock(&file->lock);
|
||||
ret = hash_table_rm(file, key);
|
||||
pthread_mutex_unlock(&file->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static kv_file_t *file = NULL;
|
||||
static int kv_get(const char *key, void *value, int *value_len)
|
||||
{
|
||||
if (!file) {
|
||||
file = kv_open(KV_FILE_NAME);
|
||||
if (!file) {
|
||||
kv_err("kv_open failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return __kv_get(file, key, value, value_len);
|
||||
}
|
||||
|
||||
static int kv_set(const char *key, void *value, int value_len)
|
||||
{
|
||||
if (!file) {
|
||||
file = kv_open(KV_FILE_NAME);
|
||||
if (!file) {
|
||||
kv_err("kv_open failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return __kv_set(file, key, value, value_len);
|
||||
}
|
||||
|
||||
static int kv_del(const char *key)
|
||||
{
|
||||
if (!file) {
|
||||
file = kv_open(KV_FILE_NAME);
|
||||
if (!file) {
|
||||
kv_err("kv_open failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return __kv_del(file, key);
|
||||
}
|
||||
|
||||
int HAL_Kv_Set(const char *key, const void *val, int len, int sync)
|
||||
{
|
||||
return kv_set(key, (void *)val, len);
|
||||
}
|
||||
|
||||
int HAL_Kv_Get(const char *key, void *val, int *buffer_len)
|
||||
{
|
||||
return kv_get(key, val, buffer_len);
|
||||
}
|
||||
|
||||
int HAL_Kv_Del(const char *key)
|
||||
{
|
||||
|
||||
return kv_del(key);
|
||||
}
|
||||
|
||||
#endif /* #if defined(HAL_KV) */
|
||||
|
||||
|
||||
|
624
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/ubuntu/HAL_OS_linux.c
vendored
Normal file
624
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/ubuntu/HAL_OS_linux.c
vendored
Normal file
@@ -0,0 +1,624 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "infra_config.h"
|
||||
#include "infra_compat.h"
|
||||
#include "infra_defs.h"
|
||||
#include "wrappers_defs.h"
|
||||
|
||||
#define PLATFORM_WAIT_INFINITE (~0)
|
||||
|
||||
#ifdef DYNAMIC_REGISTER
|
||||
char _product_key[IOTX_PRODUCT_KEY_LEN + 1] = "a1ZETBPbycq";
|
||||
char _product_secret[IOTX_PRODUCT_SECRET_LEN + 1] = "L68wCVXYUaNg1Ey9";
|
||||
char _device_name[IOTX_DEVICE_NAME_LEN + 1] = "example1";
|
||||
char _device_secret[IOTX_DEVICE_SECRET_LEN + 1] = "";
|
||||
#else
|
||||
#ifdef DEVICE_MODEL_ENABLED
|
||||
char _product_key[IOTX_PRODUCT_KEY_LEN + 1] = "a1RIsMLz2BJ";
|
||||
char _product_secret[IOTX_PRODUCT_SECRET_LEN + 1] = "fSAF0hle6xL0oRWd";
|
||||
char _device_name[IOTX_DEVICE_NAME_LEN + 1] = "example1";
|
||||
char _device_secret[IOTX_DEVICE_SECRET_LEN + 1] = "RDXf67itLqZCwdMCRrw0N5FHbv5D7jrE";
|
||||
#else
|
||||
char _product_key[IOTX_PRODUCT_KEY_LEN + 1] = "a1MZxOdcBnO";
|
||||
char _product_secret[IOTX_PRODUCT_SECRET_LEN + 1] = "h4I4dneEFp7EImTv";
|
||||
char _device_name[IOTX_DEVICE_NAME_LEN + 1] = "test_01";
|
||||
char _device_secret[IOTX_DEVICE_SECRET_LEN + 1] = "t9GmMf2jb3LgWfXBaZD2r3aJrfVWBv56";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
char _firmware_version[IOTX_FIRMWARE_VER_LEN] = "app-1.0.0-20180101.1000";
|
||||
|
||||
void *HAL_Malloc(uint32_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void *HAL_Realloc(void *ptr, uint32_t size)
|
||||
{
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
|
||||
void HAL_Free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
uint64_t HAL_UptimeMs(void)
|
||||
{
|
||||
uint64_t time_ms;
|
||||
struct timespec ts;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
time_ms = ((uint64_t)ts.tv_sec * (uint64_t)1000) + (ts.tv_nsec / 1000 / 1000);
|
||||
|
||||
return time_ms;
|
||||
}
|
||||
|
||||
void HAL_SleepMs(uint32_t ms)
|
||||
{
|
||||
usleep(1000 * ms);
|
||||
}
|
||||
|
||||
void HAL_Srandom(uint32_t seed)
|
||||
{
|
||||
srandom(seed);
|
||||
}
|
||||
|
||||
uint32_t HAL_Random(uint32_t region)
|
||||
{
|
||||
FILE *handle;
|
||||
ssize_t ret = 0;
|
||||
uint32_t output = 0;
|
||||
handle = fopen("/dev/urandom", "r");
|
||||
if (handle == NULL) {
|
||||
printf("open /dev/urandom failed\n");
|
||||
return 0;
|
||||
}
|
||||
ret = fread(&output, sizeof(uint32_t), 1, handle);
|
||||
if (ret != 1) {
|
||||
printf("fread error: %d\n", (int)ret);
|
||||
fclose(handle);
|
||||
return 0;
|
||||
}
|
||||
fclose(handle);
|
||||
return (region > 0) ? (output % region) : 0;
|
||||
}
|
||||
|
||||
int HAL_Snprintf(char *str, const int len, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int rc;
|
||||
|
||||
va_start(args, fmt);
|
||||
rc = vsnprintf(str, len, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int HAL_Vsnprintf(char *str, const int len, const char *format, va_list ap)
|
||||
{
|
||||
return vsnprintf(str, len, format, ap);
|
||||
}
|
||||
|
||||
void HAL_Printf(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int HAL_GetPartnerID(char *pid_str)
|
||||
{
|
||||
memset(pid_str, 0x0, IOTX_PARTNER_ID_LEN);
|
||||
strcpy(pid_str, "c-sdk-2.3.0-pid");
|
||||
return strlen(pid_str);
|
||||
}
|
||||
|
||||
int HAL_GetModuleID(char *mid_str)
|
||||
{
|
||||
memset(mid_str, 0x0, IOTX_MODULE_ID_LEN);
|
||||
strcpy(mid_str, "c-sdk-2.3.0-mid");
|
||||
return strlen(mid_str);
|
||||
}
|
||||
|
||||
int HAL_SetProductKey(char *product_key)
|
||||
{
|
||||
int len = strlen(product_key);
|
||||
|
||||
if (len > IOTX_PRODUCT_KEY_LEN) {
|
||||
return -1;
|
||||
}
|
||||
memset(_product_key, 0x0, IOTX_PRODUCT_KEY_LEN + 1);
|
||||
strncpy(_product_key, product_key, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
int HAL_SetDeviceName(char *device_name)
|
||||
{
|
||||
int len = strlen(device_name);
|
||||
|
||||
if (len > IOTX_DEVICE_NAME_LEN) {
|
||||
return -1;
|
||||
}
|
||||
memset(_device_name, 0x0, IOTX_DEVICE_NAME_LEN + 1);
|
||||
strncpy(_device_name, device_name, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int HAL_SetProductSecret(char *product_secret)
|
||||
{
|
||||
int len = strlen(product_secret);
|
||||
|
||||
if (len > IOTX_PRODUCT_SECRET_LEN) {
|
||||
return -1;
|
||||
}
|
||||
memset(_product_secret, 0x0, IOTX_PRODUCT_SECRET_LEN + 1);
|
||||
strncpy(_product_secret, product_secret, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int HAL_SetDeviceSecret(char *device_secret)
|
||||
{
|
||||
int len = strlen(device_secret);
|
||||
|
||||
if (len > IOTX_DEVICE_SECRET_LEN) {
|
||||
return -1;
|
||||
}
|
||||
memset(_device_secret, 0x0, IOTX_DEVICE_SECRET_LEN + 1);
|
||||
strncpy(_device_secret, device_secret, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int HAL_GetProductKey(char product_key[IOTX_PRODUCT_KEY_LEN + 1])
|
||||
{
|
||||
int len = strlen(_product_key);
|
||||
memset(product_key, 0x0, IOTX_PRODUCT_KEY_LEN + 1);
|
||||
|
||||
strncpy(product_key, _product_key, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int HAL_GetProductSecret(char product_secret[IOTX_PRODUCT_SECRET_LEN + 1])
|
||||
{
|
||||
int len = strlen(_product_secret);
|
||||
memset(product_secret, 0x0, IOTX_PRODUCT_SECRET_LEN + 1);
|
||||
|
||||
strncpy(product_secret, _product_secret, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int HAL_GetDeviceName(char device_name[IOTX_DEVICE_NAME_LEN + 1])
|
||||
{
|
||||
int len = strlen(_device_name);
|
||||
memset(device_name, 0x0, IOTX_DEVICE_NAME_LEN + 1);
|
||||
|
||||
strncpy(device_name, _device_name, len);
|
||||
|
||||
return strlen(device_name);
|
||||
}
|
||||
|
||||
int HAL_GetDeviceSecret(char device_secret[IOTX_DEVICE_SECRET_LEN + 1])
|
||||
{
|
||||
int len = strlen(_device_secret);
|
||||
memset(device_secret, 0x0, IOTX_DEVICE_SECRET_LEN + 1);
|
||||
|
||||
strncpy(device_secret, _device_secret, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void HAL_Reboot(void)
|
||||
{
|
||||
if (system("reboot")) {
|
||||
perror("HAL_Reboot failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define ROUTER_INFO_PATH "/proc/net/route"
|
||||
#define ROUTER_RECORD_SIZE 256
|
||||
|
||||
char *_get_default_routing_ifname(char *ifname, int ifname_size)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
char line[ROUTER_RECORD_SIZE] = {0};
|
||||
char iface[IFNAMSIZ] = {0};
|
||||
char *result = NULL;
|
||||
unsigned int destination, gateway, flags, mask;
|
||||
unsigned int refCnt, use, metric, mtu, window, irtt;
|
||||
char *buff = NULL;
|
||||
|
||||
fp = fopen(ROUTER_INFO_PATH, "r");
|
||||
if (fp == NULL) {
|
||||
perror("fopen");
|
||||
return result;
|
||||
}
|
||||
|
||||
buff = fgets(line, sizeof(line), fp);
|
||||
if (buff == NULL) {
|
||||
perror("fgets");
|
||||
goto out;
|
||||
}
|
||||
|
||||
while (fgets(line, sizeof(line), fp)) {
|
||||
if (11 !=
|
||||
sscanf(line, "%s %08x %08x %x %d %d %d %08x %d %d %d",
|
||||
iface, &destination, &gateway, &flags, &refCnt, &use,
|
||||
&metric, &mask, &mtu, &window, &irtt)) {
|
||||
perror("sscanf");
|
||||
continue;
|
||||
}
|
||||
|
||||
/*default route */
|
||||
if ((destination == 0) && (mask == 0)) {
|
||||
strncpy(ifname, iface, ifname_size - 1);
|
||||
result = ifname;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (fp) {
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t HAL_Wifi_Get_IP(char ip_str[NETWORK_ADDR_LEN], const char *ifname)
|
||||
{
|
||||
struct ifreq ifreq;
|
||||
int sock = -1;
|
||||
char ifname_buff[IFNAMSIZ] = {0};
|
||||
|
||||
if ((NULL == ifname || strlen(ifname) == 0) &&
|
||||
NULL == (ifname = _get_default_routing_ifname(ifname_buff, sizeof(ifname_buff)))) {
|
||||
perror("get default routeing ifname");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
perror("socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ifreq.ifr_addr.sa_family = AF_INET;
|
||||
strncpy(ifreq.ifr_name, ifname, IFNAMSIZ - 1);
|
||||
|
||||
if (ioctl(sock, SIOCGIFADDR, &ifreq) < 0) {
|
||||
close(sock);
|
||||
perror("ioctl");
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(sock);
|
||||
|
||||
strncpy(ip_str,
|
||||
inet_ntoa(((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr),
|
||||
NETWORK_ADDR_LEN);
|
||||
|
||||
return ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr;
|
||||
}
|
||||
|
||||
int HAL_GetFirmwareVersion(char *version)
|
||||
{
|
||||
char *ver = "app-1.0.0-20180101.1000";
|
||||
int len = strlen(ver);
|
||||
memset(version, 0x0, IOTX_FIRMWARE_VER_LEN);
|
||||
strncpy(version, ver, IOTX_FIRMWARE_VER_LEN);
|
||||
version[len] = '\0';
|
||||
return strlen(version);
|
||||
}
|
||||
|
||||
void *HAL_SemaphoreCreate(void)
|
||||
{
|
||||
sem_t *sem = (sem_t *)malloc(sizeof(sem_t));
|
||||
if (NULL == sem) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (0 != sem_init(sem, 0, 0)) {
|
||||
free(sem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sem;
|
||||
}
|
||||
|
||||
void HAL_SemaphoreDestroy(void *sem)
|
||||
{
|
||||
sem_destroy((sem_t *)sem);
|
||||
free(sem);
|
||||
}
|
||||
|
||||
void HAL_SemaphorePost(void *sem)
|
||||
{
|
||||
sem_post((sem_t *)sem);
|
||||
}
|
||||
|
||||
int HAL_SemaphoreWait(void *sem, uint32_t timeout_ms)
|
||||
{
|
||||
if (PLATFORM_WAIT_INFINITE == timeout_ms) {
|
||||
sem_wait(sem);
|
||||
return 0;
|
||||
} else {
|
||||
struct timespec ts;
|
||||
int s;
|
||||
/* Restart if interrupted by handler */
|
||||
do {
|
||||
if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
s = 0;
|
||||
ts.tv_nsec += (timeout_ms % 1000) * 1000000;
|
||||
if (ts.tv_nsec >= 1000000000) {
|
||||
ts.tv_nsec -= 1000000000;
|
||||
s = 1;
|
||||
}
|
||||
|
||||
ts.tv_sec += timeout_ms / 1000 + s;
|
||||
|
||||
} while (((s = sem_timedwait(sem, &ts)) != 0) && errno == EINTR);
|
||||
|
||||
return (s == 0) ? 0 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
int HAL_ThreadCreate(
|
||||
void **thread_handle,
|
||||
void *(*work_routine)(void *),
|
||||
void *arg,
|
||||
hal_os_thread_param_t *hal_os_thread_param,
|
||||
int *stack_used)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (stack_used) {
|
||||
*stack_used = 0;
|
||||
}
|
||||
|
||||
ret = pthread_create((pthread_t *)thread_handle, NULL, work_routine, arg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void HAL_ThreadDetach(void *thread_handle)
|
||||
{
|
||||
pthread_detach((pthread_t)thread_handle);
|
||||
}
|
||||
|
||||
void HAL_ThreadDelete(void *thread_handle)
|
||||
{
|
||||
if (NULL == thread_handle) {
|
||||
pthread_exit(0);
|
||||
} else {
|
||||
/*main thread delete child thread*/
|
||||
pthread_cancel((pthread_t)thread_handle);
|
||||
pthread_join((pthread_t)thread_handle, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static FILE *fp;
|
||||
|
||||
#define otafilename "/tmp/alinkota.bin"
|
||||
|
||||
void HAL_Firmware_Persistence_Start(void)
|
||||
{
|
||||
fp = fopen(otafilename, "w");
|
||||
return;
|
||||
}
|
||||
|
||||
int HAL_Firmware_Persistence_Write(char *buffer, uint32_t length)
|
||||
{
|
||||
unsigned int written_len = 0;
|
||||
written_len = fwrite(buffer, 1, length, fp);
|
||||
|
||||
if (written_len != length) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HAL_Firmware_Persistence_Stop(void)
|
||||
{
|
||||
if (fp != NULL) {
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/* check file md5, and burning it to flash ... finally reboot system */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *HAL_MutexCreate(void)
|
||||
{
|
||||
int err_num;
|
||||
pthread_mutex_t *mutex = (pthread_mutex_t *)HAL_Malloc(sizeof(pthread_mutex_t));
|
||||
if (NULL == mutex) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (0 != (err_num = pthread_mutex_init(mutex, NULL))) {
|
||||
printf("create mutex failed\n");
|
||||
HAL_Free(mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mutex;
|
||||
}
|
||||
|
||||
void HAL_MutexDestroy(void *mutex)
|
||||
{
|
||||
int err_num;
|
||||
|
||||
if (!mutex) {
|
||||
printf("mutex want to destroy is NULL!\n");
|
||||
return;
|
||||
}
|
||||
if (0 != (err_num = pthread_mutex_destroy((pthread_mutex_t *)mutex))) {
|
||||
printf("destroy mutex failed\n");
|
||||
}
|
||||
|
||||
HAL_Free(mutex);
|
||||
}
|
||||
|
||||
void HAL_MutexLock(void *mutex)
|
||||
{
|
||||
int err_num;
|
||||
if (0 != (err_num = pthread_mutex_lock((pthread_mutex_t *)mutex))) {
|
||||
printf("lock mutex failed: - '%s' (%d)\n", strerror(err_num), err_num);
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_MutexUnlock(void *mutex)
|
||||
{
|
||||
int err_num;
|
||||
if (0 != (err_num = pthread_mutex_unlock((pthread_mutex_t *)mutex))) {
|
||||
printf("unlock mutex failed - '%s' (%d)\n", strerror(err_num), err_num);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *HAL_Timer_Create(const char *name, void (*func)(void *), void *user_data)
|
||||
{
|
||||
timer_t *timer = NULL;
|
||||
|
||||
struct sigevent ent;
|
||||
|
||||
/* check parameter */
|
||||
if (func == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
timer = (timer_t *)malloc(sizeof(time_t));
|
||||
if (timer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Init */
|
||||
memset(&ent, 0x00, sizeof(struct sigevent));
|
||||
|
||||
/* create a timer */
|
||||
ent.sigev_notify = SIGEV_THREAD;
|
||||
ent.sigev_notify_function = (void (*)(union sigval))func;
|
||||
ent.sigev_value.sival_ptr = user_data;
|
||||
|
||||
printf("HAL_Timer_Create\n");
|
||||
|
||||
if (timer_create(CLOCK_MONOTONIC, &ent, timer) != 0) {
|
||||
free(timer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (void *)timer;
|
||||
}
|
||||
|
||||
int HAL_Timer_Start(void *timer, int ms)
|
||||
{
|
||||
struct itimerspec ts;
|
||||
|
||||
/* check parameter */
|
||||
if (timer == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* it_interval=0: timer run only once */
|
||||
ts.it_interval.tv_sec = 0;
|
||||
ts.it_interval.tv_nsec = 0;
|
||||
|
||||
/* it_value=0: stop timer */
|
||||
ts.it_value.tv_sec = ms / 1000;
|
||||
ts.it_value.tv_nsec = (ms % 1000) * 1000000;
|
||||
|
||||
return timer_settime(*(timer_t *)timer, 0, &ts, NULL);
|
||||
}
|
||||
|
||||
int HAL_Timer_Stop(void *timer)
|
||||
{
|
||||
struct itimerspec ts;
|
||||
|
||||
/* check parameter */
|
||||
if (timer == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* it_interval=0: timer run only once */
|
||||
ts.it_interval.tv_sec = 0;
|
||||
ts.it_interval.tv_nsec = 0;
|
||||
|
||||
/* it_value=0: stop timer */
|
||||
ts.it_value.tv_sec = 0;
|
||||
ts.it_value.tv_nsec = 0;
|
||||
|
||||
return timer_settime(*(timer_t *)timer, 0, &ts, NULL);
|
||||
}
|
||||
|
||||
int HAL_Timer_Delete(void *timer)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* check parameter */
|
||||
if (timer == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = timer_delete(*(timer_t *)timer);
|
||||
|
||||
free(timer);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int HAL_GetNetifInfo(char *nif_str)
|
||||
{
|
||||
const char *net_info = "WiFi|03ACDEFF0032";
|
||||
|
||||
memset(nif_str, 0x0, IOTX_NETWORK_IF_LEN);
|
||||
|
||||
/* if the device have only WIFI, then list as follow, note that the len MUST NOT exceed NIF_STRLEN_MAX */
|
||||
strncpy(nif_str, net_info, IOTX_NETWORK_IF_LEN);
|
||||
/* if the device have ETH, WIFI, GSM connections, then list all of them as follow, note that the len MUST NOT exceed NIF_STRLEN_MAX */
|
||||
/* const char *multi_net_info = "ETH|0123456789abcde|WiFi|03ACDEFF0032|Cellular|imei_0123456789abcde|iccid_0123456789abcdef01234|imsi_0123456789abcde|msisdn_86123456789ab"); */
|
||||
/* strncpy(nif_str, multi_net_info, strlen(multi_net_info)); */
|
||||
|
||||
return strlen(nif_str);
|
||||
}
|
||||
|
269
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/ubuntu/HAL_TCP_linux.c
vendored
Normal file
269
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/ubuntu/HAL_TCP_linux.c
vendored
Normal file
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netdb.h>
|
||||
#include "infra_config.h"
|
||||
|
||||
static uint64_t _linux_get_time_ms(void)
|
||||
{
|
||||
struct timeval tv = { 0 };
|
||||
uint64_t time_ms;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
time_ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
||||
|
||||
return time_ms;
|
||||
}
|
||||
|
||||
static uint64_t _linux_time_left(uint64_t t_end, uint64_t t_now)
|
||||
{
|
||||
uint64_t t_left;
|
||||
|
||||
if (t_end > t_now) {
|
||||
t_left = t_end - t_now;
|
||||
} else {
|
||||
t_left = 0;
|
||||
}
|
||||
|
||||
return t_left;
|
||||
}
|
||||
|
||||
uintptr_t HAL_TCP_Establish(const char *host, uint16_t port)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *addrInfoList = NULL;
|
||||
struct addrinfo *cur = NULL;
|
||||
int fd = 0;
|
||||
int rc = 0;
|
||||
char service[6];
|
||||
uint8_t dns_retry = 0;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
|
||||
printf("establish tcp connection with server(host='%s', port=[%u])\n", host, port);
|
||||
|
||||
hints.ai_family = AF_INET; /* only IPv4 */
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
sprintf(service, "%u", port);
|
||||
|
||||
while(dns_retry++ < 8) {
|
||||
rc = getaddrinfo(host, service, &hints, &addrInfoList);
|
||||
if (rc != 0) {
|
||||
printf("getaddrinfo error[%d], res: %s, host: %s, port: %s\n", dns_retry, gai_strerror(rc), host, service);
|
||||
sleep(1);
|
||||
continue;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
printf("getaddrinfo error(%d), host = '%s', port = [%d]\n", rc, host, port);
|
||||
return (uintptr_t)(-1);
|
||||
}
|
||||
|
||||
for (cur = addrInfoList; cur != NULL; cur = cur->ai_next) {
|
||||
if (cur->ai_family != AF_INET) {
|
||||
printf("socket type error\n");
|
||||
rc = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
fd = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol);
|
||||
if (fd < 0) {
|
||||
printf("create socket error\n");
|
||||
rc = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (connect(fd, cur->ai_addr, cur->ai_addrlen) == 0) {
|
||||
rc = fd;
|
||||
break;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
printf("connect error\n");
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
if (-1 == rc) {
|
||||
printf("fail to establish tcp\n");
|
||||
} else {
|
||||
printf("success to establish tcp, fd=%d\n", rc);
|
||||
}
|
||||
freeaddrinfo(addrInfoList);
|
||||
|
||||
return (uintptr_t)rc;
|
||||
}
|
||||
|
||||
int HAL_TCP_Destroy(uintptr_t fd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* Shutdown both send and receive operations. */
|
||||
rc = shutdown((int) fd, 2);
|
||||
if (0 != rc) {
|
||||
printf("shutdown error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = close((int) fd);
|
||||
if (0 != rc) {
|
||||
printf("closesocket error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t HAL_TCP_Write(uintptr_t fd, const char *buf, uint32_t len, uint32_t timeout_ms)
|
||||
{
|
||||
int ret,tcp_fd;
|
||||
uint32_t len_sent;
|
||||
uint64_t t_end, t_left;
|
||||
fd_set sets;
|
||||
int net_err = 0;
|
||||
|
||||
t_end = _linux_get_time_ms() + timeout_ms;
|
||||
len_sent = 0;
|
||||
ret = 1; /* send one time if timeout_ms is value 0 */
|
||||
|
||||
if (fd >= FD_SETSIZE) {
|
||||
return -1;
|
||||
}
|
||||
tcp_fd = (int)fd;
|
||||
|
||||
do {
|
||||
t_left = _linux_time_left(t_end, _linux_get_time_ms());
|
||||
|
||||
if (0 != t_left) {
|
||||
struct timeval timeout;
|
||||
|
||||
FD_ZERO(&sets);
|
||||
FD_SET(tcp_fd, &sets);
|
||||
|
||||
timeout.tv_sec = t_left / 1000;
|
||||
timeout.tv_usec = (t_left % 1000) * 1000;
|
||||
|
||||
ret = select(tcp_fd + 1, NULL, &sets, NULL, &timeout);
|
||||
if (ret > 0) {
|
||||
if (0 == FD_ISSET(tcp_fd, &sets)) {
|
||||
printf("Should NOT arrive\n");
|
||||
/* If timeout in next loop, it will not sent any data */
|
||||
ret = 0;
|
||||
continue;
|
||||
}
|
||||
} else if (0 == ret) {
|
||||
printf("select-write timeout %d\n", tcp_fd);
|
||||
break;
|
||||
} else {
|
||||
if (EINTR == errno) {
|
||||
printf("EINTR be caught\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("select-write fail, ret = select() = %d\n", ret);
|
||||
net_err = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret > 0) {
|
||||
ret = send(tcp_fd, buf + len_sent, len - len_sent, 0);
|
||||
if (ret > 0) {
|
||||
len_sent += ret;
|
||||
} else if (0 == ret) {
|
||||
printf("No data be sent\n");
|
||||
} else {
|
||||
if (EINTR == errno) {
|
||||
printf("EINTR be caught\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("send fail, ret = send() = %d\n", ret);
|
||||
net_err = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (!net_err && (len_sent < len) && (_linux_time_left(t_end, _linux_get_time_ms()) > 0));
|
||||
|
||||
if (net_err) {
|
||||
return -1;
|
||||
} else {
|
||||
return len_sent;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t HAL_TCP_Read(uintptr_t fd, char *buf, uint32_t len, uint32_t timeout_ms)
|
||||
{
|
||||
int ret, err_code, tcp_fd;
|
||||
uint32_t len_recv;
|
||||
uint64_t t_end, t_left;
|
||||
fd_set sets;
|
||||
struct timeval timeout;
|
||||
|
||||
t_end = _linux_get_time_ms() + timeout_ms;
|
||||
len_recv = 0;
|
||||
err_code = 0;
|
||||
|
||||
if (fd >= FD_SETSIZE) {
|
||||
return -1;
|
||||
}
|
||||
tcp_fd = (int)fd;
|
||||
|
||||
do {
|
||||
t_left = _linux_time_left(t_end, _linux_get_time_ms());
|
||||
if (0 == t_left) {
|
||||
break;
|
||||
}
|
||||
FD_ZERO(&sets);
|
||||
FD_SET(tcp_fd, &sets);
|
||||
|
||||
timeout.tv_sec = t_left / 1000;
|
||||
timeout.tv_usec = (t_left % 1000) * 1000;
|
||||
|
||||
ret = select(tcp_fd + 1, &sets, NULL, NULL, &timeout);
|
||||
if (ret > 0) {
|
||||
ret = recv(tcp_fd, buf + len_recv, len - len_recv, 0);
|
||||
if (ret > 0) {
|
||||
len_recv += ret;
|
||||
} else if (0 == ret) {
|
||||
printf("connection is closed\n");
|
||||
err_code = -1;
|
||||
break;
|
||||
} else {
|
||||
if (EINTR == errno) {
|
||||
continue;
|
||||
}
|
||||
printf("recv fail\n");
|
||||
err_code = -2;
|
||||
break;
|
||||
}
|
||||
} else if (0 == ret) {
|
||||
break;
|
||||
} else {
|
||||
if (EINTR == errno) {
|
||||
continue;
|
||||
}
|
||||
printf("select-recv fail\n");
|
||||
err_code = -2;
|
||||
break;
|
||||
}
|
||||
} while ((len_recv < len));
|
||||
|
||||
/* priority to return data bytes if any data be received from TCP connection. */
|
||||
/* It will get error code on next calling */
|
||||
return (0 != len_recv) ? len_recv : err_code;
|
||||
}
|
218
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/ubuntu/HAL_UART_linux.c
vendored
Normal file
218
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/ubuntu/HAL_UART_linux.c
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#if defined(__UBUNTU_SDK_DEMO__)
|
||||
#include <execinfo.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/select.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "infra_config.h"
|
||||
#include "at_parser.h"
|
||||
#include "at_wrapper.h"
|
||||
|
||||
static int at_uart_fd = -1;
|
||||
|
||||
static int read_and_discard_all_data(const int fd)
|
||||
{
|
||||
int was_msg_already_printed = 0;
|
||||
int errno_code;
|
||||
|
||||
while (1) {
|
||||
char buffer[1024];
|
||||
const ssize_t read_count = read(fd, buffer, sizeof(buffer));
|
||||
|
||||
if (read_count == 0) {
|
||||
/* "EOF" or "connection closed at the other end"*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (read_count > 0) {
|
||||
if (!was_msg_already_printed) {
|
||||
printf("Some stale data was discarded.\r\n");
|
||||
was_msg_already_printed = 1;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(read_count == -1); /* According to the specification. */
|
||||
|
||||
errno_code = errno;
|
||||
|
||||
if (errno_code == EINTR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (errno_code == EAGAIN ||
|
||||
errno_code == EWOULDBLOCK) {
|
||||
/**
|
||||
* We know that the file descriptor has been opened with
|
||||
* O_NONBLOCK or O_NDELAY, and these codes mean that there
|
||||
* is no data to read at present.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Some other error has occurred. */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t HAL_AT_Uart_Init(uart_dev_t *uart)
|
||||
{
|
||||
int fd;
|
||||
struct termios t_opt;
|
||||
speed_t baud;
|
||||
|
||||
if (uart->port != AT_UART_PORT) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((at_uart_fd = open(AT_UART_LINUX_DEV,
|
||||
O_RDWR | O_NOCTTY | O_NDELAY)) == -1) {
|
||||
printf("open at uart failed\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (uart->config.baud_rate) {
|
||||
case 115200:
|
||||
baud = B115200;
|
||||
break;
|
||||
case 921600:
|
||||
baud = B921600;
|
||||
break;
|
||||
default:
|
||||
baud = B115200;
|
||||
break;
|
||||
}
|
||||
|
||||
fd = at_uart_fd;
|
||||
/* set the serial port parameters */
|
||||
fcntl(fd, F_SETFL, 0);
|
||||
if (0 != tcgetattr(fd, &t_opt)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 != cfsetispeed(&t_opt, baud)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 != cfsetospeed(&t_opt, baud)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 8N1, flow control, etc. */
|
||||
t_opt.c_cflag |= (CLOCAL | CREAD);
|
||||
if (uart->config.parity == NO_PARITY) {
|
||||
t_opt.c_cflag &= ~PARENB;
|
||||
}
|
||||
if (uart->config.stop_bits == STOP_BITS_1) {
|
||||
t_opt.c_cflag &= ~CSTOPB;
|
||||
} else {
|
||||
t_opt.c_cflag |= CSTOPB;
|
||||
}
|
||||
t_opt.c_cflag &= ~CSIZE;
|
||||
switch (uart->config.data_width) {
|
||||
case DATA_WIDTH_5BIT:
|
||||
t_opt.c_cflag |= CS5;
|
||||
break;
|
||||
case DATA_WIDTH_6BIT:
|
||||
t_opt.c_cflag |= CS6;
|
||||
break;
|
||||
case DATA_WIDTH_7BIT:
|
||||
t_opt.c_cflag |= CS7;
|
||||
break;
|
||||
case DATA_WIDTH_8BIT:
|
||||
t_opt.c_cflag |= CS8;
|
||||
break;
|
||||
default:
|
||||
t_opt.c_cflag |= CS8;
|
||||
break;
|
||||
}
|
||||
t_opt.c_lflag &= ~(ECHO | ECHOE | ISIG | ICANON);
|
||||
|
||||
/**
|
||||
* AT is going to use a binary protocol, so make sure to
|
||||
* turn off any CR/LF translation and the like.
|
||||
*/
|
||||
t_opt.c_iflag &= ~(IXON | IXOFF | IXANY | INLCR | ICRNL);
|
||||
|
||||
t_opt.c_oflag &= ~OPOST;
|
||||
t_opt.c_cc[VMIN] = 0;
|
||||
t_opt.c_cc[VTIME] = 5;
|
||||
|
||||
if (0 != tcsetattr(fd, TCSANOW, &t_opt)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("open at uart succeed\r\n");
|
||||
|
||||
/* clear uart buffer */
|
||||
read_and_discard_all_data(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t HAL_AT_Uart_Deinit(uart_dev_t *uart)
|
||||
{
|
||||
if (uart->port == AT_UART_PORT) {
|
||||
close(at_uart_fd);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t HAL_AT_Uart_Send(uart_dev_t *uart, const void *data,
|
||||
uint32_t size, uint32_t timeout)
|
||||
{
|
||||
uint32_t ret, rmd = size;
|
||||
|
||||
if (uart->port == AT_UART_PORT) {
|
||||
while (rmd > 0) {
|
||||
ret = write(at_uart_fd, data + size - rmd, rmd);
|
||||
if (ret == -1) {
|
||||
printf("write uart fd failed on error: %d.\r\n", errno);
|
||||
return -1;
|
||||
}
|
||||
rmd -= ret;
|
||||
}
|
||||
} else {
|
||||
if (write(1, data, size) < 0) {
|
||||
printf("write failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t HAL_AT_Uart_Recv(uart_dev_t *uart, void *data, uint32_t expect_size,
|
||||
uint32_t *recv_size, uint32_t timeout)
|
||||
{
|
||||
int fd, n;
|
||||
|
||||
if (uart->port == AT_UART_PORT) {
|
||||
fd = at_uart_fd;
|
||||
} else {
|
||||
fd = 1;
|
||||
}
|
||||
|
||||
if ((n = read(fd, data, expect_size)) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (uart->port != AT_UART_PORT && *(char *)data == '\n') {
|
||||
*(char *)data = '\r';
|
||||
}
|
||||
if (recv_size) {
|
||||
*recv_size = n;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
375
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/ubuntu/HAL_UDP_linux.c
vendored
Normal file
375
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/os/ubuntu/HAL_UDP_linux.c
vendored
Normal file
@@ -0,0 +1,375 @@
|
||||
#include "infra_config.h"
|
||||
|
||||
#if defined(HAL_UDP)
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "infra_config.h"
|
||||
#include "infra_compat.h"
|
||||
|
||||
intptr_t HAL_UDP_create(char *host, unsigned short port)
|
||||
{
|
||||
#define NETWORK_ADDR_LEN (16)
|
||||
|
||||
int rc = -1;
|
||||
long socket_id = -1;
|
||||
char port_ptr[6] = {0};
|
||||
struct addrinfo hints;
|
||||
char addr[NETWORK_ADDR_LEN] = {0};
|
||||
struct addrinfo *res, *ainfo;
|
||||
struct sockaddr_in *sa = NULL;
|
||||
|
||||
if (NULL == host) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
sprintf(port_ptr, "%u", port);
|
||||
memset((char *)&hints, 0x00, sizeof(hints));
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_protocol = IPPROTO_UDP;
|
||||
|
||||
rc = getaddrinfo(host, port_ptr, &hints, &res);
|
||||
if (0 != rc) {
|
||||
printf("getaddrinfo error");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
for (ainfo = res; ainfo != NULL; ainfo = ainfo->ai_next) {
|
||||
if (AF_INET == ainfo->ai_family) {
|
||||
sa = (struct sockaddr_in *)ainfo->ai_addr;
|
||||
inet_ntop(AF_INET, &sa->sin_addr, addr, NETWORK_ADDR_LEN);
|
||||
fprintf(stderr, "The host IP %s, port is %d\r\n", addr, ntohs(sa->sin_port));
|
||||
|
||||
socket_id = socket(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol);
|
||||
if (socket_id < 0) {
|
||||
printf("create socket error");
|
||||
continue;
|
||||
}
|
||||
if (0 == connect(socket_id, ainfo->ai_addr, ainfo->ai_addrlen)) {
|
||||
break;
|
||||
}
|
||||
|
||||
close(socket_id);
|
||||
}
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
|
||||
return socket_id;
|
||||
|
||||
#undef NETWORK_ADDR_LEN
|
||||
}
|
||||
|
||||
void HAL_UDP_close(intptr_t p_socket)
|
||||
{
|
||||
long socket_id = -1;
|
||||
|
||||
socket_id = p_socket;
|
||||
close(socket_id);
|
||||
}
|
||||
|
||||
int HAL_UDP_write(intptr_t p_socket,
|
||||
const unsigned char *p_data,
|
||||
unsigned int datalen)
|
||||
{
|
||||
int rc = -1;
|
||||
long socket_id = -1;
|
||||
|
||||
socket_id = (long)p_socket;
|
||||
rc = send(socket_id, (char *)p_data, (int)datalen, 0);
|
||||
if (-1 == rc) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int HAL_UDP_readTimeout(intptr_t p_socket,
|
||||
unsigned char *p_data,
|
||||
unsigned int datalen,
|
||||
unsigned int timeout)
|
||||
{
|
||||
int ret;
|
||||
struct timeval tv;
|
||||
fd_set read_fds;
|
||||
long socket_id = -1;
|
||||
|
||||
if (0 == p_socket || NULL == p_data) {
|
||||
return -1;
|
||||
}
|
||||
socket_id = (long)p_socket;
|
||||
|
||||
if (socket_id < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
FD_ZERO(&read_fds);
|
||||
FD_SET(socket_id, &read_fds);
|
||||
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout % 1000) * 1000;
|
||||
|
||||
ret = select(socket_id + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv);
|
||||
|
||||
/* Zero fds ready means we timed out */
|
||||
if (ret == 0) {
|
||||
return -2; /* receive timeout */
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
if (errno == EINTR) {
|
||||
return -3; /* want read */
|
||||
}
|
||||
|
||||
return -4; /* receive failed */
|
||||
}
|
||||
|
||||
/* This call will not block */
|
||||
return read(p_socket, p_data, datalen);
|
||||
}
|
||||
|
||||
intptr_t HAL_UDP_create_without_connect(const char *host, unsigned short port)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
long sockfd;
|
||||
int opt_val = 1;
|
||||
struct hostent *hp;
|
||||
struct in_addr in;
|
||||
uint32_t ip;
|
||||
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sockfd < 0) {
|
||||
printf("socket");
|
||||
return -1;
|
||||
}
|
||||
if (0 == port) {
|
||||
return (intptr_t)sockfd;
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof(struct sockaddr_in));
|
||||
|
||||
if (0 != setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR | SO_BROADCAST, &opt_val, sizeof(opt_val))) {
|
||||
printf("setsockopt");
|
||||
close(sockfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == host) {
|
||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
} else {
|
||||
if (inet_aton(host, &in)) {
|
||||
ip = *(uint32_t *)∈
|
||||
} else {
|
||||
hp = gethostbyname(host);
|
||||
if (!hp) {
|
||||
printf("can't resolute the host address \n");
|
||||
close(sockfd);
|
||||
return -1;
|
||||
}
|
||||
ip = *(uint32_t *)(hp->h_addr);
|
||||
}
|
||||
addr.sin_addr.s_addr = ip;
|
||||
}
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
|
||||
if (-1 == bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in))) {
|
||||
close(sockfd);
|
||||
return -1;
|
||||
}
|
||||
printf("success to establish udp, fd=%d", (int)sockfd);
|
||||
|
||||
return (intptr_t)sockfd;
|
||||
}
|
||||
|
||||
int HAL_UDP_connect(intptr_t sockfd,
|
||||
const char *host,
|
||||
unsigned short port)
|
||||
{
|
||||
int rc = -1;
|
||||
char port_ptr[6] = {0};
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *res, *ainfo;
|
||||
|
||||
if (NULL == host) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("HAL_UDP_connect, host=%s, port=%d", host, port);
|
||||
sprintf(port_ptr, "%u", port);
|
||||
memset((char *)&hints, 0x00, sizeof(hints));
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_protocol = IPPROTO_UDP;
|
||||
|
||||
rc = getaddrinfo(host, port_ptr, &hints, &res);
|
||||
if (0 != rc) {
|
||||
printf("getaddrinfo error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (ainfo = res; ainfo != NULL; ainfo = ainfo->ai_next) {
|
||||
if (AF_INET == ainfo->ai_family) {
|
||||
if (0 == connect(sockfd, ainfo->ai_addr, ainfo->ai_addrlen)) {
|
||||
freeaddrinfo(res);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int HAL_UDP_close_without_connect(intptr_t sockfd)
|
||||
{
|
||||
return close((int)sockfd);
|
||||
}
|
||||
|
||||
int HAL_UDP_joinmulticast(intptr_t sockfd,
|
||||
char *p_group)
|
||||
{
|
||||
int err = -1;
|
||||
int socket_id = -1;
|
||||
int loop = 0;
|
||||
struct ip_mreq mreq;
|
||||
|
||||
if (NULL == p_group) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*set loopback*/
|
||||
socket_id = (int)sockfd;
|
||||
err = setsockopt(socket_id, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));
|
||||
if (err < 0) {
|
||||
printf("setsockopt");
|
||||
return err;
|
||||
}
|
||||
|
||||
mreq.imr_multiaddr.s_addr = inet_addr(p_group);
|
||||
mreq.imr_interface.s_addr = htonl(INADDR_ANY); /*default networt interface*/
|
||||
|
||||
/*join to the multicast group*/
|
||||
err = setsockopt(socket_id, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
|
||||
if (err < 0) {
|
||||
printf("setsockopt");
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HAL_UDP_recvfrom(intptr_t sockfd,
|
||||
NetworkAddr *p_remote,
|
||||
unsigned char *p_data,
|
||||
unsigned int datalen,
|
||||
unsigned int timeout_ms)
|
||||
{
|
||||
int ret;
|
||||
struct sockaddr_in addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
fd_set read_fds;
|
||||
struct timeval timeout = {timeout_ms / 1000, (timeout_ms % 1000) * 1000};
|
||||
|
||||
FD_ZERO(&read_fds);
|
||||
FD_SET(sockfd, &read_fds);
|
||||
|
||||
ret = select(sockfd + 1, &read_fds, NULL, NULL, &timeout);
|
||||
if (ret == 0) {
|
||||
return 0; /* receive timeout */
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
if (errno == EINTR) {
|
||||
return -3; /* want read */
|
||||
}
|
||||
return -4; /* receive failed */
|
||||
}
|
||||
|
||||
ret = recvfrom(sockfd, p_data, datalen, 0, (struct sockaddr *)&addr, &addr_len);
|
||||
if (ret > 0) {
|
||||
if (NULL != p_remote) {
|
||||
p_remote->port = ntohs(addr.sin_port);
|
||||
|
||||
strcpy((char *)p_remote->addr, inet_ntoa(addr.sin_addr));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int HAL_UDP_sendto(intptr_t sockfd,
|
||||
const NetworkAddr *p_remote,
|
||||
const unsigned char *p_data,
|
||||
unsigned int datalen,
|
||||
unsigned int timeout_ms)
|
||||
{
|
||||
int ret;
|
||||
uint32_t ip;
|
||||
struct in_addr in;
|
||||
struct hostent *hp;
|
||||
struct sockaddr_in addr;
|
||||
fd_set write_fds;
|
||||
struct timeval timeout = {timeout_ms / 1000, (timeout_ms % 1000) * 1000};
|
||||
|
||||
if (inet_aton((char *)p_remote->addr, &in)) {
|
||||
ip = *(uint32_t *)∈
|
||||
} else {
|
||||
hp = gethostbyname((char *)p_remote->addr);
|
||||
if (!hp) {
|
||||
printf("can't resolute the host address \n");
|
||||
return -1;
|
||||
}
|
||||
ip = *(uint32_t *)(hp->h_addr);
|
||||
}
|
||||
|
||||
FD_ZERO(&write_fds);
|
||||
FD_SET(sockfd, &write_fds);
|
||||
|
||||
ret = select(sockfd + 1, NULL, &write_fds, NULL, &timeout);
|
||||
if (ret == 0) {
|
||||
return 0; /* write timeout */
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
if (errno == EINTR) {
|
||||
return -3; /* want write */
|
||||
}
|
||||
return -4; /* write failed */
|
||||
}
|
||||
|
||||
addr.sin_addr.s_addr = ip;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(p_remote->port);
|
||||
|
||||
ret = sendto(sockfd, p_data, datalen, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
|
||||
|
||||
if (ret < 0) {
|
||||
printf("sendto");
|
||||
}
|
||||
|
||||
return (ret) > 0 ? ret : -1;
|
||||
}
|
||||
|
||||
#endif /* #if defined(HAL_UDP) */
|
||||
|
||||
|
||||
|
517
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/tls/HAL_DTLS_mbedtls.c
vendored
Normal file
517
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/tls/HAL_DTLS_mbedtls.c
vendored
Normal file
@@ -0,0 +1,517 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "infra_config.h"
|
||||
#ifdef COAP_DTLS_SUPPORT
|
||||
#include "wrappers_defs.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/debug.h"
|
||||
#include "mbedtls/timing.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/ssl_cookie.h"
|
||||
#include "mbedtls/net_sockets.h"
|
||||
|
||||
void *HAL_Malloc(uint32_t size);
|
||||
void HAL_Free(void *ptr);
|
||||
void HAL_Printf(const char *fmt, ...);
|
||||
|
||||
#define DTLS_TRC(...) HAL_Printf("[trc] "), HAL_Printf(__VA_ARGS__)
|
||||
#define DTLS_DUMP(...) HAL_Printf("[dump] "), HAL_Printf(__VA_ARGS__)
|
||||
#define DTLS_DEBUG(...) HAL_Printf("[dbg] "), HAL_Printf(__VA_ARGS__)
|
||||
#define DTLS_INFO(...) HAL_Printf("[inf] "), HAL_Printf(__VA_ARGS__)
|
||||
#define DTLS_ERR(...) HAL_Printf("[err] "), HAL_Printf(__VA_ARGS__)
|
||||
|
||||
#ifdef DTLS_SESSION_SAVE
|
||||
mbedtls_ssl_session *saved_session = NULL;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
mbedtls_ssl_context context;
|
||||
mbedtls_ssl_config conf;
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
mbedtls_entropy_context entropy;
|
||||
#ifdef MBEDTLS_X509_CRT_PARSE_C
|
||||
mbedtls_x509_crt cacert;
|
||||
#endif
|
||||
mbedtls_net_context fd;
|
||||
mbedtls_timing_delay_context timer;
|
||||
mbedtls_ssl_cookie_ctx cookie_ctx;
|
||||
} dtls_session_t;
|
||||
|
||||
#define MBEDTLS_MEM_TEST 1
|
||||
|
||||
#ifdef MBEDTLS_MEM_TEST
|
||||
|
||||
#define MBEDTLS_MEM_INFO_MAGIC 0x12345678
|
||||
|
||||
static unsigned int mbedtls_mem_used = 0;
|
||||
static unsigned int mbedtls_max_mem_used = 0;
|
||||
static dtls_hooks_t g_dtls_hooks = {HAL_Malloc, HAL_Free};
|
||||
|
||||
typedef struct {
|
||||
int magic;
|
||||
int size;
|
||||
} mbedtls_mem_info_t;
|
||||
|
||||
void *_DTLSCalloc_wrapper(size_t n, size_t size)
|
||||
{
|
||||
void *buf = NULL;
|
||||
mbedtls_mem_info_t *mem_info = NULL;
|
||||
|
||||
if (n == 0 || size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf = g_dtls_hooks.malloc(n * size + sizeof(mbedtls_mem_info_t));
|
||||
if (NULL == buf) {
|
||||
return NULL;
|
||||
} else {
|
||||
memset(buf, 0, n * size + sizeof(mbedtls_mem_info_t));
|
||||
}
|
||||
|
||||
mem_info = (mbedtls_mem_info_t *)buf;
|
||||
mem_info->magic = MBEDTLS_MEM_INFO_MAGIC;
|
||||
mem_info->size = n * size;
|
||||
buf += sizeof(mbedtls_mem_info_t);
|
||||
|
||||
mbedtls_mem_used += mem_info->size;
|
||||
if (mbedtls_mem_used > mbedtls_max_mem_used) {
|
||||
mbedtls_max_mem_used = mbedtls_mem_used;
|
||||
}
|
||||
|
||||
/* DTLS_TRC("INFO -- mbedtls malloc: %p %d total used: %d max used: %d\r\n",
|
||||
buf, (int)size, mbedtls_mem_used, mbedtls_max_mem_used); */
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void _DTLSFree_wrapper(void *ptr)
|
||||
{
|
||||
mbedtls_mem_info_t *mem_info = NULL;
|
||||
if (NULL == ptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
mem_info = ptr - sizeof(mbedtls_mem_info_t);
|
||||
if (mem_info->magic != MBEDTLS_MEM_INFO_MAGIC) {
|
||||
DTLS_TRC("Warning - invalid mem info magic: 0x%x\r\n", mem_info->magic);
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_mem_used -= mem_info->size;
|
||||
/* DTLS_TRC("INFO mbedtls free: %p %d total used: %d max used: %d\r\n",
|
||||
ptr, mem_info->size, mbedtls_mem_used, mbedtls_max_mem_used);*/
|
||||
|
||||
g_dtls_hooks.free(mem_info);
|
||||
}
|
||||
|
||||
#else
|
||||
static void *_DTLSCalloc_wrapper(size_t n, size_t s)
|
||||
{
|
||||
void *ptr = NULL;
|
||||
size_t len = n * s;
|
||||
ptr = HAL_Malloc(len);
|
||||
if (NULL != ptr) {
|
||||
memset(ptr, 0x00, len);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void _DTLSFree_wrapper(void *ptr)
|
||||
{
|
||||
if (NULL != ptr) {
|
||||
HAL_Free(ptr);
|
||||
ptr = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DTLS_SESSION_SAVE
|
||||
static int _DTLSSession_save(const mbedtls_ssl_session *session,
|
||||
unsigned char *buf, size_t buf_len,
|
||||
size_t *olen)
|
||||
{
|
||||
unsigned char *p = buf;
|
||||
size_t left = buf_len;
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
size_t cert_len;
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
||||
if (left < sizeof(mbedtls_ssl_session)) {
|
||||
return (MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL);
|
||||
}
|
||||
|
||||
memcpy(p, session, sizeof(mbedtls_ssl_session));
|
||||
p += sizeof(mbedtls_ssl_session);
|
||||
left -= sizeof(mbedtls_ssl_session);
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
if (session->peer_cert == NULL) {
|
||||
cert_len = 0;
|
||||
} else {
|
||||
cert_len = session->peer_cert->raw.len;
|
||||
}
|
||||
|
||||
if (left < 3 + cert_len) {
|
||||
return (MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL);
|
||||
}
|
||||
|
||||
*p++ = (unsigned char)(cert_len >> 16 & 0xFF);
|
||||
*p++ = (unsigned char)(cert_len >> 8 & 0xFF);
|
||||
*p++ = (unsigned char)(cert_len & 0xFF);
|
||||
|
||||
if (session->peer_cert != NULL) {
|
||||
memcpy(p, session->peer_cert->raw.p, cert_len);
|
||||
}
|
||||
|
||||
p += cert_len;
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
||||
*olen = p - buf;
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned int _DTLSVerifyOptions_set(dtls_session_t *p_dtls_session, unsigned char *p_ca_cert_pem, char *host)
|
||||
{
|
||||
int result;
|
||||
unsigned int err_code = DTLS_SUCCESS;
|
||||
|
||||
#ifdef MBEDTLS_X509_CRT_PARSE_C
|
||||
if (p_ca_cert_pem != NULL) {
|
||||
mbedtls_ssl_conf_authmode(&p_dtls_session->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
|
||||
if (strstr(host, "pre.iot-as-coap")) {
|
||||
DTLS_TRC("host = '%s' so verify server OPTIONAL\r\n", host);
|
||||
mbedtls_ssl_conf_authmode(&p_dtls_session->conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
|
||||
}
|
||||
DTLS_TRC("Call mbedtls_ssl_conf_authmode\r\n");
|
||||
|
||||
DTLS_TRC("x509 ca cert pem len %d\r\n%s\r\n", (int)strlen((char *)p_ca_cert_pem) + 1, p_ca_cert_pem);
|
||||
result = mbedtls_x509_crt_parse(&p_dtls_session->cacert,
|
||||
p_ca_cert_pem,
|
||||
strlen((const char *)p_ca_cert_pem) + 1);
|
||||
|
||||
DTLS_TRC("mbedtls_x509_crt_parse result 0x%04x\r\n", result);
|
||||
if (0 != result) {
|
||||
err_code = DTLS_INVALID_CA_CERTIFICATE;
|
||||
} else {
|
||||
mbedtls_ssl_conf_ca_chain(&p_dtls_session->conf, &p_dtls_session->cacert, NULL);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
mbedtls_ssl_conf_authmode(&p_dtls_session->conf, MBEDTLS_SSL_VERIFY_NONE);
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static void _DTLSLog_wrapper(void *p_ctx, int level,
|
||||
const char *p_file, int line, const char *p_str)
|
||||
{
|
||||
DTLS_INFO("[mbedTLS]:[%s]:[%d]: %s\r\n", p_file, line, p_str);
|
||||
}
|
||||
|
||||
static unsigned int _DTLSContext_setup(dtls_session_t *p_dtls_session, coap_dtls_options_t *p_options)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
mbedtls_ssl_init(&p_dtls_session->context);
|
||||
|
||||
result = mbedtls_ssl_setup(&p_dtls_session->context, &p_dtls_session->conf);
|
||||
DTLS_TRC("mbedtls_ssl_setup result 0x%04x\r\n", result);
|
||||
|
||||
if (result == 0) {
|
||||
if (p_dtls_session->conf.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
|
||||
mbedtls_ssl_set_timer_cb(&p_dtls_session->context,
|
||||
(void *)&p_dtls_session->timer,
|
||||
mbedtls_timing_set_delay,
|
||||
mbedtls_timing_get_delay);
|
||||
}
|
||||
|
||||
#ifdef MBEDTLS_X509_CRT_PARSE_C
|
||||
DTLS_TRC("mbedtls_ssl_set_hostname %s\r\n", p_options->p_host);
|
||||
mbedtls_ssl_set_hostname(&p_dtls_session->context, p_options->p_host);
|
||||
#endif
|
||||
mbedtls_ssl_set_bio(&p_dtls_session->context,
|
||||
(void *)&p_dtls_session->fd,
|
||||
mbedtls_net_send,
|
||||
mbedtls_net_recv,
|
||||
mbedtls_net_recv_timeout);
|
||||
DTLS_TRC("mbedtls_ssl_set_bio result 0x%04x\r\n", result);
|
||||
|
||||
#ifdef DTLS_SESSION_SAVE
|
||||
if (NULL != saved_session) {
|
||||
result = mbedtls_ssl_set_session(&p_dtls_session->context, saved_session);
|
||||
DTLS_TRC("mbedtls_ssl_set_session return 0x%04x\r\n", result);
|
||||
}
|
||||
#endif
|
||||
|
||||
do {
|
||||
result = mbedtls_ssl_handshake(&p_dtls_session->context);
|
||||
} while (result == MBEDTLS_ERR_SSL_WANT_READ ||
|
||||
result == MBEDTLS_ERR_SSL_WANT_WRITE);
|
||||
DTLS_TRC("mbedtls_ssl_handshake result 0x%04x\r\n", result);
|
||||
#ifdef MBEDTLS_MEM_TEST
|
||||
DTLS_TRC("mbedtls handshake memory total used: %d max used: %d\r\n",
|
||||
mbedtls_mem_used, mbedtls_max_mem_used);
|
||||
#endif
|
||||
|
||||
#ifdef DTLS_SESSION_SAVE
|
||||
if (0 == result) {
|
||||
if (NULL == saved_session) {
|
||||
saved_session = HAL_Malloc(sizeof(mbedtls_ssl_session));
|
||||
}
|
||||
if (NULL != saved_session) {
|
||||
memset(saved_session, 0x00, sizeof(mbedtls_ssl_session));
|
||||
result = mbedtls_ssl_get_session(&p_dtls_session->context, saved_session);
|
||||
DTLS_TRC("mbedtls_ssl_get_session return 0x%04x\r\n", result);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return (result ? DTLS_HANDSHAKE_FAILED : DTLS_SUCCESS);
|
||||
}
|
||||
|
||||
dtls_session_t *_DTLSSession_init()
|
||||
{
|
||||
dtls_session_t *p_dtls_session = NULL;
|
||||
p_dtls_session = HAL_Malloc(sizeof(dtls_session_t));
|
||||
|
||||
mbedtls_debug_set_threshold(0);
|
||||
#ifdef MBEDTLS_MEM_TEST
|
||||
mbedtls_mem_used = 0;
|
||||
mbedtls_max_mem_used = 0;
|
||||
#endif
|
||||
mbedtls_platform_set_calloc_free(_DTLSCalloc_wrapper, _DTLSFree_wrapper);
|
||||
if (NULL != p_dtls_session) {
|
||||
mbedtls_net_init(&p_dtls_session->fd);
|
||||
mbedtls_ssl_init(&p_dtls_session->context);
|
||||
mbedtls_ssl_config_init(&p_dtls_session->conf);
|
||||
mbedtls_net_init(&p_dtls_session->fd);
|
||||
|
||||
mbedtls_ssl_cookie_init(&p_dtls_session->cookie_ctx);
|
||||
|
||||
#ifdef MBEDTLS_X509_CRT_PARSE_C
|
||||
mbedtls_x509_crt_init(&p_dtls_session->cacert);
|
||||
#endif
|
||||
mbedtls_ctr_drbg_init(&p_dtls_session->ctr_drbg);
|
||||
mbedtls_entropy_init(&p_dtls_session->entropy);
|
||||
DTLS_INFO("HAL_DTLSSession_init success\r\n");
|
||||
|
||||
}
|
||||
|
||||
return p_dtls_session;
|
||||
}
|
||||
|
||||
unsigned int _DTLSSession_deinit(dtls_session_t *p_dtls_session)
|
||||
{
|
||||
int ret;
|
||||
if (p_dtls_session != NULL) {
|
||||
do {
|
||||
ret = mbedtls_ssl_close_notify(&p_dtls_session->context);
|
||||
} while (ret == MBEDTLS_ERR_SSL_WANT_WRITE);
|
||||
|
||||
mbedtls_net_free(&p_dtls_session->fd);
|
||||
#ifdef MBEDTLS_X509_CRT_PARSE_C
|
||||
mbedtls_x509_crt_free(&p_dtls_session->cacert);
|
||||
#endif
|
||||
mbedtls_ssl_cookie_free(&p_dtls_session->cookie_ctx);
|
||||
|
||||
mbedtls_ssl_config_free(&p_dtls_session->conf);
|
||||
mbedtls_ssl_free(&p_dtls_session->context);
|
||||
|
||||
mbedtls_ctr_drbg_free(&p_dtls_session->ctr_drbg);
|
||||
mbedtls_entropy_free(&p_dtls_session->entropy);
|
||||
HAL_Free(p_dtls_session);
|
||||
}
|
||||
|
||||
return DTLS_SUCCESS;
|
||||
}
|
||||
|
||||
int HAL_DTLSHooks_set(dtls_hooks_t *hooks)
|
||||
{
|
||||
if (hooks == NULL || hooks->malloc == NULL || hooks->free == NULL) {
|
||||
return DTLS_INVALID_PARAM;
|
||||
}
|
||||
|
||||
g_dtls_hooks.malloc = hooks->malloc;
|
||||
g_dtls_hooks.free = hooks->free;
|
||||
|
||||
return DTLS_SUCCESS;
|
||||
}
|
||||
|
||||
DTLSContext *HAL_DTLSSession_create(coap_dtls_options_t *p_options)
|
||||
{
|
||||
char port[6] = {0};
|
||||
int result = 0;
|
||||
dtls_session_t *p_dtls_session = NULL;
|
||||
|
||||
p_dtls_session = _DTLSSession_init();
|
||||
if (NULL != p_dtls_session) {
|
||||
mbedtls_ssl_config_init(&p_dtls_session->conf);
|
||||
result = mbedtls_ctr_drbg_seed(&p_dtls_session->ctr_drbg, mbedtls_entropy_func, &p_dtls_session->entropy,
|
||||
(const unsigned char *)"IoTx",
|
||||
strlen("IoTx"));
|
||||
if (0 != result) {
|
||||
DTLS_ERR("mbedtls_ctr_drbg_seed result 0x%04x\r\n", result);
|
||||
goto error;
|
||||
}
|
||||
result = mbedtls_ssl_config_defaults(&p_dtls_session->conf,
|
||||
MBEDTLS_SSL_IS_CLIENT,
|
||||
MBEDTLS_SSL_TRANSPORT_DATAGRAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT);
|
||||
if (0 != result) {
|
||||
DTLS_ERR("mbedtls_ssl_config_defaults result 0x%04x\r\n", result);
|
||||
goto error;
|
||||
}
|
||||
mbedtls_ssl_conf_rng(&p_dtls_session->conf, mbedtls_ctr_drbg_random, &p_dtls_session->ctr_drbg);
|
||||
mbedtls_ssl_conf_dbg(&p_dtls_session->conf, _DTLSLog_wrapper, NULL);
|
||||
|
||||
result = mbedtls_ssl_cookie_setup(&p_dtls_session->cookie_ctx,
|
||||
mbedtls_ctr_drbg_random, &p_dtls_session->ctr_drbg);
|
||||
if (0 != result) {
|
||||
DTLS_ERR("mbedtls_ssl_cookie_setup result 0x%04x\r\n", result);
|
||||
goto error;
|
||||
}
|
||||
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
|
||||
mbedtls_ssl_conf_dtls_cookies(&p_dtls_session->conf, mbedtls_ssl_cookie_write,
|
||||
mbedtls_ssl_cookie_check, &p_dtls_session->cookie_ctx);
|
||||
#endif
|
||||
|
||||
result = _DTLSVerifyOptions_set(p_dtls_session, p_options->p_ca_cert_pem, p_options->p_host);
|
||||
|
||||
if (DTLS_SUCCESS != result) {
|
||||
DTLS_ERR("DTLSVerifyOptions_set result 0x%04x\r\n", result);
|
||||
goto error;
|
||||
}
|
||||
sprintf(port, "%u", p_options->port);
|
||||
result = mbedtls_net_connect(&p_dtls_session->fd, p_options->p_host,
|
||||
port, MBEDTLS_NET_PROTO_UDP);
|
||||
if (0 != result) {
|
||||
DTLS_ERR("mbedtls_net_connect result 0x%04x\r\n", result);
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifdef MBEDTLS_SSL_PROTO_DTLS
|
||||
if (p_dtls_session->conf.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
|
||||
mbedtls_ssl_conf_min_version(&p_dtls_session->conf,
|
||||
MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
MBEDTLS_SSL_MINOR_VERSION_3);
|
||||
|
||||
mbedtls_ssl_conf_max_version(&p_dtls_session->conf,
|
||||
MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
MBEDTLS_SSL_MINOR_VERSION_3);
|
||||
|
||||
mbedtls_ssl_conf_handshake_timeout(&p_dtls_session->conf,
|
||||
(MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN * 2),
|
||||
(MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN * 2 * 4));
|
||||
}
|
||||
#endif
|
||||
result = _DTLSContext_setup(p_dtls_session, p_options);
|
||||
if (DTLS_SUCCESS != result) {
|
||||
DTLS_ERR("DTLSVerifyOptions_set result 0x%04x\r\n", result);
|
||||
goto error;
|
||||
}
|
||||
|
||||
return (DTLSContext *)p_dtls_session;
|
||||
}
|
||||
|
||||
error:
|
||||
if (NULL != p_dtls_session) {
|
||||
_DTLSSession_deinit(p_dtls_session);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int HAL_DTLSSession_write(DTLSContext *context,
|
||||
const unsigned char *p_data,
|
||||
unsigned int *p_datalen)
|
||||
{
|
||||
int len = 0;
|
||||
unsigned int err_code = DTLS_SUCCESS;
|
||||
dtls_session_t *p_dtls_session = (dtls_session_t *)context;
|
||||
|
||||
if (NULL != p_dtls_session && NULL != p_data && p_datalen != NULL) {
|
||||
len = (*p_datalen);
|
||||
len = mbedtls_ssl_write(&p_dtls_session->context, p_data, len);
|
||||
|
||||
if (len < 0) {
|
||||
if (len == MBEDTLS_ERR_SSL_CONN_EOF) {
|
||||
if (p_dtls_session->context.state < MBEDTLS_SSL_HANDSHAKE_OVER) {
|
||||
err_code = DTLS_HANDSHAKE_IN_PROGRESS;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
(*p_datalen) = len;
|
||||
err_code = DTLS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
unsigned int HAL_DTLSSession_read(DTLSContext *context,
|
||||
unsigned char *p_data,
|
||||
unsigned int *p_datalen,
|
||||
unsigned int timeout)
|
||||
{
|
||||
int len = 0;
|
||||
unsigned int err_code = DTLS_READ_DATA_FAILED;
|
||||
dtls_session_t *p_dtls_session = (dtls_session_t *)context;
|
||||
|
||||
if (NULL != p_dtls_session && NULL != p_data && p_datalen != NULL) {
|
||||
mbedtls_ssl_conf_read_timeout(&(p_dtls_session->conf), timeout);
|
||||
len = mbedtls_ssl_read(&p_dtls_session->context, p_data, *p_datalen);
|
||||
|
||||
if (0 < len) {
|
||||
*p_datalen = len;
|
||||
err_code = DTLS_SUCCESS;
|
||||
DTLS_TRC("mbedtls_ssl_read len %d bytes\r\n", len);
|
||||
} else {
|
||||
*p_datalen = 0;
|
||||
if (MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE == len) {
|
||||
err_code = DTLS_FATAL_ALERT_MESSAGE;
|
||||
DTLS_INFO("Recv peer fatal alert message\r\n");
|
||||
} else if (MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY == len) {
|
||||
err_code = DTLS_PEER_CLOSE_NOTIFY;
|
||||
DTLS_INFO("The DTLS session was closed by peer\r\n");
|
||||
} else if (MBEDTLS_ERR_SSL_TIMEOUT == len) {
|
||||
err_code = DTLS_SUCCESS;
|
||||
DTLS_TRC("DTLS recv timeout\r\n");
|
||||
} else {
|
||||
DTLS_TRC("mbedtls_ssl_read error result (-0x%04x)\r\n", len);
|
||||
}
|
||||
}
|
||||
}
|
||||
return err_code;
|
||||
}
|
||||
|
||||
unsigned int HAL_DTLSSession_free(DTLSContext *context)
|
||||
{
|
||||
dtls_session_t *p_dtls_session = NULL;
|
||||
if (NULL != context) {
|
||||
p_dtls_session = (dtls_session_t *)context;
|
||||
return _DTLSSession_deinit(p_dtls_session);
|
||||
}
|
||||
|
||||
return DTLS_INVALID_PARAM;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
860
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/tls/HAL_TLS_mbedtls.c
vendored
Normal file
860
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/tls/HAL_TLS_mbedtls.c
vendored
Normal file
@@ -0,0 +1,860 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if defined(_PLATFORM_IS_LINUX_)
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include "infra_config.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "mbedtls/net.h"
|
||||
#include "mbedtls/x509_crt.h"
|
||||
#include "mbedtls/pk.h"
|
||||
#include "mbedtls/debug.h"
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#include "wrappers_defs.h"
|
||||
|
||||
#define SEND_TIMEOUT_SECONDS (10)
|
||||
#define GUIDER_ONLINE_HOSTNAME ("iot-auth.cn-shanghai.aliyuncs.com")
|
||||
#define GUIDER_PRE_ADDRESS ("100.67.80.107")
|
||||
|
||||
#ifndef CONFIG_MBEDTLS_DEBUG_LEVEL
|
||||
#define CONFIG_MBEDTLS_DEBUG_LEVEL 0
|
||||
#endif
|
||||
|
||||
typedef struct _TLSDataParams {
|
||||
mbedtls_ssl_context ssl; /**< mbed TLS control context. */
|
||||
mbedtls_net_context fd; /**< mbed TLS network context. */
|
||||
mbedtls_ssl_config conf; /**< mbed TLS configuration context. */
|
||||
mbedtls_x509_crt cacertl; /**< mbed TLS CA certification. */
|
||||
mbedtls_x509_crt clicert; /**< mbed TLS Client certification. */
|
||||
mbedtls_pk_context pkey; /**< mbed TLS Client key. */
|
||||
} TLSDataParams_t, *TLSDataParams_pt;
|
||||
|
||||
void *HAL_Malloc(uint32_t size);
|
||||
void HAL_Free(void *ptr);
|
||||
|
||||
static unsigned int mbedtls_mem_used = 0;
|
||||
static unsigned int mbedtls_max_mem_used = 0;
|
||||
static ssl_hooks_t g_ssl_hooks = {HAL_Malloc, HAL_Free};
|
||||
|
||||
#define MBEDTLS_MEM_INFO_MAGIC 0x12345678
|
||||
|
||||
typedef struct {
|
||||
int magic;
|
||||
int size;
|
||||
} mbedtls_mem_info_t;
|
||||
|
||||
#if defined(TLS_SAVE_TICKET)
|
||||
|
||||
#define TLS_MAX_SESSION_BUF 384
|
||||
#define KV_SESSION_KEY "TLS_SESSION"
|
||||
|
||||
extern int HAL_Kv_Set(const char *key, const void *val, int len, int sync);
|
||||
|
||||
extern int HAL_Kv_Get(const char *key, void *val, int *buffer_len);
|
||||
|
||||
static mbedtls_ssl_session *saved_session = NULL;
|
||||
|
||||
static int ssl_serialize_session(const mbedtls_ssl_session *session,
|
||||
unsigned char *buf, size_t buf_len,
|
||||
size_t *olen)
|
||||
{
|
||||
unsigned char *p = buf;
|
||||
size_t left = buf_len;
|
||||
|
||||
if (left < sizeof(mbedtls_ssl_session)) {
|
||||
return (MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL);
|
||||
}
|
||||
|
||||
memcpy(p, session, sizeof(mbedtls_ssl_session));
|
||||
p += sizeof(mbedtls_ssl_session);
|
||||
left -= sizeof(mbedtls_ssl_session);
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
|
||||
if (left < sizeof(mbedtls_ssl_session)) {
|
||||
return (MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL);
|
||||
}
|
||||
memcpy(p, session->ticket, session->ticket_len);
|
||||
p += session->ticket_len;
|
||||
left -= session->ticket_len;
|
||||
#endif
|
||||
|
||||
*olen = p - buf;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int ssl_deserialize_session(mbedtls_ssl_session *session,
|
||||
const unsigned char *buf, size_t len)
|
||||
{
|
||||
const unsigned char *p = buf;
|
||||
const unsigned char *const end = buf + len;
|
||||
|
||||
if (sizeof(mbedtls_ssl_session) > (size_t)(end - p)) {
|
||||
return (MBEDTLS_ERR_SSL_BAD_INPUT_DATA);
|
||||
}
|
||||
|
||||
memcpy(session, p, sizeof(mbedtls_ssl_session));
|
||||
p += sizeof(mbedtls_ssl_session);
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
session->peer_cert = NULL;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
|
||||
if (session->ticket_len > 0) {
|
||||
if (session->ticket_len > (size_t)(end - p)) {
|
||||
return (MBEDTLS_ERR_SSL_BAD_INPUT_DATA);
|
||||
}
|
||||
session->ticket = HAL_Malloc(session->ticket_len);
|
||||
if (session->ticket == NULL) {
|
||||
return (MBEDTLS_ERR_SSL_ALLOC_FAILED);
|
||||
}
|
||||
memcpy(session->ticket, p, session->ticket_len);
|
||||
p += session->ticket_len;
|
||||
printf("saved ticket len = %d \r\n", (int)session->ticket_len);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (p != end) {
|
||||
return (MBEDTLS_ERR_SSL_BAD_INPUT_DATA);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned int _avRandom()
|
||||
{
|
||||
return (((unsigned int)rand() << 16) + rand());
|
||||
}
|
||||
|
||||
static int _ssl_random(void *p_rng, unsigned char *output, size_t output_len)
|
||||
{
|
||||
uint32_t rnglen = output_len;
|
||||
uint8_t rngoffset = 0;
|
||||
|
||||
while (rnglen > 0) {
|
||||
*(output + rngoffset) = (unsigned char)_avRandom() ;
|
||||
rngoffset++;
|
||||
rnglen--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _ssl_debug(void *ctx, int level, const char *file, int line, const char *str)
|
||||
{
|
||||
((void) level);
|
||||
if (NULL != ctx) {
|
||||
#if 0
|
||||
fprintf((FILE *) ctx, "%s:%04d: %s", file, line, str);
|
||||
fflush((FILE *) ctx);
|
||||
#endif
|
||||
printf("%s\n", str);
|
||||
}
|
||||
}
|
||||
|
||||
static int _real_confirm(int verify_result)
|
||||
{
|
||||
printf("certificate verification result: 0x%02x\n", verify_result);
|
||||
|
||||
#if defined(FORCE_SSL_VERIFY)
|
||||
if ((verify_result & MBEDTLS_X509_BADCERT_EXPIRED) != 0) {
|
||||
printf("! fail ! ERROR_CERTIFICATE_EXPIRED\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((verify_result & MBEDTLS_X509_BADCERT_REVOKED) != 0) {
|
||||
printf("! fail ! server certificate has been revoked\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH) != 0) {
|
||||
printf("! fail ! CN mismatch\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED) != 0) {
|
||||
printf("! fail ! self-signed or not signed by a trusted CA\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _ssl_client_init(mbedtls_ssl_context *ssl,
|
||||
mbedtls_net_context *tcp_fd,
|
||||
mbedtls_ssl_config *conf,
|
||||
mbedtls_x509_crt *crt509_ca, const char *ca_crt, size_t ca_len,
|
||||
mbedtls_x509_crt *crt509_cli, const char *cli_crt, size_t cli_len,
|
||||
mbedtls_pk_context *pk_cli, const char *cli_key, size_t key_len, const char *cli_pwd, size_t pwd_len
|
||||
)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
/*
|
||||
* 0. Initialize the RNG and the session data
|
||||
*/
|
||||
#if defined(MBEDTLS_DEBUG_C)
|
||||
mbedtls_debug_set_threshold((int)CONFIG_MBEDTLS_DEBUG_LEVEL);
|
||||
#endif
|
||||
mbedtls_net_init(tcp_fd);
|
||||
mbedtls_ssl_init(ssl);
|
||||
mbedtls_ssl_config_init(conf);
|
||||
mbedtls_x509_crt_init(crt509_ca);
|
||||
|
||||
/*verify_source->trusted_ca_crt==NULL
|
||||
* 0. Initialize certificates
|
||||
*/
|
||||
|
||||
printf("Loading the CA root certificate ...\n");
|
||||
if (NULL != ca_crt) {
|
||||
if (0 != (ret = mbedtls_x509_crt_parse(crt509_ca, (const unsigned char *)ca_crt, ca_len))) {
|
||||
printf(" failed ! x509parse_crt returned -0x%04x\n", -ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
printf(" ok (%d skipped)\n", ret);
|
||||
|
||||
|
||||
/* Setup Client Cert/Key */
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
#if defined(MBEDTLS_CERTS_C)
|
||||
mbedtls_x509_crt_init(crt509_cli);
|
||||
mbedtls_pk_init(pk_cli);
|
||||
#endif
|
||||
if (cli_crt != NULL && cli_key != NULL) {
|
||||
#if defined(MBEDTLS_CERTS_C)
|
||||
printf("start prepare client cert .\n");
|
||||
ret = mbedtls_x509_crt_parse(crt509_cli, (const unsigned char *) cli_crt, cli_len);
|
||||
#else
|
||||
{
|
||||
ret = 1;
|
||||
printf("MBEDTLS_CERTS_C not defined.\n");
|
||||
}
|
||||
#endif
|
||||
if (ret != 0) {
|
||||
printf(" failed! mbedtls_x509_crt_parse returned -0x%x\n", -ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_CERTS_C)
|
||||
printf("start mbedtls_pk_parse_key[%s]\n", cli_pwd);
|
||||
ret = mbedtls_pk_parse_key(pk_cli, (const unsigned char *) cli_key, key_len, (const unsigned char *) cli_pwd, pwd_len);
|
||||
#else
|
||||
{
|
||||
ret = 1;
|
||||
printf("MBEDTLS_CERTS_C not defined.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret != 0) {
|
||||
printf(" failed\n ! mbedtls_pk_parse_key returned -0x%x\n", -ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(_PLATFORM_IS_LINUX_)
|
||||
static int net_prepare(void)
|
||||
{
|
||||
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
|
||||
!defined(EFI32)
|
||||
WSADATA wsaData;
|
||||
static int wsa_init_done = 0;
|
||||
|
||||
if (wsa_init_done == 0) {
|
||||
if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) {
|
||||
return (MBEDTLS_ERR_NET_SOCKET_FAILED);
|
||||
}
|
||||
|
||||
wsa_init_done = 1;
|
||||
}
|
||||
#else
|
||||
#if !defined(EFIX64) && !defined(EFI32)
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static int mbedtls_net_connect_timeout(mbedtls_net_context *ctx, const char *host,
|
||||
const char *port, int proto, unsigned int timeout)
|
||||
{
|
||||
int ret;
|
||||
struct addrinfo hints, *addr_list, *cur;
|
||||
struct timeval sendtimeout;
|
||||
uint8_t dns_retry = 0;
|
||||
|
||||
if ((ret = net_prepare()) != 0) {
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* Do name resolution with both IPv6 and IPv4 */
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
|
||||
hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
|
||||
|
||||
while(dns_retry++ < 8) {
|
||||
ret = getaddrinfo(host, port, &hints, &addr_list);
|
||||
if (ret != 0) {
|
||||
printf("getaddrinfo error[%d], res: %s, host: %s, port: %s\n", dns_retry, gai_strerror(ret), host, port);
|
||||
sleep(1);
|
||||
continue;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
return (MBEDTLS_ERR_NET_UNKNOWN_HOST);
|
||||
}
|
||||
|
||||
/* Try the sockaddrs until a connection succeeds */
|
||||
ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
|
||||
for (cur = addr_list; cur != NULL; cur = cur->ai_next) {
|
||||
char ip4_str[INET_ADDRSTRLEN];
|
||||
|
||||
ctx->fd = (int) socket(cur->ai_family, cur->ai_socktype,
|
||||
cur->ai_protocol);
|
||||
if (ctx->fd < 0) {
|
||||
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
|
||||
continue;
|
||||
}
|
||||
|
||||
sendtimeout.tv_sec = timeout;
|
||||
sendtimeout.tv_usec = 0;
|
||||
|
||||
if (0 != setsockopt(ctx->fd, SOL_SOCKET, SO_SNDTIMEO, &sendtimeout, sizeof(sendtimeout))) {
|
||||
perror("setsockopt");
|
||||
printf("setsockopt error\n");
|
||||
}
|
||||
printf("setsockopt SO_SNDTIMEO timeout: %ds\n", (int)sendtimeout.tv_sec);
|
||||
|
||||
inet_ntop(AF_INET, &((const struct sockaddr_in *)cur->ai_addr)->sin_addr, ip4_str, INET_ADDRSTRLEN);
|
||||
printf("connecting IP_ADDRESS: %s\n", ip4_str);
|
||||
|
||||
if (connect(ctx->fd, cur->ai_addr, cur->ai_addrlen) == 0) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
close(ctx->fd);
|
||||
ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
|
||||
}
|
||||
|
||||
freeaddrinfo(addr_list);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
void *_SSLCalloc_wrapper(size_t n, size_t size)
|
||||
{
|
||||
unsigned char *buf = NULL;
|
||||
mbedtls_mem_info_t *mem_info = NULL;
|
||||
|
||||
if (n == 0 || size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf = (unsigned char *)(g_ssl_hooks.malloc(n * size + sizeof(mbedtls_mem_info_t)));
|
||||
if (NULL == buf) {
|
||||
return NULL;
|
||||
} else {
|
||||
memset(buf, 0, n * size + sizeof(mbedtls_mem_info_t));
|
||||
}
|
||||
|
||||
mem_info = (mbedtls_mem_info_t *)buf;
|
||||
mem_info->magic = MBEDTLS_MEM_INFO_MAGIC;
|
||||
mem_info->size = n * size;
|
||||
buf += sizeof(mbedtls_mem_info_t);
|
||||
|
||||
mbedtls_mem_used += mem_info->size;
|
||||
if (mbedtls_mem_used > mbedtls_max_mem_used) {
|
||||
mbedtls_max_mem_used = mbedtls_mem_used;
|
||||
}
|
||||
|
||||
/* printf("INFO -- mbedtls malloc: %p %d total used: %d max used: %d\r\n",
|
||||
buf, (int)size, mbedtls_mem_used, mbedtls_max_mem_used); */
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void _SSLFree_wrapper(void *ptr)
|
||||
{
|
||||
mbedtls_mem_info_t *mem_info = NULL;
|
||||
if (NULL == ptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
mem_info = (mbedtls_mem_info_t *)((unsigned char *)ptr - sizeof(mbedtls_mem_info_t));
|
||||
if (mem_info->magic != MBEDTLS_MEM_INFO_MAGIC) {
|
||||
printf("Warning - invalid mem info magic: 0x%x\r\n", mem_info->magic);
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_mem_used -= mem_info->size;
|
||||
/* printf("INFO mbedtls free: %p %d total used: %d max used: %d\r\n",
|
||||
ptr, mem_info->size, mbedtls_mem_used, mbedtls_max_mem_used);*/
|
||||
|
||||
g_ssl_hooks.free(mem_info);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function connects to the specific SSL server with TLS, and returns a value that indicates whether the connection is create successfully or not. Call #NewNetwork() to initialize network structure before calling this function.
|
||||
* @param[in] n is the the network structure pointer.
|
||||
* @param[in] addr is the Server Host name or IP address.
|
||||
* @param[in] port is the Server Port.
|
||||
* @param[in] ca_crt is the Server's CA certification.
|
||||
* @param[in] ca_crt_len is the length of Server's CA certification.
|
||||
* @param[in] client_crt is the client certification.
|
||||
* @param[in] client_crt_len is the length of client certification.
|
||||
* @param[in] client_key is the client key.
|
||||
* @param[in] client_key_len is the length of client key.
|
||||
* @param[in] client_pwd is the password of client key.
|
||||
* @param[in] client_pwd_len is the length of client key's password.
|
||||
* @sa #NewNetwork();
|
||||
* @return If the return value is 0, the connection is created successfully. If the return value is -1, then calling lwIP #socket() has failed. If the return value is -2, then calling lwIP #connect() has failed. Any other value indicates that calling lwIP #getaddrinfo() has failed.
|
||||
*/
|
||||
|
||||
static int _TLSConnectNetwork(TLSDataParams_t *pTlsData, const char *addr, const char *port,
|
||||
const char *ca_crt, size_t ca_crt_len,
|
||||
const char *client_crt, size_t client_crt_len,
|
||||
const char *client_key, size_t client_key_len,
|
||||
const char *client_pwd, size_t client_pwd_len)
|
||||
{
|
||||
int ret = -1;
|
||||
/*
|
||||
* 0. Init
|
||||
*/
|
||||
if (0 != (ret = _ssl_client_init(&(pTlsData->ssl), &(pTlsData->fd), &(pTlsData->conf),
|
||||
&(pTlsData->cacertl), ca_crt, ca_crt_len,
|
||||
&(pTlsData->clicert), client_crt, client_crt_len,
|
||||
&(pTlsData->pkey), client_key, client_key_len, client_pwd, client_pwd_len))) {
|
||||
printf(" failed ! ssl_client_init returned -0x%04x\n", -ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Start the connection
|
||||
*/
|
||||
printf("Connecting to /%s/%s...\n", addr, port);
|
||||
#if defined(_PLATFORM_IS_LINUX_)
|
||||
if (0 != (ret = mbedtls_net_connect_timeout(&(pTlsData->fd), addr, port, MBEDTLS_NET_PROTO_TCP,
|
||||
SEND_TIMEOUT_SECONDS))) {
|
||||
printf(" failed ! net_connect returned -0x%04x\n", -ret);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
if (0 != (ret = mbedtls_net_connect(&(pTlsData->fd), addr, port, MBEDTLS_NET_PROTO_TCP))) {
|
||||
printf(" failed ! net_connect returned -0x%04x\n", -ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
printf(" ok\n");
|
||||
|
||||
/*
|
||||
* 2. Setup stuff
|
||||
*/
|
||||
printf(" . Setting up the SSL/TLS structure...\n");
|
||||
if ((ret = mbedtls_ssl_config_defaults(&(pTlsData->conf), MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
|
||||
printf(" failed! mbedtls_ssl_config_defaults returned %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_max_version(&pTlsData->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
|
||||
mbedtls_ssl_conf_min_version(&pTlsData->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
|
||||
|
||||
printf(" ok\n");
|
||||
|
||||
/* OPTIONAL is not optimal for security, but makes interop easier in this simplified example */
|
||||
if (ca_crt != NULL) {
|
||||
#if defined(FORCE_SSL_VERIFY)
|
||||
mbedtls_ssl_conf_authmode(&(pTlsData->conf), MBEDTLS_SSL_VERIFY_REQUIRED);
|
||||
#else
|
||||
mbedtls_ssl_conf_authmode(&(pTlsData->conf), MBEDTLS_SSL_VERIFY_OPTIONAL);
|
||||
#endif
|
||||
} else {
|
||||
mbedtls_ssl_conf_authmode(&(pTlsData->conf), MBEDTLS_SSL_VERIFY_NONE);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
mbedtls_ssl_conf_ca_chain(&(pTlsData->conf), &(pTlsData->cacertl), NULL);
|
||||
|
||||
if ((ret = mbedtls_ssl_conf_own_cert(&(pTlsData->conf), &(pTlsData->clicert), &(pTlsData->pkey))) != 0) {
|
||||
printf(" failed\n ! mbedtls_ssl_conf_own_cert returned %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
mbedtls_ssl_conf_rng(&(pTlsData->conf), _ssl_random, NULL);
|
||||
mbedtls_ssl_conf_dbg(&(pTlsData->conf), _ssl_debug, NULL);
|
||||
mbedtls_ssl_conf_dbg(&(pTlsData->conf), _ssl_debug, stdout);
|
||||
|
||||
if ((ret = mbedtls_ssl_setup(&(pTlsData->ssl), &(pTlsData->conf))) != 0) {
|
||||
printf("failed! mbedtls_ssl_setup returned %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
#if defined(ON_PRE) || defined(ON_DAILY)
|
||||
printf("SKIPPING mbedtls_ssl_set_hostname() when ON_PRE or ON_DAILY defined!\n");
|
||||
#else
|
||||
mbedtls_ssl_set_hostname(&(pTlsData->ssl), addr);
|
||||
#endif
|
||||
mbedtls_ssl_set_bio(&(pTlsData->ssl), &(pTlsData->fd), mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout);
|
||||
|
||||
#if defined(TLS_SAVE_TICKET)
|
||||
if (NULL == saved_session) {
|
||||
do {
|
||||
int len = TLS_MAX_SESSION_BUF;
|
||||
unsigned char *save_buf = HAL_Malloc(TLS_MAX_SESSION_BUF);
|
||||
if (save_buf == NULL) {
|
||||
printf(" malloc failed\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
saved_session = HAL_Malloc(sizeof(mbedtls_ssl_session));
|
||||
|
||||
if (saved_session == NULL) {
|
||||
printf(" malloc failed\r\n");
|
||||
HAL_Free(save_buf);
|
||||
save_buf = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
memset(save_buf, 0x00, TLS_MAX_SESSION_BUF);
|
||||
memset(saved_session, 0x00, sizeof(mbedtls_ssl_session));
|
||||
|
||||
ret = HAL_Kv_Get(KV_SESSION_KEY, save_buf, &len);
|
||||
|
||||
if (ret != 0 || len == 0) {
|
||||
printf(" kv get failed len=%d,ret = %d\r\n", len, ret);
|
||||
HAL_Free(saved_session);
|
||||
HAL_Free(save_buf);
|
||||
save_buf = NULL;
|
||||
saved_session = NULL;
|
||||
break;
|
||||
}
|
||||
ret = ssl_deserialize_session(saved_session, save_buf, len);
|
||||
if (ret < 0) {
|
||||
printf("ssl_deserialize_session err,ret = %d\r\n", ret);
|
||||
HAL_Free(saved_session);
|
||||
HAL_Free(save_buf);
|
||||
save_buf = NULL;
|
||||
saved_session = NULL;
|
||||
break;
|
||||
}
|
||||
HAL_Free(save_buf);
|
||||
} while (0);
|
||||
}
|
||||
|
||||
if (NULL != saved_session) {
|
||||
mbedtls_ssl_set_session(&(pTlsData->ssl), saved_session);
|
||||
printf("use saved session!!\r\n");
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* 4. Handshake
|
||||
*/
|
||||
mbedtls_ssl_conf_read_timeout(&(pTlsData->conf), 10000);
|
||||
printf("Performing the SSL/TLS handshake...\n");
|
||||
|
||||
while ((ret = mbedtls_ssl_handshake(&(pTlsData->ssl))) != 0) {
|
||||
if ((ret != MBEDTLS_ERR_SSL_WANT_READ) && (ret != MBEDTLS_ERR_SSL_WANT_WRITE)) {
|
||||
printf("failed ! mbedtls_ssl_handshake returned -0x%04x\n", -ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
printf(" ok\n");
|
||||
|
||||
#if defined(TLS_SAVE_TICKET)
|
||||
if (NULL == saved_session) {
|
||||
do {
|
||||
size_t real_session_len = 0;
|
||||
unsigned char *save_buf = HAL_Malloc(TLS_MAX_SESSION_BUF); //for test
|
||||
if (save_buf == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
saved_session = HAL_Malloc(sizeof(mbedtls_ssl_session));
|
||||
if (NULL == saved_session) {
|
||||
HAL_Free(save_buf);
|
||||
break;
|
||||
}
|
||||
memset(save_buf, 0x00, sizeof(TLS_MAX_SESSION_BUF));
|
||||
memset(saved_session, 0x00, sizeof(mbedtls_ssl_session));
|
||||
|
||||
ret = mbedtls_ssl_get_session(&(pTlsData->ssl), saved_session);
|
||||
if (ret != 0) {
|
||||
HAL_Free(save_buf);
|
||||
HAL_Free(saved_session);
|
||||
saved_session = NULL;
|
||||
break;
|
||||
}
|
||||
ret = ssl_serialize_session(saved_session, save_buf, TLS_MAX_SESSION_BUF, &real_session_len);
|
||||
printf("mbedtls_ssl_get_session_session return 0x%04x real_len=%d\r\n", ret, (int)real_session_len);
|
||||
if (ret == 0) {
|
||||
HAL_Kv_Set(KV_SESSION_KEY, (void *)save_buf, real_session_len, 1);
|
||||
}
|
||||
HAL_Free(save_buf);
|
||||
} while (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 5. Verify the server certificate
|
||||
*/
|
||||
printf(" . Verifying peer X.509 certificate..\n");
|
||||
if (0 != (ret = _real_confirm(mbedtls_ssl_get_verify_result(&(pTlsData->ssl))))) {
|
||||
printf(" failed ! verify result not confirmed.\n");
|
||||
return ret;
|
||||
}
|
||||
/* n->my_socket = (int)((n->tlsdataparams.fd).fd); */
|
||||
/* WRITE_IOT_DEBUG_LOG("my_socket=%d", n->my_socket); */
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int _network_ssl_read(TLSDataParams_t *pTlsData, char *buffer, int len, int timeout_ms)
|
||||
{
|
||||
uint32_t readLen = 0;
|
||||
static int net_status = 0;
|
||||
int ret = -1;
|
||||
char err_str[33];
|
||||
|
||||
mbedtls_ssl_conf_read_timeout(&(pTlsData->conf), timeout_ms);
|
||||
while (readLen < len) {
|
||||
ret = mbedtls_ssl_read(&(pTlsData->ssl), (unsigned char *)(buffer + readLen), (len - readLen));
|
||||
if (ret > 0) {
|
||||
readLen += ret;
|
||||
net_status = 0;
|
||||
} else if (ret == 0) {
|
||||
/* if ret is 0 and net_status is -2, indicate the connection is closed during last call */
|
||||
return (net_status == -2) ? net_status : readLen;
|
||||
} else {
|
||||
if (MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY == ret) {
|
||||
mbedtls_strerror(ret, err_str, sizeof(err_str));
|
||||
printf("ssl recv error: code = %d, err_str = '%s'\n", ret, err_str);
|
||||
net_status = -2; /* connection is closed */
|
||||
break;
|
||||
} else if ((MBEDTLS_ERR_SSL_TIMEOUT == ret)
|
||||
|| (MBEDTLS_ERR_SSL_CONN_EOF == ret)
|
||||
|| (MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED == ret)
|
||||
|| (MBEDTLS_ERR_SSL_NON_FATAL == ret)) {
|
||||
/* read already complete */
|
||||
/* if call mbedtls_ssl_read again, it will return 0 (means EOF) */
|
||||
|
||||
return readLen;
|
||||
} else {
|
||||
mbedtls_strerror(ret, err_str, sizeof(err_str));
|
||||
printf("ssl recv error: code = %d, err_str = '%s'\n", ret, err_str);
|
||||
net_status = -1;
|
||||
return -1; /* Connection error */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (readLen > 0) ? readLen : net_status;
|
||||
}
|
||||
|
||||
static int _network_ssl_write(TLSDataParams_t *pTlsData, const char *buffer, int len, int timeout_ms)
|
||||
{
|
||||
#if defined(_PLATFORM_IS_LINUX_)
|
||||
int32_t res = 0;
|
||||
int32_t write_bytes = 0;
|
||||
uint64_t timestart_ms = 0, timenow_ms = 0;
|
||||
struct timeval timestart, timenow, timeout;
|
||||
|
||||
if (pTlsData == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* timeout */
|
||||
timeout.tv_sec = timeout_ms/1000;
|
||||
timeout.tv_usec = (timeout_ms % 1000) * 1000;
|
||||
|
||||
/* Start Time */
|
||||
gettimeofday(×tart, NULL);
|
||||
timestart_ms = timestart.tv_sec * 1000 + timestart.tv_usec / 1000;
|
||||
timenow_ms = timestart_ms;
|
||||
|
||||
res = setsockopt(pTlsData->fd.fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
|
||||
if (res < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
gettimeofday(&timenow, NULL);
|
||||
timenow_ms = timenow.tv_sec * 1000 + timenow.tv_usec / 1000;
|
||||
|
||||
if (timenow_ms - timestart_ms >= timenow_ms ||
|
||||
timeout_ms - (timenow_ms - timestart_ms) > timeout_ms) {
|
||||
break;
|
||||
}
|
||||
|
||||
res = mbedtls_ssl_write(&(pTlsData->ssl), (unsigned char *)buffer + write_bytes, len - write_bytes);
|
||||
if (res < 0) {
|
||||
if (res != MBEDTLS_ERR_SSL_WANT_READ &&
|
||||
res != MBEDTLS_ERR_SSL_WANT_WRITE) {
|
||||
if (write_bytes == 0) {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}else if (res == 0) {
|
||||
break;
|
||||
}else{
|
||||
write_bytes += res;
|
||||
}
|
||||
}while(((timenow_ms - timestart_ms) < timeout_ms) && (write_bytes < len));
|
||||
|
||||
return write_bytes;
|
||||
#else
|
||||
uint32_t writtenLen = 0;
|
||||
int ret = -1;
|
||||
|
||||
if (pTlsData == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (writtenLen < len) {
|
||||
ret = mbedtls_ssl_write(&(pTlsData->ssl), (unsigned char *)(buffer + writtenLen), (len - writtenLen));
|
||||
if (ret > 0) {
|
||||
writtenLen += ret;
|
||||
continue;
|
||||
} else if (ret == 0) {
|
||||
printf("ssl write timeout\n");
|
||||
return 0;
|
||||
} else {
|
||||
char err_str[33];
|
||||
mbedtls_strerror(ret, err_str, sizeof(err_str));
|
||||
printf("ssl write fail, code=%d, str=%s\n", ret, err_str);
|
||||
return -1; /* Connnection error */
|
||||
}
|
||||
}
|
||||
|
||||
return writtenLen;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void _network_ssl_disconnect(TLSDataParams_t *pTlsData)
|
||||
{
|
||||
mbedtls_ssl_close_notify(&(pTlsData->ssl));
|
||||
mbedtls_net_free(&(pTlsData->fd));
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
mbedtls_x509_crt_free(&(pTlsData->cacertl));
|
||||
if ((pTlsData->pkey).pk_info != NULL) {
|
||||
printf("need release client crt&key\n");
|
||||
#if defined(MBEDTLS_CERTS_C)
|
||||
mbedtls_x509_crt_free(&(pTlsData->clicert));
|
||||
mbedtls_pk_free(&(pTlsData->pkey));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
mbedtls_ssl_free(&(pTlsData->ssl));
|
||||
mbedtls_ssl_config_free(&(pTlsData->conf));
|
||||
printf("ssl_disconnect\n");
|
||||
}
|
||||
|
||||
int HAL_SSL_Read(uintptr_t handle, char *buf, int len, int timeout_ms)
|
||||
{
|
||||
return _network_ssl_read((TLSDataParams_t *)handle, buf, len, timeout_ms);;
|
||||
}
|
||||
|
||||
int HAL_SSL_Write(uintptr_t handle, const char *buf, int len, int timeout_ms)
|
||||
{
|
||||
return _network_ssl_write((TLSDataParams_t *)handle, buf, len, timeout_ms);
|
||||
}
|
||||
|
||||
int32_t HAL_SSL_Destroy(uintptr_t handle)
|
||||
{
|
||||
if ((uintptr_t)NULL == handle) {
|
||||
printf("handle is NULL\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
_network_ssl_disconnect((TLSDataParams_t *)handle);
|
||||
g_ssl_hooks.free((void *)handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ssl_hooks_set(ssl_hooks_t *hooks)
|
||||
{
|
||||
if (hooks == NULL || hooks->malloc == NULL || hooks->free == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_ssl_hooks.malloc = hooks->malloc;
|
||||
g_ssl_hooks.free = hooks->free;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uintptr_t HAL_SSL_Establish(const char *host,
|
||||
uint16_t port,
|
||||
const char *ca_crt,
|
||||
uint32_t ca_crt_len)
|
||||
{
|
||||
char port_str[6];
|
||||
const char *alter = host;
|
||||
TLSDataParams_pt pTlsData;
|
||||
|
||||
if (host == NULL || ca_crt == NULL) {
|
||||
printf("input params are NULL, abort\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strlen(host) || (strlen(host) < 8)) {
|
||||
printf("invalid host: '%s'(len=%d), abort\n", host, (int)strlen(host));
|
||||
return 0;
|
||||
}
|
||||
|
||||
pTlsData = g_ssl_hooks.malloc(sizeof(TLSDataParams_t));
|
||||
if (NULL == pTlsData) {
|
||||
return (uintptr_t)NULL;
|
||||
}
|
||||
memset(pTlsData, 0x0, sizeof(TLSDataParams_t));
|
||||
|
||||
sprintf(port_str, "%u", port);
|
||||
|
||||
#if defined(ON_PRE)
|
||||
if (!strcmp(GUIDER_ONLINE_HOSTNAME, host)) {
|
||||
printf("ALTERING '%s' to '%s' since ON_PRE defined!\n", host, GUIDER_PRE_ADDRESS);
|
||||
alter = GUIDER_PRE_ADDRESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
mbedtls_platform_set_calloc_free(_SSLCalloc_wrapper, _SSLFree_wrapper);
|
||||
|
||||
if (0 != _TLSConnectNetwork(pTlsData, alter, port_str, ca_crt, ca_crt_len, NULL, 0, NULL, 0, NULL, 0)) {
|
||||
_network_ssl_disconnect(pTlsData);
|
||||
g_ssl_hooks.free((void *)pTlsData);
|
||||
return (uintptr_t)NULL;
|
||||
}
|
||||
|
||||
return (uintptr_t)pTlsData;
|
||||
}
|
||||
|
58
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/wrappers_defs.h
vendored
Normal file
58
components/connectivity/iotkit-embedded-3.0.1/3rdparty/wrappers/wrappers_defs.h
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
#ifndef _WRAPPERS_DEFS_H_
|
||||
#define _WRAPPERS_DEFS_H_
|
||||
|
||||
#include "infra_types.h"
|
||||
#include "infra_defs.h"
|
||||
|
||||
#define PLATFORM_WAIT_INFINITE (~0)
|
||||
|
||||
typedef struct {
|
||||
void *(*malloc)(uint32_t size);
|
||||
void (*free)(void *ptr);
|
||||
} ssl_hooks_t;
|
||||
|
||||
typedef enum {
|
||||
os_thread_priority_idle = -3, /* priority: idle (lowest) */
|
||||
os_thread_priority_low = -2, /* priority: low */
|
||||
os_thread_priority_belowNormal = -1, /* priority: below normal */
|
||||
os_thread_priority_normal = 0, /* priority: normal (default) */
|
||||
os_thread_priority_aboveNormal = 1, /* priority: above normal */
|
||||
os_thread_priority_high = 2, /* priority: high */
|
||||
os_thread_priority_realtime = 3, /* priority: realtime (highest) */
|
||||
os_thread_priority_error = 0x84, /* system cannot determine priority or thread has illegal priority */
|
||||
} hal_os_thread_priority_t;
|
||||
|
||||
typedef struct _hal_os_thread {
|
||||
hal_os_thread_priority_t priority; /*initial thread priority */
|
||||
void *stack_addr; /* thread stack address malloced by caller, use system stack by . */
|
||||
int stack_size; /* stack size requirements in bytes; 0 is default stack size */
|
||||
int detach_state; /* 0: not detached state; otherwise: detached state. */
|
||||
char *name; /* thread name. */
|
||||
} hal_os_thread_param_t;
|
||||
|
||||
#define DTLS_ERROR_BASE (1<<24)
|
||||
#define DTLS_SUCCESS (0)
|
||||
#define DTLS_INVALID_PARAM (DTLS_ERROR_BASE | 1)
|
||||
#define DTLS_INVALID_CA_CERTIFICATE (DTLS_ERROR_BASE | 2)
|
||||
#define DTLS_HANDSHAKE_IN_PROGRESS (DTLS_ERROR_BASE | 3)
|
||||
#define DTLS_HANDSHAKE_FAILED (DTLS_ERROR_BASE | 4)
|
||||
#define DTLS_FATAL_ALERT_MESSAGE (DTLS_ERROR_BASE | 5)
|
||||
#define DTLS_PEER_CLOSE_NOTIFY (DTLS_ERROR_BASE | 6)
|
||||
#define DTLS_SESSION_CREATE_FAILED (DTLS_ERROR_BASE | 7)
|
||||
#define DTLS_READ_DATA_FAILED (DTLS_ERROR_BASE | 8)
|
||||
|
||||
typedef struct {
|
||||
void *(*malloc)(uint32_t size);
|
||||
void (*free)(void *ptr);
|
||||
} dtls_hooks_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char *p_ca_cert_pem;
|
||||
char *p_host;
|
||||
unsigned short port;
|
||||
} coap_dtls_options_t;
|
||||
|
||||
typedef void DTLSContext;
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user