To continue the list of PC/SC wrappers initiated in 2010 with "PC/SC sample in different languages" I now present a new sample code in Elixir.
Elixir uses the Erlang virtual machine: BEAM. I wanted to start with an example in Erlang but Erlang is more complex (for me) so I have not yet a working sample code in Erlang.
I use the PC/SC wrapper for Erlang: erlang-pcsc from Alex Wilson. The project description is "libpcsc NIF binding for erlang". The license is BSD 2 clause.
The wrapper is available on Hex.pm (The package manager for the Erlang ecosystem) at https://hex.pm/packages/pcsc.
API documentation is available at
https://arekinath.github.io/erlang-pcsc/index.html
Elixir sample project
Create a new Elixir project using mix new ...
$ mix new blog * creating README.md * creating .formatter.exs * creating .gitignore * creating mix.exs * creating lib * creating lib/blog.ex * creating test * creating test/test_helper.exs * creating test/blog_test.exs Your Mix project was created successfully. You can use "mix" to compile it, test it, and more: cd blog mix test Run "mix help" for more commands.
Edit the file
[...] defp deps do [ {:pcsc, "~> 1.3"}, ] end [...]
Install the dependency using mix deps.get
$ mix deps.get Resolving Hex dependencies... Dependency resolution completed: New: goldrush 0.1.9 lager 3.9.2 pcsc 1.3.1 * Getting pcsc (Hex package) * Getting lager (Hex package) * Getting goldrush (Hex package)
Source code
Now we create a file
# list card readers {:ok, readers} = :pcsc_card_db.list_readers() # use the fist reader [reader | _] = readers IO.puts("Using reader: " <> reader) # connect to the card {:ok, card} = :pcsc_card.start_link(reader, :shared, [:t1, :t0]) aid = << 160, 0, 0, 0, 98, 3, 1, 12, 6, 1 >> select_apdu = {:apdu_cmd, :default, :iso, :select, 4, 0, aid, :none} # send select APDU {:ok, replies} = :pcsc_card.command(card, select_apdu) IO.inspect replies # send command APDU command_apdu = {:apdu_cmd, :default, :iso, 0, 0, 0, :none, :none} {:ok, replies} = :pcsc_card.command(card, command_apdu) IO.inspect replies # get the first reply only [reply | _] = replies case reply do {:apdu_reply, _, :ok, msg} -> IO.puts(msg) {:apdu_reply, _, :error, _} -> IO.puts("Failed") end
Output
You can now build and run the code using mix run ...
The first time you run mix run
the pcsc wrapper will be built
automatically. After that you only get the build & execution of the sample code.
$ mix run blog.exs 17:40:50.239 [error] calling logger:remove_handler(default) failed: :error {:badmatch, {:error, {:not_found, :default}}} 17:40:50.273 [info] Application lager started on node nonode@nohost 17:40:50.280 [info] Application pcsc started on node nonode@nohost 17:40:50.281 [info] Application blog started on node nonode@nohost Using reader: Gemalto PC Twin Reader 00 00 [{:apdu_reply, :t1, :ok, :none}] [{:apdu_reply, :t1, :ok, "Hello world!"}] Hello world!
Remarks
I do not have any complaints for the Erlang PC/SC wrapper. It built fine on the first try. Nice work Alex.
As always my sample code is very minimal with no error handling. It is just a short sample.
Thanks to Stéphane Bortzmeyer for his Elixir training. That gave me the idea to try Elixir.
A big thank to tofferoma for his help on the Elixir forum on "How to access PCSC card readers via erlang/elixir?".
Conclusion
If you work on a Free Software PC/SC wrapper that is not yet in my list please let me know.