Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions .vscode/settings.json

This file was deleted.

258 changes: 156 additions & 102 deletions include/anedya_client.h
Original file line number Diff line number Diff line change
@@ -1,126 +1,180 @@
#pragma once

#include <stdlib.h>
#include "anedya_err.h"
#include "anedya_commons.h"
#include "anedya_config.h"
#include "anedya_err.h"
#include "anedya_sdk_config.h"
#include "anedya_txn.h"
#include <stdlib.h>

#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif

struct anedya_txn_store_t
{
anedya_txn_t *txns[ANEDYA_MAX_CONCURRENT_TXN];
bool txn_slot_free[ANEDYA_MAX_CONCURRENT_TXN];
int64_t aquired_time[ANEDYA_MAX_CONCURRENT_TXN];
bool _lock;
};

typedef struct anedya_txn_store_t anedya_txn_store_t;

typedef void (*anedya_on_connect_handler_t)(anedya_client_t *client);
typedef void (*anedya_on_disconnect_handler_t)(anedya_client_t *client);
typedef void (*anedya_message_handler_t)(anedya_client_t *cl, char *topic, int topic_len, char *payload, int payload_len);
struct anedya_client_t
{
anedya_config_t *config;
struct anedya_txn_store_t {
anedya_txn_t *txns[ANEDYA_MAX_CONCURRENT_TXN];
bool txn_slot_free[ANEDYA_MAX_CONCURRENT_TXN];
int64_t aquired_time[ANEDYA_MAX_CONCURRENT_TXN];
bool _lock;
};

typedef struct anedya_txn_store_t anedya_txn_store_t;

typedef void (*anedya_on_connect_handler_t)(anedya_client_t *client);
typedef void (*anedya_on_disconnect_handler_t)(anedya_client_t *client);
typedef void (*anedya_message_handler_t)(anedya_client_t *cl, char *topic,
int topic_len, char *payload,
int payload_len);
struct anedya_client_t {
anedya_config_t *config;
#ifdef ANEDYA_ENABLE_STATIC_ALLOCATION
char log_buffer[ANEDYA_LOG_BUFFER * ANEDYA_MAX_LOG_BATCH];
char _message_topics[4][100];
char log_buffer[ANEDYA_LOG_BUFFER * ANEDYA_MAX_LOG_BATCH];
char _message_topics[4][100];
#endif
#ifdef ANEDYA_ENABLE_DYNAMIC_ALLOCATION
char *tx_buffer;
char *rx_buffer;
#ifdef ANEDYA_ENABLE_DEVICE_LOGS
char *log_buffer;
char *log_buffer;
#endif
char *_message_topics[3];
char *_message_topics[3];
#endif
#ifdef ANEDYA_CONNECTION_METHOD_MQTT
anedya_mqtt_client_handle_t mqtt_client;
anedya_message_handler_t _message_handler;
anedya_on_connect_handler_t _anedya_on_connect_handler;
anedya_on_disconnect_handler_t _anedya_on_disconnect_handler;
uint8_t is_connected;
char broker_url[100];
anedya_mqtt_client_handle_t mqtt_client;
anedya_message_handler_t _message_handler;
anedya_on_connect_handler_t _anedya_on_connect_handler;
anedya_on_disconnect_handler_t _anedya_on_disconnect_handler;
char broker_url[100];
anedya_event_handler_t _event_handler;
#endif
#ifdef ANEDYA_CONNECTION_METHOD_HTTP
char http_base_url[100]; // e.g. "device.ap-in-1.anedya.io"
#endif
uint8_t is_connected;
anedya_txn_store_t txn_store;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The anedya_client_t structure is missing the tx_buffer and rx_buffer members, which are required when ANEDYA_ENABLE_DYNAMIC_ALLOCATION is defined, as seen in the initialization code in src/anedya_client.c (lines 22 and 25). This will result in a compilation error.

Copy link
Copy Markdown
Collaborator Author

@surajmaurya-git surajmaurya-git May 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

};

/**
* @brief Initialize the Anedya client with the provided configuration.
*
* This function initializes an Anedya client instance using the specified
* configuration parameters. It allocates required buffers and sets up MQTT
* connection if `ANEDYA_CONNECTION_METHOD_MQTT` is defined.
*
* @param[in] config Pointer to the `anedya_config_t` structure containing
* configuration parameters.
* @param[out] client Pointer to the `anedya_client_t` structure to initialize.
*
* @retval - `ANEDYA_OK` if the client initialization is successful.
* @retval - `ANEDYA_ERR_NO_MEMORY` if memory allocation for any buffer fails.
* @retval Other error codes based on initialization failures.
*
* @warning Ensure that the configuration is properly populated before calling
* this function.
*/
anedya_err_t anedya_client_init(anedya_config_t *config,
anedya_client_t *client);

anedya_err_t _anedya_txn_store_init(anedya_txn_store_t *store);
anedya_err_t _anedya_txn_store_aquire_slot(anedya_txn_store_t *store,
anedya_txn_t *txn);
anedya_err_t _anedya_txn_store_release_slot(anedya_txn_store_t *store,
anedya_txn_t *txn);
#ifdef ANEDYA_CONNECTION_METHOD_HTTP
void _anedya_handle_http_txn_response(anedya_client_t *cl, char *payload,
int payload_len, anedya_txn_t *txn);
#endif
anedya_event_handler_t _event_handler;
anedya_txn_store_t txn_store;
};

