bdc36a6209a726d41126864a64eea2dae6273e60
[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 #include <unistd.h>
21
22 #include <iostream>
23 #include <sstream>
24
25 #include "debugout.h"
26
27 #include "config.h"
28 #include "controlwebsocketclient.h"
29 #include "datamessage.h"
30 #include "eventmessage.h"
31 #include "messageformat.h"
32
33 pthread_mutex_t ControlWebsocketClient::mutex_scenario =
34         PTHREAD_MUTEX_INITIALIZER;
35 pthread_cond_t ControlWebsocketClient::cond_scenario = PTHREAD_COND_INITIALIZER;
36 std::string ControlWebsocketClient::vehiclename_scenario = "";
37 void *ControlWebsocketClient::wsi[4] = {NULL, NULL, NULL, NULL};
38
39 ControlWebsocketClient::ControlWebsocketClient()
40 {
41     mutex = PTHREAD_MUTEX_INITIALIZER;
42 }
43
44 ControlWebsocketClient::~ControlWebsocketClient()
45 {
46 }
47
48 bool
49 ControlWebsocketClient::initialize(int port,
50                                    enum ControlWebsocket::ServerProtocol stype)
51 {
52     DebugOut(10) << "ControlWebsocketClient initialize.(" << port << ")\n";
53     type = stype;
54     stringstream address, protocol;
55     address.str("");
56     address << "ws://127.0.0.1:" << port;
57     protocol.str("");
58     switch (type) {
59     case ControlWebsocket::DATA_STANDARD:
60     {
61         protocol << "standarddatamessage-only";
62         break;
63     }
64     case ControlWebsocket::CONTROL_STANDARD:
65     {
66         protocol << "standardcontrolmessage-only";
67         break;
68     }
69     case ControlWebsocket::DATA_CUSTOM:
70     {
71         protocol << "customdatamessage-only";
72         break;
73     }
74     case ControlWebsocket::CONTROL_CUSTOM:
75     {
76         protocol << "customcontrolmessage-only";
77         break;
78     }
79     default:
80     {
81         return false;
82     }
83     }
84     context = ico_uws_create_context(address.str().c_str(),
85                                      protocol.str().c_str());
86     if (context == NULL) {
87         return false;
88     }
89     if (ico_uws_set_event_cb(context, ControlWebsocketClient::callback_receive,
90                              ((void *)type)) != 0) {
91         DebugOut() << "ControlWebsocket[" << type << "]"
92                    << " couldn't set callback function." << std::endl;
93         return false;
94     }
95     /*
96      socket = libwebsocket_client_connect(context, "127.0.0.1", port, 0, "/",
97      "localhost", "websocket",
98      protocollist[0].name, -1);
99      if (socket == NULL) {
100      return false;
101      }
102      */
103     if (pthread_create(&threadid, NULL, ControlWebsocketClient::run,
104                        (void*)this) == -1) {
105         ico_uws_close(context);
106         return false;
107     }
108     return true;
109 }
110
111 bool
112 ControlWebsocketClient::send(char *keyeventtype, timeval time, void *data,
113                              size_t len)
114 {
115     pthread_mutex_lock(&mutex);
116     memset(buf, 0, sizeof(buf));
117     switch (type) {
118     case ControlWebsocket::DATA_STANDARD:
119     case ControlWebsocket::DATA_CUSTOM:
120     {
121         memcpy(buf,
122                datamsg.encode(keyeventtype, time,
123                               *(reinterpret_cast<DataOpt*>(data))),
124                               len);
125         DebugOut(10) << keyeventtype << " encode\n";
126         break;
127     }
128     case ControlWebsocket::CONTROL_STANDARD:
129     case ControlWebsocket::CONTROL_CUSTOM:
130     {
131         memcpy(buf,
132                eventmsg.encode(keyeventtype, time,
133                                *(reinterpret_cast<EventOpt*>(data))),
134                len);
135         break;
136     }
137     default:
138     {
139         return false;
140         break;
141     }
142     }
143     ico_uws_send(context, wsi[type], reinterpret_cast<unsigned char*>(buf),
144                  len);
145     pthread_mutex_unlock(&mutex);
146     return true;
147 }
148
149 bool
150 ControlWebsocketClient::receive(char *keyeventtype, timeval recordtime,
151                                 void *data, size_t len)
152 {
153     datamsg.decodeOpt(keyeventtype, recordtime, data);
154     return true;
155 }
156
157 void
158 ControlWebsocketClient::observation()
159 {
160     while (true) {
161         ico_uws_service(context);
162         usleep(50);
163     }
164 }
165
166 void
167 ControlWebsocketClient::callback_receive(const struct ico_uws_context *context,
168                                          const ico_uws_evt_e event,
169                                          const void *id,
170                                          const ico_uws_detail *detail,
171                                          void *user_data)
172 {
173     switch (event) {
174     case ICO_UWS_EVT_OPEN:
175     {
176         int idx = reinterpret_cast<int>(user_data);
177         DebugOut() << "Open. wsi index = " << idx << "\n";
178         ControlWebsocketClient::wsi[idx] = const_cast<void*>(id);
179         break;
180     }
181     case ICO_UWS_EVT_ERROR:
182         break;
183     case ICO_UWS_EVT_CLOSE:
184     {
185         int idx = reinterpret_cast<int>(user_data);
186         ControlWebsocketClient::wsi[idx] = NULL;
187         break;
188     }
189     case ICO_UWS_EVT_RECEIVE:
190     {
191         DataMessage msg;
192         char *recvbuf =
193                 reinterpret_cast<char*>(detail->_ico_uws_message.recv_data);
194         msg.decode(recvbuf, detail->_ico_uws_message.recv_len);
195         DebugOut(10) << "[R]: " << msg.getKeyEventType() << " , "
196                      << msg.getRecordtime().tv_sec << "."
197                      << msg.getRecordtime().tv_usec << " , ";
198         if (string(msg.getKeyEventType())
199                 == ControlWebsocketClient::vehiclename_scenario) {
200             pthread_cond_signal(&ControlWebsocketClient::cond_scenario);
201         }
202         break;
203     }
204     case ICO_UWS_EVT_ADD_FD:
205         break;
206     case ICO_UWS_EVT_DEL_FD:
207         break;
208     default:
209         break;
210     }
211 }
212
213 void *
214 ControlWebsocketClient::run(void *arg)
215 {
216     ControlWebsocketClient *control =
217             reinterpret_cast<ControlWebsocketClient*>(arg);
218     control->observation();
219     return NULL;
220 }