diff --git a/apps/roster/src/protocol/roster_presence.erl b/apps/roster/src/protocol/roster_presence.erl index 80d7202ef810fbf2024622edf964723ad67e4bca..b512d067e27f3a43ff7f3a2303b5acc4c129783c 100644 --- a/apps/roster/src/protocol/roster_presence.erl +++ b/apps/roster/src/protocol/roster_presence.erl @@ -9,36 +9,31 @@ info(#'Presence'{status=Status} = RequestData, Req, #cx{params = ClientId, clien ?LOG_INFO("~p:Presence/Status:~p", [ClientId, RequestData]), {reply, {bert, send_presence(Status, roster:phone_id(ClientId), C)}, Req, State}. - on_connect(Phone, ClientId, C)-> on_connect(Phone, ClientId, C, ?VERSION). on_connect(Phone, ClientId, C, Ver) -> ?LOG_INFO("~p:~p:CONNECT with Version:~p", [Phone, ClientId,Ver]), try case send_presence(online, Phone, C, ClientId) of - {error, profile_not_found} -> ?LOG_INFO("~p:~p:Connect:ProfileNotFound", [Phone, ClientId]), + {error, profile_not_found} -> + ?LOG_INFO("~p:~p:Connect:ProfileNotFound", [Phone, ClientId]), roster:delete_sessions(Phone); - #'Profile'{} when Ver==?VERSION -> + #'Profile'{} when Ver == ?VERSION -> roster:send_cache(ClientId, C); - #'Profile'{} = P-> - roster:send_profile(P#'Profile'{settings = amazon_settings(P), status = init}, [], 0, ClientId, C), + #'Profile'{} = P -> + P2 = P#'Profile'{settings = amazon_settings(P), status = init}, + roster:send_profile(P2, [], 0, ClientId, C), roster:send_cache(ClientId, C) end catch Err:Rea -> ?LOG_INFO("Catch:~p", [n2o:stack_trace(Err, Rea)]) end. -on_disconnect(#'Auth'{type = logout, phone = Phone, client_id = ClientId}, C) -> - ?LOG_INFO("~p:~p:DISCONNECT:LOGOUT", [Phone, ClientId]), - send_presence(offline, Phone, C, ClientId), - roster:unsubscribe_client(ClientId), - kvs:delete('Auth', ClientId), - roster:final_disconnect(ClientId); - -on_disconnect(#'Auth'{type = disconnect, phone = Phone, client_id = ClientId}, C) -> - ?LOG_INFO("~p:~p:DISCONNECT", [Phone, ClientId]), +on_disconnect(#'Auth'{type = Type, phone = Phone, client_id = ClientId}, C) + when Type == logout; Type == disconnect -> + ?LOG_INFO("~p:~p:DISCONNECT - ~p", [Phone, ClientId, Type]), send_presence(offline, Phone, C, ClientId), roster:unsubscribe_client(ClientId), - case should_preserve_auth_record(ClientId) of + case Type == disconnect andalso should_preserve_auth_record(ClientId) of true -> ok; false -> kvs:delete('Auth', ClientId) end, @@ -63,17 +58,15 @@ send_presence(Status, Phone, C, ClientId) when Status == online; Status == offli case kvs:get('Profile', Phone) of {ok, #'Profile'{rosters = Rosters} = P} -> case [ok || #'Auth'{client_id = CliId} <- kvs:index('Auth', phone, Phone), - ClientId /= CliId, emqttd_cm:lookup_proc(CliId) /= undefined] of + ClientId /= CliId, emqttd_cm:lookup_proc(CliId) /= undefined] of [] -> - kvs:put(P2 = P#'Profile'{presence = Status, update = Now = roster:now_msec()}), - [case kvs:get('Roster', AccId) of - {ok, #'Roster'{phone = Phone}} -> - PhoneId = roster:phone_id(Phone, AccId), - [roster:Send(C, PhoneId, #'Contact'{phone_id = PhoneId, - presence = Status, update = Now, status = internal}) || Send <- [send_muc, send_ac]]; - {error, _} -> skip - end || AccId <- Rosters], - P2; + Now = roster:now_msec(), + P2 = P#'Profile'{presence = Status, update = Now}, + kvs:put(P2), + MkContact = fun(PId) -> #'Contact'{phone_id = PId, presence = Status, + update = Now, status = internal} end, + [do_send_presence(C, RId, MkContact) || RId <- Rosters], + P2; _ -> ?LOG_INFO("~p:~p:~p",[Phone, ClientId,P]), P @@ -81,23 +74,33 @@ send_presence(Status, Phone, C, ClientId) when Status == online; Status == offli _ -> {error, profile_not_found} end. - send_presence(Status, PhoneId, C) -> case kvs:get('Profile', roster:phone(PhoneId)) of {ok, #'Profile'{rosters = Rosters} = P} -> - kvs:put(P#'Profile'{presence = Status, update = roster:now_msec()}), - [case kvs:get('Roster', AccId) of - {ok, #'Roster'{phone = Phone}} -> - PId = roster:phone_id(Phone, AccId), - [roster:Send(C, PhoneId, #'Presence'{uid = PId, - status = Status}) || Send <- [send_muc, send_ac]]; - #error{} -> skip - end || AccId <- Rosters], #'Presence'{uid = PhoneId, status = Status}; - _ -> {error, profile_not_found} end. + kvs:put(P#'Profile'{presence = Status, update = roster:now_msec()}), + MkPresence = fun(PId) -> #'Presence'{uid = PId, status = Status} end, + [do_send_presence(C, RId, MkPresence) || RId <- Rosters], + #'Presence'{uid = PhoneId, status = Status}; + _ -> + {error, profile_not_found} + end. + +do_send_presence(C, RosterId, MkRec) -> + case kvs:get('Roster', RosterId) of + {ok, #'Roster'{phone = Phone}} -> + PhoneId = roster:phone_id(Phone, RosterId), + Object = MkRec(PhoneId), + roster:send_muc(C, PhoneId, Object), + roster:send_ac(C, PhoneId, Object); + #error{} -> + skip + end. %% AWS keys for android build verification by Google Play Market amazon_settings(#'Profile'{phone = ProfileId, settings = Settings}) -> - StaticFeatures = lists:foldl(fun({Key, Value}, Acc) -> - Acc ++ [#'Feature'{id = iolist_to_binary([ProfileId, Key]), key = Key, value = Value, group = <<"SPECIAL_ANDROID_KEYS">>}] - end, [], [{<<"ACCESS_KEY">>, ?AWS_ACCESS_KEY_ID}, {<<"SECRET_KEY">>, ?AWS_SECRET_ACCESS_KEY}]), - Settings ++ StaticFeatures. + PId = fun(Key) -> iolist_to_binary([ProfileId, Key]) end, + Feat = fun(Key, Val) -> #'Feature'{id = PId(Key), key = Key, value = Val, + group = <<"SPECIAL_ANDROID_KEYS">>} end, + + Settings ++ [Feat(<<"ACCESS_KEY">>, ?AWS_ACCESS_KEY_ID), + Feat(<<"SECRET_KEY">>, ?AWS_SECRET_ACCESS_KEY)].