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
25 #include "mwinterface.h"
26 #include "controlwebsocket.h"
27 #include "viccommunicator.h"
31 MWNotifyInfo::MWNotifyInfo()
33 memset(nochangemask, 0, sizeof(nochangemask));
34 mutex = PTHREAD_MUTEX_INITIALIZER;
37 MWNotifyInfo::~MWNotifyInfo()
39 for (auto itr = notifyMap.begin(); itr != notifyMap.end(); itr++) {
40 (*itr).second.clear();
46 MWNotifyInfo::insert(std::string name, int interval, int sense, char *mask)
51 pthread_mutex_lock(&mutex);
52 if (notifyMap.find(name) == notifyMap.end()) {
53 for (auto itr = notifyMap[name].begin(); itr != notifyMap[name].end();
55 if (memcpy((*itr).mask, mask, STATUSSIZE) == 0) {
56 (*itr).interval = interval;
57 pthread_mutex_unlock(&mutex);
62 pthread_mutex_unlock(&mutex);
64 opt.interval = interval;
65 memcpy(opt.mask, mask, STATUSSIZE);
66 opt.lastChanged.tv_sec = 0;
67 opt.lastChanged.tv_usec = 0;
68 pthread_mutex_lock(&mutex);
69 notifyMap[name].push_back(opt);
70 pthread_mutex_unlock(&mutex);
75 MWNotifyInfo::erase(std::string name, char *mask)
77 pthread_mutex_lock(&mutex);
78 if (notifyMap.find(name) == notifyMap.end()) {
79 pthread_mutex_unlock(&mutex);
82 for (auto itr = notifyMap[name].begin(); itr != notifyMap[name].end();
84 if (memcpy((*itr).mask, mask, STATUSSIZE) == 0) {
85 itr = notifyMap[name].erase(itr);
86 pthread_mutex_unlock(&mutex);
90 pthread_mutex_unlock(&mutex);
95 MWNotifyInfo::eraseAllMask(std::string name)
97 pthread_mutex_lock(&mutex);
98 if (notifyMap.find(name) == notifyMap.end()) {
99 pthread_mutex_unlock(&mutex);
102 notifyMap[name].clear();
103 notifyMap.erase(name);
104 pthread_mutex_unlock(&mutex);
109 MWNotifyInfo::checkNotify(std::string name, char *olddata, char *newdata,
112 DebugOut() << "MWNotiryInfo checkNotify(" << name << ")" << std::endl;
113 pthread_mutex_lock(&mutex);
114 if (notifyMap.find(name) == notifyMap.end()) {
115 pthread_mutex_unlock(&mutex);
118 pthread_mutex_unlock(&mutex);
119 DebugOut(10) << "MWNotiryInfo checkStatus(" << name << ")" << std::endl;
120 char checkDiff[STATUSSIZE] = {};
121 for (int i = 0; i < STATUSSIZE; i++) {
122 checkDiff[i] = (*(olddata + i)) ^ (*(newdata + i));
124 DebugOut(10) << "MWNotiryInfo Update checkDiff" << std::endl;
125 pthread_mutex_lock(&mutex);
126 for (auto itr = notifyMap[name].begin(); itr != notifyMap[name].end();
128 for (int i = 0; i < STATUSSIZE; i++) {
129 DebugOut() << "checkDiff[" << i << "] = " << checkDiff[i]
130 << ", (*itr).mask[i] = " << (*itr).mask[i]
131 << " , checkDiff[i] & (*itr).mask[i] = "
132 << (int)(checkDiff[i] & (*itr).mask[i]) << std::endl;
133 if ((checkDiff[i] & (*itr).mask[i]) != 0x00) {
134 pthread_mutex_unlock(&mutex);
141 pthread_mutex_unlock(&mutex);
147 for (int i = 0; i < SERVERNUM; i++) {
148 websocketserver[i] = NULL;
154 vehicleinfoArray.clear();
155 for (int i = 0; i < SERVERNUM; i++) {
156 if (websocketserver[i] != NULL) {
157 delete websocketserver[i];
160 websocketservermap.clear();
161 mwnotifyinfomap.clear();
165 MWIF::initialize(VICCommunicator *com, AMBConfig *conf)
169 vector<VehicleInfoDefine> table;
170 table = conf->getVehicleInfoConfig();
171 for (auto itr = table.begin(); itr != table.end(); itr++) {
173 vi.name = string((*itr).KeyEventType);
174 memset(&vi.status, 0, STATUSSIZE);
176 for (auto itr2 = (*itr).status.begin(); itr2 != (*itr).status.end();
178 vi.statussize += (*itr2).typesize;
179 vi.delimeterposition.push_back((*itr2).typesize);
181 vehicleinfoArray.push_back(vi);
182 DebugOut() << "MWIF initialize mwvehicleinfo name = " << vi.name
185 PortInfo portinfo = conf->getPort();
186 DebugOut() << "MWIF initialize portinfo (" << portinfo.standard.dataPort
187 << "," << portinfo.standard.controlPort << ","
188 << portinfo.custom.dataPort << "," << portinfo.custom.controlPort
190 createThread(&portinfo);
195 MWIF::send(MWVehicleInfo *vehicleinfo)
197 DebugOut(10) << "MWIF " << "send data is " << vehicleinfo->name << "("
198 << vehicleinfo->status[0] << ")" << std::endl;
199 if (vehicleinfo == NULL) {
203 MWVehicleInfo *curvehicleinfo = find(vehicleinfo->name);
204 if (curvehicleinfo != NULL) {
205 vehicleinfo->statussize = curvehicleinfo->statussize;
206 vehicleinfo->delimeterposition = curvehicleinfo->delimeterposition;
207 DebugOut(10) << "MWIF send : mwnotifyinfomap.size() = "
208 << mwnotifyinfomap.size() << "\n";
209 for (auto itr = mwnotifyinfomap.begin(); itr != mwnotifyinfomap.end();
211 if ((*itr).second.checkNotify(vehicleinfo->name,
212 curvehicleinfo->status,
214 vehicleinfo->recordtime)) {
215 DebugOut(10) << "MWIF send Notify" << std::endl;
216 sendMessage((*itr).first, SUPPORT, vehicleinfo);
219 memcpy(curvehicleinfo->status, vehicleinfo->status, STATUSSIZE);
220 curvehicleinfo->recordtime = vehicleinfo->recordtime;
225 MWIF::recvRawdata(int commid, char *keyeventtype, timeval recordtime,
226 void *data, size_t len)
228 DebugOut() << "MWIF recvRawdata(" << commid << "," << keyeventtype << ")\n";
229 if (find(string(keyeventtype)) != NULL) {
230 if (websocketservermap.find(commid) == websocketservermap.end()) {
233 websocketserver[static_cast<int>(websocketservermap[commid])]->receive(
234 commid, keyeventtype, recordtime, data, len);
238 DebugOut() << "MWIF recvRawdata " << "Error Data." << std::endl;
239 MWVehicleInfo errorvi;
240 errorvi.name = string(keyeventtype);
241 errorvi.recordtime = recordtime;
242 errorvi.statussize = len - StandardMessage::KEYEVENTTYPESIZE
243 - sizeof(timeval) - sizeof(int);
244 memset(errorvi.status, 0, STATUSSIZE);
245 sendMessage(commid, UNKNOWN, &errorvi);
250 MWIF::recvMessage(MessageType type, int commid, char *keyeventtype,
251 timeval recordtime, void *data, size_t len)
253 DebugOut(10) << "MWIF recvMessage(" << commid << ")\n";
255 case MessageType::SET:
257 DebugOut() << "MWIF recvMessage(" << commid << ",SET) " << keyeventtype
259 DataOpt *opt = reinterpret_cast<DataOpt*>(data);
260 procSetMessage(commid, keyeventtype, recordtime, opt, len);
263 case MessageType::GET:
265 DebugOut() << "MWIF recvMessage(" << commid << ",GET) " << keyeventtype
267 EventOpt *opt = reinterpret_cast<EventOpt*>(data);
268 procGetMessage(commid, keyeventtype, recordtime, opt, len);
271 case MessageType::CALLBACK:
273 DebugOut() << "MWIF recvMessage(" << commid << ",CALLBACK) "
274 << keyeventtype << "\n";
275 EventOpt *opt = reinterpret_cast<EventOpt*>(data);
276 procCallbackMessage(commid, keyeventtype, recordtime, opt, len);
287 MWIF::registDestination(ControlWebsocket::ServerProtocol type, int commid)
289 DebugOut() << "MWIF type = " << type << std::endl;
290 if (websocketserver[type]->registSocket(commid)) {
291 DebugOut() << "MWIF registDestination insert(" << commid << "," << type
293 websocketservermap.insert(make_pair(commid, type));
298 MWIF::unregistDestination(ControlWebsocket::ServerProtocol type, int commid)
300 if (websocketservermap.find(commid) != websocketservermap.end()) {
301 if (websocketserver[type]->unregistSocket(commid)) {
302 DebugOut() << "MWIF unregistDestination erase(" << commid << ","
304 websocketservermap.erase(commid);
310 MWIF::sendMessage(int commid, CommonStatus status, MWVehicleInfo *vehicleinfo)
313 opt.common_status = status;
314 memcpy(opt.status, vehicleinfo->status, STATUSSIZE);
315 size_t len = StandardMessage::KEYEVENTTYPESIZE + sizeof(timeval)
316 + sizeof(int) + vehicleinfo->statussize;
317 DebugOut(10) << "MWIF sendMessage vehicleinfo->statussize = "
318 << vehicleinfo->statussize << ", len = " << len << std::endl;
319 if (websocketservermap.find(commid) == websocketservermap.end()) {
322 DebugOut() << "MWIF sendMessage controlwebsocket->send(" << commid << ","
323 << vehicleinfo->name << "),len = " << len << std::endl;
324 websocketserver[websocketservermap[commid]]->send(
325 commid, const_cast<char*>(vehicleinfo->name.c_str()),
326 vehicleinfo->recordtime, (void *)&opt, len);
330 MWIF::createThread(PortInfo *portinfo)
332 for (int i = 0; i < SERVERNUM; i++) {
333 websocketserver[i] = new ControlWebsocket();
335 websocketserver[ControlWebsocket::DATA_STANDARD]->initialize(
336 portinfo->standard.dataPort, ControlWebsocket::DATA_STANDARD, this);
337 websocketserver[ControlWebsocket::CONTROL_STANDARD]->initialize(
338 portinfo->standard.controlPort, ControlWebsocket::CONTROL_STANDARD,
340 websocketserver[ControlWebsocket::DATA_CUSTOM]->initialize(
341 portinfo->custom.dataPort, ControlWebsocket::DATA_CUSTOM, this);
342 websocketserver[ControlWebsocket::CONTROL_CUSTOM]->initialize(
343 portinfo->custom.controlPort, ControlWebsocket::CONTROL_CUSTOM,
348 MWIF::find(string name)
350 for (auto itr = vehicleinfoArray.begin(); itr != vehicleinfoArray.end();
352 DebugOut(10) << "MWIF find" << (*itr).name << std::endl;
353 if ((*itr).name == name) {
357 DebugOut() << "MWIF find can't find property = " << name << std::endl;
362 MWIF::procSetMessage(int commid, char *keyeventtype, timeval recordtime,
363 DataOpt *data, size_t len)
365 MWVehicleInfo *vehicleinfo = find(string(keyeventtype));
366 MWVehicleInfo updatevehicleinfo;
367 updatevehicleinfo.name = vehicleinfo->name;
368 updatevehicleinfo.recordtime = recordtime;
369 updatevehicleinfo.statussize = vehicleinfo->statussize;
370 memcpy(updatevehicleinfo.status, data->status, STATUSSIZE);
372 communicator->setAMBVehicleInfo(&updatevehicleinfo);
374 vehicleinfo->recordtime = recordtime;
375 memcpy(vehicleinfo->status, updatevehicleinfo.status, STATUSSIZE);
379 MWIF::procGetMessage(int commid, char *keyeventtype, timeval recordtime,
380 EventOpt *data, size_t len)
382 MWVehicleInfo vehicleinfo;
383 vehicleinfo.name = string(keyeventtype);
384 vehicleinfo.statussize = find(vehicleinfo.name)->statussize;
385 communicator->getAMBVehicleInfo(&vehicleinfo);
386 sendMessage(commid, SUPPORT, &vehicleinfo);
390 MWIF::procCallbackMessage(int commid, char *keyeventtype, timeval recordtime,
391 EventOpt *data, size_t len)
393 MWVehicleInfo *vehicleinfo = find(string(keyeventtype));
396 char mask[STATUSSIZE];
397 memset(mask, 0, STATUSSIZE);
398 for (int i = 0; i < static_cast<int>(vehicleinfo->delimeterposition.size());
401 if (data->sense == 0xff || (i + 1) == data->sense) {
404 for (int j = 0; j < vehicleinfo->delimeterposition[i]; j++) {
409 MWNotifyInfo notifyinfo;
410 if (mwnotifyinfomap.find(commid) == mwnotifyinfomap.end()) {
411 mwnotifyinfomap.insert(make_pair(commid, notifyinfo));
414 notifyinfo = mwnotifyinfomap[commid];
416 if (notifyinfo.insert(string(keyeventtype), data->common, data->sense,
418 sendMessage(commid, SUPPORT, vehicleinfo);
421 sendMessage(commid, NOTSUPPORT, vehicleinfo);
423 mwnotifyinfomap[commid] = notifyinfo;