Line data Source code
1 : #include <minipot_sentinel_msg_packer.h> 2 : #include <msgpack.h> 3 : #include "log.h" 4 : 5 : struct minipot_sentinel_msg_packer { 6 : msgpack_sbuffer sbuff; 7 : msgpack_packer packer; 8 : msgpack_sbuffer sbuff_data; 9 : msgpack_packer packer_data; 10 : }; 11 : 12 : minipot_sentinel_msg_packer_t minipot_sentinel_msg_packer_new() { 13 0 : minipot_sentinel_msg_packer_t packer = malloc(sizeof(*packer)); 14 : 15 0 : msgpack_sbuffer_init(&packer->sbuff); 16 0 : msgpack_packer_init(&packer->packer, &packer->sbuff, msgpack_sbuffer_write); 17 : 18 0 : msgpack_sbuffer_init(&packer->sbuff_data); 19 0 : msgpack_packer_init(&packer->packer_data, &packer->sbuff_data, 20 : msgpack_sbuffer_write); 21 : 22 0 : return packer; 23 : } 24 : 25 : void minipot_sentinel_msg_packer_free(minipot_sentinel_msg_packer_t self) { 26 0 : msgpack_sbuffer_destroy(&self->sbuff); 27 0 : msgpack_sbuffer_destroy(&self->sbuff_data); 28 0 : free(self); 29 0 : } 30 : 31 : int minipot_check_sentinel_msg(const struct minipot_sentinel_msg *msg) { 32 0 : if (msg->ts <= 0) { 33 0 : error("Sentinel message has invalid time stamp field"); 34 0 : return -1; 35 : } 36 0 : if (!msg->type || strlen(msg->type) == 0) { 37 0 : error("Sentinel message has invalid type field"); 38 0 : return -1; 39 : } 40 0 : if (!msg->ip || strlen(msg->ip) == 0) { 41 0 : error("Sentinel message has invalid ip field"); 42 0 : return -1; 43 : } 44 0 : if (!msg->action || strlen(msg->action) == 0) { 45 0 : error("Sentinel message has invalid action field"); 46 0 : return -1; 47 : } 48 0 : if (msg->data_len > 0) { 49 0 : if (!msg->data) { 50 0 : error("Sentinel message has invalid action field"); 51 0 : return -1; 52 : } 53 0 : for (size_t i = 0; i < msg->data_len; i++) { 54 : // key must have length at least 1 55 0 : if (!msg->data[i].key || msg->data[i].key_len < 1) { 56 0 : error("Key of Sentinel message data field is invalid"); 57 0 : return -1; 58 : } 59 : // value can have zero length 60 0 : if (msg->data[i].val_len > 0 && !msg->data[i].val) { 61 0 : error("Value of Sentinel message data field is invalid"); 62 0 : return -1; 63 : } 64 : } 65 : } 66 : return 0; 67 : } 68 : 69 : #define PACK_STR(packer, str) do { \ 70 : msgpack_pack_str(packer, strlen(str));\ 71 : msgpack_pack_str_body(packer, str, strlen(str)); \ 72 : } while(0); 73 : 74 : void minipot_sentinel_msg_packer_pack(minipot_sentinel_msg_packer_t self, 75 : const struct minipot_sentinel_msg *msg) { 76 : 77 0 : msgpack_sbuffer_clear(&self->sbuff); 78 0 : msgpack_sbuffer_clear(&self->sbuff_data); 79 : 80 0 : msgpack_pack_map(&self->packer, msg->data_len > 0 ? 5 : 4); 81 0 : PACK_STR(&self->packer, "ts"); 82 0 : msgpack_pack_uint32(&self->packer, msg->ts); 83 0 : PACK_STR(&self->packer, "type"); 84 0 : PACK_STR(&self->packer, msg->type); 85 0 : PACK_STR(&self->packer, "ip"); 86 0 : PACK_STR(&self->packer, msg->ip); 87 0 : PACK_STR(&self->packer, "action"); 88 0 : PACK_STR(&self->packer, msg->action); 89 : 90 0 : if (msg->data_len > 0) { 91 0 : msgpack_pack_map(&self->packer_data, msg->data_len); 92 0 : for (size_t i = 0; i < msg->data_len; i++) { 93 0 : msgpack_pack_str(&self->packer_data, msg->data[i].key_len); 94 0 : msgpack_pack_str_body(&self->packer_data, msg->data[i].key, 95 0 : msg->data[i].key_len); 96 0 : msgpack_pack_str(&self->packer_data, msg->data[i].val_len); 97 0 : msgpack_pack_str_body(&self->packer_data, msg->data[i].val, 98 0 : msg->data[i].val_len); 99 : } 100 0 : PACK_STR(&self->packer,"data"); 101 : // pack binary without header, because the data are already serialized 102 0 : msgpack_pack_str_body(&self->packer, self->sbuff_data.data, 103 : self->sbuff_data.size); 104 : } 105 0 : } 106 : 107 : char *minipot_sentinel_msg_packer_retreive_data( 108 : minipot_sentinel_msg_packer_t self) { 109 0 : return self->sbuff.data; 110 : } 111 : 112 : size_t minipot_sentinel_msg_packer_retreive_dlen( 113 : minipot_sentinel_msg_packer_t self) { 114 0 : return self->sbuff.size; 115 : }