This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to code one-shot mqtt publish function?

I'm trying to make a one-shot mqtt function. The process is below

- connect
- publish
- disconnect

Then I coded like below. I show only the core code.

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
static u8_t payload_buf[CONFIG_MQTT_PAYLOAD_BUFFER_SIZE];
/**@brief Initialize the file descriptor structure used by poll.
*/
static int fds_init(struct mqtt_client *c)
{
if (c->transport.type == MQTT_TRANSPORT_NON_SECURE) {
fds.fd = c->transport.tcp.sock;
} else {
#if defined(CONFIG_MQTT_LIB_TLS)
fds.fd = c->transport.tls.sock;
#else
return -ENOTSUP;
#endif
}
fds.events = POLLIN;
return 0;
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Do I have to execute fds_init in send_one_shot_mqtt_msg everytime it publish a message on MQTT?

Should I omit fds_init? 

I really don't understand what fds_init does. 

I would appreciate it if you help me.

  • Hi Yusuke,

    The fds_init function initializes the "File Descriptor Structure" used by the poll function.

    In that function, it either sets it up to use non-secure TCP transport for MQTT connections OR secure TCP transport for MQTT connections.

    This is dependent if you have enabled TLS or not in the configuration.

    e.g. set this in prj.conf:

    Fullscreen
    1
    CONFIG_MQTT_LIB_TLS=y
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • Hi, Martin.

    I mean, 

    do I have to execute fds_init in send_one_shot_mqtt_msg every time a MQTT message is published?

    Or is it ok to execute fds_init  once and repeatedly use the file descriptor?

  • Hi Yusuke,

    So when you run the mqtt_disconnect() and poll() afterward, the socket will be closed as far as I know so you would need to set up a new one next time.

    That means that you need to run fds_init() each time.

  • Hi there,

    I'm using this one shot technique.  All is well until I reach 22 publishes, after which the code hangs in the mqtt_transport_write function in mqtt_transport.c

    I've tried all kinds of permutations of this but I can;t get past this hang up.  Any insight?

  • Hello everyone,

    I'm doing a routine quite like Yusuke, and would like to share my experience if others have the same issues.

    I am only calling the fds_init once in the setup and polling works fine. I get retained messages on subscribed topics, and get ack on sent my messages.

    My one-shot-function is otherwise similar to Yusukes. However, I had problems with "Failed to open socket, error: 23" after several connections (this also prevented me from getting cell location from nRF Cloud).

    It seems the mqtt_disconnect-function does not close the socket, and limitations here cause trouble. I am now calling mqtt_abort after mqtt_disconnect, and this solves the issue for me.

    Description of mqtt_abort:
    "API to abort MQTT connection. This will close the corresponding transport without closing the connection gracefully at the MQTT level (with disconnect message)."

    Combining these two seems to work fine, enabling "one shot mqtt" with the mqtt.c library. Another solution could be to use the BSD library (https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.4.2/nrfxlib/bsdlib/README.html)