1aa370db9eed0d646fdde2b3810034f513856c0f
[profile/ivi/ico-vic-amb-plugin.git] / tests / controlwebsocketclient.cc
1 /**
2  * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
3  * 
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  * 
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  * 
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  * 
18  */
19 #include <string.h>
20
21 #include <iostream>
22
23 #include "debugout.h"
24
25 #include "config.h"
26 #include "controlwebsocketclient.h"
27 #include "datamessage.h"
28 #include "eventmessage.h"
29 #include "messageformat.h"
30
31 pthread_mutex_t ControlWebsocketClient::mutex_scenario =
32         PTHREAD_MUTEX_INITIALIZER;
33 pthread_cond_t ControlWebsocketClient::cond_scenario = PTHREAD_COND_INITIALIZER;
34 std::string ControlWebsocketClient::vehiclename_scenario = "";
35
36 ControlWebsocketClient::ControlWebsocketClient()
37 {
38     mutex = PTHREAD_MUTEX_INITIALIZER;
39     protocollist[1] = {NULL, NULL, 0};
40 }
41
42 ControlWebsocketClient::~ControlWebsocketClient()
43 {
44 }
45
46 bool
47 ControlWebsocketClient::initialize(int port,
48                                    enum ControlWebsocket::ServerProtocol stype)
49 {
50     DebugOut(10) << "ControlWebsocketClient initialize.(" << port << ")\n";
51     type = stype;
52     switch (type) {
53     case ControlWebsocket::DATA_STANDARD:
54     {
55         protocollist[0] = {"standarddatamessage-only", ControlWebsocketClient::callback_receive, 0};
56         break;
57     }
58     case ControlWebsocket::CONTROL_STANDARD : {
59         protocollist[0] = {"standardcontrolmessage-only", ControlWebsocketClient::callback_receive, 0};
60         break;
61     }
62     case ControlWebsocket::DATA_CUSTOM : {
63         protocollist[0] = {"customdatamessage-only", ControlWebsocketClient::callback_receive, 0};
64         break;
65     }
66     case ControlWebsocket::CONTROL_CUSTOM : {
67         protocollist[0] = {"customcontrolmessage-only", ControlWebsocketClient::callback_receive, 0};
68         break;
69     }
70     default : {
71         return false;
72     }
73     }
74     context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, "lo",
75                                           protocollist,
76                                           libwebsocket_internal_extensions,
77                                           NULL, NULL, -1, -1, 0);
78     if (context == NULL) {
79         return false;
80     }
81     socket = libwebsocket_client_connect(context, "127.0.0.1", port, 0, "/",
82                                          "localhost", "websocket",
83                                          protocollist[0].name, -1);
84     if (socket == NULL) {
85         return false;
86     }
87     if (pthread_create(&threadid, NULL, ControlWebsocketClient::run,
88                        (void*)this) == -1) {
89         libwebsocket_context_destroy(context);
90         return false;
91     }
92     return true;
93 }
94
95 bool
96 ControlWebsocketClient::send(char *keyeventtype, timeval time, void *data,
97                              size_t len)
98 {
99     pthread_mutex_lock(&mutex);
100     memset(buf, 0, sizeof(buf));
101     switch (type) {
102     case ControlWebsocket::DATA_STANDARD:
103     case ControlWebsocket::DATA_CUSTOM:
104     {
105         memcpy(buf + LWS_SEND_BUFFER_PRE_PADDING,
106                datamsg.encode(keyeventtype, time,
107                               *(reinterpret_cast<DataOpt*>(data))),
108                len);
109         DebugOut(10) << keyeventtype << " encode\n";
110         break;
111     }
112     case ControlWebsocket::CONTROL_STANDARD:
113     case ControlWebsocket::CONTROL_CUSTOM:
114     {
115         memcpy(buf + LWS_SEND_BUFFER_PRE_PADDING,
116                eventmsg.encode(keyeventtype, time,
117                                *(reinterpret_cast<EventOpt*>(data))),
118                len);
119         break;
120     }
121     default:
122     {
123         return false;
124         break;
125     }
126     }
127     int ret = libwebsocket_write(
128             socket,
129             reinterpret_cast<unsigned char*>(buf + LWS_SEND_BUFFER_PRE_PADDING),
130             len, LWS_WRITE_BINARY);
131     DebugOut(10) << "libwebsocket_write return " << ret << "\n";
132     pthread_mutex_unlock(&mutex);
133     return true;
134 }
135
136 bool
137 ControlWebsocketClient::receive(char *keyeventtype, timeval recordtime,
138                                 void *data, size_t len)
139 {
140     datamsg.decodeOpt(keyeventtype, recordtime, data);
141     return true;
142 }
143
144 void
145 ControlWebsocketClient::observation()
146 {
147     int ret = 0;
148     while (ret >= 0) {
149         ret = libwebsocket_service(context, 100);
150         if (ret != 0) {
151             break;
152         }
153     }
154 }
155
156 int
157 ControlWebsocketClient::callback_receive(libwebsocket_context *context,
158                                          libwebsocket *wsi,
159                                          libwebsocket_callback_reasons reason,
160                                          void *user, void *in, size_t len)
161 {
162     switch (reason) {
163     case LWS_CALLBACK_CLIENT_RECEIVE:
164     {
165         DataMessage msg;
166         msg.decode(reinterpret_cast<char*>(in), len);
167         DebugOut(10) << "[R]: " << msg.getKeyEventType() << " , "
168                      << msg.getRecordtime().tv_sec << "."
169                      << msg.getRecordtime().tv_usec << " , ";
170         if (string(msg.getKeyEventType())
171                 == ControlWebsocketClient::vehiclename_scenario) {
172             pthread_cond_signal(&ControlWebsocketClient::cond_scenario);
173         }
174         break;
175     }
176     default:
177     {
178         break;
179     }
180     }
181     return 0;
182 }
183
184 void *
185 ControlWebsocketClient::run(void *arg)
186 {
187     ControlWebsocketClient *control =
188             reinterpret_cast<ControlWebsocketClient*>(arg);
189     control->observation();
190     return NULL;
191 }