Erlangとビット演算

FeliCaのポーリングで取得できるPMmからコマンドごとのタイムアウト時間を計算する必要が生じたため、Erlangで書いてみました。

PMmの各バイトを、2ビット、3ビット、3ビットに分けて計算するので、まずは取り出してみましょう。

4> <<E:2, B:3, A:3>> = <<2#10011101>>.
<<157>>
5> E.
2
6> B.
3
7> A.
5

この手の処理はErlangで書くととても楽ちんですね。後は定義に従ってコードを書きます。

-module(pmm).
-compile(export_all).

decode(P, N) ->
    <<E:2, B:3, A:3>> = <<P>>,
    0.3020 * ((B + 1) * N + (A + 1)) * math:pow(4, E).

decode_pmm(PMm, N) ->
    <<_D8, _D9, D10, D11, D12, D13, D14, D15>> = PMm,
    [
     {'PMm', PMm},
     {request_service, decode(D10, N)},
     {request_response_and_request_system_code, decode(D11, 0)},
     {authentication, decode(D12, N)},
     {read, decode(D13, N)},
     {write, decode(D14, N)},
     {issue, decode(D15, 0)}].

Nは対象のブロック数です(場合によってはサービス数も含みます)。どれどれ...

8> 
pmm:decode_pmm(<<16#01, 16#10, 16#8B, 16#42, 16#8F, 16#BE, 16#CB, 16#FF>>, 5).
[{'PMm',<<1,16,139,66,143,190,203,255>>},
 {request_service,67.648},
 {request_response_and_request_system_code,
     3.6239999999999997},
 {authentication,86.976},
 {read,227.10399999999998},
 {write,270.592},
 {issue,154.624}]
9> 

よい感じのようです。