2017年1月15日

AzureでMQTT brokerを立てようとする (3)

そういえば、TLS/SSLって、サーバがはじくためじゃなくて、クライアントがはじくための通信だったような気がする。
サーバがクライアントをはじく場合は、Basic認証とか何とか認証とか、そういうのでやったような記憶が。。。

 

pythonのpaho.mqtt.clientで、tls_insecure_set(True)を呼び、tls_set('xxx.crt', cert_reqs=ssl.CERT_NONE)した。
crtファイルは、前回失敗したものをそのまま使っている。空文字列だとエラーなのだ。

そうすると・・・on_connect()がコールバックされた!
たぶん、まともなやり方ではないのだけど、CRTファイルを指定せずにTLS接続するというのはこういうことじゃないだろうか?
(ストアアプリの場合は、Windowsに登録してあるものを使ったのかもしれん。)

 

Linux上で動かすサンプルも見かけたのだが、そちらは/etc/ssl/certsにあるファイルを指定していた。

This is a simple example showing how to use the [Paho MQTT Python client](https://eclipse.org/paho/clients/python/) to send data to Azure IoT Hub. You need to assemble the rights credentials and configure TLS and the MQTT protocol version appropriately.

そういうのがWindowsにもあれば試すんだけどねー

・・・あ、Bash on Windowsがあった。
lsしてみると、同じ場所にファイルがあったので、pythonのスクリプトと同じ場所にコピーして、tls_insecure_set()を消し、tls_set('ca-certificates.crt')だけにして動かした。

動くやん。


とりあえず、これでpythonのpaho.mqttからAzure Iot HubにMQTT connectまではできたと思う。
ただ、on_connectのコールバックが呼ばれ続けるのよね。。。
Mosquittoのときはそうではなかったので、なんかしてやらんといかんのか。
on_messageなど、普通に使うコールバックを登録していないとか、subscribeするトピックを登録していないとか、そんな理由だろうか。

2017年1月14日

AzureでMQTT brokerを立てようとする (2)

AzureでIoT hubを立てるところまでできたのだが、デバイスの登録で止まっている。
ツールをインストールしたり、アプリを作ったりすれば登録できるようなのだが、もっと手軽にやりたい。
そもそも、Azureの設定画面にログインしてるのだから、そこからできるようにしてないのは需要がないからだろうか?

 

わからない。。。
敗北感が強いが、DeviceExplorerを使おう。

Releases · Azure/azure-iot-sdks
DeviceExplorerというツールは、今はここにあるようだ。

ツールの使い方は、こちらが詳しい。
Azure IoT Hubを使ってみた - Qiita
リンク先がいろいろ変わったようだが、元の情報はこれかな?
azure-iot-sdk-csharp/tools/DeviceExplorer at master · Azure/azure-iot-sdk-csharp

今のツールは、この画面からSASトークンも作ることができるようだ。

image

試しに、mqtt1というデバイスIDを登録し、SASトークンを作ってみた。
これ、Generateを押すたびに作ってくれるのだけど、一番最後のsigとseだけが変わっているようだ。

image

 

これで、ここに書かれている情報は揃ったことになる。
MQTT プロトコルの直接使用

が、パスワードがわからん。
SASトークンを使うらしい。

SharedAccessSignature sig={signature-string}&se={expiry}&sr={URL-encoded-resourceURI}

日本語だと表示が変な気がしたので、英語版を見てみた。
Using the MQTT protocol directly

ちょっと内容が違う・・・。

  • ClientId = deviceId
  • Username = {iothubhostname}/{device_id}/api-version=2016-11-14
  • Password : SAS token

それに、SharedAccessSignatureがsig, se, srの順で書いてあるけど、下に書いてある説明ではsr, sig, seの順だ。
SAS Tokenで生成したものもその順になっているから、そっちが正しいのだろう。

ESP8266, Arduino & Azure IoT Hub
こちらは、ESP8266でつないだときのことが書かれていた。
ポートは8883でTLS接続、ClientIdはデバイスIDで、UserNameはapi-versionが無く、Passwordは"SharedAccessSignature"で始まる文字列になっている。

 

お、WindowsのMQTTクライアントで接続できた!
api-versionは付けている。
スマホのMQTTクライアントは接続できないな。。。何が違うのか。。。

 

pythonのpaho.mqttでやってみると、TLS接続のハンドシェイクで失敗しているようだ。

ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)

