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
26 #include "mwinterface.h"
27 #include "controlwebsocket.h"
28 #include "viccommunicator.h"
32 MWNotifyInfo::MWNotifyInfo()
34 memset(nochangemask, 0, sizeof(nochangemask));
35 mutex = PTHREAD_MUTEX_INITIALIZER;
38 MWNotifyInfo::~MWNotifyInfo()
40 for (auto itr = notifyMap.begin(); itr != notifyMap.end(); itr++) {
41 (*itr).second.clear();
47 MWNotifyInfo::insert(std::string name, int interval, int sense, char *mask)
52 pthread_mutex_lock(&mutex);
53 if (notifyMap.find(name) == notifyMap.end()) {
54 for (auto itr = notifyMap[name].begin(); itr != notifyMap[name].end();
56 if (memcpy((*itr).mask, mask, STATUSSIZE) == 0) {
57 (*itr).interval = interval;
58 pthread_mutex_unlock(&mutex);
63 pthread_mutex_unlock(&mutex);
65 opt.interval = interval;
66 memcpy(opt.mask, mask, STATUSSIZE);
67 opt.lastChanged.tv_sec = 0;
68 opt.lastChanged.tv_usec = 0;
69 pthread_mutex_lock(&mutex);
70 notifyMap[name].push_back(opt);
71 pthread_mutex_unlock(&mutex);
76 MWNotifyInfo::erase(std::string name, char *mask)
78 pthread_mutex_lock(&mutex);
79 if (notifyMap.find(name) == notifyMap.end()) {
80 pthread_mutex_unlock(&mutex);
83 for (auto itr = notifyMap[name].begin(); itr != notifyMap[name].end();
85 if (memcpy((*itr).mask, mask, STATUSSIZE) == 0) {
86 itr = notifyMap[name].erase(itr);
87 pthread_mutex_unlock(&mutex);
91 pthread_mutex_unlock(&mutex);
96 MWNotifyInfo::eraseAllMask(std::string name)
98 pthread_mutex_lock(&mutex);
99 if (notifyMap.find(name) == notifyMap.end()) {
100 pthread_mutex_unlock(&mutex);
103 notifyMap[name].clear();
104 notifyMap.erase(name);
105 pthread_mutex_unlock(&mutex);
110 MWNotifyInfo::checkNotify(std::string name, char *olddata, char *newdata,
113 DebugOut(10) << "MWNotiryInfo checkNotify(" << name << ")" << std::endl;
114 pthread_mutex_lock(&mutex);
115 if (notifyMap.find(name) == notifyMap.end()) {
116 pthread_mutex_unlock(&mutex);
119 pthread_mutex_unlock(&mutex);
120 DebugOut(10) << "MWNotiryInfo checkStatus(" << name << ")" << std::endl;
121 char checkDiff[STATUSSIZE] = {};
122 for (int i = 0; i < STATUSSIZE; i++) {
123 checkDiff[i] = (*(olddata + i)) ^ (*(newdata + i));
125 DebugOut(10) << "MWNotiryInfo Update checkDiff" << std::endl;
126 pthread_mutex_lock(&mutex);
127 for (auto itr = notifyMap[name].begin(); itr != notifyMap[name].end();
129 for (int i = 0; i < STATUSSIZE; i++) {
130 DebugOut(10) << "checkDiff[" << i << "] = " << checkDiff[i]
131 << ", (*itr).mask[i] = " << (*itr).mask[i]
132 << " , checkDiff[i] & (*itr).mask[i] = "
133 << (int)(checkDiff[i] & (*itr).mask[i]) << std::endl;
134 if ((checkDiff[i] & (*itr).mask[i]) != 0x00) {
135 pthread_mutex_unlock(&mutex);
142 pthread_mutex_unlock(&mutex);
148 for (int i = 0; i < SERVERNUM; i++) {
149 websocketserver[i] = NULL;
151 mutex_socketmap = PTHREAD_MUTEX_INITIALIZER;
156 vehicleinfoArray.clear();
157 for (int i = 0; i < SERVERNUM; i++) {
158 if (websocketserver[i] != NULL) {
159 delete websocketserver[i];
162 websocketservermap.clear();
163 mwnotifyinfomap.clear();
164 pthread_mutex_destroy(&mutex_socketmap);
168 MWIF::initialize(VICCommunicator *com, AMBConfig *conf)
172 vector<VehicleInfoDefine> table;
173 table = conf->getVehicleInfoConfig();
174 for (auto itr = table.begin(), itr_end = table.end(); itr != itr_end; itr++) {
176 vi.name = string((*itr).KeyEventType);
177 memset(&vi.status, 0, STATUSSIZE);
179 for (auto itr2 = (*itr).status.begin(); itr2 != (*itr).status.end();
181 vi.statussize += (*itr2).typesize;
182 vi.delimeterposition.push_back((*itr2).typesize);
184 vehicleinfoArray.push_back(vi);
185 DebugOut(10) << "MWIF initialize mwvehicleinfo name = " << vi.name
188 DebugOut(1) << "INFO CHG_VIC_INF The number of VIC vehicle info is " << vehicleinfoArray.size() << ".\n";
189 PortInfo portinfo = conf->getPort();
190 DebugOut(1) << "INFO CHG_VIC_INF Portinfo list is (" << portinfo.standard.dataPort
191 << "," << portinfo.standard.controlPort << ","
192 << portinfo.custom.dataPort << "," << portinfo.custom.controlPort
194 createThread(&portinfo);
199 MWIF::send(MWVehicleInfo *vehicleinfo)
201 DebugOut(10) << "MWIF " << "send data is " << vehicleinfo->name << "("
202 << vehicleinfo->status[0] << ")" << std::endl;
203 if (vehicleinfo == NULL) {
207 MWVehicleInfo *curvehicleinfo = find(vehicleinfo->name);
208 if (curvehicleinfo != NULL) {
209 vehicleinfo->statussize = curvehicleinfo->statussize;
210 vehicleinfo->delimeterposition = curvehicleinfo->delimeterposition;
211 DebugOut(10) << "MWIF send : mwnotifyinfomap.size() = "
212 << mwnotifyinfomap.size() << "\n";
213 for (auto itr = mwnotifyinfomap.begin(); itr != mwnotifyinfomap.end();
215 if ((*itr).second.checkNotify(vehicleinfo->name,
216 curvehicleinfo->status,
218 vehicleinfo->recordtime)) {
219 DebugOut(10) << "MWIF send Notify" << std::endl;
220 sendMessage((*itr).first, SUPPORT, vehicleinfo);
223 memcpy(curvehicleinfo->status, vehicleinfo->status, STATUSSIZE);
224 curvehicleinfo->recordtime = vehicleinfo->recordtime;
229 MWIF::recvRawdata(int commid, char *keyeventtype, timeval recordtime,
230 void *data, size_t len)
232 DebugOut(10) << "MWIF recvRawdata(" << commid << "," << keyeventtype << ")\n";
233 if (find(string(keyeventtype)) != NULL) {
234 if (websocketservermap.find(commid) == websocketservermap.end()) {
237 websocketserver[static_cast<int>(websocketservermap[commid])]->receive(
238 commid, keyeventtype, recordtime, data, len);
242 DebugOut(10) << "MWIF recvRawdata " << "Error Data." << std::endl;
243 MWVehicleInfo errorvi;
244 errorvi.name = string(keyeventtype);
245 errorvi.recordtime = recordtime;
246 errorvi.statussize = len - StandardMessage::KEYEVENTTYPESIZE
247 - sizeof(timeval) - sizeof(int);
248 memset(errorvi.status, 0, STATUSSIZE);
249 sendMessage(commid, UNKNOWN, &errorvi);
254 MWIF::recvMessage(MessageType type, int commid, char *keyeventtype,
255 timeval recordtime, void *data, size_t len)
258 if ((vi = find(string(keyeventtype))) == NULL) {
259 DebugOut(10) << "MWIF recvMessage " << "Error Data." << std::endl;
260 MWVehicleInfo errorvi;
261 errorvi.name = string(keyeventtype);
262 errorvi.recordtime = recordtime;
263 errorvi.statussize = len - StandardMessage::KEYEVENTTYPESIZE
264 - sizeof(timeval) - sizeof(int);
265 memset(errorvi.status, 0, STATUSSIZE);
266 sendMessage(commid, UNKNOWN, &errorvi);
270 DebugOut(10) << "MWIF recvMessage(" << commid << ")\n";
272 case MessageType::SET:
274 DebugOut(8) << "MWIF recvMessage(" << commid << ",SET) " << keyeventtype
276 DataOpt *opt = reinterpret_cast<DataOpt*>(data);
277 procSetMessage(commid, vi, keyeventtype, recordtime, opt, len);
280 case MessageType::GET:
282 DebugOut(8) << "MWIF recvMessage(" << commid << ",GET) " << keyeventtype
284 EventOpt *opt = reinterpret_cast<EventOpt*>(data);
285 procGetMessage(commid, keyeventtype, recordtime, opt, len);
288 case MessageType::CALLBACK:
290 DebugOut(8) << "MWIF recvMessage(" << commid << ",CALLBACK) "
291 << keyeventtype << "\n";
292 EventOpt *opt = reinterpret_cast<EventOpt*>(data);
293 procCallbackMessage(commid, keyeventtype, recordtime, opt, len);
304 MWIF::registDestination(ControlWebsocket::ServerProtocol type, int commid)
306 DebugOut(10) << "MWIF type = " << type << std::endl;
307 pthread_mutex_lock(&mutex_socketmap);
308 if (websocketserver[type]->registSocket(commid)) {
309 DebugOut(10) << "MWIF registDestination insert(" << commid << "," << type
311 websocketservermap.insert(make_pair(commid, type));
313 pthread_mutex_unlock(&mutex_socketmap);
317 MWIF::unregistDestination(ControlWebsocket::ServerProtocol type, int commid)
319 pthread_mutex_lock(&mutex_socketmap);
320 if (websocketservermap.find(commid) != websocketservermap.end()) {
321 if (websocketserver[type]->unregistSocket(commid)) {
322 DebugOut(10) << "MWIF unregistDestination erase(" << commid << ","
324 websocketservermap.erase(commid);
327 pthread_mutex_unlock(&mutex_socketmap);
331 MWIF::sendMessage(int commid, CommonStatus status, MWVehicleInfo *vehicleinfo)
334 opt.common_status = status;
335 memcpy(opt.status, vehicleinfo->status, STATUSSIZE);
336 size_t len = StandardMessage::KEYEVENTTYPESIZE + sizeof(timeval)
337 + sizeof(int) + vehicleinfo->statussize;
338 DebugOut(10) << "MWIF sendMessage vehicleinfo->statussize = "
339 << vehicleinfo->statussize << ", len = " << len << std::endl;
340 if (websocketservermap.find(commid) == websocketservermap.end()) {
343 DebugOut(10) << "MWIF sendMessage controlwebsocket->send(" << commid << ","
344 << vehicleinfo->name << "),len = " << len << std::endl;
345 websocketserver[websocketservermap[commid]]->send(
346 commid, const_cast<char*>(vehicleinfo->name.c_str()),
347 vehicleinfo->recordtime, (void *)&opt, len);
351 MWIF::createThread(PortInfo *portinfo)
353 for (int i = 0; i < SERVERNUM; i++) {
354 websocketserver[i] = new ControlWebsocket();
356 websocketserver[ControlWebsocket::DATA_STANDARD]->initialize(
357 portinfo->standard.dataPort, ControlWebsocket::DATA_STANDARD, this);
358 websocketserver[ControlWebsocket::CONTROL_STANDARD]->initialize(
359 portinfo->standard.controlPort, ControlWebsocket::CONTROL_STANDARD,
361 websocketserver[ControlWebsocket::DATA_CUSTOM]->initialize(
362 portinfo->custom.dataPort, ControlWebsocket::DATA_CUSTOM, this);
363 websocketserver[ControlWebsocket::CONTROL_CUSTOM]->initialize(
364 portinfo->custom.controlPort, ControlWebsocket::CONTROL_CUSTOM,
369 MWIF::find(string name)
373 auto itr = std::find(vehicleinfoArray.begin(), vehicleinfoArray.end(), vi);
374 if (itr == vehicleinfoArray.end()) {
375 DebugOut(10) << "MWIF find can't find property = " << name << std::endl;
384 MWIF::procSetMessage(int commid, MWVehicleInfo *vi, char *keyeventtype, timeval recordtime,
385 DataOpt *data, size_t len)
387 MWVehicleInfo updatevehicleinfo;
388 updatevehicleinfo.name = vi->name;
389 updatevehicleinfo.recordtime = recordtime;
390 updatevehicleinfo.statussize = vi->statussize;
392 memcpy(updatevehicleinfo.status, data->status, getStatussize(len));
394 communicator->setAMBVehicleInfo(&updatevehicleinfo);
396 vi->recordtime = recordtime;
397 memcpy(vi->status, updatevehicleinfo.status, getStatussize(len));
401 MWIF::procGetMessage(int commid, char *keyeventtype, timeval recordtime,
402 EventOpt *data, size_t len)
404 MWVehicleInfo vehicleinfo;
405 vehicleinfo.name = string(keyeventtype);
406 vehicleinfo.statussize = find(vehicleinfo.name)->statussize;
407 communicator->getAMBVehicleInfo(&vehicleinfo);
408 sendMessage(commid, SUPPORT, &vehicleinfo);
412 MWIF::procCallbackMessage(int commid, char *keyeventtype, timeval recordtime,
413 EventOpt *data, size_t len)
415 MWVehicleInfo *vehicleinfo = find(string(keyeventtype));
418 char mask[STATUSSIZE];
419 memset(mask, 0, STATUSSIZE);
420 for (int i = 0; i < static_cast<int>(vehicleinfo->delimeterposition.size());
423 if (data->sense == 0xff || (i + 1) == data->sense) {
426 for (int j = 0; j < vehicleinfo->delimeterposition[i]; j++) {
431 MWNotifyInfo notifyinfo;
432 if (mwnotifyinfomap.find(commid) == mwnotifyinfomap.end()) {
433 mwnotifyinfomap.insert(make_pair(commid, notifyinfo));
436 notifyinfo = mwnotifyinfomap[commid];
438 if (notifyinfo.insert(string(keyeventtype), data->common, data->sense,
440 sendMessage(commid, SUPPORT, vehicleinfo);
443 sendMessage(commid, NOTSUPPORT, vehicleinfo);
445 mwnotifyinfomap[commid] = notifyinfo;