Init projects

This commit is contained in:
HuangXin 2018-12-28 10:26:20 +08:00
commit c0026875f8
33 changed files with 11874 additions and 0 deletions

View File

@ -0,0 +1,53 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include "log.h"
#include "crypto.h"
const char* rand_string(char* pRandKey, int ilen)
{
int i = 0;
static const char keyTbl[] = "0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ";
int maxSed = strlen(keyTbl);
if(pRandKey == NULL || ilen <= 0)
{
LOG_EX(LOG_Debug, "Input params error(%d)\n", ilen);
return NULL;
}
srand(time(NULL));
for(i = 0; i < ilen; i++)
{
pRandKey[i] = keyTbl[rand() % maxSed];
}
return (const char*)pRandKey;
}
const char* hash_sha1(unsigned char* pData, int iSize, char* pHashCode)
{
int len;
unsigned char sha1[SHA1_DIGEST_LENGTH];
EVP_MD_CTX evpCtx;
memset(sha1, 0, SHA1_DIGEST_LENGTH);
len = iSize;
EVP_MD_CTX_init(&evpCtx);
EVP_DigestInit_ex(&evpCtx, EVP_sha1(), NULL);
EVP_DigestUpdate(&evpCtx, pData, len);
EVP_DigestFinal_ex(&evpCtx, sha1, &len);
EVP_MD_CTX_cleanup(&evpCtx);
print_hex_dump_bytes("SHA1", DUMP_PREFIX_OFFSET, sha1, SHA1_DIGEST_LENGTH);
return (const char*)IHW_bin2hex(pHashCode, sha1, len);
}

554
src/Framework/fifo/fifo.c Normal file
View File

@ -0,0 +1,554 @@
/*
* A generic kernel FIFO implementation
*
* Copyright (C) 2009/2010 Stefani Seibold <stefani@seibold.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#if 0
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/log2.h>
#include <linux/uaccess.h>
#include <linux/kfifo.h>
#endif
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include "fifo.h"
#define is_power_of_2(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
#define min(x,y) ({ \
typeof(x) _x = (x); \
typeof(y) _y = (y); \
(void) (&_x == &_y); \
_x < _y ? _x : _y; })
#define max(x,y) ({ \
typeof(x) _x = (x); \
typeof(y) _y = (y); \
(void) (&_x == &_y); \
_x > _y ? _x : _y; })
//#define EINVAL (1)
//#define ENOMEM (2)
static inline int fls(int x);
#if defined(PLATFORM_R16) || defined(PLATFORM_R311)
static inline int constant_fls(int x)
{
int r = 32;
if (!x)
return 0;
if (!(x & 0xffff0000u)) {
x <<= 16;
r -= 16;
}
if (!(x & 0xff000000u)) {
x <<= 8;
r -= 8;
}
if (!(x & 0xf0000000u)) {
x <<= 4;
r -= 4;
}
if (!(x & 0xc0000000u)) {
x <<= 2;
r -= 2;
}
if (!(x & 0x80000000u)) {
x <<= 1;
r -= 1;
}
return r;
}
static int fls64(unsigned long long x)
{
unsigned int h = x >> 32;
if (h)
return fls(h) + 32;
return fls(x);
}
static inline int fls(int x)
{
int ret;
if (__builtin_constant_p(x))
return constant_fls(x);
asm("clz\t%0, %1" : "=r" (ret) : "r" (x));
ret = 32 - ret;
return ret;
}
#endif
#ifdef PLATFORM_CPU
#define __fls(x) (fls(x) - 1)
static __always_inline int fls64(unsigned long x)
{
if (x == 0)
return 0;
return __fls(x) + 1;
}
static inline int fls(int x)
{
int r;
long tmp = -1;
asm("bsrl %1,%0"
: "=r" (r)
: "rm" (x), "0" (tmp));
#if 0
#ifdef CONFIG_X86_64
/*
* AMD64 says BSRL won't clobber the dest reg if x==0; Intel64 says the
* dest reg is undefined if x==0, but their CPU architect says its
* value is written to set it to the same as before, except that the
* top 32 bits will be cleared.
*
* We cannot do this on 32 bits because at the very least some
* 486 CPUs did not behave this way.
*/
long tmp = -1;
asm("bsrl %1,%0"
: "=r" (r)
: "rm" (x), "0" (tmp));
#elif defined(CONFIG_X86_CMOV)
asm("bsrl %1,%0\n\t"
"cmovzl %2,%0"
: "=&r" (r) : "rm" (x), "rm" (-1));
#else
asm("bsrl %1,%0\n\t"
"jnz 1f\n\t"
"movl $-1,%0\n"
"1:" : "=r" (r) : "rm" (x));
#endif
#endif
return r + 1;
}
#endif
/*
* internal helper to calculate the unused elements in a fifo
*/
static inline unsigned int kfifo_unused(struct __kfifo *fifo)
{
return (fifo->mask + 1) - (fifo->in - fifo->out);
}
static inline unsigned fls_long(unsigned long l)
{
if (sizeof(l) == 4)
return fls(l);
return fls64(l);
}
unsigned long roundup_pow_of_two(unsigned long n)
{
return 1UL << (fls_long(n));
}
int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, unsigned int esize)
{
/*
* round down to the next power of 2, since our 'let the indices
* wrap' technique works only in this case.
*/
if (!is_power_of_2(size))
size = roundup_pow_of_two(size);
fprintf(stdout, "+++++++++++kfifo malloc size = %u\n", size);
fifo->in = 0;
fifo->out = 0;
fifo->esize = esize;
if (size < 2) {
fifo->data = NULL;
fifo->mask = 0;
return -EINVAL;
}
fifo->data = malloc(size * esize);
if (!fifo->data) {
fifo->mask = 0;
return -ENOMEM;
}
fifo->mask = size - 1;
uv_mutex_init(&fifo->lock);
return 0;
}
void __kfifo_free(struct __kfifo *fifo)
{
free(fifo->data);
fifo->in = 0;
fifo->out = 0;
fifo->esize = 0;
fifo->data = NULL;
fifo->mask = 0;
}
int __kfifo_init(struct __kfifo *fifo, void *buffer,
unsigned int size, unsigned int esize)
{
size /= esize;
if (!is_power_of_2(size))
size = roundup_pow_of_two(size);
fifo->in = 0;
fifo->out = 0;
fifo->esize = esize;
fifo->data = buffer;
if (size < 2) {
fifo->mask = 0;
return -EINVAL;
}
fifo->mask = size - 1;
uv_mutex_init(&fifo->lock);
return 0;
}
static void kfifo_copy_in(struct __kfifo *fifo, const void *src,
unsigned int len, unsigned int off)
{
unsigned int size = fifo->mask + 1;
unsigned int esize = fifo->esize;
unsigned int l;
off &= fifo->mask;
if (esize != 1) {
off *= esize;
size *= esize;
len *= esize;
}
l = min(len, size - off);
memcpy(fifo->data + off, src, l);
memcpy(fifo->data, src + l, len - l);
/*
* make sure that the data in the fifo is up to date before
* incrementing the fifo->in index counter
*/
// smp_wmb();
}
unsigned int __kfifo_in(struct __kfifo *fifo,
const void *buf, unsigned int len)
{
unsigned int l;
l = kfifo_unused(fifo);
if (len > l)
len = l;
kfifo_copy_in(fifo, buf, len, fifo->in);
fifo->in += len;
return len;
}
static void kfifo_copy_out(struct __kfifo *fifo, void *dst,
unsigned int len, unsigned int off)
{
unsigned int size = fifo->mask + 1;
unsigned int esize = fifo->esize;
unsigned int l;
off &= fifo->mask;
if (esize != 1) {
off *= esize;
size *= esize;
len *= esize;
}
l = min(len, size - off);
if (dst) {
memcpy(dst, fifo->data + off, l);
memcpy(dst + l, fifo->data, len - l);
}
/*
* make sure that the data is copied before
* incrementing the fifo->out index counter
*/
// smp_wmb();
}
unsigned int __kfifo_out_peek(struct __kfifo *fifo,
void *buf, unsigned int len)
{
unsigned int l;
l = fifo->in - fifo->out;
if (len > l)
len = l;
kfifo_copy_out(fifo, buf, len, fifo->out);
return len;
}
unsigned int __kfifo_out(struct __kfifo *fifo,
void *buf, unsigned int len)
{
len = __kfifo_out_peek(fifo, buf, len);
fifo->out += len;
return len;
}
#if 0
static unsigned long kfifo_copy_from_user(struct __kfifo *fifo,
const void *from, unsigned int len, unsigned int off,
unsigned int *copied)
{
unsigned int size = fifo->mask + 1;
unsigned int esize = fifo->esize;
unsigned int l;
unsigned long ret;
off &= fifo->mask;
if (esize != 1) {
off *= esize;
size *= esize;
len *= esize;
}
l = min(len, size - off);
ret = memcpy(fifo->data + off, from, l);
if (unlikely(ret))
ret = DIV_ROUND_UP(ret + len - l, esize);
else {
ret = memcpy(fifo->data, from + l, len - l);
if (unlikely(ret))
ret = DIV_ROUND_UP(ret, esize);
}
/*
* make sure that the data in the fifo is up to date before
* incrementing the fifo->in index counter
*/
// smp_wmb();
*copied = len - ret;
/* return the number of elements which are not copied */
return ret;
}
int __kfifo_from_user(struct __kfifo *fifo, const void __user *from,
unsigned long len, unsigned int *copied)
{
unsigned int l;
unsigned long ret;
unsigned int esize = fifo->esize;
int err;
if (esize != 1)
len /= esize;
l = kfifo_unused(fifo);
if (len > l)
len = l;
ret = kfifo_copy_from_user(fifo, from, len, fifo->in, copied);
if (unlikely(ret)) {
len -= ret;
err = -EFAULT;
} else
err = 0;
fifo->in += len;
return err;
}
static unsigned long kfifo_copy_to_user(struct __kfifo *fifo, void __user *to,
unsigned int len, unsigned int off, unsigned int *copied)
{
unsigned int l;
unsigned long ret;
unsigned int size = fifo->mask + 1;
unsigned int esize = fifo->esize;
off &= fifo->mask;
if (esize != 1) {
off *= esize;
size *= esize;
len *= esize;
}
l = min(len, size - off);
ret = memcpy(to, fifo->data + off, l);
if (unlikely(ret))
ret = DIV_ROUND_UP(ret + len - l, esize);
else {
ret = memcpy(to + l, fifo->data, len - l);
if (unlikely(ret))
ret = DIV_ROUND_UP(ret, esize);
}
/*
* make sure that the data is copied before
* incrementing the fifo->out index counter
*/
//smp_wmb();
*copied = len - ret;
/* return the number of elements which are not copied */
return ret;
}
int __kfifo_to_user(struct __kfifo *fifo, void __user *to,
unsigned long len, unsigned int *copied)
{
unsigned int l;
unsigned long ret;
unsigned int esize = fifo->esize;
int err;
if (esize != 1)
len /= esize;
l = fifo->in - fifo->out;
if (len > l)
len = l;
ret = kfifo_copy_to_user(fifo, to, len, fifo->out, copied);
if (unlikely(ret)) {
len -= ret;
err = -EFAULT;
} else
err = 0;
fifo->out += len;
return err;
}
#endif
unsigned int __kfifo_max_r(unsigned int len, unsigned int recsize)
{
unsigned int max = (1 << (recsize << 3)) - 1;
if (len > max)
return max;
return len;
}
#define __KFIFO_PEEK(data, out, mask) \
((data)[(out) & (mask)])
/*
* __kfifo_peek_n internal helper function for determinate the length of
* the next record in the fifo
*/
static unsigned int __kfifo_peek_n(struct __kfifo *fifo, unsigned int recsize)
{
unsigned int l;
unsigned int mask = fifo->mask;
unsigned char *data = fifo->data;
l = __KFIFO_PEEK(data, fifo->out, mask);
if (--recsize)
l |= __KFIFO_PEEK(data, fifo->out + 1, mask) << 8;
return l;
}
#define __KFIFO_POKE(data, in, mask, val) \
( \
(data)[(in) & (mask)] = (unsigned char)(val) \
)
/*
* __kfifo_poke_n internal helper function for storeing the length of
* the record into the fifo
*/
static void __kfifo_poke_n(struct __kfifo *fifo, unsigned int n, unsigned int recsize)
{
unsigned int mask = fifo->mask;
unsigned char *data = fifo->data;
__KFIFO_POKE(data, fifo->in, mask, n);
if (recsize > 1)
__KFIFO_POKE(data, fifo->in + 1, mask, n >> 8);
}
unsigned int __kfifo_len_r(struct __kfifo *fifo, unsigned int recsize)
{
return __kfifo_peek_n(fifo, recsize);
}
unsigned int __kfifo_in_r(struct __kfifo *fifo, const void *buf,
unsigned int len, unsigned int recsize)
{
if (len + recsize > kfifo_unused(fifo))
return 0;
__kfifo_poke_n(fifo, len, recsize);
kfifo_copy_in(fifo, buf, len, fifo->in + recsize);
fifo->in += len + recsize;
return len;
}
static unsigned int kfifo_out_copy_r(struct __kfifo *fifo,
void *buf, unsigned int len, unsigned int recsize, unsigned int *n)
{
*n = __kfifo_peek_n(fifo, recsize);
if (len > *n)
len = *n;
kfifo_copy_out(fifo, buf, len, fifo->out + recsize);
return len;
}
unsigned int __kfifo_out_peek_r(struct __kfifo *fifo, void *buf,
unsigned int len, unsigned int recsize)
{
unsigned int n;
if (fifo->in == fifo->out)
return 0;
return kfifo_out_copy_r(fifo, buf, len, recsize, &n);
}
unsigned int __kfifo_out_r(struct __kfifo *fifo, void *buf,
unsigned int len, unsigned int recsize)
{
unsigned int n;
if (fifo->in == fifo->out)
return 0;
len = kfifo_out_copy_r(fifo, buf, len, recsize, &n);
fifo->out += n + recsize;
return len;
}
void __kfifo_skip_r(struct __kfifo *fifo, unsigned int recsize)
{
unsigned int n;
n = __kfifo_peek_n(fifo, recsize);
fifo->out += n + recsize;
}

View File

@ -0,0 +1,27 @@
#include <stdio.h>
#include <string.h>
#include "hal_mtk.h"
#include "log.h"
#define CFG_SAVE_PATH ("/var/mqttcfg/mqtt_cfg.cfg")
const char* hal_get_device_id(void)
{
return "547e1a1d7a7e5ced38ee8a3989fb8f97";
}
const char* hal_get_device_secret(void)
{
return "266726e07bf3210192e0868d9f7315f7";
}
const char* hal_get_device_name(void)
{
return "e0d7930776e745508ef930e1b0efaf65";
}
const char* hal_get_device_iot_id(void)
{
return "f65250e202664a229446b6bd2d6bccc4";
}

112
src/Framework/http/http.c Normal file
View File

