Real-world examples showing how to use the OddSockets C SDK in embedded systems, IoT devices, and resource-constrained environments
Download Basic Example#include "oddsockets.h"
int main() {
// Initialize configuration
oddsockets_config_t config;
oddsockets_config_init(&config, "ak_live_1234567890abcdef");
// Create client
oddsockets_client_t* client = oddsockets_create(&config);
// Connect and create channel
oddsockets_connect(client);
oddsockets_channel_t* channel = oddsockets_channel_create(client, "my-channel");
// Subscribe and publish
oddsockets_channel_subscribe(channel, on_message, NULL, NULL);
oddsockets_channel_publish(channel, "Hello from C SDK!", NULL);
// Event loop
while (oddsockets_get_state(client) == ODDSOCKETS_STATE_CONNECTED) {
oddsockets_process_events(client);
usleep(10000); // 10ms
}
// Cleanup
oddsockets_channel_destroy(channel);
oddsockets_destroy(client);
return 0;
}
#include "FreeRTOS.h"
#include "task.h"
#include "oddsockets.h"
void oddsockets_task(void *pvParameters) {
oddsockets_config_t config;
oddsockets_config_init(&config, "your-api-key");
// Use FreeRTOS heap
oddsockets_set_memory_functions(pvPortMalloc, vPortFree, pvPortRealloc);
oddsockets_client_t* client = oddsockets_create(&config);
oddsockets_connect(client);
oddsockets_channel_t* channel = oddsockets_channel_create(client, "freertos-channel");
oddsockets_channel_subscribe(channel, on_message, NULL, NULL);
while (1) {
oddsockets_process_events(client);
vTaskDelay(pdMS_TO_TICKS(10)); // 10ms delay
}
}
void app_main() {
xTaskCreate(oddsockets_task, "oddsockets", 4096, NULL, 5, NULL);
}
#include
#include "oddsockets.h"
const char* ssid = "your-wifi";
const char* password = "your-password";
oddsockets_client_t* client;
void setup() {
Serial.begin(115200);
// Connect to WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
// Initialize OddSockets
oddsockets_config_t config;
oddsockets_config_init(&config, "your-api-key");
client = oddsockets_create(&config);
oddsockets_connect(client);
// Create sensor data channel
oddsockets_channel_t* channel = oddsockets_channel_create(client, "sensor-data");
oddsockets_channel_subscribe(channel, on_message, NULL, NULL);
}
void loop() {
oddsockets_process_events(client);
// Send sensor data every 5 seconds
static unsigned long lastSend = 0;
if (millis() - lastSend > 5000) {
char data[64];
snprintf(data, sizeof(data), "{\"temperature\":%.1f,\"humidity\":%.1f}",
25.5, 60.2);
oddsockets_channel_t* channel = oddsockets_channel_create(client, "sensor-data");
oddsockets_channel_publish(channel, data, NULL);
lastSend = millis();
}
delay(10);
}
// Enable static allocation at compile time
#define ODDSOCKETS_ENABLE_STATIC_ALLOCATION
// Pre-allocated memory pools
static uint8_t client_memory[ODDSOCKETS_CLIENT_SIZE];
static uint8_t channel_memory[ODDSOCKETS_MAX_CHANNELS][ODDSOCKETS_CHANNEL_SIZE];
static uint8_t message_buffer[ODDSOCKETS_MAX_MESSAGE_SIZE];
// Memory pool management
static size_t memory_pool_used = 0;
static uint8_t memory_pool[8192]; // 8KB pool
void* embedded_malloc(size_t size) {
if (memory_pool_used + size > sizeof(memory_pool)) {
return NULL; // Out of memory
}
void* ptr = &memory_pool[memory_pool_used];
memory_pool_used += size;
return ptr;
}
void embedded_free(void* ptr) {
// Simple pool allocator - no individual free
// Reset entire pool when done
}
int main() {
// Set custom memory functions
oddsockets_set_memory_functions(embedded_malloc, embedded_free, NULL);
// Initialize with static allocation
oddsockets_config_t config;
oddsockets_config_init(&config, "your-api-key");
oddsockets_client_t* client = oddsockets_create(&config);
// Rest of application...
return 0;
}
#include
#include
#include
#include "oddsockets.h"
static volatile int running = 1;
static oddsockets_client_t* client = NULL;
void signal_handler(int sig) {
printf("\nReceived signal %d, shutting down...\n", sig);
running = 0;
}
void on_message(const char* channel_name, const char* message, void* user_data) {
printf("[%s] %s\n", channel_name, message);
}
void on_connection_state(oddsockets_state_t state, void* user_data) {
printf("Connection state: %s\n", oddsockets_state_string(state));
}
void on_error(oddsockets_error_t error, const char* message, void* user_data) {
fprintf(stderr, "Error %d: %s\n", error, message);
}
int main(int argc, char* argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s \n", argv[0]);
return 1;
}
// Set up signal handlers
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
// Initialize OddSockets
oddsockets_config_t config;
oddsockets_config_init(&config, argv[1]);
config.connection_callback = on_connection_state;
config.error_callback = on_error;
config.log_level = ODDSOCKETS_LOG_INFO;
client = oddsockets_create(&config);
if (!client) {
fprintf(stderr, "Failed to create client\n");
return 1;
}
// Connect and run
if (oddsockets_connect(client) != ODDSOCKETS_SUCCESS) {
fprintf(stderr, "Failed to connect\n");
oddsockets_destroy(client);
return 1;
}
// Main event loop
while (running && oddsockets_get_state(client) == ODDSOCKETS_STATE_CONNECTED) {
oddsockets_process_events(client);
usleep(10000); // 10ms
}
// Cleanup
oddsockets_destroy(client);
printf("Application terminated cleanly\n");
return 0;
}
# CMake toolchain file for ARM cross-compilation
# arm-linux-gnueabihf.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
# Cross-compiler settings
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
# Root path for cross-compilation
set(CMAKE_FIND_ROOT_PATH /usr/arm-linux-gnueabihf)
# Search for programs in the build host directories
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# Search for libraries and headers in the target directories
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# Build command:
# mkdir build-arm && cd build-arm
# cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/arm-linux-gnueabihf.cmake ..
# make