2 * Copyright (C) 2012 TOYOTA MOTOR CORPORATION.
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.
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.
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
24 #include "controlwebsocket.h"
25 #include "mwinterface.h"
26 #include "standardmessage.h"
29 * Socket ID generated class.
32 class GenerateCommID {
35 * This function retrieves an instance of the class.
37 * @return Instance of GenerateCommID
39 static GenerateCommID *
42 static GenerateCommID<T> instance;
47 * This function returns the ID that is registered.
48 * If the ID is not registerd, it register the ID.
50 * @param value Value of socket.
56 pthread_mutex_lock(&mutex);
57 for (auto itr = commidmap.begin(); itr != commidmap.end(); itr++) {
58 if ((*itr).second == value) {
59 pthread_mutex_unlock(&mutex);
63 int newid = generateID();
64 commidmap.insert(make_pair(newid, value));
65 pthread_mutex_unlock(&mutex);
69 * This function returns the socket information registered.
72 * @return Value of socket
77 pthread_mutex_lock(&mutex);
78 if (commidmap.find(id) == commidmap.end()) {
79 pthread_mutex_unlock(&mutex);
82 pthread_mutex_unlock(&mutex);
87 * This function removes the socket information registered.
90 * @return Success : true Failure : false
95 pthread_mutex_lock(&mutex);
97 auto itr = commidmap.find(id);
98 if (itr != commidmap.end()) {
99 itr = commidmap.erase(itr);
102 pthread_mutex_unlock(&mutex);
106 GenerateCommID() : mutex(PTHREAD_MUTEX_INITIALIZER)
115 GenerateCommID(const GenerateCommID &)
119 const GenerateCommID&
120 operator =(const GenerateCommID &)
127 if (commidmap.empty()) {
131 for (auto itr = commidmap.begin(); itr != commidmap.end(); itr++) {
132 if (itr->first != count) {
140 std::map<int, T> commidmap;
141 pthread_mutex_t mutex;
144 MWIF *ControlWebsocket::mwif = NULL;
146 ControlWebsocket::ControlWebsocket()
148 mutex = PTHREAD_MUTEX_INITIALIZER;
149 protocollist[1] = {NULL, NULL, 0};
152 ControlWebsocket::~ControlWebsocket()
158 ControlWebsocket::initialize(int port, enum ServerProtocol stype)
160 DebugOut() << "ControlWebsocket[" << type << "]" << " initialize.(" << port
166 protocollist[0] = {"standarddatamessage-only", ControlWebsocket::callback_receive, 0};
169 case CONTROL_STANDARD : {
170 protocollist[0] = {"standardcontrolmessage-only", ControlWebsocket::callback_receive, 0};
174 protocollist[0] = {"customdatamessage-only", ControlWebsocket::callback_receive, 0};
177 case CONTROL_CUSTOM : {
178 protocollist[0] = {"customcontrolmessage-only", ControlWebsocket::callback_receive, 0};
185 context = libwebsocket_create_context(port, "lo", protocollist,
186 libwebsocket_internal_extensions,
187 NULL, NULL, -1, -1, 0);
188 if (context == NULL) {
189 DebugOut() << "ControlWebsocket[" << type << "]"
190 << " couldn't create libwebsockets_context." << std::endl;
193 if (pthread_create(&threadid, NULL, ControlWebsocket::run, (void*)this)
195 libwebsocket_context_destroy(context);
196 DebugOut() << "ControlWebsocket[" << type << "]"
197 << " couldn't create thread." << std::endl;
204 ControlWebsocket::send(int commid, char *keyeventtype, timeval time, void *data,
207 DebugOut() << "ControlWebsocket[" << type << "]" << " send data(" << commid
208 << "," << keyeventtype << ") len = " << len << std::endl;
209 libwebsocket *wsi = NULL;
210 if (socketmap.find(commid) == socketmap.end()) {
211 if (!registSocket(commid)) {
212 DebugOut() << "ControlWebsocket[" << type << "]"
213 << " can't regist socket(" << commid << ")"
218 wsi = socketmap[commid];
221 DebugOut() << "ControlWebsocket Get websocket object is NULL."
225 pthread_mutex_lock(&mutex);
226 memset(buf, 0, sizeof(buf));
227 memcpy(buf + LWS_SEND_BUFFER_PRE_PADDING,
228 datamsg.encode(keyeventtype, time,
229 *(reinterpret_cast<DataOpt*>(data))),
231 DebugOut() << "ControlWebsocket Send Data[" << keyeventtype << "]"
235 reinterpret_cast<unsigned char*>(buf + LWS_SEND_BUFFER_PRE_PADDING),
236 len, LWS_WRITE_BINARY);
237 pthread_mutex_unlock(&mutex);
242 ControlWebsocket::receive(int commid, char *keyeventtype, timeval recordtime,
243 void *data, size_t len)
245 DebugOut() << "ControlWebsocket[" << type << "]" << " receive message("
246 << commid << "," << keyeventtype << ")\n";
251 datamsg.decodeOpt(keyeventtype, recordtime, data);
252 DataOpt dop = datamsg.getDataOpt();
253 mwif->recvMessage(SET, commid, keyeventtype, recordtime, (void*)&dop,
257 case CONTROL_STANDARD:
260 eventmsg.decodeOpt(keyeventtype, recordtime, data);
261 EventOpt opt = eventmsg.getEventOpt();
262 if (opt.common == -1 && opt.sense == -1) {
263 mwif->recvMessage(GET, commid, keyeventtype, recordtime,
267 mwif->recvMessage(CALLBACK, commid, keyeventtype, recordtime,
281 ControlWebsocket::observation()
285 ret = libwebsocket_service(context, 100);
293 ControlWebsocket::registSocket(int commid)
295 if (socketmap.find(commid) != socketmap.end()) {
298 GenerateCommID<libwebsocket*> *idserver =
299 GenerateCommID<libwebsocket*>::getInstance();
300 libwebsocket *wsi = idserver->getValue(commid);
304 libwebsocket_protocols *protocol =
305 const_cast<libwebsocket_protocols*>(libwebsockets_get_protocol(wsi));
306 if (protocol != NULL) {
307 if (context == protocol[0].owning_server) {
308 socketmap[commid] = wsi;
316 ControlWebsocket::unregistSocket(int commid)
318 if (socketmap.find(commid) == socketmap.end()) {
321 socketmap.erase(commid);
322 GenerateCommID<libwebsocket*> *idserver =
323 GenerateCommID<libwebsocket*>::getInstance();
324 return idserver->unsetID(commid);
328 ControlWebsocket::callback_receive(libwebsocket_context *context,
330 libwebsocket_callback_reasons reason,
331 void *user, void *in, size_t len)
333 DebugOut(10) << "Reason(" << reason << ")\n";
335 case LWS_CALLBACK_ESTABLISHED:
337 GenerateCommID<libwebsocket*> *idserver =
338 GenerateCommID<libwebsocket*>::getInstance();
339 int id = idserver->getID(wsi);
340 DebugOut() << "ControlWebsocket callback_receive Insert ID is " << id
344 case LWS_CALLBACK_CLOSED:
346 GenerateCommID<libwebsocket*> *idserver =
347 GenerateCommID<libwebsocket*>::getInstance();
348 int id = idserver->getID(wsi);
349 idserver->unsetID(id);
350 DebugOut() << "ControlWebsocket callback_receive Delete ID is " << id
352 ControlWebsocket::mwif->unregistDestination(id);
355 case LWS_CALLBACK_RECEIVE:
357 GenerateCommID<libwebsocket*> *idserver =
358 GenerateCommID<libwebsocket*>::getInstance();
359 int id = idserver->getID(wsi);
361 char *buf = reinterpret_cast<char*>(in);
362 msg.decode(buf, len);
363 DebugOut() << "ControlWebsocket callback_receive Receive message : "
364 << msg.getKeyEventType() << "," << msg.getRecordtime().tv_sec
366 ControlWebsocket::mwif->recvRawdata(
367 id, msg.getKeyEventType(), msg.getRecordtime(),
368 (buf + StandardMessage::KEYEVENTTYPESIZE + sizeof(timeval)),
381 ControlWebsocket::run(void *arg)
383 ControlWebsocket *control = reinterpret_cast<ControlWebsocket*>(arg);
384 control->observation();