ここにあった、一番下のCERTをファイルにしてみたが、ダメだった。
https://docs.microsoft.com/ja-jp/azure/app-service-web/java-create-azure-website-using-java-sdk#create-a-certificate

keytoolでcertファイルを作って試したが、やっぱりダメ。
作ったcertファイルをAzureに登録するような操作がいるのだろうか?

動いているMQTTクライアント(MQTTBoxというストアアプリ)は、ストアアプリだからAzureと相性が良さそうだしなぁ、などと勘ぐってしまう。
TLSはv1でもv1.2でも接続できるから、あとはCertificate Typeくらいか。
アプリの設定は「CA signed server certificate」というやつにしたのだが(これ以外だとファイルの指定がいるから)、これが何をしているのか分かればなぁ。

うーん、今回はここまで。

AzureでMQTT brokerを立てようとする (1)

お仕事で、クラウド上にVMを作る、というのをやった。
なんとなくAWSが有名な気がするが、使ったのはMicrosoft Azureだ。
あらまあ便利だわねぇ、と感心した。
いや、AWSに比べて、とかではなく、単純にOSのインストールとか面倒なことをせずに済む、という意味でだ。

家でも使えると便利かもしれんと思って調べると、30日間無料だった。
まあ、ずっと使うならお金がいるよねぇ。。。と思ったら、無料枠があった。

価格サービス | Microsoft Azure

VMなんかは入っていないが、いろいろと使えるようだ。
IoT Hub、というのもあるし、これだったらMQTT brokerになってくれるんじゃなかろうか?ということでやってみることにした。


そもそも、IoT HubでMQTTがあるのか?という疑問があったが、サポートしているようだ。

IoT Hub の MQTT サポート | Microsoft Docs

試しに1つ作るとき、名前に「mqtt」と付けると「付けられません」というエラーになった。
名前を自由に決められないのか?と不思議に思ったが、その名前を使ってホスト名を作るため、既存のものは使えないというだけのことのようだ。

(なまえ).azure-devices.net

こんなホスト名になる。

 

で、作ったものの、これからどうしてよいのかわからない。。。
ホスト名があるのでpingやnslookupしたけど、解決できないのだ。
pingは止められているだけかもしれんが、名前が解決できないとどうしようもない。

あ、ネットの名前解決サービスを使うと見つけられた。
IW3 PROJECT DNSによる名前解決サービス

image

なるほど、そういうことか。
今回はFreeのものを使ったからかもしれん。
なお、Freeのものは1つしか作ることができないとのこと。

image

30日間は2万円くらいまで使えるので、S1 Standardのものも作ってみた。
うん、名前解決すると同じIPアドレスになった。

 

あれ、MQTTでつなぐとして、IPアドレスが同じだったらどうやって見分けるのだろうか?
何かしら、IDなり登録なりして通知しないとわからんだろう。
どうやるのだ?

Azure IoT Hub の使用 (Java) | Microsoft Docs
使い方のページがあった。
これはJavaだが、他に.NETやNode.jsのページもある(Node.jsは「ノード」とカタカナ表記になっていた)。

「共有アクセスポリシー>iothubowner」というページで、共有アクセスキーを見るようだ。
「主キー」なのに「セカンダリーキー」で「接続文字列—プライマリキー」なのは愛嬌だろう。
接続文字列の欄は、HostName, SharedAccessKeyName, SharedAccessKeyがひっついているだけのようだ。

で、ここから「Settings > Messaging」に相当するページに移動することになっているのだが、どこなんだ。。。
「設定」じゃなくて、トップメニューの下の方にあった。

