summaryrefslogtreecommitdiff
path: root/components/dlink_bt/src/dlink_bt_rpc.erl
diff options
context:
space:
mode:
authorMagnus Feuer <mfeuer@jaguarlandrover.com>2015-05-31 14:22:58 -0700
committerMagnus Feuer <mfeuer@jaguarlandrover.com>2015-06-09 13:52:10 -0700
commit7d3319917243563410e8f75f29826f9b0f49b2b9 (patch)
tree84a9e0955757f6fec0adaf81d329ddc352f3c431 /components/dlink_bt/src/dlink_bt_rpc.erl
parentae4f8252471077f641dc8aed5d0721508d185a08 (diff)
downloadrvi_core-7d3319917243563410e8f75f29826f9b0f49b2b9.tar.gz
Now connects, registers, and invokes services over BT. dlink_bt now feature complete. Fixed ping
Diffstat (limited to 'components/dlink_bt/src/dlink_bt_rpc.erl')
-rw-r--r--components/dlink_bt/src/dlink_bt_rpc.erl144
1 files changed, 94 insertions, 50 deletions
diff --git a/components/dlink_bt/src/dlink_bt_rpc.erl b/components/dlink_bt/src/dlink_bt_rpc.erl
index 745dd9d..05c4328 100644
--- a/components/dlink_bt/src/dlink_bt_rpc.erl
+++ b/components/dlink_bt/src/dlink_bt_rpc.erl
@@ -243,6 +243,7 @@ connect_and_retry_remote( BTAddr, Channel, CompSpec) ->
end.
+
announce_local_service_(_CompSpec, [], _Service, _Availability) ->
ok;
@@ -251,8 +252,16 @@ announce_local_service_(CompSpec,
Service, Availability) ->
Res = bt_connection:send(ConnPid,
- term_to_binary({service_announce, 3, Availability,
- [Service], { signature, {}}})),
+ term_to_json(
+ { struct,
+ [
+ { "cmd", "service_announce" },
+ { "tid", 3},
+ { "status", atom_to_list(Availability) },
+ { "services", { array, [Service]} },
+ { "signature", "" }
+ ]
+ })),
?debug("dlink_bt:announce_local_service(~p: ~p) -> ~p Res: ~p",
[ Availability, Service, ConnPid, Res]),
@@ -278,18 +287,15 @@ process_data(_FromPid, RemoteBTAddr, RemoteChannel, ProtocolMod, Data, CompSpec)
process_announce(FromPid, RemoteBTAddr, RemoteChannel,
- TransactionID, available, Services,
+ TransactionID, "available", { array, Services},
Signature, CompSpec) ->
?debug("dlink_bt:service_announce(available): Address: ~p-~p", [ RemoteBTAddr, RemoteChannel ]),
?debug("dlink_bt:service_announce(available): TransactionID: ~p", [ TransactionID ]),
?debug("dlink_bt:service_announce(available): Signature: ~p", [ Signature ]),
?debug("dlink_bt:service_announce(available): Service: ~p", [ Services ]),
-
%% Register the received services with all relevant components
-
add_services(Services, FromPid),
-
service_discovery_rpc:register_services(CompSpec, Services, ?MODULE),
ok;
@@ -298,8 +304,8 @@ process_announce(FromPid,
RemoteBTAddr,
RemoteChannel,
TransactionID,
- unavailable,
- Services,
+ "unavailable",
+ {array, Services},
Signature ,
CompSpec) ->
?debug("dlink_bt:service_announce(unavailable): Address: ~p-~p",
@@ -313,7 +319,6 @@ process_announce(FromPid,
%% Delete from our own tables.
-
delete_services(FromPid, Services),
service_discovery_rpc:unregister_services(CompSpec, Services, ?MODULE),
ok.
@@ -337,7 +342,6 @@ process_authorize(FromPid,
?debug("dlink_bt:authorize(): Signature: ~p", [ Signature ]),
- { LocalAddress, LocalChannel } = rvi_common:node_address_tuple(),
%% If FromPid (the genserver managing the socket) is not yet registered
%% with the conneciton manager, this is an incoming connection
@@ -350,11 +354,17 @@ process_authorize(FromPid,
?info("dlink_bt:authorize(): New connection!"),
bt_connection_manager:add_connection(RemoteAddress, RemoteChannel, FromPid),
?debug("dlink_bt:authorize(): Sending authorize."),
+ {ok,[{address, Address }]} = bt_drv:local_info([address]),
Res = bt_connection:send(FromPid,
- term_to_binary(
- { authorize,
- 1, LocalAddress, LocalChannel, rvi_json,
- {certificate, {}}, { signature, {}}})),
+ term_to_json(
+ {struct,
+ [ { "tid", 1 },
+ { "cmd", "authorize" },
+ { "addr", bt_address_to_string(Address) },
+ { "chan", RemoteChannel },
+ { "rvi_proto", "rvi_json" },
+ { "certificate", "" },
+ { "signature", "" } ]})),
?debug("dlink_bt:authorize(): Sending authorize: ~p", [ Res]),
ok;
_ -> ok
@@ -370,51 +380,62 @@ process_authorize(FromPid,
[LocalServices, RemoteAddress, RemoteChannel]),
bt_connection:send(FromPid,
- term_to_binary(
- { service_announce, 2, available,
- LocalServices, { signature, {}}})),
+ term_to_json(
+ {struct,
+ [ { "tid", 1 },
+ { "cmd", "service_announce" },
+ { "status", "available" },
+ { "services", { array, LocalServices }},
+ { "signature", "" } ]})),
%% Setup ping interval
- gen_server:call(?SERVER, { setup_initial_ping, RemoteAddress, RemoteChannel, FromPid }),
+ gen_server:call(?SERVER, { setup_initial_ping, PeerBTChannel, RemoteChannel, FromPid }),
ok.
handle_socket(FromPid, PeerBTAddr, PeerChannel, data,
- Data, CompSpec) ->
+ Payload, CompSpec) ->
+
+ {ok, {struct, Elems}} = exo_json:decode_string(binary_to_list(Payload)),
+ ?debug("dlink_bt:data(): Got ~p", [ Elems ]),
+
+ case opt("cmd", Elems, undefined) of
+ "authorize" ->
+ [ TransactionID, RemoteAddress, RemoteChannel,
+ RVIProtocol, Certificate, Signature ] =
+ opts(["tid", "addr", "channel", "rvi_proto",
+ "certificate", "signature"], Elems, undefined),
- try binary_to_term(Data) of
- { authorize, TransactionID, RemoteAddress, RemoteChannel,
- Protocol, Certificate, Signature} ->
process_authorize(FromPid, PeerBTAddr, RemoteChannel,
TransactionID, RemoteAddress, RemoteChannel,
- Protocol, Certificate, Signature, CompSpec);
-
- { service_announce, TransactionID, Available, Services, Signature } ->
- process_announce(FromPid, PeerBTAddr, PeerChannel,
- TransactionID, Available, Services,
- Signature, CompSpec);
+ RVIProtocol, Certificate, Signature, CompSpec);
- { receive_data, ProtocolMod, Data } ->
- process_data(FromPid, PeerBTAddr, PeerChannel,
- ProtocolMod, Data, CompSpec);
- ping ->
+ "service_announce" ->
+ [ TransactionID, Available, Services, Signature ] =
+ opts(["tid", "status", "services", "signature"],
+ Elems, undefined),
+
+ process_announce(FromPid, PeerBTAddr, PeerChannel,
+ TransactionID, Available, Services,
+ Signature, CompSpec);
+ "receive_data" ->
+ [ _TransactionID, ProtocolMod, Payload ] =
+ opts(["tid", "proto_mod", "paylaod"],
+ Elems, undefined),
+ process_data(FromPid, PeerBTAddr, PeerChannel,
+ ProtocolMod, Payload, CompSpec);
+
+ "ping" ->
?info("dlink_bt:ping(): Pinged from: ~p:~p", [ PeerBTAddr, PeerChannel]),
ok;
- Unknown ->
- ?warning("dlink_bt:handle_socket(): Unknown data: ~p", [ Unknown]),
+ undefined ->
+ ?warning("dlink_bt:data() cmd undefined., ~p", [ Elems ]),
ok
- catch
- _:_ ->
- ?warning("dlink_bt:handle_socket(data): Data could not be decoded: ~p",
- [ Data]),
- ok
-
end.
-
%% We lost the socket connection.
%% Unregister all services that were routed to the remote end that just died.
handle_socket(FromPid, SetupBTAddr, SetupChannel, closed, CompSpec) ->
@@ -464,12 +485,15 @@ handle_socket(FromPid, SetupBTAddr, SetupChannel, connected, _ExtraArgs) ->
{ok,[{address, Address }]} = bt_drv:local_info([address]),
bt_connection:send(FromPid,
- term_to_binary(
- { authorize,
- 1,
- bt_address_to_string(Address),
- SetupChannel, rvi_json,
- { certificate, {}}, { signature, {}} })),
+ term_to_json(
+ {struct,
+ [ { "tid", 1 },
+ { "cmd", "authorize" },
+ { "addr", bt_address_to_string(Address) },
+ { "chan", SetupChannel },
+ { "rvi_proto", "rvi_json" },
+ { "certificate", "" },
+ { "signature", "" } ]})),
ok;
@@ -613,8 +637,14 @@ handle_call({rvi, send_data, [ProtoMod, Service, Data, _DataLinkOpts]}, _From, S
%% FIXME: What to do if we have multiple connections to the same service?
[ConnPid | _T] ->
Res = bt_connection:send(ConnPid,
- term_to_binary(
- {receive_data, ProtoMod, Data})),
+ term_to_json(
+ {struct,
+ [ { "tid", 1 },
+ { "cmd", "receive_ddata" },
+ { "proto_mod", ProtoMod },
+ { "payload", Data }
+ ]})),
+
{ reply, [ Res ], St}
end;
@@ -649,7 +679,8 @@ handle_info({ rvi_ping, Pid, Address, Channel, Timeout}, St) ->
case bt_connection:is_connection_up(Pid) of
true ->
?info("dlink_bt:ping(): Pinging: ~p:~p", [Address, Channel]),
- bt_connection:send(Pid, term_to_binary(ping)),
+ bt_connection:send(Pid, term_to_json({ struct, [ { "cmd", "ping" }]})),
+
erlang:send_after(Timeout, self(),
{ rvi_ping, Pid, Address, Channel, Timeout });
@@ -762,3 +793,16 @@ get_connections(Key, Acc) ->
get_connections() ->
get_connections(ets:first(?CONNECTION_TABLE), []).
+
+
+term_to_json(Term) ->
+ binary_to_list(iolist_to_binary(exo_json:encode(Term))).
+
+opt(K, L, Def) ->
+ case lists:keyfind(K, 1, L) of
+ {_, V} -> V;
+ false -> Def
+ end.
+
+opts(Keys, Elems, Def) ->
+ [ opt(K, Elems, Def) || K <- Keys].