MQTTClient_setCallbacks() will always create socket and not close it - c

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;
}

Related

Correct closing DBus connection

Could you explain how to close DBus connection correctly/ Below is my variant:
int P_dbus_proto_init(DBusConnection **dbus_conn, const char *name, dbus_MessageHandler mh, int num_rules, const char **rules)
{
int rc = 0;
DBusError dbus_err;
dbus_error_init(&dbus_err);
*dbus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &dbus_err);
if (dbus_error_is_set(&dbus_err))
{
FILTER_LOG_ERROR("Connection Error (%s)\n", dbus_err.message);
dbus_error_free(&dbus_err);
return -1;
}
rc = dbus_bus_request_name(*dbus_conn, name, DBUS_NAME_FLAG_REPLACE_EXISTING, &dbus_err);
if (dbus_error_is_set(&dbus_err) || (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != rc))
{
FILTER_LOG_ERROR("Connection Error (%s)\n", dbus_err.message);
dbus_error_free(&dbus_err);
return -1;
}
dbus_connection_add_filter(*dbus_conn, mh, NULL, NULL);
if (dbus_error_is_set(&dbus_err))
{
FILTER_LOG_ERROR("Add Filter Error (%s)\n", dbus_err.message);
dbus_error_free(&dbus_err);
return -1;
}
for(int i = 0; i < num_rules; i++)
{
dbus_bus_add_match(*dbus_conn, rules[i], &dbus_err);
if (dbus_error_is_set(&dbus_err))
{
FILTER_LOG_ERROR("Match Error (%s)\n", dbus_err.message);
dbus_error_free(&dbus_err);
return -1;
}
}
return 0;
}
static const char* rules[] = {
"interface='acl_management.method'",
};
And how I use it:
DBusConnection *dbus_conn;
if (P_dbus_proto_init(&dbus_conn, "com.bla-bla-bla.acl", P_dbus_proto_job, 1, rules) == 0)
{
while (dbus_connection_read_write_dispatch(dbus_conn, 5000))
{
if(p_ctx->execute.n_nl_exit_app == 0) //My app can be terminated by n_nl_exit_app flag
{
break;
}
}
dbus_connection_close(dbus_conn);// Should I do it or not?
dbus_connection_unref(dbus_conn);// Should I do it or not?
}
From dbus.freedesktop.org docs I cannot understand how to do it correctly. I can terminate my app by turn on 'n_nl_exit_app' flag - should I call dbus_connection_closein this case?

Custom pidgin plugin crashes (GTK library and GLib on C )

