XMPP auto reconnect using libstrophe - c

using libstrophe, can I reconnect automatically when I loose connection.
I used the following code on the client side:
void conn_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status,
const int error, xmpp_stream_error_t * const stream_error,
void * const userdata)
{
if (status == XMPP_CONN_CONNECT) {
fprintf(stderr, "DEBUG: connected\n");
}
else {
fprintf(stderr, "DEBUG: disconnected\n");
}
}
void main()
{
xmpp_log_t *log;
char *jid;
jid = strdup("test#domain.com")
xmpp_initialize();
log = xmpp_get_default_logger(XMPP_LEVEL_ERROR);
cwmp->xmpp_ctx = xmpp_ctx_new(NULL, log);
cwmp->xmpp_conn = xmpp_conn_new(cwmp->xmpp_ctx);
xmpp_conn_set_jid(cwmp->xmpp_conn, jid);
xmpp_conn_set_pass(cwmp->xmpp_conn, cwmp->xmpp_param.password);
xmpp_connect_client(cwmp->xmpp_conn, NULL, 0, conn_handler, cwmp->xmpp_ctx);
xmpp_run(cwmp->xmpp_ctx);
}
when the client is connected for the first time, i get the message "DEBUG: connected"
When the server goes done, i get the message "DEBUG: disconnected". but when the server is up for the second time, the client is not reconnected automatically.

Libstrophe doesn't reconnect automatically. Starting from libstrophe-0.9.0 xmpp_conn_t object can be reconnected without loosing login information and user handlers:
#include <stdio.h>
#include <strophe.h>
void conn_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status,
const int error, xmpp_stream_error_t * const stream_error,
void * const userdata)
{
if (status == XMPP_CONN_CONNECT) {
fprintf(stderr, "DEBUG: connected\n");
} else {
fprintf(stderr, "DEBUG: disconnected, reconnecting...\n");
xmpp_connect_client(conn, NULL, 0, conn_handler, userdata);
}
}
int main()
{
xmpp_log_t *log;
xmpp_ctx_t *ctx;
xmpp_conn_t *conn;
const char *jid = "test#domain.com";
const char *pass = "password";
xmpp_initialize();
log = xmpp_get_default_logger(XMPP_LEVEL_ERROR);
ctx = xmpp_ctx_new(NULL, log);
conn = xmpp_conn_new(ctx);
xmpp_conn_set_jid(conn, jid);
xmpp_conn_set_pass(conn, pass);
xmpp_connect_client(conn, NULL, 0, conn_handler, NULL);
xmpp_run(ctx);
xmpp_conn_release(conn);
xmpp_ctx_free(ctx);
xmpp_shutdown();
return 0;
}
In versions before 0.9.0 user can't reuse xmpp_conn_t object after disconnection and needs to create new one. Example for libstrophe-0.8.8 and older:
#include <stdio.h>
#include <strophe.h>
#define TIMEOUT 1000
void conn_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status,
const int error, xmpp_stream_error_t * const stream_error,
void * const userdata)
{
int *reconnect = userdata;
if (status == XMPP_CONN_CONNECT) {
fprintf(stderr, "DEBUG: connected\n");
} else {
fprintf(stderr, "DEBUG: disconnected, reconnecting...\n");
*reconnect = 1;
}
}
int main()
{
xmpp_log_t *log;
xmpp_ctx_t *ctx;
xmpp_conn_t *conn;
const char *jid = "test#domain.com";
const char *pass = "password";
int reconnect;
xmpp_initialize();
log = xmpp_get_default_logger(XMPP_LEVEL_ERROR);
ctx = xmpp_ctx_new(NULL, log);
while (1) {
conn = xmpp_conn_new(ctx);
xmpp_conn_set_jid(conn, jid);
xmpp_conn_set_pass(conn, pass);
xmpp_connect_client(conn, NULL, 0, conn_handler, &reconnect);
reconnect = 0;
while (!reconnect)
xmpp_run_once(ctx, TIMEOUT);
xmpp_conn_release(conn);
}
xmpp_ctx_free(ctx);
xmpp_shutdown();
return 0;
}

Related

How to add function for mqtt server authentication

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

Why is my Schannel server hanging at `recv`?

