2 * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #include "CAN_TxMsg.h"
17 #include "CAN_Delivery.h"
19 #include <native_service/frameworkunified_types.h>
20 #include <native_service/frameworkunified_framework_if.h>
21 #include <peripheral_service/Canif_API.h>
25 #include "CAN_Thread.h"
26 #include "Thread_Common.h"
27 #include "Canif_API_Local.h"
28 #include "CAN_TxMsg.h"
29 #include "Canif_TransmissionData.h"
31 static std::map<CANID, CAN_SEND_STATUS_DAT> g_m_send_sts;
32 static bool can_cmd_rst_rcv = false;
33 static std::map<CANID, CAN_TRANS_START_TABLE_VAL *> g_map_trans_data;
35 void CANTxMsgInit(void) {
39 for (i = 0; i < _countof(Can_TransInitData_21PF); i++) {
40 CANID canid = Can_TransInitData_21PF[i].canid;
41 CAN_TRANS_START_TABLE_VAL *val = &(Can_TransInitData_21PF[i].val);
42 g_map_trans_data[canid] = val;
48 static bool CANCommandFuelCalcRstReqCheck(void) {
49 return can_cmd_rst_rcv;
52 void CANCommandSetFuelCalcRstReq(void) {
53 can_cmd_rst_rcv = true;
56 static void CANTxMsgErrorLog(const char *reason, const char *func,
57 CANID id, uint16_t len, HANDLE h_app) {
58 FRAMEWORKUNIFIEDLOG(ZONE_ERR, func, "%s Frame(0x%x) length=%hu from %s is ignored.",
59 reason, id, len, FrameworkunifiedGetMsgSrc(h_app));
62 static EFrameworkunifiedStatus CANCommandResponse(HANDLE h_app, CAN_MSG_CANCMD *msg,
63 size_t len, char *notifyName) {
64 HANDLE h_client = NULL;
65 EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusFail;
67 h_client = CommonFindSender(h_app, notifyName);
69 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Cannot open sender handle.");
73 msg->hdr.hdr.cid = (uint16_t)CID_CAN_CMD_DELIVERY;
74 e_status = FrameworkunifiedSendMsg(h_client, CID_CAN_CMD_DELIVERY, (uint32_t)len, msg);
75 if (e_status != eFrameworkunifiedStatusOK)
76 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "FrameworkunifiedSendMsg is failed.");
81 static EFrameworkunifiedStatus CANCommandVersionReq(HANDLE h_app, char *notifyName) {
82 EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusFail;
83 CANHAL_RET_API ret = CANHAL_RET_NORMAL;
84 std::string version_info;
87 memset(&msg, 0, sizeof(msg));
89 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__, "@@@ Call CanGetVersion for can_hal");
90 ret = CanGetVersion(h_app, &version_info);
91 if (ret != CANHAL_RET_NORMAL) {
92 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Cannot get version from can_hal.");
96 if (CAN_TX_CMD_VERSION_SIZE != version_info.length()) {
97 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Invalid length of version.");
102 msg.hdr.hdr.msgbodysize = CAN_TX_CMD_DELIVERY_SIZE + CAN_TX_CMD_VERSION_SIZE;
103 msg.data.cmd_id = CAN_CMDID_VERSION_RESP_RX;
104 strncpy((char *)msg.data.data, version_info.c_str(), CAN_TX_CMD_VERSION_SIZE);
105 return CANCommandResponse(h_app, &msg, sizeof(msg), notifyName);
108 static EFrameworkunifiedStatus CANCommandFuelcalcRstReq(HANDLE h_app, char *notifyName) {
109 EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusFail;
110 if (CANCommandFuelCalcRstReqCheck()) {
111 // CAN_CMDID_FUELCALC_RST_REQ_RX is already received from can_hal.
112 // so response it in direct.
114 memset(&msg, 0, sizeof(msg));
116 msg.hdr.hdr.msgbodysize = CAN_TX_CMD_DELIVERY_SIZE +
117 CAN_TX_CMD_FUELCALC_RST_SIZE;
118 msg.data.cmd_id = CAN_CMDID_FUELCALC_RST_REQ_RX;
119 e_status = CANCommandResponse(h_app, &msg, sizeof(msg), notifyName);
121 CANDeliveryInsert(CAN_CMDID_FUELCALC_RST_REQ_RX, notifyName);
122 e_status = eFrameworkunifiedStatusOK;
127 static EFrameworkunifiedStatus CANCommandOther(HANDLE h_app, char *notifyName,
128 uint8_t cmd, uint8_t rid) {
131 CANID can_id = (CANID)cmd;
133 memset(&msg, 0, sizeof(msg));
135 case CAN_CMDID_STARTUP_FIN_REQ_TX:
136 wait = CAN_CMDID_STARTUP_FIN_RESP_RX;
138 case CAN_CMDID_MRST_INFO_REQ_TX:
139 wait = CAN_CMDID_MRST_INFO_RESP_RX;
141 case CAN_CMDID_CONNECTION_NODE_REQ_TX:
142 wait = CAN_CMDID_CONNECTION_NODE_RESP_RX;
144 case CAN_CMDID_FUELCALC_REQ_TX:
145 wait = CAN_CMDID_FUELCALC_RST_REQ_RX;
148 CANTxMsgErrorLog("Unsupported cmd requested", __func__, cmd, 0, h_app);
149 return eFrameworkunifiedStatusFail;
152 if (cmd != CAN_CMDID_FUELCALC_REQ_TX) {
153 CANDeliveryInsert(wait, notifyName);
156 if (rid != CAN_RID_NOTUSE_CODE) {
157 // cmd can be assumed same as can_id.
158 if (0 < g_m_send_sts.count(can_id)) {
159 if (g_m_send_sts[can_id].notify_name[0] != 0x00) {
160 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__,
161 "Not yet deliver SendSts but updated(SendID=%x, CAN ID=%x, Nane=%s)",
162 g_m_send_sts[can_id].rid, can_id, g_m_send_sts[can_id].notify_name);
165 g_m_send_sts[can_id].rid = rid;
166 memcpy(g_m_send_sts[can_id].notify_name, notifyName,
167 sizeof(g_m_send_sts[can_id].notify_name));
170 msg.can_id = (CANID)cmd;
172 msg.dlc = (uint8_t)CAN_CMDSND_DATA_SIZE;
174 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__, "@@@ Call CanSend for can_hal");
175 if (CANHAL_RET_NORMAL != CanSend(h_app, &msg, CAN_HAL_TYPE_CAN)) {
176 CANTxMsgErrorLog("CAN CanSend failed", __func__, msg.can_id,
177 (uint16_t)msg.dlc, h_app);
178 return eFrameworkunifiedStatusFail;
181 return eFrameworkunifiedStatusOK;
184 EFrameworkunifiedStatus CANTxMsgCommand(HANDLE h_app) {
185 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __func__, "@@@ Start communication CanCommandCtl");
187 EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusFail;
188 CAN_CMD_CTRL_MSG_DAT rcv_msg;
190 memset(&rcv_msg, 0, sizeof(rcv_msg));
192 e_status = FrameworkunifiedGetMsgDataOfSize(h_app, &rcv_msg, sizeof(rcv_msg), eSMRRelease);
193 if (e_status != eFrameworkunifiedStatusOK) {
194 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "FrameworkunifiedGetMsgDataOfSize Error(%d)", e_status);
195 if (e_status == eFrameworkunifiedStatusInvldBufSize)
196 FrameworkunifiedClearMsgData(h_app);
200 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__, "notify_name=%s ulEvtId=%x ucRid=%x ucCmdid=%x",
201 rcv_msg.notifyName, rcv_msg.ulEvtId, rcv_msg.ucRid, rcv_msg.ucCmdid);
203 switch (rcv_msg.ucCmdid) {
204 case CAN_CMDID_VERSION_REQ_TX:
205 e_status = CANCommandVersionReq(h_app, rcv_msg.notifyName);
207 case CAN_CMDID_FUELCALC_RST_REQ_DELIVERY:
208 e_status = CANCommandFuelcalcRstReq(h_app, rcv_msg.notifyName);
211 e_status = CANCommandOther(h_app,
212 rcv_msg.notifyName, rcv_msg.ucCmdid, rcv_msg.ucRid);
218 static CAN_TRANS_START_TABLE_VAL *CANTxMsgFindMap(CAN_TRANS_START_MSG_DAT *msg) {
219 std::map<CANID, CAN_TRANS_START_TABLE_VAL *>::iterator it;
220 it = g_map_trans_data.find(msg->id);
221 if (it == g_map_trans_data.end())
226 static CAN_TRANS_START_TABLE_VAL *CanSendFind(CAN_TRANS_START_MSG_DAT *msg) {
227 return CANTxMsgFindMap(msg);
230 EFrameworkunifiedStatus CANTxMsgBit(HANDLE h_app) {
231 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __func__, "@@@ Start communication CanSend(bit)");
233 EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusFail;
234 CAN_TRANS_START_MSG_DAT rcv_msg;
236 CAN_TRANS_START_TABLE_VAL *store;
242 memset(&rcv_msg, 0, sizeof(rcv_msg));
243 memset(&snd_msg, 0, sizeof(snd_msg));
245 e_status = FrameworkunifiedGetMsgDataOfSize(h_app, &rcv_msg, sizeof(rcv_msg), eSMRRelease);
246 if (e_status != eFrameworkunifiedStatusOK) {
247 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "FrameworkunifiedGetMsgDataOfSize Error(%d)", e_status);
248 if (e_status == eFrameworkunifiedStatusInvldBufSize)
249 FrameworkunifiedClearMsgData(h_app);
253 e_status = eFrameworkunifiedStatusFail;
255 if (TRUE != CommGetAvailabilityCurrent(CAN_AVAILABILITY)) {
256 CANTxMsgErrorLog("CAN is not ready", __func__, 0, 0, h_app);
260 store = CanSendFind(&rcv_msg);
262 CANTxMsgErrorLog("No initial value", __func__,
263 rcv_msg.id, sizeof(rcv_msg.dat), h_app);
267 store_p = store->dat.dat;
268 data_p = rcv_msg.dat.dat;
269 mask_p = rcv_msg.mask.dat;
270 for (i = 0; i < store->dlc; i++) {
271 *store_p &= (uint8_t)(~(*mask_p));
272 *store_p |= ((*mask_p) & (*data_p));
278 snd_msg.can_id = rcv_msg.id;
279 snd_msg.dlc = store->dlc;
280 snd_msg.rid = CAN_RID_NOTUSE_CODE;
281 memcpy(snd_msg.data, store->dat.dat, snd_msg.dlc);
283 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__,
284 "@@@ Call CanSend for can_hal : "
285 "can_id=%x dlc=%d rid=%x", snd_msg.can_id, snd_msg.dlc, snd_msg.rid);
286 FRAMEWORKUNIFIEDLOG(ZONE_DEBUG, __func__, "msg_data=%s",
287 MessageDataOutputLog(snd_msg.data, snd_msg.dlc).c_str());
289 if (CANHAL_RET_NORMAL != CanSend(h_app, &snd_msg, CAN_HAL_TYPE_CAN)) {
290 CANTxMsgErrorLog("CAN CanSend failed", __func__, snd_msg.can_id,
291 (uint16_t)snd_msg.dlc, h_app);
296 e_status = CANDeliverySndMsg(h_app, snd_msg.can_id, 0, (uint8_t)snd_msg.dlc,
297 (const uint8_t *)snd_msg.data,
298 CID_CAN_DATA_DELIVERY, CANIF_ECHOBACK);
303 EFrameworkunifiedStatus CANTxMsg(HANDLE h_app) {
304 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __func__, "@@@ Start communication CanSend");
306 EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusFail;
307 CAN_TRANSMISSION_START_MSG_DAT rcv_msg;
309 memset(&rcv_msg, 0, sizeof(rcv_msg));
310 memset(&snd_msg, 0, sizeof(snd_msg));
312 e_status = FrameworkunifiedGetMsgDataOfSize(h_app, &rcv_msg, sizeof(rcv_msg), eSMRRelease);
313 if (e_status != eFrameworkunifiedStatusOK) {
314 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "FrameworkunifiedGetMsgDataOfSize Error(%d)", e_status);
315 if (e_status == eFrameworkunifiedStatusInvldBufSize)
316 FrameworkunifiedClearMsgData(h_app);
320 e_status = eFrameworkunifiedStatusFail;
322 if (TRUE != CommGetAvailabilityCurrent(CAN_AVAILABILITY)) {
323 CANTxMsgErrorLog("CAN is not ready", __func__, 0, 0, h_app);
327 snd_msg.can_id = rcv_msg.stCandata.can_id;
328 snd_msg.dlc = rcv_msg.stCandata.dlc;
329 snd_msg.rid = rcv_msg.ucRid;
330 memcpy(snd_msg.data, rcv_msg.stCandata.data, snd_msg.dlc);
332 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__, "@@@ Call CanSend for can_hal : "
333 "can_id=%x dlc=%d rid=%x", snd_msg.can_id, snd_msg.dlc, snd_msg.rid);
334 FRAMEWORKUNIFIEDLOG(ZONE_DEBUG, __func__, "msg_data=%s",
335 MessageDataOutputLog(snd_msg.data, snd_msg.dlc).c_str());
337 if (CANHAL_RET_NORMAL != CanSend(h_app, &snd_msg, CAN_HAL_TYPE_CAN)) {
338 CANTxMsgErrorLog("CAN CanSend failed", __func__, snd_msg.can_id,
339 (uint16_t)snd_msg.dlc, h_app);
344 e_status = CANDeliverySndMsg(h_app, snd_msg.can_id, 0, (uint8_t)snd_msg.dlc,
345 (const uint8_t *)snd_msg.data,
346 CID_CAN_DATA_DELIVERY, CANIF_ECHOBACK);
347 if (rcv_msg.ucRid == (uint8_t)CAN_RID_NOTUSE_CODE)
350 if (0 < g_m_send_sts.count(snd_msg.can_id)) {
351 if (g_m_send_sts[snd_msg.can_id].notify_name[0] != 0x00) {
352 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__,
353 "Not yet deliver SendSts but updated(SendID=%x, CAN ID=%x, Nane=%s)",
354 g_m_send_sts[snd_msg.can_id].rid, snd_msg.can_id,
355 g_m_send_sts[snd_msg.can_id].notify_name);
359 g_m_send_sts[snd_msg.can_id].rid = rcv_msg.ucRid;
360 memcpy(g_m_send_sts[snd_msg.can_id].notify_name,
362 sizeof(g_m_send_sts[snd_msg.can_id].notify_name));
367 EFrameworkunifiedStatus CANSndStsProcess(HANDLE h_app, CanSendResult *rcv_msg,
368 PS_CommunicationProtocol cid) {
369 EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusOK;
370 CAN_MSG_SENDSTS snd_msg;
371 CANID can_id = rcv_msg->can_id;
372 HANDLE sender = NULL;
373 memset(&snd_msg, 0, sizeof(snd_msg));
375 if (0 == g_m_send_sts.count(can_id))
378 if (0x00 == (g_m_send_sts[can_id].notify_name[0]))
381 if (rcv_msg->rid != g_m_send_sts[can_id].rid)
384 snd_msg.hdr.hdr.cid = (uint16_t)cid;
385 snd_msg.hdr.hdr.msgbodysize = (uint16_t)(sizeof(snd_msg.data));
386 snd_msg.hdr.hdr.rid = rcv_msg->rid;
387 snd_msg.data.ulCanid = can_id;
388 snd_msg.data.ucStatus =
389 (CAN_SEND_RESULT_SUCCESS == rcv_msg->result) ? CAN_SUCCESS : CAN_RETRYOUT;
391 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__, "cid=%x msgbodysize=%d rid=%x can_id=%x ucStatus=%x",
392 snd_msg.hdr.hdr.cid, snd_msg.hdr.hdr.msgbodysize, snd_msg.hdr.hdr.rid,
393 snd_msg.data.ulCanid, snd_msg.data.ucStatus);
395 sender = CommonFindSender(h_app, g_m_send_sts[can_id].notify_name);
397 CANTxMsgErrorLog("Could not open sender.", __func__, can_id,
398 sizeof(snd_msg), h_app);
402 e_status = FrameworkunifiedSendMsg(sender, cid, sizeof(snd_msg), &snd_msg);
403 if (eFrameworkunifiedStatusOK != e_status) {
404 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "FrameworkunifiedSendMsg Error(e_status:%d to:%s)",
405 e_status, g_m_send_sts[can_id].notify_name);
406 g_m_send_sts[can_id].notify_name[0] = 0x00;
407 g_m_send_sts[can_id].rid = 0x00;
410 g_m_send_sts[can_id].notify_name[0] = 0x00;
411 g_m_send_sts[can_id].rid = 0x00;
413 e_status = eFrameworkunifiedStatusOK;