@ -0,0 +1,112 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <curl/curl.h>
#include <sys/socket.h>
#include "uthash/utstring.h"
#include "hal_mtk.h"
#include "crypto.h"
#include "http.h"
#include "log.h"
#define HTTPS_RANDOM_LEN (14)
static size_t __writeDataCb(void *pData, size_t size, size_t nmemb, void *pParams)
{
int iMemSize = size * nmemb;
if(iMemSize > 0)
{
LOG_EX(LOG_Debug, "Receive: %s\n", (char*)pData);
}
return iMemSize;
}
const char* calc_register_checksum(char* pSecKey, char* pRandKey, int timeStamp, char* pCheckSum)
{
UT_string* pMsg;
utstring_new(pMsg);
utstring_printf(pMsg, "%s%s%d", pSecKey, pRandKey, timeStamp);
return hash_sha1((unsigned char*)utstring_body(pMsg), utstring_len(pMsg), pCheckSum);
}
int device_register(void)
{
CURLcode ret;
CURL* pCurl = NULL;
struct curl_slist* pList = NULL;
const char* pPostMsg = "";
UT_string* pProduct, *pNonce, *pCurTime, *pChecksum;
char randKey[HTTPS_RANDOM_LEN + 1];
char checkSum[64];
time_t timsStamp = time(NULL);
pCurl = curl_easy_init();
if(pCurl == NULL)
{
LOG_EX(LOG_Error, "Create CURL handle error\n");
return -1;
}
memset(checkSum, 0, 64);
memset(randKey, 0, HTTPS_RANDOM_LEN + 1);
rand_string(randKey, HTTPS_RANDOM_LEN);
utstring_new(pProduct);
utstring_new(pNonce);
utstring_new(pCurTime);
utstring_new(pChecksum);
calc_register_checksum(NETEASE_PRODUCT_SEC, randKey, timsStamp, checkSum);
utstring_printf(pProduct, "ProductKey: %s", NETEASE_PRODUCT_KEY);
utstring_printf(pNonce, "Nonce: %s", randKey);
utstring_printf(pCurTime, "CurTime: %d", timsStamp);
utstring_printf(pChecksum, "CheckSum: %s", checkSum);
pList = curl_slist_append(pList, utstring_body(pProduct));
pList = curl_slist_append(pList, utstring_body(pNonce));
pList = curl_slist_append(pList, utstring_body(pCurTime));
pList = curl_slist_append(pList, utstring_body(pChecksum));
pList = curl_slist_append(pList, "Content-Type:application/json;charset=UTF-8");
curl_easy_setopt(pCurl, CURLOPT_URL, NETEASE_API_SERVER);
curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, __writeDataCb);
curl_easy_setopt(pCurl, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt(pCurl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
curl_easy_setopt(pCurl, CURLOPT_HTTPHEADER, pList);
curl_easy_setopt(pCurl, CURLOPT_POSTFIELDS, NULL);
curl_easy_setopt(pCurl, CURLOPT_POSTFIELDSIZE, (long)0);
#if 0
curl_easy_setopt(pCurl, CURLOPT_CAINFO, "/etc/ssl/certs/ca-certificates.crt");
curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 1L);
#else
curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 0L);
#endif
ret = curl_easy_perform(pCurl);
curl_slist_free_all(pList);
utstring_free(pProduct);
utstring_free(pNonce);
utstring_free(pCurTime);
utstring_free(pChecksum);
if(ret != CURLE_OK)
{
LOG_EX(LOG_Error, "Run Http POST error: %s\n", curl_easy_strerror(ret));
curl_easy_cleanup(pCurl);
return -2;
}
curl_easy_cleanup(pCurl);
LOG_EX(LOG_Debug, "HTTP Post Finished\n");
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,294 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "cjson/s2j.h"
#include "protocol.h"
#include "log.h"
//#include "jsprase.h"
static char* __jsonSafeDecodeStr(cJSON* pJson, const char* pTags)
{
cJSON* pItem = cJSON_GetObjectItem(pJson, pTags);
if(pItem)
{
return strdup(pItem->valuestring);
}
else
{
return strdup("");
}
}
static const char* __pro2Json(void* pData)
{
PCLOUND_API pPro = (PCLOUND_API)pData;
const char* pJsonS;
s2j_create_json_obj(jObject);
s2j_json_set_basic_element(jObject, pPro, int, cmdId);
//s2j_json_set_basic_element(jObject, pPro, int, ver);
s2j_json_set_basic_element(jObject, pPro, int, cryptoType);
s2j_json_set_basic_element(jObject, pPro, int, timeStamp);
if(pPro->msgContent)
{
s2j_json_set_basic_element(jObject, pPro, string, msgContent);
}
pJsonS = cJSON_Print(jObject);
cJSON_Delete(jObject);
return pJsonS;
}
static void* __json2pro(const char* pJsonS)
{
cJSON* pItem = NULL;
PCLOUND_API pApi = NULL;
cJSON *pRoot = cJSON_Parse(pJsonS);
if(pRoot == NULL)
{
LOG_EX(LOG_Error, "Json Format Error: [%s]\n", pJsonS);
return NULL;
}
pApi = (PCLOUND_API)malloc(sizeof(CLOUND_API));
if(pApi == NULL)
{
LOG_EX(LOG_Error, "Malloc CLOUND_API Error\n");
cJSON_Delete(pRoot);
return NULL;
}
pApi->cmdId = cJSON_GetObjectItem(pRoot, "cmdId")->valueint;
//pApi->cmdId = cJSON_GetObjectItem(pRoot, "ver")->valueint;
pApi->cryptoType = cJSON_GetObjectItem(pRoot, "cryptoType")->valueint;
pApi->timeStamp = cJSON_GetObjectItem(pRoot, "timeStamp")->valueint;
pItem = cJSON_GetObjectItem(pRoot, "msgContent");
if(pItem)
{
char* pMsgContent = cJSON_GetObjectItem(pRoot, "msgContent")->valuestring;
pApi->msgContent = (char *)malloc(strlen(pMsgContent) + 1);
if(pApi->msgContent == NULL)
{
LOG_EX(LOG_Error, "Malloc MsgContent(%u) Memory Error\n", strlen(pMsgContent) + 1);
cJSON_Delete(pRoot);
free(pApi);
return NULL;
}
memset(pApi->msgContent, 0, strlen(pMsgContent) + 1);
strcpy(pApi->msgContent, pMsgContent);
}
else
{
pApi->msgContent = NULL;
}
cJSON_Delete(pRoot);
return pApi;
}
static const char* __bypass2Json(void* pData)
{
PBYPASS_INFO pInfo = (PBYPASS_INFO)pData;
const char* pJsonS;
s2j_create_json_obj(jObject);
if(pInfo->mcuCmd)
{
s2j_json_set_basic_element(jObject, pInfo, string, mcuCmd);
}
pJsonS = cJSON_Print(jObject);
cJSON_Delete(jObject);
return pJsonS;
}
static void* __json2bypass(const char* pJsonS)
{
PBYPASS_INFO pInfo = NULL;
cJSON *pRoot = cJSON_Parse(pJsonS);
if(pRoot == NULL)
{
LOG_EX(LOG_Error, "Json Format Error: [%s]\n", pJsonS);
return NULL;
}
pInfo = (PBYPASS_INFO)malloc(sizeof(BYPASS_INFO));
if(pInfo == NULL)
{
LOG_EX(LOG_Error, "Malloc BYPASS_INFO Error\n");
cJSON_Delete(pRoot);
return NULL;
}
pInfo->mcuCmd = __jsonSafeDecodeStr(pRoot, "mcuCmd");
cJSON_Delete(pRoot);
return pInfo;
}
static const char* __shadow2Json(void* pData)
{
PSHADOW_UPDATE pInfo = (PSHADOW_UPDATE)pData;
cJSON *pRoot, *pStatus, *pReports;
const char* pJsonS;
pRoot = cJSON_CreateObject();
cJSON_AddNumberToObject(pRoot, "version", pInfo->version);
cJSON_AddItemToObject(pRoot, "method", cJSON_CreateString(pInfo->method));
pStatus = cJSON_CreateObject();
pReports = cJSON_CreateObject();
cJSON_AddItemToObject(pRoot, "state", pStatus);
cJSON_AddItemToObject(pStatus, "reported", pReports);
cJSON_AddItemToObject(pReports, "mcuCmd", cJSON_CreateString(pInfo->state.reported.mcuCmd));
pJsonS = cJSON_Print(pRoot);
cJSON_Delete(pRoot);
return pJsonS;
}
static void* json2RegDev(const char* pJsonS)
{
PREGIST_DEVICE pInfo = NULL;
cJSON *pItem = NULL;
cJSON *pRoot = cJSON_Parse(pJsonS);
if(pRoot == NULL)
{
LOG_EX(LOG_Error, "Json Format Error: [%s]\n", pJsonS);
return NULL;
}
pInfo = (PREGIST_DEVICE)malloc(sizeof(REGIST_DEVICE));
if(pInfo == NULL)
{
LOG_EX(LOG_Error, "Malloc REGIST_DEVICE Error\n");
cJSON_Delete(pRoot);
return NULL;
}
memset(pInfo, 0, sizeof(REGIST_DEVICE));
pInfo->code = cJSON_GetObjectItem(pRoot, "code")->valueint;;
pInfo->msg = __jsonSafeDecodeStr(pRoot, "msg");
pInfo->requestId = __jsonSafeDecodeStr(pRoot, "requestId");
pItem = cJSON_GetObjectItem(pRoot, "data");
if(pItem)
{
pInfo->data.IotId = __jsonSafeDecodeStr(pItem, "IotId");
pInfo->data.DeviceName = __jsonSafeDecodeStr(pItem, "DeviceName");
pInfo->data.ProductKey = __jsonSafeDecodeStr(pItem, "ProductKey");
pInfo->data.DeviceSecret = __jsonSafeDecodeStr(pItem, "DeviceSecret");
}
cJSON_Delete(pRoot);
return pInfo;
}
static JSON_ENGINE g_jSonEngine[] =
{
{JE_PROMAIN, __pro2Json, __json2pro, NULL},
{JE_BYPASS, __bypass2Json, __json2bypass, NULL},
{JE_SHADOWUP, __shadow2Json, NULL, NULL},
{JE_REGDEVICE, NULL, json2RegDev, NULL},
};
void* Json2Struct(const char* pJsonStr, JSON_ENGINE_TYPE type, int cryptoType, int* pErr)
{
if(pJsonStr == NULL || pErr == NULL)
{
if(pErr)
{
*pErr = -ERR_INPUT_PARAMS;
}
return NULL;
}
if(type < 0 || type >= JE_MAX)
{
*pErr = -ERR_INPUT_PARAMS;
return NULL;
}
*pErr = 0;
//LOG_EX(LOG_Debug, "Json:\n%s\n", pJsonStr);
if(g_jSonEngine[type].jsonDecodeCb)
{
void *pStruct = g_jSonEngine[type].jsonDecodeCb(pJsonStr);
if(CRYPTO_NONE != cryptoType && g_jSonEngine[type].cryptoCb)
{
g_jSonEngine[type].cryptoCb(pStruct, cryptoType, CRYPTO_ENCODE);
}
return (pStruct);
}
else
{
return (NULL);
}
}
const char* Struct2Json(void* pStruct, JSON_ENGINE_TYPE type, int cryptoType, int* pErr)
{
if(pStruct == NULL || pErr == NULL)
{
if(pErr)
{
*pErr = -ERR_INPUT_PARAMS;
}
return NULL;
}
if(type < 0 || type >= JE_MAX)
{
*pErr = -ERR_INPUT_PARAMS;
return NULL;
}
*pErr = 0;
if(CRYPTO_NONE != cryptoType && g_jSonEngine[type].cryptoCb)
{
g_jSonEngine[type].cryptoCb(pStruct, cryptoType, CRYPTO_DECODE);
}
if(g_jSonEngine[type].jsonEncodeCb)
{
const char *pJsongStr = g_jSonEngine[type].jsonEncodeCb(pStruct);
LOG_EX(LOG_Debug, "Json: \n%s\n", pJsongStr);
return (pJsongStr);
}
else
{
return NULL;
}
}

View File

@ -0,0 +1,51 @@
/*
* This file is part of the struct2json Library.
*
* Copyright (c) 2015, Armink, <armink.ztl@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: Initialize interface for this library.
* Created on: 2015-10-14
*/
#include <stdlib.h>
#include <cjson/s2j.h>
S2jHook s2jHook = {
.malloc_fn = malloc,
.free_fn = free,
};
/**
* struct2json library initialize
* @note It will initialize cJSON library hooks.
*/
void s2j_init(S2jHook *hook) {
/* initialize cJSON library */
cJSON_InitHooks((cJSON_Hooks *)hook);
/* initialize hooks */
if (hook) {
s2jHook.malloc_fn = (hook->malloc_fn) ? hook->malloc_fn : malloc;
s2jHook.free_fn = (hook->free_fn) ? hook->free_fn : free;
} else {
s2jHook.malloc_fn = malloc;
s2jHook.free_fn = free;
}
}

168
src/Framework/mqtt/mqtt.c Normal file
View File

@ -0,0 +1,168 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <mosquitto.h>
#include <pthread.h>
#include "uthash/utstring.h"
#include "mqtt.h"
#include "log.h"
#include "hal_mtk.h"
static struct mosquitto *g_pMosq = NULL;
static pthread_t g_mqttThread;
static int g_isMqttConnected = FALSE;
static void __mqtt_connected_cb(struct mosquitto* pMosq, void* obj, int rc)
{
g_isMqttConnected = TRUE;
LOG_EX(LOG_Debug, "Connect to MQTT Server: %d\n", rc);
}
static void __mqtt_publish_cb(struct mosquitto* pMosq, void* obj, int mid)
{
LOG_EX(LOG_Debug, "Publish MQTT Message: %d\n", mid);
}
static void __mqtt_log_cb(struct mosquitto* pMosq, void* obj, int level, const char* pMsg)
{
LOG_EX(LOG_Debug, "MQTT Log Message[%d]: %s\n", level, pMsg);
}
static void __mqtt_disconnect_cb(struct mosquitto* pMosq, void* obj, int rc)
{
g_isMqttConnected = FALSE;
LOG_EX(LOG_Debug, "Disonnect to MQTT Server: %d\n", rc);
}
static void __mqtt_subscribe_cb(struct mosquitto* pMosq, void* obj, int mid, int qos_count, const int* granted_qos)
{
LOG_EX(LOG_Debug, "MQTT Subscribe: mid = %d, qos = %d\n", mid, qos_count);
}
static void __mqtt_unsubscribe_cb(struct mosquitto* pMosq, void* obj, int mid)
{
LOG_EX(LOG_Debug, "MQTT Subscribe: mid = %d\n", mid);
}
static void __mqtt_message_cb(struct mosquitto* pMosq, void* obj, const struct mosquitto_message* pMsg)
{
LOG_EX(LOG_Debug, "Receive MQTT Message:\nMid: %d\nMessage Size: %d\nMessage: %s\n",
pMsg->mid, pMsg->payloadlen, (char*)pMsg->payload);
}
static int __mqtt_connect_init(void)
{
int rc;
int major, minor, rev;
struct mosquitto *pMosq = NULL;
UT_string* pString = NULL;
g_isMqttConnected = FALSE;
rc = mosquitto_lib_version(&major, &minor, &rev);
LOG_EX(LOG_Debug, "rc:%d, major:%d, minor:%d, rev:%d\n", rc, major, minor, rev);
pMosq = mosquitto_new(hal_get_device_id(), TRUE, NULL);
if(!pMosq)
{
LOG_EX(LOG_Error, "Create MQTT Object Error\n");
return -1;
}
rc = mosquitto_tls_opts_set(pMosq, TRUE, "tlsv1.2", NULL);
if(rc)
{
LOG_EX(LOG_Error, "Set TLS Options Failed: %d\n", rc);
return -2;
}
rc = mosquitto_tls_set(pMosq, MQTT_CA_FILE_PATH, NULL, NULL, NULL, NULL);
if(rc)
{
LOG_EX(LOG_Error, "Set TLS Failed: %d\n", rc);
return -3;
}
rc = mosquitto_tls_insecure_set(pMosq, TRUE);
if(rc)
{
LOG_EX(LOG_Error, "Set Insecure Failed: %d\n", rc);
return -4;
}
mosquitto_connect_callback_set(pMosq, __mqtt_connected_cb);
mosquitto_publish_callback_set(pMosq, __mqtt_publish_cb);
mosquitto_log_callback_set(pMosq, __mqtt_log_cb);
mosquitto_disconnect_callback_set(pMosq, __mqtt_disconnect_cb);
mosquitto_subscribe_callback_set(pMosq, __mqtt_subscribe_cb);
mosquitto_unsubscribe_callback_set(pMosq, __mqtt_unsubscribe_cb);
mosquitto_message_callback_set(pMosq, __mqtt_message_cb);
utstring_new(pString);
utstring_printf(pString, "%s&%s", hal_get_device_name(), NETEASE_PRODUCT_KEY);
rc = mosquitto_username_pw_set(pMosq, utstring_body(pString), hal_get_device_secret());
if(rc)
{
utstring_free(pString);
LOG_EX(LOG_Error, "Set Username And Password error: %d\n", rc);
return -5;
}
rc = mosquitto_connect(pMosq, NETEASE_MQTT_SERVER, NETEASE_MQTT_PORT, 10);
if(rc)
{
utstring_free(pString);
LOG_EX(LOG_Error, "Can not connect to MQTT Server: %d\n", rc);
return -6;
}
else
{
LOG_EX(LOG_Debug, "MQTT Connect OK\n");
}
utstring_renew(pString);
utstring_printf(pString, "/%s/%s/get", NETEASE_PRODUCT_KEY, hal_get_device_name());
mosquitto_subscribe(pMosq, NULL, utstring_body(pString), 1);
g_pMosq = pMosq;
g_isMqttConnected = TRUE;
utstring_free(pString);
return 0;
}
static void* __mqtt_serverce_cb(void *p)
{
while(TRUE)
{
__mqtt_connect_init();
while(g_isMqttConnected)
{
mosquitto_loop(g_pMosq, 1000, 1);
usleep(1000);
}
mosquitto_disconnect(g_pMosq);
mosquitto_destroy(g_pMosq);
sleep(1);
}
}
void mqtt_proxy_setup(void)
{
pthread_create(&g_mqttThread, NULL, __mqtt_serverce_cb, NULL);
}

37
src/Makefile.cross Normal file
View File

