Ubuntu 下paho mqtt c库使用

文章目录

  • 1、概述
  • 2、实例程序
  • 2、cjson库使用

1、概述

使用paho.mqtt.c客户端库和Cjosn库实现和mqtt服务器进行数据交互实例程序

github地址:
https://github.com/eclipse/paho.mqtt.c

2、实例程序

#include 
#include "cJSON.h"
#include 
#include "MQTTAsync.h"
#define FILE_NAME 256

typedef struct 
{
    MQTTAsync async_client;
    char host[FILE_NAME];
    char username[FILE_NAME];
    char password[FILE_NAME];
    char client_id[FILE_NAME];
} mqtt_client_t;

int main()
{
    mqtt_client_t client;
    device_num = getstring("sys_device_number");
    m_assert(device_num,"device_num is null",-1);

    // init mqtt
    if(mqtt_client_init(&client,ADDRESS,USERNAME,PASSWD,device_num)){
        LOG_ERROR(c,"mqtt_client_init fail");
        goto err;
    }
    // connect mqtt server
    if(mqtt_client_connect(&client)){
        LOG_ERROR(c,"mqtt_client_connect fail");
        //goto err;
    }
    sleep(4);
    if (finished){
        goto err;
    }
    
    if(mqtt_client_run(&client)){
        LOG_ERROR(c,"mqtt_client_run fail");
        goto err;
    }

    if(mqtt_client_disconnect(&client)){
        LOG_ERROR(c,"mqtt_client_disconnect fail");
    }
    MQTTAsync_destroy(&client.async_client);
    return 0;
err:
    mqtt_client_disconnect(&client);
    MQTTAsync_destroy(&client.async_client);
    return -1;
}


int mqtt_client_init(mqtt_client_t* client, char* host, char* username, char* password, const char* client_id)
{
    m_assert(client,"client is null",-1);
    m_assert(host,"host is null",-1);
    m_assert(username,"username is null",-1);
    m_assert(password,"password is null",-1);
    m_assert(client_id,"client_id is null",-1);

    memset(client, 0, sizeof(mqtt_client_t));
    strcpy(client->host,host);
    strcpy(client->username,username);
    strcpy(client->password,password);
    strcpy(client->client_id,client_id);

    int rc;
    if((rc=MQTTAsync_create(&client->async_client, client->host, client->client_id, MQTTCLIENT_PERSISTENCE_NONE, NULL))
        != MQTTASYNC_SUCCESS)
    {
        LOG_ERROR(c,"MQTTAsync_create fail:%d\n",rc);
        return -2;
    }
    
    if((rc=MQTTAsync_setCallbacks(client->async_client, client->async_client, connlost, messageArrived, NULL))
        != MQTTASYNC_SUCCESS)
    {
        LOG_ERROR(c,"MQTTAsync_setCallbacks fail:%d\n",rc);
        return -3;
    }
    return 0;
}

void connlost(void *context, char *cause)
{
	MQTTAsync client = (MQTTAsync)context;
	MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
	MQTTAsync_SSLOptions ssl_opts = MQTTAsync_SSLOptions_initializer;
    int rc;
	conn_opts.keepAliveInterval = 600;
	conn_opts.cleansession = 0;

    ssl_opts.sslVersion = MQTT_SSL_VERSION_TLS_1_2;
    ssl_opts.enableServerCertAuth = 0; 
    conn_opts.username = USERNAME;
    conn_opts.password = PASSWD;
	conn_opts.ssl = &ssl_opts;
	if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
	{
		printf("Failed to start connect, return code %d\n", rc);
		finished = 1;
	}
    LOG_ERROR(c,"连接丢失,重连成功");
}

