2016年9月29日

CUDA 8が正式リリース

CUDA Toolkit | NVIDIA Developer

ようやく、CUDA 8が正式リリースされました。
と、わざわざ書くと、私がcaffeとかですごくCUDAを使っていて毎日監視しているように見えますが、単にNVIDIAからメールが届いただけでした。

 

うちがXubuntu16.04環境なので、Ubunt16.04で使えるものがアカウント無しでダウンロードできるようになったというのがありがたいです。

最近やっていないから、また忘れてしまった。。

Arduinoライブラリをどうしたらよいかだんだんわからなくなる

最初、あまり読まずに私がC++でやるときのルールで実装していった。

  • 公開する整数定数は、publicのstatic constに書く
  • 同じく、enumもpublicに書く
  • 最初に設定したら変更しないものは、コンストラクタでもらうようにする
  • コンストラクタでオブジェクトのポインタをもらうなら、参照でもらうようにすることも考える

 

そう実装してから他のライブラリをちらっと見たのだが、そういう実装ではなさそうだった。

  • 定数は#defineにする
  • enumは使ってない?
  • 参照を使っているところは見つけられなかった

 

Arduinoとしてはマクロはあまり使わないようなことを書いていた気がするのだけど、今見直したら書いていないな。
マクロ名も、クラスに関係しているかどうかとか気にせず、やたら短かった。
あんまり短いと、誰かとぶつかって困る羽目になりそうなのだが。。。

 

結局私も、static constやenumはやめて、#defineに置き換えることにした。
ただ、短い#defineだと衝突しそうなので、クラス名の一部をプレフィクスに付けた。
多少はましだろう。

 

あまり時間を掛けたい作業ではないのだけど、ルールがあるものは仕方が無い。
全部に従うことは無いにしても、不自然で無いようにはしたいものだ。
が、自信はないな。。。

2016年9月27日

Arduinoっぽいコーディングを調べる

Arduinoライブラリを作ることになったが、そもそもArduinoをあまり使ったことが無い。
どういうルールで書くとそれっぽくなるのだろう?

 

Arduino - StyleGuide
Arduino - APIStyleGuide
短いけど、読みづらい。。。。
幸い、日本語で訳している人のページがあった。
他のライブラリを見た調査もあって、ありがたい。

Arduinoのコーディングルールと命名規則を調べてみた - Qiita
「個人的にあまり納得のいかないルールもあった」ということだが、どれどれ。。。

ああ、なるほど。
ちょっと、すっきりしないな。。。
まあ、C/C++言語ではなく「Arduinoで使う言語」と割り切るのがよいだろう。

 

整数型の型として、uint32_tのようなものではなく、unsigned longなどを使うよう推奨している。
間違えそうなので、メモ。

整数型以外は省略する。

普通のGCCを使っているようなので、uint32_tなども使うことはできる。
が、推奨はしていないので、少なくともAPIとしては使わない方が良いだろう。

 

また、引数でポインタを取るくらいだったら配列で指定するよう推奨している。

int getName(char *pName)  -> int getName(char[] pName)

配列を引数に取る関数って、そういえば書いたことなかったな。。。
どっちにせよ、C言語としては値渡ししかないので、アドレス値が渡されるだけのことだ。

だまされたっ!

int getName(char *pName)  -> int getName(char pName[])

C/C++なんだから、配列の括弧は名前の後ろじゃ。
公式サイトが間違っているのだけど、なんでこのままになってるんだろう?
実はみんな、普通にポインタで渡してるんじゃないのか??

 

あれ、ということは、参照でもらうのはよろしくないということかい。。。


気になっていることとして、文字列をどう扱うのがよいか、というものがある。
char配列がよいのか、std::stringがよいのか。。

Arduinoのリファレンスページを見ると、「string」と「String」があった。
stringは型ではなくて、char配列を指していた。
Stringはclassで、あるバージョンから使えるようになったらしい。

 

char配列の方は、普通のchar配列のようだ。
でも、一番下にあるExamplesで、

char* myStrings[]={"This is string 1", "This is string 2", "This is string 3", "This is string 4", "This is string 5","This is string 6"};

となっていた。
"文字列"のところは文字列定数だから、const型なのだけど、const無しで受けている。
g++でコンパイルしてみると「deprecated conversion from string constant to 'char*'」の警告が出る。
いくらC言語初心者でも扱えるようにとはいえ、あまりよろしくないと思う。
「お、char型だから書き換えられるやん」、と思って変更すると、ROM領域へのアクセスになるから、何も起こらないか、不正アドレス操作で死んでしまうか、そういう期待しないことになるだろう。

 

