Repository navigation
Releases: GenericJam/mob_nfc
Releases · GenericJam/mob_nfc
Release list
0.1.5
Added
- On-device self-test (MOB-418).
MobNfc.SelfTestimplements
Mob.Plugin.SelfTestand is declared in the manifest asselftest:. It
makes one read-onlynfc_available/0call:truepasses,false(the
native side answered, but there is no radio, as on every simulator and
emulator) is{:skip, :needs_hardware},:disabledis a skip naming the
switched-off radio, and an error answer or the host stub's
nif_not_loadedfails. Run it withmix mob.selftestfrom a host app
(mob_dev 0.7.17).mob_versionin the manifest is now~> 0.9.
Changed
-
Requires mob >= 0.9.15 (was
~> 0.7), forMob.Plugin.SelfTest;
mob_versionin the manifest is now~> 0.9(was~> 0.7). Hosts on
mob 0.7 or 0.8 must upgrade before taking this release. -
Android:
nfc_available/0no longer answersfalsewithout asking the
radio.falsenow means only "no NFC hardware"; the other answers are::disabled: the radio is present but switched off;{:error, :bridge_not_registered}:MobNfcBridge.register()never ran
or the method-id lookup failed;{:error, :no_activity}: the bootstrap hasn't handed the bridge an
Activity;{:error, :no_jni_env}: no JNIEnv could be attached;{:error, :bridge_exception}: the Kotlin side threw (a pending Java
exception is now detected and cleared);{:error, :unknown_state}: the bridge returned a code the NIF doesn't
know.
The Kotlin bridge method is now
nfc_state(): Int(was
nfc_available(): Boolean).MobNfc.available?/0is unchanged (still
falsefor all of these). Method-id lookups innativeRegisternow clear
a pendingNoSuchMethodErrorso one missing method can't poison the rest.
0.1.4
Fixes from the Operator v1 release review (MOB-395).
Changed (behaviour)
- HCE no longer serves while the phone is locked. The contributed
res/xml/mob_nfc_hce_apduservice.xmlnow declares
android:requireDeviceUnlock="true"(was"false"). - HCE emulation is foreground-only and is now stopped on background.
When the host activity pauses (backgrounded, screen off, a permission
prompt / dialog-style activity on top, an activity-recreating config change) the emulated payload is
dropped, the preferred-service claim released,MobNfcApduServicerefuses
every APDU (6A82), and the owner receives{:nfc, :emulation_stopped}.
Previously only the routing preference was released and the payload was
retained and re-armed on resume. Apps that want emulation back must call
MobNfc.emulate_ndef/3again, e.g. on{:mob_device, :did_become_active}. - An
emulate_ndef/3call that passes the up-front checks (size, payload, an
attached activity) but then fails ends any emulation already running, and a
successful one from another process replaces it; the previous owner gets
{:nfc, :emulation_stopped}in both cases. Reader mode is dropped only once
emulation is actually live, so a failed emulate no longer kills a reader
session.
Fixed
emulate_ndef/3no longer claims success on hardware that can't
emulate.{:nfc, :emulation_started}is sent only when the device has
FEATURE_NFC_HOST_CARD_EMULATION, the NFC adapter exists and is enabled,
the activity is resumed, andCardEmulation.setPreferredServicesucceeded.
Otherwise one error arrives instead:{:nfc, :error, :unavailable}
(no NFC / no HCE / app not in the foreground / routing refused),
{:nfc, :error, :disabled}(NFC switched off), matchingstart_reading/2,
or{:nfc, :error, :no_activity}(no host activity attached yet).- NDEF messages larger than the emulated file are rejected. The emulated
tag advertises a 1024-byte NDEF file including the 2-byte NLEN, so
emulate_ndef/3now rejects messages over 1022 bytes with
{:nfc, :error, :too_large}(checked in Elixir before the NIF, and again in
the Android bridge). NewMobNfc.Hce.max_message_size/0,
MobNfc.Hce.check_size/1, andMobNfc.Hce.stop/1(the pure reference for the
stopped-service behaviour);MobNfc.Hce.new/2raises on an oversized message.
0.1.3
Changed
- Signed with the shared mob first-party plugin key (MOB-390).
priv/mob_plugin.pubis now the key shared by the other first-party
mob_*plugins (fingerprint
ed25519:nc56w+1Kx0gIt/4EkHxnMZCKHMzp4+S5kS/HoSzEZkg=), the same key as the other
first-party plugins. Trust is still recorded per plugin name: map
mob_nfc: "ed25519:nc56w+1Kx0gIt/4EkHxnMZCKHMzp4+S5kS/HoSzEZkg="in
config :mob, :trusted_pluginsor runmix mob.plugin.trust mob_nfc. Hosts that
recorded the old per-repo fingerprint for 0.1.2 will get a key-rotation
error; re-runmix mob.plugin.trust mob_nfcor switch the entry to the
shared fingerprint.
0.1.2
Fixed
- Android HCE now claims routing while the app is in the foreground
(MOB-300).emulate_ndef/3calls
CardEmulation.setPreferredServiceforio.mob.nfc.MobNfcApduService
while the host activity is resumed, andunsetPreferredServiceon
stop_emulation/1and when the activity pauses (re-claimed on resume if
still emulating). Previously any other installed app registering the NDEF
AIDD2760000850101competed for routing, so a reader tap could land in
Android's AID-conflict chooser. Skipped on devices without NFC/HCE; the
claim/release results are logged under theMobNfclogcat tag.
0.1.1
Fixed
MobNfc.start_reading/2,write_ndef/3,emulate_ndef/3no longer
crash withUndefinedFunctionError (Jason.encode!/1)in a consumer that
doesn't pull Jason transitively (MOB-80). The three transport helpers
calledJason.encode!whilemix.exsdeclared no:jasondep — Jason
was only present via dev/test tooling (credo, mob_dev). A regular Mob
app on{:mob, "~> 0.7"} + {:mob_nfc, "~> 0.1"}hit the exception on
the first call. Switched all three sites to the built-inJSONstdlib
(Elixir 1.18+, which mix.exs already targets); no runtime dep added.
A source-scanning lint test guards against regression.
Changed
- Android HCE is now turnkey (MOB-39). The HCE
<service>
(io.mob.nfc.MobNfcApduService) is contributed via
android.manifest_application_snippets, and the plugin ships its own
res/xml/mob_nfc_hce_apduservice.xmlandres/values/mob_nfc_strings.xml
viaandroid.res_files— no manual manifest/res edits. The service
description is now@string/mob_nfc_hce_descriptioninstead of
@string/app_name. The manual HCEhost_requirementis removed.
Requires mob_dev ≥ 0.6.19; older mob_dev silently ignores these keys.
Upgrading from 0.1.0 with HCE set up by hand: delete the
<service android:name="io.mob.nfc.MobNfcApduService">block from
android/app/src/main/AndroidManifest.xmland the hand-created
android/app/src/main/res/xml/mob_nfc_apduservice.xml. mob_dev skips a
snippet whoseandroid:nameis already in the manifest, so if you keep
the hand-added<service>it keeps pointing at your old
@xml/mob_nfc_apduservice(still works, but the plugin's file is unused).
The plugin file was renamed so it never collides with the host-owned one. - Re-signed with plugin envelope v2 (MOB-287). mob_dev 0.7.2+ verifies
this signature before evaluating the manifest. mob_dev 0.7.0 / 0.7.1 can't
read v2 signatures and report this release asinvalid signature—
upgrade the host app to{:mob_dev, "~> 0.7.2", only: :dev, runtime: false}.
0.1.0
Added
- Initial release: on-device NFC for Mob apps. (MOB-16)
- Read NDEF messages —
MobNfc.start_reading/2/stop_reading/1open a
reader session; NDEF and tag events arrive as{:nfc, ...}messages.
MobNfc.available?/0reports radio presence + enabled state. - Raw tag UIDs —
start_reading/2withmode: :tagreads a tag's UID/tech
without NDEF (iOSNFCTagReaderSession). - Write NDEF —
MobNfc.write_ndef/3writes an NDEF message to a tag. - Card emulation (HCE) —
MobNfc.emulate_ndef/3/stop_emulation/1
emulate an NDEF tag (read-only or:writable) via AndroidHostApduService.
Android only (iOS has no third-party HCE; it replies:unsupported). - iOS
CoreNFC; AndroidNfcAdapterreader mode + HCE. NDEF parse/encode and
Text/URI helpers inMobNfc.Ndef.
- Read NDEF messages —