int messageArrived(void *context, char *topicName, int topicLen, MQTTAsync_message *message)
{
    /*free memery*/
    m_assert(context,"context is null",0);
    m_assert(topicName,"topicName is null",0);
    m_assert(message,"message is null",0);

    LOG_DEBUG(c,"topicLen:%d",topicLen);
    LOG_DEBUG(c,"Message arrived on topic-%s: %.*s", topicName, message->payloadlen, (char*)message->payload);

    MQTTAsync client = (MQTTAsync )context;
    if(strncmp(topicName,topics_sub[0],topicLen) == 0)
    {
        cJSON *json_msg = down_info_request(client,message);
        m_assert(json_msg,"json_msg is null",0);
        up_info_response(client,json_msg);
        cJSON_Delete(json_msg);
    }
    else if(strncmp(topicName,topics_sub[1],topicLen) == 0)
    {
        if(upd_status == UPD_ING){
            MQTTAsync_freeMessage(&message);
            MQTTAsync_free(topicName);
            return 1;
        }
        upd_rollback_file("exec_status=","1");
        upd_rollback_file("msg=",(char*)message->payload);
        char wav_buffer[128] = {0};
        if(real_time_file()){
            LOG_DEBUG(c,"车辆正在行驶中,不能进行升级");
    #if AUDIO
            sprintf(wav_buffer,"%s %s/%s","sunxiaudio",UPD_WAV_PATH,"6.wav");
            system(wav_buffer);
    #else
            printf("Debug mode disabled\n");
    #endif
            MQTTAsync_freeMessage(&message);
            MQTTAsync_free(topicName);
            return 1;
        }

    #if AUDIO
        sprintf(wav_buffer,"%s %s/%s","sunxiaudio",UPD_WAV_PATH,"1.wav");
        system(wav_buffer);
    #else
        printf("Debug mode disabled\n");
    #endif
        cJSON *json_msg = down_upd_request(client,message);
        m_assert(json_msg,"json_msg is null",0);
        up_upd_response(client,json_msg);
        cJSON_Delete(json_msg);
        upd_rollback_file("exec_status=","0");
        upd_rollback_file("msg=","0");
    }
    else if(strncmp(topicName,topics_sub[2],topicLen) == 0)
    {
        down_teleport_on_request(client,message);
    }
    else if(strncmp(topicName,topics_sub[3],topicLen) == 0)
    {
        down_teleport_off_request(client,message);
    }

    MQTTAsync_freeMessage(&message);
    MQTTAsync_free(topicName);
    return 1;
err:
    return 0;
}


int mqtt_client_connect(mqtt_client_t* client)
{
    m_assert(client,"client is null",-1);
    MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
    MQTTAsync_SSLOptions ssl_opts = MQTTAsync_SSLOptions_initializer;
    ssl_opts.sslVersion = MQTT_SSL_VERSION_TLS_1_2;
    ssl_opts.enableServerCertAuth = 0; 
    conn_opts.keepAliveInterval = 600;
    conn_opts.cleansession = 0;
    conn_opts.username = client->username;
    conn_opts.password = client->password;
    conn_opts.ssl = &ssl_opts;
    conn_opts.context = client->async_client;
	conn_opts.onSuccess = onConnect;
	conn_opts.onFailure = onConnectFailure;
    int rc = MQTTAsync_connect(client->async_client, &conn_opts);
    if (rc != MQTTASYNC_SUCCESS) {
        LOG_ERROR(c,"Failed to start connect, return code %d\n", rc);
        return -1;
    }
    return 0;
}

int mqtt_client_run(mqtt_client_t* clients)
{
    m_assert(clients,"client is null",-1);
    m_assert(device_num,"device_num is null",-1);
    const char *hard_war = getstring("sys_hardware_ver");
    m_assert(hard_war,"hard_war is null",-1);
    
    char hear_topic[256];
    char *str_msg = NULL;
    int num_count = 0;
    int flag_res = 0;
    int flag_power = 0;
    int rc;
    sprintf(hear_topic,"%s/%s/%s/up/heartbeat",USERNAME,hard_war,device_num);
    LOG_DEBUG(c,"hear_topic:%s 20 The interval is 20 seconds",hear_topic);

    MQTTAsync client = (MQTTAsync)clients->async_client;
    MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
    MQTTAsync_message pubmsg = MQTTAsync_message_initializer;

    cJSON* cjson_test = cJSON_CreateObject();
    m_assert(cjson_test,"cjson_test is null",-1);

    cJSON *num_obj = cJSON_AddNumberToObject(cjson_test,"ts",0);
    while (1)
    {
        if (finished){
            goto err;
        }
        // power upd
        if(upd_status == UPD_ING)
        {
            if(flag_power == 0){
                LOG_DEBUG(c,"完成上次升级开始...");
                power_off_rollback(clients->async_client);
                flag_power = 1;
                upd_status = NO_UPD;
                upd_rollback_file("exec_status=","0");
                upd_rollback_file("msg=","0");
            }
        }
        // response msg
        if(flag_res == 0){    
            response_upd_res(clients->async_client);
            flag_res = 1;
        }
        cJSON_SetIntValue(num_obj,get_milliseconds());
        str_msg = cJSON_PrintUnformatted(cjson_test);
        
        pubmsg.payload = str_msg;
        pubmsg.payloadlen = strlen(str_msg);
        pubmsg.qos = QOS;
        pubmsg.retained = 0;
        MQTTAsync_sendMessage(client, hear_topic, &pubmsg, &opts);

        num_count++;
        if(!(num_count%100)){
            LOG_DEBUG(c,"已经发送心跳包次数:%d",num_count);
        }
        
        cJSON_free(str_msg);
        sleep(30);
    }
    return 0;
err:
    cJSON_Delete(cjson_test);
    return 0;
}