一方のString型だが、c_str()があるなどstd::stringっぽい。
新しく作ったということは、こっちを使ってほしいのだろうか?

いや、今回ね、APIから文字列を返すことになるかもしれないのだ。
一時的な文字列だったらライブラリで文字列のメモリを持ちたくないので、戻り値ではなく引数で受け渡しすることを考えていたのだ。
その際に、char配列がよいのか、Stringオブジェクトを参照でもらうのがよいのか、迷いがある。

中身をもらう必要は無いので、コピー渡しにはしたくない。
だから、ポインタか参照で考えていたのだけど、Arduinoで参照型を使っている例があるのかなあ。

それに、私のルールでは、constの参照渡しはするけれども、値を書き換える場合はポインタで渡すようにしていたのだ。
見分けが付きにくいから、というだけの理由だが。
C#みたいにoutとかあるといいんだけどね。

 

うーん、もう少し悩んでみます。

2016年9月26日

Arduinoのライブラリを作る

お仕事でArduinoのライブラリを作ることになった。
作る内容はさておき、そもそもどうやってつくるんじゃ?というところを調べておこう。
仕事の内容はネタにできないが、こういう一般的なものであればネタにできるのだよ。


いま(2016/09/26時点)のArduino IDEは、v1.6.12のようだ。
Web Editorというものもあるようだが、IDEでやる。
私はWindows10を使っているので、以下もWindows版についてとなる。

 

IDEでスケッチを作ると、拡張子は.inoになるが、ライブラリは普通のC++形式で作ればよいようだ。
ちなみに、IDEでcppやhを読もうとすると怒られる。

image

テキストエディタで作って、サンプルだけIDEで作ってビルドすることになるか。
ライブラリだからと言って.aとかにするわけではなく、ソース提供するだけになるみたいだ。

 

作る場所は、どこがよいか。
「How to write libraries for the Arduino?」では「hardware\libraries」に置きそうなことを書いてあるが、そういうフォルダはない。
だいたい、XPとか書いてあるので、ずいぶん前のことじゃなかろうか。。。

Program Filesに置くものでも無いので、スケッチを置くフォルダが妥当だろう。
最初から「libraries」というフォルダはあるのだが、これはライブラリをインストールしたら配置されるようだ。
ただ、これもIDEがv1.0.5となっているから、古い可能性がある。
試しておくか。

 

まず、librariesフォルダの中に「hiro99ma」というフォルダを作り、Arduino IDEを起動する。
うん、「スケッチ>ライブラリをインクルード」には出てこない。

image

では、この中に「hiro99ma.h」という空ファイルを置いて、IDEを再起動する。
出てきた。

image

「インクルード」だから、ヘッダファイルだけあればよいということか。
選択しても、スケッチの先頭にincludeされるだけのようだ。


では、中身がないうちに、ビルドするexamplesスケッチも用意しておこう。

Arduinoがインストールされるフォルダの中にあるlibraries(うちでは「C:\Program Files (x86)\Arduino\libraries」)には、IDEインストール時に提供されたインクルードできるライブラリが入っているようだ。

見てみると、だいたいがライブラリ名のフォルダの中に、以下が置かれていた。

  • examplesフォルダ
  • srcフォルダ
  • keywords.txt
  • library.properties
  • README.adoc

srcがなく直下に置いてあるもあるし、README.adocじゃなくてreadme.mdのもあったが、まあ傾向としてはこうなっていた。

では、先ほどの「hiro99ma.h」も、srcフォルダを作って移動させて、インクルードする一覧に出てくるかやっておく。
・・・出てこない。
これはちょっと、IDEがよくないと思うが、どうだろうか。

ひとまず、srcフォルダは作らず、直下にソースファイルを置いていく。


こういう構成にした。
examplesにtest1フォルダを作り、その中にtest1.inoというビルド用スケッチを置いた。
hiro99ma.hとhiro99ma.cppは、hiro99maフォルダの中に置いている。

image

順番に、hiro99ma.h、hiro99ma.cpp、test1.inoの内容。


#ifndef HIRO99MA_H__
#define HIRO99MA_H__

class hiro99ma {
public:
    hiro99ma();
    virtual ~hiro99ma() {}

