TG-3をベースに書いてありますが、おそらく他のOLYMPUS Image Share対応のOlympusカメラでも最低限の修正で使えるのではと思います。
そもそものきっかけは、所有しているOlympus TG-3の機能を外部から自由にコントロールできれば便利じゃまいか…ということ。
公式にはOLYMPUS Image ShareというWi-fi経由でOlympusカメラを操れるスマホアプリがあってそれなりに使えるのだが、あまり使い勝手がよくない。
コントローラを自作しようにもこれらのWi-fi経由のコントロール用プロトコルがどんなものかググってみたが、残念ながらWeb上には断片的な情報しか見つからない。
そこでエンジニアの特権と裏技を使って、動作中のOI ShareのWi-fiパケットを抜き出してみた。

見たところどうやらhttpプロトコルを用いて通信をしているらしい。
更にパケットの中身から得られたキーワードでググってみると(TG用ではないが)ヒントになるサイトが見つかった。
https://gist.github.com/mangelajo/6fa005ff3544fecdecfa
更にここの情報から、OPC(Open Platform Cameras)というものに辿りつく。
http://opc.olympus-imaging.com/en_sdkdocs/index.html
これは何かというと、去年発売されたOLYMPUS AIR A01というオープンプラットフォームカメラの制御プロトコルが公開されているもので、結局はImage Shareの使用しているプロトコルもこのOPCの亜種であることを突き止めた。
OPCの仕様は上のリンクからダウンロードできるので、これを参考にしながらある程度TG3のWi-fiコントロールができるようになりました。
その概要は以下のような感じ。より詳細はOPCの仕様書参照。
・カメラ側がWi-fiアクセスポイント、コントローラ側がステーションとなる。コントローラはカメラ側が示すSSIDとパスワードに従ってDHCPでログイン。
・Wi-fi接続が完了すれば、あとは決められたフォーマットに従ってhttpプロトコルで通信をしながらコントロールを行う。
・カメラのIPアドレスは192.168.0.10固定。
・各カメラには固有のコマンド群が存在する。それぞれのコマンドは
http://192.168.0.10/コマンド名.cgi
の形式で呼び出す。
・コマンドに引数(OPCではオプションと呼ばれる)がある場合は
http://192.168.0.10/コマンド名.cgi?オプション名1=オプション値1&オプション名2=オプション値2...
という風にURI上につなげていく。
・情報のやりとりが発生するコマンドではメッセージボディにxml形式の情報(エレメントと呼ばれるみたい)を埋め込むことで情報交換を行う。
・メッセージボディはその他にも画像や動画ファイルそのものを格納することもある。
・httpヘッダー部分に'Host: 192.168.0.10' 'Connection: Keep-Alive' 'User-Agent: OI.Share v2'などを指定しないと動作しないみたい。詳細は後述のサンプルにて。
・コマンドによってPOSTするかGETするかが決められている。
おそらく、ゴタクを並べるよりサンプルを示した方がわかりやすいと思うので、以下実習編です。
[準備]
・Wi-fi接続できるPC。Win10にて動作確認しましたが、おそらくMac&Linuxでもほぼ同様だと思います。
・コマンドウインドウ上にてcurlコマンドが動作すること。おそらくMSYS(2)やCygwinなどをインストールすれば使えるようになるはず。
・ちなみにcurlコマンドとは、httpプロトコルの細かいやりとりをコマンドライン上でできるプログラム。
・念のためFirewallはOFFにしておく。
[接続手順]
・TG側のWi-fi接続設定を"プライベート接続"に
・TGのWi-fiをOn。TG画面上に以下のようなSSIDとパスワードが表示されるので記録。

・PCからWi-fiアクセスポイント一覧を見ると上のSSIDが見えるはずなので接続。パスワード入力でTGにログインできる。
・コマンドウインドウからping 192.168.0.10を実行してみて通っているかどうかを確認。
[簡単な動作確認]
まず、コマンドウインドウ上でget_commandlistコマンドを実行してみる。get_commandlistは接続しているカメラで使用できるコマンドとオプション名・値一覧をxmlで返してくれる。
get_commandlistコマンドはどのカメラでもサポートされている(と思う)。以降実行はbash shell使用を前提。
curl -v --header 'Host: 192.168.0.10' --header 'Connection: Keep-Alive' --header 'User-Agent: OI.Share v2' "http://192.168.0.10/get_commandlist.cgi" >commandlist.xml
ちなみに-vオプションは無くてもよく、入れると情報表示が多くなるがエラーが発生したときに原因追求がしやすくなるのでお好みで。
ヘッダーはこれを指定しないと受け付けてくれないようなのでオマジナイ。
成功するとcommandlist.xmlが作られるのでこれをxmlビューアで開いてみると。

