mbed OS5対応版 milkcocoaライブラリ

以前の[記事](http://qiita.com/jksoft/items/6803ac0130dafed9e076)で紹介したmbed OS5対応版のmilkcocoaライブラリが完成したので紹介します。
（milkcocoaについては以前の[記事](http://qiita.com/jksoft/items/6803ac0130dafed9e076)を参照してください。）
　
　　![top.png](https://qiita-image-store.s3.amazonaws.com/0/109992/6c1c531c-65ff-f933-e202-6b6695cab111.png)



##mbed OS5対応とは
mbed OS5に対応というのは、mbed OS5のAPIやサービスに対応したということです。
今回のmilkcocoaライブラリでは、mbed OS5の[Network API](https://docs.mbed.com/docs/mbed-os-api-reference/en/latest/APIs/communication/network_sockets/)と[RTOS](https://docs.mbed.com/docs/mbed-os-api-reference/en/latest/APIs/tasks/rtos/)に対応させました。

###Network API
APIに対応させることによって、I/Fの切り替えが楽にできます。インターネットサービスである[milkcocoa](https://mlkcca.com/)に繋ぐためのEthernetやWi-Fi等のI/FのAPIはオフィシャルで定義されているので、今後はこの定義に従ったAPIを持ったライブラリが増えていくと思います。現状は、Ethernet（LAN)を持ったmbed OS5対応ボード用のライブラリとESP8266のライブラリが対応しています。
###RTOS
milkcocoaとの通信を隠蔽するために通信部分をスレッド化しています。通信は裏で動くのでアプリケーションからは関数を定期的にコールする必要無し、送信するときも通信待ちでブロックされないようにしています。


##ライブラリとサンプル
mbed OS5対応版 milkcocoaライブラリは以下のURLで公開しています。

[https://developer.mbed.org/users/jksoft/code/Milkcocoa-os/](https://developer.mbed.org/users/jksoft/code/Milkcocoa-os/)

サンプルプログラムは以下です。

Ethernet版
[https://developer.mbed.org/users/jksoft/code/MilkcocoaOsSample_Eth/](https://developer.mbed.org/users/jksoft/code/MilkcocoaOsSample_Eth/)

Wi-Fi（ESP8266）版
[https://developer.mbed.org/users/jksoft/code/MilkcocoaOsSample_ESP8266/](https://developer.mbed.org/users/jksoft/code/MilkcocoaOsSample_ESP8266/)

##ライブラリの使い方
サンプルプログラムは次のようになっています。
Ethernet版のサンプルですがコメントを追加してるので参考にしてください。

```main.cpp
#include "mbed.h"
#include "MQTTInterface.h"
#include "MQTTClient.h"
#include "Milkcocoa.h"
#include "MClient.h"
#include "EthernetInterface.h"

EthernetInterface eth;
RawSerial pc(USBTX,USBRX);

/************************* Your Milkcocoa Setup *********************************/

#define MILKCOCOA_APP_ID      "...YOUR_MILKCOCOA_APP_ID..."
#define MILKCOCOA_DATASTORE   "mbed_lan"

/************* Milkcocoa Setup (you don't need to change this!) ******************/

#define MILKCOCOA_SERVERPORT  1883

/************ Global State (you don't need to change this!) ******************/
const char MQTT_SERVER[]  = MILKCOCOA_APP_ID ".mlkcca.com";
const char MQTT_CLIENTID[] = __TIME__ MILKCOCOA_APP_ID;

extern void onpush(MQTT::MessageData& md);

int main() {
    
    pc.baud(9600);
    pc.printf("Milkcocoa mbed os ver demo\n\r\n\r\n\r");
    
    // Ethernet I/Fの準備
    int ret = eth.connect();
    if (ret != 0) {
        printf("\r\nConnection error\r\n");
        return -1;
    }
    pc.printf("\n\rEthernet connected\n\r");
    
    // 第１引数がインターフェースです。mbed　OS5のAPIに対応したクラスを指定します。
    // EthernetでもWi-Fiでもここで指定すれば違いなく使えます。
    Milkcocoa* milkcocoa = new Milkcocoa(&eth, MQTT_SERVER, MILKCOCOA_SERVERPORT, MILKCOCOA_APP_ID, MQTT_CLIENTID);
    
    //Milkcocoaのサーバに接続します。 
    milkcocoa->connect();
    
    // Subscribeの設定をする。
    pc.printf("%d\n\r",milkcocoa->on(MILKCOCOA_DATASTORE, "push", onpush));
    
    // Milkcocoaのサーバに繋げる周期を設定する
    milkcocoa->setLoopCycle(5000);

    // Milkcocoのサーバとの通信を開始する。
    milkcocoa->start();

    while(1) {
        DataElement elem = DataElement();
        elem.setValue("v", 1);
        
        // データをプッシュする
        // (実際はキューに入れるだけで実際にサーバに送信するのは、通信のタイミング)
        milkcocoa->push(MILKCOCOA_DATASTORE, elem);

        Thread::wait(7000);
    }
}

// データを受け取った際にコールされる関数
void onpush(MQTT::MessageData& md)
{
    MQTT::Message &message = md.message;
    DataElement de = DataElement((char*)message.payload);
    pc.printf("onpush\n\r");
    pc.printf("%d\n\r",de.getInt("v"));
}
```

##最後に
mbed OS5もMilkcocoaも仕様が変わったら逐次対応していきたいと思います。
もしバグフィックスや改修があったらプルリクください。