Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting the MQTT keepalive using a *_SetOption function #2663

Open
bertulli opened this issue Jan 20, 2025 · 0 comments
Open

Setting the MQTT keepalive using a *_SetOption function #2663

bertulli opened this issue Jan 20, 2025 · 0 comments
Labels

Comments

@bertulli
Copy link

Hi, thank you for your work. I'm trying to set up an Azure IotHub client with the C SDK, and I noticed that if I don't send out a new MQTT message every 10 seconds, the connection to the Hub is closed. I'd like to increase this timeout, and I think the option I need is "keepalive" (OPTION_KEEP_ALIVE, see this doc page). However, if I try to do

IOTHUB_DEVICE_CLIENT_LL_HANDLE device_ll_handle;
// [...]
int keepalive = 20;
IoTHubTransport_MQTT_Common_SetOption(device_ll_handle, OPTION_KEEP_ALIVE, &keepalive);
// [...]
device_ll_handle = IoTHubDeviceClient_LL_CreateFromConnectionString(connection_string, iothub_transport)

in the code opening the device handle, I end up with a SEGFAULT, because it detects the connection as already open, and it tries to disconnect with DisconnectFromClient(transport_data). I can't find in the doc how to set this option: where should I set it? Thanks!

A MWE:

typedef struct CLIENT_SAMPLE_INFO_TAG
{
  PROV_DEVICE_LL_HANDLE handle;
  unsigned int sleep_time_msec;
  char* iothub_uri;
  char* device_id;
  bool registration_complete;
} CLIENT_SAMPLE_INFO;

PROV_DEVICE_TRANSPORT_PROVIDER_FUNCTION prov_transport;

CLIENT_SAMPLE_INFO azure_init() {

  CLIENT_SAMPLE_INFO user_ctx;

  (void)IoTHub_Init();
  (void)prov_dev_security_init(SECURE_DEVICE_TYPE_X509);

  memset(&user_ctx, 0, sizeof(CLIENT_SAMPLE_INFO));

  // Protocol to USE
  prov_transport = Prov_Device_MQTT_Protocol;

  user_ctx.registration_complete = false;
  user_ctx.sleep_time_msec = 10;

  LOG(INFO) << "Provisioning API Version: " << Prov_Device_LL_GetVersionString();
  LOG(INFO) << "Iothub API Version: " << IoTHubClient_GetVersionString();

  return user_ctx;
}

IOTHUB_DEVICE_CLIENT_LL_HANDLE open_iothub(const std::string &connection_string,
                                           const CLIENT_SAMPLE_INFO &azure_ctx,
                                           const std::string &x509_certificate,
                                           const std::string &x509_key) {
  const CLIENT_SAMPLE_INFO user_ctx{azure_ctx};
  IOTHUB_DEVICE_CLIENT_LL_HANDLE device_ll_handle;

  // Protocol to USE
  iothub_transport = MQTT_Protocol;

  // int keepalive = 20;
  // IoTHubTransport_MQTT_Common_SetOption(device_ll_handle, OPTION_KEEP_ALIVE, &keepalive);

  LOG(INFO) << "Creating IoTHub Device handle";  
  if ((device_ll_handle = IoTHubDeviceClient_LL_CreateFromConnectionString(connection_string.c_str(), iothub_transport) ) == NULL)
    {
      LOG(ERROR) << "failed create IoTHub client " << user_ctx.iothub_uri << "!";
      return nullptr;
    }
  else
    {
      iothub_info.stop_running = false;
      iothub_info.connected = false;

      (void)IoTHubDeviceClient_LL_SetConnectionStatusCallback(device_ll_handle, iothub_connection_status, &iothub_info);

      // Set any option that are necessary.
      // For available options please see the iothub_sdk_options.md documentation
      bool traceOn = true;
      IoTHubDeviceClient_LL_SetOption(device_ll_handle, OPTION_LOG_TRACE, &traceOn);
      int keepalive = 20;
      IoTHubTransport_MQTT_Common_SetOption(device_ll_handle, OPTION_KEEP_ALIVE, &keepalive);

      //Setting the auto URL Encoder (recommended for MQTT). Please use this option unless
      //you are URL Encoding inputs yourself.
      //ONLY valid for use with MQTT
      bool urlEncodeOn = true;
      (void)IoTHubDeviceClient_LL_SetOption(device_ll_handle, OPTION_AUTO_URL_ENCODE_DECODE, &urlEncodeOn);

      // Set the X509 certificates in the SDK
      if (
          (IoTHubDeviceClient_LL_SetOption(device_ll_handle, OPTION_X509_CERT, x509_certificate.c_str()) != IOTHUB_CLIENT_OK) ||
          (IoTHubDeviceClient_LL_SetOption(device_ll_handle, OPTION_X509_PRIVATE_KEY, x509_key.c_str()) != IOTHUB_CLIENT_OK)
          )
        {
          LOG(ERROR) << "failure to set options for x509, aborting";
        }

        (void)IoTHubDeviceClient_LL_SetMessageCallback(
            device_ll_handle, receive_msg_callback, &iothub_info);
        LOG(INFO) << "Opened IoTHub connection via connection string " << connection_string;
      return device_ll_handle;
    }  
}

int main() {

    auto azure_connection = azure_helpers::azure_init();

    auto iot_handle = azure_helpers::open_iothub("HostName=XXXXXXXXXXXXXX.azure-devices.net;DeviceId=test2;x509=true",
                                                 azure_connection,
                                                 x509certificate, // read from file
                                                 x509privatekey); // read from file

}

with output

Provisioning API Version: 1.14.0
Iothub API Version: 1.14.0
Creating IoTHub Device handle
Error: Time:Tue Jan 20 09:41:58 2025 File:/home/abertulli/<project_root>/azure-iot-sdk-c/iothub_client/src/iothub_client_authorization.c Func:IoTHubClient_Auth_Get_Credential_Type Line:361 Invalid Parameter handle: (nil)
Segmentation fault
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant