使用paho.mqtt.c客户端库和Cjosn库实现和mqtt服务器进行数据交互实例程序
github地址:
https://github.com/eclipse/paho.mqtt.c
#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;
}
解析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;
}