以下主要是移植阿里云物联网平台的C-SDK
-
下载并编译C-SDK,然后将相关的文件加入到ESP的项目工程中
//下载最新的Release
# wget https://github.com/aliyun/iotkit-embedded/archive/RELEASED_V3.01.tar.gz
# tar xzvf RELEASED_V3.10.tar.gz
//选择 1, 然后make生成库文件
# make reconfig
SELECT A CONFIGURATION:
1) config.alios.esp8266 3) config.macos.x86 5) config.windows.x86
2) config.alios.mk3080 4) config.ubuntu.x86
#? 1
# make
//编译有错误,添加注释 #include
# vi wrappers/tls/HAL_TLS_mbedtls.c
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include
#include
//#include
#include
#include
//将编译生成的库文件和头文件复制到ESP8266 IDF 工程项目中/components/libiot_sdk/
# cp -rf output/release/* ~/esp/wifi_switch/components/libiot_sdk/
# cp -rf output/eng/wrappers ~/esp/wifi_switch/components/libiot_sdk/
# ls libiot_sdk/
bin component.mk include lib wrappers
//component.mk的内容
# cat component.mk
COMPONENT_ADD_INCLUDEDIRS += include wrappers
COMPONENT_SRCDIRS := wrappers
LIBS := iot_sdk
COMPONENT_ADD_LDFLAGS += -lpthread -L$(COMPONENT_PATH)/lib $(addprefix -l,$(LIBS))
文件参考(ESP32/ESP8266都可以用这个文件,记得替换里面的Key.)
/**
* NOTE:
*
* HAL_TCP_xxx API reference implementation: wrappers/os/ubuntu/HAL_TCP_linux.c
*
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/task.h"
#include "esp_wifi.h"
#include "esp_timer.h"
#include "nvs.h"
#include "esp_log.h"
#include "esp_ota_ops.h"
#include "sdkconfig.h"
#include "infra_types.h"
#include "infra_defs.h"
#include "infra_compat.h"
#include "wrappers_defs.h"
#include "stdarg.h"
#include "lwip/netdb.h"
static const char* TAG = "in";
#define hal_emerg(...) ESP_LOGE(TAG, __VA_ARGS__)
#define hal_crit(...) ESP_LOGE(TAG, __VA_ARGS__)
#define hal_err(...) ESP_LOGE(TAG, __VA_ARGS__)
#define hal_warning(...) ESP_LOGW(TAG, __VA_ARGS__)
#define hal_info(...) ESP_LOGI(TAG, __VA_ARGS__)
#define hal_debug(...) ESP_LOGD(TAG, __VA_ARGS__)
#define HAL_TCP_CONNECT_TIMEOUT 10 * 1000000
char _product_key[IOTX_PRODUCT_KEY_LEN + 1] = "x";
char _product_secret[IOTX_PRODUCT_SECRET_LEN + 1] = "x";
char _device_name[IOTX_DEVICE_NAME_LEN + 1] = "x";
char _device_secret[IOTX_DEVICE_SECRET_LEN + 1] = "x";
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;
}
/**
* @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 Get device name from user's system persistent storage
*
* @param [ou] device_name: array to store device name, max length is IOTX_DEVICE_NAME_LEN
* @return the actual length of device name
*/
int HAL_GetDeviceName(char device_name[IOTX_DEVICE_NAME_LEN + 1])
{
int len = strlen(_device_name);
memset(device_name, 0x0, IOTX_DEVICE_NAME_LEN);
strncpy(device_name, _device_name, len);
return strlen(device_name);
}
/**
* @brief Get device secret from user's system persistent storage
*
* @param [ou] device_secret: array to store device secret, max length is IOTX_DEVICE_SECRET_LEN
* @return the actual length of device secret
*/
int HAL_GetDeviceSecret(char device_secret[IOTX_DEVICE_SECRET_LEN + 1])
{
int len = strlen(_device_secret);
memset(device_secret, 0x0, IOTX_DEVICE_SECRET_LEN);
strncpy(device_secret, _device_secret, len);
return len;
}
/**
* @brief Get firmware version
*
* @param [ou] version: array to store firmware version, max length is IOTX_FIRMWARE_VER_LEN
* @return the actual length of firmware version
*/
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);
}
/**
* @brief Get product key from user's system persistent storage
*
* @param [ou] product_key: array to store product key, max length is IOTX_PRODUCT_KEY_LEN
* @return the actual length of product key
*/
int HAL_GetProductKey(char product_key[IOTX_PRODUCT_KEY_LEN + 1])
{
int len = strlen(_product_key);
memset(product_key, 0x0, IOTX_PRODUCT_KEY_LEN);
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);
strncpy(product_secret, _product_secret, len);
return len;
}
/**
* @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)
{
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))) {
hal_err("create mutex failed");
HAL_Free(mutex);
return NULL;
}
return mutex;
}
/**
* @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)
{
int err_num;
if (!mutex) {
hal_warning("mutex want to destroy is NULL!");
return;
}
if (0 != (err_num = pthread_mutex_destroy((pthread_mutex_t *)mutex))) {
hal_err("destroy mutex failed");
}
HAL_Free(mutex);
}
/**
* @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)
{
int err_num;
if (0 != (err_num = pthread_mutex_lock((pthread_mutex_t *)mutex))) {
hal_err("lock mutex failed: - '%s' (%d)", strerror(err_num), err_num);
}
}
/**
* @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)
{
int err_num;
if (0 != (err_num = pthread_mutex_unlock((pthread_mutex_t *)mutex))) {
hal_err("unlock mutex failed - '%s' (%d)", strerror(err_num), err_num);
}
}
/**
* @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);
}
uint32_t HAL_Random(uint32_t region)
{
return (region > 0) ? (esp_random() % region) : 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)
{
usleep(1000 * 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;
}
void HAL_Srandom(uint32_t seed)
{
return;
}
/**
* @brief Destroy the specific TCP connection.
*
* @param [in] fd: @n Specify the TCP connection by handle.
*
* @return The result of destroy TCP connection.
* @retval < 0 : Fail.
* @retval 0 : Success.
*/
int HAL_TCP_Destroy(uintptr_t fd)
{
int rc;
/* Shutdown both send and receive operations. */
rc = shutdown((int) fd, 2);
if (0 != rc) {
hal_err("shutdown error");
return -1;
}
rc = close((int) fd);
if (0 != rc) {
hal_err("closesocket error");
return -1;
}
return 0;
}
int HAL_TCP_Timeout(int fd, unsigned long usec)
{
int ret = 0;
struct timeval tm;
fd_set set;
int error = -1, len = sizeof(int);
tm.tv_sec = usec / 1000000;
tm.tv_usec = usec % 1000000;
FD_ZERO(&set);
FD_SET(fd, &set);
if (select(fd + 1, NULL, &set, NULL, &tm) <= 0) {
ret = false;
} else {
getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *) &len);
ret = (error == 0) ? true : false;
}
return ret;
}
/**
* @brief Establish a TCP connection.
*
* @param [in] host: @n Specify the hostname(IP) of the TCP server
* @param [in] port: @n Specify the TCP port of TCP server
*
* @return The handle of TCP connection.
@retval 0 : Fail.
@retval > 0 : Success, the value is handle of this TCP connection.
*/
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];
memset(&hints, 0, sizeof(hints));
hal_info("establish tcp connection with server(host='%s', port=[%u])", host, port);
hints.ai_family = AF_INET; /* only IPv4 */
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
sprintf(service, "%u", port);
if ((rc = getaddrinfo(host, service, &hints, &addrInfoList)) != 0) {
hal_err("getaddrinfo error(%d), host = '%s', port = [%d]", rc, host, port);
return -1;
}
for (cur = addrInfoList; cur != NULL; cur = cur->ai_next) {
if (cur->ai_family != AF_INET) {
hal_err("socket type error");
rc = -1;
continue;
}
fd = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol);
if (fd < 0) {
hal_err("create socket error");
rc = -1;
continue;
}
if (connect(fd, cur->ai_addr, cur->ai_addrlen) == 0) {
rc = fd;
break;
}
close(fd);
hal_err("connect error");
rc = -1;
}
if (-1 == rc) {
hal_err("fail to establish tcp");
} else {
hal_info("success to establish tcp, fd=%d", rc);
}
freeaddrinfo(addrInfoList);
return (uintptr_t)rc;
}
/**
* @brief Read data from the specific TCP connection with timeout parameter.
* The API will return immediately if 'len' be received from the specific TCP connection.
*
* @param [in] fd @n A descriptor identifying a TCP connection.
* @param [out] buf @n A pointer to a buffer to receive incoming data.
* @param [out] len @n The length, in bytes, of the data pointed to by the 'buf' parameter.
* @param [in] timeout_ms @n Specify the timeout value in millisecond. In other words, the API block 'timeout_ms' millisecond maximumly.
*
* @retval -2 : TCP connection error occur.
* @retval -1 : TCP connection be closed by remote server.
* @retval 0 : No any data be received in 'timeout_ms' timeout period.
* @retval (0, len] : The total number of bytes be received in 'timeout_ms' timeout period.
* @see None.
*/
int32_t HAL_TCP_Read(uintptr_t fd, char *buf, uint32_t len, uint32_t timeout_ms)
{
int ret, err_code;
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;
do {
t_left = _linux_time_left(t_end, _linux_get_time_ms());
if (0 == t_left) {
break;
}
FD_ZERO(&sets);
FD_SET(fd, &sets);
timeout.tv_sec = t_left / 1000;
timeout.tv_usec = (t_left % 1000) * 1000;
ret = select(fd + 1, &sets, NULL, NULL, &timeout);
if (ret > 0) {
ret = recv(fd, buf + len_recv, len - len_recv, 0);
if (ret > 0) {
len_recv += ret;
} else if (0 == ret) {
hal_err("connection is closed");
err_code = -1;
break;
} else {
if (EINTR == errno) {
hal_err("EINTR be caught");
continue;
}
hal_err("recv fail");
err_code = -2;
break;
}
} else if (0 == ret) {
break;
} else {
hal_err("select-recv fail");
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;
}
/**
* @brief Write data into the specific TCP connection.
* The API will return immediately if 'len' be written into the specific TCP connection.
*
* @param [in] fd @n A descriptor identifying a connection.
* @param [in] buf @n A pointer to a buffer containing the data to be transmitted.
* @param [in] len @n The length, in bytes, of the data pointed to by the 'buf' parameter.
* @param [in] timeout_ms @n Specify the timeout value in millisecond. In other words, the API block 'timeout_ms' millisecond maximumly.
*
* @retval < 0 : TCP connection error occur..
* @retval 0 : No any data be write into the TCP connection in 'timeout_ms' timeout period.
* @retval (0, len] : The total number of bytes be written in 'timeout_ms' timeout period.
* @see None.
*/
int32_t HAL_TCP_Write(uintptr_t fd, const char *buf, uint32_t len, uint32_t timeout_ms)
{
int ret;
uint32_t len_sent;
uint64_t t_end, t_left;
fd_set sets;
t_end = _linux_get_time_ms() + timeout_ms;
len_sent = 0;
ret = 1; /* send one time if timeout_ms is value 0 */
do {
t_left = _linux_time_left(t_end, _linux_get_time_ms());
if (0 != t_left) {
struct timeval timeout;
FD_ZERO(&sets);
FD_SET(fd, &sets);
timeout.tv_sec = t_left / 1000;
timeout.tv_usec = (t_left % 1000) * 1000;
ret = select(fd + 1, NULL, &sets, NULL, &timeout);
if (ret > 0) {
if (0 == FD_ISSET(fd, &sets)) {
hal_err("Should NOT arrive");
/* If timeout in next loop, it will not sent any data */
ret = 0;
continue;
}
} else if (0 == ret) {
hal_err("select-write timeout %d", (int)fd);
break;
} else {
if (EINTR == errno) {
hal_err("EINTR be caught");
continue;
}
hal_err("select-write fail");
break;
}
}
if (ret > 0) {
ret = send(fd, buf + len_sent, len - len_sent, 0);
if (ret > 0) {
len_sent += ret;
} else if (0 == ret) {
hal_err("No data be sent");
} else {
if (EINTR == errno) {
hal_err("EINTR be caught");
continue;
}
hal_err("send fail");
break;
}
}
} while ((len_sent < len) && (_linux_time_left(t_end, _linux_get_time_ms()) > 0));
return len_sent;
}
/**
* @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();
}
int HAL_Vsnprintf(char *str, const int len, const char *format, va_list ap)
{
return vsnprintf(str, len, format, ap);
}