ading callback_disconnect function

This commit is contained in:
Dominik Kuhn 2024-08-29 11:12:27 +02:00
parent 220949d94d
commit f5159dfbd7
4 changed files with 172 additions and 61 deletions

View File

@ -905,4 +905,4 @@
# plugin C:\Users\d.kuhn\Projekte\mosquitto\out\build\x64-Debug\plugins\payload-modification\mosquitto_payload_modification.dll
plugin C:\Users\d.kuhn\Projekte\mosquitto\out\build\x64-Debug\plugins\wamo\wamo.dll
plugin C:\Users\d.kuhn\Projekte\mosquitto\out\build\x64-Release\plugins\wamo\wamo.dll

View File

@ -16,16 +16,16 @@ Contributors:
#include "mosquitto.h"
#include "mosquitto_broker.h"
int json_create_array(cJSON* json, const char* name) {
json_err_t json_create_array(cJSON* json, const char* name) {
cJSON* jtmp;
jtmp = cJSON_GetObjectItem(json, name);
if (jtmp) {
if (cJSON_IsArray(jtmp) == true) {
return MOSQ_ERR_INVAL;
return JSON_ERR_ARRAY_EXISTS;
}
else {
cJSON_AddArrayToObject(json, name);
return JSON_ERR_TYPE_INVAL;
}
}
@ -33,11 +33,11 @@ int json_create_array(cJSON* json, const char* name) {
cJSON_AddArrayToObject(json, name);
}
return MOSQ_ERR_SUCCESS;
return JSON_ERR_SUCCESS;
}
int json_add_id_to_array(cJSON* json, const char* name, const char * id)
json_err_t json_add_id_to_array(cJSON* json, const char* name, const char * id)
{
cJSON* jtmp;
cJSON* tid;
@ -49,19 +49,19 @@ int json_add_id_to_array(cJSON* json, const char* name, const char * id)
cJSON_AddItemToArray(jtmp, tid);
}
else {
return MOSQ_ERR_INVAL;
return JSON_ERR_TYPE_INVAL;
}
}
else {
return MOSQ_ERR_INVAL;
return JSON_ERR_SYNTAX;
}
return MOSQ_ERR_SUCCESS;
return JSON_ERR_SUCCESS;
}
int json_del_id_from_array(cJSON* json, const char* name, const char* id)
json_err_t json_del_id_from_array(cJSON* json, const char* name, const char* id)
{
cJSON* jtmp = NULL;
cJSON* tid = NULL;
@ -71,42 +71,55 @@ int json_del_id_from_array(cJSON* json, const char* name, const char* id)
jtmp = cJSON_GetObjectItem(json, name);
if (jtmp) {
// mosquitto_log_printf(MOSQ_LOG_INFO, "wamo: deleting item from array .. debug 1");
if (cJSON_IsArray(jtmp) == true) {
// cJSON_DeleteItemFromObject(json, name);
// mosquitto_log_printf(MOSQ_LOG_INFO, "wamo: deleting item from array .. debug 2");
cJSON_ArrayForEach(tid, jtmp)
{
{
if ( strcmp( cJSON_GetStringValue(tid),id) == 0)
{
// mosquitto_log_printf(MOSQ_LOG_INFO, "wamo: deleting item from array .. debug 3");
detached_item = cJSON_DetachItemFromArray(jtmp, array_index);
}
else
{
return MOSQ_ERR_INVAL;
// mosquitto_log_printf(MOSQ_LOG_INFO, "wamo: deleting item from array .. debug 4");
}
array_index++;
}
// cJSON_ReplaceItemInObject(json, name, jtmp);
// cJSON_AddItemToObject(json, id, jtmp);
}
else {
return MOSQ_ERR_INVAL;
return JSON_ERR_TYPE_INVAL;
}
}
else {
return MOSQ_ERR_INVAL;
return JSON_ERR_SYNTAX;
}
return MOSQ_ERR_SUCCESS;
return JSON_ERR_SUCCESS;
}
json_err_t json_del_clientid(cJSON* json, const char* id)
{
cJSON* next_object = NULL;
cJSON_ArrayForEach(next_object, json)
{
if (next_object->string != NULL) {
mosquitto_log_printf(MOSQ_LOG_INFO, "wamo: deleting client with id %s from topic %s", id, next_object->string);
json_del_id_from_array(json, next_object->string, id);
}
}
return JSON_ERR_SUCCESS;
}
int json_get_bool(cJSON *json, const char *name, bool *value, bool optional, bool default_value)
{
cJSON *jtmp;

View File

@ -8,9 +8,38 @@ Contributors:
#include <cjson/cJSON.h>
#include <stdbool.h>
int json_create_array(cJSON* json, const char* name);
int json_add_id_to_array(cJSON* json, const char* name, const char* id);
int json_del_id_from_array(cJSON* json, const char* name, const char* id);
/* Enum: json_err_t
* Integer values returned from many JSON helper function functions.
*
* JSON_ERR_SUCCESS - the message/packet ID of the PUBLISH message, assuming this is a.
*
* char *topic - the topic the message was delivered on.
*
* void *payload - the message payload. This will be payloadlen bytes long, and
* may be NULL if a zero length payload was sent.
*
* int payloadlen - the length of the payload, in bytes.
*
* int qos - the quality of service of the message, 0, 1, or 2.
*/
typedef enum {
JSON_ERR_SUCCESS = 0,
JSON_ERR_FAILURE = 1,
JSON_ERR_TYPE_INVAL = 3,
JSON_ERR_VALUE = 4,
JSON_ERR_SYNTAX = 5,
JSON_ERR_ARRAY_EXISTS = 6,
} json_err_t;
json_err_t json_create_array(cJSON* json, const char* name);
json_err_t json_add_id_to_array(cJSON* json, const char* name, const char* id);
json_err_t json_del_id_from_array(cJSON* json, const char* name, const char* id);
json_err_t json_del_clientid(cJSON* json, const char* id);
/* "optional==false" can also be taken to mean "only return success if the key exists and is valid" */
int json_get_bool(cJSON *json, const char *name, bool *value, bool optional, bool default_value);

View File

@ -57,52 +57,102 @@ static int callback_control(int event, void* event_data, void* userdata)
const char * client_id = mosquitto_client_id(ed->client);
const char* topic = ed->topic;
const int access = ed->access;
const int access = ed->access;
if (access == MOSQ_ACL_SUBSCRIBE) {
json_create_array(subscribedTopics, topic);
json_add_id_to_array(subscribedTopics, topic, client_id);
char* json_string = cJSON_Print(subscribedTopics);
char* payload = cJSON_PrintUnformatted(subscribedTopics);
mosquitto_log_printf(MOSQ_LOG_INFO, "wamo: client with id %s subscribed to topic %s", client_id, topic);
mosquitto_log_printf(MOSQ_LOG_INFO, "wamo: subscribed topics %s", json_string);
mosquitto_log_printf(MOSQ_LOG_INFO, "wamo: client with ID %s subscribed to topic %s", client_id, topic);
if (payload == NULL) return MOSQ_ERR_MALFORMED_PACKET;
json_err_t rc = json_create_array(subscribedTopics, topic);
if ((rc == JSON_ERR_SUCCESS) || (rc == JSON_ERR_ARRAY_EXISTS)) {
if (json_add_id_to_array(subscribedTopics, topic, client_id) == JSON_ERR_SUCCESS) {
char* json_string = cJSON_Print(subscribedTopics);
char* payload = cJSON_PrintUnformatted(subscribedTopics);
uint32_t payload_len = strlen(payload);
if (payload_len > MQTT_MAX_PAYLOAD) {
free(payload);
return MOSQ_ERR_PAYLOAD_SIZE;
mosquitto_log_printf(MOSQ_LOG_INFO, "wamo: new subscribed topics %s", json_string);
if (payload == NULL) return MOSQ_ERR_MALFORMED_PACKET;
uint32_t payload_len = strlen(payload);
if (payload_len > MQTT_MAX_PAYLOAD) {
free(payload);
return MOSQ_ERR_PAYLOAD_SIZE;
}
mosquitto_broker_publish_copy(NULL, "mqtt/subscriptions",
(int)payload_len, payload, 0, 1, NULL);
}
else
{
mosquitto_log_printf(MOSQ_LOG_INFO, "the specified object item does not exist or is not an array");
}
}
else {
mosquitto_log_printf(MOSQ_LOG_INFO, "wamo: something went wrong while attaching the client ID to JSON object. "\
"Looks like the specified obejkt item already exists, but is not an array");
}
mosquitto_broker_publish_copy(NULL, "mqtt/subscriptions",
(int)payload_len, payload, 0, 0, NULL);
}
else if (access == MOSQ_ACL_UNSUBSCRIBE) {
json_del_id_from_array(subscribedTopics, topic, client_id);
char* json_string = cJSON_Print(subscribedTopics);
char* payload = cJSON_PrintUnformatted(subscribedTopics);
mosquitto_log_printf(MOSQ_LOG_INFO, "wamo: client with id %s unscribed to topic %s", client_id, topic);
mosquitto_log_printf(MOSQ_LOG_INFO, "wamo: subscribed topics %s", json_string);
mosquitto_log_printf(MOSQ_LOG_INFO, "wamo: client with ID %s unscribed to topic %s", client_id, topic);
if (payload == NULL) return MOSQ_ERR_MALFORMED_PACKET;
json_err_t rc = json_del_id_from_array(subscribedTopics, topic, client_id);
if (rc == JSON_ERR_SUCCESS) {
char* json_string = cJSON_Print(subscribedTopics);
char* payload = cJSON_PrintUnformatted(subscribedTopics);
mosquitto_log_printf(MOSQ_LOG_INFO, "wamo: subscribed topics %s", json_string);
uint32_t payload_len = strlen(payload);
if (payload_len > MQTT_MAX_PAYLOAD) {
free(payload);
return MOSQ_ERR_PAYLOAD_SIZE;
if (payload == NULL) return MOSQ_ERR_MALFORMED_PACKET;
uint32_t payload_len = strlen(payload);
if (payload_len > MQTT_MAX_PAYLOAD) {
free(payload);
return MOSQ_ERR_PAYLOAD_SIZE;
}
mosquitto_broker_publish_copy(NULL, "mqtt/subscriptions",
(int)payload_len, payload, 0, 1, NULL);
}
mosquitto_broker_publish_copy(NULL, "mqtt/subscriptions",
(int)payload_len, payload, 0, 0, NULL);
else
{
mosquitto_log_printf(MOSQ_LOG_INFO, "wamo: something went wrong while deleting the client ID from JSON object. "\
"The specified object item does not exist or is not an array");
}
}
return MOSQ_ERR_SUCCESS;
}
static int callback_disconnect(int event, void* event_data, void* userdata)
{
struct mosquitto_evt_disconnect* ed = event_data;
UNUSED(event);
UNUSED(userdata);
const char* client_id = mosquitto_client_id(ed->client);
json_del_clientid(subscribedTopics, client_id);
char* json_string = cJSON_Print(subscribedTopics);
char* payload = cJSON_PrintUnformatted(subscribedTopics);
mosquitto_log_printf(MOSQ_LOG_INFO, "wamo: client with ID %s disconnected", client_id );
mosquitto_log_printf(MOSQ_LOG_INFO, "wamo: subscribed topics %s", json_string);
if (payload == NULL) return MOSQ_ERR_MALFORMED_PACKET;
uint32_t payload_len = strlen(payload);
if (payload_len > MQTT_MAX_PAYLOAD) {
free(payload);
return MOSQ_ERR_PAYLOAD_SIZE;
}
mosquitto_broker_publish_copy(NULL, "mqtt/subscriptions",
(int)payload_len, payload, 0, 1, NULL);
return MOSQ_ERR_SUCCESS;
}
static int callback_message(int event, void* event_data, void* userdata)
{
@ -176,6 +226,20 @@ int mosquitto_plugin_init(mosquitto_plugin_id_t* identifier, void** user_data, s
return rc;
}
rc = mosquitto_callback_register(mosq_pid, MOSQ_EVT_DISCONNECT, callback_disconnect, NULL, NULL);
if (rc == MOSQ_ERR_ALREADY_EXISTS) {
mosquitto_log_printf(MOSQ_LOG_ERR, "Error: Dynamic security plugin can only be loaded once.");
return rc;
}
else if (rc == MOSQ_ERR_NOMEM) {
mosquitto_log_printf(MOSQ_LOG_ERR, "Error: Out of memory.");
return rc;
}
else if (rc != MOSQ_ERR_SUCCESS) {
return rc;
}
return MOSQ_ERR_SUCCESS;
@ -187,5 +251,10 @@ int mosquitto_plugin_cleanup(void* user_data, struct mosquitto_opt* opts, int op
UNUSED(opts);
UNUSED(opt_count);
return mosquitto_callback_unregister(mosq_pid, MOSQ_EVT_ACL_CHECK, callback_control, NULL);
if (mosq_pid) {
mosquitto_callback_unregister(mosq_pid, MOSQ_EVT_ACL_CHECK, callback_control, NULL);
mosquitto_callback_unregister(mosq_pid, MOSQ_EVT_DISCONNECT, callback_disconnect, NULL);
}
return MOSQ_ERR_SUCCESS;
}