So I'm writing an Schannel server to the IOS Gmail client app - IMAP server.
I'm forcing TLS1.0 (tried with TLS1.0to1.3 - 1.3 seems to bail with algo_mismatch but the other ones do the same, I've also tried with SSL3.0 but read that is not supported for gmail.
Currently I can't get over the handshake process which seems to hang at recv. I don't know what I'm doing wrong - I've also installed the certificate on my (client device - IOS).
I need to clarify - it goes into the loop the 1st time which successfully ends (AcceptSecurityContext with SEC_I_CONTINUE_NEEDED) but after the send (I've also checked its result which matches the cbBuffer size so it must be ok) next iteration it hangs on recv.
Here is the handshake part:
static struct performhandshake {
CtxtHandle ctx; CredHandle hCred; SOCKET sock; SecPkgContext_StreamSizes ctxSizes; BOOL bLowMemoryIndicator;
} performhandshake(ctx, hCred, sock) CtxtHandle ctx; CredHandle hCred; SOCKET sock; {
SecPkgContext_StreamSizes ctxSizes;
struct diagose_internal diagose_internal_res; BOOL bLowMemoryIndicator = FALSE; SECURITY_STATUS acceptctxsecstat;
CtxtHandle* pctx = SecIsValidHandle(&ctx) ? &ctx : 0;
SecBufferDesc buff = { .ulVersion = SECBUFFER_VERSION,1,(SecBuffer[]) { [0] = {.BufferType = SECBUFFER_TOKEN} } }, * LastRecieved,
outbuff = { .ulVersion = SECBUFFER_VERSION,1,(SecBuffer[]) { [0] = {.BufferType = SECBUFFER_TOKEN} } },
* InBuff = &outbuff,
* OutBuff = &buff; DWORD attrs; TimeStamp nocare;
char(*d)[USHRT_MAX] = malloc(sizeof * d);
//OutBuff->pBuffers[0].cbBuffer = check_last_error_int(recv, sock, OutBuff->pBuffers[0].pvBuffer = *d, sizeof * d, 0);
do {
InBuff->pBuffers[0].cbBuffer = check_last_error_int(recv, sock, InBuff->pBuffers[0].pvBuffer = *d, sizeof * d, 0);
switch (acceptctxsecstat = diagnose(AcceptSecurityContext, &hCred, pctx, InBuff, ctxflags, 0, &ctx, OutBuff, &attrs, &nocare))
{
case SEC_I_CONTINUE_NEEDED:
case_continue_needed:
//, server, ctxflags, 0, SECURITY_NATIVE_DREP,
//diagnose(CompleteAuthToken, &ctx, OutBuff),
//OutBuff->pBuffers[0].cbBuffer = check_last_error_int(recv, sock, OutBuff->pBuffers[0].pvBuffer = *d, sizeof * d, 0),
check_last_error_int(send, sock, OutBuff->pBuffers[0].pvBuffer, OutBuff->pBuffers[0].cbBuffer, 0);
FreeContextBuffer(OutBuff->pBuffers[0].pvBuffer);
LastRecieved = OutBuff; swap_ptr64(InBuff, OutBuff);
pctx = &ctx;
break;
case SEC_I_COMPLETE_NEEDED:
case SEC_I_COMPLETE_AND_CONTINUE:
diagnose(CompleteAuthToken, pctx, OutBuff);
switch (acceptctxsecstat) {
case SEC_I_COMPLETE_NEEDED:
goto end;
case SEC_I_COMPLETE_AND_CONTINUE:
goto case_continue_needed;
}
default: goto end;
}
} while (/*OutBuff->pBuffers[0].cbBuffer != SOCKET_ERROR && OutBuff->pBuffers[0].cbBuffer*/true);
end:
diagnose(QueryContextAttributes, &ctx, SECPKG_ATTR_STREAM_SIZES, &ctxSizes);
free(d);
return (struct performhandshake) { ctx, hCred, sock, ctxSizes, bLowMemoryIndicator };
}
Here is my main function:
main() {
WSADATA wsadat; WSAStartup(MAKEWORD(2, 2), &wsadat), getaddrinfo("<local-ip>", "993", (struct addrinfo[])
{ {.ai_family = AF_INET, .ai_socktype = SOCK_STREAM, .ai_protocol = IPPROTO_TCP, .ai_flags = AI_PASSIVE}
}, & addrinfo);
InitializeCriticalSection(&crit);
HCERTSTORE hMyCertStore = NULL;
PCCERT_CONTEXT aCertContext = NULL;
//-------------------------------------------------------
// Open the My store, also called the personal store.
// This call to CertOpenStore opens the Local_Machine My
// store as opposed to the Current_User's My store.
hMyCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM,
X509_ASN_ENCODING,
0,
CERT_SYSTEM_STORE_CURRENT_USER,
L"MY");
if (hMyCertStore == NULL)
printf("Error opening MY store for server.\n");
//-------------------------------------------------------
// Search for a certificate with some specified
// string in it. This example attempts to find
// a certificate with the string "example server" in
// its subject string. Substitute an appropriate string
// to find a certificate for a specific user.
aCertContext = CertFindCertificateInStore(hMyCertStore,
X509_ASN_ENCODING,
0,
CERT_FIND_SUBJECT_STR_A,
server, // use appropriate subject name
NULL
);
if (aCertContext == NULL)
printf("Error retrieving server certificate.");
CertCloseStore(hMyCertStore, 0);
char buff[USHRT_MAX];
SOCKET conn = beginconn(&buff);
struct performhandshake reshandshake;
CredHandle hCred; TimeStamp nocare; struct diagose_internal diagose_internal_res; BOOL bLowMemoryIndicator = FALSE;
diagnose(AcquireCredentialsHandle, 0, UNISP_NAME, SECPKG_CRED_BOTH, 0, &(SCHANNEL_CRED){.dwVersion = SCHANNEL_CRED_VERSION, .hRootStore = hMyCertStore,
.cCreds = 1, .paCred = (PCCERT_CONTEXT[]){ aCertContext }, .grbitEnabledProtocols = SP_PROT_TLS1_0_SERVER }, 0, 0, & hCred, & nocare);
SecInvalidateHandle(&reshandshake.ctx) reshandshake = performhandshake(reshandshake.ctx, hCred, conn);
return;
}
And here is the whole snippet for reference:
#undef UNICODE
#include <winsock2.h>
#include <stdio.h>
#include <stdbool.h>
#define SECURITY_WIN32
#include <Security.h>
#include <Schnlsp.h>
const char server[] = "<cert-name>";
#define errprintf(...) (printf(__VA_ARGS__))
#define ctxflags (ASC_REQ_ALLOCATE_MEMORY|ASC_REQ_CONFIDENTIALITY)
#define swap(x,y)(x ^= y,y ^= x,x ^= y)
#define swap_ptr64(x,y)swap(*(ULONG64 *)&x, *(ULONG64 *)&y)
struct addrinfo* addrinfo;
static CRITICAL_SECTION crit;
static struct diagose_internal {
SECURITY_STATUS secstat;
BOOL bLowMemoryIndicator;
} diagose_internal(in, desc, line) char desc[]; SECURITY_STATUS in; {BOOL bLowMemoryIndicator = FALSE; in & 0x80000000 ? EnterCriticalSection(&crit),
errprintf("%d - %s - %lx\n", line, desc, in), bLowMemoryIndicator = SEC_E_INSUFFICIENT_MEMORY == in, LeaveCriticalSection(&crit) : 0; return (struct diagose_internal) { in, bLowMemoryIndicator }; }
#define diagnose(x, ...) (diagose_internal_res=diagose_internal(x(__VA_ARGS__),#x,__LINE__), bLowMemoryIndicator=bLowMemoryIndicator||diagose_internal_res.bLowMemoryIndicator, diagose_internal_res.secstat)
static BOOL check_last_error_internal_int(in, desc, line) char desc[]; {BOOL bLowMemoryIndicator = FALSE; int error = WSAGetLastError(); error ? EnterCriticalSection(&crit),
errprintf("%d - %s - %lx\n", line, desc, error), bLowMemoryIndicator = error == WSA_NOT_ENOUGH_MEMORY, //|| error == WSA_QOS_TRAFFIC_CTRL_ERROR,
LeaveCriticalSection(&crit) : 0; return in; }
#define check_last_error_int(x, ...) check_last_error_internal_int(x(__VA_ARGS__),#x,__LINE__)
static struct check_last_error_internal_handle {
SOCKET socket;
BOOL bLowMemoryIndicator;
} check_last_error_internal_handle(in, desc, line) char desc[]; SOCKET in; {BOOL bLowMemoryIndicator = FALSE; int error = WSAGetLastError(); error ? EnterCriticalSection(&crit),
errprintf("%d - %s - %lx\n", line, desc, error), bLowMemoryIndicator = error == WSA_NOT_ENOUGH_MEMORY, //|| error == WSA_QOS_TRAFFIC_CTRL_ERROR,
LeaveCriticalSection(&crit) : 0; return (struct check_last_error_internal_handle) { in, bLowMemoryIndicator }; }
#define check_last_error_handle(x, ...) check_last_error_internal_int(x(__VA_ARGS__),#x,__LINE__)
static SOCKET beginconn() {
SOCKET sock = check_last_error_handle(socket, addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol);
//check_last_error_int(setsockopt, sock, SOL_SOCKET, SO_RCVTIMEO, (DWORD[]) { 100 }, sizeof(DWORD)),
//check_last_error_int(setsockopt, sock, SOL_SOCKET, SO_SNDTIMEO, (DWORD[]) { 100 }, sizeof(DWORD)),
check_last_error_int(bind, sock, addrinfo->ai_addr, addrinfo->ai_addrlen),
check_last_error_int(listen, sock, SOMAXCONN);
SOCKET finalsock = accept(sock, NULL, NULL);
closesocket(sock);
return finalsock;
}
static struct performhandshake {
CtxtHandle ctx; CredHandle hCred; SOCKET sock; SecPkgContext_StreamSizes ctxSizes; BOOL bLowMemoryIndicator;
} performhandshake(ctx, hCred, sock) CtxtHandle ctx; CredHandle hCred; SOCKET sock; {
SecPkgContext_StreamSizes ctxSizes;
struct diagose_internal diagose_internal_res; BOOL bLowMemoryIndicator = FALSE; SECURITY_STATUS acceptctxsecstat;
CtxtHandle* pctx = SecIsValidHandle(&ctx) ? &ctx : 0;
SecBufferDesc buff = { .ulVersion = SECBUFFER_VERSION,1,(SecBuffer[]) { [0] = {.BufferType = SECBUFFER_TOKEN} } }, * LastRecieved,
outbuff = { .ulVersion = SECBUFFER_VERSION,1,(SecBuffer[]) { [0] = {.BufferType = SECBUFFER_TOKEN} } },
* InBuff = &outbuff,
* OutBuff = &buff; DWORD attrs; TimeStamp nocare;
char(*d)[USHRT_MAX] = malloc(sizeof * d);
//OutBuff->pBuffers[0].cbBuffer = check_last_error_int(recv, sock, OutBuff->pBuffers[0].pvBuffer = *d, sizeof * d, 0);
do {
InBuff->pBuffers[0].cbBuffer = check_last_error_int(recv, sock, InBuff->pBuffers[0].pvBuffer = *d, sizeof * d, 0);
switch (acceptctxsecstat = diagnose(AcceptSecurityContext, &hCred, pctx, InBuff, ctxflags, 0, &ctx, OutBuff, &attrs, &nocare))
{
case SEC_I_CONTINUE_NEEDED:
case_continue_needed:
//, server, ctxflags, 0, SECURITY_NATIVE_DREP,
//diagnose(CompleteAuthToken, &ctx, OutBuff),
//OutBuff->pBuffers[0].cbBuffer = check_last_error_int(recv, sock, OutBuff->pBuffers[0].pvBuffer = *d, sizeof * d, 0),
check_last_error_int(send, sock, OutBuff->pBuffers[0].pvBuffer, OutBuff->pBuffers[0].cbBuffer, 0);
FreeContextBuffer(OutBuff->pBuffers[0].pvBuffer);
LastRecieved = OutBuff; swap_ptr64(InBuff, OutBuff);
pctx = &ctx;
break;
case SEC_I_COMPLETE_NEEDED:
case SEC_I_COMPLETE_AND_CONTINUE:
diagnose(CompleteAuthToken, pctx, OutBuff);
switch (acceptctxsecstat) {
case SEC_I_COMPLETE_NEEDED:
goto end;
case SEC_I_COMPLETE_AND_CONTINUE:
goto case_continue_needed;
}
default: goto end;
}
} while (/*OutBuff->pBuffers[0].cbBuffer != SOCKET_ERROR && OutBuff->pBuffers[0].cbBuffer*/true);
end:
diagnose(QueryContextAttributes, &ctx, SECPKG_ATTR_STREAM_SIZES, &ctxSizes);
free(d);
return (struct performhandshake) { ctx, hCred, sock, ctxSizes, bLowMemoryIndicator };
}
main() {
WSADATA wsadat; WSAStartup(MAKEWORD(2, 2), &wsadat), getaddrinfo("<local-ip>", "993", (struct addrinfo[])
{ {.ai_family = AF_INET, .ai_socktype = SOCK_STREAM, .ai_protocol = IPPROTO_TCP, .ai_flags = AI_PASSIVE}
}, & addrinfo);
InitializeCriticalSection(&crit);
HCERTSTORE hMyCertStore = NULL;
PCCERT_CONTEXT aCertContext = NULL;
//-------------------------------------------------------
// Open the My store, also called the personal store.
// This call to CertOpenStore opens the Local_Machine My
// store as opposed to the Current_User's My store.
hMyCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM,
X509_ASN_ENCODING,
0,
CERT_SYSTEM_STORE_CURRENT_USER,
L"MY");
if (hMyCertStore == NULL)
printf("Error opening MY store for server.\n");
//-------------------------------------------------------
// Search for a certificate with some specified
// string in it. This example attempts to find
// a certificate with the string "example server" in
// its subject string. Substitute an appropriate string
// to find a certificate for a specific user.
aCertContext = CertFindCertificateInStore(hMyCertStore,
X509_ASN_ENCODING,
0,
CERT_FIND_SUBJECT_STR_A,
server, // use appropriate subject name
NULL
);
if (aCertContext == NULL)
printf("Error retrieving server certificate.");
CertCloseStore(hMyCertStore, 0);
char buff[USHRT_MAX];
SOCKET conn = beginconn(&buff);
struct performhandshake reshandshake;
CredHandle hCred; TimeStamp nocare; struct diagose_internal diagose_internal_res; BOOL bLowMemoryIndicator = FALSE;
diagnose(AcquireCredentialsHandle, 0, UNISP_NAME, SECPKG_CRED_BOTH, 0, &(SCHANNEL_CRED){.dwVersion = SCHANNEL_CRED_VERSION, .hRootStore = hMyCertStore,
.cCreds = 1, .paCred = (PCCERT_CONTEXT[]){ aCertContext }, .grbitEnabledProtocols = SP_PROT_TLS1_0_SERVER }, 0, 0, & hCred, & nocare);
SecInvalidateHandle(&reshandshake.ctx) reshandshake = performhandshake(reshandshake.ctx, hCred, conn);
return;
}
<local-ip> and <cert-name> hide my real local ip and server/cert name.