@ -0,0 +1,37 @@
SHELL := /bin/sh
DIS_BUILD_WARRING ?= FALSE
EN_MAKE_MSG ?= TRUE
ifeq ($(EN_MAKE_MSG), TRUE)
MAKE_FLAGS :=
else
MAKE_FLAGS := -s
endif
ifneq ($(OPT), clean)
ifneq ($(OPT), install)
MAKE_FLAGS += -j$(shell cat /proc/cpuinfo | grep processor | wc -l)
endif
endif
ifeq ($(DIR), )
DEMO_INS_PATH := ./release
else
DEMO_INS_PATH := $(DIR)
endif
.PHONY : mqtt_proxy
all: mqtt_proxy
mqtt_proxy:
ifeq ($(OPT), clean)
@make $(MAKE_FLAGS) -C build -f Makefile.app.cross cleanall MAKE_TARGET=mqtt_proxy
else ifeq ($(OPT), install)
@make $(MAKE_FLAGS) -C build -f Makefile.app.cross install DIR=$(DIR) MAKE_TARGET=mqtt_proxy
else
@make all $(MAKE_FLAGS) -C build -f Makefile.app.cross DISABLE_WARRING=$(DIS_BUILD_WARRING) MAKE_TARGET=mqtt_proxy
endif

View File

@ -0,0 +1,57 @@
# target name, the target name must have the same name of c source file
TARGET_NAME=mqtt_proxy
# target
# for linux module driver: KO
# for application: EXE
# for dynamic library: DLL
TARGET_TYPE = EXE
# target object
# for application: APP
# for device driver: DRV
TARGET_OBJ = APP
TARGET_BOX =
#debug mode or release mode
DEBUG = TRUE
PLAT_R16 ?= TRUE
PLAT_R311 ?= FALSE
PLAT_LINUX ?= FALSE
PLAT_WIN32 ?= FALSE
PLAT_WIN64 ?= FALSE
VPATH = ../Framework ../log ../
# source code
# set the source file, don't used .o because of ...
# MRS Board Source Files
PLAT_R16_SRCS = \
log.c \
hexdump.c \
http/http.c \
mqtt/mqtt.c \
hal/hal_mtk.c \
crypto/crypto.c \
json_utils/cJSON.c \
json_utils/s2j.c \
json_utils/json_struct.c \
main.c
# gcc CFLAGS
PLAT_R16_CFLAGS := -I./ -I../include -DCURRENT_VERSION=\"1.0.0\"
R16_LIBS := -lpthread -lmosquitto -lcurl -lcrypto -lnghttp2 -lssl -lcares
# this line must be at below of thus, because of...
include /opt/common/Makefile.cross
ifeq ($(MAKECMDGOALS), )
$(shell find ./ -name $(TARGET)-*.exe -delete)
else
ifeq ($(MAKECMDGOALS), all)
$(shell find ./ -name "$(TARGET)-*.exe" -delete)
endif
endif

4
src/compile.sh Executable file
View File

@ -0,0 +1,4 @@
#!/usr/bin/env bash
source /etc/profile
make -f Makefile.cross OPT=clean && make -f Makefile.cross
#make && make OPT=install

285
src/include/cjson/cJSON.h Normal file
View File

@ -0,0 +1,285 @@
/*
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef cJSON__h
#define cJSON__h
#ifdef __cplusplus
extern "C"
{
#endif
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
#define __WINDOWS__
#endif
#ifdef __WINDOWS__
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
For *nix builds that support visibility attribute, you can define similar behavior by
setting default visibility to hidden by adding
-fvisibility=hidden (for gcc)
or
-xldscope=hidden (for sun cc)
to CFLAGS
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
*/
#define CJSON_CDECL __cdecl
#define CJSON_STDCALL __stdcall
/* export symbols by default, this is necessary for copy pasting the C and header file */
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_EXPORT_SYMBOLS
#endif
#if defined(CJSON_HIDE_SYMBOLS)
#define CJSON_PUBLIC(type) type CJSON_STDCALL
#elif defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
#elif defined(CJSON_IMPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
#endif
#else /* !__WINDOWS__ */
#define CJSON_CDECL
#define CJSON_STDCALL
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
#else
#define CJSON_PUBLIC(type) type
#endif
#endif
/* project version */
#define CJSON_VERSION_MAJOR 1
#define CJSON_VERSION_MINOR 7
#define CJSON_VERSION_PATCH 10
#include <stddef.h>
/* cJSON Types: */
#define cJSON_Invalid (0)
#define cJSON_False (1 << 0)
#define cJSON_True (1 << 1)
#define cJSON_NULL (1 << 2)
#define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4)
#define cJSON_Array (1 << 5)
#define cJSON_Object (1 << 6)
#define cJSON_Raw (1 << 7) /* raw json */
#define cJSON_IsReference 256
#define cJSON_StringIsConst 512
/* The cJSON structure: */
typedef struct cJSON
{
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *next;
struct cJSON *prev;
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
struct cJSON *child;
/* The type of the item, as above. */
int type;
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
char *valuestring;
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
int valueint;
/* The item's number, if type==cJSON_Number */
double valuedouble;
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
char *string;
} cJSON;
typedef struct cJSON_Hooks
{
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
void *(CJSON_CDECL *malloc_fn)(size_t sz);
void (CJSON_CDECL *free_fn)(void *ptr);
} cJSON_Hooks;
typedef int cJSON_bool;
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
* This is to prevent stack overflows. */
#ifndef CJSON_NESTING_LIMIT
#define CJSON_NESTING_LIMIT 1000
#endif
/* returns the version of cJSON as a string */
CJSON_PUBLIC(const char*) cJSON_Version(void);
/* Supply malloc, realloc and free functions to cJSON */
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
/* Render a cJSON entity to text for transfer/storage. */
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. */
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
/* Delete a cJSON entity and all subentities. */
CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
/* Returns the number of items in an array (or object). */
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
/* Get item "string" from object. Case insensitive. */
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
/* Check if the item is a string and return its valuestring */
CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item);
/* These functions check the type of an item */
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
/* These calls create a cJSON item of the appropriate type. */
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
/* raw json */
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
/* Create a string where valuestring references a string so
* it will not be freed by cJSON_Delete */
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
/* Create an object/arrray that only references it's elements so
* they will not be freed by cJSON_Delete */
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
/* These utilities create an Array of count items. */
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
/* Append item to the specified array/object. */
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
* writing to `item->string` */
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
/* Remove/Detatch items from Arrays/Objects. */
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
/* Update array items. */
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
/* Duplicate a cJSON item */
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
need to be released. With recurse!=0, it will duplicate any children connected to the item.
The item->next and ->prev pointers are always zero on return from Duplicate. */
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
CJSON_PUBLIC(void) cJSON_Minify(char *json);
/* Helper functions for creating and adding items to an object at the same time.
* They return the added item or NULL on failure. */
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
/* helper for the cJSON_SetNumberValue macro */
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
/* Macro for iterating over an array or object */
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
CJSON_PUBLIC(void) cJSON_free(void *object);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,88 @@
/*
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef cJSON_Utils__h
#define cJSON_Utils__h
#ifdef __cplusplus
extern "C"
{
#endif
#include "cJSON.h"
/* Implement RFC6901 (https://tools.ietf.org/html/rfc6901) JSON Pointer spec. */
CJSON_PUBLIC(cJSON *) cJSONUtils_GetPointer(cJSON * const object, const char *pointer);
CJSON_PUBLIC(cJSON *) cJSONUtils_GetPointerCaseSensitive(cJSON * const object, const char *pointer);
/* Implement RFC6902 (https://tools.ietf.org/html/rfc6902) JSON Patch spec. */
/* NOTE: This modifies objects in 'from' and 'to' by sorting the elements by their key */
CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatches(cJSON * const from, cJSON * const to);
CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatchesCaseSensitive(cJSON * const from, cJSON * const to);
/* Utility for generating patch array entries. */
CJSON_PUBLIC(void) cJSONUtils_AddPatchToArray(cJSON * const array, const char * const operation, const char * const path, const cJSON * const value);
/* Returns 0 for success. */
CJSON_PUBLIC(int) cJSONUtils_ApplyPatches(cJSON * const object, const cJSON * const patches);
CJSON_PUBLIC(int) cJSONUtils_ApplyPatchesCaseSensitive(cJSON * const object, const cJSON * const patches);
/*
// Note that ApplyPatches is NOT atomic on failure. To implement an atomic ApplyPatches, use:
//int cJSONUtils_AtomicApplyPatches(cJSON **object, cJSON *patches)
//{
// cJSON *modme = cJSON_Duplicate(*object, 1);
// int error = cJSONUtils_ApplyPatches(modme, patches);
// if (!error)
// {
// cJSON_Delete(*object);
// *object = modme;
// }
// else
// {
// cJSON_Delete(modme);
// }
//
// return error;
//}
// Code not added to library since this strategy is a LOT slower.
*/
/* Implement RFC7386 (https://tools.ietf.org/html/rfc7396) JSON Merge Patch spec. */
/* target will be modified by patch. return value is new ptr for target. */
CJSON_PUBLIC(cJSON *) cJSONUtils_MergePatch(cJSON *target, const cJSON * const patch);
CJSON_PUBLIC(cJSON *) cJSONUtils_MergePatchCaseSensitive(cJSON *target, const cJSON * const patch);
/* generates a patch to move from -> to */
/* NOTE: This modifies objects in 'from' and 'to' by sorting the elements by their key */
CJSON_PUBLIC(cJSON *) cJSONUtils_GenerateMergePatch(cJSON * const from, cJSON * const to);
CJSON_PUBLIC(cJSON *) cJSONUtils_GenerateMergePatchCaseSensitive(cJSON * const from, cJSON * const to);
/* Given a root object and a target object, construct a pointer from one to the other. */
CJSON_PUBLIC(char *) cJSONUtils_FindPointerFromObjectTo(const cJSON * const object, const cJSON * const target);
/* Sorts the members of the object into alphabetical order. */
CJSON_PUBLIC(void) cJSONUtils_SortObject(cJSON * const object);
CJSON_PUBLIC(void) cJSONUtils_SortObjectCaseSensitive(cJSON * const object);
#ifdef __cplusplus
}
#endif
#endif

92
src/include/cjson/s2j.h Normal file
View File

@ -0,0 +1,92 @@
/*
* This file is part of the struct2json Library.
*
* Copyright (c) 2015, Armink, <armink.ztl@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: It is an head file for this library. You can see all be called functions.
* Created on: 2015-10-14
*/
#ifndef __S2J_H__
#define __S2J_H__
#include <string.h>
#include "cJSON.h"
#include "s2jdef.h"
#ifdef __cplusplus
extern "C" {
#endif
/* struct2json software version number */
#define S2J_SW_VERSION "1.0.3"
/* Create JSON object */
#define s2j_create_json_obj(json_obj) \
S2J_CREATE_JSON_OBJECT(json_obj)
/* Delete JSON object */
#define s2j_delete_json_obj(json_obj) \
S2J_DELETE_JSON_OBJECT(json_obj)
/* Set basic type element for JSON object */
#define s2j_json_set_basic_element(to_json, from_struct, type, element) \
S2J_JSON_SET_BASIC_ELEMENT(to_json, from_struct, type, element)
/* Set array type element for JSON object */
#define s2j_json_set_array_element(to_json, from_struct, type, element, size) \
S2J_JSON_SET_ARRAY_ELEMENT(to_json, from_struct, type, element, size)
/* Set child structure type element for JSON object */
#define s2j_json_set_struct_element(child_json, to_json, child_struct, from_struct, type, element) \
S2J_JSON_SET_STRUCT_ELEMENT(child_json, to_json, child_struct, from_struct, type, element)
/* Create structure object */
#define s2j_create_struct_obj(struct_obj, type) \
S2J_CREATE_STRUCT_OBJECT(struct_obj, type)
/* Delete structure object */
#define s2j_delete_struct_obj(struct_obj) \
S2J_DELETE_STRUCT_OBJECT(struct_obj)
/* Get basic type element for structure object */
#define s2j_struct_get_basic_element(to_struct, from_json, type, element) \
S2J_STRUCT_GET_BASIC_ELEMENT(to_struct, from_json, type, element)
/* Get array type element for structure object */
#define s2j_struct_get_array_element(to_struct, from_json, type, element) \
S2J_STRUCT_GET_ARRAY_ELEMENT(to_struct, from_json, type, element)
/* Get child structure type element for structure object */
#define s2j_struct_get_struct_element(child_struct, to_struct, child_json, from_json, type, element) \
S2J_STRUCT_GET_STRUCT_ELEMENT(child_struct, to_struct, child_json, from_json, type, element)
/* s2j.c */
extern S2jHook s2jHook;
void s2j_init(S2jHook *hook);
#ifdef __cplusplus
}
#endif
#endif /* __S2J_H__ */

150
src/include/cjson/s2jdef.h Normal file
View File

