guowenxue
2019-06-26 6a924a29cefbea27a101790343137db819b361be
update mqttd to add configure file parser support
2 files modified
6 files added
336 ■■■■ changed files
mqttd/etc/conf.c 144 ●●●●● patch | view | raw | blame | history
mqttd/etc/conf.h 66 ●●●●● patch | view | raw | blame | history
mqttd/etc/conf.o patch | view | raw | blame | history
mqttd/etc/libetc.a patch | view | raw | blame | history
mqttd/etc/makefile 17 ●●●●● patch | view | raw | blame | history
mqttd/etc/mqttd.conf 48 ●●●●● patch | view | raw | blame | history
mqttd/main.c 56 ●●●● patch | view | raw | blame | history
mqttd/makefile 5 ●●●●● patch | view | raw | blame | history
mqttd/etc/conf.c
New file
@@ -0,0 +1,144 @@
/*********************************************************************************
 *      Copyright:  (C) 2019 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  conf.c
 *    Description:  This file is mqttd configure file parser function
 *
 *        Version:  1.0.0(2019年06月25日)
 *         Author:  Guo Wenxue <guowenxue@gmail.com>
 *      ChangeLog:  1, Release initial version on "2019年06月25日 22时23分55秒"
 *
 ********************************************************************************/
#include "conf.h"
#include "lylib/logger.h"
#include "lylib/iniparser.h"
int mqttd_parser_conf(const char *conf_file, mqtt_ctx_t *ctx, int debug)
{
    dictionary          *ini;
    char                *str;
    int                  val;
    memset(ctx, 0, sizeof(*ctx));
    if( !conf_file )
    {
        fprintf(stderr, "\nWARNNING: Use default MQTT configure\n");
        /* logger settings */
        strncpy(ctx->logfile, DBG_LOG_FILE, sizeof(ctx->logfile));
        ctx->loglevel = LOG_LEVEL_DEBUG;
        ctx->logsize = 1024;
        /* Broker settings */
        strncpy(ctx->host, DEF_BORKER_HOSTNAME, sizeof(ctx->host));
        ctx->port = DEF_BROKER_PORT;
        strncpy(ctx->uid, DEF_BROKER_USERNAME, sizeof(ctx->uid));
        strncpy(ctx->pwd, DEF_BROKER_PASSWD, sizeof(ctx->pwd));
        ctx->keepalive = DEF_BROKER_KEEPALIVE;
        /* Publisher settings */
        strncpy(ctx->pubTopic, DEF_PUBTOPIC, sizeof(ctx->pubTopic));
        ctx->pubQos = DEF_PUBQOS;
        ctx->interval = DEF_PUBINTERVAL;
        /* Subscriber settings */
        strncpy(ctx->subTopic, DEF_SUBTOPIC, sizeof(ctx->subTopic));
        ctx->subQos = DEF_SUBQOS;
        return 0;
    }
    ini = iniparser_load(conf_file);
    if( !ini )
    {
        fprintf(stderr, "ERROR: cannot parse file: '%s'\n", conf_file);
        return -1;
    }
    /*+------------------------------------------------------+
     *|    parser logger settings and start logger system    |
     *+------------------------------------------------------+*/
    if( !debug )
    {
        str = iniparser_getstring(ini, "logger:file", "/tmp/mqttd.log");
        strncpy(ctx->logfile, str, sizeof(ctx->logfile));
        ctx->logsize = iniparser_getint(ini, "logger:size", 1024);
        ctx->loglevel = iniparser_getint(ini, "logger:level", LOG_LEVEL_DEBUG);
    }
    else
    {
        strncpy(ctx->logfile, DBG_LOG_FILE, sizeof(ctx->logfile));
        ctx->loglevel = LOG_LEVEL_DEBUG;
        ctx->logsize = 1024;
    }
    if( logger_init(ctx->logfile, ctx->loglevel, ctx->logsize) < 0 )
    {
        fprintf(stderr, "Logger system initialise failure\n");
        return -2;
    }
    log_nrml("Logger system initialise ok\n");
    /*+------------------------------------------------------+
     *|              parser broker settings                  |
     *+------------------------------------------------------+*/
    if( !(str=iniparser_getstring(ini, "broker:hostname", NULL)) )
    {
        log_err("ERROR: Parser broker server hostname failure\n");
        return -2;
    }
    strncpy(ctx->host, str, sizeof(ctx->host) );
    if( (val=iniparser_getint(ini, "broker:port", -1)) < 0 )
    {
        log_err("ERROR: Parser broker server port failure\n");
        return -2;
    }
    ctx->port = val;
    log_nrml("Parser and get broker server [%s:%d]\n", ctx->host, ctx->port);
    str=iniparser_getstring(ini, "broker:username", DEF_BROKER_USERNAME);
    strncpy(ctx->uid, str, sizeof(ctx->uid) );
    str=iniparser_getstring(ini, "broker:password", DEF_BROKER_PASSWD);
    strncpy(ctx->pwd, str, sizeof(ctx->pwd) );
    log_nrml("Parser and get broker author by [%s:%s]\n", ctx->uid, ctx->pwd);
    ctx->keepalive = iniparser_getint(ini, "broker:keepalive", DEF_BROKER_KEEPALIVE);
    log_nrml("Parser and get broker keepalive timeout [%d] seconds\n", ctx->keepalive);
    /*+------------------------------------------------------+
     *|             parser publisher settings                |
     *+------------------------------------------------------+*/
    str=iniparser_getstring(ini, "publisher:pubTopic", DEF_PUBTOPIC);
    strncpy(ctx->pubTopic, str, sizeof(ctx->pubTopic) );
    log_nrml("Parser and get publisher topic \"%s\"\n", ctx->pubTopic);
    ctx->pubQos = iniparser_getint(ini, "publisher:pubQos", DEF_PUBQOS);
    ctx->interval = iniparser_getint(ini, "publisher:interval", DEF_PUBINTERVAL);
    log_nrml("Parser and get publisher Qos[%d] and interval [%d] seconds\n", ctx->pubQos, ctx->interval);
    /*+------------------------------------------------------+
     *|             parser subscriber settings               |
     *+------------------------------------------------------+*/
    str=iniparser_getstring(ini, "subsciber:subTopic", DEF_SUBTOPIC);
    strncpy(ctx->subTopic, str, sizeof(ctx->subTopic) );
    log_nrml("Parser and get subscriber topic \"%s\"\n", ctx->subTopic);
    ctx->subQos = iniparser_getint(ini, "subsciber:subQos", DEF_SUBQOS);
    log_nrml("Parser and get subscriber Qos[%d]\n", ctx->subQos);
    return 0;
}
mqttd/etc/conf.h
New file
@@ -0,0 +1,66 @@
/*********************************************************************************
 *      Copyright:  (C) 2019 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  conf.h
 *    Description:  This file is mqttd configure file parser function
 *
 *        Version:  1.0.0(2019年06月25日)
 *         Author:  Guo Wenxue <guowenxue@gmail.com>
 *      ChangeLog:  1, Release initial version on "2019年06月25日 22时23分55秒"
 *
 ********************************************************************************/
