mqtt5_callbacks.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /**
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. * SPDX-License-Identifier: Apache-2.0.
  4. */
  5. #include <aws/mqtt/private/v5/mqtt5_callbacks.h>
  6. #include <aws/io/event_loop.h>
  7. #include <aws/mqtt/private/v5/mqtt5_client_impl.h>
  8. #include <aws/mqtt/v5/mqtt5_listener.h>
  9. #include <inttypes.h>
  10. struct aws_mqtt5_callback_set_entry {
  11. struct aws_allocator *allocator;
  12. struct aws_linked_list_node node;
  13. uint64_t id;
  14. struct aws_mqtt5_callback_set callbacks;
  15. };
  16. void aws_mqtt5_callback_set_manager_init(
  17. struct aws_mqtt5_callback_set_manager *manager,
  18. struct aws_mqtt5_client *client) {
  19. manager->client = client; /* no need to ref count, it's assumed to be owned by the client */
  20. manager->next_callback_set_entry_id = 1;
  21. aws_linked_list_init(&manager->callback_set_entries);
  22. }
  23. void aws_mqtt5_callback_set_manager_clean_up(struct aws_mqtt5_callback_set_manager *manager) {
  24. struct aws_linked_list_node *node = aws_linked_list_begin(&manager->callback_set_entries);
  25. while (node != aws_linked_list_end(&manager->callback_set_entries)) {
  26. struct aws_mqtt5_callback_set_entry *entry = AWS_CONTAINER_OF(node, struct aws_mqtt5_callback_set_entry, node);
  27. node = aws_linked_list_next(node);
  28. aws_linked_list_remove(&entry->node);
  29. aws_mem_release(entry->allocator, entry);
  30. }
  31. }
  32. static struct aws_mqtt5_callback_set_entry *s_new_callback_set_entry(
  33. struct aws_mqtt5_callback_set_manager *manager,
  34. struct aws_mqtt5_callback_set *callback_set) {
  35. struct aws_mqtt5_callback_set_entry *entry =
  36. aws_mem_calloc(manager->client->allocator, 1, sizeof(struct aws_mqtt5_callback_set_entry));
  37. entry->allocator = manager->client->allocator;
  38. entry->id = manager->next_callback_set_entry_id++;
  39. entry->callbacks = *callback_set;
  40. AWS_LOGF_INFO(
  41. AWS_LS_MQTT5_GENERAL,
  42. "id=%p: callback manager created new entry :%" PRIu64,
  43. (void *)manager->client,
  44. entry->id);
  45. return entry;
  46. }
  47. uint64_t aws_mqtt5_callback_set_manager_push_front(
  48. struct aws_mqtt5_callback_set_manager *manager,
  49. struct aws_mqtt5_callback_set *callback_set) {
  50. AWS_FATAL_ASSERT(aws_event_loop_thread_is_callers_thread(manager->client->loop));
  51. struct aws_mqtt5_callback_set_entry *entry = s_new_callback_set_entry(manager, callback_set);
  52. aws_linked_list_push_front(&manager->callback_set_entries, &entry->node);
  53. return entry->id;
  54. }
  55. void aws_mqtt5_callback_set_manager_remove(struct aws_mqtt5_callback_set_manager *manager, uint64_t callback_set_id) {
  56. AWS_FATAL_ASSERT(aws_event_loop_thread_is_callers_thread(manager->client->loop));
  57. struct aws_linked_list_node *node = aws_linked_list_begin(&manager->callback_set_entries);
  58. while (node != aws_linked_list_end(&manager->callback_set_entries)) {
  59. struct aws_mqtt5_callback_set_entry *entry = AWS_CONTAINER_OF(node, struct aws_mqtt5_callback_set_entry, node);
  60. node = aws_linked_list_next(node);
  61. if (entry->id == callback_set_id) {
  62. aws_linked_list_remove(&entry->node);
  63. AWS_LOGF_INFO(
  64. AWS_LS_MQTT5_GENERAL,
  65. "id=%p: callback manager removed entry id=%" PRIu64,
  66. (void *)manager->client,
  67. entry->id);
  68. aws_mem_release(entry->allocator, entry);
  69. return;
  70. }
  71. }
  72. AWS_LOGF_INFO(
  73. AWS_LS_MQTT5_GENERAL,
  74. "id=%p: callback manager failed to remove entry id=%" PRIu64 ", callback set id not found.",
  75. (void *)manager->client,
  76. callback_set_id);
  77. }
  78. void aws_mqtt5_callback_set_manager_on_publish_received(
  79. struct aws_mqtt5_callback_set_manager *manager,
  80. const struct aws_mqtt5_packet_publish_view *publish_view) {
  81. AWS_FATAL_ASSERT(aws_event_loop_thread_is_callers_thread(manager->client->loop));
  82. struct aws_linked_list_node *node = aws_linked_list_begin(&manager->callback_set_entries);
  83. while (node != aws_linked_list_end(&manager->callback_set_entries)) {
  84. struct aws_mqtt5_callback_set_entry *entry = AWS_CONTAINER_OF(node, struct aws_mqtt5_callback_set_entry, node);
  85. node = aws_linked_list_next(node);
  86. struct aws_mqtt5_callback_set *callback_set = &entry->callbacks;
  87. if (callback_set->listener_publish_received_handler != NULL) {
  88. bool handled = (*callback_set->listener_publish_received_handler)(
  89. publish_view, callback_set->listener_publish_received_handler_user_data);
  90. if (handled) {
  91. return;
  92. }
  93. }
  94. }
  95. if (manager->client->config->publish_received_handler != NULL) {
  96. (*manager->client->config->publish_received_handler)(
  97. publish_view, manager->client->config->publish_received_handler_user_data);
  98. }
  99. }
  100. void aws_mqtt5_callback_set_manager_on_lifecycle_event(
  101. struct aws_mqtt5_callback_set_manager *manager,
  102. const struct aws_mqtt5_client_lifecycle_event *lifecycle_event) {
  103. AWS_FATAL_ASSERT(aws_event_loop_thread_is_callers_thread(manager->client->loop));
  104. struct aws_linked_list_node *node = aws_linked_list_begin(&manager->callback_set_entries);
  105. while (node != aws_linked_list_end(&manager->callback_set_entries)) {
  106. struct aws_mqtt5_callback_set_entry *entry = AWS_CONTAINER_OF(node, struct aws_mqtt5_callback_set_entry, node);
  107. node = aws_linked_list_next(node);
  108. struct aws_mqtt5_callback_set *callback_set = &entry->callbacks;
  109. if (callback_set->lifecycle_event_handler != NULL) {
  110. struct aws_mqtt5_client_lifecycle_event listener_copy = *lifecycle_event;
  111. listener_copy.user_data = callback_set->lifecycle_event_handler_user_data;
  112. (*callback_set->lifecycle_event_handler)(&listener_copy);
  113. }
  114. }
  115. struct aws_mqtt5_client_lifecycle_event client_copy = *lifecycle_event;
  116. client_copy.user_data = manager->client->config->lifecycle_event_handler_user_data;
  117. if (manager->client->config->lifecycle_event_handler != NULL) {
  118. (*manager->client->config->lifecycle_event_handler)(&client_copy);
  119. }
  120. }