Init basesystem source codes.
[staging/basesystem.git] / video_in_hal / can_hal / src / can_hal_stm.cpp
1 /*
2  * @copyright Copyright (c) 2017-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_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>
23 #include <string>
24 #include <stdbool.h>
25 #include <stdint.h>
26 #include <assert.h>
27 #include <pthread.h>
28
29 // BSS section would be initialized to all 0.
30 struct CanHalStateMachine {
31   CanHalType type;
32   HANDLE h_app;
33   bool can_hal_is_opened;
34   bool device_is_enabled;
35   struct {
36     HANDLE tx;
37     HANDLE tx_sender;
38     uint32_t tx_cmd;
39     const char *tx_name;
40     bool rx_initialized;
41     pthread_t rx;
42     pthread_attr_t rx_attr;
43   } internal;
44 } can_hal_stm[NR_CAN_HAL_TYPES];
45
46 bool TypeIsValid(enum CanHalType type) {
47   if (CAN_HAL_TYPE_CAN == type)
48     return true;
49
50   return false;
51 }
52
53 bool IsCanHalOpened(enum CanHalType type) {
54   return can_hal_stm[type].can_hal_is_opened;
55 }
56
57 void SetCanHalStateOpen(enum CanHalType type) {
58   can_hal_stm[type].can_hal_is_opened = true;
59 }
60
61 void SetCanHalStateClose(enum CanHalType type) {
62   can_hal_stm[type].can_hal_is_opened = false;
63 }
64
65 bool IsDeviceEnabled(enum CanHalType type) {
66   return can_hal_stm[type].device_is_enabled;
67 }
68
69 void SetDeviceStateEnable(enum CanHalType type) {
70   can_hal_stm[type].device_is_enabled = true;
71 }
72
73 void SetDeviceStateDisable(enum CanHalType type) {
74   can_hal_stm[type].device_is_enabled = false;
75 }
76
77 CANHAL_RET_API CanHalDestroyInternalThread(HANDLE h_app, enum CanHalType type) {
78   intptr_t ptr = (intptr_t)&(can_hal_stm[type].internal.tx_sender);
79
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;
84   }
85
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;
90   }
91   can_hal_stm[type].h_app = NULL;
92   return CANHAL_RET_NORMAL;
93 }
94
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);
99
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)
106     goto cleanup;
107
108   err = FrameworkunifiedStartChildThread(h_app,
109                   can_hal_stm[type].internal.tx, 
110                   sizeof(ptr), &ptr);
111   if (err != eFrameworkunifiedStatusOK)
112     goto cleanup;
113
114   if (0 != pthread_attr_init(&(can_hal_stm[type].internal.rx_attr)))
115     goto cleanup;
116
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)))
120     goto cleanup;
121
122   can_hal_stm[type].internal.rx_initialized = true;
123   ret = CANHAL_RET_NORMAL;
124   return ret;
125 cleanup:
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;
130   }
131
132   return ret;
133 }
134
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;
141   }
142   return CANHAL_RET_NORMAL;
143 }
144
145 static EFrameworkunifiedStatus FrameworkunifiedSendMsgOneshot(HANDLE h_app, UI_32 cmd,
146                                     UI_32 l, PCVOID d) {
147   HANDLE h_client = NULL;
148   EFrameworkunifiedStatus err = eFrameworkunifiedStatusFail;
149
150   h_client = FrameworkunifiedMcOpenSender(h_app, FrameworkunifiedGetAppName(h_app));
151   if (!h_client)
152     return err;
153
154   err = FrameworkunifiedSendMsg(h_client, cmd, l, d);
155   FrameworkunifiedMcClose(h_client);
156   return err;
157 }
158
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;
165   }
166   return CANHAL_RET_NORMAL;
167 }
168
169
170 CANHAL_RET_API InvokeStateCallback(enum CanHalType type) {
171   HANDLE sender = can_hal_stm[type].h_app;
172   uint32_t cmd = 0;
173   EFrameworkunifiedStatus err = eFrameworkunifiedStatusOK;
174   bool send = true;
175
176   switch (type) {
177   case CAN_HAL_TYPE_CAN:
178     cmd = CID_CANHAL_CMD_CAN_READY;
179     break;
180   default:
181     assert(0);
182     break;
183   }
184
185   err = FrameworkunifiedSendMsgOneshot(sender, cmd, sizeof(send), &send);
186   if (err != eFrameworkunifiedStatusOK)
187     return CANHAL_RET_ERR_ERR;
188   return CANHAL_RET_NORMAL;
189 }
190
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;
197
198   switch (type) {
199   case CAN_HAL_TYPE_CAN:
200     sprintf(msg, "Global CAN Stop");
201     break;
202   default:
203     assert(0);
204     break;
205   }
206
207   err = FrameworkunifiedSendMsgOneshot(sender, cmd, sz, msg);
208   if (err != eFrameworkunifiedStatusOK)
209     return CANHAL_RET_ERR_ERR;
210   return CANHAL_RET_NORMAL;
211 }
212
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;
219   }
220   return CANHAL_RET_NORMAL;
221 }
222
223 CANHAL_RET_API CanHalReceiveNotify(enum CanHalType type,
224                                      const void *msg, ssize_t sz) {
225   EFrameworkunifiedStatus e_status;
226   uint32_t cmd = 0;
227
228   switch (type) {
229   case CAN_HAL_TYPE_CAN:
230     cmd = CID_CANHAL_CMD_CAN_RECV;
231     break;
232   default:
233     assert(0);
234     break;
235   }
236
237   e_status = FrameworkunifiedSendMsgOneshot(can_hal_stm[type].h_app, cmd, sz, msg);
238   if (e_status != eFrameworkunifiedStatusOK) {
239     return CANHAL_RET_ERR_ERR;
240   }
241
242   return CANHAL_RET_NORMAL;
243 }