Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[paho-dev] message not correctly received using paho.mqtt.c

Hi,

I am trying to send a specific message type using the MQTT protocol. I am using the paho.mqtt.c library, and my broker is RabbitMQ 3.6.12, running Erlang 20.0. I am working on a virtual machine running CentOS 6.9. I first tried doing it by creating a struct for my specific message type, like so :

typedef struct frame1
{
    char* str;
    int entier;
} frame1;

This is my publisher program :

int main(int argc, char* argv[])
{   
    frame1* payload = (frame1*)malloc(sizeof(frame1));
    *p_entier = atoi(argv[2]);
    p_str = argv[1];

    //int p_entier = atoi(argv[2]);
    //char* p_str = argv[1];
    //payload->str = (char*)malloc(100*sizeof(char));
    //payload->str = p_str;
    //payload->entier = (int*)malloc(sizeof(int));
    //payload->entier = p_entier;

    MQTTClient publisher;
    MQTTClient_connectOptions connexion = MQTTClient_connectOptions_initializer;
    MQTTClient_message msg = msg_creation(payload,sizeof(frame1),0,0);
    int rc;
    MQTTClient_create(&publisher, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
    connexion.cleansession = 1;
    MQTTClient_setCallbacks(publisher, NULL, connlost, frame_1_arrvd, NULL);
    if ((rc = MQTTClient_connect(publisher,&connexion)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to connect, return code %d\n", rc);
    }
    printf("message à envoyer : \n");
    print_frame1(msg.payload);
    MQTTClient_publishMessage(publisher, TOPIC,&msg,NULL);
    printf("Message sent!\n");
    MQTTClient_disconnect(publisher,10000);
    MQTTClient_destroy(&publisher);
    return rc;
}

Here is the print_frame1 function :

void print_frame1(frame1* F)
{
    printf("%s : %d\n",F->str,F->entier);
}

and msg_creation :

MQTTClient_message msg_creation(void* payload, int length, int qos, int retained)
{
    MQTTClient_message pubmsg = MQTTClient_message_initializer;
    pubmsg.payload = payload;
    pubmsg.payloadlen = length;
    pubmsg.qos = qos;
    pubmsg.retained = retained;
    return pubmsg;
}

and the function used to receive the messages :

int frame_1_arrvd(void* context, char* topicName, int topicLen, MQTTClient_message* msg)
{
    int i;
    print_frame1(msg->payload);

    frame1* payload; //= (frame1*)malloc(sizeof(frame1));
    payload->str = (char*)malloc(100*sizeof(char));
    payload = msg->payload; 
    print_frame1(payload);

    printf("New message!\n     in topic %s:\n", topicName);
    printf("%s : %d\n",payload->str,payload->entier);*/

    MQTTClient_freeMessage(&msg);
    MQTTClient_free(topicName);
    return 1;
}

The parts I commented are things I tried but didn't work any better. What I mean when I say that it doesn't work is that the first print_frame1 on the receiver side results in a segmentation fault (core dumped). It appears something is received, but not the expected string. After investigating the core dumped, I tried replacing %s by %c in the print_frame1 function, and I didn't get a segmentation fault anymore, but rather a character that had nothing to do with the string that was supposed to be sent (like, I would usually get a number or a special character).

At first I thought maybe the problem came from the way I created the message, but print_frame1(msg.payload) in the publisher code works fine, so I assume the message is correctly created, and yet it is not correctly sent or received.

Before asking this question, I also tried using JSON to create my specific message type. I installed cJSON (from here), and tried creating my frame this way :

cJSON* create_frame1(char* str, int entier)
{
    cJSON* frame1 = NULL;
    frame1 = cJSON_CreateObject();
    cJSON_AddStringToObject(frame1,"string",str);
    cJSON_AddNumberToObject(frame1,"entier", entier);
    return frame1;
}

And I changed my publisher to this :

int main(int argc, char* argv[])
{   
    int p_entier = atoi(argv[2]);
    char* p_str = argv[1];

    cJSON* payload = create_frame1(p_str,p_entier);
    print_frame1(payload);

    MQTTClient publisher;
    MQTTClient_connectOptions connexion = MQTTClient_connectOptions_initializer;
    MQTTClient_message msg = msg_creation(payload,sizeof(payload),0,0);
    int rc;
    MQTTClient_create(&publisher, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
    connexion.cleansession = 1;
    MQTTClient_setCallbacks(publisher, NULL, connlost, frame_1_arrvd, NULL);
    if ((rc = MQTTClient_connect(publisher,&connexion)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to connect, return code %d\n", rc);
    }
    printf("message à envoyer : \n");
    print_frame1(msg.payload);
    MQTTClient_publishMessage(publisher, TOPIC,&msg,NULL);
    printf("Message sent!\n");
    MQTTClient_disconnect(publisher,10000);
    MQTTClient_destroy(&publisher);
    return rc;
}

I also modified the print_frame1 function :

void print_frame1(cJSON* frame1)
{
    //printf("%s",cJSON_GetObjectItem(frame1,"string"));
    //printf("  %d\n",cJSON_GetObjectItem(frame1,"entier"));
    char * str = cJSON_Print(frame1);
    printf("%s\n",str);
    //printf("%s    %d \n",str,entier);
}

and the receiving part :

int frame_1_arrvd(void* context, char* topicName, int topicLen, MQTTClient_message* msg)
{
    int i;
    print_frame1(msg->payload);
    cJSON* payload_ptr;
    payload_ptr = msg->payload;
    print_frame1(payload_ptr);
    cJSON_Delete(payload_ptr);

    MQTTClient_freeMessage(&msg);
    MQTTClient_free(topicName);
    return 1;
}

But the result is exactly the same : printing msg->payload on the publisher side works fine so it looks like the message is correctly created, but I get a segmentation fault (core dumped) at the first print_frame1(msg->payload) on the receiving side. The seg fault however appears to be for a different reason than previously.

Here is what I get when I run gdb :

Program terminated with signal 11, Segmentation fault.
#0  __strlen_sse2 () at ../sysdeps/x86_64/strlen.S:32
32              movdqu  (%rdi), %xmm1

I thought JSON would solve my problem, but either I am using it wrong or there is something deeper going on. I think maybe the problem could come from sizeof(payload) in the message creation, but at this point I am very confused.

I just looked into cJSON yesterday, so I will keep investigating in case I am using it wrong, but any help would be appreciated.


Back to the top