2 * @copyright Copyright (c) 2017-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.
17 #include "can_hal_stm.h"
18 #include "can_hal_core.h"
19 #include "can_hal_internal.h"
20 #include <native_service/ns_message_center_if.h>
21 #include <native_service/frameworkunified_framework_if.h>
22 #include <native_service/frameworkunified_multithreading.h>
29 // BSS section would be initialized to all 0.
30 struct CanHalStateMachine {
33 bool can_hal_is_opened;
34 bool device_is_enabled;
42 pthread_attr_t rx_attr;
44 } can_hal_stm[NR_CAN_HAL_TYPES];
46 bool TypeIsValid(enum CanHalType type) {
47 if (CAN_HAL_TYPE_CAN == type)
53 bool IsCanHalOpened(enum CanHalType type) {
54 return can_hal_stm[type].can_hal_is_opened;
57 void SetCanHalStateOpen(enum CanHalType type) {
58 can_hal_stm[type].can_hal_is_opened = true;
61 void SetCanHalStateClose(enum CanHalType type) {
62 can_hal_stm[type].can_hal_is_opened = false;
65 bool IsDeviceEnabled(enum CanHalType type) {
66 return can_hal_stm[type].device_is_enabled;
69 void SetDeviceStateEnable(enum CanHalType type) {
70 can_hal_stm[type].device_is_enabled = true;
73 void SetDeviceStateDisable(enum CanHalType type) {
74 can_hal_stm[type].device_is_enabled = false;
77 CANHAL_RET_API CanHalDestroyInternalThread(HANDLE h_app, enum CanHalType type) {
78 intptr_t ptr = (intptr_t)&(can_hal_stm[type].internal.tx_sender);
80 if (can_hal_stm[type].internal.tx) {
81 FrameworkunifiedStopChildThread(h_app, can_hal_stm[type].internal.tx, sizeof(ptr), &ptr);
82 FrameworkunifiedDestroyChildThread(h_app, can_hal_stm[type].internal.tx);
83 can_hal_stm[type].internal.tx = NULL;
86 if (can_hal_stm[type].internal.rx_initialized) {
87 pthread_cancel(can_hal_stm[type].internal.rx);
88 pthread_join(can_hal_stm[type].internal.rx, NULL);
89 can_hal_stm[type].internal.rx_initialized = false;
91 can_hal_stm[type].h_app = NULL;
92 return CANHAL_RET_NORMAL;
95 CANHAL_RET_API CanHalCreateInternalThread(HANDLE h_app, enum CanHalType type) {
96 enum CANHAL_RET_API ret = CANHAL_RET_ERR_PARAM;
97 EFrameworkunifiedStatus err = eFrameworkunifiedStatusOK;
98 intptr_t ptr = (intptr_t)&(can_hal_stm[type].internal.tx_sender);
100 can_hal_stm[type].h_app = h_app;
101 can_hal_stm[type].internal.tx_name = CANHAL_CAN_SEND_THREAD;
102 can_hal_stm[type].internal.tx = FrameworkunifiedCreateChildThread(h_app,
103 can_hal_stm[type].internal.tx_name,
104 CanSendThreadStart, CanSendThreadStop);
105 if (!can_hal_stm[type].internal.tx)
108 err = FrameworkunifiedStartChildThread(h_app,
109 can_hal_stm[type].internal.tx,
111 if (err != eFrameworkunifiedStatusOK)
114 if (0 != pthread_attr_init(&(can_hal_stm[type].internal.rx_attr)))
117 if (0 != pthread_create(&(can_hal_stm[type].internal.rx),
118 &(can_hal_stm[type].internal.rx_attr), CanRecvRun,
119 (void *)&(can_hal_stm[type].type)))
122 can_hal_stm[type].internal.rx_initialized = true;
123 ret = CANHAL_RET_NORMAL;
126 if (can_hal_stm[type].internal.tx) {
127 FrameworkunifiedStopChildThread(h_app, can_hal_stm[type].internal.tx, sizeof(ptr), &ptr);
128 FrameworkunifiedDestroyChildThread(h_app, can_hal_stm[type].internal.tx);
129 can_hal_stm[type].internal.tx = NULL;
135 CANHAL_RET_API CanHalInternalSend_CWORD118_(enum CanHalType type,
136 const void *msg, ssize_t sz) {
137 EFrameworkunifiedStatus e_status = FrameworkunifiedSendMsg(can_hal_stm[type].internal.tx_sender,
138 TX_INTERNAL__CWORD118_, sz, msg);
139 if (e_status != eFrameworkunifiedStatusOK) {
140 return CANHAL_RET_ERR_ERR;
142 return CANHAL_RET_NORMAL;
145 static EFrameworkunifiedStatus FrameworkunifiedSendMsgOneshot(HANDLE h_app, UI_32 cmd,
147 HANDLE h_client = NULL;
148 EFrameworkunifiedStatus err = eFrameworkunifiedStatusFail;
150 h_client = FrameworkunifiedMcOpenSender(h_app, FrameworkunifiedGetAppName(h_app));
154 err = FrameworkunifiedSendMsg(h_client, cmd, l, d);
155 FrameworkunifiedMcClose(h_client);
159 CANHAL_RET_API CanHalInternalSend(enum CanHalType type,
160 const void *msg, ssize_t sz) {
161 EFrameworkunifiedStatus e_status = FrameworkunifiedSendMsg(can_hal_stm[type].internal.tx_sender,
162 TX_INTERNAL, sz, msg);
163 if (e_status != eFrameworkunifiedStatusOK) {
164 return CANHAL_RET_ERR_ERR;
166 return CANHAL_RET_NORMAL;
170 CANHAL_RET_API InvokeStateCallback(enum CanHalType type) {
171 HANDLE sender = can_hal_stm[type].h_app;
173 EFrameworkunifiedStatus err = eFrameworkunifiedStatusOK;
177 case CAN_HAL_TYPE_CAN:
178 cmd = CID_CANHAL_CMD_CAN_READY;
185 err = FrameworkunifiedSendMsgOneshot(sender, cmd, sizeof(send), &send);
186 if (err != eFrameworkunifiedStatusOK)
187 return CANHAL_RET_ERR_ERR;
188 return CANHAL_RET_NORMAL;
191 CANHAL_RET_API InvokeErrorCallback(HANDLE h_app, enum CanHalType type) {
192 HANDLE sender = h_app;
193 uint32_t cmd = CID_CANHAL_CMD_ERROR_NOTIFY;
194 char msg[CANHAL_ERROR_MESSAGE_LEN] = {0};
195 ssize_t sz = sizeof(msg);
196 EFrameworkunifiedStatus err = eFrameworkunifiedStatusOK;
199 case CAN_HAL_TYPE_CAN:
200 sprintf(msg, "Global CAN Stop");
207 err = FrameworkunifiedSendMsgOneshot(sender, cmd, sz, msg);
208 if (err != eFrameworkunifiedStatusOK)
209 return CANHAL_RET_ERR_ERR;
210 return CANHAL_RET_NORMAL;
213 CANHAL_RET_API CanHalSendStatus(enum CanHalType type, HANDLE h_app,
214 const void *msg, ssize_t sz) {
215 EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusOK;
216 e_status = FrameworkunifiedSendMsgOneshot(h_app, CID_CANHAL_CMD_CAN_SEND_STATUS, sz, msg);
217 if (e_status != eFrameworkunifiedStatusOK) {
218 return CANHAL_RET_ERR_ERR;
220 return CANHAL_RET_NORMAL;
223 CANHAL_RET_API CanHalReceiveNotify(enum CanHalType type,
224 const void *msg, ssize_t sz) {
225 EFrameworkunifiedStatus e_status;
229 case CAN_HAL_TYPE_CAN:
230 cmd = CID_CANHAL_CMD_CAN_RECV;
237 e_status = FrameworkunifiedSendMsgOneshot(can_hal_stm[type].h_app, cmd, sz, msg);
238 if (e_status != eFrameworkunifiedStatusOK) {
239 return CANHAL_RET_ERR_ERR;
242 return CANHAL_RET_NORMAL;