11bool hasWildcardCheck(
const char topic[]) {
12 for (
int i = 0; i < strlen(topic); i++) {
13 if (topic[i] ==
'+' || topic[i] ==
'#')
19BrokerTopic::BrokerTopic(): logger(
disableLogger()), topic(
""), hasWildcards(false) {}
21BrokerTopic::BrokerTopic(Elog *_logger,
const char topic[]) {
24 strncpy(this->topic, topic,
sizeof(this->topic) - 1);
25 this->topic[
sizeof(this->topic) - 1] =
'\0';
27 this->hasWildcards = hasWildcardCheck(this->topic);
31 if (messagesQueue == NULL) {
32 logger->log(ERROR,
"[BROKER TOPIC %s] Couldn't create the message queue.", this->topic);
35 logger->log(DEBUG,
"[BROKER TOPIC %s] Created.", this->topic);
38const char* BrokerTopic::getTopic()
const {
42int BrokerTopic::getSubscribersAmount()
const {
43 return subscribers.size();
46const std::vector<std::array<uint8_t, 6>>& BrokerTopic::getSubscribers()
const {
50const char* BrokerTopic::getFilename()
const {
54void BrokerTopic::setFilename(
const char* filename) {
55 strncpy(this->filename, filename,
sizeof(this->filename) - 1);
56 this->filename[
sizeof(this->filename)-1] =
'\0';
59bool addPeer(
const uint8_t *mac) {
60 if(!esp_now_is_peer_exist(mac)) {
62 esp_now_peer_info_t peerInfo;
63 memset(&peerInfo, 0,
sizeof(peerInfo));
64 memcpy(peerInfo.peer_addr, mac, 6);
66 peerInfo.encrypt =
false;
68 if (esp_now_add_peer(&peerInfo) != ESP_OK)
74bool removePeer(
const uint8_t *mac) {
76 if (esp_now_is_peer_exist(mac)) {
77 if (esp_now_del_peer(mac) != ESP_OK)
86bool BrokerTopic::subscribe(
const uint8_t *mac)
const {
87 if (!isSubscribed(mac)) {
88 const_cast<BrokerTopic*
>(
this)->subscribers.push_back(*
reinterpret_cast<const std::array<uint8_t, 6>*
>(mac));
93bool BrokerTopic::subscribe(
const std::array<uint8_t, 6>& mac)
const {
94 if (!isSubscribed(mac.data())) {
95 const_cast<BrokerTopic*
>(
this)->subscribers.push_back(mac);
100bool BrokerTopic::unsubscribe(
const uint8_t *mac) {
102 auto it = std::find_if(subscribers.begin(), subscribers.end(), [&](
const std::array<uint8_t, 6>& subscriber) {
103 return memcmp(subscriber.data(), mac, 6) == 0;
106 if (it != subscribers.end()) {
107 subscribers.erase(it);
115bool BrokerTopic::isSubscribed(
const uint8_t *mac)
const {
116 for (
const auto& subscriber : subscribers) {
117 if (memcmp(mac, subscriber.data(), 6) == 0)
123std::string BrokerTopic::getSubscribersString()
const {
124 std::string result =
"";
125 for (
const auto& mac : subscribers) {
127 snprintf(macChar,
sizeof(macChar),
"%02X:%02X:%02X:%02X:%02X:%02X",
128 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
129 result = result + macChar +
"\n";
134void BrokerTopic::publish(
PublishContent pubContent, std::vector<std::array<uint8_t, 6>>& alreadySentMacs)
const {
135 for (
const auto& subscriber : subscribers) {
137 bool alreadySent =
false;
138 for (
const auto& sentMac : alreadySentMacs) {
139 if (sentMac == subscriber) {
145 if (addPeer(subscriber.data())) {
146 esp_now_send(subscriber.data(), (uint8_t *)&pubContent,
sizeof(
PublishContent));
147 alreadySentMacs.push_back(subscriber);
149 logger->log(ERROR,
"[BROKER TOPIC %s] Couldn't add peer %02X:%02X:%02X:%02X:%02X:%02X, it won't receive.",
150 topic, subscriber[0], subscriber[1], subscriber[2], subscriber[3], subscriber[4], subscriber[5]);
154 logger->log(DEBUG,
"[BROKER TOPIC %s] Sent message to %d subscribers.", topic, subscribers.size());
157bool BrokerTopic::isPublishable(
const char *publishTopic)
const {
159 if (strcmp(publishTopic, topic) == 0)
161 else if (!hasWildcards)
164 int publishLen = strlen(publishTopic);
165 int subscribeLen = strlen(topic);
169 while (i < publishLen && j < subscribeLen) {
170 char pubChar = publishTopic[i];
171 char subChar = topic[j];
173 if (pubChar != subChar && subChar !=
'+' && subChar !=
'#')
175 if (subChar ==
'+') {
176 while (publishTopic[i] !=
'/' && i < publishLen)
179 }
else if (subChar ==
'#') {
186 if (i < publishLen || j < subscribeLen)
193std::string BrokerTopic::toString()
const {
194 std::string result =
"Topic: " + std::string(topic) +
"\n";
195 result +=
"Subscribers:\n";
196 result += getSubscribersString();
Elog * disableLogger()
Creates a logger without the ability to print messages.
Structure that contains the fields used by a publish message, apart from those inherited from the Mes...