void onConnect(void* context, MQTTAsync_successData* response)
{
    m_assert(context,"context is null",);
    m_assert(response,"response is null",);
    connect_suc = 1;
    finished = 0;
	MQTTAsync client = (MQTTAsync)context;
	MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
	int rc;
	opts.onSuccess = onSubscribe;
	opts.onFailure = onSubscribeFailure;
	opts.context = client;
	deliveredtoken = 0;

    /* build topic name */
    const char *hdward_num,*device_num;
    for(size_t i=0; i<sizeof(topics)/sizeof(topics[0]); i++)
    {
        hdward_num = getstring("sys_hardware_ver");
        if(hdward_num == NULL) return;
        device_num = getstring("sys_device_number");
        if(device_num == NULL) return;
        sprintf(topics_sub[i],"%s/%s/%s/%s",USERNAME,hdward_num,device_num,topics[i]);
        sprintf(topics_pub[i],"%s/%s/%s/%s",USERNAME,hdward_num,device_num,topics_up[i]);
        if ((rc = MQTTAsync_subscribe(client, topics_sub[i], QOS, &opts)) != MQTTASYNC_SUCCESS)
        {
		    printf("Failed to start subscribe, return code %d\n", rc);
		    return;
        }
    }
}

void onDisconnect(void* context, MQTTAsync_successData* response)
{
	disc_finished = 1;
}


void onSubscribe(void* context, MQTTAsync_successData* response)
{
    LOG_DEBUG(c,"Subscribe succeeded");
	subscribed = 1;
}

void onSubscribeFailure(void* context, MQTTAsync_failureData* response)
{
	finished = 1;
}

void onConnectFailure(void* context, MQTTAsync_failureData* response)
{
	finished = 1;
}

int mqtt_client_disconnect(mqtt_client_t* client)
{
    MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer;
    int rc = MQTTAsync_disconnect(client->async_client, &disc_opts);
    if (rc != MQTTASYNC_SUCCESS) {
        LOG_ERROR(c,"Failed to start disconnect, return code %d\n", rc);
        return -1;
    }
    return 0;
}

2、cjson库使用

解析json字符串

enum CODE_ERR parse_update_res(const char *json_msg,cJSON *cjson_msg)
{
    cjson_msg = cJSON_Parse(json_msg);
    if(!cjson_msg){
        LOG_ERROR(c,"cJSON_Parse fail");
        return UPD_COMMD_ERROR;
    }
    cJSON* cjson_ts = NULL;
    cJSON* cjson_url = NULL;
    cJSON* cjson_hash = NULL;
    cJSON* cjson_software_ver = NULL;
    cJSON* cjson_hardware_ver = NULL;

    cjson_ts = cJSON_GetObjectItem(cjson_msg, "ts");

    if(!cjson_ts){
        LOG_ERROR(c,"cJSON_GetObjectItem fail");
        return UPD_COMMD_ERROR;
    }

    req_t->ts = cjson_ts->valueint;
    cjson_url = cJSON_GetObjectItem(cjson_msg, "url");
    if(!cjson_url){
        LOG_ERROR(c,"cJSON_GetObjectItem fail");
        return UPD_COMMD_ERROR;
    }
    
    memset(req_t->upd_url,0x00,sizeof(req_t->upd_url));
    strncpy(req_t->upd_url,cjson_url->valuestring,strlen(cjson_url->valuestring));

    cjson_hash = cJSON_GetObjectItem(cjson_msg, "md5");
    if(!cjson_hash){
        LOG_ERROR(c,"cJSON_GetObjectItem fail");
        return UPD_COMMD_ERROR;
    }
    memset(req_t->upd_hash,0x00,sizeof(req_t->upd_hash));
    strncpy(req_t->upd_hash,cjson_hash->valuestring,strlen(cjson_hash->valuestring));

    cjson_hardware_ver = cJSON_GetObjectItem(cjson_msg, "hardware_ver");
    memset(req_t->hardware_ver,0x00,sizeof(req_t->hardware_ver));
    strncpy(req_t->hardware_ver,cjson_hardware_ver->valuestring,strlen(cjson_hardware_ver->valuestring));