@ -0,0 +1,150 @@
/*
* This file is part of the struct2json Library.
*
* Copyright (c) 2015, Armink, <armink.ztl@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: It is an head file for this library.
* Created on: 2015-10-14
*/
#ifndef __S2JDEF_H__
#define __S2JDEF_H__
#include <string.h>
#include "cJSON.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
void *(*malloc_fn)(size_t sz);
void (*free_fn)(void *ptr);
} S2jHook, *S2jHook_t;
#define S2J_STRUCT_GET_int_ELEMENT(to_struct, from_json, _element) \
json_temp = cJSON_GetObjectItem(from_json, #_element); \
if (json_temp) (to_struct)->_element = json_temp->valueint;
#define S2J_STRUCT_GET_string_ELEMENT(to_struct, from_json, _element) \
json_temp = cJSON_GetObjectItem(from_json, #_element); \
if (json_temp) strcpy((to_struct)->_element, json_temp->valuestring);
#define S2J_STRUCT_GET_double_ELEMENT(to_struct, from_json, _element) \
json_temp = cJSON_GetObjectItem(from_json, #_element); \
if (json_temp) (to_struct)->_element = json_temp->valuedouble;
#define S2J_STRUCT_ARRAY_GET_int_ELEMENT(to_struct, from_json, _element, index) \
(to_struct)->_element[index] = from_json->valueint;
#define S2J_STRUCT_ARRAY_GET_string_ELEMENT(to_struct, from_json, _element, index) \
strcpy((to_struct)->_element[index], from_json->valuestring);
#define S2J_STRUCT_ARRAY_GET_double_ELEMENT(to_struct, from_json, _element, index) \
(to_struct)->_element[index] = from_json->valuedouble;
#define S2J_STRUCT_ARRAY_GET_ELEMENT(to_struct, from_json, type, _element, index) \
S2J_STRUCT_ARRAY_GET_##type##_ELEMENT(to_struct, from_json, _element, index)
#define S2J_JSON_SET_int_ELEMENT(to_json, from_struct, _element) \
cJSON_AddNumberToObject(to_json, #_element, (from_struct)->_element);
#define S2J_JSON_SET_double_ELEMENT(to_json, from_struct, _element) \
cJSON_AddNumberToObject(to_json, #_element, (from_struct)->_element);
#define S2J_JSON_SET_string_ELEMENT(to_json, from_struct, _element) \
cJSON_AddStringToObject(to_json, #_element, (from_struct)->_element);
#define S2J_JSON_ARRAY_SET_int_ELEMENT(to_json, from_struct, _element, index) \
cJSON_AddItemToArray(to_json, cJSON_CreateNumber((from_struct)->_element[index]));
#define S2J_JSON_ARRAY_SET_double_ELEMENT(to_json, from_struct, _element, index) \
cJSON_AddItemToArray(to_json, cJSON_CreateNumber((from_struct)->_element[index]));
#define S2J_JSON_ARRAY_SET_string_ELEMENT(to_json, from_struct, _element, index) \
cJSON_AddItemToArray(to_json, cJSON_CreateString((from_struct)->_element[index]));
#define S2J_JSON_ARRAY_SET_ELEMENT(to_json, from_struct, type, _element, index) \
S2J_JSON_ARRAY_SET_##type##_ELEMENT(to_json, from_struct, _element, index)
#define S2J_CREATE_JSON_OBJECT(json_obj) \
cJSON *json_obj = cJSON_CreateObject();
#define S2J_DELETE_JSON_OBJECT(json_obj) \
cJSON_Delete(json_obj);
#define S2J_JSON_SET_BASIC_ELEMENT(to_json, from_struct, type, _element) \
S2J_JSON_SET_##type##_ELEMENT(to_json, from_struct, _element)
#define S2J_JSON_SET_ARRAY_ELEMENT(to_json, from_struct, type, _element, size) \
{ \
cJSON *array; \
size_t index = 0; \
array = cJSON_CreateArray(); \
if (array) { \
while (index < size) { \
S2J_JSON_ARRAY_SET_ELEMENT(array, from_struct, type, _element, index++); \
} \
cJSON_AddItemToObject(to_json, #_element, array); \
} \
}
#define S2J_JSON_SET_STRUCT_ELEMENT(child_json, to_json, child_struct, from_struct, type, _element) \
type *child_struct = &((from_struct)->_element); \
cJSON *child_json = cJSON_CreateObject(); \
if (child_json) cJSON_AddItemToObject(to_json, #_element, child_json);
#define S2J_CREATE_STRUCT_OBJECT(struct_obj, type) \
cJSON *json_temp; \
type *struct_obj = s2jHook.malloc_fn(sizeof(type)); \
if (struct_obj) memset(struct_obj, 0, sizeof(type));
#define S2J_DELETE_STRUCT_OBJECT(struct_obj) \
s2jHook.free_fn(struct_obj);
#define S2J_STRUCT_GET_BASIC_ELEMENT(to_struct, from_json, type, _element) \
S2J_STRUCT_GET_##type##_ELEMENT(to_struct, from_json, _element)
#define S2J_STRUCT_GET_ARRAY_ELEMENT(to_struct, from_json, type, _element) \
{ \
cJSON *array, *array_element; \
size_t index = 0, size = 0; \
array = cJSON_GetObjectItem(from_json, #_element); \
if (array) { \
size = cJSON_GetArraySize(array); \
while (index < size) { \
array_element = cJSON_GetArrayItem(array, index); \
if (array_element) S2J_STRUCT_ARRAY_GET_ELEMENT(to_struct, array_element, type, _element, index++); \
} \
} \
}
#define S2J_STRUCT_GET_STRUCT_ELEMENT(child_struct, to_struct, child_json, from_json, type, _element) \
type *child_struct = &((to_struct)->_element); \
cJSON *child_json = cJSON_GetObjectItem(from_json, #_element);
#ifdef __cplusplus
}
#endif
#endif /* __S2JDEF_H__ */

20
src/include/crypto.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef CRYPTO_H
#define CRYPTO_H
#ifdef __cplusplus
extern "C" {
#endif
#define SHA1_DIGEST_LENGTH (20)
const char* rand_string(char* pRandKey, int ilen);
const char* hash_sha1(unsigned char* pData, int iSize, char* pHashCode);
#ifdef __cplusplus
}
#endif
#endif

724
src/include/fifo.h Normal file
View File

@ -0,0 +1,724 @@
/*
* A generic kernel FIFO implementation
*
* Copyright (C) 2009/2010 Stefani Seibold <stefani@seibold.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef FIFO_H
#define FIFO_H
#include <uv.h>
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
#define __must_check __attribute__((warn_unused_result))
/*
* How to porting drivers to the new generic FIFO API:
*
* - Modify the declaration of the "struct kfifo *" object into a
* in-place "struct kfifo" object
* - Init the in-place object with kfifo_alloc() or kfifo_init()
* Note: The address of the in-place "struct kfifo" object must be
* passed as the first argument to this functions
* - Replace the use of __kfifo_put into kfifo_in and __kfifo_get
* into kfifo_out
* - Replace the use of kfifo_put into kfifo_in_spinlocked and kfifo_get
* into kfifo_out_spinlocked
* Note: the spinlock pointer formerly passed to kfifo_init/kfifo_alloc
* must be passed now to the kfifo_in_spinlocked and kfifo_out_spinlocked
* as the last parameter
* - The formerly __kfifo_* functions are renamed into kfifo_*
*/
/*
* Note about locking : There is no locking required until only * one reader
* and one writer is using the fifo and no kfifo_reset() will be * called
* kfifo_reset_out() can be safely used, until it will be only called
* in the reader thread.
* For multiple writer and one reader there is only a need to lock the writer.
* And vice versa for only one writer and multiple reader there is only a need
* to lock the reader.
*/
struct __kfifo {
unsigned int in;
unsigned int out;
unsigned int mask;
unsigned int esize;
void *data;
uv_mutex_t lock;
};
#define __STRUCT_KFIFO_COMMON(datatype, recsize, ptrtype) \
union { \
struct __kfifo kfifo; \
datatype *type; \
char (*rectype)[recsize]; \
ptrtype *ptr; \
const ptrtype *ptr_const; \
}
#define __STRUCT_KFIFO(type, size, recsize, ptrtype) \
{ \
__STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \
type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \
}
#define STRUCT_KFIFO(type, size) \
struct __STRUCT_KFIFO(type, size, 0, type)
#define __STRUCT_KFIFO_PTR(type, recsize, ptrtype) \
{ \
__STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \
type buf[0]; \
}
#define STRUCT_KFIFO_PTR(type) \
struct __STRUCT_KFIFO_PTR(type, 0, type)
/*
* define compatibility "struct kfifo" for dynamic allocated fifos
*/
struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void);
#define STRUCT_KFIFO_REC_1(size) \
struct __STRUCT_KFIFO(unsigned char, size, 1, void)
#define STRUCT_KFIFO_REC_2(size) \
struct __STRUCT_KFIFO(unsigned char, size, 2, void)
/*
* define kfifo_rec types
*/
struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1, void);
struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void);
/*
* helper macro to distinguish between real in place fifo where the fifo
* array is a part of the structure and the fifo type where the array is
* outside of the fifo structure.
*/
#define __is_kfifo_ptr(fifo) (sizeof(*fifo) == sizeof(struct __kfifo))
/**
* DECLARE_KFIFO_PTR - macro to declare a fifo pointer object
* @fifo: name of the declared fifo
* @type: type of the fifo elements
*/
#define DECLARE_KFIFO_PTR(fifo, type) STRUCT_KFIFO_PTR(type) fifo
/**
* DECLARE_KFIFO - macro to declare a fifo object
* @fifo: name of the declared fifo
* @type: type of the fifo elements
* @size: the number of elements in the fifo, this must be a power of 2
*/
#define DECLARE_KFIFO(fifo, type, size) STRUCT_KFIFO(type, size) fifo
/**
* INIT_KFIFO - Initialize a fifo declared by DECLARE_KFIFO
* @fifo: name of the declared fifo datatype
*/
#define INIT_KFIFO(fifo) \
(void)({ \
typeof(&(fifo)) __tmp = &(fifo); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
__kfifo->in = 0; \
__kfifo->out = 0; \
__kfifo->mask = __is_kfifo_ptr(__tmp) ? 0 : ARRAY_SIZE(__tmp->buf) - 1;\
__kfifo->esize = sizeof(*__tmp->buf); \
__kfifo->data = __is_kfifo_ptr(__tmp) ? NULL : __tmp->buf; \
})
/**
* DEFINE_KFIFO - macro to define and initialize a fifo
* @fifo: name of the declared fifo datatype
* @type: type of the fifo elements
* @size: the number of elements in the fifo, this must be a power of 2
*
* Note: the macro can be used for global and local fifo data type variables.
*/
#define DEFINE_KFIFO(fifo, type, size) \
DECLARE_KFIFO(fifo, type, size) = \
(typeof(fifo)) { \
{ \
{ \
.in = 0, \
.out = 0, \
.mask = __is_kfifo_ptr(&(fifo)) ? \
0 : \
ARRAY_SIZE((fifo).buf) - 1, \
.esize = sizeof(*(fifo).buf), \
.data = __is_kfifo_ptr(&(fifo)) ? \
NULL : \
(fifo).buf, \
} \
} \
}
static inline unsigned int __must_check
__kfifo_uint_must_check_helper(unsigned int val)
{
return val;
}
static inline int __must_check
__kfifo_int_must_check_helper(int val)
{
return val;
}
/**
* kfifo_initialized - Check if the fifo is initialized
* @fifo: address of the fifo to check
*
* Return %true if fifo is initialized, otherwise %false.
* Assumes the fifo was 0 before.
*/
#define kfifo_initialized(fifo) ((fifo)->kfifo.mask)
/**
* kfifo_esize - returns the size of the element managed by the fifo
* @fifo: address of the fifo to be used
*/
#define kfifo_esize(fifo) ((fifo)->kfifo.esize)
/**
* kfifo_recsize - returns the size of the record length field
* @fifo: address of the fifo to be used
*/
#define kfifo_recsize(fifo) (sizeof(*(fifo)->rectype))
/**
* kfifo_size - returns the size of the fifo in elements
* @fifo: address of the fifo to be used
*/
#define kfifo_size(fifo) ((fifo)->kfifo.mask + 1)
/**
* kfifo_reset - removes the entire fifo content
* @fifo: address of the fifo to be used
*
* Note: usage of kfifo_reset() is dangerous. It should be only called when the
* fifo is exclusived locked or when it is secured that no other thread is
* accessing the fifo.
*/
#define kfifo_reset(fifo) \
(void)({ \
typeof((fifo) + 1) __tmp = (fifo); \
__tmp->kfifo.in = __tmp->kfifo.out = 0; \
})
/**
* kfifo_reset_out - skip fifo content
* @fifo: address of the fifo to be used
*
* Note: The usage of kfifo_reset_out() is safe until it will be only called
* from the reader thread and there is only one concurrent reader. Otherwise
* it is dangerous and must be handled in the same way as kfifo_reset().
*/
#define kfifo_reset_out(fifo) \
(void)({ \
typeof((fifo) + 1) __tmp = (fifo); \
__tmp->kfifo.out = __tmp->kfifo.in; \
})
/**
* kfifo_len - returns the number of used elements in the fifo
* @fifo: address of the fifo to be used
*/
#define kfifo_len(fifo) \
({ \
typeof((fifo) + 1) __tmpl = (fifo); \
__tmpl->kfifo.in - __tmpl->kfifo.out; \
})
/**
* kfifo_is_empty - returns true if the fifo is empty
* @fifo: address of the fifo to be used
*/
#define kfifo_is_empty(fifo) \
({ \
typeof((fifo) + 1) __tmpq = (fifo); \
__tmpq->kfifo.in == __tmpq->kfifo.out; \
})
/**
* kfifo_is_full - returns true if the fifo is full
* @fifo: address of the fifo to be used
*/
#define kfifo_is_full(fifo) \
({ \
typeof((fifo) + 1) __tmpq = (fifo); \
kfifo_len(__tmpq) > __tmpq->kfifo.mask; \
})
/**
* kfifo_avail - returns the number of unused elements in the fifo
* @fifo: address of the fifo to be used
*/
#define kfifo_avail(fifo) \
__kfifo_uint_must_check_helper( \
({ \
typeof((fifo) + 1) __tmpq = (fifo); \
const unsigned int __recsize = sizeof(*__tmpq->rectype); \
unsigned int __avail = kfifo_size(__tmpq) - kfifo_len(__tmpq); \
(__recsize) ? ((__avail <= __recsize) ? 0 : \
__kfifo_max_r(__avail - __recsize, __recsize)) : \
__avail; \
}) \
)
/**
* kfifo_skip - skip output data
* @fifo: address of the fifo to be used
*/
#define kfifo_skip(fifo) \
(void)({ \
typeof((fifo) + 1) __tmp = (fifo); \
const unsigned int __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (__recsize) \
__kfifo_skip_r(__kfifo, __recsize); \
else \
__kfifo->out++; \
})
/**
* kfifo_peek_len - gets the size of the next fifo record
* @fifo: address of the fifo to be used
*
* This function returns the size of the next fifo record in number of bytes.
*/
#define kfifo_peek_len(fifo) \
__kfifo_uint_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
const unsigned int __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
(!__recsize) ? kfifo_len(__tmp) * sizeof(*__tmp->type) : \
__kfifo_len_r(__kfifo, __recsize); \
}) \
)
/**
* kfifo_alloc - dynamically allocates a new fifo buffer
* @fifo: pointer to the fifo
* @size: the number of elements in the fifo, this must be a power of 2
* @gfp_mask: get_free_pages mask, passed to kmalloc()
*
* This macro dynamically allocates a new fifo buffer.
*
* The numer of elements will be rounded-up to a power of 2.
* The fifo will be release with kfifo_free().
* Return 0 if no error, otherwise an error code.
*/
#define kfifo_alloc(fifo, size) \
__kfifo_int_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
__is_kfifo_ptr(__tmp) ? \
__kfifo_alloc(__kfifo, size, sizeof(*__tmp->type)) : \
-EINVAL; \
}) \
)
/**
* kfifo_free - frees the fifo
* @fifo: the fifo to be freed
*/
#define kfifo_free(fifo) \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (__is_kfifo_ptr(__tmp)) \
__kfifo_free(__kfifo); \
})
/**
* kfifo_init - initialize a fifo using a preallocated buffer
* @fifo: the fifo to assign the buffer
* @buffer: the preallocated buffer to be used
* @size: the size of the internal buffer, this have to be a power of 2
*
* This macro initialize a fifo using a preallocated buffer.
*
* The numer of elements will be rounded-up to a power of 2.
* Return 0 if no error, otherwise an error code.
*/
#define kfifo_init(fifo, buffer, size) \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
__is_kfifo_ptr(__tmp) ? \
__kfifo_init(__kfifo, buffer, size, sizeof(*__tmp->type)) : \
-EINVAL; \
})
/**
* kfifo_put - put data into the fifo
* @fifo: address of the fifo to be used
* @val: the data to be added
*
* This macro copies the given value into the fifo.
* It returns 0 if the fifo was full. Otherwise it returns the number
* processed elements.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macro.
*/
#define kfifo_put(fifo, val) \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
typeof((val) + 1) __val = (val); \
unsigned int __ret; \
const unsigned int __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (0) { \
typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \
__dummy = (typeof(__val))NULL; \
} \
if (__recsize) \
__ret = __kfifo_in_r(__kfifo, __val, sizeof(*__val), \
__recsize); \
else { \
__ret = !kfifo_is_full(__tmp); \
if (__ret) { \
(__is_kfifo_ptr(__tmp) ? \
((typeof(__tmp->type))__kfifo->data) : \
(__tmp->buf) \
)[__kfifo->in & __tmp->kfifo.mask] = \
*(typeof(__tmp->type))__val; \
__kfifo->in++; \
} \
} \
__ret; \
})
/**
* kfifo_get - get data from the fifo
* @fifo: address of the fifo to be used
* @val: the var where to store the data to be added
*
* This macro reads the data from the fifo.
* It returns 0 if the fifo was empty. Otherwise it returns the number
* processed elements.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macro.
*/
#define kfifo_get(fifo, val) \
__kfifo_uint_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
typeof((val) + 1) __val = (val); \
unsigned int __ret; \
const unsigned int __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (0) \
__val = (typeof(__tmp->ptr))0; \
if (__recsize) \
__ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \
__recsize); \
else { \
__ret = !kfifo_is_empty(__tmp); \
if (__ret) { \
*(typeof(__tmp->type))__val = \
(__is_kfifo_ptr(__tmp) ? \
((typeof(__tmp->type))__kfifo->data) : \
(__tmp->buf) \
)[__kfifo->out & __tmp->kfifo.mask]; \
__kfifo->out++; \
} \
} \
__ret; \
}) \
)
/**
* kfifo_peek - get data from the fifo without removing
* @fifo: address of the fifo to be used
* @val: the var where to store the data to be added
*
* This reads the data from the fifo without removing it from the fifo.
* It returns 0 if the fifo was empty. Otherwise it returns the number
* processed elements.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macro.
*/
#define kfifo_peek(fifo, val) \
__kfifo_uint_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
typeof((val) + 1) __val = (val); \
unsigned int __ret; \
const unsigned int __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (0) \
__val = (typeof(__tmp->ptr))NULL; \
if (__recsize) \
__ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \
__recsize); \
else { \
__ret = !kfifo_is_empty(__tmp); \
if (__ret) { \
*(typeof(__tmp->type))__val = \
(__is_kfifo_ptr(__tmp) ? \
((typeof(__tmp->type))__kfifo->data) : \
(__tmp->buf) \
)[__kfifo->out & __tmp->kfifo.mask]; \
} \
} \
__ret; \
}) \
)
/**
* kfifo_in - put data into the fifo
* @fifo: address of the fifo to be used
* @buf: the data to be added
* @n: number of elements to be added
*
* This macro copies the given buffer into the fifo and returns the
* number of copied elements.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macro.
*/
#define kfifo_in(fifo, buf, n) \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
typeof((buf) + 1) __buf = (buf); \
unsigned long __n = (n); \
const unsigned int __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (0) { \
typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \
__dummy = (typeof(__buf))NULL; \
} \
(__recsize) ?\
__kfifo_in_r(__kfifo, __buf, __n, __recsize) : \
__kfifo_in(__kfifo, __buf, __n); \
})
/**
* kfifo_in_spinlocked - put data into the fifo using a spinlock for locking
* @fifo: address of the fifo to be used
* @buf: the data to be added
* @n: number of elements to be added
* @lock: pointer to the spinlock to use for locking
*
* This macro copies the given values buffer into the fifo and returns the
* number of copied elements.
*/
#define kfifo_in_locked(fifo, buf, n) \
({ \
unsigned int __ret; \
uv_mutex_t __lock = ((struct __kfifo*)fifo)->lock; \
uv_mutex_lock(&__lock); \
__ret = kfifo_in(fifo, buf, n); \
uv_mutex_unlock(&__lock); \
__ret; \
})
/**
* kfifo_out - get data from the fifo
* @fifo: address of the fifo to be used
* @buf: pointer to the storage buffer
* @n: max. number of elements to get
*
* This macro get some data from the fifo and return the numbers of elements
* copied.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macro.
*/
#define kfifo_out(fifo, buf, n) \
__kfifo_uint_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
typeof((buf) + 1) __buf = (buf); \
unsigned long __n = (n); \
const unsigned int __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (0) { \
typeof(__tmp->ptr) __dummy = NULL; \
__buf = __dummy; \
} \
(__recsize) ?\
__kfifo_out_r(__kfifo, __buf, __n, __recsize) : \
__kfifo_out(__kfifo, __buf, __n); \
}) \
)
/**
* kfifo_out_spinlocked - get data from the fifo using a spinlock for locking
* @fifo: address of the fifo to be used
* @buf: pointer to the storage buffer
* @n: max. number of elements to get
* @lock: pointer to the spinlock to use for locking
*
* This macro get the data from the fifo and return the numbers of elements
* copied.
*/
#define kfifo_out_locked(fifo, buf, n) \
__kfifo_uint_must_check_helper( \
({ \
unsigned int __ret; \
uv_mutex_t __lock = ((struct __kfifo*)fifo)->lock; \
uv_mutex_lock(&__lock); \
__ret = kfifo_out(fifo, buf, n); \
uv_mutex_unlock(&__lock); \
__ret; \
}) \
)
/**
* kfifo_from_user - puts some data from user space into the fifo
* @fifo: address of the fifo to be used
* @from: pointer to the data to be added
* @len: the length of the data to be added
* @copied: pointer to output variable to store the number of copied bytes
*
* This macro copies at most @len bytes from the @from into the
* fifo, depending of the available space and returns -EFAULT/0.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macro.
*/
#define kfifo_from_user(fifo, from, len, copied) \
__kfifo_uint_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
const void __user *__from = (from); \
unsigned int __len = (len); \
unsigned int *__copied = (copied); \
const unsigned int __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
(__recsize) ? \
__kfifo_from_user_r(__kfifo, __from, __len, __copied, __recsize) : \
__kfifo_from_user(__kfifo, __from, __len, __copied); \
}) \
)
/**
* kfifo_to_user - copies data from the fifo into user space
* @fifo: address of the fifo to be used
* @to: where the data must be copied
* @len: the size of the destination buffer
* @copied: pointer to output variable to store the number of copied bytes
*
* This macro copies at most @len bytes from the fifo into the
* @to buffer and returns -EFAULT/0.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macro.
*/
#define kfifo_to_user(fifo, to, len, copied) \
__kfifo_uint_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
void __user *__to = (to); \
unsigned int __len = (len); \
unsigned int *__copied = (copied); \
const unsigned int __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
(__recsize) ? \
__kfifo_to_user_r(__kfifo, __to, __len, __copied, __recsize) : \
__kfifo_to_user(__kfifo, __to, __len, __copied); \
}) \
)
/**
* kfifo_out_peek - gets some data from the fifo
* @fifo: address of the fifo to be used
* @buf: pointer to the storage buffer
* @n: max. number of elements to get
*
* This macro get the data from the fifo and return the numbers of elements
* copied. The data is not removed from the fifo.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macro.
*/
#define kfifo_out_peek(fifo, buf, n) \
__kfifo_uint_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
typeof((buf) + 1) __buf = (buf); \
unsigned long __n = (n); \
const unsigned int __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (0) { \
typeof(__tmp->ptr) __dummy __attribute__ ((unused)) = NULL; \
__buf = __dummy; \
} \
(__recsize) ? \
__kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \
__kfifo_out_peek(__kfifo, __buf, __n); \
}) \
)
#define kfifo_peek_locked(fifo, buf, n) \
__kfifo_uint_must_check_helper( \
({ \
unsigned int __ret; \
uv_mutex_t __lock = ((struct __kfifo*)fifo)->lock; \
uv_mutex_lock(&__lock); \
__ret = kfifo_out_peek(fifo, buf, n); \
uv_mutex_unlock(&__lock); \
__ret; \
}) \
)
extern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, unsigned int esize);
extern void __kfifo_free(struct __kfifo *fifo);
extern int __kfifo_init(struct __kfifo *fifo, void *buffer,
unsigned int size, unsigned int esize);
extern unsigned int __kfifo_in(struct __kfifo *fifo,
const void *buf, unsigned int len);
extern unsigned int __kfifo_out(struct __kfifo *fifo,
void *buf, unsigned int len);
extern unsigned int __kfifo_out_peek(struct __kfifo *fifo,
void *buf, unsigned int len);
extern unsigned int __kfifo_in_r(struct __kfifo *fifo,
const void *buf, unsigned int len, unsigned int recsize);
extern unsigned int __kfifo_out_r(struct __kfifo *fifo,
void *buf, unsigned int len, unsigned int recsize);
extern unsigned int __kfifo_len_r(struct __kfifo *fifo, unsigned int recsize);
extern void __kfifo_skip_r(struct __kfifo *fifo, unsigned int recsize);
extern unsigned int __kfifo_out_peek_r(struct __kfifo *fifo,
void *buf, unsigned int len, unsigned int recsize);
extern unsigned int __kfifo_max_r(unsigned int len, unsigned int recsize);
#endif

