Sample program that can send the recognition data from HVC-P2 to Fujitsu IoT Platform using REST (HTTP)

Dependencies:   AsciiFont GR-PEACH_video GraphicsFramework LCD_shield_config R_BSP USBHost_custom easy-connect-gr-peach mbed-http picojson

Information

Here are both English and Japanese description. First, English description is shown followed by Japanese one. 本ページには英語版と日本語版の説明があります。まず英語版、続いて日本語版の説明となります。

Overview

This sample program shows how to send the cognitive data gathered by Omron HVC-P2 (Human Vision Components B5T-007001) to IoT Platform managed by FUJITSU ( http://jp.fujitsu.com/solutions/cloud/k5/function/paas/iot-platform/ ).

Hardware Configuration

/media/uploads/dkato/composition_hvcp2_demo.jpg

When executing this sample program, please configure the above H/W as shown below:
/media/uploads/dkato/composition_hvcp2_demo_2.jpg

Also, please close JP3 of GR-PEACH as follows:
/media/uploads/RyoheiHagimoto/usb.jpg

Application Preconfiguration

Build Procedure

  • Import this sample program onto mbed Compiler
  • In GR-PEACH_HVC-P2_IoTPlatform_http/IoT_Platform/iot_platform.cpp, please replace <ACCESS CODE> with the access code you set up on IoT Platform. For details on how to set up Access Code, please refer to the above Application Setup. Then, please delete the line beginning with #error macro.

Access Code configuration

#define ACCESS_CODE <Access CODE>
#error "You need to replace <Access CODE for your resource> with yours"
  • In GR-PEACH_HVC-P2_IoTPlatform_http/IoT_Platform/iot_platform.cpp, please replace <Base URI>, <Tenant ID> and <Path-to-Resource> below with yours and delete the line beginning with #error macro. For details on <Base URI> and <Tenant ID>, please contact FUJITSU LIMITED. Also, for details on <Path-to-Resource>, please refer to the above Application Setup.

URI configuration

std::string put_uri_base("<Base URI>/v1/<Tenant ID>/<Path-to-Resource>.json");
#error "You need to replace <Base URI>, <Tenant ID> and <Path-to-Resource> with yours"
**snip**
std::string get_uri("<Base URI>/v1/<Tenant ID>/<Path-to-Resource>/_past.json");
#error "You need to replace <Base URI>, <Tenant ID> and <Path-to-Resource> with yours"
  • Compile the program. If compilation is successfully terminated, the binary should be downloaded on your PC.
  • Plug Ethernet cable into GR-PEACH
  • Plug micro-USB cable into the port which lies on the next to RESET button. If GR-PEACH is successfully recognized, it appears as the USB flash disk named mbed as show below:
    /media/uploads/HinoNaka/mbed_drive.png
  • Copy the downloaded binary to mbed drive
  • Press RESET button on GR-PEACH in order to run the program. If it's successfully run, you can see the following message on terminal:
    /media/uploads/HinoNaka/iotplatform_log.png

Format of Data to be sent to IoT Platform

In this program, the cognitive data sent from HVC-P2 is serialized in the following JSON format and send it to IoT Platform:

  • Face detection data

{
    "RecodeType": "HVC-P2(face)"
    "id": <GR-PEACH ID>-<Sensor ID>"
    "FaceRectangle": {
        "Height": xxxx,
        "Left": xxxx,
        "Top": xxxx,
        "Width": xxxx,
    },
    "Gender": "male" or "female",
    "Scores": {
        "Anger": zzz,
        "Hapiness": zzz,
        "Neutral": zzz,
        "Sadness": zzz,
        "Surprise": zzz
    }
}

xxxx: Top-left coordinate, width and height of the rectangle circumscribing the detected face in LCD display coordinate system
zzz: the value indicating the expression estimated from the detected face

//

  • Body detection data

{
    "RecodeType": "HVC-P2(body)"
    "id": <GR-PEACH ID>-<Sensor ID>"
    "BodyRectangle": {
        "Height": xxxx,
        "Left": xxxx,
        "Top": xxxx,
        "Width": xxxx,
    }
}

xxxx: Top-left coordinate, width and height of the rectangle circumscribing the detected body in LCD display coordinate system

概要

本プログラムは、オムロン社製HVC-P2 (Human Vision Components B5T-007001)で収集した各種認識データを、富士通社のIoT Platform ( http://jp.fujitsu.com/solutions/cloud/k5/function/paas/iot-platform/ ) に送信するサンプルプログラムです。

ハードウェア構成

/media/uploads/dkato/composition_hvcp2_demo.jpg

本プログラムを動作させる場合、上記H/Wを下図のように接続してください。 /media/uploads/dkato/composition_hvcp2_demo_2.jpg

また下図に示すGR-PEACHのJP3をショートしてください。 /media/uploads/RyoheiHagimoto/usb.jpg

アプリケーションの事前設定

ビルド手順

  • 本サンプルプログラムをmbed Compilerにインポートします
  • 下記に示すGR-PEACH_HVC-P2_IoTPlatform_http/IoT_Platform/iot_platform.cpp中の<ACCESS CODE> を、IoT Platform上で設定したアクセスコードで上書きしてください。<Access Code>の設定方法につきましては、上述のApplication Setupを参照願います。また #errorマクロで始まる行を削除してください。

Access Code configuration

#define ACCESS_CODE <Access CODE>
#error "You need to replace <Access CODE for your resource> with yours"
  • 下記に示すGR-PEACH_HVC-P2_IoTPlatform_http/IoT_Platform/iot_platform.cpp中の<Base URI><Tenant ID>、および<Path-to-Resource>>を適当な値に置換えるとともに、#errorマクロで始まる行を削除してください。ここで、<Base URI>、 <Tenant ID>の詳細につきましては富士通社へご確認願います。また<Path-to-Resource>>につきましては、Application Setupの項を参照ください。

URI configuration

std::string put_uri_base("<Base URI>/v1/<Tenant ID>/<Path-to-Resource>.json");
#error "You need to replace <Base URI>, <Tenant ID> and <Path-to-Resource> with yours"
(中略)
std::string get_uri("<Base URI>/v1/<Tenant ID>/<Path-to-Resource>/_past.json");
#error "You need to replace <Base URI>, <Tenant ID> and <Path-to-Resource> with yours"
  • プログラムをコンパイルします。コンパイルが正常終了すると、バイナリがお使いのPCにダウンロードされます。
  • GR-PEACHのRJ-45コネクタにEthernetケーブルを差し込んでください。
  • USBA - Micro USBケーブルを、GR-PEACHのRESETボタンの隣に配置されたMicro USBポートに差し込んでください。GR-PEACHが正常に認識されると、下図に示すようにGR-PEACHがmbedという名称のUSBドライブとして認識されます。
    /media/uploads/HinoNaka/mbed_drive.png
  • ダウンロードしたバイナリをmbedドライブにコピーします。
  • RESETボタンを押下してプログラムを実行します。正常に実行された場合、下記に示すメッセージがターミナル上に表示されます。
    /media/uploads/HinoNaka/iotplatform_log.png

送信データフォーマット

本プログラムでは、HVC-P2が収集した認識データを下記のJSONフォーマットにシリアライズし、IoT Platformへ送信します。

  • Face detection data

{
    "RecodeType": "HVC-P2(face)"
    "id": <GR-PEACH ID>-<Sensor ID>"
    "FaceRectangle": {
        "Height": xxxx,
        "Left": xxxx,
        "Top": xxxx,
        "Width": xxxx,
    },
    "Gender": "male" or "female",
    "Scores": {
        "Anger": zzz,
        "Hapiness": zzz,
        "Neutral": zzz,
        "Sadness": zzz,
        "Surprise": zzz
    }
}

xxxx: LCD表示座標系における検出した顔に外接する矩形の左上座標・幅・高さ
zzz: 検出した顔から推定した各種感情を示す数値

//

  • Body detection data

{
    "RecodeType": "HVC-P2(body)"
    "id": <GR-PEACH ID>-<Sensor ID>"
    "BodyRectangle": {
        "Height": xxxx,
        "Left": xxxx,
        "Top": xxxx,
        "Width": xxxx,
    }
}

xxxx: LCD表示座標系における検出した人体に外接する矩形の左上座標・幅・高さ
Committer:
Osamu Nakamura
Date:
Thu Sep 07 18:15:54 2017 +0900
Revision:
0:813a237f1c50
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Osamu Nakamura 0:813a237f1c50 1 /* NTPClient.cpp */
Osamu Nakamura 0:813a237f1c50 2 /* Copyright (C) 2012 mbed.org, MIT License
Osamu Nakamura 0:813a237f1c50 3 *
Osamu Nakamura 0:813a237f1c50 4 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
Osamu Nakamura 0:813a237f1c50 5 * and associated documentation files (the "Software"), to deal in the Software without restriction,
Osamu Nakamura 0:813a237f1c50 6 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
Osamu Nakamura 0:813a237f1c50 7 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Osamu Nakamura 0:813a237f1c50 8 * furnished to do so, subject to the following conditions:
Osamu Nakamura 0:813a237f1c50 9 *
Osamu Nakamura 0:813a237f1c50 10 * The above copyright notice and this permission notice shall be included in all copies or
Osamu Nakamura 0:813a237f1c50 11 * substantial portions of the Software.
Osamu Nakamura 0:813a237f1c50 12 *
Osamu Nakamura 0:813a237f1c50 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
Osamu Nakamura 0:813a237f1c50 14 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Osamu Nakamura 0:813a237f1c50 15 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
Osamu Nakamura 0:813a237f1c50 16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Osamu Nakamura 0:813a237f1c50 17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Osamu Nakamura 0:813a237f1c50 18 */
Osamu Nakamura 0:813a237f1c50 19
Osamu Nakamura 0:813a237f1c50 20 //Debug is disabled by default
Osamu Nakamura 0:813a237f1c50 21 #if 0
Osamu Nakamura 0:813a237f1c50 22 //Enable debug
Osamu Nakamura 0:813a237f1c50 23 #define __DEBUG__
Osamu Nakamura 0:813a237f1c50 24 #include <cstdio>
Osamu Nakamura 0:813a237f1c50 25 #define DBG(x, ...) std::printf("[NTPClient : DBG]"x"\r\n", ##__VA_ARGS__);
Osamu Nakamura 0:813a237f1c50 26 #define WARN(x, ...) std::printf("[NTPClient : WARN]"x"\r\n", ##__VA_ARGS__);
Osamu Nakamura 0:813a237f1c50 27 #define ERR(x, ...) std::printf("[NTPClient : ERR]"x"\r\n", ##__VA_ARGS__);
Osamu Nakamura 0:813a237f1c50 28
Osamu Nakamura 0:813a237f1c50 29 #else
Osamu Nakamura 0:813a237f1c50 30 //Disable debug
Osamu Nakamura 0:813a237f1c50 31 #define DBG(x, ...)
Osamu Nakamura 0:813a237f1c50 32 #define WARN(x, ...)
Osamu Nakamura 0:813a237f1c50 33 #define ERR(x, ...)
Osamu Nakamura 0:813a237f1c50 34
Osamu Nakamura 0:813a237f1c50 35 #endif
Osamu Nakamura 0:813a237f1c50 36
Osamu Nakamura 0:813a237f1c50 37 #include "NTPClient.h"
Osamu Nakamura 0:813a237f1c50 38
Osamu Nakamura 0:813a237f1c50 39 #include "UDPSocket.h"
Osamu Nakamura 0:813a237f1c50 40
Osamu Nakamura 0:813a237f1c50 41 #include "mbed.h" //time() and set_time()
Osamu Nakamura 0:813a237f1c50 42
Osamu Nakamura 0:813a237f1c50 43 #define NTP_PORT 123
Osamu Nakamura 0:813a237f1c50 44 #define NTP_CLIENT_PORT 0 //Random port
Osamu Nakamura 0:813a237f1c50 45 #define NTP_TIMESTAMP_DELTA 2208988800ull //Diff btw a UNIX timestamp (Starting Jan, 1st 1970) and a NTP timestamp (Starting Jan, 1st 1900)
Osamu Nakamura 0:813a237f1c50 46
Osamu Nakamura 0:813a237f1c50 47 NTPClient::NTPClient() : m_sock()
Osamu Nakamura 0:813a237f1c50 48 {
Osamu Nakamura 0:813a237f1c50 49
Osamu Nakamura 0:813a237f1c50 50
Osamu Nakamura 0:813a237f1c50 51 }
Osamu Nakamura 0:813a237f1c50 52
Osamu Nakamura 0:813a237f1c50 53 #if MBED_MAJOR_VERSION >= 5
Osamu Nakamura 0:813a237f1c50 54
Osamu Nakamura 0:813a237f1c50 55 #include <SocketAddress.h>
Osamu Nakamura 0:813a237f1c50 56 #include <EthernetInterface.h>
Osamu Nakamura 0:813a237f1c50 57 //extern EthernetInterface ei_;
Osamu Nakamura 0:813a237f1c50 58 EthernetInterface ei_;
Osamu Nakamura 0:813a237f1c50 59
Osamu Nakamura 0:813a237f1c50 60 class Endpoint {
Osamu Nakamura 0:813a237f1c50 61 SocketAddress sa_;
Osamu Nakamura 0:813a237f1c50 62 public:
Osamu Nakamura 0:813a237f1c50 63 Endpoint() : sa_() {}
Osamu Nakamura 0:813a237f1c50 64 int set_address(const char* host, uint16_t port)
Osamu Nakamura 0:813a237f1c50 65 {
Osamu Nakamura 0:813a237f1c50 66 sa_.set_port(port);
Osamu Nakamura 0:813a237f1c50 67 return nsapi_create_stack(&ei_)->gethostbyname(host, &sa_);
Osamu Nakamura 0:813a237f1c50 68 }
Osamu Nakamura 0:813a237f1c50 69 const char* get_address() const { return sa_.get_ip_address(); }
Osamu Nakamura 0:813a237f1c50 70 operator const SocketAddress&() { return sa_; }
Osamu Nakamura 0:813a237f1c50 71 operator SocketAddress*() { return &sa_; }
Osamu Nakamura 0:813a237f1c50 72 };
Osamu Nakamura 0:813a237f1c50 73
Osamu Nakamura 0:813a237f1c50 74 class LegacyUS {
Osamu Nakamura 0:813a237f1c50 75 UDPSocket us_;
Osamu Nakamura 0:813a237f1c50 76 public:
Osamu Nakamura 0:813a237f1c50 77 LegacyUS() : us_() {}
Osamu Nakamura 0:813a237f1c50 78 int bind(int port)
Osamu Nakamura 0:813a237f1c50 79 {
Osamu Nakamura 0:813a237f1c50 80 us_.open(&ei_);
Osamu Nakamura 0:813a237f1c50 81 return us_.bind(port);
Osamu Nakamura 0:813a237f1c50 82 }
Osamu Nakamura 0:813a237f1c50 83 void set_blocking(bool blocking, unsigned int)
Osamu Nakamura 0:813a237f1c50 84 {
Osamu Nakamura 0:813a237f1c50 85 us_.set_blocking(blocking);
Osamu Nakamura 0:813a237f1c50 86 }
Osamu Nakamura 0:813a237f1c50 87 int close() { return us_.close(); }
Osamu Nakamura 0:813a237f1c50 88 int sendTo(Endpoint& remote, char* packet, int length)
Osamu Nakamura 0:813a237f1c50 89 {
Osamu Nakamura 0:813a237f1c50 90 return us_.sendto(remote, packet, length);
Osamu Nakamura 0:813a237f1c50 91 }
Osamu Nakamura 0:813a237f1c50 92 int receiveFrom(Endpoint& remote, char* buffer, int length)
Osamu Nakamura 0:813a237f1c50 93 {
Osamu Nakamura 0:813a237f1c50 94 int ret = us_.recvfrom(remote, buffer, length);
Osamu Nakamura 0:813a237f1c50 95 if( ret == NSAPI_ERROR_WOULD_BLOCK )
Osamu Nakamura 0:813a237f1c50 96 {
Osamu Nakamura 0:813a237f1c50 97 wait(0.1);
Osamu Nakamura 0:813a237f1c50 98 ret = 0;
Osamu Nakamura 0:813a237f1c50 99 }
Osamu Nakamura 0:813a237f1c50 100 return ret;
Osamu Nakamura 0:813a237f1c50 101 }
Osamu Nakamura 0:813a237f1c50 102 };
Osamu Nakamura 0:813a237f1c50 103 #define m_sock (*((LegacyUS*)&m_sock))
Osamu Nakamura 0:813a237f1c50 104
Osamu Nakamura 0:813a237f1c50 105 #endif // MBED_MAJOR_VERSION >= 5
Osamu Nakamura 0:813a237f1c50 106
Osamu Nakamura 0:813a237f1c50 107 NTPResult NTPClient::setTime(const char* host, uint16_t port, uint32_t timeout)
Osamu Nakamura 0:813a237f1c50 108 {
Osamu Nakamura 0:813a237f1c50 109 #ifdef __DEBUG__
Osamu Nakamura 0:813a237f1c50 110 time_t ctTime;
Osamu Nakamura 0:813a237f1c50 111 ctTime = time(NULL);
Osamu Nakamura 0:813a237f1c50 112 DBG("Time is set to (UTC): %s", ctime(&ctTime));
Osamu Nakamura 0:813a237f1c50 113 #endif
Osamu Nakamura 0:813a237f1c50 114
Osamu Nakamura 0:813a237f1c50 115 //Create & bind socket
Osamu Nakamura 0:813a237f1c50 116 DBG("Binding socket");
Osamu Nakamura 0:813a237f1c50 117 m_sock.bind(0); //Bind to a random port
Osamu Nakamura 0:813a237f1c50 118
Osamu Nakamura 0:813a237f1c50 119 m_sock.set_blocking(false, timeout); //Set not blocking
Osamu Nakamura 0:813a237f1c50 120
Osamu Nakamura 0:813a237f1c50 121 struct NTPPacket pkt;
Osamu Nakamura 0:813a237f1c50 122
Osamu Nakamura 0:813a237f1c50 123 //Now ping the server and wait for response
Osamu Nakamura 0:813a237f1c50 124 DBG("Ping");
Osamu Nakamura 0:813a237f1c50 125 //Prepare NTP Packet:
Osamu Nakamura 0:813a237f1c50 126 pkt.li = 0; //Leap Indicator : No warning
Osamu Nakamura 0:813a237f1c50 127 pkt.vn = 4; //Version Number : 4
Osamu Nakamura 0:813a237f1c50 128 pkt.mode = 3; //Client mode
Osamu Nakamura 0:813a237f1c50 129 pkt.stratum = 0; //Not relevant here
Osamu Nakamura 0:813a237f1c50 130 pkt.poll = 0; //Not significant as well
Osamu Nakamura 0:813a237f1c50 131 pkt.precision = 0; //Neither this one is
Osamu Nakamura 0:813a237f1c50 132
Osamu Nakamura 0:813a237f1c50 133 pkt.rootDelay = 0; //Or this one
Osamu Nakamura 0:813a237f1c50 134 pkt.rootDispersion = 0; //Or that one
Osamu Nakamura 0:813a237f1c50 135 pkt.refId = 0; //...
Osamu Nakamura 0:813a237f1c50 136
Osamu Nakamura 0:813a237f1c50 137 pkt.refTm_s = 0;
Osamu Nakamura 0:813a237f1c50 138 pkt.origTm_s = 0;
Osamu Nakamura 0:813a237f1c50 139 pkt.rxTm_s = 0;
Osamu Nakamura 0:813a237f1c50 140 pkt.txTm_s = htonl( NTP_TIMESTAMP_DELTA + time(NULL) ); //WARN: We are in LE format, network byte order is BE
Osamu Nakamura 0:813a237f1c50 141
Osamu Nakamura 0:813a237f1c50 142 pkt.refTm_f = pkt.origTm_f = pkt.rxTm_f = pkt.txTm_f = 0;
Osamu Nakamura 0:813a237f1c50 143
Osamu Nakamura 0:813a237f1c50 144 Endpoint outEndpoint;
Osamu Nakamura 0:813a237f1c50 145
Osamu Nakamura 0:813a237f1c50 146 if( outEndpoint.set_address(host, port) < 0)
Osamu Nakamura 0:813a237f1c50 147 {
Osamu Nakamura 0:813a237f1c50 148 m_sock.close();
Osamu Nakamura 0:813a237f1c50 149 return NTP_DNS;
Osamu Nakamura 0:813a237f1c50 150 }
Osamu Nakamura 0:813a237f1c50 151
Osamu Nakamura 0:813a237f1c50 152 //Set timeout, non-blocking and wait using select
Osamu Nakamura 0:813a237f1c50 153 int ret = m_sock.sendTo( outEndpoint, (char*)&pkt, sizeof(NTPPacket) );
Osamu Nakamura 0:813a237f1c50 154 if (ret < 0 )
Osamu Nakamura 0:813a237f1c50 155 {
Osamu Nakamura 0:813a237f1c50 156 ERR("Could not send packet");
Osamu Nakamura 0:813a237f1c50 157 m_sock.close();
Osamu Nakamura 0:813a237f1c50 158 return NTP_CONN;
Osamu Nakamura 0:813a237f1c50 159 }
Osamu Nakamura 0:813a237f1c50 160
Osamu Nakamura 0:813a237f1c50 161 //Read response
Osamu Nakamura 0:813a237f1c50 162 Endpoint inEndpoint;
Osamu Nakamura 0:813a237f1c50 163 // Set the inEndpoint address property
Osamu Nakamura 0:813a237f1c50 164 inEndpoint.set_address(outEndpoint.get_address(), 0);
Osamu Nakamura 0:813a237f1c50 165 DBG("Pong");
Osamu Nakamura 0:813a237f1c50 166 do
Osamu Nakamura 0:813a237f1c50 167 {
Osamu Nakamura 0:813a237f1c50 168 ret = m_sock.receiveFrom( inEndpoint, (char*)&pkt, sizeof(NTPPacket) ); //FIXME need a DNS Resolver to actually compare the incoming address with the DNS name
Osamu Nakamura 0:813a237f1c50 169 if(ret < 0)
Osamu Nakamura 0:813a237f1c50 170 {
Osamu Nakamura 0:813a237f1c50 171 ERR("Could not receive packet");
Osamu Nakamura 0:813a237f1c50 172 m_sock.close();
Osamu Nakamura 0:813a237f1c50 173 return NTP_CONN;
Osamu Nakamura 0:813a237f1c50 174 }
Osamu Nakamura 0:813a237f1c50 175 } while( strcmp(outEndpoint.get_address(), inEndpoint.get_address()) != 0 );
Osamu Nakamura 0:813a237f1c50 176
Osamu Nakamura 0:813a237f1c50 177 if(ret < sizeof(NTPPacket)) //TODO: Accept chunks
Osamu Nakamura 0:813a237f1c50 178 {
Osamu Nakamura 0:813a237f1c50 179 ERR("Receive packet size does not match");
Osamu Nakamura 0:813a237f1c50 180 m_sock.close();
Osamu Nakamura 0:813a237f1c50 181 return NTP_PRTCL;
Osamu Nakamura 0:813a237f1c50 182 }
Osamu Nakamura 0:813a237f1c50 183
Osamu Nakamura 0:813a237f1c50 184 if( pkt.stratum == 0) //Kiss of death message : Not good !
Osamu Nakamura 0:813a237f1c50 185 {
Osamu Nakamura 0:813a237f1c50 186 ERR("Kissed to death!");
Osamu Nakamura 0:813a237f1c50 187 m_sock.close();
Osamu Nakamura 0:813a237f1c50 188 return NTP_PRTCL;
Osamu Nakamura 0:813a237f1c50 189 }
Osamu Nakamura 0:813a237f1c50 190
Osamu Nakamura 0:813a237f1c50 191 //Correct Endianness
Osamu Nakamura 0:813a237f1c50 192 pkt.refTm_s = ntohl( pkt.refTm_s );
Osamu Nakamura 0:813a237f1c50 193 pkt.refTm_f = ntohl( pkt.refTm_f );
Osamu Nakamura 0:813a237f1c50 194 pkt.origTm_s = ntohl( pkt.origTm_s );
Osamu Nakamura 0:813a237f1c50 195 pkt.origTm_f = ntohl( pkt.origTm_f );
Osamu Nakamura 0:813a237f1c50 196 pkt.rxTm_s = ntohl( pkt.rxTm_s );
Osamu Nakamura 0:813a237f1c50 197 pkt.rxTm_f = ntohl( pkt.rxTm_f );
Osamu Nakamura 0:813a237f1c50 198 pkt.txTm_s = ntohl( pkt.txTm_s );
Osamu Nakamura 0:813a237f1c50 199 pkt.txTm_f = ntohl( pkt.txTm_f );
Osamu Nakamura 0:813a237f1c50 200
Osamu Nakamura 0:813a237f1c50 201 //Compute offset, see RFC 4330 p.13
Osamu Nakamura 0:813a237f1c50 202 uint32_t destTm_s = (NTP_TIMESTAMP_DELTA + time(NULL));
Osamu Nakamura 0:813a237f1c50 203 int64_t offset = ( (int64_t)( pkt.rxTm_s - pkt.origTm_s ) + (int64_t) ( pkt.txTm_s - destTm_s ) ) / 2; //Avoid overflow
Osamu Nakamura 0:813a237f1c50 204 DBG("Sent @%ul", pkt.txTm_s);
Osamu Nakamura 0:813a237f1c50 205 DBG("Offset: %lld", offset);
Osamu Nakamura 0:813a237f1c50 206 //Set time accordingly
Osamu Nakamura 0:813a237f1c50 207 set_time( time(NULL) + offset );
Osamu Nakamura 0:813a237f1c50 208
Osamu Nakamura 0:813a237f1c50 209 #ifdef __DEBUG__
Osamu Nakamura 0:813a237f1c50 210 ctTime = time(NULL);
Osamu Nakamura 0:813a237f1c50 211 DBG("Time is now (UTC): %s", ctime(&ctTime));
Osamu Nakamura 0:813a237f1c50 212 #endif
Osamu Nakamura 0:813a237f1c50 213
Osamu Nakamura 0:813a237f1c50 214 m_sock.close();
Osamu Nakamura 0:813a237f1c50 215
Osamu Nakamura 0:813a237f1c50 216 return NTP_OK;
Osamu Nakamura 0:813a237f1c50 217 }
Osamu Nakamura 0:813a237f1c50 218
Osamu Nakamura 0:813a237f1c50 219