From 94c3e69b4425fe21b0a30b5e8c564ff05ae03055 Mon Sep 17 00:00:00 2001 From: Feng Date: Fri, 5 Feb 2016 14:26:17 +0800 Subject: [PATCH] Licensed under the Apache, Version 2.0 --- LICENSE | 214 +++++++++++++++++++++++++++++--- README.md | 2 +- include/emqttd.hrl | 94 +++++++------- include/emqttd_cli.hrl | 36 +++--- include/emqttd_internal.hrl | 41 +++--- include/emqttd_protocol.hrl | 87 ++++++------- src/emqttd.app.src | 4 +- src/emqttd.erl | 129 +++++++------------ src/emqttd_access_control.erl | 183 +++++++++++---------------- src/emqttd_access_rule.erl | 54 ++++---- src/emqttd_acl_internal.erl | 77 +++++------- src/emqttd_acl_mod.erl | 54 ++++---- src/emqttd_alarm.erl | 68 +++++----- src/emqttd_app.erl | 50 ++++---- src/emqttd_auth_anonymous.erl | 44 +++---- src/emqttd_auth_clientid.erl | 109 +++++++--------- src/emqttd_auth_ldap.erl | 52 ++++---- src/emqttd_auth_mod.erl | 50 ++++---- src/emqttd_auth_username.erl | 126 ++++++++----------- src/emqttd_bridge.erl | 88 ++++++------- src/emqttd_bridge_sup.erl | 114 +++++++---------- src/emqttd_broker.erl | 106 ++++------------ src/emqttd_cli.erl | 97 +++++---------- src/emqttd_client.erl | 49 ++++---- src/emqttd_cm.erl | 76 ++++-------- src/emqttd_cm_sup.erl | 43 +++---- src/emqttd_ctl.erl | 77 +++++------- src/emqttd_dist.erl | 43 +++---- src/emqttd_gen_mod.erl | 45 +++---- src/emqttd_guid.erl | 73 +++++------ src/emqttd_http.erl | 61 +++++---- src/emqttd_keepalive.erl | 52 +++----- src/emqttd_log.erl | 33 ----- src/emqttd_message.erl | 61 +++------ src/emqttd_metrics.erl | 97 ++++----------- src/emqttd_mnesia.erl | 89 ++++--------- src/emqttd_mod_presence.erl | 46 +++---- src/emqttd_mod_rewrite.erl | 57 ++++----- src/emqttd_mod_subscription.erl | 45 +++---- src/emqttd_mod_sup.erl | 58 ++++----- src/emqttd_mqueue.erl | 96 +++++++------- src/emqttd_net.erl | 43 +++---- src/emqttd_opts.erl | 49 +++----- src/emqttd_packet.erl | 57 +++------ src/emqttd_parser.erl | 52 +++----- src/emqttd_plugins.erl | 64 ++++------ src/emqttd_pool_sup.erl | 43 +++---- src/emqttd_pooler.erl | 73 +++++------ src/emqttd_protocol.erl | 51 ++++---- src/emqttd_pubsub.erl | 73 +++++------ src/emqttd_pubsub_helper.erl | 45 +++---- src/emqttd_pubsub_sup.erl | 43 +++---- src/emqttd_retainer.erl | 81 +++++------- src/emqttd_router.erl | 42 +++---- src/emqttd_serializer.erl | 46 +++---- src/emqttd_session.erl | 138 ++++++++------------ src/emqttd_session_sup.erl | 56 ++++----- src/emqttd_sm.erl | 82 +++++------- src/emqttd_sm_helper.erl | 52 ++++---- src/emqttd_sm_sup.erl | 43 +++---- src/emqttd_stats.erl | 80 +++++------- src/emqttd_sup.erl | 55 ++++---- src/emqttd_sysmon.erl | 52 ++++---- src/emqttd_sysmon_sup.erl | 43 +++---- src/emqttd_topic.erl | 43 +++---- src/emqttd_trace.erl | 69 +++++----- src/emqttd_trace_sup.erl | 43 +++---- src/emqttd_trie.erl | 120 ++++++------------ src/emqttd_util.erl | 43 +++---- src/emqttd_vm.erl | 43 +++---- src/emqttd_ws_client.erl | 67 ++++------ src/lager_emqtt_backend.erl | 43 +++---- 72 files changed, 1989 insertions(+), 2825 deletions(-) delete mode 100644 src/emqttd_log.erl diff --git a/LICENSE b/LICENSE index cd6ef5565..8dada3eda 100644 --- a/LICENSE +++ b/LICENSE @@ -1,25 +1,201 @@ -The MIT License (MIT) + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -Copyright (c) 2012-2016 eMQTT.IO, All Rights Reserved. + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -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: + 1. Definitions. -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. -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. + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. -The source files 'gen_server2.erl' and 'priority_queue.erl' are from RabbitMQ -v3.5.4 and licensed under MPL license. + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index a76d15bb7..c4267105b 100644 --- a/README.md +++ b/README.md @@ -145,5 +145,5 @@ Feng Lee ## License -The MIT License (MIT) +Apache License Version 2.0 diff --git a/include/emqttd.hrl b/include/emqttd.hrl index 803be1318..661deefd2 100644 --- a/include/emqttd.hrl +++ b/include/emqttd.hrl @@ -1,33 +1,25 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc -%%% MQTT Broker Header. -%%% -%%% @end -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- -%%------------------------------------------------------------------------------ +%% @doc MQTT Broker Header. + +%%-------------------------------------------------------------------- %% Banner -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- + -define(COPYRIGHT, "Copyright (C) 2012-2016, Feng Lee "). -define(LICENSE_MESSAGE, "Licensed under MIT"). @@ -42,16 +34,17 @@ %% Queue Topics. -define(QTop, <<"$Q">>). -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% PubSub -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- + -type pubsub() :: publish | subscribe. -define(IS_PUBSUB(PS), (PS =:= publish orelse PS =:= subscribe)). -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% MQTT Topic -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- -record(mqtt_topic, { topic :: binary(), node :: node() @@ -59,24 +52,23 @@ -type mqtt_topic() :: #mqtt_topic{}. -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% MQTT Subscription -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- -record(mqtt_subscription, { subid :: binary() | atom(), topic :: binary(), - qos = 0 :: 0 | 1 | 2, - static = false :: boolean() + qos = 0 :: 0 | 1 | 2 }). -type mqtt_subscription() :: #mqtt_subscription{}. -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% MQTT Client -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- --type header_key() :: atom() | binary() | string(). --type header_val() :: atom() | binary() | string() | integer(). +-type ws_header_key() :: atom() | binary() | string(). +-type ws_header_val() :: atom() | binary() | string() | integer(). -record(mqtt_client, { client_id :: binary() | undefined, @@ -87,15 +79,15 @@ proto_ver :: 3 | 4, keepalive = 0, will_topic :: undefined | binary(), - ws_initial_headers :: list({header_key(), header_val()}), + ws_initial_headers :: list({ws_header_key(), ws_header_val()}), connected_at :: erlang:timestamp() }). -type mqtt_client() :: #mqtt_client{}. -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% MQTT Session -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- -record(mqtt_session, { client_id :: binary(), sess_pid :: pid(), @@ -104,9 +96,9 @@ -type mqtt_session() :: #mqtt_session{}. -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% MQTT Message -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- -type mqtt_msgid() :: binary() | undefined. -type mqtt_pktid() :: 1..16#ffff | undefined. @@ -127,9 +119,9 @@ -type mqtt_message() :: #mqtt_message{}. -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% MQTT Alarm -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- -record(mqtt_alarm, { id :: binary(), severity :: warning | error | critical, @@ -140,9 +132,9 @@ -type mqtt_alarm() :: #mqtt_alarm{}. -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% MQTT Plugin -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- -record(mqtt_plugin, { name, version, @@ -153,10 +145,10 @@ -type mqtt_plugin() :: #mqtt_plugin{}. -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% MQTT CLI Command %% For example: 'broker metrics' -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- -record(mqtt_cli, { name, action, diff --git a/include/emqttd_cli.hrl b/include/emqttd_cli.hrl index 8a0be700a..e2c27e779 100644 --- a/include/emqttd_cli.hrl +++ b/include/emqttd_cli.hrl @@ -1,24 +1,18 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 eMQTT.IO, All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- -define(PRINT(Format, Args), io:format(Format, Args)). diff --git a/include/emqttd_internal.hrl b/include/emqttd_internal.hrl index 4a95d1d6b..548009279 100644 --- a/include/emqttd_internal.hrl +++ b/include/emqttd_internal.hrl @@ -1,27 +1,20 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 eMQTT.IO, All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc Internal Header File -%%% -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Internal Header File -define(GPROC_POOL(JoinOrLeave, Pool, I), (begin diff --git a/include/emqttd_protocol.hrl b/include/emqttd_protocol.hrl index 00635e3c2..44b1af25d 100644 --- a/include/emqttd_protocol.hrl +++ b/include/emqttd_protocol.hrl @@ -1,33 +1,24 @@ -%%%----------------------------------------------------------------------------- -%%% @Copyright (C) 2012-2016, Feng Lee -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc -%%% MQTT Protocol Header. -%%% -%%% @end -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- -%%------------------------------------------------------------------------------ +%% @doc MQTT Protocol Header. + +%%-------------------------------------------------------------------- %% MQTT Protocol Version and Levels -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- -define(MQTT_PROTO_V31, 3). -define(MQTT_PROTO_V311, 4). @@ -37,9 +28,9 @@ -type mqtt_vsn() :: ?MQTT_PROTO_V31 | ?MQTT_PROTO_V311. -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% MQTT QoS -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- -define(QOS_0, 0). %% At most once -define(QOS_1, 1). %% At least once -define(QOS_2, 2). %% Exactly once @@ -72,14 +63,14 @@ end). -%%------------------------------------------------------------------------------ -%% Max ClientId Length. Why 1024? NiDongDe! -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- +%% Max ClientId Length. Why 1024? NiDongDe... +%%-------------------------------------------------------------------- -define(MAX_CLIENTID_LEN, 1024). -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% MQTT Control Packet Types -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- -define(RESERVED, 0). %% Reserved -define(CONNECT, 1). %% Client request to connect to Server -define(CONNACK, 2). %% Server to Client: Connect acknowledgment @@ -114,9 +105,9 @@ -type mqtt_packet_type() :: ?RESERVED..?DISCONNECT. -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% MQTT Connect Return Codes -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- -define(CONNACK_ACCEPT, 0). %% Connection accepted -define(CONNACK_PROTO_VER, 1). %% Unacceptable protocol version -define(CONNACK_INVALID_ID, 2). %% Client Identifier is correct UTF-8 but not allowed by the Server @@ -126,25 +117,25 @@ -type mqtt_connack() :: ?CONNACK_ACCEPT..?CONNACK_AUTH. -%%------------------------------------------------------------------------------ -%% MQTT Parser and Serialiser -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- +%% MQTT Parser and Serializer +%%-------------------------------------------------------------------- -define(MAX_LEN, 16#fffffff). -define(HIGHBIT, 2#10000000). -define(LOWBITS, 2#01111111). -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% MQTT Packet Fixed Header -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- -record(mqtt_packet_header, { type = ?RESERVED :: mqtt_packet_type(), dup = false :: boolean(), qos = ?QOS_0 :: mqtt_qos(), retain = false :: boolean()}). -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% MQTT Packets -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- -type mqtt_client_id() :: binary(). -type mqtt_packet_id() :: 1..16#ffff | undefined. @@ -188,9 +179,9 @@ -record(mqtt_packet_unsuback, { packet_id :: mqtt_packet_id() }). -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% MQTT Control Packet -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- -record(mqtt_packet, { header :: #mqtt_packet_header{}, variable :: #mqtt_packet_connect{} | #mqtt_packet_connack{} @@ -202,9 +193,9 @@ -type mqtt_packet() :: #mqtt_packet{}. -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% MQTT Packet Match -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- -define(CONNECT_PACKET(Var), #mqtt_packet{header = #mqtt_packet_header{type = ?CONNECT}, variable = Var}). diff --git a/src/emqttd.app.src b/src/emqttd.app.src index 1777ae1ee..b95538fb4 100644 --- a/src/emqttd.app.src +++ b/src/emqttd.app.src @@ -1,8 +1,8 @@ {application, emqttd, [ - {id, "emqttd"}, - {vsn, "0.15.1"}, {description, "Erlang MQTT Broker"}, + {vsn, "0.16.0"}, + {id, "emqttd"}, {modules, []}, {registered, []}, {applications, [kernel, diff --git a/src/emqttd.erl b/src/emqttd.erl index 47686544e..f97dc80e2 100644 --- a/src/emqttd.erl +++ b/src/emqttd.erl @@ -1,38 +1,28 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd main module. -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- +%% @doc emqttd main module. +%% @author Feng Lee -module(emqttd). --export([start/0, env/1, env/2, - start_listeners/0, stop_listeners/0, - load_all_mods/0, is_mod_enabled/1, - is_running/1, seed_now/0]). +-export([start/0, env/1, env/2, start_listeners/0, stop_listeners/0, + load_all_mods/0, is_mod_enabled/1, is_running/1]). %% Utility functions. --export([reg_name/2]). +-export([reg_name/2, seed_now/0]). -define(MQTT_SOCKOPTS, [ binary, @@ -45,86 +35,66 @@ -type listener() :: {atom(), inet:port_number(), [esockd:option()]}. -%%------------------------------------------------------------------------------ %% @doc Start emqttd application. -%% @end -%%------------------------------------------------------------------------------ -spec start() -> ok | {error, any()}. -start() -> - application:start(?APP). +start() -> application:start(?APP). + +%% @doc Group environment +-spec env(Group :: atom()) -> list(). +env(Group) -> application:get_env(?APP, Group, []). -%%------------------------------------------------------------------------------ %% @doc Get environment -%% @end -%%------------------------------------------------------------------------------ --spec env(atom()) -> list(). -env(Group) -> - application:get_env(?APP, Group, []). +-spec env(Group :: atom(), Name :: atom()) -> undefined | any(). +env(Group, Name) -> proplists:get_value(Name, env(Group)). --spec env(atom(), atom()) -> undefined | any(). -env(Group, Name) -> - proplists:get_value(Name, env(Group)). - -%%------------------------------------------------------------------------------ -%% @doc Start Listeners -%% @end -%%------------------------------------------------------------------------------ +%% @doc Start Listeners of the broker. -spec start_listeners() -> any(). -start_listeners() -> - {ok, Listeners} = application:get_env(?APP, listeners), - lists:foreach(fun start_listener/1, Listeners). +start_listeners() -> lists:foreach(fun start_listener/1, env(listeners)). %% Start mqtt listener -spec start_listener(listener()) -> any(). -start_listener({mqtt, Port, Options}) -> - start_listener(mqtt, Port, Options); +start_listener({mqtt, Port, Opts}) -> start_listener(mqtt, Port, Opts); %% Start mqtt(SSL) listener -start_listener({mqtts, Port, Options}) -> - start_listener(mqtts, Port, Options); +start_listener({mqtts, Port, Opts}) -> start_listener(mqtts, Port, Opts); %% Start http listener -start_listener({http, Port, Options}) -> - MFArgs = {emqttd_http, handle_request, []}, - mochiweb:start_http(Port, Options, MFArgs); +start_listener({http, Port, Opts}) -> + mochiweb:start_http(Port, Opts, {emqttd_http, handle_request, []}); %% Start https listener -start_listener({https, Port, Options}) -> - MFArgs = {emqttd_http, handle_request, []}, - mochiweb:start_http(Port, Options, MFArgs). +start_listener({https, Port, Opts}) -> + mochiweb:start_http(Port, Opts, {emqttd_http, handle_request, []}). -start_listener(Protocol, Port, Options) -> +start_listener(Protocol, Port, Opts) -> MFArgs = {emqttd_client, start_link, [env(mqtt)]}, - esockd:open(Protocol, Port, merge_sockopts(Options) , MFArgs). + esockd:open(Protocol, Port, merge_sockopts(Opts), MFArgs). merge_sockopts(Options) -> SockOpts = emqttd_opts:merge(?MQTT_SOCKOPTS, proplists:get_value(sockopts, Options, [])), emqttd_opts:merge(Options, [{sockopts, SockOpts}]). -%%------------------------------------------------------------------------------ %% @doc Stop Listeners -%% @end -%%------------------------------------------------------------------------------ -stop_listeners() -> - {ok, Listeners} = application:get_env(?APP, listeners), - lists:foreach(fun stop_listener/1, Listeners). +stop_listeners() -> lists:foreach(fun stop_listener/1, env(listeners)). -stop_listener({Protocol, Port, _Options}) -> - esockd:close({Protocol, Port}). +stop_listener({Protocol, Port, _Opts}) -> esockd:close({Protocol, Port}). +%% @doc load all modules load_all_mods() -> lists:foreach(fun load_mod/1, env(modules)). load_mod({Name, Opts}) -> Mod = list_to_atom("emqttd_mod_" ++ atom_to_list(Name)), case catch Mod:load(Opts) of - {ok, _State} -> lager:info("load module ~s successfully", [Name]); - {'EXIT', Reason} -> lager:error("load module ~s error: ~p", [Name, Reason]) + ok -> lager:info("Load module ~s successfully", [Name]); + {error, Error} -> lager:error("Load module ~s error: ~p", [Name, Error]); + {'EXIT', Reason} -> lager:error("Load module ~s error: ~p", [Name, Reason]) end. -is_mod_enabled(Name) -> - env(modules, Name) =/= undefined. +%% @doc Is module enabled? +-spec is_mod_enabled(Name :: atom()) -> boolean(). +is_mod_enabled(Name) -> env(modules, Name) =/= undefined. %% @doc Is running? -spec is_running(node()) -> boolean(). @@ -141,10 +111,7 @@ reg_name(M, Id) when is_atom(M), is_integer(Id) -> seed_now() -> case erlang:function_exported(erlang, timestamp, 0) of - true -> %% R18 - random:seed(erlang:timestamp()); - false -> - %% compress 'now()' warning... - random:seed(os:timestamp()) + true -> random:seed(erlang:timestamp()); %% R18 + false -> random:seed(os:timestamp()) %% compress 'now()' warning... end. diff --git a/src/emqttd_access_control.erl b/src/emqttd_access_control.erl index 2e43ee4db..ead1dc727 100644 --- a/src/emqttd_access_control.erl +++ b/src/emqttd_access_control.erl @@ -1,30 +1,24 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc Authentication and ACL Control Server -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Authentication and ACL Control. -module(emqttd_access_control). +-author("Feng Lee "). + -include("emqttd.hrl"). -behaviour(gen_server). @@ -47,27 +41,22 @@ -define(ACCESS_CONTROL_TAB, mqtt_access_control). -%%%============================================================================= -%%% API -%%%============================================================================= +-type password() :: undefined | binary(). -%%------------------------------------------------------------------------------ -%% @doc Start access control server -%% @end -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- + +%% @doc Start access control server. -spec start_link() -> {ok, pid()} | ignore | {error, any()}. -start_link() -> - start_link(emqttd:env(access)). +start_link() -> start_link(emqttd:env(access)). -spec start_link(Opts :: list()) -> {ok, pid()} | ignore | {error, any()}. start_link(Opts) -> gen_server:start_link({local, ?SERVER}, ?MODULE, [Opts], []). -%%------------------------------------------------------------------------------ -%% @doc Authenticate MQTT Client -%% @end -%%------------------------------------------------------------------------------ --spec auth(mqtt_client(), undefined | binary()) -> ok | {error, string()}. +%% @doc Authenticate MQTT Client. +-spec auth(Client :: mqtt_client(), Password :: password()) -> ok | {error, any()}. auth(Client, Password) when is_record(Client, mqtt_client) -> auth(Client, Password, lookup_mods(auth)). auth(_Client, _Password, []) -> @@ -80,41 +69,32 @@ auth(Client, Password, [{Mod, State, _Seq} | Mods]) -> {'EXIT', Error} -> {error, Error} end. -%%------------------------------------------------------------------------------ %% @doc Check ACL -%% @end -%%------------------------------------------------------------------------------ -spec check_acl(Client, PubSub, Topic) -> allow | deny when Client :: mqtt_client(), PubSub :: pubsub(), Topic :: binary(). check_acl(Client, PubSub, Topic) when ?IS_PUBSUB(PubSub) -> case lookup_mods(acl) of - [] -> allow; + [] -> allow; AclMods -> check_acl(Client, PubSub, Topic, AclMods) end. check_acl(#mqtt_client{client_id = ClientId}, PubSub, Topic, []) -> - lager:error("ACL: nomatch when ~s ~s ~s", [ClientId, PubSub, Topic]), + lager:error("ACL: nomatch for ~s ~s ~s", [ClientId, PubSub, Topic]), allow; -check_acl(Client, PubSub, Topic, [{M, State, _Seq}|AclMods]) -> - case M:check_acl({Client, PubSub, Topic}, State) of +check_acl(Client, PubSub, Topic, [{Mod, State, _Seq}|AclMods]) -> + case Mod:check_acl({Client, PubSub, Topic}, State) of allow -> allow; deny -> deny; ignore -> check_acl(Client, PubSub, Topic, AclMods) end. -%%------------------------------------------------------------------------------ -%% @doc Reload ACL -%% @end -%%------------------------------------------------------------------------------ --spec reload_acl() -> list() | {error, any()}. +%% @doc Reload ACL Rules. +-spec reload_acl() -> list(ok | {error, any()}). reload_acl() -> - [M:reload_acl(State) || {M, State, _Seq} <- lookup_mods(acl)]. + [Mod:reload_acl(State) || {Mod, State, _Seq} <- lookup_mods(acl)]. -%%------------------------------------------------------------------------------ -%% @doc Register authentication or ACL module -%% @end -%%------------------------------------------------------------------------------ +%% @doc Register Authentication or ACL module. -spec register_mod(auth | acl, atom(), list()) -> ok | {error, any()}. register_mod(Type, Mod, Opts) when Type =:= auth; Type =:= acl-> register_mod(Type, Mod, Opts, 0). @@ -123,38 +103,28 @@ register_mod(Type, Mod, Opts) when Type =:= auth; Type =:= acl-> register_mod(Type, Mod, Opts, Seq) when Type =:= auth; Type =:= acl-> gen_server:call(?SERVER, {register_mod, Type, Mod, Opts, Seq}). -%%------------------------------------------------------------------------------ %% @doc Unregister authentication or ACL module -%% @end -%%------------------------------------------------------------------------------ -spec unregister_mod(Type :: auth | acl, Mod :: atom()) -> ok | {error, any()}. unregister_mod(Type, Mod) when Type =:= auth; Type =:= acl -> gen_server:call(?SERVER, {unregister_mod, Type, Mod}). -%%------------------------------------------------------------------------------ -%% @doc Lookup authentication or ACL modules -%% @end -%%------------------------------------------------------------------------------ +%% @doc Lookup authentication or ACL modules. -spec lookup_mods(auth | acl) -> list(). lookup_mods(Type) -> case ets:lookup(?ACCESS_CONTROL_TAB, tab_key(Type)) of - [] -> []; + [] -> []; [{_, Mods}] -> Mods end. tab_key(auth) -> auth_modules; tab_key(acl) -> acl_modules. -%%------------------------------------------------------------------------------ -%% @doc Stop access control server -%% @end -%%------------------------------------------------------------------------------ -stop() -> - gen_server:call(?MODULE, stop). +%% @doc Stop access control server. +stop() -> gen_server:call(?MODULE, stop). -%%%============================================================================= -%%% gen_server callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% gen_server callbacks +%%-------------------------------------------------------------------- init([Opts]) -> ets:new(?ACCESS_CONTROL_TAB, [set, named_table, protected, {read_concurrency, true}]), @@ -164,48 +134,42 @@ init([Opts]) -> {ok, state}. init_mods(auth, AuthMods) -> - [init_mod(fun authmod/1, Name, Opts) || {Name, Opts} <- AuthMods]; + [init_mod(authmod(Name), Opts) || {Name, Opts} <- AuthMods]; init_mods(acl, AclMods) -> - [init_mod(fun aclmod/1, Name, Opts) || {Name, Opts} <- AclMods]. + [init_mod(aclmod(Name), Opts) || {Name, Opts} <- AclMods]. -init_mod(Fun, Name, Opts) -> - Module = Fun(Name), - {ok, State} = Module:init(Opts), - {Module, State, 0}. +init_mod(Mod, Opts) -> + {ok, State} = Mod:init(Opts), {Mod, State, 0}. handle_call({register_mod, Type, Mod, Opts, Seq}, _From, State) -> Mods = lookup_mods(Type), - Reply = - case lists:keyfind(Mod, 1, Mods) of - false -> - case catch Mod:init(Opts) of - {ok, ModState} -> - NewMods = - lists:sort(fun({_, _, Seq1}, {_, _, Seq2}) -> - Seq1 >= Seq2 - end, [{Mod, ModState, Seq} | Mods]), - ets:insert(?ACCESS_CONTROL_TAB, {tab_key(Type), NewMods}), - ok; - {'EXIT', Error} -> - lager:error("Access Control: register ~s error - ~p", [Mod, Error]), - {error, Error} - end; - _ -> - {error, existed} - end, - {reply, Reply, State}; + Existed = lists:keyfind(Mod, 1, Mods), + {reply, if_existed(Existed, fun() -> + case catch Mod:init(Opts) of + {ok, ModState} -> + NewMods = lists:sort(fun({_, _, Seq1}, {_, _, Seq2}) -> + Seq1 >= Seq2 + end, [{Mod, ModState, Seq} | Mods]), + ets:insert(?ACCESS_CONTROL_TAB, {tab_key(Type), NewMods}); + {error, Error} -> + lager:error("Access Control: register ~s error - ~p", [Mod, Error]), + {error, Error}; + {'EXIT', Reason} -> + lager:error("Access Control: register ~s EXIT, reason - ~p", [Mod, Reason]), + {error, Reason} + end + end), State}; handle_call({unregister_mod, Type, Mod}, _From, State) -> Mods = lookup_mods(Type), - Reply = case lists:keyfind(Mod, 1, Mods) of - false -> - {error, not_found}; - _ -> - ets:insert(?ACCESS_CONTROL_TAB, {tab_key(Type), lists:keydelete(Mod, 1, Mods)}), ok - end, - {reply, Reply, State}; + false -> + {reply, {error, not_found}, State}; + _ -> + ets:insert(?ACCESS_CONTROL_TAB, {tab_key(Type), lists:keydelete(Mod, 1, Mods)}), + {reply, ok, State} + end; handle_call(stop, _From, State) -> {stop, normal, ok, State}; @@ -226,9 +190,9 @@ terminate(_Reason, _State) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. -%%%============================================================================= -%%% Internal functions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- authmod(Name) when is_atom(Name) -> mod(emqttd_auth_, Name). @@ -239,3 +203,6 @@ aclmod(Name) when is_atom(Name) -> mod(Prefix, Name) -> list_to_atom(lists:concat([Prefix, Name])). +if_existed(false, Fun) -> Fun(); +if_existed(true, _Fun) -> {error, existed}. + diff --git a/src/emqttd_access_rule.erl b/src/emqttd_access_rule.erl index 4bcec1295..6527f3ec0 100644 --- a/src/emqttd_access_rule.erl +++ b/src/emqttd_access_rule.erl @@ -1,30 +1,24 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd ACL Rule -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%% ------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% ------------------------------------------------------------------- + +%% @doc Access Rule. -module(emqttd_access_rule). +-author("Feng Lee "). + -include("emqttd.hrl"). -type who() :: all | binary() | @@ -47,10 +41,7 @@ -define(ALLOW_DENY(A), ((A =:= allow) orelse (A =:= deny))). -%%------------------------------------------------------------------------------ -%% @doc Compile access rule -%% @end -%%------------------------------------------------------------------------------ +%% @doc Compile Access Rule. compile({A, all}) when ?ALLOW_DENY(A) -> {A, all}; @@ -96,10 +87,7 @@ bin(L) when is_list(L) -> bin(B) when is_binary(B) -> B. -%%------------------------------------------------------------------------------ -%% @doc Match rule -%% @end -%%------------------------------------------------------------------------------ +%% @doc Match Access Rule -spec match(mqtt_client(), topic(), rule()) -> {matched, allow} | {matched, deny} | nomatch. match(_Client, _Topic, {AllowDeny, all}) when (AllowDeny =:= allow) orelse (AllowDeny =:= deny) -> {matched, AllowDeny}; diff --git a/src/emqttd_acl_internal.erl b/src/emqttd_acl_internal.erl index e5c084bfc..2e9d959e5 100644 --- a/src/emqttd_acl_internal.erl +++ b/src/emqttd_acl_internal.erl @@ -1,30 +1,24 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc Internal ACL that load rules from etc/acl.config -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Internal ACL that load rules from etc/acl.config -module(emqttd_acl_internal). +-author("Feng Lee "). + -include("emqttd.hrl"). -export([all_rules/0]). @@ -38,14 +32,11 @@ -record(state, {acl_file, nomatch = allow}). -%%%============================================================================= -%%% API -%%%============================================================================= +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- -%%------------------------------------------------------------------------------ %% @doc Read all rules -%% @end -%%------------------------------------------------------------------------------ -spec all_rules() -> list(emqttd_access_rule:rule()). all_rules() -> case ets:lookup(?ACL_RULE_TAB, all_rules) of @@ -53,22 +44,21 @@ all_rules() -> [{_, Rules}] -> Rules end. -%%%============================================================================= -%%% ACL callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% ACL callbacks +%%-------------------------------------------------------------------- -%%------------------------------------------------------------------------------ %% @doc Init internal ACL -%% @end -%%------------------------------------------------------------------------------ -spec init(AclOpts :: list()) -> {ok, State :: any()}. init(AclOpts) -> ets:new(?ACL_RULE_TAB, [set, public, named_table, {read_concurrency, true}]), AclFile = proplists:get_value(file, AclOpts), Default = proplists:get_value(nomatch, AclOpts, allow), State = #state{acl_file = AclFile, nomatch = Default}, - load_rules_from_file(State), - {ok, State}. + case load_rules_from_file(State) of + ok -> {ok, State}; + {error, Error} -> {error, Error} + end. load_rules_from_file(#state{acl_file = AclFile}) -> {ok, Terms} = file:consult(AclFile), @@ -92,10 +82,7 @@ filter(subscribe, {_AllowDeny, _Who, subscribe, _Topics}) -> filter(_PubSub, {_AllowDeny, _Who, _, _Topics}) -> false. -%%------------------------------------------------------------------------------ %% @doc Check ACL -%% @end -%%------------------------------------------------------------------------------ -spec check_acl({Client, PubSub, Topic}, State) -> allow | deny | ignore when Client :: mqtt_client(), PubSub :: pubsub(), @@ -123,10 +110,7 @@ match(Client, Topic, [Rule|Rules]) -> {matched, AllowDeny} -> {matched, AllowDeny} end. -%%------------------------------------------------------------------------------ %% @doc Reload ACL -%% @end -%%------------------------------------------------------------------------------ -spec reload_acl(State :: #state{}) -> ok | {error, Reason :: any()}. reload_acl(State) -> case catch load_rules_from_file(State) of @@ -134,10 +118,7 @@ reload_acl(State) -> _ -> ok end. -%%------------------------------------------------------------------------------ %% @doc ACL Module Description -%% @end -%%------------------------------------------------------------------------------ -spec description() -> string(). description() -> "Internal ACL with etc/acl.config". diff --git a/src/emqttd_acl_mod.erl b/src/emqttd_acl_mod.erl index 58b0b616a..78b327c5e 100644 --- a/src/emqttd_acl_mod.erl +++ b/src/emqttd_acl_mod.erl @@ -1,35 +1,29 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc ACL module behaviour -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc ACL module behaviour. -module(emqttd_acl_mod). +-author("Feng Lee "). + -include("emqttd.hrl"). -%%%============================================================================= -%%% ACL behavihour -%%%============================================================================= +%%-------------------------------------------------------------------- +%% ACL behavihour +%%-------------------------------------------------------------------- -ifdef(use_specs). @@ -49,9 +43,9 @@ -export([behaviour_info/1]). behaviour_info(callbacks) -> - [{init, 1}, {check_acl, 2}, {reload_acl, 1}, {description, 0}]; + [{init, 1}, {check_acl, 2}, {reload_acl, 1}, {description, 0}]; behaviour_info(_Other) -> - undefined. + undefined. -endif. diff --git a/src/emqttd_alarm.erl b/src/emqttd_alarm.erl index b78265d38..4b07d514b 100644 --- a/src/emqttd_alarm.erl +++ b/src/emqttd_alarm.erl @@ -1,30 +1,24 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc Copy alarm_handler -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Copy alarm_handler -module(emqttd_alarm). +-author("Feng Lee "). + -include("emqttd.hrl"). -behaviour(gen_event). @@ -41,9 +35,9 @@ -export([init/1, handle_event/2, handle_call/2, handle_info/2, terminate/2, code_change/3]). -%%%============================================================================= -%%% API -%%%============================================================================= +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- start_link() -> start_with(fun(Pid) -> gen_event:add_handler(Pid, ?MODULE, []) end). @@ -54,8 +48,7 @@ start_with(Fun) -> Error -> Error end. -alarm_fun() -> - alarm_fun(false). +alarm_fun() -> alarm_fun(false). alarm_fun(Bool) -> fun(alert, _Alarm) when Bool =:= true -> alarm_fun(true); @@ -85,12 +78,11 @@ add_alarm_handler(Module, Args) when is_atom(Module) -> delete_alarm_handler(Module) when is_atom(Module) -> gen_event:delete_handler(?ALARM_MGR, Module, []). -%%%============================================================================= -%%% Default Alarm handler -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Default Alarm handler +%%-------------------------------------------------------------------- -init(_) -> - {ok, []}. +init(_) -> {ok, []}. handle_event({set_alarm, Alarm = #mqtt_alarm{id = AlarmId, severity = Severity, @@ -131,9 +123,9 @@ terminate(_, _) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. -%%%============================================================================= -%%% Internal functions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- alarm_msg(Type, AlarmId, Json) -> Msg = emqttd_message:make(alarm, diff --git a/src/emqttd_app.erl b/src/emqttd_app.erl index 899323a60..447c3fd3b 100644 --- a/src/emqttd_app.erl +++ b/src/emqttd_app.erl @@ -1,30 +1,24 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd application. -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd application. -module(emqttd_app). +-author("Feng Lee "). + -include("emqttd_cli.hrl"). -behaviour(application). @@ -32,9 +26,9 @@ %% Application callbacks -export([start/2, stop/1]). -%%%============================================================================= -%%% Application callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Application callbacks +%%-------------------------------------------------------------------- -spec start(StartType, StartArgs) -> {ok, pid()} | {ok, pid(), State} | {error, Reason} when StartType :: normal | {takeover, node()} | {failover, node()}, diff --git a/src/emqttd_auth_anonymous.erl b/src/emqttd_auth_anonymous.erl index bc845fe73..5799c28b1 100644 --- a/src/emqttd_auth_anonymous.erl +++ b/src/emqttd_auth_anonymous.erl @@ -1,30 +1,24 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc Anonymous Authentication Module -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Anonymous Authentication Module -module(emqttd_auth_anonymous). +-author("Feng Lee "). + -behaviour(emqttd_auth_mod). -export([init/1, check/3, description/0]). diff --git a/src/emqttd_auth_clientid.erl b/src/emqttd_auth_clientid.erl index de3c56658..dc6a3568b 100644 --- a/src/emqttd_auth_clientid.erl +++ b/src/emqttd_auth_clientid.erl @@ -1,34 +1,27 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc ClientId Authentication Module -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc ClientId Authentication Module. -module(emqttd_auth_clientid). +-author("Feng Lee "). + -include("emqttd.hrl"). --export([add_clientid/1, add_clientid/2, - lookup_clientid/1, remove_clientid/1, +-export([add_clientid/1, add_clientid/2, lookup_clientid/1, remove_clientid/1, all_clientids/0]). -behaviour(emqttd_auth_mod). @@ -40,87 +33,71 @@ -record(?AUTH_CLIENTID_TAB, {client_id, ipaddr, password}). -%%%============================================================================= -%%% API -%%%============================================================================= +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- -%%------------------------------------------------------------------------------ %% @doc Add clientid -%% @end -%%------------------------------------------------------------------------------ -spec add_clientid(binary()) -> {atomic, ok} | {aborted, any()}. add_clientid(ClientId) when is_binary(ClientId) -> R = #mqtt_auth_clientid{client_id = ClientId}, mnesia:transaction(fun mnesia:write/1, [R]). -%%------------------------------------------------------------------------------ %% @doc Add clientid with password -%% @end -%%------------------------------------------------------------------------------ -spec add_clientid(binary(), binary()) -> {atomic, ok} | {aborted, any()}. add_clientid(ClientId, Password) -> R = #mqtt_auth_clientid{client_id = ClientId, password = Password}, mnesia:transaction(fun mnesia:write/1, [R]). -%%------------------------------------------------------------------------------ %% @doc Lookup clientid -%% @end -%%------------------------------------------------------------------------------ --spec lookup_clientid(binary()) -> list(). +-spec lookup_clientid(binary()) -> list(#mqtt_auth_clientid{}). lookup_clientid(ClientId) -> mnesia:dirty_read(?AUTH_CLIENTID_TAB, ClientId). -%%------------------------------------------------------------------------------ %% @doc Lookup all clientids -%% @end -%%------------------------------------------------------------------------------ -spec all_clientids() -> list(binary()). -all_clientids() -> - mnesia:dirty_all_keys(?AUTH_CLIENTID_TAB). +all_clientids() -> mnesia:dirty_all_keys(?AUTH_CLIENTID_TAB). -%%------------------------------------------------------------------------------ %% @doc Remove clientid -%% @end -%%------------------------------------------------------------------------------ -spec remove_clientid(binary()) -> {atomic, ok} | {aborted, any()}. remove_clientid(ClientId) -> mnesia:transaction(fun mnesia:delete/1, [{?AUTH_CLIENTID_TAB, ClientId}]). -%%%============================================================================= -%%% emqttd_auth_mod callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% emqttd_auth_mod callbacks +%%-------------------------------------------------------------------- init(Opts) -> mnesia:create_table(?AUTH_CLIENTID_TAB, [ {ram_copies, [node()]}, {attributes, record_info(fields, ?AUTH_CLIENTID_TAB)}]), mnesia:add_table_copy(?AUTH_CLIENTID_TAB, node(), ram_copies), - case proplists:get_value(file, Opts) of - undefined -> ok; - File -> load(File) - end, + load(proplists:get_value(file, Opts)), {ok, Opts}. -check(#mqtt_client{client_id = undefined}, _Password, []) -> - {error, "ClientId undefined"}; +check(#mqtt_client{client_id = undefined}, _Password, _Opts) -> + {error, clientid_undefined}; check(#mqtt_client{client_id = ClientId, peername = {IpAddress, _}}, _Password, []) -> check_clientid_only(ClientId, IpAddress); check(#mqtt_client{client_id = ClientId, peername = {IpAddress, _}}, _Password, [{password, no}|_]) -> check_clientid_only(ClientId, IpAddress); check(_Client, undefined, [{password, yes}|_]) -> - {error, "Password undefined"}; + {error, password_undefined}; check(#mqtt_client{client_id = ClientId}, Password, [{password, yes}|_]) -> case mnesia:dirty_read(?AUTH_CLIENTID_TAB, ClientId) of - [] -> {error, "ClientId Not Found"}; + [] -> {error, clientid_not_found}; [#?AUTH_CLIENTID_TAB{password = Password}] -> ok; %% TODO: plaintext?? - _ -> {error, "Password Not Right"} + _ -> {error, password_error} end. description() -> "ClientId authentication module". -%%%============================================================================= -%%% Internal functions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- + +load(undefined) -> + ok; load(File) -> {ok, Fd} = file:open(File, [read]), @@ -149,13 +126,13 @@ load(Fd, eof, Clients) -> check_clientid_only(ClientId, IpAddr) -> case mnesia:dirty_read(?AUTH_CLIENTID_TAB, ClientId) of - [] -> {error, "ClientId Not Found"}; + [] -> {error, clientid_not_found}; [#?AUTH_CLIENTID_TAB{ipaddr = undefined}] -> ok; [#?AUTH_CLIENTID_TAB{ipaddr = {_, {Start, End}}}] -> I = esockd_access:atoi(IpAddr), case I >= Start andalso I =< End of - true -> ok; - false -> {error, "ClientId with wrong IP address"} + true -> ok; + false -> {error, wrong_ipaddr} end end. diff --git a/src/emqttd_auth_ldap.erl b/src/emqttd_auth_ldap.erl index 295831c3f..026d16fdb 100644 --- a/src/emqttd_auth_ldap.erl +++ b/src/emqttd_auth_ldap.erl @@ -1,30 +1,24 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc LDAP Authentication Module -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc LDAP Authentication Module -module(emqttd_auth_ldap). +-author("Feng Lee "). + -include("emqttd.hrl"). -import(proplists, [get_value/2, get_value/3]). @@ -51,11 +45,11 @@ init(Opts) -> {ok, #state{servers = Servers, user_dn = UserDn, options = LdapOpts}}. check(#mqtt_client{username = undefined}, _Password, _State) -> - {error, "Username undefined"}; + {error, username_undefined}; check(_Client, undefined, _State) -> - {error, "Password undefined"}; + {error, password_undefined}; check(_Client, <<>>, _State) -> - {error, "Password undefined"}; + {error, password_undefined}; check(#mqtt_client{username = Username}, Password, #state{servers = Servers, user_dn = UserDn, options = Options}) -> case eldap:open(Servers, Options) of @@ -71,7 +65,7 @@ ldap_bind(LDAP, UserDn, Password) -> ok -> ok; {error, invalidCredentials} -> - {error, "LDAP Invalid Credentials"}; + {error, invalid_credentials}; {error, Error} -> {error, Error}; {'EXIT', Reason} -> diff --git a/src/emqttd_auth_mod.erl b/src/emqttd_auth_mod.erl index 63bff64d5..801b45c27 100644 --- a/src/emqttd_auth_mod.erl +++ b/src/emqttd_auth_mod.erl @@ -1,39 +1,33 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd Authentication Behaviour -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Authentication Behaviour. -module(emqttd_auth_mod). +-author("Feng Lee "). + -include("emqttd.hrl"). -export([passwd_hash/2]). -type hash_type() :: plain | md5 | sha | sha256. -%%%============================================================================= -%%% Auth behavihour -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Authentication behavihour +%%-------------------------------------------------------------------- -ifdef(use_specs). diff --git a/src/emqttd_auth_username.erl b/src/emqttd_auth_username.erl index 0e4a52891..8da1fb6e0 100644 --- a/src/emqttd_auth_username.erl +++ b/src/emqttd_auth_username.erl @@ -1,30 +1,24 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc Authentication with username and password -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Authentication with username and password -module(emqttd_auth_username). +-author("Feng Lee "). + -include("emqttd.hrl"). -include("emqttd_cli.hrl"). @@ -44,63 +38,54 @@ -record(?AUTH_USERNAME_TAB, {username, password}). -%%%============================================================================= -%%% CLI -%%%============================================================================= +%%-------------------------------------------------------------------- +%% CLI +%%-------------------------------------------------------------------- cli(["add", Username, Password]) -> - ?PRINT("~p~n", [add_user(list_to_binary(Username), list_to_binary(Password))]); + ?PRINT("~p~n", [add_user(iolist_to_binary(Username), iolist_to_binary(Password))]); cli(["del", Username]) -> - ?PRINT("~p~n", [remove_user(list_to_binary(Username))]); + ?PRINT("~p~n", [remove_user(iolist_to_binary(Username))]); cli(_) -> - ?USAGE([{"users add ", "add user"}, - {"users del ", "delete user"}]). + ?USAGE([{"users add ", "Add User"}, + {"users del ", "Delete User"}]). -%%%============================================================================= -%%% API -%%%============================================================================= +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- -%%------------------------------------------------------------------------------ -%% @doc Add user -%% @end -%%------------------------------------------------------------------------------ --spec add_user(binary(), binary()) -> {atomic, ok} | {aborted, any()}. +%% @doc Add User +-spec add_user(binary(), binary()) -> ok | {error, any()}. add_user(Username, Password) -> User = #?AUTH_USERNAME_TAB{username = Username, password = hash(Password)}, - mnesia:transaction(fun mnesia:write/1, [User]). + ret(mnesia:transaction(fun mnesia:write/1, [User])). add_default_user(Username, Password) -> - add_user(bin(Username), bin(Password)). + add_user(iolist_to_binary(Username), iolist_to_binary(Password)). -%%------------------------------------------------------------------------------ %% @doc Lookup user by username -%% @end -%%------------------------------------------------------------------------------ -spec lookup_user(binary()) -> list(). lookup_user(Username) -> mnesia:dirty_read(?AUTH_USERNAME_TAB, Username). -%%------------------------------------------------------------------------------ %% @doc Remove user -%% @end -%%------------------------------------------------------------------------------ --spec remove_user(binary()) -> {atomic, ok} | {aborted, any()}. +-spec remove_user(binary()) -> ok | {error, any()}. remove_user(Username) -> - mnesia:transaction(fun mnesia:delete/1, [{?AUTH_USERNAME_TAB, Username}]). + ret(mnesia:transaction(fun mnesia:delete/1, [{?AUTH_USERNAME_TAB, Username}])). + +ret({atomic, ok}) -> ok; +ret({aborted, Error}) -> {error, Error}. -%%------------------------------------------------------------------------------ %% @doc All usernames -%% @end -%%------------------------------------------------------------------------------ -spec all_users() -> list(). -all_users() -> - mnesia:dirty_all_keys(?AUTH_USERNAME_TAB). +all_users() -> mnesia:dirty_all_keys(?AUTH_USERNAME_TAB). + +%%-------------------------------------------------------------------- +%% emqttd_auth_mod callbacks +%%-------------------------------------------------------------------- -%%%============================================================================= -%%% emqttd_auth callbacks -%%%============================================================================= init(DefautUsers) -> mnesia:create_table(?AUTH_USERNAME_TAB, [ {disc_copies, [node()]}, @@ -113,40 +98,33 @@ init(DefautUsers) -> {ok, []}. check(#mqtt_client{username = undefined}, _Password, _Opts) -> - {error, "Username undefined"}; + {error, username_undefined}; check(_User, undefined, _Opts) -> - {error, "Password undefined"}; + {error, password_undefined}; check(#mqtt_client{username = Username}, Password, _Opts) -> case mnesia:dirty_read(?AUTH_USERNAME_TAB, Username) of [] -> - {error, "Username Not Found"}; + {error, username_not_found}; [#?AUTH_USERNAME_TAB{password = <>}] -> case Hash =:= md5_hash(Salt, Password) of true -> ok; - false -> {error, "Password Not Right"} + false -> {error, password_error} end end. description() -> "Username password authentication module". -%%%============================================================================= -%%% Internal functions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- hash(Password) -> - SaltBin = salt(), - <>. + SaltBin = salt(), <>. md5_hash(SaltBin, Password) -> erlang:md5(<>). salt() -> - emqttd:seed_now(), - Salt = random:uniform(16#ffffffff), - <>. - -bin(A) when is_atom(A) -> bin(atom_to_list(A)); -bin(L) when is_list(L) -> list_to_binary(L); -bin(B) when is_binary(B) -> B. + emqttd:seed_now(), Salt = random:uniform(16#ffffffff), <>. diff --git a/src/emqttd_bridge.erl b/src/emqttd_bridge.erl index 80f0a405d..a0b56e639 100644 --- a/src/emqttd_bridge.erl +++ b/src/emqttd_bridge.erl @@ -1,30 +1,25 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd bridge -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd bridge +%% @author Feng Lee -module(emqttd_bridge). +-behaviour(gen_server2). + -include("emqttd.hrl"). -include("emqttd_protocol.hrl"). @@ -34,8 +29,6 @@ %% API Function Exports -export([start_link/3]). --behaviour(gen_server). - %% gen_server Function Exports -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). @@ -59,32 +52,29 @@ -export_type([option/0]). -%%%============================================================================= -%%% API -%%%============================================================================= +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- -%%------------------------------------------------------------------------------ %% @doc Start a bridge -%% @end -%%------------------------------------------------------------------------------ -spec start_link(atom(), binary(), [option()]) -> {ok, pid()} | ignore | {error, term()}. -start_link(Node, SubTopic, Options) -> - gen_server:start_link(?MODULE, [Node, SubTopic, Options], []). +start_link(Node, Topic, Options) -> + gen_server2:start_link(?MODULE, [Node, Topic, Options], []). -%%%============================================================================= -%%% gen_server callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% gen_server callbacks +%%-------------------------------------------------------------------- -init([Node, SubTopic, Options]) -> +init([Node, Topic, Options]) -> process_flag(trap_exit, true), case net_kernel:connect_node(Node) of true -> true = erlang:monitor_node(Node, true), - State = parse_opts(Options, #state{node = Node, subtopic = SubTopic}), - MQueue = emqttd_mqueue:new(qname(Node, SubTopic), + State = parse_opts(Options, #state{node = Node, subtopic = Topic}), + MQueue = emqttd_mqueue:new(qname(Node, Topic), [{max_len, State#state.max_queue_len}], emqttd_alarm:alarm_fun()), - emqttd_pubsub:subscribe({SubTopic, State#state.qos}), + emqttd_pubsub:subscribe({Topic, State#state.qos}), {ok, State#state{mqueue = MQueue}}; false -> {stop, {cannot_connect, Node}} @@ -105,10 +95,10 @@ parse_opts([{ping_down_interval, Interval} | Opts], State) -> parse_opts([_Opt | Opts], State) -> parse_opts(Opts, State). -qname(Node, SubTopic) when is_atom(Node) -> - qname(atom_to_list(Node), SubTopic); -qname(Node, SubTopic) -> - list_to_binary(["Bridge:", Node, ":", SubTopic]). +qname(Node, Topic) when is_atom(Node) -> + qname(atom_to_list(Node), Topic); +qname(Node, Topic) -> + iolist_to_binary(["Bridge:", Node, ":", Topic]). handle_call(Req, _From, State) -> ?UNEXPECTED_REQ(Req, State). @@ -163,9 +153,9 @@ terminate(_Reason, _State) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. -%%%============================================================================= -%%% Internal functions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- dequeue(State = #state{mqueue = MQ}) -> case emqttd_mqueue:out(MQ) of diff --git a/src/emqttd_bridge_sup.erl b/src/emqttd_bridge_sup.erl index a3e9be81b..e2933436d 100644 --- a/src/emqttd_bridge_sup.erl +++ b/src/emqttd_bridge_sup.erl @@ -1,103 +1,75 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc Bridge Supervisor -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Bridge Supervisor +%% @author Feng Lee -module(emqttd_bridge_sup). -behavior(supervisor). --export([start_link/0, - bridges/0, - start_bridge/2, start_bridge/3, - stop_bridge/2]). +-export([start_link/0, bridges/0, start_bridge/2, start_bridge/3, stop_bridge/2]). -export([init/1]). -%%%============================================================================= -%%% API -%%%============================================================================= +-define(BRIDGE_ID(Node, Topic), {bridge, Node, Topic}). + +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- -%%------------------------------------------------------------------------------ %% @doc Start bridge supervisor -%% @end -%%------------------------------------------------------------------------------ start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). -%%------------------------------------------------------------------------------ %% @doc List all bridges -%% @end -%%------------------------------------------------------------------------------ -spec bridges() -> [{tuple(), pid()}]. bridges() -> - [{{Node, SubTopic}, Pid} || {{bridge, Node, SubTopic}, Pid, worker, _} - <- supervisor:which_children(?MODULE)]. + [{{Node, Topic}, Pid} || {?BRIDGE_ID(Node, Topic), Pid, worker, _} + <- supervisor:which_children(?MODULE)]. -%%------------------------------------------------------------------------------ %% @doc Start a bridge -%% @end -%%------------------------------------------------------------------------------ -spec start_bridge(atom(), binary()) -> {ok, pid()} | {error, any()}. -start_bridge(Node, SubTopic) when is_atom(Node) and is_binary(SubTopic) -> - start_bridge(Node, SubTopic, []). +start_bridge(Node, Topic) when is_atom(Node) andalso is_binary(Topic) -> + start_bridge(Node, Topic, []). -spec start_bridge(atom(), binary(), [emqttd_bridge:option()]) -> {ok, pid()} | {error, any()}. -start_bridge(Node, SubTopic, Options) when is_atom(Node) and is_binary(SubTopic) -> - case Node =:= node() of - true -> - {error, bridge_to_self}; - false -> - Options1 = emqttd_opts:merge(emqttd_broker:env(bridge), Options), - supervisor:start_child(?MODULE, bridge_spec(Node, SubTopic, Options1)) - end. +start_bridge(Node, _Topic, _Options) when Node =:= node() -> + {error, bridge_to_self}; +start_bridge(Node, Topic, Options) when is_atom(Node) andalso is_binary(Topic) -> + Options1 = emqttd_opts:merge(emqttd_broker:env(bridge), Options), + supervisor:start_child(?MODULE, bridge_spec(Node, Topic, Options1)). -%%------------------------------------------------------------------------------ %% @doc Stop a bridge -%% @end -%%------------------------------------------------------------------------------ -spec stop_bridge(atom(), binary()) -> {ok, pid()} | ok. -stop_bridge(Node, SubTopic) -> - ChildId = bridge_id(Node, SubTopic), +stop_bridge(Node, Topic) when is_atom(Node) andalso is_binary(Topic) -> + ChildId = ?BRIDGE_ID(Node, Topic), case supervisor:terminate_child(?MODULE, ChildId) of - ok -> - supervisor:delete_child(?MODULE, ChildId); - {error, Reason} -> - {error, Reason} + ok -> supervisor:delete_child(?MODULE, ChildId); + {error, Reason} -> {error, Reason} end. -%%%============================================================================= -%%% Supervisor callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Supervisor callbacks +%%-------------------------------------------------------------------- init([]) -> {ok, {{one_for_one, 10, 100}, []}}. -bridge_id(Node, SubTopic) -> - {bridge, Node, SubTopic}. - -bridge_spec(Node, SubTopic, Options) -> - ChildId = bridge_id(Node, SubTopic), - {ChildId, {emqttd_bridge, start_link, [Node, SubTopic, Options]}, +bridge_spec(Node, Topic, Options) -> + ChildId = ?BRIDGE_ID(Node, Topic), + {ChildId, {emqttd_bridge, start_link, [Node, Topic, Options]}, transient, 10000, worker, [emqttd_bridge]}. diff --git a/src/emqttd_broker.erl b/src/emqttd_broker.erl index bc8eee732..f68a4deff 100644 --- a/src/emqttd_broker.erl +++ b/src/emqttd_broker.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd broker -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd broker +%% @author Feng Lee -module(emqttd_broker). -behaviour(gen_server). @@ -67,78 +60,51 @@ sysdescr % Broker description ]). -%%%============================================================================= -%%% API -%%%============================================================================= +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- -%%------------------------------------------------------------------------------ %% @doc Start emqttd broker -%% @end -%%------------------------------------------------------------------------------ -spec start_link() -> {ok, pid()} | ignore | {error, any()}. start_link() -> gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). -%%------------------------------------------------------------------------------ %% @doc Get running nodes -%% @end -%%------------------------------------------------------------------------------ -spec running_nodes() -> list(node()). running_nodes() -> mnesia:system_info(running_db_nodes). -%%------------------------------------------------------------------------------ %% @doc Subscribe broker event -%% @end -%%------------------------------------------------------------------------------ -spec subscribe(EventType :: any()) -> ok. subscribe(EventType) -> gproc:reg({p, l, {broker, EventType}}). -%%------------------------------------------------------------------------------ %% @doc Notify broker event -%% @end -%%------------------------------------------------------------------------------ -spec notify(EventType :: any(), Event :: any()) -> ok. notify(EventType, Event) -> Key = {broker, EventType}, gproc:send({p, l, Key}, {self(), Key, Event}). -%%------------------------------------------------------------------------------ %% @doc Get broker env -%% @end -%%------------------------------------------------------------------------------ env(Name) -> proplists:get_value(Name, emqttd:env(broker)). -%%------------------------------------------------------------------------------ %% @doc Get broker version -%% @end -%%------------------------------------------------------------------------------ -spec version() -> string(). version() -> {ok, Version} = application:get_key(emqttd, vsn), Version. -%%------------------------------------------------------------------------------ %% @doc Get broker description -%% @end -%%------------------------------------------------------------------------------ -spec sysdescr() -> string(). sysdescr() -> {ok, Descr} = application:get_key(emqttd, description), Descr. -%%------------------------------------------------------------------------------ %% @doc Get broker uptime -%% @end -%%------------------------------------------------------------------------------ -spec uptime() -> string(). uptime() -> gen_server:call(?SERVER, uptime). -%%------------------------------------------------------------------------------ %% @doc Get broker datetime -%% @end -%%------------------------------------------------------------------------------ -spec datetime() -> string(). datetime() -> {{Y, M, D}, {H, MM, S}} = calendar:local_time(), @@ -146,26 +112,17 @@ datetime() -> io_lib:format( "~4..0w-~2..0w-~2..0w ~2..0w:~2..0w:~2..0w", [Y, M, D, H, MM, S])). -%%------------------------------------------------------------------------------ %% @doc Hook -%% @end -%%------------------------------------------------------------------------------ -spec hook(Hook :: atom(), Name :: any(), MFA :: mfa()) -> ok | {error, any()}. hook(Hook, Name, MFA) -> gen_server:call(?SERVER, {hook, Hook, Name, MFA}). -%%------------------------------------------------------------------------------ %% @doc Unhook -%% @end -%%------------------------------------------------------------------------------ -spec unhook(Hook :: atom(), Name :: any()) -> ok | {error, any()}. unhook(Hook, Name) -> gen_server:call(?SERVER, {unhook, Hook, Name}). -%%------------------------------------------------------------------------------ %% @doc Foreach hooks -%% @end -%%------------------------------------------------------------------------------ -spec foreach_hooks(Hook :: atom(), Args :: list()) -> any(). foreach_hooks(Hook, Args) -> case ets:lookup(?BROKER_TAB, {hook, Hook}) of @@ -177,10 +134,7 @@ foreach_hooks(Hook, Args) -> ok end. -%%------------------------------------------------------------------------------ %% @doc Foldl hooks -%% @end -%%------------------------------------------------------------------------------ -spec foldl_hooks(Hook :: atom(), Args :: list(), Acc0 :: any()) -> any(). foldl_hooks(Hook, Args, Acc0) -> case ets:lookup(?BROKER_TAB, {hook, Hook}) of @@ -192,10 +146,7 @@ foldl_hooks(Hook, Args, Acc0) -> Acc0 end. -%%------------------------------------------------------------------------------ %% @doc Start a tick timer -%% @end -%%------------------------------------------------------------------------------ start_tick(Msg) -> start_tick(timer:seconds(env(sys_interval)), Msg). @@ -204,18 +155,15 @@ start_tick(0, _Msg) -> start_tick(Interval, Msg) when Interval > 0 -> {ok, TRef} = timer:send_interval(Interval, Msg), TRef. -%%------------------------------------------------------------------------------ %% @doc Start tick timer -%% @end -%%------------------------------------------------------------------------------ stop_tick(undefined) -> ok; stop_tick(TRef) -> timer:cancel(TRef). -%%%============================================================================= -%%% gen_server callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% gen_server callbacks +%%-------------------------------------------------------------------- init([]) -> emqttd:seed_now(), @@ -284,9 +232,9 @@ terminate(_Reason, #state{heartbeat = Hb, tick_tref = TRef}) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. -%%%============================================================================= -%%% Internal functions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- create_topic(Topic) -> emqttd_pubsub:create(topic, emqttd_topic:systop(Topic)). diff --git a/src/emqttd_cli.erl b/src/emqttd_cli.erl index 724227eec..284584704 100644 --- a/src/emqttd_cli.erl +++ b/src/emqttd_cli.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd cli -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd cli +%% @author Feng Lee -module(emqttd_cli). -include("emqttd.hrl"). @@ -60,14 +53,12 @@ load() -> is_cmd(Fun) -> not lists:member(Fun, [init, load, module_info]). -%%%============================================================================= -%%% Commands -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Commands +%%-------------------------------------------------------------------- -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% @doc Node status -%% @end -%%------------------------------------------------------------------------------ status([]) -> {InternalStatus, _ProvidedStatus} = init:get_status(), ?PRINT("Node ~p is ~p~n", [node(), InternalStatus]), @@ -80,10 +71,8 @@ status([]) -> status(_) -> ?PRINT_CMD("status", "query broker status"). -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% @doc Query broker -%% @end -%%------------------------------------------------------------------------------ broker([]) -> Funs = [sysdescr, version, uptime, datetime], foreach(fun(Fun) -> @@ -116,10 +105,8 @@ broker(_) -> {"broker stats", "query broker statistics of clients, topics, subscribers"}, {"broker metrics", "query broker metrics"}]). -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% @doc Cluster with other node -%% @end -%%------------------------------------------------------------------------------ cluster([]) -> Nodes = emqttd_broker:running_nodes(), ?PRINT("cluster nodes: ~p~n", [Nodes]); @@ -165,10 +152,8 @@ stop_apps() -> start_apps() -> [application:start(App) || App <- [gproc, esockd, emqttd]]. -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% @doc Query clients -%% @end -%%------------------------------------------------------------------------------ clients(["list"]) -> emqttd_mnesia:dump(ets, mqtt_client, fun print/1); @@ -189,10 +174,8 @@ if_client(ClientId, Fun) -> Client -> Fun(Client) end. -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% @doc Sessions Command -%% @end -%%------------------------------------------------------------------------------ sessions(["list"]) -> [sessions(["list", Type]) || Type <- ["persistent", "transient"]]; @@ -220,10 +203,8 @@ sessions(_) -> {"sessions list transient", "list all transient sessions"}, {"sessions show ", "show a session"}]). -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% @doc Topics Command -%% @end -%%------------------------------------------------------------------------------ topics(["list"]) -> Print = fun(Topic, Records) -> print(topic, Topic, Records) end, if_could_print(topic, Print); @@ -316,11 +297,8 @@ plugins(_) -> {"plugins load ", "load plugin"}, {"plugins unload ", "unload plugin"}]). -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% @doc Bridges command -%% @end -%%------------------------------------------------------------------------------ - bridges(["list"]) -> foreach(fun({{Node, Topic}, _Pid}) -> ?PRINT("bridge: ~s--~s-->~s~n", [node(), Topic, Node]) @@ -376,10 +354,8 @@ parse_opt(bridge, queue, Len) -> parse_opt(_Cmd, Opt, _Val) -> ?PRINT("Bad Option: ~s~n", [Opt]). -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% @doc vm command -%% @end -%%------------------------------------------------------------------------------ vm([]) -> vm(["all"]); @@ -410,20 +386,16 @@ vm(_) -> {"vm process", "query process of erlang vm"}, {"vm io", "queue io of erlang vm"}]). -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% @doc mnesia Command -%% @end -%%------------------------------------------------------------------------------ mnesia([]) -> mnesia:system_info(); mnesia(_) -> ?PRINT_CMD("mnesia", "mnesia system info"). -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% @doc Trace Command -%% @end -%%------------------------------------------------------------------------------ trace(["list"]) -> foreach(fun({{Who, Name}, LogFile}) -> ?PRINT("trace ~s ~s -> ~s~n", [Who, Name, LogFile]) @@ -464,10 +436,8 @@ trace_off(Who, Name) -> ?PRINT("stop to trace ~s ~s error: ~p.~n", [Who, Name, Error]) end. -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% @doc Listeners Command -%% @end -%%------------------------------------------------------------------------------ listeners([]) -> foreach(fun({{Protocol, Port}, Pid}) -> Info = [{acceptors, esockd:get_acceptors(Pid)}, @@ -531,6 +501,5 @@ format(subscriptions, List) -> format(_, Val) -> Val. -bin(S) when is_list(S) -> list_to_binary(S); -bin(B) when is_binary(B) -> B. +bin(S) -> iolist_to_binary(S). diff --git a/src/emqttd_client.erl b/src/emqttd_client.erl index 141d18b8c..3b15ad510 100644 --- a/src/emqttd_client.erl +++ b/src/emqttd_client.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc MQTT Client Connection -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc MQTT Client Connection +%% @author Feng Lee -module(emqttd_client). -behaviour(gen_server). @@ -228,9 +221,9 @@ terminate(Reason, #client_state{connection = Connection, code_change(_OldVsn, State, _Extra) -> {ok, State}. -%%%============================================================================= -%%% Internal functions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- with_proto_state(Fun, State = #client_state{proto_state = ProtoState}) -> {ok, ProtoState1} = Fun(ProtoState), diff --git a/src/emqttd_cm.erl b/src/emqttd_cm.erl index 76a344824..f76fd869b 100644 --- a/src/emqttd_cm.erl +++ b/src/emqttd_cm.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc MQTT Client Manager -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc MQTT Client Manager +%% @author Feng Lee -module(emqttd_cm). -include("emqttd.hrl"). @@ -47,14 +40,11 @@ -define(POOL, ?MODULE). -%%%============================================================================= -%%% API -%%%============================================================================= +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- -%%------------------------------------------------------------------------------ %% @doc Start Client Manager -%% @end -%%------------------------------------------------------------------------------ -spec start_link(Pool, Id, StatsFun) -> {ok, pid()} | ignore | {error, any()} when Pool :: atom(), Id :: pos_integer(), @@ -62,10 +52,7 @@ start_link(Pool, Id, StatsFun) -> gen_server2:start_link(?MODULE, [Pool, Id, StatsFun], []). -%%------------------------------------------------------------------------------ %% @doc Lookup Client by ClientId -%% @end -%%------------------------------------------------------------------------------ -spec lookup(ClientId :: binary()) -> mqtt_client() | undefined. lookup(ClientId) when is_binary(ClientId) -> case ets:lookup(mqtt_client, ClientId) of @@ -73,10 +60,7 @@ lookup(ClientId) when is_binary(ClientId) -> [] -> undefined end. -%%------------------------------------------------------------------------------ %% @doc Lookup client pid by clientId -%% @end -%%------------------------------------------------------------------------------ -spec lookup_proc(ClientId :: binary()) -> pid() | undefined. lookup_proc(ClientId) when is_binary(ClientId) -> try ets:lookup_element(mqtt_client, ClientId, #mqtt_client.client_pid) @@ -84,27 +68,21 @@ lookup_proc(ClientId) when is_binary(ClientId) -> error:badarg -> undefined end. -%%------------------------------------------------------------------------------ %% @doc Register ClientId with Pid. -%% @end -%%------------------------------------------------------------------------------ -spec register(Client :: mqtt_client()) -> ok. register(Client = #mqtt_client{client_id = ClientId}) -> CmPid = gproc_pool:pick_worker(?POOL, ClientId), gen_server2:cast(CmPid, {register, Client}). -%%------------------------------------------------------------------------------ %% @doc Unregister clientId with pid. -%% @end -%%------------------------------------------------------------------------------ -spec unregister(ClientId :: binary()) -> ok. unregister(ClientId) when is_binary(ClientId) -> CmPid = gproc_pool:pick_worker(?POOL, ClientId), gen_server2:cast(CmPid, {unregister, ClientId, self()}). -%%%============================================================================= -%%% gen_server callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% gen_server callbacks +%%-------------------------------------------------------------------- init([Pool, Id, StatsFun]) -> ?GPROC_POOL(join, Pool, Id), @@ -174,9 +152,9 @@ terminate(_Reason, #state{pool = Pool, id = Id}) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. -%%%============================================================================= -%%% Internal functions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- monitor_client(ClientId, Pid, State = #state{monitors = Monitors}) -> MRef = erlang:monitor(process, Pid), diff --git a/src/emqttd_cm_sup.erl b/src/emqttd_cm_sup.erl index 78ead23b2..05c86c529 100644 --- a/src/emqttd_cm_sup.erl +++ b/src/emqttd_cm_sup.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc Client Manager Supervisor. -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Client Manager Supervisor. +%% @author Feng Lee -module(emqttd_cm_sup). -behaviour(supervisor). diff --git a/src/emqttd_ctl.erl b/src/emqttd_ctl.erl index acf2fc522..6a49932b0 100644 --- a/src/emqttd_ctl.erl +++ b/src/emqttd_ctl.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd control -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd control +%% @author Feng Lee -module(emqttd_ctl). -behaviour(gen_server). @@ -47,36 +40,26 @@ -define(CMD_TAB, mqttd_ctl_cmd). -%%%============================================================================= -%%% API -%%%============================================================================= +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- start_link() -> gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). -%%------------------------------------------------------------------------------ %% @doc Register a command -%% @end -%%------------------------------------------------------------------------------ -spec register_cmd(atom(), {module(), atom()}, list()) -> ok. register_cmd(Cmd, MF, Opts) -> cast({register_cmd, Cmd, MF, Opts}). -%%------------------------------------------------------------------------------ %% @doc Unregister a command -%% @end -%%------------------------------------------------------------------------------ -spec unregister_cmd(atom()) -> ok. unregister_cmd(Cmd) -> cast({unregister_cmd, Cmd}). -cast(Msg) -> - gen_server:cast(?SERVER, Msg). +cast(Msg) -> gen_server:cast(?SERVER, Msg). -%%------------------------------------------------------------------------------ %% @doc Run a command -%% @end -%%------------------------------------------------------------------------------ run([]) -> usage(); run(["help"]) -> usage(); @@ -88,18 +71,15 @@ run([CmdS|Args]) -> [] -> usage() end. -%%------------------------------------------------------------------------------ %% @doc Usage -%% @end -%%------------------------------------------------------------------------------ usage() -> ?PRINT("Usage: ~s~n", [?MODULE]), [begin ?PRINT("~80..-s~n", [""]), Mod:Cmd(usage) end || {_, {Mod, Cmd}, _} <- ets:tab2list(?CMD_TAB)]. -%%%============================================================================= -%%% gen_server callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% gen_server callbacks +%%-------------------------------------------------------------------- init([]) -> ets:new(?CMD_TAB, [ordered_set, named_table, protected]), @@ -134,9 +114,9 @@ terminate(_Reason, _State) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. -%%%============================================================================= -%%% Internal Function Definitions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Internal Function Definitions +%%-------------------------------------------------------------------- noreply(State) -> {noreply, State, hibernate}. @@ -144,4 +124,3 @@ noreply(State) -> next_seq(State = #state{seq = Seq}) -> State#state{seq = Seq + 1}. - diff --git a/src/emqttd_dist.erl b/src/emqttd_dist.erl index 55c9a3a94..980781b08 100644 --- a/src/emqttd_dist.erl +++ b/src/emqttd_dist.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd distribution functions -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd distribution functions +%% @author Feng Lee -module(emqttd_dist). -import(lists, [concat/1]). diff --git a/src/emqttd_gen_mod.erl b/src/emqttd_gen_mod.erl index 625915450..7201533b3 100644 --- a/src/emqttd_gen_mod.erl +++ b/src/emqttd_gen_mod.erl @@ -1,35 +1,28 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd gen_mod behaviour -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd gen_mod behaviour +%% @author Feng Lee -module(emqttd_gen_mod). -include("emqttd.hrl"). -ifdef(use_specs). --callback load(Opts :: any()) -> {ok, State :: any()}. +-callback load(Opts :: any()) -> ok | {error, any()}. -callback unload(State :: any()) -> any(). diff --git a/src/emqttd_guid.erl b/src/emqttd_guid.erl index b73f480b2..e2540a668 100644 --- a/src/emqttd_guid.erl +++ b/src/emqttd_guid.erl @@ -1,42 +1,34 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc -%%% -%%% Generate global unique id for mqtt message. -%%% -%%% -------------------------------------------------------- -%%% | Timestamp | NodeID + PID | Sequence | -%%% |<------- 64bits ------->|<--- 48bits --->|<- 16bits ->| -%%% -------------------------------------------------------- -%%% -%%% 1. Timestamp: erlang:system_time if Erlang >= R18, otherwise os:timestamp -%%% 2. NodeId: encode node() to 2 bytes integer -%%% 3. Pid: encode pid to 4 bytes integer -%%% 4. Sequence: 2 bytes sequence in one process -%%% -%%% @end -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Generate global unique id for mqtt message. +%% +%% -------------------------------------------------------- +%% | Timestamp | NodeID + PID | Sequence | +%% |<------- 64bits ------->|<--- 48bits --->|<- 16bits ->| +%% -------------------------------------------------------- +%% +%% 1. Timestamp: erlang:system_time if Erlang >= R18, otherwise os:timestamp +%% 2. NodeId: encode node() to 2 bytes integer +%% 3. Pid: encode pid to 4 bytes integer +%% 4. Sequence: 2 bytes sequence in one process +%% +%% @end +%% +%% @author Feng Lee -module(emqttd_guid). -export([gen/0, new/0, timestamp/1]). @@ -45,10 +37,7 @@ -type guid() :: <<_:128>>. -%%------------------------------------------------------------------------------ %% @doc Generate a global unique id. -%% @end -%%------------------------------------------------------------------------------ -spec gen() -> guid(). gen() -> Guid = case get(guid) of diff --git a/src/emqttd_http.erl b/src/emqttd_http.erl index 3b233a8e2..60a7c30d7 100644 --- a/src/emqttd_http.erl +++ b/src/emqttd_http.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd http publish API and websocket client. -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd http publish API and websocket client. +%% @author Feng Lee -module(emqttd_http). -include("emqttd.hrl"). @@ -47,9 +40,10 @@ handle_request('GET', "/status", Req) -> [node(), InternalStatus, AppStatus]), Req:ok({"text/plain", iolist_to_binary(Status)}); -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% HTTP Publish API -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- + handle_request('POST', "/mqtt/publish", Req) -> Params = mochiweb_request:parse_post(Req), lager:info("HTTP Publish: ~p", [Params]), @@ -74,9 +68,9 @@ handle_request('POST', "/mqtt/publish", Req) -> Req:respond({401, [], <<"Fobbiden">>}) end; -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% MQTT Over WebSocket -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- handle_request('GET', "/mqtt", Req) -> lager:info("WebSocket Connection from: ~s", [Req:get(peer)]), Upgrade = Req:get_header_value("Upgrade"), @@ -92,9 +86,10 @@ handle_request('GET', "/mqtt", Req) -> Req:respond({400, [], <<"Bad WebSocket Protocol">>}) end; -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% Get static files -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- + handle_request('GET', "/" ++ File, Req) -> lager:info("HTTP GET File: ~s", [File]), mochiweb_request:serve_file(File, docroot(), Req); @@ -103,9 +98,9 @@ handle_request(Method, Path, Req) -> lager:error("Unexpected HTTP Request: ~s ~s", [Method, Path]), Req:not_found(). -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% basic authorization -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- authorized(Req) -> case Req:get_header_value("Authorization") of undefined -> diff --git a/src/emqttd_keepalive.erl b/src/emqttd_keepalive.erl index b27660bb0..2154d96c5 100644 --- a/src/emqttd_keepalive.erl +++ b/src/emqttd_keepalive.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc client keepalive -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc client keepalive +%% @author Feng Lee -module(emqttd_keepalive). -export([start/3, check/1, cancel/1]). @@ -33,10 +26,7 @@ -type keepalive() :: #keepalive{}. -%%------------------------------------------------------------------------------ %% @doc Start a keepalive -%% @end -%%------------------------------------------------------------------------------ -spec start(fun(), integer(), any()) -> undefined | keepalive(). start(_, 0, _) -> undefined; @@ -46,10 +36,7 @@ start(StatFun, TimeoutSec, TimeoutMsg) -> tsec = TimeoutSec, tmsg = TimeoutMsg, tref = timer(TimeoutSec, TimeoutMsg)}. -%%------------------------------------------------------------------------------ %% @doc Check keepalive, called when timeout. -%% @end -%%------------------------------------------------------------------------------ -spec check(keepalive()) -> {ok, keepalive()} | {error, any()}. check(KeepAlive = #keepalive{statfun = StatFun, statval = LastVal, repeat = Repeat}) -> case StatFun() of @@ -68,10 +55,7 @@ check(KeepAlive = #keepalive{statfun = StatFun, statval = LastVal, repeat = Repe resume(KeepAlive = #keepalive{tsec = TimeoutSec, tmsg = TimeoutMsg}) -> KeepAlive#keepalive{tref = timer(TimeoutSec, TimeoutMsg)}. -%%------------------------------------------------------------------------------ %% @doc Cancel Keepalive -%% @end -%%------------------------------------------------------------------------------ -spec cancel(keepalive()) -> ok. cancel(#keepalive{tref = TRef}) -> cancel(TRef); diff --git a/src/emqttd_log.erl b/src/emqttd_log.erl deleted file mode 100644 index 76382b986..000000000 --- a/src/emqttd_log.erl +++ /dev/null @@ -1,33 +0,0 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc -%%% emqttd log trace. -%%% -%%% @end -%%%----------------------------------------------------------------------------- - -%% TODO: issue #103 -%% 0.12.0 ??? - --module(emqttd_log). - -%%TODO: Hooks to log??? diff --git a/src/emqttd_message.erl b/src/emqttd_message.erl index 344a3901d..80583113f 100644 --- a/src/emqttd_message.erl +++ b/src/emqttd_message.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc MQTT Message Functions -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc MQTT Message Functions +%% @author Feng Lee -module(emqttd_message). -include("emqttd.hrl"). @@ -35,10 +28,7 @@ -export([format/1]). -%%------------------------------------------------------------------------------ %% @doc Make a message -%% @end -%%------------------------------------------------------------------------------ -spec make(From, Topic, Payload) -> mqtt_message() when From :: atom() | binary(), Topic :: binary(), @@ -62,10 +52,7 @@ make(From, Qos, Topic, Payload) -> payload = Payload, timestamp = os:timestamp()}. -%%------------------------------------------------------------------------------ %% @doc Message from Packet -%% @end -%%------------------------------------------------------------------------------ -spec from_packet(mqtt_packet()) -> mqtt_message(). from_packet(#mqtt_packet{header = #mqtt_packet_header{type = ?PUBLISH, retain = Retain, @@ -106,10 +93,7 @@ msgid(?QOS_0) -> msgid(Qos) when Qos =:= ?QOS_1 orelse Qos =:= ?QOS_2 -> emqttd_guid:gen(). -%%------------------------------------------------------------------------------ %% @doc Message to packet -%% @end -%%------------------------------------------------------------------------------ -spec to_packet(mqtt_message()) -> mqtt_packet(). to_packet(#mqtt_message{pktid = PkgId, qos = Qos, @@ -130,10 +114,7 @@ to_packet(#mqtt_message{pktid = PkgId, }, payload = Payload}. -%%------------------------------------------------------------------------------ %% @doc set dup, retain flag -%% @end -%%------------------------------------------------------------------------------ -spec set_flag(mqtt_message()) -> mqtt_message(). set_flag(Msg) -> Msg#mqtt_message{dup = true, retain = true}. @@ -147,10 +128,7 @@ set_flag(retain, Msg = #mqtt_message{retain = false}) -> Msg#mqtt_message{retain = true}; set_flag(Flag, Msg) when Flag =:= dup orelse Flag =:= retain -> Msg. -%%------------------------------------------------------------------------------ %% @doc Unset dup, retain flag -%% @end -%%------------------------------------------------------------------------------ -spec unset_flag(mqtt_message()) -> mqtt_message(). unset_flag(Msg) -> Msg#mqtt_message{dup = false, retain = false}. @@ -162,10 +140,7 @@ unset_flag(retain, Msg = #mqtt_message{retain = true}) -> Msg#mqtt_message{retain = false}; unset_flag(Flag, Msg) when Flag =:= dup orelse Flag =:= retain -> Msg. -%%------------------------------------------------------------------------------ %% @doc Format MQTT Message -%% @end -%%------------------------------------------------------------------------------ format(#mqtt_message{msgid = MsgId, pktid = PktId, from = From, qos = Qos, retain = Retain, dup = Dup, topic =Topic}) -> io_lib:format("Message(Q~p, R~p, D~p, MsgId=~p, PktId=~p, From=~s, Topic=~s)", diff --git a/src/emqttd_metrics.erl b/src/emqttd_metrics.erl index 5e0d1d02e..7c3e5720d 100644 --- a/src/emqttd_metrics.erl +++ b/src/emqttd_metrics.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd metrics. responsible for collecting broker metrics -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd metrics. responsible for collecting broker metrics +%% @author Feng Lee -module(emqttd_metrics). -behaviour(gen_server). @@ -97,22 +90,16 @@ {counter, 'messages/dropped'} % Messages dropped ]). -%%%============================================================================= -%%% API -%%%============================================================================= +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- -%%------------------------------------------------------------------------------ %% @doc Start metrics server -%% @end -%%------------------------------------------------------------------------------ -spec start_link() -> {ok, pid()} | ignore | {error, any()}. start_link() -> gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). -%%------------------------------------------------------------------------------ %% @doc Count packets received. -%% @end -%%------------------------------------------------------------------------------ -spec received(mqtt_packet()) -> ok. received(Packet) -> inc('packets/received'), @@ -150,10 +137,7 @@ qos_received(?QOS_1) -> qos_received(?QOS_2) -> inc('messages/qos2/received'). -%%------------------------------------------------------------------------------ %% @doc Count packets received. Will not count $SYS PUBLISH. -%% @end -%%------------------------------------------------------------------------------ -spec sent(mqtt_packet()) -> ok. sent(?PUBLISH_PACKET(_Qos, <<"$SYS/", _/binary>>, _, _)) -> ignore; @@ -191,10 +175,7 @@ qos_sent(?QOS_1) -> qos_sent(?QOS_2) -> inc('messages/qos2/sent'). -%%------------------------------------------------------------------------------ %% @doc Get all metrics -%% @end -%%------------------------------------------------------------------------------ -spec all() -> [{atom(), non_neg_integer()}]. all() -> maps:to_list( @@ -206,26 +187,17 @@ all() -> end end, #{}, ?METRIC_TAB)). -%%------------------------------------------------------------------------------ %% @doc Get metric value -%% @end -%%------------------------------------------------------------------------------ -spec value(atom()) -> non_neg_integer(). value(Metric) -> lists:sum(ets:select(?METRIC_TAB, [{{{Metric, '_'}, '$1'}, [], ['$1']}])). -%%------------------------------------------------------------------------------ %% @doc Increase counter -%% @end -%%------------------------------------------------------------------------------ -spec inc(atom()) -> non_neg_integer(). inc(Metric) -> inc(counter, Metric, 1). -%%------------------------------------------------------------------------------ %% @doc Increase metric value -%% @end -%%------------------------------------------------------------------------------ -spec inc({counter | gauge, atom()} | atom(), pos_integer()) -> non_neg_integer(). inc({gauge, Metric}, Val) -> inc(gauge, Metric, Val); @@ -234,53 +206,38 @@ inc({counter, Metric}, Val) -> inc(Metric, Val) when is_atom(Metric) -> inc(counter, Metric, Val). -%%------------------------------------------------------------------------------ %% @doc Increase metric value -%% @end -%%------------------------------------------------------------------------------ -spec inc(counter | gauge, atom(), pos_integer()) -> pos_integer(). inc(gauge, Metric, Val) -> ets:update_counter(?METRIC_TAB, key(gauge, Metric), {2, Val}); inc(counter, Metric, Val) -> ets:update_counter(?METRIC_TAB, key(counter, Metric), {2, Val}). -%%------------------------------------------------------------------------------ %% @doc Decrease metric value -%% @end -%%------------------------------------------------------------------------------ -spec dec(gauge, atom()) -> integer(). dec(gauge, Metric) -> dec(gauge, Metric, 1). -%%------------------------------------------------------------------------------ %% @doc Decrease metric value -%% @end -%%------------------------------------------------------------------------------ -spec dec(gauge, atom(), pos_integer()) -> integer(). dec(gauge, Metric, Val) -> ets:update_counter(?METRIC_TAB, key(gauge, Metric), {2, -Val}). -%%------------------------------------------------------------------------------ %% @doc Set metric value -%% @end -%%------------------------------------------------------------------------------ set(Metric, Val) when is_atom(Metric) -> set(gauge, Metric, Val). set(gauge, Metric, Val) -> ets:insert(?METRIC_TAB, {key(gauge, Metric), Val}). -%%------------------------------------------------------------------------------ %% @doc Metric Key -%% @end -%%------------------------------------------------------------------------------ key(gauge, Metric) -> {Metric, 0}; key(counter, Metric) -> {Metric, erlang:system_info(scheduler_id)}. -%%%============================================================================= -%%% gen_server callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% gen_server callbacks +%%-------------------------------------------------------------------- init([]) -> emqttd:seed_now(), @@ -314,9 +271,9 @@ terminate(_Reason, #state{tick_tref = TRef}) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. -%%%============================================================================= -%%% Internal functions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- publish(Metric, Val) -> Payload = emqttd_util:integer_to_binary(Val), diff --git a/src/emqttd_mnesia.erl b/src/emqttd_mnesia.erl index 1d98df319..e2813a508 100644 --- a/src/emqttd_mnesia.erl +++ b/src/emqttd_mnesia.erl @@ -1,28 +1,22 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd mnesia -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% TODO: refactor this module +%% @doc emqttd mnesia +%% @author Feng Lee -module(emqttd_mnesia). -include("emqttd.hrl"). @@ -46,13 +40,8 @@ start() -> init_tables(), wait_for_tables(). -%%------------------------------------------------------------------------------ -%% @doc %% @private -%% init mnesia schema. -%% -%% @end -%%------------------------------------------------------------------------------ +%% @doc Init mnesia schema. init_schema() -> case mnesia:system_info(extra_db_nodes) of [] -> @@ -62,13 +51,8 @@ init_schema() -> ok end. -%%------------------------------------------------------------------------------ -%% @doc %% @private -%% init mnesia tables. -%% -%% @end -%%------------------------------------------------------------------------------ +%% @doc Init mnesia tables. init_tables() -> case mnesia:system_info(extra_db_nodes) of [] -> @@ -77,13 +61,8 @@ init_tables() -> copy_tables() end. -%%------------------------------------------------------------------------------ -%% @doc %% @private -%% create tables. -%% -%% @end -%%------------------------------------------------------------------------------ +%% @doc create tables. create_tables() -> emqttd_util:apply_module_attributes(boot_mnesia). @@ -95,13 +74,8 @@ create_table(Table, Attrs) -> Error -> Error end. -%%------------------------------------------------------------------------------ -%% @doc %% @private -%% copy tables. -%% -%% @end -%%------------------------------------------------------------------------------ +%% @doc copy tables. copy_tables() -> emqttd_util:apply_module_attributes(copy_mnesia). @@ -113,24 +87,15 @@ copy_table(Table) -> {aborted, Error} -> Error end. -%%------------------------------------------------------------------------------ -%% @doc %% @private -%% wait for tables. -%% -%% @end -%%------------------------------------------------------------------------------ -wait_for_tables() -> +%% @doc wait for tables. +wait_for_tables() -> %% io:format("mnesia wait_for_tables: ~p~n", [mnesia:system_info(local_tables)]), mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity). -%%------------------------------------------------------------------------------ -%% @doc +%% TODO: should move to cluster. %% @private -%% Simple cluster with another nodes. -%% -%% @end -%%------------------------------------------------------------------------------ +%% @doc Simple cluster with another nodes. cluster(Node) -> %% stop mnesia mnesia:stop(), diff --git a/src/emqttd_mod_presence.erl b/src/emqttd_mod_presence.erl index 171a081bf..7262c025d 100644 --- a/src/emqttd_mod_presence.erl +++ b/src/emqttd_mod_presence.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd presence management module -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd presence management module +%% @author Feng Lee -module(emqttd_mod_presence). -behaviour(emqttd_gen_mod). @@ -38,7 +31,7 @@ load(Opts) -> {?MODULE, client_connected, [Opts]}), emqttd_broker:hook('client.disconnected', {?MODULE, client_disconnected}, {?MODULE, client_disconnected, [Opts]}), - {ok, Opts}. + ok. client_connected(ConnAck, #mqtt_client{client_id = ClientId, username = Username, @@ -85,4 +78,3 @@ reason(Reason) when is_atom(Reason) -> Reason; reason({Error, _}) when is_atom(Error) -> Error; reason(_) -> internal_error. - diff --git a/src/emqttd_mod_rewrite.erl b/src/emqttd_mod_rewrite.erl index addc22aee..35fbedf2a 100644 --- a/src/emqttd_mod_rewrite.erl +++ b/src/emqttd_mod_rewrite.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd rewrite module -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd rewrite module +%% @author Feng Lee -module(emqttd_mod_rewrite). -behaviour(emqttd_gen_mod). @@ -33,9 +26,9 @@ -export([rewrite/3, rewrite/4]). -%%%============================================================================= -%%% API -%%%============================================================================= +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- load(Opts) -> File = proplists:get_value(file, Opts), @@ -47,7 +40,7 @@ load(Opts) -> {?MODULE, rewrite, [unsubscribe, Sections]}), emqttd_broker:hook('message.publish', {?MODULE, rewrite_publish}, {?MODULE, rewrite, [publish, Sections]}), - {ok, Sections}. + ok. rewrite(_ClientId, TopicTable, subscribe, Sections) -> lager:info("rewrite subscribe: ~p", [TopicTable]), @@ -84,9 +77,9 @@ unload(_) -> emqttd_broker:unhook('client.unsubscribe',{?MODULE, rewrite_unsubscribe}), emqttd_broker:unhook('message.publish', {?MODULE, rewrite_publish}). -%%%============================================================================= -%%% Internal functions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- compile(Sections) -> C = fun({rewrite, Re, Dest}) -> diff --git a/src/emqttd_mod_subscription.erl b/src/emqttd_mod_subscription.erl index 277cd1676..c581609ff 100644 --- a/src/emqttd_mod_subscription.erl +++ b/src/emqttd_mod_subscription.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc Subscription from Broker Side -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Subscription from Broker Side +%% @author Feng Lee -module(emqttd_mod_subscription). -behaviour(emqttd_gen_mod). @@ -44,7 +37,7 @@ load(Opts) -> State = #state{topics = Topics, stored = lists:member(stored, Opts)}, emqttd_broker:hook('client.connected', {?MODULE, client_connected}, {?MODULE, client_connected, [State]}), - {ok, State}. + ok. client_connected(?CONNACK_ACCEPT, #mqtt_client{client_id = ClientId, client_pid = ClientPid, diff --git a/src/emqttd_mod_sup.erl b/src/emqttd_mod_sup.erl index 4ec277451..a394ab9ad 100644 --- a/src/emqttd_mod_sup.erl +++ b/src/emqttd_mod_sup.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd module supervisor. -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd module supervisor. +%% @author Feng Lee -module(emqttd_mod_sup). -behaviour(supervisor). @@ -38,9 +31,9 @@ %% Helper macro for declaring children of supervisor -define(CHILD(Mod, Type), {Mod, {Mod, start_link, []}, permanent, 5000, Type, [Mod]}). -%%%============================================================================= -%%% API -%%%============================================================================= +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). @@ -55,10 +48,11 @@ start_child(ChildSpec) when is_tuple(ChildSpec) -> start_child(Mod, Type) when is_atom(Mod) and is_atom(Type) -> supervisor:start_child(?MODULE, ?CHILD(Mod, Type)). -%%%============================================================================= -%%% Supervisor callbacks -%%%============================================================================= + +%%-------------------------------------------------------------------- +%% Supervisor callbacks +%%-------------------------------------------------------------------- init([]) -> - {ok, {{one_for_one, 10, 3600}, []}}. + {ok, {{one_for_one, 10, 100}, []}}. diff --git a/src/emqttd_mqueue.erl b/src/emqttd_mqueue.erl index 1c07ffcc7..e5931899d 100644 --- a/src/emqttd_mqueue.erl +++ b/src/emqttd_mqueue.erl @@ -1,55 +1,47 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc -%%% -%%% A Simple in-memory message queue. -%%% -%%% Notice that MQTT is not an enterprise messaging queue. MQTT assume that client -%%% should be online in most of the time. -%%% -%%% This module implements a simple in-memory queue for MQTT persistent session. -%%% -%%% If the broker restarted or crashed, all the messages queued will be gone. -%%% -%%% Concept of Message Queue and Inflight Window: -%%% -%%% |<----------------- Max Len ----------------->| -%%% ----------------------------------------------- -%%% IN -> | Messages Queue | Inflight Window | -> Out -%%% ----------------------------------------------- -%%% |<--- Win Size --->| -%%% -%%% -%%% 1. Inflight Window to store the messages delivered and awaiting for puback. -%%% -%%% 2. Enqueue messages when the inflight window is full. -%%% -%%% 3. If the queue is full, dropped qos0 messages if store_qos0 is true, -%%% otherwise dropped the oldest one. -%%% -%%% @end -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc A Simple in-memory message queue. +%% +%% Notice that MQTT is not an enterprise messaging queue. MQTT assume that client +%% should be online in most of the time. +%% +%% This module implements a simple in-memory queue for MQTT persistent session. +%% +%% If the broker restarted or crashed, all the messages queued will be gone. +%% +%% Concept of Message Queue and Inflight Window: +%% +%% |<----------------- Max Len ----------------->| +%% ----------------------------------------------- +%% IN -> | Messages Queue | Inflight Window | -> Out +%% ----------------------------------------------- +%% |<--- Win Size --->| +%% +%% +%% 1. Inflight Window to store the messages delivered and awaiting for puback. +%% +%% 2. Enqueue messages when the inflight window is full. +%% +%% 3. If the queue is full, dropped qos0 messages if store_qos0 is true, +%% otherwise dropped the oldest one. +%% +%% @end +%% +%% @author Feng Lee -module(emqttd_mqueue). -include("emqttd.hrl"). diff --git a/src/emqttd_net.erl b/src/emqttd_net.erl index f9e735583..aff6032c8 100644 --- a/src/emqttd_net.erl +++ b/src/emqttd_net.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd net utility functions. some functions copied from rabbitmq. -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd net utility functions. some functions copied from rabbitmq. +%% @author Feng Lee -module(emqttd_net). -include_lib("kernel/include/inet.hrl"). diff --git a/src/emqttd_opts.erl b/src/emqttd_opts.erl index 52541eb25..2685efb05 100644 --- a/src/emqttd_opts.erl +++ b/src/emqttd_opts.erl @@ -1,36 +1,26 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd options handler. -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd options handler. +%% @author Feng Lee -module(emqttd_opts). -export([merge/2, g/2, g/3]). -%%------------------------------------------------------------------------------ %% @doc Merge Options -%% @end -%%------------------------------------------------------------------------------ merge(Defaults, Options) -> lists:foldl( fun({Opt, Val}, Acc) -> @@ -45,10 +35,7 @@ merge(Defaults, Options) -> end end, Defaults, Options). -%%------------------------------------------------------------------------------ %% @doc Get option -%% @end -%%------------------------------------------------------------------------------ g(Key, Options) -> proplists:get_value(Key, Options). diff --git a/src/emqttd_packet.erl b/src/emqttd_packet.erl index 860f1a8b5..fdb42d9b7 100644 --- a/src/emqttd_packet.erl +++ b/src/emqttd_packet.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc MQTT Packet Functions -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc MQTT Packet Functions +%% @author Feng Lee -module(emqttd_packet). -include("emqttd.hrl"). @@ -34,26 +27,17 @@ -export([format/1]). -%%------------------------------------------------------------------------------ %% @doc Protocol name of version -%% @end -%%------------------------------------------------------------------------------ -spec protocol_name(mqtt_vsn()) -> binary(). protocol_name(Ver) when Ver =:= ?MQTT_PROTO_V31; Ver =:= ?MQTT_PROTO_V311-> proplists:get_value(Ver, ?PROTOCOL_NAMES). -%%------------------------------------------------------------------------------ %% @doc Name of MQTT packet type -%% @end -%%------------------------------------------------------------------------------ -spec type_name(mqtt_packet_type()) -> atom(). type_name(Type) when Type > ?RESERVED andalso Type =< ?DISCONNECT -> lists:nth(Type, ?TYPE_NAMES). -%%------------------------------------------------------------------------------ %% @doc Connack Name -%% @end -%%------------------------------------------------------------------------------ -spec connack_name(mqtt_connack()) -> atom(). connack_name(?CONNACK_ACCEPT) -> 'CONNACK_ACCEPT'; connack_name(?CONNACK_PROTO_VER) -> 'CONNACK_PROTO_VER'; @@ -62,10 +46,7 @@ connack_name(?CONNACK_SERVER) -> 'CONNACK_SERVER'; connack_name(?CONNACK_CREDENTIALS) -> 'CONNACK_CREDENTIALS'; connack_name(?CONNACK_AUTH) -> 'CONNACK_AUTH'. -%%------------------------------------------------------------------------------ %% @doc Format packet -%% @end -%%------------------------------------------------------------------------------ -spec format(mqtt_packet()) -> iolist(). format(#mqtt_packet{header = Header, variable = Variable, payload = Payload}) -> format_header(Header, format_variable(Variable, Payload)). @@ -115,7 +96,7 @@ format_variable(#mqtt_packet_connack{ack_flags = AckFlags, format_variable(#mqtt_packet_publish{topic_name = TopicName, packet_id = PacketId}) -> - io_lib:format("TopicName=~s, PacketId=~p", [TopicName, PacketId]); + io_lib:format("Topic=~s, PacketId=~p", [TopicName, PacketId]); format_variable(#mqtt_packet_puback{packet_id = PacketId}) -> io_lib:format("PacketId=~p", [PacketId]); diff --git a/src/emqttd_parser.erl b/src/emqttd_parser.erl index e477fe5e2..94a18a20d 100644 --- a/src/emqttd_parser.erl +++ b/src/emqttd_parser.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc MQTT Packet Parser -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc MQTT Packet Parser +%% @author Feng Lee -module(emqttd_parser). -include("emqttd.hrl"). @@ -38,10 +31,7 @@ -type parser() :: fun( (binary()) -> any() ). -%%------------------------------------------------------------------------------ %% @doc Initialize a parser -%% @end -%%------------------------------------------------------------------------------ -spec new(Opts :: [option()]) -> parser(). new(Opts) -> fun(Bin) -> parse(Bin, {none, limit(Opts)}) end. @@ -50,11 +40,9 @@ limit(Opts) -> #mqtt_packet_limit{max_packet_size = proplists:get_value(max_packet_size, Opts, ?MAX_LEN)}. -%%------------------------------------------------------------------------------ %% @doc Parse MQTT Packet -%% @end -%%------------------------------------------------------------------------------ --spec parse(binary(), {none, [option()]} | fun()) -> {ok, mqtt_packet()} | {error, any()} | {more, fun()}. +-spec parse(binary(), {none, [option()]} | fun()) -> + {ok, mqtt_packet()} | {error, any()} | {more, fun()}. parse(<<>>, {none, Limit}) -> {more, fun(Bin) -> parse(Bin, {none, Limit}) end}; parse(<>, {none, Limit}) -> diff --git a/src/emqttd_plugins.erl b/src/emqttd_plugins.erl index 17afbfb16..ac5c57455 100644 --- a/src/emqttd_plugins.erl +++ b/src/emqttd_plugins.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd plugins. -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd plugins. +%% @author Feng Lee -module(emqttd_plugins). -include("emqttd.hrl"). @@ -33,10 +26,7 @@ -export([list/0]). -%%------------------------------------------------------------------------------ %% @doc Load all plugins when the broker started. -%% @end -%%------------------------------------------------------------------------------ -spec load() -> list() | {error, any()}. load() -> case env(loaded_file) of @@ -65,10 +55,7 @@ load_plugins(Names, Persistent) -> NeedToLoad = Names -- NotFound -- names(started_app), [load_plugin(find_plugin(Name, Plugins), Persistent) || Name <- NeedToLoad]. -%%------------------------------------------------------------------------------ %% @doc Unload all plugins before broker stopped. -%% @end -%%------------------------------------------------------------------------------ -spec unload() -> list() | {error, any()}. unload() -> case env(loaded_file) of @@ -82,10 +69,7 @@ unload() -> stop_plugins(Names) -> [stop_app(App) || App <- Names]. -%%------------------------------------------------------------------------------ %% @doc List all available plugins -%% @end -%%------------------------------------------------------------------------------ -spec list() -> [mqtt_plugin()]. list() -> case env(plugins_dir) of @@ -119,10 +103,7 @@ plugin(PluginsDir, AppFile0) -> Descr = proplists:get_value(description, Attrs, ""), #mqtt_plugin{name = Name, version = Ver, config = AppsEnv1, descr = Descr}. -%%------------------------------------------------------------------------------ %% @doc Load One Plugin -%% @end -%%------------------------------------------------------------------------------ -spec load(atom()) -> ok | {error, any()}. load(PluginName) when is_atom(PluginName) -> case lists:member(PluginName, names(started_app)) of @@ -182,10 +163,7 @@ find_plugin(Name) -> find_plugin(Name, Plugins) -> lists:keyfind(Name, 2, Plugins). -%%------------------------------------------------------------------------------ %% @doc UnLoad One Plugin -%% @end -%%------------------------------------------------------------------------------ -spec unload(atom()) -> ok | {error, any()}. unload(PluginName) when is_atom(PluginName) -> case {lists:member(PluginName, names(started_app)), lists:member(PluginName, names(plugin))} of @@ -217,9 +195,9 @@ stop_app(App) -> lager:error("stop plugin ~p error: ~p", [App]), {error, Reason} end. -%%%============================================================================= -%%% Internal functions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- names(plugin) -> names(list()); diff --git a/src/emqttd_pool_sup.erl b/src/emqttd_pool_sup.erl index 0f06c0431..5a4e10d72 100644 --- a/src/emqttd_pool_sup.erl +++ b/src/emqttd_pool_sup.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc Common Pool Supervisor -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Common Pool Supervisor +%% @author Feng Lee -module(emqttd_pool_sup). -behaviour(supervisor). diff --git a/src/emqttd_pooler.erl b/src/emqttd_pooler.erl index b9352d309..0f3abe574 100644 --- a/src/emqttd_pooler.erl +++ b/src/emqttd_pooler.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd pooler. -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd pooler. +%% @author Feng Lee -module(emqttd_pooler). -behaviour(gen_server). @@ -41,40 +34,30 @@ -record(state, {pool, id}). -%%------------------------------------------------------------------------------ %% @doc Start Pooler Supervisor. -%% @end -%%------------------------------------------------------------------------------ start_link() -> emqttd_pool_sup:start_link(pooler, random, {?MODULE, start_link, []}). -%%%============================================================================= -%%% API -%%%============================================================================= +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- -spec start_link(atom(), pos_integer()) -> {ok, pid()} | ignore | {error, any()}. start_link(Pool, Id) -> gen_server:start_link({local, emqttd:reg_name(?MODULE, Id)}, ?MODULE, [Pool, Id], []). -%%------------------------------------------------------------------------------ %% @doc Submit work to pooler -%% @end -%%------------------------------------------------------------------------------ -submit(Fun) -> - gen_server:call(worker(), {submit, Fun}, infinity). +submit(Fun) -> gen_server:call(worker(), {submit, Fun}, infinity). -%%------------------------------------------------------------------------------ %% @doc Submit work to pooler asynchronously -%% @end -%%------------------------------------------------------------------------------ async_submit(Fun) -> gen_server:cast(worker(), {async_submit, Fun}). worker() -> gproc_pool:pick_worker(pooler). -%%%============================================================================= -%%% gen_server callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% gen_server callbacks +%%-------------------------------------------------------------------- init([Pool, Id]) -> ?GPROC_POOL(join, Pool, Id), @@ -105,9 +88,9 @@ terminate(_Reason, #state{pool = Pool, id = Id}) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. -%%%============================================================================= -%%% Internal functions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- run({M, F, A}) -> erlang:apply(M, F, A); diff --git a/src/emqttd_protocol.erl b/src/emqttd_protocol.erl index ffcf41e6c..c1457be41 100644 --- a/src/emqttd_protocol.erl +++ b/src/emqttd_protocol.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd protocol. -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd protocol. +%% @author Feng Lee -module(emqttd_protocol). -include("emqttd.hrl"). @@ -55,10 +48,7 @@ lager:Level([{client, State#proto_state.client_id}], "Client(~s@~s): " ++ Format, [State#proto_state.client_id, esockd_net:format(State#proto_state.peername) | Args])). -%%------------------------------------------------------------------------------ %% @doc Init protocol -%% @end -%%------------------------------------------------------------------------------ init(Peername, SendFun, Opts) -> MaxLen = emqttd_opts:g(max_clientid_len, Opts, ?MAX_CLIENTID_LEN), WsInitialHeaders = emqttd_opts:g(ws_initial_headers, Opts), @@ -315,9 +305,10 @@ start_keepalive(0) -> ignore; start_keepalive(Sec) when Sec > 0 -> self() ! {keepalive, start, round(Sec * 1.2)}. -%%---------------------------------------------------------------------------- +%%-------------------------------------------------------------------- %% Validate Packets -%%---------------------------------------------------------------------------- +%%-------------------------------------------------------------------- + validate_connect(Connect = #mqtt_packet_connect{}, ProtoState) -> case validate_protocol(Connect) of true -> diff --git a/src/emqttd_pubsub.erl b/src/emqttd_pubsub.erl index 095ba6223..23a36134a 100644 --- a/src/emqttd_pubsub.erl +++ b/src/emqttd_pubsub.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc PubSub -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Core PubSub +%% @author Feng Lee -module(emqttd_pubsub). -behaviour(gen_server2). @@ -60,9 +53,9 @@ -define(ROUTER, emqttd_router). -%%%============================================================================= -%%% Mnesia callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Mnesia callbacks +%%-------------------------------------------------------------------- mnesia(boot) -> ok = create_table(topic, ram_copies), if_subscription(fun(RamOrDisc) -> @@ -115,9 +108,9 @@ cache_env(Key) -> put({pubsub, Key}, Val), Val. -%%%============================================================================= -%%% API -%%%============================================================================= +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- %% @doc Start one pubsub server -spec start_link(Pool, Id, StatsFun, Opts) -> {ok, pid()} | ignore | {error, any()} when @@ -241,9 +234,9 @@ match(To) -> %% ets:lookup for topic table will be replicated to all nodes. lists:append([ets:lookup(topic, Topic) || Topic <- MatchedTopics]). -%%%============================================================================= -%%% gen_server callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% gen_server callbacks +%%-------------------------------------------------------------------- init([Pool, Id, StatsFun, _Opts]) -> ?GPROC_POOL(join, Pool, Id), @@ -332,9 +325,9 @@ terminate(_Reason, #state{pool = Pool, id = Id}) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. -%%%============================================================================= -%%% Internal functions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- add_topics(Records) -> lists:foreach(fun add_topic/1, Records). @@ -410,9 +403,9 @@ try_monitor(SubPid) -> false -> erlang:monitor(process, SubPid) end. -%%%============================================================================= -%%% Trace Functions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Trace Functions +%%-------------------------------------------------------------------- trace(publish, From, _Msg) when is_atom(From) -> %% Dont' trace '$SYS' publish diff --git a/src/emqttd_pubsub_helper.erl b/src/emqttd_pubsub_helper.erl index baa922697..79923ca9e 100644 --- a/src/emqttd_pubsub_helper.erl +++ b/src/emqttd_pubsub_helper.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + %%% @doc PubSub Helper. -%%% %%% @author Feng Lee -%%%----------------------------------------------------------------------------- -module(emqttd_pubsub_helper). -behaviour(gen_server). @@ -47,9 +40,9 @@ start_link(StatsFun) -> gen_server:start_link({local, ?SERVER}, ?MODULE, [StatsFun], []). -%%%============================================================================= -%%% gen_server callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% gen_server callbacks +%%-------------------------------------------------------------------- init([StatsFun]) -> mnesia:subscribe(system), diff --git a/src/emqttd_pubsub_sup.erl b/src/emqttd_pubsub_sup.erl index 74d4b22b2..c5df349bc 100644 --- a/src/emqttd_pubsub_sup.erl +++ b/src/emqttd_pubsub_sup.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc PubSub Supervisor. -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc PubSub Supervisor. +%% @author Feng Lee -module(emqttd_pubsub_sup). -behaviour(supervisor). diff --git a/src/emqttd_retainer.erl b/src/emqttd_retainer.erl index e4e10c4da..7fc3ca268 100644 --- a/src/emqttd_retainer.erl +++ b/src/emqttd_retainer.erl @@ -1,32 +1,22 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc MQTT retained message storage. -%%% -%%% TODO: should match topic tree -%%% -%%% @end -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% TODO: should match topic tree +%% @doc MQTT retained message storage. +%% @author Feng Lee -module(emqttd_retainer). -behaviour(gen_server). @@ -57,9 +47,9 @@ -record(state, {stats_fun, expired_after, stats_timer, expire_timer}). -%%%============================================================================= -%%% Mnesia callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Mnesia callbacks +%%-------------------------------------------------------------------- mnesia(boot) -> ok = emqttd_mnesia:create_table(retained, [ @@ -70,22 +60,16 @@ mnesia(boot) -> mnesia(copy) -> ok = emqttd_mnesia:copy_table(retained). -%%%============================================================================= -%%% API -%%%============================================================================= +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- -%%------------------------------------------------------------------------------ %% @doc Start a retained server -%% @end -%%------------------------------------------------------------------------------ -spec start_link() -> {ok, pid()} | ignore | {error, any()}. start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). -%%%----------------------------------------------------------------------------- %% @doc Retain message -%% @end -%%%----------------------------------------------------------------------------- -spec retain(mqtt_message()) -> ok | ignore. retain(#mqtt_message{retain = false}) -> ignore; @@ -121,10 +105,7 @@ env(Key) -> Val end. -%%%----------------------------------------------------------------------------- %% @doc Deliver retained messages to subscribed client -%% @end -%%%----------------------------------------------------------------------------- -spec dispatch(Topic, CPid) -> any() when Topic :: binary(), CPid :: pid(). @@ -144,9 +125,9 @@ dispatch(Topic, CPid) when is_binary(Topic) -> end, lists:foreach(fun(Msg) -> CPid ! {dispatch, Topic, Msg} end, lists:reverse(Msgs)). -%%%============================================================================= -%%% gen_server callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% gen_server callbacks +%%-------------------------------------------------------------------- init([]) -> StatsFun = emqttd_stats:statsfun('retained/count', 'retained/max'), @@ -187,9 +168,9 @@ terminate(_Reason, _State = #state{stats_timer = TRef1, expire_timer = TRef2}) - code_change(_OldVsn, State, _Extra) -> {ok, State}. -%%%============================================================================= -%%% Internal functions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- expire(Time) -> mnesia:async_dirty( diff --git a/src/emqttd_router.erl b/src/emqttd_router.erl index 55d9d63bd..472b13501 100644 --- a/src/emqttd_router.erl +++ b/src/emqttd_router.erl @@ -1,29 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc Message Router on local node. -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- +%% @doc Message Router on local node. +%% @author Feng Lee -module(emqttd_router). -behaviour(gen_server2). diff --git a/src/emqttd_serializer.erl b/src/emqttd_serializer.erl index b88189d34..75222ffc4 100644 --- a/src/emqttd_serializer.erl +++ b/src/emqttd_serializer.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc MQTT Packet Serializer -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc MQTT Packet Serializer +%% @author Feng Lee -module(emqttd_serializer). -include("emqttd.hrl"). @@ -32,10 +25,7 @@ %% API -export([serialize/1]). -%%------------------------------------------------------------------------------ %% @doc Serialise MQTT Packet -%% @end -%%------------------------------------------------------------------------------ -spec serialize(mqtt_packet()) -> binary(). serialize(#mqtt_packet{header = Header = #mqtt_packet_header{type = Type}, variable = Variable, diff --git a/src/emqttd_session.erl b/src/emqttd_session.erl index 0c294aed3..0196b2cd7 100644 --- a/src/emqttd_session.erl +++ b/src/emqttd_session.erl @@ -1,49 +1,43 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc Session for persistent MQTT client. -%%% -%%% Session State in the broker consists of: -%%% -%%% 1. The Client’s subscriptions. -%%% -%%% 2. inflight qos1/2 messages sent to the client but unacked, QoS 1 and QoS 2 -%%% messages which have been sent to the Client, but have not been completely -%%% acknowledged. -%%% -%%% 3. inflight qos2 messages received from client and waiting for pubrel. QoS 2 -%%% messages which have been received from the Client, but have not been -%%% completely acknowledged. -%%% -%%% 4. all qos1, qos2 messages published to when client is disconnected. -%%% QoS 1 and QoS 2 messages pending transmission to the Client. -%%% -%%% 5. Optionally, QoS 0 messages pending transmission to the Client. -%%% -%%% State of Message: newcome, inflight, pending -%%% -%%% @end -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Session for persistent MQTT client. +%% +%% Session State in the broker consists of: +%% +%% 1. The Client’s subscriptions. +%% +%% 2. inflight qos1/2 messages sent to the client but unacked, QoS 1 and QoS 2 +%% messages which have been sent to the Client, but have not been completely +%% acknowledged. +%% +%% 3. inflight qos2 messages received from client and waiting for pubrel. QoS 2 +%% messages which have been received from the Client, but have not been +%% completely acknowledged. +%% +%% 4. all qos1, qos2 messages published to when client is disconnected. +%% QoS 1 and QoS 2 messages pending transmission to the Client. +%% +%% 5. Optionally, QoS 0 messages pending transmission to the Client. +%% +%% State of Message: newcome, inflight, pending +%% +%% @end +%% +%% @author Feng Lee -module(emqttd_session). -include("emqttd.hrl"). @@ -140,41 +134,26 @@ lager:Level([{client, State#session.client_id}], "Session(~s): " ++ Format, [State#session.client_id | Args])). -%%------------------------------------------------------------------------------ %% @doc Start a session. -%% @end -%%------------------------------------------------------------------------------ -spec start_link(boolean(), mqtt_client_id(), pid()) -> {ok, pid()} | {error, any()}. start_link(CleanSess, ClientId, ClientPid) -> gen_server2:start_link(?MODULE, [CleanSess, ClientId, ClientPid], []). -%%------------------------------------------------------------------------------ %% @doc Resume a session. -%% @end -%%------------------------------------------------------------------------------ -spec resume(pid(), mqtt_client_id(), pid()) -> ok. resume(SessPid, ClientId, ClientPid) -> gen_server2:cast(SessPid, {resume, ClientId, ClientPid}). -%%------------------------------------------------------------------------------ %% @doc Session Info. -%% @end -%%------------------------------------------------------------------------------ info(SessPid) -> gen_server2:call(SessPid, info). -%%------------------------------------------------------------------------------ %% @doc Destroy a session. -%% @end -%%------------------------------------------------------------------------------ -spec destroy(pid(), mqtt_client_id()) -> ok. destroy(SessPid, ClientId) -> gen_server2:cast(SessPid, {destroy, ClientId}). -%%------------------------------------------------------------------------------ %% @doc Subscribe Topics -%% @end -%%------------------------------------------------------------------------------ -spec subscribe(pid(), [{binary(), mqtt_qos()}]) -> ok. subscribe(SessPid, TopicTable) -> gen_server2:cast(SessPid, {subscribe, TopicTable, fun(_) -> ok end}). @@ -187,10 +166,7 @@ subscribe(SessPid, PacketId, TopicTable) -> end, gen_server2:cast(SessPid, {subscribe, TopicTable, AckFun}). -%%------------------------------------------------------------------------------ %% @doc Publish message -%% @end -%%------------------------------------------------------------------------------ -spec publish(pid(), mqtt_message()) -> ok | {error, any()}. publish(_SessPid, Msg = #mqtt_message{qos = ?QOS_0}) -> %% publish qos0 directly @@ -204,10 +180,7 @@ publish(SessPid, Msg = #mqtt_message{qos = ?QOS_2}) -> %% publish qos2 by session gen_server2:call(SessPid, {publish, Msg}, ?PUBSUB_TIMEOUT). -%%------------------------------------------------------------------------------ %% @doc PubAck message -%% @end -%%------------------------------------------------------------------------------ -spec puback(pid(), mqtt_packet_id()) -> ok. puback(SessPid, PktId) -> gen_server2:cast(SessPid, {puback, PktId}). @@ -224,17 +197,14 @@ pubrel(SessPid, PktId) -> pubcomp(SessPid, PktId) -> gen_server2:cast(SessPid, {pubcomp, PktId}). -%%------------------------------------------------------------------------------ %% @doc Unsubscribe Topics -%% @end -%%------------------------------------------------------------------------------ -spec unsubscribe(pid(), [binary()]) -> ok. unsubscribe(SessPid, Topics) -> gen_server2:cast(SessPid, {unsubscribe, Topics}). -%%%============================================================================= -%%% gen_server callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% gen_server callbacks +%%-------------------------------------------------------------------- init([CleanSess, ClientId, ClientPid]) -> process_flag(trap_exit, true), @@ -564,13 +534,9 @@ terminate(_Reason, #session{clean_sess = CleanSess, client_id = ClientId}) -> code_change(_OldVsn, Session, _Extra) -> {ok, Session}. -%%%============================================================================= -%%% Internal functions -%%%============================================================================= - -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% Kick old client out -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- kick(_ClientId, undefined, _Pid) -> ignore; kick(_ClientId, Pid, Pid) -> @@ -581,9 +547,9 @@ kick(ClientId, OldPid, Pid) -> %% Clean noproc receive {'EXIT', OldPid, _} -> ok after 0 -> ok end. -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% Dispatch Messages -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% Queue message if client disconnected dispatch(Msg, Session = #session{client_pid = undefined, message_queue = Q}) -> @@ -613,9 +579,9 @@ tune_qos(Topic, Msg = #mqtt_message{qos = PubQos}, Subscriptions) -> Msg end. -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% Check inflight and awaiting_rel -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- check_inflight(#session{max_inflight = 0}) -> true; @@ -628,9 +594,9 @@ check_awaiting_rel(#session{awaiting_rel = AwaitingRel, max_awaiting_rel = MaxLen}) -> maps:size(AwaitingRel) < MaxLen. -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% Dequeue and Deliver -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- dequeue(Session = #session{client_pid = undefined}) -> %% do nothing if client is disconnected @@ -670,7 +636,7 @@ redeliver(Msg = #mqtt_message{qos = QoS}, Session = #session{client_pid = Client ClientPid ! {deliver, Msg#mqtt_message{dup = true}}, await(Msg, Session). -%%------------------------------------------------------------------------------ +%%-------------------------------------------------------------------- %% Awaiting ack for qos1, qos2 message %%------------------------------------------------------------------------------ await(#mqtt_message{pktid = PktId}, Session = #session{awaiting_ack = Awaiting, diff --git a/src/emqttd_session_sup.erl b/src/emqttd_session_sup.erl index e4b75094b..820aff055 100644 --- a/src/emqttd_session_sup.erl +++ b/src/emqttd_session_sup.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd session supervisor. -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd session supervisor. +%% @author Feng Lee -module(emqttd_session_sup). -behavior(supervisor). @@ -31,29 +24,22 @@ -export([init/1]). -%%------------------------------------------------------------------------------ %% @doc Start session supervisor -%% @end -%%------------------------------------------------------------------------------ -spec start_link() -> {ok, pid()}. start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). -%%------------------------------------------------------------------------------ %% @doc Start a session -%% @end -%%------------------------------------------------------------------------------ -spec start_session(boolean(), binary(), pid()) -> {ok, pid()}. start_session(CleanSess, ClientId, ClientPid) -> supervisor:start_child(?MODULE, [CleanSess, ClientId, ClientPid]). -%%%============================================================================= -%%% Supervisor callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Supervisor callbacks +%%-------------------------------------------------------------------- init([]) -> {ok, {{simple_one_for_one, 10, 10}, [{session, {emqttd_session, start_link, []}, temporary, 10000, worker, [emqttd_session]}]}}. - diff --git a/src/emqttd_sm.erl b/src/emqttd_sm.erl index 9c6bc938b..28cb2e428 100644 --- a/src/emqttd_sm.erl +++ b/src/emqttd_sm.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc Session Manager -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Session Manager +%% @author Feng Lee -module(emqttd_sm). -include("emqttd.hrl"). @@ -60,9 +53,9 @@ -define(LOG(Level, Format, Args, Session), lager:Level("SM(~s): " ++ Format, [Session#mqtt_session.client_id | Args])). -%%%============================================================================= -%%% Mnesia callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Mnesia callbacks +%%-------------------------------------------------------------------- mnesia(boot) -> %% Global Session Table @@ -75,31 +68,22 @@ mnesia(boot) -> mnesia(copy) -> ok = emqttd_mnesia:copy_table(session). -%%%============================================================================= -%%% API -%%%============================================================================= +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- -%%------------------------------------------------------------------------------ %% @doc Start a session manager -%% @end -%%------------------------------------------------------------------------------ -spec start_link(atom(), pos_integer()) -> {ok, pid()} | ignore | {error, any()}. start_link(Pool, Id) -> gen_server2:start_link({local, emqttd:reg_name(?MODULE, Id)}, ?MODULE, [Pool, Id], []). -%%------------------------------------------------------------------------------ %% @doc Start a session -%% @end -%%------------------------------------------------------------------------------ -spec start_session(CleanSess :: boolean(), binary()) -> {ok, pid(), boolean()} | {error, any()}. start_session(CleanSess, ClientId) -> SM = gproc_pool:pick_worker(?POOL, ClientId), call(SM, {start_session, {CleanSess, ClientId, self()}}). -%%------------------------------------------------------------------------------ %% @doc Lookup a Session -%% @end -%%------------------------------------------------------------------------------ -spec lookup_session(binary()) -> mqtt_session() | undefined. lookup_session(ClientId) -> case mnesia:dirty_read(session, ClientId) of @@ -107,10 +91,7 @@ lookup_session(ClientId) -> [] -> undefined end. -%%------------------------------------------------------------------------------ %% @doc Register a session with info. -%% @end -%%------------------------------------------------------------------------------ -spec register_session(CleanSess, ClientId, Info) -> ok when CleanSess :: boolean(), ClientId :: binary(), @@ -118,10 +99,7 @@ lookup_session(ClientId) -> register_session(CleanSess, ClientId, Info) -> ets:insert(sesstab(CleanSess), {{ClientId, self()}, Info}). -%%------------------------------------------------------------------------------ %% @doc Unregister a session. -%% @end -%%------------------------------------------------------------------------------ -spec unregister_session(CleanSess, ClientId) -> ok when CleanSess :: boolean(), ClientId :: binary(). @@ -134,9 +112,9 @@ sesstab(false) -> mqtt_persistent_session. call(SM, Req) -> gen_server2:call(SM, Req, ?TIMEOUT). %%infinity). -%%%============================================================================= -%%% gen_server callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% gen_server callbacks +%%-------------------------------------------------------------------- init([Pool, Id]) -> ?GPROC_POOL(join, Pool, Id), @@ -213,9 +191,9 @@ terminate(_Reason, #state{pool = Pool, id = Id}) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. -%%%============================================================================= -%%% Internal functions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- %% Create Session Locally create_session({CleanSess, ClientId, ClientPid}, State) -> diff --git a/src/emqttd_sm_helper.erl b/src/emqttd_sm_helper.erl index 0e06d95f4..35c5676d2 100644 --- a/src/emqttd_sm_helper.erl +++ b/src/emqttd_sm_helper.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc Session Helper. -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Session Helper. +%% @author Feng Lee -module(emqttd_sm_helper). -behaviour(gen_server). @@ -42,10 +35,7 @@ -record(state, {stats_fun, tick_tref}). -%%------------------------------------------------------------------------------ %% @doc Start a session helper -%% @end -%%------------------------------------------------------------------------------ -spec start_link(fun()) -> {ok, pid()} | ignore | {error, any()}. start_link(StatsFun) -> gen_server:start_link({local, ?MODULE}, ?MODULE, [StatsFun], []). @@ -89,9 +79,9 @@ terminate(_Reason, _State = #state{tick_tref = TRef}) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. -%%%============================================================================= -%%% Internal functions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- setstats(State = #state{stats_fun = StatsFun}) -> StatsFun(ets:info(mqtt_persistent_session, size)), State. diff --git a/src/emqttd_sm_sup.erl b/src/emqttd_sm_sup.erl index 1abde1143..62b8de0ef 100644 --- a/src/emqttd_sm_sup.erl +++ b/src/emqttd_sm_sup.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc Session Manager Supervisor. -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Session Manager Supervisor. +%% @author Feng Lee -module(emqttd_sm_sup). -behaviour(supervisor). diff --git a/src/emqttd_stats.erl b/src/emqttd_stats.erl index bc5510f54..292adf4f3 100644 --- a/src/emqttd_stats.erl +++ b/src/emqttd_stats.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd statistics -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd statistics +%% @author Feng Lee -module(emqttd_stats). -include("emqttd.hrl"). @@ -76,14 +69,11 @@ 'retained/max' ]). -%%%============================================================================= -%%% API -%%%============================================================================= +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- -%%------------------------------------------------------------------------------ %% @doc Start stats server -%% @end -%%------------------------------------------------------------------------------ -spec start_link() -> {ok, pid()} | ignore | {error, term()}. start_link() -> gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). @@ -91,10 +81,7 @@ start_link() -> stop() -> gen_server:call(?SERVER, stop). -%%------------------------------------------------------------------------------ %% @doc Generate stats fun -%% @end -%%------------------------------------------------------------------------------ -spec statsfun(Stat :: atom()) -> fun(). statsfun(Stat) -> fun(Val) -> setstat(Stat, Val) end. @@ -103,18 +90,12 @@ statsfun(Stat) -> statsfun(Stat, MaxStat) -> fun(Val) -> setstats(Stat, MaxStat, Val) end. -%%------------------------------------------------------------------------------ %% @doc Get broker statistics -%% @end -%%------------------------------------------------------------------------------ -spec getstats() -> [{atom(), non_neg_integer()}]. getstats() -> lists:sort(ets:tab2list(?STATS_TAB)). -%%------------------------------------------------------------------------------ %% @doc Get stats by name -%% @end -%%------------------------------------------------------------------------------ -spec getstat(atom()) -> non_neg_integer() | undefined. getstat(Name) -> case ets:lookup(?STATS_TAB, Name) of @@ -122,25 +103,19 @@ getstat(Name) -> [] -> undefined end. -%%------------------------------------------------------------------------------ %% @doc Set broker stats -%% @end -%%------------------------------------------------------------------------------ -spec setstat(Stat :: atom(), Val :: pos_integer()) -> boolean(). setstat(Stat, Val) -> ets:update_element(?STATS_TAB, Stat, {2, Val}). -%%------------------------------------------------------------------------------ %% @doc Set stats with max -%% @end -%%------------------------------------------------------------------------------ -spec setstats(Stat :: atom(), MaxStat :: atom(), Val :: pos_integer()) -> boolean(). setstats(Stat, MaxStat, Val) -> gen_server:cast(?MODULE, {setstats, Stat, MaxStat, Val}). -%%%============================================================================= -%%% gen_server callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% gen_server callbacks +%%-------------------------------------------------------------------- init([]) -> emqttd:seed_now(), @@ -186,9 +161,10 @@ terminate(_Reason, #state{tick_tref = TRef}) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. -%%%============================================================================= -%%% Internal functions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- + publish(Stat, Val) -> Msg = emqttd_message:make(stats, stats_topic(Stat), emqttd_util:integer_to_binary(Val)), diff --git a/src/emqttd_sup.erl b/src/emqttd_sup.erl index cea2f886d..2c78af8e3 100644 --- a/src/emqttd_sup.erl +++ b/src/emqttd_sup.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd top supervisor. -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd top supervisor. +%% @author Feng Lee -module(emqttd_sup). -behaviour(supervisor). @@ -39,9 +32,9 @@ -define(CHILD(Mod, Type), {Mod, {Mod, start_link, []}, permanent, 5000, Type, [Mod]}). -%%%============================================================================= -%%% API -%%%============================================================================= +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). @@ -56,9 +49,9 @@ start_child(ChildSpec) when is_tuple(ChildSpec) -> start_child(Mod, Type) when is_atom(Mod) and is_atom(Type) -> supervisor:start_child(?MODULE, ?CHILD(Mod, Type)). -%%%============================================================================= -%%% Supervisor callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Supervisor callbacks +%%-------------------------------------------------------------------- init([]) -> {ok, {{one_for_all, 10, 3600}, []}}. diff --git a/src/emqttd_sysmon.erl b/src/emqttd_sysmon.erl index 7b8b30247..14277c23e 100644 --- a/src/emqttd_sysmon.erl +++ b/src/emqttd_sysmon.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc VM System Monitor -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc VM System Monitor +%% @author Feng Lee -module(emqttd_sysmon). -behavior(gen_server). @@ -44,18 +37,15 @@ -define(LOG(Msg, ProcInfo, PortInfo), lager:warning([{sysmon, true}], "~s~n~p~n~p", [WarnMsg, ProcInfo, PortInfo])). -%%------------------------------------------------------------------------------ %% @doc Start system monitor -%% @end -%%------------------------------------------------------------------------------ -spec start_link(Opts :: list(tuple())) -> {ok, pid()} | ignore | {error, term()}. start_link(Opts) -> gen_server:start_link({local, ?MODULE}, ?MODULE, [Opts], []). -%%%============================================================================= -%%% gen_server callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% gen_server callbacks +%%-------------------------------------------------------------------- init([Opts]) -> erlang:system_monitor(self(), parse_opt(Opts)), diff --git a/src/emqttd_sysmon_sup.erl b/src/emqttd_sysmon_sup.erl index 83fa1447a..fbbe2e436 100644 --- a/src/emqttd_sysmon_sup.erl +++ b/src/emqttd_sysmon_sup.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd sysmon supervisor. -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd sysmon supervisor. +%% @author Feng Lee -module(emqttd_sysmon_sup). -behaviour(supervisor). diff --git a/src/emqttd_topic.erl b/src/emqttd_topic.erl index dabb1acea..91ec90d0e 100644 --- a/src/emqttd_topic.erl +++ b/src/emqttd_topic.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc MQTT Topic Functions -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc MQTT Topic Functions +%% @author Feng Lee -module(emqttd_topic). -import(lists, [reverse/1]). diff --git a/src/emqttd_trace.erl b/src/emqttd_trace.erl index 0841c0b9c..9133bc1f1 100644 --- a/src/emqttd_trace.erl +++ b/src/emqttd_trace.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc Trace MQTT packets/messages by ClientID or Topic. -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Trace MQTT packets/messages by ClientID or Topic. +%% @author Feng Lee -module(emqttd_trace). -behaviour(gen_server). @@ -44,17 +37,15 @@ -define(TRACE_OPTIONS, [{formatter_config, [time, " [",severity,"] ", message, "\n"]}]). -%%%============================================================================= -%%% API -%%%============================================================================= +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- + -spec start_link() -> {ok, pid()}. start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). -%%------------------------------------------------------------------------------ %% @doc Start to trace client or topic. -%% @end -%%------------------------------------------------------------------------------ -spec start_trace(trace_who(), string()) -> ok | {error, any()}. start_trace({client, ClientId}, LogFile) -> start_trace({start_trace, {client, ClientId}, LogFile}); @@ -62,26 +53,22 @@ start_trace({client, ClientId}, LogFile) -> start_trace({topic, Topic}, LogFile) -> start_trace({start_trace, {topic, Topic}, LogFile}). -start_trace(Req) -> - gen_server:call(?MODULE, Req, infinity). +start_trace(Req) -> gen_server:call(?MODULE, Req, infinity). -%%------------------------------------------------------------------------------ %% @doc Stop tracing client or topic. -%% @end -%%------------------------------------------------------------------------------ -spec stop_trace(trace_who()) -> ok | {error, any()}. stop_trace({client, ClientId}) -> gen_server:call(?MODULE, {stop_trace, {client, ClientId}}); stop_trace({topic, Topic}) -> gen_server:call(?MODULE, {stop_trace, {topic, Topic}}). -%%------------------------------------------------------------------------------ %% @doc Lookup all traces. -%% @end -%%------------------------------------------------------------------------------ -spec all_traces() -> [{Who :: trace_who(), LogFile :: string()}]. -all_traces() -> - gen_server:call(?MODULE, all_traces). +all_traces() -> gen_server:call(?MODULE, all_traces). + +%%-------------------------------------------------------------------- +%% gen_server callbacks +%%-------------------------------------------------------------------- init([]) -> {ok, #state{level = info, traces = #{}}}. diff --git a/src/emqttd_trace_sup.erl b/src/emqttd_trace_sup.erl index bcd0cf58a..916dfaaf5 100644 --- a/src/emqttd_trace_sup.erl +++ b/src/emqttd_trace_sup.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd trace supervisor. -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd trace supervisor. +%% @author Feng Lee -module(emqttd_trace_sup). -behaviour(supervisor). diff --git a/src/emqttd_trie.erl b/src/emqttd_trie.erl index ac21e94e8..20483ba9b 100644 --- a/src/emqttd_trie.erl +++ b/src/emqttd_trie.erl @@ -1,33 +1,25 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc -%%% MQTT Topic Trie. -%%% -%%% [Trie](http://en.wikipedia.org/wiki/Trie) -%%% -%%% @end -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- +%% @doc MQTT Topic Trie. +%% +%% [Trie](http://en.wikipedia.org/wiki/Trie) +%% +%% @end +%% +%% @author Feng Lee -module(emqttd_trie). %% Mnesia Callbacks @@ -57,14 +49,11 @@ node_id :: node_id() }). -%%%============================================================================= -%%% Mnesia Callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Mnesia Callbacks +%%-------------------------------------------------------------------- -%%------------------------------------------------------------------------------ -%% @doc Create Trie Tables -%% @end -%%------------------------------------------------------------------------------ +%% @doc Create Trie Tables. -spec mnesia(boot | copy) -> ok. mnesia(boot) -> %% Trie Table @@ -78,24 +67,18 @@ mnesia(boot) -> {record_name, trie_node}, {attributes, record_info(fields, trie_node)}]); -%%------------------------------------------------------------------------------ -%% @doc Replicate trie tables -%% @end -%%------------------------------------------------------------------------------ +%% @doc Replicate trie tables. mnesia(copy) -> %% Copy Trie Table ok = emqttd_mnesia:copy_table(trie), %% Copy Trie Node Table ok = emqttd_mnesia:copy_table(trie_node). -%%%============================================================================= -%%% API -%%%============================================================================= +%%-------------------------------------------------------------------- +%% API +%%-------------------------------------------------------------------- -%%------------------------------------------------------------------------------ -%% @doc Insert topic to trie tree -%% @end -%%------------------------------------------------------------------------------ +%% @doc Insert topic to trie tree. -spec insert(Topic :: binary()) -> ok. insert(Topic) when is_binary(Topic) -> case mnesia:read(trie_node, Topic) of @@ -110,19 +93,13 @@ insert(Topic) when is_binary(Topic) -> mnesia:write(#trie_node{node_id=Topic, topic=Topic}) end. -%%------------------------------------------------------------------------------ %% @doc Find trie nodes that match topic -%% @end -%%------------------------------------------------------------------------------ -spec match(Topic :: binary()) -> list(MatchedTopic :: binary()). match(Topic) when is_binary(Topic) -> TrieNodes = match_node(root, emqttd_topic:words(Topic)), [Name || #trie_node{topic=Name} <- TrieNodes, Name =/= undefined]. -%%------------------------------------------------------------------------------ %% @doc Delete topic from trie -%% @end -%%------------------------------------------------------------------------------ -spec delete(Topic :: binary()) -> ok. delete(Topic) when is_binary(Topic) -> case mnesia:read(trie_node, Topic) of @@ -135,17 +112,12 @@ delete(Topic) when is_binary(Topic) -> ok end. -%%%============================================================================= -%%% Internal functions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- -%%------------------------------------------------------------------------------ -%% @doc %% @private -%% Add path to trie tree. -%% -%% @end -%%------------------------------------------------------------------------------ +%% @doc Add path to trie tree. add_path({Node, Word, Child}) -> Edge = #trie_edge{node_id=Node, word=Word}, case mnesia:read(trie_node, Node) of @@ -162,14 +134,8 @@ add_path({Node, Word, Child}) -> mnesia:write(#trie{edge=Edge, node_id=Child}) end. -%%------------------------------------------------------------------------------ -%% @doc %% @private -%% Match node with word or '+'. -%% -%% @end -%%------------------------------------------------------------------------------ - +%% @doc Match node with word or '+'. match_node(root, [<<"$SYS">>|Words]) -> match_node(<<"$SYS">>, Words, []); @@ -187,13 +153,8 @@ match_node(NodeId, [W|Words], ResAcc) -> end end, 'match_#'(NodeId, ResAcc), [W, '+']). -%%------------------------------------------------------------------------------ -%% @doc %% @private -%% Match node with '#'. -%% -%% @end -%%------------------------------------------------------------------------------ +%% @doc Match node with '#'. 'match_#'(NodeId, ResAcc) -> case mnesia:read(trie, #trie_edge{node_id=NodeId, word = '#'}) of [#trie{node_id=ChildId}] -> @@ -202,13 +163,8 @@ match_node(NodeId, [W|Words], ResAcc) -> ResAcc end. -%%------------------------------------------------------------------------------ -%% @doc %% @private -%% Delete paths from trie tree. -%% -%% @end -%%------------------------------------------------------------------------------ +%% @doc Delete paths from trie tree. delete_path([]) -> ok; delete_path([{NodeId, Word, _} | RestPath]) -> diff --git a/src/emqttd_util.erl b/src/emqttd_util.erl index 8c900433c..0a9936ab7 100644 --- a/src/emqttd_util.erl +++ b/src/emqttd_util.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd utility functions -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Utility functions. +%% @author Feng Lee -module(emqttd_util). -export([apply_module_attributes/1, all_module_attributes/1, cancel_timer/1, diff --git a/src/emqttd_vm.erl b/src/emqttd_vm.erl index edabca44d..3ba5fd598 100644 --- a/src/emqttd_vm.erl +++ b/src/emqttd_vm.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd erlang vm. -%%% -%%% @author huangdan -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd erlang vm. +%% @author @huangdan -module(emqttd_vm). -export([schedulers/0]). diff --git a/src/emqttd_ws_client.erl b/src/emqttd_ws_client.erl index ff46f29d1..454d00344 100644 --- a/src/emqttd_ws_client.erl +++ b/src/emqttd_ws_client.erl @@ -1,30 +1,24 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqttd websocket client -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc emqttd websocket client -module(emqttd_ws_client). +-author("Feng Lee "). + -include("emqttd.hrl"). -include("emqttd_protocol.hrl"). @@ -50,10 +44,7 @@ -define(WSLOG(Level, Format, Args, Req), lager:Level("WsClient(~s): " ++ Format, [Req:get(peer) | Args])). -%%------------------------------------------------------------------------------ %% @doc Start WebSocket client. -%% @end -%%------------------------------------------------------------------------------ start_link(Req) -> PktOpts = emqttd:env(mqtt, packet), ParserFun = emqttd_parser:new(PktOpts), @@ -80,18 +71,12 @@ subscribe(CPid, TopicTable) -> unsubscribe(CPid, Topics) -> gen_server:cast(CPid, {unsubscribe, Topics}). -%%------------------------------------------------------------------------------ %% @private -%% @doc Start WebSocket client. -%% @end -%%------------------------------------------------------------------------------ +%% @doc Upgrade WebSocket. upgrade(Req) -> mochiweb_websocket:upgrade_connection(Req, fun ?MODULE:ws_loop/3). -%%------------------------------------------------------------------------------ %% @doc WebSocket frame receive loop. -%% @end -%%------------------------------------------------------------------------------ ws_loop(<<>>, State, _ReplyChannel) -> State; ws_loop([<<>>], State, _ReplyChannel) -> @@ -118,9 +103,9 @@ ws_loop(Data, State = #wsocket_state{request = Req, reset_parser(State = #wsocket_state{packet_opts = PktOpts}) -> State#wsocket_state{parser_fun = emqttd_parser:new(PktOpts)}. -%%%============================================================================= -%%% gen_server callbacks -%%%============================================================================= +%%-------------------------------------------------------------------- +%% gen_server callbacks +%%-------------------------------------------------------------------- init([WsPid, Req, ReplyChannel, PktOpts]) -> %%issue#413: trap_exit is unnecessary @@ -241,9 +226,9 @@ terminate(Reason, #wsclient_state{proto_state = ProtoState, keepalive = KeepAliv code_change(_OldVsn, State, _Extra) -> {ok, State}. -%%%============================================================================= -%%% Internal functions -%%%============================================================================= +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- with_proto_state(Fun, State = #wsclient_state{proto_state = ProtoState}) -> {ok, ProtoState1} = Fun(ProtoState), diff --git a/src/lager_emqtt_backend.erl b/src/lager_emqtt_backend.erl index bcebc10cf..632623eba 100644 --- a/src/lager_emqtt_backend.erl +++ b/src/lager_emqtt_backend.erl @@ -1,28 +1,21 @@ -%%%----------------------------------------------------------------------------- -%%% Copyright (c) 2012-2016 Feng Lee . All Rights Reserved. -%%% -%%% 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. -%%%----------------------------------------------------------------------------- -%%% @doc emqtt lager backend -%%% -%%% @author Feng Lee -%%%----------------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Copyright (c) 2012-2016 Feng Lee . +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Lager logger backend. +%% @author Feng Lee -module(lager_emqtt_backend). -behaviour(gen_event).