2018年10月27日

[vscode]構造体メンバの候補一覧keyはselectNext/PrevSuggestion

Visual Studio CodeをVirtualBoxで立ち上げたUbuntu18.04上で使っている。
Linuxで慣れたエディタがないので助かるのだが、キーバインドが分からずに困っている。
WindowsではAutoHotKeyを動かしたままなので、どうも思った操作ができないようなのだ。


最近困っていたのが、構造体メンバの候補リストが表示されているときに矢印キーの上下で候補が選択できないこと。
デフォルトではできたのかもしれないが、いろいろ変更していたせいか、上下の矢印キーを押すとエディタ画面の方のカーソルが移動してしまうのだ。


あれこれ試した結果、該当する名前は「selectNextSuggestion」「selectPrevSuggestion」だった。
デフォルト値を見ておこう。

image

ああ、デフォルトでは普通のキーに割り当てられているのか。。。
しかし、こんなキーを変更した覚えがないのだが、どの名前がどの機能か分からないときに当てずっぽうで変更していたのかもしれん。


あらゆるキーをカスタマイズできそうな気配はするのだが、名前が分からんとカスタマイズのしようがないな。
調べ方を覚えたいものだ。

2018年10月15日

[c/c++]sizeof忘れでコンパイルエラーにならなかった(当たり前だけど)

なぜか、malloc()だか、そのfree()だかわからないけど、エラーが出ていた。
サイズが足りないのにアクセスしたような感じのエラーだ。


確保するサイズは、sizeof()で求めていた。
TLVじゃないけど、Length + Valueをいくつかつなげたようなサイズを確保したかったのだ。

Lengthは1byte分で、uint8_t型。
その箇所は、uint64_t型をValueに取りたかったので、こんな感じで書いていた(つもりだった)。


int length = sizeof(uint8_t) + sizeof(uint64_t);


しかし、私は最初の方にsizeofを書き忘れていたのだった。。。

int length = (uint8_t) + sizeof(uint64_t);


驚いたことに、これがコンパイルエラーにはならないのだ。
-Wや-Wallつけてるのに、warningも出ない。

01: #include <stdio.h>
02: #include <stdint.h>
03: 
04: int main(void)
05: {
06:     int length = (uint8_t) + sizeof(uint64_t);
07:     printf("len=%d\n", length);
08: }


なんとなく想像がつくだろうが、この結果は「8」だ。
"+sizeof(uint64_t)"をuint8_tでキャストしたことになったのだろう。


なかなか気付きませんでしたなぁ。。。

2018年10月6日

[win10][wsl]defender firewallを設定する

Windows10 1809がリリースされたので、アップデートした。

https://docs.microsoft.com/en-us/windows/whats-new/whats-new-windows-10-version-1809#windows-defender-firewall-now-supports-windows-subsystem-for-linux-wsl-processes

どうやら、Windows Defender FirewallにWSLのプログラムを設定できるらしい。
私はセキュリティに強くないので、Windows Firewall Controlを使って「許可していないアプリは禁止」にしているのだが、WSLの場合はpicoとかいうプロセスがアクセスして、これがどうやっても許可させることができなかったのだ。


やり方は、こちら。
python2.7のIN方向を許可するサンプルが載っていた。

https://docs.microsoft.com/en-us/windows/wsl/release-notes#build-17627-skip-ahead

netsh.exe advfirewall firewall add rule name=wsl_python dir=in action=allow program="C:\users\<username>\appdata\local\packages\canonicalgrouplimited.ubuntuonwindows_79rhkp1fndgsc\localstate\rootfs\usr\bin\python2.7" enable=yes

単純に、Windowsから見たファイルパスを登録するだけのようだ。
残念ながらWindows Firewall Controlは*.exeのようなものしか登録できないようだ。
「セキュリティが強化されたWindows Defender ファイアウォール」(長いよ...)だと追加できるようだが、local/packages以下がダイアログから見えなかったので、Explorerでたどったパスをコピペで登録させた。


まず/usr/bin/wgetを登録。
うん、いける。