#ifndef  __CONF_H_
#define  __CONF_H_
#define DEF_BORKER_HOSTNAME        "master.iot-yun.com"
#define DEF_BROKER_PORT            10883
#define DEF_BROKER_KEEPALIVE       30
#define DEF_BROKER_USERNAME        "lingyun"
#define DEF_BROKER_PASSWD          "lingyun-emb"
#define DEF_PUBQOS                 2
#define DEF_PUBINTERVAL            600 /* 10 minitues */
#define DEF_SUBQOS                 0
#define MQTT_SYS_TOPIC             "$Sys/Studio/"
#define DEF_SUBTOPIC               MQTT_SYS_TOPIC"Downlink"
#define DEF_PUBTOPIC               MQTT_SYS_TOPIC"Uplink"
enum
{
    Qos0, /* 发送者只发送一次消息,不进行重试,Broker不会返回确认消息。在Qos0情况下,Broker可能没有接受到消息 */
    Qos1, /* 发送者最少发送一次消息,确保消息到达Broker,Broker需要返回确认消息PUBACK。在Qos1情况下,Broker可能接受到重复消息 */
    Qos2, /* Qos2使用两阶段确认来保证消息的不丢失和不重复。在Qos2情况下,Broker肯定会收到消息,且只收到一次  */
};
typedef struct mqtt_ctx_s
{
    /* logger settings */
    char          logfile[128]; /* logger record file */
    int           loglevel;     /* logger level  */
    int           logsize;      /* logger file maxsize, oversize will rollback */
    /* Broker settings  */
    char          host[128];  /* MQTT broker server name  */
    int           port;       /* MQTT broker listen port  */
    char          uid[64];    /* username */
    char          pwd[64];    /* password */
    int           keepalive;  /* MQTT broker send PING message to subsciber/publisher keepalive timeout<seconds> */
    /* Publisher settings */
    char          pubTopic[256]; /* Publisher topic  */
    int           pubQos;        /* Publisher Qos */
    int           interval ;     /* Publish sensor data interval time, unit seconds */
    /* Subscriber settings */
    char          subTopic[256]; /* Subscriber topic */
    int           subQos;        /* Subscriber Qos  */
} mqtt_ctx_t;
extern int mqttd_parser_conf(const char *conf_file, mqtt_ctx_t *ctx, int debug);
#endif   /* ----- #ifndef _CONF_H_  ----- */
mqttd/etc/conf.o
Binary files differ
mqttd/etc/libetc.a
Binary files differ
mqttd/etc/makefile
New file
@@ -0,0 +1,17 @@
PWD=$(shell pwd )
LIBNAME=$(shell basename ${PWD} )
PROJPATH=$(shell dirname ${PWD} )
CFLAGS+=-I${PROJPATH}
all: clean
    @rm -f *.o
    @${CROSS_COMPILE}gcc ${CFLAGS} -c *.c
    ${CROSS_COMPILE}ar -rcs  lib${LIBNAME}.a *.o