31
src/include/hal_mtk.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef HAL_MTK_H
#define HAL_MTK_H
#ifdef __cplusplus
extern "C" {
#endif
#define DeviceKey "98b6e96524e8a4014ef8089e934e9e27"
#define SecuryKey "7ce57cb93ca8"
#define NETEASE_PRODUCT_KEY DeviceKey//"2c53832e7a05e6fcb52081ff3abce92c"
#define NETEASE_PRODUCT_SEC SecuryKey//"8e92003eb2f9"
#define NETEASE_MQTT_SERVER "mqtt-dev.netease.im"
#define NETEASE_MQTT_PORT 8883
#define NETEASE_API_SERVER "https://api-iot-dev.netease.im/RegisterDevice"
#define MQTT_CA_FILE_PATH ("/etc/cacert.crt")
const char* hal_get_device_id(void);
const char* hal_get_device_iot_id(void);
const char* hal_get_device_name(void);
const char* hal_get_device_secret(void);
#ifdef __cplusplus
}
#endif
#endif

14
src/include/http.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef HTTP_H
#define HTTP_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif

273
src/include/log.h Normal file
View File

@ -0,0 +1,273 @@
/** @file log.h
@brief
@details
@version 1.0.0
*/
#ifndef LOG_H_
#define LOG_H_
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __KERNEL__
#include <string.h>
#include <time.h>
#else
#include <linux/string.h>
#endif
#ifndef TRUE
#define TRUE (1)
#endif
#ifndef FALSE
#define FALSE (0)
#endif
#ifndef MAX
/** @def MAX
@brief
*/
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef MIN
/** @def MIN
@brief
*/
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#define TIMEZONE_EAST_8H (8 * 3600)
#ifndef __KERNEL__
#define DUMP_PREFIX_ADDRESS (1)
#define DUMP_PREFIX_OFFSET (2)
#endif
#define DEBUG_SQL_CALLBACK_DATA(argc, argv, azColName) do { \
for(int i = 0; i < argc; i++) { \
fprintf(stdout, "%s = [%s], ", azColName[i], argv[i]); \
} \
fprintf(stdout, "\n"); \
} while(0);
#define print(format, ...) fprintf(stdout, format, __VA_ARGS__)
typedef struct
{
int cfgCmd;
int iParams1;
int iParams2;
} LOG_CFG_PROTOCOL, *PLOG_CFG_PROTOCOL;
typedef enum
{
CMD_LOG_ENABLE = 0,
CMD_LOG_FILE = 1,
CMD_LOG_MAIL = 2,
CMD_LOG_LEVEL = 3,
CMD_LOG_NETWORK = 4,
CMD_LOG_SERVER = 5
} LOG_CFG_CMD;
/** @enum _LOG_LEVEL_
* LOG等级枚举变量
*/
typedef enum
{
LOG_Fatal = (1 << 0),
LOG_Error = (1 << 1),
LOG_Warn = (1 << 2),
LOG_Debug = (1 << 3),
LOG_Info = (1 << 4),
LOG_Test = (1 << 5),
LOG_Call = (1 << 6),
LOG_Devp = (1 << 7),
LOG_Step = (1 << 8),
LOG_Unknown = (1 << 9),
LOG_All = (0xFFFFFFFF),
LOG_Close = 0x0,
} LOG_LEVEL;
/** @var typedef _LOG_LEVEL_ LOG_LEVEL
* @brief
*/
typedef enum {
ERR_OK = 0,
ERR_INPUT_PARAMS,
ERR_NO_ITEMS,
ERR_GET_BUS,
ERR_DBUS_CONNECTION,
ERR_REQUEST_BUS_NAME,
ERR_SET_WATCH_FUNCTION,
ERR_SET_TIMEOUT_FUNCTION,
ERR_BUS_MATCH,
ERR_BUS_SET_MSG_CB,
ERR_DBUS_CREATE_MSG,
ERR_BUS_SEND_MSG,
ERR_DBUS_MSG_TO_LARGE,
ERR_BUS_RCV_MSG,
ERR_ADD_TASK,
ERR_UNSUP_EVP_TYPE,
ERR_CREATE_MQ,
ERR_MQ_SENDMSG,
ERR_CREATE_SHM,
ERR_MAP_SHM,
ERR_MALLOC_MEMORY,
ERR_EVP_INIT_KEY,
ERR_EVP_UPDATE,
ERR_EVP_FINALE,
ERR_EVP_KEY_SIZE,
ERR_OPEN_FILE,
ERR_READ_FILE,
ERR_WRITE_FILE,
ERR_COPY_FILE,
ERR_FILE_NOT_EXISTS,
ERR_GET_FILE_SIZE,
ERR_UNINIT_ITEM,
ERR_FILE_EMPTY,
ERR_SEND_MAIL,
ERR_NETWORK_SEND,
ERR_NETWORK_NOT_CONNECTED,
ERR_CREATE_SOCKET,
ERR_BIND_SOCKET,
ERR_UNSUPPORT,
} SYSTEM_ERROR;
#ifdef DISABLE_LOG
#define LOG_BUF(level, buf, len)
#define LOG_EX(level, format, args...)
#define LOG_EX2(level, format, args...)
#define LOG_TAG_EX(tag, level, format, args...)
#define DEBUG_CODE_LINE()
#define DEBUG_FUNCTION_BEGIN()
#define DEBUG_FUNCTION_END()
#else
#define LOG_BUF(level, buf, len) do { \
const char* pFmtBuf = format_hex_buf("", DUMP_PREFIX_ADDRESS, 16, 1, buf, len, 1); \
IHW_LOG(level, "[%s] - %s(%d): %s[0-%d]:\n%s", basename_v2(__FILE__), __FUNCTION__, __LINE__, \
#buf, len, pFmtBuf); \
free((void*)pFmtBuf); \
} while(0);
/*! \def LOG_EX
\brief
*/
#define LOG_EX(level, format, args...) (IHW_LOG(level, "[%s] - %s(%d):" format , basename_v2(__FILE__), __FUNCTION__, __LINE__, ##args))
/*! \def LOG_TAG_EX
\brief
*/
#define LOG_TAG_EX(tag, level, format, args...) (IHW_LOG(level, "{%s} [%s] %s(%d):" format , tag, basename_v2(__FILE__), __FUNCTION__, __LINE__, ##args))
#define LOG_EX2(level, format, args...) (IHW_LOG_UNTAG(level, format , ##args))
/*! @def APP_BUILD_INFO
@brief
*/
#define APP_BUILD_INFO(appname, appver) (IHW_LOG(LOG_Info, "%s Ver:%s (Build: %s %s GCC Ver:%s) With %d(bits) OS\n", \
appname, appver, __DATE__, __TIME__, __VERSION__, sizeof(int*) * 8))
/*! @def DEBUG_CODE_LINE
@brief
*/
#define DEBUG_CODE_LINE() (LOG_EX(LOG_Info, "\n"))
/*! @def DEBUG_FUNCTION_BEGIN
@brief
*/
#define DEBUG_FUNCTION_BEGIN() (LOG_EX(LOG_Call, "+++++\n"))
/*! @def DEBUG_FUNCTION_END
@brief
*/
#define DEBUG_FUNCTION_END() (LOG_EX(LOG_Call, "-----\n"))
/**
* @brief
* @param level
* @param pMsg
*/
void IHW_LOG(LOG_LEVEL level, const char* pMsg, ...);
void IHW_LOG_UNTAG(LOG_LEVEL level, const char* pMsg, ...);
void IHW_LogStrWithoutPrint(int level, char* pMsg);
void IHW_LogRawString(int level, char* pMsg);
/**
* @brief
* @param level
* @param iEnable 1 0
*/
void IHW_EnableLogLevel(LOG_LEVEL level, int iEnable);
/**
* @brief
* @param pLogTag
* @param pPath
* @param bEnable /
*/
void IHW_InitLOG(const char* pLogTag, const char* pPath, int bEnable);
void IHW_RunLogService(void);
/**
* @brief
* @param pPath -
* @return int 1, 0;
*/
int IHW_IsFileExist(const char* pPath);
void IHW_EnableLogOut(void);
void IHW_DisableLogOut(void);
char* IHW_bin2hex(char *p, const unsigned char *cp, int count);
/* Return the last part of a pathname */
static inline const char* basename_v2(const char* path)
{
const char* tail = strrchr(path, '/');
return tail ? tail + 1 : path;
}
static inline int dirname_v2(const char* path, char* dir)
{
const char* tail = strrchr(path, '/');
if(tail)
{
memcpy(dir, path, tail - path);
dir[tail - path] = 0;
}
else
{
strcpy(dir, "./");
}
return 0;
}
#endif
const char* LogLeveToString(LOG_LEVEL lv);
const char* format_hex_buf(const char* prefix_str, int prefix_type,
int rowsize, int groupsize,
const void* buf, int len, int ascii);
#ifndef __KERNEL__
void print_hex_dump_bytes(const char* prefix_str, int prefix_type,
const void* buf, int len);
#endif
#ifdef __cplusplus
}
#endif
#endif //LOG_H_

14
src/include/mqtt.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef MQTT_H
#define MQTT_H
#ifdef __cplusplus
extern "C" {
#endif
void mqtt_proxy_setup(void);
#ifdef __cplusplus
}
#endif
#endif

93
src/include/protocol.h Normal file
View File

@ -0,0 +1,93 @@
#ifndef PROTOCOL_H
#define PROTOCOL_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum
{
CRYPTO_NONE = 0,
CRYPTO_MD5 = 1,
CRYPTO_AES = 2,
} CRYPTO_TYPE;
typedef enum
{
CRYPTO_ENCODE = 0,
CRYPTO_DECODE = 1
} CRYPTO_OPT;
typedef struct
{
char* IotId;
char* DeviceSecret;
char* ProductKey;
char* DeviceName;
} REGIST_DEV_INFO, *PREGIST_DEV_INFO;
typedef struct
{
REGIST_DEV_INFO data;
char* requestId;
int code;
char* msg;
} REGIST_DEVICE, *PREGIST_DEVICE;
typedef struct
{
char* mcuCmd;
} BYPASS_INFO, *PBYPASS_INFO;
typedef struct
{
int cmdId;
int cryptoType;
int timeStamp;
char* msgContent;
} CLOUND_API, *PCLOUND_API;
typedef struct
{
BYPASS_INFO reported;
} SHADOW_STATE, *PSHADOW_STATE;
typedef struct
{
char* method;
int version;
SHADOW_STATE state;
} SHADOW_UPDATE, *PSHADOW_UPDATE;
typedef enum
{
JE_PROMAIN = 0,
JE_BYPASS,
JE_SHADOWUP,
JE_REGDEVICE,
JE_MAX,
} JSON_ENGINE_TYPE;
typedef const char* (*JSONENCODEPROC)(void* pStruct);
typedef void* (*JSONDECODEPROC)(const char* pJsonStr);
typedef void (*CRYPTOPROC)(void *pStruct, int cryptoType, int enCode);
typedef struct
{
JSON_ENGINE_TYPE typeId;
JSONENCODEPROC jsonEncodeCb;
JSONDECODEPROC jsonDecodeCb;
CRYPTOPROC cryptoCb;
} JSON_ENGINE, *PJSON_ENGINE;
const char* Struct2Json(void* pStruct, JSON_ENGINE_TYPE type, int cryptoType, int* pErr);
void* Json2Struct(const char* pJsonStr, JSON_ENGINE_TYPE type, int cryptoType, int* pErr);
#ifdef __cplusplus
}
#endif
#endif

285
src/include/uthash/cJSON.h Normal file
View File