I am developing plugin for Pidgin. I want to share one of my windows that are open on my computer with other user via VNC. When I select the window to be shared and press the button, Pidgin freezes and closes.
Here is working well: opening vnc connection and sends Port name to other users. (but this one for sharing all of screen.)
static void
send_button_cb(GtkButton *button, PidginConversation *gtkconv)
{
gchar *url_vnc;
gchar *url_http;
gchar *joinstr;
int std_out[2];
int autoport = purple_prefs_get_bool(PREF_AUTOPORT);
char x11vnc_port[10] = "0";
if (purple_prefs_get_bool(PREF_X11VNC) && ((x11vnc_pid == 0) || (kill(x11vnc_pid, 0) != 0)))
{
if (purple_prefs_get_bool(PREF_GENPASSWD))
{
readableRandomString(password, 4);
}
else
{
strcpy(password, purple_prefs_get_string(PREF_PASSWD));
}
sprintf(x11vnc_port, "%d", 5900 + purple_prefs_get_int(PREF_PORT));
pipe(std_out);
if ((x11vnc_pid = fork()) == 0)
{
close(1);
close(std_out[0]);
dup2(std_out[1], 1);
close(std_out[1]);
int ret = execlp("x11vnc", "x11vnc", "-shared", "-gui", "tray", "-http", "-viewonly", "-passwd", password, ((autoport) ? "-autoport" : "-rfbport"), x11vnc_port, NULL);
perror("pidgin_vnc:x11vnc");
exit(ret);
}
close(std_out[1]);
port_num = x11vnc_port;
if (fd = fdopen(std_out[0], "r"))
{
while (!feof(fd))
{
if (fscanf(fd, "PORT=%d", &port_num))
break;
}
port_num -= 5900;
//close (fd);
printf("FINI\n");
}
else
{
port_num = x11vnc_port;
}
}
const char *ip;
PurpleStunNatDiscovery *stun_res = purple_stun_discover(NULL);
if (stun_res && stun_res->status == PURPLE_STUN_STATUS_DISCOVERED)
{
printf("STUN mode %d %d\n", stun_res->status, stun_res->type);
ip = purple_network_get_my_ip(-1);
}
else
{
ip = purple_upnp_get_public_ip();
if (ip == NULL)
{
printf("LOCAL mode\n");
ip = purple_network_get_my_ip(-1);
}
else
{
printf("UPNP mode\n");
}
}
url_http = g_strdup_printf("http://%s:%d/", ip, 5800 + port_num);
url_vnc = g_strdup_printf("vnc://invitation:%s#%s:%d", password, ip, port_num);
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, url_vnc);
joinstr = g_strdup_printf("%s.\ntry %s\nor %s. Password=%s", purple_prefs_get_string(PREF_TEXT), url_vnc, url_vnc, url_http, url_http, password);
gtk_imhtml_append_text(GTK_IMHTML(gtkconv->entry), joinstr, FALSE);
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "imhtml display vnc\n");
g_signal_emit_by_name(gtkconv->entry, "message_send");
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "message sent\n");
g_free(url_vnc);
g_free(url_http);
g_free(joinstr);
}
There is a problem in here. When I click to button which is calling this function program crashes when you click the button.(this function for sharing one of my windows that are open on my computer.)
static void
send_button_cb_win(GtkButton *button, PidginConversation *gtkconv)
{
gchar *url_vnc;
gchar *url_http;
gchar *joinstr;
int std_out[2];
int comboBoxSelectedRow = gtk_combo_box_get_active(combo_box);
char *selectedId[1] = {0};
selectedId[0] = ekranIds[0][comboBoxSelectedRow];
int autoport = purple_prefs_get_bool(PREF_AUTOPORT);
char x11vnc_port[10] = "0";
if (purple_prefs_get_bool(PREF_X11VNC) && ((x11vnc_pid == 0) || (kill(x11vnc_pid, 0) != 0)))
{
if (purple_prefs_get_bool(PREF_GENPASSWD))
{
readableRandomString(password, 4);
}
else
{
strcpy(password, purple_prefs_get_string(PREF_PASSWD));
}
sprintf(x11vnc_port, "%d", 5900 + purple_prefs_get_int(PREF_PORT));
pipe(std_out);
if((x11vnc_pid = fork()) == 0)
{
close(1);
close(std_out[0]);
dup2(std_out[1], 1);
close(std_out[1]);
int ret = execlp("x11vnc", "x11vnc", "-id", selectedId[0], "-gui", "-shared", "tray", "-http", "-viewonly", "-passwd", password, ((autoport) ? "-autoport" : "-rfbport"), x11vnc_port, NULL);
perror("pidgin_vnc:x11vnc");
exit(ret);
}
close(std_out[1]);
port_num = x11vnc_port;
if (fd = fdopen(std_out[0], "r"))
{
while (!feof(fd))
{
if (fscanf(fd, "PORT=%d", &port_num))
break;
}
port_num -= 5900;
//close (fd);
printf("FINI\n");
}
else
{
port_num = x11vnc_port;
}
}
const char *ip;
PurpleStunNatDiscovery *stun_res = purple_stun_discover(NULL);
if (stun_res && stun_res->status == PURPLE_STUN_STATUS_DISCOVERED)
{
printf("STUN mode %d %d\n", stun_res->status, stun_res->type);
ip = purple_network_get_my_ip(-1);
}
else
{
ip = purple_upnp_get_public_ip();
if (ip == NULL)
{
printf("LOCAL mode\n");
ip = purple_network_get_my_ip(-1);
}
else
{
printf("UPNP mode\n");
}
}
url_http = g_strdup_printf("http://%s:%d/", ip, 5800 + port_num);
url_vnc = g_strdup_printf("vnc://invitation:%s#%s:%d", password, ip, port_num);
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, url_vnc);
joinstr = g_strdup_printf("%s.\ntry %s\nor %s. Password=%s", purple_prefs_get_string(PREF_TEXT), url_vnc, url_vnc, url_http, url_http, password);
gtk_imhtml_append_text(GTK_IMHTML(gtkconv->entry), joinstr, FALSE);
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "imhtml display vnc\n");
g_signal_emit_by_name(gtkconv->entry, "message_send");
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "message sent\n");
g_free(url_vnc);
g_free(url_http);
g_free(joinstr);
gtk_widget_show_all(button);
}
This function to fill combobox with opened windows names
static void
refresh_combo_box(GtkWidget *widget, PidginConversation *gtkconv)
{
FILE *fp1;
FILE *fp2;
char path[1035];
char path2[1035];
char sum[1035];
/* Open the command for reading. */
fp1 = popen("xprop -root | grep '_NET_CLIENT_LIST_STACKING(WINDOW)'", "r");
if (fp1 == NULL)
{
printf("Failed to run command\n" );
exit(1);
}
/* Read the output a line at a time - output it. */
while (fgets(path, sizeof(path) - 1, fp1) != NULL)
{
// printf("%s", path);
strcat(sum, path);
}
char *splitter = strtok(sum, "#");
splitter = strtok(NULL, "#");
char *virgulSplitter = strtok(splitter, ", ");
ekranIds[0][0] = strdup(virgulSplitter);
int a = 1;
while (virgulSplitter != NULL)
{
virgulSplitter = strtok(NULL, ",");
if (virgulSplitter != NULL)
{
ekranIds[0][a] = strdup(virgulSplitter);
a++;
}
}
for (int x = 0; x < a; x++)
{
ekranIds[0][a - 1][strcspn(ekranIds[0][a - 1], "\n")] = 0;
char tmp[500] = {0};
//here is get window names by id
sprintf(tmp, "xprop -id %s | grep '^WM_NAME'", ekranIds[0][x]);
fp2 = popen(tmp, "r");
if (fp1 == NULL)
{
printf("Failed to run command\n" );
exit(1);
}
// Read the output a line at a time - output it.
while (fgets(path2, sizeof(path2) - 1, fp2) != NULL)
{
char *windowSplitter = strtok(path2, "=");
windowSplitter = strtok(NULL, "=");
ekranIds[1][x] = strdup(windowSplitter);
}
}
pclose(fp2);
pclose(fp1);
char *combobox_source[30];
for (int yf = 0; yf < 30; yf++)
{
if (ekranIds[1][yf] != NULL)
{
combobox_source[yf] = strdup(ekranIds[1][yf]);
}
}
gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model(combo_box)));
for (int i = 0; i < G_N_ELEMENTS(combobox_source); i++)
{
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box), combobox_source[i]);
}
gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), 0);
gtk_widget_show_all(combo_box);
}
First function is working well: opening vnc connection and sends Port name to other users. (but this one for sharing all of screen.)
Second function has problem. When I click to button which is calling this function program crashes when you click the button.(this function for sharing one of my windows that are open on my computer.)
Third function to fill combobox with opened windows' names.

Publish Message to IOT Hub - Eclypse Paho MQTT

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;
}

Mqtt disconnecting when another publish

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);
}
}

c - trying to make irc bot

#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.

Resources