では、普段よく使う/usr/bin/aptを登録・・・したのだが、これが通信できない。
拒否しているタイミングを見計らってps auxしてみたところ、/usr/lib/apt/httpというプロセスが立ち上がっていた。
そいつを許可してやるとaptが通るようになった。
やれやれ。


しかし、これは使うのが面倒だ。
当面はWSL使うときだけFirewallを許可する方が楽そうだ。

と、ふとWindows Firewall Controlの遮断ログを見ると、先ほどの/usr/lib/apt/httpが出ているじゃないか!
そうか、picoが前面に出ていたものが、各ファイルになったのだな。
そして、Windows Firewall Controlは自分でルールを追加する場合には*.exeみたいなファイルしか設定できないものの、ログから許可設定するのはOKだった。
これなら便利ですな。

2018年9月16日

[esp8266]RTOS v3.0

かなり久々だが、ESP8266のRTOS_SDK v3.0がリリースされていたので、Windows10のWSLで動かしてみた。

https://github.com/espressif/ESP8266_RTOS_SDK



だいたいこんな感じだった。

sudo apt install libncurses5-dev flex bison gperf
sudo apt install python-pip
sudo pip install pyserial

cd (project_templateまで移動)
make menuconfig
make all


なお、COMポートの設定はこちらを見ながら行った。
chmodで先に変更しないと、"sudo make flash"ではダメだった。

WSLでシリアル通信をする
http://matsuneko22.hateblo.jp/entry/2017/12/09/144803


IO0をLにして起動後にFLASH書込み実行。

make flash


このproject_templateで何が動くのかと思ったら、printf()するだけだった。
baud rateがデフォルトなので74880bpsで送信しているようなのだが、使っているUSBシリアル変換がその速度をサポートしてないので確認できなかった。
まあ、動いてるんだろう。


いずれはesp-idfと同じ形にするのか、統合するのか、ともかくそういう計画らしい。
私が使ってみたかったMbedTLSのchacha20は入ってなかったので、ライブラリのバージョンもesp-idfより古いものがあるようだ。


まあ、socketとかは使えるので、Linuxで書いたプログラムを移植しやすいのは助かるな。

2018年9月3日

[linux][azure]OSディスクサイズを増やした後

会社でAzureを使っている。
月も変わったことだし、少しメンテナンスをしておこうと休日に見てしまったのが間違いだった。。。
ディスクがフルになっているVMがあったのだ。


開発用にVMを立てているだけなので、実はそれほど深刻ではない。
面倒でなければ、VMごと削除して新しく作っても良いくらいだ。
ただ、面倒なので、ディスクを増やすだけで対応させたい。


私はAzureやらAWSやら、そういうものに詳しくない。
なんとなく使えているので、これでいいか、と思っているだけだ。
その程度の知識の人が書いていると思って読み進めていただきたい。


まず、OSディスクサイズを増やすには、VMを停止させる。
そうすると、「設定>ディスク」とクリックして、出てきたOSディスクをクリックした先の画面で変更ができるようになる。
フルになっているものが30GiBになっていたので、ひとまず64GiBにしておいた。


そして保存してVMを起動させる。
で、ここからがよくわからないのだが、なぜかパーティション全体が拡張されるVMと、ディスクだけが拡張されているVMの2パターンが発生するのだ。
OSは、Ubuntu16.04。
gpartedか何かで拡張すればよさそうなものだが、そもそもディスクが空いていないのでインストールもできない。。。
同じようにVMを作ったような気がするけど、何が違うんだろうね?


まっとうな使い方としては、データディスクを追加して、データが大きいものはそっちを使うとかなんだろうかね。
この辺りは勘所が分からん。


仕方ないので、パーティションが拡張されなかったものは、パーティションを追加して対応させることにした。

fdiskでデフォルトサイズのままパーティションを作り、再起動して、mkfs.ext4。


問題は、これからだ。
/etc/fstabをどう書くか。。。苦手なのだ。
こんなのでどうだろうか?

/dev/sda2       /home/xxx/yyyy  ext4    default,discard 0 0

私にとって大切なのは、mountしたディスクにユーザ権限で書き込めるかどうかだ。
が、それ以上に大切なのは、起動するかどうかでs