/**
* @brief Initialize the Anedya client with the provided configuration.
*
* This function initializes an Anedya client instance using the specified configuration parameters.
* It allocates required buffers and sets up MQTT connection if `ANEDYA_CONNECTION_METHOD_MQTT` is defined.
*
* @param[in] config Pointer to the `anedya_config_t` structure containing configuration parameters.
* @param[out] client Pointer to the `anedya_client_t` structure to initialize.
*
* @retval - `ANEDYA_OK` if the client initialization is successful.
* @retval - `ANEDYA_ERR_NO_MEMORY` if memory allocation for any buffer fails.
* @retval Other error codes based on initialization failures.
*
* @warning Ensure that the configuration is properly populated before calling this function.
*/
anedya_err_t anedya_client_init(anedya_config_t *config, anedya_client_t *client);

anedya_err_t _anedya_txn_store_init(anedya_txn_store_t *store);
anedya_err_t _anedya_txn_store_aquire_slot(anedya_txn_store_t *store, anedya_txn_t *txn);
anedya_err_t _anedya_txn_store_release_slot(anedya_txn_store_t *store, anedya_txn_t *txn);
void _anedya_handle_txn_response(anedya_client_t *cl, char *payload, int payload_len, uint8_t topic);
void _anedya_handle_event(anedya_client_t *cl, char *payload, int payload_len, uint8_t topic);

void _anedya_handle_txn_response(anedya_client_t *cl, char *payload,
int payload_len, uint8_t topic);

void _anedya_handle_event(anedya_client_t *cl, char *payload, int payload_len,
uint8_t topic);

#ifdef ANEDYA_CONNECTION_METHOD_MQTT
/**
* @brief Connect the Anedya client to the server.
*
* This function establishes a connection to the server using the client's MQTT client instance.
*
* @param[in] client Pointer to the `anedya_client_t` structure representing the client to connect.
*
* @retval - `ANEDYA_OK` if the connection is successful.
* @retval Error code if the connection fails, as returned by `_anedya_interface_mqtt_connect`.
*
* @note Ensure that the client is properly initialized before attempting to connect.
* @warning This function should be called only after initializing the client.
*/
anedya_err_t anedya_client_connect(anedya_client_t *client);

/**
* @brief Disconnect the Anedya client from the server.
*
* This function disconnects the Anedya client from the server.
*
* @param[in] client Pointer to the `anedya_client_t` structure representing the client to disconnect.
*
* @retval - `ANEDYA_OK` if the disconnection is successful.
* @retval - Error code if the disconnection fails, as returned by `_anedya_interface_mqtt_disconnect`.
*
* @note Ensure that the client is connected before calling this function.
*/
anedya_err_t anedya_client_disconnect(anedya_client_t *client);

/**
* @brief Destroy the Anedya client instance.
*
* This function releases resources associated with the Anedya client's MQTT client instance.
*
* @param[in] client Pointer to the `anedya_client_t` structure representing the client to destroy.
*
* @retval - `ANEDYA_OK` if the client instance is successfully destroyed.
* @retval - Error code if destruction fails, as returned by `_anedya_interface_mqtt_destroy`.
*
* @note Ensure that the client is disconnected before calling this function.
*/
anedya_err_t anedya_client_destroy(anedya_client_t *client);

void _anedya_message_handler(anedya_client_t *cl, char *topic, int topic_len, char *payload, int payload_len);
void _anedya_on_connect_handler(anedya_client_t *client);
void _anedya_on_disconnect_handler(anedya_client_t *client);
/**
* @brief Connect the Anedya client to the server.
*
* This function establishes a connection to the server using the client's MQTT
* client instance.
*
* @param[in] client Pointer to the `anedya_client_t` structure representing the
* client to connect.
*
* @retval - `ANEDYA_OK` if the connection is successful.
* @retval Error code if the connection fails, as returned by
* `_anedya_interface_mqtt_connect`.
*
* @note Ensure that the client is properly initialized before attempting to
* connect.
* @warning This function should be called only after initializing the client.
*/
anedya_err_t anedya_client_connect(anedya_client_t *client);

/**
* @brief Disconnect the Anedya client from the server.
*
* This function disconnects the Anedya client from the server.
*
* @param[in] client Pointer to the `anedya_client_t` structure representing the
* client to disconnect.
*
* @retval - `ANEDYA_OK` if the disconnection is successful.
* @retval - Error code if the disconnection fails, as returned by
* `_anedya_interface_mqtt_disconnect`.
*
* @note Ensure that the client is connected before calling this function.
*/
anedya_err_t anedya_client_disconnect(anedya_client_t *client);