image

ここの「Endpoints」の「Built-in endpoints」一覧の「Events」をクリックすると、それっぽい画面が出てきた。
これでいいのだろうか。。。

いや、それ以前に、MQTTで接続するのに何が必要なのかを先に調べるべきだ。
MQTT プロトコルの直接使用

  • ClientId = デバイスID
  • UserName = {ホスト名}/{デバイス名}
  • Password = SASトークン

という対応になっているとのこと。
ならば、デバイスIDを作ればなんとかなるのかもしれん。

 

デバイス ID の作成
・・・Java版だからだと思うが、Javaアプリを作らないといけないのか?
「概要」の上に「デバイス」があるから、ここから追加できるのかと思ったが、押せない。

image

ハブの作成と Raspberry Pi 3 の登録 | Microsoft Docs
ここを見ると、Azure CLIというツールを使って追加するようなのだが、クライアントからできるならWebからだってできておかしくないのでは。。。

Azure IoT Hubでデバイスを管理する - Qiita
どうやら、デバイスを登録するとメニューが有効になっているようだ。

Azure/iothub-explorer: IoT Hub Explorer is a tool that allows you to explore and test Azure IoT Hub features
ツールも提供されている。
されているのだが。。。

いやだー、私はWebで全部済ませたいんだー!

2017年1月13日

[nfc]AndroidでFeliCa Liteを読む

AndroidでFeliCa Liteを読むアプリを作っておこう。
すごいことをやっているわけではなく、2年くらい前に作っていたclassを多少手直ししただけだ。

https://github.com/hirokuma/AndroidFelicaLiteRead2016

 

画面に何も出ず、Logcatで出力させるだけにしている。
このくらいシンプルだったら、アプリのソースを読むのも大変じゃなかろう。

NfcFactoryは使いそうなものをAPIにしただけで、必須ではない。
FelicaLiteが本体なのだが、MifareUltralightみたいな継承で作ることができなかったのが心残りだ。

2017年1月12日

[rpi]Raspberry PiでFeliCa Linkを動かす (4)

結果としては、Raspberry Pi + RC-S730は動いた。
いや、動いていた、というのが正しい。

今まではNFC R/WとしてNexus5のTagInfoアプリ(NXP製)を使っていた。
しかし、何か嫌な予感がして自分で作ったFeliCa Lite読込みアプリを使うと、読めた。

そう書くと、Androidアプリの書き方に特徴があるのではないかと思ってしまいそうだが、いやいやいや。。。
私は仕様書通りに、しかもAndroidのAPI仕様に従って作っているだけなので、特に技は無いと思うのだ。
MIFAREみたいに便利なAPIがあるわけでもないので、NfcFで地道にやっているだけ。

それに、NXPのTagInfoアプリだって、普通のFeliCa Liteは読めるし、FeliCa LinkにしてもPlugモードじゃなくてカードとしてアクセスできる状態にしておけばアクセスできていたと思うのだ。

 

じゃあ、一体何が違うのか・・・。
DDMSのログを見ると、TagInfoなんかで読めないときはドライバだかJNIだか忘れたが、あの辺でタイムアウトが発生していた。
でも、FeliCa Linkで設定できる時間はPMmくらいしかないと思うし、あれも0xFFだったので最大値のはずだ。
それに、ドライバでダメなのなら私のアプリでもダメなはずじゃないか。
ログからはそれ以上の情報が読み取れない。

よくわからんが、R/W側に原因があったということで、Raspberry Piの方は終わりにしよう。
github

2017年1月11日

[rpi]Raspberry PiでFeliCa Linkを動かす (3)

ロジアナを持ってきて、カード読み出し時のFeliCa Linkのピンを見てみた。

image

下から順に、RFDET、IRQ、I2Cたち、となっている。

やっぱりというか何というか、RFDETとIRQがまったく同じ動きをしている。
なんで「やっぱり」と思ったかというと、RFDETに接続したLEDの点灯とIRQ立ち下がりのコンソール出力が同じくらいのタイミングだったからだ。

 