使用できる(get_commandlist以外の)すべてのコマンドとそのオプションが羅列されているので、後述のdesclistと合わせて深く見ていくといろいろ発見がある。残念ながらまだ全部理解できていないし、実際は使えないオプションもあるようなので結構手ごわい。
更に、desclistはcommandlistを補完するというもののようで以下のようにして取得する。これはrecモード(仕様書参照)でなければ取得できないみたいなので、2ステップになっています。
curl --header 'Host: 192.168.0.10' --header 'Connection: Keep-Alive' --header 'User-Agent: OI.Share v2' "http://192.168.0.10/switch_cammode.cgi?mode=rec&lvqty=0320x0240"
curl --header 'Host: 192.168.0.10' --header 'Connection: Keep-Alive' --header 'User-Agent: OI.Share v2' "http://192.168.0.10/get_camprop.cgi?com=desc&propname=desclist" >desclist.xml
これで作成されるdesclist.xmlはこんな感じで、上述のエレメントに相当する情報がここに格納されている模様。もうすこしすっきりした構造にして欲しいところだが仕方がない。

さてでは実際に1枚撮影してその画像をPCに転送するまでをやってみます。
curl -v --header 'Host: 192.168.0.10' --header 'Connection: Keep-Alive' --header 'User-Agent: OI.Share v2' "http://192.168.0.10/switch_cammode.cgi?mode=rec&lvqty=0320x0240"
curl -v -X POST --header 'Content-Length: 49' --header 'Content-Type: text/plain; charset=ISO-8859-1' --header 'Host: 192.168.0.10' --header 'Connection: Keep-Alive' --header 'User-Agent: OI.Share v2' -d '' "http://192.168.0.10/set_camprop.cgi?com=set&propname=takemode" A
curl -v --header 'Host: 192.168.0.10' --header 'Connection: Keep-Alive' --header 'User-Agent: OI.Share v2' "http://192.168.0.10/exec_takemisc.cgi?com=startliveview&port=37789"
curl -v -X POST --header 'Content-Length: 52' --header 'Content-Type: text/plain; charset=ISO-8859-1' --header 'Host: 192.168.0.10' --header 'Connection: Keep-Alive' --header 'User-Agent: OI.Share v2' -d '' "http://192.168.0.10/set_camprop.cgi?com=set&propname=isospeedvalue" 6400
curl -v --header 'Host: 192.168.0.10' --header 'Connection: Keep-Alive' --header 'User-Agent: OI.Share v2' "http://192.168.0.10/exec_takemotion.cgi?com=assignafframe&point=0160x0240"
sleep 1
curl -v --header 'Host: 192.168.0.10' --header 'Connection: Keep-Alive' --header 'User-Agent: OI.Share v2' "http://192.168.0.10/exec_takemotion.cgi?com=starttake"
sleep 1
curl -v --header 'Host: 192.168.0.10' --header 'Connection: Keep-Alive' --header 'User-Agent: OI.Share v2' "http://192.168.0.10/exec_takemisc.cgi?com=getlastjpg" >last.jpg
実行すると撮影された画像がlast.jpgとして保存される。
詳細は先ほどのcommandlist.xmlとOPC仕様書を突き合せれば追っていけるかと思うので省略して、主要なところのみ。
・おおまかには 動作モード指定->撮影モード指定->ライブビュー開始->ISO指定(POSTの例として)->フォーカス位置指定->撮影->画像取得 の流れ。
・GETとPOSTの使い分けに注意。POSTのときにはヘッダー指定が増える点も注意。
・xmlをPOSTする場合、xml長をContent-Lengthで指定する必要があって面倒。これを間違えるとハングアップする。
・フォーカス位置を調整するにはpoint=で指定される座標を変更する。座標系は冒頭で指定したlvqty=0320x0240に準拠する模様。
・最終行を省略すると画像は転送されずカメラ本体にのみ格納される。
おまけですが、応用編でTimelapseを。
TG3は本体でもTimelapseモードを持っているのですがなぜか99枚までしか撮れず(30fpsだと3秒ちょっと)、レリーズもつけられないので事実上きちんとしたTimelapse撮影は不可能なのですが、このスクリプトを使うと連続インターバル撮影が可能になりあとはバッテリーの持ちとの勝負になります。
撮影間隔は5秒にしてあるが、数字を変えると調整できます。
curl -v --header 'Host: 192.168.0.10' --header 'Connection: Keep-Alive' --header 'User-Agent: OI.Share v2' "http://192.168.0.10/switch_cammode.cgi?mode=rec&lvqty=0320x0240"
curl -v -X POST --header 'Content-Length: 49' --header 'Content-Type: text/plain; charset=ISO-8859-1' --header 'Host: 192.168.0.10' --header 'Connection: Keep-Alive' --header 'User-Agent: OI.Share v2' -d '' "http://192.168.0.10/set_camprop.cgi?com=set&propname=takemode" A
curl -v --header 'Host: 192.168.0.10' --header 'Connection: Keep-Alive' --header 'User-Agent: OI.Share v2' "http://192.168.0.10/exec_takemisc.cgi?com=startliveview&port=37789"
curl -v --header 'Host: 192.168.0.10' --header 'Connection: Keep-Alive' --header 'User-Agent: OI.Share v2' "http://192.168.0.10/exec_takemotion.cgi?com=assignafframe&point=0160x0120"
sleep 1
while :
do
curl -v --header 'Host: 192.168.0.10' --header 'Connection: Keep-Alive' --header 'User-Agent: OI.Share v2' "http://192.168.0.10/exec_takemotion.cgi?com=starttake"
sleep 5
done
Web上を見た限りこのあたりの情報は皆無なので(ニーズもあるかどうか不明だが)どなたかの役に立てば幸いです。
この内容の利用によって生じた損害については一切の責任を負いません。