/**
* @brief Destroy the Anedya client instance.
*
* This function releases resources associated with the Anedya client's MQTT
* client instance.
*
* @param[in] client Pointer to the `anedya_client_t` structure representing the
* client to destroy.
*
* @retval - `ANEDYA_OK` if the client instance is successfully destroyed.
* @retval - Error code if destruction fails, as returned by
* `_anedya_interface_mqtt_destroy`.
*
* @note Ensure that the client is disconnected before calling this function.
*/
anedya_err_t anedya_client_destroy(anedya_client_t *client);

void _anedya_message_handler(anedya_client_t *cl, char *topic, int topic_len,
char *payload, int payload_len);
void _anedya_on_connect_handler(anedya_client_t *client);
void _anedya_on_disconnect_handler(anedya_client_t *client);

#endif

#ifdef ANEDYA_CONNECTION_METHOD_HTTP
/**
* @brief Initialize HTTP mode client as "connected" (stateless — no persistent
* TCP).
*
* In HTTP mode there is no long-lived connection to establish. This function
* simply validates the configuration, builds the base URL, and marks
* is_connected = 1 so that all operation functions can proceed.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is_connected = 1 is misleading when there is no connection. Client programs can break when there is no internet but called client_connect by changing connection method to HTTP by mistake. As programs can simply call is_connected and see it is set to 1 while ther might be situation that device isn't even connected. In fact I suggest that we remove anedya_client_connect from HTTP altogether when HTTP mode is selcted, as there's literally nothing to connect.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or other option is throw ANEDYA_UNSUPPORTED_FUNCTION error. The only purpose is if we don't do this users will never know the failure until it happens, as same code which was written for MQTT for checking connection status will keep workign with HTTP mode until operations do not work. That will be a silent failure.

*
* @param[in] client Pointer to the anedya_client_t to operate on.
* @retval ANEDYA_OK always.
*/
anedya_err_t anedya_client_connect(anedya_client_t *client);

/**
* @brief Mark HTTP mode client as disconnected.
*
* Sets is_connected = 0. Subsequent operation calls will return
* ANEDYA_ERR_NOT_CONNECTED.
*
* @param[in] client Pointer to the anedya_client_t to operate on.
* @retval ANEDYA_OK always.
*/
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same applies for disconnect, I suggest remove these methods from HTTP mode. This will force users to handle things as per MQTT or HTTP.

anedya_err_t anedya_client_disconnect(anedya_client_t *client);
#endif

#ifdef __cplusplus
Expand Down
54 changes: 54 additions & 0 deletions include/anedya_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,60 @@ extern "C"

#endif

#ifdef ANEDYA_CONNECTION_METHOD_HTTP

/**
* @brief Perform a synchronous HTTP POST request to the Anedya server.
*
* This interface function must be implemented by the platform layer. It is responsible
* for performing a TLS-secured HTTP POST request to the Anedya REST API.
*
* Authentication headers (`Auth-mode: key` and `Authorization: <connection_key>`) must
* be set by the implementation using client->config->connection_key.
*
* @param[in] client Pointer to the anedya_client_t (used to access config/region/key).
* @param[in] path The HTTP path to POST to, e.g. "/v1/submitData".
* @param[in] payload JSON payload string (null-terminated).
* @param[in] payload_len Length of payload.
* @param[out] resp_buf Pre-allocated buffer where the response body will be written.
* @param[in] resp_buf_size Size of resp_buf.
* @param[out] resp_len Actual number of bytes written into resp_buf.
*
* @retval ANEDYA_OK on HTTP 200 success.
* @retval ANEDYA_ERR on any transport/TLS/HTTP error.
*/
anedya_err_t _anedya_interface_http_post(
anedya_client_t *client,
const char *path,
const char *payload,
int payload_len,
char *resp_buf,
int resp_buf_size,
int *resp_len);

/**
* @brief Perform a synchronous HTTP GET request to the Anedya server.
*
* Identical contract to _anedya_interface_http_post but uses GET method and sends no body.
* Reserved for future use; currently all Anedya endpoints use POST.
*
* @param[in] client Pointer to the anedya_client_t.
* @param[in] path The HTTP path to GET.
* @param[out] resp_buf Pre-allocated response buffer.
* @param[in] resp_buf_size Size of resp_buf.
* @param[out] resp_len Actual bytes written.
*
* @retval ANEDYA_OK on success, ANEDYA_ERR on failure.
*/
anedya_err_t _anedya_interface_http_get(
anedya_client_t *client,
const char *path,
char *resp_buf,
int resp_buf_size,
int *resp_len);

#endif /* ANEDYA_CONNECTION_METHOD_HTTP */

#ifdef __cplusplus
}
#endif
Loading