ハンダ付けミスかと思ったが、なんと原因はFFCケーブル。
なぜか、接点部がぐちゃぐちゃになっていたのだ。
なんとも初歩的なミスよ。。。

ぐちゃぐちゃになっている部分を切断してきれいにすると、ショートが直った。


これで動くようになったかと思ったが、甘かった。
今度は、IRQが立ち下がらないのだ。
切断したせいかもしれんと思ったが、別のFeliCa Linkで試しても同じだった。

うーーん・・・。

RFDETとショートしているときにはアプリも動いたので、立ち下がればコンソールに出てくれることはわかっている。
念のため、RFDETをRaspberry Piに挿してみたが、搬送波検知でログが出るし、ちゃんとロジアナも立ち下がりで反応している。

だから、FeliCa LinkがIRQを下げる必要がないと思っているのだろう。
先は長そうだ。。。

2017年1月9日

[rpi]Raspberry PiでFeliCa Linkを動かす (2)

前回の続き。

FeliCa Linkの搬送波検知は使わず(LEDが自動で点灯)、IRQ立ち下がりでI2Cアクセスするだけの予定だ。
Read without Encryptionは実装しよう。
Write without Encryptionがあると、メモリアドレスをレジスタのように使ってR/Wから要求を出すことができるのだけど、無理はすまい。

前回はmbed用に作ったライブラリ(C++)からCに移植しようと考えていたのだが、そういえばnRF51用に書いたものがあった。
そちらを使おう。

https://github.com/hirokuma/nrf51822_felicalink_v810/tree/master/felica


そういえば、スタートコンディションやストップコンディションの制御はどうやって行うのだろう?
writeの場合は書込むだけだからよいのだが、readはレジスタを指定した後に読込むので、ストップコンディションを発行しないwriteをしたいのだ。

 

これだ、というのは見つからんのだが、i2c_smbus_read_block_data()なんかでできるのか?
https://www.kernel.org/pub/linux/kernel/people/marcelo/linux-2.4/include/linux/i2c-dev.h

でも、これはこれで、readしたデータの先頭がデータ長になっている前提のようにも見える。
そもそも、引数に読みたいデータ長を指定するようになっていないので、これはこれで困る。。。

 

Raspberry Pi で I2C の Repeated Start Condition を有効化 - Rabbit Note
これだ。
Repeated Start Conditionっていうんだ。
「ストップコンディションを自分で制御する」ではなく、「続けてスタートコンディションを発行する」という見方になるのか。
ストップコンディションは一連の処理が終わるまでやらないものかと思っていたが、そうじゃないデバイスもあるんだな。

sysfsに書込めば動的にも設定できるそうだ。
I2C Repeated Start

sudo sh -c '/bin/echo Y > /sys/module/i2c_bcm2708/parameters/combined'


あとは、ファイルをRaspberry Piに送る方法が必要だった。
これは、WinSCPを使ってSFTPでやればよいだろう。

。。。と思ったら、SSH自体が使えなかった。
SSH (Secure Shell) - Raspberry Pi Documentation

$ sudo raspi-config

ここで「5 Interfacing Options」を選び、次の画面で「P2 SSH」を選択。
Enableにするか聞かれるので、Yes。

これだけで、TeraTermからSSHすることができた。
WinSCPもOK。

 

SSHの有効化は、以前はraspi-configのAdvanced Optionsにあったようだが、少なくとも今(2017/01/09)はInterfacing Optionsのようだ。


まずは、GPIOの割込みだけ確認しよう。
GPIO7が立ち下がったらコールバックされるというだけのしくみ。

https://github.com/hirokuma/rpi_rcs730/tree/08faec97ee7fea61dd3a5844ff28c48afbd755e1

WFIみたいなもので待たせたい気もするのだが、サンプルもぐるぐる回しているようなので、まあよしとしよう。

Drogon Projects | Git - wiringPi/blob - examples/isr.c

