Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add assert_loc gatt attribute #21

Merged
merged 1 commit into from Feb 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions include/gateway_config.hrl
Expand Up @@ -15,7 +15,11 @@
-define(MINER_OBJECT(M), ?MINER_INTERFACE ++ "." ++ M).
-define(MINER_MEMBER_PUBKEY, "PubKey").
-define(MINER_MEMBER_ADD_GW, "AddGateway").
-define(MINER_MEMBER_ASSERT_LOC, "AssertLocation").

-define(MINER_ERROR_BADARGS, "com.helium.Miner.Error.BadArgs").
-define(MINER_ERROR_GW_EXISTS, "com.helium.Miner.Error.GatewayExists").
-define(MINER_ERROR_GW_NOT_FOUND, "com.helium.Miner.Error.GatewayNotFound").
-define(MINER_ERROR_ASSERT_LOC_EXISTS, "com.helium.Miner.Error.AssertLocExists").
-define(MINER_ERROR_ASSERT_LOC_PARENT, "com.helium.Miner.Error.AssertLocParent").
-define(MINER_ERROR_INTERNAL, "com.helium.Miner.Error.Internal").
1 change: 1 addition & 0 deletions rebar.config
Expand Up @@ -30,6 +30,7 @@

{deps, [
{jsx, "2.9.0"},
{h3, ".*", {git, "https://github.com/helium/erlang-h3.git", {branch, "master"}}},
{ubx, ".*", {git, "https://github.com/helium/erlang-ubx", {branch, "master"}}},
{ebus, ".*", {git, "https://github.com/helium/ebus", {branch, "master"}}},
{gatt, ".*", {git, "https://github.com/helium/ebus-gatt", {branch, "master"}}},
Expand Down
4 changes: 4 additions & 0 deletions rebar.lock
Expand Up @@ -26,6 +26,10 @@
0},
{<<"getopt">>,{pkg,<<"getopt">>,<<"1.0.1">>},2},
{<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.9">>},1},
{<<"h3">>,
{git,"https://github.com/helium/erlang-h3.git",
{ref,"584d6b20f5b64c8c0a3570d23bebcea2537d68bc"}},
0},
{<<"jsx">>,{pkg,<<"jsx">>,<<"2.9.0">>},0},
{<<"lager">>,{pkg,<<"lager">>,<<"3.6.7">>},0},
{<<"stillir">>,{pkg,<<"stillir">>,<<"1.0.0">>},1},
Expand Down
1 change: 1 addition & 0 deletions src/gateway_gatt.hrl
Expand Up @@ -6,3 +6,4 @@
-define(UUID_GATEWAY_GATT_CHAR_MAC, "9c4314f2-8a0c-45fd-a58d-d4a7e64c3a57").
-define(UUID_GATEWAY_GATT_CHAR_PUBKEY, "0a852c59-50d3-4492-bfd3-22fe58a24f01").
-define(UUID_GATEWAY_GATT_CHAR_ADD_GW, "df3b16ca-c985-4da2-a6d2-9b9b9abdb858").
-define(UUID_GATEWAY_GATT_CHAR_ASSERT_LOC, "d435f5de-01a4-4e7d-84ba-dfd347f60275").
90 changes: 90 additions & 0 deletions src/gateway_gatt_char_assert_loc.erl
@@ -0,0 +1,90 @@
-module(gateway_gatt_char_assert_loc).
-include("gateway_gatt.hrl").
-include("gateway_config.hrl").
-include("pb/gateway_gatt_char_assert_loc_pb.hrl").

-behavior(gatt_characteristic).

-define(H3_LATLON_RESOLUTION, 12).

-export([init/2,
uuid/1,
flags/1,
read_value/1,
write_value/2,
start_notify/1,
stop_notify/1]).

-record(state, {
path :: ebus:object_path(),
proxy :: ebus:proxy(),
notify=false :: boolean(),
value= <<"init">> :: binary()
}).


uuid(_) ->
?UUID_GATEWAY_GATT_CHAR_ASSERT_LOC.

flags(_) ->
[read, notify].

init(Path, [Proxy]) ->
Descriptors =
[
{gatt_descriptor_cud, 0, ["Assert Location"]},
{gatt_descriptor_pf, 1, [opaque]}
],
{ok, Descriptors, #state{path=Path, proxy=Proxy}}.

read_value(State=#state{}) ->
{ok, State#state.value, State}.

write_value(State=#state{}, Bin) ->
case (catch gateway_gatt_char_assert_loc_pb:decode_msg(Bin, gateway_assert_loc_v1_pb)) of
#gateway_assert_loc_v1_pb{lat=Lat, lon=Lon} ->
H3Index = h3:from_geo({Lat, Lon}, ?H3_LATLON_RESOLUTION),
Value = case ebus_proxy:call(State#state.proxy, "/", ?MINER_OBJECT(?MINER_MEMBER_ASSERT_LOC),
[uint64], [H3Index]) of
{ok, [BinTxn]} -> BinTxn;
{error, Error} ->
lager:warning("Failed to get assert_loc txn: ~p", [Error]),
case Error of
?MINER_ERROR_BADARGS -> <<"badargs">>;
?MINER_ERROR_INTERNAL -> <<"error">>;
?MINER_ERROR_GW_NOT_FOUND -> <<"gw_not_found">>;
?MINER_ERROR_ASSERT_LOC_PARENT -> <<"assert_loc_parent">>;
?MINER_ERROR_ASSERT_LOC_EXISTS -> <<"assert_loc_exists">>;
_ -> <<"unknown">>
end
end,
{ok, maybe_notify_value(State#state{value=Value})};
{'EXIT', Why} ->
lager:warning("Failed to decode assert_loc request: ~p", Why),
{ok, maybe_notify_value(State#state{value= <<"badargs">>})}
end.

start_notify(State=#state{notify=true}) ->
%% Already notifying
{ok, State};
start_notify(State=#state{}) ->
{ok, maybe_notify_value(State#state{notify=true})}.


stop_notify(State=#state{notify=false}) ->
%% Already not notifying
{ok, State};
stop_notify(State=#state{}) ->
{ok, State#state{notify=false}}.


%%
%% Internal
%%

maybe_notify_value(State=#state{notify=false}) ->
State;
maybe_notify_value(State=#state{}) ->
gatt_characteristic:value_changed(State#state.path,
State#state.value),
State.
6 changes: 6 additions & 0 deletions src/gateway_gatt_char_assert_loc.proto
@@ -0,0 +1,6 @@
syntax = "proto3";

message assert_loc_v1 {
float lat = 1;
float lon = 2;
}
3 changes: 2 additions & 1 deletion src/gateway_gatt_service.erl
Expand Up @@ -29,7 +29,8 @@ init(_) ->
{value, gateway_config:serial_number()}]},
{gateway_gatt_char_wifi_services, 4, []},
{gateway_gatt_char_pubkey, 5, [MinerProxy]},
{gateway_gatt_char_add_gateway, 6, [MinerProxy]}
{gateway_gatt_char_add_gateway, 6, [MinerProxy]},
{gateway_gatt_char_assert_loc, 7, [MinerProxy]}
],
self() ! enable_wifi,
{ok, Characteristics, #state{}}.
Expand Down