Init basesystem source codes.
[staging/basesystem.git] / peripheralservice / communication / server / src / CAN / CommWatch / CAN_CommWatch.cpp
1 /*
2  * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "CAN_CommWatch.h"
18
19 #include <native_service/frameworkunified_types.h>
20 #include <native_service/frameworkunified_framework_if.h>
21 #include <peripheral_service/Canif_API.h>
22 #include <utility>
23 #include <map>
24 #include <string>
25 #include "CAN_Thread.h"
26 #include "Thread_Common.h"
27
28 static CAN_CommWatchTable g_map_comm_watch_list_can;
29
30 void CANCommWatchInit(void) {
31   g_map_comm_watch_list_can.clear();
32   return;
33 }
34
35 static CAN_CommWatchTableIt CANCommWatchFind(CANID k, CAN_COMM_WATCH_VAL *val) {
36   std::pair<CAN_CommWatchTableIt, CAN_CommWatchTableIt> range;
37   CAN_CommWatchTableIt it;
38   bool found = false;
39
40   range = g_map_comm_watch_list_can.equal_range(k);
41   for (it = range.first; it != range.second; it++) {
42     if (!memcmp(&(it->second.notify_name),
43                                   val->notify_name, sizeof(val->notify_name))) {
44       found = true;
45       break;
46     }
47   }
48
49   if (!found)
50     it = g_map_comm_watch_list_can.end();
51
52   return it;
53 }
54
55 static bool CANCommWatchInsert(CANID k, CAN_COMM_WATCH_VAL *val) {
56   CAN_CommWatchTableIt it = CANCommWatchFind(k, val);
57   CAN_CommWatchTablePair p = std::make_pair((const CANID)k, *val);
58   bool inserted = false;
59
60   if (it == g_map_comm_watch_list_can.end()) {
61     g_map_comm_watch_list_can.insert(p);
62     inserted = true;
63   }
64   return inserted;
65 }
66
67 static void CANCommWatchUpdate(HANDLE h_app, CANID key,
68                                              CAN_COMM_WATCH_VAL *val) {
69   if (CANCommWatchInsert(key, val)) {
70     FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__, "Can CommWatch : "
71       "Entry (CANID=%x, DataID=%x, dst=%s, time=%d, cnt=%lu)",
72       key, val->data_id,
73       val->notify_name, val->set_time,
74       g_map_comm_watch_list_can.size());
75   } else {
76     CAN_CommWatchTableIt it = CANCommWatchFind(key, val);
77     FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__, "Can CommWatch : Update the time "
78       "(CANID=%x, DataID=%x, dst=%s, time:%d -> %d, cnt =%lu)",
79       key, val->data_id, val->notify_name,
80       it->second.set_time, val->set_time, 
81       g_map_comm_watch_list_can.size());
82     it->second.comm_watch_flag = val->comm_watch_flag;
83     it->second.set_time = val->set_time;
84     it->second.timer_cnt = val->timer_cnt;
85     it->second.data_id = val->data_id;
86   }
87
88   return;
89 }
90
91 static void CANCommWatchStop(HANDLE h_app, CANID key,
92                                            CAN_COMM_WATCH_VAL *val) {
93   CAN_CommWatchTableIt it = CANCommWatchFind(key, val);
94   if (it != g_map_comm_watch_list_can.end()) {
95     g_map_comm_watch_list_can.erase(it);
96     FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__, "Can CommWatch : Stop the commwatch"
97         "(CANID=%x, dst=%s, cnt=%lu)",
98         key, val->notify_name, g_map_comm_watch_list_can.size());
99   }
100
101   return;
102 }
103
104 EFrameworkunifiedStatus CANCommWatch(HANDLE h_app) {
105   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __func__, "@@@ Start communication CanCommWatch");
106
107   EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusFail;
108   CAN_COMM_WATCHEXT_MSG_DAT rcv_msg;
109   CANID key;
110   CAN_COMM_WATCH_VAL val;
111   CAN_CommWatchTableIt it;
112
113   memset(&rcv_msg, 0, sizeof(rcv_msg));
114   memset(&val, 0, sizeof(val));
115   e_status = FrameworkunifiedGetMsgDataOfSize(h_app, &rcv_msg, sizeof(rcv_msg), eSMRRelease);
116   if (e_status != eFrameworkunifiedStatusOK) {
117     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "FrameworkunifiedGetMsgDataOfSize Error(%d)", e_status);
118     if (e_status == eFrameworkunifiedStatusInvldBufSize) {
119       FrameworkunifiedClearMsgData(h_app);
120     }
121     goto cleanup;
122   }
123
124   // Create search data
125   key = rcv_msg.ulCanid;
126   snprintf(val.notify_name, sizeof(val.notify_name), "%s", rcv_msg.notifyName);
127   val.data_id = rcv_msg.ulDid;
128   val.comm_watch_flag = CAN_COMM_NORMAL;
129   val.set_time = rcv_msg.usWatchTime;
130   val.timer_cnt = rcv_msg.usWatchTime;
131   FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__,
132          "CAN CommWatch : dst=%s, CANID=%x, dataID=%x, time=%d",
133          rcv_msg.notifyName, 
134          rcv_msg.ulCanid, 
135          rcv_msg.ulDid, rcv_msg.usWatchTime);
136
137   if (0 == rcv_msg.usWatchTime) {
138     CANCommWatchStop(h_app, key, &val);
139   } else {
140     CANCommWatchUpdate(h_app, key, &val);
141   }
142   e_status = eFrameworkunifiedStatusOK;
143 cleanup:
144   return e_status;
145 }
146
147 static EFrameworkunifiedStatus CANCommWatchSndMsg(HANDLE h_app,
148                                         CAN_COMM_WATCH_VAL *v, uint32_t cid) {
149   EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusFail;
150   CAN_MSG_COMM_WATCHSTS msg;
151   HANDLE h_client = NULL;
152
153   memset(&msg, 0, sizeof(msg));
154   msg.hdr.hdr.cid = (uint16_t)cid;
155   msg.hdr.hdr.msgbodysize = sizeof(CAN_MSG_COMM_WATCHSTS_DAT);
156   msg.hdr.hdr.rid = 0;
157   msg.data.ulDid = v->data_id;
158
159   FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__,  "cid=%x msgbodysize=%x ulDid=%x",
160          msg.hdr.hdr.cid, msg.hdr.hdr.msgbodysize, msg.data.ulDid);
161
162   h_client = CommonFindSender(h_app, v->notify_name);
163   if (!h_client){
164     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "CommonFindSender failed");
165     goto cleanup;
166   }
167
168   e_status = FrameworkunifiedSendMsg(h_client, cid, sizeof(msg), &msg);
169   if (e_status != eFrameworkunifiedStatusOK) {
170     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__,
171       "FrameworkunifiedSendMSg Error(e_status:%d to %s)",
172       e_status, v->notify_name);
173     goto cleanup;
174   }
175
176   e_status = eFrameworkunifiedStatusOK;
177 cleanup:
178   return e_status;
179 }
180
181 static void CANCommWatchTimeoutCore(HANDLE h_app, CAN_COMM_WATCH_VAL *v) {
182   EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusFail;
183
184   if (CAN_COMM_NORMAL != v->comm_watch_flag)
185     return;
186
187   if (v->timer_cnt != 0)
188     v->timer_cnt--;
189
190   if (v->timer_cnt != 0)
191     return;
192
193   e_status = CANCommWatchSndMsg(h_app, v, CID_CAN_COMM_STOP);
194   if (eFrameworkunifiedStatusOK == e_status) {
195      v->comm_watch_flag = CAN_COMM_STOP;
196   } else {
197     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "CANCommWatchSndMsg failed");
198      // retry at next timeout.
199   }
200 }
201
202 EFrameworkunifiedStatus CANCommWatchTimeout(HANDLE h_app) {
203   CAN_CommWatchTableIt it;
204
205   for (it = g_map_comm_watch_list_can.begin();
206                             it != g_map_comm_watch_list_can.end(); it++) {
207     CANCommWatchTimeoutCore(h_app, &(it->second));
208   }
209
210   return eFrameworkunifiedStatusOK;
211 }
212
213 static void CANCommWatchClearCore(HANDLE h_app, CANID id,
214                                                 CAN_COMM_WATCH_VAL *v) {
215   EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusFail;
216
217   v->timer_cnt = v->set_time;
218
219   if (CAN_COMM_STOP != v->comm_watch_flag)
220     return;
221
222   e_status = CANCommWatchSndMsg(h_app, v, CID_CAN_COMM_RESTORE);
223   if (eFrameworkunifiedStatusOK == e_status) {
224     v->comm_watch_flag = CAN_COMM_NORMAL;
225     FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__, "Can CommWatch Clear : CANID=%x", id);
226   } else {
227     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "CANCommWatchSndMsg failed");
228      // retry at next timeout.
229   }
230 }
231
232 void CANCommWatchClear(HANDLE h_app, CANID id) {
233   std::pair<CAN_CommWatchTableIt, CAN_CommWatchTableIt> range;
234   CAN_CommWatchTableIt it;
235
236   range = g_map_comm_watch_list_can.equal_range(id);
237   for (it = range.first; it != range.second; it++) {
238     CANCommWatchClearCore(h_app, id, &(it->second));
239   }
240 }