2017年1月7日

[rpi]Raspberry PiでFeliCa Linkを動かす (1)

久々にRaspberry Piを動かそう。
ついでに、FeliCa Linkも動かすことにする。

 

基本的な配線は、これでよいだろう。
hiro99ma blog: [felica]FeliCa Linkを動かす

image

FeliCa Linkのピンは、写真のこの方向で上から順に1, 2, ..., 6番となっている。
RFDETはLEDに、IRQはGPIO4に、SDA/SCLはSDA0/SCL0に接続した。
LEDは、搬送波検知で点灯させたいだけだ。

LEDは抵抗を付けた方が良いのかもしれん。
付けよう。。。付けた。

 

この状態で、ソフトを書かなくても搬送波検知だけはできる。
うちのNexus5を近づけると、ちゃんと点灯した。


ソフトの方を作る前に、Raspberry Piの準備をせねばならぬ。

ここからRaspbianのJESSIE LITEをダウンロードして、うちはWindowsなのでWin32DisImagerをインストールし、SDカードにWriteするだけだ。
https://www.raspberrypi.org/downloads/raspbian/

SDカードをRaspberry Piに挿して・・・
HDMIのモニタが近くにないので、UART-USB変換ケーブルをピンに挿して起動する。
UARTは115200bpsだった。
loginが出てくるので、「pi」「raspberry」でログイン。

wifi設定は、こちらを見て、WPSした。
Raspberry Pi Raspbian Wheezy(2015-05-05)で最速Wi-Fiセットアップ - Qiita
うちのは、PlanexのGW-USNanoの古いやつだったと思う。

 

I2Cは、こちらを見て有効にした。
Raspberry Pi の I2C を有効化する方法 (2015年版) – ymyzk’s blog
raspi-configを使った。
2016/11/25版のraspbianだからかわからないが、メニューは7番だった。
それ以外は、同じ(再起動は求められなかった)。
が、だいたいそういうのは失敗しそうだから再起動した。

FeliCa Linkは、こう見えた。

pi@raspberrypi:~$ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

FeliCa Linkのユーザーズマニュアル「5.2.5 I2Cスレーブアドレスレジスタ」によると、出荷時設定は0x40で、レジスタは7bit分だから、そのままI2Cアドレスとして使えばよいだろう。
いや、たまに1bitシフトして8bitのアドレスを示している(下位1bitはR/W)ことがあるので、ビット数を確認しないと不安なのだ。


そして、どうやってI2Cにアクセスするとよいのだろうか。。。

Raspberry Pi でI2C: C言語プログラミング - 猫ぱーんち!

open()して、ioctl(I2C_SLAVE)でスレーブアドレスを指定し、あとはread()/write()でアクセスできるようだ。
lsすると、/dev/i2c-1があるので、これでよいのだろう。
0からじゃないのですな。

 

昔書いた、mbed用FeliCa Linkライブラリを見てみる。
RCS730 - a mercurial repository | mbed

そうか、IRQの立ち下がりで処理を始めるから、割込み検知する必要がありそうだ。

Raspberry PiでGPIOを使った割り込み処理を行う - ORBIT SPACE

WiringPiでできるらしい。

 

これで材料は揃ったと思うので、あとは作っていくだけだ。
それは、次回以降で。

[android]paho mqttを使いたい (2)

前回はsubscribeだけだったので、今回はpublishまで行う。

変更後のgithub

publish自体は、簡単だった。
慣れないので、EditTextからどのタイミングでpublishさせたらよいのか悩んだり、TextViewのスクロールをどうやったらよいのかとか、そういうところに時間がかかった。

 

どうでもよいところだが、MQTT brokerをiot.eclipse.orgにしてみた。
家の中でmosquittoを立ち上げていたのだけど、ちょろっと動かすためにVirtualBox起動して、VM立ち上げて・・・というのが面倒だったのだ。
利用制限とかユーザ登録とかなさそうだけど、どこまで使ってよいのだろうか?
pahoはeclipseなのでそこまで悪いことはしてないと思うが、paho以外でも使えるだろうし。
ここは「さすがeclipse!」と褒め称えることにしておこう。