    cjson_software_ver = cJSON_GetObjectItem(cjson_msg, "new_version");
    if(!cjson_software_ver){
        LOG_ERROR(c,"cJSON_GetObjectItem fail");
        return UPD_COMMD_ERROR;
    }

    memset(req_t->new_version,0x00,sizeof(req_t->new_version));
    strncpy(req_t->new_version,cjson_software_ver->valuestring,strlen(cjson_software_ver->valuestring));

    LOG_DEBUG(c,"req_t->ts:%d",req_t->upd_url);
    LOG_DEBUG(c,"req_t->upd_url:%s",req_t->upd_url);
    LOG_DEBUG(c,"req_t->upd_hash:%s",req_t->upd_hash);
    LOG_DEBUG(c,"req_t->hardware_ver:%s",req_t->hardware_ver);
    LOG_DEBUG(c,"req_t->new_version:%s",req_t->new_version);
    LOG_DEBUG(c,"解析JSON完成");

    // 更新状态机状态
    cJSON_Delete(cjson_msg);
    cjson_msg = NULL;
    check_state = UPDATE_PREPA;
    return SUCCESS;
}

构建json字符串

cJSON *build_version_send()
{
    /* build json linked list*/
    cJSON* cjson_test = cJSON_CreateObject();
    if(!cjson_test){
        LOG_ERROR(c,"cJSON_CreateObject");
        return NULL;
    }

    cJSON_AddNumberToObject(cjson_test, "ts", get_milliseconds());
    cJSON_AddFalseToObject(cjson_test, "status");
     cJSON *bool_obj = cJSON_GetObjectItem(cjson_test, "status");
    cJSON_SetBoolValue(bool_obj,1);

    cJSON_AddStringToObject(cjson_test, "message", error_buf);

	// AEBS
	cJSON *cjson_AEBS = cJSON_CreateObject();
    if(!cjson_AEBS){
        LOG_ERROR(c,"cJSON_CreateObject");
        goto err;
    }
    cJSON_AddNumberToObject(cjson_AEBS, "m_aebs_switch", getintDefault("m_aebs_switch",0));
    cJSON_AddNumberToObject(cjson_AEBS, "m_skid_level", getintDefault("m_skid_level",0));
    cJSON_AddNumberToObject(cjson_AEBS, "m_skid_speed", getintDefault("m_skid_speed",0));
    cJSON_AddItemToObject(cjson_test, "AEBS", cjson_AEBS);

	// BSD
	cJSON *cjson_BSD = cJSON_CreateObject();
    if(!cjson_BSD){
        LOG_ERROR(c,"cJSON_CreateObject");
        goto err;
    }
	cJSON_AddNumberToObject(cjson_BSD, "m_bsd_switch", getintDefault("m_bsd_switch",0));
	cJSON_AddNumberToObject(cjson_BSD, "m_bsdsens_back", getintDefault("m_bsdsens_back",0));
	cJSON_AddNumberToObject(cjson_BSD, "m_bsdsens_left", getintDefault("m_bsdsens_left",0));
	cJSON_AddNumberToObject(cjson_BSD, "m_bsdsens_right", getintDefault("m_bsdsens_right",0));
	cJSON_AddItemToObject(cjson_test, "BSD", cjson_BSD);

	// ENCODE
	cJSON *cjson_ENCODE = cJSON_CreateObject();
    if(!cjson_ENCODE){
        LOG_ERROR(c,"cJSON_CreateObject");
        goto err;
    }
	cJSON_AddNumberToObject(cjson_ENCODE, "bitrate", getintDefault("bitrate",0));
	cJSON_AddNumberToObject(cjson_ENCODE, "framerate", getintDefault("framerate",0));
	cJSON_AddNumberToObject(cjson_ENCODE, "video_height", getintDefault("video_height",0));
	cJSON_AddNumberToObject(cjson_ENCODE, "video_width", getintDefault("video_width",0));
	cJSON_AddItemToObject(cjson_test, "ENCODE", cjson_ENCODE);

	// FOUR_G
	cJSON *cjson_FOUR_G = cJSON_CreateObject();
    if(!cjson_FOUR_G){
        LOG_ERROR(c,"cJSON_CreateObject");
        goto err;
    }
	cJSON_AddStringToObject(cjson_FOUR_G, "ccid", getstring("ccid"));
	cJSON_AddItemToObject(cjson_test, "FOUR_G", cjson_FOUR_G);

	// FRADAR
	cJSON *cjson_FRADAR = cJSON_CreateObject();
    if(!cjson_FRADAR){
        LOG_ERROR(c,"cJSON_CreateObject");
        goto err;
    }
	cJSON_AddNumberToObject(cjson_FRADAR, "fCenter", getintDefault("fCenter",0));
	cJSON_AddNumberToObject(cjson_FRADAR, "fHight", getintDefault("fHight",0));
	cJSON_AddItemToObject(cjson_test, "FRADAR", cjson_FRADAR);

	// RCAMERA
	cJSON *cjson_RCAMERA = cJSON_CreateObject();
    if(!cjson_RCAMERA){
        LOG_ERROR(c,"cJSON_CreateObject");
        goto err;
    }
	cJSON_AddNumberToObject(cjson_RCAMERA, "rCameraAngle", getintDefault("rCameraAngle",0));
	cJSON_AddItemToObject(cjson_test, "RCAMERA", cjson_RCAMERA);

	// RRADAR
	cJSON *cjson_RRADAR = cJSON_CreateObject();
    if(!cjson_RRADAR){
        LOG_ERROR(c,"cJSON_CreateObject");
        goto err;
    }
	cJSON_AddNumberToObject(cjson_RRADAR, "rFront", getintDefault("rFront",0));
	cJSON_AddNumberToObject(cjson_RRADAR, "rHight", getintDefault("rHight",0));
	cJSON_AddItemToObject(cjson_test, "RCAMERA", cjson_RRADAR);

	// SERVERS
	cJSON *cjson_SERVERS = cJSON_CreateObject();
    if(!cjson_SERVERS){
        LOG_ERROR(c,"cJSON_CreateObject");
        goto err;
    }
    // const char *ser1 = getstring("server1");
    // const char *ser2 = getstring("server2");
    // const char *ser3 = getstring("server3");
    
    char ser1[128],ser2[128],ser3[128];
    strcpy(ser1,getstring("server1"));
    strcpy(ser2,getstring("server2"));
    strcpy(ser3,getstring("server3"));
	strip_quotes(ser1);
    strip_quotes(ser2);
    strip_quotes(ser3);

    cJSON_AddStringToObject(cjson_SERVERS, "server1", ser1);
	cJSON_AddStringToObject(cjson_SERVERS, "server2", ser2);
	cJSON_AddStringToObject(cjson_SERVERS, "server3", ser3);
	cJSON_AddItemToObject(cjson_test, "SERVERS", cjson_SERVERS);

	// SYSVER
	cJSON *cjson_SYSVER = cJSON_CreateObject();
    if(!cjson_SYSVER){
        LOG_ERROR(c,"cJSON_CreateObject");
        goto err;
    }
	cJSON_AddStringToObject(cjson_SYSVER, "sys_device_number", getstring("sys_device_number"));
	cJSON_AddStringToObject(cjson_SYSVER, "sys_hardware_ver", getstring("sys_hardware_ver"));
	cJSON_AddStringToObject(cjson_SYSVER, "sys_mcusoftware_ver", getstring("sys_mcusoftware_ver"));
	cJSON_AddStringToObject(cjson_SYSVER, "sys_software_ver", getstring("sys_software_ver"));
	cJSON_AddItemToObject(cjson_test, "SYSVER", cjson_SYSVER);

	// VEHICLE
	cJSON *cjson_VEHICLE = cJSON_CreateObject();
    if(!cjson_VEHICLE){
        LOG_ERROR(c,"cJSON_CreateObject");
        goto err;
    }
    char viNos1[128];
    strcpy(viNos1,getstring("vinNo"));
    strip_quotes(viNos1);

	cJSON_AddStringToObject(cjson_VEHICLE, "cityCounty", getstring("cityCounty"));
	cJSON_AddStringToObject(cjson_VEHICLE, "province", getstring("province"));
	cJSON_AddStringToObject(cjson_VEHICLE, "licensePlateNumber", getstring("licensePlateNumber"));
	cJSON_AddNumberToObject(cjson_VEHICLE, "plateColor", getintDefault("plateColor",0));
	cJSON_AddStringToObject(cjson_VEHICLE, "vinNo", viNos1);
	cJSON_AddNumberToObject(cjson_VEHICLE, "vehicleType", getintDefault("vehicleType",0));
	cJSON_AddItemToObject(cjson_test, "VEHICLE", cjson_VEHICLE);
    return cjson_test;
err:
    cJSON_Delete(cjson_test);
    return NULL;
}

你可能感兴趣的:(ubuntu,c语言,mqtt)