    void hello();
};

#endif /* HIRO99MA_H__ */


#include <Arduino.h>
#include "hiro99ma.h"

hiro99ma::hiro99ma()
{
}

void hiro99ma::hello()
{
}


#include <hiro99ma.h>

void setup() {
  // put your setup code here, to run once:
  hiro99ma h9m;
  h9m.hello();
}

void loop() {
  // put your main code here, to run repeatedly:

}


この内容でIDEの「検証」を行うと、エラーは発生しなかった。
試しにhiro99ma.cppを抜いてみると、ちゃんとエラーが発生したので、ビルドしているようだ。

ただ、IDEでtest1.inoを変更して保存しようとすると、書込禁止扱いになってしまった。
テキストエディタでは編集できるし、ファイルの属性も問題なさそうなので、libraries以下にあるものは書込禁止扱いにしているのかもしれない。

また、もしかしたらcppファイルはsrcフォルダに置いてもビルドしてくれるのではないか、と期待したが、ダメだった。
では、zipファイルに固めたらいけるんじゃなかろうか?

単純にzipにすると、まずライブラリとして受け入れてくれなかった。
library.propertiesファイルを置いて、適当に埋めると、インストールに成功した。
見え方は、さっきのインクルードと同じ。
ちゃんと、librariesフォルダに「hiro99ma」が展開されていた(zipインストール前に作っていたフォルダは消しておいたので、新たにインストールされたものだ)。

zipはこういう構成で、Windows標準のZIP圧縮で固めただけだ。

hiro99ma
│  library.properties
│
├─examples
│  └─test1
│          test1.ino
│
└─src
        hiro99ma.cpp
        hiro99ma.h

ちゃんとexamples\test1も「ファイル>スケッチの例」に入っていた。
ビルドすると、library.propertiesのcategoryを適当に書いたため警告が出たが、エラーは出なかった。


あれ、じゃあ、library.propertiesを置いておけば、zipじゃなくてlibrariesフォルダに置いておいてもsrcにCPPファイルを置いておけたんじゃないだろうか?

だめだ・・・。
インクルードできるライブラリの一覧に出てこない。

あまり納得できんが、zipでインストールしたときだけsrcフォルダが有効になると言うことと覚えておくことにする。

2016年9月25日

[nrf52]Secure DFU Bootloaderを試す (2)

みんな忘れていたと思うし、私も忘れていたが、前回の続きだ。
体調がよいときに書いておかねば。。

今は、SoftDevice S132 の v3.0.0が焼かれている(nRF5 SDK v12に入っていたもの)。
nRFgo Studio v1.21.2ではまだバージョンが出てこないようだ。

image

(今気付いたが、SDKに入っているビルド済みHEXファイルは、SoftDeviceも含んだ形なんだな。)

 

examplesのBLE Secure DFU Bootloaderをgccでビルドするのと、DFUで送るZIPファイルを作成しようとするまでが前回だった。

まずは、ZIPファイルの作成を行う。
公開鍵はブートローダに埋め込んであるので、指定する秘密鍵もそれに対応するものでないとダメだろう。
が、秘密鍵と思われる情報がSDKに入っていないので、自分で作るのは無理そうだ。
自分で秘密鍵から作るのは後にして、examples/dfu/ble_dfu_send_hexに入っているファイルを使おう。
名前からすると、HRMサンプルのようだ。


では、ファイルは準備できたので焼いていこう。

まずは、ブートローダをnRF52832に焼く。
これはnRFgo Studioを使う。
タブの一番右が「Program Bootloader」なので、それでよいだろう。

image

以前のブートローダと同じく、一番後ろに配置された。

 

次に、ZIPファイルをスマートフォン側に置く。
dfu_test_app_hrm_s132.zipを使うことにした。
うちはAndroidで、nRF Connectをインストール済みだ。

 

nRF52832をリセットしてやると、ブートローダが見える。

image

CONNECT。

image

右上のDFUをタップ。

image

ZIPでOKし、置いたZIPファイルを選択。

image

うまくいった。

が、これだと何だかわからないので、普通にZIPファイルを作った場合もやっておこう。

> nrfutil pkg generate --application nrf52のHRSサンプル.hex test.zip

"--key-fileが無い"と怒られた。
そして、以前のdfu genpkgは無くなっているようだ。
しょうがないので、nRFgo Studioの中に入っているnrfutilを使って作成。

