summaryrefslogtreecommitdiff
path: root/p11p-daemon/src/p11p_rpc.erl
diff options
context:
space:
mode:
Diffstat (limited to 'p11p-daemon/src/p11p_rpc.erl')
-rw-r--r--p11p-daemon/src/p11p_rpc.erl86
1 files changed, 85 insertions, 1 deletions
diff --git a/p11p-daemon/src/p11p_rpc.erl b/p11p-daemon/src/p11p_rpc.erl
index a775d30..b04cbbf 100644
--- a/p11p-daemon/src/p11p_rpc.erl
+++ b/p11p-daemon/src/p11p_rpc.erl
@@ -5,10 +5,50 @@
-module(p11p_rpc).
--export([parse/2, new/0, new/1, serialise/1]).
+-export([
+ call_code/1,
+ dump/1,
+ msg_error/2,
+ msg_ok/1,
+ new/0, new/1,
+ parse/2,
+ req_id/1,
+ serialise/1
+ ]).
-include("p11p_rpc.hrl").
+call_code(Msg) ->
+ Msg#p11rpc_msg.call_code.
+
+dump(Msg = #p11rpc_msg{data = Data}) ->
+ {ReqId, Data2} = parse_req_id(Data),
+ {ArgsDesc, Data3} = parse_args_desc(Data2),
+ {Name, _ReqArgs, _RespArgs} = lists:nth(ReqId + 1, ?REQIDS),
+ io_lib:format("RPC [~B]: ~s (~B), args \"~s\":~n~p",
+ [Msg#p11rpc_msg.call_code,
+ Name,
+ ReqId,
+ ArgsDesc,
+ Data3
+ ]).
+
+msg_error(CallCode, ErrorCode) ->
+ DataBuf = serialise_error(ErrorCode),
+ #p11rpc_msg{
+ state = done,
+ call_code = CallCode,
+ opt_len = 0,
+ data_len = size(DataBuf),
+ data = DataBuf}.
+
+msg_ok(CallCode) ->
+ #p11rpc_msg{
+ state = done,
+ call_code = CallCode,
+ opt_len = 0,
+ data_len = 0}.
+
parse(M) ->
parse(M, <<>>).
@@ -44,6 +84,11 @@ parse(#p11rpc_msg{buffer = MsgBuf} = M, DataIn)
{done, Msg}
end.
+req_id(Msg)
+ when Msg#p11rpc_msg.data_len >= 4 ->
+ {ReqId, _} = parse_req_id(Msg#p11rpc_msg.data),
+ ReqId.
+
-spec serialise(p11rpc_msg()) -> binary().
serialise(M) when M#p11rpc_msg.state == done,
M#p11rpc_msg.call_code > -1,
@@ -100,6 +145,44 @@ move_between_binaries(DstIn, SrcIn, NBytes) ->
Src = binary:part(SrcIn, N, size(SrcIn) - N),
{Dst, Src}.
+serialise_byte_array(Bin) ->
+ Len = size(Bin),
+ <<Len:32, Bin/binary>>.
+
+serialise_error(ErrCode) ->
+ ReqId = ?P11_RPC_CALL_ERROR,
+ ArgsDescString = "u", % TODO: look this up and generalise.
+
+ ReqIdBin = serialise_uint32(ReqId),
+ ArgsDescBin = serialise_byte_array(list_to_binary(ArgsDescString)),
+ ArgBin = serialise_uint64(ErrCode),
+
+ <<ReqIdBin/binary, ArgsDescBin/binary, ArgBin/binary>>.
+
+serialise_uint32(U32) ->
+ <<U32:32>>.
+
+serialise_uint64(U64) ->
+ <<U64:64>>.
+
+-spec parse_req_id(binary()) -> {integer(), binary()}.
+parse_req_id(Data) ->
+ {binary:decode_unsigned(binary:part(Data, 0, 4)),
+ binary:part(Data, 4, size(Data) - 4)}.
+
+parse_args_desc(Data) ->
+ parse_byte_array(Data).
+
+-spec parse_byte_array(binary()) -> {binary(), binary()}.
+parse_byte_array(Data) ->
+ case binary:decode_unsigned(binary:part(Data, 0, 4)) of
+ 16#ffffffff ->
+ {<<>>, binary:part(Data, 4, size(Data) - 4)};
+ Len -> % TODO: refuse Len >= 0x7fffffff.
+ {binary:part(Data, 4, Len), binary:part(Data, 4 + Len,
+ size(Data) - 4 - Len)}
+ end.
+
%%%%%%%%%%%%%%
%% Unit tests.
@@ -173,3 +256,4 @@ parse3_test_() ->
{p11rpc_msg, 47, 2, 3, <<"o1">>, <<"d12">>, <<"rest">>, done},
Msg)]
end}.
+