Remove unused directories and files in video_in_hal
[staging/basesystem.git] / can_hal / src / can_hal_core.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.h"
18 #include "can_hal_core.h"
19 #include "can_hal_internal.h"
20 #include "can_hal_frameworkunifiedlog.h"
21 #include "can_hal_stm.h"
22 extern "C" {
23   #include "can_mng_api.h"
24 }
25 #include <native_service/ns_message_center_if.h>
26 #include <native_service/frameworkunified_framework_if.h>
27 #include <native_service/frameworkunified_multithreading.h>
28 #include <stdio.h>
29 #include <pthread.h>
30 #include <string>
31
32 static CanCtlApiObj g_driver_obj;        // can driver handler
33
34 typedef struct MessageWrapper {
35   HANDLE h_app;
36   void *message;
37 } MessageWrapper;
38
39 // define frame
40 enum CANHAL_FRAME {
41   CANHAL_FRAME_SF = 0x00,
42   CANHAL_FRAME_FF,
43   CANHAL_FRAME_CF,
44   CANHAL_FRAME_NONE = 0xFF,
45 };
46
47 // Declaration of the local functions
48 static EFrameworkunifiedStatus CanSendData(HANDLE h_app);
49 static UINT8 PackageSendData(const CanMessage *send_msg,
50                             UINT8 *send_cmd);
51 static UINT8 PackageRecvData(const UINT8 *recv_data, CanMessage *message);
52 static uint32_t GetCanId(const UINT8 *recv_data);
53
54 #define CANHAL_VALID_NUM_INDEX   0x00
55 #define CANHAL_CANID_HI_INDEX    0x00
56 #define CANHAL_CANID_LO_INDEX    0x01
57 #define CANHAL_DLC_INDEX         0x02
58 #define CANHAL_DATA_START_INDEX  0x03
59
60 #define CANHAL_RECV_DATA_LENGTH_INVALID 0xFF
61
62 #define CANHAL_RECV_DATABLOCK_SIZE                (0x0B)
63 #define CANHAL_RECV_NTA_INDEX                     (0x03)
64
65 // Register table for framework callback
66 static const FrameworkunifiedProtocolCallbackHandler kCanHalPcbhs[] = {
67   { TX_INTERNAL, CanSendData },
68 };
69
70 void *CanHalPackMessage(HANDLE h_app, const void *msg, ssize_t msg_sz,
71                         ssize_t *packed_sz) {
72   *packed_sz = msg_sz + sizeof(ssize_t) + sizeof(HANDLE);
73   void *p = malloc(*packed_sz);
74   if (p) {
75     char *_p = (char *)p;
76     // Set HANDLE to new buffer.
77     memcpy(_p, &h_app, sizeof(HANDLE));
78     // Set message size to new buffer
79     _p += sizeof(HANDLE);
80     *(ssize_t *)_p = msg_sz;
81     // Set message body to new buffer
82     _p += (sizeof(ssize_t));
83     memcpy(_p, msg, msg_sz);
84   }
85   return p;
86 }
87
88 void CanHalUnPackMessage(void *packed, HANDLE *h_app, void **msg,
89                          ssize_t *msg_sz) {
90   char *_p = (char *)packed;
91   *h_app = *(HANDLE *)_p;
92   _p += sizeof(HANDLE);
93   *msg_sz = *((ssize_t *)_p);
94   _p += sizeof(ssize_t);
95   *msg = _p;
96 }
97
98 void CanHalDestroyPackedMessage(void *packed) {
99   free(packed);
100 }
101
102 // Start function of the receive thread
103 void *CanRecvRun(void *arg) {
104   UINT8 data_start_index = 0;
105   UINT8 loop_num = 0;
106   UINT32 ret = 0;
107   CanCtlApiCmd recv_cmd;
108   memset(&recv_cmd, 0x00, sizeof(CanCtlApiCmd));
109   CanMessage recv_data_can;
110   memset(&recv_data_can, 0x00, sizeof(recv_data_can));
111   enum CanHalType *type = (enum CanHalType *)arg;
112
113   while (1) {
114     // call driver API to receive the can data
115     ret = CanCtlApiRcvCmd(&g_driver_obj, &recv_cmd);
116     if (CAN_CTL_RET_SUCCESS != ret) {
117       continue;
118     }
119
120     /**
121      * Receive data in the following structure:
122      *           -----------------
123      * BYTE 01  | num of can data |
124      *           -----------------
125      * BYTE 02  | CAN ID (Hi)     |
126      *           -----------------
127      * BYTE 03  | CAN ID (Lo)     |
128      *           -----------------
129      * BYTE 04  | DLC             |
130      *           -----------------
131      * BYTE 05  | DATA #1         |
132      *           -----------------
133      *          | ...             |
134      *           -----------------
135      * BYTE 12  | DATA #8         |
136      *           -----------------
137      * BYTE 13  | CAN ID (Hi)     |
138      *           -----------------
139      * BYTE 14  | CAN ID (Lo)     |
140      *           -----------------
141      * BYTE 15  | DLC             |
142      *           -----------------
143      * BYTE 16  | DATA #1         |
144      *           -----------------
145      *          | ...             |
146      *           -----------------
147      * BYTE 23  | DATA #8         |
148      *           -----------------
149      *          | ...             |
150      *           -----------------
151      * BYTE 255 |                 |
152      *           -----------------
153      *
154      * BYTE 0 for the invalid number of the can data
155      * CAN ID (Hi) and (Lo) combine for the CAN ID
156      * CAN ID (Hi) byte's low 7 bits is the high 7 bits of the CAN ID
157      * CAN ID (Lo) byte's high 4 bits is the low 4 bits of the CAN ID
158      * DLC for the length of the following data
159      * DATA #1 ~ #8 for the receive data, its actual length changes
160      *   according to the previous DLC byte
161      */
162     UINT8 total_data_num = recv_cmd.data[CANHAL_VALID_NUM_INDEX];
163     data_start_index = 1;
164
165     for (loop_num = 0; loop_num < total_data_num; loop_num++) {
166       uint32_t can_id;
167       can_id = GetCanId(&(recv_cmd.data[data_start_index]));
168
169       // normal can
170       // Return value of the PackageRecvData is the total length
171       //   of one can data package, so add to the data_start_index
172       //   for the next can data package.
173       ret = PackageRecvData(&(recv_cmd.data[data_start_index]),
174                             &recv_data_can);
175       if (CANHAL_RECV_DATA_LENGTH_INVALID == ret) {
176         continue;
177       }
178       data_start_index += ret;
179       CanHalReceiveNotify(*type, &(recv_data_can), sizeof(recv_data_can));
180     }
181
182     // reset buffer
183     memset(&recv_cmd, 0x00, sizeof(CanCtlApiCmd));
184     usleep(1000);
185   }
186
187   return NULL;
188 }
189
190 // get can id from recive buffer
191 static uint32_t GetCanId(const UINT8 *recv_data) {
192   uint32_t can_id;
193   can_id = (recv_data[CANHAL_CANID_HI_INDEX] & 0x7F);
194   can_id <<= 4;
195   can_id |= ((recv_data[CANHAL_CANID_LO_INDEX] & 0xF0) >> 4);
196   return can_id;
197 }
198
199 static CANHAL_RET_API CanOpenCoreCAN(void) {
200   CanCtlRcvId recv_can_id;
201   memset(recv_can_id.id, 0xFF, sizeof(recv_can_id.id));
202   if (CAN_CTL_RET_SUCCESS != CanCtlApiOpen(&g_driver_obj))
203     return CANHAL_RET_ERR_ERR;
204
205   if (CAN_CTL_RET_SUCCESS != CanCtlApiSetRcvId(&g_driver_obj, &recv_can_id)) {
206     return CANHAL_RET_ERR_ERR;
207   }
208
209   return CANHAL_RET_NORMAL;
210 }
211
212 CANHAL_RET_API CanOpenCore(CanHalType type) {
213   CANHAL_RET_API ret = CANHAL_RET_ERR_ERR;
214   switch (type) {
215   case CAN_HAL_TYPE_CAN:
216     ret = CanOpenCoreCAN();
217     break;
218   default:
219     // Do nothing
220     break;
221   }
222   return ret;
223 }
224
225 // Initialize the sending thread
226 EFrameworkunifiedStatus CanSendThreadStart(HANDLE h_app) {
227   EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusOK;
228   intptr_t ptr;
229   e_status = FrameworkunifiedAttachCallbacksToDispatcher(h_app,
230                                             FRAMEWORKUNIFIED_ANY_SOURCE,
231                                             kCanHalPcbhs,
232                                             _countof(kCanHalPcbhs));
233   if (e_status != eFrameworkunifiedStatusOK)
234     goto finish;
235   
236   e_status = FrameworkunifiedGetMsgDataOfSize(h_app, &ptr, sizeof(ptr));
237   if (e_status != eFrameworkunifiedStatusOK)
238     goto finish;
239
240   *((HANDLE *)ptr) = FrameworkunifiedMcOpenSender(h_app, FrameworkunifiedGetAppName(h_app));
241   if (!(*(HANDLE *)ptr))
242     e_status = eFrameworkunifiedStatusFail;
243
244 finish:
245   return e_status;
246 }
247
248 // Clean the sending thread
249 EFrameworkunifiedStatus CanSendThreadStop(HANDLE h_app) {
250   EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusOK;
251   intptr_t ptr;
252   e_status = FrameworkunifiedGetMsgDataOfSize(h_app, &ptr, sizeof(ptr));
253   if (e_status != eFrameworkunifiedStatusOK)
254     goto finish;
255
256   FrameworkunifiedMcClose(*((HANDLE*)ptr));
257 finish:
258   return e_status;
259 }
260
261 static CANHAL_RET_API CanCloseCoreCAN(void) {
262   CanCtlApiClose(&g_driver_obj);
263   return CANHAL_RET_NORMAL;
264 }
265
266 // Stop the can hal
267 CANHAL_RET_API CanCloseCore(CanHalType type) {
268   CANHAL_RET_API ret = CANHAL_RET_NORMAL;
269   switch (type) {
270   case CAN_HAL_TYPE_CAN:
271     ret = CanCloseCoreCAN();
272     if (ret != CANHAL_RET_NORMAL)
273       goto finish;
274     break;
275   default:
276     goto finish;
277     break;
278   }
279 finish:
280   return ret;
281 }
282
283 // Callback for the sending thread to send the can data
284 static EFrameworkunifiedStatus CanSendData(HANDLE h_app) {
285   UINT8 ret = 0;
286   EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusOK;
287   HANDLE hb = NULL;
288   CanMessage mb;
289   ssize_t sz = 0;
290   void *send_msg = NULL;
291   HANDLE unpacked_h_app;
292   CanMessage *unpacked_msg;
293   ssize_t unpacked_sz;
294
295   send_msg = CanHalPackMessage(hb, (const void *)&mb, sizeof(mb), &sz);
296   if (!send_msg)
297     return eFrameworkunifiedStatusFail;
298
299   e_status = FrameworkunifiedGetMsgDataOfSize(h_app, send_msg, sz, eSMRRelease);
300   if (eFrameworkunifiedStatusOK != e_status) {
301     if (eFrameworkunifiedStatusInvldBufSize == e_status) {
302       FrameworkunifiedClearMsgData(h_app);
303     }
304     return eFrameworkunifiedStatusFail;
305   }
306
307   CanHalUnPackMessage(send_msg, &unpacked_h_app,
308                       (void **)&unpacked_msg, &unpacked_sz);
309
310   CanCtlApiCmd send_can_data;
311   memset(&send_can_data, 0, sizeof(CanCtlApiCmd));
312   send_can_data.data[CANHAL_VALID_NUM_INDEX] = 1;
313   ret = PackageSendData(unpacked_msg, &(send_can_data.data[1]));
314   send_can_data.len = ret + 1;
315   CanSendResult send_result;
316   send_result.can_id = unpacked_msg->can_id;
317   send_result.rid = unpacked_msg->rid;
318
319   if (CAN_CTL_RET_SUCCESS == CanCtlApiSndCmd(&g_driver_obj, &send_can_data)) {
320     send_result.result = CAN_SEND_RESULT_SUCCESS;
321   } else {
322     send_result.result = CAN_SEND_RESULT_FAILURE;
323   }
324   FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "Send status is %d.", send_result.result);
325
326   if (CANHAL_RET_NORMAL != CanHalSendStatus(CAN_HAL_TYPE_CAN,
327                            unpacked_h_app, &send_result, sizeof(send_result))) {
328     CanHalDestroyPackedMessage(send_msg);
329     return eFrameworkunifiedStatusFail;
330   }
331
332   CanHalDestroyPackedMessage(send_msg);
333   return eFrameworkunifiedStatusOK;
334 }
335
336 /**
337  * param [in]  send_msg
338  * param [out] send_can_data
339  */
340 static UINT8 PackageSendData(const CanMessage *send_msg,
341                              UINT8 *send_can_data) {
342   // package according to the rule of the data structure,
343   //   refer to the line 108 and 109
344   send_can_data[CANHAL_CANID_HI_INDEX] = (send_msg->can_id & 0x7F0) >> 4;
345   send_can_data[CANHAL_CANID_LO_INDEX] = (send_msg->can_id & 0x0F) << 4;
346   send_can_data[CANHAL_DLC_INDEX] = send_msg->dlc;
347   memcpy(&(send_can_data[CANHAL_DATA_START_INDEX]),
348          send_msg->data,
349          send_msg->dlc);
350   return (send_msg->dlc + CANHAL_DATA_START_INDEX);
351 }
352
353 /**
354  * param [in]  recv_data
355  * param [out] message
356  */
357 static UINT8 PackageRecvData(const UINT8 *recv_data, CanMessage *message) {
358   if (CAN_NORMAL_MESSAGE_LEN < recv_data[CANHAL_DLC_INDEX]) {
359     // receive data's length is invalid
360     return CANHAL_RECV_DATA_LENGTH_INVALID;
361   }
362   // package according to the rule of the data structure,
363   //   refer to the line 108 and 109
364   message->can_id = recv_data[CANHAL_CANID_HI_INDEX] & 0x7F;
365   message->can_id <<= 4;
366   message->can_id |= (recv_data[CANHAL_CANID_LO_INDEX] & 0xF0) >> 4;
367   message->dlc = recv_data[CANHAL_DLC_INDEX];
368   memcpy(message->data, &(recv_data[CANHAL_DATA_START_INDEX]), CAN_NORMAL_MESSAGE_LEN);
369
370   return CANHAL_RECV_DATABLOCK_SIZE;
371 }
372