あー、そしてちゃんとしたapplicationが焼かれているとブートローダは動かないので、ボタン4を押しながら起動しないといかん。
BUTTON_4は16になっているので、GPIO16とGNDをスイッチで接続(内部でプルアップされてるはず)。

ボタンを押しながらnRF52を起動するとDfuTargが見えるので、同じ手順でDFUを実行。
そうすると、グラフの画面までは進むのだが、すぐに切断されて終わった。
うん、まあうまくいったというか、うまく失敗したと思ってよいのかな。


では、自分で秘密鍵を作るところからやってみよう。
書いてあるとおりにやる。

$ nrfutil keys generate priv.pem
Generated private key and stored it in: priv.pem
$ nrfutil keys display --key pk --format code ./priv.pem --out_file dfu_public_key.c
$

できたdfu_public_key.cをオリジナルと置き換えてmake。

できたpriv.pemを使って、HRSサンプルのZIPを作成。

$ nrfutil pkg generate --application nrf52832_xxaa.hex --key-file priv.pem test2.zip
Error: --hw-version required.

まだダメらしい。
表では例として52とあったので、nRF52の52なのか。
ただ、これを指定しても、--sd-reqと--application-versionが要求された。

$ nrfutil pkg generate --application nrf52832_xxaa.hex --key-file ../priv.pem --hw-version 52 --sd-req 0x8c --application-version 0xff test2.zip
Zip created at test2.zip

0xffにするとスキップされるようだが、--sd-reqはよくわからん。
nRFgoで表示されたFirmwareのIdが0x008cだったので、そうしてみた。

これでブートローダを焼いてやってみると・・・だめだった。
さっきと同じで、すぐに切断されてしまった。
ちゃんと読もう。

・・・うん、どうもブートローダをpca10040_debugの方でビルドしたのがよくなかったようだ。
ifdefでNRF_DFU_DEBUG_VERSIONを見ているようで、先ほど置き換えたdfu_public_key.cも、おそらくifdefで分けられていた。
ソースの方でも使っていたので、何かあるのだろう。

ともかく、ブートローダをpca10040の方でビルドして焼き直すと、作ったZIPファイルでDFUできた。
examplesに入っていたZIPファイルを指定すると、ちゃんと失敗するので、うまくいっているのだろう。

[ble]Secure Gateway Kit

Windows10 64bit環境に、Secure Gateway Kitをインストールして動かした。

  • Bluetoothドングル : Planex BT-Micro4
  • Node.js : v4.5.0のwin-x64
  • Visual Studio 2015 (Community?)
  • Python 2.7

VSとPythonはインストール済み。
zadigも既にある。

 

Node.jsを適当に解凍。

管理者権限でコマンドプロンプトを開いて、Node.jsにパスを通し、インストール

> npm install --global --production windows-build-tools

ScriptAndSourceCodeでコマンドプロンプトを開いて、Node.jsにパスを通し、インストール

> npm install bluetooth-hci-socket
> npm install -g node-gyp
> npm install noble

Node.jsをよく知らないのだが、npm installはコマンドプロンプトと同じ場所にインストールするのかな。
「node_modules」というフォルダができていた。

そして、ScriptAndSourceCode/gatewayで管理者権限のコマンドプロンプトを開き、インストール。

> npm install

別の管理者権限のコマンドプロンプトをScriptAndSourceCode/navibleで開き、インストール。

> npm install

そして、それぞれのコマンドプロンプトで開始させる。

> npm start

そうすると、navibleの方にアクセスするURLが出てくるので、ブラウザで開く。
ユーザ名とパスワードを訊かれるので、とりあえず両方に「user1」を打ち込むと、こういう画面が表示された。

image

赤いところにはMACアドレスが表示されている(たぶん、お隣さんのデバイスだと思うので隠した)。
nRF52を起動させて、右上の「Scan」を押すと、少しぐるぐる回るアニメーションが出た後、更新された。

image

 

Nordic_BDSをクリックすると、詳細画面に遷移した。
横幅を狭くするとレイアウトが崩れるので、ほどほどに広くしたほうがよい。

image

Connectをクリックすると、ちゃんと接続された。

image

一番下が自作のServiceなのでクリックすると、展開される。
レイアウトが、どうやっても崩れてしまう。。。
Firefoxだからかと思ってChromeに変更してみたが、同じだ。

image