@ -0,0 +1,285 @@
/*
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef cJSON__h
#define cJSON__h
#ifdef __cplusplus
extern "C"
{
#endif
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
#define __WINDOWS__
#endif
#ifdef __WINDOWS__
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
For *nix builds that support visibility attribute, you can define similar behavior by
setting default visibility to hidden by adding
-fvisibility=hidden (for gcc)
or
-xldscope=hidden (for sun cc)
to CFLAGS
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
*/
#define CJSON_CDECL __cdecl
#define CJSON_STDCALL __stdcall
/* export symbols by default, this is necessary for copy pasting the C and header file */
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_EXPORT_SYMBOLS
#endif
#if defined(CJSON_HIDE_SYMBOLS)
#define CJSON_PUBLIC(type) type CJSON_STDCALL
#elif defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
#elif defined(CJSON_IMPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
#endif
#else /* !__WINDOWS__ */
#define CJSON_CDECL
#define CJSON_STDCALL
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
#else
#define CJSON_PUBLIC(type) type
#endif
#endif
/* project version */
#define CJSON_VERSION_MAJOR 1
#define CJSON_VERSION_MINOR 7
#define CJSON_VERSION_PATCH 10
#include <stddef.h>
/* cJSON Types: */
#define cJSON_Invalid (0)
#define cJSON_False (1 << 0)
#define cJSON_True (1 << 1)
#define cJSON_NULL (1 << 2)
#define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4)
#define cJSON_Array (1 << 5)
#define cJSON_Object (1 << 6)
#define cJSON_Raw (1 << 7) /* raw json */
#define cJSON_IsReference 256
#define cJSON_StringIsConst 512
/* The cJSON structure: */
typedef struct cJSON
{
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *next;
struct cJSON *prev;
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
struct cJSON *child;
/* The type of the item, as above. */
int type;
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
char *valuestring;
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
int valueint;
/* The item's number, if type==cJSON_Number */
double valuedouble;
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
char *string;
} cJSON;
typedef struct cJSON_Hooks
{
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
void *(CJSON_CDECL *malloc_fn)(size_t sz);
void (CJSON_CDECL *free_fn)(void *ptr);
} cJSON_Hooks;
typedef int cJSON_bool;
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
* This is to prevent stack overflows. */
#ifndef CJSON_NESTING_LIMIT
#define CJSON_NESTING_LIMIT 1000
#endif
/* returns the version of cJSON as a string */
CJSON_PUBLIC(const char*) cJSON_Version(void);
/* Supply malloc, realloc and free functions to cJSON */
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
/* Render a cJSON entity to text for transfer/storage. */
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. */
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
/* Delete a cJSON entity and all subentities. */
CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
/* Returns the number of items in an array (or object). */
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
/* Get item "string" from object. Case insensitive. */
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
/* Check if the item is a string and return its valuestring */
CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item);
/* These functions check the type of an item */
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
/* These calls create a cJSON item of the appropriate type. */
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
/* raw json */
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
/* Create a string where valuestring references a string so
* it will not be freed by cJSON_Delete */
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
/* Create an object/arrray that only references it's elements so
* they will not be freed by cJSON_Delete */
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
/* These utilities create an Array of count items. */
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
/* Append item to the specified array/object. */
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
* writing to `item->string` */
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
/* Remove/Detatch items from Arrays/Objects. */
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
/* Update array items. */
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
/* Duplicate a cJSON item */
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
need to be released. With recurse!=0, it will duplicate any children connected to the item.
The item->next and ->prev pointers are always zero on return from Duplicate. */
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
CJSON_PUBLIC(void) cJSON_Minify(char *json);
/* Helper functions for creating and adding items to an object at the same time.
* They return the added item or NULL on failure. */
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
/* helper for the cJSON_SetNumberValue macro */
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
/* Macro for iterating over an array or object */
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
CJSON_PUBLIC(void) cJSON_free(void *object);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,238 @@
/*
Copyright (c) 2008-2018, Troy D. Hanson http://troydhanson.github.com/uthash/
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* a dynamic array implementation using macros
*/
#ifndef UTARRAY_H
#define UTARRAY_H
#define UTARRAY_VERSION 2.1.0
#include <stddef.h> /* size_t */
#include <string.h> /* memset, etc */
#include <stdlib.h> /* exit */
#ifdef __GNUC__
#define UTARRAY_UNUSED __attribute__((__unused__))
#else
#define UTARRAY_UNUSED
#endif
#ifndef oom
#define oom() exit(-1)
#endif
typedef void (ctor_f)(void *dst, const void *src);
typedef void (dtor_f)(void *elt);
typedef void (init_f)(void *elt);
typedef struct {
size_t sz;
init_f *init;
ctor_f *copy;
dtor_f *dtor;
} UT_icd;
typedef struct {
unsigned i,n;/* i: index of next available slot, n: num slots */
UT_icd icd; /* initializer, copy and destructor functions */
char *d; /* n slots of size icd->sz*/
} UT_array;
#define utarray_init(a,_icd) do { \
memset(a,0,sizeof(UT_array)); \
(a)->icd = *(_icd); \
} while(0)
#define utarray_done(a) do { \
if ((a)->n) { \
if ((a)->icd.dtor) { \
unsigned _ut_i; \
for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \
(a)->icd.dtor(utarray_eltptr(a,_ut_i)); \
} \
} \
free((a)->d); \
} \
(a)->n=0; \
} while(0)
#define utarray_new(a,_icd) do { \
(a) = (UT_array*)malloc(sizeof(UT_array)); \
if ((a) == NULL) oom(); \
utarray_init(a,_icd); \
} while(0)
#define utarray_free(a) do { \
utarray_done(a); \
free(a); \
} while(0)
#define utarray_reserve(a,by) do { \
if (((a)->i+(by)) > (a)->n) { \
char *utarray_tmp; \
while (((a)->i+(by)) > (a)->n) { (a)->n = ((a)->n ? (2*(a)->n) : 8); } \
utarray_tmp=(char*)realloc((a)->d, (a)->n*(a)->icd.sz); \
if (utarray_tmp == NULL) oom(); \
(a)->d=utarray_tmp; \
} \
} while(0)
#define utarray_push_back(a,p) do { \
utarray_reserve(a,1); \
if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,(a)->i++), p); } \
else { memcpy(_utarray_eltptr(a,(a)->i++), p, (a)->icd.sz); }; \
} while(0)
#define utarray_pop_back(a) do { \
if ((a)->icd.dtor) { (a)->icd.dtor( _utarray_eltptr(a,--((a)->i))); } \
else { (a)->i--; } \
} while(0)
#define utarray_extend_back(a) do { \
utarray_reserve(a,1); \
if ((a)->icd.init) { (a)->icd.init(_utarray_eltptr(a,(a)->i)); } \
else { memset(_utarray_eltptr(a,(a)->i),0,(a)->icd.sz); } \
(a)->i++; \
} while(0)
#define utarray_len(a) ((a)->i)
#define utarray_eltptr(a,j) (((j) < (a)->i) ? _utarray_eltptr(a,j) : NULL)
#define _utarray_eltptr(a,j) ((a)->d + ((a)->icd.sz * (j)))
#define utarray_insert(a,p,j) do { \
if ((j) > (a)->i) utarray_resize(a,j); \
utarray_reserve(a,1); \
if ((j) < (a)->i) { \
memmove( _utarray_eltptr(a,(j)+1), _utarray_eltptr(a,j), \
((a)->i - (j))*((a)->icd.sz)); \
} \
if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,j), p); } \
else { memcpy(_utarray_eltptr(a,j), p, (a)->icd.sz); }; \
(a)->i++; \
} while(0)
#define utarray_inserta(a,w,j) do { \
if (utarray_len(w) == 0) break; \
if ((j) > (a)->i) utarray_resize(a,j); \
utarray_reserve(a,utarray_len(w)); \
if ((j) < (a)->i) { \
memmove(_utarray_eltptr(a,(j)+utarray_len(w)), \
_utarray_eltptr(a,j), \
((a)->i - (j))*((a)->icd.sz)); \
} \
if ((a)->icd.copy) { \
unsigned _ut_i; \
for(_ut_i=0;_ut_i<(w)->i;_ut_i++) { \
(a)->icd.copy(_utarray_eltptr(a, (j) + _ut_i), _utarray_eltptr(w, _ut_i)); \
} \
} else { \
memcpy(_utarray_eltptr(a,j), _utarray_eltptr(w,0), \
utarray_len(w)*((a)->icd.sz)); \
} \
(a)->i += utarray_len(w); \
} while(0)
#define utarray_resize(dst,num) do { \
unsigned _ut_i; \
if ((dst)->i > (unsigned)(num)) { \
if ((dst)->icd.dtor) { \
for (_ut_i = (num); _ut_i < (dst)->i; ++_ut_i) { \
(dst)->icd.dtor(_utarray_eltptr(dst, _ut_i)); \
} \
} \
} else if ((dst)->i < (unsigned)(num)) { \
utarray_reserve(dst, (num) - (dst)->i); \
if ((dst)->icd.init) { \
for (_ut_i = (dst)->i; _ut_i < (unsigned)(num); ++_ut_i) { \
(dst)->icd.init(_utarray_eltptr(dst, _ut_i)); \
} \
} else { \
memset(_utarray_eltptr(dst, (dst)->i), 0, (dst)->icd.sz*((num) - (dst)->i)); \
} \
} \
(dst)->i = (num); \
} while(0)
#define utarray_concat(dst,src) do { \
utarray_inserta(dst, src, utarray_len(dst)); \
} while(0)
#define utarray_erase(a,pos,len) do { \
if ((a)->icd.dtor) { \
unsigned _ut_i; \
for (_ut_i = 0; _ut_i < (len); _ut_i++) { \
(a)->icd.dtor(utarray_eltptr(a, (pos) + _ut_i)); \
} \
} \
if ((a)->i > ((pos) + (len))) { \
memmove(_utarray_eltptr(a, pos), _utarray_eltptr(a, (pos) + (len)), \
((a)->i - ((pos) + (len))) * (a)->icd.sz); \
} \
(a)->i -= (len); \
} while(0)
#define utarray_renew(a,u) do { \
if (a) utarray_clear(a); \
else utarray_new(a, u); \
} while(0)
#define utarray_clear(a) do { \
if ((a)->i > 0) { \
if ((a)->icd.dtor) { \
unsigned _ut_i; \
for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \
(a)->icd.dtor(_utarray_eltptr(a, _ut_i)); \
} \
} \
(a)->i = 0; \
} \
} while(0)
#define utarray_sort(a,cmp) do { \
qsort((a)->d, (a)->i, (a)->icd.sz, cmp); \
} while(0)
#define utarray_find(a,v,cmp) bsearch((v),(a)->d,(a)->i,(a)->icd.sz,cmp)
#define utarray_front(a) (((a)->i) ? (_utarray_eltptr(a,0)) : NULL)
#define utarray_next(a,e) (((e)==NULL) ? utarray_front(a) : ((((a)->i) > (utarray_eltidx(a,e)+1)) ? _utarray_eltptr(a,utarray_eltidx(a,e)+1) : NULL))
#define utarray_prev(a,e) (((e)==NULL) ? utarray_back(a) : ((utarray_eltidx(a,e) > 0) ? _utarray_eltptr(a,utarray_eltidx(a,e)-1) : NULL))
#define utarray_back(a) (((a)->i) ? (_utarray_eltptr(a,(a)->i-1)) : NULL)
#define utarray_eltidx(a,e) (((char*)(e) >= (a)->d) ? (((char*)(e) - (a)->d)/(a)->icd.sz) : -1)
/* last we pre-define a few icd for common utarrays of ints and strings */
static void utarray_str_cpy(void *dst, const void *src) {
char **_src = (char**)src, **_dst = (char**)dst;
*_dst = (*_src == NULL) ? NULL : strdup(*_src);
}
static void utarray_str_dtor(void *elt) {
char **eltc = (char**)elt;
if (*eltc != NULL) free(*eltc);
}
static const UT_icd ut_str_icd UTARRAY_UNUSED = {sizeof(char*),NULL,utarray_str_cpy,utarray_str_dtor};
static const UT_icd ut_int_icd UTARRAY_UNUSED = {sizeof(int),NULL,NULL,NULL};
static const UT_icd ut_ptr_icd UTARRAY_UNUSED = {sizeof(void*),NULL,NULL,NULL};
#endif /* UTARRAY_H */

1227
src/include/uthash/uthash.h Normal file

File diff suppressed because it is too large Load Diff

1073
src/include/uthash/utlist.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,108 @@
/*
Copyright (c) 2015-2018, Troy D. Hanson http://troydhanson.github.com/uthash/
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* a ring-buffer implementation using macros
*/
#ifndef UTRINGBUFFER_H
#define UTRINGBUFFER_H
#define UTRINGBUFFER_VERSION 2.1.0
#include <stdlib.h>
#include <string.h>
#include "utarray.h" // for "UT_icd"
typedef struct {
unsigned i; /* index of next available slot; wraps at n */
unsigned n; /* capacity */
unsigned char f; /* full */
UT_icd icd; /* initializer, copy and destructor functions */
char *d; /* n slots of size icd->sz */
} UT_ringbuffer;
#define utringbuffer_init(a, _n, _icd) do { \
memset(a, 0, sizeof(UT_ringbuffer)); \
(a)->icd = *(_icd); \
(a)->n = (_n); \
if ((a)->n) { (a)->d = (char*)malloc((a)->n * (_icd)->sz); } \
} while(0)
#define utringbuffer_clear(a) do { \
if ((a)->icd.dtor) { \
if ((a)->f) { \
unsigned _ut_i; \
for (_ut_i = 0; _ut_i < (a)->n; ++_ut_i) { \
(a)->icd.dtor(utringbuffer_eltptr(a, _ut_i)); \
} \
} else { \
unsigned _ut_i; \
for (_ut_i = 0; _ut_i < (a)->i; ++_ut_i) { \
(a)->icd.dtor(utringbuffer_eltptr(a, _ut_i)); \
} \
} \
} \
(a)->i = 0; \
(a)->f = 0; \
} while(0)
#define utringbuffer_done(a) do { \
utringbuffer_clear(a); \
free((a)->d); (a)->d = NULL; \
(a)->n = 0; \
} while(0)
#define utringbuffer_new(a,n,_icd) do { \
a = (UT_ringbuffer*)malloc(sizeof(UT_ringbuffer)); \
utringbuffer_init(a, n, _icd); \
} while(0)
#define utringbuffer_free(a) do { \
utringbuffer_done(a); \
free(a); \
} while(0)
#define utringbuffer_push_back(a,p) do { \
if ((a)->icd.dtor && (a)->f) { (a)->icd.dtor(_utringbuffer_internalptr(a,(a)->i)); } \
if ((a)->icd.copy) { (a)->icd.copy( _utringbuffer_internalptr(a,(a)->i), p); } \
else { memcpy(_utringbuffer_internalptr(a,(a)->i), p, (a)->icd.sz); }; \
if (++(a)->i == (a)->n) { (a)->i = 0; (a)->f = 1; } \
} while(0)
#define utringbuffer_len(a) ((a)->f ? (a)->n : (a)->i)
#define utringbuffer_empty(a) ((a)->i == 0 && !(a)->f)
#define utringbuffer_full(a) ((a)->f != 0)
#define _utringbuffer_real_idx(a,j) ((a)->f ? ((j) + (a)->i) % (a)->n : (j))
#define _utringbuffer_internalptr(a,j) ((void*)((a)->d + ((a)->icd.sz * (j))))
#define utringbuffer_eltptr(a,j) ((0 <= (j) && (j) < utringbuffer_len(a)) ? _utringbuffer_internalptr(a,_utringbuffer_real_idx(a,j)) : NULL)
#define _utringbuffer_fake_idx(a,j) ((a)->f ? ((j) + (a)->n - (a)->i) % (a)->n : (j))
#define _utringbuffer_internalidx(a,e) (((char*)(e) >= (a)->d) ? (((char*)(e) - (a)->d)/(a)->icd.sz) : -1)
#define utringbuffer_eltidx(a,e) _utringbuffer_fake_idx(a, _utringbuffer_internalidx(a,e))
#define utringbuffer_front(a) utringbuffer_eltptr(a,0)
#define utringbuffer_next(a,e) ((e)==NULL ? utringbuffer_front(a) : utringbuffer_eltptr(a, utringbuffer_eltidx(a,e)+1))
#define utringbuffer_prev(a,e) ((e)==NULL ? utringbuffer_back(a) : utringbuffer_eltptr(a, utringbuffer_eltidx(a,e)-1))
#define utringbuffer_back(a) (utringbuffer_empty(a) ? NULL : utringbuffer_eltptr(a, utringbuffer_len(a) - 1))
#endif /* UTRINGBUFFER_H */

View File

@ -0,0 +1,88 @@
/*
Copyright (c) 2018-2018, Troy D. Hanson http://troydhanson.github.com/uthash/
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UTSTACK_H
#define UTSTACK_H
#define UTSTACK_VERSION 2.1.0
/*
* This file contains macros to manipulate a singly-linked list as a stack.
*
* To use utstack, your structure must have a "next" pointer.
*
* ----------------.EXAMPLE -------------------------
* struct item {
* int id;
* struct item *next;
* }
*
* struct item *stack = NULL:
*
* int main() {
* int count;
* struct item *tmp;
* struct item *item = malloc(sizeof *item);
* item->id = 42;
* STACK_COUNT(stack, tmp, count); assert(count == 0);
* STACK_PUSH(stack, item);
* STACK_COUNT(stack, tmp, count); assert(count == 1);
* STACK_POP(stack, item);
* free(item);
* STACK_COUNT(stack, tmp, count); assert(count == 0);
* }
* --------------------------------------------------
*/
#define STACK_TOP(head) (head)
#define STACK_EMPTY(head) (!(head))
#define STACK_PUSH(head,add) \
STACK_PUSH2(head,add,next)
#define STACK_PUSH2(head,add,next) \
do { \
(add)->next = (head); \
(head) = (add); \
} while (0)
#define STACK_POP(head,result) \
STACK_POP2(head,result,next)
#define STACK_POP2(head,result,next) \
do { \
(result) = (head); \
(head) = (head)->next; \
} while (0)
#define STACK_COUNT(head,el,counter) \
STACK_COUNT2(head,el,counter,next) \
#define STACK_COUNT2(head,el,counter,next) \
do { \
(counter) = 0; \
for ((el) = (head); el; (el) = (el)->next) { ++(counter); } \
} while (0)
#endif /* UTSTACK_H */

