From 62ca4607afff6056758518a76bc2b4911940ecfc Mon Sep 17 00:00:00 2001 From: moninom1 Date: Wed, 28 Aug 2024 11:02:52 +0000 Subject: [PATCH] Doxygen for 43fe35f90a098365eb35cb22b93f1d22cca1073d --- _data/doc_config.json | 1 + latest | 1 - latest/annotated.html | 125 + latest/bc_s.png | Bin 0 -> 676 bytes latest/bc_sd.png | Bin 0 -> 635 bytes latest/bdwn.png | Bin 0 -> 147 bytes latest/classes.html | 118 + latest/closed.png | Bin 0 -> 132 bytes latest/coreMQTT/annotated.html | 126 + latest/coreMQTT/bc_s.png | Bin 0 -> 676 bytes latest/coreMQTT/bc_sd.png | Bin 0 -> 635 bytes latest/coreMQTT/bdwn.png | Bin 0 -> 147 bytes latest/coreMQTT/classes.html | 121 + latest/coreMQTT/closed.png | Bin 0 -> 132 bytes latest/coreMQTT/core__mqtt_8c.html | 2824 ++++++++++++++++ latest/coreMQTT/core__mqtt_8h.html | 1281 +++++++ latest/coreMQTT/core__mqtt_8h_source.html | 423 +++ .../core__mqtt__config__defaults_8h.html | 396 +++ ...ore__mqtt__config__defaults_8h_source.html | 218 ++ .../coreMQTT/core__mqtt__serializer_8c.html | 3003 +++++++++++++++++ .../coreMQTT/core__mqtt__serializer_8h.html | 1675 +++++++++ .../core__mqtt__serializer_8h_source.html | 466 +++ latest/coreMQTT/core__mqtt__state_8c.html | 1371 ++++++++ latest/coreMQTT/core__mqtt__state_8h.html | 250 ++ .../coreMQTT/core__mqtt__state_8h_source.html | 209 ++ latest/coreMQTT/core_mqtt_config.html | 176 + .../dir_359d2bec989c9a8deeeb9aee335c1c76.html | 113 + .../dir_3750548c40d9045ee3b3d006c00db089.html | 120 + .../dir_49e56c817e5e54854c35e136979f97ca.html | 113 + .../dir_8ee1a5e78eaec319fe5d64075812fc61.html | 129 + .../dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html | 133 + latest/coreMQTT/doc.png | Bin 0 -> 746 bytes latest/coreMQTT/docd.png | Bin 0 -> 756 bytes latest/coreMQTT/doxygen.css | 1989 +++++++++++ latest/coreMQTT/doxygen.svg | 26 + latest/coreMQTT/dynsections.js | 123 + latest/coreMQTT/files.html | 127 + latest/coreMQTT/folderclosed.png | Bin 0 -> 616 bytes latest/coreMQTT/folderopen.png | Bin 0 -> 597 bytes latest/coreMQTT/functions.html | 228 ++ latest/coreMQTT/functions_vars.html | 228 ++ latest/coreMQTT/globals.html | 115 + latest/coreMQTT/globals_c.html | 121 + latest/coreMQTT/globals_d.html | 120 + latest/coreMQTT/globals_defs.html | 197 ++ latest/coreMQTT/globals_e.html | 115 + latest/coreMQTT/globals_enum.html | 118 + latest/coreMQTT/globals_eval.html | 151 + latest/coreMQTT/globals_f.html | 114 + latest/coreMQTT/globals_func.html | 272 ++ latest/coreMQTT/globals_g.html | 116 + latest/coreMQTT/globals_h.html | 118 + latest/coreMQTT/globals_i.html | 115 + latest/coreMQTT/globals_l.html | 118 + latest/coreMQTT/globals_m.html | 261 ++ latest/coreMQTT/globals_n.html | 114 + latest/coreMQTT/globals_p.html | 117 + latest/coreMQTT/globals_r.html | 119 + latest/coreMQTT/globals_s.html | 123 + latest/coreMQTT/globals_t.html | 116 + latest/coreMQTT/globals_type.html | 118 + latest/coreMQTT/globals_u.html | 124 + latest/coreMQTT/globals_v.html | 118 + latest/coreMQTT/globals_vars.html | 112 + latest/coreMQTT/globals_z.html | 114 + .../coreMQTT/group__mqtt__basic__types.html | 127 + latest/coreMQTT/group__mqtt__basic__types.js | 4 + .../group__mqtt__callback__types.html | 264 ++ .../coreMQTT/group__mqtt__callback__types.js | 8 + latest/coreMQTT/group__mqtt__constants.html | 212 ++ latest/coreMQTT/group__mqtt__constants.js | 21 + latest/coreMQTT/group__mqtt__enum__types.html | 366 ++ latest/coreMQTT/group__mqtt__enum__types.js | 51 + .../coreMQTT/group__mqtt__struct__types.html | 159 + latest/coreMQTT/group__mqtt__struct__types.js | 73 + latest/coreMQTT/index.html | 143 + latest/coreMQTT/index.js | 4 + latest/coreMQTT/jquery.js | 34 + latest/coreMQTT/modules.html | 121 + latest/coreMQTT/modules.js | 8 + latest/coreMQTT/mqtt_connect_design.png | Bin 0 -> 179318 bytes latest/coreMQTT/mqtt_connect_function.html | 202 ++ .../mqtt_deserializeack_function.html | 154 + .../mqtt_deserializepublish_function.html | 180 + latest/coreMQTT/mqtt_design.html | 196 ++ latest/coreMQTT/mqtt_disconnect_function.html | 125 + latest/coreMQTT/mqtt_functions.html | 150 + latest/coreMQTT/mqtt_functions.js | 33 + .../mqtt_getconnectpacketsize_function.html | 156 + ...mqtt_getdisconnectpacketsize_function.html | 136 + ...tincomingpackettypeandlength_function.html | 173 + .../coreMQTT/mqtt_getpacketid_function.html | 124 + .../mqtt_getpingreqpacketsize_function.html | 136 + .../mqtt_getpublishpacketsize_function.html | 159 + .../mqtt_getsubackstatuscodes_function.html | 199 ++ .../mqtt_getsubscribepacketsize_function.html | 163 + ...qtt_getunsubscribepacketsize_function.html | 151 + latest/coreMQTT/mqtt_init_function.html | 188 ++ latest/coreMQTT/mqtt_ping_function.html | 125 + latest/coreMQTT/mqtt_porting.html | 161 + latest/coreMQTT/mqtt_processloop_design.png | Bin 0 -> 274031 bytes .../coreMQTT/mqtt_processloop_function.html | 148 + latest/coreMQTT/mqtt_publish_function.html | 162 + .../mqtt_publishtoresend_function.html | 189 ++ latest/coreMQTT/mqtt_receiveloop_design.png | Bin 0 -> 241200 bytes .../coreMQTT/mqtt_receiveloop_function.html | 159 + .../coreMQTT/mqtt_serializeack_function.html | 159 + .../mqtt_serializeconnect_function.html | 164 + .../mqtt_serializedisconnect_function.html | 150 + .../mqtt_serializepingreq_function.html | 150 + .../mqtt_serializepublish_function.html | 172 + .../mqtt_serializepublishheader_function.html | 185 + .../mqtt_serializesubscribe_function.html | 174 + .../mqtt_serializeunsubscribe_function.html | 174 + .../mqtt_status_strerror_function.html | 124 + latest/coreMQTT/mqtt_subscribe_function.html | 167 + latest/coreMQTT/mqtt_timeouts.html | 159 + latest/coreMQTT/mqtt_transport_interface.html | 240 ++ .../coreMQTT/mqtt_unsubscribe_function.html | 164 + latest/coreMQTT/nav_f.png | Bin 0 -> 153 bytes latest/coreMQTT/nav_fd.png | Bin 0 -> 169 bytes latest/coreMQTT/nav_g.png | Bin 0 -> 95 bytes latest/coreMQTT/nav_h.png | Bin 0 -> 98 bytes latest/coreMQTT/nav_hd.png | Bin 0 -> 114 bytes latest/coreMQTT/navtree.css | 150 + latest/coreMQTT/navtree.js | 549 +++ latest/coreMQTT/navtreedata.js | 78 + latest/coreMQTT/navtreeindex0.js | 203 ++ latest/coreMQTT/open.png | Bin 0 -> 123 bytes latest/coreMQTT/pages.html | 168 + latest/coreMQTT/resize.js | 155 + latest/coreMQTT/search/all_0.js | 6 + latest/coreMQTT/search/all_1.js | 4 + latest/coreMQTT/search/all_10.js | 12 + latest/coreMQTT/search/all_11.js | 15 + latest/coreMQTT/search/all_12.js | 15 + latest/coreMQTT/search/all_13.js | 15 + latest/coreMQTT/search/all_14.js | 8 + latest/coreMQTT/search/all_15.js | 5 + latest/coreMQTT/search/all_16.js | 4 + latest/coreMQTT/search/all_2.js | 25 + latest/coreMQTT/search/all_3.js | 13 + latest/coreMQTT/search/all_4.js | 6 + latest/coreMQTT/search/all_5.js | 5 + latest/coreMQTT/search/all_6.js | 7 + latest/coreMQTT/search/all_7.js | 9 + latest/coreMQTT/search/all_8.js | 10 + latest/coreMQTT/search/all_9.js | 5 + latest/coreMQTT/search/all_a.js | 10 + latest/coreMQTT/search/all_b.js | 161 + latest/coreMQTT/search/all_c.js | 6 + latest/coreMQTT/search/all_d.js | 6 + latest/coreMQTT/search/all_e.js | 25 + latest/coreMQTT/search/all_f.js | 4 + latest/coreMQTT/search/classes_0.js | 11 + latest/coreMQTT/search/classes_1.js | 5 + latest/coreMQTT/search/close.svg | 31 + latest/coreMQTT/search/defines_0.js | 6 + latest/coreMQTT/search/defines_1.js | 7 + latest/coreMQTT/search/defines_2.js | 36 + latest/coreMQTT/search/defines_3.js | 5 + latest/coreMQTT/search/defines_4.js | 11 + latest/coreMQTT/search/enums_0.js | 10 + latest/coreMQTT/search/enumvalues_0.js | 41 + latest/coreMQTT/search/files_0.js | 10 + latest/coreMQTT/search/files_1.js | 4 + latest/coreMQTT/search/functions_0.js | 5 + latest/coreMQTT/search/functions_1.js | 8 + latest/coreMQTT/search/functions_2.js | 10 + latest/coreMQTT/search/functions_3.js | 5 + latest/coreMQTT/search/functions_4.js | 4 + latest/coreMQTT/search/functions_5.js | 6 + latest/coreMQTT/search/functions_6.js | 8 + latest/coreMQTT/search/functions_7.js | 5 + latest/coreMQTT/search/functions_8.js | 4 + latest/coreMQTT/search/functions_9.js | 52 + latest/coreMQTT/search/functions_a.js | 5 + latest/coreMQTT/search/functions_b.js | 9 + latest/coreMQTT/search/functions_c.js | 13 + latest/coreMQTT/search/functions_d.js | 6 + latest/coreMQTT/search/functions_e.js | 8 + latest/coreMQTT/search/groups_0.js | 4 + latest/coreMQTT/search/groups_1.js | 5 + latest/coreMQTT/search/groups_2.js | 4 + latest/coreMQTT/search/groups_3.js | 4 + latest/coreMQTT/search/mag.svg | 37 + latest/coreMQTT/search/mag_d.svg | 37 + latest/coreMQTT/search/mag_sel.svg | 74 + latest/coreMQTT/search/mag_seld.svg | 74 + latest/coreMQTT/search/pages_0.js | 4 + latest/coreMQTT/search/pages_1.js | 4 + latest/coreMQTT/search/pages_2.js | 4 + latest/coreMQTT/search/pages_3.js | 33 + latest/coreMQTT/search/pages_4.js | 4 + latest/coreMQTT/search/pages_5.js | 4 + latest/coreMQTT/search/pages_6.js | 5 + latest/coreMQTT/search/search.css | 286 ++ latest/coreMQTT/search/search.js | 816 +++++ latest/coreMQTT/search/searchdata.js | 45 + latest/coreMQTT/search/typedefs_0.js | 6 + latest/coreMQTT/search/typedefs_1.js | 4 + latest/coreMQTT/search/typedefs_2.js | 6 + latest/coreMQTT/search/variables_0.js | 4 + latest/coreMQTT/search/variables_1.js | 7 + latest/coreMQTT/search/variables_10.js | 5 + latest/coreMQTT/search/variables_11.js | 4 + latest/coreMQTT/search/variables_2.js | 5 + latest/coreMQTT/search/variables_3.js | 4 + latest/coreMQTT/search/variables_4.js | 4 + latest/coreMQTT/search/variables_5.js | 8 + latest/coreMQTT/search/variables_6.js | 5 + latest/coreMQTT/search/variables_7.js | 5 + latest/coreMQTT/search/variables_8.js | 5 + latest/coreMQTT/search/variables_9.js | 5 + latest/coreMQTT/search/variables_a.js | 19 + latest/coreMQTT/search/variables_b.js | 4 + latest/coreMQTT/search/variables_c.js | 6 + latest/coreMQTT/search/variables_d.js | 5 + latest/coreMQTT/search/variables_e.js | 7 + latest/coreMQTT/search/variables_f.js | 4 + latest/coreMQTT/splitbar.png | Bin 0 -> 314 bytes latest/coreMQTT/splitbard.png | Bin 0 -> 282 bytes .../struct_m_q_t_t_connect_info__t.html | 161 + .../coreMQTT/struct_m_q_t_t_context__t.html | 197 ++ .../struct_m_q_t_t_deserialized_info__t.html | 141 + .../struct_m_q_t_t_fixed_buffer__t.html | 138 + .../struct_m_q_t_t_packet_info__t.html | 145 + .../struct_m_q_t_t_pub_ack_info__t.html | 141 + .../struct_m_q_t_t_publish_info__t.html | 157 + .../struct_m_q_t_t_subscribe_info__t.html | 141 + .../struct_transport_interface__t.html | 198 ++ .../struct_transport_out_vector__t.html | 137 + latest/coreMQTT/style.css | 132 + latest/coreMQTT/sync_off.png | Bin 0 -> 853 bytes latest/coreMQTT/sync_on.png | Bin 0 -> 845 bytes latest/coreMQTT/tab_a.png | Bin 0 -> 142 bytes latest/coreMQTT/tab_ad.png | Bin 0 -> 135 bytes latest/coreMQTT/tab_b.png | Bin 0 -> 169 bytes latest/coreMQTT/tab_bd.png | Bin 0 -> 173 bytes latest/coreMQTT/tab_h.png | Bin 0 -> 177 bytes latest/coreMQTT/tab_hd.png | Bin 0 -> 180 bytes latest/coreMQTT/tab_s.png | Bin 0 -> 184 bytes latest/coreMQTT/tab_sd.png | Bin 0 -> 188 bytes latest/coreMQTT/tabs.css | 1 + latest/coreMQTT/transport__interface_8h.html | 151 + .../transport__interface_8h_source.html | 208 ++ latest/core__mqtt__agent_8c.html | 1964 +++++++++++ latest/core__mqtt__agent_8h.html | 1197 +++++++ latest/core__mqtt__agent_8h_source.html | 374 ++ ...e__mqtt__agent__command__functions_8c.html | 540 +++ ...e__mqtt__agent__command__functions_8h.html | 642 ++++ ...__agent__command__functions_8h_source.html | 253 ++ ...ore__mqtt__agent__config__defaults_8h.html | 215 ++ ...tt__agent__config__defaults_8h_source.html | 178 + ...ore__mqtt__agent__default__logging_8h.html | 232 ++ ...tt__agent__default__logging_8h_source.html | 167 + ...e__mqtt__agent__message__interface_8h.html | 251 ++ ...__agent__message__interface_8h_source.html | 208 ++ latest/core_mqtt_agent_config.html | 160 + .../dir_359d2bec989c9a8deeeb9aee335c1c76.html | 113 + .../dir_49e56c817e5e54854c35e136979f97ca.html | 113 + .../dir_8ee1a5e78eaec319fe5d64075812fc61.html | 132 + .../dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html | 128 + latest/doc.png | Bin 0 -> 746 bytes latest/docd.png | Bin 0 -> 756 bytes latest/doxygen.css | 1989 +++++++++++ latest/doxygen.svg | 26 + latest/dynsections.js | 123 + latest/files.html | 125 + latest/folderclosed.png | Bin 0 -> 616 bytes latest/folderopen.png | Bin 0 -> 597 bytes latest/functions.html | 184 + latest/functions_vars.html | 184 + latest/globals.html | 233 ++ latest/globals_defs.html | 120 + latest/globals_enum.html | 112 + latest/globals_eval.html | 121 + latest/globals_func.html | 180 + latest/globals_type.html | 120 + .../group__mqtt__agent__callback__types.html | 181 + latest/group__mqtt__agent__callback__types.js | 5 + latest/group__mqtt__agent__enum__types.html | 179 + latest/group__mqtt__agent__enum__types.js | 15 + latest/group__mqtt__agent__struct__types.html | 180 + latest/group__mqtt__agent__struct__types.js | 55 + latest/index.html | 140 + latest/index.js | 5 + latest/jquery.js | 34 + latest/modules.html | 119 + latest/modules.js | 6 + latest/mqtt_agent_cancel_function.html | 146 + latest/mqtt_agent_command_function.html | 156 + latest/mqtt_agent_connect_function.html | 211 ++ latest/mqtt_agent_design.html | 180 + latest/mqtt_agent_disconnect_function.html | 162 + latest/mqtt_agent_functions.html | 138 + latest/mqtt_agent_functions.js | 16 + latest/mqtt_agent_init_function.html | 219 ++ latest/mqtt_agent_message_interface.html | 239 ++ latest/mqtt_agent_ping_function.html | 160 + latest/mqtt_agent_publish_function.html | 176 + latest/mqtt_agent_resume_function.html | 151 + latest/mqtt_agent_subscribe_function.html | 176 + latest/mqtt_agent_terminate_function.html | 161 + latest/mqtt_agent_unsubscribe_function.html | 175 + latest/nav_f.png | Bin 0 -> 153 bytes latest/nav_fd.png | Bin 0 -> 169 bytes latest/nav_g.png | Bin 0 -> 95 bytes latest/nav_h.png | Bin 0 -> 98 bytes latest/nav_hd.png | Bin 0 -> 114 bytes latest/navtree.css | 150 + latest/navtree.js | 549 +++ latest/navtreedata.js | 54 + latest/navtreeindex0.js | 93 + latest/open.png | Bin 0 -> 123 bytes latest/pages.html | 134 + latest/resize.js | 155 + latest/search/all_0.js | 8 + latest/search/all_1.js | 5 + latest/search/all_10.js | 10 + latest/search/all_11.js | 7 + latest/search/all_12.js | 17 + latest/search/all_13.js | 5 + latest/search/all_14.js | 5 + latest/search/all_15.js | 5 + latest/search/all_2.js | 31 + latest/search/all_3.js | 7 + latest/search/all_4.js | 5 + latest/search/all_5.js | 4 + latest/search/all_6.js | 7 + latest/search/all_7.js | 5 + latest/search/all_8.js | 9 + latest/search/all_9.js | 5 + latest/search/all_a.js | 9 + latest/search/all_b.js | 133 + latest/search/all_c.js | 9 + latest/search/all_d.js | 6 + latest/search/all_e.js | 39 + latest/search/all_f.js | 4 + latest/search/classes_0.js | 20 + latest/search/classes_1.js | 5 + latest/search/close.svg | 31 + latest/search/defines_0.js | 7 + latest/search/defines_1.js | 8 + latest/search/enums_0.js | 10 + latest/search/enumvalues_0.js | 4 + latest/search/enumvalues_1.js | 4 + latest/search/enumvalues_2.js | 5 + latest/search/enumvalues_3.js | 6 + latest/search/enumvalues_4.js | 4 + latest/search/enumvalues_5.js | 4 + latest/search/enumvalues_6.js | 4 + latest/search/files_0.js | 17 + latest/search/files_1.js | 4 + latest/search/functions_0.js | 5 + latest/search/functions_1.js | 7 + latest/search/functions_2.js | 5 + latest/search/functions_3.js | 4 + latest/search/functions_4.js | 4 + latest/search/functions_5.js | 24 + latest/search/functions_6.js | 4 + latest/search/functions_7.js | 4 + latest/search/functions_8.js | 5 + latest/search/groups_0.js | 4 + latest/search/groups_1.js | 5 + latest/search/groups_2.js | 4 + latest/search/groups_3.js | 4 + latest/search/mag.svg | 37 + latest/search/mag_d.svg | 37 + latest/search/mag_sel.svg | 74 + latest/search/mag_seld.svg | 74 + latest/search/pages_0.js | 4 + latest/search/pages_1.js | 4 + latest/search/pages_2.js | 4 + latest/search/pages_3.js | 45 + latest/search/pages_4.js | 4 + latest/search/pages_5.js | 4 + latest/search/pages_6.js | 5 + latest/search/search.css | 286 ++ latest/search/search.js | 816 +++++ latest/search/searchdata.js | 45 + latest/search/typedefs_0.js | 15 + latest/search/typedefs_1.js | 4 + latest/search/typedefs_2.js | 6 + latest/search/variables_0.js | 6 + latest/search/variables_1.js | 4 + latest/search/variables_10.js | 6 + latest/search/variables_11.js | 8 + latest/search/variables_12.js | 4 + latest/search/variables_13.js | 5 + latest/search/variables_2.js | 9 + latest/search/variables_3.js | 5 + latest/search/variables_4.js | 4 + latest/search/variables_5.js | 5 + latest/search/variables_6.js | 4 + latest/search/variables_7.js | 8 + latest/search/variables_8.js | 5 + latest/search/variables_9.js | 5 + latest/search/variables_a.js | 40 + latest/search/variables_b.js | 6 + latest/search/variables_c.js | 5 + latest/search/variables_d.js | 33 + latest/search/variables_e.js | 4 + latest/search/variables_f.js | 9 + latest/splitbar.png | Bin 0 -> 314 bytes latest/splitbard.png | Bin 0 -> 282 bytes latest/struct_m_q_t_t_agent_ack_info__t.html | 164 + latest/struct_m_q_t_t_agent_command.html | 146 + ...m_q_t_t_agent_command_func_returns__t.html | 145 + .../struct_m_q_t_t_agent_command_info__t.html | 141 + .../struct_m_q_t_t_agent_connect_args__t.html | 145 + latest/struct_m_q_t_t_agent_context__t.html | 232 ++ ...ct_m_q_t_t_agent_message_interface__t.html | 215 ++ .../struct_m_q_t_t_agent_return_info__t.html | 164 + ...truct_m_q_t_t_agent_subscribe_args__t.html | 137 + latest/style.css | 132 + latest/sync_off.png | Bin 0 -> 853 bytes latest/sync_on.png | Bin 0 -> 845 bytes latest/tab_a.png | Bin 0 -> 142 bytes latest/tab_ad.png | Bin 0 -> 135 bytes latest/tab_b.png | Bin 0 -> 169 bytes latest/tab_bd.png | Bin 0 -> 173 bytes latest/tab_h.png | Bin 0 -> 177 bytes latest/tab_hd.png | Bin 0 -> 180 bytes latest/tab_s.png | Bin 0 -> 184 bytes latest/tab_sd.png | Bin 0 -> 188 bytes latest/tabs.css | 1 + v1.3.0/annotated.html | 125 + v1.3.0/bc_s.png | Bin 0 -> 676 bytes v1.3.0/bc_sd.png | Bin 0 -> 635 bytes v1.3.0/bdwn.png | Bin 0 -> 147 bytes v1.3.0/classes.html | 118 + v1.3.0/closed.png | Bin 0 -> 132 bytes v1.3.0/coreMQTT/annotated.html | 126 + v1.3.0/coreMQTT/bc_s.png | Bin 0 -> 676 bytes v1.3.0/coreMQTT/bc_sd.png | Bin 0 -> 635 bytes v1.3.0/coreMQTT/bdwn.png | Bin 0 -> 147 bytes v1.3.0/coreMQTT/classes.html | 121 + v1.3.0/coreMQTT/closed.png | Bin 0 -> 132 bytes v1.3.0/coreMQTT/core__mqtt_8c.html | 2824 ++++++++++++++++ v1.3.0/coreMQTT/core__mqtt_8h.html | 1281 +++++++ v1.3.0/coreMQTT/core__mqtt_8h_source.html | 423 +++ .../core__mqtt__config__defaults_8h.html | 396 +++ ...ore__mqtt__config__defaults_8h_source.html | 218 ++ .../coreMQTT/core__mqtt__serializer_8c.html | 3003 +++++++++++++++++ .../coreMQTT/core__mqtt__serializer_8h.html | 1675 +++++++++ .../core__mqtt__serializer_8h_source.html | 466 +++ v1.3.0/coreMQTT/core__mqtt__state_8c.html | 1371 ++++++++ v1.3.0/coreMQTT/core__mqtt__state_8h.html | 250 ++ .../coreMQTT/core__mqtt__state_8h_source.html | 209 ++ v1.3.0/coreMQTT/core_mqtt_config.html | 176 + .../dir_359d2bec989c9a8deeeb9aee335c1c76.html | 113 + .../dir_3750548c40d9045ee3b3d006c00db089.html | 120 + .../dir_49e56c817e5e54854c35e136979f97ca.html | 113 + .../dir_8ee1a5e78eaec319fe5d64075812fc61.html | 129 + .../dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html | 133 + v1.3.0/coreMQTT/doc.png | Bin 0 -> 746 bytes v1.3.0/coreMQTT/docd.png | Bin 0 -> 756 bytes v1.3.0/coreMQTT/doxygen.css | 1989 +++++++++++ v1.3.0/coreMQTT/doxygen.svg | 26 + v1.3.0/coreMQTT/dynsections.js | 123 + v1.3.0/coreMQTT/files.html | 127 + v1.3.0/coreMQTT/folderclosed.png | Bin 0 -> 616 bytes v1.3.0/coreMQTT/folderopen.png | Bin 0 -> 597 bytes v1.3.0/coreMQTT/functions.html | 228 ++ v1.3.0/coreMQTT/functions_vars.html | 228 ++ v1.3.0/coreMQTT/globals.html | 115 + v1.3.0/coreMQTT/globals_c.html | 121 + v1.3.0/coreMQTT/globals_d.html | 120 + v1.3.0/coreMQTT/globals_defs.html | 197 ++ v1.3.0/coreMQTT/globals_e.html | 115 + v1.3.0/coreMQTT/globals_enum.html | 118 + v1.3.0/coreMQTT/globals_eval.html | 151 + v1.3.0/coreMQTT/globals_f.html | 114 + v1.3.0/coreMQTT/globals_func.html | 272 ++ v1.3.0/coreMQTT/globals_g.html | 116 + v1.3.0/coreMQTT/globals_h.html | 118 + v1.3.0/coreMQTT/globals_i.html | 115 + v1.3.0/coreMQTT/globals_l.html | 118 + v1.3.0/coreMQTT/globals_m.html | 261 ++ v1.3.0/coreMQTT/globals_n.html | 114 + v1.3.0/coreMQTT/globals_p.html | 117 + v1.3.0/coreMQTT/globals_r.html | 119 + v1.3.0/coreMQTT/globals_s.html | 123 + v1.3.0/coreMQTT/globals_t.html | 116 + v1.3.0/coreMQTT/globals_type.html | 118 + v1.3.0/coreMQTT/globals_u.html | 124 + v1.3.0/coreMQTT/globals_v.html | 118 + v1.3.0/coreMQTT/globals_vars.html | 112 + v1.3.0/coreMQTT/globals_z.html | 114 + .../coreMQTT/group__mqtt__basic__types.html | 127 + v1.3.0/coreMQTT/group__mqtt__basic__types.js | 4 + .../group__mqtt__callback__types.html | 264 ++ .../coreMQTT/group__mqtt__callback__types.js | 8 + v1.3.0/coreMQTT/group__mqtt__constants.html | 212 ++ v1.3.0/coreMQTT/group__mqtt__constants.js | 21 + v1.3.0/coreMQTT/group__mqtt__enum__types.html | 366 ++ v1.3.0/coreMQTT/group__mqtt__enum__types.js | 51 + .../coreMQTT/group__mqtt__struct__types.html | 159 + v1.3.0/coreMQTT/group__mqtt__struct__types.js | 73 + v1.3.0/coreMQTT/index.html | 143 + v1.3.0/coreMQTT/index.js | 4 + v1.3.0/coreMQTT/jquery.js | 34 + v1.3.0/coreMQTT/modules.html | 121 + v1.3.0/coreMQTT/modules.js | 8 + v1.3.0/coreMQTT/mqtt_connect_design.png | Bin 0 -> 179318 bytes v1.3.0/coreMQTT/mqtt_connect_function.html | 202 ++ .../mqtt_deserializeack_function.html | 154 + .../mqtt_deserializepublish_function.html | 180 + v1.3.0/coreMQTT/mqtt_design.html | 196 ++ v1.3.0/coreMQTT/mqtt_disconnect_function.html | 125 + v1.3.0/coreMQTT/mqtt_functions.html | 150 + v1.3.0/coreMQTT/mqtt_functions.js | 33 + .../mqtt_getconnectpacketsize_function.html | 156 + ...mqtt_getdisconnectpacketsize_function.html | 136 + ...tincomingpackettypeandlength_function.html | 173 + .../coreMQTT/mqtt_getpacketid_function.html | 124 + .../mqtt_getpingreqpacketsize_function.html | 136 + .../mqtt_getpublishpacketsize_function.html | 159 + .../mqtt_getsubackstatuscodes_function.html | 199 ++ .../mqtt_getsubscribepacketsize_function.html | 163 + ...qtt_getunsubscribepacketsize_function.html | 151 + v1.3.0/coreMQTT/mqtt_init_function.html | 188 ++ v1.3.0/coreMQTT/mqtt_ping_function.html | 125 + v1.3.0/coreMQTT/mqtt_porting.html | 161 + v1.3.0/coreMQTT/mqtt_processloop_design.png | Bin 0 -> 274031 bytes .../coreMQTT/mqtt_processloop_function.html | 148 + v1.3.0/coreMQTT/mqtt_publish_function.html | 162 + .../mqtt_publishtoresend_function.html | 189 ++ v1.3.0/coreMQTT/mqtt_receiveloop_design.png | Bin 0 -> 241200 bytes .../coreMQTT/mqtt_receiveloop_function.html | 159 + .../coreMQTT/mqtt_serializeack_function.html | 159 + .../mqtt_serializeconnect_function.html | 164 + .../mqtt_serializedisconnect_function.html | 150 + .../mqtt_serializepingreq_function.html | 150 + .../mqtt_serializepublish_function.html | 172 + .../mqtt_serializepublishheader_function.html | 185 + .../mqtt_serializesubscribe_function.html | 174 + .../mqtt_serializeunsubscribe_function.html | 174 + .../mqtt_status_strerror_function.html | 124 + v1.3.0/coreMQTT/mqtt_subscribe_function.html | 167 + v1.3.0/coreMQTT/mqtt_timeouts.html | 159 + v1.3.0/coreMQTT/mqtt_transport_interface.html | 240 ++ .../coreMQTT/mqtt_unsubscribe_function.html | 164 + v1.3.0/coreMQTT/nav_f.png | Bin 0 -> 153 bytes v1.3.0/coreMQTT/nav_fd.png | Bin 0 -> 169 bytes v1.3.0/coreMQTT/nav_g.png | Bin 0 -> 95 bytes v1.3.0/coreMQTT/nav_h.png | Bin 0 -> 98 bytes v1.3.0/coreMQTT/nav_hd.png | Bin 0 -> 114 bytes v1.3.0/coreMQTT/navtree.css | 150 + v1.3.0/coreMQTT/navtree.js | 549 +++ v1.3.0/coreMQTT/navtreedata.js | 78 + v1.3.0/coreMQTT/navtreeindex0.js | 203 ++ v1.3.0/coreMQTT/open.png | Bin 0 -> 123 bytes v1.3.0/coreMQTT/pages.html | 168 + v1.3.0/coreMQTT/resize.js | 155 + v1.3.0/coreMQTT/search/all_0.js | 6 + v1.3.0/coreMQTT/search/all_1.js | 4 + v1.3.0/coreMQTT/search/all_10.js | 12 + v1.3.0/coreMQTT/search/all_11.js | 15 + v1.3.0/coreMQTT/search/all_12.js | 15 + v1.3.0/coreMQTT/search/all_13.js | 15 + v1.3.0/coreMQTT/search/all_14.js | 8 + v1.3.0/coreMQTT/search/all_15.js | 5 + v1.3.0/coreMQTT/search/all_16.js | 4 + v1.3.0/coreMQTT/search/all_2.js | 25 + v1.3.0/coreMQTT/search/all_3.js | 13 + v1.3.0/coreMQTT/search/all_4.js | 6 + v1.3.0/coreMQTT/search/all_5.js | 5 + v1.3.0/coreMQTT/search/all_6.js | 7 + v1.3.0/coreMQTT/search/all_7.js | 9 + v1.3.0/coreMQTT/search/all_8.js | 10 + v1.3.0/coreMQTT/search/all_9.js | 5 + v1.3.0/coreMQTT/search/all_a.js | 10 + v1.3.0/coreMQTT/search/all_b.js | 161 + v1.3.0/coreMQTT/search/all_c.js | 6 + v1.3.0/coreMQTT/search/all_d.js | 6 + v1.3.0/coreMQTT/search/all_e.js | 25 + v1.3.0/coreMQTT/search/all_f.js | 4 + v1.3.0/coreMQTT/search/classes_0.js | 11 + v1.3.0/coreMQTT/search/classes_1.js | 5 + v1.3.0/coreMQTT/search/close.svg | 31 + v1.3.0/coreMQTT/search/defines_0.js | 6 + v1.3.0/coreMQTT/search/defines_1.js | 7 + v1.3.0/coreMQTT/search/defines_2.js | 36 + v1.3.0/coreMQTT/search/defines_3.js | 5 + v1.3.0/coreMQTT/search/defines_4.js | 11 + v1.3.0/coreMQTT/search/enums_0.js | 10 + v1.3.0/coreMQTT/search/enumvalues_0.js | 41 + v1.3.0/coreMQTT/search/files_0.js | 10 + v1.3.0/coreMQTT/search/files_1.js | 4 + v1.3.0/coreMQTT/search/functions_0.js | 5 + v1.3.0/coreMQTT/search/functions_1.js | 8 + v1.3.0/coreMQTT/search/functions_2.js | 10 + v1.3.0/coreMQTT/search/functions_3.js | 5 + v1.3.0/coreMQTT/search/functions_4.js | 4 + v1.3.0/coreMQTT/search/functions_5.js | 6 + v1.3.0/coreMQTT/search/functions_6.js | 8 + v1.3.0/coreMQTT/search/functions_7.js | 5 + v1.3.0/coreMQTT/search/functions_8.js | 4 + v1.3.0/coreMQTT/search/functions_9.js | 52 + v1.3.0/coreMQTT/search/functions_a.js | 5 + v1.3.0/coreMQTT/search/functions_b.js | 9 + v1.3.0/coreMQTT/search/functions_c.js | 13 + v1.3.0/coreMQTT/search/functions_d.js | 6 + v1.3.0/coreMQTT/search/functions_e.js | 8 + v1.3.0/coreMQTT/search/groups_0.js | 4 + v1.3.0/coreMQTT/search/groups_1.js | 5 + v1.3.0/coreMQTT/search/groups_2.js | 4 + v1.3.0/coreMQTT/search/groups_3.js | 4 + v1.3.0/coreMQTT/search/mag.svg | 37 + v1.3.0/coreMQTT/search/mag_d.svg | 37 + v1.3.0/coreMQTT/search/mag_sel.svg | 74 + v1.3.0/coreMQTT/search/mag_seld.svg | 74 + v1.3.0/coreMQTT/search/pages_0.js | 4 + v1.3.0/coreMQTT/search/pages_1.js | 4 + v1.3.0/coreMQTT/search/pages_2.js | 4 + v1.3.0/coreMQTT/search/pages_3.js | 33 + v1.3.0/coreMQTT/search/pages_4.js | 4 + v1.3.0/coreMQTT/search/pages_5.js | 4 + v1.3.0/coreMQTT/search/pages_6.js | 5 + v1.3.0/coreMQTT/search/search.css | 286 ++ v1.3.0/coreMQTT/search/search.js | 816 +++++ v1.3.0/coreMQTT/search/searchdata.js | 45 + v1.3.0/coreMQTT/search/typedefs_0.js | 6 + v1.3.0/coreMQTT/search/typedefs_1.js | 4 + v1.3.0/coreMQTT/search/typedefs_2.js | 6 + v1.3.0/coreMQTT/search/variables_0.js | 4 + v1.3.0/coreMQTT/search/variables_1.js | 7 + v1.3.0/coreMQTT/search/variables_10.js | 5 + v1.3.0/coreMQTT/search/variables_11.js | 4 + v1.3.0/coreMQTT/search/variables_2.js | 5 + v1.3.0/coreMQTT/search/variables_3.js | 4 + v1.3.0/coreMQTT/search/variables_4.js | 4 + v1.3.0/coreMQTT/search/variables_5.js | 8 + v1.3.0/coreMQTT/search/variables_6.js | 5 + v1.3.0/coreMQTT/search/variables_7.js | 5 + v1.3.0/coreMQTT/search/variables_8.js | 5 + v1.3.0/coreMQTT/search/variables_9.js | 5 + v1.3.0/coreMQTT/search/variables_a.js | 19 + v1.3.0/coreMQTT/search/variables_b.js | 4 + v1.3.0/coreMQTT/search/variables_c.js | 6 + v1.3.0/coreMQTT/search/variables_d.js | 5 + v1.3.0/coreMQTT/search/variables_e.js | 7 + v1.3.0/coreMQTT/search/variables_f.js | 4 + v1.3.0/coreMQTT/splitbar.png | Bin 0 -> 314 bytes v1.3.0/coreMQTT/splitbard.png | Bin 0 -> 282 bytes .../struct_m_q_t_t_connect_info__t.html | 161 + .../coreMQTT/struct_m_q_t_t_context__t.html | 197 ++ .../struct_m_q_t_t_deserialized_info__t.html | 141 + .../struct_m_q_t_t_fixed_buffer__t.html | 138 + .../struct_m_q_t_t_packet_info__t.html | 145 + .../struct_m_q_t_t_pub_ack_info__t.html | 141 + .../struct_m_q_t_t_publish_info__t.html | 157 + .../struct_m_q_t_t_subscribe_info__t.html | 141 + .../struct_transport_interface__t.html | 198 ++ .../struct_transport_out_vector__t.html | 137 + v1.3.0/coreMQTT/style.css | 132 + v1.3.0/coreMQTT/sync_off.png | Bin 0 -> 853 bytes v1.3.0/coreMQTT/sync_on.png | Bin 0 -> 845 bytes v1.3.0/coreMQTT/tab_a.png | Bin 0 -> 142 bytes v1.3.0/coreMQTT/tab_ad.png | Bin 0 -> 135 bytes v1.3.0/coreMQTT/tab_b.png | Bin 0 -> 169 bytes v1.3.0/coreMQTT/tab_bd.png | Bin 0 -> 173 bytes v1.3.0/coreMQTT/tab_h.png | Bin 0 -> 177 bytes v1.3.0/coreMQTT/tab_hd.png | Bin 0 -> 180 bytes v1.3.0/coreMQTT/tab_s.png | Bin 0 -> 184 bytes v1.3.0/coreMQTT/tab_sd.png | Bin 0 -> 188 bytes v1.3.0/coreMQTT/tabs.css | 1 + v1.3.0/coreMQTT/transport__interface_8h.html | 151 + .../transport__interface_8h_source.html | 208 ++ v1.3.0/core__mqtt__agent_8c.html | 1964 +++++++++++ v1.3.0/core__mqtt__agent_8h.html | 1197 +++++++ v1.3.0/core__mqtt__agent_8h_source.html | 374 ++ ...e__mqtt__agent__command__functions_8c.html | 540 +++ ...e__mqtt__agent__command__functions_8h.html | 642 ++++ ...__agent__command__functions_8h_source.html | 253 ++ ...ore__mqtt__agent__config__defaults_8h.html | 215 ++ ...tt__agent__config__defaults_8h_source.html | 178 + ...ore__mqtt__agent__default__logging_8h.html | 232 ++ ...tt__agent__default__logging_8h_source.html | 167 + ...e__mqtt__agent__message__interface_8h.html | 251 ++ ...__agent__message__interface_8h_source.html | 208 ++ v1.3.0/core_mqtt_agent_config.html | 160 + .../dir_359d2bec989c9a8deeeb9aee335c1c76.html | 113 + .../dir_49e56c817e5e54854c35e136979f97ca.html | 113 + .../dir_8ee1a5e78eaec319fe5d64075812fc61.html | 132 + .../dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html | 128 + v1.3.0/doc.png | Bin 0 -> 746 bytes v1.3.0/docd.png | Bin 0 -> 756 bytes v1.3.0/doxygen.css | 1989 +++++++++++ v1.3.0/doxygen.svg | 26 + v1.3.0/dynsections.js | 123 + v1.3.0/files.html | 125 + v1.3.0/folderclosed.png | Bin 0 -> 616 bytes v1.3.0/folderopen.png | Bin 0 -> 597 bytes v1.3.0/functions.html | 184 + v1.3.0/functions_vars.html | 184 + v1.3.0/globals.html | 233 ++ v1.3.0/globals_defs.html | 120 + v1.3.0/globals_enum.html | 112 + v1.3.0/globals_eval.html | 121 + v1.3.0/globals_func.html | 180 + v1.3.0/globals_type.html | 120 + .../group__mqtt__agent__callback__types.html | 181 + v1.3.0/group__mqtt__agent__callback__types.js | 5 + v1.3.0/group__mqtt__agent__enum__types.html | 179 + v1.3.0/group__mqtt__agent__enum__types.js | 15 + v1.3.0/group__mqtt__agent__struct__types.html | 180 + v1.3.0/group__mqtt__agent__struct__types.js | 55 + v1.3.0/index.html | 140 + v1.3.0/index.js | 5 + v1.3.0/jquery.js | 34 + v1.3.0/modules.html | 119 + v1.3.0/modules.js | 6 + v1.3.0/mqtt_agent_cancel_function.html | 146 + v1.3.0/mqtt_agent_command_function.html | 156 + v1.3.0/mqtt_agent_connect_function.html | 211 ++ v1.3.0/mqtt_agent_design.html | 180 + v1.3.0/mqtt_agent_disconnect_function.html | 162 + v1.3.0/mqtt_agent_functions.html | 138 + v1.3.0/mqtt_agent_functions.js | 16 + v1.3.0/mqtt_agent_init_function.html | 219 ++ v1.3.0/mqtt_agent_message_interface.html | 239 ++ v1.3.0/mqtt_agent_ping_function.html | 160 + v1.3.0/mqtt_agent_publish_function.html | 176 + v1.3.0/mqtt_agent_resume_function.html | 151 + v1.3.0/mqtt_agent_subscribe_function.html | 176 + v1.3.0/mqtt_agent_terminate_function.html | 161 + v1.3.0/mqtt_agent_unsubscribe_function.html | 175 + v1.3.0/nav_f.png | Bin 0 -> 153 bytes v1.3.0/nav_fd.png | Bin 0 -> 169 bytes v1.3.0/nav_g.png | Bin 0 -> 95 bytes v1.3.0/nav_h.png | Bin 0 -> 98 bytes v1.3.0/nav_hd.png | Bin 0 -> 114 bytes v1.3.0/navtree.css | 150 + v1.3.0/navtree.js | 549 +++ v1.3.0/navtreedata.js | 54 + v1.3.0/navtreeindex0.js | 93 + v1.3.0/open.png | Bin 0 -> 123 bytes v1.3.0/pages.html | 134 + v1.3.0/resize.js | 155 + v1.3.0/search/all_0.js | 8 + v1.3.0/search/all_1.js | 5 + v1.3.0/search/all_10.js | 10 + v1.3.0/search/all_11.js | 7 + v1.3.0/search/all_12.js | 17 + v1.3.0/search/all_13.js | 5 + v1.3.0/search/all_14.js | 5 + v1.3.0/search/all_15.js | 5 + v1.3.0/search/all_2.js | 31 + v1.3.0/search/all_3.js | 7 + v1.3.0/search/all_4.js | 5 + v1.3.0/search/all_5.js | 4 + v1.3.0/search/all_6.js | 7 + v1.3.0/search/all_7.js | 5 + v1.3.0/search/all_8.js | 9 + v1.3.0/search/all_9.js | 5 + v1.3.0/search/all_a.js | 9 + v1.3.0/search/all_b.js | 133 + v1.3.0/search/all_c.js | 9 + v1.3.0/search/all_d.js | 6 + v1.3.0/search/all_e.js | 39 + v1.3.0/search/all_f.js | 4 + v1.3.0/search/classes_0.js | 20 + v1.3.0/search/classes_1.js | 5 + v1.3.0/search/close.svg | 31 + v1.3.0/search/defines_0.js | 7 + v1.3.0/search/defines_1.js | 8 + v1.3.0/search/enums_0.js | 10 + v1.3.0/search/enumvalues_0.js | 4 + v1.3.0/search/enumvalues_1.js | 4 + v1.3.0/search/enumvalues_2.js | 5 + v1.3.0/search/enumvalues_3.js | 6 + v1.3.0/search/enumvalues_4.js | 4 + v1.3.0/search/enumvalues_5.js | 4 + v1.3.0/search/enumvalues_6.js | 4 + v1.3.0/search/files_0.js | 17 + v1.3.0/search/files_1.js | 4 + v1.3.0/search/functions_0.js | 5 + v1.3.0/search/functions_1.js | 7 + v1.3.0/search/functions_2.js | 5 + v1.3.0/search/functions_3.js | 4 + v1.3.0/search/functions_4.js | 4 + v1.3.0/search/functions_5.js | 24 + v1.3.0/search/functions_6.js | 4 + v1.3.0/search/functions_7.js | 4 + v1.3.0/search/functions_8.js | 5 + v1.3.0/search/groups_0.js | 4 + v1.3.0/search/groups_1.js | 5 + v1.3.0/search/groups_2.js | 4 + v1.3.0/search/groups_3.js | 4 + v1.3.0/search/mag.svg | 37 + v1.3.0/search/mag_d.svg | 37 + v1.3.0/search/mag_sel.svg | 74 + v1.3.0/search/mag_seld.svg | 74 + v1.3.0/search/pages_0.js | 4 + v1.3.0/search/pages_1.js | 4 + v1.3.0/search/pages_2.js | 4 + v1.3.0/search/pages_3.js | 45 + v1.3.0/search/pages_4.js | 4 + v1.3.0/search/pages_5.js | 4 + v1.3.0/search/pages_6.js | 5 + v1.3.0/search/search.css | 286 ++ v1.3.0/search/search.js | 816 +++++ v1.3.0/search/searchdata.js | 45 + v1.3.0/search/typedefs_0.js | 15 + v1.3.0/search/typedefs_1.js | 4 + v1.3.0/search/typedefs_2.js | 6 + v1.3.0/search/variables_0.js | 6 + v1.3.0/search/variables_1.js | 4 + v1.3.0/search/variables_10.js | 6 + v1.3.0/search/variables_11.js | 8 + v1.3.0/search/variables_12.js | 4 + v1.3.0/search/variables_13.js | 5 + v1.3.0/search/variables_2.js | 9 + v1.3.0/search/variables_3.js | 5 + v1.3.0/search/variables_4.js | 4 + v1.3.0/search/variables_5.js | 5 + v1.3.0/search/variables_6.js | 4 + v1.3.0/search/variables_7.js | 8 + v1.3.0/search/variables_8.js | 5 + v1.3.0/search/variables_9.js | 5 + v1.3.0/search/variables_a.js | 40 + v1.3.0/search/variables_b.js | 6 + v1.3.0/search/variables_c.js | 5 + v1.3.0/search/variables_d.js | 33 + v1.3.0/search/variables_e.js | 4 + v1.3.0/search/variables_f.js | 9 + v1.3.0/splitbar.png | Bin 0 -> 314 bytes v1.3.0/splitbard.png | Bin 0 -> 282 bytes v1.3.0/struct_m_q_t_t_agent_ack_info__t.html | 164 + v1.3.0/struct_m_q_t_t_agent_command.html | 146 + ...m_q_t_t_agent_command_func_returns__t.html | 145 + .../struct_m_q_t_t_agent_command_info__t.html | 141 + .../struct_m_q_t_t_agent_connect_args__t.html | 145 + v1.3.0/struct_m_q_t_t_agent_context__t.html | 232 ++ ...ct_m_q_t_t_agent_message_interface__t.html | 215 ++ .../struct_m_q_t_t_agent_return_info__t.html | 164 + ...truct_m_q_t_t_agent_subscribe_args__t.html | 137 + v1.3.0/style.css | 132 + v1.3.0/sync_off.png | Bin 0 -> 853 bytes v1.3.0/sync_on.png | Bin 0 -> 845 bytes v1.3.0/tab_a.png | Bin 0 -> 142 bytes v1.3.0/tab_ad.png | Bin 0 -> 135 bytes v1.3.0/tab_b.png | Bin 0 -> 169 bytes v1.3.0/tab_bd.png | Bin 0 -> 173 bytes v1.3.0/tab_h.png | Bin 0 -> 177 bytes v1.3.0/tab_hd.png | Bin 0 -> 180 bytes v1.3.0/tab_s.png | Bin 0 -> 184 bytes v1.3.0/tab_sd.png | Bin 0 -> 188 bytes v1.3.0/tabs.css | 1 + 852 files changed, 102027 insertions(+), 1 deletion(-) delete mode 120000 latest create mode 100644 latest/annotated.html create mode 100644 latest/bc_s.png create mode 100644 latest/bc_sd.png create mode 100644 latest/bdwn.png create mode 100644 latest/classes.html create mode 100644 latest/closed.png create mode 100644 latest/coreMQTT/annotated.html create mode 100644 latest/coreMQTT/bc_s.png create mode 100644 latest/coreMQTT/bc_sd.png create mode 100644 latest/coreMQTT/bdwn.png create mode 100644 latest/coreMQTT/classes.html create mode 100644 latest/coreMQTT/closed.png create mode 100644 latest/coreMQTT/core__mqtt_8c.html create mode 100644 latest/coreMQTT/core__mqtt_8h.html create mode 100644 latest/coreMQTT/core__mqtt_8h_source.html create mode 100644 latest/coreMQTT/core__mqtt__config__defaults_8h.html create mode 100644 latest/coreMQTT/core__mqtt__config__defaults_8h_source.html create mode 100644 latest/coreMQTT/core__mqtt__serializer_8c.html create mode 100644 latest/coreMQTT/core__mqtt__serializer_8h.html create mode 100644 latest/coreMQTT/core__mqtt__serializer_8h_source.html create mode 100644 latest/coreMQTT/core__mqtt__state_8c.html create mode 100644 latest/coreMQTT/core__mqtt__state_8h.html create mode 100644 latest/coreMQTT/core__mqtt__state_8h_source.html create mode 100644 latest/coreMQTT/core_mqtt_config.html create mode 100644 latest/coreMQTT/dir_359d2bec989c9a8deeeb9aee335c1c76.html create mode 100644 latest/coreMQTT/dir_3750548c40d9045ee3b3d006c00db089.html create mode 100644 latest/coreMQTT/dir_49e56c817e5e54854c35e136979f97ca.html create mode 100644 latest/coreMQTT/dir_8ee1a5e78eaec319fe5d64075812fc61.html create mode 100644 latest/coreMQTT/dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html create mode 100644 latest/coreMQTT/doc.png create mode 100644 latest/coreMQTT/docd.png create mode 100644 latest/coreMQTT/doxygen.css create mode 100644 latest/coreMQTT/doxygen.svg create mode 100644 latest/coreMQTT/dynsections.js create mode 100644 latest/coreMQTT/files.html create mode 100644 latest/coreMQTT/folderclosed.png create mode 100644 latest/coreMQTT/folderopen.png create mode 100644 latest/coreMQTT/functions.html create mode 100644 latest/coreMQTT/functions_vars.html create mode 100644 latest/coreMQTT/globals.html create mode 100644 latest/coreMQTT/globals_c.html create mode 100644 latest/coreMQTT/globals_d.html create mode 100644 latest/coreMQTT/globals_defs.html create mode 100644 latest/coreMQTT/globals_e.html create mode 100644 latest/coreMQTT/globals_enum.html create mode 100644 latest/coreMQTT/globals_eval.html create mode 100644 latest/coreMQTT/globals_f.html create mode 100644 latest/coreMQTT/globals_func.html create mode 100644 latest/coreMQTT/globals_g.html create mode 100644 latest/coreMQTT/globals_h.html create mode 100644 latest/coreMQTT/globals_i.html create mode 100644 latest/coreMQTT/globals_l.html create mode 100644 latest/coreMQTT/globals_m.html create mode 100644 latest/coreMQTT/globals_n.html create mode 100644 latest/coreMQTT/globals_p.html create mode 100644 latest/coreMQTT/globals_r.html create mode 100644 latest/coreMQTT/globals_s.html create mode 100644 latest/coreMQTT/globals_t.html create mode 100644 latest/coreMQTT/globals_type.html create mode 100644 latest/coreMQTT/globals_u.html create mode 100644 latest/coreMQTT/globals_v.html create mode 100644 latest/coreMQTT/globals_vars.html create mode 100644 latest/coreMQTT/globals_z.html create mode 100644 latest/coreMQTT/group__mqtt__basic__types.html create mode 100644 latest/coreMQTT/group__mqtt__basic__types.js create mode 100644 latest/coreMQTT/group__mqtt__callback__types.html create mode 100644 latest/coreMQTT/group__mqtt__callback__types.js create mode 100644 latest/coreMQTT/group__mqtt__constants.html create mode 100644 latest/coreMQTT/group__mqtt__constants.js create mode 100644 latest/coreMQTT/group__mqtt__enum__types.html create mode 100644 latest/coreMQTT/group__mqtt__enum__types.js create mode 100644 latest/coreMQTT/group__mqtt__struct__types.html create mode 100644 latest/coreMQTT/group__mqtt__struct__types.js create mode 100644 latest/coreMQTT/index.html create mode 100644 latest/coreMQTT/index.js create mode 100644 latest/coreMQTT/jquery.js create mode 100644 latest/coreMQTT/modules.html create mode 100644 latest/coreMQTT/modules.js create mode 100644 latest/coreMQTT/mqtt_connect_design.png create mode 100644 latest/coreMQTT/mqtt_connect_function.html create mode 100644 latest/coreMQTT/mqtt_deserializeack_function.html create mode 100644 latest/coreMQTT/mqtt_deserializepublish_function.html create mode 100644 latest/coreMQTT/mqtt_design.html create mode 100644 latest/coreMQTT/mqtt_disconnect_function.html create mode 100644 latest/coreMQTT/mqtt_functions.html create mode 100644 latest/coreMQTT/mqtt_functions.js create mode 100644 latest/coreMQTT/mqtt_getconnectpacketsize_function.html create mode 100644 latest/coreMQTT/mqtt_getdisconnectpacketsize_function.html create mode 100644 latest/coreMQTT/mqtt_getincomingpackettypeandlength_function.html create mode 100644 latest/coreMQTT/mqtt_getpacketid_function.html create mode 100644 latest/coreMQTT/mqtt_getpingreqpacketsize_function.html create mode 100644 latest/coreMQTT/mqtt_getpublishpacketsize_function.html create mode 100644 latest/coreMQTT/mqtt_getsubackstatuscodes_function.html create mode 100644 latest/coreMQTT/mqtt_getsubscribepacketsize_function.html create mode 100644 latest/coreMQTT/mqtt_getunsubscribepacketsize_function.html create mode 100644 latest/coreMQTT/mqtt_init_function.html create mode 100644 latest/coreMQTT/mqtt_ping_function.html create mode 100644 latest/coreMQTT/mqtt_porting.html create mode 100644 latest/coreMQTT/mqtt_processloop_design.png create mode 100644 latest/coreMQTT/mqtt_processloop_function.html create mode 100644 latest/coreMQTT/mqtt_publish_function.html create mode 100644 latest/coreMQTT/mqtt_publishtoresend_function.html create mode 100644 latest/coreMQTT/mqtt_receiveloop_design.png create mode 100644 latest/coreMQTT/mqtt_receiveloop_function.html create mode 100644 latest/coreMQTT/mqtt_serializeack_function.html create mode 100644 latest/coreMQTT/mqtt_serializeconnect_function.html create mode 100644 latest/coreMQTT/mqtt_serializedisconnect_function.html create mode 100644 latest/coreMQTT/mqtt_serializepingreq_function.html create mode 100644 latest/coreMQTT/mqtt_serializepublish_function.html create mode 100644 latest/coreMQTT/mqtt_serializepublishheader_function.html create mode 100644 latest/coreMQTT/mqtt_serializesubscribe_function.html create mode 100644 latest/coreMQTT/mqtt_serializeunsubscribe_function.html create mode 100644 latest/coreMQTT/mqtt_status_strerror_function.html create mode 100644 latest/coreMQTT/mqtt_subscribe_function.html create mode 100644 latest/coreMQTT/mqtt_timeouts.html create mode 100644 latest/coreMQTT/mqtt_transport_interface.html create mode 100644 latest/coreMQTT/mqtt_unsubscribe_function.html create mode 100644 latest/coreMQTT/nav_f.png create mode 100644 latest/coreMQTT/nav_fd.png create mode 100644 latest/coreMQTT/nav_g.png create mode 100644 latest/coreMQTT/nav_h.png create mode 100644 latest/coreMQTT/nav_hd.png create mode 100644 latest/coreMQTT/navtree.css create mode 100644 latest/coreMQTT/navtree.js create mode 100644 latest/coreMQTT/navtreedata.js create mode 100644 latest/coreMQTT/navtreeindex0.js create mode 100644 latest/coreMQTT/open.png create mode 100644 latest/coreMQTT/pages.html create mode 100644 latest/coreMQTT/resize.js create mode 100644 latest/coreMQTT/search/all_0.js create mode 100644 latest/coreMQTT/search/all_1.js create mode 100644 latest/coreMQTT/search/all_10.js create mode 100644 latest/coreMQTT/search/all_11.js create mode 100644 latest/coreMQTT/search/all_12.js create mode 100644 latest/coreMQTT/search/all_13.js create mode 100644 latest/coreMQTT/search/all_14.js create mode 100644 latest/coreMQTT/search/all_15.js create mode 100644 latest/coreMQTT/search/all_16.js create mode 100644 latest/coreMQTT/search/all_2.js create mode 100644 latest/coreMQTT/search/all_3.js create mode 100644 latest/coreMQTT/search/all_4.js create mode 100644 latest/coreMQTT/search/all_5.js create mode 100644 latest/coreMQTT/search/all_6.js create mode 100644 latest/coreMQTT/search/all_7.js create mode 100644 latest/coreMQTT/search/all_8.js create mode 100644 latest/coreMQTT/search/all_9.js create mode 100644 latest/coreMQTT/search/all_a.js create mode 100644 latest/coreMQTT/search/all_b.js create mode 100644 latest/coreMQTT/search/all_c.js create mode 100644 latest/coreMQTT/search/all_d.js create mode 100644 latest/coreMQTT/search/all_e.js create mode 100644 latest/coreMQTT/search/all_f.js create mode 100644 latest/coreMQTT/search/classes_0.js create mode 100644 latest/coreMQTT/search/classes_1.js create mode 100644 latest/coreMQTT/search/close.svg create mode 100644 latest/coreMQTT/search/defines_0.js create mode 100644 latest/coreMQTT/search/defines_1.js create mode 100644 latest/coreMQTT/search/defines_2.js create mode 100644 latest/coreMQTT/search/defines_3.js create mode 100644 latest/coreMQTT/search/defines_4.js create mode 100644 latest/coreMQTT/search/enums_0.js create mode 100644 latest/coreMQTT/search/enumvalues_0.js create mode 100644 latest/coreMQTT/search/files_0.js create mode 100644 latest/coreMQTT/search/files_1.js create mode 100644 latest/coreMQTT/search/functions_0.js create mode 100644 latest/coreMQTT/search/functions_1.js create mode 100644 latest/coreMQTT/search/functions_2.js create mode 100644 latest/coreMQTT/search/functions_3.js create mode 100644 latest/coreMQTT/search/functions_4.js create mode 100644 latest/coreMQTT/search/functions_5.js create mode 100644 latest/coreMQTT/search/functions_6.js create mode 100644 latest/coreMQTT/search/functions_7.js create mode 100644 latest/coreMQTT/search/functions_8.js create mode 100644 latest/coreMQTT/search/functions_9.js create mode 100644 latest/coreMQTT/search/functions_a.js create mode 100644 latest/coreMQTT/search/functions_b.js create mode 100644 latest/coreMQTT/search/functions_c.js create mode 100644 latest/coreMQTT/search/functions_d.js create mode 100644 latest/coreMQTT/search/functions_e.js create mode 100644 latest/coreMQTT/search/groups_0.js create mode 100644 latest/coreMQTT/search/groups_1.js create mode 100644 latest/coreMQTT/search/groups_2.js create mode 100644 latest/coreMQTT/search/groups_3.js create mode 100644 latest/coreMQTT/search/mag.svg create mode 100644 latest/coreMQTT/search/mag_d.svg create mode 100644 latest/coreMQTT/search/mag_sel.svg create mode 100644 latest/coreMQTT/search/mag_seld.svg create mode 100644 latest/coreMQTT/search/pages_0.js create mode 100644 latest/coreMQTT/search/pages_1.js create mode 100644 latest/coreMQTT/search/pages_2.js create mode 100644 latest/coreMQTT/search/pages_3.js create mode 100644 latest/coreMQTT/search/pages_4.js create mode 100644 latest/coreMQTT/search/pages_5.js create mode 100644 latest/coreMQTT/search/pages_6.js create mode 100644 latest/coreMQTT/search/search.css create mode 100644 latest/coreMQTT/search/search.js create mode 100644 latest/coreMQTT/search/searchdata.js create mode 100644 latest/coreMQTT/search/typedefs_0.js create mode 100644 latest/coreMQTT/search/typedefs_1.js create mode 100644 latest/coreMQTT/search/typedefs_2.js create mode 100644 latest/coreMQTT/search/variables_0.js create mode 100644 latest/coreMQTT/search/variables_1.js create mode 100644 latest/coreMQTT/search/variables_10.js create mode 100644 latest/coreMQTT/search/variables_11.js create mode 100644 latest/coreMQTT/search/variables_2.js create mode 100644 latest/coreMQTT/search/variables_3.js create mode 100644 latest/coreMQTT/search/variables_4.js create mode 100644 latest/coreMQTT/search/variables_5.js create mode 100644 latest/coreMQTT/search/variables_6.js create mode 100644 latest/coreMQTT/search/variables_7.js create mode 100644 latest/coreMQTT/search/variables_8.js create mode 100644 latest/coreMQTT/search/variables_9.js create mode 100644 latest/coreMQTT/search/variables_a.js create mode 100644 latest/coreMQTT/search/variables_b.js create mode 100644 latest/coreMQTT/search/variables_c.js create mode 100644 latest/coreMQTT/search/variables_d.js create mode 100644 latest/coreMQTT/search/variables_e.js create mode 100644 latest/coreMQTT/search/variables_f.js create mode 100644 latest/coreMQTT/splitbar.png create mode 100644 latest/coreMQTT/splitbard.png create mode 100644 latest/coreMQTT/struct_m_q_t_t_connect_info__t.html create mode 100644 latest/coreMQTT/struct_m_q_t_t_context__t.html create mode 100644 latest/coreMQTT/struct_m_q_t_t_deserialized_info__t.html create mode 100644 latest/coreMQTT/struct_m_q_t_t_fixed_buffer__t.html create mode 100644 latest/coreMQTT/struct_m_q_t_t_packet_info__t.html create mode 100644 latest/coreMQTT/struct_m_q_t_t_pub_ack_info__t.html create mode 100644 latest/coreMQTT/struct_m_q_t_t_publish_info__t.html create mode 100644 latest/coreMQTT/struct_m_q_t_t_subscribe_info__t.html create mode 100644 latest/coreMQTT/struct_transport_interface__t.html create mode 100644 latest/coreMQTT/struct_transport_out_vector__t.html create mode 100644 latest/coreMQTT/style.css create mode 100644 latest/coreMQTT/sync_off.png create mode 100644 latest/coreMQTT/sync_on.png create mode 100644 latest/coreMQTT/tab_a.png create mode 100644 latest/coreMQTT/tab_ad.png create mode 100644 latest/coreMQTT/tab_b.png create mode 100644 latest/coreMQTT/tab_bd.png create mode 100644 latest/coreMQTT/tab_h.png create mode 100644 latest/coreMQTT/tab_hd.png create mode 100644 latest/coreMQTT/tab_s.png create mode 100644 latest/coreMQTT/tab_sd.png create mode 100644 latest/coreMQTT/tabs.css create mode 100644 latest/coreMQTT/transport__interface_8h.html create mode 100644 latest/coreMQTT/transport__interface_8h_source.html create mode 100644 latest/core__mqtt__agent_8c.html create mode 100644 latest/core__mqtt__agent_8h.html create mode 100644 latest/core__mqtt__agent_8h_source.html create mode 100644 latest/core__mqtt__agent__command__functions_8c.html create mode 100644 latest/core__mqtt__agent__command__functions_8h.html create mode 100644 latest/core__mqtt__agent__command__functions_8h_source.html create mode 100644 latest/core__mqtt__agent__config__defaults_8h.html create mode 100644 latest/core__mqtt__agent__config__defaults_8h_source.html create mode 100644 latest/core__mqtt__agent__default__logging_8h.html create mode 100644 latest/core__mqtt__agent__default__logging_8h_source.html create mode 100644 latest/core__mqtt__agent__message__interface_8h.html create mode 100644 latest/core__mqtt__agent__message__interface_8h_source.html create mode 100644 latest/core_mqtt_agent_config.html create mode 100644 latest/dir_359d2bec989c9a8deeeb9aee335c1c76.html create mode 100644 latest/dir_49e56c817e5e54854c35e136979f97ca.html create mode 100644 latest/dir_8ee1a5e78eaec319fe5d64075812fc61.html create mode 100644 latest/dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html create mode 100644 latest/doc.png create mode 100644 latest/docd.png create mode 100644 latest/doxygen.css create mode 100644 latest/doxygen.svg create mode 100644 latest/dynsections.js create mode 100644 latest/files.html create mode 100644 latest/folderclosed.png create mode 100644 latest/folderopen.png create mode 100644 latest/functions.html create mode 100644 latest/functions_vars.html create mode 100644 latest/globals.html create mode 100644 latest/globals_defs.html create mode 100644 latest/globals_enum.html create mode 100644 latest/globals_eval.html create mode 100644 latest/globals_func.html create mode 100644 latest/globals_type.html create mode 100644 latest/group__mqtt__agent__callback__types.html create mode 100644 latest/group__mqtt__agent__callback__types.js create mode 100644 latest/group__mqtt__agent__enum__types.html create mode 100644 latest/group__mqtt__agent__enum__types.js create mode 100644 latest/group__mqtt__agent__struct__types.html create mode 100644 latest/group__mqtt__agent__struct__types.js create mode 100644 latest/index.html create mode 100644 latest/index.js create mode 100644 latest/jquery.js create mode 100644 latest/modules.html create mode 100644 latest/modules.js create mode 100644 latest/mqtt_agent_cancel_function.html create mode 100644 latest/mqtt_agent_command_function.html create mode 100644 latest/mqtt_agent_connect_function.html create mode 100644 latest/mqtt_agent_design.html create mode 100644 latest/mqtt_agent_disconnect_function.html create mode 100644 latest/mqtt_agent_functions.html create mode 100644 latest/mqtt_agent_functions.js create mode 100644 latest/mqtt_agent_init_function.html create mode 100644 latest/mqtt_agent_message_interface.html create mode 100644 latest/mqtt_agent_ping_function.html create mode 100644 latest/mqtt_agent_publish_function.html create mode 100644 latest/mqtt_agent_resume_function.html create mode 100644 latest/mqtt_agent_subscribe_function.html create mode 100644 latest/mqtt_agent_terminate_function.html create mode 100644 latest/mqtt_agent_unsubscribe_function.html create mode 100644 latest/nav_f.png create mode 100644 latest/nav_fd.png create mode 100644 latest/nav_g.png create mode 100644 latest/nav_h.png create mode 100644 latest/nav_hd.png create mode 100644 latest/navtree.css create mode 100644 latest/navtree.js create mode 100644 latest/navtreedata.js create mode 100644 latest/navtreeindex0.js create mode 100644 latest/open.png create mode 100644 latest/pages.html create mode 100644 latest/resize.js create mode 100644 latest/search/all_0.js create mode 100644 latest/search/all_1.js create mode 100644 latest/search/all_10.js create mode 100644 latest/search/all_11.js create mode 100644 latest/search/all_12.js create mode 100644 latest/search/all_13.js create mode 100644 latest/search/all_14.js create mode 100644 latest/search/all_15.js create mode 100644 latest/search/all_2.js create mode 100644 latest/search/all_3.js create mode 100644 latest/search/all_4.js create mode 100644 latest/search/all_5.js create mode 100644 latest/search/all_6.js create mode 100644 latest/search/all_7.js create mode 100644 latest/search/all_8.js create mode 100644 latest/search/all_9.js create mode 100644 latest/search/all_a.js create mode 100644 latest/search/all_b.js create mode 100644 latest/search/all_c.js create mode 100644 latest/search/all_d.js create mode 100644 latest/search/all_e.js create mode 100644 latest/search/all_f.js create mode 100644 latest/search/classes_0.js create mode 100644 latest/search/classes_1.js create mode 100644 latest/search/close.svg create mode 100644 latest/search/defines_0.js create mode 100644 latest/search/defines_1.js create mode 100644 latest/search/enums_0.js create mode 100644 latest/search/enumvalues_0.js create mode 100644 latest/search/enumvalues_1.js create mode 100644 latest/search/enumvalues_2.js create mode 100644 latest/search/enumvalues_3.js create mode 100644 latest/search/enumvalues_4.js create mode 100644 latest/search/enumvalues_5.js create mode 100644 latest/search/enumvalues_6.js create mode 100644 latest/search/files_0.js create mode 100644 latest/search/files_1.js create mode 100644 latest/search/functions_0.js create mode 100644 latest/search/functions_1.js create mode 100644 latest/search/functions_2.js create mode 100644 latest/search/functions_3.js create mode 100644 latest/search/functions_4.js create mode 100644 latest/search/functions_5.js create mode 100644 latest/search/functions_6.js create mode 100644 latest/search/functions_7.js create mode 100644 latest/search/functions_8.js create mode 100644 latest/search/groups_0.js create mode 100644 latest/search/groups_1.js create mode 100644 latest/search/groups_2.js create mode 100644 latest/search/groups_3.js create mode 100644 latest/search/mag.svg create mode 100644 latest/search/mag_d.svg create mode 100644 latest/search/mag_sel.svg create mode 100644 latest/search/mag_seld.svg create mode 100644 latest/search/pages_0.js create mode 100644 latest/search/pages_1.js create mode 100644 latest/search/pages_2.js create mode 100644 latest/search/pages_3.js create mode 100644 latest/search/pages_4.js create mode 100644 latest/search/pages_5.js create mode 100644 latest/search/pages_6.js create mode 100644 latest/search/search.css create mode 100644 latest/search/search.js create mode 100644 latest/search/searchdata.js create mode 100644 latest/search/typedefs_0.js create mode 100644 latest/search/typedefs_1.js create mode 100644 latest/search/typedefs_2.js create mode 100644 latest/search/variables_0.js create mode 100644 latest/search/variables_1.js create mode 100644 latest/search/variables_10.js create mode 100644 latest/search/variables_11.js create mode 100644 latest/search/variables_12.js create mode 100644 latest/search/variables_13.js create mode 100644 latest/search/variables_2.js create mode 100644 latest/search/variables_3.js create mode 100644 latest/search/variables_4.js create mode 100644 latest/search/variables_5.js create mode 100644 latest/search/variables_6.js create mode 100644 latest/search/variables_7.js create mode 100644 latest/search/variables_8.js create mode 100644 latest/search/variables_9.js create mode 100644 latest/search/variables_a.js create mode 100644 latest/search/variables_b.js create mode 100644 latest/search/variables_c.js create mode 100644 latest/search/variables_d.js create mode 100644 latest/search/variables_e.js create mode 100644 latest/search/variables_f.js create mode 100644 latest/splitbar.png create mode 100644 latest/splitbard.png create mode 100644 latest/struct_m_q_t_t_agent_ack_info__t.html create mode 100644 latest/struct_m_q_t_t_agent_command.html create mode 100644 latest/struct_m_q_t_t_agent_command_func_returns__t.html create mode 100644 latest/struct_m_q_t_t_agent_command_info__t.html create mode 100644 latest/struct_m_q_t_t_agent_connect_args__t.html create mode 100644 latest/struct_m_q_t_t_agent_context__t.html create mode 100644 latest/struct_m_q_t_t_agent_message_interface__t.html create mode 100644 latest/struct_m_q_t_t_agent_return_info__t.html create mode 100644 latest/struct_m_q_t_t_agent_subscribe_args__t.html create mode 100644 latest/style.css create mode 100644 latest/sync_off.png create mode 100644 latest/sync_on.png create mode 100644 latest/tab_a.png create mode 100644 latest/tab_ad.png create mode 100644 latest/tab_b.png create mode 100644 latest/tab_bd.png create mode 100644 latest/tab_h.png create mode 100644 latest/tab_hd.png create mode 100644 latest/tab_s.png create mode 100644 latest/tab_sd.png create mode 100644 latest/tabs.css create mode 100644 v1.3.0/annotated.html create mode 100644 v1.3.0/bc_s.png create mode 100644 v1.3.0/bc_sd.png create mode 100644 v1.3.0/bdwn.png create mode 100644 v1.3.0/classes.html create mode 100644 v1.3.0/closed.png create mode 100644 v1.3.0/coreMQTT/annotated.html create mode 100644 v1.3.0/coreMQTT/bc_s.png create mode 100644 v1.3.0/coreMQTT/bc_sd.png create mode 100644 v1.3.0/coreMQTT/bdwn.png create mode 100644 v1.3.0/coreMQTT/classes.html create mode 100644 v1.3.0/coreMQTT/closed.png create mode 100644 v1.3.0/coreMQTT/core__mqtt_8c.html create mode 100644 v1.3.0/coreMQTT/core__mqtt_8h.html create mode 100644 v1.3.0/coreMQTT/core__mqtt_8h_source.html create mode 100644 v1.3.0/coreMQTT/core__mqtt__config__defaults_8h.html create mode 100644 v1.3.0/coreMQTT/core__mqtt__config__defaults_8h_source.html create mode 100644 v1.3.0/coreMQTT/core__mqtt__serializer_8c.html create mode 100644 v1.3.0/coreMQTT/core__mqtt__serializer_8h.html create mode 100644 v1.3.0/coreMQTT/core__mqtt__serializer_8h_source.html create mode 100644 v1.3.0/coreMQTT/core__mqtt__state_8c.html create mode 100644 v1.3.0/coreMQTT/core__mqtt__state_8h.html create mode 100644 v1.3.0/coreMQTT/core__mqtt__state_8h_source.html create mode 100644 v1.3.0/coreMQTT/core_mqtt_config.html create mode 100644 v1.3.0/coreMQTT/dir_359d2bec989c9a8deeeb9aee335c1c76.html create mode 100644 v1.3.0/coreMQTT/dir_3750548c40d9045ee3b3d006c00db089.html create mode 100644 v1.3.0/coreMQTT/dir_49e56c817e5e54854c35e136979f97ca.html create mode 100644 v1.3.0/coreMQTT/dir_8ee1a5e78eaec319fe5d64075812fc61.html create mode 100644 v1.3.0/coreMQTT/dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html create mode 100644 v1.3.0/coreMQTT/doc.png create mode 100644 v1.3.0/coreMQTT/docd.png create mode 100644 v1.3.0/coreMQTT/doxygen.css create mode 100644 v1.3.0/coreMQTT/doxygen.svg create mode 100644 v1.3.0/coreMQTT/dynsections.js create mode 100644 v1.3.0/coreMQTT/files.html create mode 100644 v1.3.0/coreMQTT/folderclosed.png create mode 100644 v1.3.0/coreMQTT/folderopen.png create mode 100644 v1.3.0/coreMQTT/functions.html create mode 100644 v1.3.0/coreMQTT/functions_vars.html create mode 100644 v1.3.0/coreMQTT/globals.html create mode 100644 v1.3.0/coreMQTT/globals_c.html create mode 100644 v1.3.0/coreMQTT/globals_d.html create mode 100644 v1.3.0/coreMQTT/globals_defs.html create mode 100644 v1.3.0/coreMQTT/globals_e.html create mode 100644 v1.3.0/coreMQTT/globals_enum.html create mode 100644 v1.3.0/coreMQTT/globals_eval.html create mode 100644 v1.3.0/coreMQTT/globals_f.html create mode 100644 v1.3.0/coreMQTT/globals_func.html create mode 100644 v1.3.0/coreMQTT/globals_g.html create mode 100644 v1.3.0/coreMQTT/globals_h.html create mode 100644 v1.3.0/coreMQTT/globals_i.html create mode 100644 v1.3.0/coreMQTT/globals_l.html create mode 100644 v1.3.0/coreMQTT/globals_m.html create mode 100644 v1.3.0/coreMQTT/globals_n.html create mode 100644 v1.3.0/coreMQTT/globals_p.html create mode 100644 v1.3.0/coreMQTT/globals_r.html create mode 100644 v1.3.0/coreMQTT/globals_s.html create mode 100644 v1.3.0/coreMQTT/globals_t.html create mode 100644 v1.3.0/coreMQTT/globals_type.html create mode 100644 v1.3.0/coreMQTT/globals_u.html create mode 100644 v1.3.0/coreMQTT/globals_v.html create mode 100644 v1.3.0/coreMQTT/globals_vars.html create mode 100644 v1.3.0/coreMQTT/globals_z.html create mode 100644 v1.3.0/coreMQTT/group__mqtt__basic__types.html create mode 100644 v1.3.0/coreMQTT/group__mqtt__basic__types.js create mode 100644 v1.3.0/coreMQTT/group__mqtt__callback__types.html create mode 100644 v1.3.0/coreMQTT/group__mqtt__callback__types.js create mode 100644 v1.3.0/coreMQTT/group__mqtt__constants.html create mode 100644 v1.3.0/coreMQTT/group__mqtt__constants.js create mode 100644 v1.3.0/coreMQTT/group__mqtt__enum__types.html create mode 100644 v1.3.0/coreMQTT/group__mqtt__enum__types.js create mode 100644 v1.3.0/coreMQTT/group__mqtt__struct__types.html create mode 100644 v1.3.0/coreMQTT/group__mqtt__struct__types.js create mode 100644 v1.3.0/coreMQTT/index.html create mode 100644 v1.3.0/coreMQTT/index.js create mode 100644 v1.3.0/coreMQTT/jquery.js create mode 100644 v1.3.0/coreMQTT/modules.html create mode 100644 v1.3.0/coreMQTT/modules.js create mode 100644 v1.3.0/coreMQTT/mqtt_connect_design.png create mode 100644 v1.3.0/coreMQTT/mqtt_connect_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_deserializeack_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_deserializepublish_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_design.html create mode 100644 v1.3.0/coreMQTT/mqtt_disconnect_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_functions.html create mode 100644 v1.3.0/coreMQTT/mqtt_functions.js create mode 100644 v1.3.0/coreMQTT/mqtt_getconnectpacketsize_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_getdisconnectpacketsize_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_getincomingpackettypeandlength_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_getpacketid_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_getpingreqpacketsize_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_getpublishpacketsize_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_getsubackstatuscodes_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_getsubscribepacketsize_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_getunsubscribepacketsize_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_init_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_ping_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_porting.html create mode 100644 v1.3.0/coreMQTT/mqtt_processloop_design.png create mode 100644 v1.3.0/coreMQTT/mqtt_processloop_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_publish_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_publishtoresend_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_receiveloop_design.png create mode 100644 v1.3.0/coreMQTT/mqtt_receiveloop_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_serializeack_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_serializeconnect_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_serializedisconnect_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_serializepingreq_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_serializepublish_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_serializepublishheader_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_serializesubscribe_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_serializeunsubscribe_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_status_strerror_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_subscribe_function.html create mode 100644 v1.3.0/coreMQTT/mqtt_timeouts.html create mode 100644 v1.3.0/coreMQTT/mqtt_transport_interface.html create mode 100644 v1.3.0/coreMQTT/mqtt_unsubscribe_function.html create mode 100644 v1.3.0/coreMQTT/nav_f.png create mode 100644 v1.3.0/coreMQTT/nav_fd.png create mode 100644 v1.3.0/coreMQTT/nav_g.png create mode 100644 v1.3.0/coreMQTT/nav_h.png create mode 100644 v1.3.0/coreMQTT/nav_hd.png create mode 100644 v1.3.0/coreMQTT/navtree.css create mode 100644 v1.3.0/coreMQTT/navtree.js create mode 100644 v1.3.0/coreMQTT/navtreedata.js create mode 100644 v1.3.0/coreMQTT/navtreeindex0.js create mode 100644 v1.3.0/coreMQTT/open.png create mode 100644 v1.3.0/coreMQTT/pages.html create mode 100644 v1.3.0/coreMQTT/resize.js create mode 100644 v1.3.0/coreMQTT/search/all_0.js create mode 100644 v1.3.0/coreMQTT/search/all_1.js create mode 100644 v1.3.0/coreMQTT/search/all_10.js create mode 100644 v1.3.0/coreMQTT/search/all_11.js create mode 100644 v1.3.0/coreMQTT/search/all_12.js create mode 100644 v1.3.0/coreMQTT/search/all_13.js create mode 100644 v1.3.0/coreMQTT/search/all_14.js create mode 100644 v1.3.0/coreMQTT/search/all_15.js create mode 100644 v1.3.0/coreMQTT/search/all_16.js create mode 100644 v1.3.0/coreMQTT/search/all_2.js create mode 100644 v1.3.0/coreMQTT/search/all_3.js create mode 100644 v1.3.0/coreMQTT/search/all_4.js create mode 100644 v1.3.0/coreMQTT/search/all_5.js create mode 100644 v1.3.0/coreMQTT/search/all_6.js create mode 100644 v1.3.0/coreMQTT/search/all_7.js create mode 100644 v1.3.0/coreMQTT/search/all_8.js create mode 100644 v1.3.0/coreMQTT/search/all_9.js create mode 100644 v1.3.0/coreMQTT/search/all_a.js create mode 100644 v1.3.0/coreMQTT/search/all_b.js create mode 100644 v1.3.0/coreMQTT/search/all_c.js create mode 100644 v1.3.0/coreMQTT/search/all_d.js create mode 100644 v1.3.0/coreMQTT/search/all_e.js create mode 100644 v1.3.0/coreMQTT/search/all_f.js create mode 100644 v1.3.0/coreMQTT/search/classes_0.js create mode 100644 v1.3.0/coreMQTT/search/classes_1.js create mode 100644 v1.3.0/coreMQTT/search/close.svg create mode 100644 v1.3.0/coreMQTT/search/defines_0.js create mode 100644 v1.3.0/coreMQTT/search/defines_1.js create mode 100644 v1.3.0/coreMQTT/search/defines_2.js create mode 100644 v1.3.0/coreMQTT/search/defines_3.js create mode 100644 v1.3.0/coreMQTT/search/defines_4.js create mode 100644 v1.3.0/coreMQTT/search/enums_0.js create mode 100644 v1.3.0/coreMQTT/search/enumvalues_0.js create mode 100644 v1.3.0/coreMQTT/search/files_0.js create mode 100644 v1.3.0/coreMQTT/search/files_1.js create mode 100644 v1.3.0/coreMQTT/search/functions_0.js create mode 100644 v1.3.0/coreMQTT/search/functions_1.js create mode 100644 v1.3.0/coreMQTT/search/functions_2.js create mode 100644 v1.3.0/coreMQTT/search/functions_3.js create mode 100644 v1.3.0/coreMQTT/search/functions_4.js create mode 100644 v1.3.0/coreMQTT/search/functions_5.js create mode 100644 v1.3.0/coreMQTT/search/functions_6.js create mode 100644 v1.3.0/coreMQTT/search/functions_7.js create mode 100644 v1.3.0/coreMQTT/search/functions_8.js create mode 100644 v1.3.0/coreMQTT/search/functions_9.js create mode 100644 v1.3.0/coreMQTT/search/functions_a.js create mode 100644 v1.3.0/coreMQTT/search/functions_b.js create mode 100644 v1.3.0/coreMQTT/search/functions_c.js create mode 100644 v1.3.0/coreMQTT/search/functions_d.js create mode 100644 v1.3.0/coreMQTT/search/functions_e.js create mode 100644 v1.3.0/coreMQTT/search/groups_0.js create mode 100644 v1.3.0/coreMQTT/search/groups_1.js create mode 100644 v1.3.0/coreMQTT/search/groups_2.js create mode 100644 v1.3.0/coreMQTT/search/groups_3.js create mode 100644 v1.3.0/coreMQTT/search/mag.svg create mode 100644 v1.3.0/coreMQTT/search/mag_d.svg create mode 100644 v1.3.0/coreMQTT/search/mag_sel.svg create mode 100644 v1.3.0/coreMQTT/search/mag_seld.svg create mode 100644 v1.3.0/coreMQTT/search/pages_0.js create mode 100644 v1.3.0/coreMQTT/search/pages_1.js create mode 100644 v1.3.0/coreMQTT/search/pages_2.js create mode 100644 v1.3.0/coreMQTT/search/pages_3.js create mode 100644 v1.3.0/coreMQTT/search/pages_4.js create mode 100644 v1.3.0/coreMQTT/search/pages_5.js create mode 100644 v1.3.0/coreMQTT/search/pages_6.js create mode 100644 v1.3.0/coreMQTT/search/search.css create mode 100644 v1.3.0/coreMQTT/search/search.js create mode 100644 v1.3.0/coreMQTT/search/searchdata.js create mode 100644 v1.3.0/coreMQTT/search/typedefs_0.js create mode 100644 v1.3.0/coreMQTT/search/typedefs_1.js create mode 100644 v1.3.0/coreMQTT/search/typedefs_2.js create mode 100644 v1.3.0/coreMQTT/search/variables_0.js create mode 100644 v1.3.0/coreMQTT/search/variables_1.js create mode 100644 v1.3.0/coreMQTT/search/variables_10.js create mode 100644 v1.3.0/coreMQTT/search/variables_11.js create mode 100644 v1.3.0/coreMQTT/search/variables_2.js create mode 100644 v1.3.0/coreMQTT/search/variables_3.js create mode 100644 v1.3.0/coreMQTT/search/variables_4.js create mode 100644 v1.3.0/coreMQTT/search/variables_5.js create mode 100644 v1.3.0/coreMQTT/search/variables_6.js create mode 100644 v1.3.0/coreMQTT/search/variables_7.js create mode 100644 v1.3.0/coreMQTT/search/variables_8.js create mode 100644 v1.3.0/coreMQTT/search/variables_9.js create mode 100644 v1.3.0/coreMQTT/search/variables_a.js create mode 100644 v1.3.0/coreMQTT/search/variables_b.js create mode 100644 v1.3.0/coreMQTT/search/variables_c.js create mode 100644 v1.3.0/coreMQTT/search/variables_d.js create mode 100644 v1.3.0/coreMQTT/search/variables_e.js create mode 100644 v1.3.0/coreMQTT/search/variables_f.js create mode 100644 v1.3.0/coreMQTT/splitbar.png create mode 100644 v1.3.0/coreMQTT/splitbard.png create mode 100644 v1.3.0/coreMQTT/struct_m_q_t_t_connect_info__t.html create mode 100644 v1.3.0/coreMQTT/struct_m_q_t_t_context__t.html create mode 100644 v1.3.0/coreMQTT/struct_m_q_t_t_deserialized_info__t.html create mode 100644 v1.3.0/coreMQTT/struct_m_q_t_t_fixed_buffer__t.html create mode 100644 v1.3.0/coreMQTT/struct_m_q_t_t_packet_info__t.html create mode 100644 v1.3.0/coreMQTT/struct_m_q_t_t_pub_ack_info__t.html create mode 100644 v1.3.0/coreMQTT/struct_m_q_t_t_publish_info__t.html create mode 100644 v1.3.0/coreMQTT/struct_m_q_t_t_subscribe_info__t.html create mode 100644 v1.3.0/coreMQTT/struct_transport_interface__t.html create mode 100644 v1.3.0/coreMQTT/struct_transport_out_vector__t.html create mode 100644 v1.3.0/coreMQTT/style.css create mode 100644 v1.3.0/coreMQTT/sync_off.png create mode 100644 v1.3.0/coreMQTT/sync_on.png create mode 100644 v1.3.0/coreMQTT/tab_a.png create mode 100644 v1.3.0/coreMQTT/tab_ad.png create mode 100644 v1.3.0/coreMQTT/tab_b.png create mode 100644 v1.3.0/coreMQTT/tab_bd.png create mode 100644 v1.3.0/coreMQTT/tab_h.png create mode 100644 v1.3.0/coreMQTT/tab_hd.png create mode 100644 v1.3.0/coreMQTT/tab_s.png create mode 100644 v1.3.0/coreMQTT/tab_sd.png create mode 100644 v1.3.0/coreMQTT/tabs.css create mode 100644 v1.3.0/coreMQTT/transport__interface_8h.html create mode 100644 v1.3.0/coreMQTT/transport__interface_8h_source.html create mode 100644 v1.3.0/core__mqtt__agent_8c.html create mode 100644 v1.3.0/core__mqtt__agent_8h.html create mode 100644 v1.3.0/core__mqtt__agent_8h_source.html create mode 100644 v1.3.0/core__mqtt__agent__command__functions_8c.html create mode 100644 v1.3.0/core__mqtt__agent__command__functions_8h.html create mode 100644 v1.3.0/core__mqtt__agent__command__functions_8h_source.html create mode 100644 v1.3.0/core__mqtt__agent__config__defaults_8h.html create mode 100644 v1.3.0/core__mqtt__agent__config__defaults_8h_source.html create mode 100644 v1.3.0/core__mqtt__agent__default__logging_8h.html create mode 100644 v1.3.0/core__mqtt__agent__default__logging_8h_source.html create mode 100644 v1.3.0/core__mqtt__agent__message__interface_8h.html create mode 100644 v1.3.0/core__mqtt__agent__message__interface_8h_source.html create mode 100644 v1.3.0/core_mqtt_agent_config.html create mode 100644 v1.3.0/dir_359d2bec989c9a8deeeb9aee335c1c76.html create mode 100644 v1.3.0/dir_49e56c817e5e54854c35e136979f97ca.html create mode 100644 v1.3.0/dir_8ee1a5e78eaec319fe5d64075812fc61.html create mode 100644 v1.3.0/dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html create mode 100644 v1.3.0/doc.png create mode 100644 v1.3.0/docd.png create mode 100644 v1.3.0/doxygen.css create mode 100644 v1.3.0/doxygen.svg create mode 100644 v1.3.0/dynsections.js create mode 100644 v1.3.0/files.html create mode 100644 v1.3.0/folderclosed.png create mode 100644 v1.3.0/folderopen.png create mode 100644 v1.3.0/functions.html create mode 100644 v1.3.0/functions_vars.html create mode 100644 v1.3.0/globals.html create mode 100644 v1.3.0/globals_defs.html create mode 100644 v1.3.0/globals_enum.html create mode 100644 v1.3.0/globals_eval.html create mode 100644 v1.3.0/globals_func.html create mode 100644 v1.3.0/globals_type.html create mode 100644 v1.3.0/group__mqtt__agent__callback__types.html create mode 100644 v1.3.0/group__mqtt__agent__callback__types.js create mode 100644 v1.3.0/group__mqtt__agent__enum__types.html create mode 100644 v1.3.0/group__mqtt__agent__enum__types.js create mode 100644 v1.3.0/group__mqtt__agent__struct__types.html create mode 100644 v1.3.0/group__mqtt__agent__struct__types.js create mode 100644 v1.3.0/index.html create mode 100644 v1.3.0/index.js create mode 100644 v1.3.0/jquery.js create mode 100644 v1.3.0/modules.html create mode 100644 v1.3.0/modules.js create mode 100644 v1.3.0/mqtt_agent_cancel_function.html create mode 100644 v1.3.0/mqtt_agent_command_function.html create mode 100644 v1.3.0/mqtt_agent_connect_function.html create mode 100644 v1.3.0/mqtt_agent_design.html create mode 100644 v1.3.0/mqtt_agent_disconnect_function.html create mode 100644 v1.3.0/mqtt_agent_functions.html create mode 100644 v1.3.0/mqtt_agent_functions.js create mode 100644 v1.3.0/mqtt_agent_init_function.html create mode 100644 v1.3.0/mqtt_agent_message_interface.html create mode 100644 v1.3.0/mqtt_agent_ping_function.html create mode 100644 v1.3.0/mqtt_agent_publish_function.html create mode 100644 v1.3.0/mqtt_agent_resume_function.html create mode 100644 v1.3.0/mqtt_agent_subscribe_function.html create mode 100644 v1.3.0/mqtt_agent_terminate_function.html create mode 100644 v1.3.0/mqtt_agent_unsubscribe_function.html create mode 100644 v1.3.0/nav_f.png create mode 100644 v1.3.0/nav_fd.png create mode 100644 v1.3.0/nav_g.png create mode 100644 v1.3.0/nav_h.png create mode 100644 v1.3.0/nav_hd.png create mode 100644 v1.3.0/navtree.css create mode 100644 v1.3.0/navtree.js create mode 100644 v1.3.0/navtreedata.js create mode 100644 v1.3.0/navtreeindex0.js create mode 100644 v1.3.0/open.png create mode 100644 v1.3.0/pages.html create mode 100644 v1.3.0/resize.js create mode 100644 v1.3.0/search/all_0.js create mode 100644 v1.3.0/search/all_1.js create mode 100644 v1.3.0/search/all_10.js create mode 100644 v1.3.0/search/all_11.js create mode 100644 v1.3.0/search/all_12.js create mode 100644 v1.3.0/search/all_13.js create mode 100644 v1.3.0/search/all_14.js create mode 100644 v1.3.0/search/all_15.js create mode 100644 v1.3.0/search/all_2.js create mode 100644 v1.3.0/search/all_3.js create mode 100644 v1.3.0/search/all_4.js create mode 100644 v1.3.0/search/all_5.js create mode 100644 v1.3.0/search/all_6.js create mode 100644 v1.3.0/search/all_7.js create mode 100644 v1.3.0/search/all_8.js create mode 100644 v1.3.0/search/all_9.js create mode 100644 v1.3.0/search/all_a.js create mode 100644 v1.3.0/search/all_b.js create mode 100644 v1.3.0/search/all_c.js create mode 100644 v1.3.0/search/all_d.js create mode 100644 v1.3.0/search/all_e.js create mode 100644 v1.3.0/search/all_f.js create mode 100644 v1.3.0/search/classes_0.js create mode 100644 v1.3.0/search/classes_1.js create mode 100644 v1.3.0/search/close.svg create mode 100644 v1.3.0/search/defines_0.js create mode 100644 v1.3.0/search/defines_1.js create mode 100644 v1.3.0/search/enums_0.js create mode 100644 v1.3.0/search/enumvalues_0.js create mode 100644 v1.3.0/search/enumvalues_1.js create mode 100644 v1.3.0/search/enumvalues_2.js create mode 100644 v1.3.0/search/enumvalues_3.js create mode 100644 v1.3.0/search/enumvalues_4.js create mode 100644 v1.3.0/search/enumvalues_5.js create mode 100644 v1.3.0/search/enumvalues_6.js create mode 100644 v1.3.0/search/files_0.js create mode 100644 v1.3.0/search/files_1.js create mode 100644 v1.3.0/search/functions_0.js create mode 100644 v1.3.0/search/functions_1.js create mode 100644 v1.3.0/search/functions_2.js create mode 100644 v1.3.0/search/functions_3.js create mode 100644 v1.3.0/search/functions_4.js create mode 100644 v1.3.0/search/functions_5.js create mode 100644 v1.3.0/search/functions_6.js create mode 100644 v1.3.0/search/functions_7.js create mode 100644 v1.3.0/search/functions_8.js create mode 100644 v1.3.0/search/groups_0.js create mode 100644 v1.3.0/search/groups_1.js create mode 100644 v1.3.0/search/groups_2.js create mode 100644 v1.3.0/search/groups_3.js create mode 100644 v1.3.0/search/mag.svg create mode 100644 v1.3.0/search/mag_d.svg create mode 100644 v1.3.0/search/mag_sel.svg create mode 100644 v1.3.0/search/mag_seld.svg create mode 100644 v1.3.0/search/pages_0.js create mode 100644 v1.3.0/search/pages_1.js create mode 100644 v1.3.0/search/pages_2.js create mode 100644 v1.3.0/search/pages_3.js create mode 100644 v1.3.0/search/pages_4.js create mode 100644 v1.3.0/search/pages_5.js create mode 100644 v1.3.0/search/pages_6.js create mode 100644 v1.3.0/search/search.css create mode 100644 v1.3.0/search/search.js create mode 100644 v1.3.0/search/searchdata.js create mode 100644 v1.3.0/search/typedefs_0.js create mode 100644 v1.3.0/search/typedefs_1.js create mode 100644 v1.3.0/search/typedefs_2.js create mode 100644 v1.3.0/search/variables_0.js create mode 100644 v1.3.0/search/variables_1.js create mode 100644 v1.3.0/search/variables_10.js create mode 100644 v1.3.0/search/variables_11.js create mode 100644 v1.3.0/search/variables_12.js create mode 100644 v1.3.0/search/variables_13.js create mode 100644 v1.3.0/search/variables_2.js create mode 100644 v1.3.0/search/variables_3.js create mode 100644 v1.3.0/search/variables_4.js create mode 100644 v1.3.0/search/variables_5.js create mode 100644 v1.3.0/search/variables_6.js create mode 100644 v1.3.0/search/variables_7.js create mode 100644 v1.3.0/search/variables_8.js create mode 100644 v1.3.0/search/variables_9.js create mode 100644 v1.3.0/search/variables_a.js create mode 100644 v1.3.0/search/variables_b.js create mode 100644 v1.3.0/search/variables_c.js create mode 100644 v1.3.0/search/variables_d.js create mode 100644 v1.3.0/search/variables_e.js create mode 100644 v1.3.0/search/variables_f.js create mode 100644 v1.3.0/splitbar.png create mode 100644 v1.3.0/splitbard.png create mode 100644 v1.3.0/struct_m_q_t_t_agent_ack_info__t.html create mode 100644 v1.3.0/struct_m_q_t_t_agent_command.html create mode 100644 v1.3.0/struct_m_q_t_t_agent_command_func_returns__t.html create mode 100644 v1.3.0/struct_m_q_t_t_agent_command_info__t.html create mode 100644 v1.3.0/struct_m_q_t_t_agent_connect_args__t.html create mode 100644 v1.3.0/struct_m_q_t_t_agent_context__t.html create mode 100644 v1.3.0/struct_m_q_t_t_agent_message_interface__t.html create mode 100644 v1.3.0/struct_m_q_t_t_agent_return_info__t.html create mode 100644 v1.3.0/struct_m_q_t_t_agent_subscribe_args__t.html create mode 100644 v1.3.0/style.css create mode 100644 v1.3.0/sync_off.png create mode 100644 v1.3.0/sync_on.png create mode 100644 v1.3.0/tab_a.png create mode 100644 v1.3.0/tab_ad.png create mode 100644 v1.3.0/tab_b.png create mode 100644 v1.3.0/tab_bd.png create mode 100644 v1.3.0/tab_h.png create mode 100644 v1.3.0/tab_hd.png create mode 100644 v1.3.0/tab_s.png create mode 100644 v1.3.0/tab_sd.png create mode 100644 v1.3.0/tabs.css diff --git a/_data/doc_config.json b/_data/doc_config.json index 25b0f70a..4b2ff29e 100644 --- a/_data/doc_config.json +++ b/_data/doc_config.json @@ -1,6 +1,7 @@ { "name": "coreMQTT Agent Library", "releases": [ + "v1.3.0", "v1.2.0", "v1.1.0", "v1.0.1", diff --git a/latest b/latest deleted file mode 120000 index 0408c30b..00000000 --- a/latest +++ /dev/null @@ -1 +0,0 @@ -v1.2.0 \ No newline at end of file diff --git a/latest/annotated.html b/latest/annotated.html new file mode 100644 index 00000000..fd3b477e --- /dev/null +++ b/latest/annotated.html @@ -0,0 +1,125 @@ + + + + + + + +coreMQTT Agent: Data Structures + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Data Structures
+
+
+
Here are the data structures with brief descriptions:
+ + + + + + + + + + +
 CMQTTAgentAckInfo_tInformation for a pending MQTT ack packet expected by the agent
 CMQTTAgentCommand_tThe commands sent from the APIs to the MQTT agent task
 CMQTTAgentCommandFuncReturns_tA structure of values and flags expected to be returned by command functions
 CMQTTAgentCommandInfo_tStruct holding arguments that are common to every command
 CMQTTAgentConnectArgs_tStruct holding arguments for a CONNECT call
 CMQTTAgentContext_tInformation used by each MQTT agent. A context will be initialized by MQTTAgent_Init(), and every API function will accept a pointer to the initalized struct
 CMQTTAgentMessageInterface_tFunction pointers and contexts used for sending and receiving commands, and allocating memory for them
 CMQTTAgentReturnInfo_tStruct holding return codes and outputs from a command
 CMQTTAgentSubscribeArgs_tStruct holding arguments for a SUBSCRIBE or UNSUBSCRIBE call
+
+
+
+ + + + diff --git a/latest/bc_s.png b/latest/bc_s.png new file mode 100644 index 0000000000000000000000000000000000000000..224b29aa9847d5a4b3902efd602b7ddf7d33e6c2 GIT binary patch literal 676 zcmV;V0$crwP)y__>=_9%My z{n931IS})GlGUF8K#6VIbs%684A^L3@%PlP2>_sk`UWPq@f;rU*V%rPy_ekbhXT&s z(GN{DxFv}*vZp`F>S!r||M`I*nOwwKX+BC~3P5N3-)Y{65c;ywYiAh-1*hZcToLHK ztpl1xomJ+Yb}K(cfbJr2=GNOnT!UFA7Vy~fBz8?J>XHsbZoDad^8PxfSa0GDgENZS zuLCEqzb*xWX2CG*b&5IiO#NzrW*;`VC9455M`o1NBh+(k8~`XCEEoC1Ybwf;vr4K3 zg|EB<07?SOqHp9DhLpS&bzgo70I+ghB_#)K7H%AMU3v}xuyQq9&Bm~++VYhF09a+U zl7>n7Jjm$K#b*FONz~fj;I->Bf;ule1prFN9FovcDGBkpg>)O*-}eLnC{6oZHZ$o% zXKW$;0_{8hxHQ>l;_*HATI(`7t#^{$(zLe}h*mqwOc*nRY9=?Sx4OOeVIfI|0V(V2 zBrW#G7Ss9wvzr@>H*`r>zE z+e8bOBgqIgldUJlG(YUDviMB`9+DH8n-s9SXRLyJHO1!=wY^79WYZMTa(wiZ!zP66 zA~!21vmF3H2{ngD;+`6j#~6j;$*f*G_2ZD1E;9(yaw7d-QnSCpK(cR1zU3qU0000< KMNUMnLSTYoA~SLT literal 0 HcmV?d00001 diff --git a/latest/bc_sd.png b/latest/bc_sd.png new file mode 100644 index 0000000000000000000000000000000000000000..31ca888dc71049713b35c351933a8d0f36180bf1 GIT binary patch literal 635 zcmV->0)+jEP)Jwi0r1~gdSq#w{Bu1q z`craw(p2!hu$4C_$Oc3X(sI6e=9QSTwPt{G) z=htT&^~&c~L2~e{r5_5SYe7#Is-$ln>~Kd%$F#tC65?{LvQ}8O`A~RBB0N~`2M+waajO;5>3B&-viHGJeEK2TQOiPRa zfDKyqwMc4wfaEh4jt>H`nW_Zidwk@Bowp`}(VUaj-pSI(-1L>FJVsX}Yl9~JsqgsZ zUD9(rMwf23Gez6KPa|wwInZodP-2}9@fK0Ga_9{8SOjU&4l`pH4@qlQp83>>HT$xW zER^U>)MyV%t(Lu=`d=Y?{k1@}&r7ZGkFQ%z%N+sE9BtYjovzxyxCPxN6&@wLK{soQ zSmkj$aLI}miuE^p@~4}mg9OjDfGEkgY4~^XzLRUBB*O{+&vq<3v(E%+k_i%=`~j%{ Vj14gnt9}3g002ovPDHLkV1n!oC4m3{ literal 0 HcmV?d00001 diff --git a/latest/bdwn.png b/latest/bdwn.png new file mode 100644 index 0000000000000000000000000000000000000000..940a0b950443a0bb1b216ac03c45b8a16c955452 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)H!3HEvS)PKZC{Gv1kP61Pb5HX&C2wk~_T + + + + + + +coreMQTT Agent: Data Structure Index + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ + + + + + diff --git a/latest/closed.png b/latest/closed.png new file mode 100644 index 0000000000000000000000000000000000000000..98cc2c909da37a6df914fbf67780eebd99c597f5 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{V-kvUwAr*{o@8{^CZMh(5KoB^r_<4^zF@3)Cp&&t3hdujKf f*?bjBoY!V+E))@{xMcbjXe@)LtDnm{r-UW|*e5JT literal 0 HcmV?d00001 diff --git a/latest/coreMQTT/annotated.html b/latest/coreMQTT/annotated.html new file mode 100644 index 00000000..968de672 --- /dev/null +++ b/latest/coreMQTT/annotated.html @@ -0,0 +1,126 @@ + + + + + + + +coreMQTT: Data Structures + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Data Structures
+
+
+
Here are the data structures with brief descriptions:
+ + + + + + + + + + + +
 CMQTTConnectInfo_tMQTT CONNECT packet parameters
 CMQTTContext_tA struct representing an MQTT connection
 CMQTTDeserializedInfo_tStruct to hold deserialized packet information for an MQTTEventCallback_t callback
 CMQTTFixedBuffer_tBuffer passed to MQTT library
 CMQTTPacketInfo_tMQTT incoming packet parameters
 CMQTTPubAckInfo_tAn element of the state engine records for QoS 1 or Qos 2 publishes
 CMQTTPublishInfo_tMQTT PUBLISH packet parameters
 CMQTTSubscribeInfo_tMQTT SUBSCRIBE packet parameters
 CTransportInterface_tThe transport layer interface
 CTransportOutVector_tTransport vector structure for sending multiple messages
+
+
+
+ + + + diff --git a/latest/coreMQTT/bc_s.png b/latest/coreMQTT/bc_s.png new file mode 100644 index 0000000000000000000000000000000000000000..224b29aa9847d5a4b3902efd602b7ddf7d33e6c2 GIT binary patch literal 676 zcmV;V0$crwP)y__>=_9%My z{n931IS})GlGUF8K#6VIbs%684A^L3@%PlP2>_sk`UWPq@f;rU*V%rPy_ekbhXT&s z(GN{DxFv}*vZp`F>S!r||M`I*nOwwKX+BC~3P5N3-)Y{65c;ywYiAh-1*hZcToLHK ztpl1xomJ+Yb}K(cfbJr2=GNOnT!UFA7Vy~fBz8?J>XHsbZoDad^8PxfSa0GDgENZS zuLCEqzb*xWX2CG*b&5IiO#NzrW*;`VC9455M`o1NBh+(k8~`XCEEoC1Ybwf;vr4K3 zg|EB<07?SOqHp9DhLpS&bzgo70I+ghB_#)K7H%AMU3v}xuyQq9&Bm~++VYhF09a+U zl7>n7Jjm$K#b*FONz~fj;I->Bf;ule1prFN9FovcDGBkpg>)O*-}eLnC{6oZHZ$o% zXKW$;0_{8hxHQ>l;_*HATI(`7t#^{$(zLe}h*mqwOc*nRY9=?Sx4OOeVIfI|0V(V2 zBrW#G7Ss9wvzr@>H*`r>zE z+e8bOBgqIgldUJlG(YUDviMB`9+DH8n-s9SXRLyJHO1!=wY^79WYZMTa(wiZ!zP66 zA~!21vmF3H2{ngD;+`6j#~6j;$*f*G_2ZD1E;9(yaw7d-QnSCpK(cR1zU3qU0000< KMNUMnLSTYoA~SLT literal 0 HcmV?d00001 diff --git a/latest/coreMQTT/bc_sd.png b/latest/coreMQTT/bc_sd.png new file mode 100644 index 0000000000000000000000000000000000000000..31ca888dc71049713b35c351933a8d0f36180bf1 GIT binary patch literal 635 zcmV->0)+jEP)Jwi0r1~gdSq#w{Bu1q z`craw(p2!hu$4C_$Oc3X(sI6e=9QSTwPt{G) z=htT&^~&c~L2~e{r5_5SYe7#Is-$ln>~Kd%$F#tC65?{LvQ}8O`A~RBB0N~`2M+waajO;5>3B&-viHGJeEK2TQOiPRa zfDKyqwMc4wfaEh4jt>H`nW_Zidwk@Bowp`}(VUaj-pSI(-1L>FJVsX}Yl9~JsqgsZ zUD9(rMwf23Gez6KPa|wwInZodP-2}9@fK0Ga_9{8SOjU&4l`pH4@qlQp83>>HT$xW zER^U>)MyV%t(Lu=`d=Y?{k1@}&r7ZGkFQ%z%N+sE9BtYjovzxyxCPxN6&@wLK{soQ zSmkj$aLI}miuE^p@~4}mg9OjDfGEkgY4~^XzLRUBB*O{+&vq<3v(E%+k_i%=`~j%{ Vj14gnt9}3g002ovPDHLkV1n!oC4m3{ literal 0 HcmV?d00001 diff --git a/latest/coreMQTT/bdwn.png b/latest/coreMQTT/bdwn.png new file mode 100644 index 0000000000000000000000000000000000000000..940a0b950443a0bb1b216ac03c45b8a16c955452 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)H!3HEvS)PKZC{Gv1kP61Pb5HX&C2wk~_T + + + + + + +coreMQTT: Data Structure Index + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Data Structure Index
+
+ +
+ + + + diff --git a/latest/coreMQTT/closed.png b/latest/coreMQTT/closed.png new file mode 100644 index 0000000000000000000000000000000000000000..98cc2c909da37a6df914fbf67780eebd99c597f5 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{V-kvUwAr*{o@8{^CZMh(5KoB^r_<4^zF@3)Cp&&t3hdujKf f*?bjBoY!V+E))@{xMcbjXe@)LtDnm{r-UW|*e5JT literal 0 HcmV?d00001 diff --git a/latest/coreMQTT/core__mqtt_8c.html b/latest/coreMQTT/core__mqtt_8c.html new file mode 100644 index 00000000..5914e832 --- /dev/null +++ b/latest/coreMQTT/core__mqtt_8c.html @@ -0,0 +1,2824 @@ + + + + + + + +coreMQTT: core_mqtt.c File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt.c File Reference
+
+
+ +

Implements the user-facing functions in core_mqtt.h. +More...

+
#include <string.h>
+#include <assert.h>
+#include "core_mqtt.h"
+#include "core_mqtt_state.h"
+#include "core_mqtt_config_defaults.h"
+
+ + + + + + + + + + + + + + + + + + + + + + +

+Macros

+#define MQTT_PRE_SEND_HOOK(pContext)
 Hook called before a 'send' operation is executed.
 
+#define MQTT_POST_SEND_HOOK(pContext)
 Hook called after the 'send' operation is complete.
 
+#define MQTT_PRE_STATE_UPDATE_HOOK(pContext)
 Hook called just before an update to the MQTT state is made.
 
+#define MQTT_POST_STATE_UPDATE_HOOK(pContext)
 Hook called just after an update to the MQTT state has been made.
 
+#define CORE_MQTT_SERIALIZED_LENGTH_FIELD_BYTES   ( 2U )
 Bytes required to encode any string length in an MQTT packet header. Length is always encoded in two bytes according to the MQTT specification.
 
#define CORE_MQTT_SUBSCRIBE_PER_TOPIC_VECTOR_LENGTH   ( 3U )
 Number of vectors required to encode one topic filter in a subscribe request. Three vectors are required as there are three fields in the subscribe request namely:
 
#define CORE_MQTT_UNSUBSCRIBE_PER_TOPIC_VECTOR_LENGTH   ( 2U )
 Number of vectors required to encode one topic filter in an unsubscribe request. Two vectors are required as there are two fields in the unsubscribe request namely:
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

static int32_t sendBuffer (MQTTContext_t *pContext, const uint8_t *pBufferToSend, size_t bytesToSend)
 Sends provided buffer to network using transport send.
 
static MQTTStatus_t sendConnectWithoutCopy (MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength)
 Sends MQTT connect without copying the users data into any buffer.
 
static int32_t sendMessageVector (MQTTContext_t *pContext, TransportOutVector_t *pIoVec, size_t ioVecCount)
 Sends the vector array passed through the parameters over the network.
 
static size_t addEncodedStringToVector (uint8_t serializedLength[CORE_MQTT_SERIALIZED_LENGTH_FIELD_BYTES], const char *const string, uint16_t length, TransportOutVector_t *iterator, size_t *updatedLength)
 Add a string and its length after serializing it in a manner outlined by the MQTT specification.
 
static MQTTStatus_t sendSubscribeWithoutCopy (MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength)
 Send MQTT SUBSCRIBE message without copying the user data into a buffer and directly sending it.
 
static MQTTStatus_t sendUnsubscribeWithoutCopy (MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength)
 Send MQTT UNSUBSCRIBE message without copying the user data into a buffer and directly sending it.
 
static uint32_t calculateElapsedTime (uint32_t later, uint32_t start)
 Calculate the interval between two millisecond timestamps, including when the later value has overflowed.
 
static MQTTPubAckType_t getAckFromPacketType (uint8_t packetType)
 Convert a byte indicating a publish ack type to an MQTTPubAckType_t.
 
static int32_t recvExact (const MQTTContext_t *pContext, size_t bytesToRecv)
 Receive bytes into the network buffer.
 
static MQTTStatus_t discardPacket (const MQTTContext_t *pContext, size_t remainingLength, uint32_t timeoutMs)
 Discard a packet from the transport interface.
 
static MQTTStatus_t discardStoredPacket (MQTTContext_t *pContext, const MQTTPacketInfo_t *pPacketInfo)
 Discard a packet from the MQTT buffer and the transport interface.
 
static MQTTStatus_t receivePacket (const MQTTContext_t *pContext, MQTTPacketInfo_t incomingPacket, uint32_t remainingTimeMs)
 Receive a packet from the transport interface.
 
static uint8_t getAckTypeToSend (MQTTPublishState_t state)
 Get the correct ack type to send.
 
static MQTTStatus_t sendPublishAcks (MQTTContext_t *pContext, uint16_t packetId, MQTTPublishState_t publishState)
 Send acks for received QoS 1/2 publishes.
 
static MQTTStatus_t handleKeepAlive (MQTTContext_t *pContext)
 Send a keep alive PINGREQ if the keep alive interval has elapsed.
 
static MQTTStatus_t handleIncomingPublish (MQTTContext_t *pContext, MQTTPacketInfo_t *pIncomingPacket)
 Handle received MQTT PUBLISH packet.
 
static MQTTStatus_t handlePublishAcks (MQTTContext_t *pContext, MQTTPacketInfo_t *pIncomingPacket)
 Handle received MQTT publish acks.
 
static MQTTStatus_t handleIncomingAck (MQTTContext_t *pContext, MQTTPacketInfo_t *pIncomingPacket, bool manageKeepAlive)
 Handle received MQTT ack.
 
static MQTTStatus_t receiveSingleIteration (MQTTContext_t *pContext, bool manageKeepAlive)
 Run a single iteration of the receive loop.
 
static MQTTStatus_t validateSubscribeUnsubscribeParams (const MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
 Validates parameters of MQTT_Subscribe or MQTT_Unsubscribe.
 
static MQTTStatus_t receiveConnack (const MQTTContext_t *pContext, uint32_t timeoutMs, bool cleanSession, MQTTPacketInfo_t *pIncomingPacket, bool *pSessionPresent)
 Receives a CONNACK MQTT packet.
 
static MQTTStatus_t handleSessionResumption (MQTTContext_t *pContext, bool sessionPresent)
 Resends pending acks for a re-established MQTT session, or clears existing state records for a clean session.
 
static MQTTStatus_t sendPublishWithoutCopy (MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, const uint8_t *pMqttHeader, size_t headerSize, uint16_t packetId)
 Send the publish packet without copying the topic string and payload in the buffer.
 
static MQTTStatus_t validatePublishParams (const MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId)
 Function to validate MQTT_Publish parameters.
 
static bool matchEndWildcardsSpecialCases (const char *pTopicFilter, uint16_t topicFilterLength, uint16_t filterIndex)
 Performs matching for special cases when a topic filter ends with a wildcard character.
 
static bool matchWildcards (const char *pTopicName, uint16_t topicNameLength, const char *pTopicFilter, uint16_t topicFilterLength, uint16_t *pNameIndex, uint16_t *pFilterIndex, bool *pMatch)
 Attempt to match topic name with a topic filter starting with a wildcard.
 
static bool matchTopicFilter (const char *pTopicName, uint16_t topicNameLength, const char *pTopicFilter, uint16_t topicFilterLength)
 Match a topic name and topic filter allowing the use of wildcards.
 
MQTTStatus_t MQTT_Init (MQTTContext_t *pContext, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getTimeFunction, MQTTEventCallback_t userCallback, const MQTTFixedBuffer_t *pNetworkBuffer)
 Initialize an MQTT context.
 
MQTTStatus_t MQTT_InitStatefulQoS (MQTTContext_t *pContext, MQTTPubAckInfo_t *pOutgoingPublishRecords, size_t outgoingPublishCount, MQTTPubAckInfo_t *pIncomingPublishRecords, size_t incomingPublishCount)
 Initialize an MQTT context for QoS > 0.
 
MQTTStatus_t MQTT_CancelCallback (const MQTTContext_t *pContext, uint16_t packetId)
 Cancels an outgoing publish callback (only for QoS > QoS0) by removing it from the pending ACK list.
 
MQTTStatus_t MQTT_Connect (MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
 Establish an MQTT session.
 
MQTTStatus_t MQTT_Subscribe (MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
 Sends MQTT SUBSCRIBE for the given list of topic filters to the broker.
 
MQTTStatus_t MQTT_Publish (MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId)
 Publishes a message to the given topic name.
 
MQTTStatus_t MQTT_Ping (MQTTContext_t *pContext)
 Sends an MQTT PINGREQ to broker.
 
MQTTStatus_t MQTT_Unsubscribe (MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
 Sends MQTT UNSUBSCRIBE for the given list of topic filters to the broker.
 
MQTTStatus_t MQTT_Disconnect (MQTTContext_t *pContext)
 Disconnect an MQTT session.
 
MQTTStatus_t MQTT_ProcessLoop (MQTTContext_t *pContext)
 Loop to receive packets from the transport interface. Handles keep alive.
 
MQTTStatus_t MQTT_ReceiveLoop (MQTTContext_t *pContext)
 Loop to receive packets from the transport interface. Does not handle keep alive.
 
uint16_t MQTT_GetPacketId (MQTTContext_t *pContext)
 Get a packet ID that is valid according to the MQTT 3.1.1 spec.
 
MQTTStatus_t MQTT_MatchTopic (const char *pTopicName, const uint16_t topicNameLength, const char *pTopicFilter, const uint16_t topicFilterLength, bool *pIsMatch)
 A utility function that determines whether the passed topic filter and topic name match according to the MQTT 3.1.1 protocol specification.
 
MQTTStatus_t MQTT_GetSubAckStatusCodes (const MQTTPacketInfo_t *pSubackPacket, uint8_t **pPayloadStart, size_t *pPayloadSize)
 Parses the payload of an MQTT SUBACK packet that contains status codes corresponding to topic filter subscription requests from the original subscribe packet.
 
const char * MQTT_Status_strerror (MQTTStatus_t status)
 Error code to string conversion for MQTT statuses.
 
+

Detailed Description

+

Implements the user-facing functions in core_mqtt.h.

+

Macro Definition Documentation

+ +

◆ CORE_MQTT_SUBSCRIBE_PER_TOPIC_VECTOR_LENGTH

+ +
+
+ + + + +
#define CORE_MQTT_SUBSCRIBE_PER_TOPIC_VECTOR_LENGTH   ( 3U )
+
+ +

Number of vectors required to encode one topic filter in a subscribe request. Three vectors are required as there are three fields in the subscribe request namely:

+
    +
  1. Topic filter length; 2. Topic filter; and 3. QoS in this order.
  2. +
+ +
+
+ +

◆ CORE_MQTT_UNSUBSCRIBE_PER_TOPIC_VECTOR_LENGTH

+ +
+
+ + + + +
#define CORE_MQTT_UNSUBSCRIBE_PER_TOPIC_VECTOR_LENGTH   ( 2U )
+
+ +

Number of vectors required to encode one topic filter in an unsubscribe request. Two vectors are required as there are two fields in the unsubscribe request namely:

+
    +
  1. Topic filter length; and 2. Topic filter in this order.
  2. +
+ +
+
+

Function Documentation

+ +

◆ sendBuffer()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static int32_t sendBuffer (MQTTContext_tpContext,
const uint8_t * pBufferToSend,
size_t bytesToSend 
)
+
+static
+
+ +

Sends provided buffer to network using transport send.

+

param[in] pContext Initialized MQTT context.

+

param[in] pBufferToSend Buffer to be sent to network.

+

param[in] bytesToSend Number of bytes to be sent.

+
Note
This operation may call the transport send function repeatedly to send bytes over the network until either:
    +
  1. The requested number of bytes bytesToSend have been sent. OR
  2. +
  3. MQTT_SEND_TIMEOUT_MS milliseconds have gone by since entering this function. OR
  4. +
  5. There is an error in sending data over the network.
  6. +
+
+
Returns
Total number of bytes sent, or negative value on network error.
+ +
+
+ +

◆ sendConnectWithoutCopy()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t sendConnectWithoutCopy (MQTTContext_tpContext,
const MQTTConnectInfo_tpConnectInfo,
const MQTTPublishInfo_tpWillInfo,
size_t remainingLength 
)
+
+static
+
+ +

Sends MQTT connect without copying the users data into any buffer.

+

param[in] pContext Initialized MQTT context.

+

param[in] pConnectInfo MQTT CONNECT packet information.

+

param[in] pWillInfo Last Will and Testament. Pass NULL if Last Will and Testament is not used.

+

param[in] remainingLength the length of the connect packet.

+
Note
This operation may call the transport send function repeatedly to send bytes over the network until either:
    +
  1. The requested number of bytes remainingLength have been sent. OR
  2. +
  3. MQTT_SEND_TIMEOUT_MS milliseconds have gone by since entering this function. OR
  4. +
  5. There is an error in sending data over the network.
  6. +
+
+
Returns
MQTTSendFailed or MQTTSuccess.
+ +
+
+ +

◆ sendMessageVector()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static int32_t sendMessageVector (MQTTContext_tpContext,
TransportOutVector_tpIoVec,
size_t ioVecCount 
)
+
+static
+
+ +

Sends the vector array passed through the parameters over the network.

+
Note
The preference is given to 'writev' function if it is present in the transport interface. Otherwise, a send call is made repeatedly to achieve the result.
+
Parameters
+ + + + +
[in]pContextInitialized MQTT context.
[in]pIoVecThe vector array to be sent.
[in]ioVecCountThe number of elements in the array.
+
+
+
Note
This operation may call the transport send or writev functions repeatedly to send bytes over the network until either:
    +
  1. The requested number of bytes have been sent. OR
  2. +
  3. MQTT_SEND_TIMEOUT_MS milliseconds have gone by since entering this function. OR
  4. +
  5. There is an error in sending data over the network.
  6. +
+
+
Returns
The total number of bytes sent or the error code as received from the transport interface.
+ +
+
+ +

◆ addEncodedStringToVector()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static size_t addEncodedStringToVector (uint8_t serializedLength[CORE_MQTT_SERIALIZED_LENGTH_FIELD_BYTES],
const char *const string,
uint16_t length,
TransportOutVector_titerator,
size_t * updatedLength 
)
+
+static
+
+ +

Add a string and its length after serializing it in a manner outlined by the MQTT specification.

+
Parameters
+ + + + + + +
[in]serializedLengthArray of two bytes to which the vector will point. The array must remain in scope until the message has been sent.
[in]stringThe string to be serialized.
[in]lengthThe length of the string to be serialized.
[in]iteratorThe iterator pointing to the first element in the transport interface IO array.
[out]updatedLengthThis parameter will be added to with the number of bytes added to the vector.
+
+
+
Returns
The number of vectors added.
+ +
+
+ +

◆ sendSubscribeWithoutCopy()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t sendSubscribeWithoutCopy (MQTTContext_tpContext,
const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId,
size_t remainingLength 
)
+
+static
+
+ +

Send MQTT SUBSCRIBE message without copying the user data into a buffer and directly sending it.

+
Parameters
+ + + + + + +
[in]pContextInitialized MQTT context.
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe count of elements in the list.
[in]packetIdThe packet ID of the subscribe packet
[in]remainingLengthThe remaining length of the subscribe packet.
+
+
+
Returns
MQTTSuccess or MQTTSendFailed.
+ +
+
+ +

◆ sendUnsubscribeWithoutCopy()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t sendUnsubscribeWithoutCopy (MQTTContext_tpContext,
const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId,
size_t remainingLength 
)
+
+static
+
+ +

Send MQTT UNSUBSCRIBE message without copying the user data into a buffer and directly sending it.

+
Parameters
+ + + + + + +
[in]pContextInitialized MQTT context.
[in]pSubscriptionListMQTT subscription info.
[in]subscriptionCountThe count of elements in the list.
[in]packetIdThe packet ID of the unsubscribe packet.
[in]remainingLengthThe remaining length of the unsubscribe packet.
+
+
+
Returns
MQTTSuccess or MQTTSendFailed.
+ +
+
+ +

◆ calculateElapsedTime()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static uint32_t calculateElapsedTime (uint32_t later,
uint32_t start 
)
+
+static
+
+ +

Calculate the interval between two millisecond timestamps, including when the later value has overflowed.

+
Note
In C, the operands are promoted to signed integers in subtraction. Using this function avoids the need to cast the result of subtractions back to uint32_t.
+
Parameters
+ + + +
[in]laterThe later time stamp, in milliseconds.
[in]startThe earlier time stamp, in milliseconds.
+
+
+
Returns
later - start.
+ +
+
+ +

◆ getAckFromPacketType()

+ +
+
+ + + + + +
+ + + + + + + + +
static MQTTPubAckType_t getAckFromPacketType (uint8_t packetType)
+
+static
+
+ +

Convert a byte indicating a publish ack type to an MQTTPubAckType_t.

+
Parameters
+ + +
[in]packetTypeFirst byte of fixed header.
+
+
+
Returns
Type of ack.
+ +
+
+ +

◆ recvExact()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static int32_t recvExact (const MQTTContext_tpContext,
size_t bytesToRecv 
)
+
+static
+
+ +

Receive bytes into the network buffer.

+
Parameters
+ + + +
[in]pContextInitialized MQTT Context.
[in]bytesToRecvNumber of bytes to receive.
+
+
+
Note
This operation calls the transport receive function repeatedly to read bytes from the network until either:
    +
  1. The requested number of bytes bytesToRecv are read. OR
  2. +
  3. No data is received from the network for MQTT_RECV_POLLING_TIMEOUT_MS duration.
                OR
    +
  4. +
  5. There is an error in reading from the network.
  6. +
+
+
Returns
Number of bytes received, or negative number on network error.
+ +
+
+ +

◆ discardPacket()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t discardPacket (const MQTTContext_tpContext,
size_t remainingLength,
uint32_t timeoutMs 
)
+
+static
+
+ +

Discard a packet from the transport interface.

+
Parameters
+ + + + +
[in]pContextMQTT Connection context.
[in]remainingLengthRemaining length of the packet to dump.
[in]timeoutMsTime remaining to discard the packet.
+
+
+
Returns
MQTTRecvFailed or MQTTNoDataAvailable.
+ +
+
+ +

◆ discardStoredPacket()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTStatus_t discardStoredPacket (MQTTContext_tpContext,
const MQTTPacketInfo_tpPacketInfo 
)
+
+static
+
+ +

Discard a packet from the MQTT buffer and the transport interface.

+
Parameters
+ + + +
[in]pContextMQTT Connection context.
[in]pPacketInfoInformation struct of the packet to be discarded.
+
+
+
Returns
MQTTRecvFailed or MQTTNoDataAvailable.
+ +
+
+ +

◆ receivePacket()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t receivePacket (const MQTTContext_tpContext,
MQTTPacketInfo_t incomingPacket,
uint32_t remainingTimeMs 
)
+
+static
+
+ +

Receive a packet from the transport interface.

+
Parameters
+ + + + +
[in]pContextMQTT Connection context.
[in]incomingPacketpacket struct with remaining length.
[in]remainingTimeMsTime remaining to receive the packet.
+
+
+
Returns
MQTTSuccess or MQTTRecvFailed.
+ +
+
+ +

◆ getAckTypeToSend()

+ +
+
+ + + + + +
+ + + + + + + + +
static uint8_t getAckTypeToSend (MQTTPublishState_t state)
+
+static
+
+ +

Get the correct ack type to send.

+
Parameters
+ + +
[in]stateCurrent state of publish.
+
+
+
Returns
Packet Type byte of PUBACK, PUBREC, PUBREL, or PUBCOMP if one of those should be sent, else 0.
+ +
+
+ +

◆ sendPublishAcks()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t sendPublishAcks (MQTTContext_tpContext,
uint16_t packetId,
MQTTPublishState_t publishState 
)
+
+static
+
+ +

Send acks for received QoS 1/2 publishes.

+
Parameters
+ + + + +
[in]pContextMQTT Connection context.
[in]packetIdpacket ID of original PUBLISH.
[in]publishStateCurrent publish state in record.
+
+
+
Returns
MQTTSuccess, MQTTIllegalState or MQTTSendFailed.
+ +
+
+ +

◆ handleKeepAlive()

+ +
+
+ + + + + +
+ + + + + + + + +
static MQTTStatus_t handleKeepAlive (MQTTContext_tpContext)
+
+static
+
+ +

Send a keep alive PINGREQ if the keep alive interval has elapsed.

+
Parameters
+ + +
[in]pContextInitialized MQTT Context.
+
+
+
Returns
MQTTKeepAliveTimeout if a PINGRESP is not received in time, MQTTSendFailed if the PINGREQ cannot be sent, or MQTTSuccess.
+ +
+
+ +

◆ handleIncomingPublish()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTStatus_t handleIncomingPublish (MQTTContext_tpContext,
MQTTPacketInfo_tpIncomingPacket 
)
+
+static
+
+ +

Handle received MQTT PUBLISH packet.

+
Parameters
+ + + +
[in]pContextMQTT Connection context.
[in]pIncomingPacketIncoming packet.
+
+
+
Returns
MQTTSuccess, MQTTIllegalState or deserialization error.
+ +
+
+ +

◆ handlePublishAcks()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTStatus_t handlePublishAcks (MQTTContext_tpContext,
MQTTPacketInfo_tpIncomingPacket 
)
+
+static
+
+ +

Handle received MQTT publish acks.

+
Parameters
+ + + +
[in]pContextMQTT Connection context.
[in]pIncomingPacketIncoming packet.
+
+
+
Returns
MQTTSuccess, MQTTIllegalState, or deserialization error.
+ +
+
+ +

◆ handleIncomingAck()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t handleIncomingAck (MQTTContext_tpContext,
MQTTPacketInfo_tpIncomingPacket,
bool manageKeepAlive 
)
+
+static
+
+ +

Handle received MQTT ack.

+
Parameters
+ + + + +
[in]pContextMQTT Connection context.
[in]pIncomingPacketIncoming packet.
[in]manageKeepAliveFlag indicating if PINGRESPs should not be given to the application
+
+
+
Returns
MQTTSuccess, MQTTIllegalState, or deserialization error.
+ +
+
+ +

◆ receiveSingleIteration()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTStatus_t receiveSingleIteration (MQTTContext_tpContext,
bool manageKeepAlive 
)
+
+static
+
+ +

Run a single iteration of the receive loop.

+
Parameters
+ + + +
[in]pContextMQTT Connection context.
[in]manageKeepAliveFlag indicating if keep alive should be handled.
+
+
+
Returns
MQTTRecvFailed if a network error occurs during reception; MQTTSendFailed if a network error occurs while sending an ACK or PINGREQ; MQTTBadResponse if an invalid packet is received; MQTTKeepAliveTimeout if the server has not sent a PINGRESP before MQTT_PINGRESP_TIMEOUT_MS milliseconds; MQTTIllegalState if an incoming QoS 1/2 publish or ack causes an invalid transition for the internal state machine; MQTTSuccess on success.
+ +
+
+ +

◆ validateSubscribeUnsubscribeParams()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t validateSubscribeUnsubscribeParams (const MQTTContext_tpContext,
const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId 
)
+
+static
+
+ +

Validates parameters of MQTT_Subscribe or MQTT_Unsubscribe.

+
Parameters
+ + + + + +
[in]pContextInitialized MQTT context.
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdPacket identifier.
+
+
+
Returns
MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+ +
+
+ +

◆ receiveConnack()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t receiveConnack (const MQTTContext_tpContext,
uint32_t timeoutMs,
bool cleanSession,
MQTTPacketInfo_tpIncomingPacket,
bool * pSessionPresent 
)
+
+static
+
+ +

Receives a CONNACK MQTT packet.

+
Parameters
+ + + + + + +
[in]pContextInitialized MQTT context.
[in]timeoutMsTimeout for waiting for CONNACK packet.
[in]cleanSessionClean session flag set by application.
[out]pIncomingPacketList of MQTT subscription info.
[out]pSessionPresentWhether a previous session was present. Only relevant if not establishing a clean session.
+
+
+
Returns
MQTTBadResponse if a bad response is received; MQTTNoDataAvailable if no data available for transport recv;
+

+MQTTRecvFailed if transport recv failed;

+

MQTTSuccess otherwise.

+ +
+
+ +

◆ handleSessionResumption()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTStatus_t handleSessionResumption (MQTTContext_tpContext,
bool sessionPresent 
)
+
+static
+
+ +

Resends pending acks for a re-established MQTT session, or clears existing state records for a clean session.

+
Parameters
+ + + +
[in]pContextInitialized MQTT context.
[in]sessionPresentSession present flag received from the MQTT broker.
+
+
+
Returns
MQTTSendFailed if transport send during resend failed; MQTTSuccess otherwise.
+ +
+
+ +

◆ sendPublishWithoutCopy()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t sendPublishWithoutCopy (MQTTContext_tpContext,
const MQTTPublishInfo_tpPublishInfo,
const uint8_t * pMqttHeader,
size_t headerSize,
uint16_t packetId 
)
+
+static
+
+ +

Send the publish packet without copying the topic string and payload in the buffer.

+

param[in] pContext Initialized MQTT context.

+

param[in] pPublishInfo MQTT PUBLISH packet parameters.

+

param[in] pMqttHeader the serialized MQTT header with the header byte; the encoded length of the packet; and the encoded length of the topic string.

+

param[in] headerSize Size of the serialized PUBLISH header.

+

param[in] packetId Packet Id of the publish packet.

+
Returns
MQTTSendFailed if transport send during resend failed; MQTTSuccess otherwise.
+ +
+
+ +

◆ validatePublishParams()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t validatePublishParams (const MQTTContext_tpContext,
const MQTTPublishInfo_tpPublishInfo,
uint16_t packetId 
)
+
+static
+
+ +

Function to validate MQTT_Publish parameters.

+

param[in] pContext Initialized MQTT context.

+

param[in] pPublishInfo MQTT PUBLISH packet parameters.

+

param[in] packetId Packet Id for the MQTT PUBLISH packet.

+
Returns
MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+ +
+
+ +

◆ matchEndWildcardsSpecialCases()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static bool matchEndWildcardsSpecialCases (const char * pTopicFilter,
uint16_t topicFilterLength,
uint16_t filterIndex 
)
+
+static
+
+ +

Performs matching for special cases when a topic filter ends with a wildcard character.

+

When the topic name has been consumed but there are remaining characters to to match in topic filter, this function handles the following 2 cases:

    +
  • When the topic filter ends with "/+" or "/#" characters, but the topic name only ends with '/'.
  • +
  • When the topic filter ends with "/#" characters, but the topic name ends at the parent level.
  • +
+
Note
This function ASSUMES that the topic name been consumed in linear matching with the topic filer, but the topic filter has remaining characters to be matched.
+
Parameters
+ + + + +
[in]pTopicFilterThe topic filter containing the wildcard.
[in]topicFilterLengthLength of the topic filter being examined.
[in]filterIndexIndex of the topic filter being examined.
+
+
+
Returns
Returns whether the topic filter and the topic name match.
+ +
+
+ +

◆ matchWildcards()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static bool matchWildcards (const char * pTopicName,
uint16_t topicNameLength,
const char * pTopicFilter,
uint16_t topicFilterLength,
uint16_t * pNameIndex,
uint16_t * pFilterIndex,
bool * pMatch 
)
+
+static
+
+ +

Attempt to match topic name with a topic filter starting with a wildcard.

+

If the topic filter starts with a '+' (single-level) wildcard, the function advances the pNameIndex by a level in the topic name. If the topic filter starts with a '#' (multi-level) wildcard, the function concludes that both the topic name and topic filter match.

+
Parameters
+ + + + + + + + +
[in]pTopicNameThe topic name to match.
[in]topicNameLengthLength of the topic name.
[in]pTopicFilterThe topic filter to match.
[in]topicFilterLengthLength of the topic filter.
[in,out]pNameIndexCurrent index in the topic name being examined. It is advanced by one level for + wildcards.
[in,out]pFilterIndexCurrent index in the topic filter being examined. It is advanced to position of '/' level separator for '+' wildcard.
[out]pMatchWhether the topic filter and topic name match.
+
+
+
Returns
true if the caller of this function should exit; false if the caller should continue parsing the topics.
+ +
+
+ +

◆ matchTopicFilter()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static bool matchTopicFilter (const char * pTopicName,
uint16_t topicNameLength,
const char * pTopicFilter,
uint16_t topicFilterLength 
)
+
+static
+
+ +

Match a topic name and topic filter allowing the use of wildcards.

+
Parameters
+ + + + + +
[in]pTopicNameThe topic name to check.
[in]topicNameLengthLength of the topic name.
[in]pTopicFilterThe topic filter to check.
[in]topicFilterLengthLength of topic filter.
+
+
+
Returns
true if the topic name and topic filter match; false otherwise.
+ +
+
+ +

◆ MQTT_Init()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_Init (MQTTContext_tpContext,
const TransportInterface_tpTransportInterface,
MQTTGetCurrentTimeFunc_t getTimeFunction,
MQTTEventCallback_t userCallback,
const MQTTFixedBuffer_tpNetworkBuffer 
)
+
+ +

Initialize an MQTT context.

+

This function must be called on an MQTTContext_t before any other function.

+
Note
The MQTTGetCurrentTimeFunc_t function for querying time must be defined. If there is no time implementation, it is the responsibility of the application to provide a dummy function to always return 0, provide 0 timeouts for all calls to MQTT_Connect, MQTT_ProcessLoop, and MQTT_ReceiveLoop and configure the MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS configurations to be 0. This will result in loop functions running for a single iteration, and MQTT_Connect relying on MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT to receive the CONNACK packet.
+
Parameters
+ + + + + + +
[in]pContextThe context to initialize.
[in]pTransportInterfaceThe transport interface to use with the context.
[in]getTimeFunctionThe time utility function which can return the amount of time (in milliseconds) elapsed since a given epoch. This function will be used to ensure that timeouts in the API calls are met and keep-alive messages are sent on time.
[in]userCallbackThe user callback to use with the context to notify about incoming packet events.
[in]pNetworkBufferNetwork buffer provided for the context. This buffer will be used to receive incoming messages from the broker. This buffer must remain valid and in scope for the entire lifetime of the pContext and must not be used by another context and/or application.
+
+
+
Returns
MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Function for obtaining a timestamp.
+
uint32_t getTimeStampMs();
+
// Callback function for receiving packets.
+
void eventCallback(
+
MQTTContext_t * pContext,
+
MQTTPacketInfo_t * pPacketInfo,
+
MQTTDeserializedInfo_t * pDeserializedInfo
+
);
+
// Network send.
+
int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
+
// Network receive.
+
int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
+
+
MQTTContext_t mqttContext;
+ +
MQTTFixedBuffer_t fixedBuffer;
+
// Create a globally accessible buffer which remains in scope for the entire duration
+
// of the MQTT context.
+
uint8_t buffer[ 1024 ];
+
+
// Clear context.
+
memset( ( void * ) &mqttContext, 0x00, sizeof( MQTTContext_t ) );
+
+
// Set transport interface members.
+
transport.pNetworkContext = &someTransportContext;
+
transport.send = networkSend;
+
transport.recv = networkRecv;
+
+
// Set buffer members.
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = 1024;
+
+
status = MQTT_Init( &mqttContext, &transport, getTimeStampMs, eventCallback, &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// Do something with mqttContext. The transport and fixedBuffer structs were
+
// copied into the context, so the original structs do not need to stay in scope.
+
// However, the memory pointed to by the fixedBuffer.pBuffer must remain in scope.
+
}
+
MQTTStatus_t MQTT_Init(MQTTContext_t *pContext, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getTimeFunction, MQTTEventCallback_t userCallback, const MQTTFixedBuffer_t *pNetworkBuffer)
Initialize an MQTT context.
Definition: core_mqtt.c:2531
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
Struct to hold deserialized packet information for an MQTTEventCallback_t callback.
Definition: core_mqtt.h:257
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+
The transport layer interface.
Definition: transport_interface.h:299
+
TransportSend_t send
Definition: transport_interface.h:301
+
TransportRecv_t recv
Definition: transport_interface.h:300
+
NetworkContext_t * pNetworkContext
Definition: transport_interface.h:303
+
+
+
+ +

◆ MQTT_InitStatefulQoS()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_InitStatefulQoS (MQTTContext_tpContext,
MQTTPubAckInfo_tpOutgoingPublishRecords,
size_t outgoingPublishCount,
MQTTPubAckInfo_tpIncomingPublishRecords,
size_t incomingPublishCount 
)
+
+ +

Initialize an MQTT context for QoS > 0.

+

This function must be called on an MQTTContext_t after MQTT_Init and before any other function.

+
Parameters
+ + + + + + +
[in]pContextThe context to initialize.
[in]pOutgoingPublishRecordsPointer to memory which will be used to store state of outgoing publishes.
[in]outgoingPublishCountMaximum number of records which can be kept in the memory pointed to by pOutgoingPublishRecords.
[in]pIncomingPublishRecordsPointer to memory which will be used to store state of incoming publishes.
[in]incomingPublishCountMaximum number of records which can be kept in the memory pointed to by pIncomingPublishRecords.
+
+
+
Returns
MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Function for obtaining a timestamp.
+
uint32_t getTimeStampMs();
+
// Callback function for receiving packets.
+
void eventCallback(
+
MQTTContext_t * pContext,
+
MQTTPacketInfo_t * pPacketInfo,
+
MQTTDeserializedInfo_t * pDeserializedInfo
+
);
+
// Network send.
+
int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
+
// Network receive.
+
int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
+
+
MQTTContext_t mqttContext;
+ +
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ 1024 ];
+
const size_t outgoingPublishCount = 30;
+
MQTTPubAckInfo_t outgoingPublishes[ outgoingPublishCount ];
+
+
// Clear context.
+
memset( ( void * ) &mqttContext, 0x00, sizeof( MQTTContext_t ) );
+
+
// Set transport interface members.
+
transport.pNetworkContext = &someTransportContext;
+
transport.send = networkSend;
+
transport.recv = networkRecv;
+
+
// Set buffer members.
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = 1024;
+
+
status = MQTT_Init( &mqttContext, &transport, getTimeStampMs, eventCallback, &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// We do not expect any incoming publishes in this example, therefore the incoming
+
// publish pointer is NULL and the count is zero.
+
status = MQTT_InitStatefulQoS( &mqttContext, outgoingPublishes, outgoingPublishCount, NULL, 0 );
+
+
// Now QoS1 and/or QoS2 publishes can be sent with this context.
+
}
+
MQTTStatus_t MQTT_InitStatefulQoS(MQTTContext_t *pContext, MQTTPubAckInfo_t *pOutgoingPublishRecords, size_t outgoingPublishCount, MQTTPubAckInfo_t *pIncomingPublishRecords, size_t incomingPublishCount)
Initialize an MQTT context for QoS > 0.
Definition: core_mqtt.c:2590
+
An element of the state engine records for QoS 1 or Qos 2 publishes.
Definition: core_mqtt.h:162
+
+
+
+ +

◆ MQTT_CancelCallback()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_CancelCallback (const MQTTContext_tpContext,
uint16_t packetId 
)
+
+ +

Cancels an outgoing publish callback (only for QoS > QoS0) by removing it from the pending ACK list.

+
Note
This cannot cancel the actual publish as that might have already been sent to the broker. This only removes the details of the given packet ID from the list of unACKed packet. That allows the caller to free any memory associated with the publish payload, topic string etc. Also, after this API call, the user provided callback will not be invoked when the ACK packet is received.
+
Parameters
+ + + +
[in]pContextInitialized MQTT context.
[in]packetIdpacket ID corresponding to the outstanding publish.
+
+
+
Returns
MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+ +
+
+ +

◆ MQTT_Connect()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_Connect (MQTTContext_tpContext,
const MQTTConnectInfo_tpConnectInfo,
const MQTTPublishInfo_tpWillInfo,
uint32_t timeoutMs,
bool * pSessionPresent 
)
+
+ +

Establish an MQTT session.

+

This function will send MQTT CONNECT packet and receive a CONNACK packet. The send and receive from the network is done through the transport interface.

+

The maximum time this function waits for a CONNACK is decided in one of the following ways:

    +
  1. If timeoutMs is greater than 0: MQTTContext_t.getTime is used to ensure that the function does not wait more than timeoutMs for CONNACK.
  2. +
  3. If timeoutMs is 0: The network receive for CONNACK is retried up to the number of times configured by MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT.
  4. +
+
Note
If a dummy MQTTGetCurrentTimeFunc_t was passed to MQTT_Init, then a timeout value of 0 MUST be passed to the API, and the MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS timeout configurations MUST be set to 0.
+
Parameters
+ + + + + + +
[in]pContextInitialized MQTT context.
[in]pConnectInfoMQTT CONNECT packet information.
[in]pWillInfoLast Will and Testament. Pass NULL if Last Will and Testament is not used.
[in]timeoutMsMaximum time in milliseconds to wait for a CONNACK packet. A zero timeout makes use of the retries for receiving CONNACK as configured with MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT.
[out]pSessionPresentThis value will be set to true if a previous session was present; otherwise it will be set to false. It is only relevant if not establishing a clean session.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport send failed; MQTTRecvFailed if transport receive failed for CONNACK; MQTTNoDataAvailable if no data available to receive in transport until the timeoutMs for CONNACK; MQTTSuccess otherwise.
+
Note
This API may spend more time than provided in the timeoutMS parameters in certain conditions as listed below:
+
    +
  1. Timeouts are incorrectly configured - If the timeoutMS is less than the transport receive timeout and if a CONNACK packet is not received within the transport receive timeout, the API will spend the transport receive timeout (which is more time than the timeoutMs). It is the case of incorrect timeout configuration as the timeoutMs parameter passed to this API must be greater than the transport receive timeout. Please refer to the transport interface documentation for more details about timeout configurations.
  2. +
  3. Partial CONNACK packet is received right before the expiry of the timeout - It is possible that first two bytes of CONNACK packet (packet type and remaining length) are received right before the expiry of the timeoutMS. In that case, the API makes one more network receive call in an attempt to receive the remaining 2 bytes. In the worst case, it can happen that the remaining 2 bytes are never received and this API will end up spending timeoutMs + transport receive timeout.
  4. +
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
bool sessionPresent;
+
// This is assumed to have been initialized before calling this function.
+
MQTTContext_t * pContext;
+
+
// True for creating a new session with broker, false if we want to resume an old one.
+
connectInfo.cleanSession = true;
+
// Client ID must be unique to broker. This field is required.
+
connectInfo.pClientIdentifier = "someClientID";
+
connectInfo.clientIdentifierLength = strlen( connectInfo.pClientIdentifier );
+
+
// The following fields are optional.
+
// Value for keep alive.
+
connectInfo.keepAliveSeconds = 60;
+
// Optional username and password.
+
connectInfo.pUserName = "someUserName";
+
connectInfo.userNameLength = strlen( connectInfo.pUserName );
+
connectInfo.pPassword = "somePassword";
+
connectInfo.passwordLength = strlen( connectInfo.pPassword );
+
+
// The last will and testament is optional, it will be published by the broker
+
// should this client disconnect without sending a DISCONNECT packet.
+
willInfo.qos = MQTTQoS0;
+
willInfo.pTopicName = "/lwt/topic/name";
+
willInfo.topicNameLength = strlen( willInfo.pTopicName );
+
willInfo.pPayload = "LWT Message";
+
willInfo.payloadLength = strlen( "LWT Message" );
+
+
// Send the connect packet. Use 100 ms as the timeout to wait for the CONNACK packet.
+
status = MQTT_Connect( pContext, &connectInfo, &willInfo, 100, &sessionPresent );
+
+
if( status == MQTTSuccess )
+
{
+
// Since we requested a clean session, this must be false
+
assert( sessionPresent == false );
+
+
// Do something with the connection.
+
}
+
MQTTStatus_t MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
Establish an MQTT session.
Definition: core_mqtt.c:2679
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
@ MQTTQoS0
Definition: core_mqtt_serializer.h:110
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
const char * pClientIdentifier
MQTT client identifier. Must be unique per client.
Definition: core_mqtt_serializer.h:147
+
const char * pUserName
MQTT user name. Set to NULL if not used.
Definition: core_mqtt_serializer.h:157
+
bool cleanSession
Whether to establish a new, clean session or resume a previous session.
Definition: core_mqtt_serializer.h:137
+
uint16_t userNameLength
Length of MQTT user name. Set to 0 if not used.
Definition: core_mqtt_serializer.h:162
+
uint16_t keepAliveSeconds
MQTT keep alive period.
Definition: core_mqtt_serializer.h:142
+
uint16_t clientIdentifierLength
Length of the client identifier.
Definition: core_mqtt_serializer.h:152
+
uint16_t passwordLength
Length of MQTT password. Set to 0 if not used.
Definition: core_mqtt_serializer.h:172
+
const char * pPassword
MQTT password. Set to NULL if not used.
Definition: core_mqtt_serializer.h:167
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+
MQTTQoS_t qos
Quality of Service for message.
Definition: core_mqtt_serializer.h:206
+
uint16_t topicNameLength
Length of topic name.
Definition: core_mqtt_serializer.h:226
+
size_t payloadLength
Message payload length.
Definition: core_mqtt_serializer.h:236
+
const char * pTopicName
Topic name on which the message is published.
Definition: core_mqtt_serializer.h:221
+
const void * pPayload
Message payload.
Definition: core_mqtt_serializer.h:231
+
+
+
+ +

◆ MQTT_Subscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_Subscribe (MQTTContext_tpContext,
const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId 
)
+
+ +

Sends MQTT SUBSCRIBE for the given list of topic filters to the broker.

+
Parameters
+ + + + + +
[in]pContextInitialized MQTT context.
[in]pSubscriptionListArray of MQTT subscription info.
[in]subscriptionCountThe number of elements in @ pSubscriptionList array.
[in]packetIdPacket ID generated by MQTT_GetPacketId.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
uint16_t packetId;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
// This is assumed to be a list of filters we want to subscribe to.
+
const char * filters[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// Set each subscription.
+
for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )
+
{
+
subscriptionList[ i ].qos = MQTTQoS0;
+
// Each subscription needs a topic filter.
+
subscriptionList[ i ].pTopicFilter = filters[ i ];
+
subscriptionList[ i ].topicFilterLength = strlen( filters[ i ] );
+
}
+
+
// Obtain a new packet id for the subscription.
+
packetId = MQTT_GetPacketId( pContext );
+
+
status = MQTT_Subscribe( pContext, &subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// We must now call MQTT_ReceiveLoop() or MQTT_ProcessLoop() to receive the SUBACK.
+
// If the broker accepts the subscription we can now receive publishes
+
// on the requested topics.
+
}
+
uint16_t MQTT_GetPacketId(MQTTContext_t *pContext)
Get a packet ID that is valid according to the MQTT 3.1.1 spec.
Definition: core_mqtt.c:3172
+
MQTTStatus_t MQTT_Subscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
Sends MQTT SUBSCRIBE for the given list of topic filters to the broker.
Definition: core_mqtt.c:2761
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+
MQTTQoS_t qos
Quality of Service for subscription.
Definition: core_mqtt_serializer.h:184
+
uint16_t topicFilterLength
Length of subscription topic filter.
Definition: core_mqtt_serializer.h:194
+
const char * pTopicFilter
Topic filter to subscribe to.
Definition: core_mqtt_serializer.h:189
+
+
+
+ +

◆ MQTT_Publish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_Publish (MQTTContext_tpContext,
const MQTTPublishInfo_tpPublishInfo,
uint16_t packetId 
)
+
+ +

Publishes a message to the given topic name.

+
Parameters
+ + + + +
[in]pContextInitialized MQTT context.
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
+
+
+
Returns
MQTTNoMemory if pBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo;
+
uint16_t packetId;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
+
// QoS of publish.
+
publishInfo.qos = MQTTQoS1;
+
publishInfo.pTopicName = "/some/topic/name";
+
publishInfo.topicNameLength = strlen( publishInfo.pTopicName );
+
publishInfo.pPayload = "Hello World!";
+
publishInfo.payloadLength = strlen( "Hello World!" );
+
+
// Packet ID is needed for QoS > 0.
+
packetId = MQTT_GetPacketId( pContext );
+
+
status = MQTT_Publish( pContext, &publishInfo, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// Since the QoS is > 0, we will need to call MQTT_ReceiveLoop()
+
// or MQTT_ProcessLoop() to process the publish acknowledgments.
+
}
+
MQTTStatus_t MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId)
Publishes a message to the given topic name.
Definition: core_mqtt.c:2805
+
@ MQTTQoS1
Definition: core_mqtt_serializer.h:111
+
+
+
+ +

◆ MQTT_Ping()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_Ping (MQTTContext_tpContext)
+
+ +

Sends an MQTT PINGREQ to broker.

+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Returns
MQTTNoMemory if pBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+ +
+
+ +

◆ MQTT_Unsubscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_Unsubscribe (MQTTContext_tpContext,
const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId 
)
+
+ +

Sends MQTT UNSUBSCRIBE for the given list of topic filters to the broker.

+
Parameters
+ + + + + +
[in]pContextInitialized MQTT context.
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t unsubscribeList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
uint16_t packetId;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
// This is assumed to be a list of filters we want to unsubscribe from.
+
const char * filters[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// Set information for each unsubscribe request.
+
for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )
+
{
+
unsubscribeList[ i ].pTopicFilter = filters[ i ];
+
unsubscribeList[ i ].topicFilterLength = strlen( filters[ i ] );
+
+
// The QoS field of MQTT_SubscribeInfo_t is unused for unsubscribing.
+
}
+
+
// Obtain a new packet id for the unsubscribe request.
+
packetId = MQTT_GetPacketId( pContext );
+
+
status = MQTT_Unsubscribe( pContext, &unsubscribeList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// We must now call MQTT_ReceiveLoop() or MQTT_ProcessLoop() to receive the UNSUBACK.
+
// After this the broker should no longer send publishes for these topics.
+
}
+
MQTTStatus_t MQTT_Unsubscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
Sends MQTT UNSUBSCRIBE for the given list of topic filters to the broker.
Definition: core_mqtt.c:3000
+
+
+
+ +

◆ MQTT_Disconnect()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_Disconnect (MQTTContext_tpContext)
+
+ +

Disconnect an MQTT session.

+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport send failed; MQTTSuccess otherwise.
+ +
+
+ +

◆ MQTT_ProcessLoop()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_ProcessLoop (MQTTContext_tpContext)
+
+ +

Loop to receive packets from the transport interface. Handles keep alive.

+
Note
If a dummy timer function, MQTTGetCurrentTimeFunc_t, is passed to the library, then the keep-alive mechanism is not supported by the MQTT_ProcessLoop API. In that case, the MQTT_ReceiveLoop API function should be used instead.
+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Note
Calling this function blocks the calling context for a time period that depends on the passed the configuration macros, MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS, and the underlying transport interface implementation timeouts, unless an error occurs. The blocking period also depends on the execution time of the MQTTEventCallback_t callback supplied to the library. It is recommended that the supplied MQTTEventCallback_t callback does not contain blocking operations to prevent potential non-deterministic blocking period of the MQTT_ProcessLoop API call.
+
Returns
MQTTBadParameter if context is NULL; MQTTRecvFailed if a network error occurs during reception; MQTTSendFailed if a network error occurs while sending an ACK or PINGREQ; MQTTBadResponse if an invalid packet is received; MQTTKeepAliveTimeout if the server has not sent a PINGRESP before MQTT_PINGRESP_TIMEOUT_MS milliseconds; MQTTIllegalState if an incoming QoS 1/2 publish or ack causes an invalid transition for the internal state machine; MQTTNeedMoreBytes if MQTT_ProcessLoop has received incomplete data; it should be called again (probably after a delay); MQTTSuccess on success.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
+
while( true )
+
{
+
status = MQTT_ProcessLoop( pContext );
+
+
if( status != MQTTSuccess && status != MQTTNeedMoreBytes )
+
{
+
// Determine the error. It's possible we might need to disconnect
+
// the underlying transport connection.
+
}
+
else
+
{
+
// Other application functions.
+
}
+
}
+
MQTTStatus_t MQTT_ProcessLoop(MQTTContext_t *pContext)
Loop to receive packets from the transport interface. Handles keep alive.
Definition: core_mqtt.c:3119
+
@ MQTTNeedMoreBytes
Definition: core_mqtt_serializer.h:99
+
+
+
+ +

◆ MQTT_ReceiveLoop()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_ReceiveLoop (MQTTContext_tpContext)
+
+ +

Loop to receive packets from the transport interface. Does not handle keep alive.

+
Note
If a dummy MQTTGetCurrentTimeFunc_t was passed to MQTT_Init, then the MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS timeout configurations MUST be set to 0.
+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Note
Calling this function blocks the calling context for a time period that depends on the the configuration macros, MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS, and the underlying transport interface implementation timeouts, unless an error occurs. The blocking period also depends on the execution time of the MQTTEventCallback_t callback supplied to the library. It is recommended that the supplied MQTTEventCallback_t callback does not contain blocking operations to prevent potential non-deterministic blocking period of the MQTT_ReceiveLoop API call.
+
Returns
MQTTBadParameter if context is NULL; MQTTRecvFailed if a network error occurs during reception; MQTTSendFailed if a network error occurs while sending an ACK or PINGREQ; MQTTBadResponse if an invalid packet is received; MQTTIllegalState if an incoming QoS 1/2 publish or ack causes an invalid transition for the internal state machine; MQTTNeedMoreBytes if MQTT_ReceiveLoop has received incomplete data; it should be called again (probably after a delay); MQTTSuccess on success.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
uint32_t keepAliveMs = 60 * 1000;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
+
while( true )
+
{
+
status = MQTT_ReceiveLoop( pContext );
+
+
if( status != MQTTSuccess && status != MQTTNeedMoreBytes )
+
{
+
// Determine the error. It's possible we might need to disconnect
+
// the underlying transport connection.
+
}
+
else
+
{
+
// Since this function does not send pings, the application may need
+
// to in order to comply with keep alive.
+
if( ( pContext->getTime() - pContext->lastPacketTxTime ) > keepAliveMs )
+
{
+
status = MQTT_Ping( pContext );
+
}
+
+
// Other application functions.
+
}
+
}
+
MQTTStatus_t MQTT_Ping(MQTTContext_t *pContext)
Sends an MQTT PINGREQ to broker.
Definition: core_mqtt.c:2922
+
MQTTStatus_t MQTT_ReceiveLoop(MQTTContext_t *pContext)
Loop to receive packets from the transport interface. Does not handle keep alive.
Definition: core_mqtt.c:3146
+
uint32_t lastPacketTxTime
Timestamp of the last packet sent by the library.
Definition: core_mqtt.h:227
+
MQTTGetCurrentTimeFunc_t getTime
Function used to get millisecond timestamps.
Definition: core_mqtt.h:217
+
+
+
+ +

◆ MQTT_GetPacketId()

+ +
+
+ + + + + + + + +
uint16_t MQTT_GetPacketId (MQTTContext_tpContext)
+
+ +

Get a packet ID that is valid according to the MQTT 3.1.1 spec.

+
Parameters
+ + +
[in]pContextInitialized MQTT context.
+
+
+
Returns
A non-zero number.
+ +
+
+ +

◆ MQTT_MatchTopic()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_MatchTopic (const char * pTopicName,
const uint16_t topicNameLength,
const char * pTopicFilter,
const uint16_t topicFilterLength,
bool * pIsMatch 
)
+
+ +

A utility function that determines whether the passed topic filter and topic name match according to the MQTT 3.1.1 protocol specification.

+
Parameters
+ + + + + + +
[in]pTopicNameThe topic name to check.
[in]topicNameLengthLength of the topic name.
[in]pTopicFilterThe topic filter to check.
[in]topicFilterLengthLength of topic filter.
[out]pIsMatchIf the match is performed without any error, that is if the return value is MQTTSuccess, then and only then the value in this parameter is valid and updated. In such a case, if the topic filter and the topic name match, then this value is set to true; otherwise if there is no match then it is set to false.
+
+
+
Note
The API assumes that the passed topic name is valid to meet the requirements of the MQTT 3.1.1 specification. Invalid topic names (for example, containing wildcard characters) should not be passed to the function. Also, the API checks validity of topic filter for wildcard characters ONLY if the passed topic name and topic filter do not have an exact string match.
+
Returns
Returns one of the following: +
+

Example

// Variables used in this example.
+
const char * pTopic = "topic/match/1";
+
const char * pFilter = "topic/#";
+ +
bool match = false;
+
+
status = MQTT_MatchTopic( pTopic, strlen( pTopic ), pFilter, strlen( pFilter ), &match );
+
// Our parameters were valid, so this will return success.
+
assert( status == MQTTSuccess );
+
+
// For this specific example, we already know this value is true. This
+
// check is placed here as an example for use with variable topic names.
+
if( match )
+
{
+
// Application can decide what to do with the matching topic name.
+
}
+
MQTTStatus_t MQTT_MatchTopic(const char *pTopicName, const uint16_t topicNameLength, const char *pTopicFilter, const uint16_t topicFilterLength, bool *pIsMatch)
A utility function that determines whether the passed topic filter and topic name match according to ...
Definition: core_mqtt.c:3201
+
+
+
+ +

◆ MQTT_GetSubAckStatusCodes()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetSubAckStatusCodes (const MQTTPacketInfo_tpSubackPacket,
uint8_t ** pPayloadStart,
size_t * pPayloadSize 
)
+
+ +

Parses the payload of an MQTT SUBACK packet that contains status codes corresponding to topic filter subscription requests from the original subscribe packet.

+

Each return code in the SUBACK packet corresponds to a topic filter in the SUBSCRIBE Packet being acknowledged. The status codes can be one of the following:

    +
  • 0x00 - Success - Maximum QoS 0
  • +
  • 0x01 - Success - Maximum QoS 1
  • +
  • 0x02 - Success - Maximum QoS 2
  • +
  • 0x80 - Failure Refer to MQTTSubAckStatus_t for the status codes.
  • +
+
Parameters
+ + + + +
[in]pSubackPacketThe SUBACK packet whose payload is to be parsed.
[out]pPayloadStartThis is populated with the starting address of the payload (or return codes for topic filters) in the SUBACK packet.
[out]pPayloadSizeThis is populated with the size of the payload in the SUBACK packet. It represents the number of topic filters whose SUBACK status is present in the packet.
+
+
+
Returns
Returns one of the following: +
+

Example

// Global variable used in this example.
+
// This is assumed to be the subscription list in the original SUBSCRIBE packet.
+
MQTTSubscribeInfo_t pSubscribes[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// MQTT_GetSubAckStatusCodes is intended to be used from the application
+
// callback that is called by the library in MQTT_ProcessLoop or MQTT_ReceiveLoop.
+
void eventCallback(
+
MQTTContext_t * pContext,
+
MQTTPacketInfo_t * pPacketInfo,
+
MQTTDeserializedInfo_t * pDeserializedInfo
+
)
+
{
+ +
uint8_t * pCodes;
+
size_t numCodes;
+
+
if( pPacketInfo->type == MQTT_PACKET_TYPE_SUBACK )
+
{
+
status = MQTT_GetSubAckStatusCodes( pPacketInfo, &pCodes, &numCodes );
+
+
// Since the pointers to the payload and payload size are not NULL, and
+
// we use the packet info struct passed to the app callback (verified
+
// to be valid by the library), this function must return success.
+
assert( status == MQTTSuccess );
+
// The server must send a response code for each topic filter in the
+
// original SUBSCRIBE packet.
+
assert( numCodes == NUMBER_OF_SUBSCRIPTIONS );
+
+
for( int i = 0; i < numCodes; i++ )
+
{
+
// The only failure code is 0x80 = MQTTSubAckFailure.
+
if( pCodes[ i ] == MQTTSubAckFailure )
+
{
+
// The subscription failed, we may want to retry the
+
// subscription in pSubscribes[ i ] outside of this callback.
+
}
+
else
+
{
+
// The subscription was granted, but the maximum QoS may be
+
// lower than what was requested. We can verify the granted QoS.
+
if( pSubscribes[ i ].qos != pCodes[ i ] )
+
{
+ +
"Requested QoS %u, but granted QoS %u for %s",
+
pSubscribes[ i ].qos, pCodes[ i ], pSubscribes[ i ].pTopicFilter
+
) );
+
}
+
}
+
}
+
}
+
// Handle other packet types.
+
}
+
MQTTStatus_t MQTT_GetSubAckStatusCodes(const MQTTPacketInfo_t *pSubackPacket, uint8_t **pPayloadStart, size_t *pPayloadSize)
Parses the payload of an MQTT SUBACK packet that contains status codes corresponding to topic filter ...
Definition: core_mqtt.c:3270
+
#define LogWarn(message)
Macro that is called in the MQTT library for logging "Warning" level messages.
Definition: core_mqtt_config_defaults.h:235
+
#define MQTT_PACKET_TYPE_SUBACK
SUBACK (server-to-client).
Definition: core_mqtt_serializer.h:61
+
@ MQTTSubAckFailure
Failure.
Definition: core_mqtt.h:154
+
uint8_t type
Type of incoming MQTT packet.
Definition: core_mqtt_serializer.h:248
+
+
+
+ +

◆ MQTT_Status_strerror()

+ +
+
+ + + + + + + + +
const char * MQTT_Status_strerror (MQTTStatus_t status)
+
+ +

Error code to string conversion for MQTT statuses.

+
Parameters
+ + +
[in]statusThe status to convert to a string.
+
+
+
Returns
The string representation of the status.
+ +
+
+
+
+ + + + diff --git a/latest/coreMQTT/core__mqtt_8h.html b/latest/coreMQTT/core__mqtt_8h.html new file mode 100644 index 00000000..fc26a0fd --- /dev/null +++ b/latest/coreMQTT/core__mqtt_8h.html @@ -0,0 +1,1281 @@ + + + + + + + +coreMQTT: core_mqtt.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt.h File Reference
+
+
+ +

User-facing functions of the MQTT 3.1.1 library. +More...

+ +

Go to the source code of this file.

+ + + + + + + + + + + +

+Data Structures

struct  MQTTPubAckInfo_t
 An element of the state engine records for QoS 1 or Qos 2 publishes. More...
 
struct  MQTTContext_t
 A struct representing an MQTT connection. More...
 
struct  MQTTDeserializedInfo_t
 Struct to hold deserialized packet information for an MQTTEventCallback_t callback. More...
 
+ + + + +

+Macros

#define MQTT_PACKET_ID_INVALID   ( ( uint16_t ) 0U )
 Invalid packet identifier.
 
+ + + + + + + +

+Typedefs

typedef uint32_t(* MQTTGetCurrentTimeFunc_t) (void)
 Application provided function to query the time elapsed since a given epoch in milliseconds.
 
typedef void(* MQTTEventCallback_t) (struct MQTTContext *pContext, struct MQTTPacketInfo *pPacketInfo, struct MQTTDeserializedInfo *pDeserializedInfo)
 Application callback for receiving incoming publishes and incoming acks.
 
+ + + + + + + + + + + + + +

+Enumerations

enum  MQTTConnectionStatus_t { MQTTNotConnected +, MQTTConnected + }
 Values indicating if an MQTT connection exists. More...
 
enum  MQTTPublishState_t {
+  MQTTStateNull = 0 +, MQTTPublishSend +, MQTTPubAckSend +, MQTTPubRecSend +,
+  MQTTPubRelSend +, MQTTPubCompSend +, MQTTPubAckPending +, MQTTPubRecPending +,
+  MQTTPubRelPending +, MQTTPubCompPending +, MQTTPublishDone +
+ }
 The state of QoS 1 or QoS 2 MQTT publishes, used in the state engine. More...
 
enum  MQTTPubAckType_t { MQTTPuback +, MQTTPubrec +, MQTTPubrel +, MQTTPubcomp + }
 Packet types used in acknowledging QoS 1 or QoS 2 publishes. More...
 
enum  MQTTSubAckStatus_t { MQTTSubAckSuccessQos0 = 0x00 +, MQTTSubAckSuccessQos1 = 0x01 +, MQTTSubAckSuccessQos2 = 0x02 +, MQTTSubAckFailure = 0x80 + }
 The status codes in the SUBACK response to a subscription request. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

MQTTStatus_t MQTT_Init (MQTTContext_t *pContext, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getTimeFunction, MQTTEventCallback_t userCallback, const MQTTFixedBuffer_t *pNetworkBuffer)
 Initialize an MQTT context.
 
MQTTStatus_t MQTT_InitStatefulQoS (MQTTContext_t *pContext, MQTTPubAckInfo_t *pOutgoingPublishRecords, size_t outgoingPublishCount, MQTTPubAckInfo_t *pIncomingPublishRecords, size_t incomingPublishCount)
 Initialize an MQTT context for QoS > 0.
 
MQTTStatus_t MQTT_Connect (MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
 Establish an MQTT session.
 
MQTTStatus_t MQTT_Subscribe (MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
 Sends MQTT SUBSCRIBE for the given list of topic filters to the broker.
 
MQTTStatus_t MQTT_Publish (MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId)
 Publishes a message to the given topic name.
 
MQTTStatus_t MQTT_CancelCallback (const MQTTContext_t *pContext, uint16_t packetId)
 Cancels an outgoing publish callback (only for QoS > QoS0) by removing it from the pending ACK list.
 
MQTTStatus_t MQTT_Ping (MQTTContext_t *pContext)
 Sends an MQTT PINGREQ to broker.
 
MQTTStatus_t MQTT_Unsubscribe (MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
 Sends MQTT UNSUBSCRIBE for the given list of topic filters to the broker.
 
MQTTStatus_t MQTT_Disconnect (MQTTContext_t *pContext)
 Disconnect an MQTT session.
 
MQTTStatus_t MQTT_ProcessLoop (MQTTContext_t *pContext)
 Loop to receive packets from the transport interface. Handles keep alive.
 
MQTTStatus_t MQTT_ReceiveLoop (MQTTContext_t *pContext)
 Loop to receive packets from the transport interface. Does not handle keep alive.
 
uint16_t MQTT_GetPacketId (MQTTContext_t *pContext)
 Get a packet ID that is valid according to the MQTT 3.1.1 spec.
 
MQTTStatus_t MQTT_MatchTopic (const char *pTopicName, const uint16_t topicNameLength, const char *pTopicFilter, const uint16_t topicFilterLength, bool *pIsMatch)
 A utility function that determines whether the passed topic filter and topic name match according to the MQTT 3.1.1 protocol specification.
 
MQTTStatus_t MQTT_GetSubAckStatusCodes (const MQTTPacketInfo_t *pSubackPacket, uint8_t **pPayloadStart, size_t *pPayloadSize)
 Parses the payload of an MQTT SUBACK packet that contains status codes corresponding to topic filter subscription requests from the original subscribe packet.
 
const char * MQTT_Status_strerror (MQTTStatus_t status)
 Error code to string conversion for MQTT statuses.
 
+

Detailed Description

+

User-facing functions of the MQTT 3.1.1 library.

+

Function Documentation

+ +

◆ MQTT_Init()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_Init (MQTTContext_tpContext,
const TransportInterface_tpTransportInterface,
MQTTGetCurrentTimeFunc_t getTimeFunction,
MQTTEventCallback_t userCallback,
const MQTTFixedBuffer_tpNetworkBuffer 
)
+
+ +

Initialize an MQTT context.

+

This function must be called on an MQTTContext_t before any other function.

+
Note
The MQTTGetCurrentTimeFunc_t function for querying time must be defined. If there is no time implementation, it is the responsibility of the application to provide a dummy function to always return 0, provide 0 timeouts for all calls to MQTT_Connect, MQTT_ProcessLoop, and MQTT_ReceiveLoop and configure the MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS configurations to be 0. This will result in loop functions running for a single iteration, and MQTT_Connect relying on MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT to receive the CONNACK packet.
+
Parameters
+ + + + + + +
[in]pContextThe context to initialize.
[in]pTransportInterfaceThe transport interface to use with the context.
[in]getTimeFunctionThe time utility function which can return the amount of time (in milliseconds) elapsed since a given epoch. This function will be used to ensure that timeouts in the API calls are met and keep-alive messages are sent on time.
[in]userCallbackThe user callback to use with the context to notify about incoming packet events.
[in]pNetworkBufferNetwork buffer provided for the context. This buffer will be used to receive incoming messages from the broker. This buffer must remain valid and in scope for the entire lifetime of the pContext and must not be used by another context and/or application.
+
+
+
Returns
MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Function for obtaining a timestamp.
+
uint32_t getTimeStampMs();
+
// Callback function for receiving packets.
+
void eventCallback(
+
MQTTContext_t * pContext,
+
MQTTPacketInfo_t * pPacketInfo,
+
MQTTDeserializedInfo_t * pDeserializedInfo
+
);
+
// Network send.
+
int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
+
// Network receive.
+
int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
+
+
MQTTContext_t mqttContext;
+ +
MQTTFixedBuffer_t fixedBuffer;
+
// Create a globally accessible buffer which remains in scope for the entire duration
+
// of the MQTT context.
+
uint8_t buffer[ 1024 ];
+
+
// Clear context.
+
memset( ( void * ) &mqttContext, 0x00, sizeof( MQTTContext_t ) );
+
+
// Set transport interface members.
+
transport.pNetworkContext = &someTransportContext;
+
transport.send = networkSend;
+
transport.recv = networkRecv;
+
+
// Set buffer members.
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = 1024;
+
+
status = MQTT_Init( &mqttContext, &transport, getTimeStampMs, eventCallback, &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// Do something with mqttContext. The transport and fixedBuffer structs were
+
// copied into the context, so the original structs do not need to stay in scope.
+
// However, the memory pointed to by the fixedBuffer.pBuffer must remain in scope.
+
}
+
MQTTStatus_t MQTT_Init(MQTTContext_t *pContext, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getTimeFunction, MQTTEventCallback_t userCallback, const MQTTFixedBuffer_t *pNetworkBuffer)
Initialize an MQTT context.
Definition: core_mqtt.c:2531
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
Struct to hold deserialized packet information for an MQTTEventCallback_t callback.
Definition: core_mqtt.h:257
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+
The transport layer interface.
Definition: transport_interface.h:299
+
TransportSend_t send
Definition: transport_interface.h:301
+
TransportRecv_t recv
Definition: transport_interface.h:300
+
NetworkContext_t * pNetworkContext
Definition: transport_interface.h:303
+
+
+
+ +

◆ MQTT_InitStatefulQoS()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_InitStatefulQoS (MQTTContext_tpContext,
MQTTPubAckInfo_tpOutgoingPublishRecords,
size_t outgoingPublishCount,
MQTTPubAckInfo_tpIncomingPublishRecords,
size_t incomingPublishCount 
)
+
+ +

Initialize an MQTT context for QoS > 0.

+

This function must be called on an MQTTContext_t after MQTT_Init and before any other function.

+
Parameters
+ + + + + + +
[in]pContextThe context to initialize.
[in]pOutgoingPublishRecordsPointer to memory which will be used to store state of outgoing publishes.
[in]outgoingPublishCountMaximum number of records which can be kept in the memory pointed to by pOutgoingPublishRecords.
[in]pIncomingPublishRecordsPointer to memory which will be used to store state of incoming publishes.
[in]incomingPublishCountMaximum number of records which can be kept in the memory pointed to by pIncomingPublishRecords.
+
+
+
Returns
MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Function for obtaining a timestamp.
+
uint32_t getTimeStampMs();
+
// Callback function for receiving packets.
+
void eventCallback(
+
MQTTContext_t * pContext,
+
MQTTPacketInfo_t * pPacketInfo,
+
MQTTDeserializedInfo_t * pDeserializedInfo
+
);
+
// Network send.
+
int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
+
// Network receive.
+
int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
+
+
MQTTContext_t mqttContext;
+ +
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ 1024 ];
+
const size_t outgoingPublishCount = 30;
+
MQTTPubAckInfo_t outgoingPublishes[ outgoingPublishCount ];
+
+
// Clear context.
+
memset( ( void * ) &mqttContext, 0x00, sizeof( MQTTContext_t ) );
+
+
// Set transport interface members.
+
transport.pNetworkContext = &someTransportContext;
+
transport.send = networkSend;
+
transport.recv = networkRecv;
+
+
// Set buffer members.
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = 1024;
+
+
status = MQTT_Init( &mqttContext, &transport, getTimeStampMs, eventCallback, &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// We do not expect any incoming publishes in this example, therefore the incoming
+
// publish pointer is NULL and the count is zero.
+
status = MQTT_InitStatefulQoS( &mqttContext, outgoingPublishes, outgoingPublishCount, NULL, 0 );
+
+
// Now QoS1 and/or QoS2 publishes can be sent with this context.
+
}
+
MQTTStatus_t MQTT_InitStatefulQoS(MQTTContext_t *pContext, MQTTPubAckInfo_t *pOutgoingPublishRecords, size_t outgoingPublishCount, MQTTPubAckInfo_t *pIncomingPublishRecords, size_t incomingPublishCount)
Initialize an MQTT context for QoS > 0.
Definition: core_mqtt.c:2590
+
An element of the state engine records for QoS 1 or Qos 2 publishes.
Definition: core_mqtt.h:162
+
+
+
+ +

◆ MQTT_Connect()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_Connect (MQTTContext_tpContext,
const MQTTConnectInfo_tpConnectInfo,
const MQTTPublishInfo_tpWillInfo,
uint32_t timeoutMs,
bool * pSessionPresent 
)
+
+ +

Establish an MQTT session.

+

This function will send MQTT CONNECT packet and receive a CONNACK packet. The send and receive from the network is done through the transport interface.

+

The maximum time this function waits for a CONNACK is decided in one of the following ways:

    +
  1. If timeoutMs is greater than 0: MQTTContext_t.getTime is used to ensure that the function does not wait more than timeoutMs for CONNACK.
  2. +
  3. If timeoutMs is 0: The network receive for CONNACK is retried up to the number of times configured by MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT.
  4. +
+
Note
If a dummy MQTTGetCurrentTimeFunc_t was passed to MQTT_Init, then a timeout value of 0 MUST be passed to the API, and the MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS timeout configurations MUST be set to 0.
+
Parameters
+ + + + + + +
[in]pContextInitialized MQTT context.
[in]pConnectInfoMQTT CONNECT packet information.
[in]pWillInfoLast Will and Testament. Pass NULL if Last Will and Testament is not used.
[in]timeoutMsMaximum time in milliseconds to wait for a CONNACK packet. A zero timeout makes use of the retries for receiving CONNACK as configured with MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT.
[out]pSessionPresentThis value will be set to true if a previous session was present; otherwise it will be set to false. It is only relevant if not establishing a clean session.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport send failed; MQTTRecvFailed if transport receive failed for CONNACK; MQTTNoDataAvailable if no data available to receive in transport until the timeoutMs for CONNACK; MQTTSuccess otherwise.
+
Note
This API may spend more time than provided in the timeoutMS parameters in certain conditions as listed below:
+
    +
  1. Timeouts are incorrectly configured - If the timeoutMS is less than the transport receive timeout and if a CONNACK packet is not received within the transport receive timeout, the API will spend the transport receive timeout (which is more time than the timeoutMs). It is the case of incorrect timeout configuration as the timeoutMs parameter passed to this API must be greater than the transport receive timeout. Please refer to the transport interface documentation for more details about timeout configurations.
  2. +
  3. Partial CONNACK packet is received right before the expiry of the timeout - It is possible that first two bytes of CONNACK packet (packet type and remaining length) are received right before the expiry of the timeoutMS. In that case, the API makes one more network receive call in an attempt to receive the remaining 2 bytes. In the worst case, it can happen that the remaining 2 bytes are never received and this API will end up spending timeoutMs + transport receive timeout.
  4. +
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
bool sessionPresent;
+
// This is assumed to have been initialized before calling this function.
+
MQTTContext_t * pContext;
+
+
// True for creating a new session with broker, false if we want to resume an old one.
+
connectInfo.cleanSession = true;
+
// Client ID must be unique to broker. This field is required.
+
connectInfo.pClientIdentifier = "someClientID";
+
connectInfo.clientIdentifierLength = strlen( connectInfo.pClientIdentifier );
+
+
// The following fields are optional.
+
// Value for keep alive.
+
connectInfo.keepAliveSeconds = 60;
+
// Optional username and password.
+
connectInfo.pUserName = "someUserName";
+
connectInfo.userNameLength = strlen( connectInfo.pUserName );
+
connectInfo.pPassword = "somePassword";
+
connectInfo.passwordLength = strlen( connectInfo.pPassword );
+
+
// The last will and testament is optional, it will be published by the broker
+
// should this client disconnect without sending a DISCONNECT packet.
+
willInfo.qos = MQTTQoS0;
+
willInfo.pTopicName = "/lwt/topic/name";
+
willInfo.topicNameLength = strlen( willInfo.pTopicName );
+
willInfo.pPayload = "LWT Message";
+
willInfo.payloadLength = strlen( "LWT Message" );
+
+
// Send the connect packet. Use 100 ms as the timeout to wait for the CONNACK packet.
+
status = MQTT_Connect( pContext, &connectInfo, &willInfo, 100, &sessionPresent );
+
+
if( status == MQTTSuccess )
+
{
+
// Since we requested a clean session, this must be false
+
assert( sessionPresent == false );
+
+
// Do something with the connection.
+
}
+
MQTTStatus_t MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
Establish an MQTT session.
Definition: core_mqtt.c:2679
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
@ MQTTQoS0
Definition: core_mqtt_serializer.h:110
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
const char * pClientIdentifier
MQTT client identifier. Must be unique per client.
Definition: core_mqtt_serializer.h:147
+
const char * pUserName
MQTT user name. Set to NULL if not used.
Definition: core_mqtt_serializer.h:157
+
bool cleanSession
Whether to establish a new, clean session or resume a previous session.
Definition: core_mqtt_serializer.h:137
+
uint16_t userNameLength
Length of MQTT user name. Set to 0 if not used.
Definition: core_mqtt_serializer.h:162
+
uint16_t keepAliveSeconds
MQTT keep alive period.
Definition: core_mqtt_serializer.h:142
+
uint16_t clientIdentifierLength
Length of the client identifier.
Definition: core_mqtt_serializer.h:152
+
uint16_t passwordLength
Length of MQTT password. Set to 0 if not used.
Definition: core_mqtt_serializer.h:172
+
const char * pPassword
MQTT password. Set to NULL if not used.
Definition: core_mqtt_serializer.h:167
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+
MQTTQoS_t qos
Quality of Service for message.
Definition: core_mqtt_serializer.h:206
+
uint16_t topicNameLength
Length of topic name.
Definition: core_mqtt_serializer.h:226
+
size_t payloadLength
Message payload length.
Definition: core_mqtt_serializer.h:236
+
const char * pTopicName
Topic name on which the message is published.
Definition: core_mqtt_serializer.h:221
+
const void * pPayload
Message payload.
Definition: core_mqtt_serializer.h:231
+
+
+
+ +

◆ MQTT_Subscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_Subscribe (MQTTContext_tpContext,
const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId 
)
+
+ +

Sends MQTT SUBSCRIBE for the given list of topic filters to the broker.

+
Parameters
+ + + + + +
[in]pContextInitialized MQTT context.
[in]pSubscriptionListArray of MQTT subscription info.
[in]subscriptionCountThe number of elements in @ pSubscriptionList array.
[in]packetIdPacket ID generated by MQTT_GetPacketId.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
uint16_t packetId;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
// This is assumed to be a list of filters we want to subscribe to.
+
const char * filters[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// Set each subscription.
+
for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )
+
{
+
subscriptionList[ i ].qos = MQTTQoS0;
+
// Each subscription needs a topic filter.
+
subscriptionList[ i ].pTopicFilter = filters[ i ];
+
subscriptionList[ i ].topicFilterLength = strlen( filters[ i ] );
+
}
+
+
// Obtain a new packet id for the subscription.
+
packetId = MQTT_GetPacketId( pContext );
+
+
status = MQTT_Subscribe( pContext, &subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// We must now call MQTT_ReceiveLoop() or MQTT_ProcessLoop() to receive the SUBACK.
+
// If the broker accepts the subscription we can now receive publishes
+
// on the requested topics.
+
}
+
uint16_t MQTT_GetPacketId(MQTTContext_t *pContext)
Get a packet ID that is valid according to the MQTT 3.1.1 spec.
Definition: core_mqtt.c:3172
+
MQTTStatus_t MQTT_Subscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
Sends MQTT SUBSCRIBE for the given list of topic filters to the broker.
Definition: core_mqtt.c:2761
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+
MQTTQoS_t qos
Quality of Service for subscription.
Definition: core_mqtt_serializer.h:184
+
uint16_t topicFilterLength
Length of subscription topic filter.
Definition: core_mqtt_serializer.h:194
+
const char * pTopicFilter
Topic filter to subscribe to.
Definition: core_mqtt_serializer.h:189
+
+
+
+ +

◆ MQTT_Publish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_Publish (MQTTContext_tpContext,
const MQTTPublishInfo_tpPublishInfo,
uint16_t packetId 
)
+
+ +

Publishes a message to the given topic name.

+
Parameters
+ + + + +
[in]pContextInitialized MQTT context.
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
+
+
+
Returns
MQTTNoMemory if pBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo;
+
uint16_t packetId;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
+
// QoS of publish.
+
publishInfo.qos = MQTTQoS1;
+
publishInfo.pTopicName = "/some/topic/name";
+
publishInfo.topicNameLength = strlen( publishInfo.pTopicName );
+
publishInfo.pPayload = "Hello World!";
+
publishInfo.payloadLength = strlen( "Hello World!" );
+
+
// Packet ID is needed for QoS > 0.
+
packetId = MQTT_GetPacketId( pContext );
+
+
status = MQTT_Publish( pContext, &publishInfo, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// Since the QoS is > 0, we will need to call MQTT_ReceiveLoop()
+
// or MQTT_ProcessLoop() to process the publish acknowledgments.
+
}
+
MQTTStatus_t MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId)
Publishes a message to the given topic name.
Definition: core_mqtt.c:2805
+
@ MQTTQoS1
Definition: core_mqtt_serializer.h:111
+
+
+
+ +

◆ MQTT_CancelCallback()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_CancelCallback (const MQTTContext_tpContext,
uint16_t packetId 
)
+
+ +

Cancels an outgoing publish callback (only for QoS > QoS0) by removing it from the pending ACK list.

+
Note
This cannot cancel the actual publish as that might have already been sent to the broker. This only removes the details of the given packet ID from the list of unACKed packet. That allows the caller to free any memory associated with the publish payload, topic string etc. Also, after this API call, the user provided callback will not be invoked when the ACK packet is received.
+
Parameters
+ + + +
[in]pContextInitialized MQTT context.
[in]packetIdpacket ID corresponding to the outstanding publish.
+
+
+
Returns
MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+ +
+
+ +

◆ MQTT_Ping()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_Ping (MQTTContext_tpContext)
+
+ +

Sends an MQTT PINGREQ to broker.

+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Returns
MQTTNoMemory if pBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+ +
+
+ +

◆ MQTT_Unsubscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_Unsubscribe (MQTTContext_tpContext,
const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId 
)
+
+ +

Sends MQTT UNSUBSCRIBE for the given list of topic filters to the broker.

+
Parameters
+ + + + + +
[in]pContextInitialized MQTT context.
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t unsubscribeList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
uint16_t packetId;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
// This is assumed to be a list of filters we want to unsubscribe from.
+
const char * filters[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// Set information for each unsubscribe request.
+
for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )
+
{
+
unsubscribeList[ i ].pTopicFilter = filters[ i ];
+
unsubscribeList[ i ].topicFilterLength = strlen( filters[ i ] );
+
+
// The QoS field of MQTT_SubscribeInfo_t is unused for unsubscribing.
+
}
+
+
// Obtain a new packet id for the unsubscribe request.
+
packetId = MQTT_GetPacketId( pContext );
+
+
status = MQTT_Unsubscribe( pContext, &unsubscribeList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// We must now call MQTT_ReceiveLoop() or MQTT_ProcessLoop() to receive the UNSUBACK.
+
// After this the broker should no longer send publishes for these topics.
+
}
+
MQTTStatus_t MQTT_Unsubscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
Sends MQTT UNSUBSCRIBE for the given list of topic filters to the broker.
Definition: core_mqtt.c:3000
+
+
+
+ +

◆ MQTT_Disconnect()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_Disconnect (MQTTContext_tpContext)
+
+ +

Disconnect an MQTT session.

+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport send failed; MQTTSuccess otherwise.
+ +
+
+ +

◆ MQTT_ProcessLoop()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_ProcessLoop (MQTTContext_tpContext)
+
+ +

Loop to receive packets from the transport interface. Handles keep alive.

+
Note
If a dummy timer function, MQTTGetCurrentTimeFunc_t, is passed to the library, then the keep-alive mechanism is not supported by the MQTT_ProcessLoop API. In that case, the MQTT_ReceiveLoop API function should be used instead.
+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Note
Calling this function blocks the calling context for a time period that depends on the passed the configuration macros, MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS, and the underlying transport interface implementation timeouts, unless an error occurs. The blocking period also depends on the execution time of the MQTTEventCallback_t callback supplied to the library. It is recommended that the supplied MQTTEventCallback_t callback does not contain blocking operations to prevent potential non-deterministic blocking period of the MQTT_ProcessLoop API call.
+
Returns
MQTTBadParameter if context is NULL; MQTTRecvFailed if a network error occurs during reception; MQTTSendFailed if a network error occurs while sending an ACK or PINGREQ; MQTTBadResponse if an invalid packet is received; MQTTKeepAliveTimeout if the server has not sent a PINGRESP before MQTT_PINGRESP_TIMEOUT_MS milliseconds; MQTTIllegalState if an incoming QoS 1/2 publish or ack causes an invalid transition for the internal state machine; MQTTNeedMoreBytes if MQTT_ProcessLoop has received incomplete data; it should be called again (probably after a delay); MQTTSuccess on success.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
+
while( true )
+
{
+
status = MQTT_ProcessLoop( pContext );
+
+
if( status != MQTTSuccess && status != MQTTNeedMoreBytes )
+
{
+
// Determine the error. It's possible we might need to disconnect
+
// the underlying transport connection.
+
}
+
else
+
{
+
// Other application functions.
+
}
+
}
+
MQTTStatus_t MQTT_ProcessLoop(MQTTContext_t *pContext)
Loop to receive packets from the transport interface. Handles keep alive.
Definition: core_mqtt.c:3119
+
@ MQTTNeedMoreBytes
Definition: core_mqtt_serializer.h:99
+
+
+
+ +

◆ MQTT_ReceiveLoop()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_ReceiveLoop (MQTTContext_tpContext)
+
+ +

Loop to receive packets from the transport interface. Does not handle keep alive.

+
Note
If a dummy MQTTGetCurrentTimeFunc_t was passed to MQTT_Init, then the MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS timeout configurations MUST be set to 0.
+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Note
Calling this function blocks the calling context for a time period that depends on the the configuration macros, MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS, and the underlying transport interface implementation timeouts, unless an error occurs. The blocking period also depends on the execution time of the MQTTEventCallback_t callback supplied to the library. It is recommended that the supplied MQTTEventCallback_t callback does not contain blocking operations to prevent potential non-deterministic blocking period of the MQTT_ReceiveLoop API call.
+
Returns
MQTTBadParameter if context is NULL; MQTTRecvFailed if a network error occurs during reception; MQTTSendFailed if a network error occurs while sending an ACK or PINGREQ; MQTTBadResponse if an invalid packet is received; MQTTIllegalState if an incoming QoS 1/2 publish or ack causes an invalid transition for the internal state machine; MQTTNeedMoreBytes if MQTT_ReceiveLoop has received incomplete data; it should be called again (probably after a delay); MQTTSuccess on success.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
uint32_t keepAliveMs = 60 * 1000;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
+
while( true )
+
{
+
status = MQTT_ReceiveLoop( pContext );
+
+
if( status != MQTTSuccess && status != MQTTNeedMoreBytes )
+
{
+
// Determine the error. It's possible we might need to disconnect
+
// the underlying transport connection.
+
}
+
else
+
{
+
// Since this function does not send pings, the application may need
+
// to in order to comply with keep alive.
+
if( ( pContext->getTime() - pContext->lastPacketTxTime ) > keepAliveMs )
+
{
+
status = MQTT_Ping( pContext );
+
}
+
+
// Other application functions.
+
}
+
}
+
MQTTStatus_t MQTT_Ping(MQTTContext_t *pContext)
Sends an MQTT PINGREQ to broker.
Definition: core_mqtt.c:2922
+
MQTTStatus_t MQTT_ReceiveLoop(MQTTContext_t *pContext)
Loop to receive packets from the transport interface. Does not handle keep alive.
Definition: core_mqtt.c:3146
+
uint32_t lastPacketTxTime
Timestamp of the last packet sent by the library.
Definition: core_mqtt.h:227
+
MQTTGetCurrentTimeFunc_t getTime
Function used to get millisecond timestamps.
Definition: core_mqtt.h:217
+
+
+
+ +

◆ MQTT_GetPacketId()

+ +
+
+ + + + + + + + +
uint16_t MQTT_GetPacketId (MQTTContext_tpContext)
+
+ +

Get a packet ID that is valid according to the MQTT 3.1.1 spec.

+
Parameters
+ + +
[in]pContextInitialized MQTT context.
+
+
+
Returns
A non-zero number.
+ +
+
+ +

◆ MQTT_MatchTopic()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_MatchTopic (const char * pTopicName,
const uint16_t topicNameLength,
const char * pTopicFilter,
const uint16_t topicFilterLength,
bool * pIsMatch 
)
+
+ +

A utility function that determines whether the passed topic filter and topic name match according to the MQTT 3.1.1 protocol specification.

+
Parameters
+ + + + + + +
[in]pTopicNameThe topic name to check.
[in]topicNameLengthLength of the topic name.
[in]pTopicFilterThe topic filter to check.
[in]topicFilterLengthLength of topic filter.
[out]pIsMatchIf the match is performed without any error, that is if the return value is MQTTSuccess, then and only then the value in this parameter is valid and updated. In such a case, if the topic filter and the topic name match, then this value is set to true; otherwise if there is no match then it is set to false.
+
+
+
Note
The API assumes that the passed topic name is valid to meet the requirements of the MQTT 3.1.1 specification. Invalid topic names (for example, containing wildcard characters) should not be passed to the function. Also, the API checks validity of topic filter for wildcard characters ONLY if the passed topic name and topic filter do not have an exact string match.
+
Returns
Returns one of the following: +
+

Example

// Variables used in this example.
+
const char * pTopic = "topic/match/1";
+
const char * pFilter = "topic/#";
+ +
bool match = false;
+
+
status = MQTT_MatchTopic( pTopic, strlen( pTopic ), pFilter, strlen( pFilter ), &match );
+
// Our parameters were valid, so this will return success.
+
assert( status == MQTTSuccess );
+
+
// For this specific example, we already know this value is true. This
+
// check is placed here as an example for use with variable topic names.
+
if( match )
+
{
+
// Application can decide what to do with the matching topic name.
+
}
+
MQTTStatus_t MQTT_MatchTopic(const char *pTopicName, const uint16_t topicNameLength, const char *pTopicFilter, const uint16_t topicFilterLength, bool *pIsMatch)
A utility function that determines whether the passed topic filter and topic name match according to ...
Definition: core_mqtt.c:3201
+
+
+
+ +

◆ MQTT_GetSubAckStatusCodes()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetSubAckStatusCodes (const MQTTPacketInfo_tpSubackPacket,
uint8_t ** pPayloadStart,
size_t * pPayloadSize 
)
+
+ +

Parses the payload of an MQTT SUBACK packet that contains status codes corresponding to topic filter subscription requests from the original subscribe packet.

+

Each return code in the SUBACK packet corresponds to a topic filter in the SUBSCRIBE Packet being acknowledged. The status codes can be one of the following:

    +
  • 0x00 - Success - Maximum QoS 0
  • +
  • 0x01 - Success - Maximum QoS 1
  • +
  • 0x02 - Success - Maximum QoS 2
  • +
  • 0x80 - Failure Refer to MQTTSubAckStatus_t for the status codes.
  • +
+
Parameters
+ + + + +
[in]pSubackPacketThe SUBACK packet whose payload is to be parsed.
[out]pPayloadStartThis is populated with the starting address of the payload (or return codes for topic filters) in the SUBACK packet.
[out]pPayloadSizeThis is populated with the size of the payload in the SUBACK packet. It represents the number of topic filters whose SUBACK status is present in the packet.
+
+
+
Returns
Returns one of the following: +
+

Example

// Global variable used in this example.
+
// This is assumed to be the subscription list in the original SUBSCRIBE packet.
+
MQTTSubscribeInfo_t pSubscribes[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// MQTT_GetSubAckStatusCodes is intended to be used from the application
+
// callback that is called by the library in MQTT_ProcessLoop or MQTT_ReceiveLoop.
+
void eventCallback(
+
MQTTContext_t * pContext,
+
MQTTPacketInfo_t * pPacketInfo,
+
MQTTDeserializedInfo_t * pDeserializedInfo
+
)
+
{
+ +
uint8_t * pCodes;
+
size_t numCodes;
+
+
if( pPacketInfo->type == MQTT_PACKET_TYPE_SUBACK )
+
{
+
status = MQTT_GetSubAckStatusCodes( pPacketInfo, &pCodes, &numCodes );
+
+
// Since the pointers to the payload and payload size are not NULL, and
+
// we use the packet info struct passed to the app callback (verified
+
// to be valid by the library), this function must return success.
+
assert( status == MQTTSuccess );
+
// The server must send a response code for each topic filter in the
+
// original SUBSCRIBE packet.
+
assert( numCodes == NUMBER_OF_SUBSCRIPTIONS );
+
+
for( int i = 0; i < numCodes; i++ )
+
{
+
// The only failure code is 0x80 = MQTTSubAckFailure.
+
if( pCodes[ i ] == MQTTSubAckFailure )
+
{
+
// The subscription failed, we may want to retry the
+
// subscription in pSubscribes[ i ] outside of this callback.
+
}
+
else
+
{
+
// The subscription was granted, but the maximum QoS may be
+
// lower than what was requested. We can verify the granted QoS.
+
if( pSubscribes[ i ].qos != pCodes[ i ] )
+
{
+ +
"Requested QoS %u, but granted QoS %u for %s",
+
pSubscribes[ i ].qos, pCodes[ i ], pSubscribes[ i ].pTopicFilter
+
) );
+
}
+
}
+
}
+
}
+
// Handle other packet types.
+
}
+
MQTTStatus_t MQTT_GetSubAckStatusCodes(const MQTTPacketInfo_t *pSubackPacket, uint8_t **pPayloadStart, size_t *pPayloadSize)
Parses the payload of an MQTT SUBACK packet that contains status codes corresponding to topic filter ...
Definition: core_mqtt.c:3270
+
#define LogWarn(message)
Macro that is called in the MQTT library for logging "Warning" level messages.
Definition: core_mqtt_config_defaults.h:235
+
#define MQTT_PACKET_TYPE_SUBACK
SUBACK (server-to-client).
Definition: core_mqtt_serializer.h:61
+
@ MQTTSubAckFailure
Failure.
Definition: core_mqtt.h:154
+
uint8_t type
Type of incoming MQTT packet.
Definition: core_mqtt_serializer.h:248
+
+
+
+ +

◆ MQTT_Status_strerror()

+ +
+
+ + + + + + + + +
const char * MQTT_Status_strerror (MQTTStatus_t status)
+
+ +

Error code to string conversion for MQTT statuses.

+
Parameters
+ + +
[in]statusThe status to convert to a string.
+
+
+
Returns
The string representation of the status.
+ +
+
+
+
+ + + + diff --git a/latest/coreMQTT/core__mqtt_8h_source.html b/latest/coreMQTT/core__mqtt_8h_source.html new file mode 100644 index 00000000..f8e91ae3 --- /dev/null +++ b/latest/coreMQTT/core__mqtt_8h_source.html @@ -0,0 +1,423 @@ + + + + + + + +coreMQTT: core_mqtt.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
core_mqtt.h
+
+
+Go to the documentation of this file.
1/*
+
2 * coreMQTT v2.3.1
+
3 * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
4 *
+
5 * SPDX-License-Identifier: MIT
+
6 *
+
7 * Permission is hereby granted, free of charge, to any person obtaining a copy of
+
8 * this software and associated documentation files (the "Software"), to deal in
+
9 * the Software without restriction, including without limitation the rights to
+
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
11 * the Software, and to permit persons to whom the Software is furnished to do so,
+
12 * subject to the following conditions:
+
13 *
+
14 * The above copyright notice and this permission notice shall be included in all
+
15 * copies or substantial portions of the Software.
+
16 *
+
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
23 */
+
24
+
29#ifndef CORE_MQTT_H
+
30#define CORE_MQTT_H
+
31
+
32/* *INDENT-OFF* */
+
33#ifdef __cplusplus
+
34 extern "C" {
+
35#endif
+
36/* *INDENT-ON* */
+
37
+
38/* Include MQTT serializer library. */
+ +
40
+
41/* Include transport interface. */
+
42#include "transport_interface.h"
+
43
+
51#define MQTT_LIBRARY_VERSION "v2.3.1"
+
60#define MQTT_PACKET_ID_INVALID ( ( uint16_t ) 0U )
+
61
+
62/* Structures defined in this file. */
+
63struct MQTTPubAckInfo;
+
64struct MQTTContext;
+
65struct MQTTDeserializedInfo;
+
66
+
85typedef uint32_t (* MQTTGetCurrentTimeFunc_t )( void );
+
86
+
100typedef void (* MQTTEventCallback_t )( struct MQTTContext * pContext,
+
101 struct MQTTPacketInfo * pPacketInfo,
+
102 struct MQTTDeserializedInfo * pDeserializedInfo );
+
103
+
108typedef enum MQTTConnectionStatus
+
109{
+ + + +
113
+
118typedef enum MQTTPublishState
+
119{
+ + + + + + + + + + + + +
132
+
137typedef enum MQTTPubAckType
+
138{
+ + + + + +
144
+
149typedef enum MQTTSubAckStatus
+
150{
+ + + +
154 MQTTSubAckFailure = 0x80
+ +
156
+
161typedef struct MQTTPubAckInfo
+
162{
+
163 uint16_t packetId;
+ + + +
167
+
172typedef struct MQTTContext
+
173{
+ +
178
+ +
183
+ +
188
+ +
193
+ +
198
+ +
203
+
207 uint16_t nextPacketId;
+
208
+ +
213
+ +
218
+ +
223
+ +
228
+ +
233
+ +
239
+
243 size_t index;
+
244
+
245 /* Keep alive members. */
+ + + + +
250
+
256typedef struct MQTTDeserializedInfo
+
257{
+ + + + +
262
+
336/* @[declare_mqtt_init] */
+ +
338 const TransportInterface_t * pTransportInterface,
+
339 MQTTGetCurrentTimeFunc_t getTimeFunction,
+
340 MQTTEventCallback_t userCallback,
+
341 const MQTTFixedBuffer_t * pNetworkBuffer );
+
342/* @[declare_mqtt_init] */
+
343
+
409/* @[declare_mqtt_initstatefulqos] */
+ +
411 MQTTPubAckInfo_t * pOutgoingPublishRecords,
+
412 size_t outgoingPublishCount,
+
413 MQTTPubAckInfo_t * pIncomingPublishRecords,
+
414 size_t incomingPublishCount );
+
415/* @[declare_mqtt_initstatefulqos] */
+
416
+
520/* @[declare_mqtt_connect] */
+ +
522 const MQTTConnectInfo_t * pConnectInfo,
+
523 const MQTTPublishInfo_t * pWillInfo,
+
524 uint32_t timeoutMs,
+
525 bool * pSessionPresent );
+
526/* @[declare_mqtt_connect] */
+
527
+
578/* @[declare_mqtt_subscribe] */
+ +
580 const MQTTSubscribeInfo_t * pSubscriptionList,
+
581 size_t subscriptionCount,
+
582 uint16_t packetId );
+
583/* @[declare_mqtt_subscribe] */
+
584
+
626/* @[declare_mqtt_publish] */
+ +
628 const MQTTPublishInfo_t * pPublishInfo,
+
629 uint16_t packetId );
+
630/* @[declare_mqtt_publish] */
+
631
+
649/* @[declare_mqtt_cancelcallback] */
+ +
651 uint16_t packetId );
+
652/* @[declare_mqtt_cancelcallback] */
+
653
+
664/* @[declare_mqtt_ping] */
+ +
666/* @[declare_mqtt_ping] */
+
667
+
716/* @[declare_mqtt_unsubscribe] */
+ +
718 const MQTTSubscribeInfo_t * pSubscriptionList,
+
719 size_t subscriptionCount,
+
720 uint16_t packetId );
+
721/* @[declare_mqtt_unsubscribe] */
+
722
+
734/* @[declare_mqtt_disconnect] */
+ +
736/* @[declare_mqtt_disconnect] */
+
737
+
792/* @[declare_mqtt_processloop] */
+ +
794/* @[declare_mqtt_processloop] */
+
795
+
856/* @[declare_mqtt_receiveloop] */
+ +
858/* @[declare_mqtt_receiveloop] */
+
859
+
867/* @[declare_mqtt_getpacketid] */
+
868uint16_t MQTT_GetPacketId( MQTTContext_t * pContext );
+
869/* @[declare_mqtt_getpacketid] */
+
870
+
915MQTTStatus_t MQTT_MatchTopic( const char * pTopicName,
+
916 const uint16_t topicNameLength,
+
917 const char * pTopicFilter,
+
918 const uint16_t topicFilterLength,
+
919 bool * pIsMatch );
+
920
+
1003/* @[declare_mqtt_getsubackstatuscodes] */
+ +
1005 uint8_t ** pPayloadStart,
+
1006 size_t * pPayloadSize );
+
1007/* @[declare_mqtt_getsubackstatuscodes] */
+
1008
+
1016/* @[declare_mqtt_status_strerror] */
+
1017const char * MQTT_Status_strerror( MQTTStatus_t status );
+
1018/* @[declare_mqtt_status_strerror] */
+
1019
+
1020/* *INDENT-OFF* */
+
1021#ifdef __cplusplus
+
1022 }
+
1023#endif
+
1024/* *INDENT-ON* */
+
1025
+
1026#endif /* ifndef CORE_MQTT_H */
+
uint16_t MQTT_GetPacketId(MQTTContext_t *pContext)
Get a packet ID that is valid according to the MQTT 3.1.1 spec.
Definition: core_mqtt.c:3172
+
const char * MQTT_Status_strerror(MQTTStatus_t status)
Error code to string conversion for MQTT statuses.
Definition: core_mqtt.c:3329
+
MQTTStatus_t MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId)
Publishes a message to the given topic name.
Definition: core_mqtt.c:2805
+
MQTTStatus_t MQTT_CancelCallback(const MQTTContext_t *pContext, uint16_t packetId)
Cancels an outgoing publish callback (only for QoS > QoS0) by removing it from the pending ACK list.
Definition: core_mqtt.c:2647
+
MQTTStatus_t MQTT_Subscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
Sends MQTT SUBSCRIBE for the given list of topic filters to the broker.
Definition: core_mqtt.c:2761
+
MQTTStatus_t MQTT_MatchTopic(const char *pTopicName, const uint16_t topicNameLength, const char *pTopicFilter, const uint16_t topicFilterLength, bool *pIsMatch)
A utility function that determines whether the passed topic filter and topic name match according to ...
Definition: core_mqtt.c:3201
+
MQTTStatus_t MQTT_Ping(MQTTContext_t *pContext)
Sends an MQTT PINGREQ to broker.
Definition: core_mqtt.c:2922
+
MQTTStatus_t MQTT_Unsubscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
Sends MQTT UNSUBSCRIBE for the given list of topic filters to the broker.
Definition: core_mqtt.c:3000
+
MQTTStatus_t MQTT_ProcessLoop(MQTTContext_t *pContext)
Loop to receive packets from the transport interface. Handles keep alive.
Definition: core_mqtt.c:3119
+
MQTTStatus_t MQTT_GetSubAckStatusCodes(const MQTTPacketInfo_t *pSubackPacket, uint8_t **pPayloadStart, size_t *pPayloadSize)
Parses the payload of an MQTT SUBACK packet that contains status codes corresponding to topic filter ...
Definition: core_mqtt.c:3270
+
MQTTStatus_t MQTT_Disconnect(MQTTContext_t *pContext)
Disconnect an MQTT session.
Definition: core_mqtt.c:3045
+
MQTTStatus_t MQTT_Init(MQTTContext_t *pContext, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getTimeFunction, MQTTEventCallback_t userCallback, const MQTTFixedBuffer_t *pNetworkBuffer)
Initialize an MQTT context.
Definition: core_mqtt.c:2531
+
MQTTStatus_t MQTT_ReceiveLoop(MQTTContext_t *pContext)
Loop to receive packets from the transport interface. Does not handle keep alive.
Definition: core_mqtt.c:3146
+
MQTTStatus_t MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
Establish an MQTT session.
Definition: core_mqtt.c:2679
+
MQTTStatus_t MQTT_InitStatefulQoS(MQTTContext_t *pContext, MQTTPubAckInfo_t *pOutgoingPublishRecords, size_t outgoingPublishCount, MQTTPubAckInfo_t *pIncomingPublishRecords, size_t incomingPublishCount)
Initialize an MQTT context for QoS > 0.
Definition: core_mqtt.c:2590
+
User-facing functions for serializing and deserializing MQTT 3.1.1 packets. This header should be inc...
+
void(* MQTTEventCallback_t)(struct MQTTContext *pContext, struct MQTTPacketInfo *pPacketInfo, struct MQTTDeserializedInfo *pDeserializedInfo)
Application callback for receiving incoming publishes and incoming acks.
Definition: core_mqtt.h:100
+
uint32_t(* MQTTGetCurrentTimeFunc_t)(void)
Application provided function to query the time elapsed since a given epoch in milliseconds.
Definition: core_mqtt.h:85
+
MQTTPublishState_t
The state of QoS 1 or QoS 2 MQTT publishes, used in the state engine.
Definition: core_mqtt.h:119
+
MQTTSubAckStatus_t
The status codes in the SUBACK response to a subscription request.
Definition: core_mqtt.h:150
+
MQTTPubAckType_t
Packet types used in acknowledging QoS 1 or QoS 2 publishes.
Definition: core_mqtt.h:138
+
MQTTConnectionStatus_t
Values indicating if an MQTT connection exists.
Definition: core_mqtt.h:109
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTTQoS_t
MQTT Quality of Service values.
Definition: core_mqtt_serializer.h:109
+
@ MQTTPubRecSend
The library will send a PUBREC for a received PUBLISH.
Definition: core_mqtt.h:123
+
@ MQTTPubRecPending
The library is awaiting a PUBREC for an outgoing PUBLISH.
Definition: core_mqtt.h:127
+
@ MQTTPubCompPending
The library is awaiting a PUBCOMP for an outgoing PUBLISH.
Definition: core_mqtt.h:129
+
@ MQTTPubRelSend
The library will send a PUBREL for a received PUBREC.
Definition: core_mqtt.h:124
+
@ MQTTPubAckSend
The library will send a PUBACK for a received PUBLISH.
Definition: core_mqtt.h:122
+
@ MQTTPubRelPending
The library is awaiting a PUBREL for an incoming PUBLISH.
Definition: core_mqtt.h:128
+
@ MQTTPubCompSend
The library will send a PUBCOMP for a received PUBREL.
Definition: core_mqtt.h:125
+
@ MQTTStateNull
An empty state with no corresponding PUBLISH.
Definition: core_mqtt.h:120
+
@ MQTTPublishSend
The library will send an outgoing PUBLISH packet.
Definition: core_mqtt.h:121
+
@ MQTTPubAckPending
The library is awaiting a PUBACK for an outgoing PUBLISH.
Definition: core_mqtt.h:126
+
@ MQTTPublishDone
The PUBLISH has been completed.
Definition: core_mqtt.h:130
+
@ MQTTSubAckSuccessQos2
Success with a maximum delivery at QoS 2.
Definition: core_mqtt.h:153
+
@ MQTTSubAckSuccessQos1
Success with a maximum delivery at QoS 1.
Definition: core_mqtt.h:152
+
@ MQTTSubAckSuccessQos0
Success with a maximum delivery at QoS 0.
Definition: core_mqtt.h:151
+
@ MQTTSubAckFailure
Failure.
Definition: core_mqtt.h:154
+
@ MQTTPuback
PUBACKs are sent in response to a QoS 1 PUBLISH.
Definition: core_mqtt.h:139
+
@ MQTTPubrec
PUBRECs are sent in response to a QoS 2 PUBLISH.
Definition: core_mqtt.h:140
+
@ MQTTPubcomp
PUBCOMPs are sent in response to a PUBREL.
Definition: core_mqtt.h:142
+
@ MQTTPubrel
PUBRELs are sent in response to a PUBREC.
Definition: core_mqtt.h:141
+
@ MQTTNotConnected
MQTT Connection is inactive.
Definition: core_mqtt.h:110
+
@ MQTTConnected
MQTT Connection is active.
Definition: core_mqtt.h:111
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
uint32_t lastPacketTxTime
Timestamp of the last packet sent by the library.
Definition: core_mqtt.h:227
+
MQTTFixedBuffer_t networkBuffer
The buffer used in sending and receiving packets from the network.
Definition: core_mqtt.h:202
+
size_t outgoingPublishRecordMaxCount
The maximum number of outgoing publish records.
Definition: core_mqtt.h:187
+
size_t index
Index to keep track of the number of bytes received in network buffer.
Definition: core_mqtt.h:243
+
MQTTConnectionStatus_t connectStatus
Whether the context currently has a connection to the broker.
Definition: core_mqtt.h:212
+
MQTTPubAckInfo_t * outgoingPublishRecords
State engine records for outgoing publishes.
Definition: core_mqtt.h:177
+
uint32_t lastPacketRxTime
Timestamp of the last packet received by the library.
Definition: core_mqtt.h:232
+
MQTTEventCallback_t appCallback
Callback function used to give deserialized MQTT packets to the application.
Definition: core_mqtt.h:222
+
TransportInterface_t transportInterface
The transport interface used by the MQTT connection.
Definition: core_mqtt.h:197
+
size_t incomingPublishRecordMaxCount
The maximum number of incoming publish records.
Definition: core_mqtt.h:192
+
MQTTGetCurrentTimeFunc_t getTime
Function used to get millisecond timestamps.
Definition: core_mqtt.h:217
+
bool waitingForPingResp
If the library is currently awaiting a PINGRESP.
Definition: core_mqtt.h:248
+
uint32_t pingReqSendTimeMs
Timestamp of the last sent PINGREQ.
Definition: core_mqtt.h:247
+
uint16_t nextPacketId
The next available ID for outgoing MQTT packets.
Definition: core_mqtt.h:207
+
bool controlPacketSent
Whether the library sent a packet during a call of MQTT_ProcessLoop or MQTT_ReceiveLoop.
Definition: core_mqtt.h:238
+
MQTTPubAckInfo_t * incomingPublishRecords
State engine records for incoming publishes.
Definition: core_mqtt.h:182
+
uint16_t keepAliveIntervalSec
Keep Alive interval.
Definition: core_mqtt.h:246
+
Struct to hold deserialized packet information for an MQTTEventCallback_t callback.
Definition: core_mqtt.h:257
+
MQTTStatus_t deserializationResult
Return code of deserialization.
Definition: core_mqtt.h:260
+
MQTTPublishInfo_t * pPublishInfo
Pointer to deserialized publish info.
Definition: core_mqtt.h:259
+
uint16_t packetIdentifier
Packet ID of deserialized packet.
Definition: core_mqtt.h:258
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+
An element of the state engine records for QoS 1 or Qos 2 publishes.
Definition: core_mqtt.h:162
+
MQTTQoS_t qos
The QoS of the original PUBLISH.
Definition: core_mqtt.h:164
+
MQTTPublishState_t publishState
The current state of the publish process.
Definition: core_mqtt.h:165
+
uint16_t packetId
The packet ID of the original PUBLISH.
Definition: core_mqtt.h:163
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+
The transport layer interface.
Definition: transport_interface.h:299
+
Transport interface definitions to send and receive data over the network.
+
+
+ + + + diff --git a/latest/coreMQTT/core__mqtt__config__defaults_8h.html b/latest/coreMQTT/core__mqtt__config__defaults_8h.html new file mode 100644 index 00000000..2d920853 --- /dev/null +++ b/latest/coreMQTT/core__mqtt__config__defaults_8h.html @@ -0,0 +1,396 @@ + + + + + + + +coreMQTT: core_mqtt_config_defaults.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_config_defaults.h File Reference
+
+
+ +

This represents the default values for the configuration macros for the MQTT library. +More...

+
#include "core_mqtt_config.h"
+
+

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Macros

#define MQTT_DO_NOT_USE_CUSTOM_CONFIG
 Define this macro to build the MQTT library without the custom config file core_mqtt_config.h.
 
+#define MQTT_SUB_UNSUB_MAX_VECTORS   ( 4U )
 Maximum number of vectors in subscribe and unsubscribe packet.
 
#define MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT   ( 5U )
 The number of retries for receiving CONNACK.
 
#define MQTT_PINGRESP_TIMEOUT_MS   ( 5000U )
 Maximum number of milliseconds to wait for a ping response to a ping request as part of the keep-alive mechanism.
 
#define PACKET_TX_TIMEOUT_MS   ( 30000U )
 Maximum number of milliseconds of TX inactivity to wait before initiating a PINGREQ.
 
#define PACKET_RX_TIMEOUT_MS   ( 30000U )
 Maximum number of milliseconds of RX inactivity to wait before initiating a PINGREQ.
 
#define MQTT_RECV_POLLING_TIMEOUT_MS   ( 10U )
 The maximum duration between non-empty network reads while receiving an MQTT packet via the MQTT_ProcessLoop or MQTT_ReceiveLoop API functions.
 
#define MQTT_SEND_TIMEOUT_MS   ( 20000U )
 The maximum duration allowed to send an MQTT packet over the transport interface.
 
#define LogError(message)
 Macro that is called in the MQTT library for logging "Error" level messages.
 
#define LogWarn(message)
 Macro that is called in the MQTT library for logging "Warning" level messages.
 
#define LogInfo(message)
 Macro that is called in the MQTT library for logging "Info" level messages.
 
#define LogDebug(message)
 Macro that is called in the MQTT library for logging "Debug" level messages.
 
+

Detailed Description

+

This represents the default values for the configuration macros for the MQTT library.

+
Note
This file SHOULD NOT be modified. If custom values are needed for any configuration macro, a core_mqtt_config.h file should be provided to the MQTT library to override the default values defined in this file. To use the custom config file, the MQTT_DO_NOT_USE_CUSTOM_CONFIG preprocessor macro SHOULD NOT be set.
+

Macro Definition Documentation

+ +

◆ MQTT_DO_NOT_USE_CUSTOM_CONFIG

+ +
+
+ + + + +
#define MQTT_DO_NOT_USE_CUSTOM_CONFIG
+
+ +

Define this macro to build the MQTT library without the custom config file core_mqtt_config.h.

+

Without the custom config, the MQTT library builds with default values of config macros defined in core_mqtt_config_defaults.h file.

+

If a custom config is provided, then MQTT_DO_NOT_USE_CUSTOM_CONFIG should not be defined.

+ +
+
+ +

◆ MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT

+ +
+
+ + + + +
#define MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT   ( 5U )
+
+ +

The number of retries for receiving CONNACK.

+

The MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT will be used only when the timeoutMs parameter of MQTT_Connect is passed as 0 . The transport receive for CONNACK will be retried MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT times before timing out. A value of 0 for this config will cause the transport receive for CONNACK to be invoked only once.

+

Possible values: Any positive 16 bit integer.
+ Default value: 5

+ +
+
+ +

◆ MQTT_PINGRESP_TIMEOUT_MS

+ +
+
+ + + + +
#define MQTT_PINGRESP_TIMEOUT_MS   ( 5000U )
+
+ +

Maximum number of milliseconds to wait for a ping response to a ping request as part of the keep-alive mechanism.

+

If a ping response is not received before this timeout, then MQTT_ProcessLoop will return MQTTKeepAliveTimeout.

+
Note
If this value is more than half of the keep alive interval, and the server does not receive the previous ping request, then it is likely that the server will disconnect the client before MQTTKeepAliveTimeout can be returned.
+
+If a dummy implementation of the MQTTGetCurrentTimeFunc_t timer function, is supplied to the library, then the keep-alive mechanism is not supported by the MQTT_ProcessLoop API function. In that case, the value of MQTT_PINGRESP_TIMEOUT_MS is irrelevant to the behavior of the library.
+

Possible values: Any positive integer up to SIZE_MAX.
+ Default value: 5000

+ +
+
+ +

◆ PACKET_TX_TIMEOUT_MS

+ +
+
+ + + + +
#define PACKET_TX_TIMEOUT_MS   ( 30000U )
+
+ +

Maximum number of milliseconds of TX inactivity to wait before initiating a PINGREQ.

+
Note
If this value is less than the keep alive interval than it will be used instead.
+

Possible values: Any positive integer up to SIZE_MAX.
+ Default value: '30000'

+ +
+
+ +

◆ PACKET_RX_TIMEOUT_MS

+ +
+
+ + + + +
#define PACKET_RX_TIMEOUT_MS   ( 30000U )
+
+ +

Maximum number of milliseconds of RX inactivity to wait before initiating a PINGREQ.

+

Possible values: Any positive integer up to SIZE_MAX.
+ Default value: '30000'

+ +
+
+ +

◆ MQTT_RECV_POLLING_TIMEOUT_MS

+ +
+
+ + + + +
#define MQTT_RECV_POLLING_TIMEOUT_MS   ( 10U )
+
+ +

The maximum duration between non-empty network reads while receiving an MQTT packet via the MQTT_ProcessLoop or MQTT_ReceiveLoop API functions.

+

When an incoming MQTT packet is detected, the transport receive function may be called multiple times until all of the expected number of bytes of the packet are received. This timeout represents the maximum polling duration that is allowed without any data reception from the network for the incoming packet.

+

If the timeout expires, the MQTT_ProcessLoop and MQTT_ReceiveLoop functions return MQTTRecvFailed.

+
Note
If a dummy implementation of the MQTTGetCurrentTimeFunc_t timer function, is supplied to the library, then MQTT_RECV_POLLING_TIMEOUT_MS MUST be set to 0.
+

Possible values: Any positive 32 bit integer. Recommended to use a small timeout value.
+ Default value: 10

+ +
+
+ +

◆ MQTT_SEND_TIMEOUT_MS

+ +
+
+ + + + +
#define MQTT_SEND_TIMEOUT_MS   ( 20000U )
+
+ +

The maximum duration allowed to send an MQTT packet over the transport interface.

+

When sending an MQTT packet, the transport send or writev functions may be called multiple times until all of the required number of bytes are sent. This timeout represents the maximum duration that is allowed to send the MQTT packet while calling the transport send or writev functions.

+

If the timeout expires, MQTTSendFailed will be returned by the public API functions.

+
Note
If a dummy implementation of the MQTTGetCurrentTimeFunc_t timer function, is supplied to the library, then MQTT_SEND_TIMEOUT_MS MUST be set to 0.
+

Possible values: Any positive 32 bit integer.
+ Default value: 20000

+ +
+
+ +

◆ LogError

+ +
+
+ + + + + + + + +
#define LogError( message)
+
+ +

Macro that is called in the MQTT library for logging "Error" level messages.

+

To enable error level logging in the MQTT library, this macro should be mapped to the application-specific logging implementation that supports error logging.

+
Note
This logging macro is called in the MQTT library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Error logging is turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+ +
+
+ +

◆ LogWarn

+ +
+
+ + + + + + + + +
#define LogWarn( message)
+
+ +

Macro that is called in the MQTT library for logging "Warning" level messages.

+

To enable warning level logging in the MQTT library, this macro should be mapped to the application-specific logging implementation that supports warning logging.

+
Note
This logging macro is called in the MQTT library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Warning logs are turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+ +
+
+ +

◆ LogInfo

+ +
+
+ + + + + + + + +
#define LogInfo( message)
+
+ +

Macro that is called in the MQTT library for logging "Info" level messages.

+

To enable info level logging in the MQTT library, this macro should be mapped to the application-specific logging implementation that supports info logging.

+
Note
This logging macro is called in the MQTT library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Info logging is turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+ +
+
+ +

◆ LogDebug

+ +
+
+ + + + + + + + +
#define LogDebug( message)
+
+ +

Macro that is called in the MQTT library for logging "Debug" level messages.

+

To enable debug level logging from MQTT library, this macro should be mapped to the application-specific logging implementation that supports debug logging.

+
Note
This logging macro is called in the MQTT library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Debug logging is turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+ +
+
+
+
+ + + + diff --git a/latest/coreMQTT/core__mqtt__config__defaults_8h_source.html b/latest/coreMQTT/core__mqtt__config__defaults_8h_source.html new file mode 100644 index 00000000..87ca718c --- /dev/null +++ b/latest/coreMQTT/core__mqtt__config__defaults_8h_source.html @@ -0,0 +1,218 @@ + + + + + + + +coreMQTT: core_mqtt_config_defaults.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
core_mqtt_config_defaults.h
+
+
+Go to the documentation of this file.
1/*
+
2 * coreMQTT v2.3.1
+
3 * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
4 *
+
5 * SPDX-License-Identifier: MIT
+
6 *
+
7 * Permission is hereby granted, free of charge, to any person obtaining a copy of
+
8 * this software and associated documentation files (the "Software"), to deal in
+
9 * the Software without restriction, including without limitation the rights to
+
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
11 * the Software, and to permit persons to whom the Software is furnished to do so,
+
12 * subject to the following conditions:
+
13 *
+
14 * The above copyright notice and this permission notice shall be included in all
+
15 * copies or substantial portions of the Software.
+
16 *
+
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
23 */
+
24
+
37#ifndef CORE_MQTT_CONFIG_DEFAULTS_H_
+
38#define CORE_MQTT_CONFIG_DEFAULTS_H_
+
39
+
40/* *INDENT-OFF* */
+
41#ifdef __cplusplus
+
42 extern "C" {
+
43#endif
+
44/* *INDENT-ON* */
+
45
+
46/* MQTT_DO_NOT_USE_CUSTOM_CONFIG allows building the MQTT library
+
47 * without a custom config. If a custom config is provided, the
+
48 * MQTT_DO_NOT_USE_CUSTOM_CONFIG macro should not be defined. */
+
49#ifndef MQTT_DO_NOT_USE_CUSTOM_CONFIG
+
50/* Include custom config file before other headers. */
+
51 #include "core_mqtt_config.h"
+
52#endif
+
53
+
54/* The macro definition for MQTT_DO_NOT_USE_CUSTOM_CONFIG is for Doxygen
+
55 * documentation only. */
+
56
+
67#ifdef DOXYGEN
+
68 #define MQTT_DO_NOT_USE_CUSTOM_CONFIG
+
69#endif
+
70
+
75#ifndef MQTT_SUB_UNSUB_MAX_VECTORS
+
76 #define MQTT_SUB_UNSUB_MAX_VECTORS ( 4U )
+
77#endif
+
78
+
91#ifndef MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT
+
92/* Default value for the CONNACK receive retries. */
+
93 #define MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT ( 5U )
+
94#endif
+
95
+
115#ifndef MQTT_PINGRESP_TIMEOUT_MS
+
116/* Wait 5 seconds by default for a ping response. */
+
117 #define MQTT_PINGRESP_TIMEOUT_MS ( 5000U )
+
118#endif
+
119
+
130#ifndef PACKET_TX_TIMEOUT_MS
+
131 #define PACKET_TX_TIMEOUT_MS ( 30000U )
+
132#endif
+
133
+
142#ifndef PACKET_RX_TIMEOUT_MS
+
143 #define PACKET_RX_TIMEOUT_MS ( 30000U )
+
144#endif
+
145
+
167#ifndef MQTT_RECV_POLLING_TIMEOUT_MS
+
168 #define MQTT_RECV_POLLING_TIMEOUT_MS ( 10U )
+
169#endif
+
170
+
190#ifndef MQTT_SEND_TIMEOUT_MS
+
191 #define MQTT_SEND_TIMEOUT_MS ( 20000U )
+
192#endif
+
193
+
194#ifdef MQTT_SEND_RETRY_TIMEOUT_MS
+
195 #error MQTT_SEND_RETRY_TIMEOUT_MS is deprecated. Instead use MQTT_SEND_TIMEOUT_MS.
+
196#endif
+
197
+
214#ifndef LogError
+
215 #define LogError( message )
+
216#endif
+
217
+
234#ifndef LogWarn
+
235 #define LogWarn( message )
+
236#endif
+
237
+
254#ifndef LogInfo
+
255 #define LogInfo( message )
+
256#endif
+
257
+
274#ifndef LogDebug
+
275 #define LogDebug( message )
+
276#endif
+
277
+
278/* *INDENT-OFF* */
+
279#ifdef __cplusplus
+
280 }
+
281#endif
+
282/* *INDENT-ON* */
+
283
+
284#endif /* ifndef CORE_MQTT_CONFIG_DEFAULTS_H_ */
+
+
+ + + + diff --git a/latest/coreMQTT/core__mqtt__serializer_8c.html b/latest/coreMQTT/core__mqtt__serializer_8c.html new file mode 100644 index 00000000..127482a9 --- /dev/null +++ b/latest/coreMQTT/core__mqtt__serializer_8c.html @@ -0,0 +1,3003 @@ + + + + + + + +coreMQTT: core_mqtt_serializer.c File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_serializer.c File Reference
+
+
+ +

Implements the user-facing functions in core_mqtt_serializer.h. +More...

+
#include <string.h>
+#include <assert.h>
+#include "core_mqtt_serializer.h"
+#include "core_mqtt_config_defaults.h"
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Macros

+#define MQTT_VERSION_3_1_1   ( ( uint8_t ) 4U )
 MQTT protocol version 3.1.1.
 
+#define MQTT_PACKET_CONNECT_HEADER_SIZE   ( 10UL )
 Size of the fixed and variable header of a CONNECT packet.
 
+#define MQTT_CONNECT_FLAG_CLEAN   ( 1 )
 Clean session.
 
+#define MQTT_CONNECT_FLAG_WILL   ( 2 )
 Will present.
 
+#define MQTT_CONNECT_FLAG_WILL_QOS1   ( 3 )
 Will QoS 1.
 
+#define MQTT_CONNECT_FLAG_WILL_QOS2   ( 4 )
 Will QoS 2.
 
+#define MQTT_CONNECT_FLAG_WILL_RETAIN   ( 5 )
 Will retain.
 
+#define MQTT_CONNECT_FLAG_PASSWORD   ( 6 )
 Password present.
 
+#define MQTT_CONNECT_FLAG_USERNAME   ( 7 )
 User name present.
 
+#define MQTT_PUBLISH_FLAG_RETAIN   ( 0 )
 MQTT PUBLISH retain flag.
 
+#define MQTT_PUBLISH_FLAG_QOS1   ( 1 )
 MQTT PUBLISH QoS1 flag.
 
+#define MQTT_PUBLISH_FLAG_QOS2   ( 2 )
 MQTT PUBLISH QoS2 flag.
 
+#define MQTT_PUBLISH_FLAG_DUP   ( 3 )
 MQTT PUBLISH duplicate flag.
 
+#define MQTT_DISCONNECT_PACKET_SIZE   ( 2UL )
 The size of MQTT DISCONNECT packets, per MQTT spec.
 
+#define MQTT_PACKET_PINGREQ_SIZE   ( 2UL )
 A PINGREQ packet is always 2 bytes in size, defined by MQTT 3.1.1 spec.
 
+#define MQTT_DISCONNECT_REMAINING_LENGTH   ( ( uint8_t ) 0 )
 The Remaining Length field of MQTT disconnect packets, per MQTT spec.
 
+#define MQTT_PACKET_CONNACK_REMAINING_LENGTH   ( ( uint8_t ) 2U )
 A CONNACK packet always has a "Remaining length" of 2.
 
+#define MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK   ( ( uint8_t ) 0x01U )
 The "Session Present" bit is always the lowest bit.
 
+#define MQTT_PACKET_SIMPLE_ACK_REMAINING_LENGTH   ( ( uint8_t ) 2 )
 PUBACK, PUBREC, PUBREl, PUBCOMP, UNSUBACK Remaining length.
 
+#define MQTT_PACKET_PINGRESP_REMAINING_LENGTH   ( 0U )
 A PINGRESP packet always has a "Remaining length" of 0.
 
+#define MQTT_MAX_REMAINING_LENGTH   ( 268435455UL )
 Per the MQTT 3.1.1 spec, the largest "Remaining Length" of an MQTT packet is this value, 256 MB.
 
+#define UINT8_SET_BIT(x, position)   ( ( x ) = ( uint8_t ) ( ( x ) | ( 0x01U << ( position ) ) ) )
 Set a bit in an 8-bit unsigned integer.
 
#define UINT8_CHECK_BIT(x, position)   ( ( ( x ) & ( 0x01U << ( position ) ) ) == ( 0x01U << ( position ) ) )
 Macro for checking if a bit is set in a 1-byte unsigned int.
 
+#define UINT16_HIGH_BYTE(x)   ( ( uint8_t ) ( ( x ) >> 8 ) )
 Get the high byte of a 16-bit unsigned integer.
 
+#define UINT16_LOW_BYTE(x)   ( ( uint8_t ) ( ( x ) & 0x00ffU ) )
 Get the low byte of a 16-bit unsigned integer.
 
#define UINT16_DECODE(ptr)
 Macro for decoding a 2-byte unsigned int from a sequence of bytes.
 
#define MQTT_REMAINING_LENGTH_INVALID   ( ( size_t ) 268435456 )
 A value that represents an invalid remaining length.
 
#define MQTT_MIN_PUBLISH_REMAINING_LENGTH_QOS0   ( 3U )
 The minimum remaining length for a QoS 0 PUBLISH.
 
+ + + + +

+Enumerations

enum  MQTTSubscriptionType_t { MQTT_SUBSCRIBE +, MQTT_UNSUBSCRIBE + }
 MQTT Subscription packet types. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

static void serializePublishCommon (const MQTTPublishInfo_t *pPublishInfo, size_t remainingLength, uint16_t packetIdentifier, const MQTTFixedBuffer_t *pFixedBuffer, bool serializePayload)
 Serializes MQTT PUBLISH packet into the buffer provided.
 
static bool calculatePublishPacketSize (const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize)
 Calculates the packet size and remaining length of an MQTT PUBLISH packet.
 
static MQTTStatus_t calculateSubscriptionPacketSize (const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize, MQTTSubscriptionType_t subscriptionType)
 Calculates the packet size and remaining length of an MQTT SUBSCRIBE or UNSUBSCRIBE packet.
 
static MQTTStatus_t validateSubscriptionSerializeParams (const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
 Validates parameters of MQTT_SerializeSubscribe or MQTT_SerializeUnsubscribe.
 
static void serializeConnectPacket (const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT CONNECT packet in the given buffer.
 
static void logConnackResponse (uint8_t responseCode)
 Prints the appropriate message for the CONNACK response code if logs are enabled.
 
static uint8_t * encodeRemainingLength (uint8_t *pDestination, size_t length)
 Encodes the remaining length of the packet using the variable length encoding scheme provided in the MQTT v3.1.1 specification.
 
static size_t remainingLengthEncodedSize (size_t length)
 Retrieve the size of the remaining length if it were to be encoded.
 
static uint8_t * encodeString (uint8_t *pDestination, const char *pSource, uint16_t sourceLength)
 Encode a string whose size is at maximum 16 bits in length.
 
static size_t getRemainingLength (TransportRecv_t recvFunc, NetworkContext_t *pNetworkContext)
 Retrieves and decodes the Remaining Length from the network interface by reading a single byte at a time.
 
static MQTTStatus_t processRemainingLength (const uint8_t *pBuffer, const size_t *pIndex, MQTTPacketInfo_t *pIncomingPacket)
 Retrieves, decodes and stores the Remaining Length from the network interface by reading a single byte at a time.
 
static bool incomingPacketValid (uint8_t packetType)
 Check if an incoming packet type is valid.
 
static MQTTStatus_t checkPublishRemainingLength (size_t remainingLength, MQTTQoS_t qos, size_t qos0Minimum)
 Check the remaining length of an incoming PUBLISH packet against some value for QoS 0, or for QoS 1 and 2.
 
static MQTTStatus_t processPublishFlags (uint8_t publishFlags, MQTTPublishInfo_t *pPublishInfo)
 Process the flags of an incoming PUBLISH packet.
 
static MQTTStatus_t deserializeConnack (const MQTTPacketInfo_t *pConnack, bool *pSessionPresent)
 Deserialize a CONNACK packet.
 
static MQTTStatus_t readSubackStatus (size_t statusCount, const uint8_t *pStatusStart)
 Decode the status bytes of a SUBACK packet to a MQTTStatus_t.
 
static MQTTStatus_t deserializeSuback (const MQTTPacketInfo_t *pSuback, uint16_t *pPacketIdentifier)
 Deserialize a SUBACK packet.
 
static MQTTStatus_t deserializePublish (const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo)
 Deserialize a PUBLISH packet received from the server.
 
static MQTTStatus_t deserializeSimpleAck (const MQTTPacketInfo_t *pAck, uint16_t *pPacketIdentifier)
 Deserialize an UNSUBACK, PUBACK, PUBREC, PUBREL, or PUBCOMP packet.
 
static MQTTStatus_t deserializePingresp (const MQTTPacketInfo_t *pPingresp)
 Deserialize a PINGRESP packet.
 
MQTTStatus_t MQTT_SerializePublishHeaderWithoutTopic (const MQTTPublishInfo_t *pPublishInfo, size_t remainingLength, uint8_t *pBuffer, size_t *headerSize)
 Serialize an MQTT PUBLISH packet header without the topic string in the given buffer. This function will add the topic string length to the provided buffer. This helps reduce an unnecessary copy of the topic string into the buffer.
 
uint8_t * MQTT_SerializeConnectFixedHeader (uint8_t *pIndex, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength)
 Serialize the fixed part of the connect packet header.
 
MQTTStatus_t MQTT_GetConnectPacketSize (const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize)
 Get the size and Remaining Length of an MQTT CONNECT packet.
 
MQTTStatus_t MQTT_SerializeConnect (const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT CONNECT packet in the given fixed buffer pFixedBuffer.
 
MQTTStatus_t MQTT_GetSubscribePacketSize (const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
 Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.
 
uint8_t * MQTT_SerializeSubscribeHeader (size_t remainingLength, uint8_t *pIndex, uint16_t packetId)
 Serialize the fixed part of the subscribe packet header.
 
uint8_t * MQTT_SerializeUnsubscribeHeader (size_t remainingLength, uint8_t *pIndex, uint16_t packetId)
 Serialize the fixed part of the unsubscribe packet header.
 
MQTTStatus_t MQTT_SerializeSubscribe (const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT SUBSCRIBE packet in the given buffer.
 
MQTTStatus_t MQTT_GetUnsubscribePacketSize (const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
 Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.
 
MQTTStatus_t MQTT_SerializeUnsubscribe (const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT UNSUBSCRIBE packet in the given buffer.
 
MQTTStatus_t MQTT_GetPublishPacketSize (const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize)
 Get the packet size and remaining length of an MQTT PUBLISH packet.
 
MQTTStatus_t MQTT_SerializePublish (const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT PUBLISH packet in the given buffer.
 
MQTTStatus_t MQTT_SerializePublishHeader (const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer, size_t *pHeaderSize)
 Serialize an MQTT PUBLISH packet header in the given buffer.
 
MQTTStatus_t MQTT_SerializeAck (const MQTTFixedBuffer_t *pFixedBuffer, uint8_t packetType, uint16_t packetId)
 Serialize an MQTT PUBACK, PUBREC, PUBREL, or PUBCOMP into the given buffer.
 
MQTTStatus_t MQTT_GetDisconnectPacketSize (size_t *pPacketSize)
 Get the size of an MQTT DISCONNECT packet.
 
MQTTStatus_t MQTT_SerializeDisconnect (const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT DISCONNECT packet into the given buffer.
 
MQTTStatus_t MQTT_GetPingreqPacketSize (size_t *pPacketSize)
 Get the size of an MQTT PINGREQ packet.
 
MQTTStatus_t MQTT_SerializePingreq (const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT PINGREQ packet into the given buffer.
 
MQTTStatus_t MQTT_DeserializePublish (const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo)
 Deserialize an MQTT PUBLISH packet.
 
MQTTStatus_t MQTT_DeserializeAck (const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, bool *pSessionPresent)
 Deserialize an MQTT CONNACK, SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, PUBCOMP, or PINGRESP.
 
MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength (TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket)
 Extract the MQTT packet type and length from incoming packet.
 
MQTTStatus_t MQTT_ProcessIncomingPacketTypeAndLength (const uint8_t *pBuffer, const size_t *pIndex, MQTTPacketInfo_t *pIncomingPacket)
 Extract the MQTT packet type and length from incoming packet.
 
+

Detailed Description

+

Implements the user-facing functions in core_mqtt_serializer.h.

+

Macro Definition Documentation

+ +

◆ UINT8_CHECK_BIT

+ +
+
+ + + + + + + + + + + + + + + + + + +
#define UINT8_CHECK_BIT( x,
 position 
)   ( ( ( x ) & ( 0x01U << ( position ) ) ) == ( 0x01U << ( position ) ) )
+
+ +

Macro for checking if a bit is set in a 1-byte unsigned int.

+
Parameters
+ + + +
[in]xThe unsigned int to check.
[in]positionWhich bit to check.
+
+
+ +
+
+ +

◆ UINT16_DECODE

+ +
+
+ + + + + + + + +
#define UINT16_DECODE( ptr)
+
+Value:
( uint16_t ) ( ( ( ( uint16_t ) ptr[ 0 ] ) << 8 ) | \
+
( ( uint16_t ) ptr[ 1 ] ) )
+
+

Macro for decoding a 2-byte unsigned int from a sequence of bytes.

+
Parameters
+ + +
[in]ptrA uint8_t* that points to the high byte.
+
+
+ +
+
+ +

◆ MQTT_REMAINING_LENGTH_INVALID

+ +
+
+ + + + +
#define MQTT_REMAINING_LENGTH_INVALID   ( ( size_t ) 268435456 )
+
+ +

A value that represents an invalid remaining length.

+

This value is greater than what is allowed by the MQTT specification.

+ +
+
+ +

◆ MQTT_MIN_PUBLISH_REMAINING_LENGTH_QOS0

+ +
+
+ + + + +
#define MQTT_MIN_PUBLISH_REMAINING_LENGTH_QOS0   ( 3U )
+
+ +

The minimum remaining length for a QoS 0 PUBLISH.

+

Includes two bytes for topic name length and one byte for topic name.

+ +
+
+

Enumeration Type Documentation

+ +

◆ MQTTSubscriptionType_t

+ +
+
+ + + + +
enum MQTTSubscriptionType_t
+
+ +

MQTT Subscription packet types.

+ + + +
Enumerator
MQTT_SUBSCRIBE 

The type is a SUBSCRIBE packet.

+
MQTT_UNSUBSCRIBE 

The type is a UNSUBSCRIBE packet.

+
+ +
+
+

Function Documentation

+ +

◆ serializePublishCommon()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static void serializePublishCommon (const MQTTPublishInfo_tpPublishInfo,
size_t remainingLength,
uint16_t packetIdentifier,
const MQTTFixedBuffer_tpFixedBuffer,
bool serializePayload 
)
+
+static
+
+ +

Serializes MQTT PUBLISH packet into the buffer provided.

+

This function serializes MQTT PUBLISH packet into MQTTFixedBuffer_t.pBuffer. Copy of the payload into the buffer is done as part of the serialization only if serializePayload is true.

+

param[in] pPublishInfo Publish information.

+

param[in] remainingLength Remaining length of the PUBLISH packet.

+

param[in] packetIdentifier Packet identifier of PUBLISH packet.

+

param[in, out] pFixedBuffer Buffer to which PUBLISH packet will be serialized.

+

param[in] serializePayload Copy payload to the serialized buffer only if true. Only PUBLISH header will be serialized if false.

+ +
+
+ +

◆ calculatePublishPacketSize()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static bool calculatePublishPacketSize (const MQTTPublishInfo_tpPublishInfo,
size_t * pRemainingLength,
size_t * pPacketSize 
)
+
+static
+
+ +

Calculates the packet size and remaining length of an MQTT PUBLISH packet.

+
Parameters
+ + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[out]pRemainingLengthThe Remaining Length of the MQTT PUBLISH packet.
[out]pPacketSizeThe total size of the MQTT PUBLISH packet.
+
+
+
Returns
false if the packet would exceed the size allowed by the MQTT spec; true otherwise.
+ +
+
+ +

◆ calculateSubscriptionPacketSize()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t calculateSubscriptionPacketSize (const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
size_t * pRemainingLength,
size_t * pPacketSize,
MQTTSubscriptionType_t subscriptionType 
)
+
+static
+
+ +

Calculates the packet size and remaining length of an MQTT SUBSCRIBE or UNSUBSCRIBE packet.

+
Parameters
+ + + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[out]pRemainingLengthThe Remaining Length of the MQTT SUBSCRIBE or UNSUBSCRIBE packet.
[out]pPacketSizeThe total size of the MQTT MQTT SUBSCRIBE or UNSUBSCRIBE packet.
[in]subscriptionTypeMQTT_SUBSCRIBE or MQTT_UNSUBSCRIBE.
+
+
+

MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec or a subscription is empty; MQTTSuccess otherwise.

+ +
+
+ +

◆ validateSubscriptionSerializeParams()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t validateSubscriptionSerializeParams (const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer 
)
+
+static
+
+ +

Validates parameters of MQTT_SerializeSubscribe or MQTT_SerializeUnsubscribe.

+
Parameters
+ + + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdPacket identifier.
[in]remainingLengthRemaining length of the packet.
[in]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+ +
+
+ +

◆ serializeConnectPacket()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static void serializeConnectPacket (const MQTTConnectInfo_tpConnectInfo,
const MQTTPublishInfo_tpWillInfo,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer 
)
+
+static
+
+ +

Serialize an MQTT CONNECT packet in the given buffer.

+
Parameters
+ + + + + +
[in]pConnectInfoMQTT CONNECT packet parameters.
[in]pWillInfoLast Will and Testament. Pass NULL if not used.
[in]remainingLengthRemaining Length of MQTT CONNECT packet.
[out]pFixedBufferBuffer for packet serialization.
+
+
+ +
+
+ +

◆ logConnackResponse()

+ +
+
+ + + + + +
+ + + + + + + + +
static void logConnackResponse (uint8_t responseCode)
+
+static
+
+ +

Prints the appropriate message for the CONNACK response code if logs are enabled.

+
Parameters
+ + +
[in]responseCodeMQTT standard CONNACK response code.
+
+
+ +
+
+ +

◆ encodeRemainingLength()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static uint8_t * encodeRemainingLength (uint8_t * pDestination,
size_t length 
)
+
+static
+
+ +

Encodes the remaining length of the packet using the variable length encoding scheme provided in the MQTT v3.1.1 specification.

+
Parameters
+ + + +
[out]pDestinationThe destination buffer to store the encoded remaining length.
[in]lengthThe remaining length to encode.
+
+
+
Returns
The location of the byte following the encoded value.
+ +
+
+ +

◆ remainingLengthEncodedSize()

+ +
+
+ + + + + +
+ + + + + + + + +
static size_t remainingLengthEncodedSize (size_t length)
+
+static
+
+ +

Retrieve the size of the remaining length if it were to be encoded.

+
Parameters
+ + +
[in]lengthThe remaining length to be encoded.
+
+
+
Returns
The size of the remaining length if it were to be encoded.
+ +
+
+ +

◆ encodeString()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static uint8_t * encodeString (uint8_t * pDestination,
const char * pSource,
uint16_t sourceLength 
)
+
+static
+
+ +

Encode a string whose size is at maximum 16 bits in length.

+
Parameters
+ + + + +
[out]pDestinationDestination buffer for the encoding.
[in]pSourceThe source string to encode.
[in]sourceLengthThe length of the source string to encode.
+
+
+
Returns
A pointer to the end of the encoded string.
+ +
+
+ +

◆ getRemainingLength()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static size_t getRemainingLength (TransportRecv_t recvFunc,
NetworkContext_tpNetworkContext 
)
+
+static
+
+ +

Retrieves and decodes the Remaining Length from the network interface by reading a single byte at a time.

+
Parameters
+ + + +
[in]recvFuncNetwork interface receive function.
[in]pNetworkContextNetwork interface context to the receive function.
+
+
+
Returns
The Remaining Length of the incoming packet.
+ +
+
+ +

◆ processRemainingLength()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t processRemainingLength (const uint8_t * pBuffer,
const size_t * pIndex,
MQTTPacketInfo_tpIncomingPacket 
)
+
+static
+
+ +

Retrieves, decodes and stores the Remaining Length from the network interface by reading a single byte at a time.

+
Parameters
+ + + + +
[in]pBufferThe buffer holding the raw data to be processed
[in]pIndexPointer to the index within the buffer to marking the end of raw data available.
[in]pIncomingPacketStructure used to hold the fields of the incoming packet.
+
+
+
Returns
MQTTNeedMoreBytes is returned to show that the incoming packet is not yet fully received and decoded. Otherwise, MQTTSuccess shows that processing of the packet was successful.
+ +
+
+ +

◆ incomingPacketValid()

+ +
+
+ + + + + +
+ + + + + + + + +
static bool incomingPacketValid (uint8_t packetType)
+
+static
+
+ +

Check if an incoming packet type is valid.

+
Parameters
+ + +
[in]packetTypeThe packet type to check.
+
+
+
Returns
true if the packet type is valid; false otherwise.
+ +
+
+ +

◆ checkPublishRemainingLength()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t checkPublishRemainingLength (size_t remainingLength,
MQTTQoS_t qos,
size_t qos0Minimum 
)
+
+static
+
+ +

Check the remaining length of an incoming PUBLISH packet against some value for QoS 0, or for QoS 1 and 2.

+

The remaining length for a QoS 1 and 2 packet will always be two greater than for a QoS 0.

+
Parameters
+ + + + +
[in]remainingLengthRemaining length of the PUBLISH packet.
[in]qosThe QoS of the PUBLISH.
[in]qos0MinimumMinimum possible remaining length for a QoS 0 PUBLISH.
+
+
+
Returns
MQTTSuccess or MQTTBadResponse.
+ +
+
+ +

◆ processPublishFlags()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTStatus_t processPublishFlags (uint8_t publishFlags,
MQTTPublishInfo_tpPublishInfo 
)
+
+static
+
+ +

Process the flags of an incoming PUBLISH packet.

+
Parameters
+ + + +
[in]publishFlagsFlags of an incoming PUBLISH.
[in,out]pPublishInfoPointer to MQTTPublishInfo_t struct where output will be written.
+
+
+
Returns
MQTTSuccess or MQTTBadResponse.
+ +
+
+ +

◆ deserializeConnack()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTStatus_t deserializeConnack (const MQTTPacketInfo_tpConnack,
bool * pSessionPresent 
)
+
+static
+
+ +

Deserialize a CONNACK packet.

+

Converts the packet from a stream of bytes to an MQTTStatus_t.

+
Parameters
+ + + +
[in]pConnackPointer to an MQTT packet struct representing a CONNACK.
[out]pSessionPresentWhether a previous session was present.
+
+
+
Returns
MQTTSuccess if CONNACK specifies that CONNECT was accepted; MQTTServerRefused if CONNACK specifies that CONNECT was rejected; MQTTBadResponse if the CONNACK packet doesn't follow MQTT spec.
+ +
+
+ +

◆ readSubackStatus()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTStatus_t readSubackStatus (size_t statusCount,
const uint8_t * pStatusStart 
)
+
+static
+
+ +

Decode the status bytes of a SUBACK packet to a MQTTStatus_t.

+
Parameters
+ + + +
[in]statusCountNumber of status bytes in the SUBACK.
[in]pStatusStartThe first status byte in the SUBACK.
+
+
+
Returns
MQTTSuccess, MQTTServerRefused, or MQTTBadResponse.
+ +
+
+ +

◆ deserializeSuback()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTStatus_t deserializeSuback (const MQTTPacketInfo_tpSuback,
uint16_t * pPacketIdentifier 
)
+
+static
+
+ +

Deserialize a SUBACK packet.

+

Converts the packet from a stream of bytes to an MQTTStatus_t and extracts the packet identifier.

+
Parameters
+ + + +
[in]pSubackPointer to an MQTT packet struct representing a SUBACK.
[out]pPacketIdentifierPacket ID of the SUBACK.
+
+
+
Returns
MQTTSuccess if SUBACK is valid; MQTTBadResponse if SUBACK packet doesn't follow the MQTT spec.
+ +
+
+ +

◆ deserializePublish()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t deserializePublish (const MQTTPacketInfo_tpIncomingPacket,
uint16_t * pPacketId,
MQTTPublishInfo_tpPublishInfo 
)
+
+static
+
+ +

Deserialize a PUBLISH packet received from the server.

+

Converts the packet from a stream of bytes to an MQTTPublishInfo_t and extracts the packet identifier. Also prints out debug log messages about the packet.

+
Parameters
+ + + + +
[in]pIncomingPacketPointer to an MQTT packet struct representing a PUBLISH.
[out]pPacketIdPacket identifier of the PUBLISH.
[out]pPublishInfoPointer to MQTTPublishInfo_t where output is written.
+
+
+
Returns
MQTTSuccess if PUBLISH is valid; MQTTBadResponse if the PUBLISH packet doesn't follow MQTT spec.
+ +
+
+ +

◆ deserializeSimpleAck()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTStatus_t deserializeSimpleAck (const MQTTPacketInfo_tpAck,
uint16_t * pPacketIdentifier 
)
+
+static
+
+ +

Deserialize an UNSUBACK, PUBACK, PUBREC, PUBREL, or PUBCOMP packet.

+

Converts the packet from a stream of bytes to an MQTTStatus_t and extracts the packet identifier.

+
Parameters
+ + + +
[in]pAckPointer to the MQTT packet structure representing the packet.
[out]pPacketIdentifierPacket ID of the ack type packet.
+
+
+
Returns
MQTTSuccess if UNSUBACK, PUBACK, PUBREC, PUBREL, or PUBCOMP is valid; MQTTBadResponse if the packet doesn't follow the MQTT spec.
+ +
+
+ +

◆ deserializePingresp()

+ +
+
+ + + + + +
+ + + + + + + + +
static MQTTStatus_t deserializePingresp (const MQTTPacketInfo_tpPingresp)
+
+static
+
+ +

Deserialize a PINGRESP packet.

+

Converts the packet from a stream of bytes to an MQTTStatus_t.

+
Parameters
+ + +
[in]pPingrespPointer to an MQTT packet struct representing a PINGRESP.
+
+
+
Returns
MQTTSuccess if PINGRESP is valid; MQTTBadResponse if the PINGRESP packet doesn't follow MQTT spec.
+ +
+
+ +

◆ MQTT_SerializePublishHeaderWithoutTopic()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializePublishHeaderWithoutTopic (const MQTTPublishInfo_tpPublishInfo,
size_t remainingLength,
uint8_t * pBuffer,
size_t * headerSize 
)
+
+ +

Serialize an MQTT PUBLISH packet header without the topic string in the given buffer. This function will add the topic string length to the provided buffer. This helps reduce an unnecessary copy of the topic string into the buffer.

+
Parameters
+ + + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]remainingLengthRemaining Length provided by MQTT_GetPublishPacketSize.
[out]pBufferBuffer for packet serialization.
[out]headerSizeSize of the serialized MQTT PUBLISH header.
+
+
+
Returns
MQTTSuccess if the serialization is successful. Otherwise, MQTTBadParameter.
+ +
+
+ +

◆ MQTT_SerializeConnectFixedHeader()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint8_t * MQTT_SerializeConnectFixedHeader (uint8_t * pIndex,
const MQTTConnectInfo_tpConnectInfo,
const MQTTPublishInfo_tpWillInfo,
size_t remainingLength 
)
+
+ +

Serialize the fixed part of the connect packet header.

+
Parameters
+ + + + + +
[out]pIndexPointer to the buffer where the header is to be serialized.
[in]pConnectInfoThe connect information.
[in]pWillInfoThe last will and testament information.
[in]remainingLengthThe remaining length of the packet to be serialized.
+
+
+
Returns
A pointer to the end of the encoded string.
+ +
+
+ +

◆ MQTT_GetConnectPacketSize()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetConnectPacketSize (const MQTTConnectInfo_tpConnectInfo,
const MQTTPublishInfo_tpWillInfo,
size_t * pRemainingLength,
size_t * pPacketSize 
)
+
+ +

Get the size and Remaining Length of an MQTT CONNECT packet.

+

This function must be called before MQTT_SerializeConnect in order to get the size of the MQTT CONNECT packet that is generated from MQTTConnectInfo_t and optional MQTTPublishInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializeConnect must be at least pPacketSize. The provided pConnectInfo and pWillInfo are valid for serialization with MQTT_SerializeConnect only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + + +
[in]pConnectInfoMQTT CONNECT packet parameters.
[in]pWillInfoLast Will and Testament. Pass NULL if not used.
[out]pRemainingLengthThe Remaining Length of the MQTT CONNECT packet.
[out]pPacketSizeThe total size of the MQTT CONNECT packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
+
// Initialize the connection info, the details are out of scope for this example.
+
initializeConnectInfo( &connectInfo );
+
+
// Initialize the optional will info, the details are out of scope for this example.
+
initializeWillInfo( &willInfo );
+
+
// Get the size requirement for the connect packet.
+ +
&connectInfo, &willInfo, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the connect request.
+
}
+
MQTTStatus_t MQTT_GetConnectPacketSize(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the size and Remaining Length of an MQTT CONNECT packet.
Definition: core_mqtt_serializer.c:1690
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+
+
+
+ +

◆ MQTT_SerializeConnect()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializeConnect (const MQTTConnectInfo_tpConnectInfo,
const MQTTPublishInfo_tpWillInfo,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer 
)
+
+ +

Serialize an MQTT CONNECT packet in the given fixed buffer pFixedBuffer.

+

MQTT_GetConnectPacketSize should be called with pConnectInfo and pWillInfo before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetConnectPacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetConnectPacketSize.

+
Parameters
+ + + + + +
[in]pConnectInfoMQTT CONNECT packet parameters.
[in]pWillInfoLast Will and Testament. Pass NULL if not used.
[in]remainingLengthRemaining Length provided by MQTT_GetConnectPacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Assume connectInfo and willInfo are initialized. Get the size requirement for
+
// the connect packet.
+ +
&connectInfo, &willInfo, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the connect packet into the fixed buffer.
+
status = MQTT_SerializeConnect( &connectInfo, &willInfo, remainingLength, &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// The connect packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializeConnect(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT CONNECT packet in the given fixed buffer pFixedBuffer.
Definition: core_mqtt_serializer.c:1790
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
+
+
+ +

◆ MQTT_GetSubscribePacketSize()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetSubscribePacketSize (const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
size_t * pRemainingLength,
size_t * pPacketSize 
)
+
+ +

Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.

+

This function must be called before MQTT_SerializeSubscribe in order to get the size of the MQTT SUBSCRIBE packet that is generated from the list of MQTTSubscribeInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializeSubscribe must be at least pPacketSize. The provided pSubscriptionList is valid for serialization with MQTT_SerializeSubscribe only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[out]pRemainingLengthThe Remaining Length of the MQTT SUBSCRIBE packet.
[out]pPacketSizeThe total size of the MQTT SUBSCRIBE packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
// This is assumed to be a list of filters we want to subscribe to.
+
const char * filters[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// Set each subscription.
+
for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )
+
{
+
subscriptionList[ i ].qos = MQTTQoS0;
+
// Each subscription needs a topic filter.
+
subscriptionList[ i ].pTopicFilter = filters[ i ];
+
subscriptionList[ i ].topicFilterLength = strlen( filters[ i ] );
+
}
+
+
// Get the size requirement for the subscribe packet.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the subscribe request.
+
}
+
MQTTStatus_t MQTT_GetSubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.
Definition: core_mqtt_serializer.c:1848
+
@ MQTTQoS0
Definition: core_mqtt_serializer.h:110
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+
MQTTQoS_t qos
Quality of Service for subscription.
Definition: core_mqtt_serializer.h:184
+
uint16_t topicFilterLength
Length of subscription topic filter.
Definition: core_mqtt_serializer.h:194
+
const char * pTopicFilter
Topic filter to subscribe to.
Definition: core_mqtt_serializer.h:189
+
+
+
+ +

◆ MQTT_SerializeSubscribeHeader()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint8_t * MQTT_SerializeSubscribeHeader (size_t remainingLength,
uint8_t * pIndex,
uint16_t packetId 
)
+
+ +

Serialize the fixed part of the subscribe packet header.

+
Parameters
+ + + + +
[in]remainingLengthThe remaining length of the packet to be serialized.
[in]pIndexPointer to the buffer where the header is to be serialized.
[in]packetIdThe packet ID to be serialized.
+
+
+
Returns
A pointer to the end of the encoded string.
+ +
+
+ +

◆ MQTT_SerializeUnsubscribeHeader()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint8_t * MQTT_SerializeUnsubscribeHeader (size_t remainingLength,
uint8_t * pIndex,
uint16_t packetId 
)
+
+ +

Serialize the fixed part of the unsubscribe packet header.

+
Parameters
+ + + + +
[in]remainingLengthThe remaining length of the packet to be serialized.
[in]pIndexPointer to the buffer where the header is to be serialized.
[in]packetIdThe packet ID to be serialized.
+
+
+
Returns
A pointer to the end of the encoded string.
+ +
+
+ +

◆ MQTT_SerializeSubscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializeSubscribe (const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer 
)
+
+ +

Serialize an MQTT SUBSCRIBE packet in the given buffer.

+

MQTT_GetSubscribePacketSize should be called with pSubscriptionList before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetSubscribePacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetSubscribePacketSize.

+
Parameters
+ + + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetSubscribePacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
uint16_t packetId;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Function to return a valid, unused packet identifier. The details are out of
+
// scope for this example.
+
packetId = getNewPacketId();
+
+
// Assume subscriptionList has been initialized. Get the subscribe packet size.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the subscribe packet into the fixed buffer.
+ +
&subscriptionList[ 0 ],
+
NUMBER_OF_SUBSCRIPTIONS,
+
packetId,
+
remainingLength,
+
&fixedBuffer
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The subscribe packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializeSubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT SUBSCRIBE packet in the given buffer.
Definition: core_mqtt_serializer.c:1932
+
+
+
+ +

◆ MQTT_GetUnsubscribePacketSize()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetUnsubscribePacketSize (const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
size_t * pRemainingLength,
size_t * pPacketSize 
)
+
+ +

Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.

+

This function must be called before MQTT_SerializeUnsubscribe in order to get the size of the MQTT UNSUBSCRIBE packet that is generated from the list of MQTTSubscribeInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializeUnsubscribe must be at least pPacketSize. The provided pSubscriptionList is valid for serialization with MQTT_SerializeUnsubscribe only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[out]pRemainingLengthThe Remaining Length of the MQTT UNSUBSCRIBE packet.
[out]pPacketSizeThe total size of the MQTT UNSUBSCRIBE packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
+
// Initialize the subscribe info. The details are out of scope for this example.
+
initializeSubscribeInfo( &subscriptionList[ 0 ] );
+
+
// Get the size requirement for the unsubscribe packet.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the unsubscribe request.
+
}
+
MQTTStatus_t MQTT_GetUnsubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.
Definition: core_mqtt_serializer.c:1978
+
+
+
+ +

◆ MQTT_SerializeUnsubscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializeUnsubscribe (const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer 
)
+
+ +

Serialize an MQTT UNSUBSCRIBE packet in the given buffer.

+

MQTT_GetUnsubscribePacketSize should be called with pSubscriptionList before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetUnsubscribePacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetUnsubscribePacketSize.

+
Parameters
+ + + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetUnsubscribePacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
uint16_t packetId;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Function to return a valid, unused packet identifier. The details are out of
+
// scope for this example.
+
packetId = getNewPacketId();
+
+
// Assume subscriptionList has been initialized. Get the unsubscribe packet size.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the unsubscribe packet into the fixed buffer.
+ +
&subscriptionList[ 0 ],
+
NUMBER_OF_SUBSCRIPTIONS,
+
packetId,
+
remainingLength,
+
&fixedBuffer
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The unsubscribe packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializeUnsubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT UNSUBSCRIBE packet in the given buffer.
Definition: core_mqtt_serializer.c:2016
+
+
+
+ +

◆ MQTT_GetPublishPacketSize()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetPublishPacketSize (const MQTTPublishInfo_tpPublishInfo,
size_t * pRemainingLength,
size_t * pPacketSize 
)
+
+ +

Get the packet size and remaining length of an MQTT PUBLISH packet.

+

This function must be called before MQTT_SerializePublish in order to get the size of the MQTT PUBLISH packet that is generated from MQTTPublishInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializePublish must be at least pPacketSize. The provided pPublishInfo is valid for serialization with MQTT_SerializePublish only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[out]pRemainingLengthThe Remaining Length of the MQTT PUBLISH packet.
[out]pPacketSizeThe total size of the MQTT PUBLISH packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec or if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
+
// Initialize the publish info.
+
publishInfo.qos = MQTTQoS0;
+
publishInfo.pTopicName = "/some/topic/name";
+
publishInfo.topicNameLength = strlen( publishInfo.pTopicName );
+
publishInfo.pPayload = "Hello World!";
+
publishInfo.payloadLength = strlen( "Hello World!" );
+
+
// Get the size requirement for the publish packet.
+ +
&publishInfo, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the publish.
+
}
+
MQTTStatus_t MQTT_GetPublishPacketSize(const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the packet size and remaining length of an MQTT PUBLISH packet.
Definition: core_mqtt_serializer.c:2057
+
MQTTQoS_t qos
Quality of Service for message.
Definition: core_mqtt_serializer.h:206
+
uint16_t topicNameLength
Length of topic name.
Definition: core_mqtt_serializer.h:226
+
size_t payloadLength
Message payload length.
Definition: core_mqtt_serializer.h:236
+
const char * pTopicName
Topic name on which the message is published.
Definition: core_mqtt_serializer.h:221
+
const void * pPayload
Message payload.
Definition: core_mqtt_serializer.h:231
+
+
+
+ +

◆ MQTT_SerializePublish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializePublish (const MQTTPublishInfo_tpPublishInfo,
uint16_t packetId,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer 
)
+
+ +

Serialize an MQTT PUBLISH packet in the given buffer.

+

This function will serialize complete MQTT PUBLISH packet into the given buffer. If the PUBLISH payload can be sent separately, consider using MQTT_SerializePublishHeader, which will serialize only the PUBLISH header into the buffer.

+

MQTT_GetPublishPacketSize should be called with pPublishInfo before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetPublishPacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetPublishPacketSize.

+
Parameters
+ + + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetPublishPacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
uint16_t packetId;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// A packet identifier is unused for QoS 0 publishes. Otherwise, a valid, unused packet
+
// identifier must be used.
+
packetId = 0;
+
+
// Assume publishInfo has been initialized. Get publish packet size.
+ +
&publishInfo, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the publish packet into the fixed buffer.
+ +
&publishInfo,
+
packetId,
+
remainingLength,
+
&fixedBuffer
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The publish packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializePublish(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT PUBLISH packet in the given buffer.
Definition: core_mqtt_serializer.c:2098
+
+
+
+ +

◆ MQTT_SerializePublishHeader()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializePublishHeader (const MQTTPublishInfo_tpPublishInfo,
uint16_t packetId,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer,
size_t * pHeaderSize 
)
+
+ +

Serialize an MQTT PUBLISH packet header in the given buffer.

+

This function serializes PUBLISH header in to the given buffer. The payload for PUBLISH will not be copied over to the buffer. This will help reduce the memory needed for the buffer and avoid an unwanted copy operation of the PUBLISH payload into the buffer. If the payload also would need to be part of the serialized buffer, consider using MQTT_SerializePublish.

+

MQTT_GetPublishPacketSize should be called with pPublishInfo before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetPublishPacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetPublishPacketSize.

+
Parameters
+ + + + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetPublishPacketSize.
[out]pFixedBufferBuffer for packet serialization.
[out]pHeaderSizeSize of the serialized MQTT PUBLISH header.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0, headerSize = 0;
+
uint16_t packetId;
+
int32_t bytesSent;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// A packet identifier is unused for QoS 0 publishes. Otherwise, a valid, unused packet
+
// identifier must be used.
+
packetId = 0;
+
+
// Assume publishInfo has been initialized. Get the publish packet size.
+ +
&publishInfo, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
// The payload will not be serialized, so the the fixed buffer does not need to hold it.
+
assert( ( packetSize - publishInfo.payloadLength ) <= BUFFER_SIZE );
+
+
// Serialize the publish packet header into the fixed buffer.
+ +
&publishInfo,
+
packetId,
+
remainingLength,
+
&fixedBuffer,
+
&headerSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The publish header and payload can now be sent to the broker.
+
// mqttSocket here is a socket descriptor created and connected to the MQTT
+
// broker outside of this function.
+
bytesSent = send( mqttSocket, ( void * ) fixedBuffer.pBuffer, headerSize, 0 );
+
assert( bytesSent == headerSize );
+
bytesSent = send( mqttSocket, publishInfo.pPayload, publishInfo.payloadLength, 0 );
+
assert( bytesSent == publishInfo.payloadLength );
+
}
+
MQTTStatus_t MQTT_SerializePublishHeader(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer, size_t *pHeaderSize)
Serialize an MQTT PUBLISH packet header in the given buffer.
Definition: core_mqtt_serializer.c:2183
+
+
+
+ +

◆ MQTT_SerializeAck()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializeAck (const MQTTFixedBuffer_tpFixedBuffer,
uint8_t packetType,
uint16_t packetId 
)
+
+ +

Serialize an MQTT PUBACK, PUBREC, PUBREL, or PUBCOMP into the given buffer.

+
Parameters
+ + + + +
[out]pFixedBufferBuffer for packet serialization.
[in]packetTypeByte of the corresponding packet fixed header per the MQTT spec.
[in]packetIdPacket ID of the publish.
+
+
+
Returns
MQTTBadParameter, MQTTNoMemory, or MQTTSuccess.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
uint16_t packetId;
+
uint8_t packetType;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
// The fixed buffer must be large enough to hold 4 bytes.
+
assert( BUFFER_SIZE >= MQTT_PUBLISH_ACK_PACKET_SIZE );
+
+
// The packet ID must be the same as the original publish packet.
+
packetId = publishPacketId;
+
+
// The byte representing a packet of type ACK. This function accepts PUBACK, PUBREC, PUBREL, or PUBCOMP.
+ +
+
// Serialize the publish acknowledgment into the fixed buffer.
+
status = MQTT_SerializeAck( &fixedBuffer, packetType, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// The publish acknowledgment can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializeAck(const MQTTFixedBuffer_t *pFixedBuffer, uint8_t packetType, uint16_t packetId)
Serialize an MQTT PUBACK, PUBREC, PUBREL, or PUBCOMP into the given buffer.
Definition: core_mqtt_serializer.c:2266
+
#define MQTT_PUBLISH_ACK_PACKET_SIZE
The size of MQTT PUBACK, PUBREC, PUBREL, and PUBCOMP packets, per MQTT spec.
Definition: core_mqtt_serializer.h:73
+
#define MQTT_PACKET_TYPE_PUBACK
PUBACK (bidirectional).
Definition: core_mqtt_serializer.h:56
+
+
+
+ +

◆ MQTT_GetDisconnectPacketSize()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_GetDisconnectPacketSize (size_t * pPacketSize)
+
+ +

Get the size of an MQTT DISCONNECT packet.

+
Parameters
+ + +
[out]pPacketSizeThe size of the MQTT DISCONNECT packet.
+
+
+
Returns
MQTTSuccess, or MQTTBadParameter if pPacketSize is NULL.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
size_t packetSize = 0;
+
+
// Get the size requirement for the disconnect packet.
+
status = MQTT_GetDisconnectPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize == 2 );
+
+
// The application should allocate or use a static #MQTTFixedBuffer_t of
+
// size >= 2 to serialize the disconnect packet.
+
MQTTStatus_t MQTT_GetDisconnectPacketSize(size_t *pPacketSize)
Get the size of an MQTT DISCONNECT packet.
Definition: core_mqtt_serializer.c:2321
+
+
+
+ +

◆ MQTT_SerializeDisconnect()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_SerializeDisconnect (const MQTTFixedBuffer_tpFixedBuffer)
+
+ +

Serialize an MQTT DISCONNECT packet into the given buffer.

+

The input MQTTFixedBuffer_t.size must be at least as large as the size returned by MQTT_GetDisconnectPacketSize.

+
Parameters
+ + +
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Get the disconnect packet size.
+
status = MQTT_GetDisconnectPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the disconnect into the fixed buffer.
+
status = MQTT_SerializeDisconnect( &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// The disconnect packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializeDisconnect(const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT DISCONNECT packet into the given buffer.
Definition: core_mqtt_serializer.c:2341
+
+
+
+ +

◆ MQTT_GetPingreqPacketSize()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_GetPingreqPacketSize (size_t * pPacketSize)
+
+ +

Get the size of an MQTT PINGREQ packet.

+
Parameters
+ + +
[out]pPacketSizeThe size of the MQTT PINGREQ packet.
+
+
+
Returns
MQTTSuccess or MQTTBadParameter if pPacketSize is NULL.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
size_t packetSize = 0;
+
+
// Get the size requirement for the ping request packet.
+
status = MQTT_GetPingreqPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize == 2 );
+
+
// The application should allocate or use a static #MQTTFixedBuffer_t of
+
// size >= 2 to serialize the ping request.
+
MQTTStatus_t MQTT_GetPingreqPacketSize(size_t *pPacketSize)
Get the size of an MQTT PINGREQ packet.
Definition: core_mqtt_serializer.c:2384
+
+
+
+ +

◆ MQTT_SerializePingreq()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_SerializePingreq (const MQTTFixedBuffer_tpFixedBuffer)
+
+ +

Serialize an MQTT PINGREQ packet into the given buffer.

+

The input MQTTFixedBuffer_t.size must be at least as large as the size returned by MQTT_GetPingreqPacketSize.

+
Parameters
+ + +
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Get the ping request packet size.
+
status = MQTT_GetPingreqPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the ping request into the fixed buffer.
+
status = MQTT_SerializePingreq( &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// The ping request can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializePingreq(const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT PINGREQ packet into the given buffer.
Definition: core_mqtt_serializer.c:2404
+
+
+
+ +

◆ MQTT_DeserializePublish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_DeserializePublish (const MQTTPacketInfo_tpIncomingPacket,
uint16_t * pPacketId,
MQTTPublishInfo_tpPublishInfo 
)
+
+ +

Deserialize an MQTT PUBLISH packet.

+
Parameters
+ + + + +
[in]pIncomingPacketMQTTPacketInfo_t containing the buffer.
[out]pPacketIdThe packet ID obtained from the buffer.
[out]pPublishInfoStruct containing information about the publish.
+
+
+
Returns
MQTTBadParameter, MQTTBadResponse, or MQTTSuccess.
+

Example

// TransportRecv_t function for reading from the network.
+
int32_t socket_recv(
+
NetworkContext_t * pNetworkContext,
+
void * pBuffer,
+
size_t bytesToRecv
+
);
+
// Some context to be used with the above transport receive function.
+
NetworkContext_t networkContext;
+
+
// Other variables used in this example.
+
MQTTStatus_t status;
+
MQTTPacketInfo_t incomingPacket;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
uint16_t packetId;
+
+
int32_t bytesRecvd;
+
// A buffer to hold remaining data of the incoming packet.
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
// Populate all fields of the incoming packet.
+ +
socket_recv,
+
&networkContext,
+
&incomingPacket
+
);
+
assert( status == MQTTSuccess );
+
assert( incomingPacket.remainingLength <= BUFFER_SIZE );
+
bytesRecvd = socket_recv(
+
&networkContext,
+
( void * ) buffer,
+
incomingPacket.remainingLength
+
);
+
incomingPacket.pRemainingData = buffer;
+
+
// Deserialize the publish information if the incoming packet is a publish.
+
if( ( incomingPacket.type & 0xF0 ) == MQTT_PACKET_TYPE_PUBLISH )
+
{
+
status = MQTT_DeserializePublish( &incomingPacket, &packetId, &publishInfo );
+
if( status == MQTTSuccess )
+
{
+
// The deserialized publish information can now be used from `publishInfo`.
+
}
+
}
+
MQTTStatus_t MQTT_DeserializePublish(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo)
Deserialize an MQTT PUBLISH packet.
Definition: core_mqtt_serializer.c:2447
+
MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength(TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket)
Extract the MQTT packet type and length from incoming packet.
Definition: core_mqtt_serializer.c:2561
+
#define MQTT_PACKET_TYPE_PUBLISH
PUBLISH (bidirectional).
Definition: core_mqtt_serializer.h:55
+
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+
size_t remainingLength
Length of remaining serialized data.
Definition: core_mqtt_serializer.h:258
+
uint8_t type
Type of incoming MQTT packet.
Definition: core_mqtt_serializer.h:248
+
uint8_t * pRemainingData
Remaining serialized data in the MQTT packet.
Definition: core_mqtt_serializer.h:253
+
+
+
+ +

◆ MQTT_DeserializeAck()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_DeserializeAck (const MQTTPacketInfo_tpIncomingPacket,
uint16_t * pPacketId,
bool * pSessionPresent 
)
+
+ +

Deserialize an MQTT CONNACK, SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, PUBCOMP, or PINGRESP.

+
Parameters
+ + + + +
[in]pIncomingPacketMQTTPacketInfo_t containing the buffer.
[out]pPacketIdThe packet ID of obtained from the buffer. Not used in CONNACK or PINGRESP.
[out]pSessionPresentBoolean flag from a CONNACK indicating present session.
+
+
+
Returns
MQTTBadParameter, MQTTBadResponse, MQTTServerRefused, or MQTTSuccess.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPacketInfo_t incomingPacket;
+
// Used for SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, and PUBCOMP.
+
uint16_t packetId;
+
// Used for CONNACK.
+
bool sessionPresent;
+
+
// Receive an incoming packet and populate all fields. The details are out of scope
+
// for this example.
+
receiveIncomingPacket( &incomingPacket );
+
+
// Deserialize ack information if the incoming packet is not a publish.
+
if( ( incomingPacket.type & 0xF0 ) != MQTT_PACKET_TYPE_PUBLISH )
+
{
+
status = MQTT_DeserializeAck( &incomingPacket, &packetId, &sessionPresent );
+
if( status == MQTTSuccess )
+
{
+
// The packet ID or session present flag information is available. For
+
// ping response packets, the only information is the status code.
+
}
+
}
+
MQTTStatus_t MQTT_DeserializeAck(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, bool *pSessionPresent)
Deserialize an MQTT CONNACK, SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, PUBCOMP, or PINGRESP.
Definition: core_mqtt_serializer.c:2484
+
+
+
+ +

◆ MQTT_GetIncomingPacketTypeAndLength()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength (TransportRecv_t readFunc,
NetworkContext_tpNetworkContext,
MQTTPacketInfo_tpIncomingPacket 
)
+
+ +

Extract the MQTT packet type and length from incoming packet.

+

This function must be called for every incoming packet to retrieve the MQTTPacketInfo_t.type and MQTTPacketInfo_t.remainingLength. A MQTTPacketInfo_t is not valid until this routine has been invoked.

+
Parameters
+ + + + +
[in]readFuncTransport layer read function pointer.
[in]pNetworkContextThe network context pointer provided by the application.
[out]pIncomingPacketPointer to MQTTPacketInfo_t structure. This is where type, remaining length and packet identifier are stored.
+
+
+
Returns
MQTTSuccess on successful extraction of type and length, MQTTBadParameter if pIncomingPacket is invalid, MQTTRecvFailed on transport receive failure, MQTTBadResponse if an invalid packet is read, and MQTTNoDataAvailable if there is nothing to read.
+

Example

// TransportRecv_t function for reading from the network.
+
int32_t socket_recv(
+
NetworkContext_t * pNetworkContext,
+
void * pBuffer,
+
size_t bytesToRecv
+
);
+
// Some context to be used with above transport receive function.
+
NetworkContext_t networkContext;
+
+
// Struct to hold the incoming packet information.
+
MQTTPacketInfo_t incomingPacket;
+ +
int32_t bytesRecvd;
+
// Buffer to hold the remaining data of the incoming packet.
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
// Loop until data is available to be received.
+
do{
+ +
socket_recv,
+
&networkContext,
+
&incomingPacket
+
);
+
} while( status == MQTTNoDataAvailable );
+
+
assert( status == MQTTSuccess );
+
+
// Receive the rest of the incoming packet.
+
assert( incomingPacket.remainingLength <= BUFFER_SIZE );
+
bytesRecvd = socket_recv(
+
&networkContext,
+
( void * ) buffer,
+
incomingPacket.remainingLength
+
);
+
+
// Set the remaining data field.
+
incomingPacket.pRemainingData = buffer;
+
@ MQTTNoDataAvailable
Definition: core_mqtt_serializer.h:95
+
+
+
+ +

◆ MQTT_ProcessIncomingPacketTypeAndLength()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_ProcessIncomingPacketTypeAndLength (const uint8_t * pBuffer,
const size_t * pIndex,
MQTTPacketInfo_tpIncomingPacket 
)
+
+ +

Extract the MQTT packet type and length from incoming packet.

+

This function must be called for every incoming packet to retrieve the MQTTPacketInfo_t.type and MQTTPacketInfo_t.remainingLength. A MQTTPacketInfo_t is not valid until this routine has been invoked.

+
Parameters
+ + + + +
[in]pBufferThe buffer holding the raw data to be processed
[in]pIndexPointer to the index within the buffer to marking the end of raw data available.
[out]pIncomingPacketStructure used to hold the fields of the incoming packet.
+
+
+
Returns
MQTTSuccess on successful extraction of type and length, MQTTBadParameter if pIncomingPacket is invalid, MQTTBadResponse if an invalid packet is read, and MQTTNoDataAvailable if there is nothing to read.
+ +
+
+
+
+ + + + diff --git a/latest/coreMQTT/core__mqtt__serializer_8h.html b/latest/coreMQTT/core__mqtt__serializer_8h.html new file mode 100644 index 00000000..3088a5dd --- /dev/null +++ b/latest/coreMQTT/core__mqtt__serializer_8h.html @@ -0,0 +1,1675 @@ + + + + + + + +coreMQTT: core_mqtt_serializer.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_serializer.h File Reference
+
+
+ +

User-facing functions for serializing and deserializing MQTT 3.1.1 packets. This header should be included for building a lighter weight MQTT client than the managed CSDK MQTT library API in core_mqtt.h, by using the serializer and de-serializer functions exposed in this file's API. +More...

+
#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include "transport_interface.h"
+
+

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + +

+Data Structures

struct  MQTTFixedBuffer_t
 Buffer passed to MQTT library. More...
 
struct  MQTTConnectInfo_t
 MQTT CONNECT packet parameters. More...
 
struct  MQTTSubscribeInfo_t
 MQTT SUBSCRIBE packet parameters. More...
 
struct  MQTTPublishInfo_t
 MQTT PUBLISH packet parameters. More...
 
struct  MQTTPacketInfo_t
 MQTT incoming packet parameters. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Macros

+#define MQTT_PACKET_TYPE_CONNECT   ( ( uint8_t ) 0x10U )
 CONNECT (client-to-server).
 
+#define MQTT_PACKET_TYPE_CONNACK   ( ( uint8_t ) 0x20U )
 CONNACK (server-to-client).
 
+#define MQTT_PACKET_TYPE_PUBLISH   ( ( uint8_t ) 0x30U )
 PUBLISH (bidirectional).
 
+#define MQTT_PACKET_TYPE_PUBACK   ( ( uint8_t ) 0x40U )
 PUBACK (bidirectional).
 
+#define MQTT_PACKET_TYPE_PUBREC   ( ( uint8_t ) 0x50U )
 PUBREC (bidirectional).
 
+#define MQTT_PACKET_TYPE_PUBREL   ( ( uint8_t ) 0x62U )
 PUBREL (bidirectional).
 
+#define MQTT_PACKET_TYPE_PUBCOMP   ( ( uint8_t ) 0x70U )
 PUBCOMP (bidirectional).
 
+#define MQTT_PACKET_TYPE_SUBSCRIBE   ( ( uint8_t ) 0x82U )
 SUBSCRIBE (client-to-server).
 
+#define MQTT_PACKET_TYPE_SUBACK   ( ( uint8_t ) 0x90U )
 SUBACK (server-to-client).
 
+#define MQTT_PACKET_TYPE_UNSUBSCRIBE   ( ( uint8_t ) 0xA2U )
 UNSUBSCRIBE (client-to-server).
 
+#define MQTT_PACKET_TYPE_UNSUBACK   ( ( uint8_t ) 0xB0U )
 UNSUBACK (server-to-client).
 
+#define MQTT_PACKET_TYPE_PINGREQ   ( ( uint8_t ) 0xC0U )
 PINGREQ (client-to-server).
 
+#define MQTT_PACKET_TYPE_PINGRESP   ( ( uint8_t ) 0xD0U )
 PINGRESP (server-to-client).
 
+#define MQTT_PACKET_TYPE_DISCONNECT   ( ( uint8_t ) 0xE0U )
 DISCONNECT (client-to-server).
 
+#define MQTT_PUBLISH_ACK_PACKET_SIZE   ( 4UL )
 The size of MQTT PUBACK, PUBREC, PUBREL, and PUBCOMP packets, per MQTT spec.
 
+ + + + + + + +

+Enumerations

enum  MQTTStatus_t {
+  MQTTSuccess = 0 +, MQTTBadParameter +, MQTTNoMemory +, MQTTSendFailed +,
+  MQTTRecvFailed +, MQTTBadResponse +, MQTTServerRefused +, MQTTNoDataAvailable +,
+  MQTTIllegalState +, MQTTStateCollision +, MQTTKeepAliveTimeout +, MQTTNeedMoreBytes +
+ }
 Return codes from MQTT functions. More...
 
enum  MQTTQoS_t { MQTTQoS0 = 0 +, MQTTQoS1 = 1 +, MQTTQoS2 = 2 + }
 MQTT Quality of Service values. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

MQTTStatus_t MQTT_GetConnectPacketSize (const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize)
 Get the size and Remaining Length of an MQTT CONNECT packet.
 
MQTTStatus_t MQTT_SerializeConnect (const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT CONNECT packet in the given fixed buffer pFixedBuffer.
 
MQTTStatus_t MQTT_GetSubscribePacketSize (const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
 Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.
 
MQTTStatus_t MQTT_SerializeSubscribe (const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT SUBSCRIBE packet in the given buffer.
 
MQTTStatus_t MQTT_GetUnsubscribePacketSize (const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
 Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.
 
MQTTStatus_t MQTT_SerializeUnsubscribe (const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT UNSUBSCRIBE packet in the given buffer.
 
MQTTStatus_t MQTT_GetPublishPacketSize (const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize)
 Get the packet size and remaining length of an MQTT PUBLISH packet.
 
MQTTStatus_t MQTT_SerializePublish (const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT PUBLISH packet in the given buffer.
 
MQTTStatus_t MQTT_SerializePublishHeaderWithoutTopic (const MQTTPublishInfo_t *pPublishInfo, size_t remainingLength, uint8_t *pBuffer, size_t *headerSize)
 Serialize an MQTT PUBLISH packet header without the topic string in the given buffer. This function will add the topic string length to the provided buffer. This helps reduce an unnecessary copy of the topic string into the buffer.
 
MQTTStatus_t MQTT_SerializePublishHeader (const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer, size_t *pHeaderSize)
 Serialize an MQTT PUBLISH packet header in the given buffer.
 
MQTTStatus_t MQTT_SerializeAck (const MQTTFixedBuffer_t *pFixedBuffer, uint8_t packetType, uint16_t packetId)
 Serialize an MQTT PUBACK, PUBREC, PUBREL, or PUBCOMP into the given buffer.
 
MQTTStatus_t MQTT_GetDisconnectPacketSize (size_t *pPacketSize)
 Get the size of an MQTT DISCONNECT packet.
 
MQTTStatus_t MQTT_SerializeDisconnect (const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT DISCONNECT packet into the given buffer.
 
MQTTStatus_t MQTT_GetPingreqPacketSize (size_t *pPacketSize)
 Get the size of an MQTT PINGREQ packet.
 
MQTTStatus_t MQTT_SerializePingreq (const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT PINGREQ packet into the given buffer.
 
MQTTStatus_t MQTT_DeserializePublish (const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo)
 Deserialize an MQTT PUBLISH packet.
 
MQTTStatus_t MQTT_DeserializeAck (const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, bool *pSessionPresent)
 Deserialize an MQTT CONNACK, SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, PUBCOMP, or PINGRESP.
 
MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength (TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket)
 Extract the MQTT packet type and length from incoming packet.
 
MQTTStatus_t MQTT_ProcessIncomingPacketTypeAndLength (const uint8_t *pBuffer, const size_t *pIndex, MQTTPacketInfo_t *pIncomingPacket)
 Extract the MQTT packet type and length from incoming packet.
 
+

Detailed Description

+

User-facing functions for serializing and deserializing MQTT 3.1.1 packets. This header should be included for building a lighter weight MQTT client than the managed CSDK MQTT library API in core_mqtt.h, by using the serializer and de-serializer functions exposed in this file's API.

+

Function Documentation

+ +

◆ MQTT_GetConnectPacketSize()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetConnectPacketSize (const MQTTConnectInfo_tpConnectInfo,
const MQTTPublishInfo_tpWillInfo,
size_t * pRemainingLength,
size_t * pPacketSize 
)
+
+ +

Get the size and Remaining Length of an MQTT CONNECT packet.

+

This function must be called before MQTT_SerializeConnect in order to get the size of the MQTT CONNECT packet that is generated from MQTTConnectInfo_t and optional MQTTPublishInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializeConnect must be at least pPacketSize. The provided pConnectInfo and pWillInfo are valid for serialization with MQTT_SerializeConnect only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + + +
[in]pConnectInfoMQTT CONNECT packet parameters.
[in]pWillInfoLast Will and Testament. Pass NULL if not used.
[out]pRemainingLengthThe Remaining Length of the MQTT CONNECT packet.
[out]pPacketSizeThe total size of the MQTT CONNECT packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
+
// Initialize the connection info, the details are out of scope for this example.
+
initializeConnectInfo( &connectInfo );
+
+
// Initialize the optional will info, the details are out of scope for this example.
+
initializeWillInfo( &willInfo );
+
+
// Get the size requirement for the connect packet.
+ +
&connectInfo, &willInfo, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the connect request.
+
}
+
MQTTStatus_t MQTT_GetConnectPacketSize(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the size and Remaining Length of an MQTT CONNECT packet.
Definition: core_mqtt_serializer.c:1690
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+
+
+
+ +

◆ MQTT_SerializeConnect()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializeConnect (const MQTTConnectInfo_tpConnectInfo,
const MQTTPublishInfo_tpWillInfo,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer 
)
+
+ +

Serialize an MQTT CONNECT packet in the given fixed buffer pFixedBuffer.

+

MQTT_GetConnectPacketSize should be called with pConnectInfo and pWillInfo before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetConnectPacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetConnectPacketSize.

+
Parameters
+ + + + + +
[in]pConnectInfoMQTT CONNECT packet parameters.
[in]pWillInfoLast Will and Testament. Pass NULL if not used.
[in]remainingLengthRemaining Length provided by MQTT_GetConnectPacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Assume connectInfo and willInfo are initialized. Get the size requirement for
+
// the connect packet.
+ +
&connectInfo, &willInfo, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the connect packet into the fixed buffer.
+
status = MQTT_SerializeConnect( &connectInfo, &willInfo, remainingLength, &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// The connect packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializeConnect(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT CONNECT packet in the given fixed buffer pFixedBuffer.
Definition: core_mqtt_serializer.c:1790
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
+
+
+ +

◆ MQTT_GetSubscribePacketSize()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetSubscribePacketSize (const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
size_t * pRemainingLength,
size_t * pPacketSize 
)
+
+ +

Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.

+

This function must be called before MQTT_SerializeSubscribe in order to get the size of the MQTT SUBSCRIBE packet that is generated from the list of MQTTSubscribeInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializeSubscribe must be at least pPacketSize. The provided pSubscriptionList is valid for serialization with MQTT_SerializeSubscribe only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[out]pRemainingLengthThe Remaining Length of the MQTT SUBSCRIBE packet.
[out]pPacketSizeThe total size of the MQTT SUBSCRIBE packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
// This is assumed to be a list of filters we want to subscribe to.
+
const char * filters[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// Set each subscription.
+
for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )
+
{
+
subscriptionList[ i ].qos = MQTTQoS0;
+
// Each subscription needs a topic filter.
+
subscriptionList[ i ].pTopicFilter = filters[ i ];
+
subscriptionList[ i ].topicFilterLength = strlen( filters[ i ] );
+
}
+
+
// Get the size requirement for the subscribe packet.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the subscribe request.
+
}
+
MQTTStatus_t MQTT_GetSubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.
Definition: core_mqtt_serializer.c:1848
+
@ MQTTQoS0
Definition: core_mqtt_serializer.h:110
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+
MQTTQoS_t qos
Quality of Service for subscription.
Definition: core_mqtt_serializer.h:184
+
uint16_t topicFilterLength
Length of subscription topic filter.
Definition: core_mqtt_serializer.h:194
+
const char * pTopicFilter
Topic filter to subscribe to.
Definition: core_mqtt_serializer.h:189
+
+
+
+ +

◆ MQTT_SerializeSubscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializeSubscribe (const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer 
)
+
+ +

Serialize an MQTT SUBSCRIBE packet in the given buffer.

+

MQTT_GetSubscribePacketSize should be called with pSubscriptionList before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetSubscribePacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetSubscribePacketSize.

+
Parameters
+ + + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetSubscribePacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
uint16_t packetId;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Function to return a valid, unused packet identifier. The details are out of
+
// scope for this example.
+
packetId = getNewPacketId();
+
+
// Assume subscriptionList has been initialized. Get the subscribe packet size.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the subscribe packet into the fixed buffer.
+ +
&subscriptionList[ 0 ],
+
NUMBER_OF_SUBSCRIPTIONS,
+
packetId,
+
remainingLength,
+
&fixedBuffer
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The subscribe packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializeSubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT SUBSCRIBE packet in the given buffer.
Definition: core_mqtt_serializer.c:1932
+
+
+
+ +

◆ MQTT_GetUnsubscribePacketSize()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetUnsubscribePacketSize (const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
size_t * pRemainingLength,
size_t * pPacketSize 
)
+
+ +

Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.

+

This function must be called before MQTT_SerializeUnsubscribe in order to get the size of the MQTT UNSUBSCRIBE packet that is generated from the list of MQTTSubscribeInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializeUnsubscribe must be at least pPacketSize. The provided pSubscriptionList is valid for serialization with MQTT_SerializeUnsubscribe only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[out]pRemainingLengthThe Remaining Length of the MQTT UNSUBSCRIBE packet.
[out]pPacketSizeThe total size of the MQTT UNSUBSCRIBE packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
+
// Initialize the subscribe info. The details are out of scope for this example.
+
initializeSubscribeInfo( &subscriptionList[ 0 ] );
+
+
// Get the size requirement for the unsubscribe packet.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the unsubscribe request.
+
}
+
MQTTStatus_t MQTT_GetUnsubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.
Definition: core_mqtt_serializer.c:1978
+
+
+
+ +

◆ MQTT_SerializeUnsubscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializeUnsubscribe (const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer 
)
+
+ +

Serialize an MQTT UNSUBSCRIBE packet in the given buffer.

+

MQTT_GetUnsubscribePacketSize should be called with pSubscriptionList before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetUnsubscribePacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetUnsubscribePacketSize.

+
Parameters
+ + + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetUnsubscribePacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
uint16_t packetId;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Function to return a valid, unused packet identifier. The details are out of
+
// scope for this example.
+
packetId = getNewPacketId();
+
+
// Assume subscriptionList has been initialized. Get the unsubscribe packet size.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the unsubscribe packet into the fixed buffer.
+ +
&subscriptionList[ 0 ],
+
NUMBER_OF_SUBSCRIPTIONS,
+
packetId,
+
remainingLength,
+
&fixedBuffer
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The unsubscribe packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializeUnsubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT UNSUBSCRIBE packet in the given buffer.
Definition: core_mqtt_serializer.c:2016
+
+
+
+ +

◆ MQTT_GetPublishPacketSize()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetPublishPacketSize (const MQTTPublishInfo_tpPublishInfo,
size_t * pRemainingLength,
size_t * pPacketSize 
)
+
+ +

Get the packet size and remaining length of an MQTT PUBLISH packet.

+

This function must be called before MQTT_SerializePublish in order to get the size of the MQTT PUBLISH packet that is generated from MQTTPublishInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializePublish must be at least pPacketSize. The provided pPublishInfo is valid for serialization with MQTT_SerializePublish only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[out]pRemainingLengthThe Remaining Length of the MQTT PUBLISH packet.
[out]pPacketSizeThe total size of the MQTT PUBLISH packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec or if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
+
// Initialize the publish info.
+
publishInfo.qos = MQTTQoS0;
+
publishInfo.pTopicName = "/some/topic/name";
+
publishInfo.topicNameLength = strlen( publishInfo.pTopicName );
+
publishInfo.pPayload = "Hello World!";
+
publishInfo.payloadLength = strlen( "Hello World!" );
+
+
// Get the size requirement for the publish packet.
+ +
&publishInfo, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the publish.
+
}
+
MQTTStatus_t MQTT_GetPublishPacketSize(const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the packet size and remaining length of an MQTT PUBLISH packet.
Definition: core_mqtt_serializer.c:2057
+
MQTTQoS_t qos
Quality of Service for message.
Definition: core_mqtt_serializer.h:206
+
uint16_t topicNameLength
Length of topic name.
Definition: core_mqtt_serializer.h:226
+
size_t payloadLength
Message payload length.
Definition: core_mqtt_serializer.h:236
+
const char * pTopicName
Topic name on which the message is published.
Definition: core_mqtt_serializer.h:221
+
const void * pPayload
Message payload.
Definition: core_mqtt_serializer.h:231
+
+
+
+ +

◆ MQTT_SerializePublish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializePublish (const MQTTPublishInfo_tpPublishInfo,
uint16_t packetId,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer 
)
+
+ +

Serialize an MQTT PUBLISH packet in the given buffer.

+

This function will serialize complete MQTT PUBLISH packet into the given buffer. If the PUBLISH payload can be sent separately, consider using MQTT_SerializePublishHeader, which will serialize only the PUBLISH header into the buffer.

+

MQTT_GetPublishPacketSize should be called with pPublishInfo before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetPublishPacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetPublishPacketSize.

+
Parameters
+ + + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetPublishPacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
uint16_t packetId;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// A packet identifier is unused for QoS 0 publishes. Otherwise, a valid, unused packet
+
// identifier must be used.
+
packetId = 0;
+
+
// Assume publishInfo has been initialized. Get publish packet size.
+ +
&publishInfo, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the publish packet into the fixed buffer.
+ +
&publishInfo,
+
packetId,
+
remainingLength,
+
&fixedBuffer
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The publish packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializePublish(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT PUBLISH packet in the given buffer.
Definition: core_mqtt_serializer.c:2098
+
+
+
+ +

◆ MQTT_SerializePublishHeaderWithoutTopic()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializePublishHeaderWithoutTopic (const MQTTPublishInfo_tpPublishInfo,
size_t remainingLength,
uint8_t * pBuffer,
size_t * headerSize 
)
+
+ +

Serialize an MQTT PUBLISH packet header without the topic string in the given buffer. This function will add the topic string length to the provided buffer. This helps reduce an unnecessary copy of the topic string into the buffer.

+
Parameters
+ + + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]remainingLengthRemaining Length provided by MQTT_GetPublishPacketSize.
[out]pBufferBuffer for packet serialization.
[out]headerSizeSize of the serialized MQTT PUBLISH header.
+
+
+
Returns
MQTTSuccess if the serialization is successful. Otherwise, MQTTBadParameter.
+ +
+
+ +

◆ MQTT_SerializePublishHeader()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializePublishHeader (const MQTTPublishInfo_tpPublishInfo,
uint16_t packetId,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer,
size_t * pHeaderSize 
)
+
+ +

Serialize an MQTT PUBLISH packet header in the given buffer.

+

This function serializes PUBLISH header in to the given buffer. The payload for PUBLISH will not be copied over to the buffer. This will help reduce the memory needed for the buffer and avoid an unwanted copy operation of the PUBLISH payload into the buffer. If the payload also would need to be part of the serialized buffer, consider using MQTT_SerializePublish.

+

MQTT_GetPublishPacketSize should be called with pPublishInfo before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetPublishPacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetPublishPacketSize.

+
Parameters
+ + + + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetPublishPacketSize.
[out]pFixedBufferBuffer for packet serialization.
[out]pHeaderSizeSize of the serialized MQTT PUBLISH header.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0, headerSize = 0;
+
uint16_t packetId;
+
int32_t bytesSent;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// A packet identifier is unused for QoS 0 publishes. Otherwise, a valid, unused packet
+
// identifier must be used.
+
packetId = 0;
+
+
// Assume publishInfo has been initialized. Get the publish packet size.
+ +
&publishInfo, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
// The payload will not be serialized, so the the fixed buffer does not need to hold it.
+
assert( ( packetSize - publishInfo.payloadLength ) <= BUFFER_SIZE );
+
+
// Serialize the publish packet header into the fixed buffer.
+ +
&publishInfo,
+
packetId,
+
remainingLength,
+
&fixedBuffer,
+
&headerSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The publish header and payload can now be sent to the broker.
+
// mqttSocket here is a socket descriptor created and connected to the MQTT
+
// broker outside of this function.
+
bytesSent = send( mqttSocket, ( void * ) fixedBuffer.pBuffer, headerSize, 0 );
+
assert( bytesSent == headerSize );
+
bytesSent = send( mqttSocket, publishInfo.pPayload, publishInfo.payloadLength, 0 );
+
assert( bytesSent == publishInfo.payloadLength );
+
}
+
MQTTStatus_t MQTT_SerializePublishHeader(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer, size_t *pHeaderSize)
Serialize an MQTT PUBLISH packet header in the given buffer.
Definition: core_mqtt_serializer.c:2183
+
+
+
+ +

◆ MQTT_SerializeAck()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializeAck (const MQTTFixedBuffer_tpFixedBuffer,
uint8_t packetType,
uint16_t packetId 
)
+
+ +

Serialize an MQTT PUBACK, PUBREC, PUBREL, or PUBCOMP into the given buffer.

+
Parameters
+ + + + +
[out]pFixedBufferBuffer for packet serialization.
[in]packetTypeByte of the corresponding packet fixed header per the MQTT spec.
[in]packetIdPacket ID of the publish.
+
+
+
Returns
MQTTBadParameter, MQTTNoMemory, or MQTTSuccess.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
uint16_t packetId;
+
uint8_t packetType;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
// The fixed buffer must be large enough to hold 4 bytes.
+
assert( BUFFER_SIZE >= MQTT_PUBLISH_ACK_PACKET_SIZE );
+
+
// The packet ID must be the same as the original publish packet.
+
packetId = publishPacketId;
+
+
// The byte representing a packet of type ACK. This function accepts PUBACK, PUBREC, PUBREL, or PUBCOMP.
+ +
+
// Serialize the publish acknowledgment into the fixed buffer.
+
status = MQTT_SerializeAck( &fixedBuffer, packetType, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// The publish acknowledgment can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializeAck(const MQTTFixedBuffer_t *pFixedBuffer, uint8_t packetType, uint16_t packetId)
Serialize an MQTT PUBACK, PUBREC, PUBREL, or PUBCOMP into the given buffer.
Definition: core_mqtt_serializer.c:2266
+
#define MQTT_PUBLISH_ACK_PACKET_SIZE
The size of MQTT PUBACK, PUBREC, PUBREL, and PUBCOMP packets, per MQTT spec.
Definition: core_mqtt_serializer.h:73
+
#define MQTT_PACKET_TYPE_PUBACK
PUBACK (bidirectional).
Definition: core_mqtt_serializer.h:56
+
+
+
+ +

◆ MQTT_GetDisconnectPacketSize()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_GetDisconnectPacketSize (size_t * pPacketSize)
+
+ +

Get the size of an MQTT DISCONNECT packet.

+
Parameters
+ + +
[out]pPacketSizeThe size of the MQTT DISCONNECT packet.
+
+
+
Returns
MQTTSuccess, or MQTTBadParameter if pPacketSize is NULL.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
size_t packetSize = 0;
+
+
// Get the size requirement for the disconnect packet.
+
status = MQTT_GetDisconnectPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize == 2 );
+
+
// The application should allocate or use a static #MQTTFixedBuffer_t of
+
// size >= 2 to serialize the disconnect packet.
+
MQTTStatus_t MQTT_GetDisconnectPacketSize(size_t *pPacketSize)
Get the size of an MQTT DISCONNECT packet.
Definition: core_mqtt_serializer.c:2321
+
+
+
+ +

◆ MQTT_SerializeDisconnect()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_SerializeDisconnect (const MQTTFixedBuffer_tpFixedBuffer)
+
+ +

Serialize an MQTT DISCONNECT packet into the given buffer.

+

The input MQTTFixedBuffer_t.size must be at least as large as the size returned by MQTT_GetDisconnectPacketSize.

+
Parameters
+ + +
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Get the disconnect packet size.
+
status = MQTT_GetDisconnectPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the disconnect into the fixed buffer.
+
status = MQTT_SerializeDisconnect( &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// The disconnect packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializeDisconnect(const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT DISCONNECT packet into the given buffer.
Definition: core_mqtt_serializer.c:2341
+
+
+
+ +

◆ MQTT_GetPingreqPacketSize()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_GetPingreqPacketSize (size_t * pPacketSize)
+
+ +

Get the size of an MQTT PINGREQ packet.

+
Parameters
+ + +
[out]pPacketSizeThe size of the MQTT PINGREQ packet.
+
+
+
Returns
MQTTSuccess or MQTTBadParameter if pPacketSize is NULL.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
size_t packetSize = 0;
+
+
// Get the size requirement for the ping request packet.
+
status = MQTT_GetPingreqPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize == 2 );
+
+
// The application should allocate or use a static #MQTTFixedBuffer_t of
+
// size >= 2 to serialize the ping request.
+
MQTTStatus_t MQTT_GetPingreqPacketSize(size_t *pPacketSize)
Get the size of an MQTT PINGREQ packet.
Definition: core_mqtt_serializer.c:2384
+
+
+
+ +

◆ MQTT_SerializePingreq()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_SerializePingreq (const MQTTFixedBuffer_tpFixedBuffer)
+
+ +

Serialize an MQTT PINGREQ packet into the given buffer.

+

The input MQTTFixedBuffer_t.size must be at least as large as the size returned by MQTT_GetPingreqPacketSize.

+
Parameters
+ + +
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Get the ping request packet size.
+
status = MQTT_GetPingreqPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the ping request into the fixed buffer.
+
status = MQTT_SerializePingreq( &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// The ping request can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializePingreq(const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT PINGREQ packet into the given buffer.
Definition: core_mqtt_serializer.c:2404
+
+
+
+ +

◆ MQTT_DeserializePublish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_DeserializePublish (const MQTTPacketInfo_tpIncomingPacket,
uint16_t * pPacketId,
MQTTPublishInfo_tpPublishInfo 
)
+
+ +

Deserialize an MQTT PUBLISH packet.

+
Parameters
+ + + + +
[in]pIncomingPacketMQTTPacketInfo_t containing the buffer.
[out]pPacketIdThe packet ID obtained from the buffer.
[out]pPublishInfoStruct containing information about the publish.
+
+
+
Returns
MQTTBadParameter, MQTTBadResponse, or MQTTSuccess.
+

Example

// TransportRecv_t function for reading from the network.
+
int32_t socket_recv(
+
NetworkContext_t * pNetworkContext,
+
void * pBuffer,
+
size_t bytesToRecv
+
);
+
// Some context to be used with the above transport receive function.
+
NetworkContext_t networkContext;
+
+
// Other variables used in this example.
+
MQTTStatus_t status;
+
MQTTPacketInfo_t incomingPacket;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
uint16_t packetId;
+
+
int32_t bytesRecvd;
+
// A buffer to hold remaining data of the incoming packet.
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
// Populate all fields of the incoming packet.
+ +
socket_recv,
+
&networkContext,
+
&incomingPacket
+
);
+
assert( status == MQTTSuccess );
+
assert( incomingPacket.remainingLength <= BUFFER_SIZE );
+
bytesRecvd = socket_recv(
+
&networkContext,
+
( void * ) buffer,
+
incomingPacket.remainingLength
+
);
+
incomingPacket.pRemainingData = buffer;
+
+
// Deserialize the publish information if the incoming packet is a publish.
+
if( ( incomingPacket.type & 0xF0 ) == MQTT_PACKET_TYPE_PUBLISH )
+
{
+
status = MQTT_DeserializePublish( &incomingPacket, &packetId, &publishInfo );
+
if( status == MQTTSuccess )
+
{
+
// The deserialized publish information can now be used from `publishInfo`.
+
}
+
}
+
MQTTStatus_t MQTT_DeserializePublish(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo)
Deserialize an MQTT PUBLISH packet.
Definition: core_mqtt_serializer.c:2447
+
MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength(TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket)
Extract the MQTT packet type and length from incoming packet.
Definition: core_mqtt_serializer.c:2561
+
#define MQTT_PACKET_TYPE_PUBLISH
PUBLISH (bidirectional).
Definition: core_mqtt_serializer.h:55
+
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+
size_t remainingLength
Length of remaining serialized data.
Definition: core_mqtt_serializer.h:258
+
uint8_t type
Type of incoming MQTT packet.
Definition: core_mqtt_serializer.h:248
+
uint8_t * pRemainingData
Remaining serialized data in the MQTT packet.
Definition: core_mqtt_serializer.h:253
+
+
+
+ +

◆ MQTT_DeserializeAck()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_DeserializeAck (const MQTTPacketInfo_tpIncomingPacket,
uint16_t * pPacketId,
bool * pSessionPresent 
)
+
+ +

Deserialize an MQTT CONNACK, SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, PUBCOMP, or PINGRESP.

+
Parameters
+ + + + +
[in]pIncomingPacketMQTTPacketInfo_t containing the buffer.
[out]pPacketIdThe packet ID of obtained from the buffer. Not used in CONNACK or PINGRESP.
[out]pSessionPresentBoolean flag from a CONNACK indicating present session.
+
+
+
Returns
MQTTBadParameter, MQTTBadResponse, MQTTServerRefused, or MQTTSuccess.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPacketInfo_t incomingPacket;
+
// Used for SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, and PUBCOMP.
+
uint16_t packetId;
+
// Used for CONNACK.
+
bool sessionPresent;
+
+
// Receive an incoming packet and populate all fields. The details are out of scope
+
// for this example.
+
receiveIncomingPacket( &incomingPacket );
+
+
// Deserialize ack information if the incoming packet is not a publish.
+
if( ( incomingPacket.type & 0xF0 ) != MQTT_PACKET_TYPE_PUBLISH )
+
{
+
status = MQTT_DeserializeAck( &incomingPacket, &packetId, &sessionPresent );
+
if( status == MQTTSuccess )
+
{
+
// The packet ID or session present flag information is available. For
+
// ping response packets, the only information is the status code.
+
}
+
}
+
MQTTStatus_t MQTT_DeserializeAck(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, bool *pSessionPresent)
Deserialize an MQTT CONNACK, SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, PUBCOMP, or PINGRESP.
Definition: core_mqtt_serializer.c:2484
+
+
+
+ +

◆ MQTT_GetIncomingPacketTypeAndLength()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength (TransportRecv_t readFunc,
NetworkContext_tpNetworkContext,
MQTTPacketInfo_tpIncomingPacket 
)
+
+ +

Extract the MQTT packet type and length from incoming packet.

+

This function must be called for every incoming packet to retrieve the MQTTPacketInfo_t.type and MQTTPacketInfo_t.remainingLength. A MQTTPacketInfo_t is not valid until this routine has been invoked.

+
Parameters
+ + + + +
[in]readFuncTransport layer read function pointer.
[in]pNetworkContextThe network context pointer provided by the application.
[out]pIncomingPacketPointer to MQTTPacketInfo_t structure. This is where type, remaining length and packet identifier are stored.
+
+
+
Returns
MQTTSuccess on successful extraction of type and length, MQTTBadParameter if pIncomingPacket is invalid, MQTTRecvFailed on transport receive failure, MQTTBadResponse if an invalid packet is read, and MQTTNoDataAvailable if there is nothing to read.
+

Example

// TransportRecv_t function for reading from the network.
+
int32_t socket_recv(
+
NetworkContext_t * pNetworkContext,
+
void * pBuffer,
+
size_t bytesToRecv
+
);
+
// Some context to be used with above transport receive function.
+
NetworkContext_t networkContext;
+
+
// Struct to hold the incoming packet information.
+
MQTTPacketInfo_t incomingPacket;
+ +
int32_t bytesRecvd;
+
// Buffer to hold the remaining data of the incoming packet.
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
// Loop until data is available to be received.
+
do{
+ +
socket_recv,
+
&networkContext,
+
&incomingPacket
+
);
+
} while( status == MQTTNoDataAvailable );
+
+
assert( status == MQTTSuccess );
+
+
// Receive the rest of the incoming packet.
+
assert( incomingPacket.remainingLength <= BUFFER_SIZE );
+
bytesRecvd = socket_recv(
+
&networkContext,
+
( void * ) buffer,
+
incomingPacket.remainingLength
+
);
+
+
// Set the remaining data field.
+
incomingPacket.pRemainingData = buffer;
+
@ MQTTNoDataAvailable
Definition: core_mqtt_serializer.h:95
+
+
+
+ +

◆ MQTT_ProcessIncomingPacketTypeAndLength()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_ProcessIncomingPacketTypeAndLength (const uint8_t * pBuffer,
const size_t * pIndex,
MQTTPacketInfo_tpIncomingPacket 
)
+
+ +

Extract the MQTT packet type and length from incoming packet.

+

This function must be called for every incoming packet to retrieve the MQTTPacketInfo_t.type and MQTTPacketInfo_t.remainingLength. A MQTTPacketInfo_t is not valid until this routine has been invoked.

+
Parameters
+ + + + +
[in]pBufferThe buffer holding the raw data to be processed
[in]pIndexPointer to the index within the buffer to marking the end of raw data available.
[out]pIncomingPacketStructure used to hold the fields of the incoming packet.
+
+
+
Returns
MQTTSuccess on successful extraction of type and length, MQTTBadParameter if pIncomingPacket is invalid, MQTTBadResponse if an invalid packet is read, and MQTTNoDataAvailable if there is nothing to read.
+ +
+
+
+
+ + + + diff --git a/latest/coreMQTT/core__mqtt__serializer_8h_source.html b/latest/coreMQTT/core__mqtt__serializer_8h_source.html new file mode 100644 index 00000000..a92c391c --- /dev/null +++ b/latest/coreMQTT/core__mqtt__serializer_8h_source.html @@ -0,0 +1,466 @@ + + + + + + + +coreMQTT: core_mqtt_serializer.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
core_mqtt_serializer.h
+
+
+Go to the documentation of this file.
1/*
+
2 * coreMQTT v2.3.1
+
3 * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
4 *
+
5 * SPDX-License-Identifier: MIT
+
6 *
+
7 * Permission is hereby granted, free of charge, to any person obtaining a copy of
+
8 * this software and associated documentation files (the "Software"), to deal in
+
9 * the Software without restriction, including without limitation the rights to
+
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
11 * the Software, and to permit persons to whom the Software is furnished to do so,
+
12 * subject to the following conditions:
+
13 *
+
14 * The above copyright notice and this permission notice shall be included in all
+
15 * copies or substantial portions of the Software.
+
16 *
+
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
23 */
+
24
+
32#ifndef CORE_MQTT_SERIALIZER_H
+
33#define CORE_MQTT_SERIALIZER_H
+
34
+
35#include <stddef.h>
+
36#include <stdint.h>
+
37#include <stdbool.h>
+
38
+
39/* *INDENT-OFF* */
+
40#ifdef __cplusplus
+
41 extern "C" {
+
42#endif
+
43/* *INDENT-ON */
+
44
+
45#include "transport_interface.h"
+
46
+
47/* MQTT packet types. */
+
48
+
53#define MQTT_PACKET_TYPE_CONNECT ( ( uint8_t ) 0x10U )
+
54#define MQTT_PACKET_TYPE_CONNACK ( ( uint8_t ) 0x20U )
+
55#define MQTT_PACKET_TYPE_PUBLISH ( ( uint8_t ) 0x30U )
+
56#define MQTT_PACKET_TYPE_PUBACK ( ( uint8_t ) 0x40U )
+
57#define MQTT_PACKET_TYPE_PUBREC ( ( uint8_t ) 0x50U )
+
58#define MQTT_PACKET_TYPE_PUBREL ( ( uint8_t ) 0x62U )
+
59#define MQTT_PACKET_TYPE_PUBCOMP ( ( uint8_t ) 0x70U )
+
60#define MQTT_PACKET_TYPE_SUBSCRIBE ( ( uint8_t ) 0x82U )
+
61#define MQTT_PACKET_TYPE_SUBACK ( ( uint8_t ) 0x90U )
+
62#define MQTT_PACKET_TYPE_UNSUBSCRIBE ( ( uint8_t ) 0xA2U )
+
63#define MQTT_PACKET_TYPE_UNSUBACK ( ( uint8_t ) 0xB0U )
+
64#define MQTT_PACKET_TYPE_PINGREQ ( ( uint8_t ) 0xC0U )
+
65#define MQTT_PACKET_TYPE_PINGRESP ( ( uint8_t ) 0xD0U )
+
66#define MQTT_PACKET_TYPE_DISCONNECT ( ( uint8_t ) 0xE0U )
+
73#define MQTT_PUBLISH_ACK_PACKET_SIZE ( 4UL )
+
74
+
75/* Structures defined in this file. */
+
76struct MQTTFixedBuffer;
+
77struct MQTTConnectInfo;
+
78struct MQTTSubscribeInfo;
+
79struct MQTTPublishInfo;
+
80struct MQTTPacketInfo;
+
81
+
86typedef enum MQTTStatus
+
87{
+ + + + + + + + + + + + + +
103
+
108typedef enum MQTTQoS
+
109{
+ + +
112 MQTTQoS2 = 2
+ +
114
+
122typedef struct MQTTFixedBuffer
+
123{
+
124 uint8_t * pBuffer;
+
125 size_t size;
+ +
127
+
132typedef struct MQTTConnectInfo
+
133{
+ +
138
+ +
143
+
147 const char * pClientIdentifier;
+
148
+ +
153
+
157 const char * pUserName;
+
158
+ +
163
+
167 const char * pPassword;
+
168
+ + +
174
+
179typedef struct MQTTSubscribeInfo
+
180{
+ +
185
+
189 const char * pTopicFilter;
+
190
+ + +
196
+
201typedef struct MQTTPublishInfo
+
202{
+ +
207
+
211 bool retain;
+
212
+
216 bool dup;
+
217
+
221 const char * pTopicName;
+
222
+ +
227
+
231 const void * pPayload;
+
232
+ + +
238
+
243typedef struct MQTTPacketInfo
+
244{
+
248 uint8_t type;
+
249
+
253 uint8_t * pRemainingData;
+
254
+ +
259
+ + +
265
+
313/* @[declare_mqtt_getconnectpacketsize] */
+ +
315 const MQTTPublishInfo_t * pWillInfo,
+
316 size_t * pRemainingLength,
+
317 size_t * pPacketSize );
+
318/* @[declare_mqtt_getconnectpacketsize] */
+
319
+
369/* @[declare_mqtt_serializeconnect] */
+ +
371 const MQTTPublishInfo_t * pWillInfo,
+
372 size_t remainingLength,
+
373 const MQTTFixedBuffer_t * pFixedBuffer );
+
374/* @[declare_mqtt_serializeconnect] */
+
375
+
427/* @[declare_mqtt_getsubscribepacketsize] */
+ +
429 size_t subscriptionCount,
+
430 size_t * pRemainingLength,
+
431 size_t * pPacketSize );
+
432/* @[declare_mqtt_getsubscribepacketsize] */
+
433
+
493/* @[declare_mqtt_serializesubscribe] */
+ +
495 size_t subscriptionCount,
+
496 uint16_t packetId,
+
497 size_t remainingLength,
+
498 const MQTTFixedBuffer_t * pFixedBuffer );
+
499/* @[declare_mqtt_serializesubscribe] */
+
500
+
544/* @[declare_mqtt_getunsubscribepacketsize] */
+ +
546 size_t subscriptionCount,
+
547 size_t * pRemainingLength,
+
548 size_t * pPacketSize );
+
549/* @[declare_mqtt_getunsubscribepacketsize] */
+
550
+
610/* @[declare_mqtt_serializeunsubscribe] */
+ +
612 size_t subscriptionCount,
+
613 uint16_t packetId,
+
614 size_t remainingLength,
+
615 const MQTTFixedBuffer_t * pFixedBuffer );
+
616/* @[declare_mqtt_serializeunsubscribe] */
+
617
+
664/* @[declare_mqtt_getpublishpacketsize] */
+ +
666 size_t * pRemainingLength,
+
667 size_t * pPacketSize );
+
668/* @[declare_mqtt_getpublishpacketsize] */
+
669
+
732/* @[declare_mqtt_serializepublish] */
+ +
734 uint16_t packetId,
+
735 size_t remainingLength,
+
736 const MQTTFixedBuffer_t * pFixedBuffer );
+
737/* @[declare_mqtt_serializepublish] */
+
738
+ +
753 size_t remainingLength,
+
754 uint8_t * pBuffer,
+
755 size_t * headerSize );
+
756
+
830/* @[declare_mqtt_serializepublishheader] */
+ +
832 uint16_t packetId,
+
833 size_t remainingLength,
+
834 const MQTTFixedBuffer_t * pFixedBuffer,
+
835 size_t * pHeaderSize );
+
836/* @[declare_mqtt_serializepublishheader] */
+
837
+
879/* @[declare_mqtt_serializeack] */
+ +
881 uint8_t packetType,
+
882 uint16_t packetId );
+
883/* @[declare_mqtt_serializeack] */
+
884
+
909/* @[declare_mqtt_getdisconnectpacketsize] */
+
910MQTTStatus_t MQTT_GetDisconnectPacketSize( size_t * pPacketSize );
+
911/* @[declare_mqtt_getdisconnectpacketsize] */
+
912
+
950/* @[declare_mqtt_serializedisconnect] */
+ +
952/* @[declare_mqtt_serializedisconnect] */
+
953
+
978/* @[declare_mqtt_getpingreqpacketsize] */
+
979MQTTStatus_t MQTT_GetPingreqPacketSize( size_t * pPacketSize );
+
980/* @[declare_mqtt_getpingreqpacketsize] */
+
981
+
1019/* @[declare_mqtt_serializepingreq] */
+ +
1021/* @[declare_mqtt_serializepingreq] */
+
1022
+
1080/* @[declare_mqtt_deserializepublish] */
+ +
1082 uint16_t * pPacketId,
+
1083 MQTTPublishInfo_t * pPublishInfo );
+
1084/* @[declare_mqtt_deserializepublish] */
+
1085
+
1124/* @[declare_mqtt_deserializeack] */
+
1125MQTTStatus_t MQTT_DeserializeAck( const MQTTPacketInfo_t * pIncomingPacket,
+
1126 uint16_t * pPacketId,
+
1127 bool * pSessionPresent );
+
1128/* @[declare_mqtt_deserializeack] */
+
1129
+
1190/* @[declare_mqtt_getincomingpackettypeandlength] */
+ +
1192 NetworkContext_t * pNetworkContext,
+
1193 MQTTPacketInfo_t * pIncomingPacket );
+
1194/* @[declare_mqtt_getincomingpackettypeandlength] */
+
1195
+
1214 /* @[declare_mqtt_processincomingpackettypeandlength] */
+ +
1216 const size_t * pIndex,
+
1217 MQTTPacketInfo_t * pIncomingPacket );
+
1218/* @[declare_mqtt_processincomingpackettypeandlength] */
+
1219
+
1238uint8_t * MQTT_SerializeConnectFixedHeader( uint8_t * pIndex,
+
1239 const MQTTConnectInfo_t * pConnectInfo,
+
1240 const MQTTPublishInfo_t * pWillInfo,
+
1241 size_t remainingLength );
+
1261uint8_t * MQTT_SerializeSubscribeHeader( size_t remainingLength,
+
1262 uint8_t * pIndex,
+
1263 uint16_t packetId );
+
1283uint8_t * MQTT_SerializeUnsubscribeHeader( size_t remainingLength,
+
1284 uint8_t * pIndex,
+
1285 uint16_t packetId );
+
1288/* *INDENT-OFF* */
+
1289#ifdef __cplusplus
+
1290 }
+
1291#endif
+
1292/* *INDENT-ON* */
+
1293
+
1294#endif /* ifndef CORE_MQTT_SERIALIZER_H */
+
uint8_t * MQTT_SerializeUnsubscribeHeader(size_t remainingLength, uint8_t *pIndex, uint16_t packetId)
Serialize the fixed part of the unsubscribe packet header.
Definition: core_mqtt_serializer.c:1910
+
uint8_t * MQTT_SerializeConnectFixedHeader(uint8_t *pIndex, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength)
Serialize the fixed part of the connect packet header.
Definition: core_mqtt_serializer.c:1553
+
uint8_t * MQTT_SerializeSubscribeHeader(size_t remainingLength, uint8_t *pIndex, uint16_t packetId)
Serialize the fixed part of the subscribe packet header.
Definition: core_mqtt_serializer.c:1886
+
MQTTStatus_t MQTT_GetPingreqPacketSize(size_t *pPacketSize)
Get the size of an MQTT PINGREQ packet.
Definition: core_mqtt_serializer.c:2384
+
MQTTStatus_t MQTT_SerializeAck(const MQTTFixedBuffer_t *pFixedBuffer, uint8_t packetType, uint16_t packetId)
Serialize an MQTT PUBACK, PUBREC, PUBREL, or PUBCOMP into the given buffer.
Definition: core_mqtt_serializer.c:2266
+
MQTTStatus_t MQTT_SerializeSubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT SUBSCRIBE packet in the given buffer.
Definition: core_mqtt_serializer.c:1932
+
MQTTStatus_t MQTT_GetUnsubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.
Definition: core_mqtt_serializer.c:1978
+
MQTTStatus_t MQTT_SerializePublishHeaderWithoutTopic(const MQTTPublishInfo_t *pPublishInfo, size_t remainingLength, uint8_t *pBuffer, size_t *headerSize)
Serialize an MQTT PUBLISH packet header without the topic string in the given buffer....
Definition: core_mqtt_serializer.c:636
+
MQTTStatus_t MQTT_DeserializePublish(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo)
Deserialize an MQTT PUBLISH packet.
Definition: core_mqtt_serializer.c:2447
+
MQTTStatus_t MQTT_GetConnectPacketSize(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the size and Remaining Length of an MQTT CONNECT packet.
Definition: core_mqtt_serializer.c:1690
+
MQTTStatus_t MQTT_SerializePublishHeader(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer, size_t *pHeaderSize)
Serialize an MQTT PUBLISH packet header in the given buffer.
Definition: core_mqtt_serializer.c:2183
+
MQTTStatus_t MQTT_SerializeDisconnect(const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT DISCONNECT packet into the given buffer.
Definition: core_mqtt_serializer.c:2341
+
MQTTStatus_t MQTT_GetDisconnectPacketSize(size_t *pPacketSize)
Get the size of an MQTT DISCONNECT packet.
Definition: core_mqtt_serializer.c:2321
+
MQTTStatus_t MQTT_ProcessIncomingPacketTypeAndLength(const uint8_t *pBuffer, const size_t *pIndex, MQTTPacketInfo_t *pIncomingPacket)
Extract the MQTT packet type and length from incoming packet.
Definition: core_mqtt_serializer.c:2626
+
MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength(TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket)
Extract the MQTT packet type and length from incoming packet.
Definition: core_mqtt_serializer.c:2561
+
MQTTStatus_t MQTT_GetPublishPacketSize(const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the packet size and remaining length of an MQTT PUBLISH packet.
Definition: core_mqtt_serializer.c:2057
+
MQTTStatus_t MQTT_SerializeConnect(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT CONNECT packet in the given fixed buffer pFixedBuffer.
Definition: core_mqtt_serializer.c:1790
+
MQTTStatus_t MQTT_SerializeUnsubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT UNSUBSCRIBE packet in the given buffer.
Definition: core_mqtt_serializer.c:2016
+
MQTTStatus_t MQTT_GetSubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.
Definition: core_mqtt_serializer.c:1848
+
MQTTStatus_t MQTT_SerializePublish(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT PUBLISH packet in the given buffer.
Definition: core_mqtt_serializer.c:2098
+
MQTTStatus_t MQTT_DeserializeAck(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, bool *pSessionPresent)
Deserialize an MQTT CONNACK, SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, PUBCOMP, or PINGRESP.
Definition: core_mqtt_serializer.c:2484
+
MQTTStatus_t MQTT_SerializePingreq(const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT PINGREQ packet into the given buffer.
Definition: core_mqtt_serializer.c:2404
+
int32_t(* TransportRecv_t)(NetworkContext_t *pNetworkContext, void *pBuffer, size_t bytesToRecv)
Transport interface for receiving data on the network.
Definition: transport_interface.h:218
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTTQoS_t
MQTT Quality of Service values.
Definition: core_mqtt_serializer.h:109
+
@ MQTTKeepAliveTimeout
Definition: core_mqtt_serializer.h:98
+
@ MQTTServerRefused
Definition: core_mqtt_serializer.h:94
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
@ MQTTNoDataAvailable
Definition: core_mqtt_serializer.h:95
+
@ MQTTIllegalState
Definition: core_mqtt_serializer.h:96
+
@ MQTTStateCollision
Definition: core_mqtt_serializer.h:97
+
@ MQTTRecvFailed
Definition: core_mqtt_serializer.h:92
+
@ MQTTBadParameter
Definition: core_mqtt_serializer.h:89
+
@ MQTTBadResponse
Definition: core_mqtt_serializer.h:93
+
@ MQTTNeedMoreBytes
Definition: core_mqtt_serializer.h:99
+
@ MQTTNoMemory
Definition: core_mqtt_serializer.h:90
+
@ MQTTSendFailed
Definition: core_mqtt_serializer.h:91
+
@ MQTTQoS1
Definition: core_mqtt_serializer.h:111
+
@ MQTTQoS2
Definition: core_mqtt_serializer.h:112
+
@ MQTTQoS0
Definition: core_mqtt_serializer.h:110
+
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
const char * pClientIdentifier
MQTT client identifier. Must be unique per client.
Definition: core_mqtt_serializer.h:147
+
const char * pUserName
MQTT user name. Set to NULL if not used.
Definition: core_mqtt_serializer.h:157
+
bool cleanSession
Whether to establish a new, clean session or resume a previous session.
Definition: core_mqtt_serializer.h:137
+
uint16_t userNameLength
Length of MQTT user name. Set to 0 if not used.
Definition: core_mqtt_serializer.h:162
+
uint16_t keepAliveSeconds
MQTT keep alive period.
Definition: core_mqtt_serializer.h:142
+
uint16_t clientIdentifierLength
Length of the client identifier.
Definition: core_mqtt_serializer.h:152
+
uint16_t passwordLength
Length of MQTT password. Set to 0 if not used.
Definition: core_mqtt_serializer.h:172
+
const char * pPassword
MQTT password. Set to NULL if not used.
Definition: core_mqtt_serializer.h:167
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+
size_t remainingLength
Length of remaining serialized data.
Definition: core_mqtt_serializer.h:258
+
uint8_t type
Type of incoming MQTT packet.
Definition: core_mqtt_serializer.h:248
+
size_t headerLength
The length of the MQTT header including the type and length.
Definition: core_mqtt_serializer.h:263
+
uint8_t * pRemainingData
Remaining serialized data in the MQTT packet.
Definition: core_mqtt_serializer.h:253
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+
MQTTQoS_t qos
Quality of Service for message.
Definition: core_mqtt_serializer.h:206
+
bool retain
Whether this is a retained message.
Definition: core_mqtt_serializer.h:211
+
uint16_t topicNameLength
Length of topic name.
Definition: core_mqtt_serializer.h:226
+
size_t payloadLength
Message payload length.
Definition: core_mqtt_serializer.h:236
+
bool dup
Whether this is a duplicate publish message.
Definition: core_mqtt_serializer.h:216
+
const char * pTopicName
Topic name on which the message is published.
Definition: core_mqtt_serializer.h:221
+
const void * pPayload
Message payload.
Definition: core_mqtt_serializer.h:231
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+
MQTTQoS_t qos
Quality of Service for subscription.
Definition: core_mqtt_serializer.h:184
+
uint16_t topicFilterLength
Length of subscription topic filter.
Definition: core_mqtt_serializer.h:194
+
const char * pTopicFilter
Topic filter to subscribe to.
Definition: core_mqtt_serializer.h:189
+
Transport interface definitions to send and receive data over the network.
+
+
+ + + + diff --git a/latest/coreMQTT/core__mqtt__state_8c.html b/latest/coreMQTT/core__mqtt__state_8c.html new file mode 100644 index 00000000..bac03e9c --- /dev/null +++ b/latest/coreMQTT/core__mqtt__state_8c.html @@ -0,0 +1,1371 @@ + + + + + + + +coreMQTT: core_mqtt_state.c File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_state.c File Reference
+
+
+ +

Implements the functions in core_mqtt_state.h. +More...

+
#include <assert.h>
+#include <string.h>
+#include "core_mqtt_state.h"
+#include "core_mqtt_config_defaults.h"
+
+ + + + + + + + + + + + + +

+Macros

+#define MQTT_INVALID_STATE_COUNT   ( ~ZERO_SIZE_T )
 This macro depicts the invalid value for the state publishes.
 
#define UINT16_BITMAP_BIT_SET_AT(position)   ( ( uint16_t ) 0x01U << ( ( uint16_t ) position ) )
 Create a 16-bit bitmap with bit set at specified position.
 
#define UINT16_SET_BIT(x, position)   ( ( x ) = ( uint16_t ) ( ( x ) | ( UINT16_BITMAP_BIT_SET_AT( position ) ) ) )
 Set a bit in an 16-bit unsigned integer.
 
#define UINT16_CHECK_BIT(x, position)   ( ( ( x ) & ( UINT16_BITMAP_BIT_SET_AT( position ) ) ) == ( UINT16_BITMAP_BIT_SET_AT( position ) ) )
 Macro for checking if a bit is set in a 16-bit unsigned integer.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

static bool validateTransitionPublish (MQTTPublishState_t currentState, MQTTPublishState_t newState, MQTTStateOperation_t opType, MQTTQoS_t qos)
 Test if a transition to new state is possible, when dealing with PUBLISHes.
 
static bool validateTransitionAck (MQTTPublishState_t currentState, MQTTPublishState_t newState)
 Test if a transition to a new state is possible, when dealing with acks.
 
static bool isPublishOutgoing (MQTTPubAckType_t packetType, MQTTStateOperation_t opType)
 Test if the publish corresponding to an ack is outgoing or incoming.
 
static size_t findInRecord (const MQTTPubAckInfo_t *records, size_t recordCount, uint16_t packetId, MQTTQoS_t *pQos, MQTTPublishState_t *pCurrentState)
 Find a packet ID in the state record.
 
static void compactRecords (MQTTPubAckInfo_t *records, size_t recordCount)
 Compact records.
 
static MQTTStatus_t addRecord (MQTTPubAckInfo_t *records, size_t recordCount, uint16_t packetId, MQTTQoS_t qos, MQTTPublishState_t publishState)
 Store a new entry in the state record.
 
static void updateRecord (MQTTPubAckInfo_t *records, size_t recordIndex, MQTTPublishState_t newState, bool shouldDelete)
 Update and possibly delete an entry in the state record.
 
static uint16_t stateSelect (const MQTTContext_t *pMqttContext, uint16_t searchStates, MQTTStateCursor_t *pCursor)
 Get the packet ID and index of an outgoing publish in specified states.
 
static MQTTStatus_t updateStateAck (MQTTPubAckInfo_t *records, size_t maxRecordCount, size_t recordIndex, uint16_t packetId, MQTTPublishState_t currentState, MQTTPublishState_t newState)
 Update the state records for an ACK after state transition validations.
 
static MQTTStatus_t updateStatePublish (const MQTTContext_t *pMqttContext, size_t recordIndex, uint16_t packetId, MQTTStateOperation_t opType, MQTTQoS_t qos, MQTTPublishState_t currentState, MQTTPublishState_t newState)
 Update the state record for a PUBLISH packet after validating the state transitions.
 
MQTTPublishState_t MQTT_CalculateStateAck (MQTTPubAckType_t packetType, MQTTStateOperation_t opType, MQTTQoS_t qos)
 Calculate the state from a PUBACK, PUBREC, PUBREL, or PUBCOMP.
 
MQTTStatus_t MQTT_ReserveState (const MQTTContext_t *pMqttContext, uint16_t packetId, MQTTQoS_t qos)
 Reserve an entry for an outgoing QoS 1 or Qos 2 publish.
 
MQTTPublishState_t MQTT_CalculateStatePublish (MQTTStateOperation_t opType, MQTTQoS_t qos)
 Calculate the new state for a publish from its qos and operation type.
 
MQTTStatus_t MQTT_UpdateStatePublish (const MQTTContext_t *pMqttContext, uint16_t packetId, MQTTStateOperation_t opType, MQTTQoS_t qos, MQTTPublishState_t *pNewState)
 Update the state record for a PUBLISH packet.
 
MQTTStatus_t MQTT_RemoveStateRecord (const MQTTContext_t *pMqttContext, uint16_t packetId)
 Remove the state record for a PUBLISH packet.
 
MQTTStatus_t MQTT_UpdateStateAck (const MQTTContext_t *pMqttContext, uint16_t packetId, MQTTPubAckType_t packetType, MQTTStateOperation_t opType, MQTTPublishState_t *pNewState)
 Update the state record for an ACKed publish.
 
uint16_t MQTT_PubrelToResend (const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor, MQTTPublishState_t *pState)
 Get the packet ID of next pending PUBREL ack to be resent.
 
uint16_t MQTT_PublishToResend (const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor)
 Get the packet ID of next pending publish to be resent.
 
const char * MQTT_State_strerror (MQTTPublishState_t state)
 State to string conversion for state engine.
 
+ + + + +

+Variables

+static const size_t ZERO_SIZE_T = 0U
 A global static variable used to generate the macro MQTT_INVALID_STATE_COUNT of size_t length.
 
+

Detailed Description

+

Implements the functions in core_mqtt_state.h.

+

Macro Definition Documentation

+ +

◆ UINT16_BITMAP_BIT_SET_AT

+ +
+
+ + + + + + + + +
#define UINT16_BITMAP_BIT_SET_AT( position)   ( ( uint16_t ) 0x01U << ( ( uint16_t ) position ) )
+
+ +

Create a 16-bit bitmap with bit set at specified position.

+
Parameters
+ + +
[in]positionThe position at which the bit need to be set.
+
+
+ +
+
+ +

◆ UINT16_SET_BIT

+ +
+
+ + + + + + + + + + + + + + + + + + +
#define UINT16_SET_BIT( x,
 position 
)   ( ( x ) = ( uint16_t ) ( ( x ) | ( UINT16_BITMAP_BIT_SET_AT( position ) ) ) )
+
+ +

Set a bit in an 16-bit unsigned integer.

+
Parameters
+ + + +
[in]xThe 16-bit unsigned integer to set a bit.
[in]positionThe position at which the bit need to be set.
+
+
+ +
+
+ +

◆ UINT16_CHECK_BIT

+ +
+
+ + + + + + + + + + + + + + + + + + +
#define UINT16_CHECK_BIT( x,
 position 
)   ( ( ( x ) & ( UINT16_BITMAP_BIT_SET_AT( position ) ) ) == ( UINT16_BITMAP_BIT_SET_AT( position ) ) )
+
+ +

Macro for checking if a bit is set in a 16-bit unsigned integer.

+
Parameters
+ + + +
[in]xThe unsigned 16-bit integer to check.
[in]positionWhich bit to check.
+
+
+ +
+
+

Function Documentation

+ +

◆ validateTransitionPublish()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static bool validateTransitionPublish (MQTTPublishState_t currentState,
MQTTPublishState_t newState,
MQTTStateOperation_t opType,
MQTTQoS_t qos 
)
+
+static
+
+ +

Test if a transition to new state is possible, when dealing with PUBLISHes.

+
Parameters
+ + + + + +
[in]currentStateThe current state.
[in]newStateState to transition to.
[in]opTypeReserve, Send, or Receive.
[in]qos0, 1, or 2.
+
+
+
Note
This function does not validate the current state, or the new state based on either the operation type or QoS. It assumes the new state is valid given the opType and QoS, which will be the case if calculated by MQTT_CalculateStatePublish().
+
Returns
true if transition is possible, else false
+ +
+
+ +

◆ validateTransitionAck()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static bool validateTransitionAck (MQTTPublishState_t currentState,
MQTTPublishState_t newState 
)
+
+static
+
+ +

Test if a transition to a new state is possible, when dealing with acks.

+
Parameters
+ + + +
[in]currentStateThe current state.
[in]newStateState to transition to.
+
+
+
Returns
true if transition is possible, else false.
+ +
+
+ +

◆ isPublishOutgoing()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static bool isPublishOutgoing (MQTTPubAckType_t packetType,
MQTTStateOperation_t opType 
)
+
+static
+
+ +

Test if the publish corresponding to an ack is outgoing or incoming.

+
Parameters
+ + + +
[in]packetTypePUBACK, PUBREC, PUBREL, or PUBCOMP.
[in]opTypeSend, or Receive.
+
+
+
Returns
true if corresponds to outgoing publish, else false.
+ +
+
+ +

◆ findInRecord()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static size_t findInRecord (const MQTTPubAckInfo_trecords,
size_t recordCount,
uint16_t packetId,
MQTTQoS_tpQos,
MQTTPublishState_tpCurrentState 
)
+
+static
+
+ +

Find a packet ID in the state record.

+
Parameters
+ + + + + + +
[in]recordsState record array.
[in]recordCountLength of record array.
[in]packetIdpacket ID to search for.
[out]pQosQoS retrieved from record.
[out]pCurrentStatestate retrieved from record.
+
+
+
Returns
index of the packet id in the record if it exists, else the record length.
+ +
+
+ +

◆ compactRecords()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static void compactRecords (MQTTPubAckInfo_trecords,
size_t recordCount 
)
+
+static
+
+ +

Compact records.

+

Records are arranged in the relative order to maintain message ordering. This will lead to fragmentation and this function will help in defragmenting the records array.

+
Parameters
+ + + +
[in]recordsState record array.
[in]recordCountLength of record array.
+
+
+ +
+
+ +

◆ addRecord()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t addRecord (MQTTPubAckInfo_trecords,
size_t recordCount,
uint16_t packetId,
MQTTQoS_t qos,
MQTTPublishState_t publishState 
)
+
+static
+
+ +

Store a new entry in the state record.

+
Parameters
+ + + + + + +
[in]recordsState record array.
[in]recordCountLength of record array.
[in]packetIdPacket ID of new entry.
[in]qosQoS of new entry.
[in]publishStateState of new entry.
+
+
+
Returns
MQTTSuccess, MQTTNoMemory, or MQTTStateCollision.
+ +
+
+ +

◆ updateRecord()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static void updateRecord (MQTTPubAckInfo_trecords,
size_t recordIndex,
MQTTPublishState_t newState,
bool shouldDelete 
)
+
+static
+
+ +

Update and possibly delete an entry in the state record.

+
Parameters
+ + + + + +
[in]recordsState record array.
[in]recordIndexindex of record to update.
[in]newStateNew state to update.
[in]shouldDeleteWhether an existing entry should be deleted.
+
+
+ +
+
+ +

◆ stateSelect()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static uint16_t stateSelect (const MQTTContext_tpMqttContext,
uint16_t searchStates,
MQTTStateCursor_tpCursor 
)
+
+static
+
+ +

Get the packet ID and index of an outgoing publish in specified states.

+
Parameters
+ + + + +
[in]pMqttContextInitialized MQTT context.
[in]searchStatesThe states to search for in 2-byte bit map.
[in,out]pCursorIndex at which to start searching.
+
+
+
Returns
Packet ID of the outgoing publish.
+ +
+
+ +

◆ updateStateAck()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t updateStateAck (MQTTPubAckInfo_trecords,
size_t maxRecordCount,
size_t recordIndex,
uint16_t packetId,
MQTTPublishState_t currentState,
MQTTPublishState_t newState 
)
+
+static
+
+ +

Update the state records for an ACK after state transition validations.

+
Parameters
+ + + + + + + +
[in]recordsState records pointer.
[in]maxRecordCountThe maximum number of records.
[in]recordIndexIndex at which the record is stored.
[in]packetIdPacket id of the packet.
[in]currentStateCurrent state of the publish record.
[in]newStateNew state of the publish.
+
+
+
Returns
MQTTIllegalState, or MQTTSuccess.
+ +
+
+ +

◆ updateStatePublish()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t updateStatePublish (const MQTTContext_tpMqttContext,
size_t recordIndex,
uint16_t packetId,
MQTTStateOperation_t opType,
MQTTQoS_t qos,
MQTTPublishState_t currentState,
MQTTPublishState_t newState 
)
+
+static
+
+ +

Update the state record for a PUBLISH packet after validating the state transitions.

+
Parameters
+ + + + + + + + +
[in]pMqttContextInitialized MQTT context.
[in]recordIndexIndex in state records at which publish record exists.
[in]packetIdID of the PUBLISH packet.
[in]opTypeSend or Receive.
[in]qos0, 1, or 2.
[in]currentStateCurrent state of the publish record.
[in]newStateNew state of the publish record.
+
+
+
Returns
MQTTIllegalState, MQTTStateCollision or MQTTSuccess.
+ +
+
+ +

◆ MQTT_CalculateStateAck()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTPublishState_t MQTT_CalculateStateAck (MQTTPubAckType_t packetType,
MQTTStateOperation_t opType,
MQTTQoS_t qos 
)
+
+ +

Calculate the state from a PUBACK, PUBREC, PUBREL, or PUBCOMP.

+
Parameters
+ + + + +
[in]packetTypePUBACK, PUBREC, PUBREL, or PUBCOMP.
[in]opTypeSend or Receive.
[in]qos1 or 2.
+
+
+
Returns
The calculated state.
+ +
+
+ +

◆ MQTT_ReserveState()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_ReserveState (const MQTTContext_tpMqttContext,
uint16_t packetId,
MQTTQoS_t qos 
)
+
+ +

Reserve an entry for an outgoing QoS 1 or Qos 2 publish.

+
Parameters
+ + + + +
[in]pMqttContextInitialized MQTT context.
[in]packetIdThe ID of the publish packet.
[in]qos1 or 2.
+
+
+
Returns
MQTTSuccess, MQTTNoMemory, or MQTTStateCollision.
+ +
+
+ +

◆ MQTT_CalculateStatePublish()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTPublishState_t MQTT_CalculateStatePublish (MQTTStateOperation_t opType,
MQTTQoS_t qos 
)
+
+ +

Calculate the new state for a publish from its qos and operation type.

+
Parameters
+ + + +
[in]opTypeSend or Receive.
[in]qos0, 1, or 2.
+
+
+
Returns
The calculated state.
+ +
+
+ +

◆ MQTT_UpdateStatePublish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_UpdateStatePublish (const MQTTContext_tpMqttContext,
uint16_t packetId,
MQTTStateOperation_t opType,
MQTTQoS_t qos,
MQTTPublishState_tpNewState 
)
+
+ +

Update the state record for a PUBLISH packet.

+
Parameters
+ + + + + + +
[in]pMqttContextInitialized MQTT context.
[in]packetIdID of the PUBLISH packet.
[in]opTypeSend or Receive.
[in]qos0, 1, or 2.
[out]pNewStateUpdated state of the publish.
+
+
+
Returns
MQTTBadParameter, MQTTIllegalState, MQTTStateCollision or MQTTSuccess.
+ +
+
+ +

◆ MQTT_RemoveStateRecord()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_RemoveStateRecord (const MQTTContext_tpMqttContext,
uint16_t packetId 
)
+
+ +

Remove the state record for a PUBLISH packet.

+
Parameters
+ + + +
[in]pMqttContextInitialized MQTT context.
[in]packetIdID of the PUBLISH packet.
+
+
+
Returns
MQTTBadParameter or MQTTSuccess.
+ +
+
+ +

◆ MQTT_UpdateStateAck()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_UpdateStateAck (const MQTTContext_tpMqttContext,
uint16_t packetId,
MQTTPubAckType_t packetType,
MQTTStateOperation_t opType,
MQTTPublishState_tpNewState 
)
+
+ +

Update the state record for an ACKed publish.

+
Parameters
+ + + + + + +
[in]pMqttContextInitialized MQTT context.
[in]packetIdID of the ack packet.
[in]packetTypePUBACK, PUBREC, PUBREL, or PUBCOMP.
[in]opTypeSend or Receive.
[out]pNewStateUpdated state of the publish.
+
+
+
Returns
MQTTBadParameter if an invalid parameter is passed; MQTTBadResponse if the packet from the network is not found in the records; MQTTIllegalState if the requested update would result in an illegal transition; MQTTSuccess otherwise.
+ +
+
+ +

◆ MQTT_PubrelToResend()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t MQTT_PubrelToResend (const MQTTContext_tpMqttContext,
MQTTStateCursor_tpCursor,
MQTTPublishState_tpState 
)
+
+ +

Get the packet ID of next pending PUBREL ack to be resent.

+

This function will need to be called to get the packet for which a PUBREL need to be sent when a session is reestablished. Calling this function repeatedly until packet id is 0 will give all the packets for which a PUBREL need to be resent in the correct order.

+
Parameters
+ + + + +
[in]pMqttContextInitialized MQTT context.
[in,out]pCursorIndex at which to start searching.
[out]pStateState indicating that PUBREL packet need to be sent.
+
+
+ +
+
+ +

◆ MQTT_PublishToResend()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint16_t MQTT_PublishToResend (const MQTTContext_tpMqttContext,
MQTTStateCursor_tpCursor 
)
+
+ +

Get the packet ID of next pending publish to be resent.

+

This function will need to be called to get the packet for which a publish need to be sent when a session is reestablished. Calling this function repeatedly until packet id is 0 will give all the packets for which a publish need to be resent in the correct order.

+
Parameters
+ + + +
[in]pMqttContextInitialized MQTT context.
[in,out]pCursorIndex at which to start searching.
+
+
+

Example

// For this example assume this function returns an outgoing unacknowledged
+
// QoS 1 or 2 publish from its packet identifier.
+
MQTTPublishInfo_t * getPublish( uint16_t packetID );
+
+
// Variables used in this example.
+
MQTTStatus_t status;
+ +
bool sessionPresent;
+
uint16_t packetID;
+
MQTTPublishInfo_t * pResendPublish = NULL;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
+
// This is assumed to have been initialized before the call to MQTT_Connect().
+
MQTTContext_t * pContext;
+
+
// Set clean session to false to attempt session resumption.
+
connectInfo.cleanSession = false;
+
connectInfo.pClientIdentifier = "someClientID";
+
connectInfo.clientIdentifierLength = strlen( connectInfo.pClientIdentifier );
+
connectInfo.keepAliveSeconds = 60;
+
// Optional connect parameters are not relevant to this example.
+
+
// Create an MQTT connection. Use 100 milliseconds as a timeout.
+
status = MQTT_Connect( pContext, &connectInfo, NULL, 100, &sessionPresent );
+
+
if( status == MQTTSuccess )
+
{
+
if( sessionPresent )
+
{
+
// Loop while packet ID is nonzero.
+
while( ( packetID = MQTT_PublishToResend( pContext, &cursor ) ) != 0 )
+
{
+
// Assume this function will succeed.
+
pResendPublish = getPublish( packetID );
+
// Set DUP flag.
+
pResendPublish->dup = true;
+
status = MQTT_Publish( pContext, pResendPublish, packetID );
+
+
if( status != MQTTSuccess )
+
{
+
// Application can decide how to handle a failure.
+
}
+
}
+
}
+
else
+
{
+
// The broker did not resume a session, so we can clean up the
+
// list of outgoing publishes.
+
}
+
}
+
MQTTStatus_t MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId)
Publishes a message to the given topic name.
Definition: core_mqtt.c:2805
+
MQTTStatus_t MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
Establish an MQTT session.
Definition: core_mqtt.c:2679
+
uint16_t MQTT_PublishToResend(const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor)
Get the packet ID of next pending publish to be resent.
Definition: core_mqtt_state.c:1123
+
size_t MQTTStateCursor_t
Cursor for iterating through state records.
Definition: core_mqtt_state.h:51
+
#define MQTT_STATE_CURSOR_INITIALIZER
Initializer value for an MQTTStateCursor_t, indicating a search should start at the beginning of a st...
Definition: core_mqtt_state.h:45
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
const char * pClientIdentifier
MQTT client identifier. Must be unique per client.
Definition: core_mqtt_serializer.h:147
+
bool cleanSession
Whether to establish a new, clean session or resume a previous session.
Definition: core_mqtt_serializer.h:137
+
uint16_t keepAliveSeconds
MQTT keep alive period.
Definition: core_mqtt_serializer.h:142
+
uint16_t clientIdentifierLength
Length of the client identifier.
Definition: core_mqtt_serializer.h:152
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+
bool dup
Whether this is a duplicate publish message.
Definition: core_mqtt_serializer.h:216
+
+
+
+ +

◆ MQTT_State_strerror()

+ +
+
+ + + + + + + + +
const char * MQTT_State_strerror (MQTTPublishState_t state)
+
+ +

State to string conversion for state engine.

+
Parameters
+ + +
[in]stateThe state to convert to a string.
+
+
+
Returns
The string representation of the state.
+ +
+
+
+
+ + + + diff --git a/latest/coreMQTT/core__mqtt__state_8h.html b/latest/coreMQTT/core__mqtt__state_8h.html new file mode 100644 index 00000000..519bc936 --- /dev/null +++ b/latest/coreMQTT/core__mqtt__state_8h.html @@ -0,0 +1,250 @@ + + + + + + + +coreMQTT: core_mqtt_state.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_state.h File Reference
+
+
+ +

Function to keep state of MQTT PUBLISH packet deliveries. +More...

+
#include "core_mqtt.h"
+
+

Go to the source code of this file.

+ + + + + +

+Macros

+#define MQTT_STATE_CURSOR_INITIALIZER   ( ( size_t ) 0 )
 Initializer value for an MQTTStateCursor_t, indicating a search should start at the beginning of a state record array.
 
+ + + + +

+Typedefs

+typedef size_t MQTTStateCursor_t
 Cursor for iterating through state records.
 
+ + + + +

+Functions

uint16_t MQTT_PublishToResend (const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor)
 Get the packet ID of next pending publish to be resent.
 
+

Detailed Description

+

Function to keep state of MQTT PUBLISH packet deliveries.

+

Function Documentation

+ +

◆ MQTT_PublishToResend()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint16_t MQTT_PublishToResend (const MQTTContext_tpMqttContext,
MQTTStateCursor_tpCursor 
)
+
+ +

Get the packet ID of next pending publish to be resent.

+

This function will need to be called to get the packet for which a publish need to be sent when a session is reestablished. Calling this function repeatedly until packet id is 0 will give all the packets for which a publish need to be resent in the correct order.

+
Parameters
+ + + +
[in]pMqttContextInitialized MQTT context.
[in,out]pCursorIndex at which to start searching.
+
+
+

Example

// For this example assume this function returns an outgoing unacknowledged
+
// QoS 1 or 2 publish from its packet identifier.
+
MQTTPublishInfo_t * getPublish( uint16_t packetID );
+
+
// Variables used in this example.
+
MQTTStatus_t status;
+ +
bool sessionPresent;
+
uint16_t packetID;
+
MQTTPublishInfo_t * pResendPublish = NULL;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
+
// This is assumed to have been initialized before the call to MQTT_Connect().
+
MQTTContext_t * pContext;
+
+
// Set clean session to false to attempt session resumption.
+
connectInfo.cleanSession = false;
+
connectInfo.pClientIdentifier = "someClientID";
+
connectInfo.clientIdentifierLength = strlen( connectInfo.pClientIdentifier );
+
connectInfo.keepAliveSeconds = 60;
+
// Optional connect parameters are not relevant to this example.
+
+
// Create an MQTT connection. Use 100 milliseconds as a timeout.
+
status = MQTT_Connect( pContext, &connectInfo, NULL, 100, &sessionPresent );
+
+
if( status == MQTTSuccess )
+
{
+
if( sessionPresent )
+
{
+
// Loop while packet ID is nonzero.
+
while( ( packetID = MQTT_PublishToResend( pContext, &cursor ) ) != 0 )
+
{
+
// Assume this function will succeed.
+
pResendPublish = getPublish( packetID );
+
// Set DUP flag.
+
pResendPublish->dup = true;
+
status = MQTT_Publish( pContext, pResendPublish, packetID );
+
+
if( status != MQTTSuccess )
+
{
+
// Application can decide how to handle a failure.
+
}
+
}
+
}
+
else
+
{
+
// The broker did not resume a session, so we can clean up the
+
// list of outgoing publishes.
+
}
+
}
+
MQTTStatus_t MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId)
Publishes a message to the given topic name.
Definition: core_mqtt.c:2805
+
MQTTStatus_t MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
Establish an MQTT session.
Definition: core_mqtt.c:2679
+
uint16_t MQTT_PublishToResend(const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor)
Get the packet ID of next pending publish to be resent.
Definition: core_mqtt_state.c:1123
+
size_t MQTTStateCursor_t
Cursor for iterating through state records.
Definition: core_mqtt_state.h:51
+
#define MQTT_STATE_CURSOR_INITIALIZER
Initializer value for an MQTTStateCursor_t, indicating a search should start at the beginning of a st...
Definition: core_mqtt_state.h:45
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
const char * pClientIdentifier
MQTT client identifier. Must be unique per client.
Definition: core_mqtt_serializer.h:147
+
bool cleanSession
Whether to establish a new, clean session or resume a previous session.
Definition: core_mqtt_serializer.h:137
+
uint16_t keepAliveSeconds
MQTT keep alive period.
Definition: core_mqtt_serializer.h:142
+
uint16_t clientIdentifierLength
Length of the client identifier.
Definition: core_mqtt_serializer.h:152
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+
bool dup
Whether this is a duplicate publish message.
Definition: core_mqtt_serializer.h:216
+
+
+
+
+
+ + + + diff --git a/latest/coreMQTT/core__mqtt__state_8h_source.html b/latest/coreMQTT/core__mqtt__state_8h_source.html new file mode 100644 index 00000000..e6d516bf --- /dev/null +++ b/latest/coreMQTT/core__mqtt__state_8h_source.html @@ -0,0 +1,209 @@ + + + + + + + +coreMQTT: core_mqtt_state.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
core_mqtt_state.h
+
+
+Go to the documentation of this file.
1/*
+
2 * coreMQTT v2.3.1
+
3 * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
4 *
+
5 * SPDX-License-Identifier: MIT
+
6 *
+
7 * Permission is hereby granted, free of charge, to any person obtaining a copy of
+
8 * this software and associated documentation files (the "Software"), to deal in
+
9 * the Software without restriction, including without limitation the rights to
+
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
11 * the Software, and to permit persons to whom the Software is furnished to do so,
+
12 * subject to the following conditions:
+
13 *
+
14 * The above copyright notice and this permission notice shall be included in all
+
15 * copies or substantial portions of the Software.
+
16 *
+
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
23 */
+
24
+
29#ifndef CORE_MQTT_STATE_H
+
30#define CORE_MQTT_STATE_H
+
31
+
32/* *INDENT-OFF* */
+
33#ifdef __cplusplus
+
34 extern "C" {
+
35#endif
+
36/* *INDENT-ON* */
+
37
+
38#include "core_mqtt.h"
+
39
+
45#define MQTT_STATE_CURSOR_INITIALIZER ( ( size_t ) 0 )
+
46
+
51typedef size_t MQTTStateCursor_t;
+
52
+
59typedef enum MQTTStateOperation
+
60{
+
61 MQTT_SEND,
+
62 MQTT_RECEIVE
+
63} MQTTStateOperation_t;
+
81MQTTStatus_t MQTT_ReserveState( const MQTTContext_t * pMqttContext,
+
82 uint16_t packetId,
+
83 MQTTQoS_t qos );
+
100MQTTPublishState_t MQTT_CalculateStatePublish( MQTTStateOperation_t opType,
+
101 MQTTQoS_t qos );
+ +
123 uint16_t packetId,
+
124 MQTTStateOperation_t opType,
+
125 MQTTQoS_t qos,
+
126 MQTTPublishState_t * pNewState );
+ +
144 uint16_t packetId );
+ +
163 MQTTStateOperation_t opType,
+
164 MQTTQoS_t qos );
+ +
188 uint16_t packetId,
+
189 MQTTPubAckType_t packetType,
+
190 MQTTStateOperation_t opType,
+
191 MQTTPublishState_t * pNewState );
+
212uint16_t MQTT_PubrelToResend( const MQTTContext_t * pMqttContext,
+
213 MQTTStateCursor_t * pCursor,
+
214 MQTTPublishState_t * pState );
+
283/* @[declare_mqtt_publishtoresend] */
+
284uint16_t MQTT_PublishToResend( const MQTTContext_t * pMqttContext,
+
285 MQTTStateCursor_t * pCursor );
+
286/* @[declare_mqtt_publishtoresend] */
+
287
+
301const char * MQTT_State_strerror( MQTTPublishState_t state );
+
304/* *INDENT-OFF* */
+
305#ifdef __cplusplus
+
306 }
+
307#endif
+
308/* *INDENT-ON* */
+
309
+
310#endif /* ifndef CORE_MQTT_STATE_H */
+
User-facing functions of the MQTT 3.1.1 library.
+
MQTTStatus_t MQTT_UpdateStateAck(const MQTTContext_t *pMqttContext, uint16_t packetId, MQTTPubAckType_t packetType, MQTTStateOperation_t opType, MQTTPublishState_t *pNewState)
Update the state record for an ACKed publish.
Definition: core_mqtt_state.c:1005
+
MQTTPublishState_t MQTT_CalculateStateAck(MQTTPubAckType_t packetType, MQTTStateOperation_t opType, MQTTQoS_t qos)
Calculate the state from a PUBACK, PUBREC, PUBREL, or PUBCOMP.
Definition: core_mqtt_state.c:657
+
MQTTStatus_t MQTT_ReserveState(const MQTTContext_t *pMqttContext, uint16_t packetId, MQTTQoS_t qos)
Reserve an entry for an outgoing QoS 1 or Qos 2 publish.
Definition: core_mqtt_state.c:825
+
const char * MQTT_State_strerror(MQTTPublishState_t state)
State to string conversion for state engine.
Definition: core_mqtt_state.c:1153
+
MQTTPublishState_t MQTT_CalculateStatePublish(MQTTStateOperation_t opType, MQTTQoS_t qos)
Calculate the new state for a publish from its qos and operation type.
Definition: core_mqtt_state.c:854
+
MQTTStatus_t MQTT_UpdateStatePublish(const MQTTContext_t *pMqttContext, uint16_t packetId, MQTTStateOperation_t opType, MQTTQoS_t qos, MQTTPublishState_t *pNewState)
Update the state record for a PUBLISH packet.
Definition: core_mqtt_state.c:883
+
uint16_t MQTT_PubrelToResend(const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor, MQTTPublishState_t *pState)
Get the packet ID of next pending PUBREL ack to be resent.
Definition: core_mqtt_state.c:1087
+
MQTTStatus_t MQTT_RemoveStateRecord(const MQTTContext_t *pMqttContext, uint16_t packetId)
Remove the state record for a PUBLISH packet.
Definition: core_mqtt_state.c:957
+
uint16_t MQTT_PublishToResend(const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor)
Get the packet ID of next pending publish to be resent.
Definition: core_mqtt_state.c:1123
+
size_t MQTTStateCursor_t
Cursor for iterating through state records.
Definition: core_mqtt_state.h:51
+
MQTTPublishState_t
The state of QoS 1 or QoS 2 MQTT publishes, used in the state engine.
Definition: core_mqtt.h:119
+
MQTTPubAckType_t
Packet types used in acknowledging QoS 1 or QoS 2 publishes.
Definition: core_mqtt.h:138
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTTQoS_t
MQTT Quality of Service values.
Definition: core_mqtt_serializer.h:109
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
+
+ + + + diff --git a/latest/coreMQTT/core_mqtt_config.html b/latest/coreMQTT/core_mqtt_config.html new file mode 100644 index 00000000..9cce5b47 --- /dev/null +++ b/latest/coreMQTT/core_mqtt_config.html @@ -0,0 +1,176 @@ + + + + + + + +coreMQTT: Configurations + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Configurations
+
+
+

Configurations of the MQTT Library.

+
configpagestyle
+

Some configuration settings are C pre-processor constants, and some are function-like macros for logging. They can be set with a #define in the config file (core_mqtt_config.h) or by using a compiler option such as -D in gcc.

+

+MQTT_DO_NOT_USE_CUSTOM_CONFIG

+

Define this macro to build the MQTT library without the custom config file core_mqtt_config.h.

+

Without the custom config, the MQTT library builds with default values of config macros defined in core_mqtt_config_defaults.h file.

+

If a custom config is provided, then MQTT_DO_NOT_USE_CUSTOM_CONFIG should not be defined.

+

+MQTT_PINGRESP_TIMEOUT_MS

+

Maximum number of milliseconds to wait for a ping response to a ping request as part of the keep-alive mechanism.

+

If a ping response is not received before this timeout, then MQTT_ProcessLoop will return MQTTKeepAliveTimeout.

+
Note
If this value is more than half of the keep alive interval, and the server does not receive the previous ping request, then it is likely that the server will disconnect the client before MQTTKeepAliveTimeout can be returned.
+
+If a dummy implementation of the MQTTGetCurrentTimeFunc_t timer function, is supplied to the library, then the keep-alive mechanism is not supported by the MQTT_ProcessLoop API function. In that case, the value of MQTT_PINGRESP_TIMEOUT_MS is irrelevant to the behavior of the library.
+

Possible values: Any positive integer up to SIZE_MAX.
+ Default value: 5000

+

+MQTT_RECV_POLLING_TIMEOUT_MS

+

The maximum duration between non-empty network reads while receiving an MQTT packet via the MQTT_ProcessLoop or MQTT_ReceiveLoop API functions.

+

When an incoming MQTT packet is detected, the transport receive function may be called multiple times until all of the expected number of bytes of the packet are received. This timeout represents the maximum polling duration that is allowed without any data reception from the network for the incoming packet.

+

If the timeout expires, the MQTT_ProcessLoop and MQTT_ReceiveLoop functions return MQTTRecvFailed.

+
Note
If a dummy implementation of the MQTTGetCurrentTimeFunc_t timer function, is supplied to the library, then MQTT_RECV_POLLING_TIMEOUT_MS MUST be set to 0.
+

Possible values: Any positive 32 bit integer. Recommended to use a small timeout value.
+ Default value: 10

+

+MQTT_SEND_TIMEOUT_MS

+

The maximum duration allowed to send an MQTT packet over the transport interface.

+

When sending an MQTT packet, the transport send or writev functions may be called multiple times until all of the required number of bytes are sent. This timeout represents the maximum duration that is allowed to send the MQTT packet while calling the transport send or writev functions.

+

If the timeout expires, MQTTSendFailed will be returned by the public API functions.

+
Note
If a dummy implementation of the MQTTGetCurrentTimeFunc_t timer function, is supplied to the library, then MQTT_SEND_TIMEOUT_MS MUST be set to 0.
+

Possible values: Any positive 32 bit integer.
+ Default value: 20000

+

+MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT

+

The number of retries for receiving CONNACK.

+

The MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT will be used only when the timeoutMs parameter of MQTT_Connect is passed as 0 . The transport receive for CONNACK will be retried MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT times before timing out. A value of 0 for this config will cause the transport receive for CONNACK to be invoked only once.

+

Possible values: Any positive 16 bit integer.
+ Default value: 5

+

+LogError

+

Macro that is called in the MQTT library for logging "Error" level messages.

+

To enable error level logging in the MQTT library, this macro should be mapped to the application-specific logging implementation that supports error logging.

+
Note
This logging macro is called in the MQTT library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Error logging is turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+

+LogWarn

+

Macro that is called in the MQTT library for logging "Warning" level messages.

+

To enable warning level logging in the MQTT library, this macro should be mapped to the application-specific logging implementation that supports warning logging.

+
Note
This logging macro is called in the MQTT library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Warning logs are turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+

+LogInfo

+

Macro that is called in the MQTT library for logging "Info" level messages.

+

To enable info level logging in the MQTT library, this macro should be mapped to the application-specific logging implementation that supports info logging.

+
Note
This logging macro is called in the MQTT library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Info logging is turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+

+LogDebug

+

Macro that is called in the MQTT library for logging "Debug" level messages.

+

To enable debug level logging from MQTT library, this macro should be mapped to the application-specific logging implementation that supports debug logging.

+
Note
This logging macro is called in the MQTT library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Debug logging is turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+
+
+
+ + + + diff --git a/latest/coreMQTT/dir_359d2bec989c9a8deeeb9aee335c1c76.html b/latest/coreMQTT/dir_359d2bec989c9a8deeeb9aee335c1c76.html new file mode 100644 index 00000000..19d14860 --- /dev/null +++ b/latest/coreMQTT/dir_359d2bec989c9a8deeeb9aee335c1c76.html @@ -0,0 +1,113 @@ + + + + + + + +coreMQTT: doxygen Directory Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
doxygen Directory Reference
+
+
+
+
+ + + + diff --git a/latest/coreMQTT/dir_3750548c40d9045ee3b3d006c00db089.html b/latest/coreMQTT/dir_3750548c40d9045ee3b3d006c00db089.html new file mode 100644 index 00000000..bab2ab67 --- /dev/null +++ b/latest/coreMQTT/dir_3750548c40d9045ee3b3d006c00db089.html @@ -0,0 +1,120 @@ + + + + + + + +coreMQTT: interface Directory Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
interface Directory Reference
+
+
+ + + + + +

+Files

file  transport_interface.h [code]
 Transport interface definitions to send and receive data over the network.
 
+
+
+ + + + diff --git a/latest/coreMQTT/dir_49e56c817e5e54854c35e136979f97ca.html b/latest/coreMQTT/dir_49e56c817e5e54854c35e136979f97ca.html new file mode 100644 index 00000000..8c0639c1 --- /dev/null +++ b/latest/coreMQTT/dir_49e56c817e5e54854c35e136979f97ca.html @@ -0,0 +1,113 @@ + + + + + + + +coreMQTT: docs Directory Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
docs Directory Reference
+
+
+
+
+ + + + diff --git a/latest/coreMQTT/dir_8ee1a5e78eaec319fe5d64075812fc61.html b/latest/coreMQTT/dir_8ee1a5e78eaec319fe5d64075812fc61.html new file mode 100644 index 00000000..f43d5b5d --- /dev/null +++ b/latest/coreMQTT/dir_8ee1a5e78eaec319fe5d64075812fc61.html @@ -0,0 +1,129 @@ + + + + + + + +coreMQTT: include Directory Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
include Directory Reference
+
+
+ + + + + + + + + + + + + + +

+Files

file  core_mqtt.h [code]
 User-facing functions of the MQTT 3.1.1 library.
 
file  core_mqtt_config_defaults.h [code]
 This represents the default values for the configuration macros for the MQTT library.
 
file  core_mqtt_serializer.h [code]
 User-facing functions for serializing and deserializing MQTT 3.1.1 packets. This header should be included for building a lighter weight MQTT client than the managed CSDK MQTT library API in core_mqtt.h, by using the serializer and de-serializer functions exposed in this file's API.
 
file  core_mqtt_state.h [code]
 Function to keep state of MQTT PUBLISH packet deliveries.
 
+
+
+ + + + diff --git a/latest/coreMQTT/dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html b/latest/coreMQTT/dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html new file mode 100644 index 00000000..97560768 --- /dev/null +++ b/latest/coreMQTT/dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html @@ -0,0 +1,133 @@ + + + + + + + +coreMQTT: source Directory Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
source Directory Reference
+
+
+ + + + + + +

+Directories

directory  include
 
directory  interface
 
+ + + + + + + + + + +

+Files

file  core_mqtt.c
 Implements the user-facing functions in core_mqtt.h.
 
file  core_mqtt_serializer.c
 Implements the user-facing functions in core_mqtt_serializer.h.
 
file  core_mqtt_state.c
 Implements the functions in core_mqtt_state.h.
 
+
+
+ + + + diff --git a/latest/coreMQTT/doc.png b/latest/coreMQTT/doc.png new file mode 100644 index 0000000000000000000000000000000000000000..17edabff95f7b8da13c9516a04efe05493c29501 GIT binary patch literal 746 zcmV7=@pnbNXRFEm&G8P!&WHG=d)>K?YZ1bzou)2{$)) zumDct!>4SyxL;zgaG>wy`^Hv*+}0kUfCrz~BCOViSb$_*&;{TGGn2^x9K*!Sf0=lV zpP=7O;GA0*Jm*tTYj$IoXvimpnV4S1Z5f$p*f$Db2iq2zrVGQUz~yq`ahn7ck(|CE z7Gz;%OP~J6)tEZWDzjhL9h2hdfoU2)Nd%T<5Kt;Y0XLt&<@6pQx!nw*5`@bq#?l*?3z{Hlzoc=Pr>oB5(9i6~_&-}A(4{Q$>c>%rV&E|a(r&;?i5cQB=} zYSDU5nXG)NS4HEs0it2AHe2>shCyr7`6@4*6{r@8fXRbTA?=IFVWAQJL&H5H{)DpM#{W(GL+Idzf^)uRV@oB8u$ z8v{MfJbTiiRg4bza<41NAzrl{=3fl_D+$t+^!xlQ8S}{UtY`e z;;&9UhyZqQRN%2pot{*Ei0*4~hSF_3AH2@fKU!$NSflS>{@tZpDT4`M2WRTTVH+D? z)GFlEGGHe?koB}i|1w45!BF}N_q&^HJ&-tyR{(afC6H7|aml|tBBbv}55C5DNP8p3 z)~jLEO4Z&2hZmP^i-e%(@d!(E|KRafiU8Q5u(wU((j8un3OR*Hvj+t literal 0 HcmV?d00001 diff --git a/latest/coreMQTT/docd.png b/latest/coreMQTT/docd.png new file mode 100644 index 0000000000000000000000000000000000000000..d7c94fda9bf08ecc02c7190d968452b7a2dbf04b GIT binary patch literal 756 zcmV1wr-rhpn+wxm%q2)IkAYsr{iGq<}_z5JCD4J;FN?6Qh;@TCubdp(_XdD-^ zG_#)IP7_z6hKNdx5^+FGArwLWTWCG!j+oKji?U!hxA#d-ljgkN`+e^@-P+RWG{Bx= z2iQyYTtEf*o~ySWrIVW}HWHi0_hd4~$E6Jx1U`>Owo}EYJ1O>iZvS?!z8}B}QwLMA zC3Keqf1c}K@?C`X>68b(EUzYUYAS&OH^VPteZLPr{S&|nQvp@6W4GH-1U8!u&7l~A zx~RUSNH+>7@q38W6!BzirtjLFCzc|XGx)EF#G%^pWION*k@?vP<2O>|XkCD3ujl%1 z{55JSVkw{~HbX>iEZ2%yJ2eHj5Yh8OTpzs0A2;tZ^x!#5D+y-es{k1&0|Ns9-|+Xt ziGiTsZ8(^nUo#wdTpIDkb-Zp(3|A*FzW}GZ5SQD-r^R`&X@`26E3W|GyrwDIZjtQ& z$g5f8Sv=VgVtDien@J(!^BK+#l;s-LgP--p7C;7;E!ysXcXK6?+9D>_-B(?Wm(U zQbNm-5TyYxIU=rs0+)!ixqzhuxw(AqKc3?KKX32{D~Qibp*r0x&Wux5-9WCMMRi3U zTd6dOCQlj>a;gr;gLwRKulT&(m@^L{&HkSC(qH05HSSf$YEhynGvH zWNez``Z8FJXE+BSg=%ak{OR z+Nylcb{?evLYLuE1_HngYw0g%LC#=$a@?4~Tx>F9295Q>9UJ|_6v-KMw;!YZSgGj@ zR8fRov=hJ#QvsO@xw*{0%zH@OKVEUrsummary { + list-style-type: none; +} + +details > summary::-webkit-details-marker { + display: none; +} + +details>summary::before { + content: "\25ba"; + padding-right:4px; + font-size: 80%; +} + +details[open]>summary::before { + content: "\25bc"; + padding-right:4px; + font-size: 80%; +} + diff --git a/latest/coreMQTT/doxygen.svg b/latest/coreMQTT/doxygen.svg new file mode 100644 index 00000000..d42dad52 --- /dev/null +++ b/latest/coreMQTT/doxygen.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/latest/coreMQTT/dynsections.js b/latest/coreMQTT/dynsections.js new file mode 100644 index 00000000..f579fbf3 --- /dev/null +++ b/latest/coreMQTT/dynsections.js @@ -0,0 +1,123 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); + $('table.directory tr'). + removeClass('odd').filter(':visible:odd').addClass('odd'); +} + +function toggleLevel(level) +{ + $('table.directory tr').each(function() { + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l + + + + + + +coreMQTT: Files + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Files
+
+
+
The following files are associated with this library.
+
[detail level 123]
+ + + + + + + + + + + +
  source
  include
 core_mqtt.hUser-facing functions of the MQTT 3.1.1 library
 core_mqtt_config_defaults.hThis represents the default values for the configuration macros for the MQTT library
 core_mqtt_serializer.hUser-facing functions for serializing and deserializing MQTT 3.1.1 packets. This header should be included for building a lighter weight MQTT client than the managed CSDK MQTT library API in core_mqtt.h, by using the serializer and de-serializer functions exposed in this file's API
 core_mqtt_state.hFunction to keep state of MQTT PUBLISH packet deliveries
  interface
 transport_interface.hTransport interface definitions to send and receive data over the network
 core_mqtt.cImplements the user-facing functions in core_mqtt.h
 core_mqtt_serializer.cImplements the user-facing functions in core_mqtt_serializer.h
 core_mqtt_state.cImplements the functions in core_mqtt_state.h
+
+
+
+ + + + diff --git a/latest/coreMQTT/folderclosed.png b/latest/coreMQTT/folderclosed.png new file mode 100644 index 0000000000000000000000000000000000000000..bb8ab35edce8e97554e360005ee9fc5bffb36e66 GIT binary patch literal 616 zcmV-u0+;=XP)a9#ETzayK)T~Jw&MMH>OIr#&;dC}is*2Mqdf&akCc=O@`qC+4i z5Iu3w#1M@KqXCz8TIZd1wli&kkl2HVcAiZ8PUn5z_kG@-y;?yK06=cA0U%H0PH+kU zl6dp}OR(|r8-RG+YLu`zbI}5TlOU6ToR41{9=uz^?dGTNL;wIMf|V3`d1Wj3y!#6` zBLZ?xpKR~^2x}?~zA(_NUu3IaDB$tKma*XUdOZN~c=dLt_h_k!dbxm_*ibDM zlFX`g{k$X}yIe%$N)cn1LNu=q9_CS)*>A zsX_mM4L@`(cSNQKMFc$RtYbx{79#j-J7hk*>*+ZZhM4Hw?I?rsXCi#mRWJ=-0LGV5a-WR0Qgt<|Nqf)C-@80`5gIz45^_20000IqP)X=#(TiCT&PiIIVc55T}TU}EUh*{q$|`3@{d>{Tc9Bo>e= zfmF3!f>fbI9#GoEHh0f`i5)wkLpva0ztf%HpZneK?w-7AK@b4Itw{y|Zd3k!fH?q2 zlhckHd_V2M_X7+)U&_Xcfvtw60l;--DgZmLSw-Y?S>)zIqMyJ1#FwLU*%bl38ok+! zh78H87n`ZTS;uhzAR$M`zZ`bVhq=+%u9^$5jDplgxd44}9;IRqUH1YHH|@6oFe%z( zo4)_>E$F&^P-f(#)>(TrnbE>Pefs9~@iN=|)Rz|V`sGfHNrJ)0gJb8xx+SBmRf@1l zvuzt=vGfI)<-F9!o&3l?>9~0QbUDT(wFdnQPv%xdD)m*g%!20>Bc9iYmGAp<9YAa( z0QgYgTWqf1qN++Gqp z8@AYPTB3E|6s=WLG?xw0tm|U!o=&zd+H0oRYE;Dbx+Na9s^STqX|Gnq%H8s(nGDGJ j8vwW|`Ts`)fSK|Kx=IK@RG@g200000NkvXXu0mjfauFEA literal 0 HcmV?d00001 diff --git a/latest/coreMQTT/functions.html b/latest/coreMQTT/functions.html new file mode 100644 index 00000000..4c910bf5 --- /dev/null +++ b/latest/coreMQTT/functions.html @@ -0,0 +1,228 @@ + + + + + + + +coreMQTT: Data Fields + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- a -

+ + +

- c -

+ + +

- d -

+ + +

- g -

+ + +

- h -

+ + +

- i -

+ + +

- k -

+ + +

- l -

+ + +

- n -

+ + +

- o -

+ + +

- p -

+ + +

- q -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- u -

+ + +

- w -

+
+
+ + + + diff --git a/latest/coreMQTT/functions_vars.html b/latest/coreMQTT/functions_vars.html new file mode 100644 index 00000000..a6307fff --- /dev/null +++ b/latest/coreMQTT/functions_vars.html @@ -0,0 +1,228 @@ + + + + + + + +coreMQTT: Data Fields - Variables + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- a -

+ + +

- c -

+ + +

- d -

+ + +

- g -

+ + +

- h -

+ + +

- i -

+ + +

- k -

+ + +

- l -

+ + +

- n -

+ + +

- o -

+ + +

- p -

+ + +

- q -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- u -

+ + +

- w -

+
+
+ + + + diff --git a/latest/coreMQTT/globals.html b/latest/coreMQTT/globals.html new file mode 100644 index 00000000..d6ecd0f5 --- /dev/null +++ b/latest/coreMQTT/globals.html @@ -0,0 +1,115 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- a -

+
+
+ + + + diff --git a/latest/coreMQTT/globals_c.html b/latest/coreMQTT/globals_c.html new file mode 100644 index 00000000..a1b333f2 --- /dev/null +++ b/latest/coreMQTT/globals_c.html @@ -0,0 +1,121 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- c -

+
+
+ + + + diff --git a/latest/coreMQTT/globals_d.html b/latest/coreMQTT/globals_d.html new file mode 100644 index 00000000..f34ffaeb --- /dev/null +++ b/latest/coreMQTT/globals_d.html @@ -0,0 +1,120 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- d -

+
+
+ + + + diff --git a/latest/coreMQTT/globals_defs.html b/latest/coreMQTT/globals_defs.html new file mode 100644 index 00000000..5b40f48e --- /dev/null +++ b/latest/coreMQTT/globals_defs.html @@ -0,0 +1,197 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- c -

    +
  • CORE_MQTT_SERIALIZED_LENGTH_FIELD_BYTES : core_mqtt.c
  • +
  • CORE_MQTT_SUBSCRIBE_PER_TOPIC_VECTOR_LENGTH : core_mqtt.c
  • +
  • CORE_MQTT_UNSUBSCRIBE_PER_TOPIC_VECTOR_LENGTH : core_mqtt.c
  • +
+ + +

- l -

+ + +

- m -

+ + +

- p -

+ + +

- u -

+
+
+ + + + diff --git a/latest/coreMQTT/globals_e.html b/latest/coreMQTT/globals_e.html new file mode 100644 index 00000000..bd01185a --- /dev/null +++ b/latest/coreMQTT/globals_e.html @@ -0,0 +1,115 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- e -

+
+
+ + + + diff --git a/latest/coreMQTT/globals_enum.html b/latest/coreMQTT/globals_enum.html new file mode 100644 index 00000000..3ba18fb2 --- /dev/null +++ b/latest/coreMQTT/globals_enum.html @@ -0,0 +1,118 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
+ + + + diff --git a/latest/coreMQTT/globals_eval.html b/latest/coreMQTT/globals_eval.html new file mode 100644 index 00000000..d0c674bb --- /dev/null +++ b/latest/coreMQTT/globals_eval.html @@ -0,0 +1,151 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- m -

+
+
+ + + + diff --git a/latest/coreMQTT/globals_f.html b/latest/coreMQTT/globals_f.html new file mode 100644 index 00000000..93171d95 --- /dev/null +++ b/latest/coreMQTT/globals_f.html @@ -0,0 +1,114 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- f -

+
+
+ + + + diff --git a/latest/coreMQTT/globals_func.html b/latest/coreMQTT/globals_func.html new file mode 100644 index 00000000..d2b6e973 --- /dev/null +++ b/latest/coreMQTT/globals_func.html @@ -0,0 +1,272 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- a -

+ + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- g -

+ + +

- h -

+ + +

- i -

+ + +

- l -

+ + +

- m -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- u -

+ + +

- v -

+
+
+ + + + diff --git a/latest/coreMQTT/globals_g.html b/latest/coreMQTT/globals_g.html new file mode 100644 index 00000000..d31715bd --- /dev/null +++ b/latest/coreMQTT/globals_g.html @@ -0,0 +1,116 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- g -

+
+
+ + + + diff --git a/latest/coreMQTT/globals_h.html b/latest/coreMQTT/globals_h.html new file mode 100644 index 00000000..bbf43219 --- /dev/null +++ b/latest/coreMQTT/globals_h.html @@ -0,0 +1,118 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- h -

+
+
+ + + + diff --git a/latest/coreMQTT/globals_i.html b/latest/coreMQTT/globals_i.html new file mode 100644 index 00000000..85c01707 --- /dev/null +++ b/latest/coreMQTT/globals_i.html @@ -0,0 +1,115 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- i -

+
+
+ + + + diff --git a/latest/coreMQTT/globals_l.html b/latest/coreMQTT/globals_l.html new file mode 100644 index 00000000..cdba1c92 --- /dev/null +++ b/latest/coreMQTT/globals_l.html @@ -0,0 +1,118 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- l -

+
+
+ + + + diff --git a/latest/coreMQTT/globals_m.html b/latest/coreMQTT/globals_m.html new file mode 100644 index 00000000..20ed8c7f --- /dev/null +++ b/latest/coreMQTT/globals_m.html @@ -0,0 +1,261 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- m -

+
+
+ + + + diff --git a/latest/coreMQTT/globals_n.html b/latest/coreMQTT/globals_n.html new file mode 100644 index 00000000..6d1be764 --- /dev/null +++ b/latest/coreMQTT/globals_n.html @@ -0,0 +1,114 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- n -

+
+
+ + + + diff --git a/latest/coreMQTT/globals_p.html b/latest/coreMQTT/globals_p.html new file mode 100644 index 00000000..f07bde1d --- /dev/null +++ b/latest/coreMQTT/globals_p.html @@ -0,0 +1,117 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- p -

+
+
+ + + + diff --git a/latest/coreMQTT/globals_r.html b/latest/coreMQTT/globals_r.html new file mode 100644 index 00000000..ca7245a1 --- /dev/null +++ b/latest/coreMQTT/globals_r.html @@ -0,0 +1,119 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- r -

+
+
+ + + + diff --git a/latest/coreMQTT/globals_s.html b/latest/coreMQTT/globals_s.html new file mode 100644 index 00000000..576e3257 --- /dev/null +++ b/latest/coreMQTT/globals_s.html @@ -0,0 +1,123 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- s -

+
+
+ + + + diff --git a/latest/coreMQTT/globals_t.html b/latest/coreMQTT/globals_t.html new file mode 100644 index 00000000..7bc746db --- /dev/null +++ b/latest/coreMQTT/globals_t.html @@ -0,0 +1,116 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- t -

+
+
+ + + + diff --git a/latest/coreMQTT/globals_type.html b/latest/coreMQTT/globals_type.html new file mode 100644 index 00000000..aac3131c --- /dev/null +++ b/latest/coreMQTT/globals_type.html @@ -0,0 +1,118 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
+ + + + diff --git a/latest/coreMQTT/globals_u.html b/latest/coreMQTT/globals_u.html new file mode 100644 index 00000000..02c481d2 --- /dev/null +++ b/latest/coreMQTT/globals_u.html @@ -0,0 +1,124 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- u -

+
+
+ + + + diff --git a/latest/coreMQTT/globals_v.html b/latest/coreMQTT/globals_v.html new file mode 100644 index 00000000..4eef4917 --- /dev/null +++ b/latest/coreMQTT/globals_v.html @@ -0,0 +1,118 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- v -

+
+
+ + + + diff --git a/latest/coreMQTT/globals_vars.html b/latest/coreMQTT/globals_vars.html new file mode 100644 index 00000000..e10e3e4e --- /dev/null +++ b/latest/coreMQTT/globals_vars.html @@ -0,0 +1,112 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
+ + + + diff --git a/latest/coreMQTT/globals_z.html b/latest/coreMQTT/globals_z.html new file mode 100644 index 00000000..3a3a0f92 --- /dev/null +++ b/latest/coreMQTT/globals_z.html @@ -0,0 +1,114 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- z -

+
+
+ + + + diff --git a/latest/coreMQTT/group__mqtt__basic__types.html b/latest/coreMQTT/group__mqtt__basic__types.html new file mode 100644 index 00000000..978e8a77 --- /dev/null +++ b/latest/coreMQTT/group__mqtt__basic__types.html @@ -0,0 +1,127 @@ + + + + + + + +coreMQTT: Basic Types + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
Basic Types
+
+
+ +

Primitive types of the MQTT library. +More...

+ + + + + +

+Typedefs

+typedef size_t MQTTStateCursor_t
 Cursor for iterating through state records.
 
+

Detailed Description

+

Primitive types of the MQTT library.

+
+
+ + + + diff --git a/latest/coreMQTT/group__mqtt__basic__types.js b/latest/coreMQTT/group__mqtt__basic__types.js new file mode 100644 index 00000000..c0e30048 --- /dev/null +++ b/latest/coreMQTT/group__mqtt__basic__types.js @@ -0,0 +1,4 @@ +var group__mqtt__basic__types = +[ + [ "MQTTStateCursor_t", "group__mqtt__basic__types.html#ga2ca7d486d83fe555953a8c7876ee0d6e", null ] +]; \ No newline at end of file diff --git a/latest/coreMQTT/group__mqtt__callback__types.html b/latest/coreMQTT/group__mqtt__callback__types.html new file mode 100644 index 00000000..f62787f4 --- /dev/null +++ b/latest/coreMQTT/group__mqtt__callback__types.html @@ -0,0 +1,264 @@ + + + + + + + +coreMQTT: Callback Types + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
Callback Types
+
+
+ +

Callback function pointer types of the MQTT library. +More...

+ + + + + + + + + + + + + + + + + +

+Typedefs

typedef uint32_t(* MQTTGetCurrentTimeFunc_t) (void)
 Application provided function to query the time elapsed since a given epoch in milliseconds.
 
typedef void(* MQTTEventCallback_t) (struct MQTTContext *pContext, struct MQTTPacketInfo *pPacketInfo, struct MQTTDeserializedInfo *pDeserializedInfo)
 Application callback for receiving incoming publishes and incoming acks.
 
typedef int32_t(* TransportRecv_t) (NetworkContext_t *pNetworkContext, void *pBuffer, size_t bytesToRecv)
 Transport interface for receiving data on the network.
 
typedef int32_t(* TransportSend_t) (NetworkContext_t *pNetworkContext, const void *pBuffer, size_t bytesToSend)
 Transport interface for sending data over the network.
 
typedef int32_t(* TransportWritev_t) (NetworkContext_t *pNetworkContext, TransportOutVector_t *pIoVec, size_t ioVecCount)
 Transport interface function for "vectored" / scatter-gather based writes. This function is expected to iterate over the list of vectors pIoVec having ioVecCount entries containing portions of one MQTT message at a maximum. If the proper functionality is available, then the data in the list should be copied to the underlying TCP buffer before flushing the buffer. Implementing it in this fashion will lead to sending of fewer TCP packets for all the values in the list.
 
+

Detailed Description

+

Callback function pointer types of the MQTT library.

+

Typedef Documentation

+ +

◆ MQTTGetCurrentTimeFunc_t

+ +
+
+ + + + +
typedef uint32_t(* MQTTGetCurrentTimeFunc_t) (void)
+
+ +

Application provided function to query the time elapsed since a given epoch in milliseconds.

+
Note
The timer should be a monotonic timer. It just needs to provide an incrementing count of milliseconds elapsed since a given epoch.
+
+As the timer is supposed to be a millisecond timer returning a 32-bit value, it will overflow in just under 50 days. But it will not cause any issues in the library as the time function is only used for calculating durations for timeouts and keep alive periods. The difference in unsigned numbers is used where unsigned wrap around is defined. Unless the timeout is bigger than 100 days (50*2) where the numbers can wrap around more than once the code should work properly.
+
Returns
The time elapsed in milliseconds.
+ +
+
+ +

◆ MQTTEventCallback_t

+ +
+
+ + + + +
typedef void(* MQTTEventCallback_t) (struct MQTTContext *pContext, struct MQTTPacketInfo *pPacketInfo, struct MQTTDeserializedInfo *pDeserializedInfo)
+
+ +

Application callback for receiving incoming publishes and incoming acks.

+
Note
This callback will be called only if packets are deserialized with a result of MQTTSuccess or MQTTServerRefused. The latter can be obtained when deserializing a SUBACK, indicating a broker's rejection of a subscribe.
+
Parameters
+ + + + +
[in]pContextInitialized MQTT context.
[in]pPacketInfoInformation on the type of incoming MQTT packet.
[in]pDeserializedInfoDeserialized information from incoming packet.
+
+
+ +
+
+ +

◆ TransportRecv_t

+ +
+
+ + + + +
typedef int32_t(* TransportRecv_t) (NetworkContext_t *pNetworkContext, void *pBuffer, size_t bytesToRecv)
+
+ +

Transport interface for receiving data on the network.

+
Note
It is HIGHLY RECOMMENDED that the transport receive implementation does NOT block. coreMQTT will continue to call the transport interface if it receives a partial packet until it accumulates enough data to get the complete MQTT packet.
+
Parameters
+ + + + +
[in]pNetworkContextImplementation-defined network context.
[in]pBufferBuffer to receive the data into.
[in]bytesToRecvNumber of bytes requested from the network.
+
+
+
Returns
The number of bytes received or a negative value to indicate error.
+
Note
If no data is available on the network to read and no error has occurred, zero MUST be the return value. A zero return value SHOULD represent that the read operation can be retried by calling the API function. Zero MUST NOT be returned if a network disconnection has occurred.
+ +
+
+ +

◆ TransportSend_t

+ +
+
+ + + + +
typedef int32_t(* TransportSend_t) (NetworkContext_t *pNetworkContext, const void *pBuffer, size_t bytesToSend)
+
+ +

Transport interface for sending data over the network.

+
Parameters
+ + + + +
[in]pNetworkContextImplementation-defined network context.
[in]pBufferBuffer containing the bytes to send over the network stack.
[in]bytesToSendNumber of bytes to send over the network.
+
+
+
Returns
The number of bytes sent or a negative value to indicate error.
+
Note
If no data is transmitted over the network due to a full TX buffer and no network error has occurred, this MUST return zero as the return value. A zero return value SHOULD represent that the send operation can be retried by calling the API function. Zero MUST NOT be returned if a network disconnection has occurred.
+ +
+
+ +

◆ TransportWritev_t

+ +
+
+ + + + +
typedef int32_t(* TransportWritev_t) (NetworkContext_t *pNetworkContext, TransportOutVector_t *pIoVec, size_t ioVecCount)
+
+ +

Transport interface function for "vectored" / scatter-gather based writes. This function is expected to iterate over the list of vectors pIoVec having ioVecCount entries containing portions of one MQTT message at a maximum. If the proper functionality is available, then the data in the list should be copied to the underlying TCP buffer before flushing the buffer. Implementing it in this fashion will lead to sending of fewer TCP packets for all the values in the list.

+
Note
If the proper write functionality is not present for a given device/IP-stack, then there is no strict requirement to implement write. Only the send and recv interfaces must be defined for the application to work properly.
+
Parameters
+ + + + +
[in]pNetworkContextImplementation-defined network context.
[in]pIoVecAn array of TransportIoVector_t structs.
[in]ioVecCountNumber of TransportIoVector_t in pIoVec.
+
+
+
Returns
The number of bytes written or a negative value to indicate error.
+
Note
If no data is written to the buffer due to the buffer being full this MUST return zero as the return value. A zero return value SHOULD represent that the write operation can be retried by calling the API function. Zero MUST NOT be returned if a network disconnection has occurred.
+ +
+
+
+
+ + + + diff --git a/latest/coreMQTT/group__mqtt__callback__types.js b/latest/coreMQTT/group__mqtt__callback__types.js new file mode 100644 index 00000000..fed9ffb6 --- /dev/null +++ b/latest/coreMQTT/group__mqtt__callback__types.js @@ -0,0 +1,8 @@ +var group__mqtt__callback__types = +[ + [ "MQTTGetCurrentTimeFunc_t", "group__mqtt__callback__types.html#gae3bea55b0e49e5208b8c5709a5ea23aa", null ], + [ "MQTTEventCallback_t", "group__mqtt__callback__types.html#ga00d348277ed4fde23c95bfc749ae954a", null ], + [ "TransportRecv_t", "group__mqtt__callback__types.html#ga227df31d6daf07e5d833537c12130167", null ], + [ "TransportSend_t", "group__mqtt__callback__types.html#ga2a39853ff952edd715ab07b33ab2a7c5", null ], + [ "TransportWritev_t", "group__mqtt__callback__types.html#ga47e779557b0c2db95949ef9526861dfb", null ] +]; \ No newline at end of file diff --git a/latest/coreMQTT/group__mqtt__constants.html b/latest/coreMQTT/group__mqtt__constants.html new file mode 100644 index 00000000..95c6fc72 --- /dev/null +++ b/latest/coreMQTT/group__mqtt__constants.html @@ -0,0 +1,212 @@ + + + + + + + +coreMQTT: Constants + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
Constants
+
+
+ +

Constants defined in the MQTT library. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Macros

#define MQTT_PACKET_ID_INVALID   ( ( uint16_t ) 0U )
 Invalid packet identifier.
 
+#define MQTT_SUB_UNSUB_MAX_VECTORS   ( 4U )
 Maximum number of vectors in subscribe and unsubscribe packet.
 
+#define MQTT_PACKET_TYPE_CONNECT   ( ( uint8_t ) 0x10U )
 CONNECT (client-to-server).
 
+#define MQTT_PACKET_TYPE_CONNACK   ( ( uint8_t ) 0x20U )
 CONNACK (server-to-client).
 
+#define MQTT_PACKET_TYPE_PUBLISH   ( ( uint8_t ) 0x30U )
 PUBLISH (bidirectional).
 
+#define MQTT_PACKET_TYPE_PUBACK   ( ( uint8_t ) 0x40U )
 PUBACK (bidirectional).
 
+#define MQTT_PACKET_TYPE_PUBREC   ( ( uint8_t ) 0x50U )
 PUBREC (bidirectional).
 
+#define MQTT_PACKET_TYPE_PUBREL   ( ( uint8_t ) 0x62U )
 PUBREL (bidirectional).
 
+#define MQTT_PACKET_TYPE_PUBCOMP   ( ( uint8_t ) 0x70U )
 PUBCOMP (bidirectional).
 
+#define MQTT_PACKET_TYPE_SUBSCRIBE   ( ( uint8_t ) 0x82U )
 SUBSCRIBE (client-to-server).
 
+#define MQTT_PACKET_TYPE_SUBACK   ( ( uint8_t ) 0x90U )
 SUBACK (server-to-client).
 
+#define MQTT_PACKET_TYPE_UNSUBSCRIBE   ( ( uint8_t ) 0xA2U )
 UNSUBSCRIBE (client-to-server).
 
+#define MQTT_PACKET_TYPE_UNSUBACK   ( ( uint8_t ) 0xB0U )
 UNSUBACK (server-to-client).
 
+#define MQTT_PACKET_TYPE_PINGREQ   ( ( uint8_t ) 0xC0U )
 PINGREQ (client-to-server).
 
+#define MQTT_PACKET_TYPE_PINGRESP   ( ( uint8_t ) 0xD0U )
 PINGRESP (server-to-client).
 
+#define MQTT_PACKET_TYPE_DISCONNECT   ( ( uint8_t ) 0xE0U )
 DISCONNECT (client-to-server).
 
+#define MQTT_PUBLISH_ACK_PACKET_SIZE   ( 4UL )
 The size of MQTT PUBACK, PUBREC, PUBREL, and PUBCOMP packets, per MQTT spec.
 
+#define MQTT_STATE_CURSOR_INITIALIZER   ( ( size_t ) 0 )
 Initializer value for an MQTTStateCursor_t, indicating a search should start at the beginning of a state record array.
 
+

Detailed Description

+

Constants defined in the MQTT library.

+

Macro Definition Documentation

+ +

◆ MQTT_PACKET_ID_INVALID

+ +
+
+ + + + +
#define MQTT_PACKET_ID_INVALID   ( ( uint16_t ) 0U )
+
+ +

Invalid packet identifier.

+

Zero is an invalid packet identifier as per MQTT v3.1.1 spec.

+ +
+
+
+
+ + + + diff --git a/latest/coreMQTT/group__mqtt__constants.js b/latest/coreMQTT/group__mqtt__constants.js new file mode 100644 index 00000000..57529cab --- /dev/null +++ b/latest/coreMQTT/group__mqtt__constants.js @@ -0,0 +1,21 @@ +var group__mqtt__constants = +[ + [ "MQTT_PACKET_ID_INVALID", "group__mqtt__constants.html#ga9fde6503edb9eaad50ecd3392ab9992a", null ], + [ "MQTT_SUB_UNSUB_MAX_VECTORS", "group__mqtt__constants.html#ga928ea0bff12ebf9cf9fa9dfe5cafebbb", null ], + [ "MQTT_PACKET_TYPE_CONNECT", "group__mqtt__constants.html#ga64a0515bda2ecc89e97595535e1cf0ef", null ], + [ "MQTT_PACKET_TYPE_CONNACK", "group__mqtt__constants.html#gab14f6c39c303eac1a76816edfde7feab", null ], + [ "MQTT_PACKET_TYPE_PUBLISH", "group__mqtt__constants.html#ga5b2d79c61f2591c8e5772f974826d4ad", null ], + [ "MQTT_PACKET_TYPE_PUBACK", "group__mqtt__constants.html#ga5f279d63de47a973b41b95f74f47a4f6", null ], + [ "MQTT_PACKET_TYPE_PUBREC", "group__mqtt__constants.html#gafa2d8f28da39560f152076b99610e6a3", null ], + [ "MQTT_PACKET_TYPE_PUBREL", "group__mqtt__constants.html#gaeaa2ceecffda50e2d22ccecf046083c6", null ], + [ "MQTT_PACKET_TYPE_PUBCOMP", "group__mqtt__constants.html#ga478ecbc98d2ca83d4ce7db33622b5c3b", null ], + [ "MQTT_PACKET_TYPE_SUBSCRIBE", "group__mqtt__constants.html#ga80cfef333e60d967ca927b2e5e665f18", null ], + [ "MQTT_PACKET_TYPE_SUBACK", "group__mqtt__constants.html#ga307e0186aa17fdd0d6d181d3d2715766", null ], + [ "MQTT_PACKET_TYPE_UNSUBSCRIBE", "group__mqtt__constants.html#ga4a94c954cfcea31c8fc3e2adf092b228", null ], + [ "MQTT_PACKET_TYPE_UNSUBACK", "group__mqtt__constants.html#ga38bc8ed0b9a1581cf85cecdede7d1a64", null ], + [ "MQTT_PACKET_TYPE_PINGREQ", "group__mqtt__constants.html#gacbe28c7d081275d1805c2142ff792185", null ], + [ "MQTT_PACKET_TYPE_PINGRESP", "group__mqtt__constants.html#ga285fc02048e2482794042fa98639e514", null ], + [ "MQTT_PACKET_TYPE_DISCONNECT", "group__mqtt__constants.html#gaed07155a3d6fa4b7624b9f36ed33ec6d", null ], + [ "MQTT_PUBLISH_ACK_PACKET_SIZE", "group__mqtt__constants.html#ga26994fcfacb1cff892caa45ec31ca7c6", null ], + [ "MQTT_STATE_CURSOR_INITIALIZER", "group__mqtt__constants.html#ga666ad78e7eaaffa51f5cab96201a9476", null ] +]; \ No newline at end of file diff --git a/latest/coreMQTT/group__mqtt__enum__types.html b/latest/coreMQTT/group__mqtt__enum__types.html new file mode 100644 index 00000000..4df26dcb --- /dev/null +++ b/latest/coreMQTT/group__mqtt__enum__types.html @@ -0,0 +1,366 @@ + + + + + + + +coreMQTT: Enumerated Types + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
Enumerated Types
+
+
+ +

Enumerated types of the MQTT library. +More...

+ + + + + + + + + + + + + + + + + + + + +

+Enumerations

enum  MQTTConnectionStatus_t { MQTTNotConnected +, MQTTConnected + }
 Values indicating if an MQTT connection exists. More...
 
enum  MQTTPublishState_t {
+  MQTTStateNull = 0 +, MQTTPublishSend +, MQTTPubAckSend +, MQTTPubRecSend +,
+  MQTTPubRelSend +, MQTTPubCompSend +, MQTTPubAckPending +, MQTTPubRecPending +,
+  MQTTPubRelPending +, MQTTPubCompPending +, MQTTPublishDone +
+ }
 The state of QoS 1 or QoS 2 MQTT publishes, used in the state engine. More...
 
enum  MQTTPubAckType_t { MQTTPuback +, MQTTPubrec +, MQTTPubrel +, MQTTPubcomp + }
 Packet types used in acknowledging QoS 1 or QoS 2 publishes. More...
 
enum  MQTTSubAckStatus_t { MQTTSubAckSuccessQos0 = 0x00 +, MQTTSubAckSuccessQos1 = 0x01 +, MQTTSubAckSuccessQos2 = 0x02 +, MQTTSubAckFailure = 0x80 + }
 The status codes in the SUBACK response to a subscription request. More...
 
enum  MQTTStatus_t {
+  MQTTSuccess = 0 +, MQTTBadParameter +, MQTTNoMemory +, MQTTSendFailed +,
+  MQTTRecvFailed +, MQTTBadResponse +, MQTTServerRefused +, MQTTNoDataAvailable +,
+  MQTTIllegalState +, MQTTStateCollision +, MQTTKeepAliveTimeout +, MQTTNeedMoreBytes +
+ }
 Return codes from MQTT functions. More...
 
enum  MQTTQoS_t { MQTTQoS0 = 0 +, MQTTQoS1 = 1 +, MQTTQoS2 = 2 + }
 MQTT Quality of Service values. More...
 
+

Detailed Description

+

Enumerated types of the MQTT library.

+

Enumeration Type Documentation

+ +

◆ MQTTConnectionStatus_t

+ +
+
+ + + + +
enum MQTTConnectionStatus_t
+
+ +

Values indicating if an MQTT connection exists.

+ + + +
Enumerator
MQTTNotConnected 

MQTT Connection is inactive.

+
MQTTConnected 

MQTT Connection is active.

+
+ +
+
+ +

◆ MQTTPublishState_t

+ +
+
+ + + + +
enum MQTTPublishState_t
+
+ +

The state of QoS 1 or QoS 2 MQTT publishes, used in the state engine.

+ + + + + + + + + + + + +
Enumerator
MQTTStateNull 

An empty state with no corresponding PUBLISH.

+
MQTTPublishSend 

The library will send an outgoing PUBLISH packet.

+
MQTTPubAckSend 

The library will send a PUBACK for a received PUBLISH.

+
MQTTPubRecSend 

The library will send a PUBREC for a received PUBLISH.

+
MQTTPubRelSend 

The library will send a PUBREL for a received PUBREC.

+
MQTTPubCompSend 

The library will send a PUBCOMP for a received PUBREL.

+
MQTTPubAckPending 

The library is awaiting a PUBACK for an outgoing PUBLISH.

+
MQTTPubRecPending 

The library is awaiting a PUBREC for an outgoing PUBLISH.

+
MQTTPubRelPending 

The library is awaiting a PUBREL for an incoming PUBLISH.

+
MQTTPubCompPending 

The library is awaiting a PUBCOMP for an outgoing PUBLISH.

+
MQTTPublishDone 

The PUBLISH has been completed.

+
+ +
+
+ +

◆ MQTTPubAckType_t

+ +
+
+ + + + +
enum MQTTPubAckType_t
+
+ +

Packet types used in acknowledging QoS 1 or QoS 2 publishes.

+ + + + + +
Enumerator
MQTTPuback 

PUBACKs are sent in response to a QoS 1 PUBLISH.

+
MQTTPubrec 

PUBRECs are sent in response to a QoS 2 PUBLISH.

+
MQTTPubrel 

PUBRELs are sent in response to a PUBREC.

+
MQTTPubcomp 

PUBCOMPs are sent in response to a PUBREL.

+
+ +
+
+ +

◆ MQTTSubAckStatus_t

+ +
+
+ + + + +
enum MQTTSubAckStatus_t
+
+ +

The status codes in the SUBACK response to a subscription request.

+ + + + + +
Enumerator
MQTTSubAckSuccessQos0 

Success with a maximum delivery at QoS 0.

+
MQTTSubAckSuccessQos1 

Success with a maximum delivery at QoS 1.

+
MQTTSubAckSuccessQos2 

Success with a maximum delivery at QoS 2.

+
MQTTSubAckFailure 

Failure.

+
+ +
+
+ +

◆ MQTTStatus_t

+ +
+
+ + + + +
enum MQTTStatus_t
+
+ +

Return codes from MQTT functions.

+ + + + + + + + + + + + + +
Enumerator
MQTTSuccess 

Function completed successfully.

+
MQTTBadParameter 

At least one parameter was invalid.

+
MQTTNoMemory 

A provided buffer was too small.

+
MQTTSendFailed 

The transport send function failed.

+
MQTTRecvFailed 

The transport receive function failed.

+
MQTTBadResponse 

An invalid packet was received from the server.

+
MQTTServerRefused 

The server refused a CONNECT or SUBSCRIBE.

+
MQTTNoDataAvailable 

No data available from the transport interface.

+
MQTTIllegalState 

An illegal state in the state record.

+
MQTTStateCollision 

A collision with an existing state record entry.

+
MQTTKeepAliveTimeout 

Timeout while waiting for PINGRESP.

+
MQTTNeedMoreBytes 

MQTT_ProcessLoop/MQTT_ReceiveLoop has received incomplete data; it should be called again (probably after a delay).

+
+ +
+
+ +

◆ MQTTQoS_t

+ +
+
+ + + + +
enum MQTTQoS_t
+
+ +

MQTT Quality of Service values.

+ + + + +
Enumerator
MQTTQoS0 

Delivery at most once.

+
MQTTQoS1 

Delivery at least once.

+
MQTTQoS2 

Delivery exactly once.

+
+ +
+
+
+
+ + + + diff --git a/latest/coreMQTT/group__mqtt__enum__types.js b/latest/coreMQTT/group__mqtt__enum__types.js new file mode 100644 index 00000000..c6948c66 --- /dev/null +++ b/latest/coreMQTT/group__mqtt__enum__types.js @@ -0,0 +1,51 @@ +var group__mqtt__enum__types = +[ + [ "MQTTConnectionStatus_t", "group__mqtt__enum__types.html#ga9f84d003695205cf10a7bd0bafb3dbf6", [ + [ "MQTTNotConnected", "group__mqtt__enum__types.html#gga9f84d003695205cf10a7bd0bafb3dbf6a0320177ebf1f1b2e24646b44702cec69", null ], + [ "MQTTConnected", "group__mqtt__enum__types.html#gga9f84d003695205cf10a7bd0bafb3dbf6a82c8f64d976734e5632e5257bc429ef5", null ] + ] ], + [ "MQTTPublishState_t", "group__mqtt__enum__types.html#ga0480de7552eedd739a26a23fa8e6fd94", [ + [ "MQTTStateNull", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a8349567b7a9efb3913a64a8f4f6fe5c9", null ], + [ "MQTTPublishSend", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a896b1507647b504c9208580e4cde26ad", null ], + [ "MQTTPubAckSend", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a65f6f7b343a30fc0558e3aeeb8c97f35", null ], + [ "MQTTPubRecSend", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a11e2319a2b25b82121471743d39761e1", null ], + [ "MQTTPubRelSend", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a5d2ee2709c6dc7a1eb8b9c40f318909b", null ], + [ "MQTTPubCompSend", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a7d88904d550b502b4424a41aa4205e56", null ], + [ "MQTTPubAckPending", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94ab086c55acf106cdc8d420f90899b6803", null ], + [ "MQTTPubRecPending", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a1bea59454700be9b683b7eb8aaf6bb4f", null ], + [ "MQTTPubRelPending", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a695431cde1dc9dc5a2dcbd10eba49df2", null ], + [ "MQTTPubCompPending", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a3281a28d1829d954b596f091b547b627", null ], + [ "MQTTPublishDone", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94ad07733793a235ef9a6a04d16637cd7dc", null ] + ] ], + [ "MQTTPubAckType_t", "group__mqtt__enum__types.html#ga8c1bee959b3ed5fab2a2688dd72bf237", [ + [ "MQTTPuback", "group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a53d5939c680962f37c15ee87ffd63d0f", null ], + [ "MQTTPubrec", "group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a8c98d5d1a68dda33d9039009ab4ef053", null ], + [ "MQTTPubrel", "group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237af2d737088a231c88e7603acfdbc4fc8c", null ], + [ "MQTTPubcomp", "group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a910c34311ad6a2341afc04839e1c13bd", null ] + ] ], + [ "MQTTSubAckStatus_t", "group__mqtt__enum__types.html#ga48dabc1579e3c0ac6058ce9068054611", [ + [ "MQTTSubAckSuccessQos0", "group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611abcc3040d7d53025baee3542c40758abb", null ], + [ "MQTTSubAckSuccessQos1", "group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611ab180361a6da712c8144d8c499537787d", null ], + [ "MQTTSubAckSuccessQos2", "group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611a877b2afbc6ec7d9ab57d4862caadf4f1", null ], + [ "MQTTSubAckFailure", "group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611aeb83b20da8eda934cde6b92db225a808", null ] + ] ], + [ "MQTTStatus_t", "group__mqtt__enum__types.html#gaba7ec045874a1c3432f99173367f735c", [ + [ "MQTTSuccess", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca484e062cb4f3fccc1858dd25cfeee056", null ], + [ "MQTTBadParameter", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa39030c93b0263b2699502a074f003b5", null ], + [ "MQTTNoMemory", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735cab1be4db832a0468f024243bca151a8df", null ], + [ "MQTTSendFailed", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735cafd06b63fe9677fa2af06b0f4c7d4ad55", null ], + [ "MQTTRecvFailed", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa14bc8aa4ad218702d782366945d43ac", null ], + [ "MQTTBadResponse", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa5d7507e7664a14d63a8bc44b280093e", null ], + [ "MQTTServerRefused", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca25a3d1747e308e99daa805fe576f84b9", null ], + [ "MQTTNoDataAvailable", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca676f21c0ddf297ae3ec874bc829aa957", null ], + [ "MQTTIllegalState", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca67905d7a05f98faa557a73eb5092bd8f", null ], + [ "MQTTStateCollision", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca8d05b92240dea6df08eab5a9e3799c11", null ], + [ "MQTTKeepAliveTimeout", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca076ca8965e836a06e707a94adb26144f", null ], + [ "MQTTNeedMoreBytes", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa97df53014d919df5ecd54398f89f9b9", null ] + ] ], + [ "MQTTQoS_t", "group__mqtt__enum__types.html#gae308a5928d7f537379c29a894228093a", [ + [ "MQTTQoS0", "group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aaad51b23a1ae1417f96d8f343c788d1d2", null ], + [ "MQTTQoS1", "group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aa019d0b8a8cfadb6f98462b046bdacbb2", null ], + [ "MQTTQoS2", "group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aa85e04ac0465cbdef6dd69ff71b2bbfbb", null ] + ] ] +]; \ No newline at end of file diff --git a/latest/coreMQTT/group__mqtt__struct__types.html b/latest/coreMQTT/group__mqtt__struct__types.html new file mode 100644 index 00000000..3976a95d --- /dev/null +++ b/latest/coreMQTT/group__mqtt__struct__types.html @@ -0,0 +1,159 @@ + + + + + + + +coreMQTT: Parameter Structures + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
Parameter Structures
+
+
+ +

Structures passed as parameters to MQTT library functions. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Structures

struct  MQTTPubAckInfo_t
 An element of the state engine records for QoS 1 or Qos 2 publishes. More...
 
struct  MQTTContext_t
 A struct representing an MQTT connection. More...
 
struct  MQTTDeserializedInfo_t
 Struct to hold deserialized packet information for an MQTTEventCallback_t callback. More...
 
struct  MQTTFixedBuffer_t
 Buffer passed to MQTT library. More...
 
struct  MQTTConnectInfo_t
 MQTT CONNECT packet parameters. More...
 
struct  MQTTSubscribeInfo_t
 MQTT SUBSCRIBE packet parameters. More...
 
struct  MQTTPublishInfo_t
 MQTT PUBLISH packet parameters. More...
 
struct  MQTTPacketInfo_t
 MQTT incoming packet parameters. More...
 
struct  TransportInterface_t
 The transport layer interface. More...
 
+ + + + +

+Typedefs

+typedef struct NetworkContext NetworkContext_t
 The NetworkContext is an incomplete type. An implementation of this interface must define struct NetworkContext for the system requirements. This context is passed into the network interface functions.
 
+

Detailed Description

+

Structures passed as parameters to MQTT library functions.

+

These structures are passed as parameters to library functions. Documentation for these structures will state the functions associated with each parameter structure and the purpose of each member.

+
+
+ + + + diff --git a/latest/coreMQTT/group__mqtt__struct__types.js b/latest/coreMQTT/group__mqtt__struct__types.js new file mode 100644 index 00000000..62fc0825 --- /dev/null +++ b/latest/coreMQTT/group__mqtt__struct__types.js @@ -0,0 +1,73 @@ +var group__mqtt__struct__types = +[ + [ "MQTTPubAckInfo_t", "struct_m_q_t_t_pub_ack_info__t.html", [ + [ "packetId", "struct_m_q_t_t_pub_ack_info__t.html#a66cef7b43af5d7fdd33b5d2dc766b2d0", null ], + [ "qos", "struct_m_q_t_t_pub_ack_info__t.html#a086fcd48ef0b787697526a95c861e8a0", null ], + [ "publishState", "struct_m_q_t_t_pub_ack_info__t.html#a61314203ef87a231c6489c68b579de34", null ] + ] ], + [ "MQTTContext_t", "struct_m_q_t_t_context__t.html", [ + [ "outgoingPublishRecords", "struct_m_q_t_t_context__t.html#a4ea1e37e0e81f010fbf84365ac2ef6de", null ], + [ "incomingPublishRecords", "struct_m_q_t_t_context__t.html#afc147663a5933de81212fa77057f0a4d", null ], + [ "outgoingPublishRecordMaxCount", "struct_m_q_t_t_context__t.html#a2851073e252d1e744596272ef13dd14a", null ], + [ "incomingPublishRecordMaxCount", "struct_m_q_t_t_context__t.html#aa33ed2e10380a854629f1386d0323ea8", null ], + [ "transportInterface", "struct_m_q_t_t_context__t.html#a87ab9d61e7711325c2c85ce3ce63386a", null ], + [ "networkBuffer", "struct_m_q_t_t_context__t.html#a231c5576a6ce389317a3f00f95628276", null ], + [ "nextPacketId", "struct_m_q_t_t_context__t.html#af47ed55ad7e9bb112324f5f209b70534", null ], + [ "connectStatus", "struct_m_q_t_t_context__t.html#a4e38c4dc77e7751a0ad8730a41bee47f", null ], + [ "getTime", "struct_m_q_t_t_context__t.html#aabe1d302a16771292151013e8e30c582", null ], + [ "appCallback", "struct_m_q_t_t_context__t.html#a73bd9259db9c3a9b84518cbf928ed91f", null ], + [ "lastPacketTxTime", "struct_m_q_t_t_context__t.html#a01acf90953e830ba3e7f44182cb1d482", null ], + [ "lastPacketRxTime", "struct_m_q_t_t_context__t.html#a7111ef16e4a4e75a72861f6f3ea8a7c3", null ], + [ "controlPacketSent", "struct_m_q_t_t_context__t.html#af9724f2426132e3ce96a03892902ef89", null ], + [ "index", "struct_m_q_t_t_context__t.html#a41b7735cd0746563483b72e17cf103aa", null ], + [ "keepAliveIntervalSec", "struct_m_q_t_t_context__t.html#afd6071827ef48b230212a5725c2075be", null ], + [ "pingReqSendTimeMs", "struct_m_q_t_t_context__t.html#acca3efa4146d85f7e874c7c326e23556", null ], + [ "waitingForPingResp", "struct_m_q_t_t_context__t.html#ac7073f43645f7b7c0c5b7763980004bb", null ] + ] ], + [ "MQTTDeserializedInfo_t", "struct_m_q_t_t_deserialized_info__t.html", [ + [ "packetIdentifier", "struct_m_q_t_t_deserialized_info__t.html#af4df2a9926a4a68059195daa712d9b84", null ], + [ "pPublishInfo", "struct_m_q_t_t_deserialized_info__t.html#ac347273fae1e92b9cbeda1714066c1de", null ], + [ "deserializationResult", "struct_m_q_t_t_deserialized_info__t.html#a7df1b7b60404c9f1604fec0081d2625d", null ] + ] ], + [ "MQTTFixedBuffer_t", "struct_m_q_t_t_fixed_buffer__t.html", [ + [ "pBuffer", "struct_m_q_t_t_fixed_buffer__t.html#acea147448e044870fb36b7fa2347dbd6", null ], + [ "size", "struct_m_q_t_t_fixed_buffer__t.html#a0b0b6a93cc62751ebeb03095d5431636", null ] + ] ], + [ "MQTTConnectInfo_t", "struct_m_q_t_t_connect_info__t.html", [ + [ "cleanSession", "struct_m_q_t_t_connect_info__t.html#a606e7765c4f2215fb2bf630f6eb9ff6b", null ], + [ "keepAliveSeconds", "struct_m_q_t_t_connect_info__t.html#a7d05d53261732ebdfbb9ee665a347591", null ], + [ "pClientIdentifier", "struct_m_q_t_t_connect_info__t.html#a010f8f6993cbf8899648d5c515ff7884", null ], + [ "clientIdentifierLength", "struct_m_q_t_t_connect_info__t.html#a8077ef36ab318f3d35bee6f098fa54d4", null ], + [ "pUserName", "struct_m_q_t_t_connect_info__t.html#a1118d7d3251a11445318557280db53b4", null ], + [ "userNameLength", "struct_m_q_t_t_connect_info__t.html#a7165be3bb06d4527ab4eb773b50e05e1", null ], + [ "pPassword", "struct_m_q_t_t_connect_info__t.html#acec6c79a11d2f0f130802393f34d2b5e", null ], + [ "passwordLength", "struct_m_q_t_t_connect_info__t.html#a818c4e212a12020a4109eb890ec96383", null ] + ] ], + [ "MQTTSubscribeInfo_t", "struct_m_q_t_t_subscribe_info__t.html", [ + [ "qos", "struct_m_q_t_t_subscribe_info__t.html#a64cf2e423f60cfec122eeaef80c0fd86", null ], + [ "pTopicFilter", "struct_m_q_t_t_subscribe_info__t.html#adb0b28240fdcd82a85f11cf2f8b5bbf0", null ], + [ "topicFilterLength", "struct_m_q_t_t_subscribe_info__t.html#a6972f8e036f8bde9b1f23a2aacb61382", null ] + ] ], + [ "MQTTPublishInfo_t", "struct_m_q_t_t_publish_info__t.html", [ + [ "qos", "struct_m_q_t_t_publish_info__t.html#a178224d02b4acdec7e08e88de0e4b399", null ], + [ "retain", "struct_m_q_t_t_publish_info__t.html#a343b0af89c46a900db4aa5c775a0975a", null ], + [ "dup", "struct_m_q_t_t_publish_info__t.html#aa1c8954e83bfa678d1ff5429679d4e89", null ], + [ "pTopicName", "struct_m_q_t_t_publish_info__t.html#aa80e8ca282d01630f878ad0afe81d7a4", null ], + [ "topicNameLength", "struct_m_q_t_t_publish_info__t.html#a6161c792d20cc7cf8284c1b71ea1145f", null ], + [ "pPayload", "struct_m_q_t_t_publish_info__t.html#afc28299f4f625f5e674bb61b42f03380", null ], + [ "payloadLength", "struct_m_q_t_t_publish_info__t.html#a7997964e11571f35f0c3b729db0f760f", null ] + ] ], + [ "MQTTPacketInfo_t", "struct_m_q_t_t_packet_info__t.html", [ + [ "type", "struct_m_q_t_t_packet_info__t.html#a7fef40548c1aa0f0e7f812a6a7243758", null ], + [ "pRemainingData", "struct_m_q_t_t_packet_info__t.html#ac66cedff052bc844ec9b296387df60bc", null ], + [ "remainingLength", "struct_m_q_t_t_packet_info__t.html#a7c85becf08de0ec9776dd4be1fcc4bf8", null ], + [ "headerLength", "struct_m_q_t_t_packet_info__t.html#aa7de1631ed8e08410942d36a72db558a", null ] + ] ], + [ "TransportInterface_t", "struct_transport_interface__t.html", [ + [ "recv", "struct_transport_interface__t.html#a7c34e9b865e2a509306f09c7dfa3699e", null ], + [ "send", "struct_transport_interface__t.html#a01cd9935e9a5266ca196243a0054d489", null ], + [ "writev", "struct_transport_interface__t.html#a8cf677fbeee53d270daa6dacfa138b79", null ], + [ "pNetworkContext", "struct_transport_interface__t.html#aaf4702050bef8d62714a4d3900e95087", null ] + ] ], + [ "NetworkContext_t", "group__mqtt__struct__types.html#ga7769e434e7811caed8cd6fd7f9ec26ec", null ] +]; \ No newline at end of file diff --git a/latest/coreMQTT/index.html b/latest/coreMQTT/index.html new file mode 100644 index 00000000..f12f447a --- /dev/null +++ b/latest/coreMQTT/index.html @@ -0,0 +1,143 @@ + + + + + + + +coreMQTT: Overview + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Overview
+
+
+

MQTT 3.1.1 client library

+
+

‍MQTT stands for MQ Telemetry Transport. It is a publish/subscribe, extremely simple and lightweight messaging protocol, designed for constrained devices and low-bandwidth, high-latency or unreliable networks. The design principles are to minimise network bandwidth and device resource requirements whilst also attempting to ensure reliability and some degree of assurance of delivery. These principles also turn out to make the protocol ideal of the emerging "machine-to-machine" (M2M) or "Internet of Things" world of connected devices, and for mobile applications where bandwidth and battery power are at a premium.

+
+

Official description of MQTT from mqtt.org
+

+

This MQTT library implements the client side of the MQTT 3.1.1 protocol. This library is optimized for resource constrained embedded devices. Features of this library include:

    +
  • Fully synchronous API, to allow applications to completely manage their concurrency and multi-threading method.
  • +
  • Operations on fixed buffers, so that applications may control their memory allocation strategy.
  • +
  • Scalable performance and footprint. The configuration settings allow this library to be tailored to a system's resources.
  • +
+

Please see https://github.com/aws/aws-iot-device-sdk-embedded-C/tree/main/demos/mqtt for example code demonstrating integration with TLS.

+

+Memory Requirements

+

Memory requirements of the MQTT library.

+

+ + + + + + + + + + + + +
Code Size of coreMQTT (example generated with GCC for ARM Cortex-M)
File
With -O1 Optimization
With -Os Optimization
core_mqtt.c
4.1K
3.5K
core_mqtt_state.c
1.7K
1.3K
core_mqtt_serializer.c
2.8K
2.2K
Total estimates
8.6K
7.0K
+

+
+
+
+ + + + diff --git a/latest/coreMQTT/index.js b/latest/coreMQTT/index.js new file mode 100644 index 00000000..d1fc3cbb --- /dev/null +++ b/latest/coreMQTT/index.js @@ -0,0 +1,4 @@ +var index = +[ + [ "Memory Requirements", "index.html#mqtt_memory_requirements", null ] +]; \ No newline at end of file diff --git a/latest/coreMQTT/jquery.js b/latest/coreMQTT/jquery.js new file mode 100644 index 00000000..1dffb65b --- /dev/null +++ b/latest/coreMQTT/jquery.js @@ -0,0 +1,34 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=y(e||this.defaultElement||this)[0],this.element=y(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=y(),this.hoverable=y(),this.focusable=y(),this.classesElementLookup={},e!==this&&(y.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=y(e.style?e.ownerDocument:e.document||e),this.window=y(this.document[0].defaultView||this.document[0].parentWindow)),this.options=y.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:y.noop,_create:y.noop,_init:y.noop,destroy:function(){var i=this;this._destroy(),y.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:y.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return y.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=y.widget.extend({},this.options[t]),n=0;n
"),i=e.children()[0];return y("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),s=t-i},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.widthx(D(s),D(n))?o.important="horizontal":o.important="vertical",p.using.call(this,t,o)}),h.offset(y.extend(l,{using:t}))})},y.ui.position={fit:{left:function(t,e){var i=e.within,s=i.isWindow?i.scrollLeft:i.offset.left,n=i.width,o=t.left-e.collisionPosition.marginLeft,h=s-o,a=o+e.collisionWidth-n-s;e.collisionWidth>n?0n?0=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),y.ui.plugin={add:function(t,e,i){var s,n=y.ui[t].prototype;for(s in i)n.plugins[s]=n.plugins[s]||[],n.plugins[s].push([e,i[s]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;n").css({overflow:"hidden",position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,t={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(t),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(t),this._proportionallyResize()),this._setupHandles(),e.autoHide&&y(this.element).on("mouseenter",function(){e.disabled||(i._removeClass("ui-resizable-autohide"),i._handles.show())}).on("mouseleave",function(){e.disabled||i.resizing||(i._addClass("ui-resizable-autohide"),i._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy(),this._addedHandles.remove();function t(t){y(t).removeData("resizable").removeData("ui-resizable").off(".resizable")}var e;return this.elementIsWrapper&&(t(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),t(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;case"aspectRatio":this._aspectRatio=!!e}},_setupHandles:function(){var t,e,i,s,n,o=this.options,h=this;if(this.handles=o.handles||(y(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=y(),this._addedHandles=y(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),i=this.handles.split(","),this.handles={},e=0;e"),this._addClass(n,"ui-resizable-handle "+s),n.css({zIndex:o.zIndex}),this.handles[t]=".ui-resizable-"+t,this.element.children(this.handles[t]).length||(this.element.append(n),this._addedHandles=this._addedHandles.add(n));this._renderAxis=function(t){var e,i,s;for(e in t=t||this.element,this.handles)this.handles[e].constructor===String?this.handles[e]=this.element.children(this.handles[e]).first().show():(this.handles[e].jquery||this.handles[e].nodeType)&&(this.handles[e]=y(this.handles[e]),this._on(this.handles[e],{mousedown:h._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(i=y(this.handles[e],this.element),s=/sw|ne|nw|se|n|s/.test(e)?i.outerHeight():i.outerWidth(),i=["padding",/ne|nw|n/.test(e)?"Top":/se|sw|s/.test(e)?"Bottom":/^e$/.test(e)?"Right":"Left"].join(""),t.css(i,s),this._proportionallyResize()),this._handles=this._handles.add(this.handles[e])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){h.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),h.axis=n&&n[1]?n[1]:"se")}),o.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._addedHandles.remove()},_mouseCapture:function(t){var e,i,s=!1;for(e in this.handles)(i=y(this.handles[e])[0])!==t.target&&!y.contains(i,t.target)||(s=!0);return!this.options.disabled&&s},_mouseStart:function(t){var e,i,s=this.options,n=this.element;return this.resizing=!0,this._renderProxy(),e=this._num(this.helper.css("left")),i=this._num(this.helper.css("top")),s.containment&&(e+=y(s.containment).scrollLeft()||0,i+=y(s.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:e,top:i},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:n.width(),height:n.height()},this.originalSize=this._helper?{width:n.outerWidth(),height:n.outerHeight()}:{width:n.width(),height:n.height()},this.sizeDiff={width:n.outerWidth()-n.width(),height:n.outerHeight()-n.height()},this.originalPosition={left:e,top:i},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio="number"==typeof s.aspectRatio?s.aspectRatio:this.originalSize.width/this.originalSize.height||1,s=y(".ui-resizable-"+this.axis).css("cursor"),y("body").css("cursor","auto"===s?this.axis+"-resize":s),this._addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var e=this.originalMousePosition,i=this.axis,s=t.pageX-e.left||0,e=t.pageY-e.top||0,i=this._change[i];return this._updatePrevProperties(),i&&(e=i.apply(this,[t,s,e]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(e=this._updateRatio(e,t)),e=this._respectSize(e,t),this._updateCache(e),this._propagate("resize",t),e=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),y.isEmptyObject(e)||(this._updatePrevProperties(),this._trigger("resize",t,this.ui()),this._applyChanges())),!1},_mouseStop:function(t){this.resizing=!1;var e,i,s,n=this.options,o=this;return this._helper&&(s=(e=(i=this._proportionallyResizeElements).length&&/textarea/i.test(i[0].nodeName))&&this._hasScroll(i[0],"left")?0:o.sizeDiff.height,i=e?0:o.sizeDiff.width,e={width:o.helper.width()-i,height:o.helper.height()-s},i=parseFloat(o.element.css("left"))+(o.position.left-o.originalPosition.left)||null,s=parseFloat(o.element.css("top"))+(o.position.top-o.originalPosition.top)||null,n.animate||this.element.css(y.extend(e,{top:s,left:i})),o.helper.height(o.size.height),o.helper.width(o.size.width),this._helper&&!n.animate&&this._proportionallyResize()),y("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s=this.options,n={minWidth:this._isNumber(s.minWidth)?s.minWidth:0,maxWidth:this._isNumber(s.maxWidth)?s.maxWidth:1/0,minHeight:this._isNumber(s.minHeight)?s.minHeight:0,maxHeight:this._isNumber(s.maxHeight)?s.maxHeight:1/0};(this._aspectRatio||t)&&(e=n.minHeight*this.aspectRatio,i=n.minWidth/this.aspectRatio,s=n.maxHeight*this.aspectRatio,t=n.maxWidth/this.aspectRatio,e>n.minWidth&&(n.minWidth=e),i>n.minHeight&&(n.minHeight=i),st.width,h=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,a=this.originalPosition.left+this.originalSize.width,r=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),i=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),h&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=a-e.minWidth),s&&l&&(t.left=a-e.maxWidth),h&&i&&(t.top=r-e.minHeight),n&&i&&(t.top=r-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];e<4;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;e").css({overflow:"hidden"}),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++e.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize;return{left:this.originalPosition.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize;return{top:this.originalPosition.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(t,e,i){return y.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},sw:function(t,e,i){return y.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,e,i]))},ne:function(t,e,i){return y.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},nw:function(t,e,i){return y.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,e,i]))}},_propagate:function(t,e){y.ui.plugin.call(this,t,[e,this.ui()]),"resize"!==t&&this._trigger(t,e,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),y.ui.plugin.add("resizable","animate",{stop:function(e){var i=y(this).resizable("instance"),t=i.options,s=i._proportionallyResizeElements,n=s.length&&/textarea/i.test(s[0].nodeName),o=n&&i._hasScroll(s[0],"left")?0:i.sizeDiff.height,h=n?0:i.sizeDiff.width,n={width:i.size.width-h,height:i.size.height-o},h=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,o=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(y.extend(n,o&&h?{top:o,left:h}:{}),{duration:t.animateDuration,easing:t.animateEasing,step:function(){var t={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};s&&s.length&&y(s[0]).css({width:t.width,height:t.height}),i._updateCache(t),i._propagate("resize",e)}})}}),y.ui.plugin.add("resizable","containment",{start:function(){var i,s,n=y(this).resizable("instance"),t=n.options,e=n.element,o=t.containment,h=o instanceof y?o.get(0):/parent/.test(o)?e.parent().get(0):o;h&&(n.containerElement=y(h),/document/.test(o)||o===document?(n.containerOffset={left:0,top:0},n.containerPosition={left:0,top:0},n.parentData={element:y(document),left:0,top:0,width:y(document).width(),height:y(document).height()||document.body.parentNode.scrollHeight}):(i=y(h),s=[],y(["Top","Right","Left","Bottom"]).each(function(t,e){s[t]=n._num(i.css("padding"+e))}),n.containerOffset=i.offset(),n.containerPosition=i.position(),n.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},t=n.containerOffset,e=n.containerSize.height,o=n.containerSize.width,o=n._hasScroll(h,"left")?h.scrollWidth:o,e=n._hasScroll(h)?h.scrollHeight:e,n.parentData={element:h,left:t.left,top:t.top,width:o,height:e}))},resize:function(t){var e=y(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.position,o=e._aspectRatio||t.shiftKey,h={top:0,left:0},a=e.containerElement,t=!0;a[0]!==document&&/static/.test(a.css("position"))&&(h=s),n.left<(e._helper?s.left:0)&&(e.size.width=e.size.width+(e._helper?e.position.left-s.left:e.position.left-h.left),o&&(e.size.height=e.size.width/e.aspectRatio,t=!1),e.position.left=i.helper?s.left:0),n.top<(e._helper?s.top:0)&&(e.size.height=e.size.height+(e._helper?e.position.top-s.top:e.position.top),o&&(e.size.width=e.size.height*e.aspectRatio,t=!1),e.position.top=e._helper?s.top:0),i=e.containerElement.get(0)===e.element.parent().get(0),n=/relative|absolute/.test(e.containerElement.css("position")),i&&n?(e.offset.left=e.parentData.left+e.position.left,e.offset.top=e.parentData.top+e.position.top):(e.offset.left=e.element.offset().left,e.offset.top=e.element.offset().top),n=Math.abs(e.sizeDiff.width+(e._helper?e.offset.left-h.left:e.offset.left-s.left)),s=Math.abs(e.sizeDiff.height+(e._helper?e.offset.top-h.top:e.offset.top-s.top)),n+e.size.width>=e.parentData.width&&(e.size.width=e.parentData.width-n,o&&(e.size.height=e.size.width/e.aspectRatio,t=!1)),s+e.size.height>=e.parentData.height&&(e.size.height=e.parentData.height-s,o&&(e.size.width=e.size.height*e.aspectRatio,t=!1)),t||(e.position.left=e.prevPosition.left,e.position.top=e.prevPosition.top,e.size.width=e.prevSize.width,e.size.height=e.prevSize.height)},stop:function(){var t=y(this).resizable("instance"),e=t.options,i=t.containerOffset,s=t.containerPosition,n=t.containerElement,o=y(t.helper),h=o.offset(),a=o.outerWidth()-t.sizeDiff.width,o=o.outerHeight()-t.sizeDiff.height;t._helper&&!e.animate&&/relative/.test(n.css("position"))&&y(this).css({left:h.left-s.left-i.left,width:a,height:o}),t._helper&&!e.animate&&/static/.test(n.css("position"))&&y(this).css({left:h.left-s.left-i.left,width:a,height:o})}}),y.ui.plugin.add("resizable","alsoResize",{start:function(){var t=y(this).resizable("instance").options;y(t.alsoResize).each(function(){var t=y(this);t.data("ui-resizable-alsoresize",{width:parseFloat(t.width()),height:parseFloat(t.height()),left:parseFloat(t.css("left")),top:parseFloat(t.css("top"))})})},resize:function(t,i){var e=y(this).resizable("instance"),s=e.options,n=e.originalSize,o=e.originalPosition,h={height:e.size.height-n.height||0,width:e.size.width-n.width||0,top:e.position.top-o.top||0,left:e.position.left-o.left||0};y(s.alsoResize).each(function(){var t=y(this),s=y(this).data("ui-resizable-alsoresize"),n={},e=t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];y.each(e,function(t,e){var i=(s[e]||0)+(h[e]||0);i&&0<=i&&(n[e]=i||null)}),t.css(n)})},stop:function(){y(this).removeData("ui-resizable-alsoresize")}}),y.ui.plugin.add("resizable","ghost",{start:function(){var t=y(this).resizable("instance"),e=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}),t._addClass(t.ghost,"ui-resizable-ghost"),!1!==y.uiBackCompat&&"string"==typeof t.options.ghost&&t.ghost.addClass(this.options.ghost),t.ghost.appendTo(t.helper)},resize:function(){var t=y(this).resizable("instance");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=y(this).resizable("instance");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),y.ui.plugin.add("resizable","grid",{resize:function(){var t,e=y(this).resizable("instance"),i=e.options,s=e.size,n=e.originalSize,o=e.originalPosition,h=e.axis,a="number"==typeof i.grid?[i.grid,i.grid]:i.grid,r=a[0]||1,l=a[1]||1,u=Math.round((s.width-n.width)/r)*r,p=Math.round((s.height-n.height)/l)*l,d=n.width+u,c=n.height+p,f=i.maxWidth&&i.maxWidthd,s=i.minHeight&&i.minHeight>c;i.grid=a,m&&(d+=r),s&&(c+=l),f&&(d-=r),g&&(c-=l),/^(se|s|e)$/.test(h)?(e.size.width=d,e.size.height=c):/^(ne)$/.test(h)?(e.size.width=d,e.size.height=c,e.position.top=o.top-p):/^(sw)$/.test(h)?(e.size.width=d,e.size.height=c,e.position.left=o.left-u):((c-l<=0||d-r<=0)&&(t=e._getPaddingPlusBorderDimensions(this)),0=f[g]?0:Math.min(f[g],n));!a&&1-1){targetElements.on(evt+EVENT_NAMESPACE,function elementToggle(event){$.powerTip.toggle(this,event)})}else{targetElements.on(evt+EVENT_NAMESPACE,function elementOpen(event){$.powerTip.show(this,event)})}});$.each(options.closeEvents,function(idx,evt){if($.inArray(evt,options.openEvents)<0){targetElements.on(evt+EVENT_NAMESPACE,function elementClose(event){$.powerTip.hide(this,!isMouseEvent(event))})}});targetElements.on("keydown"+EVENT_NAMESPACE,function elementKeyDown(event){if(event.keyCode===27){$.powerTip.hide(this,true)}})}return targetElements};$.fn.powerTip.defaults={fadeInTime:200,fadeOutTime:100,followMouse:false,popupId:"powerTip",popupClass:null,intentSensitivity:7,intentPollInterval:100,closeDelay:100,placement:"n",smartPlacement:false,offset:10,mouseOnToPopup:false,manual:false,openEvents:["mouseenter","focus"],closeEvents:["mouseleave","blur"]};$.fn.powerTip.smartPlacementLists={n:["n","ne","nw","s"],e:["e","ne","se","w","nw","sw","n","s","e"],s:["s","se","sw","n"],w:["w","nw","sw","e","ne","se","n","s","w"],nw:["nw","w","sw","n","s","se","nw"],ne:["ne","e","se","n","s","sw","ne"],sw:["sw","w","nw","s","n","ne","sw"],se:["se","e","ne","s","n","nw","se"],"nw-alt":["nw-alt","n","ne-alt","sw-alt","s","se-alt","w","e"],"ne-alt":["ne-alt","n","nw-alt","se-alt","s","sw-alt","e","w"],"sw-alt":["sw-alt","s","se-alt","nw-alt","n","ne-alt","w","e"],"se-alt":["se-alt","s","sw-alt","ne-alt","n","nw-alt","e","w"]};$.powerTip={show:function apiShowTip(element,event){if(isMouseEvent(event)){trackMouse(event);session.previousX=event.pageX;session.previousY=event.pageY;$(element).data(DATA_DISPLAYCONTROLLER).show()}else{$(element).first().data(DATA_DISPLAYCONTROLLER).show(true,true)}return element},reposition:function apiResetPosition(element){$(element).first().data(DATA_DISPLAYCONTROLLER).resetPosition();return element},hide:function apiCloseTip(element,immediate){var displayController;immediate=element?immediate:true;if(element){displayController=$(element).first().data(DATA_DISPLAYCONTROLLER)}else if(session.activeHover){displayController=session.activeHover.data(DATA_DISPLAYCONTROLLER)}if(displayController){displayController.hide(immediate)}return element},toggle:function apiToggle(element,event){if(session.activeHover&&session.activeHover.is(element)){$.powerTip.hide(element,!isMouseEvent(event))}else{$.powerTip.show(element,event)}return element}};$.powerTip.showTip=$.powerTip.show;$.powerTip.closeTip=$.powerTip.hide;function CSSCoordinates(){var me=this;me.top="auto";me.left="auto";me.right="auto";me.bottom="auto";me.set=function(property,value){if($.isNumeric(value)){me[property]=Math.round(value)}}}function DisplayController(element,options,tipController){var hoverTimer=null,myCloseDelay=null;function openTooltip(immediate,forceOpen){cancelTimer();if(!element.data(DATA_HASACTIVEHOVER)){if(!immediate){session.tipOpenImminent=true;hoverTimer=setTimeout(function intentDelay(){hoverTimer=null;checkForIntent()},options.intentPollInterval)}else{if(forceOpen){element.data(DATA_FORCEDOPEN,true)}closeAnyDelayed();tipController.showTip(element)}}else{cancelClose()}}function closeTooltip(disableDelay){if(myCloseDelay){myCloseDelay=session.closeDelayTimeout=clearTimeout(myCloseDelay);session.delayInProgress=false}cancelTimer();session.tipOpenImminent=false;if(element.data(DATA_HASACTIVEHOVER)){element.data(DATA_FORCEDOPEN,false);if(!disableDelay){session.delayInProgress=true;session.closeDelayTimeout=setTimeout(function closeDelay(){session.closeDelayTimeout=null;tipController.hideTip(element);session.delayInProgress=false;myCloseDelay=null},options.closeDelay);myCloseDelay=session.closeDelayTimeout}else{tipController.hideTip(element)}}}function checkForIntent(){var xDifference=Math.abs(session.previousX-session.currentX),yDifference=Math.abs(session.previousY-session.currentY),totalDifference=xDifference+yDifference;if(totalDifference",{id:options.popupId});if($body.length===0){$body=$("body")}$body.append(tipElement);session.tooltips=session.tooltips?session.tooltips.add(tipElement):tipElement}if(options.followMouse){if(!tipElement.data(DATA_HASMOUSEMOVE)){$document.on("mousemove"+EVENT_NAMESPACE,positionTipOnCursor);$window.on("scroll"+EVENT_NAMESPACE,positionTipOnCursor);tipElement.data(DATA_HASMOUSEMOVE,true)}}function beginShowTip(element){element.data(DATA_HASACTIVEHOVER,true);tipElement.queue(function queueTipInit(next){showTip(element);next()})}function showTip(element){var tipContent;if(!element.data(DATA_HASACTIVEHOVER)){return}if(session.isTipOpen){if(!session.isClosing){hideTip(session.activeHover)}tipElement.delay(100).queue(function queueTipAgain(next){showTip(element);next()});return}element.trigger("powerTipPreRender");tipContent=getTooltipContent(element);if(tipContent){tipElement.empty().append(tipContent)}else{return}element.trigger("powerTipRender");session.activeHover=element;session.isTipOpen=true;tipElement.data(DATA_MOUSEONTOTIP,options.mouseOnToPopup);tipElement.addClass(options.popupClass);if(!options.followMouse||element.data(DATA_FORCEDOPEN)){positionTipOnElement(element);session.isFixedTipOpen=true}else{positionTipOnCursor()}if(!element.data(DATA_FORCEDOPEN)&&!options.followMouse){$document.on("click"+EVENT_NAMESPACE,function documentClick(event){var target=event.target;if(target!==element[0]){if(options.mouseOnToPopup){if(target!==tipElement[0]&&!$.contains(tipElement[0],target)){$.powerTip.hide()}}else{$.powerTip.hide()}}})}if(options.mouseOnToPopup&&!options.manual){tipElement.on("mouseenter"+EVENT_NAMESPACE,function tipMouseEnter(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).cancel()}});tipElement.on("mouseleave"+EVENT_NAMESPACE,function tipMouseLeave(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).hide()}})}tipElement.fadeIn(options.fadeInTime,function fadeInCallback(){if(!session.desyncTimeout){session.desyncTimeout=setInterval(closeDesyncedTip,500)}element.trigger("powerTipOpen")})}function hideTip(element){session.isClosing=true;session.isTipOpen=false;session.desyncTimeout=clearInterval(session.desyncTimeout);element.data(DATA_HASACTIVEHOVER,false);element.data(DATA_FORCEDOPEN,false);$document.off("click"+EVENT_NAMESPACE);tipElement.off(EVENT_NAMESPACE);tipElement.fadeOut(options.fadeOutTime,function fadeOutCallback(){var coords=new CSSCoordinates;session.activeHover=null;session.isClosing=false;session.isFixedTipOpen=false;tipElement.removeClass();coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);tipElement.css(coords);element.trigger("powerTipClose")})}function positionTipOnCursor(){var tipWidth,tipHeight,coords,collisions,collisionCount;if(!session.isFixedTipOpen&&(session.isTipOpen||session.tipOpenImminent&&tipElement.data(DATA_HASMOUSEMOVE))){tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=new CSSCoordinates;coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);collisions=getViewportCollisions(coords,tipWidth,tipHeight);if(collisions!==Collision.none){collisionCount=countFlags(collisions);if(collisionCount===1){if(collisions===Collision.right){coords.set("left",session.scrollLeft+session.windowWidth-tipWidth)}else if(collisions===Collision.bottom){coords.set("top",session.scrollTop+session.windowHeight-tipHeight)}}else{coords.set("left",session.currentX-tipWidth-options.offset);coords.set("top",session.currentY-tipHeight-options.offset)}}tipElement.css(coords)}}function positionTipOnElement(element){var priorityList,finalPlacement;if(options.smartPlacement||options.followMouse&&element.data(DATA_FORCEDOPEN)){priorityList=$.fn.powerTip.smartPlacementLists[options.placement];$.each(priorityList,function(idx,pos){var collisions=getViewportCollisions(placeTooltip(element,pos),tipElement.outerWidth(),tipElement.outerHeight());finalPlacement=pos;return collisions!==Collision.none})}else{placeTooltip(element,options.placement);finalPlacement=options.placement}tipElement.removeClass("w nw sw e ne se n s w se-alt sw-alt ne-alt nw-alt");tipElement.addClass(finalPlacement)}function placeTooltip(element,placement){var iterationCount=0,tipWidth,tipHeight,coords=new CSSCoordinates;coords.set("top",0);coords.set("left",0);tipElement.css(coords);do{tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=placementCalculator.compute(element,placement,tipWidth,tipHeight,options.offset);tipElement.css(coords)}while(++iterationCount<=5&&(tipWidth!==tipElement.outerWidth()||tipHeight!==tipElement.outerHeight()));return coords}function closeDesyncedTip(){var isDesynced=false,hasDesyncableCloseEvent=$.grep(["mouseleave","mouseout","blur","focusout"],function(eventType){return $.inArray(eventType,options.closeEvents)!==-1}).length>0;if(session.isTipOpen&&!session.isClosing&&!session.delayInProgress&&hasDesyncableCloseEvent){if(session.activeHover.data(DATA_HASACTIVEHOVER)===false||session.activeHover.is(":disabled")){isDesynced=true}else if(!isMouseOver(session.activeHover)&&!session.activeHover.is(":focus")&&!session.activeHover.data(DATA_FORCEDOPEN)){if(tipElement.data(DATA_MOUSEONTOTIP)){if(!isMouseOver(tipElement)){isDesynced=true}}else{isDesynced=true}}if(isDesynced){hideTip(session.activeHover)}}}this.showTip=beginShowTip;this.hideTip=hideTip;this.resetPosition=positionTipOnElement}function isSvgElement(element){return Boolean(window.SVGElement&&element[0]instanceof SVGElement)}function isMouseEvent(event){return Boolean(event&&$.inArray(event.type,MOUSE_EVENTS)>-1&&typeof event.pageX==="number")}function initTracking(){if(!session.mouseTrackingActive){session.mouseTrackingActive=true;getViewportDimensions();$(getViewportDimensions);$document.on("mousemove"+EVENT_NAMESPACE,trackMouse);$window.on("resize"+EVENT_NAMESPACE,trackResize);$window.on("scroll"+EVENT_NAMESPACE,trackScroll)}}function getViewportDimensions(){session.scrollLeft=$window.scrollLeft();session.scrollTop=$window.scrollTop();session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackResize(){session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackScroll(){var x=$window.scrollLeft(),y=$window.scrollTop();if(x!==session.scrollLeft){session.currentX+=x-session.scrollLeft;session.scrollLeft=x}if(y!==session.scrollTop){session.currentY+=y-session.scrollTop;session.scrollTop=y}}function trackMouse(event){session.currentX=event.pageX;session.currentY=event.pageY}function isMouseOver(element){var elementPosition=element.offset(),elementBox=element[0].getBoundingClientRect(),elementWidth=elementBox.right-elementBox.left,elementHeight=elementBox.bottom-elementBox.top;return session.currentX>=elementPosition.left&&session.currentX<=elementPosition.left+elementWidth&&session.currentY>=elementPosition.top&&session.currentY<=elementPosition.top+elementHeight}function getTooltipContent(element){var tipText=element.data(DATA_POWERTIP),tipObject=element.data(DATA_POWERTIPJQ),tipTarget=element.data(DATA_POWERTIPTARGET),targetElement,content;if(tipText){if($.isFunction(tipText)){tipText=tipText.call(element[0])}content=tipText}else if(tipObject){if($.isFunction(tipObject)){tipObject=tipObject.call(element[0])}if(tipObject.length>0){content=tipObject.clone(true,true)}}else if(tipTarget){targetElement=$("#"+tipTarget);if(targetElement.length>0){content=targetElement.html()}}return content}function getViewportCollisions(coords,elementWidth,elementHeight){var viewportTop=session.scrollTop,viewportLeft=session.scrollLeft,viewportBottom=viewportTop+session.windowHeight,viewportRight=viewportLeft+session.windowWidth,collisions=Collision.none;if(coords.topviewportBottom||Math.abs(coords.bottom-session.windowHeight)>viewportBottom){collisions|=Collision.bottom}if(coords.leftviewportRight){collisions|=Collision.left}if(coords.left+elementWidth>viewportRight||coords.right1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);/*! SmartMenus jQuery Plugin - v1.1.0 - September 17, 2017 + * http://www.smartmenus.org/ + * Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function($){function initMouseDetection(t){var e=".smartmenus_mouse";if(mouseDetectionEnabled||t)mouseDetectionEnabled&&t&&($(document).off(e),mouseDetectionEnabled=!1);else{var i=!0,s=null,o={mousemove:function(t){var e={x:t.pageX,y:t.pageY,timeStamp:(new Date).getTime()};if(s){var o=Math.abs(s.x-e.x),a=Math.abs(s.y-e.y);if((o>0||a>0)&&2>=o&&2>=a&&300>=e.timeStamp-s.timeStamp&&(mouse=!0,i)){var n=$(t.target).closest("a");n.is("a")&&$.each(menuTrees,function(){return $.contains(this.$root[0],n[0])?(this.itemEnter({currentTarget:n[0]}),!1):void 0}),i=!1}}s=e}};o[touchEvents?"touchstart":"pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut"]=function(t){isTouchEvent(t.originalEvent)&&(mouse=!1)},$(document).on(getEventsNS(o,e)),mouseDetectionEnabled=!0}}function isTouchEvent(t){return!/^(4|mouse)$/.test(t.pointerType)}function getEventsNS(t,e){e||(e="");var i={};for(var s in t)i[s.split(" ").join(e+" ")+e]=t[s];return i}var menuTrees=[],mouse=!1,touchEvents="ontouchstart"in window,mouseDetectionEnabled=!1,requestAnimationFrame=window.requestAnimationFrame||function(t){return setTimeout(t,1e3/60)},cancelAnimationFrame=window.cancelAnimationFrame||function(t){clearTimeout(t)},canAnimate=!!$.fn.animate;return $.SmartMenus=function(t,e){this.$root=$(t),this.opts=e,this.rootId="",this.accessIdPrefix="",this.$subArrow=null,this.activatedItems=[],this.visibleSubMenus=[],this.showTimeout=0,this.hideTimeout=0,this.scrollTimeout=0,this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.idInc=0,this.$firstLink=null,this.$firstSub=null,this.disabled=!1,this.$disableOverlay=null,this.$touchScrollingSub=null,this.cssTransforms3d="perspective"in t.style||"webkitPerspective"in t.style,this.wasCollapsible=!1,this.init()},$.extend($.SmartMenus,{hideAll:function(){$.each(menuTrees,function(){this.menuHideAll()})},destroy:function(){for(;menuTrees.length;)menuTrees[0].destroy();initMouseDetection(!0)},prototype:{init:function(t){var e=this;if(!t){menuTrees.push(this),this.rootId=((new Date).getTime()+Math.random()+"").replace(/\D/g,""),this.accessIdPrefix="sm-"+this.rootId+"-",this.$root.hasClass("sm-rtl")&&(this.opts.rightToLeftSubMenus=!0);var i=".smartmenus";this.$root.data("smartmenus",this).attr("data-smartmenus-id",this.rootId).dataSM("level",1).on(getEventsNS({"mouseover focusin":$.proxy(this.rootOver,this),"mouseout focusout":$.proxy(this.rootOut,this),keydown:$.proxy(this.rootKeyDown,this)},i)).on(getEventsNS({mouseenter:$.proxy(this.itemEnter,this),mouseleave:$.proxy(this.itemLeave,this),mousedown:$.proxy(this.itemDown,this),focus:$.proxy(this.itemFocus,this),blur:$.proxy(this.itemBlur,this),click:$.proxy(this.itemClick,this)},i),"a"),i+=this.rootId,this.opts.hideOnClick&&$(document).on(getEventsNS({touchstart:$.proxy(this.docTouchStart,this),touchmove:$.proxy(this.docTouchMove,this),touchend:$.proxy(this.docTouchEnd,this),click:$.proxy(this.docClick,this)},i)),$(window).on(getEventsNS({"resize orientationchange":$.proxy(this.winResize,this)},i)),this.opts.subIndicators&&(this.$subArrow=$("").addClass("sub-arrow"),this.opts.subIndicatorsText&&this.$subArrow.html(this.opts.subIndicatorsText)),initMouseDetection()}if(this.$firstSub=this.$root.find("ul").each(function(){e.menuInit($(this))}).eq(0),this.$firstLink=this.$root.find("a").eq(0),this.opts.markCurrentItem){var s=/(index|default)\.[^#\?\/]*/i,o=/#.*/,a=window.location.href.replace(s,""),n=a.replace(o,"");this.$root.find("a").each(function(){var t=this.href.replace(s,""),i=$(this);(t==a||t==n)&&(i.addClass("current"),e.opts.markCurrentTree&&i.parentsUntil("[data-smartmenus-id]","ul").each(function(){$(this).dataSM("parent-a").addClass("current")}))})}this.wasCollapsible=this.isCollapsible()},destroy:function(t){if(!t){var e=".smartmenus";this.$root.removeData("smartmenus").removeAttr("data-smartmenus-id").removeDataSM("level").off(e),e+=this.rootId,$(document).off(e),$(window).off(e),this.opts.subIndicators&&(this.$subArrow=null)}this.menuHideAll();var i=this;this.$root.find("ul").each(function(){var t=$(this);t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.dataSM("shown-before")&&((i.opts.subMenusMinWidth||i.opts.subMenusMaxWidth)&&t.css({width:"",minWidth:"",maxWidth:""}).removeClass("sm-nowrap"),t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.css({zIndex:"",top:"",left:"",marginLeft:"",marginTop:"",display:""})),0==(t.attr("id")||"").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeDataSM("in-mega").removeDataSM("shown-before").removeDataSM("scroll-arrows").removeDataSM("parent-a").removeDataSM("level").removeDataSM("beforefirstshowfired").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeAttr("aria-expanded"),this.$root.find("a.has-submenu").each(function(){var t=$(this);0==t.attr("id").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeClass("has-submenu").removeDataSM("sub").removeAttr("aria-haspopup").removeAttr("aria-controls").removeAttr("aria-expanded").closest("li").removeDataSM("sub"),this.opts.subIndicators&&this.$root.find("span.sub-arrow").remove(),this.opts.markCurrentItem&&this.$root.find("a.current").removeClass("current"),t||(this.$root=null,this.$firstLink=null,this.$firstSub=null,this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),menuTrees.splice($.inArray(this,menuTrees),1))},disable:function(t){if(!this.disabled){if(this.menuHideAll(),!t&&!this.opts.isPopup&&this.$root.is(":visible")){var e=this.$root.offset();this.$disableOverlay=$('
').css({position:"absolute",top:e.top,left:e.left,width:this.$root.outerWidth(),height:this.$root.outerHeight(),zIndex:this.getStartZIndex(!0),opacity:0}).appendTo(document.body)}this.disabled=!0}},docClick:function(t){return this.$touchScrollingSub?(this.$touchScrollingSub=null,void 0):((this.visibleSubMenus.length&&!$.contains(this.$root[0],t.target)||$(t.target).closest("a").length)&&this.menuHideAll(),void 0)},docTouchEnd:function(){if(this.lastTouch){if(!(!this.visibleSubMenus.length||void 0!==this.lastTouch.x2&&this.lastTouch.x1!=this.lastTouch.x2||void 0!==this.lastTouch.y2&&this.lastTouch.y1!=this.lastTouch.y2||this.lastTouch.target&&$.contains(this.$root[0],this.lastTouch.target))){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var t=this;this.hideTimeout=setTimeout(function(){t.menuHideAll()},350)}this.lastTouch=null}},docTouchMove:function(t){if(this.lastTouch){var e=t.originalEvent.touches[0];this.lastTouch.x2=e.pageX,this.lastTouch.y2=e.pageY}},docTouchStart:function(t){var e=t.originalEvent.touches[0];this.lastTouch={x1:e.pageX,y1:e.pageY,target:e.target}},enable:function(){this.disabled&&(this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),this.disabled=!1)},getClosestMenu:function(t){for(var e=$(t).closest("ul");e.dataSM("in-mega");)e=e.parent().closest("ul");return e[0]||null},getHeight:function(t){return this.getOffset(t,!0)},getOffset:function(t,e){var i;"none"==t.css("display")&&(i={position:t[0].style.position,visibility:t[0].style.visibility},t.css({position:"absolute",visibility:"hidden"}).show());var s=t[0].getBoundingClientRect&&t[0].getBoundingClientRect(),o=s&&(e?s.height||s.bottom-s.top:s.width||s.right-s.left);return o||0===o||(o=e?t[0].offsetHeight:t[0].offsetWidth),i&&t.hide().css(i),o},getStartZIndex:function(t){var e=parseInt(this[t?"$root":"$firstSub"].css("z-index"));return!t&&isNaN(e)&&(e=parseInt(this.$root.css("z-index"))),isNaN(e)?1:e},getTouchPoint:function(t){return t.touches&&t.touches[0]||t.changedTouches&&t.changedTouches[0]||t},getViewport:function(t){var e=t?"Height":"Width",i=document.documentElement["client"+e],s=window["inner"+e];return s&&(i=Math.min(i,s)),i},getViewportHeight:function(){return this.getViewport(!0)},getViewportWidth:function(){return this.getViewport()},getWidth:function(t){return this.getOffset(t)},handleEvents:function(){return!this.disabled&&this.isCSSOn()},handleItemEvents:function(t){return this.handleEvents()&&!this.isLinkInMegaMenu(t)},isCollapsible:function(){return"static"==this.$firstSub.css("position")},isCSSOn:function(){return"inline"!=this.$firstLink.css("display")},isFixed:function(){var t="fixed"==this.$root.css("position");return t||this.$root.parentsUntil("body").each(function(){return"fixed"==$(this).css("position")?(t=!0,!1):void 0}),t},isLinkInMegaMenu:function(t){return $(this.getClosestMenu(t[0])).hasClass("mega-menu")},isTouchMode:function(){return!mouse||this.opts.noMouseOver||this.isCollapsible()},itemActivate:function(t,e){var i=t.closest("ul"),s=i.dataSM("level");if(s>1&&(!this.activatedItems[s-2]||this.activatedItems[s-2][0]!=i.dataSM("parent-a")[0])){var o=this;$(i.parentsUntil("[data-smartmenus-id]","ul").get().reverse()).add(i).each(function(){o.itemActivate($(this).dataSM("parent-a"))})}if((!this.isCollapsible()||e)&&this.menuHideSubMenus(this.activatedItems[s-1]&&this.activatedItems[s-1][0]==t[0]?s:s-1),this.activatedItems[s-1]=t,this.$root.triggerHandler("activate.smapi",t[0])!==!1){var a=t.dataSM("sub");a&&(this.isTouchMode()||!this.opts.showOnClick||this.clickActivated)&&this.menuShow(a)}},itemBlur:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&this.$root.triggerHandler("blur.smapi",e[0])},itemClick:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(this.$touchScrollingSub&&this.$touchScrollingSub[0]==e.closest("ul")[0])return this.$touchScrollingSub=null,t.stopPropagation(),!1;if(this.$root.triggerHandler("click.smapi",e[0])===!1)return!1;var i=$(t.target).is(".sub-arrow"),s=e.dataSM("sub"),o=s?2==s.dataSM("level"):!1,a=this.isCollapsible(),n=/toggle$/.test(this.opts.collapsibleBehavior),r=/link$/.test(this.opts.collapsibleBehavior),h=/^accordion/.test(this.opts.collapsibleBehavior);if(s&&!s.is(":visible")){if((!r||!a||i)&&(this.opts.showOnClick&&o&&(this.clickActivated=!0),this.itemActivate(e,h),s.is(":visible")))return this.focusActivated=!0,!1}else if(a&&(n||i))return this.itemActivate(e,h),this.menuHide(s),n&&(this.focusActivated=!1),!1;return this.opts.showOnClick&&o||e.hasClass("disabled")||this.$root.triggerHandler("select.smapi",e[0])===!1?!1:void 0}},itemDown:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&e.dataSM("mousedown",!0)},itemEnter:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(!this.isTouchMode()){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);var i=this;this.showTimeout=setTimeout(function(){i.itemActivate(e)},this.opts.showOnClick&&1==e.closest("ul").dataSM("level")?1:this.opts.showTimeout)}this.$root.triggerHandler("mouseenter.smapi",e[0])}},itemFocus:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(!this.focusActivated||this.isTouchMode()&&e.dataSM("mousedown")||this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0]==e[0]||this.itemActivate(e,!0),this.$root.triggerHandler("focus.smapi",e[0]))},itemLeave:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(this.isTouchMode()||(e[0].blur(),this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0)),e.removeDataSM("mousedown"),this.$root.triggerHandler("mouseleave.smapi",e[0]))},menuHide:function(t){if(this.$root.triggerHandler("beforehide.smapi",t[0])!==!1&&(canAnimate&&t.stop(!0,!0),"none"!=t.css("display"))){var e=function(){t.css("z-index","")};this.isCollapsible()?canAnimate&&this.opts.collapsibleHideFunction?this.opts.collapsibleHideFunction.call(this,t,e):t.hide(this.opts.collapsibleHideDuration,e):canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,t,e):t.hide(this.opts.hideDuration,e),t.dataSM("scroll")&&(this.menuScrollStop(t),t.css({"touch-action":"","-ms-touch-action":"","-webkit-transform":"",transform:""}).off(".smartmenus_scroll").removeDataSM("scroll").dataSM("scroll-arrows").hide()),t.dataSM("parent-a").removeClass("highlighted").attr("aria-expanded","false"),t.attr({"aria-expanded":"false","aria-hidden":"true"});var i=t.dataSM("level");this.activatedItems.splice(i-1,1),this.visibleSubMenus.splice($.inArray(t,this.visibleSubMenus),1),this.$root.triggerHandler("hide.smapi",t[0])}},menuHideAll:function(){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);for(var t=this.opts.isPopup?1:0,e=this.visibleSubMenus.length-1;e>=t;e--)this.menuHide(this.visibleSubMenus[e]);this.opts.isPopup&&(canAnimate&&this.$root.stop(!0,!0),this.$root.is(":visible")&&(canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,this.$root):this.$root.hide(this.opts.hideDuration))),this.activatedItems=[],this.visibleSubMenus=[],this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.$root.triggerHandler("hideAll.smapi")},menuHideSubMenus:function(t){for(var e=this.activatedItems.length-1;e>=t;e--){var i=this.activatedItems[e].dataSM("sub");i&&this.menuHide(i)}},menuInit:function(t){if(!t.dataSM("in-mega")){t.hasClass("mega-menu")&&t.find("ul").dataSM("in-mega",!0);for(var e=2,i=t[0];(i=i.parentNode.parentNode)!=this.$root[0];)e++;var s=t.prevAll("a").eq(-1);s.length||(s=t.prevAll().find("a").eq(-1)),s.addClass("has-submenu").dataSM("sub",t),t.dataSM("parent-a",s).dataSM("level",e).parent().dataSM("sub",t);var o=s.attr("id")||this.accessIdPrefix+ ++this.idInc,a=t.attr("id")||this.accessIdPrefix+ ++this.idInc;s.attr({id:o,"aria-haspopup":"true","aria-controls":a,"aria-expanded":"false"}),t.attr({id:a,role:"group","aria-hidden":"true","aria-labelledby":o,"aria-expanded":"false"}),this.opts.subIndicators&&s[this.opts.subIndicatorsPos](this.$subArrow.clone())}},menuPosition:function(t){var e,i,s=t.dataSM("parent-a"),o=s.closest("li"),a=o.parent(),n=t.dataSM("level"),r=this.getWidth(t),h=this.getHeight(t),u=s.offset(),l=u.left,c=u.top,d=this.getWidth(s),m=this.getHeight(s),p=$(window),f=p.scrollLeft(),v=p.scrollTop(),b=this.getViewportWidth(),S=this.getViewportHeight(),g=a.parent().is("[data-sm-horizontal-sub]")||2==n&&!a.hasClass("sm-vertical"),M=this.opts.rightToLeftSubMenus&&!o.is("[data-sm-reverse]")||!this.opts.rightToLeftSubMenus&&o.is("[data-sm-reverse]"),w=2==n?this.opts.mainMenuSubOffsetX:this.opts.subMenusSubOffsetX,T=2==n?this.opts.mainMenuSubOffsetY:this.opts.subMenusSubOffsetY;if(g?(e=M?d-r-w:w,i=this.opts.bottomToTopSubMenus?-h-T:m+T):(e=M?w-r:d-w,i=this.opts.bottomToTopSubMenus?m-T-h:T),this.opts.keepInViewport){var y=l+e,I=c+i;if(M&&f>y?e=g?f-y+e:d-w:!M&&y+r>f+b&&(e=g?f+b-r-y+e:w-r),g||(S>h&&I+h>v+S?i+=v+S-h-I:(h>=S||v>I)&&(i+=v-I)),g&&(I+h>v+S+.49||v>I)||!g&&h>S+.49){var x=this;t.dataSM("scroll-arrows")||t.dataSM("scroll-arrows",$([$('')[0],$('')[0]]).on({mouseenter:function(){t.dataSM("scroll").up=$(this).hasClass("scroll-up"),x.menuScroll(t)},mouseleave:function(e){x.menuScrollStop(t),x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(t){t.preventDefault()}}).insertAfter(t));var A=".smartmenus_scroll";if(t.dataSM("scroll",{y:this.cssTransforms3d?0:i-m,step:1,itemH:m,subH:h,arrowDownH:this.getHeight(t.dataSM("scroll-arrows").eq(1))}).on(getEventsNS({mouseover:function(e){x.menuScrollOver(t,e)},mouseout:function(e){x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(e){x.menuScrollMousewheel(t,e)}},A)).dataSM("scroll-arrows").css({top:"auto",left:"0",marginLeft:e+(parseInt(t.css("border-left-width"))||0),width:r-(parseInt(t.css("border-left-width"))||0)-(parseInt(t.css("border-right-width"))||0),zIndex:t.css("z-index")}).eq(g&&this.opts.bottomToTopSubMenus?0:1).show(),this.isFixed()){var C={};C[touchEvents?"touchstart touchmove touchend":"pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp"]=function(e){x.menuScrollTouch(t,e)},t.css({"touch-action":"none","-ms-touch-action":"none"}).on(getEventsNS(C,A))}}}t.css({top:"auto",left:"0",marginLeft:e,marginTop:i-m})},menuScroll:function(t,e,i){var s,o=t.dataSM("scroll"),a=t.dataSM("scroll-arrows"),n=o.up?o.upEnd:o.downEnd;if(!e&&o.momentum){if(o.momentum*=.92,s=o.momentum,.5>s)return this.menuScrollStop(t),void 0}else s=i||(e||!this.opts.scrollAccelerate?this.opts.scrollStep:Math.floor(o.step));var r=t.dataSM("level");if(this.activatedItems[r-1]&&this.activatedItems[r-1].dataSM("sub")&&this.activatedItems[r-1].dataSM("sub").is(":visible")&&this.menuHideSubMenus(r-1),o.y=o.up&&o.y>=n||!o.up&&n>=o.y?o.y:Math.abs(n-o.y)>s?o.y+(o.up?s:-s):n,t.css(this.cssTransforms3d?{"-webkit-transform":"translate3d(0, "+o.y+"px, 0)",transform:"translate3d(0, "+o.y+"px, 0)"}:{marginTop:o.y}),mouse&&(o.up&&o.y>o.downEnd||!o.up&&o.y0;t.dataSM("scroll-arrows").eq(i?0:1).is(":visible")&&(t.dataSM("scroll").up=i,this.menuScroll(t,!0))}e.preventDefault()},menuScrollOut:function(t,e){mouse&&(/^scroll-(up|down)/.test((e.relatedTarget||"").className)||(t[0]==e.relatedTarget||$.contains(t[0],e.relatedTarget))&&this.getClosestMenu(e.relatedTarget)==t[0]||t.dataSM("scroll-arrows").css("visibility","hidden"))},menuScrollOver:function(t,e){if(mouse&&!/^scroll-(up|down)/.test(e.target.className)&&this.getClosestMenu(e.target)==t[0]){this.menuScrollRefreshData(t);var i=t.dataSM("scroll"),s=$(window).scrollTop()-t.dataSM("parent-a").offset().top-i.itemH;t.dataSM("scroll-arrows").eq(0).css("margin-top",s).end().eq(1).css("margin-top",s+this.getViewportHeight()-i.arrowDownH).end().css("visibility","visible")}},menuScrollRefreshData:function(t){var e=t.dataSM("scroll"),i=$(window).scrollTop()-t.dataSM("parent-a").offset().top-e.itemH;this.cssTransforms3d&&(i=-(parseFloat(t.css("margin-top"))-i)),$.extend(e,{upEnd:i,downEnd:i+this.getViewportHeight()-e.subH})},menuScrollStop:function(t){return this.scrollTimeout?(cancelAnimationFrame(this.scrollTimeout),this.scrollTimeout=0,t.dataSM("scroll").step=1,!0):void 0},menuScrollTouch:function(t,e){if(e=e.originalEvent,isTouchEvent(e)){var i=this.getTouchPoint(e);if(this.getClosestMenu(i.target)==t[0]){var s=t.dataSM("scroll");if(/(start|down)$/i.test(e.type))this.menuScrollStop(t)?(e.preventDefault(),this.$touchScrollingSub=t):this.$touchScrollingSub=null,this.menuScrollRefreshData(t),$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp});else if(/move$/i.test(e.type)){var o=void 0!==s.touchY?s.touchY:s.touchStartY;if(void 0!==o&&o!=i.pageY){this.$touchScrollingSub=t;var a=i.pageY>o;void 0!==s.up&&s.up!=a&&$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp}),$.extend(s,{up:a,touchY:i.pageY}),this.menuScroll(t,!0,Math.abs(i.pageY-o))}e.preventDefault()}else void 0!==s.touchY&&((s.momentum=15*Math.pow(Math.abs(i.pageY-s.touchStartY)/(e.timeStamp-s.touchStartTime),2))&&(this.menuScrollStop(t),this.menuScroll(t),e.preventDefault()),delete s.touchY)}}},menuShow:function(t){if((t.dataSM("beforefirstshowfired")||(t.dataSM("beforefirstshowfired",!0),this.$root.triggerHandler("beforefirstshow.smapi",t[0])!==!1))&&this.$root.triggerHandler("beforeshow.smapi",t[0])!==!1&&(t.dataSM("shown-before",!0),canAnimate&&t.stop(!0,!0),!t.is(":visible"))){var e=t.dataSM("parent-a"),i=this.isCollapsible();if((this.opts.keepHighlighted||i)&&e.addClass("highlighted"),i)t.removeClass("sm-nowrap").css({zIndex:"",width:"auto",minWidth:"",maxWidth:"",top:"",left:"",marginLeft:"",marginTop:""});else{if(t.css("z-index",this.zIndexInc=(this.zIndexInc||this.getStartZIndex())+1),(this.opts.subMenusMinWidth||this.opts.subMenusMaxWidth)&&(t.css({width:"auto",minWidth:"",maxWidth:""}).addClass("sm-nowrap"),this.opts.subMenusMinWidth&&t.css("min-width",this.opts.subMenusMinWidth),this.opts.subMenusMaxWidth)){var s=this.getWidth(t);t.css("max-width",this.opts.subMenusMaxWidth),s>this.getWidth(t)&&t.removeClass("sm-nowrap").css("width",this.opts.subMenusMaxWidth)}this.menuPosition(t)}var o=function(){t.css("overflow","")};i?canAnimate&&this.opts.collapsibleShowFunction?this.opts.collapsibleShowFunction.call(this,t,o):t.show(this.opts.collapsibleShowDuration,o):canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,t,o):t.show(this.opts.showDuration,o),e.attr("aria-expanded","true"),t.attr({"aria-expanded":"true","aria-hidden":"false"}),this.visibleSubMenus.push(t),this.$root.triggerHandler("show.smapi",t[0])}},popupHide:function(t){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},t?1:this.opts.hideTimeout)},popupShow:function(t,e){if(!this.opts.isPopup)return alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'),void 0;if(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),this.$root.dataSM("shown-before",!0),canAnimate&&this.$root.stop(!0,!0),!this.$root.is(":visible")){this.$root.css({left:t,top:e});var i=this,s=function(){i.$root.css("overflow","")};canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,this.$root,s):this.$root.show(this.opts.showDuration,s),this.visibleSubMenus[0]=this.$root}},refresh:function(){this.destroy(!0),this.init(!0)},rootKeyDown:function(t){if(this.handleEvents())switch(t.keyCode){case 27:var e=this.activatedItems[0];if(e){this.menuHideAll(),e[0].focus();var i=e.dataSM("sub");i&&this.menuHide(i)}break;case 32:var s=$(t.target);if(s.is("a")&&this.handleItemEvents(s)){var i=s.dataSM("sub");i&&!i.is(":visible")&&(this.itemClick({currentTarget:t.target}),t.preventDefault())}}},rootOut:function(t){if(this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),!this.opts.showOnClick||!this.opts.hideOnClick)){var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},this.opts.hideTimeout)}},rootOver:function(t){this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0)},winResize:function(t){if(this.handleEvents()){if(!("onorientationchange"in window)||"orientationchange"==t.type){var e=this.isCollapsible();this.wasCollapsible&&e||(this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0].blur(),this.menuHideAll()),this.wasCollapsible=e}}else if(this.$disableOverlay){var i=this.$root.offset();this.$disableOverlay.css({top:i.top,left:i.left,width:this.$root.outerWidth(),height:this.$root.outerHeight()})}}}}),$.fn.dataSM=function(t,e){return e?this.data(t+"_smartmenus",e):this.data(t+"_smartmenus")},$.fn.removeDataSM=function(t){return this.removeData(t+"_smartmenus")},$.fn.smartmenus=function(options){if("string"==typeof options){var args=arguments,method=options;return Array.prototype.shift.call(args),this.each(function(){var t=$(this).data("smartmenus");t&&t[method]&&t[method].apply(t,args)})}return this.each(function(){var dataOpts=$(this).data("sm-options")||null;if(dataOpts)try{dataOpts=eval("("+dataOpts+")")}catch(e){dataOpts=null,alert('ERROR\n\nSmartMenus jQuery init:\nInvalid "data-sm-options" attribute value syntax.')}new $.SmartMenus(this,$.extend({},$.fn.smartmenus.defaults,options,dataOpts))})},$.fn.smartmenus.defaults={isPopup:!1,mainMenuSubOffsetX:0,mainMenuSubOffsetY:0,subMenusSubOffsetX:0,subMenusSubOffsetY:0,subMenusMinWidth:"10em",subMenusMaxWidth:"20em",subIndicators:!0,subIndicatorsPos:"append",subIndicatorsText:"",scrollStep:30,scrollAccelerate:!0,showTimeout:250,hideTimeout:500,showDuration:0,showFunction:null,hideDuration:0,hideFunction:function(t,e){t.fadeOut(200,e)},collapsibleShowDuration:0,collapsibleShowFunction:function(t,e){t.slideDown(200,e)},collapsibleHideDuration:0,collapsibleHideFunction:function(t,e){t.slideUp(200,e)},showOnClick:!1,hideOnClick:!0,noMouseOver:!1,keepInViewport:!0,keepHighlighted:!0,markCurrentItem:!1,markCurrentTree:!0,rightToLeftSubMenus:!1,bottomToTopSubMenus:!1,collapsibleBehavior:"default"},$}); \ No newline at end of file diff --git a/latest/coreMQTT/modules.html b/latest/coreMQTT/modules.html new file mode 100644 index 00000000..e4267a73 --- /dev/null +++ b/latest/coreMQTT/modules.html @@ -0,0 +1,121 @@ + + + + + + + +coreMQTT: Data types and Constants + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Data types and Constants
+
+
+
This library defines the following data types and constants.
+ + + + + + +
 Enumerated TypesEnumerated types of the MQTT library
 Callback TypesCallback function pointer types of the MQTT library
 Parameter StructuresStructures passed as parameters to MQTT library functions
 Basic TypesPrimitive types of the MQTT library
 ConstantsConstants defined in the MQTT library
+
+
+
+ + + + diff --git a/latest/coreMQTT/modules.js b/latest/coreMQTT/modules.js new file mode 100644 index 00000000..7f3931b2 --- /dev/null +++ b/latest/coreMQTT/modules.js @@ -0,0 +1,8 @@ +var modules = +[ + [ "Enumerated Types", "group__mqtt__enum__types.html", "group__mqtt__enum__types" ], + [ "Callback Types", "group__mqtt__callback__types.html", "group__mqtt__callback__types" ], + [ "Parameter Structures", "group__mqtt__struct__types.html", "group__mqtt__struct__types" ], + [ "Basic Types", "group__mqtt__basic__types.html", "group__mqtt__basic__types" ], + [ "Constants", "group__mqtt__constants.html", "group__mqtt__constants" ] +]; \ No newline at end of file diff --git a/latest/coreMQTT/mqtt_connect_design.png b/latest/coreMQTT/mqtt_connect_design.png new file mode 100644 index 0000000000000000000000000000000000000000..81a1933c6c592396000cdad6566ced3d636f4cfc GIT binary patch literal 179318 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 z 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 + + + + + + +coreMQTT: MQTT_Connect + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_Connect
+
+
+
+
const MQTTConnectInfo_t * pConnectInfo,
+
const MQTTPublishInfo_t * pWillInfo,
+
uint32_t timeoutMs,
+
bool * pSessionPresent );
+
MQTTStatus_t MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
Establish an MQTT session.
Definition: core_mqtt.c:2679
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+

Establish an MQTT session.

+

This function will send MQTT CONNECT packet and receive a CONNACK packet. The send and receive from the network is done through the transport interface.

+

The maximum time this function waits for a CONNACK is decided in one of the following ways:

    +
  1. If timeoutMs is greater than 0: MQTTContext_t.getTime is used to ensure that the function does not wait more than timeoutMs for CONNACK.
  2. +
  3. If timeoutMs is 0: The network receive for CONNACK is retried up to the number of times configured by MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT.
  4. +
+
Note
If a dummy MQTTGetCurrentTimeFunc_t was passed to MQTT_Init, then a timeout value of 0 MUST be passed to the API, and the MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS timeout configurations MUST be set to 0.
+
Parameters
+ + + + + + +
[in]pContextInitialized MQTT context.
[in]pConnectInfoMQTT CONNECT packet information.
[in]pWillInfoLast Will and Testament. Pass NULL if Last Will and Testament is not used.
[in]timeoutMsMaximum time in milliseconds to wait for a CONNACK packet. A zero timeout makes use of the retries for receiving CONNACK as configured with MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT.
[out]pSessionPresentThis value will be set to true if a previous session was present; otherwise it will be set to false. It is only relevant if not establishing a clean session.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport send failed; MQTTRecvFailed if transport receive failed for CONNACK; MQTTNoDataAvailable if no data available to receive in transport until the timeoutMs for CONNACK; MQTTSuccess otherwise.
+
Note
This API may spend more time than provided in the timeoutMS parameters in certain conditions as listed below:
+
    +
  1. Timeouts are incorrectly configured - If the timeoutMS is less than the transport receive timeout and if a CONNACK packet is not received within the transport receive timeout, the API will spend the transport receive timeout (which is more time than the timeoutMs). It is the case of incorrect timeout configuration as the timeoutMs parameter passed to this API must be greater than the transport receive timeout. Please refer to the transport interface documentation for more details about timeout configurations.
  2. +
  3. Partial CONNACK packet is received right before the expiry of the timeout - It is possible that first two bytes of CONNACK packet (packet type and remaining length) are received right before the expiry of the timeoutMS. In that case, the API makes one more network receive call in an attempt to receive the remaining 2 bytes. In the worst case, it can happen that the remaining 2 bytes are never received and this API will end up spending timeoutMs + transport receive timeout.
  4. +
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
bool sessionPresent;
+
// This is assumed to have been initialized before calling this function.
+
MQTTContext_t * pContext;
+
+
// True for creating a new session with broker, false if we want to resume an old one.
+
connectInfo.cleanSession = true;
+
// Client ID must be unique to broker. This field is required.
+
connectInfo.pClientIdentifier = "someClientID";
+
connectInfo.clientIdentifierLength = strlen( connectInfo.pClientIdentifier );
+
+
// The following fields are optional.
+
// Value for keep alive.
+
connectInfo.keepAliveSeconds = 60;
+
// Optional username and password.
+
connectInfo.pUserName = "someUserName";
+
connectInfo.userNameLength = strlen( connectInfo.pUserName );
+
connectInfo.pPassword = "somePassword";
+
connectInfo.passwordLength = strlen( connectInfo.pPassword );
+
+
// The last will and testament is optional, it will be published by the broker
+
// should this client disconnect without sending a DISCONNECT packet.
+
willInfo.qos = MQTTQoS0;
+
willInfo.pTopicName = "/lwt/topic/name";
+
willInfo.topicNameLength = strlen( willInfo.pTopicName );
+
willInfo.pPayload = "LWT Message";
+
willInfo.payloadLength = strlen( "LWT Message" );
+
+
// Send the connect packet. Use 100 ms as the timeout to wait for the CONNACK packet.
+
status = MQTT_Connect( pContext, &connectInfo, &willInfo, 100, &sessionPresent );
+
+
if( status == MQTTSuccess )
+
{
+
// Since we requested a clean session, this must be false
+
assert( sessionPresent == false );
+
+
// Do something with the connection.
+
}
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
@ MQTTQoS0
Definition: core_mqtt_serializer.h:110
+
const char * pClientIdentifier
MQTT client identifier. Must be unique per client.
Definition: core_mqtt_serializer.h:147
+
const char * pUserName
MQTT user name. Set to NULL if not used.
Definition: core_mqtt_serializer.h:157
+
bool cleanSession
Whether to establish a new, clean session or resume a previous session.
Definition: core_mqtt_serializer.h:137
+
uint16_t userNameLength
Length of MQTT user name. Set to 0 if not used.
Definition: core_mqtt_serializer.h:162
+
uint16_t keepAliveSeconds
MQTT keep alive period.
Definition: core_mqtt_serializer.h:142
+
uint16_t clientIdentifierLength
Length of the client identifier.
Definition: core_mqtt_serializer.h:152
+
uint16_t passwordLength
Length of MQTT password. Set to 0 if not used.
Definition: core_mqtt_serializer.h:172
+
const char * pPassword
MQTT password. Set to NULL if not used.
Definition: core_mqtt_serializer.h:167
+
MQTTQoS_t qos
Quality of Service for message.
Definition: core_mqtt_serializer.h:206
+
uint16_t topicNameLength
Length of topic name.
Definition: core_mqtt_serializer.h:226
+
size_t payloadLength
Message payload length.
Definition: core_mqtt_serializer.h:236
+
const char * pTopicName
Topic name on which the message is published.
Definition: core_mqtt_serializer.h:221
+
const void * pPayload
Message payload.
Definition: core_mqtt_serializer.h:231
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_deserializeack_function.html b/latest/coreMQTT/mqtt_deserializeack_function.html new file mode 100644 index 00000000..3ab4e6b4 --- /dev/null +++ b/latest/coreMQTT/mqtt_deserializeack_function.html @@ -0,0 +1,154 @@ + + + + + + + +coreMQTT: MQTT_DeserializeAck + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_DeserializeAck
+
+
+
+
uint16_t * pPacketId,
+
bool * pSessionPresent );
+
MQTTStatus_t MQTT_DeserializeAck(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, bool *pSessionPresent)
Deserialize an MQTT CONNACK, SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, PUBCOMP, or PINGRESP.
Definition: core_mqtt_serializer.c:2484
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+

Deserialize an MQTT CONNACK, SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, PUBCOMP, or PINGRESP.

+
Parameters
+ + + + +
[in]pIncomingPacketMQTTPacketInfo_t containing the buffer.
[out]pPacketIdThe packet ID of obtained from the buffer. Not used in CONNACK or PINGRESP.
[out]pSessionPresentBoolean flag from a CONNACK indicating present session.
+
+
+
Returns
MQTTBadParameter, MQTTBadResponse, MQTTServerRefused, or MQTTSuccess.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPacketInfo_t incomingPacket;
+
// Used for SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, and PUBCOMP.
+
uint16_t packetId;
+
// Used for CONNACK.
+
bool sessionPresent;
+
+
// Receive an incoming packet and populate all fields. The details are out of scope
+
// for this example.
+
receiveIncomingPacket( &incomingPacket );
+
+
// Deserialize ack information if the incoming packet is not a publish.
+
if( ( incomingPacket.type & 0xF0 ) != MQTT_PACKET_TYPE_PUBLISH )
+
{
+
status = MQTT_DeserializeAck( &incomingPacket, &packetId, &sessionPresent );
+
if( status == MQTTSuccess )
+
{
+
// The packet ID or session present flag information is available. For
+
// ping response packets, the only information is the status code.
+
}
+
}
+
#define MQTT_PACKET_TYPE_PUBLISH
PUBLISH (bidirectional).
Definition: core_mqtt_serializer.h:55
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
uint8_t type
Type of incoming MQTT packet.
Definition: core_mqtt_serializer.h:248
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_deserializepublish_function.html b/latest/coreMQTT/mqtt_deserializepublish_function.html new file mode 100644 index 00000000..99a5fcc2 --- /dev/null +++ b/latest/coreMQTT/mqtt_deserializepublish_function.html @@ -0,0 +1,180 @@ + + + + + + + +coreMQTT: MQTT_DeserializePublish + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_DeserializePublish
+
+
+
+
uint16_t * pPacketId,
+
MQTTPublishInfo_t * pPublishInfo );
+
MQTTStatus_t MQTT_DeserializePublish(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo)
Deserialize an MQTT PUBLISH packet.
Definition: core_mqtt_serializer.c:2447
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+

Deserialize an MQTT PUBLISH packet.

+
Parameters
+ + + + +
[in]pIncomingPacketMQTTPacketInfo_t containing the buffer.
[out]pPacketIdThe packet ID obtained from the buffer.
[out]pPublishInfoStruct containing information about the publish.
+
+
+
Returns
MQTTBadParameter, MQTTBadResponse, or MQTTSuccess.
+

Example

// TransportRecv_t function for reading from the network.
+
int32_t socket_recv(
+
NetworkContext_t * pNetworkContext,
+
void * pBuffer,
+
size_t bytesToRecv
+
);
+
// Some context to be used with the above transport receive function.
+
NetworkContext_t networkContext;
+
+
// Other variables used in this example.
+
MQTTStatus_t status;
+
MQTTPacketInfo_t incomingPacket;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
uint16_t packetId;
+
+
int32_t bytesRecvd;
+
// A buffer to hold remaining data of the incoming packet.
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
// Populate all fields of the incoming packet.
+ +
socket_recv,
+
&networkContext,
+
&incomingPacket
+
);
+
assert( status == MQTTSuccess );
+
assert( incomingPacket.remainingLength <= BUFFER_SIZE );
+
bytesRecvd = socket_recv(
+
&networkContext,
+
( void * ) buffer,
+
incomingPacket.remainingLength
+
);
+
incomingPacket.pRemainingData = buffer;
+
+
// Deserialize the publish information if the incoming packet is a publish.
+
if( ( incomingPacket.type & 0xF0 ) == MQTT_PACKET_TYPE_PUBLISH )
+
{
+
status = MQTT_DeserializePublish( &incomingPacket, &packetId, &publishInfo );
+
if( status == MQTTSuccess )
+
{
+
// The deserialized publish information can now be used from `publishInfo`.
+
}
+
}
+
MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength(TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket)
Extract the MQTT packet type and length from incoming packet.
Definition: core_mqtt_serializer.c:2561
+
#define MQTT_PACKET_TYPE_PUBLISH
PUBLISH (bidirectional).
Definition: core_mqtt_serializer.h:55
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
+
size_t remainingLength
Length of remaining serialized data.
Definition: core_mqtt_serializer.h:258
+
uint8_t type
Type of incoming MQTT packet.
Definition: core_mqtt_serializer.h:248
+
uint8_t * pRemainingData
Remaining serialized data in the MQTT packet.
Definition: core_mqtt_serializer.h:253
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_design.html b/latest/coreMQTT/mqtt_design.html new file mode 100644 index 00000000..bd9b16ff --- /dev/null +++ b/latest/coreMQTT/mqtt_design.html @@ -0,0 +1,196 @@ + + + + + + + +coreMQTT: Design + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Design
+
+
+

Architecture of the MQTT library.

+

This MQTT client library provides an implementation of the MQTT 3.1.1 specification. It is optimized for resource constrained devices and does not allocate any memory.

+

+Interfaces and Callbacks

+

The MQTT library relies on interfaces to dissociate itself from platform specific functionality, such as the transport layer or maintaining time. Interfaces used by MQTT are simply function pointers with expectations of behavior.

+

The MQTT library expects the application to provide implementations for the following interfaces:

+ + + + + + + + + + + +
Function Pointer Use
TransportRecv_t Receiving data from an established network connection.
TransportSend_t Sending data over an established network connection.
MQTTGetCurrentTimeFunc_t Obtaining timestamps for complying with user-specified timeouts and the MQTT keep-alive mechanism.
MQTTEventCallback_t Returning packets received from the network to the user application after deserialization.
+

+Serializers and Deserializers

+

The managed MQTT API in core_mqtt.h uses a set of serialization and deserialization functions declared in core_mqtt_serializer.h. If a user does not want to use the functionality provided by the managed API, these low-level functions can be used directly:

+ +

+Sessions and State

+

The MQTT 3.1.1 protocol allows for a client and server to maintain persistent sessions, which can be resumed after a reconnect. The elements of a session stored by this client library consist of the states of incomplete publishes with Quality of Service levels of 1 (at least once), or 2 (exactly once). These states are stored in the pointers pointed to by MQTTContext_t::outgoingPublishRecords and MQTTContext_t::incomingPublishRecords; This library does not store any subscription information, nor any information for QoS 0 publishes.

+

When resuming a persistent session, the client library will resend PUBRELs for all PUBRECs that had been received for incomplete outgoing QoS 2 publishes. If the broker does not resume the session, then all state information in the client will be reset.

+
Note
The library stores only the state of incomplete publishes and not the publish payloads. It is the responsibility of the user application to save publish payloads until the publish is complete. If a persistent session is resumed, then MQTT_PublishToResend should be called to obtain the packet identifiers of incomplete publishes, followed by a call to MQTT_Publish to resend the unacknowledged publish.
+

+Packet Reception

+

MQTT Packets are received from the network with calls to MQTT_ProcessLoop or MQTT_ReceiveLoop. These functions are mostly identical, with the exception of keep-alive; the former sends ping requests and processes ping responses to ensure the MQTT session does not remain idle for more than the keep-alive interval, while the latter does not. Since calls to MQTT_Publish, MQTT_Subscribe, and MQTT_Unsubscribe only send packets and do not wait for acknowledgments, a call to MQTT_ProcessLoop or MQTT_ReceiveLoop must follow in order to receive any expected acknowledgment. The exception is MQTT_Connect; since a MQTT session cannot be considered established until the server acknowledges a CONNECT packet with a CONNACK, the function waits until the CONNACK is received.

+

+Runtime Timeouts passed to MQTT library

+

MQTT_Connect, MQTT_ProcessLoop, and MQTT_ReceiveLoop all accept a timeout parameter for packet reception.
+ For the MQTT_Connect, if this value is set to 0, then instead of a time-based loop, it will attempt to call the transport receive function up to a maximum number of retries, which is defined by MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT.

+

For MQTT_ProcessLoop and MQTT_ReceiveLoop, the timeout value represents the minimum duration that will be spent in the function, provided there are no network errors. Should the timeout be set to 0, then the loop will run for a single iteration. A single iteration of a loop consists of an attempt to receive a single byte from the network, and if the single byte receive was successful, then attempt(s) to receive the rest of the packet (with retry attempts governed by MQTT_RECV_POLLING_TIMEOUT_MS), followed by sending acknowledgement response, if needed (with retry attempts governed by MQTT_SEND_TIMEOUT_MS), and then, finally deserialization of the packet received and a call to the application callback. If the first read did not succeed, then instead the library checks if a ping request needs to be sent (only for the process loop).

+

See the below diagrams for a representation of the above flows:

+ + + + +
MQTT Connect Diagram MQTT ProcessLoop Diagram MQTT ReceiveLoop Diagram
MQTT Connect MQTT Process Loop MQTT Receive Loop
+

+Keep-Alive

+

The MQTT standard specifies a keep-alive mechanism to detect half-open or otherwise unusable network connections. An MQTT client will send periodic ping requests (PINGREQ) to the server if the connection is idle. The MQTT server must respond to ping requests with a ping response (PINGRESP).

+

In this library, MQTT_ProcessLoop handles sending of PINGREQs and processing corresponding PINGRESPs to comply with the keep-alive interval set in MQTTContext_t::keepAliveIntervalSec.

+

The standard does not specify the time duration within which the server has to respond to a ping request, noting only a "reasonable amount of time". If the response to a ping request is not received within MQTT_PINGRESP_TIMEOUT_MS, this library assumes that the connection is dead.

+

If MQTT_ReceiveLoop is used instead of MQTT_ProcessLoop, then no ping requests are sent. The application must ensure the connection does not remain idle for more than the keep-alive interval by calling MQTT_Ping to send ping requests. The timestamp in MQTTContext_t::lastPacketTxTime indicates when a packet was last sent by the library.

+

Sending any ping request sets the MQTTContext_t::waitingForPingResp flag. This flag is cleared by MQTT_ProcessLoop when a ping response is received. If MQTT_ReceiveLoop is used instead, then this flag must be cleared manually by the application's callback.

+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_disconnect_function.html b/latest/coreMQTT/mqtt_disconnect_function.html new file mode 100644 index 00000000..0fc1f269 --- /dev/null +++ b/latest/coreMQTT/mqtt_disconnect_function.html @@ -0,0 +1,125 @@ + + + + + + + +coreMQTT: MQTT_Disconnect + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_Disconnect
+
+
+
+
MQTTStatus_t MQTT_Disconnect(MQTTContext_t *pContext)
Disconnect an MQTT session.
Definition: core_mqtt.c:3045
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+

Disconnect an MQTT session.

+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport send failed; MQTTSuccess otherwise.
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_functions.html b/latest/coreMQTT/mqtt_functions.html new file mode 100644 index 00000000..6a17fa65 --- /dev/null +++ b/latest/coreMQTT/mqtt_functions.html @@ -0,0 +1,150 @@ + + + + + + + +coreMQTT: Functions + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ + + + + + diff --git a/latest/coreMQTT/mqtt_functions.js b/latest/coreMQTT/mqtt_functions.js new file mode 100644 index 00000000..2f84fba7 --- /dev/null +++ b/latest/coreMQTT/mqtt_functions.js @@ -0,0 +1,33 @@ +var mqtt_functions = +[ + [ "MQTT_Init", "mqtt_init_function.html", null ], + [ "MQTT_Connect", "mqtt_connect_function.html", null ], + [ "MQTT_Subscribe", "mqtt_subscribe_function.html", null ], + [ "MQTT_Publish", "mqtt_publish_function.html", null ], + [ "MQTT_Ping", "mqtt_ping_function.html", null ], + [ "MQTT_Unsubscribe", "mqtt_unsubscribe_function.html", null ], + [ "MQTT_Disconnect", "mqtt_disconnect_function.html", null ], + [ "MQTT_ProcessLoop", "mqtt_processloop_function.html", null ], + [ "MQTT_ReceiveLoop", "mqtt_receiveloop_function.html", null ], + [ "MQTT_GetPacketId", "mqtt_getpacketid_function.html", null ], + [ "MQTT_GetSubAckStatusCodes", "mqtt_getsubackstatuscodes_function.html", null ], + [ "MQTT_Status_strerror", "mqtt_status_strerror_function.html", null ], + [ "MQTT_PublishToResend", "mqtt_publishtoresend_function.html", null ], + [ "MQTT_GetConnectPacketSize", "mqtt_getconnectpacketsize_function.html", null ], + [ "MQTT_SerializeConnect", "mqtt_serializeconnect_function.html", null ], + [ "MQTT_GetSubscribePacketSize", "mqtt_getsubscribepacketsize_function.html", null ], + [ "MQTT_SerializeSubscribe", "mqtt_serializesubscribe_function.html", null ], + [ "MQTT_GetUnsubscribePacketSize", "mqtt_getunsubscribepacketsize_function.html", null ], + [ "MQTT_SerializeUnsubscribe", "mqtt_serializeunsubscribe_function.html", null ], + [ "MQTT_GetPublishPacketSize", "mqtt_getpublishpacketsize_function.html", null ], + [ "MQTT_SerializePublish", "mqtt_serializepublish_function.html", null ], + [ "MQTT_SerializePublishHeader", "mqtt_serializepublishheader_function.html", null ], + [ "MQTT_SerializeAck", "mqtt_serializeack_function.html", null ], + [ "MQTT_GetDisconnectPacketSize", "mqtt_getdisconnectpacketsize_function.html", null ], + [ "MQTT_SerializeDisconnect", "mqtt_serializedisconnect_function.html", null ], + [ "MQTT_GetPingreqPacketSize", "mqtt_getpingreqpacketsize_function.html", null ], + [ "MQTT_SerializePingreq", "mqtt_serializepingreq_function.html", null ], + [ "MQTT_DeserializePublish", "mqtt_deserializepublish_function.html", null ], + [ "MQTT_DeserializeAck", "mqtt_deserializeack_function.html", null ], + [ "MQTT_GetIncomingPacketTypeAndLength", "mqtt_getincomingpackettypeandlength_function.html", null ] +]; \ No newline at end of file diff --git a/latest/coreMQTT/mqtt_getconnectpacketsize_function.html b/latest/coreMQTT/mqtt_getconnectpacketsize_function.html new file mode 100644 index 00000000..d6d4bdcd --- /dev/null +++ b/latest/coreMQTT/mqtt_getconnectpacketsize_function.html @@ -0,0 +1,156 @@ + + + + + + + +coreMQTT: MQTT_GetConnectPacketSize + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_GetConnectPacketSize
+
+
+
+
const MQTTPublishInfo_t * pWillInfo,
+
size_t * pRemainingLength,
+
size_t * pPacketSize );
+
MQTTStatus_t MQTT_GetConnectPacketSize(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the size and Remaining Length of an MQTT CONNECT packet.
Definition: core_mqtt_serializer.c:1690
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+

Get the size and Remaining Length of an MQTT CONNECT packet.

+

This function must be called before MQTT_SerializeConnect in order to get the size of the MQTT CONNECT packet that is generated from MQTTConnectInfo_t and optional MQTTPublishInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializeConnect must be at least pPacketSize. The provided pConnectInfo and pWillInfo are valid for serialization with MQTT_SerializeConnect only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + + +
[in]pConnectInfoMQTT CONNECT packet parameters.
[in]pWillInfoLast Will and Testament. Pass NULL if not used.
[out]pRemainingLengthThe Remaining Length of the MQTT CONNECT packet.
[out]pPacketSizeThe total size of the MQTT CONNECT packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
+
// Initialize the connection info, the details are out of scope for this example.
+
initializeConnectInfo( &connectInfo );
+
+
// Initialize the optional will info, the details are out of scope for this example.
+
initializeWillInfo( &willInfo );
+
+
// Get the size requirement for the connect packet.
+ +
&connectInfo, &willInfo, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the connect request.
+
}
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_getdisconnectpacketsize_function.html b/latest/coreMQTT/mqtt_getdisconnectpacketsize_function.html new file mode 100644 index 00000000..eae578ad --- /dev/null +++ b/latest/coreMQTT/mqtt_getdisconnectpacketsize_function.html @@ -0,0 +1,136 @@ + + + + + + + +coreMQTT: MQTT_GetDisconnectPacketSize + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_GetDisconnectPacketSize
+
+
+
+
MQTTStatus_t MQTT_GetDisconnectPacketSize(size_t *pPacketSize)
Get the size of an MQTT DISCONNECT packet.
Definition: core_mqtt_serializer.c:2321
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+

Get the size of an MQTT DISCONNECT packet.

+
Parameters
+ + +
[out]pPacketSizeThe size of the MQTT DISCONNECT packet.
+
+
+
Returns
MQTTSuccess, or MQTTBadParameter if pPacketSize is NULL.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
size_t packetSize = 0;
+
+
// Get the size requirement for the disconnect packet.
+
status = MQTT_GetDisconnectPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize == 2 );
+
+
// The application should allocate or use a static #MQTTFixedBuffer_t of
+
// size >= 2 to serialize the disconnect packet.
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_getincomingpackettypeandlength_function.html b/latest/coreMQTT/mqtt_getincomingpackettypeandlength_function.html new file mode 100644 index 00000000..5ddfdcb4 --- /dev/null +++ b/latest/coreMQTT/mqtt_getincomingpackettypeandlength_function.html @@ -0,0 +1,173 @@ + + + + + + + +coreMQTT: MQTT_GetIncomingPacketTypeAndLength + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_GetIncomingPacketTypeAndLength
+
+
+
+
NetworkContext_t * pNetworkContext,
+
MQTTPacketInfo_t * pIncomingPacket );
+
MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength(TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket)
Extract the MQTT packet type and length from incoming packet.
Definition: core_mqtt_serializer.c:2561
+
int32_t(* TransportRecv_t)(NetworkContext_t *pNetworkContext, void *pBuffer, size_t bytesToRecv)
Transport interface for receiving data on the network.
Definition: transport_interface.h:218
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+

Extract the MQTT packet type and length from incoming packet.

+

This function must be called for every incoming packet to retrieve the MQTTPacketInfo_t.type and MQTTPacketInfo_t.remainingLength. A MQTTPacketInfo_t is not valid until this routine has been invoked.

+
Parameters
+ + + + +
[in]readFuncTransport layer read function pointer.
[in]pNetworkContextThe network context pointer provided by the application.
[out]pIncomingPacketPointer to MQTTPacketInfo_t structure. This is where type, remaining length and packet identifier are stored.
+
+
+
Returns
MQTTSuccess on successful extraction of type and length, MQTTBadParameter if pIncomingPacket is invalid, MQTTRecvFailed on transport receive failure, MQTTBadResponse if an invalid packet is read, and MQTTNoDataAvailable if there is nothing to read.
+

Example

// TransportRecv_t function for reading from the network.
+
int32_t socket_recv(
+
NetworkContext_t * pNetworkContext,
+
void * pBuffer,
+
size_t bytesToRecv
+
);
+
// Some context to be used with above transport receive function.
+
NetworkContext_t networkContext;
+
+
// Struct to hold the incoming packet information.
+
MQTTPacketInfo_t incomingPacket;
+ +
int32_t bytesRecvd;
+
// Buffer to hold the remaining data of the incoming packet.
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
// Loop until data is available to be received.
+
do{
+ +
socket_recv,
+
&networkContext,
+
&incomingPacket
+
);
+
} while( status == MQTTNoDataAvailable );
+
+
assert( status == MQTTSuccess );
+
+
// Receive the rest of the incoming packet.
+
assert( incomingPacket.remainingLength <= BUFFER_SIZE );
+
bytesRecvd = socket_recv(
+
&networkContext,
+
( void * ) buffer,
+
incomingPacket.remainingLength
+
);
+
+
// Set the remaining data field.
+
incomingPacket.pRemainingData = buffer;
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
@ MQTTNoDataAvailable
Definition: core_mqtt_serializer.h:95
+
size_t remainingLength
Length of remaining serialized data.
Definition: core_mqtt_serializer.h:258
+
uint8_t * pRemainingData
Remaining serialized data in the MQTT packet.
Definition: core_mqtt_serializer.h:253
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_getpacketid_function.html b/latest/coreMQTT/mqtt_getpacketid_function.html new file mode 100644 index 00000000..e19987a0 --- /dev/null +++ b/latest/coreMQTT/mqtt_getpacketid_function.html @@ -0,0 +1,124 @@ + + + + + + + +coreMQTT: MQTT_GetPacketId + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_GetPacketId
+
+
+
uint16_t MQTT_GetPacketId( MQTTContext_t * pContext );
+
uint16_t MQTT_GetPacketId(MQTTContext_t *pContext)
Get a packet ID that is valid according to the MQTT 3.1.1 spec.
Definition: core_mqtt.c:3172
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+

Get a packet ID that is valid according to the MQTT 3.1.1 spec.

+
Parameters
+ + +
[in]pContextInitialized MQTT context.
+
+
+
Returns
A non-zero number.
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_getpingreqpacketsize_function.html b/latest/coreMQTT/mqtt_getpingreqpacketsize_function.html new file mode 100644 index 00000000..c04f71b7 --- /dev/null +++ b/latest/coreMQTT/mqtt_getpingreqpacketsize_function.html @@ -0,0 +1,136 @@ + + + + + + + +coreMQTT: MQTT_GetPingreqPacketSize + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_GetPingreqPacketSize
+
+
+
MQTTStatus_t MQTT_GetPingreqPacketSize( size_t * pPacketSize );
+
MQTTStatus_t MQTT_GetPingreqPacketSize(size_t *pPacketSize)
Get the size of an MQTT PINGREQ packet.
Definition: core_mqtt_serializer.c:2384
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+

Get the size of an MQTT PINGREQ packet.

+
Parameters
+ + +
[out]pPacketSizeThe size of the MQTT PINGREQ packet.
+
+
+
Returns
MQTTSuccess or MQTTBadParameter if pPacketSize is NULL.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
size_t packetSize = 0;
+
+
// Get the size requirement for the ping request packet.
+
status = MQTT_GetPingreqPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize == 2 );
+
+
// The application should allocate or use a static #MQTTFixedBuffer_t of
+
// size >= 2 to serialize the ping request.
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_getpublishpacketsize_function.html b/latest/coreMQTT/mqtt_getpublishpacketsize_function.html new file mode 100644 index 00000000..81f48155 --- /dev/null +++ b/latest/coreMQTT/mqtt_getpublishpacketsize_function.html @@ -0,0 +1,159 @@ + + + + + + + +coreMQTT: MQTT_GetPublishPacketSize + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_GetPublishPacketSize
+
+
+
+
size_t * pRemainingLength,
+
size_t * pPacketSize );
+
MQTTStatus_t MQTT_GetPublishPacketSize(const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the packet size and remaining length of an MQTT PUBLISH packet.
Definition: core_mqtt_serializer.c:2057
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+

Get the packet size and remaining length of an MQTT PUBLISH packet.

+

This function must be called before MQTT_SerializePublish in order to get the size of the MQTT PUBLISH packet that is generated from MQTTPublishInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializePublish must be at least pPacketSize. The provided pPublishInfo is valid for serialization with MQTT_SerializePublish only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[out]pRemainingLengthThe Remaining Length of the MQTT PUBLISH packet.
[out]pPacketSizeThe total size of the MQTT PUBLISH packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec or if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
+
// Initialize the publish info.
+
publishInfo.qos = MQTTQoS0;
+
publishInfo.pTopicName = "/some/topic/name";
+
publishInfo.topicNameLength = strlen( publishInfo.pTopicName );
+
publishInfo.pPayload = "Hello World!";
+
publishInfo.payloadLength = strlen( "Hello World!" );
+
+
// Get the size requirement for the publish packet.
+ +
&publishInfo, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the publish.
+
}
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
@ MQTTQoS0
Definition: core_mqtt_serializer.h:110
+
MQTTQoS_t qos
Quality of Service for message.
Definition: core_mqtt_serializer.h:206
+
uint16_t topicNameLength
Length of topic name.
Definition: core_mqtt_serializer.h:226
+
size_t payloadLength
Message payload length.
Definition: core_mqtt_serializer.h:236
+
const char * pTopicName
Topic name on which the message is published.
Definition: core_mqtt_serializer.h:221
+
const void * pPayload
Message payload.
Definition: core_mqtt_serializer.h:231
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_getsubackstatuscodes_function.html b/latest/coreMQTT/mqtt_getsubackstatuscodes_function.html new file mode 100644 index 00000000..167b5ae3 --- /dev/null +++ b/latest/coreMQTT/mqtt_getsubackstatuscodes_function.html @@ -0,0 +1,199 @@ + + + + + + + +coreMQTT: MQTT_GetSubAckStatusCodes + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_GetSubAckStatusCodes
+
+
+
+
uint8_t ** pPayloadStart,
+
size_t * pPayloadSize );
+
MQTTStatus_t MQTT_GetSubAckStatusCodes(const MQTTPacketInfo_t *pSubackPacket, uint8_t **pPayloadStart, size_t *pPayloadSize)
Parses the payload of an MQTT SUBACK packet that contains status codes corresponding to topic filter ...
Definition: core_mqtt.c:3270
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+

Parses the payload of an MQTT SUBACK packet that contains status codes corresponding to topic filter subscription requests from the original subscribe packet.

+

Each return code in the SUBACK packet corresponds to a topic filter in the SUBSCRIBE Packet being acknowledged. The status codes can be one of the following:

    +
  • 0x00 - Success - Maximum QoS 0
  • +
  • 0x01 - Success - Maximum QoS 1
  • +
  • 0x02 - Success - Maximum QoS 2
  • +
  • 0x80 - Failure Refer to MQTTSubAckStatus_t for the status codes.
  • +
+
Parameters
+ + + + +
[in]pSubackPacketThe SUBACK packet whose payload is to be parsed.
[out]pPayloadStartThis is populated with the starting address of the payload (or return codes for topic filters) in the SUBACK packet.
[out]pPayloadSizeThis is populated with the size of the payload in the SUBACK packet. It represents the number of topic filters whose SUBACK status is present in the packet.
+
+
+
Returns
Returns one of the following: +
+

Example

// Global variable used in this example.
+
// This is assumed to be the subscription list in the original SUBSCRIBE packet.
+
MQTTSubscribeInfo_t pSubscribes[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// MQTT_GetSubAckStatusCodes is intended to be used from the application
+
// callback that is called by the library in MQTT_ProcessLoop or MQTT_ReceiveLoop.
+
void eventCallback(
+
MQTTContext_t * pContext,
+
MQTTPacketInfo_t * pPacketInfo,
+
MQTTDeserializedInfo_t * pDeserializedInfo
+
)
+
{
+ +
uint8_t * pCodes;
+
size_t numCodes;
+
+
if( pPacketInfo->type == MQTT_PACKET_TYPE_SUBACK )
+
{
+
status = MQTT_GetSubAckStatusCodes( pPacketInfo, &pCodes, &numCodes );
+
+
// Since the pointers to the payload and payload size are not NULL, and
+
// we use the packet info struct passed to the app callback (verified
+
// to be valid by the library), this function must return success.
+
assert( status == MQTTSuccess );
+
// The server must send a response code for each topic filter in the
+
// original SUBSCRIBE packet.
+
assert( numCodes == NUMBER_OF_SUBSCRIPTIONS );
+
+
for( int i = 0; i < numCodes; i++ )
+
{
+
// The only failure code is 0x80 = MQTTSubAckFailure.
+
if( pCodes[ i ] == MQTTSubAckFailure )
+
{
+
// The subscription failed, we may want to retry the
+
// subscription in pSubscribes[ i ] outside of this callback.
+
}
+
else
+
{
+
// The subscription was granted, but the maximum QoS may be
+
// lower than what was requested. We can verify the granted QoS.
+
if( pSubscribes[ i ].qos != pCodes[ i ] )
+
{
+ +
"Requested QoS %u, but granted QoS %u for %s",
+
pSubscribes[ i ].qos, pCodes[ i ], pSubscribes[ i ].pTopicFilter
+
) );
+
}
+
}
+
}
+
}
+
// Handle other packet types.
+
}
+
#define LogWarn(message)
Macro that is called in the MQTT library for logging "Warning" level messages.
Definition: core_mqtt_config_defaults.h:235
+
#define MQTT_PACKET_TYPE_SUBACK
SUBACK (server-to-client).
Definition: core_mqtt_serializer.h:61
+
@ MQTTSubAckFailure
Failure.
Definition: core_mqtt.h:154
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
Struct to hold deserialized packet information for an MQTTEventCallback_t callback.
Definition: core_mqtt.h:257
+
uint8_t type
Type of incoming MQTT packet.
Definition: core_mqtt_serializer.h:248
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_getsubscribepacketsize_function.html b/latest/coreMQTT/mqtt_getsubscribepacketsize_function.html new file mode 100644 index 00000000..d150cad6 --- /dev/null +++ b/latest/coreMQTT/mqtt_getsubscribepacketsize_function.html @@ -0,0 +1,163 @@ + + + + + + + +coreMQTT: MQTT_GetSubscribePacketSize + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_GetSubscribePacketSize
+
+
+
+
size_t subscriptionCount,
+
size_t * pRemainingLength,
+
size_t * pPacketSize );
+
MQTTStatus_t MQTT_GetSubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.
Definition: core_mqtt_serializer.c:1848
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+

Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.

+

This function must be called before MQTT_SerializeSubscribe in order to get the size of the MQTT SUBSCRIBE packet that is generated from the list of MQTTSubscribeInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializeSubscribe must be at least pPacketSize. The provided pSubscriptionList is valid for serialization with MQTT_SerializeSubscribe only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[out]pRemainingLengthThe Remaining Length of the MQTT SUBSCRIBE packet.
[out]pPacketSizeThe total size of the MQTT SUBSCRIBE packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
// This is assumed to be a list of filters we want to subscribe to.
+
const char * filters[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// Set each subscription.
+
for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )
+
{
+
subscriptionList[ i ].qos = MQTTQoS0;
+
// Each subscription needs a topic filter.
+
subscriptionList[ i ].pTopicFilter = filters[ i ];
+
subscriptionList[ i ].topicFilterLength = strlen( filters[ i ] );
+
}
+
+
// Get the size requirement for the subscribe packet.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the subscribe request.
+
}
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
@ MQTTQoS0
Definition: core_mqtt_serializer.h:110
+
MQTTQoS_t qos
Quality of Service for subscription.
Definition: core_mqtt_serializer.h:184
+
uint16_t topicFilterLength
Length of subscription topic filter.
Definition: core_mqtt_serializer.h:194
+
const char * pTopicFilter
Topic filter to subscribe to.
Definition: core_mqtt_serializer.h:189
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_getunsubscribepacketsize_function.html b/latest/coreMQTT/mqtt_getunsubscribepacketsize_function.html new file mode 100644 index 00000000..daaa13ae --- /dev/null +++ b/latest/coreMQTT/mqtt_getunsubscribepacketsize_function.html @@ -0,0 +1,151 @@ + + + + + + + +coreMQTT: MQTT_GetUnsubscribePacketSize + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_GetUnsubscribePacketSize
+
+
+
+
size_t subscriptionCount,
+
size_t * pRemainingLength,
+
size_t * pPacketSize );
+
MQTTStatus_t MQTT_GetUnsubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.
Definition: core_mqtt_serializer.c:1978
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+

Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.

+

This function must be called before MQTT_SerializeUnsubscribe in order to get the size of the MQTT UNSUBSCRIBE packet that is generated from the list of MQTTSubscribeInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializeUnsubscribe must be at least pPacketSize. The provided pSubscriptionList is valid for serialization with MQTT_SerializeUnsubscribe only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[out]pRemainingLengthThe Remaining Length of the MQTT UNSUBSCRIBE packet.
[out]pPacketSizeThe total size of the MQTT UNSUBSCRIBE packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
+
// Initialize the subscribe info. The details are out of scope for this example.
+
initializeSubscribeInfo( &subscriptionList[ 0 ] );
+
+
// Get the size requirement for the unsubscribe packet.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the unsubscribe request.
+
}
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_init_function.html b/latest/coreMQTT/mqtt_init_function.html new file mode 100644 index 00000000..2a55121f --- /dev/null +++ b/latest/coreMQTT/mqtt_init_function.html @@ -0,0 +1,188 @@ + + + + + + + +coreMQTT: MQTT_Init + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_Init
+
+
+
+
const TransportInterface_t * pTransportInterface,
+
MQTTGetCurrentTimeFunc_t getTimeFunction,
+
MQTTEventCallback_t userCallback,
+
const MQTTFixedBuffer_t * pNetworkBuffer );
+
MQTTStatus_t MQTT_Init(MQTTContext_t *pContext, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getTimeFunction, MQTTEventCallback_t userCallback, const MQTTFixedBuffer_t *pNetworkBuffer)
Initialize an MQTT context.
Definition: core_mqtt.c:2531
+
void(* MQTTEventCallback_t)(struct MQTTContext *pContext, struct MQTTPacketInfo *pPacketInfo, struct MQTTDeserializedInfo *pDeserializedInfo)
Application callback for receiving incoming publishes and incoming acks.
Definition: core_mqtt.h:100
+
uint32_t(* MQTTGetCurrentTimeFunc_t)(void)
Application provided function to query the time elapsed since a given epoch in milliseconds.
Definition: core_mqtt.h:85
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
The transport layer interface.
Definition: transport_interface.h:299
+

Initialize an MQTT context.

+

This function must be called on an MQTTContext_t before any other function.

+
Note
The MQTTGetCurrentTimeFunc_t function for querying time must be defined. If there is no time implementation, it is the responsibility of the application to provide a dummy function to always return 0, provide 0 timeouts for all calls to MQTT_Connect, MQTT_ProcessLoop, and MQTT_ReceiveLoop and configure the MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS configurations to be 0. This will result in loop functions running for a single iteration, and MQTT_Connect relying on MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT to receive the CONNACK packet.
+
Parameters
+ + + + + + +
[in]pContextThe context to initialize.
[in]pTransportInterfaceThe transport interface to use with the context.
[in]getTimeFunctionThe time utility function which can return the amount of time (in milliseconds) elapsed since a given epoch. This function will be used to ensure that timeouts in the API calls are met and keep-alive messages are sent on time.
[in]userCallbackThe user callback to use with the context to notify about incoming packet events.
[in]pNetworkBufferNetwork buffer provided for the context. This buffer will be used to receive incoming messages from the broker. This buffer must remain valid and in scope for the entire lifetime of the pContext and must not be used by another context and/or application.
+
+
+
Returns
MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Function for obtaining a timestamp.
+
uint32_t getTimeStampMs();
+
// Callback function for receiving packets.
+
void eventCallback(
+
MQTTContext_t * pContext,
+
MQTTPacketInfo_t * pPacketInfo,
+
MQTTDeserializedInfo_t * pDeserializedInfo
+
);
+
// Network send.
+
int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
+
// Network receive.
+
int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
+
+
MQTTContext_t mqttContext;
+ +
MQTTFixedBuffer_t fixedBuffer;
+
// Create a globally accessible buffer which remains in scope for the entire duration
+
// of the MQTT context.
+
uint8_t buffer[ 1024 ];
+
+
// Clear context.
+
memset( ( void * ) &mqttContext, 0x00, sizeof( MQTTContext_t ) );
+
+
// Set transport interface members.
+
transport.pNetworkContext = &someTransportContext;
+
transport.send = networkSend;
+
transport.recv = networkRecv;
+
+
// Set buffer members.
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = 1024;
+
+
status = MQTT_Init( &mqttContext, &transport, getTimeStampMs, eventCallback, &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// Do something with mqttContext. The transport and fixedBuffer structs were
+
// copied into the context, so the original structs do not need to stay in scope.
+
// However, the memory pointed to by the fixedBuffer.pBuffer must remain in scope.
+
}
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
+
Struct to hold deserialized packet information for an MQTTEventCallback_t callback.
Definition: core_mqtt.h:257
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+
TransportSend_t send
Definition: transport_interface.h:301
+
TransportRecv_t recv
Definition: transport_interface.h:300
+
NetworkContext_t * pNetworkContext
Definition: transport_interface.h:303
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_ping_function.html b/latest/coreMQTT/mqtt_ping_function.html new file mode 100644 index 00000000..21d995fb --- /dev/null +++ b/latest/coreMQTT/mqtt_ping_function.html @@ -0,0 +1,125 @@ + + + + + + + +coreMQTT: MQTT_Ping + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_Ping
+
+
+
+
MQTTStatus_t MQTT_Ping(MQTTContext_t *pContext)
Sends an MQTT PINGREQ to broker.
Definition: core_mqtt.c:2922
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+

Sends an MQTT PINGREQ to broker.

+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Returns
MQTTNoMemory if pBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_porting.html b/latest/coreMQTT/mqtt_porting.html new file mode 100644 index 00000000..c76bccd7 --- /dev/null +++ b/latest/coreMQTT/mqtt_porting.html @@ -0,0 +1,161 @@ + + + + + + + +coreMQTT: Porting Guide + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Porting Guide
+
+
+

Guide for porting MQTT to a new platform.

+

A port to a new platform must provide the following components:

    +
  1. Configuration Macros
  2. +
  3. Transport Interface
  4. +
  5. Time Function
  6. +
+

+Configuration Macros

+

Settings that must be set as macros in the config header core_mqtt_config.h, or passed in as compiler options.

+
Note
If a custom configuration header core_mqtt_config.h is not provided, then the MQTT_DO_NOT_USE_CUSTOM_CONFIG macro must be defined.
+
See also
Configurations
+

The following macros can be configured for the managed MQTT library:

+

In addition, the following logging macros are used throughout the library:

+

+Transport Interface

+

The MQTT library relies on an underlying transport interface API that must be implemented in order to send and receive packets on a network.

+
See also
Transport Interface
+

The transport interface API used by MQTT is defined in transport_interface.h. A port must implement functions corresponding to the following functions pointers:

    +
  • Transport Receive: A function to receive bytes from a network.
    int32_t (* TransportRecv_t )(
    +
    NetworkContext_t * pNetworkContext, void * pBuffer, size_t bytesToRecv
    +
    );
    +
    int32_t(* TransportRecv_t)(NetworkContext_t *pNetworkContext, void *pBuffer, size_t bytesToRecv)
    Transport interface for receiving data on the network.
    Definition: transport_interface.h:218
    +
    struct NetworkContext NetworkContext_t
    The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
    Definition: transport_interface.h:191
    +
  • +
  • Transport Send: A function to send bytes over a network.
    int32_t (* TransportSend_t )(
    +
    NetworkContext_t * pNetworkContext, const void * pBuffer, size_t bytesToSend
    +
    );
    +
    int32_t(* TransportSend_t)(NetworkContext_t *pNetworkContext, const void *pBuffer, size_t bytesToSend)
    Transport interface for sending data over the network.
    Definition: transport_interface.h:240
    +
  • +
+

The above two functions take in a pointer to a NetworkContext_t, the typename of a struct NetworkContext. The NetworkContext struct must also be defined by the port, and ought to contain any information necessary to send and receive data with the TransportSend_t and TransportRecv_t implementations, respectively:

struct NetworkContext {
+
// Fields necessary for the transport implementations, e.g. a TCP socket descriptor.
+
};
+

+Time Function

+

The MQTT library relies on a function to generate millisecond timestamps, for the purpose of calculating durations and timeouts, as well as maintaining the keep-alive mechanism of the MQTT protocol.

+
See also
MQTTGetCurrentTimeFunc_t
+

Platforms must supply a function capable of generating 32 bit timestamps of millisecond resolution. These timestamps need not correspond with any real world clock; the only requirement is that the difference between two timestamps must be an accurate representation of the duration between them, in milliseconds.

+
Note
Should the platform be incapable of providing millisecond timestamps, the port may instead provide a function that always returns 0, or a strictly non-decreasing sequence. In this case, the timeout values in all library calls to MQTT_Connect, MQTT_ProcessLoop, or MQTT_ReceiveLoop MUST be set to 0, resulting in loop functions running for a single iteration, and MQTT_Connect relying on MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT to receive the CONNACK packet.
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_processloop_design.png b/latest/coreMQTT/mqtt_processloop_design.png new file mode 100644 index 0000000000000000000000000000000000000000..cffe3d256ea929745f39d1ecb10d2e265a7a1a03 GIT binary patch literal 274031 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

xnIuuoK)`Bba{X>{i#+{otHQQ-fa_@C3|Yj7 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%0DT<;70{JJZgd({;A;l&<-jrue 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

%!#fRjvh86cG_nQ9!DQ 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 literal 0 HcmV?d00001 diff --git a/latest/coreMQTT/mqtt_processloop_function.html b/latest/coreMQTT/mqtt_processloop_function.html new file mode 100644 index 00000000..d01ebe9b --- /dev/null +++ b/latest/coreMQTT/mqtt_processloop_function.html @@ -0,0 +1,148 @@ + + + + + + + +coreMQTT: MQTT_ProcessLoop + + + + + + + + + + + + + + + +

+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_ProcessLoop
+
+
+
+
MQTTStatus_t MQTT_ProcessLoop(MQTTContext_t *pContext)
Loop to receive packets from the transport interface. Handles keep alive.
Definition: core_mqtt.c:3119
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+

Loop to receive packets from the transport interface. Handles keep alive.

+
Note
If a dummy timer function, MQTTGetCurrentTimeFunc_t, is passed to the library, then the keep-alive mechanism is not supported by the MQTT_ProcessLoop API. In that case, the MQTT_ReceiveLoop API function should be used instead.
+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Note
Calling this function blocks the calling context for a time period that depends on the passed the configuration macros, MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS, and the underlying transport interface implementation timeouts, unless an error occurs. The blocking period also depends on the execution time of the MQTTEventCallback_t callback supplied to the library. It is recommended that the supplied MQTTEventCallback_t callback does not contain blocking operations to prevent potential non-deterministic blocking period of the MQTT_ProcessLoop API call.
+
Returns
MQTTBadParameter if context is NULL; MQTTRecvFailed if a network error occurs during reception; MQTTSendFailed if a network error occurs while sending an ACK or PINGREQ; MQTTBadResponse if an invalid packet is received; MQTTKeepAliveTimeout if the server has not sent a PINGRESP before MQTT_PINGRESP_TIMEOUT_MS milliseconds; MQTTIllegalState if an incoming QoS 1/2 publish or ack causes an invalid transition for the internal state machine; MQTTNeedMoreBytes if MQTT_ProcessLoop has received incomplete data; it should be called again (probably after a delay); MQTTSuccess on success.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
+
while( true )
+
{
+
status = MQTT_ProcessLoop( pContext );
+
+
if( status != MQTTSuccess && status != MQTTNeedMoreBytes )
+
{
+
// Determine the error. It's possible we might need to disconnect
+
// the underlying transport connection.
+
}
+
else
+
{
+
// Other application functions.
+
}
+
}
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
@ MQTTNeedMoreBytes
Definition: core_mqtt_serializer.h:99
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_publish_function.html b/latest/coreMQTT/mqtt_publish_function.html new file mode 100644 index 00000000..170f1865 --- /dev/null +++ b/latest/coreMQTT/mqtt_publish_function.html @@ -0,0 +1,162 @@ + + + + + + + +coreMQTT: MQTT_Publish + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_Publish
+
+
+
+
const MQTTPublishInfo_t * pPublishInfo,
+
uint16_t packetId );
+
MQTTStatus_t MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId)
Publishes a message to the given topic name.
Definition: core_mqtt.c:2805
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+

Publishes a message to the given topic name.

+
Parameters
+ + + + +
[in]pContextInitialized MQTT context.
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
+
+
+
Returns
MQTTNoMemory if pBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo;
+
uint16_t packetId;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
+
// QoS of publish.
+
publishInfo.qos = MQTTQoS1;
+
publishInfo.pTopicName = "/some/topic/name";
+
publishInfo.topicNameLength = strlen( publishInfo.pTopicName );
+
publishInfo.pPayload = "Hello World!";
+
publishInfo.payloadLength = strlen( "Hello World!" );
+
+
// Packet ID is needed for QoS > 0.
+
packetId = MQTT_GetPacketId( pContext );
+
+
status = MQTT_Publish( pContext, &publishInfo, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// Since the QoS is > 0, we will need to call MQTT_ReceiveLoop()
+
// or MQTT_ProcessLoop() to process the publish acknowledgments.
+
}
+
uint16_t MQTT_GetPacketId(MQTTContext_t *pContext)
Get a packet ID that is valid according to the MQTT 3.1.1 spec.
Definition: core_mqtt.c:3172
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
@ MQTTQoS1
Definition: core_mqtt_serializer.h:111
+
MQTTQoS_t qos
Quality of Service for message.
Definition: core_mqtt_serializer.h:206
+
uint16_t topicNameLength
Length of topic name.
Definition: core_mqtt_serializer.h:226
+
size_t payloadLength
Message payload length.
Definition: core_mqtt_serializer.h:236
+
const char * pTopicName
Topic name on which the message is published.
Definition: core_mqtt_serializer.h:221
+
const void * pPayload
Message payload.
Definition: core_mqtt_serializer.h:231
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_publishtoresend_function.html b/latest/coreMQTT/mqtt_publishtoresend_function.html new file mode 100644 index 00000000..cdc9ba65 --- /dev/null +++ b/latest/coreMQTT/mqtt_publishtoresend_function.html @@ -0,0 +1,189 @@ + + + + + + + +coreMQTT: MQTT_PublishToResend + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_PublishToResend
+
+
+
uint16_t MQTT_PublishToResend( const MQTTContext_t * pMqttContext,
+
MQTTStateCursor_t * pCursor );
+
uint16_t MQTT_PublishToResend(const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor)
Get the packet ID of next pending publish to be resent.
Definition: core_mqtt_state.c:1123
+
size_t MQTTStateCursor_t
Cursor for iterating through state records.
Definition: core_mqtt_state.h:51
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+

Get the packet ID of next pending publish to be resent.

+

This function will need to be called to get the packet for which a publish need to be sent when a session is reestablished. Calling this function repeatedly until packet id is 0 will give all the packets for which a publish need to be resent in the correct order.

+
Parameters
+ + + +
[in]pMqttContextInitialized MQTT context.
[in,out]pCursorIndex at which to start searching.
+
+
+

Example

// For this example assume this function returns an outgoing unacknowledged
+
// QoS 1 or 2 publish from its packet identifier.
+
MQTTPublishInfo_t * getPublish( uint16_t packetID );
+
+
// Variables used in this example.
+
MQTTStatus_t status;
+ +
bool sessionPresent;
+
uint16_t packetID;
+
MQTTPublishInfo_t * pResendPublish = NULL;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
+
// This is assumed to have been initialized before the call to MQTT_Connect().
+
MQTTContext_t * pContext;
+
+
// Set clean session to false to attempt session resumption.
+
connectInfo.cleanSession = false;
+
connectInfo.pClientIdentifier = "someClientID";
+
connectInfo.clientIdentifierLength = strlen( connectInfo.pClientIdentifier );
+
connectInfo.keepAliveSeconds = 60;
+
// Optional connect parameters are not relevant to this example.
+
+
// Create an MQTT connection. Use 100 milliseconds as a timeout.
+
status = MQTT_Connect( pContext, &connectInfo, NULL, 100, &sessionPresent );
+
+
if( status == MQTTSuccess )
+
{
+
if( sessionPresent )
+
{
+
// Loop while packet ID is nonzero.
+
while( ( packetID = MQTT_PublishToResend( pContext, &cursor ) ) != 0 )
+
{
+
// Assume this function will succeed.
+
pResendPublish = getPublish( packetID );
+
// Set DUP flag.
+
pResendPublish->dup = true;
+
status = MQTT_Publish( pContext, pResendPublish, packetID );
+
+
if( status != MQTTSuccess )
+
{
+
// Application can decide how to handle a failure.
+
}
+
}
+
}
+
else
+
{
+
// The broker did not resume a session, so we can clean up the
+
// list of outgoing publishes.
+
}
+
}
+
MQTTStatus_t MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId)
Publishes a message to the given topic name.
Definition: core_mqtt.c:2805
+
MQTTStatus_t MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
Establish an MQTT session.
Definition: core_mqtt.c:2679
+
#define MQTT_STATE_CURSOR_INITIALIZER
Initializer value for an MQTTStateCursor_t, indicating a search should start at the beginning of a st...
Definition: core_mqtt_state.h:45
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
const char * pClientIdentifier
MQTT client identifier. Must be unique per client.
Definition: core_mqtt_serializer.h:147
+
bool cleanSession
Whether to establish a new, clean session or resume a previous session.
Definition: core_mqtt_serializer.h:137
+
uint16_t keepAliveSeconds
MQTT keep alive period.
Definition: core_mqtt_serializer.h:142
+
uint16_t clientIdentifierLength
Length of the client identifier.
Definition: core_mqtt_serializer.h:152
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+
bool dup
Whether this is a duplicate publish message.
Definition: core_mqtt_serializer.h:216
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_receiveloop_design.png b/latest/coreMQTT/mqtt_receiveloop_design.png new file mode 100644 index 0000000000000000000000000000000000000000..d86b72b52b98ffa0bb248a6d0f7ca901d4b4ed1a GIT binary patch literal 241200 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%0DChF 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

AJbk6ytfS-5=xW)9c_ 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�Q-f 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

vQf0XS@L6fJ?`Ydut37KYYj>x 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 E0F#nHf&c&j literal 0 HcmV?d00001 diff --git a/latest/coreMQTT/mqtt_receiveloop_function.html b/latest/coreMQTT/mqtt_receiveloop_function.html new file mode 100644 index 00000000..57e9a025 --- /dev/null +++ b/latest/coreMQTT/mqtt_receiveloop_function.html @@ -0,0 +1,159 @@ + + + + + + + +coreMQTT: MQTT_ReceiveLoop + + + + + + + + + + + + + + + +

+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_ReceiveLoop
+
+
+
+
MQTTStatus_t MQTT_ReceiveLoop(MQTTContext_t *pContext)
Loop to receive packets from the transport interface. Does not handle keep alive.
Definition: core_mqtt.c:3146
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+

Loop to receive packets from the transport interface. Does not handle keep alive.

+
Note
If a dummy MQTTGetCurrentTimeFunc_t was passed to MQTT_Init, then the MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS timeout configurations MUST be set to 0.
+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Note
Calling this function blocks the calling context for a time period that depends on the the configuration macros, MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS, and the underlying transport interface implementation timeouts, unless an error occurs. The blocking period also depends on the execution time of the MQTTEventCallback_t callback supplied to the library. It is recommended that the supplied MQTTEventCallback_t callback does not contain blocking operations to prevent potential non-deterministic blocking period of the MQTT_ReceiveLoop API call.
+
Returns
MQTTBadParameter if context is NULL; MQTTRecvFailed if a network error occurs during reception; MQTTSendFailed if a network error occurs while sending an ACK or PINGREQ; MQTTBadResponse if an invalid packet is received; MQTTIllegalState if an incoming QoS 1/2 publish or ack causes an invalid transition for the internal state machine; MQTTNeedMoreBytes if MQTT_ReceiveLoop has received incomplete data; it should be called again (probably after a delay); MQTTSuccess on success.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
uint32_t keepAliveMs = 60 * 1000;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
+
while( true )
+
{
+
status = MQTT_ReceiveLoop( pContext );
+
+
if( status != MQTTSuccess && status != MQTTNeedMoreBytes )
+
{
+
// Determine the error. It's possible we might need to disconnect
+
// the underlying transport connection.
+
}
+
else
+
{
+
// Since this function does not send pings, the application may need
+
// to in order to comply with keep alive.
+
if( ( pContext->getTime() - pContext->lastPacketTxTime ) > keepAliveMs )
+
{
+
status = MQTT_Ping( pContext );
+
}
+
+
// Other application functions.
+
}
+
}
+
MQTTStatus_t MQTT_Ping(MQTTContext_t *pContext)
Sends an MQTT PINGREQ to broker.
Definition: core_mqtt.c:2922
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
@ MQTTNeedMoreBytes
Definition: core_mqtt_serializer.h:99
+
uint32_t lastPacketTxTime
Timestamp of the last packet sent by the library.
Definition: core_mqtt.h:227
+
MQTTGetCurrentTimeFunc_t getTime
Function used to get millisecond timestamps.
Definition: core_mqtt.h:217
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_serializeack_function.html b/latest/coreMQTT/mqtt_serializeack_function.html new file mode 100644 index 00000000..632539c8 --- /dev/null +++ b/latest/coreMQTT/mqtt_serializeack_function.html @@ -0,0 +1,159 @@ + + + + + + + +coreMQTT: MQTT_SerializeAck + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_SerializeAck
+
+
+
+
uint8_t packetType,
+
uint16_t packetId );
+
MQTTStatus_t MQTT_SerializeAck(const MQTTFixedBuffer_t *pFixedBuffer, uint8_t packetType, uint16_t packetId)
Serialize an MQTT PUBACK, PUBREC, PUBREL, or PUBCOMP into the given buffer.
Definition: core_mqtt_serializer.c:2266
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+

Serialize an MQTT PUBACK, PUBREC, PUBREL, or PUBCOMP into the given buffer.

+
Parameters
+ + + + +
[out]pFixedBufferBuffer for packet serialization.
[in]packetTypeByte of the corresponding packet fixed header per the MQTT spec.
[in]packetIdPacket ID of the publish.
+
+
+
Returns
MQTTBadParameter, MQTTNoMemory, or MQTTSuccess.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
uint16_t packetId;
+
uint8_t packetType;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
// The fixed buffer must be large enough to hold 4 bytes.
+
assert( BUFFER_SIZE >= MQTT_PUBLISH_ACK_PACKET_SIZE );
+
+
// The packet ID must be the same as the original publish packet.
+
packetId = publishPacketId;
+
+
// The byte representing a packet of type ACK. This function accepts PUBACK, PUBREC, PUBREL, or PUBCOMP.
+ +
+
// Serialize the publish acknowledgment into the fixed buffer.
+
status = MQTT_SerializeAck( &fixedBuffer, packetType, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// The publish acknowledgment can now be sent to the broker.
+
}
+
#define MQTT_PUBLISH_ACK_PACKET_SIZE
The size of MQTT PUBACK, PUBREC, PUBREL, and PUBCOMP packets, per MQTT spec.
Definition: core_mqtt_serializer.h:73
+
#define MQTT_PACKET_TYPE_PUBACK
PUBACK (bidirectional).
Definition: core_mqtt_serializer.h:56
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_serializeconnect_function.html b/latest/coreMQTT/mqtt_serializeconnect_function.html new file mode 100644 index 00000000..40ea635c --- /dev/null +++ b/latest/coreMQTT/mqtt_serializeconnect_function.html @@ -0,0 +1,164 @@ + + + + + + + +coreMQTT: MQTT_SerializeConnect + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_SerializeConnect
+
+
+
+
const MQTTPublishInfo_t * pWillInfo,
+
size_t remainingLength,
+
const MQTTFixedBuffer_t * pFixedBuffer );
+
MQTTStatus_t MQTT_SerializeConnect(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT CONNECT packet in the given fixed buffer pFixedBuffer.
Definition: core_mqtt_serializer.c:1790
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+

Serialize an MQTT CONNECT packet in the given fixed buffer pFixedBuffer.

+

MQTT_GetConnectPacketSize should be called with pConnectInfo and pWillInfo before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetConnectPacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetConnectPacketSize.

+
Parameters
+ + + + + +
[in]pConnectInfoMQTT CONNECT packet parameters.
[in]pWillInfoLast Will and Testament. Pass NULL if not used.
[in]remainingLengthRemaining Length provided by MQTT_GetConnectPacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Assume connectInfo and willInfo are initialized. Get the size requirement for
+
// the connect packet.
+ +
&connectInfo, &willInfo, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the connect packet into the fixed buffer.
+
status = MQTT_SerializeConnect( &connectInfo, &willInfo, remainingLength, &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// The connect packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_GetConnectPacketSize(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the size and Remaining Length of an MQTT CONNECT packet.
Definition: core_mqtt_serializer.c:1690
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_serializedisconnect_function.html b/latest/coreMQTT/mqtt_serializedisconnect_function.html new file mode 100644 index 00000000..9fd8d5c8 --- /dev/null +++ b/latest/coreMQTT/mqtt_serializedisconnect_function.html @@ -0,0 +1,150 @@ + + + + + + + +coreMQTT: MQTT_SerializeDisconnect + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_SerializeDisconnect
+
+
+
+
MQTTStatus_t MQTT_SerializeDisconnect(const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT DISCONNECT packet into the given buffer.
Definition: core_mqtt_serializer.c:2341
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+

Serialize an MQTT DISCONNECT packet into the given buffer.

+

The input MQTTFixedBuffer_t.size must be at least as large as the size returned by MQTT_GetDisconnectPacketSize.

+
Parameters
+ + +
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Get the disconnect packet size.
+
status = MQTT_GetDisconnectPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the disconnect into the fixed buffer.
+
status = MQTT_SerializeDisconnect( &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// The disconnect packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_GetDisconnectPacketSize(size_t *pPacketSize)
Get the size of an MQTT DISCONNECT packet.
Definition: core_mqtt_serializer.c:2321
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_serializepingreq_function.html b/latest/coreMQTT/mqtt_serializepingreq_function.html new file mode 100644 index 00000000..e9d7987e --- /dev/null +++ b/latest/coreMQTT/mqtt_serializepingreq_function.html @@ -0,0 +1,150 @@ + + + + + + + +coreMQTT: MQTT_SerializePingreq + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_SerializePingreq
+
+
+
+
MQTTStatus_t MQTT_SerializePingreq(const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT PINGREQ packet into the given buffer.
Definition: core_mqtt_serializer.c:2404
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+

Serialize an MQTT PINGREQ packet into the given buffer.

+

The input MQTTFixedBuffer_t.size must be at least as large as the size returned by MQTT_GetPingreqPacketSize.

+
Parameters
+ + +
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Get the ping request packet size.
+
status = MQTT_GetPingreqPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the ping request into the fixed buffer.
+
status = MQTT_SerializePingreq( &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// The ping request can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_GetPingreqPacketSize(size_t *pPacketSize)
Get the size of an MQTT PINGREQ packet.
Definition: core_mqtt_serializer.c:2384
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_serializepublish_function.html b/latest/coreMQTT/mqtt_serializepublish_function.html new file mode 100644 index 00000000..f31b6041 --- /dev/null +++ b/latest/coreMQTT/mqtt_serializepublish_function.html @@ -0,0 +1,172 @@ + + + + + + + +coreMQTT: MQTT_SerializePublish + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_SerializePublish
+
+
+
+
uint16_t packetId,
+
size_t remainingLength,
+
const MQTTFixedBuffer_t * pFixedBuffer );
+
MQTTStatus_t MQTT_SerializePublish(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT PUBLISH packet in the given buffer.
Definition: core_mqtt_serializer.c:2098
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+

Serialize an MQTT PUBLISH packet in the given buffer.

+

This function will serialize complete MQTT PUBLISH packet into the given buffer. If the PUBLISH payload can be sent separately, consider using MQTT_SerializePublishHeader, which will serialize only the PUBLISH header into the buffer.

+

MQTT_GetPublishPacketSize should be called with pPublishInfo before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetPublishPacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetPublishPacketSize.

+
Parameters
+ + + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetPublishPacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
uint16_t packetId;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// A packet identifier is unused for QoS 0 publishes. Otherwise, a valid, unused packet
+
// identifier must be used.
+
packetId = 0;
+
+
// Assume publishInfo has been initialized. Get publish packet size.
+ +
&publishInfo, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the publish packet into the fixed buffer.
+ +
&publishInfo,
+
packetId,
+
remainingLength,
+
&fixedBuffer
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The publish packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_GetPublishPacketSize(const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the packet size and remaining length of an MQTT PUBLISH packet.
Definition: core_mqtt_serializer.c:2057
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_serializepublishheader_function.html b/latest/coreMQTT/mqtt_serializepublishheader_function.html new file mode 100644 index 00000000..7da34f54 --- /dev/null +++ b/latest/coreMQTT/mqtt_serializepublishheader_function.html @@ -0,0 +1,185 @@ + + + + + + + +coreMQTT: MQTT_SerializePublishHeader + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_SerializePublishHeader
+
+
+
+
uint16_t packetId,
+
size_t remainingLength,
+
const MQTTFixedBuffer_t * pFixedBuffer,
+
size_t * pHeaderSize );
+
MQTTStatus_t MQTT_SerializePublishHeader(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer, size_t *pHeaderSize)
Serialize an MQTT PUBLISH packet header in the given buffer.
Definition: core_mqtt_serializer.c:2183
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+

Serialize an MQTT PUBLISH packet header in the given buffer.

+

This function serializes PUBLISH header in to the given buffer. The payload for PUBLISH will not be copied over to the buffer. This will help reduce the memory needed for the buffer and avoid an unwanted copy operation of the PUBLISH payload into the buffer. If the payload also would need to be part of the serialized buffer, consider using MQTT_SerializePublish.

+

MQTT_GetPublishPacketSize should be called with pPublishInfo before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetPublishPacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetPublishPacketSize.

+
Parameters
+ + + + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetPublishPacketSize.
[out]pFixedBufferBuffer for packet serialization.
[out]pHeaderSizeSize of the serialized MQTT PUBLISH header.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0, headerSize = 0;
+
uint16_t packetId;
+
int32_t bytesSent;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// A packet identifier is unused for QoS 0 publishes. Otherwise, a valid, unused packet
+
// identifier must be used.
+
packetId = 0;
+
+
// Assume publishInfo has been initialized. Get the publish packet size.
+ +
&publishInfo, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
// The payload will not be serialized, so the the fixed buffer does not need to hold it.
+
assert( ( packetSize - publishInfo.payloadLength ) <= BUFFER_SIZE );
+
+
// Serialize the publish packet header into the fixed buffer.
+ +
&publishInfo,
+
packetId,
+
remainingLength,
+
&fixedBuffer,
+
&headerSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The publish header and payload can now be sent to the broker.
+
// mqttSocket here is a socket descriptor created and connected to the MQTT
+
// broker outside of this function.
+
bytesSent = send( mqttSocket, ( void * ) fixedBuffer.pBuffer, headerSize, 0 );
+
assert( bytesSent == headerSize );
+
bytesSent = send( mqttSocket, publishInfo.pPayload, publishInfo.payloadLength, 0 );
+
assert( bytesSent == publishInfo.payloadLength );
+
}
+
MQTTStatus_t MQTT_GetPublishPacketSize(const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the packet size and remaining length of an MQTT PUBLISH packet.
Definition: core_mqtt_serializer.c:2057
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
size_t payloadLength
Message payload length.
Definition: core_mqtt_serializer.h:236
+
const void * pPayload
Message payload.
Definition: core_mqtt_serializer.h:231
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_serializesubscribe_function.html b/latest/coreMQTT/mqtt_serializesubscribe_function.html new file mode 100644 index 00000000..ca7ad054 --- /dev/null +++ b/latest/coreMQTT/mqtt_serializesubscribe_function.html @@ -0,0 +1,174 @@ + + + + + + + +coreMQTT: MQTT_SerializeSubscribe + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_SerializeSubscribe
+
+
+
+
size_t subscriptionCount,
+
uint16_t packetId,
+
size_t remainingLength,
+
const MQTTFixedBuffer_t * pFixedBuffer );
+
MQTTStatus_t MQTT_SerializeSubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT SUBSCRIBE packet in the given buffer.
Definition: core_mqtt_serializer.c:1932
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+

Serialize an MQTT SUBSCRIBE packet in the given buffer.

+

MQTT_GetSubscribePacketSize should be called with pSubscriptionList before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetSubscribePacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetSubscribePacketSize.

+
Parameters
+ + + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetSubscribePacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
uint16_t packetId;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Function to return a valid, unused packet identifier. The details are out of
+
// scope for this example.
+
packetId = getNewPacketId();
+
+
// Assume subscriptionList has been initialized. Get the subscribe packet size.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the subscribe packet into the fixed buffer.
+ +
&subscriptionList[ 0 ],
+
NUMBER_OF_SUBSCRIPTIONS,
+
packetId,
+
remainingLength,
+
&fixedBuffer
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The subscribe packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_GetSubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.
Definition: core_mqtt_serializer.c:1848
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_serializeunsubscribe_function.html b/latest/coreMQTT/mqtt_serializeunsubscribe_function.html new file mode 100644 index 00000000..19a6d061 --- /dev/null +++ b/latest/coreMQTT/mqtt_serializeunsubscribe_function.html @@ -0,0 +1,174 @@ + + + + + + + +coreMQTT: MQTT_SerializeUnsubscribe + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_SerializeUnsubscribe
+
+
+
+
size_t subscriptionCount,
+
uint16_t packetId,
+
size_t remainingLength,
+
const MQTTFixedBuffer_t * pFixedBuffer );
+
MQTTStatus_t MQTT_SerializeUnsubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT UNSUBSCRIBE packet in the given buffer.
Definition: core_mqtt_serializer.c:2016
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+

Serialize an MQTT UNSUBSCRIBE packet in the given buffer.

+

MQTT_GetUnsubscribePacketSize should be called with pSubscriptionList before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetUnsubscribePacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetUnsubscribePacketSize.

+
Parameters
+ + + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetUnsubscribePacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
uint16_t packetId;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Function to return a valid, unused packet identifier. The details are out of
+
// scope for this example.
+
packetId = getNewPacketId();
+
+
// Assume subscriptionList has been initialized. Get the unsubscribe packet size.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the unsubscribe packet into the fixed buffer.
+ +
&subscriptionList[ 0 ],
+
NUMBER_OF_SUBSCRIPTIONS,
+
packetId,
+
remainingLength,
+
&fixedBuffer
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The unsubscribe packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_GetUnsubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.
Definition: core_mqtt_serializer.c:1978
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_status_strerror_function.html b/latest/coreMQTT/mqtt_status_strerror_function.html new file mode 100644 index 00000000..5a781bcb --- /dev/null +++ b/latest/coreMQTT/mqtt_status_strerror_function.html @@ -0,0 +1,124 @@ + + + + + + + +coreMQTT: MQTT_Status_strerror + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_Status_strerror
+
+
+
const char * MQTT_Status_strerror( MQTTStatus_t status );
+
const char * MQTT_Status_strerror(MQTTStatus_t status)
Error code to string conversion for MQTT statuses.
Definition: core_mqtt.c:3329
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+

Error code to string conversion for MQTT statuses.

+
Parameters
+ + +
[in]statusThe status to convert to a string.
+
+
+
Returns
The string representation of the status.
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_subscribe_function.html b/latest/coreMQTT/mqtt_subscribe_function.html new file mode 100644 index 00000000..e7fe3cb9 --- /dev/null +++ b/latest/coreMQTT/mqtt_subscribe_function.html @@ -0,0 +1,167 @@ + + + + + + + +coreMQTT: MQTT_Subscribe + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_Subscribe
+
+
+
+
const MQTTSubscribeInfo_t * pSubscriptionList,
+
size_t subscriptionCount,
+
uint16_t packetId );
+
MQTTStatus_t MQTT_Subscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
Sends MQTT SUBSCRIBE for the given list of topic filters to the broker.
Definition: core_mqtt.c:2761
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+

Sends MQTT SUBSCRIBE for the given list of topic filters to the broker.

+
Parameters
+ + + + + +
[in]pContextInitialized MQTT context.
[in]pSubscriptionListArray of MQTT subscription info.
[in]subscriptionCountThe number of elements in @ pSubscriptionList array.
[in]packetIdPacket ID generated by MQTT_GetPacketId.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
uint16_t packetId;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
// This is assumed to be a list of filters we want to subscribe to.
+
const char * filters[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// Set each subscription.
+
for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )
+
{
+
subscriptionList[ i ].qos = MQTTQoS0;
+
// Each subscription needs a topic filter.
+
subscriptionList[ i ].pTopicFilter = filters[ i ];
+
subscriptionList[ i ].topicFilterLength = strlen( filters[ i ] );
+
}
+
+
// Obtain a new packet id for the subscription.
+
packetId = MQTT_GetPacketId( pContext );
+
+
status = MQTT_Subscribe( pContext, &subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// We must now call MQTT_ReceiveLoop() or MQTT_ProcessLoop() to receive the SUBACK.
+
// If the broker accepts the subscription we can now receive publishes
+
// on the requested topics.
+
}
+
uint16_t MQTT_GetPacketId(MQTTContext_t *pContext)
Get a packet ID that is valid according to the MQTT 3.1.1 spec.
Definition: core_mqtt.c:3172
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
@ MQTTQoS0
Definition: core_mqtt_serializer.h:110
+
MQTTQoS_t qos
Quality of Service for subscription.
Definition: core_mqtt_serializer.h:184
+
uint16_t topicFilterLength
Length of subscription topic filter.
Definition: core_mqtt_serializer.h:194
+
const char * pTopicFilter
Topic filter to subscribe to.
Definition: core_mqtt_serializer.h:189
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_timeouts.html b/latest/coreMQTT/mqtt_timeouts.html new file mode 100644 index 00000000..484f32dc --- /dev/null +++ b/latest/coreMQTT/mqtt_timeouts.html @@ -0,0 +1,159 @@ + + + + + + + +coreMQTT: Timeouts in coreMQTT library + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Timeouts in coreMQTT library
+
+
+

Information about timeouts that coreMQTT library relies on.

+

The coreMQTT library relies on timeouts to handle MQTT keep-alive mechanism and Transport Send and Receive operations. Timeouts must be configured correctly for ensuring the expected behavior of the application using the coreMQTT library. The timeouts and the recommended configurations are listed below.

    +
  1. Transport Send and Receive timeouts
  2. +
  3. MQTT Keep Alive interval
  4. +
  5. MQTT Ping Response timeout
  6. +
  7. MQTT Receive Polling timeout
  8. +
  9. MQTT Send timeout
  10. +
  11. Timeouts for MQTT_ProcessLoop and MQTT_ReceiveLoop APIs
  12. +
  13. Timeout for MQTT_Connect
  14. +
+

+Transport Send and Receive timeouts

+

These are the network send and read operation blocking timeouts used by the implementation of Transport Send and Transport Receive functions, respectively, that are supplied to the coreMQTT library. Transport Send and Receive timeouts must be configured by the application for the Transport interface implementation provided to the coreMQTT library. If it is essential to send more data than the size of the TCP buffer, then the Transport Send timeout can be set to a bigger value than that of cases in which size of the data to be sent is smaller than the TCP buffer, so as to efficiently wait for the TCP buffer to be available to copy the data from MQTT buffers.

+

We recommend using a relatively smaller value for these timeouts as compared to the MQTT Keep Alive interval, so as to make sure that an MQTT Control packet including an MQTT ping request packet can be sent to the Server even within the Keep Alive interval, even if the Transport functions block for the maximum time.

+
See also
Transport Interface
+

+MQTT Keep Alive interval

+

MQTT Keep Alive interval is the maximum time interval that is permitted to elapse between the point at which the MQTT Client finishes transmitting one Control Packet and the point it starts sending the next. If the Server does not receive a Control Packet from the Client within one and a half times the Keep Alive time period, it will disconnect the MQTT connection to the Client.

+

If MQTT_ProcessLoop function is used to manage keep alive in the application, the MQTT Keep Alive interval must be configured to be a value larger than that of the Transport Send and Receive timeouts. This is to make sure that a Control packet including an MQTT ping request packet can be sent to the Server even if the Transport functions block for the maximum time. MQTT Keep Alive interval can be configured by setting the keepAliveIntervalSec member of the MQTTContext_t structure.

+
See also
Keep-Alive
+

+MQTT Ping Response timeout

+

MQTT Ping Response timeout is the time to wait for a ping response to an MQTT ping request as part of the keep-alive mechanism in the MQTT Client. This timeout can be configured independent of the Transport timeouts unlike the MQTT Keep Alive interval, since this timeout only depends on the MQTT broker, the platform and the network latencies.

+

We recommend to choose a ping response timeout by experimenting with an MQTT application on a sample of devices and collecting the data of latency for each ping response from the broker after a ping request is sent. A timeout value can then be chosen based on the statistical measure suitable for the end application, such as 99th percentile or average.

+

MQTT Ping Response timeout can be set by defining the configuration MQTT_PINGRESP_TIMEOUT_MS.

+

+MQTT Receive Polling timeout

+

MQTT Receive Polling timeout is the maximum duration between non-empty network reads while receiving an MQTT packet via the MQTT_ProcessLoop or MQTT_ReceiveLoop API functions. This timeout represents the maximum polling duration that is allowed without any data reception from the network for the incoming packet.

+

It is important to note that having this timeout too short will result in MQTT being disconnected due to the possibility of partial data being received. If you have small TCP buffers and a high latency network, the optimum value for the timeout can be surprisingly long. In such cases, optimum value for the timeout can be better determined based on experimenting the MQTT applications with payloads bigger than the TCP buffer. If a retry is required for a Transport Receive even after hitting a timeout of Transport Receive without any data received, we recommend using a value larger than the Transport Receive timeout. If a dummy implementation of the MQTTGetCurrentTimeFunc_t timer function, that always returns 0, is used, then this timeout must be set to 0.

+

The MQTT Receive Polling timeout can be set by defining the configuration MQTT_RECV_POLLING_TIMEOUT_MS.

+

+MQTT Send timeout

+

MQTT Send timeout is the maximum duration allowed to send an MQTT packet over the transport interface.

+

It is important to note that having this timeout too short will result in MQTT being disconnected due to the possibility of partial data being sent. If you have small TCP buffers and a high latency network, the optimum value for the timeout can be surprisingly long. In such cases, optimum value for the timeout can be better determined based on experimenting the MQTT applications with payloads bigger than the TCP buffer. If a retry is required for a Transport Send even after hitting a timeout of Transport Send before any data could be sent to transport layer, we recommend using a value larger than the Transport Send timeout. If a dummy implementation of the MQTTGetCurrentTimeFunc_t timer function, that always returns 0, is used, then this timeout must be set to 0.

+

The MQTT Send timeout can be set by defining the configuration MQTT_SEND_TIMEOUT_MS.

+

+Timeouts for MQTT_ProcessLoop and MQTT_ReceiveLoop APIs

+

This timeout is passed as an argument to MQTT_ProcessLoop or MQTT_ReceiveLoop API functions. It is the minimum time that the receive loop in these API functions will run, unless an error occurs. These APIs may be blocked for more time than this timeout, since the APIs will attempt to send and receive MQTT packets to the network using the Transport implementation. The maximum time spent on Transport functions for send and receive depends on the Transport Send and Receive timeouts and the MQTT Receive Polling timeouts as explained in the descriptions of these timeouts above.

+

Passing a timeout value of 0 will run these APIs for a single iteration. The other timeouts mentioned thus far ensure you don't disconnect the MQTT just because the network is slow or buffers get full. They are necessary because coreMQTT has no 'memory' of being half way through a packet and will just error and disconnect if you don't give enough time for incoming or outgoing packet delivery. That means, especially in multi-threaded application, the process loop timeout can be zero.

+

MQTT_ProcessLoop API can be used to manage the MQTT keep-alive mechanism and if used, application must invoke this API faster than the MQTT Keep Alive interval. If a dummy MQTTGetCurrentTimeFunc_t was passed to MQTT_Init, then the keep-alive mechanism is not supported by the MQTT_ProcessLoop API; instead the MQTT_ReceiveLoop should be used.

+
See also
Runtime Timeouts passed to MQTT library
+

+Timeout for MQTT_Connect

+

This timeout is passed as an argument to MQTT_Connect. It is the maximum time to wait for an MQTT CONNACK packet. If this value is set to 0, then instead of a time-based loop, it will attempt to call the Transport Receive function up to a maximum number of retries, which is defined by MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT.

+

We recommend to choose a timeout for MQTT_Connect by experimenting with an MQTT application on a sample of devices and collecting the data of latency for each CONNACK packet received from the broker after an MQTT CONNECT packet is sent. A timeout value can then be chosen based on the statistical measure suitable for the end application, such as 99th percentile or average.

+
See also
Runtime Timeouts passed to MQTT library
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_transport_interface.html b/latest/coreMQTT/mqtt_transport_interface.html new file mode 100644 index 00000000..126fccbc --- /dev/null +++ b/latest/coreMQTT/mqtt_transport_interface.html @@ -0,0 +1,240 @@ + + + + + + + +coreMQTT: Transport Interface + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Transport Interface
+
+
+

The transport interface definition.

+

+Transport Interface Overview

+

The transport interface is a set of APIs that must be implemented using an external transport layer protocol. The transport interface is defined in transport_interface.h. This interface allows protocols like MQTT and HTTP to send and receive data over the transport layer. This interface does not handle connection and disconnection to the server of interest. The connection, disconnection, and other transport settings, like timeout and TLS setup, must be handled in the user application.
+

+

The functions that must be implemented are:
+

+

Each of the functions above take in an opaque context NetworkContext_t. The functions above and the context are also grouped together in the TransportInterface_t structure:
+
+

typedef struct TransportInterface
+
{
+ + + +
NetworkContext_t * pNetworkContext;
+ +
int32_t(* TransportRecv_t)(NetworkContext_t *pNetworkContext, void *pBuffer, size_t bytesToRecv)
Transport interface for receiving data on the network.
Definition: transport_interface.h:218
+
int32_t(* TransportSend_t)(NetworkContext_t *pNetworkContext, const void *pBuffer, size_t bytesToSend)
Transport interface for sending data over the network.
Definition: transport_interface.h:240
+
int32_t(* TransportWritev_t)(NetworkContext_t *pNetworkContext, TransportOutVector_t *pIoVec, size_t ioVecCount)
Transport interface function for "vectored" / scatter-gather based writes. This function is expected ...
Definition: transport_interface.h:288
+
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
+
The transport layer interface.
Definition: transport_interface.h:299
+


+

+

+Implementing the Transport Interface

+

The following steps give guidance on implementing the transport interface:

+
    +
  1. Implementing NetworkContext_t
    +

    +
    struct NetworkContext;
    +
    typedef struct NetworkContext NetworkContext_t;
    +

    + NetworkContext_t is the incomplete type struct NetworkContext. The implemented struct NetworkContext must contain all of the information that is needed to receive and send data with the TransportRecv_t and the TransportSend_t implementations.
    + In the case of TLS over TCP, struct NetworkContext is typically implemented with the TCP socket context and a TLS context.
    +
    + Example code:
    struct NetworkContext
    +
    {
    +
    struct MyTCPSocketContext tcpSocketContext;
    +
    struct MyTLSContext tlsContext;
    +
    };
    +

    +
  2. +
  3. Implementing TransportRecv_t
    +

    +
    typedef int32_t ( * TransportRecv_t )( NetworkContext_t * pNetworkContext,
    +
    void * pBuffer,
    +
    size_t bytesToRecv );
    +

    + This function is expected to populate a buffer, with bytes received from the transport, and return the number of bytes placed in the buffer. In the case of TLS over TCP, TransportRecv_t is typically implemented by calling the TLS layer function to receive data. In case of plaintext TCP without TLS, it is typically implemented by calling the TCP layer receive function. TransportRecv_t may be invoked multiple times by the protocol library, if fewer bytes than were requested to receive are returned.
    +
    + Example code:
    int32_t myNetworkRecvImplementation( NetworkContext_t * pNetworkContext,
    +
    void * pBuffer,
    +
    size_t bytesToRecv )
    +
    {
    +
    int32_t bytesReceived = 0;
    +
    bool callTlsRecvFunc = true;
    +
    +
    // For a single byte read request, check if data is available on the network.
    +
    if( bytesToRecv == 1 )
    +
    {
    +
    // If no data is available on the network, do not call TLSRecv
    +
    // to avoid blocking for socket timeout.
    +
    if( TLSRecvCount( pNetworkContext->tlsContext ) == 0 )
    +
    {
    +
    callTlsRecvFunc = false;
    +
    }
    +
    }
    +
    +
    if( callTlsRecvFunc == true )
    +
    {
    +
    bytesReceived = TLSRecv( pNetworkContext->tlsContext,
    +
    pBuffer,
    +
    bytesToRecv,
    +
    MY_SOCKET_TIMEOUT );
    +
    if( bytesReceived < 0 )
    +
    {
    +
    // If the error code represents a timeout, then the return
    +
    // code should be translated to zero so that the caller
    +
    // can retry the read operation.
    +
    if( bytesReceived == MY_SOCKET_ERROR_TIMEOUT )
    +
    {
    +
    bytesReceived = 0;
    +
    }
    +
    }
    +
    // Handle other cases.
    +
    }
    +
    return bytesReceived;
    +
    }
    +

    +
  4. +
  5. Implementing TransportSend_t
    +

    +
    typedef int32_t ( * TransportSend_t )( NetworkContext_t * pNetworkContext,
    +
    const void * pBuffer,
    +
    size_t bytesToSend );
    +

    + This function is expected to send the bytes, in the given buffer over the transport, and return the number of bytes sent. In the case of TLS over TCP, TransportSend_t is typically implemented by calling the TLS layer function to send data. In case of plaintext TCP without TLS, it is typically implemented by calling the TCP layer send function. TransportSend_t may be invoked multiple times by the protocol library, if fewer bytes than were requested to send are returned.
    +
    + Example code:
    int32_t myNetworkSendImplementation( NetworkContext_t * pNetworkContext,
    +
    const void * pBuffer,
    +
    size_t bytesToSend )
    +
    {
    +
    int32_t bytesSent = 0;
    +
    bytesSent = TLSSend( pNetworkContext->tlsContext,
    +
    pBuffer,
    +
    bytesToSend,
    +
    MY_SOCKET_TIMEOUT );
    +
    +
    // If underlying TCP buffer is full, set the return value to zero
    +
    // so that caller can retry the send operation.
    +
    if( bytesSent == MY_SOCKET_ERROR_BUFFER_FULL )
    +
    {
    +
    bytesSent = 0;
    +
    }
    +
    else if( bytesSent < 0 )
    +
    {
    +
    // Handle socket error.
    +
    }
    +
    // Handle other cases.
    +
    +
    return bytesSent;
    +
    }
    +
  6. +
+
+
+
+ + + + diff --git a/latest/coreMQTT/mqtt_unsubscribe_function.html b/latest/coreMQTT/mqtt_unsubscribe_function.html new file mode 100644 index 00000000..d98acea6 --- /dev/null +++ b/latest/coreMQTT/mqtt_unsubscribe_function.html @@ -0,0 +1,164 @@ + + + + + + + +coreMQTT: MQTT_Unsubscribe + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_Unsubscribe
+
+
+
+
const MQTTSubscribeInfo_t * pSubscriptionList,
+
size_t subscriptionCount,
+
uint16_t packetId );
+
MQTTStatus_t MQTT_Unsubscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
Sends MQTT UNSUBSCRIBE for the given list of topic filters to the broker.
Definition: core_mqtt.c:3000
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+

Sends MQTT UNSUBSCRIBE for the given list of topic filters to the broker.

+
Parameters
+ + + + + +
[in]pContextInitialized MQTT context.
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t unsubscribeList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
uint16_t packetId;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
// This is assumed to be a list of filters we want to unsubscribe from.
+
const char * filters[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// Set information for each unsubscribe request.
+
for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )
+
{
+
unsubscribeList[ i ].pTopicFilter = filters[ i ];
+
unsubscribeList[ i ].topicFilterLength = strlen( filters[ i ] );
+
+
// The QoS field of MQTT_SubscribeInfo_t is unused for unsubscribing.
+
}
+
+
// Obtain a new packet id for the unsubscribe request.
+
packetId = MQTT_GetPacketId( pContext );
+
+
status = MQTT_Unsubscribe( pContext, &unsubscribeList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// We must now call MQTT_ReceiveLoop() or MQTT_ProcessLoop() to receive the UNSUBACK.
+
// After this the broker should no longer send publishes for these topics.
+
}
+
uint16_t MQTT_GetPacketId(MQTTContext_t *pContext)
Get a packet ID that is valid according to the MQTT 3.1.1 spec.
Definition: core_mqtt.c:3172
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
uint16_t topicFilterLength
Length of subscription topic filter.
Definition: core_mqtt_serializer.h:194
+
const char * pTopicFilter
Topic filter to subscribe to.
Definition: core_mqtt_serializer.h:189
+
+
+
+ + + + diff --git a/latest/coreMQTT/nav_f.png b/latest/coreMQTT/nav_f.png new file mode 100644 index 0000000000000000000000000000000000000000..72a58a529ed3a9ed6aa0c51a79cf207e026deee2 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI`!2~2XGqLUlQVE_ejv*C{Z|{2ZH7M}7UYxc) zn!W8uqtnIQ>_z8U literal 0 HcmV?d00001 diff --git a/latest/coreMQTT/nav_fd.png b/latest/coreMQTT/nav_fd.png new file mode 100644 index 0000000000000000000000000000000000000000..032fbdd4c54f54fa9a2e6423b94ef4b2ebdfaceb GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI`!2~2XGqLUlQU#tajv*C{Z|C~*H7f|XvG1G8 zt7aS*L7xwMeS}!z6R#{C5tIw-s~AJ==F^i}x3XyJseHR@yF& zerFf(Zf;Dd{+(0lDIROL@Sj-Ju2JQ8&-n%4%q?>|^bShc&lR?}7HeMo@BDl5N(aHY Uj$gdr1MOz;boFyt=akR{0D!zeaR2}S literal 0 HcmV?d00001 diff --git a/latest/coreMQTT/nav_g.png b/latest/coreMQTT/nav_g.png new file mode 100644 index 0000000000000000000000000000000000000000..2093a237a94f6c83e19ec6e5fd42f7ddabdafa81 GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^j6lrB!3HFm1ilyoDK$?Q$B+ufw|5PB85lU25BhtE tr?otc=hd~V+ws&_A@j8Fiv!KF$B+ufw|5=67#uj90@pIL wZ=Q8~_Ju`#59=RjDrmm`tMD@M=!-l18IR?&vFVdQ&MBb@0HFXL6W-eg#Jd_@e6*DPn)w;=|1H}Zvm9l6xXXB%>yL=NQU;mg M>FVdQ&MBb@0Bdt1Qvd(} literal 0 HcmV?d00001 diff --git a/latest/coreMQTT/navtree.css b/latest/coreMQTT/navtree.css new file mode 100644 index 00000000..c8a7766a --- /dev/null +++ b/latest/coreMQTT/navtree.css @@ -0,0 +1,150 @@ +#nav-tree .children_ul { + margin:0; + padding:4px; +} + +#nav-tree ul { + list-style:none outside none; + margin:0px; + padding:0px; +} + +#nav-tree li { + white-space:nowrap; + margin:0px; + padding:0px; +} + +#nav-tree .plus { + margin:0px; +} + +#nav-tree .selected { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + color: var(--nav-text-active-color); + text-shadow: var(--nav-text-active-shadow); +} + +#nav-tree .selected .arrow { + color: var(--nav-arrow-selected-color); + text-shadow: none; +} + +#nav-tree img { + margin:0px; + padding:0px; + border:0px; + vertical-align: middle; +} + +#nav-tree a { + text-decoration:none; + padding:0px; + margin:0px; + outline:none; +} + +#nav-tree .label { + margin:0px; + padding:0px; + font: 12px var(--font-family-nav); +} + +#nav-tree .label a { + padding:2px; +} + +#nav-tree .selected a { + text-decoration:none; + color:var(--nav-text-active-color); +} + +#nav-tree .children_ul { + margin:0px; + padding:0px; +} + +#nav-tree .item { + margin:0px; + padding:0px; +} + +#nav-tree { + padding: 0px 0px; + font-size:14px; + overflow:auto; +} + +#doc-content { + overflow:auto; + display:block; + padding:0px; + margin:0px; + -webkit-overflow-scrolling : touch; /* iOS 5+ */ +} + +#side-nav { + padding:0 6px 0 0; + margin: 0px; + display:block; + position: absolute; + left: 0px; + width: $width; + overflow : hidden; +} + +.ui-resizable .ui-resizable-handle { + display:block; +} + +.ui-resizable-e { + background-image:var(--nav-splitbar-image); + background-size:100%; + background-repeat:repeat-y; + background-attachment: scroll; + cursor:ew-resize; + height:100%; + right:0; + top:0; + width:6px; +} + +.ui-resizable-handle { + display:none; + font-size:0.1px; + position:absolute; + z-index:1; +} + +#nav-tree-contents { + margin: 6px 0px 0px 0px; +} + +#nav-tree { + background-repeat:repeat-x; + background-color: var(--nav-background-color); + -webkit-overflow-scrolling : touch; /* iOS 5+ */ +} + +#nav-sync { + position:absolute; + top:5px; + right:24px; + z-index:0; +} + +#nav-sync img { + opacity:0.3; +} + +#nav-sync img:hover { + opacity:0.9; +} + +@media print +{ + #nav-tree { display: none; } + div.ui-resizable-handle { display: none; position: relative; } +} + diff --git a/latest/coreMQTT/navtree.js b/latest/coreMQTT/navtree.js new file mode 100644 index 00000000..27983687 --- /dev/null +++ b/latest/coreMQTT/navtree.js @@ -0,0 +1,549 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +var navTreeSubIndices = new Array(); +var arrowDown = '▼'; +var arrowRight = '►'; + +function getData(varName) +{ + var i = varName.lastIndexOf('/'); + var n = i>=0 ? varName.substring(i+1) : varName; + return eval(n.replace(/\-/g,'_')); +} + +function stripPath(uri) +{ + return uri.substring(uri.lastIndexOf('/')+1); +} + +function stripPath2(uri) +{ + var i = uri.lastIndexOf('/'); + var s = uri.substring(i+1); + var m = uri.substring(0,i+1).match(/\/d\w\/d\w\w\/$/); + return m ? uri.substring(i-6) : s; +} + +function hashValue() +{ + return $(location).attr('hash').substring(1).replace(/[^\w\-]/g,''); +} + +function hashUrl() +{ + return '#'+hashValue(); +} + +function pathName() +{ + return $(location).attr('pathname').replace(/[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]/g, ''); +} + +function localStorageSupported() +{ + try { + return 'localStorage' in window && window['localStorage'] !== null && window.localStorage.getItem; + } + catch(e) { + return false; + } +} + +function storeLink(link) +{ + if (!$("#nav-sync").hasClass('sync') && localStorageSupported()) { + window.localStorage.setItem('navpath',link); + } +} + +function deleteLink() +{ + if (localStorageSupported()) { + window.localStorage.setItem('navpath',''); + } +} + +function cachedLink() +{ + if (localStorageSupported()) { + return window.localStorage.getItem('navpath'); + } else { + return ''; + } +} + +function getScript(scriptName,func,show) +{ + var head = document.getElementsByTagName("head")[0]; + var script = document.createElement('script'); + script.id = scriptName; + script.type = 'text/javascript'; + script.onload = func; + script.src = scriptName+'.js'; + head.appendChild(script); +} + +function createIndent(o,domNode,node,level) +{ + var level=-1; + var n = node; + while (n.parentNode) { level++; n=n.parentNode; } + if (node.childrenData) { + var imgNode = document.createElement("span"); + imgNode.className = 'arrow'; + imgNode.style.paddingLeft=(16*level).toString()+'px'; + imgNode.innerHTML=arrowRight; + node.plus_img = imgNode; + node.expandToggle = document.createElement("a"); + node.expandToggle.href = "javascript:void(0)"; + node.expandToggle.onclick = function() { + if (node.expanded) { + $(node.getChildrenUL()).slideUp("fast"); + node.plus_img.innerHTML=arrowRight; + node.expanded = false; + } else { + expandNode(o, node, false, false); + } + } + node.expandToggle.appendChild(imgNode); + domNode.appendChild(node.expandToggle); + } else { + var span = document.createElement("span"); + span.className = 'arrow'; + span.style.width = 16*(level+1)+'px'; + span.innerHTML = ' '; + domNode.appendChild(span); + } +} + +var animationInProgress = false; + +function gotoAnchor(anchor,aname,updateLocation) +{ + var pos, docContent = $('#doc-content'); + var ancParent = $(anchor.parent()); + if (ancParent.hasClass('memItemLeft') || + ancParent.hasClass('memtitle') || + ancParent.hasClass('fieldname') || + ancParent.hasClass('fieldtype') || + ancParent.is(':header')) + { + pos = ancParent.position().top; + } else if (anchor.position()) { + pos = anchor.position().top; + } + if (pos) { + var dist = Math.abs(Math.min( + pos-docContent.offset().top, + docContent[0].scrollHeight- + docContent.height()-docContent.scrollTop())); + animationInProgress=true; + docContent.animate({ + scrollTop: pos + docContent.scrollTop() - docContent.offset().top + },Math.max(50,Math.min(500,dist)),function(){ + if (updateLocation) window.location.href=aname; + animationInProgress=false; + }); + } +} + +function newNode(o, po, text, link, childrenData, lastNode) +{ + var node = new Object(); + node.children = Array(); + node.childrenData = childrenData; + node.depth = po.depth + 1; + node.relpath = po.relpath; + node.isLast = lastNode; + + node.li = document.createElement("li"); + po.getChildrenUL().appendChild(node.li); + node.parentNode = po; + + node.itemDiv = document.createElement("div"); + node.itemDiv.className = "item"; + + node.labelSpan = document.createElement("span"); + node.labelSpan.className = "label"; + + createIndent(o,node.itemDiv,node,0); + node.itemDiv.appendChild(node.labelSpan); + node.li.appendChild(node.itemDiv); + + var a = document.createElement("a"); + node.labelSpan.appendChild(a); + node.label = document.createTextNode(text); + node.expanded = false; + a.appendChild(node.label); + if (link) { + var url; + if (link.substring(0,1)=='^') { + url = link.substring(1); + link = url; + } else { + url = node.relpath+link; + } + a.className = stripPath(link.replace('#',':')); + if (link.indexOf('#')!=-1) { + var aname = '#'+link.split('#')[1]; + var srcPage = stripPath(pathName()); + var targetPage = stripPath(link.split('#')[0]); + a.href = srcPage!=targetPage ? url : "javascript:void(0)"; + a.onclick = function(){ + storeLink(link); + if (!$(a).parent().parent().hasClass('selected')) + { + $('.item').removeClass('selected'); + $('.item').removeAttr('id'); + $(a).parent().parent().addClass('selected'); + $(a).parent().parent().attr('id','selected'); + } + var anchor = $(aname); + gotoAnchor(anchor,aname,true); + }; + } else { + a.href = url; + a.onclick = function() { storeLink(link); } + } + } else { + if (childrenData != null) + { + a.className = "nolink"; + a.href = "javascript:void(0)"; + a.onclick = node.expandToggle.onclick; + } + } + + node.childrenUL = null; + node.getChildrenUL = function() { + if (!node.childrenUL) { + node.childrenUL = document.createElement("ul"); + node.childrenUL.className = "children_ul"; + node.childrenUL.style.display = "none"; + node.li.appendChild(node.childrenUL); + } + return node.childrenUL; + }; + + return node; +} + +function showRoot() +{ + var headerHeight = $("#top").height(); + var footerHeight = $("#nav-path").height(); + var windowHeight = $(window).height() - headerHeight - footerHeight; + (function (){ // retry until we can scroll to the selected item + try { + var navtree=$('#nav-tree'); + navtree.scrollTo('#selected',100,{offset:-windowHeight/2}); + } catch (err) { + setTimeout(arguments.callee, 0); + } + })(); +} + +function expandNode(o, node, imm, showRoot) +{ + if (node.childrenData && !node.expanded) { + if (typeof(node.childrenData)==='string') { + var varName = node.childrenData; + getScript(node.relpath+varName,function(){ + node.childrenData = getData(varName); + expandNode(o, node, imm, showRoot); + }, showRoot); + } else { + if (!node.childrenVisited) { + getNode(o, node); + } + $(node.getChildrenUL()).slideDown("fast"); + node.plus_img.innerHTML = arrowDown; + node.expanded = true; + } + } +} + +function glowEffect(n,duration) +{ + n.addClass('glow').delay(duration).queue(function(next){ + $(this).removeClass('glow');next(); + }); +} + +function highlightAnchor() +{ + var aname = hashUrl(); + var anchor = $(aname); + if (anchor.parent().attr('class')=='memItemLeft'){ + var rows = $('.memberdecls tr[class$="'+hashValue()+'"]'); + glowEffect(rows.children(),300); // member without details + } else if (anchor.parent().attr('class')=='fieldname'){ + glowEffect(anchor.parent().parent(),1000); // enum value + } else if (anchor.parent().attr('class')=='fieldtype'){ + glowEffect(anchor.parent().parent(),1000); // struct field + } else if (anchor.parent().is(":header")) { + glowEffect(anchor.parent(),1000); // section header + } else { + glowEffect(anchor.next(),1000); // normal member + } +} + +function selectAndHighlight(hash,n) +{ + var a; + if (hash) { + var link=stripPath(pathName())+':'+hash.substring(1); + a=$('.item a[class$="'+link+'"]'); + } + if (a && a.length) { + a.parent().parent().addClass('selected'); + a.parent().parent().attr('id','selected'); + highlightAnchor(); + } else if (n) { + $(n.itemDiv).addClass('selected'); + $(n.itemDiv).attr('id','selected'); + } + var topOffset=5; + if (typeof page_layout!=='undefined' && page_layout==1) { + topOffset+=$('#top').outerHeight(); + } + if ($('#nav-tree-contents .item:first').hasClass('selected')) { + topOffset+=25; + } + $('#nav-sync').css('top',topOffset+'px'); + showRoot(); +} + +function showNode(o, node, index, hash) +{ + if (node && node.childrenData) { + if (typeof(node.childrenData)==='string') { + var varName = node.childrenData; + getScript(node.relpath+varName,function(){ + node.childrenData = getData(varName); + showNode(o,node,index,hash); + },true); + } else { + if (!node.childrenVisited) { + getNode(o, node); + } + $(node.getChildrenUL()).css({'display':'block'}); + node.plus_img.innerHTML = arrowDown; + node.expanded = true; + var n = node.children[o.breadcrumbs[index]]; + if (index+11) hash = '#'+parts[1].replace(/[^\w\-]/g,''); + else hash=''; + } + if (hash.match(/^#l\d+$/)) { + var anchor=$('a[name='+hash.substring(1)+']'); + glowEffect(anchor.parent(),1000); // line number + hash=''; // strip line number anchors + } + var url=root+hash; + var i=-1; + while (NAVTREEINDEX[i+1]<=url) i++; + if (i==-1) { i=0; root=NAVTREE[0][1]; } // fallback: show index + if (navTreeSubIndices[i]) { + gotoNode(o,i,root,hash,relpath) + } else { + getScript(relpath+'navtreeindex'+i,function(){ + navTreeSubIndices[i] = eval('NAVTREEINDEX'+i); + if (navTreeSubIndices[i]) { + gotoNode(o,i,root,hash,relpath); + } + },true); + } +} + +function showSyncOff(n,relpath) +{ + n.html(''); +} + +function showSyncOn(n,relpath) +{ + n.html(''); +} + +function toggleSyncButton(relpath) +{ + var navSync = $('#nav-sync'); + if (navSync.hasClass('sync')) { + navSync.removeClass('sync'); + showSyncOff(navSync,relpath); + storeLink(stripPath2(pathName())+hashUrl()); + } else { + navSync.addClass('sync'); + showSyncOn(navSync,relpath); + deleteLink(); + } +} + +var loadTriggered = false; +var readyTriggered = false; +var loadObject,loadToRoot,loadUrl,loadRelPath; + +$(window).on('load',function(){ + if (readyTriggered) { // ready first + navTo(loadObject,loadToRoot,loadUrl,loadRelPath); + showRoot(); + } + loadTriggered=true; +}); + +function initNavTree(toroot,relpath) +{ + var o = new Object(); + o.toroot = toroot; + o.node = new Object(); + o.node.li = document.getElementById("nav-tree-contents"); + o.node.childrenData = NAVTREE; + o.node.children = new Array(); + o.node.childrenUL = document.createElement("ul"); + o.node.getChildrenUL = function() { return o.node.childrenUL; }; + o.node.li.appendChild(o.node.childrenUL); + o.node.depth = 0; + o.node.relpath = relpath; + o.node.expanded = false; + o.node.isLast = true; + o.node.plus_img = document.createElement("span"); + o.node.plus_img.className = 'arrow'; + o.node.plus_img.innerHTML = arrowRight; + + if (localStorageSupported()) { + var navSync = $('#nav-sync'); + if (cachedLink()) { + showSyncOff(navSync,relpath); + navSync.removeClass('sync'); + } else { + showSyncOn(navSync,relpath); + } + navSync.click(function(){ toggleSyncButton(relpath); }); + } + + if (loadTriggered) { // load before ready + navTo(o,toroot,hashUrl(),relpath); + showRoot(); + } else { // ready before load + loadObject = o; + loadToRoot = toroot; + loadUrl = hashUrl(); + loadRelPath = relpath; + readyTriggered=true; + } + + $(window).bind('hashchange', function(){ + if (window.location.hash && window.location.hash.length>1){ + var a; + if ($(location).attr('hash')){ + var clslink=stripPath(pathName())+':'+hashValue(); + a=$('.item a[class$="'+clslink.replace(/1|%O$WD@{VPM$7~Ar*{o?;hlAFyLXmaDC0y znK1_#cQqJWPES%4Uujug^TE?jMft$}Eq^WaR~)%f)vSNs&gek&x%A9X9sM + + + + + + +coreMQTT: Related Pages + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Related Pages
+
+ +
+ + + + diff --git a/latest/coreMQTT/resize.js b/latest/coreMQTT/resize.js new file mode 100644 index 00000000..aaeb6fc0 --- /dev/null +++ b/latest/coreMQTT/resize.js @@ -0,0 +1,155 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +var once=1; +function initResizable() +{ + var cookie_namespace = 'doxygen'; + var sidenav,navtree,content,header,barWidth=6,desktop_vp=768,titleHeight; + + function readSetting(cookie) + { + if (window.chrome) { + var val = localStorage.getItem(cookie_namespace+'_width'); + if (val) return val; + } else { + var myCookie = cookie_namespace+"_"+cookie+"="; + if (document.cookie) { + var index = document.cookie.indexOf(myCookie); + if (index != -1) { + var valStart = index + myCookie.length; + var valEnd = document.cookie.indexOf(";", valStart); + if (valEnd == -1) { + valEnd = document.cookie.length; + } + var val = document.cookie.substring(valStart, valEnd); + return val; + } + } + } + return 250; + } + + function writeSetting(cookie, val) + { + if (window.chrome) { + localStorage.setItem(cookie_namespace+"_width",val); + } else { + var date = new Date(); + date.setTime(date.getTime()+(10*365*24*60*60*1000)); // default expiration is one week + expiration = date.toGMTString(); + document.cookie = cookie_namespace + "_" + cookie + "=" + val + "; SameSite=Lax; expires=" + expiration+"; path=/"; + } + } + + function resizeWidth() + { + var windowWidth = $(window).width() + "px"; + var sidenavWidth = $(sidenav).outerWidth(); + content.css({marginLeft:parseInt(sidenavWidth)+"px"}); + if (typeof page_layout!=='undefined' && page_layout==1) { + footer.css({marginLeft:parseInt(sidenavWidth)+"px"}); + } + writeSetting('width',sidenavWidth-barWidth); + } + + function restoreWidth(navWidth) + { + var windowWidth = $(window).width() + "px"; + content.css({marginLeft:parseInt(navWidth)+barWidth+"px"}); + if (typeof page_layout!=='undefined' && page_layout==1) { + footer.css({marginLeft:parseInt(navWidth)+barWidth+"px"}); + } + sidenav.css({width:navWidth + "px"}); + } + + function resizeHeight() + { + var headerHeight = header.outerHeight(); + var footerHeight = footer.outerHeight(); + var windowHeight = $(window).height(); + var contentHeight,navtreeHeight,sideNavHeight; + if (typeof page_layout==='undefined' || page_layout==0) { /* DISABLE_INDEX=NO */ + contentHeight = windowHeight - headerHeight - footerHeight; + navtreeHeight = contentHeight; + sideNavHeight = contentHeight; + } else if (page_layout==1) { /* DISABLE_INDEX=YES */ + contentHeight = windowHeight - footerHeight; + navtreeHeight = windowHeight - headerHeight; + sideNavHeight = windowHeight; + } + content.css({height:contentHeight + "px"}); + navtree.css({height:navtreeHeight + "px"}); + sidenav.css({height:sideNavHeight + "px"}); + if (location.hash.slice(1)) { + (document.getElementById(location.hash.slice(1))||document.body).scrollIntoView(); + } + } + + function collapseExpand() + { + var newWidth; + if (sidenav.width()>0) { + newWidth=0; + } + else { + var width = readSetting('width'); + newWidth = (width>250 && width<$(window).width()) ? width : 250; + } + restoreWidth(newWidth); + var sidenavWidth = $(sidenav).outerWidth(); + writeSetting('width',sidenavWidth-barWidth); + } + + header = $("#top"); + sidenav = $("#side-nav"); + content = $("#doc-content"); + navtree = $("#nav-tree"); + footer = $("#nav-path"); + $(".side-nav-resizable").resizable({resize: function(e, ui) { resizeWidth(); } }); + $(sidenav).resizable({ minWidth: 0 }); + $(window).resize(function() { resizeHeight(); }); + var device = navigator.userAgent.toLowerCase(); + var touch_device = device.match(/(iphone|ipod|ipad|android)/); + if (touch_device) { /* wider split bar for touch only devices */ + $(sidenav).css({ paddingRight:'20px' }); + $('.ui-resizable-e').css({ width:'20px' }); + $('#nav-sync').css({ right:'34px' }); + barWidth=20; + } + var width = readSetting('width'); + if (width) { restoreWidth(width); } else { resizeWidth(); } + resizeHeight(); + var url = location.href; + var i=url.indexOf("#"); + if (i>=0) window.location.hash=url.substr(i); + var _preventDefault = function(evt) { evt.preventDefault(); }; + $("#splitbar").bind("dragstart", _preventDefault).bind("selectstart", _preventDefault); + if (once) { + $(".ui-resizable-handle").dblclick(collapseExpand); + once=0 + } + $(window).on('load',resizeHeight); +} +/* @license-end */ diff --git a/latest/coreMQTT/search/all_0.js b/latest/coreMQTT/search/all_0.js new file mode 100644 index 00000000..4e077c9b --- /dev/null +++ b/latest/coreMQTT/search/all_0.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['addencodedstringtovector_0',['addEncodedStringToVector',['../core__mqtt_8c.html#a35952c4a02872c18702e7fbbdb1c467f',1,'core_mqtt.c']]], + ['addrecord_1',['addRecord',['../core__mqtt__state_8c.html#a5d0ffdfde0c38a1cc1d4e3f4750a8cc4',1,'core_mqtt_state.c']]], + ['appcallback_2',['appCallback',['../struct_m_q_t_t_context__t.html#a73bd9259db9c3a9b84518cbf928ed91f',1,'MQTTContext_t']]] +]; diff --git a/latest/coreMQTT/search/all_1.js b/latest/coreMQTT/search/all_1.js new file mode 100644 index 00000000..482cc48a --- /dev/null +++ b/latest/coreMQTT/search/all_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['basic_20types_0',['Basic Types',['../group__mqtt__basic__types.html',1,'']]] +]; diff --git a/latest/coreMQTT/search/all_10.js b/latest/coreMQTT/search/all_10.js new file mode 100644 index 00000000..ba3adad2 --- /dev/null +++ b/latest/coreMQTT/search/all_10.js @@ -0,0 +1,12 @@ +var searchData= +[ + ['readsubackstatus_0',['readSubackStatus',['../core__mqtt__serializer_8c.html#a02cace9415c300f4dd3394bf1eee0787',1,'core_mqtt_serializer.c']]], + ['receiveconnack_1',['receiveConnack',['../core__mqtt_8c.html#aa3c5d4f6154122cedcce9508ea7d1dce',1,'core_mqtt.c']]], + ['receivepacket_2',['receivePacket',['../core__mqtt_8c.html#aa674664c166b58a5b6630961d8760d3a',1,'core_mqtt.c']]], + ['receivesingleiteration_3',['receiveSingleIteration',['../core__mqtt_8c.html#a14d3be6806a945c14c0529daa1714e10',1,'core_mqtt.c']]], + ['recv_4',['recv',['../struct_transport_interface__t.html#a7c34e9b865e2a509306f09c7dfa3699e',1,'TransportInterface_t']]], + ['recvexact_5',['recvExact',['../core__mqtt_8c.html#a509d9dd1ede2bc000035d8f9926a473c',1,'core_mqtt.c']]], + ['remaininglength_6',['remainingLength',['../struct_m_q_t_t_packet_info__t.html#a7c85becf08de0ec9776dd4be1fcc4bf8',1,'MQTTPacketInfo_t']]], + ['remaininglengthencodedsize_7',['remainingLengthEncodedSize',['../core__mqtt__serializer_8c.html#aeead0813fa045d754e3d6ec964d0686e',1,'core_mqtt_serializer.c']]], + ['retain_8',['retain',['../struct_m_q_t_t_publish_info__t.html#a343b0af89c46a900db4aa5c775a0975a',1,'MQTTPublishInfo_t']]] +]; diff --git a/latest/coreMQTT/search/all_11.js b/latest/coreMQTT/search/all_11.js new file mode 100644 index 00000000..2760bd6f --- /dev/null +++ b/latest/coreMQTT/search/all_11.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['send_0',['send',['../struct_transport_interface__t.html#a01cd9935e9a5266ca196243a0054d489',1,'TransportInterface_t']]], + ['sendbuffer_1',['sendBuffer',['../core__mqtt_8c.html#a7f4f9871c75f8f987e3c86ae910bd982',1,'core_mqtt.c']]], + ['sendconnectwithoutcopy_2',['sendConnectWithoutCopy',['../core__mqtt_8c.html#a3c6935ecef4879b9aeee05ffb0f0a9cb',1,'core_mqtt.c']]], + ['sendmessagevector_3',['sendMessageVector',['../core__mqtt_8c.html#a39f478d2bb0366a5f14bfa90316d8d26',1,'core_mqtt.c']]], + ['sendpublishacks_4',['sendPublishAcks',['../core__mqtt_8c.html#ab4b719d2f726b049c279dcb37fcba840',1,'core_mqtt.c']]], + ['sendpublishwithoutcopy_5',['sendPublishWithoutCopy',['../core__mqtt_8c.html#aaaca64a926603116f5dfec4a65f28283',1,'core_mqtt.c']]], + ['sendsubscribewithoutcopy_6',['sendSubscribeWithoutCopy',['../core__mqtt_8c.html#a86259fe46a81f7981a7b43b677ab896d',1,'core_mqtt.c']]], + ['sendunsubscribewithoutcopy_7',['sendUnsubscribeWithoutCopy',['../core__mqtt_8c.html#a5fc0209190ce8ce635050195689306e2',1,'core_mqtt.c']]], + ['serializeconnectpacket_8',['serializeConnectPacket',['../core__mqtt__serializer_8c.html#a95bf697a3b1f86950e5c199d9cf3a185',1,'core_mqtt_serializer.c']]], + ['serializepublishcommon_9',['serializePublishCommon',['../core__mqtt__serializer_8c.html#a6b4138d990e2c8fbedbe28683c0fa83a',1,'core_mqtt_serializer.c']]], + ['size_10',['size',['../struct_m_q_t_t_fixed_buffer__t.html#a0b0b6a93cc62751ebeb03095d5431636',1,'MQTTFixedBuffer_t']]], + ['stateselect_11',['stateSelect',['../core__mqtt__state_8c.html#adfc09b0c75d5de09cd73650f944699c0',1,'core_mqtt_state.c']]] +]; diff --git a/latest/coreMQTT/search/all_12.js b/latest/coreMQTT/search/all_12.js new file mode 100644 index 00000000..3a47c51b --- /dev/null +++ b/latest/coreMQTT/search/all_12.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['timeouts_20in_20coremqtt_20library_0',['Timeouts in coreMQTT library',['../mqtt_timeouts.html',1,'']]], + ['topicfilterlength_1',['topicFilterLength',['../struct_m_q_t_t_subscribe_info__t.html#a6972f8e036f8bde9b1f23a2aacb61382',1,'MQTTSubscribeInfo_t']]], + ['topicnamelength_2',['topicNameLength',['../struct_m_q_t_t_publish_info__t.html#a6161c792d20cc7cf8284c1b71ea1145f',1,'MQTTPublishInfo_t']]], + ['transport_20interface_3',['Transport Interface',['../mqtt_transport_interface.html',1,'']]], + ['transport_5finterface_2eh_4',['transport_interface.h',['../transport__interface_8h.html',1,'']]], + ['transportinterface_5',['transportInterface',['../struct_m_q_t_t_context__t.html#a87ab9d61e7711325c2c85ce3ce63386a',1,'MQTTContext_t']]], + ['transportinterface_5ft_6',['TransportInterface_t',['../struct_transport_interface__t.html',1,'']]], + ['transportoutvector_5ft_7',['TransportOutVector_t',['../struct_transport_out_vector__t.html',1,'']]], + ['transportrecv_5ft_8',['TransportRecv_t',['../group__mqtt__callback__types.html#ga227df31d6daf07e5d833537c12130167',1,'transport_interface.h']]], + ['transportsend_5ft_9',['TransportSend_t',['../group__mqtt__callback__types.html#ga2a39853ff952edd715ab07b33ab2a7c5',1,'transport_interface.h']]], + ['transportwritev_5ft_10',['TransportWritev_t',['../group__mqtt__callback__types.html#ga47e779557b0c2db95949ef9526861dfb',1,'transport_interface.h']]], + ['type_11',['type',['../struct_m_q_t_t_packet_info__t.html#a7fef40548c1aa0f0e7f812a6a7243758',1,'MQTTPacketInfo_t']]] +]; diff --git a/latest/coreMQTT/search/all_13.js b/latest/coreMQTT/search/all_13.js new file mode 100644 index 00000000..f992eef2 --- /dev/null +++ b/latest/coreMQTT/search/all_13.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['uint16_5fbitmap_5fbit_5fset_5fat_0',['UINT16_BITMAP_BIT_SET_AT',['../core__mqtt__state_8c.html#a50892214c51968df798f584272f16a17',1,'core_mqtt_state.c']]], + ['uint16_5fcheck_5fbit_1',['UINT16_CHECK_BIT',['../core__mqtt__state_8c.html#a085ab1307745f304ce2e6d24bdc3f6a7',1,'core_mqtt_state.c']]], + ['uint16_5fdecode_2',['UINT16_DECODE',['../core__mqtt__serializer_8c.html#acc849aa739edff3ec532219a3860a3a0',1,'core_mqtt_serializer.c']]], + ['uint16_5fhigh_5fbyte_3',['UINT16_HIGH_BYTE',['../core__mqtt__serializer_8c.html#a24aab781ef139dd38be534ee137ea2f9',1,'core_mqtt_serializer.c']]], + ['uint16_5flow_5fbyte_4',['UINT16_LOW_BYTE',['../core__mqtt__serializer_8c.html#af2ae35b27e0140a77238cd175508cb4e',1,'core_mqtt_serializer.c']]], + ['uint16_5fset_5fbit_5',['UINT16_SET_BIT',['../core__mqtt__state_8c.html#acd96521b31682b7d93de544704fd9594',1,'core_mqtt_state.c']]], + ['uint8_5fcheck_5fbit_6',['UINT8_CHECK_BIT',['../core__mqtt__serializer_8c.html#a07cc5f3f934e1ebf8011a6c15a667206',1,'core_mqtt_serializer.c']]], + ['uint8_5fset_5fbit_7',['UINT8_SET_BIT',['../core__mqtt__serializer_8c.html#af259c91b3075c24df53fa3ffe516b208',1,'core_mqtt_serializer.c']]], + ['updaterecord_8',['updateRecord',['../core__mqtt__state_8c.html#a819c7c72087621fcf97a028bff02759e',1,'core_mqtt_state.c']]], + ['updatestateack_9',['updateStateAck',['../core__mqtt__state_8c.html#a174a91b9491a344d6fb4f0b39189392f',1,'core_mqtt_state.c']]], + ['updatestatepublish_10',['updateStatePublish',['../core__mqtt__state_8c.html#aa0550584e3733da2e31c9478b9307b49',1,'core_mqtt_state.c']]], + ['usernamelength_11',['userNameLength',['../struct_m_q_t_t_connect_info__t.html#a7165be3bb06d4527ab4eb773b50e05e1',1,'MQTTConnectInfo_t']]] +]; diff --git a/latest/coreMQTT/search/all_14.js b/latest/coreMQTT/search/all_14.js new file mode 100644 index 00000000..460ee0c0 --- /dev/null +++ b/latest/coreMQTT/search/all_14.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['validatepublishparams_0',['validatePublishParams',['../core__mqtt_8c.html#ad7eda8c9d4a5afa7b3f830dbd8cf4de4',1,'core_mqtt.c']]], + ['validatesubscribeunsubscribeparams_1',['validateSubscribeUnsubscribeParams',['../core__mqtt_8c.html#a37c146709806e0974638784edeb587f8',1,'core_mqtt.c']]], + ['validatesubscriptionserializeparams_2',['validateSubscriptionSerializeParams',['../core__mqtt__serializer_8c.html#a81262cb0b9d47dee979420f6fd8a7271',1,'core_mqtt_serializer.c']]], + ['validatetransitionack_3',['validateTransitionAck',['../core__mqtt__state_8c.html#ac85ca8874163b399b7f8e5e17d3c5872',1,'core_mqtt_state.c']]], + ['validatetransitionpublish_4',['validateTransitionPublish',['../core__mqtt__state_8c.html#aad1473b9a2d46be62c3e80dd3524af9d',1,'core_mqtt_state.c']]] +]; diff --git a/latest/coreMQTT/search/all_15.js b/latest/coreMQTT/search/all_15.js new file mode 100644 index 00000000..9b440655 --- /dev/null +++ b/latest/coreMQTT/search/all_15.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['waitingforpingresp_0',['waitingForPingResp',['../struct_m_q_t_t_context__t.html#ac7073f43645f7b7c0c5b7763980004bb',1,'MQTTContext_t']]], + ['writev_1',['writev',['../struct_transport_interface__t.html#a8cf677fbeee53d270daa6dacfa138b79',1,'TransportInterface_t']]] +]; diff --git a/latest/coreMQTT/search/all_16.js b/latest/coreMQTT/search/all_16.js new file mode 100644 index 00000000..c6b43ceb --- /dev/null +++ b/latest/coreMQTT/search/all_16.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['zero_5fsize_5ft_0',['ZERO_SIZE_T',['../core__mqtt__state_8c.html#ab93bbb754488b23d5ac75abcd385e086',1,'core_mqtt_state.c']]] +]; diff --git a/latest/coreMQTT/search/all_2.js b/latest/coreMQTT/search/all_2.js new file mode 100644 index 00000000..904a7226 --- /dev/null +++ b/latest/coreMQTT/search/all_2.js @@ -0,0 +1,25 @@ +var searchData= +[ + ['calculateelapsedtime_0',['calculateElapsedTime',['../core__mqtt_8c.html#a04f9f5742bc28fe29e61f3f46d20d3d6',1,'core_mqtt.c']]], + ['calculatepublishpacketsize_1',['calculatePublishPacketSize',['../core__mqtt__serializer_8c.html#a76d0156e521588fb3319043f9d35ea9a',1,'core_mqtt_serializer.c']]], + ['calculatesubscriptionpacketsize_2',['calculateSubscriptionPacketSize',['../core__mqtt__serializer_8c.html#abdbabda0aa9db25166963afa975adb10',1,'core_mqtt_serializer.c']]], + ['callback_20types_3',['Callback Types',['../group__mqtt__callback__types.html',1,'']]], + ['checkpublishremaininglength_4',['checkPublishRemainingLength',['../core__mqtt__serializer_8c.html#a33a2680aab1ce2186acd7c78aeb270f1',1,'core_mqtt_serializer.c']]], + ['cleansession_5',['cleanSession',['../struct_m_q_t_t_connect_info__t.html#a606e7765c4f2215fb2bf630f6eb9ff6b',1,'MQTTConnectInfo_t']]], + ['clientidentifierlength_6',['clientIdentifierLength',['../struct_m_q_t_t_connect_info__t.html#a8077ef36ab318f3d35bee6f098fa54d4',1,'MQTTConnectInfo_t']]], + ['compactrecords_7',['compactRecords',['../core__mqtt__state_8c.html#a6cd7b86de2ddb125fee886d58d1a5fd4',1,'core_mqtt_state.c']]], + ['configurations_8',['Configurations',['../core_mqtt_config.html',1,'']]], + ['connectstatus_9',['connectStatus',['../struct_m_q_t_t_context__t.html#a4e38c4dc77e7751a0ad8730a41bee47f',1,'MQTTContext_t']]], + ['constants_10',['Constants',['../group__mqtt__constants.html',1,'']]], + ['controlpacketsent_11',['controlPacketSent',['../struct_m_q_t_t_context__t.html#af9724f2426132e3ce96a03892902ef89',1,'MQTTContext_t']]], + ['core_5fmqtt_2ec_12',['core_mqtt.c',['../core__mqtt_8c.html',1,'']]], + ['core_5fmqtt_2eh_13',['core_mqtt.h',['../core__mqtt_8h.html',1,'']]], + ['core_5fmqtt_5fconfig_5fdefaults_2eh_14',['core_mqtt_config_defaults.h',['../core__mqtt__config__defaults_8h.html',1,'']]], + ['core_5fmqtt_5fserialized_5flength_5ffield_5fbytes_15',['CORE_MQTT_SERIALIZED_LENGTH_FIELD_BYTES',['../core__mqtt_8c.html#a989426922a1f5f04ea8b612fd1f4b185',1,'core_mqtt.c']]], + ['core_5fmqtt_5fserializer_2ec_16',['core_mqtt_serializer.c',['../core__mqtt__serializer_8c.html',1,'']]], + ['core_5fmqtt_5fserializer_2eh_17',['core_mqtt_serializer.h',['../core__mqtt__serializer_8h.html',1,'']]], + ['core_5fmqtt_5fstate_2ec_18',['core_mqtt_state.c',['../core__mqtt__state_8c.html',1,'']]], + ['core_5fmqtt_5fstate_2eh_19',['core_mqtt_state.h',['../core__mqtt__state_8h.html',1,'']]], + ['core_5fmqtt_5fsubscribe_5fper_5ftopic_5fvector_5flength_20',['CORE_MQTT_SUBSCRIBE_PER_TOPIC_VECTOR_LENGTH',['../core__mqtt_8c.html#a97f180c9cc32ca9e354e7c22378a386b',1,'core_mqtt.c']]], + ['core_5fmqtt_5funsubscribe_5fper_5ftopic_5fvector_5flength_21',['CORE_MQTT_UNSUBSCRIBE_PER_TOPIC_VECTOR_LENGTH',['../core__mqtt_8c.html#a42477ec456354f2b944b47646ee5a9ce',1,'core_mqtt.c']]] +]; diff --git a/latest/coreMQTT/search/all_3.js b/latest/coreMQTT/search/all_3.js new file mode 100644 index 00000000..15d55e27 --- /dev/null +++ b/latest/coreMQTT/search/all_3.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['deserializationresult_0',['deserializationResult',['../struct_m_q_t_t_deserialized_info__t.html#a7df1b7b60404c9f1604fec0081d2625d',1,'MQTTDeserializedInfo_t']]], + ['deserializeconnack_1',['deserializeConnack',['../core__mqtt__serializer_8c.html#aa7b25e1e3114536e9b0526fc93a1f76c',1,'core_mqtt_serializer.c']]], + ['deserializepingresp_2',['deserializePingresp',['../core__mqtt__serializer_8c.html#afdd9b08562ccaa6cf8dd68baa6bc7060',1,'core_mqtt_serializer.c']]], + ['deserializepublish_3',['deserializePublish',['../core__mqtt__serializer_8c.html#a6e8bcde1280e14706e0cb9180358607c',1,'core_mqtt_serializer.c']]], + ['deserializesimpleack_4',['deserializeSimpleAck',['../core__mqtt__serializer_8c.html#a5d437c287290fa28a0ed65635fd6c9ae',1,'core_mqtt_serializer.c']]], + ['deserializesuback_5',['deserializeSuback',['../core__mqtt__serializer_8c.html#ae7b71036fc19c9a6da480dcfd3a2387b',1,'core_mqtt_serializer.c']]], + ['design_6',['Design',['../mqtt_design.html',1,'']]], + ['discardpacket_7',['discardPacket',['../core__mqtt_8c.html#abb02f1853a4805205636f2c11a435216',1,'core_mqtt.c']]], + ['discardstoredpacket_8',['discardStoredPacket',['../core__mqtt_8c.html#af827b2088c38c31a0b75dc70377db536',1,'core_mqtt.c']]], + ['dup_9',['dup',['../struct_m_q_t_t_publish_info__t.html#aa1c8954e83bfa678d1ff5429679d4e89',1,'MQTTPublishInfo_t']]] +]; diff --git a/latest/coreMQTT/search/all_4.js b/latest/coreMQTT/search/all_4.js new file mode 100644 index 00000000..5b751d64 --- /dev/null +++ b/latest/coreMQTT/search/all_4.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['encoderemaininglength_0',['encodeRemainingLength',['../core__mqtt__serializer_8c.html#a3a3858fbb0cbd845f208b3fc60f36130',1,'core_mqtt_serializer.c']]], + ['encodestring_1',['encodeString',['../core__mqtt__serializer_8c.html#a60e580c28431eb08f05a156949137f1f',1,'core_mqtt_serializer.c']]], + ['enumerated_20types_2',['Enumerated Types',['../group__mqtt__enum__types.html',1,'']]] +]; diff --git a/latest/coreMQTT/search/all_5.js b/latest/coreMQTT/search/all_5.js new file mode 100644 index 00000000..07ce47bb --- /dev/null +++ b/latest/coreMQTT/search/all_5.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['findinrecord_0',['findInRecord',['../core__mqtt__state_8c.html#ac805558ac65e84ea9111ce70c873e59e',1,'core_mqtt_state.c']]], + ['functions_1',['Functions',['../mqtt_functions.html',1,'']]] +]; diff --git a/latest/coreMQTT/search/all_6.js b/latest/coreMQTT/search/all_6.js new file mode 100644 index 00000000..25049862 --- /dev/null +++ b/latest/coreMQTT/search/all_6.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['getackfrompackettype_0',['getAckFromPacketType',['../core__mqtt_8c.html#aa1f35063dbe3b2c35f278ea6aa347a0e',1,'core_mqtt.c']]], + ['getacktypetosend_1',['getAckTypeToSend',['../core__mqtt_8c.html#a02f112e21a6d0b87a3c69ef300d264de',1,'core_mqtt.c']]], + ['getremaininglength_2',['getRemainingLength',['../core__mqtt__serializer_8c.html#a5685b753d1d42788a00bd59ffa4639e2',1,'core_mqtt_serializer.c']]], + ['gettime_3',['getTime',['../struct_m_q_t_t_context__t.html#aabe1d302a16771292151013e8e30c582',1,'MQTTContext_t']]] +]; diff --git a/latest/coreMQTT/search/all_7.js b/latest/coreMQTT/search/all_7.js new file mode 100644 index 00000000..e757c7a1 --- /dev/null +++ b/latest/coreMQTT/search/all_7.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['handleincomingack_0',['handleIncomingAck',['../core__mqtt_8c.html#a264afa489cbfbd96086614d335969115',1,'core_mqtt.c']]], + ['handleincomingpublish_1',['handleIncomingPublish',['../core__mqtt_8c.html#a4ac6e6829500c4f522eae413c9470e4d',1,'core_mqtt.c']]], + ['handlekeepalive_2',['handleKeepAlive',['../core__mqtt_8c.html#ae0e50de302a1aa66e3c5b2cdcacc4f3f',1,'core_mqtt.c']]], + ['handlepublishacks_3',['handlePublishAcks',['../core__mqtt_8c.html#a2363868c0417261c27c750251aad13e5',1,'core_mqtt.c']]], + ['handlesessionresumption_4',['handleSessionResumption',['../core__mqtt_8c.html#aae9ba11e41bc1dfef340208bc49c836c',1,'core_mqtt.c']]], + ['headerlength_5',['headerLength',['../struct_m_q_t_t_packet_info__t.html#aa7de1631ed8e08410942d36a72db558a',1,'MQTTPacketInfo_t']]] +]; diff --git a/latest/coreMQTT/search/all_8.js b/latest/coreMQTT/search/all_8.js new file mode 100644 index 00000000..fc182a43 --- /dev/null +++ b/latest/coreMQTT/search/all_8.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['incomingpacketvalid_0',['incomingPacketValid',['../core__mqtt__serializer_8c.html#a03dfebbfbc1635567839f7abb7c0f8db',1,'core_mqtt_serializer.c']]], + ['incomingpublishrecordmaxcount_1',['incomingPublishRecordMaxCount',['../struct_m_q_t_t_context__t.html#aa33ed2e10380a854629f1386d0323ea8',1,'MQTTContext_t']]], + ['incomingpublishrecords_2',['incomingPublishRecords',['../struct_m_q_t_t_context__t.html#afc147663a5933de81212fa77057f0a4d',1,'MQTTContext_t']]], + ['index_3',['index',['../struct_m_q_t_t_context__t.html#a41b7735cd0746563483b72e17cf103aa',1,'MQTTContext_t']]], + ['iov_5fbase_4',['iov_base',['../struct_transport_out_vector__t.html#a0ffa5c06bf00006cbafa8e244951038d',1,'TransportOutVector_t']]], + ['iov_5flen_5',['iov_len',['../struct_transport_out_vector__t.html#ada73dafb2d34311f33fefad38603b35c',1,'TransportOutVector_t']]], + ['ispublishoutgoing_6',['isPublishOutgoing',['../core__mqtt__state_8c.html#aaf9d4c6e766e40189ff7b68ffea40aa0',1,'core_mqtt_state.c']]] +]; diff --git a/latest/coreMQTT/search/all_9.js b/latest/coreMQTT/search/all_9.js new file mode 100644 index 00000000..dcbf16db --- /dev/null +++ b/latest/coreMQTT/search/all_9.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['keepaliveintervalsec_0',['keepAliveIntervalSec',['../struct_m_q_t_t_context__t.html#afd6071827ef48b230212a5725c2075be',1,'MQTTContext_t']]], + ['keepaliveseconds_1',['keepAliveSeconds',['../struct_m_q_t_t_connect_info__t.html#a7d05d53261732ebdfbb9ee665a347591',1,'MQTTConnectInfo_t']]] +]; diff --git a/latest/coreMQTT/search/all_a.js b/latest/coreMQTT/search/all_a.js new file mode 100644 index 00000000..2088ac2c --- /dev/null +++ b/latest/coreMQTT/search/all_a.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['lastpacketrxtime_0',['lastPacketRxTime',['../struct_m_q_t_t_context__t.html#a7111ef16e4a4e75a72861f6f3ea8a7c3',1,'MQTTContext_t']]], + ['lastpackettxtime_1',['lastPacketTxTime',['../struct_m_q_t_t_context__t.html#a01acf90953e830ba3e7f44182cb1d482',1,'MQTTContext_t']]], + ['logconnackresponse_2',['logConnackResponse',['../core__mqtt__serializer_8c.html#a5451f2e3468faaf2bdf85220ebb95aaa',1,'core_mqtt_serializer.c']]], + ['logdebug_3',['LogDebug',['../core__mqtt__config__defaults_8h.html#af60e8ffc327d136e5d0d8441ed98c98d',1,'core_mqtt_config_defaults.h']]], + ['logerror_4',['LogError',['../core__mqtt__config__defaults_8h.html#a8d9dbaaa88129137a4c68ba0456a18b1',1,'core_mqtt_config_defaults.h']]], + ['loginfo_5',['LogInfo',['../core__mqtt__config__defaults_8h.html#a00810b1cb9d2f25d25ce2d4d93815fba',1,'core_mqtt_config_defaults.h']]], + ['logwarn_6',['LogWarn',['../core__mqtt__config__defaults_8h.html#a7da92048aaf0cbfcacde9539c98a0e05',1,'core_mqtt_config_defaults.h']]] +]; diff --git a/latest/coreMQTT/search/all_b.js b/latest/coreMQTT/search/all_b.js new file mode 100644 index 00000000..b9e3fd9a --- /dev/null +++ b/latest/coreMQTT/search/all_b.js @@ -0,0 +1,161 @@ +var searchData= +[ + ['matchendwildcardsspecialcases_0',['matchEndWildcardsSpecialCases',['../core__mqtt_8c.html#ab29bb66fe7385c52452a3087bcfbc98e',1,'core_mqtt.c']]], + ['matchtopicfilter_1',['matchTopicFilter',['../core__mqtt_8c.html#a4c052d9dd6a81e866121c24a2ee2aa0b',1,'core_mqtt.c']]], + ['matchwildcards_2',['matchWildcards',['../core__mqtt_8c.html#ab1f061741c445d07454cfa03786a5eea',1,'core_mqtt.c']]], + ['mqtt_5fcalculatestateack_3',['MQTT_CalculateStateAck',['../core__mqtt__state_8c.html#a0cad28e34f03b84aff43ee243ce8e2cf',1,'core_mqtt_state.c']]], + ['mqtt_5fcalculatestatepublish_4',['MQTT_CalculateStatePublish',['../core__mqtt__state_8c.html#aadc4fdd8af74ac25b848a33e916bff50',1,'core_mqtt_state.c']]], + ['mqtt_5fcancelcallback_5',['MQTT_CancelCallback',['../core__mqtt_8h.html#a31b74c34cd295b98ed5f5b4c15ed4a8b',1,'MQTT_CancelCallback(const MQTTContext_t *pContext, uint16_t packetId): core_mqtt.c'],['../core__mqtt_8c.html#a31b74c34cd295b98ed5f5b4c15ed4a8b',1,'MQTT_CancelCallback(const MQTTContext_t *pContext, uint16_t packetId): core_mqtt.c']]], + ['mqtt_5fconnect_6',['MQTT_Connect',['../core__mqtt_8c.html#aed1e4dc123a8ba79ac569cb17c69bfa0',1,'MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent): core_mqtt.c'],['../core__mqtt_8h.html#aed1e4dc123a8ba79ac569cb17c69bfa0',1,'MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent): core_mqtt.c'],['../mqtt_connect_function.html',1,'mqtt_functions']]], + ['mqtt_5fconnect_5fflag_5fclean_7',['MQTT_CONNECT_FLAG_CLEAN',['../core__mqtt__serializer_8c.html#a1b131e766e003e36fe499d9f6a79fc03',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fpassword_8',['MQTT_CONNECT_FLAG_PASSWORD',['../core__mqtt__serializer_8c.html#ac5f0bb47789c1182392f5029e0238a81',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fusername_9',['MQTT_CONNECT_FLAG_USERNAME',['../core__mqtt__serializer_8c.html#a8d23d14a4cf296feffb9db79728dd1d0',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fwill_10',['MQTT_CONNECT_FLAG_WILL',['../core__mqtt__serializer_8c.html#a04d8c55ea2b595a277cbcd4340e36d6c',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fwill_5fqos1_11',['MQTT_CONNECT_FLAG_WILL_QOS1',['../core__mqtt__serializer_8c.html#a2aee739b1fa7e61feb907bc92a73c3b4',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fwill_5fqos2_12',['MQTT_CONNECT_FLAG_WILL_QOS2',['../core__mqtt__serializer_8c.html#ac750789b338a2b9be75725ab340dabce',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fwill_5fretain_13',['MQTT_CONNECT_FLAG_WILL_RETAIN',['../core__mqtt__serializer_8c.html#a8ae294d4ca7960920816339fedbdc4a0',1,'core_mqtt_serializer.c']]], + ['mqtt_5fdeserializeack_14',['MQTT_DeserializeAck',['../core__mqtt__serializer_8h.html#ae9971855df71edf94124116e0625bf18',1,'MQTT_DeserializeAck(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, bool *pSessionPresent): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#ae9971855df71edf94124116e0625bf18',1,'MQTT_DeserializeAck(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, bool *pSessionPresent): core_mqtt_serializer.c'],['../mqtt_deserializeack_function.html',1,'mqtt_functions']]], + ['mqtt_5fdeserializepublish_15',['MQTT_DeserializePublish',['../core__mqtt__serializer_8h.html#a4c2aec031f31d0fe55c1cda46544e95a',1,'MQTT_DeserializePublish(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a4c2aec031f31d0fe55c1cda46544e95a',1,'MQTT_DeserializePublish(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo): core_mqtt_serializer.c'],['../mqtt_deserializepublish_function.html',1,'mqtt_functions']]], + ['mqtt_5fdisconnect_16',['MQTT_Disconnect',['../core__mqtt_8h.html#ac79c366acbc3dddd88072d99ccb9140c',1,'MQTT_Disconnect(MQTTContext_t *pContext): core_mqtt.c'],['../core__mqtt_8c.html#ac79c366acbc3dddd88072d99ccb9140c',1,'MQTT_Disconnect(MQTTContext_t *pContext): core_mqtt.c'],['../mqtt_disconnect_function.html',1,'mqtt_functions']]], + ['mqtt_5fdisconnect_5fpacket_5fsize_17',['MQTT_DISCONNECT_PACKET_SIZE',['../core__mqtt__serializer_8c.html#abdcffcd69d858203747236b5c4afa834',1,'core_mqtt_serializer.c']]], + ['mqtt_5fdisconnect_5fremaining_5flength_18',['MQTT_DISCONNECT_REMAINING_LENGTH',['../core__mqtt__serializer_8c.html#ac4f3ff016aa6011e3fc707b9f27f6b8c',1,'core_mqtt_serializer.c']]], + ['mqtt_5fdo_5fnot_5fuse_5fcustom_5fconfig_19',['MQTT_DO_NOT_USE_CUSTOM_CONFIG',['../core__mqtt__config__defaults_8h.html#abd12bb401eecf3f6694447ea3b1c886d',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5fgetconnectpacketsize_20',['MQTT_GetConnectPacketSize',['../core__mqtt__serializer_8h.html#a4e57ccef527a25b572dc66eeb2e217c5',1,'MQTT_GetConnectPacketSize(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a4e57ccef527a25b572dc66eeb2e217c5',1,'MQTT_GetConnectPacketSize(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../mqtt_getconnectpacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetdisconnectpacketsize_21',['MQTT_GetDisconnectPacketSize',['../core__mqtt__serializer_8h.html#a6fdd8cbde6b7c4ff85c20aaca0fd8741',1,'MQTT_GetDisconnectPacketSize(size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a6fdd8cbde6b7c4ff85c20aaca0fd8741',1,'MQTT_GetDisconnectPacketSize(size_t *pPacketSize): core_mqtt_serializer.c'],['../mqtt_getdisconnectpacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetincomingpackettypeandlength_22',['MQTT_GetIncomingPacketTypeAndLength',['../core__mqtt__serializer_8c.html#a98cdda86f86a0a1888745a584199e930',1,'MQTT_GetIncomingPacketTypeAndLength(TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#a98cdda86f86a0a1888745a584199e930',1,'MQTT_GetIncomingPacketTypeAndLength(TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket): core_mqtt_serializer.c'],['../mqtt_getincomingpackettypeandlength_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetpacketid_23',['MQTT_GetPacketId',['../core__mqtt_8h.html#a00e1a3eba2c21899a6b4312c7d65d090',1,'MQTT_GetPacketId(MQTTContext_t *pContext): core_mqtt.c'],['../core__mqtt_8c.html#a00e1a3eba2c21899a6b4312c7d65d090',1,'MQTT_GetPacketId(MQTTContext_t *pContext): core_mqtt.c'],['../mqtt_getpacketid_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetpingreqpacketsize_24',['MQTT_GetPingreqPacketSize',['../core__mqtt__serializer_8h.html#a015562f30e220d2534f773bfa45a5cfe',1,'MQTT_GetPingreqPacketSize(size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a015562f30e220d2534f773bfa45a5cfe',1,'MQTT_GetPingreqPacketSize(size_t *pPacketSize): core_mqtt_serializer.c'],['../mqtt_getpingreqpacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetpublishpacketsize_25',['MQTT_GetPublishPacketSize',['../core__mqtt__serializer_8h.html#a9971fb98c6af22b1bfe697d44492a819',1,'MQTT_GetPublishPacketSize(const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a9971fb98c6af22b1bfe697d44492a819',1,'MQTT_GetPublishPacketSize(const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../mqtt_getpublishpacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetsubackstatuscodes_26',['MQTT_GetSubAckStatusCodes',['../core__mqtt_8h.html#ac43449e06856c6703cda73359c222bd2',1,'MQTT_GetSubAckStatusCodes(const MQTTPacketInfo_t *pSubackPacket, uint8_t **pPayloadStart, size_t *pPayloadSize): core_mqtt.c'],['../core__mqtt_8c.html#ac43449e06856c6703cda73359c222bd2',1,'MQTT_GetSubAckStatusCodes(const MQTTPacketInfo_t *pSubackPacket, uint8_t **pPayloadStart, size_t *pPayloadSize): core_mqtt.c'],['../mqtt_getsubackstatuscodes_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetsubscribepacketsize_27',['MQTT_GetSubscribePacketSize',['../core__mqtt__serializer_8c.html#abb9a703cb23ab39fdd6fe282a5f3ddc5',1,'MQTT_GetSubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#abb9a703cb23ab39fdd6fe282a5f3ddc5',1,'MQTT_GetSubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../mqtt_getsubscribepacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetunsubscribepacketsize_28',['MQTT_GetUnsubscribePacketSize',['../core__mqtt__serializer_8c.html#a2a18563d5f63c8975b57118a6836c932',1,'MQTT_GetUnsubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#a2a18563d5f63c8975b57118a6836c932',1,'MQTT_GetUnsubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../mqtt_getunsubscribepacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5finit_29',['MQTT_Init',['../core__mqtt_8h.html#ae8444f3a85535e62cdb1ae9c192677d6',1,'MQTT_Init(MQTTContext_t *pContext, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getTimeFunction, MQTTEventCallback_t userCallback, const MQTTFixedBuffer_t *pNetworkBuffer): core_mqtt.c'],['../core__mqtt_8c.html#ae8444f3a85535e62cdb1ae9c192677d6',1,'MQTT_Init(MQTTContext_t *pContext, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getTimeFunction, MQTTEventCallback_t userCallback, const MQTTFixedBuffer_t *pNetworkBuffer): core_mqtt.c'],['../mqtt_init_function.html',1,'mqtt_functions']]], + ['mqtt_5finitstatefulqos_30',['MQTT_InitStatefulQoS',['../core__mqtt_8c.html#afe4c020749e3b9ca044e0e9ad96025c5',1,'MQTT_InitStatefulQoS(MQTTContext_t *pContext, MQTTPubAckInfo_t *pOutgoingPublishRecords, size_t outgoingPublishCount, MQTTPubAckInfo_t *pIncomingPublishRecords, size_t incomingPublishCount): core_mqtt.c'],['../core__mqtt_8h.html#afe4c020749e3b9ca044e0e9ad96025c5',1,'MQTT_InitStatefulQoS(MQTTContext_t *pContext, MQTTPubAckInfo_t *pOutgoingPublishRecords, size_t outgoingPublishCount, MQTTPubAckInfo_t *pIncomingPublishRecords, size_t incomingPublishCount): core_mqtt.c']]], + ['mqtt_5finvalid_5fstate_5fcount_31',['MQTT_INVALID_STATE_COUNT',['../core__mqtt__state_8c.html#a49d2236ebe2b3d27e82e54a7b9e74984',1,'core_mqtt_state.c']]], + ['mqtt_5fmatchtopic_32',['MQTT_MatchTopic',['../core__mqtt_8c.html#a633409812b18547365ec9b853069021b',1,'MQTT_MatchTopic(const char *pTopicName, const uint16_t topicNameLength, const char *pTopicFilter, const uint16_t topicFilterLength, bool *pIsMatch): core_mqtt.c'],['../core__mqtt_8h.html#a633409812b18547365ec9b853069021b',1,'MQTT_MatchTopic(const char *pTopicName, const uint16_t topicNameLength, const char *pTopicFilter, const uint16_t topicFilterLength, bool *pIsMatch): core_mqtt.c']]], + ['mqtt_5fmax_5fconnack_5freceive_5fretry_5fcount_33',['MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT',['../core__mqtt__config__defaults_8h.html#a8ca6c96436d5e7c2c8a7933fb28a5c87',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5fmax_5fremaining_5flength_34',['MQTT_MAX_REMAINING_LENGTH',['../core__mqtt__serializer_8c.html#a9d9ea40a1ff486557a553523a0743647',1,'core_mqtt_serializer.c']]], + ['mqtt_5fmin_5fpublish_5fremaining_5flength_5fqos0_35',['MQTT_MIN_PUBLISH_REMAINING_LENGTH_QOS0',['../core__mqtt__serializer_8c.html#a3b8709529a24bc195c7310183ffbcc2b',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fconnack_5fremaining_5flength_36',['MQTT_PACKET_CONNACK_REMAINING_LENGTH',['../core__mqtt__serializer_8c.html#a999c4ebc0d629df9b08a3c88107b5b80',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fconnack_5fsession_5fpresent_5fmask_37',['MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK',['../core__mqtt__serializer_8c.html#aab69dd14c12f8086245c2371288944f0',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fconnect_5fheader_5fsize_38',['MQTT_PACKET_CONNECT_HEADER_SIZE',['../core__mqtt__serializer_8c.html#aa7c310cb084af0025c356ed844ae443d',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fid_5finvalid_39',['MQTT_PACKET_ID_INVALID',['../group__mqtt__constants.html#ga9fde6503edb9eaad50ecd3392ab9992a',1,'core_mqtt.h']]], + ['mqtt_5fpacket_5fpingreq_5fsize_40',['MQTT_PACKET_PINGREQ_SIZE',['../core__mqtt__serializer_8c.html#a6e8a49d0d88f0b038a5379d533858103',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fpingresp_5fremaining_5flength_41',['MQTT_PACKET_PINGRESP_REMAINING_LENGTH',['../core__mqtt__serializer_8c.html#aeab5c92e86ed98750cbf6422b8b57c06',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fsimple_5fack_5fremaining_5flength_42',['MQTT_PACKET_SIMPLE_ACK_REMAINING_LENGTH',['../core__mqtt__serializer_8c.html#a4c576df64bca769a91cb64d5d5d86505',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5ftype_5fconnack_43',['MQTT_PACKET_TYPE_CONNACK',['../group__mqtt__constants.html#gab14f6c39c303eac1a76816edfde7feab',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fconnect_44',['MQTT_PACKET_TYPE_CONNECT',['../group__mqtt__constants.html#ga64a0515bda2ecc89e97595535e1cf0ef',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fdisconnect_45',['MQTT_PACKET_TYPE_DISCONNECT',['../group__mqtt__constants.html#gaed07155a3d6fa4b7624b9f36ed33ec6d',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fpingreq_46',['MQTT_PACKET_TYPE_PINGREQ',['../group__mqtt__constants.html#gacbe28c7d081275d1805c2142ff792185',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fpingresp_47',['MQTT_PACKET_TYPE_PINGRESP',['../group__mqtt__constants.html#ga285fc02048e2482794042fa98639e514',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fpuback_48',['MQTT_PACKET_TYPE_PUBACK',['../group__mqtt__constants.html#ga5f279d63de47a973b41b95f74f47a4f6',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fpubcomp_49',['MQTT_PACKET_TYPE_PUBCOMP',['../group__mqtt__constants.html#ga478ecbc98d2ca83d4ce7db33622b5c3b',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fpublish_50',['MQTT_PACKET_TYPE_PUBLISH',['../group__mqtt__constants.html#ga5b2d79c61f2591c8e5772f974826d4ad',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fpubrec_51',['MQTT_PACKET_TYPE_PUBREC',['../group__mqtt__constants.html#gafa2d8f28da39560f152076b99610e6a3',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fpubrel_52',['MQTT_PACKET_TYPE_PUBREL',['../group__mqtt__constants.html#gaeaa2ceecffda50e2d22ccecf046083c6',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fsuback_53',['MQTT_PACKET_TYPE_SUBACK',['../group__mqtt__constants.html#ga307e0186aa17fdd0d6d181d3d2715766',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fsubscribe_54',['MQTT_PACKET_TYPE_SUBSCRIBE',['../group__mqtt__constants.html#ga80cfef333e60d967ca927b2e5e665f18',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5funsuback_55',['MQTT_PACKET_TYPE_UNSUBACK',['../group__mqtt__constants.html#ga38bc8ed0b9a1581cf85cecdede7d1a64',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5funsubscribe_56',['MQTT_PACKET_TYPE_UNSUBSCRIBE',['../group__mqtt__constants.html#ga4a94c954cfcea31c8fc3e2adf092b228',1,'core_mqtt_serializer.h']]], + ['mqtt_5fping_57',['MQTT_Ping',['../core__mqtt_8h.html#a66eced0c62ace790354ae3de40fc0959',1,'MQTT_Ping(MQTTContext_t *pContext): core_mqtt.c'],['../core__mqtt_8c.html#a66eced0c62ace790354ae3de40fc0959',1,'MQTT_Ping(MQTTContext_t *pContext): core_mqtt.c'],['../mqtt_ping_function.html',1,'mqtt_functions']]], + ['mqtt_5fpingresp_5ftimeout_5fms_58',['MQTT_PINGRESP_TIMEOUT_MS',['../core__mqtt__config__defaults_8h.html#afa825fddb52da7df88fb56d2befcd2fa',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5fpost_5fsend_5fhook_59',['MQTT_POST_SEND_HOOK',['../core__mqtt_8c.html#a205b7112b6bb0697f85b9e25512c67be',1,'core_mqtt.c']]], + ['mqtt_5fpost_5fstate_5fupdate_5fhook_60',['MQTT_POST_STATE_UPDATE_HOOK',['../core__mqtt_8c.html#a436983fba04e3d13cabea35efc4e9bf8',1,'core_mqtt.c']]], + ['mqtt_5fpre_5fsend_5fhook_61',['MQTT_PRE_SEND_HOOK',['../core__mqtt_8c.html#a18f9369f0d6d553db6d1af1bd7156545',1,'core_mqtt.c']]], + ['mqtt_5fpre_5fstate_5fupdate_5fhook_62',['MQTT_PRE_STATE_UPDATE_HOOK',['../core__mqtt_8c.html#acba4b6e51723d384aa9140313effdf8b',1,'core_mqtt.c']]], + ['mqtt_5fprocessincomingpackettypeandlength_63',['MQTT_ProcessIncomingPacketTypeAndLength',['../core__mqtt__serializer_8c.html#a94fd3f746074b3f6e16ae6b23dad9a28',1,'MQTT_ProcessIncomingPacketTypeAndLength(const uint8_t *pBuffer, const size_t *pIndex, MQTTPacketInfo_t *pIncomingPacket): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#a94fd3f746074b3f6e16ae6b23dad9a28',1,'MQTT_ProcessIncomingPacketTypeAndLength(const uint8_t *pBuffer, const size_t *pIndex, MQTTPacketInfo_t *pIncomingPacket): core_mqtt_serializer.c']]], + ['mqtt_5fprocessloop_64',['MQTT_ProcessLoop',['../core__mqtt_8h.html#ab95d3d6b3eed98a6184fb2018c5b55d7',1,'MQTT_ProcessLoop(MQTTContext_t *pContext): core_mqtt.c'],['../core__mqtt_8c.html#ab95d3d6b3eed98a6184fb2018c5b55d7',1,'MQTT_ProcessLoop(MQTTContext_t *pContext): core_mqtt.c'],['../mqtt_processloop_function.html',1,'mqtt_functions']]], + ['mqtt_5fpublish_65',['MQTT_Publish',['../core__mqtt_8h.html#a1d8217e9d30fb2aed002060a8c97c63e',1,'MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId): core_mqtt.c'],['../core__mqtt_8c.html#a1d8217e9d30fb2aed002060a8c97c63e',1,'MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId): core_mqtt.c'],['../mqtt_publish_function.html',1,'mqtt_functions']]], + ['mqtt_5fpublish_5fack_5fpacket_5fsize_66',['MQTT_PUBLISH_ACK_PACKET_SIZE',['../group__mqtt__constants.html#ga26994fcfacb1cff892caa45ec31ca7c6',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpublish_5fflag_5fdup_67',['MQTT_PUBLISH_FLAG_DUP',['../core__mqtt__serializer_8c.html#a57c437ecc3720de76093b08eb0d4f813',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpublish_5fflag_5fqos1_68',['MQTT_PUBLISH_FLAG_QOS1',['../core__mqtt__serializer_8c.html#ac23212835606fade167fb5ce25eaf103',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpublish_5fflag_5fqos2_69',['MQTT_PUBLISH_FLAG_QOS2',['../core__mqtt__serializer_8c.html#afe1d2a0b7c0803f5a20ebb3c7a607d65',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpublish_5fflag_5fretain_70',['MQTT_PUBLISH_FLAG_RETAIN',['../core__mqtt__serializer_8c.html#a3d04b1e1ad7ec25d18fd13726e164f06',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpublishtoresend_71',['MQTT_PublishToResend',['../core__mqtt__state_8c.html#a44b3cf50dc477a9f97413a9238a961f6',1,'MQTT_PublishToResend(const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor): core_mqtt_state.c'],['../core__mqtt__state_8h.html#a44b3cf50dc477a9f97413a9238a961f6',1,'MQTT_PublishToResend(const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor): core_mqtt_state.c'],['../mqtt_publishtoresend_function.html',1,'mqtt_functions']]], + ['mqtt_5fpubreltoresend_72',['MQTT_PubrelToResend',['../core__mqtt__state_8c.html#ae58ade262ec01262687554b349b2fdf5',1,'core_mqtt_state.c']]], + ['mqtt_5freceiveloop_73',['MQTT_ReceiveLoop',['../core__mqtt_8c.html#aeb7c37284fcf6f68eb577427a6763fc6',1,'MQTT_ReceiveLoop(MQTTContext_t *pContext): core_mqtt.c'],['../core__mqtt_8h.html#aeb7c37284fcf6f68eb577427a6763fc6',1,'MQTT_ReceiveLoop(MQTTContext_t *pContext): core_mqtt.c'],['../mqtt_receiveloop_function.html',1,'mqtt_functions']]], + ['mqtt_5frecv_5fpolling_5ftimeout_5fms_74',['MQTT_RECV_POLLING_TIMEOUT_MS',['../core__mqtt__config__defaults_8h.html#a43dc9a67427d9e420a65955eea0e2671',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5fremaining_5flength_5finvalid_75',['MQTT_REMAINING_LENGTH_INVALID',['../core__mqtt__serializer_8c.html#a6f6b43661df6f9e9e9e7123ab01e9eb5',1,'core_mqtt_serializer.c']]], + ['mqtt_5fremovestaterecord_76',['MQTT_RemoveStateRecord',['../core__mqtt__state_8c.html#aef2c13cffbbd5c71183282e69ac9d799',1,'core_mqtt_state.c']]], + ['mqtt_5freservestate_77',['MQTT_ReserveState',['../core__mqtt__state_8c.html#a43bc5d82716e1d8b6e167ec0fe50de5d',1,'core_mqtt_state.c']]], + ['mqtt_5fsend_5ftimeout_5fms_78',['MQTT_SEND_TIMEOUT_MS',['../core__mqtt__config__defaults_8h.html#ac262cab68c4c713ebc2b91a2e4ab8b19',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5fserializeack_79',['MQTT_SerializeAck',['../core__mqtt__serializer_8h.html#a11ea4ac5ea27e93121288e463ca34ee6',1,'MQTT_SerializeAck(const MQTTFixedBuffer_t *pFixedBuffer, uint8_t packetType, uint16_t packetId): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a11ea4ac5ea27e93121288e463ca34ee6',1,'MQTT_SerializeAck(const MQTTFixedBuffer_t *pFixedBuffer, uint8_t packetType, uint16_t packetId): core_mqtt_serializer.c'],['../mqtt_serializeack_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializeconnect_80',['MQTT_SerializeConnect',['../core__mqtt__serializer_8c.html#aa2e2300d6c43e61f8f2cf83f7149835c',1,'MQTT_SerializeConnect(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#aa2e2300d6c43e61f8f2cf83f7149835c',1,'MQTT_SerializeConnect(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../mqtt_serializeconnect_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializeconnectfixedheader_81',['MQTT_SerializeConnectFixedHeader',['../core__mqtt__serializer_8c.html#a5e6043289c05db1cdb7e33e0921247a0',1,'core_mqtt_serializer.c']]], + ['mqtt_5fserializedisconnect_82',['MQTT_SerializeDisconnect',['../core__mqtt__serializer_8c.html#a6aae40d4656eb533a74b67bf9c827d3b',1,'MQTT_SerializeDisconnect(const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#a6aae40d4656eb533a74b67bf9c827d3b',1,'MQTT_SerializeDisconnect(const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../mqtt_serializedisconnect_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializepingreq_83',['MQTT_SerializePingreq',['../core__mqtt__serializer_8c.html#af3b3e40858fd984c871511e02a61e15d',1,'MQTT_SerializePingreq(const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#af3b3e40858fd984c871511e02a61e15d',1,'MQTT_SerializePingreq(const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../mqtt_serializepingreq_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializepublish_84',['MQTT_SerializePublish',['../core__mqtt__serializer_8c.html#ac6c453f9c4b7f48aad511bc677ec7eb9',1,'MQTT_SerializePublish(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#ac6c453f9c4b7f48aad511bc677ec7eb9',1,'MQTT_SerializePublish(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../mqtt_serializepublish_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializepublishheader_85',['MQTT_SerializePublishHeader',['../core__mqtt__serializer_8c.html#a659cf2bcaf2c5131daa0acc1917401a2',1,'MQTT_SerializePublishHeader(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer, size_t *pHeaderSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#a659cf2bcaf2c5131daa0acc1917401a2',1,'MQTT_SerializePublishHeader(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer, size_t *pHeaderSize): core_mqtt_serializer.c'],['../mqtt_serializepublishheader_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializepublishheaderwithouttopic_86',['MQTT_SerializePublishHeaderWithoutTopic',['../core__mqtt__serializer_8h.html#a32de7fabeca85a4d360fa1dd06ff7cd0',1,'MQTT_SerializePublishHeaderWithoutTopic(const MQTTPublishInfo_t *pPublishInfo, size_t remainingLength, uint8_t *pBuffer, size_t *headerSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a32de7fabeca85a4d360fa1dd06ff7cd0',1,'MQTT_SerializePublishHeaderWithoutTopic(const MQTTPublishInfo_t *pPublishInfo, size_t remainingLength, uint8_t *pBuffer, size_t *headerSize): core_mqtt_serializer.c']]], + ['mqtt_5fserializesubscribe_87',['MQTT_SerializeSubscribe',['../core__mqtt__serializer_8h.html#a21273b13070e8340cc33b0f86bf79571',1,'MQTT_SerializeSubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a21273b13070e8340cc33b0f86bf79571',1,'MQTT_SerializeSubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../mqtt_serializesubscribe_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializesubscribeheader_88',['MQTT_SerializeSubscribeHeader',['../core__mqtt__serializer_8c.html#a6fe31953d7b8dacb769adcf4c2719730',1,'core_mqtt_serializer.c']]], + ['mqtt_5fserializeunsubscribe_89',['MQTT_SerializeUnsubscribe',['../core__mqtt__serializer_8h.html#aab58219c203077c07ffd7061405e1adb',1,'MQTT_SerializeUnsubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#aab58219c203077c07ffd7061405e1adb',1,'MQTT_SerializeUnsubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../mqtt_serializeunsubscribe_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializeunsubscribeheader_90',['MQTT_SerializeUnsubscribeHeader',['../core__mqtt__serializer_8c.html#a5b6f47fa319a444835ffed2d6af04709',1,'core_mqtt_serializer.c']]], + ['mqtt_5fstate_5fcursor_5finitializer_91',['MQTT_STATE_CURSOR_INITIALIZER',['../group__mqtt__constants.html#ga666ad78e7eaaffa51f5cab96201a9476',1,'core_mqtt_state.h']]], + ['mqtt_5fstate_5fstrerror_92',['MQTT_State_strerror',['../core__mqtt__state_8c.html#a53d786203ca4d5d5630a9eb3dd4cddae',1,'core_mqtt_state.c']]], + ['mqtt_5fstatus_5fstrerror_93',['MQTT_Status_strerror',['../core__mqtt_8h.html#a05d9facfce89c5f9edef09ca13717f50',1,'MQTT_Status_strerror(MQTTStatus_t status): core_mqtt.c'],['../core__mqtt_8c.html#a05d9facfce89c5f9edef09ca13717f50',1,'MQTT_Status_strerror(MQTTStatus_t status): core_mqtt.c'],['../mqtt_status_strerror_function.html',1,'mqtt_functions']]], + ['mqtt_5fsub_5funsub_5fmax_5fvectors_94',['MQTT_SUB_UNSUB_MAX_VECTORS',['../group__mqtt__constants.html#ga928ea0bff12ebf9cf9fa9dfe5cafebbb',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5fsubscribe_95',['MQTT_Subscribe',['../core__mqtt_8h.html#a567aa9c38726a7879f9cbf943e813e8f',1,'MQTT_Subscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId): core_mqtt.c'],['../core__mqtt_8c.html#a567aa9c38726a7879f9cbf943e813e8f',1,'MQTT_Subscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId): core_mqtt.c']]], + ['mqtt_5fsubscribe_96',['MQTT_SUBSCRIBE',['../core__mqtt__serializer_8c.html#a92e39b92b76d439a183fc6f5e300195fa7dd20d5d68728190c8c1050599b562f7',1,'core_mqtt_serializer.c']]], + ['mqtt_5fsubscribe_97',['MQTT_Subscribe',['../mqtt_subscribe_function.html',1,'mqtt_functions']]], + ['mqtt_5funsubscribe_98',['MQTT_Unsubscribe',['../core__mqtt_8c.html#a77c911dbe24c5a51aaea88250895dba4',1,'core_mqtt.c']]], + ['mqtt_5funsubscribe_99',['MQTT_UNSUBSCRIBE',['../core__mqtt__serializer_8c.html#a92e39b92b76d439a183fc6f5e300195fa94eb5b78f584ff379c799a142b03e7a7',1,'core_mqtt_serializer.c']]], + ['mqtt_5funsubscribe_100',['MQTT_Unsubscribe',['../core__mqtt_8h.html#a77c911dbe24c5a51aaea88250895dba4',1,'MQTT_Unsubscribe(): core_mqtt.c'],['../mqtt_unsubscribe_function.html',1,'mqtt_functions']]], + ['mqtt_5fupdatestateack_101',['MQTT_UpdateStateAck',['../core__mqtt__state_8c.html#a09a013b709085ffd51faa33c067cce1f',1,'core_mqtt_state.c']]], + ['mqtt_5fupdatestatepublish_102',['MQTT_UpdateStatePublish',['../core__mqtt__state_8c.html#ad657bd67745c66bc50f0441b4cc94763',1,'core_mqtt_state.c']]], + ['mqtt_5fversion_5f3_5f1_5f1_103',['MQTT_VERSION_3_1_1',['../core__mqtt__serializer_8c.html#a7c621dd360dd439f0d6d8dc5d951a619',1,'core_mqtt_serializer.c']]], + ['mqttbadparameter_104',['MQTTBadParameter',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa39030c93b0263b2699502a074f003b5',1,'core_mqtt_serializer.h']]], + ['mqttbadresponse_105',['MQTTBadResponse',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa5d7507e7664a14d63a8bc44b280093e',1,'core_mqtt_serializer.h']]], + ['mqttconnected_106',['MQTTConnected',['../group__mqtt__enum__types.html#gga9f84d003695205cf10a7bd0bafb3dbf6a82c8f64d976734e5632e5257bc429ef5',1,'core_mqtt.h']]], + ['mqttconnectinfo_5ft_107',['MQTTConnectInfo_t',['../struct_m_q_t_t_connect_info__t.html',1,'']]], + ['mqttconnectionstatus_5ft_108',['MQTTConnectionStatus_t',['../group__mqtt__enum__types.html#ga9f84d003695205cf10a7bd0bafb3dbf6',1,'core_mqtt.h']]], + ['mqttcontext_5ft_109',['MQTTContext_t',['../struct_m_q_t_t_context__t.html',1,'']]], + ['mqttdeserializedinfo_5ft_110',['MQTTDeserializedInfo_t',['../struct_m_q_t_t_deserialized_info__t.html',1,'']]], + ['mqtteventcallback_5ft_111',['MQTTEventCallback_t',['../group__mqtt__callback__types.html#ga00d348277ed4fde23c95bfc749ae954a',1,'core_mqtt.h']]], + ['mqttfixedbuffer_5ft_112',['MQTTFixedBuffer_t',['../struct_m_q_t_t_fixed_buffer__t.html',1,'']]], + ['mqttgetcurrenttimefunc_5ft_113',['MQTTGetCurrentTimeFunc_t',['../group__mqtt__callback__types.html#gae3bea55b0e49e5208b8c5709a5ea23aa',1,'core_mqtt.h']]], + ['mqttillegalstate_114',['MQTTIllegalState',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca67905d7a05f98faa557a73eb5092bd8f',1,'core_mqtt_serializer.h']]], + ['mqttkeepalivetimeout_115',['MQTTKeepAliveTimeout',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca076ca8965e836a06e707a94adb26144f',1,'core_mqtt_serializer.h']]], + ['mqttneedmorebytes_116',['MQTTNeedMoreBytes',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa97df53014d919df5ecd54398f89f9b9',1,'core_mqtt_serializer.h']]], + ['mqttnodataavailable_117',['MQTTNoDataAvailable',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca676f21c0ddf297ae3ec874bc829aa957',1,'core_mqtt_serializer.h']]], + ['mqttnomemory_118',['MQTTNoMemory',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735cab1be4db832a0468f024243bca151a8df',1,'core_mqtt_serializer.h']]], + ['mqttnotconnected_119',['MQTTNotConnected',['../group__mqtt__enum__types.html#gga9f84d003695205cf10a7bd0bafb3dbf6a0320177ebf1f1b2e24646b44702cec69',1,'core_mqtt.h']]], + ['mqttpacketinfo_5ft_120',['MQTTPacketInfo_t',['../struct_m_q_t_t_packet_info__t.html',1,'']]], + ['mqttpuback_121',['MQTTPuback',['../group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a53d5939c680962f37c15ee87ffd63d0f',1,'core_mqtt.h']]], + ['mqttpubackinfo_5ft_122',['MQTTPubAckInfo_t',['../struct_m_q_t_t_pub_ack_info__t.html',1,'']]], + ['mqttpubackpending_123',['MQTTPubAckPending',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94ab086c55acf106cdc8d420f90899b6803',1,'core_mqtt.h']]], + ['mqttpubacksend_124',['MQTTPubAckSend',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a65f6f7b343a30fc0558e3aeeb8c97f35',1,'core_mqtt.h']]], + ['mqttpubacktype_5ft_125',['MQTTPubAckType_t',['../group__mqtt__enum__types.html#ga8c1bee959b3ed5fab2a2688dd72bf237',1,'core_mqtt.h']]], + ['mqttpubcomp_126',['MQTTPubcomp',['../group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a910c34311ad6a2341afc04839e1c13bd',1,'core_mqtt.h']]], + ['mqttpubcomppending_127',['MQTTPubCompPending',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a3281a28d1829d954b596f091b547b627',1,'core_mqtt.h']]], + ['mqttpubcompsend_128',['MQTTPubCompSend',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a7d88904d550b502b4424a41aa4205e56',1,'core_mqtt.h']]], + ['mqttpublishdone_129',['MQTTPublishDone',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94ad07733793a235ef9a6a04d16637cd7dc',1,'core_mqtt.h']]], + ['mqttpublishinfo_5ft_130',['MQTTPublishInfo_t',['../struct_m_q_t_t_publish_info__t.html',1,'']]], + ['mqttpublishsend_131',['MQTTPublishSend',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a896b1507647b504c9208580e4cde26ad',1,'core_mqtt.h']]], + ['mqttpublishstate_5ft_132',['MQTTPublishState_t',['../group__mqtt__enum__types.html#ga0480de7552eedd739a26a23fa8e6fd94',1,'core_mqtt.h']]], + ['mqttpubrec_133',['MQTTPubrec',['../group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a8c98d5d1a68dda33d9039009ab4ef053',1,'core_mqtt.h']]], + ['mqttpubrecpending_134',['MQTTPubRecPending',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a1bea59454700be9b683b7eb8aaf6bb4f',1,'core_mqtt.h']]], + ['mqttpubrecsend_135',['MQTTPubRecSend',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a11e2319a2b25b82121471743d39761e1',1,'core_mqtt.h']]], + ['mqttpubrel_136',['MQTTPubrel',['../group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237af2d737088a231c88e7603acfdbc4fc8c',1,'core_mqtt.h']]], + ['mqttpubrelpending_137',['MQTTPubRelPending',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a695431cde1dc9dc5a2dcbd10eba49df2',1,'core_mqtt.h']]], + ['mqttpubrelsend_138',['MQTTPubRelSend',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a5d2ee2709c6dc7a1eb8b9c40f318909b',1,'core_mqtt.h']]], + ['mqttqos0_139',['MQTTQoS0',['../group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aaad51b23a1ae1417f96d8f343c788d1d2',1,'core_mqtt_serializer.h']]], + ['mqttqos1_140',['MQTTQoS1',['../group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aa019d0b8a8cfadb6f98462b046bdacbb2',1,'core_mqtt_serializer.h']]], + ['mqttqos2_141',['MQTTQoS2',['../group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aa85e04ac0465cbdef6dd69ff71b2bbfbb',1,'core_mqtt_serializer.h']]], + ['mqttqos_5ft_142',['MQTTQoS_t',['../group__mqtt__enum__types.html#gae308a5928d7f537379c29a894228093a',1,'core_mqtt_serializer.h']]], + ['mqttrecvfailed_143',['MQTTRecvFailed',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa14bc8aa4ad218702d782366945d43ac',1,'core_mqtt_serializer.h']]], + ['mqttsendfailed_144',['MQTTSendFailed',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735cafd06b63fe9677fa2af06b0f4c7d4ad55',1,'core_mqtt_serializer.h']]], + ['mqttserverrefused_145',['MQTTServerRefused',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca25a3d1747e308e99daa805fe576f84b9',1,'core_mqtt_serializer.h']]], + ['mqttstatecollision_146',['MQTTStateCollision',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca8d05b92240dea6df08eab5a9e3799c11',1,'core_mqtt_serializer.h']]], + ['mqttstatecursor_5ft_147',['MQTTStateCursor_t',['../group__mqtt__basic__types.html#ga2ca7d486d83fe555953a8c7876ee0d6e',1,'core_mqtt_state.h']]], + ['mqttstatenull_148',['MQTTStateNull',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a8349567b7a9efb3913a64a8f4f6fe5c9',1,'core_mqtt.h']]], + ['mqttstatus_5ft_149',['MQTTStatus_t',['../group__mqtt__enum__types.html#gaba7ec045874a1c3432f99173367f735c',1,'core_mqtt_serializer.h']]], + ['mqttsubackfailure_150',['MQTTSubAckFailure',['../group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611aeb83b20da8eda934cde6b92db225a808',1,'core_mqtt.h']]], + ['mqttsubackstatus_5ft_151',['MQTTSubAckStatus_t',['../group__mqtt__enum__types.html#ga48dabc1579e3c0ac6058ce9068054611',1,'core_mqtt.h']]], + ['mqttsubacksuccessqos0_152',['MQTTSubAckSuccessQos0',['../group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611abcc3040d7d53025baee3542c40758abb',1,'core_mqtt.h']]], + ['mqttsubacksuccessqos1_153',['MQTTSubAckSuccessQos1',['../group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611ab180361a6da712c8144d8c499537787d',1,'core_mqtt.h']]], + ['mqttsubacksuccessqos2_154',['MQTTSubAckSuccessQos2',['../group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611a877b2afbc6ec7d9ab57d4862caadf4f1',1,'core_mqtt.h']]], + ['mqttsubscribeinfo_5ft_155',['MQTTSubscribeInfo_t',['../struct_m_q_t_t_subscribe_info__t.html',1,'']]], + ['mqttsubscriptiontype_5ft_156',['MQTTSubscriptionType_t',['../core__mqtt__serializer_8c.html#a92e39b92b76d439a183fc6f5e300195f',1,'core_mqtt_serializer.c']]], + ['mqttsuccess_157',['MQTTSuccess',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca484e062cb4f3fccc1858dd25cfeee056',1,'core_mqtt_serializer.h']]] +]; diff --git a/latest/coreMQTT/search/all_c.js b/latest/coreMQTT/search/all_c.js new file mode 100644 index 00000000..0b6647b3 --- /dev/null +++ b/latest/coreMQTT/search/all_c.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['networkbuffer_0',['networkBuffer',['../struct_m_q_t_t_context__t.html#a231c5576a6ce389317a3f00f95628276',1,'MQTTContext_t']]], + ['networkcontext_5ft_1',['NetworkContext_t',['../group__mqtt__struct__types.html#ga7769e434e7811caed8cd6fd7f9ec26ec',1,'transport_interface.h']]], + ['nextpacketid_2',['nextPacketId',['../struct_m_q_t_t_context__t.html#af47ed55ad7e9bb112324f5f209b70534',1,'MQTTContext_t']]] +]; diff --git a/latest/coreMQTT/search/all_d.js b/latest/coreMQTT/search/all_d.js new file mode 100644 index 00000000..614d1aba --- /dev/null +++ b/latest/coreMQTT/search/all_d.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['outgoingpublishrecordmaxcount_0',['outgoingPublishRecordMaxCount',['../struct_m_q_t_t_context__t.html#a2851073e252d1e744596272ef13dd14a',1,'MQTTContext_t']]], + ['outgoingpublishrecords_1',['outgoingPublishRecords',['../struct_m_q_t_t_context__t.html#a4ea1e37e0e81f010fbf84365ac2ef6de',1,'MQTTContext_t']]], + ['overview_2',['Overview',['../index.html',1,'']]] +]; diff --git a/latest/coreMQTT/search/all_e.js b/latest/coreMQTT/search/all_e.js new file mode 100644 index 00000000..b91e420b --- /dev/null +++ b/latest/coreMQTT/search/all_e.js @@ -0,0 +1,25 @@ +var searchData= +[ + ['packet_5frx_5ftimeout_5fms_0',['PACKET_RX_TIMEOUT_MS',['../core__mqtt__config__defaults_8h.html#a46ef647d5a8315f626dc17d62e264aed',1,'core_mqtt_config_defaults.h']]], + ['packet_5ftx_5ftimeout_5fms_1',['PACKET_TX_TIMEOUT_MS',['../core__mqtt__config__defaults_8h.html#a9b3c7c33badcafec477a205d916424bc',1,'core_mqtt_config_defaults.h']]], + ['packetid_2',['packetId',['../struct_m_q_t_t_pub_ack_info__t.html#a66cef7b43af5d7fdd33b5d2dc766b2d0',1,'MQTTPubAckInfo_t']]], + ['packetidentifier_3',['packetIdentifier',['../struct_m_q_t_t_deserialized_info__t.html#af4df2a9926a4a68059195daa712d9b84',1,'MQTTDeserializedInfo_t']]], + ['parameter_20structures_4',['Parameter Structures',['../group__mqtt__struct__types.html',1,'']]], + ['passwordlength_5',['passwordLength',['../struct_m_q_t_t_connect_info__t.html#a818c4e212a12020a4109eb890ec96383',1,'MQTTConnectInfo_t']]], + ['payloadlength_6',['payloadLength',['../struct_m_q_t_t_publish_info__t.html#a7997964e11571f35f0c3b729db0f760f',1,'MQTTPublishInfo_t']]], + ['pbuffer_7',['pBuffer',['../struct_m_q_t_t_fixed_buffer__t.html#acea147448e044870fb36b7fa2347dbd6',1,'MQTTFixedBuffer_t']]], + ['pclientidentifier_8',['pClientIdentifier',['../struct_m_q_t_t_connect_info__t.html#a010f8f6993cbf8899648d5c515ff7884',1,'MQTTConnectInfo_t']]], + ['pingreqsendtimems_9',['pingReqSendTimeMs',['../struct_m_q_t_t_context__t.html#acca3efa4146d85f7e874c7c326e23556',1,'MQTTContext_t']]], + ['pnetworkcontext_10',['pNetworkContext',['../struct_transport_interface__t.html#aaf4702050bef8d62714a4d3900e95087',1,'TransportInterface_t']]], + ['porting_20guide_11',['Porting Guide',['../mqtt_porting.html',1,'']]], + ['ppassword_12',['pPassword',['../struct_m_q_t_t_connect_info__t.html#acec6c79a11d2f0f130802393f34d2b5e',1,'MQTTConnectInfo_t']]], + ['ppayload_13',['pPayload',['../struct_m_q_t_t_publish_info__t.html#afc28299f4f625f5e674bb61b42f03380',1,'MQTTPublishInfo_t']]], + ['ppublishinfo_14',['pPublishInfo',['../struct_m_q_t_t_deserialized_info__t.html#ac347273fae1e92b9cbeda1714066c1de',1,'MQTTDeserializedInfo_t']]], + ['premainingdata_15',['pRemainingData',['../struct_m_q_t_t_packet_info__t.html#ac66cedff052bc844ec9b296387df60bc',1,'MQTTPacketInfo_t']]], + ['processpublishflags_16',['processPublishFlags',['../core__mqtt__serializer_8c.html#a47a044115ee5df1ac7fe02d2ee37e1e0',1,'core_mqtt_serializer.c']]], + ['processremaininglength_17',['processRemainingLength',['../core__mqtt__serializer_8c.html#a8a4f72e05cd72fa57ba5a90e204569b3',1,'core_mqtt_serializer.c']]], + ['ptopicfilter_18',['pTopicFilter',['../struct_m_q_t_t_subscribe_info__t.html#adb0b28240fdcd82a85f11cf2f8b5bbf0',1,'MQTTSubscribeInfo_t']]], + ['ptopicname_19',['pTopicName',['../struct_m_q_t_t_publish_info__t.html#aa80e8ca282d01630f878ad0afe81d7a4',1,'MQTTPublishInfo_t']]], + ['publishstate_20',['publishState',['../struct_m_q_t_t_pub_ack_info__t.html#a61314203ef87a231c6489c68b579de34',1,'MQTTPubAckInfo_t']]], + ['pusername_21',['pUserName',['../struct_m_q_t_t_connect_info__t.html#a1118d7d3251a11445318557280db53b4',1,'MQTTConnectInfo_t']]] +]; diff --git a/latest/coreMQTT/search/all_f.js b/latest/coreMQTT/search/all_f.js new file mode 100644 index 00000000..b55c4097 --- /dev/null +++ b/latest/coreMQTT/search/all_f.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['qos_0',['qos',['../struct_m_q_t_t_pub_ack_info__t.html#a086fcd48ef0b787697526a95c861e8a0',1,'MQTTPubAckInfo_t::qos()'],['../struct_m_q_t_t_subscribe_info__t.html#a64cf2e423f60cfec122eeaef80c0fd86',1,'MQTTSubscribeInfo_t::qos()'],['../struct_m_q_t_t_publish_info__t.html#a178224d02b4acdec7e08e88de0e4b399',1,'MQTTPublishInfo_t::qos()']]] +]; diff --git a/latest/coreMQTT/search/classes_0.js b/latest/coreMQTT/search/classes_0.js new file mode 100644 index 00000000..3abaafa4 --- /dev/null +++ b/latest/coreMQTT/search/classes_0.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['mqttconnectinfo_5ft_0',['MQTTConnectInfo_t',['../struct_m_q_t_t_connect_info__t.html',1,'']]], + ['mqttcontext_5ft_1',['MQTTContext_t',['../struct_m_q_t_t_context__t.html',1,'']]], + ['mqttdeserializedinfo_5ft_2',['MQTTDeserializedInfo_t',['../struct_m_q_t_t_deserialized_info__t.html',1,'']]], + ['mqttfixedbuffer_5ft_3',['MQTTFixedBuffer_t',['../struct_m_q_t_t_fixed_buffer__t.html',1,'']]], + ['mqttpacketinfo_5ft_4',['MQTTPacketInfo_t',['../struct_m_q_t_t_packet_info__t.html',1,'']]], + ['mqttpubackinfo_5ft_5',['MQTTPubAckInfo_t',['../struct_m_q_t_t_pub_ack_info__t.html',1,'']]], + ['mqttpublishinfo_5ft_6',['MQTTPublishInfo_t',['../struct_m_q_t_t_publish_info__t.html',1,'']]], + ['mqttsubscribeinfo_5ft_7',['MQTTSubscribeInfo_t',['../struct_m_q_t_t_subscribe_info__t.html',1,'']]] +]; diff --git a/latest/coreMQTT/search/classes_1.js b/latest/coreMQTT/search/classes_1.js new file mode 100644 index 00000000..46dbff17 --- /dev/null +++ b/latest/coreMQTT/search/classes_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['transportinterface_5ft_0',['TransportInterface_t',['../struct_transport_interface__t.html',1,'']]], + ['transportoutvector_5ft_1',['TransportOutVector_t',['../struct_transport_out_vector__t.html',1,'']]] +]; diff --git a/latest/coreMQTT/search/close.svg b/latest/coreMQTT/search/close.svg new file mode 100644 index 00000000..a933eea1 --- /dev/null +++ b/latest/coreMQTT/search/close.svg @@ -0,0 +1,31 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/latest/coreMQTT/search/defines_0.js b/latest/coreMQTT/search/defines_0.js new file mode 100644 index 00000000..9ba21c3e --- /dev/null +++ b/latest/coreMQTT/search/defines_0.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['core_5fmqtt_5fserialized_5flength_5ffield_5fbytes_0',['CORE_MQTT_SERIALIZED_LENGTH_FIELD_BYTES',['../core__mqtt_8c.html#a989426922a1f5f04ea8b612fd1f4b185',1,'core_mqtt.c']]], + ['core_5fmqtt_5fsubscribe_5fper_5ftopic_5fvector_5flength_1',['CORE_MQTT_SUBSCRIBE_PER_TOPIC_VECTOR_LENGTH',['../core__mqtt_8c.html#a97f180c9cc32ca9e354e7c22378a386b',1,'core_mqtt.c']]], + ['core_5fmqtt_5funsubscribe_5fper_5ftopic_5fvector_5flength_2',['CORE_MQTT_UNSUBSCRIBE_PER_TOPIC_VECTOR_LENGTH',['../core__mqtt_8c.html#a42477ec456354f2b944b47646ee5a9ce',1,'core_mqtt.c']]] +]; diff --git a/latest/coreMQTT/search/defines_1.js b/latest/coreMQTT/search/defines_1.js new file mode 100644 index 00000000..635f7dea --- /dev/null +++ b/latest/coreMQTT/search/defines_1.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['logdebug_0',['LogDebug',['../core__mqtt__config__defaults_8h.html#af60e8ffc327d136e5d0d8441ed98c98d',1,'core_mqtt_config_defaults.h']]], + ['logerror_1',['LogError',['../core__mqtt__config__defaults_8h.html#a8d9dbaaa88129137a4c68ba0456a18b1',1,'core_mqtt_config_defaults.h']]], + ['loginfo_2',['LogInfo',['../core__mqtt__config__defaults_8h.html#a00810b1cb9d2f25d25ce2d4d93815fba',1,'core_mqtt_config_defaults.h']]], + ['logwarn_3',['LogWarn',['../core__mqtt__config__defaults_8h.html#a7da92048aaf0cbfcacde9539c98a0e05',1,'core_mqtt_config_defaults.h']]] +]; diff --git a/latest/coreMQTT/search/defines_2.js b/latest/coreMQTT/search/defines_2.js new file mode 100644 index 00000000..ad224fad --- /dev/null +++ b/latest/coreMQTT/search/defines_2.js @@ -0,0 +1,36 @@ +var searchData= +[ + ['mqtt_5fconnect_5fflag_5fclean_0',['MQTT_CONNECT_FLAG_CLEAN',['../core__mqtt__serializer_8c.html#a1b131e766e003e36fe499d9f6a79fc03',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fpassword_1',['MQTT_CONNECT_FLAG_PASSWORD',['../core__mqtt__serializer_8c.html#ac5f0bb47789c1182392f5029e0238a81',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fusername_2',['MQTT_CONNECT_FLAG_USERNAME',['../core__mqtt__serializer_8c.html#a8d23d14a4cf296feffb9db79728dd1d0',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fwill_3',['MQTT_CONNECT_FLAG_WILL',['../core__mqtt__serializer_8c.html#a04d8c55ea2b595a277cbcd4340e36d6c',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fwill_5fqos1_4',['MQTT_CONNECT_FLAG_WILL_QOS1',['../core__mqtt__serializer_8c.html#a2aee739b1fa7e61feb907bc92a73c3b4',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fwill_5fqos2_5',['MQTT_CONNECT_FLAG_WILL_QOS2',['../core__mqtt__serializer_8c.html#ac750789b338a2b9be75725ab340dabce',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fwill_5fretain_6',['MQTT_CONNECT_FLAG_WILL_RETAIN',['../core__mqtt__serializer_8c.html#a8ae294d4ca7960920816339fedbdc4a0',1,'core_mqtt_serializer.c']]], + ['mqtt_5fdisconnect_5fpacket_5fsize_7',['MQTT_DISCONNECT_PACKET_SIZE',['../core__mqtt__serializer_8c.html#abdcffcd69d858203747236b5c4afa834',1,'core_mqtt_serializer.c']]], + ['mqtt_5fdisconnect_5fremaining_5flength_8',['MQTT_DISCONNECT_REMAINING_LENGTH',['../core__mqtt__serializer_8c.html#ac4f3ff016aa6011e3fc707b9f27f6b8c',1,'core_mqtt_serializer.c']]], + ['mqtt_5fdo_5fnot_5fuse_5fcustom_5fconfig_9',['MQTT_DO_NOT_USE_CUSTOM_CONFIG',['../core__mqtt__config__defaults_8h.html#abd12bb401eecf3f6694447ea3b1c886d',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5finvalid_5fstate_5fcount_10',['MQTT_INVALID_STATE_COUNT',['../core__mqtt__state_8c.html#a49d2236ebe2b3d27e82e54a7b9e74984',1,'core_mqtt_state.c']]], + ['mqtt_5fmax_5fconnack_5freceive_5fretry_5fcount_11',['MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT',['../core__mqtt__config__defaults_8h.html#a8ca6c96436d5e7c2c8a7933fb28a5c87',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5fmax_5fremaining_5flength_12',['MQTT_MAX_REMAINING_LENGTH',['../core__mqtt__serializer_8c.html#a9d9ea40a1ff486557a553523a0743647',1,'core_mqtt_serializer.c']]], + ['mqtt_5fmin_5fpublish_5fremaining_5flength_5fqos0_13',['MQTT_MIN_PUBLISH_REMAINING_LENGTH_QOS0',['../core__mqtt__serializer_8c.html#a3b8709529a24bc195c7310183ffbcc2b',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fconnack_5fremaining_5flength_14',['MQTT_PACKET_CONNACK_REMAINING_LENGTH',['../core__mqtt__serializer_8c.html#a999c4ebc0d629df9b08a3c88107b5b80',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fconnack_5fsession_5fpresent_5fmask_15',['MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK',['../core__mqtt__serializer_8c.html#aab69dd14c12f8086245c2371288944f0',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fconnect_5fheader_5fsize_16',['MQTT_PACKET_CONNECT_HEADER_SIZE',['../core__mqtt__serializer_8c.html#aa7c310cb084af0025c356ed844ae443d',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fpingreq_5fsize_17',['MQTT_PACKET_PINGREQ_SIZE',['../core__mqtt__serializer_8c.html#a6e8a49d0d88f0b038a5379d533858103',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fpingresp_5fremaining_5flength_18',['MQTT_PACKET_PINGRESP_REMAINING_LENGTH',['../core__mqtt__serializer_8c.html#aeab5c92e86ed98750cbf6422b8b57c06',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fsimple_5fack_5fremaining_5flength_19',['MQTT_PACKET_SIMPLE_ACK_REMAINING_LENGTH',['../core__mqtt__serializer_8c.html#a4c576df64bca769a91cb64d5d5d86505',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpingresp_5ftimeout_5fms_20',['MQTT_PINGRESP_TIMEOUT_MS',['../core__mqtt__config__defaults_8h.html#afa825fddb52da7df88fb56d2befcd2fa',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5fpost_5fsend_5fhook_21',['MQTT_POST_SEND_HOOK',['../core__mqtt_8c.html#a205b7112b6bb0697f85b9e25512c67be',1,'core_mqtt.c']]], + ['mqtt_5fpost_5fstate_5fupdate_5fhook_22',['MQTT_POST_STATE_UPDATE_HOOK',['../core__mqtt_8c.html#a436983fba04e3d13cabea35efc4e9bf8',1,'core_mqtt.c']]], + ['mqtt_5fpre_5fsend_5fhook_23',['MQTT_PRE_SEND_HOOK',['../core__mqtt_8c.html#a18f9369f0d6d553db6d1af1bd7156545',1,'core_mqtt.c']]], + ['mqtt_5fpre_5fstate_5fupdate_5fhook_24',['MQTT_PRE_STATE_UPDATE_HOOK',['../core__mqtt_8c.html#acba4b6e51723d384aa9140313effdf8b',1,'core_mqtt.c']]], + ['mqtt_5fpublish_5fflag_5fdup_25',['MQTT_PUBLISH_FLAG_DUP',['../core__mqtt__serializer_8c.html#a57c437ecc3720de76093b08eb0d4f813',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpublish_5fflag_5fqos1_26',['MQTT_PUBLISH_FLAG_QOS1',['../core__mqtt__serializer_8c.html#ac23212835606fade167fb5ce25eaf103',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpublish_5fflag_5fqos2_27',['MQTT_PUBLISH_FLAG_QOS2',['../core__mqtt__serializer_8c.html#afe1d2a0b7c0803f5a20ebb3c7a607d65',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpublish_5fflag_5fretain_28',['MQTT_PUBLISH_FLAG_RETAIN',['../core__mqtt__serializer_8c.html#a3d04b1e1ad7ec25d18fd13726e164f06',1,'core_mqtt_serializer.c']]], + ['mqtt_5frecv_5fpolling_5ftimeout_5fms_29',['MQTT_RECV_POLLING_TIMEOUT_MS',['../core__mqtt__config__defaults_8h.html#a43dc9a67427d9e420a65955eea0e2671',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5fremaining_5flength_5finvalid_30',['MQTT_REMAINING_LENGTH_INVALID',['../core__mqtt__serializer_8c.html#a6f6b43661df6f9e9e9e7123ab01e9eb5',1,'core_mqtt_serializer.c']]], + ['mqtt_5fsend_5ftimeout_5fms_31',['MQTT_SEND_TIMEOUT_MS',['../core__mqtt__config__defaults_8h.html#ac262cab68c4c713ebc2b91a2e4ab8b19',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5fversion_5f3_5f1_5f1_32',['MQTT_VERSION_3_1_1',['../core__mqtt__serializer_8c.html#a7c621dd360dd439f0d6d8dc5d951a619',1,'core_mqtt_serializer.c']]] +]; diff --git a/latest/coreMQTT/search/defines_3.js b/latest/coreMQTT/search/defines_3.js new file mode 100644 index 00000000..b28dafae --- /dev/null +++ b/latest/coreMQTT/search/defines_3.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['packet_5frx_5ftimeout_5fms_0',['PACKET_RX_TIMEOUT_MS',['../core__mqtt__config__defaults_8h.html#a46ef647d5a8315f626dc17d62e264aed',1,'core_mqtt_config_defaults.h']]], + ['packet_5ftx_5ftimeout_5fms_1',['PACKET_TX_TIMEOUT_MS',['../core__mqtt__config__defaults_8h.html#a9b3c7c33badcafec477a205d916424bc',1,'core_mqtt_config_defaults.h']]] +]; diff --git a/latest/coreMQTT/search/defines_4.js b/latest/coreMQTT/search/defines_4.js new file mode 100644 index 00000000..bec633d1 --- /dev/null +++ b/latest/coreMQTT/search/defines_4.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['uint16_5fbitmap_5fbit_5fset_5fat_0',['UINT16_BITMAP_BIT_SET_AT',['../core__mqtt__state_8c.html#a50892214c51968df798f584272f16a17',1,'core_mqtt_state.c']]], + ['uint16_5fcheck_5fbit_1',['UINT16_CHECK_BIT',['../core__mqtt__state_8c.html#a085ab1307745f304ce2e6d24bdc3f6a7',1,'core_mqtt_state.c']]], + ['uint16_5fdecode_2',['UINT16_DECODE',['../core__mqtt__serializer_8c.html#acc849aa739edff3ec532219a3860a3a0',1,'core_mqtt_serializer.c']]], + ['uint16_5fhigh_5fbyte_3',['UINT16_HIGH_BYTE',['../core__mqtt__serializer_8c.html#a24aab781ef139dd38be534ee137ea2f9',1,'core_mqtt_serializer.c']]], + ['uint16_5flow_5fbyte_4',['UINT16_LOW_BYTE',['../core__mqtt__serializer_8c.html#af2ae35b27e0140a77238cd175508cb4e',1,'core_mqtt_serializer.c']]], + ['uint16_5fset_5fbit_5',['UINT16_SET_BIT',['../core__mqtt__state_8c.html#acd96521b31682b7d93de544704fd9594',1,'core_mqtt_state.c']]], + ['uint8_5fcheck_5fbit_6',['UINT8_CHECK_BIT',['../core__mqtt__serializer_8c.html#a07cc5f3f934e1ebf8011a6c15a667206',1,'core_mqtt_serializer.c']]], + ['uint8_5fset_5fbit_7',['UINT8_SET_BIT',['../core__mqtt__serializer_8c.html#af259c91b3075c24df53fa3ffe516b208',1,'core_mqtt_serializer.c']]] +]; diff --git a/latest/coreMQTT/search/enums_0.js b/latest/coreMQTT/search/enums_0.js new file mode 100644 index 00000000..7f127dd8 --- /dev/null +++ b/latest/coreMQTT/search/enums_0.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['mqttconnectionstatus_5ft_0',['MQTTConnectionStatus_t',['../group__mqtt__enum__types.html#ga9f84d003695205cf10a7bd0bafb3dbf6',1,'core_mqtt.h']]], + ['mqttpubacktype_5ft_1',['MQTTPubAckType_t',['../group__mqtt__enum__types.html#ga8c1bee959b3ed5fab2a2688dd72bf237',1,'core_mqtt.h']]], + ['mqttpublishstate_5ft_2',['MQTTPublishState_t',['../group__mqtt__enum__types.html#ga0480de7552eedd739a26a23fa8e6fd94',1,'core_mqtt.h']]], + ['mqttqos_5ft_3',['MQTTQoS_t',['../group__mqtt__enum__types.html#gae308a5928d7f537379c29a894228093a',1,'core_mqtt_serializer.h']]], + ['mqttstatus_5ft_4',['MQTTStatus_t',['../group__mqtt__enum__types.html#gaba7ec045874a1c3432f99173367f735c',1,'core_mqtt_serializer.h']]], + ['mqttsubackstatus_5ft_5',['MQTTSubAckStatus_t',['../group__mqtt__enum__types.html#ga48dabc1579e3c0ac6058ce9068054611',1,'core_mqtt.h']]], + ['mqttsubscriptiontype_5ft_6',['MQTTSubscriptionType_t',['../core__mqtt__serializer_8c.html#a92e39b92b76d439a183fc6f5e300195f',1,'core_mqtt_serializer.c']]] +]; diff --git a/latest/coreMQTT/search/enumvalues_0.js b/latest/coreMQTT/search/enumvalues_0.js new file mode 100644 index 00000000..01a3695f --- /dev/null +++ b/latest/coreMQTT/search/enumvalues_0.js @@ -0,0 +1,41 @@ +var searchData= +[ + ['mqtt_5fsubscribe_0',['MQTT_SUBSCRIBE',['../core__mqtt__serializer_8c.html#a92e39b92b76d439a183fc6f5e300195fa7dd20d5d68728190c8c1050599b562f7',1,'core_mqtt_serializer.c']]], + ['mqtt_5funsubscribe_1',['MQTT_UNSUBSCRIBE',['../core__mqtt__serializer_8c.html#a92e39b92b76d439a183fc6f5e300195fa94eb5b78f584ff379c799a142b03e7a7',1,'core_mqtt_serializer.c']]], + ['mqttbadparameter_2',['MQTTBadParameter',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa39030c93b0263b2699502a074f003b5',1,'core_mqtt_serializer.h']]], + ['mqttbadresponse_3',['MQTTBadResponse',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa5d7507e7664a14d63a8bc44b280093e',1,'core_mqtt_serializer.h']]], + ['mqttconnected_4',['MQTTConnected',['../group__mqtt__enum__types.html#gga9f84d003695205cf10a7bd0bafb3dbf6a82c8f64d976734e5632e5257bc429ef5',1,'core_mqtt.h']]], + ['mqttillegalstate_5',['MQTTIllegalState',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca67905d7a05f98faa557a73eb5092bd8f',1,'core_mqtt_serializer.h']]], + ['mqttkeepalivetimeout_6',['MQTTKeepAliveTimeout',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca076ca8965e836a06e707a94adb26144f',1,'core_mqtt_serializer.h']]], + ['mqttneedmorebytes_7',['MQTTNeedMoreBytes',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa97df53014d919df5ecd54398f89f9b9',1,'core_mqtt_serializer.h']]], + ['mqttnodataavailable_8',['MQTTNoDataAvailable',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca676f21c0ddf297ae3ec874bc829aa957',1,'core_mqtt_serializer.h']]], + ['mqttnomemory_9',['MQTTNoMemory',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735cab1be4db832a0468f024243bca151a8df',1,'core_mqtt_serializer.h']]], + ['mqttnotconnected_10',['MQTTNotConnected',['../group__mqtt__enum__types.html#gga9f84d003695205cf10a7bd0bafb3dbf6a0320177ebf1f1b2e24646b44702cec69',1,'core_mqtt.h']]], + ['mqttpuback_11',['MQTTPuback',['../group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a53d5939c680962f37c15ee87ffd63d0f',1,'core_mqtt.h']]], + ['mqttpubackpending_12',['MQTTPubAckPending',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94ab086c55acf106cdc8d420f90899b6803',1,'core_mqtt.h']]], + ['mqttpubacksend_13',['MQTTPubAckSend',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a65f6f7b343a30fc0558e3aeeb8c97f35',1,'core_mqtt.h']]], + ['mqttpubcomp_14',['MQTTPubcomp',['../group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a910c34311ad6a2341afc04839e1c13bd',1,'core_mqtt.h']]], + ['mqttpubcomppending_15',['MQTTPubCompPending',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a3281a28d1829d954b596f091b547b627',1,'core_mqtt.h']]], + ['mqttpubcompsend_16',['MQTTPubCompSend',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a7d88904d550b502b4424a41aa4205e56',1,'core_mqtt.h']]], + ['mqttpublishdone_17',['MQTTPublishDone',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94ad07733793a235ef9a6a04d16637cd7dc',1,'core_mqtt.h']]], + ['mqttpublishsend_18',['MQTTPublishSend',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a896b1507647b504c9208580e4cde26ad',1,'core_mqtt.h']]], + ['mqttpubrec_19',['MQTTPubrec',['../group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a8c98d5d1a68dda33d9039009ab4ef053',1,'core_mqtt.h']]], + ['mqttpubrecpending_20',['MQTTPubRecPending',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a1bea59454700be9b683b7eb8aaf6bb4f',1,'core_mqtt.h']]], + ['mqttpubrecsend_21',['MQTTPubRecSend',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a11e2319a2b25b82121471743d39761e1',1,'core_mqtt.h']]], + ['mqttpubrel_22',['MQTTPubrel',['../group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237af2d737088a231c88e7603acfdbc4fc8c',1,'core_mqtt.h']]], + ['mqttpubrelpending_23',['MQTTPubRelPending',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a695431cde1dc9dc5a2dcbd10eba49df2',1,'core_mqtt.h']]], + ['mqttpubrelsend_24',['MQTTPubRelSend',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a5d2ee2709c6dc7a1eb8b9c40f318909b',1,'core_mqtt.h']]], + ['mqttqos0_25',['MQTTQoS0',['../group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aaad51b23a1ae1417f96d8f343c788d1d2',1,'core_mqtt_serializer.h']]], + ['mqttqos1_26',['MQTTQoS1',['../group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aa019d0b8a8cfadb6f98462b046bdacbb2',1,'core_mqtt_serializer.h']]], + ['mqttqos2_27',['MQTTQoS2',['../group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aa85e04ac0465cbdef6dd69ff71b2bbfbb',1,'core_mqtt_serializer.h']]], + ['mqttrecvfailed_28',['MQTTRecvFailed',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa14bc8aa4ad218702d782366945d43ac',1,'core_mqtt_serializer.h']]], + ['mqttsendfailed_29',['MQTTSendFailed',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735cafd06b63fe9677fa2af06b0f4c7d4ad55',1,'core_mqtt_serializer.h']]], + ['mqttserverrefused_30',['MQTTServerRefused',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca25a3d1747e308e99daa805fe576f84b9',1,'core_mqtt_serializer.h']]], + ['mqttstatecollision_31',['MQTTStateCollision',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca8d05b92240dea6df08eab5a9e3799c11',1,'core_mqtt_serializer.h']]], + ['mqttstatenull_32',['MQTTStateNull',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a8349567b7a9efb3913a64a8f4f6fe5c9',1,'core_mqtt.h']]], + ['mqttsubackfailure_33',['MQTTSubAckFailure',['../group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611aeb83b20da8eda934cde6b92db225a808',1,'core_mqtt.h']]], + ['mqttsubacksuccessqos0_34',['MQTTSubAckSuccessQos0',['../group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611abcc3040d7d53025baee3542c40758abb',1,'core_mqtt.h']]], + ['mqttsubacksuccessqos1_35',['MQTTSubAckSuccessQos1',['../group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611ab180361a6da712c8144d8c499537787d',1,'core_mqtt.h']]], + ['mqttsubacksuccessqos2_36',['MQTTSubAckSuccessQos2',['../group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611a877b2afbc6ec7d9ab57d4862caadf4f1',1,'core_mqtt.h']]], + ['mqttsuccess_37',['MQTTSuccess',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca484e062cb4f3fccc1858dd25cfeee056',1,'core_mqtt_serializer.h']]] +]; diff --git a/latest/coreMQTT/search/files_0.js b/latest/coreMQTT/search/files_0.js new file mode 100644 index 00000000..65ced30d --- /dev/null +++ b/latest/coreMQTT/search/files_0.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['core_5fmqtt_2ec_0',['core_mqtt.c',['../core__mqtt_8c.html',1,'']]], + ['core_5fmqtt_2eh_1',['core_mqtt.h',['../core__mqtt_8h.html',1,'']]], + ['core_5fmqtt_5fconfig_5fdefaults_2eh_2',['core_mqtt_config_defaults.h',['../core__mqtt__config__defaults_8h.html',1,'']]], + ['core_5fmqtt_5fserializer_2ec_3',['core_mqtt_serializer.c',['../core__mqtt__serializer_8c.html',1,'']]], + ['core_5fmqtt_5fserializer_2eh_4',['core_mqtt_serializer.h',['../core__mqtt__serializer_8h.html',1,'']]], + ['core_5fmqtt_5fstate_2ec_5',['core_mqtt_state.c',['../core__mqtt__state_8c.html',1,'']]], + ['core_5fmqtt_5fstate_2eh_6',['core_mqtt_state.h',['../core__mqtt__state_8h.html',1,'']]] +]; diff --git a/latest/coreMQTT/search/files_1.js b/latest/coreMQTT/search/files_1.js new file mode 100644 index 00000000..1beeb5d6 --- /dev/null +++ b/latest/coreMQTT/search/files_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['transport_5finterface_2eh_0',['transport_interface.h',['../transport__interface_8h.html',1,'']]] +]; diff --git a/latest/coreMQTT/search/functions_0.js b/latest/coreMQTT/search/functions_0.js new file mode 100644 index 00000000..2621cb9f --- /dev/null +++ b/latest/coreMQTT/search/functions_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['addencodedstringtovector_0',['addEncodedStringToVector',['../core__mqtt_8c.html#a35952c4a02872c18702e7fbbdb1c467f',1,'core_mqtt.c']]], + ['addrecord_1',['addRecord',['../core__mqtt__state_8c.html#a5d0ffdfde0c38a1cc1d4e3f4750a8cc4',1,'core_mqtt_state.c']]] +]; diff --git a/latest/coreMQTT/search/functions_1.js b/latest/coreMQTT/search/functions_1.js new file mode 100644 index 00000000..719c44ae --- /dev/null +++ b/latest/coreMQTT/search/functions_1.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['calculateelapsedtime_0',['calculateElapsedTime',['../core__mqtt_8c.html#a04f9f5742bc28fe29e61f3f46d20d3d6',1,'core_mqtt.c']]], + ['calculatepublishpacketsize_1',['calculatePublishPacketSize',['../core__mqtt__serializer_8c.html#a76d0156e521588fb3319043f9d35ea9a',1,'core_mqtt_serializer.c']]], + ['calculatesubscriptionpacketsize_2',['calculateSubscriptionPacketSize',['../core__mqtt__serializer_8c.html#abdbabda0aa9db25166963afa975adb10',1,'core_mqtt_serializer.c']]], + ['checkpublishremaininglength_3',['checkPublishRemainingLength',['../core__mqtt__serializer_8c.html#a33a2680aab1ce2186acd7c78aeb270f1',1,'core_mqtt_serializer.c']]], + ['compactrecords_4',['compactRecords',['../core__mqtt__state_8c.html#a6cd7b86de2ddb125fee886d58d1a5fd4',1,'core_mqtt_state.c']]] +]; diff --git a/latest/coreMQTT/search/functions_2.js b/latest/coreMQTT/search/functions_2.js new file mode 100644 index 00000000..920a90c3 --- /dev/null +++ b/latest/coreMQTT/search/functions_2.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['deserializeconnack_0',['deserializeConnack',['../core__mqtt__serializer_8c.html#aa7b25e1e3114536e9b0526fc93a1f76c',1,'core_mqtt_serializer.c']]], + ['deserializepingresp_1',['deserializePingresp',['../core__mqtt__serializer_8c.html#afdd9b08562ccaa6cf8dd68baa6bc7060',1,'core_mqtt_serializer.c']]], + ['deserializepublish_2',['deserializePublish',['../core__mqtt__serializer_8c.html#a6e8bcde1280e14706e0cb9180358607c',1,'core_mqtt_serializer.c']]], + ['deserializesimpleack_3',['deserializeSimpleAck',['../core__mqtt__serializer_8c.html#a5d437c287290fa28a0ed65635fd6c9ae',1,'core_mqtt_serializer.c']]], + ['deserializesuback_4',['deserializeSuback',['../core__mqtt__serializer_8c.html#ae7b71036fc19c9a6da480dcfd3a2387b',1,'core_mqtt_serializer.c']]], + ['discardpacket_5',['discardPacket',['../core__mqtt_8c.html#abb02f1853a4805205636f2c11a435216',1,'core_mqtt.c']]], + ['discardstoredpacket_6',['discardStoredPacket',['../core__mqtt_8c.html#af827b2088c38c31a0b75dc70377db536',1,'core_mqtt.c']]] +]; diff --git a/latest/coreMQTT/search/functions_3.js b/latest/coreMQTT/search/functions_3.js new file mode 100644 index 00000000..11f3261d --- /dev/null +++ b/latest/coreMQTT/search/functions_3.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['encoderemaininglength_0',['encodeRemainingLength',['../core__mqtt__serializer_8c.html#a3a3858fbb0cbd845f208b3fc60f36130',1,'core_mqtt_serializer.c']]], + ['encodestring_1',['encodeString',['../core__mqtt__serializer_8c.html#a60e580c28431eb08f05a156949137f1f',1,'core_mqtt_serializer.c']]] +]; diff --git a/latest/coreMQTT/search/functions_4.js b/latest/coreMQTT/search/functions_4.js new file mode 100644 index 00000000..3a875e59 --- /dev/null +++ b/latest/coreMQTT/search/functions_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['findinrecord_0',['findInRecord',['../core__mqtt__state_8c.html#ac805558ac65e84ea9111ce70c873e59e',1,'core_mqtt_state.c']]] +]; diff --git a/latest/coreMQTT/search/functions_5.js b/latest/coreMQTT/search/functions_5.js new file mode 100644 index 00000000..bf76372e --- /dev/null +++ b/latest/coreMQTT/search/functions_5.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['getackfrompackettype_0',['getAckFromPacketType',['../core__mqtt_8c.html#aa1f35063dbe3b2c35f278ea6aa347a0e',1,'core_mqtt.c']]], + ['getacktypetosend_1',['getAckTypeToSend',['../core__mqtt_8c.html#a02f112e21a6d0b87a3c69ef300d264de',1,'core_mqtt.c']]], + ['getremaininglength_2',['getRemainingLength',['../core__mqtt__serializer_8c.html#a5685b753d1d42788a00bd59ffa4639e2',1,'core_mqtt_serializer.c']]] +]; diff --git a/latest/coreMQTT/search/functions_6.js b/latest/coreMQTT/search/functions_6.js new file mode 100644 index 00000000..3041f294 --- /dev/null +++ b/latest/coreMQTT/search/functions_6.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['handleincomingack_0',['handleIncomingAck',['../core__mqtt_8c.html#a264afa489cbfbd96086614d335969115',1,'core_mqtt.c']]], + ['handleincomingpublish_1',['handleIncomingPublish',['../core__mqtt_8c.html#a4ac6e6829500c4f522eae413c9470e4d',1,'core_mqtt.c']]], + ['handlekeepalive_2',['handleKeepAlive',['../core__mqtt_8c.html#ae0e50de302a1aa66e3c5b2cdcacc4f3f',1,'core_mqtt.c']]], + ['handlepublishacks_3',['handlePublishAcks',['../core__mqtt_8c.html#a2363868c0417261c27c750251aad13e5',1,'core_mqtt.c']]], + ['handlesessionresumption_4',['handleSessionResumption',['../core__mqtt_8c.html#aae9ba11e41bc1dfef340208bc49c836c',1,'core_mqtt.c']]] +]; diff --git a/latest/coreMQTT/search/functions_7.js b/latest/coreMQTT/search/functions_7.js new file mode 100644 index 00000000..adb39651 --- /dev/null +++ b/latest/coreMQTT/search/functions_7.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['incomingpacketvalid_0',['incomingPacketValid',['../core__mqtt__serializer_8c.html#a03dfebbfbc1635567839f7abb7c0f8db',1,'core_mqtt_serializer.c']]], + ['ispublishoutgoing_1',['isPublishOutgoing',['../core__mqtt__state_8c.html#aaf9d4c6e766e40189ff7b68ffea40aa0',1,'core_mqtt_state.c']]] +]; diff --git a/latest/coreMQTT/search/functions_8.js b/latest/coreMQTT/search/functions_8.js new file mode 100644 index 00000000..918f1c59 --- /dev/null +++ b/latest/coreMQTT/search/functions_8.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['logconnackresponse_0',['logConnackResponse',['../core__mqtt__serializer_8c.html#a5451f2e3468faaf2bdf85220ebb95aaa',1,'core_mqtt_serializer.c']]] +]; diff --git a/latest/coreMQTT/search/functions_9.js b/latest/coreMQTT/search/functions_9.js new file mode 100644 index 00000000..f6d9361b --- /dev/null +++ b/latest/coreMQTT/search/functions_9.js @@ -0,0 +1,52 @@ +var searchData= +[ + ['matchendwildcardsspecialcases_0',['matchEndWildcardsSpecialCases',['../core__mqtt_8c.html#ab29bb66fe7385c52452a3087bcfbc98e',1,'core_mqtt.c']]], + ['matchtopicfilter_1',['matchTopicFilter',['../core__mqtt_8c.html#a4c052d9dd6a81e866121c24a2ee2aa0b',1,'core_mqtt.c']]], + ['matchwildcards_2',['matchWildcards',['../core__mqtt_8c.html#ab1f061741c445d07454cfa03786a5eea',1,'core_mqtt.c']]], + ['mqtt_5fcalculatestateack_3',['MQTT_CalculateStateAck',['../core__mqtt__state_8c.html#a0cad28e34f03b84aff43ee243ce8e2cf',1,'core_mqtt_state.c']]], + ['mqtt_5fcalculatestatepublish_4',['MQTT_CalculateStatePublish',['../core__mqtt__state_8c.html#aadc4fdd8af74ac25b848a33e916bff50',1,'core_mqtt_state.c']]], + ['mqtt_5fcancelcallback_5',['MQTT_CancelCallback',['../core__mqtt_8h.html#a31b74c34cd295b98ed5f5b4c15ed4a8b',1,'MQTT_CancelCallback(const MQTTContext_t *pContext, uint16_t packetId): core_mqtt.c'],['../core__mqtt_8c.html#a31b74c34cd295b98ed5f5b4c15ed4a8b',1,'MQTT_CancelCallback(const MQTTContext_t *pContext, uint16_t packetId): core_mqtt.c']]], + ['mqtt_5fconnect_6',['MQTT_Connect',['../core__mqtt_8h.html#aed1e4dc123a8ba79ac569cb17c69bfa0',1,'MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent): core_mqtt.c'],['../core__mqtt_8c.html#aed1e4dc123a8ba79ac569cb17c69bfa0',1,'MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent): core_mqtt.c']]], + ['mqtt_5fdeserializeack_7',['MQTT_DeserializeAck',['../core__mqtt__serializer_8h.html#ae9971855df71edf94124116e0625bf18',1,'MQTT_DeserializeAck(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, bool *pSessionPresent): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#ae9971855df71edf94124116e0625bf18',1,'MQTT_DeserializeAck(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, bool *pSessionPresent): core_mqtt_serializer.c']]], + ['mqtt_5fdeserializepublish_8',['MQTT_DeserializePublish',['../core__mqtt__serializer_8h.html#a4c2aec031f31d0fe55c1cda46544e95a',1,'MQTT_DeserializePublish(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a4c2aec031f31d0fe55c1cda46544e95a',1,'MQTT_DeserializePublish(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo): core_mqtt_serializer.c']]], + ['mqtt_5fdisconnect_9',['MQTT_Disconnect',['../core__mqtt_8h.html#ac79c366acbc3dddd88072d99ccb9140c',1,'MQTT_Disconnect(MQTTContext_t *pContext): core_mqtt.c'],['../core__mqtt_8c.html#ac79c366acbc3dddd88072d99ccb9140c',1,'MQTT_Disconnect(MQTTContext_t *pContext): core_mqtt.c']]], + ['mqtt_5fgetconnectpacketsize_10',['MQTT_GetConnectPacketSize',['../core__mqtt__serializer_8h.html#a4e57ccef527a25b572dc66eeb2e217c5',1,'MQTT_GetConnectPacketSize(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a4e57ccef527a25b572dc66eeb2e217c5',1,'MQTT_GetConnectPacketSize(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c']]], + ['mqtt_5fgetdisconnectpacketsize_11',['MQTT_GetDisconnectPacketSize',['../core__mqtt__serializer_8h.html#a6fdd8cbde6b7c4ff85c20aaca0fd8741',1,'MQTT_GetDisconnectPacketSize(size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a6fdd8cbde6b7c4ff85c20aaca0fd8741',1,'MQTT_GetDisconnectPacketSize(size_t *pPacketSize): core_mqtt_serializer.c']]], + ['mqtt_5fgetincomingpackettypeandlength_12',['MQTT_GetIncomingPacketTypeAndLength',['../core__mqtt__serializer_8h.html#a98cdda86f86a0a1888745a584199e930',1,'MQTT_GetIncomingPacketTypeAndLength(TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a98cdda86f86a0a1888745a584199e930',1,'MQTT_GetIncomingPacketTypeAndLength(TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket): core_mqtt_serializer.c']]], + ['mqtt_5fgetpacketid_13',['MQTT_GetPacketId',['../core__mqtt_8c.html#a00e1a3eba2c21899a6b4312c7d65d090',1,'MQTT_GetPacketId(MQTTContext_t *pContext): core_mqtt.c'],['../core__mqtt_8h.html#a00e1a3eba2c21899a6b4312c7d65d090',1,'MQTT_GetPacketId(MQTTContext_t *pContext): core_mqtt.c']]], + ['mqtt_5fgetpingreqpacketsize_14',['MQTT_GetPingreqPacketSize',['../core__mqtt__serializer_8h.html#a015562f30e220d2534f773bfa45a5cfe',1,'MQTT_GetPingreqPacketSize(size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a015562f30e220d2534f773bfa45a5cfe',1,'MQTT_GetPingreqPacketSize(size_t *pPacketSize): core_mqtt_serializer.c']]], + ['mqtt_5fgetpublishpacketsize_15',['MQTT_GetPublishPacketSize',['../core__mqtt__serializer_8h.html#a9971fb98c6af22b1bfe697d44492a819',1,'MQTT_GetPublishPacketSize(const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a9971fb98c6af22b1bfe697d44492a819',1,'MQTT_GetPublishPacketSize(const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c']]], + ['mqtt_5fgetsubackstatuscodes_16',['MQTT_GetSubAckStatusCodes',['../core__mqtt_8h.html#ac43449e06856c6703cda73359c222bd2',1,'MQTT_GetSubAckStatusCodes(const MQTTPacketInfo_t *pSubackPacket, uint8_t **pPayloadStart, size_t *pPayloadSize): core_mqtt.c'],['../core__mqtt_8c.html#ac43449e06856c6703cda73359c222bd2',1,'MQTT_GetSubAckStatusCodes(const MQTTPacketInfo_t *pSubackPacket, uint8_t **pPayloadStart, size_t *pPayloadSize): core_mqtt.c']]], + ['mqtt_5fgetsubscribepacketsize_17',['MQTT_GetSubscribePacketSize',['../core__mqtt__serializer_8h.html#abb9a703cb23ab39fdd6fe282a5f3ddc5',1,'MQTT_GetSubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#abb9a703cb23ab39fdd6fe282a5f3ddc5',1,'MQTT_GetSubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c']]], + ['mqtt_5fgetunsubscribepacketsize_18',['MQTT_GetUnsubscribePacketSize',['../core__mqtt__serializer_8c.html#a2a18563d5f63c8975b57118a6836c932',1,'MQTT_GetUnsubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#a2a18563d5f63c8975b57118a6836c932',1,'MQTT_GetUnsubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c']]], + ['mqtt_5finit_19',['MQTT_Init',['../core__mqtt_8h.html#ae8444f3a85535e62cdb1ae9c192677d6',1,'MQTT_Init(MQTTContext_t *pContext, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getTimeFunction, MQTTEventCallback_t userCallback, const MQTTFixedBuffer_t *pNetworkBuffer): core_mqtt.c'],['../core__mqtt_8c.html#ae8444f3a85535e62cdb1ae9c192677d6',1,'MQTT_Init(MQTTContext_t *pContext, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getTimeFunction, MQTTEventCallback_t userCallback, const MQTTFixedBuffer_t *pNetworkBuffer): core_mqtt.c']]], + ['mqtt_5finitstatefulqos_20',['MQTT_InitStatefulQoS',['../core__mqtt_8h.html#afe4c020749e3b9ca044e0e9ad96025c5',1,'MQTT_InitStatefulQoS(MQTTContext_t *pContext, MQTTPubAckInfo_t *pOutgoingPublishRecords, size_t outgoingPublishCount, MQTTPubAckInfo_t *pIncomingPublishRecords, size_t incomingPublishCount): core_mqtt.c'],['../core__mqtt_8c.html#afe4c020749e3b9ca044e0e9ad96025c5',1,'MQTT_InitStatefulQoS(MQTTContext_t *pContext, MQTTPubAckInfo_t *pOutgoingPublishRecords, size_t outgoingPublishCount, MQTTPubAckInfo_t *pIncomingPublishRecords, size_t incomingPublishCount): core_mqtt.c']]], + ['mqtt_5fmatchtopic_21',['MQTT_MatchTopic',['../core__mqtt_8h.html#a633409812b18547365ec9b853069021b',1,'MQTT_MatchTopic(const char *pTopicName, const uint16_t topicNameLength, const char *pTopicFilter, const uint16_t topicFilterLength, bool *pIsMatch): core_mqtt.c'],['../core__mqtt_8c.html#a633409812b18547365ec9b853069021b',1,'MQTT_MatchTopic(const char *pTopicName, const uint16_t topicNameLength, const char *pTopicFilter, const uint16_t topicFilterLength, bool *pIsMatch): core_mqtt.c']]], + ['mqtt_5fping_22',['MQTT_Ping',['../core__mqtt_8h.html#a66eced0c62ace790354ae3de40fc0959',1,'MQTT_Ping(MQTTContext_t *pContext): core_mqtt.c'],['../core__mqtt_8c.html#a66eced0c62ace790354ae3de40fc0959',1,'MQTT_Ping(MQTTContext_t *pContext): core_mqtt.c']]], + ['mqtt_5fprocessincomingpackettypeandlength_23',['MQTT_ProcessIncomingPacketTypeAndLength',['../core__mqtt__serializer_8c.html#a94fd3f746074b3f6e16ae6b23dad9a28',1,'MQTT_ProcessIncomingPacketTypeAndLength(const uint8_t *pBuffer, const size_t *pIndex, MQTTPacketInfo_t *pIncomingPacket): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#a94fd3f746074b3f6e16ae6b23dad9a28',1,'MQTT_ProcessIncomingPacketTypeAndLength(const uint8_t *pBuffer, const size_t *pIndex, MQTTPacketInfo_t *pIncomingPacket): core_mqtt_serializer.c']]], + ['mqtt_5fprocessloop_24',['MQTT_ProcessLoop',['../core__mqtt_8h.html#ab95d3d6b3eed98a6184fb2018c5b55d7',1,'MQTT_ProcessLoop(MQTTContext_t *pContext): core_mqtt.c'],['../core__mqtt_8c.html#ab95d3d6b3eed98a6184fb2018c5b55d7',1,'MQTT_ProcessLoop(MQTTContext_t *pContext): core_mqtt.c']]], + ['mqtt_5fpublish_25',['MQTT_Publish',['../core__mqtt_8h.html#a1d8217e9d30fb2aed002060a8c97c63e',1,'MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId): core_mqtt.c'],['../core__mqtt_8c.html#a1d8217e9d30fb2aed002060a8c97c63e',1,'MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId): core_mqtt.c']]], + ['mqtt_5fpublishtoresend_26',['MQTT_PublishToResend',['../core__mqtt__state_8h.html#a44b3cf50dc477a9f97413a9238a961f6',1,'MQTT_PublishToResend(const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor): core_mqtt_state.c'],['../core__mqtt__state_8c.html#a44b3cf50dc477a9f97413a9238a961f6',1,'MQTT_PublishToResend(const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor): core_mqtt_state.c']]], + ['mqtt_5fpubreltoresend_27',['MQTT_PubrelToResend',['../core__mqtt__state_8c.html#ae58ade262ec01262687554b349b2fdf5',1,'core_mqtt_state.c']]], + ['mqtt_5freceiveloop_28',['MQTT_ReceiveLoop',['../core__mqtt_8h.html#aeb7c37284fcf6f68eb577427a6763fc6',1,'MQTT_ReceiveLoop(MQTTContext_t *pContext): core_mqtt.c'],['../core__mqtt_8c.html#aeb7c37284fcf6f68eb577427a6763fc6',1,'MQTT_ReceiveLoop(MQTTContext_t *pContext): core_mqtt.c']]], + ['mqtt_5fremovestaterecord_29',['MQTT_RemoveStateRecord',['../core__mqtt__state_8c.html#aef2c13cffbbd5c71183282e69ac9d799',1,'core_mqtt_state.c']]], + ['mqtt_5freservestate_30',['MQTT_ReserveState',['../core__mqtt__state_8c.html#a43bc5d82716e1d8b6e167ec0fe50de5d',1,'core_mqtt_state.c']]], + ['mqtt_5fserializeack_31',['MQTT_SerializeAck',['../core__mqtt__serializer_8h.html#a11ea4ac5ea27e93121288e463ca34ee6',1,'MQTT_SerializeAck(const MQTTFixedBuffer_t *pFixedBuffer, uint8_t packetType, uint16_t packetId): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a11ea4ac5ea27e93121288e463ca34ee6',1,'MQTT_SerializeAck(const MQTTFixedBuffer_t *pFixedBuffer, uint8_t packetType, uint16_t packetId): core_mqtt_serializer.c']]], + ['mqtt_5fserializeconnect_32',['MQTT_SerializeConnect',['../core__mqtt__serializer_8h.html#aa2e2300d6c43e61f8f2cf83f7149835c',1,'MQTT_SerializeConnect(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#aa2e2300d6c43e61f8f2cf83f7149835c',1,'MQTT_SerializeConnect(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c']]], + ['mqtt_5fserializeconnectfixedheader_33',['MQTT_SerializeConnectFixedHeader',['../core__mqtt__serializer_8c.html#a5e6043289c05db1cdb7e33e0921247a0',1,'core_mqtt_serializer.c']]], + ['mqtt_5fserializedisconnect_34',['MQTT_SerializeDisconnect',['../core__mqtt__serializer_8h.html#a6aae40d4656eb533a74b67bf9c827d3b',1,'MQTT_SerializeDisconnect(const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a6aae40d4656eb533a74b67bf9c827d3b',1,'MQTT_SerializeDisconnect(const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c']]], + ['mqtt_5fserializepingreq_35',['MQTT_SerializePingreq',['../core__mqtt__serializer_8h.html#af3b3e40858fd984c871511e02a61e15d',1,'MQTT_SerializePingreq(const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#af3b3e40858fd984c871511e02a61e15d',1,'MQTT_SerializePingreq(const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c']]], + ['mqtt_5fserializepublish_36',['MQTT_SerializePublish',['../core__mqtt__serializer_8h.html#ac6c453f9c4b7f48aad511bc677ec7eb9',1,'MQTT_SerializePublish(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#ac6c453f9c4b7f48aad511bc677ec7eb9',1,'MQTT_SerializePublish(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c']]], + ['mqtt_5fserializepublishheader_37',['MQTT_SerializePublishHeader',['../core__mqtt__serializer_8h.html#a659cf2bcaf2c5131daa0acc1917401a2',1,'MQTT_SerializePublishHeader(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer, size_t *pHeaderSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a659cf2bcaf2c5131daa0acc1917401a2',1,'MQTT_SerializePublishHeader(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer, size_t *pHeaderSize): core_mqtt_serializer.c']]], + ['mqtt_5fserializepublishheaderwithouttopic_38',['MQTT_SerializePublishHeaderWithoutTopic',['../core__mqtt__serializer_8h.html#a32de7fabeca85a4d360fa1dd06ff7cd0',1,'MQTT_SerializePublishHeaderWithoutTopic(const MQTTPublishInfo_t *pPublishInfo, size_t remainingLength, uint8_t *pBuffer, size_t *headerSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a32de7fabeca85a4d360fa1dd06ff7cd0',1,'MQTT_SerializePublishHeaderWithoutTopic(const MQTTPublishInfo_t *pPublishInfo, size_t remainingLength, uint8_t *pBuffer, size_t *headerSize): core_mqtt_serializer.c']]], + ['mqtt_5fserializesubscribe_39',['MQTT_SerializeSubscribe',['../core__mqtt__serializer_8h.html#a21273b13070e8340cc33b0f86bf79571',1,'MQTT_SerializeSubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a21273b13070e8340cc33b0f86bf79571',1,'MQTT_SerializeSubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c']]], + ['mqtt_5fserializesubscribeheader_40',['MQTT_SerializeSubscribeHeader',['../core__mqtt__serializer_8c.html#a6fe31953d7b8dacb769adcf4c2719730',1,'core_mqtt_serializer.c']]], + ['mqtt_5fserializeunsubscribe_41',['MQTT_SerializeUnsubscribe',['../core__mqtt__serializer_8h.html#aab58219c203077c07ffd7061405e1adb',1,'MQTT_SerializeUnsubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#aab58219c203077c07ffd7061405e1adb',1,'MQTT_SerializeUnsubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c']]], + ['mqtt_5fserializeunsubscribeheader_42',['MQTT_SerializeUnsubscribeHeader',['../core__mqtt__serializer_8c.html#a5b6f47fa319a444835ffed2d6af04709',1,'core_mqtt_serializer.c']]], + ['mqtt_5fstate_5fstrerror_43',['MQTT_State_strerror',['../core__mqtt__state_8c.html#a53d786203ca4d5d5630a9eb3dd4cddae',1,'core_mqtt_state.c']]], + ['mqtt_5fstatus_5fstrerror_44',['MQTT_Status_strerror',['../core__mqtt_8h.html#a05d9facfce89c5f9edef09ca13717f50',1,'MQTT_Status_strerror(MQTTStatus_t status): core_mqtt.c'],['../core__mqtt_8c.html#a05d9facfce89c5f9edef09ca13717f50',1,'MQTT_Status_strerror(MQTTStatus_t status): core_mqtt.c']]], + ['mqtt_5fsubscribe_45',['MQTT_Subscribe',['../core__mqtt_8h.html#a567aa9c38726a7879f9cbf943e813e8f',1,'MQTT_Subscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId): core_mqtt.c'],['../core__mqtt_8c.html#a567aa9c38726a7879f9cbf943e813e8f',1,'MQTT_Subscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId): core_mqtt.c']]], + ['mqtt_5funsubscribe_46',['MQTT_Unsubscribe',['../core__mqtt_8h.html#a77c911dbe24c5a51aaea88250895dba4',1,'MQTT_Unsubscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId): core_mqtt.c'],['../core__mqtt_8c.html#a77c911dbe24c5a51aaea88250895dba4',1,'MQTT_Unsubscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId): core_mqtt.c']]], + ['mqtt_5fupdatestateack_47',['MQTT_UpdateStateAck',['../core__mqtt__state_8c.html#a09a013b709085ffd51faa33c067cce1f',1,'core_mqtt_state.c']]], + ['mqtt_5fupdatestatepublish_48',['MQTT_UpdateStatePublish',['../core__mqtt__state_8c.html#ad657bd67745c66bc50f0441b4cc94763',1,'core_mqtt_state.c']]] +]; diff --git a/latest/coreMQTT/search/functions_a.js b/latest/coreMQTT/search/functions_a.js new file mode 100644 index 00000000..7eff3baf --- /dev/null +++ b/latest/coreMQTT/search/functions_a.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['processpublishflags_0',['processPublishFlags',['../core__mqtt__serializer_8c.html#a47a044115ee5df1ac7fe02d2ee37e1e0',1,'core_mqtt_serializer.c']]], + ['processremaininglength_1',['processRemainingLength',['../core__mqtt__serializer_8c.html#a8a4f72e05cd72fa57ba5a90e204569b3',1,'core_mqtt_serializer.c']]] +]; diff --git a/latest/coreMQTT/search/functions_b.js b/latest/coreMQTT/search/functions_b.js new file mode 100644 index 00000000..f9d3c0ed --- /dev/null +++ b/latest/coreMQTT/search/functions_b.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['readsubackstatus_0',['readSubackStatus',['../core__mqtt__serializer_8c.html#a02cace9415c300f4dd3394bf1eee0787',1,'core_mqtt_serializer.c']]], + ['receiveconnack_1',['receiveConnack',['../core__mqtt_8c.html#aa3c5d4f6154122cedcce9508ea7d1dce',1,'core_mqtt.c']]], + ['receivepacket_2',['receivePacket',['../core__mqtt_8c.html#aa674664c166b58a5b6630961d8760d3a',1,'core_mqtt.c']]], + ['receivesingleiteration_3',['receiveSingleIteration',['../core__mqtt_8c.html#a14d3be6806a945c14c0529daa1714e10',1,'core_mqtt.c']]], + ['recvexact_4',['recvExact',['../core__mqtt_8c.html#a509d9dd1ede2bc000035d8f9926a473c',1,'core_mqtt.c']]], + ['remaininglengthencodedsize_5',['remainingLengthEncodedSize',['../core__mqtt__serializer_8c.html#aeead0813fa045d754e3d6ec964d0686e',1,'core_mqtt_serializer.c']]] +]; diff --git a/latest/coreMQTT/search/functions_c.js b/latest/coreMQTT/search/functions_c.js new file mode 100644 index 00000000..fb65351b --- /dev/null +++ b/latest/coreMQTT/search/functions_c.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['sendbuffer_0',['sendBuffer',['../core__mqtt_8c.html#a7f4f9871c75f8f987e3c86ae910bd982',1,'core_mqtt.c']]], + ['sendconnectwithoutcopy_1',['sendConnectWithoutCopy',['../core__mqtt_8c.html#a3c6935ecef4879b9aeee05ffb0f0a9cb',1,'core_mqtt.c']]], + ['sendmessagevector_2',['sendMessageVector',['../core__mqtt_8c.html#a39f478d2bb0366a5f14bfa90316d8d26',1,'core_mqtt.c']]], + ['sendpublishacks_3',['sendPublishAcks',['../core__mqtt_8c.html#ab4b719d2f726b049c279dcb37fcba840',1,'core_mqtt.c']]], + ['sendpublishwithoutcopy_4',['sendPublishWithoutCopy',['../core__mqtt_8c.html#aaaca64a926603116f5dfec4a65f28283',1,'core_mqtt.c']]], + ['sendsubscribewithoutcopy_5',['sendSubscribeWithoutCopy',['../core__mqtt_8c.html#a86259fe46a81f7981a7b43b677ab896d',1,'core_mqtt.c']]], + ['sendunsubscribewithoutcopy_6',['sendUnsubscribeWithoutCopy',['../core__mqtt_8c.html#a5fc0209190ce8ce635050195689306e2',1,'core_mqtt.c']]], + ['serializeconnectpacket_7',['serializeConnectPacket',['../core__mqtt__serializer_8c.html#a95bf697a3b1f86950e5c199d9cf3a185',1,'core_mqtt_serializer.c']]], + ['serializepublishcommon_8',['serializePublishCommon',['../core__mqtt__serializer_8c.html#a6b4138d990e2c8fbedbe28683c0fa83a',1,'core_mqtt_serializer.c']]], + ['stateselect_9',['stateSelect',['../core__mqtt__state_8c.html#adfc09b0c75d5de09cd73650f944699c0',1,'core_mqtt_state.c']]] +]; diff --git a/latest/coreMQTT/search/functions_d.js b/latest/coreMQTT/search/functions_d.js new file mode 100644 index 00000000..139f219f --- /dev/null +++ b/latest/coreMQTT/search/functions_d.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['updaterecord_0',['updateRecord',['../core__mqtt__state_8c.html#a819c7c72087621fcf97a028bff02759e',1,'core_mqtt_state.c']]], + ['updatestateack_1',['updateStateAck',['../core__mqtt__state_8c.html#a174a91b9491a344d6fb4f0b39189392f',1,'core_mqtt_state.c']]], + ['updatestatepublish_2',['updateStatePublish',['../core__mqtt__state_8c.html#aa0550584e3733da2e31c9478b9307b49',1,'core_mqtt_state.c']]] +]; diff --git a/latest/coreMQTT/search/functions_e.js b/latest/coreMQTT/search/functions_e.js new file mode 100644 index 00000000..460ee0c0 --- /dev/null +++ b/latest/coreMQTT/search/functions_e.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['validatepublishparams_0',['validatePublishParams',['../core__mqtt_8c.html#ad7eda8c9d4a5afa7b3f830dbd8cf4de4',1,'core_mqtt.c']]], + ['validatesubscribeunsubscribeparams_1',['validateSubscribeUnsubscribeParams',['../core__mqtt_8c.html#a37c146709806e0974638784edeb587f8',1,'core_mqtt.c']]], + ['validatesubscriptionserializeparams_2',['validateSubscriptionSerializeParams',['../core__mqtt__serializer_8c.html#a81262cb0b9d47dee979420f6fd8a7271',1,'core_mqtt_serializer.c']]], + ['validatetransitionack_3',['validateTransitionAck',['../core__mqtt__state_8c.html#ac85ca8874163b399b7f8e5e17d3c5872',1,'core_mqtt_state.c']]], + ['validatetransitionpublish_4',['validateTransitionPublish',['../core__mqtt__state_8c.html#aad1473b9a2d46be62c3e80dd3524af9d',1,'core_mqtt_state.c']]] +]; diff --git a/latest/coreMQTT/search/groups_0.js b/latest/coreMQTT/search/groups_0.js new file mode 100644 index 00000000..482cc48a --- /dev/null +++ b/latest/coreMQTT/search/groups_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['basic_20types_0',['Basic Types',['../group__mqtt__basic__types.html',1,'']]] +]; diff --git a/latest/coreMQTT/search/groups_1.js b/latest/coreMQTT/search/groups_1.js new file mode 100644 index 00000000..a0612bb6 --- /dev/null +++ b/latest/coreMQTT/search/groups_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['callback_20types_0',['Callback Types',['../group__mqtt__callback__types.html',1,'']]], + ['constants_1',['Constants',['../group__mqtt__constants.html',1,'']]] +]; diff --git a/latest/coreMQTT/search/groups_2.js b/latest/coreMQTT/search/groups_2.js new file mode 100644 index 00000000..6a1f1a06 --- /dev/null +++ b/latest/coreMQTT/search/groups_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['enumerated_20types_0',['Enumerated Types',['../group__mqtt__enum__types.html',1,'']]] +]; diff --git a/latest/coreMQTT/search/groups_3.js b/latest/coreMQTT/search/groups_3.js new file mode 100644 index 00000000..22c34526 --- /dev/null +++ b/latest/coreMQTT/search/groups_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['parameter_20structures_0',['Parameter Structures',['../group__mqtt__struct__types.html',1,'']]] +]; diff --git a/latest/coreMQTT/search/mag.svg b/latest/coreMQTT/search/mag.svg new file mode 100644 index 00000000..9f46b301 --- /dev/null +++ b/latest/coreMQTT/search/mag.svg @@ -0,0 +1,37 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/latest/coreMQTT/search/mag_d.svg b/latest/coreMQTT/search/mag_d.svg new file mode 100644 index 00000000..b9a814c7 --- /dev/null +++ b/latest/coreMQTT/search/mag_d.svg @@ -0,0 +1,37 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/latest/coreMQTT/search/mag_sel.svg b/latest/coreMQTT/search/mag_sel.svg new file mode 100644 index 00000000..03626f64 --- /dev/null +++ b/latest/coreMQTT/search/mag_sel.svg @@ -0,0 +1,74 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/latest/coreMQTT/search/mag_seld.svg b/latest/coreMQTT/search/mag_seld.svg new file mode 100644 index 00000000..6e720dcc --- /dev/null +++ b/latest/coreMQTT/search/mag_seld.svg @@ -0,0 +1,74 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/latest/coreMQTT/search/pages_0.js b/latest/coreMQTT/search/pages_0.js new file mode 100644 index 00000000..1d113db4 --- /dev/null +++ b/latest/coreMQTT/search/pages_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['configurations_0',['Configurations',['../core_mqtt_config.html',1,'']]] +]; diff --git a/latest/coreMQTT/search/pages_1.js b/latest/coreMQTT/search/pages_1.js new file mode 100644 index 00000000..5f3b990e --- /dev/null +++ b/latest/coreMQTT/search/pages_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['design_0',['Design',['../mqtt_design.html',1,'']]] +]; diff --git a/latest/coreMQTT/search/pages_2.js b/latest/coreMQTT/search/pages_2.js new file mode 100644 index 00000000..d505ab5d --- /dev/null +++ b/latest/coreMQTT/search/pages_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['functions_0',['Functions',['../mqtt_functions.html',1,'']]] +]; diff --git a/latest/coreMQTT/search/pages_3.js b/latest/coreMQTT/search/pages_3.js new file mode 100644 index 00000000..ccdc8a3d --- /dev/null +++ b/latest/coreMQTT/search/pages_3.js @@ -0,0 +1,33 @@ +var searchData= +[ + ['mqtt_5fconnect_0',['MQTT_Connect',['../mqtt_connect_function.html',1,'mqtt_functions']]], + ['mqtt_5fdeserializeack_1',['MQTT_DeserializeAck',['../mqtt_deserializeack_function.html',1,'mqtt_functions']]], + ['mqtt_5fdeserializepublish_2',['MQTT_DeserializePublish',['../mqtt_deserializepublish_function.html',1,'mqtt_functions']]], + ['mqtt_5fdisconnect_3',['MQTT_Disconnect',['../mqtt_disconnect_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetconnectpacketsize_4',['MQTT_GetConnectPacketSize',['../mqtt_getconnectpacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetdisconnectpacketsize_5',['MQTT_GetDisconnectPacketSize',['../mqtt_getdisconnectpacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetincomingpackettypeandlength_6',['MQTT_GetIncomingPacketTypeAndLength',['../mqtt_getincomingpackettypeandlength_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetpacketid_7',['MQTT_GetPacketId',['../mqtt_getpacketid_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetpingreqpacketsize_8',['MQTT_GetPingreqPacketSize',['../mqtt_getpingreqpacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetpublishpacketsize_9',['MQTT_GetPublishPacketSize',['../mqtt_getpublishpacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetsubackstatuscodes_10',['MQTT_GetSubAckStatusCodes',['../mqtt_getsubackstatuscodes_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetsubscribepacketsize_11',['MQTT_GetSubscribePacketSize',['../mqtt_getsubscribepacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetunsubscribepacketsize_12',['MQTT_GetUnsubscribePacketSize',['../mqtt_getunsubscribepacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5finit_13',['MQTT_Init',['../mqtt_init_function.html',1,'mqtt_functions']]], + ['mqtt_5fping_14',['MQTT_Ping',['../mqtt_ping_function.html',1,'mqtt_functions']]], + ['mqtt_5fprocessloop_15',['MQTT_ProcessLoop',['../mqtt_processloop_function.html',1,'mqtt_functions']]], + ['mqtt_5fpublish_16',['MQTT_Publish',['../mqtt_publish_function.html',1,'mqtt_functions']]], + ['mqtt_5fpublishtoresend_17',['MQTT_PublishToResend',['../mqtt_publishtoresend_function.html',1,'mqtt_functions']]], + ['mqtt_5freceiveloop_18',['MQTT_ReceiveLoop',['../mqtt_receiveloop_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializeack_19',['MQTT_SerializeAck',['../mqtt_serializeack_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializeconnect_20',['MQTT_SerializeConnect',['../mqtt_serializeconnect_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializedisconnect_21',['MQTT_SerializeDisconnect',['../mqtt_serializedisconnect_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializepingreq_22',['MQTT_SerializePingreq',['../mqtt_serializepingreq_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializepublish_23',['MQTT_SerializePublish',['../mqtt_serializepublish_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializepublishheader_24',['MQTT_SerializePublishHeader',['../mqtt_serializepublishheader_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializesubscribe_25',['MQTT_SerializeSubscribe',['../mqtt_serializesubscribe_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializeunsubscribe_26',['MQTT_SerializeUnsubscribe',['../mqtt_serializeunsubscribe_function.html',1,'mqtt_functions']]], + ['mqtt_5fstatus_5fstrerror_27',['MQTT_Status_strerror',['../mqtt_status_strerror_function.html',1,'mqtt_functions']]], + ['mqtt_5fsubscribe_28',['MQTT_Subscribe',['../mqtt_subscribe_function.html',1,'mqtt_functions']]], + ['mqtt_5funsubscribe_29',['MQTT_Unsubscribe',['../mqtt_unsubscribe_function.html',1,'mqtt_functions']]] +]; diff --git a/latest/coreMQTT/search/pages_4.js b/latest/coreMQTT/search/pages_4.js new file mode 100644 index 00000000..0398f4f4 --- /dev/null +++ b/latest/coreMQTT/search/pages_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['overview_0',['Overview',['../index.html',1,'']]] +]; diff --git a/latest/coreMQTT/search/pages_5.js b/latest/coreMQTT/search/pages_5.js new file mode 100644 index 00000000..892aa998 --- /dev/null +++ b/latest/coreMQTT/search/pages_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['porting_20guide_0',['Porting Guide',['../mqtt_porting.html',1,'']]] +]; diff --git a/latest/coreMQTT/search/pages_6.js b/latest/coreMQTT/search/pages_6.js new file mode 100644 index 00000000..41a56c5a --- /dev/null +++ b/latest/coreMQTT/search/pages_6.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['timeouts_20in_20coremqtt_20library_0',['Timeouts in coreMQTT library',['../mqtt_timeouts.html',1,'']]], + ['transport_20interface_1',['Transport Interface',['../mqtt_transport_interface.html',1,'']]] +]; diff --git a/latest/coreMQTT/search/search.css b/latest/coreMQTT/search/search.css new file mode 100644 index 00000000..a53214fc --- /dev/null +++ b/latest/coreMQTT/search/search.css @@ -0,0 +1,286 @@ +/*---------------- Search Box */ + +#MSearchBox { + position: absolute; + right: 5px; +} +/*---------------- Search box styling */ + +.SRPage * { + font-weight: normal; + line-height: normal; +} + +dark-mode-toggle { + margin-left: 5px; + display: flex; + float: right; +} + +#MSearchBox { + display: inline-block; + white-space : nowrap; + background: var(--search-background-color); + border-radius: 0.65em; + box-shadow: var(--search-box-shadow); + z-index: 102; +} + +#MSearchBox .left { + display: inline-block; + vertical-align: middle; + height: 1.4em; +} + +#MSearchSelect { + display: inline-block; + vertical-align: middle; + width: 20px; + height: 19px; + background-image: var(--search-magnification-select-image); + margin: 0 0 0 0.3em; + padding: 0; +} + +#MSearchSelectExt { + display: inline-block; + vertical-align: middle; + width: 10px; + height: 19px; + background-image: var(--search-magnification-image); + margin: 0 0 0 0.5em; + padding: 0; +} + + +#MSearchField { + display: inline-block; + vertical-align: middle; + width: 7.5em; + height: 19px; + margin: 0 0.15em; + padding: 0; + line-height: 1em; + border:none; + color: var(--search-foreground-color); + outline: none; + font-family: var(--font-family-search); + -webkit-border-radius: 0px; + border-radius: 0px; + background: none; +} + +@media(hover: none) { + /* to avoid zooming on iOS */ + #MSearchField { + font-size: 16px; + } +} + +#MSearchBox .right { + display: inline-block; + vertical-align: middle; + width: 1.4em; + height: 1.4em; +} + +#MSearchClose { + display: none; + font-size: inherit; + background : none; + border: none; + margin: 0; + padding: 0; + outline: none; + +} + +#MSearchCloseImg { + padding: 0.3em; + margin: 0; +} + +.MSearchBoxActive #MSearchField { + color: var(--search-active-color); +} + + + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid var(--search-filter-border-color); + background-color: var(--search-filter-background-color); + z-index: 10001; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt var(--font-family-search); + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: var(--font-family-monospace); + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: var(--search-filter-foreground-color); + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: var(--search-filter-foreground-color); + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: var(--search-filter-highlight-text-color); + background-color: var(--search-filter-highlight-bg-color); + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + /*width: 60ex;*/ + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid var(--search-results-border-color); + background-color: var(--search-results-background-color); + z-index:10000; + width: 300px; + height: 400px; + overflow: auto; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +div.SRPage { + margin: 5px 2px; + background-color: var(--search-results-background-color); +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: var(--search-results-foreground-color); + font-family: var(--font-family-search); + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: var(--search-results-foreground-color); + font-family: var(--font-family-search); + font-size: 8pt; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; + font-family: var(--font-family-search); +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; + font-family: var(--font-family-search); +} + +.SRResult { + display: none; +} + +div.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: var(--nav-gradient-active-image-parent); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/latest/coreMQTT/search/search.js b/latest/coreMQTT/search/search.js new file mode 100644 index 00000000..e103a262 --- /dev/null +++ b/latest/coreMQTT/search/search.js @@ -0,0 +1,816 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var idxChar = searchValue.substr(0, 1).toLowerCase(); + if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair + { + idxChar = searchValue.substr(0, 2); + } + + var jsFile; + + var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); + if (idx!=-1) + { + var hexCode=idx.toString(16); + jsFile = this.resultsPath + indexSectionNames[this.searchIndex] + '_' + hexCode + '.js'; + } + + var loadJS = function(url, impl, loc){ + var scriptTag = document.createElement('script'); + scriptTag.src = url; + scriptTag.onload = impl; + scriptTag.onreadystatechange = impl; + loc.appendChild(scriptTag); + } + + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + var domSearchBox = this.DOMSearchBox(); + var domPopupSearchResults = this.DOMPopupSearchResults(); + var domSearchClose = this.DOMSearchClose(); + var resultsPath = this.resultsPath; + + var handleResults = function() { + document.getElementById("Loading").style.display="none"; + if (typeof searchData !== 'undefined') { + createResults(resultsPath); + document.getElementById("NoMatches").style.display="none"; + } + + searchResults.Search(searchValue); + + if (domPopupSearchResultsWindow.style.display!='block') + { + domSearchClose.style.display = 'inline-block'; + var left = getXPos(domSearchBox) + 150; + var top = getYPos(domSearchBox) + 20; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + var maxWidth = document.body.clientWidth; + var maxHeight = document.body.clientHeight; + var width = 300; + if (left<10) left=10; + if (width+left+8>maxWidth) width=maxWidth-left-8; + var height = 400; + if (height+top+8>maxHeight) height=maxHeight-top-8; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResultsWindow.style.height = height + 'px'; + } + } + + if (jsFile) { + loadJS(jsFile, handleResults, this.DOMPopupSearchResultsWindow()); + } else { + handleResults(); + } + + this.lastSearchValue = searchValue; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + this.searchActive = true; + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + this.DOMSearchField().value = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName.toLowerCase() == 'div' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName.toLowerCase() == 'div' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + searchBox.CloseResultsWindow(); + document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + searchBox.CloseResultsWindow(); + document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults(resultsPath) +{ + var results = document.getElementById("SRResults"); + results.innerHTML = ''; + for (var e=0; e-{AmhX=Jf(#6djGiuzAr*{o?=JLmPLyc> z_*`QK&+BH@jWrYJ7>r6%keRM@)Qyv8R=enp0jiI>aWlGyB58O zFVR20d+y`K7vDw(hJF3;>dD*3-?v=<8M)@x|EEGLnJsniYK!2U1 Y!`|5biEc?d1`HDhPgg&ebxsLQ02F6;9RL6T literal 0 HcmV?d00001 diff --git a/latest/coreMQTT/splitbard.png b/latest/coreMQTT/splitbard.png new file mode 100644 index 0000000000000000000000000000000000000000..8367416d757fd7b6dc4272b6432dc75a75abd068 GIT binary patch literal 282 zcmeAS@N?(olHy`uVBq!ia0vp^Yzz!63>-{AmhX=Jf@VhhFKy35^fiT zT~&lUj3=cDh^%3HDY9k5CEku}PHXNoNC(_$U3XPb&Q*ME25pT;2(*BOgAf<+R$lzakPG`kF31()Fx{L5Wrac|GQzjeE= zueY1`Ze{#x<8=S|`~MgGetGce)#vN&|J{Cd^tS%;tBYTo?+^d68<#n_Y_xx`J||4O V@QB{^CqU0Kc)I$ztaD0e0svEzbJzd? literal 0 HcmV?d00001 diff --git a/latest/coreMQTT/struct_m_q_t_t_connect_info__t.html b/latest/coreMQTT/struct_m_q_t_t_connect_info__t.html new file mode 100644 index 00000000..ab6c35c5 --- /dev/null +++ b/latest/coreMQTT/struct_m_q_t_t_connect_info__t.html @@ -0,0 +1,161 @@ + + + + + + + +coreMQTT: MQTTConnectInfo_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTConnectInfo_t Struct Reference
+
+
+ +

MQTT CONNECT packet parameters. + More...

+ +

#include <core_mqtt_serializer.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Fields

+bool cleanSession
 Whether to establish a new, clean session or resume a previous session.
 
+uint16_t keepAliveSeconds
 MQTT keep alive period.
 
+const char * pClientIdentifier
 MQTT client identifier. Must be unique per client.
 
+uint16_t clientIdentifierLength
 Length of the client identifier.
 
+const char * pUserName
 MQTT user name. Set to NULL if not used.
 
+uint16_t userNameLength
 Length of MQTT user name. Set to 0 if not used.
 
+const char * pPassword
 MQTT password. Set to NULL if not used.
 
+uint16_t passwordLength
 Length of MQTT password. Set to 0 if not used.
 
+

Detailed Description

+

MQTT CONNECT packet parameters.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/latest/coreMQTT/struct_m_q_t_t_context__t.html b/latest/coreMQTT/struct_m_q_t_t_context__t.html new file mode 100644 index 00000000..08f580f7 --- /dev/null +++ b/latest/coreMQTT/struct_m_q_t_t_context__t.html @@ -0,0 +1,197 @@ + + + + + + + +coreMQTT: MQTTContext_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTContext_t Struct Reference
+
+
+ +

A struct representing an MQTT connection. + More...

+ +

#include <core_mqtt.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Fields

+MQTTPubAckInfo_toutgoingPublishRecords
 State engine records for outgoing publishes.
 
+MQTTPubAckInfo_tincomingPublishRecords
 State engine records for incoming publishes.
 
+size_t outgoingPublishRecordMaxCount
 The maximum number of outgoing publish records.
 
+size_t incomingPublishRecordMaxCount
 The maximum number of incoming publish records.
 
+TransportInterface_t transportInterface
 The transport interface used by the MQTT connection.
 
+MQTTFixedBuffer_t networkBuffer
 The buffer used in sending and receiving packets from the network.
 
+uint16_t nextPacketId
 The next available ID for outgoing MQTT packets.
 
+MQTTConnectionStatus_t connectStatus
 Whether the context currently has a connection to the broker.
 
+MQTTGetCurrentTimeFunc_t getTime
 Function used to get millisecond timestamps.
 
+MQTTEventCallback_t appCallback
 Callback function used to give deserialized MQTT packets to the application.
 
+uint32_t lastPacketTxTime
 Timestamp of the last packet sent by the library.
 
+uint32_t lastPacketRxTime
 Timestamp of the last packet received by the library.
 
+bool controlPacketSent
 Whether the library sent a packet during a call of MQTT_ProcessLoop or MQTT_ReceiveLoop.
 
+size_t index
 Index to keep track of the number of bytes received in network buffer.
 
+uint16_t keepAliveIntervalSec
 Keep Alive interval.
 
+uint32_t pingReqSendTimeMs
 Timestamp of the last sent PINGREQ.
 
+bool waitingForPingResp
 If the library is currently awaiting a PINGRESP.
 
+

Detailed Description

+

A struct representing an MQTT connection.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/latest/coreMQTT/struct_m_q_t_t_deserialized_info__t.html b/latest/coreMQTT/struct_m_q_t_t_deserialized_info__t.html new file mode 100644 index 00000000..9061ce9d --- /dev/null +++ b/latest/coreMQTT/struct_m_q_t_t_deserialized_info__t.html @@ -0,0 +1,141 @@ + + + + + + + +coreMQTT: MQTTDeserializedInfo_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTDeserializedInfo_t Struct Reference
+
+
+ +

Struct to hold deserialized packet information for an MQTTEventCallback_t callback. + More...

+ +

#include <core_mqtt.h>

+ + + + + + + + + + + +

+Data Fields

+uint16_t packetIdentifier
 Packet ID of deserialized packet.
 
+MQTTPublishInfo_tpPublishInfo
 Pointer to deserialized publish info.
 
+MQTTStatus_t deserializationResult
 Return code of deserialization.
 
+

Detailed Description

+

Struct to hold deserialized packet information for an MQTTEventCallback_t callback.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/latest/coreMQTT/struct_m_q_t_t_fixed_buffer__t.html b/latest/coreMQTT/struct_m_q_t_t_fixed_buffer__t.html new file mode 100644 index 00000000..50b8a332 --- /dev/null +++ b/latest/coreMQTT/struct_m_q_t_t_fixed_buffer__t.html @@ -0,0 +1,138 @@ + + + + + + + +coreMQTT: MQTTFixedBuffer_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTFixedBuffer_t Struct Reference
+
+
+ +

Buffer passed to MQTT library. + More...

+ +

#include <core_mqtt_serializer.h>

+ + + + + + + + +

+Data Fields

+uint8_t * pBuffer
 Pointer to buffer.
 
+size_t size
 Size of buffer.
 
+

Detailed Description

+

Buffer passed to MQTT library.

+

These buffers are not copied and must remain in scope for the duration of the MQTT operation.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/latest/coreMQTT/struct_m_q_t_t_packet_info__t.html b/latest/coreMQTT/struct_m_q_t_t_packet_info__t.html new file mode 100644 index 00000000..3800e125 --- /dev/null +++ b/latest/coreMQTT/struct_m_q_t_t_packet_info__t.html @@ -0,0 +1,145 @@ + + + + + + + +coreMQTT: MQTTPacketInfo_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTPacketInfo_t Struct Reference
+
+
+ +

MQTT incoming packet parameters. + More...

+ +

#include <core_mqtt_serializer.h>

+ + + + + + + + + + + + + + +

+Data Fields

+uint8_t type
 Type of incoming MQTT packet.
 
+uint8_t * pRemainingData
 Remaining serialized data in the MQTT packet.
 
+size_t remainingLength
 Length of remaining serialized data.
 
+size_t headerLength
 The length of the MQTT header including the type and length.
 
+

Detailed Description

+

MQTT incoming packet parameters.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/latest/coreMQTT/struct_m_q_t_t_pub_ack_info__t.html b/latest/coreMQTT/struct_m_q_t_t_pub_ack_info__t.html new file mode 100644 index 00000000..45ee07ce --- /dev/null +++ b/latest/coreMQTT/struct_m_q_t_t_pub_ack_info__t.html @@ -0,0 +1,141 @@ + + + + + + + +coreMQTT: MQTTPubAckInfo_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTPubAckInfo_t Struct Reference
+
+
+ +

An element of the state engine records for QoS 1 or Qos 2 publishes. + More...

+ +

#include <core_mqtt.h>

+ + + + + + + + + + + +

+Data Fields

+uint16_t packetId
 The packet ID of the original PUBLISH.
 
+MQTTQoS_t qos
 The QoS of the original PUBLISH.
 
+MQTTPublishState_t publishState
 The current state of the publish process.
 
+

Detailed Description

+

An element of the state engine records for QoS 1 or Qos 2 publishes.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/latest/coreMQTT/struct_m_q_t_t_publish_info__t.html b/latest/coreMQTT/struct_m_q_t_t_publish_info__t.html new file mode 100644 index 00000000..ec91a576 --- /dev/null +++ b/latest/coreMQTT/struct_m_q_t_t_publish_info__t.html @@ -0,0 +1,157 @@ + + + + + + + +coreMQTT: MQTTPublishInfo_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTPublishInfo_t Struct Reference
+
+
+ +

MQTT PUBLISH packet parameters. + More...

+ +

#include <core_mqtt_serializer.h>

+ + + + + + + + + + + + + + + + + + + + + + + +

+Data Fields

+MQTTQoS_t qos
 Quality of Service for message.
 
+bool retain
 Whether this is a retained message.
 
+bool dup
 Whether this is a duplicate publish message.
 
+const char * pTopicName
 Topic name on which the message is published.
 
+uint16_t topicNameLength
 Length of topic name.
 
+const void * pPayload
 Message payload.
 
+size_t payloadLength
 Message payload length.
 
+

Detailed Description

+

MQTT PUBLISH packet parameters.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/latest/coreMQTT/struct_m_q_t_t_subscribe_info__t.html b/latest/coreMQTT/struct_m_q_t_t_subscribe_info__t.html new file mode 100644 index 00000000..19ac7421 --- /dev/null +++ b/latest/coreMQTT/struct_m_q_t_t_subscribe_info__t.html @@ -0,0 +1,141 @@ + + + + + + + +coreMQTT: MQTTSubscribeInfo_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTSubscribeInfo_t Struct Reference
+
+
+ +

MQTT SUBSCRIBE packet parameters. + More...

+ +

#include <core_mqtt_serializer.h>

+ + + + + + + + + + + +

+Data Fields

+MQTTQoS_t qos
 Quality of Service for subscription.
 
+const char * pTopicFilter
 Topic filter to subscribe to.
 
+uint16_t topicFilterLength
 Length of subscription topic filter.
 
+

Detailed Description

+

MQTT SUBSCRIBE packet parameters.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/latest/coreMQTT/struct_transport_interface__t.html b/latest/coreMQTT/struct_transport_interface__t.html new file mode 100644 index 00000000..f2a64a74 --- /dev/null +++ b/latest/coreMQTT/struct_transport_interface__t.html @@ -0,0 +1,198 @@ + + + + + + + +coreMQTT: TransportInterface_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
TransportInterface_t Struct Reference
+
+
+ +

The transport layer interface. + More...

+ +

#include <transport_interface.h>

+ + + + + + + + + + +

+Data Fields

TransportRecv_t recv
 
TransportSend_t send
 
TransportWritev_t writev
 
NetworkContext_tpNetworkContext
 
+

Detailed Description

+

The transport layer interface.

+

Field Documentation

+ +

◆ recv

+ +
+
+ + + + +
TransportRecv_t TransportInterface_t::recv
+
+

Transport receive function pointer.

+ +
+
+ +

◆ send

+ +
+
+ + + + +
TransportSend_t TransportInterface_t::send
+
+

Transport send function pointer.

+ +
+
+ +

◆ writev

+ +
+
+ + + + +
TransportWritev_t TransportInterface_t::writev
+
+

Transport writev function pointer.

+ +
+
+ +

◆ pNetworkContext

+ +
+
+ + + + +
NetworkContext_t* TransportInterface_t::pNetworkContext
+
+

Implementation-defined network context.

+ +
+
+
The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/latest/coreMQTT/struct_transport_out_vector__t.html b/latest/coreMQTT/struct_transport_out_vector__t.html new file mode 100644 index 00000000..0df3cb13 --- /dev/null +++ b/latest/coreMQTT/struct_transport_out_vector__t.html @@ -0,0 +1,137 @@ + + + + + + + +coreMQTT: TransportOutVector_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
TransportOutVector_t Struct Reference
+
+
+ +

Transport vector structure for sending multiple messages. + More...

+ +

#include <transport_interface.h>

+ + + + + + + + +

+Data Fields

+const void * iov_base
 Base address of data.
 
+size_t iov_len
 Length of data in buffer.
 
+

Detailed Description

+

Transport vector structure for sending multiple messages.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/latest/coreMQTT/style.css b/latest/coreMQTT/style.css new file mode 100644 index 00000000..99d7ab71 --- /dev/null +++ b/latest/coreMQTT/style.css @@ -0,0 +1,132 @@ +/* + * Stylesheet for Doxygen HTML output. + * + * This file defines styles for custom elements in the header/footer and + * overrides some of the default Doxygen styles. + * + * Styles in this file do not affect the treeview sidebar. + */ + +/* Set the margins to place a small amount of whitespace on the left and right + * side of the page. */ +div.contents { + margin-left:4em; + margin-right:4em; +} + +/* Justify text in paragraphs. */ +p { + text-align: justify; +} + +/* Style of section headings. */ +h1 { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 160%; + font-weight: normal; + padding-bottom: 4px; + padding-top: 8px; +} + +/* Style of subsection headings. */ +h2:not(.memtitle):not(.groupheader) { + font-size: 125%; + margin-bottom: 0px; + margin-top: 16px; + padding: 0px; +} + +/* Style of paragraphs immediately after subsection headings. */ +h2 + p { + margin: 0px; + padding: 0px; +} + +/* Style of subsection headings. */ +h3 { + font-size: 100%; + margin-bottom: 0px; + margin-left: 2em; + margin-right: 2em; +} + +/* Style of paragraphs immediately after subsubsection headings. */ +h3 + p { + margin-top: 0px; + margin-left: 2em; + margin-right: 2em; +} + +/* Style of the prefix "AWS IoT Device SDK C" that appears in the header. */ +#csdkprefix { + color: #757575; +} + +/* Style of the "Return to main page" link that appears in the header. */ +#returntomain { + padding: 0.5em; +} + +/* Style of the dividers on Configuration Settings pages. */ +div.configpagedivider { + margin-left: 0px !important; + margin-right: 0px !important; + margin-top: 20px !important; +} + +/* Style of configuration setting names. */ +dl.section.user ~ h1 { + border-bottom: none; + color: #000000; + font-family: monospace, fixed; + font-size: 16px; + margin-bottom: 0px; + margin-left: 2em; + margin-top: 1.5em; +} + +/* Style of paragraphs on a configuration settings page. */ +dl.section.user ~ * { + margin-bottom: 10px; + margin-left: 4em; + margin-right: 4em; + margin-top: 0px; +} + +/* Hide the configuration setting marker. */ +dl.section.user { + display: none; +} + +/* Overrides for code fragments and lines. */ +div.fragment { + background: #ffffff; + border: none; + padding: 5px; +} + +div.line { + color: #3a3a3a; +} + +/* Overrides for code syntax highlighting colors. */ +span.comment { + color: #008000; +} + +span.keyword, span.keywordtype, span.keywordflow { + color: #0000ff; +} + +span.preprocessor { + color: #50015a; +} + +span.stringliteral, span.charliteral { + color: #800c0c; +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #496194; +} diff --git a/latest/coreMQTT/sync_off.png b/latest/coreMQTT/sync_off.png new file mode 100644 index 0000000000000000000000000000000000000000..3b443fc62892114406e3d399421b2a881b897acc GIT binary patch literal 853 zcmV-b1FHOqP)oT|#XixUYy%lpuf3i8{fX!o zUyDD0jOrAiT^tq>fLSOOABs-#u{dV^F$b{L9&!2=9&RmV;;8s^x&UqB$PCj4FdKbh zoB1WTskPUPu05XzFbA}=KZ-GP1fPpAfSs>6AHb12UlR%-i&uOlTpFNS7{jm@mkU1V zh`nrXr~+^lsV-s1dkZOaI|kYyVj3WBpPCY{n~yd%u%e+d=f%`N0FItMPtdgBb@py; zq@v6NVArhyTC7)ULw-Jy8y42S1~4n(3LkrW8mW(F-4oXUP3E`e#g**YyqI7h-J2zK zK{m9##m4ri!7N>CqQqCcnI3hqo1I;Yh&QLNY4T`*ptiQGozK>FF$!$+84Z`xwmeMh zJ0WT+OH$WYFALEaGj2_l+#DC3t7_S`vHpSivNeFbP6+r50cO8iu)`7i%Z4BTPh@_m3Tk!nAm^)5Bqnr%Ov|Baunj#&RPtRuK& z4RGz|D5HNrW83-#ydk}tVKJrNmyYt-sTxLGlJY5nc&Re zU4SgHNPx8~Yxwr$bsju?4q&%T1874xxzq+_%?h8_ofw~(bld=o3iC)LUNR*BY%c0y zWd_jX{Y8`l%z+ol1$@Qa?Cy!(0CVIEeYpKZ`(9{z>3$CIe;pJDQk$m3p}$>xBm4lb zKo{4S)`wdU9Ba9jJbVJ0C=SOefZe%d$8=2r={nu<_^a3~>c#t_U6dye5)JrR(_a^E f@}b6j1K9lwFJq@>o)+Ry00000NkvXXu0mjfWa5j* literal 0 HcmV?d00001 diff --git a/latest/coreMQTT/sync_on.png b/latest/coreMQTT/sync_on.png new file mode 100644 index 0000000000000000000000000000000000000000..e08320fb64e6fa33b573005ed6d8fe294e19db76 GIT binary patch literal 845 zcmV-T1G4;yP)Y;xxyHF2B5Wzm| zOOGupOTn@c(JmBOl)e;XMNnZuiTJP>rM8<|Q`7I_))aP?*T)ow&n59{}X4$3Goat zgjs?*aasfbrokzG5cT4K=uG`E14xZl@z)F={P0Y^?$4t z>v!teRnNZym<6h{7sLyF1V0HsfEl+l6TrZpsfr1}luH~F7L}ktXu|*uVX^RG$L0`K zWs3j|0tIvVe(N%_?2{(iCPFGf#B6Hjy6o&}D$A%W%jfO8_W%ZO#-mh}EM$LMn7joJ z05dHr!5Y92g+31l<%i1(=L1a1pXX+OYnalY>31V4K}BjyRe3)9n#;-cCVRD_IG1fT zOKGeNY8q;TL@K{dj@D^scf&VCs*-Jb>8b>|`b*osv52-!A?BpbYtTQBns5EAU**$m zSnVSm(teh>tQi*S*A>#ySc=n;`BHz`DuG4&g4Kf8lLhca+zvZ7t7RflD6-i-mcK=M z!=^P$*u2)bkY5asG4gsss!Hn%u~>}kIW`vMs%lJLH+u*9<4PaV_c6U`KqWXQH%+Nu zTv41O(^ZVi@qhjQdG!fbZw&y+2o!iYymO^?ud3{P*HdoX83YV*Uu_HB=?U&W9%AU# z80}k1SS-CXTU7dcQlsm<^oYLxVSseqY6NO}dc`Nj?8vrhNuCdm@^{a3AQ_>6myOj+ z`1RsLUXF|dm|3k7s2jD(B{rzE>WI2scH8i1;=O5Cc9xB3^aJk%fQjqsu+kH#0=_5a z0nCE8@dbQa-|YIuUVvG0L_IwHMEhOj$Mj4Uq05 X8=0q~qBNan00000NkvXXu0mjfptF>5 literal 0 HcmV?d00001 diff --git a/latest/coreMQTT/tab_a.png b/latest/coreMQTT/tab_a.png new file mode 100644 index 0000000000000000000000000000000000000000..3b725c41c5a527a3a3e40097077d0e206a681247 GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QlXwMjv*C{Z|8b*H5dputLHD# z=<0|*y7z(Vor?d;H&?EG&cXR}?!j-Lm&u1OOI7AIF5&c)RFE;&p0MYK>*Kl@eiymD r@|NpwKX@^z+;{u_Z~trSBfrMKa%3`zocFjEXaR$#tDnm{r-UW|TZ1%4 literal 0 HcmV?d00001 diff --git a/latest/coreMQTT/tab_ad.png b/latest/coreMQTT/tab_ad.png new file mode 100644 index 0000000000000000000000000000000000000000..e34850acfc24be58da6d2fd1ccc6b29cc84fe34d GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QhuH;jv*C{Z|5d*H3V=pKi{In zd2jxLclDRPylmD}^l7{QOtL{vUjO{-WqItb5sQp2h-99b8^^Scr-=2mblCdZuUm?4 jzOJvgvt3{(cjKLW5(A@0qPS@<&}0TrS3j3^P6y&q2{!U5bk+Tso_B!YCpDh>v z{CM*1U8YvQRyBUHt^Ju0W_sq-?;9@_4equ-bavTs=gk796zopr0EBT&m;e9( literal 0 HcmV?d00001 diff --git a/latest/coreMQTT/tab_s.png b/latest/coreMQTT/tab_s.png new file mode 100644 index 0000000000000000000000000000000000000000..ab478c95b67371d700a20869f7de1ddd73522d50 GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QuUrLjv*C{Z|^p8HaRdjTwH7) zC?wLlL}}I{)n%R&r+1}IGmDnq;&J#%V6)9VsYhS`O^BVBQlxOUep0c$RENLq#g8A$ z)z7%K_bI&n@J+X_=x}fJoEKed-$<>=ZI-;YrdjIl`U`uzuDWSP?o#Dmo{%SgM#oan kX~E1%D-|#H#QbHoIja2U-MgvsK&LQxy85}Sb4q9e0Efg%P5=M^ literal 0 HcmV?d00001 diff --git a/latest/coreMQTT/tab_sd.png b/latest/coreMQTT/tab_sd.png new file mode 100644 index 0000000000000000000000000000000000000000..757a565ced4730f85c833fb2547d8e199ae68f19 GIT binary patch literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!Qq7(&jv*C{Z|_!fH5o7*c=%9% zcILh!EA=pAQKdx-Cdiev=v{eg{8Ht<{e8_NAN~b=)%W>-WDCE0PyDHGemi$BoXwcK z{>e9^za6*c1ilttWw&V+U;WCPlV9{LdC~Ey%_H(qj`xgfES(4Yz5jSTZfCt`4E$0YRsR*S^mTCR^;V&sxC8{l_Cp7w8-YPgg&ebxsLQ00$vXK>z>% literal 0 HcmV?d00001 diff --git a/latest/coreMQTT/tabs.css b/latest/coreMQTT/tabs.css new file mode 100644 index 00000000..71c8a470 --- /dev/null +++ b/latest/coreMQTT/tabs.css @@ -0,0 +1 @@ +.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.main-menu-btn{position:relative;display:inline-block;width:36px;height:36px;text-indent:36px;margin-left:8px;white-space:nowrap;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0)}.main-menu-btn-icon,.main-menu-btn-icon:before,.main-menu-btn-icon:after{position:absolute;top:50%;left:2px;height:2px;width:24px;background:var(--nav-menu-button-color);-webkit-transition:all .25s;transition:all .25s}.main-menu-btn-icon:before{content:'';top:-7px;left:0}.main-menu-btn-icon:after{content:'';top:7px;left:0}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon{height:0}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon:before{top:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon:after{top:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}#main-menu-state{position:absolute;width:1px;height:1px;margin:-1px;border:0;padding:0;overflow:hidden;clip:rect(1px,1px,1px,1px)}#main-menu-state:not(:checked) ~ #main-menu{display:none}#main-menu-state:checked ~ #main-menu{display:block}@media(min-width:768px){.main-menu-btn{position:absolute;top:-99999px}#main-menu-state:not(:checked) ~ #main-menu{display:block}}.sm-dox{background-image:var(--nav-gradient-image)}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0 12px;padding-right:43px;font-family:var(--font-family-nav);font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:var(--nav-text-normal-shadow);color:var(--nav-text-normal-color);outline:0}.sm-dox a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox a.current{color:#d23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace !important;text-align:center;text-shadow:none;background:var(--nav-menu-toggle-color);-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox a span.sub-arrow:before{display:block;content:'+'}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px;border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0;border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox ul{background:var(--nav-menu-background-color)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:var(--nav-menu-background-color);background-image:none}.sm-dox ul a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:0 1px 1px black}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media(min-width:768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:var(--nav-gradient-image);line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:var(--nav-text-normal-color) transparent transparent transparent;background:transparent;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0 12px;background-image:var(--nav-separator-image);background-repeat:no-repeat;background-position:right;-moz-border-radius:0 !important;-webkit-border-radius:0;border-radius:0 !important}.sm-dox a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox a:hover span.sub-arrow{border-color:var(--nav-text-hover-color) transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent var(--nav-menu-background-color) transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:var(--nav-menu-background-color);-moz-border-radius:5px !important;-webkit-border-radius:5px;border-radius:5px !important;-moz-box-shadow:0 5px 9px rgba(0,0,0,0.2);-webkit-box-shadow:0 5px 9px rgba(0,0,0,0.2);box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent var(--nav-menu-foreground-color);border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:var(--nav-menu-foreground-color);background-image:none;border:0 !important;color:var(--nav-menu-foreground-color);background-image:none}.sm-dox ul a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent var(--nav-text-hover-color)}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:var(--nav-menu-background-color);height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #d23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#d23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent var(--nav-menu-foreground-color) transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:var(--nav-menu-foreground-color) transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px !important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:var(--nav-gradient-image)}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:var(--nav-menu-background-color)}} \ No newline at end of file diff --git a/latest/coreMQTT/transport__interface_8h.html b/latest/coreMQTT/transport__interface_8h.html new file mode 100644 index 00000000..6ccb890f --- /dev/null +++ b/latest/coreMQTT/transport__interface_8h.html @@ -0,0 +1,151 @@ + + + + + + + +coreMQTT: transport_interface.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
transport_interface.h File Reference
+
+
+ +

Transport interface definitions to send and receive data over the network. +More...

+
#include <stdint.h>
+#include <stddef.h>
+
+

Go to the source code of this file.

+ + + + + + + + +

+Data Structures

struct  TransportOutVector_t
 Transport vector structure for sending multiple messages. More...
 
struct  TransportInterface_t
 The transport layer interface. More...
 
+ + + + + + + + + + + + + +

+Typedefs

+typedef struct NetworkContext NetworkContext_t
 The NetworkContext is an incomplete type. An implementation of this interface must define struct NetworkContext for the system requirements. This context is passed into the network interface functions.
 
typedef int32_t(* TransportRecv_t) (NetworkContext_t *pNetworkContext, void *pBuffer, size_t bytesToRecv)
 Transport interface for receiving data on the network.
 
typedef int32_t(* TransportSend_t) (NetworkContext_t *pNetworkContext, const void *pBuffer, size_t bytesToSend)
 Transport interface for sending data over the network.
 
typedef int32_t(* TransportWritev_t) (NetworkContext_t *pNetworkContext, TransportOutVector_t *pIoVec, size_t ioVecCount)
 Transport interface function for "vectored" / scatter-gather based writes. This function is expected to iterate over the list of vectors pIoVec having ioVecCount entries containing portions of one MQTT message at a maximum. If the proper functionality is available, then the data in the list should be copied to the underlying TCP buffer before flushing the buffer. Implementing it in this fashion will lead to sending of fewer TCP packets for all the values in the list.
 
+

Detailed Description

+

Transport interface definitions to send and receive data over the network.

+
+
+ + + + diff --git a/latest/coreMQTT/transport__interface_8h_source.html b/latest/coreMQTT/transport__interface_8h_source.html new file mode 100644 index 00000000..e3f61339 --- /dev/null +++ b/latest/coreMQTT/transport__interface_8h_source.html @@ -0,0 +1,208 @@ + + + + + + + +coreMQTT: transport_interface.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
transport_interface.h
+
+
+Go to the documentation of this file.
1/*
+
2 * coreMQTT v2.3.1
+
3 * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
4 *
+
5 * SPDX-License-Identifier: MIT
+
6 *
+
7 * Permission is hereby granted, free of charge, to any person obtaining a copy of
+
8 * this software and associated documentation files (the "Software"), to deal in
+
9 * the Software without restriction, including without limitation the rights to
+
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
11 * the Software, and to permit persons to whom the Software is furnished to do so,
+
12 * subject to the following conditions:
+
13 *
+
14 * The above copyright notice and this permission notice shall be included in all
+
15 * copies or substantial portions of the Software.
+
16 *
+
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
23 */
+
24
+
30#ifndef TRANSPORT_INTERFACE_H_
+
31#define TRANSPORT_INTERFACE_H_
+
32
+
33#include <stdint.h>
+
34#include <stddef.h>
+
35
+
36/* *INDENT-OFF* */
+
37#ifdef __cplusplus
+
38 extern "C" {
+
39#endif
+
40/* *INDENT-ON* */
+
41
+
189/* @[define_networkcontext] */
+
190struct NetworkContext;
+
191typedef struct NetworkContext NetworkContext_t;
+
192/* @[define_networkcontext] */
+
193
+
217/* @[define_transportrecv] */
+
218typedef int32_t ( * TransportRecv_t )( NetworkContext_t * pNetworkContext,
+
219 void * pBuffer,
+
220 size_t bytesToRecv );
+
221/* @[define_transportrecv] */
+
222
+
239/* @[define_transportsend] */
+
240typedef int32_t ( * TransportSend_t )( NetworkContext_t * pNetworkContext,
+
241 const void * pBuffer,
+
242 size_t bytesToSend );
+
243/* @[define_transportsend] */
+
244
+
248typedef struct TransportOutVector
+
249{
+
253 const void * iov_base;
+
254
+
258 size_t iov_len;
+ +
260
+
287/* @[define_transportwritev] */
+
288typedef int32_t ( * TransportWritev_t )( NetworkContext_t * pNetworkContext,
+
289 TransportOutVector_t * pIoVec,
+
290 size_t ioVecCount );
+
291/* @[define_transportwritev] */
+
292
+
297/* @[define_transportinterface] */
+
298typedef struct TransportInterface
+
299{
+ + + + + +
305/* @[define_transportinterface] */
+
306
+
307/* *INDENT-OFF* */
+
308#ifdef __cplusplus
+
309 }
+
310#endif
+
311/* *INDENT-ON* */
+
312
+
313#endif /* ifndef TRANSPORT_INTERFACE_H_ */
+
int32_t(* TransportRecv_t)(NetworkContext_t *pNetworkContext, void *pBuffer, size_t bytesToRecv)
Transport interface for receiving data on the network.
Definition: transport_interface.h:218
+
int32_t(* TransportSend_t)(NetworkContext_t *pNetworkContext, const void *pBuffer, size_t bytesToSend)
Transport interface for sending data over the network.
Definition: transport_interface.h:240
+
int32_t(* TransportWritev_t)(NetworkContext_t *pNetworkContext, TransportOutVector_t *pIoVec, size_t ioVecCount)
Transport interface function for "vectored" / scatter-gather based writes. This function is expected ...
Definition: transport_interface.h:288
+
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
+
The transport layer interface.
Definition: transport_interface.h:299
+
TransportSend_t send
Definition: transport_interface.h:301
+
TransportRecv_t recv
Definition: transport_interface.h:300
+
TransportWritev_t writev
Definition: transport_interface.h:302
+
NetworkContext_t * pNetworkContext
Definition: transport_interface.h:303
+
Transport vector structure for sending multiple messages.
Definition: transport_interface.h:249
+
const void * iov_base
Base address of data.
Definition: transport_interface.h:253
+
size_t iov_len
Length of data in buffer.
Definition: transport_interface.h:258
+
+
+ + + + diff --git a/latest/core__mqtt__agent_8c.html b/latest/core__mqtt__agent_8c.html new file mode 100644 index 00000000..9c581607 --- /dev/null +++ b/latest/core__mqtt__agent_8c.html @@ -0,0 +1,1964 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent.c File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_agent.c File Reference
+
+
+ +

Implements an MQTT agent (or daemon task) to enable multithreaded access to coreMQTT. +More...

+
#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include "core_mqtt_agent.h"
+#include "core_mqtt_agent_command_functions.h"
+#include "core_mqtt_agent_default_logging.h"
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

static MQTTStatus_t addAwaitingOperation (MQTTAgentContext_t *pAgentContext, uint16_t packetId, MQTTAgentCommand_t *pCommand)
 Track an operation by adding it to a list, indicating it is anticipating an acknowledgment.
 
static MQTTAgentAckInfo_tgetAwaitingOperation (MQTTAgentContext_t *pAgentContext, uint16_t incomingPacketId)
 Retrieve an operation from the list of pending acks, and optionally remove it from the list.
 
static MQTTStatus_t createCommand (MQTTAgentCommandType_t commandType, const MQTTAgentContext_t *pMqttAgentContext, void *pMqttInfoParam, MQTTAgentCommandCallback_t commandCompleteCallback, MQTTAgentCommandContext_t *pCommandCompleteCallbackContext, MQTTAgentCommand_t *pCommand)
 Populate the parameters of a MQTTAgentCommand struct.
 
static MQTTStatus_t addCommandToQueue (const MQTTAgentContext_t *pAgentContext, MQTTAgentCommand_t *pCommand, uint32_t blockTimeMs)
 Add a command to the global command queue.
 
static MQTTStatus_t processCommand (MQTTAgentContext_t *pMqttAgentContext, MQTTAgentCommand_t *pCommand, bool *pEndLoop)
 Process a MQTTAgentCommand struct.
 
static void mqttEventCallback (MQTTContext_t *pMqttContext, MQTTPacketInfo_t *pPacketInfo, MQTTDeserializedInfo_t *pDeserializedInfo)
 Dispatch incoming publishes and acks to their various handler functions.
 
static void handleAcks (const MQTTAgentContext_t *pAgentContext, const MQTTPacketInfo_t *pPacketInfo, const MQTTDeserializedInfo_t *pDeserializedInfo, MQTTAgentAckInfo_t *pAckInfo, uint8_t packetType)
 Mark a command as complete after receiving an acknowledgment packet.
 
static MQTTAgentContext_tgetAgentFromMQTTContext (MQTTContext_t *pMQTTContext)
 Retrieve a pointer to an agent context given an MQTT context.
 
static MQTTStatus_t createAndAddCommand (MQTTAgentCommandType_t commandType, const MQTTAgentContext_t *pMqttAgentContext, void *pMqttInfoParam, MQTTAgentCommandCallback_t commandCompleteCallback, MQTTAgentCommandContext_t *pCommandCompleteCallbackContext, uint32_t blockTimeMs)
 Helper function for creating a command and adding it to the command queue.
 
static void concludeCommand (const MQTTAgentContext_t *pAgentContext, MQTTAgentCommand_t *pCommand, MQTTStatus_t returnCode, uint8_t *pSubackCodes)
 Helper function to mark a command as complete and invoke its callback. This function calls the releaseCommand callback.
 
static MQTTStatus_t resendPublishes (MQTTAgentContext_t *pMqttAgentContext)
 Resend QoS 1 and 2 publishes after resuming a session.
 
static void clearPendingAcknowledgments (MQTTAgentContext_t *pMqttAgentContext, bool clearOnlySubUnsubEntries)
 Clears the list of pending acknowledgments by invoking each callback with MQTTRecvFailed either for ALL operations in the list OR only for Subscribe/Unsubscribe operations.
 
static bool validateStruct (const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
 Validate an MQTTAgentContext_t and a MQTTAgentCommandInfo_t from API functions.
 
static bool validateParams (MQTTAgentCommandType_t commandType, const void *pParams)
 Validate the parameters for a CONNECT, SUBSCRIBE, UNSUBSCRIBE or PUBLISH.
 
static bool isSpaceInPendingAckList (const MQTTAgentContext_t *pAgentContext)
 Called before accepting any PUBLISH or SUBSCRIBE messages to check there is space in the pending ACK list for the outgoing PUBLISH or SUBSCRIBE.
 
MQTTStatus_t MQTTAgent_Init (MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentMessageInterface_t *pMsgInterface, const MQTTFixedBuffer_t *pNetworkBuffer, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getCurrentTimeMs, MQTTAgentIncomingPublishCallback_t incomingCallback, void *pIncomingPacketContext)
 Perform any initialization the MQTT agent requires before it can be used. Must be called before any other function.
 
MQTTStatus_t MQTTAgent_CommandLoop (MQTTAgentContext_t *pMqttAgentContext)
 Process commands from the command queue in a loop.
 
MQTTStatus_t MQTTAgent_ResumeSession (MQTTAgentContext_t *pMqttAgentContext, bool sessionPresent)
 Resume a session by resending publishes if a session is present in the broker, or clear state information if not.
 
MQTTStatus_t MQTTAgent_CancelAll (MQTTAgentContext_t *pMqttAgentContext)
 Cancel all enqueued commands and those awaiting acknowledgment while the command loop is not running.
 
MQTTStatus_t MQTTAgent_Subscribe (const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to call MQTT_Subscribe() for an MQTT connection.
 
MQTTStatus_t MQTTAgent_Unsubscribe (const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to call MQTT_Unsubscribe() for an MQTT connection.
 
MQTTStatus_t MQTTAgent_Publish (const MQTTAgentContext_t *pMqttAgentContext, MQTTPublishInfo_t *pPublishInfo, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to call MQTT_Publish() for an MQTT connection.
 
MQTTStatus_t MQTTAgent_ProcessLoop (const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
 Send a message to the MQTT agent purely to trigger an iteration of its loop, which will result in a call to MQTT_ProcessLoop(). This function can be used to wake the MQTT agent task when it is known data may be available on the connected socket.
 
MQTTStatus_t MQTTAgent_Connect (const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentConnectArgs_t *pConnectArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to call MQTT_Connect() for an MQTT connection. If a session is resumed with the broker, it will also resend the necessary QoS1/2 publishes.
 
MQTTStatus_t MQTTAgent_Disconnect (const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to disconnect an MQTT connection.
 
MQTTStatus_t MQTTAgent_Ping (const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to call MQTT_Ping() for an MQTT connection.
 
MQTTStatus_t MQTTAgent_Terminate (const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a termination command to the command queue.
 
+

Detailed Description

+

Implements an MQTT agent (or daemon task) to enable multithreaded access to coreMQTT.

+
Note
Implements an MQTT agent (or daemon task) on top of the coreMQTT MQTT client library. The agent makes coreMQTT usage thread safe by being the only task (or thread) in the system that is allowed to access the native coreMQTT API - and in so doing, serializes all access to coreMQTT even when multiple tasks are using the same MQTT connection.
+

The agent provides an equivalent API for each coreMQTT API. Whereas coreMQTT APIs are prefixed "MQTT_", the agent APIs are prefixed "MQTTAgent_". For example, that agent's MQTTAgent_Publish() API is the thread safe equivalent to coreMQTT's MQTT_Publish() API.

+

Function Documentation

+ +

◆ addAwaitingOperation()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t addAwaitingOperation (MQTTAgentContext_tpAgentContext,
uint16_t packetId,
MQTTAgentCommand_t * pCommand 
)
+
+static
+
+ +

Track an operation by adding it to a list, indicating it is anticipating an acknowledgment.

+
Parameters
+ + + + +
[in]pAgentContextAgent context for the MQTT connection.
[in]packetIdPacket ID of pending ack.
[in]pCommandPointer to command that is expecting an ack.
+
+
+
Returns
Returns one of the following:
    +
  • MQTTSuccess if an entry was added for the to the list.
  • +
  • MQTTStateCollision if there already exists an entry for the same packet ID in the list.
  • +
  • MQTTNoMemory if there is no space available in the list for adding a new entry.
  • +
+
+ +
+
+ +

◆ getAwaitingOperation()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTAgentAckInfo_t * getAwaitingOperation (MQTTAgentContext_tpAgentContext,
uint16_t incomingPacketId 
)
+
+static
+
+ +

Retrieve an operation from the list of pending acks, and optionally remove it from the list.

+
Parameters
+ + + +
[in]pAgentContextAgent context for the MQTT connection.
[in]incomingPacketIdPacket ID of incoming ack.
+
+
+
Returns
Pointer to stored information about the operation awaiting the ack. Returns NULL if the packet ID is zero or original command does not exist.
+ +
+
+ +

◆ createCommand()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t createCommand (MQTTAgentCommandType_t commandType,
const MQTTAgentContext_tpMqttAgentContext,
void * pMqttInfoParam,
MQTTAgentCommandCallback_t commandCompleteCallback,
MQTTAgentCommandContext_tpCommandCompleteCallbackContext,
MQTTAgentCommand_t * pCommand 
)
+
+static
+
+ +

Populate the parameters of a MQTTAgentCommand struct.

+
Parameters
+ + + + + + + +
[in]commandTypeType of command. For example, publish or subscribe.
[in]pMqttAgentContextPointer to MQTT context to use for command.
[in]pMqttInfoParamPointer to MQTTPublishInfo_t or MQTTSubscribeInfo_t.
[in]commandCompleteCallbackCallback for when command completes.
[in]pCommandCompleteCallbackContextContext and necessary structs for command.
[out]pCommandPointer to initialized command.
+
+
+
Returns
MQTTSuccess if all necessary fields for the command are passed, else an enumerated error code.
+ +
+
+ +

◆ addCommandToQueue()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t addCommandToQueue (const MQTTAgentContext_tpAgentContext,
MQTTAgentCommand_t * pCommand,
uint32_t blockTimeMs 
)
+
+static
+
+ +

Add a command to the global command queue.

+
Parameters
+ + + + +
[in]pAgentContextAgent context for the MQTT connection.
[in]pCommandPointer to command to copy to queue.
[in]blockTimeMsThe maximum amount of time to milliseconds to wait in the Blocked state (so not consuming any CPU time) for the command to be posted to the queue should the queue already be full.
+
+
+
Returns
MQTTSuccess if the command was added to the queue, else an enumerated error code.
+ +
+
+ +

◆ processCommand()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t processCommand (MQTTAgentContext_tpMqttAgentContext,
MQTTAgentCommand_t * pCommand,
bool * pEndLoop 
)
+
+static
+
+ +

Process a MQTTAgentCommand struct.

+
Note
This agent does not check existing subscriptions before sending a SUBSCRIBE or UNSUBSCRIBE packet. If a subscription already exists, then a SUBSCRIBE packet will be sent anyway, and if multiple tasks are subscribed to a topic filter, then they will all be unsubscribed after an UNSUBSCRIBE.
+
Parameters
+ + + + +
[in]pMqttAgentContextAgent context for MQTT connection.
[in]pCommandPointer to command to process.
[out]pEndLoopWhether the command loop should terminate.
+
+
+
Returns
status of MQTT library API call.
+ +
+
+ +

◆ mqttEventCallback()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static void mqttEventCallback (MQTTContext_tpMqttContext,
MQTTPacketInfo_tpPacketInfo,
MQTTDeserializedInfo_tpDeserializedInfo 
)
+
+static
+
+ +

Dispatch incoming publishes and acks to their various handler functions.

+
Parameters
+ + + + +
[in]pMqttContextMQTT Context
[in]pPacketInfoPointer to incoming packet.
[in]pDeserializedInfoPointer to deserialized information from the incoming packet.
+
+
+ +
+
+ +

◆ handleAcks()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static void handleAcks (const MQTTAgentContext_tpAgentContext,
const MQTTPacketInfo_tpPacketInfo,
const MQTTDeserializedInfo_tpDeserializedInfo,
MQTTAgentAckInfo_tpAckInfo,
uint8_t packetType 
)
+
+static
+
+ +

Mark a command as complete after receiving an acknowledgment packet.

+
Parameters
+ + + + + + +
[in]pAgentContextAgent context for the MQTT connection.
[in]pPacketInfoPointer to incoming packet.
[in]pDeserializedInfoPointer to deserialized information from the incoming packet.
[in]pAckInfoPointer to stored information for the original operation resulting in the received packet.
[in]packetTypeThe type of the incoming packet, either SUBACK, UNSUBACK, PUBACK, or PUBCOMP.
+
+
+ +
+
+ +

◆ getAgentFromMQTTContext()

+ +
+
+ + + + + +
+ + + + + + + + +
static MQTTAgentContext_t * getAgentFromMQTTContext (MQTTContext_tpMQTTContext)
+
+static
+
+ +

Retrieve a pointer to an agent context given an MQTT context.

+
Parameters
+ + +
[in]pMQTTContextMQTT Context to search for.
+
+
+
Returns
Pointer to agent context, or NULL.
+ +
+
+ +

◆ createAndAddCommand()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t createAndAddCommand (MQTTAgentCommandType_t commandType,
const MQTTAgentContext_tpMqttAgentContext,
void * pMqttInfoParam,
MQTTAgentCommandCallback_t commandCompleteCallback,
MQTTAgentCommandContext_tpCommandCompleteCallbackContext,
uint32_t blockTimeMs 
)
+
+static
+
+ +

Helper function for creating a command and adding it to the command queue.

+
Parameters
+ + + + + + + +
[in]commandTypeType of command.
[in]pMqttAgentContextHandle of the MQTT connection to use.
[in]pCommandCompleteCallbackContextContext and necessary structs for command.
[in]commandCompleteCallbackCallback for when command completes.
[in]pMqttInfoParamPointer to command argument.
[in]blockTimeMsMaximum amount of time in milliseconds to wait (in the Blocked state, so not consuming any CPU time) for the command to be posted to the MQTT agent should the MQTT agent's event queue be full.
+
+
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+ +
+
+ +

◆ concludeCommand()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static void concludeCommand (const MQTTAgentContext_tpAgentContext,
MQTTAgentCommand_t * pCommand,
MQTTStatus_t returnCode,
uint8_t * pSubackCodes 
)
+
+static
+
+ +

Helper function to mark a command as complete and invoke its callback. This function calls the releaseCommand callback.

+
Parameters
+ + + + + +
[in]pAgentContextAgent context for the MQTT connection.
[in]pCommandCommand to complete.
[in]returnCodeReturn status of command.
[in]pSubackCodesPointer to suback array, if command is a SUBSCRIBE.
+
+
+ +
+
+ +

◆ resendPublishes()

+ +
+
+ + + + + +
+ + + + + + + + +
static MQTTStatus_t resendPublishes (MQTTAgentContext_tpMqttAgentContext)
+
+static
+
+ +

Resend QoS 1 and 2 publishes after resuming a session.

+
Parameters
+ + +
[in]pMqttAgentContextAgent context for the MQTT connection.
+
+
+
Returns
MQTTSuccess if all publishes resent successfully, else error code from MQTT_Publish.
+ +
+
+ +

◆ clearPendingAcknowledgments()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static void clearPendingAcknowledgments (MQTTAgentContext_tpMqttAgentContext,
bool clearOnlySubUnsubEntries 
)
+
+static
+
+ +

Clears the list of pending acknowledgments by invoking each callback with MQTTRecvFailed either for ALL operations in the list OR only for Subscribe/Unsubscribe operations.

+
Parameters
+ + + +
[in]pMqttAgentContextAgent context of the MQTT connection.
[in]clearOnlySubUnsubEntriesFlag indicating whether all entries OR entries pertaining to only Subscribe/Unsubscribe operations should be cleaned from the list.
+
+
+ +
+
+ +

◆ validateStruct()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static bool validateStruct (const MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+static
+
+ +

Validate an MQTTAgentContext_t and a MQTTAgentCommandInfo_t from API functions.

+
Parameters
+ + + +
[in]pMqttAgentContextMQTTAgentContext_t to validate.
[in]pCommandInfoMQTTAgentCommandInfo_t to validate.
+
+
+
Returns
true if parameters are valid, else false.
+ +
+
+ +

◆ validateParams()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static bool validateParams (MQTTAgentCommandType_t commandType,
const void * pParams 
)
+
+static
+
+ +

Validate the parameters for a CONNECT, SUBSCRIBE, UNSUBSCRIBE or PUBLISH.

+
Parameters
+ + + +
[in]commandTypeCONNECT, SUBSCRIBE, UNSUBSCRIBE, or PUBLISH.
[in]pParamsParameter structure to validate.
+
+
+
Returns
true if parameter structure is valid, else false.
+ +
+
+ +

◆ isSpaceInPendingAckList()

+ +
+
+ + + + + +
+ + + + + + + + +
static bool isSpaceInPendingAckList (const MQTTAgentContext_tpAgentContext)
+
+static
+
+ +

Called before accepting any PUBLISH or SUBSCRIBE messages to check there is space in the pending ACK list for the outgoing PUBLISH or SUBSCRIBE.

+
Note
Because the MQTT agent is inherently multi threaded, and this function is called from the context of the application task and not the MQTT agent task, this function can only return a best effort result. It can definitely say if there is space for a new pending ACK when the function is called, but the case of space being exhausted when the agent executes a command that results in an ACK must still be handled.
+
Parameters
+ + +
[in]pAgentContextPointer to the context for the MQTT connection to which the PUBLISH or SUBSCRIBE message is to be sent.
+
+
+
Returns
true if there is space in that MQTT connection's ACK list, otherwise false;
+ +
+
+ +

◆ MQTTAgent_Init()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Init (MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentMessageInterface_tpMsgInterface,
const MQTTFixedBuffer_tpNetworkBuffer,
const TransportInterface_tpTransportInterface,
MQTTGetCurrentTimeFunc_t getCurrentTimeMs,
MQTTAgentIncomingPublishCallback_t incomingCallback,
void * pIncomingPacketContext 
)
+
+ +

Perform any initialization the MQTT agent requires before it can be used. Must be called before any other function.

+
Parameters
+ + + + + + + + +
[in]pMqttAgentContextPointer to struct to initialize.
[in]pMsgInterfaceCommand interface to use for allocating and sending commands.
[in]pNetworkBufferPointer to network buffer to use.
[in]pTransportInterfaceTransport interface to use with the MQTT library. See https://www.freertos.org/Documentation/03-Libraries/03-FreeRTOS-core/06-Transport-Interface/01-Transport-interface
[in]getCurrentTimeMsPointer to a function that returns a count value that increments every millisecond.
[in]incomingCallbackThe callback to execute when receiving publishes.
[in]pIncomingPacketContextA pointer to a context structure defined by the application writer.
+
+
+
Note
The pIncomingPacketContext context provided for the incoming publish callback MUST remain in scope throughout the period that the agent task is running.
+
Returns
Appropriate status code from MQTT_Init().
+

Example

// Function for obtaining a timestamp.
+
uint32_t getTimeStampMs();
+
// Callback function for receiving packets.
+
void incomingPublishCallback( MQTTAgentContext_t * pMqttAgentContext,
+
uint16_t packetId,
+
MQTTPublishInfo_t * pPublishInfo );
+
// Platform function for network send interface.
+
int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
+
// Platform for network receive interface.
+
int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
+
+
// Platform function for Agent Message Send.
+
bool agentSendMessage( MQTTAgentMessageContext_t * pMsgCtx,
+
MQTTAgentCommand_t * const * pCommandToSend,
+
uint32_t blockTimeMs );
+
// Platform function for Agent Message Receive.
+
bool agentReceiveMessage( MQTTAgentMessageContext_t * pMsgCtx,
+
MQTTAgentCommand_t ** pCommandToSend,
+
uint32_t blockTimeMs );
+
// Platform function to Get Agent Command.
+
MQTTAgentCommand_t * getCommand( uint32_t blockTimeMs );
+
// Platform function to Release Agent Command.
+
bool releaseCommand( MQTTAgentCommand_t * pCommandToRelease );
+
+
// Variables used in this example.
+
MQTTAgentMessageInterface_t messageInterface;
+ +
MQTTAgentContext_t agentContext;
+ +
// Buffer for storing outgoing and incoming MQTT packets.
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ 1024 ];
+
MQTTStatus_t status;
+
+
// Set transport interface members.
+
transport.pNetworkContext = &someTransportContext;
+
transport.send = networkSend;
+
transport.recv = networkRecv;
+
+
// Set agent message interface members.
+
messageInterface.pMsgCtx = &messageContext;
+
messageInterface.send = agentSendMessage;
+
messageInterface.recv = agentReceiveMessage;
+
messageInterface.getCommand = getCommand;
+
messageInterface.releaseCommand = releaseCommand;
+
+
// Set buffer members.
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = 1024;
+
+
status = MQTTAgent_Init( &agentContext,
+
&messageInterface,
+
&networkBuffer,
+
&transportInterface,
+
stubGetTime,
+
stubPublishCallback,
+
incomingPacketContext );
+
+
if( status == MQTTSuccess )
+
{
+
// Do something with agentContext. The transport and message interfaces, and
+
// fixedBuffer structs were copied into the context, so the original structs
+
// do not need to stay in scope.
+
}
+
MQTTStatus_t MQTTAgent_Init(MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentMessageInterface_t *pMsgInterface, const MQTTFixedBuffer_t *pNetworkBuffer, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getCurrentTimeMs, MQTTAgentIncomingPublishCallback_t incomingCallback, void *pIncomingPacketContext)
Perform any initialization the MQTT agent requires before it can be used. Must be called before any o...
Definition: core_mqtt_agent.c:968
+
struct MQTTAgentMessageContext MQTTAgentMessageContext_t
Context with which tasks may deliver messages to the agent.
Definition: core_mqtt_agent_message_interface.h:54
+
MQTTStatus_t
+
struct NetworkContext NetworkContext_t
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+
Function pointers and contexts used for sending and receiving commands, and allocating memory for the...
Definition: core_mqtt_agent_message_interface.h:133
+
MQTTAgentMessageContext_t * pMsgCtx
Definition: core_mqtt_agent_message_interface.h:134
+
MQTTAgentMessageRecv_t recv
Definition: core_mqtt_agent_message_interface.h:136
+
MQTTAgentCommandGet_t getCommand
Definition: core_mqtt_agent_message_interface.h:137
+
MQTTAgentMessageSend_t send
Definition: core_mqtt_agent_message_interface.h:135
+
MQTTAgentCommandRelease_t releaseCommand
Definition: core_mqtt_agent_message_interface.h:138
+ + + + + +
TransportSend_t send
+
TransportRecv_t recv
+
NetworkContext_t * pNetworkContext
+

Array used to maintain the outgoing publish records and their state by the coreMQTT library.

+

Array used to maintain the outgoing publish records and their state by the coreMQTT library.

+ +
+
+ +

◆ MQTTAgent_CommandLoop()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTTAgent_CommandLoop (MQTTAgentContext_tpMqttAgentContext)
+
+ +

Process commands from the command queue in a loop.

+
Parameters
+ + +
[in]pMqttAgentContextThe MQTT agent to use.
+
+
+
Returns
appropriate error code, or MQTTSuccess from a successful disconnect or termination.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTAgentContext_t mqttAgentContext;
+
+
status = MQTTAgent_CommandLoop( &mqttAgentContext );
+
+
// The function returns on either receiving a terminate command,
+
// undergoing network disconnection OR encountering an error.
+
if( ( status == MQTTSuccess ) && ( mqttAgentContext.mqttContext.connectStatus == MQTTNotConnected ) )
+
{
+
// A terminate command was processed and MQTT connection was closed.
+
// Need to close socket connection.
+
Platform_DisconnectNetwork( mqttAgentContext.mqttContext.transportInterface.pNetworkContext );
+
}
+
else if( status == MQTTSuccess )
+
{
+
// Terminate command was processed but MQTT connection was not
+
// closed. Thus, need to close both MQTT and socket connections.
+
status = MQTT_Disconnect( &( mqttAgentContext.mqttContext ) );
+
assert( status == MQTTSuccess );
+
Platform_DisconnectNetwork( mqttAgentContext.mqttContext.transportInterface.pNetworkContext );
+
}
+
else
+
{
+
// Handle error.
+
}
+
MQTTStatus_t MQTT_Disconnect(MQTTContext_t *pContext)
+
MQTTStatus_t MQTTAgent_CommandLoop(MQTTAgentContext_t *pMqttAgentContext)
Process commands from the command queue in a loop.
Definition: core_mqtt_agent.c:1043
+
MQTTContext_t mqttContext
Definition: core_mqtt_agent.h:154
+
MQTTConnectionStatus_t connectStatus
+
TransportInterface_t transportInterface
+
+
+
+ +

◆ MQTTAgent_ResumeSession()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_ResumeSession (MQTTAgentContext_tpMqttAgentContext,
bool sessionPresent 
)
+
+ +

Resume a session by resending publishes if a session is present in the broker, or clear state information if not.

+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]sessionPresentThe session present flag from the broker.
+
+
+
Note
This function is NOT thread-safe and should only be called from the context of the task responsible for MQTTAgent_CommandLoop.
+
Returns
MQTTSuccess if it succeeds in resending publishes, else an appropriate error code from MQTT_Publish()
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTAgentContext_t mqttAgentContext;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
bool sessionPresent;
+
+
// The example assumes that all variables have been filled with
+
// data for the MQTT_Connect call
+
// Refer to the MQTT_Connect API for a more detailed example.
+
+
// Attempt to resume session with the broker.
+
status = MQTT_Connect( &( mqttAgentContext.mqttContext ), &connectInfo, &willInfo, 100, &sessionPresent )
+
+
if( status == MQTTSuccess )
+
{
+
// Process the session present status sent by the broker.
+
status = MQTTAgent_ResumeSession( &mqttAgentContext, sessionPresent );
+
}
+
MQTTStatus_t MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
+
MQTTStatus_t MQTTAgent_ResumeSession(MQTTAgentContext_t *pMqttAgentContext, bool sessionPresent)
Resume a session by resending publishes if a session is present in the broker, or clear state informa...
Definition: core_mqtt_agent.c:1085
+ +
+
+
+ +

◆ MQTTAgent_CancelAll()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTTAgent_CancelAll (MQTTAgentContext_tpMqttAgentContext)
+
+ +

Cancel all enqueued commands and those awaiting acknowledgment while the command loop is not running.

+

Canceled commands will be terminated with return code MQTTRecvFailed.

+
Parameters
+ + +
[in]pMqttAgentContextThe MQTT agent to use.
+
+
+
Note
This function is NOT thread-safe and should only be called from the context of the task responsible for MQTTAgent_CommandLoop.
+
Returns
MQTTBadParameter if an invalid context is given, else MQTTSuccess.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTAgentContext_t mqttAgentContext;
+
+
status = MQTTAgent_CommandLoop( &mqttAgentContext );
+
+
//An error was returned, but reconnection is not desired. Cancel all commands
+
//that are in the queue or awaiting an acknowledgment.
+
if( status != MQTTSuccess )
+
{
+
//Cancel commands so any completion callbacks will be invoked.
+
status = MQTTAgent_CancelAll( &mqttAgentContext );
+
}
+
+
Platform_DisconnectNetwork( mqttAgentContext.mqttContext.transportInterface.pNetworkContext );
+
MQTTStatus_t MQTTAgent_CancelAll(MQTTAgentContext_t *pMqttAgentContext)
Cancel all enqueued commands and those awaiting acknowledgment while the command loop is not running.
Definition: core_mqtt_agent.c:1128
+
+
+
+ +

◆ MQTTAgent_Subscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Subscribe (const MQTTAgentContext_tpMqttAgentContext,
MQTTAgentSubscribeArgs_tpSubscriptionArgs,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to call MQTT_Subscribe() for an MQTT connection.

+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pSubscriptionArgsStruct describing topic to subscribe to.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
MQTTSubscribeInfo_t subscribeInfo = { 0 };
+
MQTTAgentSubscribeArgs_t subscribeArgs = { 0 };
+
+
// Function for command complete callback.
+
void subscribeCmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.CmdCompleteCallback = subscribeCmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
// Fill the information for topic filters to subscribe to.
+
subscribeInfo.qos = Qos1;
+
subscribeInfo.pTopicFilter = "/foo/bar";
+
subscribeInfo.topicFilterLength = strlen("/foo/bar");
+
subscribeArgs.pSubscribeInfo = &subscribeInfo;
+
subscribeArgs.numSubscriptions = 1U;
+
+
status = MQTTAgent_Subscribe( &agentContext, &subscribeArgs, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to send subscribe request to the server has been queued. Notification
+
// about completion of the subscribe operation will be notified to application
+
// through invocation of subscribeCmdCompleteCb().
+
}
+
MQTTStatus_t MQTTAgent_Subscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Subscribe() for an MQTT connection.
Definition: core_mqtt_agent.c:1177
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
Struct holding arguments that are common to every command.
Definition: core_mqtt_agent.h:189
+
uint32_t blockTimeMs
Maximum block time for enqueueing the command.
Definition: core_mqtt_agent.h:192
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+
Struct holding arguments for a SUBSCRIBE or UNSUBSCRIBE call.
Definition: core_mqtt_agent.h:167
+
MQTTSubscribeInfo_t * pSubscribeInfo
List of MQTT subscriptions.
Definition: core_mqtt_agent.h:168
+
size_t numSubscriptions
Number of elements in pSubscribeInfo.
Definition: core_mqtt_agent.h:169
+ + +
uint16_t topicFilterLength
+
const char * pTopicFilter
+
+
+
+ +

◆ MQTTAgent_Unsubscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Unsubscribe (const MQTTAgentContext_tpMqttAgentContext,
MQTTAgentSubscribeArgs_tpSubscriptionArgs,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to call MQTT_Unsubscribe() for an MQTT connection.

+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pSubscriptionArgsList of topics to unsubscribe from.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
MQTTSubscribeInfo_t unsubscribeInfo = { 0 };
+
MQTTAgentSubscribeArgs_t unsubscribeArgs = { 0 };
+
+
// Function for command complete callback.
+
void unsubscribeCmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = unsubscribeCmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
// Fill the information for topics to unsubscribe from.
+
unsubscribeInfo.pTopicFilter = "/foo/bar";
+
unsubscribeInfo.topicFilterLength = strlen("/foo/bar");
+
unsubscribeArgs.pSubscribeInfo = &unsubscribeInfo;
+
unsubscribeArgs.numSubscriptions = 1U;
+
+
status = MQTTAgent_Unsubscribe( &agentContext, &unsubscribeArgs, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to send Unsubscribe request to the server has been queued. Notification
+
// about completion of the Unsubscribe operation will be notified to application
+
// through invocation of unsubscribeCompleteCb().
+
}
+
MQTTStatus_t MQTTAgent_Unsubscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Unsubscribe() for an MQTT connection.
Definition: core_mqtt_agent.c:1202
+
MQTTAgentCommandCallback_t cmdCompleteCallback
Callback to invoke upon completion.
Definition: core_mqtt_agent.h:190
+
+
+
+ +

◆ MQTTAgent_Publish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Publish (const MQTTAgentContext_tpMqttAgentContext,
MQTTPublishInfo_tpPublishInfo,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to call MQTT_Publish() for an MQTT connection.

+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pPublishInfoMQTT PUBLISH information.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
MQTTPublishInfo_t publishInfo = { 0 };
+
+
// Function for command complete callback.
+
void publishCmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = publishCmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
// Fill the information for publish operation.
+
publishInfo.qos = MQTTQoS1;
+
publishInfo.pTopicName = "/some/topic/name";
+
publishInfo.topicNameLength = strlen( publishInfo.pTopicName );
+
publishInfo.pPayload = "Hello World!";
+
publishInfo.payloadLength = strlen( "Hello World!" );
+
+
status = MQTTAgent_Publish( &agentContext, &publishInfo, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to publish message to broker has been queued.
+
// The event of publish operation completion will be notified with
+
// the invocation of the publishCmdCompleteCb().
+
}
+
MQTTStatus_t MQTTAgent_Publish(const MQTTAgentContext_t *pMqttAgentContext, MQTTPublishInfo_t *pPublishInfo, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Publish() for an MQTT connection.
Definition: core_mqtt_agent.c:1227
+
MQTTQoS1
+ +
uint16_t topicNameLength
+ +
const char * pTopicName
+
const void * pPayload
+
+
+
+ +

◆ MQTTAgent_ProcessLoop()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_ProcessLoop (const MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Send a message to the MQTT agent purely to trigger an iteration of its loop, which will result in a call to MQTT_ProcessLoop(). This function can be used to wake the MQTT agent task when it is known data may be available on the connected socket.

+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void cmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = cmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_ProcessLoop( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to call MQTT_ProcessLoop() has been queued.
+
// After processing the command, if an incoming publish is received,
+
// the event will be notified with invocation of the incoming publish
+
// callback configured in the agent context.
+
}
+
MQTTStatus_t MQTTAgent_ProcessLoop(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Send a message to the MQTT agent purely to trigger an iteration of its loop, which will result in a c...
Definition: core_mqtt_agent.c:1252
+
+
+
+ +

◆ MQTTAgent_Connect()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Connect (const MQTTAgentContext_tpMqttAgentContext,
MQTTAgentConnectArgs_tpConnectArgs,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to call MQTT_Connect() for an MQTT connection. If a session is resumed with the broker, it will also resend the necessary QoS1/2 publishes.

+
Note
The MQTTAgent_Connect function is provided to give a thread safe equivalent to the MQTT_Connect API. However, it is RECOMMENDED that instead of the application tasks (i.e. tasks other than the agent task), the agent be responsible for creating the MQTT connection (by calling MQTT_Connect) before starting the command loop (with the MQTTAgent_CommandLoop() call). In that case, the agent SHOULD also be responsible for disconnecting the MQTT connection after the command loop has terminated (through an MQTTAgent_Terminate() call from an application task).
+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in,out]pConnectArgsStruct holding args for MQTT_Connect(). On a successful connection after the command is processed, the sessionPresent member will be filled to indicate whether the broker resumed an existing session.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
MQTTAgentConnectArgs_t connectionArgs;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// True for creating a new session with broker, false if we want to resume an old one.
+
connectInfo.cleanSession = true;
+
// Client ID must be unique to broker. This field is required.
+
connectInfo.pClientIdentifier = "someClientID";
+
connectInfo.clientIdentifierLength = strlen( connectInfo.pClientIdentifier );
+
+
// Value for keep alive.
+
connectInfo.keepAliveSeconds = 60;
+
// The following fields are optional.
+
// Optional username and password.
+
connectInfo.pUserName = "someUserName";
+
connectInfo.userNameLength = strlen( connectInfo.pUserName );
+
connectInfo.pPassword = "somePassword";
+
connectInfo.passwordLength = strlen( connectInfo.pPassword );
+
+
// The last will and testament is optional, it will be published by the broker
+
// should this client disconnect without sending a DISCONNECT packet.
+
willInfo.qos = MQTTQoS0;
+
willInfo.pTopicName = "/lwt/topic/name";
+
willInfo.topicNameLength = strlen( willInfo.pTopicName );
+
willInfo.pPayload = "LWT Message";
+
willInfo.payloadLength = strlen( "LWT Message" );
+
+
// Fill the MQTTAgentConnectArgs_t structure.
+
connectArgs.pConnectInfo = &connectInfo;
+
connectArgs.pWillInfo = &willInfo;
+
// Time to block for CONNACK response when command is processed.
+
connectArgs.timeoutMs = 500;
+
+
// Function for command complete callback.
+
void connectCmdCallback( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = connectCmdCallback;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Connect( &agentContext, &connectArgs, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command for creating the MQTT connection has been queued.
+
// The MQTT connection event will be notified through the
+
// invocation of connectCmdCallback().
+
}
+
MQTTStatus_t MQTTAgent_Connect(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentConnectArgs_t *pConnectArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Connect() for an MQTT connection. If a session is resumed with the broker,...
Definition: core_mqtt_agent.c:1275
+
MQTTQoS0
+
Struct holding arguments for a CONNECT call.
Definition: core_mqtt_agent.h:177
+
const char * pClientIdentifier
+
const char * pUserName
+ +
uint16_t userNameLength
+
uint16_t keepAliveSeconds
+
uint16_t clientIdentifierLength
+
uint16_t passwordLength
+
const char * pPassword
+
+
+
+ +

◆ MQTTAgent_Disconnect()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Disconnect (const MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to disconnect an MQTT connection.

+
Note
MQTTAgent_CommandLoop will return after processing a DISCONNECT command to allow the network connection to be disconnected. However, any pending commands in the queue, as well as those waiting for an acknowledgment, will NOT be terminated.
+
+The MQTTAgent_Disconnect function is provided to give a thread safe equivalent to the MQTT_Disconnect API. However, if the agent task is responsible for creating the MQTT connection (before calling MQTTAgent_CommandLoop()), then it is RECOMMENDED that an application task (i.e. a task other than the agent task) use MQTTAgent_Terminate to terminate the command loop in the agent, and the agent task be responsible for disconnecting the MQTT connection.
+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void disconnectCmdCallback( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = disconnectCmdCallback;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Disconnect( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command for closing the MQTT connection has been queued.
+
// The MQTT disconnection event will be notified through the
+
// invocation of disconnectCmdCallback().
+
}
+
MQTTStatus_t MQTTAgent_Disconnect(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to disconnect an MQTT connection.
Definition: core_mqtt_agent.c:1300
+
+
+
+ +

◆ MQTTAgent_Ping()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Ping (const MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to call MQTT_Ping() for an MQTT connection.

+
Note
This API function ONLY enqueues a command to send a ping request to the server, and DOES NOT wait for a ping response to be received from the server. To detect whether a Ping Response, has not been received from the server, the MQTTAgent_CommandLoop function SHOULD be used, which returns the MQTTKeepAliveTimeout return code on a ping response (or keep-alive) timeout.
+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void pingRequestCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = pingRequestCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Ping( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command for sending request has been queued. Application can
+
// handle keep-alive timeout if detected through return value of
+
// MQTTAgent_CommandLoop in the task running the agent.
+
}
+
MQTTStatus_t MQTTAgent_Ping(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Ping() for an MQTT connection.
Definition: core_mqtt_agent.c:1323
+
+
+
+ +

◆ MQTTAgent_Terminate()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Terminate (const MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a termination command to the command queue.

+

On command loop termination, all pending commands in the queue, as well as those waiting for an acknowledgment, will be terminated with error code MQTTRecvFailed.

+
Note
Commands may still be posted to the command queue after MQTTAgent_CommandLoop has returned. It is the responsibility of the application to cancel any commands that are posted while the command loop is not running, such as by invoking MQTTAgent_CancelAll.
+
+We RECOMMEND that this function is used from application task(s), that is a task not running the agent, to terminate the agent loop instead of calling MQTTAgent_Disconnect, so that the logic for creating and closing MQTT connection is owned by the agent task.
+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void terminateCallback( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = terminateCallback;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Terminate( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to terminate the agent loop has been queued.
+
}
+
MQTTStatus_t MQTTAgent_Terminate(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a termination command to the command queue.
Definition: core_mqtt_agent.c:1346
+
+
+
+
+
+ + + + diff --git a/latest/core__mqtt__agent_8h.html b/latest/core__mqtt__agent_8h.html new file mode 100644 index 00000000..a6740486 --- /dev/null +++ b/latest/core__mqtt__agent_8h.html @@ -0,0 +1,1197 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_agent.h File Reference
+
+
+ +

Functions for running a coreMQTT client in a dedicated thread. +More...

+ +

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + + + + + + + +

+Data Structures

struct  MQTTAgentReturnInfo_t
 Struct holding return codes and outputs from a command. More...
 
struct  MQTTAgentCommand_t
 The commands sent from the APIs to the MQTT agent task. More...
 
struct  MQTTAgentAckInfo_t
 Information for a pending MQTT ack packet expected by the agent. More...
 
struct  MQTTAgentContext_t
 Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(), and every API function will accept a pointer to the initalized struct. More...
 
struct  MQTTAgentSubscribeArgs_t
 Struct holding arguments for a SUBSCRIBE or UNSUBSCRIBE call. More...
 
struct  MQTTAgentConnectArgs_t
 Struct holding arguments for a CONNECT call. More...
 
struct  MQTTAgentCommandInfo_t
 Struct holding arguments that are common to every command. More...
 
+ + + + + + + + + + +

+Typedefs

typedef struct MQTTAgentCommandContext MQTTAgentCommandContext_t
 Struct containing context for a specific command.
 
typedef void(* MQTTAgentCommandCallback_t) (MQTTAgentCommandContext_t *pCmdCallbackContext, MQTTAgentReturnInfo_t *pReturnInfo)
 Callback function called when a command completes.
 
typedef void(* MQTTAgentIncomingPublishCallback_t) (struct MQTTAgentContext *pMqttAgentContext, uint16_t packetId, MQTTPublishInfo_t *pPublishInfo)
 Callback function called when receiving a publish.
 
+ + + + +

+Enumerations

enum  MQTTAgentCommandType_t {
+  NONE = 0 +, PROCESSLOOP +, PUBLISH +, SUBSCRIBE +,
+  UNSUBSCRIBE +, PING +, CONNECT +, DISCONNECT +,
+  TERMINATE +, NUM_COMMANDS +
+ }
 A type of command for interacting with the MQTT API. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

MQTTStatus_t MQTTAgent_Init (MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentMessageInterface_t *pMsgInterface, const MQTTFixedBuffer_t *pNetworkBuffer, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getCurrentTimeMs, MQTTAgentIncomingPublishCallback_t incomingCallback, void *pIncomingPacketContext)
 Perform any initialization the MQTT agent requires before it can be used. Must be called before any other function.
 
MQTTStatus_t MQTTAgent_CommandLoop (MQTTAgentContext_t *pMqttAgentContext)
 Process commands from the command queue in a loop.
 
MQTTStatus_t MQTTAgent_ResumeSession (MQTTAgentContext_t *pMqttAgentContext, bool sessionPresent)
 Resume a session by resending publishes if a session is present in the broker, or clear state information if not.
 
MQTTStatus_t MQTTAgent_CancelAll (MQTTAgentContext_t *pMqttAgentContext)
 Cancel all enqueued commands and those awaiting acknowledgment while the command loop is not running.
 
MQTTStatus_t MQTTAgent_Subscribe (const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to call MQTT_Subscribe() for an MQTT connection.
 
MQTTStatus_t MQTTAgent_Unsubscribe (const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to call MQTT_Unsubscribe() for an MQTT connection.
 
MQTTStatus_t MQTTAgent_Publish (const MQTTAgentContext_t *pMqttAgentContext, MQTTPublishInfo_t *pPublishInfo, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to call MQTT_Publish() for an MQTT connection.
 
MQTTStatus_t MQTTAgent_ProcessLoop (const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
 Send a message to the MQTT agent purely to trigger an iteration of its loop, which will result in a call to MQTT_ProcessLoop(). This function can be used to wake the MQTT agent task when it is known data may be available on the connected socket.
 
MQTTStatus_t MQTTAgent_Ping (const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to call MQTT_Ping() for an MQTT connection.
 
MQTTStatus_t MQTTAgent_Connect (const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentConnectArgs_t *pConnectArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to call MQTT_Connect() for an MQTT connection. If a session is resumed with the broker, it will also resend the necessary QoS1/2 publishes.
 
MQTTStatus_t MQTTAgent_Disconnect (const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to disconnect an MQTT connection.
 
MQTTStatus_t MQTTAgent_Terminate (const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a termination command to the command queue.
 
+

Detailed Description

+

Functions for running a coreMQTT client in a dedicated thread.

+

Function Documentation

+ +

◆ MQTTAgent_Init()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Init (MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentMessageInterface_tpMsgInterface,
const MQTTFixedBuffer_tpNetworkBuffer,
const TransportInterface_tpTransportInterface,
MQTTGetCurrentTimeFunc_t getCurrentTimeMs,
MQTTAgentIncomingPublishCallback_t incomingCallback,
void * pIncomingPacketContext 
)
+
+ +

Perform any initialization the MQTT agent requires before it can be used. Must be called before any other function.

+
Parameters
+ + + + + + + + +
[in]pMqttAgentContextPointer to struct to initialize.
[in]pMsgInterfaceCommand interface to use for allocating and sending commands.
[in]pNetworkBufferPointer to network buffer to use.
[in]pTransportInterfaceTransport interface to use with the MQTT library. See https://www.freertos.org/Documentation/03-Libraries/03-FreeRTOS-core/06-Transport-Interface/01-Transport-interface
[in]getCurrentTimeMsPointer to a function that returns a count value that increments every millisecond.
[in]incomingCallbackThe callback to execute when receiving publishes.
[in]pIncomingPacketContextA pointer to a context structure defined by the application writer.
+
+
+
Note
The pIncomingPacketContext context provided for the incoming publish callback MUST remain in scope throughout the period that the agent task is running.
+
Returns
Appropriate status code from MQTT_Init().
+

Example

// Function for obtaining a timestamp.
+
uint32_t getTimeStampMs();
+
// Callback function for receiving packets.
+
void incomingPublishCallback( MQTTAgentContext_t * pMqttAgentContext,
+
uint16_t packetId,
+
MQTTPublishInfo_t * pPublishInfo );
+
// Platform function for network send interface.
+
int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
+
// Platform for network receive interface.
+
int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
+
+
// Platform function for Agent Message Send.
+
bool agentSendMessage( MQTTAgentMessageContext_t * pMsgCtx,
+
MQTTAgentCommand_t * const * pCommandToSend,
+
uint32_t blockTimeMs );
+
// Platform function for Agent Message Receive.
+
bool agentReceiveMessage( MQTTAgentMessageContext_t * pMsgCtx,
+
MQTTAgentCommand_t ** pCommandToSend,
+
uint32_t blockTimeMs );
+
// Platform function to Get Agent Command.
+
MQTTAgentCommand_t * getCommand( uint32_t blockTimeMs );
+
// Platform function to Release Agent Command.
+
bool releaseCommand( MQTTAgentCommand_t * pCommandToRelease );
+
+
// Variables used in this example.
+
MQTTAgentMessageInterface_t messageInterface;
+ +
MQTTAgentContext_t agentContext;
+ +
// Buffer for storing outgoing and incoming MQTT packets.
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ 1024 ];
+
MQTTStatus_t status;
+
+
// Set transport interface members.
+
transport.pNetworkContext = &someTransportContext;
+
transport.send = networkSend;
+
transport.recv = networkRecv;
+
+
// Set agent message interface members.
+
messageInterface.pMsgCtx = &messageContext;
+
messageInterface.send = agentSendMessage;
+
messageInterface.recv = agentReceiveMessage;
+
messageInterface.getCommand = getCommand;
+
messageInterface.releaseCommand = releaseCommand;
+
+
// Set buffer members.
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = 1024;
+
+
status = MQTTAgent_Init( &agentContext,
+
&messageInterface,
+
&networkBuffer,
+
&transportInterface,
+
stubGetTime,
+
stubPublishCallback,
+
incomingPacketContext );
+
+
if( status == MQTTSuccess )
+
{
+
// Do something with agentContext. The transport and message interfaces, and
+
// fixedBuffer structs were copied into the context, so the original structs
+
// do not need to stay in scope.
+
}
+
MQTTStatus_t MQTTAgent_Init(MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentMessageInterface_t *pMsgInterface, const MQTTFixedBuffer_t *pNetworkBuffer, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getCurrentTimeMs, MQTTAgentIncomingPublishCallback_t incomingCallback, void *pIncomingPacketContext)
Perform any initialization the MQTT agent requires before it can be used. Must be called before any o...
Definition: core_mqtt_agent.c:968
+
struct MQTTAgentMessageContext MQTTAgentMessageContext_t
Context with which tasks may deliver messages to the agent.
Definition: core_mqtt_agent_message_interface.h:54
+
MQTTStatus_t
+
struct NetworkContext NetworkContext_t
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+
Function pointers and contexts used for sending and receiving commands, and allocating memory for the...
Definition: core_mqtt_agent_message_interface.h:133
+
MQTTAgentMessageContext_t * pMsgCtx
Definition: core_mqtt_agent_message_interface.h:134
+
MQTTAgentMessageRecv_t recv
Definition: core_mqtt_agent_message_interface.h:136
+
MQTTAgentCommandGet_t getCommand
Definition: core_mqtt_agent_message_interface.h:137
+
MQTTAgentMessageSend_t send
Definition: core_mqtt_agent_message_interface.h:135
+
MQTTAgentCommandRelease_t releaseCommand
Definition: core_mqtt_agent_message_interface.h:138
+ + + + + +
TransportSend_t send
+
TransportRecv_t recv
+
NetworkContext_t * pNetworkContext
+

Array used to maintain the outgoing publish records and their state by the coreMQTT library.

+

Array used to maintain the outgoing publish records and their state by the coreMQTT library.

+ +
+
+ +

◆ MQTTAgent_CommandLoop()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTTAgent_CommandLoop (MQTTAgentContext_tpMqttAgentContext)
+
+ +

Process commands from the command queue in a loop.

+
Parameters
+ + +
[in]pMqttAgentContextThe MQTT agent to use.
+
+
+
Returns
appropriate error code, or MQTTSuccess from a successful disconnect or termination.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTAgentContext_t mqttAgentContext;
+
+
status = MQTTAgent_CommandLoop( &mqttAgentContext );
+
+
// The function returns on either receiving a terminate command,
+
// undergoing network disconnection OR encountering an error.
+
if( ( status == MQTTSuccess ) && ( mqttAgentContext.mqttContext.connectStatus == MQTTNotConnected ) )
+
{
+
// A terminate command was processed and MQTT connection was closed.
+
// Need to close socket connection.
+
Platform_DisconnectNetwork( mqttAgentContext.mqttContext.transportInterface.pNetworkContext );
+
}
+
else if( status == MQTTSuccess )
+
{
+
// Terminate command was processed but MQTT connection was not
+
// closed. Thus, need to close both MQTT and socket connections.
+
status = MQTT_Disconnect( &( mqttAgentContext.mqttContext ) );
+
assert( status == MQTTSuccess );
+
Platform_DisconnectNetwork( mqttAgentContext.mqttContext.transportInterface.pNetworkContext );
+
}
+
else
+
{
+
// Handle error.
+
}
+
MQTTStatus_t MQTT_Disconnect(MQTTContext_t *pContext)
+
MQTTStatus_t MQTTAgent_CommandLoop(MQTTAgentContext_t *pMqttAgentContext)
Process commands from the command queue in a loop.
Definition: core_mqtt_agent.c:1043
+
MQTTContext_t mqttContext
Definition: core_mqtt_agent.h:154
+
MQTTConnectionStatus_t connectStatus
+
TransportInterface_t transportInterface
+
+
+
+ +

◆ MQTTAgent_ResumeSession()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_ResumeSession (MQTTAgentContext_tpMqttAgentContext,
bool sessionPresent 
)
+
+ +

Resume a session by resending publishes if a session is present in the broker, or clear state information if not.

+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]sessionPresentThe session present flag from the broker.
+
+
+
Note
This function is NOT thread-safe and should only be called from the context of the task responsible for MQTTAgent_CommandLoop.
+
Returns
MQTTSuccess if it succeeds in resending publishes, else an appropriate error code from MQTT_Publish()
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTAgentContext_t mqttAgentContext;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
bool sessionPresent;
+
+
// The example assumes that all variables have been filled with
+
// data for the MQTT_Connect call
+
// Refer to the MQTT_Connect API for a more detailed example.
+
+
// Attempt to resume session with the broker.
+
status = MQTT_Connect( &( mqttAgentContext.mqttContext ), &connectInfo, &willInfo, 100, &sessionPresent )
+
+
if( status == MQTTSuccess )
+
{
+
// Process the session present status sent by the broker.
+
status = MQTTAgent_ResumeSession( &mqttAgentContext, sessionPresent );
+
}
+
MQTTStatus_t MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
+
MQTTStatus_t MQTTAgent_ResumeSession(MQTTAgentContext_t *pMqttAgentContext, bool sessionPresent)
Resume a session by resending publishes if a session is present in the broker, or clear state informa...
Definition: core_mqtt_agent.c:1085
+ +
+
+
+ +

◆ MQTTAgent_CancelAll()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTTAgent_CancelAll (MQTTAgentContext_tpMqttAgentContext)
+
+ +

Cancel all enqueued commands and those awaiting acknowledgment while the command loop is not running.

+

Canceled commands will be terminated with return code MQTTRecvFailed.

+
Parameters
+ + +
[in]pMqttAgentContextThe MQTT agent to use.
+
+
+
Note
This function is NOT thread-safe and should only be called from the context of the task responsible for MQTTAgent_CommandLoop.
+
Returns
MQTTBadParameter if an invalid context is given, else MQTTSuccess.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTAgentContext_t mqttAgentContext;
+
+
status = MQTTAgent_CommandLoop( &mqttAgentContext );
+
+
//An error was returned, but reconnection is not desired. Cancel all commands
+
//that are in the queue or awaiting an acknowledgment.
+
if( status != MQTTSuccess )
+
{
+
//Cancel commands so any completion callbacks will be invoked.
+
status = MQTTAgent_CancelAll( &mqttAgentContext );
+
}
+
+
Platform_DisconnectNetwork( mqttAgentContext.mqttContext.transportInterface.pNetworkContext );
+
MQTTStatus_t MQTTAgent_CancelAll(MQTTAgentContext_t *pMqttAgentContext)
Cancel all enqueued commands and those awaiting acknowledgment while the command loop is not running.
Definition: core_mqtt_agent.c:1128
+
+
+
+ +

◆ MQTTAgent_Subscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Subscribe (const MQTTAgentContext_tpMqttAgentContext,
MQTTAgentSubscribeArgs_tpSubscriptionArgs,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to call MQTT_Subscribe() for an MQTT connection.

+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pSubscriptionArgsStruct describing topic to subscribe to.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
MQTTSubscribeInfo_t subscribeInfo = { 0 };
+
MQTTAgentSubscribeArgs_t subscribeArgs = { 0 };
+
+
// Function for command complete callback.
+
void subscribeCmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.CmdCompleteCallback = subscribeCmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
// Fill the information for topic filters to subscribe to.
+
subscribeInfo.qos = Qos1;
+
subscribeInfo.pTopicFilter = "/foo/bar";
+
subscribeInfo.topicFilterLength = strlen("/foo/bar");
+
subscribeArgs.pSubscribeInfo = &subscribeInfo;
+
subscribeArgs.numSubscriptions = 1U;
+
+
status = MQTTAgent_Subscribe( &agentContext, &subscribeArgs, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to send subscribe request to the server has been queued. Notification
+
// about completion of the subscribe operation will be notified to application
+
// through invocation of subscribeCmdCompleteCb().
+
}
+
MQTTStatus_t MQTTAgent_Subscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Subscribe() for an MQTT connection.
Definition: core_mqtt_agent.c:1177
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
Struct holding arguments that are common to every command.
Definition: core_mqtt_agent.h:189
+
uint32_t blockTimeMs
Maximum block time for enqueueing the command.
Definition: core_mqtt_agent.h:192
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+
Struct holding arguments for a SUBSCRIBE or UNSUBSCRIBE call.
Definition: core_mqtt_agent.h:167
+
MQTTSubscribeInfo_t * pSubscribeInfo
List of MQTT subscriptions.
Definition: core_mqtt_agent.h:168
+
size_t numSubscriptions
Number of elements in pSubscribeInfo.
Definition: core_mqtt_agent.h:169
+ + +
uint16_t topicFilterLength
+
const char * pTopicFilter
+
+
+
+ +

◆ MQTTAgent_Unsubscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Unsubscribe (const MQTTAgentContext_tpMqttAgentContext,
MQTTAgentSubscribeArgs_tpSubscriptionArgs,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to call MQTT_Unsubscribe() for an MQTT connection.

+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pSubscriptionArgsList of topics to unsubscribe from.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
MQTTSubscribeInfo_t unsubscribeInfo = { 0 };
+
MQTTAgentSubscribeArgs_t unsubscribeArgs = { 0 };
+
+
// Function for command complete callback.
+
void unsubscribeCmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = unsubscribeCmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
// Fill the information for topics to unsubscribe from.
+
unsubscribeInfo.pTopicFilter = "/foo/bar";
+
unsubscribeInfo.topicFilterLength = strlen("/foo/bar");
+
unsubscribeArgs.pSubscribeInfo = &unsubscribeInfo;
+
unsubscribeArgs.numSubscriptions = 1U;
+
+
status = MQTTAgent_Unsubscribe( &agentContext, &unsubscribeArgs, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to send Unsubscribe request to the server has been queued. Notification
+
// about completion of the Unsubscribe operation will be notified to application
+
// through invocation of unsubscribeCompleteCb().
+
}
+
MQTTStatus_t MQTTAgent_Unsubscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Unsubscribe() for an MQTT connection.
Definition: core_mqtt_agent.c:1202
+
MQTTAgentCommandCallback_t cmdCompleteCallback
Callback to invoke upon completion.
Definition: core_mqtt_agent.h:190
+
+
+
+ +

◆ MQTTAgent_Publish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Publish (const MQTTAgentContext_tpMqttAgentContext,
MQTTPublishInfo_tpPublishInfo,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to call MQTT_Publish() for an MQTT connection.

+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pPublishInfoMQTT PUBLISH information.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
MQTTPublishInfo_t publishInfo = { 0 };
+
+
// Function for command complete callback.
+
void publishCmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = publishCmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
// Fill the information for publish operation.
+
publishInfo.qos = MQTTQoS1;
+
publishInfo.pTopicName = "/some/topic/name";
+
publishInfo.topicNameLength = strlen( publishInfo.pTopicName );
+
publishInfo.pPayload = "Hello World!";
+
publishInfo.payloadLength = strlen( "Hello World!" );
+
+
status = MQTTAgent_Publish( &agentContext, &publishInfo, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to publish message to broker has been queued.
+
// The event of publish operation completion will be notified with
+
// the invocation of the publishCmdCompleteCb().
+
}
+
MQTTStatus_t MQTTAgent_Publish(const MQTTAgentContext_t *pMqttAgentContext, MQTTPublishInfo_t *pPublishInfo, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Publish() for an MQTT connection.
Definition: core_mqtt_agent.c:1227
+
MQTTQoS1
+ +
uint16_t topicNameLength
+ +
const char * pTopicName
+
const void * pPayload
+
+
+
+ +

◆ MQTTAgent_ProcessLoop()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_ProcessLoop (const MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Send a message to the MQTT agent purely to trigger an iteration of its loop, which will result in a call to MQTT_ProcessLoop(). This function can be used to wake the MQTT agent task when it is known data may be available on the connected socket.

+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void cmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = cmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_ProcessLoop( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to call MQTT_ProcessLoop() has been queued.
+
// After processing the command, if an incoming publish is received,
+
// the event will be notified with invocation of the incoming publish
+
// callback configured in the agent context.
+
}
+
MQTTStatus_t MQTTAgent_ProcessLoop(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Send a message to the MQTT agent purely to trigger an iteration of its loop, which will result in a c...
Definition: core_mqtt_agent.c:1252
+
+
+
+ +

◆ MQTTAgent_Ping()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Ping (const MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to call MQTT_Ping() for an MQTT connection.

+
Note
This API function ONLY enqueues a command to send a ping request to the server, and DOES NOT wait for a ping response to be received from the server. To detect whether a Ping Response, has not been received from the server, the MQTTAgent_CommandLoop function SHOULD be used, which returns the MQTTKeepAliveTimeout return code on a ping response (or keep-alive) timeout.
+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void pingRequestCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = pingRequestCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Ping( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command for sending request has been queued. Application can
+
// handle keep-alive timeout if detected through return value of
+
// MQTTAgent_CommandLoop in the task running the agent.
+
}
+
MQTTStatus_t MQTTAgent_Ping(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Ping() for an MQTT connection.
Definition: core_mqtt_agent.c:1323
+
+
+
+ +

◆ MQTTAgent_Connect()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Connect (const MQTTAgentContext_tpMqttAgentContext,
MQTTAgentConnectArgs_tpConnectArgs,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to call MQTT_Connect() for an MQTT connection. If a session is resumed with the broker, it will also resend the necessary QoS1/2 publishes.

+
Note
The MQTTAgent_Connect function is provided to give a thread safe equivalent to the MQTT_Connect API. However, it is RECOMMENDED that instead of the application tasks (i.e. tasks other than the agent task), the agent be responsible for creating the MQTT connection (by calling MQTT_Connect) before starting the command loop (with the MQTTAgent_CommandLoop() call). In that case, the agent SHOULD also be responsible for disconnecting the MQTT connection after the command loop has terminated (through an MQTTAgent_Terminate() call from an application task).
+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in,out]pConnectArgsStruct holding args for MQTT_Connect(). On a successful connection after the command is processed, the sessionPresent member will be filled to indicate whether the broker resumed an existing session.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
MQTTAgentConnectArgs_t connectionArgs;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// True for creating a new session with broker, false if we want to resume an old one.
+
connectInfo.cleanSession = true;
+
// Client ID must be unique to broker. This field is required.
+
connectInfo.pClientIdentifier = "someClientID";
+
connectInfo.clientIdentifierLength = strlen( connectInfo.pClientIdentifier );
+
+
// Value for keep alive.
+
connectInfo.keepAliveSeconds = 60;
+
// The following fields are optional.
+
// Optional username and password.
+
connectInfo.pUserName = "someUserName";
+
connectInfo.userNameLength = strlen( connectInfo.pUserName );
+
connectInfo.pPassword = "somePassword";
+
connectInfo.passwordLength = strlen( connectInfo.pPassword );
+
+
// The last will and testament is optional, it will be published by the broker
+
// should this client disconnect without sending a DISCONNECT packet.
+
willInfo.qos = MQTTQoS0;
+
willInfo.pTopicName = "/lwt/topic/name";
+
willInfo.topicNameLength = strlen( willInfo.pTopicName );
+
willInfo.pPayload = "LWT Message";
+
willInfo.payloadLength = strlen( "LWT Message" );
+
+
// Fill the MQTTAgentConnectArgs_t structure.
+
connectArgs.pConnectInfo = &connectInfo;
+
connectArgs.pWillInfo = &willInfo;
+
// Time to block for CONNACK response when command is processed.
+
connectArgs.timeoutMs = 500;
+
+
// Function for command complete callback.
+
void connectCmdCallback( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = connectCmdCallback;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Connect( &agentContext, &connectArgs, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command for creating the MQTT connection has been queued.
+
// The MQTT connection event will be notified through the
+
// invocation of connectCmdCallback().
+
}
+
MQTTStatus_t MQTTAgent_Connect(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentConnectArgs_t *pConnectArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Connect() for an MQTT connection. If a session is resumed with the broker,...
Definition: core_mqtt_agent.c:1275
+
MQTTQoS0
+
Struct holding arguments for a CONNECT call.
Definition: core_mqtt_agent.h:177
+
const char * pClientIdentifier
+
const char * pUserName
+ +
uint16_t userNameLength
+
uint16_t keepAliveSeconds
+
uint16_t clientIdentifierLength
+
uint16_t passwordLength
+
const char * pPassword
+
+
+
+ +

◆ MQTTAgent_Disconnect()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Disconnect (const MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to disconnect an MQTT connection.

+
Note
MQTTAgent_CommandLoop will return after processing a DISCONNECT command to allow the network connection to be disconnected. However, any pending commands in the queue, as well as those waiting for an acknowledgment, will NOT be terminated.
+
+The MQTTAgent_Disconnect function is provided to give a thread safe equivalent to the MQTT_Disconnect API. However, if the agent task is responsible for creating the MQTT connection (before calling MQTTAgent_CommandLoop()), then it is RECOMMENDED that an application task (i.e. a task other than the agent task) use MQTTAgent_Terminate to terminate the command loop in the agent, and the agent task be responsible for disconnecting the MQTT connection.
+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void disconnectCmdCallback( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = disconnectCmdCallback;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Disconnect( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command for closing the MQTT connection has been queued.
+
// The MQTT disconnection event will be notified through the
+
// invocation of disconnectCmdCallback().
+
}
+
MQTTStatus_t MQTTAgent_Disconnect(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to disconnect an MQTT connection.
Definition: core_mqtt_agent.c:1300
+
+
+
+ +

◆ MQTTAgent_Terminate()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Terminate (const MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a termination command to the command queue.

+

On command loop termination, all pending commands in the queue, as well as those waiting for an acknowledgment, will be terminated with error code MQTTRecvFailed.

+
Note
Commands may still be posted to the command queue after MQTTAgent_CommandLoop has returned. It is the responsibility of the application to cancel any commands that are posted while the command loop is not running, such as by invoking MQTTAgent_CancelAll.
+
+We RECOMMEND that this function is used from application task(s), that is a task not running the agent, to terminate the agent loop instead of calling MQTTAgent_Disconnect, so that the logic for creating and closing MQTT connection is owned by the agent task.
+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void terminateCallback( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = terminateCallback;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Terminate( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to terminate the agent loop has been queued.
+
}
+
MQTTStatus_t MQTTAgent_Terminate(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a termination command to the command queue.
Definition: core_mqtt_agent.c:1346
+
+
+
+
+
+ + + + diff --git a/latest/core__mqtt__agent_8h_source.html b/latest/core__mqtt__agent_8h_source.html new file mode 100644 index 00000000..ee2d34a4 --- /dev/null +++ b/latest/core__mqtt__agent_8h_source.html @@ -0,0 +1,374 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
core_mqtt_agent.h
+
+
+Go to the documentation of this file.
1/*
+
2 * coreMQTT Agent <v1.3.0>
+
3 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
4 *
+
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
+
6 * this software and associated documentation files (the "Software"), to deal in
+
7 * the Software without restriction, including without limitation the rights to
+
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
9 * the Software, and to permit persons to whom the Software is furnished to do so,
+
10 * subject to the following conditions:
+
11 *
+
12 * The above copyright notice and this permission notice shall be included in all
+
13 * copies or substantial portions of the Software.
+
14 *
+
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
21 */
+
22
+
27#ifndef CORE_MQTT_AGENT_H
+
28#define CORE_MQTT_AGENT_H
+
29
+
30/* *INDENT-OFF* */
+
31#ifdef __cplusplus
+
32 extern "C" {
+
33#endif
+
34/* *INDENT-ON* */
+
35
+
36/* MQTT library includes. */
+
37#include "core_mqtt.h"
+
38#include "core_mqtt_state.h"
+
39
+ +
41
+
42/* Command messaging interface include. */
+ +
44
+
49typedef enum MQTTCommandType
+
50{
+
51 NONE = 0,
+ + + + + + + + + + +
62
+
63struct MQTTAgentContext;
+
64struct MQTTAgentCommandContext;
+
65
+
70typedef struct MQTTAgentReturnInfo
+
71{
+ +
73 uint8_t * pSubackCodes;
+ +
75
+
83typedef struct MQTTAgentCommandContext MQTTAgentCommandContext_t;
+
84
+
101typedef void (* MQTTAgentCommandCallback_t )( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
102 MQTTAgentReturnInfo_t * pReturnInfo );
+
103
+ +
111{
+ +
113 void * pArgs;
+ + +
116};
+
117
+
122typedef struct MQTTAckInfo
+
123{
+
124 uint16_t packetId;
+
125 MQTTAgentCommand_t * pOriginalCommand;
+ +
127
+
142typedef void (* MQTTAgentIncomingPublishCallback_t )( struct MQTTAgentContext * pMqttAgentContext,
+
143 uint16_t packetId,
+
144 MQTTPublishInfo_t * pPublishInfo );
+
145
+
152typedef struct MQTTAgentContext
+
153{
+ + + + + + + +
161
+
166typedef struct MQTTAgentSubscribeArgs
+
167{
+ + + +
171
+
176typedef struct MQTTAgentConnectArgs
+
177{
+ + +
180 uint32_t timeoutMs;
+ + +
183
+
188typedef struct MQTTAgentCommandInfo
+
189{
+ + +
192 uint32_t blockTimeMs;
+ +
194
+
195/*-----------------------------------------------------------*/
+
196
+
286/* @[declare_mqtt_agent_init] */
+ +
288 const MQTTAgentMessageInterface_t * pMsgInterface,
+
289 const MQTTFixedBuffer_t * pNetworkBuffer,
+
290 const TransportInterface_t * pTransportInterface,
+
291 MQTTGetCurrentTimeFunc_t getCurrentTimeMs,
+
292 MQTTAgentIncomingPublishCallback_t incomingCallback,
+
293 void * pIncomingPacketContext );
+
294/* @[declare_mqtt_agent_init] */
+
295
+
336/* @[declare_mqtt_agent_commandloop] */
+ +
338/* @[declare_mqtt_agent_commandloop] */
+
339
+
377/* @[declare_mqtt_agent_resumesession] */
+ +
379 bool sessionPresent );
+
380/* @[declare_mqtt_agent_resumesession] */
+
381
+
416/* @[declare_mqtt_agent_cancelall] */
+ +
418/* @[declare_mqtt_agent_cancelall] */
+
419
+
475/* @[declare_mqtt_agent_subscribe] */
+
476MQTTStatus_t MQTTAgent_Subscribe( const MQTTAgentContext_t * pMqttAgentContext,
+
477 MQTTAgentSubscribeArgs_t * pSubscriptionArgs,
+
478 const MQTTAgentCommandInfo_t * pCommandInfo );
+
479/* @[declare_mqtt_agent_subscribe] */
+
480
+
535/* @[declare_mqtt_agent_unsubscribe] */
+
536MQTTStatus_t MQTTAgent_Unsubscribe( const MQTTAgentContext_t * pMqttAgentContext,
+
537 MQTTAgentSubscribeArgs_t * pSubscriptionArgs,
+
538 const MQTTAgentCommandInfo_t * pCommandInfo );
+
539/* @[declare_mqtt_agent_unsubscribe] */
+
540
+
595/* @[declare_mqtt_agent_publish] */
+
596MQTTStatus_t MQTTAgent_Publish( const MQTTAgentContext_t * pMqttAgentContext,
+
597 MQTTPublishInfo_t * pPublishInfo,
+
598 const MQTTAgentCommandInfo_t * pCommandInfo );
+
599/* @[declare_mqtt_agent_publish] */
+
600
+
646/* @[declare_mqtt_agent_processloop] */
+
647MQTTStatus_t MQTTAgent_ProcessLoop( const MQTTAgentContext_t * pMqttAgentContext,
+
648 const MQTTAgentCommandInfo_t * pCommandInfo );
+
649/* @[declare_mqtt_agent_processloop] */
+
650
+
702/* @[declare_mqtt_agent_ping] */
+
703MQTTStatus_t MQTTAgent_Ping( const MQTTAgentContext_t * pMqttAgentContext,
+
704 const MQTTAgentCommandInfo_t * pCommandInfo );
+
705/* @[declare_mqtt_agent_ping] */
+
706
+
795/* @[declare_mqtt_agent_connect] */
+
796MQTTStatus_t MQTTAgent_Connect( const MQTTAgentContext_t * pMqttAgentContext,
+
797 MQTTAgentConnectArgs_t * pConnectArgs,
+
798 const MQTTAgentCommandInfo_t * pCommandInfo );
+
799/* @[declare_mqtt_agent_connect] */
+
800
+
858/* @[declare_mqtt_agent_disconnect] */
+
859MQTTStatus_t MQTTAgent_Disconnect( const MQTTAgentContext_t * pMqttAgentContext,
+
860 const MQTTAgentCommandInfo_t * pCommandInfo );
+
861/* @[declare_mqtt_agent_disconnect] */
+
862
+
921/* @[declare_mqtt_agent_terminate] */
+
922MQTTStatus_t MQTTAgent_Terminate( const MQTTAgentContext_t * pMqttAgentContext,
+
923 const MQTTAgentCommandInfo_t * pCommandInfo );
+
924/* @[declare_mqtt_agent_terminate] */
+
925
+
926/* *INDENT-OFF* */
+
927#ifdef __cplusplus
+
928 }
+
929#endif
+
930/* *INDENT-ON* */
+
931
+
932#endif /* CORE_MQTT_AGENT_H */
+ +
MQTTStatus_t MQTTAgent_CancelAll(MQTTAgentContext_t *pMqttAgentContext)
Cancel all enqueued commands and those awaiting acknowledgment while the command loop is not running.
Definition: core_mqtt_agent.c:1128
+
MQTTStatus_t MQTTAgent_Disconnect(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to disconnect an MQTT connection.
Definition: core_mqtt_agent.c:1300
+
MQTTStatus_t MQTTAgent_Init(MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentMessageInterface_t *pMsgInterface, const MQTTFixedBuffer_t *pNetworkBuffer, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getCurrentTimeMs, MQTTAgentIncomingPublishCallback_t incomingCallback, void *pIncomingPacketContext)
Perform any initialization the MQTT agent requires before it can be used. Must be called before any o...
Definition: core_mqtt_agent.c:968
+
MQTTStatus_t MQTTAgent_Subscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Subscribe() for an MQTT connection.
Definition: core_mqtt_agent.c:1177
+
MQTTStatus_t MQTTAgent_ResumeSession(MQTTAgentContext_t *pMqttAgentContext, bool sessionPresent)
Resume a session by resending publishes if a session is present in the broker, or clear state informa...
Definition: core_mqtt_agent.c:1085
+
MQTTStatus_t MQTTAgent_Connect(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentConnectArgs_t *pConnectArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Connect() for an MQTT connection. If a session is resumed with the broker,...
Definition: core_mqtt_agent.c:1275
+
MQTTStatus_t MQTTAgent_CommandLoop(MQTTAgentContext_t *pMqttAgentContext)
Process commands from the command queue in a loop.
Definition: core_mqtt_agent.c:1043
+
MQTTStatus_t MQTTAgent_ProcessLoop(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Send a message to the MQTT agent purely to trigger an iteration of its loop, which will result in a c...
Definition: core_mqtt_agent.c:1252
+
MQTTStatus_t MQTTAgent_Unsubscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Unsubscribe() for an MQTT connection.
Definition: core_mqtt_agent.c:1202
+
MQTTStatus_t MQTTAgent_Terminate(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a termination command to the command queue.
Definition: core_mqtt_agent.c:1346
+
MQTTStatus_t MQTTAgent_Ping(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Ping() for an MQTT connection.
Definition: core_mqtt_agent.c:1323
+
MQTTStatus_t MQTTAgent_Publish(const MQTTAgentContext_t *pMqttAgentContext, MQTTPublishInfo_t *pPublishInfo, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Publish() for an MQTT connection.
Definition: core_mqtt_agent.c:1227
+
This represents the default values for the configuration macros for the MQTT-Agent library.
+
#define MQTT_AGENT_MAX_OUTSTANDING_ACKS
The maximum number of pending acknowledgments to track for a single connection.
Definition: core_mqtt_agent_config_defaults.h:82
+
Functions to interact with queues.
+ +
void(* MQTTAgentCommandCallback_t)(MQTTAgentCommandContext_t *pCmdCallbackContext, MQTTAgentReturnInfo_t *pReturnInfo)
Callback function called when a command completes.
Definition: core_mqtt_agent.h:101
+
void(* MQTTAgentIncomingPublishCallback_t)(struct MQTTAgentContext *pMqttAgentContext, uint16_t packetId, MQTTPublishInfo_t *pPublishInfo)
Callback function called when receiving a publish.
Definition: core_mqtt_agent.h:142
+
MQTTAgentCommandType_t
A type of command for interacting with the MQTT API.
Definition: core_mqtt_agent.h:50
+
@ NUM_COMMANDS
The number of command types handled by the agent.
Definition: core_mqtt_agent.h:60
+
@ CONNECT
Call MQTT_Connect().
Definition: core_mqtt_agent.h:57
+
@ DISCONNECT
Call MQTT_Disconnect().
Definition: core_mqtt_agent.h:58
+
@ PING
Call MQTT_Ping().
Definition: core_mqtt_agent.h:56
+
@ UNSUBSCRIBE
Call MQTT_Unsubscribe().
Definition: core_mqtt_agent.h:55
+
@ PROCESSLOOP
Call MQTT_ProcessLoop().
Definition: core_mqtt_agent.h:52
+
@ TERMINATE
Exit the command loop and stop processing commands.
Definition: core_mqtt_agent.h:59
+
@ SUBSCRIBE
Call MQTT_Subscribe().
Definition: core_mqtt_agent.h:54
+
@ PUBLISH
Call MQTT_Publish().
Definition: core_mqtt_agent.h:53
+
@ NONE
No command received. Must be zero (its memset() value).
Definition: core_mqtt_agent.h:51
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
MQTTStatus_t
+
Information for a pending MQTT ack packet expected by the agent.
Definition: core_mqtt_agent.h:123
+
MQTTAgentCommand_t * pOriginalCommand
Definition: core_mqtt_agent.h:125
+
uint16_t packetId
Definition: core_mqtt_agent.h:124
+
The commands sent from the APIs to the MQTT agent task.
Definition: core_mqtt_agent.h:111
+
void * pArgs
Arguments of command.
Definition: core_mqtt_agent.h:113
+
MQTTAgentCommandCallback_t pCommandCompleteCallback
Callback to invoke upon completion.
Definition: core_mqtt_agent.h:114
+
MQTTAgentCommandContext_t * pCmdContext
Context for completion callback.
Definition: core_mqtt_agent.h:115
+
MQTTAgentCommandType_t commandType
Type of command.
Definition: core_mqtt_agent.h:112
+
Struct holding arguments that are common to every command.
Definition: core_mqtt_agent.h:189
+
MQTTAgentCommandContext_t * pCmdCompleteCallbackContext
Context for completion callback.
Definition: core_mqtt_agent.h:191
+
MQTTAgentCommandCallback_t cmdCompleteCallback
Callback to invoke upon completion.
Definition: core_mqtt_agent.h:190
+
uint32_t blockTimeMs
Maximum block time for enqueueing the command.
Definition: core_mqtt_agent.h:192
+
Struct holding arguments for a CONNECT call.
Definition: core_mqtt_agent.h:177
+
bool sessionPresent
Output flag set if a previous session was present.
Definition: core_mqtt_agent.h:181
+
MQTTPublishInfo_t * pWillInfo
Optional Last Will and Testament.
Definition: core_mqtt_agent.h:179
+
uint32_t timeoutMs
Maximum timeout for a CONNACK packet.
Definition: core_mqtt_agent.h:180
+
MQTTConnectInfo_t * pConnectInfo
MQTT CONNECT packet information.
Definition: core_mqtt_agent.h:178
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+
void * pIncomingCallbackContext
Definition: core_mqtt_agent.h:158
+
MQTTAgentIncomingPublishCallback_t pIncomingCallback
Definition: core_mqtt_agent.h:157
+
MQTTAgentMessageInterface_t agentInterface
Definition: core_mqtt_agent.h:155
+
MQTTContext_t mqttContext
Definition: core_mqtt_agent.h:154
+
bool packetReceivedInLoop
Definition: core_mqtt_agent.h:159
+
Function pointers and contexts used for sending and receiving commands, and allocating memory for the...
Definition: core_mqtt_agent_message_interface.h:133
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+
MQTTStatus_t returnCode
Definition: core_mqtt_agent.h:72
+
uint8_t * pSubackCodes
Definition: core_mqtt_agent.h:73
+
Struct holding arguments for a SUBSCRIBE or UNSUBSCRIBE call.
Definition: core_mqtt_agent.h:167
+
MQTTSubscribeInfo_t * pSubscribeInfo
List of MQTT subscriptions.
Definition: core_mqtt_agent.h:168
+
size_t numSubscriptions
Number of elements in pSubscribeInfo.
Definition: core_mqtt_agent.h:169
+ + + + + + +
+
+ + + + diff --git a/latest/core__mqtt__agent__command__functions_8c.html b/latest/core__mqtt__agent__command__functions_8c.html new file mode 100644 index 00000000..f90b7e54 --- /dev/null +++ b/latest/core__mqtt__agent__command__functions_8c.html @@ -0,0 +1,540 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent_command_functions.c File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_agent_command_functions.c File Reference
+
+
+ +

Implements functions to process MQTT agent commands. +More...

+
#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include "core_mqtt_agent.h"
+#include "core_mqtt_agent_command_functions.h"
+#include "core_mqtt_agent_default_logging.h"
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

MQTTStatus_t MQTTAgentCommand_ProcessLoop (MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a NONE command. This function does not call MQTT_ProcessLoop itself, but instead sets a flag to indicate it should be called.
 
MQTTStatus_t MQTTAgentCommand_Publish (MQTTAgentContext_t *pMqttAgentContext, void *pPublishArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a PUBLISH command.
 
MQTTStatus_t MQTTAgentCommand_Subscribe (MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a SUBSCRIBE command.
 
MQTTStatus_t MQTTAgentCommand_Unsubscribe (MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for an UNSUBSCRIBE command.
 
MQTTStatus_t MQTTAgentCommand_Connect (MQTTAgentContext_t *pMqttAgentContext, void *pVoidConnectArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a CONNECT command.
 
MQTTStatus_t MQTTAgentCommand_Disconnect (MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a DISCONNECT command.
 
MQTTStatus_t MQTTAgentCommand_Ping (MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a PING command.
 
MQTTStatus_t MQTTAgentCommand_Terminate (MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a TERMINATE command. Calls MQTTAgent_CancelAll to terminate all unfinished commands with MQTTRecvFailed.
 
+

Detailed Description

+

Implements functions to process MQTT agent commands.

+

Function Documentation

+ +

◆ MQTTAgentCommand_ProcessLoop()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_ProcessLoop (MQTTAgentContext_tpMqttAgentContext,
void * pUnusedArg,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a NONE command. This function does not call MQTT_ProcessLoop itself, but instead sets a flag to indicate it should be called.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pUnusedArgUnused NULL argument.
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
MQTTSuccess.
+ +
+
+ +

◆ MQTTAgentCommand_Publish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Publish (MQTTAgentContext_tpMqttAgentContext,
void * pPublishArg,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a PUBLISH command.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pPublishArgPublish information for MQTT_Publish().
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Publish().
+ +
+
+ +

◆ MQTTAgentCommand_Subscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Subscribe (MQTTAgentContext_tpMqttAgentContext,
void * pVoidSubscribeArgs,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a SUBSCRIBE command.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pVoidSubscribeArgsArguments for MQTT_Subscribe().
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Subscribe().
+ +
+
+ +

◆ MQTTAgentCommand_Unsubscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Unsubscribe (MQTTAgentContext_tpMqttAgentContext,
void * pVoidSubscribeArgs,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for an UNSUBSCRIBE command.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pVoidSubscribeArgsArguments for MQTT_Unsubscribe().
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Unsubscribe().
+ +
+
+ +

◆ MQTTAgentCommand_Connect()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Connect (MQTTAgentContext_tpMqttAgentContext,
void * pVoidConnectArgs,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a CONNECT command.

+

This sets all return flags to false.

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pVoidConnectArgsArguments for MQTT_Connect().
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Connect().
+ +
+
+ +

◆ MQTTAgentCommand_Disconnect()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Disconnect (MQTTAgentContext_tpMqttAgentContext,
void * pUnusedArg,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a DISCONNECT command.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pUnusedArgUnused NULL argument.
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Disconnect().
+ +
+
+ +

◆ MQTTAgentCommand_Ping()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Ping (MQTTAgentContext_tpMqttAgentContext,
void * pUnusedArg,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a PING command.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pUnusedArgUnused NULL argument.
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Ping().
+ +
+
+ +

◆ MQTTAgentCommand_Terminate()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Terminate (MQTTAgentContext_tpMqttAgentContext,
void * pUnusedArg,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a TERMINATE command. Calls MQTTAgent_CancelAll to terminate all unfinished commands with MQTTRecvFailed.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pUnusedArgUnused NULL argument.
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
MQTTSuccess.
+ +
+
+
+
+ + + + diff --git a/latest/core__mqtt__agent__command__functions_8h.html b/latest/core__mqtt__agent__command__functions_8h.html new file mode 100644 index 00000000..70c52323 --- /dev/null +++ b/latest/core__mqtt__agent__command__functions_8h.html @@ -0,0 +1,642 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent_command_functions.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_agent_command_functions.h File Reference
+
+
+ +

Functions for processing an MQTT agent command. +More...

+
#include "core_mqtt_agent.h"
+
+

Go to the source code of this file.

+ + + + + +

+Data Structures

struct  MQTTAgentCommandFuncReturns_t
 A structure of values and flags expected to be returned by command functions. More...
 
+ + + + +

+Macros

#define MQTT_AGENT_FUNCTION_TABLE
 An array of function pointers mapping command types to a function to execute. Configurable to allow a linker to remove unneeded functions.
 
+ + + + +

+Typedefs

typedef MQTTStatus_t(* MQTTAgentCommandFunc_t) (MQTTAgentContext_t *pMqttAgentContext, void *pArgs, MQTTAgentCommandFuncReturns_t *pFlags)
 Function prototype for a command.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

MQTTStatus_t MQTTAgentCommand_ProcessLoop (MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a NONE command. This function does not call MQTT_ProcessLoop itself, but instead sets a flag to indicate it should be called.
 
MQTTStatus_t MQTTAgentCommand_Publish (MQTTAgentContext_t *pMqttAgentContext, void *pPublishArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a PUBLISH command.
 
MQTTStatus_t MQTTAgentCommand_Subscribe (MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a SUBSCRIBE command.
 
MQTTStatus_t MQTTAgentCommand_Unsubscribe (MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for an UNSUBSCRIBE command.
 
MQTTStatus_t MQTTAgentCommand_Connect (MQTTAgentContext_t *pMqttAgentContext, void *pVoidConnectArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a CONNECT command.
 
MQTTStatus_t MQTTAgentCommand_Disconnect (MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a DISCONNECT command.
 
MQTTStatus_t MQTTAgentCommand_Ping (MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a PING command.
 
MQTTStatus_t MQTTAgentCommand_Terminate (MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a TERMINATE command. Calls MQTTAgent_CancelAll to terminate all unfinished commands with MQTTRecvFailed.
 
+

Detailed Description

+

Functions for processing an MQTT agent command.

+

Macro Definition Documentation

+ +

◆ MQTT_AGENT_FUNCTION_TABLE

+ +
+
+ + + + +
#define MQTT_AGENT_FUNCTION_TABLE
+
+Value:
{ \
+ + + + + + + + + +
}
+
MQTTStatus_t MQTTAgentCommand_Publish(MQTTAgentContext_t *pMqttAgentContext, void *pPublishArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a PUBLISH command.
Definition: core_mqtt_agent_command_functions.c:60
+
MQTTStatus_t MQTTAgentCommand_Ping(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a PING command.
Definition: core_mqtt_agent_command_functions.c:202
+
MQTTStatus_t MQTTAgentCommand_Terminate(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a TERMINATE command. Calls MQTTAgent_CancelAll to terminate all unfinished co...
Definition: core_mqtt_agent_command_functions.c:224
+
MQTTStatus_t MQTTAgentCommand_Disconnect(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a DISCONNECT command.
Definition: core_mqtt_agent_command_functions.c:181
+
MQTTStatus_t MQTTAgentCommand_Connect(MQTTAgentContext_t *pMqttAgentContext, void *pVoidConnectArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a CONNECT command.
Definition: core_mqtt_agent_command_functions.c:147
+
MQTTStatus_t MQTTAgentCommand_Subscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a SUBSCRIBE command.
Definition: core_mqtt_agent_command_functions.c:91
+
MQTTStatus_t MQTTAgentCommand_ProcessLoop(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a NONE command. This function does not call MQTT_ProcessLoop itself,...
Definition: core_mqtt_agent_command_functions.c:44
+
MQTTStatus_t MQTTAgentCommand_Unsubscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for an UNSUBSCRIBE command.
Definition: core_mqtt_agent_command_functions.c:119
+
+

An array of function pointers mapping command types to a function to execute. Configurable to allow a linker to remove unneeded functions.

+
Note
This array controls the behavior of each command. Altering the array would allow a linker to discard unused MQTT functions if desired. The size of this array MUST equal NUM_COMMANDS and the order MUST correspond to MQTTAgentCommandType_t commands if not using C99 designated initializers. If any function is desired not to be linked, it may be set to MQTTAgentCommand_ProcessLoop or a custom function matching an MQTTAgentCommandFunc_t prototype.
+

Default value:

{
+ + + + + + + + + +
}
+
@ CONNECT
Call MQTT_Connect().
Definition: core_mqtt_agent.h:57
+
@ DISCONNECT
Call MQTT_Disconnect().
Definition: core_mqtt_agent.h:58
+
@ PING
Call MQTT_Ping().
Definition: core_mqtt_agent.h:56
+
@ UNSUBSCRIBE
Call MQTT_Unsubscribe().
Definition: core_mqtt_agent.h:55
+
@ PROCESSLOOP
Call MQTT_ProcessLoop().
Definition: core_mqtt_agent.h:52
+
@ TERMINATE
Exit the command loop and stop processing commands.
Definition: core_mqtt_agent.h:59
+
@ SUBSCRIBE
Call MQTT_Subscribe().
Definition: core_mqtt_agent.h:54
+
@ PUBLISH
Call MQTT_Publish().
Definition: core_mqtt_agent.h:53
+
@ NONE
No command received. Must be zero (its memset() value).
Definition: core_mqtt_agent.h:51
+
+
+
+

Typedef Documentation

+ +

◆ MQTTAgentCommandFunc_t

+ +
+
+ + + + +
typedef MQTTStatus_t(* MQTTAgentCommandFunc_t) (MQTTAgentContext_t *pMqttAgentContext, void *pArgs, MQTTAgentCommandFuncReturns_t *pFlags)
+
+ +

Function prototype for a command.

+
Note
These functions should only be called from within MQTTAgent_CommandLoop.
+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context.
[in]pArgsArguments for the command.
[out]pFlagsReturn flags set by the function.
+
+
+
Returns
Return code of MQTT call.
+ +
+
+

Function Documentation

+ +

◆ MQTTAgentCommand_ProcessLoop()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_ProcessLoop (MQTTAgentContext_tpMqttAgentContext,
void * pUnusedArg,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a NONE command. This function does not call MQTT_ProcessLoop itself, but instead sets a flag to indicate it should be called.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pUnusedArgUnused NULL argument.
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
MQTTSuccess.
+ +
+
+ +

◆ MQTTAgentCommand_Publish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Publish (MQTTAgentContext_tpMqttAgentContext,
void * pPublishArg,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a PUBLISH command.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pPublishArgPublish information for MQTT_Publish().
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Publish().
+ +
+
+ +

◆ MQTTAgentCommand_Subscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Subscribe (MQTTAgentContext_tpMqttAgentContext,
void * pVoidSubscribeArgs,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a SUBSCRIBE command.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pVoidSubscribeArgsArguments for MQTT_Subscribe().
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Subscribe().
+ +
+
+ +

◆ MQTTAgentCommand_Unsubscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Unsubscribe (MQTTAgentContext_tpMqttAgentContext,
void * pVoidSubscribeArgs,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for an UNSUBSCRIBE command.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pVoidSubscribeArgsArguments for MQTT_Unsubscribe().
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Unsubscribe().
+ +
+
+ +

◆ MQTTAgentCommand_Connect()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Connect (MQTTAgentContext_tpMqttAgentContext,
void * pVoidConnectArgs,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a CONNECT command.

+

This sets all return flags to false.

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pVoidConnectArgsArguments for MQTT_Connect().
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Connect().
+ +
+
+ +

◆ MQTTAgentCommand_Disconnect()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Disconnect (MQTTAgentContext_tpMqttAgentContext,
void * pUnusedArg,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a DISCONNECT command.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pUnusedArgUnused NULL argument.
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Disconnect().
+ +
+
+ +

◆ MQTTAgentCommand_Ping()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Ping (MQTTAgentContext_tpMqttAgentContext,
void * pUnusedArg,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a PING command.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pUnusedArgUnused NULL argument.
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Ping().
+ +
+
+ +

◆ MQTTAgentCommand_Terminate()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Terminate (MQTTAgentContext_tpMqttAgentContext,
void * pUnusedArg,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a TERMINATE command. Calls MQTTAgent_CancelAll to terminate all unfinished commands with MQTTRecvFailed.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pUnusedArgUnused NULL argument.
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
MQTTSuccess.
+ +
+
+
+
+ + + + diff --git a/latest/core__mqtt__agent__command__functions_8h_source.html b/latest/core__mqtt__agent__command__functions_8h_source.html new file mode 100644 index 00000000..e7b6c96b --- /dev/null +++ b/latest/core__mqtt__agent__command__functions_8h_source.html @@ -0,0 +1,253 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent_command_functions.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
core_mqtt_agent_command_functions.h
+
+
+Go to the documentation of this file.
1/*
+
2 * coreMQTT Agent <v1.3.0>
+
3 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
4 *
+
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
+
6 * this software and associated documentation files (the "Software"), to deal in
+
7 * the Software without restriction, including without limitation the rights to
+
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
9 * the Software, and to permit persons to whom the Software is furnished to do so,
+
10 * subject to the following conditions:
+
11 *
+
12 * The above copyright notice and this permission notice shall be included in all
+
13 * copies or substantial portions of the Software.
+
14 *
+
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
21 */
+
22
+
27#ifndef CORE_MQTT_AGENT_COMMAND_FUNCTIONS_H
+
28#define CORE_MQTT_AGENT_COMMAND_FUNCTIONS_H
+
29
+
30/* *INDENT-OFF* */
+
31#ifdef __cplusplus
+
32 extern "C" {
+
33#endif
+
34/* *INDENT-ON* */
+
35
+
36/* MQTT Agent include. */
+
37#include "core_mqtt_agent.h"
+
38
+
64#ifndef MQTT_AGENT_FUNCTION_TABLE
+
65 /* Designated initializers are only in C99+. */
+
66 #if defined( __STDC_VERSION__ ) && ( __STDC_VERSION__ >= 199901L )
+
67 #define MQTT_AGENT_FUNCTION_TABLE \
+
68 { \
+
69 [ NONE ] = MQTTAgentCommand_ProcessLoop, \
+
70 [ PROCESSLOOP ] = MQTTAgentCommand_ProcessLoop, \
+
71 [ PUBLISH ] = MQTTAgentCommand_Publish, \
+
72 [ SUBSCRIBE ] = MQTTAgentCommand_Subscribe, \
+
73 [ UNSUBSCRIBE ] = MQTTAgentCommand_Unsubscribe, \
+
74 [ PING ] = MQTTAgentCommand_Ping, \
+
75 [ CONNECT ] = MQTTAgentCommand_Connect, \
+
76 [ DISCONNECT ] = MQTTAgentCommand_Disconnect, \
+
77 [ TERMINATE ] = MQTTAgentCommand_Terminate \
+
78 }
+
79 #else /* if defined( __STDC_VERSION__ ) && ( __STDC_VERSION__ >= 199901L ) */
+
80
+
81/* If not using designated initializers, this must correspond
+
82 * to the order of MQTTAgentCommandType_t commands. */
+
83 #define MQTT_AGENT_FUNCTION_TABLE \
+
84 { \
+
85 MQTTAgentCommand_ProcessLoop, \
+
86 MQTTAgentCommand_ProcessLoop, \
+
87 MQTTAgentCommand_Publish, \
+
88 MQTTAgentCommand_Subscribe, \
+
89 MQTTAgentCommand_Unsubscribe, \
+
90 MQTTAgentCommand_Ping, \
+
91 MQTTAgentCommand_Connect, \
+
92 MQTTAgentCommand_Disconnect, \
+
93 MQTTAgentCommand_Terminate \
+
94 }
+
95 #endif /* if defined( __STDC_VERSION__ ) && ( __STDC_VERSION__ >= 199901L ) */
+
96#endif /* ifndef MQTT_AGENT_FUNCTION_TABLE */
+
97
+
98/*-----------------------------------------------------------*/
+
99
+
105typedef struct MQTTAgentCommandFuncReturns
+
106{
+
107 uint16_t packetId;
+
108 bool endLoop;
+ + + +
112
+
125typedef MQTTStatus_t (* MQTTAgentCommandFunc_t ) ( MQTTAgentContext_t * pMqttAgentContext,
+
126 void * pArgs,
+ +
128
+
129/*-----------------------------------------------------------*/
+
130
+ +
145 void * pUnusedArg,
+
146 MQTTAgentCommandFuncReturns_t * pReturnFlags );
+
147
+ +
162 void * pPublishArg,
+
163 MQTTAgentCommandFuncReturns_t * pReturnFlags );
+
164
+ +
179 void * pVoidSubscribeArgs,
+
180 MQTTAgentCommandFuncReturns_t * pReturnFlags );
+
181
+ +
196 void * pVoidSubscribeArgs,
+
197 MQTTAgentCommandFuncReturns_t * pReturnFlags );
+
198
+ +
211 void * pVoidConnectArgs,
+
212 MQTTAgentCommandFuncReturns_t * pReturnFlags );
+
213
+ +
227 void * pUnusedArg,
+
228 MQTTAgentCommandFuncReturns_t * pReturnFlags );
+
229
+ +
243 void * pUnusedArg,
+
244 MQTTAgentCommandFuncReturns_t * pReturnFlags );
+
245
+ +
260 void * pUnusedArg,
+
261 MQTTAgentCommandFuncReturns_t * pReturnFlags );
+
262
+
263/* *INDENT-OFF* */
+
264#ifdef __cplusplus
+
265 }
+
266#endif
+
267/* *INDENT-ON* */
+
268
+
269#endif /* CORE_MQTT_AGENT_COMMAND_FUNCTIONS_H */
+
Functions for running a coreMQTT client in a dedicated thread.
+
MQTTStatus_t MQTTAgentCommand_Publish(MQTTAgentContext_t *pMqttAgentContext, void *pPublishArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a PUBLISH command.
Definition: core_mqtt_agent_command_functions.c:60
+
MQTTStatus_t MQTTAgentCommand_Ping(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a PING command.
Definition: core_mqtt_agent_command_functions.c:202
+
MQTTStatus_t MQTTAgentCommand_Terminate(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a TERMINATE command. Calls MQTTAgent_CancelAll to terminate all unfinished co...
Definition: core_mqtt_agent_command_functions.c:224
+
MQTTStatus_t MQTTAgentCommand_Disconnect(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a DISCONNECT command.
Definition: core_mqtt_agent_command_functions.c:181
+
MQTTStatus_t MQTTAgentCommand_Connect(MQTTAgentContext_t *pMqttAgentContext, void *pVoidConnectArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a CONNECT command.
Definition: core_mqtt_agent_command_functions.c:147
+
MQTTStatus_t MQTTAgentCommand_Subscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a SUBSCRIBE command.
Definition: core_mqtt_agent_command_functions.c:91
+
MQTTStatus_t MQTTAgentCommand_ProcessLoop(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a NONE command. This function does not call MQTT_ProcessLoop itself,...
Definition: core_mqtt_agent_command_functions.c:44
+
MQTTStatus_t MQTTAgentCommand_Unsubscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for an UNSUBSCRIBE command.
Definition: core_mqtt_agent_command_functions.c:119
+
MQTTStatus_t(* MQTTAgentCommandFunc_t)(MQTTAgentContext_t *pMqttAgentContext, void *pArgs, MQTTAgentCommandFuncReturns_t *pFlags)
Function prototype for a command.
Definition: core_mqtt_agent_command_functions.h:125
+
MQTTStatus_t
+
A structure of values and flags expected to be returned by command functions.
Definition: core_mqtt_agent_command_functions.h:106
+
bool addAcknowledgment
Flag to indicate an acknowledgment should be tracked.
Definition: core_mqtt_agent_command_functions.h:109
+
bool runProcessLoop
Flag to indicate MQTT_ProcessLoop() should be called after this command.
Definition: core_mqtt_agent_command_functions.h:110
+
uint16_t packetId
Packet ID of packet sent by command.
Definition: core_mqtt_agent_command_functions.h:107
+
bool endLoop
Flag to indicate command loop should terminate.
Definition: core_mqtt_agent_command_functions.h:108
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+
+
+ + + + diff --git a/latest/core__mqtt__agent__config__defaults_8h.html b/latest/core__mqtt__agent__config__defaults_8h.html new file mode 100644 index 00000000..fa87aec3 --- /dev/null +++ b/latest/core__mqtt__agent__config__defaults_8h.html @@ -0,0 +1,215 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent_config_defaults.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_agent_config_defaults.h File Reference
+
+
+ +

This represents the default values for the configuration macros for the MQTT-Agent library. +More...

+
#include "core_mqtt_agent_config.h"
+
+

Go to the source code of this file.

+ + + + + + + + + + + + + + +

+Macros

#define MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG
 Define this macro to build the MQTT library without the custom config file core_mqtt_agent_config.h.
 
#define MQTT_AGENT_MAX_OUTSTANDING_ACKS   ( 20U )
 The maximum number of pending acknowledgments to track for a single connection.
 
#define MQTT_AGENT_MAX_EVENT_QUEUE_WAIT_TIME   ( 1000U )
 Time in milliseconds that the MQTT agent task will wait in the Blocked state (so not using any CPU time) for a command to arrive in its command queue before exiting the blocked state so it can call MQTT_ProcessLoop().
 
#define MQTT_AGENT_USE_QOS_1_2_PUBLISH   ( 1 )
 Whether the agent should configure the coreMQTT library to be used with publishes greater than QoS0. Setting this to 0 will disallow the coreMQTT library to send publishes with QoS > 0.
 
+

Detailed Description

+

This represents the default values for the configuration macros for the MQTT-Agent library.

+
Note
This file SHOULD NOT be modified. If custom values are needed for any configuration macro, a core_mqtt_agent_config.h file should be provided to the MQTT-Agent library to override the default values defined in this file. To use the custom config file, the MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG preprocessor macro SHOULD NOT be set.
+

Macro Definition Documentation

+ +

◆ MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG

+ +
+
+ + + + +
#define MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG
+
+ +

Define this macro to build the MQTT library without the custom config file core_mqtt_agent_config.h.

+

Without the custom config, the MQTT library builds with default values of config macros defined in core_mqtt_agent_config_defaults.h file.

+

If a custom config is provided, then MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG should be defined.

+ +
+
+ +

◆ MQTT_AGENT_MAX_OUTSTANDING_ACKS

+ +
+
+ + + + +
#define MQTT_AGENT_MAX_OUTSTANDING_ACKS   ( 20U )
+
+ +

The maximum number of pending acknowledgments to track for a single connection.

+
Note
The MQTT agent tracks MQTT commands (such as PUBLISH and SUBSCRIBE) th at are still waiting to be acknowledged. MQTT_AGENT_MAX_OUTSTANDING_ACKS set the maximum number of acknowledgments that can be outstanding at any one time. The higher this number is the greater the agent's RAM consumption will be.
+

Possible values: Any positive integer up to SIZE_MAX.
+ Default value: 20

+ +
+
+ +

◆ MQTT_AGENT_MAX_EVENT_QUEUE_WAIT_TIME

+ +
+
+ + + + +
#define MQTT_AGENT_MAX_EVENT_QUEUE_WAIT_TIME   ( 1000U )
+
+ +

Time in milliseconds that the MQTT agent task will wait in the Blocked state (so not using any CPU time) for a command to arrive in its command queue before exiting the blocked state so it can call MQTT_ProcessLoop().

+
Note
It is important MQTT_ProcessLoop() is called often if there is known MQTT traffic, but calling it too often can take processing time away from lower priority tasks and waste CPU time and power.
+

Possible values: Any positive 32 bit integer.
+ Default value: 1000

+ +
+
+ +

◆ MQTT_AGENT_USE_QOS_1_2_PUBLISH

+ +
+
+ + + + +
#define MQTT_AGENT_USE_QOS_1_2_PUBLISH   ( 1 )
+
+ +

Whether the agent should configure the coreMQTT library to be used with publishes greater than QoS0. Setting this to 0 will disallow the coreMQTT library to send publishes with QoS > 0.

+

Possible values: 0 or 1
+ Default value: 1

+ +
+
+
+
+ + + + diff --git a/latest/core__mqtt__agent__config__defaults_8h_source.html b/latest/core__mqtt__agent__config__defaults_8h_source.html new file mode 100644 index 00000000..979e3745 --- /dev/null +++ b/latest/core__mqtt__agent__config__defaults_8h_source.html @@ -0,0 +1,178 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent_config_defaults.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
core_mqtt_agent_config_defaults.h
+
+
+Go to the documentation of this file.
1/*
+
2 * coreMQTT Agent <v1.3.0>
+
3 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
4 *
+
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
+
6 * this software and associated documentation files (the "Software"), to deal in
+
7 * the Software without restriction, including without limitation the rights to
+
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
9 * the Software, and to permit persons to whom the Software is furnished to do so,
+
10 * subject to the following conditions:
+
11 *
+
12 * The above copyright notice and this permission notice shall be included in all
+
13 * copies or substantial portions of the Software.
+
14 *
+
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
21 */
+
22
+
35#ifndef CORE_MQTT_AGENT_CONFIG_DEFAULTS_H_
+
36#define CORE_MQTT_AGENT_CONFIG_DEFAULTS_H_
+
37
+
38/* *INDENT-OFF* */
+
39#ifdef __cplusplus
+
40 extern "C" {
+
41#endif
+
42/* *INDENT-ON* */
+
43
+
44/* MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG allows building the MQTT library
+
45 * without a custom config. If a custom config is provided, the
+
46 * MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG macro should be defined. */
+
47#ifndef MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG
+
48 /* Include custom config file before other headers. */
+
49 #include "core_mqtt_agent_config.h"
+
50#endif
+
51
+
52/* The macro definition for MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG is for Doxygen
+
53 * documentation only. */
+
54
+
65#ifdef DOXYGEN
+
66 #define MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG
+
67#endif
+
68
+
81#ifndef MQTT_AGENT_MAX_OUTSTANDING_ACKS
+
82 #define MQTT_AGENT_MAX_OUTSTANDING_ACKS ( 20U )
+
83#endif
+
84
+
97#ifndef MQTT_AGENT_MAX_EVENT_QUEUE_WAIT_TIME
+
98 #define MQTT_AGENT_MAX_EVENT_QUEUE_WAIT_TIME ( 1000U )
+
99#endif
+
100
+
109#ifndef MQTT_AGENT_USE_QOS_1_2_PUBLISH
+
110 #define MQTT_AGENT_USE_QOS_1_2_PUBLISH ( 1 )
+
111#endif
+
112
+
113/* *INDENT-OFF* */
+
114#ifdef __cplusplus
+
115 }
+
116#endif
+
117/* *INDENT-ON* */
+
118
+
119#endif /* ifndef CORE_MQTT_AGENT_CONFIG_DEFAULTS_H_ */
+
+
+ + + + diff --git a/latest/core__mqtt__agent__default__logging_8h.html b/latest/core__mqtt__agent__default__logging_8h.html new file mode 100644 index 00000000..3c99760e --- /dev/null +++ b/latest/core__mqtt__agent__default__logging_8h.html @@ -0,0 +1,232 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent_default_logging.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_agent_default_logging.h File Reference
+
+
+ +

This represents the default values for the logging macros for the MQTT-Agent library. +More...

+ +

Go to the source code of this file.

+ + + + + + + + + + + + + + +

+Macros

#define LogError(message)
 Macro that is called in the MQTT-Agent library for logging "Error" level messages.
 
#define LogWarn(message)
 Macro that is called in the MQTT-Agent library for logging "Warning" level messages.
 
#define LogInfo(message)
 Macro that is called in the MQTT-Agent library for logging "Info" level messages.
 
#define LogDebug(message)
 Macro that is called in the MQTT-Agent library for logging "Debug" level messages.
 
+

Detailed Description

+

This represents the default values for the logging macros for the MQTT-Agent library.

+
Note
This file SHOULD NOT be modified. If custom values are needed for any configuration macro, a core_mqtt_agent_config.h file should be provided to the MQTT-Agent library to override the default values defined in this file. To use the custom config file, the MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG preprocessor macro SHOULD NOT be set.
+

Macro Definition Documentation

+ +

◆ LogError

+ +
+
+ + + + + + + + +
#define LogError( message)
+
+ +

Macro that is called in the MQTT-Agent library for logging "Error" level messages.

+

To enable error level logging in the MQTT-Agent library, this macro should be mapped to the application-specific logging implementation that supports error logging.

+
Note
This logging macro is called in the MQTT-Agent library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Error logging is turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+ +
+
+ +

◆ LogWarn

+ +
+
+ + + + + + + + +
#define LogWarn( message)
+
+ +

Macro that is called in the MQTT-Agent library for logging "Warning" level messages.

+

To enable warning level logging in the MQTT-Agent library, this macro should be mapped to the application-specific logging implementation that supports warning logging.

+
Note
This logging macro is called in the MQTT-Agent library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Warning logs are turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+ +
+
+ +

◆ LogInfo

+ +
+
+ + + + + + + + +
#define LogInfo( message)
+
+ +

Macro that is called in the MQTT-Agent library for logging "Info" level messages.

+

To enable info level logging in the MQTT-Agent library, this macro should be mapped to the application-specific logging implementation that supports info logging.

+
Note
This logging macro is called in the MQTT-Agent library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Info logging is turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+ +
+
+ +

◆ LogDebug

+ +
+
+ + + + + + + + +
#define LogDebug( message)
+
+ +

Macro that is called in the MQTT-Agent library for logging "Debug" level messages.

+

To enable debug level logging from MQTT-Agent library, this macro should be mapped to the application-specific logging implementation that supports debug logging.

+
Note
This logging macro is called in the MQTT-Agent library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Debug logging is turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+ +
+
+
+
+ + + + diff --git a/latest/core__mqtt__agent__default__logging_8h_source.html b/latest/core__mqtt__agent__default__logging_8h_source.html new file mode 100644 index 00000000..4587cd97 --- /dev/null +++ b/latest/core__mqtt__agent__default__logging_8h_source.html @@ -0,0 +1,167 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent_default_logging.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
core_mqtt_agent_default_logging.h
+
+
+Go to the documentation of this file.
1/*
+
2 * coreMQTT Agent <v1.3.0>
+
3 * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
4 *
+
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
+
6 * this software and associated documentation files (the "Software"), to deal in
+
7 * the Software without restriction, including without limitation the rights to
+
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
9 * the Software, and to permit persons to whom the Software is furnished to do so,
+
10 * subject to the following conditions:
+
11 *
+
12 * The above copyright notice and this permission notice shall be included in all
+
13 * copies or substantial portions of the Software.
+
14 *
+
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
21 */
+
22
+
35#ifndef CORE_MQTT_AGENT_DEFAULT_LOGGING_H_
+
36#define CORE_MQTT_AGENT_DEFAULT_LOGGING_H_
+
37
+
38/* *INDENT-OFF* */
+
39#ifdef __cplusplus
+
40 extern "C" {
+
41#endif
+
42/* *INDENT-ON* */
+
43
+
60#ifndef LogError
+
61 #define LogError( message )
+
62#endif
+
63
+
79#ifndef LogWarn
+
80 #define LogWarn( message )
+
81#endif
+
82
+
99#ifndef LogInfo
+
100 #define LogInfo( message )
+
101#endif
+
102
+
119#ifndef LogDebug
+
120 #define LogDebug( message )
+
121#endif
+
122
+
123/* *INDENT-OFF* */
+
124#ifdef __cplusplus
+
125 }
+
126#endif
+
127/* *INDENT-ON* */
+
128
+
129#endif /* ifndef CORE_MQTT_AGENT_DEFAULT_LOGGING_H_ */
+
+
+ + + + diff --git a/latest/core__mqtt__agent__message__interface_8h.html b/latest/core__mqtt__agent__message__interface_8h.html new file mode 100644 index 00000000..a229aae6 --- /dev/null +++ b/latest/core__mqtt__agent__message__interface_8h.html @@ -0,0 +1,251 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent_message_interface.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_agent_message_interface.h File Reference
+
+
+ +

Functions to interact with queues. +More...

+
#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+

Go to the source code of this file.

+ + + + + +

+Data Structures

struct  MQTTAgentMessageInterface_t
 Function pointers and contexts used for sending and receiving commands, and allocating memory for them. More...
 
+ + + + + + + + + + + + + + + + +

+Typedefs

+typedef struct MQTTAgentMessageContext MQTTAgentMessageContext_t
 Context with which tasks may deliver messages to the agent.
 
typedef bool(* MQTTAgentMessageSend_t) (MQTTAgentMessageContext_t *pMsgCtx, MQTTAgentCommand_t *const *pCommandToSend, uint32_t blockTimeMs)
 Send a message to the specified context. Must be thread safe.
 
typedef bool(* MQTTAgentMessageRecv_t) (MQTTAgentMessageContext_t *pMsgCtx, MQTTAgentCommand_t **pReceivedCommand, uint32_t blockTimeMs)
 Receive a message from the specified context. Must be thread safe.
 
typedef MQTTAgentCommand_t *(* MQTTAgentCommandGet_t) (uint32_t blockTimeMs)
 Obtain a MQTTAgentCommand_t structure.
 
typedef bool(* MQTTAgentCommandRelease_t) (MQTTAgentCommand_t *pCommandToRelease)
 Give a MQTTAgentCommand_t structure back to the application.
 
+

Detailed Description

+

Functions to interact with queues.

+

Typedef Documentation

+ +

◆ MQTTAgentMessageSend_t

+ +
+
+ + + + +
typedef bool(* MQTTAgentMessageSend_t) (MQTTAgentMessageContext_t *pMsgCtx, MQTTAgentCommand_t *const *pCommandToSend, uint32_t blockTimeMs)
+
+ +

Send a message to the specified context. Must be thread safe.

+
Parameters
+ + + + +
[in]pMsgCtxAn MQTTAgentMessageContext_t.
[in]pCommandToSendPointer to address to send to queue.
[in]blockTimeMsBlock time to wait for a send.
+
+
+
Returns
true if send was successful, else false.
+ +
+
+ +

◆ MQTTAgentMessageRecv_t

+ +
+
+ + + + +
typedef bool(* MQTTAgentMessageRecv_t) (MQTTAgentMessageContext_t *pMsgCtx, MQTTAgentCommand_t **pReceivedCommand, uint32_t blockTimeMs)
+
+ +

Receive a message from the specified context. Must be thread safe.

+
Parameters
+ + + + +
[in]pMsgCtxAn MQTTAgentMessageContext_t.
[out]pReceivedCommandPointer to write address of received command.
[in]blockTimeMsBlock time to wait for a receive.
+
+
+
Returns
true if receive was successful, else false.
+ +
+
+ +

◆ MQTTAgentCommandGet_t

+ +
+
+ + + + +
typedef MQTTAgentCommand_t *(* MQTTAgentCommandGet_t) (uint32_t blockTimeMs)
+
+ +

Obtain a MQTTAgentCommand_t structure.

+
Note
MQTTAgentCommand_t structures hold everything the MQTT agent needs to process a command that originates from application. Examples of commands are PUBLISH and SUBSCRIBE. The MQTTAgentCommand_t structure must persist for the duration of the command's operation.
+
Parameters
+ + +
[in]blockTimeMsThe length of time the calling task should remain in the Blocked state (so not consuming any CPU time) to wait for a MQTTAgentCommand_t structure to become available should one not be immediately at the time of the call.
+
+
+
Returns
A pointer to a MQTTAgentCommand_t structure if one becomes available before blockTimeMs time expired, otherwise NULL.
+ +
+
+ +

◆ MQTTAgentCommandRelease_t

+ +
+
+ + + + +
typedef bool(* MQTTAgentCommandRelease_t) (MQTTAgentCommand_t *pCommandToRelease)
+
+ +

Give a MQTTAgentCommand_t structure back to the application.

+
Note
MQTTAgentCommand_t structures hold everything the MQTT agent needs to process a command that originates from application. Examples of commands are PUBLISH and SUBSCRIBE. The MQTTAgentCommand_t structure must persist for the duration of the command's operation.
+
Parameters
+ + +
[in]pCommandToReleaseA pointer to the MQTTAgentCommand_t structure to return to the application. The structure must first have been obtained by calling an MQTTAgentCommandGet_t, otherwise it will have no effect.
+
+
+
Returns
true if the MQTTAgentCommand_t structure was returned to the application, otherwise false.
+ +
+
+
+
+ + + + diff --git a/latest/core__mqtt__agent__message__interface_8h_source.html b/latest/core__mqtt__agent__message__interface_8h_source.html new file mode 100644 index 00000000..3cfef118 --- /dev/null +++ b/latest/core__mqtt__agent__message__interface_8h_source.html @@ -0,0 +1,208 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent_message_interface.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
core_mqtt_agent_message_interface.h
+
+
+Go to the documentation of this file.
1/*
+
2 * coreMQTT Agent <v1.3.0>
+
3 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
4 *
+
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
+
6 * this software and associated documentation files (the "Software"), to deal in
+
7 * the Software without restriction, including without limitation the rights to
+
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
9 * the Software, and to permit persons to whom the Software is furnished to do so,
+
10 * subject to the following conditions:
+
11 *
+
12 * The above copyright notice and this permission notice shall be included in all
+
13 * copies or substantial portions of the Software.
+
14 *
+
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
21 */
+
22
+
27#ifndef CORE_MQTT_AGENT_MESSAGE_INTERFACE_H
+
28#define CORE_MQTT_AGENT_MESSAGE_INTERFACE_H
+
29
+
30#include <stddef.h>
+
31#include <stdint.h>
+
32#include <stdbool.h>
+
33
+
34/* *INDENT-OFF* */
+
35#ifdef __cplusplus
+
36 extern "C" {
+
37#endif
+
38/* *INDENT-ON* */
+
39
+
40/* Declare here so interface functions can use. */
+
41struct MQTTAgentCommand;
+
42struct MQTTAgentMessageContext;
+
43
+
47typedef struct MQTTAgentCommand MQTTAgentCommand_t;
+
48
+
53/* @[define_messagectx] */
+
54typedef struct MQTTAgentMessageContext MQTTAgentMessageContext_t;
+
55/* @[define_messagectx] */
+
56
+
67/* @[define_messagesend] */
+ +
69 MQTTAgentCommand_t * const * pCommandToSend,
+
70 uint32_t blockTimeMs );
+
71/* @[define_messagesend] */
+
72
+
83/* @[define_messagerecv] */
+ +
85 MQTTAgentCommand_t ** pReceivedCommand,
+
86 uint32_t blockTimeMs );
+
87/* @[define_messagerecv] */
+
88
+
104/* @[define_messageget] */
+
105typedef MQTTAgentCommand_t * ( * MQTTAgentCommandGet_t )( uint32_t blockTimeMs );
+
106/* @[define_messageget] */
+
107
+
122/* @[define_messagerelease] */
+
123typedef bool ( * MQTTAgentCommandRelease_t )( MQTTAgentCommand_t * pCommandToRelease );
+
124/* @[define_messagerelease] */
+
125
+
131/* @[define_messageinterface] */
+
132typedef struct MQTTAgentMessageInterface
+
133{
+ + + + + + +
140/* @[define_messageinterface] */
+
141
+
142/* *INDENT-OFF* */
+
143#ifdef __cplusplus
+
144 }
+
145#endif
+
146/* *INDENT-ON* */
+
147
+
148#endif /* CORE_MQTT_AGENT_MESSAGE_INTERFACE_H */
+
MQTTAgentCommand_t *(* MQTTAgentCommandGet_t)(uint32_t blockTimeMs)
Obtain a MQTTAgentCommand_t structure.
Definition: core_mqtt_agent_message_interface.h:105
+
bool(* MQTTAgentMessageSend_t)(MQTTAgentMessageContext_t *pMsgCtx, MQTTAgentCommand_t *const *pCommandToSend, uint32_t blockTimeMs)
Send a message to the specified context. Must be thread safe.
Definition: core_mqtt_agent_message_interface.h:68
+
bool(* MQTTAgentCommandRelease_t)(MQTTAgentCommand_t *pCommandToRelease)
Give a MQTTAgentCommand_t structure back to the application.
Definition: core_mqtt_agent_message_interface.h:123
+
bool(* MQTTAgentMessageRecv_t)(MQTTAgentMessageContext_t *pMsgCtx, MQTTAgentCommand_t **pReceivedCommand, uint32_t blockTimeMs)
Receive a message from the specified context. Must be thread safe.
Definition: core_mqtt_agent_message_interface.h:84
+
struct MQTTAgentMessageContext MQTTAgentMessageContext_t
Context with which tasks may deliver messages to the agent.
Definition: core_mqtt_agent_message_interface.h:54
+
The commands sent from the APIs to the MQTT agent task.
Definition: core_mqtt_agent.h:111
+
Function pointers and contexts used for sending and receiving commands, and allocating memory for the...
Definition: core_mqtt_agent_message_interface.h:133
+
MQTTAgentMessageContext_t * pMsgCtx
Definition: core_mqtt_agent_message_interface.h:134
+
MQTTAgentMessageRecv_t recv
Definition: core_mqtt_agent_message_interface.h:136
+
MQTTAgentCommandGet_t getCommand
Definition: core_mqtt_agent_message_interface.h:137
+
MQTTAgentMessageSend_t send
Definition: core_mqtt_agent_message_interface.h:135
+
MQTTAgentCommandRelease_t releaseCommand
Definition: core_mqtt_agent_message_interface.h:138
+
+
+ + + + diff --git a/latest/core_mqtt_agent_config.html b/latest/core_mqtt_agent_config.html new file mode 100644 index 00000000..590a0cf5 --- /dev/null +++ b/latest/core_mqtt_agent_config.html @@ -0,0 +1,160 @@ + + + + + + + +coreMQTT Agent: Configurations + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Configurations
+
+
+

Configurations of the MQTT Agent.

+
configpagestyle
+

Configuration settings are C preprocessor constants. They can be set with a #define in the config file (core_mqtt_config.h) or by using a compiler option such as -D in gcc. The MQTT Agent uses the same configuration file as coreMQTT.

+

+MQTT_AGENT_MAX_OUTSTANDING_ACKS

+

The maximum number of pending acknowledgments to track for a single connection.

+
Note
The MQTT agent tracks MQTT commands (such as PUBLISH and SUBSCRIBE) th at are still waiting to be acknowledged. MQTT_AGENT_MAX_OUTSTANDING_ACKS set the maximum number of acknowledgments that can be outstanding at any one time. The higher this number is the greater the agent's RAM consumption will be.
+

Possible values: Any positive integer up to SIZE_MAX.
+ Default value: 20

+

+MQTT_AGENT_MAX_EVENT_QUEUE_WAIT_TIME

+

Time in milliseconds that the MQTT agent task will wait in the Blocked state (so not using any CPU time) for a command to arrive in its command queue before exiting the blocked state so it can call MQTT_ProcessLoop().

+
Note
It is important MQTT_ProcessLoop() is called often if there is known MQTT traffic, but calling it too often can take processing time away from lower priority tasks and waste CPU time and power.
+

Possible values: Any positive 32 bit integer.
+ Default value: 1000

+

+MQTT_AGENT_FUNCTION_TABLE

+

An array of function pointers mapping command types to a function to execute. Configurable to allow a linker to remove unneeded functions.

+
Note
This array controls the behavior of each command. Altering the array would allow a linker to discard unused MQTT functions if desired. The size of this array MUST equal NUM_COMMANDS and the order MUST correspond to MQTTAgentCommandType_t commands if not using C99 designated initializers. If any function is desired not to be linked, it may be set to MQTTAgentCommand_ProcessLoop or a custom function matching an MQTTAgentCommandFunc_t prototype.
+

Default value:

{
+ + + + + + + + + +
}
+
MQTTStatus_t MQTTAgentCommand_Publish(MQTTAgentContext_t *pMqttAgentContext, void *pPublishArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a PUBLISH command.
Definition: core_mqtt_agent_command_functions.c:60
+
MQTTStatus_t MQTTAgentCommand_Ping(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a PING command.
Definition: core_mqtt_agent_command_functions.c:202
+
MQTTStatus_t MQTTAgentCommand_Terminate(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a TERMINATE command. Calls MQTTAgent_CancelAll to terminate all unfinished co...
Definition: core_mqtt_agent_command_functions.c:224
+
MQTTStatus_t MQTTAgentCommand_Disconnect(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a DISCONNECT command.
Definition: core_mqtt_agent_command_functions.c:181
+
MQTTStatus_t MQTTAgentCommand_Connect(MQTTAgentContext_t *pMqttAgentContext, void *pVoidConnectArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a CONNECT command.
Definition: core_mqtt_agent_command_functions.c:147
+
MQTTStatus_t MQTTAgentCommand_Subscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a SUBSCRIBE command.
Definition: core_mqtt_agent_command_functions.c:91
+
MQTTStatus_t MQTTAgentCommand_ProcessLoop(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a NONE command. This function does not call MQTT_ProcessLoop itself,...
Definition: core_mqtt_agent_command_functions.c:44
+
MQTTStatus_t MQTTAgentCommand_Unsubscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for an UNSUBSCRIBE command.
Definition: core_mqtt_agent_command_functions.c:119
+
@ CONNECT
Call MQTT_Connect().
Definition: core_mqtt_agent.h:57
+
@ DISCONNECT
Call MQTT_Disconnect().
Definition: core_mqtt_agent.h:58
+
@ PING
Call MQTT_Ping().
Definition: core_mqtt_agent.h:56
+
@ UNSUBSCRIBE
Call MQTT_Unsubscribe().
Definition: core_mqtt_agent.h:55
+
@ PROCESSLOOP
Call MQTT_ProcessLoop().
Definition: core_mqtt_agent.h:52
+
@ TERMINATE
Exit the command loop and stop processing commands.
Definition: core_mqtt_agent.h:59
+
@ SUBSCRIBE
Call MQTT_Subscribe().
Definition: core_mqtt_agent.h:54
+
@ PUBLISH
Call MQTT_Publish().
Definition: core_mqtt_agent.h:53
+
@ NONE
No command received. Must be zero (its memset() value).
Definition: core_mqtt_agent.h:51
+
+
+
+ + + + diff --git a/latest/dir_359d2bec989c9a8deeeb9aee335c1c76.html b/latest/dir_359d2bec989c9a8deeeb9aee335c1c76.html new file mode 100644 index 00000000..cc63484a --- /dev/null +++ b/latest/dir_359d2bec989c9a8deeeb9aee335c1c76.html @@ -0,0 +1,113 @@ + + + + + + + +coreMQTT Agent: doxygen Directory Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
doxygen Directory Reference
+
+
+
+
+ + + + diff --git a/latest/dir_49e56c817e5e54854c35e136979f97ca.html b/latest/dir_49e56c817e5e54854c35e136979f97ca.html new file mode 100644 index 00000000..f60286c9 --- /dev/null +++ b/latest/dir_49e56c817e5e54854c35e136979f97ca.html @@ -0,0 +1,113 @@ + + + + + + + +coreMQTT Agent: docs Directory Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
docs Directory Reference
+
+
+
+
+ + + + diff --git a/latest/dir_8ee1a5e78eaec319fe5d64075812fc61.html b/latest/dir_8ee1a5e78eaec319fe5d64075812fc61.html new file mode 100644 index 00000000..e8e30ee7 --- /dev/null +++ b/latest/dir_8ee1a5e78eaec319fe5d64075812fc61.html @@ -0,0 +1,132 @@ + + + + + + + +coreMQTT Agent: include Directory Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
include Directory Reference
+
+
+ + + + + + + + + + + + + + + + + +

+Files

file  core_mqtt_agent.h [code]
 Functions for running a coreMQTT client in a dedicated thread.
 
file  core_mqtt_agent_command_functions.h [code]
 Functions for processing an MQTT agent command.
 
file  core_mqtt_agent_config_defaults.h [code]
 This represents the default values for the configuration macros for the MQTT-Agent library.
 
file  core_mqtt_agent_default_logging.h [code]
 This represents the default values for the logging macros for the MQTT-Agent library.
 
file  core_mqtt_agent_message_interface.h [code]
 Functions to interact with queues.
 
+
+
+ + + + diff --git a/latest/dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html b/latest/dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html new file mode 100644 index 00000000..b83ef156 --- /dev/null +++ b/latest/dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html @@ -0,0 +1,128 @@ + + + + + + + +coreMQTT Agent: source Directory Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
source Directory Reference
+
+
+ + + + +

+Directories

directory  include
 
+ + + + + + + +

+Files

file  core_mqtt_agent.c
 Implements an MQTT agent (or daemon task) to enable multithreaded access to coreMQTT.
 
file  core_mqtt_agent_command_functions.c
 Implements functions to process MQTT agent commands.
 
+
+
+ + + + diff --git a/latest/doc.png b/latest/doc.png new file mode 100644 index 0000000000000000000000000000000000000000..17edabff95f7b8da13c9516a04efe05493c29501 GIT binary patch literal 746 zcmV7=@pnbNXRFEm&G8P!&WHG=d)>K?YZ1bzou)2{$)) zumDct!>4SyxL;zgaG>wy`^Hv*+}0kUfCrz~BCOViSb$_*&;{TGGn2^x9K*!Sf0=lV zpP=7O;GA0*Jm*tTYj$IoXvimpnV4S1Z5f$p*f$Db2iq2zrVGQUz~yq`ahn7ck(|CE z7Gz;%OP~J6)tEZWDzjhL9h2hdfoU2)Nd%T<5Kt;Y0XLt&<@6pQx!nw*5`@bq#?l*?3z{Hlzoc=Pr>oB5(9i6~_&-}A(4{Q$>c>%rV&E|a(r&;?i5cQB=} zYSDU5nXG)NS4HEs0it2AHe2>shCyr7`6@4*6{r@8fXRbTA?=IFVWAQJL&H5H{)DpM#{W(GL+Idzf^)uRV@oB8u$ z8v{MfJbTiiRg4bza<41NAzrl{=3fl_D+$t+^!xlQ8S}{UtY`e z;;&9UhyZqQRN%2pot{*Ei0*4~hSF_3AH2@fKU!$NSflS>{@tZpDT4`M2WRTTVH+D? z)GFlEGGHe?koB}i|1w45!BF}N_q&^HJ&-tyR{(afC6H7|aml|tBBbv}55C5DNP8p3 z)~jLEO4Z&2hZmP^i-e%(@d!(E|KRafiU8Q5u(wU((j8un3OR*Hvj+t literal 0 HcmV?d00001 diff --git a/latest/docd.png b/latest/docd.png new file mode 100644 index 0000000000000000000000000000000000000000..d7c94fda9bf08ecc02c7190d968452b7a2dbf04b GIT binary patch literal 756 zcmV1wr-rhpn+wxm%q2)IkAYsr{iGq<}_z5JCD4J;FN?6Qh;@TCubdp(_XdD-^ zG_#)IP7_z6hKNdx5^+FGArwLWTWCG!j+oKji?U!hxA#d-ljgkN`+e^@-P+RWG{Bx= z2iQyYTtEf*o~ySWrIVW}HWHi0_hd4~$E6Jx1U`>Owo}EYJ1O>iZvS?!z8}B}QwLMA zC3Keqf1c}K@?C`X>68b(EUzYUYAS&OH^VPteZLPr{S&|nQvp@6W4GH-1U8!u&7l~A zx~RUSNH+>7@q38W6!BzirtjLFCzc|XGx)EF#G%^pWION*k@?vP<2O>|XkCD3ujl%1 z{55JSVkw{~HbX>iEZ2%yJ2eHj5Yh8OTpzs0A2;tZ^x!#5D+y-es{k1&0|Ns9-|+Xt ziGiTsZ8(^nUo#wdTpIDkb-Zp(3|A*FzW}GZ5SQD-r^R`&X@`26E3W|GyrwDIZjtQ& z$g5f8Sv=VgVtDien@J(!^BK+#l;s-LgP--p7C;7;E!ysXcXK6?+9D>_-B(?Wm(U zQbNm-5TyYxIU=rs0+)!ixqzhuxw(AqKc3?KKX32{D~Qibp*r0x&Wux5-9WCMMRi3U zTd6dOCQlj>a;gr;gLwRKulT&(m@^L{&HkSC(qH05HSSf$YEhynGvH zWNez``Z8FJXE+BSg=%ak{OR z+Nylcb{?evLYLuE1_HngYw0g%LC#=$a@?4~Tx>F9295Q>9UJ|_6v-KMw;!YZSgGj@ zR8fRov=hJ#QvsO@xw*{0%zH@OKVEUrsummary { + list-style-type: none; +} + +details > summary::-webkit-details-marker { + display: none; +} + +details>summary::before { + content: "\25ba"; + padding-right:4px; + font-size: 80%; +} + +details[open]>summary::before { + content: "\25bc"; + padding-right:4px; + font-size: 80%; +} + diff --git a/latest/doxygen.svg b/latest/doxygen.svg new file mode 100644 index 00000000..d42dad52 --- /dev/null +++ b/latest/doxygen.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/latest/dynsections.js b/latest/dynsections.js new file mode 100644 index 00000000..f579fbf3 --- /dev/null +++ b/latest/dynsections.js @@ -0,0 +1,123 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); + $('table.directory tr'). + removeClass('odd').filter(':visible:odd').addClass('odd'); +} + +function toggleLevel(level) +{ + $('table.directory tr').each(function() { + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l + + + + + + +coreMQTT Agent: Files + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Files
+
+
+
The following files are associated with this library.
+
[detail level 123]
+ + + + + + + + + +
  source
  include
 core_mqtt_agent.hFunctions for running a coreMQTT client in a dedicated thread
 core_mqtt_agent_command_functions.hFunctions for processing an MQTT agent command
 core_mqtt_agent_config_defaults.hThis represents the default values for the configuration macros for the MQTT-Agent library
 core_mqtt_agent_default_logging.hThis represents the default values for the logging macros for the MQTT-Agent library
 core_mqtt_agent_message_interface.hFunctions to interact with queues
 core_mqtt_agent.cImplements an MQTT agent (or daemon task) to enable multithreaded access to coreMQTT
 core_mqtt_agent_command_functions.cImplements functions to process MQTT agent commands
+
+
+
+ + + + diff --git a/latest/folderclosed.png b/latest/folderclosed.png new file mode 100644 index 0000000000000000000000000000000000000000..bb8ab35edce8e97554e360005ee9fc5bffb36e66 GIT binary patch literal 616 zcmV-u0+;=XP)a9#ETzayK)T~Jw&MMH>OIr#&;dC}is*2Mqdf&akCc=O@`qC+4i z5Iu3w#1M@KqXCz8TIZd1wli&kkl2HVcAiZ8PUn5z_kG@-y;?yK06=cA0U%H0PH+kU zl6dp}OR(|r8-RG+YLu`zbI}5TlOU6ToR41{9=uz^?dGTNL;wIMf|V3`d1Wj3y!#6` zBLZ?xpKR~^2x}?~zA(_NUu3IaDB$tKma*XUdOZN~c=dLt_h_k!dbxm_*ibDM zlFX`g{k$X}yIe%$N)cn1LNu=q9_CS)*>A zsX_mM4L@`(cSNQKMFc$RtYbx{79#j-J7hk*>*+ZZhM4Hw?I?rsXCi#mRWJ=-0LGV5a-WR0Qgt<|Nqf)C-@80`5gIz45^_20000IqP)X=#(TiCT&PiIIVc55T}TU}EUh*{q$|`3@{d>{Tc9Bo>e= zfmF3!f>fbI9#GoEHh0f`i5)wkLpva0ztf%HpZneK?w-7AK@b4Itw{y|Zd3k!fH?q2 zlhckHd_V2M_X7+)U&_Xcfvtw60l;--DgZmLSw-Y?S>)zIqMyJ1#FwLU*%bl38ok+! zh78H87n`ZTS;uhzAR$M`zZ`bVhq=+%u9^$5jDplgxd44}9;IRqUH1YHH|@6oFe%z( zo4)_>E$F&^P-f(#)>(TrnbE>Pefs9~@iN=|)Rz|V`sGfHNrJ)0gJb8xx+SBmRf@1l zvuzt=vGfI)<-F9!o&3l?>9~0QbUDT(wFdnQPv%xdD)m*g%!20>Bc9iYmGAp<9YAa( z0QgYgTWqf1qN++Gqp z8@AYPTB3E|6s=WLG?xw0tm|U!o=&zd+H0oRYE;Dbx+Na9s^STqX|Gnq%H8s(nGDGJ j8vwW|`Ts`)fSK|Kx=IK@RG@g200000NkvXXu0mjfauFEA literal 0 HcmV?d00001 diff --git a/latest/functions.html b/latest/functions.html new file mode 100644 index 00000000..8786ec30 --- /dev/null +++ b/latest/functions.html @@ -0,0 +1,184 @@ + + + + + + + +coreMQTT Agent: Data Fields + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- a -

+ + +

- b -

+ + +

- c -

+ + +

- e -

+ + +

- g -

+ + +

- m -

+ + +

- n -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+
+
+ + + + diff --git a/latest/functions_vars.html b/latest/functions_vars.html new file mode 100644 index 00000000..2157a05c --- /dev/null +++ b/latest/functions_vars.html @@ -0,0 +1,184 @@ + + + + + + + +coreMQTT Agent: Data Fields - Variables + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- a -

+ + +

- b -

+ + +

- c -

+ + +

- e -

+ + +

- g -

+ + +

- m -

+ + +

- n -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+
+
+ + + + diff --git a/latest/globals.html b/latest/globals.html new file mode 100644 index 00000000..2be06205 --- /dev/null +++ b/latest/globals.html @@ -0,0 +1,233 @@ + + + + + + + +coreMQTT Agent: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- a -

+ + +

- c -

+ + +

- d -

+ + +

- g -

+ + +

- h -

+ + +

- i -

+ + +

- l -

+ + +

- m -

+ + +

- n -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- u -

+ + +

- v -

+
+
+ + + + diff --git a/latest/globals_defs.html b/latest/globals_defs.html new file mode 100644 index 00000000..90979b07 --- /dev/null +++ b/latest/globals_defs.html @@ -0,0 +1,120 @@ + + + + + + + +coreMQTT Agent: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
+ + + + diff --git a/latest/globals_enum.html b/latest/globals_enum.html new file mode 100644 index 00000000..f6a49ec8 --- /dev/null +++ b/latest/globals_enum.html @@ -0,0 +1,112 @@ + + + + + + + +coreMQTT Agent: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
+ + + + diff --git a/latest/globals_eval.html b/latest/globals_eval.html new file mode 100644 index 00000000..4b6c1871 --- /dev/null +++ b/latest/globals_eval.html @@ -0,0 +1,121 @@ + + + + + + + +coreMQTT Agent: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
+ + + + diff --git a/latest/globals_func.html b/latest/globals_func.html new file mode 100644 index 00000000..a9660602 --- /dev/null +++ b/latest/globals_func.html @@ -0,0 +1,180 @@ + + + + + + + +coreMQTT Agent: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- a -

+ + +

- c -

+ + +

- g -

+ + +

- h -

+ + +

- i -

+ + +

- m -

+ + +

- p -

+ + +

- r -

+ + +

- v -

+
+
+ + + + diff --git a/latest/globals_type.html b/latest/globals_type.html new file mode 100644 index 00000000..199bd3af --- /dev/null +++ b/latest/globals_type.html @@ -0,0 +1,120 @@ + + + + + + + +coreMQTT Agent: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
+ + + + diff --git a/latest/group__mqtt__agent__callback__types.html b/latest/group__mqtt__agent__callback__types.html new file mode 100644 index 00000000..6f3392c0 --- /dev/null +++ b/latest/group__mqtt__agent__callback__types.html @@ -0,0 +1,181 @@ + + + + + + + +coreMQTT Agent: Callback Types + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
Callback Types
+
+
+ +

Callback function pointer types of the MQTT Agent. +More...

+ + + + + + + + +

+Typedefs

typedef void(* MQTTAgentCommandCallback_t) (MQTTAgentCommandContext_t *pCmdCallbackContext, MQTTAgentReturnInfo_t *pReturnInfo)
 Callback function called when a command completes.
 
typedef void(* MQTTAgentIncomingPublishCallback_t) (struct MQTTAgentContext *pMqttAgentContext, uint16_t packetId, MQTTPublishInfo_t *pPublishInfo)
 Callback function called when receiving a publish.
 
+

Detailed Description

+

Callback function pointer types of the MQTT Agent.

+

Typedef Documentation

+ +

◆ MQTTAgentCommandCallback_t

+ +
+
+ + + + +
typedef void(* MQTTAgentCommandCallback_t) (MQTTAgentCommandContext_t *pCmdCallbackContext, MQTTAgentReturnInfo_t *pReturnInfo)
+
+ +

Callback function called when a command completes.

+
Parameters
+ + + +
[in]pCmdCallbackContextThe callback context passed to the original command.
[in]pReturnInfoA struct of status codes and outputs from the command.
+
+
+
Note
A command should not be considered complete until this callback is called, and the arguments that the command uses MUST stay in scope until such happens.
+
+The callback MUST NOT block as it runs in the context of the MQTT agent task. If the callback calls any MQTT Agent API to enqueue a command, the blocking time (blockTimeMs member of MQTTAgentCommandInfo_t) MUST be zero. If the application wants to enqueue command(s) with non-zero blocking time, the callback can notify a different task to enqueue command(s) to the MQTT agent.
+ +
+
+ +

◆ MQTTAgentIncomingPublishCallback_t

+ +
+
+ + + + +
typedef void(* MQTTAgentIncomingPublishCallback_t) (struct MQTTAgentContext *pMqttAgentContext, uint16_t packetId, MQTTPublishInfo_t *pPublishInfo)
+
+ +

Callback function called when receiving a publish.

+
Parameters
+ + + + +
[in]pMqttAgentContextThe context of the MQTT agent.
[in]packetIdThe packet ID of the received publish.
[in]pPublishInfoDeserialized publish information.
+
+
+
Note
The callback MUST NOT block as it runs in the context of the MQTT agent task. If the callback calls any MQTT Agent API to enqueue a command, the blocking time (blockTimeMs member of MQTTAgentCommandInfo_t) MUST be zero. If the application wants to enqueue command(s) with non-zero blocking time, the callback can notify a different task to enqueue command(s) to the MQTT agent.
+ +
+
+
+
+ + + + diff --git a/latest/group__mqtt__agent__callback__types.js b/latest/group__mqtt__agent__callback__types.js new file mode 100644 index 00000000..6e8dac1e --- /dev/null +++ b/latest/group__mqtt__agent__callback__types.js @@ -0,0 +1,5 @@ +var group__mqtt__agent__callback__types = +[ + [ "MQTTAgentCommandCallback_t", "group__mqtt__agent__callback__types.html#gaa2497c28b3fb55b8dc38b0873f749eef", null ], + [ "MQTTAgentIncomingPublishCallback_t", "group__mqtt__agent__callback__types.html#gacdfb8687b1217d321e7cc58e365ec6a1", null ] +]; \ No newline at end of file diff --git a/latest/group__mqtt__agent__enum__types.html b/latest/group__mqtt__agent__enum__types.html new file mode 100644 index 00000000..2d33a184 --- /dev/null +++ b/latest/group__mqtt__agent__enum__types.html @@ -0,0 +1,179 @@ + + + + + + + +coreMQTT Agent: Enumerated Types + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
Enumerated Types
+
+
+ +

Enumerated types of the MQTT Agent. +More...

+ + + + + +

+Enumerations

enum  MQTTAgentCommandType_t {
+  NONE = 0 +, PROCESSLOOP +, PUBLISH +, SUBSCRIBE +,
+  UNSUBSCRIBE +, PING +, CONNECT +, DISCONNECT +,
+  TERMINATE +, NUM_COMMANDS +
+ }
 A type of command for interacting with the MQTT API. More...
 
+

Detailed Description

+

Enumerated types of the MQTT Agent.

+

Enumeration Type Documentation

+ +

◆ MQTTAgentCommandType_t

+ +
+
+ + + + +
enum MQTTAgentCommandType_t
+
+ +

A type of command for interacting with the MQTT API.

+ + + + + + + + + + + +
Enumerator
NONE 

No command received. Must be zero (its memset() value).

+
PROCESSLOOP 

Call MQTT_ProcessLoop().

+
PUBLISH 

Call MQTT_Publish().

+
SUBSCRIBE 

Call MQTT_Subscribe().

+
UNSUBSCRIBE 

Call MQTT_Unsubscribe().

+
PING 

Call MQTT_Ping().

+
CONNECT 

Call MQTT_Connect().

+
DISCONNECT 

Call MQTT_Disconnect().

+
TERMINATE 

Exit the command loop and stop processing commands.

+
NUM_COMMANDS 

The number of command types handled by the agent.

+
+ +
+
+
+
+ + + + diff --git a/latest/group__mqtt__agent__enum__types.js b/latest/group__mqtt__agent__enum__types.js new file mode 100644 index 00000000..3f994aac --- /dev/null +++ b/latest/group__mqtt__agent__enum__types.js @@ -0,0 +1,15 @@ +var group__mqtt__agent__enum__types = +[ + [ "MQTTAgentCommandType_t", "group__mqtt__agent__enum__types.html#ga76604fa58b7ee6c32ba084fda9379f33", [ + [ "NONE", "group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33ac157bdf0b85a40d2619cbc8bc1ae5fe2", null ], + [ "PROCESSLOOP", "group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a955e933dab5938a6cce4e140278a24d2", null ], + [ "PUBLISH", "group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33abd1a204dcfa4933760cd12e779f36fc5", null ], + [ "SUBSCRIBE", "group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33abc6f919ff681f5f552b2f7d1f0fba832", null ], + [ "UNSUBSCRIBE", "group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a8395e5981c15d813c588c86988fd4aea", null ], + [ "PING", "group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a3a95ef902bc659901cceef98e0bc8041", null ], + [ "CONNECT", "group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a20391dd2915a0e64343d24c2f2e40b95", null ], + [ "DISCONNECT", "group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a2f6318afb30e8e2817e6203ebedc8173", null ], + [ "TERMINATE", "group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a9aab2d9eae3e9a84d9fed3f0cadd7e22", null ], + [ "NUM_COMMANDS", "group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a158760c3c33699acd8723f4c983822a6", null ] + ] ] +]; \ No newline at end of file diff --git a/latest/group__mqtt__agent__struct__types.html b/latest/group__mqtt__agent__struct__types.html new file mode 100644 index 00000000..a00d79fc --- /dev/null +++ b/latest/group__mqtt__agent__struct__types.html @@ -0,0 +1,180 @@ + + + + + + + +coreMQTT Agent: Parameter Structures + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
Parameter Structures
+
+
+ +

Structures passed as parameters to MQTT Agent functions. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Structures

struct  MQTTAgentReturnInfo_t
 Struct holding return codes and outputs from a command. More...
 
struct  MQTTAgentCommand_t
 The commands sent from the APIs to the MQTT agent task. More...
 
struct  MQTTAgentAckInfo_t
 Information for a pending MQTT ack packet expected by the agent. More...
 
struct  MQTTAgentContext_t
 Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(), and every API function will accept a pointer to the initalized struct. More...
 
struct  MQTTAgentSubscribeArgs_t
 Struct holding arguments for a SUBSCRIBE or UNSUBSCRIBE call. More...
 
struct  MQTTAgentConnectArgs_t
 Struct holding arguments for a CONNECT call. More...
 
struct  MQTTAgentCommandInfo_t
 Struct holding arguments that are common to every command. More...
 
struct  MQTTAgentCommandFuncReturns_t
 A structure of values and flags expected to be returned by command functions. More...
 
struct  MQTTAgentMessageInterface_t
 Function pointers and contexts used for sending and receiving commands, and allocating memory for them. More...
 
+ + + + + + + +

+Typedefs

typedef struct MQTTAgentCommandContext MQTTAgentCommandContext_t
 Struct containing context for a specific command.
 
+typedef struct MQTTAgentMessageContext MQTTAgentMessageContext_t
 Context with which tasks may deliver messages to the agent.
 
+

Detailed Description

+

Structures passed as parameters to MQTT Agent functions.

+

These structures are passed as parameters to library functions. Documentation for these structures will state the functions associated with each parameter structure and the purpose of each member.

+

Typedef Documentation

+ +

◆ MQTTAgentCommandContext_t

+ +
+
+ + + + +
typedef struct MQTTAgentCommandContext MQTTAgentCommandContext_t
+
+ +

Struct containing context for a specific command.

+
Note
An instance of this struct and any variables it points to MUST stay in scope until the associated command is processed, and its callback called.
+ +
+
+
+
+ + + + diff --git a/latest/group__mqtt__agent__struct__types.js b/latest/group__mqtt__agent__struct__types.js new file mode 100644 index 00000000..1d0ab4f2 --- /dev/null +++ b/latest/group__mqtt__agent__struct__types.js @@ -0,0 +1,55 @@ +var group__mqtt__agent__struct__types = +[ + [ "MQTTAgentReturnInfo_t", "struct_m_q_t_t_agent_return_info__t.html", [ + [ "returnCode", "struct_m_q_t_t_agent_return_info__t.html#ab04f05e53b8e9039f8983f68b032ccc8", null ], + [ "pSubackCodes", "struct_m_q_t_t_agent_return_info__t.html#ad68d82134f1f72460f82b83256409542", null ] + ] ], + [ "MQTTAgentCommand_t", "struct_m_q_t_t_agent_command.html", [ + [ "commandType", "struct_m_q_t_t_agent_command.html#ae810f32d3650badbe3f8a86d5754adf1", null ], + [ "pArgs", "struct_m_q_t_t_agent_command.html#a0d41721e83bc91b39b7f54b39c97fafa", null ], + [ "pCommandCompleteCallback", "struct_m_q_t_t_agent_command.html#a4221813f0ee8d6be1e2b1f60b31fb2a3", null ], + [ "pCmdContext", "struct_m_q_t_t_agent_command.html#ae7f9dad4bc0c849dae9dd2aa8c20eeef", null ] + ] ], + [ "MQTTAgentAckInfo_t", "struct_m_q_t_t_agent_ack_info__t.html", [ + [ "packetId", "struct_m_q_t_t_agent_ack_info__t.html#ac3db584579455d37c7ad8656aa4b03f2", null ], + [ "pOriginalCommand", "struct_m_q_t_t_agent_ack_info__t.html#a4cddb1600b6ef0d3a34af262d919b2be", null ] + ] ], + [ "MQTTAgentContext_t", "struct_m_q_t_t_agent_context__t.html", [ + [ "mqttContext", "struct_m_q_t_t_agent_context__t.html#aec01b2b61213956dc2219f620964a055", null ], + [ "agentInterface", "struct_m_q_t_t_agent_context__t.html#ab89557b0a015d1848b8d6a9adbff8a4d", null ], + [ "pPendingAcks", "struct_m_q_t_t_agent_context__t.html#a324ccd898ba0769142b29b4cab38c5be", null ], + [ "pIncomingCallback", "struct_m_q_t_t_agent_context__t.html#a1e20b7a77aab94f5c775ca3c534cb006", null ], + [ "pIncomingCallbackContext", "struct_m_q_t_t_agent_context__t.html#a00a73b9d9cfda64aeb9e7b796222dde4", null ], + [ "packetReceivedInLoop", "struct_m_q_t_t_agent_context__t.html#af284de4e09e0b18411969aad986c8789", null ] + ] ], + [ "MQTTAgentSubscribeArgs_t", "struct_m_q_t_t_agent_subscribe_args__t.html", [ + [ "pSubscribeInfo", "struct_m_q_t_t_agent_subscribe_args__t.html#a27e21bfcf0184a4a168a6170a60fc026", null ], + [ "numSubscriptions", "struct_m_q_t_t_agent_subscribe_args__t.html#ae30aaa33e7a0e67a5989c2d15170de95", null ] + ] ], + [ "MQTTAgentConnectArgs_t", "struct_m_q_t_t_agent_connect_args__t.html", [ + [ "pConnectInfo", "struct_m_q_t_t_agent_connect_args__t.html#a9b71b1787c8cfe03654b1ca06ac594fa", null ], + [ "pWillInfo", "struct_m_q_t_t_agent_connect_args__t.html#a1ab24eb17eebc51bdad53ee2b36c8cdb", null ], + [ "timeoutMs", "struct_m_q_t_t_agent_connect_args__t.html#a631a199abde2ad2b3e4c69cf211e4d54", null ], + [ "sessionPresent", "struct_m_q_t_t_agent_connect_args__t.html#a01e3a80d5db4f5f89df44697cca1513f", null ] + ] ], + [ "MQTTAgentCommandInfo_t", "struct_m_q_t_t_agent_command_info__t.html", [ + [ "cmdCompleteCallback", "struct_m_q_t_t_agent_command_info__t.html#a4c9e9b55c7b576a390f734238b60f3aa", null ], + [ "pCmdCompleteCallbackContext", "struct_m_q_t_t_agent_command_info__t.html#a22fc349b76808064646fe71a43d37b96", null ], + [ "blockTimeMs", "struct_m_q_t_t_agent_command_info__t.html#aa0f490187c1199c2d31d4c04a01d4637", null ] + ] ], + [ "MQTTAgentCommandFuncReturns_t", "struct_m_q_t_t_agent_command_func_returns__t.html", [ + [ "packetId", "struct_m_q_t_t_agent_command_func_returns__t.html#ae37354b1e32541cb6b014f270815a28d", null ], + [ "endLoop", "struct_m_q_t_t_agent_command_func_returns__t.html#aea0742c902ee70380f308b7f957dc9a2", null ], + [ "addAcknowledgment", "struct_m_q_t_t_agent_command_func_returns__t.html#a474988426514661ae649a613b1dee051", null ], + [ "runProcessLoop", "struct_m_q_t_t_agent_command_func_returns__t.html#aae5a1d50a22df21950d586f5584e8994", null ] + ] ], + [ "MQTTAgentMessageInterface_t", "struct_m_q_t_t_agent_message_interface__t.html", [ + [ "pMsgCtx", "struct_m_q_t_t_agent_message_interface__t.html#a00cad3c3514a03d5deed20609ffdc94b", null ], + [ "send", "struct_m_q_t_t_agent_message_interface__t.html#abdc8e1c30aa27bf633f4f6e7da9a6465", null ], + [ "recv", "struct_m_q_t_t_agent_message_interface__t.html#a19e00e6431f53e595837d8ac7e4f744b", null ], + [ "getCommand", "struct_m_q_t_t_agent_message_interface__t.html#aaa4d0614e8289d7ea12422e66c1e8689", null ], + [ "releaseCommand", "struct_m_q_t_t_agent_message_interface__t.html#ac809ba46da91df0fc4750ce515bf8f41", null ] + ] ], + [ "MQTTAgentCommandContext_t", "group__mqtt__agent__struct__types.html#ga953da1618097a29381f3fc38f576055c", null ], + [ "MQTTAgentMessageContext_t", "group__mqtt__agent__struct__types.html#ga3c47f2ebcec2e1150e40d039639e5a3b", null ] +]; \ No newline at end of file diff --git a/latest/index.html b/latest/index.html new file mode 100644 index 00000000..6f00ec41 --- /dev/null +++ b/latest/index.html @@ -0,0 +1,140 @@ + + + + + + + +coreMQTT Agent: Overview + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Overview
+
+
+

Thread safe MQTT 3.1.1 client

+

The coreMQTT Agent is a thread-safe library to serialize calls to coreMQTT, to be executed by a single thread. It provides APIs for a single, dedicated agent task to process coreMQTT related commands, and the APIs for other tasks to enqueue these commands for processing.

+

+Why is there a higher level library based on coreMQTT?

+

coreMQTT is an MIT licensed open source C MQTT client library for microcontroller and small microprocessor based IoT devices. Its design is intentionally simple to ensure it has no dependency on any other library or operating system, and to better enable static analysis including memory safety proofs. That simplicity and lack of operating system dependency (coreMQTT does not require multithreading at all) means coreMQTT does not build thread safety directly into its implementation. Instead, thread safety must be provided by higher level software. The coreMQTT Agent library is a coreMQTT extension that provides that higher level functionality in the form of an MQTT agent (or MQTT daemon).

+

+Memory Requirements

+

Memory requirements of the MQTT Agent library, including the coreMQTT library.

+

+ + + + + + + + + + + + + + + + +
Code Size of coreMQTT Agent (example generated with GCC for ARM Cortex-M)
File
With -O1 Optimization
With -Os Optimization
core_mqtt_agent.c
1.7K
1.5K
core_mqtt_agent_command_functions.c
0.3K
0.2K
core_mqtt.c (coreMQTT)
4.1K
3.5K
core_mqtt_state.c (coreMQTT)
1.7K
1.3K
core_mqtt_serializer.c (coreMQTT)
2.8K
2.2K
Total estimates
10.6K
8.7K
+

+
+
+
+ + + + diff --git a/latest/index.js b/latest/index.js new file mode 100644 index 00000000..3078b616 --- /dev/null +++ b/latest/index.js @@ -0,0 +1,5 @@ +var index = +[ + [ "Why is there a higher level library based on coreMQTT?", "index.html#coreMQTT_brief", null ], + [ "Memory Requirements", "index.html#core_mqtt_agent_memory_requirements", null ] +]; \ No newline at end of file diff --git a/latest/jquery.js b/latest/jquery.js new file mode 100644 index 00000000..1dffb65b --- /dev/null +++ b/latest/jquery.js @@ -0,0 +1,34 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=y(e||this.defaultElement||this)[0],this.element=y(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=y(),this.hoverable=y(),this.focusable=y(),this.classesElementLookup={},e!==this&&(y.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=y(e.style?e.ownerDocument:e.document||e),this.window=y(this.document[0].defaultView||this.document[0].parentWindow)),this.options=y.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:y.noop,_create:y.noop,_init:y.noop,destroy:function(){var i=this;this._destroy(),y.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:y.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return y.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=y.widget.extend({},this.options[t]),n=0;n
"),i=e.children()[0];return y("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),s=t-i},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.widthx(D(s),D(n))?o.important="horizontal":o.important="vertical",p.using.call(this,t,o)}),h.offset(y.extend(l,{using:t}))})},y.ui.position={fit:{left:function(t,e){var i=e.within,s=i.isWindow?i.scrollLeft:i.offset.left,n=i.width,o=t.left-e.collisionPosition.marginLeft,h=s-o,a=o+e.collisionWidth-n-s;e.collisionWidth>n?0n?0=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),y.ui.plugin={add:function(t,e,i){var s,n=y.ui[t].prototype;for(s in i)n.plugins[s]=n.plugins[s]||[],n.plugins[s].push([e,i[s]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;n").css({overflow:"hidden",position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,t={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(t),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(t),this._proportionallyResize()),this._setupHandles(),e.autoHide&&y(this.element).on("mouseenter",function(){e.disabled||(i._removeClass("ui-resizable-autohide"),i._handles.show())}).on("mouseleave",function(){e.disabled||i.resizing||(i._addClass("ui-resizable-autohide"),i._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy(),this._addedHandles.remove();function t(t){y(t).removeData("resizable").removeData("ui-resizable").off(".resizable")}var e;return this.elementIsWrapper&&(t(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),t(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;case"aspectRatio":this._aspectRatio=!!e}},_setupHandles:function(){var t,e,i,s,n,o=this.options,h=this;if(this.handles=o.handles||(y(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=y(),this._addedHandles=y(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),i=this.handles.split(","),this.handles={},e=0;e"),this._addClass(n,"ui-resizable-handle "+s),n.css({zIndex:o.zIndex}),this.handles[t]=".ui-resizable-"+t,this.element.children(this.handles[t]).length||(this.element.append(n),this._addedHandles=this._addedHandles.add(n));this._renderAxis=function(t){var e,i,s;for(e in t=t||this.element,this.handles)this.handles[e].constructor===String?this.handles[e]=this.element.children(this.handles[e]).first().show():(this.handles[e].jquery||this.handles[e].nodeType)&&(this.handles[e]=y(this.handles[e]),this._on(this.handles[e],{mousedown:h._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(i=y(this.handles[e],this.element),s=/sw|ne|nw|se|n|s/.test(e)?i.outerHeight():i.outerWidth(),i=["padding",/ne|nw|n/.test(e)?"Top":/se|sw|s/.test(e)?"Bottom":/^e$/.test(e)?"Right":"Left"].join(""),t.css(i,s),this._proportionallyResize()),this._handles=this._handles.add(this.handles[e])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){h.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),h.axis=n&&n[1]?n[1]:"se")}),o.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._addedHandles.remove()},_mouseCapture:function(t){var e,i,s=!1;for(e in this.handles)(i=y(this.handles[e])[0])!==t.target&&!y.contains(i,t.target)||(s=!0);return!this.options.disabled&&s},_mouseStart:function(t){var e,i,s=this.options,n=this.element;return this.resizing=!0,this._renderProxy(),e=this._num(this.helper.css("left")),i=this._num(this.helper.css("top")),s.containment&&(e+=y(s.containment).scrollLeft()||0,i+=y(s.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:e,top:i},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:n.width(),height:n.height()},this.originalSize=this._helper?{width:n.outerWidth(),height:n.outerHeight()}:{width:n.width(),height:n.height()},this.sizeDiff={width:n.outerWidth()-n.width(),height:n.outerHeight()-n.height()},this.originalPosition={left:e,top:i},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio="number"==typeof s.aspectRatio?s.aspectRatio:this.originalSize.width/this.originalSize.height||1,s=y(".ui-resizable-"+this.axis).css("cursor"),y("body").css("cursor","auto"===s?this.axis+"-resize":s),this._addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var e=this.originalMousePosition,i=this.axis,s=t.pageX-e.left||0,e=t.pageY-e.top||0,i=this._change[i];return this._updatePrevProperties(),i&&(e=i.apply(this,[t,s,e]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(e=this._updateRatio(e,t)),e=this._respectSize(e,t),this._updateCache(e),this._propagate("resize",t),e=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),y.isEmptyObject(e)||(this._updatePrevProperties(),this._trigger("resize",t,this.ui()),this._applyChanges())),!1},_mouseStop:function(t){this.resizing=!1;var e,i,s,n=this.options,o=this;return this._helper&&(s=(e=(i=this._proportionallyResizeElements).length&&/textarea/i.test(i[0].nodeName))&&this._hasScroll(i[0],"left")?0:o.sizeDiff.height,i=e?0:o.sizeDiff.width,e={width:o.helper.width()-i,height:o.helper.height()-s},i=parseFloat(o.element.css("left"))+(o.position.left-o.originalPosition.left)||null,s=parseFloat(o.element.css("top"))+(o.position.top-o.originalPosition.top)||null,n.animate||this.element.css(y.extend(e,{top:s,left:i})),o.helper.height(o.size.height),o.helper.width(o.size.width),this._helper&&!n.animate&&this._proportionallyResize()),y("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s=this.options,n={minWidth:this._isNumber(s.minWidth)?s.minWidth:0,maxWidth:this._isNumber(s.maxWidth)?s.maxWidth:1/0,minHeight:this._isNumber(s.minHeight)?s.minHeight:0,maxHeight:this._isNumber(s.maxHeight)?s.maxHeight:1/0};(this._aspectRatio||t)&&(e=n.minHeight*this.aspectRatio,i=n.minWidth/this.aspectRatio,s=n.maxHeight*this.aspectRatio,t=n.maxWidth/this.aspectRatio,e>n.minWidth&&(n.minWidth=e),i>n.minHeight&&(n.minHeight=i),st.width,h=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,a=this.originalPosition.left+this.originalSize.width,r=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),i=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),h&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=a-e.minWidth),s&&l&&(t.left=a-e.maxWidth),h&&i&&(t.top=r-e.minHeight),n&&i&&(t.top=r-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];e<4;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;e").css({overflow:"hidden"}),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++e.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize;return{left:this.originalPosition.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize;return{top:this.originalPosition.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(t,e,i){return y.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},sw:function(t,e,i){return y.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,e,i]))},ne:function(t,e,i){return y.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},nw:function(t,e,i){return y.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,e,i]))}},_propagate:function(t,e){y.ui.plugin.call(this,t,[e,this.ui()]),"resize"!==t&&this._trigger(t,e,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),y.ui.plugin.add("resizable","animate",{stop:function(e){var i=y(this).resizable("instance"),t=i.options,s=i._proportionallyResizeElements,n=s.length&&/textarea/i.test(s[0].nodeName),o=n&&i._hasScroll(s[0],"left")?0:i.sizeDiff.height,h=n?0:i.sizeDiff.width,n={width:i.size.width-h,height:i.size.height-o},h=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,o=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(y.extend(n,o&&h?{top:o,left:h}:{}),{duration:t.animateDuration,easing:t.animateEasing,step:function(){var t={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};s&&s.length&&y(s[0]).css({width:t.width,height:t.height}),i._updateCache(t),i._propagate("resize",e)}})}}),y.ui.plugin.add("resizable","containment",{start:function(){var i,s,n=y(this).resizable("instance"),t=n.options,e=n.element,o=t.containment,h=o instanceof y?o.get(0):/parent/.test(o)?e.parent().get(0):o;h&&(n.containerElement=y(h),/document/.test(o)||o===document?(n.containerOffset={left:0,top:0},n.containerPosition={left:0,top:0},n.parentData={element:y(document),left:0,top:0,width:y(document).width(),height:y(document).height()||document.body.parentNode.scrollHeight}):(i=y(h),s=[],y(["Top","Right","Left","Bottom"]).each(function(t,e){s[t]=n._num(i.css("padding"+e))}),n.containerOffset=i.offset(),n.containerPosition=i.position(),n.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},t=n.containerOffset,e=n.containerSize.height,o=n.containerSize.width,o=n._hasScroll(h,"left")?h.scrollWidth:o,e=n._hasScroll(h)?h.scrollHeight:e,n.parentData={element:h,left:t.left,top:t.top,width:o,height:e}))},resize:function(t){var e=y(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.position,o=e._aspectRatio||t.shiftKey,h={top:0,left:0},a=e.containerElement,t=!0;a[0]!==document&&/static/.test(a.css("position"))&&(h=s),n.left<(e._helper?s.left:0)&&(e.size.width=e.size.width+(e._helper?e.position.left-s.left:e.position.left-h.left),o&&(e.size.height=e.size.width/e.aspectRatio,t=!1),e.position.left=i.helper?s.left:0),n.top<(e._helper?s.top:0)&&(e.size.height=e.size.height+(e._helper?e.position.top-s.top:e.position.top),o&&(e.size.width=e.size.height*e.aspectRatio,t=!1),e.position.top=e._helper?s.top:0),i=e.containerElement.get(0)===e.element.parent().get(0),n=/relative|absolute/.test(e.containerElement.css("position")),i&&n?(e.offset.left=e.parentData.left+e.position.left,e.offset.top=e.parentData.top+e.position.top):(e.offset.left=e.element.offset().left,e.offset.top=e.element.offset().top),n=Math.abs(e.sizeDiff.width+(e._helper?e.offset.left-h.left:e.offset.left-s.left)),s=Math.abs(e.sizeDiff.height+(e._helper?e.offset.top-h.top:e.offset.top-s.top)),n+e.size.width>=e.parentData.width&&(e.size.width=e.parentData.width-n,o&&(e.size.height=e.size.width/e.aspectRatio,t=!1)),s+e.size.height>=e.parentData.height&&(e.size.height=e.parentData.height-s,o&&(e.size.width=e.size.height*e.aspectRatio,t=!1)),t||(e.position.left=e.prevPosition.left,e.position.top=e.prevPosition.top,e.size.width=e.prevSize.width,e.size.height=e.prevSize.height)},stop:function(){var t=y(this).resizable("instance"),e=t.options,i=t.containerOffset,s=t.containerPosition,n=t.containerElement,o=y(t.helper),h=o.offset(),a=o.outerWidth()-t.sizeDiff.width,o=o.outerHeight()-t.sizeDiff.height;t._helper&&!e.animate&&/relative/.test(n.css("position"))&&y(this).css({left:h.left-s.left-i.left,width:a,height:o}),t._helper&&!e.animate&&/static/.test(n.css("position"))&&y(this).css({left:h.left-s.left-i.left,width:a,height:o})}}),y.ui.plugin.add("resizable","alsoResize",{start:function(){var t=y(this).resizable("instance").options;y(t.alsoResize).each(function(){var t=y(this);t.data("ui-resizable-alsoresize",{width:parseFloat(t.width()),height:parseFloat(t.height()),left:parseFloat(t.css("left")),top:parseFloat(t.css("top"))})})},resize:function(t,i){var e=y(this).resizable("instance"),s=e.options,n=e.originalSize,o=e.originalPosition,h={height:e.size.height-n.height||0,width:e.size.width-n.width||0,top:e.position.top-o.top||0,left:e.position.left-o.left||0};y(s.alsoResize).each(function(){var t=y(this),s=y(this).data("ui-resizable-alsoresize"),n={},e=t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];y.each(e,function(t,e){var i=(s[e]||0)+(h[e]||0);i&&0<=i&&(n[e]=i||null)}),t.css(n)})},stop:function(){y(this).removeData("ui-resizable-alsoresize")}}),y.ui.plugin.add("resizable","ghost",{start:function(){var t=y(this).resizable("instance"),e=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}),t._addClass(t.ghost,"ui-resizable-ghost"),!1!==y.uiBackCompat&&"string"==typeof t.options.ghost&&t.ghost.addClass(this.options.ghost),t.ghost.appendTo(t.helper)},resize:function(){var t=y(this).resizable("instance");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=y(this).resizable("instance");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),y.ui.plugin.add("resizable","grid",{resize:function(){var t,e=y(this).resizable("instance"),i=e.options,s=e.size,n=e.originalSize,o=e.originalPosition,h=e.axis,a="number"==typeof i.grid?[i.grid,i.grid]:i.grid,r=a[0]||1,l=a[1]||1,u=Math.round((s.width-n.width)/r)*r,p=Math.round((s.height-n.height)/l)*l,d=n.width+u,c=n.height+p,f=i.maxWidth&&i.maxWidthd,s=i.minHeight&&i.minHeight>c;i.grid=a,m&&(d+=r),s&&(c+=l),f&&(d-=r),g&&(c-=l),/^(se|s|e)$/.test(h)?(e.size.width=d,e.size.height=c):/^(ne)$/.test(h)?(e.size.width=d,e.size.height=c,e.position.top=o.top-p):/^(sw)$/.test(h)?(e.size.width=d,e.size.height=c,e.position.left=o.left-u):((c-l<=0||d-r<=0)&&(t=e._getPaddingPlusBorderDimensions(this)),0=f[g]?0:Math.min(f[g],n));!a&&1-1){targetElements.on(evt+EVENT_NAMESPACE,function elementToggle(event){$.powerTip.toggle(this,event)})}else{targetElements.on(evt+EVENT_NAMESPACE,function elementOpen(event){$.powerTip.show(this,event)})}});$.each(options.closeEvents,function(idx,evt){if($.inArray(evt,options.openEvents)<0){targetElements.on(evt+EVENT_NAMESPACE,function elementClose(event){$.powerTip.hide(this,!isMouseEvent(event))})}});targetElements.on("keydown"+EVENT_NAMESPACE,function elementKeyDown(event){if(event.keyCode===27){$.powerTip.hide(this,true)}})}return targetElements};$.fn.powerTip.defaults={fadeInTime:200,fadeOutTime:100,followMouse:false,popupId:"powerTip",popupClass:null,intentSensitivity:7,intentPollInterval:100,closeDelay:100,placement:"n",smartPlacement:false,offset:10,mouseOnToPopup:false,manual:false,openEvents:["mouseenter","focus"],closeEvents:["mouseleave","blur"]};$.fn.powerTip.smartPlacementLists={n:["n","ne","nw","s"],e:["e","ne","se","w","nw","sw","n","s","e"],s:["s","se","sw","n"],w:["w","nw","sw","e","ne","se","n","s","w"],nw:["nw","w","sw","n","s","se","nw"],ne:["ne","e","se","n","s","sw","ne"],sw:["sw","w","nw","s","n","ne","sw"],se:["se","e","ne","s","n","nw","se"],"nw-alt":["nw-alt","n","ne-alt","sw-alt","s","se-alt","w","e"],"ne-alt":["ne-alt","n","nw-alt","se-alt","s","sw-alt","e","w"],"sw-alt":["sw-alt","s","se-alt","nw-alt","n","ne-alt","w","e"],"se-alt":["se-alt","s","sw-alt","ne-alt","n","nw-alt","e","w"]};$.powerTip={show:function apiShowTip(element,event){if(isMouseEvent(event)){trackMouse(event);session.previousX=event.pageX;session.previousY=event.pageY;$(element).data(DATA_DISPLAYCONTROLLER).show()}else{$(element).first().data(DATA_DISPLAYCONTROLLER).show(true,true)}return element},reposition:function apiResetPosition(element){$(element).first().data(DATA_DISPLAYCONTROLLER).resetPosition();return element},hide:function apiCloseTip(element,immediate){var displayController;immediate=element?immediate:true;if(element){displayController=$(element).first().data(DATA_DISPLAYCONTROLLER)}else if(session.activeHover){displayController=session.activeHover.data(DATA_DISPLAYCONTROLLER)}if(displayController){displayController.hide(immediate)}return element},toggle:function apiToggle(element,event){if(session.activeHover&&session.activeHover.is(element)){$.powerTip.hide(element,!isMouseEvent(event))}else{$.powerTip.show(element,event)}return element}};$.powerTip.showTip=$.powerTip.show;$.powerTip.closeTip=$.powerTip.hide;function CSSCoordinates(){var me=this;me.top="auto";me.left="auto";me.right="auto";me.bottom="auto";me.set=function(property,value){if($.isNumeric(value)){me[property]=Math.round(value)}}}function DisplayController(element,options,tipController){var hoverTimer=null,myCloseDelay=null;function openTooltip(immediate,forceOpen){cancelTimer();if(!element.data(DATA_HASACTIVEHOVER)){if(!immediate){session.tipOpenImminent=true;hoverTimer=setTimeout(function intentDelay(){hoverTimer=null;checkForIntent()},options.intentPollInterval)}else{if(forceOpen){element.data(DATA_FORCEDOPEN,true)}closeAnyDelayed();tipController.showTip(element)}}else{cancelClose()}}function closeTooltip(disableDelay){if(myCloseDelay){myCloseDelay=session.closeDelayTimeout=clearTimeout(myCloseDelay);session.delayInProgress=false}cancelTimer();session.tipOpenImminent=false;if(element.data(DATA_HASACTIVEHOVER)){element.data(DATA_FORCEDOPEN,false);if(!disableDelay){session.delayInProgress=true;session.closeDelayTimeout=setTimeout(function closeDelay(){session.closeDelayTimeout=null;tipController.hideTip(element);session.delayInProgress=false;myCloseDelay=null},options.closeDelay);myCloseDelay=session.closeDelayTimeout}else{tipController.hideTip(element)}}}function checkForIntent(){var xDifference=Math.abs(session.previousX-session.currentX),yDifference=Math.abs(session.previousY-session.currentY),totalDifference=xDifference+yDifference;if(totalDifference",{id:options.popupId});if($body.length===0){$body=$("body")}$body.append(tipElement);session.tooltips=session.tooltips?session.tooltips.add(tipElement):tipElement}if(options.followMouse){if(!tipElement.data(DATA_HASMOUSEMOVE)){$document.on("mousemove"+EVENT_NAMESPACE,positionTipOnCursor);$window.on("scroll"+EVENT_NAMESPACE,positionTipOnCursor);tipElement.data(DATA_HASMOUSEMOVE,true)}}function beginShowTip(element){element.data(DATA_HASACTIVEHOVER,true);tipElement.queue(function queueTipInit(next){showTip(element);next()})}function showTip(element){var tipContent;if(!element.data(DATA_HASACTIVEHOVER)){return}if(session.isTipOpen){if(!session.isClosing){hideTip(session.activeHover)}tipElement.delay(100).queue(function queueTipAgain(next){showTip(element);next()});return}element.trigger("powerTipPreRender");tipContent=getTooltipContent(element);if(tipContent){tipElement.empty().append(tipContent)}else{return}element.trigger("powerTipRender");session.activeHover=element;session.isTipOpen=true;tipElement.data(DATA_MOUSEONTOTIP,options.mouseOnToPopup);tipElement.addClass(options.popupClass);if(!options.followMouse||element.data(DATA_FORCEDOPEN)){positionTipOnElement(element);session.isFixedTipOpen=true}else{positionTipOnCursor()}if(!element.data(DATA_FORCEDOPEN)&&!options.followMouse){$document.on("click"+EVENT_NAMESPACE,function documentClick(event){var target=event.target;if(target!==element[0]){if(options.mouseOnToPopup){if(target!==tipElement[0]&&!$.contains(tipElement[0],target)){$.powerTip.hide()}}else{$.powerTip.hide()}}})}if(options.mouseOnToPopup&&!options.manual){tipElement.on("mouseenter"+EVENT_NAMESPACE,function tipMouseEnter(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).cancel()}});tipElement.on("mouseleave"+EVENT_NAMESPACE,function tipMouseLeave(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).hide()}})}tipElement.fadeIn(options.fadeInTime,function fadeInCallback(){if(!session.desyncTimeout){session.desyncTimeout=setInterval(closeDesyncedTip,500)}element.trigger("powerTipOpen")})}function hideTip(element){session.isClosing=true;session.isTipOpen=false;session.desyncTimeout=clearInterval(session.desyncTimeout);element.data(DATA_HASACTIVEHOVER,false);element.data(DATA_FORCEDOPEN,false);$document.off("click"+EVENT_NAMESPACE);tipElement.off(EVENT_NAMESPACE);tipElement.fadeOut(options.fadeOutTime,function fadeOutCallback(){var coords=new CSSCoordinates;session.activeHover=null;session.isClosing=false;session.isFixedTipOpen=false;tipElement.removeClass();coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);tipElement.css(coords);element.trigger("powerTipClose")})}function positionTipOnCursor(){var tipWidth,tipHeight,coords,collisions,collisionCount;if(!session.isFixedTipOpen&&(session.isTipOpen||session.tipOpenImminent&&tipElement.data(DATA_HASMOUSEMOVE))){tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=new CSSCoordinates;coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);collisions=getViewportCollisions(coords,tipWidth,tipHeight);if(collisions!==Collision.none){collisionCount=countFlags(collisions);if(collisionCount===1){if(collisions===Collision.right){coords.set("left",session.scrollLeft+session.windowWidth-tipWidth)}else if(collisions===Collision.bottom){coords.set("top",session.scrollTop+session.windowHeight-tipHeight)}}else{coords.set("left",session.currentX-tipWidth-options.offset);coords.set("top",session.currentY-tipHeight-options.offset)}}tipElement.css(coords)}}function positionTipOnElement(element){var priorityList,finalPlacement;if(options.smartPlacement||options.followMouse&&element.data(DATA_FORCEDOPEN)){priorityList=$.fn.powerTip.smartPlacementLists[options.placement];$.each(priorityList,function(idx,pos){var collisions=getViewportCollisions(placeTooltip(element,pos),tipElement.outerWidth(),tipElement.outerHeight());finalPlacement=pos;return collisions!==Collision.none})}else{placeTooltip(element,options.placement);finalPlacement=options.placement}tipElement.removeClass("w nw sw e ne se n s w se-alt sw-alt ne-alt nw-alt");tipElement.addClass(finalPlacement)}function placeTooltip(element,placement){var iterationCount=0,tipWidth,tipHeight,coords=new CSSCoordinates;coords.set("top",0);coords.set("left",0);tipElement.css(coords);do{tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=placementCalculator.compute(element,placement,tipWidth,tipHeight,options.offset);tipElement.css(coords)}while(++iterationCount<=5&&(tipWidth!==tipElement.outerWidth()||tipHeight!==tipElement.outerHeight()));return coords}function closeDesyncedTip(){var isDesynced=false,hasDesyncableCloseEvent=$.grep(["mouseleave","mouseout","blur","focusout"],function(eventType){return $.inArray(eventType,options.closeEvents)!==-1}).length>0;if(session.isTipOpen&&!session.isClosing&&!session.delayInProgress&&hasDesyncableCloseEvent){if(session.activeHover.data(DATA_HASACTIVEHOVER)===false||session.activeHover.is(":disabled")){isDesynced=true}else if(!isMouseOver(session.activeHover)&&!session.activeHover.is(":focus")&&!session.activeHover.data(DATA_FORCEDOPEN)){if(tipElement.data(DATA_MOUSEONTOTIP)){if(!isMouseOver(tipElement)){isDesynced=true}}else{isDesynced=true}}if(isDesynced){hideTip(session.activeHover)}}}this.showTip=beginShowTip;this.hideTip=hideTip;this.resetPosition=positionTipOnElement}function isSvgElement(element){return Boolean(window.SVGElement&&element[0]instanceof SVGElement)}function isMouseEvent(event){return Boolean(event&&$.inArray(event.type,MOUSE_EVENTS)>-1&&typeof event.pageX==="number")}function initTracking(){if(!session.mouseTrackingActive){session.mouseTrackingActive=true;getViewportDimensions();$(getViewportDimensions);$document.on("mousemove"+EVENT_NAMESPACE,trackMouse);$window.on("resize"+EVENT_NAMESPACE,trackResize);$window.on("scroll"+EVENT_NAMESPACE,trackScroll)}}function getViewportDimensions(){session.scrollLeft=$window.scrollLeft();session.scrollTop=$window.scrollTop();session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackResize(){session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackScroll(){var x=$window.scrollLeft(),y=$window.scrollTop();if(x!==session.scrollLeft){session.currentX+=x-session.scrollLeft;session.scrollLeft=x}if(y!==session.scrollTop){session.currentY+=y-session.scrollTop;session.scrollTop=y}}function trackMouse(event){session.currentX=event.pageX;session.currentY=event.pageY}function isMouseOver(element){var elementPosition=element.offset(),elementBox=element[0].getBoundingClientRect(),elementWidth=elementBox.right-elementBox.left,elementHeight=elementBox.bottom-elementBox.top;return session.currentX>=elementPosition.left&&session.currentX<=elementPosition.left+elementWidth&&session.currentY>=elementPosition.top&&session.currentY<=elementPosition.top+elementHeight}function getTooltipContent(element){var tipText=element.data(DATA_POWERTIP),tipObject=element.data(DATA_POWERTIPJQ),tipTarget=element.data(DATA_POWERTIPTARGET),targetElement,content;if(tipText){if($.isFunction(tipText)){tipText=tipText.call(element[0])}content=tipText}else if(tipObject){if($.isFunction(tipObject)){tipObject=tipObject.call(element[0])}if(tipObject.length>0){content=tipObject.clone(true,true)}}else if(tipTarget){targetElement=$("#"+tipTarget);if(targetElement.length>0){content=targetElement.html()}}return content}function getViewportCollisions(coords,elementWidth,elementHeight){var viewportTop=session.scrollTop,viewportLeft=session.scrollLeft,viewportBottom=viewportTop+session.windowHeight,viewportRight=viewportLeft+session.windowWidth,collisions=Collision.none;if(coords.topviewportBottom||Math.abs(coords.bottom-session.windowHeight)>viewportBottom){collisions|=Collision.bottom}if(coords.leftviewportRight){collisions|=Collision.left}if(coords.left+elementWidth>viewportRight||coords.right1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);/*! SmartMenus jQuery Plugin - v1.1.0 - September 17, 2017 + * http://www.smartmenus.org/ + * Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function($){function initMouseDetection(t){var e=".smartmenus_mouse";if(mouseDetectionEnabled||t)mouseDetectionEnabled&&t&&($(document).off(e),mouseDetectionEnabled=!1);else{var i=!0,s=null,o={mousemove:function(t){var e={x:t.pageX,y:t.pageY,timeStamp:(new Date).getTime()};if(s){var o=Math.abs(s.x-e.x),a=Math.abs(s.y-e.y);if((o>0||a>0)&&2>=o&&2>=a&&300>=e.timeStamp-s.timeStamp&&(mouse=!0,i)){var n=$(t.target).closest("a");n.is("a")&&$.each(menuTrees,function(){return $.contains(this.$root[0],n[0])?(this.itemEnter({currentTarget:n[0]}),!1):void 0}),i=!1}}s=e}};o[touchEvents?"touchstart":"pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut"]=function(t){isTouchEvent(t.originalEvent)&&(mouse=!1)},$(document).on(getEventsNS(o,e)),mouseDetectionEnabled=!0}}function isTouchEvent(t){return!/^(4|mouse)$/.test(t.pointerType)}function getEventsNS(t,e){e||(e="");var i={};for(var s in t)i[s.split(" ").join(e+" ")+e]=t[s];return i}var menuTrees=[],mouse=!1,touchEvents="ontouchstart"in window,mouseDetectionEnabled=!1,requestAnimationFrame=window.requestAnimationFrame||function(t){return setTimeout(t,1e3/60)},cancelAnimationFrame=window.cancelAnimationFrame||function(t){clearTimeout(t)},canAnimate=!!$.fn.animate;return $.SmartMenus=function(t,e){this.$root=$(t),this.opts=e,this.rootId="",this.accessIdPrefix="",this.$subArrow=null,this.activatedItems=[],this.visibleSubMenus=[],this.showTimeout=0,this.hideTimeout=0,this.scrollTimeout=0,this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.idInc=0,this.$firstLink=null,this.$firstSub=null,this.disabled=!1,this.$disableOverlay=null,this.$touchScrollingSub=null,this.cssTransforms3d="perspective"in t.style||"webkitPerspective"in t.style,this.wasCollapsible=!1,this.init()},$.extend($.SmartMenus,{hideAll:function(){$.each(menuTrees,function(){this.menuHideAll()})},destroy:function(){for(;menuTrees.length;)menuTrees[0].destroy();initMouseDetection(!0)},prototype:{init:function(t){var e=this;if(!t){menuTrees.push(this),this.rootId=((new Date).getTime()+Math.random()+"").replace(/\D/g,""),this.accessIdPrefix="sm-"+this.rootId+"-",this.$root.hasClass("sm-rtl")&&(this.opts.rightToLeftSubMenus=!0);var i=".smartmenus";this.$root.data("smartmenus",this).attr("data-smartmenus-id",this.rootId).dataSM("level",1).on(getEventsNS({"mouseover focusin":$.proxy(this.rootOver,this),"mouseout focusout":$.proxy(this.rootOut,this),keydown:$.proxy(this.rootKeyDown,this)},i)).on(getEventsNS({mouseenter:$.proxy(this.itemEnter,this),mouseleave:$.proxy(this.itemLeave,this),mousedown:$.proxy(this.itemDown,this),focus:$.proxy(this.itemFocus,this),blur:$.proxy(this.itemBlur,this),click:$.proxy(this.itemClick,this)},i),"a"),i+=this.rootId,this.opts.hideOnClick&&$(document).on(getEventsNS({touchstart:$.proxy(this.docTouchStart,this),touchmove:$.proxy(this.docTouchMove,this),touchend:$.proxy(this.docTouchEnd,this),click:$.proxy(this.docClick,this)},i)),$(window).on(getEventsNS({"resize orientationchange":$.proxy(this.winResize,this)},i)),this.opts.subIndicators&&(this.$subArrow=$("").addClass("sub-arrow"),this.opts.subIndicatorsText&&this.$subArrow.html(this.opts.subIndicatorsText)),initMouseDetection()}if(this.$firstSub=this.$root.find("ul").each(function(){e.menuInit($(this))}).eq(0),this.$firstLink=this.$root.find("a").eq(0),this.opts.markCurrentItem){var s=/(index|default)\.[^#\?\/]*/i,o=/#.*/,a=window.location.href.replace(s,""),n=a.replace(o,"");this.$root.find("a").each(function(){var t=this.href.replace(s,""),i=$(this);(t==a||t==n)&&(i.addClass("current"),e.opts.markCurrentTree&&i.parentsUntil("[data-smartmenus-id]","ul").each(function(){$(this).dataSM("parent-a").addClass("current")}))})}this.wasCollapsible=this.isCollapsible()},destroy:function(t){if(!t){var e=".smartmenus";this.$root.removeData("smartmenus").removeAttr("data-smartmenus-id").removeDataSM("level").off(e),e+=this.rootId,$(document).off(e),$(window).off(e),this.opts.subIndicators&&(this.$subArrow=null)}this.menuHideAll();var i=this;this.$root.find("ul").each(function(){var t=$(this);t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.dataSM("shown-before")&&((i.opts.subMenusMinWidth||i.opts.subMenusMaxWidth)&&t.css({width:"",minWidth:"",maxWidth:""}).removeClass("sm-nowrap"),t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.css({zIndex:"",top:"",left:"",marginLeft:"",marginTop:"",display:""})),0==(t.attr("id")||"").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeDataSM("in-mega").removeDataSM("shown-before").removeDataSM("scroll-arrows").removeDataSM("parent-a").removeDataSM("level").removeDataSM("beforefirstshowfired").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeAttr("aria-expanded"),this.$root.find("a.has-submenu").each(function(){var t=$(this);0==t.attr("id").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeClass("has-submenu").removeDataSM("sub").removeAttr("aria-haspopup").removeAttr("aria-controls").removeAttr("aria-expanded").closest("li").removeDataSM("sub"),this.opts.subIndicators&&this.$root.find("span.sub-arrow").remove(),this.opts.markCurrentItem&&this.$root.find("a.current").removeClass("current"),t||(this.$root=null,this.$firstLink=null,this.$firstSub=null,this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),menuTrees.splice($.inArray(this,menuTrees),1))},disable:function(t){if(!this.disabled){if(this.menuHideAll(),!t&&!this.opts.isPopup&&this.$root.is(":visible")){var e=this.$root.offset();this.$disableOverlay=$('
').css({position:"absolute",top:e.top,left:e.left,width:this.$root.outerWidth(),height:this.$root.outerHeight(),zIndex:this.getStartZIndex(!0),opacity:0}).appendTo(document.body)}this.disabled=!0}},docClick:function(t){return this.$touchScrollingSub?(this.$touchScrollingSub=null,void 0):((this.visibleSubMenus.length&&!$.contains(this.$root[0],t.target)||$(t.target).closest("a").length)&&this.menuHideAll(),void 0)},docTouchEnd:function(){if(this.lastTouch){if(!(!this.visibleSubMenus.length||void 0!==this.lastTouch.x2&&this.lastTouch.x1!=this.lastTouch.x2||void 0!==this.lastTouch.y2&&this.lastTouch.y1!=this.lastTouch.y2||this.lastTouch.target&&$.contains(this.$root[0],this.lastTouch.target))){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var t=this;this.hideTimeout=setTimeout(function(){t.menuHideAll()},350)}this.lastTouch=null}},docTouchMove:function(t){if(this.lastTouch){var e=t.originalEvent.touches[0];this.lastTouch.x2=e.pageX,this.lastTouch.y2=e.pageY}},docTouchStart:function(t){var e=t.originalEvent.touches[0];this.lastTouch={x1:e.pageX,y1:e.pageY,target:e.target}},enable:function(){this.disabled&&(this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),this.disabled=!1)},getClosestMenu:function(t){for(var e=$(t).closest("ul");e.dataSM("in-mega");)e=e.parent().closest("ul");return e[0]||null},getHeight:function(t){return this.getOffset(t,!0)},getOffset:function(t,e){var i;"none"==t.css("display")&&(i={position:t[0].style.position,visibility:t[0].style.visibility},t.css({position:"absolute",visibility:"hidden"}).show());var s=t[0].getBoundingClientRect&&t[0].getBoundingClientRect(),o=s&&(e?s.height||s.bottom-s.top:s.width||s.right-s.left);return o||0===o||(o=e?t[0].offsetHeight:t[0].offsetWidth),i&&t.hide().css(i),o},getStartZIndex:function(t){var e=parseInt(this[t?"$root":"$firstSub"].css("z-index"));return!t&&isNaN(e)&&(e=parseInt(this.$root.css("z-index"))),isNaN(e)?1:e},getTouchPoint:function(t){return t.touches&&t.touches[0]||t.changedTouches&&t.changedTouches[0]||t},getViewport:function(t){var e=t?"Height":"Width",i=document.documentElement["client"+e],s=window["inner"+e];return s&&(i=Math.min(i,s)),i},getViewportHeight:function(){return this.getViewport(!0)},getViewportWidth:function(){return this.getViewport()},getWidth:function(t){return this.getOffset(t)},handleEvents:function(){return!this.disabled&&this.isCSSOn()},handleItemEvents:function(t){return this.handleEvents()&&!this.isLinkInMegaMenu(t)},isCollapsible:function(){return"static"==this.$firstSub.css("position")},isCSSOn:function(){return"inline"!=this.$firstLink.css("display")},isFixed:function(){var t="fixed"==this.$root.css("position");return t||this.$root.parentsUntil("body").each(function(){return"fixed"==$(this).css("position")?(t=!0,!1):void 0}),t},isLinkInMegaMenu:function(t){return $(this.getClosestMenu(t[0])).hasClass("mega-menu")},isTouchMode:function(){return!mouse||this.opts.noMouseOver||this.isCollapsible()},itemActivate:function(t,e){var i=t.closest("ul"),s=i.dataSM("level");if(s>1&&(!this.activatedItems[s-2]||this.activatedItems[s-2][0]!=i.dataSM("parent-a")[0])){var o=this;$(i.parentsUntil("[data-smartmenus-id]","ul").get().reverse()).add(i).each(function(){o.itemActivate($(this).dataSM("parent-a"))})}if((!this.isCollapsible()||e)&&this.menuHideSubMenus(this.activatedItems[s-1]&&this.activatedItems[s-1][0]==t[0]?s:s-1),this.activatedItems[s-1]=t,this.$root.triggerHandler("activate.smapi",t[0])!==!1){var a=t.dataSM("sub");a&&(this.isTouchMode()||!this.opts.showOnClick||this.clickActivated)&&this.menuShow(a)}},itemBlur:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&this.$root.triggerHandler("blur.smapi",e[0])},itemClick:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(this.$touchScrollingSub&&this.$touchScrollingSub[0]==e.closest("ul")[0])return this.$touchScrollingSub=null,t.stopPropagation(),!1;if(this.$root.triggerHandler("click.smapi",e[0])===!1)return!1;var i=$(t.target).is(".sub-arrow"),s=e.dataSM("sub"),o=s?2==s.dataSM("level"):!1,a=this.isCollapsible(),n=/toggle$/.test(this.opts.collapsibleBehavior),r=/link$/.test(this.opts.collapsibleBehavior),h=/^accordion/.test(this.opts.collapsibleBehavior);if(s&&!s.is(":visible")){if((!r||!a||i)&&(this.opts.showOnClick&&o&&(this.clickActivated=!0),this.itemActivate(e,h),s.is(":visible")))return this.focusActivated=!0,!1}else if(a&&(n||i))return this.itemActivate(e,h),this.menuHide(s),n&&(this.focusActivated=!1),!1;return this.opts.showOnClick&&o||e.hasClass("disabled")||this.$root.triggerHandler("select.smapi",e[0])===!1?!1:void 0}},itemDown:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&e.dataSM("mousedown",!0)},itemEnter:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(!this.isTouchMode()){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);var i=this;this.showTimeout=setTimeout(function(){i.itemActivate(e)},this.opts.showOnClick&&1==e.closest("ul").dataSM("level")?1:this.opts.showTimeout)}this.$root.triggerHandler("mouseenter.smapi",e[0])}},itemFocus:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(!this.focusActivated||this.isTouchMode()&&e.dataSM("mousedown")||this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0]==e[0]||this.itemActivate(e,!0),this.$root.triggerHandler("focus.smapi",e[0]))},itemLeave:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(this.isTouchMode()||(e[0].blur(),this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0)),e.removeDataSM("mousedown"),this.$root.triggerHandler("mouseleave.smapi",e[0]))},menuHide:function(t){if(this.$root.triggerHandler("beforehide.smapi",t[0])!==!1&&(canAnimate&&t.stop(!0,!0),"none"!=t.css("display"))){var e=function(){t.css("z-index","")};this.isCollapsible()?canAnimate&&this.opts.collapsibleHideFunction?this.opts.collapsibleHideFunction.call(this,t,e):t.hide(this.opts.collapsibleHideDuration,e):canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,t,e):t.hide(this.opts.hideDuration,e),t.dataSM("scroll")&&(this.menuScrollStop(t),t.css({"touch-action":"","-ms-touch-action":"","-webkit-transform":"",transform:""}).off(".smartmenus_scroll").removeDataSM("scroll").dataSM("scroll-arrows").hide()),t.dataSM("parent-a").removeClass("highlighted").attr("aria-expanded","false"),t.attr({"aria-expanded":"false","aria-hidden":"true"});var i=t.dataSM("level");this.activatedItems.splice(i-1,1),this.visibleSubMenus.splice($.inArray(t,this.visibleSubMenus),1),this.$root.triggerHandler("hide.smapi",t[0])}},menuHideAll:function(){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);for(var t=this.opts.isPopup?1:0,e=this.visibleSubMenus.length-1;e>=t;e--)this.menuHide(this.visibleSubMenus[e]);this.opts.isPopup&&(canAnimate&&this.$root.stop(!0,!0),this.$root.is(":visible")&&(canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,this.$root):this.$root.hide(this.opts.hideDuration))),this.activatedItems=[],this.visibleSubMenus=[],this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.$root.triggerHandler("hideAll.smapi")},menuHideSubMenus:function(t){for(var e=this.activatedItems.length-1;e>=t;e--){var i=this.activatedItems[e].dataSM("sub");i&&this.menuHide(i)}},menuInit:function(t){if(!t.dataSM("in-mega")){t.hasClass("mega-menu")&&t.find("ul").dataSM("in-mega",!0);for(var e=2,i=t[0];(i=i.parentNode.parentNode)!=this.$root[0];)e++;var s=t.prevAll("a").eq(-1);s.length||(s=t.prevAll().find("a").eq(-1)),s.addClass("has-submenu").dataSM("sub",t),t.dataSM("parent-a",s).dataSM("level",e).parent().dataSM("sub",t);var o=s.attr("id")||this.accessIdPrefix+ ++this.idInc,a=t.attr("id")||this.accessIdPrefix+ ++this.idInc;s.attr({id:o,"aria-haspopup":"true","aria-controls":a,"aria-expanded":"false"}),t.attr({id:a,role:"group","aria-hidden":"true","aria-labelledby":o,"aria-expanded":"false"}),this.opts.subIndicators&&s[this.opts.subIndicatorsPos](this.$subArrow.clone())}},menuPosition:function(t){var e,i,s=t.dataSM("parent-a"),o=s.closest("li"),a=o.parent(),n=t.dataSM("level"),r=this.getWidth(t),h=this.getHeight(t),u=s.offset(),l=u.left,c=u.top,d=this.getWidth(s),m=this.getHeight(s),p=$(window),f=p.scrollLeft(),v=p.scrollTop(),b=this.getViewportWidth(),S=this.getViewportHeight(),g=a.parent().is("[data-sm-horizontal-sub]")||2==n&&!a.hasClass("sm-vertical"),M=this.opts.rightToLeftSubMenus&&!o.is("[data-sm-reverse]")||!this.opts.rightToLeftSubMenus&&o.is("[data-sm-reverse]"),w=2==n?this.opts.mainMenuSubOffsetX:this.opts.subMenusSubOffsetX,T=2==n?this.opts.mainMenuSubOffsetY:this.opts.subMenusSubOffsetY;if(g?(e=M?d-r-w:w,i=this.opts.bottomToTopSubMenus?-h-T:m+T):(e=M?w-r:d-w,i=this.opts.bottomToTopSubMenus?m-T-h:T),this.opts.keepInViewport){var y=l+e,I=c+i;if(M&&f>y?e=g?f-y+e:d-w:!M&&y+r>f+b&&(e=g?f+b-r-y+e:w-r),g||(S>h&&I+h>v+S?i+=v+S-h-I:(h>=S||v>I)&&(i+=v-I)),g&&(I+h>v+S+.49||v>I)||!g&&h>S+.49){var x=this;t.dataSM("scroll-arrows")||t.dataSM("scroll-arrows",$([$('')[0],$('')[0]]).on({mouseenter:function(){t.dataSM("scroll").up=$(this).hasClass("scroll-up"),x.menuScroll(t)},mouseleave:function(e){x.menuScrollStop(t),x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(t){t.preventDefault()}}).insertAfter(t));var A=".smartmenus_scroll";if(t.dataSM("scroll",{y:this.cssTransforms3d?0:i-m,step:1,itemH:m,subH:h,arrowDownH:this.getHeight(t.dataSM("scroll-arrows").eq(1))}).on(getEventsNS({mouseover:function(e){x.menuScrollOver(t,e)},mouseout:function(e){x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(e){x.menuScrollMousewheel(t,e)}},A)).dataSM("scroll-arrows").css({top:"auto",left:"0",marginLeft:e+(parseInt(t.css("border-left-width"))||0),width:r-(parseInt(t.css("border-left-width"))||0)-(parseInt(t.css("border-right-width"))||0),zIndex:t.css("z-index")}).eq(g&&this.opts.bottomToTopSubMenus?0:1).show(),this.isFixed()){var C={};C[touchEvents?"touchstart touchmove touchend":"pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp"]=function(e){x.menuScrollTouch(t,e)},t.css({"touch-action":"none","-ms-touch-action":"none"}).on(getEventsNS(C,A))}}}t.css({top:"auto",left:"0",marginLeft:e,marginTop:i-m})},menuScroll:function(t,e,i){var s,o=t.dataSM("scroll"),a=t.dataSM("scroll-arrows"),n=o.up?o.upEnd:o.downEnd;if(!e&&o.momentum){if(o.momentum*=.92,s=o.momentum,.5>s)return this.menuScrollStop(t),void 0}else s=i||(e||!this.opts.scrollAccelerate?this.opts.scrollStep:Math.floor(o.step));var r=t.dataSM("level");if(this.activatedItems[r-1]&&this.activatedItems[r-1].dataSM("sub")&&this.activatedItems[r-1].dataSM("sub").is(":visible")&&this.menuHideSubMenus(r-1),o.y=o.up&&o.y>=n||!o.up&&n>=o.y?o.y:Math.abs(n-o.y)>s?o.y+(o.up?s:-s):n,t.css(this.cssTransforms3d?{"-webkit-transform":"translate3d(0, "+o.y+"px, 0)",transform:"translate3d(0, "+o.y+"px, 0)"}:{marginTop:o.y}),mouse&&(o.up&&o.y>o.downEnd||!o.up&&o.y0;t.dataSM("scroll-arrows").eq(i?0:1).is(":visible")&&(t.dataSM("scroll").up=i,this.menuScroll(t,!0))}e.preventDefault()},menuScrollOut:function(t,e){mouse&&(/^scroll-(up|down)/.test((e.relatedTarget||"").className)||(t[0]==e.relatedTarget||$.contains(t[0],e.relatedTarget))&&this.getClosestMenu(e.relatedTarget)==t[0]||t.dataSM("scroll-arrows").css("visibility","hidden"))},menuScrollOver:function(t,e){if(mouse&&!/^scroll-(up|down)/.test(e.target.className)&&this.getClosestMenu(e.target)==t[0]){this.menuScrollRefreshData(t);var i=t.dataSM("scroll"),s=$(window).scrollTop()-t.dataSM("parent-a").offset().top-i.itemH;t.dataSM("scroll-arrows").eq(0).css("margin-top",s).end().eq(1).css("margin-top",s+this.getViewportHeight()-i.arrowDownH).end().css("visibility","visible")}},menuScrollRefreshData:function(t){var e=t.dataSM("scroll"),i=$(window).scrollTop()-t.dataSM("parent-a").offset().top-e.itemH;this.cssTransforms3d&&(i=-(parseFloat(t.css("margin-top"))-i)),$.extend(e,{upEnd:i,downEnd:i+this.getViewportHeight()-e.subH})},menuScrollStop:function(t){return this.scrollTimeout?(cancelAnimationFrame(this.scrollTimeout),this.scrollTimeout=0,t.dataSM("scroll").step=1,!0):void 0},menuScrollTouch:function(t,e){if(e=e.originalEvent,isTouchEvent(e)){var i=this.getTouchPoint(e);if(this.getClosestMenu(i.target)==t[0]){var s=t.dataSM("scroll");if(/(start|down)$/i.test(e.type))this.menuScrollStop(t)?(e.preventDefault(),this.$touchScrollingSub=t):this.$touchScrollingSub=null,this.menuScrollRefreshData(t),$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp});else if(/move$/i.test(e.type)){var o=void 0!==s.touchY?s.touchY:s.touchStartY;if(void 0!==o&&o!=i.pageY){this.$touchScrollingSub=t;var a=i.pageY>o;void 0!==s.up&&s.up!=a&&$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp}),$.extend(s,{up:a,touchY:i.pageY}),this.menuScroll(t,!0,Math.abs(i.pageY-o))}e.preventDefault()}else void 0!==s.touchY&&((s.momentum=15*Math.pow(Math.abs(i.pageY-s.touchStartY)/(e.timeStamp-s.touchStartTime),2))&&(this.menuScrollStop(t),this.menuScroll(t),e.preventDefault()),delete s.touchY)}}},menuShow:function(t){if((t.dataSM("beforefirstshowfired")||(t.dataSM("beforefirstshowfired",!0),this.$root.triggerHandler("beforefirstshow.smapi",t[0])!==!1))&&this.$root.triggerHandler("beforeshow.smapi",t[0])!==!1&&(t.dataSM("shown-before",!0),canAnimate&&t.stop(!0,!0),!t.is(":visible"))){var e=t.dataSM("parent-a"),i=this.isCollapsible();if((this.opts.keepHighlighted||i)&&e.addClass("highlighted"),i)t.removeClass("sm-nowrap").css({zIndex:"",width:"auto",minWidth:"",maxWidth:"",top:"",left:"",marginLeft:"",marginTop:""});else{if(t.css("z-index",this.zIndexInc=(this.zIndexInc||this.getStartZIndex())+1),(this.opts.subMenusMinWidth||this.opts.subMenusMaxWidth)&&(t.css({width:"auto",minWidth:"",maxWidth:""}).addClass("sm-nowrap"),this.opts.subMenusMinWidth&&t.css("min-width",this.opts.subMenusMinWidth),this.opts.subMenusMaxWidth)){var s=this.getWidth(t);t.css("max-width",this.opts.subMenusMaxWidth),s>this.getWidth(t)&&t.removeClass("sm-nowrap").css("width",this.opts.subMenusMaxWidth)}this.menuPosition(t)}var o=function(){t.css("overflow","")};i?canAnimate&&this.opts.collapsibleShowFunction?this.opts.collapsibleShowFunction.call(this,t,o):t.show(this.opts.collapsibleShowDuration,o):canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,t,o):t.show(this.opts.showDuration,o),e.attr("aria-expanded","true"),t.attr({"aria-expanded":"true","aria-hidden":"false"}),this.visibleSubMenus.push(t),this.$root.triggerHandler("show.smapi",t[0])}},popupHide:function(t){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},t?1:this.opts.hideTimeout)},popupShow:function(t,e){if(!this.opts.isPopup)return alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'),void 0;if(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),this.$root.dataSM("shown-before",!0),canAnimate&&this.$root.stop(!0,!0),!this.$root.is(":visible")){this.$root.css({left:t,top:e});var i=this,s=function(){i.$root.css("overflow","")};canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,this.$root,s):this.$root.show(this.opts.showDuration,s),this.visibleSubMenus[0]=this.$root}},refresh:function(){this.destroy(!0),this.init(!0)},rootKeyDown:function(t){if(this.handleEvents())switch(t.keyCode){case 27:var e=this.activatedItems[0];if(e){this.menuHideAll(),e[0].focus();var i=e.dataSM("sub");i&&this.menuHide(i)}break;case 32:var s=$(t.target);if(s.is("a")&&this.handleItemEvents(s)){var i=s.dataSM("sub");i&&!i.is(":visible")&&(this.itemClick({currentTarget:t.target}),t.preventDefault())}}},rootOut:function(t){if(this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),!this.opts.showOnClick||!this.opts.hideOnClick)){var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},this.opts.hideTimeout)}},rootOver:function(t){this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0)},winResize:function(t){if(this.handleEvents()){if(!("onorientationchange"in window)||"orientationchange"==t.type){var e=this.isCollapsible();this.wasCollapsible&&e||(this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0].blur(),this.menuHideAll()),this.wasCollapsible=e}}else if(this.$disableOverlay){var i=this.$root.offset();this.$disableOverlay.css({top:i.top,left:i.left,width:this.$root.outerWidth(),height:this.$root.outerHeight()})}}}}),$.fn.dataSM=function(t,e){return e?this.data(t+"_smartmenus",e):this.data(t+"_smartmenus")},$.fn.removeDataSM=function(t){return this.removeData(t+"_smartmenus")},$.fn.smartmenus=function(options){if("string"==typeof options){var args=arguments,method=options;return Array.prototype.shift.call(args),this.each(function(){var t=$(this).data("smartmenus");t&&t[method]&&t[method].apply(t,args)})}return this.each(function(){var dataOpts=$(this).data("sm-options")||null;if(dataOpts)try{dataOpts=eval("("+dataOpts+")")}catch(e){dataOpts=null,alert('ERROR\n\nSmartMenus jQuery init:\nInvalid "data-sm-options" attribute value syntax.')}new $.SmartMenus(this,$.extend({},$.fn.smartmenus.defaults,options,dataOpts))})},$.fn.smartmenus.defaults={isPopup:!1,mainMenuSubOffsetX:0,mainMenuSubOffsetY:0,subMenusSubOffsetX:0,subMenusSubOffsetY:0,subMenusMinWidth:"10em",subMenusMaxWidth:"20em",subIndicators:!0,subIndicatorsPos:"append",subIndicatorsText:"",scrollStep:30,scrollAccelerate:!0,showTimeout:250,hideTimeout:500,showDuration:0,showFunction:null,hideDuration:0,hideFunction:function(t,e){t.fadeOut(200,e)},collapsibleShowDuration:0,collapsibleShowFunction:function(t,e){t.slideDown(200,e)},collapsibleHideDuration:0,collapsibleHideFunction:function(t,e){t.slideUp(200,e)},showOnClick:!1,hideOnClick:!0,noMouseOver:!1,keepInViewport:!0,keepHighlighted:!0,markCurrentItem:!1,markCurrentTree:!0,rightToLeftSubMenus:!1,bottomToTopSubMenus:!1,collapsibleBehavior:"default"},$}); \ No newline at end of file diff --git a/latest/modules.html b/latest/modules.html new file mode 100644 index 00000000..b1fd7efe --- /dev/null +++ b/latest/modules.html @@ -0,0 +1,119 @@ + + + + + + + +coreMQTT Agent: Data types and Constants + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Data types and Constants
+
+
+
This library defines the following data types and constants.
+ + + + +
 Enumerated TypesEnumerated types of the MQTT Agent
 Callback TypesCallback function pointer types of the MQTT Agent
 Parameter StructuresStructures passed as parameters to MQTT Agent functions
+
+
+
+ + + + diff --git a/latest/modules.js b/latest/modules.js new file mode 100644 index 00000000..77297ed1 --- /dev/null +++ b/latest/modules.js @@ -0,0 +1,6 @@ +var modules = +[ + [ "Enumerated Types", "group__mqtt__agent__enum__types.html", "group__mqtt__agent__enum__types" ], + [ "Callback Types", "group__mqtt__agent__callback__types.html", "group__mqtt__agent__callback__types" ], + [ "Parameter Structures", "group__mqtt__agent__struct__types.html", "group__mqtt__agent__struct__types" ] +]; \ No newline at end of file diff --git a/latest/mqtt_agent_cancel_function.html b/latest/mqtt_agent_cancel_function.html new file mode 100644 index 00000000..be68e84d --- /dev/null +++ b/latest/mqtt_agent_cancel_function.html @@ -0,0 +1,146 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_CancelAll + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_CancelAll
+
+
+
+
MQTTStatus_t MQTTAgent_CancelAll(MQTTAgentContext_t *pMqttAgentContext)
Cancel all enqueued commands and those awaiting acknowledgment while the command loop is not running.
Definition: core_mqtt_agent.c:1128
+
MQTTStatus_t
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+

Cancel all enqueued commands and those awaiting acknowledgment while the command loop is not running.

+

Canceled commands will be terminated with return code MQTTRecvFailed.

+
Parameters
+ + +
[in]pMqttAgentContextThe MQTT agent to use.
+
+
+
Note
This function is NOT thread-safe and should only be called from the context of the task responsible for MQTTAgent_CommandLoop.
+
Returns
MQTTBadParameter if an invalid context is given, else MQTTSuccess.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTAgentContext_t mqttAgentContext;
+
+
status = MQTTAgent_CommandLoop( &mqttAgentContext );
+
+
//An error was returned, but reconnection is not desired. Cancel all commands
+
//that are in the queue or awaiting an acknowledgment.
+
if( status != MQTTSuccess )
+
{
+
//Cancel commands so any completion callbacks will be invoked.
+
status = MQTTAgent_CancelAll( &mqttAgentContext );
+
}
+
+
Platform_DisconnectNetwork( mqttAgentContext.mqttContext.transportInterface.pNetworkContext );
+
MQTTStatus_t MQTTAgent_CommandLoop(MQTTAgentContext_t *pMqttAgentContext)
Process commands from the command queue in a loop.
Definition: core_mqtt_agent.c:1043
+
MQTTContext_t mqttContext
Definition: core_mqtt_agent.h:154
+
TransportInterface_t transportInterface
+
NetworkContext_t * pNetworkContext
+
+
+
+ + + + diff --git a/latest/mqtt_agent_command_function.html b/latest/mqtt_agent_command_function.html new file mode 100644 index 00000000..c8d3df2a --- /dev/null +++ b/latest/mqtt_agent_command_function.html @@ -0,0 +1,156 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_CommandLoop + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_CommandLoop
+
+
+
+
MQTTStatus_t MQTTAgent_CommandLoop(MQTTAgentContext_t *pMqttAgentContext)
Process commands from the command queue in a loop.
Definition: core_mqtt_agent.c:1043
+
MQTTStatus_t
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+

Process commands from the command queue in a loop.

+
Parameters
+ + +
[in]pMqttAgentContextThe MQTT agent to use.
+
+
+
Returns
appropriate error code, or MQTTSuccess from a successful disconnect or termination.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTAgentContext_t mqttAgentContext;
+
+
status = MQTTAgent_CommandLoop( &mqttAgentContext );
+
+
// The function returns on either receiving a terminate command,
+
// undergoing network disconnection OR encountering an error.
+
if( ( status == MQTTSuccess ) && ( mqttAgentContext.mqttContext.connectStatus == MQTTNotConnected ) )
+
{
+
// A terminate command was processed and MQTT connection was closed.
+
// Need to close socket connection.
+
Platform_DisconnectNetwork( mqttAgentContext.mqttContext.transportInterface.pNetworkContext );
+
}
+
else if( status == MQTTSuccess )
+
{
+
// Terminate command was processed but MQTT connection was not
+
// closed. Thus, need to close both MQTT and socket connections.
+
status = MQTT_Disconnect( &( mqttAgentContext.mqttContext ) );
+
assert( status == MQTTSuccess );
+
Platform_DisconnectNetwork( mqttAgentContext.mqttContext.transportInterface.pNetworkContext );
+
}
+
else
+
{
+
// Handle error.
+
}
+
MQTTStatus_t MQTT_Disconnect(MQTTContext_t *pContext)
+
MQTTContext_t mqttContext
Definition: core_mqtt_agent.h:154
+
MQTTConnectionStatus_t connectStatus
+
TransportInterface_t transportInterface
+
NetworkContext_t * pNetworkContext
+
+
+
+ + + + diff --git a/latest/mqtt_agent_connect_function.html b/latest/mqtt_agent_connect_function.html new file mode 100644 index 00000000..a93ccf29 --- /dev/null +++ b/latest/mqtt_agent_connect_function.html @@ -0,0 +1,211 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_Connect + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_Connect
+
+
+
+
MQTTAgentConnectArgs_t * pConnectArgs,
+
const MQTTAgentCommandInfo_t * pCommandInfo );
+
MQTTStatus_t MQTTAgent_Connect(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentConnectArgs_t *pConnectArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Connect() for an MQTT connection. If a session is resumed with the broker,...
Definition: core_mqtt_agent.c:1275
+
MQTTStatus_t
+
Struct holding arguments that are common to every command.
Definition: core_mqtt_agent.h:189
+
Struct holding arguments for a CONNECT call.
Definition: core_mqtt_agent.h:177
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+

Add a command to call MQTT_Connect() for an MQTT connection. If a session is resumed with the broker, it will also resend the necessary QoS1/2 publishes.

+
Note
The MQTTAgent_Connect function is provided to give a thread safe equivalent to the MQTT_Connect API. However, it is RECOMMENDED that instead of the application tasks (i.e. tasks other than the agent task), the agent be responsible for creating the MQTT connection (by calling MQTT_Connect) before starting the command loop (with the MQTTAgent_CommandLoop() call). In that case, the agent SHOULD also be responsible for disconnecting the MQTT connection after the command loop has terminated (through an MQTTAgent_Terminate() call from an application task).
+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in,out]pConnectArgsStruct holding args for MQTT_Connect(). On a successful connection after the command is processed, the sessionPresent member will be filled to indicate whether the broker resumed an existing session.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
MQTTAgentConnectArgs_t connectionArgs;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// True for creating a new session with broker, false if we want to resume an old one.
+
connectInfo.cleanSession = true;
+
// Client ID must be unique to broker. This field is required.
+
connectInfo.pClientIdentifier = "someClientID";
+
connectInfo.clientIdentifierLength = strlen( connectInfo.pClientIdentifier );
+
+
// Value for keep alive.
+
connectInfo.keepAliveSeconds = 60;
+
// The following fields are optional.
+
// Optional username and password.
+
connectInfo.pUserName = "someUserName";
+
connectInfo.userNameLength = strlen( connectInfo.pUserName );
+
connectInfo.pPassword = "somePassword";
+
connectInfo.passwordLength = strlen( connectInfo.pPassword );
+
+
// The last will and testament is optional, it will be published by the broker
+
// should this client disconnect without sending a DISCONNECT packet.
+
willInfo.qos = MQTTQoS0;
+
willInfo.pTopicName = "/lwt/topic/name";
+
willInfo.topicNameLength = strlen( willInfo.pTopicName );
+
willInfo.pPayload = "LWT Message";
+
willInfo.payloadLength = strlen( "LWT Message" );
+
+
// Fill the MQTTAgentConnectArgs_t structure.
+
connectArgs.pConnectInfo = &connectInfo;
+
connectArgs.pWillInfo = &willInfo;
+
// Time to block for CONNACK response when command is processed.
+
connectArgs.timeoutMs = 500;
+
+
// Function for command complete callback.
+
void connectCmdCallback( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = connectCmdCallback;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Connect( &agentContext, &connectArgs, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command for creating the MQTT connection has been queued.
+
// The MQTT connection event will be notified through the
+
// invocation of connectCmdCallback().
+
}
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
MQTTQoS0
+
MQTTAgentCommandCallback_t cmdCompleteCallback
Callback to invoke upon completion.
Definition: core_mqtt_agent.h:190
+
uint32_t blockTimeMs
Maximum block time for enqueueing the command.
Definition: core_mqtt_agent.h:192
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+ +
const char * pClientIdentifier
+
const char * pUserName
+ +
uint16_t userNameLength
+
uint16_t keepAliveSeconds
+
uint16_t clientIdentifierLength
+
uint16_t passwordLength
+
const char * pPassword
+ + +
uint16_t topicNameLength
+ +
const char * pTopicName
+
const void * pPayload
+
+
+
+ + + + diff --git a/latest/mqtt_agent_design.html b/latest/mqtt_agent_design.html new file mode 100644 index 00000000..35344ca0 --- /dev/null +++ b/latest/mqtt_agent_design.html @@ -0,0 +1,180 @@ + + + + + + + +coreMQTT Agent: Design + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Design
+
+
+

Architecture of the MQTT Agent library.

+

+Thread Safe and Unsafe APIs

+

The MQTT Agent APIs are designed to be used by two types of tasks:

+

+Interfaces and Callbacks

+

Similar to coreMQTT, the MQTT Agent library relies on interfaces to dissociate itself from platform specific functionality. Interfaces used by the MQTT Agent library are simply function pointers with expectations of behavior.

+

The MQTT Agent library expects the application to provide implementations for the following interfaces:

+ + + + + + + + + + + + + +
Function Pointer Use
MQTTAgentMessageRecv_t Receiving commands sent to the agent task.
MQTTAgentMessageSend_t Sending commands to the agent task from the application
MQTTAgentCommandGet_t Allocating storage for a command to be sent to the agent task.
MQTTAgentCommandRelease_t Releasing a command obtained from MQTTAgentCommandGet_t.
MQTTAgentIncomingPublishCallback_t Accepting incoming publish messages, with the possibility of further distributing them to other tasks.
+

+Command Completion

+

Commands do not have any timeout associated with them. The only way for a task to be aware of a command's completion is through the invocation of an optional MQTTAgentCommandCallback_t completion callback. The completion callback will be invoked with an optional MQTTAgentCommandContext_t, which is the incomplete type struct MQTTAgentCommandContext. This type must be defined by the application, and should contain information that would be useful in distinguishing commands.
+ Example code:

struct MQTTAgentCommandContext
+
{
+
//Allow the calling thread to view the return code by copying it here.
+
MQTTStatus_t returnCode;
+
//pthread mutex and condition variables to signal to the thread that created the command.
+
pthread_mutex_t lock;
+
pthread_cond_t cond;
+
};
+
MQTTStatus_t
+


+ The completion callback using such a context could be:

void commandCompleteCallback( MQTTAgentCommandContext_t * pCmdContext, MQTTAgentReturnInfo_t * pReturnInfo )
+
{
+
pthread_mutex_lock( &( pCmdContext->lock ) );
+
//Set return code so the thread that created the command can view.
+
pCmdContext->returnCode = pReturnInfo->returnCode;
+
pthread_mutex_unlock( &( pCmdContext->lock ) );
+
//Signal the thread using the condition variable.
+
pthread_cond_broadcast( &( pCmdContext->cond ) );
+
}
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+
MQTTStatus_t returnCode
Definition: core_mqtt_agent.h:72
+


+ The completion callback and completion context are each optional, and passed at time of command creation in the MQTTAgentCommandInfo_t parameter. If a command completion context is passed, it MUST remain in scope until the completion callback has been invoked.

+
+
+
+ + + + diff --git a/latest/mqtt_agent_disconnect_function.html b/latest/mqtt_agent_disconnect_function.html new file mode 100644 index 00000000..dc4b71b3 --- /dev/null +++ b/latest/mqtt_agent_disconnect_function.html @@ -0,0 +1,162 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_Disconnect + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_Disconnect
+
+
+
+
const MQTTAgentCommandInfo_t * pCommandInfo );
+
MQTTStatus_t MQTTAgent_Disconnect(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to disconnect an MQTT connection.
Definition: core_mqtt_agent.c:1300
+
MQTTStatus_t
+
Struct holding arguments that are common to every command.
Definition: core_mqtt_agent.h:189
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+

Add a command to disconnect an MQTT connection.

+
Note
MQTTAgent_CommandLoop will return after processing a DISCONNECT command to allow the network connection to be disconnected. However, any pending commands in the queue, as well as those waiting for an acknowledgment, will NOT be terminated.
+
+The MQTTAgent_Disconnect function is provided to give a thread safe equivalent to the MQTT_Disconnect API. However, if the agent task is responsible for creating the MQTT connection (before calling MQTTAgent_CommandLoop()), then it is RECOMMENDED that an application task (i.e. a task other than the agent task) use MQTTAgent_Terminate to terminate the command loop in the agent, and the agent task be responsible for disconnecting the MQTT connection.
+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void disconnectCmdCallback( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = disconnectCmdCallback;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Disconnect( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command for closing the MQTT connection has been queued.
+
// The MQTT disconnection event will be notified through the
+
// invocation of disconnectCmdCallback().
+
}
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
MQTTAgentCommandCallback_t cmdCompleteCallback
Callback to invoke upon completion.
Definition: core_mqtt_agent.h:190
+
uint32_t blockTimeMs
Maximum block time for enqueueing the command.
Definition: core_mqtt_agent.h:192
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+
+
+
+ + + + diff --git a/latest/mqtt_agent_functions.html b/latest/mqtt_agent_functions.html new file mode 100644 index 00000000..384f1797 --- /dev/null +++ b/latest/mqtt_agent_functions.html @@ -0,0 +1,138 @@ + + + + + + + +coreMQTT Agent: Functions + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Functions
+
+
+

Functions of the MQTT Agent library<br>
+

+

+Thread Unsafe Functions

+

These functions are not thread safe and are designed to be used only by an MQTT agent task - a task dedicated to interfacing with the coreMQTT API.
+
+ MQTTAgent_Init
+ MQTTAgent_CommandLoop
+ MQTTAgent_ResumeSession
+ MQTTAgent_CancelAll
+
+

+

+Thread Safe Functions

+

These functions are thread safe and designed to be used by any application task (one that is not the MQTT agent task).
+
+ MQTTAgent_Publish
+ MQTTAgent_Subscribe
+ MQTTAgent_Unsubscribe
+ MQTTAgent_Connect
+ MQTTAgent_Disconnect
+ MQTTAgent_Ping
+ MQTTAgent_Terminate
+
+

+
+
+
+ + + + diff --git a/latest/mqtt_agent_functions.js b/latest/mqtt_agent_functions.js new file mode 100644 index 00000000..6deeb7ca --- /dev/null +++ b/latest/mqtt_agent_functions.js @@ -0,0 +1,16 @@ +var mqtt_agent_functions = +[ + [ "Thread Unsafe Functions", "mqtt_agent_functions.html#mqtt_agent_thread_unsafe_functions", null ], + [ "Thread Safe Functions", "mqtt_agent_functions.html#mqtt_agent_thread_safe_functions", null ], + [ "MQTTAgent_Init", "mqtt_agent_init_function.html", null ], + [ "MQTTAgent_CommandLoop", "mqtt_agent_command_function.html", null ], + [ "MQTTAgent_ResumeSession", "mqtt_agent_resume_function.html", null ], + [ "MQTTAgent_CancelAll", "mqtt_agent_cancel_function.html", null ], + [ "MQTTAgent_Publish", "mqtt_agent_publish_function.html", null ], + [ "MQTTAgent_Subscribe", "mqtt_agent_subscribe_function.html", null ], + [ "MQTTAgent_Unsubscribe", "mqtt_agent_unsubscribe_function.html", null ], + [ "MQTTAgent_Connect", "mqtt_agent_connect_function.html", null ], + [ "MQTTAgent_Disconnect", "mqtt_agent_disconnect_function.html", null ], + [ "MQTTAgent_Ping", "mqtt_agent_ping_function.html", null ], + [ "MQTTAgent_Terminate", "mqtt_agent_terminate_function.html", null ] +]; \ No newline at end of file diff --git a/latest/mqtt_agent_init_function.html b/latest/mqtt_agent_init_function.html new file mode 100644 index 00000000..11b3c80c --- /dev/null +++ b/latest/mqtt_agent_init_function.html @@ -0,0 +1,219 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_Init + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_Init
+
+
+
+
const MQTTAgentMessageInterface_t * pMsgInterface,
+
const MQTTFixedBuffer_t * pNetworkBuffer,
+
const TransportInterface_t * pTransportInterface,
+
MQTTGetCurrentTimeFunc_t getCurrentTimeMs,
+ +
void * pIncomingPacketContext );
+
MQTTStatus_t MQTTAgent_Init(MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentMessageInterface_t *pMsgInterface, const MQTTFixedBuffer_t *pNetworkBuffer, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getCurrentTimeMs, MQTTAgentIncomingPublishCallback_t incomingCallback, void *pIncomingPacketContext)
Perform any initialization the MQTT agent requires before it can be used. Must be called before any o...
Definition: core_mqtt_agent.c:968
+
void(* MQTTAgentIncomingPublishCallback_t)(struct MQTTAgentContext *pMqttAgentContext, uint16_t packetId, MQTTPublishInfo_t *pPublishInfo)
Callback function called when receiving a publish.
Definition: core_mqtt_agent.h:142
+
MQTTStatus_t
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+
Function pointers and contexts used for sending and receiving commands, and allocating memory for the...
Definition: core_mqtt_agent_message_interface.h:133
+ + +

Perform any initialization the MQTT agent requires before it can be used. Must be called before any other function.

+
Parameters
+ + + + + + + + +
[in]pMqttAgentContextPointer to struct to initialize.
[in]pMsgInterfaceCommand interface to use for allocating and sending commands.
[in]pNetworkBufferPointer to network buffer to use.
[in]pTransportInterfaceTransport interface to use with the MQTT library. See https://www.freertos.org/Documentation/03-Libraries/03-FreeRTOS-core/06-Transport-Interface/01-Transport-interface
[in]getCurrentTimeMsPointer to a function that returns a count value that increments every millisecond.
[in]incomingCallbackThe callback to execute when receiving publishes.
[in]pIncomingPacketContextA pointer to a context structure defined by the application writer.
+
+
+
Note
The pIncomingPacketContext context provided for the incoming publish callback MUST remain in scope throughout the period that the agent task is running.
+
Returns
Appropriate status code from MQTT_Init().
+

Example

// Function for obtaining a timestamp.
+
uint32_t getTimeStampMs();
+
// Callback function for receiving packets.
+
void incomingPublishCallback( MQTTAgentContext_t * pMqttAgentContext,
+
uint16_t packetId,
+
MQTTPublishInfo_t * pPublishInfo );
+
// Platform function for network send interface.
+
int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
+
// Platform for network receive interface.
+
int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
+
+
// Platform function for Agent Message Send.
+
bool agentSendMessage( MQTTAgentMessageContext_t * pMsgCtx,
+
MQTTAgentCommand_t * const * pCommandToSend,
+
uint32_t blockTimeMs );
+
// Platform function for Agent Message Receive.
+
bool agentReceiveMessage( MQTTAgentMessageContext_t * pMsgCtx,
+
MQTTAgentCommand_t ** pCommandToSend,
+
uint32_t blockTimeMs );
+
// Platform function to Get Agent Command.
+
MQTTAgentCommand_t * getCommand( uint32_t blockTimeMs );
+
// Platform function to Release Agent Command.
+
bool releaseCommand( MQTTAgentCommand_t * pCommandToRelease );
+
+
// Variables used in this example.
+
MQTTAgentMessageInterface_t messageInterface;
+ +
MQTTAgentContext_t agentContext;
+ +
// Buffer for storing outgoing and incoming MQTT packets.
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ 1024 ];
+
MQTTStatus_t status;
+
+
// Set transport interface members.
+
transport.pNetworkContext = &someTransportContext;
+
transport.send = networkSend;
+
transport.recv = networkRecv;
+
+
// Set agent message interface members.
+
messageInterface.pMsgCtx = &messageContext;
+
messageInterface.send = agentSendMessage;
+
messageInterface.recv = agentReceiveMessage;
+
messageInterface.getCommand = getCommand;
+
messageInterface.releaseCommand = releaseCommand;
+
+
// Set buffer members.
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = 1024;
+
+
status = MQTTAgent_Init( &agentContext,
+
&messageInterface,
+
&networkBuffer,
+
&transportInterface,
+
stubGetTime,
+
stubPublishCallback,
+
incomingPacketContext );
+
+
if( status == MQTTSuccess )
+
{
+
// Do something with agentContext. The transport and message interfaces, and
+
// fixedBuffer structs were copied into the context, so the original structs
+
// do not need to stay in scope.
+
}
+
struct MQTTAgentMessageContext MQTTAgentMessageContext_t
Context with which tasks may deliver messages to the agent.
Definition: core_mqtt_agent_message_interface.h:54
+
struct NetworkContext NetworkContext_t
+
MQTTAgentMessageContext_t * pMsgCtx
Definition: core_mqtt_agent_message_interface.h:134
+
MQTTAgentMessageRecv_t recv
Definition: core_mqtt_agent_message_interface.h:136
+
MQTTAgentCommandGet_t getCommand
Definition: core_mqtt_agent_message_interface.h:137
+
MQTTAgentMessageSend_t send
Definition: core_mqtt_agent_message_interface.h:135
+
MQTTAgentCommandRelease_t releaseCommand
Definition: core_mqtt_agent_message_interface.h:138
+ + + +
TransportSend_t send
+
TransportRecv_t recv
+
NetworkContext_t * pNetworkContext
+
+
+
+ + + + diff --git a/latest/mqtt_agent_message_interface.html b/latest/mqtt_agent_message_interface.html new file mode 100644 index 00000000..1a72dd48 --- /dev/null +++ b/latest/mqtt_agent_message_interface.html @@ -0,0 +1,239 @@ + + + + + + + +coreMQTT Agent: Message Interface + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Message Interface
+
+
+

Messaging interface used by the MQTT Agent.
+
+

+

+Message Interface Overview

+

The message interface is a set of APIs to send MQTT Agent commands from application tasks to the MQTT agent task, as well as functions to allocate and release storage for these commands. It must be implemented with thread safety, as multiple tasks can send commands concurrently. The message interface is defined in core_mqtt_agent_message_interface.h.
+

+

The functions that must be implemented are:
+

+

The send and receive functions take in an opaque context MQTTAgentMessageContext_t. The functions above and the context are grouped together in the MQTTAgentMessageInterface_t structure:
+

typedef struct MQTTAgentMessageInterface
+
{
+ + + +
MQTTAgentCommandGet_t getCommand;
+
MQTTAgentCommandRelease_t releaseCommand;
+ +
MQTTAgentCommand_t *(* MQTTAgentCommandGet_t)(uint32_t blockTimeMs)
Obtain a MQTTAgentCommand_t structure.
Definition: core_mqtt_agent_message_interface.h:105
+
bool(* MQTTAgentMessageSend_t)(MQTTAgentMessageContext_t *pMsgCtx, MQTTAgentCommand_t *const *pCommandToSend, uint32_t blockTimeMs)
Send a message to the specified context. Must be thread safe.
Definition: core_mqtt_agent_message_interface.h:68
+
bool(* MQTTAgentCommandRelease_t)(MQTTAgentCommand_t *pCommandToRelease)
Give a MQTTAgentCommand_t structure back to the application.
Definition: core_mqtt_agent_message_interface.h:123
+
bool(* MQTTAgentMessageRecv_t)(MQTTAgentMessageContext_t *pMsgCtx, MQTTAgentCommand_t **pReceivedCommand, uint32_t blockTimeMs)
Receive a message from the specified context. Must be thread safe.
Definition: core_mqtt_agent_message_interface.h:84
+
struct MQTTAgentMessageContext MQTTAgentMessageContext_t
Context with which tasks may deliver messages to the agent.
Definition: core_mqtt_agent_message_interface.h:54
+
Function pointers and contexts used for sending and receiving commands, and allocating memory for the...
Definition: core_mqtt_agent_message_interface.h:133
+


+

+

+Implementing the Message Interface

+

The following steps give guidance on implementing the messaging interface:
+

+
    +
  1. Implementing MQTTAgentMessageContext_t
    +

    +
    typedef struct MQTTAgentMessageContext MQTTAgentMessageContext_t;
    +

    + MQTTAgentMessageContext_t is the incomplete type struct MQTTAgentMessageContext. The implemented struct MQTTAgentMessageContext must contain all of the information needed to send and receive commands with MQTTAgentMessageSend_t and MQTTAgentMessageRecv_t with thread safety. For example, this may be a handle to a thread safe queue, or a queue along with synchronization primitives. Commands are sent by pointer, so this structure should be able to relay pointers of type MQTTAgentCommand_t.
    +
    + Example code:
    struct MQTTAgentMessageContext
    +
    {
    +
    //Queue holding MQTTAgentCommand_t * pointers.
    +
    Queue_t queue;
    +
    };
    +

    +
  2. +
  3. Implementing MQTTAgentMessageSend_t
    +

    +
    typedef bool ( * MQTTAgentMessageSend_t )( MQTTAgentMessageContext_t * pMsgCtx,
    +
    MQTTAgentCommand_t * const * pCommandToSend,
    +
    uint32_t blockTimeMs );
    +

    + This function is expected to send the pointer that is pointed to by pCommandToSend using the message context. It will return true if the send was successful, else false.
    +
    + Example code:
    bool myMessageSendImplementation( MQTTAgentMessageContext_t * pMsgCtx,
    +
    MQTTAgentCommand_t * const * pCommandToSend,
    +
    uint32_t blockTimeMs )
    +
    {
    +
    int status = EXIT_FAILURE;
    +
    if( ( pMsgCtx != NULL ) && ( pCommandToSend != NULL ) )
    +
    {
    +
    //A function to send data to via pointer to a queue.
    +
    status = Queue_SendToBack( pMsgCtx->queue, pCommandToSend, blockTimeMs );
    +
    }
    +
    return ( status == EXIT_SUCCESS );
    +
    }
    +

    +
  4. +
  5. Implementing MQTTAgentMessageRecv_t
    +

    +
    typedef bool ( * MQTTAgentMessageRecv_t )( MQTTAgentMessageContext_t * pMsgCtx,
    +
    MQTTAgentCommand_t ** pReceivedCommand,
    +
    uint32_t blockTimeMs );
    +

    + This function is expected to receive a pointer that has been previously sent to the message context, and return in via the pReceivedCommand parameter. It will return true if the receive was successful, else false.
    +
    + Example code:
    bool myMessageRecvImplementation( MQTTAgentMessageContext_t * pMsgCtx,
    +
    MQTTAgentCommand_t ** pReceivedCommand,
    +
    uint32_t blockTimeMs )
    +
    {
    +
    int status = EXIT_FAILURE;
    +
    void * pReceivedPointer;
    +
    if( ( pMsgCtx != NULL ) && ( pCommandToSend != NULL ) )
    +
    {
    +
    //A function to receive data from a queue.
    +
    status = Queue_Recv( pMsgCtx->queue, &pReceivedPointer, blockTimeMs );
    +
    if( status == EXIT_SUCCESS )
    +
    {
    +
    *pReceivedCommand = ( MQTTAgentCommand_t * ) pReceivedPointer;
    +
    }
    +
    }
    +
    return ( status == EXIT_SUCCESS );
    +
    }
    +

    +
  6. +
  7. Implementing MQTTAgentCommandGet_t
    +

    +
    typedef MQTTAgentCommand_t * ( * MQTTAgentCommandGet_t )( uint32_t blockTimeMs );
    +

    + This function is expected to allocate storage for an MQTTAgentCommand_t struct. This function must be thread safe. It will return a pointer to the allocated command, or NULL if allocation failed.
    +
    + Example code:
    MQTTAgentCommand_t * myGetCommandImplementation( uint32_t blockTimeMs )
    +
    {
    +
    MQTTAgentCommand_t * ret = ( MQTTAgentCommand_t * ) malloc( sizeof( MQTTAgentCommand_t ) );
    +
    return ret;
    +
    }
    +

    +
  8. +
  9. Implementing MQTTAgentCommandRelease_t
    +

    +
    typedef bool ( * MQTTAgentCommandRelease_t )( MQTTAgentCommand_t * pCommandToRelease );
    +

    + This function will release a MQTTAgentCommand_t struct that had been allocated with MQTTAgentCommandGet_t. It will return a true if the command was release, else false.
    +
    + Example code:
    bool myReleaseCommandImplementation( MQTTAgentCommand_t * pCommandToRelease )
    +
    {
    +
    free( pCommandToRelease );
    +
    //free() does not have a return value.
    +
    return true;
    +
    }
    +

    +
  10. +
+
+
+
+ + + + diff --git a/latest/mqtt_agent_ping_function.html b/latest/mqtt_agent_ping_function.html new file mode 100644 index 00000000..ef772b2d --- /dev/null +++ b/latest/mqtt_agent_ping_function.html @@ -0,0 +1,160 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_Ping + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_Ping
+
+
+
MQTTStatus_t MQTTAgent_Ping( const MQTTAgentContext_t * pMqttAgentContext,
+
const MQTTAgentCommandInfo_t * pCommandInfo );
+
MQTTStatus_t MQTTAgent_Ping(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Ping() for an MQTT connection.
Definition: core_mqtt_agent.c:1323
+
MQTTStatus_t
+
Struct holding arguments that are common to every command.
Definition: core_mqtt_agent.h:189
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+

Add a command to call MQTT_Ping() for an MQTT connection.

+
Note
This API function ONLY enqueues a command to send a ping request to the server, and DOES NOT wait for a ping response to be received from the server. To detect whether a Ping Response, has not been received from the server, the MQTTAgent_CommandLoop function SHOULD be used, which returns the MQTTKeepAliveTimeout return code on a ping response (or keep-alive) timeout.
+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void pingRequestCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = pingRequestCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Ping( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command for sending request has been queued. Application can
+
// handle keep-alive timeout if detected through return value of
+
// MQTTAgent_CommandLoop in the task running the agent.
+
}
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
MQTTAgentCommandCallback_t cmdCompleteCallback
Callback to invoke upon completion.
Definition: core_mqtt_agent.h:190
+
uint32_t blockTimeMs
Maximum block time for enqueueing the command.
Definition: core_mqtt_agent.h:192
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+
+
+
+ + + + diff --git a/latest/mqtt_agent_publish_function.html b/latest/mqtt_agent_publish_function.html new file mode 100644 index 00000000..d38cd9cd --- /dev/null +++ b/latest/mqtt_agent_publish_function.html @@ -0,0 +1,176 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_Publish + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_Publish
+
+
+
+
MQTTPublishInfo_t * pPublishInfo,
+
const MQTTAgentCommandInfo_t * pCommandInfo );
+
MQTTStatus_t MQTTAgent_Publish(const MQTTAgentContext_t *pMqttAgentContext, MQTTPublishInfo_t *pPublishInfo, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Publish() for an MQTT connection.
Definition: core_mqtt_agent.c:1227
+
MQTTStatus_t
+
Struct holding arguments that are common to every command.
Definition: core_mqtt_agent.h:189
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+ +

Add a command to call MQTT_Publish() for an MQTT connection.

+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pPublishInfoMQTT PUBLISH information.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
MQTTPublishInfo_t publishInfo = { 0 };
+
+
// Function for command complete callback.
+
void publishCmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = publishCmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
// Fill the information for publish operation.
+
publishInfo.qos = MQTTQoS1;
+
publishInfo.pTopicName = "/some/topic/name";
+
publishInfo.topicNameLength = strlen( publishInfo.pTopicName );
+
publishInfo.pPayload = "Hello World!";
+
publishInfo.payloadLength = strlen( "Hello World!" );
+
+
status = MQTTAgent_Publish( &agentContext, &publishInfo, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to publish message to broker has been queued.
+
// The event of publish operation completion will be notified with
+
// the invocation of the publishCmdCompleteCb().
+
}
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
MQTTQoS1
+
MQTTAgentCommandCallback_t cmdCompleteCallback
Callback to invoke upon completion.
Definition: core_mqtt_agent.h:190
+
uint32_t blockTimeMs
Maximum block time for enqueueing the command.
Definition: core_mqtt_agent.h:192
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+ +
uint16_t topicNameLength
+ +
const char * pTopicName
+
const void * pPayload
+
+
+
+ + + + diff --git a/latest/mqtt_agent_resume_function.html b/latest/mqtt_agent_resume_function.html new file mode 100644 index 00000000..cdfb66a1 --- /dev/null +++ b/latest/mqtt_agent_resume_function.html @@ -0,0 +1,151 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_ResumeSession + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_ResumeSession
+
+
+
+
bool sessionPresent );
+
MQTTStatus_t MQTTAgent_ResumeSession(MQTTAgentContext_t *pMqttAgentContext, bool sessionPresent)
Resume a session by resending publishes if a session is present in the broker, or clear state informa...
Definition: core_mqtt_agent.c:1085
+
MQTTStatus_t
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+

Resume a session by resending publishes if a session is present in the broker, or clear state information if not.

+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]sessionPresentThe session present flag from the broker.
+
+
+
Note
This function is NOT thread-safe and should only be called from the context of the task responsible for MQTTAgent_CommandLoop.
+
Returns
MQTTSuccess if it succeeds in resending publishes, else an appropriate error code from MQTT_Publish()
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTAgentContext_t mqttAgentContext;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
bool sessionPresent;
+
+
// The example assumes that all variables have been filled with
+
// data for the MQTT_Connect call
+
// Refer to the MQTT_Connect API for a more detailed example.
+
+
// Attempt to resume session with the broker.
+
status = MQTT_Connect( &( mqttAgentContext.mqttContext ), &connectInfo, &willInfo, 100, &sessionPresent )
+
+
if( status == MQTTSuccess )
+
{
+
// Process the session present status sent by the broker.
+
status = MQTTAgent_ResumeSession( &mqttAgentContext, sessionPresent );
+
}
+
MQTTStatus_t MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
+
MQTTContext_t mqttContext
Definition: core_mqtt_agent.h:154
+ + +
+
+
+ + + + diff --git a/latest/mqtt_agent_subscribe_function.html b/latest/mqtt_agent_subscribe_function.html new file mode 100644 index 00000000..b370b31a --- /dev/null +++ b/latest/mqtt_agent_subscribe_function.html @@ -0,0 +1,176 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_Subscribe + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_Subscribe
+
+
+
+
MQTTAgentSubscribeArgs_t * pSubscriptionArgs,
+
const MQTTAgentCommandInfo_t * pCommandInfo );
+
MQTTStatus_t MQTTAgent_Subscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Subscribe() for an MQTT connection.
Definition: core_mqtt_agent.c:1177
+
MQTTStatus_t
+
Struct holding arguments that are common to every command.
Definition: core_mqtt_agent.h:189
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+
Struct holding arguments for a SUBSCRIBE or UNSUBSCRIBE call.
Definition: core_mqtt_agent.h:167
+

Add a command to call MQTT_Subscribe() for an MQTT connection.

+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pSubscriptionArgsStruct describing topic to subscribe to.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
MQTTSubscribeInfo_t subscribeInfo = { 0 };
+
MQTTAgentSubscribeArgs_t subscribeArgs = { 0 };
+
+
// Function for command complete callback.
+
void subscribeCmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.CmdCompleteCallback = subscribeCmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
// Fill the information for topic filters to subscribe to.
+
subscribeInfo.qos = Qos1;
+
subscribeInfo.pTopicFilter = "/foo/bar";
+
subscribeInfo.topicFilterLength = strlen("/foo/bar");
+
subscribeArgs.pSubscribeInfo = &subscribeInfo;
+
subscribeArgs.numSubscriptions = 1U;
+
+
status = MQTTAgent_Subscribe( &agentContext, &subscribeArgs, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to send subscribe request to the server has been queued. Notification
+
// about completion of the subscribe operation will be notified to application
+
// through invocation of subscribeCmdCompleteCb().
+
}
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
uint32_t blockTimeMs
Maximum block time for enqueueing the command.
Definition: core_mqtt_agent.h:192
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+
MQTTSubscribeInfo_t * pSubscribeInfo
List of MQTT subscriptions.
Definition: core_mqtt_agent.h:168
+
size_t numSubscriptions
Number of elements in pSubscribeInfo.
Definition: core_mqtt_agent.h:169
+ + +
uint16_t topicFilterLength
+
const char * pTopicFilter
+
+
+
+ + + + diff --git a/latest/mqtt_agent_terminate_function.html b/latest/mqtt_agent_terminate_function.html new file mode 100644 index 00000000..b72290d3 --- /dev/null +++ b/latest/mqtt_agent_terminate_function.html @@ -0,0 +1,161 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_Terminate + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_Terminate
+
+
+
+
const MQTTAgentCommandInfo_t * pCommandInfo );
+
MQTTStatus_t MQTTAgent_Terminate(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a termination command to the command queue.
Definition: core_mqtt_agent.c:1346
+
MQTTStatus_t
+
Struct holding arguments that are common to every command.
Definition: core_mqtt_agent.h:189
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+

Add a termination command to the command queue.

+

On command loop termination, all pending commands in the queue, as well as those waiting for an acknowledgment, will be terminated with error code MQTTRecvFailed.

+
Note
Commands may still be posted to the command queue after MQTTAgent_CommandLoop has returned. It is the responsibility of the application to cancel any commands that are posted while the command loop is not running, such as by invoking MQTTAgent_CancelAll.
+
+We RECOMMEND that this function is used from application task(s), that is a task not running the agent, to terminate the agent loop instead of calling MQTTAgent_Disconnect, so that the logic for creating and closing MQTT connection is owned by the agent task.
+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void terminateCallback( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = terminateCallback;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Terminate( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to terminate the agent loop has been queued.
+
}
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
MQTTAgentCommandCallback_t cmdCompleteCallback
Callback to invoke upon completion.
Definition: core_mqtt_agent.h:190
+
uint32_t blockTimeMs
Maximum block time for enqueueing the command.
Definition: core_mqtt_agent.h:192
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+
+
+
+ + + + diff --git a/latest/mqtt_agent_unsubscribe_function.html b/latest/mqtt_agent_unsubscribe_function.html new file mode 100644 index 00000000..e051e51c --- /dev/null +++ b/latest/mqtt_agent_unsubscribe_function.html @@ -0,0 +1,175 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_Unsubscribe + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_Unsubscribe
+
+
+
+
MQTTAgentSubscribeArgs_t * pSubscriptionArgs,
+
const MQTTAgentCommandInfo_t * pCommandInfo );
+
MQTTStatus_t MQTTAgent_Unsubscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Unsubscribe() for an MQTT connection.
Definition: core_mqtt_agent.c:1202
+
MQTTStatus_t
+
Struct holding arguments that are common to every command.
Definition: core_mqtt_agent.h:189
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+
Struct holding arguments for a SUBSCRIBE or UNSUBSCRIBE call.
Definition: core_mqtt_agent.h:167
+

Add a command to call MQTT_Unsubscribe() for an MQTT connection.

+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pSubscriptionArgsList of topics to unsubscribe from.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
MQTTSubscribeInfo_t unsubscribeInfo = { 0 };
+
MQTTAgentSubscribeArgs_t unsubscribeArgs = { 0 };
+
+
// Function for command complete callback.
+
void unsubscribeCmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = unsubscribeCmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
// Fill the information for topics to unsubscribe from.
+
unsubscribeInfo.pTopicFilter = "/foo/bar";
+
unsubscribeInfo.topicFilterLength = strlen("/foo/bar");
+
unsubscribeArgs.pSubscribeInfo = &unsubscribeInfo;
+
unsubscribeArgs.numSubscriptions = 1U;
+
+
status = MQTTAgent_Unsubscribe( &agentContext, &unsubscribeArgs, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to send Unsubscribe request to the server has been queued. Notification
+
// about completion of the Unsubscribe operation will be notified to application
+
// through invocation of unsubscribeCompleteCb().
+
}
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
MQTTAgentCommandCallback_t cmdCompleteCallback
Callback to invoke upon completion.
Definition: core_mqtt_agent.h:190
+
uint32_t blockTimeMs
Maximum block time for enqueueing the command.
Definition: core_mqtt_agent.h:192
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+
MQTTSubscribeInfo_t * pSubscribeInfo
List of MQTT subscriptions.
Definition: core_mqtt_agent.h:168
+
size_t numSubscriptions
Number of elements in pSubscribeInfo.
Definition: core_mqtt_agent.h:169
+ +
uint16_t topicFilterLength
+
const char * pTopicFilter
+
+
+
+ + + + diff --git a/latest/nav_f.png b/latest/nav_f.png new file mode 100644 index 0000000000000000000000000000000000000000..72a58a529ed3a9ed6aa0c51a79cf207e026deee2 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI`!2~2XGqLUlQVE_ejv*C{Z|{2ZH7M}7UYxc) zn!W8uqtnIQ>_z8U literal 0 HcmV?d00001 diff --git a/latest/nav_fd.png b/latest/nav_fd.png new file mode 100644 index 0000000000000000000000000000000000000000..032fbdd4c54f54fa9a2e6423b94ef4b2ebdfaceb GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI`!2~2XGqLUlQU#tajv*C{Z|C~*H7f|XvG1G8 zt7aS*L7xwMeS}!z6R#{C5tIw-s~AJ==F^i}x3XyJseHR@yF& zerFf(Zf;Dd{+(0lDIROL@Sj-Ju2JQ8&-n%4%q?>|^bShc&lR?}7HeMo@BDl5N(aHY Uj$gdr1MOz;boFyt=akR{0D!zeaR2}S literal 0 HcmV?d00001 diff --git a/latest/nav_g.png b/latest/nav_g.png new file mode 100644 index 0000000000000000000000000000000000000000..2093a237a94f6c83e19ec6e5fd42f7ddabdafa81 GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^j6lrB!3HFm1ilyoDK$?Q$B+ufw|5PB85lU25BhtE tr?otc=hd~V+ws&_A@j8Fiv!KF$B+ufw|5=67#uj90@pIL wZ=Q8~_Ju`#59=RjDrmm`tMD@M=!-l18IR?&vFVdQ&MBb@0HFXL6W-eg#Jd_@e6*DPn)w;=|1H}Zvm9l6xXXB%>yL=NQU;mg M>FVdQ&MBb@0Bdt1Qvd(} literal 0 HcmV?d00001 diff --git a/latest/navtree.css b/latest/navtree.css new file mode 100644 index 00000000..c8a7766a --- /dev/null +++ b/latest/navtree.css @@ -0,0 +1,150 @@ +#nav-tree .children_ul { + margin:0; + padding:4px; +} + +#nav-tree ul { + list-style:none outside none; + margin:0px; + padding:0px; +} + +#nav-tree li { + white-space:nowrap; + margin:0px; + padding:0px; +} + +#nav-tree .plus { + margin:0px; +} + +#nav-tree .selected { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + color: var(--nav-text-active-color); + text-shadow: var(--nav-text-active-shadow); +} + +#nav-tree .selected .arrow { + color: var(--nav-arrow-selected-color); + text-shadow: none; +} + +#nav-tree img { + margin:0px; + padding:0px; + border:0px; + vertical-align: middle; +} + +#nav-tree a { + text-decoration:none; + padding:0px; + margin:0px; + outline:none; +} + +#nav-tree .label { + margin:0px; + padding:0px; + font: 12px var(--font-family-nav); +} + +#nav-tree .label a { + padding:2px; +} + +#nav-tree .selected a { + text-decoration:none; + color:var(--nav-text-active-color); +} + +#nav-tree .children_ul { + margin:0px; + padding:0px; +} + +#nav-tree .item { + margin:0px; + padding:0px; +} + +#nav-tree { + padding: 0px 0px; + font-size:14px; + overflow:auto; +} + +#doc-content { + overflow:auto; + display:block; + padding:0px; + margin:0px; + -webkit-overflow-scrolling : touch; /* iOS 5+ */ +} + +#side-nav { + padding:0 6px 0 0; + margin: 0px; + display:block; + position: absolute; + left: 0px; + width: $width; + overflow : hidden; +} + +.ui-resizable .ui-resizable-handle { + display:block; +} + +.ui-resizable-e { + background-image:var(--nav-splitbar-image); + background-size:100%; + background-repeat:repeat-y; + background-attachment: scroll; + cursor:ew-resize; + height:100%; + right:0; + top:0; + width:6px; +} + +.ui-resizable-handle { + display:none; + font-size:0.1px; + position:absolute; + z-index:1; +} + +#nav-tree-contents { + margin: 6px 0px 0px 0px; +} + +#nav-tree { + background-repeat:repeat-x; + background-color: var(--nav-background-color); + -webkit-overflow-scrolling : touch; /* iOS 5+ */ +} + +#nav-sync { + position:absolute; + top:5px; + right:24px; + z-index:0; +} + +#nav-sync img { + opacity:0.3; +} + +#nav-sync img:hover { + opacity:0.9; +} + +@media print +{ + #nav-tree { display: none; } + div.ui-resizable-handle { display: none; position: relative; } +} + diff --git a/latest/navtree.js b/latest/navtree.js new file mode 100644 index 00000000..27983687 --- /dev/null +++ b/latest/navtree.js @@ -0,0 +1,549 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +var navTreeSubIndices = new Array(); +var arrowDown = '▼'; +var arrowRight = '►'; + +function getData(varName) +{ + var i = varName.lastIndexOf('/'); + var n = i>=0 ? varName.substring(i+1) : varName; + return eval(n.replace(/\-/g,'_')); +} + +function stripPath(uri) +{ + return uri.substring(uri.lastIndexOf('/')+1); +} + +function stripPath2(uri) +{ + var i = uri.lastIndexOf('/'); + var s = uri.substring(i+1); + var m = uri.substring(0,i+1).match(/\/d\w\/d\w\w\/$/); + return m ? uri.substring(i-6) : s; +} + +function hashValue() +{ + return $(location).attr('hash').substring(1).replace(/[^\w\-]/g,''); +} + +function hashUrl() +{ + return '#'+hashValue(); +} + +function pathName() +{ + return $(location).attr('pathname').replace(/[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]/g, ''); +} + +function localStorageSupported() +{ + try { + return 'localStorage' in window && window['localStorage'] !== null && window.localStorage.getItem; + } + catch(e) { + return false; + } +} + +function storeLink(link) +{ + if (!$("#nav-sync").hasClass('sync') && localStorageSupported()) { + window.localStorage.setItem('navpath',link); + } +} + +function deleteLink() +{ + if (localStorageSupported()) { + window.localStorage.setItem('navpath',''); + } +} + +function cachedLink() +{ + if (localStorageSupported()) { + return window.localStorage.getItem('navpath'); + } else { + return ''; + } +} + +function getScript(scriptName,func,show) +{ + var head = document.getElementsByTagName("head")[0]; + var script = document.createElement('script'); + script.id = scriptName; + script.type = 'text/javascript'; + script.onload = func; + script.src = scriptName+'.js'; + head.appendChild(script); +} + +function createIndent(o,domNode,node,level) +{ + var level=-1; + var n = node; + while (n.parentNode) { level++; n=n.parentNode; } + if (node.childrenData) { + var imgNode = document.createElement("span"); + imgNode.className = 'arrow'; + imgNode.style.paddingLeft=(16*level).toString()+'px'; + imgNode.innerHTML=arrowRight; + node.plus_img = imgNode; + node.expandToggle = document.createElement("a"); + node.expandToggle.href = "javascript:void(0)"; + node.expandToggle.onclick = function() { + if (node.expanded) { + $(node.getChildrenUL()).slideUp("fast"); + node.plus_img.innerHTML=arrowRight; + node.expanded = false; + } else { + expandNode(o, node, false, false); + } + } + node.expandToggle.appendChild(imgNode); + domNode.appendChild(node.expandToggle); + } else { + var span = document.createElement("span"); + span.className = 'arrow'; + span.style.width = 16*(level+1)+'px'; + span.innerHTML = ' '; + domNode.appendChild(span); + } +} + +var animationInProgress = false; + +function gotoAnchor(anchor,aname,updateLocation) +{ + var pos, docContent = $('#doc-content'); + var ancParent = $(anchor.parent()); + if (ancParent.hasClass('memItemLeft') || + ancParent.hasClass('memtitle') || + ancParent.hasClass('fieldname') || + ancParent.hasClass('fieldtype') || + ancParent.is(':header')) + { + pos = ancParent.position().top; + } else if (anchor.position()) { + pos = anchor.position().top; + } + if (pos) { + var dist = Math.abs(Math.min( + pos-docContent.offset().top, + docContent[0].scrollHeight- + docContent.height()-docContent.scrollTop())); + animationInProgress=true; + docContent.animate({ + scrollTop: pos + docContent.scrollTop() - docContent.offset().top + },Math.max(50,Math.min(500,dist)),function(){ + if (updateLocation) window.location.href=aname; + animationInProgress=false; + }); + } +} + +function newNode(o, po, text, link, childrenData, lastNode) +{ + var node = new Object(); + node.children = Array(); + node.childrenData = childrenData; + node.depth = po.depth + 1; + node.relpath = po.relpath; + node.isLast = lastNode; + + node.li = document.createElement("li"); + po.getChildrenUL().appendChild(node.li); + node.parentNode = po; + + node.itemDiv = document.createElement("div"); + node.itemDiv.className = "item"; + + node.labelSpan = document.createElement("span"); + node.labelSpan.className = "label"; + + createIndent(o,node.itemDiv,node,0); + node.itemDiv.appendChild(node.labelSpan); + node.li.appendChild(node.itemDiv); + + var a = document.createElement("a"); + node.labelSpan.appendChild(a); + node.label = document.createTextNode(text); + node.expanded = false; + a.appendChild(node.label); + if (link) { + var url; + if (link.substring(0,1)=='^') { + url = link.substring(1); + link = url; + } else { + url = node.relpath+link; + } + a.className = stripPath(link.replace('#',':')); + if (link.indexOf('#')!=-1) { + var aname = '#'+link.split('#')[1]; + var srcPage = stripPath(pathName()); + var targetPage = stripPath(link.split('#')[0]); + a.href = srcPage!=targetPage ? url : "javascript:void(0)"; + a.onclick = function(){ + storeLink(link); + if (!$(a).parent().parent().hasClass('selected')) + { + $('.item').removeClass('selected'); + $('.item').removeAttr('id'); + $(a).parent().parent().addClass('selected'); + $(a).parent().parent().attr('id','selected'); + } + var anchor = $(aname); + gotoAnchor(anchor,aname,true); + }; + } else { + a.href = url; + a.onclick = function() { storeLink(link); } + } + } else { + if (childrenData != null) + { + a.className = "nolink"; + a.href = "javascript:void(0)"; + a.onclick = node.expandToggle.onclick; + } + } + + node.childrenUL = null; + node.getChildrenUL = function() { + if (!node.childrenUL) { + node.childrenUL = document.createElement("ul"); + node.childrenUL.className = "children_ul"; + node.childrenUL.style.display = "none"; + node.li.appendChild(node.childrenUL); + } + return node.childrenUL; + }; + + return node; +} + +function showRoot() +{ + var headerHeight = $("#top").height(); + var footerHeight = $("#nav-path").height(); + var windowHeight = $(window).height() - headerHeight - footerHeight; + (function (){ // retry until we can scroll to the selected item + try { + var navtree=$('#nav-tree'); + navtree.scrollTo('#selected',100,{offset:-windowHeight/2}); + } catch (err) { + setTimeout(arguments.callee, 0); + } + })(); +} + +function expandNode(o, node, imm, showRoot) +{ + if (node.childrenData && !node.expanded) { + if (typeof(node.childrenData)==='string') { + var varName = node.childrenData; + getScript(node.relpath+varName,function(){ + node.childrenData = getData(varName); + expandNode(o, node, imm, showRoot); + }, showRoot); + } else { + if (!node.childrenVisited) { + getNode(o, node); + } + $(node.getChildrenUL()).slideDown("fast"); + node.plus_img.innerHTML = arrowDown; + node.expanded = true; + } + } +} + +function glowEffect(n,duration) +{ + n.addClass('glow').delay(duration).queue(function(next){ + $(this).removeClass('glow');next(); + }); +} + +function highlightAnchor() +{ + var aname = hashUrl(); + var anchor = $(aname); + if (anchor.parent().attr('class')=='memItemLeft'){ + var rows = $('.memberdecls tr[class$="'+hashValue()+'"]'); + glowEffect(rows.children(),300); // member without details + } else if (anchor.parent().attr('class')=='fieldname'){ + glowEffect(anchor.parent().parent(),1000); // enum value + } else if (anchor.parent().attr('class')=='fieldtype'){ + glowEffect(anchor.parent().parent(),1000); // struct field + } else if (anchor.parent().is(":header")) { + glowEffect(anchor.parent(),1000); // section header + } else { + glowEffect(anchor.next(),1000); // normal member + } +} + +function selectAndHighlight(hash,n) +{ + var a; + if (hash) { + var link=stripPath(pathName())+':'+hash.substring(1); + a=$('.item a[class$="'+link+'"]'); + } + if (a && a.length) { + a.parent().parent().addClass('selected'); + a.parent().parent().attr('id','selected'); + highlightAnchor(); + } else if (n) { + $(n.itemDiv).addClass('selected'); + $(n.itemDiv).attr('id','selected'); + } + var topOffset=5; + if (typeof page_layout!=='undefined' && page_layout==1) { + topOffset+=$('#top').outerHeight(); + } + if ($('#nav-tree-contents .item:first').hasClass('selected')) { + topOffset+=25; + } + $('#nav-sync').css('top',topOffset+'px'); + showRoot(); +} + +function showNode(o, node, index, hash) +{ + if (node && node.childrenData) { + if (typeof(node.childrenData)==='string') { + var varName = node.childrenData; + getScript(node.relpath+varName,function(){ + node.childrenData = getData(varName); + showNode(o,node,index,hash); + },true); + } else { + if (!node.childrenVisited) { + getNode(o, node); + } + $(node.getChildrenUL()).css({'display':'block'}); + node.plus_img.innerHTML = arrowDown; + node.expanded = true; + var n = node.children[o.breadcrumbs[index]]; + if (index+11) hash = '#'+parts[1].replace(/[^\w\-]/g,''); + else hash=''; + } + if (hash.match(/^#l\d+$/)) { + var anchor=$('a[name='+hash.substring(1)+']'); + glowEffect(anchor.parent(),1000); // line number + hash=''; // strip line number anchors + } + var url=root+hash; + var i=-1; + while (NAVTREEINDEX[i+1]<=url) i++; + if (i==-1) { i=0; root=NAVTREE[0][1]; } // fallback: show index + if (navTreeSubIndices[i]) { + gotoNode(o,i,root,hash,relpath) + } else { + getScript(relpath+'navtreeindex'+i,function(){ + navTreeSubIndices[i] = eval('NAVTREEINDEX'+i); + if (navTreeSubIndices[i]) { + gotoNode(o,i,root,hash,relpath); + } + },true); + } +} + +function showSyncOff(n,relpath) +{ + n.html(''); +} + +function showSyncOn(n,relpath) +{ + n.html(''); +} + +function toggleSyncButton(relpath) +{ + var navSync = $('#nav-sync'); + if (navSync.hasClass('sync')) { + navSync.removeClass('sync'); + showSyncOff(navSync,relpath); + storeLink(stripPath2(pathName())+hashUrl()); + } else { + navSync.addClass('sync'); + showSyncOn(navSync,relpath); + deleteLink(); + } +} + +var loadTriggered = false; +var readyTriggered = false; +var loadObject,loadToRoot,loadUrl,loadRelPath; + +$(window).on('load',function(){ + if (readyTriggered) { // ready first + navTo(loadObject,loadToRoot,loadUrl,loadRelPath); + showRoot(); + } + loadTriggered=true; +}); + +function initNavTree(toroot,relpath) +{ + var o = new Object(); + o.toroot = toroot; + o.node = new Object(); + o.node.li = document.getElementById("nav-tree-contents"); + o.node.childrenData = NAVTREE; + o.node.children = new Array(); + o.node.childrenUL = document.createElement("ul"); + o.node.getChildrenUL = function() { return o.node.childrenUL; }; + o.node.li.appendChild(o.node.childrenUL); + o.node.depth = 0; + o.node.relpath = relpath; + o.node.expanded = false; + o.node.isLast = true; + o.node.plus_img = document.createElement("span"); + o.node.plus_img.className = 'arrow'; + o.node.plus_img.innerHTML = arrowRight; + + if (localStorageSupported()) { + var navSync = $('#nav-sync'); + if (cachedLink()) { + showSyncOff(navSync,relpath); + navSync.removeClass('sync'); + } else { + showSyncOn(navSync,relpath); + } + navSync.click(function(){ toggleSyncButton(relpath); }); + } + + if (loadTriggered) { // load before ready + navTo(o,toroot,hashUrl(),relpath); + showRoot(); + } else { // ready before load + loadObject = o; + loadToRoot = toroot; + loadUrl = hashUrl(); + loadRelPath = relpath; + readyTriggered=true; + } + + $(window).bind('hashchange', function(){ + if (window.location.hash && window.location.hash.length>1){ + var a; + if ($(location).attr('hash')){ + var clslink=stripPath(pathName())+':'+hashValue(); + a=$('.item a[class$="'+clslink.replace(/1|%O$WD@{VPM$7~Ar*{o?;hlAFyLXmaDC0y znK1_#cQqJWPES%4Uujug^TE?jMft$}Eq^WaR~)%f)vSNs&gek&x%A9X9sM + + + + + + +coreMQTT Agent: Related Pages + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Related Pages
+
+
+
Here is a list of all related documentation pages:
+
[detail level 12]
+ + + + + + + + + + + + + + + +
 DesignArchitecture of the MQTT Agent library
 ConfigurationsConfigurations of the MQTT Agent
 FunctionsFunctions of the MQTT Agent library<br>
+
 MQTTAgent_Init
 MQTTAgent_CommandLoop
 MQTTAgent_ResumeSession
 MQTTAgent_CancelAll
 MQTTAgent_Publish
 MQTTAgent_Subscribe
 MQTTAgent_Unsubscribe
 MQTTAgent_Connect
 MQTTAgent_Disconnect
 MQTTAgent_Ping
 MQTTAgent_Terminate
 Message InterfaceMessaging interface used by the MQTT Agent.
+
+
+
+
+
+ + + + diff --git a/latest/resize.js b/latest/resize.js new file mode 100644 index 00000000..aaeb6fc0 --- /dev/null +++ b/latest/resize.js @@ -0,0 +1,155 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +var once=1; +function initResizable() +{ + var cookie_namespace = 'doxygen'; + var sidenav,navtree,content,header,barWidth=6,desktop_vp=768,titleHeight; + + function readSetting(cookie) + { + if (window.chrome) { + var val = localStorage.getItem(cookie_namespace+'_width'); + if (val) return val; + } else { + var myCookie = cookie_namespace+"_"+cookie+"="; + if (document.cookie) { + var index = document.cookie.indexOf(myCookie); + if (index != -1) { + var valStart = index + myCookie.length; + var valEnd = document.cookie.indexOf(";", valStart); + if (valEnd == -1) { + valEnd = document.cookie.length; + } + var val = document.cookie.substring(valStart, valEnd); + return val; + } + } + } + return 250; + } + + function writeSetting(cookie, val) + { + if (window.chrome) { + localStorage.setItem(cookie_namespace+"_width",val); + } else { + var date = new Date(); + date.setTime(date.getTime()+(10*365*24*60*60*1000)); // default expiration is one week + expiration = date.toGMTString(); + document.cookie = cookie_namespace + "_" + cookie + "=" + val + "; SameSite=Lax; expires=" + expiration+"; path=/"; + } + } + + function resizeWidth() + { + var windowWidth = $(window).width() + "px"; + var sidenavWidth = $(sidenav).outerWidth(); + content.css({marginLeft:parseInt(sidenavWidth)+"px"}); + if (typeof page_layout!=='undefined' && page_layout==1) { + footer.css({marginLeft:parseInt(sidenavWidth)+"px"}); + } + writeSetting('width',sidenavWidth-barWidth); + } + + function restoreWidth(navWidth) + { + var windowWidth = $(window).width() + "px"; + content.css({marginLeft:parseInt(navWidth)+barWidth+"px"}); + if (typeof page_layout!=='undefined' && page_layout==1) { + footer.css({marginLeft:parseInt(navWidth)+barWidth+"px"}); + } + sidenav.css({width:navWidth + "px"}); + } + + function resizeHeight() + { + var headerHeight = header.outerHeight(); + var footerHeight = footer.outerHeight(); + var windowHeight = $(window).height(); + var contentHeight,navtreeHeight,sideNavHeight; + if (typeof page_layout==='undefined' || page_layout==0) { /* DISABLE_INDEX=NO */ + contentHeight = windowHeight - headerHeight - footerHeight; + navtreeHeight = contentHeight; + sideNavHeight = contentHeight; + } else if (page_layout==1) { /* DISABLE_INDEX=YES */ + contentHeight = windowHeight - footerHeight; + navtreeHeight = windowHeight - headerHeight; + sideNavHeight = windowHeight; + } + content.css({height:contentHeight + "px"}); + navtree.css({height:navtreeHeight + "px"}); + sidenav.css({height:sideNavHeight + "px"}); + if (location.hash.slice(1)) { + (document.getElementById(location.hash.slice(1))||document.body).scrollIntoView(); + } + } + + function collapseExpand() + { + var newWidth; + if (sidenav.width()>0) { + newWidth=0; + } + else { + var width = readSetting('width'); + newWidth = (width>250 && width<$(window).width()) ? width : 250; + } + restoreWidth(newWidth); + var sidenavWidth = $(sidenav).outerWidth(); + writeSetting('width',sidenavWidth-barWidth); + } + + header = $("#top"); + sidenav = $("#side-nav"); + content = $("#doc-content"); + navtree = $("#nav-tree"); + footer = $("#nav-path"); + $(".side-nav-resizable").resizable({resize: function(e, ui) { resizeWidth(); } }); + $(sidenav).resizable({ minWidth: 0 }); + $(window).resize(function() { resizeHeight(); }); + var device = navigator.userAgent.toLowerCase(); + var touch_device = device.match(/(iphone|ipod|ipad|android)/); + if (touch_device) { /* wider split bar for touch only devices */ + $(sidenav).css({ paddingRight:'20px' }); + $('.ui-resizable-e').css({ width:'20px' }); + $('#nav-sync').css({ right:'34px' }); + barWidth=20; + } + var width = readSetting('width'); + if (width) { restoreWidth(width); } else { resizeWidth(); } + resizeHeight(); + var url = location.href; + var i=url.indexOf("#"); + if (i>=0) window.location.hash=url.substr(i); + var _preventDefault = function(evt) { evt.preventDefault(); }; + $("#splitbar").bind("dragstart", _preventDefault).bind("selectstart", _preventDefault); + if (once) { + $(".ui-resizable-handle").dblclick(collapseExpand); + once=0 + } + $(window).on('load',resizeHeight); +} +/* @license-end */ diff --git a/latest/search/all_0.js b/latest/search/all_0.js new file mode 100644 index 00000000..1f54c078 --- /dev/null +++ b/latest/search/all_0.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['addacknowledgment_0',['addAcknowledgment',['../struct_m_q_t_t_agent_command_func_returns__t.html#a474988426514661ae649a613b1dee051',1,'MQTTAgentCommandFuncReturns_t']]], + ['addawaitingoperation_1',['addAwaitingOperation',['../core__mqtt__agent_8c.html#ae70f7438de05ac589b4e48d4a2a7dd7b',1,'core_mqtt_agent.c']]], + ['addcommandtoqueue_2',['addCommandToQueue',['../core__mqtt__agent_8c.html#a38a109884abe76bd9e0b90d23b9d67b4',1,'core_mqtt_agent.c']]], + ['agentinterface_3',['agentInterface',['../struct_m_q_t_t_agent_context__t.html#ab89557b0a015d1848b8d6a9adbff8a4d',1,'MQTTAgentContext_t']]], + ['appcallback_4',['appCallback',['coreMQTT/struct_m_q_t_t_context__t.html#a73bd9259db9c3a9b84518cbf928ed91f',1,'MQTTContext_t']]] +]; diff --git a/latest/search/all_1.js b/latest/search/all_1.js new file mode 100644 index 00000000..57d8dac1 --- /dev/null +++ b/latest/search/all_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['basic_20types_0',['Basic Types',['coreMQTT/group__mqtt__basic__types.html',1,'']]], + ['blocktimems_1',['blockTimeMs',['../struct_m_q_t_t_agent_command_info__t.html#aa0f490187c1199c2d31d4c04a01d4637',1,'MQTTAgentCommandInfo_t']]] +]; diff --git a/latest/search/all_10.js b/latest/search/all_10.js new file mode 100644 index 00000000..bc9aab10 --- /dev/null +++ b/latest/search/all_10.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['recv_0',['recv',['coreMQTT/struct_transport_interface__t.html#a7c34e9b865e2a509306f09c7dfa3699e',1,'TransportInterface_t::recv()'],['../struct_m_q_t_t_agent_message_interface__t.html#a19e00e6431f53e595837d8ac7e4f744b',1,'MQTTAgentMessageInterface_t::recv()']]], + ['releasecommand_1',['releaseCommand',['../struct_m_q_t_t_agent_message_interface__t.html#ac809ba46da91df0fc4750ce515bf8f41',1,'MQTTAgentMessageInterface_t']]], + ['remaininglength_2',['remainingLength',['coreMQTT/struct_m_q_t_t_packet_info__t.html#a7c85becf08de0ec9776dd4be1fcc4bf8',1,'MQTTPacketInfo_t']]], + ['resendpublishes_3',['resendPublishes',['../core__mqtt__agent_8c.html#a0c7ea532d3da52d5c8ceb7493ce5fe36',1,'core_mqtt_agent.c']]], + ['retain_4',['retain',['coreMQTT/struct_m_q_t_t_publish_info__t.html#a343b0af89c46a900db4aa5c775a0975a',1,'MQTTPublishInfo_t']]], + ['returncode_5',['returnCode',['../struct_m_q_t_t_agent_return_info__t.html#ab04f05e53b8e9039f8983f68b032ccc8',1,'MQTTAgentReturnInfo_t']]], + ['runprocessloop_6',['runProcessLoop',['../struct_m_q_t_t_agent_command_func_returns__t.html#aae5a1d50a22df21950d586f5584e8994',1,'MQTTAgentCommandFuncReturns_t']]] +]; diff --git a/latest/search/all_11.js b/latest/search/all_11.js new file mode 100644 index 00000000..514a2f90 --- /dev/null +++ b/latest/search/all_11.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['send_0',['send',['coreMQTT/struct_transport_interface__t.html#a01cd9935e9a5266ca196243a0054d489',1,'TransportInterface_t::send()'],['../struct_m_q_t_t_agent_message_interface__t.html#abdc8e1c30aa27bf633f4f6e7da9a6465',1,'MQTTAgentMessageInterface_t::send()']]], + ['sessionpresent_1',['sessionPresent',['../struct_m_q_t_t_agent_connect_args__t.html#a01e3a80d5db4f5f89df44697cca1513f',1,'MQTTAgentConnectArgs_t']]], + ['size_2',['size',['coreMQTT/struct_m_q_t_t_fixed_buffer__t.html#a0b0b6a93cc62751ebeb03095d5431636',1,'MQTTFixedBuffer_t']]], + ['subscribe_3',['SUBSCRIBE',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33abc6f919ff681f5f552b2f7d1f0fba832',1,'core_mqtt_agent.h']]] +]; diff --git a/latest/search/all_12.js b/latest/search/all_12.js new file mode 100644 index 00000000..cbc808e9 --- /dev/null +++ b/latest/search/all_12.js @@ -0,0 +1,17 @@ +var searchData= +[ + ['terminate_0',['TERMINATE',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a9aab2d9eae3e9a84d9fed3f0cadd7e22',1,'core_mqtt_agent.h']]], + ['timeoutms_1',['timeoutMs',['../struct_m_q_t_t_agent_connect_args__t.html#a631a199abde2ad2b3e4c69cf211e4d54',1,'MQTTAgentConnectArgs_t']]], + ['timeouts_20in_20coremqtt_20library_2',['Timeouts in coreMQTT library',['coreMQTT/mqtt_timeouts.html',1,'']]], + ['topicfilterlength_3',['topicFilterLength',['coreMQTT/struct_m_q_t_t_subscribe_info__t.html#a6972f8e036f8bde9b1f23a2aacb61382',1,'MQTTSubscribeInfo_t']]], + ['topicnamelength_4',['topicNameLength',['coreMQTT/struct_m_q_t_t_publish_info__t.html#a6161c792d20cc7cf8284c1b71ea1145f',1,'MQTTPublishInfo_t']]], + ['transport_20interface_5',['Transport Interface',['coreMQTT/mqtt_transport_interface.html',1,'']]], + ['transport_5finterface_2eh_6',['transport_interface.h',['coreMQTT/transport__interface_8h.html',1,'']]], + ['transportinterface_7',['transportInterface',['coreMQTT/struct_m_q_t_t_context__t.html#a87ab9d61e7711325c2c85ce3ce63386a',1,'MQTTContext_t']]], + ['transportinterface_5ft_8',['TransportInterface_t',['coreMQTT/struct_transport_interface__t.html',1,'']]], + ['transportoutvector_5ft_9',['TransportOutVector_t',['coreMQTT/struct_transport_out_vector__t.html',1,'']]], + ['transportrecv_5ft_10',['TransportRecv_t',['coreMQTT/group__mqtt__callback__types.html#ga227df31d6daf07e5d833537c12130167',1,]]], + ['transportsend_5ft_11',['TransportSend_t',['coreMQTT/group__mqtt__callback__types.html#ga2a39853ff952edd715ab07b33ab2a7c5',1,]]], + ['transportwritev_5ft_12',['TransportWritev_t',['coreMQTT/group__mqtt__callback__types.html#ga47e779557b0c2db95949ef9526861dfb',1,]]], + ['type_13',['type',['coreMQTT/struct_m_q_t_t_packet_info__t.html#a7fef40548c1aa0f0e7f812a6a7243758',1,'MQTTPacketInfo_t']]] +]; diff --git a/latest/search/all_13.js b/latest/search/all_13.js new file mode 100644 index 00000000..06f23797 --- /dev/null +++ b/latest/search/all_13.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['unsubscribe_0',['UNSUBSCRIBE',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a8395e5981c15d813c588c86988fd4aea',1,'core_mqtt_agent.h']]], + ['usernamelength_1',['userNameLength',['coreMQTT/struct_m_q_t_t_connect_info__t.html#a7165be3bb06d4527ab4eb773b50e05e1',1,'MQTTConnectInfo_t']]] +]; diff --git a/latest/search/all_14.js b/latest/search/all_14.js new file mode 100644 index 00000000..8d1b51f7 --- /dev/null +++ b/latest/search/all_14.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['validateparams_0',['validateParams',['../core__mqtt__agent_8c.html#ac6b1b83accad3124122fed5c7ec14870',1,'core_mqtt_agent.c']]], + ['validatestruct_1',['validateStruct',['../core__mqtt__agent_8c.html#a77d4ec3f1e90897d6f173a2fcd7b9b61',1,'core_mqtt_agent.c']]] +]; diff --git a/latest/search/all_15.js b/latest/search/all_15.js new file mode 100644 index 00000000..1ab46090 --- /dev/null +++ b/latest/search/all_15.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['waitingforpingresp_0',['waitingForPingResp',['coreMQTT/struct_m_q_t_t_context__t.html#ac7073f43645f7b7c0c5b7763980004bb',1,'MQTTContext_t']]], + ['writev_1',['writev',['coreMQTT/struct_transport_interface__t.html#a8cf677fbeee53d270daa6dacfa138b79',1,'TransportInterface_t']]] +]; diff --git a/latest/search/all_2.js b/latest/search/all_2.js new file mode 100644 index 00000000..31ad8319 --- /dev/null +++ b/latest/search/all_2.js @@ -0,0 +1,31 @@ +var searchData= +[ + ['callback_20types_0',['Callback Types',['../group__mqtt__agent__callback__types.html',1,'(Global Namespace)'],['coreMQTT/group__mqtt__callback__types.html',1,'(Global Namespace)']]], + ['cleansession_1',['cleanSession',['coreMQTT/struct_m_q_t_t_connect_info__t.html#a606e7765c4f2215fb2bf630f6eb9ff6b',1,'MQTTConnectInfo_t']]], + ['clearpendingacknowledgments_2',['clearPendingAcknowledgments',['../core__mqtt__agent_8c.html#afb076dcf75919d5b638c33054b95461d',1,'core_mqtt_agent.c']]], + ['clientidentifierlength_3',['clientIdentifierLength',['coreMQTT/struct_m_q_t_t_connect_info__t.html#a8077ef36ab318f3d35bee6f098fa54d4',1,'MQTTConnectInfo_t']]], + ['cmdcompletecallback_4',['cmdCompleteCallback',['../struct_m_q_t_t_agent_command_info__t.html#a4c9e9b55c7b576a390f734238b60f3aa',1,'MQTTAgentCommandInfo_t']]], + ['commandtype_5',['commandType',['../struct_m_q_t_t_agent_command.html#ae810f32d3650badbe3f8a86d5754adf1',1,'MQTTAgentCommand']]], + ['concludecommand_6',['concludeCommand',['../core__mqtt__agent_8c.html#a848611250b309e0d84cb18a42fbf6391',1,'core_mqtt_agent.c']]], + ['configurations_7',['Configurations',['../core_mqtt_agent_config.html',1,'(Global Namespace)'],['coreMQTT/core_mqtt_config.html',1,'(Global Namespace)']]], + ['connect_8',['CONNECT',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a20391dd2915a0e64343d24c2f2e40b95',1,'core_mqtt_agent.h']]], + ['connectstatus_9',['connectStatus',['coreMQTT/struct_m_q_t_t_context__t.html#a4e38c4dc77e7751a0ad8730a41bee47f',1,'MQTTContext_t']]], + ['constants_10',['Constants',['coreMQTT/group__mqtt__constants.html',1,'']]], + ['controlpacketsent_11',['controlPacketSent',['coreMQTT/struct_m_q_t_t_context__t.html#af9724f2426132e3ce96a03892902ef89',1,'MQTTContext_t']]], + ['core_5fmqtt_2ec_12',['core_mqtt.c',['coreMQTT/core__mqtt_8c.html',1,'']]], + ['core_5fmqtt_2eh_13',['core_mqtt.h',['coreMQTT/core__mqtt_8h.html',1,'']]], + ['core_5fmqtt_5fagent_2ec_14',['core_mqtt_agent.c',['../core__mqtt__agent_8c.html',1,'']]], + ['core_5fmqtt_5fagent_2eh_15',['core_mqtt_agent.h',['../core__mqtt__agent_8h.html',1,'']]], + ['core_5fmqtt_5fagent_5fcommand_5ffunctions_2ec_16',['core_mqtt_agent_command_functions.c',['../core__mqtt__agent__command__functions_8c.html',1,'']]], + ['core_5fmqtt_5fagent_5fcommand_5ffunctions_2eh_17',['core_mqtt_agent_command_functions.h',['../core__mqtt__agent__command__functions_8h.html',1,'']]], + ['core_5fmqtt_5fagent_5fconfig_5fdefaults_2eh_18',['core_mqtt_agent_config_defaults.h',['../core__mqtt__agent__config__defaults_8h.html',1,'']]], + ['core_5fmqtt_5fagent_5fdefault_5flogging_2eh_19',['core_mqtt_agent_default_logging.h',['../core__mqtt__agent__default__logging_8h.html',1,'']]], + ['core_5fmqtt_5fagent_5fmessage_5finterface_2eh_20',['core_mqtt_agent_message_interface.h',['../core__mqtt__agent__message__interface_8h.html',1,'']]], + ['core_5fmqtt_5fconfig_5fdefaults_2eh_21',['core_mqtt_config_defaults.h',['coreMQTT/core__mqtt__config__defaults_8h.html',1,'']]], + ['core_5fmqtt_5fserializer_2ec_22',['core_mqtt_serializer.c',['coreMQTT/core__mqtt__serializer_8c.html',1,'']]], + ['core_5fmqtt_5fserializer_2eh_23',['core_mqtt_serializer.h',['coreMQTT/core__mqtt__serializer_8h.html',1,'']]], + ['core_5fmqtt_5fstate_2ec_24',['core_mqtt_state.c',['coreMQTT/core__mqtt__state_8c.html',1,'']]], + ['core_5fmqtt_5fstate_2eh_25',['core_mqtt_state.h',['coreMQTT/core__mqtt__state_8h.html',1,'']]], + ['createandaddcommand_26',['createAndAddCommand',['../core__mqtt__agent_8c.html#a594dbfd47f77c6988960110da3c25a2c',1,'core_mqtt_agent.c']]], + ['createcommand_27',['createCommand',['../core__mqtt__agent_8c.html#a4f2d34a65263b609595aa8f1705ff89f',1,'core_mqtt_agent.c']]] +]; diff --git a/latest/search/all_3.js b/latest/search/all_3.js new file mode 100644 index 00000000..d69965e6 --- /dev/null +++ b/latest/search/all_3.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['deserializationresult_0',['deserializationResult',['coreMQTT/struct_m_q_t_t_deserialized_info__t.html#a7df1b7b60404c9f1604fec0081d2625d',1,'MQTTDeserializedInfo_t']]], + ['design_1',['Design',['../mqtt_agent_design.html',1,'(Global Namespace)'],['coreMQTT/mqtt_design.html',1,'(Global Namespace)']]], + ['disconnect_2',['DISCONNECT',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a2f6318afb30e8e2817e6203ebedc8173',1,'core_mqtt_agent.h']]], + ['dup_3',['dup',['coreMQTT/struct_m_q_t_t_publish_info__t.html#aa1c8954e83bfa678d1ff5429679d4e89',1,'MQTTPublishInfo_t']]] +]; diff --git a/latest/search/all_4.js b/latest/search/all_4.js new file mode 100644 index 00000000..f9370c29 --- /dev/null +++ b/latest/search/all_4.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['endloop_0',['endLoop',['../struct_m_q_t_t_agent_command_func_returns__t.html#aea0742c902ee70380f308b7f957dc9a2',1,'MQTTAgentCommandFuncReturns_t']]], + ['enumerated_20types_1',['Enumerated Types',['../group__mqtt__agent__enum__types.html',1,'(Global Namespace)'],['coreMQTT/group__mqtt__enum__types.html',1,'(Global Namespace)']]] +]; diff --git a/latest/search/all_5.js b/latest/search/all_5.js new file mode 100644 index 00000000..5455fb0c --- /dev/null +++ b/latest/search/all_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['functions_0',['Functions',['../mqtt_agent_functions.html',1,'(Global Namespace)'],['coreMQTT/mqtt_functions.html',1,'(Global Namespace)']]] +]; diff --git a/latest/search/all_6.js b/latest/search/all_6.js new file mode 100644 index 00000000..778c0148 --- /dev/null +++ b/latest/search/all_6.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['getagentfrommqttcontext_0',['getAgentFromMQTTContext',['../core__mqtt__agent_8c.html#adb6cd05d1e6b270a021cb50980654707',1,'core_mqtt_agent.c']]], + ['getawaitingoperation_1',['getAwaitingOperation',['../core__mqtt__agent_8c.html#af4ab608204e853ab34bda491a47f6b84',1,'core_mqtt_agent.c']]], + ['getcommand_2',['getCommand',['../struct_m_q_t_t_agent_message_interface__t.html#aaa4d0614e8289d7ea12422e66c1e8689',1,'MQTTAgentMessageInterface_t']]], + ['gettime_3',['getTime',['coreMQTT/struct_m_q_t_t_context__t.html#aabe1d302a16771292151013e8e30c582',1,'MQTTContext_t']]] +]; diff --git a/latest/search/all_7.js b/latest/search/all_7.js new file mode 100644 index 00000000..fc41aafc --- /dev/null +++ b/latest/search/all_7.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['handleacks_0',['handleAcks',['../core__mqtt__agent_8c.html#ace2cab4efce97019ae5e12ccae2780cd',1,'core_mqtt_agent.c']]], + ['headerlength_1',['headerLength',['coreMQTT/struct_m_q_t_t_packet_info__t.html#aa7de1631ed8e08410942d36a72db558a',1,'MQTTPacketInfo_t']]] +]; diff --git a/latest/search/all_8.js b/latest/search/all_8.js new file mode 100644 index 00000000..9fcbff89 --- /dev/null +++ b/latest/search/all_8.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['incomingpublishrecordmaxcount_0',['incomingPublishRecordMaxCount',['coreMQTT/struct_m_q_t_t_context__t.html#aa33ed2e10380a854629f1386d0323ea8',1,'MQTTContext_t']]], + ['incomingpublishrecords_1',['incomingPublishRecords',['coreMQTT/struct_m_q_t_t_context__t.html#afc147663a5933de81212fa77057f0a4d',1,'MQTTContext_t']]], + ['index_2',['index',['coreMQTT/struct_m_q_t_t_context__t.html#a41b7735cd0746563483b72e17cf103aa',1,'MQTTContext_t']]], + ['iov_5fbase_3',['iov_base',['coreMQTT/struct_transport_out_vector__t.html#a0ffa5c06bf00006cbafa8e244951038d',1,'TransportOutVector_t']]], + ['iov_5flen_4',['iov_len',['coreMQTT/struct_transport_out_vector__t.html#ada73dafb2d34311f33fefad38603b35c',1,'TransportOutVector_t']]], + ['isspaceinpendingacklist_5',['isSpaceInPendingAckList',['../core__mqtt__agent_8c.html#a6082ea8cf8fe3f34e0a8de08d6980a29',1,'core_mqtt_agent.c']]] +]; diff --git a/latest/search/all_9.js b/latest/search/all_9.js new file mode 100644 index 00000000..86d59e93 --- /dev/null +++ b/latest/search/all_9.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['keepaliveintervalsec_0',['keepAliveIntervalSec',['coreMQTT/struct_m_q_t_t_context__t.html#afd6071827ef48b230212a5725c2075be',1,'MQTTContext_t']]], + ['keepaliveseconds_1',['keepAliveSeconds',['coreMQTT/struct_m_q_t_t_connect_info__t.html#a7d05d53261732ebdfbb9ee665a347591',1,'MQTTConnectInfo_t']]] +]; diff --git a/latest/search/all_a.js b/latest/search/all_a.js new file mode 100644 index 00000000..a8b24df3 --- /dev/null +++ b/latest/search/all_a.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['lastpacketrxtime_0',['lastPacketRxTime',['coreMQTT/struct_m_q_t_t_context__t.html#a7111ef16e4a4e75a72861f6f3ea8a7c3',1,'MQTTContext_t']]], + ['lastpackettxtime_1',['lastPacketTxTime',['coreMQTT/struct_m_q_t_t_context__t.html#a01acf90953e830ba3e7f44182cb1d482',1,'MQTTContext_t']]], + ['logdebug_2',['LogDebug',['../core__mqtt__agent__default__logging_8h.html#af60e8ffc327d136e5d0d8441ed98c98d',1,'core_mqtt_agent_default_logging.h']]], + ['logerror_3',['LogError',['../core__mqtt__agent__default__logging_8h.html#a8d9dbaaa88129137a4c68ba0456a18b1',1,'core_mqtt_agent_default_logging.h']]], + ['loginfo_4',['LogInfo',['../core__mqtt__agent__default__logging_8h.html#a00810b1cb9d2f25d25ce2d4d93815fba',1,'core_mqtt_agent_default_logging.h']]], + ['logwarn_5',['LogWarn',['../core__mqtt__agent__default__logging_8h.html#a7da92048aaf0cbfcacde9539c98a0e05',1,'core_mqtt_agent_default_logging.h']]] +]; diff --git a/latest/search/all_b.js b/latest/search/all_b.js new file mode 100644 index 00000000..37c075e9 --- /dev/null +++ b/latest/search/all_b.js @@ -0,0 +1,133 @@ +var searchData= +[ + ['message_20interface_0',['Message Interface',['../mqtt_agent_message_interface.html',1,'']]], + ['mqtt_5fagent_5fdo_5fnot_5fuse_5fcustom_5fconfig_1',['MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG',['../core__mqtt__agent__config__defaults_8h.html#aa10d2a7250bc5471633048ad4f238138',1,'core_mqtt_agent_config_defaults.h']]], + ['mqtt_5fagent_5ffunction_5ftable_2',['MQTT_AGENT_FUNCTION_TABLE',['../core__mqtt__agent__command__functions_8h.html#adf96732c68dea38cfc3b325639304bba',1,'core_mqtt_agent_command_functions.h']]], + ['mqtt_5fagent_5fmax_5fevent_5fqueue_5fwait_5ftime_3',['MQTT_AGENT_MAX_EVENT_QUEUE_WAIT_TIME',['../core__mqtt__agent__config__defaults_8h.html#a9fbd3d9f02a4cabb01e900cfa4d01980',1,'core_mqtt_agent_config_defaults.h']]], + ['mqtt_5fagent_5fmax_5foutstanding_5facks_4',['MQTT_AGENT_MAX_OUTSTANDING_ACKS',['../core__mqtt__agent__config__defaults_8h.html#afc749954a2c0c3a81bcf1e2eb5fecaad',1,'core_mqtt_agent_config_defaults.h']]], + ['mqtt_5fagent_5fuse_5fqos_5f1_5f2_5fpublish_5',['MQTT_AGENT_USE_QOS_1_2_PUBLISH',['../core__mqtt__agent__config__defaults_8h.html#af20d4b1937cbd282f193f69b1b27742e',1,'core_mqtt_agent_config_defaults.h']]], + ['mqtt_5fconnect_6',['MQTT_Connect',['coreMQTT/mqtt_connect_function.html',1,'']]], + ['mqtt_5fdeserializeack_7',['MQTT_DeserializeAck',['coreMQTT/mqtt_deserializeack_function.html',1,'']]], + ['mqtt_5fdeserializepublish_8',['MQTT_DeserializePublish',['coreMQTT/mqtt_deserializepublish_function.html',1,'']]], + ['mqtt_5fdisconnect_9',['MQTT_Disconnect',['coreMQTT/mqtt_disconnect_function.html',1,'']]], + ['mqtt_5fgetconnectpacketsize_10',['MQTT_GetConnectPacketSize',['coreMQTT/mqtt_getconnectpacketsize_function.html',1,'']]], + ['mqtt_5fgetdisconnectpacketsize_11',['MQTT_GetDisconnectPacketSize',['coreMQTT/mqtt_getdisconnectpacketsize_function.html',1,'']]], + ['mqtt_5fgetincomingpackettypeandlength_12',['MQTT_GetIncomingPacketTypeAndLength',['coreMQTT/mqtt_getincomingpackettypeandlength_function.html',1,'']]], + ['mqtt_5fgetpacketid_13',['MQTT_GetPacketId',['coreMQTT/mqtt_getpacketid_function.html',1,'']]], + ['mqtt_5fgetpingreqpacketsize_14',['MQTT_GetPingreqPacketSize',['coreMQTT/mqtt_getpingreqpacketsize_function.html',1,'']]], + ['mqtt_5fgetpublishpacketsize_15',['MQTT_GetPublishPacketSize',['coreMQTT/mqtt_getpublishpacketsize_function.html',1,'']]], + ['mqtt_5fgetsubackstatuscodes_16',['MQTT_GetSubAckStatusCodes',['coreMQTT/mqtt_getsubackstatuscodes_function.html',1,'']]], + ['mqtt_5fgetsubscribepacketsize_17',['MQTT_GetSubscribePacketSize',['coreMQTT/mqtt_getsubscribepacketsize_function.html',1,'']]], + ['mqtt_5fgetunsubscribepacketsize_18',['MQTT_GetUnsubscribePacketSize',['coreMQTT/mqtt_getunsubscribepacketsize_function.html',1,'']]], + ['mqtt_5finit_19',['MQTT_Init',['coreMQTT/mqtt_init_function.html',1,'']]], + ['mqtt_5fping_20',['MQTT_Ping',['coreMQTT/mqtt_ping_function.html',1,'']]], + ['mqtt_5fprocessloop_21',['MQTT_ProcessLoop',['coreMQTT/mqtt_processloop_function.html',1,'']]], + ['mqtt_5fpublish_22',['MQTT_Publish',['coreMQTT/mqtt_publish_function.html',1,'']]], + ['mqtt_5fpublishtoresend_23',['MQTT_PublishToResend',['coreMQTT/mqtt_publishtoresend_function.html',1,'']]], + ['mqtt_5freceiveloop_24',['MQTT_ReceiveLoop',['coreMQTT/mqtt_receiveloop_function.html',1,'']]], + ['mqtt_5fserializeack_25',['MQTT_SerializeAck',['coreMQTT/mqtt_serializeack_function.html',1,'']]], + ['mqtt_5fserializeconnect_26',['MQTT_SerializeConnect',['coreMQTT/mqtt_serializeconnect_function.html',1,'']]], + ['mqtt_5fserializedisconnect_27',['MQTT_SerializeDisconnect',['coreMQTT/mqtt_serializedisconnect_function.html',1,'']]], + ['mqtt_5fserializepingreq_28',['MQTT_SerializePingreq',['coreMQTT/mqtt_serializepingreq_function.html',1,'']]], + ['mqtt_5fserializepublish_29',['MQTT_SerializePublish',['coreMQTT/mqtt_serializepublish_function.html',1,'']]], + ['mqtt_5fserializepublishheader_30',['MQTT_SerializePublishHeader',['coreMQTT/mqtt_serializepublishheader_function.html',1,'']]], + ['mqtt_5fserializesubscribe_31',['MQTT_SerializeSubscribe',['coreMQTT/mqtt_serializesubscribe_function.html',1,'']]], + ['mqtt_5fserializeunsubscribe_32',['MQTT_SerializeUnsubscribe',['coreMQTT/mqtt_serializeunsubscribe_function.html',1,'']]], + ['mqtt_5fstatus_5fstrerror_33',['MQTT_Status_strerror',['coreMQTT/mqtt_status_strerror_function.html',1,'']]], + ['mqtt_5fsubscribe_34',['MQTT_Subscribe',['coreMQTT/mqtt_subscribe_function.html',1,'']]], + ['mqtt_5funsubscribe_35',['MQTT_Unsubscribe',['coreMQTT/mqtt_unsubscribe_function.html',1,'']]], + ['mqttagent_5fcancelall_36',['MQTTAgent_CancelAll',['../mqtt_agent_cancel_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8c.html#a0362d7d3d68628413f01b32ec2ff4ab6',1,'MQTTAgent_CancelAll(MQTTAgentContext_t *pMqttAgentContext): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#a0362d7d3d68628413f01b32ec2ff4ab6',1,'MQTTAgent_CancelAll(MQTTAgentContext_t *pMqttAgentContext): core_mqtt_agent.c']]], + ['mqttagent_5fcommandloop_37',['MQTTAgent_CommandLoop',['../mqtt_agent_command_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8c.html#a9dafeb1701b1a0ee897b626a09cfcff7',1,'MQTTAgent_CommandLoop(MQTTAgentContext_t *pMqttAgentContext): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#a9dafeb1701b1a0ee897b626a09cfcff7',1,'MQTTAgent_CommandLoop(MQTTAgentContext_t *pMqttAgentContext): core_mqtt_agent.c']]], + ['mqttagent_5fconnect_38',['MQTTAgent_Connect',['../mqtt_agent_connect_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8c.html#a782425e50d258837d23e379471254412',1,'MQTTAgent_Connect(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentConnectArgs_t *pConnectArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#a782425e50d258837d23e379471254412',1,'MQTTAgent_Connect(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentConnectArgs_t *pConnectArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5fdisconnect_39',['MQTTAgent_Disconnect',['../mqtt_agent_disconnect_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8h.html#a26687b9b762b5f52b14387bacdf17224',1,'MQTTAgent_Disconnect(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#a26687b9b762b5f52b14387bacdf17224',1,'MQTTAgent_Disconnect(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5finit_40',['MQTTAgent_Init',['../mqtt_agent_init_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8h.html#a584863528e72229f35003485f7ee0edd',1,'MQTTAgent_Init(MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentMessageInterface_t *pMsgInterface, const MQTTFixedBuffer_t *pNetworkBuffer, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getCurrentTimeMs, MQTTAgentIncomingPublishCallback_t incomingCallback, void *pIncomingPacketContext): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#a584863528e72229f35003485f7ee0edd',1,'MQTTAgent_Init(MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentMessageInterface_t *pMsgInterface, const MQTTFixedBuffer_t *pNetworkBuffer, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getCurrentTimeMs, MQTTAgentIncomingPublishCallback_t incomingCallback, void *pIncomingPacketContext): core_mqtt_agent.c']]], + ['mqttagent_5fping_41',['MQTTAgent_Ping',['../mqtt_agent_ping_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8c.html#ae260e29f31d51953cbab2e1437f645ed',1,'MQTTAgent_Ping(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#ae260e29f31d51953cbab2e1437f645ed',1,'MQTTAgent_Ping(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5fprocessloop_42',['MQTTAgent_ProcessLoop',['../core__mqtt__agent_8c.html#aa14c9c86e036d0b1f5c04a538597cc46',1,'MQTTAgent_ProcessLoop(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#aa14c9c86e036d0b1f5c04a538597cc46',1,'MQTTAgent_ProcessLoop(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5fpublish_43',['MQTTAgent_Publish',['../mqtt_agent_publish_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8c.html#afea2405ab859324cb241ea47e6a5ab81',1,'MQTTAgent_Publish(const MQTTAgentContext_t *pMqttAgentContext, MQTTPublishInfo_t *pPublishInfo, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#afea2405ab859324cb241ea47e6a5ab81',1,'MQTTAgent_Publish(const MQTTAgentContext_t *pMqttAgentContext, MQTTPublishInfo_t *pPublishInfo, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5fresumesession_44',['MQTTAgent_ResumeSession',['../mqtt_agent_resume_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8c.html#a75065d6bff5f2d32831f2c74922296fb',1,'MQTTAgent_ResumeSession(MQTTAgentContext_t *pMqttAgentContext, bool sessionPresent): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#a75065d6bff5f2d32831f2c74922296fb',1,'MQTTAgent_ResumeSession(MQTTAgentContext_t *pMqttAgentContext, bool sessionPresent): core_mqtt_agent.c']]], + ['mqttagent_5fsubscribe_45',['MQTTAgent_Subscribe',['../mqtt_agent_subscribe_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8c.html#a651cf10182392ecea5e8609af8855d49',1,'MQTTAgent_Subscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#a651cf10182392ecea5e8609af8855d49',1,'MQTTAgent_Subscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5fterminate_46',['MQTTAgent_Terminate',['../mqtt_agent_terminate_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8c.html#ae1b19c10831f72251603b045f2608313',1,'MQTTAgent_Terminate(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#ae1b19c10831f72251603b045f2608313',1,'MQTTAgent_Terminate(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5funsubscribe_47',['MQTTAgent_Unsubscribe',['../mqtt_agent_unsubscribe_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8h.html#ac3f70c81c8f8947dfb7346045c8edb63',1,'MQTTAgent_Unsubscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#ac3f70c81c8f8947dfb7346045c8edb63',1,'MQTTAgent_Unsubscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagentackinfo_5ft_48',['MQTTAgentAckInfo_t',['../struct_m_q_t_t_agent_ack_info__t.html',1,'']]], + ['mqttagentcommand_49',['MQTTAgentCommand',['../struct_m_q_t_t_agent_command.html',1,'']]], + ['mqttagentcommand_5fconnect_50',['MQTTAgentCommand_Connect',['../core__mqtt__agent__command__functions_8h.html#abe89d0e3cf7ddd095a3c840df4955a9e',1,'MQTTAgentCommand_Connect(MQTTAgentContext_t *pMqttAgentContext, void *pVoidConnectArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#abe89d0e3cf7ddd095a3c840df4955a9e',1,'MQTTAgentCommand_Connect(MQTTAgentContext_t *pMqttAgentContext, void *pVoidConnectArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fdisconnect_51',['MQTTAgentCommand_Disconnect',['../core__mqtt__agent__command__functions_8h.html#aa7507c7a01cdc06af0d5f42711357b6e',1,'MQTTAgentCommand_Disconnect(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#aa7507c7a01cdc06af0d5f42711357b6e',1,'MQTTAgentCommand_Disconnect(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fping_52',['MQTTAgentCommand_Ping',['../core__mqtt__agent__command__functions_8h.html#a9840f5683a5e513b99ab15961e17e42b',1,'MQTTAgentCommand_Ping(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#a9840f5683a5e513b99ab15961e17e42b',1,'MQTTAgentCommand_Ping(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fprocessloop_53',['MQTTAgentCommand_ProcessLoop',['../core__mqtt__agent__command__functions_8c.html#ae2a8b7caae9b06f36f9784663c8f8a49',1,'MQTTAgentCommand_ProcessLoop(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8h.html#ae2a8b7caae9b06f36f9784663c8f8a49',1,'MQTTAgentCommand_ProcessLoop(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fpublish_54',['MQTTAgentCommand_Publish',['../core__mqtt__agent__command__functions_8c.html#a5b4be57b6b6a55054e94850c805fd943',1,'MQTTAgentCommand_Publish(MQTTAgentContext_t *pMqttAgentContext, void *pPublishArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8h.html#a5b4be57b6b6a55054e94850c805fd943',1,'MQTTAgentCommand_Publish(MQTTAgentContext_t *pMqttAgentContext, void *pPublishArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fsubscribe_55',['MQTTAgentCommand_Subscribe',['../core__mqtt__agent__command__functions_8c.html#accbd434285c7cd823270614513ecd4a0',1,'MQTTAgentCommand_Subscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8h.html#accbd434285c7cd823270614513ecd4a0',1,'MQTTAgentCommand_Subscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fterminate_56',['MQTTAgentCommand_Terminate',['../core__mqtt__agent__command__functions_8c.html#aa017a4f5741920140688973e4b8bf0f1',1,'MQTTAgentCommand_Terminate(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8h.html#aa017a4f5741920140688973e4b8bf0f1',1,'MQTTAgentCommand_Terminate(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5funsubscribe_57',['MQTTAgentCommand_Unsubscribe',['../core__mqtt__agent__command__functions_8h.html#aea9ea15866e2e7940469d9a200b45362',1,'MQTTAgentCommand_Unsubscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#aea9ea15866e2e7940469d9a200b45362',1,'MQTTAgentCommand_Unsubscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommandcallback_5ft_58',['MQTTAgentCommandCallback_t',['../group__mqtt__agent__callback__types.html#gaa2497c28b3fb55b8dc38b0873f749eef',1,'core_mqtt_agent.h']]], + ['mqttagentcommandcontext_5ft_59',['MQTTAgentCommandContext_t',['../group__mqtt__agent__struct__types.html#ga953da1618097a29381f3fc38f576055c',1,'core_mqtt_agent.h']]], + ['mqttagentcommandfunc_5ft_60',['MQTTAgentCommandFunc_t',['../core__mqtt__agent__command__functions_8h.html#af1595d37e917f7e6f336bc866d00e37d',1,'core_mqtt_agent_command_functions.h']]], + ['mqttagentcommandfuncreturns_5ft_61',['MQTTAgentCommandFuncReturns_t',['../struct_m_q_t_t_agent_command_func_returns__t.html',1,'']]], + ['mqttagentcommandget_5ft_62',['MQTTAgentCommandGet_t',['../core__mqtt__agent__message__interface_8h.html#a2d52058b819a1a4e813b8f37cbdda5a2',1,'core_mqtt_agent_message_interface.h']]], + ['mqttagentcommandinfo_5ft_63',['MQTTAgentCommandInfo_t',['../struct_m_q_t_t_agent_command_info__t.html',1,'']]], + ['mqttagentcommandrelease_5ft_64',['MQTTAgentCommandRelease_t',['../core__mqtt__agent__message__interface_8h.html#a95a4a0f7d915b957f7fc986874f954f9',1,'core_mqtt_agent_message_interface.h']]], + ['mqttagentcommandtype_5ft_65',['MQTTAgentCommandType_t',['../group__mqtt__agent__enum__types.html#ga76604fa58b7ee6c32ba084fda9379f33',1,'core_mqtt_agent.h']]], + ['mqttagentconnectargs_5ft_66',['MQTTAgentConnectArgs_t',['../struct_m_q_t_t_agent_connect_args__t.html',1,'']]], + ['mqttagentcontext_5ft_67',['MQTTAgentContext_t',['../struct_m_q_t_t_agent_context__t.html',1,'']]], + ['mqttagentincomingpublishcallback_5ft_68',['MQTTAgentIncomingPublishCallback_t',['../group__mqtt__agent__callback__types.html#gacdfb8687b1217d321e7cc58e365ec6a1',1,'core_mqtt_agent.h']]], + ['mqttagentmessagecontext_5ft_69',['MQTTAgentMessageContext_t',['../group__mqtt__agent__struct__types.html#ga3c47f2ebcec2e1150e40d039639e5a3b',1,'core_mqtt_agent_message_interface.h']]], + ['mqttagentmessageinterface_5ft_70',['MQTTAgentMessageInterface_t',['../struct_m_q_t_t_agent_message_interface__t.html',1,'']]], + ['mqttagentmessagerecv_5ft_71',['MQTTAgentMessageRecv_t',['../core__mqtt__agent__message__interface_8h.html#aafd35ead1877c1235d407d4e487f1a0a',1,'core_mqtt_agent_message_interface.h']]], + ['mqttagentmessagesend_5ft_72',['MQTTAgentMessageSend_t',['../core__mqtt__agent__message__interface_8h.html#a4cdea15a0c979080b1a83f0753d82e8c',1,'core_mqtt_agent_message_interface.h']]], + ['mqttagentreturninfo_5ft_73',['MQTTAgentReturnInfo_t',['../struct_m_q_t_t_agent_return_info__t.html',1,'']]], + ['mqttagentsubscribeargs_5ft_74',['MQTTAgentSubscribeArgs_t',['../struct_m_q_t_t_agent_subscribe_args__t.html',1,'']]], + ['mqttbadparameter_75',['MQTTBadParameter',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa39030c93b0263b2699502a074f003b5',1,]]], + ['mqttbadresponse_76',['MQTTBadResponse',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa5d7507e7664a14d63a8bc44b280093e',1,]]], + ['mqttconnected_77',['MQTTConnected',['coreMQTT/group__mqtt__enum__types.html#gga9f84d003695205cf10a7bd0bafb3dbf6a82c8f64d976734e5632e5257bc429ef5',1,]]], + ['mqttconnectinfo_5ft_78',['MQTTConnectInfo_t',['coreMQTT/struct_m_q_t_t_connect_info__t.html',1,'']]], + ['mqttconnectionstatus_5ft_79',['MQTTConnectionStatus_t',['coreMQTT/group__mqtt__enum__types.html#ga9f84d003695205cf10a7bd0bafb3dbf6',1,]]], + ['mqttcontext_80',['mqttContext',['../struct_m_q_t_t_agent_context__t.html#aec01b2b61213956dc2219f620964a055',1,'MQTTAgentContext_t']]], + ['mqttcontext_5ft_81',['MQTTContext_t',['coreMQTT/struct_m_q_t_t_context__t.html',1,'']]], + ['mqttdeserializedinfo_5ft_82',['MQTTDeserializedInfo_t',['coreMQTT/struct_m_q_t_t_deserialized_info__t.html',1,'']]], + ['mqtteventcallback_83',['mqttEventCallback',['../core__mqtt__agent_8c.html#a4aeca55423966c3eff1734316f6a7466',1,'core_mqtt_agent.c']]], + ['mqtteventcallback_5ft_84',['MQTTEventCallback_t',['coreMQTT/group__mqtt__callback__types.html#ga00d348277ed4fde23c95bfc749ae954a',1,]]], + ['mqttfixedbuffer_5ft_85',['MQTTFixedBuffer_t',['coreMQTT/struct_m_q_t_t_fixed_buffer__t.html',1,'']]], + ['mqttgetcurrenttimefunc_5ft_86',['MQTTGetCurrentTimeFunc_t',['coreMQTT/group__mqtt__callback__types.html#gae3bea55b0e49e5208b8c5709a5ea23aa',1,]]], + ['mqttillegalstate_87',['MQTTIllegalState',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca67905d7a05f98faa557a73eb5092bd8f',1,]]], + ['mqttkeepalivetimeout_88',['MQTTKeepAliveTimeout',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca076ca8965e836a06e707a94adb26144f',1,]]], + ['mqttneedmorebytes_89',['MQTTNeedMoreBytes',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa97df53014d919df5ecd54398f89f9b9',1,]]], + ['mqttnodataavailable_90',['MQTTNoDataAvailable',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca676f21c0ddf297ae3ec874bc829aa957',1,]]], + ['mqttnomemory_91',['MQTTNoMemory',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735cab1be4db832a0468f024243bca151a8df',1,]]], + ['mqttnotconnected_92',['MQTTNotConnected',['coreMQTT/group__mqtt__enum__types.html#gga9f84d003695205cf10a7bd0bafb3dbf6a0320177ebf1f1b2e24646b44702cec69',1,]]], + ['mqttpacketinfo_5ft_93',['MQTTPacketInfo_t',['coreMQTT/struct_m_q_t_t_packet_info__t.html',1,'']]], + ['mqttpuback_94',['MQTTPuback',['coreMQTT/group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a53d5939c680962f37c15ee87ffd63d0f',1,]]], + ['mqttpubackinfo_5ft_95',['MQTTPubAckInfo_t',['coreMQTT/struct_m_q_t_t_pub_ack_info__t.html',1,'']]], + ['mqttpubackpending_96',['MQTTPubAckPending',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94ab086c55acf106cdc8d420f90899b6803',1,]]], + ['mqttpubacksend_97',['MQTTPubAckSend',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a65f6f7b343a30fc0558e3aeeb8c97f35',1,]]], + ['mqttpubacktype_5ft_98',['MQTTPubAckType_t',['coreMQTT/group__mqtt__enum__types.html#ga8c1bee959b3ed5fab2a2688dd72bf237',1,]]], + ['mqttpubcomp_99',['MQTTPubcomp',['coreMQTT/group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a910c34311ad6a2341afc04839e1c13bd',1,]]], + ['mqttpubcomppending_100',['MQTTPubCompPending',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a3281a28d1829d954b596f091b547b627',1,]]], + ['mqttpubcompsend_101',['MQTTPubCompSend',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a7d88904d550b502b4424a41aa4205e56',1,]]], + ['mqttpublishdone_102',['MQTTPublishDone',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94ad07733793a235ef9a6a04d16637cd7dc',1,]]], + ['mqttpublishinfo_5ft_103',['MQTTPublishInfo_t',['coreMQTT/struct_m_q_t_t_publish_info__t.html',1,'']]], + ['mqttpublishsend_104',['MQTTPublishSend',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a896b1507647b504c9208580e4cde26ad',1,]]], + ['mqttpublishstate_5ft_105',['MQTTPublishState_t',['coreMQTT/group__mqtt__enum__types.html#ga0480de7552eedd739a26a23fa8e6fd94',1,]]], + ['mqttpubrec_106',['MQTTPubrec',['coreMQTT/group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a8c98d5d1a68dda33d9039009ab4ef053',1,]]], + ['mqttpubrecpending_107',['MQTTPubRecPending',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a1bea59454700be9b683b7eb8aaf6bb4f',1,]]], + ['mqttpubrecsend_108',['MQTTPubRecSend',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a11e2319a2b25b82121471743d39761e1',1,]]], + ['mqttpubrel_109',['MQTTPubrel',['coreMQTT/group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237af2d737088a231c88e7603acfdbc4fc8c',1,]]], + ['mqttpubrelpending_110',['MQTTPubRelPending',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a695431cde1dc9dc5a2dcbd10eba49df2',1,]]], + ['mqttpubrelsend_111',['MQTTPubRelSend',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a5d2ee2709c6dc7a1eb8b9c40f318909b',1,]]], + ['mqttqos0_112',['MQTTQoS0',['coreMQTT/group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aaad51b23a1ae1417f96d8f343c788d1d2',1,]]], + ['mqttqos1_113',['MQTTQoS1',['coreMQTT/group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aa019d0b8a8cfadb6f98462b046bdacbb2',1,]]], + ['mqttqos2_114',['MQTTQoS2',['coreMQTT/group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aa85e04ac0465cbdef6dd69ff71b2bbfbb',1,]]], + ['mqttqos_5ft_115',['MQTTQoS_t',['coreMQTT/group__mqtt__enum__types.html#gae308a5928d7f537379c29a894228093a',1,]]], + ['mqttrecvfailed_116',['MQTTRecvFailed',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa14bc8aa4ad218702d782366945d43ac',1,]]], + ['mqttsendfailed_117',['MQTTSendFailed',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735cafd06b63fe9677fa2af06b0f4c7d4ad55',1,]]], + ['mqttserverrefused_118',['MQTTServerRefused',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca25a3d1747e308e99daa805fe576f84b9',1,]]], + ['mqttstatecollision_119',['MQTTStateCollision',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca8d05b92240dea6df08eab5a9e3799c11',1,]]], + ['mqttstatecursor_5ft_120',['MQTTStateCursor_t',['coreMQTT/group__mqtt__basic__types.html#ga2ca7d486d83fe555953a8c7876ee0d6e',1,]]], + ['mqttstatenull_121',['MQTTStateNull',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a8349567b7a9efb3913a64a8f4f6fe5c9',1,]]], + ['mqttstatus_5ft_122',['MQTTStatus_t',['coreMQTT/group__mqtt__enum__types.html#gaba7ec045874a1c3432f99173367f735c',1,]]], + ['mqttsubackfailure_123',['MQTTSubAckFailure',['coreMQTT/group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611aeb83b20da8eda934cde6b92db225a808',1,]]], + ['mqttsubackstatus_5ft_124',['MQTTSubAckStatus_t',['coreMQTT/group__mqtt__enum__types.html#ga48dabc1579e3c0ac6058ce9068054611',1,]]], + ['mqttsubacksuccessqos0_125',['MQTTSubAckSuccessQos0',['coreMQTT/group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611abcc3040d7d53025baee3542c40758abb',1,]]], + ['mqttsubacksuccessqos1_126',['MQTTSubAckSuccessQos1',['coreMQTT/group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611ab180361a6da712c8144d8c499537787d',1,]]], + ['mqttsubacksuccessqos2_127',['MQTTSubAckSuccessQos2',['coreMQTT/group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611a877b2afbc6ec7d9ab57d4862caadf4f1',1,]]], + ['mqttsubscribeinfo_5ft_128',['MQTTSubscribeInfo_t',['coreMQTT/struct_m_q_t_t_subscribe_info__t.html',1,'']]], + ['mqttsuccess_129',['MQTTSuccess',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca484e062cb4f3fccc1858dd25cfeee056',1,]]] +]; diff --git a/latest/search/all_c.js b/latest/search/all_c.js new file mode 100644 index 00000000..e459c420 --- /dev/null +++ b/latest/search/all_c.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['networkbuffer_0',['networkBuffer',['coreMQTT/struct_m_q_t_t_context__t.html#a231c5576a6ce389317a3f00f95628276',1,'MQTTContext_t']]], + ['networkcontext_5ft_1',['NetworkContext_t',['coreMQTT/group__mqtt__struct__types.html#ga7769e434e7811caed8cd6fd7f9ec26ec',1,]]], + ['nextpacketid_2',['nextPacketId',['coreMQTT/struct_m_q_t_t_context__t.html#af47ed55ad7e9bb112324f5f209b70534',1,'MQTTContext_t']]], + ['none_3',['NONE',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33ac157bdf0b85a40d2619cbc8bc1ae5fe2',1,'core_mqtt_agent.h']]], + ['num_5fcommands_4',['NUM_COMMANDS',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a158760c3c33699acd8723f4c983822a6',1,'core_mqtt_agent.h']]], + ['numsubscriptions_5',['numSubscriptions',['../struct_m_q_t_t_agent_subscribe_args__t.html#ae30aaa33e7a0e67a5989c2d15170de95',1,'MQTTAgentSubscribeArgs_t']]] +]; diff --git a/latest/search/all_d.js b/latest/search/all_d.js new file mode 100644 index 00000000..85291b91 --- /dev/null +++ b/latest/search/all_d.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['outgoingpublishrecordmaxcount_0',['outgoingPublishRecordMaxCount',['coreMQTT/struct_m_q_t_t_context__t.html#a2851073e252d1e744596272ef13dd14a',1,'MQTTContext_t']]], + ['outgoingpublishrecords_1',['outgoingPublishRecords',['coreMQTT/struct_m_q_t_t_context__t.html#a4ea1e37e0e81f010fbf84365ac2ef6de',1,'MQTTContext_t']]], + ['overview_2',['Overview',['../index.html',1,'']]] +]; diff --git a/latest/search/all_e.js b/latest/search/all_e.js new file mode 100644 index 00000000..8acbcf86 --- /dev/null +++ b/latest/search/all_e.js @@ -0,0 +1,39 @@ +var searchData= +[ + ['packetid_0',['packetId',['../struct_m_q_t_t_agent_ack_info__t.html#ac3db584579455d37c7ad8656aa4b03f2',1,'MQTTAgentAckInfo_t::packetId()'],['../struct_m_q_t_t_agent_command_func_returns__t.html#ae37354b1e32541cb6b014f270815a28d',1,'MQTTAgentCommandFuncReturns_t::packetId()'],['coreMQTT/struct_m_q_t_t_pub_ack_info__t.html#a66cef7b43af5d7fdd33b5d2dc766b2d0',1,'MQTTPubAckInfo_t::packetId()']]], + ['packetidentifier_1',['packetIdentifier',['coreMQTT/struct_m_q_t_t_deserialized_info__t.html#af4df2a9926a4a68059195daa712d9b84',1,'MQTTDeserializedInfo_t']]], + ['packetreceivedinloop_2',['packetReceivedInLoop',['../struct_m_q_t_t_agent_context__t.html#af284de4e09e0b18411969aad986c8789',1,'MQTTAgentContext_t']]], + ['parameter_20structures_3',['Parameter Structures',['../group__mqtt__agent__struct__types.html',1,'(Global Namespace)'],['coreMQTT/group__mqtt__struct__types.html',1,'(Global Namespace)']]], + ['pargs_4',['pArgs',['../struct_m_q_t_t_agent_command.html#a0d41721e83bc91b39b7f54b39c97fafa',1,'MQTTAgentCommand']]], + ['passwordlength_5',['passwordLength',['coreMQTT/struct_m_q_t_t_connect_info__t.html#a818c4e212a12020a4109eb890ec96383',1,'MQTTConnectInfo_t']]], + ['payloadlength_6',['payloadLength',['coreMQTT/struct_m_q_t_t_publish_info__t.html#a7997964e11571f35f0c3b729db0f760f',1,'MQTTPublishInfo_t']]], + ['pbuffer_7',['pBuffer',['coreMQTT/struct_m_q_t_t_fixed_buffer__t.html#acea147448e044870fb36b7fa2347dbd6',1,'MQTTFixedBuffer_t']]], + ['pclientidentifier_8',['pClientIdentifier',['coreMQTT/struct_m_q_t_t_connect_info__t.html#a010f8f6993cbf8899648d5c515ff7884',1,'MQTTConnectInfo_t']]], + ['pcmdcompletecallbackcontext_9',['pCmdCompleteCallbackContext',['../struct_m_q_t_t_agent_command_info__t.html#a22fc349b76808064646fe71a43d37b96',1,'MQTTAgentCommandInfo_t']]], + ['pcmdcontext_10',['pCmdContext',['../struct_m_q_t_t_agent_command.html#ae7f9dad4bc0c849dae9dd2aa8c20eeef',1,'MQTTAgentCommand']]], + ['pcommandcompletecallback_11',['pCommandCompleteCallback',['../struct_m_q_t_t_agent_command.html#a4221813f0ee8d6be1e2b1f60b31fb2a3',1,'MQTTAgentCommand']]], + ['pconnectinfo_12',['pConnectInfo',['../struct_m_q_t_t_agent_connect_args__t.html#a9b71b1787c8cfe03654b1ca06ac594fa',1,'MQTTAgentConnectArgs_t']]], + ['pincomingcallback_13',['pIncomingCallback',['../struct_m_q_t_t_agent_context__t.html#a1e20b7a77aab94f5c775ca3c534cb006',1,'MQTTAgentContext_t']]], + ['pincomingcallbackcontext_14',['pIncomingCallbackContext',['../struct_m_q_t_t_agent_context__t.html#a00a73b9d9cfda64aeb9e7b796222dde4',1,'MQTTAgentContext_t']]], + ['ping_15',['PING',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a3a95ef902bc659901cceef98e0bc8041',1,'core_mqtt_agent.h']]], + ['pingreqsendtimems_16',['pingReqSendTimeMs',['coreMQTT/struct_m_q_t_t_context__t.html#acca3efa4146d85f7e874c7c326e23556',1,'MQTTContext_t']]], + ['pmsgctx_17',['pMsgCtx',['../struct_m_q_t_t_agent_message_interface__t.html#a00cad3c3514a03d5deed20609ffdc94b',1,'MQTTAgentMessageInterface_t']]], + ['pnetworkcontext_18',['pNetworkContext',['coreMQTT/struct_transport_interface__t.html#aaf4702050bef8d62714a4d3900e95087',1,'TransportInterface_t']]], + ['poriginalcommand_19',['pOriginalCommand',['../struct_m_q_t_t_agent_ack_info__t.html#a4cddb1600b6ef0d3a34af262d919b2be',1,'MQTTAgentAckInfo_t']]], + ['porting_20guide_20',['Porting Guide',['coreMQTT/mqtt_porting.html',1,'']]], + ['ppassword_21',['pPassword',['coreMQTT/struct_m_q_t_t_connect_info__t.html#acec6c79a11d2f0f130802393f34d2b5e',1,'MQTTConnectInfo_t']]], + ['ppayload_22',['pPayload',['coreMQTT/struct_m_q_t_t_publish_info__t.html#afc28299f4f625f5e674bb61b42f03380',1,'MQTTPublishInfo_t']]], + ['ppendingacks_23',['pPendingAcks',['../struct_m_q_t_t_agent_context__t.html#a324ccd898ba0769142b29b4cab38c5be',1,'MQTTAgentContext_t']]], + ['ppublishinfo_24',['pPublishInfo',['coreMQTT/struct_m_q_t_t_deserialized_info__t.html#ac347273fae1e92b9cbeda1714066c1de',1,'MQTTDeserializedInfo_t']]], + ['premainingdata_25',['pRemainingData',['coreMQTT/struct_m_q_t_t_packet_info__t.html#ac66cedff052bc844ec9b296387df60bc',1,'MQTTPacketInfo_t']]], + ['processcommand_26',['processCommand',['../core__mqtt__agent_8c.html#a18da6f0f75cb79d2b56db65b40ba9437',1,'core_mqtt_agent.c']]], + ['processloop_27',['PROCESSLOOP',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a955e933dab5938a6cce4e140278a24d2',1,'core_mqtt_agent.h']]], + ['psubackcodes_28',['pSubackCodes',['../struct_m_q_t_t_agent_return_info__t.html#ad68d82134f1f72460f82b83256409542',1,'MQTTAgentReturnInfo_t']]], + ['psubscribeinfo_29',['pSubscribeInfo',['../struct_m_q_t_t_agent_subscribe_args__t.html#a27e21bfcf0184a4a168a6170a60fc026',1,'MQTTAgentSubscribeArgs_t']]], + ['ptopicfilter_30',['pTopicFilter',['coreMQTT/struct_m_q_t_t_subscribe_info__t.html#adb0b28240fdcd82a85f11cf2f8b5bbf0',1,'MQTTSubscribeInfo_t']]], + ['ptopicname_31',['pTopicName',['coreMQTT/struct_m_q_t_t_publish_info__t.html#aa80e8ca282d01630f878ad0afe81d7a4',1,'MQTTPublishInfo_t']]], + ['publish_32',['PUBLISH',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33abd1a204dcfa4933760cd12e779f36fc5',1,'core_mqtt_agent.h']]], + ['publishstate_33',['publishState',['coreMQTT/struct_m_q_t_t_pub_ack_info__t.html#a61314203ef87a231c6489c68b579de34',1,'MQTTPubAckInfo_t']]], + ['pusername_34',['pUserName',['coreMQTT/struct_m_q_t_t_connect_info__t.html#a1118d7d3251a11445318557280db53b4',1,'MQTTConnectInfo_t']]], + ['pwillinfo_35',['pWillInfo',['../struct_m_q_t_t_agent_connect_args__t.html#a1ab24eb17eebc51bdad53ee2b36c8cdb',1,'MQTTAgentConnectArgs_t']]] +]; diff --git a/latest/search/all_f.js b/latest/search/all_f.js new file mode 100644 index 00000000..e6dbfbb6 --- /dev/null +++ b/latest/search/all_f.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['qos_0',['qos',['coreMQTT/struct_m_q_t_t_pub_ack_info__t.html#a086fcd48ef0b787697526a95c861e8a0',1,'MQTTPubAckInfo_t::qos()'],['coreMQTT/struct_m_q_t_t_publish_info__t.html#a178224d02b4acdec7e08e88de0e4b399',1,'MQTTPublishInfo_t::qos()'],['coreMQTT/struct_m_q_t_t_subscribe_info__t.html#a64cf2e423f60cfec122eeaef80c0fd86',1,'MQTTSubscribeInfo_t::qos()']]] +]; diff --git a/latest/search/classes_0.js b/latest/search/classes_0.js new file mode 100644 index 00000000..468a83e0 --- /dev/null +++ b/latest/search/classes_0.js @@ -0,0 +1,20 @@ +var searchData= +[ + ['mqttagentackinfo_5ft_0',['MQTTAgentAckInfo_t',['../struct_m_q_t_t_agent_ack_info__t.html',1,'']]], + ['mqttagentcommand_1',['MQTTAgentCommand',['../struct_m_q_t_t_agent_command.html',1,'']]], + ['mqttagentcommandfuncreturns_5ft_2',['MQTTAgentCommandFuncReturns_t',['../struct_m_q_t_t_agent_command_func_returns__t.html',1,'']]], + ['mqttagentcommandinfo_5ft_3',['MQTTAgentCommandInfo_t',['../struct_m_q_t_t_agent_command_info__t.html',1,'']]], + ['mqttagentconnectargs_5ft_4',['MQTTAgentConnectArgs_t',['../struct_m_q_t_t_agent_connect_args__t.html',1,'']]], + ['mqttagentcontext_5ft_5',['MQTTAgentContext_t',['../struct_m_q_t_t_agent_context__t.html',1,'']]], + ['mqttagentmessageinterface_5ft_6',['MQTTAgentMessageInterface_t',['../struct_m_q_t_t_agent_message_interface__t.html',1,'']]], + ['mqttagentreturninfo_5ft_7',['MQTTAgentReturnInfo_t',['../struct_m_q_t_t_agent_return_info__t.html',1,'']]], + ['mqttagentsubscribeargs_5ft_8',['MQTTAgentSubscribeArgs_t',['../struct_m_q_t_t_agent_subscribe_args__t.html',1,'']]], + ['mqttconnectinfo_5ft_9',['MQTTConnectInfo_t',['coreMQTT/struct_m_q_t_t_connect_info__t.html',1,'']]], + ['mqttcontext_5ft_10',['MQTTContext_t',['coreMQTT/struct_m_q_t_t_context__t.html',1,'']]], + ['mqttdeserializedinfo_5ft_11',['MQTTDeserializedInfo_t',['coreMQTT/struct_m_q_t_t_deserialized_info__t.html',1,'']]], + ['mqttfixedbuffer_5ft_12',['MQTTFixedBuffer_t',['coreMQTT/struct_m_q_t_t_fixed_buffer__t.html',1,'']]], + ['mqttpacketinfo_5ft_13',['MQTTPacketInfo_t',['coreMQTT/struct_m_q_t_t_packet_info__t.html',1,'']]], + ['mqttpubackinfo_5ft_14',['MQTTPubAckInfo_t',['coreMQTT/struct_m_q_t_t_pub_ack_info__t.html',1,'']]], + ['mqttpublishinfo_5ft_15',['MQTTPublishInfo_t',['coreMQTT/struct_m_q_t_t_publish_info__t.html',1,'']]], + ['mqttsubscribeinfo_5ft_16',['MQTTSubscribeInfo_t',['coreMQTT/struct_m_q_t_t_subscribe_info__t.html',1,'']]] +]; diff --git a/latest/search/classes_1.js b/latest/search/classes_1.js new file mode 100644 index 00000000..73efd8ea --- /dev/null +++ b/latest/search/classes_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['transportinterface_5ft_0',['TransportInterface_t',['coreMQTT/struct_transport_interface__t.html',1,'']]], + ['transportoutvector_5ft_1',['TransportOutVector_t',['coreMQTT/struct_transport_out_vector__t.html',1,'']]] +]; diff --git a/latest/search/close.svg b/latest/search/close.svg new file mode 100644 index 00000000..a933eea1 --- /dev/null +++ b/latest/search/close.svg @@ -0,0 +1,31 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/latest/search/defines_0.js b/latest/search/defines_0.js new file mode 100644 index 00000000..14668825 --- /dev/null +++ b/latest/search/defines_0.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['logdebug_0',['LogDebug',['../core__mqtt__agent__default__logging_8h.html#af60e8ffc327d136e5d0d8441ed98c98d',1,'core_mqtt_agent_default_logging.h']]], + ['logerror_1',['LogError',['../core__mqtt__agent__default__logging_8h.html#a8d9dbaaa88129137a4c68ba0456a18b1',1,'core_mqtt_agent_default_logging.h']]], + ['loginfo_2',['LogInfo',['../core__mqtt__agent__default__logging_8h.html#a00810b1cb9d2f25d25ce2d4d93815fba',1,'core_mqtt_agent_default_logging.h']]], + ['logwarn_3',['LogWarn',['../core__mqtt__agent__default__logging_8h.html#a7da92048aaf0cbfcacde9539c98a0e05',1,'core_mqtt_agent_default_logging.h']]] +]; diff --git a/latest/search/defines_1.js b/latest/search/defines_1.js new file mode 100644 index 00000000..dc76b449 --- /dev/null +++ b/latest/search/defines_1.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['mqtt_5fagent_5fdo_5fnot_5fuse_5fcustom_5fconfig_0',['MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG',['../core__mqtt__agent__config__defaults_8h.html#aa10d2a7250bc5471633048ad4f238138',1,'core_mqtt_agent_config_defaults.h']]], + ['mqtt_5fagent_5ffunction_5ftable_1',['MQTT_AGENT_FUNCTION_TABLE',['../core__mqtt__agent__command__functions_8h.html#adf96732c68dea38cfc3b325639304bba',1,'core_mqtt_agent_command_functions.h']]], + ['mqtt_5fagent_5fmax_5fevent_5fqueue_5fwait_5ftime_2',['MQTT_AGENT_MAX_EVENT_QUEUE_WAIT_TIME',['../core__mqtt__agent__config__defaults_8h.html#a9fbd3d9f02a4cabb01e900cfa4d01980',1,'core_mqtt_agent_config_defaults.h']]], + ['mqtt_5fagent_5fmax_5foutstanding_5facks_3',['MQTT_AGENT_MAX_OUTSTANDING_ACKS',['../core__mqtt__agent__config__defaults_8h.html#afc749954a2c0c3a81bcf1e2eb5fecaad',1,'core_mqtt_agent_config_defaults.h']]], + ['mqtt_5fagent_5fuse_5fqos_5f1_5f2_5fpublish_4',['MQTT_AGENT_USE_QOS_1_2_PUBLISH',['../core__mqtt__agent__config__defaults_8h.html#af20d4b1937cbd282f193f69b1b27742e',1,'core_mqtt_agent_config_defaults.h']]] +]; diff --git a/latest/search/enums_0.js b/latest/search/enums_0.js new file mode 100644 index 00000000..c22d1428 --- /dev/null +++ b/latest/search/enums_0.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['mqttagentcommandtype_5ft_0',['MQTTAgentCommandType_t',['../group__mqtt__agent__enum__types.html#ga76604fa58b7ee6c32ba084fda9379f33',1,'core_mqtt_agent.h']]], + ['mqttconnectionstatus_5ft_1',['MQTTConnectionStatus_t',['coreMQTT/group__mqtt__enum__types.html#ga9f84d003695205cf10a7bd0bafb3dbf6',1,]]], + ['mqttpubacktype_5ft_2',['MQTTPubAckType_t',['coreMQTT/group__mqtt__enum__types.html#ga8c1bee959b3ed5fab2a2688dd72bf237',1,]]], + ['mqttpublishstate_5ft_3',['MQTTPublishState_t',['coreMQTT/group__mqtt__enum__types.html#ga0480de7552eedd739a26a23fa8e6fd94',1,]]], + ['mqttqos_5ft_4',['MQTTQoS_t',['coreMQTT/group__mqtt__enum__types.html#gae308a5928d7f537379c29a894228093a',1,]]], + ['mqttstatus_5ft_5',['MQTTStatus_t',['coreMQTT/group__mqtt__enum__types.html#gaba7ec045874a1c3432f99173367f735c',1,]]], + ['mqttsubackstatus_5ft_6',['MQTTSubAckStatus_t',['coreMQTT/group__mqtt__enum__types.html#ga48dabc1579e3c0ac6058ce9068054611',1,]]] +]; diff --git a/latest/search/enumvalues_0.js b/latest/search/enumvalues_0.js new file mode 100644 index 00000000..2347fdf4 --- /dev/null +++ b/latest/search/enumvalues_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['connect_0',['CONNECT',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a20391dd2915a0e64343d24c2f2e40b95',1,'core_mqtt_agent.h']]] +]; diff --git a/latest/search/enumvalues_1.js b/latest/search/enumvalues_1.js new file mode 100644 index 00000000..51ec9acb --- /dev/null +++ b/latest/search/enumvalues_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['disconnect_0',['DISCONNECT',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a2f6318afb30e8e2817e6203ebedc8173',1,'core_mqtt_agent.h']]] +]; diff --git a/latest/search/enumvalues_2.js b/latest/search/enumvalues_2.js new file mode 100644 index 00000000..f1fcf7f6 --- /dev/null +++ b/latest/search/enumvalues_2.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['none_0',['NONE',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33ac157bdf0b85a40d2619cbc8bc1ae5fe2',1,'core_mqtt_agent.h']]], + ['num_5fcommands_1',['NUM_COMMANDS',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a158760c3c33699acd8723f4c983822a6',1,'core_mqtt_agent.h']]] +]; diff --git a/latest/search/enumvalues_3.js b/latest/search/enumvalues_3.js new file mode 100644 index 00000000..05d7ec2b --- /dev/null +++ b/latest/search/enumvalues_3.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['ping_0',['PING',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a3a95ef902bc659901cceef98e0bc8041',1,'core_mqtt_agent.h']]], + ['processloop_1',['PROCESSLOOP',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a955e933dab5938a6cce4e140278a24d2',1,'core_mqtt_agent.h']]], + ['publish_2',['PUBLISH',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33abd1a204dcfa4933760cd12e779f36fc5',1,'core_mqtt_agent.h']]] +]; diff --git a/latest/search/enumvalues_4.js b/latest/search/enumvalues_4.js new file mode 100644 index 00000000..152858c0 --- /dev/null +++ b/latest/search/enumvalues_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['subscribe_0',['SUBSCRIBE',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33abc6f919ff681f5f552b2f7d1f0fba832',1,'core_mqtt_agent.h']]] +]; diff --git a/latest/search/enumvalues_5.js b/latest/search/enumvalues_5.js new file mode 100644 index 00000000..bffd0e84 --- /dev/null +++ b/latest/search/enumvalues_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['terminate_0',['TERMINATE',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a9aab2d9eae3e9a84d9fed3f0cadd7e22',1,'core_mqtt_agent.h']]] +]; diff --git a/latest/search/enumvalues_6.js b/latest/search/enumvalues_6.js new file mode 100644 index 00000000..c941c24e --- /dev/null +++ b/latest/search/enumvalues_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['unsubscribe_0',['UNSUBSCRIBE',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a8395e5981c15d813c588c86988fd4aea',1,'core_mqtt_agent.h']]] +]; diff --git a/latest/search/files_0.js b/latest/search/files_0.js new file mode 100644 index 00000000..7827fafa --- /dev/null +++ b/latest/search/files_0.js @@ -0,0 +1,17 @@ +var searchData= +[ + ['core_5fmqtt_2ec_0',['core_mqtt.c',['coreMQTT/core__mqtt_8c.html',1,'']]], + ['core_5fmqtt_2eh_1',['core_mqtt.h',['coreMQTT/core__mqtt_8h.html',1,'']]], + ['core_5fmqtt_5fagent_2ec_2',['core_mqtt_agent.c',['../core__mqtt__agent_8c.html',1,'']]], + ['core_5fmqtt_5fagent_2eh_3',['core_mqtt_agent.h',['../core__mqtt__agent_8h.html',1,'']]], + ['core_5fmqtt_5fagent_5fcommand_5ffunctions_2ec_4',['core_mqtt_agent_command_functions.c',['../core__mqtt__agent__command__functions_8c.html',1,'']]], + ['core_5fmqtt_5fagent_5fcommand_5ffunctions_2eh_5',['core_mqtt_agent_command_functions.h',['../core__mqtt__agent__command__functions_8h.html',1,'']]], + ['core_5fmqtt_5fagent_5fconfig_5fdefaults_2eh_6',['core_mqtt_agent_config_defaults.h',['../core__mqtt__agent__config__defaults_8h.html',1,'']]], + ['core_5fmqtt_5fagent_5fdefault_5flogging_2eh_7',['core_mqtt_agent_default_logging.h',['../core__mqtt__agent__default__logging_8h.html',1,'']]], + ['core_5fmqtt_5fagent_5fmessage_5finterface_2eh_8',['core_mqtt_agent_message_interface.h',['../core__mqtt__agent__message__interface_8h.html',1,'']]], + ['core_5fmqtt_5fconfig_5fdefaults_2eh_9',['core_mqtt_config_defaults.h',['coreMQTT/core__mqtt__config__defaults_8h.html',1,'']]], + ['core_5fmqtt_5fserializer_2ec_10',['core_mqtt_serializer.c',['coreMQTT/core__mqtt__serializer_8c.html',1,'']]], + ['core_5fmqtt_5fserializer_2eh_11',['core_mqtt_serializer.h',['coreMQTT/core__mqtt__serializer_8h.html',1,'']]], + ['core_5fmqtt_5fstate_2ec_12',['core_mqtt_state.c',['coreMQTT/core__mqtt__state_8c.html',1,'']]], + ['core_5fmqtt_5fstate_2eh_13',['core_mqtt_state.h',['coreMQTT/core__mqtt__state_8h.html',1,'']]] +]; diff --git a/latest/search/files_1.js b/latest/search/files_1.js new file mode 100644 index 00000000..1a653f21 --- /dev/null +++ b/latest/search/files_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['transport_5finterface_2eh_0',['transport_interface.h',['coreMQTT/transport__interface_8h.html',1,'']]] +]; diff --git a/latest/search/functions_0.js b/latest/search/functions_0.js new file mode 100644 index 00000000..8850a2b3 --- /dev/null +++ b/latest/search/functions_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['addawaitingoperation_0',['addAwaitingOperation',['../core__mqtt__agent_8c.html#ae70f7438de05ac589b4e48d4a2a7dd7b',1,'core_mqtt_agent.c']]], + ['addcommandtoqueue_1',['addCommandToQueue',['../core__mqtt__agent_8c.html#a38a109884abe76bd9e0b90d23b9d67b4',1,'core_mqtt_agent.c']]] +]; diff --git a/latest/search/functions_1.js b/latest/search/functions_1.js new file mode 100644 index 00000000..9f35aba6 --- /dev/null +++ b/latest/search/functions_1.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['clearpendingacknowledgments_0',['clearPendingAcknowledgments',['../core__mqtt__agent_8c.html#afb076dcf75919d5b638c33054b95461d',1,'core_mqtt_agent.c']]], + ['concludecommand_1',['concludeCommand',['../core__mqtt__agent_8c.html#a848611250b309e0d84cb18a42fbf6391',1,'core_mqtt_agent.c']]], + ['createandaddcommand_2',['createAndAddCommand',['../core__mqtt__agent_8c.html#a594dbfd47f77c6988960110da3c25a2c',1,'core_mqtt_agent.c']]], + ['createcommand_3',['createCommand',['../core__mqtt__agent_8c.html#a4f2d34a65263b609595aa8f1705ff89f',1,'core_mqtt_agent.c']]] +]; diff --git a/latest/search/functions_2.js b/latest/search/functions_2.js new file mode 100644 index 00000000..d4dfa2ce --- /dev/null +++ b/latest/search/functions_2.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['getagentfrommqttcontext_0',['getAgentFromMQTTContext',['../core__mqtt__agent_8c.html#adb6cd05d1e6b270a021cb50980654707',1,'core_mqtt_agent.c']]], + ['getawaitingoperation_1',['getAwaitingOperation',['../core__mqtt__agent_8c.html#af4ab608204e853ab34bda491a47f6b84',1,'core_mqtt_agent.c']]] +]; diff --git a/latest/search/functions_3.js b/latest/search/functions_3.js new file mode 100644 index 00000000..28f20a71 --- /dev/null +++ b/latest/search/functions_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['handleacks_0',['handleAcks',['../core__mqtt__agent_8c.html#ace2cab4efce97019ae5e12ccae2780cd',1,'core_mqtt_agent.c']]] +]; diff --git a/latest/search/functions_4.js b/latest/search/functions_4.js new file mode 100644 index 00000000..ededbd72 --- /dev/null +++ b/latest/search/functions_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['isspaceinpendingacklist_0',['isSpaceInPendingAckList',['../core__mqtt__agent_8c.html#a6082ea8cf8fe3f34e0a8de08d6980a29',1,'core_mqtt_agent.c']]] +]; diff --git a/latest/search/functions_5.js b/latest/search/functions_5.js new file mode 100644 index 00000000..8bafde34 --- /dev/null +++ b/latest/search/functions_5.js @@ -0,0 +1,24 @@ +var searchData= +[ + ['mqttagent_5fcancelall_0',['MQTTAgent_CancelAll',['../core__mqtt__agent_8c.html#a0362d7d3d68628413f01b32ec2ff4ab6',1,'MQTTAgent_CancelAll(MQTTAgentContext_t *pMqttAgentContext): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#a0362d7d3d68628413f01b32ec2ff4ab6',1,'MQTTAgent_CancelAll(MQTTAgentContext_t *pMqttAgentContext): core_mqtt_agent.c']]], + ['mqttagent_5fcommandloop_1',['MQTTAgent_CommandLoop',['../core__mqtt__agent_8c.html#a9dafeb1701b1a0ee897b626a09cfcff7',1,'MQTTAgent_CommandLoop(MQTTAgentContext_t *pMqttAgentContext): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#a9dafeb1701b1a0ee897b626a09cfcff7',1,'MQTTAgent_CommandLoop(MQTTAgentContext_t *pMqttAgentContext): core_mqtt_agent.c']]], + ['mqttagent_5fconnect_2',['MQTTAgent_Connect',['../core__mqtt__agent_8h.html#a782425e50d258837d23e379471254412',1,'MQTTAgent_Connect(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentConnectArgs_t *pConnectArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#a782425e50d258837d23e379471254412',1,'MQTTAgent_Connect(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentConnectArgs_t *pConnectArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5fdisconnect_3',['MQTTAgent_Disconnect',['../core__mqtt__agent_8h.html#a26687b9b762b5f52b14387bacdf17224',1,'MQTTAgent_Disconnect(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#a26687b9b762b5f52b14387bacdf17224',1,'MQTTAgent_Disconnect(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5finit_4',['MQTTAgent_Init',['../core__mqtt__agent_8h.html#a584863528e72229f35003485f7ee0edd',1,'MQTTAgent_Init(MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentMessageInterface_t *pMsgInterface, const MQTTFixedBuffer_t *pNetworkBuffer, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getCurrentTimeMs, MQTTAgentIncomingPublishCallback_t incomingCallback, void *pIncomingPacketContext): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#a584863528e72229f35003485f7ee0edd',1,'MQTTAgent_Init(MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentMessageInterface_t *pMsgInterface, const MQTTFixedBuffer_t *pNetworkBuffer, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getCurrentTimeMs, MQTTAgentIncomingPublishCallback_t incomingCallback, void *pIncomingPacketContext): core_mqtt_agent.c']]], + ['mqttagent_5fping_5',['MQTTAgent_Ping',['../core__mqtt__agent_8c.html#ae260e29f31d51953cbab2e1437f645ed',1,'MQTTAgent_Ping(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#ae260e29f31d51953cbab2e1437f645ed',1,'MQTTAgent_Ping(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5fprocessloop_6',['MQTTAgent_ProcessLoop',['../core__mqtt__agent_8h.html#aa14c9c86e036d0b1f5c04a538597cc46',1,'MQTTAgent_ProcessLoop(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#aa14c9c86e036d0b1f5c04a538597cc46',1,'MQTTAgent_ProcessLoop(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5fpublish_7',['MQTTAgent_Publish',['../core__mqtt__agent_8h.html#afea2405ab859324cb241ea47e6a5ab81',1,'MQTTAgent_Publish(const MQTTAgentContext_t *pMqttAgentContext, MQTTPublishInfo_t *pPublishInfo, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#afea2405ab859324cb241ea47e6a5ab81',1,'MQTTAgent_Publish(const MQTTAgentContext_t *pMqttAgentContext, MQTTPublishInfo_t *pPublishInfo, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5fresumesession_8',['MQTTAgent_ResumeSession',['../core__mqtt__agent_8h.html#a75065d6bff5f2d32831f2c74922296fb',1,'MQTTAgent_ResumeSession(MQTTAgentContext_t *pMqttAgentContext, bool sessionPresent): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#a75065d6bff5f2d32831f2c74922296fb',1,'MQTTAgent_ResumeSession(MQTTAgentContext_t *pMqttAgentContext, bool sessionPresent): core_mqtt_agent.c']]], + ['mqttagent_5fsubscribe_9',['MQTTAgent_Subscribe',['../core__mqtt__agent_8h.html#a651cf10182392ecea5e8609af8855d49',1,'MQTTAgent_Subscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#a651cf10182392ecea5e8609af8855d49',1,'MQTTAgent_Subscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5fterminate_10',['MQTTAgent_Terminate',['../core__mqtt__agent_8h.html#ae1b19c10831f72251603b045f2608313',1,'MQTTAgent_Terminate(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#ae1b19c10831f72251603b045f2608313',1,'MQTTAgent_Terminate(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5funsubscribe_11',['MQTTAgent_Unsubscribe',['../core__mqtt__agent_8h.html#ac3f70c81c8f8947dfb7346045c8edb63',1,'MQTTAgent_Unsubscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#ac3f70c81c8f8947dfb7346045c8edb63',1,'MQTTAgent_Unsubscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagentcommand_5fconnect_12',['MQTTAgentCommand_Connect',['../core__mqtt__agent__command__functions_8h.html#abe89d0e3cf7ddd095a3c840df4955a9e',1,'MQTTAgentCommand_Connect(MQTTAgentContext_t *pMqttAgentContext, void *pVoidConnectArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#abe89d0e3cf7ddd095a3c840df4955a9e',1,'MQTTAgentCommand_Connect(MQTTAgentContext_t *pMqttAgentContext, void *pVoidConnectArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fdisconnect_13',['MQTTAgentCommand_Disconnect',['../core__mqtt__agent__command__functions_8h.html#aa7507c7a01cdc06af0d5f42711357b6e',1,'MQTTAgentCommand_Disconnect(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#aa7507c7a01cdc06af0d5f42711357b6e',1,'MQTTAgentCommand_Disconnect(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fping_14',['MQTTAgentCommand_Ping',['../core__mqtt__agent__command__functions_8h.html#a9840f5683a5e513b99ab15961e17e42b',1,'MQTTAgentCommand_Ping(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#a9840f5683a5e513b99ab15961e17e42b',1,'MQTTAgentCommand_Ping(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fprocessloop_15',['MQTTAgentCommand_ProcessLoop',['../core__mqtt__agent__command__functions_8c.html#ae2a8b7caae9b06f36f9784663c8f8a49',1,'MQTTAgentCommand_ProcessLoop(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8h.html#ae2a8b7caae9b06f36f9784663c8f8a49',1,'MQTTAgentCommand_ProcessLoop(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fpublish_16',['MQTTAgentCommand_Publish',['../core__mqtt__agent__command__functions_8h.html#a5b4be57b6b6a55054e94850c805fd943',1,'MQTTAgentCommand_Publish(MQTTAgentContext_t *pMqttAgentContext, void *pPublishArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#a5b4be57b6b6a55054e94850c805fd943',1,'MQTTAgentCommand_Publish(MQTTAgentContext_t *pMqttAgentContext, void *pPublishArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fsubscribe_17',['MQTTAgentCommand_Subscribe',['../core__mqtt__agent__command__functions_8h.html#accbd434285c7cd823270614513ecd4a0',1,'MQTTAgentCommand_Subscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#accbd434285c7cd823270614513ecd4a0',1,'MQTTAgentCommand_Subscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fterminate_18',['MQTTAgentCommand_Terminate',['../core__mqtt__agent__command__functions_8h.html#aa017a4f5741920140688973e4b8bf0f1',1,'MQTTAgentCommand_Terminate(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#aa017a4f5741920140688973e4b8bf0f1',1,'MQTTAgentCommand_Terminate(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5funsubscribe_19',['MQTTAgentCommand_Unsubscribe',['../core__mqtt__agent__command__functions_8h.html#aea9ea15866e2e7940469d9a200b45362',1,'MQTTAgentCommand_Unsubscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#aea9ea15866e2e7940469d9a200b45362',1,'MQTTAgentCommand_Unsubscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqtteventcallback_20',['mqttEventCallback',['../core__mqtt__agent_8c.html#a4aeca55423966c3eff1734316f6a7466',1,'core_mqtt_agent.c']]] +]; diff --git a/latest/search/functions_6.js b/latest/search/functions_6.js new file mode 100644 index 00000000..7800d5e2 --- /dev/null +++ b/latest/search/functions_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['processcommand_0',['processCommand',['../core__mqtt__agent_8c.html#a18da6f0f75cb79d2b56db65b40ba9437',1,'core_mqtt_agent.c']]] +]; diff --git a/latest/search/functions_7.js b/latest/search/functions_7.js new file mode 100644 index 00000000..c87ec25a --- /dev/null +++ b/latest/search/functions_7.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['resendpublishes_0',['resendPublishes',['../core__mqtt__agent_8c.html#a0c7ea532d3da52d5c8ceb7493ce5fe36',1,'core_mqtt_agent.c']]] +]; diff --git a/latest/search/functions_8.js b/latest/search/functions_8.js new file mode 100644 index 00000000..8d1b51f7 --- /dev/null +++ b/latest/search/functions_8.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['validateparams_0',['validateParams',['../core__mqtt__agent_8c.html#ac6b1b83accad3124122fed5c7ec14870',1,'core_mqtt_agent.c']]], + ['validatestruct_1',['validateStruct',['../core__mqtt__agent_8c.html#a77d4ec3f1e90897d6f173a2fcd7b9b61',1,'core_mqtt_agent.c']]] +]; diff --git a/latest/search/groups_0.js b/latest/search/groups_0.js new file mode 100644 index 00000000..2a9e610c --- /dev/null +++ b/latest/search/groups_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['basic_20types_0',['Basic Types',['coreMQTT/group__mqtt__basic__types.html',1,'']]] +]; diff --git a/latest/search/groups_1.js b/latest/search/groups_1.js new file mode 100644 index 00000000..9b881a8e --- /dev/null +++ b/latest/search/groups_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['callback_20types_0',['Callback Types',['../group__mqtt__agent__callback__types.html',1,'(Global Namespace)'],['coreMQTT/group__mqtt__callback__types.html',1,'(Global Namespace)']]], + ['constants_1',['Constants',['coreMQTT/group__mqtt__constants.html',1,'']]] +]; diff --git a/latest/search/groups_2.js b/latest/search/groups_2.js new file mode 100644 index 00000000..63da9bfc --- /dev/null +++ b/latest/search/groups_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['enumerated_20types_0',['Enumerated Types',['../group__mqtt__agent__enum__types.html',1,'(Global Namespace)'],['coreMQTT/group__mqtt__enum__types.html',1,'(Global Namespace)']]] +]; diff --git a/latest/search/groups_3.js b/latest/search/groups_3.js new file mode 100644 index 00000000..7135a814 --- /dev/null +++ b/latest/search/groups_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['parameter_20structures_0',['Parameter Structures',['../group__mqtt__agent__struct__types.html',1,'(Global Namespace)'],['coreMQTT/group__mqtt__struct__types.html',1,'(Global Namespace)']]] +]; diff --git a/latest/search/mag.svg b/latest/search/mag.svg new file mode 100644 index 00000000..9f46b301 --- /dev/null +++ b/latest/search/mag.svg @@ -0,0 +1,37 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/latest/search/mag_d.svg b/latest/search/mag_d.svg new file mode 100644 index 00000000..b9a814c7 --- /dev/null +++ b/latest/search/mag_d.svg @@ -0,0 +1,37 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/latest/search/mag_sel.svg b/latest/search/mag_sel.svg new file mode 100644 index 00000000..03626f64 --- /dev/null +++ b/latest/search/mag_sel.svg @@ -0,0 +1,74 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/latest/search/mag_seld.svg b/latest/search/mag_seld.svg new file mode 100644 index 00000000..6e720dcc --- /dev/null +++ b/latest/search/mag_seld.svg @@ -0,0 +1,74 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/latest/search/pages_0.js b/latest/search/pages_0.js new file mode 100644 index 00000000..bb0e4938 --- /dev/null +++ b/latest/search/pages_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['configurations_0',['Configurations',['../core_mqtt_agent_config.html',1,'(Global Namespace)'],['coreMQTT/core_mqtt_config.html',1,'(Global Namespace)']]] +]; diff --git a/latest/search/pages_1.js b/latest/search/pages_1.js new file mode 100644 index 00000000..8533aa4f --- /dev/null +++ b/latest/search/pages_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['design_0',['Design',['../mqtt_agent_design.html',1,'(Global Namespace)'],['coreMQTT/mqtt_design.html',1,'(Global Namespace)']]] +]; diff --git a/latest/search/pages_2.js b/latest/search/pages_2.js new file mode 100644 index 00000000..5455fb0c --- /dev/null +++ b/latest/search/pages_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['functions_0',['Functions',['../mqtt_agent_functions.html',1,'(Global Namespace)'],['coreMQTT/mqtt_functions.html',1,'(Global Namespace)']]] +]; diff --git a/latest/search/pages_3.js b/latest/search/pages_3.js new file mode 100644 index 00000000..cb46f52c --- /dev/null +++ b/latest/search/pages_3.js @@ -0,0 +1,45 @@ +var searchData= +[ + ['message_20interface_0',['Message Interface',['../mqtt_agent_message_interface.html',1,'']]], + ['mqtt_5fconnect_1',['MQTT_Connect',['coreMQTT/mqtt_connect_function.html',1,'']]], + ['mqtt_5fdeserializeack_2',['MQTT_DeserializeAck',['coreMQTT/mqtt_deserializeack_function.html',1,'']]], + ['mqtt_5fdeserializepublish_3',['MQTT_DeserializePublish',['coreMQTT/mqtt_deserializepublish_function.html',1,'']]], + ['mqtt_5fdisconnect_4',['MQTT_Disconnect',['coreMQTT/mqtt_disconnect_function.html',1,'']]], + ['mqtt_5fgetconnectpacketsize_5',['MQTT_GetConnectPacketSize',['coreMQTT/mqtt_getconnectpacketsize_function.html',1,'']]], + ['mqtt_5fgetdisconnectpacketsize_6',['MQTT_GetDisconnectPacketSize',['coreMQTT/mqtt_getdisconnectpacketsize_function.html',1,'']]], + ['mqtt_5fgetincomingpackettypeandlength_7',['MQTT_GetIncomingPacketTypeAndLength',['coreMQTT/mqtt_getincomingpackettypeandlength_function.html',1,'']]], + ['mqtt_5fgetpacketid_8',['MQTT_GetPacketId',['coreMQTT/mqtt_getpacketid_function.html',1,'']]], + ['mqtt_5fgetpingreqpacketsize_9',['MQTT_GetPingreqPacketSize',['coreMQTT/mqtt_getpingreqpacketsize_function.html',1,'']]], + ['mqtt_5fgetpublishpacketsize_10',['MQTT_GetPublishPacketSize',['coreMQTT/mqtt_getpublishpacketsize_function.html',1,'']]], + ['mqtt_5fgetsubackstatuscodes_11',['MQTT_GetSubAckStatusCodes',['coreMQTT/mqtt_getsubackstatuscodes_function.html',1,'']]], + ['mqtt_5fgetsubscribepacketsize_12',['MQTT_GetSubscribePacketSize',['coreMQTT/mqtt_getsubscribepacketsize_function.html',1,'']]], + ['mqtt_5fgetunsubscribepacketsize_13',['MQTT_GetUnsubscribePacketSize',['coreMQTT/mqtt_getunsubscribepacketsize_function.html',1,'']]], + ['mqtt_5finit_14',['MQTT_Init',['coreMQTT/mqtt_init_function.html',1,'']]], + ['mqtt_5fping_15',['MQTT_Ping',['coreMQTT/mqtt_ping_function.html',1,'']]], + ['mqtt_5fprocessloop_16',['MQTT_ProcessLoop',['coreMQTT/mqtt_processloop_function.html',1,'']]], + ['mqtt_5fpublish_17',['MQTT_Publish',['coreMQTT/mqtt_publish_function.html',1,'']]], + ['mqtt_5fpublishtoresend_18',['MQTT_PublishToResend',['coreMQTT/mqtt_publishtoresend_function.html',1,'']]], + ['mqtt_5freceiveloop_19',['MQTT_ReceiveLoop',['coreMQTT/mqtt_receiveloop_function.html',1,'']]], + ['mqtt_5fserializeack_20',['MQTT_SerializeAck',['coreMQTT/mqtt_serializeack_function.html',1,'']]], + ['mqtt_5fserializeconnect_21',['MQTT_SerializeConnect',['coreMQTT/mqtt_serializeconnect_function.html',1,'']]], + ['mqtt_5fserializedisconnect_22',['MQTT_SerializeDisconnect',['coreMQTT/mqtt_serializedisconnect_function.html',1,'']]], + ['mqtt_5fserializepingreq_23',['MQTT_SerializePingreq',['coreMQTT/mqtt_serializepingreq_function.html',1,'']]], + ['mqtt_5fserializepublish_24',['MQTT_SerializePublish',['coreMQTT/mqtt_serializepublish_function.html',1,'']]], + ['mqtt_5fserializepublishheader_25',['MQTT_SerializePublishHeader',['coreMQTT/mqtt_serializepublishheader_function.html',1,'']]], + ['mqtt_5fserializesubscribe_26',['MQTT_SerializeSubscribe',['coreMQTT/mqtt_serializesubscribe_function.html',1,'']]], + ['mqtt_5fserializeunsubscribe_27',['MQTT_SerializeUnsubscribe',['coreMQTT/mqtt_serializeunsubscribe_function.html',1,'']]], + ['mqtt_5fstatus_5fstrerror_28',['MQTT_Status_strerror',['coreMQTT/mqtt_status_strerror_function.html',1,'']]], + ['mqtt_5fsubscribe_29',['MQTT_Subscribe',['coreMQTT/mqtt_subscribe_function.html',1,'']]], + ['mqtt_5funsubscribe_30',['MQTT_Unsubscribe',['coreMQTT/mqtt_unsubscribe_function.html',1,'']]], + ['mqttagent_5fcancelall_31',['MQTTAgent_CancelAll',['../mqtt_agent_cancel_function.html',1,'mqtt_agent_functions']]], + ['mqttagent_5fcommandloop_32',['MQTTAgent_CommandLoop',['../mqtt_agent_command_function.html',1,'mqtt_agent_functions']]], + ['mqttagent_5fconnect_33',['MQTTAgent_Connect',['../mqtt_agent_connect_function.html',1,'mqtt_agent_functions']]], + ['mqttagent_5fdisconnect_34',['MQTTAgent_Disconnect',['../mqtt_agent_disconnect_function.html',1,'mqtt_agent_functions']]], + ['mqttagent_5finit_35',['MQTTAgent_Init',['../mqtt_agent_init_function.html',1,'mqtt_agent_functions']]], + ['mqttagent_5fping_36',['MQTTAgent_Ping',['../mqtt_agent_ping_function.html',1,'mqtt_agent_functions']]], + ['mqttagent_5fpublish_37',['MQTTAgent_Publish',['../mqtt_agent_publish_function.html',1,'mqtt_agent_functions']]], + ['mqttagent_5fresumesession_38',['MQTTAgent_ResumeSession',['../mqtt_agent_resume_function.html',1,'mqtt_agent_functions']]], + ['mqttagent_5fsubscribe_39',['MQTTAgent_Subscribe',['../mqtt_agent_subscribe_function.html',1,'mqtt_agent_functions']]], + ['mqttagent_5fterminate_40',['MQTTAgent_Terminate',['../mqtt_agent_terminate_function.html',1,'mqtt_agent_functions']]], + ['mqttagent_5funsubscribe_41',['MQTTAgent_Unsubscribe',['../mqtt_agent_unsubscribe_function.html',1,'mqtt_agent_functions']]] +]; diff --git a/latest/search/pages_4.js b/latest/search/pages_4.js new file mode 100644 index 00000000..0398f4f4 --- /dev/null +++ b/latest/search/pages_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['overview_0',['Overview',['../index.html',1,'']]] +]; diff --git a/latest/search/pages_5.js b/latest/search/pages_5.js new file mode 100644 index 00000000..0219e673 --- /dev/null +++ b/latest/search/pages_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['porting_20guide_0',['Porting Guide',['coreMQTT/mqtt_porting.html',1,'']]] +]; diff --git a/latest/search/pages_6.js b/latest/search/pages_6.js new file mode 100644 index 00000000..14a95a73 --- /dev/null +++ b/latest/search/pages_6.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['timeouts_20in_20coremqtt_20library_0',['Timeouts in coreMQTT library',['coreMQTT/mqtt_timeouts.html',1,'']]], + ['transport_20interface_1',['Transport Interface',['coreMQTT/mqtt_transport_interface.html',1,'']]] +]; diff --git a/latest/search/search.css b/latest/search/search.css new file mode 100644 index 00000000..a53214fc --- /dev/null +++ b/latest/search/search.css @@ -0,0 +1,286 @@ +/*---------------- Search Box */ + +#MSearchBox { + position: absolute; + right: 5px; +} +/*---------------- Search box styling */ + +.SRPage * { + font-weight: normal; + line-height: normal; +} + +dark-mode-toggle { + margin-left: 5px; + display: flex; + float: right; +} + +#MSearchBox { + display: inline-block; + white-space : nowrap; + background: var(--search-background-color); + border-radius: 0.65em; + box-shadow: var(--search-box-shadow); + z-index: 102; +} + +#MSearchBox .left { + display: inline-block; + vertical-align: middle; + height: 1.4em; +} + +#MSearchSelect { + display: inline-block; + vertical-align: middle; + width: 20px; + height: 19px; + background-image: var(--search-magnification-select-image); + margin: 0 0 0 0.3em; + padding: 0; +} + +#MSearchSelectExt { + display: inline-block; + vertical-align: middle; + width: 10px; + height: 19px; + background-image: var(--search-magnification-image); + margin: 0 0 0 0.5em; + padding: 0; +} + + +#MSearchField { + display: inline-block; + vertical-align: middle; + width: 7.5em; + height: 19px; + margin: 0 0.15em; + padding: 0; + line-height: 1em; + border:none; + color: var(--search-foreground-color); + outline: none; + font-family: var(--font-family-search); + -webkit-border-radius: 0px; + border-radius: 0px; + background: none; +} + +@media(hover: none) { + /* to avoid zooming on iOS */ + #MSearchField { + font-size: 16px; + } +} + +#MSearchBox .right { + display: inline-block; + vertical-align: middle; + width: 1.4em; + height: 1.4em; +} + +#MSearchClose { + display: none; + font-size: inherit; + background : none; + border: none; + margin: 0; + padding: 0; + outline: none; + +} + +#MSearchCloseImg { + padding: 0.3em; + margin: 0; +} + +.MSearchBoxActive #MSearchField { + color: var(--search-active-color); +} + + + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid var(--search-filter-border-color); + background-color: var(--search-filter-background-color); + z-index: 10001; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt var(--font-family-search); + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: var(--font-family-monospace); + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: var(--search-filter-foreground-color); + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: var(--search-filter-foreground-color); + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: var(--search-filter-highlight-text-color); + background-color: var(--search-filter-highlight-bg-color); + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + /*width: 60ex;*/ + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid var(--search-results-border-color); + background-color: var(--search-results-background-color); + z-index:10000; + width: 300px; + height: 400px; + overflow: auto; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +div.SRPage { + margin: 5px 2px; + background-color: var(--search-results-background-color); +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: var(--search-results-foreground-color); + font-family: var(--font-family-search); + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: var(--search-results-foreground-color); + font-family: var(--font-family-search); + font-size: 8pt; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; + font-family: var(--font-family-search); +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; + font-family: var(--font-family-search); +} + +.SRResult { + display: none; +} + +div.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: var(--nav-gradient-active-image-parent); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/latest/search/search.js b/latest/search/search.js new file mode 100644 index 00000000..e103a262 --- /dev/null +++ b/latest/search/search.js @@ -0,0 +1,816 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var idxChar = searchValue.substr(0, 1).toLowerCase(); + if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair + { + idxChar = searchValue.substr(0, 2); + } + + var jsFile; + + var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); + if (idx!=-1) + { + var hexCode=idx.toString(16); + jsFile = this.resultsPath + indexSectionNames[this.searchIndex] + '_' + hexCode + '.js'; + } + + var loadJS = function(url, impl, loc){ + var scriptTag = document.createElement('script'); + scriptTag.src = url; + scriptTag.onload = impl; + scriptTag.onreadystatechange = impl; + loc.appendChild(scriptTag); + } + + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + var domSearchBox = this.DOMSearchBox(); + var domPopupSearchResults = this.DOMPopupSearchResults(); + var domSearchClose = this.DOMSearchClose(); + var resultsPath = this.resultsPath; + + var handleResults = function() { + document.getElementById("Loading").style.display="none"; + if (typeof searchData !== 'undefined') { + createResults(resultsPath); + document.getElementById("NoMatches").style.display="none"; + } + + searchResults.Search(searchValue); + + if (domPopupSearchResultsWindow.style.display!='block') + { + domSearchClose.style.display = 'inline-block'; + var left = getXPos(domSearchBox) + 150; + var top = getYPos(domSearchBox) + 20; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + var maxWidth = document.body.clientWidth; + var maxHeight = document.body.clientHeight; + var width = 300; + if (left<10) left=10; + if (width+left+8>maxWidth) width=maxWidth-left-8; + var height = 400; + if (height+top+8>maxHeight) height=maxHeight-top-8; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResultsWindow.style.height = height + 'px'; + } + } + + if (jsFile) { + loadJS(jsFile, handleResults, this.DOMPopupSearchResultsWindow()); + } else { + handleResults(); + } + + this.lastSearchValue = searchValue; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + this.searchActive = true; + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + this.DOMSearchField().value = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName.toLowerCase() == 'div' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName.toLowerCase() == 'div' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + searchBox.CloseResultsWindow(); + document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + searchBox.CloseResultsWindow(); + document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults(resultsPath) +{ + var results = document.getElementById("SRResults"); + results.innerHTML = ''; + for (var e=0; e-{AmhX=Jf(#6djGiuzAr*{o?=JLmPLyc> z_*`QK&+BH@jWrYJ7>r6%keRM@)Qyv8R=enp0jiI>aWlGyB58O zFVR20d+y`K7vDw(hJF3;>dD*3-?v=<8M)@x|EEGLnJsniYK!2U1 Y!`|5biEc?d1`HDhPgg&ebxsLQ02F6;9RL6T literal 0 HcmV?d00001 diff --git a/latest/splitbard.png b/latest/splitbard.png new file mode 100644 index 0000000000000000000000000000000000000000..8367416d757fd7b6dc4272b6432dc75a75abd068 GIT binary patch literal 282 zcmeAS@N?(olHy`uVBq!ia0vp^Yzz!63>-{AmhX=Jf@VhhFKy35^fiT zT~&lUj3=cDh^%3HDY9k5CEku}PHXNoNC(_$U3XPb&Q*ME25pT;2(*BOgAf<+R$lzakPG`kF31()Fx{L5Wrac|GQzjeE= zueY1`Ze{#x<8=S|`~MgGetGce)#vN&|J{Cd^tS%;tBYTo?+^d68<#n_Y_xx`J||4O V@QB{^CqU0Kc)I$ztaD0e0svEzbJzd? literal 0 HcmV?d00001 diff --git a/latest/struct_m_q_t_t_agent_ack_info__t.html b/latest/struct_m_q_t_t_agent_ack_info__t.html new file mode 100644 index 00000000..f65dc8ba --- /dev/null +++ b/latest/struct_m_q_t_t_agent_ack_info__t.html @@ -0,0 +1,164 @@ + + + + + + + +coreMQTT Agent: MQTTAgentAckInfo_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTAgentAckInfo_t Struct Reference
+
+
+ +

Information for a pending MQTT ack packet expected by the agent. + More...

+ +

#include <core_mqtt_agent.h>

+ + + + + + +

+Data Fields

uint16_t packetId
 
MQTTAgentCommand_t * pOriginalCommand
 
+

Detailed Description

+

Information for a pending MQTT ack packet expected by the agent.

+

Field Documentation

+ +

◆ packetId

+ +
+
+ + + + +
uint16_t MQTTAgentAckInfo_t::packetId
+
+

Packet ID of the pending acknowledgment.

+ +
+
+ +

◆ pOriginalCommand

+ +
+
+ + + + +
MQTTAgentCommand_t* MQTTAgentAckInfo_t::pOriginalCommand
+
+

Command expecting acknowledgment.

+ +
+
+
The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/latest/struct_m_q_t_t_agent_command.html b/latest/struct_m_q_t_t_agent_command.html new file mode 100644 index 00000000..b2d39193 --- /dev/null +++ b/latest/struct_m_q_t_t_agent_command.html @@ -0,0 +1,146 @@ + + + + + + + +coreMQTT Agent: MQTTAgentCommand_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTAgentCommand_t Struct Reference
+
+
+ +

The commands sent from the APIs to the MQTT agent task. + More...

+ +

#include <core_mqtt_agent.h>

+ + + + + + + + + + + + + + +

+Data Fields

+MQTTAgentCommandType_t commandType
 Type of command.
 
+void * pArgs
 Arguments of command.
 
+MQTTAgentCommandCallback_t pCommandCompleteCallback
 Callback to invoke upon completion.
 
+MQTTAgentCommandContext_tpCmdContext
 Context for completion callback.
 
+

Detailed Description

+

The commands sent from the APIs to the MQTT agent task.

+
Note
The structure used to pass information from the public facing API into the agent task.
+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/latest/struct_m_q_t_t_agent_command_func_returns__t.html b/latest/struct_m_q_t_t_agent_command_func_returns__t.html new file mode 100644 index 00000000..6b00b2be --- /dev/null +++ b/latest/struct_m_q_t_t_agent_command_func_returns__t.html @@ -0,0 +1,145 @@ + + + + + + + +coreMQTT Agent: MQTTAgentCommandFuncReturns_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTAgentCommandFuncReturns_t Struct Reference
+
+
+ +

A structure of values and flags expected to be returned by command functions. + More...

+ +

#include <core_mqtt_agent_command_functions.h>

+ + + + + + + + + + + + + + +

+Data Fields

+uint16_t packetId
 Packet ID of packet sent by command.
 
+bool endLoop
 Flag to indicate command loop should terminate.
 
+bool addAcknowledgment
 Flag to indicate an acknowledgment should be tracked.
 
+bool runProcessLoop
 Flag to indicate MQTT_ProcessLoop() should be called after this command.
 
+

Detailed Description

+

A structure of values and flags expected to be returned by command functions.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/latest/struct_m_q_t_t_agent_command_info__t.html b/latest/struct_m_q_t_t_agent_command_info__t.html new file mode 100644 index 00000000..6d13c792 --- /dev/null +++ b/latest/struct_m_q_t_t_agent_command_info__t.html @@ -0,0 +1,141 @@ + + + + + + + +coreMQTT Agent: MQTTAgentCommandInfo_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTAgentCommandInfo_t Struct Reference
+
+
+ +

Struct holding arguments that are common to every command. + More...

+ +

#include <core_mqtt_agent.h>

+ + + + + + + + + + + +

+Data Fields

+MQTTAgentCommandCallback_t cmdCompleteCallback
 Callback to invoke upon completion.
 
+MQTTAgentCommandContext_tpCmdCompleteCallbackContext
 Context for completion callback.
 
+uint32_t blockTimeMs
 Maximum block time for enqueueing the command.
 
+

Detailed Description

+

Struct holding arguments that are common to every command.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/latest/struct_m_q_t_t_agent_connect_args__t.html b/latest/struct_m_q_t_t_agent_connect_args__t.html new file mode 100644 index 00000000..f1c9353e --- /dev/null +++ b/latest/struct_m_q_t_t_agent_connect_args__t.html @@ -0,0 +1,145 @@ + + + + + + + +coreMQTT Agent: MQTTAgentConnectArgs_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTAgentConnectArgs_t Struct Reference
+
+
+ +

Struct holding arguments for a CONNECT call. + More...

+ +

#include <core_mqtt_agent.h>

+ + + + + + + + + + + + + + +

+Data Fields

+MQTTConnectInfo_tpConnectInfo
 MQTT CONNECT packet information.
 
+MQTTPublishInfo_tpWillInfo
 Optional Last Will and Testament.
 
+uint32_t timeoutMs
 Maximum timeout for a CONNACK packet.
 
+bool sessionPresent
 Output flag set if a previous session was present.
 
+

Detailed Description

+

Struct holding arguments for a CONNECT call.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/latest/struct_m_q_t_t_agent_context__t.html b/latest/struct_m_q_t_t_agent_context__t.html new file mode 100644 index 00000000..ead582df --- /dev/null +++ b/latest/struct_m_q_t_t_agent_context__t.html @@ -0,0 +1,232 @@ + + + + + + + +coreMQTT Agent: MQTTAgentContext_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTAgentContext_t Struct Reference
+
+
+ +

Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(), and every API function will accept a pointer to the initalized struct. + More...

+ +

#include <core_mqtt_agent.h>

+ + + + + + + + + + + + + + +

+Data Fields

MQTTContext_t mqttContext
 
MQTTAgentMessageInterface_t agentInterface
 
MQTTAgentAckInfo_t pPendingAcks [MQTT_AGENT_MAX_OUTSTANDING_ACKS]
 
MQTTAgentIncomingPublishCallback_t pIncomingCallback
 
void * pIncomingCallbackContext
 
bool packetReceivedInLoop
 
+

Detailed Description

+

Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(), and every API function will accept a pointer to the initalized struct.

+

Field Documentation

+ +

◆ mqttContext

+ +
+
+ + + + +
MQTTContext_t MQTTAgentContext_t::mqttContext
+
+

MQTT connection information used by coreMQTT.

+ +
+
+ +

◆ agentInterface

+ +
+
+ + + + +
MQTTAgentMessageInterface_t MQTTAgentContext_t::agentInterface
+
+

Struct of function pointers for agent messaging.

+ +
+
+ +

◆ pPendingAcks

+ +
+
+ + + + +
MQTTAgentAckInfo_t MQTTAgentContext_t::pPendingAcks[MQTT_AGENT_MAX_OUTSTANDING_ACKS]
+
+

List of pending acknowledgment packets.

+ +
+
+ +

◆ pIncomingCallback

+ +
+
+ + + + +
MQTTAgentIncomingPublishCallback_t MQTTAgentContext_t::pIncomingCallback
+
+

Callback to invoke for incoming publishes.

+ +
+
+ +

◆ pIncomingCallbackContext

+ +
+
+ + + + +
void* MQTTAgentContext_t::pIncomingCallbackContext
+
+

Context for incoming publish callback.

+ +
+
+ +

◆ packetReceivedInLoop

+ +
+
+ + + + +
bool MQTTAgentContext_t::packetReceivedInLoop
+
+

Whether a MQTT_ProcessLoop() call received a packet.

+ +
+
+
The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/latest/struct_m_q_t_t_agent_message_interface__t.html b/latest/struct_m_q_t_t_agent_message_interface__t.html new file mode 100644 index 00000000..4df91493 --- /dev/null +++ b/latest/struct_m_q_t_t_agent_message_interface__t.html @@ -0,0 +1,215 @@ + + + + + + + +coreMQTT Agent: MQTTAgentMessageInterface_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTAgentMessageInterface_t Struct Reference
+
+
+ +

Function pointers and contexts used for sending and receiving commands, and allocating memory for them. + More...

+ +

#include <core_mqtt_agent_message_interface.h>

+ + + + + + + + + + + + +

+Data Fields

MQTTAgentMessageContext_tpMsgCtx
 
MQTTAgentMessageSend_t send
 
MQTTAgentMessageRecv_t recv
 
MQTTAgentCommandGet_t getCommand
 
MQTTAgentCommandRelease_t releaseCommand
 
+

Detailed Description

+

Function pointers and contexts used for sending and receiving commands, and allocating memory for them.

+

Field Documentation

+ +

◆ pMsgCtx

+ +
+
+ + + + +
MQTTAgentMessageContext_t* MQTTAgentMessageInterface_t::pMsgCtx
+
+

Context with which tasks may deliver messages to the agent.

+ +
+
+ +

◆ send

+ +
+
+ + + + +
MQTTAgentMessageSend_t MQTTAgentMessageInterface_t::send
+
+

Function to send a command to the agent.

+ +
+
+ +

◆ recv

+ +
+
+ + + + +
MQTTAgentMessageRecv_t MQTTAgentMessageInterface_t::recv
+
+

Function for the agent to receive a command.

+ +
+
+ +

◆ getCommand

+ +
+
+ + + + +
MQTTAgentCommandGet_t MQTTAgentMessageInterface_t::getCommand
+
+

Function to obtain a pointer to an allocated command.

+ +
+
+ +

◆ releaseCommand

+ +
+
+ + + + +
MQTTAgentCommandRelease_t MQTTAgentMessageInterface_t::releaseCommand
+
+

Function to release an allocated command.

+ +
+
+
The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/latest/struct_m_q_t_t_agent_return_info__t.html b/latest/struct_m_q_t_t_agent_return_info__t.html new file mode 100644 index 00000000..aa7f6d4b --- /dev/null +++ b/latest/struct_m_q_t_t_agent_return_info__t.html @@ -0,0 +1,164 @@ + + + + + + + +coreMQTT Agent: MQTTAgentReturnInfo_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTAgentReturnInfo_t Struct Reference
+
+
+ +

Struct holding return codes and outputs from a command. + More...

+ +

#include <core_mqtt_agent.h>

+ + + + + + +

+Data Fields

MQTTStatus_t returnCode
 
uint8_t * pSubackCodes
 
+

Detailed Description

+

Struct holding return codes and outputs from a command.

+

Field Documentation

+ +

◆ returnCode

+ +
+
+ + + + +
MQTTStatus_t MQTTAgentReturnInfo_t::returnCode
+
+

Return code of the MQTT command.

+ +
+
+ +

◆ pSubackCodes

+ +
+
+ + + + +
uint8_t* MQTTAgentReturnInfo_t::pSubackCodes
+
+

Array of SUBACK statuses, for a SUBSCRIBE command.

+ +
+
+
The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/latest/struct_m_q_t_t_agent_subscribe_args__t.html b/latest/struct_m_q_t_t_agent_subscribe_args__t.html new file mode 100644 index 00000000..7c4e3a93 --- /dev/null +++ b/latest/struct_m_q_t_t_agent_subscribe_args__t.html @@ -0,0 +1,137 @@ + + + + + + + +coreMQTT Agent: MQTTAgentSubscribeArgs_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTAgentSubscribeArgs_t Struct Reference
+
+
+ +

Struct holding arguments for a SUBSCRIBE or UNSUBSCRIBE call. + More...

+ +

#include <core_mqtt_agent.h>

+ + + + + + + + +

+Data Fields

+MQTTSubscribeInfo_tpSubscribeInfo
 List of MQTT subscriptions.
 
+size_t numSubscriptions
 Number of elements in pSubscribeInfo.
 
+

Detailed Description

+

Struct holding arguments for a SUBSCRIBE or UNSUBSCRIBE call.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/latest/style.css b/latest/style.css new file mode 100644 index 00000000..99d7ab71 --- /dev/null +++ b/latest/style.css @@ -0,0 +1,132 @@ +/* + * Stylesheet for Doxygen HTML output. + * + * This file defines styles for custom elements in the header/footer and + * overrides some of the default Doxygen styles. + * + * Styles in this file do not affect the treeview sidebar. + */ + +/* Set the margins to place a small amount of whitespace on the left and right + * side of the page. */ +div.contents { + margin-left:4em; + margin-right:4em; +} + +/* Justify text in paragraphs. */ +p { + text-align: justify; +} + +/* Style of section headings. */ +h1 { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 160%; + font-weight: normal; + padding-bottom: 4px; + padding-top: 8px; +} + +/* Style of subsection headings. */ +h2:not(.memtitle):not(.groupheader) { + font-size: 125%; + margin-bottom: 0px; + margin-top: 16px; + padding: 0px; +} + +/* Style of paragraphs immediately after subsection headings. */ +h2 + p { + margin: 0px; + padding: 0px; +} + +/* Style of subsection headings. */ +h3 { + font-size: 100%; + margin-bottom: 0px; + margin-left: 2em; + margin-right: 2em; +} + +/* Style of paragraphs immediately after subsubsection headings. */ +h3 + p { + margin-top: 0px; + margin-left: 2em; + margin-right: 2em; +} + +/* Style of the prefix "AWS IoT Device SDK C" that appears in the header. */ +#csdkprefix { + color: #757575; +} + +/* Style of the "Return to main page" link that appears in the header. */ +#returntomain { + padding: 0.5em; +} + +/* Style of the dividers on Configuration Settings pages. */ +div.configpagedivider { + margin-left: 0px !important; + margin-right: 0px !important; + margin-top: 20px !important; +} + +/* Style of configuration setting names. */ +dl.section.user ~ h1 { + border-bottom: none; + color: #000000; + font-family: monospace, fixed; + font-size: 16px; + margin-bottom: 0px; + margin-left: 2em; + margin-top: 1.5em; +} + +/* Style of paragraphs on a configuration settings page. */ +dl.section.user ~ * { + margin-bottom: 10px; + margin-left: 4em; + margin-right: 4em; + margin-top: 0px; +} + +/* Hide the configuration setting marker. */ +dl.section.user { + display: none; +} + +/* Overrides for code fragments and lines. */ +div.fragment { + background: #ffffff; + border: none; + padding: 5px; +} + +div.line { + color: #3a3a3a; +} + +/* Overrides for code syntax highlighting colors. */ +span.comment { + color: #008000; +} + +span.keyword, span.keywordtype, span.keywordflow { + color: #0000ff; +} + +span.preprocessor { + color: #50015a; +} + +span.stringliteral, span.charliteral { + color: #800c0c; +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #496194; +} diff --git a/latest/sync_off.png b/latest/sync_off.png new file mode 100644 index 0000000000000000000000000000000000000000..3b443fc62892114406e3d399421b2a881b897acc GIT binary patch literal 853 zcmV-b1FHOqP)oT|#XixUYy%lpuf3i8{fX!o zUyDD0jOrAiT^tq>fLSOOABs-#u{dV^F$b{L9&!2=9&RmV;;8s^x&UqB$PCj4FdKbh zoB1WTskPUPu05XzFbA}=KZ-GP1fPpAfSs>6AHb12UlR%-i&uOlTpFNS7{jm@mkU1V zh`nrXr~+^lsV-s1dkZOaI|kYyVj3WBpPCY{n~yd%u%e+d=f%`N0FItMPtdgBb@py; zq@v6NVArhyTC7)ULw-Jy8y42S1~4n(3LkrW8mW(F-4oXUP3E`e#g**YyqI7h-J2zK zK{m9##m4ri!7N>CqQqCcnI3hqo1I;Yh&QLNY4T`*ptiQGozK>FF$!$+84Z`xwmeMh zJ0WT+OH$WYFALEaGj2_l+#DC3t7_S`vHpSivNeFbP6+r50cO8iu)`7i%Z4BTPh@_m3Tk!nAm^)5Bqnr%Ov|Baunj#&RPtRuK& z4RGz|D5HNrW83-#ydk}tVKJrNmyYt-sTxLGlJY5nc&Re zU4SgHNPx8~Yxwr$bsju?4q&%T1874xxzq+_%?h8_ofw~(bld=o3iC)LUNR*BY%c0y zWd_jX{Y8`l%z+ol1$@Qa?Cy!(0CVIEeYpKZ`(9{z>3$CIe;pJDQk$m3p}$>xBm4lb zKo{4S)`wdU9Ba9jJbVJ0C=SOefZe%d$8=2r={nu<_^a3~>c#t_U6dye5)JrR(_a^E f@}b6j1K9lwFJq@>o)+Ry00000NkvXXu0mjfWa5j* literal 0 HcmV?d00001 diff --git a/latest/sync_on.png b/latest/sync_on.png new file mode 100644 index 0000000000000000000000000000000000000000..e08320fb64e6fa33b573005ed6d8fe294e19db76 GIT binary patch literal 845 zcmV-T1G4;yP)Y;xxyHF2B5Wzm| zOOGupOTn@c(JmBOl)e;XMNnZuiTJP>rM8<|Q`7I_))aP?*T)ow&n59{}X4$3Goat zgjs?*aasfbrokzG5cT4K=uG`E14xZl@z)F={P0Y^?$4t z>v!teRnNZym<6h{7sLyF1V0HsfEl+l6TrZpsfr1}luH~F7L}ktXu|*uVX^RG$L0`K zWs3j|0tIvVe(N%_?2{(iCPFGf#B6Hjy6o&}D$A%W%jfO8_W%ZO#-mh}EM$LMn7joJ z05dHr!5Y92g+31l<%i1(=L1a1pXX+OYnalY>31V4K}BjyRe3)9n#;-cCVRD_IG1fT zOKGeNY8q;TL@K{dj@D^scf&VCs*-Jb>8b>|`b*osv52-!A?BpbYtTQBns5EAU**$m zSnVSm(teh>tQi*S*A>#ySc=n;`BHz`DuG4&g4Kf8lLhca+zvZ7t7RflD6-i-mcK=M z!=^P$*u2)bkY5asG4gsss!Hn%u~>}kIW`vMs%lJLH+u*9<4PaV_c6U`KqWXQH%+Nu zTv41O(^ZVi@qhjQdG!fbZw&y+2o!iYymO^?ud3{P*HdoX83YV*Uu_HB=?U&W9%AU# z80}k1SS-CXTU7dcQlsm<^oYLxVSseqY6NO}dc`Nj?8vrhNuCdm@^{a3AQ_>6myOj+ z`1RsLUXF|dm|3k7s2jD(B{rzE>WI2scH8i1;=O5Cc9xB3^aJk%fQjqsu+kH#0=_5a z0nCE8@dbQa-|YIuUVvG0L_IwHMEhOj$Mj4Uq05 X8=0q~qBNan00000NkvXXu0mjfptF>5 literal 0 HcmV?d00001 diff --git a/latest/tab_a.png b/latest/tab_a.png new file mode 100644 index 0000000000000000000000000000000000000000..3b725c41c5a527a3a3e40097077d0e206a681247 GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QlXwMjv*C{Z|8b*H5dputLHD# z=<0|*y7z(Vor?d;H&?EG&cXR}?!j-Lm&u1OOI7AIF5&c)RFE;&p0MYK>*Kl@eiymD r@|NpwKX@^z+;{u_Z~trSBfrMKa%3`zocFjEXaR$#tDnm{r-UW|TZ1%4 literal 0 HcmV?d00001 diff --git a/latest/tab_ad.png b/latest/tab_ad.png new file mode 100644 index 0000000000000000000000000000000000000000..e34850acfc24be58da6d2fd1ccc6b29cc84fe34d GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QhuH;jv*C{Z|5d*H3V=pKi{In zd2jxLclDRPylmD}^l7{QOtL{vUjO{-WqItb5sQp2h-99b8^^Scr-=2mblCdZuUm?4 jzOJvgvt3{(cjKLW5(A@0qPS@<&}0TrS3j3^P6y&q2{!U5bk+Tso_B!YCpDh>v z{CM*1U8YvQRyBUHt^Ju0W_sq-?;9@_4equ-bavTs=gk796zopr0EBT&m;e9( literal 0 HcmV?d00001 diff --git a/latest/tab_s.png b/latest/tab_s.png new file mode 100644 index 0000000000000000000000000000000000000000..ab478c95b67371d700a20869f7de1ddd73522d50 GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QuUrLjv*C{Z|^p8HaRdjTwH7) zC?wLlL}}I{)n%R&r+1}IGmDnq;&J#%V6)9VsYhS`O^BVBQlxOUep0c$RENLq#g8A$ z)z7%K_bI&n@J+X_=x}fJoEKed-$<>=ZI-;YrdjIl`U`uzuDWSP?o#Dmo{%SgM#oan kX~E1%D-|#H#QbHoIja2U-MgvsK&LQxy85}Sb4q9e0Efg%P5=M^ literal 0 HcmV?d00001 diff --git a/latest/tab_sd.png b/latest/tab_sd.png new file mode 100644 index 0000000000000000000000000000000000000000..757a565ced4730f85c833fb2547d8e199ae68f19 GIT binary patch literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!Qq7(&jv*C{Z|_!fH5o7*c=%9% zcILh!EA=pAQKdx-Cdiev=v{eg{8Ht<{e8_NAN~b=)%W>-WDCE0PyDHGemi$BoXwcK z{>e9^za6*c1ilttWw&V+U;WCPlV9{LdC~Ey%_H(qj`xgfES(4Yz5jSTZfCt`4E$0YRsR*S^mTCR^;V&sxC8{l_Cp7w8-YPgg&ebxsLQ00$vXK>z>% literal 0 HcmV?d00001 diff --git a/latest/tabs.css b/latest/tabs.css new file mode 100644 index 00000000..71c8a470 --- /dev/null +++ b/latest/tabs.css @@ -0,0 +1 @@ +.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.main-menu-btn{position:relative;display:inline-block;width:36px;height:36px;text-indent:36px;margin-left:8px;white-space:nowrap;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0)}.main-menu-btn-icon,.main-menu-btn-icon:before,.main-menu-btn-icon:after{position:absolute;top:50%;left:2px;height:2px;width:24px;background:var(--nav-menu-button-color);-webkit-transition:all .25s;transition:all .25s}.main-menu-btn-icon:before{content:'';top:-7px;left:0}.main-menu-btn-icon:after{content:'';top:7px;left:0}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon{height:0}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon:before{top:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon:after{top:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}#main-menu-state{position:absolute;width:1px;height:1px;margin:-1px;border:0;padding:0;overflow:hidden;clip:rect(1px,1px,1px,1px)}#main-menu-state:not(:checked) ~ #main-menu{display:none}#main-menu-state:checked ~ #main-menu{display:block}@media(min-width:768px){.main-menu-btn{position:absolute;top:-99999px}#main-menu-state:not(:checked) ~ #main-menu{display:block}}.sm-dox{background-image:var(--nav-gradient-image)}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0 12px;padding-right:43px;font-family:var(--font-family-nav);font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:var(--nav-text-normal-shadow);color:var(--nav-text-normal-color);outline:0}.sm-dox a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox a.current{color:#d23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace !important;text-align:center;text-shadow:none;background:var(--nav-menu-toggle-color);-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox a span.sub-arrow:before{display:block;content:'+'}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px;border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0;border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox ul{background:var(--nav-menu-background-color)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:var(--nav-menu-background-color);background-image:none}.sm-dox ul a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:0 1px 1px black}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media(min-width:768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:var(--nav-gradient-image);line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:var(--nav-text-normal-color) transparent transparent transparent;background:transparent;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0 12px;background-image:var(--nav-separator-image);background-repeat:no-repeat;background-position:right;-moz-border-radius:0 !important;-webkit-border-radius:0;border-radius:0 !important}.sm-dox a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox a:hover span.sub-arrow{border-color:var(--nav-text-hover-color) transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent var(--nav-menu-background-color) transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:var(--nav-menu-background-color);-moz-border-radius:5px !important;-webkit-border-radius:5px;border-radius:5px !important;-moz-box-shadow:0 5px 9px rgba(0,0,0,0.2);-webkit-box-shadow:0 5px 9px rgba(0,0,0,0.2);box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent var(--nav-menu-foreground-color);border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:var(--nav-menu-foreground-color);background-image:none;border:0 !important;color:var(--nav-menu-foreground-color);background-image:none}.sm-dox ul a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent var(--nav-text-hover-color)}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:var(--nav-menu-background-color);height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #d23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#d23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent var(--nav-menu-foreground-color) transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:var(--nav-menu-foreground-color) transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px !important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:var(--nav-gradient-image)}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:var(--nav-menu-background-color)}} \ No newline at end of file diff --git a/v1.3.0/annotated.html b/v1.3.0/annotated.html new file mode 100644 index 00000000..fd3b477e --- /dev/null +++ b/v1.3.0/annotated.html @@ -0,0 +1,125 @@ + + + + + + + +coreMQTT Agent: Data Structures + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Data Structures
+
+
+
Here are the data structures with brief descriptions:
+ + + + + + + + + + +
 CMQTTAgentAckInfo_tInformation for a pending MQTT ack packet expected by the agent
 CMQTTAgentCommand_tThe commands sent from the APIs to the MQTT agent task
 CMQTTAgentCommandFuncReturns_tA structure of values and flags expected to be returned by command functions
 CMQTTAgentCommandInfo_tStruct holding arguments that are common to every command
 CMQTTAgentConnectArgs_tStruct holding arguments for a CONNECT call
 CMQTTAgentContext_tInformation used by each MQTT agent. A context will be initialized by MQTTAgent_Init(), and every API function will accept a pointer to the initalized struct
 CMQTTAgentMessageInterface_tFunction pointers and contexts used for sending and receiving commands, and allocating memory for them
 CMQTTAgentReturnInfo_tStruct holding return codes and outputs from a command
 CMQTTAgentSubscribeArgs_tStruct holding arguments for a SUBSCRIBE or UNSUBSCRIBE call
+
+
+
+ + + + diff --git a/v1.3.0/bc_s.png b/v1.3.0/bc_s.png new file mode 100644 index 0000000000000000000000000000000000000000..224b29aa9847d5a4b3902efd602b7ddf7d33e6c2 GIT binary patch literal 676 zcmV;V0$crwP)y__>=_9%My z{n931IS})GlGUF8K#6VIbs%684A^L3@%PlP2>_sk`UWPq@f;rU*V%rPy_ekbhXT&s z(GN{DxFv}*vZp`F>S!r||M`I*nOwwKX+BC~3P5N3-)Y{65c;ywYiAh-1*hZcToLHK ztpl1xomJ+Yb}K(cfbJr2=GNOnT!UFA7Vy~fBz8?J>XHsbZoDad^8PxfSa0GDgENZS zuLCEqzb*xWX2CG*b&5IiO#NzrW*;`VC9455M`o1NBh+(k8~`XCEEoC1Ybwf;vr4K3 zg|EB<07?SOqHp9DhLpS&bzgo70I+ghB_#)K7H%AMU3v}xuyQq9&Bm~++VYhF09a+U zl7>n7Jjm$K#b*FONz~fj;I->Bf;ule1prFN9FovcDGBkpg>)O*-}eLnC{6oZHZ$o% zXKW$;0_{8hxHQ>l;_*HATI(`7t#^{$(zLe}h*mqwOc*nRY9=?Sx4OOeVIfI|0V(V2 zBrW#G7Ss9wvzr@>H*`r>zE z+e8bOBgqIgldUJlG(YUDviMB`9+DH8n-s9SXRLyJHO1!=wY^79WYZMTa(wiZ!zP66 zA~!21vmF3H2{ngD;+`6j#~6j;$*f*G_2ZD1E;9(yaw7d-QnSCpK(cR1zU3qU0000< KMNUMnLSTYoA~SLT literal 0 HcmV?d00001 diff --git a/v1.3.0/bc_sd.png b/v1.3.0/bc_sd.png new file mode 100644 index 0000000000000000000000000000000000000000..31ca888dc71049713b35c351933a8d0f36180bf1 GIT binary patch literal 635 zcmV->0)+jEP)Jwi0r1~gdSq#w{Bu1q z`craw(p2!hu$4C_$Oc3X(sI6e=9QSTwPt{G) z=htT&^~&c~L2~e{r5_5SYe7#Is-$ln>~Kd%$F#tC65?{LvQ}8O`A~RBB0N~`2M+waajO;5>3B&-viHGJeEK2TQOiPRa zfDKyqwMc4wfaEh4jt>H`nW_Zidwk@Bowp`}(VUaj-pSI(-1L>FJVsX}Yl9~JsqgsZ zUD9(rMwf23Gez6KPa|wwInZodP-2}9@fK0Ga_9{8SOjU&4l`pH4@qlQp83>>HT$xW zER^U>)MyV%t(Lu=`d=Y?{k1@}&r7ZGkFQ%z%N+sE9BtYjovzxyxCPxN6&@wLK{soQ zSmkj$aLI}miuE^p@~4}mg9OjDfGEkgY4~^XzLRUBB*O{+&vq<3v(E%+k_i%=`~j%{ Vj14gnt9}3g002ovPDHLkV1n!oC4m3{ literal 0 HcmV?d00001 diff --git a/v1.3.0/bdwn.png b/v1.3.0/bdwn.png new file mode 100644 index 0000000000000000000000000000000000000000..940a0b950443a0bb1b216ac03c45b8a16c955452 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)H!3HEvS)PKZC{Gv1kP61Pb5HX&C2wk~_T + + + + + + +coreMQTT Agent: Data Structure Index + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ + + + + + diff --git a/v1.3.0/closed.png b/v1.3.0/closed.png new file mode 100644 index 0000000000000000000000000000000000000000..98cc2c909da37a6df914fbf67780eebd99c597f5 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{V-kvUwAr*{o@8{^CZMh(5KoB^r_<4^zF@3)Cp&&t3hdujKf f*?bjBoY!V+E))@{xMcbjXe@)LtDnm{r-UW|*e5JT literal 0 HcmV?d00001 diff --git a/v1.3.0/coreMQTT/annotated.html b/v1.3.0/coreMQTT/annotated.html new file mode 100644 index 00000000..968de672 --- /dev/null +++ b/v1.3.0/coreMQTT/annotated.html @@ -0,0 +1,126 @@ + + + + + + + +coreMQTT: Data Structures + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Data Structures
+
+
+
Here are the data structures with brief descriptions:
+ + + + + + + + + + + +
 CMQTTConnectInfo_tMQTT CONNECT packet parameters
 CMQTTContext_tA struct representing an MQTT connection
 CMQTTDeserializedInfo_tStruct to hold deserialized packet information for an MQTTEventCallback_t callback
 CMQTTFixedBuffer_tBuffer passed to MQTT library
 CMQTTPacketInfo_tMQTT incoming packet parameters
 CMQTTPubAckInfo_tAn element of the state engine records for QoS 1 or Qos 2 publishes
 CMQTTPublishInfo_tMQTT PUBLISH packet parameters
 CMQTTSubscribeInfo_tMQTT SUBSCRIBE packet parameters
 CTransportInterface_tThe transport layer interface
 CTransportOutVector_tTransport vector structure for sending multiple messages
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/bc_s.png b/v1.3.0/coreMQTT/bc_s.png new file mode 100644 index 0000000000000000000000000000000000000000..224b29aa9847d5a4b3902efd602b7ddf7d33e6c2 GIT binary patch literal 676 zcmV;V0$crwP)y__>=_9%My z{n931IS})GlGUF8K#6VIbs%684A^L3@%PlP2>_sk`UWPq@f;rU*V%rPy_ekbhXT&s z(GN{DxFv}*vZp`F>S!r||M`I*nOwwKX+BC~3P5N3-)Y{65c;ywYiAh-1*hZcToLHK ztpl1xomJ+Yb}K(cfbJr2=GNOnT!UFA7Vy~fBz8?J>XHsbZoDad^8PxfSa0GDgENZS zuLCEqzb*xWX2CG*b&5IiO#NzrW*;`VC9455M`o1NBh+(k8~`XCEEoC1Ybwf;vr4K3 zg|EB<07?SOqHp9DhLpS&bzgo70I+ghB_#)K7H%AMU3v}xuyQq9&Bm~++VYhF09a+U zl7>n7Jjm$K#b*FONz~fj;I->Bf;ule1prFN9FovcDGBkpg>)O*-}eLnC{6oZHZ$o% zXKW$;0_{8hxHQ>l;_*HATI(`7t#^{$(zLe}h*mqwOc*nRY9=?Sx4OOeVIfI|0V(V2 zBrW#G7Ss9wvzr@>H*`r>zE z+e8bOBgqIgldUJlG(YUDviMB`9+DH8n-s9SXRLyJHO1!=wY^79WYZMTa(wiZ!zP66 zA~!21vmF3H2{ngD;+`6j#~6j;$*f*G_2ZD1E;9(yaw7d-QnSCpK(cR1zU3qU0000< KMNUMnLSTYoA~SLT literal 0 HcmV?d00001 diff --git a/v1.3.0/coreMQTT/bc_sd.png b/v1.3.0/coreMQTT/bc_sd.png new file mode 100644 index 0000000000000000000000000000000000000000..31ca888dc71049713b35c351933a8d0f36180bf1 GIT binary patch literal 635 zcmV->0)+jEP)Jwi0r1~gdSq#w{Bu1q z`craw(p2!hu$4C_$Oc3X(sI6e=9QSTwPt{G) z=htT&^~&c~L2~e{r5_5SYe7#Is-$ln>~Kd%$F#tC65?{LvQ}8O`A~RBB0N~`2M+waajO;5>3B&-viHGJeEK2TQOiPRa zfDKyqwMc4wfaEh4jt>H`nW_Zidwk@Bowp`}(VUaj-pSI(-1L>FJVsX}Yl9~JsqgsZ zUD9(rMwf23Gez6KPa|wwInZodP-2}9@fK0Ga_9{8SOjU&4l`pH4@qlQp83>>HT$xW zER^U>)MyV%t(Lu=`d=Y?{k1@}&r7ZGkFQ%z%N+sE9BtYjovzxyxCPxN6&@wLK{soQ zSmkj$aLI}miuE^p@~4}mg9OjDfGEkgY4~^XzLRUBB*O{+&vq<3v(E%+k_i%=`~j%{ Vj14gnt9}3g002ovPDHLkV1n!oC4m3{ literal 0 HcmV?d00001 diff --git a/v1.3.0/coreMQTT/bdwn.png b/v1.3.0/coreMQTT/bdwn.png new file mode 100644 index 0000000000000000000000000000000000000000..940a0b950443a0bb1b216ac03c45b8a16c955452 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)H!3HEvS)PKZC{Gv1kP61Pb5HX&C2wk~_T + + + + + + +coreMQTT: Data Structure Index + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Data Structure Index
+
+ +
+ + + + diff --git a/v1.3.0/coreMQTT/closed.png b/v1.3.0/coreMQTT/closed.png new file mode 100644 index 0000000000000000000000000000000000000000..98cc2c909da37a6df914fbf67780eebd99c597f5 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{V-kvUwAr*{o@8{^CZMh(5KoB^r_<4^zF@3)Cp&&t3hdujKf f*?bjBoY!V+E))@{xMcbjXe@)LtDnm{r-UW|*e5JT literal 0 HcmV?d00001 diff --git a/v1.3.0/coreMQTT/core__mqtt_8c.html b/v1.3.0/coreMQTT/core__mqtt_8c.html new file mode 100644 index 00000000..5914e832 --- /dev/null +++ b/v1.3.0/coreMQTT/core__mqtt_8c.html @@ -0,0 +1,2824 @@ + + + + + + + +coreMQTT: core_mqtt.c File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt.c File Reference
+
+
+ +

Implements the user-facing functions in core_mqtt.h. +More...

+
#include <string.h>
+#include <assert.h>
+#include "core_mqtt.h"
+#include "core_mqtt_state.h"
+#include "core_mqtt_config_defaults.h"
+
+ + + + + + + + + + + + + + + + + + + + + + +

+Macros

+#define MQTT_PRE_SEND_HOOK(pContext)
 Hook called before a 'send' operation is executed.
 
+#define MQTT_POST_SEND_HOOK(pContext)
 Hook called after the 'send' operation is complete.
 
+#define MQTT_PRE_STATE_UPDATE_HOOK(pContext)
 Hook called just before an update to the MQTT state is made.
 
+#define MQTT_POST_STATE_UPDATE_HOOK(pContext)
 Hook called just after an update to the MQTT state has been made.
 
+#define CORE_MQTT_SERIALIZED_LENGTH_FIELD_BYTES   ( 2U )
 Bytes required to encode any string length in an MQTT packet header. Length is always encoded in two bytes according to the MQTT specification.
 
#define CORE_MQTT_SUBSCRIBE_PER_TOPIC_VECTOR_LENGTH   ( 3U )
 Number of vectors required to encode one topic filter in a subscribe request. Three vectors are required as there are three fields in the subscribe request namely:
 
#define CORE_MQTT_UNSUBSCRIBE_PER_TOPIC_VECTOR_LENGTH   ( 2U )
 Number of vectors required to encode one topic filter in an unsubscribe request. Two vectors are required as there are two fields in the unsubscribe request namely:
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

static int32_t sendBuffer (MQTTContext_t *pContext, const uint8_t *pBufferToSend, size_t bytesToSend)
 Sends provided buffer to network using transport send.
 
static MQTTStatus_t sendConnectWithoutCopy (MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength)
 Sends MQTT connect without copying the users data into any buffer.
 
static int32_t sendMessageVector (MQTTContext_t *pContext, TransportOutVector_t *pIoVec, size_t ioVecCount)
 Sends the vector array passed through the parameters over the network.
 
static size_t addEncodedStringToVector (uint8_t serializedLength[CORE_MQTT_SERIALIZED_LENGTH_FIELD_BYTES], const char *const string, uint16_t length, TransportOutVector_t *iterator, size_t *updatedLength)
 Add a string and its length after serializing it in a manner outlined by the MQTT specification.
 
static MQTTStatus_t sendSubscribeWithoutCopy (MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength)
 Send MQTT SUBSCRIBE message without copying the user data into a buffer and directly sending it.
 
static MQTTStatus_t sendUnsubscribeWithoutCopy (MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength)
 Send MQTT UNSUBSCRIBE message without copying the user data into a buffer and directly sending it.
 
static uint32_t calculateElapsedTime (uint32_t later, uint32_t start)
 Calculate the interval between two millisecond timestamps, including when the later value has overflowed.
 
static MQTTPubAckType_t getAckFromPacketType (uint8_t packetType)
 Convert a byte indicating a publish ack type to an MQTTPubAckType_t.
 
static int32_t recvExact (const MQTTContext_t *pContext, size_t bytesToRecv)
 Receive bytes into the network buffer.
 
static MQTTStatus_t discardPacket (const MQTTContext_t *pContext, size_t remainingLength, uint32_t timeoutMs)
 Discard a packet from the transport interface.
 
static MQTTStatus_t discardStoredPacket (MQTTContext_t *pContext, const MQTTPacketInfo_t *pPacketInfo)
 Discard a packet from the MQTT buffer and the transport interface.
 
static MQTTStatus_t receivePacket (const MQTTContext_t *pContext, MQTTPacketInfo_t incomingPacket, uint32_t remainingTimeMs)
 Receive a packet from the transport interface.
 
static uint8_t getAckTypeToSend (MQTTPublishState_t state)
 Get the correct ack type to send.
 
static MQTTStatus_t sendPublishAcks (MQTTContext_t *pContext, uint16_t packetId, MQTTPublishState_t publishState)
 Send acks for received QoS 1/2 publishes.
 
static MQTTStatus_t handleKeepAlive (MQTTContext_t *pContext)
 Send a keep alive PINGREQ if the keep alive interval has elapsed.
 
static MQTTStatus_t handleIncomingPublish (MQTTContext_t *pContext, MQTTPacketInfo_t *pIncomingPacket)
 Handle received MQTT PUBLISH packet.
 
static MQTTStatus_t handlePublishAcks (MQTTContext_t *pContext, MQTTPacketInfo_t *pIncomingPacket)
 Handle received MQTT publish acks.
 
static MQTTStatus_t handleIncomingAck (MQTTContext_t *pContext, MQTTPacketInfo_t *pIncomingPacket, bool manageKeepAlive)
 Handle received MQTT ack.
 
static MQTTStatus_t receiveSingleIteration (MQTTContext_t *pContext, bool manageKeepAlive)
 Run a single iteration of the receive loop.
 
static MQTTStatus_t validateSubscribeUnsubscribeParams (const MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
 Validates parameters of MQTT_Subscribe or MQTT_Unsubscribe.
 
static MQTTStatus_t receiveConnack (const MQTTContext_t *pContext, uint32_t timeoutMs, bool cleanSession, MQTTPacketInfo_t *pIncomingPacket, bool *pSessionPresent)
 Receives a CONNACK MQTT packet.
 
static MQTTStatus_t handleSessionResumption (MQTTContext_t *pContext, bool sessionPresent)
 Resends pending acks for a re-established MQTT session, or clears existing state records for a clean session.
 
static MQTTStatus_t sendPublishWithoutCopy (MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, const uint8_t *pMqttHeader, size_t headerSize, uint16_t packetId)
 Send the publish packet without copying the topic string and payload in the buffer.
 
static MQTTStatus_t validatePublishParams (const MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId)
 Function to validate MQTT_Publish parameters.
 
static bool matchEndWildcardsSpecialCases (const char *pTopicFilter, uint16_t topicFilterLength, uint16_t filterIndex)
 Performs matching for special cases when a topic filter ends with a wildcard character.
 
static bool matchWildcards (const char *pTopicName, uint16_t topicNameLength, const char *pTopicFilter, uint16_t topicFilterLength, uint16_t *pNameIndex, uint16_t *pFilterIndex, bool *pMatch)
 Attempt to match topic name with a topic filter starting with a wildcard.
 
static bool matchTopicFilter (const char *pTopicName, uint16_t topicNameLength, const char *pTopicFilter, uint16_t topicFilterLength)
 Match a topic name and topic filter allowing the use of wildcards.
 
MQTTStatus_t MQTT_Init (MQTTContext_t *pContext, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getTimeFunction, MQTTEventCallback_t userCallback, const MQTTFixedBuffer_t *pNetworkBuffer)
 Initialize an MQTT context.
 
MQTTStatus_t MQTT_InitStatefulQoS (MQTTContext_t *pContext, MQTTPubAckInfo_t *pOutgoingPublishRecords, size_t outgoingPublishCount, MQTTPubAckInfo_t *pIncomingPublishRecords, size_t incomingPublishCount)
 Initialize an MQTT context for QoS > 0.
 
MQTTStatus_t MQTT_CancelCallback (const MQTTContext_t *pContext, uint16_t packetId)
 Cancels an outgoing publish callback (only for QoS > QoS0) by removing it from the pending ACK list.
 
MQTTStatus_t MQTT_Connect (MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
 Establish an MQTT session.
 
MQTTStatus_t MQTT_Subscribe (MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
 Sends MQTT SUBSCRIBE for the given list of topic filters to the broker.
 
MQTTStatus_t MQTT_Publish (MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId)
 Publishes a message to the given topic name.
 
MQTTStatus_t MQTT_Ping (MQTTContext_t *pContext)
 Sends an MQTT PINGREQ to broker.
 
MQTTStatus_t MQTT_Unsubscribe (MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
 Sends MQTT UNSUBSCRIBE for the given list of topic filters to the broker.
 
MQTTStatus_t MQTT_Disconnect (MQTTContext_t *pContext)
 Disconnect an MQTT session.
 
MQTTStatus_t MQTT_ProcessLoop (MQTTContext_t *pContext)
 Loop to receive packets from the transport interface. Handles keep alive.
 
MQTTStatus_t MQTT_ReceiveLoop (MQTTContext_t *pContext)
 Loop to receive packets from the transport interface. Does not handle keep alive.
 
uint16_t MQTT_GetPacketId (MQTTContext_t *pContext)
 Get a packet ID that is valid according to the MQTT 3.1.1 spec.
 
MQTTStatus_t MQTT_MatchTopic (const char *pTopicName, const uint16_t topicNameLength, const char *pTopicFilter, const uint16_t topicFilterLength, bool *pIsMatch)
 A utility function that determines whether the passed topic filter and topic name match according to the MQTT 3.1.1 protocol specification.
 
MQTTStatus_t MQTT_GetSubAckStatusCodes (const MQTTPacketInfo_t *pSubackPacket, uint8_t **pPayloadStart, size_t *pPayloadSize)
 Parses the payload of an MQTT SUBACK packet that contains status codes corresponding to topic filter subscription requests from the original subscribe packet.
 
const char * MQTT_Status_strerror (MQTTStatus_t status)
 Error code to string conversion for MQTT statuses.
 
+

Detailed Description

+

Implements the user-facing functions in core_mqtt.h.

+

Macro Definition Documentation

+ +

◆ CORE_MQTT_SUBSCRIBE_PER_TOPIC_VECTOR_LENGTH

+ +
+
+ + + + +
#define CORE_MQTT_SUBSCRIBE_PER_TOPIC_VECTOR_LENGTH   ( 3U )
+
+ +

Number of vectors required to encode one topic filter in a subscribe request. Three vectors are required as there are three fields in the subscribe request namely:

+
    +
  1. Topic filter length; 2. Topic filter; and 3. QoS in this order.
  2. +
+ +
+
+ +

◆ CORE_MQTT_UNSUBSCRIBE_PER_TOPIC_VECTOR_LENGTH

+ +
+
+ + + + +
#define CORE_MQTT_UNSUBSCRIBE_PER_TOPIC_VECTOR_LENGTH   ( 2U )
+
+ +

Number of vectors required to encode one topic filter in an unsubscribe request. Two vectors are required as there are two fields in the unsubscribe request namely:

+
    +
  1. Topic filter length; and 2. Topic filter in this order.
  2. +
+ +
+
+

Function Documentation

+ +

◆ sendBuffer()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static int32_t sendBuffer (MQTTContext_tpContext,
const uint8_t * pBufferToSend,
size_t bytesToSend 
)
+
+static
+
+ +

Sends provided buffer to network using transport send.

+

param[in] pContext Initialized MQTT context.

+

param[in] pBufferToSend Buffer to be sent to network.

+

param[in] bytesToSend Number of bytes to be sent.

+
Note
This operation may call the transport send function repeatedly to send bytes over the network until either:
    +
  1. The requested number of bytes bytesToSend have been sent. OR
  2. +
  3. MQTT_SEND_TIMEOUT_MS milliseconds have gone by since entering this function. OR
  4. +
  5. There is an error in sending data over the network.
  6. +
+
+
Returns
Total number of bytes sent, or negative value on network error.
+ +
+
+ +

◆ sendConnectWithoutCopy()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t sendConnectWithoutCopy (MQTTContext_tpContext,
const MQTTConnectInfo_tpConnectInfo,
const MQTTPublishInfo_tpWillInfo,
size_t remainingLength 
)
+
+static
+
+ +

Sends MQTT connect without copying the users data into any buffer.

+

param[in] pContext Initialized MQTT context.

+

param[in] pConnectInfo MQTT CONNECT packet information.

+

param[in] pWillInfo Last Will and Testament. Pass NULL if Last Will and Testament is not used.

+

param[in] remainingLength the length of the connect packet.

+
Note
This operation may call the transport send function repeatedly to send bytes over the network until either:
    +
  1. The requested number of bytes remainingLength have been sent. OR
  2. +
  3. MQTT_SEND_TIMEOUT_MS milliseconds have gone by since entering this function. OR
  4. +
  5. There is an error in sending data over the network.
  6. +
+
+
Returns
MQTTSendFailed or MQTTSuccess.
+ +
+
+ +

◆ sendMessageVector()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static int32_t sendMessageVector (MQTTContext_tpContext,
TransportOutVector_tpIoVec,
size_t ioVecCount 
)
+
+static
+
+ +

Sends the vector array passed through the parameters over the network.

+
Note
The preference is given to 'writev' function if it is present in the transport interface. Otherwise, a send call is made repeatedly to achieve the result.
+
Parameters
+ + + + +
[in]pContextInitialized MQTT context.
[in]pIoVecThe vector array to be sent.
[in]ioVecCountThe number of elements in the array.
+
+
+
Note
This operation may call the transport send or writev functions repeatedly to send bytes over the network until either:
    +
  1. The requested number of bytes have been sent. OR
  2. +
  3. MQTT_SEND_TIMEOUT_MS milliseconds have gone by since entering this function. OR
  4. +
  5. There is an error in sending data over the network.
  6. +
+
+
Returns
The total number of bytes sent or the error code as received from the transport interface.
+ +
+
+ +

◆ addEncodedStringToVector()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static size_t addEncodedStringToVector (uint8_t serializedLength[CORE_MQTT_SERIALIZED_LENGTH_FIELD_BYTES],
const char *const string,
uint16_t length,
TransportOutVector_titerator,
size_t * updatedLength 
)
+
+static
+
+ +

Add a string and its length after serializing it in a manner outlined by the MQTT specification.

+
Parameters
+ + + + + + +
[in]serializedLengthArray of two bytes to which the vector will point. The array must remain in scope until the message has been sent.
[in]stringThe string to be serialized.
[in]lengthThe length of the string to be serialized.
[in]iteratorThe iterator pointing to the first element in the transport interface IO array.
[out]updatedLengthThis parameter will be added to with the number of bytes added to the vector.
+
+
+
Returns
The number of vectors added.
+ +
+
+ +

◆ sendSubscribeWithoutCopy()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t sendSubscribeWithoutCopy (MQTTContext_tpContext,
const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId,
size_t remainingLength 
)
+
+static
+
+ +

Send MQTT SUBSCRIBE message without copying the user data into a buffer and directly sending it.

+
Parameters
+ + + + + + +
[in]pContextInitialized MQTT context.
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe count of elements in the list.
[in]packetIdThe packet ID of the subscribe packet
[in]remainingLengthThe remaining length of the subscribe packet.
+
+
+
Returns
MQTTSuccess or MQTTSendFailed.
+ +
+
+ +

◆ sendUnsubscribeWithoutCopy()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t sendUnsubscribeWithoutCopy (MQTTContext_tpContext,
const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId,
size_t remainingLength 
)
+
+static
+
+ +

Send MQTT UNSUBSCRIBE message without copying the user data into a buffer and directly sending it.

+
Parameters
+ + + + + + +
[in]pContextInitialized MQTT context.
[in]pSubscriptionListMQTT subscription info.
[in]subscriptionCountThe count of elements in the list.
[in]packetIdThe packet ID of the unsubscribe packet.
[in]remainingLengthThe remaining length of the unsubscribe packet.
+
+
+
Returns
MQTTSuccess or MQTTSendFailed.
+ +
+
+ +

◆ calculateElapsedTime()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static uint32_t calculateElapsedTime (uint32_t later,
uint32_t start 
)
+
+static
+
+ +

Calculate the interval between two millisecond timestamps, including when the later value has overflowed.

+
Note
In C, the operands are promoted to signed integers in subtraction. Using this function avoids the need to cast the result of subtractions back to uint32_t.
+
Parameters
+ + + +
[in]laterThe later time stamp, in milliseconds.
[in]startThe earlier time stamp, in milliseconds.
+
+
+
Returns
later - start.
+ +
+
+ +

◆ getAckFromPacketType()

+ +
+
+ + + + + +
+ + + + + + + + +
static MQTTPubAckType_t getAckFromPacketType (uint8_t packetType)
+
+static
+
+ +

Convert a byte indicating a publish ack type to an MQTTPubAckType_t.

+
Parameters
+ + +
[in]packetTypeFirst byte of fixed header.
+
+
+
Returns
Type of ack.
+ +
+
+ +

◆ recvExact()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static int32_t recvExact (const MQTTContext_tpContext,
size_t bytesToRecv 
)
+
+static
+
+ +

Receive bytes into the network buffer.

+
Parameters
+ + + +
[in]pContextInitialized MQTT Context.
[in]bytesToRecvNumber of bytes to receive.
+
+
+
Note
This operation calls the transport receive function repeatedly to read bytes from the network until either:
    +
  1. The requested number of bytes bytesToRecv are read. OR
  2. +
  3. No data is received from the network for MQTT_RECV_POLLING_TIMEOUT_MS duration.
                OR
    +
  4. +
  5. There is an error in reading from the network.
  6. +
+
+
Returns
Number of bytes received, or negative number on network error.
+ +
+
+ +

◆ discardPacket()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t discardPacket (const MQTTContext_tpContext,
size_t remainingLength,
uint32_t timeoutMs 
)
+
+static
+
+ +

Discard a packet from the transport interface.

+
Parameters
+ + + + +
[in]pContextMQTT Connection context.
[in]remainingLengthRemaining length of the packet to dump.
[in]timeoutMsTime remaining to discard the packet.
+
+
+
Returns
MQTTRecvFailed or MQTTNoDataAvailable.
+ +
+
+ +

◆ discardStoredPacket()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTStatus_t discardStoredPacket (MQTTContext_tpContext,
const MQTTPacketInfo_tpPacketInfo 
)
+
+static
+
+ +

Discard a packet from the MQTT buffer and the transport interface.

+
Parameters
+ + + +
[in]pContextMQTT Connection context.
[in]pPacketInfoInformation struct of the packet to be discarded.
+
+
+
Returns
MQTTRecvFailed or MQTTNoDataAvailable.
+ +
+
+ +

◆ receivePacket()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t receivePacket (const MQTTContext_tpContext,
MQTTPacketInfo_t incomingPacket,
uint32_t remainingTimeMs 
)
+
+static
+
+ +

Receive a packet from the transport interface.

+
Parameters
+ + + + +
[in]pContextMQTT Connection context.
[in]incomingPacketpacket struct with remaining length.
[in]remainingTimeMsTime remaining to receive the packet.
+
+
+
Returns
MQTTSuccess or MQTTRecvFailed.
+ +
+
+ +

◆ getAckTypeToSend()

+ +
+
+ + + + + +
+ + + + + + + + +
static uint8_t getAckTypeToSend (MQTTPublishState_t state)
+
+static
+
+ +

Get the correct ack type to send.

+
Parameters
+ + +
[in]stateCurrent state of publish.
+
+
+
Returns
Packet Type byte of PUBACK, PUBREC, PUBREL, or PUBCOMP if one of those should be sent, else 0.
+ +
+
+ +

◆ sendPublishAcks()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t sendPublishAcks (MQTTContext_tpContext,
uint16_t packetId,
MQTTPublishState_t publishState 
)
+
+static
+
+ +

Send acks for received QoS 1/2 publishes.

+
Parameters
+ + + + +
[in]pContextMQTT Connection context.
[in]packetIdpacket ID of original PUBLISH.
[in]publishStateCurrent publish state in record.
+
+
+
Returns
MQTTSuccess, MQTTIllegalState or MQTTSendFailed.
+ +
+
+ +

◆ handleKeepAlive()

+ +
+
+ + + + + +
+ + + + + + + + +
static MQTTStatus_t handleKeepAlive (MQTTContext_tpContext)
+
+static
+
+ +

Send a keep alive PINGREQ if the keep alive interval has elapsed.

+
Parameters
+ + +
[in]pContextInitialized MQTT Context.
+
+
+
Returns
MQTTKeepAliveTimeout if a PINGRESP is not received in time, MQTTSendFailed if the PINGREQ cannot be sent, or MQTTSuccess.
+ +
+
+ +

◆ handleIncomingPublish()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTStatus_t handleIncomingPublish (MQTTContext_tpContext,
MQTTPacketInfo_tpIncomingPacket 
)
+
+static
+
+ +

Handle received MQTT PUBLISH packet.

+
Parameters
+ + + +
[in]pContextMQTT Connection context.
[in]pIncomingPacketIncoming packet.
+
+
+
Returns
MQTTSuccess, MQTTIllegalState or deserialization error.
+ +
+
+ +

◆ handlePublishAcks()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTStatus_t handlePublishAcks (MQTTContext_tpContext,
MQTTPacketInfo_tpIncomingPacket 
)
+
+static
+
+ +

Handle received MQTT publish acks.

+
Parameters
+ + + +
[in]pContextMQTT Connection context.
[in]pIncomingPacketIncoming packet.
+
+
+
Returns
MQTTSuccess, MQTTIllegalState, or deserialization error.
+ +
+
+ +

◆ handleIncomingAck()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t handleIncomingAck (MQTTContext_tpContext,
MQTTPacketInfo_tpIncomingPacket,
bool manageKeepAlive 
)
+
+static
+
+ +

Handle received MQTT ack.

+
Parameters
+ + + + +
[in]pContextMQTT Connection context.
[in]pIncomingPacketIncoming packet.
[in]manageKeepAliveFlag indicating if PINGRESPs should not be given to the application
+
+
+
Returns
MQTTSuccess, MQTTIllegalState, or deserialization error.
+ +
+
+ +

◆ receiveSingleIteration()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTStatus_t receiveSingleIteration (MQTTContext_tpContext,
bool manageKeepAlive 
)
+
+static
+
+ +

Run a single iteration of the receive loop.

+
Parameters
+ + + +
[in]pContextMQTT Connection context.
[in]manageKeepAliveFlag indicating if keep alive should be handled.
+
+
+
Returns
MQTTRecvFailed if a network error occurs during reception; MQTTSendFailed if a network error occurs while sending an ACK or PINGREQ; MQTTBadResponse if an invalid packet is received; MQTTKeepAliveTimeout if the server has not sent a PINGRESP before MQTT_PINGRESP_TIMEOUT_MS milliseconds; MQTTIllegalState if an incoming QoS 1/2 publish or ack causes an invalid transition for the internal state machine; MQTTSuccess on success.
+ +
+
+ +

◆ validateSubscribeUnsubscribeParams()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t validateSubscribeUnsubscribeParams (const MQTTContext_tpContext,
const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId 
)
+
+static
+
+ +

Validates parameters of MQTT_Subscribe or MQTT_Unsubscribe.

+
Parameters
+ + + + + +
[in]pContextInitialized MQTT context.
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdPacket identifier.
+
+
+
Returns
MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+ +
+
+ +

◆ receiveConnack()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t receiveConnack (const MQTTContext_tpContext,
uint32_t timeoutMs,
bool cleanSession,
MQTTPacketInfo_tpIncomingPacket,
bool * pSessionPresent 
)
+
+static
+
+ +

Receives a CONNACK MQTT packet.

+
Parameters
+ + + + + + +
[in]pContextInitialized MQTT context.
[in]timeoutMsTimeout for waiting for CONNACK packet.
[in]cleanSessionClean session flag set by application.
[out]pIncomingPacketList of MQTT subscription info.
[out]pSessionPresentWhether a previous session was present. Only relevant if not establishing a clean session.
+
+
+
Returns
MQTTBadResponse if a bad response is received; MQTTNoDataAvailable if no data available for transport recv;
+

+MQTTRecvFailed if transport recv failed;

+

MQTTSuccess otherwise.

+ +
+
+ +

◆ handleSessionResumption()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTStatus_t handleSessionResumption (MQTTContext_tpContext,
bool sessionPresent 
)
+
+static
+
+ +

Resends pending acks for a re-established MQTT session, or clears existing state records for a clean session.

+
Parameters
+ + + +
[in]pContextInitialized MQTT context.
[in]sessionPresentSession present flag received from the MQTT broker.
+
+
+
Returns
MQTTSendFailed if transport send during resend failed; MQTTSuccess otherwise.
+ +
+
+ +

◆ sendPublishWithoutCopy()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t sendPublishWithoutCopy (MQTTContext_tpContext,
const MQTTPublishInfo_tpPublishInfo,
const uint8_t * pMqttHeader,
size_t headerSize,
uint16_t packetId 
)
+
+static
+
+ +

Send the publish packet without copying the topic string and payload in the buffer.

+

param[in] pContext Initialized MQTT context.

+

param[in] pPublishInfo MQTT PUBLISH packet parameters.

+

param[in] pMqttHeader the serialized MQTT header with the header byte; the encoded length of the packet; and the encoded length of the topic string.

+

param[in] headerSize Size of the serialized PUBLISH header.

+

param[in] packetId Packet Id of the publish packet.

+
Returns
MQTTSendFailed if transport send during resend failed; MQTTSuccess otherwise.
+ +
+
+ +

◆ validatePublishParams()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t validatePublishParams (const MQTTContext_tpContext,
const MQTTPublishInfo_tpPublishInfo,
uint16_t packetId 
)
+
+static
+
+ +

Function to validate MQTT_Publish parameters.

+

param[in] pContext Initialized MQTT context.

+

param[in] pPublishInfo MQTT PUBLISH packet parameters.

+

param[in] packetId Packet Id for the MQTT PUBLISH packet.

+
Returns
MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+ +
+
+ +

◆ matchEndWildcardsSpecialCases()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static bool matchEndWildcardsSpecialCases (const char * pTopicFilter,
uint16_t topicFilterLength,
uint16_t filterIndex 
)
+
+static
+
+ +

Performs matching for special cases when a topic filter ends with a wildcard character.

+

When the topic name has been consumed but there are remaining characters to to match in topic filter, this function handles the following 2 cases:

    +
  • When the topic filter ends with "/+" or "/#" characters, but the topic name only ends with '/'.
  • +
  • When the topic filter ends with "/#" characters, but the topic name ends at the parent level.
  • +
+
Note
This function ASSUMES that the topic name been consumed in linear matching with the topic filer, but the topic filter has remaining characters to be matched.
+
Parameters
+ + + + +
[in]pTopicFilterThe topic filter containing the wildcard.
[in]topicFilterLengthLength of the topic filter being examined.
[in]filterIndexIndex of the topic filter being examined.
+
+
+
Returns
Returns whether the topic filter and the topic name match.
+ +
+
+ +

◆ matchWildcards()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static bool matchWildcards (const char * pTopicName,
uint16_t topicNameLength,
const char * pTopicFilter,
uint16_t topicFilterLength,
uint16_t * pNameIndex,
uint16_t * pFilterIndex,
bool * pMatch 
)
+
+static
+
+ +

Attempt to match topic name with a topic filter starting with a wildcard.

+

If the topic filter starts with a '+' (single-level) wildcard, the function advances the pNameIndex by a level in the topic name. If the topic filter starts with a '#' (multi-level) wildcard, the function concludes that both the topic name and topic filter match.

+
Parameters
+ + + + + + + + +
[in]pTopicNameThe topic name to match.
[in]topicNameLengthLength of the topic name.
[in]pTopicFilterThe topic filter to match.
[in]topicFilterLengthLength of the topic filter.
[in,out]pNameIndexCurrent index in the topic name being examined. It is advanced by one level for + wildcards.
[in,out]pFilterIndexCurrent index in the topic filter being examined. It is advanced to position of '/' level separator for '+' wildcard.
[out]pMatchWhether the topic filter and topic name match.
+
+
+
Returns
true if the caller of this function should exit; false if the caller should continue parsing the topics.
+ +
+
+ +

◆ matchTopicFilter()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static bool matchTopicFilter (const char * pTopicName,
uint16_t topicNameLength,
const char * pTopicFilter,
uint16_t topicFilterLength 
)
+
+static
+
+ +

Match a topic name and topic filter allowing the use of wildcards.

+
Parameters
+ + + + + +
[in]pTopicNameThe topic name to check.
[in]topicNameLengthLength of the topic name.
[in]pTopicFilterThe topic filter to check.
[in]topicFilterLengthLength of topic filter.
+
+
+
Returns
true if the topic name and topic filter match; false otherwise.
+ +
+
+ +

◆ MQTT_Init()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_Init (MQTTContext_tpContext,
const TransportInterface_tpTransportInterface,
MQTTGetCurrentTimeFunc_t getTimeFunction,
MQTTEventCallback_t userCallback,
const MQTTFixedBuffer_tpNetworkBuffer 
)
+
+ +

Initialize an MQTT context.

+

This function must be called on an MQTTContext_t before any other function.

+
Note
The MQTTGetCurrentTimeFunc_t function for querying time must be defined. If there is no time implementation, it is the responsibility of the application to provide a dummy function to always return 0, provide 0 timeouts for all calls to MQTT_Connect, MQTT_ProcessLoop, and MQTT_ReceiveLoop and configure the MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS configurations to be 0. This will result in loop functions running for a single iteration, and MQTT_Connect relying on MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT to receive the CONNACK packet.
+
Parameters
+ + + + + + +
[in]pContextThe context to initialize.
[in]pTransportInterfaceThe transport interface to use with the context.
[in]getTimeFunctionThe time utility function which can return the amount of time (in milliseconds) elapsed since a given epoch. This function will be used to ensure that timeouts in the API calls are met and keep-alive messages are sent on time.
[in]userCallbackThe user callback to use with the context to notify about incoming packet events.
[in]pNetworkBufferNetwork buffer provided for the context. This buffer will be used to receive incoming messages from the broker. This buffer must remain valid and in scope for the entire lifetime of the pContext and must not be used by another context and/or application.
+
+
+
Returns
MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Function for obtaining a timestamp.
+
uint32_t getTimeStampMs();
+
// Callback function for receiving packets.
+
void eventCallback(
+
MQTTContext_t * pContext,
+
MQTTPacketInfo_t * pPacketInfo,
+
MQTTDeserializedInfo_t * pDeserializedInfo
+
);
+
// Network send.
+
int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
+
// Network receive.
+
int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
+
+
MQTTContext_t mqttContext;
+ +
MQTTFixedBuffer_t fixedBuffer;
+
// Create a globally accessible buffer which remains in scope for the entire duration
+
// of the MQTT context.
+
uint8_t buffer[ 1024 ];
+
+
// Clear context.
+
memset( ( void * ) &mqttContext, 0x00, sizeof( MQTTContext_t ) );
+
+
// Set transport interface members.
+
transport.pNetworkContext = &someTransportContext;
+
transport.send = networkSend;
+
transport.recv = networkRecv;
+
+
// Set buffer members.
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = 1024;
+
+
status = MQTT_Init( &mqttContext, &transport, getTimeStampMs, eventCallback, &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// Do something with mqttContext. The transport and fixedBuffer structs were
+
// copied into the context, so the original structs do not need to stay in scope.
+
// However, the memory pointed to by the fixedBuffer.pBuffer must remain in scope.
+
}
+
MQTTStatus_t MQTT_Init(MQTTContext_t *pContext, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getTimeFunction, MQTTEventCallback_t userCallback, const MQTTFixedBuffer_t *pNetworkBuffer)
Initialize an MQTT context.
Definition: core_mqtt.c:2531
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
Struct to hold deserialized packet information for an MQTTEventCallback_t callback.
Definition: core_mqtt.h:257
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+
The transport layer interface.
Definition: transport_interface.h:299
+
TransportSend_t send
Definition: transport_interface.h:301
+
TransportRecv_t recv
Definition: transport_interface.h:300
+
NetworkContext_t * pNetworkContext
Definition: transport_interface.h:303
+
+
+
+ +

◆ MQTT_InitStatefulQoS()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_InitStatefulQoS (MQTTContext_tpContext,
MQTTPubAckInfo_tpOutgoingPublishRecords,
size_t outgoingPublishCount,
MQTTPubAckInfo_tpIncomingPublishRecords,
size_t incomingPublishCount 
)
+
+ +

Initialize an MQTT context for QoS > 0.

+

This function must be called on an MQTTContext_t after MQTT_Init and before any other function.

+
Parameters
+ + + + + + +
[in]pContextThe context to initialize.
[in]pOutgoingPublishRecordsPointer to memory which will be used to store state of outgoing publishes.
[in]outgoingPublishCountMaximum number of records which can be kept in the memory pointed to by pOutgoingPublishRecords.
[in]pIncomingPublishRecordsPointer to memory which will be used to store state of incoming publishes.
[in]incomingPublishCountMaximum number of records which can be kept in the memory pointed to by pIncomingPublishRecords.
+
+
+
Returns
MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Function for obtaining a timestamp.
+
uint32_t getTimeStampMs();
+
// Callback function for receiving packets.
+
void eventCallback(
+
MQTTContext_t * pContext,
+
MQTTPacketInfo_t * pPacketInfo,
+
MQTTDeserializedInfo_t * pDeserializedInfo
+
);
+
// Network send.
+
int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
+
// Network receive.
+
int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
+
+
MQTTContext_t mqttContext;
+ +
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ 1024 ];
+
const size_t outgoingPublishCount = 30;
+
MQTTPubAckInfo_t outgoingPublishes[ outgoingPublishCount ];
+
+
// Clear context.
+
memset( ( void * ) &mqttContext, 0x00, sizeof( MQTTContext_t ) );
+
+
// Set transport interface members.
+
transport.pNetworkContext = &someTransportContext;
+
transport.send = networkSend;
+
transport.recv = networkRecv;
+
+
// Set buffer members.
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = 1024;
+
+
status = MQTT_Init( &mqttContext, &transport, getTimeStampMs, eventCallback, &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// We do not expect any incoming publishes in this example, therefore the incoming
+
// publish pointer is NULL and the count is zero.
+
status = MQTT_InitStatefulQoS( &mqttContext, outgoingPublishes, outgoingPublishCount, NULL, 0 );
+
+
// Now QoS1 and/or QoS2 publishes can be sent with this context.
+
}
+
MQTTStatus_t MQTT_InitStatefulQoS(MQTTContext_t *pContext, MQTTPubAckInfo_t *pOutgoingPublishRecords, size_t outgoingPublishCount, MQTTPubAckInfo_t *pIncomingPublishRecords, size_t incomingPublishCount)
Initialize an MQTT context for QoS > 0.
Definition: core_mqtt.c:2590
+
An element of the state engine records for QoS 1 or Qos 2 publishes.
Definition: core_mqtt.h:162
+
+
+
+ +

◆ MQTT_CancelCallback()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_CancelCallback (const MQTTContext_tpContext,
uint16_t packetId 
)
+
+ +

Cancels an outgoing publish callback (only for QoS > QoS0) by removing it from the pending ACK list.

+
Note
This cannot cancel the actual publish as that might have already been sent to the broker. This only removes the details of the given packet ID from the list of unACKed packet. That allows the caller to free any memory associated with the publish payload, topic string etc. Also, after this API call, the user provided callback will not be invoked when the ACK packet is received.
+
Parameters
+ + + +
[in]pContextInitialized MQTT context.
[in]packetIdpacket ID corresponding to the outstanding publish.
+
+
+
Returns
MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+ +
+
+ +

◆ MQTT_Connect()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_Connect (MQTTContext_tpContext,
const MQTTConnectInfo_tpConnectInfo,
const MQTTPublishInfo_tpWillInfo,
uint32_t timeoutMs,
bool * pSessionPresent 
)
+
+ +

Establish an MQTT session.

+

This function will send MQTT CONNECT packet and receive a CONNACK packet. The send and receive from the network is done through the transport interface.

+

The maximum time this function waits for a CONNACK is decided in one of the following ways:

    +
  1. If timeoutMs is greater than 0: MQTTContext_t.getTime is used to ensure that the function does not wait more than timeoutMs for CONNACK.
  2. +
  3. If timeoutMs is 0: The network receive for CONNACK is retried up to the number of times configured by MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT.
  4. +
+
Note
If a dummy MQTTGetCurrentTimeFunc_t was passed to MQTT_Init, then a timeout value of 0 MUST be passed to the API, and the MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS timeout configurations MUST be set to 0.
+
Parameters
+ + + + + + +
[in]pContextInitialized MQTT context.
[in]pConnectInfoMQTT CONNECT packet information.
[in]pWillInfoLast Will and Testament. Pass NULL if Last Will and Testament is not used.
[in]timeoutMsMaximum time in milliseconds to wait for a CONNACK packet. A zero timeout makes use of the retries for receiving CONNACK as configured with MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT.
[out]pSessionPresentThis value will be set to true if a previous session was present; otherwise it will be set to false. It is only relevant if not establishing a clean session.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport send failed; MQTTRecvFailed if transport receive failed for CONNACK; MQTTNoDataAvailable if no data available to receive in transport until the timeoutMs for CONNACK; MQTTSuccess otherwise.
+
Note
This API may spend more time than provided in the timeoutMS parameters in certain conditions as listed below:
+
    +
  1. Timeouts are incorrectly configured - If the timeoutMS is less than the transport receive timeout and if a CONNACK packet is not received within the transport receive timeout, the API will spend the transport receive timeout (which is more time than the timeoutMs). It is the case of incorrect timeout configuration as the timeoutMs parameter passed to this API must be greater than the transport receive timeout. Please refer to the transport interface documentation for more details about timeout configurations.
  2. +
  3. Partial CONNACK packet is received right before the expiry of the timeout - It is possible that first two bytes of CONNACK packet (packet type and remaining length) are received right before the expiry of the timeoutMS. In that case, the API makes one more network receive call in an attempt to receive the remaining 2 bytes. In the worst case, it can happen that the remaining 2 bytes are never received and this API will end up spending timeoutMs + transport receive timeout.
  4. +
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
bool sessionPresent;
+
// This is assumed to have been initialized before calling this function.
+
MQTTContext_t * pContext;
+
+
// True for creating a new session with broker, false if we want to resume an old one.
+
connectInfo.cleanSession = true;
+
// Client ID must be unique to broker. This field is required.
+
connectInfo.pClientIdentifier = "someClientID";
+
connectInfo.clientIdentifierLength = strlen( connectInfo.pClientIdentifier );
+
+
// The following fields are optional.
+
// Value for keep alive.
+
connectInfo.keepAliveSeconds = 60;
+
// Optional username and password.
+
connectInfo.pUserName = "someUserName";
+
connectInfo.userNameLength = strlen( connectInfo.pUserName );
+
connectInfo.pPassword = "somePassword";
+
connectInfo.passwordLength = strlen( connectInfo.pPassword );
+
+
// The last will and testament is optional, it will be published by the broker
+
// should this client disconnect without sending a DISCONNECT packet.
+
willInfo.qos = MQTTQoS0;
+
willInfo.pTopicName = "/lwt/topic/name";
+
willInfo.topicNameLength = strlen( willInfo.pTopicName );
+
willInfo.pPayload = "LWT Message";
+
willInfo.payloadLength = strlen( "LWT Message" );
+
+
// Send the connect packet. Use 100 ms as the timeout to wait for the CONNACK packet.
+
status = MQTT_Connect( pContext, &connectInfo, &willInfo, 100, &sessionPresent );
+
+
if( status == MQTTSuccess )
+
{
+
// Since we requested a clean session, this must be false
+
assert( sessionPresent == false );
+
+
// Do something with the connection.
+
}
+
MQTTStatus_t MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
Establish an MQTT session.
Definition: core_mqtt.c:2679
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
@ MQTTQoS0
Definition: core_mqtt_serializer.h:110
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
const char * pClientIdentifier
MQTT client identifier. Must be unique per client.
Definition: core_mqtt_serializer.h:147
+
const char * pUserName
MQTT user name. Set to NULL if not used.
Definition: core_mqtt_serializer.h:157
+
bool cleanSession
Whether to establish a new, clean session or resume a previous session.
Definition: core_mqtt_serializer.h:137
+
uint16_t userNameLength
Length of MQTT user name. Set to 0 if not used.
Definition: core_mqtt_serializer.h:162
+
uint16_t keepAliveSeconds
MQTT keep alive period.
Definition: core_mqtt_serializer.h:142
+
uint16_t clientIdentifierLength
Length of the client identifier.
Definition: core_mqtt_serializer.h:152
+
uint16_t passwordLength
Length of MQTT password. Set to 0 if not used.
Definition: core_mqtt_serializer.h:172
+
const char * pPassword
MQTT password. Set to NULL if not used.
Definition: core_mqtt_serializer.h:167
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+
MQTTQoS_t qos
Quality of Service for message.
Definition: core_mqtt_serializer.h:206
+
uint16_t topicNameLength
Length of topic name.
Definition: core_mqtt_serializer.h:226
+
size_t payloadLength
Message payload length.
Definition: core_mqtt_serializer.h:236
+
const char * pTopicName
Topic name on which the message is published.
Definition: core_mqtt_serializer.h:221
+
const void * pPayload
Message payload.
Definition: core_mqtt_serializer.h:231
+
+
+
+ +

◆ MQTT_Subscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_Subscribe (MQTTContext_tpContext,
const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId 
)
+
+ +

Sends MQTT SUBSCRIBE for the given list of topic filters to the broker.

+
Parameters
+ + + + + +
[in]pContextInitialized MQTT context.
[in]pSubscriptionListArray of MQTT subscription info.
[in]subscriptionCountThe number of elements in @ pSubscriptionList array.
[in]packetIdPacket ID generated by MQTT_GetPacketId.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
uint16_t packetId;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
// This is assumed to be a list of filters we want to subscribe to.
+
const char * filters[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// Set each subscription.
+
for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )
+
{
+
subscriptionList[ i ].qos = MQTTQoS0;
+
// Each subscription needs a topic filter.
+
subscriptionList[ i ].pTopicFilter = filters[ i ];
+
subscriptionList[ i ].topicFilterLength = strlen( filters[ i ] );
+
}
+
+
// Obtain a new packet id for the subscription.
+
packetId = MQTT_GetPacketId( pContext );
+
+
status = MQTT_Subscribe( pContext, &subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// We must now call MQTT_ReceiveLoop() or MQTT_ProcessLoop() to receive the SUBACK.
+
// If the broker accepts the subscription we can now receive publishes
+
// on the requested topics.
+
}
+
uint16_t MQTT_GetPacketId(MQTTContext_t *pContext)
Get a packet ID that is valid according to the MQTT 3.1.1 spec.
Definition: core_mqtt.c:3172
+
MQTTStatus_t MQTT_Subscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
Sends MQTT SUBSCRIBE for the given list of topic filters to the broker.
Definition: core_mqtt.c:2761
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+
MQTTQoS_t qos
Quality of Service for subscription.
Definition: core_mqtt_serializer.h:184
+
uint16_t topicFilterLength
Length of subscription topic filter.
Definition: core_mqtt_serializer.h:194
+
const char * pTopicFilter
Topic filter to subscribe to.
Definition: core_mqtt_serializer.h:189
+
+
+
+ +

◆ MQTT_Publish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_Publish (MQTTContext_tpContext,
const MQTTPublishInfo_tpPublishInfo,
uint16_t packetId 
)
+
+ +

Publishes a message to the given topic name.

+
Parameters
+ + + + +
[in]pContextInitialized MQTT context.
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
+
+
+
Returns
MQTTNoMemory if pBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo;
+
uint16_t packetId;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
+
// QoS of publish.
+
publishInfo.qos = MQTTQoS1;
+
publishInfo.pTopicName = "/some/topic/name";
+
publishInfo.topicNameLength = strlen( publishInfo.pTopicName );
+
publishInfo.pPayload = "Hello World!";
+
publishInfo.payloadLength = strlen( "Hello World!" );
+
+
// Packet ID is needed for QoS > 0.
+
packetId = MQTT_GetPacketId( pContext );
+
+
status = MQTT_Publish( pContext, &publishInfo, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// Since the QoS is > 0, we will need to call MQTT_ReceiveLoop()
+
// or MQTT_ProcessLoop() to process the publish acknowledgments.
+
}
+
MQTTStatus_t MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId)
Publishes a message to the given topic name.
Definition: core_mqtt.c:2805
+
@ MQTTQoS1
Definition: core_mqtt_serializer.h:111
+
+
+
+ +

◆ MQTT_Ping()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_Ping (MQTTContext_tpContext)
+
+ +

Sends an MQTT PINGREQ to broker.

+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Returns
MQTTNoMemory if pBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+ +
+
+ +

◆ MQTT_Unsubscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_Unsubscribe (MQTTContext_tpContext,
const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId 
)
+
+ +

Sends MQTT UNSUBSCRIBE for the given list of topic filters to the broker.

+
Parameters
+ + + + + +
[in]pContextInitialized MQTT context.
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t unsubscribeList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
uint16_t packetId;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
// This is assumed to be a list of filters we want to unsubscribe from.
+
const char * filters[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// Set information for each unsubscribe request.
+
for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )
+
{
+
unsubscribeList[ i ].pTopicFilter = filters[ i ];
+
unsubscribeList[ i ].topicFilterLength = strlen( filters[ i ] );
+
+
// The QoS field of MQTT_SubscribeInfo_t is unused for unsubscribing.
+
}
+
+
// Obtain a new packet id for the unsubscribe request.
+
packetId = MQTT_GetPacketId( pContext );
+
+
status = MQTT_Unsubscribe( pContext, &unsubscribeList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// We must now call MQTT_ReceiveLoop() or MQTT_ProcessLoop() to receive the UNSUBACK.
+
// After this the broker should no longer send publishes for these topics.
+
}
+
MQTTStatus_t MQTT_Unsubscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
Sends MQTT UNSUBSCRIBE for the given list of topic filters to the broker.
Definition: core_mqtt.c:3000
+
+
+
+ +

◆ MQTT_Disconnect()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_Disconnect (MQTTContext_tpContext)
+
+ +

Disconnect an MQTT session.

+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport send failed; MQTTSuccess otherwise.
+ +
+
+ +

◆ MQTT_ProcessLoop()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_ProcessLoop (MQTTContext_tpContext)
+
+ +

Loop to receive packets from the transport interface. Handles keep alive.

+
Note
If a dummy timer function, MQTTGetCurrentTimeFunc_t, is passed to the library, then the keep-alive mechanism is not supported by the MQTT_ProcessLoop API. In that case, the MQTT_ReceiveLoop API function should be used instead.
+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Note
Calling this function blocks the calling context for a time period that depends on the passed the configuration macros, MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS, and the underlying transport interface implementation timeouts, unless an error occurs. The blocking period also depends on the execution time of the MQTTEventCallback_t callback supplied to the library. It is recommended that the supplied MQTTEventCallback_t callback does not contain blocking operations to prevent potential non-deterministic blocking period of the MQTT_ProcessLoop API call.
+
Returns
MQTTBadParameter if context is NULL; MQTTRecvFailed if a network error occurs during reception; MQTTSendFailed if a network error occurs while sending an ACK or PINGREQ; MQTTBadResponse if an invalid packet is received; MQTTKeepAliveTimeout if the server has not sent a PINGRESP before MQTT_PINGRESP_TIMEOUT_MS milliseconds; MQTTIllegalState if an incoming QoS 1/2 publish or ack causes an invalid transition for the internal state machine; MQTTNeedMoreBytes if MQTT_ProcessLoop has received incomplete data; it should be called again (probably after a delay); MQTTSuccess on success.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
+
while( true )
+
{
+
status = MQTT_ProcessLoop( pContext );
+
+
if( status != MQTTSuccess && status != MQTTNeedMoreBytes )
+
{
+
// Determine the error. It's possible we might need to disconnect
+
// the underlying transport connection.
+
}
+
else
+
{
+
// Other application functions.
+
}
+
}
+
MQTTStatus_t MQTT_ProcessLoop(MQTTContext_t *pContext)
Loop to receive packets from the transport interface. Handles keep alive.
Definition: core_mqtt.c:3119
+
@ MQTTNeedMoreBytes
Definition: core_mqtt_serializer.h:99
+
+
+
+ +

◆ MQTT_ReceiveLoop()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_ReceiveLoop (MQTTContext_tpContext)
+
+ +

Loop to receive packets from the transport interface. Does not handle keep alive.

+
Note
If a dummy MQTTGetCurrentTimeFunc_t was passed to MQTT_Init, then the MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS timeout configurations MUST be set to 0.
+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Note
Calling this function blocks the calling context for a time period that depends on the the configuration macros, MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS, and the underlying transport interface implementation timeouts, unless an error occurs. The blocking period also depends on the execution time of the MQTTEventCallback_t callback supplied to the library. It is recommended that the supplied MQTTEventCallback_t callback does not contain blocking operations to prevent potential non-deterministic blocking period of the MQTT_ReceiveLoop API call.
+
Returns
MQTTBadParameter if context is NULL; MQTTRecvFailed if a network error occurs during reception; MQTTSendFailed if a network error occurs while sending an ACK or PINGREQ; MQTTBadResponse if an invalid packet is received; MQTTIllegalState if an incoming QoS 1/2 publish or ack causes an invalid transition for the internal state machine; MQTTNeedMoreBytes if MQTT_ReceiveLoop has received incomplete data; it should be called again (probably after a delay); MQTTSuccess on success.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
uint32_t keepAliveMs = 60 * 1000;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
+
while( true )
+
{
+
status = MQTT_ReceiveLoop( pContext );
+
+
if( status != MQTTSuccess && status != MQTTNeedMoreBytes )
+
{
+
// Determine the error. It's possible we might need to disconnect
+
// the underlying transport connection.
+
}
+
else
+
{
+
// Since this function does not send pings, the application may need
+
// to in order to comply with keep alive.
+
if( ( pContext->getTime() - pContext->lastPacketTxTime ) > keepAliveMs )
+
{
+
status = MQTT_Ping( pContext );
+
}
+
+
// Other application functions.
+
}
+
}
+
MQTTStatus_t MQTT_Ping(MQTTContext_t *pContext)
Sends an MQTT PINGREQ to broker.
Definition: core_mqtt.c:2922
+
MQTTStatus_t MQTT_ReceiveLoop(MQTTContext_t *pContext)
Loop to receive packets from the transport interface. Does not handle keep alive.
Definition: core_mqtt.c:3146
+
uint32_t lastPacketTxTime
Timestamp of the last packet sent by the library.
Definition: core_mqtt.h:227
+
MQTTGetCurrentTimeFunc_t getTime
Function used to get millisecond timestamps.
Definition: core_mqtt.h:217
+
+
+
+ +

◆ MQTT_GetPacketId()

+ +
+
+ + + + + + + + +
uint16_t MQTT_GetPacketId (MQTTContext_tpContext)
+
+ +

Get a packet ID that is valid according to the MQTT 3.1.1 spec.

+
Parameters
+ + +
[in]pContextInitialized MQTT context.
+
+
+
Returns
A non-zero number.
+ +
+
+ +

◆ MQTT_MatchTopic()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_MatchTopic (const char * pTopicName,
const uint16_t topicNameLength,
const char * pTopicFilter,
const uint16_t topicFilterLength,
bool * pIsMatch 
)
+
+ +

A utility function that determines whether the passed topic filter and topic name match according to the MQTT 3.1.1 protocol specification.

+
Parameters
+ + + + + + +
[in]pTopicNameThe topic name to check.
[in]topicNameLengthLength of the topic name.
[in]pTopicFilterThe topic filter to check.
[in]topicFilterLengthLength of topic filter.
[out]pIsMatchIf the match is performed without any error, that is if the return value is MQTTSuccess, then and only then the value in this parameter is valid and updated. In such a case, if the topic filter and the topic name match, then this value is set to true; otherwise if there is no match then it is set to false.
+
+
+
Note
The API assumes that the passed topic name is valid to meet the requirements of the MQTT 3.1.1 specification. Invalid topic names (for example, containing wildcard characters) should not be passed to the function. Also, the API checks validity of topic filter for wildcard characters ONLY if the passed topic name and topic filter do not have an exact string match.
+
Returns
Returns one of the following: +
+

Example

// Variables used in this example.
+
const char * pTopic = "topic/match/1";
+
const char * pFilter = "topic/#";
+ +
bool match = false;
+
+
status = MQTT_MatchTopic( pTopic, strlen( pTopic ), pFilter, strlen( pFilter ), &match );
+
// Our parameters were valid, so this will return success.
+
assert( status == MQTTSuccess );
+
+
// For this specific example, we already know this value is true. This
+
// check is placed here as an example for use with variable topic names.
+
if( match )
+
{
+
// Application can decide what to do with the matching topic name.
+
}
+
MQTTStatus_t MQTT_MatchTopic(const char *pTopicName, const uint16_t topicNameLength, const char *pTopicFilter, const uint16_t topicFilterLength, bool *pIsMatch)
A utility function that determines whether the passed topic filter and topic name match according to ...
Definition: core_mqtt.c:3201
+
+
+
+ +

◆ MQTT_GetSubAckStatusCodes()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetSubAckStatusCodes (const MQTTPacketInfo_tpSubackPacket,
uint8_t ** pPayloadStart,
size_t * pPayloadSize 
)
+
+ +

Parses the payload of an MQTT SUBACK packet that contains status codes corresponding to topic filter subscription requests from the original subscribe packet.

+

Each return code in the SUBACK packet corresponds to a topic filter in the SUBSCRIBE Packet being acknowledged. The status codes can be one of the following:

    +
  • 0x00 - Success - Maximum QoS 0
  • +
  • 0x01 - Success - Maximum QoS 1
  • +
  • 0x02 - Success - Maximum QoS 2
  • +
  • 0x80 - Failure Refer to MQTTSubAckStatus_t for the status codes.
  • +
+
Parameters
+ + + + +
[in]pSubackPacketThe SUBACK packet whose payload is to be parsed.
[out]pPayloadStartThis is populated with the starting address of the payload (or return codes for topic filters) in the SUBACK packet.
[out]pPayloadSizeThis is populated with the size of the payload in the SUBACK packet. It represents the number of topic filters whose SUBACK status is present in the packet.
+
+
+
Returns
Returns one of the following: +
+

Example

// Global variable used in this example.
+
// This is assumed to be the subscription list in the original SUBSCRIBE packet.
+
MQTTSubscribeInfo_t pSubscribes[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// MQTT_GetSubAckStatusCodes is intended to be used from the application
+
// callback that is called by the library in MQTT_ProcessLoop or MQTT_ReceiveLoop.
+
void eventCallback(
+
MQTTContext_t * pContext,
+
MQTTPacketInfo_t * pPacketInfo,
+
MQTTDeserializedInfo_t * pDeserializedInfo
+
)
+
{
+ +
uint8_t * pCodes;
+
size_t numCodes;
+
+
if( pPacketInfo->type == MQTT_PACKET_TYPE_SUBACK )
+
{
+
status = MQTT_GetSubAckStatusCodes( pPacketInfo, &pCodes, &numCodes );
+
+
// Since the pointers to the payload and payload size are not NULL, and
+
// we use the packet info struct passed to the app callback (verified
+
// to be valid by the library), this function must return success.
+
assert( status == MQTTSuccess );
+
// The server must send a response code for each topic filter in the
+
// original SUBSCRIBE packet.
+
assert( numCodes == NUMBER_OF_SUBSCRIPTIONS );
+
+
for( int i = 0; i < numCodes; i++ )
+
{
+
// The only failure code is 0x80 = MQTTSubAckFailure.
+
if( pCodes[ i ] == MQTTSubAckFailure )
+
{
+
// The subscription failed, we may want to retry the
+
// subscription in pSubscribes[ i ] outside of this callback.
+
}
+
else
+
{
+
// The subscription was granted, but the maximum QoS may be
+
// lower than what was requested. We can verify the granted QoS.
+
if( pSubscribes[ i ].qos != pCodes[ i ] )
+
{
+ +
"Requested QoS %u, but granted QoS %u for %s",
+
pSubscribes[ i ].qos, pCodes[ i ], pSubscribes[ i ].pTopicFilter
+
) );
+
}
+
}
+
}
+
}
+
// Handle other packet types.
+
}
+
MQTTStatus_t MQTT_GetSubAckStatusCodes(const MQTTPacketInfo_t *pSubackPacket, uint8_t **pPayloadStart, size_t *pPayloadSize)
Parses the payload of an MQTT SUBACK packet that contains status codes corresponding to topic filter ...
Definition: core_mqtt.c:3270
+
#define LogWarn(message)
Macro that is called in the MQTT library for logging "Warning" level messages.
Definition: core_mqtt_config_defaults.h:235
+
#define MQTT_PACKET_TYPE_SUBACK
SUBACK (server-to-client).
Definition: core_mqtt_serializer.h:61
+
@ MQTTSubAckFailure
Failure.
Definition: core_mqtt.h:154
+
uint8_t type
Type of incoming MQTT packet.
Definition: core_mqtt_serializer.h:248
+
+
+
+ +

◆ MQTT_Status_strerror()

+ +
+
+ + + + + + + + +
const char * MQTT_Status_strerror (MQTTStatus_t status)
+
+ +

Error code to string conversion for MQTT statuses.

+
Parameters
+ + +
[in]statusThe status to convert to a string.
+
+
+
Returns
The string representation of the status.
+ +
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/core__mqtt_8h.html b/v1.3.0/coreMQTT/core__mqtt_8h.html new file mode 100644 index 00000000..fc26a0fd --- /dev/null +++ b/v1.3.0/coreMQTT/core__mqtt_8h.html @@ -0,0 +1,1281 @@ + + + + + + + +coreMQTT: core_mqtt.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt.h File Reference
+
+
+ +

User-facing functions of the MQTT 3.1.1 library. +More...

+ +

Go to the source code of this file.

+ + + + + + + + + + + +

+Data Structures

struct  MQTTPubAckInfo_t
 An element of the state engine records for QoS 1 or Qos 2 publishes. More...
 
struct  MQTTContext_t
 A struct representing an MQTT connection. More...
 
struct  MQTTDeserializedInfo_t
 Struct to hold deserialized packet information for an MQTTEventCallback_t callback. More...
 
+ + + + +

+Macros

#define MQTT_PACKET_ID_INVALID   ( ( uint16_t ) 0U )
 Invalid packet identifier.
 
+ + + + + + + +

+Typedefs

typedef uint32_t(* MQTTGetCurrentTimeFunc_t) (void)
 Application provided function to query the time elapsed since a given epoch in milliseconds.
 
typedef void(* MQTTEventCallback_t) (struct MQTTContext *pContext, struct MQTTPacketInfo *pPacketInfo, struct MQTTDeserializedInfo *pDeserializedInfo)
 Application callback for receiving incoming publishes and incoming acks.
 
+ + + + + + + + + + + + + +

+Enumerations

enum  MQTTConnectionStatus_t { MQTTNotConnected +, MQTTConnected + }
 Values indicating if an MQTT connection exists. More...
 
enum  MQTTPublishState_t {
+  MQTTStateNull = 0 +, MQTTPublishSend +, MQTTPubAckSend +, MQTTPubRecSend +,
+  MQTTPubRelSend +, MQTTPubCompSend +, MQTTPubAckPending +, MQTTPubRecPending +,
+  MQTTPubRelPending +, MQTTPubCompPending +, MQTTPublishDone +
+ }
 The state of QoS 1 or QoS 2 MQTT publishes, used in the state engine. More...
 
enum  MQTTPubAckType_t { MQTTPuback +, MQTTPubrec +, MQTTPubrel +, MQTTPubcomp + }
 Packet types used in acknowledging QoS 1 or QoS 2 publishes. More...
 
enum  MQTTSubAckStatus_t { MQTTSubAckSuccessQos0 = 0x00 +, MQTTSubAckSuccessQos1 = 0x01 +, MQTTSubAckSuccessQos2 = 0x02 +, MQTTSubAckFailure = 0x80 + }
 The status codes in the SUBACK response to a subscription request. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

MQTTStatus_t MQTT_Init (MQTTContext_t *pContext, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getTimeFunction, MQTTEventCallback_t userCallback, const MQTTFixedBuffer_t *pNetworkBuffer)
 Initialize an MQTT context.
 
MQTTStatus_t MQTT_InitStatefulQoS (MQTTContext_t *pContext, MQTTPubAckInfo_t *pOutgoingPublishRecords, size_t outgoingPublishCount, MQTTPubAckInfo_t *pIncomingPublishRecords, size_t incomingPublishCount)
 Initialize an MQTT context for QoS > 0.
 
MQTTStatus_t MQTT_Connect (MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
 Establish an MQTT session.
 
MQTTStatus_t MQTT_Subscribe (MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
 Sends MQTT SUBSCRIBE for the given list of topic filters to the broker.
 
MQTTStatus_t MQTT_Publish (MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId)
 Publishes a message to the given topic name.
 
MQTTStatus_t MQTT_CancelCallback (const MQTTContext_t *pContext, uint16_t packetId)
 Cancels an outgoing publish callback (only for QoS > QoS0) by removing it from the pending ACK list.
 
MQTTStatus_t MQTT_Ping (MQTTContext_t *pContext)
 Sends an MQTT PINGREQ to broker.
 
MQTTStatus_t MQTT_Unsubscribe (MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
 Sends MQTT UNSUBSCRIBE for the given list of topic filters to the broker.
 
MQTTStatus_t MQTT_Disconnect (MQTTContext_t *pContext)
 Disconnect an MQTT session.
 
MQTTStatus_t MQTT_ProcessLoop (MQTTContext_t *pContext)
 Loop to receive packets from the transport interface. Handles keep alive.
 
MQTTStatus_t MQTT_ReceiveLoop (MQTTContext_t *pContext)
 Loop to receive packets from the transport interface. Does not handle keep alive.
 
uint16_t MQTT_GetPacketId (MQTTContext_t *pContext)
 Get a packet ID that is valid according to the MQTT 3.1.1 spec.
 
MQTTStatus_t MQTT_MatchTopic (const char *pTopicName, const uint16_t topicNameLength, const char *pTopicFilter, const uint16_t topicFilterLength, bool *pIsMatch)
 A utility function that determines whether the passed topic filter and topic name match according to the MQTT 3.1.1 protocol specification.
 
MQTTStatus_t MQTT_GetSubAckStatusCodes (const MQTTPacketInfo_t *pSubackPacket, uint8_t **pPayloadStart, size_t *pPayloadSize)
 Parses the payload of an MQTT SUBACK packet that contains status codes corresponding to topic filter subscription requests from the original subscribe packet.
 
const char * MQTT_Status_strerror (MQTTStatus_t status)
 Error code to string conversion for MQTT statuses.
 
+

Detailed Description

+

User-facing functions of the MQTT 3.1.1 library.

+

Function Documentation

+ +

◆ MQTT_Init()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_Init (MQTTContext_tpContext,
const TransportInterface_tpTransportInterface,
MQTTGetCurrentTimeFunc_t getTimeFunction,
MQTTEventCallback_t userCallback,
const MQTTFixedBuffer_tpNetworkBuffer 
)
+
+ +

Initialize an MQTT context.

+

This function must be called on an MQTTContext_t before any other function.

+
Note
The MQTTGetCurrentTimeFunc_t function for querying time must be defined. If there is no time implementation, it is the responsibility of the application to provide a dummy function to always return 0, provide 0 timeouts for all calls to MQTT_Connect, MQTT_ProcessLoop, and MQTT_ReceiveLoop and configure the MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS configurations to be 0. This will result in loop functions running for a single iteration, and MQTT_Connect relying on MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT to receive the CONNACK packet.
+
Parameters
+ + + + + + +
[in]pContextThe context to initialize.
[in]pTransportInterfaceThe transport interface to use with the context.
[in]getTimeFunctionThe time utility function which can return the amount of time (in milliseconds) elapsed since a given epoch. This function will be used to ensure that timeouts in the API calls are met and keep-alive messages are sent on time.
[in]userCallbackThe user callback to use with the context to notify about incoming packet events.
[in]pNetworkBufferNetwork buffer provided for the context. This buffer will be used to receive incoming messages from the broker. This buffer must remain valid and in scope for the entire lifetime of the pContext and must not be used by another context and/or application.
+
+
+
Returns
MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Function for obtaining a timestamp.
+
uint32_t getTimeStampMs();
+
// Callback function for receiving packets.
+
void eventCallback(
+
MQTTContext_t * pContext,
+
MQTTPacketInfo_t * pPacketInfo,
+
MQTTDeserializedInfo_t * pDeserializedInfo
+
);
+
// Network send.
+
int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
+
// Network receive.
+
int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
+
+
MQTTContext_t mqttContext;
+ +
MQTTFixedBuffer_t fixedBuffer;
+
// Create a globally accessible buffer which remains in scope for the entire duration
+
// of the MQTT context.
+
uint8_t buffer[ 1024 ];
+
+
// Clear context.
+
memset( ( void * ) &mqttContext, 0x00, sizeof( MQTTContext_t ) );
+
+
// Set transport interface members.
+
transport.pNetworkContext = &someTransportContext;
+
transport.send = networkSend;
+
transport.recv = networkRecv;
+
+
// Set buffer members.
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = 1024;
+
+
status = MQTT_Init( &mqttContext, &transport, getTimeStampMs, eventCallback, &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// Do something with mqttContext. The transport and fixedBuffer structs were
+
// copied into the context, so the original structs do not need to stay in scope.
+
// However, the memory pointed to by the fixedBuffer.pBuffer must remain in scope.
+
}
+
MQTTStatus_t MQTT_Init(MQTTContext_t *pContext, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getTimeFunction, MQTTEventCallback_t userCallback, const MQTTFixedBuffer_t *pNetworkBuffer)
Initialize an MQTT context.
Definition: core_mqtt.c:2531
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
Struct to hold deserialized packet information for an MQTTEventCallback_t callback.
Definition: core_mqtt.h:257
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+
The transport layer interface.
Definition: transport_interface.h:299
+
TransportSend_t send
Definition: transport_interface.h:301
+
TransportRecv_t recv
Definition: transport_interface.h:300
+
NetworkContext_t * pNetworkContext
Definition: transport_interface.h:303
+
+
+
+ +

◆ MQTT_InitStatefulQoS()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_InitStatefulQoS (MQTTContext_tpContext,
MQTTPubAckInfo_tpOutgoingPublishRecords,
size_t outgoingPublishCount,
MQTTPubAckInfo_tpIncomingPublishRecords,
size_t incomingPublishCount 
)
+
+ +

Initialize an MQTT context for QoS > 0.

+

This function must be called on an MQTTContext_t after MQTT_Init and before any other function.

+
Parameters
+ + + + + + +
[in]pContextThe context to initialize.
[in]pOutgoingPublishRecordsPointer to memory which will be used to store state of outgoing publishes.
[in]outgoingPublishCountMaximum number of records which can be kept in the memory pointed to by pOutgoingPublishRecords.
[in]pIncomingPublishRecordsPointer to memory which will be used to store state of incoming publishes.
[in]incomingPublishCountMaximum number of records which can be kept in the memory pointed to by pIncomingPublishRecords.
+
+
+
Returns
MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Function for obtaining a timestamp.
+
uint32_t getTimeStampMs();
+
// Callback function for receiving packets.
+
void eventCallback(
+
MQTTContext_t * pContext,
+
MQTTPacketInfo_t * pPacketInfo,
+
MQTTDeserializedInfo_t * pDeserializedInfo
+
);
+
// Network send.
+
int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
+
// Network receive.
+
int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
+
+
MQTTContext_t mqttContext;
+ +
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ 1024 ];
+
const size_t outgoingPublishCount = 30;
+
MQTTPubAckInfo_t outgoingPublishes[ outgoingPublishCount ];
+
+
// Clear context.
+
memset( ( void * ) &mqttContext, 0x00, sizeof( MQTTContext_t ) );
+
+
// Set transport interface members.
+
transport.pNetworkContext = &someTransportContext;
+
transport.send = networkSend;
+
transport.recv = networkRecv;
+
+
// Set buffer members.
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = 1024;
+
+
status = MQTT_Init( &mqttContext, &transport, getTimeStampMs, eventCallback, &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// We do not expect any incoming publishes in this example, therefore the incoming
+
// publish pointer is NULL and the count is zero.
+
status = MQTT_InitStatefulQoS( &mqttContext, outgoingPublishes, outgoingPublishCount, NULL, 0 );
+
+
// Now QoS1 and/or QoS2 publishes can be sent with this context.
+
}
+
MQTTStatus_t MQTT_InitStatefulQoS(MQTTContext_t *pContext, MQTTPubAckInfo_t *pOutgoingPublishRecords, size_t outgoingPublishCount, MQTTPubAckInfo_t *pIncomingPublishRecords, size_t incomingPublishCount)
Initialize an MQTT context for QoS > 0.
Definition: core_mqtt.c:2590
+
An element of the state engine records for QoS 1 or Qos 2 publishes.
Definition: core_mqtt.h:162
+
+
+
+ +

◆ MQTT_Connect()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_Connect (MQTTContext_tpContext,
const MQTTConnectInfo_tpConnectInfo,
const MQTTPublishInfo_tpWillInfo,
uint32_t timeoutMs,
bool * pSessionPresent 
)
+
+ +

Establish an MQTT session.

+

This function will send MQTT CONNECT packet and receive a CONNACK packet. The send and receive from the network is done through the transport interface.

+

The maximum time this function waits for a CONNACK is decided in one of the following ways:

    +
  1. If timeoutMs is greater than 0: MQTTContext_t.getTime is used to ensure that the function does not wait more than timeoutMs for CONNACK.
  2. +
  3. If timeoutMs is 0: The network receive for CONNACK is retried up to the number of times configured by MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT.
  4. +
+
Note
If a dummy MQTTGetCurrentTimeFunc_t was passed to MQTT_Init, then a timeout value of 0 MUST be passed to the API, and the MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS timeout configurations MUST be set to 0.
+
Parameters
+ + + + + + +
[in]pContextInitialized MQTT context.
[in]pConnectInfoMQTT CONNECT packet information.
[in]pWillInfoLast Will and Testament. Pass NULL if Last Will and Testament is not used.
[in]timeoutMsMaximum time in milliseconds to wait for a CONNACK packet. A zero timeout makes use of the retries for receiving CONNACK as configured with MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT.
[out]pSessionPresentThis value will be set to true if a previous session was present; otherwise it will be set to false. It is only relevant if not establishing a clean session.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport send failed; MQTTRecvFailed if transport receive failed for CONNACK; MQTTNoDataAvailable if no data available to receive in transport until the timeoutMs for CONNACK; MQTTSuccess otherwise.
+
Note
This API may spend more time than provided in the timeoutMS parameters in certain conditions as listed below:
+
    +
  1. Timeouts are incorrectly configured - If the timeoutMS is less than the transport receive timeout and if a CONNACK packet is not received within the transport receive timeout, the API will spend the transport receive timeout (which is more time than the timeoutMs). It is the case of incorrect timeout configuration as the timeoutMs parameter passed to this API must be greater than the transport receive timeout. Please refer to the transport interface documentation for more details about timeout configurations.
  2. +
  3. Partial CONNACK packet is received right before the expiry of the timeout - It is possible that first two bytes of CONNACK packet (packet type and remaining length) are received right before the expiry of the timeoutMS. In that case, the API makes one more network receive call in an attempt to receive the remaining 2 bytes. In the worst case, it can happen that the remaining 2 bytes are never received and this API will end up spending timeoutMs + transport receive timeout.
  4. +
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
bool sessionPresent;
+
// This is assumed to have been initialized before calling this function.
+
MQTTContext_t * pContext;
+
+
// True for creating a new session with broker, false if we want to resume an old one.
+
connectInfo.cleanSession = true;
+
// Client ID must be unique to broker. This field is required.
+
connectInfo.pClientIdentifier = "someClientID";
+
connectInfo.clientIdentifierLength = strlen( connectInfo.pClientIdentifier );
+
+
// The following fields are optional.
+
// Value for keep alive.
+
connectInfo.keepAliveSeconds = 60;
+
// Optional username and password.
+
connectInfo.pUserName = "someUserName";
+
connectInfo.userNameLength = strlen( connectInfo.pUserName );
+
connectInfo.pPassword = "somePassword";
+
connectInfo.passwordLength = strlen( connectInfo.pPassword );
+
+
// The last will and testament is optional, it will be published by the broker
+
// should this client disconnect without sending a DISCONNECT packet.
+
willInfo.qos = MQTTQoS0;
+
willInfo.pTopicName = "/lwt/topic/name";
+
willInfo.topicNameLength = strlen( willInfo.pTopicName );
+
willInfo.pPayload = "LWT Message";
+
willInfo.payloadLength = strlen( "LWT Message" );
+
+
// Send the connect packet. Use 100 ms as the timeout to wait for the CONNACK packet.
+
status = MQTT_Connect( pContext, &connectInfo, &willInfo, 100, &sessionPresent );
+
+
if( status == MQTTSuccess )
+
{
+
// Since we requested a clean session, this must be false
+
assert( sessionPresent == false );
+
+
// Do something with the connection.
+
}
+
MQTTStatus_t MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
Establish an MQTT session.
Definition: core_mqtt.c:2679
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
@ MQTTQoS0
Definition: core_mqtt_serializer.h:110
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
const char * pClientIdentifier
MQTT client identifier. Must be unique per client.
Definition: core_mqtt_serializer.h:147
+
const char * pUserName
MQTT user name. Set to NULL if not used.
Definition: core_mqtt_serializer.h:157
+
bool cleanSession
Whether to establish a new, clean session or resume a previous session.
Definition: core_mqtt_serializer.h:137
+
uint16_t userNameLength
Length of MQTT user name. Set to 0 if not used.
Definition: core_mqtt_serializer.h:162
+
uint16_t keepAliveSeconds
MQTT keep alive period.
Definition: core_mqtt_serializer.h:142
+
uint16_t clientIdentifierLength
Length of the client identifier.
Definition: core_mqtt_serializer.h:152
+
uint16_t passwordLength
Length of MQTT password. Set to 0 if not used.
Definition: core_mqtt_serializer.h:172
+
const char * pPassword
MQTT password. Set to NULL if not used.
Definition: core_mqtt_serializer.h:167
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+
MQTTQoS_t qos
Quality of Service for message.
Definition: core_mqtt_serializer.h:206
+
uint16_t topicNameLength
Length of topic name.
Definition: core_mqtt_serializer.h:226
+
size_t payloadLength
Message payload length.
Definition: core_mqtt_serializer.h:236
+
const char * pTopicName
Topic name on which the message is published.
Definition: core_mqtt_serializer.h:221
+
const void * pPayload
Message payload.
Definition: core_mqtt_serializer.h:231
+
+
+
+ +

◆ MQTT_Subscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_Subscribe (MQTTContext_tpContext,
const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId 
)
+
+ +

Sends MQTT SUBSCRIBE for the given list of topic filters to the broker.

+
Parameters
+ + + + + +
[in]pContextInitialized MQTT context.
[in]pSubscriptionListArray of MQTT subscription info.
[in]subscriptionCountThe number of elements in @ pSubscriptionList array.
[in]packetIdPacket ID generated by MQTT_GetPacketId.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
uint16_t packetId;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
// This is assumed to be a list of filters we want to subscribe to.
+
const char * filters[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// Set each subscription.
+
for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )
+
{
+
subscriptionList[ i ].qos = MQTTQoS0;
+
// Each subscription needs a topic filter.
+
subscriptionList[ i ].pTopicFilter = filters[ i ];
+
subscriptionList[ i ].topicFilterLength = strlen( filters[ i ] );
+
}
+
+
// Obtain a new packet id for the subscription.
+
packetId = MQTT_GetPacketId( pContext );
+
+
status = MQTT_Subscribe( pContext, &subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// We must now call MQTT_ReceiveLoop() or MQTT_ProcessLoop() to receive the SUBACK.
+
// If the broker accepts the subscription we can now receive publishes
+
// on the requested topics.
+
}
+
uint16_t MQTT_GetPacketId(MQTTContext_t *pContext)
Get a packet ID that is valid according to the MQTT 3.1.1 spec.
Definition: core_mqtt.c:3172
+
MQTTStatus_t MQTT_Subscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
Sends MQTT SUBSCRIBE for the given list of topic filters to the broker.
Definition: core_mqtt.c:2761
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+
MQTTQoS_t qos
Quality of Service for subscription.
Definition: core_mqtt_serializer.h:184
+
uint16_t topicFilterLength
Length of subscription topic filter.
Definition: core_mqtt_serializer.h:194
+
const char * pTopicFilter
Topic filter to subscribe to.
Definition: core_mqtt_serializer.h:189
+
+
+
+ +

◆ MQTT_Publish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_Publish (MQTTContext_tpContext,
const MQTTPublishInfo_tpPublishInfo,
uint16_t packetId 
)
+
+ +

Publishes a message to the given topic name.

+
Parameters
+ + + + +
[in]pContextInitialized MQTT context.
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
+
+
+
Returns
MQTTNoMemory if pBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo;
+
uint16_t packetId;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
+
// QoS of publish.
+
publishInfo.qos = MQTTQoS1;
+
publishInfo.pTopicName = "/some/topic/name";
+
publishInfo.topicNameLength = strlen( publishInfo.pTopicName );
+
publishInfo.pPayload = "Hello World!";
+
publishInfo.payloadLength = strlen( "Hello World!" );
+
+
// Packet ID is needed for QoS > 0.
+
packetId = MQTT_GetPacketId( pContext );
+
+
status = MQTT_Publish( pContext, &publishInfo, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// Since the QoS is > 0, we will need to call MQTT_ReceiveLoop()
+
// or MQTT_ProcessLoop() to process the publish acknowledgments.
+
}
+
MQTTStatus_t MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId)
Publishes a message to the given topic name.
Definition: core_mqtt.c:2805
+
@ MQTTQoS1
Definition: core_mqtt_serializer.h:111
+
+
+
+ +

◆ MQTT_CancelCallback()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_CancelCallback (const MQTTContext_tpContext,
uint16_t packetId 
)
+
+ +

Cancels an outgoing publish callback (only for QoS > QoS0) by removing it from the pending ACK list.

+
Note
This cannot cancel the actual publish as that might have already been sent to the broker. This only removes the details of the given packet ID from the list of unACKed packet. That allows the caller to free any memory associated with the publish payload, topic string etc. Also, after this API call, the user provided callback will not be invoked when the ACK packet is received.
+
Parameters
+ + + +
[in]pContextInitialized MQTT context.
[in]packetIdpacket ID corresponding to the outstanding publish.
+
+
+
Returns
MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+ +
+
+ +

◆ MQTT_Ping()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_Ping (MQTTContext_tpContext)
+
+ +

Sends an MQTT PINGREQ to broker.

+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Returns
MQTTNoMemory if pBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+ +
+
+ +

◆ MQTT_Unsubscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_Unsubscribe (MQTTContext_tpContext,
const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId 
)
+
+ +

Sends MQTT UNSUBSCRIBE for the given list of topic filters to the broker.

+
Parameters
+ + + + + +
[in]pContextInitialized MQTT context.
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t unsubscribeList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
uint16_t packetId;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
// This is assumed to be a list of filters we want to unsubscribe from.
+
const char * filters[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// Set information for each unsubscribe request.
+
for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )
+
{
+
unsubscribeList[ i ].pTopicFilter = filters[ i ];
+
unsubscribeList[ i ].topicFilterLength = strlen( filters[ i ] );
+
+
// The QoS field of MQTT_SubscribeInfo_t is unused for unsubscribing.
+
}
+
+
// Obtain a new packet id for the unsubscribe request.
+
packetId = MQTT_GetPacketId( pContext );
+
+
status = MQTT_Unsubscribe( pContext, &unsubscribeList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// We must now call MQTT_ReceiveLoop() or MQTT_ProcessLoop() to receive the UNSUBACK.
+
// After this the broker should no longer send publishes for these topics.
+
}
+
MQTTStatus_t MQTT_Unsubscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
Sends MQTT UNSUBSCRIBE for the given list of topic filters to the broker.
Definition: core_mqtt.c:3000
+
+
+
+ +

◆ MQTT_Disconnect()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_Disconnect (MQTTContext_tpContext)
+
+ +

Disconnect an MQTT session.

+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport send failed; MQTTSuccess otherwise.
+ +
+
+ +

◆ MQTT_ProcessLoop()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_ProcessLoop (MQTTContext_tpContext)
+
+ +

Loop to receive packets from the transport interface. Handles keep alive.

+
Note
If a dummy timer function, MQTTGetCurrentTimeFunc_t, is passed to the library, then the keep-alive mechanism is not supported by the MQTT_ProcessLoop API. In that case, the MQTT_ReceiveLoop API function should be used instead.
+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Note
Calling this function blocks the calling context for a time period that depends on the passed the configuration macros, MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS, and the underlying transport interface implementation timeouts, unless an error occurs. The blocking period also depends on the execution time of the MQTTEventCallback_t callback supplied to the library. It is recommended that the supplied MQTTEventCallback_t callback does not contain blocking operations to prevent potential non-deterministic blocking period of the MQTT_ProcessLoop API call.
+
Returns
MQTTBadParameter if context is NULL; MQTTRecvFailed if a network error occurs during reception; MQTTSendFailed if a network error occurs while sending an ACK or PINGREQ; MQTTBadResponse if an invalid packet is received; MQTTKeepAliveTimeout if the server has not sent a PINGRESP before MQTT_PINGRESP_TIMEOUT_MS milliseconds; MQTTIllegalState if an incoming QoS 1/2 publish or ack causes an invalid transition for the internal state machine; MQTTNeedMoreBytes if MQTT_ProcessLoop has received incomplete data; it should be called again (probably after a delay); MQTTSuccess on success.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
+
while( true )
+
{
+
status = MQTT_ProcessLoop( pContext );
+
+
if( status != MQTTSuccess && status != MQTTNeedMoreBytes )
+
{
+
// Determine the error. It's possible we might need to disconnect
+
// the underlying transport connection.
+
}
+
else
+
{
+
// Other application functions.
+
}
+
}
+
MQTTStatus_t MQTT_ProcessLoop(MQTTContext_t *pContext)
Loop to receive packets from the transport interface. Handles keep alive.
Definition: core_mqtt.c:3119
+
@ MQTTNeedMoreBytes
Definition: core_mqtt_serializer.h:99
+
+
+
+ +

◆ MQTT_ReceiveLoop()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_ReceiveLoop (MQTTContext_tpContext)
+
+ +

Loop to receive packets from the transport interface. Does not handle keep alive.

+
Note
If a dummy MQTTGetCurrentTimeFunc_t was passed to MQTT_Init, then the MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS timeout configurations MUST be set to 0.
+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Note
Calling this function blocks the calling context for a time period that depends on the the configuration macros, MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS, and the underlying transport interface implementation timeouts, unless an error occurs. The blocking period also depends on the execution time of the MQTTEventCallback_t callback supplied to the library. It is recommended that the supplied MQTTEventCallback_t callback does not contain blocking operations to prevent potential non-deterministic blocking period of the MQTT_ReceiveLoop API call.
+
Returns
MQTTBadParameter if context is NULL; MQTTRecvFailed if a network error occurs during reception; MQTTSendFailed if a network error occurs while sending an ACK or PINGREQ; MQTTBadResponse if an invalid packet is received; MQTTIllegalState if an incoming QoS 1/2 publish or ack causes an invalid transition for the internal state machine; MQTTNeedMoreBytes if MQTT_ReceiveLoop has received incomplete data; it should be called again (probably after a delay); MQTTSuccess on success.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
uint32_t keepAliveMs = 60 * 1000;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
+
while( true )
+
{
+
status = MQTT_ReceiveLoop( pContext );
+
+
if( status != MQTTSuccess && status != MQTTNeedMoreBytes )
+
{
+
// Determine the error. It's possible we might need to disconnect
+
// the underlying transport connection.
+
}
+
else
+
{
+
// Since this function does not send pings, the application may need
+
// to in order to comply with keep alive.
+
if( ( pContext->getTime() - pContext->lastPacketTxTime ) > keepAliveMs )
+
{
+
status = MQTT_Ping( pContext );
+
}
+
+
// Other application functions.
+
}
+
}
+
MQTTStatus_t MQTT_Ping(MQTTContext_t *pContext)
Sends an MQTT PINGREQ to broker.
Definition: core_mqtt.c:2922
+
MQTTStatus_t MQTT_ReceiveLoop(MQTTContext_t *pContext)
Loop to receive packets from the transport interface. Does not handle keep alive.
Definition: core_mqtt.c:3146
+
uint32_t lastPacketTxTime
Timestamp of the last packet sent by the library.
Definition: core_mqtt.h:227
+
MQTTGetCurrentTimeFunc_t getTime
Function used to get millisecond timestamps.
Definition: core_mqtt.h:217
+
+
+
+ +

◆ MQTT_GetPacketId()

+ +
+
+ + + + + + + + +
uint16_t MQTT_GetPacketId (MQTTContext_tpContext)
+
+ +

Get a packet ID that is valid according to the MQTT 3.1.1 spec.

+
Parameters
+ + +
[in]pContextInitialized MQTT context.
+
+
+
Returns
A non-zero number.
+ +
+
+ +

◆ MQTT_MatchTopic()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_MatchTopic (const char * pTopicName,
const uint16_t topicNameLength,
const char * pTopicFilter,
const uint16_t topicFilterLength,
bool * pIsMatch 
)
+
+ +

A utility function that determines whether the passed topic filter and topic name match according to the MQTT 3.1.1 protocol specification.

+
Parameters
+ + + + + + +
[in]pTopicNameThe topic name to check.
[in]topicNameLengthLength of the topic name.
[in]pTopicFilterThe topic filter to check.
[in]topicFilterLengthLength of topic filter.
[out]pIsMatchIf the match is performed without any error, that is if the return value is MQTTSuccess, then and only then the value in this parameter is valid and updated. In such a case, if the topic filter and the topic name match, then this value is set to true; otherwise if there is no match then it is set to false.
+
+
+
Note
The API assumes that the passed topic name is valid to meet the requirements of the MQTT 3.1.1 specification. Invalid topic names (for example, containing wildcard characters) should not be passed to the function. Also, the API checks validity of topic filter for wildcard characters ONLY if the passed topic name and topic filter do not have an exact string match.
+
Returns
Returns one of the following: +
+

Example

// Variables used in this example.
+
const char * pTopic = "topic/match/1";
+
const char * pFilter = "topic/#";
+ +
bool match = false;
+
+
status = MQTT_MatchTopic( pTopic, strlen( pTopic ), pFilter, strlen( pFilter ), &match );
+
// Our parameters were valid, so this will return success.
+
assert( status == MQTTSuccess );
+
+
// For this specific example, we already know this value is true. This
+
// check is placed here as an example for use with variable topic names.
+
if( match )
+
{
+
// Application can decide what to do with the matching topic name.
+
}
+
MQTTStatus_t MQTT_MatchTopic(const char *pTopicName, const uint16_t topicNameLength, const char *pTopicFilter, const uint16_t topicFilterLength, bool *pIsMatch)
A utility function that determines whether the passed topic filter and topic name match according to ...
Definition: core_mqtt.c:3201
+
+
+
+ +

◆ MQTT_GetSubAckStatusCodes()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetSubAckStatusCodes (const MQTTPacketInfo_tpSubackPacket,
uint8_t ** pPayloadStart,
size_t * pPayloadSize 
)
+
+ +

Parses the payload of an MQTT SUBACK packet that contains status codes corresponding to topic filter subscription requests from the original subscribe packet.

+

Each return code in the SUBACK packet corresponds to a topic filter in the SUBSCRIBE Packet being acknowledged. The status codes can be one of the following:

    +
  • 0x00 - Success - Maximum QoS 0
  • +
  • 0x01 - Success - Maximum QoS 1
  • +
  • 0x02 - Success - Maximum QoS 2
  • +
  • 0x80 - Failure Refer to MQTTSubAckStatus_t for the status codes.
  • +
+
Parameters
+ + + + +
[in]pSubackPacketThe SUBACK packet whose payload is to be parsed.
[out]pPayloadStartThis is populated with the starting address of the payload (or return codes for topic filters) in the SUBACK packet.
[out]pPayloadSizeThis is populated with the size of the payload in the SUBACK packet. It represents the number of topic filters whose SUBACK status is present in the packet.
+
+
+
Returns
Returns one of the following: +
+

Example

// Global variable used in this example.
+
// This is assumed to be the subscription list in the original SUBSCRIBE packet.
+
MQTTSubscribeInfo_t pSubscribes[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// MQTT_GetSubAckStatusCodes is intended to be used from the application
+
// callback that is called by the library in MQTT_ProcessLoop or MQTT_ReceiveLoop.
+
void eventCallback(
+
MQTTContext_t * pContext,
+
MQTTPacketInfo_t * pPacketInfo,
+
MQTTDeserializedInfo_t * pDeserializedInfo
+
)
+
{
+ +
uint8_t * pCodes;
+
size_t numCodes;
+
+
if( pPacketInfo->type == MQTT_PACKET_TYPE_SUBACK )
+
{
+
status = MQTT_GetSubAckStatusCodes( pPacketInfo, &pCodes, &numCodes );
+
+
// Since the pointers to the payload and payload size are not NULL, and
+
// we use the packet info struct passed to the app callback (verified
+
// to be valid by the library), this function must return success.
+
assert( status == MQTTSuccess );
+
// The server must send a response code for each topic filter in the
+
// original SUBSCRIBE packet.
+
assert( numCodes == NUMBER_OF_SUBSCRIPTIONS );
+
+
for( int i = 0; i < numCodes; i++ )
+
{
+
// The only failure code is 0x80 = MQTTSubAckFailure.
+
if( pCodes[ i ] == MQTTSubAckFailure )
+
{
+
// The subscription failed, we may want to retry the
+
// subscription in pSubscribes[ i ] outside of this callback.
+
}
+
else
+
{
+
// The subscription was granted, but the maximum QoS may be
+
// lower than what was requested. We can verify the granted QoS.
+
if( pSubscribes[ i ].qos != pCodes[ i ] )
+
{
+ +
"Requested QoS %u, but granted QoS %u for %s",
+
pSubscribes[ i ].qos, pCodes[ i ], pSubscribes[ i ].pTopicFilter
+
) );
+
}
+
}
+
}
+
}
+
// Handle other packet types.
+
}
+
MQTTStatus_t MQTT_GetSubAckStatusCodes(const MQTTPacketInfo_t *pSubackPacket, uint8_t **pPayloadStart, size_t *pPayloadSize)
Parses the payload of an MQTT SUBACK packet that contains status codes corresponding to topic filter ...
Definition: core_mqtt.c:3270
+
#define LogWarn(message)
Macro that is called in the MQTT library for logging "Warning" level messages.
Definition: core_mqtt_config_defaults.h:235
+
#define MQTT_PACKET_TYPE_SUBACK
SUBACK (server-to-client).
Definition: core_mqtt_serializer.h:61
+
@ MQTTSubAckFailure
Failure.
Definition: core_mqtt.h:154
+
uint8_t type
Type of incoming MQTT packet.
Definition: core_mqtt_serializer.h:248
+
+
+
+ +

◆ MQTT_Status_strerror()

+ +
+
+ + + + + + + + +
const char * MQTT_Status_strerror (MQTTStatus_t status)
+
+ +

Error code to string conversion for MQTT statuses.

+
Parameters
+ + +
[in]statusThe status to convert to a string.
+
+
+
Returns
The string representation of the status.
+ +
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/core__mqtt_8h_source.html b/v1.3.0/coreMQTT/core__mqtt_8h_source.html new file mode 100644 index 00000000..f8e91ae3 --- /dev/null +++ b/v1.3.0/coreMQTT/core__mqtt_8h_source.html @@ -0,0 +1,423 @@ + + + + + + + +coreMQTT: core_mqtt.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
core_mqtt.h
+
+
+Go to the documentation of this file.
1/*
+
2 * coreMQTT v2.3.1
+
3 * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
4 *
+
5 * SPDX-License-Identifier: MIT
+
6 *
+
7 * Permission is hereby granted, free of charge, to any person obtaining a copy of
+
8 * this software and associated documentation files (the "Software"), to deal in
+
9 * the Software without restriction, including without limitation the rights to
+
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
11 * the Software, and to permit persons to whom the Software is furnished to do so,
+
12 * subject to the following conditions:
+
13 *
+
14 * The above copyright notice and this permission notice shall be included in all
+
15 * copies or substantial portions of the Software.
+
16 *
+
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
23 */
+
24
+
29#ifndef CORE_MQTT_H
+
30#define CORE_MQTT_H
+
31
+
32/* *INDENT-OFF* */
+
33#ifdef __cplusplus
+
34 extern "C" {
+
35#endif
+
36/* *INDENT-ON* */
+
37
+
38/* Include MQTT serializer library. */
+ +
40
+
41/* Include transport interface. */
+
42#include "transport_interface.h"
+
43
+
51#define MQTT_LIBRARY_VERSION "v2.3.1"
+
60#define MQTT_PACKET_ID_INVALID ( ( uint16_t ) 0U )
+
61
+
62/* Structures defined in this file. */
+
63struct MQTTPubAckInfo;
+
64struct MQTTContext;
+
65struct MQTTDeserializedInfo;
+
66
+
85typedef uint32_t (* MQTTGetCurrentTimeFunc_t )( void );
+
86
+
100typedef void (* MQTTEventCallback_t )( struct MQTTContext * pContext,
+
101 struct MQTTPacketInfo * pPacketInfo,
+
102 struct MQTTDeserializedInfo * pDeserializedInfo );
+
103
+
108typedef enum MQTTConnectionStatus
+
109{
+ + + +
113
+
118typedef enum MQTTPublishState
+
119{
+ + + + + + + + + + + + +
132
+
137typedef enum MQTTPubAckType
+
138{
+ + + + + +
144
+
149typedef enum MQTTSubAckStatus
+
150{
+ + + +
154 MQTTSubAckFailure = 0x80
+ +
156
+
161typedef struct MQTTPubAckInfo
+
162{
+
163 uint16_t packetId;
+ + + +
167
+
172typedef struct MQTTContext
+
173{
+ +
178
+ +
183
+ +
188
+ +
193
+ +
198
+ +
203
+
207 uint16_t nextPacketId;
+
208
+ +
213
+ +
218
+ +
223
+ +
228
+ +
233
+ +
239
+
243 size_t index;
+
244
+
245 /* Keep alive members. */
+ + + + +
250
+
256typedef struct MQTTDeserializedInfo
+
257{
+ + + + +
262
+
336/* @[declare_mqtt_init] */
+ +
338 const TransportInterface_t * pTransportInterface,
+
339 MQTTGetCurrentTimeFunc_t getTimeFunction,
+
340 MQTTEventCallback_t userCallback,
+
341 const MQTTFixedBuffer_t * pNetworkBuffer );
+
342/* @[declare_mqtt_init] */
+
343
+
409/* @[declare_mqtt_initstatefulqos] */
+ +
411 MQTTPubAckInfo_t * pOutgoingPublishRecords,
+
412 size_t outgoingPublishCount,
+
413 MQTTPubAckInfo_t * pIncomingPublishRecords,
+
414 size_t incomingPublishCount );
+
415/* @[declare_mqtt_initstatefulqos] */
+
416
+
520/* @[declare_mqtt_connect] */
+ +
522 const MQTTConnectInfo_t * pConnectInfo,
+
523 const MQTTPublishInfo_t * pWillInfo,
+
524 uint32_t timeoutMs,
+
525 bool * pSessionPresent );
+
526/* @[declare_mqtt_connect] */
+
527
+
578/* @[declare_mqtt_subscribe] */
+ +
580 const MQTTSubscribeInfo_t * pSubscriptionList,
+
581 size_t subscriptionCount,
+
582 uint16_t packetId );
+
583/* @[declare_mqtt_subscribe] */
+
584
+
626/* @[declare_mqtt_publish] */
+ +
628 const MQTTPublishInfo_t * pPublishInfo,
+
629 uint16_t packetId );
+
630/* @[declare_mqtt_publish] */
+
631
+
649/* @[declare_mqtt_cancelcallback] */
+ +
651 uint16_t packetId );
+
652/* @[declare_mqtt_cancelcallback] */
+
653
+
664/* @[declare_mqtt_ping] */
+ +
666/* @[declare_mqtt_ping] */
+
667
+
716/* @[declare_mqtt_unsubscribe] */
+ +
718 const MQTTSubscribeInfo_t * pSubscriptionList,
+
719 size_t subscriptionCount,
+
720 uint16_t packetId );
+
721/* @[declare_mqtt_unsubscribe] */
+
722
+
734/* @[declare_mqtt_disconnect] */
+ +
736/* @[declare_mqtt_disconnect] */
+
737
+
792/* @[declare_mqtt_processloop] */
+ +
794/* @[declare_mqtt_processloop] */
+
795
+
856/* @[declare_mqtt_receiveloop] */
+ +
858/* @[declare_mqtt_receiveloop] */
+
859
+
867/* @[declare_mqtt_getpacketid] */
+
868uint16_t MQTT_GetPacketId( MQTTContext_t * pContext );
+
869/* @[declare_mqtt_getpacketid] */
+
870
+
915MQTTStatus_t MQTT_MatchTopic( const char * pTopicName,
+
916 const uint16_t topicNameLength,
+
917 const char * pTopicFilter,
+
918 const uint16_t topicFilterLength,
+
919 bool * pIsMatch );
+
920
+
1003/* @[declare_mqtt_getsubackstatuscodes] */
+ +
1005 uint8_t ** pPayloadStart,
+
1006 size_t * pPayloadSize );
+
1007/* @[declare_mqtt_getsubackstatuscodes] */
+
1008
+
1016/* @[declare_mqtt_status_strerror] */
+
1017const char * MQTT_Status_strerror( MQTTStatus_t status );
+
1018/* @[declare_mqtt_status_strerror] */
+
1019
+
1020/* *INDENT-OFF* */
+
1021#ifdef __cplusplus
+
1022 }
+
1023#endif
+
1024/* *INDENT-ON* */
+
1025
+
1026#endif /* ifndef CORE_MQTT_H */
+
uint16_t MQTT_GetPacketId(MQTTContext_t *pContext)
Get a packet ID that is valid according to the MQTT 3.1.1 spec.
Definition: core_mqtt.c:3172
+
const char * MQTT_Status_strerror(MQTTStatus_t status)
Error code to string conversion for MQTT statuses.
Definition: core_mqtt.c:3329
+
MQTTStatus_t MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId)
Publishes a message to the given topic name.
Definition: core_mqtt.c:2805
+
MQTTStatus_t MQTT_CancelCallback(const MQTTContext_t *pContext, uint16_t packetId)
Cancels an outgoing publish callback (only for QoS > QoS0) by removing it from the pending ACK list.
Definition: core_mqtt.c:2647
+
MQTTStatus_t MQTT_Subscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
Sends MQTT SUBSCRIBE for the given list of topic filters to the broker.
Definition: core_mqtt.c:2761
+
MQTTStatus_t MQTT_MatchTopic(const char *pTopicName, const uint16_t topicNameLength, const char *pTopicFilter, const uint16_t topicFilterLength, bool *pIsMatch)
A utility function that determines whether the passed topic filter and topic name match according to ...
Definition: core_mqtt.c:3201
+
MQTTStatus_t MQTT_Ping(MQTTContext_t *pContext)
Sends an MQTT PINGREQ to broker.
Definition: core_mqtt.c:2922
+
MQTTStatus_t MQTT_Unsubscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
Sends MQTT UNSUBSCRIBE for the given list of topic filters to the broker.
Definition: core_mqtt.c:3000
+
MQTTStatus_t MQTT_ProcessLoop(MQTTContext_t *pContext)
Loop to receive packets from the transport interface. Handles keep alive.
Definition: core_mqtt.c:3119
+
MQTTStatus_t MQTT_GetSubAckStatusCodes(const MQTTPacketInfo_t *pSubackPacket, uint8_t **pPayloadStart, size_t *pPayloadSize)
Parses the payload of an MQTT SUBACK packet that contains status codes corresponding to topic filter ...
Definition: core_mqtt.c:3270
+
MQTTStatus_t MQTT_Disconnect(MQTTContext_t *pContext)
Disconnect an MQTT session.
Definition: core_mqtt.c:3045
+
MQTTStatus_t MQTT_Init(MQTTContext_t *pContext, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getTimeFunction, MQTTEventCallback_t userCallback, const MQTTFixedBuffer_t *pNetworkBuffer)
Initialize an MQTT context.
Definition: core_mqtt.c:2531
+
MQTTStatus_t MQTT_ReceiveLoop(MQTTContext_t *pContext)
Loop to receive packets from the transport interface. Does not handle keep alive.
Definition: core_mqtt.c:3146
+
MQTTStatus_t MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
Establish an MQTT session.
Definition: core_mqtt.c:2679
+
MQTTStatus_t MQTT_InitStatefulQoS(MQTTContext_t *pContext, MQTTPubAckInfo_t *pOutgoingPublishRecords, size_t outgoingPublishCount, MQTTPubAckInfo_t *pIncomingPublishRecords, size_t incomingPublishCount)
Initialize an MQTT context for QoS > 0.
Definition: core_mqtt.c:2590
+
User-facing functions for serializing and deserializing MQTT 3.1.1 packets. This header should be inc...
+
void(* MQTTEventCallback_t)(struct MQTTContext *pContext, struct MQTTPacketInfo *pPacketInfo, struct MQTTDeserializedInfo *pDeserializedInfo)
Application callback for receiving incoming publishes and incoming acks.
Definition: core_mqtt.h:100
+
uint32_t(* MQTTGetCurrentTimeFunc_t)(void)
Application provided function to query the time elapsed since a given epoch in milliseconds.
Definition: core_mqtt.h:85
+
MQTTPublishState_t
The state of QoS 1 or QoS 2 MQTT publishes, used in the state engine.
Definition: core_mqtt.h:119
+
MQTTSubAckStatus_t
The status codes in the SUBACK response to a subscription request.
Definition: core_mqtt.h:150
+
MQTTPubAckType_t
Packet types used in acknowledging QoS 1 or QoS 2 publishes.
Definition: core_mqtt.h:138
+
MQTTConnectionStatus_t
Values indicating if an MQTT connection exists.
Definition: core_mqtt.h:109
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTTQoS_t
MQTT Quality of Service values.
Definition: core_mqtt_serializer.h:109
+
@ MQTTPubRecSend
The library will send a PUBREC for a received PUBLISH.
Definition: core_mqtt.h:123
+
@ MQTTPubRecPending
The library is awaiting a PUBREC for an outgoing PUBLISH.
Definition: core_mqtt.h:127
+
@ MQTTPubCompPending
The library is awaiting a PUBCOMP for an outgoing PUBLISH.
Definition: core_mqtt.h:129
+
@ MQTTPubRelSend
The library will send a PUBREL for a received PUBREC.
Definition: core_mqtt.h:124
+
@ MQTTPubAckSend
The library will send a PUBACK for a received PUBLISH.
Definition: core_mqtt.h:122
+
@ MQTTPubRelPending
The library is awaiting a PUBREL for an incoming PUBLISH.
Definition: core_mqtt.h:128
+
@ MQTTPubCompSend
The library will send a PUBCOMP for a received PUBREL.
Definition: core_mqtt.h:125
+
@ MQTTStateNull
An empty state with no corresponding PUBLISH.
Definition: core_mqtt.h:120
+
@ MQTTPublishSend
The library will send an outgoing PUBLISH packet.
Definition: core_mqtt.h:121
+
@ MQTTPubAckPending
The library is awaiting a PUBACK for an outgoing PUBLISH.
Definition: core_mqtt.h:126
+
@ MQTTPublishDone
The PUBLISH has been completed.
Definition: core_mqtt.h:130
+
@ MQTTSubAckSuccessQos2
Success with a maximum delivery at QoS 2.
Definition: core_mqtt.h:153
+
@ MQTTSubAckSuccessQos1
Success with a maximum delivery at QoS 1.
Definition: core_mqtt.h:152
+
@ MQTTSubAckSuccessQos0
Success with a maximum delivery at QoS 0.
Definition: core_mqtt.h:151
+
@ MQTTSubAckFailure
Failure.
Definition: core_mqtt.h:154
+
@ MQTTPuback
PUBACKs are sent in response to a QoS 1 PUBLISH.
Definition: core_mqtt.h:139
+
@ MQTTPubrec
PUBRECs are sent in response to a QoS 2 PUBLISH.
Definition: core_mqtt.h:140
+
@ MQTTPubcomp
PUBCOMPs are sent in response to a PUBREL.
Definition: core_mqtt.h:142
+
@ MQTTPubrel
PUBRELs are sent in response to a PUBREC.
Definition: core_mqtt.h:141
+
@ MQTTNotConnected
MQTT Connection is inactive.
Definition: core_mqtt.h:110
+
@ MQTTConnected
MQTT Connection is active.
Definition: core_mqtt.h:111
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
uint32_t lastPacketTxTime
Timestamp of the last packet sent by the library.
Definition: core_mqtt.h:227
+
MQTTFixedBuffer_t networkBuffer
The buffer used in sending and receiving packets from the network.
Definition: core_mqtt.h:202
+
size_t outgoingPublishRecordMaxCount
The maximum number of outgoing publish records.
Definition: core_mqtt.h:187
+
size_t index
Index to keep track of the number of bytes received in network buffer.
Definition: core_mqtt.h:243
+
MQTTConnectionStatus_t connectStatus
Whether the context currently has a connection to the broker.
Definition: core_mqtt.h:212
+
MQTTPubAckInfo_t * outgoingPublishRecords
State engine records for outgoing publishes.
Definition: core_mqtt.h:177
+
uint32_t lastPacketRxTime
Timestamp of the last packet received by the library.
Definition: core_mqtt.h:232
+
MQTTEventCallback_t appCallback
Callback function used to give deserialized MQTT packets to the application.
Definition: core_mqtt.h:222
+
TransportInterface_t transportInterface
The transport interface used by the MQTT connection.
Definition: core_mqtt.h:197
+
size_t incomingPublishRecordMaxCount
The maximum number of incoming publish records.
Definition: core_mqtt.h:192
+
MQTTGetCurrentTimeFunc_t getTime
Function used to get millisecond timestamps.
Definition: core_mqtt.h:217
+
bool waitingForPingResp
If the library is currently awaiting a PINGRESP.
Definition: core_mqtt.h:248
+
uint32_t pingReqSendTimeMs
Timestamp of the last sent PINGREQ.
Definition: core_mqtt.h:247
+
uint16_t nextPacketId
The next available ID for outgoing MQTT packets.
Definition: core_mqtt.h:207
+
bool controlPacketSent
Whether the library sent a packet during a call of MQTT_ProcessLoop or MQTT_ReceiveLoop.
Definition: core_mqtt.h:238
+
MQTTPubAckInfo_t * incomingPublishRecords
State engine records for incoming publishes.
Definition: core_mqtt.h:182
+
uint16_t keepAliveIntervalSec
Keep Alive interval.
Definition: core_mqtt.h:246
+
Struct to hold deserialized packet information for an MQTTEventCallback_t callback.
Definition: core_mqtt.h:257
+
MQTTStatus_t deserializationResult
Return code of deserialization.
Definition: core_mqtt.h:260
+
MQTTPublishInfo_t * pPublishInfo
Pointer to deserialized publish info.
Definition: core_mqtt.h:259
+
uint16_t packetIdentifier
Packet ID of deserialized packet.
Definition: core_mqtt.h:258
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+
An element of the state engine records for QoS 1 or Qos 2 publishes.
Definition: core_mqtt.h:162
+
MQTTQoS_t qos
The QoS of the original PUBLISH.
Definition: core_mqtt.h:164
+
MQTTPublishState_t publishState
The current state of the publish process.
Definition: core_mqtt.h:165
+
uint16_t packetId
The packet ID of the original PUBLISH.
Definition: core_mqtt.h:163
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+
The transport layer interface.
Definition: transport_interface.h:299
+
Transport interface definitions to send and receive data over the network.
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/core__mqtt__config__defaults_8h.html b/v1.3.0/coreMQTT/core__mqtt__config__defaults_8h.html new file mode 100644 index 00000000..2d920853 --- /dev/null +++ b/v1.3.0/coreMQTT/core__mqtt__config__defaults_8h.html @@ -0,0 +1,396 @@ + + + + + + + +coreMQTT: core_mqtt_config_defaults.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_config_defaults.h File Reference
+
+
+ +

This represents the default values for the configuration macros for the MQTT library. +More...

+
#include "core_mqtt_config.h"
+
+

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Macros

#define MQTT_DO_NOT_USE_CUSTOM_CONFIG
 Define this macro to build the MQTT library without the custom config file core_mqtt_config.h.
 
+#define MQTT_SUB_UNSUB_MAX_VECTORS   ( 4U )
 Maximum number of vectors in subscribe and unsubscribe packet.
 
#define MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT   ( 5U )
 The number of retries for receiving CONNACK.
 
#define MQTT_PINGRESP_TIMEOUT_MS   ( 5000U )
 Maximum number of milliseconds to wait for a ping response to a ping request as part of the keep-alive mechanism.
 
#define PACKET_TX_TIMEOUT_MS   ( 30000U )
 Maximum number of milliseconds of TX inactivity to wait before initiating a PINGREQ.
 
#define PACKET_RX_TIMEOUT_MS   ( 30000U )
 Maximum number of milliseconds of RX inactivity to wait before initiating a PINGREQ.
 
#define MQTT_RECV_POLLING_TIMEOUT_MS   ( 10U )
 The maximum duration between non-empty network reads while receiving an MQTT packet via the MQTT_ProcessLoop or MQTT_ReceiveLoop API functions.
 
#define MQTT_SEND_TIMEOUT_MS   ( 20000U )
 The maximum duration allowed to send an MQTT packet over the transport interface.
 
#define LogError(message)
 Macro that is called in the MQTT library for logging "Error" level messages.
 
#define LogWarn(message)
 Macro that is called in the MQTT library for logging "Warning" level messages.
 
#define LogInfo(message)
 Macro that is called in the MQTT library for logging "Info" level messages.
 
#define LogDebug(message)
 Macro that is called in the MQTT library for logging "Debug" level messages.
 
+

Detailed Description

+

This represents the default values for the configuration macros for the MQTT library.

+
Note
This file SHOULD NOT be modified. If custom values are needed for any configuration macro, a core_mqtt_config.h file should be provided to the MQTT library to override the default values defined in this file. To use the custom config file, the MQTT_DO_NOT_USE_CUSTOM_CONFIG preprocessor macro SHOULD NOT be set.
+

Macro Definition Documentation

+ +

◆ MQTT_DO_NOT_USE_CUSTOM_CONFIG

+ +
+
+ + + + +
#define MQTT_DO_NOT_USE_CUSTOM_CONFIG
+
+ +

Define this macro to build the MQTT library without the custom config file core_mqtt_config.h.

+

Without the custom config, the MQTT library builds with default values of config macros defined in core_mqtt_config_defaults.h file.

+

If a custom config is provided, then MQTT_DO_NOT_USE_CUSTOM_CONFIG should not be defined.

+ +
+
+ +

◆ MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT

+ +
+
+ + + + +
#define MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT   ( 5U )
+
+ +

The number of retries for receiving CONNACK.

+

The MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT will be used only when the timeoutMs parameter of MQTT_Connect is passed as 0 . The transport receive for CONNACK will be retried MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT times before timing out. A value of 0 for this config will cause the transport receive for CONNACK to be invoked only once.

+

Possible values: Any positive 16 bit integer.
+ Default value: 5

+ +
+
+ +

◆ MQTT_PINGRESP_TIMEOUT_MS

+ +
+
+ + + + +
#define MQTT_PINGRESP_TIMEOUT_MS   ( 5000U )
+
+ +

Maximum number of milliseconds to wait for a ping response to a ping request as part of the keep-alive mechanism.

+

If a ping response is not received before this timeout, then MQTT_ProcessLoop will return MQTTKeepAliveTimeout.

+
Note
If this value is more than half of the keep alive interval, and the server does not receive the previous ping request, then it is likely that the server will disconnect the client before MQTTKeepAliveTimeout can be returned.
+
+If a dummy implementation of the MQTTGetCurrentTimeFunc_t timer function, is supplied to the library, then the keep-alive mechanism is not supported by the MQTT_ProcessLoop API function. In that case, the value of MQTT_PINGRESP_TIMEOUT_MS is irrelevant to the behavior of the library.
+

Possible values: Any positive integer up to SIZE_MAX.
+ Default value: 5000

+ +
+
+ +

◆ PACKET_TX_TIMEOUT_MS

+ +
+
+ + + + +
#define PACKET_TX_TIMEOUT_MS   ( 30000U )
+
+ +

Maximum number of milliseconds of TX inactivity to wait before initiating a PINGREQ.

+
Note
If this value is less than the keep alive interval than it will be used instead.
+

Possible values: Any positive integer up to SIZE_MAX.
+ Default value: '30000'

+ +
+
+ +

◆ PACKET_RX_TIMEOUT_MS

+ +
+
+ + + + +
#define PACKET_RX_TIMEOUT_MS   ( 30000U )
+
+ +

Maximum number of milliseconds of RX inactivity to wait before initiating a PINGREQ.

+

Possible values: Any positive integer up to SIZE_MAX.
+ Default value: '30000'

+ +
+
+ +

◆ MQTT_RECV_POLLING_TIMEOUT_MS

+ +
+
+ + + + +
#define MQTT_RECV_POLLING_TIMEOUT_MS   ( 10U )
+
+ +

The maximum duration between non-empty network reads while receiving an MQTT packet via the MQTT_ProcessLoop or MQTT_ReceiveLoop API functions.

+

When an incoming MQTT packet is detected, the transport receive function may be called multiple times until all of the expected number of bytes of the packet are received. This timeout represents the maximum polling duration that is allowed without any data reception from the network for the incoming packet.

+

If the timeout expires, the MQTT_ProcessLoop and MQTT_ReceiveLoop functions return MQTTRecvFailed.

+
Note
If a dummy implementation of the MQTTGetCurrentTimeFunc_t timer function, is supplied to the library, then MQTT_RECV_POLLING_TIMEOUT_MS MUST be set to 0.
+

Possible values: Any positive 32 bit integer. Recommended to use a small timeout value.
+ Default value: 10

+ +
+
+ +

◆ MQTT_SEND_TIMEOUT_MS

+ +
+
+ + + + +
#define MQTT_SEND_TIMEOUT_MS   ( 20000U )
+
+ +

The maximum duration allowed to send an MQTT packet over the transport interface.

+

When sending an MQTT packet, the transport send or writev functions may be called multiple times until all of the required number of bytes are sent. This timeout represents the maximum duration that is allowed to send the MQTT packet while calling the transport send or writev functions.

+

If the timeout expires, MQTTSendFailed will be returned by the public API functions.

+
Note
If a dummy implementation of the MQTTGetCurrentTimeFunc_t timer function, is supplied to the library, then MQTT_SEND_TIMEOUT_MS MUST be set to 0.
+

Possible values: Any positive 32 bit integer.
+ Default value: 20000

+ +
+
+ +

◆ LogError

+ +
+
+ + + + + + + + +
#define LogError( message)
+
+ +

Macro that is called in the MQTT library for logging "Error" level messages.

+

To enable error level logging in the MQTT library, this macro should be mapped to the application-specific logging implementation that supports error logging.

+
Note
This logging macro is called in the MQTT library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Error logging is turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+ +
+
+ +

◆ LogWarn

+ +
+
+ + + + + + + + +
#define LogWarn( message)
+
+ +

Macro that is called in the MQTT library for logging "Warning" level messages.

+

To enable warning level logging in the MQTT library, this macro should be mapped to the application-specific logging implementation that supports warning logging.

+
Note
This logging macro is called in the MQTT library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Warning logs are turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+ +
+
+ +

◆ LogInfo

+ +
+
+ + + + + + + + +
#define LogInfo( message)
+
+ +

Macro that is called in the MQTT library for logging "Info" level messages.

+

To enable info level logging in the MQTT library, this macro should be mapped to the application-specific logging implementation that supports info logging.

+
Note
This logging macro is called in the MQTT library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Info logging is turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+ +
+
+ +

◆ LogDebug

+ +
+
+ + + + + + + + +
#define LogDebug( message)
+
+ +

Macro that is called in the MQTT library for logging "Debug" level messages.

+

To enable debug level logging from MQTT library, this macro should be mapped to the application-specific logging implementation that supports debug logging.

+
Note
This logging macro is called in the MQTT library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Debug logging is turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+ +
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/core__mqtt__config__defaults_8h_source.html b/v1.3.0/coreMQTT/core__mqtt__config__defaults_8h_source.html new file mode 100644 index 00000000..87ca718c --- /dev/null +++ b/v1.3.0/coreMQTT/core__mqtt__config__defaults_8h_source.html @@ -0,0 +1,218 @@ + + + + + + + +coreMQTT: core_mqtt_config_defaults.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
core_mqtt_config_defaults.h
+
+
+Go to the documentation of this file.
1/*
+
2 * coreMQTT v2.3.1
+
3 * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
4 *
+
5 * SPDX-License-Identifier: MIT
+
6 *
+
7 * Permission is hereby granted, free of charge, to any person obtaining a copy of
+
8 * this software and associated documentation files (the "Software"), to deal in
+
9 * the Software without restriction, including without limitation the rights to
+
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
11 * the Software, and to permit persons to whom the Software is furnished to do so,
+
12 * subject to the following conditions:
+
13 *
+
14 * The above copyright notice and this permission notice shall be included in all
+
15 * copies or substantial portions of the Software.
+
16 *
+
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
23 */
+
24
+
37#ifndef CORE_MQTT_CONFIG_DEFAULTS_H_
+
38#define CORE_MQTT_CONFIG_DEFAULTS_H_
+
39
+
40/* *INDENT-OFF* */
+
41#ifdef __cplusplus
+
42 extern "C" {
+
43#endif
+
44/* *INDENT-ON* */
+
45
+
46/* MQTT_DO_NOT_USE_CUSTOM_CONFIG allows building the MQTT library
+
47 * without a custom config. If a custom config is provided, the
+
48 * MQTT_DO_NOT_USE_CUSTOM_CONFIG macro should not be defined. */
+
49#ifndef MQTT_DO_NOT_USE_CUSTOM_CONFIG
+
50/* Include custom config file before other headers. */
+
51 #include "core_mqtt_config.h"
+
52#endif
+
53
+
54/* The macro definition for MQTT_DO_NOT_USE_CUSTOM_CONFIG is for Doxygen
+
55 * documentation only. */
+
56
+
67#ifdef DOXYGEN
+
68 #define MQTT_DO_NOT_USE_CUSTOM_CONFIG
+
69#endif
+
70
+
75#ifndef MQTT_SUB_UNSUB_MAX_VECTORS
+
76 #define MQTT_SUB_UNSUB_MAX_VECTORS ( 4U )
+
77#endif
+
78
+
91#ifndef MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT
+
92/* Default value for the CONNACK receive retries. */
+
93 #define MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT ( 5U )
+
94#endif
+
95
+
115#ifndef MQTT_PINGRESP_TIMEOUT_MS
+
116/* Wait 5 seconds by default for a ping response. */
+
117 #define MQTT_PINGRESP_TIMEOUT_MS ( 5000U )
+
118#endif
+
119
+
130#ifndef PACKET_TX_TIMEOUT_MS
+
131 #define PACKET_TX_TIMEOUT_MS ( 30000U )
+
132#endif
+
133
+
142#ifndef PACKET_RX_TIMEOUT_MS
+
143 #define PACKET_RX_TIMEOUT_MS ( 30000U )
+
144#endif
+
145
+
167#ifndef MQTT_RECV_POLLING_TIMEOUT_MS
+
168 #define MQTT_RECV_POLLING_TIMEOUT_MS ( 10U )
+
169#endif
+
170
+
190#ifndef MQTT_SEND_TIMEOUT_MS
+
191 #define MQTT_SEND_TIMEOUT_MS ( 20000U )
+
192#endif
+
193
+
194#ifdef MQTT_SEND_RETRY_TIMEOUT_MS
+
195 #error MQTT_SEND_RETRY_TIMEOUT_MS is deprecated. Instead use MQTT_SEND_TIMEOUT_MS.
+
196#endif
+
197
+
214#ifndef LogError
+
215 #define LogError( message )
+
216#endif
+
217
+
234#ifndef LogWarn
+
235 #define LogWarn( message )
+
236#endif
+
237
+
254#ifndef LogInfo
+
255 #define LogInfo( message )
+
256#endif
+
257
+
274#ifndef LogDebug
+
275 #define LogDebug( message )
+
276#endif
+
277
+
278/* *INDENT-OFF* */
+
279#ifdef __cplusplus
+
280 }
+
281#endif
+
282/* *INDENT-ON* */
+
283
+
284#endif /* ifndef CORE_MQTT_CONFIG_DEFAULTS_H_ */
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/core__mqtt__serializer_8c.html b/v1.3.0/coreMQTT/core__mqtt__serializer_8c.html new file mode 100644 index 00000000..127482a9 --- /dev/null +++ b/v1.3.0/coreMQTT/core__mqtt__serializer_8c.html @@ -0,0 +1,3003 @@ + + + + + + + +coreMQTT: core_mqtt_serializer.c File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_serializer.c File Reference
+
+
+ +

Implements the user-facing functions in core_mqtt_serializer.h. +More...

+
#include <string.h>
+#include <assert.h>
+#include "core_mqtt_serializer.h"
+#include "core_mqtt_config_defaults.h"
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Macros

+#define MQTT_VERSION_3_1_1   ( ( uint8_t ) 4U )
 MQTT protocol version 3.1.1.
 
+#define MQTT_PACKET_CONNECT_HEADER_SIZE   ( 10UL )
 Size of the fixed and variable header of a CONNECT packet.
 
+#define MQTT_CONNECT_FLAG_CLEAN   ( 1 )
 Clean session.
 
+#define MQTT_CONNECT_FLAG_WILL   ( 2 )
 Will present.
 
+#define MQTT_CONNECT_FLAG_WILL_QOS1   ( 3 )
 Will QoS 1.
 
+#define MQTT_CONNECT_FLAG_WILL_QOS2   ( 4 )
 Will QoS 2.
 
+#define MQTT_CONNECT_FLAG_WILL_RETAIN   ( 5 )
 Will retain.
 
+#define MQTT_CONNECT_FLAG_PASSWORD   ( 6 )
 Password present.
 
+#define MQTT_CONNECT_FLAG_USERNAME   ( 7 )
 User name present.
 
+#define MQTT_PUBLISH_FLAG_RETAIN   ( 0 )
 MQTT PUBLISH retain flag.
 
+#define MQTT_PUBLISH_FLAG_QOS1   ( 1 )
 MQTT PUBLISH QoS1 flag.
 
+#define MQTT_PUBLISH_FLAG_QOS2   ( 2 )
 MQTT PUBLISH QoS2 flag.
 
+#define MQTT_PUBLISH_FLAG_DUP   ( 3 )
 MQTT PUBLISH duplicate flag.
 
+#define MQTT_DISCONNECT_PACKET_SIZE   ( 2UL )
 The size of MQTT DISCONNECT packets, per MQTT spec.
 
+#define MQTT_PACKET_PINGREQ_SIZE   ( 2UL )
 A PINGREQ packet is always 2 bytes in size, defined by MQTT 3.1.1 spec.
 
+#define MQTT_DISCONNECT_REMAINING_LENGTH   ( ( uint8_t ) 0 )
 The Remaining Length field of MQTT disconnect packets, per MQTT spec.
 
+#define MQTT_PACKET_CONNACK_REMAINING_LENGTH   ( ( uint8_t ) 2U )
 A CONNACK packet always has a "Remaining length" of 2.
 
+#define MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK   ( ( uint8_t ) 0x01U )
 The "Session Present" bit is always the lowest bit.
 
+#define MQTT_PACKET_SIMPLE_ACK_REMAINING_LENGTH   ( ( uint8_t ) 2 )
 PUBACK, PUBREC, PUBREl, PUBCOMP, UNSUBACK Remaining length.
 
+#define MQTT_PACKET_PINGRESP_REMAINING_LENGTH   ( 0U )
 A PINGRESP packet always has a "Remaining length" of 0.
 
+#define MQTT_MAX_REMAINING_LENGTH   ( 268435455UL )
 Per the MQTT 3.1.1 spec, the largest "Remaining Length" of an MQTT packet is this value, 256 MB.
 
+#define UINT8_SET_BIT(x, position)   ( ( x ) = ( uint8_t ) ( ( x ) | ( 0x01U << ( position ) ) ) )
 Set a bit in an 8-bit unsigned integer.
 
#define UINT8_CHECK_BIT(x, position)   ( ( ( x ) & ( 0x01U << ( position ) ) ) == ( 0x01U << ( position ) ) )
 Macro for checking if a bit is set in a 1-byte unsigned int.
 
+#define UINT16_HIGH_BYTE(x)   ( ( uint8_t ) ( ( x ) >> 8 ) )
 Get the high byte of a 16-bit unsigned integer.
 
+#define UINT16_LOW_BYTE(x)   ( ( uint8_t ) ( ( x ) & 0x00ffU ) )
 Get the low byte of a 16-bit unsigned integer.
 
#define UINT16_DECODE(ptr)
 Macro for decoding a 2-byte unsigned int from a sequence of bytes.
 
#define MQTT_REMAINING_LENGTH_INVALID   ( ( size_t ) 268435456 )
 A value that represents an invalid remaining length.
 
#define MQTT_MIN_PUBLISH_REMAINING_LENGTH_QOS0   ( 3U )
 The minimum remaining length for a QoS 0 PUBLISH.
 
+ + + + +

+Enumerations

enum  MQTTSubscriptionType_t { MQTT_SUBSCRIBE +, MQTT_UNSUBSCRIBE + }
 MQTT Subscription packet types. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

static void serializePublishCommon (const MQTTPublishInfo_t *pPublishInfo, size_t remainingLength, uint16_t packetIdentifier, const MQTTFixedBuffer_t *pFixedBuffer, bool serializePayload)
 Serializes MQTT PUBLISH packet into the buffer provided.
 
static bool calculatePublishPacketSize (const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize)
 Calculates the packet size and remaining length of an MQTT PUBLISH packet.
 
static MQTTStatus_t calculateSubscriptionPacketSize (const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize, MQTTSubscriptionType_t subscriptionType)
 Calculates the packet size and remaining length of an MQTT SUBSCRIBE or UNSUBSCRIBE packet.
 
static MQTTStatus_t validateSubscriptionSerializeParams (const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
 Validates parameters of MQTT_SerializeSubscribe or MQTT_SerializeUnsubscribe.
 
static void serializeConnectPacket (const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT CONNECT packet in the given buffer.
 
static void logConnackResponse (uint8_t responseCode)
 Prints the appropriate message for the CONNACK response code if logs are enabled.
 
static uint8_t * encodeRemainingLength (uint8_t *pDestination, size_t length)
 Encodes the remaining length of the packet using the variable length encoding scheme provided in the MQTT v3.1.1 specification.
 
static size_t remainingLengthEncodedSize (size_t length)
 Retrieve the size of the remaining length if it were to be encoded.
 
static uint8_t * encodeString (uint8_t *pDestination, const char *pSource, uint16_t sourceLength)
 Encode a string whose size is at maximum 16 bits in length.
 
static size_t getRemainingLength (TransportRecv_t recvFunc, NetworkContext_t *pNetworkContext)
 Retrieves and decodes the Remaining Length from the network interface by reading a single byte at a time.
 
static MQTTStatus_t processRemainingLength (const uint8_t *pBuffer, const size_t *pIndex, MQTTPacketInfo_t *pIncomingPacket)
 Retrieves, decodes and stores the Remaining Length from the network interface by reading a single byte at a time.
 
static bool incomingPacketValid (uint8_t packetType)
 Check if an incoming packet type is valid.
 
static MQTTStatus_t checkPublishRemainingLength (size_t remainingLength, MQTTQoS_t qos, size_t qos0Minimum)
 Check the remaining length of an incoming PUBLISH packet against some value for QoS 0, or for QoS 1 and 2.
 
static MQTTStatus_t processPublishFlags (uint8_t publishFlags, MQTTPublishInfo_t *pPublishInfo)
 Process the flags of an incoming PUBLISH packet.
 
static MQTTStatus_t deserializeConnack (const MQTTPacketInfo_t *pConnack, bool *pSessionPresent)
 Deserialize a CONNACK packet.
 
static MQTTStatus_t readSubackStatus (size_t statusCount, const uint8_t *pStatusStart)
 Decode the status bytes of a SUBACK packet to a MQTTStatus_t.
 
static MQTTStatus_t deserializeSuback (const MQTTPacketInfo_t *pSuback, uint16_t *pPacketIdentifier)
 Deserialize a SUBACK packet.
 
static MQTTStatus_t deserializePublish (const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo)
 Deserialize a PUBLISH packet received from the server.
 
static MQTTStatus_t deserializeSimpleAck (const MQTTPacketInfo_t *pAck, uint16_t *pPacketIdentifier)
 Deserialize an UNSUBACK, PUBACK, PUBREC, PUBREL, or PUBCOMP packet.
 
static MQTTStatus_t deserializePingresp (const MQTTPacketInfo_t *pPingresp)
 Deserialize a PINGRESP packet.
 
MQTTStatus_t MQTT_SerializePublishHeaderWithoutTopic (const MQTTPublishInfo_t *pPublishInfo, size_t remainingLength, uint8_t *pBuffer, size_t *headerSize)
 Serialize an MQTT PUBLISH packet header without the topic string in the given buffer. This function will add the topic string length to the provided buffer. This helps reduce an unnecessary copy of the topic string into the buffer.
 
uint8_t * MQTT_SerializeConnectFixedHeader (uint8_t *pIndex, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength)
 Serialize the fixed part of the connect packet header.
 
MQTTStatus_t MQTT_GetConnectPacketSize (const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize)
 Get the size and Remaining Length of an MQTT CONNECT packet.
 
MQTTStatus_t MQTT_SerializeConnect (const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT CONNECT packet in the given fixed buffer pFixedBuffer.
 
MQTTStatus_t MQTT_GetSubscribePacketSize (const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
 Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.
 
uint8_t * MQTT_SerializeSubscribeHeader (size_t remainingLength, uint8_t *pIndex, uint16_t packetId)
 Serialize the fixed part of the subscribe packet header.
 
uint8_t * MQTT_SerializeUnsubscribeHeader (size_t remainingLength, uint8_t *pIndex, uint16_t packetId)
 Serialize the fixed part of the unsubscribe packet header.
 
MQTTStatus_t MQTT_SerializeSubscribe (const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT SUBSCRIBE packet in the given buffer.
 
MQTTStatus_t MQTT_GetUnsubscribePacketSize (const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
 Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.
 
MQTTStatus_t MQTT_SerializeUnsubscribe (const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT UNSUBSCRIBE packet in the given buffer.
 
MQTTStatus_t MQTT_GetPublishPacketSize (const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize)
 Get the packet size and remaining length of an MQTT PUBLISH packet.
 
MQTTStatus_t MQTT_SerializePublish (const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT PUBLISH packet in the given buffer.
 
MQTTStatus_t MQTT_SerializePublishHeader (const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer, size_t *pHeaderSize)
 Serialize an MQTT PUBLISH packet header in the given buffer.
 
MQTTStatus_t MQTT_SerializeAck (const MQTTFixedBuffer_t *pFixedBuffer, uint8_t packetType, uint16_t packetId)
 Serialize an MQTT PUBACK, PUBREC, PUBREL, or PUBCOMP into the given buffer.
 
MQTTStatus_t MQTT_GetDisconnectPacketSize (size_t *pPacketSize)
 Get the size of an MQTT DISCONNECT packet.
 
MQTTStatus_t MQTT_SerializeDisconnect (const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT DISCONNECT packet into the given buffer.
 
MQTTStatus_t MQTT_GetPingreqPacketSize (size_t *pPacketSize)
 Get the size of an MQTT PINGREQ packet.
 
MQTTStatus_t MQTT_SerializePingreq (const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT PINGREQ packet into the given buffer.
 
MQTTStatus_t MQTT_DeserializePublish (const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo)
 Deserialize an MQTT PUBLISH packet.
 
MQTTStatus_t MQTT_DeserializeAck (const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, bool *pSessionPresent)
 Deserialize an MQTT CONNACK, SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, PUBCOMP, or PINGRESP.
 
MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength (TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket)
 Extract the MQTT packet type and length from incoming packet.
 
MQTTStatus_t MQTT_ProcessIncomingPacketTypeAndLength (const uint8_t *pBuffer, const size_t *pIndex, MQTTPacketInfo_t *pIncomingPacket)
 Extract the MQTT packet type and length from incoming packet.
 
+

Detailed Description

+

Implements the user-facing functions in core_mqtt_serializer.h.

+

Macro Definition Documentation

+ +

◆ UINT8_CHECK_BIT

+ +
+
+ + + + + + + + + + + + + + + + + + +
#define UINT8_CHECK_BIT( x,
 position 
)   ( ( ( x ) & ( 0x01U << ( position ) ) ) == ( 0x01U << ( position ) ) )
+
+ +

Macro for checking if a bit is set in a 1-byte unsigned int.

+
Parameters
+ + + +
[in]xThe unsigned int to check.
[in]positionWhich bit to check.
+
+
+ +
+
+ +

◆ UINT16_DECODE

+ +
+
+ + + + + + + + +
#define UINT16_DECODE( ptr)
+
+Value:
( uint16_t ) ( ( ( ( uint16_t ) ptr[ 0 ] ) << 8 ) | \
+
( ( uint16_t ) ptr[ 1 ] ) )
+
+

Macro for decoding a 2-byte unsigned int from a sequence of bytes.

+
Parameters
+ + +
[in]ptrA uint8_t* that points to the high byte.
+
+
+ +
+
+ +

◆ MQTT_REMAINING_LENGTH_INVALID

+ +
+
+ + + + +
#define MQTT_REMAINING_LENGTH_INVALID   ( ( size_t ) 268435456 )
+
+ +

A value that represents an invalid remaining length.

+

This value is greater than what is allowed by the MQTT specification.

+ +
+
+ +

◆ MQTT_MIN_PUBLISH_REMAINING_LENGTH_QOS0

+ +
+
+ + + + +
#define MQTT_MIN_PUBLISH_REMAINING_LENGTH_QOS0   ( 3U )
+
+ +

The minimum remaining length for a QoS 0 PUBLISH.

+

Includes two bytes for topic name length and one byte for topic name.

+ +
+
+

Enumeration Type Documentation

+ +

◆ MQTTSubscriptionType_t

+ +
+
+ + + + +
enum MQTTSubscriptionType_t
+
+ +

MQTT Subscription packet types.

+ + + +
Enumerator
MQTT_SUBSCRIBE 

The type is a SUBSCRIBE packet.

+
MQTT_UNSUBSCRIBE 

The type is a UNSUBSCRIBE packet.

+
+ +
+
+

Function Documentation

+ +

◆ serializePublishCommon()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static void serializePublishCommon (const MQTTPublishInfo_tpPublishInfo,
size_t remainingLength,
uint16_t packetIdentifier,
const MQTTFixedBuffer_tpFixedBuffer,
bool serializePayload 
)
+
+static
+
+ +

Serializes MQTT PUBLISH packet into the buffer provided.

+

This function serializes MQTT PUBLISH packet into MQTTFixedBuffer_t.pBuffer. Copy of the payload into the buffer is done as part of the serialization only if serializePayload is true.

+

param[in] pPublishInfo Publish information.

+

param[in] remainingLength Remaining length of the PUBLISH packet.

+

param[in] packetIdentifier Packet identifier of PUBLISH packet.

+

param[in, out] pFixedBuffer Buffer to which PUBLISH packet will be serialized.

+

param[in] serializePayload Copy payload to the serialized buffer only if true. Only PUBLISH header will be serialized if false.

+ +
+
+ +

◆ calculatePublishPacketSize()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static bool calculatePublishPacketSize (const MQTTPublishInfo_tpPublishInfo,
size_t * pRemainingLength,
size_t * pPacketSize 
)
+
+static
+
+ +

Calculates the packet size and remaining length of an MQTT PUBLISH packet.

+
Parameters
+ + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[out]pRemainingLengthThe Remaining Length of the MQTT PUBLISH packet.
[out]pPacketSizeThe total size of the MQTT PUBLISH packet.
+
+
+
Returns
false if the packet would exceed the size allowed by the MQTT spec; true otherwise.
+ +
+
+ +

◆ calculateSubscriptionPacketSize()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t calculateSubscriptionPacketSize (const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
size_t * pRemainingLength,
size_t * pPacketSize,
MQTTSubscriptionType_t subscriptionType 
)
+
+static
+
+ +

Calculates the packet size and remaining length of an MQTT SUBSCRIBE or UNSUBSCRIBE packet.

+
Parameters
+ + + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[out]pRemainingLengthThe Remaining Length of the MQTT SUBSCRIBE or UNSUBSCRIBE packet.
[out]pPacketSizeThe total size of the MQTT MQTT SUBSCRIBE or UNSUBSCRIBE packet.
[in]subscriptionTypeMQTT_SUBSCRIBE or MQTT_UNSUBSCRIBE.
+
+
+

MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec or a subscription is empty; MQTTSuccess otherwise.

+ +
+
+ +

◆ validateSubscriptionSerializeParams()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t validateSubscriptionSerializeParams (const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer 
)
+
+static
+
+ +

Validates parameters of MQTT_SerializeSubscribe or MQTT_SerializeUnsubscribe.

+
Parameters
+ + + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdPacket identifier.
[in]remainingLengthRemaining length of the packet.
[in]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+ +
+
+ +

◆ serializeConnectPacket()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static void serializeConnectPacket (const MQTTConnectInfo_tpConnectInfo,
const MQTTPublishInfo_tpWillInfo,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer 
)
+
+static
+
+ +

Serialize an MQTT CONNECT packet in the given buffer.

+
Parameters
+ + + + + +
[in]pConnectInfoMQTT CONNECT packet parameters.
[in]pWillInfoLast Will and Testament. Pass NULL if not used.
[in]remainingLengthRemaining Length of MQTT CONNECT packet.
[out]pFixedBufferBuffer for packet serialization.
+
+
+ +
+
+ +

◆ logConnackResponse()

+ +
+
+ + + + + +
+ + + + + + + + +
static void logConnackResponse (uint8_t responseCode)
+
+static
+
+ +

Prints the appropriate message for the CONNACK response code if logs are enabled.

+
Parameters
+ + +
[in]responseCodeMQTT standard CONNACK response code.
+
+
+ +
+
+ +

◆ encodeRemainingLength()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static uint8_t * encodeRemainingLength (uint8_t * pDestination,
size_t length 
)
+
+static
+
+ +

Encodes the remaining length of the packet using the variable length encoding scheme provided in the MQTT v3.1.1 specification.

+
Parameters
+ + + +
[out]pDestinationThe destination buffer to store the encoded remaining length.
[in]lengthThe remaining length to encode.
+
+
+
Returns
The location of the byte following the encoded value.
+ +
+
+ +

◆ remainingLengthEncodedSize()

+ +
+
+ + + + + +
+ + + + + + + + +
static size_t remainingLengthEncodedSize (size_t length)
+
+static
+
+ +

Retrieve the size of the remaining length if it were to be encoded.

+
Parameters
+ + +
[in]lengthThe remaining length to be encoded.
+
+
+
Returns
The size of the remaining length if it were to be encoded.
+ +
+
+ +

◆ encodeString()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static uint8_t * encodeString (uint8_t * pDestination,
const char * pSource,
uint16_t sourceLength 
)
+
+static
+
+ +

Encode a string whose size is at maximum 16 bits in length.

+
Parameters
+ + + + +
[out]pDestinationDestination buffer for the encoding.
[in]pSourceThe source string to encode.
[in]sourceLengthThe length of the source string to encode.
+
+
+
Returns
A pointer to the end of the encoded string.
+ +
+
+ +

◆ getRemainingLength()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static size_t getRemainingLength (TransportRecv_t recvFunc,
NetworkContext_tpNetworkContext 
)
+
+static
+
+ +

Retrieves and decodes the Remaining Length from the network interface by reading a single byte at a time.

+
Parameters
+ + + +
[in]recvFuncNetwork interface receive function.
[in]pNetworkContextNetwork interface context to the receive function.
+
+
+
Returns
The Remaining Length of the incoming packet.
+ +
+
+ +

◆ processRemainingLength()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t processRemainingLength (const uint8_t * pBuffer,
const size_t * pIndex,
MQTTPacketInfo_tpIncomingPacket 
)
+
+static
+
+ +

Retrieves, decodes and stores the Remaining Length from the network interface by reading a single byte at a time.

+
Parameters
+ + + + +
[in]pBufferThe buffer holding the raw data to be processed
[in]pIndexPointer to the index within the buffer to marking the end of raw data available.
[in]pIncomingPacketStructure used to hold the fields of the incoming packet.
+
+
+
Returns
MQTTNeedMoreBytes is returned to show that the incoming packet is not yet fully received and decoded. Otherwise, MQTTSuccess shows that processing of the packet was successful.
+ +
+
+ +

◆ incomingPacketValid()

+ +
+
+ + + + + +
+ + + + + + + + +
static bool incomingPacketValid (uint8_t packetType)
+
+static
+
+ +

Check if an incoming packet type is valid.

+
Parameters
+ + +
[in]packetTypeThe packet type to check.
+
+
+
Returns
true if the packet type is valid; false otherwise.
+ +
+
+ +

◆ checkPublishRemainingLength()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t checkPublishRemainingLength (size_t remainingLength,
MQTTQoS_t qos,
size_t qos0Minimum 
)
+
+static
+
+ +

Check the remaining length of an incoming PUBLISH packet against some value for QoS 0, or for QoS 1 and 2.

+

The remaining length for a QoS 1 and 2 packet will always be two greater than for a QoS 0.

+
Parameters
+ + + + +
[in]remainingLengthRemaining length of the PUBLISH packet.
[in]qosThe QoS of the PUBLISH.
[in]qos0MinimumMinimum possible remaining length for a QoS 0 PUBLISH.
+
+
+
Returns
MQTTSuccess or MQTTBadResponse.
+ +
+
+ +

◆ processPublishFlags()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTStatus_t processPublishFlags (uint8_t publishFlags,
MQTTPublishInfo_tpPublishInfo 
)
+
+static
+
+ +

Process the flags of an incoming PUBLISH packet.

+
Parameters
+ + + +
[in]publishFlagsFlags of an incoming PUBLISH.
[in,out]pPublishInfoPointer to MQTTPublishInfo_t struct where output will be written.
+
+
+
Returns
MQTTSuccess or MQTTBadResponse.
+ +
+
+ +

◆ deserializeConnack()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTStatus_t deserializeConnack (const MQTTPacketInfo_tpConnack,
bool * pSessionPresent 
)
+
+static
+
+ +

Deserialize a CONNACK packet.

+

Converts the packet from a stream of bytes to an MQTTStatus_t.

+
Parameters
+ + + +
[in]pConnackPointer to an MQTT packet struct representing a CONNACK.
[out]pSessionPresentWhether a previous session was present.
+
+
+
Returns
MQTTSuccess if CONNACK specifies that CONNECT was accepted; MQTTServerRefused if CONNACK specifies that CONNECT was rejected; MQTTBadResponse if the CONNACK packet doesn't follow MQTT spec.
+ +
+
+ +

◆ readSubackStatus()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTStatus_t readSubackStatus (size_t statusCount,
const uint8_t * pStatusStart 
)
+
+static
+
+ +

Decode the status bytes of a SUBACK packet to a MQTTStatus_t.

+
Parameters
+ + + +
[in]statusCountNumber of status bytes in the SUBACK.
[in]pStatusStartThe first status byte in the SUBACK.
+
+
+
Returns
MQTTSuccess, MQTTServerRefused, or MQTTBadResponse.
+ +
+
+ +

◆ deserializeSuback()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTStatus_t deserializeSuback (const MQTTPacketInfo_tpSuback,
uint16_t * pPacketIdentifier 
)
+
+static
+
+ +

Deserialize a SUBACK packet.

+

Converts the packet from a stream of bytes to an MQTTStatus_t and extracts the packet identifier.

+
Parameters
+ + + +
[in]pSubackPointer to an MQTT packet struct representing a SUBACK.
[out]pPacketIdentifierPacket ID of the SUBACK.
+
+
+
Returns
MQTTSuccess if SUBACK is valid; MQTTBadResponse if SUBACK packet doesn't follow the MQTT spec.
+ +
+
+ +

◆ deserializePublish()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t deserializePublish (const MQTTPacketInfo_tpIncomingPacket,
uint16_t * pPacketId,
MQTTPublishInfo_tpPublishInfo 
)
+
+static
+
+ +

Deserialize a PUBLISH packet received from the server.

+

Converts the packet from a stream of bytes to an MQTTPublishInfo_t and extracts the packet identifier. Also prints out debug log messages about the packet.

+
Parameters
+ + + + +
[in]pIncomingPacketPointer to an MQTT packet struct representing a PUBLISH.
[out]pPacketIdPacket identifier of the PUBLISH.
[out]pPublishInfoPointer to MQTTPublishInfo_t where output is written.
+
+
+
Returns
MQTTSuccess if PUBLISH is valid; MQTTBadResponse if the PUBLISH packet doesn't follow MQTT spec.
+ +
+
+ +

◆ deserializeSimpleAck()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTStatus_t deserializeSimpleAck (const MQTTPacketInfo_tpAck,
uint16_t * pPacketIdentifier 
)
+
+static
+
+ +

Deserialize an UNSUBACK, PUBACK, PUBREC, PUBREL, or PUBCOMP packet.

+

Converts the packet from a stream of bytes to an MQTTStatus_t and extracts the packet identifier.

+
Parameters
+ + + +
[in]pAckPointer to the MQTT packet structure representing the packet.
[out]pPacketIdentifierPacket ID of the ack type packet.
+
+
+
Returns
MQTTSuccess if UNSUBACK, PUBACK, PUBREC, PUBREL, or PUBCOMP is valid; MQTTBadResponse if the packet doesn't follow the MQTT spec.
+ +
+
+ +

◆ deserializePingresp()

+ +
+
+ + + + + +
+ + + + + + + + +
static MQTTStatus_t deserializePingresp (const MQTTPacketInfo_tpPingresp)
+
+static
+
+ +

Deserialize a PINGRESP packet.

+

Converts the packet from a stream of bytes to an MQTTStatus_t.

+
Parameters
+ + +
[in]pPingrespPointer to an MQTT packet struct representing a PINGRESP.
+
+
+
Returns
MQTTSuccess if PINGRESP is valid; MQTTBadResponse if the PINGRESP packet doesn't follow MQTT spec.
+ +
+
+ +

◆ MQTT_SerializePublishHeaderWithoutTopic()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializePublishHeaderWithoutTopic (const MQTTPublishInfo_tpPublishInfo,
size_t remainingLength,
uint8_t * pBuffer,
size_t * headerSize 
)
+
+ +

Serialize an MQTT PUBLISH packet header without the topic string in the given buffer. This function will add the topic string length to the provided buffer. This helps reduce an unnecessary copy of the topic string into the buffer.

+
Parameters
+ + + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]remainingLengthRemaining Length provided by MQTT_GetPublishPacketSize.
[out]pBufferBuffer for packet serialization.
[out]headerSizeSize of the serialized MQTT PUBLISH header.
+
+
+
Returns
MQTTSuccess if the serialization is successful. Otherwise, MQTTBadParameter.
+ +
+
+ +

◆ MQTT_SerializeConnectFixedHeader()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint8_t * MQTT_SerializeConnectFixedHeader (uint8_t * pIndex,
const MQTTConnectInfo_tpConnectInfo,
const MQTTPublishInfo_tpWillInfo,
size_t remainingLength 
)
+
+ +

Serialize the fixed part of the connect packet header.

+
Parameters
+ + + + + +
[out]pIndexPointer to the buffer where the header is to be serialized.
[in]pConnectInfoThe connect information.
[in]pWillInfoThe last will and testament information.
[in]remainingLengthThe remaining length of the packet to be serialized.
+
+
+
Returns
A pointer to the end of the encoded string.
+ +
+
+ +

◆ MQTT_GetConnectPacketSize()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetConnectPacketSize (const MQTTConnectInfo_tpConnectInfo,
const MQTTPublishInfo_tpWillInfo,
size_t * pRemainingLength,
size_t * pPacketSize 
)
+
+ +

Get the size and Remaining Length of an MQTT CONNECT packet.

+

This function must be called before MQTT_SerializeConnect in order to get the size of the MQTT CONNECT packet that is generated from MQTTConnectInfo_t and optional MQTTPublishInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializeConnect must be at least pPacketSize. The provided pConnectInfo and pWillInfo are valid for serialization with MQTT_SerializeConnect only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + + +
[in]pConnectInfoMQTT CONNECT packet parameters.
[in]pWillInfoLast Will and Testament. Pass NULL if not used.
[out]pRemainingLengthThe Remaining Length of the MQTT CONNECT packet.
[out]pPacketSizeThe total size of the MQTT CONNECT packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
+
// Initialize the connection info, the details are out of scope for this example.
+
initializeConnectInfo( &connectInfo );
+
+
// Initialize the optional will info, the details are out of scope for this example.
+
initializeWillInfo( &willInfo );
+
+
// Get the size requirement for the connect packet.
+ +
&connectInfo, &willInfo, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the connect request.
+
}
+
MQTTStatus_t MQTT_GetConnectPacketSize(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the size and Remaining Length of an MQTT CONNECT packet.
Definition: core_mqtt_serializer.c:1690
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+
+
+
+ +

◆ MQTT_SerializeConnect()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializeConnect (const MQTTConnectInfo_tpConnectInfo,
const MQTTPublishInfo_tpWillInfo,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer 
)
+
+ +

Serialize an MQTT CONNECT packet in the given fixed buffer pFixedBuffer.

+

MQTT_GetConnectPacketSize should be called with pConnectInfo and pWillInfo before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetConnectPacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetConnectPacketSize.

+
Parameters
+ + + + + +
[in]pConnectInfoMQTT CONNECT packet parameters.
[in]pWillInfoLast Will and Testament. Pass NULL if not used.
[in]remainingLengthRemaining Length provided by MQTT_GetConnectPacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Assume connectInfo and willInfo are initialized. Get the size requirement for
+
// the connect packet.
+ +
&connectInfo, &willInfo, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the connect packet into the fixed buffer.
+
status = MQTT_SerializeConnect( &connectInfo, &willInfo, remainingLength, &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// The connect packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializeConnect(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT CONNECT packet in the given fixed buffer pFixedBuffer.
Definition: core_mqtt_serializer.c:1790
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
+
+
+ +

◆ MQTT_GetSubscribePacketSize()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetSubscribePacketSize (const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
size_t * pRemainingLength,
size_t * pPacketSize 
)
+
+ +

Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.

+

This function must be called before MQTT_SerializeSubscribe in order to get the size of the MQTT SUBSCRIBE packet that is generated from the list of MQTTSubscribeInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializeSubscribe must be at least pPacketSize. The provided pSubscriptionList is valid for serialization with MQTT_SerializeSubscribe only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[out]pRemainingLengthThe Remaining Length of the MQTT SUBSCRIBE packet.
[out]pPacketSizeThe total size of the MQTT SUBSCRIBE packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
// This is assumed to be a list of filters we want to subscribe to.
+
const char * filters[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// Set each subscription.
+
for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )
+
{
+
subscriptionList[ i ].qos = MQTTQoS0;
+
// Each subscription needs a topic filter.
+
subscriptionList[ i ].pTopicFilter = filters[ i ];
+
subscriptionList[ i ].topicFilterLength = strlen( filters[ i ] );
+
}
+
+
// Get the size requirement for the subscribe packet.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the subscribe request.
+
}
+
MQTTStatus_t MQTT_GetSubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.
Definition: core_mqtt_serializer.c:1848
+
@ MQTTQoS0
Definition: core_mqtt_serializer.h:110
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+
MQTTQoS_t qos
Quality of Service for subscription.
Definition: core_mqtt_serializer.h:184
+
uint16_t topicFilterLength
Length of subscription topic filter.
Definition: core_mqtt_serializer.h:194
+
const char * pTopicFilter
Topic filter to subscribe to.
Definition: core_mqtt_serializer.h:189
+
+
+
+ +

◆ MQTT_SerializeSubscribeHeader()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint8_t * MQTT_SerializeSubscribeHeader (size_t remainingLength,
uint8_t * pIndex,
uint16_t packetId 
)
+
+ +

Serialize the fixed part of the subscribe packet header.

+
Parameters
+ + + + +
[in]remainingLengthThe remaining length of the packet to be serialized.
[in]pIndexPointer to the buffer where the header is to be serialized.
[in]packetIdThe packet ID to be serialized.
+
+
+
Returns
A pointer to the end of the encoded string.
+ +
+
+ +

◆ MQTT_SerializeUnsubscribeHeader()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint8_t * MQTT_SerializeUnsubscribeHeader (size_t remainingLength,
uint8_t * pIndex,
uint16_t packetId 
)
+
+ +

Serialize the fixed part of the unsubscribe packet header.

+
Parameters
+ + + + +
[in]remainingLengthThe remaining length of the packet to be serialized.
[in]pIndexPointer to the buffer where the header is to be serialized.
[in]packetIdThe packet ID to be serialized.
+
+
+
Returns
A pointer to the end of the encoded string.
+ +
+
+ +

◆ MQTT_SerializeSubscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializeSubscribe (const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer 
)
+
+ +

Serialize an MQTT SUBSCRIBE packet in the given buffer.

+

MQTT_GetSubscribePacketSize should be called with pSubscriptionList before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetSubscribePacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetSubscribePacketSize.

+
Parameters
+ + + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetSubscribePacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
uint16_t packetId;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Function to return a valid, unused packet identifier. The details are out of
+
// scope for this example.
+
packetId = getNewPacketId();
+
+
// Assume subscriptionList has been initialized. Get the subscribe packet size.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the subscribe packet into the fixed buffer.
+ +
&subscriptionList[ 0 ],
+
NUMBER_OF_SUBSCRIPTIONS,
+
packetId,
+
remainingLength,
+
&fixedBuffer
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The subscribe packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializeSubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT SUBSCRIBE packet in the given buffer.
Definition: core_mqtt_serializer.c:1932
+
+
+
+ +

◆ MQTT_GetUnsubscribePacketSize()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetUnsubscribePacketSize (const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
size_t * pRemainingLength,
size_t * pPacketSize 
)
+
+ +

Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.

+

This function must be called before MQTT_SerializeUnsubscribe in order to get the size of the MQTT UNSUBSCRIBE packet that is generated from the list of MQTTSubscribeInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializeUnsubscribe must be at least pPacketSize. The provided pSubscriptionList is valid for serialization with MQTT_SerializeUnsubscribe only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[out]pRemainingLengthThe Remaining Length of the MQTT UNSUBSCRIBE packet.
[out]pPacketSizeThe total size of the MQTT UNSUBSCRIBE packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
+
// Initialize the subscribe info. The details are out of scope for this example.
+
initializeSubscribeInfo( &subscriptionList[ 0 ] );
+
+
// Get the size requirement for the unsubscribe packet.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the unsubscribe request.
+
}
+
MQTTStatus_t MQTT_GetUnsubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.
Definition: core_mqtt_serializer.c:1978
+
+
+
+ +

◆ MQTT_SerializeUnsubscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializeUnsubscribe (const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer 
)
+
+ +

Serialize an MQTT UNSUBSCRIBE packet in the given buffer.

+

MQTT_GetUnsubscribePacketSize should be called with pSubscriptionList before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetUnsubscribePacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetUnsubscribePacketSize.

+
Parameters
+ + + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetUnsubscribePacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
uint16_t packetId;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Function to return a valid, unused packet identifier. The details are out of
+
// scope for this example.
+
packetId = getNewPacketId();
+
+
// Assume subscriptionList has been initialized. Get the unsubscribe packet size.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the unsubscribe packet into the fixed buffer.
+ +
&subscriptionList[ 0 ],
+
NUMBER_OF_SUBSCRIPTIONS,
+
packetId,
+
remainingLength,
+
&fixedBuffer
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The unsubscribe packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializeUnsubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT UNSUBSCRIBE packet in the given buffer.
Definition: core_mqtt_serializer.c:2016
+
+
+
+ +

◆ MQTT_GetPublishPacketSize()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetPublishPacketSize (const MQTTPublishInfo_tpPublishInfo,
size_t * pRemainingLength,
size_t * pPacketSize 
)
+
+ +

Get the packet size and remaining length of an MQTT PUBLISH packet.

+

This function must be called before MQTT_SerializePublish in order to get the size of the MQTT PUBLISH packet that is generated from MQTTPublishInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializePublish must be at least pPacketSize. The provided pPublishInfo is valid for serialization with MQTT_SerializePublish only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[out]pRemainingLengthThe Remaining Length of the MQTT PUBLISH packet.
[out]pPacketSizeThe total size of the MQTT PUBLISH packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec or if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
+
// Initialize the publish info.
+
publishInfo.qos = MQTTQoS0;
+
publishInfo.pTopicName = "/some/topic/name";
+
publishInfo.topicNameLength = strlen( publishInfo.pTopicName );
+
publishInfo.pPayload = "Hello World!";
+
publishInfo.payloadLength = strlen( "Hello World!" );
+
+
// Get the size requirement for the publish packet.
+ +
&publishInfo, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the publish.
+
}
+
MQTTStatus_t MQTT_GetPublishPacketSize(const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the packet size and remaining length of an MQTT PUBLISH packet.
Definition: core_mqtt_serializer.c:2057
+
MQTTQoS_t qos
Quality of Service for message.
Definition: core_mqtt_serializer.h:206
+
uint16_t topicNameLength
Length of topic name.
Definition: core_mqtt_serializer.h:226
+
size_t payloadLength
Message payload length.
Definition: core_mqtt_serializer.h:236
+
const char * pTopicName
Topic name on which the message is published.
Definition: core_mqtt_serializer.h:221
+
const void * pPayload
Message payload.
Definition: core_mqtt_serializer.h:231
+
+
+
+ +

◆ MQTT_SerializePublish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializePublish (const MQTTPublishInfo_tpPublishInfo,
uint16_t packetId,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer 
)
+
+ +

Serialize an MQTT PUBLISH packet in the given buffer.

+

This function will serialize complete MQTT PUBLISH packet into the given buffer. If the PUBLISH payload can be sent separately, consider using MQTT_SerializePublishHeader, which will serialize only the PUBLISH header into the buffer.

+

MQTT_GetPublishPacketSize should be called with pPublishInfo before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetPublishPacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetPublishPacketSize.

+
Parameters
+ + + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetPublishPacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
uint16_t packetId;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// A packet identifier is unused for QoS 0 publishes. Otherwise, a valid, unused packet
+
// identifier must be used.
+
packetId = 0;
+
+
// Assume publishInfo has been initialized. Get publish packet size.
+ +
&publishInfo, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the publish packet into the fixed buffer.
+ +
&publishInfo,
+
packetId,
+
remainingLength,
+
&fixedBuffer
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The publish packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializePublish(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT PUBLISH packet in the given buffer.
Definition: core_mqtt_serializer.c:2098
+
+
+
+ +

◆ MQTT_SerializePublishHeader()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializePublishHeader (const MQTTPublishInfo_tpPublishInfo,
uint16_t packetId,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer,
size_t * pHeaderSize 
)
+
+ +

Serialize an MQTT PUBLISH packet header in the given buffer.

+

This function serializes PUBLISH header in to the given buffer. The payload for PUBLISH will not be copied over to the buffer. This will help reduce the memory needed for the buffer and avoid an unwanted copy operation of the PUBLISH payload into the buffer. If the payload also would need to be part of the serialized buffer, consider using MQTT_SerializePublish.

+

MQTT_GetPublishPacketSize should be called with pPublishInfo before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetPublishPacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetPublishPacketSize.

+
Parameters
+ + + + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetPublishPacketSize.
[out]pFixedBufferBuffer for packet serialization.
[out]pHeaderSizeSize of the serialized MQTT PUBLISH header.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0, headerSize = 0;
+
uint16_t packetId;
+
int32_t bytesSent;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// A packet identifier is unused for QoS 0 publishes. Otherwise, a valid, unused packet
+
// identifier must be used.
+
packetId = 0;
+
+
// Assume publishInfo has been initialized. Get the publish packet size.
+ +
&publishInfo, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
// The payload will not be serialized, so the the fixed buffer does not need to hold it.
+
assert( ( packetSize - publishInfo.payloadLength ) <= BUFFER_SIZE );
+
+
// Serialize the publish packet header into the fixed buffer.
+ +
&publishInfo,
+
packetId,
+
remainingLength,
+
&fixedBuffer,
+
&headerSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The publish header and payload can now be sent to the broker.
+
// mqttSocket here is a socket descriptor created and connected to the MQTT
+
// broker outside of this function.
+
bytesSent = send( mqttSocket, ( void * ) fixedBuffer.pBuffer, headerSize, 0 );
+
assert( bytesSent == headerSize );
+
bytesSent = send( mqttSocket, publishInfo.pPayload, publishInfo.payloadLength, 0 );
+
assert( bytesSent == publishInfo.payloadLength );
+
}
+
MQTTStatus_t MQTT_SerializePublishHeader(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer, size_t *pHeaderSize)
Serialize an MQTT PUBLISH packet header in the given buffer.
Definition: core_mqtt_serializer.c:2183
+
+
+
+ +

◆ MQTT_SerializeAck()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializeAck (const MQTTFixedBuffer_tpFixedBuffer,
uint8_t packetType,
uint16_t packetId 
)
+
+ +

Serialize an MQTT PUBACK, PUBREC, PUBREL, or PUBCOMP into the given buffer.

+
Parameters
+ + + + +
[out]pFixedBufferBuffer for packet serialization.
[in]packetTypeByte of the corresponding packet fixed header per the MQTT spec.
[in]packetIdPacket ID of the publish.
+
+
+
Returns
MQTTBadParameter, MQTTNoMemory, or MQTTSuccess.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
uint16_t packetId;
+
uint8_t packetType;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
// The fixed buffer must be large enough to hold 4 bytes.
+
assert( BUFFER_SIZE >= MQTT_PUBLISH_ACK_PACKET_SIZE );
+
+
// The packet ID must be the same as the original publish packet.
+
packetId = publishPacketId;
+
+
// The byte representing a packet of type ACK. This function accepts PUBACK, PUBREC, PUBREL, or PUBCOMP.
+ +
+
// Serialize the publish acknowledgment into the fixed buffer.
+
status = MQTT_SerializeAck( &fixedBuffer, packetType, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// The publish acknowledgment can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializeAck(const MQTTFixedBuffer_t *pFixedBuffer, uint8_t packetType, uint16_t packetId)
Serialize an MQTT PUBACK, PUBREC, PUBREL, or PUBCOMP into the given buffer.
Definition: core_mqtt_serializer.c:2266
+
#define MQTT_PUBLISH_ACK_PACKET_SIZE
The size of MQTT PUBACK, PUBREC, PUBREL, and PUBCOMP packets, per MQTT spec.
Definition: core_mqtt_serializer.h:73
+
#define MQTT_PACKET_TYPE_PUBACK
PUBACK (bidirectional).
Definition: core_mqtt_serializer.h:56
+
+
+
+ +

◆ MQTT_GetDisconnectPacketSize()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_GetDisconnectPacketSize (size_t * pPacketSize)
+
+ +

Get the size of an MQTT DISCONNECT packet.

+
Parameters
+ + +
[out]pPacketSizeThe size of the MQTT DISCONNECT packet.
+
+
+
Returns
MQTTSuccess, or MQTTBadParameter if pPacketSize is NULL.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
size_t packetSize = 0;
+
+
// Get the size requirement for the disconnect packet.
+
status = MQTT_GetDisconnectPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize == 2 );
+
+
// The application should allocate or use a static #MQTTFixedBuffer_t of
+
// size >= 2 to serialize the disconnect packet.
+
MQTTStatus_t MQTT_GetDisconnectPacketSize(size_t *pPacketSize)
Get the size of an MQTT DISCONNECT packet.
Definition: core_mqtt_serializer.c:2321
+
+
+
+ +

◆ MQTT_SerializeDisconnect()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_SerializeDisconnect (const MQTTFixedBuffer_tpFixedBuffer)
+
+ +

Serialize an MQTT DISCONNECT packet into the given buffer.

+

The input MQTTFixedBuffer_t.size must be at least as large as the size returned by MQTT_GetDisconnectPacketSize.

+
Parameters
+ + +
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Get the disconnect packet size.
+
status = MQTT_GetDisconnectPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the disconnect into the fixed buffer.
+
status = MQTT_SerializeDisconnect( &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// The disconnect packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializeDisconnect(const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT DISCONNECT packet into the given buffer.
Definition: core_mqtt_serializer.c:2341
+
+
+
+ +

◆ MQTT_GetPingreqPacketSize()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_GetPingreqPacketSize (size_t * pPacketSize)
+
+ +

Get the size of an MQTT PINGREQ packet.

+
Parameters
+ + +
[out]pPacketSizeThe size of the MQTT PINGREQ packet.
+
+
+
Returns
MQTTSuccess or MQTTBadParameter if pPacketSize is NULL.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
size_t packetSize = 0;
+
+
// Get the size requirement for the ping request packet.
+
status = MQTT_GetPingreqPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize == 2 );
+
+
// The application should allocate or use a static #MQTTFixedBuffer_t of
+
// size >= 2 to serialize the ping request.
+
MQTTStatus_t MQTT_GetPingreqPacketSize(size_t *pPacketSize)
Get the size of an MQTT PINGREQ packet.
Definition: core_mqtt_serializer.c:2384
+
+
+
+ +

◆ MQTT_SerializePingreq()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_SerializePingreq (const MQTTFixedBuffer_tpFixedBuffer)
+
+ +

Serialize an MQTT PINGREQ packet into the given buffer.

+

The input MQTTFixedBuffer_t.size must be at least as large as the size returned by MQTT_GetPingreqPacketSize.

+
Parameters
+ + +
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Get the ping request packet size.
+
status = MQTT_GetPingreqPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the ping request into the fixed buffer.
+
status = MQTT_SerializePingreq( &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// The ping request can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializePingreq(const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT PINGREQ packet into the given buffer.
Definition: core_mqtt_serializer.c:2404
+
+
+
+ +

◆ MQTT_DeserializePublish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_DeserializePublish (const MQTTPacketInfo_tpIncomingPacket,
uint16_t * pPacketId,
MQTTPublishInfo_tpPublishInfo 
)
+
+ +

Deserialize an MQTT PUBLISH packet.

+
Parameters
+ + + + +
[in]pIncomingPacketMQTTPacketInfo_t containing the buffer.
[out]pPacketIdThe packet ID obtained from the buffer.
[out]pPublishInfoStruct containing information about the publish.
+
+
+
Returns
MQTTBadParameter, MQTTBadResponse, or MQTTSuccess.
+

Example

// TransportRecv_t function for reading from the network.
+
int32_t socket_recv(
+
NetworkContext_t * pNetworkContext,
+
void * pBuffer,
+
size_t bytesToRecv
+
);
+
// Some context to be used with the above transport receive function.
+
NetworkContext_t networkContext;
+
+
// Other variables used in this example.
+
MQTTStatus_t status;
+
MQTTPacketInfo_t incomingPacket;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
uint16_t packetId;
+
+
int32_t bytesRecvd;
+
// A buffer to hold remaining data of the incoming packet.
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
// Populate all fields of the incoming packet.
+ +
socket_recv,
+
&networkContext,
+
&incomingPacket
+
);
+
assert( status == MQTTSuccess );
+
assert( incomingPacket.remainingLength <= BUFFER_SIZE );
+
bytesRecvd = socket_recv(
+
&networkContext,
+
( void * ) buffer,
+
incomingPacket.remainingLength
+
);
+
incomingPacket.pRemainingData = buffer;
+
+
// Deserialize the publish information if the incoming packet is a publish.
+
if( ( incomingPacket.type & 0xF0 ) == MQTT_PACKET_TYPE_PUBLISH )
+
{
+
status = MQTT_DeserializePublish( &incomingPacket, &packetId, &publishInfo );
+
if( status == MQTTSuccess )
+
{
+
// The deserialized publish information can now be used from `publishInfo`.
+
}
+
}
+
MQTTStatus_t MQTT_DeserializePublish(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo)
Deserialize an MQTT PUBLISH packet.
Definition: core_mqtt_serializer.c:2447
+
MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength(TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket)
Extract the MQTT packet type and length from incoming packet.
Definition: core_mqtt_serializer.c:2561
+
#define MQTT_PACKET_TYPE_PUBLISH
PUBLISH (bidirectional).
Definition: core_mqtt_serializer.h:55
+
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+
size_t remainingLength
Length of remaining serialized data.
Definition: core_mqtt_serializer.h:258
+
uint8_t type
Type of incoming MQTT packet.
Definition: core_mqtt_serializer.h:248
+
uint8_t * pRemainingData
Remaining serialized data in the MQTT packet.
Definition: core_mqtt_serializer.h:253
+
+
+
+ +

◆ MQTT_DeserializeAck()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_DeserializeAck (const MQTTPacketInfo_tpIncomingPacket,
uint16_t * pPacketId,
bool * pSessionPresent 
)
+
+ +

Deserialize an MQTT CONNACK, SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, PUBCOMP, or PINGRESP.

+
Parameters
+ + + + +
[in]pIncomingPacketMQTTPacketInfo_t containing the buffer.
[out]pPacketIdThe packet ID of obtained from the buffer. Not used in CONNACK or PINGRESP.
[out]pSessionPresentBoolean flag from a CONNACK indicating present session.
+
+
+
Returns
MQTTBadParameter, MQTTBadResponse, MQTTServerRefused, or MQTTSuccess.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPacketInfo_t incomingPacket;
+
// Used for SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, and PUBCOMP.
+
uint16_t packetId;
+
// Used for CONNACK.
+
bool sessionPresent;
+
+
// Receive an incoming packet and populate all fields. The details are out of scope
+
// for this example.
+
receiveIncomingPacket( &incomingPacket );
+
+
// Deserialize ack information if the incoming packet is not a publish.
+
if( ( incomingPacket.type & 0xF0 ) != MQTT_PACKET_TYPE_PUBLISH )
+
{
+
status = MQTT_DeserializeAck( &incomingPacket, &packetId, &sessionPresent );
+
if( status == MQTTSuccess )
+
{
+
// The packet ID or session present flag information is available. For
+
// ping response packets, the only information is the status code.
+
}
+
}
+
MQTTStatus_t MQTT_DeserializeAck(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, bool *pSessionPresent)
Deserialize an MQTT CONNACK, SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, PUBCOMP, or PINGRESP.
Definition: core_mqtt_serializer.c:2484
+
+
+
+ +

◆ MQTT_GetIncomingPacketTypeAndLength()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength (TransportRecv_t readFunc,
NetworkContext_tpNetworkContext,
MQTTPacketInfo_tpIncomingPacket 
)
+
+ +

Extract the MQTT packet type and length from incoming packet.

+

This function must be called for every incoming packet to retrieve the MQTTPacketInfo_t.type and MQTTPacketInfo_t.remainingLength. A MQTTPacketInfo_t is not valid until this routine has been invoked.

+
Parameters
+ + + + +
[in]readFuncTransport layer read function pointer.
[in]pNetworkContextThe network context pointer provided by the application.
[out]pIncomingPacketPointer to MQTTPacketInfo_t structure. This is where type, remaining length and packet identifier are stored.
+
+
+
Returns
MQTTSuccess on successful extraction of type and length, MQTTBadParameter if pIncomingPacket is invalid, MQTTRecvFailed on transport receive failure, MQTTBadResponse if an invalid packet is read, and MQTTNoDataAvailable if there is nothing to read.
+

Example

// TransportRecv_t function for reading from the network.
+
int32_t socket_recv(
+
NetworkContext_t * pNetworkContext,
+
void * pBuffer,
+
size_t bytesToRecv
+
);
+
// Some context to be used with above transport receive function.
+
NetworkContext_t networkContext;
+
+
// Struct to hold the incoming packet information.
+
MQTTPacketInfo_t incomingPacket;
+ +
int32_t bytesRecvd;
+
// Buffer to hold the remaining data of the incoming packet.
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
// Loop until data is available to be received.
+
do{
+ +
socket_recv,
+
&networkContext,
+
&incomingPacket
+
);
+
} while( status == MQTTNoDataAvailable );
+
+
assert( status == MQTTSuccess );
+
+
// Receive the rest of the incoming packet.
+
assert( incomingPacket.remainingLength <= BUFFER_SIZE );
+
bytesRecvd = socket_recv(
+
&networkContext,
+
( void * ) buffer,
+
incomingPacket.remainingLength
+
);
+
+
// Set the remaining data field.
+
incomingPacket.pRemainingData = buffer;
+
@ MQTTNoDataAvailable
Definition: core_mqtt_serializer.h:95
+
+
+
+ +

◆ MQTT_ProcessIncomingPacketTypeAndLength()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_ProcessIncomingPacketTypeAndLength (const uint8_t * pBuffer,
const size_t * pIndex,
MQTTPacketInfo_tpIncomingPacket 
)
+
+ +

Extract the MQTT packet type and length from incoming packet.

+

This function must be called for every incoming packet to retrieve the MQTTPacketInfo_t.type and MQTTPacketInfo_t.remainingLength. A MQTTPacketInfo_t is not valid until this routine has been invoked.

+
Parameters
+ + + + +
[in]pBufferThe buffer holding the raw data to be processed
[in]pIndexPointer to the index within the buffer to marking the end of raw data available.
[out]pIncomingPacketStructure used to hold the fields of the incoming packet.
+
+
+
Returns
MQTTSuccess on successful extraction of type and length, MQTTBadParameter if pIncomingPacket is invalid, MQTTBadResponse if an invalid packet is read, and MQTTNoDataAvailable if there is nothing to read.
+ +
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/core__mqtt__serializer_8h.html b/v1.3.0/coreMQTT/core__mqtt__serializer_8h.html new file mode 100644 index 00000000..3088a5dd --- /dev/null +++ b/v1.3.0/coreMQTT/core__mqtt__serializer_8h.html @@ -0,0 +1,1675 @@ + + + + + + + +coreMQTT: core_mqtt_serializer.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_serializer.h File Reference
+
+
+ +

User-facing functions for serializing and deserializing MQTT 3.1.1 packets. This header should be included for building a lighter weight MQTT client than the managed CSDK MQTT library API in core_mqtt.h, by using the serializer and de-serializer functions exposed in this file's API. +More...

+
#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include "transport_interface.h"
+
+

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + +

+Data Structures

struct  MQTTFixedBuffer_t
 Buffer passed to MQTT library. More...
 
struct  MQTTConnectInfo_t
 MQTT CONNECT packet parameters. More...
 
struct  MQTTSubscribeInfo_t
 MQTT SUBSCRIBE packet parameters. More...
 
struct  MQTTPublishInfo_t
 MQTT PUBLISH packet parameters. More...
 
struct  MQTTPacketInfo_t
 MQTT incoming packet parameters. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Macros

+#define MQTT_PACKET_TYPE_CONNECT   ( ( uint8_t ) 0x10U )
 CONNECT (client-to-server).
 
+#define MQTT_PACKET_TYPE_CONNACK   ( ( uint8_t ) 0x20U )
 CONNACK (server-to-client).
 
+#define MQTT_PACKET_TYPE_PUBLISH   ( ( uint8_t ) 0x30U )
 PUBLISH (bidirectional).
 
+#define MQTT_PACKET_TYPE_PUBACK   ( ( uint8_t ) 0x40U )
 PUBACK (bidirectional).
 
+#define MQTT_PACKET_TYPE_PUBREC   ( ( uint8_t ) 0x50U )
 PUBREC (bidirectional).
 
+#define MQTT_PACKET_TYPE_PUBREL   ( ( uint8_t ) 0x62U )
 PUBREL (bidirectional).
 
+#define MQTT_PACKET_TYPE_PUBCOMP   ( ( uint8_t ) 0x70U )
 PUBCOMP (bidirectional).
 
+#define MQTT_PACKET_TYPE_SUBSCRIBE   ( ( uint8_t ) 0x82U )
 SUBSCRIBE (client-to-server).
 
+#define MQTT_PACKET_TYPE_SUBACK   ( ( uint8_t ) 0x90U )
 SUBACK (server-to-client).
 
+#define MQTT_PACKET_TYPE_UNSUBSCRIBE   ( ( uint8_t ) 0xA2U )
 UNSUBSCRIBE (client-to-server).
 
+#define MQTT_PACKET_TYPE_UNSUBACK   ( ( uint8_t ) 0xB0U )
 UNSUBACK (server-to-client).
 
+#define MQTT_PACKET_TYPE_PINGREQ   ( ( uint8_t ) 0xC0U )
 PINGREQ (client-to-server).
 
+#define MQTT_PACKET_TYPE_PINGRESP   ( ( uint8_t ) 0xD0U )
 PINGRESP (server-to-client).
 
+#define MQTT_PACKET_TYPE_DISCONNECT   ( ( uint8_t ) 0xE0U )
 DISCONNECT (client-to-server).
 
+#define MQTT_PUBLISH_ACK_PACKET_SIZE   ( 4UL )
 The size of MQTT PUBACK, PUBREC, PUBREL, and PUBCOMP packets, per MQTT spec.
 
+ + + + + + + +

+Enumerations

enum  MQTTStatus_t {
+  MQTTSuccess = 0 +, MQTTBadParameter +, MQTTNoMemory +, MQTTSendFailed +,
+  MQTTRecvFailed +, MQTTBadResponse +, MQTTServerRefused +, MQTTNoDataAvailable +,
+  MQTTIllegalState +, MQTTStateCollision +, MQTTKeepAliveTimeout +, MQTTNeedMoreBytes +
+ }
 Return codes from MQTT functions. More...
 
enum  MQTTQoS_t { MQTTQoS0 = 0 +, MQTTQoS1 = 1 +, MQTTQoS2 = 2 + }
 MQTT Quality of Service values. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

MQTTStatus_t MQTT_GetConnectPacketSize (const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize)
 Get the size and Remaining Length of an MQTT CONNECT packet.
 
MQTTStatus_t MQTT_SerializeConnect (const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT CONNECT packet in the given fixed buffer pFixedBuffer.
 
MQTTStatus_t MQTT_GetSubscribePacketSize (const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
 Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.
 
MQTTStatus_t MQTT_SerializeSubscribe (const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT SUBSCRIBE packet in the given buffer.
 
MQTTStatus_t MQTT_GetUnsubscribePacketSize (const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
 Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.
 
MQTTStatus_t MQTT_SerializeUnsubscribe (const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT UNSUBSCRIBE packet in the given buffer.
 
MQTTStatus_t MQTT_GetPublishPacketSize (const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize)
 Get the packet size and remaining length of an MQTT PUBLISH packet.
 
MQTTStatus_t MQTT_SerializePublish (const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT PUBLISH packet in the given buffer.
 
MQTTStatus_t MQTT_SerializePublishHeaderWithoutTopic (const MQTTPublishInfo_t *pPublishInfo, size_t remainingLength, uint8_t *pBuffer, size_t *headerSize)
 Serialize an MQTT PUBLISH packet header without the topic string in the given buffer. This function will add the topic string length to the provided buffer. This helps reduce an unnecessary copy of the topic string into the buffer.
 
MQTTStatus_t MQTT_SerializePublishHeader (const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer, size_t *pHeaderSize)
 Serialize an MQTT PUBLISH packet header in the given buffer.
 
MQTTStatus_t MQTT_SerializeAck (const MQTTFixedBuffer_t *pFixedBuffer, uint8_t packetType, uint16_t packetId)
 Serialize an MQTT PUBACK, PUBREC, PUBREL, or PUBCOMP into the given buffer.
 
MQTTStatus_t MQTT_GetDisconnectPacketSize (size_t *pPacketSize)
 Get the size of an MQTT DISCONNECT packet.
 
MQTTStatus_t MQTT_SerializeDisconnect (const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT DISCONNECT packet into the given buffer.
 
MQTTStatus_t MQTT_GetPingreqPacketSize (size_t *pPacketSize)
 Get the size of an MQTT PINGREQ packet.
 
MQTTStatus_t MQTT_SerializePingreq (const MQTTFixedBuffer_t *pFixedBuffer)
 Serialize an MQTT PINGREQ packet into the given buffer.
 
MQTTStatus_t MQTT_DeserializePublish (const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo)
 Deserialize an MQTT PUBLISH packet.
 
MQTTStatus_t MQTT_DeserializeAck (const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, bool *pSessionPresent)
 Deserialize an MQTT CONNACK, SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, PUBCOMP, or PINGRESP.
 
MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength (TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket)
 Extract the MQTT packet type and length from incoming packet.
 
MQTTStatus_t MQTT_ProcessIncomingPacketTypeAndLength (const uint8_t *pBuffer, const size_t *pIndex, MQTTPacketInfo_t *pIncomingPacket)
 Extract the MQTT packet type and length from incoming packet.
 
+

Detailed Description

+

User-facing functions for serializing and deserializing MQTT 3.1.1 packets. This header should be included for building a lighter weight MQTT client than the managed CSDK MQTT library API in core_mqtt.h, by using the serializer and de-serializer functions exposed in this file's API.

+

Function Documentation

+ +

◆ MQTT_GetConnectPacketSize()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetConnectPacketSize (const MQTTConnectInfo_tpConnectInfo,
const MQTTPublishInfo_tpWillInfo,
size_t * pRemainingLength,
size_t * pPacketSize 
)
+
+ +

Get the size and Remaining Length of an MQTT CONNECT packet.

+

This function must be called before MQTT_SerializeConnect in order to get the size of the MQTT CONNECT packet that is generated from MQTTConnectInfo_t and optional MQTTPublishInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializeConnect must be at least pPacketSize. The provided pConnectInfo and pWillInfo are valid for serialization with MQTT_SerializeConnect only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + + +
[in]pConnectInfoMQTT CONNECT packet parameters.
[in]pWillInfoLast Will and Testament. Pass NULL if not used.
[out]pRemainingLengthThe Remaining Length of the MQTT CONNECT packet.
[out]pPacketSizeThe total size of the MQTT CONNECT packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
+
// Initialize the connection info, the details are out of scope for this example.
+
initializeConnectInfo( &connectInfo );
+
+
// Initialize the optional will info, the details are out of scope for this example.
+
initializeWillInfo( &willInfo );
+
+
// Get the size requirement for the connect packet.
+ +
&connectInfo, &willInfo, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the connect request.
+
}
+
MQTTStatus_t MQTT_GetConnectPacketSize(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the size and Remaining Length of an MQTT CONNECT packet.
Definition: core_mqtt_serializer.c:1690
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+
+
+
+ +

◆ MQTT_SerializeConnect()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializeConnect (const MQTTConnectInfo_tpConnectInfo,
const MQTTPublishInfo_tpWillInfo,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer 
)
+
+ +

Serialize an MQTT CONNECT packet in the given fixed buffer pFixedBuffer.

+

MQTT_GetConnectPacketSize should be called with pConnectInfo and pWillInfo before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetConnectPacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetConnectPacketSize.

+
Parameters
+ + + + + +
[in]pConnectInfoMQTT CONNECT packet parameters.
[in]pWillInfoLast Will and Testament. Pass NULL if not used.
[in]remainingLengthRemaining Length provided by MQTT_GetConnectPacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Assume connectInfo and willInfo are initialized. Get the size requirement for
+
// the connect packet.
+ +
&connectInfo, &willInfo, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the connect packet into the fixed buffer.
+
status = MQTT_SerializeConnect( &connectInfo, &willInfo, remainingLength, &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// The connect packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializeConnect(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT CONNECT packet in the given fixed buffer pFixedBuffer.
Definition: core_mqtt_serializer.c:1790
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
+
+
+ +

◆ MQTT_GetSubscribePacketSize()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetSubscribePacketSize (const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
size_t * pRemainingLength,
size_t * pPacketSize 
)
+
+ +

Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.

+

This function must be called before MQTT_SerializeSubscribe in order to get the size of the MQTT SUBSCRIBE packet that is generated from the list of MQTTSubscribeInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializeSubscribe must be at least pPacketSize. The provided pSubscriptionList is valid for serialization with MQTT_SerializeSubscribe only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[out]pRemainingLengthThe Remaining Length of the MQTT SUBSCRIBE packet.
[out]pPacketSizeThe total size of the MQTT SUBSCRIBE packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
// This is assumed to be a list of filters we want to subscribe to.
+
const char * filters[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// Set each subscription.
+
for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )
+
{
+
subscriptionList[ i ].qos = MQTTQoS0;
+
// Each subscription needs a topic filter.
+
subscriptionList[ i ].pTopicFilter = filters[ i ];
+
subscriptionList[ i ].topicFilterLength = strlen( filters[ i ] );
+
}
+
+
// Get the size requirement for the subscribe packet.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the subscribe request.
+
}
+
MQTTStatus_t MQTT_GetSubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.
Definition: core_mqtt_serializer.c:1848
+
@ MQTTQoS0
Definition: core_mqtt_serializer.h:110
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+
MQTTQoS_t qos
Quality of Service for subscription.
Definition: core_mqtt_serializer.h:184
+
uint16_t topicFilterLength
Length of subscription topic filter.
Definition: core_mqtt_serializer.h:194
+
const char * pTopicFilter
Topic filter to subscribe to.
Definition: core_mqtt_serializer.h:189
+
+
+
+ +

◆ MQTT_SerializeSubscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializeSubscribe (const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer 
)
+
+ +

Serialize an MQTT SUBSCRIBE packet in the given buffer.

+

MQTT_GetSubscribePacketSize should be called with pSubscriptionList before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetSubscribePacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetSubscribePacketSize.

+
Parameters
+ + + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetSubscribePacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
uint16_t packetId;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Function to return a valid, unused packet identifier. The details are out of
+
// scope for this example.
+
packetId = getNewPacketId();
+
+
// Assume subscriptionList has been initialized. Get the subscribe packet size.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the subscribe packet into the fixed buffer.
+ +
&subscriptionList[ 0 ],
+
NUMBER_OF_SUBSCRIPTIONS,
+
packetId,
+
remainingLength,
+
&fixedBuffer
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The subscribe packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializeSubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT SUBSCRIBE packet in the given buffer.
Definition: core_mqtt_serializer.c:1932
+
+
+
+ +

◆ MQTT_GetUnsubscribePacketSize()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetUnsubscribePacketSize (const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
size_t * pRemainingLength,
size_t * pPacketSize 
)
+
+ +

Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.

+

This function must be called before MQTT_SerializeUnsubscribe in order to get the size of the MQTT UNSUBSCRIBE packet that is generated from the list of MQTTSubscribeInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializeUnsubscribe must be at least pPacketSize. The provided pSubscriptionList is valid for serialization with MQTT_SerializeUnsubscribe only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[out]pRemainingLengthThe Remaining Length of the MQTT UNSUBSCRIBE packet.
[out]pPacketSizeThe total size of the MQTT UNSUBSCRIBE packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
+
// Initialize the subscribe info. The details are out of scope for this example.
+
initializeSubscribeInfo( &subscriptionList[ 0 ] );
+
+
// Get the size requirement for the unsubscribe packet.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the unsubscribe request.
+
}
+
MQTTStatus_t MQTT_GetUnsubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.
Definition: core_mqtt_serializer.c:1978
+
+
+
+ +

◆ MQTT_SerializeUnsubscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializeUnsubscribe (const MQTTSubscribeInfo_tpSubscriptionList,
size_t subscriptionCount,
uint16_t packetId,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer 
)
+
+ +

Serialize an MQTT UNSUBSCRIBE packet in the given buffer.

+

MQTT_GetUnsubscribePacketSize should be called with pSubscriptionList before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetUnsubscribePacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetUnsubscribePacketSize.

+
Parameters
+ + + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetUnsubscribePacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
uint16_t packetId;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Function to return a valid, unused packet identifier. The details are out of
+
// scope for this example.
+
packetId = getNewPacketId();
+
+
// Assume subscriptionList has been initialized. Get the unsubscribe packet size.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the unsubscribe packet into the fixed buffer.
+ +
&subscriptionList[ 0 ],
+
NUMBER_OF_SUBSCRIPTIONS,
+
packetId,
+
remainingLength,
+
&fixedBuffer
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The unsubscribe packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializeUnsubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT UNSUBSCRIBE packet in the given buffer.
Definition: core_mqtt_serializer.c:2016
+
+
+
+ +

◆ MQTT_GetPublishPacketSize()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetPublishPacketSize (const MQTTPublishInfo_tpPublishInfo,
size_t * pRemainingLength,
size_t * pPacketSize 
)
+
+ +

Get the packet size and remaining length of an MQTT PUBLISH packet.

+

This function must be called before MQTT_SerializePublish in order to get the size of the MQTT PUBLISH packet that is generated from MQTTPublishInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializePublish must be at least pPacketSize. The provided pPublishInfo is valid for serialization with MQTT_SerializePublish only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[out]pRemainingLengthThe Remaining Length of the MQTT PUBLISH packet.
[out]pPacketSizeThe total size of the MQTT PUBLISH packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec or if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
+
// Initialize the publish info.
+
publishInfo.qos = MQTTQoS0;
+
publishInfo.pTopicName = "/some/topic/name";
+
publishInfo.topicNameLength = strlen( publishInfo.pTopicName );
+
publishInfo.pPayload = "Hello World!";
+
publishInfo.payloadLength = strlen( "Hello World!" );
+
+
// Get the size requirement for the publish packet.
+ +
&publishInfo, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the publish.
+
}
+
MQTTStatus_t MQTT_GetPublishPacketSize(const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the packet size and remaining length of an MQTT PUBLISH packet.
Definition: core_mqtt_serializer.c:2057
+
MQTTQoS_t qos
Quality of Service for message.
Definition: core_mqtt_serializer.h:206
+
uint16_t topicNameLength
Length of topic name.
Definition: core_mqtt_serializer.h:226
+
size_t payloadLength
Message payload length.
Definition: core_mqtt_serializer.h:236
+
const char * pTopicName
Topic name on which the message is published.
Definition: core_mqtt_serializer.h:221
+
const void * pPayload
Message payload.
Definition: core_mqtt_serializer.h:231
+
+
+
+ +

◆ MQTT_SerializePublish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializePublish (const MQTTPublishInfo_tpPublishInfo,
uint16_t packetId,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer 
)
+
+ +

Serialize an MQTT PUBLISH packet in the given buffer.

+

This function will serialize complete MQTT PUBLISH packet into the given buffer. If the PUBLISH payload can be sent separately, consider using MQTT_SerializePublishHeader, which will serialize only the PUBLISH header into the buffer.

+

MQTT_GetPublishPacketSize should be called with pPublishInfo before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetPublishPacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetPublishPacketSize.

+
Parameters
+ + + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetPublishPacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
uint16_t packetId;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// A packet identifier is unused for QoS 0 publishes. Otherwise, a valid, unused packet
+
// identifier must be used.
+
packetId = 0;
+
+
// Assume publishInfo has been initialized. Get publish packet size.
+ +
&publishInfo, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the publish packet into the fixed buffer.
+ +
&publishInfo,
+
packetId,
+
remainingLength,
+
&fixedBuffer
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The publish packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializePublish(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT PUBLISH packet in the given buffer.
Definition: core_mqtt_serializer.c:2098
+
+
+
+ +

◆ MQTT_SerializePublishHeaderWithoutTopic()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializePublishHeaderWithoutTopic (const MQTTPublishInfo_tpPublishInfo,
size_t remainingLength,
uint8_t * pBuffer,
size_t * headerSize 
)
+
+ +

Serialize an MQTT PUBLISH packet header without the topic string in the given buffer. This function will add the topic string length to the provided buffer. This helps reduce an unnecessary copy of the topic string into the buffer.

+
Parameters
+ + + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]remainingLengthRemaining Length provided by MQTT_GetPublishPacketSize.
[out]pBufferBuffer for packet serialization.
[out]headerSizeSize of the serialized MQTT PUBLISH header.
+
+
+
Returns
MQTTSuccess if the serialization is successful. Otherwise, MQTTBadParameter.
+ +
+
+ +

◆ MQTT_SerializePublishHeader()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializePublishHeader (const MQTTPublishInfo_tpPublishInfo,
uint16_t packetId,
size_t remainingLength,
const MQTTFixedBuffer_tpFixedBuffer,
size_t * pHeaderSize 
)
+
+ +

Serialize an MQTT PUBLISH packet header in the given buffer.

+

This function serializes PUBLISH header in to the given buffer. The payload for PUBLISH will not be copied over to the buffer. This will help reduce the memory needed for the buffer and avoid an unwanted copy operation of the PUBLISH payload into the buffer. If the payload also would need to be part of the serialized buffer, consider using MQTT_SerializePublish.

+

MQTT_GetPublishPacketSize should be called with pPublishInfo before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetPublishPacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetPublishPacketSize.

+
Parameters
+ + + + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetPublishPacketSize.
[out]pFixedBufferBuffer for packet serialization.
[out]pHeaderSizeSize of the serialized MQTT PUBLISH header.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0, headerSize = 0;
+
uint16_t packetId;
+
int32_t bytesSent;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// A packet identifier is unused for QoS 0 publishes. Otherwise, a valid, unused packet
+
// identifier must be used.
+
packetId = 0;
+
+
// Assume publishInfo has been initialized. Get the publish packet size.
+ +
&publishInfo, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
// The payload will not be serialized, so the the fixed buffer does not need to hold it.
+
assert( ( packetSize - publishInfo.payloadLength ) <= BUFFER_SIZE );
+
+
// Serialize the publish packet header into the fixed buffer.
+ +
&publishInfo,
+
packetId,
+
remainingLength,
+
&fixedBuffer,
+
&headerSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The publish header and payload can now be sent to the broker.
+
// mqttSocket here is a socket descriptor created and connected to the MQTT
+
// broker outside of this function.
+
bytesSent = send( mqttSocket, ( void * ) fixedBuffer.pBuffer, headerSize, 0 );
+
assert( bytesSent == headerSize );
+
bytesSent = send( mqttSocket, publishInfo.pPayload, publishInfo.payloadLength, 0 );
+
assert( bytesSent == publishInfo.payloadLength );
+
}
+
MQTTStatus_t MQTT_SerializePublishHeader(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer, size_t *pHeaderSize)
Serialize an MQTT PUBLISH packet header in the given buffer.
Definition: core_mqtt_serializer.c:2183
+
+
+
+ +

◆ MQTT_SerializeAck()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_SerializeAck (const MQTTFixedBuffer_tpFixedBuffer,
uint8_t packetType,
uint16_t packetId 
)
+
+ +

Serialize an MQTT PUBACK, PUBREC, PUBREL, or PUBCOMP into the given buffer.

+
Parameters
+ + + + +
[out]pFixedBufferBuffer for packet serialization.
[in]packetTypeByte of the corresponding packet fixed header per the MQTT spec.
[in]packetIdPacket ID of the publish.
+
+
+
Returns
MQTTBadParameter, MQTTNoMemory, or MQTTSuccess.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
uint16_t packetId;
+
uint8_t packetType;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
// The fixed buffer must be large enough to hold 4 bytes.
+
assert( BUFFER_SIZE >= MQTT_PUBLISH_ACK_PACKET_SIZE );
+
+
// The packet ID must be the same as the original publish packet.
+
packetId = publishPacketId;
+
+
// The byte representing a packet of type ACK. This function accepts PUBACK, PUBREC, PUBREL, or PUBCOMP.
+ +
+
// Serialize the publish acknowledgment into the fixed buffer.
+
status = MQTT_SerializeAck( &fixedBuffer, packetType, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// The publish acknowledgment can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializeAck(const MQTTFixedBuffer_t *pFixedBuffer, uint8_t packetType, uint16_t packetId)
Serialize an MQTT PUBACK, PUBREC, PUBREL, or PUBCOMP into the given buffer.
Definition: core_mqtt_serializer.c:2266
+
#define MQTT_PUBLISH_ACK_PACKET_SIZE
The size of MQTT PUBACK, PUBREC, PUBREL, and PUBCOMP packets, per MQTT spec.
Definition: core_mqtt_serializer.h:73
+
#define MQTT_PACKET_TYPE_PUBACK
PUBACK (bidirectional).
Definition: core_mqtt_serializer.h:56
+
+
+
+ +

◆ MQTT_GetDisconnectPacketSize()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_GetDisconnectPacketSize (size_t * pPacketSize)
+
+ +

Get the size of an MQTT DISCONNECT packet.

+
Parameters
+ + +
[out]pPacketSizeThe size of the MQTT DISCONNECT packet.
+
+
+
Returns
MQTTSuccess, or MQTTBadParameter if pPacketSize is NULL.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
size_t packetSize = 0;
+
+
// Get the size requirement for the disconnect packet.
+
status = MQTT_GetDisconnectPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize == 2 );
+
+
// The application should allocate or use a static #MQTTFixedBuffer_t of
+
// size >= 2 to serialize the disconnect packet.
+
MQTTStatus_t MQTT_GetDisconnectPacketSize(size_t *pPacketSize)
Get the size of an MQTT DISCONNECT packet.
Definition: core_mqtt_serializer.c:2321
+
+
+
+ +

◆ MQTT_SerializeDisconnect()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_SerializeDisconnect (const MQTTFixedBuffer_tpFixedBuffer)
+
+ +

Serialize an MQTT DISCONNECT packet into the given buffer.

+

The input MQTTFixedBuffer_t.size must be at least as large as the size returned by MQTT_GetDisconnectPacketSize.

+
Parameters
+ + +
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Get the disconnect packet size.
+
status = MQTT_GetDisconnectPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the disconnect into the fixed buffer.
+
status = MQTT_SerializeDisconnect( &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// The disconnect packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializeDisconnect(const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT DISCONNECT packet into the given buffer.
Definition: core_mqtt_serializer.c:2341
+
+
+
+ +

◆ MQTT_GetPingreqPacketSize()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_GetPingreqPacketSize (size_t * pPacketSize)
+
+ +

Get the size of an MQTT PINGREQ packet.

+
Parameters
+ + +
[out]pPacketSizeThe size of the MQTT PINGREQ packet.
+
+
+
Returns
MQTTSuccess or MQTTBadParameter if pPacketSize is NULL.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
size_t packetSize = 0;
+
+
// Get the size requirement for the ping request packet.
+
status = MQTT_GetPingreqPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize == 2 );
+
+
// The application should allocate or use a static #MQTTFixedBuffer_t of
+
// size >= 2 to serialize the ping request.
+
MQTTStatus_t MQTT_GetPingreqPacketSize(size_t *pPacketSize)
Get the size of an MQTT PINGREQ packet.
Definition: core_mqtt_serializer.c:2384
+
+
+
+ +

◆ MQTT_SerializePingreq()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTT_SerializePingreq (const MQTTFixedBuffer_tpFixedBuffer)
+
+ +

Serialize an MQTT PINGREQ packet into the given buffer.

+

The input MQTTFixedBuffer_t.size must be at least as large as the size returned by MQTT_GetPingreqPacketSize.

+
Parameters
+ + +
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Get the ping request packet size.
+
status = MQTT_GetPingreqPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the ping request into the fixed buffer.
+
status = MQTT_SerializePingreq( &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// The ping request can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_SerializePingreq(const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT PINGREQ packet into the given buffer.
Definition: core_mqtt_serializer.c:2404
+
+
+
+ +

◆ MQTT_DeserializePublish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_DeserializePublish (const MQTTPacketInfo_tpIncomingPacket,
uint16_t * pPacketId,
MQTTPublishInfo_tpPublishInfo 
)
+
+ +

Deserialize an MQTT PUBLISH packet.

+
Parameters
+ + + + +
[in]pIncomingPacketMQTTPacketInfo_t containing the buffer.
[out]pPacketIdThe packet ID obtained from the buffer.
[out]pPublishInfoStruct containing information about the publish.
+
+
+
Returns
MQTTBadParameter, MQTTBadResponse, or MQTTSuccess.
+

Example

// TransportRecv_t function for reading from the network.
+
int32_t socket_recv(
+
NetworkContext_t * pNetworkContext,
+
void * pBuffer,
+
size_t bytesToRecv
+
);
+
// Some context to be used with the above transport receive function.
+
NetworkContext_t networkContext;
+
+
// Other variables used in this example.
+
MQTTStatus_t status;
+
MQTTPacketInfo_t incomingPacket;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
uint16_t packetId;
+
+
int32_t bytesRecvd;
+
// A buffer to hold remaining data of the incoming packet.
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
// Populate all fields of the incoming packet.
+ +
socket_recv,
+
&networkContext,
+
&incomingPacket
+
);
+
assert( status == MQTTSuccess );
+
assert( incomingPacket.remainingLength <= BUFFER_SIZE );
+
bytesRecvd = socket_recv(
+
&networkContext,
+
( void * ) buffer,
+
incomingPacket.remainingLength
+
);
+
incomingPacket.pRemainingData = buffer;
+
+
// Deserialize the publish information if the incoming packet is a publish.
+
if( ( incomingPacket.type & 0xF0 ) == MQTT_PACKET_TYPE_PUBLISH )
+
{
+
status = MQTT_DeserializePublish( &incomingPacket, &packetId, &publishInfo );
+
if( status == MQTTSuccess )
+
{
+
// The deserialized publish information can now be used from `publishInfo`.
+
}
+
}
+
MQTTStatus_t MQTT_DeserializePublish(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo)
Deserialize an MQTT PUBLISH packet.
Definition: core_mqtt_serializer.c:2447
+
MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength(TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket)
Extract the MQTT packet type and length from incoming packet.
Definition: core_mqtt_serializer.c:2561
+
#define MQTT_PACKET_TYPE_PUBLISH
PUBLISH (bidirectional).
Definition: core_mqtt_serializer.h:55
+
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+
size_t remainingLength
Length of remaining serialized data.
Definition: core_mqtt_serializer.h:258
+
uint8_t type
Type of incoming MQTT packet.
Definition: core_mqtt_serializer.h:248
+
uint8_t * pRemainingData
Remaining serialized data in the MQTT packet.
Definition: core_mqtt_serializer.h:253
+
+
+
+ +

◆ MQTT_DeserializeAck()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_DeserializeAck (const MQTTPacketInfo_tpIncomingPacket,
uint16_t * pPacketId,
bool * pSessionPresent 
)
+
+ +

Deserialize an MQTT CONNACK, SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, PUBCOMP, or PINGRESP.

+
Parameters
+ + + + +
[in]pIncomingPacketMQTTPacketInfo_t containing the buffer.
[out]pPacketIdThe packet ID of obtained from the buffer. Not used in CONNACK or PINGRESP.
[out]pSessionPresentBoolean flag from a CONNACK indicating present session.
+
+
+
Returns
MQTTBadParameter, MQTTBadResponse, MQTTServerRefused, or MQTTSuccess.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPacketInfo_t incomingPacket;
+
// Used for SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, and PUBCOMP.
+
uint16_t packetId;
+
// Used for CONNACK.
+
bool sessionPresent;
+
+
// Receive an incoming packet and populate all fields. The details are out of scope
+
// for this example.
+
receiveIncomingPacket( &incomingPacket );
+
+
// Deserialize ack information if the incoming packet is not a publish.
+
if( ( incomingPacket.type & 0xF0 ) != MQTT_PACKET_TYPE_PUBLISH )
+
{
+
status = MQTT_DeserializeAck( &incomingPacket, &packetId, &sessionPresent );
+
if( status == MQTTSuccess )
+
{
+
// The packet ID or session present flag information is available. For
+
// ping response packets, the only information is the status code.
+
}
+
}
+
MQTTStatus_t MQTT_DeserializeAck(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, bool *pSessionPresent)
Deserialize an MQTT CONNACK, SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, PUBCOMP, or PINGRESP.
Definition: core_mqtt_serializer.c:2484
+
+
+
+ +

◆ MQTT_GetIncomingPacketTypeAndLength()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength (TransportRecv_t readFunc,
NetworkContext_tpNetworkContext,
MQTTPacketInfo_tpIncomingPacket 
)
+
+ +

Extract the MQTT packet type and length from incoming packet.

+

This function must be called for every incoming packet to retrieve the MQTTPacketInfo_t.type and MQTTPacketInfo_t.remainingLength. A MQTTPacketInfo_t is not valid until this routine has been invoked.

+
Parameters
+ + + + +
[in]readFuncTransport layer read function pointer.
[in]pNetworkContextThe network context pointer provided by the application.
[out]pIncomingPacketPointer to MQTTPacketInfo_t structure. This is where type, remaining length and packet identifier are stored.
+
+
+
Returns
MQTTSuccess on successful extraction of type and length, MQTTBadParameter if pIncomingPacket is invalid, MQTTRecvFailed on transport receive failure, MQTTBadResponse if an invalid packet is read, and MQTTNoDataAvailable if there is nothing to read.
+

Example

// TransportRecv_t function for reading from the network.
+
int32_t socket_recv(
+
NetworkContext_t * pNetworkContext,
+
void * pBuffer,
+
size_t bytesToRecv
+
);
+
// Some context to be used with above transport receive function.
+
NetworkContext_t networkContext;
+
+
// Struct to hold the incoming packet information.
+
MQTTPacketInfo_t incomingPacket;
+ +
int32_t bytesRecvd;
+
// Buffer to hold the remaining data of the incoming packet.
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
// Loop until data is available to be received.
+
do{
+ +
socket_recv,
+
&networkContext,
+
&incomingPacket
+
);
+
} while( status == MQTTNoDataAvailable );
+
+
assert( status == MQTTSuccess );
+
+
// Receive the rest of the incoming packet.
+
assert( incomingPacket.remainingLength <= BUFFER_SIZE );
+
bytesRecvd = socket_recv(
+
&networkContext,
+
( void * ) buffer,
+
incomingPacket.remainingLength
+
);
+
+
// Set the remaining data field.
+
incomingPacket.pRemainingData = buffer;
+
@ MQTTNoDataAvailable
Definition: core_mqtt_serializer.h:95
+
+
+
+ +

◆ MQTT_ProcessIncomingPacketTypeAndLength()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_ProcessIncomingPacketTypeAndLength (const uint8_t * pBuffer,
const size_t * pIndex,
MQTTPacketInfo_tpIncomingPacket 
)
+
+ +

Extract the MQTT packet type and length from incoming packet.

+

This function must be called for every incoming packet to retrieve the MQTTPacketInfo_t.type and MQTTPacketInfo_t.remainingLength. A MQTTPacketInfo_t is not valid until this routine has been invoked.

+
Parameters
+ + + + +
[in]pBufferThe buffer holding the raw data to be processed
[in]pIndexPointer to the index within the buffer to marking the end of raw data available.
[out]pIncomingPacketStructure used to hold the fields of the incoming packet.
+
+
+
Returns
MQTTSuccess on successful extraction of type and length, MQTTBadParameter if pIncomingPacket is invalid, MQTTBadResponse if an invalid packet is read, and MQTTNoDataAvailable if there is nothing to read.
+ +
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/core__mqtt__serializer_8h_source.html b/v1.3.0/coreMQTT/core__mqtt__serializer_8h_source.html new file mode 100644 index 00000000..a92c391c --- /dev/null +++ b/v1.3.0/coreMQTT/core__mqtt__serializer_8h_source.html @@ -0,0 +1,466 @@ + + + + + + + +coreMQTT: core_mqtt_serializer.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
core_mqtt_serializer.h
+
+
+Go to the documentation of this file.
1/*
+
2 * coreMQTT v2.3.1
+
3 * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
4 *
+
5 * SPDX-License-Identifier: MIT
+
6 *
+
7 * Permission is hereby granted, free of charge, to any person obtaining a copy of
+
8 * this software and associated documentation files (the "Software"), to deal in
+
9 * the Software without restriction, including without limitation the rights to
+
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
11 * the Software, and to permit persons to whom the Software is furnished to do so,
+
12 * subject to the following conditions:
+
13 *
+
14 * The above copyright notice and this permission notice shall be included in all
+
15 * copies or substantial portions of the Software.
+
16 *
+
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
23 */
+
24
+
32#ifndef CORE_MQTT_SERIALIZER_H
+
33#define CORE_MQTT_SERIALIZER_H
+
34
+
35#include <stddef.h>
+
36#include <stdint.h>
+
37#include <stdbool.h>
+
38
+
39/* *INDENT-OFF* */
+
40#ifdef __cplusplus
+
41 extern "C" {
+
42#endif
+
43/* *INDENT-ON */
+
44
+
45#include "transport_interface.h"
+
46
+
47/* MQTT packet types. */
+
48
+
53#define MQTT_PACKET_TYPE_CONNECT ( ( uint8_t ) 0x10U )
+
54#define MQTT_PACKET_TYPE_CONNACK ( ( uint8_t ) 0x20U )
+
55#define MQTT_PACKET_TYPE_PUBLISH ( ( uint8_t ) 0x30U )
+
56#define MQTT_PACKET_TYPE_PUBACK ( ( uint8_t ) 0x40U )
+
57#define MQTT_PACKET_TYPE_PUBREC ( ( uint8_t ) 0x50U )
+
58#define MQTT_PACKET_TYPE_PUBREL ( ( uint8_t ) 0x62U )
+
59#define MQTT_PACKET_TYPE_PUBCOMP ( ( uint8_t ) 0x70U )
+
60#define MQTT_PACKET_TYPE_SUBSCRIBE ( ( uint8_t ) 0x82U )
+
61#define MQTT_PACKET_TYPE_SUBACK ( ( uint8_t ) 0x90U )
+
62#define MQTT_PACKET_TYPE_UNSUBSCRIBE ( ( uint8_t ) 0xA2U )
+
63#define MQTT_PACKET_TYPE_UNSUBACK ( ( uint8_t ) 0xB0U )
+
64#define MQTT_PACKET_TYPE_PINGREQ ( ( uint8_t ) 0xC0U )
+
65#define MQTT_PACKET_TYPE_PINGRESP ( ( uint8_t ) 0xD0U )
+
66#define MQTT_PACKET_TYPE_DISCONNECT ( ( uint8_t ) 0xE0U )
+
73#define MQTT_PUBLISH_ACK_PACKET_SIZE ( 4UL )
+
74
+
75/* Structures defined in this file. */
+
76struct MQTTFixedBuffer;
+
77struct MQTTConnectInfo;
+
78struct MQTTSubscribeInfo;
+
79struct MQTTPublishInfo;
+
80struct MQTTPacketInfo;
+
81
+
86typedef enum MQTTStatus
+
87{
+ + + + + + + + + + + + + +
103
+
108typedef enum MQTTQoS
+
109{
+ + +
112 MQTTQoS2 = 2
+ +
114
+
122typedef struct MQTTFixedBuffer
+
123{
+
124 uint8_t * pBuffer;
+
125 size_t size;
+ +
127
+
132typedef struct MQTTConnectInfo
+
133{
+ +
138
+ +
143
+
147 const char * pClientIdentifier;
+
148
+ +
153
+
157 const char * pUserName;
+
158
+ +
163
+
167 const char * pPassword;
+
168
+ + +
174
+
179typedef struct MQTTSubscribeInfo
+
180{
+ +
185
+
189 const char * pTopicFilter;
+
190
+ + +
196
+
201typedef struct MQTTPublishInfo
+
202{
+ +
207
+
211 bool retain;
+
212
+
216 bool dup;
+
217
+
221 const char * pTopicName;
+
222
+ +
227
+
231 const void * pPayload;
+
232
+ + +
238
+
243typedef struct MQTTPacketInfo
+
244{
+
248 uint8_t type;
+
249
+
253 uint8_t * pRemainingData;
+
254
+ +
259
+ + +
265
+
313/* @[declare_mqtt_getconnectpacketsize] */
+ +
315 const MQTTPublishInfo_t * pWillInfo,
+
316 size_t * pRemainingLength,
+
317 size_t * pPacketSize );
+
318/* @[declare_mqtt_getconnectpacketsize] */
+
319
+
369/* @[declare_mqtt_serializeconnect] */
+ +
371 const MQTTPublishInfo_t * pWillInfo,
+
372 size_t remainingLength,
+
373 const MQTTFixedBuffer_t * pFixedBuffer );
+
374/* @[declare_mqtt_serializeconnect] */
+
375
+
427/* @[declare_mqtt_getsubscribepacketsize] */
+ +
429 size_t subscriptionCount,
+
430 size_t * pRemainingLength,
+
431 size_t * pPacketSize );
+
432/* @[declare_mqtt_getsubscribepacketsize] */
+
433
+
493/* @[declare_mqtt_serializesubscribe] */
+ +
495 size_t subscriptionCount,
+
496 uint16_t packetId,
+
497 size_t remainingLength,
+
498 const MQTTFixedBuffer_t * pFixedBuffer );
+
499/* @[declare_mqtt_serializesubscribe] */
+
500
+
544/* @[declare_mqtt_getunsubscribepacketsize] */
+ +
546 size_t subscriptionCount,
+
547 size_t * pRemainingLength,
+
548 size_t * pPacketSize );
+
549/* @[declare_mqtt_getunsubscribepacketsize] */
+
550
+
610/* @[declare_mqtt_serializeunsubscribe] */
+ +
612 size_t subscriptionCount,
+
613 uint16_t packetId,
+
614 size_t remainingLength,
+
615 const MQTTFixedBuffer_t * pFixedBuffer );
+
616/* @[declare_mqtt_serializeunsubscribe] */
+
617
+
664/* @[declare_mqtt_getpublishpacketsize] */
+ +
666 size_t * pRemainingLength,
+
667 size_t * pPacketSize );
+
668/* @[declare_mqtt_getpublishpacketsize] */
+
669
+
732/* @[declare_mqtt_serializepublish] */
+ +
734 uint16_t packetId,
+
735 size_t remainingLength,
+
736 const MQTTFixedBuffer_t * pFixedBuffer );
+
737/* @[declare_mqtt_serializepublish] */
+
738
+ +
753 size_t remainingLength,
+
754 uint8_t * pBuffer,
+
755 size_t * headerSize );
+
756
+
830/* @[declare_mqtt_serializepublishheader] */
+ +
832 uint16_t packetId,
+
833 size_t remainingLength,
+
834 const MQTTFixedBuffer_t * pFixedBuffer,
+
835 size_t * pHeaderSize );
+
836/* @[declare_mqtt_serializepublishheader] */
+
837
+
879/* @[declare_mqtt_serializeack] */
+ +
881 uint8_t packetType,
+
882 uint16_t packetId );
+
883/* @[declare_mqtt_serializeack] */
+
884
+
909/* @[declare_mqtt_getdisconnectpacketsize] */
+
910MQTTStatus_t MQTT_GetDisconnectPacketSize( size_t * pPacketSize );
+
911/* @[declare_mqtt_getdisconnectpacketsize] */
+
912
+
950/* @[declare_mqtt_serializedisconnect] */
+ +
952/* @[declare_mqtt_serializedisconnect] */
+
953
+
978/* @[declare_mqtt_getpingreqpacketsize] */
+
979MQTTStatus_t MQTT_GetPingreqPacketSize( size_t * pPacketSize );
+
980/* @[declare_mqtt_getpingreqpacketsize] */
+
981
+
1019/* @[declare_mqtt_serializepingreq] */
+ +
1021/* @[declare_mqtt_serializepingreq] */
+
1022
+
1080/* @[declare_mqtt_deserializepublish] */
+ +
1082 uint16_t * pPacketId,
+
1083 MQTTPublishInfo_t * pPublishInfo );
+
1084/* @[declare_mqtt_deserializepublish] */
+
1085
+
1124/* @[declare_mqtt_deserializeack] */
+
1125MQTTStatus_t MQTT_DeserializeAck( const MQTTPacketInfo_t * pIncomingPacket,
+
1126 uint16_t * pPacketId,
+
1127 bool * pSessionPresent );
+
1128/* @[declare_mqtt_deserializeack] */
+
1129
+
1190/* @[declare_mqtt_getincomingpackettypeandlength] */
+ +
1192 NetworkContext_t * pNetworkContext,
+
1193 MQTTPacketInfo_t * pIncomingPacket );
+
1194/* @[declare_mqtt_getincomingpackettypeandlength] */
+
1195
+
1214 /* @[declare_mqtt_processincomingpackettypeandlength] */
+ +
1216 const size_t * pIndex,
+
1217 MQTTPacketInfo_t * pIncomingPacket );
+
1218/* @[declare_mqtt_processincomingpackettypeandlength] */
+
1219
+
1238uint8_t * MQTT_SerializeConnectFixedHeader( uint8_t * pIndex,
+
1239 const MQTTConnectInfo_t * pConnectInfo,
+
1240 const MQTTPublishInfo_t * pWillInfo,
+
1241 size_t remainingLength );
+
1261uint8_t * MQTT_SerializeSubscribeHeader( size_t remainingLength,
+
1262 uint8_t * pIndex,
+
1263 uint16_t packetId );
+
1283uint8_t * MQTT_SerializeUnsubscribeHeader( size_t remainingLength,
+
1284 uint8_t * pIndex,
+
1285 uint16_t packetId );
+
1288/* *INDENT-OFF* */
+
1289#ifdef __cplusplus
+
1290 }
+
1291#endif
+
1292/* *INDENT-ON* */
+
1293
+
1294#endif /* ifndef CORE_MQTT_SERIALIZER_H */
+
uint8_t * MQTT_SerializeUnsubscribeHeader(size_t remainingLength, uint8_t *pIndex, uint16_t packetId)
Serialize the fixed part of the unsubscribe packet header.
Definition: core_mqtt_serializer.c:1910
+
uint8_t * MQTT_SerializeConnectFixedHeader(uint8_t *pIndex, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength)
Serialize the fixed part of the connect packet header.
Definition: core_mqtt_serializer.c:1553
+
uint8_t * MQTT_SerializeSubscribeHeader(size_t remainingLength, uint8_t *pIndex, uint16_t packetId)
Serialize the fixed part of the subscribe packet header.
Definition: core_mqtt_serializer.c:1886
+
MQTTStatus_t MQTT_GetPingreqPacketSize(size_t *pPacketSize)
Get the size of an MQTT PINGREQ packet.
Definition: core_mqtt_serializer.c:2384
+
MQTTStatus_t MQTT_SerializeAck(const MQTTFixedBuffer_t *pFixedBuffer, uint8_t packetType, uint16_t packetId)
Serialize an MQTT PUBACK, PUBREC, PUBREL, or PUBCOMP into the given buffer.
Definition: core_mqtt_serializer.c:2266
+
MQTTStatus_t MQTT_SerializeSubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT SUBSCRIBE packet in the given buffer.
Definition: core_mqtt_serializer.c:1932
+
MQTTStatus_t MQTT_GetUnsubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.
Definition: core_mqtt_serializer.c:1978
+
MQTTStatus_t MQTT_SerializePublishHeaderWithoutTopic(const MQTTPublishInfo_t *pPublishInfo, size_t remainingLength, uint8_t *pBuffer, size_t *headerSize)
Serialize an MQTT PUBLISH packet header without the topic string in the given buffer....
Definition: core_mqtt_serializer.c:636
+
MQTTStatus_t MQTT_DeserializePublish(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo)
Deserialize an MQTT PUBLISH packet.
Definition: core_mqtt_serializer.c:2447
+
MQTTStatus_t MQTT_GetConnectPacketSize(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the size and Remaining Length of an MQTT CONNECT packet.
Definition: core_mqtt_serializer.c:1690
+
MQTTStatus_t MQTT_SerializePublishHeader(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer, size_t *pHeaderSize)
Serialize an MQTT PUBLISH packet header in the given buffer.
Definition: core_mqtt_serializer.c:2183
+
MQTTStatus_t MQTT_SerializeDisconnect(const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT DISCONNECT packet into the given buffer.
Definition: core_mqtt_serializer.c:2341
+
MQTTStatus_t MQTT_GetDisconnectPacketSize(size_t *pPacketSize)
Get the size of an MQTT DISCONNECT packet.
Definition: core_mqtt_serializer.c:2321
+
MQTTStatus_t MQTT_ProcessIncomingPacketTypeAndLength(const uint8_t *pBuffer, const size_t *pIndex, MQTTPacketInfo_t *pIncomingPacket)
Extract the MQTT packet type and length from incoming packet.
Definition: core_mqtt_serializer.c:2626
+
MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength(TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket)
Extract the MQTT packet type and length from incoming packet.
Definition: core_mqtt_serializer.c:2561
+
MQTTStatus_t MQTT_GetPublishPacketSize(const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the packet size and remaining length of an MQTT PUBLISH packet.
Definition: core_mqtt_serializer.c:2057
+
MQTTStatus_t MQTT_SerializeConnect(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT CONNECT packet in the given fixed buffer pFixedBuffer.
Definition: core_mqtt_serializer.c:1790
+
MQTTStatus_t MQTT_SerializeUnsubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT UNSUBSCRIBE packet in the given buffer.
Definition: core_mqtt_serializer.c:2016
+
MQTTStatus_t MQTT_GetSubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.
Definition: core_mqtt_serializer.c:1848
+
MQTTStatus_t MQTT_SerializePublish(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT PUBLISH packet in the given buffer.
Definition: core_mqtt_serializer.c:2098
+
MQTTStatus_t MQTT_DeserializeAck(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, bool *pSessionPresent)
Deserialize an MQTT CONNACK, SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, PUBCOMP, or PINGRESP.
Definition: core_mqtt_serializer.c:2484
+
MQTTStatus_t MQTT_SerializePingreq(const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT PINGREQ packet into the given buffer.
Definition: core_mqtt_serializer.c:2404
+
int32_t(* TransportRecv_t)(NetworkContext_t *pNetworkContext, void *pBuffer, size_t bytesToRecv)
Transport interface for receiving data on the network.
Definition: transport_interface.h:218
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTTQoS_t
MQTT Quality of Service values.
Definition: core_mqtt_serializer.h:109
+
@ MQTTKeepAliveTimeout
Definition: core_mqtt_serializer.h:98
+
@ MQTTServerRefused
Definition: core_mqtt_serializer.h:94
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
@ MQTTNoDataAvailable
Definition: core_mqtt_serializer.h:95
+
@ MQTTIllegalState
Definition: core_mqtt_serializer.h:96
+
@ MQTTStateCollision
Definition: core_mqtt_serializer.h:97
+
@ MQTTRecvFailed
Definition: core_mqtt_serializer.h:92
+
@ MQTTBadParameter
Definition: core_mqtt_serializer.h:89
+
@ MQTTBadResponse
Definition: core_mqtt_serializer.h:93
+
@ MQTTNeedMoreBytes
Definition: core_mqtt_serializer.h:99
+
@ MQTTNoMemory
Definition: core_mqtt_serializer.h:90
+
@ MQTTSendFailed
Definition: core_mqtt_serializer.h:91
+
@ MQTTQoS1
Definition: core_mqtt_serializer.h:111
+
@ MQTTQoS2
Definition: core_mqtt_serializer.h:112
+
@ MQTTQoS0
Definition: core_mqtt_serializer.h:110
+
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
const char * pClientIdentifier
MQTT client identifier. Must be unique per client.
Definition: core_mqtt_serializer.h:147
+
const char * pUserName
MQTT user name. Set to NULL if not used.
Definition: core_mqtt_serializer.h:157
+
bool cleanSession
Whether to establish a new, clean session or resume a previous session.
Definition: core_mqtt_serializer.h:137
+
uint16_t userNameLength
Length of MQTT user name. Set to 0 if not used.
Definition: core_mqtt_serializer.h:162
+
uint16_t keepAliveSeconds
MQTT keep alive period.
Definition: core_mqtt_serializer.h:142
+
uint16_t clientIdentifierLength
Length of the client identifier.
Definition: core_mqtt_serializer.h:152
+
uint16_t passwordLength
Length of MQTT password. Set to 0 if not used.
Definition: core_mqtt_serializer.h:172
+
const char * pPassword
MQTT password. Set to NULL if not used.
Definition: core_mqtt_serializer.h:167
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+
size_t remainingLength
Length of remaining serialized data.
Definition: core_mqtt_serializer.h:258
+
uint8_t type
Type of incoming MQTT packet.
Definition: core_mqtt_serializer.h:248
+
size_t headerLength
The length of the MQTT header including the type and length.
Definition: core_mqtt_serializer.h:263
+
uint8_t * pRemainingData
Remaining serialized data in the MQTT packet.
Definition: core_mqtt_serializer.h:253
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+
MQTTQoS_t qos
Quality of Service for message.
Definition: core_mqtt_serializer.h:206
+
bool retain
Whether this is a retained message.
Definition: core_mqtt_serializer.h:211
+
uint16_t topicNameLength
Length of topic name.
Definition: core_mqtt_serializer.h:226
+
size_t payloadLength
Message payload length.
Definition: core_mqtt_serializer.h:236
+
bool dup
Whether this is a duplicate publish message.
Definition: core_mqtt_serializer.h:216
+
const char * pTopicName
Topic name on which the message is published.
Definition: core_mqtt_serializer.h:221
+
const void * pPayload
Message payload.
Definition: core_mqtt_serializer.h:231
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+
MQTTQoS_t qos
Quality of Service for subscription.
Definition: core_mqtt_serializer.h:184
+
uint16_t topicFilterLength
Length of subscription topic filter.
Definition: core_mqtt_serializer.h:194
+
const char * pTopicFilter
Topic filter to subscribe to.
Definition: core_mqtt_serializer.h:189
+
Transport interface definitions to send and receive data over the network.
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/core__mqtt__state_8c.html b/v1.3.0/coreMQTT/core__mqtt__state_8c.html new file mode 100644 index 00000000..bac03e9c --- /dev/null +++ b/v1.3.0/coreMQTT/core__mqtt__state_8c.html @@ -0,0 +1,1371 @@ + + + + + + + +coreMQTT: core_mqtt_state.c File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_state.c File Reference
+
+
+ +

Implements the functions in core_mqtt_state.h. +More...

+
#include <assert.h>
+#include <string.h>
+#include "core_mqtt_state.h"
+#include "core_mqtt_config_defaults.h"
+
+ + + + + + + + + + + + + +

+Macros

+#define MQTT_INVALID_STATE_COUNT   ( ~ZERO_SIZE_T )
 This macro depicts the invalid value for the state publishes.
 
#define UINT16_BITMAP_BIT_SET_AT(position)   ( ( uint16_t ) 0x01U << ( ( uint16_t ) position ) )
 Create a 16-bit bitmap with bit set at specified position.
 
#define UINT16_SET_BIT(x, position)   ( ( x ) = ( uint16_t ) ( ( x ) | ( UINT16_BITMAP_BIT_SET_AT( position ) ) ) )
 Set a bit in an 16-bit unsigned integer.
 
#define UINT16_CHECK_BIT(x, position)   ( ( ( x ) & ( UINT16_BITMAP_BIT_SET_AT( position ) ) ) == ( UINT16_BITMAP_BIT_SET_AT( position ) ) )
 Macro for checking if a bit is set in a 16-bit unsigned integer.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

static bool validateTransitionPublish (MQTTPublishState_t currentState, MQTTPublishState_t newState, MQTTStateOperation_t opType, MQTTQoS_t qos)
 Test if a transition to new state is possible, when dealing with PUBLISHes.
 
static bool validateTransitionAck (MQTTPublishState_t currentState, MQTTPublishState_t newState)
 Test if a transition to a new state is possible, when dealing with acks.
 
static bool isPublishOutgoing (MQTTPubAckType_t packetType, MQTTStateOperation_t opType)
 Test if the publish corresponding to an ack is outgoing or incoming.
 
static size_t findInRecord (const MQTTPubAckInfo_t *records, size_t recordCount, uint16_t packetId, MQTTQoS_t *pQos, MQTTPublishState_t *pCurrentState)
 Find a packet ID in the state record.
 
static void compactRecords (MQTTPubAckInfo_t *records, size_t recordCount)
 Compact records.
 
static MQTTStatus_t addRecord (MQTTPubAckInfo_t *records, size_t recordCount, uint16_t packetId, MQTTQoS_t qos, MQTTPublishState_t publishState)
 Store a new entry in the state record.
 
static void updateRecord (MQTTPubAckInfo_t *records, size_t recordIndex, MQTTPublishState_t newState, bool shouldDelete)
 Update and possibly delete an entry in the state record.
 
static uint16_t stateSelect (const MQTTContext_t *pMqttContext, uint16_t searchStates, MQTTStateCursor_t *pCursor)
 Get the packet ID and index of an outgoing publish in specified states.
 
static MQTTStatus_t updateStateAck (MQTTPubAckInfo_t *records, size_t maxRecordCount, size_t recordIndex, uint16_t packetId, MQTTPublishState_t currentState, MQTTPublishState_t newState)
 Update the state records for an ACK after state transition validations.
 
static MQTTStatus_t updateStatePublish (const MQTTContext_t *pMqttContext, size_t recordIndex, uint16_t packetId, MQTTStateOperation_t opType, MQTTQoS_t qos, MQTTPublishState_t currentState, MQTTPublishState_t newState)
 Update the state record for a PUBLISH packet after validating the state transitions.
 
MQTTPublishState_t MQTT_CalculateStateAck (MQTTPubAckType_t packetType, MQTTStateOperation_t opType, MQTTQoS_t qos)
 Calculate the state from a PUBACK, PUBREC, PUBREL, or PUBCOMP.
 
MQTTStatus_t MQTT_ReserveState (const MQTTContext_t *pMqttContext, uint16_t packetId, MQTTQoS_t qos)
 Reserve an entry for an outgoing QoS 1 or Qos 2 publish.
 
MQTTPublishState_t MQTT_CalculateStatePublish (MQTTStateOperation_t opType, MQTTQoS_t qos)
 Calculate the new state for a publish from its qos and operation type.
 
MQTTStatus_t MQTT_UpdateStatePublish (const MQTTContext_t *pMqttContext, uint16_t packetId, MQTTStateOperation_t opType, MQTTQoS_t qos, MQTTPublishState_t *pNewState)
 Update the state record for a PUBLISH packet.
 
MQTTStatus_t MQTT_RemoveStateRecord (const MQTTContext_t *pMqttContext, uint16_t packetId)
 Remove the state record for a PUBLISH packet.
 
MQTTStatus_t MQTT_UpdateStateAck (const MQTTContext_t *pMqttContext, uint16_t packetId, MQTTPubAckType_t packetType, MQTTStateOperation_t opType, MQTTPublishState_t *pNewState)
 Update the state record for an ACKed publish.
 
uint16_t MQTT_PubrelToResend (const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor, MQTTPublishState_t *pState)
 Get the packet ID of next pending PUBREL ack to be resent.
 
uint16_t MQTT_PublishToResend (const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor)
 Get the packet ID of next pending publish to be resent.
 
const char * MQTT_State_strerror (MQTTPublishState_t state)
 State to string conversion for state engine.
 
+ + + + +

+Variables

+static const size_t ZERO_SIZE_T = 0U
 A global static variable used to generate the macro MQTT_INVALID_STATE_COUNT of size_t length.
 
+

Detailed Description

+

Implements the functions in core_mqtt_state.h.

+

Macro Definition Documentation

+ +

◆ UINT16_BITMAP_BIT_SET_AT

+ +
+
+ + + + + + + + +
#define UINT16_BITMAP_BIT_SET_AT( position)   ( ( uint16_t ) 0x01U << ( ( uint16_t ) position ) )
+
+ +

Create a 16-bit bitmap with bit set at specified position.

+
Parameters
+ + +
[in]positionThe position at which the bit need to be set.
+
+
+ +
+
+ +

◆ UINT16_SET_BIT

+ +
+
+ + + + + + + + + + + + + + + + + + +
#define UINT16_SET_BIT( x,
 position 
)   ( ( x ) = ( uint16_t ) ( ( x ) | ( UINT16_BITMAP_BIT_SET_AT( position ) ) ) )
+
+ +

Set a bit in an 16-bit unsigned integer.

+
Parameters
+ + + +
[in]xThe 16-bit unsigned integer to set a bit.
[in]positionThe position at which the bit need to be set.
+
+
+ +
+
+ +

◆ UINT16_CHECK_BIT

+ +
+
+ + + + + + + + + + + + + + + + + + +
#define UINT16_CHECK_BIT( x,
 position 
)   ( ( ( x ) & ( UINT16_BITMAP_BIT_SET_AT( position ) ) ) == ( UINT16_BITMAP_BIT_SET_AT( position ) ) )
+
+ +

Macro for checking if a bit is set in a 16-bit unsigned integer.

+
Parameters
+ + + +
[in]xThe unsigned 16-bit integer to check.
[in]positionWhich bit to check.
+
+
+ +
+
+

Function Documentation

+ +

◆ validateTransitionPublish()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static bool validateTransitionPublish (MQTTPublishState_t currentState,
MQTTPublishState_t newState,
MQTTStateOperation_t opType,
MQTTQoS_t qos 
)
+
+static
+
+ +

Test if a transition to new state is possible, when dealing with PUBLISHes.

+
Parameters
+ + + + + +
[in]currentStateThe current state.
[in]newStateState to transition to.
[in]opTypeReserve, Send, or Receive.
[in]qos0, 1, or 2.
+
+
+
Note
This function does not validate the current state, or the new state based on either the operation type or QoS. It assumes the new state is valid given the opType and QoS, which will be the case if calculated by MQTT_CalculateStatePublish().
+
Returns
true if transition is possible, else false
+ +
+
+ +

◆ validateTransitionAck()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static bool validateTransitionAck (MQTTPublishState_t currentState,
MQTTPublishState_t newState 
)
+
+static
+
+ +

Test if a transition to a new state is possible, when dealing with acks.

+
Parameters
+ + + +
[in]currentStateThe current state.
[in]newStateState to transition to.
+
+
+
Returns
true if transition is possible, else false.
+ +
+
+ +

◆ isPublishOutgoing()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static bool isPublishOutgoing (MQTTPubAckType_t packetType,
MQTTStateOperation_t opType 
)
+
+static
+
+ +

Test if the publish corresponding to an ack is outgoing or incoming.

+
Parameters
+ + + +
[in]packetTypePUBACK, PUBREC, PUBREL, or PUBCOMP.
[in]opTypeSend, or Receive.
+
+
+
Returns
true if corresponds to outgoing publish, else false.
+ +
+
+ +

◆ findInRecord()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static size_t findInRecord (const MQTTPubAckInfo_trecords,
size_t recordCount,
uint16_t packetId,
MQTTQoS_tpQos,
MQTTPublishState_tpCurrentState 
)
+
+static
+
+ +

Find a packet ID in the state record.

+
Parameters
+ + + + + + +
[in]recordsState record array.
[in]recordCountLength of record array.
[in]packetIdpacket ID to search for.
[out]pQosQoS retrieved from record.
[out]pCurrentStatestate retrieved from record.
+
+
+
Returns
index of the packet id in the record if it exists, else the record length.
+ +
+
+ +

◆ compactRecords()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static void compactRecords (MQTTPubAckInfo_trecords,
size_t recordCount 
)
+
+static
+
+ +

Compact records.

+

Records are arranged in the relative order to maintain message ordering. This will lead to fragmentation and this function will help in defragmenting the records array.

+
Parameters
+ + + +
[in]recordsState record array.
[in]recordCountLength of record array.
+
+
+ +
+
+ +

◆ addRecord()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t addRecord (MQTTPubAckInfo_trecords,
size_t recordCount,
uint16_t packetId,
MQTTQoS_t qos,
MQTTPublishState_t publishState 
)
+
+static
+
+ +

Store a new entry in the state record.

+
Parameters
+ + + + + + +
[in]recordsState record array.
[in]recordCountLength of record array.
[in]packetIdPacket ID of new entry.
[in]qosQoS of new entry.
[in]publishStateState of new entry.
+
+
+
Returns
MQTTSuccess, MQTTNoMemory, or MQTTStateCollision.
+ +
+
+ +

◆ updateRecord()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static void updateRecord (MQTTPubAckInfo_trecords,
size_t recordIndex,
MQTTPublishState_t newState,
bool shouldDelete 
)
+
+static
+
+ +

Update and possibly delete an entry in the state record.

+
Parameters
+ + + + + +
[in]recordsState record array.
[in]recordIndexindex of record to update.
[in]newStateNew state to update.
[in]shouldDeleteWhether an existing entry should be deleted.
+
+
+ +
+
+ +

◆ stateSelect()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static uint16_t stateSelect (const MQTTContext_tpMqttContext,
uint16_t searchStates,
MQTTStateCursor_tpCursor 
)
+
+static
+
+ +

Get the packet ID and index of an outgoing publish in specified states.

+
Parameters
+ + + + +
[in]pMqttContextInitialized MQTT context.
[in]searchStatesThe states to search for in 2-byte bit map.
[in,out]pCursorIndex at which to start searching.
+
+
+
Returns
Packet ID of the outgoing publish.
+ +
+
+ +

◆ updateStateAck()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t updateStateAck (MQTTPubAckInfo_trecords,
size_t maxRecordCount,
size_t recordIndex,
uint16_t packetId,
MQTTPublishState_t currentState,
MQTTPublishState_t newState 
)
+
+static
+
+ +

Update the state records for an ACK after state transition validations.

+
Parameters
+ + + + + + + +
[in]recordsState records pointer.
[in]maxRecordCountThe maximum number of records.
[in]recordIndexIndex at which the record is stored.
[in]packetIdPacket id of the packet.
[in]currentStateCurrent state of the publish record.
[in]newStateNew state of the publish.
+
+
+
Returns
MQTTIllegalState, or MQTTSuccess.
+ +
+
+ +

◆ updateStatePublish()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t updateStatePublish (const MQTTContext_tpMqttContext,
size_t recordIndex,
uint16_t packetId,
MQTTStateOperation_t opType,
MQTTQoS_t qos,
MQTTPublishState_t currentState,
MQTTPublishState_t newState 
)
+
+static
+
+ +

Update the state record for a PUBLISH packet after validating the state transitions.

+
Parameters
+ + + + + + + + +
[in]pMqttContextInitialized MQTT context.
[in]recordIndexIndex in state records at which publish record exists.
[in]packetIdID of the PUBLISH packet.
[in]opTypeSend or Receive.
[in]qos0, 1, or 2.
[in]currentStateCurrent state of the publish record.
[in]newStateNew state of the publish record.
+
+
+
Returns
MQTTIllegalState, MQTTStateCollision or MQTTSuccess.
+ +
+
+ +

◆ MQTT_CalculateStateAck()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTPublishState_t MQTT_CalculateStateAck (MQTTPubAckType_t packetType,
MQTTStateOperation_t opType,
MQTTQoS_t qos 
)
+
+ +

Calculate the state from a PUBACK, PUBREC, PUBREL, or PUBCOMP.

+
Parameters
+ + + + +
[in]packetTypePUBACK, PUBREC, PUBREL, or PUBCOMP.
[in]opTypeSend or Receive.
[in]qos1 or 2.
+
+
+
Returns
The calculated state.
+ +
+
+ +

◆ MQTT_ReserveState()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_ReserveState (const MQTTContext_tpMqttContext,
uint16_t packetId,
MQTTQoS_t qos 
)
+
+ +

Reserve an entry for an outgoing QoS 1 or Qos 2 publish.

+
Parameters
+ + + + +
[in]pMqttContextInitialized MQTT context.
[in]packetIdThe ID of the publish packet.
[in]qos1 or 2.
+
+
+
Returns
MQTTSuccess, MQTTNoMemory, or MQTTStateCollision.
+ +
+
+ +

◆ MQTT_CalculateStatePublish()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTPublishState_t MQTT_CalculateStatePublish (MQTTStateOperation_t opType,
MQTTQoS_t qos 
)
+
+ +

Calculate the new state for a publish from its qos and operation type.

+
Parameters
+ + + +
[in]opTypeSend or Receive.
[in]qos0, 1, or 2.
+
+
+
Returns
The calculated state.
+ +
+
+ +

◆ MQTT_UpdateStatePublish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_UpdateStatePublish (const MQTTContext_tpMqttContext,
uint16_t packetId,
MQTTStateOperation_t opType,
MQTTQoS_t qos,
MQTTPublishState_tpNewState 
)
+
+ +

Update the state record for a PUBLISH packet.

+
Parameters
+ + + + + + +
[in]pMqttContextInitialized MQTT context.
[in]packetIdID of the PUBLISH packet.
[in]opTypeSend or Receive.
[in]qos0, 1, or 2.
[out]pNewStateUpdated state of the publish.
+
+
+
Returns
MQTTBadParameter, MQTTIllegalState, MQTTStateCollision or MQTTSuccess.
+ +
+
+ +

◆ MQTT_RemoveStateRecord()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_RemoveStateRecord (const MQTTContext_tpMqttContext,
uint16_t packetId 
)
+
+ +

Remove the state record for a PUBLISH packet.

+
Parameters
+ + + +
[in]pMqttContextInitialized MQTT context.
[in]packetIdID of the PUBLISH packet.
+
+
+
Returns
MQTTBadParameter or MQTTSuccess.
+ +
+
+ +

◆ MQTT_UpdateStateAck()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTT_UpdateStateAck (const MQTTContext_tpMqttContext,
uint16_t packetId,
MQTTPubAckType_t packetType,
MQTTStateOperation_t opType,
MQTTPublishState_tpNewState 
)
+
+ +

Update the state record for an ACKed publish.

+
Parameters
+ + + + + + +
[in]pMqttContextInitialized MQTT context.
[in]packetIdID of the ack packet.
[in]packetTypePUBACK, PUBREC, PUBREL, or PUBCOMP.
[in]opTypeSend or Receive.
[out]pNewStateUpdated state of the publish.
+
+
+
Returns
MQTTBadParameter if an invalid parameter is passed; MQTTBadResponse if the packet from the network is not found in the records; MQTTIllegalState if the requested update would result in an illegal transition; MQTTSuccess otherwise.
+ +
+
+ +

◆ MQTT_PubrelToResend()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t MQTT_PubrelToResend (const MQTTContext_tpMqttContext,
MQTTStateCursor_tpCursor,
MQTTPublishState_tpState 
)
+
+ +

Get the packet ID of next pending PUBREL ack to be resent.

+

This function will need to be called to get the packet for which a PUBREL need to be sent when a session is reestablished. Calling this function repeatedly until packet id is 0 will give all the packets for which a PUBREL need to be resent in the correct order.

+
Parameters
+ + + + +
[in]pMqttContextInitialized MQTT context.
[in,out]pCursorIndex at which to start searching.
[out]pStateState indicating that PUBREL packet need to be sent.
+
+
+ +
+
+ +

◆ MQTT_PublishToResend()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint16_t MQTT_PublishToResend (const MQTTContext_tpMqttContext,
MQTTStateCursor_tpCursor 
)
+
+ +

Get the packet ID of next pending publish to be resent.

+

This function will need to be called to get the packet for which a publish need to be sent when a session is reestablished. Calling this function repeatedly until packet id is 0 will give all the packets for which a publish need to be resent in the correct order.

+
Parameters
+ + + +
[in]pMqttContextInitialized MQTT context.
[in,out]pCursorIndex at which to start searching.
+
+
+

Example

// For this example assume this function returns an outgoing unacknowledged
+
// QoS 1 or 2 publish from its packet identifier.
+
MQTTPublishInfo_t * getPublish( uint16_t packetID );
+
+
// Variables used in this example.
+
MQTTStatus_t status;
+ +
bool sessionPresent;
+
uint16_t packetID;
+
MQTTPublishInfo_t * pResendPublish = NULL;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
+
// This is assumed to have been initialized before the call to MQTT_Connect().
+
MQTTContext_t * pContext;
+
+
// Set clean session to false to attempt session resumption.
+
connectInfo.cleanSession = false;
+
connectInfo.pClientIdentifier = "someClientID";
+
connectInfo.clientIdentifierLength = strlen( connectInfo.pClientIdentifier );
+
connectInfo.keepAliveSeconds = 60;
+
// Optional connect parameters are not relevant to this example.
+
+
// Create an MQTT connection. Use 100 milliseconds as a timeout.
+
status = MQTT_Connect( pContext, &connectInfo, NULL, 100, &sessionPresent );
+
+
if( status == MQTTSuccess )
+
{
+
if( sessionPresent )
+
{
+
// Loop while packet ID is nonzero.
+
while( ( packetID = MQTT_PublishToResend( pContext, &cursor ) ) != 0 )
+
{
+
// Assume this function will succeed.
+
pResendPublish = getPublish( packetID );
+
// Set DUP flag.
+
pResendPublish->dup = true;
+
status = MQTT_Publish( pContext, pResendPublish, packetID );
+
+
if( status != MQTTSuccess )
+
{
+
// Application can decide how to handle a failure.
+
}
+
}
+
}
+
else
+
{
+
// The broker did not resume a session, so we can clean up the
+
// list of outgoing publishes.
+
}
+
}
+
MQTTStatus_t MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId)
Publishes a message to the given topic name.
Definition: core_mqtt.c:2805
+
MQTTStatus_t MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
Establish an MQTT session.
Definition: core_mqtt.c:2679
+
uint16_t MQTT_PublishToResend(const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor)
Get the packet ID of next pending publish to be resent.
Definition: core_mqtt_state.c:1123
+
size_t MQTTStateCursor_t
Cursor for iterating through state records.
Definition: core_mqtt_state.h:51
+
#define MQTT_STATE_CURSOR_INITIALIZER
Initializer value for an MQTTStateCursor_t, indicating a search should start at the beginning of a st...
Definition: core_mqtt_state.h:45
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
const char * pClientIdentifier
MQTT client identifier. Must be unique per client.
Definition: core_mqtt_serializer.h:147
+
bool cleanSession
Whether to establish a new, clean session or resume a previous session.
Definition: core_mqtt_serializer.h:137
+
uint16_t keepAliveSeconds
MQTT keep alive period.
Definition: core_mqtt_serializer.h:142
+
uint16_t clientIdentifierLength
Length of the client identifier.
Definition: core_mqtt_serializer.h:152
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+
bool dup
Whether this is a duplicate publish message.
Definition: core_mqtt_serializer.h:216
+
+
+
+ +

◆ MQTT_State_strerror()

+ +
+
+ + + + + + + + +
const char * MQTT_State_strerror (MQTTPublishState_t state)
+
+ +

State to string conversion for state engine.

+
Parameters
+ + +
[in]stateThe state to convert to a string.
+
+
+
Returns
The string representation of the state.
+ +
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/core__mqtt__state_8h.html b/v1.3.0/coreMQTT/core__mqtt__state_8h.html new file mode 100644 index 00000000..519bc936 --- /dev/null +++ b/v1.3.0/coreMQTT/core__mqtt__state_8h.html @@ -0,0 +1,250 @@ + + + + + + + +coreMQTT: core_mqtt_state.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_state.h File Reference
+
+
+ +

Function to keep state of MQTT PUBLISH packet deliveries. +More...

+
#include "core_mqtt.h"
+
+

Go to the source code of this file.

+ + + + + +

+Macros

+#define MQTT_STATE_CURSOR_INITIALIZER   ( ( size_t ) 0 )
 Initializer value for an MQTTStateCursor_t, indicating a search should start at the beginning of a state record array.
 
+ + + + +

+Typedefs

+typedef size_t MQTTStateCursor_t
 Cursor for iterating through state records.
 
+ + + + +

+Functions

uint16_t MQTT_PublishToResend (const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor)
 Get the packet ID of next pending publish to be resent.
 
+

Detailed Description

+

Function to keep state of MQTT PUBLISH packet deliveries.

+

Function Documentation

+ +

◆ MQTT_PublishToResend()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint16_t MQTT_PublishToResend (const MQTTContext_tpMqttContext,
MQTTStateCursor_tpCursor 
)
+
+ +

Get the packet ID of next pending publish to be resent.

+

This function will need to be called to get the packet for which a publish need to be sent when a session is reestablished. Calling this function repeatedly until packet id is 0 will give all the packets for which a publish need to be resent in the correct order.

+
Parameters
+ + + +
[in]pMqttContextInitialized MQTT context.
[in,out]pCursorIndex at which to start searching.
+
+
+

Example

// For this example assume this function returns an outgoing unacknowledged
+
// QoS 1 or 2 publish from its packet identifier.
+
MQTTPublishInfo_t * getPublish( uint16_t packetID );
+
+
// Variables used in this example.
+
MQTTStatus_t status;
+ +
bool sessionPresent;
+
uint16_t packetID;
+
MQTTPublishInfo_t * pResendPublish = NULL;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
+
// This is assumed to have been initialized before the call to MQTT_Connect().
+
MQTTContext_t * pContext;
+
+
// Set clean session to false to attempt session resumption.
+
connectInfo.cleanSession = false;
+
connectInfo.pClientIdentifier = "someClientID";
+
connectInfo.clientIdentifierLength = strlen( connectInfo.pClientIdentifier );
+
connectInfo.keepAliveSeconds = 60;
+
// Optional connect parameters are not relevant to this example.
+
+
// Create an MQTT connection. Use 100 milliseconds as a timeout.
+
status = MQTT_Connect( pContext, &connectInfo, NULL, 100, &sessionPresent );
+
+
if( status == MQTTSuccess )
+
{
+
if( sessionPresent )
+
{
+
// Loop while packet ID is nonzero.
+
while( ( packetID = MQTT_PublishToResend( pContext, &cursor ) ) != 0 )
+
{
+
// Assume this function will succeed.
+
pResendPublish = getPublish( packetID );
+
// Set DUP flag.
+
pResendPublish->dup = true;
+
status = MQTT_Publish( pContext, pResendPublish, packetID );
+
+
if( status != MQTTSuccess )
+
{
+
// Application can decide how to handle a failure.
+
}
+
}
+
}
+
else
+
{
+
// The broker did not resume a session, so we can clean up the
+
// list of outgoing publishes.
+
}
+
}
+
MQTTStatus_t MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId)
Publishes a message to the given topic name.
Definition: core_mqtt.c:2805
+
MQTTStatus_t MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
Establish an MQTT session.
Definition: core_mqtt.c:2679
+
uint16_t MQTT_PublishToResend(const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor)
Get the packet ID of next pending publish to be resent.
Definition: core_mqtt_state.c:1123
+
size_t MQTTStateCursor_t
Cursor for iterating through state records.
Definition: core_mqtt_state.h:51
+
#define MQTT_STATE_CURSOR_INITIALIZER
Initializer value for an MQTTStateCursor_t, indicating a search should start at the beginning of a st...
Definition: core_mqtt_state.h:45
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
const char * pClientIdentifier
MQTT client identifier. Must be unique per client.
Definition: core_mqtt_serializer.h:147
+
bool cleanSession
Whether to establish a new, clean session or resume a previous session.
Definition: core_mqtt_serializer.h:137
+
uint16_t keepAliveSeconds
MQTT keep alive period.
Definition: core_mqtt_serializer.h:142
+
uint16_t clientIdentifierLength
Length of the client identifier.
Definition: core_mqtt_serializer.h:152
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+
bool dup
Whether this is a duplicate publish message.
Definition: core_mqtt_serializer.h:216
+
+
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/core__mqtt__state_8h_source.html b/v1.3.0/coreMQTT/core__mqtt__state_8h_source.html new file mode 100644 index 00000000..e6d516bf --- /dev/null +++ b/v1.3.0/coreMQTT/core__mqtt__state_8h_source.html @@ -0,0 +1,209 @@ + + + + + + + +coreMQTT: core_mqtt_state.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
core_mqtt_state.h
+
+
+Go to the documentation of this file.
1/*
+
2 * coreMQTT v2.3.1
+
3 * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
4 *
+
5 * SPDX-License-Identifier: MIT
+
6 *
+
7 * Permission is hereby granted, free of charge, to any person obtaining a copy of
+
8 * this software and associated documentation files (the "Software"), to deal in
+
9 * the Software without restriction, including without limitation the rights to
+
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
11 * the Software, and to permit persons to whom the Software is furnished to do so,
+
12 * subject to the following conditions:
+
13 *
+
14 * The above copyright notice and this permission notice shall be included in all
+
15 * copies or substantial portions of the Software.
+
16 *
+
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
23 */
+
24
+
29#ifndef CORE_MQTT_STATE_H
+
30#define CORE_MQTT_STATE_H
+
31
+
32/* *INDENT-OFF* */
+
33#ifdef __cplusplus
+
34 extern "C" {
+
35#endif
+
36/* *INDENT-ON* */
+
37
+
38#include "core_mqtt.h"
+
39
+
45#define MQTT_STATE_CURSOR_INITIALIZER ( ( size_t ) 0 )
+
46
+
51typedef size_t MQTTStateCursor_t;
+
52
+
59typedef enum MQTTStateOperation
+
60{
+
61 MQTT_SEND,
+
62 MQTT_RECEIVE
+
63} MQTTStateOperation_t;
+
81MQTTStatus_t MQTT_ReserveState( const MQTTContext_t * pMqttContext,
+
82 uint16_t packetId,
+
83 MQTTQoS_t qos );
+
100MQTTPublishState_t MQTT_CalculateStatePublish( MQTTStateOperation_t opType,
+
101 MQTTQoS_t qos );
+ +
123 uint16_t packetId,
+
124 MQTTStateOperation_t opType,
+
125 MQTTQoS_t qos,
+
126 MQTTPublishState_t * pNewState );
+ +
144 uint16_t packetId );
+ +
163 MQTTStateOperation_t opType,
+
164 MQTTQoS_t qos );
+ +
188 uint16_t packetId,
+
189 MQTTPubAckType_t packetType,
+
190 MQTTStateOperation_t opType,
+
191 MQTTPublishState_t * pNewState );
+
212uint16_t MQTT_PubrelToResend( const MQTTContext_t * pMqttContext,
+
213 MQTTStateCursor_t * pCursor,
+
214 MQTTPublishState_t * pState );
+
283/* @[declare_mqtt_publishtoresend] */
+
284uint16_t MQTT_PublishToResend( const MQTTContext_t * pMqttContext,
+
285 MQTTStateCursor_t * pCursor );
+
286/* @[declare_mqtt_publishtoresend] */
+
287
+
301const char * MQTT_State_strerror( MQTTPublishState_t state );
+
304/* *INDENT-OFF* */
+
305#ifdef __cplusplus
+
306 }
+
307#endif
+
308/* *INDENT-ON* */
+
309
+
310#endif /* ifndef CORE_MQTT_STATE_H */
+
User-facing functions of the MQTT 3.1.1 library.
+
MQTTStatus_t MQTT_UpdateStateAck(const MQTTContext_t *pMqttContext, uint16_t packetId, MQTTPubAckType_t packetType, MQTTStateOperation_t opType, MQTTPublishState_t *pNewState)
Update the state record for an ACKed publish.
Definition: core_mqtt_state.c:1005
+
MQTTPublishState_t MQTT_CalculateStateAck(MQTTPubAckType_t packetType, MQTTStateOperation_t opType, MQTTQoS_t qos)
Calculate the state from a PUBACK, PUBREC, PUBREL, or PUBCOMP.
Definition: core_mqtt_state.c:657
+
MQTTStatus_t MQTT_ReserveState(const MQTTContext_t *pMqttContext, uint16_t packetId, MQTTQoS_t qos)
Reserve an entry for an outgoing QoS 1 or Qos 2 publish.
Definition: core_mqtt_state.c:825
+
const char * MQTT_State_strerror(MQTTPublishState_t state)
State to string conversion for state engine.
Definition: core_mqtt_state.c:1153
+
MQTTPublishState_t MQTT_CalculateStatePublish(MQTTStateOperation_t opType, MQTTQoS_t qos)
Calculate the new state for a publish from its qos and operation type.
Definition: core_mqtt_state.c:854
+
MQTTStatus_t MQTT_UpdateStatePublish(const MQTTContext_t *pMqttContext, uint16_t packetId, MQTTStateOperation_t opType, MQTTQoS_t qos, MQTTPublishState_t *pNewState)
Update the state record for a PUBLISH packet.
Definition: core_mqtt_state.c:883
+
uint16_t MQTT_PubrelToResend(const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor, MQTTPublishState_t *pState)
Get the packet ID of next pending PUBREL ack to be resent.
Definition: core_mqtt_state.c:1087
+
MQTTStatus_t MQTT_RemoveStateRecord(const MQTTContext_t *pMqttContext, uint16_t packetId)
Remove the state record for a PUBLISH packet.
Definition: core_mqtt_state.c:957
+
uint16_t MQTT_PublishToResend(const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor)
Get the packet ID of next pending publish to be resent.
Definition: core_mqtt_state.c:1123
+
size_t MQTTStateCursor_t
Cursor for iterating through state records.
Definition: core_mqtt_state.h:51
+
MQTTPublishState_t
The state of QoS 1 or QoS 2 MQTT publishes, used in the state engine.
Definition: core_mqtt.h:119
+
MQTTPubAckType_t
Packet types used in acknowledging QoS 1 or QoS 2 publishes.
Definition: core_mqtt.h:138
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTTQoS_t
MQTT Quality of Service values.
Definition: core_mqtt_serializer.h:109
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/core_mqtt_config.html b/v1.3.0/coreMQTT/core_mqtt_config.html new file mode 100644 index 00000000..9cce5b47 --- /dev/null +++ b/v1.3.0/coreMQTT/core_mqtt_config.html @@ -0,0 +1,176 @@ + + + + + + + +coreMQTT: Configurations + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Configurations
+
+
+

Configurations of the MQTT Library.

+
configpagestyle
+

Some configuration settings are C pre-processor constants, and some are function-like macros for logging. They can be set with a #define in the config file (core_mqtt_config.h) or by using a compiler option such as -D in gcc.

+

+MQTT_DO_NOT_USE_CUSTOM_CONFIG

+

Define this macro to build the MQTT library without the custom config file core_mqtt_config.h.

+

Without the custom config, the MQTT library builds with default values of config macros defined in core_mqtt_config_defaults.h file.

+

If a custom config is provided, then MQTT_DO_NOT_USE_CUSTOM_CONFIG should not be defined.

+

+MQTT_PINGRESP_TIMEOUT_MS

+

Maximum number of milliseconds to wait for a ping response to a ping request as part of the keep-alive mechanism.

+

If a ping response is not received before this timeout, then MQTT_ProcessLoop will return MQTTKeepAliveTimeout.

+
Note
If this value is more than half of the keep alive interval, and the server does not receive the previous ping request, then it is likely that the server will disconnect the client before MQTTKeepAliveTimeout can be returned.
+
+If a dummy implementation of the MQTTGetCurrentTimeFunc_t timer function, is supplied to the library, then the keep-alive mechanism is not supported by the MQTT_ProcessLoop API function. In that case, the value of MQTT_PINGRESP_TIMEOUT_MS is irrelevant to the behavior of the library.
+

Possible values: Any positive integer up to SIZE_MAX.
+ Default value: 5000

+

+MQTT_RECV_POLLING_TIMEOUT_MS

+

The maximum duration between non-empty network reads while receiving an MQTT packet via the MQTT_ProcessLoop or MQTT_ReceiveLoop API functions.

+

When an incoming MQTT packet is detected, the transport receive function may be called multiple times until all of the expected number of bytes of the packet are received. This timeout represents the maximum polling duration that is allowed without any data reception from the network for the incoming packet.

+

If the timeout expires, the MQTT_ProcessLoop and MQTT_ReceiveLoop functions return MQTTRecvFailed.

+
Note
If a dummy implementation of the MQTTGetCurrentTimeFunc_t timer function, is supplied to the library, then MQTT_RECV_POLLING_TIMEOUT_MS MUST be set to 0.
+

Possible values: Any positive 32 bit integer. Recommended to use a small timeout value.
+ Default value: 10

+

+MQTT_SEND_TIMEOUT_MS

+

The maximum duration allowed to send an MQTT packet over the transport interface.

+

When sending an MQTT packet, the transport send or writev functions may be called multiple times until all of the required number of bytes are sent. This timeout represents the maximum duration that is allowed to send the MQTT packet while calling the transport send or writev functions.

+

If the timeout expires, MQTTSendFailed will be returned by the public API functions.

+
Note
If a dummy implementation of the MQTTGetCurrentTimeFunc_t timer function, is supplied to the library, then MQTT_SEND_TIMEOUT_MS MUST be set to 0.
+

Possible values: Any positive 32 bit integer.
+ Default value: 20000

+

+MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT

+

The number of retries for receiving CONNACK.

+

The MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT will be used only when the timeoutMs parameter of MQTT_Connect is passed as 0 . The transport receive for CONNACK will be retried MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT times before timing out. A value of 0 for this config will cause the transport receive for CONNACK to be invoked only once.

+

Possible values: Any positive 16 bit integer.
+ Default value: 5

+

+LogError

+

Macro that is called in the MQTT library for logging "Error" level messages.

+

To enable error level logging in the MQTT library, this macro should be mapped to the application-specific logging implementation that supports error logging.

+
Note
This logging macro is called in the MQTT library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Error logging is turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+

+LogWarn

+

Macro that is called in the MQTT library for logging "Warning" level messages.

+

To enable warning level logging in the MQTT library, this macro should be mapped to the application-specific logging implementation that supports warning logging.

+
Note
This logging macro is called in the MQTT library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Warning logs are turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+

+LogInfo

+

Macro that is called in the MQTT library for logging "Info" level messages.

+

To enable info level logging in the MQTT library, this macro should be mapped to the application-specific logging implementation that supports info logging.

+
Note
This logging macro is called in the MQTT library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Info logging is turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+

+LogDebug

+

Macro that is called in the MQTT library for logging "Debug" level messages.

+

To enable debug level logging from MQTT library, this macro should be mapped to the application-specific logging implementation that supports debug logging.

+
Note
This logging macro is called in the MQTT library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Debug logging is turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/dir_359d2bec989c9a8deeeb9aee335c1c76.html b/v1.3.0/coreMQTT/dir_359d2bec989c9a8deeeb9aee335c1c76.html new file mode 100644 index 00000000..19d14860 --- /dev/null +++ b/v1.3.0/coreMQTT/dir_359d2bec989c9a8deeeb9aee335c1c76.html @@ -0,0 +1,113 @@ + + + + + + + +coreMQTT: doxygen Directory Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
doxygen Directory Reference
+
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/dir_3750548c40d9045ee3b3d006c00db089.html b/v1.3.0/coreMQTT/dir_3750548c40d9045ee3b3d006c00db089.html new file mode 100644 index 00000000..bab2ab67 --- /dev/null +++ b/v1.3.0/coreMQTT/dir_3750548c40d9045ee3b3d006c00db089.html @@ -0,0 +1,120 @@ + + + + + + + +coreMQTT: interface Directory Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
interface Directory Reference
+
+
+ + + + + +

+Files

file  transport_interface.h [code]
 Transport interface definitions to send and receive data over the network.
 
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/dir_49e56c817e5e54854c35e136979f97ca.html b/v1.3.0/coreMQTT/dir_49e56c817e5e54854c35e136979f97ca.html new file mode 100644 index 00000000..8c0639c1 --- /dev/null +++ b/v1.3.0/coreMQTT/dir_49e56c817e5e54854c35e136979f97ca.html @@ -0,0 +1,113 @@ + + + + + + + +coreMQTT: docs Directory Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
docs Directory Reference
+
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/dir_8ee1a5e78eaec319fe5d64075812fc61.html b/v1.3.0/coreMQTT/dir_8ee1a5e78eaec319fe5d64075812fc61.html new file mode 100644 index 00000000..f43d5b5d --- /dev/null +++ b/v1.3.0/coreMQTT/dir_8ee1a5e78eaec319fe5d64075812fc61.html @@ -0,0 +1,129 @@ + + + + + + + +coreMQTT: include Directory Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
include Directory Reference
+
+
+ + + + + + + + + + + + + + +

+Files

file  core_mqtt.h [code]
 User-facing functions of the MQTT 3.1.1 library.
 
file  core_mqtt_config_defaults.h [code]
 This represents the default values for the configuration macros for the MQTT library.
 
file  core_mqtt_serializer.h [code]
 User-facing functions for serializing and deserializing MQTT 3.1.1 packets. This header should be included for building a lighter weight MQTT client than the managed CSDK MQTT library API in core_mqtt.h, by using the serializer and de-serializer functions exposed in this file's API.
 
file  core_mqtt_state.h [code]
 Function to keep state of MQTT PUBLISH packet deliveries.
 
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html b/v1.3.0/coreMQTT/dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html new file mode 100644 index 00000000..97560768 --- /dev/null +++ b/v1.3.0/coreMQTT/dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html @@ -0,0 +1,133 @@ + + + + + + + +coreMQTT: source Directory Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
source Directory Reference
+
+
+ + + + + + +

+Directories

directory  include
 
directory  interface
 
+ + + + + + + + + + +

+Files

file  core_mqtt.c
 Implements the user-facing functions in core_mqtt.h.
 
file  core_mqtt_serializer.c
 Implements the user-facing functions in core_mqtt_serializer.h.
 
file  core_mqtt_state.c
 Implements the functions in core_mqtt_state.h.
 
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/doc.png b/v1.3.0/coreMQTT/doc.png new file mode 100644 index 0000000000000000000000000000000000000000..17edabff95f7b8da13c9516a04efe05493c29501 GIT binary patch literal 746 zcmV7=@pnbNXRFEm&G8P!&WHG=d)>K?YZ1bzou)2{$)) zumDct!>4SyxL;zgaG>wy`^Hv*+}0kUfCrz~BCOViSb$_*&;{TGGn2^x9K*!Sf0=lV zpP=7O;GA0*Jm*tTYj$IoXvimpnV4S1Z5f$p*f$Db2iq2zrVGQUz~yq`ahn7ck(|CE z7Gz;%OP~J6)tEZWDzjhL9h2hdfoU2)Nd%T<5Kt;Y0XLt&<@6pQx!nw*5`@bq#?l*?3z{Hlzoc=Pr>oB5(9i6~_&-}A(4{Q$>c>%rV&E|a(r&;?i5cQB=} zYSDU5nXG)NS4HEs0it2AHe2>shCyr7`6@4*6{r@8fXRbTA?=IFVWAQJL&H5H{)DpM#{W(GL+Idzf^)uRV@oB8u$ z8v{MfJbTiiRg4bza<41NAzrl{=3fl_D+$t+^!xlQ8S}{UtY`e z;;&9UhyZqQRN%2pot{*Ei0*4~hSF_3AH2@fKU!$NSflS>{@tZpDT4`M2WRTTVH+D? z)GFlEGGHe?koB}i|1w45!BF}N_q&^HJ&-tyR{(afC6H7|aml|tBBbv}55C5DNP8p3 z)~jLEO4Z&2hZmP^i-e%(@d!(E|KRafiU8Q5u(wU((j8un3OR*Hvj+t literal 0 HcmV?d00001 diff --git a/v1.3.0/coreMQTT/docd.png b/v1.3.0/coreMQTT/docd.png new file mode 100644 index 0000000000000000000000000000000000000000..d7c94fda9bf08ecc02c7190d968452b7a2dbf04b GIT binary patch literal 756 zcmV1wr-rhpn+wxm%q2)IkAYsr{iGq<}_z5JCD4J;FN?6Qh;@TCubdp(_XdD-^ zG_#)IP7_z6hKNdx5^+FGArwLWTWCG!j+oKji?U!hxA#d-ljgkN`+e^@-P+RWG{Bx= z2iQyYTtEf*o~ySWrIVW}HWHi0_hd4~$E6Jx1U`>Owo}EYJ1O>iZvS?!z8}B}QwLMA zC3Keqf1c}K@?C`X>68b(EUzYUYAS&OH^VPteZLPr{S&|nQvp@6W4GH-1U8!u&7l~A zx~RUSNH+>7@q38W6!BzirtjLFCzc|XGx)EF#G%^pWION*k@?vP<2O>|XkCD3ujl%1 z{55JSVkw{~HbX>iEZ2%yJ2eHj5Yh8OTpzs0A2;tZ^x!#5D+y-es{k1&0|Ns9-|+Xt ziGiTsZ8(^nUo#wdTpIDkb-Zp(3|A*FzW}GZ5SQD-r^R`&X@`26E3W|GyrwDIZjtQ& z$g5f8Sv=VgVtDien@J(!^BK+#l;s-LgP--p7C;7;E!ysXcXK6?+9D>_-B(?Wm(U zQbNm-5TyYxIU=rs0+)!ixqzhuxw(AqKc3?KKX32{D~Qibp*r0x&Wux5-9WCMMRi3U zTd6dOCQlj>a;gr;gLwRKulT&(m@^L{&HkSC(qH05HSSf$YEhynGvH zWNez``Z8FJXE+BSg=%ak{OR z+Nylcb{?evLYLuE1_HngYw0g%LC#=$a@?4~Tx>F9295Q>9UJ|_6v-KMw;!YZSgGj@ zR8fRov=hJ#QvsO@xw*{0%zH@OKVEUrsummary { + list-style-type: none; +} + +details > summary::-webkit-details-marker { + display: none; +} + +details>summary::before { + content: "\25ba"; + padding-right:4px; + font-size: 80%; +} + +details[open]>summary::before { + content: "\25bc"; + padding-right:4px; + font-size: 80%; +} + diff --git a/v1.3.0/coreMQTT/doxygen.svg b/v1.3.0/coreMQTT/doxygen.svg new file mode 100644 index 00000000..d42dad52 --- /dev/null +++ b/v1.3.0/coreMQTT/doxygen.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v1.3.0/coreMQTT/dynsections.js b/v1.3.0/coreMQTT/dynsections.js new file mode 100644 index 00000000..f579fbf3 --- /dev/null +++ b/v1.3.0/coreMQTT/dynsections.js @@ -0,0 +1,123 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); + $('table.directory tr'). + removeClass('odd').filter(':visible:odd').addClass('odd'); +} + +function toggleLevel(level) +{ + $('table.directory tr').each(function() { + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l + + + + + + +coreMQTT: Files + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Files
+
+
+
The following files are associated with this library.
+
[detail level 123]
+ + + + + + + + + + + +
  source
  include
 core_mqtt.hUser-facing functions of the MQTT 3.1.1 library
 core_mqtt_config_defaults.hThis represents the default values for the configuration macros for the MQTT library
 core_mqtt_serializer.hUser-facing functions for serializing and deserializing MQTT 3.1.1 packets. This header should be included for building a lighter weight MQTT client than the managed CSDK MQTT library API in core_mqtt.h, by using the serializer and de-serializer functions exposed in this file's API
 core_mqtt_state.hFunction to keep state of MQTT PUBLISH packet deliveries
  interface
 transport_interface.hTransport interface definitions to send and receive data over the network
 core_mqtt.cImplements the user-facing functions in core_mqtt.h
 core_mqtt_serializer.cImplements the user-facing functions in core_mqtt_serializer.h
 core_mqtt_state.cImplements the functions in core_mqtt_state.h
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/folderclosed.png b/v1.3.0/coreMQTT/folderclosed.png new file mode 100644 index 0000000000000000000000000000000000000000..bb8ab35edce8e97554e360005ee9fc5bffb36e66 GIT binary patch literal 616 zcmV-u0+;=XP)a9#ETzayK)T~Jw&MMH>OIr#&;dC}is*2Mqdf&akCc=O@`qC+4i z5Iu3w#1M@KqXCz8TIZd1wli&kkl2HVcAiZ8PUn5z_kG@-y;?yK06=cA0U%H0PH+kU zl6dp}OR(|r8-RG+YLu`zbI}5TlOU6ToR41{9=uz^?dGTNL;wIMf|V3`d1Wj3y!#6` zBLZ?xpKR~^2x}?~zA(_NUu3IaDB$tKma*XUdOZN~c=dLt_h_k!dbxm_*ibDM zlFX`g{k$X}yIe%$N)cn1LNu=q9_CS)*>A zsX_mM4L@`(cSNQKMFc$RtYbx{79#j-J7hk*>*+ZZhM4Hw?I?rsXCi#mRWJ=-0LGV5a-WR0Qgt<|Nqf)C-@80`5gIz45^_20000IqP)X=#(TiCT&PiIIVc55T}TU}EUh*{q$|`3@{d>{Tc9Bo>e= zfmF3!f>fbI9#GoEHh0f`i5)wkLpva0ztf%HpZneK?w-7AK@b4Itw{y|Zd3k!fH?q2 zlhckHd_V2M_X7+)U&_Xcfvtw60l;--DgZmLSw-Y?S>)zIqMyJ1#FwLU*%bl38ok+! zh78H87n`ZTS;uhzAR$M`zZ`bVhq=+%u9^$5jDplgxd44}9;IRqUH1YHH|@6oFe%z( zo4)_>E$F&^P-f(#)>(TrnbE>Pefs9~@iN=|)Rz|V`sGfHNrJ)0gJb8xx+SBmRf@1l zvuzt=vGfI)<-F9!o&3l?>9~0QbUDT(wFdnQPv%xdD)m*g%!20>Bc9iYmGAp<9YAa( z0QgYgTWqf1qN++Gqp z8@AYPTB3E|6s=WLG?xw0tm|U!o=&zd+H0oRYE;Dbx+Na9s^STqX|Gnq%H8s(nGDGJ j8vwW|`Ts`)fSK|Kx=IK@RG@g200000NkvXXu0mjfauFEA literal 0 HcmV?d00001 diff --git a/v1.3.0/coreMQTT/functions.html b/v1.3.0/coreMQTT/functions.html new file mode 100644 index 00000000..4c910bf5 --- /dev/null +++ b/v1.3.0/coreMQTT/functions.html @@ -0,0 +1,228 @@ + + + + + + + +coreMQTT: Data Fields + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- a -

+ + +

- c -

+ + +

- d -

+ + +

- g -

+ + +

- h -

+ + +

- i -

+ + +

- k -

+ + +

- l -

+ + +

- n -

+ + +

- o -

+ + +

- p -

+ + +

- q -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- u -

+ + +

- w -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/functions_vars.html b/v1.3.0/coreMQTT/functions_vars.html new file mode 100644 index 00000000..a6307fff --- /dev/null +++ b/v1.3.0/coreMQTT/functions_vars.html @@ -0,0 +1,228 @@ + + + + + + + +coreMQTT: Data Fields - Variables + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- a -

+ + +

- c -

+ + +

- d -

+ + +

- g -

+ + +

- h -

+ + +

- i -

+ + +

- k -

+ + +

- l -

+ + +

- n -

+ + +

- o -

+ + +

- p -

+ + +

- q -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- u -

+ + +

- w -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals.html b/v1.3.0/coreMQTT/globals.html new file mode 100644 index 00000000..d6ecd0f5 --- /dev/null +++ b/v1.3.0/coreMQTT/globals.html @@ -0,0 +1,115 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- a -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_c.html b/v1.3.0/coreMQTT/globals_c.html new file mode 100644 index 00000000..a1b333f2 --- /dev/null +++ b/v1.3.0/coreMQTT/globals_c.html @@ -0,0 +1,121 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- c -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_d.html b/v1.3.0/coreMQTT/globals_d.html new file mode 100644 index 00000000..f34ffaeb --- /dev/null +++ b/v1.3.0/coreMQTT/globals_d.html @@ -0,0 +1,120 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- d -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_defs.html b/v1.3.0/coreMQTT/globals_defs.html new file mode 100644 index 00000000..5b40f48e --- /dev/null +++ b/v1.3.0/coreMQTT/globals_defs.html @@ -0,0 +1,197 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- c -

    +
  • CORE_MQTT_SERIALIZED_LENGTH_FIELD_BYTES : core_mqtt.c
  • +
  • CORE_MQTT_SUBSCRIBE_PER_TOPIC_VECTOR_LENGTH : core_mqtt.c
  • +
  • CORE_MQTT_UNSUBSCRIBE_PER_TOPIC_VECTOR_LENGTH : core_mqtt.c
  • +
+ + +

- l -

+ + +

- m -

+ + +

- p -

+ + +

- u -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_e.html b/v1.3.0/coreMQTT/globals_e.html new file mode 100644 index 00000000..bd01185a --- /dev/null +++ b/v1.3.0/coreMQTT/globals_e.html @@ -0,0 +1,115 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- e -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_enum.html b/v1.3.0/coreMQTT/globals_enum.html new file mode 100644 index 00000000..3ba18fb2 --- /dev/null +++ b/v1.3.0/coreMQTT/globals_enum.html @@ -0,0 +1,118 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_eval.html b/v1.3.0/coreMQTT/globals_eval.html new file mode 100644 index 00000000..d0c674bb --- /dev/null +++ b/v1.3.0/coreMQTT/globals_eval.html @@ -0,0 +1,151 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- m -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_f.html b/v1.3.0/coreMQTT/globals_f.html new file mode 100644 index 00000000..93171d95 --- /dev/null +++ b/v1.3.0/coreMQTT/globals_f.html @@ -0,0 +1,114 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- f -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_func.html b/v1.3.0/coreMQTT/globals_func.html new file mode 100644 index 00000000..d2b6e973 --- /dev/null +++ b/v1.3.0/coreMQTT/globals_func.html @@ -0,0 +1,272 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- a -

+ + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- g -

+ + +

- h -

+ + +

- i -

+ + +

- l -

+ + +

- m -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- u -

+ + +

- v -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_g.html b/v1.3.0/coreMQTT/globals_g.html new file mode 100644 index 00000000..d31715bd --- /dev/null +++ b/v1.3.0/coreMQTT/globals_g.html @@ -0,0 +1,116 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- g -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_h.html b/v1.3.0/coreMQTT/globals_h.html new file mode 100644 index 00000000..bbf43219 --- /dev/null +++ b/v1.3.0/coreMQTT/globals_h.html @@ -0,0 +1,118 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- h -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_i.html b/v1.3.0/coreMQTT/globals_i.html new file mode 100644 index 00000000..85c01707 --- /dev/null +++ b/v1.3.0/coreMQTT/globals_i.html @@ -0,0 +1,115 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- i -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_l.html b/v1.3.0/coreMQTT/globals_l.html new file mode 100644 index 00000000..cdba1c92 --- /dev/null +++ b/v1.3.0/coreMQTT/globals_l.html @@ -0,0 +1,118 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- l -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_m.html b/v1.3.0/coreMQTT/globals_m.html new file mode 100644 index 00000000..20ed8c7f --- /dev/null +++ b/v1.3.0/coreMQTT/globals_m.html @@ -0,0 +1,261 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- m -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_n.html b/v1.3.0/coreMQTT/globals_n.html new file mode 100644 index 00000000..6d1be764 --- /dev/null +++ b/v1.3.0/coreMQTT/globals_n.html @@ -0,0 +1,114 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- n -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_p.html b/v1.3.0/coreMQTT/globals_p.html new file mode 100644 index 00000000..f07bde1d --- /dev/null +++ b/v1.3.0/coreMQTT/globals_p.html @@ -0,0 +1,117 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- p -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_r.html b/v1.3.0/coreMQTT/globals_r.html new file mode 100644 index 00000000..ca7245a1 --- /dev/null +++ b/v1.3.0/coreMQTT/globals_r.html @@ -0,0 +1,119 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- r -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_s.html b/v1.3.0/coreMQTT/globals_s.html new file mode 100644 index 00000000..576e3257 --- /dev/null +++ b/v1.3.0/coreMQTT/globals_s.html @@ -0,0 +1,123 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- s -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_t.html b/v1.3.0/coreMQTT/globals_t.html new file mode 100644 index 00000000..7bc746db --- /dev/null +++ b/v1.3.0/coreMQTT/globals_t.html @@ -0,0 +1,116 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- t -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_type.html b/v1.3.0/coreMQTT/globals_type.html new file mode 100644 index 00000000..aac3131c --- /dev/null +++ b/v1.3.0/coreMQTT/globals_type.html @@ -0,0 +1,118 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_u.html b/v1.3.0/coreMQTT/globals_u.html new file mode 100644 index 00000000..02c481d2 --- /dev/null +++ b/v1.3.0/coreMQTT/globals_u.html @@ -0,0 +1,124 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- u -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_v.html b/v1.3.0/coreMQTT/globals_v.html new file mode 100644 index 00000000..4eef4917 --- /dev/null +++ b/v1.3.0/coreMQTT/globals_v.html @@ -0,0 +1,118 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- v -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_vars.html b/v1.3.0/coreMQTT/globals_vars.html new file mode 100644 index 00000000..e10e3e4e --- /dev/null +++ b/v1.3.0/coreMQTT/globals_vars.html @@ -0,0 +1,112 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/globals_z.html b/v1.3.0/coreMQTT/globals_z.html new file mode 100644 index 00000000..3a3a0f92 --- /dev/null +++ b/v1.3.0/coreMQTT/globals_z.html @@ -0,0 +1,114 @@ + + + + + + + +coreMQTT: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- z -

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/group__mqtt__basic__types.html b/v1.3.0/coreMQTT/group__mqtt__basic__types.html new file mode 100644 index 00000000..978e8a77 --- /dev/null +++ b/v1.3.0/coreMQTT/group__mqtt__basic__types.html @@ -0,0 +1,127 @@ + + + + + + + +coreMQTT: Basic Types + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
Basic Types
+
+
+ +

Primitive types of the MQTT library. +More...

+ + + + + +

+Typedefs

+typedef size_t MQTTStateCursor_t
 Cursor for iterating through state records.
 
+

Detailed Description

+

Primitive types of the MQTT library.

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/group__mqtt__basic__types.js b/v1.3.0/coreMQTT/group__mqtt__basic__types.js new file mode 100644 index 00000000..c0e30048 --- /dev/null +++ b/v1.3.0/coreMQTT/group__mqtt__basic__types.js @@ -0,0 +1,4 @@ +var group__mqtt__basic__types = +[ + [ "MQTTStateCursor_t", "group__mqtt__basic__types.html#ga2ca7d486d83fe555953a8c7876ee0d6e", null ] +]; \ No newline at end of file diff --git a/v1.3.0/coreMQTT/group__mqtt__callback__types.html b/v1.3.0/coreMQTT/group__mqtt__callback__types.html new file mode 100644 index 00000000..f62787f4 --- /dev/null +++ b/v1.3.0/coreMQTT/group__mqtt__callback__types.html @@ -0,0 +1,264 @@ + + + + + + + +coreMQTT: Callback Types + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
Callback Types
+
+
+ +

Callback function pointer types of the MQTT library. +More...

+ + + + + + + + + + + + + + + + + +

+Typedefs

typedef uint32_t(* MQTTGetCurrentTimeFunc_t) (void)
 Application provided function to query the time elapsed since a given epoch in milliseconds.
 
typedef void(* MQTTEventCallback_t) (struct MQTTContext *pContext, struct MQTTPacketInfo *pPacketInfo, struct MQTTDeserializedInfo *pDeserializedInfo)
 Application callback for receiving incoming publishes and incoming acks.
 
typedef int32_t(* TransportRecv_t) (NetworkContext_t *pNetworkContext, void *pBuffer, size_t bytesToRecv)
 Transport interface for receiving data on the network.
 
typedef int32_t(* TransportSend_t) (NetworkContext_t *pNetworkContext, const void *pBuffer, size_t bytesToSend)
 Transport interface for sending data over the network.
 
typedef int32_t(* TransportWritev_t) (NetworkContext_t *pNetworkContext, TransportOutVector_t *pIoVec, size_t ioVecCount)
 Transport interface function for "vectored" / scatter-gather based writes. This function is expected to iterate over the list of vectors pIoVec having ioVecCount entries containing portions of one MQTT message at a maximum. If the proper functionality is available, then the data in the list should be copied to the underlying TCP buffer before flushing the buffer. Implementing it in this fashion will lead to sending of fewer TCP packets for all the values in the list.
 
+

Detailed Description

+

Callback function pointer types of the MQTT library.

+

Typedef Documentation

+ +

◆ MQTTGetCurrentTimeFunc_t

+ +
+
+ + + + +
typedef uint32_t(* MQTTGetCurrentTimeFunc_t) (void)
+
+ +

Application provided function to query the time elapsed since a given epoch in milliseconds.

+
Note
The timer should be a monotonic timer. It just needs to provide an incrementing count of milliseconds elapsed since a given epoch.
+
+As the timer is supposed to be a millisecond timer returning a 32-bit value, it will overflow in just under 50 days. But it will not cause any issues in the library as the time function is only used for calculating durations for timeouts and keep alive periods. The difference in unsigned numbers is used where unsigned wrap around is defined. Unless the timeout is bigger than 100 days (50*2) where the numbers can wrap around more than once the code should work properly.
+
Returns
The time elapsed in milliseconds.
+ +
+
+ +

◆ MQTTEventCallback_t

+ +
+
+ + + + +
typedef void(* MQTTEventCallback_t) (struct MQTTContext *pContext, struct MQTTPacketInfo *pPacketInfo, struct MQTTDeserializedInfo *pDeserializedInfo)
+
+ +

Application callback for receiving incoming publishes and incoming acks.

+
Note
This callback will be called only if packets are deserialized with a result of MQTTSuccess or MQTTServerRefused. The latter can be obtained when deserializing a SUBACK, indicating a broker's rejection of a subscribe.
+
Parameters
+ + + + +
[in]pContextInitialized MQTT context.
[in]pPacketInfoInformation on the type of incoming MQTT packet.
[in]pDeserializedInfoDeserialized information from incoming packet.
+
+
+ +
+
+ +

◆ TransportRecv_t

+ +
+
+ + + + +
typedef int32_t(* TransportRecv_t) (NetworkContext_t *pNetworkContext, void *pBuffer, size_t bytesToRecv)
+
+ +

Transport interface for receiving data on the network.

+
Note
It is HIGHLY RECOMMENDED that the transport receive implementation does NOT block. coreMQTT will continue to call the transport interface if it receives a partial packet until it accumulates enough data to get the complete MQTT packet.
+
Parameters
+ + + + +
[in]pNetworkContextImplementation-defined network context.
[in]pBufferBuffer to receive the data into.
[in]bytesToRecvNumber of bytes requested from the network.
+
+
+
Returns
The number of bytes received or a negative value to indicate error.
+
Note
If no data is available on the network to read and no error has occurred, zero MUST be the return value. A zero return value SHOULD represent that the read operation can be retried by calling the API function. Zero MUST NOT be returned if a network disconnection has occurred.
+ +
+
+ +

◆ TransportSend_t

+ +
+
+ + + + +
typedef int32_t(* TransportSend_t) (NetworkContext_t *pNetworkContext, const void *pBuffer, size_t bytesToSend)
+
+ +

Transport interface for sending data over the network.

+
Parameters
+ + + + +
[in]pNetworkContextImplementation-defined network context.
[in]pBufferBuffer containing the bytes to send over the network stack.
[in]bytesToSendNumber of bytes to send over the network.
+
+
+
Returns
The number of bytes sent or a negative value to indicate error.
+
Note
If no data is transmitted over the network due to a full TX buffer and no network error has occurred, this MUST return zero as the return value. A zero return value SHOULD represent that the send operation can be retried by calling the API function. Zero MUST NOT be returned if a network disconnection has occurred.
+ +
+
+ +

◆ TransportWritev_t

+ +
+
+ + + + +
typedef int32_t(* TransportWritev_t) (NetworkContext_t *pNetworkContext, TransportOutVector_t *pIoVec, size_t ioVecCount)
+
+ +

Transport interface function for "vectored" / scatter-gather based writes. This function is expected to iterate over the list of vectors pIoVec having ioVecCount entries containing portions of one MQTT message at a maximum. If the proper functionality is available, then the data in the list should be copied to the underlying TCP buffer before flushing the buffer. Implementing it in this fashion will lead to sending of fewer TCP packets for all the values in the list.

+
Note
If the proper write functionality is not present for a given device/IP-stack, then there is no strict requirement to implement write. Only the send and recv interfaces must be defined for the application to work properly.
+
Parameters
+ + + + +
[in]pNetworkContextImplementation-defined network context.
[in]pIoVecAn array of TransportIoVector_t structs.
[in]ioVecCountNumber of TransportIoVector_t in pIoVec.
+
+
+
Returns
The number of bytes written or a negative value to indicate error.
+
Note
If no data is written to the buffer due to the buffer being full this MUST return zero as the return value. A zero return value SHOULD represent that the write operation can be retried by calling the API function. Zero MUST NOT be returned if a network disconnection has occurred.
+ +
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/group__mqtt__callback__types.js b/v1.3.0/coreMQTT/group__mqtt__callback__types.js new file mode 100644 index 00000000..fed9ffb6 --- /dev/null +++ b/v1.3.0/coreMQTT/group__mqtt__callback__types.js @@ -0,0 +1,8 @@ +var group__mqtt__callback__types = +[ + [ "MQTTGetCurrentTimeFunc_t", "group__mqtt__callback__types.html#gae3bea55b0e49e5208b8c5709a5ea23aa", null ], + [ "MQTTEventCallback_t", "group__mqtt__callback__types.html#ga00d348277ed4fde23c95bfc749ae954a", null ], + [ "TransportRecv_t", "group__mqtt__callback__types.html#ga227df31d6daf07e5d833537c12130167", null ], + [ "TransportSend_t", "group__mqtt__callback__types.html#ga2a39853ff952edd715ab07b33ab2a7c5", null ], + [ "TransportWritev_t", "group__mqtt__callback__types.html#ga47e779557b0c2db95949ef9526861dfb", null ] +]; \ No newline at end of file diff --git a/v1.3.0/coreMQTT/group__mqtt__constants.html b/v1.3.0/coreMQTT/group__mqtt__constants.html new file mode 100644 index 00000000..95c6fc72 --- /dev/null +++ b/v1.3.0/coreMQTT/group__mqtt__constants.html @@ -0,0 +1,212 @@ + + + + + + + +coreMQTT: Constants + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
Constants
+
+
+ +

Constants defined in the MQTT library. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Macros

#define MQTT_PACKET_ID_INVALID   ( ( uint16_t ) 0U )
 Invalid packet identifier.
 
+#define MQTT_SUB_UNSUB_MAX_VECTORS   ( 4U )
 Maximum number of vectors in subscribe and unsubscribe packet.
 
+#define MQTT_PACKET_TYPE_CONNECT   ( ( uint8_t ) 0x10U )
 CONNECT (client-to-server).
 
+#define MQTT_PACKET_TYPE_CONNACK   ( ( uint8_t ) 0x20U )
 CONNACK (server-to-client).
 
+#define MQTT_PACKET_TYPE_PUBLISH   ( ( uint8_t ) 0x30U )
 PUBLISH (bidirectional).
 
+#define MQTT_PACKET_TYPE_PUBACK   ( ( uint8_t ) 0x40U )
 PUBACK (bidirectional).
 
+#define MQTT_PACKET_TYPE_PUBREC   ( ( uint8_t ) 0x50U )
 PUBREC (bidirectional).
 
+#define MQTT_PACKET_TYPE_PUBREL   ( ( uint8_t ) 0x62U )
 PUBREL (bidirectional).
 
+#define MQTT_PACKET_TYPE_PUBCOMP   ( ( uint8_t ) 0x70U )
 PUBCOMP (bidirectional).
 
+#define MQTT_PACKET_TYPE_SUBSCRIBE   ( ( uint8_t ) 0x82U )
 SUBSCRIBE (client-to-server).
 
+#define MQTT_PACKET_TYPE_SUBACK   ( ( uint8_t ) 0x90U )
 SUBACK (server-to-client).
 
+#define MQTT_PACKET_TYPE_UNSUBSCRIBE   ( ( uint8_t ) 0xA2U )
 UNSUBSCRIBE (client-to-server).
 
+#define MQTT_PACKET_TYPE_UNSUBACK   ( ( uint8_t ) 0xB0U )
 UNSUBACK (server-to-client).
 
+#define MQTT_PACKET_TYPE_PINGREQ   ( ( uint8_t ) 0xC0U )
 PINGREQ (client-to-server).
 
+#define MQTT_PACKET_TYPE_PINGRESP   ( ( uint8_t ) 0xD0U )
 PINGRESP (server-to-client).
 
+#define MQTT_PACKET_TYPE_DISCONNECT   ( ( uint8_t ) 0xE0U )
 DISCONNECT (client-to-server).
 
+#define MQTT_PUBLISH_ACK_PACKET_SIZE   ( 4UL )
 The size of MQTT PUBACK, PUBREC, PUBREL, and PUBCOMP packets, per MQTT spec.
 
+#define MQTT_STATE_CURSOR_INITIALIZER   ( ( size_t ) 0 )
 Initializer value for an MQTTStateCursor_t, indicating a search should start at the beginning of a state record array.
 
+

Detailed Description

+

Constants defined in the MQTT library.

+

Macro Definition Documentation

+ +

◆ MQTT_PACKET_ID_INVALID

+ +
+
+ + + + +
#define MQTT_PACKET_ID_INVALID   ( ( uint16_t ) 0U )
+
+ +

Invalid packet identifier.

+

Zero is an invalid packet identifier as per MQTT v3.1.1 spec.

+ +
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/group__mqtt__constants.js b/v1.3.0/coreMQTT/group__mqtt__constants.js new file mode 100644 index 00000000..57529cab --- /dev/null +++ b/v1.3.0/coreMQTT/group__mqtt__constants.js @@ -0,0 +1,21 @@ +var group__mqtt__constants = +[ + [ "MQTT_PACKET_ID_INVALID", "group__mqtt__constants.html#ga9fde6503edb9eaad50ecd3392ab9992a", null ], + [ "MQTT_SUB_UNSUB_MAX_VECTORS", "group__mqtt__constants.html#ga928ea0bff12ebf9cf9fa9dfe5cafebbb", null ], + [ "MQTT_PACKET_TYPE_CONNECT", "group__mqtt__constants.html#ga64a0515bda2ecc89e97595535e1cf0ef", null ], + [ "MQTT_PACKET_TYPE_CONNACK", "group__mqtt__constants.html#gab14f6c39c303eac1a76816edfde7feab", null ], + [ "MQTT_PACKET_TYPE_PUBLISH", "group__mqtt__constants.html#ga5b2d79c61f2591c8e5772f974826d4ad", null ], + [ "MQTT_PACKET_TYPE_PUBACK", "group__mqtt__constants.html#ga5f279d63de47a973b41b95f74f47a4f6", null ], + [ "MQTT_PACKET_TYPE_PUBREC", "group__mqtt__constants.html#gafa2d8f28da39560f152076b99610e6a3", null ], + [ "MQTT_PACKET_TYPE_PUBREL", "group__mqtt__constants.html#gaeaa2ceecffda50e2d22ccecf046083c6", null ], + [ "MQTT_PACKET_TYPE_PUBCOMP", "group__mqtt__constants.html#ga478ecbc98d2ca83d4ce7db33622b5c3b", null ], + [ "MQTT_PACKET_TYPE_SUBSCRIBE", "group__mqtt__constants.html#ga80cfef333e60d967ca927b2e5e665f18", null ], + [ "MQTT_PACKET_TYPE_SUBACK", "group__mqtt__constants.html#ga307e0186aa17fdd0d6d181d3d2715766", null ], + [ "MQTT_PACKET_TYPE_UNSUBSCRIBE", "group__mqtt__constants.html#ga4a94c954cfcea31c8fc3e2adf092b228", null ], + [ "MQTT_PACKET_TYPE_UNSUBACK", "group__mqtt__constants.html#ga38bc8ed0b9a1581cf85cecdede7d1a64", null ], + [ "MQTT_PACKET_TYPE_PINGREQ", "group__mqtt__constants.html#gacbe28c7d081275d1805c2142ff792185", null ], + [ "MQTT_PACKET_TYPE_PINGRESP", "group__mqtt__constants.html#ga285fc02048e2482794042fa98639e514", null ], + [ "MQTT_PACKET_TYPE_DISCONNECT", "group__mqtt__constants.html#gaed07155a3d6fa4b7624b9f36ed33ec6d", null ], + [ "MQTT_PUBLISH_ACK_PACKET_SIZE", "group__mqtt__constants.html#ga26994fcfacb1cff892caa45ec31ca7c6", null ], + [ "MQTT_STATE_CURSOR_INITIALIZER", "group__mqtt__constants.html#ga666ad78e7eaaffa51f5cab96201a9476", null ] +]; \ No newline at end of file diff --git a/v1.3.0/coreMQTT/group__mqtt__enum__types.html b/v1.3.0/coreMQTT/group__mqtt__enum__types.html new file mode 100644 index 00000000..4df26dcb --- /dev/null +++ b/v1.3.0/coreMQTT/group__mqtt__enum__types.html @@ -0,0 +1,366 @@ + + + + + + + +coreMQTT: Enumerated Types + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
Enumerated Types
+
+
+ +

Enumerated types of the MQTT library. +More...

+ + + + + + + + + + + + + + + + + + + + +

+Enumerations

enum  MQTTConnectionStatus_t { MQTTNotConnected +, MQTTConnected + }
 Values indicating if an MQTT connection exists. More...
 
enum  MQTTPublishState_t {
+  MQTTStateNull = 0 +, MQTTPublishSend +, MQTTPubAckSend +, MQTTPubRecSend +,
+  MQTTPubRelSend +, MQTTPubCompSend +, MQTTPubAckPending +, MQTTPubRecPending +,
+  MQTTPubRelPending +, MQTTPubCompPending +, MQTTPublishDone +
+ }
 The state of QoS 1 or QoS 2 MQTT publishes, used in the state engine. More...
 
enum  MQTTPubAckType_t { MQTTPuback +, MQTTPubrec +, MQTTPubrel +, MQTTPubcomp + }
 Packet types used in acknowledging QoS 1 or QoS 2 publishes. More...
 
enum  MQTTSubAckStatus_t { MQTTSubAckSuccessQos0 = 0x00 +, MQTTSubAckSuccessQos1 = 0x01 +, MQTTSubAckSuccessQos2 = 0x02 +, MQTTSubAckFailure = 0x80 + }
 The status codes in the SUBACK response to a subscription request. More...
 
enum  MQTTStatus_t {
+  MQTTSuccess = 0 +, MQTTBadParameter +, MQTTNoMemory +, MQTTSendFailed +,
+  MQTTRecvFailed +, MQTTBadResponse +, MQTTServerRefused +, MQTTNoDataAvailable +,
+  MQTTIllegalState +, MQTTStateCollision +, MQTTKeepAliveTimeout +, MQTTNeedMoreBytes +
+ }
 Return codes from MQTT functions. More...
 
enum  MQTTQoS_t { MQTTQoS0 = 0 +, MQTTQoS1 = 1 +, MQTTQoS2 = 2 + }
 MQTT Quality of Service values. More...
 
+

Detailed Description

+

Enumerated types of the MQTT library.

+

Enumeration Type Documentation

+ +

◆ MQTTConnectionStatus_t

+ +
+
+ + + + +
enum MQTTConnectionStatus_t
+
+ +

Values indicating if an MQTT connection exists.

+ + + +
Enumerator
MQTTNotConnected 

MQTT Connection is inactive.

+
MQTTConnected 

MQTT Connection is active.

+
+ +
+
+ +

◆ MQTTPublishState_t

+ +
+
+ + + + +
enum MQTTPublishState_t
+
+ +

The state of QoS 1 or QoS 2 MQTT publishes, used in the state engine.

+ + + + + + + + + + + + +
Enumerator
MQTTStateNull 

An empty state with no corresponding PUBLISH.

+
MQTTPublishSend 

The library will send an outgoing PUBLISH packet.

+
MQTTPubAckSend 

The library will send a PUBACK for a received PUBLISH.

+
MQTTPubRecSend 

The library will send a PUBREC for a received PUBLISH.

+
MQTTPubRelSend 

The library will send a PUBREL for a received PUBREC.

+
MQTTPubCompSend 

The library will send a PUBCOMP for a received PUBREL.

+
MQTTPubAckPending 

The library is awaiting a PUBACK for an outgoing PUBLISH.

+
MQTTPubRecPending 

The library is awaiting a PUBREC for an outgoing PUBLISH.

+
MQTTPubRelPending 

The library is awaiting a PUBREL for an incoming PUBLISH.

+
MQTTPubCompPending 

The library is awaiting a PUBCOMP for an outgoing PUBLISH.

+
MQTTPublishDone 

The PUBLISH has been completed.

+
+ +
+
+ +

◆ MQTTPubAckType_t

+ +
+
+ + + + +
enum MQTTPubAckType_t
+
+ +

Packet types used in acknowledging QoS 1 or QoS 2 publishes.

+ + + + + +
Enumerator
MQTTPuback 

PUBACKs are sent in response to a QoS 1 PUBLISH.

+
MQTTPubrec 

PUBRECs are sent in response to a QoS 2 PUBLISH.

+
MQTTPubrel 

PUBRELs are sent in response to a PUBREC.

+
MQTTPubcomp 

PUBCOMPs are sent in response to a PUBREL.

+
+ +
+
+ +

◆ MQTTSubAckStatus_t

+ +
+
+ + + + +
enum MQTTSubAckStatus_t
+
+ +

The status codes in the SUBACK response to a subscription request.

+ + + + + +
Enumerator
MQTTSubAckSuccessQos0 

Success with a maximum delivery at QoS 0.

+
MQTTSubAckSuccessQos1 

Success with a maximum delivery at QoS 1.

+
MQTTSubAckSuccessQos2 

Success with a maximum delivery at QoS 2.

+
MQTTSubAckFailure 

Failure.

+
+ +
+
+ +

◆ MQTTStatus_t

+ +
+
+ + + + +
enum MQTTStatus_t
+
+ +

Return codes from MQTT functions.

+ + + + + + + + + + + + + +
Enumerator
MQTTSuccess 

Function completed successfully.

+
MQTTBadParameter 

At least one parameter was invalid.

+
MQTTNoMemory 

A provided buffer was too small.

+
MQTTSendFailed 

The transport send function failed.

+
MQTTRecvFailed 

The transport receive function failed.

+
MQTTBadResponse 

An invalid packet was received from the server.

+
MQTTServerRefused 

The server refused a CONNECT or SUBSCRIBE.

+
MQTTNoDataAvailable 

No data available from the transport interface.

+
MQTTIllegalState 

An illegal state in the state record.

+
MQTTStateCollision 

A collision with an existing state record entry.

+
MQTTKeepAliveTimeout 

Timeout while waiting for PINGRESP.

+
MQTTNeedMoreBytes 

MQTT_ProcessLoop/MQTT_ReceiveLoop has received incomplete data; it should be called again (probably after a delay).

+
+ +
+
+ +

◆ MQTTQoS_t

+ +
+
+ + + + +
enum MQTTQoS_t
+
+ +

MQTT Quality of Service values.

+ + + + +
Enumerator
MQTTQoS0 

Delivery at most once.

+
MQTTQoS1 

Delivery at least once.

+
MQTTQoS2 

Delivery exactly once.

+
+ +
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/group__mqtt__enum__types.js b/v1.3.0/coreMQTT/group__mqtt__enum__types.js new file mode 100644 index 00000000..c6948c66 --- /dev/null +++ b/v1.3.0/coreMQTT/group__mqtt__enum__types.js @@ -0,0 +1,51 @@ +var group__mqtt__enum__types = +[ + [ "MQTTConnectionStatus_t", "group__mqtt__enum__types.html#ga9f84d003695205cf10a7bd0bafb3dbf6", [ + [ "MQTTNotConnected", "group__mqtt__enum__types.html#gga9f84d003695205cf10a7bd0bafb3dbf6a0320177ebf1f1b2e24646b44702cec69", null ], + [ "MQTTConnected", "group__mqtt__enum__types.html#gga9f84d003695205cf10a7bd0bafb3dbf6a82c8f64d976734e5632e5257bc429ef5", null ] + ] ], + [ "MQTTPublishState_t", "group__mqtt__enum__types.html#ga0480de7552eedd739a26a23fa8e6fd94", [ + [ "MQTTStateNull", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a8349567b7a9efb3913a64a8f4f6fe5c9", null ], + [ "MQTTPublishSend", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a896b1507647b504c9208580e4cde26ad", null ], + [ "MQTTPubAckSend", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a65f6f7b343a30fc0558e3aeeb8c97f35", null ], + [ "MQTTPubRecSend", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a11e2319a2b25b82121471743d39761e1", null ], + [ "MQTTPubRelSend", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a5d2ee2709c6dc7a1eb8b9c40f318909b", null ], + [ "MQTTPubCompSend", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a7d88904d550b502b4424a41aa4205e56", null ], + [ "MQTTPubAckPending", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94ab086c55acf106cdc8d420f90899b6803", null ], + [ "MQTTPubRecPending", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a1bea59454700be9b683b7eb8aaf6bb4f", null ], + [ "MQTTPubRelPending", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a695431cde1dc9dc5a2dcbd10eba49df2", null ], + [ "MQTTPubCompPending", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a3281a28d1829d954b596f091b547b627", null ], + [ "MQTTPublishDone", "group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94ad07733793a235ef9a6a04d16637cd7dc", null ] + ] ], + [ "MQTTPubAckType_t", "group__mqtt__enum__types.html#ga8c1bee959b3ed5fab2a2688dd72bf237", [ + [ "MQTTPuback", "group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a53d5939c680962f37c15ee87ffd63d0f", null ], + [ "MQTTPubrec", "group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a8c98d5d1a68dda33d9039009ab4ef053", null ], + [ "MQTTPubrel", "group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237af2d737088a231c88e7603acfdbc4fc8c", null ], + [ "MQTTPubcomp", "group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a910c34311ad6a2341afc04839e1c13bd", null ] + ] ], + [ "MQTTSubAckStatus_t", "group__mqtt__enum__types.html#ga48dabc1579e3c0ac6058ce9068054611", [ + [ "MQTTSubAckSuccessQos0", "group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611abcc3040d7d53025baee3542c40758abb", null ], + [ "MQTTSubAckSuccessQos1", "group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611ab180361a6da712c8144d8c499537787d", null ], + [ "MQTTSubAckSuccessQos2", "group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611a877b2afbc6ec7d9ab57d4862caadf4f1", null ], + [ "MQTTSubAckFailure", "group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611aeb83b20da8eda934cde6b92db225a808", null ] + ] ], + [ "MQTTStatus_t", "group__mqtt__enum__types.html#gaba7ec045874a1c3432f99173367f735c", [ + [ "MQTTSuccess", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca484e062cb4f3fccc1858dd25cfeee056", null ], + [ "MQTTBadParameter", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa39030c93b0263b2699502a074f003b5", null ], + [ "MQTTNoMemory", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735cab1be4db832a0468f024243bca151a8df", null ], + [ "MQTTSendFailed", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735cafd06b63fe9677fa2af06b0f4c7d4ad55", null ], + [ "MQTTRecvFailed", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa14bc8aa4ad218702d782366945d43ac", null ], + [ "MQTTBadResponse", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa5d7507e7664a14d63a8bc44b280093e", null ], + [ "MQTTServerRefused", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca25a3d1747e308e99daa805fe576f84b9", null ], + [ "MQTTNoDataAvailable", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca676f21c0ddf297ae3ec874bc829aa957", null ], + [ "MQTTIllegalState", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca67905d7a05f98faa557a73eb5092bd8f", null ], + [ "MQTTStateCollision", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca8d05b92240dea6df08eab5a9e3799c11", null ], + [ "MQTTKeepAliveTimeout", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca076ca8965e836a06e707a94adb26144f", null ], + [ "MQTTNeedMoreBytes", "group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa97df53014d919df5ecd54398f89f9b9", null ] + ] ], + [ "MQTTQoS_t", "group__mqtt__enum__types.html#gae308a5928d7f537379c29a894228093a", [ + [ "MQTTQoS0", "group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aaad51b23a1ae1417f96d8f343c788d1d2", null ], + [ "MQTTQoS1", "group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aa019d0b8a8cfadb6f98462b046bdacbb2", null ], + [ "MQTTQoS2", "group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aa85e04ac0465cbdef6dd69ff71b2bbfbb", null ] + ] ] +]; \ No newline at end of file diff --git a/v1.3.0/coreMQTT/group__mqtt__struct__types.html b/v1.3.0/coreMQTT/group__mqtt__struct__types.html new file mode 100644 index 00000000..3976a95d --- /dev/null +++ b/v1.3.0/coreMQTT/group__mqtt__struct__types.html @@ -0,0 +1,159 @@ + + + + + + + +coreMQTT: Parameter Structures + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
Parameter Structures
+
+
+ +

Structures passed as parameters to MQTT library functions. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Structures

struct  MQTTPubAckInfo_t
 An element of the state engine records for QoS 1 or Qos 2 publishes. More...
 
struct  MQTTContext_t
 A struct representing an MQTT connection. More...
 
struct  MQTTDeserializedInfo_t
 Struct to hold deserialized packet information for an MQTTEventCallback_t callback. More...
 
struct  MQTTFixedBuffer_t
 Buffer passed to MQTT library. More...
 
struct  MQTTConnectInfo_t
 MQTT CONNECT packet parameters. More...
 
struct  MQTTSubscribeInfo_t
 MQTT SUBSCRIBE packet parameters. More...
 
struct  MQTTPublishInfo_t
 MQTT PUBLISH packet parameters. More...
 
struct  MQTTPacketInfo_t
 MQTT incoming packet parameters. More...
 
struct  TransportInterface_t
 The transport layer interface. More...
 
+ + + + +

+Typedefs

+typedef struct NetworkContext NetworkContext_t
 The NetworkContext is an incomplete type. An implementation of this interface must define struct NetworkContext for the system requirements. This context is passed into the network interface functions.
 
+

Detailed Description

+

Structures passed as parameters to MQTT library functions.

+

These structures are passed as parameters to library functions. Documentation for these structures will state the functions associated with each parameter structure and the purpose of each member.

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/group__mqtt__struct__types.js b/v1.3.0/coreMQTT/group__mqtt__struct__types.js new file mode 100644 index 00000000..62fc0825 --- /dev/null +++ b/v1.3.0/coreMQTT/group__mqtt__struct__types.js @@ -0,0 +1,73 @@ +var group__mqtt__struct__types = +[ + [ "MQTTPubAckInfo_t", "struct_m_q_t_t_pub_ack_info__t.html", [ + [ "packetId", "struct_m_q_t_t_pub_ack_info__t.html#a66cef7b43af5d7fdd33b5d2dc766b2d0", null ], + [ "qos", "struct_m_q_t_t_pub_ack_info__t.html#a086fcd48ef0b787697526a95c861e8a0", null ], + [ "publishState", "struct_m_q_t_t_pub_ack_info__t.html#a61314203ef87a231c6489c68b579de34", null ] + ] ], + [ "MQTTContext_t", "struct_m_q_t_t_context__t.html", [ + [ "outgoingPublishRecords", "struct_m_q_t_t_context__t.html#a4ea1e37e0e81f010fbf84365ac2ef6de", null ], + [ "incomingPublishRecords", "struct_m_q_t_t_context__t.html#afc147663a5933de81212fa77057f0a4d", null ], + [ "outgoingPublishRecordMaxCount", "struct_m_q_t_t_context__t.html#a2851073e252d1e744596272ef13dd14a", null ], + [ "incomingPublishRecordMaxCount", "struct_m_q_t_t_context__t.html#aa33ed2e10380a854629f1386d0323ea8", null ], + [ "transportInterface", "struct_m_q_t_t_context__t.html#a87ab9d61e7711325c2c85ce3ce63386a", null ], + [ "networkBuffer", "struct_m_q_t_t_context__t.html#a231c5576a6ce389317a3f00f95628276", null ], + [ "nextPacketId", "struct_m_q_t_t_context__t.html#af47ed55ad7e9bb112324f5f209b70534", null ], + [ "connectStatus", "struct_m_q_t_t_context__t.html#a4e38c4dc77e7751a0ad8730a41bee47f", null ], + [ "getTime", "struct_m_q_t_t_context__t.html#aabe1d302a16771292151013e8e30c582", null ], + [ "appCallback", "struct_m_q_t_t_context__t.html#a73bd9259db9c3a9b84518cbf928ed91f", null ], + [ "lastPacketTxTime", "struct_m_q_t_t_context__t.html#a01acf90953e830ba3e7f44182cb1d482", null ], + [ "lastPacketRxTime", "struct_m_q_t_t_context__t.html#a7111ef16e4a4e75a72861f6f3ea8a7c3", null ], + [ "controlPacketSent", "struct_m_q_t_t_context__t.html#af9724f2426132e3ce96a03892902ef89", null ], + [ "index", "struct_m_q_t_t_context__t.html#a41b7735cd0746563483b72e17cf103aa", null ], + [ "keepAliveIntervalSec", "struct_m_q_t_t_context__t.html#afd6071827ef48b230212a5725c2075be", null ], + [ "pingReqSendTimeMs", "struct_m_q_t_t_context__t.html#acca3efa4146d85f7e874c7c326e23556", null ], + [ "waitingForPingResp", "struct_m_q_t_t_context__t.html#ac7073f43645f7b7c0c5b7763980004bb", null ] + ] ], + [ "MQTTDeserializedInfo_t", "struct_m_q_t_t_deserialized_info__t.html", [ + [ "packetIdentifier", "struct_m_q_t_t_deserialized_info__t.html#af4df2a9926a4a68059195daa712d9b84", null ], + [ "pPublishInfo", "struct_m_q_t_t_deserialized_info__t.html#ac347273fae1e92b9cbeda1714066c1de", null ], + [ "deserializationResult", "struct_m_q_t_t_deserialized_info__t.html#a7df1b7b60404c9f1604fec0081d2625d", null ] + ] ], + [ "MQTTFixedBuffer_t", "struct_m_q_t_t_fixed_buffer__t.html", [ + [ "pBuffer", "struct_m_q_t_t_fixed_buffer__t.html#acea147448e044870fb36b7fa2347dbd6", null ], + [ "size", "struct_m_q_t_t_fixed_buffer__t.html#a0b0b6a93cc62751ebeb03095d5431636", null ] + ] ], + [ "MQTTConnectInfo_t", "struct_m_q_t_t_connect_info__t.html", [ + [ "cleanSession", "struct_m_q_t_t_connect_info__t.html#a606e7765c4f2215fb2bf630f6eb9ff6b", null ], + [ "keepAliveSeconds", "struct_m_q_t_t_connect_info__t.html#a7d05d53261732ebdfbb9ee665a347591", null ], + [ "pClientIdentifier", "struct_m_q_t_t_connect_info__t.html#a010f8f6993cbf8899648d5c515ff7884", null ], + [ "clientIdentifierLength", "struct_m_q_t_t_connect_info__t.html#a8077ef36ab318f3d35bee6f098fa54d4", null ], + [ "pUserName", "struct_m_q_t_t_connect_info__t.html#a1118d7d3251a11445318557280db53b4", null ], + [ "userNameLength", "struct_m_q_t_t_connect_info__t.html#a7165be3bb06d4527ab4eb773b50e05e1", null ], + [ "pPassword", "struct_m_q_t_t_connect_info__t.html#acec6c79a11d2f0f130802393f34d2b5e", null ], + [ "passwordLength", "struct_m_q_t_t_connect_info__t.html#a818c4e212a12020a4109eb890ec96383", null ] + ] ], + [ "MQTTSubscribeInfo_t", "struct_m_q_t_t_subscribe_info__t.html", [ + [ "qos", "struct_m_q_t_t_subscribe_info__t.html#a64cf2e423f60cfec122eeaef80c0fd86", null ], + [ "pTopicFilter", "struct_m_q_t_t_subscribe_info__t.html#adb0b28240fdcd82a85f11cf2f8b5bbf0", null ], + [ "topicFilterLength", "struct_m_q_t_t_subscribe_info__t.html#a6972f8e036f8bde9b1f23a2aacb61382", null ] + ] ], + [ "MQTTPublishInfo_t", "struct_m_q_t_t_publish_info__t.html", [ + [ "qos", "struct_m_q_t_t_publish_info__t.html#a178224d02b4acdec7e08e88de0e4b399", null ], + [ "retain", "struct_m_q_t_t_publish_info__t.html#a343b0af89c46a900db4aa5c775a0975a", null ], + [ "dup", "struct_m_q_t_t_publish_info__t.html#aa1c8954e83bfa678d1ff5429679d4e89", null ], + [ "pTopicName", "struct_m_q_t_t_publish_info__t.html#aa80e8ca282d01630f878ad0afe81d7a4", null ], + [ "topicNameLength", "struct_m_q_t_t_publish_info__t.html#a6161c792d20cc7cf8284c1b71ea1145f", null ], + [ "pPayload", "struct_m_q_t_t_publish_info__t.html#afc28299f4f625f5e674bb61b42f03380", null ], + [ "payloadLength", "struct_m_q_t_t_publish_info__t.html#a7997964e11571f35f0c3b729db0f760f", null ] + ] ], + [ "MQTTPacketInfo_t", "struct_m_q_t_t_packet_info__t.html", [ + [ "type", "struct_m_q_t_t_packet_info__t.html#a7fef40548c1aa0f0e7f812a6a7243758", null ], + [ "pRemainingData", "struct_m_q_t_t_packet_info__t.html#ac66cedff052bc844ec9b296387df60bc", null ], + [ "remainingLength", "struct_m_q_t_t_packet_info__t.html#a7c85becf08de0ec9776dd4be1fcc4bf8", null ], + [ "headerLength", "struct_m_q_t_t_packet_info__t.html#aa7de1631ed8e08410942d36a72db558a", null ] + ] ], + [ "TransportInterface_t", "struct_transport_interface__t.html", [ + [ "recv", "struct_transport_interface__t.html#a7c34e9b865e2a509306f09c7dfa3699e", null ], + [ "send", "struct_transport_interface__t.html#a01cd9935e9a5266ca196243a0054d489", null ], + [ "writev", "struct_transport_interface__t.html#a8cf677fbeee53d270daa6dacfa138b79", null ], + [ "pNetworkContext", "struct_transport_interface__t.html#aaf4702050bef8d62714a4d3900e95087", null ] + ] ], + [ "NetworkContext_t", "group__mqtt__struct__types.html#ga7769e434e7811caed8cd6fd7f9ec26ec", null ] +]; \ No newline at end of file diff --git a/v1.3.0/coreMQTT/index.html b/v1.3.0/coreMQTT/index.html new file mode 100644 index 00000000..f12f447a --- /dev/null +++ b/v1.3.0/coreMQTT/index.html @@ -0,0 +1,143 @@ + + + + + + + +coreMQTT: Overview + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Overview
+
+
+

MQTT 3.1.1 client library

+
+

‍MQTT stands for MQ Telemetry Transport. It is a publish/subscribe, extremely simple and lightweight messaging protocol, designed for constrained devices and low-bandwidth, high-latency or unreliable networks. The design principles are to minimise network bandwidth and device resource requirements whilst also attempting to ensure reliability and some degree of assurance of delivery. These principles also turn out to make the protocol ideal of the emerging "machine-to-machine" (M2M) or "Internet of Things" world of connected devices, and for mobile applications where bandwidth and battery power are at a premium.

+
+

Official description of MQTT from mqtt.org
+

+

This MQTT library implements the client side of the MQTT 3.1.1 protocol. This library is optimized for resource constrained embedded devices. Features of this library include:

    +
  • Fully synchronous API, to allow applications to completely manage their concurrency and multi-threading method.
  • +
  • Operations on fixed buffers, so that applications may control their memory allocation strategy.
  • +
  • Scalable performance and footprint. The configuration settings allow this library to be tailored to a system's resources.
  • +
+

Please see https://github.com/aws/aws-iot-device-sdk-embedded-C/tree/main/demos/mqtt for example code demonstrating integration with TLS.

+

+Memory Requirements

+

Memory requirements of the MQTT library.

+

+ + + + + + + + + + + + +
Code Size of coreMQTT (example generated with GCC for ARM Cortex-M)
File
With -O1 Optimization
With -Os Optimization
core_mqtt.c
4.1K
3.5K
core_mqtt_state.c
1.7K
1.3K
core_mqtt_serializer.c
2.8K
2.2K
Total estimates
8.6K
7.0K
+

+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/index.js b/v1.3.0/coreMQTT/index.js new file mode 100644 index 00000000..d1fc3cbb --- /dev/null +++ b/v1.3.0/coreMQTT/index.js @@ -0,0 +1,4 @@ +var index = +[ + [ "Memory Requirements", "index.html#mqtt_memory_requirements", null ] +]; \ No newline at end of file diff --git a/v1.3.0/coreMQTT/jquery.js b/v1.3.0/coreMQTT/jquery.js new file mode 100644 index 00000000..1dffb65b --- /dev/null +++ b/v1.3.0/coreMQTT/jquery.js @@ -0,0 +1,34 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=y(e||this.defaultElement||this)[0],this.element=y(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=y(),this.hoverable=y(),this.focusable=y(),this.classesElementLookup={},e!==this&&(y.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=y(e.style?e.ownerDocument:e.document||e),this.window=y(this.document[0].defaultView||this.document[0].parentWindow)),this.options=y.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:y.noop,_create:y.noop,_init:y.noop,destroy:function(){var i=this;this._destroy(),y.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:y.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return y.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=y.widget.extend({},this.options[t]),n=0;n
"),i=e.children()[0];return y("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),s=t-i},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.widthx(D(s),D(n))?o.important="horizontal":o.important="vertical",p.using.call(this,t,o)}),h.offset(y.extend(l,{using:t}))})},y.ui.position={fit:{left:function(t,e){var i=e.within,s=i.isWindow?i.scrollLeft:i.offset.left,n=i.width,o=t.left-e.collisionPosition.marginLeft,h=s-o,a=o+e.collisionWidth-n-s;e.collisionWidth>n?0n?0=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),y.ui.plugin={add:function(t,e,i){var s,n=y.ui[t].prototype;for(s in i)n.plugins[s]=n.plugins[s]||[],n.plugins[s].push([e,i[s]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;n").css({overflow:"hidden",position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,t={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(t),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(t),this._proportionallyResize()),this._setupHandles(),e.autoHide&&y(this.element).on("mouseenter",function(){e.disabled||(i._removeClass("ui-resizable-autohide"),i._handles.show())}).on("mouseleave",function(){e.disabled||i.resizing||(i._addClass("ui-resizable-autohide"),i._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy(),this._addedHandles.remove();function t(t){y(t).removeData("resizable").removeData("ui-resizable").off(".resizable")}var e;return this.elementIsWrapper&&(t(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),t(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;case"aspectRatio":this._aspectRatio=!!e}},_setupHandles:function(){var t,e,i,s,n,o=this.options,h=this;if(this.handles=o.handles||(y(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=y(),this._addedHandles=y(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),i=this.handles.split(","),this.handles={},e=0;e"),this._addClass(n,"ui-resizable-handle "+s),n.css({zIndex:o.zIndex}),this.handles[t]=".ui-resizable-"+t,this.element.children(this.handles[t]).length||(this.element.append(n),this._addedHandles=this._addedHandles.add(n));this._renderAxis=function(t){var e,i,s;for(e in t=t||this.element,this.handles)this.handles[e].constructor===String?this.handles[e]=this.element.children(this.handles[e]).first().show():(this.handles[e].jquery||this.handles[e].nodeType)&&(this.handles[e]=y(this.handles[e]),this._on(this.handles[e],{mousedown:h._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(i=y(this.handles[e],this.element),s=/sw|ne|nw|se|n|s/.test(e)?i.outerHeight():i.outerWidth(),i=["padding",/ne|nw|n/.test(e)?"Top":/se|sw|s/.test(e)?"Bottom":/^e$/.test(e)?"Right":"Left"].join(""),t.css(i,s),this._proportionallyResize()),this._handles=this._handles.add(this.handles[e])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){h.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),h.axis=n&&n[1]?n[1]:"se")}),o.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._addedHandles.remove()},_mouseCapture:function(t){var e,i,s=!1;for(e in this.handles)(i=y(this.handles[e])[0])!==t.target&&!y.contains(i,t.target)||(s=!0);return!this.options.disabled&&s},_mouseStart:function(t){var e,i,s=this.options,n=this.element;return this.resizing=!0,this._renderProxy(),e=this._num(this.helper.css("left")),i=this._num(this.helper.css("top")),s.containment&&(e+=y(s.containment).scrollLeft()||0,i+=y(s.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:e,top:i},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:n.width(),height:n.height()},this.originalSize=this._helper?{width:n.outerWidth(),height:n.outerHeight()}:{width:n.width(),height:n.height()},this.sizeDiff={width:n.outerWidth()-n.width(),height:n.outerHeight()-n.height()},this.originalPosition={left:e,top:i},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio="number"==typeof s.aspectRatio?s.aspectRatio:this.originalSize.width/this.originalSize.height||1,s=y(".ui-resizable-"+this.axis).css("cursor"),y("body").css("cursor","auto"===s?this.axis+"-resize":s),this._addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var e=this.originalMousePosition,i=this.axis,s=t.pageX-e.left||0,e=t.pageY-e.top||0,i=this._change[i];return this._updatePrevProperties(),i&&(e=i.apply(this,[t,s,e]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(e=this._updateRatio(e,t)),e=this._respectSize(e,t),this._updateCache(e),this._propagate("resize",t),e=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),y.isEmptyObject(e)||(this._updatePrevProperties(),this._trigger("resize",t,this.ui()),this._applyChanges())),!1},_mouseStop:function(t){this.resizing=!1;var e,i,s,n=this.options,o=this;return this._helper&&(s=(e=(i=this._proportionallyResizeElements).length&&/textarea/i.test(i[0].nodeName))&&this._hasScroll(i[0],"left")?0:o.sizeDiff.height,i=e?0:o.sizeDiff.width,e={width:o.helper.width()-i,height:o.helper.height()-s},i=parseFloat(o.element.css("left"))+(o.position.left-o.originalPosition.left)||null,s=parseFloat(o.element.css("top"))+(o.position.top-o.originalPosition.top)||null,n.animate||this.element.css(y.extend(e,{top:s,left:i})),o.helper.height(o.size.height),o.helper.width(o.size.width),this._helper&&!n.animate&&this._proportionallyResize()),y("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s=this.options,n={minWidth:this._isNumber(s.minWidth)?s.minWidth:0,maxWidth:this._isNumber(s.maxWidth)?s.maxWidth:1/0,minHeight:this._isNumber(s.minHeight)?s.minHeight:0,maxHeight:this._isNumber(s.maxHeight)?s.maxHeight:1/0};(this._aspectRatio||t)&&(e=n.minHeight*this.aspectRatio,i=n.minWidth/this.aspectRatio,s=n.maxHeight*this.aspectRatio,t=n.maxWidth/this.aspectRatio,e>n.minWidth&&(n.minWidth=e),i>n.minHeight&&(n.minHeight=i),st.width,h=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,a=this.originalPosition.left+this.originalSize.width,r=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),i=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),h&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=a-e.minWidth),s&&l&&(t.left=a-e.maxWidth),h&&i&&(t.top=r-e.minHeight),n&&i&&(t.top=r-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];e<4;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;e").css({overflow:"hidden"}),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++e.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize;return{left:this.originalPosition.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize;return{top:this.originalPosition.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(t,e,i){return y.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},sw:function(t,e,i){return y.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,e,i]))},ne:function(t,e,i){return y.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},nw:function(t,e,i){return y.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,e,i]))}},_propagate:function(t,e){y.ui.plugin.call(this,t,[e,this.ui()]),"resize"!==t&&this._trigger(t,e,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),y.ui.plugin.add("resizable","animate",{stop:function(e){var i=y(this).resizable("instance"),t=i.options,s=i._proportionallyResizeElements,n=s.length&&/textarea/i.test(s[0].nodeName),o=n&&i._hasScroll(s[0],"left")?0:i.sizeDiff.height,h=n?0:i.sizeDiff.width,n={width:i.size.width-h,height:i.size.height-o},h=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,o=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(y.extend(n,o&&h?{top:o,left:h}:{}),{duration:t.animateDuration,easing:t.animateEasing,step:function(){var t={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};s&&s.length&&y(s[0]).css({width:t.width,height:t.height}),i._updateCache(t),i._propagate("resize",e)}})}}),y.ui.plugin.add("resizable","containment",{start:function(){var i,s,n=y(this).resizable("instance"),t=n.options,e=n.element,o=t.containment,h=o instanceof y?o.get(0):/parent/.test(o)?e.parent().get(0):o;h&&(n.containerElement=y(h),/document/.test(o)||o===document?(n.containerOffset={left:0,top:0},n.containerPosition={left:0,top:0},n.parentData={element:y(document),left:0,top:0,width:y(document).width(),height:y(document).height()||document.body.parentNode.scrollHeight}):(i=y(h),s=[],y(["Top","Right","Left","Bottom"]).each(function(t,e){s[t]=n._num(i.css("padding"+e))}),n.containerOffset=i.offset(),n.containerPosition=i.position(),n.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},t=n.containerOffset,e=n.containerSize.height,o=n.containerSize.width,o=n._hasScroll(h,"left")?h.scrollWidth:o,e=n._hasScroll(h)?h.scrollHeight:e,n.parentData={element:h,left:t.left,top:t.top,width:o,height:e}))},resize:function(t){var e=y(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.position,o=e._aspectRatio||t.shiftKey,h={top:0,left:0},a=e.containerElement,t=!0;a[0]!==document&&/static/.test(a.css("position"))&&(h=s),n.left<(e._helper?s.left:0)&&(e.size.width=e.size.width+(e._helper?e.position.left-s.left:e.position.left-h.left),o&&(e.size.height=e.size.width/e.aspectRatio,t=!1),e.position.left=i.helper?s.left:0),n.top<(e._helper?s.top:0)&&(e.size.height=e.size.height+(e._helper?e.position.top-s.top:e.position.top),o&&(e.size.width=e.size.height*e.aspectRatio,t=!1),e.position.top=e._helper?s.top:0),i=e.containerElement.get(0)===e.element.parent().get(0),n=/relative|absolute/.test(e.containerElement.css("position")),i&&n?(e.offset.left=e.parentData.left+e.position.left,e.offset.top=e.parentData.top+e.position.top):(e.offset.left=e.element.offset().left,e.offset.top=e.element.offset().top),n=Math.abs(e.sizeDiff.width+(e._helper?e.offset.left-h.left:e.offset.left-s.left)),s=Math.abs(e.sizeDiff.height+(e._helper?e.offset.top-h.top:e.offset.top-s.top)),n+e.size.width>=e.parentData.width&&(e.size.width=e.parentData.width-n,o&&(e.size.height=e.size.width/e.aspectRatio,t=!1)),s+e.size.height>=e.parentData.height&&(e.size.height=e.parentData.height-s,o&&(e.size.width=e.size.height*e.aspectRatio,t=!1)),t||(e.position.left=e.prevPosition.left,e.position.top=e.prevPosition.top,e.size.width=e.prevSize.width,e.size.height=e.prevSize.height)},stop:function(){var t=y(this).resizable("instance"),e=t.options,i=t.containerOffset,s=t.containerPosition,n=t.containerElement,o=y(t.helper),h=o.offset(),a=o.outerWidth()-t.sizeDiff.width,o=o.outerHeight()-t.sizeDiff.height;t._helper&&!e.animate&&/relative/.test(n.css("position"))&&y(this).css({left:h.left-s.left-i.left,width:a,height:o}),t._helper&&!e.animate&&/static/.test(n.css("position"))&&y(this).css({left:h.left-s.left-i.left,width:a,height:o})}}),y.ui.plugin.add("resizable","alsoResize",{start:function(){var t=y(this).resizable("instance").options;y(t.alsoResize).each(function(){var t=y(this);t.data("ui-resizable-alsoresize",{width:parseFloat(t.width()),height:parseFloat(t.height()),left:parseFloat(t.css("left")),top:parseFloat(t.css("top"))})})},resize:function(t,i){var e=y(this).resizable("instance"),s=e.options,n=e.originalSize,o=e.originalPosition,h={height:e.size.height-n.height||0,width:e.size.width-n.width||0,top:e.position.top-o.top||0,left:e.position.left-o.left||0};y(s.alsoResize).each(function(){var t=y(this),s=y(this).data("ui-resizable-alsoresize"),n={},e=t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];y.each(e,function(t,e){var i=(s[e]||0)+(h[e]||0);i&&0<=i&&(n[e]=i||null)}),t.css(n)})},stop:function(){y(this).removeData("ui-resizable-alsoresize")}}),y.ui.plugin.add("resizable","ghost",{start:function(){var t=y(this).resizable("instance"),e=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}),t._addClass(t.ghost,"ui-resizable-ghost"),!1!==y.uiBackCompat&&"string"==typeof t.options.ghost&&t.ghost.addClass(this.options.ghost),t.ghost.appendTo(t.helper)},resize:function(){var t=y(this).resizable("instance");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=y(this).resizable("instance");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),y.ui.plugin.add("resizable","grid",{resize:function(){var t,e=y(this).resizable("instance"),i=e.options,s=e.size,n=e.originalSize,o=e.originalPosition,h=e.axis,a="number"==typeof i.grid?[i.grid,i.grid]:i.grid,r=a[0]||1,l=a[1]||1,u=Math.round((s.width-n.width)/r)*r,p=Math.round((s.height-n.height)/l)*l,d=n.width+u,c=n.height+p,f=i.maxWidth&&i.maxWidthd,s=i.minHeight&&i.minHeight>c;i.grid=a,m&&(d+=r),s&&(c+=l),f&&(d-=r),g&&(c-=l),/^(se|s|e)$/.test(h)?(e.size.width=d,e.size.height=c):/^(ne)$/.test(h)?(e.size.width=d,e.size.height=c,e.position.top=o.top-p):/^(sw)$/.test(h)?(e.size.width=d,e.size.height=c,e.position.left=o.left-u):((c-l<=0||d-r<=0)&&(t=e._getPaddingPlusBorderDimensions(this)),0=f[g]?0:Math.min(f[g],n));!a&&1-1){targetElements.on(evt+EVENT_NAMESPACE,function elementToggle(event){$.powerTip.toggle(this,event)})}else{targetElements.on(evt+EVENT_NAMESPACE,function elementOpen(event){$.powerTip.show(this,event)})}});$.each(options.closeEvents,function(idx,evt){if($.inArray(evt,options.openEvents)<0){targetElements.on(evt+EVENT_NAMESPACE,function elementClose(event){$.powerTip.hide(this,!isMouseEvent(event))})}});targetElements.on("keydown"+EVENT_NAMESPACE,function elementKeyDown(event){if(event.keyCode===27){$.powerTip.hide(this,true)}})}return targetElements};$.fn.powerTip.defaults={fadeInTime:200,fadeOutTime:100,followMouse:false,popupId:"powerTip",popupClass:null,intentSensitivity:7,intentPollInterval:100,closeDelay:100,placement:"n",smartPlacement:false,offset:10,mouseOnToPopup:false,manual:false,openEvents:["mouseenter","focus"],closeEvents:["mouseleave","blur"]};$.fn.powerTip.smartPlacementLists={n:["n","ne","nw","s"],e:["e","ne","se","w","nw","sw","n","s","e"],s:["s","se","sw","n"],w:["w","nw","sw","e","ne","se","n","s","w"],nw:["nw","w","sw","n","s","se","nw"],ne:["ne","e","se","n","s","sw","ne"],sw:["sw","w","nw","s","n","ne","sw"],se:["se","e","ne","s","n","nw","se"],"nw-alt":["nw-alt","n","ne-alt","sw-alt","s","se-alt","w","e"],"ne-alt":["ne-alt","n","nw-alt","se-alt","s","sw-alt","e","w"],"sw-alt":["sw-alt","s","se-alt","nw-alt","n","ne-alt","w","e"],"se-alt":["se-alt","s","sw-alt","ne-alt","n","nw-alt","e","w"]};$.powerTip={show:function apiShowTip(element,event){if(isMouseEvent(event)){trackMouse(event);session.previousX=event.pageX;session.previousY=event.pageY;$(element).data(DATA_DISPLAYCONTROLLER).show()}else{$(element).first().data(DATA_DISPLAYCONTROLLER).show(true,true)}return element},reposition:function apiResetPosition(element){$(element).first().data(DATA_DISPLAYCONTROLLER).resetPosition();return element},hide:function apiCloseTip(element,immediate){var displayController;immediate=element?immediate:true;if(element){displayController=$(element).first().data(DATA_DISPLAYCONTROLLER)}else if(session.activeHover){displayController=session.activeHover.data(DATA_DISPLAYCONTROLLER)}if(displayController){displayController.hide(immediate)}return element},toggle:function apiToggle(element,event){if(session.activeHover&&session.activeHover.is(element)){$.powerTip.hide(element,!isMouseEvent(event))}else{$.powerTip.show(element,event)}return element}};$.powerTip.showTip=$.powerTip.show;$.powerTip.closeTip=$.powerTip.hide;function CSSCoordinates(){var me=this;me.top="auto";me.left="auto";me.right="auto";me.bottom="auto";me.set=function(property,value){if($.isNumeric(value)){me[property]=Math.round(value)}}}function DisplayController(element,options,tipController){var hoverTimer=null,myCloseDelay=null;function openTooltip(immediate,forceOpen){cancelTimer();if(!element.data(DATA_HASACTIVEHOVER)){if(!immediate){session.tipOpenImminent=true;hoverTimer=setTimeout(function intentDelay(){hoverTimer=null;checkForIntent()},options.intentPollInterval)}else{if(forceOpen){element.data(DATA_FORCEDOPEN,true)}closeAnyDelayed();tipController.showTip(element)}}else{cancelClose()}}function closeTooltip(disableDelay){if(myCloseDelay){myCloseDelay=session.closeDelayTimeout=clearTimeout(myCloseDelay);session.delayInProgress=false}cancelTimer();session.tipOpenImminent=false;if(element.data(DATA_HASACTIVEHOVER)){element.data(DATA_FORCEDOPEN,false);if(!disableDelay){session.delayInProgress=true;session.closeDelayTimeout=setTimeout(function closeDelay(){session.closeDelayTimeout=null;tipController.hideTip(element);session.delayInProgress=false;myCloseDelay=null},options.closeDelay);myCloseDelay=session.closeDelayTimeout}else{tipController.hideTip(element)}}}function checkForIntent(){var xDifference=Math.abs(session.previousX-session.currentX),yDifference=Math.abs(session.previousY-session.currentY),totalDifference=xDifference+yDifference;if(totalDifference",{id:options.popupId});if($body.length===0){$body=$("body")}$body.append(tipElement);session.tooltips=session.tooltips?session.tooltips.add(tipElement):tipElement}if(options.followMouse){if(!tipElement.data(DATA_HASMOUSEMOVE)){$document.on("mousemove"+EVENT_NAMESPACE,positionTipOnCursor);$window.on("scroll"+EVENT_NAMESPACE,positionTipOnCursor);tipElement.data(DATA_HASMOUSEMOVE,true)}}function beginShowTip(element){element.data(DATA_HASACTIVEHOVER,true);tipElement.queue(function queueTipInit(next){showTip(element);next()})}function showTip(element){var tipContent;if(!element.data(DATA_HASACTIVEHOVER)){return}if(session.isTipOpen){if(!session.isClosing){hideTip(session.activeHover)}tipElement.delay(100).queue(function queueTipAgain(next){showTip(element);next()});return}element.trigger("powerTipPreRender");tipContent=getTooltipContent(element);if(tipContent){tipElement.empty().append(tipContent)}else{return}element.trigger("powerTipRender");session.activeHover=element;session.isTipOpen=true;tipElement.data(DATA_MOUSEONTOTIP,options.mouseOnToPopup);tipElement.addClass(options.popupClass);if(!options.followMouse||element.data(DATA_FORCEDOPEN)){positionTipOnElement(element);session.isFixedTipOpen=true}else{positionTipOnCursor()}if(!element.data(DATA_FORCEDOPEN)&&!options.followMouse){$document.on("click"+EVENT_NAMESPACE,function documentClick(event){var target=event.target;if(target!==element[0]){if(options.mouseOnToPopup){if(target!==tipElement[0]&&!$.contains(tipElement[0],target)){$.powerTip.hide()}}else{$.powerTip.hide()}}})}if(options.mouseOnToPopup&&!options.manual){tipElement.on("mouseenter"+EVENT_NAMESPACE,function tipMouseEnter(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).cancel()}});tipElement.on("mouseleave"+EVENT_NAMESPACE,function tipMouseLeave(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).hide()}})}tipElement.fadeIn(options.fadeInTime,function fadeInCallback(){if(!session.desyncTimeout){session.desyncTimeout=setInterval(closeDesyncedTip,500)}element.trigger("powerTipOpen")})}function hideTip(element){session.isClosing=true;session.isTipOpen=false;session.desyncTimeout=clearInterval(session.desyncTimeout);element.data(DATA_HASACTIVEHOVER,false);element.data(DATA_FORCEDOPEN,false);$document.off("click"+EVENT_NAMESPACE);tipElement.off(EVENT_NAMESPACE);tipElement.fadeOut(options.fadeOutTime,function fadeOutCallback(){var coords=new CSSCoordinates;session.activeHover=null;session.isClosing=false;session.isFixedTipOpen=false;tipElement.removeClass();coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);tipElement.css(coords);element.trigger("powerTipClose")})}function positionTipOnCursor(){var tipWidth,tipHeight,coords,collisions,collisionCount;if(!session.isFixedTipOpen&&(session.isTipOpen||session.tipOpenImminent&&tipElement.data(DATA_HASMOUSEMOVE))){tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=new CSSCoordinates;coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);collisions=getViewportCollisions(coords,tipWidth,tipHeight);if(collisions!==Collision.none){collisionCount=countFlags(collisions);if(collisionCount===1){if(collisions===Collision.right){coords.set("left",session.scrollLeft+session.windowWidth-tipWidth)}else if(collisions===Collision.bottom){coords.set("top",session.scrollTop+session.windowHeight-tipHeight)}}else{coords.set("left",session.currentX-tipWidth-options.offset);coords.set("top",session.currentY-tipHeight-options.offset)}}tipElement.css(coords)}}function positionTipOnElement(element){var priorityList,finalPlacement;if(options.smartPlacement||options.followMouse&&element.data(DATA_FORCEDOPEN)){priorityList=$.fn.powerTip.smartPlacementLists[options.placement];$.each(priorityList,function(idx,pos){var collisions=getViewportCollisions(placeTooltip(element,pos),tipElement.outerWidth(),tipElement.outerHeight());finalPlacement=pos;return collisions!==Collision.none})}else{placeTooltip(element,options.placement);finalPlacement=options.placement}tipElement.removeClass("w nw sw e ne se n s w se-alt sw-alt ne-alt nw-alt");tipElement.addClass(finalPlacement)}function placeTooltip(element,placement){var iterationCount=0,tipWidth,tipHeight,coords=new CSSCoordinates;coords.set("top",0);coords.set("left",0);tipElement.css(coords);do{tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=placementCalculator.compute(element,placement,tipWidth,tipHeight,options.offset);tipElement.css(coords)}while(++iterationCount<=5&&(tipWidth!==tipElement.outerWidth()||tipHeight!==tipElement.outerHeight()));return coords}function closeDesyncedTip(){var isDesynced=false,hasDesyncableCloseEvent=$.grep(["mouseleave","mouseout","blur","focusout"],function(eventType){return $.inArray(eventType,options.closeEvents)!==-1}).length>0;if(session.isTipOpen&&!session.isClosing&&!session.delayInProgress&&hasDesyncableCloseEvent){if(session.activeHover.data(DATA_HASACTIVEHOVER)===false||session.activeHover.is(":disabled")){isDesynced=true}else if(!isMouseOver(session.activeHover)&&!session.activeHover.is(":focus")&&!session.activeHover.data(DATA_FORCEDOPEN)){if(tipElement.data(DATA_MOUSEONTOTIP)){if(!isMouseOver(tipElement)){isDesynced=true}}else{isDesynced=true}}if(isDesynced){hideTip(session.activeHover)}}}this.showTip=beginShowTip;this.hideTip=hideTip;this.resetPosition=positionTipOnElement}function isSvgElement(element){return Boolean(window.SVGElement&&element[0]instanceof SVGElement)}function isMouseEvent(event){return Boolean(event&&$.inArray(event.type,MOUSE_EVENTS)>-1&&typeof event.pageX==="number")}function initTracking(){if(!session.mouseTrackingActive){session.mouseTrackingActive=true;getViewportDimensions();$(getViewportDimensions);$document.on("mousemove"+EVENT_NAMESPACE,trackMouse);$window.on("resize"+EVENT_NAMESPACE,trackResize);$window.on("scroll"+EVENT_NAMESPACE,trackScroll)}}function getViewportDimensions(){session.scrollLeft=$window.scrollLeft();session.scrollTop=$window.scrollTop();session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackResize(){session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackScroll(){var x=$window.scrollLeft(),y=$window.scrollTop();if(x!==session.scrollLeft){session.currentX+=x-session.scrollLeft;session.scrollLeft=x}if(y!==session.scrollTop){session.currentY+=y-session.scrollTop;session.scrollTop=y}}function trackMouse(event){session.currentX=event.pageX;session.currentY=event.pageY}function isMouseOver(element){var elementPosition=element.offset(),elementBox=element[0].getBoundingClientRect(),elementWidth=elementBox.right-elementBox.left,elementHeight=elementBox.bottom-elementBox.top;return session.currentX>=elementPosition.left&&session.currentX<=elementPosition.left+elementWidth&&session.currentY>=elementPosition.top&&session.currentY<=elementPosition.top+elementHeight}function getTooltipContent(element){var tipText=element.data(DATA_POWERTIP),tipObject=element.data(DATA_POWERTIPJQ),tipTarget=element.data(DATA_POWERTIPTARGET),targetElement,content;if(tipText){if($.isFunction(tipText)){tipText=tipText.call(element[0])}content=tipText}else if(tipObject){if($.isFunction(tipObject)){tipObject=tipObject.call(element[0])}if(tipObject.length>0){content=tipObject.clone(true,true)}}else if(tipTarget){targetElement=$("#"+tipTarget);if(targetElement.length>0){content=targetElement.html()}}return content}function getViewportCollisions(coords,elementWidth,elementHeight){var viewportTop=session.scrollTop,viewportLeft=session.scrollLeft,viewportBottom=viewportTop+session.windowHeight,viewportRight=viewportLeft+session.windowWidth,collisions=Collision.none;if(coords.topviewportBottom||Math.abs(coords.bottom-session.windowHeight)>viewportBottom){collisions|=Collision.bottom}if(coords.leftviewportRight){collisions|=Collision.left}if(coords.left+elementWidth>viewportRight||coords.right1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);/*! SmartMenus jQuery Plugin - v1.1.0 - September 17, 2017 + * http://www.smartmenus.org/ + * Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function($){function initMouseDetection(t){var e=".smartmenus_mouse";if(mouseDetectionEnabled||t)mouseDetectionEnabled&&t&&($(document).off(e),mouseDetectionEnabled=!1);else{var i=!0,s=null,o={mousemove:function(t){var e={x:t.pageX,y:t.pageY,timeStamp:(new Date).getTime()};if(s){var o=Math.abs(s.x-e.x),a=Math.abs(s.y-e.y);if((o>0||a>0)&&2>=o&&2>=a&&300>=e.timeStamp-s.timeStamp&&(mouse=!0,i)){var n=$(t.target).closest("a");n.is("a")&&$.each(menuTrees,function(){return $.contains(this.$root[0],n[0])?(this.itemEnter({currentTarget:n[0]}),!1):void 0}),i=!1}}s=e}};o[touchEvents?"touchstart":"pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut"]=function(t){isTouchEvent(t.originalEvent)&&(mouse=!1)},$(document).on(getEventsNS(o,e)),mouseDetectionEnabled=!0}}function isTouchEvent(t){return!/^(4|mouse)$/.test(t.pointerType)}function getEventsNS(t,e){e||(e="");var i={};for(var s in t)i[s.split(" ").join(e+" ")+e]=t[s];return i}var menuTrees=[],mouse=!1,touchEvents="ontouchstart"in window,mouseDetectionEnabled=!1,requestAnimationFrame=window.requestAnimationFrame||function(t){return setTimeout(t,1e3/60)},cancelAnimationFrame=window.cancelAnimationFrame||function(t){clearTimeout(t)},canAnimate=!!$.fn.animate;return $.SmartMenus=function(t,e){this.$root=$(t),this.opts=e,this.rootId="",this.accessIdPrefix="",this.$subArrow=null,this.activatedItems=[],this.visibleSubMenus=[],this.showTimeout=0,this.hideTimeout=0,this.scrollTimeout=0,this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.idInc=0,this.$firstLink=null,this.$firstSub=null,this.disabled=!1,this.$disableOverlay=null,this.$touchScrollingSub=null,this.cssTransforms3d="perspective"in t.style||"webkitPerspective"in t.style,this.wasCollapsible=!1,this.init()},$.extend($.SmartMenus,{hideAll:function(){$.each(menuTrees,function(){this.menuHideAll()})},destroy:function(){for(;menuTrees.length;)menuTrees[0].destroy();initMouseDetection(!0)},prototype:{init:function(t){var e=this;if(!t){menuTrees.push(this),this.rootId=((new Date).getTime()+Math.random()+"").replace(/\D/g,""),this.accessIdPrefix="sm-"+this.rootId+"-",this.$root.hasClass("sm-rtl")&&(this.opts.rightToLeftSubMenus=!0);var i=".smartmenus";this.$root.data("smartmenus",this).attr("data-smartmenus-id",this.rootId).dataSM("level",1).on(getEventsNS({"mouseover focusin":$.proxy(this.rootOver,this),"mouseout focusout":$.proxy(this.rootOut,this),keydown:$.proxy(this.rootKeyDown,this)},i)).on(getEventsNS({mouseenter:$.proxy(this.itemEnter,this),mouseleave:$.proxy(this.itemLeave,this),mousedown:$.proxy(this.itemDown,this),focus:$.proxy(this.itemFocus,this),blur:$.proxy(this.itemBlur,this),click:$.proxy(this.itemClick,this)},i),"a"),i+=this.rootId,this.opts.hideOnClick&&$(document).on(getEventsNS({touchstart:$.proxy(this.docTouchStart,this),touchmove:$.proxy(this.docTouchMove,this),touchend:$.proxy(this.docTouchEnd,this),click:$.proxy(this.docClick,this)},i)),$(window).on(getEventsNS({"resize orientationchange":$.proxy(this.winResize,this)},i)),this.opts.subIndicators&&(this.$subArrow=$("").addClass("sub-arrow"),this.opts.subIndicatorsText&&this.$subArrow.html(this.opts.subIndicatorsText)),initMouseDetection()}if(this.$firstSub=this.$root.find("ul").each(function(){e.menuInit($(this))}).eq(0),this.$firstLink=this.$root.find("a").eq(0),this.opts.markCurrentItem){var s=/(index|default)\.[^#\?\/]*/i,o=/#.*/,a=window.location.href.replace(s,""),n=a.replace(o,"");this.$root.find("a").each(function(){var t=this.href.replace(s,""),i=$(this);(t==a||t==n)&&(i.addClass("current"),e.opts.markCurrentTree&&i.parentsUntil("[data-smartmenus-id]","ul").each(function(){$(this).dataSM("parent-a").addClass("current")}))})}this.wasCollapsible=this.isCollapsible()},destroy:function(t){if(!t){var e=".smartmenus";this.$root.removeData("smartmenus").removeAttr("data-smartmenus-id").removeDataSM("level").off(e),e+=this.rootId,$(document).off(e),$(window).off(e),this.opts.subIndicators&&(this.$subArrow=null)}this.menuHideAll();var i=this;this.$root.find("ul").each(function(){var t=$(this);t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.dataSM("shown-before")&&((i.opts.subMenusMinWidth||i.opts.subMenusMaxWidth)&&t.css({width:"",minWidth:"",maxWidth:""}).removeClass("sm-nowrap"),t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.css({zIndex:"",top:"",left:"",marginLeft:"",marginTop:"",display:""})),0==(t.attr("id")||"").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeDataSM("in-mega").removeDataSM("shown-before").removeDataSM("scroll-arrows").removeDataSM("parent-a").removeDataSM("level").removeDataSM("beforefirstshowfired").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeAttr("aria-expanded"),this.$root.find("a.has-submenu").each(function(){var t=$(this);0==t.attr("id").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeClass("has-submenu").removeDataSM("sub").removeAttr("aria-haspopup").removeAttr("aria-controls").removeAttr("aria-expanded").closest("li").removeDataSM("sub"),this.opts.subIndicators&&this.$root.find("span.sub-arrow").remove(),this.opts.markCurrentItem&&this.$root.find("a.current").removeClass("current"),t||(this.$root=null,this.$firstLink=null,this.$firstSub=null,this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),menuTrees.splice($.inArray(this,menuTrees),1))},disable:function(t){if(!this.disabled){if(this.menuHideAll(),!t&&!this.opts.isPopup&&this.$root.is(":visible")){var e=this.$root.offset();this.$disableOverlay=$('
').css({position:"absolute",top:e.top,left:e.left,width:this.$root.outerWidth(),height:this.$root.outerHeight(),zIndex:this.getStartZIndex(!0),opacity:0}).appendTo(document.body)}this.disabled=!0}},docClick:function(t){return this.$touchScrollingSub?(this.$touchScrollingSub=null,void 0):((this.visibleSubMenus.length&&!$.contains(this.$root[0],t.target)||$(t.target).closest("a").length)&&this.menuHideAll(),void 0)},docTouchEnd:function(){if(this.lastTouch){if(!(!this.visibleSubMenus.length||void 0!==this.lastTouch.x2&&this.lastTouch.x1!=this.lastTouch.x2||void 0!==this.lastTouch.y2&&this.lastTouch.y1!=this.lastTouch.y2||this.lastTouch.target&&$.contains(this.$root[0],this.lastTouch.target))){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var t=this;this.hideTimeout=setTimeout(function(){t.menuHideAll()},350)}this.lastTouch=null}},docTouchMove:function(t){if(this.lastTouch){var e=t.originalEvent.touches[0];this.lastTouch.x2=e.pageX,this.lastTouch.y2=e.pageY}},docTouchStart:function(t){var e=t.originalEvent.touches[0];this.lastTouch={x1:e.pageX,y1:e.pageY,target:e.target}},enable:function(){this.disabled&&(this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),this.disabled=!1)},getClosestMenu:function(t){for(var e=$(t).closest("ul");e.dataSM("in-mega");)e=e.parent().closest("ul");return e[0]||null},getHeight:function(t){return this.getOffset(t,!0)},getOffset:function(t,e){var i;"none"==t.css("display")&&(i={position:t[0].style.position,visibility:t[0].style.visibility},t.css({position:"absolute",visibility:"hidden"}).show());var s=t[0].getBoundingClientRect&&t[0].getBoundingClientRect(),o=s&&(e?s.height||s.bottom-s.top:s.width||s.right-s.left);return o||0===o||(o=e?t[0].offsetHeight:t[0].offsetWidth),i&&t.hide().css(i),o},getStartZIndex:function(t){var e=parseInt(this[t?"$root":"$firstSub"].css("z-index"));return!t&&isNaN(e)&&(e=parseInt(this.$root.css("z-index"))),isNaN(e)?1:e},getTouchPoint:function(t){return t.touches&&t.touches[0]||t.changedTouches&&t.changedTouches[0]||t},getViewport:function(t){var e=t?"Height":"Width",i=document.documentElement["client"+e],s=window["inner"+e];return s&&(i=Math.min(i,s)),i},getViewportHeight:function(){return this.getViewport(!0)},getViewportWidth:function(){return this.getViewport()},getWidth:function(t){return this.getOffset(t)},handleEvents:function(){return!this.disabled&&this.isCSSOn()},handleItemEvents:function(t){return this.handleEvents()&&!this.isLinkInMegaMenu(t)},isCollapsible:function(){return"static"==this.$firstSub.css("position")},isCSSOn:function(){return"inline"!=this.$firstLink.css("display")},isFixed:function(){var t="fixed"==this.$root.css("position");return t||this.$root.parentsUntil("body").each(function(){return"fixed"==$(this).css("position")?(t=!0,!1):void 0}),t},isLinkInMegaMenu:function(t){return $(this.getClosestMenu(t[0])).hasClass("mega-menu")},isTouchMode:function(){return!mouse||this.opts.noMouseOver||this.isCollapsible()},itemActivate:function(t,e){var i=t.closest("ul"),s=i.dataSM("level");if(s>1&&(!this.activatedItems[s-2]||this.activatedItems[s-2][0]!=i.dataSM("parent-a")[0])){var o=this;$(i.parentsUntil("[data-smartmenus-id]","ul").get().reverse()).add(i).each(function(){o.itemActivate($(this).dataSM("parent-a"))})}if((!this.isCollapsible()||e)&&this.menuHideSubMenus(this.activatedItems[s-1]&&this.activatedItems[s-1][0]==t[0]?s:s-1),this.activatedItems[s-1]=t,this.$root.triggerHandler("activate.smapi",t[0])!==!1){var a=t.dataSM("sub");a&&(this.isTouchMode()||!this.opts.showOnClick||this.clickActivated)&&this.menuShow(a)}},itemBlur:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&this.$root.triggerHandler("blur.smapi",e[0])},itemClick:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(this.$touchScrollingSub&&this.$touchScrollingSub[0]==e.closest("ul")[0])return this.$touchScrollingSub=null,t.stopPropagation(),!1;if(this.$root.triggerHandler("click.smapi",e[0])===!1)return!1;var i=$(t.target).is(".sub-arrow"),s=e.dataSM("sub"),o=s?2==s.dataSM("level"):!1,a=this.isCollapsible(),n=/toggle$/.test(this.opts.collapsibleBehavior),r=/link$/.test(this.opts.collapsibleBehavior),h=/^accordion/.test(this.opts.collapsibleBehavior);if(s&&!s.is(":visible")){if((!r||!a||i)&&(this.opts.showOnClick&&o&&(this.clickActivated=!0),this.itemActivate(e,h),s.is(":visible")))return this.focusActivated=!0,!1}else if(a&&(n||i))return this.itemActivate(e,h),this.menuHide(s),n&&(this.focusActivated=!1),!1;return this.opts.showOnClick&&o||e.hasClass("disabled")||this.$root.triggerHandler("select.smapi",e[0])===!1?!1:void 0}},itemDown:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&e.dataSM("mousedown",!0)},itemEnter:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(!this.isTouchMode()){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);var i=this;this.showTimeout=setTimeout(function(){i.itemActivate(e)},this.opts.showOnClick&&1==e.closest("ul").dataSM("level")?1:this.opts.showTimeout)}this.$root.triggerHandler("mouseenter.smapi",e[0])}},itemFocus:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(!this.focusActivated||this.isTouchMode()&&e.dataSM("mousedown")||this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0]==e[0]||this.itemActivate(e,!0),this.$root.triggerHandler("focus.smapi",e[0]))},itemLeave:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(this.isTouchMode()||(e[0].blur(),this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0)),e.removeDataSM("mousedown"),this.$root.triggerHandler("mouseleave.smapi",e[0]))},menuHide:function(t){if(this.$root.triggerHandler("beforehide.smapi",t[0])!==!1&&(canAnimate&&t.stop(!0,!0),"none"!=t.css("display"))){var e=function(){t.css("z-index","")};this.isCollapsible()?canAnimate&&this.opts.collapsibleHideFunction?this.opts.collapsibleHideFunction.call(this,t,e):t.hide(this.opts.collapsibleHideDuration,e):canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,t,e):t.hide(this.opts.hideDuration,e),t.dataSM("scroll")&&(this.menuScrollStop(t),t.css({"touch-action":"","-ms-touch-action":"","-webkit-transform":"",transform:""}).off(".smartmenus_scroll").removeDataSM("scroll").dataSM("scroll-arrows").hide()),t.dataSM("parent-a").removeClass("highlighted").attr("aria-expanded","false"),t.attr({"aria-expanded":"false","aria-hidden":"true"});var i=t.dataSM("level");this.activatedItems.splice(i-1,1),this.visibleSubMenus.splice($.inArray(t,this.visibleSubMenus),1),this.$root.triggerHandler("hide.smapi",t[0])}},menuHideAll:function(){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);for(var t=this.opts.isPopup?1:0,e=this.visibleSubMenus.length-1;e>=t;e--)this.menuHide(this.visibleSubMenus[e]);this.opts.isPopup&&(canAnimate&&this.$root.stop(!0,!0),this.$root.is(":visible")&&(canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,this.$root):this.$root.hide(this.opts.hideDuration))),this.activatedItems=[],this.visibleSubMenus=[],this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.$root.triggerHandler("hideAll.smapi")},menuHideSubMenus:function(t){for(var e=this.activatedItems.length-1;e>=t;e--){var i=this.activatedItems[e].dataSM("sub");i&&this.menuHide(i)}},menuInit:function(t){if(!t.dataSM("in-mega")){t.hasClass("mega-menu")&&t.find("ul").dataSM("in-mega",!0);for(var e=2,i=t[0];(i=i.parentNode.parentNode)!=this.$root[0];)e++;var s=t.prevAll("a").eq(-1);s.length||(s=t.prevAll().find("a").eq(-1)),s.addClass("has-submenu").dataSM("sub",t),t.dataSM("parent-a",s).dataSM("level",e).parent().dataSM("sub",t);var o=s.attr("id")||this.accessIdPrefix+ ++this.idInc,a=t.attr("id")||this.accessIdPrefix+ ++this.idInc;s.attr({id:o,"aria-haspopup":"true","aria-controls":a,"aria-expanded":"false"}),t.attr({id:a,role:"group","aria-hidden":"true","aria-labelledby":o,"aria-expanded":"false"}),this.opts.subIndicators&&s[this.opts.subIndicatorsPos](this.$subArrow.clone())}},menuPosition:function(t){var e,i,s=t.dataSM("parent-a"),o=s.closest("li"),a=o.parent(),n=t.dataSM("level"),r=this.getWidth(t),h=this.getHeight(t),u=s.offset(),l=u.left,c=u.top,d=this.getWidth(s),m=this.getHeight(s),p=$(window),f=p.scrollLeft(),v=p.scrollTop(),b=this.getViewportWidth(),S=this.getViewportHeight(),g=a.parent().is("[data-sm-horizontal-sub]")||2==n&&!a.hasClass("sm-vertical"),M=this.opts.rightToLeftSubMenus&&!o.is("[data-sm-reverse]")||!this.opts.rightToLeftSubMenus&&o.is("[data-sm-reverse]"),w=2==n?this.opts.mainMenuSubOffsetX:this.opts.subMenusSubOffsetX,T=2==n?this.opts.mainMenuSubOffsetY:this.opts.subMenusSubOffsetY;if(g?(e=M?d-r-w:w,i=this.opts.bottomToTopSubMenus?-h-T:m+T):(e=M?w-r:d-w,i=this.opts.bottomToTopSubMenus?m-T-h:T),this.opts.keepInViewport){var y=l+e,I=c+i;if(M&&f>y?e=g?f-y+e:d-w:!M&&y+r>f+b&&(e=g?f+b-r-y+e:w-r),g||(S>h&&I+h>v+S?i+=v+S-h-I:(h>=S||v>I)&&(i+=v-I)),g&&(I+h>v+S+.49||v>I)||!g&&h>S+.49){var x=this;t.dataSM("scroll-arrows")||t.dataSM("scroll-arrows",$([$('')[0],$('')[0]]).on({mouseenter:function(){t.dataSM("scroll").up=$(this).hasClass("scroll-up"),x.menuScroll(t)},mouseleave:function(e){x.menuScrollStop(t),x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(t){t.preventDefault()}}).insertAfter(t));var A=".smartmenus_scroll";if(t.dataSM("scroll",{y:this.cssTransforms3d?0:i-m,step:1,itemH:m,subH:h,arrowDownH:this.getHeight(t.dataSM("scroll-arrows").eq(1))}).on(getEventsNS({mouseover:function(e){x.menuScrollOver(t,e)},mouseout:function(e){x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(e){x.menuScrollMousewheel(t,e)}},A)).dataSM("scroll-arrows").css({top:"auto",left:"0",marginLeft:e+(parseInt(t.css("border-left-width"))||0),width:r-(parseInt(t.css("border-left-width"))||0)-(parseInt(t.css("border-right-width"))||0),zIndex:t.css("z-index")}).eq(g&&this.opts.bottomToTopSubMenus?0:1).show(),this.isFixed()){var C={};C[touchEvents?"touchstart touchmove touchend":"pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp"]=function(e){x.menuScrollTouch(t,e)},t.css({"touch-action":"none","-ms-touch-action":"none"}).on(getEventsNS(C,A))}}}t.css({top:"auto",left:"0",marginLeft:e,marginTop:i-m})},menuScroll:function(t,e,i){var s,o=t.dataSM("scroll"),a=t.dataSM("scroll-arrows"),n=o.up?o.upEnd:o.downEnd;if(!e&&o.momentum){if(o.momentum*=.92,s=o.momentum,.5>s)return this.menuScrollStop(t),void 0}else s=i||(e||!this.opts.scrollAccelerate?this.opts.scrollStep:Math.floor(o.step));var r=t.dataSM("level");if(this.activatedItems[r-1]&&this.activatedItems[r-1].dataSM("sub")&&this.activatedItems[r-1].dataSM("sub").is(":visible")&&this.menuHideSubMenus(r-1),o.y=o.up&&o.y>=n||!o.up&&n>=o.y?o.y:Math.abs(n-o.y)>s?o.y+(o.up?s:-s):n,t.css(this.cssTransforms3d?{"-webkit-transform":"translate3d(0, "+o.y+"px, 0)",transform:"translate3d(0, "+o.y+"px, 0)"}:{marginTop:o.y}),mouse&&(o.up&&o.y>o.downEnd||!o.up&&o.y0;t.dataSM("scroll-arrows").eq(i?0:1).is(":visible")&&(t.dataSM("scroll").up=i,this.menuScroll(t,!0))}e.preventDefault()},menuScrollOut:function(t,e){mouse&&(/^scroll-(up|down)/.test((e.relatedTarget||"").className)||(t[0]==e.relatedTarget||$.contains(t[0],e.relatedTarget))&&this.getClosestMenu(e.relatedTarget)==t[0]||t.dataSM("scroll-arrows").css("visibility","hidden"))},menuScrollOver:function(t,e){if(mouse&&!/^scroll-(up|down)/.test(e.target.className)&&this.getClosestMenu(e.target)==t[0]){this.menuScrollRefreshData(t);var i=t.dataSM("scroll"),s=$(window).scrollTop()-t.dataSM("parent-a").offset().top-i.itemH;t.dataSM("scroll-arrows").eq(0).css("margin-top",s).end().eq(1).css("margin-top",s+this.getViewportHeight()-i.arrowDownH).end().css("visibility","visible")}},menuScrollRefreshData:function(t){var e=t.dataSM("scroll"),i=$(window).scrollTop()-t.dataSM("parent-a").offset().top-e.itemH;this.cssTransforms3d&&(i=-(parseFloat(t.css("margin-top"))-i)),$.extend(e,{upEnd:i,downEnd:i+this.getViewportHeight()-e.subH})},menuScrollStop:function(t){return this.scrollTimeout?(cancelAnimationFrame(this.scrollTimeout),this.scrollTimeout=0,t.dataSM("scroll").step=1,!0):void 0},menuScrollTouch:function(t,e){if(e=e.originalEvent,isTouchEvent(e)){var i=this.getTouchPoint(e);if(this.getClosestMenu(i.target)==t[0]){var s=t.dataSM("scroll");if(/(start|down)$/i.test(e.type))this.menuScrollStop(t)?(e.preventDefault(),this.$touchScrollingSub=t):this.$touchScrollingSub=null,this.menuScrollRefreshData(t),$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp});else if(/move$/i.test(e.type)){var o=void 0!==s.touchY?s.touchY:s.touchStartY;if(void 0!==o&&o!=i.pageY){this.$touchScrollingSub=t;var a=i.pageY>o;void 0!==s.up&&s.up!=a&&$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp}),$.extend(s,{up:a,touchY:i.pageY}),this.menuScroll(t,!0,Math.abs(i.pageY-o))}e.preventDefault()}else void 0!==s.touchY&&((s.momentum=15*Math.pow(Math.abs(i.pageY-s.touchStartY)/(e.timeStamp-s.touchStartTime),2))&&(this.menuScrollStop(t),this.menuScroll(t),e.preventDefault()),delete s.touchY)}}},menuShow:function(t){if((t.dataSM("beforefirstshowfired")||(t.dataSM("beforefirstshowfired",!0),this.$root.triggerHandler("beforefirstshow.smapi",t[0])!==!1))&&this.$root.triggerHandler("beforeshow.smapi",t[0])!==!1&&(t.dataSM("shown-before",!0),canAnimate&&t.stop(!0,!0),!t.is(":visible"))){var e=t.dataSM("parent-a"),i=this.isCollapsible();if((this.opts.keepHighlighted||i)&&e.addClass("highlighted"),i)t.removeClass("sm-nowrap").css({zIndex:"",width:"auto",minWidth:"",maxWidth:"",top:"",left:"",marginLeft:"",marginTop:""});else{if(t.css("z-index",this.zIndexInc=(this.zIndexInc||this.getStartZIndex())+1),(this.opts.subMenusMinWidth||this.opts.subMenusMaxWidth)&&(t.css({width:"auto",minWidth:"",maxWidth:""}).addClass("sm-nowrap"),this.opts.subMenusMinWidth&&t.css("min-width",this.opts.subMenusMinWidth),this.opts.subMenusMaxWidth)){var s=this.getWidth(t);t.css("max-width",this.opts.subMenusMaxWidth),s>this.getWidth(t)&&t.removeClass("sm-nowrap").css("width",this.opts.subMenusMaxWidth)}this.menuPosition(t)}var o=function(){t.css("overflow","")};i?canAnimate&&this.opts.collapsibleShowFunction?this.opts.collapsibleShowFunction.call(this,t,o):t.show(this.opts.collapsibleShowDuration,o):canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,t,o):t.show(this.opts.showDuration,o),e.attr("aria-expanded","true"),t.attr({"aria-expanded":"true","aria-hidden":"false"}),this.visibleSubMenus.push(t),this.$root.triggerHandler("show.smapi",t[0])}},popupHide:function(t){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},t?1:this.opts.hideTimeout)},popupShow:function(t,e){if(!this.opts.isPopup)return alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'),void 0;if(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),this.$root.dataSM("shown-before",!0),canAnimate&&this.$root.stop(!0,!0),!this.$root.is(":visible")){this.$root.css({left:t,top:e});var i=this,s=function(){i.$root.css("overflow","")};canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,this.$root,s):this.$root.show(this.opts.showDuration,s),this.visibleSubMenus[0]=this.$root}},refresh:function(){this.destroy(!0),this.init(!0)},rootKeyDown:function(t){if(this.handleEvents())switch(t.keyCode){case 27:var e=this.activatedItems[0];if(e){this.menuHideAll(),e[0].focus();var i=e.dataSM("sub");i&&this.menuHide(i)}break;case 32:var s=$(t.target);if(s.is("a")&&this.handleItemEvents(s)){var i=s.dataSM("sub");i&&!i.is(":visible")&&(this.itemClick({currentTarget:t.target}),t.preventDefault())}}},rootOut:function(t){if(this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),!this.opts.showOnClick||!this.opts.hideOnClick)){var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},this.opts.hideTimeout)}},rootOver:function(t){this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0)},winResize:function(t){if(this.handleEvents()){if(!("onorientationchange"in window)||"orientationchange"==t.type){var e=this.isCollapsible();this.wasCollapsible&&e||(this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0].blur(),this.menuHideAll()),this.wasCollapsible=e}}else if(this.$disableOverlay){var i=this.$root.offset();this.$disableOverlay.css({top:i.top,left:i.left,width:this.$root.outerWidth(),height:this.$root.outerHeight()})}}}}),$.fn.dataSM=function(t,e){return e?this.data(t+"_smartmenus",e):this.data(t+"_smartmenus")},$.fn.removeDataSM=function(t){return this.removeData(t+"_smartmenus")},$.fn.smartmenus=function(options){if("string"==typeof options){var args=arguments,method=options;return Array.prototype.shift.call(args),this.each(function(){var t=$(this).data("smartmenus");t&&t[method]&&t[method].apply(t,args)})}return this.each(function(){var dataOpts=$(this).data("sm-options")||null;if(dataOpts)try{dataOpts=eval("("+dataOpts+")")}catch(e){dataOpts=null,alert('ERROR\n\nSmartMenus jQuery init:\nInvalid "data-sm-options" attribute value syntax.')}new $.SmartMenus(this,$.extend({},$.fn.smartmenus.defaults,options,dataOpts))})},$.fn.smartmenus.defaults={isPopup:!1,mainMenuSubOffsetX:0,mainMenuSubOffsetY:0,subMenusSubOffsetX:0,subMenusSubOffsetY:0,subMenusMinWidth:"10em",subMenusMaxWidth:"20em",subIndicators:!0,subIndicatorsPos:"append",subIndicatorsText:"",scrollStep:30,scrollAccelerate:!0,showTimeout:250,hideTimeout:500,showDuration:0,showFunction:null,hideDuration:0,hideFunction:function(t,e){t.fadeOut(200,e)},collapsibleShowDuration:0,collapsibleShowFunction:function(t,e){t.slideDown(200,e)},collapsibleHideDuration:0,collapsibleHideFunction:function(t,e){t.slideUp(200,e)},showOnClick:!1,hideOnClick:!0,noMouseOver:!1,keepInViewport:!0,keepHighlighted:!0,markCurrentItem:!1,markCurrentTree:!0,rightToLeftSubMenus:!1,bottomToTopSubMenus:!1,collapsibleBehavior:"default"},$}); \ No newline at end of file diff --git a/v1.3.0/coreMQTT/modules.html b/v1.3.0/coreMQTT/modules.html new file mode 100644 index 00000000..e4267a73 --- /dev/null +++ b/v1.3.0/coreMQTT/modules.html @@ -0,0 +1,121 @@ + + + + + + + +coreMQTT: Data types and Constants + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Data types and Constants
+
+
+
This library defines the following data types and constants.
+ + + + + + +
 Enumerated TypesEnumerated types of the MQTT library
 Callback TypesCallback function pointer types of the MQTT library
 Parameter StructuresStructures passed as parameters to MQTT library functions
 Basic TypesPrimitive types of the MQTT library
 ConstantsConstants defined in the MQTT library
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/modules.js b/v1.3.0/coreMQTT/modules.js new file mode 100644 index 00000000..7f3931b2 --- /dev/null +++ b/v1.3.0/coreMQTT/modules.js @@ -0,0 +1,8 @@ +var modules = +[ + [ "Enumerated Types", "group__mqtt__enum__types.html", "group__mqtt__enum__types" ], + [ "Callback Types", "group__mqtt__callback__types.html", "group__mqtt__callback__types" ], + [ "Parameter Structures", "group__mqtt__struct__types.html", "group__mqtt__struct__types" ], + [ "Basic Types", "group__mqtt__basic__types.html", "group__mqtt__basic__types" ], + [ "Constants", "group__mqtt__constants.html", "group__mqtt__constants" ] +]; \ No newline at end of file diff --git a/v1.3.0/coreMQTT/mqtt_connect_design.png b/v1.3.0/coreMQTT/mqtt_connect_design.png new file mode 100644 index 0000000000000000000000000000000000000000..81a1933c6c592396000cdad6566ced3d636f4cfc GIT binary patch literal 179318 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 z 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 + + + + + + +coreMQTT: MQTT_Connect + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_Connect
+
+
+
+
const MQTTConnectInfo_t * pConnectInfo,
+
const MQTTPublishInfo_t * pWillInfo,
+
uint32_t timeoutMs,
+
bool * pSessionPresent );
+
MQTTStatus_t MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
Establish an MQTT session.
Definition: core_mqtt.c:2679
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+

Establish an MQTT session.

+

This function will send MQTT CONNECT packet and receive a CONNACK packet. The send and receive from the network is done through the transport interface.

+

The maximum time this function waits for a CONNACK is decided in one of the following ways:

    +
  1. If timeoutMs is greater than 0: MQTTContext_t.getTime is used to ensure that the function does not wait more than timeoutMs for CONNACK.
  2. +
  3. If timeoutMs is 0: The network receive for CONNACK is retried up to the number of times configured by MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT.
  4. +
+
Note
If a dummy MQTTGetCurrentTimeFunc_t was passed to MQTT_Init, then a timeout value of 0 MUST be passed to the API, and the MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS timeout configurations MUST be set to 0.
+
Parameters
+ + + + + + +
[in]pContextInitialized MQTT context.
[in]pConnectInfoMQTT CONNECT packet information.
[in]pWillInfoLast Will and Testament. Pass NULL if Last Will and Testament is not used.
[in]timeoutMsMaximum time in milliseconds to wait for a CONNACK packet. A zero timeout makes use of the retries for receiving CONNACK as configured with MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT.
[out]pSessionPresentThis value will be set to true if a previous session was present; otherwise it will be set to false. It is only relevant if not establishing a clean session.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport send failed; MQTTRecvFailed if transport receive failed for CONNACK; MQTTNoDataAvailable if no data available to receive in transport until the timeoutMs for CONNACK; MQTTSuccess otherwise.
+
Note
This API may spend more time than provided in the timeoutMS parameters in certain conditions as listed below:
+
    +
  1. Timeouts are incorrectly configured - If the timeoutMS is less than the transport receive timeout and if a CONNACK packet is not received within the transport receive timeout, the API will spend the transport receive timeout (which is more time than the timeoutMs). It is the case of incorrect timeout configuration as the timeoutMs parameter passed to this API must be greater than the transport receive timeout. Please refer to the transport interface documentation for more details about timeout configurations.
  2. +
  3. Partial CONNACK packet is received right before the expiry of the timeout - It is possible that first two bytes of CONNACK packet (packet type and remaining length) are received right before the expiry of the timeoutMS. In that case, the API makes one more network receive call in an attempt to receive the remaining 2 bytes. In the worst case, it can happen that the remaining 2 bytes are never received and this API will end up spending timeoutMs + transport receive timeout.
  4. +
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
bool sessionPresent;
+
// This is assumed to have been initialized before calling this function.
+
MQTTContext_t * pContext;
+
+
// True for creating a new session with broker, false if we want to resume an old one.
+
connectInfo.cleanSession = true;
+
// Client ID must be unique to broker. This field is required.
+
connectInfo.pClientIdentifier = "someClientID";
+
connectInfo.clientIdentifierLength = strlen( connectInfo.pClientIdentifier );
+
+
// The following fields are optional.
+
// Value for keep alive.
+
connectInfo.keepAliveSeconds = 60;
+
// Optional username and password.
+
connectInfo.pUserName = "someUserName";
+
connectInfo.userNameLength = strlen( connectInfo.pUserName );
+
connectInfo.pPassword = "somePassword";
+
connectInfo.passwordLength = strlen( connectInfo.pPassword );
+
+
// The last will and testament is optional, it will be published by the broker
+
// should this client disconnect without sending a DISCONNECT packet.
+
willInfo.qos = MQTTQoS0;
+
willInfo.pTopicName = "/lwt/topic/name";
+
willInfo.topicNameLength = strlen( willInfo.pTopicName );
+
willInfo.pPayload = "LWT Message";
+
willInfo.payloadLength = strlen( "LWT Message" );
+
+
// Send the connect packet. Use 100 ms as the timeout to wait for the CONNACK packet.
+
status = MQTT_Connect( pContext, &connectInfo, &willInfo, 100, &sessionPresent );
+
+
if( status == MQTTSuccess )
+
{
+
// Since we requested a clean session, this must be false
+
assert( sessionPresent == false );
+
+
// Do something with the connection.
+
}
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
@ MQTTQoS0
Definition: core_mqtt_serializer.h:110
+
const char * pClientIdentifier
MQTT client identifier. Must be unique per client.
Definition: core_mqtt_serializer.h:147
+
const char * pUserName
MQTT user name. Set to NULL if not used.
Definition: core_mqtt_serializer.h:157
+
bool cleanSession
Whether to establish a new, clean session or resume a previous session.
Definition: core_mqtt_serializer.h:137
+
uint16_t userNameLength
Length of MQTT user name. Set to 0 if not used.
Definition: core_mqtt_serializer.h:162
+
uint16_t keepAliveSeconds
MQTT keep alive period.
Definition: core_mqtt_serializer.h:142
+
uint16_t clientIdentifierLength
Length of the client identifier.
Definition: core_mqtt_serializer.h:152
+
uint16_t passwordLength
Length of MQTT password. Set to 0 if not used.
Definition: core_mqtt_serializer.h:172
+
const char * pPassword
MQTT password. Set to NULL if not used.
Definition: core_mqtt_serializer.h:167
+
MQTTQoS_t qos
Quality of Service for message.
Definition: core_mqtt_serializer.h:206
+
uint16_t topicNameLength
Length of topic name.
Definition: core_mqtt_serializer.h:226
+
size_t payloadLength
Message payload length.
Definition: core_mqtt_serializer.h:236
+
const char * pTopicName
Topic name on which the message is published.
Definition: core_mqtt_serializer.h:221
+
const void * pPayload
Message payload.
Definition: core_mqtt_serializer.h:231
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_deserializeack_function.html b/v1.3.0/coreMQTT/mqtt_deserializeack_function.html new file mode 100644 index 00000000..3ab4e6b4 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_deserializeack_function.html @@ -0,0 +1,154 @@ + + + + + + + +coreMQTT: MQTT_DeserializeAck + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_DeserializeAck
+
+
+
+
uint16_t * pPacketId,
+
bool * pSessionPresent );
+
MQTTStatus_t MQTT_DeserializeAck(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, bool *pSessionPresent)
Deserialize an MQTT CONNACK, SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, PUBCOMP, or PINGRESP.
Definition: core_mqtt_serializer.c:2484
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+

Deserialize an MQTT CONNACK, SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, PUBCOMP, or PINGRESP.

+
Parameters
+ + + + +
[in]pIncomingPacketMQTTPacketInfo_t containing the buffer.
[out]pPacketIdThe packet ID of obtained from the buffer. Not used in CONNACK or PINGRESP.
[out]pSessionPresentBoolean flag from a CONNACK indicating present session.
+
+
+
Returns
MQTTBadParameter, MQTTBadResponse, MQTTServerRefused, or MQTTSuccess.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPacketInfo_t incomingPacket;
+
// Used for SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, and PUBCOMP.
+
uint16_t packetId;
+
// Used for CONNACK.
+
bool sessionPresent;
+
+
// Receive an incoming packet and populate all fields. The details are out of scope
+
// for this example.
+
receiveIncomingPacket( &incomingPacket );
+
+
// Deserialize ack information if the incoming packet is not a publish.
+
if( ( incomingPacket.type & 0xF0 ) != MQTT_PACKET_TYPE_PUBLISH )
+
{
+
status = MQTT_DeserializeAck( &incomingPacket, &packetId, &sessionPresent );
+
if( status == MQTTSuccess )
+
{
+
// The packet ID or session present flag information is available. For
+
// ping response packets, the only information is the status code.
+
}
+
}
+
#define MQTT_PACKET_TYPE_PUBLISH
PUBLISH (bidirectional).
Definition: core_mqtt_serializer.h:55
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
uint8_t type
Type of incoming MQTT packet.
Definition: core_mqtt_serializer.h:248
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_deserializepublish_function.html b/v1.3.0/coreMQTT/mqtt_deserializepublish_function.html new file mode 100644 index 00000000..99a5fcc2 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_deserializepublish_function.html @@ -0,0 +1,180 @@ + + + + + + + +coreMQTT: MQTT_DeserializePublish + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_DeserializePublish
+
+
+
+
uint16_t * pPacketId,
+
MQTTPublishInfo_t * pPublishInfo );
+
MQTTStatus_t MQTT_DeserializePublish(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo)
Deserialize an MQTT PUBLISH packet.
Definition: core_mqtt_serializer.c:2447
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+

Deserialize an MQTT PUBLISH packet.

+
Parameters
+ + + + +
[in]pIncomingPacketMQTTPacketInfo_t containing the buffer.
[out]pPacketIdThe packet ID obtained from the buffer.
[out]pPublishInfoStruct containing information about the publish.
+
+
+
Returns
MQTTBadParameter, MQTTBadResponse, or MQTTSuccess.
+

Example

// TransportRecv_t function for reading from the network.
+
int32_t socket_recv(
+
NetworkContext_t * pNetworkContext,
+
void * pBuffer,
+
size_t bytesToRecv
+
);
+
// Some context to be used with the above transport receive function.
+
NetworkContext_t networkContext;
+
+
// Other variables used in this example.
+
MQTTStatus_t status;
+
MQTTPacketInfo_t incomingPacket;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
uint16_t packetId;
+
+
int32_t bytesRecvd;
+
// A buffer to hold remaining data of the incoming packet.
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
// Populate all fields of the incoming packet.
+ +
socket_recv,
+
&networkContext,
+
&incomingPacket
+
);
+
assert( status == MQTTSuccess );
+
assert( incomingPacket.remainingLength <= BUFFER_SIZE );
+
bytesRecvd = socket_recv(
+
&networkContext,
+
( void * ) buffer,
+
incomingPacket.remainingLength
+
);
+
incomingPacket.pRemainingData = buffer;
+
+
// Deserialize the publish information if the incoming packet is a publish.
+
if( ( incomingPacket.type & 0xF0 ) == MQTT_PACKET_TYPE_PUBLISH )
+
{
+
status = MQTT_DeserializePublish( &incomingPacket, &packetId, &publishInfo );
+
if( status == MQTTSuccess )
+
{
+
// The deserialized publish information can now be used from `publishInfo`.
+
}
+
}
+
MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength(TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket)
Extract the MQTT packet type and length from incoming packet.
Definition: core_mqtt_serializer.c:2561
+
#define MQTT_PACKET_TYPE_PUBLISH
PUBLISH (bidirectional).
Definition: core_mqtt_serializer.h:55
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
+
size_t remainingLength
Length of remaining serialized data.
Definition: core_mqtt_serializer.h:258
+
uint8_t type
Type of incoming MQTT packet.
Definition: core_mqtt_serializer.h:248
+
uint8_t * pRemainingData
Remaining serialized data in the MQTT packet.
Definition: core_mqtt_serializer.h:253
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_design.html b/v1.3.0/coreMQTT/mqtt_design.html new file mode 100644 index 00000000..bd9b16ff --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_design.html @@ -0,0 +1,196 @@ + + + + + + + +coreMQTT: Design + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Design
+
+
+

Architecture of the MQTT library.

+

This MQTT client library provides an implementation of the MQTT 3.1.1 specification. It is optimized for resource constrained devices and does not allocate any memory.

+

+Interfaces and Callbacks

+

The MQTT library relies on interfaces to dissociate itself from platform specific functionality, such as the transport layer or maintaining time. Interfaces used by MQTT are simply function pointers with expectations of behavior.

+

The MQTT library expects the application to provide implementations for the following interfaces:

+ + + + + + + + + + + +
Function Pointer Use
TransportRecv_t Receiving data from an established network connection.
TransportSend_t Sending data over an established network connection.
MQTTGetCurrentTimeFunc_t Obtaining timestamps for complying with user-specified timeouts and the MQTT keep-alive mechanism.
MQTTEventCallback_t Returning packets received from the network to the user application after deserialization.
+

+Serializers and Deserializers

+

The managed MQTT API in core_mqtt.h uses a set of serialization and deserialization functions declared in core_mqtt_serializer.h. If a user does not want to use the functionality provided by the managed API, these low-level functions can be used directly:

+ +

+Sessions and State

+

The MQTT 3.1.1 protocol allows for a client and server to maintain persistent sessions, which can be resumed after a reconnect. The elements of a session stored by this client library consist of the states of incomplete publishes with Quality of Service levels of 1 (at least once), or 2 (exactly once). These states are stored in the pointers pointed to by MQTTContext_t::outgoingPublishRecords and MQTTContext_t::incomingPublishRecords; This library does not store any subscription information, nor any information for QoS 0 publishes.

+

When resuming a persistent session, the client library will resend PUBRELs for all PUBRECs that had been received for incomplete outgoing QoS 2 publishes. If the broker does not resume the session, then all state information in the client will be reset.

+
Note
The library stores only the state of incomplete publishes and not the publish payloads. It is the responsibility of the user application to save publish payloads until the publish is complete. If a persistent session is resumed, then MQTT_PublishToResend should be called to obtain the packet identifiers of incomplete publishes, followed by a call to MQTT_Publish to resend the unacknowledged publish.
+

+Packet Reception

+

MQTT Packets are received from the network with calls to MQTT_ProcessLoop or MQTT_ReceiveLoop. These functions are mostly identical, with the exception of keep-alive; the former sends ping requests and processes ping responses to ensure the MQTT session does not remain idle for more than the keep-alive interval, while the latter does not. Since calls to MQTT_Publish, MQTT_Subscribe, and MQTT_Unsubscribe only send packets and do not wait for acknowledgments, a call to MQTT_ProcessLoop or MQTT_ReceiveLoop must follow in order to receive any expected acknowledgment. The exception is MQTT_Connect; since a MQTT session cannot be considered established until the server acknowledges a CONNECT packet with a CONNACK, the function waits until the CONNACK is received.

+

+Runtime Timeouts passed to MQTT library

+

MQTT_Connect, MQTT_ProcessLoop, and MQTT_ReceiveLoop all accept a timeout parameter for packet reception.
+ For the MQTT_Connect, if this value is set to 0, then instead of a time-based loop, it will attempt to call the transport receive function up to a maximum number of retries, which is defined by MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT.

+

For MQTT_ProcessLoop and MQTT_ReceiveLoop, the timeout value represents the minimum duration that will be spent in the function, provided there are no network errors. Should the timeout be set to 0, then the loop will run for a single iteration. A single iteration of a loop consists of an attempt to receive a single byte from the network, and if the single byte receive was successful, then attempt(s) to receive the rest of the packet (with retry attempts governed by MQTT_RECV_POLLING_TIMEOUT_MS), followed by sending acknowledgement response, if needed (with retry attempts governed by MQTT_SEND_TIMEOUT_MS), and then, finally deserialization of the packet received and a call to the application callback. If the first read did not succeed, then instead the library checks if a ping request needs to be sent (only for the process loop).

+

See the below diagrams for a representation of the above flows:

+ + + + +
MQTT Connect Diagram MQTT ProcessLoop Diagram MQTT ReceiveLoop Diagram
MQTT Connect MQTT Process Loop MQTT Receive Loop
+

+Keep-Alive

+

The MQTT standard specifies a keep-alive mechanism to detect half-open or otherwise unusable network connections. An MQTT client will send periodic ping requests (PINGREQ) to the server if the connection is idle. The MQTT server must respond to ping requests with a ping response (PINGRESP).

+

In this library, MQTT_ProcessLoop handles sending of PINGREQs and processing corresponding PINGRESPs to comply with the keep-alive interval set in MQTTContext_t::keepAliveIntervalSec.

+

The standard does not specify the time duration within which the server has to respond to a ping request, noting only a "reasonable amount of time". If the response to a ping request is not received within MQTT_PINGRESP_TIMEOUT_MS, this library assumes that the connection is dead.

+

If MQTT_ReceiveLoop is used instead of MQTT_ProcessLoop, then no ping requests are sent. The application must ensure the connection does not remain idle for more than the keep-alive interval by calling MQTT_Ping to send ping requests. The timestamp in MQTTContext_t::lastPacketTxTime indicates when a packet was last sent by the library.

+

Sending any ping request sets the MQTTContext_t::waitingForPingResp flag. This flag is cleared by MQTT_ProcessLoop when a ping response is received. If MQTT_ReceiveLoop is used instead, then this flag must be cleared manually by the application's callback.

+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_disconnect_function.html b/v1.3.0/coreMQTT/mqtt_disconnect_function.html new file mode 100644 index 00000000..0fc1f269 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_disconnect_function.html @@ -0,0 +1,125 @@ + + + + + + + +coreMQTT: MQTT_Disconnect + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_Disconnect
+
+
+
+
MQTTStatus_t MQTT_Disconnect(MQTTContext_t *pContext)
Disconnect an MQTT session.
Definition: core_mqtt.c:3045
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+

Disconnect an MQTT session.

+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport send failed; MQTTSuccess otherwise.
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_functions.html b/v1.3.0/coreMQTT/mqtt_functions.html new file mode 100644 index 00000000..6a17fa65 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_functions.html @@ -0,0 +1,150 @@ + + + + + + + +coreMQTT: Functions + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ + + + + + diff --git a/v1.3.0/coreMQTT/mqtt_functions.js b/v1.3.0/coreMQTT/mqtt_functions.js new file mode 100644 index 00000000..2f84fba7 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_functions.js @@ -0,0 +1,33 @@ +var mqtt_functions = +[ + [ "MQTT_Init", "mqtt_init_function.html", null ], + [ "MQTT_Connect", "mqtt_connect_function.html", null ], + [ "MQTT_Subscribe", "mqtt_subscribe_function.html", null ], + [ "MQTT_Publish", "mqtt_publish_function.html", null ], + [ "MQTT_Ping", "mqtt_ping_function.html", null ], + [ "MQTT_Unsubscribe", "mqtt_unsubscribe_function.html", null ], + [ "MQTT_Disconnect", "mqtt_disconnect_function.html", null ], + [ "MQTT_ProcessLoop", "mqtt_processloop_function.html", null ], + [ "MQTT_ReceiveLoop", "mqtt_receiveloop_function.html", null ], + [ "MQTT_GetPacketId", "mqtt_getpacketid_function.html", null ], + [ "MQTT_GetSubAckStatusCodes", "mqtt_getsubackstatuscodes_function.html", null ], + [ "MQTT_Status_strerror", "mqtt_status_strerror_function.html", null ], + [ "MQTT_PublishToResend", "mqtt_publishtoresend_function.html", null ], + [ "MQTT_GetConnectPacketSize", "mqtt_getconnectpacketsize_function.html", null ], + [ "MQTT_SerializeConnect", "mqtt_serializeconnect_function.html", null ], + [ "MQTT_GetSubscribePacketSize", "mqtt_getsubscribepacketsize_function.html", null ], + [ "MQTT_SerializeSubscribe", "mqtt_serializesubscribe_function.html", null ], + [ "MQTT_GetUnsubscribePacketSize", "mqtt_getunsubscribepacketsize_function.html", null ], + [ "MQTT_SerializeUnsubscribe", "mqtt_serializeunsubscribe_function.html", null ], + [ "MQTT_GetPublishPacketSize", "mqtt_getpublishpacketsize_function.html", null ], + [ "MQTT_SerializePublish", "mqtt_serializepublish_function.html", null ], + [ "MQTT_SerializePublishHeader", "mqtt_serializepublishheader_function.html", null ], + [ "MQTT_SerializeAck", "mqtt_serializeack_function.html", null ], + [ "MQTT_GetDisconnectPacketSize", "mqtt_getdisconnectpacketsize_function.html", null ], + [ "MQTT_SerializeDisconnect", "mqtt_serializedisconnect_function.html", null ], + [ "MQTT_GetPingreqPacketSize", "mqtt_getpingreqpacketsize_function.html", null ], + [ "MQTT_SerializePingreq", "mqtt_serializepingreq_function.html", null ], + [ "MQTT_DeserializePublish", "mqtt_deserializepublish_function.html", null ], + [ "MQTT_DeserializeAck", "mqtt_deserializeack_function.html", null ], + [ "MQTT_GetIncomingPacketTypeAndLength", "mqtt_getincomingpackettypeandlength_function.html", null ] +]; \ No newline at end of file diff --git a/v1.3.0/coreMQTT/mqtt_getconnectpacketsize_function.html b/v1.3.0/coreMQTT/mqtt_getconnectpacketsize_function.html new file mode 100644 index 00000000..d6d4bdcd --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_getconnectpacketsize_function.html @@ -0,0 +1,156 @@ + + + + + + + +coreMQTT: MQTT_GetConnectPacketSize + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_GetConnectPacketSize
+
+
+
+
const MQTTPublishInfo_t * pWillInfo,
+
size_t * pRemainingLength,
+
size_t * pPacketSize );
+
MQTTStatus_t MQTT_GetConnectPacketSize(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the size and Remaining Length of an MQTT CONNECT packet.
Definition: core_mqtt_serializer.c:1690
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+

Get the size and Remaining Length of an MQTT CONNECT packet.

+

This function must be called before MQTT_SerializeConnect in order to get the size of the MQTT CONNECT packet that is generated from MQTTConnectInfo_t and optional MQTTPublishInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializeConnect must be at least pPacketSize. The provided pConnectInfo and pWillInfo are valid for serialization with MQTT_SerializeConnect only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + + +
[in]pConnectInfoMQTT CONNECT packet parameters.
[in]pWillInfoLast Will and Testament. Pass NULL if not used.
[out]pRemainingLengthThe Remaining Length of the MQTT CONNECT packet.
[out]pPacketSizeThe total size of the MQTT CONNECT packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
+
// Initialize the connection info, the details are out of scope for this example.
+
initializeConnectInfo( &connectInfo );
+
+
// Initialize the optional will info, the details are out of scope for this example.
+
initializeWillInfo( &willInfo );
+
+
// Get the size requirement for the connect packet.
+ +
&connectInfo, &willInfo, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the connect request.
+
}
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_getdisconnectpacketsize_function.html b/v1.3.0/coreMQTT/mqtt_getdisconnectpacketsize_function.html new file mode 100644 index 00000000..eae578ad --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_getdisconnectpacketsize_function.html @@ -0,0 +1,136 @@ + + + + + + + +coreMQTT: MQTT_GetDisconnectPacketSize + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_GetDisconnectPacketSize
+
+
+
+
MQTTStatus_t MQTT_GetDisconnectPacketSize(size_t *pPacketSize)
Get the size of an MQTT DISCONNECT packet.
Definition: core_mqtt_serializer.c:2321
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+

Get the size of an MQTT DISCONNECT packet.

+
Parameters
+ + +
[out]pPacketSizeThe size of the MQTT DISCONNECT packet.
+
+
+
Returns
MQTTSuccess, or MQTTBadParameter if pPacketSize is NULL.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
size_t packetSize = 0;
+
+
// Get the size requirement for the disconnect packet.
+
status = MQTT_GetDisconnectPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize == 2 );
+
+
// The application should allocate or use a static #MQTTFixedBuffer_t of
+
// size >= 2 to serialize the disconnect packet.
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_getincomingpackettypeandlength_function.html b/v1.3.0/coreMQTT/mqtt_getincomingpackettypeandlength_function.html new file mode 100644 index 00000000..5ddfdcb4 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_getincomingpackettypeandlength_function.html @@ -0,0 +1,173 @@ + + + + + + + +coreMQTT: MQTT_GetIncomingPacketTypeAndLength + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_GetIncomingPacketTypeAndLength
+
+
+
+
NetworkContext_t * pNetworkContext,
+
MQTTPacketInfo_t * pIncomingPacket );
+
MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength(TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket)
Extract the MQTT packet type and length from incoming packet.
Definition: core_mqtt_serializer.c:2561
+
int32_t(* TransportRecv_t)(NetworkContext_t *pNetworkContext, void *pBuffer, size_t bytesToRecv)
Transport interface for receiving data on the network.
Definition: transport_interface.h:218
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+

Extract the MQTT packet type and length from incoming packet.

+

This function must be called for every incoming packet to retrieve the MQTTPacketInfo_t.type and MQTTPacketInfo_t.remainingLength. A MQTTPacketInfo_t is not valid until this routine has been invoked.

+
Parameters
+ + + + +
[in]readFuncTransport layer read function pointer.
[in]pNetworkContextThe network context pointer provided by the application.
[out]pIncomingPacketPointer to MQTTPacketInfo_t structure. This is where type, remaining length and packet identifier are stored.
+
+
+
Returns
MQTTSuccess on successful extraction of type and length, MQTTBadParameter if pIncomingPacket is invalid, MQTTRecvFailed on transport receive failure, MQTTBadResponse if an invalid packet is read, and MQTTNoDataAvailable if there is nothing to read.
+

Example

// TransportRecv_t function for reading from the network.
+
int32_t socket_recv(
+
NetworkContext_t * pNetworkContext,
+
void * pBuffer,
+
size_t bytesToRecv
+
);
+
// Some context to be used with above transport receive function.
+
NetworkContext_t networkContext;
+
+
// Struct to hold the incoming packet information.
+
MQTTPacketInfo_t incomingPacket;
+ +
int32_t bytesRecvd;
+
// Buffer to hold the remaining data of the incoming packet.
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
// Loop until data is available to be received.
+
do{
+ +
socket_recv,
+
&networkContext,
+
&incomingPacket
+
);
+
} while( status == MQTTNoDataAvailable );
+
+
assert( status == MQTTSuccess );
+
+
// Receive the rest of the incoming packet.
+
assert( incomingPacket.remainingLength <= BUFFER_SIZE );
+
bytesRecvd = socket_recv(
+
&networkContext,
+
( void * ) buffer,
+
incomingPacket.remainingLength
+
);
+
+
// Set the remaining data field.
+
incomingPacket.pRemainingData = buffer;
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
@ MQTTNoDataAvailable
Definition: core_mqtt_serializer.h:95
+
size_t remainingLength
Length of remaining serialized data.
Definition: core_mqtt_serializer.h:258
+
uint8_t * pRemainingData
Remaining serialized data in the MQTT packet.
Definition: core_mqtt_serializer.h:253
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_getpacketid_function.html b/v1.3.0/coreMQTT/mqtt_getpacketid_function.html new file mode 100644 index 00000000..e19987a0 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_getpacketid_function.html @@ -0,0 +1,124 @@ + + + + + + + +coreMQTT: MQTT_GetPacketId + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_GetPacketId
+
+
+
uint16_t MQTT_GetPacketId( MQTTContext_t * pContext );
+
uint16_t MQTT_GetPacketId(MQTTContext_t *pContext)
Get a packet ID that is valid according to the MQTT 3.1.1 spec.
Definition: core_mqtt.c:3172
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+

Get a packet ID that is valid according to the MQTT 3.1.1 spec.

+
Parameters
+ + +
[in]pContextInitialized MQTT context.
+
+
+
Returns
A non-zero number.
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_getpingreqpacketsize_function.html b/v1.3.0/coreMQTT/mqtt_getpingreqpacketsize_function.html new file mode 100644 index 00000000..c04f71b7 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_getpingreqpacketsize_function.html @@ -0,0 +1,136 @@ + + + + + + + +coreMQTT: MQTT_GetPingreqPacketSize + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_GetPingreqPacketSize
+
+
+
MQTTStatus_t MQTT_GetPingreqPacketSize( size_t * pPacketSize );
+
MQTTStatus_t MQTT_GetPingreqPacketSize(size_t *pPacketSize)
Get the size of an MQTT PINGREQ packet.
Definition: core_mqtt_serializer.c:2384
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+

Get the size of an MQTT PINGREQ packet.

+
Parameters
+ + +
[out]pPacketSizeThe size of the MQTT PINGREQ packet.
+
+
+
Returns
MQTTSuccess or MQTTBadParameter if pPacketSize is NULL.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
size_t packetSize = 0;
+
+
// Get the size requirement for the ping request packet.
+
status = MQTT_GetPingreqPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize == 2 );
+
+
// The application should allocate or use a static #MQTTFixedBuffer_t of
+
// size >= 2 to serialize the ping request.
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_getpublishpacketsize_function.html b/v1.3.0/coreMQTT/mqtt_getpublishpacketsize_function.html new file mode 100644 index 00000000..81f48155 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_getpublishpacketsize_function.html @@ -0,0 +1,159 @@ + + + + + + + +coreMQTT: MQTT_GetPublishPacketSize + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_GetPublishPacketSize
+
+
+
+
size_t * pRemainingLength,
+
size_t * pPacketSize );
+
MQTTStatus_t MQTT_GetPublishPacketSize(const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the packet size and remaining length of an MQTT PUBLISH packet.
Definition: core_mqtt_serializer.c:2057
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+

Get the packet size and remaining length of an MQTT PUBLISH packet.

+

This function must be called before MQTT_SerializePublish in order to get the size of the MQTT PUBLISH packet that is generated from MQTTPublishInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializePublish must be at least pPacketSize. The provided pPublishInfo is valid for serialization with MQTT_SerializePublish only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[out]pRemainingLengthThe Remaining Length of the MQTT PUBLISH packet.
[out]pPacketSizeThe total size of the MQTT PUBLISH packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec or if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
+
// Initialize the publish info.
+
publishInfo.qos = MQTTQoS0;
+
publishInfo.pTopicName = "/some/topic/name";
+
publishInfo.topicNameLength = strlen( publishInfo.pTopicName );
+
publishInfo.pPayload = "Hello World!";
+
publishInfo.payloadLength = strlen( "Hello World!" );
+
+
// Get the size requirement for the publish packet.
+ +
&publishInfo, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the publish.
+
}
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
@ MQTTQoS0
Definition: core_mqtt_serializer.h:110
+
MQTTQoS_t qos
Quality of Service for message.
Definition: core_mqtt_serializer.h:206
+
uint16_t topicNameLength
Length of topic name.
Definition: core_mqtt_serializer.h:226
+
size_t payloadLength
Message payload length.
Definition: core_mqtt_serializer.h:236
+
const char * pTopicName
Topic name on which the message is published.
Definition: core_mqtt_serializer.h:221
+
const void * pPayload
Message payload.
Definition: core_mqtt_serializer.h:231
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_getsubackstatuscodes_function.html b/v1.3.0/coreMQTT/mqtt_getsubackstatuscodes_function.html new file mode 100644 index 00000000..167b5ae3 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_getsubackstatuscodes_function.html @@ -0,0 +1,199 @@ + + + + + + + +coreMQTT: MQTT_GetSubAckStatusCodes + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_GetSubAckStatusCodes
+
+
+
+
uint8_t ** pPayloadStart,
+
size_t * pPayloadSize );
+
MQTTStatus_t MQTT_GetSubAckStatusCodes(const MQTTPacketInfo_t *pSubackPacket, uint8_t **pPayloadStart, size_t *pPayloadSize)
Parses the payload of an MQTT SUBACK packet that contains status codes corresponding to topic filter ...
Definition: core_mqtt.c:3270
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+

Parses the payload of an MQTT SUBACK packet that contains status codes corresponding to topic filter subscription requests from the original subscribe packet.

+

Each return code in the SUBACK packet corresponds to a topic filter in the SUBSCRIBE Packet being acknowledged. The status codes can be one of the following:

    +
  • 0x00 - Success - Maximum QoS 0
  • +
  • 0x01 - Success - Maximum QoS 1
  • +
  • 0x02 - Success - Maximum QoS 2
  • +
  • 0x80 - Failure Refer to MQTTSubAckStatus_t for the status codes.
  • +
+
Parameters
+ + + + +
[in]pSubackPacketThe SUBACK packet whose payload is to be parsed.
[out]pPayloadStartThis is populated with the starting address of the payload (or return codes for topic filters) in the SUBACK packet.
[out]pPayloadSizeThis is populated with the size of the payload in the SUBACK packet. It represents the number of topic filters whose SUBACK status is present in the packet.
+
+
+
Returns
Returns one of the following: +
+

Example

// Global variable used in this example.
+
// This is assumed to be the subscription list in the original SUBSCRIBE packet.
+
MQTTSubscribeInfo_t pSubscribes[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// MQTT_GetSubAckStatusCodes is intended to be used from the application
+
// callback that is called by the library in MQTT_ProcessLoop or MQTT_ReceiveLoop.
+
void eventCallback(
+
MQTTContext_t * pContext,
+
MQTTPacketInfo_t * pPacketInfo,
+
MQTTDeserializedInfo_t * pDeserializedInfo
+
)
+
{
+ +
uint8_t * pCodes;
+
size_t numCodes;
+
+
if( pPacketInfo->type == MQTT_PACKET_TYPE_SUBACK )
+
{
+
status = MQTT_GetSubAckStatusCodes( pPacketInfo, &pCodes, &numCodes );
+
+
// Since the pointers to the payload and payload size are not NULL, and
+
// we use the packet info struct passed to the app callback (verified
+
// to be valid by the library), this function must return success.
+
assert( status == MQTTSuccess );
+
// The server must send a response code for each topic filter in the
+
// original SUBSCRIBE packet.
+
assert( numCodes == NUMBER_OF_SUBSCRIPTIONS );
+
+
for( int i = 0; i < numCodes; i++ )
+
{
+
// The only failure code is 0x80 = MQTTSubAckFailure.
+
if( pCodes[ i ] == MQTTSubAckFailure )
+
{
+
// The subscription failed, we may want to retry the
+
// subscription in pSubscribes[ i ] outside of this callback.
+
}
+
else
+
{
+
// The subscription was granted, but the maximum QoS may be
+
// lower than what was requested. We can verify the granted QoS.
+
if( pSubscribes[ i ].qos != pCodes[ i ] )
+
{
+ +
"Requested QoS %u, but granted QoS %u for %s",
+
pSubscribes[ i ].qos, pCodes[ i ], pSubscribes[ i ].pTopicFilter
+
) );
+
}
+
}
+
}
+
}
+
// Handle other packet types.
+
}
+
#define LogWarn(message)
Macro that is called in the MQTT library for logging "Warning" level messages.
Definition: core_mqtt_config_defaults.h:235
+
#define MQTT_PACKET_TYPE_SUBACK
SUBACK (server-to-client).
Definition: core_mqtt_serializer.h:61
+
@ MQTTSubAckFailure
Failure.
Definition: core_mqtt.h:154
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
Struct to hold deserialized packet information for an MQTTEventCallback_t callback.
Definition: core_mqtt.h:257
+
uint8_t type
Type of incoming MQTT packet.
Definition: core_mqtt_serializer.h:248
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_getsubscribepacketsize_function.html b/v1.3.0/coreMQTT/mqtt_getsubscribepacketsize_function.html new file mode 100644 index 00000000..d150cad6 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_getsubscribepacketsize_function.html @@ -0,0 +1,163 @@ + + + + + + + +coreMQTT: MQTT_GetSubscribePacketSize + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_GetSubscribePacketSize
+
+
+
+
size_t subscriptionCount,
+
size_t * pRemainingLength,
+
size_t * pPacketSize );
+
MQTTStatus_t MQTT_GetSubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.
Definition: core_mqtt_serializer.c:1848
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+

Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.

+

This function must be called before MQTT_SerializeSubscribe in order to get the size of the MQTT SUBSCRIBE packet that is generated from the list of MQTTSubscribeInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializeSubscribe must be at least pPacketSize. The provided pSubscriptionList is valid for serialization with MQTT_SerializeSubscribe only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[out]pRemainingLengthThe Remaining Length of the MQTT SUBSCRIBE packet.
[out]pPacketSizeThe total size of the MQTT SUBSCRIBE packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
// This is assumed to be a list of filters we want to subscribe to.
+
const char * filters[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// Set each subscription.
+
for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )
+
{
+
subscriptionList[ i ].qos = MQTTQoS0;
+
// Each subscription needs a topic filter.
+
subscriptionList[ i ].pTopicFilter = filters[ i ];
+
subscriptionList[ i ].topicFilterLength = strlen( filters[ i ] );
+
}
+
+
// Get the size requirement for the subscribe packet.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the subscribe request.
+
}
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
@ MQTTQoS0
Definition: core_mqtt_serializer.h:110
+
MQTTQoS_t qos
Quality of Service for subscription.
Definition: core_mqtt_serializer.h:184
+
uint16_t topicFilterLength
Length of subscription topic filter.
Definition: core_mqtt_serializer.h:194
+
const char * pTopicFilter
Topic filter to subscribe to.
Definition: core_mqtt_serializer.h:189
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_getunsubscribepacketsize_function.html b/v1.3.0/coreMQTT/mqtt_getunsubscribepacketsize_function.html new file mode 100644 index 00000000..daaa13ae --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_getunsubscribepacketsize_function.html @@ -0,0 +1,151 @@ + + + + + + + +coreMQTT: MQTT_GetUnsubscribePacketSize + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_GetUnsubscribePacketSize
+
+
+
+
size_t subscriptionCount,
+
size_t * pRemainingLength,
+
size_t * pPacketSize );
+
MQTTStatus_t MQTT_GetUnsubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.
Definition: core_mqtt_serializer.c:1978
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+

Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.

+

This function must be called before MQTT_SerializeUnsubscribe in order to get the size of the MQTT UNSUBSCRIBE packet that is generated from the list of MQTTSubscribeInfo_t. The size of the MQTTFixedBuffer_t supplied to MQTT_SerializeUnsubscribe must be at least pPacketSize. The provided pSubscriptionList is valid for serialization with MQTT_SerializeUnsubscribe only if this function returns MQTTSuccess. The remaining length returned in pRemainingLength and the packet size returned in pPacketSize are valid only if this function returns MQTTSuccess.

+
Parameters
+ + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[out]pRemainingLengthThe Remaining Length of the MQTT UNSUBSCRIBE packet.
[out]pPacketSizeThe total size of the MQTT UNSUBSCRIBE packet.
+
+
+
Returns
MQTTBadParameter if the packet would exceed the size allowed by the MQTT spec; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
size_t remainingLength = 0, packetSize = 0;
+
+
// Initialize the subscribe info. The details are out of scope for this example.
+
initializeSubscribeInfo( &subscriptionList[ 0 ] );
+
+
// Get the size requirement for the unsubscribe packet.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The application should allocate or use a static #MQTTFixedBuffer_t
+
// of size >= packetSize to serialize the unsubscribe request.
+
}
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_init_function.html b/v1.3.0/coreMQTT/mqtt_init_function.html new file mode 100644 index 00000000..2a55121f --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_init_function.html @@ -0,0 +1,188 @@ + + + + + + + +coreMQTT: MQTT_Init + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_Init
+
+
+
+
const TransportInterface_t * pTransportInterface,
+
MQTTGetCurrentTimeFunc_t getTimeFunction,
+
MQTTEventCallback_t userCallback,
+
const MQTTFixedBuffer_t * pNetworkBuffer );
+
MQTTStatus_t MQTT_Init(MQTTContext_t *pContext, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getTimeFunction, MQTTEventCallback_t userCallback, const MQTTFixedBuffer_t *pNetworkBuffer)
Initialize an MQTT context.
Definition: core_mqtt.c:2531
+
void(* MQTTEventCallback_t)(struct MQTTContext *pContext, struct MQTTPacketInfo *pPacketInfo, struct MQTTDeserializedInfo *pDeserializedInfo)
Application callback for receiving incoming publishes and incoming acks.
Definition: core_mqtt.h:100
+
uint32_t(* MQTTGetCurrentTimeFunc_t)(void)
Application provided function to query the time elapsed since a given epoch in milliseconds.
Definition: core_mqtt.h:85
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
The transport layer interface.
Definition: transport_interface.h:299
+

Initialize an MQTT context.

+

This function must be called on an MQTTContext_t before any other function.

+
Note
The MQTTGetCurrentTimeFunc_t function for querying time must be defined. If there is no time implementation, it is the responsibility of the application to provide a dummy function to always return 0, provide 0 timeouts for all calls to MQTT_Connect, MQTT_ProcessLoop, and MQTT_ReceiveLoop and configure the MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS configurations to be 0. This will result in loop functions running for a single iteration, and MQTT_Connect relying on MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT to receive the CONNACK packet.
+
Parameters
+ + + + + + +
[in]pContextThe context to initialize.
[in]pTransportInterfaceThe transport interface to use with the context.
[in]getTimeFunctionThe time utility function which can return the amount of time (in milliseconds) elapsed since a given epoch. This function will be used to ensure that timeouts in the API calls are met and keep-alive messages are sent on time.
[in]userCallbackThe user callback to use with the context to notify about incoming packet events.
[in]pNetworkBufferNetwork buffer provided for the context. This buffer will be used to receive incoming messages from the broker. This buffer must remain valid and in scope for the entire lifetime of the pContext and must not be used by another context and/or application.
+
+
+
Returns
MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Function for obtaining a timestamp.
+
uint32_t getTimeStampMs();
+
// Callback function for receiving packets.
+
void eventCallback(
+
MQTTContext_t * pContext,
+
MQTTPacketInfo_t * pPacketInfo,
+
MQTTDeserializedInfo_t * pDeserializedInfo
+
);
+
// Network send.
+
int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
+
// Network receive.
+
int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
+
+
MQTTContext_t mqttContext;
+ +
MQTTFixedBuffer_t fixedBuffer;
+
// Create a globally accessible buffer which remains in scope for the entire duration
+
// of the MQTT context.
+
uint8_t buffer[ 1024 ];
+
+
// Clear context.
+
memset( ( void * ) &mqttContext, 0x00, sizeof( MQTTContext_t ) );
+
+
// Set transport interface members.
+
transport.pNetworkContext = &someTransportContext;
+
transport.send = networkSend;
+
transport.recv = networkRecv;
+
+
// Set buffer members.
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = 1024;
+
+
status = MQTT_Init( &mqttContext, &transport, getTimeStampMs, eventCallback, &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// Do something with mqttContext. The transport and fixedBuffer structs were
+
// copied into the context, so the original structs do not need to stay in scope.
+
// However, the memory pointed to by the fixedBuffer.pBuffer must remain in scope.
+
}
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
+
Struct to hold deserialized packet information for an MQTTEventCallback_t callback.
Definition: core_mqtt.h:257
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
MQTT incoming packet parameters.
Definition: core_mqtt_serializer.h:244
+
TransportSend_t send
Definition: transport_interface.h:301
+
TransportRecv_t recv
Definition: transport_interface.h:300
+
NetworkContext_t * pNetworkContext
Definition: transport_interface.h:303
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_ping_function.html b/v1.3.0/coreMQTT/mqtt_ping_function.html new file mode 100644 index 00000000..21d995fb --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_ping_function.html @@ -0,0 +1,125 @@ + + + + + + + +coreMQTT: MQTT_Ping + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_Ping
+
+
+
+
MQTTStatus_t MQTT_Ping(MQTTContext_t *pContext)
Sends an MQTT PINGREQ to broker.
Definition: core_mqtt.c:2922
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+

Sends an MQTT PINGREQ to broker.

+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Returns
MQTTNoMemory if pBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_porting.html b/v1.3.0/coreMQTT/mqtt_porting.html new file mode 100644 index 00000000..c76bccd7 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_porting.html @@ -0,0 +1,161 @@ + + + + + + + +coreMQTT: Porting Guide + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Porting Guide
+
+
+

Guide for porting MQTT to a new platform.

+

A port to a new platform must provide the following components:

    +
  1. Configuration Macros
  2. +
  3. Transport Interface
  4. +
  5. Time Function
  6. +
+

+Configuration Macros

+

Settings that must be set as macros in the config header core_mqtt_config.h, or passed in as compiler options.

+
Note
If a custom configuration header core_mqtt_config.h is not provided, then the MQTT_DO_NOT_USE_CUSTOM_CONFIG macro must be defined.
+
See also
Configurations
+

The following macros can be configured for the managed MQTT library:

+

In addition, the following logging macros are used throughout the library:

+

+Transport Interface

+

The MQTT library relies on an underlying transport interface API that must be implemented in order to send and receive packets on a network.

+
See also
Transport Interface
+

The transport interface API used by MQTT is defined in transport_interface.h. A port must implement functions corresponding to the following functions pointers:

    +
  • Transport Receive: A function to receive bytes from a network.
    int32_t (* TransportRecv_t )(
    +
    NetworkContext_t * pNetworkContext, void * pBuffer, size_t bytesToRecv
    +
    );
    +
    int32_t(* TransportRecv_t)(NetworkContext_t *pNetworkContext, void *pBuffer, size_t bytesToRecv)
    Transport interface for receiving data on the network.
    Definition: transport_interface.h:218
    +
    struct NetworkContext NetworkContext_t
    The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
    Definition: transport_interface.h:191
    +
  • +
  • Transport Send: A function to send bytes over a network.
    int32_t (* TransportSend_t )(
    +
    NetworkContext_t * pNetworkContext, const void * pBuffer, size_t bytesToSend
    +
    );
    +
    int32_t(* TransportSend_t)(NetworkContext_t *pNetworkContext, const void *pBuffer, size_t bytesToSend)
    Transport interface for sending data over the network.
    Definition: transport_interface.h:240
    +
  • +
+

The above two functions take in a pointer to a NetworkContext_t, the typename of a struct NetworkContext. The NetworkContext struct must also be defined by the port, and ought to contain any information necessary to send and receive data with the TransportSend_t and TransportRecv_t implementations, respectively:

struct NetworkContext {
+
// Fields necessary for the transport implementations, e.g. a TCP socket descriptor.
+
};
+

+Time Function

+

The MQTT library relies on a function to generate millisecond timestamps, for the purpose of calculating durations and timeouts, as well as maintaining the keep-alive mechanism of the MQTT protocol.

+
See also
MQTTGetCurrentTimeFunc_t
+

Platforms must supply a function capable of generating 32 bit timestamps of millisecond resolution. These timestamps need not correspond with any real world clock; the only requirement is that the difference between two timestamps must be an accurate representation of the duration between them, in milliseconds.

+
Note
Should the platform be incapable of providing millisecond timestamps, the port may instead provide a function that always returns 0, or a strictly non-decreasing sequence. In this case, the timeout values in all library calls to MQTT_Connect, MQTT_ProcessLoop, or MQTT_ReceiveLoop MUST be set to 0, resulting in loop functions running for a single iteration, and MQTT_Connect relying on MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT to receive the CONNACK packet.
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_processloop_design.png b/v1.3.0/coreMQTT/mqtt_processloop_design.png new file mode 100644 index 0000000000000000000000000000000000000000..cffe3d256ea929745f39d1ecb10d2e265a7a1a03 GIT binary patch literal 274031 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

xnIuuoK)`Bba{X>{i#+{otHQQ-fa_@C3|Yj7 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%0DT<;70{JJZgd({;A;l&<-jrue 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

%!#fRjvh86cG_nQ9!DQ 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 literal 0 HcmV?d00001 diff --git a/v1.3.0/coreMQTT/mqtt_processloop_function.html b/v1.3.0/coreMQTT/mqtt_processloop_function.html new file mode 100644 index 00000000..d01ebe9b --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_processloop_function.html @@ -0,0 +1,148 @@ + + + + + + + +coreMQTT: MQTT_ProcessLoop + + + + + + + + + + + + + + + +

+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_ProcessLoop
+
+
+
+
MQTTStatus_t MQTT_ProcessLoop(MQTTContext_t *pContext)
Loop to receive packets from the transport interface. Handles keep alive.
Definition: core_mqtt.c:3119
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+

Loop to receive packets from the transport interface. Handles keep alive.

+
Note
If a dummy timer function, MQTTGetCurrentTimeFunc_t, is passed to the library, then the keep-alive mechanism is not supported by the MQTT_ProcessLoop API. In that case, the MQTT_ReceiveLoop API function should be used instead.
+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Note
Calling this function blocks the calling context for a time period that depends on the passed the configuration macros, MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS, and the underlying transport interface implementation timeouts, unless an error occurs. The blocking period also depends on the execution time of the MQTTEventCallback_t callback supplied to the library. It is recommended that the supplied MQTTEventCallback_t callback does not contain blocking operations to prevent potential non-deterministic blocking period of the MQTT_ProcessLoop API call.
+
Returns
MQTTBadParameter if context is NULL; MQTTRecvFailed if a network error occurs during reception; MQTTSendFailed if a network error occurs while sending an ACK or PINGREQ; MQTTBadResponse if an invalid packet is received; MQTTKeepAliveTimeout if the server has not sent a PINGRESP before MQTT_PINGRESP_TIMEOUT_MS milliseconds; MQTTIllegalState if an incoming QoS 1/2 publish or ack causes an invalid transition for the internal state machine; MQTTNeedMoreBytes if MQTT_ProcessLoop has received incomplete data; it should be called again (probably after a delay); MQTTSuccess on success.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
+
while( true )
+
{
+
status = MQTT_ProcessLoop( pContext );
+
+
if( status != MQTTSuccess && status != MQTTNeedMoreBytes )
+
{
+
// Determine the error. It's possible we might need to disconnect
+
// the underlying transport connection.
+
}
+
else
+
{
+
// Other application functions.
+
}
+
}
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
@ MQTTNeedMoreBytes
Definition: core_mqtt_serializer.h:99
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_publish_function.html b/v1.3.0/coreMQTT/mqtt_publish_function.html new file mode 100644 index 00000000..170f1865 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_publish_function.html @@ -0,0 +1,162 @@ + + + + + + + +coreMQTT: MQTT_Publish + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_Publish
+
+
+
+
const MQTTPublishInfo_t * pPublishInfo,
+
uint16_t packetId );
+
MQTTStatus_t MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId)
Publishes a message to the given topic name.
Definition: core_mqtt.c:2805
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+

Publishes a message to the given topic name.

+
Parameters
+ + + + +
[in]pContextInitialized MQTT context.
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
+
+
+
Returns
MQTTNoMemory if pBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo;
+
uint16_t packetId;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
+
// QoS of publish.
+
publishInfo.qos = MQTTQoS1;
+
publishInfo.pTopicName = "/some/topic/name";
+
publishInfo.topicNameLength = strlen( publishInfo.pTopicName );
+
publishInfo.pPayload = "Hello World!";
+
publishInfo.payloadLength = strlen( "Hello World!" );
+
+
// Packet ID is needed for QoS > 0.
+
packetId = MQTT_GetPacketId( pContext );
+
+
status = MQTT_Publish( pContext, &publishInfo, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// Since the QoS is > 0, we will need to call MQTT_ReceiveLoop()
+
// or MQTT_ProcessLoop() to process the publish acknowledgments.
+
}
+
uint16_t MQTT_GetPacketId(MQTTContext_t *pContext)
Get a packet ID that is valid according to the MQTT 3.1.1 spec.
Definition: core_mqtt.c:3172
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
@ MQTTQoS1
Definition: core_mqtt_serializer.h:111
+
MQTTQoS_t qos
Quality of Service for message.
Definition: core_mqtt_serializer.h:206
+
uint16_t topicNameLength
Length of topic name.
Definition: core_mqtt_serializer.h:226
+
size_t payloadLength
Message payload length.
Definition: core_mqtt_serializer.h:236
+
const char * pTopicName
Topic name on which the message is published.
Definition: core_mqtt_serializer.h:221
+
const void * pPayload
Message payload.
Definition: core_mqtt_serializer.h:231
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_publishtoresend_function.html b/v1.3.0/coreMQTT/mqtt_publishtoresend_function.html new file mode 100644 index 00000000..cdc9ba65 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_publishtoresend_function.html @@ -0,0 +1,189 @@ + + + + + + + +coreMQTT: MQTT_PublishToResend + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_PublishToResend
+
+
+
uint16_t MQTT_PublishToResend( const MQTTContext_t * pMqttContext,
+
MQTTStateCursor_t * pCursor );
+
uint16_t MQTT_PublishToResend(const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor)
Get the packet ID of next pending publish to be resent.
Definition: core_mqtt_state.c:1123
+
size_t MQTTStateCursor_t
Cursor for iterating through state records.
Definition: core_mqtt_state.h:51
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+

Get the packet ID of next pending publish to be resent.

+

This function will need to be called to get the packet for which a publish need to be sent when a session is reestablished. Calling this function repeatedly until packet id is 0 will give all the packets for which a publish need to be resent in the correct order.

+
Parameters
+ + + +
[in]pMqttContextInitialized MQTT context.
[in,out]pCursorIndex at which to start searching.
+
+
+

Example

// For this example assume this function returns an outgoing unacknowledged
+
// QoS 1 or 2 publish from its packet identifier.
+
MQTTPublishInfo_t * getPublish( uint16_t packetID );
+
+
// Variables used in this example.
+
MQTTStatus_t status;
+ +
bool sessionPresent;
+
uint16_t packetID;
+
MQTTPublishInfo_t * pResendPublish = NULL;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
+
// This is assumed to have been initialized before the call to MQTT_Connect().
+
MQTTContext_t * pContext;
+
+
// Set clean session to false to attempt session resumption.
+
connectInfo.cleanSession = false;
+
connectInfo.pClientIdentifier = "someClientID";
+
connectInfo.clientIdentifierLength = strlen( connectInfo.pClientIdentifier );
+
connectInfo.keepAliveSeconds = 60;
+
// Optional connect parameters are not relevant to this example.
+
+
// Create an MQTT connection. Use 100 milliseconds as a timeout.
+
status = MQTT_Connect( pContext, &connectInfo, NULL, 100, &sessionPresent );
+
+
if( status == MQTTSuccess )
+
{
+
if( sessionPresent )
+
{
+
// Loop while packet ID is nonzero.
+
while( ( packetID = MQTT_PublishToResend( pContext, &cursor ) ) != 0 )
+
{
+
// Assume this function will succeed.
+
pResendPublish = getPublish( packetID );
+
// Set DUP flag.
+
pResendPublish->dup = true;
+
status = MQTT_Publish( pContext, pResendPublish, packetID );
+
+
if( status != MQTTSuccess )
+
{
+
// Application can decide how to handle a failure.
+
}
+
}
+
}
+
else
+
{
+
// The broker did not resume a session, so we can clean up the
+
// list of outgoing publishes.
+
}
+
}
+
MQTTStatus_t MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId)
Publishes a message to the given topic name.
Definition: core_mqtt.c:2805
+
MQTTStatus_t MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
Establish an MQTT session.
Definition: core_mqtt.c:2679
+
#define MQTT_STATE_CURSOR_INITIALIZER
Initializer value for an MQTTStateCursor_t, indicating a search should start at the beginning of a st...
Definition: core_mqtt_state.h:45
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
const char * pClientIdentifier
MQTT client identifier. Must be unique per client.
Definition: core_mqtt_serializer.h:147
+
bool cleanSession
Whether to establish a new, clean session or resume a previous session.
Definition: core_mqtt_serializer.h:137
+
uint16_t keepAliveSeconds
MQTT keep alive period.
Definition: core_mqtt_serializer.h:142
+
uint16_t clientIdentifierLength
Length of the client identifier.
Definition: core_mqtt_serializer.h:152
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+
bool dup
Whether this is a duplicate publish message.
Definition: core_mqtt_serializer.h:216
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_receiveloop_design.png b/v1.3.0/coreMQTT/mqtt_receiveloop_design.png new file mode 100644 index 0000000000000000000000000000000000000000..d86b72b52b98ffa0bb248a6d0f7ca901d4b4ed1a GIT binary patch literal 241200 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%0DChF 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

AJbk6ytfS-5=xW)9c_ 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�Q-f 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

vQf0XS@L6fJ?`Ydut37KYYj>x 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 E0F#nHf&c&j literal 0 HcmV?d00001 diff --git a/v1.3.0/coreMQTT/mqtt_receiveloop_function.html b/v1.3.0/coreMQTT/mqtt_receiveloop_function.html new file mode 100644 index 00000000..57e9a025 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_receiveloop_function.html @@ -0,0 +1,159 @@ + + + + + + + +coreMQTT: MQTT_ReceiveLoop + + + + + + + + + + + + + + + +

+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_ReceiveLoop
+
+
+
+
MQTTStatus_t MQTT_ReceiveLoop(MQTTContext_t *pContext)
Loop to receive packets from the transport interface. Does not handle keep alive.
Definition: core_mqtt.c:3146
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+

Loop to receive packets from the transport interface. Does not handle keep alive.

+
Note
If a dummy MQTTGetCurrentTimeFunc_t was passed to MQTT_Init, then the MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS timeout configurations MUST be set to 0.
+
Parameters
+ + +
[in]pContextInitialized and connected MQTT context.
+
+
+
Note
Calling this function blocks the calling context for a time period that depends on the the configuration macros, MQTT_RECV_POLLING_TIMEOUT_MS and MQTT_SEND_TIMEOUT_MS, and the underlying transport interface implementation timeouts, unless an error occurs. The blocking period also depends on the execution time of the MQTTEventCallback_t callback supplied to the library. It is recommended that the supplied MQTTEventCallback_t callback does not contain blocking operations to prevent potential non-deterministic blocking period of the MQTT_ReceiveLoop API call.
+
Returns
MQTTBadParameter if context is NULL; MQTTRecvFailed if a network error occurs during reception; MQTTSendFailed if a network error occurs while sending an ACK or PINGREQ; MQTTBadResponse if an invalid packet is received; MQTTIllegalState if an incoming QoS 1/2 publish or ack causes an invalid transition for the internal state machine; MQTTNeedMoreBytes if MQTT_ReceiveLoop has received incomplete data; it should be called again (probably after a delay); MQTTSuccess on success.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
uint32_t keepAliveMs = 60 * 1000;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
+
while( true )
+
{
+
status = MQTT_ReceiveLoop( pContext );
+
+
if( status != MQTTSuccess && status != MQTTNeedMoreBytes )
+
{
+
// Determine the error. It's possible we might need to disconnect
+
// the underlying transport connection.
+
}
+
else
+
{
+
// Since this function does not send pings, the application may need
+
// to in order to comply with keep alive.
+
if( ( pContext->getTime() - pContext->lastPacketTxTime ) > keepAliveMs )
+
{
+
status = MQTT_Ping( pContext );
+
}
+
+
// Other application functions.
+
}
+
}
+
MQTTStatus_t MQTT_Ping(MQTTContext_t *pContext)
Sends an MQTT PINGREQ to broker.
Definition: core_mqtt.c:2922
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
@ MQTTNeedMoreBytes
Definition: core_mqtt_serializer.h:99
+
uint32_t lastPacketTxTime
Timestamp of the last packet sent by the library.
Definition: core_mqtt.h:227
+
MQTTGetCurrentTimeFunc_t getTime
Function used to get millisecond timestamps.
Definition: core_mqtt.h:217
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_serializeack_function.html b/v1.3.0/coreMQTT/mqtt_serializeack_function.html new file mode 100644 index 00000000..632539c8 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_serializeack_function.html @@ -0,0 +1,159 @@ + + + + + + + +coreMQTT: MQTT_SerializeAck + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_SerializeAck
+
+
+
+
uint8_t packetType,
+
uint16_t packetId );
+
MQTTStatus_t MQTT_SerializeAck(const MQTTFixedBuffer_t *pFixedBuffer, uint8_t packetType, uint16_t packetId)
Serialize an MQTT PUBACK, PUBREC, PUBREL, or PUBCOMP into the given buffer.
Definition: core_mqtt_serializer.c:2266
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+

Serialize an MQTT PUBACK, PUBREC, PUBREL, or PUBCOMP into the given buffer.

+
Parameters
+ + + + +
[out]pFixedBufferBuffer for packet serialization.
[in]packetTypeByte of the corresponding packet fixed header per the MQTT spec.
[in]packetIdPacket ID of the publish.
+
+
+
Returns
MQTTBadParameter, MQTTNoMemory, or MQTTSuccess.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
uint16_t packetId;
+
uint8_t packetType;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
// The fixed buffer must be large enough to hold 4 bytes.
+
assert( BUFFER_SIZE >= MQTT_PUBLISH_ACK_PACKET_SIZE );
+
+
// The packet ID must be the same as the original publish packet.
+
packetId = publishPacketId;
+
+
// The byte representing a packet of type ACK. This function accepts PUBACK, PUBREC, PUBREL, or PUBCOMP.
+ +
+
// Serialize the publish acknowledgment into the fixed buffer.
+
status = MQTT_SerializeAck( &fixedBuffer, packetType, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// The publish acknowledgment can now be sent to the broker.
+
}
+
#define MQTT_PUBLISH_ACK_PACKET_SIZE
The size of MQTT PUBACK, PUBREC, PUBREL, and PUBCOMP packets, per MQTT spec.
Definition: core_mqtt_serializer.h:73
+
#define MQTT_PACKET_TYPE_PUBACK
PUBACK (bidirectional).
Definition: core_mqtt_serializer.h:56
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_serializeconnect_function.html b/v1.3.0/coreMQTT/mqtt_serializeconnect_function.html new file mode 100644 index 00000000..40ea635c --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_serializeconnect_function.html @@ -0,0 +1,164 @@ + + + + + + + +coreMQTT: MQTT_SerializeConnect + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_SerializeConnect
+
+
+
+
const MQTTPublishInfo_t * pWillInfo,
+
size_t remainingLength,
+
const MQTTFixedBuffer_t * pFixedBuffer );
+
MQTTStatus_t MQTT_SerializeConnect(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT CONNECT packet in the given fixed buffer pFixedBuffer.
Definition: core_mqtt_serializer.c:1790
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
MQTT CONNECT packet parameters.
Definition: core_mqtt_serializer.h:133
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+

Serialize an MQTT CONNECT packet in the given fixed buffer pFixedBuffer.

+

MQTT_GetConnectPacketSize should be called with pConnectInfo and pWillInfo before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetConnectPacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetConnectPacketSize.

+
Parameters
+ + + + + +
[in]pConnectInfoMQTT CONNECT packet parameters.
[in]pWillInfoLast Will and Testament. Pass NULL if not used.
[in]remainingLengthRemaining Length provided by MQTT_GetConnectPacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Assume connectInfo and willInfo are initialized. Get the size requirement for
+
// the connect packet.
+ +
&connectInfo, &willInfo, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the connect packet into the fixed buffer.
+
status = MQTT_SerializeConnect( &connectInfo, &willInfo, remainingLength, &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// The connect packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_GetConnectPacketSize(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the size and Remaining Length of an MQTT CONNECT packet.
Definition: core_mqtt_serializer.c:1690
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_serializedisconnect_function.html b/v1.3.0/coreMQTT/mqtt_serializedisconnect_function.html new file mode 100644 index 00000000..9fd8d5c8 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_serializedisconnect_function.html @@ -0,0 +1,150 @@ + + + + + + + +coreMQTT: MQTT_SerializeDisconnect + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_SerializeDisconnect
+
+
+
+
MQTTStatus_t MQTT_SerializeDisconnect(const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT DISCONNECT packet into the given buffer.
Definition: core_mqtt_serializer.c:2341
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+

Serialize an MQTT DISCONNECT packet into the given buffer.

+

The input MQTTFixedBuffer_t.size must be at least as large as the size returned by MQTT_GetDisconnectPacketSize.

+
Parameters
+ + +
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Get the disconnect packet size.
+
status = MQTT_GetDisconnectPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the disconnect into the fixed buffer.
+
status = MQTT_SerializeDisconnect( &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// The disconnect packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_GetDisconnectPacketSize(size_t *pPacketSize)
Get the size of an MQTT DISCONNECT packet.
Definition: core_mqtt_serializer.c:2321
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_serializepingreq_function.html b/v1.3.0/coreMQTT/mqtt_serializepingreq_function.html new file mode 100644 index 00000000..e9d7987e --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_serializepingreq_function.html @@ -0,0 +1,150 @@ + + + + + + + +coreMQTT: MQTT_SerializePingreq + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_SerializePingreq
+
+
+
+
MQTTStatus_t MQTT_SerializePingreq(const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT PINGREQ packet into the given buffer.
Definition: core_mqtt_serializer.c:2404
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+

Serialize an MQTT PINGREQ packet into the given buffer.

+

The input MQTTFixedBuffer_t.size must be at least as large as the size returned by MQTT_GetPingreqPacketSize.

+
Parameters
+ + +
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Get the ping request packet size.
+
status = MQTT_GetPingreqPacketSize( &packetSize );
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the ping request into the fixed buffer.
+
status = MQTT_SerializePingreq( &fixedBuffer );
+
+
if( status == MQTTSuccess )
+
{
+
// The ping request can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_GetPingreqPacketSize(size_t *pPacketSize)
Get the size of an MQTT PINGREQ packet.
Definition: core_mqtt_serializer.c:2384
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_serializepublish_function.html b/v1.3.0/coreMQTT/mqtt_serializepublish_function.html new file mode 100644 index 00000000..f31b6041 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_serializepublish_function.html @@ -0,0 +1,172 @@ + + + + + + + +coreMQTT: MQTT_SerializePublish + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_SerializePublish
+
+
+
+
uint16_t packetId,
+
size_t remainingLength,
+
const MQTTFixedBuffer_t * pFixedBuffer );
+
MQTTStatus_t MQTT_SerializePublish(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT PUBLISH packet in the given buffer.
Definition: core_mqtt_serializer.c:2098
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+

Serialize an MQTT PUBLISH packet in the given buffer.

+

This function will serialize complete MQTT PUBLISH packet into the given buffer. If the PUBLISH payload can be sent separately, consider using MQTT_SerializePublishHeader, which will serialize only the PUBLISH header into the buffer.

+

MQTT_GetPublishPacketSize should be called with pPublishInfo before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetPublishPacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetPublishPacketSize.

+
Parameters
+ + + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetPublishPacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
uint16_t packetId;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// A packet identifier is unused for QoS 0 publishes. Otherwise, a valid, unused packet
+
// identifier must be used.
+
packetId = 0;
+
+
// Assume publishInfo has been initialized. Get publish packet size.
+ +
&publishInfo, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the publish packet into the fixed buffer.
+ +
&publishInfo,
+
packetId,
+
remainingLength,
+
&fixedBuffer
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The publish packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_GetPublishPacketSize(const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the packet size and remaining length of an MQTT PUBLISH packet.
Definition: core_mqtt_serializer.c:2057
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_serializepublishheader_function.html b/v1.3.0/coreMQTT/mqtt_serializepublishheader_function.html new file mode 100644 index 00000000..7da34f54 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_serializepublishheader_function.html @@ -0,0 +1,185 @@ + + + + + + + +coreMQTT: MQTT_SerializePublishHeader + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_SerializePublishHeader
+
+
+
+
uint16_t packetId,
+
size_t remainingLength,
+
const MQTTFixedBuffer_t * pFixedBuffer,
+
size_t * pHeaderSize );
+
MQTTStatus_t MQTT_SerializePublishHeader(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer, size_t *pHeaderSize)
Serialize an MQTT PUBLISH packet header in the given buffer.
Definition: core_mqtt_serializer.c:2183
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
MQTT PUBLISH packet parameters.
Definition: core_mqtt_serializer.h:202
+

Serialize an MQTT PUBLISH packet header in the given buffer.

+

This function serializes PUBLISH header in to the given buffer. The payload for PUBLISH will not be copied over to the buffer. This will help reduce the memory needed for the buffer and avoid an unwanted copy operation of the PUBLISH payload into the buffer. If the payload also would need to be part of the serialized buffer, consider using MQTT_SerializePublish.

+

MQTT_GetPublishPacketSize should be called with pPublishInfo before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetPublishPacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetPublishPacketSize.

+
Parameters
+ + + + + + +
[in]pPublishInfoMQTT PUBLISH packet parameters.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetPublishPacketSize.
[out]pFixedBufferBuffer for packet serialization.
[out]pHeaderSizeSize of the serialized MQTT PUBLISH header.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTPublishInfo_t publishInfo = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0, headerSize = 0;
+
uint16_t packetId;
+
int32_t bytesSent;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// A packet identifier is unused for QoS 0 publishes. Otherwise, a valid, unused packet
+
// identifier must be used.
+
packetId = 0;
+
+
// Assume publishInfo has been initialized. Get the publish packet size.
+ +
&publishInfo, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
// The payload will not be serialized, so the the fixed buffer does not need to hold it.
+
assert( ( packetSize - publishInfo.payloadLength ) <= BUFFER_SIZE );
+
+
// Serialize the publish packet header into the fixed buffer.
+ +
&publishInfo,
+
packetId,
+
remainingLength,
+
&fixedBuffer,
+
&headerSize
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The publish header and payload can now be sent to the broker.
+
// mqttSocket here is a socket descriptor created and connected to the MQTT
+
// broker outside of this function.
+
bytesSent = send( mqttSocket, ( void * ) fixedBuffer.pBuffer, headerSize, 0 );
+
assert( bytesSent == headerSize );
+
bytesSent = send( mqttSocket, publishInfo.pPayload, publishInfo.payloadLength, 0 );
+
assert( bytesSent == publishInfo.payloadLength );
+
}
+
MQTTStatus_t MQTT_GetPublishPacketSize(const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize)
Get the packet size and remaining length of an MQTT PUBLISH packet.
Definition: core_mqtt_serializer.c:2057
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
size_t payloadLength
Message payload length.
Definition: core_mqtt_serializer.h:236
+
const void * pPayload
Message payload.
Definition: core_mqtt_serializer.h:231
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_serializesubscribe_function.html b/v1.3.0/coreMQTT/mqtt_serializesubscribe_function.html new file mode 100644 index 00000000..ca7ad054 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_serializesubscribe_function.html @@ -0,0 +1,174 @@ + + + + + + + +coreMQTT: MQTT_SerializeSubscribe + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_SerializeSubscribe
+
+
+
+
size_t subscriptionCount,
+
uint16_t packetId,
+
size_t remainingLength,
+
const MQTTFixedBuffer_t * pFixedBuffer );
+
MQTTStatus_t MQTT_SerializeSubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT SUBSCRIBE packet in the given buffer.
Definition: core_mqtt_serializer.c:1932
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+

Serialize an MQTT SUBSCRIBE packet in the given buffer.

+

MQTT_GetSubscribePacketSize should be called with pSubscriptionList before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetSubscribePacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetSubscribePacketSize.

+
Parameters
+ + + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetSubscribePacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
uint16_t packetId;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Function to return a valid, unused packet identifier. The details are out of
+
// scope for this example.
+
packetId = getNewPacketId();
+
+
// Assume subscriptionList has been initialized. Get the subscribe packet size.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the subscribe packet into the fixed buffer.
+ +
&subscriptionList[ 0 ],
+
NUMBER_OF_SUBSCRIPTIONS,
+
packetId,
+
remainingLength,
+
&fixedBuffer
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The subscribe packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_GetSubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.
Definition: core_mqtt_serializer.c:1848
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_serializeunsubscribe_function.html b/v1.3.0/coreMQTT/mqtt_serializeunsubscribe_function.html new file mode 100644 index 00000000..19a6d061 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_serializeunsubscribe_function.html @@ -0,0 +1,174 @@ + + + + + + + +coreMQTT: MQTT_SerializeUnsubscribe + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_SerializeUnsubscribe
+
+
+
+
size_t subscriptionCount,
+
uint16_t packetId,
+
size_t remainingLength,
+
const MQTTFixedBuffer_t * pFixedBuffer );
+
MQTTStatus_t MQTT_SerializeUnsubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer)
Serialize an MQTT UNSUBSCRIBE packet in the given buffer.
Definition: core_mqtt_serializer.c:2016
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
Buffer passed to MQTT library.
Definition: core_mqtt_serializer.h:123
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+

Serialize an MQTT UNSUBSCRIBE packet in the given buffer.

+

MQTT_GetUnsubscribePacketSize should be called with pSubscriptionList before invoking this function to get the size of the required MQTTFixedBuffer_t and remainingLength. The remainingLength must be the same as returned by MQTT_GetUnsubscribePacketSize. The MQTTFixedBuffer_t must be at least as large as the size returned by MQTT_GetUnsubscribePacketSize.

+
Parameters
+ + + + + + +
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
[in]remainingLengthRemaining Length provided by MQTT_GetUnsubscribePacketSize.
[out]pFixedBufferBuffer for packet serialization.
+
+
+
Returns
MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ BUFFER_SIZE ];
+
size_t remainingLength = 0, packetSize = 0;
+
uint16_t packetId;
+
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = BUFFER_SIZE;
+
+
// Function to return a valid, unused packet identifier. The details are out of
+
// scope for this example.
+
packetId = getNewPacketId();
+
+
// Assume subscriptionList has been initialized. Get the unsubscribe packet size.
+ +
&subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
+
);
+
assert( status == MQTTSuccess );
+
assert( packetSize <= BUFFER_SIZE );
+
+
// Serialize the unsubscribe packet into the fixed buffer.
+ +
&subscriptionList[ 0 ],
+
NUMBER_OF_SUBSCRIPTIONS,
+
packetId,
+
remainingLength,
+
&fixedBuffer
+
);
+
+
if( status == MQTTSuccess )
+
{
+
// The unsubscribe packet can now be sent to the broker.
+
}
+
MQTTStatus_t MQTT_GetUnsubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize)
Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.
Definition: core_mqtt_serializer.c:1978
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
size_t size
Size of buffer.
Definition: core_mqtt_serializer.h:125
+
uint8_t * pBuffer
Pointer to buffer.
Definition: core_mqtt_serializer.h:124
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_status_strerror_function.html b/v1.3.0/coreMQTT/mqtt_status_strerror_function.html new file mode 100644 index 00000000..5a781bcb --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_status_strerror_function.html @@ -0,0 +1,124 @@ + + + + + + + +coreMQTT: MQTT_Status_strerror + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_Status_strerror
+
+
+
const char * MQTT_Status_strerror( MQTTStatus_t status );
+
const char * MQTT_Status_strerror(MQTTStatus_t status)
Error code to string conversion for MQTT statuses.
Definition: core_mqtt.c:3329
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+

Error code to string conversion for MQTT statuses.

+
Parameters
+ + +
[in]statusThe status to convert to a string.
+
+
+
Returns
The string representation of the status.
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_subscribe_function.html b/v1.3.0/coreMQTT/mqtt_subscribe_function.html new file mode 100644 index 00000000..e7fe3cb9 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_subscribe_function.html @@ -0,0 +1,167 @@ + + + + + + + +coreMQTT: MQTT_Subscribe + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_Subscribe
+
+
+
+
const MQTTSubscribeInfo_t * pSubscriptionList,
+
size_t subscriptionCount,
+
uint16_t packetId );
+
MQTTStatus_t MQTT_Subscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
Sends MQTT SUBSCRIBE for the given list of topic filters to the broker.
Definition: core_mqtt.c:2761
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+

Sends MQTT SUBSCRIBE for the given list of topic filters to the broker.

+
Parameters
+ + + + + +
[in]pContextInitialized MQTT context.
[in]pSubscriptionListArray of MQTT subscription info.
[in]subscriptionCountThe number of elements in @ pSubscriptionList array.
[in]packetIdPacket ID generated by MQTT_GetPacketId.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
uint16_t packetId;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
// This is assumed to be a list of filters we want to subscribe to.
+
const char * filters[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// Set each subscription.
+
for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )
+
{
+
subscriptionList[ i ].qos = MQTTQoS0;
+
// Each subscription needs a topic filter.
+
subscriptionList[ i ].pTopicFilter = filters[ i ];
+
subscriptionList[ i ].topicFilterLength = strlen( filters[ i ] );
+
}
+
+
// Obtain a new packet id for the subscription.
+
packetId = MQTT_GetPacketId( pContext );
+
+
status = MQTT_Subscribe( pContext, &subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// We must now call MQTT_ReceiveLoop() or MQTT_ProcessLoop() to receive the SUBACK.
+
// If the broker accepts the subscription we can now receive publishes
+
// on the requested topics.
+
}
+
uint16_t MQTT_GetPacketId(MQTTContext_t *pContext)
Get a packet ID that is valid according to the MQTT 3.1.1 spec.
Definition: core_mqtt.c:3172
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
@ MQTTQoS0
Definition: core_mqtt_serializer.h:110
+
MQTTQoS_t qos
Quality of Service for subscription.
Definition: core_mqtt_serializer.h:184
+
uint16_t topicFilterLength
Length of subscription topic filter.
Definition: core_mqtt_serializer.h:194
+
const char * pTopicFilter
Topic filter to subscribe to.
Definition: core_mqtt_serializer.h:189
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_timeouts.html b/v1.3.0/coreMQTT/mqtt_timeouts.html new file mode 100644 index 00000000..484f32dc --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_timeouts.html @@ -0,0 +1,159 @@ + + + + + + + +coreMQTT: Timeouts in coreMQTT library + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Timeouts in coreMQTT library
+
+
+

Information about timeouts that coreMQTT library relies on.

+

The coreMQTT library relies on timeouts to handle MQTT keep-alive mechanism and Transport Send and Receive operations. Timeouts must be configured correctly for ensuring the expected behavior of the application using the coreMQTT library. The timeouts and the recommended configurations are listed below.

    +
  1. Transport Send and Receive timeouts
  2. +
  3. MQTT Keep Alive interval
  4. +
  5. MQTT Ping Response timeout
  6. +
  7. MQTT Receive Polling timeout
  8. +
  9. MQTT Send timeout
  10. +
  11. Timeouts for MQTT_ProcessLoop and MQTT_ReceiveLoop APIs
  12. +
  13. Timeout for MQTT_Connect
  14. +
+

+Transport Send and Receive timeouts

+

These are the network send and read operation blocking timeouts used by the implementation of Transport Send and Transport Receive functions, respectively, that are supplied to the coreMQTT library. Transport Send and Receive timeouts must be configured by the application for the Transport interface implementation provided to the coreMQTT library. If it is essential to send more data than the size of the TCP buffer, then the Transport Send timeout can be set to a bigger value than that of cases in which size of the data to be sent is smaller than the TCP buffer, so as to efficiently wait for the TCP buffer to be available to copy the data from MQTT buffers.

+

We recommend using a relatively smaller value for these timeouts as compared to the MQTT Keep Alive interval, so as to make sure that an MQTT Control packet including an MQTT ping request packet can be sent to the Server even within the Keep Alive interval, even if the Transport functions block for the maximum time.

+
See also
Transport Interface
+

+MQTT Keep Alive interval

+

MQTT Keep Alive interval is the maximum time interval that is permitted to elapse between the point at which the MQTT Client finishes transmitting one Control Packet and the point it starts sending the next. If the Server does not receive a Control Packet from the Client within one and a half times the Keep Alive time period, it will disconnect the MQTT connection to the Client.

+

If MQTT_ProcessLoop function is used to manage keep alive in the application, the MQTT Keep Alive interval must be configured to be a value larger than that of the Transport Send and Receive timeouts. This is to make sure that a Control packet including an MQTT ping request packet can be sent to the Server even if the Transport functions block for the maximum time. MQTT Keep Alive interval can be configured by setting the keepAliveIntervalSec member of the MQTTContext_t structure.

+
See also
Keep-Alive
+

+MQTT Ping Response timeout

+

MQTT Ping Response timeout is the time to wait for a ping response to an MQTT ping request as part of the keep-alive mechanism in the MQTT Client. This timeout can be configured independent of the Transport timeouts unlike the MQTT Keep Alive interval, since this timeout only depends on the MQTT broker, the platform and the network latencies.

+

We recommend to choose a ping response timeout by experimenting with an MQTT application on a sample of devices and collecting the data of latency for each ping response from the broker after a ping request is sent. A timeout value can then be chosen based on the statistical measure suitable for the end application, such as 99th percentile or average.

+

MQTT Ping Response timeout can be set by defining the configuration MQTT_PINGRESP_TIMEOUT_MS.

+

+MQTT Receive Polling timeout

+

MQTT Receive Polling timeout is the maximum duration between non-empty network reads while receiving an MQTT packet via the MQTT_ProcessLoop or MQTT_ReceiveLoop API functions. This timeout represents the maximum polling duration that is allowed without any data reception from the network for the incoming packet.

+

It is important to note that having this timeout too short will result in MQTT being disconnected due to the possibility of partial data being received. If you have small TCP buffers and a high latency network, the optimum value for the timeout can be surprisingly long. In such cases, optimum value for the timeout can be better determined based on experimenting the MQTT applications with payloads bigger than the TCP buffer. If a retry is required for a Transport Receive even after hitting a timeout of Transport Receive without any data received, we recommend using a value larger than the Transport Receive timeout. If a dummy implementation of the MQTTGetCurrentTimeFunc_t timer function, that always returns 0, is used, then this timeout must be set to 0.

+

The MQTT Receive Polling timeout can be set by defining the configuration MQTT_RECV_POLLING_TIMEOUT_MS.

+

+MQTT Send timeout

+

MQTT Send timeout is the maximum duration allowed to send an MQTT packet over the transport interface.

+

It is important to note that having this timeout too short will result in MQTT being disconnected due to the possibility of partial data being sent. If you have small TCP buffers and a high latency network, the optimum value for the timeout can be surprisingly long. In such cases, optimum value for the timeout can be better determined based on experimenting the MQTT applications with payloads bigger than the TCP buffer. If a retry is required for a Transport Send even after hitting a timeout of Transport Send before any data could be sent to transport layer, we recommend using a value larger than the Transport Send timeout. If a dummy implementation of the MQTTGetCurrentTimeFunc_t timer function, that always returns 0, is used, then this timeout must be set to 0.

+

The MQTT Send timeout can be set by defining the configuration MQTT_SEND_TIMEOUT_MS.

+

+Timeouts for MQTT_ProcessLoop and MQTT_ReceiveLoop APIs

+

This timeout is passed as an argument to MQTT_ProcessLoop or MQTT_ReceiveLoop API functions. It is the minimum time that the receive loop in these API functions will run, unless an error occurs. These APIs may be blocked for more time than this timeout, since the APIs will attempt to send and receive MQTT packets to the network using the Transport implementation. The maximum time spent on Transport functions for send and receive depends on the Transport Send and Receive timeouts and the MQTT Receive Polling timeouts as explained in the descriptions of these timeouts above.

+

Passing a timeout value of 0 will run these APIs for a single iteration. The other timeouts mentioned thus far ensure you don't disconnect the MQTT just because the network is slow or buffers get full. They are necessary because coreMQTT has no 'memory' of being half way through a packet and will just error and disconnect if you don't give enough time for incoming or outgoing packet delivery. That means, especially in multi-threaded application, the process loop timeout can be zero.

+

MQTT_ProcessLoop API can be used to manage the MQTT keep-alive mechanism and if used, application must invoke this API faster than the MQTT Keep Alive interval. If a dummy MQTTGetCurrentTimeFunc_t was passed to MQTT_Init, then the keep-alive mechanism is not supported by the MQTT_ProcessLoop API; instead the MQTT_ReceiveLoop should be used.

+
See also
Runtime Timeouts passed to MQTT library
+

+Timeout for MQTT_Connect

+

This timeout is passed as an argument to MQTT_Connect. It is the maximum time to wait for an MQTT CONNACK packet. If this value is set to 0, then instead of a time-based loop, it will attempt to call the Transport Receive function up to a maximum number of retries, which is defined by MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT.

+

We recommend to choose a timeout for MQTT_Connect by experimenting with an MQTT application on a sample of devices and collecting the data of latency for each CONNACK packet received from the broker after an MQTT CONNECT packet is sent. A timeout value can then be chosen based on the statistical measure suitable for the end application, such as 99th percentile or average.

+
See also
Runtime Timeouts passed to MQTT library
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_transport_interface.html b/v1.3.0/coreMQTT/mqtt_transport_interface.html new file mode 100644 index 00000000..126fccbc --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_transport_interface.html @@ -0,0 +1,240 @@ + + + + + + + +coreMQTT: Transport Interface + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Transport Interface
+
+
+

The transport interface definition.

+

+Transport Interface Overview

+

The transport interface is a set of APIs that must be implemented using an external transport layer protocol. The transport interface is defined in transport_interface.h. This interface allows protocols like MQTT and HTTP to send and receive data over the transport layer. This interface does not handle connection and disconnection to the server of interest. The connection, disconnection, and other transport settings, like timeout and TLS setup, must be handled in the user application.
+

+

The functions that must be implemented are:
+

+

Each of the functions above take in an opaque context NetworkContext_t. The functions above and the context are also grouped together in the TransportInterface_t structure:
+
+

typedef struct TransportInterface
+
{
+ + + +
NetworkContext_t * pNetworkContext;
+ +
int32_t(* TransportRecv_t)(NetworkContext_t *pNetworkContext, void *pBuffer, size_t bytesToRecv)
Transport interface for receiving data on the network.
Definition: transport_interface.h:218
+
int32_t(* TransportSend_t)(NetworkContext_t *pNetworkContext, const void *pBuffer, size_t bytesToSend)
Transport interface for sending data over the network.
Definition: transport_interface.h:240
+
int32_t(* TransportWritev_t)(NetworkContext_t *pNetworkContext, TransportOutVector_t *pIoVec, size_t ioVecCount)
Transport interface function for "vectored" / scatter-gather based writes. This function is expected ...
Definition: transport_interface.h:288
+
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
+
The transport layer interface.
Definition: transport_interface.h:299
+


+

+

+Implementing the Transport Interface

+

The following steps give guidance on implementing the transport interface:

+
    +
  1. Implementing NetworkContext_t
    +

    +
    struct NetworkContext;
    +
    typedef struct NetworkContext NetworkContext_t;
    +

    + NetworkContext_t is the incomplete type struct NetworkContext. The implemented struct NetworkContext must contain all of the information that is needed to receive and send data with the TransportRecv_t and the TransportSend_t implementations.
    + In the case of TLS over TCP, struct NetworkContext is typically implemented with the TCP socket context and a TLS context.
    +
    + Example code:
    struct NetworkContext
    +
    {
    +
    struct MyTCPSocketContext tcpSocketContext;
    +
    struct MyTLSContext tlsContext;
    +
    };
    +

    +
  2. +
  3. Implementing TransportRecv_t
    +

    +
    typedef int32_t ( * TransportRecv_t )( NetworkContext_t * pNetworkContext,
    +
    void * pBuffer,
    +
    size_t bytesToRecv );
    +

    + This function is expected to populate a buffer, with bytes received from the transport, and return the number of bytes placed in the buffer. In the case of TLS over TCP, TransportRecv_t is typically implemented by calling the TLS layer function to receive data. In case of plaintext TCP without TLS, it is typically implemented by calling the TCP layer receive function. TransportRecv_t may be invoked multiple times by the protocol library, if fewer bytes than were requested to receive are returned.
    +
    + Example code:
    int32_t myNetworkRecvImplementation( NetworkContext_t * pNetworkContext,
    +
    void * pBuffer,
    +
    size_t bytesToRecv )
    +
    {
    +
    int32_t bytesReceived = 0;
    +
    bool callTlsRecvFunc = true;
    +
    +
    // For a single byte read request, check if data is available on the network.
    +
    if( bytesToRecv == 1 )
    +
    {
    +
    // If no data is available on the network, do not call TLSRecv
    +
    // to avoid blocking for socket timeout.
    +
    if( TLSRecvCount( pNetworkContext->tlsContext ) == 0 )
    +
    {
    +
    callTlsRecvFunc = false;
    +
    }
    +
    }
    +
    +
    if( callTlsRecvFunc == true )
    +
    {
    +
    bytesReceived = TLSRecv( pNetworkContext->tlsContext,
    +
    pBuffer,
    +
    bytesToRecv,
    +
    MY_SOCKET_TIMEOUT );
    +
    if( bytesReceived < 0 )
    +
    {
    +
    // If the error code represents a timeout, then the return
    +
    // code should be translated to zero so that the caller
    +
    // can retry the read operation.
    +
    if( bytesReceived == MY_SOCKET_ERROR_TIMEOUT )
    +
    {
    +
    bytesReceived = 0;
    +
    }
    +
    }
    +
    // Handle other cases.
    +
    }
    +
    return bytesReceived;
    +
    }
    +

    +
  4. +
  5. Implementing TransportSend_t
    +

    +
    typedef int32_t ( * TransportSend_t )( NetworkContext_t * pNetworkContext,
    +
    const void * pBuffer,
    +
    size_t bytesToSend );
    +

    + This function is expected to send the bytes, in the given buffer over the transport, and return the number of bytes sent. In the case of TLS over TCP, TransportSend_t is typically implemented by calling the TLS layer function to send data. In case of plaintext TCP without TLS, it is typically implemented by calling the TCP layer send function. TransportSend_t may be invoked multiple times by the protocol library, if fewer bytes than were requested to send are returned.
    +
    + Example code:
    int32_t myNetworkSendImplementation( NetworkContext_t * pNetworkContext,
    +
    const void * pBuffer,
    +
    size_t bytesToSend )
    +
    {
    +
    int32_t bytesSent = 0;
    +
    bytesSent = TLSSend( pNetworkContext->tlsContext,
    +
    pBuffer,
    +
    bytesToSend,
    +
    MY_SOCKET_TIMEOUT );
    +
    +
    // If underlying TCP buffer is full, set the return value to zero
    +
    // so that caller can retry the send operation.
    +
    if( bytesSent == MY_SOCKET_ERROR_BUFFER_FULL )
    +
    {
    +
    bytesSent = 0;
    +
    }
    +
    else if( bytesSent < 0 )
    +
    {
    +
    // Handle socket error.
    +
    }
    +
    // Handle other cases.
    +
    +
    return bytesSent;
    +
    }
    +
  6. +
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/mqtt_unsubscribe_function.html b/v1.3.0/coreMQTT/mqtt_unsubscribe_function.html new file mode 100644 index 00000000..d98acea6 --- /dev/null +++ b/v1.3.0/coreMQTT/mqtt_unsubscribe_function.html @@ -0,0 +1,164 @@ + + + + + + + +coreMQTT: MQTT_Unsubscribe + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTT_Unsubscribe
+
+
+
+
const MQTTSubscribeInfo_t * pSubscriptionList,
+
size_t subscriptionCount,
+
uint16_t packetId );
+
MQTTStatus_t MQTT_Unsubscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId)
Sends MQTT UNSUBSCRIBE for the given list of topic filters to the broker.
Definition: core_mqtt.c:3000
+
MQTTStatus_t
Return codes from MQTT functions.
Definition: core_mqtt_serializer.h:87
+
A struct representing an MQTT connection.
Definition: core_mqtt.h:173
+
MQTT SUBSCRIBE packet parameters.
Definition: core_mqtt_serializer.h:180
+

Sends MQTT UNSUBSCRIBE for the given list of topic filters to the broker.

+
Parameters
+ + + + + +
[in]pContextInitialized MQTT context.
[in]pSubscriptionListList of MQTT subscription info.
[in]subscriptionCountThe number of elements in pSubscriptionList.
[in]packetIdpacket ID generated by MQTT_GetPacketId.
+
+
+
Returns
MQTTNoMemory if the MQTTContext_t.networkBuffer is too small to hold the MQTT packet; MQTTBadParameter if invalid parameters are passed; MQTTSendFailed if transport write failed; MQTTSuccess otherwise.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTSubscribeInfo_t unsubscribeList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
+
uint16_t packetId;
+
// This context is assumed to be initialized and connected.
+
MQTTContext_t * pContext;
+
// This is assumed to be a list of filters we want to unsubscribe from.
+
const char * filters[ NUMBER_OF_SUBSCRIPTIONS ];
+
+
// Set information for each unsubscribe request.
+
for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )
+
{
+
unsubscribeList[ i ].pTopicFilter = filters[ i ];
+
unsubscribeList[ i ].topicFilterLength = strlen( filters[ i ] );
+
+
// The QoS field of MQTT_SubscribeInfo_t is unused for unsubscribing.
+
}
+
+
// Obtain a new packet id for the unsubscribe request.
+
packetId = MQTT_GetPacketId( pContext );
+
+
status = MQTT_Unsubscribe( pContext, &unsubscribeList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, packetId );
+
+
if( status == MQTTSuccess )
+
{
+
// We must now call MQTT_ReceiveLoop() or MQTT_ProcessLoop() to receive the UNSUBACK.
+
// After this the broker should no longer send publishes for these topics.
+
}
+
uint16_t MQTT_GetPacketId(MQTTContext_t *pContext)
Get a packet ID that is valid according to the MQTT 3.1.1 spec.
Definition: core_mqtt.c:3172
+
@ MQTTSuccess
Definition: core_mqtt_serializer.h:88
+
uint16_t topicFilterLength
Length of subscription topic filter.
Definition: core_mqtt_serializer.h:194
+
const char * pTopicFilter
Topic filter to subscribe to.
Definition: core_mqtt_serializer.h:189
+
+
+
+ + + + diff --git a/v1.3.0/coreMQTT/nav_f.png b/v1.3.0/coreMQTT/nav_f.png new file mode 100644 index 0000000000000000000000000000000000000000..72a58a529ed3a9ed6aa0c51a79cf207e026deee2 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI`!2~2XGqLUlQVE_ejv*C{Z|{2ZH7M}7UYxc) zn!W8uqtnIQ>_z8U literal 0 HcmV?d00001 diff --git a/v1.3.0/coreMQTT/nav_fd.png b/v1.3.0/coreMQTT/nav_fd.png new file mode 100644 index 0000000000000000000000000000000000000000..032fbdd4c54f54fa9a2e6423b94ef4b2ebdfaceb GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI`!2~2XGqLUlQU#tajv*C{Z|C~*H7f|XvG1G8 zt7aS*L7xwMeS}!z6R#{C5tIw-s~AJ==F^i}x3XyJseHR@yF& zerFf(Zf;Dd{+(0lDIROL@Sj-Ju2JQ8&-n%4%q?>|^bShc&lR?}7HeMo@BDl5N(aHY Uj$gdr1MOz;boFyt=akR{0D!zeaR2}S literal 0 HcmV?d00001 diff --git a/v1.3.0/coreMQTT/nav_g.png b/v1.3.0/coreMQTT/nav_g.png new file mode 100644 index 0000000000000000000000000000000000000000..2093a237a94f6c83e19ec6e5fd42f7ddabdafa81 GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^j6lrB!3HFm1ilyoDK$?Q$B+ufw|5PB85lU25BhtE tr?otc=hd~V+ws&_A@j8Fiv!KF$B+ufw|5=67#uj90@pIL wZ=Q8~_Ju`#59=RjDrmm`tMD@M=!-l18IR?&vFVdQ&MBb@0HFXL6W-eg#Jd_@e6*DPn)w;=|1H}Zvm9l6xXXB%>yL=NQU;mg M>FVdQ&MBb@0Bdt1Qvd(} literal 0 HcmV?d00001 diff --git a/v1.3.0/coreMQTT/navtree.css b/v1.3.0/coreMQTT/navtree.css new file mode 100644 index 00000000..c8a7766a --- /dev/null +++ b/v1.3.0/coreMQTT/navtree.css @@ -0,0 +1,150 @@ +#nav-tree .children_ul { + margin:0; + padding:4px; +} + +#nav-tree ul { + list-style:none outside none; + margin:0px; + padding:0px; +} + +#nav-tree li { + white-space:nowrap; + margin:0px; + padding:0px; +} + +#nav-tree .plus { + margin:0px; +} + +#nav-tree .selected { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + color: var(--nav-text-active-color); + text-shadow: var(--nav-text-active-shadow); +} + +#nav-tree .selected .arrow { + color: var(--nav-arrow-selected-color); + text-shadow: none; +} + +#nav-tree img { + margin:0px; + padding:0px; + border:0px; + vertical-align: middle; +} + +#nav-tree a { + text-decoration:none; + padding:0px; + margin:0px; + outline:none; +} + +#nav-tree .label { + margin:0px; + padding:0px; + font: 12px var(--font-family-nav); +} + +#nav-tree .label a { + padding:2px; +} + +#nav-tree .selected a { + text-decoration:none; + color:var(--nav-text-active-color); +} + +#nav-tree .children_ul { + margin:0px; + padding:0px; +} + +#nav-tree .item { + margin:0px; + padding:0px; +} + +#nav-tree { + padding: 0px 0px; + font-size:14px; + overflow:auto; +} + +#doc-content { + overflow:auto; + display:block; + padding:0px; + margin:0px; + -webkit-overflow-scrolling : touch; /* iOS 5+ */ +} + +#side-nav { + padding:0 6px 0 0; + margin: 0px; + display:block; + position: absolute; + left: 0px; + width: $width; + overflow : hidden; +} + +.ui-resizable .ui-resizable-handle { + display:block; +} + +.ui-resizable-e { + background-image:var(--nav-splitbar-image); + background-size:100%; + background-repeat:repeat-y; + background-attachment: scroll; + cursor:ew-resize; + height:100%; + right:0; + top:0; + width:6px; +} + +.ui-resizable-handle { + display:none; + font-size:0.1px; + position:absolute; + z-index:1; +} + +#nav-tree-contents { + margin: 6px 0px 0px 0px; +} + +#nav-tree { + background-repeat:repeat-x; + background-color: var(--nav-background-color); + -webkit-overflow-scrolling : touch; /* iOS 5+ */ +} + +#nav-sync { + position:absolute; + top:5px; + right:24px; + z-index:0; +} + +#nav-sync img { + opacity:0.3; +} + +#nav-sync img:hover { + opacity:0.9; +} + +@media print +{ + #nav-tree { display: none; } + div.ui-resizable-handle { display: none; position: relative; } +} + diff --git a/v1.3.0/coreMQTT/navtree.js b/v1.3.0/coreMQTT/navtree.js new file mode 100644 index 00000000..27983687 --- /dev/null +++ b/v1.3.0/coreMQTT/navtree.js @@ -0,0 +1,549 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +var navTreeSubIndices = new Array(); +var arrowDown = '▼'; +var arrowRight = '►'; + +function getData(varName) +{ + var i = varName.lastIndexOf('/'); + var n = i>=0 ? varName.substring(i+1) : varName; + return eval(n.replace(/\-/g,'_')); +} + +function stripPath(uri) +{ + return uri.substring(uri.lastIndexOf('/')+1); +} + +function stripPath2(uri) +{ + var i = uri.lastIndexOf('/'); + var s = uri.substring(i+1); + var m = uri.substring(0,i+1).match(/\/d\w\/d\w\w\/$/); + return m ? uri.substring(i-6) : s; +} + +function hashValue() +{ + return $(location).attr('hash').substring(1).replace(/[^\w\-]/g,''); +} + +function hashUrl() +{ + return '#'+hashValue(); +} + +function pathName() +{ + return $(location).attr('pathname').replace(/[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]/g, ''); +} + +function localStorageSupported() +{ + try { + return 'localStorage' in window && window['localStorage'] !== null && window.localStorage.getItem; + } + catch(e) { + return false; + } +} + +function storeLink(link) +{ + if (!$("#nav-sync").hasClass('sync') && localStorageSupported()) { + window.localStorage.setItem('navpath',link); + } +} + +function deleteLink() +{ + if (localStorageSupported()) { + window.localStorage.setItem('navpath',''); + } +} + +function cachedLink() +{ + if (localStorageSupported()) { + return window.localStorage.getItem('navpath'); + } else { + return ''; + } +} + +function getScript(scriptName,func,show) +{ + var head = document.getElementsByTagName("head")[0]; + var script = document.createElement('script'); + script.id = scriptName; + script.type = 'text/javascript'; + script.onload = func; + script.src = scriptName+'.js'; + head.appendChild(script); +} + +function createIndent(o,domNode,node,level) +{ + var level=-1; + var n = node; + while (n.parentNode) { level++; n=n.parentNode; } + if (node.childrenData) { + var imgNode = document.createElement("span"); + imgNode.className = 'arrow'; + imgNode.style.paddingLeft=(16*level).toString()+'px'; + imgNode.innerHTML=arrowRight; + node.plus_img = imgNode; + node.expandToggle = document.createElement("a"); + node.expandToggle.href = "javascript:void(0)"; + node.expandToggle.onclick = function() { + if (node.expanded) { + $(node.getChildrenUL()).slideUp("fast"); + node.plus_img.innerHTML=arrowRight; + node.expanded = false; + } else { + expandNode(o, node, false, false); + } + } + node.expandToggle.appendChild(imgNode); + domNode.appendChild(node.expandToggle); + } else { + var span = document.createElement("span"); + span.className = 'arrow'; + span.style.width = 16*(level+1)+'px'; + span.innerHTML = ' '; + domNode.appendChild(span); + } +} + +var animationInProgress = false; + +function gotoAnchor(anchor,aname,updateLocation) +{ + var pos, docContent = $('#doc-content'); + var ancParent = $(anchor.parent()); + if (ancParent.hasClass('memItemLeft') || + ancParent.hasClass('memtitle') || + ancParent.hasClass('fieldname') || + ancParent.hasClass('fieldtype') || + ancParent.is(':header')) + { + pos = ancParent.position().top; + } else if (anchor.position()) { + pos = anchor.position().top; + } + if (pos) { + var dist = Math.abs(Math.min( + pos-docContent.offset().top, + docContent[0].scrollHeight- + docContent.height()-docContent.scrollTop())); + animationInProgress=true; + docContent.animate({ + scrollTop: pos + docContent.scrollTop() - docContent.offset().top + },Math.max(50,Math.min(500,dist)),function(){ + if (updateLocation) window.location.href=aname; + animationInProgress=false; + }); + } +} + +function newNode(o, po, text, link, childrenData, lastNode) +{ + var node = new Object(); + node.children = Array(); + node.childrenData = childrenData; + node.depth = po.depth + 1; + node.relpath = po.relpath; + node.isLast = lastNode; + + node.li = document.createElement("li"); + po.getChildrenUL().appendChild(node.li); + node.parentNode = po; + + node.itemDiv = document.createElement("div"); + node.itemDiv.className = "item"; + + node.labelSpan = document.createElement("span"); + node.labelSpan.className = "label"; + + createIndent(o,node.itemDiv,node,0); + node.itemDiv.appendChild(node.labelSpan); + node.li.appendChild(node.itemDiv); + + var a = document.createElement("a"); + node.labelSpan.appendChild(a); + node.label = document.createTextNode(text); + node.expanded = false; + a.appendChild(node.label); + if (link) { + var url; + if (link.substring(0,1)=='^') { + url = link.substring(1); + link = url; + } else { + url = node.relpath+link; + } + a.className = stripPath(link.replace('#',':')); + if (link.indexOf('#')!=-1) { + var aname = '#'+link.split('#')[1]; + var srcPage = stripPath(pathName()); + var targetPage = stripPath(link.split('#')[0]); + a.href = srcPage!=targetPage ? url : "javascript:void(0)"; + a.onclick = function(){ + storeLink(link); + if (!$(a).parent().parent().hasClass('selected')) + { + $('.item').removeClass('selected'); + $('.item').removeAttr('id'); + $(a).parent().parent().addClass('selected'); + $(a).parent().parent().attr('id','selected'); + } + var anchor = $(aname); + gotoAnchor(anchor,aname,true); + }; + } else { + a.href = url; + a.onclick = function() { storeLink(link); } + } + } else { + if (childrenData != null) + { + a.className = "nolink"; + a.href = "javascript:void(0)"; + a.onclick = node.expandToggle.onclick; + } + } + + node.childrenUL = null; + node.getChildrenUL = function() { + if (!node.childrenUL) { + node.childrenUL = document.createElement("ul"); + node.childrenUL.className = "children_ul"; + node.childrenUL.style.display = "none"; + node.li.appendChild(node.childrenUL); + } + return node.childrenUL; + }; + + return node; +} + +function showRoot() +{ + var headerHeight = $("#top").height(); + var footerHeight = $("#nav-path").height(); + var windowHeight = $(window).height() - headerHeight - footerHeight; + (function (){ // retry until we can scroll to the selected item + try { + var navtree=$('#nav-tree'); + navtree.scrollTo('#selected',100,{offset:-windowHeight/2}); + } catch (err) { + setTimeout(arguments.callee, 0); + } + })(); +} + +function expandNode(o, node, imm, showRoot) +{ + if (node.childrenData && !node.expanded) { + if (typeof(node.childrenData)==='string') { + var varName = node.childrenData; + getScript(node.relpath+varName,function(){ + node.childrenData = getData(varName); + expandNode(o, node, imm, showRoot); + }, showRoot); + } else { + if (!node.childrenVisited) { + getNode(o, node); + } + $(node.getChildrenUL()).slideDown("fast"); + node.plus_img.innerHTML = arrowDown; + node.expanded = true; + } + } +} + +function glowEffect(n,duration) +{ + n.addClass('glow').delay(duration).queue(function(next){ + $(this).removeClass('glow');next(); + }); +} + +function highlightAnchor() +{ + var aname = hashUrl(); + var anchor = $(aname); + if (anchor.parent().attr('class')=='memItemLeft'){ + var rows = $('.memberdecls tr[class$="'+hashValue()+'"]'); + glowEffect(rows.children(),300); // member without details + } else if (anchor.parent().attr('class')=='fieldname'){ + glowEffect(anchor.parent().parent(),1000); // enum value + } else if (anchor.parent().attr('class')=='fieldtype'){ + glowEffect(anchor.parent().parent(),1000); // struct field + } else if (anchor.parent().is(":header")) { + glowEffect(anchor.parent(),1000); // section header + } else { + glowEffect(anchor.next(),1000); // normal member + } +} + +function selectAndHighlight(hash,n) +{ + var a; + if (hash) { + var link=stripPath(pathName())+':'+hash.substring(1); + a=$('.item a[class$="'+link+'"]'); + } + if (a && a.length) { + a.parent().parent().addClass('selected'); + a.parent().parent().attr('id','selected'); + highlightAnchor(); + } else if (n) { + $(n.itemDiv).addClass('selected'); + $(n.itemDiv).attr('id','selected'); + } + var topOffset=5; + if (typeof page_layout!=='undefined' && page_layout==1) { + topOffset+=$('#top').outerHeight(); + } + if ($('#nav-tree-contents .item:first').hasClass('selected')) { + topOffset+=25; + } + $('#nav-sync').css('top',topOffset+'px'); + showRoot(); +} + +function showNode(o, node, index, hash) +{ + if (node && node.childrenData) { + if (typeof(node.childrenData)==='string') { + var varName = node.childrenData; + getScript(node.relpath+varName,function(){ + node.childrenData = getData(varName); + showNode(o,node,index,hash); + },true); + } else { + if (!node.childrenVisited) { + getNode(o, node); + } + $(node.getChildrenUL()).css({'display':'block'}); + node.plus_img.innerHTML = arrowDown; + node.expanded = true; + var n = node.children[o.breadcrumbs[index]]; + if (index+11) hash = '#'+parts[1].replace(/[^\w\-]/g,''); + else hash=''; + } + if (hash.match(/^#l\d+$/)) { + var anchor=$('a[name='+hash.substring(1)+']'); + glowEffect(anchor.parent(),1000); // line number + hash=''; // strip line number anchors + } + var url=root+hash; + var i=-1; + while (NAVTREEINDEX[i+1]<=url) i++; + if (i==-1) { i=0; root=NAVTREE[0][1]; } // fallback: show index + if (navTreeSubIndices[i]) { + gotoNode(o,i,root,hash,relpath) + } else { + getScript(relpath+'navtreeindex'+i,function(){ + navTreeSubIndices[i] = eval('NAVTREEINDEX'+i); + if (navTreeSubIndices[i]) { + gotoNode(o,i,root,hash,relpath); + } + },true); + } +} + +function showSyncOff(n,relpath) +{ + n.html(''); +} + +function showSyncOn(n,relpath) +{ + n.html(''); +} + +function toggleSyncButton(relpath) +{ + var navSync = $('#nav-sync'); + if (navSync.hasClass('sync')) { + navSync.removeClass('sync'); + showSyncOff(navSync,relpath); + storeLink(stripPath2(pathName())+hashUrl()); + } else { + navSync.addClass('sync'); + showSyncOn(navSync,relpath); + deleteLink(); + } +} + +var loadTriggered = false; +var readyTriggered = false; +var loadObject,loadToRoot,loadUrl,loadRelPath; + +$(window).on('load',function(){ + if (readyTriggered) { // ready first + navTo(loadObject,loadToRoot,loadUrl,loadRelPath); + showRoot(); + } + loadTriggered=true; +}); + +function initNavTree(toroot,relpath) +{ + var o = new Object(); + o.toroot = toroot; + o.node = new Object(); + o.node.li = document.getElementById("nav-tree-contents"); + o.node.childrenData = NAVTREE; + o.node.children = new Array(); + o.node.childrenUL = document.createElement("ul"); + o.node.getChildrenUL = function() { return o.node.childrenUL; }; + o.node.li.appendChild(o.node.childrenUL); + o.node.depth = 0; + o.node.relpath = relpath; + o.node.expanded = false; + o.node.isLast = true; + o.node.plus_img = document.createElement("span"); + o.node.plus_img.className = 'arrow'; + o.node.plus_img.innerHTML = arrowRight; + + if (localStorageSupported()) { + var navSync = $('#nav-sync'); + if (cachedLink()) { + showSyncOff(navSync,relpath); + navSync.removeClass('sync'); + } else { + showSyncOn(navSync,relpath); + } + navSync.click(function(){ toggleSyncButton(relpath); }); + } + + if (loadTriggered) { // load before ready + navTo(o,toroot,hashUrl(),relpath); + showRoot(); + } else { // ready before load + loadObject = o; + loadToRoot = toroot; + loadUrl = hashUrl(); + loadRelPath = relpath; + readyTriggered=true; + } + + $(window).bind('hashchange', function(){ + if (window.location.hash && window.location.hash.length>1){ + var a; + if ($(location).attr('hash')){ + var clslink=stripPath(pathName())+':'+hashValue(); + a=$('.item a[class$="'+clslink.replace(/1|%O$WD@{VPM$7~Ar*{o?;hlAFyLXmaDC0y znK1_#cQqJWPES%4Uujug^TE?jMft$}Eq^WaR~)%f)vSNs&gek&x%A9X9sM + + + + + + +coreMQTT: Related Pages + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Related Pages
+
+ +
+ + + + diff --git a/v1.3.0/coreMQTT/resize.js b/v1.3.0/coreMQTT/resize.js new file mode 100644 index 00000000..aaeb6fc0 --- /dev/null +++ b/v1.3.0/coreMQTT/resize.js @@ -0,0 +1,155 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +var once=1; +function initResizable() +{ + var cookie_namespace = 'doxygen'; + var sidenav,navtree,content,header,barWidth=6,desktop_vp=768,titleHeight; + + function readSetting(cookie) + { + if (window.chrome) { + var val = localStorage.getItem(cookie_namespace+'_width'); + if (val) return val; + } else { + var myCookie = cookie_namespace+"_"+cookie+"="; + if (document.cookie) { + var index = document.cookie.indexOf(myCookie); + if (index != -1) { + var valStart = index + myCookie.length; + var valEnd = document.cookie.indexOf(";", valStart); + if (valEnd == -1) { + valEnd = document.cookie.length; + } + var val = document.cookie.substring(valStart, valEnd); + return val; + } + } + } + return 250; + } + + function writeSetting(cookie, val) + { + if (window.chrome) { + localStorage.setItem(cookie_namespace+"_width",val); + } else { + var date = new Date(); + date.setTime(date.getTime()+(10*365*24*60*60*1000)); // default expiration is one week + expiration = date.toGMTString(); + document.cookie = cookie_namespace + "_" + cookie + "=" + val + "; SameSite=Lax; expires=" + expiration+"; path=/"; + } + } + + function resizeWidth() + { + var windowWidth = $(window).width() + "px"; + var sidenavWidth = $(sidenav).outerWidth(); + content.css({marginLeft:parseInt(sidenavWidth)+"px"}); + if (typeof page_layout!=='undefined' && page_layout==1) { + footer.css({marginLeft:parseInt(sidenavWidth)+"px"}); + } + writeSetting('width',sidenavWidth-barWidth); + } + + function restoreWidth(navWidth) + { + var windowWidth = $(window).width() + "px"; + content.css({marginLeft:parseInt(navWidth)+barWidth+"px"}); + if (typeof page_layout!=='undefined' && page_layout==1) { + footer.css({marginLeft:parseInt(navWidth)+barWidth+"px"}); + } + sidenav.css({width:navWidth + "px"}); + } + + function resizeHeight() + { + var headerHeight = header.outerHeight(); + var footerHeight = footer.outerHeight(); + var windowHeight = $(window).height(); + var contentHeight,navtreeHeight,sideNavHeight; + if (typeof page_layout==='undefined' || page_layout==0) { /* DISABLE_INDEX=NO */ + contentHeight = windowHeight - headerHeight - footerHeight; + navtreeHeight = contentHeight; + sideNavHeight = contentHeight; + } else if (page_layout==1) { /* DISABLE_INDEX=YES */ + contentHeight = windowHeight - footerHeight; + navtreeHeight = windowHeight - headerHeight; + sideNavHeight = windowHeight; + } + content.css({height:contentHeight + "px"}); + navtree.css({height:navtreeHeight + "px"}); + sidenav.css({height:sideNavHeight + "px"}); + if (location.hash.slice(1)) { + (document.getElementById(location.hash.slice(1))||document.body).scrollIntoView(); + } + } + + function collapseExpand() + { + var newWidth; + if (sidenav.width()>0) { + newWidth=0; + } + else { + var width = readSetting('width'); + newWidth = (width>250 && width<$(window).width()) ? width : 250; + } + restoreWidth(newWidth); + var sidenavWidth = $(sidenav).outerWidth(); + writeSetting('width',sidenavWidth-barWidth); + } + + header = $("#top"); + sidenav = $("#side-nav"); + content = $("#doc-content"); + navtree = $("#nav-tree"); + footer = $("#nav-path"); + $(".side-nav-resizable").resizable({resize: function(e, ui) { resizeWidth(); } }); + $(sidenav).resizable({ minWidth: 0 }); + $(window).resize(function() { resizeHeight(); }); + var device = navigator.userAgent.toLowerCase(); + var touch_device = device.match(/(iphone|ipod|ipad|android)/); + if (touch_device) { /* wider split bar for touch only devices */ + $(sidenav).css({ paddingRight:'20px' }); + $('.ui-resizable-e').css({ width:'20px' }); + $('#nav-sync').css({ right:'34px' }); + barWidth=20; + } + var width = readSetting('width'); + if (width) { restoreWidth(width); } else { resizeWidth(); } + resizeHeight(); + var url = location.href; + var i=url.indexOf("#"); + if (i>=0) window.location.hash=url.substr(i); + var _preventDefault = function(evt) { evt.preventDefault(); }; + $("#splitbar").bind("dragstart", _preventDefault).bind("selectstart", _preventDefault); + if (once) { + $(".ui-resizable-handle").dblclick(collapseExpand); + once=0 + } + $(window).on('load',resizeHeight); +} +/* @license-end */ diff --git a/v1.3.0/coreMQTT/search/all_0.js b/v1.3.0/coreMQTT/search/all_0.js new file mode 100644 index 00000000..4e077c9b --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_0.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['addencodedstringtovector_0',['addEncodedStringToVector',['../core__mqtt_8c.html#a35952c4a02872c18702e7fbbdb1c467f',1,'core_mqtt.c']]], + ['addrecord_1',['addRecord',['../core__mqtt__state_8c.html#a5d0ffdfde0c38a1cc1d4e3f4750a8cc4',1,'core_mqtt_state.c']]], + ['appcallback_2',['appCallback',['../struct_m_q_t_t_context__t.html#a73bd9259db9c3a9b84518cbf928ed91f',1,'MQTTContext_t']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_1.js b/v1.3.0/coreMQTT/search/all_1.js new file mode 100644 index 00000000..482cc48a --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['basic_20types_0',['Basic Types',['../group__mqtt__basic__types.html',1,'']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_10.js b/v1.3.0/coreMQTT/search/all_10.js new file mode 100644 index 00000000..ba3adad2 --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_10.js @@ -0,0 +1,12 @@ +var searchData= +[ + ['readsubackstatus_0',['readSubackStatus',['../core__mqtt__serializer_8c.html#a02cace9415c300f4dd3394bf1eee0787',1,'core_mqtt_serializer.c']]], + ['receiveconnack_1',['receiveConnack',['../core__mqtt_8c.html#aa3c5d4f6154122cedcce9508ea7d1dce',1,'core_mqtt.c']]], + ['receivepacket_2',['receivePacket',['../core__mqtt_8c.html#aa674664c166b58a5b6630961d8760d3a',1,'core_mqtt.c']]], + ['receivesingleiteration_3',['receiveSingleIteration',['../core__mqtt_8c.html#a14d3be6806a945c14c0529daa1714e10',1,'core_mqtt.c']]], + ['recv_4',['recv',['../struct_transport_interface__t.html#a7c34e9b865e2a509306f09c7dfa3699e',1,'TransportInterface_t']]], + ['recvexact_5',['recvExact',['../core__mqtt_8c.html#a509d9dd1ede2bc000035d8f9926a473c',1,'core_mqtt.c']]], + ['remaininglength_6',['remainingLength',['../struct_m_q_t_t_packet_info__t.html#a7c85becf08de0ec9776dd4be1fcc4bf8',1,'MQTTPacketInfo_t']]], + ['remaininglengthencodedsize_7',['remainingLengthEncodedSize',['../core__mqtt__serializer_8c.html#aeead0813fa045d754e3d6ec964d0686e',1,'core_mqtt_serializer.c']]], + ['retain_8',['retain',['../struct_m_q_t_t_publish_info__t.html#a343b0af89c46a900db4aa5c775a0975a',1,'MQTTPublishInfo_t']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_11.js b/v1.3.0/coreMQTT/search/all_11.js new file mode 100644 index 00000000..2760bd6f --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_11.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['send_0',['send',['../struct_transport_interface__t.html#a01cd9935e9a5266ca196243a0054d489',1,'TransportInterface_t']]], + ['sendbuffer_1',['sendBuffer',['../core__mqtt_8c.html#a7f4f9871c75f8f987e3c86ae910bd982',1,'core_mqtt.c']]], + ['sendconnectwithoutcopy_2',['sendConnectWithoutCopy',['../core__mqtt_8c.html#a3c6935ecef4879b9aeee05ffb0f0a9cb',1,'core_mqtt.c']]], + ['sendmessagevector_3',['sendMessageVector',['../core__mqtt_8c.html#a39f478d2bb0366a5f14bfa90316d8d26',1,'core_mqtt.c']]], + ['sendpublishacks_4',['sendPublishAcks',['../core__mqtt_8c.html#ab4b719d2f726b049c279dcb37fcba840',1,'core_mqtt.c']]], + ['sendpublishwithoutcopy_5',['sendPublishWithoutCopy',['../core__mqtt_8c.html#aaaca64a926603116f5dfec4a65f28283',1,'core_mqtt.c']]], + ['sendsubscribewithoutcopy_6',['sendSubscribeWithoutCopy',['../core__mqtt_8c.html#a86259fe46a81f7981a7b43b677ab896d',1,'core_mqtt.c']]], + ['sendunsubscribewithoutcopy_7',['sendUnsubscribeWithoutCopy',['../core__mqtt_8c.html#a5fc0209190ce8ce635050195689306e2',1,'core_mqtt.c']]], + ['serializeconnectpacket_8',['serializeConnectPacket',['../core__mqtt__serializer_8c.html#a95bf697a3b1f86950e5c199d9cf3a185',1,'core_mqtt_serializer.c']]], + ['serializepublishcommon_9',['serializePublishCommon',['../core__mqtt__serializer_8c.html#a6b4138d990e2c8fbedbe28683c0fa83a',1,'core_mqtt_serializer.c']]], + ['size_10',['size',['../struct_m_q_t_t_fixed_buffer__t.html#a0b0b6a93cc62751ebeb03095d5431636',1,'MQTTFixedBuffer_t']]], + ['stateselect_11',['stateSelect',['../core__mqtt__state_8c.html#adfc09b0c75d5de09cd73650f944699c0',1,'core_mqtt_state.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_12.js b/v1.3.0/coreMQTT/search/all_12.js new file mode 100644 index 00000000..3a47c51b --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_12.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['timeouts_20in_20coremqtt_20library_0',['Timeouts in coreMQTT library',['../mqtt_timeouts.html',1,'']]], + ['topicfilterlength_1',['topicFilterLength',['../struct_m_q_t_t_subscribe_info__t.html#a6972f8e036f8bde9b1f23a2aacb61382',1,'MQTTSubscribeInfo_t']]], + ['topicnamelength_2',['topicNameLength',['../struct_m_q_t_t_publish_info__t.html#a6161c792d20cc7cf8284c1b71ea1145f',1,'MQTTPublishInfo_t']]], + ['transport_20interface_3',['Transport Interface',['../mqtt_transport_interface.html',1,'']]], + ['transport_5finterface_2eh_4',['transport_interface.h',['../transport__interface_8h.html',1,'']]], + ['transportinterface_5',['transportInterface',['../struct_m_q_t_t_context__t.html#a87ab9d61e7711325c2c85ce3ce63386a',1,'MQTTContext_t']]], + ['transportinterface_5ft_6',['TransportInterface_t',['../struct_transport_interface__t.html',1,'']]], + ['transportoutvector_5ft_7',['TransportOutVector_t',['../struct_transport_out_vector__t.html',1,'']]], + ['transportrecv_5ft_8',['TransportRecv_t',['../group__mqtt__callback__types.html#ga227df31d6daf07e5d833537c12130167',1,'transport_interface.h']]], + ['transportsend_5ft_9',['TransportSend_t',['../group__mqtt__callback__types.html#ga2a39853ff952edd715ab07b33ab2a7c5',1,'transport_interface.h']]], + ['transportwritev_5ft_10',['TransportWritev_t',['../group__mqtt__callback__types.html#ga47e779557b0c2db95949ef9526861dfb',1,'transport_interface.h']]], + ['type_11',['type',['../struct_m_q_t_t_packet_info__t.html#a7fef40548c1aa0f0e7f812a6a7243758',1,'MQTTPacketInfo_t']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_13.js b/v1.3.0/coreMQTT/search/all_13.js new file mode 100644 index 00000000..f992eef2 --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_13.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['uint16_5fbitmap_5fbit_5fset_5fat_0',['UINT16_BITMAP_BIT_SET_AT',['../core__mqtt__state_8c.html#a50892214c51968df798f584272f16a17',1,'core_mqtt_state.c']]], + ['uint16_5fcheck_5fbit_1',['UINT16_CHECK_BIT',['../core__mqtt__state_8c.html#a085ab1307745f304ce2e6d24bdc3f6a7',1,'core_mqtt_state.c']]], + ['uint16_5fdecode_2',['UINT16_DECODE',['../core__mqtt__serializer_8c.html#acc849aa739edff3ec532219a3860a3a0',1,'core_mqtt_serializer.c']]], + ['uint16_5fhigh_5fbyte_3',['UINT16_HIGH_BYTE',['../core__mqtt__serializer_8c.html#a24aab781ef139dd38be534ee137ea2f9',1,'core_mqtt_serializer.c']]], + ['uint16_5flow_5fbyte_4',['UINT16_LOW_BYTE',['../core__mqtt__serializer_8c.html#af2ae35b27e0140a77238cd175508cb4e',1,'core_mqtt_serializer.c']]], + ['uint16_5fset_5fbit_5',['UINT16_SET_BIT',['../core__mqtt__state_8c.html#acd96521b31682b7d93de544704fd9594',1,'core_mqtt_state.c']]], + ['uint8_5fcheck_5fbit_6',['UINT8_CHECK_BIT',['../core__mqtt__serializer_8c.html#a07cc5f3f934e1ebf8011a6c15a667206',1,'core_mqtt_serializer.c']]], + ['uint8_5fset_5fbit_7',['UINT8_SET_BIT',['../core__mqtt__serializer_8c.html#af259c91b3075c24df53fa3ffe516b208',1,'core_mqtt_serializer.c']]], + ['updaterecord_8',['updateRecord',['../core__mqtt__state_8c.html#a819c7c72087621fcf97a028bff02759e',1,'core_mqtt_state.c']]], + ['updatestateack_9',['updateStateAck',['../core__mqtt__state_8c.html#a174a91b9491a344d6fb4f0b39189392f',1,'core_mqtt_state.c']]], + ['updatestatepublish_10',['updateStatePublish',['../core__mqtt__state_8c.html#aa0550584e3733da2e31c9478b9307b49',1,'core_mqtt_state.c']]], + ['usernamelength_11',['userNameLength',['../struct_m_q_t_t_connect_info__t.html#a7165be3bb06d4527ab4eb773b50e05e1',1,'MQTTConnectInfo_t']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_14.js b/v1.3.0/coreMQTT/search/all_14.js new file mode 100644 index 00000000..460ee0c0 --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_14.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['validatepublishparams_0',['validatePublishParams',['../core__mqtt_8c.html#ad7eda8c9d4a5afa7b3f830dbd8cf4de4',1,'core_mqtt.c']]], + ['validatesubscribeunsubscribeparams_1',['validateSubscribeUnsubscribeParams',['../core__mqtt_8c.html#a37c146709806e0974638784edeb587f8',1,'core_mqtt.c']]], + ['validatesubscriptionserializeparams_2',['validateSubscriptionSerializeParams',['../core__mqtt__serializer_8c.html#a81262cb0b9d47dee979420f6fd8a7271',1,'core_mqtt_serializer.c']]], + ['validatetransitionack_3',['validateTransitionAck',['../core__mqtt__state_8c.html#ac85ca8874163b399b7f8e5e17d3c5872',1,'core_mqtt_state.c']]], + ['validatetransitionpublish_4',['validateTransitionPublish',['../core__mqtt__state_8c.html#aad1473b9a2d46be62c3e80dd3524af9d',1,'core_mqtt_state.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_15.js b/v1.3.0/coreMQTT/search/all_15.js new file mode 100644 index 00000000..9b440655 --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_15.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['waitingforpingresp_0',['waitingForPingResp',['../struct_m_q_t_t_context__t.html#ac7073f43645f7b7c0c5b7763980004bb',1,'MQTTContext_t']]], + ['writev_1',['writev',['../struct_transport_interface__t.html#a8cf677fbeee53d270daa6dacfa138b79',1,'TransportInterface_t']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_16.js b/v1.3.0/coreMQTT/search/all_16.js new file mode 100644 index 00000000..c6b43ceb --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_16.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['zero_5fsize_5ft_0',['ZERO_SIZE_T',['../core__mqtt__state_8c.html#ab93bbb754488b23d5ac75abcd385e086',1,'core_mqtt_state.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_2.js b/v1.3.0/coreMQTT/search/all_2.js new file mode 100644 index 00000000..904a7226 --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_2.js @@ -0,0 +1,25 @@ +var searchData= +[ + ['calculateelapsedtime_0',['calculateElapsedTime',['../core__mqtt_8c.html#a04f9f5742bc28fe29e61f3f46d20d3d6',1,'core_mqtt.c']]], + ['calculatepublishpacketsize_1',['calculatePublishPacketSize',['../core__mqtt__serializer_8c.html#a76d0156e521588fb3319043f9d35ea9a',1,'core_mqtt_serializer.c']]], + ['calculatesubscriptionpacketsize_2',['calculateSubscriptionPacketSize',['../core__mqtt__serializer_8c.html#abdbabda0aa9db25166963afa975adb10',1,'core_mqtt_serializer.c']]], + ['callback_20types_3',['Callback Types',['../group__mqtt__callback__types.html',1,'']]], + ['checkpublishremaininglength_4',['checkPublishRemainingLength',['../core__mqtt__serializer_8c.html#a33a2680aab1ce2186acd7c78aeb270f1',1,'core_mqtt_serializer.c']]], + ['cleansession_5',['cleanSession',['../struct_m_q_t_t_connect_info__t.html#a606e7765c4f2215fb2bf630f6eb9ff6b',1,'MQTTConnectInfo_t']]], + ['clientidentifierlength_6',['clientIdentifierLength',['../struct_m_q_t_t_connect_info__t.html#a8077ef36ab318f3d35bee6f098fa54d4',1,'MQTTConnectInfo_t']]], + ['compactrecords_7',['compactRecords',['../core__mqtt__state_8c.html#a6cd7b86de2ddb125fee886d58d1a5fd4',1,'core_mqtt_state.c']]], + ['configurations_8',['Configurations',['../core_mqtt_config.html',1,'']]], + ['connectstatus_9',['connectStatus',['../struct_m_q_t_t_context__t.html#a4e38c4dc77e7751a0ad8730a41bee47f',1,'MQTTContext_t']]], + ['constants_10',['Constants',['../group__mqtt__constants.html',1,'']]], + ['controlpacketsent_11',['controlPacketSent',['../struct_m_q_t_t_context__t.html#af9724f2426132e3ce96a03892902ef89',1,'MQTTContext_t']]], + ['core_5fmqtt_2ec_12',['core_mqtt.c',['../core__mqtt_8c.html',1,'']]], + ['core_5fmqtt_2eh_13',['core_mqtt.h',['../core__mqtt_8h.html',1,'']]], + ['core_5fmqtt_5fconfig_5fdefaults_2eh_14',['core_mqtt_config_defaults.h',['../core__mqtt__config__defaults_8h.html',1,'']]], + ['core_5fmqtt_5fserialized_5flength_5ffield_5fbytes_15',['CORE_MQTT_SERIALIZED_LENGTH_FIELD_BYTES',['../core__mqtt_8c.html#a989426922a1f5f04ea8b612fd1f4b185',1,'core_mqtt.c']]], + ['core_5fmqtt_5fserializer_2ec_16',['core_mqtt_serializer.c',['../core__mqtt__serializer_8c.html',1,'']]], + ['core_5fmqtt_5fserializer_2eh_17',['core_mqtt_serializer.h',['../core__mqtt__serializer_8h.html',1,'']]], + ['core_5fmqtt_5fstate_2ec_18',['core_mqtt_state.c',['../core__mqtt__state_8c.html',1,'']]], + ['core_5fmqtt_5fstate_2eh_19',['core_mqtt_state.h',['../core__mqtt__state_8h.html',1,'']]], + ['core_5fmqtt_5fsubscribe_5fper_5ftopic_5fvector_5flength_20',['CORE_MQTT_SUBSCRIBE_PER_TOPIC_VECTOR_LENGTH',['../core__mqtt_8c.html#a97f180c9cc32ca9e354e7c22378a386b',1,'core_mqtt.c']]], + ['core_5fmqtt_5funsubscribe_5fper_5ftopic_5fvector_5flength_21',['CORE_MQTT_UNSUBSCRIBE_PER_TOPIC_VECTOR_LENGTH',['../core__mqtt_8c.html#a42477ec456354f2b944b47646ee5a9ce',1,'core_mqtt.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_3.js b/v1.3.0/coreMQTT/search/all_3.js new file mode 100644 index 00000000..15d55e27 --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_3.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['deserializationresult_0',['deserializationResult',['../struct_m_q_t_t_deserialized_info__t.html#a7df1b7b60404c9f1604fec0081d2625d',1,'MQTTDeserializedInfo_t']]], + ['deserializeconnack_1',['deserializeConnack',['../core__mqtt__serializer_8c.html#aa7b25e1e3114536e9b0526fc93a1f76c',1,'core_mqtt_serializer.c']]], + ['deserializepingresp_2',['deserializePingresp',['../core__mqtt__serializer_8c.html#afdd9b08562ccaa6cf8dd68baa6bc7060',1,'core_mqtt_serializer.c']]], + ['deserializepublish_3',['deserializePublish',['../core__mqtt__serializer_8c.html#a6e8bcde1280e14706e0cb9180358607c',1,'core_mqtt_serializer.c']]], + ['deserializesimpleack_4',['deserializeSimpleAck',['../core__mqtt__serializer_8c.html#a5d437c287290fa28a0ed65635fd6c9ae',1,'core_mqtt_serializer.c']]], + ['deserializesuback_5',['deserializeSuback',['../core__mqtt__serializer_8c.html#ae7b71036fc19c9a6da480dcfd3a2387b',1,'core_mqtt_serializer.c']]], + ['design_6',['Design',['../mqtt_design.html',1,'']]], + ['discardpacket_7',['discardPacket',['../core__mqtt_8c.html#abb02f1853a4805205636f2c11a435216',1,'core_mqtt.c']]], + ['discardstoredpacket_8',['discardStoredPacket',['../core__mqtt_8c.html#af827b2088c38c31a0b75dc70377db536',1,'core_mqtt.c']]], + ['dup_9',['dup',['../struct_m_q_t_t_publish_info__t.html#aa1c8954e83bfa678d1ff5429679d4e89',1,'MQTTPublishInfo_t']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_4.js b/v1.3.0/coreMQTT/search/all_4.js new file mode 100644 index 00000000..5b751d64 --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_4.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['encoderemaininglength_0',['encodeRemainingLength',['../core__mqtt__serializer_8c.html#a3a3858fbb0cbd845f208b3fc60f36130',1,'core_mqtt_serializer.c']]], + ['encodestring_1',['encodeString',['../core__mqtt__serializer_8c.html#a60e580c28431eb08f05a156949137f1f',1,'core_mqtt_serializer.c']]], + ['enumerated_20types_2',['Enumerated Types',['../group__mqtt__enum__types.html',1,'']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_5.js b/v1.3.0/coreMQTT/search/all_5.js new file mode 100644 index 00000000..07ce47bb --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_5.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['findinrecord_0',['findInRecord',['../core__mqtt__state_8c.html#ac805558ac65e84ea9111ce70c873e59e',1,'core_mqtt_state.c']]], + ['functions_1',['Functions',['../mqtt_functions.html',1,'']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_6.js b/v1.3.0/coreMQTT/search/all_6.js new file mode 100644 index 00000000..25049862 --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_6.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['getackfrompackettype_0',['getAckFromPacketType',['../core__mqtt_8c.html#aa1f35063dbe3b2c35f278ea6aa347a0e',1,'core_mqtt.c']]], + ['getacktypetosend_1',['getAckTypeToSend',['../core__mqtt_8c.html#a02f112e21a6d0b87a3c69ef300d264de',1,'core_mqtt.c']]], + ['getremaininglength_2',['getRemainingLength',['../core__mqtt__serializer_8c.html#a5685b753d1d42788a00bd59ffa4639e2',1,'core_mqtt_serializer.c']]], + ['gettime_3',['getTime',['../struct_m_q_t_t_context__t.html#aabe1d302a16771292151013e8e30c582',1,'MQTTContext_t']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_7.js b/v1.3.0/coreMQTT/search/all_7.js new file mode 100644 index 00000000..e757c7a1 --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_7.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['handleincomingack_0',['handleIncomingAck',['../core__mqtt_8c.html#a264afa489cbfbd96086614d335969115',1,'core_mqtt.c']]], + ['handleincomingpublish_1',['handleIncomingPublish',['../core__mqtt_8c.html#a4ac6e6829500c4f522eae413c9470e4d',1,'core_mqtt.c']]], + ['handlekeepalive_2',['handleKeepAlive',['../core__mqtt_8c.html#ae0e50de302a1aa66e3c5b2cdcacc4f3f',1,'core_mqtt.c']]], + ['handlepublishacks_3',['handlePublishAcks',['../core__mqtt_8c.html#a2363868c0417261c27c750251aad13e5',1,'core_mqtt.c']]], + ['handlesessionresumption_4',['handleSessionResumption',['../core__mqtt_8c.html#aae9ba11e41bc1dfef340208bc49c836c',1,'core_mqtt.c']]], + ['headerlength_5',['headerLength',['../struct_m_q_t_t_packet_info__t.html#aa7de1631ed8e08410942d36a72db558a',1,'MQTTPacketInfo_t']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_8.js b/v1.3.0/coreMQTT/search/all_8.js new file mode 100644 index 00000000..fc182a43 --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_8.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['incomingpacketvalid_0',['incomingPacketValid',['../core__mqtt__serializer_8c.html#a03dfebbfbc1635567839f7abb7c0f8db',1,'core_mqtt_serializer.c']]], + ['incomingpublishrecordmaxcount_1',['incomingPublishRecordMaxCount',['../struct_m_q_t_t_context__t.html#aa33ed2e10380a854629f1386d0323ea8',1,'MQTTContext_t']]], + ['incomingpublishrecords_2',['incomingPublishRecords',['../struct_m_q_t_t_context__t.html#afc147663a5933de81212fa77057f0a4d',1,'MQTTContext_t']]], + ['index_3',['index',['../struct_m_q_t_t_context__t.html#a41b7735cd0746563483b72e17cf103aa',1,'MQTTContext_t']]], + ['iov_5fbase_4',['iov_base',['../struct_transport_out_vector__t.html#a0ffa5c06bf00006cbafa8e244951038d',1,'TransportOutVector_t']]], + ['iov_5flen_5',['iov_len',['../struct_transport_out_vector__t.html#ada73dafb2d34311f33fefad38603b35c',1,'TransportOutVector_t']]], + ['ispublishoutgoing_6',['isPublishOutgoing',['../core__mqtt__state_8c.html#aaf9d4c6e766e40189ff7b68ffea40aa0',1,'core_mqtt_state.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_9.js b/v1.3.0/coreMQTT/search/all_9.js new file mode 100644 index 00000000..dcbf16db --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_9.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['keepaliveintervalsec_0',['keepAliveIntervalSec',['../struct_m_q_t_t_context__t.html#afd6071827ef48b230212a5725c2075be',1,'MQTTContext_t']]], + ['keepaliveseconds_1',['keepAliveSeconds',['../struct_m_q_t_t_connect_info__t.html#a7d05d53261732ebdfbb9ee665a347591',1,'MQTTConnectInfo_t']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_a.js b/v1.3.0/coreMQTT/search/all_a.js new file mode 100644 index 00000000..2088ac2c --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_a.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['lastpacketrxtime_0',['lastPacketRxTime',['../struct_m_q_t_t_context__t.html#a7111ef16e4a4e75a72861f6f3ea8a7c3',1,'MQTTContext_t']]], + ['lastpackettxtime_1',['lastPacketTxTime',['../struct_m_q_t_t_context__t.html#a01acf90953e830ba3e7f44182cb1d482',1,'MQTTContext_t']]], + ['logconnackresponse_2',['logConnackResponse',['../core__mqtt__serializer_8c.html#a5451f2e3468faaf2bdf85220ebb95aaa',1,'core_mqtt_serializer.c']]], + ['logdebug_3',['LogDebug',['../core__mqtt__config__defaults_8h.html#af60e8ffc327d136e5d0d8441ed98c98d',1,'core_mqtt_config_defaults.h']]], + ['logerror_4',['LogError',['../core__mqtt__config__defaults_8h.html#a8d9dbaaa88129137a4c68ba0456a18b1',1,'core_mqtt_config_defaults.h']]], + ['loginfo_5',['LogInfo',['../core__mqtt__config__defaults_8h.html#a00810b1cb9d2f25d25ce2d4d93815fba',1,'core_mqtt_config_defaults.h']]], + ['logwarn_6',['LogWarn',['../core__mqtt__config__defaults_8h.html#a7da92048aaf0cbfcacde9539c98a0e05',1,'core_mqtt_config_defaults.h']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_b.js b/v1.3.0/coreMQTT/search/all_b.js new file mode 100644 index 00000000..b9e3fd9a --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_b.js @@ -0,0 +1,161 @@ +var searchData= +[ + ['matchendwildcardsspecialcases_0',['matchEndWildcardsSpecialCases',['../core__mqtt_8c.html#ab29bb66fe7385c52452a3087bcfbc98e',1,'core_mqtt.c']]], + ['matchtopicfilter_1',['matchTopicFilter',['../core__mqtt_8c.html#a4c052d9dd6a81e866121c24a2ee2aa0b',1,'core_mqtt.c']]], + ['matchwildcards_2',['matchWildcards',['../core__mqtt_8c.html#ab1f061741c445d07454cfa03786a5eea',1,'core_mqtt.c']]], + ['mqtt_5fcalculatestateack_3',['MQTT_CalculateStateAck',['../core__mqtt__state_8c.html#a0cad28e34f03b84aff43ee243ce8e2cf',1,'core_mqtt_state.c']]], + ['mqtt_5fcalculatestatepublish_4',['MQTT_CalculateStatePublish',['../core__mqtt__state_8c.html#aadc4fdd8af74ac25b848a33e916bff50',1,'core_mqtt_state.c']]], + ['mqtt_5fcancelcallback_5',['MQTT_CancelCallback',['../core__mqtt_8h.html#a31b74c34cd295b98ed5f5b4c15ed4a8b',1,'MQTT_CancelCallback(const MQTTContext_t *pContext, uint16_t packetId): core_mqtt.c'],['../core__mqtt_8c.html#a31b74c34cd295b98ed5f5b4c15ed4a8b',1,'MQTT_CancelCallback(const MQTTContext_t *pContext, uint16_t packetId): core_mqtt.c']]], + ['mqtt_5fconnect_6',['MQTT_Connect',['../core__mqtt_8c.html#aed1e4dc123a8ba79ac569cb17c69bfa0',1,'MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent): core_mqtt.c'],['../core__mqtt_8h.html#aed1e4dc123a8ba79ac569cb17c69bfa0',1,'MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent): core_mqtt.c'],['../mqtt_connect_function.html',1,'mqtt_functions']]], + ['mqtt_5fconnect_5fflag_5fclean_7',['MQTT_CONNECT_FLAG_CLEAN',['../core__mqtt__serializer_8c.html#a1b131e766e003e36fe499d9f6a79fc03',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fpassword_8',['MQTT_CONNECT_FLAG_PASSWORD',['../core__mqtt__serializer_8c.html#ac5f0bb47789c1182392f5029e0238a81',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fusername_9',['MQTT_CONNECT_FLAG_USERNAME',['../core__mqtt__serializer_8c.html#a8d23d14a4cf296feffb9db79728dd1d0',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fwill_10',['MQTT_CONNECT_FLAG_WILL',['../core__mqtt__serializer_8c.html#a04d8c55ea2b595a277cbcd4340e36d6c',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fwill_5fqos1_11',['MQTT_CONNECT_FLAG_WILL_QOS1',['../core__mqtt__serializer_8c.html#a2aee739b1fa7e61feb907bc92a73c3b4',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fwill_5fqos2_12',['MQTT_CONNECT_FLAG_WILL_QOS2',['../core__mqtt__serializer_8c.html#ac750789b338a2b9be75725ab340dabce',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fwill_5fretain_13',['MQTT_CONNECT_FLAG_WILL_RETAIN',['../core__mqtt__serializer_8c.html#a8ae294d4ca7960920816339fedbdc4a0',1,'core_mqtt_serializer.c']]], + ['mqtt_5fdeserializeack_14',['MQTT_DeserializeAck',['../core__mqtt__serializer_8h.html#ae9971855df71edf94124116e0625bf18',1,'MQTT_DeserializeAck(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, bool *pSessionPresent): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#ae9971855df71edf94124116e0625bf18',1,'MQTT_DeserializeAck(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, bool *pSessionPresent): core_mqtt_serializer.c'],['../mqtt_deserializeack_function.html',1,'mqtt_functions']]], + ['mqtt_5fdeserializepublish_15',['MQTT_DeserializePublish',['../core__mqtt__serializer_8h.html#a4c2aec031f31d0fe55c1cda46544e95a',1,'MQTT_DeserializePublish(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a4c2aec031f31d0fe55c1cda46544e95a',1,'MQTT_DeserializePublish(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo): core_mqtt_serializer.c'],['../mqtt_deserializepublish_function.html',1,'mqtt_functions']]], + ['mqtt_5fdisconnect_16',['MQTT_Disconnect',['../core__mqtt_8h.html#ac79c366acbc3dddd88072d99ccb9140c',1,'MQTT_Disconnect(MQTTContext_t *pContext): core_mqtt.c'],['../core__mqtt_8c.html#ac79c366acbc3dddd88072d99ccb9140c',1,'MQTT_Disconnect(MQTTContext_t *pContext): core_mqtt.c'],['../mqtt_disconnect_function.html',1,'mqtt_functions']]], + ['mqtt_5fdisconnect_5fpacket_5fsize_17',['MQTT_DISCONNECT_PACKET_SIZE',['../core__mqtt__serializer_8c.html#abdcffcd69d858203747236b5c4afa834',1,'core_mqtt_serializer.c']]], + ['mqtt_5fdisconnect_5fremaining_5flength_18',['MQTT_DISCONNECT_REMAINING_LENGTH',['../core__mqtt__serializer_8c.html#ac4f3ff016aa6011e3fc707b9f27f6b8c',1,'core_mqtt_serializer.c']]], + ['mqtt_5fdo_5fnot_5fuse_5fcustom_5fconfig_19',['MQTT_DO_NOT_USE_CUSTOM_CONFIG',['../core__mqtt__config__defaults_8h.html#abd12bb401eecf3f6694447ea3b1c886d',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5fgetconnectpacketsize_20',['MQTT_GetConnectPacketSize',['../core__mqtt__serializer_8h.html#a4e57ccef527a25b572dc66eeb2e217c5',1,'MQTT_GetConnectPacketSize(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a4e57ccef527a25b572dc66eeb2e217c5',1,'MQTT_GetConnectPacketSize(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../mqtt_getconnectpacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetdisconnectpacketsize_21',['MQTT_GetDisconnectPacketSize',['../core__mqtt__serializer_8h.html#a6fdd8cbde6b7c4ff85c20aaca0fd8741',1,'MQTT_GetDisconnectPacketSize(size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a6fdd8cbde6b7c4ff85c20aaca0fd8741',1,'MQTT_GetDisconnectPacketSize(size_t *pPacketSize): core_mqtt_serializer.c'],['../mqtt_getdisconnectpacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetincomingpackettypeandlength_22',['MQTT_GetIncomingPacketTypeAndLength',['../core__mqtt__serializer_8c.html#a98cdda86f86a0a1888745a584199e930',1,'MQTT_GetIncomingPacketTypeAndLength(TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#a98cdda86f86a0a1888745a584199e930',1,'MQTT_GetIncomingPacketTypeAndLength(TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket): core_mqtt_serializer.c'],['../mqtt_getincomingpackettypeandlength_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetpacketid_23',['MQTT_GetPacketId',['../core__mqtt_8h.html#a00e1a3eba2c21899a6b4312c7d65d090',1,'MQTT_GetPacketId(MQTTContext_t *pContext): core_mqtt.c'],['../core__mqtt_8c.html#a00e1a3eba2c21899a6b4312c7d65d090',1,'MQTT_GetPacketId(MQTTContext_t *pContext): core_mqtt.c'],['../mqtt_getpacketid_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetpingreqpacketsize_24',['MQTT_GetPingreqPacketSize',['../core__mqtt__serializer_8h.html#a015562f30e220d2534f773bfa45a5cfe',1,'MQTT_GetPingreqPacketSize(size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a015562f30e220d2534f773bfa45a5cfe',1,'MQTT_GetPingreqPacketSize(size_t *pPacketSize): core_mqtt_serializer.c'],['../mqtt_getpingreqpacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetpublishpacketsize_25',['MQTT_GetPublishPacketSize',['../core__mqtt__serializer_8h.html#a9971fb98c6af22b1bfe697d44492a819',1,'MQTT_GetPublishPacketSize(const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a9971fb98c6af22b1bfe697d44492a819',1,'MQTT_GetPublishPacketSize(const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../mqtt_getpublishpacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetsubackstatuscodes_26',['MQTT_GetSubAckStatusCodes',['../core__mqtt_8h.html#ac43449e06856c6703cda73359c222bd2',1,'MQTT_GetSubAckStatusCodes(const MQTTPacketInfo_t *pSubackPacket, uint8_t **pPayloadStart, size_t *pPayloadSize): core_mqtt.c'],['../core__mqtt_8c.html#ac43449e06856c6703cda73359c222bd2',1,'MQTT_GetSubAckStatusCodes(const MQTTPacketInfo_t *pSubackPacket, uint8_t **pPayloadStart, size_t *pPayloadSize): core_mqtt.c'],['../mqtt_getsubackstatuscodes_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetsubscribepacketsize_27',['MQTT_GetSubscribePacketSize',['../core__mqtt__serializer_8c.html#abb9a703cb23ab39fdd6fe282a5f3ddc5',1,'MQTT_GetSubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#abb9a703cb23ab39fdd6fe282a5f3ddc5',1,'MQTT_GetSubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../mqtt_getsubscribepacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetunsubscribepacketsize_28',['MQTT_GetUnsubscribePacketSize',['../core__mqtt__serializer_8c.html#a2a18563d5f63c8975b57118a6836c932',1,'MQTT_GetUnsubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#a2a18563d5f63c8975b57118a6836c932',1,'MQTT_GetUnsubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../mqtt_getunsubscribepacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5finit_29',['MQTT_Init',['../core__mqtt_8h.html#ae8444f3a85535e62cdb1ae9c192677d6',1,'MQTT_Init(MQTTContext_t *pContext, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getTimeFunction, MQTTEventCallback_t userCallback, const MQTTFixedBuffer_t *pNetworkBuffer): core_mqtt.c'],['../core__mqtt_8c.html#ae8444f3a85535e62cdb1ae9c192677d6',1,'MQTT_Init(MQTTContext_t *pContext, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getTimeFunction, MQTTEventCallback_t userCallback, const MQTTFixedBuffer_t *pNetworkBuffer): core_mqtt.c'],['../mqtt_init_function.html',1,'mqtt_functions']]], + ['mqtt_5finitstatefulqos_30',['MQTT_InitStatefulQoS',['../core__mqtt_8c.html#afe4c020749e3b9ca044e0e9ad96025c5',1,'MQTT_InitStatefulQoS(MQTTContext_t *pContext, MQTTPubAckInfo_t *pOutgoingPublishRecords, size_t outgoingPublishCount, MQTTPubAckInfo_t *pIncomingPublishRecords, size_t incomingPublishCount): core_mqtt.c'],['../core__mqtt_8h.html#afe4c020749e3b9ca044e0e9ad96025c5',1,'MQTT_InitStatefulQoS(MQTTContext_t *pContext, MQTTPubAckInfo_t *pOutgoingPublishRecords, size_t outgoingPublishCount, MQTTPubAckInfo_t *pIncomingPublishRecords, size_t incomingPublishCount): core_mqtt.c']]], + ['mqtt_5finvalid_5fstate_5fcount_31',['MQTT_INVALID_STATE_COUNT',['../core__mqtt__state_8c.html#a49d2236ebe2b3d27e82e54a7b9e74984',1,'core_mqtt_state.c']]], + ['mqtt_5fmatchtopic_32',['MQTT_MatchTopic',['../core__mqtt_8c.html#a633409812b18547365ec9b853069021b',1,'MQTT_MatchTopic(const char *pTopicName, const uint16_t topicNameLength, const char *pTopicFilter, const uint16_t topicFilterLength, bool *pIsMatch): core_mqtt.c'],['../core__mqtt_8h.html#a633409812b18547365ec9b853069021b',1,'MQTT_MatchTopic(const char *pTopicName, const uint16_t topicNameLength, const char *pTopicFilter, const uint16_t topicFilterLength, bool *pIsMatch): core_mqtt.c']]], + ['mqtt_5fmax_5fconnack_5freceive_5fretry_5fcount_33',['MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT',['../core__mqtt__config__defaults_8h.html#a8ca6c96436d5e7c2c8a7933fb28a5c87',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5fmax_5fremaining_5flength_34',['MQTT_MAX_REMAINING_LENGTH',['../core__mqtt__serializer_8c.html#a9d9ea40a1ff486557a553523a0743647',1,'core_mqtt_serializer.c']]], + ['mqtt_5fmin_5fpublish_5fremaining_5flength_5fqos0_35',['MQTT_MIN_PUBLISH_REMAINING_LENGTH_QOS0',['../core__mqtt__serializer_8c.html#a3b8709529a24bc195c7310183ffbcc2b',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fconnack_5fremaining_5flength_36',['MQTT_PACKET_CONNACK_REMAINING_LENGTH',['../core__mqtt__serializer_8c.html#a999c4ebc0d629df9b08a3c88107b5b80',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fconnack_5fsession_5fpresent_5fmask_37',['MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK',['../core__mqtt__serializer_8c.html#aab69dd14c12f8086245c2371288944f0',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fconnect_5fheader_5fsize_38',['MQTT_PACKET_CONNECT_HEADER_SIZE',['../core__mqtt__serializer_8c.html#aa7c310cb084af0025c356ed844ae443d',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fid_5finvalid_39',['MQTT_PACKET_ID_INVALID',['../group__mqtt__constants.html#ga9fde6503edb9eaad50ecd3392ab9992a',1,'core_mqtt.h']]], + ['mqtt_5fpacket_5fpingreq_5fsize_40',['MQTT_PACKET_PINGREQ_SIZE',['../core__mqtt__serializer_8c.html#a6e8a49d0d88f0b038a5379d533858103',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fpingresp_5fremaining_5flength_41',['MQTT_PACKET_PINGRESP_REMAINING_LENGTH',['../core__mqtt__serializer_8c.html#aeab5c92e86ed98750cbf6422b8b57c06',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fsimple_5fack_5fremaining_5flength_42',['MQTT_PACKET_SIMPLE_ACK_REMAINING_LENGTH',['../core__mqtt__serializer_8c.html#a4c576df64bca769a91cb64d5d5d86505',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5ftype_5fconnack_43',['MQTT_PACKET_TYPE_CONNACK',['../group__mqtt__constants.html#gab14f6c39c303eac1a76816edfde7feab',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fconnect_44',['MQTT_PACKET_TYPE_CONNECT',['../group__mqtt__constants.html#ga64a0515bda2ecc89e97595535e1cf0ef',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fdisconnect_45',['MQTT_PACKET_TYPE_DISCONNECT',['../group__mqtt__constants.html#gaed07155a3d6fa4b7624b9f36ed33ec6d',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fpingreq_46',['MQTT_PACKET_TYPE_PINGREQ',['../group__mqtt__constants.html#gacbe28c7d081275d1805c2142ff792185',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fpingresp_47',['MQTT_PACKET_TYPE_PINGRESP',['../group__mqtt__constants.html#ga285fc02048e2482794042fa98639e514',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fpuback_48',['MQTT_PACKET_TYPE_PUBACK',['../group__mqtt__constants.html#ga5f279d63de47a973b41b95f74f47a4f6',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fpubcomp_49',['MQTT_PACKET_TYPE_PUBCOMP',['../group__mqtt__constants.html#ga478ecbc98d2ca83d4ce7db33622b5c3b',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fpublish_50',['MQTT_PACKET_TYPE_PUBLISH',['../group__mqtt__constants.html#ga5b2d79c61f2591c8e5772f974826d4ad',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fpubrec_51',['MQTT_PACKET_TYPE_PUBREC',['../group__mqtt__constants.html#gafa2d8f28da39560f152076b99610e6a3',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fpubrel_52',['MQTT_PACKET_TYPE_PUBREL',['../group__mqtt__constants.html#gaeaa2ceecffda50e2d22ccecf046083c6',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fsuback_53',['MQTT_PACKET_TYPE_SUBACK',['../group__mqtt__constants.html#ga307e0186aa17fdd0d6d181d3d2715766',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5fsubscribe_54',['MQTT_PACKET_TYPE_SUBSCRIBE',['../group__mqtt__constants.html#ga80cfef333e60d967ca927b2e5e665f18',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5funsuback_55',['MQTT_PACKET_TYPE_UNSUBACK',['../group__mqtt__constants.html#ga38bc8ed0b9a1581cf85cecdede7d1a64',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpacket_5ftype_5funsubscribe_56',['MQTT_PACKET_TYPE_UNSUBSCRIBE',['../group__mqtt__constants.html#ga4a94c954cfcea31c8fc3e2adf092b228',1,'core_mqtt_serializer.h']]], + ['mqtt_5fping_57',['MQTT_Ping',['../core__mqtt_8h.html#a66eced0c62ace790354ae3de40fc0959',1,'MQTT_Ping(MQTTContext_t *pContext): core_mqtt.c'],['../core__mqtt_8c.html#a66eced0c62ace790354ae3de40fc0959',1,'MQTT_Ping(MQTTContext_t *pContext): core_mqtt.c'],['../mqtt_ping_function.html',1,'mqtt_functions']]], + ['mqtt_5fpingresp_5ftimeout_5fms_58',['MQTT_PINGRESP_TIMEOUT_MS',['../core__mqtt__config__defaults_8h.html#afa825fddb52da7df88fb56d2befcd2fa',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5fpost_5fsend_5fhook_59',['MQTT_POST_SEND_HOOK',['../core__mqtt_8c.html#a205b7112b6bb0697f85b9e25512c67be',1,'core_mqtt.c']]], + ['mqtt_5fpost_5fstate_5fupdate_5fhook_60',['MQTT_POST_STATE_UPDATE_HOOK',['../core__mqtt_8c.html#a436983fba04e3d13cabea35efc4e9bf8',1,'core_mqtt.c']]], + ['mqtt_5fpre_5fsend_5fhook_61',['MQTT_PRE_SEND_HOOK',['../core__mqtt_8c.html#a18f9369f0d6d553db6d1af1bd7156545',1,'core_mqtt.c']]], + ['mqtt_5fpre_5fstate_5fupdate_5fhook_62',['MQTT_PRE_STATE_UPDATE_HOOK',['../core__mqtt_8c.html#acba4b6e51723d384aa9140313effdf8b',1,'core_mqtt.c']]], + ['mqtt_5fprocessincomingpackettypeandlength_63',['MQTT_ProcessIncomingPacketTypeAndLength',['../core__mqtt__serializer_8c.html#a94fd3f746074b3f6e16ae6b23dad9a28',1,'MQTT_ProcessIncomingPacketTypeAndLength(const uint8_t *pBuffer, const size_t *pIndex, MQTTPacketInfo_t *pIncomingPacket): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#a94fd3f746074b3f6e16ae6b23dad9a28',1,'MQTT_ProcessIncomingPacketTypeAndLength(const uint8_t *pBuffer, const size_t *pIndex, MQTTPacketInfo_t *pIncomingPacket): core_mqtt_serializer.c']]], + ['mqtt_5fprocessloop_64',['MQTT_ProcessLoop',['../core__mqtt_8h.html#ab95d3d6b3eed98a6184fb2018c5b55d7',1,'MQTT_ProcessLoop(MQTTContext_t *pContext): core_mqtt.c'],['../core__mqtt_8c.html#ab95d3d6b3eed98a6184fb2018c5b55d7',1,'MQTT_ProcessLoop(MQTTContext_t *pContext): core_mqtt.c'],['../mqtt_processloop_function.html',1,'mqtt_functions']]], + ['mqtt_5fpublish_65',['MQTT_Publish',['../core__mqtt_8h.html#a1d8217e9d30fb2aed002060a8c97c63e',1,'MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId): core_mqtt.c'],['../core__mqtt_8c.html#a1d8217e9d30fb2aed002060a8c97c63e',1,'MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId): core_mqtt.c'],['../mqtt_publish_function.html',1,'mqtt_functions']]], + ['mqtt_5fpublish_5fack_5fpacket_5fsize_66',['MQTT_PUBLISH_ACK_PACKET_SIZE',['../group__mqtt__constants.html#ga26994fcfacb1cff892caa45ec31ca7c6',1,'core_mqtt_serializer.h']]], + ['mqtt_5fpublish_5fflag_5fdup_67',['MQTT_PUBLISH_FLAG_DUP',['../core__mqtt__serializer_8c.html#a57c437ecc3720de76093b08eb0d4f813',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpublish_5fflag_5fqos1_68',['MQTT_PUBLISH_FLAG_QOS1',['../core__mqtt__serializer_8c.html#ac23212835606fade167fb5ce25eaf103',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpublish_5fflag_5fqos2_69',['MQTT_PUBLISH_FLAG_QOS2',['../core__mqtt__serializer_8c.html#afe1d2a0b7c0803f5a20ebb3c7a607d65',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpublish_5fflag_5fretain_70',['MQTT_PUBLISH_FLAG_RETAIN',['../core__mqtt__serializer_8c.html#a3d04b1e1ad7ec25d18fd13726e164f06',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpublishtoresend_71',['MQTT_PublishToResend',['../core__mqtt__state_8c.html#a44b3cf50dc477a9f97413a9238a961f6',1,'MQTT_PublishToResend(const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor): core_mqtt_state.c'],['../core__mqtt__state_8h.html#a44b3cf50dc477a9f97413a9238a961f6',1,'MQTT_PublishToResend(const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor): core_mqtt_state.c'],['../mqtt_publishtoresend_function.html',1,'mqtt_functions']]], + ['mqtt_5fpubreltoresend_72',['MQTT_PubrelToResend',['../core__mqtt__state_8c.html#ae58ade262ec01262687554b349b2fdf5',1,'core_mqtt_state.c']]], + ['mqtt_5freceiveloop_73',['MQTT_ReceiveLoop',['../core__mqtt_8c.html#aeb7c37284fcf6f68eb577427a6763fc6',1,'MQTT_ReceiveLoop(MQTTContext_t *pContext): core_mqtt.c'],['../core__mqtt_8h.html#aeb7c37284fcf6f68eb577427a6763fc6',1,'MQTT_ReceiveLoop(MQTTContext_t *pContext): core_mqtt.c'],['../mqtt_receiveloop_function.html',1,'mqtt_functions']]], + ['mqtt_5frecv_5fpolling_5ftimeout_5fms_74',['MQTT_RECV_POLLING_TIMEOUT_MS',['../core__mqtt__config__defaults_8h.html#a43dc9a67427d9e420a65955eea0e2671',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5fremaining_5flength_5finvalid_75',['MQTT_REMAINING_LENGTH_INVALID',['../core__mqtt__serializer_8c.html#a6f6b43661df6f9e9e9e7123ab01e9eb5',1,'core_mqtt_serializer.c']]], + ['mqtt_5fremovestaterecord_76',['MQTT_RemoveStateRecord',['../core__mqtt__state_8c.html#aef2c13cffbbd5c71183282e69ac9d799',1,'core_mqtt_state.c']]], + ['mqtt_5freservestate_77',['MQTT_ReserveState',['../core__mqtt__state_8c.html#a43bc5d82716e1d8b6e167ec0fe50de5d',1,'core_mqtt_state.c']]], + ['mqtt_5fsend_5ftimeout_5fms_78',['MQTT_SEND_TIMEOUT_MS',['../core__mqtt__config__defaults_8h.html#ac262cab68c4c713ebc2b91a2e4ab8b19',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5fserializeack_79',['MQTT_SerializeAck',['../core__mqtt__serializer_8h.html#a11ea4ac5ea27e93121288e463ca34ee6',1,'MQTT_SerializeAck(const MQTTFixedBuffer_t *pFixedBuffer, uint8_t packetType, uint16_t packetId): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a11ea4ac5ea27e93121288e463ca34ee6',1,'MQTT_SerializeAck(const MQTTFixedBuffer_t *pFixedBuffer, uint8_t packetType, uint16_t packetId): core_mqtt_serializer.c'],['../mqtt_serializeack_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializeconnect_80',['MQTT_SerializeConnect',['../core__mqtt__serializer_8c.html#aa2e2300d6c43e61f8f2cf83f7149835c',1,'MQTT_SerializeConnect(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#aa2e2300d6c43e61f8f2cf83f7149835c',1,'MQTT_SerializeConnect(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../mqtt_serializeconnect_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializeconnectfixedheader_81',['MQTT_SerializeConnectFixedHeader',['../core__mqtt__serializer_8c.html#a5e6043289c05db1cdb7e33e0921247a0',1,'core_mqtt_serializer.c']]], + ['mqtt_5fserializedisconnect_82',['MQTT_SerializeDisconnect',['../core__mqtt__serializer_8c.html#a6aae40d4656eb533a74b67bf9c827d3b',1,'MQTT_SerializeDisconnect(const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#a6aae40d4656eb533a74b67bf9c827d3b',1,'MQTT_SerializeDisconnect(const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../mqtt_serializedisconnect_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializepingreq_83',['MQTT_SerializePingreq',['../core__mqtt__serializer_8c.html#af3b3e40858fd984c871511e02a61e15d',1,'MQTT_SerializePingreq(const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#af3b3e40858fd984c871511e02a61e15d',1,'MQTT_SerializePingreq(const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../mqtt_serializepingreq_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializepublish_84',['MQTT_SerializePublish',['../core__mqtt__serializer_8c.html#ac6c453f9c4b7f48aad511bc677ec7eb9',1,'MQTT_SerializePublish(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#ac6c453f9c4b7f48aad511bc677ec7eb9',1,'MQTT_SerializePublish(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../mqtt_serializepublish_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializepublishheader_85',['MQTT_SerializePublishHeader',['../core__mqtt__serializer_8c.html#a659cf2bcaf2c5131daa0acc1917401a2',1,'MQTT_SerializePublishHeader(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer, size_t *pHeaderSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#a659cf2bcaf2c5131daa0acc1917401a2',1,'MQTT_SerializePublishHeader(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer, size_t *pHeaderSize): core_mqtt_serializer.c'],['../mqtt_serializepublishheader_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializepublishheaderwithouttopic_86',['MQTT_SerializePublishHeaderWithoutTopic',['../core__mqtt__serializer_8h.html#a32de7fabeca85a4d360fa1dd06ff7cd0',1,'MQTT_SerializePublishHeaderWithoutTopic(const MQTTPublishInfo_t *pPublishInfo, size_t remainingLength, uint8_t *pBuffer, size_t *headerSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a32de7fabeca85a4d360fa1dd06ff7cd0',1,'MQTT_SerializePublishHeaderWithoutTopic(const MQTTPublishInfo_t *pPublishInfo, size_t remainingLength, uint8_t *pBuffer, size_t *headerSize): core_mqtt_serializer.c']]], + ['mqtt_5fserializesubscribe_87',['MQTT_SerializeSubscribe',['../core__mqtt__serializer_8h.html#a21273b13070e8340cc33b0f86bf79571',1,'MQTT_SerializeSubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a21273b13070e8340cc33b0f86bf79571',1,'MQTT_SerializeSubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../mqtt_serializesubscribe_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializesubscribeheader_88',['MQTT_SerializeSubscribeHeader',['../core__mqtt__serializer_8c.html#a6fe31953d7b8dacb769adcf4c2719730',1,'core_mqtt_serializer.c']]], + ['mqtt_5fserializeunsubscribe_89',['MQTT_SerializeUnsubscribe',['../core__mqtt__serializer_8h.html#aab58219c203077c07ffd7061405e1adb',1,'MQTT_SerializeUnsubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#aab58219c203077c07ffd7061405e1adb',1,'MQTT_SerializeUnsubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../mqtt_serializeunsubscribe_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializeunsubscribeheader_90',['MQTT_SerializeUnsubscribeHeader',['../core__mqtt__serializer_8c.html#a5b6f47fa319a444835ffed2d6af04709',1,'core_mqtt_serializer.c']]], + ['mqtt_5fstate_5fcursor_5finitializer_91',['MQTT_STATE_CURSOR_INITIALIZER',['../group__mqtt__constants.html#ga666ad78e7eaaffa51f5cab96201a9476',1,'core_mqtt_state.h']]], + ['mqtt_5fstate_5fstrerror_92',['MQTT_State_strerror',['../core__mqtt__state_8c.html#a53d786203ca4d5d5630a9eb3dd4cddae',1,'core_mqtt_state.c']]], + ['mqtt_5fstatus_5fstrerror_93',['MQTT_Status_strerror',['../core__mqtt_8h.html#a05d9facfce89c5f9edef09ca13717f50',1,'MQTT_Status_strerror(MQTTStatus_t status): core_mqtt.c'],['../core__mqtt_8c.html#a05d9facfce89c5f9edef09ca13717f50',1,'MQTT_Status_strerror(MQTTStatus_t status): core_mqtt.c'],['../mqtt_status_strerror_function.html',1,'mqtt_functions']]], + ['mqtt_5fsub_5funsub_5fmax_5fvectors_94',['MQTT_SUB_UNSUB_MAX_VECTORS',['../group__mqtt__constants.html#ga928ea0bff12ebf9cf9fa9dfe5cafebbb',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5fsubscribe_95',['MQTT_Subscribe',['../core__mqtt_8h.html#a567aa9c38726a7879f9cbf943e813e8f',1,'MQTT_Subscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId): core_mqtt.c'],['../core__mqtt_8c.html#a567aa9c38726a7879f9cbf943e813e8f',1,'MQTT_Subscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId): core_mqtt.c']]], + ['mqtt_5fsubscribe_96',['MQTT_SUBSCRIBE',['../core__mqtt__serializer_8c.html#a92e39b92b76d439a183fc6f5e300195fa7dd20d5d68728190c8c1050599b562f7',1,'core_mqtt_serializer.c']]], + ['mqtt_5fsubscribe_97',['MQTT_Subscribe',['../mqtt_subscribe_function.html',1,'mqtt_functions']]], + ['mqtt_5funsubscribe_98',['MQTT_Unsubscribe',['../core__mqtt_8c.html#a77c911dbe24c5a51aaea88250895dba4',1,'core_mqtt.c']]], + ['mqtt_5funsubscribe_99',['MQTT_UNSUBSCRIBE',['../core__mqtt__serializer_8c.html#a92e39b92b76d439a183fc6f5e300195fa94eb5b78f584ff379c799a142b03e7a7',1,'core_mqtt_serializer.c']]], + ['mqtt_5funsubscribe_100',['MQTT_Unsubscribe',['../core__mqtt_8h.html#a77c911dbe24c5a51aaea88250895dba4',1,'MQTT_Unsubscribe(): core_mqtt.c'],['../mqtt_unsubscribe_function.html',1,'mqtt_functions']]], + ['mqtt_5fupdatestateack_101',['MQTT_UpdateStateAck',['../core__mqtt__state_8c.html#a09a013b709085ffd51faa33c067cce1f',1,'core_mqtt_state.c']]], + ['mqtt_5fupdatestatepublish_102',['MQTT_UpdateStatePublish',['../core__mqtt__state_8c.html#ad657bd67745c66bc50f0441b4cc94763',1,'core_mqtt_state.c']]], + ['mqtt_5fversion_5f3_5f1_5f1_103',['MQTT_VERSION_3_1_1',['../core__mqtt__serializer_8c.html#a7c621dd360dd439f0d6d8dc5d951a619',1,'core_mqtt_serializer.c']]], + ['mqttbadparameter_104',['MQTTBadParameter',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa39030c93b0263b2699502a074f003b5',1,'core_mqtt_serializer.h']]], + ['mqttbadresponse_105',['MQTTBadResponse',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa5d7507e7664a14d63a8bc44b280093e',1,'core_mqtt_serializer.h']]], + ['mqttconnected_106',['MQTTConnected',['../group__mqtt__enum__types.html#gga9f84d003695205cf10a7bd0bafb3dbf6a82c8f64d976734e5632e5257bc429ef5',1,'core_mqtt.h']]], + ['mqttconnectinfo_5ft_107',['MQTTConnectInfo_t',['../struct_m_q_t_t_connect_info__t.html',1,'']]], + ['mqttconnectionstatus_5ft_108',['MQTTConnectionStatus_t',['../group__mqtt__enum__types.html#ga9f84d003695205cf10a7bd0bafb3dbf6',1,'core_mqtt.h']]], + ['mqttcontext_5ft_109',['MQTTContext_t',['../struct_m_q_t_t_context__t.html',1,'']]], + ['mqttdeserializedinfo_5ft_110',['MQTTDeserializedInfo_t',['../struct_m_q_t_t_deserialized_info__t.html',1,'']]], + ['mqtteventcallback_5ft_111',['MQTTEventCallback_t',['../group__mqtt__callback__types.html#ga00d348277ed4fde23c95bfc749ae954a',1,'core_mqtt.h']]], + ['mqttfixedbuffer_5ft_112',['MQTTFixedBuffer_t',['../struct_m_q_t_t_fixed_buffer__t.html',1,'']]], + ['mqttgetcurrenttimefunc_5ft_113',['MQTTGetCurrentTimeFunc_t',['../group__mqtt__callback__types.html#gae3bea55b0e49e5208b8c5709a5ea23aa',1,'core_mqtt.h']]], + ['mqttillegalstate_114',['MQTTIllegalState',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca67905d7a05f98faa557a73eb5092bd8f',1,'core_mqtt_serializer.h']]], + ['mqttkeepalivetimeout_115',['MQTTKeepAliveTimeout',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca076ca8965e836a06e707a94adb26144f',1,'core_mqtt_serializer.h']]], + ['mqttneedmorebytes_116',['MQTTNeedMoreBytes',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa97df53014d919df5ecd54398f89f9b9',1,'core_mqtt_serializer.h']]], + ['mqttnodataavailable_117',['MQTTNoDataAvailable',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca676f21c0ddf297ae3ec874bc829aa957',1,'core_mqtt_serializer.h']]], + ['mqttnomemory_118',['MQTTNoMemory',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735cab1be4db832a0468f024243bca151a8df',1,'core_mqtt_serializer.h']]], + ['mqttnotconnected_119',['MQTTNotConnected',['../group__mqtt__enum__types.html#gga9f84d003695205cf10a7bd0bafb3dbf6a0320177ebf1f1b2e24646b44702cec69',1,'core_mqtt.h']]], + ['mqttpacketinfo_5ft_120',['MQTTPacketInfo_t',['../struct_m_q_t_t_packet_info__t.html',1,'']]], + ['mqttpuback_121',['MQTTPuback',['../group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a53d5939c680962f37c15ee87ffd63d0f',1,'core_mqtt.h']]], + ['mqttpubackinfo_5ft_122',['MQTTPubAckInfo_t',['../struct_m_q_t_t_pub_ack_info__t.html',1,'']]], + ['mqttpubackpending_123',['MQTTPubAckPending',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94ab086c55acf106cdc8d420f90899b6803',1,'core_mqtt.h']]], + ['mqttpubacksend_124',['MQTTPubAckSend',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a65f6f7b343a30fc0558e3aeeb8c97f35',1,'core_mqtt.h']]], + ['mqttpubacktype_5ft_125',['MQTTPubAckType_t',['../group__mqtt__enum__types.html#ga8c1bee959b3ed5fab2a2688dd72bf237',1,'core_mqtt.h']]], + ['mqttpubcomp_126',['MQTTPubcomp',['../group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a910c34311ad6a2341afc04839e1c13bd',1,'core_mqtt.h']]], + ['mqttpubcomppending_127',['MQTTPubCompPending',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a3281a28d1829d954b596f091b547b627',1,'core_mqtt.h']]], + ['mqttpubcompsend_128',['MQTTPubCompSend',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a7d88904d550b502b4424a41aa4205e56',1,'core_mqtt.h']]], + ['mqttpublishdone_129',['MQTTPublishDone',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94ad07733793a235ef9a6a04d16637cd7dc',1,'core_mqtt.h']]], + ['mqttpublishinfo_5ft_130',['MQTTPublishInfo_t',['../struct_m_q_t_t_publish_info__t.html',1,'']]], + ['mqttpublishsend_131',['MQTTPublishSend',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a896b1507647b504c9208580e4cde26ad',1,'core_mqtt.h']]], + ['mqttpublishstate_5ft_132',['MQTTPublishState_t',['../group__mqtt__enum__types.html#ga0480de7552eedd739a26a23fa8e6fd94',1,'core_mqtt.h']]], + ['mqttpubrec_133',['MQTTPubrec',['../group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a8c98d5d1a68dda33d9039009ab4ef053',1,'core_mqtt.h']]], + ['mqttpubrecpending_134',['MQTTPubRecPending',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a1bea59454700be9b683b7eb8aaf6bb4f',1,'core_mqtt.h']]], + ['mqttpubrecsend_135',['MQTTPubRecSend',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a11e2319a2b25b82121471743d39761e1',1,'core_mqtt.h']]], + ['mqttpubrel_136',['MQTTPubrel',['../group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237af2d737088a231c88e7603acfdbc4fc8c',1,'core_mqtt.h']]], + ['mqttpubrelpending_137',['MQTTPubRelPending',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a695431cde1dc9dc5a2dcbd10eba49df2',1,'core_mqtt.h']]], + ['mqttpubrelsend_138',['MQTTPubRelSend',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a5d2ee2709c6dc7a1eb8b9c40f318909b',1,'core_mqtt.h']]], + ['mqttqos0_139',['MQTTQoS0',['../group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aaad51b23a1ae1417f96d8f343c788d1d2',1,'core_mqtt_serializer.h']]], + ['mqttqos1_140',['MQTTQoS1',['../group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aa019d0b8a8cfadb6f98462b046bdacbb2',1,'core_mqtt_serializer.h']]], + ['mqttqos2_141',['MQTTQoS2',['../group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aa85e04ac0465cbdef6dd69ff71b2bbfbb',1,'core_mqtt_serializer.h']]], + ['mqttqos_5ft_142',['MQTTQoS_t',['../group__mqtt__enum__types.html#gae308a5928d7f537379c29a894228093a',1,'core_mqtt_serializer.h']]], + ['mqttrecvfailed_143',['MQTTRecvFailed',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa14bc8aa4ad218702d782366945d43ac',1,'core_mqtt_serializer.h']]], + ['mqttsendfailed_144',['MQTTSendFailed',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735cafd06b63fe9677fa2af06b0f4c7d4ad55',1,'core_mqtt_serializer.h']]], + ['mqttserverrefused_145',['MQTTServerRefused',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca25a3d1747e308e99daa805fe576f84b9',1,'core_mqtt_serializer.h']]], + ['mqttstatecollision_146',['MQTTStateCollision',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca8d05b92240dea6df08eab5a9e3799c11',1,'core_mqtt_serializer.h']]], + ['mqttstatecursor_5ft_147',['MQTTStateCursor_t',['../group__mqtt__basic__types.html#ga2ca7d486d83fe555953a8c7876ee0d6e',1,'core_mqtt_state.h']]], + ['mqttstatenull_148',['MQTTStateNull',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a8349567b7a9efb3913a64a8f4f6fe5c9',1,'core_mqtt.h']]], + ['mqttstatus_5ft_149',['MQTTStatus_t',['../group__mqtt__enum__types.html#gaba7ec045874a1c3432f99173367f735c',1,'core_mqtt_serializer.h']]], + ['mqttsubackfailure_150',['MQTTSubAckFailure',['../group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611aeb83b20da8eda934cde6b92db225a808',1,'core_mqtt.h']]], + ['mqttsubackstatus_5ft_151',['MQTTSubAckStatus_t',['../group__mqtt__enum__types.html#ga48dabc1579e3c0ac6058ce9068054611',1,'core_mqtt.h']]], + ['mqttsubacksuccessqos0_152',['MQTTSubAckSuccessQos0',['../group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611abcc3040d7d53025baee3542c40758abb',1,'core_mqtt.h']]], + ['mqttsubacksuccessqos1_153',['MQTTSubAckSuccessQos1',['../group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611ab180361a6da712c8144d8c499537787d',1,'core_mqtt.h']]], + ['mqttsubacksuccessqos2_154',['MQTTSubAckSuccessQos2',['../group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611a877b2afbc6ec7d9ab57d4862caadf4f1',1,'core_mqtt.h']]], + ['mqttsubscribeinfo_5ft_155',['MQTTSubscribeInfo_t',['../struct_m_q_t_t_subscribe_info__t.html',1,'']]], + ['mqttsubscriptiontype_5ft_156',['MQTTSubscriptionType_t',['../core__mqtt__serializer_8c.html#a92e39b92b76d439a183fc6f5e300195f',1,'core_mqtt_serializer.c']]], + ['mqttsuccess_157',['MQTTSuccess',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca484e062cb4f3fccc1858dd25cfeee056',1,'core_mqtt_serializer.h']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_c.js b/v1.3.0/coreMQTT/search/all_c.js new file mode 100644 index 00000000..0b6647b3 --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_c.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['networkbuffer_0',['networkBuffer',['../struct_m_q_t_t_context__t.html#a231c5576a6ce389317a3f00f95628276',1,'MQTTContext_t']]], + ['networkcontext_5ft_1',['NetworkContext_t',['../group__mqtt__struct__types.html#ga7769e434e7811caed8cd6fd7f9ec26ec',1,'transport_interface.h']]], + ['nextpacketid_2',['nextPacketId',['../struct_m_q_t_t_context__t.html#af47ed55ad7e9bb112324f5f209b70534',1,'MQTTContext_t']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_d.js b/v1.3.0/coreMQTT/search/all_d.js new file mode 100644 index 00000000..614d1aba --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_d.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['outgoingpublishrecordmaxcount_0',['outgoingPublishRecordMaxCount',['../struct_m_q_t_t_context__t.html#a2851073e252d1e744596272ef13dd14a',1,'MQTTContext_t']]], + ['outgoingpublishrecords_1',['outgoingPublishRecords',['../struct_m_q_t_t_context__t.html#a4ea1e37e0e81f010fbf84365ac2ef6de',1,'MQTTContext_t']]], + ['overview_2',['Overview',['../index.html',1,'']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_e.js b/v1.3.0/coreMQTT/search/all_e.js new file mode 100644 index 00000000..b91e420b --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_e.js @@ -0,0 +1,25 @@ +var searchData= +[ + ['packet_5frx_5ftimeout_5fms_0',['PACKET_RX_TIMEOUT_MS',['../core__mqtt__config__defaults_8h.html#a46ef647d5a8315f626dc17d62e264aed',1,'core_mqtt_config_defaults.h']]], + ['packet_5ftx_5ftimeout_5fms_1',['PACKET_TX_TIMEOUT_MS',['../core__mqtt__config__defaults_8h.html#a9b3c7c33badcafec477a205d916424bc',1,'core_mqtt_config_defaults.h']]], + ['packetid_2',['packetId',['../struct_m_q_t_t_pub_ack_info__t.html#a66cef7b43af5d7fdd33b5d2dc766b2d0',1,'MQTTPubAckInfo_t']]], + ['packetidentifier_3',['packetIdentifier',['../struct_m_q_t_t_deserialized_info__t.html#af4df2a9926a4a68059195daa712d9b84',1,'MQTTDeserializedInfo_t']]], + ['parameter_20structures_4',['Parameter Structures',['../group__mqtt__struct__types.html',1,'']]], + ['passwordlength_5',['passwordLength',['../struct_m_q_t_t_connect_info__t.html#a818c4e212a12020a4109eb890ec96383',1,'MQTTConnectInfo_t']]], + ['payloadlength_6',['payloadLength',['../struct_m_q_t_t_publish_info__t.html#a7997964e11571f35f0c3b729db0f760f',1,'MQTTPublishInfo_t']]], + ['pbuffer_7',['pBuffer',['../struct_m_q_t_t_fixed_buffer__t.html#acea147448e044870fb36b7fa2347dbd6',1,'MQTTFixedBuffer_t']]], + ['pclientidentifier_8',['pClientIdentifier',['../struct_m_q_t_t_connect_info__t.html#a010f8f6993cbf8899648d5c515ff7884',1,'MQTTConnectInfo_t']]], + ['pingreqsendtimems_9',['pingReqSendTimeMs',['../struct_m_q_t_t_context__t.html#acca3efa4146d85f7e874c7c326e23556',1,'MQTTContext_t']]], + ['pnetworkcontext_10',['pNetworkContext',['../struct_transport_interface__t.html#aaf4702050bef8d62714a4d3900e95087',1,'TransportInterface_t']]], + ['porting_20guide_11',['Porting Guide',['../mqtt_porting.html',1,'']]], + ['ppassword_12',['pPassword',['../struct_m_q_t_t_connect_info__t.html#acec6c79a11d2f0f130802393f34d2b5e',1,'MQTTConnectInfo_t']]], + ['ppayload_13',['pPayload',['../struct_m_q_t_t_publish_info__t.html#afc28299f4f625f5e674bb61b42f03380',1,'MQTTPublishInfo_t']]], + ['ppublishinfo_14',['pPublishInfo',['../struct_m_q_t_t_deserialized_info__t.html#ac347273fae1e92b9cbeda1714066c1de',1,'MQTTDeserializedInfo_t']]], + ['premainingdata_15',['pRemainingData',['../struct_m_q_t_t_packet_info__t.html#ac66cedff052bc844ec9b296387df60bc',1,'MQTTPacketInfo_t']]], + ['processpublishflags_16',['processPublishFlags',['../core__mqtt__serializer_8c.html#a47a044115ee5df1ac7fe02d2ee37e1e0',1,'core_mqtt_serializer.c']]], + ['processremaininglength_17',['processRemainingLength',['../core__mqtt__serializer_8c.html#a8a4f72e05cd72fa57ba5a90e204569b3',1,'core_mqtt_serializer.c']]], + ['ptopicfilter_18',['pTopicFilter',['../struct_m_q_t_t_subscribe_info__t.html#adb0b28240fdcd82a85f11cf2f8b5bbf0',1,'MQTTSubscribeInfo_t']]], + ['ptopicname_19',['pTopicName',['../struct_m_q_t_t_publish_info__t.html#aa80e8ca282d01630f878ad0afe81d7a4',1,'MQTTPublishInfo_t']]], + ['publishstate_20',['publishState',['../struct_m_q_t_t_pub_ack_info__t.html#a61314203ef87a231c6489c68b579de34',1,'MQTTPubAckInfo_t']]], + ['pusername_21',['pUserName',['../struct_m_q_t_t_connect_info__t.html#a1118d7d3251a11445318557280db53b4',1,'MQTTConnectInfo_t']]] +]; diff --git a/v1.3.0/coreMQTT/search/all_f.js b/v1.3.0/coreMQTT/search/all_f.js new file mode 100644 index 00000000..b55c4097 --- /dev/null +++ b/v1.3.0/coreMQTT/search/all_f.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['qos_0',['qos',['../struct_m_q_t_t_pub_ack_info__t.html#a086fcd48ef0b787697526a95c861e8a0',1,'MQTTPubAckInfo_t::qos()'],['../struct_m_q_t_t_subscribe_info__t.html#a64cf2e423f60cfec122eeaef80c0fd86',1,'MQTTSubscribeInfo_t::qos()'],['../struct_m_q_t_t_publish_info__t.html#a178224d02b4acdec7e08e88de0e4b399',1,'MQTTPublishInfo_t::qos()']]] +]; diff --git a/v1.3.0/coreMQTT/search/classes_0.js b/v1.3.0/coreMQTT/search/classes_0.js new file mode 100644 index 00000000..3abaafa4 --- /dev/null +++ b/v1.3.0/coreMQTT/search/classes_0.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['mqttconnectinfo_5ft_0',['MQTTConnectInfo_t',['../struct_m_q_t_t_connect_info__t.html',1,'']]], + ['mqttcontext_5ft_1',['MQTTContext_t',['../struct_m_q_t_t_context__t.html',1,'']]], + ['mqttdeserializedinfo_5ft_2',['MQTTDeserializedInfo_t',['../struct_m_q_t_t_deserialized_info__t.html',1,'']]], + ['mqttfixedbuffer_5ft_3',['MQTTFixedBuffer_t',['../struct_m_q_t_t_fixed_buffer__t.html',1,'']]], + ['mqttpacketinfo_5ft_4',['MQTTPacketInfo_t',['../struct_m_q_t_t_packet_info__t.html',1,'']]], + ['mqttpubackinfo_5ft_5',['MQTTPubAckInfo_t',['../struct_m_q_t_t_pub_ack_info__t.html',1,'']]], + ['mqttpublishinfo_5ft_6',['MQTTPublishInfo_t',['../struct_m_q_t_t_publish_info__t.html',1,'']]], + ['mqttsubscribeinfo_5ft_7',['MQTTSubscribeInfo_t',['../struct_m_q_t_t_subscribe_info__t.html',1,'']]] +]; diff --git a/v1.3.0/coreMQTT/search/classes_1.js b/v1.3.0/coreMQTT/search/classes_1.js new file mode 100644 index 00000000..46dbff17 --- /dev/null +++ b/v1.3.0/coreMQTT/search/classes_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['transportinterface_5ft_0',['TransportInterface_t',['../struct_transport_interface__t.html',1,'']]], + ['transportoutvector_5ft_1',['TransportOutVector_t',['../struct_transport_out_vector__t.html',1,'']]] +]; diff --git a/v1.3.0/coreMQTT/search/close.svg b/v1.3.0/coreMQTT/search/close.svg new file mode 100644 index 00000000..a933eea1 --- /dev/null +++ b/v1.3.0/coreMQTT/search/close.svg @@ -0,0 +1,31 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/v1.3.0/coreMQTT/search/defines_0.js b/v1.3.0/coreMQTT/search/defines_0.js new file mode 100644 index 00000000..9ba21c3e --- /dev/null +++ b/v1.3.0/coreMQTT/search/defines_0.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['core_5fmqtt_5fserialized_5flength_5ffield_5fbytes_0',['CORE_MQTT_SERIALIZED_LENGTH_FIELD_BYTES',['../core__mqtt_8c.html#a989426922a1f5f04ea8b612fd1f4b185',1,'core_mqtt.c']]], + ['core_5fmqtt_5fsubscribe_5fper_5ftopic_5fvector_5flength_1',['CORE_MQTT_SUBSCRIBE_PER_TOPIC_VECTOR_LENGTH',['../core__mqtt_8c.html#a97f180c9cc32ca9e354e7c22378a386b',1,'core_mqtt.c']]], + ['core_5fmqtt_5funsubscribe_5fper_5ftopic_5fvector_5flength_2',['CORE_MQTT_UNSUBSCRIBE_PER_TOPIC_VECTOR_LENGTH',['../core__mqtt_8c.html#a42477ec456354f2b944b47646ee5a9ce',1,'core_mqtt.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/defines_1.js b/v1.3.0/coreMQTT/search/defines_1.js new file mode 100644 index 00000000..635f7dea --- /dev/null +++ b/v1.3.0/coreMQTT/search/defines_1.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['logdebug_0',['LogDebug',['../core__mqtt__config__defaults_8h.html#af60e8ffc327d136e5d0d8441ed98c98d',1,'core_mqtt_config_defaults.h']]], + ['logerror_1',['LogError',['../core__mqtt__config__defaults_8h.html#a8d9dbaaa88129137a4c68ba0456a18b1',1,'core_mqtt_config_defaults.h']]], + ['loginfo_2',['LogInfo',['../core__mqtt__config__defaults_8h.html#a00810b1cb9d2f25d25ce2d4d93815fba',1,'core_mqtt_config_defaults.h']]], + ['logwarn_3',['LogWarn',['../core__mqtt__config__defaults_8h.html#a7da92048aaf0cbfcacde9539c98a0e05',1,'core_mqtt_config_defaults.h']]] +]; diff --git a/v1.3.0/coreMQTT/search/defines_2.js b/v1.3.0/coreMQTT/search/defines_2.js new file mode 100644 index 00000000..ad224fad --- /dev/null +++ b/v1.3.0/coreMQTT/search/defines_2.js @@ -0,0 +1,36 @@ +var searchData= +[ + ['mqtt_5fconnect_5fflag_5fclean_0',['MQTT_CONNECT_FLAG_CLEAN',['../core__mqtt__serializer_8c.html#a1b131e766e003e36fe499d9f6a79fc03',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fpassword_1',['MQTT_CONNECT_FLAG_PASSWORD',['../core__mqtt__serializer_8c.html#ac5f0bb47789c1182392f5029e0238a81',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fusername_2',['MQTT_CONNECT_FLAG_USERNAME',['../core__mqtt__serializer_8c.html#a8d23d14a4cf296feffb9db79728dd1d0',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fwill_3',['MQTT_CONNECT_FLAG_WILL',['../core__mqtt__serializer_8c.html#a04d8c55ea2b595a277cbcd4340e36d6c',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fwill_5fqos1_4',['MQTT_CONNECT_FLAG_WILL_QOS1',['../core__mqtt__serializer_8c.html#a2aee739b1fa7e61feb907bc92a73c3b4',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fwill_5fqos2_5',['MQTT_CONNECT_FLAG_WILL_QOS2',['../core__mqtt__serializer_8c.html#ac750789b338a2b9be75725ab340dabce',1,'core_mqtt_serializer.c']]], + ['mqtt_5fconnect_5fflag_5fwill_5fretain_6',['MQTT_CONNECT_FLAG_WILL_RETAIN',['../core__mqtt__serializer_8c.html#a8ae294d4ca7960920816339fedbdc4a0',1,'core_mqtt_serializer.c']]], + ['mqtt_5fdisconnect_5fpacket_5fsize_7',['MQTT_DISCONNECT_PACKET_SIZE',['../core__mqtt__serializer_8c.html#abdcffcd69d858203747236b5c4afa834',1,'core_mqtt_serializer.c']]], + ['mqtt_5fdisconnect_5fremaining_5flength_8',['MQTT_DISCONNECT_REMAINING_LENGTH',['../core__mqtt__serializer_8c.html#ac4f3ff016aa6011e3fc707b9f27f6b8c',1,'core_mqtt_serializer.c']]], + ['mqtt_5fdo_5fnot_5fuse_5fcustom_5fconfig_9',['MQTT_DO_NOT_USE_CUSTOM_CONFIG',['../core__mqtt__config__defaults_8h.html#abd12bb401eecf3f6694447ea3b1c886d',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5finvalid_5fstate_5fcount_10',['MQTT_INVALID_STATE_COUNT',['../core__mqtt__state_8c.html#a49d2236ebe2b3d27e82e54a7b9e74984',1,'core_mqtt_state.c']]], + ['mqtt_5fmax_5fconnack_5freceive_5fretry_5fcount_11',['MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT',['../core__mqtt__config__defaults_8h.html#a8ca6c96436d5e7c2c8a7933fb28a5c87',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5fmax_5fremaining_5flength_12',['MQTT_MAX_REMAINING_LENGTH',['../core__mqtt__serializer_8c.html#a9d9ea40a1ff486557a553523a0743647',1,'core_mqtt_serializer.c']]], + ['mqtt_5fmin_5fpublish_5fremaining_5flength_5fqos0_13',['MQTT_MIN_PUBLISH_REMAINING_LENGTH_QOS0',['../core__mqtt__serializer_8c.html#a3b8709529a24bc195c7310183ffbcc2b',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fconnack_5fremaining_5flength_14',['MQTT_PACKET_CONNACK_REMAINING_LENGTH',['../core__mqtt__serializer_8c.html#a999c4ebc0d629df9b08a3c88107b5b80',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fconnack_5fsession_5fpresent_5fmask_15',['MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK',['../core__mqtt__serializer_8c.html#aab69dd14c12f8086245c2371288944f0',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fconnect_5fheader_5fsize_16',['MQTT_PACKET_CONNECT_HEADER_SIZE',['../core__mqtt__serializer_8c.html#aa7c310cb084af0025c356ed844ae443d',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fpingreq_5fsize_17',['MQTT_PACKET_PINGREQ_SIZE',['../core__mqtt__serializer_8c.html#a6e8a49d0d88f0b038a5379d533858103',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fpingresp_5fremaining_5flength_18',['MQTT_PACKET_PINGRESP_REMAINING_LENGTH',['../core__mqtt__serializer_8c.html#aeab5c92e86ed98750cbf6422b8b57c06',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpacket_5fsimple_5fack_5fremaining_5flength_19',['MQTT_PACKET_SIMPLE_ACK_REMAINING_LENGTH',['../core__mqtt__serializer_8c.html#a4c576df64bca769a91cb64d5d5d86505',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpingresp_5ftimeout_5fms_20',['MQTT_PINGRESP_TIMEOUT_MS',['../core__mqtt__config__defaults_8h.html#afa825fddb52da7df88fb56d2befcd2fa',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5fpost_5fsend_5fhook_21',['MQTT_POST_SEND_HOOK',['../core__mqtt_8c.html#a205b7112b6bb0697f85b9e25512c67be',1,'core_mqtt.c']]], + ['mqtt_5fpost_5fstate_5fupdate_5fhook_22',['MQTT_POST_STATE_UPDATE_HOOK',['../core__mqtt_8c.html#a436983fba04e3d13cabea35efc4e9bf8',1,'core_mqtt.c']]], + ['mqtt_5fpre_5fsend_5fhook_23',['MQTT_PRE_SEND_HOOK',['../core__mqtt_8c.html#a18f9369f0d6d553db6d1af1bd7156545',1,'core_mqtt.c']]], + ['mqtt_5fpre_5fstate_5fupdate_5fhook_24',['MQTT_PRE_STATE_UPDATE_HOOK',['../core__mqtt_8c.html#acba4b6e51723d384aa9140313effdf8b',1,'core_mqtt.c']]], + ['mqtt_5fpublish_5fflag_5fdup_25',['MQTT_PUBLISH_FLAG_DUP',['../core__mqtt__serializer_8c.html#a57c437ecc3720de76093b08eb0d4f813',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpublish_5fflag_5fqos1_26',['MQTT_PUBLISH_FLAG_QOS1',['../core__mqtt__serializer_8c.html#ac23212835606fade167fb5ce25eaf103',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpublish_5fflag_5fqos2_27',['MQTT_PUBLISH_FLAG_QOS2',['../core__mqtt__serializer_8c.html#afe1d2a0b7c0803f5a20ebb3c7a607d65',1,'core_mqtt_serializer.c']]], + ['mqtt_5fpublish_5fflag_5fretain_28',['MQTT_PUBLISH_FLAG_RETAIN',['../core__mqtt__serializer_8c.html#a3d04b1e1ad7ec25d18fd13726e164f06',1,'core_mqtt_serializer.c']]], + ['mqtt_5frecv_5fpolling_5ftimeout_5fms_29',['MQTT_RECV_POLLING_TIMEOUT_MS',['../core__mqtt__config__defaults_8h.html#a43dc9a67427d9e420a65955eea0e2671',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5fremaining_5flength_5finvalid_30',['MQTT_REMAINING_LENGTH_INVALID',['../core__mqtt__serializer_8c.html#a6f6b43661df6f9e9e9e7123ab01e9eb5',1,'core_mqtt_serializer.c']]], + ['mqtt_5fsend_5ftimeout_5fms_31',['MQTT_SEND_TIMEOUT_MS',['../core__mqtt__config__defaults_8h.html#ac262cab68c4c713ebc2b91a2e4ab8b19',1,'core_mqtt_config_defaults.h']]], + ['mqtt_5fversion_5f3_5f1_5f1_32',['MQTT_VERSION_3_1_1',['../core__mqtt__serializer_8c.html#a7c621dd360dd439f0d6d8dc5d951a619',1,'core_mqtt_serializer.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/defines_3.js b/v1.3.0/coreMQTT/search/defines_3.js new file mode 100644 index 00000000..b28dafae --- /dev/null +++ b/v1.3.0/coreMQTT/search/defines_3.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['packet_5frx_5ftimeout_5fms_0',['PACKET_RX_TIMEOUT_MS',['../core__mqtt__config__defaults_8h.html#a46ef647d5a8315f626dc17d62e264aed',1,'core_mqtt_config_defaults.h']]], + ['packet_5ftx_5ftimeout_5fms_1',['PACKET_TX_TIMEOUT_MS',['../core__mqtt__config__defaults_8h.html#a9b3c7c33badcafec477a205d916424bc',1,'core_mqtt_config_defaults.h']]] +]; diff --git a/v1.3.0/coreMQTT/search/defines_4.js b/v1.3.0/coreMQTT/search/defines_4.js new file mode 100644 index 00000000..bec633d1 --- /dev/null +++ b/v1.3.0/coreMQTT/search/defines_4.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['uint16_5fbitmap_5fbit_5fset_5fat_0',['UINT16_BITMAP_BIT_SET_AT',['../core__mqtt__state_8c.html#a50892214c51968df798f584272f16a17',1,'core_mqtt_state.c']]], + ['uint16_5fcheck_5fbit_1',['UINT16_CHECK_BIT',['../core__mqtt__state_8c.html#a085ab1307745f304ce2e6d24bdc3f6a7',1,'core_mqtt_state.c']]], + ['uint16_5fdecode_2',['UINT16_DECODE',['../core__mqtt__serializer_8c.html#acc849aa739edff3ec532219a3860a3a0',1,'core_mqtt_serializer.c']]], + ['uint16_5fhigh_5fbyte_3',['UINT16_HIGH_BYTE',['../core__mqtt__serializer_8c.html#a24aab781ef139dd38be534ee137ea2f9',1,'core_mqtt_serializer.c']]], + ['uint16_5flow_5fbyte_4',['UINT16_LOW_BYTE',['../core__mqtt__serializer_8c.html#af2ae35b27e0140a77238cd175508cb4e',1,'core_mqtt_serializer.c']]], + ['uint16_5fset_5fbit_5',['UINT16_SET_BIT',['../core__mqtt__state_8c.html#acd96521b31682b7d93de544704fd9594',1,'core_mqtt_state.c']]], + ['uint8_5fcheck_5fbit_6',['UINT8_CHECK_BIT',['../core__mqtt__serializer_8c.html#a07cc5f3f934e1ebf8011a6c15a667206',1,'core_mqtt_serializer.c']]], + ['uint8_5fset_5fbit_7',['UINT8_SET_BIT',['../core__mqtt__serializer_8c.html#af259c91b3075c24df53fa3ffe516b208',1,'core_mqtt_serializer.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/enums_0.js b/v1.3.0/coreMQTT/search/enums_0.js new file mode 100644 index 00000000..7f127dd8 --- /dev/null +++ b/v1.3.0/coreMQTT/search/enums_0.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['mqttconnectionstatus_5ft_0',['MQTTConnectionStatus_t',['../group__mqtt__enum__types.html#ga9f84d003695205cf10a7bd0bafb3dbf6',1,'core_mqtt.h']]], + ['mqttpubacktype_5ft_1',['MQTTPubAckType_t',['../group__mqtt__enum__types.html#ga8c1bee959b3ed5fab2a2688dd72bf237',1,'core_mqtt.h']]], + ['mqttpublishstate_5ft_2',['MQTTPublishState_t',['../group__mqtt__enum__types.html#ga0480de7552eedd739a26a23fa8e6fd94',1,'core_mqtt.h']]], + ['mqttqos_5ft_3',['MQTTQoS_t',['../group__mqtt__enum__types.html#gae308a5928d7f537379c29a894228093a',1,'core_mqtt_serializer.h']]], + ['mqttstatus_5ft_4',['MQTTStatus_t',['../group__mqtt__enum__types.html#gaba7ec045874a1c3432f99173367f735c',1,'core_mqtt_serializer.h']]], + ['mqttsubackstatus_5ft_5',['MQTTSubAckStatus_t',['../group__mqtt__enum__types.html#ga48dabc1579e3c0ac6058ce9068054611',1,'core_mqtt.h']]], + ['mqttsubscriptiontype_5ft_6',['MQTTSubscriptionType_t',['../core__mqtt__serializer_8c.html#a92e39b92b76d439a183fc6f5e300195f',1,'core_mqtt_serializer.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/enumvalues_0.js b/v1.3.0/coreMQTT/search/enumvalues_0.js new file mode 100644 index 00000000..01a3695f --- /dev/null +++ b/v1.3.0/coreMQTT/search/enumvalues_0.js @@ -0,0 +1,41 @@ +var searchData= +[ + ['mqtt_5fsubscribe_0',['MQTT_SUBSCRIBE',['../core__mqtt__serializer_8c.html#a92e39b92b76d439a183fc6f5e300195fa7dd20d5d68728190c8c1050599b562f7',1,'core_mqtt_serializer.c']]], + ['mqtt_5funsubscribe_1',['MQTT_UNSUBSCRIBE',['../core__mqtt__serializer_8c.html#a92e39b92b76d439a183fc6f5e300195fa94eb5b78f584ff379c799a142b03e7a7',1,'core_mqtt_serializer.c']]], + ['mqttbadparameter_2',['MQTTBadParameter',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa39030c93b0263b2699502a074f003b5',1,'core_mqtt_serializer.h']]], + ['mqttbadresponse_3',['MQTTBadResponse',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa5d7507e7664a14d63a8bc44b280093e',1,'core_mqtt_serializer.h']]], + ['mqttconnected_4',['MQTTConnected',['../group__mqtt__enum__types.html#gga9f84d003695205cf10a7bd0bafb3dbf6a82c8f64d976734e5632e5257bc429ef5',1,'core_mqtt.h']]], + ['mqttillegalstate_5',['MQTTIllegalState',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca67905d7a05f98faa557a73eb5092bd8f',1,'core_mqtt_serializer.h']]], + ['mqttkeepalivetimeout_6',['MQTTKeepAliveTimeout',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca076ca8965e836a06e707a94adb26144f',1,'core_mqtt_serializer.h']]], + ['mqttneedmorebytes_7',['MQTTNeedMoreBytes',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa97df53014d919df5ecd54398f89f9b9',1,'core_mqtt_serializer.h']]], + ['mqttnodataavailable_8',['MQTTNoDataAvailable',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca676f21c0ddf297ae3ec874bc829aa957',1,'core_mqtt_serializer.h']]], + ['mqttnomemory_9',['MQTTNoMemory',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735cab1be4db832a0468f024243bca151a8df',1,'core_mqtt_serializer.h']]], + ['mqttnotconnected_10',['MQTTNotConnected',['../group__mqtt__enum__types.html#gga9f84d003695205cf10a7bd0bafb3dbf6a0320177ebf1f1b2e24646b44702cec69',1,'core_mqtt.h']]], + ['mqttpuback_11',['MQTTPuback',['../group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a53d5939c680962f37c15ee87ffd63d0f',1,'core_mqtt.h']]], + ['mqttpubackpending_12',['MQTTPubAckPending',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94ab086c55acf106cdc8d420f90899b6803',1,'core_mqtt.h']]], + ['mqttpubacksend_13',['MQTTPubAckSend',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a65f6f7b343a30fc0558e3aeeb8c97f35',1,'core_mqtt.h']]], + ['mqttpubcomp_14',['MQTTPubcomp',['../group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a910c34311ad6a2341afc04839e1c13bd',1,'core_mqtt.h']]], + ['mqttpubcomppending_15',['MQTTPubCompPending',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a3281a28d1829d954b596f091b547b627',1,'core_mqtt.h']]], + ['mqttpubcompsend_16',['MQTTPubCompSend',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a7d88904d550b502b4424a41aa4205e56',1,'core_mqtt.h']]], + ['mqttpublishdone_17',['MQTTPublishDone',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94ad07733793a235ef9a6a04d16637cd7dc',1,'core_mqtt.h']]], + ['mqttpublishsend_18',['MQTTPublishSend',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a896b1507647b504c9208580e4cde26ad',1,'core_mqtt.h']]], + ['mqttpubrec_19',['MQTTPubrec',['../group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a8c98d5d1a68dda33d9039009ab4ef053',1,'core_mqtt.h']]], + ['mqttpubrecpending_20',['MQTTPubRecPending',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a1bea59454700be9b683b7eb8aaf6bb4f',1,'core_mqtt.h']]], + ['mqttpubrecsend_21',['MQTTPubRecSend',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a11e2319a2b25b82121471743d39761e1',1,'core_mqtt.h']]], + ['mqttpubrel_22',['MQTTPubrel',['../group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237af2d737088a231c88e7603acfdbc4fc8c',1,'core_mqtt.h']]], + ['mqttpubrelpending_23',['MQTTPubRelPending',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a695431cde1dc9dc5a2dcbd10eba49df2',1,'core_mqtt.h']]], + ['mqttpubrelsend_24',['MQTTPubRelSend',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a5d2ee2709c6dc7a1eb8b9c40f318909b',1,'core_mqtt.h']]], + ['mqttqos0_25',['MQTTQoS0',['../group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aaad51b23a1ae1417f96d8f343c788d1d2',1,'core_mqtt_serializer.h']]], + ['mqttqos1_26',['MQTTQoS1',['../group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aa019d0b8a8cfadb6f98462b046bdacbb2',1,'core_mqtt_serializer.h']]], + ['mqttqos2_27',['MQTTQoS2',['../group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aa85e04ac0465cbdef6dd69ff71b2bbfbb',1,'core_mqtt_serializer.h']]], + ['mqttrecvfailed_28',['MQTTRecvFailed',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa14bc8aa4ad218702d782366945d43ac',1,'core_mqtt_serializer.h']]], + ['mqttsendfailed_29',['MQTTSendFailed',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735cafd06b63fe9677fa2af06b0f4c7d4ad55',1,'core_mqtt_serializer.h']]], + ['mqttserverrefused_30',['MQTTServerRefused',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca25a3d1747e308e99daa805fe576f84b9',1,'core_mqtt_serializer.h']]], + ['mqttstatecollision_31',['MQTTStateCollision',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca8d05b92240dea6df08eab5a9e3799c11',1,'core_mqtt_serializer.h']]], + ['mqttstatenull_32',['MQTTStateNull',['../group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a8349567b7a9efb3913a64a8f4f6fe5c9',1,'core_mqtt.h']]], + ['mqttsubackfailure_33',['MQTTSubAckFailure',['../group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611aeb83b20da8eda934cde6b92db225a808',1,'core_mqtt.h']]], + ['mqttsubacksuccessqos0_34',['MQTTSubAckSuccessQos0',['../group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611abcc3040d7d53025baee3542c40758abb',1,'core_mqtt.h']]], + ['mqttsubacksuccessqos1_35',['MQTTSubAckSuccessQos1',['../group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611ab180361a6da712c8144d8c499537787d',1,'core_mqtt.h']]], + ['mqttsubacksuccessqos2_36',['MQTTSubAckSuccessQos2',['../group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611a877b2afbc6ec7d9ab57d4862caadf4f1',1,'core_mqtt.h']]], + ['mqttsuccess_37',['MQTTSuccess',['../group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca484e062cb4f3fccc1858dd25cfeee056',1,'core_mqtt_serializer.h']]] +]; diff --git a/v1.3.0/coreMQTT/search/files_0.js b/v1.3.0/coreMQTT/search/files_0.js new file mode 100644 index 00000000..65ced30d --- /dev/null +++ b/v1.3.0/coreMQTT/search/files_0.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['core_5fmqtt_2ec_0',['core_mqtt.c',['../core__mqtt_8c.html',1,'']]], + ['core_5fmqtt_2eh_1',['core_mqtt.h',['../core__mqtt_8h.html',1,'']]], + ['core_5fmqtt_5fconfig_5fdefaults_2eh_2',['core_mqtt_config_defaults.h',['../core__mqtt__config__defaults_8h.html',1,'']]], + ['core_5fmqtt_5fserializer_2ec_3',['core_mqtt_serializer.c',['../core__mqtt__serializer_8c.html',1,'']]], + ['core_5fmqtt_5fserializer_2eh_4',['core_mqtt_serializer.h',['../core__mqtt__serializer_8h.html',1,'']]], + ['core_5fmqtt_5fstate_2ec_5',['core_mqtt_state.c',['../core__mqtt__state_8c.html',1,'']]], + ['core_5fmqtt_5fstate_2eh_6',['core_mqtt_state.h',['../core__mqtt__state_8h.html',1,'']]] +]; diff --git a/v1.3.0/coreMQTT/search/files_1.js b/v1.3.0/coreMQTT/search/files_1.js new file mode 100644 index 00000000..1beeb5d6 --- /dev/null +++ b/v1.3.0/coreMQTT/search/files_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['transport_5finterface_2eh_0',['transport_interface.h',['../transport__interface_8h.html',1,'']]] +]; diff --git a/v1.3.0/coreMQTT/search/functions_0.js b/v1.3.0/coreMQTT/search/functions_0.js new file mode 100644 index 00000000..2621cb9f --- /dev/null +++ b/v1.3.0/coreMQTT/search/functions_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['addencodedstringtovector_0',['addEncodedStringToVector',['../core__mqtt_8c.html#a35952c4a02872c18702e7fbbdb1c467f',1,'core_mqtt.c']]], + ['addrecord_1',['addRecord',['../core__mqtt__state_8c.html#a5d0ffdfde0c38a1cc1d4e3f4750a8cc4',1,'core_mqtt_state.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/functions_1.js b/v1.3.0/coreMQTT/search/functions_1.js new file mode 100644 index 00000000..719c44ae --- /dev/null +++ b/v1.3.0/coreMQTT/search/functions_1.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['calculateelapsedtime_0',['calculateElapsedTime',['../core__mqtt_8c.html#a04f9f5742bc28fe29e61f3f46d20d3d6',1,'core_mqtt.c']]], + ['calculatepublishpacketsize_1',['calculatePublishPacketSize',['../core__mqtt__serializer_8c.html#a76d0156e521588fb3319043f9d35ea9a',1,'core_mqtt_serializer.c']]], + ['calculatesubscriptionpacketsize_2',['calculateSubscriptionPacketSize',['../core__mqtt__serializer_8c.html#abdbabda0aa9db25166963afa975adb10',1,'core_mqtt_serializer.c']]], + ['checkpublishremaininglength_3',['checkPublishRemainingLength',['../core__mqtt__serializer_8c.html#a33a2680aab1ce2186acd7c78aeb270f1',1,'core_mqtt_serializer.c']]], + ['compactrecords_4',['compactRecords',['../core__mqtt__state_8c.html#a6cd7b86de2ddb125fee886d58d1a5fd4',1,'core_mqtt_state.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/functions_2.js b/v1.3.0/coreMQTT/search/functions_2.js new file mode 100644 index 00000000..920a90c3 --- /dev/null +++ b/v1.3.0/coreMQTT/search/functions_2.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['deserializeconnack_0',['deserializeConnack',['../core__mqtt__serializer_8c.html#aa7b25e1e3114536e9b0526fc93a1f76c',1,'core_mqtt_serializer.c']]], + ['deserializepingresp_1',['deserializePingresp',['../core__mqtt__serializer_8c.html#afdd9b08562ccaa6cf8dd68baa6bc7060',1,'core_mqtt_serializer.c']]], + ['deserializepublish_2',['deserializePublish',['../core__mqtt__serializer_8c.html#a6e8bcde1280e14706e0cb9180358607c',1,'core_mqtt_serializer.c']]], + ['deserializesimpleack_3',['deserializeSimpleAck',['../core__mqtt__serializer_8c.html#a5d437c287290fa28a0ed65635fd6c9ae',1,'core_mqtt_serializer.c']]], + ['deserializesuback_4',['deserializeSuback',['../core__mqtt__serializer_8c.html#ae7b71036fc19c9a6da480dcfd3a2387b',1,'core_mqtt_serializer.c']]], + ['discardpacket_5',['discardPacket',['../core__mqtt_8c.html#abb02f1853a4805205636f2c11a435216',1,'core_mqtt.c']]], + ['discardstoredpacket_6',['discardStoredPacket',['../core__mqtt_8c.html#af827b2088c38c31a0b75dc70377db536',1,'core_mqtt.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/functions_3.js b/v1.3.0/coreMQTT/search/functions_3.js new file mode 100644 index 00000000..11f3261d --- /dev/null +++ b/v1.3.0/coreMQTT/search/functions_3.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['encoderemaininglength_0',['encodeRemainingLength',['../core__mqtt__serializer_8c.html#a3a3858fbb0cbd845f208b3fc60f36130',1,'core_mqtt_serializer.c']]], + ['encodestring_1',['encodeString',['../core__mqtt__serializer_8c.html#a60e580c28431eb08f05a156949137f1f',1,'core_mqtt_serializer.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/functions_4.js b/v1.3.0/coreMQTT/search/functions_4.js new file mode 100644 index 00000000..3a875e59 --- /dev/null +++ b/v1.3.0/coreMQTT/search/functions_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['findinrecord_0',['findInRecord',['../core__mqtt__state_8c.html#ac805558ac65e84ea9111ce70c873e59e',1,'core_mqtt_state.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/functions_5.js b/v1.3.0/coreMQTT/search/functions_5.js new file mode 100644 index 00000000..bf76372e --- /dev/null +++ b/v1.3.0/coreMQTT/search/functions_5.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['getackfrompackettype_0',['getAckFromPacketType',['../core__mqtt_8c.html#aa1f35063dbe3b2c35f278ea6aa347a0e',1,'core_mqtt.c']]], + ['getacktypetosend_1',['getAckTypeToSend',['../core__mqtt_8c.html#a02f112e21a6d0b87a3c69ef300d264de',1,'core_mqtt.c']]], + ['getremaininglength_2',['getRemainingLength',['../core__mqtt__serializer_8c.html#a5685b753d1d42788a00bd59ffa4639e2',1,'core_mqtt_serializer.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/functions_6.js b/v1.3.0/coreMQTT/search/functions_6.js new file mode 100644 index 00000000..3041f294 --- /dev/null +++ b/v1.3.0/coreMQTT/search/functions_6.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['handleincomingack_0',['handleIncomingAck',['../core__mqtt_8c.html#a264afa489cbfbd96086614d335969115',1,'core_mqtt.c']]], + ['handleincomingpublish_1',['handleIncomingPublish',['../core__mqtt_8c.html#a4ac6e6829500c4f522eae413c9470e4d',1,'core_mqtt.c']]], + ['handlekeepalive_2',['handleKeepAlive',['../core__mqtt_8c.html#ae0e50de302a1aa66e3c5b2cdcacc4f3f',1,'core_mqtt.c']]], + ['handlepublishacks_3',['handlePublishAcks',['../core__mqtt_8c.html#a2363868c0417261c27c750251aad13e5',1,'core_mqtt.c']]], + ['handlesessionresumption_4',['handleSessionResumption',['../core__mqtt_8c.html#aae9ba11e41bc1dfef340208bc49c836c',1,'core_mqtt.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/functions_7.js b/v1.3.0/coreMQTT/search/functions_7.js new file mode 100644 index 00000000..adb39651 --- /dev/null +++ b/v1.3.0/coreMQTT/search/functions_7.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['incomingpacketvalid_0',['incomingPacketValid',['../core__mqtt__serializer_8c.html#a03dfebbfbc1635567839f7abb7c0f8db',1,'core_mqtt_serializer.c']]], + ['ispublishoutgoing_1',['isPublishOutgoing',['../core__mqtt__state_8c.html#aaf9d4c6e766e40189ff7b68ffea40aa0',1,'core_mqtt_state.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/functions_8.js b/v1.3.0/coreMQTT/search/functions_8.js new file mode 100644 index 00000000..918f1c59 --- /dev/null +++ b/v1.3.0/coreMQTT/search/functions_8.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['logconnackresponse_0',['logConnackResponse',['../core__mqtt__serializer_8c.html#a5451f2e3468faaf2bdf85220ebb95aaa',1,'core_mqtt_serializer.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/functions_9.js b/v1.3.0/coreMQTT/search/functions_9.js new file mode 100644 index 00000000..f6d9361b --- /dev/null +++ b/v1.3.0/coreMQTT/search/functions_9.js @@ -0,0 +1,52 @@ +var searchData= +[ + ['matchendwildcardsspecialcases_0',['matchEndWildcardsSpecialCases',['../core__mqtt_8c.html#ab29bb66fe7385c52452a3087bcfbc98e',1,'core_mqtt.c']]], + ['matchtopicfilter_1',['matchTopicFilter',['../core__mqtt_8c.html#a4c052d9dd6a81e866121c24a2ee2aa0b',1,'core_mqtt.c']]], + ['matchwildcards_2',['matchWildcards',['../core__mqtt_8c.html#ab1f061741c445d07454cfa03786a5eea',1,'core_mqtt.c']]], + ['mqtt_5fcalculatestateack_3',['MQTT_CalculateStateAck',['../core__mqtt__state_8c.html#a0cad28e34f03b84aff43ee243ce8e2cf',1,'core_mqtt_state.c']]], + ['mqtt_5fcalculatestatepublish_4',['MQTT_CalculateStatePublish',['../core__mqtt__state_8c.html#aadc4fdd8af74ac25b848a33e916bff50',1,'core_mqtt_state.c']]], + ['mqtt_5fcancelcallback_5',['MQTT_CancelCallback',['../core__mqtt_8h.html#a31b74c34cd295b98ed5f5b4c15ed4a8b',1,'MQTT_CancelCallback(const MQTTContext_t *pContext, uint16_t packetId): core_mqtt.c'],['../core__mqtt_8c.html#a31b74c34cd295b98ed5f5b4c15ed4a8b',1,'MQTT_CancelCallback(const MQTTContext_t *pContext, uint16_t packetId): core_mqtt.c']]], + ['mqtt_5fconnect_6',['MQTT_Connect',['../core__mqtt_8h.html#aed1e4dc123a8ba79ac569cb17c69bfa0',1,'MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent): core_mqtt.c'],['../core__mqtt_8c.html#aed1e4dc123a8ba79ac569cb17c69bfa0',1,'MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent): core_mqtt.c']]], + ['mqtt_5fdeserializeack_7',['MQTT_DeserializeAck',['../core__mqtt__serializer_8h.html#ae9971855df71edf94124116e0625bf18',1,'MQTT_DeserializeAck(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, bool *pSessionPresent): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#ae9971855df71edf94124116e0625bf18',1,'MQTT_DeserializeAck(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, bool *pSessionPresent): core_mqtt_serializer.c']]], + ['mqtt_5fdeserializepublish_8',['MQTT_DeserializePublish',['../core__mqtt__serializer_8h.html#a4c2aec031f31d0fe55c1cda46544e95a',1,'MQTT_DeserializePublish(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a4c2aec031f31d0fe55c1cda46544e95a',1,'MQTT_DeserializePublish(const MQTTPacketInfo_t *pIncomingPacket, uint16_t *pPacketId, MQTTPublishInfo_t *pPublishInfo): core_mqtt_serializer.c']]], + ['mqtt_5fdisconnect_9',['MQTT_Disconnect',['../core__mqtt_8h.html#ac79c366acbc3dddd88072d99ccb9140c',1,'MQTT_Disconnect(MQTTContext_t *pContext): core_mqtt.c'],['../core__mqtt_8c.html#ac79c366acbc3dddd88072d99ccb9140c',1,'MQTT_Disconnect(MQTTContext_t *pContext): core_mqtt.c']]], + ['mqtt_5fgetconnectpacketsize_10',['MQTT_GetConnectPacketSize',['../core__mqtt__serializer_8h.html#a4e57ccef527a25b572dc66eeb2e217c5',1,'MQTT_GetConnectPacketSize(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a4e57ccef527a25b572dc66eeb2e217c5',1,'MQTT_GetConnectPacketSize(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c']]], + ['mqtt_5fgetdisconnectpacketsize_11',['MQTT_GetDisconnectPacketSize',['../core__mqtt__serializer_8h.html#a6fdd8cbde6b7c4ff85c20aaca0fd8741',1,'MQTT_GetDisconnectPacketSize(size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a6fdd8cbde6b7c4ff85c20aaca0fd8741',1,'MQTT_GetDisconnectPacketSize(size_t *pPacketSize): core_mqtt_serializer.c']]], + ['mqtt_5fgetincomingpackettypeandlength_12',['MQTT_GetIncomingPacketTypeAndLength',['../core__mqtt__serializer_8h.html#a98cdda86f86a0a1888745a584199e930',1,'MQTT_GetIncomingPacketTypeAndLength(TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a98cdda86f86a0a1888745a584199e930',1,'MQTT_GetIncomingPacketTypeAndLength(TransportRecv_t readFunc, NetworkContext_t *pNetworkContext, MQTTPacketInfo_t *pIncomingPacket): core_mqtt_serializer.c']]], + ['mqtt_5fgetpacketid_13',['MQTT_GetPacketId',['../core__mqtt_8c.html#a00e1a3eba2c21899a6b4312c7d65d090',1,'MQTT_GetPacketId(MQTTContext_t *pContext): core_mqtt.c'],['../core__mqtt_8h.html#a00e1a3eba2c21899a6b4312c7d65d090',1,'MQTT_GetPacketId(MQTTContext_t *pContext): core_mqtt.c']]], + ['mqtt_5fgetpingreqpacketsize_14',['MQTT_GetPingreqPacketSize',['../core__mqtt__serializer_8h.html#a015562f30e220d2534f773bfa45a5cfe',1,'MQTT_GetPingreqPacketSize(size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a015562f30e220d2534f773bfa45a5cfe',1,'MQTT_GetPingreqPacketSize(size_t *pPacketSize): core_mqtt_serializer.c']]], + ['mqtt_5fgetpublishpacketsize_15',['MQTT_GetPublishPacketSize',['../core__mqtt__serializer_8h.html#a9971fb98c6af22b1bfe697d44492a819',1,'MQTT_GetPublishPacketSize(const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a9971fb98c6af22b1bfe697d44492a819',1,'MQTT_GetPublishPacketSize(const MQTTPublishInfo_t *pPublishInfo, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c']]], + ['mqtt_5fgetsubackstatuscodes_16',['MQTT_GetSubAckStatusCodes',['../core__mqtt_8h.html#ac43449e06856c6703cda73359c222bd2',1,'MQTT_GetSubAckStatusCodes(const MQTTPacketInfo_t *pSubackPacket, uint8_t **pPayloadStart, size_t *pPayloadSize): core_mqtt.c'],['../core__mqtt_8c.html#ac43449e06856c6703cda73359c222bd2',1,'MQTT_GetSubAckStatusCodes(const MQTTPacketInfo_t *pSubackPacket, uint8_t **pPayloadStart, size_t *pPayloadSize): core_mqtt.c']]], + ['mqtt_5fgetsubscribepacketsize_17',['MQTT_GetSubscribePacketSize',['../core__mqtt__serializer_8h.html#abb9a703cb23ab39fdd6fe282a5f3ddc5',1,'MQTT_GetSubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#abb9a703cb23ab39fdd6fe282a5f3ddc5',1,'MQTT_GetSubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c']]], + ['mqtt_5fgetunsubscribepacketsize_18',['MQTT_GetUnsubscribePacketSize',['../core__mqtt__serializer_8c.html#a2a18563d5f63c8975b57118a6836c932',1,'MQTT_GetUnsubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#a2a18563d5f63c8975b57118a6836c932',1,'MQTT_GetUnsubscribePacketSize(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, size_t *pRemainingLength, size_t *pPacketSize): core_mqtt_serializer.c']]], + ['mqtt_5finit_19',['MQTT_Init',['../core__mqtt_8h.html#ae8444f3a85535e62cdb1ae9c192677d6',1,'MQTT_Init(MQTTContext_t *pContext, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getTimeFunction, MQTTEventCallback_t userCallback, const MQTTFixedBuffer_t *pNetworkBuffer): core_mqtt.c'],['../core__mqtt_8c.html#ae8444f3a85535e62cdb1ae9c192677d6',1,'MQTT_Init(MQTTContext_t *pContext, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getTimeFunction, MQTTEventCallback_t userCallback, const MQTTFixedBuffer_t *pNetworkBuffer): core_mqtt.c']]], + ['mqtt_5finitstatefulqos_20',['MQTT_InitStatefulQoS',['../core__mqtt_8h.html#afe4c020749e3b9ca044e0e9ad96025c5',1,'MQTT_InitStatefulQoS(MQTTContext_t *pContext, MQTTPubAckInfo_t *pOutgoingPublishRecords, size_t outgoingPublishCount, MQTTPubAckInfo_t *pIncomingPublishRecords, size_t incomingPublishCount): core_mqtt.c'],['../core__mqtt_8c.html#afe4c020749e3b9ca044e0e9ad96025c5',1,'MQTT_InitStatefulQoS(MQTTContext_t *pContext, MQTTPubAckInfo_t *pOutgoingPublishRecords, size_t outgoingPublishCount, MQTTPubAckInfo_t *pIncomingPublishRecords, size_t incomingPublishCount): core_mqtt.c']]], + ['mqtt_5fmatchtopic_21',['MQTT_MatchTopic',['../core__mqtt_8h.html#a633409812b18547365ec9b853069021b',1,'MQTT_MatchTopic(const char *pTopicName, const uint16_t topicNameLength, const char *pTopicFilter, const uint16_t topicFilterLength, bool *pIsMatch): core_mqtt.c'],['../core__mqtt_8c.html#a633409812b18547365ec9b853069021b',1,'MQTT_MatchTopic(const char *pTopicName, const uint16_t topicNameLength, const char *pTopicFilter, const uint16_t topicFilterLength, bool *pIsMatch): core_mqtt.c']]], + ['mqtt_5fping_22',['MQTT_Ping',['../core__mqtt_8h.html#a66eced0c62ace790354ae3de40fc0959',1,'MQTT_Ping(MQTTContext_t *pContext): core_mqtt.c'],['../core__mqtt_8c.html#a66eced0c62ace790354ae3de40fc0959',1,'MQTT_Ping(MQTTContext_t *pContext): core_mqtt.c']]], + ['mqtt_5fprocessincomingpackettypeandlength_23',['MQTT_ProcessIncomingPacketTypeAndLength',['../core__mqtt__serializer_8c.html#a94fd3f746074b3f6e16ae6b23dad9a28',1,'MQTT_ProcessIncomingPacketTypeAndLength(const uint8_t *pBuffer, const size_t *pIndex, MQTTPacketInfo_t *pIncomingPacket): core_mqtt_serializer.c'],['../core__mqtt__serializer_8h.html#a94fd3f746074b3f6e16ae6b23dad9a28',1,'MQTT_ProcessIncomingPacketTypeAndLength(const uint8_t *pBuffer, const size_t *pIndex, MQTTPacketInfo_t *pIncomingPacket): core_mqtt_serializer.c']]], + ['mqtt_5fprocessloop_24',['MQTT_ProcessLoop',['../core__mqtt_8h.html#ab95d3d6b3eed98a6184fb2018c5b55d7',1,'MQTT_ProcessLoop(MQTTContext_t *pContext): core_mqtt.c'],['../core__mqtt_8c.html#ab95d3d6b3eed98a6184fb2018c5b55d7',1,'MQTT_ProcessLoop(MQTTContext_t *pContext): core_mqtt.c']]], + ['mqtt_5fpublish_25',['MQTT_Publish',['../core__mqtt_8h.html#a1d8217e9d30fb2aed002060a8c97c63e',1,'MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId): core_mqtt.c'],['../core__mqtt_8c.html#a1d8217e9d30fb2aed002060a8c97c63e',1,'MQTT_Publish(MQTTContext_t *pContext, const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId): core_mqtt.c']]], + ['mqtt_5fpublishtoresend_26',['MQTT_PublishToResend',['../core__mqtt__state_8h.html#a44b3cf50dc477a9f97413a9238a961f6',1,'MQTT_PublishToResend(const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor): core_mqtt_state.c'],['../core__mqtt__state_8c.html#a44b3cf50dc477a9f97413a9238a961f6',1,'MQTT_PublishToResend(const MQTTContext_t *pMqttContext, MQTTStateCursor_t *pCursor): core_mqtt_state.c']]], + ['mqtt_5fpubreltoresend_27',['MQTT_PubrelToResend',['../core__mqtt__state_8c.html#ae58ade262ec01262687554b349b2fdf5',1,'core_mqtt_state.c']]], + ['mqtt_5freceiveloop_28',['MQTT_ReceiveLoop',['../core__mqtt_8h.html#aeb7c37284fcf6f68eb577427a6763fc6',1,'MQTT_ReceiveLoop(MQTTContext_t *pContext): core_mqtt.c'],['../core__mqtt_8c.html#aeb7c37284fcf6f68eb577427a6763fc6',1,'MQTT_ReceiveLoop(MQTTContext_t *pContext): core_mqtt.c']]], + ['mqtt_5fremovestaterecord_29',['MQTT_RemoveStateRecord',['../core__mqtt__state_8c.html#aef2c13cffbbd5c71183282e69ac9d799',1,'core_mqtt_state.c']]], + ['mqtt_5freservestate_30',['MQTT_ReserveState',['../core__mqtt__state_8c.html#a43bc5d82716e1d8b6e167ec0fe50de5d',1,'core_mqtt_state.c']]], + ['mqtt_5fserializeack_31',['MQTT_SerializeAck',['../core__mqtt__serializer_8h.html#a11ea4ac5ea27e93121288e463ca34ee6',1,'MQTT_SerializeAck(const MQTTFixedBuffer_t *pFixedBuffer, uint8_t packetType, uint16_t packetId): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a11ea4ac5ea27e93121288e463ca34ee6',1,'MQTT_SerializeAck(const MQTTFixedBuffer_t *pFixedBuffer, uint8_t packetType, uint16_t packetId): core_mqtt_serializer.c']]], + ['mqtt_5fserializeconnect_32',['MQTT_SerializeConnect',['../core__mqtt__serializer_8h.html#aa2e2300d6c43e61f8f2cf83f7149835c',1,'MQTT_SerializeConnect(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#aa2e2300d6c43e61f8f2cf83f7149835c',1,'MQTT_SerializeConnect(const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c']]], + ['mqtt_5fserializeconnectfixedheader_33',['MQTT_SerializeConnectFixedHeader',['../core__mqtt__serializer_8c.html#a5e6043289c05db1cdb7e33e0921247a0',1,'core_mqtt_serializer.c']]], + ['mqtt_5fserializedisconnect_34',['MQTT_SerializeDisconnect',['../core__mqtt__serializer_8h.html#a6aae40d4656eb533a74b67bf9c827d3b',1,'MQTT_SerializeDisconnect(const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a6aae40d4656eb533a74b67bf9c827d3b',1,'MQTT_SerializeDisconnect(const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c']]], + ['mqtt_5fserializepingreq_35',['MQTT_SerializePingreq',['../core__mqtt__serializer_8h.html#af3b3e40858fd984c871511e02a61e15d',1,'MQTT_SerializePingreq(const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#af3b3e40858fd984c871511e02a61e15d',1,'MQTT_SerializePingreq(const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c']]], + ['mqtt_5fserializepublish_36',['MQTT_SerializePublish',['../core__mqtt__serializer_8h.html#ac6c453f9c4b7f48aad511bc677ec7eb9',1,'MQTT_SerializePublish(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#ac6c453f9c4b7f48aad511bc677ec7eb9',1,'MQTT_SerializePublish(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c']]], + ['mqtt_5fserializepublishheader_37',['MQTT_SerializePublishHeader',['../core__mqtt__serializer_8h.html#a659cf2bcaf2c5131daa0acc1917401a2',1,'MQTT_SerializePublishHeader(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer, size_t *pHeaderSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a659cf2bcaf2c5131daa0acc1917401a2',1,'MQTT_SerializePublishHeader(const MQTTPublishInfo_t *pPublishInfo, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer, size_t *pHeaderSize): core_mqtt_serializer.c']]], + ['mqtt_5fserializepublishheaderwithouttopic_38',['MQTT_SerializePublishHeaderWithoutTopic',['../core__mqtt__serializer_8h.html#a32de7fabeca85a4d360fa1dd06ff7cd0',1,'MQTT_SerializePublishHeaderWithoutTopic(const MQTTPublishInfo_t *pPublishInfo, size_t remainingLength, uint8_t *pBuffer, size_t *headerSize): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a32de7fabeca85a4d360fa1dd06ff7cd0',1,'MQTT_SerializePublishHeaderWithoutTopic(const MQTTPublishInfo_t *pPublishInfo, size_t remainingLength, uint8_t *pBuffer, size_t *headerSize): core_mqtt_serializer.c']]], + ['mqtt_5fserializesubscribe_39',['MQTT_SerializeSubscribe',['../core__mqtt__serializer_8h.html#a21273b13070e8340cc33b0f86bf79571',1,'MQTT_SerializeSubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#a21273b13070e8340cc33b0f86bf79571',1,'MQTT_SerializeSubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c']]], + ['mqtt_5fserializesubscribeheader_40',['MQTT_SerializeSubscribeHeader',['../core__mqtt__serializer_8c.html#a6fe31953d7b8dacb769adcf4c2719730',1,'core_mqtt_serializer.c']]], + ['mqtt_5fserializeunsubscribe_41',['MQTT_SerializeUnsubscribe',['../core__mqtt__serializer_8h.html#aab58219c203077c07ffd7061405e1adb',1,'MQTT_SerializeUnsubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c'],['../core__mqtt__serializer_8c.html#aab58219c203077c07ffd7061405e1adb',1,'MQTT_SerializeUnsubscribe(const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId, size_t remainingLength, const MQTTFixedBuffer_t *pFixedBuffer): core_mqtt_serializer.c']]], + ['mqtt_5fserializeunsubscribeheader_42',['MQTT_SerializeUnsubscribeHeader',['../core__mqtt__serializer_8c.html#a5b6f47fa319a444835ffed2d6af04709',1,'core_mqtt_serializer.c']]], + ['mqtt_5fstate_5fstrerror_43',['MQTT_State_strerror',['../core__mqtt__state_8c.html#a53d786203ca4d5d5630a9eb3dd4cddae',1,'core_mqtt_state.c']]], + ['mqtt_5fstatus_5fstrerror_44',['MQTT_Status_strerror',['../core__mqtt_8h.html#a05d9facfce89c5f9edef09ca13717f50',1,'MQTT_Status_strerror(MQTTStatus_t status): core_mqtt.c'],['../core__mqtt_8c.html#a05d9facfce89c5f9edef09ca13717f50',1,'MQTT_Status_strerror(MQTTStatus_t status): core_mqtt.c']]], + ['mqtt_5fsubscribe_45',['MQTT_Subscribe',['../core__mqtt_8h.html#a567aa9c38726a7879f9cbf943e813e8f',1,'MQTT_Subscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId): core_mqtt.c'],['../core__mqtt_8c.html#a567aa9c38726a7879f9cbf943e813e8f',1,'MQTT_Subscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId): core_mqtt.c']]], + ['mqtt_5funsubscribe_46',['MQTT_Unsubscribe',['../core__mqtt_8h.html#a77c911dbe24c5a51aaea88250895dba4',1,'MQTT_Unsubscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId): core_mqtt.c'],['../core__mqtt_8c.html#a77c911dbe24c5a51aaea88250895dba4',1,'MQTT_Unsubscribe(MQTTContext_t *pContext, const MQTTSubscribeInfo_t *pSubscriptionList, size_t subscriptionCount, uint16_t packetId): core_mqtt.c']]], + ['mqtt_5fupdatestateack_47',['MQTT_UpdateStateAck',['../core__mqtt__state_8c.html#a09a013b709085ffd51faa33c067cce1f',1,'core_mqtt_state.c']]], + ['mqtt_5fupdatestatepublish_48',['MQTT_UpdateStatePublish',['../core__mqtt__state_8c.html#ad657bd67745c66bc50f0441b4cc94763',1,'core_mqtt_state.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/functions_a.js b/v1.3.0/coreMQTT/search/functions_a.js new file mode 100644 index 00000000..7eff3baf --- /dev/null +++ b/v1.3.0/coreMQTT/search/functions_a.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['processpublishflags_0',['processPublishFlags',['../core__mqtt__serializer_8c.html#a47a044115ee5df1ac7fe02d2ee37e1e0',1,'core_mqtt_serializer.c']]], + ['processremaininglength_1',['processRemainingLength',['../core__mqtt__serializer_8c.html#a8a4f72e05cd72fa57ba5a90e204569b3',1,'core_mqtt_serializer.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/functions_b.js b/v1.3.0/coreMQTT/search/functions_b.js new file mode 100644 index 00000000..f9d3c0ed --- /dev/null +++ b/v1.3.0/coreMQTT/search/functions_b.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['readsubackstatus_0',['readSubackStatus',['../core__mqtt__serializer_8c.html#a02cace9415c300f4dd3394bf1eee0787',1,'core_mqtt_serializer.c']]], + ['receiveconnack_1',['receiveConnack',['../core__mqtt_8c.html#aa3c5d4f6154122cedcce9508ea7d1dce',1,'core_mqtt.c']]], + ['receivepacket_2',['receivePacket',['../core__mqtt_8c.html#aa674664c166b58a5b6630961d8760d3a',1,'core_mqtt.c']]], + ['receivesingleiteration_3',['receiveSingleIteration',['../core__mqtt_8c.html#a14d3be6806a945c14c0529daa1714e10',1,'core_mqtt.c']]], + ['recvexact_4',['recvExact',['../core__mqtt_8c.html#a509d9dd1ede2bc000035d8f9926a473c',1,'core_mqtt.c']]], + ['remaininglengthencodedsize_5',['remainingLengthEncodedSize',['../core__mqtt__serializer_8c.html#aeead0813fa045d754e3d6ec964d0686e',1,'core_mqtt_serializer.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/functions_c.js b/v1.3.0/coreMQTT/search/functions_c.js new file mode 100644 index 00000000..fb65351b --- /dev/null +++ b/v1.3.0/coreMQTT/search/functions_c.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['sendbuffer_0',['sendBuffer',['../core__mqtt_8c.html#a7f4f9871c75f8f987e3c86ae910bd982',1,'core_mqtt.c']]], + ['sendconnectwithoutcopy_1',['sendConnectWithoutCopy',['../core__mqtt_8c.html#a3c6935ecef4879b9aeee05ffb0f0a9cb',1,'core_mqtt.c']]], + ['sendmessagevector_2',['sendMessageVector',['../core__mqtt_8c.html#a39f478d2bb0366a5f14bfa90316d8d26',1,'core_mqtt.c']]], + ['sendpublishacks_3',['sendPublishAcks',['../core__mqtt_8c.html#ab4b719d2f726b049c279dcb37fcba840',1,'core_mqtt.c']]], + ['sendpublishwithoutcopy_4',['sendPublishWithoutCopy',['../core__mqtt_8c.html#aaaca64a926603116f5dfec4a65f28283',1,'core_mqtt.c']]], + ['sendsubscribewithoutcopy_5',['sendSubscribeWithoutCopy',['../core__mqtt_8c.html#a86259fe46a81f7981a7b43b677ab896d',1,'core_mqtt.c']]], + ['sendunsubscribewithoutcopy_6',['sendUnsubscribeWithoutCopy',['../core__mqtt_8c.html#a5fc0209190ce8ce635050195689306e2',1,'core_mqtt.c']]], + ['serializeconnectpacket_7',['serializeConnectPacket',['../core__mqtt__serializer_8c.html#a95bf697a3b1f86950e5c199d9cf3a185',1,'core_mqtt_serializer.c']]], + ['serializepublishcommon_8',['serializePublishCommon',['../core__mqtt__serializer_8c.html#a6b4138d990e2c8fbedbe28683c0fa83a',1,'core_mqtt_serializer.c']]], + ['stateselect_9',['stateSelect',['../core__mqtt__state_8c.html#adfc09b0c75d5de09cd73650f944699c0',1,'core_mqtt_state.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/functions_d.js b/v1.3.0/coreMQTT/search/functions_d.js new file mode 100644 index 00000000..139f219f --- /dev/null +++ b/v1.3.0/coreMQTT/search/functions_d.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['updaterecord_0',['updateRecord',['../core__mqtt__state_8c.html#a819c7c72087621fcf97a028bff02759e',1,'core_mqtt_state.c']]], + ['updatestateack_1',['updateStateAck',['../core__mqtt__state_8c.html#a174a91b9491a344d6fb4f0b39189392f',1,'core_mqtt_state.c']]], + ['updatestatepublish_2',['updateStatePublish',['../core__mqtt__state_8c.html#aa0550584e3733da2e31c9478b9307b49',1,'core_mqtt_state.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/functions_e.js b/v1.3.0/coreMQTT/search/functions_e.js new file mode 100644 index 00000000..460ee0c0 --- /dev/null +++ b/v1.3.0/coreMQTT/search/functions_e.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['validatepublishparams_0',['validatePublishParams',['../core__mqtt_8c.html#ad7eda8c9d4a5afa7b3f830dbd8cf4de4',1,'core_mqtt.c']]], + ['validatesubscribeunsubscribeparams_1',['validateSubscribeUnsubscribeParams',['../core__mqtt_8c.html#a37c146709806e0974638784edeb587f8',1,'core_mqtt.c']]], + ['validatesubscriptionserializeparams_2',['validateSubscriptionSerializeParams',['../core__mqtt__serializer_8c.html#a81262cb0b9d47dee979420f6fd8a7271',1,'core_mqtt_serializer.c']]], + ['validatetransitionack_3',['validateTransitionAck',['../core__mqtt__state_8c.html#ac85ca8874163b399b7f8e5e17d3c5872',1,'core_mqtt_state.c']]], + ['validatetransitionpublish_4',['validateTransitionPublish',['../core__mqtt__state_8c.html#aad1473b9a2d46be62c3e80dd3524af9d',1,'core_mqtt_state.c']]] +]; diff --git a/v1.3.0/coreMQTT/search/groups_0.js b/v1.3.0/coreMQTT/search/groups_0.js new file mode 100644 index 00000000..482cc48a --- /dev/null +++ b/v1.3.0/coreMQTT/search/groups_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['basic_20types_0',['Basic Types',['../group__mqtt__basic__types.html',1,'']]] +]; diff --git a/v1.3.0/coreMQTT/search/groups_1.js b/v1.3.0/coreMQTT/search/groups_1.js new file mode 100644 index 00000000..a0612bb6 --- /dev/null +++ b/v1.3.0/coreMQTT/search/groups_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['callback_20types_0',['Callback Types',['../group__mqtt__callback__types.html',1,'']]], + ['constants_1',['Constants',['../group__mqtt__constants.html',1,'']]] +]; diff --git a/v1.3.0/coreMQTT/search/groups_2.js b/v1.3.0/coreMQTT/search/groups_2.js new file mode 100644 index 00000000..6a1f1a06 --- /dev/null +++ b/v1.3.0/coreMQTT/search/groups_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['enumerated_20types_0',['Enumerated Types',['../group__mqtt__enum__types.html',1,'']]] +]; diff --git a/v1.3.0/coreMQTT/search/groups_3.js b/v1.3.0/coreMQTT/search/groups_3.js new file mode 100644 index 00000000..22c34526 --- /dev/null +++ b/v1.3.0/coreMQTT/search/groups_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['parameter_20structures_0',['Parameter Structures',['../group__mqtt__struct__types.html',1,'']]] +]; diff --git a/v1.3.0/coreMQTT/search/mag.svg b/v1.3.0/coreMQTT/search/mag.svg new file mode 100644 index 00000000..9f46b301 --- /dev/null +++ b/v1.3.0/coreMQTT/search/mag.svg @@ -0,0 +1,37 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/v1.3.0/coreMQTT/search/mag_d.svg b/v1.3.0/coreMQTT/search/mag_d.svg new file mode 100644 index 00000000..b9a814c7 --- /dev/null +++ b/v1.3.0/coreMQTT/search/mag_d.svg @@ -0,0 +1,37 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/v1.3.0/coreMQTT/search/mag_sel.svg b/v1.3.0/coreMQTT/search/mag_sel.svg new file mode 100644 index 00000000..03626f64 --- /dev/null +++ b/v1.3.0/coreMQTT/search/mag_sel.svg @@ -0,0 +1,74 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/v1.3.0/coreMQTT/search/mag_seld.svg b/v1.3.0/coreMQTT/search/mag_seld.svg new file mode 100644 index 00000000..6e720dcc --- /dev/null +++ b/v1.3.0/coreMQTT/search/mag_seld.svg @@ -0,0 +1,74 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/v1.3.0/coreMQTT/search/pages_0.js b/v1.3.0/coreMQTT/search/pages_0.js new file mode 100644 index 00000000..1d113db4 --- /dev/null +++ b/v1.3.0/coreMQTT/search/pages_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['configurations_0',['Configurations',['../core_mqtt_config.html',1,'']]] +]; diff --git a/v1.3.0/coreMQTT/search/pages_1.js b/v1.3.0/coreMQTT/search/pages_1.js new file mode 100644 index 00000000..5f3b990e --- /dev/null +++ b/v1.3.0/coreMQTT/search/pages_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['design_0',['Design',['../mqtt_design.html',1,'']]] +]; diff --git a/v1.3.0/coreMQTT/search/pages_2.js b/v1.3.0/coreMQTT/search/pages_2.js new file mode 100644 index 00000000..d505ab5d --- /dev/null +++ b/v1.3.0/coreMQTT/search/pages_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['functions_0',['Functions',['../mqtt_functions.html',1,'']]] +]; diff --git a/v1.3.0/coreMQTT/search/pages_3.js b/v1.3.0/coreMQTT/search/pages_3.js new file mode 100644 index 00000000..ccdc8a3d --- /dev/null +++ b/v1.3.0/coreMQTT/search/pages_3.js @@ -0,0 +1,33 @@ +var searchData= +[ + ['mqtt_5fconnect_0',['MQTT_Connect',['../mqtt_connect_function.html',1,'mqtt_functions']]], + ['mqtt_5fdeserializeack_1',['MQTT_DeserializeAck',['../mqtt_deserializeack_function.html',1,'mqtt_functions']]], + ['mqtt_5fdeserializepublish_2',['MQTT_DeserializePublish',['../mqtt_deserializepublish_function.html',1,'mqtt_functions']]], + ['mqtt_5fdisconnect_3',['MQTT_Disconnect',['../mqtt_disconnect_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetconnectpacketsize_4',['MQTT_GetConnectPacketSize',['../mqtt_getconnectpacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetdisconnectpacketsize_5',['MQTT_GetDisconnectPacketSize',['../mqtt_getdisconnectpacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetincomingpackettypeandlength_6',['MQTT_GetIncomingPacketTypeAndLength',['../mqtt_getincomingpackettypeandlength_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetpacketid_7',['MQTT_GetPacketId',['../mqtt_getpacketid_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetpingreqpacketsize_8',['MQTT_GetPingreqPacketSize',['../mqtt_getpingreqpacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetpublishpacketsize_9',['MQTT_GetPublishPacketSize',['../mqtt_getpublishpacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetsubackstatuscodes_10',['MQTT_GetSubAckStatusCodes',['../mqtt_getsubackstatuscodes_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetsubscribepacketsize_11',['MQTT_GetSubscribePacketSize',['../mqtt_getsubscribepacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5fgetunsubscribepacketsize_12',['MQTT_GetUnsubscribePacketSize',['../mqtt_getunsubscribepacketsize_function.html',1,'mqtt_functions']]], + ['mqtt_5finit_13',['MQTT_Init',['../mqtt_init_function.html',1,'mqtt_functions']]], + ['mqtt_5fping_14',['MQTT_Ping',['../mqtt_ping_function.html',1,'mqtt_functions']]], + ['mqtt_5fprocessloop_15',['MQTT_ProcessLoop',['../mqtt_processloop_function.html',1,'mqtt_functions']]], + ['mqtt_5fpublish_16',['MQTT_Publish',['../mqtt_publish_function.html',1,'mqtt_functions']]], + ['mqtt_5fpublishtoresend_17',['MQTT_PublishToResend',['../mqtt_publishtoresend_function.html',1,'mqtt_functions']]], + ['mqtt_5freceiveloop_18',['MQTT_ReceiveLoop',['../mqtt_receiveloop_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializeack_19',['MQTT_SerializeAck',['../mqtt_serializeack_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializeconnect_20',['MQTT_SerializeConnect',['../mqtt_serializeconnect_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializedisconnect_21',['MQTT_SerializeDisconnect',['../mqtt_serializedisconnect_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializepingreq_22',['MQTT_SerializePingreq',['../mqtt_serializepingreq_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializepublish_23',['MQTT_SerializePublish',['../mqtt_serializepublish_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializepublishheader_24',['MQTT_SerializePublishHeader',['../mqtt_serializepublishheader_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializesubscribe_25',['MQTT_SerializeSubscribe',['../mqtt_serializesubscribe_function.html',1,'mqtt_functions']]], + ['mqtt_5fserializeunsubscribe_26',['MQTT_SerializeUnsubscribe',['../mqtt_serializeunsubscribe_function.html',1,'mqtt_functions']]], + ['mqtt_5fstatus_5fstrerror_27',['MQTT_Status_strerror',['../mqtt_status_strerror_function.html',1,'mqtt_functions']]], + ['mqtt_5fsubscribe_28',['MQTT_Subscribe',['../mqtt_subscribe_function.html',1,'mqtt_functions']]], + ['mqtt_5funsubscribe_29',['MQTT_Unsubscribe',['../mqtt_unsubscribe_function.html',1,'mqtt_functions']]] +]; diff --git a/v1.3.0/coreMQTT/search/pages_4.js b/v1.3.0/coreMQTT/search/pages_4.js new file mode 100644 index 00000000..0398f4f4 --- /dev/null +++ b/v1.3.0/coreMQTT/search/pages_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['overview_0',['Overview',['../index.html',1,'']]] +]; diff --git a/v1.3.0/coreMQTT/search/pages_5.js b/v1.3.0/coreMQTT/search/pages_5.js new file mode 100644 index 00000000..892aa998 --- /dev/null +++ b/v1.3.0/coreMQTT/search/pages_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['porting_20guide_0',['Porting Guide',['../mqtt_porting.html',1,'']]] +]; diff --git a/v1.3.0/coreMQTT/search/pages_6.js b/v1.3.0/coreMQTT/search/pages_6.js new file mode 100644 index 00000000..41a56c5a --- /dev/null +++ b/v1.3.0/coreMQTT/search/pages_6.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['timeouts_20in_20coremqtt_20library_0',['Timeouts in coreMQTT library',['../mqtt_timeouts.html',1,'']]], + ['transport_20interface_1',['Transport Interface',['../mqtt_transport_interface.html',1,'']]] +]; diff --git a/v1.3.0/coreMQTT/search/search.css b/v1.3.0/coreMQTT/search/search.css new file mode 100644 index 00000000..a53214fc --- /dev/null +++ b/v1.3.0/coreMQTT/search/search.css @@ -0,0 +1,286 @@ +/*---------------- Search Box */ + +#MSearchBox { + position: absolute; + right: 5px; +} +/*---------------- Search box styling */ + +.SRPage * { + font-weight: normal; + line-height: normal; +} + +dark-mode-toggle { + margin-left: 5px; + display: flex; + float: right; +} + +#MSearchBox { + display: inline-block; + white-space : nowrap; + background: var(--search-background-color); + border-radius: 0.65em; + box-shadow: var(--search-box-shadow); + z-index: 102; +} + +#MSearchBox .left { + display: inline-block; + vertical-align: middle; + height: 1.4em; +} + +#MSearchSelect { + display: inline-block; + vertical-align: middle; + width: 20px; + height: 19px; + background-image: var(--search-magnification-select-image); + margin: 0 0 0 0.3em; + padding: 0; +} + +#MSearchSelectExt { + display: inline-block; + vertical-align: middle; + width: 10px; + height: 19px; + background-image: var(--search-magnification-image); + margin: 0 0 0 0.5em; + padding: 0; +} + + +#MSearchField { + display: inline-block; + vertical-align: middle; + width: 7.5em; + height: 19px; + margin: 0 0.15em; + padding: 0; + line-height: 1em; + border:none; + color: var(--search-foreground-color); + outline: none; + font-family: var(--font-family-search); + -webkit-border-radius: 0px; + border-radius: 0px; + background: none; +} + +@media(hover: none) { + /* to avoid zooming on iOS */ + #MSearchField { + font-size: 16px; + } +} + +#MSearchBox .right { + display: inline-block; + vertical-align: middle; + width: 1.4em; + height: 1.4em; +} + +#MSearchClose { + display: none; + font-size: inherit; + background : none; + border: none; + margin: 0; + padding: 0; + outline: none; + +} + +#MSearchCloseImg { + padding: 0.3em; + margin: 0; +} + +.MSearchBoxActive #MSearchField { + color: var(--search-active-color); +} + + + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid var(--search-filter-border-color); + background-color: var(--search-filter-background-color); + z-index: 10001; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt var(--font-family-search); + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: var(--font-family-monospace); + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: var(--search-filter-foreground-color); + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: var(--search-filter-foreground-color); + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: var(--search-filter-highlight-text-color); + background-color: var(--search-filter-highlight-bg-color); + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + /*width: 60ex;*/ + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid var(--search-results-border-color); + background-color: var(--search-results-background-color); + z-index:10000; + width: 300px; + height: 400px; + overflow: auto; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +div.SRPage { + margin: 5px 2px; + background-color: var(--search-results-background-color); +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: var(--search-results-foreground-color); + font-family: var(--font-family-search); + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: var(--search-results-foreground-color); + font-family: var(--font-family-search); + font-size: 8pt; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; + font-family: var(--font-family-search); +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; + font-family: var(--font-family-search); +} + +.SRResult { + display: none; +} + +div.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: var(--nav-gradient-active-image-parent); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/v1.3.0/coreMQTT/search/search.js b/v1.3.0/coreMQTT/search/search.js new file mode 100644 index 00000000..e103a262 --- /dev/null +++ b/v1.3.0/coreMQTT/search/search.js @@ -0,0 +1,816 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var idxChar = searchValue.substr(0, 1).toLowerCase(); + if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair + { + idxChar = searchValue.substr(0, 2); + } + + var jsFile; + + var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); + if (idx!=-1) + { + var hexCode=idx.toString(16); + jsFile = this.resultsPath + indexSectionNames[this.searchIndex] + '_' + hexCode + '.js'; + } + + var loadJS = function(url, impl, loc){ + var scriptTag = document.createElement('script'); + scriptTag.src = url; + scriptTag.onload = impl; + scriptTag.onreadystatechange = impl; + loc.appendChild(scriptTag); + } + + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + var domSearchBox = this.DOMSearchBox(); + var domPopupSearchResults = this.DOMPopupSearchResults(); + var domSearchClose = this.DOMSearchClose(); + var resultsPath = this.resultsPath; + + var handleResults = function() { + document.getElementById("Loading").style.display="none"; + if (typeof searchData !== 'undefined') { + createResults(resultsPath); + document.getElementById("NoMatches").style.display="none"; + } + + searchResults.Search(searchValue); + + if (domPopupSearchResultsWindow.style.display!='block') + { + domSearchClose.style.display = 'inline-block'; + var left = getXPos(domSearchBox) + 150; + var top = getYPos(domSearchBox) + 20; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + var maxWidth = document.body.clientWidth; + var maxHeight = document.body.clientHeight; + var width = 300; + if (left<10) left=10; + if (width+left+8>maxWidth) width=maxWidth-left-8; + var height = 400; + if (height+top+8>maxHeight) height=maxHeight-top-8; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResultsWindow.style.height = height + 'px'; + } + } + + if (jsFile) { + loadJS(jsFile, handleResults, this.DOMPopupSearchResultsWindow()); + } else { + handleResults(); + } + + this.lastSearchValue = searchValue; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + this.searchActive = true; + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + this.DOMSearchField().value = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName.toLowerCase() == 'div' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName.toLowerCase() == 'div' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + searchBox.CloseResultsWindow(); + document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + searchBox.CloseResultsWindow(); + document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults(resultsPath) +{ + var results = document.getElementById("SRResults"); + results.innerHTML = ''; + for (var e=0; e-{AmhX=Jf(#6djGiuzAr*{o?=JLmPLyc> z_*`QK&+BH@jWrYJ7>r6%keRM@)Qyv8R=enp0jiI>aWlGyB58O zFVR20d+y`K7vDw(hJF3;>dD*3-?v=<8M)@x|EEGLnJsniYK!2U1 Y!`|5biEc?d1`HDhPgg&ebxsLQ02F6;9RL6T literal 0 HcmV?d00001 diff --git a/v1.3.0/coreMQTT/splitbard.png b/v1.3.0/coreMQTT/splitbard.png new file mode 100644 index 0000000000000000000000000000000000000000..8367416d757fd7b6dc4272b6432dc75a75abd068 GIT binary patch literal 282 zcmeAS@N?(olHy`uVBq!ia0vp^Yzz!63>-{AmhX=Jf@VhhFKy35^fiT zT~&lUj3=cDh^%3HDY9k5CEku}PHXNoNC(_$U3XPb&Q*ME25pT;2(*BOgAf<+R$lzakPG`kF31()Fx{L5Wrac|GQzjeE= zueY1`Ze{#x<8=S|`~MgGetGce)#vN&|J{Cd^tS%;tBYTo?+^d68<#n_Y_xx`J||4O V@QB{^CqU0Kc)I$ztaD0e0svEzbJzd? literal 0 HcmV?d00001 diff --git a/v1.3.0/coreMQTT/struct_m_q_t_t_connect_info__t.html b/v1.3.0/coreMQTT/struct_m_q_t_t_connect_info__t.html new file mode 100644 index 00000000..ab6c35c5 --- /dev/null +++ b/v1.3.0/coreMQTT/struct_m_q_t_t_connect_info__t.html @@ -0,0 +1,161 @@ + + + + + + + +coreMQTT: MQTTConnectInfo_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTConnectInfo_t Struct Reference
+
+
+ +

MQTT CONNECT packet parameters. + More...

+ +

#include <core_mqtt_serializer.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Fields

+bool cleanSession
 Whether to establish a new, clean session or resume a previous session.
 
+uint16_t keepAliveSeconds
 MQTT keep alive period.
 
+const char * pClientIdentifier
 MQTT client identifier. Must be unique per client.
 
+uint16_t clientIdentifierLength
 Length of the client identifier.
 
+const char * pUserName
 MQTT user name. Set to NULL if not used.
 
+uint16_t userNameLength
 Length of MQTT user name. Set to 0 if not used.
 
+const char * pPassword
 MQTT password. Set to NULL if not used.
 
+uint16_t passwordLength
 Length of MQTT password. Set to 0 if not used.
 
+

Detailed Description

+

MQTT CONNECT packet parameters.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/v1.3.0/coreMQTT/struct_m_q_t_t_context__t.html b/v1.3.0/coreMQTT/struct_m_q_t_t_context__t.html new file mode 100644 index 00000000..08f580f7 --- /dev/null +++ b/v1.3.0/coreMQTT/struct_m_q_t_t_context__t.html @@ -0,0 +1,197 @@ + + + + + + + +coreMQTT: MQTTContext_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTContext_t Struct Reference
+
+
+ +

A struct representing an MQTT connection. + More...

+ +

#include <core_mqtt.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Fields

+MQTTPubAckInfo_toutgoingPublishRecords
 State engine records for outgoing publishes.
 
+MQTTPubAckInfo_tincomingPublishRecords
 State engine records for incoming publishes.
 
+size_t outgoingPublishRecordMaxCount
 The maximum number of outgoing publish records.
 
+size_t incomingPublishRecordMaxCount
 The maximum number of incoming publish records.
 
+TransportInterface_t transportInterface
 The transport interface used by the MQTT connection.
 
+MQTTFixedBuffer_t networkBuffer
 The buffer used in sending and receiving packets from the network.
 
+uint16_t nextPacketId
 The next available ID for outgoing MQTT packets.
 
+MQTTConnectionStatus_t connectStatus
 Whether the context currently has a connection to the broker.
 
+MQTTGetCurrentTimeFunc_t getTime
 Function used to get millisecond timestamps.
 
+MQTTEventCallback_t appCallback
 Callback function used to give deserialized MQTT packets to the application.
 
+uint32_t lastPacketTxTime
 Timestamp of the last packet sent by the library.
 
+uint32_t lastPacketRxTime
 Timestamp of the last packet received by the library.
 
+bool controlPacketSent
 Whether the library sent a packet during a call of MQTT_ProcessLoop or MQTT_ReceiveLoop.
 
+size_t index
 Index to keep track of the number of bytes received in network buffer.
 
+uint16_t keepAliveIntervalSec
 Keep Alive interval.
 
+uint32_t pingReqSendTimeMs
 Timestamp of the last sent PINGREQ.
 
+bool waitingForPingResp
 If the library is currently awaiting a PINGRESP.
 
+

Detailed Description

+

A struct representing an MQTT connection.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/v1.3.0/coreMQTT/struct_m_q_t_t_deserialized_info__t.html b/v1.3.0/coreMQTT/struct_m_q_t_t_deserialized_info__t.html new file mode 100644 index 00000000..9061ce9d --- /dev/null +++ b/v1.3.0/coreMQTT/struct_m_q_t_t_deserialized_info__t.html @@ -0,0 +1,141 @@ + + + + + + + +coreMQTT: MQTTDeserializedInfo_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTDeserializedInfo_t Struct Reference
+
+
+ +

Struct to hold deserialized packet information for an MQTTEventCallback_t callback. + More...

+ +

#include <core_mqtt.h>

+ + + + + + + + + + + +

+Data Fields

+uint16_t packetIdentifier
 Packet ID of deserialized packet.
 
+MQTTPublishInfo_tpPublishInfo
 Pointer to deserialized publish info.
 
+MQTTStatus_t deserializationResult
 Return code of deserialization.
 
+

Detailed Description

+

Struct to hold deserialized packet information for an MQTTEventCallback_t callback.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/v1.3.0/coreMQTT/struct_m_q_t_t_fixed_buffer__t.html b/v1.3.0/coreMQTT/struct_m_q_t_t_fixed_buffer__t.html new file mode 100644 index 00000000..50b8a332 --- /dev/null +++ b/v1.3.0/coreMQTT/struct_m_q_t_t_fixed_buffer__t.html @@ -0,0 +1,138 @@ + + + + + + + +coreMQTT: MQTTFixedBuffer_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTFixedBuffer_t Struct Reference
+
+
+ +

Buffer passed to MQTT library. + More...

+ +

#include <core_mqtt_serializer.h>

+ + + + + + + + +

+Data Fields

+uint8_t * pBuffer
 Pointer to buffer.
 
+size_t size
 Size of buffer.
 
+

Detailed Description

+

Buffer passed to MQTT library.

+

These buffers are not copied and must remain in scope for the duration of the MQTT operation.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/v1.3.0/coreMQTT/struct_m_q_t_t_packet_info__t.html b/v1.3.0/coreMQTT/struct_m_q_t_t_packet_info__t.html new file mode 100644 index 00000000..3800e125 --- /dev/null +++ b/v1.3.0/coreMQTT/struct_m_q_t_t_packet_info__t.html @@ -0,0 +1,145 @@ + + + + + + + +coreMQTT: MQTTPacketInfo_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTPacketInfo_t Struct Reference
+
+
+ +

MQTT incoming packet parameters. + More...

+ +

#include <core_mqtt_serializer.h>

+ + + + + + + + + + + + + + +

+Data Fields

+uint8_t type
 Type of incoming MQTT packet.
 
+uint8_t * pRemainingData
 Remaining serialized data in the MQTT packet.
 
+size_t remainingLength
 Length of remaining serialized data.
 
+size_t headerLength
 The length of the MQTT header including the type and length.
 
+

Detailed Description

+

MQTT incoming packet parameters.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/v1.3.0/coreMQTT/struct_m_q_t_t_pub_ack_info__t.html b/v1.3.0/coreMQTT/struct_m_q_t_t_pub_ack_info__t.html new file mode 100644 index 00000000..45ee07ce --- /dev/null +++ b/v1.3.0/coreMQTT/struct_m_q_t_t_pub_ack_info__t.html @@ -0,0 +1,141 @@ + + + + + + + +coreMQTT: MQTTPubAckInfo_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTPubAckInfo_t Struct Reference
+
+
+ +

An element of the state engine records for QoS 1 or Qos 2 publishes. + More...

+ +

#include <core_mqtt.h>

+ + + + + + + + + + + +

+Data Fields

+uint16_t packetId
 The packet ID of the original PUBLISH.
 
+MQTTQoS_t qos
 The QoS of the original PUBLISH.
 
+MQTTPublishState_t publishState
 The current state of the publish process.
 
+

Detailed Description

+

An element of the state engine records for QoS 1 or Qos 2 publishes.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/v1.3.0/coreMQTT/struct_m_q_t_t_publish_info__t.html b/v1.3.0/coreMQTT/struct_m_q_t_t_publish_info__t.html new file mode 100644 index 00000000..ec91a576 --- /dev/null +++ b/v1.3.0/coreMQTT/struct_m_q_t_t_publish_info__t.html @@ -0,0 +1,157 @@ + + + + + + + +coreMQTT: MQTTPublishInfo_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTPublishInfo_t Struct Reference
+
+
+ +

MQTT PUBLISH packet parameters. + More...

+ +

#include <core_mqtt_serializer.h>

+ + + + + + + + + + + + + + + + + + + + + + + +

+Data Fields

+MQTTQoS_t qos
 Quality of Service for message.
 
+bool retain
 Whether this is a retained message.
 
+bool dup
 Whether this is a duplicate publish message.
 
+const char * pTopicName
 Topic name on which the message is published.
 
+uint16_t topicNameLength
 Length of topic name.
 
+const void * pPayload
 Message payload.
 
+size_t payloadLength
 Message payload length.
 
+

Detailed Description

+

MQTT PUBLISH packet parameters.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/v1.3.0/coreMQTT/struct_m_q_t_t_subscribe_info__t.html b/v1.3.0/coreMQTT/struct_m_q_t_t_subscribe_info__t.html new file mode 100644 index 00000000..19ac7421 --- /dev/null +++ b/v1.3.0/coreMQTT/struct_m_q_t_t_subscribe_info__t.html @@ -0,0 +1,141 @@ + + + + + + + +coreMQTT: MQTTSubscribeInfo_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTSubscribeInfo_t Struct Reference
+
+
+ +

MQTT SUBSCRIBE packet parameters. + More...

+ +

#include <core_mqtt_serializer.h>

+ + + + + + + + + + + +

+Data Fields

+MQTTQoS_t qos
 Quality of Service for subscription.
 
+const char * pTopicFilter
 Topic filter to subscribe to.
 
+uint16_t topicFilterLength
 Length of subscription topic filter.
 
+

Detailed Description

+

MQTT SUBSCRIBE packet parameters.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/v1.3.0/coreMQTT/struct_transport_interface__t.html b/v1.3.0/coreMQTT/struct_transport_interface__t.html new file mode 100644 index 00000000..f2a64a74 --- /dev/null +++ b/v1.3.0/coreMQTT/struct_transport_interface__t.html @@ -0,0 +1,198 @@ + + + + + + + +coreMQTT: TransportInterface_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
TransportInterface_t Struct Reference
+
+
+ +

The transport layer interface. + More...

+ +

#include <transport_interface.h>

+ + + + + + + + + + +

+Data Fields

TransportRecv_t recv
 
TransportSend_t send
 
TransportWritev_t writev
 
NetworkContext_tpNetworkContext
 
+

Detailed Description

+

The transport layer interface.

+

Field Documentation

+ +

◆ recv

+ +
+
+ + + + +
TransportRecv_t TransportInterface_t::recv
+
+

Transport receive function pointer.

+ +
+
+ +

◆ send

+ +
+
+ + + + +
TransportSend_t TransportInterface_t::send
+
+

Transport send function pointer.

+ +
+
+ +

◆ writev

+ +
+
+ + + + +
TransportWritev_t TransportInterface_t::writev
+
+

Transport writev function pointer.

+ +
+
+ +

◆ pNetworkContext

+ +
+
+ + + + +
NetworkContext_t* TransportInterface_t::pNetworkContext
+
+

Implementation-defined network context.

+ +
+
+
The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/v1.3.0/coreMQTT/struct_transport_out_vector__t.html b/v1.3.0/coreMQTT/struct_transport_out_vector__t.html new file mode 100644 index 00000000..0df3cb13 --- /dev/null +++ b/v1.3.0/coreMQTT/struct_transport_out_vector__t.html @@ -0,0 +1,137 @@ + + + + + + + +coreMQTT: TransportOutVector_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
TransportOutVector_t Struct Reference
+
+
+ +

Transport vector structure for sending multiple messages. + More...

+ +

#include <transport_interface.h>

+ + + + + + + + +

+Data Fields

+const void * iov_base
 Base address of data.
 
+size_t iov_len
 Length of data in buffer.
 
+

Detailed Description

+

Transport vector structure for sending multiple messages.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/v1.3.0/coreMQTT/style.css b/v1.3.0/coreMQTT/style.css new file mode 100644 index 00000000..99d7ab71 --- /dev/null +++ b/v1.3.0/coreMQTT/style.css @@ -0,0 +1,132 @@ +/* + * Stylesheet for Doxygen HTML output. + * + * This file defines styles for custom elements in the header/footer and + * overrides some of the default Doxygen styles. + * + * Styles in this file do not affect the treeview sidebar. + */ + +/* Set the margins to place a small amount of whitespace on the left and right + * side of the page. */ +div.contents { + margin-left:4em; + margin-right:4em; +} + +/* Justify text in paragraphs. */ +p { + text-align: justify; +} + +/* Style of section headings. */ +h1 { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 160%; + font-weight: normal; + padding-bottom: 4px; + padding-top: 8px; +} + +/* Style of subsection headings. */ +h2:not(.memtitle):not(.groupheader) { + font-size: 125%; + margin-bottom: 0px; + margin-top: 16px; + padding: 0px; +} + +/* Style of paragraphs immediately after subsection headings. */ +h2 + p { + margin: 0px; + padding: 0px; +} + +/* Style of subsection headings. */ +h3 { + font-size: 100%; + margin-bottom: 0px; + margin-left: 2em; + margin-right: 2em; +} + +/* Style of paragraphs immediately after subsubsection headings. */ +h3 + p { + margin-top: 0px; + margin-left: 2em; + margin-right: 2em; +} + +/* Style of the prefix "AWS IoT Device SDK C" that appears in the header. */ +#csdkprefix { + color: #757575; +} + +/* Style of the "Return to main page" link that appears in the header. */ +#returntomain { + padding: 0.5em; +} + +/* Style of the dividers on Configuration Settings pages. */ +div.configpagedivider { + margin-left: 0px !important; + margin-right: 0px !important; + margin-top: 20px !important; +} + +/* Style of configuration setting names. */ +dl.section.user ~ h1 { + border-bottom: none; + color: #000000; + font-family: monospace, fixed; + font-size: 16px; + margin-bottom: 0px; + margin-left: 2em; + margin-top: 1.5em; +} + +/* Style of paragraphs on a configuration settings page. */ +dl.section.user ~ * { + margin-bottom: 10px; + margin-left: 4em; + margin-right: 4em; + margin-top: 0px; +} + +/* Hide the configuration setting marker. */ +dl.section.user { + display: none; +} + +/* Overrides for code fragments and lines. */ +div.fragment { + background: #ffffff; + border: none; + padding: 5px; +} + +div.line { + color: #3a3a3a; +} + +/* Overrides for code syntax highlighting colors. */ +span.comment { + color: #008000; +} + +span.keyword, span.keywordtype, span.keywordflow { + color: #0000ff; +} + +span.preprocessor { + color: #50015a; +} + +span.stringliteral, span.charliteral { + color: #800c0c; +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #496194; +} diff --git a/v1.3.0/coreMQTT/sync_off.png b/v1.3.0/coreMQTT/sync_off.png new file mode 100644 index 0000000000000000000000000000000000000000..3b443fc62892114406e3d399421b2a881b897acc GIT binary patch literal 853 zcmV-b1FHOqP)oT|#XixUYy%lpuf3i8{fX!o zUyDD0jOrAiT^tq>fLSOOABs-#u{dV^F$b{L9&!2=9&RmV;;8s^x&UqB$PCj4FdKbh zoB1WTskPUPu05XzFbA}=KZ-GP1fPpAfSs>6AHb12UlR%-i&uOlTpFNS7{jm@mkU1V zh`nrXr~+^lsV-s1dkZOaI|kYyVj3WBpPCY{n~yd%u%e+d=f%`N0FItMPtdgBb@py; zq@v6NVArhyTC7)ULw-Jy8y42S1~4n(3LkrW8mW(F-4oXUP3E`e#g**YyqI7h-J2zK zK{m9##m4ri!7N>CqQqCcnI3hqo1I;Yh&QLNY4T`*ptiQGozK>FF$!$+84Z`xwmeMh zJ0WT+OH$WYFALEaGj2_l+#DC3t7_S`vHpSivNeFbP6+r50cO8iu)`7i%Z4BTPh@_m3Tk!nAm^)5Bqnr%Ov|Baunj#&RPtRuK& z4RGz|D5HNrW83-#ydk}tVKJrNmyYt-sTxLGlJY5nc&Re zU4SgHNPx8~Yxwr$bsju?4q&%T1874xxzq+_%?h8_ofw~(bld=o3iC)LUNR*BY%c0y zWd_jX{Y8`l%z+ol1$@Qa?Cy!(0CVIEeYpKZ`(9{z>3$CIe;pJDQk$m3p}$>xBm4lb zKo{4S)`wdU9Ba9jJbVJ0C=SOefZe%d$8=2r={nu<_^a3~>c#t_U6dye5)JrR(_a^E f@}b6j1K9lwFJq@>o)+Ry00000NkvXXu0mjfWa5j* literal 0 HcmV?d00001 diff --git a/v1.3.0/coreMQTT/sync_on.png b/v1.3.0/coreMQTT/sync_on.png new file mode 100644 index 0000000000000000000000000000000000000000..e08320fb64e6fa33b573005ed6d8fe294e19db76 GIT binary patch literal 845 zcmV-T1G4;yP)Y;xxyHF2B5Wzm| zOOGupOTn@c(JmBOl)e;XMNnZuiTJP>rM8<|Q`7I_))aP?*T)ow&n59{}X4$3Goat zgjs?*aasfbrokzG5cT4K=uG`E14xZl@z)F={P0Y^?$4t z>v!teRnNZym<6h{7sLyF1V0HsfEl+l6TrZpsfr1}luH~F7L}ktXu|*uVX^RG$L0`K zWs3j|0tIvVe(N%_?2{(iCPFGf#B6Hjy6o&}D$A%W%jfO8_W%ZO#-mh}EM$LMn7joJ z05dHr!5Y92g+31l<%i1(=L1a1pXX+OYnalY>31V4K}BjyRe3)9n#;-cCVRD_IG1fT zOKGeNY8q;TL@K{dj@D^scf&VCs*-Jb>8b>|`b*osv52-!A?BpbYtTQBns5EAU**$m zSnVSm(teh>tQi*S*A>#ySc=n;`BHz`DuG4&g4Kf8lLhca+zvZ7t7RflD6-i-mcK=M z!=^P$*u2)bkY5asG4gsss!Hn%u~>}kIW`vMs%lJLH+u*9<4PaV_c6U`KqWXQH%+Nu zTv41O(^ZVi@qhjQdG!fbZw&y+2o!iYymO^?ud3{P*HdoX83YV*Uu_HB=?U&W9%AU# z80}k1SS-CXTU7dcQlsm<^oYLxVSseqY6NO}dc`Nj?8vrhNuCdm@^{a3AQ_>6myOj+ z`1RsLUXF|dm|3k7s2jD(B{rzE>WI2scH8i1;=O5Cc9xB3^aJk%fQjqsu+kH#0=_5a z0nCE8@dbQa-|YIuUVvG0L_IwHMEhOj$Mj4Uq05 X8=0q~qBNan00000NkvXXu0mjfptF>5 literal 0 HcmV?d00001 diff --git a/v1.3.0/coreMQTT/tab_a.png b/v1.3.0/coreMQTT/tab_a.png new file mode 100644 index 0000000000000000000000000000000000000000..3b725c41c5a527a3a3e40097077d0e206a681247 GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QlXwMjv*C{Z|8b*H5dputLHD# z=<0|*y7z(Vor?d;H&?EG&cXR}?!j-Lm&u1OOI7AIF5&c)RFE;&p0MYK>*Kl@eiymD r@|NpwKX@^z+;{u_Z~trSBfrMKa%3`zocFjEXaR$#tDnm{r-UW|TZ1%4 literal 0 HcmV?d00001 diff --git a/v1.3.0/coreMQTT/tab_ad.png b/v1.3.0/coreMQTT/tab_ad.png new file mode 100644 index 0000000000000000000000000000000000000000..e34850acfc24be58da6d2fd1ccc6b29cc84fe34d GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QhuH;jv*C{Z|5d*H3V=pKi{In zd2jxLclDRPylmD}^l7{QOtL{vUjO{-WqItb5sQp2h-99b8^^Scr-=2mblCdZuUm?4 jzOJvgvt3{(cjKLW5(A@0qPS@<&}0TrS3j3^P6y&q2{!U5bk+Tso_B!YCpDh>v z{CM*1U8YvQRyBUHt^Ju0W_sq-?;9@_4equ-bavTs=gk796zopr0EBT&m;e9( literal 0 HcmV?d00001 diff --git a/v1.3.0/coreMQTT/tab_s.png b/v1.3.0/coreMQTT/tab_s.png new file mode 100644 index 0000000000000000000000000000000000000000..ab478c95b67371d700a20869f7de1ddd73522d50 GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QuUrLjv*C{Z|^p8HaRdjTwH7) zC?wLlL}}I{)n%R&r+1}IGmDnq;&J#%V6)9VsYhS`O^BVBQlxOUep0c$RENLq#g8A$ z)z7%K_bI&n@J+X_=x}fJoEKed-$<>=ZI-;YrdjIl`U`uzuDWSP?o#Dmo{%SgM#oan kX~E1%D-|#H#QbHoIja2U-MgvsK&LQxy85}Sb4q9e0Efg%P5=M^ literal 0 HcmV?d00001 diff --git a/v1.3.0/coreMQTT/tab_sd.png b/v1.3.0/coreMQTT/tab_sd.png new file mode 100644 index 0000000000000000000000000000000000000000..757a565ced4730f85c833fb2547d8e199ae68f19 GIT binary patch literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!Qq7(&jv*C{Z|_!fH5o7*c=%9% zcILh!EA=pAQKdx-Cdiev=v{eg{8Ht<{e8_NAN~b=)%W>-WDCE0PyDHGemi$BoXwcK z{>e9^za6*c1ilttWw&V+U;WCPlV9{LdC~Ey%_H(qj`xgfES(4Yz5jSTZfCt`4E$0YRsR*S^mTCR^;V&sxC8{l_Cp7w8-YPgg&ebxsLQ00$vXK>z>% literal 0 HcmV?d00001 diff --git a/v1.3.0/coreMQTT/tabs.css b/v1.3.0/coreMQTT/tabs.css new file mode 100644 index 00000000..71c8a470 --- /dev/null +++ b/v1.3.0/coreMQTT/tabs.css @@ -0,0 +1 @@ +.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.main-menu-btn{position:relative;display:inline-block;width:36px;height:36px;text-indent:36px;margin-left:8px;white-space:nowrap;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0)}.main-menu-btn-icon,.main-menu-btn-icon:before,.main-menu-btn-icon:after{position:absolute;top:50%;left:2px;height:2px;width:24px;background:var(--nav-menu-button-color);-webkit-transition:all .25s;transition:all .25s}.main-menu-btn-icon:before{content:'';top:-7px;left:0}.main-menu-btn-icon:after{content:'';top:7px;left:0}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon{height:0}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon:before{top:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon:after{top:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}#main-menu-state{position:absolute;width:1px;height:1px;margin:-1px;border:0;padding:0;overflow:hidden;clip:rect(1px,1px,1px,1px)}#main-menu-state:not(:checked) ~ #main-menu{display:none}#main-menu-state:checked ~ #main-menu{display:block}@media(min-width:768px){.main-menu-btn{position:absolute;top:-99999px}#main-menu-state:not(:checked) ~ #main-menu{display:block}}.sm-dox{background-image:var(--nav-gradient-image)}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0 12px;padding-right:43px;font-family:var(--font-family-nav);font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:var(--nav-text-normal-shadow);color:var(--nav-text-normal-color);outline:0}.sm-dox a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox a.current{color:#d23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace !important;text-align:center;text-shadow:none;background:var(--nav-menu-toggle-color);-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox a span.sub-arrow:before{display:block;content:'+'}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px;border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0;border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox ul{background:var(--nav-menu-background-color)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:var(--nav-menu-background-color);background-image:none}.sm-dox ul a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:0 1px 1px black}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media(min-width:768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:var(--nav-gradient-image);line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:var(--nav-text-normal-color) transparent transparent transparent;background:transparent;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0 12px;background-image:var(--nav-separator-image);background-repeat:no-repeat;background-position:right;-moz-border-radius:0 !important;-webkit-border-radius:0;border-radius:0 !important}.sm-dox a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox a:hover span.sub-arrow{border-color:var(--nav-text-hover-color) transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent var(--nav-menu-background-color) transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:var(--nav-menu-background-color);-moz-border-radius:5px !important;-webkit-border-radius:5px;border-radius:5px !important;-moz-box-shadow:0 5px 9px rgba(0,0,0,0.2);-webkit-box-shadow:0 5px 9px rgba(0,0,0,0.2);box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent var(--nav-menu-foreground-color);border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:var(--nav-menu-foreground-color);background-image:none;border:0 !important;color:var(--nav-menu-foreground-color);background-image:none}.sm-dox ul a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent var(--nav-text-hover-color)}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:var(--nav-menu-background-color);height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #d23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#d23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent var(--nav-menu-foreground-color) transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:var(--nav-menu-foreground-color) transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px !important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:var(--nav-gradient-image)}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:var(--nav-menu-background-color)}} \ No newline at end of file diff --git a/v1.3.0/coreMQTT/transport__interface_8h.html b/v1.3.0/coreMQTT/transport__interface_8h.html new file mode 100644 index 00000000..6ccb890f --- /dev/null +++ b/v1.3.0/coreMQTT/transport__interface_8h.html @@ -0,0 +1,151 @@ + + + + + + + +coreMQTT: transport_interface.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
transport_interface.h File Reference
+
+
+ +

Transport interface definitions to send and receive data over the network. +More...

+
#include <stdint.h>
+#include <stddef.h>
+
+

Go to the source code of this file.

+ + + + + + + + +

+Data Structures

struct  TransportOutVector_t
 Transport vector structure for sending multiple messages. More...
 
struct  TransportInterface_t
 The transport layer interface. More...
 
+ + + + + + + + + + + + + +

+Typedefs

+typedef struct NetworkContext NetworkContext_t
 The NetworkContext is an incomplete type. An implementation of this interface must define struct NetworkContext for the system requirements. This context is passed into the network interface functions.
 
typedef int32_t(* TransportRecv_t) (NetworkContext_t *pNetworkContext, void *pBuffer, size_t bytesToRecv)
 Transport interface for receiving data on the network.
 
typedef int32_t(* TransportSend_t) (NetworkContext_t *pNetworkContext, const void *pBuffer, size_t bytesToSend)
 Transport interface for sending data over the network.
 
typedef int32_t(* TransportWritev_t) (NetworkContext_t *pNetworkContext, TransportOutVector_t *pIoVec, size_t ioVecCount)
 Transport interface function for "vectored" / scatter-gather based writes. This function is expected to iterate over the list of vectors pIoVec having ioVecCount entries containing portions of one MQTT message at a maximum. If the proper functionality is available, then the data in the list should be copied to the underlying TCP buffer before flushing the buffer. Implementing it in this fashion will lead to sending of fewer TCP packets for all the values in the list.
 
+

Detailed Description

+

Transport interface definitions to send and receive data over the network.

+
+
+ + + + diff --git a/v1.3.0/coreMQTT/transport__interface_8h_source.html b/v1.3.0/coreMQTT/transport__interface_8h_source.html new file mode 100644 index 00000000..e3f61339 --- /dev/null +++ b/v1.3.0/coreMQTT/transport__interface_8h_source.html @@ -0,0 +1,208 @@ + + + + + + + +coreMQTT: transport_interface.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT v2.3.1 +
+
MQTT 3.1.1 Client Library
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
transport_interface.h
+
+
+Go to the documentation of this file.
1/*
+
2 * coreMQTT v2.3.1
+
3 * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
4 *
+
5 * SPDX-License-Identifier: MIT
+
6 *
+
7 * Permission is hereby granted, free of charge, to any person obtaining a copy of
+
8 * this software and associated documentation files (the "Software"), to deal in
+
9 * the Software without restriction, including without limitation the rights to
+
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
11 * the Software, and to permit persons to whom the Software is furnished to do so,
+
12 * subject to the following conditions:
+
13 *
+
14 * The above copyright notice and this permission notice shall be included in all
+
15 * copies or substantial portions of the Software.
+
16 *
+
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
23 */
+
24
+
30#ifndef TRANSPORT_INTERFACE_H_
+
31#define TRANSPORT_INTERFACE_H_
+
32
+
33#include <stdint.h>
+
34#include <stddef.h>
+
35
+
36/* *INDENT-OFF* */
+
37#ifdef __cplusplus
+
38 extern "C" {
+
39#endif
+
40/* *INDENT-ON* */
+
41
+
189/* @[define_networkcontext] */
+
190struct NetworkContext;
+
191typedef struct NetworkContext NetworkContext_t;
+
192/* @[define_networkcontext] */
+
193
+
217/* @[define_transportrecv] */
+
218typedef int32_t ( * TransportRecv_t )( NetworkContext_t * pNetworkContext,
+
219 void * pBuffer,
+
220 size_t bytesToRecv );
+
221/* @[define_transportrecv] */
+
222
+
239/* @[define_transportsend] */
+
240typedef int32_t ( * TransportSend_t )( NetworkContext_t * pNetworkContext,
+
241 const void * pBuffer,
+
242 size_t bytesToSend );
+
243/* @[define_transportsend] */
+
244
+
248typedef struct TransportOutVector
+
249{
+
253 const void * iov_base;
+
254
+
258 size_t iov_len;
+ +
260
+
287/* @[define_transportwritev] */
+
288typedef int32_t ( * TransportWritev_t )( NetworkContext_t * pNetworkContext,
+
289 TransportOutVector_t * pIoVec,
+
290 size_t ioVecCount );
+
291/* @[define_transportwritev] */
+
292
+
297/* @[define_transportinterface] */
+
298typedef struct TransportInterface
+
299{
+ + + + + +
305/* @[define_transportinterface] */
+
306
+
307/* *INDENT-OFF* */
+
308#ifdef __cplusplus
+
309 }
+
310#endif
+
311/* *INDENT-ON* */
+
312
+
313#endif /* ifndef TRANSPORT_INTERFACE_H_ */
+
int32_t(* TransportRecv_t)(NetworkContext_t *pNetworkContext, void *pBuffer, size_t bytesToRecv)
Transport interface for receiving data on the network.
Definition: transport_interface.h:218
+
int32_t(* TransportSend_t)(NetworkContext_t *pNetworkContext, const void *pBuffer, size_t bytesToSend)
Transport interface for sending data over the network.
Definition: transport_interface.h:240
+
int32_t(* TransportWritev_t)(NetworkContext_t *pNetworkContext, TransportOutVector_t *pIoVec, size_t ioVecCount)
Transport interface function for "vectored" / scatter-gather based writes. This function is expected ...
Definition: transport_interface.h:288
+
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
+
The transport layer interface.
Definition: transport_interface.h:299
+
TransportSend_t send
Definition: transport_interface.h:301
+
TransportRecv_t recv
Definition: transport_interface.h:300
+
TransportWritev_t writev
Definition: transport_interface.h:302
+
NetworkContext_t * pNetworkContext
Definition: transport_interface.h:303
+
Transport vector structure for sending multiple messages.
Definition: transport_interface.h:249
+
const void * iov_base
Base address of data.
Definition: transport_interface.h:253
+
size_t iov_len
Length of data in buffer.
Definition: transport_interface.h:258
+
+
+ + + + diff --git a/v1.3.0/core__mqtt__agent_8c.html b/v1.3.0/core__mqtt__agent_8c.html new file mode 100644 index 00000000..9c581607 --- /dev/null +++ b/v1.3.0/core__mqtt__agent_8c.html @@ -0,0 +1,1964 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent.c File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_agent.c File Reference
+
+
+ +

Implements an MQTT agent (or daemon task) to enable multithreaded access to coreMQTT. +More...

+
#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include "core_mqtt_agent.h"
+#include "core_mqtt_agent_command_functions.h"
+#include "core_mqtt_agent_default_logging.h"
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

static MQTTStatus_t addAwaitingOperation (MQTTAgentContext_t *pAgentContext, uint16_t packetId, MQTTAgentCommand_t *pCommand)
 Track an operation by adding it to a list, indicating it is anticipating an acknowledgment.
 
static MQTTAgentAckInfo_tgetAwaitingOperation (MQTTAgentContext_t *pAgentContext, uint16_t incomingPacketId)
 Retrieve an operation from the list of pending acks, and optionally remove it from the list.
 
static MQTTStatus_t createCommand (MQTTAgentCommandType_t commandType, const MQTTAgentContext_t *pMqttAgentContext, void *pMqttInfoParam, MQTTAgentCommandCallback_t commandCompleteCallback, MQTTAgentCommandContext_t *pCommandCompleteCallbackContext, MQTTAgentCommand_t *pCommand)
 Populate the parameters of a MQTTAgentCommand struct.
 
static MQTTStatus_t addCommandToQueue (const MQTTAgentContext_t *pAgentContext, MQTTAgentCommand_t *pCommand, uint32_t blockTimeMs)
 Add a command to the global command queue.
 
static MQTTStatus_t processCommand (MQTTAgentContext_t *pMqttAgentContext, MQTTAgentCommand_t *pCommand, bool *pEndLoop)
 Process a MQTTAgentCommand struct.
 
static void mqttEventCallback (MQTTContext_t *pMqttContext, MQTTPacketInfo_t *pPacketInfo, MQTTDeserializedInfo_t *pDeserializedInfo)
 Dispatch incoming publishes and acks to their various handler functions.
 
static void handleAcks (const MQTTAgentContext_t *pAgentContext, const MQTTPacketInfo_t *pPacketInfo, const MQTTDeserializedInfo_t *pDeserializedInfo, MQTTAgentAckInfo_t *pAckInfo, uint8_t packetType)
 Mark a command as complete after receiving an acknowledgment packet.
 
static MQTTAgentContext_tgetAgentFromMQTTContext (MQTTContext_t *pMQTTContext)
 Retrieve a pointer to an agent context given an MQTT context.
 
static MQTTStatus_t createAndAddCommand (MQTTAgentCommandType_t commandType, const MQTTAgentContext_t *pMqttAgentContext, void *pMqttInfoParam, MQTTAgentCommandCallback_t commandCompleteCallback, MQTTAgentCommandContext_t *pCommandCompleteCallbackContext, uint32_t blockTimeMs)
 Helper function for creating a command and adding it to the command queue.
 
static void concludeCommand (const MQTTAgentContext_t *pAgentContext, MQTTAgentCommand_t *pCommand, MQTTStatus_t returnCode, uint8_t *pSubackCodes)
 Helper function to mark a command as complete and invoke its callback. This function calls the releaseCommand callback.
 
static MQTTStatus_t resendPublishes (MQTTAgentContext_t *pMqttAgentContext)
 Resend QoS 1 and 2 publishes after resuming a session.
 
static void clearPendingAcknowledgments (MQTTAgentContext_t *pMqttAgentContext, bool clearOnlySubUnsubEntries)
 Clears the list of pending acknowledgments by invoking each callback with MQTTRecvFailed either for ALL operations in the list OR only for Subscribe/Unsubscribe operations.
 
static bool validateStruct (const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
 Validate an MQTTAgentContext_t and a MQTTAgentCommandInfo_t from API functions.
 
static bool validateParams (MQTTAgentCommandType_t commandType, const void *pParams)
 Validate the parameters for a CONNECT, SUBSCRIBE, UNSUBSCRIBE or PUBLISH.
 
static bool isSpaceInPendingAckList (const MQTTAgentContext_t *pAgentContext)
 Called before accepting any PUBLISH or SUBSCRIBE messages to check there is space in the pending ACK list for the outgoing PUBLISH or SUBSCRIBE.
 
MQTTStatus_t MQTTAgent_Init (MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentMessageInterface_t *pMsgInterface, const MQTTFixedBuffer_t *pNetworkBuffer, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getCurrentTimeMs, MQTTAgentIncomingPublishCallback_t incomingCallback, void *pIncomingPacketContext)
 Perform any initialization the MQTT agent requires before it can be used. Must be called before any other function.
 
MQTTStatus_t MQTTAgent_CommandLoop (MQTTAgentContext_t *pMqttAgentContext)
 Process commands from the command queue in a loop.
 
MQTTStatus_t MQTTAgent_ResumeSession (MQTTAgentContext_t *pMqttAgentContext, bool sessionPresent)
 Resume a session by resending publishes if a session is present in the broker, or clear state information if not.
 
MQTTStatus_t MQTTAgent_CancelAll (MQTTAgentContext_t *pMqttAgentContext)
 Cancel all enqueued commands and those awaiting acknowledgment while the command loop is not running.
 
MQTTStatus_t MQTTAgent_Subscribe (const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to call MQTT_Subscribe() for an MQTT connection.
 
MQTTStatus_t MQTTAgent_Unsubscribe (const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to call MQTT_Unsubscribe() for an MQTT connection.
 
MQTTStatus_t MQTTAgent_Publish (const MQTTAgentContext_t *pMqttAgentContext, MQTTPublishInfo_t *pPublishInfo, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to call MQTT_Publish() for an MQTT connection.
 
MQTTStatus_t MQTTAgent_ProcessLoop (const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
 Send a message to the MQTT agent purely to trigger an iteration of its loop, which will result in a call to MQTT_ProcessLoop(). This function can be used to wake the MQTT agent task when it is known data may be available on the connected socket.
 
MQTTStatus_t MQTTAgent_Connect (const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentConnectArgs_t *pConnectArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to call MQTT_Connect() for an MQTT connection. If a session is resumed with the broker, it will also resend the necessary QoS1/2 publishes.
 
MQTTStatus_t MQTTAgent_Disconnect (const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to disconnect an MQTT connection.
 
MQTTStatus_t MQTTAgent_Ping (const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to call MQTT_Ping() for an MQTT connection.
 
MQTTStatus_t MQTTAgent_Terminate (const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a termination command to the command queue.
 
+

Detailed Description

+

Implements an MQTT agent (or daemon task) to enable multithreaded access to coreMQTT.

+
Note
Implements an MQTT agent (or daemon task) on top of the coreMQTT MQTT client library. The agent makes coreMQTT usage thread safe by being the only task (or thread) in the system that is allowed to access the native coreMQTT API - and in so doing, serializes all access to coreMQTT even when multiple tasks are using the same MQTT connection.
+

The agent provides an equivalent API for each coreMQTT API. Whereas coreMQTT APIs are prefixed "MQTT_", the agent APIs are prefixed "MQTTAgent_". For example, that agent's MQTTAgent_Publish() API is the thread safe equivalent to coreMQTT's MQTT_Publish() API.

+

Function Documentation

+ +

◆ addAwaitingOperation()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t addAwaitingOperation (MQTTAgentContext_tpAgentContext,
uint16_t packetId,
MQTTAgentCommand_t * pCommand 
)
+
+static
+
+ +

Track an operation by adding it to a list, indicating it is anticipating an acknowledgment.

+
Parameters
+ + + + +
[in]pAgentContextAgent context for the MQTT connection.
[in]packetIdPacket ID of pending ack.
[in]pCommandPointer to command that is expecting an ack.
+
+
+
Returns
Returns one of the following:
    +
  • MQTTSuccess if an entry was added for the to the list.
  • +
  • MQTTStateCollision if there already exists an entry for the same packet ID in the list.
  • +
  • MQTTNoMemory if there is no space available in the list for adding a new entry.
  • +
+
+ +
+
+ +

◆ getAwaitingOperation()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MQTTAgentAckInfo_t * getAwaitingOperation (MQTTAgentContext_tpAgentContext,
uint16_t incomingPacketId 
)
+
+static
+
+ +

Retrieve an operation from the list of pending acks, and optionally remove it from the list.

+
Parameters
+ + + +
[in]pAgentContextAgent context for the MQTT connection.
[in]incomingPacketIdPacket ID of incoming ack.
+
+
+
Returns
Pointer to stored information about the operation awaiting the ack. Returns NULL if the packet ID is zero or original command does not exist.
+ +
+
+ +

◆ createCommand()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t createCommand (MQTTAgentCommandType_t commandType,
const MQTTAgentContext_tpMqttAgentContext,
void * pMqttInfoParam,
MQTTAgentCommandCallback_t commandCompleteCallback,
MQTTAgentCommandContext_tpCommandCompleteCallbackContext,
MQTTAgentCommand_t * pCommand 
)
+
+static
+
+ +

Populate the parameters of a MQTTAgentCommand struct.

+
Parameters
+ + + + + + + +
[in]commandTypeType of command. For example, publish or subscribe.
[in]pMqttAgentContextPointer to MQTT context to use for command.
[in]pMqttInfoParamPointer to MQTTPublishInfo_t or MQTTSubscribeInfo_t.
[in]commandCompleteCallbackCallback for when command completes.
[in]pCommandCompleteCallbackContextContext and necessary structs for command.
[out]pCommandPointer to initialized command.
+
+
+
Returns
MQTTSuccess if all necessary fields for the command are passed, else an enumerated error code.
+ +
+
+ +

◆ addCommandToQueue()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t addCommandToQueue (const MQTTAgentContext_tpAgentContext,
MQTTAgentCommand_t * pCommand,
uint32_t blockTimeMs 
)
+
+static
+
+ +

Add a command to the global command queue.

+
Parameters
+ + + + +
[in]pAgentContextAgent context for the MQTT connection.
[in]pCommandPointer to command to copy to queue.
[in]blockTimeMsThe maximum amount of time to milliseconds to wait in the Blocked state (so not consuming any CPU time) for the command to be posted to the queue should the queue already be full.
+
+
+
Returns
MQTTSuccess if the command was added to the queue, else an enumerated error code.
+ +
+
+ +

◆ processCommand()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t processCommand (MQTTAgentContext_tpMqttAgentContext,
MQTTAgentCommand_t * pCommand,
bool * pEndLoop 
)
+
+static
+
+ +

Process a MQTTAgentCommand struct.

+
Note
This agent does not check existing subscriptions before sending a SUBSCRIBE or UNSUBSCRIBE packet. If a subscription already exists, then a SUBSCRIBE packet will be sent anyway, and if multiple tasks are subscribed to a topic filter, then they will all be unsubscribed after an UNSUBSCRIBE.
+
Parameters
+ + + + +
[in]pMqttAgentContextAgent context for MQTT connection.
[in]pCommandPointer to command to process.
[out]pEndLoopWhether the command loop should terminate.
+
+
+
Returns
status of MQTT library API call.
+ +
+
+ +

◆ mqttEventCallback()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static void mqttEventCallback (MQTTContext_tpMqttContext,
MQTTPacketInfo_tpPacketInfo,
MQTTDeserializedInfo_tpDeserializedInfo 
)
+
+static
+
+ +

Dispatch incoming publishes and acks to their various handler functions.

+
Parameters
+ + + + +
[in]pMqttContextMQTT Context
[in]pPacketInfoPointer to incoming packet.
[in]pDeserializedInfoPointer to deserialized information from the incoming packet.
+
+
+ +
+
+ +

◆ handleAcks()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static void handleAcks (const MQTTAgentContext_tpAgentContext,
const MQTTPacketInfo_tpPacketInfo,
const MQTTDeserializedInfo_tpDeserializedInfo,
MQTTAgentAckInfo_tpAckInfo,
uint8_t packetType 
)
+
+static
+
+ +

Mark a command as complete after receiving an acknowledgment packet.

+
Parameters
+ + + + + + +
[in]pAgentContextAgent context for the MQTT connection.
[in]pPacketInfoPointer to incoming packet.
[in]pDeserializedInfoPointer to deserialized information from the incoming packet.
[in]pAckInfoPointer to stored information for the original operation resulting in the received packet.
[in]packetTypeThe type of the incoming packet, either SUBACK, UNSUBACK, PUBACK, or PUBCOMP.
+
+
+ +
+
+ +

◆ getAgentFromMQTTContext()

+ +
+
+ + + + + +
+ + + + + + + + +
static MQTTAgentContext_t * getAgentFromMQTTContext (MQTTContext_tpMQTTContext)
+
+static
+
+ +

Retrieve a pointer to an agent context given an MQTT context.

+
Parameters
+ + +
[in]pMQTTContextMQTT Context to search for.
+
+
+
Returns
Pointer to agent context, or NULL.
+ +
+
+ +

◆ createAndAddCommand()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static MQTTStatus_t createAndAddCommand (MQTTAgentCommandType_t commandType,
const MQTTAgentContext_tpMqttAgentContext,
void * pMqttInfoParam,
MQTTAgentCommandCallback_t commandCompleteCallback,
MQTTAgentCommandContext_tpCommandCompleteCallbackContext,
uint32_t blockTimeMs 
)
+
+static
+
+ +

Helper function for creating a command and adding it to the command queue.

+
Parameters
+ + + + + + + +
[in]commandTypeType of command.
[in]pMqttAgentContextHandle of the MQTT connection to use.
[in]pCommandCompleteCallbackContextContext and necessary structs for command.
[in]commandCompleteCallbackCallback for when command completes.
[in]pMqttInfoParamPointer to command argument.
[in]blockTimeMsMaximum amount of time in milliseconds to wait (in the Blocked state, so not consuming any CPU time) for the command to be posted to the MQTT agent should the MQTT agent's event queue be full.
+
+
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+ +
+
+ +

◆ concludeCommand()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static void concludeCommand (const MQTTAgentContext_tpAgentContext,
MQTTAgentCommand_t * pCommand,
MQTTStatus_t returnCode,
uint8_t * pSubackCodes 
)
+
+static
+
+ +

Helper function to mark a command as complete and invoke its callback. This function calls the releaseCommand callback.

+
Parameters
+ + + + + +
[in]pAgentContextAgent context for the MQTT connection.
[in]pCommandCommand to complete.
[in]returnCodeReturn status of command.
[in]pSubackCodesPointer to suback array, if command is a SUBSCRIBE.
+
+
+ +
+
+ +

◆ resendPublishes()

+ +
+
+ + + + + +
+ + + + + + + + +
static MQTTStatus_t resendPublishes (MQTTAgentContext_tpMqttAgentContext)
+
+static
+
+ +

Resend QoS 1 and 2 publishes after resuming a session.

+
Parameters
+ + +
[in]pMqttAgentContextAgent context for the MQTT connection.
+
+
+
Returns
MQTTSuccess if all publishes resent successfully, else error code from MQTT_Publish.
+ +
+
+ +

◆ clearPendingAcknowledgments()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static void clearPendingAcknowledgments (MQTTAgentContext_tpMqttAgentContext,
bool clearOnlySubUnsubEntries 
)
+
+static
+
+ +

Clears the list of pending acknowledgments by invoking each callback with MQTTRecvFailed either for ALL operations in the list OR only for Subscribe/Unsubscribe operations.

+
Parameters
+ + + +
[in]pMqttAgentContextAgent context of the MQTT connection.
[in]clearOnlySubUnsubEntriesFlag indicating whether all entries OR entries pertaining to only Subscribe/Unsubscribe operations should be cleaned from the list.
+
+
+ +
+
+ +

◆ validateStruct()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static bool validateStruct (const MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+static
+
+ +

Validate an MQTTAgentContext_t and a MQTTAgentCommandInfo_t from API functions.

+
Parameters
+ + + +
[in]pMqttAgentContextMQTTAgentContext_t to validate.
[in]pCommandInfoMQTTAgentCommandInfo_t to validate.
+
+
+
Returns
true if parameters are valid, else false.
+ +
+
+ +

◆ validateParams()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static bool validateParams (MQTTAgentCommandType_t commandType,
const void * pParams 
)
+
+static
+
+ +

Validate the parameters for a CONNECT, SUBSCRIBE, UNSUBSCRIBE or PUBLISH.

+
Parameters
+ + + +
[in]commandTypeCONNECT, SUBSCRIBE, UNSUBSCRIBE, or PUBLISH.
[in]pParamsParameter structure to validate.
+
+
+
Returns
true if parameter structure is valid, else false.
+ +
+
+ +

◆ isSpaceInPendingAckList()

+ +
+
+ + + + + +
+ + + + + + + + +
static bool isSpaceInPendingAckList (const MQTTAgentContext_tpAgentContext)
+
+static
+
+ +

Called before accepting any PUBLISH or SUBSCRIBE messages to check there is space in the pending ACK list for the outgoing PUBLISH or SUBSCRIBE.

+
Note
Because the MQTT agent is inherently multi threaded, and this function is called from the context of the application task and not the MQTT agent task, this function can only return a best effort result. It can definitely say if there is space for a new pending ACK when the function is called, but the case of space being exhausted when the agent executes a command that results in an ACK must still be handled.
+
Parameters
+ + +
[in]pAgentContextPointer to the context for the MQTT connection to which the PUBLISH or SUBSCRIBE message is to be sent.
+
+
+
Returns
true if there is space in that MQTT connection's ACK list, otherwise false;
+ +
+
+ +

◆ MQTTAgent_Init()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Init (MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentMessageInterface_tpMsgInterface,
const MQTTFixedBuffer_tpNetworkBuffer,
const TransportInterface_tpTransportInterface,
MQTTGetCurrentTimeFunc_t getCurrentTimeMs,
MQTTAgentIncomingPublishCallback_t incomingCallback,
void * pIncomingPacketContext 
)
+
+ +

Perform any initialization the MQTT agent requires before it can be used. Must be called before any other function.

+
Parameters
+ + + + + + + + +
[in]pMqttAgentContextPointer to struct to initialize.
[in]pMsgInterfaceCommand interface to use for allocating and sending commands.
[in]pNetworkBufferPointer to network buffer to use.
[in]pTransportInterfaceTransport interface to use with the MQTT library. See https://www.freertos.org/Documentation/03-Libraries/03-FreeRTOS-core/06-Transport-Interface/01-Transport-interface
[in]getCurrentTimeMsPointer to a function that returns a count value that increments every millisecond.
[in]incomingCallbackThe callback to execute when receiving publishes.
[in]pIncomingPacketContextA pointer to a context structure defined by the application writer.
+
+
+
Note
The pIncomingPacketContext context provided for the incoming publish callback MUST remain in scope throughout the period that the agent task is running.
+
Returns
Appropriate status code from MQTT_Init().
+

Example

// Function for obtaining a timestamp.
+
uint32_t getTimeStampMs();
+
// Callback function for receiving packets.
+
void incomingPublishCallback( MQTTAgentContext_t * pMqttAgentContext,
+
uint16_t packetId,
+
MQTTPublishInfo_t * pPublishInfo );
+
// Platform function for network send interface.
+
int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
+
// Platform for network receive interface.
+
int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
+
+
// Platform function for Agent Message Send.
+
bool agentSendMessage( MQTTAgentMessageContext_t * pMsgCtx,
+
MQTTAgentCommand_t * const * pCommandToSend,
+
uint32_t blockTimeMs );
+
// Platform function for Agent Message Receive.
+
bool agentReceiveMessage( MQTTAgentMessageContext_t * pMsgCtx,
+
MQTTAgentCommand_t ** pCommandToSend,
+
uint32_t blockTimeMs );
+
// Platform function to Get Agent Command.
+
MQTTAgentCommand_t * getCommand( uint32_t blockTimeMs );
+
// Platform function to Release Agent Command.
+
bool releaseCommand( MQTTAgentCommand_t * pCommandToRelease );
+
+
// Variables used in this example.
+
MQTTAgentMessageInterface_t messageInterface;
+ +
MQTTAgentContext_t agentContext;
+ +
// Buffer for storing outgoing and incoming MQTT packets.
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ 1024 ];
+
MQTTStatus_t status;
+
+
// Set transport interface members.
+
transport.pNetworkContext = &someTransportContext;
+
transport.send = networkSend;
+
transport.recv = networkRecv;
+
+
// Set agent message interface members.
+
messageInterface.pMsgCtx = &messageContext;
+
messageInterface.send = agentSendMessage;
+
messageInterface.recv = agentReceiveMessage;
+
messageInterface.getCommand = getCommand;
+
messageInterface.releaseCommand = releaseCommand;
+
+
// Set buffer members.
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = 1024;
+
+
status = MQTTAgent_Init( &agentContext,
+
&messageInterface,
+
&networkBuffer,
+
&transportInterface,
+
stubGetTime,
+
stubPublishCallback,
+
incomingPacketContext );
+
+
if( status == MQTTSuccess )
+
{
+
// Do something with agentContext. The transport and message interfaces, and
+
// fixedBuffer structs were copied into the context, so the original structs
+
// do not need to stay in scope.
+
}
+
MQTTStatus_t MQTTAgent_Init(MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentMessageInterface_t *pMsgInterface, const MQTTFixedBuffer_t *pNetworkBuffer, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getCurrentTimeMs, MQTTAgentIncomingPublishCallback_t incomingCallback, void *pIncomingPacketContext)
Perform any initialization the MQTT agent requires before it can be used. Must be called before any o...
Definition: core_mqtt_agent.c:968
+
struct MQTTAgentMessageContext MQTTAgentMessageContext_t
Context with which tasks may deliver messages to the agent.
Definition: core_mqtt_agent_message_interface.h:54
+
MQTTStatus_t
+
struct NetworkContext NetworkContext_t
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+
Function pointers and contexts used for sending and receiving commands, and allocating memory for the...
Definition: core_mqtt_agent_message_interface.h:133
+
MQTTAgentMessageContext_t * pMsgCtx
Definition: core_mqtt_agent_message_interface.h:134
+
MQTTAgentMessageRecv_t recv
Definition: core_mqtt_agent_message_interface.h:136
+
MQTTAgentCommandGet_t getCommand
Definition: core_mqtt_agent_message_interface.h:137
+
MQTTAgentMessageSend_t send
Definition: core_mqtt_agent_message_interface.h:135
+
MQTTAgentCommandRelease_t releaseCommand
Definition: core_mqtt_agent_message_interface.h:138
+ + + + + +
TransportSend_t send
+
TransportRecv_t recv
+
NetworkContext_t * pNetworkContext
+

Array used to maintain the outgoing publish records and their state by the coreMQTT library.

+

Array used to maintain the outgoing publish records and their state by the coreMQTT library.

+ +
+
+ +

◆ MQTTAgent_CommandLoop()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTTAgent_CommandLoop (MQTTAgentContext_tpMqttAgentContext)
+
+ +

Process commands from the command queue in a loop.

+
Parameters
+ + +
[in]pMqttAgentContextThe MQTT agent to use.
+
+
+
Returns
appropriate error code, or MQTTSuccess from a successful disconnect or termination.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTAgentContext_t mqttAgentContext;
+
+
status = MQTTAgent_CommandLoop( &mqttAgentContext );
+
+
// The function returns on either receiving a terminate command,
+
// undergoing network disconnection OR encountering an error.
+
if( ( status == MQTTSuccess ) && ( mqttAgentContext.mqttContext.connectStatus == MQTTNotConnected ) )
+
{
+
// A terminate command was processed and MQTT connection was closed.
+
// Need to close socket connection.
+
Platform_DisconnectNetwork( mqttAgentContext.mqttContext.transportInterface.pNetworkContext );
+
}
+
else if( status == MQTTSuccess )
+
{
+
// Terminate command was processed but MQTT connection was not
+
// closed. Thus, need to close both MQTT and socket connections.
+
status = MQTT_Disconnect( &( mqttAgentContext.mqttContext ) );
+
assert( status == MQTTSuccess );
+
Platform_DisconnectNetwork( mqttAgentContext.mqttContext.transportInterface.pNetworkContext );
+
}
+
else
+
{
+
// Handle error.
+
}
+
MQTTStatus_t MQTT_Disconnect(MQTTContext_t *pContext)
+
MQTTStatus_t MQTTAgent_CommandLoop(MQTTAgentContext_t *pMqttAgentContext)
Process commands from the command queue in a loop.
Definition: core_mqtt_agent.c:1043
+
MQTTContext_t mqttContext
Definition: core_mqtt_agent.h:154
+
MQTTConnectionStatus_t connectStatus
+
TransportInterface_t transportInterface
+
+
+
+ +

◆ MQTTAgent_ResumeSession()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_ResumeSession (MQTTAgentContext_tpMqttAgentContext,
bool sessionPresent 
)
+
+ +

Resume a session by resending publishes if a session is present in the broker, or clear state information if not.

+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]sessionPresentThe session present flag from the broker.
+
+
+
Note
This function is NOT thread-safe and should only be called from the context of the task responsible for MQTTAgent_CommandLoop.
+
Returns
MQTTSuccess if it succeeds in resending publishes, else an appropriate error code from MQTT_Publish()
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTAgentContext_t mqttAgentContext;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
bool sessionPresent;
+
+
// The example assumes that all variables have been filled with
+
// data for the MQTT_Connect call
+
// Refer to the MQTT_Connect API for a more detailed example.
+
+
// Attempt to resume session with the broker.
+
status = MQTT_Connect( &( mqttAgentContext.mqttContext ), &connectInfo, &willInfo, 100, &sessionPresent )
+
+
if( status == MQTTSuccess )
+
{
+
// Process the session present status sent by the broker.
+
status = MQTTAgent_ResumeSession( &mqttAgentContext, sessionPresent );
+
}
+
MQTTStatus_t MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
+
MQTTStatus_t MQTTAgent_ResumeSession(MQTTAgentContext_t *pMqttAgentContext, bool sessionPresent)
Resume a session by resending publishes if a session is present in the broker, or clear state informa...
Definition: core_mqtt_agent.c:1085
+ +
+
+
+ +

◆ MQTTAgent_CancelAll()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTTAgent_CancelAll (MQTTAgentContext_tpMqttAgentContext)
+
+ +

Cancel all enqueued commands and those awaiting acknowledgment while the command loop is not running.

+

Canceled commands will be terminated with return code MQTTRecvFailed.

+
Parameters
+ + +
[in]pMqttAgentContextThe MQTT agent to use.
+
+
+
Note
This function is NOT thread-safe and should only be called from the context of the task responsible for MQTTAgent_CommandLoop.
+
Returns
MQTTBadParameter if an invalid context is given, else MQTTSuccess.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTAgentContext_t mqttAgentContext;
+
+
status = MQTTAgent_CommandLoop( &mqttAgentContext );
+
+
//An error was returned, but reconnection is not desired. Cancel all commands
+
//that are in the queue or awaiting an acknowledgment.
+
if( status != MQTTSuccess )
+
{
+
//Cancel commands so any completion callbacks will be invoked.
+
status = MQTTAgent_CancelAll( &mqttAgentContext );
+
}
+
+
Platform_DisconnectNetwork( mqttAgentContext.mqttContext.transportInterface.pNetworkContext );
+
MQTTStatus_t MQTTAgent_CancelAll(MQTTAgentContext_t *pMqttAgentContext)
Cancel all enqueued commands and those awaiting acknowledgment while the command loop is not running.
Definition: core_mqtt_agent.c:1128
+
+
+
+ +

◆ MQTTAgent_Subscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Subscribe (const MQTTAgentContext_tpMqttAgentContext,
MQTTAgentSubscribeArgs_tpSubscriptionArgs,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to call MQTT_Subscribe() for an MQTT connection.

+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pSubscriptionArgsStruct describing topic to subscribe to.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
MQTTSubscribeInfo_t subscribeInfo = { 0 };
+
MQTTAgentSubscribeArgs_t subscribeArgs = { 0 };
+
+
// Function for command complete callback.
+
void subscribeCmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.CmdCompleteCallback = subscribeCmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
// Fill the information for topic filters to subscribe to.
+
subscribeInfo.qos = Qos1;
+
subscribeInfo.pTopicFilter = "/foo/bar";
+
subscribeInfo.topicFilterLength = strlen("/foo/bar");
+
subscribeArgs.pSubscribeInfo = &subscribeInfo;
+
subscribeArgs.numSubscriptions = 1U;
+
+
status = MQTTAgent_Subscribe( &agentContext, &subscribeArgs, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to send subscribe request to the server has been queued. Notification
+
// about completion of the subscribe operation will be notified to application
+
// through invocation of subscribeCmdCompleteCb().
+
}
+
MQTTStatus_t MQTTAgent_Subscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Subscribe() for an MQTT connection.
Definition: core_mqtt_agent.c:1177
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
Struct holding arguments that are common to every command.
Definition: core_mqtt_agent.h:189
+
uint32_t blockTimeMs
Maximum block time for enqueueing the command.
Definition: core_mqtt_agent.h:192
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+
Struct holding arguments for a SUBSCRIBE or UNSUBSCRIBE call.
Definition: core_mqtt_agent.h:167
+
MQTTSubscribeInfo_t * pSubscribeInfo
List of MQTT subscriptions.
Definition: core_mqtt_agent.h:168
+
size_t numSubscriptions
Number of elements in pSubscribeInfo.
Definition: core_mqtt_agent.h:169
+ + +
uint16_t topicFilterLength
+
const char * pTopicFilter
+
+
+
+ +

◆ MQTTAgent_Unsubscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Unsubscribe (const MQTTAgentContext_tpMqttAgentContext,
MQTTAgentSubscribeArgs_tpSubscriptionArgs,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to call MQTT_Unsubscribe() for an MQTT connection.

+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pSubscriptionArgsList of topics to unsubscribe from.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
MQTTSubscribeInfo_t unsubscribeInfo = { 0 };
+
MQTTAgentSubscribeArgs_t unsubscribeArgs = { 0 };
+
+
// Function for command complete callback.
+
void unsubscribeCmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = unsubscribeCmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
// Fill the information for topics to unsubscribe from.
+
unsubscribeInfo.pTopicFilter = "/foo/bar";
+
unsubscribeInfo.topicFilterLength = strlen("/foo/bar");
+
unsubscribeArgs.pSubscribeInfo = &unsubscribeInfo;
+
unsubscribeArgs.numSubscriptions = 1U;
+
+
status = MQTTAgent_Unsubscribe( &agentContext, &unsubscribeArgs, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to send Unsubscribe request to the server has been queued. Notification
+
// about completion of the Unsubscribe operation will be notified to application
+
// through invocation of unsubscribeCompleteCb().
+
}
+
MQTTStatus_t MQTTAgent_Unsubscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Unsubscribe() for an MQTT connection.
Definition: core_mqtt_agent.c:1202
+
MQTTAgentCommandCallback_t cmdCompleteCallback
Callback to invoke upon completion.
Definition: core_mqtt_agent.h:190
+
+
+
+ +

◆ MQTTAgent_Publish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Publish (const MQTTAgentContext_tpMqttAgentContext,
MQTTPublishInfo_tpPublishInfo,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to call MQTT_Publish() for an MQTT connection.

+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pPublishInfoMQTT PUBLISH information.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
MQTTPublishInfo_t publishInfo = { 0 };
+
+
// Function for command complete callback.
+
void publishCmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = publishCmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
// Fill the information for publish operation.
+
publishInfo.qos = MQTTQoS1;
+
publishInfo.pTopicName = "/some/topic/name";
+
publishInfo.topicNameLength = strlen( publishInfo.pTopicName );
+
publishInfo.pPayload = "Hello World!";
+
publishInfo.payloadLength = strlen( "Hello World!" );
+
+
status = MQTTAgent_Publish( &agentContext, &publishInfo, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to publish message to broker has been queued.
+
// The event of publish operation completion will be notified with
+
// the invocation of the publishCmdCompleteCb().
+
}
+
MQTTStatus_t MQTTAgent_Publish(const MQTTAgentContext_t *pMqttAgentContext, MQTTPublishInfo_t *pPublishInfo, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Publish() for an MQTT connection.
Definition: core_mqtt_agent.c:1227
+
MQTTQoS1
+ +
uint16_t topicNameLength
+ +
const char * pTopicName
+
const void * pPayload
+
+
+
+ +

◆ MQTTAgent_ProcessLoop()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_ProcessLoop (const MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Send a message to the MQTT agent purely to trigger an iteration of its loop, which will result in a call to MQTT_ProcessLoop(). This function can be used to wake the MQTT agent task when it is known data may be available on the connected socket.

+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void cmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = cmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_ProcessLoop( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to call MQTT_ProcessLoop() has been queued.
+
// After processing the command, if an incoming publish is received,
+
// the event will be notified with invocation of the incoming publish
+
// callback configured in the agent context.
+
}
+
MQTTStatus_t MQTTAgent_ProcessLoop(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Send a message to the MQTT agent purely to trigger an iteration of its loop, which will result in a c...
Definition: core_mqtt_agent.c:1252
+
+
+
+ +

◆ MQTTAgent_Connect()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Connect (const MQTTAgentContext_tpMqttAgentContext,
MQTTAgentConnectArgs_tpConnectArgs,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to call MQTT_Connect() for an MQTT connection. If a session is resumed with the broker, it will also resend the necessary QoS1/2 publishes.

+
Note
The MQTTAgent_Connect function is provided to give a thread safe equivalent to the MQTT_Connect API. However, it is RECOMMENDED that instead of the application tasks (i.e. tasks other than the agent task), the agent be responsible for creating the MQTT connection (by calling MQTT_Connect) before starting the command loop (with the MQTTAgent_CommandLoop() call). In that case, the agent SHOULD also be responsible for disconnecting the MQTT connection after the command loop has terminated (through an MQTTAgent_Terminate() call from an application task).
+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in,out]pConnectArgsStruct holding args for MQTT_Connect(). On a successful connection after the command is processed, the sessionPresent member will be filled to indicate whether the broker resumed an existing session.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
MQTTAgentConnectArgs_t connectionArgs;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// True for creating a new session with broker, false if we want to resume an old one.
+
connectInfo.cleanSession = true;
+
// Client ID must be unique to broker. This field is required.
+
connectInfo.pClientIdentifier = "someClientID";
+
connectInfo.clientIdentifierLength = strlen( connectInfo.pClientIdentifier );
+
+
// Value for keep alive.
+
connectInfo.keepAliveSeconds = 60;
+
// The following fields are optional.
+
// Optional username and password.
+
connectInfo.pUserName = "someUserName";
+
connectInfo.userNameLength = strlen( connectInfo.pUserName );
+
connectInfo.pPassword = "somePassword";
+
connectInfo.passwordLength = strlen( connectInfo.pPassword );
+
+
// The last will and testament is optional, it will be published by the broker
+
// should this client disconnect without sending a DISCONNECT packet.
+
willInfo.qos = MQTTQoS0;
+
willInfo.pTopicName = "/lwt/topic/name";
+
willInfo.topicNameLength = strlen( willInfo.pTopicName );
+
willInfo.pPayload = "LWT Message";
+
willInfo.payloadLength = strlen( "LWT Message" );
+
+
// Fill the MQTTAgentConnectArgs_t structure.
+
connectArgs.pConnectInfo = &connectInfo;
+
connectArgs.pWillInfo = &willInfo;
+
// Time to block for CONNACK response when command is processed.
+
connectArgs.timeoutMs = 500;
+
+
// Function for command complete callback.
+
void connectCmdCallback( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = connectCmdCallback;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Connect( &agentContext, &connectArgs, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command for creating the MQTT connection has been queued.
+
// The MQTT connection event will be notified through the
+
// invocation of connectCmdCallback().
+
}
+
MQTTStatus_t MQTTAgent_Connect(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentConnectArgs_t *pConnectArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Connect() for an MQTT connection. If a session is resumed with the broker,...
Definition: core_mqtt_agent.c:1275
+
MQTTQoS0
+
Struct holding arguments for a CONNECT call.
Definition: core_mqtt_agent.h:177
+
const char * pClientIdentifier
+
const char * pUserName
+ +
uint16_t userNameLength
+
uint16_t keepAliveSeconds
+
uint16_t clientIdentifierLength
+
uint16_t passwordLength
+
const char * pPassword
+
+
+
+ +

◆ MQTTAgent_Disconnect()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Disconnect (const MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to disconnect an MQTT connection.

+
Note
MQTTAgent_CommandLoop will return after processing a DISCONNECT command to allow the network connection to be disconnected. However, any pending commands in the queue, as well as those waiting for an acknowledgment, will NOT be terminated.
+
+The MQTTAgent_Disconnect function is provided to give a thread safe equivalent to the MQTT_Disconnect API. However, if the agent task is responsible for creating the MQTT connection (before calling MQTTAgent_CommandLoop()), then it is RECOMMENDED that an application task (i.e. a task other than the agent task) use MQTTAgent_Terminate to terminate the command loop in the agent, and the agent task be responsible for disconnecting the MQTT connection.
+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void disconnectCmdCallback( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = disconnectCmdCallback;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Disconnect( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command for closing the MQTT connection has been queued.
+
// The MQTT disconnection event will be notified through the
+
// invocation of disconnectCmdCallback().
+
}
+
MQTTStatus_t MQTTAgent_Disconnect(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to disconnect an MQTT connection.
Definition: core_mqtt_agent.c:1300
+
+
+
+ +

◆ MQTTAgent_Ping()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Ping (const MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to call MQTT_Ping() for an MQTT connection.

+
Note
This API function ONLY enqueues a command to send a ping request to the server, and DOES NOT wait for a ping response to be received from the server. To detect whether a Ping Response, has not been received from the server, the MQTTAgent_CommandLoop function SHOULD be used, which returns the MQTTKeepAliveTimeout return code on a ping response (or keep-alive) timeout.
+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void pingRequestCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = pingRequestCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Ping( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command for sending request has been queued. Application can
+
// handle keep-alive timeout if detected through return value of
+
// MQTTAgent_CommandLoop in the task running the agent.
+
}
+
MQTTStatus_t MQTTAgent_Ping(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Ping() for an MQTT connection.
Definition: core_mqtt_agent.c:1323
+
+
+
+ +

◆ MQTTAgent_Terminate()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Terminate (const MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a termination command to the command queue.

+

On command loop termination, all pending commands in the queue, as well as those waiting for an acknowledgment, will be terminated with error code MQTTRecvFailed.

+
Note
Commands may still be posted to the command queue after MQTTAgent_CommandLoop has returned. It is the responsibility of the application to cancel any commands that are posted while the command loop is not running, such as by invoking MQTTAgent_CancelAll.
+
+We RECOMMEND that this function is used from application task(s), that is a task not running the agent, to terminate the agent loop instead of calling MQTTAgent_Disconnect, so that the logic for creating and closing MQTT connection is owned by the agent task.
+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void terminateCallback( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = terminateCallback;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Terminate( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to terminate the agent loop has been queued.
+
}
+
MQTTStatus_t MQTTAgent_Terminate(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a termination command to the command queue.
Definition: core_mqtt_agent.c:1346
+
+
+
+
+
+ + + + diff --git a/v1.3.0/core__mqtt__agent_8h.html b/v1.3.0/core__mqtt__agent_8h.html new file mode 100644 index 00000000..a6740486 --- /dev/null +++ b/v1.3.0/core__mqtt__agent_8h.html @@ -0,0 +1,1197 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_agent.h File Reference
+
+
+ +

Functions for running a coreMQTT client in a dedicated thread. +More...

+ +

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + + + + + + + +

+Data Structures

struct  MQTTAgentReturnInfo_t
 Struct holding return codes and outputs from a command. More...
 
struct  MQTTAgentCommand_t
 The commands sent from the APIs to the MQTT agent task. More...
 
struct  MQTTAgentAckInfo_t
 Information for a pending MQTT ack packet expected by the agent. More...
 
struct  MQTTAgentContext_t
 Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(), and every API function will accept a pointer to the initalized struct. More...
 
struct  MQTTAgentSubscribeArgs_t
 Struct holding arguments for a SUBSCRIBE or UNSUBSCRIBE call. More...
 
struct  MQTTAgentConnectArgs_t
 Struct holding arguments for a CONNECT call. More...
 
struct  MQTTAgentCommandInfo_t
 Struct holding arguments that are common to every command. More...
 
+ + + + + + + + + + +

+Typedefs

typedef struct MQTTAgentCommandContext MQTTAgentCommandContext_t
 Struct containing context for a specific command.
 
typedef void(* MQTTAgentCommandCallback_t) (MQTTAgentCommandContext_t *pCmdCallbackContext, MQTTAgentReturnInfo_t *pReturnInfo)
 Callback function called when a command completes.
 
typedef void(* MQTTAgentIncomingPublishCallback_t) (struct MQTTAgentContext *pMqttAgentContext, uint16_t packetId, MQTTPublishInfo_t *pPublishInfo)
 Callback function called when receiving a publish.
 
+ + + + +

+Enumerations

enum  MQTTAgentCommandType_t {
+  NONE = 0 +, PROCESSLOOP +, PUBLISH +, SUBSCRIBE +,
+  UNSUBSCRIBE +, PING +, CONNECT +, DISCONNECT +,
+  TERMINATE +, NUM_COMMANDS +
+ }
 A type of command for interacting with the MQTT API. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

MQTTStatus_t MQTTAgent_Init (MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentMessageInterface_t *pMsgInterface, const MQTTFixedBuffer_t *pNetworkBuffer, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getCurrentTimeMs, MQTTAgentIncomingPublishCallback_t incomingCallback, void *pIncomingPacketContext)
 Perform any initialization the MQTT agent requires before it can be used. Must be called before any other function.
 
MQTTStatus_t MQTTAgent_CommandLoop (MQTTAgentContext_t *pMqttAgentContext)
 Process commands from the command queue in a loop.
 
MQTTStatus_t MQTTAgent_ResumeSession (MQTTAgentContext_t *pMqttAgentContext, bool sessionPresent)
 Resume a session by resending publishes if a session is present in the broker, or clear state information if not.
 
MQTTStatus_t MQTTAgent_CancelAll (MQTTAgentContext_t *pMqttAgentContext)
 Cancel all enqueued commands and those awaiting acknowledgment while the command loop is not running.
 
MQTTStatus_t MQTTAgent_Subscribe (const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to call MQTT_Subscribe() for an MQTT connection.
 
MQTTStatus_t MQTTAgent_Unsubscribe (const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to call MQTT_Unsubscribe() for an MQTT connection.
 
MQTTStatus_t MQTTAgent_Publish (const MQTTAgentContext_t *pMqttAgentContext, MQTTPublishInfo_t *pPublishInfo, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to call MQTT_Publish() for an MQTT connection.
 
MQTTStatus_t MQTTAgent_ProcessLoop (const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
 Send a message to the MQTT agent purely to trigger an iteration of its loop, which will result in a call to MQTT_ProcessLoop(). This function can be used to wake the MQTT agent task when it is known data may be available on the connected socket.
 
MQTTStatus_t MQTTAgent_Ping (const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to call MQTT_Ping() for an MQTT connection.
 
MQTTStatus_t MQTTAgent_Connect (const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentConnectArgs_t *pConnectArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to call MQTT_Connect() for an MQTT connection. If a session is resumed with the broker, it will also resend the necessary QoS1/2 publishes.
 
MQTTStatus_t MQTTAgent_Disconnect (const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a command to disconnect an MQTT connection.
 
MQTTStatus_t MQTTAgent_Terminate (const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
 Add a termination command to the command queue.
 
+

Detailed Description

+

Functions for running a coreMQTT client in a dedicated thread.

+

Function Documentation

+ +

◆ MQTTAgent_Init()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Init (MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentMessageInterface_tpMsgInterface,
const MQTTFixedBuffer_tpNetworkBuffer,
const TransportInterface_tpTransportInterface,
MQTTGetCurrentTimeFunc_t getCurrentTimeMs,
MQTTAgentIncomingPublishCallback_t incomingCallback,
void * pIncomingPacketContext 
)
+
+ +

Perform any initialization the MQTT agent requires before it can be used. Must be called before any other function.

+
Parameters
+ + + + + + + + +
[in]pMqttAgentContextPointer to struct to initialize.
[in]pMsgInterfaceCommand interface to use for allocating and sending commands.
[in]pNetworkBufferPointer to network buffer to use.
[in]pTransportInterfaceTransport interface to use with the MQTT library. See https://www.freertos.org/Documentation/03-Libraries/03-FreeRTOS-core/06-Transport-Interface/01-Transport-interface
[in]getCurrentTimeMsPointer to a function that returns a count value that increments every millisecond.
[in]incomingCallbackThe callback to execute when receiving publishes.
[in]pIncomingPacketContextA pointer to a context structure defined by the application writer.
+
+
+
Note
The pIncomingPacketContext context provided for the incoming publish callback MUST remain in scope throughout the period that the agent task is running.
+
Returns
Appropriate status code from MQTT_Init().
+

Example

// Function for obtaining a timestamp.
+
uint32_t getTimeStampMs();
+
// Callback function for receiving packets.
+
void incomingPublishCallback( MQTTAgentContext_t * pMqttAgentContext,
+
uint16_t packetId,
+
MQTTPublishInfo_t * pPublishInfo );
+
// Platform function for network send interface.
+
int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
+
// Platform for network receive interface.
+
int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
+
+
// Platform function for Agent Message Send.
+
bool agentSendMessage( MQTTAgentMessageContext_t * pMsgCtx,
+
MQTTAgentCommand_t * const * pCommandToSend,
+
uint32_t blockTimeMs );
+
// Platform function for Agent Message Receive.
+
bool agentReceiveMessage( MQTTAgentMessageContext_t * pMsgCtx,
+
MQTTAgentCommand_t ** pCommandToSend,
+
uint32_t blockTimeMs );
+
// Platform function to Get Agent Command.
+
MQTTAgentCommand_t * getCommand( uint32_t blockTimeMs );
+
// Platform function to Release Agent Command.
+
bool releaseCommand( MQTTAgentCommand_t * pCommandToRelease );
+
+
// Variables used in this example.
+
MQTTAgentMessageInterface_t messageInterface;
+ +
MQTTAgentContext_t agentContext;
+ +
// Buffer for storing outgoing and incoming MQTT packets.
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ 1024 ];
+
MQTTStatus_t status;
+
+
// Set transport interface members.
+
transport.pNetworkContext = &someTransportContext;
+
transport.send = networkSend;
+
transport.recv = networkRecv;
+
+
// Set agent message interface members.
+
messageInterface.pMsgCtx = &messageContext;
+
messageInterface.send = agentSendMessage;
+
messageInterface.recv = agentReceiveMessage;
+
messageInterface.getCommand = getCommand;
+
messageInterface.releaseCommand = releaseCommand;
+
+
// Set buffer members.
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = 1024;
+
+
status = MQTTAgent_Init( &agentContext,
+
&messageInterface,
+
&networkBuffer,
+
&transportInterface,
+
stubGetTime,
+
stubPublishCallback,
+
incomingPacketContext );
+
+
if( status == MQTTSuccess )
+
{
+
// Do something with agentContext. The transport and message interfaces, and
+
// fixedBuffer structs were copied into the context, so the original structs
+
// do not need to stay in scope.
+
}
+
MQTTStatus_t MQTTAgent_Init(MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentMessageInterface_t *pMsgInterface, const MQTTFixedBuffer_t *pNetworkBuffer, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getCurrentTimeMs, MQTTAgentIncomingPublishCallback_t incomingCallback, void *pIncomingPacketContext)
Perform any initialization the MQTT agent requires before it can be used. Must be called before any o...
Definition: core_mqtt_agent.c:968
+
struct MQTTAgentMessageContext MQTTAgentMessageContext_t
Context with which tasks may deliver messages to the agent.
Definition: core_mqtt_agent_message_interface.h:54
+
MQTTStatus_t
+
struct NetworkContext NetworkContext_t
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+
Function pointers and contexts used for sending and receiving commands, and allocating memory for the...
Definition: core_mqtt_agent_message_interface.h:133
+
MQTTAgentMessageContext_t * pMsgCtx
Definition: core_mqtt_agent_message_interface.h:134
+
MQTTAgentMessageRecv_t recv
Definition: core_mqtt_agent_message_interface.h:136
+
MQTTAgentCommandGet_t getCommand
Definition: core_mqtt_agent_message_interface.h:137
+
MQTTAgentMessageSend_t send
Definition: core_mqtt_agent_message_interface.h:135
+
MQTTAgentCommandRelease_t releaseCommand
Definition: core_mqtt_agent_message_interface.h:138
+ + + + + +
TransportSend_t send
+
TransportRecv_t recv
+
NetworkContext_t * pNetworkContext
+

Array used to maintain the outgoing publish records and their state by the coreMQTT library.

+

Array used to maintain the outgoing publish records and their state by the coreMQTT library.

+ +
+
+ +

◆ MQTTAgent_CommandLoop()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTTAgent_CommandLoop (MQTTAgentContext_tpMqttAgentContext)
+
+ +

Process commands from the command queue in a loop.

+
Parameters
+ + +
[in]pMqttAgentContextThe MQTT agent to use.
+
+
+
Returns
appropriate error code, or MQTTSuccess from a successful disconnect or termination.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTAgentContext_t mqttAgentContext;
+
+
status = MQTTAgent_CommandLoop( &mqttAgentContext );
+
+
// The function returns on either receiving a terminate command,
+
// undergoing network disconnection OR encountering an error.
+
if( ( status == MQTTSuccess ) && ( mqttAgentContext.mqttContext.connectStatus == MQTTNotConnected ) )
+
{
+
// A terminate command was processed and MQTT connection was closed.
+
// Need to close socket connection.
+
Platform_DisconnectNetwork( mqttAgentContext.mqttContext.transportInterface.pNetworkContext );
+
}
+
else if( status == MQTTSuccess )
+
{
+
// Terminate command was processed but MQTT connection was not
+
// closed. Thus, need to close both MQTT and socket connections.
+
status = MQTT_Disconnect( &( mqttAgentContext.mqttContext ) );
+
assert( status == MQTTSuccess );
+
Platform_DisconnectNetwork( mqttAgentContext.mqttContext.transportInterface.pNetworkContext );
+
}
+
else
+
{
+
// Handle error.
+
}
+
MQTTStatus_t MQTT_Disconnect(MQTTContext_t *pContext)
+
MQTTStatus_t MQTTAgent_CommandLoop(MQTTAgentContext_t *pMqttAgentContext)
Process commands from the command queue in a loop.
Definition: core_mqtt_agent.c:1043
+
MQTTContext_t mqttContext
Definition: core_mqtt_agent.h:154
+
MQTTConnectionStatus_t connectStatus
+
TransportInterface_t transportInterface
+
+
+
+ +

◆ MQTTAgent_ResumeSession()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_ResumeSession (MQTTAgentContext_tpMqttAgentContext,
bool sessionPresent 
)
+
+ +

Resume a session by resending publishes if a session is present in the broker, or clear state information if not.

+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]sessionPresentThe session present flag from the broker.
+
+
+
Note
This function is NOT thread-safe and should only be called from the context of the task responsible for MQTTAgent_CommandLoop.
+
Returns
MQTTSuccess if it succeeds in resending publishes, else an appropriate error code from MQTT_Publish()
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTAgentContext_t mqttAgentContext;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
bool sessionPresent;
+
+
// The example assumes that all variables have been filled with
+
// data for the MQTT_Connect call
+
// Refer to the MQTT_Connect API for a more detailed example.
+
+
// Attempt to resume session with the broker.
+
status = MQTT_Connect( &( mqttAgentContext.mqttContext ), &connectInfo, &willInfo, 100, &sessionPresent )
+
+
if( status == MQTTSuccess )
+
{
+
// Process the session present status sent by the broker.
+
status = MQTTAgent_ResumeSession( &mqttAgentContext, sessionPresent );
+
}
+
MQTTStatus_t MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
+
MQTTStatus_t MQTTAgent_ResumeSession(MQTTAgentContext_t *pMqttAgentContext, bool sessionPresent)
Resume a session by resending publishes if a session is present in the broker, or clear state informa...
Definition: core_mqtt_agent.c:1085
+ +
+
+
+ +

◆ MQTTAgent_CancelAll()

+ +
+
+ + + + + + + + +
MQTTStatus_t MQTTAgent_CancelAll (MQTTAgentContext_tpMqttAgentContext)
+
+ +

Cancel all enqueued commands and those awaiting acknowledgment while the command loop is not running.

+

Canceled commands will be terminated with return code MQTTRecvFailed.

+
Parameters
+ + +
[in]pMqttAgentContextThe MQTT agent to use.
+
+
+
Note
This function is NOT thread-safe and should only be called from the context of the task responsible for MQTTAgent_CommandLoop.
+
Returns
MQTTBadParameter if an invalid context is given, else MQTTSuccess.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTAgentContext_t mqttAgentContext;
+
+
status = MQTTAgent_CommandLoop( &mqttAgentContext );
+
+
//An error was returned, but reconnection is not desired. Cancel all commands
+
//that are in the queue or awaiting an acknowledgment.
+
if( status != MQTTSuccess )
+
{
+
//Cancel commands so any completion callbacks will be invoked.
+
status = MQTTAgent_CancelAll( &mqttAgentContext );
+
}
+
+
Platform_DisconnectNetwork( mqttAgentContext.mqttContext.transportInterface.pNetworkContext );
+
MQTTStatus_t MQTTAgent_CancelAll(MQTTAgentContext_t *pMqttAgentContext)
Cancel all enqueued commands and those awaiting acknowledgment while the command loop is not running.
Definition: core_mqtt_agent.c:1128
+
+
+
+ +

◆ MQTTAgent_Subscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Subscribe (const MQTTAgentContext_tpMqttAgentContext,
MQTTAgentSubscribeArgs_tpSubscriptionArgs,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to call MQTT_Subscribe() for an MQTT connection.

+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pSubscriptionArgsStruct describing topic to subscribe to.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
MQTTSubscribeInfo_t subscribeInfo = { 0 };
+
MQTTAgentSubscribeArgs_t subscribeArgs = { 0 };
+
+
// Function for command complete callback.
+
void subscribeCmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.CmdCompleteCallback = subscribeCmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
// Fill the information for topic filters to subscribe to.
+
subscribeInfo.qos = Qos1;
+
subscribeInfo.pTopicFilter = "/foo/bar";
+
subscribeInfo.topicFilterLength = strlen("/foo/bar");
+
subscribeArgs.pSubscribeInfo = &subscribeInfo;
+
subscribeArgs.numSubscriptions = 1U;
+
+
status = MQTTAgent_Subscribe( &agentContext, &subscribeArgs, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to send subscribe request to the server has been queued. Notification
+
// about completion of the subscribe operation will be notified to application
+
// through invocation of subscribeCmdCompleteCb().
+
}
+
MQTTStatus_t MQTTAgent_Subscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Subscribe() for an MQTT connection.
Definition: core_mqtt_agent.c:1177
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
Struct holding arguments that are common to every command.
Definition: core_mqtt_agent.h:189
+
uint32_t blockTimeMs
Maximum block time for enqueueing the command.
Definition: core_mqtt_agent.h:192
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+
Struct holding arguments for a SUBSCRIBE or UNSUBSCRIBE call.
Definition: core_mqtt_agent.h:167
+
MQTTSubscribeInfo_t * pSubscribeInfo
List of MQTT subscriptions.
Definition: core_mqtt_agent.h:168
+
size_t numSubscriptions
Number of elements in pSubscribeInfo.
Definition: core_mqtt_agent.h:169
+ + +
uint16_t topicFilterLength
+
const char * pTopicFilter
+
+
+
+ +

◆ MQTTAgent_Unsubscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Unsubscribe (const MQTTAgentContext_tpMqttAgentContext,
MQTTAgentSubscribeArgs_tpSubscriptionArgs,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to call MQTT_Unsubscribe() for an MQTT connection.

+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pSubscriptionArgsList of topics to unsubscribe from.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
MQTTSubscribeInfo_t unsubscribeInfo = { 0 };
+
MQTTAgentSubscribeArgs_t unsubscribeArgs = { 0 };
+
+
// Function for command complete callback.
+
void unsubscribeCmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = unsubscribeCmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
// Fill the information for topics to unsubscribe from.
+
unsubscribeInfo.pTopicFilter = "/foo/bar";
+
unsubscribeInfo.topicFilterLength = strlen("/foo/bar");
+
unsubscribeArgs.pSubscribeInfo = &unsubscribeInfo;
+
unsubscribeArgs.numSubscriptions = 1U;
+
+
status = MQTTAgent_Unsubscribe( &agentContext, &unsubscribeArgs, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to send Unsubscribe request to the server has been queued. Notification
+
// about completion of the Unsubscribe operation will be notified to application
+
// through invocation of unsubscribeCompleteCb().
+
}
+
MQTTStatus_t MQTTAgent_Unsubscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Unsubscribe() for an MQTT connection.
Definition: core_mqtt_agent.c:1202
+
MQTTAgentCommandCallback_t cmdCompleteCallback
Callback to invoke upon completion.
Definition: core_mqtt_agent.h:190
+
+
+
+ +

◆ MQTTAgent_Publish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Publish (const MQTTAgentContext_tpMqttAgentContext,
MQTTPublishInfo_tpPublishInfo,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to call MQTT_Publish() for an MQTT connection.

+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pPublishInfoMQTT PUBLISH information.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
MQTTPublishInfo_t publishInfo = { 0 };
+
+
// Function for command complete callback.
+
void publishCmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = publishCmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
// Fill the information for publish operation.
+
publishInfo.qos = MQTTQoS1;
+
publishInfo.pTopicName = "/some/topic/name";
+
publishInfo.topicNameLength = strlen( publishInfo.pTopicName );
+
publishInfo.pPayload = "Hello World!";
+
publishInfo.payloadLength = strlen( "Hello World!" );
+
+
status = MQTTAgent_Publish( &agentContext, &publishInfo, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to publish message to broker has been queued.
+
// The event of publish operation completion will be notified with
+
// the invocation of the publishCmdCompleteCb().
+
}
+
MQTTStatus_t MQTTAgent_Publish(const MQTTAgentContext_t *pMqttAgentContext, MQTTPublishInfo_t *pPublishInfo, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Publish() for an MQTT connection.
Definition: core_mqtt_agent.c:1227
+
MQTTQoS1
+ +
uint16_t topicNameLength
+ +
const char * pTopicName
+
const void * pPayload
+
+
+
+ +

◆ MQTTAgent_ProcessLoop()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_ProcessLoop (const MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Send a message to the MQTT agent purely to trigger an iteration of its loop, which will result in a call to MQTT_ProcessLoop(). This function can be used to wake the MQTT agent task when it is known data may be available on the connected socket.

+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void cmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = cmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_ProcessLoop( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to call MQTT_ProcessLoop() has been queued.
+
// After processing the command, if an incoming publish is received,
+
// the event will be notified with invocation of the incoming publish
+
// callback configured in the agent context.
+
}
+
MQTTStatus_t MQTTAgent_ProcessLoop(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Send a message to the MQTT agent purely to trigger an iteration of its loop, which will result in a c...
Definition: core_mqtt_agent.c:1252
+
+
+
+ +

◆ MQTTAgent_Ping()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Ping (const MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to call MQTT_Ping() for an MQTT connection.

+
Note
This API function ONLY enqueues a command to send a ping request to the server, and DOES NOT wait for a ping response to be received from the server. To detect whether a Ping Response, has not been received from the server, the MQTTAgent_CommandLoop function SHOULD be used, which returns the MQTTKeepAliveTimeout return code on a ping response (or keep-alive) timeout.
+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void pingRequestCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = pingRequestCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Ping( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command for sending request has been queued. Application can
+
// handle keep-alive timeout if detected through return value of
+
// MQTTAgent_CommandLoop in the task running the agent.
+
}
+
MQTTStatus_t MQTTAgent_Ping(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Ping() for an MQTT connection.
Definition: core_mqtt_agent.c:1323
+
+
+
+ +

◆ MQTTAgent_Connect()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Connect (const MQTTAgentContext_tpMqttAgentContext,
MQTTAgentConnectArgs_tpConnectArgs,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to call MQTT_Connect() for an MQTT connection. If a session is resumed with the broker, it will also resend the necessary QoS1/2 publishes.

+
Note
The MQTTAgent_Connect function is provided to give a thread safe equivalent to the MQTT_Connect API. However, it is RECOMMENDED that instead of the application tasks (i.e. tasks other than the agent task), the agent be responsible for creating the MQTT connection (by calling MQTT_Connect) before starting the command loop (with the MQTTAgent_CommandLoop() call). In that case, the agent SHOULD also be responsible for disconnecting the MQTT connection after the command loop has terminated (through an MQTTAgent_Terminate() call from an application task).
+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in,out]pConnectArgsStruct holding args for MQTT_Connect(). On a successful connection after the command is processed, the sessionPresent member will be filled to indicate whether the broker resumed an existing session.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
MQTTAgentConnectArgs_t connectionArgs;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// True for creating a new session with broker, false if we want to resume an old one.
+
connectInfo.cleanSession = true;
+
// Client ID must be unique to broker. This field is required.
+
connectInfo.pClientIdentifier = "someClientID";
+
connectInfo.clientIdentifierLength = strlen( connectInfo.pClientIdentifier );
+
+
// Value for keep alive.
+
connectInfo.keepAliveSeconds = 60;
+
// The following fields are optional.
+
// Optional username and password.
+
connectInfo.pUserName = "someUserName";
+
connectInfo.userNameLength = strlen( connectInfo.pUserName );
+
connectInfo.pPassword = "somePassword";
+
connectInfo.passwordLength = strlen( connectInfo.pPassword );
+
+
// The last will and testament is optional, it will be published by the broker
+
// should this client disconnect without sending a DISCONNECT packet.
+
willInfo.qos = MQTTQoS0;
+
willInfo.pTopicName = "/lwt/topic/name";
+
willInfo.topicNameLength = strlen( willInfo.pTopicName );
+
willInfo.pPayload = "LWT Message";
+
willInfo.payloadLength = strlen( "LWT Message" );
+
+
// Fill the MQTTAgentConnectArgs_t structure.
+
connectArgs.pConnectInfo = &connectInfo;
+
connectArgs.pWillInfo = &willInfo;
+
// Time to block for CONNACK response when command is processed.
+
connectArgs.timeoutMs = 500;
+
+
// Function for command complete callback.
+
void connectCmdCallback( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = connectCmdCallback;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Connect( &agentContext, &connectArgs, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command for creating the MQTT connection has been queued.
+
// The MQTT connection event will be notified through the
+
// invocation of connectCmdCallback().
+
}
+
MQTTStatus_t MQTTAgent_Connect(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentConnectArgs_t *pConnectArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Connect() for an MQTT connection. If a session is resumed with the broker,...
Definition: core_mqtt_agent.c:1275
+
MQTTQoS0
+
Struct holding arguments for a CONNECT call.
Definition: core_mqtt_agent.h:177
+
const char * pClientIdentifier
+
const char * pUserName
+ +
uint16_t userNameLength
+
uint16_t keepAliveSeconds
+
uint16_t clientIdentifierLength
+
uint16_t passwordLength
+
const char * pPassword
+
+
+
+ +

◆ MQTTAgent_Disconnect()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Disconnect (const MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a command to disconnect an MQTT connection.

+
Note
MQTTAgent_CommandLoop will return after processing a DISCONNECT command to allow the network connection to be disconnected. However, any pending commands in the queue, as well as those waiting for an acknowledgment, will NOT be terminated.
+
+The MQTTAgent_Disconnect function is provided to give a thread safe equivalent to the MQTT_Disconnect API. However, if the agent task is responsible for creating the MQTT connection (before calling MQTTAgent_CommandLoop()), then it is RECOMMENDED that an application task (i.e. a task other than the agent task) use MQTTAgent_Terminate to terminate the command loop in the agent, and the agent task be responsible for disconnecting the MQTT connection.
+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void disconnectCmdCallback( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = disconnectCmdCallback;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Disconnect( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command for closing the MQTT connection has been queued.
+
// The MQTT disconnection event will be notified through the
+
// invocation of disconnectCmdCallback().
+
}
+
MQTTStatus_t MQTTAgent_Disconnect(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to disconnect an MQTT connection.
Definition: core_mqtt_agent.c:1300
+
+
+
+ +

◆ MQTTAgent_Terminate()

+ +
+
+ + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgent_Terminate (const MQTTAgentContext_tpMqttAgentContext,
const MQTTAgentCommandInfo_tpCommandInfo 
)
+
+ +

Add a termination command to the command queue.

+

On command loop termination, all pending commands in the queue, as well as those waiting for an acknowledgment, will be terminated with error code MQTTRecvFailed.

+
Note
Commands may still be posted to the command queue after MQTTAgent_CommandLoop has returned. It is the responsibility of the application to cancel any commands that are posted while the command loop is not running, such as by invoking MQTTAgent_CancelAll.
+
+We RECOMMEND that this function is used from application task(s), that is a task not running the agent, to terminate the agent loop instead of calling MQTTAgent_Disconnect, so that the logic for creating and closing MQTT connection is owned by the agent task.
+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void terminateCallback( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = terminateCallback;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Terminate( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to terminate the agent loop has been queued.
+
}
+
MQTTStatus_t MQTTAgent_Terminate(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a termination command to the command queue.
Definition: core_mqtt_agent.c:1346
+
+
+
+
+
+ + + + diff --git a/v1.3.0/core__mqtt__agent_8h_source.html b/v1.3.0/core__mqtt__agent_8h_source.html new file mode 100644 index 00000000..ee2d34a4 --- /dev/null +++ b/v1.3.0/core__mqtt__agent_8h_source.html @@ -0,0 +1,374 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
core_mqtt_agent.h
+
+
+Go to the documentation of this file.
1/*
+
2 * coreMQTT Agent <v1.3.0>
+
3 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
4 *
+
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
+
6 * this software and associated documentation files (the "Software"), to deal in
+
7 * the Software without restriction, including without limitation the rights to
+
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
9 * the Software, and to permit persons to whom the Software is furnished to do so,
+
10 * subject to the following conditions:
+
11 *
+
12 * The above copyright notice and this permission notice shall be included in all
+
13 * copies or substantial portions of the Software.
+
14 *
+
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
21 */
+
22
+
27#ifndef CORE_MQTT_AGENT_H
+
28#define CORE_MQTT_AGENT_H
+
29
+
30/* *INDENT-OFF* */
+
31#ifdef __cplusplus
+
32 extern "C" {
+
33#endif
+
34/* *INDENT-ON* */
+
35
+
36/* MQTT library includes. */
+
37#include "core_mqtt.h"
+
38#include "core_mqtt_state.h"
+
39
+ +
41
+
42/* Command messaging interface include. */
+ +
44
+
49typedef enum MQTTCommandType
+
50{
+
51 NONE = 0,
+ + + + + + + + + + +
62
+
63struct MQTTAgentContext;
+
64struct MQTTAgentCommandContext;
+
65
+
70typedef struct MQTTAgentReturnInfo
+
71{
+ +
73 uint8_t * pSubackCodes;
+ +
75
+
83typedef struct MQTTAgentCommandContext MQTTAgentCommandContext_t;
+
84
+
101typedef void (* MQTTAgentCommandCallback_t )( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
102 MQTTAgentReturnInfo_t * pReturnInfo );
+
103
+ +
111{
+ +
113 void * pArgs;
+ + +
116};
+
117
+
122typedef struct MQTTAckInfo
+
123{
+
124 uint16_t packetId;
+
125 MQTTAgentCommand_t * pOriginalCommand;
+ +
127
+
142typedef void (* MQTTAgentIncomingPublishCallback_t )( struct MQTTAgentContext * pMqttAgentContext,
+
143 uint16_t packetId,
+
144 MQTTPublishInfo_t * pPublishInfo );
+
145
+
152typedef struct MQTTAgentContext
+
153{
+ + + + + + + +
161
+
166typedef struct MQTTAgentSubscribeArgs
+
167{
+ + + +
171
+
176typedef struct MQTTAgentConnectArgs
+
177{
+ + +
180 uint32_t timeoutMs;
+ + +
183
+
188typedef struct MQTTAgentCommandInfo
+
189{
+ + +
192 uint32_t blockTimeMs;
+ +
194
+
195/*-----------------------------------------------------------*/
+
196
+
286/* @[declare_mqtt_agent_init] */
+ +
288 const MQTTAgentMessageInterface_t * pMsgInterface,
+
289 const MQTTFixedBuffer_t * pNetworkBuffer,
+
290 const TransportInterface_t * pTransportInterface,
+
291 MQTTGetCurrentTimeFunc_t getCurrentTimeMs,
+
292 MQTTAgentIncomingPublishCallback_t incomingCallback,
+
293 void * pIncomingPacketContext );
+
294/* @[declare_mqtt_agent_init] */
+
295
+
336/* @[declare_mqtt_agent_commandloop] */
+ +
338/* @[declare_mqtt_agent_commandloop] */
+
339
+
377/* @[declare_mqtt_agent_resumesession] */
+ +
379 bool sessionPresent );
+
380/* @[declare_mqtt_agent_resumesession] */
+
381
+
416/* @[declare_mqtt_agent_cancelall] */
+ +
418/* @[declare_mqtt_agent_cancelall] */
+
419
+
475/* @[declare_mqtt_agent_subscribe] */
+
476MQTTStatus_t MQTTAgent_Subscribe( const MQTTAgentContext_t * pMqttAgentContext,
+
477 MQTTAgentSubscribeArgs_t * pSubscriptionArgs,
+
478 const MQTTAgentCommandInfo_t * pCommandInfo );
+
479/* @[declare_mqtt_agent_subscribe] */
+
480
+
535/* @[declare_mqtt_agent_unsubscribe] */
+
536MQTTStatus_t MQTTAgent_Unsubscribe( const MQTTAgentContext_t * pMqttAgentContext,
+
537 MQTTAgentSubscribeArgs_t * pSubscriptionArgs,
+
538 const MQTTAgentCommandInfo_t * pCommandInfo );
+
539/* @[declare_mqtt_agent_unsubscribe] */
+
540
+
595/* @[declare_mqtt_agent_publish] */
+
596MQTTStatus_t MQTTAgent_Publish( const MQTTAgentContext_t * pMqttAgentContext,
+
597 MQTTPublishInfo_t * pPublishInfo,
+
598 const MQTTAgentCommandInfo_t * pCommandInfo );
+
599/* @[declare_mqtt_agent_publish] */
+
600
+
646/* @[declare_mqtt_agent_processloop] */
+
647MQTTStatus_t MQTTAgent_ProcessLoop( const MQTTAgentContext_t * pMqttAgentContext,
+
648 const MQTTAgentCommandInfo_t * pCommandInfo );
+
649/* @[declare_mqtt_agent_processloop] */
+
650
+
702/* @[declare_mqtt_agent_ping] */
+
703MQTTStatus_t MQTTAgent_Ping( const MQTTAgentContext_t * pMqttAgentContext,
+
704 const MQTTAgentCommandInfo_t * pCommandInfo );
+
705/* @[declare_mqtt_agent_ping] */
+
706
+
795/* @[declare_mqtt_agent_connect] */
+
796MQTTStatus_t MQTTAgent_Connect( const MQTTAgentContext_t * pMqttAgentContext,
+
797 MQTTAgentConnectArgs_t * pConnectArgs,
+
798 const MQTTAgentCommandInfo_t * pCommandInfo );
+
799/* @[declare_mqtt_agent_connect] */
+
800
+
858/* @[declare_mqtt_agent_disconnect] */
+
859MQTTStatus_t MQTTAgent_Disconnect( const MQTTAgentContext_t * pMqttAgentContext,
+
860 const MQTTAgentCommandInfo_t * pCommandInfo );
+
861/* @[declare_mqtt_agent_disconnect] */
+
862
+
921/* @[declare_mqtt_agent_terminate] */
+
922MQTTStatus_t MQTTAgent_Terminate( const MQTTAgentContext_t * pMqttAgentContext,
+
923 const MQTTAgentCommandInfo_t * pCommandInfo );
+
924/* @[declare_mqtt_agent_terminate] */
+
925
+
926/* *INDENT-OFF* */
+
927#ifdef __cplusplus
+
928 }
+
929#endif
+
930/* *INDENT-ON* */
+
931
+
932#endif /* CORE_MQTT_AGENT_H */
+ +
MQTTStatus_t MQTTAgent_CancelAll(MQTTAgentContext_t *pMqttAgentContext)
Cancel all enqueued commands and those awaiting acknowledgment while the command loop is not running.
Definition: core_mqtt_agent.c:1128
+
MQTTStatus_t MQTTAgent_Disconnect(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to disconnect an MQTT connection.
Definition: core_mqtt_agent.c:1300
+
MQTTStatus_t MQTTAgent_Init(MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentMessageInterface_t *pMsgInterface, const MQTTFixedBuffer_t *pNetworkBuffer, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getCurrentTimeMs, MQTTAgentIncomingPublishCallback_t incomingCallback, void *pIncomingPacketContext)
Perform any initialization the MQTT agent requires before it can be used. Must be called before any o...
Definition: core_mqtt_agent.c:968
+
MQTTStatus_t MQTTAgent_Subscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Subscribe() for an MQTT connection.
Definition: core_mqtt_agent.c:1177
+
MQTTStatus_t MQTTAgent_ResumeSession(MQTTAgentContext_t *pMqttAgentContext, bool sessionPresent)
Resume a session by resending publishes if a session is present in the broker, or clear state informa...
Definition: core_mqtt_agent.c:1085
+
MQTTStatus_t MQTTAgent_Connect(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentConnectArgs_t *pConnectArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Connect() for an MQTT connection. If a session is resumed with the broker,...
Definition: core_mqtt_agent.c:1275
+
MQTTStatus_t MQTTAgent_CommandLoop(MQTTAgentContext_t *pMqttAgentContext)
Process commands from the command queue in a loop.
Definition: core_mqtt_agent.c:1043
+
MQTTStatus_t MQTTAgent_ProcessLoop(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Send a message to the MQTT agent purely to trigger an iteration of its loop, which will result in a c...
Definition: core_mqtt_agent.c:1252
+
MQTTStatus_t MQTTAgent_Unsubscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Unsubscribe() for an MQTT connection.
Definition: core_mqtt_agent.c:1202
+
MQTTStatus_t MQTTAgent_Terminate(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a termination command to the command queue.
Definition: core_mqtt_agent.c:1346
+
MQTTStatus_t MQTTAgent_Ping(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Ping() for an MQTT connection.
Definition: core_mqtt_agent.c:1323
+
MQTTStatus_t MQTTAgent_Publish(const MQTTAgentContext_t *pMqttAgentContext, MQTTPublishInfo_t *pPublishInfo, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Publish() for an MQTT connection.
Definition: core_mqtt_agent.c:1227
+
This represents the default values for the configuration macros for the MQTT-Agent library.
+
#define MQTT_AGENT_MAX_OUTSTANDING_ACKS
The maximum number of pending acknowledgments to track for a single connection.
Definition: core_mqtt_agent_config_defaults.h:82
+
Functions to interact with queues.
+ +
void(* MQTTAgentCommandCallback_t)(MQTTAgentCommandContext_t *pCmdCallbackContext, MQTTAgentReturnInfo_t *pReturnInfo)
Callback function called when a command completes.
Definition: core_mqtt_agent.h:101
+
void(* MQTTAgentIncomingPublishCallback_t)(struct MQTTAgentContext *pMqttAgentContext, uint16_t packetId, MQTTPublishInfo_t *pPublishInfo)
Callback function called when receiving a publish.
Definition: core_mqtt_agent.h:142
+
MQTTAgentCommandType_t
A type of command for interacting with the MQTT API.
Definition: core_mqtt_agent.h:50
+
@ NUM_COMMANDS
The number of command types handled by the agent.
Definition: core_mqtt_agent.h:60
+
@ CONNECT
Call MQTT_Connect().
Definition: core_mqtt_agent.h:57
+
@ DISCONNECT
Call MQTT_Disconnect().
Definition: core_mqtt_agent.h:58
+
@ PING
Call MQTT_Ping().
Definition: core_mqtt_agent.h:56
+
@ UNSUBSCRIBE
Call MQTT_Unsubscribe().
Definition: core_mqtt_agent.h:55
+
@ PROCESSLOOP
Call MQTT_ProcessLoop().
Definition: core_mqtt_agent.h:52
+
@ TERMINATE
Exit the command loop and stop processing commands.
Definition: core_mqtt_agent.h:59
+
@ SUBSCRIBE
Call MQTT_Subscribe().
Definition: core_mqtt_agent.h:54
+
@ PUBLISH
Call MQTT_Publish().
Definition: core_mqtt_agent.h:53
+
@ NONE
No command received. Must be zero (its memset() value).
Definition: core_mqtt_agent.h:51
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
MQTTStatus_t
+
Information for a pending MQTT ack packet expected by the agent.
Definition: core_mqtt_agent.h:123
+
MQTTAgentCommand_t * pOriginalCommand
Definition: core_mqtt_agent.h:125
+
uint16_t packetId
Definition: core_mqtt_agent.h:124
+
The commands sent from the APIs to the MQTT agent task.
Definition: core_mqtt_agent.h:111
+
void * pArgs
Arguments of command.
Definition: core_mqtt_agent.h:113
+
MQTTAgentCommandCallback_t pCommandCompleteCallback
Callback to invoke upon completion.
Definition: core_mqtt_agent.h:114
+
MQTTAgentCommandContext_t * pCmdContext
Context for completion callback.
Definition: core_mqtt_agent.h:115
+
MQTTAgentCommandType_t commandType
Type of command.
Definition: core_mqtt_agent.h:112
+
Struct holding arguments that are common to every command.
Definition: core_mqtt_agent.h:189
+
MQTTAgentCommandContext_t * pCmdCompleteCallbackContext
Context for completion callback.
Definition: core_mqtt_agent.h:191
+
MQTTAgentCommandCallback_t cmdCompleteCallback
Callback to invoke upon completion.
Definition: core_mqtt_agent.h:190
+
uint32_t blockTimeMs
Maximum block time for enqueueing the command.
Definition: core_mqtt_agent.h:192
+
Struct holding arguments for a CONNECT call.
Definition: core_mqtt_agent.h:177
+
bool sessionPresent
Output flag set if a previous session was present.
Definition: core_mqtt_agent.h:181
+
MQTTPublishInfo_t * pWillInfo
Optional Last Will and Testament.
Definition: core_mqtt_agent.h:179
+
uint32_t timeoutMs
Maximum timeout for a CONNACK packet.
Definition: core_mqtt_agent.h:180
+
MQTTConnectInfo_t * pConnectInfo
MQTT CONNECT packet information.
Definition: core_mqtt_agent.h:178
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+
void * pIncomingCallbackContext
Definition: core_mqtt_agent.h:158
+
MQTTAgentIncomingPublishCallback_t pIncomingCallback
Definition: core_mqtt_agent.h:157
+
MQTTAgentMessageInterface_t agentInterface
Definition: core_mqtt_agent.h:155
+
MQTTContext_t mqttContext
Definition: core_mqtt_agent.h:154
+
bool packetReceivedInLoop
Definition: core_mqtt_agent.h:159
+
Function pointers and contexts used for sending and receiving commands, and allocating memory for the...
Definition: core_mqtt_agent_message_interface.h:133
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+
MQTTStatus_t returnCode
Definition: core_mqtt_agent.h:72
+
uint8_t * pSubackCodes
Definition: core_mqtt_agent.h:73
+
Struct holding arguments for a SUBSCRIBE or UNSUBSCRIBE call.
Definition: core_mqtt_agent.h:167
+
MQTTSubscribeInfo_t * pSubscribeInfo
List of MQTT subscriptions.
Definition: core_mqtt_agent.h:168
+
size_t numSubscriptions
Number of elements in pSubscribeInfo.
Definition: core_mqtt_agent.h:169
+ + + + + + +
+
+ + + + diff --git a/v1.3.0/core__mqtt__agent__command__functions_8c.html b/v1.3.0/core__mqtt__agent__command__functions_8c.html new file mode 100644 index 00000000..f90b7e54 --- /dev/null +++ b/v1.3.0/core__mqtt__agent__command__functions_8c.html @@ -0,0 +1,540 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent_command_functions.c File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_agent_command_functions.c File Reference
+
+
+ +

Implements functions to process MQTT agent commands. +More...

+
#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include "core_mqtt_agent.h"
+#include "core_mqtt_agent_command_functions.h"
+#include "core_mqtt_agent_default_logging.h"
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

MQTTStatus_t MQTTAgentCommand_ProcessLoop (MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a NONE command. This function does not call MQTT_ProcessLoop itself, but instead sets a flag to indicate it should be called.
 
MQTTStatus_t MQTTAgentCommand_Publish (MQTTAgentContext_t *pMqttAgentContext, void *pPublishArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a PUBLISH command.
 
MQTTStatus_t MQTTAgentCommand_Subscribe (MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a SUBSCRIBE command.
 
MQTTStatus_t MQTTAgentCommand_Unsubscribe (MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for an UNSUBSCRIBE command.
 
MQTTStatus_t MQTTAgentCommand_Connect (MQTTAgentContext_t *pMqttAgentContext, void *pVoidConnectArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a CONNECT command.
 
MQTTStatus_t MQTTAgentCommand_Disconnect (MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a DISCONNECT command.
 
MQTTStatus_t MQTTAgentCommand_Ping (MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a PING command.
 
MQTTStatus_t MQTTAgentCommand_Terminate (MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a TERMINATE command. Calls MQTTAgent_CancelAll to terminate all unfinished commands with MQTTRecvFailed.
 
+

Detailed Description

+

Implements functions to process MQTT agent commands.

+

Function Documentation

+ +

◆ MQTTAgentCommand_ProcessLoop()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_ProcessLoop (MQTTAgentContext_tpMqttAgentContext,
void * pUnusedArg,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a NONE command. This function does not call MQTT_ProcessLoop itself, but instead sets a flag to indicate it should be called.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pUnusedArgUnused NULL argument.
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
MQTTSuccess.
+ +
+
+ +

◆ MQTTAgentCommand_Publish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Publish (MQTTAgentContext_tpMqttAgentContext,
void * pPublishArg,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a PUBLISH command.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pPublishArgPublish information for MQTT_Publish().
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Publish().
+ +
+
+ +

◆ MQTTAgentCommand_Subscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Subscribe (MQTTAgentContext_tpMqttAgentContext,
void * pVoidSubscribeArgs,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a SUBSCRIBE command.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pVoidSubscribeArgsArguments for MQTT_Subscribe().
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Subscribe().
+ +
+
+ +

◆ MQTTAgentCommand_Unsubscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Unsubscribe (MQTTAgentContext_tpMqttAgentContext,
void * pVoidSubscribeArgs,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for an UNSUBSCRIBE command.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pVoidSubscribeArgsArguments for MQTT_Unsubscribe().
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Unsubscribe().
+ +
+
+ +

◆ MQTTAgentCommand_Connect()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Connect (MQTTAgentContext_tpMqttAgentContext,
void * pVoidConnectArgs,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a CONNECT command.

+

This sets all return flags to false.

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pVoidConnectArgsArguments for MQTT_Connect().
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Connect().
+ +
+
+ +

◆ MQTTAgentCommand_Disconnect()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Disconnect (MQTTAgentContext_tpMqttAgentContext,
void * pUnusedArg,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a DISCONNECT command.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pUnusedArgUnused NULL argument.
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Disconnect().
+ +
+
+ +

◆ MQTTAgentCommand_Ping()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Ping (MQTTAgentContext_tpMqttAgentContext,
void * pUnusedArg,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a PING command.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pUnusedArgUnused NULL argument.
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Ping().
+ +
+
+ +

◆ MQTTAgentCommand_Terminate()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Terminate (MQTTAgentContext_tpMqttAgentContext,
void * pUnusedArg,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a TERMINATE command. Calls MQTTAgent_CancelAll to terminate all unfinished commands with MQTTRecvFailed.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pUnusedArgUnused NULL argument.
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
MQTTSuccess.
+ +
+
+
+
+ + + + diff --git a/v1.3.0/core__mqtt__agent__command__functions_8h.html b/v1.3.0/core__mqtt__agent__command__functions_8h.html new file mode 100644 index 00000000..70c52323 --- /dev/null +++ b/v1.3.0/core__mqtt__agent__command__functions_8h.html @@ -0,0 +1,642 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent_command_functions.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_agent_command_functions.h File Reference
+
+
+ +

Functions for processing an MQTT agent command. +More...

+
#include "core_mqtt_agent.h"
+
+

Go to the source code of this file.

+ + + + + +

+Data Structures

struct  MQTTAgentCommandFuncReturns_t
 A structure of values and flags expected to be returned by command functions. More...
 
+ + + + +

+Macros

#define MQTT_AGENT_FUNCTION_TABLE
 An array of function pointers mapping command types to a function to execute. Configurable to allow a linker to remove unneeded functions.
 
+ + + + +

+Typedefs

typedef MQTTStatus_t(* MQTTAgentCommandFunc_t) (MQTTAgentContext_t *pMqttAgentContext, void *pArgs, MQTTAgentCommandFuncReturns_t *pFlags)
 Function prototype for a command.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

MQTTStatus_t MQTTAgentCommand_ProcessLoop (MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a NONE command. This function does not call MQTT_ProcessLoop itself, but instead sets a flag to indicate it should be called.
 
MQTTStatus_t MQTTAgentCommand_Publish (MQTTAgentContext_t *pMqttAgentContext, void *pPublishArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a PUBLISH command.
 
MQTTStatus_t MQTTAgentCommand_Subscribe (MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a SUBSCRIBE command.
 
MQTTStatus_t MQTTAgentCommand_Unsubscribe (MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for an UNSUBSCRIBE command.
 
MQTTStatus_t MQTTAgentCommand_Connect (MQTTAgentContext_t *pMqttAgentContext, void *pVoidConnectArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a CONNECT command.
 
MQTTStatus_t MQTTAgentCommand_Disconnect (MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a DISCONNECT command.
 
MQTTStatus_t MQTTAgentCommand_Ping (MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a PING command.
 
MQTTStatus_t MQTTAgentCommand_Terminate (MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
 Function to execute for a TERMINATE command. Calls MQTTAgent_CancelAll to terminate all unfinished commands with MQTTRecvFailed.
 
+

Detailed Description

+

Functions for processing an MQTT agent command.

+

Macro Definition Documentation

+ +

◆ MQTT_AGENT_FUNCTION_TABLE

+ +
+
+ + + + +
#define MQTT_AGENT_FUNCTION_TABLE
+
+Value:
{ \
+ + + + + + + + + +
}
+
MQTTStatus_t MQTTAgentCommand_Publish(MQTTAgentContext_t *pMqttAgentContext, void *pPublishArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a PUBLISH command.
Definition: core_mqtt_agent_command_functions.c:60
+
MQTTStatus_t MQTTAgentCommand_Ping(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a PING command.
Definition: core_mqtt_agent_command_functions.c:202
+
MQTTStatus_t MQTTAgentCommand_Terminate(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a TERMINATE command. Calls MQTTAgent_CancelAll to terminate all unfinished co...
Definition: core_mqtt_agent_command_functions.c:224
+
MQTTStatus_t MQTTAgentCommand_Disconnect(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a DISCONNECT command.
Definition: core_mqtt_agent_command_functions.c:181
+
MQTTStatus_t MQTTAgentCommand_Connect(MQTTAgentContext_t *pMqttAgentContext, void *pVoidConnectArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a CONNECT command.
Definition: core_mqtt_agent_command_functions.c:147
+
MQTTStatus_t MQTTAgentCommand_Subscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a SUBSCRIBE command.
Definition: core_mqtt_agent_command_functions.c:91
+
MQTTStatus_t MQTTAgentCommand_ProcessLoop(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a NONE command. This function does not call MQTT_ProcessLoop itself,...
Definition: core_mqtt_agent_command_functions.c:44
+
MQTTStatus_t MQTTAgentCommand_Unsubscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for an UNSUBSCRIBE command.
Definition: core_mqtt_agent_command_functions.c:119
+
+

An array of function pointers mapping command types to a function to execute. Configurable to allow a linker to remove unneeded functions.

+
Note
This array controls the behavior of each command. Altering the array would allow a linker to discard unused MQTT functions if desired. The size of this array MUST equal NUM_COMMANDS and the order MUST correspond to MQTTAgentCommandType_t commands if not using C99 designated initializers. If any function is desired not to be linked, it may be set to MQTTAgentCommand_ProcessLoop or a custom function matching an MQTTAgentCommandFunc_t prototype.
+

Default value:

{
+ + + + + + + + + +
}
+
@ CONNECT
Call MQTT_Connect().
Definition: core_mqtt_agent.h:57
+
@ DISCONNECT
Call MQTT_Disconnect().
Definition: core_mqtt_agent.h:58
+
@ PING
Call MQTT_Ping().
Definition: core_mqtt_agent.h:56
+
@ UNSUBSCRIBE
Call MQTT_Unsubscribe().
Definition: core_mqtt_agent.h:55
+
@ PROCESSLOOP
Call MQTT_ProcessLoop().
Definition: core_mqtt_agent.h:52
+
@ TERMINATE
Exit the command loop and stop processing commands.
Definition: core_mqtt_agent.h:59
+
@ SUBSCRIBE
Call MQTT_Subscribe().
Definition: core_mqtt_agent.h:54
+
@ PUBLISH
Call MQTT_Publish().
Definition: core_mqtt_agent.h:53
+
@ NONE
No command received. Must be zero (its memset() value).
Definition: core_mqtt_agent.h:51
+
+
+
+

Typedef Documentation

+ +

◆ MQTTAgentCommandFunc_t

+ +
+
+ + + + +
typedef MQTTStatus_t(* MQTTAgentCommandFunc_t) (MQTTAgentContext_t *pMqttAgentContext, void *pArgs, MQTTAgentCommandFuncReturns_t *pFlags)
+
+ +

Function prototype for a command.

+
Note
These functions should only be called from within MQTTAgent_CommandLoop.
+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context.
[in]pArgsArguments for the command.
[out]pFlagsReturn flags set by the function.
+
+
+
Returns
Return code of MQTT call.
+ +
+
+

Function Documentation

+ +

◆ MQTTAgentCommand_ProcessLoop()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_ProcessLoop (MQTTAgentContext_tpMqttAgentContext,
void * pUnusedArg,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a NONE command. This function does not call MQTT_ProcessLoop itself, but instead sets a flag to indicate it should be called.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pUnusedArgUnused NULL argument.
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
MQTTSuccess.
+ +
+
+ +

◆ MQTTAgentCommand_Publish()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Publish (MQTTAgentContext_tpMqttAgentContext,
void * pPublishArg,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a PUBLISH command.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pPublishArgPublish information for MQTT_Publish().
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Publish().
+ +
+
+ +

◆ MQTTAgentCommand_Subscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Subscribe (MQTTAgentContext_tpMqttAgentContext,
void * pVoidSubscribeArgs,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a SUBSCRIBE command.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pVoidSubscribeArgsArguments for MQTT_Subscribe().
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Subscribe().
+ +
+
+ +

◆ MQTTAgentCommand_Unsubscribe()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Unsubscribe (MQTTAgentContext_tpMqttAgentContext,
void * pVoidSubscribeArgs,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for an UNSUBSCRIBE command.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pVoidSubscribeArgsArguments for MQTT_Unsubscribe().
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Unsubscribe().
+ +
+
+ +

◆ MQTTAgentCommand_Connect()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Connect (MQTTAgentContext_tpMqttAgentContext,
void * pVoidConnectArgs,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a CONNECT command.

+

This sets all return flags to false.

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pVoidConnectArgsArguments for MQTT_Connect().
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Connect().
+ +
+
+ +

◆ MQTTAgentCommand_Disconnect()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Disconnect (MQTTAgentContext_tpMqttAgentContext,
void * pUnusedArg,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a DISCONNECT command.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pUnusedArgUnused NULL argument.
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Disconnect().
+ +
+
+ +

◆ MQTTAgentCommand_Ping()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Ping (MQTTAgentContext_tpMqttAgentContext,
void * pUnusedArg,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a PING command.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pUnusedArgUnused NULL argument.
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
Status code of MQTT_Ping().
+ +
+
+ +

◆ MQTTAgentCommand_Terminate()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
MQTTStatus_t MQTTAgentCommand_Terminate (MQTTAgentContext_tpMqttAgentContext,
void * pUnusedArg,
MQTTAgentCommandFuncReturns_tpReturnFlags 
)
+
+ +

Function to execute for a TERMINATE command. Calls MQTTAgent_CancelAll to terminate all unfinished commands with MQTTRecvFailed.

+

This sets the following flags to true:

+
Parameters
+ + + + +
[in]pMqttAgentContextMQTT Agent context information.
[in]pUnusedArgUnused NULL argument.
[out]pReturnFlagsFlags set to indicate actions the MQTT agent should take.
+
+
+
Returns
MQTTSuccess.
+ +
+
+
+
+ + + + diff --git a/v1.3.0/core__mqtt__agent__command__functions_8h_source.html b/v1.3.0/core__mqtt__agent__command__functions_8h_source.html new file mode 100644 index 00000000..e7b6c96b --- /dev/null +++ b/v1.3.0/core__mqtt__agent__command__functions_8h_source.html @@ -0,0 +1,253 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent_command_functions.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
core_mqtt_agent_command_functions.h
+
+
+Go to the documentation of this file.
1/*
+
2 * coreMQTT Agent <v1.3.0>
+
3 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
4 *
+
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
+
6 * this software and associated documentation files (the "Software"), to deal in
+
7 * the Software without restriction, including without limitation the rights to
+
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
9 * the Software, and to permit persons to whom the Software is furnished to do so,
+
10 * subject to the following conditions:
+
11 *
+
12 * The above copyright notice and this permission notice shall be included in all
+
13 * copies or substantial portions of the Software.
+
14 *
+
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
21 */
+
22
+
27#ifndef CORE_MQTT_AGENT_COMMAND_FUNCTIONS_H
+
28#define CORE_MQTT_AGENT_COMMAND_FUNCTIONS_H
+
29
+
30/* *INDENT-OFF* */
+
31#ifdef __cplusplus
+
32 extern "C" {
+
33#endif
+
34/* *INDENT-ON* */
+
35
+
36/* MQTT Agent include. */
+
37#include "core_mqtt_agent.h"
+
38
+
64#ifndef MQTT_AGENT_FUNCTION_TABLE
+
65 /* Designated initializers are only in C99+. */
+
66 #if defined( __STDC_VERSION__ ) && ( __STDC_VERSION__ >= 199901L )
+
67 #define MQTT_AGENT_FUNCTION_TABLE \
+
68 { \
+
69 [ NONE ] = MQTTAgentCommand_ProcessLoop, \
+
70 [ PROCESSLOOP ] = MQTTAgentCommand_ProcessLoop, \
+
71 [ PUBLISH ] = MQTTAgentCommand_Publish, \
+
72 [ SUBSCRIBE ] = MQTTAgentCommand_Subscribe, \
+
73 [ UNSUBSCRIBE ] = MQTTAgentCommand_Unsubscribe, \
+
74 [ PING ] = MQTTAgentCommand_Ping, \
+
75 [ CONNECT ] = MQTTAgentCommand_Connect, \
+
76 [ DISCONNECT ] = MQTTAgentCommand_Disconnect, \
+
77 [ TERMINATE ] = MQTTAgentCommand_Terminate \
+
78 }
+
79 #else /* if defined( __STDC_VERSION__ ) && ( __STDC_VERSION__ >= 199901L ) */
+
80
+
81/* If not using designated initializers, this must correspond
+
82 * to the order of MQTTAgentCommandType_t commands. */
+
83 #define MQTT_AGENT_FUNCTION_TABLE \
+
84 { \
+
85 MQTTAgentCommand_ProcessLoop, \
+
86 MQTTAgentCommand_ProcessLoop, \
+
87 MQTTAgentCommand_Publish, \
+
88 MQTTAgentCommand_Subscribe, \
+
89 MQTTAgentCommand_Unsubscribe, \
+
90 MQTTAgentCommand_Ping, \
+
91 MQTTAgentCommand_Connect, \
+
92 MQTTAgentCommand_Disconnect, \
+
93 MQTTAgentCommand_Terminate \
+
94 }
+
95 #endif /* if defined( __STDC_VERSION__ ) && ( __STDC_VERSION__ >= 199901L ) */
+
96#endif /* ifndef MQTT_AGENT_FUNCTION_TABLE */
+
97
+
98/*-----------------------------------------------------------*/
+
99
+
105typedef struct MQTTAgentCommandFuncReturns
+
106{
+
107 uint16_t packetId;
+
108 bool endLoop;
+ + + +
112
+
125typedef MQTTStatus_t (* MQTTAgentCommandFunc_t ) ( MQTTAgentContext_t * pMqttAgentContext,
+
126 void * pArgs,
+ +
128
+
129/*-----------------------------------------------------------*/
+
130
+ +
145 void * pUnusedArg,
+
146 MQTTAgentCommandFuncReturns_t * pReturnFlags );
+
147
+ +
162 void * pPublishArg,
+
163 MQTTAgentCommandFuncReturns_t * pReturnFlags );
+
164
+ +
179 void * pVoidSubscribeArgs,
+
180 MQTTAgentCommandFuncReturns_t * pReturnFlags );
+
181
+ +
196 void * pVoidSubscribeArgs,
+
197 MQTTAgentCommandFuncReturns_t * pReturnFlags );
+
198
+ +
211 void * pVoidConnectArgs,
+
212 MQTTAgentCommandFuncReturns_t * pReturnFlags );
+
213
+ +
227 void * pUnusedArg,
+
228 MQTTAgentCommandFuncReturns_t * pReturnFlags );
+
229
+ +
243 void * pUnusedArg,
+
244 MQTTAgentCommandFuncReturns_t * pReturnFlags );
+
245
+ +
260 void * pUnusedArg,
+
261 MQTTAgentCommandFuncReturns_t * pReturnFlags );
+
262
+
263/* *INDENT-OFF* */
+
264#ifdef __cplusplus
+
265 }
+
266#endif
+
267/* *INDENT-ON* */
+
268
+
269#endif /* CORE_MQTT_AGENT_COMMAND_FUNCTIONS_H */
+
Functions for running a coreMQTT client in a dedicated thread.
+
MQTTStatus_t MQTTAgentCommand_Publish(MQTTAgentContext_t *pMqttAgentContext, void *pPublishArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a PUBLISH command.
Definition: core_mqtt_agent_command_functions.c:60
+
MQTTStatus_t MQTTAgentCommand_Ping(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a PING command.
Definition: core_mqtt_agent_command_functions.c:202
+
MQTTStatus_t MQTTAgentCommand_Terminate(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a TERMINATE command. Calls MQTTAgent_CancelAll to terminate all unfinished co...
Definition: core_mqtt_agent_command_functions.c:224
+
MQTTStatus_t MQTTAgentCommand_Disconnect(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a DISCONNECT command.
Definition: core_mqtt_agent_command_functions.c:181
+
MQTTStatus_t MQTTAgentCommand_Connect(MQTTAgentContext_t *pMqttAgentContext, void *pVoidConnectArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a CONNECT command.
Definition: core_mqtt_agent_command_functions.c:147
+
MQTTStatus_t MQTTAgentCommand_Subscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a SUBSCRIBE command.
Definition: core_mqtt_agent_command_functions.c:91
+
MQTTStatus_t MQTTAgentCommand_ProcessLoop(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a NONE command. This function does not call MQTT_ProcessLoop itself,...
Definition: core_mqtt_agent_command_functions.c:44
+
MQTTStatus_t MQTTAgentCommand_Unsubscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for an UNSUBSCRIBE command.
Definition: core_mqtt_agent_command_functions.c:119
+
MQTTStatus_t(* MQTTAgentCommandFunc_t)(MQTTAgentContext_t *pMqttAgentContext, void *pArgs, MQTTAgentCommandFuncReturns_t *pFlags)
Function prototype for a command.
Definition: core_mqtt_agent_command_functions.h:125
+
MQTTStatus_t
+
A structure of values and flags expected to be returned by command functions.
Definition: core_mqtt_agent_command_functions.h:106
+
bool addAcknowledgment
Flag to indicate an acknowledgment should be tracked.
Definition: core_mqtt_agent_command_functions.h:109
+
bool runProcessLoop
Flag to indicate MQTT_ProcessLoop() should be called after this command.
Definition: core_mqtt_agent_command_functions.h:110
+
uint16_t packetId
Packet ID of packet sent by command.
Definition: core_mqtt_agent_command_functions.h:107
+
bool endLoop
Flag to indicate command loop should terminate.
Definition: core_mqtt_agent_command_functions.h:108
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+
+
+ + + + diff --git a/v1.3.0/core__mqtt__agent__config__defaults_8h.html b/v1.3.0/core__mqtt__agent__config__defaults_8h.html new file mode 100644 index 00000000..fa87aec3 --- /dev/null +++ b/v1.3.0/core__mqtt__agent__config__defaults_8h.html @@ -0,0 +1,215 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent_config_defaults.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_agent_config_defaults.h File Reference
+
+
+ +

This represents the default values for the configuration macros for the MQTT-Agent library. +More...

+
#include "core_mqtt_agent_config.h"
+
+

Go to the source code of this file.

+ + + + + + + + + + + + + + +

+Macros

#define MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG
 Define this macro to build the MQTT library without the custom config file core_mqtt_agent_config.h.
 
#define MQTT_AGENT_MAX_OUTSTANDING_ACKS   ( 20U )
 The maximum number of pending acknowledgments to track for a single connection.
 
#define MQTT_AGENT_MAX_EVENT_QUEUE_WAIT_TIME   ( 1000U )
 Time in milliseconds that the MQTT agent task will wait in the Blocked state (so not using any CPU time) for a command to arrive in its command queue before exiting the blocked state so it can call MQTT_ProcessLoop().
 
#define MQTT_AGENT_USE_QOS_1_2_PUBLISH   ( 1 )
 Whether the agent should configure the coreMQTT library to be used with publishes greater than QoS0. Setting this to 0 will disallow the coreMQTT library to send publishes with QoS > 0.
 
+

Detailed Description

+

This represents the default values for the configuration macros for the MQTT-Agent library.

+
Note
This file SHOULD NOT be modified. If custom values are needed for any configuration macro, a core_mqtt_agent_config.h file should be provided to the MQTT-Agent library to override the default values defined in this file. To use the custom config file, the MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG preprocessor macro SHOULD NOT be set.
+

Macro Definition Documentation

+ +

◆ MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG

+ +
+
+ + + + +
#define MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG
+
+ +

Define this macro to build the MQTT library without the custom config file core_mqtt_agent_config.h.

+

Without the custom config, the MQTT library builds with default values of config macros defined in core_mqtt_agent_config_defaults.h file.

+

If a custom config is provided, then MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG should be defined.

+ +
+
+ +

◆ MQTT_AGENT_MAX_OUTSTANDING_ACKS

+ +
+
+ + + + +
#define MQTT_AGENT_MAX_OUTSTANDING_ACKS   ( 20U )
+
+ +

The maximum number of pending acknowledgments to track for a single connection.

+
Note
The MQTT agent tracks MQTT commands (such as PUBLISH and SUBSCRIBE) th at are still waiting to be acknowledged. MQTT_AGENT_MAX_OUTSTANDING_ACKS set the maximum number of acknowledgments that can be outstanding at any one time. The higher this number is the greater the agent's RAM consumption will be.
+

Possible values: Any positive integer up to SIZE_MAX.
+ Default value: 20

+ +
+
+ +

◆ MQTT_AGENT_MAX_EVENT_QUEUE_WAIT_TIME

+ +
+
+ + + + +
#define MQTT_AGENT_MAX_EVENT_QUEUE_WAIT_TIME   ( 1000U )
+
+ +

Time in milliseconds that the MQTT agent task will wait in the Blocked state (so not using any CPU time) for a command to arrive in its command queue before exiting the blocked state so it can call MQTT_ProcessLoop().

+
Note
It is important MQTT_ProcessLoop() is called often if there is known MQTT traffic, but calling it too often can take processing time away from lower priority tasks and waste CPU time and power.
+

Possible values: Any positive 32 bit integer.
+ Default value: 1000

+ +
+
+ +

◆ MQTT_AGENT_USE_QOS_1_2_PUBLISH

+ +
+
+ + + + +
#define MQTT_AGENT_USE_QOS_1_2_PUBLISH   ( 1 )
+
+ +

Whether the agent should configure the coreMQTT library to be used with publishes greater than QoS0. Setting this to 0 will disallow the coreMQTT library to send publishes with QoS > 0.

+

Possible values: 0 or 1
+ Default value: 1

+ +
+
+
+
+ + + + diff --git a/v1.3.0/core__mqtt__agent__config__defaults_8h_source.html b/v1.3.0/core__mqtt__agent__config__defaults_8h_source.html new file mode 100644 index 00000000..979e3745 --- /dev/null +++ b/v1.3.0/core__mqtt__agent__config__defaults_8h_source.html @@ -0,0 +1,178 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent_config_defaults.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
core_mqtt_agent_config_defaults.h
+
+
+Go to the documentation of this file.
1/*
+
2 * coreMQTT Agent <v1.3.0>
+
3 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
4 *
+
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
+
6 * this software and associated documentation files (the "Software"), to deal in
+
7 * the Software without restriction, including without limitation the rights to
+
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
9 * the Software, and to permit persons to whom the Software is furnished to do so,
+
10 * subject to the following conditions:
+
11 *
+
12 * The above copyright notice and this permission notice shall be included in all
+
13 * copies or substantial portions of the Software.
+
14 *
+
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
21 */
+
22
+
35#ifndef CORE_MQTT_AGENT_CONFIG_DEFAULTS_H_
+
36#define CORE_MQTT_AGENT_CONFIG_DEFAULTS_H_
+
37
+
38/* *INDENT-OFF* */
+
39#ifdef __cplusplus
+
40 extern "C" {
+
41#endif
+
42/* *INDENT-ON* */
+
43
+
44/* MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG allows building the MQTT library
+
45 * without a custom config. If a custom config is provided, the
+
46 * MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG macro should be defined. */
+
47#ifndef MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG
+
48 /* Include custom config file before other headers. */
+
49 #include "core_mqtt_agent_config.h"
+
50#endif
+
51
+
52/* The macro definition for MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG is for Doxygen
+
53 * documentation only. */
+
54
+
65#ifdef DOXYGEN
+
66 #define MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG
+
67#endif
+
68
+
81#ifndef MQTT_AGENT_MAX_OUTSTANDING_ACKS
+
82 #define MQTT_AGENT_MAX_OUTSTANDING_ACKS ( 20U )
+
83#endif
+
84
+
97#ifndef MQTT_AGENT_MAX_EVENT_QUEUE_WAIT_TIME
+
98 #define MQTT_AGENT_MAX_EVENT_QUEUE_WAIT_TIME ( 1000U )
+
99#endif
+
100
+
109#ifndef MQTT_AGENT_USE_QOS_1_2_PUBLISH
+
110 #define MQTT_AGENT_USE_QOS_1_2_PUBLISH ( 1 )
+
111#endif
+
112
+
113/* *INDENT-OFF* */
+
114#ifdef __cplusplus
+
115 }
+
116#endif
+
117/* *INDENT-ON* */
+
118
+
119#endif /* ifndef CORE_MQTT_AGENT_CONFIG_DEFAULTS_H_ */
+
+
+ + + + diff --git a/v1.3.0/core__mqtt__agent__default__logging_8h.html b/v1.3.0/core__mqtt__agent__default__logging_8h.html new file mode 100644 index 00000000..3c99760e --- /dev/null +++ b/v1.3.0/core__mqtt__agent__default__logging_8h.html @@ -0,0 +1,232 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent_default_logging.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_agent_default_logging.h File Reference
+
+
+ +

This represents the default values for the logging macros for the MQTT-Agent library. +More...

+ +

Go to the source code of this file.

+ + + + + + + + + + + + + + +

+Macros

#define LogError(message)
 Macro that is called in the MQTT-Agent library for logging "Error" level messages.
 
#define LogWarn(message)
 Macro that is called in the MQTT-Agent library for logging "Warning" level messages.
 
#define LogInfo(message)
 Macro that is called in the MQTT-Agent library for logging "Info" level messages.
 
#define LogDebug(message)
 Macro that is called in the MQTT-Agent library for logging "Debug" level messages.
 
+

Detailed Description

+

This represents the default values for the logging macros for the MQTT-Agent library.

+
Note
This file SHOULD NOT be modified. If custom values are needed for any configuration macro, a core_mqtt_agent_config.h file should be provided to the MQTT-Agent library to override the default values defined in this file. To use the custom config file, the MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG preprocessor macro SHOULD NOT be set.
+

Macro Definition Documentation

+ +

◆ LogError

+ +
+
+ + + + + + + + +
#define LogError( message)
+
+ +

Macro that is called in the MQTT-Agent library for logging "Error" level messages.

+

To enable error level logging in the MQTT-Agent library, this macro should be mapped to the application-specific logging implementation that supports error logging.

+
Note
This logging macro is called in the MQTT-Agent library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Error logging is turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+ +
+
+ +

◆ LogWarn

+ +
+
+ + + + + + + + +
#define LogWarn( message)
+
+ +

Macro that is called in the MQTT-Agent library for logging "Warning" level messages.

+

To enable warning level logging in the MQTT-Agent library, this macro should be mapped to the application-specific logging implementation that supports warning logging.

+
Note
This logging macro is called in the MQTT-Agent library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Warning logs are turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+ +
+
+ +

◆ LogInfo

+ +
+
+ + + + + + + + +
#define LogInfo( message)
+
+ +

Macro that is called in the MQTT-Agent library for logging "Info" level messages.

+

To enable info level logging in the MQTT-Agent library, this macro should be mapped to the application-specific logging implementation that supports info logging.

+
Note
This logging macro is called in the MQTT-Agent library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Info logging is turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+ +
+
+ +

◆ LogDebug

+ +
+
+ + + + + + + + +
#define LogDebug( message)
+
+ +

Macro that is called in the MQTT-Agent library for logging "Debug" level messages.

+

To enable debug level logging from MQTT-Agent library, this macro should be mapped to the application-specific logging implementation that supports debug logging.

+
Note
This logging macro is called in the MQTT-Agent library with parameters wrapped in double parentheses to be ISO C89/C90 standard compliant. For a reference POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the logging-stack in demos folder of the AWS IoT Embedded C SDK repository.
+

Default value: Debug logging is turned off, and no code is generated for calls to the macro in the MQTT library on compilation.

+ +
+
+
+
+ + + + diff --git a/v1.3.0/core__mqtt__agent__default__logging_8h_source.html b/v1.3.0/core__mqtt__agent__default__logging_8h_source.html new file mode 100644 index 00000000..4587cd97 --- /dev/null +++ b/v1.3.0/core__mqtt__agent__default__logging_8h_source.html @@ -0,0 +1,167 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent_default_logging.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
core_mqtt_agent_default_logging.h
+
+
+Go to the documentation of this file.
1/*
+
2 * coreMQTT Agent <v1.3.0>
+
3 * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
4 *
+
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
+
6 * this software and associated documentation files (the "Software"), to deal in
+
7 * the Software without restriction, including without limitation the rights to
+
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
9 * the Software, and to permit persons to whom the Software is furnished to do so,
+
10 * subject to the following conditions:
+
11 *
+
12 * The above copyright notice and this permission notice shall be included in all
+
13 * copies or substantial portions of the Software.
+
14 *
+
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
21 */
+
22
+
35#ifndef CORE_MQTT_AGENT_DEFAULT_LOGGING_H_
+
36#define CORE_MQTT_AGENT_DEFAULT_LOGGING_H_
+
37
+
38/* *INDENT-OFF* */
+
39#ifdef __cplusplus
+
40 extern "C" {
+
41#endif
+
42/* *INDENT-ON* */
+
43
+
60#ifndef LogError
+
61 #define LogError( message )
+
62#endif
+
63
+
79#ifndef LogWarn
+
80 #define LogWarn( message )
+
81#endif
+
82
+
99#ifndef LogInfo
+
100 #define LogInfo( message )
+
101#endif
+
102
+
119#ifndef LogDebug
+
120 #define LogDebug( message )
+
121#endif
+
122
+
123/* *INDENT-OFF* */
+
124#ifdef __cplusplus
+
125 }
+
126#endif
+
127/* *INDENT-ON* */
+
128
+
129#endif /* ifndef CORE_MQTT_AGENT_DEFAULT_LOGGING_H_ */
+
+
+ + + + diff --git a/v1.3.0/core__mqtt__agent__message__interface_8h.html b/v1.3.0/core__mqtt__agent__message__interface_8h.html new file mode 100644 index 00000000..a229aae6 --- /dev/null +++ b/v1.3.0/core__mqtt__agent__message__interface_8h.html @@ -0,0 +1,251 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent_message_interface.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
core_mqtt_agent_message_interface.h File Reference
+
+
+ +

Functions to interact with queues. +More...

+
#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+

Go to the source code of this file.

+ + + + + +

+Data Structures

struct  MQTTAgentMessageInterface_t
 Function pointers and contexts used for sending and receiving commands, and allocating memory for them. More...
 
+ + + + + + + + + + + + + + + + +

+Typedefs

+typedef struct MQTTAgentMessageContext MQTTAgentMessageContext_t
 Context with which tasks may deliver messages to the agent.
 
typedef bool(* MQTTAgentMessageSend_t) (MQTTAgentMessageContext_t *pMsgCtx, MQTTAgentCommand_t *const *pCommandToSend, uint32_t blockTimeMs)
 Send a message to the specified context. Must be thread safe.
 
typedef bool(* MQTTAgentMessageRecv_t) (MQTTAgentMessageContext_t *pMsgCtx, MQTTAgentCommand_t **pReceivedCommand, uint32_t blockTimeMs)
 Receive a message from the specified context. Must be thread safe.
 
typedef MQTTAgentCommand_t *(* MQTTAgentCommandGet_t) (uint32_t blockTimeMs)
 Obtain a MQTTAgentCommand_t structure.
 
typedef bool(* MQTTAgentCommandRelease_t) (MQTTAgentCommand_t *pCommandToRelease)
 Give a MQTTAgentCommand_t structure back to the application.
 
+

Detailed Description

+

Functions to interact with queues.

+

Typedef Documentation

+ +

◆ MQTTAgentMessageSend_t

+ +
+
+ + + + +
typedef bool(* MQTTAgentMessageSend_t) (MQTTAgentMessageContext_t *pMsgCtx, MQTTAgentCommand_t *const *pCommandToSend, uint32_t blockTimeMs)
+
+ +

Send a message to the specified context. Must be thread safe.

+
Parameters
+ + + + +
[in]pMsgCtxAn MQTTAgentMessageContext_t.
[in]pCommandToSendPointer to address to send to queue.
[in]blockTimeMsBlock time to wait for a send.
+
+
+
Returns
true if send was successful, else false.
+ +
+
+ +

◆ MQTTAgentMessageRecv_t

+ +
+
+ + + + +
typedef bool(* MQTTAgentMessageRecv_t) (MQTTAgentMessageContext_t *pMsgCtx, MQTTAgentCommand_t **pReceivedCommand, uint32_t blockTimeMs)
+
+ +

Receive a message from the specified context. Must be thread safe.

+
Parameters
+ + + + +
[in]pMsgCtxAn MQTTAgentMessageContext_t.
[out]pReceivedCommandPointer to write address of received command.
[in]blockTimeMsBlock time to wait for a receive.
+
+
+
Returns
true if receive was successful, else false.
+ +
+
+ +

◆ MQTTAgentCommandGet_t

+ +
+
+ + + + +
typedef MQTTAgentCommand_t *(* MQTTAgentCommandGet_t) (uint32_t blockTimeMs)
+
+ +

Obtain a MQTTAgentCommand_t structure.

+
Note
MQTTAgentCommand_t structures hold everything the MQTT agent needs to process a command that originates from application. Examples of commands are PUBLISH and SUBSCRIBE. The MQTTAgentCommand_t structure must persist for the duration of the command's operation.
+
Parameters
+ + +
[in]blockTimeMsThe length of time the calling task should remain in the Blocked state (so not consuming any CPU time) to wait for a MQTTAgentCommand_t structure to become available should one not be immediately at the time of the call.
+
+
+
Returns
A pointer to a MQTTAgentCommand_t structure if one becomes available before blockTimeMs time expired, otherwise NULL.
+ +
+
+ +

◆ MQTTAgentCommandRelease_t

+ +
+
+ + + + +
typedef bool(* MQTTAgentCommandRelease_t) (MQTTAgentCommand_t *pCommandToRelease)
+
+ +

Give a MQTTAgentCommand_t structure back to the application.

+
Note
MQTTAgentCommand_t structures hold everything the MQTT agent needs to process a command that originates from application. Examples of commands are PUBLISH and SUBSCRIBE. The MQTTAgentCommand_t structure must persist for the duration of the command's operation.
+
Parameters
+ + +
[in]pCommandToReleaseA pointer to the MQTTAgentCommand_t structure to return to the application. The structure must first have been obtained by calling an MQTTAgentCommandGet_t, otherwise it will have no effect.
+
+
+
Returns
true if the MQTTAgentCommand_t structure was returned to the application, otherwise false.
+ +
+
+
+
+ + + + diff --git a/v1.3.0/core__mqtt__agent__message__interface_8h_source.html b/v1.3.0/core__mqtt__agent__message__interface_8h_source.html new file mode 100644 index 00000000..3cfef118 --- /dev/null +++ b/v1.3.0/core__mqtt__agent__message__interface_8h_source.html @@ -0,0 +1,208 @@ + + + + + + + +coreMQTT Agent: core_mqtt_agent_message_interface.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
core_mqtt_agent_message_interface.h
+
+
+Go to the documentation of this file.
1/*
+
2 * coreMQTT Agent <v1.3.0>
+
3 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
4 *
+
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
+
6 * this software and associated documentation files (the "Software"), to deal in
+
7 * the Software without restriction, including without limitation the rights to
+
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
9 * the Software, and to permit persons to whom the Software is furnished to do so,
+
10 * subject to the following conditions:
+
11 *
+
12 * The above copyright notice and this permission notice shall be included in all
+
13 * copies or substantial portions of the Software.
+
14 *
+
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
21 */
+
22
+
27#ifndef CORE_MQTT_AGENT_MESSAGE_INTERFACE_H
+
28#define CORE_MQTT_AGENT_MESSAGE_INTERFACE_H
+
29
+
30#include <stddef.h>
+
31#include <stdint.h>
+
32#include <stdbool.h>
+
33
+
34/* *INDENT-OFF* */
+
35#ifdef __cplusplus
+
36 extern "C" {
+
37#endif
+
38/* *INDENT-ON* */
+
39
+
40/* Declare here so interface functions can use. */
+
41struct MQTTAgentCommand;
+
42struct MQTTAgentMessageContext;
+
43
+
47typedef struct MQTTAgentCommand MQTTAgentCommand_t;
+
48
+
53/* @[define_messagectx] */
+
54typedef struct MQTTAgentMessageContext MQTTAgentMessageContext_t;
+
55/* @[define_messagectx] */
+
56
+
67/* @[define_messagesend] */
+ +
69 MQTTAgentCommand_t * const * pCommandToSend,
+
70 uint32_t blockTimeMs );
+
71/* @[define_messagesend] */
+
72
+
83/* @[define_messagerecv] */
+ +
85 MQTTAgentCommand_t ** pReceivedCommand,
+
86 uint32_t blockTimeMs );
+
87/* @[define_messagerecv] */
+
88
+
104/* @[define_messageget] */
+
105typedef MQTTAgentCommand_t * ( * MQTTAgentCommandGet_t )( uint32_t blockTimeMs );
+
106/* @[define_messageget] */
+
107
+
122/* @[define_messagerelease] */
+
123typedef bool ( * MQTTAgentCommandRelease_t )( MQTTAgentCommand_t * pCommandToRelease );
+
124/* @[define_messagerelease] */
+
125
+
131/* @[define_messageinterface] */
+
132typedef struct MQTTAgentMessageInterface
+
133{
+ + + + + + +
140/* @[define_messageinterface] */
+
141
+
142/* *INDENT-OFF* */
+
143#ifdef __cplusplus
+
144 }
+
145#endif
+
146/* *INDENT-ON* */
+
147
+
148#endif /* CORE_MQTT_AGENT_MESSAGE_INTERFACE_H */
+
MQTTAgentCommand_t *(* MQTTAgentCommandGet_t)(uint32_t blockTimeMs)
Obtain a MQTTAgentCommand_t structure.
Definition: core_mqtt_agent_message_interface.h:105
+
bool(* MQTTAgentMessageSend_t)(MQTTAgentMessageContext_t *pMsgCtx, MQTTAgentCommand_t *const *pCommandToSend, uint32_t blockTimeMs)
Send a message to the specified context. Must be thread safe.
Definition: core_mqtt_agent_message_interface.h:68
+
bool(* MQTTAgentCommandRelease_t)(MQTTAgentCommand_t *pCommandToRelease)
Give a MQTTAgentCommand_t structure back to the application.
Definition: core_mqtt_agent_message_interface.h:123
+
bool(* MQTTAgentMessageRecv_t)(MQTTAgentMessageContext_t *pMsgCtx, MQTTAgentCommand_t **pReceivedCommand, uint32_t blockTimeMs)
Receive a message from the specified context. Must be thread safe.
Definition: core_mqtt_agent_message_interface.h:84
+
struct MQTTAgentMessageContext MQTTAgentMessageContext_t
Context with which tasks may deliver messages to the agent.
Definition: core_mqtt_agent_message_interface.h:54
+
The commands sent from the APIs to the MQTT agent task.
Definition: core_mqtt_agent.h:111
+
Function pointers and contexts used for sending and receiving commands, and allocating memory for the...
Definition: core_mqtt_agent_message_interface.h:133
+
MQTTAgentMessageContext_t * pMsgCtx
Definition: core_mqtt_agent_message_interface.h:134
+
MQTTAgentMessageRecv_t recv
Definition: core_mqtt_agent_message_interface.h:136
+
MQTTAgentCommandGet_t getCommand
Definition: core_mqtt_agent_message_interface.h:137
+
MQTTAgentMessageSend_t send
Definition: core_mqtt_agent_message_interface.h:135
+
MQTTAgentCommandRelease_t releaseCommand
Definition: core_mqtt_agent_message_interface.h:138
+
+
+ + + + diff --git a/v1.3.0/core_mqtt_agent_config.html b/v1.3.0/core_mqtt_agent_config.html new file mode 100644 index 00000000..590a0cf5 --- /dev/null +++ b/v1.3.0/core_mqtt_agent_config.html @@ -0,0 +1,160 @@ + + + + + + + +coreMQTT Agent: Configurations + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Configurations
+
+
+

Configurations of the MQTT Agent.

+
configpagestyle
+

Configuration settings are C preprocessor constants. They can be set with a #define in the config file (core_mqtt_config.h) or by using a compiler option such as -D in gcc. The MQTT Agent uses the same configuration file as coreMQTT.

+

+MQTT_AGENT_MAX_OUTSTANDING_ACKS

+

The maximum number of pending acknowledgments to track for a single connection.

+
Note
The MQTT agent tracks MQTT commands (such as PUBLISH and SUBSCRIBE) th at are still waiting to be acknowledged. MQTT_AGENT_MAX_OUTSTANDING_ACKS set the maximum number of acknowledgments that can be outstanding at any one time. The higher this number is the greater the agent's RAM consumption will be.
+

Possible values: Any positive integer up to SIZE_MAX.
+ Default value: 20

+

+MQTT_AGENT_MAX_EVENT_QUEUE_WAIT_TIME

+

Time in milliseconds that the MQTT agent task will wait in the Blocked state (so not using any CPU time) for a command to arrive in its command queue before exiting the blocked state so it can call MQTT_ProcessLoop().

+
Note
It is important MQTT_ProcessLoop() is called often if there is known MQTT traffic, but calling it too often can take processing time away from lower priority tasks and waste CPU time and power.
+

Possible values: Any positive 32 bit integer.
+ Default value: 1000

+

+MQTT_AGENT_FUNCTION_TABLE

+

An array of function pointers mapping command types to a function to execute. Configurable to allow a linker to remove unneeded functions.

+
Note
This array controls the behavior of each command. Altering the array would allow a linker to discard unused MQTT functions if desired. The size of this array MUST equal NUM_COMMANDS and the order MUST correspond to MQTTAgentCommandType_t commands if not using C99 designated initializers. If any function is desired not to be linked, it may be set to MQTTAgentCommand_ProcessLoop or a custom function matching an MQTTAgentCommandFunc_t prototype.
+

Default value:

{
+ + + + + + + + + +
}
+
MQTTStatus_t MQTTAgentCommand_Publish(MQTTAgentContext_t *pMqttAgentContext, void *pPublishArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a PUBLISH command.
Definition: core_mqtt_agent_command_functions.c:60
+
MQTTStatus_t MQTTAgentCommand_Ping(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a PING command.
Definition: core_mqtt_agent_command_functions.c:202
+
MQTTStatus_t MQTTAgentCommand_Terminate(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a TERMINATE command. Calls MQTTAgent_CancelAll to terminate all unfinished co...
Definition: core_mqtt_agent_command_functions.c:224
+
MQTTStatus_t MQTTAgentCommand_Disconnect(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a DISCONNECT command.
Definition: core_mqtt_agent_command_functions.c:181
+
MQTTStatus_t MQTTAgentCommand_Connect(MQTTAgentContext_t *pMqttAgentContext, void *pVoidConnectArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a CONNECT command.
Definition: core_mqtt_agent_command_functions.c:147
+
MQTTStatus_t MQTTAgentCommand_Subscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a SUBSCRIBE command.
Definition: core_mqtt_agent_command_functions.c:91
+
MQTTStatus_t MQTTAgentCommand_ProcessLoop(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for a NONE command. This function does not call MQTT_ProcessLoop itself,...
Definition: core_mqtt_agent_command_functions.c:44
+
MQTTStatus_t MQTTAgentCommand_Unsubscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags)
Function to execute for an UNSUBSCRIBE command.
Definition: core_mqtt_agent_command_functions.c:119
+
@ CONNECT
Call MQTT_Connect().
Definition: core_mqtt_agent.h:57
+
@ DISCONNECT
Call MQTT_Disconnect().
Definition: core_mqtt_agent.h:58
+
@ PING
Call MQTT_Ping().
Definition: core_mqtt_agent.h:56
+
@ UNSUBSCRIBE
Call MQTT_Unsubscribe().
Definition: core_mqtt_agent.h:55
+
@ PROCESSLOOP
Call MQTT_ProcessLoop().
Definition: core_mqtt_agent.h:52
+
@ TERMINATE
Exit the command loop and stop processing commands.
Definition: core_mqtt_agent.h:59
+
@ SUBSCRIBE
Call MQTT_Subscribe().
Definition: core_mqtt_agent.h:54
+
@ PUBLISH
Call MQTT_Publish().
Definition: core_mqtt_agent.h:53
+
@ NONE
No command received. Must be zero (its memset() value).
Definition: core_mqtt_agent.h:51
+
+
+
+ + + + diff --git a/v1.3.0/dir_359d2bec989c9a8deeeb9aee335c1c76.html b/v1.3.0/dir_359d2bec989c9a8deeeb9aee335c1c76.html new file mode 100644 index 00000000..cc63484a --- /dev/null +++ b/v1.3.0/dir_359d2bec989c9a8deeeb9aee335c1c76.html @@ -0,0 +1,113 @@ + + + + + + + +coreMQTT Agent: doxygen Directory Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
doxygen Directory Reference
+
+
+
+
+ + + + diff --git a/v1.3.0/dir_49e56c817e5e54854c35e136979f97ca.html b/v1.3.0/dir_49e56c817e5e54854c35e136979f97ca.html new file mode 100644 index 00000000..f60286c9 --- /dev/null +++ b/v1.3.0/dir_49e56c817e5e54854c35e136979f97ca.html @@ -0,0 +1,113 @@ + + + + + + + +coreMQTT Agent: docs Directory Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
docs Directory Reference
+
+
+
+
+ + + + diff --git a/v1.3.0/dir_8ee1a5e78eaec319fe5d64075812fc61.html b/v1.3.0/dir_8ee1a5e78eaec319fe5d64075812fc61.html new file mode 100644 index 00000000..e8e30ee7 --- /dev/null +++ b/v1.3.0/dir_8ee1a5e78eaec319fe5d64075812fc61.html @@ -0,0 +1,132 @@ + + + + + + + +coreMQTT Agent: include Directory Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
include Directory Reference
+
+
+ + + + + + + + + + + + + + + + + +

+Files

file  core_mqtt_agent.h [code]
 Functions for running a coreMQTT client in a dedicated thread.
 
file  core_mqtt_agent_command_functions.h [code]
 Functions for processing an MQTT agent command.
 
file  core_mqtt_agent_config_defaults.h [code]
 This represents the default values for the configuration macros for the MQTT-Agent library.
 
file  core_mqtt_agent_default_logging.h [code]
 This represents the default values for the logging macros for the MQTT-Agent library.
 
file  core_mqtt_agent_message_interface.h [code]
 Functions to interact with queues.
 
+
+
+ + + + diff --git a/v1.3.0/dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html b/v1.3.0/dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html new file mode 100644 index 00000000..b83ef156 --- /dev/null +++ b/v1.3.0/dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html @@ -0,0 +1,128 @@ + + + + + + + +coreMQTT Agent: source Directory Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
source Directory Reference
+
+
+ + + + +

+Directories

directory  include
 
+ + + + + + + +

+Files

file  core_mqtt_agent.c
 Implements an MQTT agent (or daemon task) to enable multithreaded access to coreMQTT.
 
file  core_mqtt_agent_command_functions.c
 Implements functions to process MQTT agent commands.
 
+
+
+ + + + diff --git a/v1.3.0/doc.png b/v1.3.0/doc.png new file mode 100644 index 0000000000000000000000000000000000000000..17edabff95f7b8da13c9516a04efe05493c29501 GIT binary patch literal 746 zcmV7=@pnbNXRFEm&G8P!&WHG=d)>K?YZ1bzou)2{$)) zumDct!>4SyxL;zgaG>wy`^Hv*+}0kUfCrz~BCOViSb$_*&;{TGGn2^x9K*!Sf0=lV zpP=7O;GA0*Jm*tTYj$IoXvimpnV4S1Z5f$p*f$Db2iq2zrVGQUz~yq`ahn7ck(|CE z7Gz;%OP~J6)tEZWDzjhL9h2hdfoU2)Nd%T<5Kt;Y0XLt&<@6pQx!nw*5`@bq#?l*?3z{Hlzoc=Pr>oB5(9i6~_&-}A(4{Q$>c>%rV&E|a(r&;?i5cQB=} zYSDU5nXG)NS4HEs0it2AHe2>shCyr7`6@4*6{r@8fXRbTA?=IFVWAQJL&H5H{)DpM#{W(GL+Idzf^)uRV@oB8u$ z8v{MfJbTiiRg4bza<41NAzrl{=3fl_D+$t+^!xlQ8S}{UtY`e z;;&9UhyZqQRN%2pot{*Ei0*4~hSF_3AH2@fKU!$NSflS>{@tZpDT4`M2WRTTVH+D? z)GFlEGGHe?koB}i|1w45!BF}N_q&^HJ&-tyR{(afC6H7|aml|tBBbv}55C5DNP8p3 z)~jLEO4Z&2hZmP^i-e%(@d!(E|KRafiU8Q5u(wU((j8un3OR*Hvj+t literal 0 HcmV?d00001 diff --git a/v1.3.0/docd.png b/v1.3.0/docd.png new file mode 100644 index 0000000000000000000000000000000000000000..d7c94fda9bf08ecc02c7190d968452b7a2dbf04b GIT binary patch literal 756 zcmV1wr-rhpn+wxm%q2)IkAYsr{iGq<}_z5JCD4J;FN?6Qh;@TCubdp(_XdD-^ zG_#)IP7_z6hKNdx5^+FGArwLWTWCG!j+oKji?U!hxA#d-ljgkN`+e^@-P+RWG{Bx= z2iQyYTtEf*o~ySWrIVW}HWHi0_hd4~$E6Jx1U`>Owo}EYJ1O>iZvS?!z8}B}QwLMA zC3Keqf1c}K@?C`X>68b(EUzYUYAS&OH^VPteZLPr{S&|nQvp@6W4GH-1U8!u&7l~A zx~RUSNH+>7@q38W6!BzirtjLFCzc|XGx)EF#G%^pWION*k@?vP<2O>|XkCD3ujl%1 z{55JSVkw{~HbX>iEZ2%yJ2eHj5Yh8OTpzs0A2;tZ^x!#5D+y-es{k1&0|Ns9-|+Xt ziGiTsZ8(^nUo#wdTpIDkb-Zp(3|A*FzW}GZ5SQD-r^R`&X@`26E3W|GyrwDIZjtQ& z$g5f8Sv=VgVtDien@J(!^BK+#l;s-LgP--p7C;7;E!ysXcXK6?+9D>_-B(?Wm(U zQbNm-5TyYxIU=rs0+)!ixqzhuxw(AqKc3?KKX32{D~Qibp*r0x&Wux5-9WCMMRi3U zTd6dOCQlj>a;gr;gLwRKulT&(m@^L{&HkSC(qH05HSSf$YEhynGvH zWNez``Z8FJXE+BSg=%ak{OR z+Nylcb{?evLYLuE1_HngYw0g%LC#=$a@?4~Tx>F9295Q>9UJ|_6v-KMw;!YZSgGj@ zR8fRov=hJ#QvsO@xw*{0%zH@OKVEUrsummary { + list-style-type: none; +} + +details > summary::-webkit-details-marker { + display: none; +} + +details>summary::before { + content: "\25ba"; + padding-right:4px; + font-size: 80%; +} + +details[open]>summary::before { + content: "\25bc"; + padding-right:4px; + font-size: 80%; +} + diff --git a/v1.3.0/doxygen.svg b/v1.3.0/doxygen.svg new file mode 100644 index 00000000..d42dad52 --- /dev/null +++ b/v1.3.0/doxygen.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v1.3.0/dynsections.js b/v1.3.0/dynsections.js new file mode 100644 index 00000000..f579fbf3 --- /dev/null +++ b/v1.3.0/dynsections.js @@ -0,0 +1,123 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); + $('table.directory tr'). + removeClass('odd').filter(':visible:odd').addClass('odd'); +} + +function toggleLevel(level) +{ + $('table.directory tr').each(function() { + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l + + + + + + +coreMQTT Agent: Files + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Files
+
+
+
The following files are associated with this library.
+
[detail level 123]
+ + + + + + + + + +
  source
  include
 core_mqtt_agent.hFunctions for running a coreMQTT client in a dedicated thread
 core_mqtt_agent_command_functions.hFunctions for processing an MQTT agent command
 core_mqtt_agent_config_defaults.hThis represents the default values for the configuration macros for the MQTT-Agent library
 core_mqtt_agent_default_logging.hThis represents the default values for the logging macros for the MQTT-Agent library
 core_mqtt_agent_message_interface.hFunctions to interact with queues
 core_mqtt_agent.cImplements an MQTT agent (or daemon task) to enable multithreaded access to coreMQTT
 core_mqtt_agent_command_functions.cImplements functions to process MQTT agent commands
+
+
+
+ + + + diff --git a/v1.3.0/folderclosed.png b/v1.3.0/folderclosed.png new file mode 100644 index 0000000000000000000000000000000000000000..bb8ab35edce8e97554e360005ee9fc5bffb36e66 GIT binary patch literal 616 zcmV-u0+;=XP)a9#ETzayK)T~Jw&MMH>OIr#&;dC}is*2Mqdf&akCc=O@`qC+4i z5Iu3w#1M@KqXCz8TIZd1wli&kkl2HVcAiZ8PUn5z_kG@-y;?yK06=cA0U%H0PH+kU zl6dp}OR(|r8-RG+YLu`zbI}5TlOU6ToR41{9=uz^?dGTNL;wIMf|V3`d1Wj3y!#6` zBLZ?xpKR~^2x}?~zA(_NUu3IaDB$tKma*XUdOZN~c=dLt_h_k!dbxm_*ibDM zlFX`g{k$X}yIe%$N)cn1LNu=q9_CS)*>A zsX_mM4L@`(cSNQKMFc$RtYbx{79#j-J7hk*>*+ZZhM4Hw?I?rsXCi#mRWJ=-0LGV5a-WR0Qgt<|Nqf)C-@80`5gIz45^_20000IqP)X=#(TiCT&PiIIVc55T}TU}EUh*{q$|`3@{d>{Tc9Bo>e= zfmF3!f>fbI9#GoEHh0f`i5)wkLpva0ztf%HpZneK?w-7AK@b4Itw{y|Zd3k!fH?q2 zlhckHd_V2M_X7+)U&_Xcfvtw60l;--DgZmLSw-Y?S>)zIqMyJ1#FwLU*%bl38ok+! zh78H87n`ZTS;uhzAR$M`zZ`bVhq=+%u9^$5jDplgxd44}9;IRqUH1YHH|@6oFe%z( zo4)_>E$F&^P-f(#)>(TrnbE>Pefs9~@iN=|)Rz|V`sGfHNrJ)0gJb8xx+SBmRf@1l zvuzt=vGfI)<-F9!o&3l?>9~0QbUDT(wFdnQPv%xdD)m*g%!20>Bc9iYmGAp<9YAa( z0QgYgTWqf1qN++Gqp z8@AYPTB3E|6s=WLG?xw0tm|U!o=&zd+H0oRYE;Dbx+Na9s^STqX|Gnq%H8s(nGDGJ j8vwW|`Ts`)fSK|Kx=IK@RG@g200000NkvXXu0mjfauFEA literal 0 HcmV?d00001 diff --git a/v1.3.0/functions.html b/v1.3.0/functions.html new file mode 100644 index 00000000..8786ec30 --- /dev/null +++ b/v1.3.0/functions.html @@ -0,0 +1,184 @@ + + + + + + + +coreMQTT Agent: Data Fields + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- a -

+ + +

- b -

+ + +

- c -

+ + +

- e -

+ + +

- g -

+ + +

- m -

+ + +

- n -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+
+
+ + + + diff --git a/v1.3.0/functions_vars.html b/v1.3.0/functions_vars.html new file mode 100644 index 00000000..2157a05c --- /dev/null +++ b/v1.3.0/functions_vars.html @@ -0,0 +1,184 @@ + + + + + + + +coreMQTT Agent: Data Fields - Variables + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- a -

+ + +

- b -

+ + +

- c -

+ + +

- e -

+ + +

- g -

+ + +

- m -

+ + +

- n -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+
+
+ + + + diff --git a/v1.3.0/globals.html b/v1.3.0/globals.html new file mode 100644 index 00000000..2be06205 --- /dev/null +++ b/v1.3.0/globals.html @@ -0,0 +1,233 @@ + + + + + + + +coreMQTT Agent: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- a -

+ + +

- c -

+ + +

- d -

+ + +

- g -

+ + +

- h -

+ + +

- i -

+ + +

- l -

+ + +

- m -

+ + +

- n -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- u -

+ + +

- v -

+
+
+ + + + diff --git a/v1.3.0/globals_defs.html b/v1.3.0/globals_defs.html new file mode 100644 index 00000000..90979b07 --- /dev/null +++ b/v1.3.0/globals_defs.html @@ -0,0 +1,120 @@ + + + + + + + +coreMQTT Agent: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
+ + + + diff --git a/v1.3.0/globals_enum.html b/v1.3.0/globals_enum.html new file mode 100644 index 00000000..f6a49ec8 --- /dev/null +++ b/v1.3.0/globals_enum.html @@ -0,0 +1,112 @@ + + + + + + + +coreMQTT Agent: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
+ + + + diff --git a/v1.3.0/globals_eval.html b/v1.3.0/globals_eval.html new file mode 100644 index 00000000..4b6c1871 --- /dev/null +++ b/v1.3.0/globals_eval.html @@ -0,0 +1,121 @@ + + + + + + + +coreMQTT Agent: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
+ + + + diff --git a/v1.3.0/globals_func.html b/v1.3.0/globals_func.html new file mode 100644 index 00000000..a9660602 --- /dev/null +++ b/v1.3.0/globals_func.html @@ -0,0 +1,180 @@ + + + + + + + +coreMQTT Agent: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- a -

+ + +

- c -

+ + +

- g -

+ + +

- h -

+ + +

- i -

+ + +

- m -

+ + +

- p -

+ + +

- r -

+ + +

- v -

+
+
+ + + + diff --git a/v1.3.0/globals_type.html b/v1.3.0/globals_type.html new file mode 100644 index 00000000..199bd3af --- /dev/null +++ b/v1.3.0/globals_type.html @@ -0,0 +1,120 @@ + + + + + + + +coreMQTT Agent: Globals + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
+ + + + diff --git a/v1.3.0/group__mqtt__agent__callback__types.html b/v1.3.0/group__mqtt__agent__callback__types.html new file mode 100644 index 00000000..6f3392c0 --- /dev/null +++ b/v1.3.0/group__mqtt__agent__callback__types.html @@ -0,0 +1,181 @@ + + + + + + + +coreMQTT Agent: Callback Types + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
Callback Types
+
+
+ +

Callback function pointer types of the MQTT Agent. +More...

+ + + + + + + + +

+Typedefs

typedef void(* MQTTAgentCommandCallback_t) (MQTTAgentCommandContext_t *pCmdCallbackContext, MQTTAgentReturnInfo_t *pReturnInfo)
 Callback function called when a command completes.
 
typedef void(* MQTTAgentIncomingPublishCallback_t) (struct MQTTAgentContext *pMqttAgentContext, uint16_t packetId, MQTTPublishInfo_t *pPublishInfo)
 Callback function called when receiving a publish.
 
+

Detailed Description

+

Callback function pointer types of the MQTT Agent.

+

Typedef Documentation

+ +

◆ MQTTAgentCommandCallback_t

+ +
+
+ + + + +
typedef void(* MQTTAgentCommandCallback_t) (MQTTAgentCommandContext_t *pCmdCallbackContext, MQTTAgentReturnInfo_t *pReturnInfo)
+
+ +

Callback function called when a command completes.

+
Parameters
+ + + +
[in]pCmdCallbackContextThe callback context passed to the original command.
[in]pReturnInfoA struct of status codes and outputs from the command.
+
+
+
Note
A command should not be considered complete until this callback is called, and the arguments that the command uses MUST stay in scope until such happens.
+
+The callback MUST NOT block as it runs in the context of the MQTT agent task. If the callback calls any MQTT Agent API to enqueue a command, the blocking time (blockTimeMs member of MQTTAgentCommandInfo_t) MUST be zero. If the application wants to enqueue command(s) with non-zero blocking time, the callback can notify a different task to enqueue command(s) to the MQTT agent.
+ +
+
+ +

◆ MQTTAgentIncomingPublishCallback_t

+ +
+
+ + + + +
typedef void(* MQTTAgentIncomingPublishCallback_t) (struct MQTTAgentContext *pMqttAgentContext, uint16_t packetId, MQTTPublishInfo_t *pPublishInfo)
+
+ +

Callback function called when receiving a publish.

+
Parameters
+ + + + +
[in]pMqttAgentContextThe context of the MQTT agent.
[in]packetIdThe packet ID of the received publish.
[in]pPublishInfoDeserialized publish information.
+
+
+
Note
The callback MUST NOT block as it runs in the context of the MQTT agent task. If the callback calls any MQTT Agent API to enqueue a command, the blocking time (blockTimeMs member of MQTTAgentCommandInfo_t) MUST be zero. If the application wants to enqueue command(s) with non-zero blocking time, the callback can notify a different task to enqueue command(s) to the MQTT agent.
+ +
+
+
+
+ + + + diff --git a/v1.3.0/group__mqtt__agent__callback__types.js b/v1.3.0/group__mqtt__agent__callback__types.js new file mode 100644 index 00000000..6e8dac1e --- /dev/null +++ b/v1.3.0/group__mqtt__agent__callback__types.js @@ -0,0 +1,5 @@ +var group__mqtt__agent__callback__types = +[ + [ "MQTTAgentCommandCallback_t", "group__mqtt__agent__callback__types.html#gaa2497c28b3fb55b8dc38b0873f749eef", null ], + [ "MQTTAgentIncomingPublishCallback_t", "group__mqtt__agent__callback__types.html#gacdfb8687b1217d321e7cc58e365ec6a1", null ] +]; \ No newline at end of file diff --git a/v1.3.0/group__mqtt__agent__enum__types.html b/v1.3.0/group__mqtt__agent__enum__types.html new file mode 100644 index 00000000..2d33a184 --- /dev/null +++ b/v1.3.0/group__mqtt__agent__enum__types.html @@ -0,0 +1,179 @@ + + + + + + + +coreMQTT Agent: Enumerated Types + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
Enumerated Types
+
+
+ +

Enumerated types of the MQTT Agent. +More...

+ + + + + +

+Enumerations

enum  MQTTAgentCommandType_t {
+  NONE = 0 +, PROCESSLOOP +, PUBLISH +, SUBSCRIBE +,
+  UNSUBSCRIBE +, PING +, CONNECT +, DISCONNECT +,
+  TERMINATE +, NUM_COMMANDS +
+ }
 A type of command for interacting with the MQTT API. More...
 
+

Detailed Description

+

Enumerated types of the MQTT Agent.

+

Enumeration Type Documentation

+ +

◆ MQTTAgentCommandType_t

+ +
+
+ + + + +
enum MQTTAgentCommandType_t
+
+ +

A type of command for interacting with the MQTT API.

+ + + + + + + + + + + +
Enumerator
NONE 

No command received. Must be zero (its memset() value).

+
PROCESSLOOP 

Call MQTT_ProcessLoop().

+
PUBLISH 

Call MQTT_Publish().

+
SUBSCRIBE 

Call MQTT_Subscribe().

+
UNSUBSCRIBE 

Call MQTT_Unsubscribe().

+
PING 

Call MQTT_Ping().

+
CONNECT 

Call MQTT_Connect().

+
DISCONNECT 

Call MQTT_Disconnect().

+
TERMINATE 

Exit the command loop and stop processing commands.

+
NUM_COMMANDS 

The number of command types handled by the agent.

+
+ +
+
+
+
+ + + + diff --git a/v1.3.0/group__mqtt__agent__enum__types.js b/v1.3.0/group__mqtt__agent__enum__types.js new file mode 100644 index 00000000..3f994aac --- /dev/null +++ b/v1.3.0/group__mqtt__agent__enum__types.js @@ -0,0 +1,15 @@ +var group__mqtt__agent__enum__types = +[ + [ "MQTTAgentCommandType_t", "group__mqtt__agent__enum__types.html#ga76604fa58b7ee6c32ba084fda9379f33", [ + [ "NONE", "group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33ac157bdf0b85a40d2619cbc8bc1ae5fe2", null ], + [ "PROCESSLOOP", "group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a955e933dab5938a6cce4e140278a24d2", null ], + [ "PUBLISH", "group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33abd1a204dcfa4933760cd12e779f36fc5", null ], + [ "SUBSCRIBE", "group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33abc6f919ff681f5f552b2f7d1f0fba832", null ], + [ "UNSUBSCRIBE", "group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a8395e5981c15d813c588c86988fd4aea", null ], + [ "PING", "group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a3a95ef902bc659901cceef98e0bc8041", null ], + [ "CONNECT", "group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a20391dd2915a0e64343d24c2f2e40b95", null ], + [ "DISCONNECT", "group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a2f6318afb30e8e2817e6203ebedc8173", null ], + [ "TERMINATE", "group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a9aab2d9eae3e9a84d9fed3f0cadd7e22", null ], + [ "NUM_COMMANDS", "group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a158760c3c33699acd8723f4c983822a6", null ] + ] ] +]; \ No newline at end of file diff --git a/v1.3.0/group__mqtt__agent__struct__types.html b/v1.3.0/group__mqtt__agent__struct__types.html new file mode 100644 index 00000000..a00d79fc --- /dev/null +++ b/v1.3.0/group__mqtt__agent__struct__types.html @@ -0,0 +1,180 @@ + + + + + + + +coreMQTT Agent: Parameter Structures + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
Parameter Structures
+
+
+ +

Structures passed as parameters to MQTT Agent functions. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Structures

struct  MQTTAgentReturnInfo_t
 Struct holding return codes and outputs from a command. More...
 
struct  MQTTAgentCommand_t
 The commands sent from the APIs to the MQTT agent task. More...
 
struct  MQTTAgentAckInfo_t
 Information for a pending MQTT ack packet expected by the agent. More...
 
struct  MQTTAgentContext_t
 Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(), and every API function will accept a pointer to the initalized struct. More...
 
struct  MQTTAgentSubscribeArgs_t
 Struct holding arguments for a SUBSCRIBE or UNSUBSCRIBE call. More...
 
struct  MQTTAgentConnectArgs_t
 Struct holding arguments for a CONNECT call. More...
 
struct  MQTTAgentCommandInfo_t
 Struct holding arguments that are common to every command. More...
 
struct  MQTTAgentCommandFuncReturns_t
 A structure of values and flags expected to be returned by command functions. More...
 
struct  MQTTAgentMessageInterface_t
 Function pointers and contexts used for sending and receiving commands, and allocating memory for them. More...
 
+ + + + + + + +

+Typedefs

typedef struct MQTTAgentCommandContext MQTTAgentCommandContext_t
 Struct containing context for a specific command.
 
+typedef struct MQTTAgentMessageContext MQTTAgentMessageContext_t
 Context with which tasks may deliver messages to the agent.
 
+

Detailed Description

+

Structures passed as parameters to MQTT Agent functions.

+

These structures are passed as parameters to library functions. Documentation for these structures will state the functions associated with each parameter structure and the purpose of each member.

+

Typedef Documentation

+ +

◆ MQTTAgentCommandContext_t

+ +
+
+ + + + +
typedef struct MQTTAgentCommandContext MQTTAgentCommandContext_t
+
+ +

Struct containing context for a specific command.

+
Note
An instance of this struct and any variables it points to MUST stay in scope until the associated command is processed, and its callback called.
+ +
+
+
+
+ + + + diff --git a/v1.3.0/group__mqtt__agent__struct__types.js b/v1.3.0/group__mqtt__agent__struct__types.js new file mode 100644 index 00000000..1d0ab4f2 --- /dev/null +++ b/v1.3.0/group__mqtt__agent__struct__types.js @@ -0,0 +1,55 @@ +var group__mqtt__agent__struct__types = +[ + [ "MQTTAgentReturnInfo_t", "struct_m_q_t_t_agent_return_info__t.html", [ + [ "returnCode", "struct_m_q_t_t_agent_return_info__t.html#ab04f05e53b8e9039f8983f68b032ccc8", null ], + [ "pSubackCodes", "struct_m_q_t_t_agent_return_info__t.html#ad68d82134f1f72460f82b83256409542", null ] + ] ], + [ "MQTTAgentCommand_t", "struct_m_q_t_t_agent_command.html", [ + [ "commandType", "struct_m_q_t_t_agent_command.html#ae810f32d3650badbe3f8a86d5754adf1", null ], + [ "pArgs", "struct_m_q_t_t_agent_command.html#a0d41721e83bc91b39b7f54b39c97fafa", null ], + [ "pCommandCompleteCallback", "struct_m_q_t_t_agent_command.html#a4221813f0ee8d6be1e2b1f60b31fb2a3", null ], + [ "pCmdContext", "struct_m_q_t_t_agent_command.html#ae7f9dad4bc0c849dae9dd2aa8c20eeef", null ] + ] ], + [ "MQTTAgentAckInfo_t", "struct_m_q_t_t_agent_ack_info__t.html", [ + [ "packetId", "struct_m_q_t_t_agent_ack_info__t.html#ac3db584579455d37c7ad8656aa4b03f2", null ], + [ "pOriginalCommand", "struct_m_q_t_t_agent_ack_info__t.html#a4cddb1600b6ef0d3a34af262d919b2be", null ] + ] ], + [ "MQTTAgentContext_t", "struct_m_q_t_t_agent_context__t.html", [ + [ "mqttContext", "struct_m_q_t_t_agent_context__t.html#aec01b2b61213956dc2219f620964a055", null ], + [ "agentInterface", "struct_m_q_t_t_agent_context__t.html#ab89557b0a015d1848b8d6a9adbff8a4d", null ], + [ "pPendingAcks", "struct_m_q_t_t_agent_context__t.html#a324ccd898ba0769142b29b4cab38c5be", null ], + [ "pIncomingCallback", "struct_m_q_t_t_agent_context__t.html#a1e20b7a77aab94f5c775ca3c534cb006", null ], + [ "pIncomingCallbackContext", "struct_m_q_t_t_agent_context__t.html#a00a73b9d9cfda64aeb9e7b796222dde4", null ], + [ "packetReceivedInLoop", "struct_m_q_t_t_agent_context__t.html#af284de4e09e0b18411969aad986c8789", null ] + ] ], + [ "MQTTAgentSubscribeArgs_t", "struct_m_q_t_t_agent_subscribe_args__t.html", [ + [ "pSubscribeInfo", "struct_m_q_t_t_agent_subscribe_args__t.html#a27e21bfcf0184a4a168a6170a60fc026", null ], + [ "numSubscriptions", "struct_m_q_t_t_agent_subscribe_args__t.html#ae30aaa33e7a0e67a5989c2d15170de95", null ] + ] ], + [ "MQTTAgentConnectArgs_t", "struct_m_q_t_t_agent_connect_args__t.html", [ + [ "pConnectInfo", "struct_m_q_t_t_agent_connect_args__t.html#a9b71b1787c8cfe03654b1ca06ac594fa", null ], + [ "pWillInfo", "struct_m_q_t_t_agent_connect_args__t.html#a1ab24eb17eebc51bdad53ee2b36c8cdb", null ], + [ "timeoutMs", "struct_m_q_t_t_agent_connect_args__t.html#a631a199abde2ad2b3e4c69cf211e4d54", null ], + [ "sessionPresent", "struct_m_q_t_t_agent_connect_args__t.html#a01e3a80d5db4f5f89df44697cca1513f", null ] + ] ], + [ "MQTTAgentCommandInfo_t", "struct_m_q_t_t_agent_command_info__t.html", [ + [ "cmdCompleteCallback", "struct_m_q_t_t_agent_command_info__t.html#a4c9e9b55c7b576a390f734238b60f3aa", null ], + [ "pCmdCompleteCallbackContext", "struct_m_q_t_t_agent_command_info__t.html#a22fc349b76808064646fe71a43d37b96", null ], + [ "blockTimeMs", "struct_m_q_t_t_agent_command_info__t.html#aa0f490187c1199c2d31d4c04a01d4637", null ] + ] ], + [ "MQTTAgentCommandFuncReturns_t", "struct_m_q_t_t_agent_command_func_returns__t.html", [ + [ "packetId", "struct_m_q_t_t_agent_command_func_returns__t.html#ae37354b1e32541cb6b014f270815a28d", null ], + [ "endLoop", "struct_m_q_t_t_agent_command_func_returns__t.html#aea0742c902ee70380f308b7f957dc9a2", null ], + [ "addAcknowledgment", "struct_m_q_t_t_agent_command_func_returns__t.html#a474988426514661ae649a613b1dee051", null ], + [ "runProcessLoop", "struct_m_q_t_t_agent_command_func_returns__t.html#aae5a1d50a22df21950d586f5584e8994", null ] + ] ], + [ "MQTTAgentMessageInterface_t", "struct_m_q_t_t_agent_message_interface__t.html", [ + [ "pMsgCtx", "struct_m_q_t_t_agent_message_interface__t.html#a00cad3c3514a03d5deed20609ffdc94b", null ], + [ "send", "struct_m_q_t_t_agent_message_interface__t.html#abdc8e1c30aa27bf633f4f6e7da9a6465", null ], + [ "recv", "struct_m_q_t_t_agent_message_interface__t.html#a19e00e6431f53e595837d8ac7e4f744b", null ], + [ "getCommand", "struct_m_q_t_t_agent_message_interface__t.html#aaa4d0614e8289d7ea12422e66c1e8689", null ], + [ "releaseCommand", "struct_m_q_t_t_agent_message_interface__t.html#ac809ba46da91df0fc4750ce515bf8f41", null ] + ] ], + [ "MQTTAgentCommandContext_t", "group__mqtt__agent__struct__types.html#ga953da1618097a29381f3fc38f576055c", null ], + [ "MQTTAgentMessageContext_t", "group__mqtt__agent__struct__types.html#ga3c47f2ebcec2e1150e40d039639e5a3b", null ] +]; \ No newline at end of file diff --git a/v1.3.0/index.html b/v1.3.0/index.html new file mode 100644 index 00000000..6f00ec41 --- /dev/null +++ b/v1.3.0/index.html @@ -0,0 +1,140 @@ + + + + + + + +coreMQTT Agent: Overview + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Overview
+
+
+

Thread safe MQTT 3.1.1 client

+

The coreMQTT Agent is a thread-safe library to serialize calls to coreMQTT, to be executed by a single thread. It provides APIs for a single, dedicated agent task to process coreMQTT related commands, and the APIs for other tasks to enqueue these commands for processing.

+

+Why is there a higher level library based on coreMQTT?

+

coreMQTT is an MIT licensed open source C MQTT client library for microcontroller and small microprocessor based IoT devices. Its design is intentionally simple to ensure it has no dependency on any other library or operating system, and to better enable static analysis including memory safety proofs. That simplicity and lack of operating system dependency (coreMQTT does not require multithreading at all) means coreMQTT does not build thread safety directly into its implementation. Instead, thread safety must be provided by higher level software. The coreMQTT Agent library is a coreMQTT extension that provides that higher level functionality in the form of an MQTT agent (or MQTT daemon).

+

+Memory Requirements

+

Memory requirements of the MQTT Agent library, including the coreMQTT library.

+

+ + + + + + + + + + + + + + + + +
Code Size of coreMQTT Agent (example generated with GCC for ARM Cortex-M)
File
With -O1 Optimization
With -Os Optimization
core_mqtt_agent.c
1.7K
1.5K
core_mqtt_agent_command_functions.c
0.3K
0.2K
core_mqtt.c (coreMQTT)
4.1K
3.5K
core_mqtt_state.c (coreMQTT)
1.7K
1.3K
core_mqtt_serializer.c (coreMQTT)
2.8K
2.2K
Total estimates
10.6K
8.7K
+

+
+
+
+ + + + diff --git a/v1.3.0/index.js b/v1.3.0/index.js new file mode 100644 index 00000000..3078b616 --- /dev/null +++ b/v1.3.0/index.js @@ -0,0 +1,5 @@ +var index = +[ + [ "Why is there a higher level library based on coreMQTT?", "index.html#coreMQTT_brief", null ], + [ "Memory Requirements", "index.html#core_mqtt_agent_memory_requirements", null ] +]; \ No newline at end of file diff --git a/v1.3.0/jquery.js b/v1.3.0/jquery.js new file mode 100644 index 00000000..1dffb65b --- /dev/null +++ b/v1.3.0/jquery.js @@ -0,0 +1,34 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=y(e||this.defaultElement||this)[0],this.element=y(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=y(),this.hoverable=y(),this.focusable=y(),this.classesElementLookup={},e!==this&&(y.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=y(e.style?e.ownerDocument:e.document||e),this.window=y(this.document[0].defaultView||this.document[0].parentWindow)),this.options=y.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:y.noop,_create:y.noop,_init:y.noop,destroy:function(){var i=this;this._destroy(),y.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:y.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return y.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=y.widget.extend({},this.options[t]),n=0;n
"),i=e.children()[0];return y("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),s=t-i},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.widthx(D(s),D(n))?o.important="horizontal":o.important="vertical",p.using.call(this,t,o)}),h.offset(y.extend(l,{using:t}))})},y.ui.position={fit:{left:function(t,e){var i=e.within,s=i.isWindow?i.scrollLeft:i.offset.left,n=i.width,o=t.left-e.collisionPosition.marginLeft,h=s-o,a=o+e.collisionWidth-n-s;e.collisionWidth>n?0n?0=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),y.ui.plugin={add:function(t,e,i){var s,n=y.ui[t].prototype;for(s in i)n.plugins[s]=n.plugins[s]||[],n.plugins[s].push([e,i[s]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;n").css({overflow:"hidden",position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,t={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(t),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(t),this._proportionallyResize()),this._setupHandles(),e.autoHide&&y(this.element).on("mouseenter",function(){e.disabled||(i._removeClass("ui-resizable-autohide"),i._handles.show())}).on("mouseleave",function(){e.disabled||i.resizing||(i._addClass("ui-resizable-autohide"),i._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy(),this._addedHandles.remove();function t(t){y(t).removeData("resizable").removeData("ui-resizable").off(".resizable")}var e;return this.elementIsWrapper&&(t(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),t(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;case"aspectRatio":this._aspectRatio=!!e}},_setupHandles:function(){var t,e,i,s,n,o=this.options,h=this;if(this.handles=o.handles||(y(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=y(),this._addedHandles=y(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),i=this.handles.split(","),this.handles={},e=0;e"),this._addClass(n,"ui-resizable-handle "+s),n.css({zIndex:o.zIndex}),this.handles[t]=".ui-resizable-"+t,this.element.children(this.handles[t]).length||(this.element.append(n),this._addedHandles=this._addedHandles.add(n));this._renderAxis=function(t){var e,i,s;for(e in t=t||this.element,this.handles)this.handles[e].constructor===String?this.handles[e]=this.element.children(this.handles[e]).first().show():(this.handles[e].jquery||this.handles[e].nodeType)&&(this.handles[e]=y(this.handles[e]),this._on(this.handles[e],{mousedown:h._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(i=y(this.handles[e],this.element),s=/sw|ne|nw|se|n|s/.test(e)?i.outerHeight():i.outerWidth(),i=["padding",/ne|nw|n/.test(e)?"Top":/se|sw|s/.test(e)?"Bottom":/^e$/.test(e)?"Right":"Left"].join(""),t.css(i,s),this._proportionallyResize()),this._handles=this._handles.add(this.handles[e])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){h.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),h.axis=n&&n[1]?n[1]:"se")}),o.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._addedHandles.remove()},_mouseCapture:function(t){var e,i,s=!1;for(e in this.handles)(i=y(this.handles[e])[0])!==t.target&&!y.contains(i,t.target)||(s=!0);return!this.options.disabled&&s},_mouseStart:function(t){var e,i,s=this.options,n=this.element;return this.resizing=!0,this._renderProxy(),e=this._num(this.helper.css("left")),i=this._num(this.helper.css("top")),s.containment&&(e+=y(s.containment).scrollLeft()||0,i+=y(s.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:e,top:i},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:n.width(),height:n.height()},this.originalSize=this._helper?{width:n.outerWidth(),height:n.outerHeight()}:{width:n.width(),height:n.height()},this.sizeDiff={width:n.outerWidth()-n.width(),height:n.outerHeight()-n.height()},this.originalPosition={left:e,top:i},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio="number"==typeof s.aspectRatio?s.aspectRatio:this.originalSize.width/this.originalSize.height||1,s=y(".ui-resizable-"+this.axis).css("cursor"),y("body").css("cursor","auto"===s?this.axis+"-resize":s),this._addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var e=this.originalMousePosition,i=this.axis,s=t.pageX-e.left||0,e=t.pageY-e.top||0,i=this._change[i];return this._updatePrevProperties(),i&&(e=i.apply(this,[t,s,e]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(e=this._updateRatio(e,t)),e=this._respectSize(e,t),this._updateCache(e),this._propagate("resize",t),e=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),y.isEmptyObject(e)||(this._updatePrevProperties(),this._trigger("resize",t,this.ui()),this._applyChanges())),!1},_mouseStop:function(t){this.resizing=!1;var e,i,s,n=this.options,o=this;return this._helper&&(s=(e=(i=this._proportionallyResizeElements).length&&/textarea/i.test(i[0].nodeName))&&this._hasScroll(i[0],"left")?0:o.sizeDiff.height,i=e?0:o.sizeDiff.width,e={width:o.helper.width()-i,height:o.helper.height()-s},i=parseFloat(o.element.css("left"))+(o.position.left-o.originalPosition.left)||null,s=parseFloat(o.element.css("top"))+(o.position.top-o.originalPosition.top)||null,n.animate||this.element.css(y.extend(e,{top:s,left:i})),o.helper.height(o.size.height),o.helper.width(o.size.width),this._helper&&!n.animate&&this._proportionallyResize()),y("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s=this.options,n={minWidth:this._isNumber(s.minWidth)?s.minWidth:0,maxWidth:this._isNumber(s.maxWidth)?s.maxWidth:1/0,minHeight:this._isNumber(s.minHeight)?s.minHeight:0,maxHeight:this._isNumber(s.maxHeight)?s.maxHeight:1/0};(this._aspectRatio||t)&&(e=n.minHeight*this.aspectRatio,i=n.minWidth/this.aspectRatio,s=n.maxHeight*this.aspectRatio,t=n.maxWidth/this.aspectRatio,e>n.minWidth&&(n.minWidth=e),i>n.minHeight&&(n.minHeight=i),st.width,h=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,a=this.originalPosition.left+this.originalSize.width,r=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),i=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),h&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=a-e.minWidth),s&&l&&(t.left=a-e.maxWidth),h&&i&&(t.top=r-e.minHeight),n&&i&&(t.top=r-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];e<4;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;e").css({overflow:"hidden"}),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++e.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize;return{left:this.originalPosition.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize;return{top:this.originalPosition.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(t,e,i){return y.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},sw:function(t,e,i){return y.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,e,i]))},ne:function(t,e,i){return y.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},nw:function(t,e,i){return y.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,e,i]))}},_propagate:function(t,e){y.ui.plugin.call(this,t,[e,this.ui()]),"resize"!==t&&this._trigger(t,e,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),y.ui.plugin.add("resizable","animate",{stop:function(e){var i=y(this).resizable("instance"),t=i.options,s=i._proportionallyResizeElements,n=s.length&&/textarea/i.test(s[0].nodeName),o=n&&i._hasScroll(s[0],"left")?0:i.sizeDiff.height,h=n?0:i.sizeDiff.width,n={width:i.size.width-h,height:i.size.height-o},h=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,o=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(y.extend(n,o&&h?{top:o,left:h}:{}),{duration:t.animateDuration,easing:t.animateEasing,step:function(){var t={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};s&&s.length&&y(s[0]).css({width:t.width,height:t.height}),i._updateCache(t),i._propagate("resize",e)}})}}),y.ui.plugin.add("resizable","containment",{start:function(){var i,s,n=y(this).resizable("instance"),t=n.options,e=n.element,o=t.containment,h=o instanceof y?o.get(0):/parent/.test(o)?e.parent().get(0):o;h&&(n.containerElement=y(h),/document/.test(o)||o===document?(n.containerOffset={left:0,top:0},n.containerPosition={left:0,top:0},n.parentData={element:y(document),left:0,top:0,width:y(document).width(),height:y(document).height()||document.body.parentNode.scrollHeight}):(i=y(h),s=[],y(["Top","Right","Left","Bottom"]).each(function(t,e){s[t]=n._num(i.css("padding"+e))}),n.containerOffset=i.offset(),n.containerPosition=i.position(),n.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},t=n.containerOffset,e=n.containerSize.height,o=n.containerSize.width,o=n._hasScroll(h,"left")?h.scrollWidth:o,e=n._hasScroll(h)?h.scrollHeight:e,n.parentData={element:h,left:t.left,top:t.top,width:o,height:e}))},resize:function(t){var e=y(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.position,o=e._aspectRatio||t.shiftKey,h={top:0,left:0},a=e.containerElement,t=!0;a[0]!==document&&/static/.test(a.css("position"))&&(h=s),n.left<(e._helper?s.left:0)&&(e.size.width=e.size.width+(e._helper?e.position.left-s.left:e.position.left-h.left),o&&(e.size.height=e.size.width/e.aspectRatio,t=!1),e.position.left=i.helper?s.left:0),n.top<(e._helper?s.top:0)&&(e.size.height=e.size.height+(e._helper?e.position.top-s.top:e.position.top),o&&(e.size.width=e.size.height*e.aspectRatio,t=!1),e.position.top=e._helper?s.top:0),i=e.containerElement.get(0)===e.element.parent().get(0),n=/relative|absolute/.test(e.containerElement.css("position")),i&&n?(e.offset.left=e.parentData.left+e.position.left,e.offset.top=e.parentData.top+e.position.top):(e.offset.left=e.element.offset().left,e.offset.top=e.element.offset().top),n=Math.abs(e.sizeDiff.width+(e._helper?e.offset.left-h.left:e.offset.left-s.left)),s=Math.abs(e.sizeDiff.height+(e._helper?e.offset.top-h.top:e.offset.top-s.top)),n+e.size.width>=e.parentData.width&&(e.size.width=e.parentData.width-n,o&&(e.size.height=e.size.width/e.aspectRatio,t=!1)),s+e.size.height>=e.parentData.height&&(e.size.height=e.parentData.height-s,o&&(e.size.width=e.size.height*e.aspectRatio,t=!1)),t||(e.position.left=e.prevPosition.left,e.position.top=e.prevPosition.top,e.size.width=e.prevSize.width,e.size.height=e.prevSize.height)},stop:function(){var t=y(this).resizable("instance"),e=t.options,i=t.containerOffset,s=t.containerPosition,n=t.containerElement,o=y(t.helper),h=o.offset(),a=o.outerWidth()-t.sizeDiff.width,o=o.outerHeight()-t.sizeDiff.height;t._helper&&!e.animate&&/relative/.test(n.css("position"))&&y(this).css({left:h.left-s.left-i.left,width:a,height:o}),t._helper&&!e.animate&&/static/.test(n.css("position"))&&y(this).css({left:h.left-s.left-i.left,width:a,height:o})}}),y.ui.plugin.add("resizable","alsoResize",{start:function(){var t=y(this).resizable("instance").options;y(t.alsoResize).each(function(){var t=y(this);t.data("ui-resizable-alsoresize",{width:parseFloat(t.width()),height:parseFloat(t.height()),left:parseFloat(t.css("left")),top:parseFloat(t.css("top"))})})},resize:function(t,i){var e=y(this).resizable("instance"),s=e.options,n=e.originalSize,o=e.originalPosition,h={height:e.size.height-n.height||0,width:e.size.width-n.width||0,top:e.position.top-o.top||0,left:e.position.left-o.left||0};y(s.alsoResize).each(function(){var t=y(this),s=y(this).data("ui-resizable-alsoresize"),n={},e=t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];y.each(e,function(t,e){var i=(s[e]||0)+(h[e]||0);i&&0<=i&&(n[e]=i||null)}),t.css(n)})},stop:function(){y(this).removeData("ui-resizable-alsoresize")}}),y.ui.plugin.add("resizable","ghost",{start:function(){var t=y(this).resizable("instance"),e=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}),t._addClass(t.ghost,"ui-resizable-ghost"),!1!==y.uiBackCompat&&"string"==typeof t.options.ghost&&t.ghost.addClass(this.options.ghost),t.ghost.appendTo(t.helper)},resize:function(){var t=y(this).resizable("instance");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=y(this).resizable("instance");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),y.ui.plugin.add("resizable","grid",{resize:function(){var t,e=y(this).resizable("instance"),i=e.options,s=e.size,n=e.originalSize,o=e.originalPosition,h=e.axis,a="number"==typeof i.grid?[i.grid,i.grid]:i.grid,r=a[0]||1,l=a[1]||1,u=Math.round((s.width-n.width)/r)*r,p=Math.round((s.height-n.height)/l)*l,d=n.width+u,c=n.height+p,f=i.maxWidth&&i.maxWidthd,s=i.minHeight&&i.minHeight>c;i.grid=a,m&&(d+=r),s&&(c+=l),f&&(d-=r),g&&(c-=l),/^(se|s|e)$/.test(h)?(e.size.width=d,e.size.height=c):/^(ne)$/.test(h)?(e.size.width=d,e.size.height=c,e.position.top=o.top-p):/^(sw)$/.test(h)?(e.size.width=d,e.size.height=c,e.position.left=o.left-u):((c-l<=0||d-r<=0)&&(t=e._getPaddingPlusBorderDimensions(this)),0=f[g]?0:Math.min(f[g],n));!a&&1-1){targetElements.on(evt+EVENT_NAMESPACE,function elementToggle(event){$.powerTip.toggle(this,event)})}else{targetElements.on(evt+EVENT_NAMESPACE,function elementOpen(event){$.powerTip.show(this,event)})}});$.each(options.closeEvents,function(idx,evt){if($.inArray(evt,options.openEvents)<0){targetElements.on(evt+EVENT_NAMESPACE,function elementClose(event){$.powerTip.hide(this,!isMouseEvent(event))})}});targetElements.on("keydown"+EVENT_NAMESPACE,function elementKeyDown(event){if(event.keyCode===27){$.powerTip.hide(this,true)}})}return targetElements};$.fn.powerTip.defaults={fadeInTime:200,fadeOutTime:100,followMouse:false,popupId:"powerTip",popupClass:null,intentSensitivity:7,intentPollInterval:100,closeDelay:100,placement:"n",smartPlacement:false,offset:10,mouseOnToPopup:false,manual:false,openEvents:["mouseenter","focus"],closeEvents:["mouseleave","blur"]};$.fn.powerTip.smartPlacementLists={n:["n","ne","nw","s"],e:["e","ne","se","w","nw","sw","n","s","e"],s:["s","se","sw","n"],w:["w","nw","sw","e","ne","se","n","s","w"],nw:["nw","w","sw","n","s","se","nw"],ne:["ne","e","se","n","s","sw","ne"],sw:["sw","w","nw","s","n","ne","sw"],se:["se","e","ne","s","n","nw","se"],"nw-alt":["nw-alt","n","ne-alt","sw-alt","s","se-alt","w","e"],"ne-alt":["ne-alt","n","nw-alt","se-alt","s","sw-alt","e","w"],"sw-alt":["sw-alt","s","se-alt","nw-alt","n","ne-alt","w","e"],"se-alt":["se-alt","s","sw-alt","ne-alt","n","nw-alt","e","w"]};$.powerTip={show:function apiShowTip(element,event){if(isMouseEvent(event)){trackMouse(event);session.previousX=event.pageX;session.previousY=event.pageY;$(element).data(DATA_DISPLAYCONTROLLER).show()}else{$(element).first().data(DATA_DISPLAYCONTROLLER).show(true,true)}return element},reposition:function apiResetPosition(element){$(element).first().data(DATA_DISPLAYCONTROLLER).resetPosition();return element},hide:function apiCloseTip(element,immediate){var displayController;immediate=element?immediate:true;if(element){displayController=$(element).first().data(DATA_DISPLAYCONTROLLER)}else if(session.activeHover){displayController=session.activeHover.data(DATA_DISPLAYCONTROLLER)}if(displayController){displayController.hide(immediate)}return element},toggle:function apiToggle(element,event){if(session.activeHover&&session.activeHover.is(element)){$.powerTip.hide(element,!isMouseEvent(event))}else{$.powerTip.show(element,event)}return element}};$.powerTip.showTip=$.powerTip.show;$.powerTip.closeTip=$.powerTip.hide;function CSSCoordinates(){var me=this;me.top="auto";me.left="auto";me.right="auto";me.bottom="auto";me.set=function(property,value){if($.isNumeric(value)){me[property]=Math.round(value)}}}function DisplayController(element,options,tipController){var hoverTimer=null,myCloseDelay=null;function openTooltip(immediate,forceOpen){cancelTimer();if(!element.data(DATA_HASACTIVEHOVER)){if(!immediate){session.tipOpenImminent=true;hoverTimer=setTimeout(function intentDelay(){hoverTimer=null;checkForIntent()},options.intentPollInterval)}else{if(forceOpen){element.data(DATA_FORCEDOPEN,true)}closeAnyDelayed();tipController.showTip(element)}}else{cancelClose()}}function closeTooltip(disableDelay){if(myCloseDelay){myCloseDelay=session.closeDelayTimeout=clearTimeout(myCloseDelay);session.delayInProgress=false}cancelTimer();session.tipOpenImminent=false;if(element.data(DATA_HASACTIVEHOVER)){element.data(DATA_FORCEDOPEN,false);if(!disableDelay){session.delayInProgress=true;session.closeDelayTimeout=setTimeout(function closeDelay(){session.closeDelayTimeout=null;tipController.hideTip(element);session.delayInProgress=false;myCloseDelay=null},options.closeDelay);myCloseDelay=session.closeDelayTimeout}else{tipController.hideTip(element)}}}function checkForIntent(){var xDifference=Math.abs(session.previousX-session.currentX),yDifference=Math.abs(session.previousY-session.currentY),totalDifference=xDifference+yDifference;if(totalDifference",{id:options.popupId});if($body.length===0){$body=$("body")}$body.append(tipElement);session.tooltips=session.tooltips?session.tooltips.add(tipElement):tipElement}if(options.followMouse){if(!tipElement.data(DATA_HASMOUSEMOVE)){$document.on("mousemove"+EVENT_NAMESPACE,positionTipOnCursor);$window.on("scroll"+EVENT_NAMESPACE,positionTipOnCursor);tipElement.data(DATA_HASMOUSEMOVE,true)}}function beginShowTip(element){element.data(DATA_HASACTIVEHOVER,true);tipElement.queue(function queueTipInit(next){showTip(element);next()})}function showTip(element){var tipContent;if(!element.data(DATA_HASACTIVEHOVER)){return}if(session.isTipOpen){if(!session.isClosing){hideTip(session.activeHover)}tipElement.delay(100).queue(function queueTipAgain(next){showTip(element);next()});return}element.trigger("powerTipPreRender");tipContent=getTooltipContent(element);if(tipContent){tipElement.empty().append(tipContent)}else{return}element.trigger("powerTipRender");session.activeHover=element;session.isTipOpen=true;tipElement.data(DATA_MOUSEONTOTIP,options.mouseOnToPopup);tipElement.addClass(options.popupClass);if(!options.followMouse||element.data(DATA_FORCEDOPEN)){positionTipOnElement(element);session.isFixedTipOpen=true}else{positionTipOnCursor()}if(!element.data(DATA_FORCEDOPEN)&&!options.followMouse){$document.on("click"+EVENT_NAMESPACE,function documentClick(event){var target=event.target;if(target!==element[0]){if(options.mouseOnToPopup){if(target!==tipElement[0]&&!$.contains(tipElement[0],target)){$.powerTip.hide()}}else{$.powerTip.hide()}}})}if(options.mouseOnToPopup&&!options.manual){tipElement.on("mouseenter"+EVENT_NAMESPACE,function tipMouseEnter(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).cancel()}});tipElement.on("mouseleave"+EVENT_NAMESPACE,function tipMouseLeave(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).hide()}})}tipElement.fadeIn(options.fadeInTime,function fadeInCallback(){if(!session.desyncTimeout){session.desyncTimeout=setInterval(closeDesyncedTip,500)}element.trigger("powerTipOpen")})}function hideTip(element){session.isClosing=true;session.isTipOpen=false;session.desyncTimeout=clearInterval(session.desyncTimeout);element.data(DATA_HASACTIVEHOVER,false);element.data(DATA_FORCEDOPEN,false);$document.off("click"+EVENT_NAMESPACE);tipElement.off(EVENT_NAMESPACE);tipElement.fadeOut(options.fadeOutTime,function fadeOutCallback(){var coords=new CSSCoordinates;session.activeHover=null;session.isClosing=false;session.isFixedTipOpen=false;tipElement.removeClass();coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);tipElement.css(coords);element.trigger("powerTipClose")})}function positionTipOnCursor(){var tipWidth,tipHeight,coords,collisions,collisionCount;if(!session.isFixedTipOpen&&(session.isTipOpen||session.tipOpenImminent&&tipElement.data(DATA_HASMOUSEMOVE))){tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=new CSSCoordinates;coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);collisions=getViewportCollisions(coords,tipWidth,tipHeight);if(collisions!==Collision.none){collisionCount=countFlags(collisions);if(collisionCount===1){if(collisions===Collision.right){coords.set("left",session.scrollLeft+session.windowWidth-tipWidth)}else if(collisions===Collision.bottom){coords.set("top",session.scrollTop+session.windowHeight-tipHeight)}}else{coords.set("left",session.currentX-tipWidth-options.offset);coords.set("top",session.currentY-tipHeight-options.offset)}}tipElement.css(coords)}}function positionTipOnElement(element){var priorityList,finalPlacement;if(options.smartPlacement||options.followMouse&&element.data(DATA_FORCEDOPEN)){priorityList=$.fn.powerTip.smartPlacementLists[options.placement];$.each(priorityList,function(idx,pos){var collisions=getViewportCollisions(placeTooltip(element,pos),tipElement.outerWidth(),tipElement.outerHeight());finalPlacement=pos;return collisions!==Collision.none})}else{placeTooltip(element,options.placement);finalPlacement=options.placement}tipElement.removeClass("w nw sw e ne se n s w se-alt sw-alt ne-alt nw-alt");tipElement.addClass(finalPlacement)}function placeTooltip(element,placement){var iterationCount=0,tipWidth,tipHeight,coords=new CSSCoordinates;coords.set("top",0);coords.set("left",0);tipElement.css(coords);do{tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=placementCalculator.compute(element,placement,tipWidth,tipHeight,options.offset);tipElement.css(coords)}while(++iterationCount<=5&&(tipWidth!==tipElement.outerWidth()||tipHeight!==tipElement.outerHeight()));return coords}function closeDesyncedTip(){var isDesynced=false,hasDesyncableCloseEvent=$.grep(["mouseleave","mouseout","blur","focusout"],function(eventType){return $.inArray(eventType,options.closeEvents)!==-1}).length>0;if(session.isTipOpen&&!session.isClosing&&!session.delayInProgress&&hasDesyncableCloseEvent){if(session.activeHover.data(DATA_HASACTIVEHOVER)===false||session.activeHover.is(":disabled")){isDesynced=true}else if(!isMouseOver(session.activeHover)&&!session.activeHover.is(":focus")&&!session.activeHover.data(DATA_FORCEDOPEN)){if(tipElement.data(DATA_MOUSEONTOTIP)){if(!isMouseOver(tipElement)){isDesynced=true}}else{isDesynced=true}}if(isDesynced){hideTip(session.activeHover)}}}this.showTip=beginShowTip;this.hideTip=hideTip;this.resetPosition=positionTipOnElement}function isSvgElement(element){return Boolean(window.SVGElement&&element[0]instanceof SVGElement)}function isMouseEvent(event){return Boolean(event&&$.inArray(event.type,MOUSE_EVENTS)>-1&&typeof event.pageX==="number")}function initTracking(){if(!session.mouseTrackingActive){session.mouseTrackingActive=true;getViewportDimensions();$(getViewportDimensions);$document.on("mousemove"+EVENT_NAMESPACE,trackMouse);$window.on("resize"+EVENT_NAMESPACE,trackResize);$window.on("scroll"+EVENT_NAMESPACE,trackScroll)}}function getViewportDimensions(){session.scrollLeft=$window.scrollLeft();session.scrollTop=$window.scrollTop();session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackResize(){session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackScroll(){var x=$window.scrollLeft(),y=$window.scrollTop();if(x!==session.scrollLeft){session.currentX+=x-session.scrollLeft;session.scrollLeft=x}if(y!==session.scrollTop){session.currentY+=y-session.scrollTop;session.scrollTop=y}}function trackMouse(event){session.currentX=event.pageX;session.currentY=event.pageY}function isMouseOver(element){var elementPosition=element.offset(),elementBox=element[0].getBoundingClientRect(),elementWidth=elementBox.right-elementBox.left,elementHeight=elementBox.bottom-elementBox.top;return session.currentX>=elementPosition.left&&session.currentX<=elementPosition.left+elementWidth&&session.currentY>=elementPosition.top&&session.currentY<=elementPosition.top+elementHeight}function getTooltipContent(element){var tipText=element.data(DATA_POWERTIP),tipObject=element.data(DATA_POWERTIPJQ),tipTarget=element.data(DATA_POWERTIPTARGET),targetElement,content;if(tipText){if($.isFunction(tipText)){tipText=tipText.call(element[0])}content=tipText}else if(tipObject){if($.isFunction(tipObject)){tipObject=tipObject.call(element[0])}if(tipObject.length>0){content=tipObject.clone(true,true)}}else if(tipTarget){targetElement=$("#"+tipTarget);if(targetElement.length>0){content=targetElement.html()}}return content}function getViewportCollisions(coords,elementWidth,elementHeight){var viewportTop=session.scrollTop,viewportLeft=session.scrollLeft,viewportBottom=viewportTop+session.windowHeight,viewportRight=viewportLeft+session.windowWidth,collisions=Collision.none;if(coords.topviewportBottom||Math.abs(coords.bottom-session.windowHeight)>viewportBottom){collisions|=Collision.bottom}if(coords.leftviewportRight){collisions|=Collision.left}if(coords.left+elementWidth>viewportRight||coords.right1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);/*! SmartMenus jQuery Plugin - v1.1.0 - September 17, 2017 + * http://www.smartmenus.org/ + * Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function($){function initMouseDetection(t){var e=".smartmenus_mouse";if(mouseDetectionEnabled||t)mouseDetectionEnabled&&t&&($(document).off(e),mouseDetectionEnabled=!1);else{var i=!0,s=null,o={mousemove:function(t){var e={x:t.pageX,y:t.pageY,timeStamp:(new Date).getTime()};if(s){var o=Math.abs(s.x-e.x),a=Math.abs(s.y-e.y);if((o>0||a>0)&&2>=o&&2>=a&&300>=e.timeStamp-s.timeStamp&&(mouse=!0,i)){var n=$(t.target).closest("a");n.is("a")&&$.each(menuTrees,function(){return $.contains(this.$root[0],n[0])?(this.itemEnter({currentTarget:n[0]}),!1):void 0}),i=!1}}s=e}};o[touchEvents?"touchstart":"pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut"]=function(t){isTouchEvent(t.originalEvent)&&(mouse=!1)},$(document).on(getEventsNS(o,e)),mouseDetectionEnabled=!0}}function isTouchEvent(t){return!/^(4|mouse)$/.test(t.pointerType)}function getEventsNS(t,e){e||(e="");var i={};for(var s in t)i[s.split(" ").join(e+" ")+e]=t[s];return i}var menuTrees=[],mouse=!1,touchEvents="ontouchstart"in window,mouseDetectionEnabled=!1,requestAnimationFrame=window.requestAnimationFrame||function(t){return setTimeout(t,1e3/60)},cancelAnimationFrame=window.cancelAnimationFrame||function(t){clearTimeout(t)},canAnimate=!!$.fn.animate;return $.SmartMenus=function(t,e){this.$root=$(t),this.opts=e,this.rootId="",this.accessIdPrefix="",this.$subArrow=null,this.activatedItems=[],this.visibleSubMenus=[],this.showTimeout=0,this.hideTimeout=0,this.scrollTimeout=0,this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.idInc=0,this.$firstLink=null,this.$firstSub=null,this.disabled=!1,this.$disableOverlay=null,this.$touchScrollingSub=null,this.cssTransforms3d="perspective"in t.style||"webkitPerspective"in t.style,this.wasCollapsible=!1,this.init()},$.extend($.SmartMenus,{hideAll:function(){$.each(menuTrees,function(){this.menuHideAll()})},destroy:function(){for(;menuTrees.length;)menuTrees[0].destroy();initMouseDetection(!0)},prototype:{init:function(t){var e=this;if(!t){menuTrees.push(this),this.rootId=((new Date).getTime()+Math.random()+"").replace(/\D/g,""),this.accessIdPrefix="sm-"+this.rootId+"-",this.$root.hasClass("sm-rtl")&&(this.opts.rightToLeftSubMenus=!0);var i=".smartmenus";this.$root.data("smartmenus",this).attr("data-smartmenus-id",this.rootId).dataSM("level",1).on(getEventsNS({"mouseover focusin":$.proxy(this.rootOver,this),"mouseout focusout":$.proxy(this.rootOut,this),keydown:$.proxy(this.rootKeyDown,this)},i)).on(getEventsNS({mouseenter:$.proxy(this.itemEnter,this),mouseleave:$.proxy(this.itemLeave,this),mousedown:$.proxy(this.itemDown,this),focus:$.proxy(this.itemFocus,this),blur:$.proxy(this.itemBlur,this),click:$.proxy(this.itemClick,this)},i),"a"),i+=this.rootId,this.opts.hideOnClick&&$(document).on(getEventsNS({touchstart:$.proxy(this.docTouchStart,this),touchmove:$.proxy(this.docTouchMove,this),touchend:$.proxy(this.docTouchEnd,this),click:$.proxy(this.docClick,this)},i)),$(window).on(getEventsNS({"resize orientationchange":$.proxy(this.winResize,this)},i)),this.opts.subIndicators&&(this.$subArrow=$("").addClass("sub-arrow"),this.opts.subIndicatorsText&&this.$subArrow.html(this.opts.subIndicatorsText)),initMouseDetection()}if(this.$firstSub=this.$root.find("ul").each(function(){e.menuInit($(this))}).eq(0),this.$firstLink=this.$root.find("a").eq(0),this.opts.markCurrentItem){var s=/(index|default)\.[^#\?\/]*/i,o=/#.*/,a=window.location.href.replace(s,""),n=a.replace(o,"");this.$root.find("a").each(function(){var t=this.href.replace(s,""),i=$(this);(t==a||t==n)&&(i.addClass("current"),e.opts.markCurrentTree&&i.parentsUntil("[data-smartmenus-id]","ul").each(function(){$(this).dataSM("parent-a").addClass("current")}))})}this.wasCollapsible=this.isCollapsible()},destroy:function(t){if(!t){var e=".smartmenus";this.$root.removeData("smartmenus").removeAttr("data-smartmenus-id").removeDataSM("level").off(e),e+=this.rootId,$(document).off(e),$(window).off(e),this.opts.subIndicators&&(this.$subArrow=null)}this.menuHideAll();var i=this;this.$root.find("ul").each(function(){var t=$(this);t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.dataSM("shown-before")&&((i.opts.subMenusMinWidth||i.opts.subMenusMaxWidth)&&t.css({width:"",minWidth:"",maxWidth:""}).removeClass("sm-nowrap"),t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.css({zIndex:"",top:"",left:"",marginLeft:"",marginTop:"",display:""})),0==(t.attr("id")||"").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeDataSM("in-mega").removeDataSM("shown-before").removeDataSM("scroll-arrows").removeDataSM("parent-a").removeDataSM("level").removeDataSM("beforefirstshowfired").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeAttr("aria-expanded"),this.$root.find("a.has-submenu").each(function(){var t=$(this);0==t.attr("id").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeClass("has-submenu").removeDataSM("sub").removeAttr("aria-haspopup").removeAttr("aria-controls").removeAttr("aria-expanded").closest("li").removeDataSM("sub"),this.opts.subIndicators&&this.$root.find("span.sub-arrow").remove(),this.opts.markCurrentItem&&this.$root.find("a.current").removeClass("current"),t||(this.$root=null,this.$firstLink=null,this.$firstSub=null,this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),menuTrees.splice($.inArray(this,menuTrees),1))},disable:function(t){if(!this.disabled){if(this.menuHideAll(),!t&&!this.opts.isPopup&&this.$root.is(":visible")){var e=this.$root.offset();this.$disableOverlay=$('
').css({position:"absolute",top:e.top,left:e.left,width:this.$root.outerWidth(),height:this.$root.outerHeight(),zIndex:this.getStartZIndex(!0),opacity:0}).appendTo(document.body)}this.disabled=!0}},docClick:function(t){return this.$touchScrollingSub?(this.$touchScrollingSub=null,void 0):((this.visibleSubMenus.length&&!$.contains(this.$root[0],t.target)||$(t.target).closest("a").length)&&this.menuHideAll(),void 0)},docTouchEnd:function(){if(this.lastTouch){if(!(!this.visibleSubMenus.length||void 0!==this.lastTouch.x2&&this.lastTouch.x1!=this.lastTouch.x2||void 0!==this.lastTouch.y2&&this.lastTouch.y1!=this.lastTouch.y2||this.lastTouch.target&&$.contains(this.$root[0],this.lastTouch.target))){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var t=this;this.hideTimeout=setTimeout(function(){t.menuHideAll()},350)}this.lastTouch=null}},docTouchMove:function(t){if(this.lastTouch){var e=t.originalEvent.touches[0];this.lastTouch.x2=e.pageX,this.lastTouch.y2=e.pageY}},docTouchStart:function(t){var e=t.originalEvent.touches[0];this.lastTouch={x1:e.pageX,y1:e.pageY,target:e.target}},enable:function(){this.disabled&&(this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),this.disabled=!1)},getClosestMenu:function(t){for(var e=$(t).closest("ul");e.dataSM("in-mega");)e=e.parent().closest("ul");return e[0]||null},getHeight:function(t){return this.getOffset(t,!0)},getOffset:function(t,e){var i;"none"==t.css("display")&&(i={position:t[0].style.position,visibility:t[0].style.visibility},t.css({position:"absolute",visibility:"hidden"}).show());var s=t[0].getBoundingClientRect&&t[0].getBoundingClientRect(),o=s&&(e?s.height||s.bottom-s.top:s.width||s.right-s.left);return o||0===o||(o=e?t[0].offsetHeight:t[0].offsetWidth),i&&t.hide().css(i),o},getStartZIndex:function(t){var e=parseInt(this[t?"$root":"$firstSub"].css("z-index"));return!t&&isNaN(e)&&(e=parseInt(this.$root.css("z-index"))),isNaN(e)?1:e},getTouchPoint:function(t){return t.touches&&t.touches[0]||t.changedTouches&&t.changedTouches[0]||t},getViewport:function(t){var e=t?"Height":"Width",i=document.documentElement["client"+e],s=window["inner"+e];return s&&(i=Math.min(i,s)),i},getViewportHeight:function(){return this.getViewport(!0)},getViewportWidth:function(){return this.getViewport()},getWidth:function(t){return this.getOffset(t)},handleEvents:function(){return!this.disabled&&this.isCSSOn()},handleItemEvents:function(t){return this.handleEvents()&&!this.isLinkInMegaMenu(t)},isCollapsible:function(){return"static"==this.$firstSub.css("position")},isCSSOn:function(){return"inline"!=this.$firstLink.css("display")},isFixed:function(){var t="fixed"==this.$root.css("position");return t||this.$root.parentsUntil("body").each(function(){return"fixed"==$(this).css("position")?(t=!0,!1):void 0}),t},isLinkInMegaMenu:function(t){return $(this.getClosestMenu(t[0])).hasClass("mega-menu")},isTouchMode:function(){return!mouse||this.opts.noMouseOver||this.isCollapsible()},itemActivate:function(t,e){var i=t.closest("ul"),s=i.dataSM("level");if(s>1&&(!this.activatedItems[s-2]||this.activatedItems[s-2][0]!=i.dataSM("parent-a")[0])){var o=this;$(i.parentsUntil("[data-smartmenus-id]","ul").get().reverse()).add(i).each(function(){o.itemActivate($(this).dataSM("parent-a"))})}if((!this.isCollapsible()||e)&&this.menuHideSubMenus(this.activatedItems[s-1]&&this.activatedItems[s-1][0]==t[0]?s:s-1),this.activatedItems[s-1]=t,this.$root.triggerHandler("activate.smapi",t[0])!==!1){var a=t.dataSM("sub");a&&(this.isTouchMode()||!this.opts.showOnClick||this.clickActivated)&&this.menuShow(a)}},itemBlur:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&this.$root.triggerHandler("blur.smapi",e[0])},itemClick:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(this.$touchScrollingSub&&this.$touchScrollingSub[0]==e.closest("ul")[0])return this.$touchScrollingSub=null,t.stopPropagation(),!1;if(this.$root.triggerHandler("click.smapi",e[0])===!1)return!1;var i=$(t.target).is(".sub-arrow"),s=e.dataSM("sub"),o=s?2==s.dataSM("level"):!1,a=this.isCollapsible(),n=/toggle$/.test(this.opts.collapsibleBehavior),r=/link$/.test(this.opts.collapsibleBehavior),h=/^accordion/.test(this.opts.collapsibleBehavior);if(s&&!s.is(":visible")){if((!r||!a||i)&&(this.opts.showOnClick&&o&&(this.clickActivated=!0),this.itemActivate(e,h),s.is(":visible")))return this.focusActivated=!0,!1}else if(a&&(n||i))return this.itemActivate(e,h),this.menuHide(s),n&&(this.focusActivated=!1),!1;return this.opts.showOnClick&&o||e.hasClass("disabled")||this.$root.triggerHandler("select.smapi",e[0])===!1?!1:void 0}},itemDown:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&e.dataSM("mousedown",!0)},itemEnter:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(!this.isTouchMode()){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);var i=this;this.showTimeout=setTimeout(function(){i.itemActivate(e)},this.opts.showOnClick&&1==e.closest("ul").dataSM("level")?1:this.opts.showTimeout)}this.$root.triggerHandler("mouseenter.smapi",e[0])}},itemFocus:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(!this.focusActivated||this.isTouchMode()&&e.dataSM("mousedown")||this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0]==e[0]||this.itemActivate(e,!0),this.$root.triggerHandler("focus.smapi",e[0]))},itemLeave:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(this.isTouchMode()||(e[0].blur(),this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0)),e.removeDataSM("mousedown"),this.$root.triggerHandler("mouseleave.smapi",e[0]))},menuHide:function(t){if(this.$root.triggerHandler("beforehide.smapi",t[0])!==!1&&(canAnimate&&t.stop(!0,!0),"none"!=t.css("display"))){var e=function(){t.css("z-index","")};this.isCollapsible()?canAnimate&&this.opts.collapsibleHideFunction?this.opts.collapsibleHideFunction.call(this,t,e):t.hide(this.opts.collapsibleHideDuration,e):canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,t,e):t.hide(this.opts.hideDuration,e),t.dataSM("scroll")&&(this.menuScrollStop(t),t.css({"touch-action":"","-ms-touch-action":"","-webkit-transform":"",transform:""}).off(".smartmenus_scroll").removeDataSM("scroll").dataSM("scroll-arrows").hide()),t.dataSM("parent-a").removeClass("highlighted").attr("aria-expanded","false"),t.attr({"aria-expanded":"false","aria-hidden":"true"});var i=t.dataSM("level");this.activatedItems.splice(i-1,1),this.visibleSubMenus.splice($.inArray(t,this.visibleSubMenus),1),this.$root.triggerHandler("hide.smapi",t[0])}},menuHideAll:function(){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);for(var t=this.opts.isPopup?1:0,e=this.visibleSubMenus.length-1;e>=t;e--)this.menuHide(this.visibleSubMenus[e]);this.opts.isPopup&&(canAnimate&&this.$root.stop(!0,!0),this.$root.is(":visible")&&(canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,this.$root):this.$root.hide(this.opts.hideDuration))),this.activatedItems=[],this.visibleSubMenus=[],this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.$root.triggerHandler("hideAll.smapi")},menuHideSubMenus:function(t){for(var e=this.activatedItems.length-1;e>=t;e--){var i=this.activatedItems[e].dataSM("sub");i&&this.menuHide(i)}},menuInit:function(t){if(!t.dataSM("in-mega")){t.hasClass("mega-menu")&&t.find("ul").dataSM("in-mega",!0);for(var e=2,i=t[0];(i=i.parentNode.parentNode)!=this.$root[0];)e++;var s=t.prevAll("a").eq(-1);s.length||(s=t.prevAll().find("a").eq(-1)),s.addClass("has-submenu").dataSM("sub",t),t.dataSM("parent-a",s).dataSM("level",e).parent().dataSM("sub",t);var o=s.attr("id")||this.accessIdPrefix+ ++this.idInc,a=t.attr("id")||this.accessIdPrefix+ ++this.idInc;s.attr({id:o,"aria-haspopup":"true","aria-controls":a,"aria-expanded":"false"}),t.attr({id:a,role:"group","aria-hidden":"true","aria-labelledby":o,"aria-expanded":"false"}),this.opts.subIndicators&&s[this.opts.subIndicatorsPos](this.$subArrow.clone())}},menuPosition:function(t){var e,i,s=t.dataSM("parent-a"),o=s.closest("li"),a=o.parent(),n=t.dataSM("level"),r=this.getWidth(t),h=this.getHeight(t),u=s.offset(),l=u.left,c=u.top,d=this.getWidth(s),m=this.getHeight(s),p=$(window),f=p.scrollLeft(),v=p.scrollTop(),b=this.getViewportWidth(),S=this.getViewportHeight(),g=a.parent().is("[data-sm-horizontal-sub]")||2==n&&!a.hasClass("sm-vertical"),M=this.opts.rightToLeftSubMenus&&!o.is("[data-sm-reverse]")||!this.opts.rightToLeftSubMenus&&o.is("[data-sm-reverse]"),w=2==n?this.opts.mainMenuSubOffsetX:this.opts.subMenusSubOffsetX,T=2==n?this.opts.mainMenuSubOffsetY:this.opts.subMenusSubOffsetY;if(g?(e=M?d-r-w:w,i=this.opts.bottomToTopSubMenus?-h-T:m+T):(e=M?w-r:d-w,i=this.opts.bottomToTopSubMenus?m-T-h:T),this.opts.keepInViewport){var y=l+e,I=c+i;if(M&&f>y?e=g?f-y+e:d-w:!M&&y+r>f+b&&(e=g?f+b-r-y+e:w-r),g||(S>h&&I+h>v+S?i+=v+S-h-I:(h>=S||v>I)&&(i+=v-I)),g&&(I+h>v+S+.49||v>I)||!g&&h>S+.49){var x=this;t.dataSM("scroll-arrows")||t.dataSM("scroll-arrows",$([$('')[0],$('')[0]]).on({mouseenter:function(){t.dataSM("scroll").up=$(this).hasClass("scroll-up"),x.menuScroll(t)},mouseleave:function(e){x.menuScrollStop(t),x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(t){t.preventDefault()}}).insertAfter(t));var A=".smartmenus_scroll";if(t.dataSM("scroll",{y:this.cssTransforms3d?0:i-m,step:1,itemH:m,subH:h,arrowDownH:this.getHeight(t.dataSM("scroll-arrows").eq(1))}).on(getEventsNS({mouseover:function(e){x.menuScrollOver(t,e)},mouseout:function(e){x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(e){x.menuScrollMousewheel(t,e)}},A)).dataSM("scroll-arrows").css({top:"auto",left:"0",marginLeft:e+(parseInt(t.css("border-left-width"))||0),width:r-(parseInt(t.css("border-left-width"))||0)-(parseInt(t.css("border-right-width"))||0),zIndex:t.css("z-index")}).eq(g&&this.opts.bottomToTopSubMenus?0:1).show(),this.isFixed()){var C={};C[touchEvents?"touchstart touchmove touchend":"pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp"]=function(e){x.menuScrollTouch(t,e)},t.css({"touch-action":"none","-ms-touch-action":"none"}).on(getEventsNS(C,A))}}}t.css({top:"auto",left:"0",marginLeft:e,marginTop:i-m})},menuScroll:function(t,e,i){var s,o=t.dataSM("scroll"),a=t.dataSM("scroll-arrows"),n=o.up?o.upEnd:o.downEnd;if(!e&&o.momentum){if(o.momentum*=.92,s=o.momentum,.5>s)return this.menuScrollStop(t),void 0}else s=i||(e||!this.opts.scrollAccelerate?this.opts.scrollStep:Math.floor(o.step));var r=t.dataSM("level");if(this.activatedItems[r-1]&&this.activatedItems[r-1].dataSM("sub")&&this.activatedItems[r-1].dataSM("sub").is(":visible")&&this.menuHideSubMenus(r-1),o.y=o.up&&o.y>=n||!o.up&&n>=o.y?o.y:Math.abs(n-o.y)>s?o.y+(o.up?s:-s):n,t.css(this.cssTransforms3d?{"-webkit-transform":"translate3d(0, "+o.y+"px, 0)",transform:"translate3d(0, "+o.y+"px, 0)"}:{marginTop:o.y}),mouse&&(o.up&&o.y>o.downEnd||!o.up&&o.y0;t.dataSM("scroll-arrows").eq(i?0:1).is(":visible")&&(t.dataSM("scroll").up=i,this.menuScroll(t,!0))}e.preventDefault()},menuScrollOut:function(t,e){mouse&&(/^scroll-(up|down)/.test((e.relatedTarget||"").className)||(t[0]==e.relatedTarget||$.contains(t[0],e.relatedTarget))&&this.getClosestMenu(e.relatedTarget)==t[0]||t.dataSM("scroll-arrows").css("visibility","hidden"))},menuScrollOver:function(t,e){if(mouse&&!/^scroll-(up|down)/.test(e.target.className)&&this.getClosestMenu(e.target)==t[0]){this.menuScrollRefreshData(t);var i=t.dataSM("scroll"),s=$(window).scrollTop()-t.dataSM("parent-a").offset().top-i.itemH;t.dataSM("scroll-arrows").eq(0).css("margin-top",s).end().eq(1).css("margin-top",s+this.getViewportHeight()-i.arrowDownH).end().css("visibility","visible")}},menuScrollRefreshData:function(t){var e=t.dataSM("scroll"),i=$(window).scrollTop()-t.dataSM("parent-a").offset().top-e.itemH;this.cssTransforms3d&&(i=-(parseFloat(t.css("margin-top"))-i)),$.extend(e,{upEnd:i,downEnd:i+this.getViewportHeight()-e.subH})},menuScrollStop:function(t){return this.scrollTimeout?(cancelAnimationFrame(this.scrollTimeout),this.scrollTimeout=0,t.dataSM("scroll").step=1,!0):void 0},menuScrollTouch:function(t,e){if(e=e.originalEvent,isTouchEvent(e)){var i=this.getTouchPoint(e);if(this.getClosestMenu(i.target)==t[0]){var s=t.dataSM("scroll");if(/(start|down)$/i.test(e.type))this.menuScrollStop(t)?(e.preventDefault(),this.$touchScrollingSub=t):this.$touchScrollingSub=null,this.menuScrollRefreshData(t),$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp});else if(/move$/i.test(e.type)){var o=void 0!==s.touchY?s.touchY:s.touchStartY;if(void 0!==o&&o!=i.pageY){this.$touchScrollingSub=t;var a=i.pageY>o;void 0!==s.up&&s.up!=a&&$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp}),$.extend(s,{up:a,touchY:i.pageY}),this.menuScroll(t,!0,Math.abs(i.pageY-o))}e.preventDefault()}else void 0!==s.touchY&&((s.momentum=15*Math.pow(Math.abs(i.pageY-s.touchStartY)/(e.timeStamp-s.touchStartTime),2))&&(this.menuScrollStop(t),this.menuScroll(t),e.preventDefault()),delete s.touchY)}}},menuShow:function(t){if((t.dataSM("beforefirstshowfired")||(t.dataSM("beforefirstshowfired",!0),this.$root.triggerHandler("beforefirstshow.smapi",t[0])!==!1))&&this.$root.triggerHandler("beforeshow.smapi",t[0])!==!1&&(t.dataSM("shown-before",!0),canAnimate&&t.stop(!0,!0),!t.is(":visible"))){var e=t.dataSM("parent-a"),i=this.isCollapsible();if((this.opts.keepHighlighted||i)&&e.addClass("highlighted"),i)t.removeClass("sm-nowrap").css({zIndex:"",width:"auto",minWidth:"",maxWidth:"",top:"",left:"",marginLeft:"",marginTop:""});else{if(t.css("z-index",this.zIndexInc=(this.zIndexInc||this.getStartZIndex())+1),(this.opts.subMenusMinWidth||this.opts.subMenusMaxWidth)&&(t.css({width:"auto",minWidth:"",maxWidth:""}).addClass("sm-nowrap"),this.opts.subMenusMinWidth&&t.css("min-width",this.opts.subMenusMinWidth),this.opts.subMenusMaxWidth)){var s=this.getWidth(t);t.css("max-width",this.opts.subMenusMaxWidth),s>this.getWidth(t)&&t.removeClass("sm-nowrap").css("width",this.opts.subMenusMaxWidth)}this.menuPosition(t)}var o=function(){t.css("overflow","")};i?canAnimate&&this.opts.collapsibleShowFunction?this.opts.collapsibleShowFunction.call(this,t,o):t.show(this.opts.collapsibleShowDuration,o):canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,t,o):t.show(this.opts.showDuration,o),e.attr("aria-expanded","true"),t.attr({"aria-expanded":"true","aria-hidden":"false"}),this.visibleSubMenus.push(t),this.$root.triggerHandler("show.smapi",t[0])}},popupHide:function(t){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},t?1:this.opts.hideTimeout)},popupShow:function(t,e){if(!this.opts.isPopup)return alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'),void 0;if(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),this.$root.dataSM("shown-before",!0),canAnimate&&this.$root.stop(!0,!0),!this.$root.is(":visible")){this.$root.css({left:t,top:e});var i=this,s=function(){i.$root.css("overflow","")};canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,this.$root,s):this.$root.show(this.opts.showDuration,s),this.visibleSubMenus[0]=this.$root}},refresh:function(){this.destroy(!0),this.init(!0)},rootKeyDown:function(t){if(this.handleEvents())switch(t.keyCode){case 27:var e=this.activatedItems[0];if(e){this.menuHideAll(),e[0].focus();var i=e.dataSM("sub");i&&this.menuHide(i)}break;case 32:var s=$(t.target);if(s.is("a")&&this.handleItemEvents(s)){var i=s.dataSM("sub");i&&!i.is(":visible")&&(this.itemClick({currentTarget:t.target}),t.preventDefault())}}},rootOut:function(t){if(this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),!this.opts.showOnClick||!this.opts.hideOnClick)){var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},this.opts.hideTimeout)}},rootOver:function(t){this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0)},winResize:function(t){if(this.handleEvents()){if(!("onorientationchange"in window)||"orientationchange"==t.type){var e=this.isCollapsible();this.wasCollapsible&&e||(this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0].blur(),this.menuHideAll()),this.wasCollapsible=e}}else if(this.$disableOverlay){var i=this.$root.offset();this.$disableOverlay.css({top:i.top,left:i.left,width:this.$root.outerWidth(),height:this.$root.outerHeight()})}}}}),$.fn.dataSM=function(t,e){return e?this.data(t+"_smartmenus",e):this.data(t+"_smartmenus")},$.fn.removeDataSM=function(t){return this.removeData(t+"_smartmenus")},$.fn.smartmenus=function(options){if("string"==typeof options){var args=arguments,method=options;return Array.prototype.shift.call(args),this.each(function(){var t=$(this).data("smartmenus");t&&t[method]&&t[method].apply(t,args)})}return this.each(function(){var dataOpts=$(this).data("sm-options")||null;if(dataOpts)try{dataOpts=eval("("+dataOpts+")")}catch(e){dataOpts=null,alert('ERROR\n\nSmartMenus jQuery init:\nInvalid "data-sm-options" attribute value syntax.')}new $.SmartMenus(this,$.extend({},$.fn.smartmenus.defaults,options,dataOpts))})},$.fn.smartmenus.defaults={isPopup:!1,mainMenuSubOffsetX:0,mainMenuSubOffsetY:0,subMenusSubOffsetX:0,subMenusSubOffsetY:0,subMenusMinWidth:"10em",subMenusMaxWidth:"20em",subIndicators:!0,subIndicatorsPos:"append",subIndicatorsText:"",scrollStep:30,scrollAccelerate:!0,showTimeout:250,hideTimeout:500,showDuration:0,showFunction:null,hideDuration:0,hideFunction:function(t,e){t.fadeOut(200,e)},collapsibleShowDuration:0,collapsibleShowFunction:function(t,e){t.slideDown(200,e)},collapsibleHideDuration:0,collapsibleHideFunction:function(t,e){t.slideUp(200,e)},showOnClick:!1,hideOnClick:!0,noMouseOver:!1,keepInViewport:!0,keepHighlighted:!0,markCurrentItem:!1,markCurrentTree:!0,rightToLeftSubMenus:!1,bottomToTopSubMenus:!1,collapsibleBehavior:"default"},$}); \ No newline at end of file diff --git a/v1.3.0/modules.html b/v1.3.0/modules.html new file mode 100644 index 00000000..b1fd7efe --- /dev/null +++ b/v1.3.0/modules.html @@ -0,0 +1,119 @@ + + + + + + + +coreMQTT Agent: Data types and Constants + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Data types and Constants
+
+
+
This library defines the following data types and constants.
+ + + + +
 Enumerated TypesEnumerated types of the MQTT Agent
 Callback TypesCallback function pointer types of the MQTT Agent
 Parameter StructuresStructures passed as parameters to MQTT Agent functions
+
+
+
+ + + + diff --git a/v1.3.0/modules.js b/v1.3.0/modules.js new file mode 100644 index 00000000..77297ed1 --- /dev/null +++ b/v1.3.0/modules.js @@ -0,0 +1,6 @@ +var modules = +[ + [ "Enumerated Types", "group__mqtt__agent__enum__types.html", "group__mqtt__agent__enum__types" ], + [ "Callback Types", "group__mqtt__agent__callback__types.html", "group__mqtt__agent__callback__types" ], + [ "Parameter Structures", "group__mqtt__agent__struct__types.html", "group__mqtt__agent__struct__types" ] +]; \ No newline at end of file diff --git a/v1.3.0/mqtt_agent_cancel_function.html b/v1.3.0/mqtt_agent_cancel_function.html new file mode 100644 index 00000000..be68e84d --- /dev/null +++ b/v1.3.0/mqtt_agent_cancel_function.html @@ -0,0 +1,146 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_CancelAll + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_CancelAll
+
+
+
+
MQTTStatus_t MQTTAgent_CancelAll(MQTTAgentContext_t *pMqttAgentContext)
Cancel all enqueued commands and those awaiting acknowledgment while the command loop is not running.
Definition: core_mqtt_agent.c:1128
+
MQTTStatus_t
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+

Cancel all enqueued commands and those awaiting acknowledgment while the command loop is not running.

+

Canceled commands will be terminated with return code MQTTRecvFailed.

+
Parameters
+ + +
[in]pMqttAgentContextThe MQTT agent to use.
+
+
+
Note
This function is NOT thread-safe and should only be called from the context of the task responsible for MQTTAgent_CommandLoop.
+
Returns
MQTTBadParameter if an invalid context is given, else MQTTSuccess.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTAgentContext_t mqttAgentContext;
+
+
status = MQTTAgent_CommandLoop( &mqttAgentContext );
+
+
//An error was returned, but reconnection is not desired. Cancel all commands
+
//that are in the queue or awaiting an acknowledgment.
+
if( status != MQTTSuccess )
+
{
+
//Cancel commands so any completion callbacks will be invoked.
+
status = MQTTAgent_CancelAll( &mqttAgentContext );
+
}
+
+
Platform_DisconnectNetwork( mqttAgentContext.mqttContext.transportInterface.pNetworkContext );
+
MQTTStatus_t MQTTAgent_CommandLoop(MQTTAgentContext_t *pMqttAgentContext)
Process commands from the command queue in a loop.
Definition: core_mqtt_agent.c:1043
+
MQTTContext_t mqttContext
Definition: core_mqtt_agent.h:154
+
TransportInterface_t transportInterface
+
NetworkContext_t * pNetworkContext
+
+
+
+ + + + diff --git a/v1.3.0/mqtt_agent_command_function.html b/v1.3.0/mqtt_agent_command_function.html new file mode 100644 index 00000000..c8d3df2a --- /dev/null +++ b/v1.3.0/mqtt_agent_command_function.html @@ -0,0 +1,156 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_CommandLoop + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_CommandLoop
+
+
+
+
MQTTStatus_t MQTTAgent_CommandLoop(MQTTAgentContext_t *pMqttAgentContext)
Process commands from the command queue in a loop.
Definition: core_mqtt_agent.c:1043
+
MQTTStatus_t
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+

Process commands from the command queue in a loop.

+
Parameters
+ + +
[in]pMqttAgentContextThe MQTT agent to use.
+
+
+
Returns
appropriate error code, or MQTTSuccess from a successful disconnect or termination.
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTAgentContext_t mqttAgentContext;
+
+
status = MQTTAgent_CommandLoop( &mqttAgentContext );
+
+
// The function returns on either receiving a terminate command,
+
// undergoing network disconnection OR encountering an error.
+
if( ( status == MQTTSuccess ) && ( mqttAgentContext.mqttContext.connectStatus == MQTTNotConnected ) )
+
{
+
// A terminate command was processed and MQTT connection was closed.
+
// Need to close socket connection.
+
Platform_DisconnectNetwork( mqttAgentContext.mqttContext.transportInterface.pNetworkContext );
+
}
+
else if( status == MQTTSuccess )
+
{
+
// Terminate command was processed but MQTT connection was not
+
// closed. Thus, need to close both MQTT and socket connections.
+
status = MQTT_Disconnect( &( mqttAgentContext.mqttContext ) );
+
assert( status == MQTTSuccess );
+
Platform_DisconnectNetwork( mqttAgentContext.mqttContext.transportInterface.pNetworkContext );
+
}
+
else
+
{
+
// Handle error.
+
}
+
MQTTStatus_t MQTT_Disconnect(MQTTContext_t *pContext)
+
MQTTContext_t mqttContext
Definition: core_mqtt_agent.h:154
+
MQTTConnectionStatus_t connectStatus
+
TransportInterface_t transportInterface
+
NetworkContext_t * pNetworkContext
+
+
+
+ + + + diff --git a/v1.3.0/mqtt_agent_connect_function.html b/v1.3.0/mqtt_agent_connect_function.html new file mode 100644 index 00000000..a93ccf29 --- /dev/null +++ b/v1.3.0/mqtt_agent_connect_function.html @@ -0,0 +1,211 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_Connect + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_Connect
+
+
+
+
MQTTAgentConnectArgs_t * pConnectArgs,
+
const MQTTAgentCommandInfo_t * pCommandInfo );
+
MQTTStatus_t MQTTAgent_Connect(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentConnectArgs_t *pConnectArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Connect() for an MQTT connection. If a session is resumed with the broker,...
Definition: core_mqtt_agent.c:1275
+
MQTTStatus_t
+
Struct holding arguments that are common to every command.
Definition: core_mqtt_agent.h:189
+
Struct holding arguments for a CONNECT call.
Definition: core_mqtt_agent.h:177
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+

Add a command to call MQTT_Connect() for an MQTT connection. If a session is resumed with the broker, it will also resend the necessary QoS1/2 publishes.

+
Note
The MQTTAgent_Connect function is provided to give a thread safe equivalent to the MQTT_Connect API. However, it is RECOMMENDED that instead of the application tasks (i.e. tasks other than the agent task), the agent be responsible for creating the MQTT connection (by calling MQTT_Connect) before starting the command loop (with the MQTTAgent_CommandLoop() call). In that case, the agent SHOULD also be responsible for disconnecting the MQTT connection after the command loop has terminated (through an MQTTAgent_Terminate() call from an application task).
+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in,out]pConnectArgsStruct holding args for MQTT_Connect(). On a successful connection after the command is processed, the sessionPresent member will be filled to indicate whether the broker resumed an existing session.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
MQTTAgentConnectArgs_t connectionArgs;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// True for creating a new session with broker, false if we want to resume an old one.
+
connectInfo.cleanSession = true;
+
// Client ID must be unique to broker. This field is required.
+
connectInfo.pClientIdentifier = "someClientID";
+
connectInfo.clientIdentifierLength = strlen( connectInfo.pClientIdentifier );
+
+
// Value for keep alive.
+
connectInfo.keepAliveSeconds = 60;
+
// The following fields are optional.
+
// Optional username and password.
+
connectInfo.pUserName = "someUserName";
+
connectInfo.userNameLength = strlen( connectInfo.pUserName );
+
connectInfo.pPassword = "somePassword";
+
connectInfo.passwordLength = strlen( connectInfo.pPassword );
+
+
// The last will and testament is optional, it will be published by the broker
+
// should this client disconnect without sending a DISCONNECT packet.
+
willInfo.qos = MQTTQoS0;
+
willInfo.pTopicName = "/lwt/topic/name";
+
willInfo.topicNameLength = strlen( willInfo.pTopicName );
+
willInfo.pPayload = "LWT Message";
+
willInfo.payloadLength = strlen( "LWT Message" );
+
+
// Fill the MQTTAgentConnectArgs_t structure.
+
connectArgs.pConnectInfo = &connectInfo;
+
connectArgs.pWillInfo = &willInfo;
+
// Time to block for CONNACK response when command is processed.
+
connectArgs.timeoutMs = 500;
+
+
// Function for command complete callback.
+
void connectCmdCallback( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = connectCmdCallback;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Connect( &agentContext, &connectArgs, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command for creating the MQTT connection has been queued.
+
// The MQTT connection event will be notified through the
+
// invocation of connectCmdCallback().
+
}
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
MQTTQoS0
+
MQTTAgentCommandCallback_t cmdCompleteCallback
Callback to invoke upon completion.
Definition: core_mqtt_agent.h:190
+
uint32_t blockTimeMs
Maximum block time for enqueueing the command.
Definition: core_mqtt_agent.h:192
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+ +
const char * pClientIdentifier
+
const char * pUserName
+ +
uint16_t userNameLength
+
uint16_t keepAliveSeconds
+
uint16_t clientIdentifierLength
+
uint16_t passwordLength
+
const char * pPassword
+ + +
uint16_t topicNameLength
+ +
const char * pTopicName
+
const void * pPayload
+
+
+
+ + + + diff --git a/v1.3.0/mqtt_agent_design.html b/v1.3.0/mqtt_agent_design.html new file mode 100644 index 00000000..35344ca0 --- /dev/null +++ b/v1.3.0/mqtt_agent_design.html @@ -0,0 +1,180 @@ + + + + + + + +coreMQTT Agent: Design + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Design
+
+
+

Architecture of the MQTT Agent library.

+

+Thread Safe and Unsafe APIs

+

The MQTT Agent APIs are designed to be used by two types of tasks:

+

+Interfaces and Callbacks

+

Similar to coreMQTT, the MQTT Agent library relies on interfaces to dissociate itself from platform specific functionality. Interfaces used by the MQTT Agent library are simply function pointers with expectations of behavior.

+

The MQTT Agent library expects the application to provide implementations for the following interfaces:

+ + + + + + + + + + + + + +
Function Pointer Use
MQTTAgentMessageRecv_t Receiving commands sent to the agent task.
MQTTAgentMessageSend_t Sending commands to the agent task from the application
MQTTAgentCommandGet_t Allocating storage for a command to be sent to the agent task.
MQTTAgentCommandRelease_t Releasing a command obtained from MQTTAgentCommandGet_t.
MQTTAgentIncomingPublishCallback_t Accepting incoming publish messages, with the possibility of further distributing them to other tasks.
+

+Command Completion

+

Commands do not have any timeout associated with them. The only way for a task to be aware of a command's completion is through the invocation of an optional MQTTAgentCommandCallback_t completion callback. The completion callback will be invoked with an optional MQTTAgentCommandContext_t, which is the incomplete type struct MQTTAgentCommandContext. This type must be defined by the application, and should contain information that would be useful in distinguishing commands.
+ Example code:

struct MQTTAgentCommandContext
+
{
+
//Allow the calling thread to view the return code by copying it here.
+
MQTTStatus_t returnCode;
+
//pthread mutex and condition variables to signal to the thread that created the command.
+
pthread_mutex_t lock;
+
pthread_cond_t cond;
+
};
+
MQTTStatus_t
+


+ The completion callback using such a context could be:

void commandCompleteCallback( MQTTAgentCommandContext_t * pCmdContext, MQTTAgentReturnInfo_t * pReturnInfo )
+
{
+
pthread_mutex_lock( &( pCmdContext->lock ) );
+
//Set return code so the thread that created the command can view.
+
pCmdContext->returnCode = pReturnInfo->returnCode;
+
pthread_mutex_unlock( &( pCmdContext->lock ) );
+
//Signal the thread using the condition variable.
+
pthread_cond_broadcast( &( pCmdContext->cond ) );
+
}
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+
MQTTStatus_t returnCode
Definition: core_mqtt_agent.h:72
+


+ The completion callback and completion context are each optional, and passed at time of command creation in the MQTTAgentCommandInfo_t parameter. If a command completion context is passed, it MUST remain in scope until the completion callback has been invoked.

+
+
+
+ + + + diff --git a/v1.3.0/mqtt_agent_disconnect_function.html b/v1.3.0/mqtt_agent_disconnect_function.html new file mode 100644 index 00000000..dc4b71b3 --- /dev/null +++ b/v1.3.0/mqtt_agent_disconnect_function.html @@ -0,0 +1,162 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_Disconnect + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_Disconnect
+
+
+
+
const MQTTAgentCommandInfo_t * pCommandInfo );
+
MQTTStatus_t MQTTAgent_Disconnect(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to disconnect an MQTT connection.
Definition: core_mqtt_agent.c:1300
+
MQTTStatus_t
+
Struct holding arguments that are common to every command.
Definition: core_mqtt_agent.h:189
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+

Add a command to disconnect an MQTT connection.

+
Note
MQTTAgent_CommandLoop will return after processing a DISCONNECT command to allow the network connection to be disconnected. However, any pending commands in the queue, as well as those waiting for an acknowledgment, will NOT be terminated.
+
+The MQTTAgent_Disconnect function is provided to give a thread safe equivalent to the MQTT_Disconnect API. However, if the agent task is responsible for creating the MQTT connection (before calling MQTTAgent_CommandLoop()), then it is RECOMMENDED that an application task (i.e. a task other than the agent task) use MQTTAgent_Terminate to terminate the command loop in the agent, and the agent task be responsible for disconnecting the MQTT connection.
+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void disconnectCmdCallback( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = disconnectCmdCallback;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Disconnect( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command for closing the MQTT connection has been queued.
+
// The MQTT disconnection event will be notified through the
+
// invocation of disconnectCmdCallback().
+
}
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
MQTTAgentCommandCallback_t cmdCompleteCallback
Callback to invoke upon completion.
Definition: core_mqtt_agent.h:190
+
uint32_t blockTimeMs
Maximum block time for enqueueing the command.
Definition: core_mqtt_agent.h:192
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+
+
+
+ + + + diff --git a/v1.3.0/mqtt_agent_functions.html b/v1.3.0/mqtt_agent_functions.html new file mode 100644 index 00000000..384f1797 --- /dev/null +++ b/v1.3.0/mqtt_agent_functions.html @@ -0,0 +1,138 @@ + + + + + + + +coreMQTT Agent: Functions + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Functions
+
+
+

Functions of the MQTT Agent library<br>
+

+

+Thread Unsafe Functions

+

These functions are not thread safe and are designed to be used only by an MQTT agent task - a task dedicated to interfacing with the coreMQTT API.
+
+ MQTTAgent_Init
+ MQTTAgent_CommandLoop
+ MQTTAgent_ResumeSession
+ MQTTAgent_CancelAll
+
+

+

+Thread Safe Functions

+

These functions are thread safe and designed to be used by any application task (one that is not the MQTT agent task).
+
+ MQTTAgent_Publish
+ MQTTAgent_Subscribe
+ MQTTAgent_Unsubscribe
+ MQTTAgent_Connect
+ MQTTAgent_Disconnect
+ MQTTAgent_Ping
+ MQTTAgent_Terminate
+
+

+
+
+
+ + + + diff --git a/v1.3.0/mqtt_agent_functions.js b/v1.3.0/mqtt_agent_functions.js new file mode 100644 index 00000000..6deeb7ca --- /dev/null +++ b/v1.3.0/mqtt_agent_functions.js @@ -0,0 +1,16 @@ +var mqtt_agent_functions = +[ + [ "Thread Unsafe Functions", "mqtt_agent_functions.html#mqtt_agent_thread_unsafe_functions", null ], + [ "Thread Safe Functions", "mqtt_agent_functions.html#mqtt_agent_thread_safe_functions", null ], + [ "MQTTAgent_Init", "mqtt_agent_init_function.html", null ], + [ "MQTTAgent_CommandLoop", "mqtt_agent_command_function.html", null ], + [ "MQTTAgent_ResumeSession", "mqtt_agent_resume_function.html", null ], + [ "MQTTAgent_CancelAll", "mqtt_agent_cancel_function.html", null ], + [ "MQTTAgent_Publish", "mqtt_agent_publish_function.html", null ], + [ "MQTTAgent_Subscribe", "mqtt_agent_subscribe_function.html", null ], + [ "MQTTAgent_Unsubscribe", "mqtt_agent_unsubscribe_function.html", null ], + [ "MQTTAgent_Connect", "mqtt_agent_connect_function.html", null ], + [ "MQTTAgent_Disconnect", "mqtt_agent_disconnect_function.html", null ], + [ "MQTTAgent_Ping", "mqtt_agent_ping_function.html", null ], + [ "MQTTAgent_Terminate", "mqtt_agent_terminate_function.html", null ] +]; \ No newline at end of file diff --git a/v1.3.0/mqtt_agent_init_function.html b/v1.3.0/mqtt_agent_init_function.html new file mode 100644 index 00000000..11b3c80c --- /dev/null +++ b/v1.3.0/mqtt_agent_init_function.html @@ -0,0 +1,219 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_Init + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_Init
+
+
+
+
const MQTTAgentMessageInterface_t * pMsgInterface,
+
const MQTTFixedBuffer_t * pNetworkBuffer,
+
const TransportInterface_t * pTransportInterface,
+
MQTTGetCurrentTimeFunc_t getCurrentTimeMs,
+ +
void * pIncomingPacketContext );
+
MQTTStatus_t MQTTAgent_Init(MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentMessageInterface_t *pMsgInterface, const MQTTFixedBuffer_t *pNetworkBuffer, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getCurrentTimeMs, MQTTAgentIncomingPublishCallback_t incomingCallback, void *pIncomingPacketContext)
Perform any initialization the MQTT agent requires before it can be used. Must be called before any o...
Definition: core_mqtt_agent.c:968
+
void(* MQTTAgentIncomingPublishCallback_t)(struct MQTTAgentContext *pMqttAgentContext, uint16_t packetId, MQTTPublishInfo_t *pPublishInfo)
Callback function called when receiving a publish.
Definition: core_mqtt_agent.h:142
+
MQTTStatus_t
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+
Function pointers and contexts used for sending and receiving commands, and allocating memory for the...
Definition: core_mqtt_agent_message_interface.h:133
+ + +

Perform any initialization the MQTT agent requires before it can be used. Must be called before any other function.

+
Parameters
+ + + + + + + + +
[in]pMqttAgentContextPointer to struct to initialize.
[in]pMsgInterfaceCommand interface to use for allocating and sending commands.
[in]pNetworkBufferPointer to network buffer to use.
[in]pTransportInterfaceTransport interface to use with the MQTT library. See https://www.freertos.org/Documentation/03-Libraries/03-FreeRTOS-core/06-Transport-Interface/01-Transport-interface
[in]getCurrentTimeMsPointer to a function that returns a count value that increments every millisecond.
[in]incomingCallbackThe callback to execute when receiving publishes.
[in]pIncomingPacketContextA pointer to a context structure defined by the application writer.
+
+
+
Note
The pIncomingPacketContext context provided for the incoming publish callback MUST remain in scope throughout the period that the agent task is running.
+
Returns
Appropriate status code from MQTT_Init().
+

Example

// Function for obtaining a timestamp.
+
uint32_t getTimeStampMs();
+
// Callback function for receiving packets.
+
void incomingPublishCallback( MQTTAgentContext_t * pMqttAgentContext,
+
uint16_t packetId,
+
MQTTPublishInfo_t * pPublishInfo );
+
// Platform function for network send interface.
+
int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
+
// Platform for network receive interface.
+
int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
+
+
// Platform function for Agent Message Send.
+
bool agentSendMessage( MQTTAgentMessageContext_t * pMsgCtx,
+
MQTTAgentCommand_t * const * pCommandToSend,
+
uint32_t blockTimeMs );
+
// Platform function for Agent Message Receive.
+
bool agentReceiveMessage( MQTTAgentMessageContext_t * pMsgCtx,
+
MQTTAgentCommand_t ** pCommandToSend,
+
uint32_t blockTimeMs );
+
// Platform function to Get Agent Command.
+
MQTTAgentCommand_t * getCommand( uint32_t blockTimeMs );
+
// Platform function to Release Agent Command.
+
bool releaseCommand( MQTTAgentCommand_t * pCommandToRelease );
+
+
// Variables used in this example.
+
MQTTAgentMessageInterface_t messageInterface;
+ +
MQTTAgentContext_t agentContext;
+ +
// Buffer for storing outgoing and incoming MQTT packets.
+
MQTTFixedBuffer_t fixedBuffer;
+
uint8_t buffer[ 1024 ];
+
MQTTStatus_t status;
+
+
// Set transport interface members.
+
transport.pNetworkContext = &someTransportContext;
+
transport.send = networkSend;
+
transport.recv = networkRecv;
+
+
// Set agent message interface members.
+
messageInterface.pMsgCtx = &messageContext;
+
messageInterface.send = agentSendMessage;
+
messageInterface.recv = agentReceiveMessage;
+
messageInterface.getCommand = getCommand;
+
messageInterface.releaseCommand = releaseCommand;
+
+
// Set buffer members.
+
fixedBuffer.pBuffer = buffer;
+
fixedBuffer.size = 1024;
+
+
status = MQTTAgent_Init( &agentContext,
+
&messageInterface,
+
&networkBuffer,
+
&transportInterface,
+
stubGetTime,
+
stubPublishCallback,
+
incomingPacketContext );
+
+
if( status == MQTTSuccess )
+
{
+
// Do something with agentContext. The transport and message interfaces, and
+
// fixedBuffer structs were copied into the context, so the original structs
+
// do not need to stay in scope.
+
}
+
struct MQTTAgentMessageContext MQTTAgentMessageContext_t
Context with which tasks may deliver messages to the agent.
Definition: core_mqtt_agent_message_interface.h:54
+
struct NetworkContext NetworkContext_t
+
MQTTAgentMessageContext_t * pMsgCtx
Definition: core_mqtt_agent_message_interface.h:134
+
MQTTAgentMessageRecv_t recv
Definition: core_mqtt_agent_message_interface.h:136
+
MQTTAgentCommandGet_t getCommand
Definition: core_mqtt_agent_message_interface.h:137
+
MQTTAgentMessageSend_t send
Definition: core_mqtt_agent_message_interface.h:135
+
MQTTAgentCommandRelease_t releaseCommand
Definition: core_mqtt_agent_message_interface.h:138
+ + + +
TransportSend_t send
+
TransportRecv_t recv
+
NetworkContext_t * pNetworkContext
+
+
+
+ + + + diff --git a/v1.3.0/mqtt_agent_message_interface.html b/v1.3.0/mqtt_agent_message_interface.html new file mode 100644 index 00000000..1a72dd48 --- /dev/null +++ b/v1.3.0/mqtt_agent_message_interface.html @@ -0,0 +1,239 @@ + + + + + + + +coreMQTT Agent: Message Interface + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Message Interface
+
+
+

Messaging interface used by the MQTT Agent.
+
+

+

+Message Interface Overview

+

The message interface is a set of APIs to send MQTT Agent commands from application tasks to the MQTT agent task, as well as functions to allocate and release storage for these commands. It must be implemented with thread safety, as multiple tasks can send commands concurrently. The message interface is defined in core_mqtt_agent_message_interface.h.
+

+

The functions that must be implemented are:
+

+

The send and receive functions take in an opaque context MQTTAgentMessageContext_t. The functions above and the context are grouped together in the MQTTAgentMessageInterface_t structure:
+

typedef struct MQTTAgentMessageInterface
+
{
+ + + +
MQTTAgentCommandGet_t getCommand;
+
MQTTAgentCommandRelease_t releaseCommand;
+ +
MQTTAgentCommand_t *(* MQTTAgentCommandGet_t)(uint32_t blockTimeMs)
Obtain a MQTTAgentCommand_t structure.
Definition: core_mqtt_agent_message_interface.h:105
+
bool(* MQTTAgentMessageSend_t)(MQTTAgentMessageContext_t *pMsgCtx, MQTTAgentCommand_t *const *pCommandToSend, uint32_t blockTimeMs)
Send a message to the specified context. Must be thread safe.
Definition: core_mqtt_agent_message_interface.h:68
+
bool(* MQTTAgentCommandRelease_t)(MQTTAgentCommand_t *pCommandToRelease)
Give a MQTTAgentCommand_t structure back to the application.
Definition: core_mqtt_agent_message_interface.h:123
+
bool(* MQTTAgentMessageRecv_t)(MQTTAgentMessageContext_t *pMsgCtx, MQTTAgentCommand_t **pReceivedCommand, uint32_t blockTimeMs)
Receive a message from the specified context. Must be thread safe.
Definition: core_mqtt_agent_message_interface.h:84
+
struct MQTTAgentMessageContext MQTTAgentMessageContext_t
Context with which tasks may deliver messages to the agent.
Definition: core_mqtt_agent_message_interface.h:54
+
Function pointers and contexts used for sending and receiving commands, and allocating memory for the...
Definition: core_mqtt_agent_message_interface.h:133
+


+

+

+Implementing the Message Interface

+

The following steps give guidance on implementing the messaging interface:
+

+
    +
  1. Implementing MQTTAgentMessageContext_t
    +

    +
    typedef struct MQTTAgentMessageContext MQTTAgentMessageContext_t;
    +

    + MQTTAgentMessageContext_t is the incomplete type struct MQTTAgentMessageContext. The implemented struct MQTTAgentMessageContext must contain all of the information needed to send and receive commands with MQTTAgentMessageSend_t and MQTTAgentMessageRecv_t with thread safety. For example, this may be a handle to a thread safe queue, or a queue along with synchronization primitives. Commands are sent by pointer, so this structure should be able to relay pointers of type MQTTAgentCommand_t.
    +
    + Example code:
    struct MQTTAgentMessageContext
    +
    {
    +
    //Queue holding MQTTAgentCommand_t * pointers.
    +
    Queue_t queue;
    +
    };
    +

    +
  2. +
  3. Implementing MQTTAgentMessageSend_t
    +

    +
    typedef bool ( * MQTTAgentMessageSend_t )( MQTTAgentMessageContext_t * pMsgCtx,
    +
    MQTTAgentCommand_t * const * pCommandToSend,
    +
    uint32_t blockTimeMs );
    +

    + This function is expected to send the pointer that is pointed to by pCommandToSend using the message context. It will return true if the send was successful, else false.
    +
    + Example code:
    bool myMessageSendImplementation( MQTTAgentMessageContext_t * pMsgCtx,
    +
    MQTTAgentCommand_t * const * pCommandToSend,
    +
    uint32_t blockTimeMs )
    +
    {
    +
    int status = EXIT_FAILURE;
    +
    if( ( pMsgCtx != NULL ) && ( pCommandToSend != NULL ) )
    +
    {
    +
    //A function to send data to via pointer to a queue.
    +
    status = Queue_SendToBack( pMsgCtx->queue, pCommandToSend, blockTimeMs );
    +
    }
    +
    return ( status == EXIT_SUCCESS );
    +
    }
    +

    +
  4. +
  5. Implementing MQTTAgentMessageRecv_t
    +

    +
    typedef bool ( * MQTTAgentMessageRecv_t )( MQTTAgentMessageContext_t * pMsgCtx,
    +
    MQTTAgentCommand_t ** pReceivedCommand,
    +
    uint32_t blockTimeMs );
    +

    + This function is expected to receive a pointer that has been previously sent to the message context, and return in via the pReceivedCommand parameter. It will return true if the receive was successful, else false.
    +
    + Example code:
    bool myMessageRecvImplementation( MQTTAgentMessageContext_t * pMsgCtx,
    +
    MQTTAgentCommand_t ** pReceivedCommand,
    +
    uint32_t blockTimeMs )
    +
    {
    +
    int status = EXIT_FAILURE;
    +
    void * pReceivedPointer;
    +
    if( ( pMsgCtx != NULL ) && ( pCommandToSend != NULL ) )
    +
    {
    +
    //A function to receive data from a queue.
    +
    status = Queue_Recv( pMsgCtx->queue, &pReceivedPointer, blockTimeMs );
    +
    if( status == EXIT_SUCCESS )
    +
    {
    +
    *pReceivedCommand = ( MQTTAgentCommand_t * ) pReceivedPointer;
    +
    }
    +
    }
    +
    return ( status == EXIT_SUCCESS );
    +
    }
    +

    +
  6. +
  7. Implementing MQTTAgentCommandGet_t
    +

    +
    typedef MQTTAgentCommand_t * ( * MQTTAgentCommandGet_t )( uint32_t blockTimeMs );
    +

    + This function is expected to allocate storage for an MQTTAgentCommand_t struct. This function must be thread safe. It will return a pointer to the allocated command, or NULL if allocation failed.
    +
    + Example code:
    MQTTAgentCommand_t * myGetCommandImplementation( uint32_t blockTimeMs )
    +
    {
    +
    MQTTAgentCommand_t * ret = ( MQTTAgentCommand_t * ) malloc( sizeof( MQTTAgentCommand_t ) );
    +
    return ret;
    +
    }
    +

    +
  8. +
  9. Implementing MQTTAgentCommandRelease_t
    +

    +
    typedef bool ( * MQTTAgentCommandRelease_t )( MQTTAgentCommand_t * pCommandToRelease );
    +

    + This function will release a MQTTAgentCommand_t struct that had been allocated with MQTTAgentCommandGet_t. It will return a true if the command was release, else false.
    +
    + Example code:
    bool myReleaseCommandImplementation( MQTTAgentCommand_t * pCommandToRelease )
    +
    {
    +
    free( pCommandToRelease );
    +
    //free() does not have a return value.
    +
    return true;
    +
    }
    +

    +
  10. +
+
+
+
+ + + + diff --git a/v1.3.0/mqtt_agent_ping_function.html b/v1.3.0/mqtt_agent_ping_function.html new file mode 100644 index 00000000..ef772b2d --- /dev/null +++ b/v1.3.0/mqtt_agent_ping_function.html @@ -0,0 +1,160 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_Ping + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_Ping
+
+
+
MQTTStatus_t MQTTAgent_Ping( const MQTTAgentContext_t * pMqttAgentContext,
+
const MQTTAgentCommandInfo_t * pCommandInfo );
+
MQTTStatus_t MQTTAgent_Ping(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Ping() for an MQTT connection.
Definition: core_mqtt_agent.c:1323
+
MQTTStatus_t
+
Struct holding arguments that are common to every command.
Definition: core_mqtt_agent.h:189
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+

Add a command to call MQTT_Ping() for an MQTT connection.

+
Note
This API function ONLY enqueues a command to send a ping request to the server, and DOES NOT wait for a ping response to be received from the server. To detect whether a Ping Response, has not been received from the server, the MQTTAgent_CommandLoop function SHOULD be used, which returns the MQTTKeepAliveTimeout return code on a ping response (or keep-alive) timeout.
+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void pingRequestCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = pingRequestCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Ping( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command for sending request has been queued. Application can
+
// handle keep-alive timeout if detected through return value of
+
// MQTTAgent_CommandLoop in the task running the agent.
+
}
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
MQTTAgentCommandCallback_t cmdCompleteCallback
Callback to invoke upon completion.
Definition: core_mqtt_agent.h:190
+
uint32_t blockTimeMs
Maximum block time for enqueueing the command.
Definition: core_mqtt_agent.h:192
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+
+
+
+ + + + diff --git a/v1.3.0/mqtt_agent_publish_function.html b/v1.3.0/mqtt_agent_publish_function.html new file mode 100644 index 00000000..d38cd9cd --- /dev/null +++ b/v1.3.0/mqtt_agent_publish_function.html @@ -0,0 +1,176 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_Publish + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_Publish
+
+
+
+
MQTTPublishInfo_t * pPublishInfo,
+
const MQTTAgentCommandInfo_t * pCommandInfo );
+
MQTTStatus_t MQTTAgent_Publish(const MQTTAgentContext_t *pMqttAgentContext, MQTTPublishInfo_t *pPublishInfo, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Publish() for an MQTT connection.
Definition: core_mqtt_agent.c:1227
+
MQTTStatus_t
+
Struct holding arguments that are common to every command.
Definition: core_mqtt_agent.h:189
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+ +

Add a command to call MQTT_Publish() for an MQTT connection.

+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pPublishInfoMQTT PUBLISH information.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
MQTTPublishInfo_t publishInfo = { 0 };
+
+
// Function for command complete callback.
+
void publishCmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = publishCmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
// Fill the information for publish operation.
+
publishInfo.qos = MQTTQoS1;
+
publishInfo.pTopicName = "/some/topic/name";
+
publishInfo.topicNameLength = strlen( publishInfo.pTopicName );
+
publishInfo.pPayload = "Hello World!";
+
publishInfo.payloadLength = strlen( "Hello World!" );
+
+
status = MQTTAgent_Publish( &agentContext, &publishInfo, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to publish message to broker has been queued.
+
// The event of publish operation completion will be notified with
+
// the invocation of the publishCmdCompleteCb().
+
}
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
MQTTQoS1
+
MQTTAgentCommandCallback_t cmdCompleteCallback
Callback to invoke upon completion.
Definition: core_mqtt_agent.h:190
+
uint32_t blockTimeMs
Maximum block time for enqueueing the command.
Definition: core_mqtt_agent.h:192
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+ +
uint16_t topicNameLength
+ +
const char * pTopicName
+
const void * pPayload
+
+
+
+ + + + diff --git a/v1.3.0/mqtt_agent_resume_function.html b/v1.3.0/mqtt_agent_resume_function.html new file mode 100644 index 00000000..cdfb66a1 --- /dev/null +++ b/v1.3.0/mqtt_agent_resume_function.html @@ -0,0 +1,151 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_ResumeSession + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_ResumeSession
+
+
+
+
bool sessionPresent );
+
MQTTStatus_t MQTTAgent_ResumeSession(MQTTAgentContext_t *pMqttAgentContext, bool sessionPresent)
Resume a session by resending publishes if a session is present in the broker, or clear state informa...
Definition: core_mqtt_agent.c:1085
+
MQTTStatus_t
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+

Resume a session by resending publishes if a session is present in the broker, or clear state information if not.

+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]sessionPresentThe session present flag from the broker.
+
+
+
Note
This function is NOT thread-safe and should only be called from the context of the task responsible for MQTTAgent_CommandLoop.
+
Returns
MQTTSuccess if it succeeds in resending publishes, else an appropriate error code from MQTT_Publish()
+

Example

// Variables used in this example.
+
MQTTStatus_t status;
+
MQTTAgentContext_t mqttAgentContext;
+
MQTTConnectInfo_t connectInfo = { 0 };
+
MQTTPublishInfo_t willInfo = { 0 };
+
bool sessionPresent;
+
+
// The example assumes that all variables have been filled with
+
// data for the MQTT_Connect call
+
// Refer to the MQTT_Connect API for a more detailed example.
+
+
// Attempt to resume session with the broker.
+
status = MQTT_Connect( &( mqttAgentContext.mqttContext ), &connectInfo, &willInfo, 100, &sessionPresent )
+
+
if( status == MQTTSuccess )
+
{
+
// Process the session present status sent by the broker.
+
status = MQTTAgent_ResumeSession( &mqttAgentContext, sessionPresent );
+
}
+
MQTTStatus_t MQTT_Connect(MQTTContext_t *pContext, const MQTTConnectInfo_t *pConnectInfo, const MQTTPublishInfo_t *pWillInfo, uint32_t timeoutMs, bool *pSessionPresent)
+
MQTTContext_t mqttContext
Definition: core_mqtt_agent.h:154
+ + +
+
+
+ + + + diff --git a/v1.3.0/mqtt_agent_subscribe_function.html b/v1.3.0/mqtt_agent_subscribe_function.html new file mode 100644 index 00000000..b370b31a --- /dev/null +++ b/v1.3.0/mqtt_agent_subscribe_function.html @@ -0,0 +1,176 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_Subscribe + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_Subscribe
+
+
+
+
MQTTAgentSubscribeArgs_t * pSubscriptionArgs,
+
const MQTTAgentCommandInfo_t * pCommandInfo );
+
MQTTStatus_t MQTTAgent_Subscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Subscribe() for an MQTT connection.
Definition: core_mqtt_agent.c:1177
+
MQTTStatus_t
+
Struct holding arguments that are common to every command.
Definition: core_mqtt_agent.h:189
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+
Struct holding arguments for a SUBSCRIBE or UNSUBSCRIBE call.
Definition: core_mqtt_agent.h:167
+

Add a command to call MQTT_Subscribe() for an MQTT connection.

+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pSubscriptionArgsStruct describing topic to subscribe to.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
MQTTSubscribeInfo_t subscribeInfo = { 0 };
+
MQTTAgentSubscribeArgs_t subscribeArgs = { 0 };
+
+
// Function for command complete callback.
+
void subscribeCmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.CmdCompleteCallback = subscribeCmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
// Fill the information for topic filters to subscribe to.
+
subscribeInfo.qos = Qos1;
+
subscribeInfo.pTopicFilter = "/foo/bar";
+
subscribeInfo.topicFilterLength = strlen("/foo/bar");
+
subscribeArgs.pSubscribeInfo = &subscribeInfo;
+
subscribeArgs.numSubscriptions = 1U;
+
+
status = MQTTAgent_Subscribe( &agentContext, &subscribeArgs, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to send subscribe request to the server has been queued. Notification
+
// about completion of the subscribe operation will be notified to application
+
// through invocation of subscribeCmdCompleteCb().
+
}
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
uint32_t blockTimeMs
Maximum block time for enqueueing the command.
Definition: core_mqtt_agent.h:192
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+
MQTTSubscribeInfo_t * pSubscribeInfo
List of MQTT subscriptions.
Definition: core_mqtt_agent.h:168
+
size_t numSubscriptions
Number of elements in pSubscribeInfo.
Definition: core_mqtt_agent.h:169
+ + +
uint16_t topicFilterLength
+
const char * pTopicFilter
+
+
+
+ + + + diff --git a/v1.3.0/mqtt_agent_terminate_function.html b/v1.3.0/mqtt_agent_terminate_function.html new file mode 100644 index 00000000..b72290d3 --- /dev/null +++ b/v1.3.0/mqtt_agent_terminate_function.html @@ -0,0 +1,161 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_Terminate + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_Terminate
+
+
+
+
const MQTTAgentCommandInfo_t * pCommandInfo );
+
MQTTStatus_t MQTTAgent_Terminate(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a termination command to the command queue.
Definition: core_mqtt_agent.c:1346
+
MQTTStatus_t
+
Struct holding arguments that are common to every command.
Definition: core_mqtt_agent.h:189
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+

Add a termination command to the command queue.

+

On command loop termination, all pending commands in the queue, as well as those waiting for an acknowledgment, will be terminated with error code MQTTRecvFailed.

+
Note
Commands may still be posted to the command queue after MQTTAgent_CommandLoop has returned. It is the responsibility of the application to cancel any commands that are posted while the command loop is not running, such as by invoking MQTTAgent_CancelAll.
+
+We RECOMMEND that this function is used from application task(s), that is a task not running the agent, to terminate the agent loop instead of calling MQTTAgent_Disconnect, so that the logic for creating and closing MQTT connection is owned by the agent task.
+
Parameters
+ + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
+
// Function for command complete callback.
+
void terminateCallback( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = terminateCallback;
+
commandInfo.blockTimeMs = 500;
+
+
status = MQTTAgent_Terminate( &agentContext, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to terminate the agent loop has been queued.
+
}
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
MQTTAgentCommandCallback_t cmdCompleteCallback
Callback to invoke upon completion.
Definition: core_mqtt_agent.h:190
+
uint32_t blockTimeMs
Maximum block time for enqueueing the command.
Definition: core_mqtt_agent.h:192
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+
+
+
+ + + + diff --git a/v1.3.0/mqtt_agent_unsubscribe_function.html b/v1.3.0/mqtt_agent_unsubscribe_function.html new file mode 100644 index 00000000..e051e51c --- /dev/null +++ b/v1.3.0/mqtt_agent_unsubscribe_function.html @@ -0,0 +1,175 @@ + + + + + + + +coreMQTT Agent: MQTTAgent_Unsubscribe + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
MQTTAgent_Unsubscribe
+
+
+
+
MQTTAgentSubscribeArgs_t * pSubscriptionArgs,
+
const MQTTAgentCommandInfo_t * pCommandInfo );
+
MQTTStatus_t MQTTAgent_Unsubscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo)
Add a command to call MQTT_Unsubscribe() for an MQTT connection.
Definition: core_mqtt_agent.c:1202
+
MQTTStatus_t
+
Struct holding arguments that are common to every command.
Definition: core_mqtt_agent.h:189
+
Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(),...
Definition: core_mqtt_agent.h:153
+
Struct holding arguments for a SUBSCRIBE or UNSUBSCRIBE call.
Definition: core_mqtt_agent.h:167
+

Add a command to call MQTT_Unsubscribe() for an MQTT connection.

+
Parameters
+ + + + +
[in]pMqttAgentContextThe MQTT agent to use.
[in]pSubscriptionArgsList of topics to unsubscribe from.
[in]pCommandInfoThe information pertaining to the command, including:
    +
  • cmdCompleteCallback Optional callback to invoke when the command completes.
  • +
  • pCmdCompleteCallbackContext Optional completion callback context.
  • +
  • blockTimeMs The maximum amount of time in milliseconds to wait for the command to be posted to the MQTT agent, should the agent's event queue be full. Tasks wait in the Blocked state so don't use any CPU time.
  • +
+
+
+
+
Note
The context passed to the callback through pCmdContext member of pCommandInfo parameter MUST remain in scope at least until the callback has been executed by the agent task.
+
Returns
MQTTSuccess if the command was posted to the MQTT agent's event queue. Otherwise an enumerated error code.
+

Example

// Variables used in this example.
+
MQTTAgentContext_t agentContext;
+
MQTTStatus_t status;
+
MQTTAgentCommandInfo_t commandInfo = { 0 };
+
MQTTSubscribeInfo_t unsubscribeInfo = { 0 };
+
MQTTAgentSubscribeArgs_t unsubscribeArgs = { 0 };
+
+
// Function for command complete callback.
+
void unsubscribeCmdCompleteCb( MQTTAgentCommandContext_t * pCmdCallbackContext,
+
MQTTAgentReturnInfo_t * pReturnInfo );
+
+
// Fill the command information.
+
commandInfo.cmdCompleteCallback = unsubscribeCmdCompleteCb;
+
commandInfo.blockTimeMs = 500;
+
+
// Fill the information for topics to unsubscribe from.
+
unsubscribeInfo.pTopicFilter = "/foo/bar";
+
unsubscribeInfo.topicFilterLength = strlen("/foo/bar");
+
unsubscribeArgs.pSubscribeInfo = &unsubscribeInfo;
+
unsubscribeArgs.numSubscriptions = 1U;
+
+
status = MQTTAgent_Unsubscribe( &agentContext, &unsubscribeArgs, &commandInfo );
+
+
if( status == MQTTSuccess )
+
{
+
// Command to send Unsubscribe request to the server has been queued. Notification
+
// about completion of the Unsubscribe operation will be notified to application
+
// through invocation of unsubscribeCompleteCb().
+
}
+
struct MQTTAgentCommandContext MQTTAgentCommandContext_t
Struct containing context for a specific command.
Definition: core_mqtt_agent.h:83
+
MQTTAgentCommandCallback_t cmdCompleteCallback
Callback to invoke upon completion.
Definition: core_mqtt_agent.h:190
+
uint32_t blockTimeMs
Maximum block time for enqueueing the command.
Definition: core_mqtt_agent.h:192
+
Struct holding return codes and outputs from a command.
Definition: core_mqtt_agent.h:71
+
MQTTSubscribeInfo_t * pSubscribeInfo
List of MQTT subscriptions.
Definition: core_mqtt_agent.h:168
+
size_t numSubscriptions
Number of elements in pSubscribeInfo.
Definition: core_mqtt_agent.h:169
+ +
uint16_t topicFilterLength
+
const char * pTopicFilter
+
+
+
+ + + + diff --git a/v1.3.0/nav_f.png b/v1.3.0/nav_f.png new file mode 100644 index 0000000000000000000000000000000000000000..72a58a529ed3a9ed6aa0c51a79cf207e026deee2 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI`!2~2XGqLUlQVE_ejv*C{Z|{2ZH7M}7UYxc) zn!W8uqtnIQ>_z8U literal 0 HcmV?d00001 diff --git a/v1.3.0/nav_fd.png b/v1.3.0/nav_fd.png new file mode 100644 index 0000000000000000000000000000000000000000..032fbdd4c54f54fa9a2e6423b94ef4b2ebdfaceb GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI`!2~2XGqLUlQU#tajv*C{Z|C~*H7f|XvG1G8 zt7aS*L7xwMeS}!z6R#{C5tIw-s~AJ==F^i}x3XyJseHR@yF& zerFf(Zf;Dd{+(0lDIROL@Sj-Ju2JQ8&-n%4%q?>|^bShc&lR?}7HeMo@BDl5N(aHY Uj$gdr1MOz;boFyt=akR{0D!zeaR2}S literal 0 HcmV?d00001 diff --git a/v1.3.0/nav_g.png b/v1.3.0/nav_g.png new file mode 100644 index 0000000000000000000000000000000000000000..2093a237a94f6c83e19ec6e5fd42f7ddabdafa81 GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^j6lrB!3HFm1ilyoDK$?Q$B+ufw|5PB85lU25BhtE tr?otc=hd~V+ws&_A@j8Fiv!KF$B+ufw|5=67#uj90@pIL wZ=Q8~_Ju`#59=RjDrmm`tMD@M=!-l18IR?&vFVdQ&MBb@0HFXL6W-eg#Jd_@e6*DPn)w;=|1H}Zvm9l6xXXB%>yL=NQU;mg M>FVdQ&MBb@0Bdt1Qvd(} literal 0 HcmV?d00001 diff --git a/v1.3.0/navtree.css b/v1.3.0/navtree.css new file mode 100644 index 00000000..c8a7766a --- /dev/null +++ b/v1.3.0/navtree.css @@ -0,0 +1,150 @@ +#nav-tree .children_ul { + margin:0; + padding:4px; +} + +#nav-tree ul { + list-style:none outside none; + margin:0px; + padding:0px; +} + +#nav-tree li { + white-space:nowrap; + margin:0px; + padding:0px; +} + +#nav-tree .plus { + margin:0px; +} + +#nav-tree .selected { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + color: var(--nav-text-active-color); + text-shadow: var(--nav-text-active-shadow); +} + +#nav-tree .selected .arrow { + color: var(--nav-arrow-selected-color); + text-shadow: none; +} + +#nav-tree img { + margin:0px; + padding:0px; + border:0px; + vertical-align: middle; +} + +#nav-tree a { + text-decoration:none; + padding:0px; + margin:0px; + outline:none; +} + +#nav-tree .label { + margin:0px; + padding:0px; + font: 12px var(--font-family-nav); +} + +#nav-tree .label a { + padding:2px; +} + +#nav-tree .selected a { + text-decoration:none; + color:var(--nav-text-active-color); +} + +#nav-tree .children_ul { + margin:0px; + padding:0px; +} + +#nav-tree .item { + margin:0px; + padding:0px; +} + +#nav-tree { + padding: 0px 0px; + font-size:14px; + overflow:auto; +} + +#doc-content { + overflow:auto; + display:block; + padding:0px; + margin:0px; + -webkit-overflow-scrolling : touch; /* iOS 5+ */ +} + +#side-nav { + padding:0 6px 0 0; + margin: 0px; + display:block; + position: absolute; + left: 0px; + width: $width; + overflow : hidden; +} + +.ui-resizable .ui-resizable-handle { + display:block; +} + +.ui-resizable-e { + background-image:var(--nav-splitbar-image); + background-size:100%; + background-repeat:repeat-y; + background-attachment: scroll; + cursor:ew-resize; + height:100%; + right:0; + top:0; + width:6px; +} + +.ui-resizable-handle { + display:none; + font-size:0.1px; + position:absolute; + z-index:1; +} + +#nav-tree-contents { + margin: 6px 0px 0px 0px; +} + +#nav-tree { + background-repeat:repeat-x; + background-color: var(--nav-background-color); + -webkit-overflow-scrolling : touch; /* iOS 5+ */ +} + +#nav-sync { + position:absolute; + top:5px; + right:24px; + z-index:0; +} + +#nav-sync img { + opacity:0.3; +} + +#nav-sync img:hover { + opacity:0.9; +} + +@media print +{ + #nav-tree { display: none; } + div.ui-resizable-handle { display: none; position: relative; } +} + diff --git a/v1.3.0/navtree.js b/v1.3.0/navtree.js new file mode 100644 index 00000000..27983687 --- /dev/null +++ b/v1.3.0/navtree.js @@ -0,0 +1,549 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +var navTreeSubIndices = new Array(); +var arrowDown = '▼'; +var arrowRight = '►'; + +function getData(varName) +{ + var i = varName.lastIndexOf('/'); + var n = i>=0 ? varName.substring(i+1) : varName; + return eval(n.replace(/\-/g,'_')); +} + +function stripPath(uri) +{ + return uri.substring(uri.lastIndexOf('/')+1); +} + +function stripPath2(uri) +{ + var i = uri.lastIndexOf('/'); + var s = uri.substring(i+1); + var m = uri.substring(0,i+1).match(/\/d\w\/d\w\w\/$/); + return m ? uri.substring(i-6) : s; +} + +function hashValue() +{ + return $(location).attr('hash').substring(1).replace(/[^\w\-]/g,''); +} + +function hashUrl() +{ + return '#'+hashValue(); +} + +function pathName() +{ + return $(location).attr('pathname').replace(/[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]/g, ''); +} + +function localStorageSupported() +{ + try { + return 'localStorage' in window && window['localStorage'] !== null && window.localStorage.getItem; + } + catch(e) { + return false; + } +} + +function storeLink(link) +{ + if (!$("#nav-sync").hasClass('sync') && localStorageSupported()) { + window.localStorage.setItem('navpath',link); + } +} + +function deleteLink() +{ + if (localStorageSupported()) { + window.localStorage.setItem('navpath',''); + } +} + +function cachedLink() +{ + if (localStorageSupported()) { + return window.localStorage.getItem('navpath'); + } else { + return ''; + } +} + +function getScript(scriptName,func,show) +{ + var head = document.getElementsByTagName("head")[0]; + var script = document.createElement('script'); + script.id = scriptName; + script.type = 'text/javascript'; + script.onload = func; + script.src = scriptName+'.js'; + head.appendChild(script); +} + +function createIndent(o,domNode,node,level) +{ + var level=-1; + var n = node; + while (n.parentNode) { level++; n=n.parentNode; } + if (node.childrenData) { + var imgNode = document.createElement("span"); + imgNode.className = 'arrow'; + imgNode.style.paddingLeft=(16*level).toString()+'px'; + imgNode.innerHTML=arrowRight; + node.plus_img = imgNode; + node.expandToggle = document.createElement("a"); + node.expandToggle.href = "javascript:void(0)"; + node.expandToggle.onclick = function() { + if (node.expanded) { + $(node.getChildrenUL()).slideUp("fast"); + node.plus_img.innerHTML=arrowRight; + node.expanded = false; + } else { + expandNode(o, node, false, false); + } + } + node.expandToggle.appendChild(imgNode); + domNode.appendChild(node.expandToggle); + } else { + var span = document.createElement("span"); + span.className = 'arrow'; + span.style.width = 16*(level+1)+'px'; + span.innerHTML = ' '; + domNode.appendChild(span); + } +} + +var animationInProgress = false; + +function gotoAnchor(anchor,aname,updateLocation) +{ + var pos, docContent = $('#doc-content'); + var ancParent = $(anchor.parent()); + if (ancParent.hasClass('memItemLeft') || + ancParent.hasClass('memtitle') || + ancParent.hasClass('fieldname') || + ancParent.hasClass('fieldtype') || + ancParent.is(':header')) + { + pos = ancParent.position().top; + } else if (anchor.position()) { + pos = anchor.position().top; + } + if (pos) { + var dist = Math.abs(Math.min( + pos-docContent.offset().top, + docContent[0].scrollHeight- + docContent.height()-docContent.scrollTop())); + animationInProgress=true; + docContent.animate({ + scrollTop: pos + docContent.scrollTop() - docContent.offset().top + },Math.max(50,Math.min(500,dist)),function(){ + if (updateLocation) window.location.href=aname; + animationInProgress=false; + }); + } +} + +function newNode(o, po, text, link, childrenData, lastNode) +{ + var node = new Object(); + node.children = Array(); + node.childrenData = childrenData; + node.depth = po.depth + 1; + node.relpath = po.relpath; + node.isLast = lastNode; + + node.li = document.createElement("li"); + po.getChildrenUL().appendChild(node.li); + node.parentNode = po; + + node.itemDiv = document.createElement("div"); + node.itemDiv.className = "item"; + + node.labelSpan = document.createElement("span"); + node.labelSpan.className = "label"; + + createIndent(o,node.itemDiv,node,0); + node.itemDiv.appendChild(node.labelSpan); + node.li.appendChild(node.itemDiv); + + var a = document.createElement("a"); + node.labelSpan.appendChild(a); + node.label = document.createTextNode(text); + node.expanded = false; + a.appendChild(node.label); + if (link) { + var url; + if (link.substring(0,1)=='^') { + url = link.substring(1); + link = url; + } else { + url = node.relpath+link; + } + a.className = stripPath(link.replace('#',':')); + if (link.indexOf('#')!=-1) { + var aname = '#'+link.split('#')[1]; + var srcPage = stripPath(pathName()); + var targetPage = stripPath(link.split('#')[0]); + a.href = srcPage!=targetPage ? url : "javascript:void(0)"; + a.onclick = function(){ + storeLink(link); + if (!$(a).parent().parent().hasClass('selected')) + { + $('.item').removeClass('selected'); + $('.item').removeAttr('id'); + $(a).parent().parent().addClass('selected'); + $(a).parent().parent().attr('id','selected'); + } + var anchor = $(aname); + gotoAnchor(anchor,aname,true); + }; + } else { + a.href = url; + a.onclick = function() { storeLink(link); } + } + } else { + if (childrenData != null) + { + a.className = "nolink"; + a.href = "javascript:void(0)"; + a.onclick = node.expandToggle.onclick; + } + } + + node.childrenUL = null; + node.getChildrenUL = function() { + if (!node.childrenUL) { + node.childrenUL = document.createElement("ul"); + node.childrenUL.className = "children_ul"; + node.childrenUL.style.display = "none"; + node.li.appendChild(node.childrenUL); + } + return node.childrenUL; + }; + + return node; +} + +function showRoot() +{ + var headerHeight = $("#top").height(); + var footerHeight = $("#nav-path").height(); + var windowHeight = $(window).height() - headerHeight - footerHeight; + (function (){ // retry until we can scroll to the selected item + try { + var navtree=$('#nav-tree'); + navtree.scrollTo('#selected',100,{offset:-windowHeight/2}); + } catch (err) { + setTimeout(arguments.callee, 0); + } + })(); +} + +function expandNode(o, node, imm, showRoot) +{ + if (node.childrenData && !node.expanded) { + if (typeof(node.childrenData)==='string') { + var varName = node.childrenData; + getScript(node.relpath+varName,function(){ + node.childrenData = getData(varName); + expandNode(o, node, imm, showRoot); + }, showRoot); + } else { + if (!node.childrenVisited) { + getNode(o, node); + } + $(node.getChildrenUL()).slideDown("fast"); + node.plus_img.innerHTML = arrowDown; + node.expanded = true; + } + } +} + +function glowEffect(n,duration) +{ + n.addClass('glow').delay(duration).queue(function(next){ + $(this).removeClass('glow');next(); + }); +} + +function highlightAnchor() +{ + var aname = hashUrl(); + var anchor = $(aname); + if (anchor.parent().attr('class')=='memItemLeft'){ + var rows = $('.memberdecls tr[class$="'+hashValue()+'"]'); + glowEffect(rows.children(),300); // member without details + } else if (anchor.parent().attr('class')=='fieldname'){ + glowEffect(anchor.parent().parent(),1000); // enum value + } else if (anchor.parent().attr('class')=='fieldtype'){ + glowEffect(anchor.parent().parent(),1000); // struct field + } else if (anchor.parent().is(":header")) { + glowEffect(anchor.parent(),1000); // section header + } else { + glowEffect(anchor.next(),1000); // normal member + } +} + +function selectAndHighlight(hash,n) +{ + var a; + if (hash) { + var link=stripPath(pathName())+':'+hash.substring(1); + a=$('.item a[class$="'+link+'"]'); + } + if (a && a.length) { + a.parent().parent().addClass('selected'); + a.parent().parent().attr('id','selected'); + highlightAnchor(); + } else if (n) { + $(n.itemDiv).addClass('selected'); + $(n.itemDiv).attr('id','selected'); + } + var topOffset=5; + if (typeof page_layout!=='undefined' && page_layout==1) { + topOffset+=$('#top').outerHeight(); + } + if ($('#nav-tree-contents .item:first').hasClass('selected')) { + topOffset+=25; + } + $('#nav-sync').css('top',topOffset+'px'); + showRoot(); +} + +function showNode(o, node, index, hash) +{ + if (node && node.childrenData) { + if (typeof(node.childrenData)==='string') { + var varName = node.childrenData; + getScript(node.relpath+varName,function(){ + node.childrenData = getData(varName); + showNode(o,node,index,hash); + },true); + } else { + if (!node.childrenVisited) { + getNode(o, node); + } + $(node.getChildrenUL()).css({'display':'block'}); + node.plus_img.innerHTML = arrowDown; + node.expanded = true; + var n = node.children[o.breadcrumbs[index]]; + if (index+11) hash = '#'+parts[1].replace(/[^\w\-]/g,''); + else hash=''; + } + if (hash.match(/^#l\d+$/)) { + var anchor=$('a[name='+hash.substring(1)+']'); + glowEffect(anchor.parent(),1000); // line number + hash=''; // strip line number anchors + } + var url=root+hash; + var i=-1; + while (NAVTREEINDEX[i+1]<=url) i++; + if (i==-1) { i=0; root=NAVTREE[0][1]; } // fallback: show index + if (navTreeSubIndices[i]) { + gotoNode(o,i,root,hash,relpath) + } else { + getScript(relpath+'navtreeindex'+i,function(){ + navTreeSubIndices[i] = eval('NAVTREEINDEX'+i); + if (navTreeSubIndices[i]) { + gotoNode(o,i,root,hash,relpath); + } + },true); + } +} + +function showSyncOff(n,relpath) +{ + n.html(''); +} + +function showSyncOn(n,relpath) +{ + n.html(''); +} + +function toggleSyncButton(relpath) +{ + var navSync = $('#nav-sync'); + if (navSync.hasClass('sync')) { + navSync.removeClass('sync'); + showSyncOff(navSync,relpath); + storeLink(stripPath2(pathName())+hashUrl()); + } else { + navSync.addClass('sync'); + showSyncOn(navSync,relpath); + deleteLink(); + } +} + +var loadTriggered = false; +var readyTriggered = false; +var loadObject,loadToRoot,loadUrl,loadRelPath; + +$(window).on('load',function(){ + if (readyTriggered) { // ready first + navTo(loadObject,loadToRoot,loadUrl,loadRelPath); + showRoot(); + } + loadTriggered=true; +}); + +function initNavTree(toroot,relpath) +{ + var o = new Object(); + o.toroot = toroot; + o.node = new Object(); + o.node.li = document.getElementById("nav-tree-contents"); + o.node.childrenData = NAVTREE; + o.node.children = new Array(); + o.node.childrenUL = document.createElement("ul"); + o.node.getChildrenUL = function() { return o.node.childrenUL; }; + o.node.li.appendChild(o.node.childrenUL); + o.node.depth = 0; + o.node.relpath = relpath; + o.node.expanded = false; + o.node.isLast = true; + o.node.plus_img = document.createElement("span"); + o.node.plus_img.className = 'arrow'; + o.node.plus_img.innerHTML = arrowRight; + + if (localStorageSupported()) { + var navSync = $('#nav-sync'); + if (cachedLink()) { + showSyncOff(navSync,relpath); + navSync.removeClass('sync'); + } else { + showSyncOn(navSync,relpath); + } + navSync.click(function(){ toggleSyncButton(relpath); }); + } + + if (loadTriggered) { // load before ready + navTo(o,toroot,hashUrl(),relpath); + showRoot(); + } else { // ready before load + loadObject = o; + loadToRoot = toroot; + loadUrl = hashUrl(); + loadRelPath = relpath; + readyTriggered=true; + } + + $(window).bind('hashchange', function(){ + if (window.location.hash && window.location.hash.length>1){ + var a; + if ($(location).attr('hash')){ + var clslink=stripPath(pathName())+':'+hashValue(); + a=$('.item a[class$="'+clslink.replace(/1|%O$WD@{VPM$7~Ar*{o?;hlAFyLXmaDC0y znK1_#cQqJWPES%4Uujug^TE?jMft$}Eq^WaR~)%f)vSNs&gek&x%A9X9sM + + + + + + +coreMQTT Agent: Related Pages + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Related Pages
+
+
+
Here is a list of all related documentation pages:
+
[detail level 12]
+ + + + + + + + + + + + + + + +
 DesignArchitecture of the MQTT Agent library
 ConfigurationsConfigurations of the MQTT Agent
 FunctionsFunctions of the MQTT Agent library<br>
+
 MQTTAgent_Init
 MQTTAgent_CommandLoop
 MQTTAgent_ResumeSession
 MQTTAgent_CancelAll
 MQTTAgent_Publish
 MQTTAgent_Subscribe
 MQTTAgent_Unsubscribe
 MQTTAgent_Connect
 MQTTAgent_Disconnect
 MQTTAgent_Ping
 MQTTAgent_Terminate
 Message InterfaceMessaging interface used by the MQTT Agent.
+
+
+
+
+
+ + + + diff --git a/v1.3.0/resize.js b/v1.3.0/resize.js new file mode 100644 index 00000000..aaeb6fc0 --- /dev/null +++ b/v1.3.0/resize.js @@ -0,0 +1,155 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +var once=1; +function initResizable() +{ + var cookie_namespace = 'doxygen'; + var sidenav,navtree,content,header,barWidth=6,desktop_vp=768,titleHeight; + + function readSetting(cookie) + { + if (window.chrome) { + var val = localStorage.getItem(cookie_namespace+'_width'); + if (val) return val; + } else { + var myCookie = cookie_namespace+"_"+cookie+"="; + if (document.cookie) { + var index = document.cookie.indexOf(myCookie); + if (index != -1) { + var valStart = index + myCookie.length; + var valEnd = document.cookie.indexOf(";", valStart); + if (valEnd == -1) { + valEnd = document.cookie.length; + } + var val = document.cookie.substring(valStart, valEnd); + return val; + } + } + } + return 250; + } + + function writeSetting(cookie, val) + { + if (window.chrome) { + localStorage.setItem(cookie_namespace+"_width",val); + } else { + var date = new Date(); + date.setTime(date.getTime()+(10*365*24*60*60*1000)); // default expiration is one week + expiration = date.toGMTString(); + document.cookie = cookie_namespace + "_" + cookie + "=" + val + "; SameSite=Lax; expires=" + expiration+"; path=/"; + } + } + + function resizeWidth() + { + var windowWidth = $(window).width() + "px"; + var sidenavWidth = $(sidenav).outerWidth(); + content.css({marginLeft:parseInt(sidenavWidth)+"px"}); + if (typeof page_layout!=='undefined' && page_layout==1) { + footer.css({marginLeft:parseInt(sidenavWidth)+"px"}); + } + writeSetting('width',sidenavWidth-barWidth); + } + + function restoreWidth(navWidth) + { + var windowWidth = $(window).width() + "px"; + content.css({marginLeft:parseInt(navWidth)+barWidth+"px"}); + if (typeof page_layout!=='undefined' && page_layout==1) { + footer.css({marginLeft:parseInt(navWidth)+barWidth+"px"}); + } + sidenav.css({width:navWidth + "px"}); + } + + function resizeHeight() + { + var headerHeight = header.outerHeight(); + var footerHeight = footer.outerHeight(); + var windowHeight = $(window).height(); + var contentHeight,navtreeHeight,sideNavHeight; + if (typeof page_layout==='undefined' || page_layout==0) { /* DISABLE_INDEX=NO */ + contentHeight = windowHeight - headerHeight - footerHeight; + navtreeHeight = contentHeight; + sideNavHeight = contentHeight; + } else if (page_layout==1) { /* DISABLE_INDEX=YES */ + contentHeight = windowHeight - footerHeight; + navtreeHeight = windowHeight - headerHeight; + sideNavHeight = windowHeight; + } + content.css({height:contentHeight + "px"}); + navtree.css({height:navtreeHeight + "px"}); + sidenav.css({height:sideNavHeight + "px"}); + if (location.hash.slice(1)) { + (document.getElementById(location.hash.slice(1))||document.body).scrollIntoView(); + } + } + + function collapseExpand() + { + var newWidth; + if (sidenav.width()>0) { + newWidth=0; + } + else { + var width = readSetting('width'); + newWidth = (width>250 && width<$(window).width()) ? width : 250; + } + restoreWidth(newWidth); + var sidenavWidth = $(sidenav).outerWidth(); + writeSetting('width',sidenavWidth-barWidth); + } + + header = $("#top"); + sidenav = $("#side-nav"); + content = $("#doc-content"); + navtree = $("#nav-tree"); + footer = $("#nav-path"); + $(".side-nav-resizable").resizable({resize: function(e, ui) { resizeWidth(); } }); + $(sidenav).resizable({ minWidth: 0 }); + $(window).resize(function() { resizeHeight(); }); + var device = navigator.userAgent.toLowerCase(); + var touch_device = device.match(/(iphone|ipod|ipad|android)/); + if (touch_device) { /* wider split bar for touch only devices */ + $(sidenav).css({ paddingRight:'20px' }); + $('.ui-resizable-e').css({ width:'20px' }); + $('#nav-sync').css({ right:'34px' }); + barWidth=20; + } + var width = readSetting('width'); + if (width) { restoreWidth(width); } else { resizeWidth(); } + resizeHeight(); + var url = location.href; + var i=url.indexOf("#"); + if (i>=0) window.location.hash=url.substr(i); + var _preventDefault = function(evt) { evt.preventDefault(); }; + $("#splitbar").bind("dragstart", _preventDefault).bind("selectstart", _preventDefault); + if (once) { + $(".ui-resizable-handle").dblclick(collapseExpand); + once=0 + } + $(window).on('load',resizeHeight); +} +/* @license-end */ diff --git a/v1.3.0/search/all_0.js b/v1.3.0/search/all_0.js new file mode 100644 index 00000000..1f54c078 --- /dev/null +++ b/v1.3.0/search/all_0.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['addacknowledgment_0',['addAcknowledgment',['../struct_m_q_t_t_agent_command_func_returns__t.html#a474988426514661ae649a613b1dee051',1,'MQTTAgentCommandFuncReturns_t']]], + ['addawaitingoperation_1',['addAwaitingOperation',['../core__mqtt__agent_8c.html#ae70f7438de05ac589b4e48d4a2a7dd7b',1,'core_mqtt_agent.c']]], + ['addcommandtoqueue_2',['addCommandToQueue',['../core__mqtt__agent_8c.html#a38a109884abe76bd9e0b90d23b9d67b4',1,'core_mqtt_agent.c']]], + ['agentinterface_3',['agentInterface',['../struct_m_q_t_t_agent_context__t.html#ab89557b0a015d1848b8d6a9adbff8a4d',1,'MQTTAgentContext_t']]], + ['appcallback_4',['appCallback',['coreMQTT/struct_m_q_t_t_context__t.html#a73bd9259db9c3a9b84518cbf928ed91f',1,'MQTTContext_t']]] +]; diff --git a/v1.3.0/search/all_1.js b/v1.3.0/search/all_1.js new file mode 100644 index 00000000..57d8dac1 --- /dev/null +++ b/v1.3.0/search/all_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['basic_20types_0',['Basic Types',['coreMQTT/group__mqtt__basic__types.html',1,'']]], + ['blocktimems_1',['blockTimeMs',['../struct_m_q_t_t_agent_command_info__t.html#aa0f490187c1199c2d31d4c04a01d4637',1,'MQTTAgentCommandInfo_t']]] +]; diff --git a/v1.3.0/search/all_10.js b/v1.3.0/search/all_10.js new file mode 100644 index 00000000..bc9aab10 --- /dev/null +++ b/v1.3.0/search/all_10.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['recv_0',['recv',['coreMQTT/struct_transport_interface__t.html#a7c34e9b865e2a509306f09c7dfa3699e',1,'TransportInterface_t::recv()'],['../struct_m_q_t_t_agent_message_interface__t.html#a19e00e6431f53e595837d8ac7e4f744b',1,'MQTTAgentMessageInterface_t::recv()']]], + ['releasecommand_1',['releaseCommand',['../struct_m_q_t_t_agent_message_interface__t.html#ac809ba46da91df0fc4750ce515bf8f41',1,'MQTTAgentMessageInterface_t']]], + ['remaininglength_2',['remainingLength',['coreMQTT/struct_m_q_t_t_packet_info__t.html#a7c85becf08de0ec9776dd4be1fcc4bf8',1,'MQTTPacketInfo_t']]], + ['resendpublishes_3',['resendPublishes',['../core__mqtt__agent_8c.html#a0c7ea532d3da52d5c8ceb7493ce5fe36',1,'core_mqtt_agent.c']]], + ['retain_4',['retain',['coreMQTT/struct_m_q_t_t_publish_info__t.html#a343b0af89c46a900db4aa5c775a0975a',1,'MQTTPublishInfo_t']]], + ['returncode_5',['returnCode',['../struct_m_q_t_t_agent_return_info__t.html#ab04f05e53b8e9039f8983f68b032ccc8',1,'MQTTAgentReturnInfo_t']]], + ['runprocessloop_6',['runProcessLoop',['../struct_m_q_t_t_agent_command_func_returns__t.html#aae5a1d50a22df21950d586f5584e8994',1,'MQTTAgentCommandFuncReturns_t']]] +]; diff --git a/v1.3.0/search/all_11.js b/v1.3.0/search/all_11.js new file mode 100644 index 00000000..514a2f90 --- /dev/null +++ b/v1.3.0/search/all_11.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['send_0',['send',['coreMQTT/struct_transport_interface__t.html#a01cd9935e9a5266ca196243a0054d489',1,'TransportInterface_t::send()'],['../struct_m_q_t_t_agent_message_interface__t.html#abdc8e1c30aa27bf633f4f6e7da9a6465',1,'MQTTAgentMessageInterface_t::send()']]], + ['sessionpresent_1',['sessionPresent',['../struct_m_q_t_t_agent_connect_args__t.html#a01e3a80d5db4f5f89df44697cca1513f',1,'MQTTAgentConnectArgs_t']]], + ['size_2',['size',['coreMQTT/struct_m_q_t_t_fixed_buffer__t.html#a0b0b6a93cc62751ebeb03095d5431636',1,'MQTTFixedBuffer_t']]], + ['subscribe_3',['SUBSCRIBE',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33abc6f919ff681f5f552b2f7d1f0fba832',1,'core_mqtt_agent.h']]] +]; diff --git a/v1.3.0/search/all_12.js b/v1.3.0/search/all_12.js new file mode 100644 index 00000000..cbc808e9 --- /dev/null +++ b/v1.3.0/search/all_12.js @@ -0,0 +1,17 @@ +var searchData= +[ + ['terminate_0',['TERMINATE',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a9aab2d9eae3e9a84d9fed3f0cadd7e22',1,'core_mqtt_agent.h']]], + ['timeoutms_1',['timeoutMs',['../struct_m_q_t_t_agent_connect_args__t.html#a631a199abde2ad2b3e4c69cf211e4d54',1,'MQTTAgentConnectArgs_t']]], + ['timeouts_20in_20coremqtt_20library_2',['Timeouts in coreMQTT library',['coreMQTT/mqtt_timeouts.html',1,'']]], + ['topicfilterlength_3',['topicFilterLength',['coreMQTT/struct_m_q_t_t_subscribe_info__t.html#a6972f8e036f8bde9b1f23a2aacb61382',1,'MQTTSubscribeInfo_t']]], + ['topicnamelength_4',['topicNameLength',['coreMQTT/struct_m_q_t_t_publish_info__t.html#a6161c792d20cc7cf8284c1b71ea1145f',1,'MQTTPublishInfo_t']]], + ['transport_20interface_5',['Transport Interface',['coreMQTT/mqtt_transport_interface.html',1,'']]], + ['transport_5finterface_2eh_6',['transport_interface.h',['coreMQTT/transport__interface_8h.html',1,'']]], + ['transportinterface_7',['transportInterface',['coreMQTT/struct_m_q_t_t_context__t.html#a87ab9d61e7711325c2c85ce3ce63386a',1,'MQTTContext_t']]], + ['transportinterface_5ft_8',['TransportInterface_t',['coreMQTT/struct_transport_interface__t.html',1,'']]], + ['transportoutvector_5ft_9',['TransportOutVector_t',['coreMQTT/struct_transport_out_vector__t.html',1,'']]], + ['transportrecv_5ft_10',['TransportRecv_t',['coreMQTT/group__mqtt__callback__types.html#ga227df31d6daf07e5d833537c12130167',1,]]], + ['transportsend_5ft_11',['TransportSend_t',['coreMQTT/group__mqtt__callback__types.html#ga2a39853ff952edd715ab07b33ab2a7c5',1,]]], + ['transportwritev_5ft_12',['TransportWritev_t',['coreMQTT/group__mqtt__callback__types.html#ga47e779557b0c2db95949ef9526861dfb',1,]]], + ['type_13',['type',['coreMQTT/struct_m_q_t_t_packet_info__t.html#a7fef40548c1aa0f0e7f812a6a7243758',1,'MQTTPacketInfo_t']]] +]; diff --git a/v1.3.0/search/all_13.js b/v1.3.0/search/all_13.js new file mode 100644 index 00000000..06f23797 --- /dev/null +++ b/v1.3.0/search/all_13.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['unsubscribe_0',['UNSUBSCRIBE',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a8395e5981c15d813c588c86988fd4aea',1,'core_mqtt_agent.h']]], + ['usernamelength_1',['userNameLength',['coreMQTT/struct_m_q_t_t_connect_info__t.html#a7165be3bb06d4527ab4eb773b50e05e1',1,'MQTTConnectInfo_t']]] +]; diff --git a/v1.3.0/search/all_14.js b/v1.3.0/search/all_14.js new file mode 100644 index 00000000..8d1b51f7 --- /dev/null +++ b/v1.3.0/search/all_14.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['validateparams_0',['validateParams',['../core__mqtt__agent_8c.html#ac6b1b83accad3124122fed5c7ec14870',1,'core_mqtt_agent.c']]], + ['validatestruct_1',['validateStruct',['../core__mqtt__agent_8c.html#a77d4ec3f1e90897d6f173a2fcd7b9b61',1,'core_mqtt_agent.c']]] +]; diff --git a/v1.3.0/search/all_15.js b/v1.3.0/search/all_15.js new file mode 100644 index 00000000..1ab46090 --- /dev/null +++ b/v1.3.0/search/all_15.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['waitingforpingresp_0',['waitingForPingResp',['coreMQTT/struct_m_q_t_t_context__t.html#ac7073f43645f7b7c0c5b7763980004bb',1,'MQTTContext_t']]], + ['writev_1',['writev',['coreMQTT/struct_transport_interface__t.html#a8cf677fbeee53d270daa6dacfa138b79',1,'TransportInterface_t']]] +]; diff --git a/v1.3.0/search/all_2.js b/v1.3.0/search/all_2.js new file mode 100644 index 00000000..31ad8319 --- /dev/null +++ b/v1.3.0/search/all_2.js @@ -0,0 +1,31 @@ +var searchData= +[ + ['callback_20types_0',['Callback Types',['../group__mqtt__agent__callback__types.html',1,'(Global Namespace)'],['coreMQTT/group__mqtt__callback__types.html',1,'(Global Namespace)']]], + ['cleansession_1',['cleanSession',['coreMQTT/struct_m_q_t_t_connect_info__t.html#a606e7765c4f2215fb2bf630f6eb9ff6b',1,'MQTTConnectInfo_t']]], + ['clearpendingacknowledgments_2',['clearPendingAcknowledgments',['../core__mqtt__agent_8c.html#afb076dcf75919d5b638c33054b95461d',1,'core_mqtt_agent.c']]], + ['clientidentifierlength_3',['clientIdentifierLength',['coreMQTT/struct_m_q_t_t_connect_info__t.html#a8077ef36ab318f3d35bee6f098fa54d4',1,'MQTTConnectInfo_t']]], + ['cmdcompletecallback_4',['cmdCompleteCallback',['../struct_m_q_t_t_agent_command_info__t.html#a4c9e9b55c7b576a390f734238b60f3aa',1,'MQTTAgentCommandInfo_t']]], + ['commandtype_5',['commandType',['../struct_m_q_t_t_agent_command.html#ae810f32d3650badbe3f8a86d5754adf1',1,'MQTTAgentCommand']]], + ['concludecommand_6',['concludeCommand',['../core__mqtt__agent_8c.html#a848611250b309e0d84cb18a42fbf6391',1,'core_mqtt_agent.c']]], + ['configurations_7',['Configurations',['../core_mqtt_agent_config.html',1,'(Global Namespace)'],['coreMQTT/core_mqtt_config.html',1,'(Global Namespace)']]], + ['connect_8',['CONNECT',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a20391dd2915a0e64343d24c2f2e40b95',1,'core_mqtt_agent.h']]], + ['connectstatus_9',['connectStatus',['coreMQTT/struct_m_q_t_t_context__t.html#a4e38c4dc77e7751a0ad8730a41bee47f',1,'MQTTContext_t']]], + ['constants_10',['Constants',['coreMQTT/group__mqtt__constants.html',1,'']]], + ['controlpacketsent_11',['controlPacketSent',['coreMQTT/struct_m_q_t_t_context__t.html#af9724f2426132e3ce96a03892902ef89',1,'MQTTContext_t']]], + ['core_5fmqtt_2ec_12',['core_mqtt.c',['coreMQTT/core__mqtt_8c.html',1,'']]], + ['core_5fmqtt_2eh_13',['core_mqtt.h',['coreMQTT/core__mqtt_8h.html',1,'']]], + ['core_5fmqtt_5fagent_2ec_14',['core_mqtt_agent.c',['../core__mqtt__agent_8c.html',1,'']]], + ['core_5fmqtt_5fagent_2eh_15',['core_mqtt_agent.h',['../core__mqtt__agent_8h.html',1,'']]], + ['core_5fmqtt_5fagent_5fcommand_5ffunctions_2ec_16',['core_mqtt_agent_command_functions.c',['../core__mqtt__agent__command__functions_8c.html',1,'']]], + ['core_5fmqtt_5fagent_5fcommand_5ffunctions_2eh_17',['core_mqtt_agent_command_functions.h',['../core__mqtt__agent__command__functions_8h.html',1,'']]], + ['core_5fmqtt_5fagent_5fconfig_5fdefaults_2eh_18',['core_mqtt_agent_config_defaults.h',['../core__mqtt__agent__config__defaults_8h.html',1,'']]], + ['core_5fmqtt_5fagent_5fdefault_5flogging_2eh_19',['core_mqtt_agent_default_logging.h',['../core__mqtt__agent__default__logging_8h.html',1,'']]], + ['core_5fmqtt_5fagent_5fmessage_5finterface_2eh_20',['core_mqtt_agent_message_interface.h',['../core__mqtt__agent__message__interface_8h.html',1,'']]], + ['core_5fmqtt_5fconfig_5fdefaults_2eh_21',['core_mqtt_config_defaults.h',['coreMQTT/core__mqtt__config__defaults_8h.html',1,'']]], + ['core_5fmqtt_5fserializer_2ec_22',['core_mqtt_serializer.c',['coreMQTT/core__mqtt__serializer_8c.html',1,'']]], + ['core_5fmqtt_5fserializer_2eh_23',['core_mqtt_serializer.h',['coreMQTT/core__mqtt__serializer_8h.html',1,'']]], + ['core_5fmqtt_5fstate_2ec_24',['core_mqtt_state.c',['coreMQTT/core__mqtt__state_8c.html',1,'']]], + ['core_5fmqtt_5fstate_2eh_25',['core_mqtt_state.h',['coreMQTT/core__mqtt__state_8h.html',1,'']]], + ['createandaddcommand_26',['createAndAddCommand',['../core__mqtt__agent_8c.html#a594dbfd47f77c6988960110da3c25a2c',1,'core_mqtt_agent.c']]], + ['createcommand_27',['createCommand',['../core__mqtt__agent_8c.html#a4f2d34a65263b609595aa8f1705ff89f',1,'core_mqtt_agent.c']]] +]; diff --git a/v1.3.0/search/all_3.js b/v1.3.0/search/all_3.js new file mode 100644 index 00000000..d69965e6 --- /dev/null +++ b/v1.3.0/search/all_3.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['deserializationresult_0',['deserializationResult',['coreMQTT/struct_m_q_t_t_deserialized_info__t.html#a7df1b7b60404c9f1604fec0081d2625d',1,'MQTTDeserializedInfo_t']]], + ['design_1',['Design',['../mqtt_agent_design.html',1,'(Global Namespace)'],['coreMQTT/mqtt_design.html',1,'(Global Namespace)']]], + ['disconnect_2',['DISCONNECT',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a2f6318afb30e8e2817e6203ebedc8173',1,'core_mqtt_agent.h']]], + ['dup_3',['dup',['coreMQTT/struct_m_q_t_t_publish_info__t.html#aa1c8954e83bfa678d1ff5429679d4e89',1,'MQTTPublishInfo_t']]] +]; diff --git a/v1.3.0/search/all_4.js b/v1.3.0/search/all_4.js new file mode 100644 index 00000000..f9370c29 --- /dev/null +++ b/v1.3.0/search/all_4.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['endloop_0',['endLoop',['../struct_m_q_t_t_agent_command_func_returns__t.html#aea0742c902ee70380f308b7f957dc9a2',1,'MQTTAgentCommandFuncReturns_t']]], + ['enumerated_20types_1',['Enumerated Types',['../group__mqtt__agent__enum__types.html',1,'(Global Namespace)'],['coreMQTT/group__mqtt__enum__types.html',1,'(Global Namespace)']]] +]; diff --git a/v1.3.0/search/all_5.js b/v1.3.0/search/all_5.js new file mode 100644 index 00000000..5455fb0c --- /dev/null +++ b/v1.3.0/search/all_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['functions_0',['Functions',['../mqtt_agent_functions.html',1,'(Global Namespace)'],['coreMQTT/mqtt_functions.html',1,'(Global Namespace)']]] +]; diff --git a/v1.3.0/search/all_6.js b/v1.3.0/search/all_6.js new file mode 100644 index 00000000..778c0148 --- /dev/null +++ b/v1.3.0/search/all_6.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['getagentfrommqttcontext_0',['getAgentFromMQTTContext',['../core__mqtt__agent_8c.html#adb6cd05d1e6b270a021cb50980654707',1,'core_mqtt_agent.c']]], + ['getawaitingoperation_1',['getAwaitingOperation',['../core__mqtt__agent_8c.html#af4ab608204e853ab34bda491a47f6b84',1,'core_mqtt_agent.c']]], + ['getcommand_2',['getCommand',['../struct_m_q_t_t_agent_message_interface__t.html#aaa4d0614e8289d7ea12422e66c1e8689',1,'MQTTAgentMessageInterface_t']]], + ['gettime_3',['getTime',['coreMQTT/struct_m_q_t_t_context__t.html#aabe1d302a16771292151013e8e30c582',1,'MQTTContext_t']]] +]; diff --git a/v1.3.0/search/all_7.js b/v1.3.0/search/all_7.js new file mode 100644 index 00000000..fc41aafc --- /dev/null +++ b/v1.3.0/search/all_7.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['handleacks_0',['handleAcks',['../core__mqtt__agent_8c.html#ace2cab4efce97019ae5e12ccae2780cd',1,'core_mqtt_agent.c']]], + ['headerlength_1',['headerLength',['coreMQTT/struct_m_q_t_t_packet_info__t.html#aa7de1631ed8e08410942d36a72db558a',1,'MQTTPacketInfo_t']]] +]; diff --git a/v1.3.0/search/all_8.js b/v1.3.0/search/all_8.js new file mode 100644 index 00000000..9fcbff89 --- /dev/null +++ b/v1.3.0/search/all_8.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['incomingpublishrecordmaxcount_0',['incomingPublishRecordMaxCount',['coreMQTT/struct_m_q_t_t_context__t.html#aa33ed2e10380a854629f1386d0323ea8',1,'MQTTContext_t']]], + ['incomingpublishrecords_1',['incomingPublishRecords',['coreMQTT/struct_m_q_t_t_context__t.html#afc147663a5933de81212fa77057f0a4d',1,'MQTTContext_t']]], + ['index_2',['index',['coreMQTT/struct_m_q_t_t_context__t.html#a41b7735cd0746563483b72e17cf103aa',1,'MQTTContext_t']]], + ['iov_5fbase_3',['iov_base',['coreMQTT/struct_transport_out_vector__t.html#a0ffa5c06bf00006cbafa8e244951038d',1,'TransportOutVector_t']]], + ['iov_5flen_4',['iov_len',['coreMQTT/struct_transport_out_vector__t.html#ada73dafb2d34311f33fefad38603b35c',1,'TransportOutVector_t']]], + ['isspaceinpendingacklist_5',['isSpaceInPendingAckList',['../core__mqtt__agent_8c.html#a6082ea8cf8fe3f34e0a8de08d6980a29',1,'core_mqtt_agent.c']]] +]; diff --git a/v1.3.0/search/all_9.js b/v1.3.0/search/all_9.js new file mode 100644 index 00000000..86d59e93 --- /dev/null +++ b/v1.3.0/search/all_9.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['keepaliveintervalsec_0',['keepAliveIntervalSec',['coreMQTT/struct_m_q_t_t_context__t.html#afd6071827ef48b230212a5725c2075be',1,'MQTTContext_t']]], + ['keepaliveseconds_1',['keepAliveSeconds',['coreMQTT/struct_m_q_t_t_connect_info__t.html#a7d05d53261732ebdfbb9ee665a347591',1,'MQTTConnectInfo_t']]] +]; diff --git a/v1.3.0/search/all_a.js b/v1.3.0/search/all_a.js new file mode 100644 index 00000000..a8b24df3 --- /dev/null +++ b/v1.3.0/search/all_a.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['lastpacketrxtime_0',['lastPacketRxTime',['coreMQTT/struct_m_q_t_t_context__t.html#a7111ef16e4a4e75a72861f6f3ea8a7c3',1,'MQTTContext_t']]], + ['lastpackettxtime_1',['lastPacketTxTime',['coreMQTT/struct_m_q_t_t_context__t.html#a01acf90953e830ba3e7f44182cb1d482',1,'MQTTContext_t']]], + ['logdebug_2',['LogDebug',['../core__mqtt__agent__default__logging_8h.html#af60e8ffc327d136e5d0d8441ed98c98d',1,'core_mqtt_agent_default_logging.h']]], + ['logerror_3',['LogError',['../core__mqtt__agent__default__logging_8h.html#a8d9dbaaa88129137a4c68ba0456a18b1',1,'core_mqtt_agent_default_logging.h']]], + ['loginfo_4',['LogInfo',['../core__mqtt__agent__default__logging_8h.html#a00810b1cb9d2f25d25ce2d4d93815fba',1,'core_mqtt_agent_default_logging.h']]], + ['logwarn_5',['LogWarn',['../core__mqtt__agent__default__logging_8h.html#a7da92048aaf0cbfcacde9539c98a0e05',1,'core_mqtt_agent_default_logging.h']]] +]; diff --git a/v1.3.0/search/all_b.js b/v1.3.0/search/all_b.js new file mode 100644 index 00000000..37c075e9 --- /dev/null +++ b/v1.3.0/search/all_b.js @@ -0,0 +1,133 @@ +var searchData= +[ + ['message_20interface_0',['Message Interface',['../mqtt_agent_message_interface.html',1,'']]], + ['mqtt_5fagent_5fdo_5fnot_5fuse_5fcustom_5fconfig_1',['MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG',['../core__mqtt__agent__config__defaults_8h.html#aa10d2a7250bc5471633048ad4f238138',1,'core_mqtt_agent_config_defaults.h']]], + ['mqtt_5fagent_5ffunction_5ftable_2',['MQTT_AGENT_FUNCTION_TABLE',['../core__mqtt__agent__command__functions_8h.html#adf96732c68dea38cfc3b325639304bba',1,'core_mqtt_agent_command_functions.h']]], + ['mqtt_5fagent_5fmax_5fevent_5fqueue_5fwait_5ftime_3',['MQTT_AGENT_MAX_EVENT_QUEUE_WAIT_TIME',['../core__mqtt__agent__config__defaults_8h.html#a9fbd3d9f02a4cabb01e900cfa4d01980',1,'core_mqtt_agent_config_defaults.h']]], + ['mqtt_5fagent_5fmax_5foutstanding_5facks_4',['MQTT_AGENT_MAX_OUTSTANDING_ACKS',['../core__mqtt__agent__config__defaults_8h.html#afc749954a2c0c3a81bcf1e2eb5fecaad',1,'core_mqtt_agent_config_defaults.h']]], + ['mqtt_5fagent_5fuse_5fqos_5f1_5f2_5fpublish_5',['MQTT_AGENT_USE_QOS_1_2_PUBLISH',['../core__mqtt__agent__config__defaults_8h.html#af20d4b1937cbd282f193f69b1b27742e',1,'core_mqtt_agent_config_defaults.h']]], + ['mqtt_5fconnect_6',['MQTT_Connect',['coreMQTT/mqtt_connect_function.html',1,'']]], + ['mqtt_5fdeserializeack_7',['MQTT_DeserializeAck',['coreMQTT/mqtt_deserializeack_function.html',1,'']]], + ['mqtt_5fdeserializepublish_8',['MQTT_DeserializePublish',['coreMQTT/mqtt_deserializepublish_function.html',1,'']]], + ['mqtt_5fdisconnect_9',['MQTT_Disconnect',['coreMQTT/mqtt_disconnect_function.html',1,'']]], + ['mqtt_5fgetconnectpacketsize_10',['MQTT_GetConnectPacketSize',['coreMQTT/mqtt_getconnectpacketsize_function.html',1,'']]], + ['mqtt_5fgetdisconnectpacketsize_11',['MQTT_GetDisconnectPacketSize',['coreMQTT/mqtt_getdisconnectpacketsize_function.html',1,'']]], + ['mqtt_5fgetincomingpackettypeandlength_12',['MQTT_GetIncomingPacketTypeAndLength',['coreMQTT/mqtt_getincomingpackettypeandlength_function.html',1,'']]], + ['mqtt_5fgetpacketid_13',['MQTT_GetPacketId',['coreMQTT/mqtt_getpacketid_function.html',1,'']]], + ['mqtt_5fgetpingreqpacketsize_14',['MQTT_GetPingreqPacketSize',['coreMQTT/mqtt_getpingreqpacketsize_function.html',1,'']]], + ['mqtt_5fgetpublishpacketsize_15',['MQTT_GetPublishPacketSize',['coreMQTT/mqtt_getpublishpacketsize_function.html',1,'']]], + ['mqtt_5fgetsubackstatuscodes_16',['MQTT_GetSubAckStatusCodes',['coreMQTT/mqtt_getsubackstatuscodes_function.html',1,'']]], + ['mqtt_5fgetsubscribepacketsize_17',['MQTT_GetSubscribePacketSize',['coreMQTT/mqtt_getsubscribepacketsize_function.html',1,'']]], + ['mqtt_5fgetunsubscribepacketsize_18',['MQTT_GetUnsubscribePacketSize',['coreMQTT/mqtt_getunsubscribepacketsize_function.html',1,'']]], + ['mqtt_5finit_19',['MQTT_Init',['coreMQTT/mqtt_init_function.html',1,'']]], + ['mqtt_5fping_20',['MQTT_Ping',['coreMQTT/mqtt_ping_function.html',1,'']]], + ['mqtt_5fprocessloop_21',['MQTT_ProcessLoop',['coreMQTT/mqtt_processloop_function.html',1,'']]], + ['mqtt_5fpublish_22',['MQTT_Publish',['coreMQTT/mqtt_publish_function.html',1,'']]], + ['mqtt_5fpublishtoresend_23',['MQTT_PublishToResend',['coreMQTT/mqtt_publishtoresend_function.html',1,'']]], + ['mqtt_5freceiveloop_24',['MQTT_ReceiveLoop',['coreMQTT/mqtt_receiveloop_function.html',1,'']]], + ['mqtt_5fserializeack_25',['MQTT_SerializeAck',['coreMQTT/mqtt_serializeack_function.html',1,'']]], + ['mqtt_5fserializeconnect_26',['MQTT_SerializeConnect',['coreMQTT/mqtt_serializeconnect_function.html',1,'']]], + ['mqtt_5fserializedisconnect_27',['MQTT_SerializeDisconnect',['coreMQTT/mqtt_serializedisconnect_function.html',1,'']]], + ['mqtt_5fserializepingreq_28',['MQTT_SerializePingreq',['coreMQTT/mqtt_serializepingreq_function.html',1,'']]], + ['mqtt_5fserializepublish_29',['MQTT_SerializePublish',['coreMQTT/mqtt_serializepublish_function.html',1,'']]], + ['mqtt_5fserializepublishheader_30',['MQTT_SerializePublishHeader',['coreMQTT/mqtt_serializepublishheader_function.html',1,'']]], + ['mqtt_5fserializesubscribe_31',['MQTT_SerializeSubscribe',['coreMQTT/mqtt_serializesubscribe_function.html',1,'']]], + ['mqtt_5fserializeunsubscribe_32',['MQTT_SerializeUnsubscribe',['coreMQTT/mqtt_serializeunsubscribe_function.html',1,'']]], + ['mqtt_5fstatus_5fstrerror_33',['MQTT_Status_strerror',['coreMQTT/mqtt_status_strerror_function.html',1,'']]], + ['mqtt_5fsubscribe_34',['MQTT_Subscribe',['coreMQTT/mqtt_subscribe_function.html',1,'']]], + ['mqtt_5funsubscribe_35',['MQTT_Unsubscribe',['coreMQTT/mqtt_unsubscribe_function.html',1,'']]], + ['mqttagent_5fcancelall_36',['MQTTAgent_CancelAll',['../mqtt_agent_cancel_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8c.html#a0362d7d3d68628413f01b32ec2ff4ab6',1,'MQTTAgent_CancelAll(MQTTAgentContext_t *pMqttAgentContext): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#a0362d7d3d68628413f01b32ec2ff4ab6',1,'MQTTAgent_CancelAll(MQTTAgentContext_t *pMqttAgentContext): core_mqtt_agent.c']]], + ['mqttagent_5fcommandloop_37',['MQTTAgent_CommandLoop',['../mqtt_agent_command_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8c.html#a9dafeb1701b1a0ee897b626a09cfcff7',1,'MQTTAgent_CommandLoop(MQTTAgentContext_t *pMqttAgentContext): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#a9dafeb1701b1a0ee897b626a09cfcff7',1,'MQTTAgent_CommandLoop(MQTTAgentContext_t *pMqttAgentContext): core_mqtt_agent.c']]], + ['mqttagent_5fconnect_38',['MQTTAgent_Connect',['../mqtt_agent_connect_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8c.html#a782425e50d258837d23e379471254412',1,'MQTTAgent_Connect(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentConnectArgs_t *pConnectArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#a782425e50d258837d23e379471254412',1,'MQTTAgent_Connect(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentConnectArgs_t *pConnectArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5fdisconnect_39',['MQTTAgent_Disconnect',['../mqtt_agent_disconnect_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8h.html#a26687b9b762b5f52b14387bacdf17224',1,'MQTTAgent_Disconnect(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#a26687b9b762b5f52b14387bacdf17224',1,'MQTTAgent_Disconnect(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5finit_40',['MQTTAgent_Init',['../mqtt_agent_init_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8h.html#a584863528e72229f35003485f7ee0edd',1,'MQTTAgent_Init(MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentMessageInterface_t *pMsgInterface, const MQTTFixedBuffer_t *pNetworkBuffer, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getCurrentTimeMs, MQTTAgentIncomingPublishCallback_t incomingCallback, void *pIncomingPacketContext): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#a584863528e72229f35003485f7ee0edd',1,'MQTTAgent_Init(MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentMessageInterface_t *pMsgInterface, const MQTTFixedBuffer_t *pNetworkBuffer, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getCurrentTimeMs, MQTTAgentIncomingPublishCallback_t incomingCallback, void *pIncomingPacketContext): core_mqtt_agent.c']]], + ['mqttagent_5fping_41',['MQTTAgent_Ping',['../mqtt_agent_ping_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8c.html#ae260e29f31d51953cbab2e1437f645ed',1,'MQTTAgent_Ping(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#ae260e29f31d51953cbab2e1437f645ed',1,'MQTTAgent_Ping(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5fprocessloop_42',['MQTTAgent_ProcessLoop',['../core__mqtt__agent_8c.html#aa14c9c86e036d0b1f5c04a538597cc46',1,'MQTTAgent_ProcessLoop(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#aa14c9c86e036d0b1f5c04a538597cc46',1,'MQTTAgent_ProcessLoop(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5fpublish_43',['MQTTAgent_Publish',['../mqtt_agent_publish_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8c.html#afea2405ab859324cb241ea47e6a5ab81',1,'MQTTAgent_Publish(const MQTTAgentContext_t *pMqttAgentContext, MQTTPublishInfo_t *pPublishInfo, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#afea2405ab859324cb241ea47e6a5ab81',1,'MQTTAgent_Publish(const MQTTAgentContext_t *pMqttAgentContext, MQTTPublishInfo_t *pPublishInfo, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5fresumesession_44',['MQTTAgent_ResumeSession',['../mqtt_agent_resume_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8c.html#a75065d6bff5f2d32831f2c74922296fb',1,'MQTTAgent_ResumeSession(MQTTAgentContext_t *pMqttAgentContext, bool sessionPresent): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#a75065d6bff5f2d32831f2c74922296fb',1,'MQTTAgent_ResumeSession(MQTTAgentContext_t *pMqttAgentContext, bool sessionPresent): core_mqtt_agent.c']]], + ['mqttagent_5fsubscribe_45',['MQTTAgent_Subscribe',['../mqtt_agent_subscribe_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8c.html#a651cf10182392ecea5e8609af8855d49',1,'MQTTAgent_Subscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#a651cf10182392ecea5e8609af8855d49',1,'MQTTAgent_Subscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5fterminate_46',['MQTTAgent_Terminate',['../mqtt_agent_terminate_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8c.html#ae1b19c10831f72251603b045f2608313',1,'MQTTAgent_Terminate(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#ae1b19c10831f72251603b045f2608313',1,'MQTTAgent_Terminate(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5funsubscribe_47',['MQTTAgent_Unsubscribe',['../mqtt_agent_unsubscribe_function.html',1,'mqtt_agent_functions'],['../core__mqtt__agent_8h.html#ac3f70c81c8f8947dfb7346045c8edb63',1,'MQTTAgent_Unsubscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#ac3f70c81c8f8947dfb7346045c8edb63',1,'MQTTAgent_Unsubscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagentackinfo_5ft_48',['MQTTAgentAckInfo_t',['../struct_m_q_t_t_agent_ack_info__t.html',1,'']]], + ['mqttagentcommand_49',['MQTTAgentCommand',['../struct_m_q_t_t_agent_command.html',1,'']]], + ['mqttagentcommand_5fconnect_50',['MQTTAgentCommand_Connect',['../core__mqtt__agent__command__functions_8h.html#abe89d0e3cf7ddd095a3c840df4955a9e',1,'MQTTAgentCommand_Connect(MQTTAgentContext_t *pMqttAgentContext, void *pVoidConnectArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#abe89d0e3cf7ddd095a3c840df4955a9e',1,'MQTTAgentCommand_Connect(MQTTAgentContext_t *pMqttAgentContext, void *pVoidConnectArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fdisconnect_51',['MQTTAgentCommand_Disconnect',['../core__mqtt__agent__command__functions_8h.html#aa7507c7a01cdc06af0d5f42711357b6e',1,'MQTTAgentCommand_Disconnect(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#aa7507c7a01cdc06af0d5f42711357b6e',1,'MQTTAgentCommand_Disconnect(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fping_52',['MQTTAgentCommand_Ping',['../core__mqtt__agent__command__functions_8h.html#a9840f5683a5e513b99ab15961e17e42b',1,'MQTTAgentCommand_Ping(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#a9840f5683a5e513b99ab15961e17e42b',1,'MQTTAgentCommand_Ping(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fprocessloop_53',['MQTTAgentCommand_ProcessLoop',['../core__mqtt__agent__command__functions_8c.html#ae2a8b7caae9b06f36f9784663c8f8a49',1,'MQTTAgentCommand_ProcessLoop(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8h.html#ae2a8b7caae9b06f36f9784663c8f8a49',1,'MQTTAgentCommand_ProcessLoop(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fpublish_54',['MQTTAgentCommand_Publish',['../core__mqtt__agent__command__functions_8c.html#a5b4be57b6b6a55054e94850c805fd943',1,'MQTTAgentCommand_Publish(MQTTAgentContext_t *pMqttAgentContext, void *pPublishArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8h.html#a5b4be57b6b6a55054e94850c805fd943',1,'MQTTAgentCommand_Publish(MQTTAgentContext_t *pMqttAgentContext, void *pPublishArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fsubscribe_55',['MQTTAgentCommand_Subscribe',['../core__mqtt__agent__command__functions_8c.html#accbd434285c7cd823270614513ecd4a0',1,'MQTTAgentCommand_Subscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8h.html#accbd434285c7cd823270614513ecd4a0',1,'MQTTAgentCommand_Subscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fterminate_56',['MQTTAgentCommand_Terminate',['../core__mqtt__agent__command__functions_8c.html#aa017a4f5741920140688973e4b8bf0f1',1,'MQTTAgentCommand_Terminate(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8h.html#aa017a4f5741920140688973e4b8bf0f1',1,'MQTTAgentCommand_Terminate(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5funsubscribe_57',['MQTTAgentCommand_Unsubscribe',['../core__mqtt__agent__command__functions_8h.html#aea9ea15866e2e7940469d9a200b45362',1,'MQTTAgentCommand_Unsubscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#aea9ea15866e2e7940469d9a200b45362',1,'MQTTAgentCommand_Unsubscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommandcallback_5ft_58',['MQTTAgentCommandCallback_t',['../group__mqtt__agent__callback__types.html#gaa2497c28b3fb55b8dc38b0873f749eef',1,'core_mqtt_agent.h']]], + ['mqttagentcommandcontext_5ft_59',['MQTTAgentCommandContext_t',['../group__mqtt__agent__struct__types.html#ga953da1618097a29381f3fc38f576055c',1,'core_mqtt_agent.h']]], + ['mqttagentcommandfunc_5ft_60',['MQTTAgentCommandFunc_t',['../core__mqtt__agent__command__functions_8h.html#af1595d37e917f7e6f336bc866d00e37d',1,'core_mqtt_agent_command_functions.h']]], + ['mqttagentcommandfuncreturns_5ft_61',['MQTTAgentCommandFuncReturns_t',['../struct_m_q_t_t_agent_command_func_returns__t.html',1,'']]], + ['mqttagentcommandget_5ft_62',['MQTTAgentCommandGet_t',['../core__mqtt__agent__message__interface_8h.html#a2d52058b819a1a4e813b8f37cbdda5a2',1,'core_mqtt_agent_message_interface.h']]], + ['mqttagentcommandinfo_5ft_63',['MQTTAgentCommandInfo_t',['../struct_m_q_t_t_agent_command_info__t.html',1,'']]], + ['mqttagentcommandrelease_5ft_64',['MQTTAgentCommandRelease_t',['../core__mqtt__agent__message__interface_8h.html#a95a4a0f7d915b957f7fc986874f954f9',1,'core_mqtt_agent_message_interface.h']]], + ['mqttagentcommandtype_5ft_65',['MQTTAgentCommandType_t',['../group__mqtt__agent__enum__types.html#ga76604fa58b7ee6c32ba084fda9379f33',1,'core_mqtt_agent.h']]], + ['mqttagentconnectargs_5ft_66',['MQTTAgentConnectArgs_t',['../struct_m_q_t_t_agent_connect_args__t.html',1,'']]], + ['mqttagentcontext_5ft_67',['MQTTAgentContext_t',['../struct_m_q_t_t_agent_context__t.html',1,'']]], + ['mqttagentincomingpublishcallback_5ft_68',['MQTTAgentIncomingPublishCallback_t',['../group__mqtt__agent__callback__types.html#gacdfb8687b1217d321e7cc58e365ec6a1',1,'core_mqtt_agent.h']]], + ['mqttagentmessagecontext_5ft_69',['MQTTAgentMessageContext_t',['../group__mqtt__agent__struct__types.html#ga3c47f2ebcec2e1150e40d039639e5a3b',1,'core_mqtt_agent_message_interface.h']]], + ['mqttagentmessageinterface_5ft_70',['MQTTAgentMessageInterface_t',['../struct_m_q_t_t_agent_message_interface__t.html',1,'']]], + ['mqttagentmessagerecv_5ft_71',['MQTTAgentMessageRecv_t',['../core__mqtt__agent__message__interface_8h.html#aafd35ead1877c1235d407d4e487f1a0a',1,'core_mqtt_agent_message_interface.h']]], + ['mqttagentmessagesend_5ft_72',['MQTTAgentMessageSend_t',['../core__mqtt__agent__message__interface_8h.html#a4cdea15a0c979080b1a83f0753d82e8c',1,'core_mqtt_agent_message_interface.h']]], + ['mqttagentreturninfo_5ft_73',['MQTTAgentReturnInfo_t',['../struct_m_q_t_t_agent_return_info__t.html',1,'']]], + ['mqttagentsubscribeargs_5ft_74',['MQTTAgentSubscribeArgs_t',['../struct_m_q_t_t_agent_subscribe_args__t.html',1,'']]], + ['mqttbadparameter_75',['MQTTBadParameter',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa39030c93b0263b2699502a074f003b5',1,]]], + ['mqttbadresponse_76',['MQTTBadResponse',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa5d7507e7664a14d63a8bc44b280093e',1,]]], + ['mqttconnected_77',['MQTTConnected',['coreMQTT/group__mqtt__enum__types.html#gga9f84d003695205cf10a7bd0bafb3dbf6a82c8f64d976734e5632e5257bc429ef5',1,]]], + ['mqttconnectinfo_5ft_78',['MQTTConnectInfo_t',['coreMQTT/struct_m_q_t_t_connect_info__t.html',1,'']]], + ['mqttconnectionstatus_5ft_79',['MQTTConnectionStatus_t',['coreMQTT/group__mqtt__enum__types.html#ga9f84d003695205cf10a7bd0bafb3dbf6',1,]]], + ['mqttcontext_80',['mqttContext',['../struct_m_q_t_t_agent_context__t.html#aec01b2b61213956dc2219f620964a055',1,'MQTTAgentContext_t']]], + ['mqttcontext_5ft_81',['MQTTContext_t',['coreMQTT/struct_m_q_t_t_context__t.html',1,'']]], + ['mqttdeserializedinfo_5ft_82',['MQTTDeserializedInfo_t',['coreMQTT/struct_m_q_t_t_deserialized_info__t.html',1,'']]], + ['mqtteventcallback_83',['mqttEventCallback',['../core__mqtt__agent_8c.html#a4aeca55423966c3eff1734316f6a7466',1,'core_mqtt_agent.c']]], + ['mqtteventcallback_5ft_84',['MQTTEventCallback_t',['coreMQTT/group__mqtt__callback__types.html#ga00d348277ed4fde23c95bfc749ae954a',1,]]], + ['mqttfixedbuffer_5ft_85',['MQTTFixedBuffer_t',['coreMQTT/struct_m_q_t_t_fixed_buffer__t.html',1,'']]], + ['mqttgetcurrenttimefunc_5ft_86',['MQTTGetCurrentTimeFunc_t',['coreMQTT/group__mqtt__callback__types.html#gae3bea55b0e49e5208b8c5709a5ea23aa',1,]]], + ['mqttillegalstate_87',['MQTTIllegalState',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca67905d7a05f98faa557a73eb5092bd8f',1,]]], + ['mqttkeepalivetimeout_88',['MQTTKeepAliveTimeout',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca076ca8965e836a06e707a94adb26144f',1,]]], + ['mqttneedmorebytes_89',['MQTTNeedMoreBytes',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa97df53014d919df5ecd54398f89f9b9',1,]]], + ['mqttnodataavailable_90',['MQTTNoDataAvailable',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca676f21c0ddf297ae3ec874bc829aa957',1,]]], + ['mqttnomemory_91',['MQTTNoMemory',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735cab1be4db832a0468f024243bca151a8df',1,]]], + ['mqttnotconnected_92',['MQTTNotConnected',['coreMQTT/group__mqtt__enum__types.html#gga9f84d003695205cf10a7bd0bafb3dbf6a0320177ebf1f1b2e24646b44702cec69',1,]]], + ['mqttpacketinfo_5ft_93',['MQTTPacketInfo_t',['coreMQTT/struct_m_q_t_t_packet_info__t.html',1,'']]], + ['mqttpuback_94',['MQTTPuback',['coreMQTT/group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a53d5939c680962f37c15ee87ffd63d0f',1,]]], + ['mqttpubackinfo_5ft_95',['MQTTPubAckInfo_t',['coreMQTT/struct_m_q_t_t_pub_ack_info__t.html',1,'']]], + ['mqttpubackpending_96',['MQTTPubAckPending',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94ab086c55acf106cdc8d420f90899b6803',1,]]], + ['mqttpubacksend_97',['MQTTPubAckSend',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a65f6f7b343a30fc0558e3aeeb8c97f35',1,]]], + ['mqttpubacktype_5ft_98',['MQTTPubAckType_t',['coreMQTT/group__mqtt__enum__types.html#ga8c1bee959b3ed5fab2a2688dd72bf237',1,]]], + ['mqttpubcomp_99',['MQTTPubcomp',['coreMQTT/group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a910c34311ad6a2341afc04839e1c13bd',1,]]], + ['mqttpubcomppending_100',['MQTTPubCompPending',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a3281a28d1829d954b596f091b547b627',1,]]], + ['mqttpubcompsend_101',['MQTTPubCompSend',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a7d88904d550b502b4424a41aa4205e56',1,]]], + ['mqttpublishdone_102',['MQTTPublishDone',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94ad07733793a235ef9a6a04d16637cd7dc',1,]]], + ['mqttpublishinfo_5ft_103',['MQTTPublishInfo_t',['coreMQTT/struct_m_q_t_t_publish_info__t.html',1,'']]], + ['mqttpublishsend_104',['MQTTPublishSend',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a896b1507647b504c9208580e4cde26ad',1,]]], + ['mqttpublishstate_5ft_105',['MQTTPublishState_t',['coreMQTT/group__mqtt__enum__types.html#ga0480de7552eedd739a26a23fa8e6fd94',1,]]], + ['mqttpubrec_106',['MQTTPubrec',['coreMQTT/group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237a8c98d5d1a68dda33d9039009ab4ef053',1,]]], + ['mqttpubrecpending_107',['MQTTPubRecPending',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a1bea59454700be9b683b7eb8aaf6bb4f',1,]]], + ['mqttpubrecsend_108',['MQTTPubRecSend',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a11e2319a2b25b82121471743d39761e1',1,]]], + ['mqttpubrel_109',['MQTTPubrel',['coreMQTT/group__mqtt__enum__types.html#gga8c1bee959b3ed5fab2a2688dd72bf237af2d737088a231c88e7603acfdbc4fc8c',1,]]], + ['mqttpubrelpending_110',['MQTTPubRelPending',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a695431cde1dc9dc5a2dcbd10eba49df2',1,]]], + ['mqttpubrelsend_111',['MQTTPubRelSend',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a5d2ee2709c6dc7a1eb8b9c40f318909b',1,]]], + ['mqttqos0_112',['MQTTQoS0',['coreMQTT/group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aaad51b23a1ae1417f96d8f343c788d1d2',1,]]], + ['mqttqos1_113',['MQTTQoS1',['coreMQTT/group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aa019d0b8a8cfadb6f98462b046bdacbb2',1,]]], + ['mqttqos2_114',['MQTTQoS2',['coreMQTT/group__mqtt__enum__types.html#ggae308a5928d7f537379c29a894228093aa85e04ac0465cbdef6dd69ff71b2bbfbb',1,]]], + ['mqttqos_5ft_115',['MQTTQoS_t',['coreMQTT/group__mqtt__enum__types.html#gae308a5928d7f537379c29a894228093a',1,]]], + ['mqttrecvfailed_116',['MQTTRecvFailed',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735caa14bc8aa4ad218702d782366945d43ac',1,]]], + ['mqttsendfailed_117',['MQTTSendFailed',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735cafd06b63fe9677fa2af06b0f4c7d4ad55',1,]]], + ['mqttserverrefused_118',['MQTTServerRefused',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca25a3d1747e308e99daa805fe576f84b9',1,]]], + ['mqttstatecollision_119',['MQTTStateCollision',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca8d05b92240dea6df08eab5a9e3799c11',1,]]], + ['mqttstatecursor_5ft_120',['MQTTStateCursor_t',['coreMQTT/group__mqtt__basic__types.html#ga2ca7d486d83fe555953a8c7876ee0d6e',1,]]], + ['mqttstatenull_121',['MQTTStateNull',['coreMQTT/group__mqtt__enum__types.html#gga0480de7552eedd739a26a23fa8e6fd94a8349567b7a9efb3913a64a8f4f6fe5c9',1,]]], + ['mqttstatus_5ft_122',['MQTTStatus_t',['coreMQTT/group__mqtt__enum__types.html#gaba7ec045874a1c3432f99173367f735c',1,]]], + ['mqttsubackfailure_123',['MQTTSubAckFailure',['coreMQTT/group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611aeb83b20da8eda934cde6b92db225a808',1,]]], + ['mqttsubackstatus_5ft_124',['MQTTSubAckStatus_t',['coreMQTT/group__mqtt__enum__types.html#ga48dabc1579e3c0ac6058ce9068054611',1,]]], + ['mqttsubacksuccessqos0_125',['MQTTSubAckSuccessQos0',['coreMQTT/group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611abcc3040d7d53025baee3542c40758abb',1,]]], + ['mqttsubacksuccessqos1_126',['MQTTSubAckSuccessQos1',['coreMQTT/group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611ab180361a6da712c8144d8c499537787d',1,]]], + ['mqttsubacksuccessqos2_127',['MQTTSubAckSuccessQos2',['coreMQTT/group__mqtt__enum__types.html#gga48dabc1579e3c0ac6058ce9068054611a877b2afbc6ec7d9ab57d4862caadf4f1',1,]]], + ['mqttsubscribeinfo_5ft_128',['MQTTSubscribeInfo_t',['coreMQTT/struct_m_q_t_t_subscribe_info__t.html',1,'']]], + ['mqttsuccess_129',['MQTTSuccess',['coreMQTT/group__mqtt__enum__types.html#ggaba7ec045874a1c3432f99173367f735ca484e062cb4f3fccc1858dd25cfeee056',1,]]] +]; diff --git a/v1.3.0/search/all_c.js b/v1.3.0/search/all_c.js new file mode 100644 index 00000000..e459c420 --- /dev/null +++ b/v1.3.0/search/all_c.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['networkbuffer_0',['networkBuffer',['coreMQTT/struct_m_q_t_t_context__t.html#a231c5576a6ce389317a3f00f95628276',1,'MQTTContext_t']]], + ['networkcontext_5ft_1',['NetworkContext_t',['coreMQTT/group__mqtt__struct__types.html#ga7769e434e7811caed8cd6fd7f9ec26ec',1,]]], + ['nextpacketid_2',['nextPacketId',['coreMQTT/struct_m_q_t_t_context__t.html#af47ed55ad7e9bb112324f5f209b70534',1,'MQTTContext_t']]], + ['none_3',['NONE',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33ac157bdf0b85a40d2619cbc8bc1ae5fe2',1,'core_mqtt_agent.h']]], + ['num_5fcommands_4',['NUM_COMMANDS',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a158760c3c33699acd8723f4c983822a6',1,'core_mqtt_agent.h']]], + ['numsubscriptions_5',['numSubscriptions',['../struct_m_q_t_t_agent_subscribe_args__t.html#ae30aaa33e7a0e67a5989c2d15170de95',1,'MQTTAgentSubscribeArgs_t']]] +]; diff --git a/v1.3.0/search/all_d.js b/v1.3.0/search/all_d.js new file mode 100644 index 00000000..85291b91 --- /dev/null +++ b/v1.3.0/search/all_d.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['outgoingpublishrecordmaxcount_0',['outgoingPublishRecordMaxCount',['coreMQTT/struct_m_q_t_t_context__t.html#a2851073e252d1e744596272ef13dd14a',1,'MQTTContext_t']]], + ['outgoingpublishrecords_1',['outgoingPublishRecords',['coreMQTT/struct_m_q_t_t_context__t.html#a4ea1e37e0e81f010fbf84365ac2ef6de',1,'MQTTContext_t']]], + ['overview_2',['Overview',['../index.html',1,'']]] +]; diff --git a/v1.3.0/search/all_e.js b/v1.3.0/search/all_e.js new file mode 100644 index 00000000..8acbcf86 --- /dev/null +++ b/v1.3.0/search/all_e.js @@ -0,0 +1,39 @@ +var searchData= +[ + ['packetid_0',['packetId',['../struct_m_q_t_t_agent_ack_info__t.html#ac3db584579455d37c7ad8656aa4b03f2',1,'MQTTAgentAckInfo_t::packetId()'],['../struct_m_q_t_t_agent_command_func_returns__t.html#ae37354b1e32541cb6b014f270815a28d',1,'MQTTAgentCommandFuncReturns_t::packetId()'],['coreMQTT/struct_m_q_t_t_pub_ack_info__t.html#a66cef7b43af5d7fdd33b5d2dc766b2d0',1,'MQTTPubAckInfo_t::packetId()']]], + ['packetidentifier_1',['packetIdentifier',['coreMQTT/struct_m_q_t_t_deserialized_info__t.html#af4df2a9926a4a68059195daa712d9b84',1,'MQTTDeserializedInfo_t']]], + ['packetreceivedinloop_2',['packetReceivedInLoop',['../struct_m_q_t_t_agent_context__t.html#af284de4e09e0b18411969aad986c8789',1,'MQTTAgentContext_t']]], + ['parameter_20structures_3',['Parameter Structures',['../group__mqtt__agent__struct__types.html',1,'(Global Namespace)'],['coreMQTT/group__mqtt__struct__types.html',1,'(Global Namespace)']]], + ['pargs_4',['pArgs',['../struct_m_q_t_t_agent_command.html#a0d41721e83bc91b39b7f54b39c97fafa',1,'MQTTAgentCommand']]], + ['passwordlength_5',['passwordLength',['coreMQTT/struct_m_q_t_t_connect_info__t.html#a818c4e212a12020a4109eb890ec96383',1,'MQTTConnectInfo_t']]], + ['payloadlength_6',['payloadLength',['coreMQTT/struct_m_q_t_t_publish_info__t.html#a7997964e11571f35f0c3b729db0f760f',1,'MQTTPublishInfo_t']]], + ['pbuffer_7',['pBuffer',['coreMQTT/struct_m_q_t_t_fixed_buffer__t.html#acea147448e044870fb36b7fa2347dbd6',1,'MQTTFixedBuffer_t']]], + ['pclientidentifier_8',['pClientIdentifier',['coreMQTT/struct_m_q_t_t_connect_info__t.html#a010f8f6993cbf8899648d5c515ff7884',1,'MQTTConnectInfo_t']]], + ['pcmdcompletecallbackcontext_9',['pCmdCompleteCallbackContext',['../struct_m_q_t_t_agent_command_info__t.html#a22fc349b76808064646fe71a43d37b96',1,'MQTTAgentCommandInfo_t']]], + ['pcmdcontext_10',['pCmdContext',['../struct_m_q_t_t_agent_command.html#ae7f9dad4bc0c849dae9dd2aa8c20eeef',1,'MQTTAgentCommand']]], + ['pcommandcompletecallback_11',['pCommandCompleteCallback',['../struct_m_q_t_t_agent_command.html#a4221813f0ee8d6be1e2b1f60b31fb2a3',1,'MQTTAgentCommand']]], + ['pconnectinfo_12',['pConnectInfo',['../struct_m_q_t_t_agent_connect_args__t.html#a9b71b1787c8cfe03654b1ca06ac594fa',1,'MQTTAgentConnectArgs_t']]], + ['pincomingcallback_13',['pIncomingCallback',['../struct_m_q_t_t_agent_context__t.html#a1e20b7a77aab94f5c775ca3c534cb006',1,'MQTTAgentContext_t']]], + ['pincomingcallbackcontext_14',['pIncomingCallbackContext',['../struct_m_q_t_t_agent_context__t.html#a00a73b9d9cfda64aeb9e7b796222dde4',1,'MQTTAgentContext_t']]], + ['ping_15',['PING',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a3a95ef902bc659901cceef98e0bc8041',1,'core_mqtt_agent.h']]], + ['pingreqsendtimems_16',['pingReqSendTimeMs',['coreMQTT/struct_m_q_t_t_context__t.html#acca3efa4146d85f7e874c7c326e23556',1,'MQTTContext_t']]], + ['pmsgctx_17',['pMsgCtx',['../struct_m_q_t_t_agent_message_interface__t.html#a00cad3c3514a03d5deed20609ffdc94b',1,'MQTTAgentMessageInterface_t']]], + ['pnetworkcontext_18',['pNetworkContext',['coreMQTT/struct_transport_interface__t.html#aaf4702050bef8d62714a4d3900e95087',1,'TransportInterface_t']]], + ['poriginalcommand_19',['pOriginalCommand',['../struct_m_q_t_t_agent_ack_info__t.html#a4cddb1600b6ef0d3a34af262d919b2be',1,'MQTTAgentAckInfo_t']]], + ['porting_20guide_20',['Porting Guide',['coreMQTT/mqtt_porting.html',1,'']]], + ['ppassword_21',['pPassword',['coreMQTT/struct_m_q_t_t_connect_info__t.html#acec6c79a11d2f0f130802393f34d2b5e',1,'MQTTConnectInfo_t']]], + ['ppayload_22',['pPayload',['coreMQTT/struct_m_q_t_t_publish_info__t.html#afc28299f4f625f5e674bb61b42f03380',1,'MQTTPublishInfo_t']]], + ['ppendingacks_23',['pPendingAcks',['../struct_m_q_t_t_agent_context__t.html#a324ccd898ba0769142b29b4cab38c5be',1,'MQTTAgentContext_t']]], + ['ppublishinfo_24',['pPublishInfo',['coreMQTT/struct_m_q_t_t_deserialized_info__t.html#ac347273fae1e92b9cbeda1714066c1de',1,'MQTTDeserializedInfo_t']]], + ['premainingdata_25',['pRemainingData',['coreMQTT/struct_m_q_t_t_packet_info__t.html#ac66cedff052bc844ec9b296387df60bc',1,'MQTTPacketInfo_t']]], + ['processcommand_26',['processCommand',['../core__mqtt__agent_8c.html#a18da6f0f75cb79d2b56db65b40ba9437',1,'core_mqtt_agent.c']]], + ['processloop_27',['PROCESSLOOP',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a955e933dab5938a6cce4e140278a24d2',1,'core_mqtt_agent.h']]], + ['psubackcodes_28',['pSubackCodes',['../struct_m_q_t_t_agent_return_info__t.html#ad68d82134f1f72460f82b83256409542',1,'MQTTAgentReturnInfo_t']]], + ['psubscribeinfo_29',['pSubscribeInfo',['../struct_m_q_t_t_agent_subscribe_args__t.html#a27e21bfcf0184a4a168a6170a60fc026',1,'MQTTAgentSubscribeArgs_t']]], + ['ptopicfilter_30',['pTopicFilter',['coreMQTT/struct_m_q_t_t_subscribe_info__t.html#adb0b28240fdcd82a85f11cf2f8b5bbf0',1,'MQTTSubscribeInfo_t']]], + ['ptopicname_31',['pTopicName',['coreMQTT/struct_m_q_t_t_publish_info__t.html#aa80e8ca282d01630f878ad0afe81d7a4',1,'MQTTPublishInfo_t']]], + ['publish_32',['PUBLISH',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33abd1a204dcfa4933760cd12e779f36fc5',1,'core_mqtt_agent.h']]], + ['publishstate_33',['publishState',['coreMQTT/struct_m_q_t_t_pub_ack_info__t.html#a61314203ef87a231c6489c68b579de34',1,'MQTTPubAckInfo_t']]], + ['pusername_34',['pUserName',['coreMQTT/struct_m_q_t_t_connect_info__t.html#a1118d7d3251a11445318557280db53b4',1,'MQTTConnectInfo_t']]], + ['pwillinfo_35',['pWillInfo',['../struct_m_q_t_t_agent_connect_args__t.html#a1ab24eb17eebc51bdad53ee2b36c8cdb',1,'MQTTAgentConnectArgs_t']]] +]; diff --git a/v1.3.0/search/all_f.js b/v1.3.0/search/all_f.js new file mode 100644 index 00000000..e6dbfbb6 --- /dev/null +++ b/v1.3.0/search/all_f.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['qos_0',['qos',['coreMQTT/struct_m_q_t_t_pub_ack_info__t.html#a086fcd48ef0b787697526a95c861e8a0',1,'MQTTPubAckInfo_t::qos()'],['coreMQTT/struct_m_q_t_t_publish_info__t.html#a178224d02b4acdec7e08e88de0e4b399',1,'MQTTPublishInfo_t::qos()'],['coreMQTT/struct_m_q_t_t_subscribe_info__t.html#a64cf2e423f60cfec122eeaef80c0fd86',1,'MQTTSubscribeInfo_t::qos()']]] +]; diff --git a/v1.3.0/search/classes_0.js b/v1.3.0/search/classes_0.js new file mode 100644 index 00000000..468a83e0 --- /dev/null +++ b/v1.3.0/search/classes_0.js @@ -0,0 +1,20 @@ +var searchData= +[ + ['mqttagentackinfo_5ft_0',['MQTTAgentAckInfo_t',['../struct_m_q_t_t_agent_ack_info__t.html',1,'']]], + ['mqttagentcommand_1',['MQTTAgentCommand',['../struct_m_q_t_t_agent_command.html',1,'']]], + ['mqttagentcommandfuncreturns_5ft_2',['MQTTAgentCommandFuncReturns_t',['../struct_m_q_t_t_agent_command_func_returns__t.html',1,'']]], + ['mqttagentcommandinfo_5ft_3',['MQTTAgentCommandInfo_t',['../struct_m_q_t_t_agent_command_info__t.html',1,'']]], + ['mqttagentconnectargs_5ft_4',['MQTTAgentConnectArgs_t',['../struct_m_q_t_t_agent_connect_args__t.html',1,'']]], + ['mqttagentcontext_5ft_5',['MQTTAgentContext_t',['../struct_m_q_t_t_agent_context__t.html',1,'']]], + ['mqttagentmessageinterface_5ft_6',['MQTTAgentMessageInterface_t',['../struct_m_q_t_t_agent_message_interface__t.html',1,'']]], + ['mqttagentreturninfo_5ft_7',['MQTTAgentReturnInfo_t',['../struct_m_q_t_t_agent_return_info__t.html',1,'']]], + ['mqttagentsubscribeargs_5ft_8',['MQTTAgentSubscribeArgs_t',['../struct_m_q_t_t_agent_subscribe_args__t.html',1,'']]], + ['mqttconnectinfo_5ft_9',['MQTTConnectInfo_t',['coreMQTT/struct_m_q_t_t_connect_info__t.html',1,'']]], + ['mqttcontext_5ft_10',['MQTTContext_t',['coreMQTT/struct_m_q_t_t_context__t.html',1,'']]], + ['mqttdeserializedinfo_5ft_11',['MQTTDeserializedInfo_t',['coreMQTT/struct_m_q_t_t_deserialized_info__t.html',1,'']]], + ['mqttfixedbuffer_5ft_12',['MQTTFixedBuffer_t',['coreMQTT/struct_m_q_t_t_fixed_buffer__t.html',1,'']]], + ['mqttpacketinfo_5ft_13',['MQTTPacketInfo_t',['coreMQTT/struct_m_q_t_t_packet_info__t.html',1,'']]], + ['mqttpubackinfo_5ft_14',['MQTTPubAckInfo_t',['coreMQTT/struct_m_q_t_t_pub_ack_info__t.html',1,'']]], + ['mqttpublishinfo_5ft_15',['MQTTPublishInfo_t',['coreMQTT/struct_m_q_t_t_publish_info__t.html',1,'']]], + ['mqttsubscribeinfo_5ft_16',['MQTTSubscribeInfo_t',['coreMQTT/struct_m_q_t_t_subscribe_info__t.html',1,'']]] +]; diff --git a/v1.3.0/search/classes_1.js b/v1.3.0/search/classes_1.js new file mode 100644 index 00000000..73efd8ea --- /dev/null +++ b/v1.3.0/search/classes_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['transportinterface_5ft_0',['TransportInterface_t',['coreMQTT/struct_transport_interface__t.html',1,'']]], + ['transportoutvector_5ft_1',['TransportOutVector_t',['coreMQTT/struct_transport_out_vector__t.html',1,'']]] +]; diff --git a/v1.3.0/search/close.svg b/v1.3.0/search/close.svg new file mode 100644 index 00000000..a933eea1 --- /dev/null +++ b/v1.3.0/search/close.svg @@ -0,0 +1,31 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/v1.3.0/search/defines_0.js b/v1.3.0/search/defines_0.js new file mode 100644 index 00000000..14668825 --- /dev/null +++ b/v1.3.0/search/defines_0.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['logdebug_0',['LogDebug',['../core__mqtt__agent__default__logging_8h.html#af60e8ffc327d136e5d0d8441ed98c98d',1,'core_mqtt_agent_default_logging.h']]], + ['logerror_1',['LogError',['../core__mqtt__agent__default__logging_8h.html#a8d9dbaaa88129137a4c68ba0456a18b1',1,'core_mqtt_agent_default_logging.h']]], + ['loginfo_2',['LogInfo',['../core__mqtt__agent__default__logging_8h.html#a00810b1cb9d2f25d25ce2d4d93815fba',1,'core_mqtt_agent_default_logging.h']]], + ['logwarn_3',['LogWarn',['../core__mqtt__agent__default__logging_8h.html#a7da92048aaf0cbfcacde9539c98a0e05',1,'core_mqtt_agent_default_logging.h']]] +]; diff --git a/v1.3.0/search/defines_1.js b/v1.3.0/search/defines_1.js new file mode 100644 index 00000000..dc76b449 --- /dev/null +++ b/v1.3.0/search/defines_1.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['mqtt_5fagent_5fdo_5fnot_5fuse_5fcustom_5fconfig_0',['MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG',['../core__mqtt__agent__config__defaults_8h.html#aa10d2a7250bc5471633048ad4f238138',1,'core_mqtt_agent_config_defaults.h']]], + ['mqtt_5fagent_5ffunction_5ftable_1',['MQTT_AGENT_FUNCTION_TABLE',['../core__mqtt__agent__command__functions_8h.html#adf96732c68dea38cfc3b325639304bba',1,'core_mqtt_agent_command_functions.h']]], + ['mqtt_5fagent_5fmax_5fevent_5fqueue_5fwait_5ftime_2',['MQTT_AGENT_MAX_EVENT_QUEUE_WAIT_TIME',['../core__mqtt__agent__config__defaults_8h.html#a9fbd3d9f02a4cabb01e900cfa4d01980',1,'core_mqtt_agent_config_defaults.h']]], + ['mqtt_5fagent_5fmax_5foutstanding_5facks_3',['MQTT_AGENT_MAX_OUTSTANDING_ACKS',['../core__mqtt__agent__config__defaults_8h.html#afc749954a2c0c3a81bcf1e2eb5fecaad',1,'core_mqtt_agent_config_defaults.h']]], + ['mqtt_5fagent_5fuse_5fqos_5f1_5f2_5fpublish_4',['MQTT_AGENT_USE_QOS_1_2_PUBLISH',['../core__mqtt__agent__config__defaults_8h.html#af20d4b1937cbd282f193f69b1b27742e',1,'core_mqtt_agent_config_defaults.h']]] +]; diff --git a/v1.3.0/search/enums_0.js b/v1.3.0/search/enums_0.js new file mode 100644 index 00000000..c22d1428 --- /dev/null +++ b/v1.3.0/search/enums_0.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['mqttagentcommandtype_5ft_0',['MQTTAgentCommandType_t',['../group__mqtt__agent__enum__types.html#ga76604fa58b7ee6c32ba084fda9379f33',1,'core_mqtt_agent.h']]], + ['mqttconnectionstatus_5ft_1',['MQTTConnectionStatus_t',['coreMQTT/group__mqtt__enum__types.html#ga9f84d003695205cf10a7bd0bafb3dbf6',1,]]], + ['mqttpubacktype_5ft_2',['MQTTPubAckType_t',['coreMQTT/group__mqtt__enum__types.html#ga8c1bee959b3ed5fab2a2688dd72bf237',1,]]], + ['mqttpublishstate_5ft_3',['MQTTPublishState_t',['coreMQTT/group__mqtt__enum__types.html#ga0480de7552eedd739a26a23fa8e6fd94',1,]]], + ['mqttqos_5ft_4',['MQTTQoS_t',['coreMQTT/group__mqtt__enum__types.html#gae308a5928d7f537379c29a894228093a',1,]]], + ['mqttstatus_5ft_5',['MQTTStatus_t',['coreMQTT/group__mqtt__enum__types.html#gaba7ec045874a1c3432f99173367f735c',1,]]], + ['mqttsubackstatus_5ft_6',['MQTTSubAckStatus_t',['coreMQTT/group__mqtt__enum__types.html#ga48dabc1579e3c0ac6058ce9068054611',1,]]] +]; diff --git a/v1.3.0/search/enumvalues_0.js b/v1.3.0/search/enumvalues_0.js new file mode 100644 index 00000000..2347fdf4 --- /dev/null +++ b/v1.3.0/search/enumvalues_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['connect_0',['CONNECT',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a20391dd2915a0e64343d24c2f2e40b95',1,'core_mqtt_agent.h']]] +]; diff --git a/v1.3.0/search/enumvalues_1.js b/v1.3.0/search/enumvalues_1.js new file mode 100644 index 00000000..51ec9acb --- /dev/null +++ b/v1.3.0/search/enumvalues_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['disconnect_0',['DISCONNECT',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a2f6318afb30e8e2817e6203ebedc8173',1,'core_mqtt_agent.h']]] +]; diff --git a/v1.3.0/search/enumvalues_2.js b/v1.3.0/search/enumvalues_2.js new file mode 100644 index 00000000..f1fcf7f6 --- /dev/null +++ b/v1.3.0/search/enumvalues_2.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['none_0',['NONE',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33ac157bdf0b85a40d2619cbc8bc1ae5fe2',1,'core_mqtt_agent.h']]], + ['num_5fcommands_1',['NUM_COMMANDS',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a158760c3c33699acd8723f4c983822a6',1,'core_mqtt_agent.h']]] +]; diff --git a/v1.3.0/search/enumvalues_3.js b/v1.3.0/search/enumvalues_3.js new file mode 100644 index 00000000..05d7ec2b --- /dev/null +++ b/v1.3.0/search/enumvalues_3.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['ping_0',['PING',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a3a95ef902bc659901cceef98e0bc8041',1,'core_mqtt_agent.h']]], + ['processloop_1',['PROCESSLOOP',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a955e933dab5938a6cce4e140278a24d2',1,'core_mqtt_agent.h']]], + ['publish_2',['PUBLISH',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33abd1a204dcfa4933760cd12e779f36fc5',1,'core_mqtt_agent.h']]] +]; diff --git a/v1.3.0/search/enumvalues_4.js b/v1.3.0/search/enumvalues_4.js new file mode 100644 index 00000000..152858c0 --- /dev/null +++ b/v1.3.0/search/enumvalues_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['subscribe_0',['SUBSCRIBE',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33abc6f919ff681f5f552b2f7d1f0fba832',1,'core_mqtt_agent.h']]] +]; diff --git a/v1.3.0/search/enumvalues_5.js b/v1.3.0/search/enumvalues_5.js new file mode 100644 index 00000000..bffd0e84 --- /dev/null +++ b/v1.3.0/search/enumvalues_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['terminate_0',['TERMINATE',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a9aab2d9eae3e9a84d9fed3f0cadd7e22',1,'core_mqtt_agent.h']]] +]; diff --git a/v1.3.0/search/enumvalues_6.js b/v1.3.0/search/enumvalues_6.js new file mode 100644 index 00000000..c941c24e --- /dev/null +++ b/v1.3.0/search/enumvalues_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['unsubscribe_0',['UNSUBSCRIBE',['../group__mqtt__agent__enum__types.html#gga76604fa58b7ee6c32ba084fda9379f33a8395e5981c15d813c588c86988fd4aea',1,'core_mqtt_agent.h']]] +]; diff --git a/v1.3.0/search/files_0.js b/v1.3.0/search/files_0.js new file mode 100644 index 00000000..7827fafa --- /dev/null +++ b/v1.3.0/search/files_0.js @@ -0,0 +1,17 @@ +var searchData= +[ + ['core_5fmqtt_2ec_0',['core_mqtt.c',['coreMQTT/core__mqtt_8c.html',1,'']]], + ['core_5fmqtt_2eh_1',['core_mqtt.h',['coreMQTT/core__mqtt_8h.html',1,'']]], + ['core_5fmqtt_5fagent_2ec_2',['core_mqtt_agent.c',['../core__mqtt__agent_8c.html',1,'']]], + ['core_5fmqtt_5fagent_2eh_3',['core_mqtt_agent.h',['../core__mqtt__agent_8h.html',1,'']]], + ['core_5fmqtt_5fagent_5fcommand_5ffunctions_2ec_4',['core_mqtt_agent_command_functions.c',['../core__mqtt__agent__command__functions_8c.html',1,'']]], + ['core_5fmqtt_5fagent_5fcommand_5ffunctions_2eh_5',['core_mqtt_agent_command_functions.h',['../core__mqtt__agent__command__functions_8h.html',1,'']]], + ['core_5fmqtt_5fagent_5fconfig_5fdefaults_2eh_6',['core_mqtt_agent_config_defaults.h',['../core__mqtt__agent__config__defaults_8h.html',1,'']]], + ['core_5fmqtt_5fagent_5fdefault_5flogging_2eh_7',['core_mqtt_agent_default_logging.h',['../core__mqtt__agent__default__logging_8h.html',1,'']]], + ['core_5fmqtt_5fagent_5fmessage_5finterface_2eh_8',['core_mqtt_agent_message_interface.h',['../core__mqtt__agent__message__interface_8h.html',1,'']]], + ['core_5fmqtt_5fconfig_5fdefaults_2eh_9',['core_mqtt_config_defaults.h',['coreMQTT/core__mqtt__config__defaults_8h.html',1,'']]], + ['core_5fmqtt_5fserializer_2ec_10',['core_mqtt_serializer.c',['coreMQTT/core__mqtt__serializer_8c.html',1,'']]], + ['core_5fmqtt_5fserializer_2eh_11',['core_mqtt_serializer.h',['coreMQTT/core__mqtt__serializer_8h.html',1,'']]], + ['core_5fmqtt_5fstate_2ec_12',['core_mqtt_state.c',['coreMQTT/core__mqtt__state_8c.html',1,'']]], + ['core_5fmqtt_5fstate_2eh_13',['core_mqtt_state.h',['coreMQTT/core__mqtt__state_8h.html',1,'']]] +]; diff --git a/v1.3.0/search/files_1.js b/v1.3.0/search/files_1.js new file mode 100644 index 00000000..1a653f21 --- /dev/null +++ b/v1.3.0/search/files_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['transport_5finterface_2eh_0',['transport_interface.h',['coreMQTT/transport__interface_8h.html',1,'']]] +]; diff --git a/v1.3.0/search/functions_0.js b/v1.3.0/search/functions_0.js new file mode 100644 index 00000000..8850a2b3 --- /dev/null +++ b/v1.3.0/search/functions_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['addawaitingoperation_0',['addAwaitingOperation',['../core__mqtt__agent_8c.html#ae70f7438de05ac589b4e48d4a2a7dd7b',1,'core_mqtt_agent.c']]], + ['addcommandtoqueue_1',['addCommandToQueue',['../core__mqtt__agent_8c.html#a38a109884abe76bd9e0b90d23b9d67b4',1,'core_mqtt_agent.c']]] +]; diff --git a/v1.3.0/search/functions_1.js b/v1.3.0/search/functions_1.js new file mode 100644 index 00000000..9f35aba6 --- /dev/null +++ b/v1.3.0/search/functions_1.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['clearpendingacknowledgments_0',['clearPendingAcknowledgments',['../core__mqtt__agent_8c.html#afb076dcf75919d5b638c33054b95461d',1,'core_mqtt_agent.c']]], + ['concludecommand_1',['concludeCommand',['../core__mqtt__agent_8c.html#a848611250b309e0d84cb18a42fbf6391',1,'core_mqtt_agent.c']]], + ['createandaddcommand_2',['createAndAddCommand',['../core__mqtt__agent_8c.html#a594dbfd47f77c6988960110da3c25a2c',1,'core_mqtt_agent.c']]], + ['createcommand_3',['createCommand',['../core__mqtt__agent_8c.html#a4f2d34a65263b609595aa8f1705ff89f',1,'core_mqtt_agent.c']]] +]; diff --git a/v1.3.0/search/functions_2.js b/v1.3.0/search/functions_2.js new file mode 100644 index 00000000..d4dfa2ce --- /dev/null +++ b/v1.3.0/search/functions_2.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['getagentfrommqttcontext_0',['getAgentFromMQTTContext',['../core__mqtt__agent_8c.html#adb6cd05d1e6b270a021cb50980654707',1,'core_mqtt_agent.c']]], + ['getawaitingoperation_1',['getAwaitingOperation',['../core__mqtt__agent_8c.html#af4ab608204e853ab34bda491a47f6b84',1,'core_mqtt_agent.c']]] +]; diff --git a/v1.3.0/search/functions_3.js b/v1.3.0/search/functions_3.js new file mode 100644 index 00000000..28f20a71 --- /dev/null +++ b/v1.3.0/search/functions_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['handleacks_0',['handleAcks',['../core__mqtt__agent_8c.html#ace2cab4efce97019ae5e12ccae2780cd',1,'core_mqtt_agent.c']]] +]; diff --git a/v1.3.0/search/functions_4.js b/v1.3.0/search/functions_4.js new file mode 100644 index 00000000..ededbd72 --- /dev/null +++ b/v1.3.0/search/functions_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['isspaceinpendingacklist_0',['isSpaceInPendingAckList',['../core__mqtt__agent_8c.html#a6082ea8cf8fe3f34e0a8de08d6980a29',1,'core_mqtt_agent.c']]] +]; diff --git a/v1.3.0/search/functions_5.js b/v1.3.0/search/functions_5.js new file mode 100644 index 00000000..8bafde34 --- /dev/null +++ b/v1.3.0/search/functions_5.js @@ -0,0 +1,24 @@ +var searchData= +[ + ['mqttagent_5fcancelall_0',['MQTTAgent_CancelAll',['../core__mqtt__agent_8c.html#a0362d7d3d68628413f01b32ec2ff4ab6',1,'MQTTAgent_CancelAll(MQTTAgentContext_t *pMqttAgentContext): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#a0362d7d3d68628413f01b32ec2ff4ab6',1,'MQTTAgent_CancelAll(MQTTAgentContext_t *pMqttAgentContext): core_mqtt_agent.c']]], + ['mqttagent_5fcommandloop_1',['MQTTAgent_CommandLoop',['../core__mqtt__agent_8c.html#a9dafeb1701b1a0ee897b626a09cfcff7',1,'MQTTAgent_CommandLoop(MQTTAgentContext_t *pMqttAgentContext): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#a9dafeb1701b1a0ee897b626a09cfcff7',1,'MQTTAgent_CommandLoop(MQTTAgentContext_t *pMqttAgentContext): core_mqtt_agent.c']]], + ['mqttagent_5fconnect_2',['MQTTAgent_Connect',['../core__mqtt__agent_8h.html#a782425e50d258837d23e379471254412',1,'MQTTAgent_Connect(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentConnectArgs_t *pConnectArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#a782425e50d258837d23e379471254412',1,'MQTTAgent_Connect(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentConnectArgs_t *pConnectArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5fdisconnect_3',['MQTTAgent_Disconnect',['../core__mqtt__agent_8h.html#a26687b9b762b5f52b14387bacdf17224',1,'MQTTAgent_Disconnect(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#a26687b9b762b5f52b14387bacdf17224',1,'MQTTAgent_Disconnect(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5finit_4',['MQTTAgent_Init',['../core__mqtt__agent_8h.html#a584863528e72229f35003485f7ee0edd',1,'MQTTAgent_Init(MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentMessageInterface_t *pMsgInterface, const MQTTFixedBuffer_t *pNetworkBuffer, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getCurrentTimeMs, MQTTAgentIncomingPublishCallback_t incomingCallback, void *pIncomingPacketContext): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#a584863528e72229f35003485f7ee0edd',1,'MQTTAgent_Init(MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentMessageInterface_t *pMsgInterface, const MQTTFixedBuffer_t *pNetworkBuffer, const TransportInterface_t *pTransportInterface, MQTTGetCurrentTimeFunc_t getCurrentTimeMs, MQTTAgentIncomingPublishCallback_t incomingCallback, void *pIncomingPacketContext): core_mqtt_agent.c']]], + ['mqttagent_5fping_5',['MQTTAgent_Ping',['../core__mqtt__agent_8c.html#ae260e29f31d51953cbab2e1437f645ed',1,'MQTTAgent_Ping(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8h.html#ae260e29f31d51953cbab2e1437f645ed',1,'MQTTAgent_Ping(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5fprocessloop_6',['MQTTAgent_ProcessLoop',['../core__mqtt__agent_8h.html#aa14c9c86e036d0b1f5c04a538597cc46',1,'MQTTAgent_ProcessLoop(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#aa14c9c86e036d0b1f5c04a538597cc46',1,'MQTTAgent_ProcessLoop(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5fpublish_7',['MQTTAgent_Publish',['../core__mqtt__agent_8h.html#afea2405ab859324cb241ea47e6a5ab81',1,'MQTTAgent_Publish(const MQTTAgentContext_t *pMqttAgentContext, MQTTPublishInfo_t *pPublishInfo, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#afea2405ab859324cb241ea47e6a5ab81',1,'MQTTAgent_Publish(const MQTTAgentContext_t *pMqttAgentContext, MQTTPublishInfo_t *pPublishInfo, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5fresumesession_8',['MQTTAgent_ResumeSession',['../core__mqtt__agent_8h.html#a75065d6bff5f2d32831f2c74922296fb',1,'MQTTAgent_ResumeSession(MQTTAgentContext_t *pMqttAgentContext, bool sessionPresent): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#a75065d6bff5f2d32831f2c74922296fb',1,'MQTTAgent_ResumeSession(MQTTAgentContext_t *pMqttAgentContext, bool sessionPresent): core_mqtt_agent.c']]], + ['mqttagent_5fsubscribe_9',['MQTTAgent_Subscribe',['../core__mqtt__agent_8h.html#a651cf10182392ecea5e8609af8855d49',1,'MQTTAgent_Subscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#a651cf10182392ecea5e8609af8855d49',1,'MQTTAgent_Subscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5fterminate_10',['MQTTAgent_Terminate',['../core__mqtt__agent_8h.html#ae1b19c10831f72251603b045f2608313',1,'MQTTAgent_Terminate(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#ae1b19c10831f72251603b045f2608313',1,'MQTTAgent_Terminate(const MQTTAgentContext_t *pMqttAgentContext, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagent_5funsubscribe_11',['MQTTAgent_Unsubscribe',['../core__mqtt__agent_8h.html#ac3f70c81c8f8947dfb7346045c8edb63',1,'MQTTAgent_Unsubscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c'],['../core__mqtt__agent_8c.html#ac3f70c81c8f8947dfb7346045c8edb63',1,'MQTTAgent_Unsubscribe(const MQTTAgentContext_t *pMqttAgentContext, MQTTAgentSubscribeArgs_t *pSubscriptionArgs, const MQTTAgentCommandInfo_t *pCommandInfo): core_mqtt_agent.c']]], + ['mqttagentcommand_5fconnect_12',['MQTTAgentCommand_Connect',['../core__mqtt__agent__command__functions_8h.html#abe89d0e3cf7ddd095a3c840df4955a9e',1,'MQTTAgentCommand_Connect(MQTTAgentContext_t *pMqttAgentContext, void *pVoidConnectArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#abe89d0e3cf7ddd095a3c840df4955a9e',1,'MQTTAgentCommand_Connect(MQTTAgentContext_t *pMqttAgentContext, void *pVoidConnectArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fdisconnect_13',['MQTTAgentCommand_Disconnect',['../core__mqtt__agent__command__functions_8h.html#aa7507c7a01cdc06af0d5f42711357b6e',1,'MQTTAgentCommand_Disconnect(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#aa7507c7a01cdc06af0d5f42711357b6e',1,'MQTTAgentCommand_Disconnect(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fping_14',['MQTTAgentCommand_Ping',['../core__mqtt__agent__command__functions_8h.html#a9840f5683a5e513b99ab15961e17e42b',1,'MQTTAgentCommand_Ping(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#a9840f5683a5e513b99ab15961e17e42b',1,'MQTTAgentCommand_Ping(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fprocessloop_15',['MQTTAgentCommand_ProcessLoop',['../core__mqtt__agent__command__functions_8c.html#ae2a8b7caae9b06f36f9784663c8f8a49',1,'MQTTAgentCommand_ProcessLoop(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8h.html#ae2a8b7caae9b06f36f9784663c8f8a49',1,'MQTTAgentCommand_ProcessLoop(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fpublish_16',['MQTTAgentCommand_Publish',['../core__mqtt__agent__command__functions_8h.html#a5b4be57b6b6a55054e94850c805fd943',1,'MQTTAgentCommand_Publish(MQTTAgentContext_t *pMqttAgentContext, void *pPublishArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#a5b4be57b6b6a55054e94850c805fd943',1,'MQTTAgentCommand_Publish(MQTTAgentContext_t *pMqttAgentContext, void *pPublishArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fsubscribe_17',['MQTTAgentCommand_Subscribe',['../core__mqtt__agent__command__functions_8h.html#accbd434285c7cd823270614513ecd4a0',1,'MQTTAgentCommand_Subscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#accbd434285c7cd823270614513ecd4a0',1,'MQTTAgentCommand_Subscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5fterminate_18',['MQTTAgentCommand_Terminate',['../core__mqtt__agent__command__functions_8h.html#aa017a4f5741920140688973e4b8bf0f1',1,'MQTTAgentCommand_Terminate(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#aa017a4f5741920140688973e4b8bf0f1',1,'MQTTAgentCommand_Terminate(MQTTAgentContext_t *pMqttAgentContext, void *pUnusedArg, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqttagentcommand_5funsubscribe_19',['MQTTAgentCommand_Unsubscribe',['../core__mqtt__agent__command__functions_8h.html#aea9ea15866e2e7940469d9a200b45362',1,'MQTTAgentCommand_Unsubscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c'],['../core__mqtt__agent__command__functions_8c.html#aea9ea15866e2e7940469d9a200b45362',1,'MQTTAgentCommand_Unsubscribe(MQTTAgentContext_t *pMqttAgentContext, void *pVoidSubscribeArgs, MQTTAgentCommandFuncReturns_t *pReturnFlags): core_mqtt_agent_command_functions.c']]], + ['mqtteventcallback_20',['mqttEventCallback',['../core__mqtt__agent_8c.html#a4aeca55423966c3eff1734316f6a7466',1,'core_mqtt_agent.c']]] +]; diff --git a/v1.3.0/search/functions_6.js b/v1.3.0/search/functions_6.js new file mode 100644 index 00000000..7800d5e2 --- /dev/null +++ b/v1.3.0/search/functions_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['processcommand_0',['processCommand',['../core__mqtt__agent_8c.html#a18da6f0f75cb79d2b56db65b40ba9437',1,'core_mqtt_agent.c']]] +]; diff --git a/v1.3.0/search/functions_7.js b/v1.3.0/search/functions_7.js new file mode 100644 index 00000000..c87ec25a --- /dev/null +++ b/v1.3.0/search/functions_7.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['resendpublishes_0',['resendPublishes',['../core__mqtt__agent_8c.html#a0c7ea532d3da52d5c8ceb7493ce5fe36',1,'core_mqtt_agent.c']]] +]; diff --git a/v1.3.0/search/functions_8.js b/v1.3.0/search/functions_8.js new file mode 100644 index 00000000..8d1b51f7 --- /dev/null +++ b/v1.3.0/search/functions_8.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['validateparams_0',['validateParams',['../core__mqtt__agent_8c.html#ac6b1b83accad3124122fed5c7ec14870',1,'core_mqtt_agent.c']]], + ['validatestruct_1',['validateStruct',['../core__mqtt__agent_8c.html#a77d4ec3f1e90897d6f173a2fcd7b9b61',1,'core_mqtt_agent.c']]] +]; diff --git a/v1.3.0/search/groups_0.js b/v1.3.0/search/groups_0.js new file mode 100644 index 00000000..2a9e610c --- /dev/null +++ b/v1.3.0/search/groups_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['basic_20types_0',['Basic Types',['coreMQTT/group__mqtt__basic__types.html',1,'']]] +]; diff --git a/v1.3.0/search/groups_1.js b/v1.3.0/search/groups_1.js new file mode 100644 index 00000000..9b881a8e --- /dev/null +++ b/v1.3.0/search/groups_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['callback_20types_0',['Callback Types',['../group__mqtt__agent__callback__types.html',1,'(Global Namespace)'],['coreMQTT/group__mqtt__callback__types.html',1,'(Global Namespace)']]], + ['constants_1',['Constants',['coreMQTT/group__mqtt__constants.html',1,'']]] +]; diff --git a/v1.3.0/search/groups_2.js b/v1.3.0/search/groups_2.js new file mode 100644 index 00000000..63da9bfc --- /dev/null +++ b/v1.3.0/search/groups_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['enumerated_20types_0',['Enumerated Types',['../group__mqtt__agent__enum__types.html',1,'(Global Namespace)'],['coreMQTT/group__mqtt__enum__types.html',1,'(Global Namespace)']]] +]; diff --git a/v1.3.0/search/groups_3.js b/v1.3.0/search/groups_3.js new file mode 100644 index 00000000..7135a814 --- /dev/null +++ b/v1.3.0/search/groups_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['parameter_20structures_0',['Parameter Structures',['../group__mqtt__agent__struct__types.html',1,'(Global Namespace)'],['coreMQTT/group__mqtt__struct__types.html',1,'(Global Namespace)']]] +]; diff --git a/v1.3.0/search/mag.svg b/v1.3.0/search/mag.svg new file mode 100644 index 00000000..9f46b301 --- /dev/null +++ b/v1.3.0/search/mag.svg @@ -0,0 +1,37 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/v1.3.0/search/mag_d.svg b/v1.3.0/search/mag_d.svg new file mode 100644 index 00000000..b9a814c7 --- /dev/null +++ b/v1.3.0/search/mag_d.svg @@ -0,0 +1,37 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/v1.3.0/search/mag_sel.svg b/v1.3.0/search/mag_sel.svg new file mode 100644 index 00000000..03626f64 --- /dev/null +++ b/v1.3.0/search/mag_sel.svg @@ -0,0 +1,74 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/v1.3.0/search/mag_seld.svg b/v1.3.0/search/mag_seld.svg new file mode 100644 index 00000000..6e720dcc --- /dev/null +++ b/v1.3.0/search/mag_seld.svg @@ -0,0 +1,74 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/v1.3.0/search/pages_0.js b/v1.3.0/search/pages_0.js new file mode 100644 index 00000000..bb0e4938 --- /dev/null +++ b/v1.3.0/search/pages_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['configurations_0',['Configurations',['../core_mqtt_agent_config.html',1,'(Global Namespace)'],['coreMQTT/core_mqtt_config.html',1,'(Global Namespace)']]] +]; diff --git a/v1.3.0/search/pages_1.js b/v1.3.0/search/pages_1.js new file mode 100644 index 00000000..8533aa4f --- /dev/null +++ b/v1.3.0/search/pages_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['design_0',['Design',['../mqtt_agent_design.html',1,'(Global Namespace)'],['coreMQTT/mqtt_design.html',1,'(Global Namespace)']]] +]; diff --git a/v1.3.0/search/pages_2.js b/v1.3.0/search/pages_2.js new file mode 100644 index 00000000..5455fb0c --- /dev/null +++ b/v1.3.0/search/pages_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['functions_0',['Functions',['../mqtt_agent_functions.html',1,'(Global Namespace)'],['coreMQTT/mqtt_functions.html',1,'(Global Namespace)']]] +]; diff --git a/v1.3.0/search/pages_3.js b/v1.3.0/search/pages_3.js new file mode 100644 index 00000000..cb46f52c --- /dev/null +++ b/v1.3.0/search/pages_3.js @@ -0,0 +1,45 @@ +var searchData= +[ + ['message_20interface_0',['Message Interface',['../mqtt_agent_message_interface.html',1,'']]], + ['mqtt_5fconnect_1',['MQTT_Connect',['coreMQTT/mqtt_connect_function.html',1,'']]], + ['mqtt_5fdeserializeack_2',['MQTT_DeserializeAck',['coreMQTT/mqtt_deserializeack_function.html',1,'']]], + ['mqtt_5fdeserializepublish_3',['MQTT_DeserializePublish',['coreMQTT/mqtt_deserializepublish_function.html',1,'']]], + ['mqtt_5fdisconnect_4',['MQTT_Disconnect',['coreMQTT/mqtt_disconnect_function.html',1,'']]], + ['mqtt_5fgetconnectpacketsize_5',['MQTT_GetConnectPacketSize',['coreMQTT/mqtt_getconnectpacketsize_function.html',1,'']]], + ['mqtt_5fgetdisconnectpacketsize_6',['MQTT_GetDisconnectPacketSize',['coreMQTT/mqtt_getdisconnectpacketsize_function.html',1,'']]], + ['mqtt_5fgetincomingpackettypeandlength_7',['MQTT_GetIncomingPacketTypeAndLength',['coreMQTT/mqtt_getincomingpackettypeandlength_function.html',1,'']]], + ['mqtt_5fgetpacketid_8',['MQTT_GetPacketId',['coreMQTT/mqtt_getpacketid_function.html',1,'']]], + ['mqtt_5fgetpingreqpacketsize_9',['MQTT_GetPingreqPacketSize',['coreMQTT/mqtt_getpingreqpacketsize_function.html',1,'']]], + ['mqtt_5fgetpublishpacketsize_10',['MQTT_GetPublishPacketSize',['coreMQTT/mqtt_getpublishpacketsize_function.html',1,'']]], + ['mqtt_5fgetsubackstatuscodes_11',['MQTT_GetSubAckStatusCodes',['coreMQTT/mqtt_getsubackstatuscodes_function.html',1,'']]], + ['mqtt_5fgetsubscribepacketsize_12',['MQTT_GetSubscribePacketSize',['coreMQTT/mqtt_getsubscribepacketsize_function.html',1,'']]], + ['mqtt_5fgetunsubscribepacketsize_13',['MQTT_GetUnsubscribePacketSize',['coreMQTT/mqtt_getunsubscribepacketsize_function.html',1,'']]], + ['mqtt_5finit_14',['MQTT_Init',['coreMQTT/mqtt_init_function.html',1,'']]], + ['mqtt_5fping_15',['MQTT_Ping',['coreMQTT/mqtt_ping_function.html',1,'']]], + ['mqtt_5fprocessloop_16',['MQTT_ProcessLoop',['coreMQTT/mqtt_processloop_function.html',1,'']]], + ['mqtt_5fpublish_17',['MQTT_Publish',['coreMQTT/mqtt_publish_function.html',1,'']]], + ['mqtt_5fpublishtoresend_18',['MQTT_PublishToResend',['coreMQTT/mqtt_publishtoresend_function.html',1,'']]], + ['mqtt_5freceiveloop_19',['MQTT_ReceiveLoop',['coreMQTT/mqtt_receiveloop_function.html',1,'']]], + ['mqtt_5fserializeack_20',['MQTT_SerializeAck',['coreMQTT/mqtt_serializeack_function.html',1,'']]], + ['mqtt_5fserializeconnect_21',['MQTT_SerializeConnect',['coreMQTT/mqtt_serializeconnect_function.html',1,'']]], + ['mqtt_5fserializedisconnect_22',['MQTT_SerializeDisconnect',['coreMQTT/mqtt_serializedisconnect_function.html',1,'']]], + ['mqtt_5fserializepingreq_23',['MQTT_SerializePingreq',['coreMQTT/mqtt_serializepingreq_function.html',1,'']]], + ['mqtt_5fserializepublish_24',['MQTT_SerializePublish',['coreMQTT/mqtt_serializepublish_function.html',1,'']]], + ['mqtt_5fserializepublishheader_25',['MQTT_SerializePublishHeader',['coreMQTT/mqtt_serializepublishheader_function.html',1,'']]], + ['mqtt_5fserializesubscribe_26',['MQTT_SerializeSubscribe',['coreMQTT/mqtt_serializesubscribe_function.html',1,'']]], + ['mqtt_5fserializeunsubscribe_27',['MQTT_SerializeUnsubscribe',['coreMQTT/mqtt_serializeunsubscribe_function.html',1,'']]], + ['mqtt_5fstatus_5fstrerror_28',['MQTT_Status_strerror',['coreMQTT/mqtt_status_strerror_function.html',1,'']]], + ['mqtt_5fsubscribe_29',['MQTT_Subscribe',['coreMQTT/mqtt_subscribe_function.html',1,'']]], + ['mqtt_5funsubscribe_30',['MQTT_Unsubscribe',['coreMQTT/mqtt_unsubscribe_function.html',1,'']]], + ['mqttagent_5fcancelall_31',['MQTTAgent_CancelAll',['../mqtt_agent_cancel_function.html',1,'mqtt_agent_functions']]], + ['mqttagent_5fcommandloop_32',['MQTTAgent_CommandLoop',['../mqtt_agent_command_function.html',1,'mqtt_agent_functions']]], + ['mqttagent_5fconnect_33',['MQTTAgent_Connect',['../mqtt_agent_connect_function.html',1,'mqtt_agent_functions']]], + ['mqttagent_5fdisconnect_34',['MQTTAgent_Disconnect',['../mqtt_agent_disconnect_function.html',1,'mqtt_agent_functions']]], + ['mqttagent_5finit_35',['MQTTAgent_Init',['../mqtt_agent_init_function.html',1,'mqtt_agent_functions']]], + ['mqttagent_5fping_36',['MQTTAgent_Ping',['../mqtt_agent_ping_function.html',1,'mqtt_agent_functions']]], + ['mqttagent_5fpublish_37',['MQTTAgent_Publish',['../mqtt_agent_publish_function.html',1,'mqtt_agent_functions']]], + ['mqttagent_5fresumesession_38',['MQTTAgent_ResumeSession',['../mqtt_agent_resume_function.html',1,'mqtt_agent_functions']]], + ['mqttagent_5fsubscribe_39',['MQTTAgent_Subscribe',['../mqtt_agent_subscribe_function.html',1,'mqtt_agent_functions']]], + ['mqttagent_5fterminate_40',['MQTTAgent_Terminate',['../mqtt_agent_terminate_function.html',1,'mqtt_agent_functions']]], + ['mqttagent_5funsubscribe_41',['MQTTAgent_Unsubscribe',['../mqtt_agent_unsubscribe_function.html',1,'mqtt_agent_functions']]] +]; diff --git a/v1.3.0/search/pages_4.js b/v1.3.0/search/pages_4.js new file mode 100644 index 00000000..0398f4f4 --- /dev/null +++ b/v1.3.0/search/pages_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['overview_0',['Overview',['../index.html',1,'']]] +]; diff --git a/v1.3.0/search/pages_5.js b/v1.3.0/search/pages_5.js new file mode 100644 index 00000000..0219e673 --- /dev/null +++ b/v1.3.0/search/pages_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['porting_20guide_0',['Porting Guide',['coreMQTT/mqtt_porting.html',1,'']]] +]; diff --git a/v1.3.0/search/pages_6.js b/v1.3.0/search/pages_6.js new file mode 100644 index 00000000..14a95a73 --- /dev/null +++ b/v1.3.0/search/pages_6.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['timeouts_20in_20coremqtt_20library_0',['Timeouts in coreMQTT library',['coreMQTT/mqtt_timeouts.html',1,'']]], + ['transport_20interface_1',['Transport Interface',['coreMQTT/mqtt_transport_interface.html',1,'']]] +]; diff --git a/v1.3.0/search/search.css b/v1.3.0/search/search.css new file mode 100644 index 00000000..a53214fc --- /dev/null +++ b/v1.3.0/search/search.css @@ -0,0 +1,286 @@ +/*---------------- Search Box */ + +#MSearchBox { + position: absolute; + right: 5px; +} +/*---------------- Search box styling */ + +.SRPage * { + font-weight: normal; + line-height: normal; +} + +dark-mode-toggle { + margin-left: 5px; + display: flex; + float: right; +} + +#MSearchBox { + display: inline-block; + white-space : nowrap; + background: var(--search-background-color); + border-radius: 0.65em; + box-shadow: var(--search-box-shadow); + z-index: 102; +} + +#MSearchBox .left { + display: inline-block; + vertical-align: middle; + height: 1.4em; +} + +#MSearchSelect { + display: inline-block; + vertical-align: middle; + width: 20px; + height: 19px; + background-image: var(--search-magnification-select-image); + margin: 0 0 0 0.3em; + padding: 0; +} + +#MSearchSelectExt { + display: inline-block; + vertical-align: middle; + width: 10px; + height: 19px; + background-image: var(--search-magnification-image); + margin: 0 0 0 0.5em; + padding: 0; +} + + +#MSearchField { + display: inline-block; + vertical-align: middle; + width: 7.5em; + height: 19px; + margin: 0 0.15em; + padding: 0; + line-height: 1em; + border:none; + color: var(--search-foreground-color); + outline: none; + font-family: var(--font-family-search); + -webkit-border-radius: 0px; + border-radius: 0px; + background: none; +} + +@media(hover: none) { + /* to avoid zooming on iOS */ + #MSearchField { + font-size: 16px; + } +} + +#MSearchBox .right { + display: inline-block; + vertical-align: middle; + width: 1.4em; + height: 1.4em; +} + +#MSearchClose { + display: none; + font-size: inherit; + background : none; + border: none; + margin: 0; + padding: 0; + outline: none; + +} + +#MSearchCloseImg { + padding: 0.3em; + margin: 0; +} + +.MSearchBoxActive #MSearchField { + color: var(--search-active-color); +} + + + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid var(--search-filter-border-color); + background-color: var(--search-filter-background-color); + z-index: 10001; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt var(--font-family-search); + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: var(--font-family-monospace); + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: var(--search-filter-foreground-color); + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: var(--search-filter-foreground-color); + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: var(--search-filter-highlight-text-color); + background-color: var(--search-filter-highlight-bg-color); + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + /*width: 60ex;*/ + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid var(--search-results-border-color); + background-color: var(--search-results-background-color); + z-index:10000; + width: 300px; + height: 400px; + overflow: auto; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +div.SRPage { + margin: 5px 2px; + background-color: var(--search-results-background-color); +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: var(--search-results-foreground-color); + font-family: var(--font-family-search); + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: var(--search-results-foreground-color); + font-family: var(--font-family-search); + font-size: 8pt; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; + font-family: var(--font-family-search); +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; + font-family: var(--font-family-search); +} + +.SRResult { + display: none; +} + +div.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: var(--nav-gradient-active-image-parent); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/v1.3.0/search/search.js b/v1.3.0/search/search.js new file mode 100644 index 00000000..e103a262 --- /dev/null +++ b/v1.3.0/search/search.js @@ -0,0 +1,816 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var idxChar = searchValue.substr(0, 1).toLowerCase(); + if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair + { + idxChar = searchValue.substr(0, 2); + } + + var jsFile; + + var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); + if (idx!=-1) + { + var hexCode=idx.toString(16); + jsFile = this.resultsPath + indexSectionNames[this.searchIndex] + '_' + hexCode + '.js'; + } + + var loadJS = function(url, impl, loc){ + var scriptTag = document.createElement('script'); + scriptTag.src = url; + scriptTag.onload = impl; + scriptTag.onreadystatechange = impl; + loc.appendChild(scriptTag); + } + + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + var domSearchBox = this.DOMSearchBox(); + var domPopupSearchResults = this.DOMPopupSearchResults(); + var domSearchClose = this.DOMSearchClose(); + var resultsPath = this.resultsPath; + + var handleResults = function() { + document.getElementById("Loading").style.display="none"; + if (typeof searchData !== 'undefined') { + createResults(resultsPath); + document.getElementById("NoMatches").style.display="none"; + } + + searchResults.Search(searchValue); + + if (domPopupSearchResultsWindow.style.display!='block') + { + domSearchClose.style.display = 'inline-block'; + var left = getXPos(domSearchBox) + 150; + var top = getYPos(domSearchBox) + 20; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + var maxWidth = document.body.clientWidth; + var maxHeight = document.body.clientHeight; + var width = 300; + if (left<10) left=10; + if (width+left+8>maxWidth) width=maxWidth-left-8; + var height = 400; + if (height+top+8>maxHeight) height=maxHeight-top-8; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResultsWindow.style.height = height + 'px'; + } + } + + if (jsFile) { + loadJS(jsFile, handleResults, this.DOMPopupSearchResultsWindow()); + } else { + handleResults(); + } + + this.lastSearchValue = searchValue; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + this.searchActive = true; + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + this.DOMSearchField().value = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName.toLowerCase() == 'div' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName.toLowerCase() == 'div' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + searchBox.CloseResultsWindow(); + document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + searchBox.CloseResultsWindow(); + document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults(resultsPath) +{ + var results = document.getElementById("SRResults"); + results.innerHTML = ''; + for (var e=0; e-{AmhX=Jf(#6djGiuzAr*{o?=JLmPLyc> z_*`QK&+BH@jWrYJ7>r6%keRM@)Qyv8R=enp0jiI>aWlGyB58O zFVR20d+y`K7vDw(hJF3;>dD*3-?v=<8M)@x|EEGLnJsniYK!2U1 Y!`|5biEc?d1`HDhPgg&ebxsLQ02F6;9RL6T literal 0 HcmV?d00001 diff --git a/v1.3.0/splitbard.png b/v1.3.0/splitbard.png new file mode 100644 index 0000000000000000000000000000000000000000..8367416d757fd7b6dc4272b6432dc75a75abd068 GIT binary patch literal 282 zcmeAS@N?(olHy`uVBq!ia0vp^Yzz!63>-{AmhX=Jf@VhhFKy35^fiT zT~&lUj3=cDh^%3HDY9k5CEku}PHXNoNC(_$U3XPb&Q*ME25pT;2(*BOgAf<+R$lzakPG`kF31()Fx{L5Wrac|GQzjeE= zueY1`Ze{#x<8=S|`~MgGetGce)#vN&|J{Cd^tS%;tBYTo?+^d68<#n_Y_xx`J||4O V@QB{^CqU0Kc)I$ztaD0e0svEzbJzd? literal 0 HcmV?d00001 diff --git a/v1.3.0/struct_m_q_t_t_agent_ack_info__t.html b/v1.3.0/struct_m_q_t_t_agent_ack_info__t.html new file mode 100644 index 00000000..f65dc8ba --- /dev/null +++ b/v1.3.0/struct_m_q_t_t_agent_ack_info__t.html @@ -0,0 +1,164 @@ + + + + + + + +coreMQTT Agent: MQTTAgentAckInfo_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTAgentAckInfo_t Struct Reference
+
+
+ +

Information for a pending MQTT ack packet expected by the agent. + More...

+ +

#include <core_mqtt_agent.h>

+ + + + + + +

+Data Fields

uint16_t packetId
 
MQTTAgentCommand_t * pOriginalCommand
 
+

Detailed Description

+

Information for a pending MQTT ack packet expected by the agent.

+

Field Documentation

+ +

◆ packetId

+ +
+
+ + + + +
uint16_t MQTTAgentAckInfo_t::packetId
+
+

Packet ID of the pending acknowledgment.

+ +
+
+ +

◆ pOriginalCommand

+ +
+
+ + + + +
MQTTAgentCommand_t* MQTTAgentAckInfo_t::pOriginalCommand
+
+

Command expecting acknowledgment.

+ +
+
+
The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/v1.3.0/struct_m_q_t_t_agent_command.html b/v1.3.0/struct_m_q_t_t_agent_command.html new file mode 100644 index 00000000..b2d39193 --- /dev/null +++ b/v1.3.0/struct_m_q_t_t_agent_command.html @@ -0,0 +1,146 @@ + + + + + + + +coreMQTT Agent: MQTTAgentCommand_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTAgentCommand_t Struct Reference
+
+
+ +

The commands sent from the APIs to the MQTT agent task. + More...

+ +

#include <core_mqtt_agent.h>

+ + + + + + + + + + + + + + +

+Data Fields

+MQTTAgentCommandType_t commandType
 Type of command.
 
+void * pArgs
 Arguments of command.
 
+MQTTAgentCommandCallback_t pCommandCompleteCallback
 Callback to invoke upon completion.
 
+MQTTAgentCommandContext_tpCmdContext
 Context for completion callback.
 
+

Detailed Description

+

The commands sent from the APIs to the MQTT agent task.

+
Note
The structure used to pass information from the public facing API into the agent task.
+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/v1.3.0/struct_m_q_t_t_agent_command_func_returns__t.html b/v1.3.0/struct_m_q_t_t_agent_command_func_returns__t.html new file mode 100644 index 00000000..6b00b2be --- /dev/null +++ b/v1.3.0/struct_m_q_t_t_agent_command_func_returns__t.html @@ -0,0 +1,145 @@ + + + + + + + +coreMQTT Agent: MQTTAgentCommandFuncReturns_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTAgentCommandFuncReturns_t Struct Reference
+
+
+ +

A structure of values and flags expected to be returned by command functions. + More...

+ +

#include <core_mqtt_agent_command_functions.h>

+ + + + + + + + + + + + + + +

+Data Fields

+uint16_t packetId
 Packet ID of packet sent by command.
 
+bool endLoop
 Flag to indicate command loop should terminate.
 
+bool addAcknowledgment
 Flag to indicate an acknowledgment should be tracked.
 
+bool runProcessLoop
 Flag to indicate MQTT_ProcessLoop() should be called after this command.
 
+

Detailed Description

+

A structure of values and flags expected to be returned by command functions.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/v1.3.0/struct_m_q_t_t_agent_command_info__t.html b/v1.3.0/struct_m_q_t_t_agent_command_info__t.html new file mode 100644 index 00000000..6d13c792 --- /dev/null +++ b/v1.3.0/struct_m_q_t_t_agent_command_info__t.html @@ -0,0 +1,141 @@ + + + + + + + +coreMQTT Agent: MQTTAgentCommandInfo_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTAgentCommandInfo_t Struct Reference
+
+
+ +

Struct holding arguments that are common to every command. + More...

+ +

#include <core_mqtt_agent.h>

+ + + + + + + + + + + +

+Data Fields

+MQTTAgentCommandCallback_t cmdCompleteCallback
 Callback to invoke upon completion.
 
+MQTTAgentCommandContext_tpCmdCompleteCallbackContext
 Context for completion callback.
 
+uint32_t blockTimeMs
 Maximum block time for enqueueing the command.
 
+

Detailed Description

+

Struct holding arguments that are common to every command.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/v1.3.0/struct_m_q_t_t_agent_connect_args__t.html b/v1.3.0/struct_m_q_t_t_agent_connect_args__t.html new file mode 100644 index 00000000..f1c9353e --- /dev/null +++ b/v1.3.0/struct_m_q_t_t_agent_connect_args__t.html @@ -0,0 +1,145 @@ + + + + + + + +coreMQTT Agent: MQTTAgentConnectArgs_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTAgentConnectArgs_t Struct Reference
+
+
+ +

Struct holding arguments for a CONNECT call. + More...

+ +

#include <core_mqtt_agent.h>

+ + + + + + + + + + + + + + +

+Data Fields

+MQTTConnectInfo_tpConnectInfo
 MQTT CONNECT packet information.
 
+MQTTPublishInfo_tpWillInfo
 Optional Last Will and Testament.
 
+uint32_t timeoutMs
 Maximum timeout for a CONNACK packet.
 
+bool sessionPresent
 Output flag set if a previous session was present.
 
+

Detailed Description

+

Struct holding arguments for a CONNECT call.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/v1.3.0/struct_m_q_t_t_agent_context__t.html b/v1.3.0/struct_m_q_t_t_agent_context__t.html new file mode 100644 index 00000000..ead582df --- /dev/null +++ b/v1.3.0/struct_m_q_t_t_agent_context__t.html @@ -0,0 +1,232 @@ + + + + + + + +coreMQTT Agent: MQTTAgentContext_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTAgentContext_t Struct Reference
+
+
+ +

Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(), and every API function will accept a pointer to the initalized struct. + More...

+ +

#include <core_mqtt_agent.h>

+ + + + + + + + + + + + + + +

+Data Fields

MQTTContext_t mqttContext
 
MQTTAgentMessageInterface_t agentInterface
 
MQTTAgentAckInfo_t pPendingAcks [MQTT_AGENT_MAX_OUTSTANDING_ACKS]
 
MQTTAgentIncomingPublishCallback_t pIncomingCallback
 
void * pIncomingCallbackContext
 
bool packetReceivedInLoop
 
+

Detailed Description

+

Information used by each MQTT agent. A context will be initialized by MQTTAgent_Init(), and every API function will accept a pointer to the initalized struct.

+

Field Documentation

+ +

◆ mqttContext

+ +
+
+ + + + +
MQTTContext_t MQTTAgentContext_t::mqttContext
+
+

MQTT connection information used by coreMQTT.

+ +
+
+ +

◆ agentInterface

+ +
+
+ + + + +
MQTTAgentMessageInterface_t MQTTAgentContext_t::agentInterface
+
+

Struct of function pointers for agent messaging.

+ +
+
+ +

◆ pPendingAcks

+ +
+
+ + + + +
MQTTAgentAckInfo_t MQTTAgentContext_t::pPendingAcks[MQTT_AGENT_MAX_OUTSTANDING_ACKS]
+
+

List of pending acknowledgment packets.

+ +
+
+ +

◆ pIncomingCallback

+ +
+
+ + + + +
MQTTAgentIncomingPublishCallback_t MQTTAgentContext_t::pIncomingCallback
+
+

Callback to invoke for incoming publishes.

+ +
+
+ +

◆ pIncomingCallbackContext

+ +
+
+ + + + +
void* MQTTAgentContext_t::pIncomingCallbackContext
+
+

Context for incoming publish callback.

+ +
+
+ +

◆ packetReceivedInLoop

+ +
+
+ + + + +
bool MQTTAgentContext_t::packetReceivedInLoop
+
+

Whether a MQTT_ProcessLoop() call received a packet.

+ +
+
+
The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/v1.3.0/struct_m_q_t_t_agent_message_interface__t.html b/v1.3.0/struct_m_q_t_t_agent_message_interface__t.html new file mode 100644 index 00000000..4df91493 --- /dev/null +++ b/v1.3.0/struct_m_q_t_t_agent_message_interface__t.html @@ -0,0 +1,215 @@ + + + + + + + +coreMQTT Agent: MQTTAgentMessageInterface_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTAgentMessageInterface_t Struct Reference
+
+
+ +

Function pointers and contexts used for sending and receiving commands, and allocating memory for them. + More...

+ +

#include <core_mqtt_agent_message_interface.h>

+ + + + + + + + + + + + +

+Data Fields

MQTTAgentMessageContext_tpMsgCtx
 
MQTTAgentMessageSend_t send
 
MQTTAgentMessageRecv_t recv
 
MQTTAgentCommandGet_t getCommand
 
MQTTAgentCommandRelease_t releaseCommand
 
+

Detailed Description

+

Function pointers and contexts used for sending and receiving commands, and allocating memory for them.

+

Field Documentation

+ +

◆ pMsgCtx

+ +
+
+ + + + +
MQTTAgentMessageContext_t* MQTTAgentMessageInterface_t::pMsgCtx
+
+

Context with which tasks may deliver messages to the agent.

+ +
+
+ +

◆ send

+ +
+
+ + + + +
MQTTAgentMessageSend_t MQTTAgentMessageInterface_t::send
+
+

Function to send a command to the agent.

+ +
+
+ +

◆ recv

+ +
+
+ + + + +
MQTTAgentMessageRecv_t MQTTAgentMessageInterface_t::recv
+
+

Function for the agent to receive a command.

+ +
+
+ +

◆ getCommand

+ +
+
+ + + + +
MQTTAgentCommandGet_t MQTTAgentMessageInterface_t::getCommand
+
+

Function to obtain a pointer to an allocated command.

+ +
+
+ +

◆ releaseCommand

+ +
+
+ + + + +
MQTTAgentCommandRelease_t MQTTAgentMessageInterface_t::releaseCommand
+
+

Function to release an allocated command.

+ +
+
+
The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/v1.3.0/struct_m_q_t_t_agent_return_info__t.html b/v1.3.0/struct_m_q_t_t_agent_return_info__t.html new file mode 100644 index 00000000..aa7f6d4b --- /dev/null +++ b/v1.3.0/struct_m_q_t_t_agent_return_info__t.html @@ -0,0 +1,164 @@ + + + + + + + +coreMQTT Agent: MQTTAgentReturnInfo_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTAgentReturnInfo_t Struct Reference
+
+
+ +

Struct holding return codes and outputs from a command. + More...

+ +

#include <core_mqtt_agent.h>

+ + + + + + +

+Data Fields

MQTTStatus_t returnCode
 
uint8_t * pSubackCodes
 
+

Detailed Description

+

Struct holding return codes and outputs from a command.

+

Field Documentation

+ +

◆ returnCode

+ +
+
+ + + + +
MQTTStatus_t MQTTAgentReturnInfo_t::returnCode
+
+

Return code of the MQTT command.

+ +
+
+ +

◆ pSubackCodes

+ +
+
+ + + + +
uint8_t* MQTTAgentReturnInfo_t::pSubackCodes
+
+

Array of SUBACK statuses, for a SUBSCRIBE command.

+ +
+
+
The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/v1.3.0/struct_m_q_t_t_agent_subscribe_args__t.html b/v1.3.0/struct_m_q_t_t_agent_subscribe_args__t.html new file mode 100644 index 00000000..7c4e3a93 --- /dev/null +++ b/v1.3.0/struct_m_q_t_t_agent_subscribe_args__t.html @@ -0,0 +1,137 @@ + + + + + + + +coreMQTT Agent: MQTTAgentSubscribeArgs_t Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
coreMQTT Agent v1.3.0+ +
+
Thread safe MQTT 3.1.1 Client
+
+ +   + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
MQTTAgentSubscribeArgs_t Struct Reference
+
+
+ +

Struct holding arguments for a SUBSCRIBE or UNSUBSCRIBE call. + More...

+ +

#include <core_mqtt_agent.h>

+ + + + + + + + +

+Data Fields

+MQTTSubscribeInfo_tpSubscribeInfo
 List of MQTT subscriptions.
 
+size_t numSubscriptions
 Number of elements in pSubscribeInfo.
 
+

Detailed Description

+

Struct holding arguments for a SUBSCRIBE or UNSUBSCRIBE call.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/v1.3.0/style.css b/v1.3.0/style.css new file mode 100644 index 00000000..99d7ab71 --- /dev/null +++ b/v1.3.0/style.css @@ -0,0 +1,132 @@ +/* + * Stylesheet for Doxygen HTML output. + * + * This file defines styles for custom elements in the header/footer and + * overrides some of the default Doxygen styles. + * + * Styles in this file do not affect the treeview sidebar. + */ + +/* Set the margins to place a small amount of whitespace on the left and right + * side of the page. */ +div.contents { + margin-left:4em; + margin-right:4em; +} + +/* Justify text in paragraphs. */ +p { + text-align: justify; +} + +/* Style of section headings. */ +h1 { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 160%; + font-weight: normal; + padding-bottom: 4px; + padding-top: 8px; +} + +/* Style of subsection headings. */ +h2:not(.memtitle):not(.groupheader) { + font-size: 125%; + margin-bottom: 0px; + margin-top: 16px; + padding: 0px; +} + +/* Style of paragraphs immediately after subsection headings. */ +h2 + p { + margin: 0px; + padding: 0px; +} + +/* Style of subsection headings. */ +h3 { + font-size: 100%; + margin-bottom: 0px; + margin-left: 2em; + margin-right: 2em; +} + +/* Style of paragraphs immediately after subsubsection headings. */ +h3 + p { + margin-top: 0px; + margin-left: 2em; + margin-right: 2em; +} + +/* Style of the prefix "AWS IoT Device SDK C" that appears in the header. */ +#csdkprefix { + color: #757575; +} + +/* Style of the "Return to main page" link that appears in the header. */ +#returntomain { + padding: 0.5em; +} + +/* Style of the dividers on Configuration Settings pages. */ +div.configpagedivider { + margin-left: 0px !important; + margin-right: 0px !important; + margin-top: 20px !important; +} + +/* Style of configuration setting names. */ +dl.section.user ~ h1 { + border-bottom: none; + color: #000000; + font-family: monospace, fixed; + font-size: 16px; + margin-bottom: 0px; + margin-left: 2em; + margin-top: 1.5em; +} + +/* Style of paragraphs on a configuration settings page. */ +dl.section.user ~ * { + margin-bottom: 10px; + margin-left: 4em; + margin-right: 4em; + margin-top: 0px; +} + +/* Hide the configuration setting marker. */ +dl.section.user { + display: none; +} + +/* Overrides for code fragments and lines. */ +div.fragment { + background: #ffffff; + border: none; + padding: 5px; +} + +div.line { + color: #3a3a3a; +} + +/* Overrides for code syntax highlighting colors. */ +span.comment { + color: #008000; +} + +span.keyword, span.keywordtype, span.keywordflow { + color: #0000ff; +} + +span.preprocessor { + color: #50015a; +} + +span.stringliteral, span.charliteral { + color: #800c0c; +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #496194; +} diff --git a/v1.3.0/sync_off.png b/v1.3.0/sync_off.png new file mode 100644 index 0000000000000000000000000000000000000000..3b443fc62892114406e3d399421b2a881b897acc GIT binary patch literal 853 zcmV-b1FHOqP)oT|#XixUYy%lpuf3i8{fX!o zUyDD0jOrAiT^tq>fLSOOABs-#u{dV^F$b{L9&!2=9&RmV;;8s^x&UqB$PCj4FdKbh zoB1WTskPUPu05XzFbA}=KZ-GP1fPpAfSs>6AHb12UlR%-i&uOlTpFNS7{jm@mkU1V zh`nrXr~+^lsV-s1dkZOaI|kYyVj3WBpPCY{n~yd%u%e+d=f%`N0FItMPtdgBb@py; zq@v6NVArhyTC7)ULw-Jy8y42S1~4n(3LkrW8mW(F-4oXUP3E`e#g**YyqI7h-J2zK zK{m9##m4ri!7N>CqQqCcnI3hqo1I;Yh&QLNY4T`*ptiQGozK>FF$!$+84Z`xwmeMh zJ0WT+OH$WYFALEaGj2_l+#DC3t7_S`vHpSivNeFbP6+r50cO8iu)`7i%Z4BTPh@_m3Tk!nAm^)5Bqnr%Ov|Baunj#&RPtRuK& z4RGz|D5HNrW83-#ydk}tVKJrNmyYt-sTxLGlJY5nc&Re zU4SgHNPx8~Yxwr$bsju?4q&%T1874xxzq+_%?h8_ofw~(bld=o3iC)LUNR*BY%c0y zWd_jX{Y8`l%z+ol1$@Qa?Cy!(0CVIEeYpKZ`(9{z>3$CIe;pJDQk$m3p}$>xBm4lb zKo{4S)`wdU9Ba9jJbVJ0C=SOefZe%d$8=2r={nu<_^a3~>c#t_U6dye5)JrR(_a^E f@}b6j1K9lwFJq@>o)+Ry00000NkvXXu0mjfWa5j* literal 0 HcmV?d00001 diff --git a/v1.3.0/sync_on.png b/v1.3.0/sync_on.png new file mode 100644 index 0000000000000000000000000000000000000000..e08320fb64e6fa33b573005ed6d8fe294e19db76 GIT binary patch literal 845 zcmV-T1G4;yP)Y;xxyHF2B5Wzm| zOOGupOTn@c(JmBOl)e;XMNnZuiTJP>rM8<|Q`7I_))aP?*T)ow&n59{}X4$3Goat zgjs?*aasfbrokzG5cT4K=uG`E14xZl@z)F={P0Y^?$4t z>v!teRnNZym<6h{7sLyF1V0HsfEl+l6TrZpsfr1}luH~F7L}ktXu|*uVX^RG$L0`K zWs3j|0tIvVe(N%_?2{(iCPFGf#B6Hjy6o&}D$A%W%jfO8_W%ZO#-mh}EM$LMn7joJ z05dHr!5Y92g+31l<%i1(=L1a1pXX+OYnalY>31V4K}BjyRe3)9n#;-cCVRD_IG1fT zOKGeNY8q;TL@K{dj@D^scf&VCs*-Jb>8b>|`b*osv52-!A?BpbYtTQBns5EAU**$m zSnVSm(teh>tQi*S*A>#ySc=n;`BHz`DuG4&g4Kf8lLhca+zvZ7t7RflD6-i-mcK=M z!=^P$*u2)bkY5asG4gsss!Hn%u~>}kIW`vMs%lJLH+u*9<4PaV_c6U`KqWXQH%+Nu zTv41O(^ZVi@qhjQdG!fbZw&y+2o!iYymO^?ud3{P*HdoX83YV*Uu_HB=?U&W9%AU# z80}k1SS-CXTU7dcQlsm<^oYLxVSseqY6NO}dc`Nj?8vrhNuCdm@^{a3AQ_>6myOj+ z`1RsLUXF|dm|3k7s2jD(B{rzE>WI2scH8i1;=O5Cc9xB3^aJk%fQjqsu+kH#0=_5a z0nCE8@dbQa-|YIuUVvG0L_IwHMEhOj$Mj4Uq05 X8=0q~qBNan00000NkvXXu0mjfptF>5 literal 0 HcmV?d00001 diff --git a/v1.3.0/tab_a.png b/v1.3.0/tab_a.png new file mode 100644 index 0000000000000000000000000000000000000000..3b725c41c5a527a3a3e40097077d0e206a681247 GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QlXwMjv*C{Z|8b*H5dputLHD# z=<0|*y7z(Vor?d;H&?EG&cXR}?!j-Lm&u1OOI7AIF5&c)RFE;&p0MYK>*Kl@eiymD r@|NpwKX@^z+;{u_Z~trSBfrMKa%3`zocFjEXaR$#tDnm{r-UW|TZ1%4 literal 0 HcmV?d00001 diff --git a/v1.3.0/tab_ad.png b/v1.3.0/tab_ad.png new file mode 100644 index 0000000000000000000000000000000000000000..e34850acfc24be58da6d2fd1ccc6b29cc84fe34d GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QhuH;jv*C{Z|5d*H3V=pKi{In zd2jxLclDRPylmD}^l7{QOtL{vUjO{-WqItb5sQp2h-99b8^^Scr-=2mblCdZuUm?4 jzOJvgvt3{(cjKLW5(A@0qPS@<&}0TrS3j3^P6y&q2{!U5bk+Tso_B!YCpDh>v z{CM*1U8YvQRyBUHt^Ju0W_sq-?;9@_4equ-bavTs=gk796zopr0EBT&m;e9( literal 0 HcmV?d00001 diff --git a/v1.3.0/tab_s.png b/v1.3.0/tab_s.png new file mode 100644 index 0000000000000000000000000000000000000000..ab478c95b67371d700a20869f7de1ddd73522d50 GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QuUrLjv*C{Z|^p8HaRdjTwH7) zC?wLlL}}I{)n%R&r+1}IGmDnq;&J#%V6)9VsYhS`O^BVBQlxOUep0c$RENLq#g8A$ z)z7%K_bI&n@J+X_=x}fJoEKed-$<>=ZI-;YrdjIl`U`uzuDWSP?o#Dmo{%SgM#oan kX~E1%D-|#H#QbHoIja2U-MgvsK&LQxy85}Sb4q9e0Efg%P5=M^ literal 0 HcmV?d00001 diff --git a/v1.3.0/tab_sd.png b/v1.3.0/tab_sd.png new file mode 100644 index 0000000000000000000000000000000000000000..757a565ced4730f85c833fb2547d8e199ae68f19 GIT binary patch literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!Qq7(&jv*C{Z|_!fH5o7*c=%9% zcILh!EA=pAQKdx-Cdiev=v{eg{8Ht<{e8_NAN~b=)%W>-WDCE0PyDHGemi$BoXwcK z{>e9^za6*c1ilttWw&V+U;WCPlV9{LdC~Ey%_H(qj`xgfES(4Yz5jSTZfCt`4E$0YRsR*S^mTCR^;V&sxC8{l_Cp7w8-YPgg&ebxsLQ00$vXK>z>% literal 0 HcmV?d00001 diff --git a/v1.3.0/tabs.css b/v1.3.0/tabs.css new file mode 100644 index 00000000..71c8a470 --- /dev/null +++ b/v1.3.0/tabs.css @@ -0,0 +1 @@ +.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.main-menu-btn{position:relative;display:inline-block;width:36px;height:36px;text-indent:36px;margin-left:8px;white-space:nowrap;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0)}.main-menu-btn-icon,.main-menu-btn-icon:before,.main-menu-btn-icon:after{position:absolute;top:50%;left:2px;height:2px;width:24px;background:var(--nav-menu-button-color);-webkit-transition:all .25s;transition:all .25s}.main-menu-btn-icon:before{content:'';top:-7px;left:0}.main-menu-btn-icon:after{content:'';top:7px;left:0}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon{height:0}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon:before{top:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon:after{top:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}#main-menu-state{position:absolute;width:1px;height:1px;margin:-1px;border:0;padding:0;overflow:hidden;clip:rect(1px,1px,1px,1px)}#main-menu-state:not(:checked) ~ #main-menu{display:none}#main-menu-state:checked ~ #main-menu{display:block}@media(min-width:768px){.main-menu-btn{position:absolute;top:-99999px}#main-menu-state:not(:checked) ~ #main-menu{display:block}}.sm-dox{background-image:var(--nav-gradient-image)}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0 12px;padding-right:43px;font-family:var(--font-family-nav);font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:var(--nav-text-normal-shadow);color:var(--nav-text-normal-color);outline:0}.sm-dox a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox a.current{color:#d23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace !important;text-align:center;text-shadow:none;background:var(--nav-menu-toggle-color);-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox a span.sub-arrow:before{display:block;content:'+'}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px;border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0;border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox ul{background:var(--nav-menu-background-color)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:var(--nav-menu-background-color);background-image:none}.sm-dox ul a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:0 1px 1px black}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media(min-width:768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:var(--nav-gradient-image);line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:var(--nav-text-normal-color) transparent transparent transparent;background:transparent;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0 12px;background-image:var(--nav-separator-image);background-repeat:no-repeat;background-position:right;-moz-border-radius:0 !important;-webkit-border-radius:0;border-radius:0 !important}.sm-dox a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox a:hover span.sub-arrow{border-color:var(--nav-text-hover-color) transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent var(--nav-menu-background-color) transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:var(--nav-menu-background-color);-moz-border-radius:5px !important;-webkit-border-radius:5px;border-radius:5px !important;-moz-box-shadow:0 5px 9px rgba(0,0,0,0.2);-webkit-box-shadow:0 5px 9px rgba(0,0,0,0.2);box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent var(--nav-menu-foreground-color);border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:var(--nav-menu-foreground-color);background-image:none;border:0 !important;color:var(--nav-menu-foreground-color);background-image:none}.sm-dox ul a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent var(--nav-text-hover-color)}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:var(--nav-menu-background-color);height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #d23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#d23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent var(--nav-menu-foreground-color) transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:var(--nav-menu-foreground-color) transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px !important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:var(--nav-gradient-image)}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:var(--nav-menu-background-color)}} \ No newline at end of file