aboutsummaryrefslogtreecommitdiffstats
path: root/man/psmq_receive.3
blob: f400b7d1551e9fca64cc8fa1bcb0c84d8a690cb9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
.TH "psmq_receive" "3" "19 May 2021 (v9999)" "bofc.pl"
.SH NAME
.PP
.BR psmq_receive ,\  psmq_timedreceive ,\  psmq_timedreceive_ms
- receive single message over
.BR psmq.
.SH SYNOPSIS
.PP
.BI "#include <psmq.h>"
.PP
.BI "int psmq_receive(struct psmq *" psmq ", struct psmq_msg *" msg ", \
unsigned *" prio ")"
.br
.BI "int psmq_timedreceive(struct psmq *" psmq ", struct psmq_msg *" msg ", \
unsigned *" prio ", struct timespec *" tp ")"
.br
.BI "int psmq_timedreceive_ms(struct psmq *" psmq ", struct psmq_msg *" msg ", \
unsigned *" prio ", size_t " ms ")"
.br
.BI char\ *\ PSMQ_TOPIC(struct\ psmq_msg\  psmq )
.br
.BI void\ *\ PSMQ_PAYLOAD(struct\ psmq_msg\  psmq )
.SH DESCRIPTION
.PP
Receive single control message or message that client has subscribed to.
Functions will block calling thread until message is received.
Message will be stored in user provided memory pointed by
.IR msg .
.PP
Message is stored in
.B struct psmq_msg
which definition is:
.nf
    struct psmq_msg {
        struct ctrl {
.RI "            char  " cmd ;
.RI "            unsigned char " data ;
.RI "        } " ctrl ;
.RI "        unsigned short " paylen ;
.RI "        char " data [PSMQ_MSG_MAX];
    }
.fi
.PP
.IR ctrl . cmd
defines type of received message.
This can be one of:
.TP
.B PSMQ_CTRL_CMD_PUBLISH
Received message on previously subscribed topics.
.TP
.B PSMQ_CTRL_CMD_SUBSCRIBE
Subscribe confirmation has been received.
.TP
.B PSMQ_CTRL_CMD_UNSUBSCRIBE
Unsubscribe confirmation has been received.
.TP
.B PSMQ_CTRL_CMD_CLOSE
Broker closed connection with the client.
.PP
.IR ctrl . data
is a response status of received message.
Or simply return code of a previous request.
0 is set when request was a success or
.B errno
when error occured.
For example, when
.BR psmq_subscribe (3)
has been sent, broker will reply with
.IR ctrl . cmd
set to
.B PSMQ_CTRL_CMD_SUBSCRIBE
and
.IR ctrl . data
set to 0 when subscribe has been successful or, for example
.B EBADMSG
when topic was not correct.
.PP
.I data
contains both topic and payload data.
Topic and payload can be extracted by using
.BR PSMQ_TOPIC ()
and
.BR PSMQ_PAYLOAD ()
macros and passing
.RB struct\  psmq_msg
as argument.
.BR PSMQ_TOPIC ()
will return valid c-string with topic, while
.BR PSMQ_PAYLOAD ()
will return pointer where payload starts.
Accessing pointer returned by
.BR PSMQ_PAYLOAD ()
is only valid when
.I paylen
is bigger than 0, otherwise you risk getting
.B SIGSEGV
from OS.
.PP
.I paylen
Length of payload part in
.IR data .
.PP
.BR psmq_timedreceive (3)
works same way as
.BR psmq_receive (3)
but will block only until timeout
.I tp
occurs.
Timeout is absolute time since Epoch when timeout should occur.
If this function is called when timeout already occured
.RI ( tp
happens to be behind current time) and message is not available in queue,
function will return immediately.
.PP
.BR psmq_timedreceive_ms (3)
works same way as
.BR psmq_timedreceive (3)
but accepts relative timeout in form of
.IR ms .
If message is not received in
.I ms
time from the moment function is called, then the function will return.
If
.I ms
is set to 0 and message is not on the queue, function will return immediately.
.SH "RETURN VALUE"
.PP
When message is received 0 is returned.
On error -1 with appropriate errno set is returned.
.SH ERRORS
.TP
.B EINVAL
.I psmq
or
.I msg
is
.BR NULL .
.TP
.B EBADF
Subscribe queue is invalid inside passed
.I psmq
object.
It is possible that
.I psmq
has not yet been initialized, or
.BR psmq_cleanup (3)
has been called on it earlier, or
.BR psmq_init (3)
failed.
.TP
.B EINTR
The call was interrupted by a signal handler.
.PP
.BR psmq_timedreceive (3)
and
.BR psmq_timedreceive_ms (3)
can also return:
.TP
.B ETIMEDOUT
The call timedout before a message could be transferred.
.SH EXAMPLE
.PP
Example shows how to initialize, subscribe and receive data from psmq.
Note: error checking has been ommited for clarity.
.PP
.nf
    #include <psmq.h>
    #include <stdio.h>

    int main(void)
    {
        struct psmq psmq;
        int rpm;
        int i;

        /* initialize psmq object that will create /sub mqueue for
         * receiving data, and will connect to broker of name /brok.
         * Max items in queue is set to 10 */
        psmq_init(&psmq, "/brok", "/sub", 10);

        /* subscribe to receive revolution per minute information */
        psmq_subscribe(&psmq, "/can/+/rpm");

        for (i = 0; i != 10; ++i) {
            /* now we are ready to receive data. In this example we
             * simply print received rpm */
            struct psmq_msg msg;
            psmq_receive(&psmq, &msg, NULL);
            memcpy(&rpm, PSMQ_PAYLOAD(msg), sizeof(rpm));
            printf("topic: %s; rpm %d\en", PSMQ_TOPIC(msg), rpm);
        }

        /* after work is finished, we need to deregister from broker to
         * make space in broker for another client */
        psmq_cleanup(&psmq);
        return 0;
    }
.fi
.SH "BUG REPORTING"
.PP
Please, report all bugs to "Michał Łyszczek <michal.lyszczek@bofc.pl>"
.SH "SEE ALSO"
.PP
.BR psmqd (1),
.BR psmq-pub (1),
.BR psmq-sub (1),
.BR psmq_cleanup (3),
.BR psmq_init (3),
.BR psmq_publish (3),
.BR psmq_receive (3),
.BR psmq_subscribe (3),
.BR psmq_timedreceive (3),
.BR psmq_timedreceive_ms (3),
.BR psmq_unsubscribe (3),
.BR psmq_building (7),
.BR psmq_overview (7).