あ、起動しなくなった。。。


Azureの助かるところは、SSHがだめでもブラウザからログインできることだ。
fstabの設定を消したら、やはりログインできるので、なんかよくないのだろう。

$ sudo mount -t ext4 /dev/sda2 yyyy

これも大丈夫だった。
何が悪いんだ・・・。


はっ、「default」ではなく「defaults」なのか!
無事起動しました。

ユーザからのアクセスも、sudo chownで対応できた。
mountするディレクトリはユーザが作ったから大丈夫かと思っていたけど、mount後にchownしないといかんのかな?

2018年9月2日

[python]pythonの仮想環境

名前はよく聞くし、なんとなく仮想的なものを意味している感じがするのは分かっている。
そんなvirtualenvだが、意識的に使ったことが無い。
使い方の説明でコマンドが書かれていて、そのまま使っている程度だ。


歳を取ってきて覚えるのが面倒になってきているのを実感しているが、それに逆らってみよう。


https://virtualenv.pypa.io/en/stable/

virtualenv is a tool to create isolated Python environments.

isolatedとあるので、分離してくれるのだろう。


pipを使っていたので意識しなかったが、パッケージはどこかにインストールされる。
"site-packages/"というディレクトリらしい。
作っているものによってはバージョンが異なるパッケージを使いたいこともあるだろう。
そういうときの問題を解決できるらしい。


らしい、というのは、私がそういう状況に陥っていないからだ。
まあ、pythonで大したものを作っていないという意味でもあるが。。。


そういえば、最近は提供されるものでpython3を使っていることが多い。
pipがpip3になっているかのように、virtualenvもvirtualenv3なのだろうか?


そもそも、pipはpython2で、pip3はpython3なのだろうか?
python2がインストールされているからpip3になっていて、python3だけだったらpipでよいのだろうか?


https://docs.python.org/ja/3/tutorial/venv.html?highlight=pip#managing-packages-with-pip

ここではpipになっている。
このサイトがそう説明しているなら、そうなのだろう。


https://docs.python.org/ja/3/installing/index.html#installing-index

python3.4からは一緒にインストールされるようになったということは、それ以前はpipを単独でインストールしていることになる。
確かに、apt installした気がする。
Ubuntu16.04からアンインストールしてからpipを使ってみよう。

$ sudo pip install --upgrade pip
The directory '/home/xxx/.cache/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
The directory '/home/xxx/.cache/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
Collecting pip
  Downloading https://files.pythonhosted.org/packages/5f/25/e52d3f31441505a5f3af41213346e5b6c221c9e086a166f3703d2ddaf940/pip-18.0-py2.py3-none-any.whl (1.3MB)
    100% |████████████████████████████████| 1.3MB 1.1MB/s 
Installing collected packages: pip
  Found existing installation: pip 9.0.1
    Uninstalling pip-9.0.1:
      Successfully uninstalled pip-9.0.1
Successfully installed pip-18.0

うーん、よくわからん。

$ sudo -H pip install numpy
Requirement already satisfied: numpy in /usr/lib/python3/dist-packages (1.11.0)

これはpython3だろう。


ここで、ようやく--versionオプションに気付いた。

$ pip2 --version
pip 9.0.1 from /usr/local/lib/python2.7/dist-packages (python 2.7)

$ pip3 --version
pip 18.0 from /usr/local/lib/python3.5/dist-packages/pip (python 3.5)

$ pip --version
pip 18.0 from /usr/local/lib/python3.5/dist-packages/pip (python 3.5)

python-pipをアンインストールしてもpip2は使えるらしい。が、pipはpython3のものだ。


https://docs.python.org/ja/3/installing/index.html#installing-index

で、このサイトを見ると、仮想環境を作るのはvenvが標準らしい。
virtualenvはサードパーティの代替え案とのことだ。



https://docs.python.org/ja/3.7/library/venv.html#module-venv

見ながら使ってみよう。
Ubuntu16.04にpython3.5.2がインストールされていたから、3.7にしてみる。

https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa
こういうppaって、何も考えずに信用していいのか悩むな。。