View File

@ -0,0 +1,398 @@
/*
Copyright (c) 2008-2018, Troy D. Hanson http://troydhanson.github.com/uthash/
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* a dynamic string implementation using macros
*/
#ifndef UTSTRING_H
#define UTSTRING_H
#define UTSTRING_VERSION 2.1.0
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#ifdef __GNUC__
#define UTSTRING_UNUSED __attribute__((__unused__))
#else
#define UTSTRING_UNUSED
#endif
#ifndef oom
#define oom() exit(-1)
#endif
typedef struct {
char *d; /* pointer to allocated buffer */
size_t n; /* allocated capacity */
size_t i; /* index of first unused byte */
} UT_string;
#define utstring_reserve(s,amt) \
do { \
if (((s)->n - (s)->i) < (size_t)(amt)) { \
char *utstring_tmp = (char*)realloc( \
(s)->d, (s)->n + (amt)); \
if (utstring_tmp == NULL) oom(); \
(s)->d = utstring_tmp; \
(s)->n += (amt); \
} \
} while(0)
#define utstring_init(s) \
do { \
(s)->n = 0; (s)->i = 0; (s)->d = NULL; \
utstring_reserve(s,100); \
(s)->d[0] = '\0'; \
} while(0)
#define utstring_done(s) \
do { \
if ((s)->d != NULL) free((s)->d); \
(s)->n = 0; \
} while(0)
#define utstring_free(s) \
do { \
utstring_done(s); \
free(s); \
} while(0)
#define utstring_new(s) \
do { \
(s) = (UT_string*)malloc(sizeof(UT_string)); \
if (!(s)) oom(); \
utstring_init(s); \
} while(0)
#define utstring_renew(s) \
do { \
if (s) { \
utstring_clear(s); \
} else { \
utstring_new(s); \
} \
} while(0)
#define utstring_clear(s) \
do { \
(s)->i = 0; \
(s)->d[0] = '\0'; \
} while(0)
#define utstring_bincpy(s,b,l) \
do { \
utstring_reserve((s),(l)+1); \
if (l) memcpy(&(s)->d[(s)->i], b, l); \
(s)->i += (l); \
(s)->d[(s)->i]='\0'; \
} while(0)
#define utstring_concat(dst,src) \
do { \
utstring_reserve((dst),((src)->i)+1); \
if ((src)->i) memcpy(&(dst)->d[(dst)->i], (src)->d, (src)->i); \
(dst)->i += (src)->i; \
(dst)->d[(dst)->i]='\0'; \
} while(0)
#define utstring_len(s) ((s)->i)
#define utstring_body(s) ((s)->d)
UTSTRING_UNUSED static void utstring_printf_va(UT_string *s, const char *fmt, va_list ap) {
int n;
va_list cp;
for (;;) {
#ifdef _WIN32
cp = ap;
#else
va_copy(cp, ap);
#endif
n = vsnprintf (&s->d[s->i], s->n-s->i, fmt, cp);
va_end(cp);
if ((n > -1) && ((size_t) n < (s->n-s->i))) {
s->i += n;
return;
}
/* Else try again with more space. */
if (n > -1) utstring_reserve(s,n+1); /* exact */
else utstring_reserve(s,(s->n)*2); /* 2x */
}
}
#ifdef __GNUC__
/* support printf format checking (2=the format string, 3=start of varargs) */
static void utstring_printf(UT_string *s, const char *fmt, ...)
__attribute__ (( format( printf, 2, 3) ));
#endif
UTSTRING_UNUSED static void utstring_printf(UT_string *s, const char *fmt, ...) {
va_list ap;
va_start(ap,fmt);
utstring_printf_va(s,fmt,ap);
va_end(ap);
}
/*******************************************************************************
* begin substring search functions *
******************************************************************************/
/* Build KMP table from left to right. */
UTSTRING_UNUSED static void _utstring_BuildTable(
const char *P_Needle,
size_t P_NeedleLen,
long *P_KMP_Table)
{
long i, j;
i = 0;
j = i - 1;
P_KMP_Table[i] = j;
while (i < (long) P_NeedleLen)
{
while ( (j > -1) && (P_Needle[i] != P_Needle[j]) )
{
j = P_KMP_Table[j];
}
i++;
j++;
if (i < (long) P_NeedleLen)
{
if (P_Needle[i] == P_Needle[j])
{
P_KMP_Table[i] = P_KMP_Table[j];
}
else
{
P_KMP_Table[i] = j;
}
}
else
{
P_KMP_Table[i] = j;
}
}
return;
}
/* Build KMP table from right to left. */
UTSTRING_UNUSED static void _utstring_BuildTableR(
const char *P_Needle,
size_t P_NeedleLen,
long *P_KMP_Table)
{
long i, j;
i = P_NeedleLen - 1;
j = i + 1;
P_KMP_Table[i + 1] = j;
while (i >= 0)
{
while ( (j < (long) P_NeedleLen) && (P_Needle[i] != P_Needle[j]) )
{
j = P_KMP_Table[j + 1];
}
i--;
j--;
if (i >= 0)
{
if (P_Needle[i] == P_Needle[j])
{
P_KMP_Table[i + 1] = P_KMP_Table[j + 1];
}
else
{
P_KMP_Table[i + 1] = j;
}
}
else
{
P_KMP_Table[i + 1] = j;
}
}
return;
}
/* Search data from left to right. ( Multiple search mode. ) */
UTSTRING_UNUSED static long _utstring_find(
const char *P_Haystack,
size_t P_HaystackLen,
const char *P_Needle,
size_t P_NeedleLen,
long *P_KMP_Table)
{
long i, j;
long V_FindPosition = -1;
/* Search from left to right. */
i = j = 0;
while ( (j < (int)P_HaystackLen) && (((P_HaystackLen - j) + i) >= P_NeedleLen) )
{
while ( (i > -1) && (P_Needle[i] != P_Haystack[j]) )
{
i = P_KMP_Table[i];
}
i++;
j++;
if (i >= (int)P_NeedleLen)
{
/* Found. */
V_FindPosition = j - i;
break;
}
}
return V_FindPosition;
}
/* Search data from right to left. ( Multiple search mode. ) */
UTSTRING_UNUSED static long _utstring_findR(
const char *P_Haystack,
size_t P_HaystackLen,
const char *P_Needle,
size_t P_NeedleLen,
long *P_KMP_Table)
{
long i, j;
long V_FindPosition = -1;
/* Search from right to left. */
j = (P_HaystackLen - 1);
i = (P_NeedleLen - 1);
while ( (j >= 0) && (j >= i) )
{
while ( (i < (int)P_NeedleLen) && (P_Needle[i] != P_Haystack[j]) )
{
i = P_KMP_Table[i + 1];
}
i--;
j--;
if (i < 0)
{
/* Found. */
V_FindPosition = j + 1;
break;
}
}
return V_FindPosition;
}
/* Search data from left to right. ( One time search mode. ) */
UTSTRING_UNUSED static long utstring_find(
UT_string *s,
long P_StartPosition, /* Start from 0. -1 means last position. */
const char *P_Needle,
size_t P_NeedleLen)
{
long V_StartPosition;
long V_HaystackLen;
long *V_KMP_Table;
long V_FindPosition = -1;
if (P_StartPosition < 0)
{
V_StartPosition = s->i + P_StartPosition;
}
else
{
V_StartPosition = P_StartPosition;
}
V_HaystackLen = s->i - V_StartPosition;
if ( (V_HaystackLen >= (long) P_NeedleLen) && (P_NeedleLen > 0) )
{
V_KMP_Table = (long *)malloc(sizeof(long) * (P_NeedleLen + 1));
if (V_KMP_Table != NULL)
{
_utstring_BuildTable(P_Needle, P_NeedleLen, V_KMP_Table);
V_FindPosition = _utstring_find(s->d + V_StartPosition,
V_HaystackLen,
P_Needle,
P_NeedleLen,
V_KMP_Table);
if (V_FindPosition >= 0)
{
V_FindPosition += V_StartPosition;
}
free(V_KMP_Table);
}
}
return V_FindPosition;
}
/* Search data from right to left. ( One time search mode. ) */
UTSTRING_UNUSED static long utstring_findR(
UT_string *s,
long P_StartPosition, /* Start from 0. -1 means last position. */
const char *P_Needle,
size_t P_NeedleLen)
{
long V_StartPosition;
long V_HaystackLen;
long *V_KMP_Table;
long V_FindPosition = -1;
if (P_StartPosition < 0)
{
V_StartPosition = s->i + P_StartPosition;
}
else
{
V_StartPosition = P_StartPosition;
}
V_HaystackLen = V_StartPosition + 1;
if ( (V_HaystackLen >= (long) P_NeedleLen) && (P_NeedleLen > 0) )
{
V_KMP_Table = (long *)malloc(sizeof(long) * (P_NeedleLen + 1));
if (V_KMP_Table != NULL)
{
_utstring_BuildTableR(P_Needle, P_NeedleLen, V_KMP_Table);
V_FindPosition = _utstring_findR(s->d,
V_HaystackLen,
P_Needle,
P_NeedleLen,
V_KMP_Table);
free(V_KMP_Table);
}
}
return V_FindPosition;
}
/*******************************************************************************
* end substring search functions *
******************************************************************************/
#endif /* UTSTRING_H */

326
src/log/hexdump.c Normal file
View File

@ -0,0 +1,326 @@
#ifndef __KERNEL__
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <uthash/utstring.h>
#include "log.h"
static const char hex_asc[] = "0123456789abcdef";
#define hex_asc_lo(x) hex_asc[((x) & 0x0f)]
#define hex_asc_hi(x) hex_asc[((x) & 0xf0) >> 4]
char* IHW_bin2hex(char *p, const unsigned char *cp, int count)
{
while (count) {
unsigned char c = *cp++;
/* put lowercase hex digits */
*p++ = 0x20 | hex_asc[c >> 4];
*p++ = 0x20 | hex_asc[c & 0xf];
count--;
}
return p;
}
/**
* hex_to_bin - convert a hex digit to its real value
* @ch: ascii character represents hex digit
*
* hex_to_bin() converts one hex digit to its actual value or -1 in case of bad
* input.
*/
int hex_to_bin(char ch)
{
if((ch >= '0') && (ch <= '9'))
{
return ch - '0';
}
ch = tolower(ch);
if((ch >= 'a') && (ch <= 'f'))
{
return ch - 'a' + 10;
}
return -1;
}
/**
* hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
* @buf: data blob to dump
* @len: number of bytes in the @buf
* @rowsize: number of bytes to print per line; must be 16 or 32
* @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
* @linebuf: where to put the converted data
* @linebuflen: total size of @linebuf, including space for terminating NUL
* @ascii: include ASCII after the hex output
*
* hex_dump_to_buffer() works on one "line" of output at a time, i.e.,
* 16 or 32 bytes of input data converted to hex + ASCII output.
*
* Given a buffer of u8 data, hex_dump_to_buffer() converts the input data
* to a hex + ASCII dump at the supplied memory location.
* The converted output is always NUL-terminated.
*
* E.g.:
* hex_dump_to_buffer(frame->data, frame->len, 16, 1,
* linebuf, sizeof(linebuf), true);
*
* example output buffer:
* 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO
*/
void hex_dump_to_buffer(const void* buf, int len, int rowsize,
int groupsize, char* linebuf, size_t linebuflen,
int ascii)
{
const unsigned char* ptr = (const unsigned char *)buf;
unsigned char ch;
int j, lx = 0;
int ascii_column;
if(rowsize != 16 && rowsize != 32)
{
rowsize = 16;
}
if(!len)
{
goto nil;
}
if(len > rowsize) /* limit to one line at a time */
{
len = rowsize;
}
if((len % groupsize) != 0) /* no mixed size output */
{
groupsize = 1;
}
switch(groupsize)
{
case 8:
{
const unsigned long long* ptr8 = (const unsigned long long *)buf;
int ngroups = len / groupsize;
for(j = 0; j < ngroups; j++)
lx += snprintf(linebuf + lx, linebuflen - lx,
"%s%16.16llx", j ? " " : "",
(unsigned long long) * (ptr8 + j));
ascii_column = 17 * ngroups + 2;
break;
}
case 4:
{
const unsigned int* ptr4 = (const unsigned int *)buf;
int ngroups = len / groupsize;
for(j = 0; j < ngroups; j++)
lx += snprintf(linebuf + lx, linebuflen - lx,
"%s%8.8x", j ? " " : "", *(ptr4 + j));
ascii_column = 9 * ngroups + 2;
break;
}
case 2:
{
const unsigned short* ptr2 = (const unsigned short *)buf;
int ngroups = len / groupsize;
for(j = 0; j < ngroups; j++)
lx += snprintf(linebuf + lx, linebuflen - lx,
"%s%4.4x", j ? " " : "", *(ptr2 + j));
ascii_column = 5 * ngroups + 2;
break;
}
default:
for(j = 0; (j < len) && (lx + 3) <= linebuflen; j++)
{
ch = ptr[j];
linebuf[lx++] = hex_asc_hi(ch);
linebuf[lx++] = hex_asc_lo(ch);
linebuf[lx++] = ' ';
}
if(j)
{
lx--;
}
ascii_column = 3 * rowsize + 2;
break;
}
if(!ascii)
{
goto nil;
}
while(lx < (linebuflen - 1) && lx < (ascii_column - 1))
{
linebuf[lx++] = ' ';
}
for(j = 0; (j < len) && (lx + 2) < linebuflen; j++)
{
ch = ptr[j];
linebuf[lx++] = (isascii(ch) && isprint(ch)) ? ch : '.';
}
nil:
linebuf[lx++] = '\0';
}
/**
* print_hex_dump - print a text hex dump to syslog for a binary blob of data
* @level: kernel log level (e.g. KERN_DEBUG)
* @prefix_str: string to prefix each line with;
* caller supplies trailing spaces for alignment if desired
* @prefix_type: controls whether prefix of an offset, address, or none
* is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE)
* @rowsize: number of bytes to print per line; must be 16 or 32
* @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
* @buf: data blob to dump
* @len: number of bytes in the @buf
* @ascii: include ASCII after the hex output
*
* Given a buffer of u8 data, print_hex_dump() prints a hex + ASCII dump
* to the kernel log at the specified kernel log level, with an optional
* leading prefix.
*
* print_hex_dump() works on one "line" of output at a time, i.e.,
* 16 or 32 bytes of input data converted to hex + ASCII output.
* print_hex_dump() iterates over the entire input @buf, breaking it into
* "line size" chunks to format and print.
*
* E.g.:
* print_hex_dump(KERN_DEBUG, "raw data: ", DUMP_PREFIX_ADDRESS,
* 16, 1, frame->data, frame->len, true);
*
* Example output using %DUMP_PREFIX_OFFSET and 1-byte mode:
* 0009ab42: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO
* Example output using %DUMP_PREFIX_ADDRESS and 4-byte mode:
* ffffffff88089af0: 73727170 77767574 7b7a7978 7f7e7d7c pqrstuvwxyz{|}~.
*/
void print_hex_dump(const char* prefix_str, int prefix_type,
int rowsize, int groupsize,
const void* buf, int len, int ascii)
{
const unsigned char* ptr = (const unsigned char *)buf;
int i, remaining = len;
unsigned char linebuf[32 * 3 + 2 + 32 + 1];
if(rowsize != 16 && rowsize != 32)
{
rowsize = 16;
}
for(i = 0; i < len; i += rowsize)
{
int linelen = MIN(remaining, rowsize);
remaining -= rowsize;
hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize,
(char *)linebuf, sizeof(linebuf), ascii);
switch(prefix_type)
{
case DUMP_PREFIX_ADDRESS:
print("%s%p: %s\n",
prefix_str, ptr + i, linebuf);
break;
case DUMP_PREFIX_OFFSET:
print("%s%.8x: %s\n", prefix_str, i, linebuf);
break;
default:
print("%s%.8x: %s\n", prefix_str, i, linebuf);
break;
}
}
print("%s", "\n");
}
/**
* print_hex_dump_bytes - shorthand form of print_hex_dump() with default params
* @prefix_str: string to prefix each line with;
* caller supplies trailing spaces for alignment if desired
* @prefix_type: controls whether prefix of an offset, address, or none
* is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE)
* @buf: data blob to dump
* @len: number of bytes in the @buf
*
* Calls print_hex_dump(), with log level of KERN_DEBUG,
* rowsize of 16, groupsize of 1, and ASCII output included.
*/
void print_hex_dump_bytes(const char* prefix_str, int prefix_type,
const void* buf, int len)
{
print_hex_dump(prefix_str, prefix_type, 16, 1,
buf, len, 1);
}
const char* format_hex_buf(const char* prefix_str, int prefix_type,
int rowsize, int groupsize,
const void* buf, int len, int ascii)
{
UT_string* pLogStr = NULL;
const char* pFormatStr;
const unsigned char* ptr = (const unsigned char *)buf;
int i, remaining = len;
unsigned char linebuf[32 * 3 + 2 + 32 + 1];
if(rowsize != 16 && rowsize != 32)
{
rowsize = 16;
}
utstring_new(pLogStr);
for(i = 0; i < len; i += rowsize)
{
int linelen = MIN(remaining, rowsize);
remaining -= rowsize;
hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize,
(char *)linebuf, sizeof(linebuf), ascii);
switch(prefix_type)
{
case DUMP_PREFIX_ADDRESS:
utstring_printf(pLogStr, "%s%p: %s\n",
prefix_str, ptr + i, linebuf);
break;
case DUMP_PREFIX_OFFSET:
utstring_printf(pLogStr, "%s%.8x: %s\n",
prefix_str, i, linebuf);
break;
default:
utstring_printf(pLogStr, "%s%.8x: %s\n",
prefix_str, i, linebuf);
break;
}
}
pFormatStr = strdup(utstring_body(pLogStr));
utstring_free(pLogStr);
return pFormatStr;
}
#endif

