void packet_received(struct broadcast_conn *connection, const rimeaddr_t *from) { struct subscription_item *si; switch(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE)) { case MWARE_MSG_SUB: si = subscription_get(&(packetbuf_msg_sub())->id); if (si != NULL) { if (subscription_is_unsubscribed(si)) { subscription_reset_last_shout(si); } else { if (!subscription_update(si, from, (packetbuf_msg_sub())->sub.hops + 1)) { si = NULL; } } } else if (!subscription_is_too_far(&(packetbuf_msg_sub())->sub)) { const rimeaddr_t * parent; parent = (identifier_is_mine(&(packetbuf_msg_sub())->id) ? &rimeaddr_null : from); si = subscription_insert( &(packetbuf_msg_sub())->id, &(packetbuf_msg_sub())->sub, parent, (packetbuf_msg_sub())->sub.hops + 1); } if (si != NULL) { subscription_print(si, "rs"); subscription_sync_epoch(si, &(packetbuf_msg_sub())->sub); wind_item_timer(si, subscription_desync_jitter(si, &(packetbuf_msg_sub())->sub)); } break; case MWARE_MSG_PUB: si = subscription_get(&(packetbuf_msg_pub())->id); if (si == NULL || subscription_is_unsubscribed(si)) { break; } if (rimeaddr_cmp(&si->next_hop, from)) { subscription_update_last_heard(si); } else if (message_is_published_to_me()) { subscription_data_input(si, (packetbuf_msg_pub())->data, (packetbuf_msg_pub())->node_count); } break; case MWARE_MSG_UNSUB: si = subscription_get(&(packetbuf_msg_unsub())->id); if (si == NULL) { break; } subscription_print(si, "ru"); subscription_unsubscribe(si); break; } packetbuf_clear(); }
void mware_unsubscribe(struct identifier *i) { struct subscription_item *si; si = subscription_get(i); if (si != NULL) { subscription_unsubscribe(si); } }
bool unsubscribe(Subscriptions *subscriptions, const char *topic, void *subscriber) { Subscription *sub = subscription_get(subscriptions, topic); if (sub) return subscription_remove_subscriber(subscriptions, sub, subscriber); return false; }
void mware_publish(struct identifier *i, uint16_t data, uint16_t node_count) { struct subscription_item *si; si = subscription_get(i); if (si == NULL || subscription_is_unsubscribed(si)) { return; } subscription_data_input(si, data, node_count); }
bool subscribe(Subscriptions *subscriptions, const char *topic, void *subscriber) { Subscription *sub = subscription_get(subscriptions, topic); if (!sub) sub = subscription_new(subscriptions, topic); return subscription_add_subscriber(sub, subscriber); }
/* * @return true if given subscriber subscribed to given description */ bool subscribed_to(Subscriptions *subscriptions, const char *topic, void *subscriber) { Subscription *sub = subscription_get(subscriptions, topic); if (sub) { int i; for (i = 0; i < sub->count_subscribed; i++) if (sub->subscribers[i] == subscriber) return true; } return false; }
static void my_message_callback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message) { if (message->payloadlen) { llog(LOG_INFO, "Received message %s : %s\n", message->topic, message->payload); Subscription *subscription = subscription_get(&SUBSCRIPTIONS, message->topic); if (subscription) { llog(LOG_INFO, "Notify %d lws clients for topic %s\n", subscription->count_subscribed, message->topic); Message msg; message_new(&msg, PUBLISH, message->topic, message->payload); message_serialize_response(&msg); // create libwebsockets message from MQTT payload unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + msg.size + LWS_SEND_BUFFER_POST_PADDING]; unsigned char *lws_message = &buf[LWS_SEND_BUFFER_PRE_PADDING]; int lws_message_length = sprintf((char* )lws_message, "%s", msg.serialized); // dispatch message to all subscribers for (int i = 0; i < subscription->count_subscribed; i++) { struct libwebsocket *wsi = subscription->subscribers[i]; int bytes_written = libwebsocket_write(wsi, lws_message, lws_message_length, LWS_WRITE_TEXT); if (bytes_written < lws_message_length) { llog(LOG_ERR, "ERROR only %d bytes written (message length is %d)\n", bytes_written, lws_message_length); } } message_free(&msg); } else llog(LOG_ERR, "No lws clients are subscribed to topic %s\n", message->topic); } else printf("%s (null)\n", message->topic); }