// SPDX-FileCopyrightText: 2024 Cesanta Software Limited // SPDX-License-Identifier: GPL-2.0-only or commercial // Generated by Mongoose Wizard, https://mongoose.ws/wizard/ // Default mock implementation of the API callbacks #include "mongoose_glue.h" void glue_lock_init(void) { // callback to initialize the MQTT semaphore } void glue_lock(void) { // Lock mutex. Implement only if you use MQTT publish } void glue_unlock(void) { // Unlock mutex. Implement only if you use MQTT publish } // Update this with the real CA for the WIZARD_MQTT_URL #define TLS_CA \ "" void glue_mqtt_tls_init(struct mg_connection *c) { bool is_tls = mg_url_is_ssl(WIZARD_MQTT_URL); MG_DEBUG(("%lu TLS enabled: %s", c->id, is_tls ? "yes" : "no")); if (is_tls) { struct mg_tls_opts opts; memset(&opts, 0, sizeof(opts)); opts.ca = mg_str(TLS_CA); opts.name = mg_url_host(WIZARD_MQTT_URL); mg_tls_init(c, &opts); } } // Called when we connected to the MQTT server void glue_mqtt_on_connect(struct mg_connection *c, int code) { struct mg_mqtt_opts opts; memset(&opts, 0, sizeof(opts)); opts.qos = 1; opts.topic = mg_str("device1/rx"); mg_mqtt_sub(c, &opts); MG_DEBUG(("%lu code %d. Subscribing to [%.*s]", c->id, code, opts.topic.len, opts.topic.buf)); } // This function gets called for every received MQTT message void glue_mqtt_on_message(struct mg_connection *c, struct mg_str topic, struct mg_str data) { char tmp[100]; struct mg_mqtt_opts opts; mg_snprintf(tmp, sizeof(tmp), "Got [%.*s] -> [%.*s] !", topic.len, topic.buf, data.len, data.buf); MG_DEBUG(("%lu %s", c->id, tmp)); // Send response to the TX topic if (g_mqtt_conn != NULL) { memset(&opts, 0, sizeof(opts)); opts.topic = mg_str("device1/tx"); opts.message = mg_str(tmp); mg_mqtt_pub(g_mqtt_conn, &opts); } } void glue_mqtt_on_cmd(struct mg_connection *c, struct mg_mqtt_message *mm) { MG_DEBUG(("%lu cmd %d qos %d", c->id, mm->cmd, mm->qos)); } struct mg_connection *glue_mqtt_connect(mg_event_handler_t fn) { const char *url = WIZARD_MQTT_URL; struct mg_mqtt_opts opts; memset(&opts, 0, sizeof(opts)); opts.clean = true; return mg_mqtt_connect(&g_mgr, url, &opts, fn, NULL); } void glue_sntp_on_time(uint64_t utc_time_in_milliseconds) { MG_INFO(("UTC time in milliseconds from SNTP: %llu, current time: %llu", utc_time_in_milliseconds, mg_now())); } // Authenticate user/password. Return access level for the authenticated user: // 0 - authentication error // 1,2,3... - authentication success. Higher levels are more privileged than lower int glue_authenticate(const char *user, const char *pass) { int level = 0; // Authentication failure if (strcmp(user, "admin") == 0 && strcmp(pass, "admin") == 0) { level = 7; // Administrator } else if (strcmp(user, "user") == 0 && strcmp(pass, "user") == 0) { level = 3; // Ordinary dude } return level; } static uint64_t s_action_timeout_reboot; // Time when reboot ends bool glue_check_reboot(void) { return s_action_timeout_reboot > mg_now(); // Return true if reboot is in progress } void glue_start_reboot(struct mg_str params) { MG_DEBUG(("Passed parameters: [%.*s]", params.len, params.buf)); s_action_timeout_reboot = mg_now() + 1000; // Start reboot, finish after 1 second } static uint64_t s_action_timeout_reformat; // Time when reformat ends bool glue_check_reformat(void) { return s_action_timeout_reformat > mg_now(); // Return true if reformat is in progress } void glue_start_reformat(struct mg_str params) { MG_DEBUG(("Passed parameters: [%.*s]", params.len, params.buf)); s_action_timeout_reformat = mg_now() + 1000; // Start reformat, finish after 1 second } void *glue_ota_begin_firmware_update(char *file_name, size_t total_size) { bool ok = mg_ota_begin(total_size); MG_DEBUG(("%s size %lu, ok: %d", file_name, total_size, ok)); return ok ? (void *) 1 : NULL; } bool glue_ota_end_firmware_update(void *context) { mg_timer_add(&g_mgr, 500, 0, (void (*)(void *)) (void *) mg_ota_end, context); return true; } bool glue_ota_write_firmware_update(void *context, void *buf, size_t len) { MG_DEBUG(("ctx: %p %p/%lu", context, buf, len)); return mg_ota_write(buf, len); } void *glue_file_open_file_upload(char *file_name, size_t total_size) { char path[128], *p = NULL; FILE *fp = NULL; if ((p = strrchr(file_name, '/')) == NULL) p = file_name; mg_snprintf(path, sizeof(path), "/tmp/%s", p); #if MG_ENABLE_POSIX_FS fp = fopen(path, "w+b"); #endif MG_DEBUG(("opening [%s] size %lu, fp %p", path, total_size, fp)); return fp; } bool glue_file_close_file_upload(void *fp) { MG_DEBUG(("closing %p", fp)); #if MG_ENABLE_POSIX_FS return fclose((FILE *) fp) == 0; #else return false; #endif } bool glue_file_write_file_upload(void *fp, void *buf, size_t len) { MG_DEBUG(("writing fp %p %p %lu bytes", fp, buf, len)); #if MG_ENABLE_POSIX_FS return fwrite(buf, 1, len, (FILE *) fp) == len; #else return false; #endif } void glue_reply_graph_data(struct mg_connection *c, struct mg_http_message *hm) { const char *headers = "Cache-Control: no-cache\r\n" "Content-Type: application/json\r\n"; const char *value = "[[1724576787,20.3],[1724576847,27.2],[1724576907,29.7],[1724576967,27.9],[1724577027,25.1],[1724577087,23.8],[1724577147,22.5],[1724577207,22.2],[1724577267,23.3],[1724577327,23.9]]"; (void) hm; mg_http_reply(c, 200, headers, "%s\n", value); } static struct state s_state = {42, 27, 67, 10, "1.0.0", true, false, 83}; void glue_get_state(struct state *data) { *data = s_state; // Sync with your device } static struct leds s_leds = {false, true, false}; void glue_get_leds(struct leds *data) { *data = s_leds; // Sync with your device } void glue_set_leds(struct leds *data) { s_leds = *data; // Sync with your device } static struct network_settings s_network_settings = {"192.168.0.42", "192.168.0.1", "255.255.255.0", true}; void glue_get_network_settings(struct network_settings *data) { *data = s_network_settings; // Sync with your device } void glue_set_network_settings(struct network_settings *data) { s_network_settings = *data; // Sync with your device } static struct settings s_settings = {"edit & save me", "info", 123.12345, 17, true}; void glue_get_settings(struct settings *data) { *data = s_settings; // Sync with your device } void glue_set_settings(struct settings *data) { s_settings = *data; // Sync with your device } static struct security s_security = {"admin", "user"}; void glue_get_security(struct security *data) { *data = s_security; // Sync with your device } void glue_set_security(struct security *data) { s_security = *data; // Sync with your device } void glue_reply_loglevels(struct mg_connection *c, struct mg_http_message *hm) { const char *headers = "Cache-Control: no-cache\r\n" "Content-Type: application/json\r\n"; const char *value = "[\"disabled\",\"error\",\"info\",\"debug\",\"verbose\"]"; (void) hm; mg_http_reply(c, 200, headers, "%s\n", value); } void glue_reply_events(struct mg_connection *c, struct mg_http_message *hm) { const char *headers = "Cache-Control: no-cache\r\n" "Content-Type: application/json\r\n"; const char *value = "[{\"priority\":1,\"timestamp\":1738653279,\"active\":false,\"message\":\"event 1\"},{\"priority\":2,\"timestamp\":1738653390,\"active\":true,\"message\":\"event 2\"}]"; (void) hm; mg_http_reply(c, 200, headers, "%s\n", value); }