Branch data MC/DC data Line data Source code
1 : : : #include "can_utils.h"
2 : : : #include "dio_utils.h"
3 : : : #include <ecu.h>
4 : : : #include <mcal.h>
5 : : :
6 : : : #include <linux/can.h> // struct can_frame, canid_t
7 : : : #include <linux/can/raw.h> // CAN_RAW para socket
8 : : : #include <net/if.h> // struct ifreq, IFNAMSIZ
9 : : : #include <stdint.h> // uint8_t
10 : : : #include <stdio.h> // printf, perror, sprintf
11 : : : #include <stdlib.h> // system
12 : : : #include <string.h> // strcpy, strncpy, memset
13 : : : #include <sys/ioctl.h> // ioctl, SIOCGIFFLAGS, SIOCGIFINDEX
14 : : : #include <sys/socket.h> // socket, bind
15 : : : #include <sys/types.h> // Tipos de dados do sistema
16 : : : #include <unistd.h> // close, write
17 : : : #include <time.h> // clock_getime()
18 : : :
19 : : : dIO pins[IOPINS];
20 : : : // pin 0 - luz de pisca alerta
21 : : : // pin 1 - botão do pisca alerta
22 : : : // pin 2 - Server envia bloqueio REB
23 : : : // pin 3 - reb envia sinal de REB ativado ao motorista
24 : : : // pin 4 - Server envia desbloqueio REB
25 : : : // pin 5 - REB envia sinal para motor ser bloqueado
26 : : : //
27 : : : // pin 8 - Envia sinal na redCAN para desligar o pisca alerta
28 : : : // pin 9 - Envia sinal na redCAN para ligar o pisca alerta
29 : : :
30 : : : int my_vcan;
31 : : : const char *interface = "vcan0";
32 : : :
33 : : : /**
34 : : : *
35 : : : * @brief Create a new thread in posix.
36 : : : * @param func Pointer to the function that will runin the thread.
37 : : : * @return The created pthread_t identifier.
38 : : : */
39 : : 1 : pthread_t new_thread(void *func)
40 : : : {
41 : : : pthread_t nthread;
42 : : 1 : (void)pthread_create(&nthread, NULL, func, NULL);
43 : : 1 : return nthread;
44 : : : }
45 : : :
46 : : : /**
47 : : : * @brief Show in terminal ERROR Message.
48 : : : * @param errorStr Pointer to the charr array of message.
49 : : : * @requir{SwHLR_F_16}
50 : : : * @return SUCCESS(0), FAIL(1)
51 : : : */
52 : : 83 : void show_error(const char errorStr[])
53 : : : {
54 : : 83 : (void) printf("%s", errorStr);
55 : : 83 : }
56 : : :
57 : : : /**
58 : : : * @brief Set the status of PIN by terminal
59 : : : *
60 : : : * @param p_pin Pointer of PIN number to be read.
61 : : : * @param p_ststus Pointer to store the read status of the PIN (0 or 1).
62 : : : * @return SUCCESS(0), FAIL(1)
63 : : : * @requir{SwHLR_F_13}
64 : : : */
65 : : 18 : uint8_t read_pint_status(uint8_t *p_pin, uint8_t *p_status)
66 : : : {
67 : : 18 : char *line = NULL;
68 : : 18 : size_t len = 0;
69 : : 18 : uint8_t ret = SUCCESS;
70 [ + + ]: [ T F ]: 18 : if (getline(&line, &len, stdin) == -1)
71 : : : {
72 : : 1 : ret = FAIL;
73 : : : }
74 [ + + ]: [ T F ]: 14 : if (ret == SUCCESS)
75 : : : {
76 [ + + ]: [ T F ]: 13 : if (memcmp(line, "pin", 3) == 0)
77 : : : {
78 : : : int pin;
79 : : : int status;
80 [ + + ]: [ T F ]: 12 : if (sscanf(line + 4, "%d %d", &pin, &status) == 2)
81 : : : {
82 [ + + + + ]:[ T F T F ]: 10 : if ((status == 0) || (status == 1))
83 : : : {
84 : : 8 : *p_pin = pin;
85 : : 8 : *p_status = status;
86 : : 8 : ret = SUCCESS;
87 : : : }
88 : : : else
89 : : : {
90 : : 2 : ret = FAIL;
91 : : : }
92 : : : }
93 : : : else
94 : : : {
95 : : 2 : ret = FAIL;
96 : : : }
97 : : : }
98 : : : else
99 : : : {
100 : : 1 : ret = FAIL;
101 : : : }
102 : : : }
103 : : 14 : free(line);
104 : : 14 : return ret;
105 : : : }
106 : : :
107 : : : /**
108 : : : * @brief Inicializate the PINs status.
109 : : : *
110 : : : * @return void
111 : : : */
112 : : 57 : void mcal_init(void)
113 : : : {
114 [ + + ]: [ T F ]: 627 : for (uint8_t i = 0; i < IOPINS; i++)
115 : : : {
116 : : 570 : pins[i].pinNumber = i;
117 : : 570 : pins[i].status = 0;
118 : : : }
119 : : 57 : }
120 : : :
121 : : : /**
122 : : : * @brief Get the status of desired PIN number.
123 : : : *
124 : : : * @param status Pointer to store the read status of the PIN (0 or 1).
125 : : : * @param pin Pointer of PIN number to be read.
126 : : : * @return SUCCESS(0), FAIL(1)
127 : : : * @requir{SwHLR_F_13}
128 : : : */
129 : : 886251469 : uint8_t read_pin_status(uint8_t *status, uint8_t pin)
130 : : : {
131 : : 886251469 : uint8_t return_status = FAIL;
132 [ + + ]: [ T F ]: 886251469 : if (pin < IOPINS)
133 : : : {
134 : : 886251468 : return_status = dio_get_pin(status, pin, pins);
135 : : : }
136 : : 886251469 : return return_status;
137 : : : }
138 : : :
139 : : : /**
140 : : : * @brief Set the status of desired PIN number.
141 : : : *
142 : : : * @param status Pointer to store the status of the PIN (0 or 1).
143 : : : * @param pin Pointer of PIN number to be read.
144 : : : * @return SUCCESS(0), FAIL(1)
145 : : : * @requir{SwHLR_F_13}
146 : : : */
147 : : 97 : uint8_t set_pin_status(uint8_t p_status, uint8_t p_pin)
148 : : : {
149 : : 97 : uint8_t return_status = FAIL;
150 [ + + ]: [ T F ]: 97 : if (p_pin < IOPINS)
151 : : : {
152 : : 96 : return_status = dio_set_pin(p_status, p_pin, pins);
153 : : : }
154 : : 97 : return return_status;
155 : : : }
156 : : :
157 : : : /**
158 : : : * @brief Sleep thread POSIX.
159 : : : *
160 : : : * @param seconds How many seconds to sleep.
161 : : : */
162 : : 106 : void go_sleep(uint8_t seconds) { (void)sleep(seconds); }
163 : : :
164 : : : //======================================================================
165 : : : //======================== CAN =========================================
166 : : : //======================================================================
167 : : :
168 : : : /**
169 : : : * @brief Opens Can socket - does not depend on VCAN interface.
170 : : : *
171 : : : * @param can_socket Pointer to store the number of socket.
172 : : : * @return SUCCESS(0), FAIL(1)
173 : : : * @requir{SwHLR_F_6}
174 : : : * @requir{SwHLR_F_10}
175 : : : * @requir{SwHLR_F_15}
176 : : : */
177 : : 11 : uint8_t can_socket_open(int *can_socket)
178 : : : {
179 : : 11 : uint8_t return_status = SUCCESS;
180 : : 11 : *can_socket = socket_create(PF_CAN, SOCK_RAW, CAN_RAW);
181 [ + + ]: [ T F ]: 11 : if (*can_socket < 0)
182 : : : {
183 : : 4 : perror("Socket Open Failed: ");
184 : : 4 : return_status = FAIL;
185 : : : }
186 : : 11 : return return_status;
187 : : : }
188 : : :
189 : : : /**
190 : : : * @brief Closes CAN socket - does not depend on VCAN interface.
191 : : : *
192 : : : * @param can_socket Pointer to store the number of socket.
193 : : : * @return SUCCESS(0), FAIL(1)
194 : : : * @requir{SwHLR_F_6}
195 : : : * @requir{SwHLR_F_10}
196 : : : * @requir{SwHLR_F_15}
197 : : : */
198 : : 3 : uint8_t can_socket_close(int *can_socket)
199 : : : {
200 : : 3 : uint8_t return_status = SUCCESS;
201 [ + + ]: [ T F ]: 3 : if (socket_close(*can_socket) < 0)
202 : : : {
203 : : 1 : perror("Socket Close Failed:");
204 : : 1 : return_status = FAIL;
205 : : : }
206 : : 3 : return return_status;
207 : : : }
208 : : :
209 : : : /**
210 : : : * @brief Function to verify if can interface is UP or DOWN.
211 : : : *
212 : : : * @param can_socket Pointer to store the number of socket.
213 : : : * @param interface Pointer to char interface
214 : : : * @return SUCCESS(0), FAIL(1)
215 : : : * @requir{SwHLR_F_6}
216 : : : * @requir{SwHLR_F_10}
217 : : : * @requir{SwHLR_F_15}
218 : : : */
219 : : 9 : uint8_t can_interface_status(int *can_socket, const char *interface)
220 : : : {
221 : : 9 : uint8_t return_status = SUCCESS;
222 : : : struct ifreq socket_info; // Initialize the struct ifreq to hold the interface information
223 : : 9 : (void)strncpy(socket_info.ifr_name, interface, IFNAMSIZ);
224 : : :
225 : : : // check if the interface exist getting the status using ioctl
226 [ + + ]: [ T F ]: 9 : if (can_ioctl(*can_socket, SIOCGIFFLAGS, &socket_info) < 0)
227 : : : {
228 : : 1 : perror("Error getting interface flags");
229 : : 1 : return_status = FAIL;
230 : : : }
231 : : :
232 : : : // Check if the interface is up - IFF_UP is a flag that indicate if interface is UP
233 [ + + ]: [ T F ]: 9 : if (socket_info.ifr_flags & IFF_UP)
234 : : : {
235 : : 6 : return_status = SUCCESS;
236 : : : }
237 : : : else
238 : : : {
239 : : 3 : return_status = FAIL;
240 : : : }
241 : : 9 : return return_status;
242 : : : }
243 : : :
244 : : : /**
245 : : : * @brief Armed with the interface index, we can now bind the socket to the CAN Interface:
246 : : : *
247 : : : * @param can_socket Pointer to store the number of socket.
248 : : : * @param interface Pointer to char interface
249 : : : * @return SUCCESS(0), FAIL(1)
250 : : : * @requir{SwHLR_F_6}
251 : : : * @requir{SwHLR_F_10}
252 : : : * @requir{SwHLR_F_15}
253 : : : */
254 : : 7 : uint8_t can_bind_socket(int *can_socket, const char *interface)
255 : : : {
256 : : 7 : uint8_t return_status = SUCCESS;
257 : : : struct ifreq ifr;
258 : : 7 : (void)strcpy(ifr.ifr_name, interface);
259 : : 7 : (void)can_ioctl(*can_socket, SIOCGIFINDEX, &ifr);
260 : : :
261 : : : struct sockaddr_can addr;
262 : : 7 : (void)memset(&addr, 0, sizeof(addr));
263 : : 7 : addr.can_family = AF_CAN;
264 : : 7 : addr.can_ifindex = ifr.ifr_ifindex;
265 [ + + ]: [ T F ]: 7 : if (can_bind(*can_socket, (struct sockaddr *)&addr, sizeof(addr)) < 0)
266 : : : {
267 : : 2 : perror("Bind");
268 : : 2 : return_status = FAIL;
269 : : : }
270 : : 7 : return return_status;
271 : : : }
272 : : :
273 : : : /**
274 : : : * @brief function to send frames on CAN BUS.
275 : : : *
276 : : : * @param can_socket Pointer to store the number of socket.
277 : : : * @param frame Pointer to frame that will be send to can.
278 : : : * @return SUCCESS(0), FAIL(1)
279 : : : * @requir{SwHLR_F_6}
280 : : : * @requir{SwHLR_F_10}
281 : : : * @requir{SwHLR_F_15}
282 : : : */
283 : : 52 : uint8_t can_send(int *can_socket, struct can_frame *frame)
284 : : : {
285 : : 52 : uint8_t return_status = SUCCESS;
286 [ + + ]: [ T F ]: 52 : if (can_write(can_socket, frame) == (int)FAIL)
287 : : : {
288 : : 22 : perror("Can Write error: ");
289 : : 22 : return_status = FAIL;
290 : : : }
291 : : 52 : return return_status;
292 : : : }
293 : : :
294 : : : /**
295 : : : * @brief function to read frames on CAN - this will block execution until a frame is received.
296 : : : *
297 : : : * @param can_socket Pointer to store the number of socket.
298 : : : * @param frame Pointer to frame that will be read from can.
299 : : : * @return SUCCESS(0), FAIL(1)
300 : : : * @requir{SwHLR_F_6}
301 : : : * @requir{SwHLR_F_10}
302 : : : * @requir{SwHLR_F_15}
303 : : : */
304 : : 27 : uint8_t can_read(int *can_socket, struct can_frame *frame)
305 : : : {
306 : : 27 : uint8_t return_status = SUCCESS;
307 : : : // this will block until frame avaliable
308 : : 27 : int nbytes = can_read_socket(*can_socket, frame, sizeof(struct can_frame));
309 [ + + ]: [ T F ]: 17 : if (nbytes < 0)
310 : : : {
311 : : 4 : perror("Can Read Error: ");
312 : : 4 : return_status = FAIL;
313 : : : }
314 : : 17 : return return_status;
315 : : : }
316 : : :
317 : : : /**
318 : : : * @brief function that open SOCKET CAN.
319 : : : *
320 : : : * @param my_vcan Pointer to store the number of socket.
321 : : : * @param interface Pointer to store the char interface.
322 : : : * @return SUCCESS(0), FAIL(1)
323 : : : * @requir{SwHLR_F_6}
324 : : : * @requir{SwHLR_F_10}
325 : : : * @requir{SwHLR_F_15}
326 : : : */
327 : : 9 : uint8_t can_start(int *my_vcan, const char *interface)
328 : : : {
329 : : 9 : uint8_t return_status = SUCCESS;
330 [ + + ]: [ T F ]: 9 : if (can_socket_open(my_vcan) == FAIL)
331 : : : {
332 : : 3 : perror("Can socket open Error: ");
333 : : 3 : return_status = FAIL;
334 : : : }
335 [ + + ]: [ T F ]: 6 : else if ((can_interface_status(my_vcan, interface) == FAIL))
336 : : : {
337 : : 1 : perror("Can interface Error: ");
338 : : 1 : return_status = FAIL;
339 : : : }
340 [ + + ]: [ T F ]: 5 : else if((can_bind_socket(my_vcan, interface) == FAIL))
341 : : : {
342 : : 1 : perror("Can bind Error: ");
343 : : 1 : return_status = FAIL;
344 : : : }
345 : : : else
346 : : : {
347 : : :
348 : : : }
349 : : 9 : return return_status;
350 : : : }
351 : : :
352 : : : /**
353 : : : * @brief function that send frame CAN to vcan0 of LINUX
354 : : : *
355 : : : * @param frame Pointer of frame can that will be send.
356 : : : * @return SUCCESS(0), FAIL(1)
357 : : : * @requir{SwHLR_F_6}
358 : : : * @requir{SwHLR_F_10}
359 : : : * @requir{SwHLR_F_15}
360 : : : */
361 : : 50 : uint8_t can_send_vcan0(struct can_frame *frame) { return can_send(&my_vcan, frame); }
362 : : :
363 : : : /**
364 : : : * @brief function that will read frame can coming from vcan0 of LINUX
365 : : : *
366 : : : * @param frame Pointer of frame can that will be send.
367 : : : * @return SUCCESS(0), FAIL(1)
368 : : : * @requir{SwHLR_F_6}
369 : : : * @requir{SwHLR_F_10}
370 : : : * @requir{SwHLR_F_15}
371 : : : */
372 : : 25 : uint8_t can_read_vcan0(struct can_frame *frame) { return can_read(&my_vcan, frame); }
373 : : :
374 : : : /**
375 : : : * @brief function that initialize Socket CAN Linux.
376 : : : *
377 : : : * @return SUCCESS(0), FAIL(1)
378 : : : * @requir{SwHLR_F_6}
379 : : : * @requir{SwHLR_F_10}
380 : : : * @requir{SwHLR_F_15}
381 : : : */
382 : : 5 : uint8_t can_init(void) { return can_start(&my_vcan, interface); }
383 : : :
384 : : : /**
385 : : : * @brief function that close Socket CAN Linux.
386 : : : *
387 : : : * @return SUCCESS(0), FAIL(1)
388 : : : * @requir{SwHLR_F_6}
389 : : : * @requir{SwHLR_F_10}
390 : : : * @requir{SwHLR_F_15}
391 : : : */
392 : : 1 : uint8_t can_close(void) { return can_socket_close(&my_vcan); }
393 : : :
394 : : : /**
395 : : : * @brief Show in terminal LOG Message.
396 : : : * @param errorStr Pointer to the charr array of message.
397 : : : * @requir{SwHLR_F_16}
398 : : : * @return SUCCESS(0), FAIL(1)
399 : : : */
400 : : 58 : void show_log(const char logStr[])
401 : : : {
402 : : :
403 : : 58 : (void)printf("%s\n", logStr);
404 : : :
405 : : 58 : }
406 : : :
407 : : :
408 : : 886251429 : void get_time(struct timespec *time)
409 : : : {
410 : : 886251429 : (void) clock_gettime(CLOCK_MONOTONIC, time);
411 : : 886251429 : }
|