また、ReadやWriteしても、うまく行かなかった。
でも、Generic AccessのDevice Nameは読めたので、なんかあるのか、単にnRF52に焼いているソフトが変なのか。。。

 

nRF52にHRSサンプルを焼いたが、うーん、やはり動きがあやしい。

値の表示を「string/hex/byte」で切り替えられるのだけど、うまく切り替わらないことがある。
たとえば、Generic AccessのAppearanceをstringでReadすると「A」と表示され、hexにすると「41 03」、byteにすると「65, 3」になるのだけど、最初から「hex」でReadしても「A」なのだ。
ここは、Readした後で切り替えるもの、と思っていた方がよい。

Notificationの有効化はうまくいくようだ。
Heat Rate MeasurementのNotifyにチェックすると、ぱらぱらと値が変わっていた。

しかし、しばらく接続していると急に切断されるようだ。
ブラウザは接続中のままなので、HCIとかそっち側かもしれない。

使えるかと思ったが、うーん、ちょっと微妙な感じだ。
BT-Micro4以外で試せないので、他ので試すとうまくいく、というパターンかもしれない。
サポートしているUSBドングルは、これらとのこと(BT-Micro4は、CSR8510 A10として見えていた)。

develop with blue

Bluetooth SIGに「新機能!」という項目があったので見ていた。
毎日見ているわけではないので、ずいぶん前からあったのかもしれない。。

https://www.bluetooth.com/develop-with-bluetooth/developer-resources-tools

最初に開くと日本語ページだったのだが、サイトの上からEnglishを選んだ方がよい。

「develop with blue」になって、Starter Kitやら、Secure Gateway Kitやらがあった。
いつの間に。

 

Starter Kit

これは、Arduino 101というものらしい。
検索すると、ずいぶん前からあったようだ。
スイッチサイエンスさんにもあった。
アメリカでは"Arduino"で、それ以外の国では"Genuino"だそうだ。
3.3Vというのが、よいですな。

Application Accelarator2.1やBeacon Smarter Kitもあるが、これはこのStarter Kitに対して使うもののようだ。
Accelarator2.1だけダウンロードしたのだけど、Bluetooth Developer Studioのようなものではなく、サンプルソースが入っているだけのようなのだ。
まあそれでも、Windows10でのBLEアプリは作り方を知らなかったので役に立ちそうだ。

 

Secure Gateway Kit

こちらは何も書いていないので、仕方なくダウンロードした。
名前とメールアドレスを入れるだけなのだが、その手間がめんどくさい。。。

解凍すると、PDFとJavaScriptたちが見えた。
どうやら、Raspberry Pi(2 or 3)のBluezとNode.jsをインストールして使うようだ。
こちらはBluetoothSecureGateway-HandsOnLab.pdfに載っていた図だ。

image

PDFの後ろの方に、Windowsにインストールする場合について書かれていた。
zadigを使わせるなど、なかなか楽しいやり方みたいだ。
Node.jsは普通にインストールさせているから、Bluezが使えない分をまかなっているようだ。

ということは、Raspberry Piじゃなくても、Linux系だったらそのまま使えるのだろう。
BluezとNode.jsが動けばよいのかな。

 

中身を余り見ていないのだが、CC2650 SensorTagの管理画面がブラウザで見えているから、BLE peripheralを登録して管理できるのだろうか。
GatewayがPeripheralたちとの仲立ちをして、Explorerで管理、というやりかたか。

図のSecure CommunicationとUnsecure Communicationは、単にペアリングのことを指しているような感じがする。
ただ、Secure Pairingと書いてあるし、BLE Legacyも別に書いてあるので、Core v4.2で追加された"LE Secure Connections"もちゃんと扱えるよ、ということかもしれない。


うちには、PlanexのBT-Micro4というドングルがあるのだが、これでもv4.2がいけるのだろうか。
ドングルってプロトコルスタックを自分で持ってないような気がするので、もしそうならソフト側だけ変更するといけるんじゃなかろうか。

うちのデスクトップPCはBLE開発はできるものの、BLE通信についてはnRF51やTIのドングルを使って読み取るくらいしかやっていないので、使えるのであればありがたいのだ。

2016年9月24日

[nfc]どうやるつもりだろう

iPhone7の分解記事も出たことだし、どういうしくみでSuicaを動かすのか想像だけしてみよう。
まあ、今まで外してきたので、今回も外れると思ってるけどね。。。
iPhoneに興味は無いが、しくみには興味があるので、予想くらいはしておこう。

 

