Below is my code for connecting and sending data from device to cloud using Eclypse Paho MQTT Library. I am able to connect with IOT Hub as rc results 0 in my case but It doesn't send message to my IOT Hub device. Can anyone please guide me where I have made mistake or what I am doing wrong ?
I am using Visual studio 2015 with .Net framework 4.0 and eclipse-paho-mqtt-c-windows-1.0.3 libraries
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MQTTAsync.h"
#if !defined(WIN32)
#include <unistd.h>
#else
#include <windows.h>
#endif
#if defined(_WRS_KERNEL)
#include <OsWrapper.h>
#endif
#define ADDRESS "ssl://xxxxx.azure-devices.net:8883" //tcp://localhost:1883"
#define CLIENTID "EnergyMeter" //"ExampleClientPub"
#define TOPIC "devices/EnergyMeter/messages/events/" //"MQTT Examples"
#define PAYLOAD "Hello World!"
#define QOS 1
#define TIMEOUT 10000L
volatile MQTTAsync_token deliveredtoken;
int finished = 0;
void connlost(void *context, char *cause)
{
MQTTAsync client = (MQTTAsync)context;
MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
int rc;
printf("\nConnection lost\n");
printf(" cause: %s\n", cause);
printf("Reconnecting\n");
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
{
printf("Failed to start connect, return code %d\n", rc);
finished = 1;
}
}
void onDisconnect(void* context, MQTTAsync_successData* response)
{
printf("Successful disconnection\n");
finished = 1;
}
void onSend(void* context, MQTTAsync_successData* response)
{
MQTTAsync client = (MQTTAsync)context;
MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer;
int rc;
printf("Message with token value %d delivery confirmed\n", response->token);
opts.onSuccess = onDisconnect;
opts.context = client;
if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS)
{
printf("Failed to start sendMessage, return code %d\n", rc);
exit(EXIT_FAILURE);
}
}
void onConnectFailure(void* context, MQTTAsync_failureData* response)
{
printf("Connect failed, rc %d\n", response ? response->code : 0);
finished = 1;
}
void onConnect(void* context, MQTTAsync_successData* response)
{
printf("hello");
MQTTAsync client = (MQTTAsync)context;
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
int rc;
printf("Successful connection\n");
opts.onSuccess = onSend;
opts.context = client;
pubmsg.payload = PAYLOAD;
pubmsg.payloadlen = strlen(PAYLOAD);
pubmsg.qos = QOS;
pubmsg.retained = 0;
deliveredtoken = 0;
if ((rc = MQTTAsync_sendMessage(client, TOPIC, &pubmsg, &opts)) != MQTTASYNC_SUCCESS)
{
printf("Failed to start sendMessage, return code %d\n", rc);
exit(EXIT_FAILURE);
}
}
int main(int argc, char* argv[])
{
MQTTAsync client;
MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
int rc = 5;
int a;
a = MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
printf("a is %d", a);
printf("Hey");
MQTTAsync_setCallbacks(client, NULL, connlost, NULL, NULL);
printf("check1\n");
conn_opts.keepAliveInterval = 5;
//conn_opts.username = "ssl://Ironman.azure-devices.net/stark";
//conn_opts.password = "SharedAccessSignature sr=Ironman.azure-devices.net%2Fdevices%2Fstark&sig=eoAum3Hl2gWWiFVJT%2FhmUMwYH4NFAT%2B5fG8tRTm%2BbaA%3D&se=1558677763";
conn_opts.cleansession = 1;
printf("check2\n");
conn_opts.onSuccess = onConnect;
conn_opts.username = "CCMSIoTHub.azure-devices.net/EnergyMeter/api-version=2016-11-14";
conn_opts.password = "SharedAccessSignature sr=xxxxxxx.azure-devices.net%2Fdevices%2FEnergyMeter&sig=undNm%xxxxxxxxz87I%3D&se=xxxxxxxxx";
printf("check3\n");
conn_opts.onFailure = onConnectFailure;
conn_opts.context = client;
if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
{
printf("Failed to start connect, return code %d\n", rc);
exit(EXIT_FAILURE);
}
else
{
printf("rc is %d ", rc);
}
printf("Waiting for publication of %s\n"
"on topic %s for client with ClientID: %s\n",
PAYLOAD, TOPIC, CLIENTID);
while (!finished)
#if defined(WIN32) || defined(WIN64)
Sleep(100);
#else
usleep(10000L);
#endif
MQTTAsync_destroy(&client);
return rc;
}
Below Code works fine In my case
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MQTTClient.h"
#define ADDRESS "ssl://xxxxxxxxxx.azure-devices.net:8883" //tcp://localhost:1883"
#define CLIENTID "xxxxxxxxxx" //"ExampleClientPub"
#define TOPIC "devices/xxxxxxxxxx/messages/events/" //"MQTT Examples"
#define PAYLOAD "Hello World!"
#define QOS 1
#define TIMEOUT 10000L
volatile MQTTClient_deliveryToken deliveredtoken;
void delivered(void *context, MQTTClient_deliveryToken dt)
{
printf("Message with token value %d delivery confirmed\n", dt);
deliveredtoken = dt;
}
int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
int i;
char* payloadptr;
printf("Message arrived\n");
printf(" topic: %s\n", topicName);
printf(" message: ");
payloadptr = (char *)message->payload;
for (i = 0; i<message->payloadlen; i++)
{
putchar(*payloadptr++);
}
putchar('\n');
MQTTClient_freeMessage(&message);
MQTTClient_free(topicName);
return 1;
}
void connlost(void *context, char *cause)
{
printf("\nConnection lost\n");
printf(" cause: %s\n", cause);
}
#define TEST_SSL
int main(int argc, char* argv[])
{
MQTTClient client;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
MQTTClient_message pubmsg = MQTTClient_message_initializer;
MQTTClient_deliveryToken token;
int rc;
rc = MQTTClient_create(&client, ADDRESS, CLIENTID,
1, NULL);
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
conn_opts.username = "xxxxxxxxxx.azure-devices.net/xxxxxxxxxx/api-version=2016-11-14";
conn_opts.password = "SharedAccessSignature sr=xxxxxxxxxx.azure-devices.net%2Fdevices%2Fxxxxxxxxxx&sig=undNm%2Fxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=15xxxxxx";
#ifdef TEST_SSL
MQTTClient_SSLOptions sslOptions = MQTTClient_SSLOptions_initializer;
sslOptions.enableServerCertAuth = 1;
sslOptions.trustStore = "D:/Parth/Projects/MQTT/MQTT Sample D2C Azure IOT Hub Tested Program/rootCA.crt";
conn_opts.ssl = &sslOptions;
#endif
//conn_opts.ssl->trustStore = "D:\Parth\Projects\MQTT\paho.mqtt.c-master\test\ssl\test - alt - ca.crt";
rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered);
if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
{
printf("Failed to connect, return code %d\n", rc);
exit(EXIT_FAILURE);
}
pubmsg.payload = PAYLOAD;
pubmsg.payloadlen = strlen(PAYLOAD);
pubmsg.qos = QOS;
pubmsg.retained = 0;
deliveredtoken = 0;
MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token);
printf("Waiting for publication of %s\n"
"on topic %s for client with ClientID: %s\n",
PAYLOAD, TOPIC, CLIENTID);
while (deliveredtoken != token);
MQTTClient_disconnect(client, 10000);
MQTTClient_destroy(&client);
return rc;
}
Related
How can I add the functions for username and password to authen mqtt broker.
The original file has not section for authentication. How can I adding function for username and password in authentication mqtt server?
This file has mqtt.h that is sitting parameters (such as hotsname, port, etc.). and I have added parameter for username and password in mqtt.h following this
struct mqtt_handle_s {
// Public members
char *host;
int port;
char *username;
char *password;
char *client_id;
mqtt_on_connect_t on_connect;
mqtt_on_message_t on_message;
// Private members
struct mosquitto *client;
char *topic_list;
size_t topic_size;
};
and then how can I adding the function for running that parameter to using in mqtt server authentication?
the main code is following..
#mqtt.c full code.
#if defined(_WIN32)
#include <windows.h>
#endif
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include "app_log.h"
#include "mqtt.h"
// Check if libmosquitto version is at least 1.5.7
#if LIBMOSQUITTO_VERSION_NUMBER < 1005007
#warning Untested libmosquitto version!
#endif
#define QOS 1
#define KEEPALIVE_INTERVAL_SEC 30
#define LOOP_TIMEOUT_MS 1
#define LOG_MASK MOSQ_LOG_NONE
static void mqtt_on_connect(struct mosquitto *mosq, void *obj, int rc);
static void mqtt_on_disconnect(struct mosquitto *mosq, void *obj, int rc);
static void mqtt_on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message);
static void mqtt_on_log(struct mosquitto *mosq, void *obj, int level, const char *str);
static const char * mqtt_err2str(int rc);
mqtt_status_t mqtt_init(mqtt_handle_t *handle)
{
mqtt_status_t ret = MQTT_SUCCESS;
int rc = MOSQ_ERR_ERRNO; // return code if mosquitto_new() fails
struct mosquitto *mosq;
mosquitto_lib_init();
mosq = mosquitto_new(handle->client_id, true, handle);
if (mosq != NULL) {
mosquitto_connect_callback_set(mosq, mqtt_on_connect);
mosquitto_disconnect_callback_set(mosq, mqtt_on_disconnect);
mosquitto_message_callback_set(mosq, mqtt_on_message);
mosquitto_log_callback_set(mosq, mqtt_on_log);
rc = mosquitto_connect(mosq, handle->host, handle->port, KEEPALIVE_INTERVAL_SEC);
}
if (rc != MOSQ_ERR_SUCCESS) {
app_log("MQTT init failed: '%s'\n", mqtt_err2str(rc));
ret = MQTT_ERROR_CONNECT;
handle->client = NULL;
if (mosq != NULL) {
mosquitto_destroy(mosq);
}
} else {
handle->client = mosq;
}
handle->topic_list = NULL;
handle->topic_size = 0;
return ret;
}
mqtt_status_t mqtt_publish(mqtt_handle_t *handle, const char *topic, const char *payload)
{
mqtt_status_t ret = MQTT_SUCCESS;
int rc;
int mid;
if (handle->client != NULL) {
rc = mosquitto_publish(handle->client, &mid, topic, strlen(payload), payload, QOS, false);
if (rc != MOSQ_ERR_SUCCESS) {
app_log("MQTT publish attempt failed: '%s'\n", mqtt_err2str(rc));
ret = MQTT_ERROR_PUBLISH;
}
} else {
ret = MQTT_ERROR_PUBLISH;
}
return ret;
}
mqtt_status_t mqtt_step(mqtt_handle_t *handle)
{
mqtt_status_t ret = MQTT_SUCCESS;
int rc;
if (handle->client != NULL) {
rc = mosquitto_loop(handle->client, LOOP_TIMEOUT_MS, 1);
if (rc != MOSQ_ERR_SUCCESS) {
app_log("MQTT loop failed: '%s'\n", mqtt_err2str(rc));
ret = MQTT_ERROR_STEP;
}
} else {
ret = MQTT_ERROR_STEP;
}
return ret;
}
mqtt_status_t mqtt_subscribe(mqtt_handle_t *handle, const char *topic)
{
mqtt_status_t ret = MQTT_SUCCESS;
int rc;
size_t topic_size;
if (handle->client != NULL) {
// Try to subscribe to topic.
rc = mosquitto_subscribe(handle->client, NULL, topic, QOS);
if ((rc != MOSQ_ERR_SUCCESS) && (rc != MOSQ_ERR_NO_CONN)) {
app_log("MQTT subscribe attempt failed to topic '%s': '%s'\n", topic, mqtt_err2str(rc));
ret = MQTT_ERROR_SUBSCRIBE;
}
// Append topic to topic list.
topic_size = strlen(topic) + 1;
handle->topic_list = realloc(handle->topic_list, handle->topic_size + topic_size);
if (handle->topic_list == NULL) {
app_log("MQTT failed to append topic to topic list.\n");
ret = MQTT_ERROR_SUBSCRIBE;
} else {
strcpy(&handle->topic_list[handle->topic_size], topic);
handle->topic_size += topic_size;
}
} else {
ret = MQTT_ERROR_SUBSCRIBE;
}
return ret;
}
mqtt_status_t mqtt_deinit(mqtt_handle_t *handle)
{
int rc;
if (handle->client != NULL) {
rc = mosquitto_disconnect(handle->client);
if (rc != MOSQ_ERR_SUCCESS) {
app_log("MQTT failed to disconnect: '%s', continue deinit.\n", mqtt_err2str(rc));
}
mosquitto_destroy(handle->client);
mosquitto_lib_cleanup();
if (handle->topic_list != NULL) {
free(handle->topic_list);
}
}
return MQTT_SUCCESS;
}
static void mqtt_on_connect(struct mosquitto *mosq, void *obj, int rc)
{
mqtt_handle_t *handle = (mqtt_handle_t *)obj;
size_t topic_start = 0;
char *topic;
int ret = MOSQ_ERR_SUCCESS;
app_log("MQTT connect status '%s'\n", mosquitto_connack_string(rc));
if (rc == 0) {
if (handle->on_connect != NULL) {
handle->on_connect(handle);
}
while (topic_start < handle->topic_size) {
topic = &handle->topic_list[topic_start];
ret = mosquitto_subscribe(mosq, NULL, topic, QOS);
topic_start += strlen(topic) + 1;
if (ret != MOSQ_ERR_SUCCESS) {
app_log("MQTT subscribe attempt failed to topic '%s': '%s'\n", topic, mqtt_err2str(ret));
}
}
}
}
static void mqtt_on_disconnect(struct mosquitto *mosq, void *obj, int rc)
{
int ret;
app_log("MQTT disconnected with reason '%d'\n", rc);
if (rc != 0) {
ret = mosquitto_reconnect(mosq);
app_log("MQTT reconnection attempt with status '%s'\n", mqtt_err2str(ret));
}
}
static void mqtt_on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
{
mqtt_handle_t *handle = (mqtt_handle_t *)obj;
char *payload;
if (handle->on_message != NULL) {
payload = malloc(message->payloadlen + 1);
if (NULL == payload) {
app_log("MQTT failed to allocate payload buffer.\n");
} else {
memcpy(payload, message->payload, message->payloadlen);
// Make sure that payload is NULL terminated.
payload[message->payloadlen] = 0;
handle->on_message(handle, message->topic, payload);
free(payload);
}
}
}
static void mqtt_on_log(struct mosquitto *mosq, void *obj, int level, const char *str)
{
if (level & LOG_MASK) {
app_log("MQTT log (%d): %s\n", level, str);
}
}
#if defined(_WIN32)
static const char * mqtt_err2str(int rc)
{
char *ret = NULL;
static char err_str[256];
if (MOSQ_ERR_ERRNO == rc) {
// Make sure to have a default output if FormatMessage fails
// or if error code is not available in errno.
strncpy(err_str, "Unknown system error", sizeof(err_str));
if (errno != 0) {
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, // dwFlags
NULL, // lpSource
errno, // dwMessageId
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // dwLanguageId
err_str, // lpBuffer
sizeof(err_str), // nSize
NULL); // Arguments
}
// Make sure that err_str is NULL terminated.
err_str[sizeof(err_str) - 1] = 0;
ret = err_str;
} else {
ret = (char *)mosquitto_strerror(rc);
}
return ret;
}
#else
static const char * mqtt_err2str(int rc)
{
return (MOSQ_ERR_ERRNO == rc) ? strerror(errno) : mosquitto_strerror(rc);
}
#endif // _WIN32
My System OS is Linux, Use C for development, My MQTT Library is "paho-MQTT"
The simple application below will run for a while before generating a "open too much files" error. I have attempted to diagnose using losf command to find out what is the fd not closed.
I believed I had traced the issue to the MQTT Function "MQTTClient_setCallbacks()" but that seems OK. Currently I'm unable to find out the true cause of the error.
Note: When this problem occurs, the device has no external network capability, so will be in an infinite loop attempting to connect.
My code is below as:
int InternalSock::MQTTSubscribe()
{
MQTTClient client;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
int rc;
int ch;
const char *TOPIC=ModTcpIPA->DC1SN[0];
const char *address;
if (ModTcpIPA->ThirdPartyMode == 1) {
address = "ws://52.163.118.233:8080"; //3rd party
}
else {
address = "ws://52.187.179.41:8080"; //delta
}
const char *client_id=ModTcpIPA->DC1SN[0];
char *chs = ModTcpIPA->DC1SN[0];
char **topic=&chs;
disconnectflag = 1;
ModTcpIPA->MQTTSubscribing = 0;
MQTTClient_create(&client, address, client_id, MQTTCLIENT_PERSISTENCE_NONE, NULL);
conn_opts.keepAliveInterval = 30;
conn_opts.cleansession = 0;
if (ModTcpIPA->ThirdPartyMode == 1) {
conn_opts.username = THIRDPARTYUSERNAME;
conn_opts.password = THIRDPARTYPASSWORD;
}
else {
conn_opts.username = DELTAUSERNAME;
conn_opts.password = DELTAPASSWORD;
}
conn_opts.MQTTVersion = MQTTVERSION_3_1;
while(!ModTcpIPA->CloseMQTTThread){
if(disconnectflag == 1){
MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered);
disconnectflag = 0;
}
if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
{
//if(ModTcpIPA->CloudRegist_st == 1){
printf("Failed to connect, return code %d\n", rc);
//}
}else{
printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n"
"Press Q<Enter> to quit\n\n", TOPIC, client_id, QOS);
MQTTClient_subscribe(client, TOPIC, QOS);
ModTcpIPA->MQTTSubscribing = 1;
while(disconnectflag == 0){
if(strlen(MQTTBuff)!= 0){
ParseMQTTMsg(&client);
}
sleep(1);
}
ModTcpIPA->MQTTSubscribing = 0;
MQTTClient_unsubscribe(client, TOPIC);
MQTTClient_disconnect(client, 10000);
}
sleep(3);
}
MQTTClient_destroy(&client);
return rc;
}
add callback functions:
void delivered(void *context, MQTTClient_deliveryToken dt)
{
printf("Message with token value %d delivery confirmed\n", dt);
deliveredtoken = dt;
}
int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
int i;
char* payloadptr;
printf("Message arrived\n");
printf(" topic: %s\n", topicName);
printf(" message: ");
payloadptr = (char*)message->payload;
for(i=0; i<message->payloadlen; i++)
{
putchar(*payloadptr++);
}
putchar('\n');
memset(MQTTBuff, '\0', sizeof(MQTTBuff));
memcpy(MQTTBuff, message->payload, message->payloadlen);
MQTTClient_freeMessage(&message);
MQTTClient_free(topicName);
return 1;
}
void connlost(void *context, char *cause)
{
printf("\nConnection lost\n");
printf(" cause: %s\n", cause);
disconnectflag = 1;
}
I am trying to use MQTT library to connect to Amazon IOT Service
/*
* Copyright (c) 2019 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <logging/log.h>
LOG_MODULE_REGISTER(aws_mqtt, LOG_LEVEL_DBG);
#include <zephyr.h>
#include <net/socket.h>
#include <net/mqtt.h>
#include <net/net_config.h>
#include <net/net_event.h>
#include <net/sntp.h>
#include <sys/printk.h>
#include <string.h>
#include <errno.h>
#include "dhcp.h"
#include <time.h>
#include <inttypes.h>
#include "globalsign.inc"
/* The mqtt client struct */
static struct mqtt_client client_ctx;
s64_t time_base;
/* MQTT Broker details. */
static struct sockaddr_storage broker;
#if defined(CONFIG_SOCKS)
static struct sockaddr socks5_proxy;
#endif
static struct pollfd fds[1];
static int nfds;
#define APP_MQTT_BUFFER_SIZE 128
static sec_tag_t m_sec_tags[] = {
#if defined(MBEDTLS_X509_CRT_PARSE_C) || defined(CONFIG_NET_SOCKETS_OFFLOAD)
APP_CA_CERT_TAG,
#endif
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
APP_PSK_TAG,
#endif
};
#define APP_CA_CERT_TAG 1
#define APP_PSK_TAG 2
/* Buffers for MQTT client. */
static u8_t rx_buffer[APP_MQTT_BUFFER_SIZE];
static u8_t tx_buffer[APP_MQTT_BUFFER_SIZE];
static bool connected;
#define MQTT_CLIENTID "zephyr_publisher"
struct zsock_addrinfo *haddr;
time_t my_k_time(time_t *ptr)
{
s64_t stamp;
time_t now;
stamp = k_uptime_get();
now = (time_t)((stamp + time_base) / 1000);
if (ptr) {
*ptr = now;
}
return now;
}
static void broker_init(void)
{
struct sockaddr_in *broker4 = (struct sockaddr_in *)&broker;
broker4->sin_family = AF_INET;
broker4->sin_port = htons(8883);
net_ipaddr_copy(&broker4->sin_addr,
&net_sin(haddr->ai_addr)->sin_addr);
#if defined(CONFIG_SOCKS)
struct sockaddr_in *proxy4 = (struct sockaddr_in *)&socks5_proxy;
proxy4->sin_family = AF_INET;
proxy4->sin_port = htons(1081);
inet_pton(AF_INET, "agwgaprlb6xdl-ats.iot.us-west-2.amazonaws.com", &proxy4->sin_addr);
#endif
}
void mqtt_evt_handler(struct mqtt_client *const client,
const struct mqtt_evt *evt)
{
int err;
switch (evt->type) {
case MQTT_EVT_CONNACK:
if (evt->result != 0) {
LOG_ERR("MQTT connect failed %d", evt->result);
break;
}
connected = true;
LOG_INF("MQTT client connected!");
break;
case MQTT_EVT_DISCONNECT:
LOG_INF("MQTT client disconnected %d", evt->result);
connected = false;
//clear_fds();
break;
case MQTT_EVT_PUBACK:
if (evt->result != 0) {
LOG_ERR("MQTT PUBACK error %d", evt->result);
break;
}
LOG_INF("PUBACK packet id: %u", evt->param.puback.message_id);
break;
case MQTT_EVT_PUBREC:
if (evt->result != 0) {
LOG_ERR("MQTT PUBREC error %d", evt->result);
break;
}
LOG_INF("PUBREC packet id: %u", evt->param.pubrec.message_id);
const struct mqtt_pubrel_param rel_param = {
.message_id = evt->param.pubrec.message_id
};
err = mqtt_publish_qos2_release(client, &rel_param);
if (err != 0) {
LOG_ERR("Failed to send MQTT PUBREL: %d", err);
}
break;
case MQTT_EVT_PUBCOMP:
if (evt->result != 0) {
LOG_ERR("MQTT PUBCOMP error %d", evt->result);
break;
}
LOG_INF("PUBCOMP packet id: %u",
evt->param.pubcomp.message_id);
break;
default:
break;
}
}
static void client_init(struct mqtt_client *client)
{
static struct mqtt_utf8 password;
static struct mqtt_utf8 username;
mqtt_client_init(client);
broker_init();
password.utf8 = (u8_t *)CONFIG_SAMPLE_CLOUD_AWS_PASSWORD;
password.size = strlen(CONFIG_SAMPLE_CLOUD_AWS_PASSWORD);
client->password = &password;
username.utf8 = (u8_t *)CONFIG_SAMPLE_CLOUD_AWS_USERNAME;
username.size = strlen(CONFIG_SAMPLE_CLOUD_AWS_USERNAME);
client->user_name = &username;
/* MQTT client configuration */
client->broker = &broker;
client->evt_cb = mqtt_evt_handler;
client->client_id.utf8 = (u8_t *)MQTT_CLIENTID;
client->client_id.size = strlen(MQTT_CLIENTID);
client->password = NULL;
client->user_name = NULL;
client->protocol_version = MQTT_VERSION_3_1_1;
/* MQTT buffers configuration */
client->rx_buf = rx_buffer;
client->rx_buf_size = sizeof(rx_buffer);
client->tx_buf = tx_buffer;
client->tx_buf_size = sizeof(tx_buffer);
client->transport.type = MQTT_TRANSPORT_SECURE;
struct mqtt_sec_config *tls_config = &client->transport.tls.config;
tls_config->peer_verify = TLS_PEER_VERIFY_REQUIRED;
tls_config->cipher_list = NULL;
tls_config->sec_tag_list = m_sec_tags;
tls_config->sec_tag_count = ARRAY_SIZE(m_sec_tags);
tls_config->hostname = NULL;
client->transport.type = MQTT_TRANSPORT_NON_SECURE;
#if defined(CONFIG_SOCKS)
mqtt_client_set_proxy(client, &socks5_proxy,
socks5_proxy.sa_family == AF_INET ?
sizeof(struct sockaddr_in) :
sizeof(struct sockaddr_in6));
#endif
}
#define RC_STR(rc) ((rc) == 0 ? "OK" : "ERROR")
#define PRINT_RESULT(func, rc) \
LOG_INF("%s: %d <%s>", (func), rc, RC_STR(rc))
static void prepare_fds(struct mqtt_client *client)
{
if (client->transport.type == MQTT_TRANSPORT_NON_SECURE) {
fds[0].fd = client->transport.tcp.sock;
}
#if defined(CONFIG_MQTT_LIB_TLS)
else if (client->transport.type == MQTT_TRANSPORT_SECURE) {
fds[0].fd = client->transport.tls.sock;
}
#endif
fds[0].events = ZSOCK_POLLIN;
nfds = 1;
}
static void clear_fds(void)
{
nfds = 0;
}
static void wait(int timeout)
{
if (nfds > 0) {
if (poll(fds, nfds, timeout) < 0) {
LOG_ERR("poll error: %d", errno);
}
}
}
static int try_to_connect(struct mqtt_client *client)
{
u8_t retries = 3U;
int rc;
LOG_DBG("attempting to connect...");
client_init(client);
rc = mqtt_connect(client);
if (rc != 0) {
PRINT_RESULT("mqtt_connect", rc);
k_sleep(500);
} else {
prepare_fds(client);
wait(500);
mqtt_input(client);
if (!connected) {
LOG_INF("Aborting connection\n");
mqtt_abort(client);
}
}
if (connected) {
return 0;
}
return -EINVAL;
}
void mqtt_startup(char *hostname, int port)
{
struct mqtt_client *client = &client_ctx;
int retries = 5;
int err, cnt;
static struct zsock_addrinfo hints;
int res = 0;
int rc;
mbedtls_platform_set_time(my_k_time);
err = tls_credential_add(1, TLS_CREDENTIAL_CA_CERTIFICATE,
globalsign_certificate,
sizeof(globalsign_certificate));
if (err < 0) {
LOG_ERR("Failed to register public certificate: %d", err);
}
LOG_DBG("tls credential added\n");
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = 0;
cnt = 0;
while ((err = getaddrinfo("agwgaprlb6xdl-ats.iot.us-west-2.amazonaws.com", "8883", &hints,
&haddr)) && cnt < 3) {
LOG_ERR("Unable to get address for broker, retrying");
cnt++;
}
if (err != 0) {
LOG_ERR("Unable to get address for broker, error %d",
res);
return;
}
LOG_INF("DNS resolved for agwgaprlb6xdl-ats.iot.us-west-2.amazonaws.com:8833");
try_to_connect(client);
PRINT_RESULT("try_to_connect", rc);
}
static void show_addrinfo(struct addrinfo *addr)
{
char hr_addr[NET_IPV6_ADDR_LEN];
void *a;
top:
LOG_DBG(" flags : %d", addr->ai_flags);
LOG_DBG(" family : %d", addr->ai_family);
LOG_DBG(" socktype: %d", addr->ai_socktype);
LOG_DBG(" protocol: %d", addr->ai_protocol);
LOG_DBG(" addrlen : %d", (int)addr->ai_addrlen);
/* Assume two words. */
LOG_DBG(" addr[0]: 0x%lx", ((uint32_t *)addr->ai_addr)[0]);
LOG_DBG(" addr[1]: 0x%lx", ((uint32_t *)addr->ai_addr)[1]);
if (addr->ai_next != 0) {
addr = addr->ai_next;
goto top;
}
a = &net_sin(addr->ai_addr)->sin_addr;
LOG_INF(" Got %s",
log_strdup(net_addr_ntop(addr->ai_family, a,
hr_addr, sizeof(hr_addr))));
}
void do_sntp(struct addrinfo *addr)
{
struct sntp_ctx ctx;
int rc;
s64_t stamp;
struct sntp_time sntp_time;
char time_str[sizeof("1970-01-01T00:00:00")];
LOG_INF("Sending NTP request for current time:");
/* Initialize sntp */
rc = sntp_init(&ctx, addr->ai_addr, sizeof(struct sockaddr_in));
if (rc < 0) {
LOG_ERR("Unable to init sntp context: %d", rc);
return;
}
rc = sntp_query(&ctx, K_FOREVER, &sntp_time);
if (rc == 0) {
stamp = k_uptime_get();
time_base = sntp_time.seconds * MSEC_PER_SEC - stamp;
/* Convert time to make sure. */
time_t now = sntp_time.seconds;
struct tm now_tm;
gmtime_r(&now, &now_tm);
strftime(time_str, sizeof(time_str), "%FT%T", &now_tm);
LOG_INF(" Acquired time: %s", log_strdup(time_str));
} else {
LOG_ERR(" Failed to acquire SNTP, code %d\n", rc);
}
sntp_close(&ctx);
}
void main(void)
{
static struct addrinfo hints;
struct addrinfo *haddr;
int res;
int cnt = 0;
app_dhcpv4_startup();
LOG_INF("Should have DHCPv4 lease at this point.");
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = 0;
//while ((res = getaddrinfo("console.aws.amazon.com", "80", &hints,
while ((res = getaddrinfo("time.google.com", "123", &hints,
&haddr)) && cnt < 3) {
LOG_ERR("Unable to get address for NTP server, retrying");
cnt++;
}
if (res != 0) {
LOG_ERR("Unable to get address of NTP server, exiting %d", res);
return;
}
LOG_INF("DNS resolved for console.aws.amazon.com:80");
show_addrinfo(haddr);
do_sntp(haddr);
mqtt_startup("agwgaprlb6xdl-ats.iot.us-west-2.amazonaws.com", 8883);
}
Following are the logs:
[00:00:07.193,000] <dbg> net_mqtt_enc.pack_uint8: (0x20401bac): >> val:10 cur:0x20401d64, end:0x20401de1
[00:00:07.205,000] <dbg> net_mqtt_enc.packet_length_encode: (0x20401bac): >> length:0x0000001c cur:0x20401d65, end:0x20401de1
[00:00:07.219,000] <dbg> net_mqtt.client_connect: (0x20401bac): Connect completed
[00:00:07.684,000] <dbg> net_mqtt.mqtt_input: (0x20401bac): state:0x00000002
[00:00:07.693,000] <dbg> net_mqtt_rx.mqtt_read_message_chunk: (0x20401bac): [CID 0x20400254]: Connection closed.
[00:00:07.706,000] <dbg> net_mqtt_sock_tcp.mqtt_client_tcp_disconnect: (0x20401bac): Closing socket 0
[00:00:07.718,000] <err> aws_mqtt: MQTT connect failed -111
[00:00:07.726,000] <inf> aws_mqtt: Aborting connection
[00:00:07.734,000] <inf> aws_mqtt: try_to_connect: 0 <OK>
I have 2 gateways (OS:yocto embedded linux ).Which send and receive commands from a cloud application.When i run mqtt application in gateway 1 alone, it is able to send and receive commands from cloud application.And when i run gatway1 and gateway 2 together, they are able to send commands to cloud application but when cloud send a command to any of the gateway the other one is disconnecting.
Im using paho-mqtt c library version 3.1
i tried different client ID specific TOPIC but none of them worked,please give me some help .
here is my MQTT application.
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "MQTTAsync.h"
#if !defined(WIN32)
#include <unistd.h>
#else
#include <windows.h>
#endif
#define ADDRESS "test.mosquitto.org:1883"
#define CLIENTID "ExampleClientPub1" //client id is UNIQUE
#define TOPIC_SUB "pubTopic" /*2 gateways subscribed to this topic and cloud app publish to this topic */
#define TOPIC_PUB "MQTT Examples" /*gateway send message to this topic and cloud app subscribe to this topic*/
#define PAYLOAD "******from app2!******" /* sample payload*/
#define QOS 1
#define TIMEOUT 10000L
volatile MQTTAsync_token deliveredtoken;
int finished = 0;
MQTTAsync client;
int disc_finished = 0;
int subscribed = 0;
void connlost(void *context, char *cause)
{
MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
int rc;
printf("\nConnection lost\n");
printf(" cause: %s\n", cause);
printf("Reconnecting\n");
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
{
printf("Failed to start connect, return code %d\n", rc);
finished = 1;
}
}
void onDisconnect(void* context, MQTTAsync_successData* response)
{
printf("Successful disconnection\n");
finished = 1;
}
void onSend(void* context, MQTTAsync_successData* response)
{
// MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer;
int rc;
printf("Message with token value %d delivery confirmed\n", response->token);
// opts.onSuccess = onDisconnect;
// opts.context = client;
// if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS)
// {
// printf("Failed to start sendMessage, return code %d\n", rc);
// exit(EXIT_FAILURE);
// }
}
void onConnectFailure(void* context, MQTTAsync_failureData* response)
{
printf("Connect failed, rc %d\n", response ? response->code : 0);
finished = 1;
}
void transfer() /*function usesd for publishing*/
{
static int i=1;
printf("\n................................Transmitt %d................................\n",i++);
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
int rc;
printf("Successful connection\n");
opts.onSuccess = onSend;
opts.context = client;
pubmsg.payload = PAYLOAD;
pubmsg.payloadlen = strlen(PAYLOAD);
pubmsg.qos = QOS;
pubmsg.retained = 0;
deliveredtoken = 0;
if ((rc = MQTTAsync_sendMessage(client, TOPIC_PUB, &pubmsg, &opts)) != MQTTASYNC_SUCCESS)
{
printf("Failed to start sendMessage, return code %d\n", rc);
exit(EXIT_FAILURE);
}
}
/************subscribe****************/
void onSubscribe(void* context, MQTTAsync_successData* response)
{
printf("Subscribe succeeded\n");
subscribed = 1;
}
void onSubscribeFailure(void* context, MQTTAsync_failureData* response)
{
printf("Subscribe failed, rc %d\n", response ? response->code : 0);
finished = 1;
}
void onConnect(void* context, MQTTAsync_successData* response)
{
MQTTAsync client = (MQTTAsync)context;
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
int rc;
printf("Successful connection\n");
printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n"
"Press Q<Enter> to quit\n\n", TOPIC_SUB, CLIENTID, QOS);
opts.onSuccess = onSubscribe;
opts.onFailure = onSubscribeFailure;
opts.context = client;
deliveredtoken = 0;
if ((rc = MQTTAsync_subscribe(client, TOPIC_SUB, QOS, &opts)) != MQTTASYNC_SUCCESS)
{
printf("Failed to start subscribe, return code %d\n", rc);
exit(EXIT_FAILURE);
}
}
int msgarrvd(void *context, char *topicName, int topicLen, MQTTAsync_message *message)
{
int i;
char* payloadptr;
printf("Message arrived\n");
printf(" topic: %s\n", topicName);
printf(" message: ");
payloadptr = message->payload;
for(i=0; i<message->payloadlen; i++)
{
putchar(*payloadptr++);
}
putchar('\n');
MQTTAsync_freeMessage(&message);
MQTTAsync_free(topicName);
return 1;
}
int main ()
{
MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
MQTTAsync_token token;
int rc;
MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
MQTTAsync_setCallbacks(client, NULL, connlost, msgarrvd, NULL);
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
conn_opts.onSuccess = onConnect;
conn_opts.onFailure = onConnectFailure;
conn_opts.context = client;
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
conn_opts.onSuccess = onConnect;
conn_opts.onFailure = onConnectFailure;
conn_opts.context = client;
if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
{
printf("Failed to start connect, return code %d\n", rc);
exit(EXIT_FAILURE);
}
while(!subscribed)
#if defined(WIN32)
Sleep(100);
#else
usleep(10000L);
#endif
while(1)
{
sleep(1);
transfer();
sleep(2);
}
}
#include <winsock2.h>
#include <stdio.h>
const int PORT = 6667;
const char *SERVER = "irc.freenode.org";
const char *CHAN = "#channela";
const char *NICK = "loveMilk";
const int MAX_BUFF_SIZE = 512;
int sock_conn(SOCKET *socketn, const char *HOST, int portn);
int sock_send(SOCKET *socketn, char* msg, ...);
int main(int argc, char *argv[])
{
WSADATA wsadata;
char buff[MAX_BUFF_SIZE];
char oBuff[MAX_BUFF_SIZE];
int buffRec;
if (WSAStartup(MAKEWORD(2,2), &wsadata) != 0)
return 0;
SOCKET sock;
if(sock_conn(&sock, SERVER, PORT) != 0)
{
WSACleanup();
return 0;
}
printf("connected.\n");
sock_send(&sock, "USER %s \"\" \"127.0.0.1\" :%s\r\n", NICK, NICK);
sock_send(&sock, "NICK %s\r\n", NICK);
Sleep(100);
sock_send(&sock, "JOIN %s\r\n", CHAN);
printf("Joined channel.\n");
while(1)
{
memset(buff, 0, MAX_BUFF_SIZE);
memset(oBuff, 0, MAX_BUFF_SIZE);
buffRec = recv(sock, buff, MAX_BUFF_SIZE, 0);
if((buffRec == 0) || (buffRec == SOCKET_ERROR)) break;
/* New line: Terminate buffer as a string */
buff[buffRec] = '\0';
if(buff[0] != ':')
{
strcpy(oBuff, "PONG :");
printf("PONG");
sock_send(&sock, oBuff);
}
else
{
if(strstr(buff, "PRIVMSG"))
{
int i, num = 0;
for(i = 0; i < strlen(buff); ++i) if(buff[i] = ' ') ++num;
char** parts = malloc(sizeof(char*) * num);
char *p;
p = strtok(buff, " ");
int j = 0;
while(p != NULL)
{
parts[j] = p;
j++;
p = strtok(NULL, " ");
}
printf("%s", parts[3]);
free(parts);
}
}
}
closesocket(sock);
return 1;
}
int sock_conn(SOCKET *socketn, const char *HOST, int portn)
{
WSADATA wsadata;
SOCKADDR_IN sockA;
LPHOSTENT hostE;
if(WSAStartup(MAKEWORD(2,2), &wsadata) == -1) return -1;
if(!(hostE = gethostbyname(HOST)))
{
WSACleanup();
return -1;
}
if ((*socketn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
WSACleanup();
return -1;
}
sockA.sin_family = AF_INET;
sockA.sin_port = htons(portn);
sockA.sin_addr = *((LPIN_ADDR)*hostE->h_addr_list);
if(connect(*socketn, (LPSOCKADDR)&sockA, sizeof(struct sockaddr)) == SOCKET_ERROR)
{
WSACleanup();
return -1;
}
}
int sock_send(SOCKET *socketn, char* msg, ...)
{
char buff[MAX_BUFF_SIZE];
va_list va;
va_start(va, msg);
vsprintf(buff, msg, va);
va_end(va);
send(*socketn, buff, strlen(buff), 0);
return 1;
}
parts always null, why? someone told me to terminate the buff with this line: buff[buffRec] = '\0';, but still I got nothing, how can I change the buff to string cause I believe this is the problem... the bot is connecting and all and I can communicate with it, but when I try to reach to parts, it's NULL.
char buff[MAX_BUFF_SIZE];
/* ... */
buffRec = recv(sock, buff, MAX_BUFF_SIZE, 0);
buff[buffRec] = '\0';
If buffRec value is MAX_BUFF_SIZE you have a buffer overflow.