tarでやるのが確実だろうけど、pythonはUbuntuのモジュールも使っているようだから、何か怖い。
pythonのバージョンごと仮想化する方法もあるんだろう。

では、カレントディレクトリに作ってみる。

$ python3 -m venv ./env1
The virtual environment was not created successfully because ensurepip is not
available.  On Debian/Ubuntu systems, you need to install the python3-venv
package using the following command.

    apt-get install python3-venv

You may need to use sudo with that command.  After installing the python3-venv
package, recreate your virtual environment.

Failing command: ['/home/hiroshi/Python/.env1/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']

えっ、venvは標準じゃなかったの??
釈然としないが、apt installでpython3-venvをインストールしてやり直す。


フォルダができたので、移動。
そこから何をしたらいいのか分からんかったが、bin/activateをたたけば良いようだ。
https://qiita.com/fiftystorm36/items/b2fd47cf32c7694adc2e

そうすると、コマンドプロンプトの先頭に環境名が出てくるようになった。

~/Python/env1$ source bin/activate
(env1) ~/Python/env1$

試しにnumpyをpipでinstallさせてみた。bin/activate前は「既にインストールされています」というようなメッセージだけだったのだが、bin/activate後はちゃんとインストールされた。


あれ、どうやって元に戻ればいいんだ・・・と思ったら、deactivateというコマンドがあるようだ。
これはbin/ ではないし、whichでも見つからなかった。
でも、実行すると元に戻った。


ここまでやって気付いたが、使っているpython3はpython3.5.2のままだった。
どうも、"python3.7"とやらないとそうなるようだ。
そして、python3.7-venvをインストールしないとvenvが作れなかった。

python3.7でvenvを実行すると、その中の実行もpython3.7になるようだ。
バージョンはそれで保てそうだ。

2018年8月19日

[nfc][rpi]最近のOM5578/PN7150S

掃除をしていると、Raspberry Pi2が見つかった。
NXPのプレゼントで当選したOM5578/PN7150Sが載ったままだった。
https://hiro99ma.blogspot.com/2017/01/nfcraspiom5578pn7150s-1.html

当時はkernelにドライバを入れるので苦労したのだが、最近は楽になっているかもしれない。
確かめておこう。


https://github.com/NXPNFCLinux/linux_libnfc-nci

現在の最新リリースは、R2.4。
PDFはAN11697。


0. Raspberry Piのkernelのクロスコンパイル環境

ページの上の方はセルフビルド、下の方はクロスコンパイルの記述になっているので、下を見る。
.bashrcに設定を書くようになっているが、うちは毎回sourceコマンドで読み込むことにする。

echo export PATH=~/Raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin:$PATH > compiler.sh
source ./compiler.sh

1. Raspberry Piのkernelダウンロード

git clone --depth=1 https://github.com/raspberrypi/linux
cd linux

2. ドライバのダウンロード

cd drivers/misc
git clone https://github.com/NXPNFCLinux/nxp-pn5xx.git

3. Makefileの編集

vi Makefile
(obj-がならんでいる一番下に追加)

obj-y               += nxp-pn5xx/

4. Kconfigの変数

vi Kconfig
(sourceがならんでいる一番下に追加)

source "drivers/misc/nxp-pn5xx/Kconfig"

5. Creating the device node

やり方が2種類提示してある。Device treeとPlatform data。
ソースファイルを変更するのは気が進まないので、Device treeにしよう。
と思ったが、どういう設定にすればいいんだ?
ああ、前回と同じ流れじゃないか!

6. ビルド

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
   (Device Drivers ---> Misc devices ---> < > NXP PN5XX based driver)
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs


・・・ここまでやった後で、PDFの「3.2 Alternative to pn5xx_i2c kernel driver」に気付いた。

image

この構成だと、Kernel spaceはI2CとGPIOのドライバで済みそうだ。

https://github.com/NXPNFCLinux/linux_libnfc-nci

src/halimpl/pn54x/tml/i2c/phTmlNfc_alt.h

/* Describe PN71xx connection
  *  0 = Custom configuration
  *  1 = OM557x on Raspberry Pi
  *  2 = OM557x on UdooNeo
  *  3 = OM557x on BeagleBone black
  *
  */