Unable to send image via RabbitMQ C master

I am trying to send an image via RabbitMQ C master by using its binary data as message and then transferring it and copying it onto another image file.
My code is as follows:
Client/sender:
#include "amqp_wrapper_library.h"
int main(int argc, char const *const *argv)
{
char const *hostname;
int port;
char const *exchange;
char const *routingkey;
char const *messagebody;
char const *username;
char const *password;
amqp_connection_state_t conn;
if (argc < 7) {
fprintf(stderr, "Usage: amqp_sendstring host port exchange routingkey messagebody username password\n");
return 1;
}
hostname = argv[1];
port = atoi(argv[2]);
exchange = argv[3];
routingkey = argv[4];
username = argv[5];
password = argv[6];
int length;
FILE *image1;
image1= fopen("/home/sneha/Desktop/Sender/image1.jpg", "rb");
fseek(image1, 0, SEEK_END);
length= ftell(image1);
rewind(image1);
messagebody = (char *)malloc(sizeof(char)*(length+1));
fread(messagebody, length, 1, image1);
printf("%s",messagebody);
fclose(image1);
conn = create_messagebus_context(hostname,port,username,password);
send_message_on_messagebus(conn,exchange,routingkey,messagebody);
close_messagebus_context(conn);
return 0;
}
Server/receiver:
#include "amqp_wrapper_library.h"
int main(int argc, char const *const *argv)
{
char const *hostname;
int port;
char const *exchange;
char const *bindingkey;
char const *username;
char const *password;
amqp_connection_state_t conn;
FILE *image2;
if (argc < 7) {
fprintf(stderr, "Usage: amqp_listen host port exchange bindingkey username password\n");
return 1;
}
hostname = argv[1];
port = atoi(argv[2]);
exchange = argv[3];
bindingkey = argv[4];
username = argv[5];
password = argv[6];
conn = create_messagebus_context(hostname, port, username, password);
image2 = fopen ("/home/sneha/Desktop/Receiver/image2.jpg", "wb");
char *messagebody = receive_message_on_messagebus(conn,exchange,bindingkey);
fwrite (messagebody, 1, sizeof(messagebody), image2);
printf("%s",messagebody);
fclose(image2);
close_messagebus_context(conn);
return 0;
}
amqp_wrapper_library.c
#include "amqp_wrapper_library.h"
amqp_connection_state_t create_messagebus_context(char const *hostname,int port,char const *username,char const *password)
{
amqp_socket_t *socket = NULL;
amqp_connection_state_t conn = amqp_new_connection();
socket = amqp_tcp_socket_new(conn);
if (!socket) {
die("creating TCP socket");
}
int status = amqp_socket_open(socket, hostname, port);
if (status) {
die("opening TCP socket");
}
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, username, password), "Logging in");
amqp_channel_open(conn, 1);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
return conn;
}
void close_messagebus_context(amqp_connection_state_t conn)
{
die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
die_on_error(amqp_destroy_connection(conn), "Ending connection");
}
void send_message_on_messagebus(amqp_connection_state_t conn,char const *exchange,char const *routingkey,char const *messagebody)
{
amqp_basic_properties_t props;
props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG;
props.content_type = amqp_cstring_bytes("text/plain");
props.delivery_mode = 2; /* persistent delivery mode */
die_on_error(amqp_basic_publish(conn, 1, amqp_cstring_bytes(exchange), amqp_cstring_bytes(routingkey), 0, 0, &props, amqp_cstring_bytes(messagebody)), "Publishing");
}
char* receive_message_on_messagebus(amqp_connection_state_t conn,char const *exchange,char const *bindingkey)
{
amqp_bytes_t queuename;
{
amqp_queue_declare_ok_t *r = amqp_queue_declare(conn, 1, amqp_empty_bytes, 0, 0, 0, 1, amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring queue");
queuename = amqp_bytes_malloc_dup(r->queue);
if (queuename.bytes == NULL)
{
fprintf(stderr, "Out of memory while copying queue name");
return 0;
}
}
amqp_queue_bind(conn, 1, queuename, amqp_cstring_bytes(exchange), amqp_cstring_bytes(bindingkey), amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Binding queue");
amqp_basic_consume(conn, 1, queuename, amqp_empty_bytes, 0, 1, 0, amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming");
{
//for (;;)
//{
amqp_rpc_reply_t res;
amqp_envelope_t envelope;
amqp_maybe_release_buffers(conn);
res = amqp_consume_message(conn, &envelope, NULL, 0);
if (AMQP_RESPONSE_NORMAL != res.reply_type)
{
return;
}
char *result = (char *)malloc((int) envelope.message.body.len);
sprintf(result,"%.*s",(int) envelope.message.body.len, (char *) envelope.message.body.bytes);
amqp_destroy_envelope(&envelope);
return result;
//}
}
}
However, the image2 is nt getting reconstructed. I checked image size, the sizes of both images do not match. What is the issue here?
Data from a JPEG file is not a c-string (null-terminated string of bytes), thus functions like printf and amqp_cstring_bytes that expect a null-terminated strings cannot be used to handle the image data.
Instead of using a const char* to hold the jpg data, use an amqp_bytes_t struct in your code.
To read from a file into an struct amqp_bytes_t
amqp_bytes_t msg = amqp_bytes_alloc(length);
/* Make sure that allocation succeeded */
assert(msg.bytes != NULL);
fread(msg.bytes, msg.len, 1, image1);
...
/* Free the memory when you're done with it */
amqp_bytes_free(msg);
Do the reverse to write it back out:
/* if you wish to create a copy of the message body
* free it using amqp_bytes_free */
amqp_bytes_t msg = amqp_bytes_malloc_dup(envelope.message.body);
fwrite(msg.bytes, msg.len, 1, image2);
Edit: add sample code.

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

Emit signal is not happening in bluez dbus

I wrote some basic code to access the "start inquiry" bluez functionality by using dbus api's. Start Inquiry is happening that I could saw on hcidump. But I am not receiving any signal from the dbus which is "DeviceFound". I have tried lot. I tried to use different dbus tools like d-feet, dbus-monitor, bustle but I couln't got any clue.
Below is my written code. Anyone please tell me why this code is not working.
#include <stdio.h>
#include <stdlib.h>
#include <dbus/dbus.h>
#include <glib.h>
struct generic_data {
unsigned int refcount;
GSList *interfaces;
char *introspect;
};
static void unregister(DBusConnection *connection, void *user_data)
{
}
static DBusHandlerResult filter_func(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
printf("Signal is called \n");
if (dbus_message_is_signal(message, "org.bluez.Adapter",
"DeviceFound"))
{
const char *adapter, *bdaddr;
char *name;
DBusMessageIter iter;
dbus_message_iter_init(message, &iter);
dbus_message_iter_get_basic(&iter, &bdaddr);
printf("Finally found device address is %s\n", bdaddr);
}
}
static DBusObjectPathVTable generic_table = {
.unregister_function = unregister,
.message_function = filter_func,
};
int main(int argc, char **argv) {
DBusConnection *conn;
DBusError error;
DBusMessage *msg, *reply,*signal;
dbus_bool_t hcid_exists,start;
DBusMessageIter reply_iter;
const char *name,*address;
char *adapter, *match;
DBusMessageIter iter;
struct generic_data *data;
va_list var_args;
static GMainLoop *loop = NULL;
conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
dbus_error_init(&error);
hcid_exists = dbus_bus_name_has_owner(conn, "org.bluez", &error);
if(hcid_exists)
printf("good news hurrey\n");
/* Get the default adapter */
msg = dbus_message_new_method_call("org.bluez", "/", "org.bluez.Manager", "DefaultAdapter");
if (msg == NULL) {
dbus_connection_unref(conn);
return FALSE;
}
reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &error);
dbus_message_unref(msg);
if (dbus_error_is_set(&error))
{
dbus_connection_unref(conn);
}
dbus_message_iter_init(reply, &reply_iter);
if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_OBJECT_PATH)
{
dbus_message_unref(reply);
dbus_connection_unref(conn);
return FALSE;
}
dbus_message_iter_get_basic(&reply_iter, &adapter);
adapter = g_strdup(adapter);
//printf("Ohhhh gooood finally got adapter name %s\n",adapter);
dbus_message_unref(reply);
data = g_new0(struct generic_data, 1);
if (!dbus_connection_register_object_path(conn,adapter,&generic_table, data)) {
g_free(data->introspect);
g_free(data);
return FALSE;
}
if (!dbus_connection_add_filter(conn, filter_func, data, g_free))
{
g_free(adapter);
dbus_connection_unref(conn);
return FALSE;
}
if(conn!=NULL)
msg = dbus_message_new_method_call("org.bluez",adapter,"org.bluez.Adapter", "StartDiscovery");
else
printf("conn is failed\n");
if(msg!=NULL)
start = dbus_connection_send_with_reply(conn, msg,NULL,-1);
else
printf("msg is failed\n");
if(start)
{
//printf("Main llop hasd tp start\n");
loop = g_main_loop_new(NULL, TRUE);
g_main_loop_run(loop);
}
dbus_message_unref(msg);
dbus_message_unref(reply);
dbus_connection_close(conn);
return 0;
}

Resources