まだ日経さんの方は出ていないが、iFixitさんの方では分解していた。
モバイルFeliCaチップのことが書かれていなかったのでわからんねー、というのが前回だ。

まあ、せっかくだからNXPのコントローラしか載っていなかったということにしよう。
このチップは、たぶんType-Aのエミュレーションがデフォルト動作になってるんじゃなかろうか。
NXPといえばType-Aだから、という理由だが。

67V04と書いてあるが、一昔前は、PN544がよく使われていたと思うので、たぶん後継チップだろう。
iPhone6は65とかじゃなかったっけ。
位置づけとしては、このチップがいわゆるモバイルFeliCaチップに相当する。

このチップが、NFCアンテナとか、SIMとか、SEメモリとかにつながっていると思う。
セキュアエレメントは、だいたいSIMに載っているか、ボード上のメモリとして載っているかだろう。
FeliCaは後者ですな。
GSMだったか3GPPだったか忘れたけど、あっち側の規格ではSIMに置くこととなっているので、FeliCaもそこに入るためにはSIMにも置けるようにならんとね、というのが、ドコモとかが進めていたステップだと思う。
「SIMに置くことになっている」というのは、ドキュメントを読んだわけではなく、どこかの記事に書いてあっただけなので、本当かどうかは知らん。

 

NFCコントローラがNXPだろうとSonyだろうとBroadcomだろうと、だいたいどれもType-A/BやFeliCaにアクセスはできる。
周波数は一緒で、通信の方式が違うだけだから、使えなくするほどでもないか、ということかもしれん。
RC-S390だって、Edyに課金できるしね。

だから、FeliCaに67V04がアクセスできるのは当然なのだけど、今度はカード側にならないといけないので、エミュレーションしないといけない。
モバイルFeliCaチップはデフォルトでFeliCaになれると思うから、67V04はType-Aのみなんじゃないか、と考えている。
Type-BもFeliCaもエミュレーションするのは、面倒なんじゃなかろうか。

 

ちなみに、R/WタイプのNFCコントローラもカードエミュレーションできるが、こっちはデフォルトで動くことができないので、開始時に「Type-Aだったら、こう。Type-Bだったら、こう。FeliCaだったら、こう」みたいな指示を最初に出しておく。
「こう」と言っても、最初は必ずカードの有無を検出されるところから始まるので、相手から検出されようとしたらこれを返す、という指示をするだけだ。

その後は、受信するたびにいちいちホスト側のCPUが受信データを解析して、返信データを作ってやらないといけない。
PN544なんかは「デフォルトでType-A」と書いたが、つまりホスト側のCPUを介さずに勝手に処理してくれる、という意味だ。

このデフォルト動作を全部組み込まさせるのは大変だろうと思うので、67V04もType-Aだけなんじゃないかな、と思ったのだ。

 

じゃあ、改札側のR/WがiPhoneの場合だけType-Aでアクセスしに来ればいいやん、という感じもするが、まあ無理だろう。
FeliCaが来るかType-Aが来るかわからないので、R/Wは交互に切り替えながらやることになるだろうけど、そんなことをしていたらかざす時間が間に合わないと思う。
全国の改札を一斉に変更するのも大変だろうし。

だから、改札はFeliCaアクセスだけで、従来と変えていないと思う。

 

じゃあ、やっぱりiPhone側がSuicaアクセスをエミュレーションしないといけないことになる。
にもかかわらずモバイルFeliCaチップが載っていないのだったら、ホスト側ががんばってエミュレーションするんじゃないだろうか。
私の中で「HCE」はAndroid用語になっているので使わないけど、そういうことをやるんじゃなかろうか、という予想だ。

 

そうであれば、日本向け対応といってもハードウェアから変更したわけじゃないので、関係者さえ納得すればソフトウェア対応だけでいけるという気はする。
まあ、対応するのは少々じゃないとは思うけど。

iPhone6のときは、セキュアエレメントにお金の情報が直接入っているわけではなかったと思う。
あんまり私はわかっていないが、トークンとかそういう言葉で説明していた気がする。
5分でわかる iPhone6の新機能“Apple Pay”の仕組み - 週刊アスキー

お金の支払いでネットを使えたけど、改札だとその場で決済というか、お金を引いていくから、しくみが違いそうだ。
iPhoneで支払ったからと言って、Appleが儲かるわけでもなさそうだし、使用者の情報を得られるわけでもない気がするし。