やる気十分じゃないか!
マクロのCONFIGURATIONを変更するだけでよさそうだし、githubに入っているものはデフォルトが1番だから今回は変更しなくて良い。


Raspberry Pi2にセルフビルドさせよう。
Raspbianは2018-06-27のDesktopで、apt update/upgradeも行っておく。
raspi-configなどでI2Cを有効にしておこう。

git clone https://github.com/NXPNFCLinux/linux_libnfc-nci.git
sudo apt install automake autoconf libtool
cd linux_libnfc-nci
./bootstrap
./configure --enable-alt
make
sudo make install

では、デモアプリを動かそう。

nfcDemoApp poll

1回目に実行したときはエラーがたくさん出てしまったが、タグをかざすと読み取っているようだ(エラーによってコンソールが流されて見えん)。
2回目は普通に動いた。
よくわからんが、深追いは止めておこう。


もしかしたら、前回も見逃していただけで、ドライバは何もせずとも動いたのかもしれんな。


私としては、BeagleBone Greenも持っているので、PN7150SとRapberry Pi用のアタッチメントとBeagleBone用のアタッチメントが分かれているとよいのだが、まあ高いものではないから仕方ないのか(Raspiモデルで3500円くらい)。
いつもだとSonyのRC-S620/Sを使うところなのだが、プロトコルを意識せず使用できるというのは強みがある。
まあ、Linuxが載る前提にはなってしまうが。


相手から読まれるだけでよいなら、FeliCa Linkという選択もある。
試作品を作る場合なんかは、Raspberry PiでもFeliCa Linkで済ませていたりする。
ボードにどーん、というのもよいのだが、FeliCa Linkみたいな小ささだと必要なピンだけつなげば良いので、小回りがきくのだ。


image(どーん)


まあ、適材適所ということで。

2018年7月28日

[c/c++][mbedtls]ChaCha20-Poly1305サポートとIETF variant (3)

第3弾まで書く気はなかったのだが、ネタは思いついたときに残しておかねば。



libsodiumからMbedTLSに全部置き換えたいと思っている。
別にlibsodiumに不満があるわけではないのだが、使っている理由がChaCha20とPoly1305だけなので、MbedTLSが対応したなら統一したいのである。


ChaCha20-Poly1305については、IETF variantのAPIを使っていたため、MbedTLSと置き換えできた。
しかし、見逃していたのだが、別の箇所でChaCha20を使っていることに気付いた。
こっちは純粋にChaCha20単体で使っていたのだが、nonceが8byteになっているからオリジナルのChaCha20っぽい。


さて、困った。
MbedTLSはChaCha20単体もIETF variantっぽい(nonceが12byteになっていたから)。

もしかしたら同じ結果になるかもしれない、と思ってやってみると、あら不思議、同じになるではないか。
しかし、条件があるに違いない。


libsodiumのChaCha20処理は、このあたりにある。
https://github.com/jedisct1/libsodium/tree/0468e778d229054a966d0fdc629ec8b677bc37c6/src/libsodium/crypto_stream/chacha20


呼ばれているのは、これのようだ。
_ietfが付いているかどうか。
https://github.com/jedisct1/libsodium/blob/bac61ebf506c1b32185a3f3cc6a582445d55bc75/src/libsodium/crypto_stream/chacha20/ref/chacha20_ref.c#L226-L262

この2つの違いはchacha_ivsetup()かchacha_ietf_ivsetup()かだけみたいだ。


IV設定は、ここ。
https://github.com/jedisct1/libsodium/blob/bac61ebf506c1b32185a3f3cc6a582445d55bc75/src/libsodium/crypto_stream/chacha20/ref/chacha20_ref.c#L62-L78

counterのバイト数と、ivのバイト数が違うだけのように見える。


RFC-7539の7ページ目に図が載っている。
https://tools.ietf.org/html/rfc7539#page-7

image

IETF variantは、bが1つ、nが3つになっている。
ということは、オリジナル版は、bが2つ、nが2つということだろう。
それなら、IV設定の関数と整合がとれる。


