diff --git a/apps/iot/src/iot_device.erl b/apps/iot/src/iot_device.erl index 2f5da92..cf7cfcb 100644 --- a/apps/iot/src/iot_device.erl +++ b/apps/iot/src/iot_device.erl @@ -10,7 +10,7 @@ -include("iot.hrl"). %% API --export([new/1, is_activated/1, change_status/2, reload/1, auth/2]). +-export([new/1, change_status/2, reload/1]). %% 终端是否授权 -define(DEVICE_AUTH_DENIED, 0). @@ -22,7 +22,6 @@ -record(device, { device_uuid :: binary(), - auth_state = ?STATE_DENIED, status = ?DEVICE_OFFLINE }). @@ -33,18 +32,14 @@ -spec new(DeviceInfo :: binary() | map()) -> error | {ok, Device :: #device{}}. new(DeviceUUID) when is_binary(DeviceUUID) -> case iot_api:get_device_by_uuid(DeviceUUID) of - {ok, #{<<"device_uuid">> := DeviceUUID, <<"authorize_status">> := AuthorizeStatus, <<"status">> := Status}} -> - {ok, #device{device_uuid = DeviceUUID, status = Status, auth_state = auth_state(AuthorizeStatus)}}; + {ok, #{<<"device_uuid">> := DeviceUUID, <<"status">> := Status}} -> + {ok, #device{device_uuid = DeviceUUID, status = Status}}; undefined -> lager:warning("[iot_device] device uuid: ~p, loaded from mysql failed", [DeviceUUID]), error end; -new(#{<<"device_uuid">> := DeviceUUID, <<"authorize_status">> := AuthorizeStatus, <<"status">> := Status}) -> - {ok, #device{device_uuid = DeviceUUID, status = Status, auth_state = auth_state(AuthorizeStatus)}}. - --spec is_activated(Device :: #device{}) -> boolean(). -is_activated(#device{auth_state = AuthState}) -> - AuthState =:= ?STATE_ACTIVATED. +new(#{<<"device_uuid">> := DeviceUUID, <<"status">> := Status}) -> + {ok, #device{device_uuid = DeviceUUID, status = Status}}. -spec change_status(Device :: #device{}, NewStatus :: integer()) -> NDevice :: #device{}. change_status(Device = #device{status = Status}, NewStatus) when is_integer(NewStatus), Status =:= NewStatus -> @@ -70,35 +65,9 @@ change_status(Device = #device{device_uuid = DeviceUUID}, ?DEVICE_OFFLINE) -> reload(Device = #device{device_uuid = DeviceUUID}) -> lager:debug("[iot_device] will reload: ~p", [DeviceUUID]), case iot_api:get_device_by_uuid(DeviceUUID) of - {ok, #{<<"authorize_status">> := AuthorizeStatus, <<"status">> := Status}} -> - {ok, Device#device{device_uuid = DeviceUUID, status = Status, auth_state = auth_state(AuthorizeStatus)}}; + {ok, #{<<"status">> := Status}} -> + {ok, Device#device{device_uuid = DeviceUUID, status = Status}}; undefined -> lager:warning("[iot_device] device uuid: ~p, loaded from mysql failed", [DeviceUUID]), error - end. - --spec auth(Device :: #device{}, Auth :: boolean()) -> NDevice :: #device{}. -auth(Device = #device{auth_state = StateName, device_uuid = DeviceUUID}, Auth) when is_boolean(Auth) -> - case {StateName, Auth} of - {?STATE_DENIED, false} -> - lager:debug("[iot_device] device_uuid: ~p, auth: false, will keep state_name: ~p", [DeviceUUID, ?STATE_DENIED]), - Device; - {?STATE_DENIED, true} -> - Device#device{auth_state = ?STATE_ACTIVATED}; - {?STATE_ACTIVATED, false} -> - lager:debug("[iot_device] device_uuid: ~p, auth: false, state_name from: ~p, to: ~p", [DeviceUUID, ?STATE_ACTIVATED, ?STATE_DENIED]), - Device#device{auth_state = ?STATE_DENIED}; - {?STATE_ACTIVATED, true} -> - lager:debug("[iot_device] device_uuid: ~p, auth: true, will keep state_name: ~p", [DeviceUUID, ?STATE_ACTIVATED]), - Device - end. - -%%%=================================================================== -%%% Internal functions -%%%=================================================================== - --spec auth_state(integer()) -> atom(). -auth_state(?DEVICE_AUTH_AUTHED) -> - ?STATE_ACTIVATED; -auth_state(?DEVICE_AUTH_DENIED) -> - ?STATE_DENIED. \ No newline at end of file + end. \ No newline at end of file diff --git a/apps/iot/src/iot_host.erl b/apps/iot/src/iot_host.erl index bf68e7e..eb42f61 100644 --- a/apps/iot/src/iot_host.erl +++ b/apps/iot/src/iot_host.erl @@ -27,7 +27,7 @@ -export([pub/3, attach_channel/2, command/3]). -export([deploy_container/3, start_container/2, stop_container/2, remove_container/2, kill_container/2, config_container/3, get_containers/1, await_reply/2]). %% 设备管理 --export([reload_device/2, delete_device/2, activate_device/3]). +-export([reload_device/2, delete_device/2]). -export([heartbeat/1]). %% gen_statem callbacks @@ -159,10 +159,6 @@ reload_device(Pid, DeviceUUID) when is_pid(Pid), is_binary(DeviceUUID) -> delete_device(Pid, DeviceUUID) when is_pid(Pid), is_binary(DeviceUUID) -> gen_statem:call(Pid, {delete_device, DeviceUUID}). --spec activate_device(Pid :: pid(), DeviceUUID :: binary(), Auth :: boolean()) -> ok | {error, Reason :: any()}. -activate_device(Pid, DeviceUUID, Auth) when is_pid(Pid), is_binary(DeviceUUID), is_boolean(Auth) -> - gen_statem:call(Pid, {activate_device, DeviceUUID, Auth}). - -spec heartbeat(Pid :: pid()) -> no_return(). heartbeat(undefined) -> ok; @@ -340,41 +336,20 @@ handle_event({call, From}, {reload_device, DeviceUUID}, _, State = #state{device handle_event({call, From}, {delete_device, DeviceUUID}, _, State = #state{device_map = DeviceMap}) -> {keep_state, State#state{device_map = maps:remove(DeviceUUID, DeviceMap)}, [{reply, From, ok}]}; -%% 激活设备 -handle_event({call, From}, {activate_device, DeviceUUID, Auth}, _, State = #state{device_map = DeviceMap}) -> - case maps:find(DeviceUUID, DeviceMap) of - error -> - {keep_state, State, [{reply, From, {error, <<"device not found">>}}]}; - {ok, Device} -> - NDevice = iot_device:auth(Device, Auth), - {keep_state, State#state{device_map = maps:put(DeviceUUID, NDevice, DeviceMap)}, [{reply, From, ok}]} - end; - %% todo handle_event(cast, {handle, {data, #data{service_id = ServiceId, device_uuid = DeviceUUID, route_key = RouteKey0, metric = Metric}}}, ?STATE_ACTIVATED, State = #state{uuid = UUID, has_session = true, device_map = DeviceMap}) -> lager:debug("[iot_host] metric_data host: ~p, service_id: ~p, device_uuid: ~p, route_key: ~p, metric: ~p", [UUID, ServiceId, DeviceUUID, RouteKey0, Metric]), - case DeviceUUID =/= <<"">> of - true -> - case maps:find(DeviceUUID, DeviceMap) of - error -> - lager:warning("[iot_host] host uuid: ~p, device uuid: ~p not found, metric: ~p", [UUID, DeviceUUID, Metric]), - {keep_state, State}; - {ok, Device} -> - case iot_device:is_activated(Device) of - true -> - RouteKey = get_route_key(RouteKey0), - endpoint_subscription:publish(RouteKey, ServiceId, Metric), - NDevice = iot_device:change_status(Device, ?DEVICE_ONLINE), - {keep_state, State#state{device_map = maps:put(DeviceUUID, NDevice, DeviceMap)}}; - false -> - lager:warning("[iot_host] host uuid: ~p, device_uuid: ~p not activated, metric: ~p", [UUID, DeviceUUID, Metric]), - {keep_state, State} - end - end; - false -> - {keep_state, State} + case maps:find(DeviceUUID, DeviceMap) of + error -> + lager:warning("[iot_host] host uuid: ~p, device uuid: ~p not found, metric: ~p", [UUID, DeviceUUID, Metric]), + {keep_state, State}; + {ok, Device} -> + RouteKey = get_route_key(RouteKey0), + endpoint_subscription:publish(RouteKey, ServiceId, Metric), + NDevice = iot_device:change_status(Device, ?DEVICE_ONLINE), + {keep_state, State#state{device_map = maps:put(DeviceUUID, NDevice, DeviceMap)}} end; %% ping的数据是通过aes加密后的,因此需要在有会话的情况下才行 diff --git a/apps/iot/src/iot_name_server.erl b/apps/iot/src/iot_name_server.erl deleted file mode 100644 index 92e7a33..0000000 --- a/apps/iot/src/iot_name_server.erl +++ /dev/null @@ -1,137 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2025, -%%% @doc -%%% -%%% @end -%%% Created : 17. 8月 2025 00:26 -%%%------------------------------------------------------------------- --module(iot_name_server). --author("anlicheng"). - --behaviour(gen_server). - -%% API --export([start_link/0]). --export([whereis_alias/1, register/2]). - -%% gen_server callbacks --export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). - --define(SERVER, ?MODULE). --define(TAB, iot_name_server). - --record(state, { - %% #{Pid => Name} - pid_names = #{}, - refs = [] -}). - -%%%=================================================================== -%%% API -%%%=================================================================== - --spec register(Name :: atom(), Pid :: pid()) -> ok. -register(Name, Pid) when is_atom(Name), is_pid(Pid) -> - gen_server:call(?SERVER, {register, Name, Pid}). - --spec whereis_alias(Name :: atom()) -> undefined | pid(). -whereis_alias(Name) when is_atom(Name) -> - case ets:lookup(?TAB, Name) of - [] -> - undefined; - [{Name, Pid}|_] -> - case is_process_alive(Pid) of - true -> - Pid; - false -> - undefined - end - end. - -%% @doc Spawns the server and registers the local name (unique) --spec(start_link() -> - {ok, Pid :: pid()} | ignore | {error, Reason :: term()}). -start_link() -> - gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). - -%%%=================================================================== -%%% gen_server callbacks -%%%=================================================================== - -%% @private -%% @doc Initializes the server --spec(init(Args :: term()) -> - {ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} | - {stop, Reason :: term()} | ignore). -init([]) -> - %% 初始化存储 - ets:new(?TAB, [named_table, ordered_set, public, {keypos, 1}]), - {ok, #state{}}. - -%% @private -%% @doc Handling call messages --spec(handle_call(Request :: term(), From :: {pid(), Tag :: term()}, - State :: #state{}) -> - {reply, Reply :: term(), NewState :: #state{}} | - {reply, Reply :: term(), NewState :: #state{}, timeout() | hibernate} | - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), Reply :: term(), NewState :: #state{}} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_call({register, Name, Pid}, _From, State = #state{refs = Refs, pid_names = PidNames}) -> - true = ets:insert(?TAB, {Name, Pid}), - MRef = erlang:monitor(process, Pid), - {reply, ok, State#state{refs = [MRef|Refs], pid_names = maps:put(Pid, Name, PidNames)}}. - -%% @private -%% @doc Handling cast messages --spec(handle_cast(Request :: term(), State :: #state{}) -> - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_cast(_Request, State = #state{}) -> - {noreply, State}. - -%% @private -%% @doc Handling all non call/cast messages --spec(handle_info(Info :: timeout() | term(), State :: #state{}) -> - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_info({'DOWN', MRef, process, Pid, Reason}, State = #state{refs = Refs, pid_names = PidNames}) -> - % lager:debug("[iot_name_server] pid: ~p, down with reason: ~p", [Reason]), - case lists:member(MRef, Refs) of - true -> - case maps:take(Pid, PidNames) of - error -> - {noreply, State#state{refs = lists:delete(MRef, Refs)}}; - {Name, NPidNames} -> - true = ets:delete(?TAB, Name), - {noreply, State#state{pid_names = NPidNames, refs = lists:delete(MRef, Refs)}} - end; - false -> - {noreply, State} - end. - -%% @private -%% @doc This function is called by a gen_server when it is about to -%% terminate. It should be the opposite of Module:init/1 and do any -%% necessary cleaning up. When it returns, the gen_server terminates -%% with Reason. The return value is ignored. --spec(terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()), - State :: #state{}) -> term()). -terminate(_Reason, _State = #state{}) -> - ok. - -%% @private -%% @doc Convert process state when code is changed --spec(code_change(OldVsn :: term() | {down, term()}, State :: #state{}, - Extra :: term()) -> - {ok, NewState :: #state{}} | {error, Reason :: term()}). -code_change(_OldVsn, State = #state{}, _Extra) -> - {ok, State}. - -%%%=================================================================== -%%% Internal functions -%%%=================================================================== diff --git a/apps/iot/src/iot_sup.erl b/apps/iot/src/iot_sup.erl index 57ab0be..c84a665 100644 --- a/apps/iot/src/iot_sup.erl +++ b/apps/iot/src/iot_sup.erl @@ -37,15 +37,6 @@ init([]) -> modules => ['iot_event_stream_observer'] }, - #{ - id => 'iot_name_server', - start => {'iot_name_server', start_link, []}, - restart => permanent, - shutdown => 2000, - type => worker, - modules => ['iot_name_server'] - }, - #{ id => endpoint_sup_sup, start => {'endpoint_sup_sup', start_link, []},