メリットがよくわからないけど、裏で何をやっているか知らないし、お金持ってそうだし、いろいろ戦略がありそうだし。
母屋を取られるようなことにならなければよいのだけど、私が心配しても仕方ないですな。

 

誰かが試して調べてくれるだろうから、予想はここまでにしよう。
少しくらいは当たってくれてもよいと思うんだけどねぇ。

[c/c++]私のC言語 (失敗談) - リンカオプションが残っていた

たまには、失敗談でも書こう。
失敗をたまにしかしないのではなく、失敗談をたまにしか書かないだけだ。
今まで、けっこうミスをしてきたので、ミスが起きたときに「ああ、あれね」でわかることもあり、あなどれないのだ(よい面を見よう!)。


gccでライブラリを作っている。
最初は共有ライブラリにするつもりで、-fPIC、なんかつけていたのだが、やっぱり静的ライブラリにしようということで、オプションを外した。
arしてlibxx.aを作って、ちゃんと動いて、単体テストも結合テストもほぼ終わっていた。

が、さっきMakefileを見ると、-sharedが残っている!
うわー、こりゃいかんだろー。

ということで、外してビルドし直し、テストもやり直している。
が、ライブラリにバイナリ差分はあったのだけど、実行ファイルは-sharedがあろうとなかろうと差分がないのだ。

偶然そういうコードだったのか?と思ってgccのオプションを調べ直したら、-sharedってリンクオプションじゃないか!
静的ライブラリはarするだけでリンクしないから、リンクオプションに何が残っていても意味が無いのだ。
あぁぁぁぁ。。。

 

ライブラリを作り直した以上、実行ファイルが同じものであってもなくても、タイムスタンプ的に時間のずれがあると気持ちが悪いし、説明を求められるとなかなか苦しい。
あきらめて、最初からログを取り直している最中である。。。

ゴミ箱にファイルは残っているから戻せばよいのだけど、もう気持ちの問題だ。
幸い、放置系のテストが多いので、動かしておけばよいだけだし。
テストアプリに時間を掛けてよかった。。。

 

反省

使っているオプションかどうかくらいは確認しよう。


気になるのは、arした結果が違ったということだ。

差分はファイルの先頭だけだったので、きっとファイルヘッダ程度だろうとは思ったものの、案外こういうので手を抜いてしまうと失敗するというのを経験上知っている(そして、手を抜かなかった場合は、今回のようになんともない、ということが多い。。。)。

オブジェクトを残してarだけし直しても差分がある。
やはり、コンパイルしたオブジェクトには変化がなく、arしたときの差分だけということだ。
オブジェクトが同じだからチェックサムのようなものではなく、タイムスタンプ的なものだろう。

 

ar (UNIX) - Wikipedia

あー、ファイルヘッダの2項目目にタイムスタンプがあるな。
差分があるのも、確かにタイムスタンプフィールドの後半だけだ。
touchなどでファイルのタイムスタンプを変更しても、ar自体のタイムスタンプを書き換えないと「偽ってるだろう!」と思われかねないのか。

2016年9月17日

[android]HCE-Fのソースを少しだけ見る

HCE-F記事のアクセス件数が多いと思ったら、紹介してもらっていた。
ありがたや。

Android 7.0のNFC HCE-Fの実装について – Qiita

 

HCE-F自体は、2年くらい前からSonyの人かFeliCaNetworksの人が発表していた。
Host Card Emulation、の略でHCEで、それのNFC-F版というかFeliCa版だから、HCE-F。

私が「HCE」という単語を見たのはAndroidが最初だが、私がやっていたカードエミュレーションもジャンルとしてはHCEになる。

カードエミュレーションは「エミュレーション」なので、NFCカード以外が行うことになる。
前回の話と重複するが、NFCチップはだいたい3つに分けられる。

  1. NFCカード用のチップ
  2. NFC R/W用のチップ
  3. NFCカードエミュレーション用のチップ

1番は、普通のカードに載るタイプだ。
nimocaやSuica、NTAG203なんかもそうで、カード側にしかならない。

2番は、R/Wに載るタイプだ。
PaSoRiのようなカードリーダで使うことになる。
基本的にR/Wでの用途になるのだけど、だいたいカードエミュレーションする命令も持っていて、カードになることができる。
私がやっていたのは、これだ。
ホスト側がないと、何もできない。