clean:
    @rm -f *.o
    @rm -f *.a
mqttd/etc/mqttd.conf
New file
@@ -0,0 +1,48 @@
[logger]
# 日志记录文件
file=/tmp/mqttd.log
# 日志级别: 0:Disable 1:Fatal 2:ERROR 3:warnning 4:Normal 5:Debug 6:Infor 7:Trace
level=5
# 日志回滚大小
size=1024
[broker]
# broker 服务器地址和端口号
hostname="master.iot-yun.com"
port=10883
# broker 认证连接的用户名和密码
username="lingyun"
password="lingyun-emb"
# broker给subsciber和publisher发送PING报文保持 keepalive 的时间周期,单位是秒
keepalive=30
# Qos0: 发送者只发送一次消息,不进行重试,Broker不会返回确认消息。在Qos0情况下,Broker可能没有接受到消息
# Qos1: 发送者最少发送一次消息,确保消息到达Broker,Broker需要返回确认消息PUBACK。在Qos1情况下,Broker可能接受到重复消息
# Qos2: Qos2使用两阶段确认来保证消息的不丢失和不重复。在Qos2情况下,Broker肯定会收到消息,且只收到一次
[publisher]
pubTopic="$Sys/Studio/Uplink"
pubQos=2
# Publisher上报传感器数据的周期
interval=60
[subsciber]
subTopic="$Sys/Studio/Downlink"
subQos=0
mqttd/main.c
@@ -21,36 +21,9 @@
#include "proc.h"
#include "hal.h"
#include "conf.h"
#define DAEMON_PIDFILE             "/tmp/.mqtt.pid"
#define MQTT_SYS_TOPIC             "$Sys/Studio/"
#define MQTT_SYS_DLINK_TOPIC       MQTT_SYS_TOPIC"Downlink"
#define MQTT_SYS_ULINK_TOPIC       MQTT_SYS_TOPIC"Uplink"
enum
{
    Qos0, /* 发送者只发送一次消息,不进行重试,Broker不会返回确认消息。在Qos0情况下,Broker可能没有接受到消息 */
    Qos1, /* 发送者最少发送一次消息,确保消息到达Broker,Broker需要返回确认消息PUBACK。在Qos1情况下,Broker可能接受到重复消息 */
    Qos2, /* Qos2使用两阶段确认来保证消息的不丢失和不重复。在Qos2情况下,Broker肯定会收到消息,且只收到一次  */
};
typedef struct mqtt_ctx_s
{
    /* Broker settings  */
    char          host[128];  /* MQTT broker server name  */
    int           port;       /* MQTT broker listen port  */
    int           keepalive;  /* MQTT broker send PING message to subsciber/publisher keepalive timeout<seconds> */
    char          uid[64];    /* username */
    char          pwd[64];    /* password */
    /* Publisher settings */
    int           pubQos;     /* Publisher Qos */
    int           interval;   /* Publish sensor data interval time, unit seconds */
    /* Subscriber settings */
    int           subQos;     /* Subscriber Qos  */
} mqtt_ctx_t;
int check_set_program_running(int daemon);
@@ -65,24 +38,14 @@
    int                daemon = 0;
    pthread_t          tid;
    mqtt_ctx_t         ctx;
    char               *conf="./etc/mqttd.conf";
    int                debug = 1;
    strcpy(ctx.host, "127.0.0.1");
    ctx.port = 10883;
    ctx.keepalive = 60;
    strcpy(ctx.uid, "lingyun");
    strcpy(ctx.pwd, "lingyun-emb");
    ctx.pubQos = Qos0;
    ctx.interval = 300;
    ctx.subQos = Qos2;
    //if( logger_init("mqttd.log", LOG_LEVEL_DEBUG, 1024) < 0 )
    if( logger_init(DBG_LOG_FILE, LOG_LEVEL_DEBUG, 1024) < 0 )
    if( mqttd_parser_conf(conf, &ctx, debug)<0 )
    {
        fprintf(stderr, "Logger system initialise failure\n");
        fprintf(stderr, "Parser mqtted configure file failure\n");
        return -2;
    }
    log_dbg("Logger system initialise ok\n");