ということは、これを利用して、MbedTLSでもcounterとnonceの配分をうまくやればいけるのだろう。
stream()ではcounterがNULLになっているから、0扱い。
nonceは8byteだから、何も考えずに置き換えて使えるんじゃなかろうか。
エンディアンがちょっとわからんのだが、必要があれば4バイトシフトさせればいいだけだ。


私が置き換えたかったのはcrypto_stream_chacha20()だったので、前回と同じようにソースを書いてみた。

https://gist.github.com/hirokuma/f9ee0da7bd428458662473964b57fa6c

nonceの前方に4byteの0を入れると同等になるみたいね。

[c/c++][mbedtls]ChaCha20-Poly1305サポートとIETF variant (2)

前回の続きだが、あまり大したことは書けない。

  • MbedTLSにChaCha20-Poly1305がサポートされたけどIETF variantなのか?
  • ソースファイルからするとIETF variantっぽいし、libsodiumのIETF variant APIで同じ結果になった
  • じゃあ、なんで私がやったAPI置き換え版は結果が同じにならないの??


はい、なんとなく予想できたかと思うが「置き換えに失敗していたから」でした・・・。



これだけだとあんまりなので、どう間違えたのか書いておこう。

libsodiumは、エンコードしたデータ+MACをまとまったデータとして扱っていたのだ。
しかし、MbedTLSでは別々に扱っている。
だから置き換える際に、MACのアドレスも指定するし、データ長もMACを外したサイズにせねばならなかったのだ。

そこら辺を間違えていたのですな。
まあ、ありがちといえばありがちだが。

[c/c++][mbedtls]ChaCha20-Poly1305サポートとIETF variant (1)

Mbed TLS 2.12.0, 2.7.5 and 2.1.14 released


いやあ、とうとうリリースされました。

私にとって大きいのは、ChaCha20-Poly1305サポート。
だいたいの部分はMbedTLSで実装していたのだが、ChaCha20-Poly1305だけはlibsodiumを使っていたのだ。
libsodiumを別の環境でビルドするのは難しそうだったのだけど、MbedTLSなら何とかできる気がする!



で、APIを置き換えてみたものの・・・結果が違う。
全部じゃなくて、MACのチェックで失敗するものがあるのだ。


何も考えずに置き換えていたのだが、libsodiumは3種類APIがあるのだ。

Authenticated Encryption with Additional Data using ChaCha20-Poly1305

  • The original construction can safely encrypt up to 2^64 messages with the same key (even more with most protocols), without any practical limit to the size of a message (up to 2^64 bytes for a 128-bit tag).
  • The IETF variant. It can safely encrypt a pratically unlimited number of messages, but individual messages cannot exceed 64*(2^32)-64 bytes (approximatively 256 GB).
  • The XChaCha20 variant, introduced in libsodium 1.0.12. It can safely encrypt a practically unlimited number of messages of any sizes, and random nonces are safe to use.

私が使っていたのは、この真ん中のIETF variantというAPI。
ソースファイルを見比べたのだが、originalのものに似ているが、追加されているような感じがする。

MbedTLSでも同じことができるものかは別として、IETF variantが何なのかを調べておこう。


"variant"は「変形」とか「変種」というような意味。
だから、originalに対してIETFなりの変更を加えたバージョンということだろう。

libsodiumのIETF variant APIページの一番下にリンクがあった。

ChaCha20 and Poly1305 for IETF protocols

IETF variantの仕様らしい。
リンク先は、RFC-7539。

あれー、と思うだろう。
だって、MbedTLSのソースファイルにもRFC-7539と書いてあるのだから。。。



むう、もしかして、APIが違うんじゃなくて、置き換え損なっているのだろうか?
APIが同じ種類かどうかは、テストデータを動かして確認するしかあるまい。



https://gist.github.com/hirokuma/e8d3e68300810d284b7d65df5473fe22

データをMbedTLSのtestから持ってきて、APIはlibsodium 1.0.16で実装。
困ったことに、"ok"が出力されてしまった。


なんで困ったかというと、encryptのテストしかないからだ。
失敗していたのはMACのチェックなので、どちらかといえばdecryptの方なのだ。

これは、もっとちゃんと調べろ、ということなんだろう。