特に凝ったコーディングにはしていないつもり。
ただ、トピック名は「hirokuma@github」にしているので、この辺りを修正しておいたほうがよいだろう。
まあ、見られて困らないなら、そのまま使ってもらってもよいです。

2017年1月6日

[android]paho mqttを使いたい (1)

以前、paho.mqttをpythonで使った。
あれは使いやすかったので、今度はそれをAndroidでも使いたい。

paho.android.service

githubにあるのだが、なんか使い方がpythonのときよりも面倒そうだ。
まあ、Androidのルールにあわせないといけないので仕方ないのだが。。。


今回は、こういう構成で試す。

  • 本体:Nexus5 + Android 6.0.1
  • Android Studio 2.2.3 (Windows 10 Home 64bit)
  • API 22(Android 5.1)

まず、Android StudioでEmptyな画面のプロジェクトを作った。

次はライブラリの追加なのだが、何だかよくわからない。。。
Android Studioの「File > Project Structure...」で、左からappを選び、タブの「Dependencies」をクリック。
右上のプラスアイコンをクリックし、1番のLibrary Dependencyを選択。
検索できるので「paho.client」と入力し、虫眼鏡をクリック。
いくつか候補が出てくるので「paho.client.mqttv3」を選択してOKする(testやrepositoryが付いていないやつ)。
同じようにして「paho.android.service」を追加する。

ただ、これだとgithubに書いてある最新バージョンが出てこなかった。
PropertiesタブのLibrary Repositoryにpaho-releasesのURLを書いて検索しても、出てこない(paho.android.service:1.0.2が出てくる)。

image

が、1.0.2を1.1.0に書き換えてOKすると、追加してくれた。
Library Repositoryに記載する前はできなかったので、そういうものなのだろう。
(mqttv3は1.1.0だったので、今だけの話かもしれん。)

image

この状態でビルドして実機に焼くと、警告がたくさん出るもののビルドは成功して動いた。
「Ignoring InnerClasses attribute for an anonymous inner class」などと出てくる。
ProGuard関連のようだが、今はアプリに何もやっていないし、無視しておこう。


あとは、サンプルをまねしていけばよいのか?

 

AndroidManifest.xml

<application>にserviceタグを追加するのはわかるが、<uses-permission>はこんなにいるのだろうか?
ACCESS_NETWORK_STATEとINTERNETはなんとなくいりそうな気がするが、他はアプリの内容次第ではなかろうか。
まあ、<uses-permission>は動かなかったら追加することにしよう。

 

PahoExampleActivity.java

これをまねして、adadHistory()みたいなものは、Log.d()で出力させることにした。
importできていないものは、Alt+Enterでお任せすると、動きそうなコードができた。
publishは面倒なので、まずはsubscribeだけ試そう。

 

これで起動すると、WAKE_LOCKが無いということでアプリが起動できなかった。
追加すると、次はACCESS_NETWORK_STATE。
その2つを追加するとエラーは出なくなったものの、MQTT brokerとの接続に失敗している。。。

なんとなくINTERNETも追加すると、今度は接続できた!
警告も出ずにうまく行かないのは、API 22でやっているからだろうか?

 

ともかく、subscribeまでしているので、ソースをgithubに上げておこう。
Brokerが192.168.0.70:1883になっているが、これはうちの中のVirtualBoxに立てているMosquittoだ。

github - android_paho_mqtt_test

 

次回は、publishするサンプルだ。
どうせボタンを押したら文字列を送信する、というだけになるだろうが、今日は力尽きたので次回にしよう。

 

そういえば、ProGuardの設定はうまくいかなかったら変更する、といっておきながら、変更したままになっていた。
コメントアウトしても動いているようなので、元に戻しておこう。
https://github.com/hirokuma/android_paho_mqtt_test/blob/master/app/proguard-rules.pro