514
src/log/log.c Normal file
View File

@ -0,0 +1,514 @@
/** @file log.c
@brief
@version 1.0.0
*/
#include <sys/time.h>
#include <fcntl.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <uthash/utlist.h>
#include <uthash/utstring.h>
#include <uthash/utringbuffer.h>
#include "log.h"
#ifndef MAX_PATH
#define MAX_PATH (256)
#endif
#define SHOW_CONSOLE_RED ("\033[31;48m\033[1m%s\033[0m%c")
#define SHOW_CONSOLE_YELLOW ("\033[33;48m\033[1m%s\033[0m%c")
#define SHOW_CONSOLE_GREEN ("\033[32;48m\033[1m%s\033[0m%c")
#define SHOW_CONSOLE_BLUE ("\033[34;48m\033[1m%s\033[0m%c")
#ifdef PLATFORM_CPU
#define LOG_FILE_BASEDIR (".")
#else
#define LOG_FILE_BASEDIR ("/tmp")
#endif
#define MAX_LOG_ITEM (1000)
#define MAX_LOG_FILE_SIZE (1024 * 1024)
#define LOG_PRE_SIZE (512)
#define GET_FILE_SIZE(path, size) \
do { \
struct stat st; \
memset(&st, 0, sizeof(struct stat)); \
if (stat(path, &st) != 0) { \
size = -1; \
} else { \
size = st.st_size; \
} \
} while (0)
typedef struct LOG_ITEM
{
LOG_LEVEL level;
int isPrinted;
int isAddTags;
struct timeval timestamp;
char *pLogContent;
struct LOG_ITEM *next, *prev;
}*PLOG_ITEM;
typedef struct LOG_BACKUP
{
time_t timestamp;
char *plogFilePath;
char *pGzFilePath;
unsigned int sendTimes;
unsigned int tolLogs;
struct LOG_BACKUP *next, *prev;
} *PLOG_BACKUP;
typedef struct
{
pid_t pid;
char* pChipId;
char* pChipSerial;
char exeName[MAX_PATH];
char logFilePath[MAX_PATH];
FILE *pLogFile;
} LOG_PROCESS_INFO, *PLOG_PROCESS_INFO;
static int g_bEnableLog = FALSE; // 是否启用 Log 功能
static int g_bEnLogToFile = TRUE;
static int g_bEnLogToServer = TRUE;
static char g_strLogTag[32]; // Log 标志
static unsigned int g_LogRdPos = 0;
static pthread_t g_logThreadId;
static pthread_t g_backupThreadId;
static LOG_PROCESS_INFO g_LogProcessInfo;
static pthread_mutex_t g_uvLogLock;
static PLOG_ITEM g_pLogItemList = NULL;
static PLOG_BACKUP g_pLogBackupList = NULL;
static int g_logSock = -1;
static int g_iMinLevel = LOG_Fatal | LOG_Error | LOG_Warn | LOG_Debug | LOG_Info | LOG_Step;
/**
* @brief Log
* @param level
* @return
*/
const char* LogLevelToStr(LOG_LEVEL level)
{
switch(level)
{
case LOG_Test:
return "T";
case LOG_Info:
return "I";
case LOG_Call:
return "C";
case LOG_Debug:
return "D";
case LOG_Warn:
return "W";
case LOG_Error:
return "E";
case LOG_Fatal:
return "F";
case LOG_Step:
return "S";
case LOG_Devp:
return "V";
case LOG_Unknown:
return "U";
case LOG_All:
return "A";
default:
return "?";
}
return "U";
}
#pragma pack (push)
#pragma pack (1)
typedef struct
{
unsigned short logSeq;
unsigned int pid;
unsigned int timeStamp;
unsigned int nanotime;
unsigned int logLevel;
char logContent[0];
} LOG_PROTO_CONTENT, *PLOG_PROTO_CONTENT;
#pragma pack (pop)
static void __logColorOutput(const char* pColFmt, UT_string* pLog)
{
if(pLog == NULL)
{
return;
}
if(pColFmt == NULL)
{
print("%s", utstring_body(pLog));
}
else
{
if(utstring_find(pLog, -1, "\n", 1) == utstring_len(pLog) - 1)
{
char* pLogArray = utstring_body(pLog);
pLogArray[utstring_len(pLog) - 1] = 0;
print(pColFmt, pLogArray, '\n');
strcat(pLogArray, "\n");
}
else
{
print(pColFmt, utstring_body(pLog), '\0');
}
}
}
static void* __logOutputThread(void *p)
{
while(TRUE)
{
int isWriteLog = FALSE;
PLOG_ITEM pItem = NULL, pTmp = NULL;
pthread_mutex_lock(&g_uvLogLock);
LL_FOREACH_SAFE(g_pLogItemList, pItem, pTmp)
{
UT_string *pLogStr;
struct tm lTime;
int logFileSize = 0;
if(++g_LogRdPos % 100 == 0)
{
GET_FILE_SIZE(g_LogProcessInfo.logFilePath, logFileSize);
}
localtime_r(&(pItem->timestamp.tv_sec), &lTime);
utstring_new(pLogStr);
if(pItem->isAddTags)
{
utstring_printf(pLogStr, "[%04d-%02d-%02d %02d:%02d:%02d.%03ld] [%s] %s",
lTime.tm_year + 1900, lTime.tm_mon + 1, lTime.tm_mday,
lTime.tm_hour, lTime.tm_min, lTime.tm_sec, pItem->timestamp.tv_usec / 1000,
LogLevelToStr(pItem->level), pItem->pLogContent);
}
else
{
utstring_printf(pLogStr, "%s", pItem->pLogContent);
}
if(pItem->isPrinted == FALSE)
{
if(pItem->level & LOG_Error
|| pItem->level & LOG_Fatal)
{
__logColorOutput(SHOW_CONSOLE_RED, pLogStr);
}
else if(pItem->level & LOG_Warn
|| pItem->level & LOG_Unknown)
{
__logColorOutput(SHOW_CONSOLE_YELLOW, pLogStr);
}
else if(pItem->level & LOG_Test
|| pItem->level & LOG_Call)
{
__logColorOutput(SHOW_CONSOLE_BLUE, pLogStr);
}
else if(pItem->level & LOG_Devp)
{
__logColorOutput(SHOW_CONSOLE_GREEN, pLogStr);
}
else
{
print("%s", utstring_body(pLogStr));
}
pItem->isPrinted = TRUE;
}
#if 0
if(g_logSock != -1 && GetCurrWIFIConnStatus() == WIFI_CONNECTED)
{
__logNetworkSend(pItem);
}
#endif
if(g_LogProcessInfo.pLogFile != NULL && g_bEnLogToFile)
{
if(logFileSize >= MAX_LOG_FILE_SIZE)
{
fflush(g_LogProcessInfo.pLogFile);
fclose(g_LogProcessInfo.pLogFile);
g_LogProcessInfo.pLogFile = fopen(g_LogProcessInfo.logFilePath, "w+");
}
if(g_LogProcessInfo.pLogFile)
{
fwrite(utstring_body(pLogStr), 1, utstring_len(pLogStr), g_LogProcessInfo.pLogFile);
}
isWriteLog = TRUE;
}
LL_DELETE(g_pLogItemList, pItem);
utstring_free(pLogStr);
free(pItem->pLogContent);
free(pItem);
if(g_LogRdPos % 100 == 0)
{
break;
}
}
pthread_mutex_unlock(&g_uvLogLock);
usleep(1000);
if(g_LogProcessInfo.pLogFile != NULL && isWriteLog)
{
fflush(g_LogProcessInfo.pLogFile);
}
}
pthread_detach(pthread_self());
return (NULL);
}
/**
* @brief
* @param level
* @param iEnable 1 0
*/
void IHW_EnableLogLevel(LOG_LEVEL level, int iEnable)
{
if(iEnable > 0)
{
g_iMinLevel |= level;
}
else
{
g_iMinLevel &= ~(level);
}
}
/**
* @brief
* @param pLogTag
* @param pPath
* @param bEnable /
*/
void IHW_InitLOG(const char* pLogTag, const char* pPath, int bEnable)
{
int ret;
char strPath[MAX_PATH];
g_LogRdPos = 0;
memset(g_strLogTag, 0, 32);
memset(&g_LogProcessInfo, 0, sizeof(LOG_PROCESS_INFO));
if(pLogTag == NULL)
{
strcpy(g_strLogTag, "");
}
else
{
strncpy(g_strLogTag, pLogTag, 31);
}
memset(strPath, 0, MAX_PATH);
g_LogProcessInfo.pid = getpid();
if(readlink("/proc/self/exe", strPath, MAX_PATH) == -1)
{
strcpy(g_LogProcessInfo.exeName, pLogTag);
}
else
{
char *pExeName = strrchr(strPath, '/');
if(pExeName == NULL)
{
strncpy(g_LogProcessInfo.exeName, strPath, MAX_PATH - 1);
}
else
{
strncpy(g_LogProcessInfo.exeName, pExeName + 1, MAX_PATH - 1);
}
}
//fprintf(stdout, "pid = %d, name = %s\n", g_LogProcessInfo.pid, g_LogProcessInfo.exeName);
g_LogProcessInfo.pChipId = "";
g_LogProcessInfo.pChipSerial = "";
memset(g_LogProcessInfo.logFilePath, 0, MAX_PATH);
sprintf(g_LogProcessInfo.logFilePath, "%s/%s_%d.log", LOG_FILE_BASEDIR, g_LogProcessInfo.exeName, g_LogProcessInfo.pid);
memset(strPath, 0, MAX_PATH);
sprintf(strPath, "rm -f %s/%s_*.log > /dev/zero", LOG_FILE_BASEDIR, g_LogProcessInfo.exeName);
ret = system(strPath);
g_LogProcessInfo.pLogFile = fopen(g_LogProcessInfo.logFilePath, "w+");
g_bEnableLog = bEnable;
// __getCfgFromCfgFile();
}
void IHW_RunLogService(void)
{
pthread_create(&g_logThreadId, NULL, __logOutputThread, NULL);
}
static void __logTo(LOG_LEVEL level, int isAddTag, char* pMsg, int isPrint)
{
PLOG_ITEM pLogItem;
pLogItem = (PLOG_ITEM)malloc(sizeof(struct LOG_ITEM));
if(pLogItem == NULL)
{
return;
}
pLogItem->pLogContent = strdup(pMsg);
pLogItem->isPrinted = isPrint ? FALSE : TRUE;
pLogItem->level = level;
pLogItem->isAddTags = isAddTag ? TRUE : FALSE;
gettimeofday(&(pLogItem->timestamp), NULL);
pthread_mutex_lock(&g_uvLogLock);
LL_APPEND(g_pLogItemList, pLogItem);
pthread_mutex_unlock(&g_uvLogLock);
}
void IHW_LogStrWithoutPrint(int level, char* pMsg)
{
__logTo(level, TRUE, pMsg, FALSE);
}
void IHW_LogRawString(int level, char* pMsg)
{
__logTo(level, TRUE, pMsg, TRUE);
}
/**
* @brief
* @param cFlag
* @param pMsg
*/
void IHW_LOG_UNTAG(LOG_LEVEL level, const char* pMsg, ...)
{
va_list arg_ptr;
UT_string *pLogContent;
if(!g_bEnableLog)
{
return;
}
// 检查调试等级
if(!(g_iMinLevel & level))
{
return;
}
utstring_new(pLogContent);
va_start(arg_ptr, pMsg);
utstring_printf_va(pLogContent, pMsg, arg_ptr);
va_end(arg_ptr);
__logTo(level, FALSE, utstring_body(pLogContent), TRUE);
utstring_free(pLogContent);
}
/**
* @brief
* @param cFlag
* @param pMsg
*/
void IHW_LOG(LOG_LEVEL level, const char* pMsg, ...)
{
UT_string* pLogContent = NULL;
va_list arg_ptr;
if(!g_bEnableLog)
{
return;
}
// 检查调试等级
if(!(g_iMinLevel & level))
{
return;
}
utstring_new(pLogContent);
va_start(arg_ptr, pMsg);
utstring_printf_va(pLogContent, pMsg, arg_ptr);
va_end(arg_ptr);
__logTo(level, TRUE, utstring_body(pLogContent), TRUE);
utstring_free(pLogContent);
}
void IHW_DisableLogOut(void)
{
g_bEnableLog = FALSE;
}
void IHW_EnableLogOut(void)
{
g_bEnableLog = TRUE;
}
const char* LogLeveToString(LOG_LEVEL lv)
{
switch(lv)
{
case LOG_Fatal: return "LOG_Fatal";
case LOG_Error: return "LOG_Error";
case LOG_Warn: return "LOG_Warn";
case LOG_Debug: return "LOG_Debug";
case LOG_Info: return "LOG_Info";
case LOG_Test: return "LOG_Test";
case LOG_Call: return "LOG_Call";
case LOG_Devp: return "LOG_Devp";
case LOG_Step: return "LOG_Step";
case LOG_Unknown: return "LOG_Unknown";
case LOG_All: return "LOG_All";
case LOG_Close: return "LOG_Close";
}
return "Unknown";
}

90
src/main.c Normal file
View File

@ -0,0 +1,90 @@
/*
***************************************************************************
* Ralink Tech Inc.
* 4F, No. 2 Technology 5th Rd.
* Science-based Industrial Park
* Hsin-chu, Taiwan, R.O.C.
*
* (c) Copyright, Ralink Technology, Inc.
*
* All rights reserved. Ralink's source code is an unpublished work and the
* use of a copyright notice does not imply otherwise. This source code
* contains confidential trade secret material of Ralink Tech. Any attemp
* or participation in deciphering, decoding, reverse engineering or in any
* way altering the source code is stricitly prohibited, unless the prior
* written consent of Ralink Technology, Inc. is obtained.
***************************************************************************
*
* $Id: //WIFI_SOC/MP/SDK_4_3_0_0/RT288x_SDK/source/user/rt2880_app/gpio/gpio.c#1 $
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <curl/curl.h>
#include <sys/socket.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include <mosquitto.h>
#include "uthash/utstring.h"
#include "mqtt.h"
#include "http.h"
#include "log.h"
#if 1
int evp_sha1(void)
{
unsigned char result[SHA512_DIGEST_LENGTH];
const char* pSrc = "8e92003eb2f95wYFsgJd002aO2123456";
memset(result, 0, SHA512_DIGEST_LENGTH);
size_t len = strlen(pSrc);
EVP_MD_CTX evpCtx;
EVP_MD_CTX_init(&evpCtx);
EVP_DigestInit_ex(&evpCtx, EVP_sha1(), NULL);
EVP_DigestUpdate(&evpCtx, pSrc, len);
EVP_DigestFinal_ex(&evpCtx, result, &len);
EVP_MD_CTX_cleanup(&evpCtx);
print_hex_dump_bytes("SHA1", DUMP_PREFIX_OFFSET, result, SHA512_DIGEST_LENGTH);
}
#endif
int main(int argc, char* argv[])
{
int rc;
int major, minor, rev;
struct mosquitto *pMosq = NULL;
IHW_InitLOG("MQTT", NULL, TRUE);
IHW_EnableLogLevel(LOG_Fatal | LOG_Error | LOG_Warn | LOG_Debug | LOG_Info, 1);
IHW_RunLogService();
APP_BUILD_INFO("MQTT_Proxy", CURRENT_VERSION);
curl_global_init(CURL_GLOBAL_ALL);
mosquitto_lib_init();
//evp_sha1();
//curl_init();
//device_register();
//mqtt_init();
mqtt_proxy_setup();
while(TRUE)
{
usleep(1000);
}
mosquitto_lib_cleanup();
return 0;
}