Branch data MC/DC data Line data Source code
1 : : : /**
2 : : : * @file mq_utils.c
3 : : : * @brief Utilities for handling POSIX message queues.
4 : : : *
5 : : : * This file contains functions for creating, opening, closing,
6 : : : * reading, and writing POSIX message queues.
7 : : : */
8 : : :
9 : : : #include "mq_utils.h"
10 : : : #include "constants.h"
11 : : : #include <stdlib.h>
12 : : : #include <stdio.h>
13 : : : #include <string.h>
14 : : :
15 : : : #define QUEUE_PERMISSIONS 0660
16 : : :
17 : : : /**
18 : : : * @brief Gets the default attributes for a message queue.
19 : : : *
20 : : : * @return A mq_attr structure configured with default values.
21 : : : * \anchor get_mq_attr
22 : : : */
23 : : 13 : struct mq_attr get_mq_attr()
24 : : : {
25 : : : struct mq_attr attr;
26 : : 13 : attr.mq_flags = O_NONBLOCK;
27 : : 13 : attr.mq_curmsgs = 0;
28 : : 13 : attr.mq_maxmsg = MQ_MAX_MESSAGES;
29 : : 13 : attr.mq_msgsize = MQ_MAX_MSG_SIZE;
30 : : 13 : return attr;
31 : : : }
32 : : :
33 : : : /**
34 : : : * @brief Creates a POSIX message queue.
35 : : : *
36 : : : * @param mq_name Name of the message queue to be created.
37 : : : * @return Message queue identifier (mqd_t).
38 : : : * \anchor create_mq
39 : : : */
40 : : 8 : mqd_t create_mq(char *mq_name)
41 : : : {
42 : : 8 : struct mq_attr attr = get_mq_attr();
43 : : 8 : mqd_t mqd = mq_open(mq_name, O_RDWR | O_CREAT | O_NONBLOCK, QUEUE_PERMISSIONS, &attr);
44 [ + + ]: [ T F ]: 8 : if (mqd == (mqd_t)-1)
45 : : : {
46 : : 1 : perror("Error creating message queue");
47 : : 1 : return (mqd_t)-1;
48 : : : }
49 : : :
50 : : 7 : printf("Queue %s created\n", mq_name);
51 : : :
52 : : 7 : return mqd;
53 : : : }
54 : : :
55 : : : /**
56 : : : * @brief Opens a POSIX message queue.
57 : : : *
58 : : : * @param mq_name Name of the message queue to be opened.
59 : : : * @return Message queue identifier (mqd_t).
60 : : : * \anchor open_mq
61 : : : */
62 : : 4 : mqd_t open_mq(char *mq_name)
63 : : : {
64 : : 4 : struct mq_attr attr = get_mq_attr();
65 : : 4 : mqd_t mqd = mq_open(mq_name, O_RDWR | O_NONBLOCK, QUEUE_PERMISSIONS, &attr);
66 [ + - ]: [ T f ]: 4 : if (mqd == (mqd_t)-1)
67 : : : {
68 : : 4 : perror("Error opening message queue");
69 : : 4 : return (mqd_t)-1;
70 : : : }
71 : : 0 : return mqd;
72 : : : }
73 : : :
74 : : : /**
75 : : : * @brief Closes and unlinks the specified POSIX message queue.
76 : : : *
77 : : : * @param mqd Message queue identifier.
78 : : : * @param mq_name Name of the message queue to be closed.
79 : : : * @return void
80 : : : * \anchor close_mq
81 : : : */
82 : : 17 : void close_mq(mqd_t mqd, char *mq_name)
83 : : : {
84 : : 17 : printf("Closing %s message queue\n", mq_name);
85 [ + + ]: [ T F ]: 17 : if (mq_close(mqd) == -1)
86 : : : {
87 : : 10 : perror("Error closing message queue");
88 : : 10 : return;
89 : : : }
90 [ + + ]: [ T F ]: 7 : if (mq_unlink(mq_name) == -1)
91 : : : {
92 : : 2 : perror("Error unlinking message queue");
93 : : 2 : return;
94 : : : }
95 : : : }
96 : : :
97 : : : /**
98 : : : * @brief Reads a message from a POSIX message queue.
99 : : : *
100 : : : * @param mq_receiver Identifier of the message queue from which the message will be read.
101 : : : * @param msg_read Pointer to the structure where the read message will be stored, in can_msg struct type.
102 : : : * @return 0 on success, -1 on failure.
103 : : : * \anchor read_mq
104 : : : */
105 : : 3 : int read_mq(mqd_t mq_receiver, can_msg *msg_read)
106 : : : {
107 : : : char buffer[MQ_MAX_MSG_SIZE];
108 [ + - ]: [ T f ]: 3 : if (mq_receive(mq_receiver, buffer, MQ_MAX_MSG_SIZE, NULL) == (mqd_t)-1)
109 : : : {
110 : : : // perror("Error receiving message");
111 : : 3 : return -1;
112 : : : }
113 : : 0 : memcpy(msg_read, buffer, MQ_MAX_MSG_SIZE);
114 : : 0 : return 0;
115 : : : }
116 : : :
117 : : : /**
118 : : : * @brief Writes a message from a POSIX message queue.
119 : : : *
120 : : : * @param mq_receiver Identifier of the message queue from which the message will be read.
121 : : : * @param msg_read Pointer to the can_msg struct type used to write a message in the MQ POSIX format.
122 : : : * @return 0 on success, -1 on failure.
123 : : : * \anchor write_mq
124 : : : */
125 : : 13 : int write_mq(mqd_t mq_sender, can_msg *msg)
126 : : : {
127 : : : char buffer[MQ_MAX_MSG_SIZE];
128 : : 13 : memcpy(buffer, msg, MQ_MAX_MSG_SIZE);
129 [ + + ]: [ T F ]: 13 : if (mq_send(mq_sender, buffer, MQ_MAX_MSG_SIZE, 0) == -1)
130 : : : {
131 : : 3 : perror("Error sending message. Message queue is full");
132 : : 3 : return -1;
133 : : : }
134 : : 10 : return 0;
135 : : : }
|