#if 0
    if( hal_init() < 0 )
@@ -167,6 +130,7 @@
    float                   temp = 25.64;
    float                   rh = 65.35;
    char                    light[] = "on";
    int                     retain = 0;
    if( result )
    {
@@ -179,7 +143,7 @@
    memset(msg, 0, sizeof(msg));
    snprintf(msg, sizeof(msg), "{ \"temp\":\"%.2f\",  \"R&H\":\"%.2f%%\" }", temp, rh);
    rv = mosquitto_publish(mosq, NULL, MQTT_SYS_ULINK_TOPIC, strlen(msg)+1, msg, ctx->pubQos, 0);
    rv = mosquitto_publish(mosq, NULL, ctx->pubTopic, strlen(msg)+1, msg, ctx->pubQos, retain);
    if( rv )
    {
        log_err("Publisher broadcast message '%s' failure: %d\n", msg, rv);
@@ -192,7 +156,7 @@
    memset(msg, 0, sizeof(msg));
    snprintf(msg, sizeof(msg), "{ \"light\":\"%s\" }", light);
    rv = mosquitto_publish(mosq, NULL, MQTT_SYS_ULINK_TOPIC, strlen(msg)+1, msg, ctx->pubQos, 0);
    rv = mosquitto_publish(mosq, NULL, ctx->pubTopic, strlen(msg)+1, msg, ctx->pubQos, retain);
    if( rv )
    {
        log_err("Publisher broadcast message failure: %d\n", rv);
@@ -262,7 +226,7 @@
    }
    
    log_nrml("Subscriber connect to broker server[%s:%d] successfully\n", ctx->host, ctx->port); 
    mosquitto_subscribe(mosq, NULL, MQTT_SYS_DLINK_TOPIC, 2);
    mosquitto_subscribe(mosq, NULL, ctx->subTopic, ctx->subQos);
}
void sub_disconnect_callback(struct mosquitto *mosq, void *userdata, int result)
mqttd/makefile
@@ -38,8 +38,8 @@
export LDFLAGS
CFLAGS+=-Ihal -Ilylib
LDFLAGS+=-L hal -lhal -Llylib -llylib
CFLAGS+=-Ihal -Ietc -Ilylib
LDFLAGS+=-L hal -lhal -Letc -letc -Llylib -llylib
LDFLAGS+=-lmosquitto -lpthread -lm
@@ -56,6 +56,7 @@
modules:
    make -C hal
    make -C lylib
    make ${CFLAGS} -C etc
    cd ${MQTT_LIBPATH} && bash build.sh
binary:  ${SRCFILES}