3番は、携帯電話に載るタイプだ。
PN544やモバイルFeliCaチップがそれにあたる。
基本的にカードエミュレーションするようにできていて、ホスト=本体側のCPUがなくても必要な機器に電源が入っていれば自律して動くことができる・・・と思う。

 

1番目はよく売られているし、2番目も売られているけど、3番目は一般にはほぼ出回らないと思っている。
下手に出回って悪用されると、カードのふりをすることができるから、ひどいことになるからだ。
まあ、2番目のでもカードエミュレーションできるから何かできるのかもしれないが、秘密の情報を保持するセキュアエレメントにアクセスできないのだと思う。

セキュアエレメントって、それこそNFCの信用に関する生命線なので、私のような一般人にはさっぱり何だかわからないのだ。
だから、ここら辺で書いているものも、私の推測が多い。
詳しい人が見たら「ふふん」と思われそうだけど、まあいいや。


紹介記事にあったソースファイルを見ると、nfa_dm_act.cの144行目あたりに差分がある。
「T3T」は、NFC Forumの「Type 3 Tag」の略で、まあFeliCaを指すと思ってもらえばよい。
LF_T3T_IDENTIFIERS_1~16とあり、これは「Listen Mode NFC-F Discovery Parameters」のことだ。
Listen Modeは、搬送波を生成しない側なので、カード側だ。
NCI v1.1ドキュメントでは、Page 59(PDFのp.69)の表に載っている。

0-1 : System Code
2-9 : NFCID2
10-17 : (optional) PMm

まあ、このコードは初期値の設定なので、あまり意味は無い。

 

実際に使う値は、たとえばnfa_dm_cfg.cの差分になるだろう。
ce_t3t.cの差分も同じようなものだ。
2つ数字が変わっているが、これはコメントによるとPAD0らしい。
PAD0は、いわゆるPMmのICコードに当たる。

PMmについては、Sonyの技術資料を読むとよい。
Sony Japan | FeliCa | 法人のお客様 | ダウンロード
この中の「FeliCa技術方式の各種コードについて」に書かれている(数字の意味は書かれていないが)。

PAD0という名称は、NFC ForumのDigitalProtocolで使われている。
こっちはこっちで定義がないのだが、0xFFFFはNFC-DEPするデバイス用として割り当てられている。

 

値くらいだったら見るのは簡単だと思ったけど、そもそも値はAPIから与えられるので、見ていってもあまり面白くないか。。。


NfcFCardEmulationクラスのAPIを見ると、NFCID2(IDm)とSystemコードは設定できそうだ。
Serviceコードもできるのかな?
あるいは、そこから自分で実装するのか。

Systemコードはドライブに、Serviceコードはフォルダに相当する。
Sonyの技術資料にもそういう説明があったような気がするが、見つけられなかった。

だいたいのFeliCaではSystemコードが0xFE00がデフォルトになっているけど、Suicaなどのサイバネ系は0x0003を使っている。
ポーリングするコマンド(NFC ForumのDigitalProtocolでいう、SENSF_REQ)でもSystemコードを指定するが、ワイルドカードの0xFFFFを指定するとデフォルトのSystemコードが反応する。
Suica側を見たかったら、Systemコードをちゃんと指定しないと出てこない。
まあ、これはFeliCa LiteをNDEF対応したときも同じ話だ。

 

以前、HCEで訳もわからず作ったときは、HostApduServiceクラスをextensしたクラスにprocessCommandApdu()の中身を実装した。
それに相当するのは、HostNfcFServiceクラスだろう。

processCommandApdu()に相当するのはprocessNfcFPacket()か。
PCD側に値を返すときはreturnで返すところも同じだ。

APDUの場合は、引数のデータはCLAから入っていた。
NFC-Fにはそういう形式はないので、サブコマンドコード(Check=0x06、Update=0x08など)から渡されて、返す値もサブレスポンスコード(Check Res=0x07、Update Res=0x09)などとなるのだろうか。

だったら、NDEFくらいだったら簡単そうだ。


ただ。。。うちには試せる環境が無いので、確かめられない。

これをうまいこと使えて、しかもNCIがデータをチェックせずに送受信できるのであれば、実在しないFeliCaコマンドを作ることができるかもしれない。
どうなんだろう、さすがにチップ側でチェックするのかなぁ。
くぅ、だんだん試したくなってきた。。。