NewMadeleine

Documentation

« back to PM2 home.
nm_minidriver_interface.h
Go to the documentation of this file.
1/*
2 * NewMadeleine
3 * Copyright (C) 2011-2026 (see AUTHORS file)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 */
15
21#ifndef NM_MINIDRIVER_INTERFACE_H
22#define NM_MINIDRIVER_INTERFACE_H
23
24#include <nm_minidriver.h>
25#include <nm_public.h>
26#include <nm_errno.h>
27#include <nm_parameters.h>
28
29#include <sys/uio.h>
30
31#define NM_MINIDRIVER_CHECK_RC(OP, RC) \
32 { \
33 if(((RC) != NM_ESUCCESS) && ((RC) != -NM_EAGAIN) && ((RC) != -NM_EINPROGRESS)) \
34 NM_FATAL("nm_minidriver: op %s returned rc = %d (%s)", (OP), rc, nm_strerror(rc)); \
35 }
36
37
38/* ** init/close ******************************************* */
39
40static inline void nm_minidriver_getprops(const struct nm_minidriver_iface_s*p_minidriver,
41 puk_context_t p_context, struct nm_minidriver_properties_s*p_props)
42{
44 (*p_minidriver->getprops)(p_context, p_props);
46}
47
48static inline void nm_minidriver_init(const struct nm_minidriver_iface_s*p_minidriver,
49 puk_context_t p_context, const void**drv_url, size_t*url_size)
50{
51 (*p_minidriver->init)(p_context, drv_url, url_size);
52}
53
54static inline void nm_minidriver_close(const struct nm_minidriver_iface_s*p_minidriver,
55 puk_context_t p_context)
56{
57 if(p_minidriver->close != NULL)
58 {
59 (*p_minidriver->close)(p_context);
60 }
61}
62
63
64/* ** connect ********************************************** */
65
66static inline void nm_minidriver_connect(struct puk_receptacle_NewMad_minidriver_s*r,
67 const void*remote_url, size_t url_size)
68{
69 assert(r->driver->connect_async != NULL);
70 (*r->driver->connect_async)(r->_status, remote_url, url_size);
71 if(r->driver->connect_wait != NULL)
72 {
73 (*r->driver->connect_wait)(r->_status);
74 }
75}
76
77static inline void nm_minidriver_disconnect(struct puk_receptacle_NewMad_minidriver_s*r)
78{
79 if(r->driver->disconnect != NULL)
80 {
81 (*r->driver->disconnect)(r->_status);
82 }
83}
84
85/* ** send ************************************************* */
86
89static inline void nm_minidriver_send_pkt_build(struct puk_receptacle_NewMad_minidriver_s*r,
90 const struct nm_minidriver_properties_s*p_props __attribute__((unused)),
91 struct nm_pkt_s*p_pkt,
92 const void*buf, size_t len)
93{
94 nm_pkt_init(p_pkt);
95 if(p_props->capabilities.supports_buf_send)
96 {
97 assert(r->driver->send_pkt_buf_get);
98 p_pkt->buf.p_buf = NULL;
99 p_pkt->buf.len = NM_LEN_UNDEFINED;
100 int rc = (*r->driver->send_pkt_buf_get)(r->_status, p_pkt);
101 NM_MINIDRIVER_CHECK_RC("send_buf_get", rc);
102 assert(p_pkt->buf.len != NM_LEN_UNDEFINED);
103 assert(p_pkt->buf.len >= len);
104 assert(p_pkt->buf.p_buf != NULL);
105 memcpy(p_pkt->buf.p_buf, buf, len);
106 p_pkt->buf.len = len;
107 }
108 else if(p_props->capabilities.supports_data)
109 {
110 p_pkt->data.p_data = padico_malloc(sizeof(struct nm_data_s));
111 p_pkt->data.chunk_len = len;
112 p_pkt->data.chunk_offset = 0;
113 nm_data_contiguous_build(p_pkt->data.p_data, (void*)buf, len);
115 }
116 else
117 {
118 p_pkt->iov.v = padico_malloc(sizeof(struct iovec));
119 p_pkt->iov.n = 1;
120 p_pkt->iov.v->iov_base = (void*)buf;
121 p_pkt->iov.v->iov_len = len;
122 }
123}
124
125static inline void nm_minidriver_isend(struct puk_receptacle_NewMad_minidriver_s*r,
126 const struct nm_minidriver_properties_s*p_props __attribute__((unused)),
127 struct nm_pkt_s*p_pkt)
128{
129 int rc = (*r->driver->send_pkt_post)(r->_status, p_pkt);
130 NM_MINIDRIVER_CHECK_RC("send_pkt_post", rc);
131}
132
133static inline int nm_minidriver_spoll(struct puk_receptacle_NewMad_minidriver_s*r,
134 const struct nm_minidriver_properties_s*p_props,
135 struct nm_pkt_s*p_pkt)
136{
137 int rc = (*r->driver->send_pkt_poll)(r->_status, p_pkt);
138 NM_MINIDRIVER_CHECK_RC("send_pkt_poll", rc);
139 if(rc == NM_ESUCCESS)
140 {
141 if(p_pkt->data.p_data != NULL)
142 {
143 padico_free(p_pkt->data.p_data);
144 p_pkt->data.p_data = NULL;
145 }
146 else if(p_pkt->iov.v != NULL)
147 {
148 padico_free(p_pkt->iov.v);
149 p_pkt->iov.v = NULL;
150 }
151 }
152 return rc;
153}
154
155static inline void nm_minidriver_send(struct puk_receptacle_NewMad_minidriver_s*r,
156 const struct nm_minidriver_properties_s*p_props,
157 const void*buf, size_t len)
158{
159 struct nm_pkt_s pkt;
160 nm_minidriver_send_pkt_build(r, p_props, &pkt, buf, len);
161 nm_minidriver_isend(r, p_props, &pkt);
162 int rc = -1;
163 do
164 {
165 rc = nm_minidriver_spoll(r, p_props, &pkt);
166 }
167 while(rc != NM_ESUCCESS);
168}
169
170
171/* ** receive ********************************************** */
172
175static inline void nm_minidriver_recv_pkt_build(struct puk_receptacle_NewMad_minidriver_s*r,
176 const struct nm_minidriver_properties_s*p_props __attribute__((unused)),
177 struct nm_pkt_s*p_pkt,
178 const void*buf, size_t len)
179{
180 nm_pkt_init(p_pkt);
181 p_pkt->iov.v = padico_malloc(sizeof(struct iovec));
182 p_pkt->iov.v->iov_base = (void*)buf;
183 p_pkt->iov.v->iov_len = len;
184 p_pkt->iov.n = 1;
185 p_pkt->buf.p_buf = NULL;
186 p_pkt->buf.len = NM_LEN_UNDEFINED;
187 if(p_props->capabilities.supports_data)
188 {
189 p_pkt->data.p_data = padico_malloc(sizeof(struct nm_data_s));
190 p_pkt->data.chunk_len = len;
191 p_pkt->data.chunk_offset = 0;
192 nm_data_contiguous_build(p_pkt->data.p_data, (void*)buf, len);
194 }
195}
196
197static inline void nm_minidriver_irecv(struct puk_receptacle_NewMad_minidriver_s*r,
198 const struct nm_minidriver_properties_s*p_props __attribute__((unused)),
199 struct nm_pkt_s*p_pkt)
200{
201 if(!p_props->capabilities.supports_buf_recv)
202 {
203 int rc = (*r->driver->recv_pkt_post)(r->_status, p_pkt);
204 NM_MINIDRIVER_CHECK_RC("recv_pkt_post", rc);
205 }
206}
207
208static inline int nm_minidriver_rpoll(struct puk_receptacle_NewMad_minidriver_s*r,
209 const struct nm_minidriver_properties_s*p_props __attribute__((unused)),
210 struct nm_pkt_s*p_pkt)
211{
212 int rc = (*r->driver->recv_pkt_poll)(r->_status, p_pkt);
213 NM_MINIDRIVER_CHECK_RC("recv_pkt_poll", rc);
214 if(rc == NM_ESUCCESS)
215 {
216 if(p_props->capabilities.supports_buf_recv)
217 {
218 assert(p_pkt->buf.len <= p_pkt->iov.v[0].iov_len);
219 memcpy(p_pkt->iov.v[0].iov_base, p_pkt->buf.p_buf, p_pkt->buf.len);
220 rc = (*r->driver->recv_pkt_buf_release)(r->_status, p_pkt);
221 NM_MINIDRIVER_CHECK_RC("recv_pkt_release", rc);
222 }
223 padico_free(p_pkt->iov.v);
224 }
225 return rc;
226}
227
228static inline void nm_minidriver_recv(struct puk_receptacle_NewMad_minidriver_s*r,
229 const struct nm_minidriver_properties_s*p_props,
230 void*buf, size_t len)
231{
232 struct nm_pkt_s pkt;
233 nm_minidriver_recv_pkt_build(r, p_props, &pkt, buf, len);
234 nm_minidriver_irecv(r, p_props, &pkt);
235 int rc = -1;
236 do
237 {
238 rc = nm_minidriver_rpoll(r, p_props, &pkt);
239 }
240 while(rc != NM_ESUCCESS);
241}
242
243/* ** receive any ****************************************** */
244
245static inline void nm_minidriver_recv_probe_any(const struct nm_minidriver_iface_s*p_minidriver,
246 puk_context_t p_context, void**_status)
247{
248 int rc = (*p_minidriver->recv_probe_any)(p_context, _status);
249 NM_MINIDRIVER_CHECK_RC("recv_probe_any", rc);
250}
251
252static inline int nm_minidriver_recv_cancel(struct puk_receptacle_NewMad_minidriver_s*r,
253 const struct nm_minidriver_properties_s*p_props __attribute__((unused)),
254 struct nm_pkt_s*p_pkt)
255{
256 if(r->driver->recv_pkt_cancel == NULL)
257 return -NM_ENOTIMPL;
258 else
259 return (*r->driver->recv_pkt_cancel)(r->_status, p_pkt);
260}
261
262/* ** rdv send/recv **************************************** */
263
264static inline void nm_minidriver_recv_rdv(struct puk_receptacle_NewMad_minidriver_s*r,
265 const struct nm_minidriver_properties_s*p_props __attribute__((unused)),
266 void*buf, size_t len,
267 struct puk_receptacle_NewMad_minidriver_s*rrdv,
268 const struct nm_minidriver_properties_s*p_props_rdv)
269{
270 struct nm_pkt_s pkt;
271 nm_minidriver_recv_pkt_build(r, p_props, &pkt, buf, len);
272 nm_minidriver_irecv(r, p_props, &pkt);
273 nm_len_t rdv_data_size = pkt.rdv_data.size;
274 nm_minidriver_send(rrdv, p_props_rdv, &rdv_data_size, sizeof(nm_len_t));
275 if(rdv_data_size > 0)
276 {
277 nm_minidriver_send(rrdv, p_props_rdv, pkt.rdv_data.p_content, pkt.rdv_data.size);
278 }
279 int rc = -1;
280 do
281 {
282 rc = nm_minidriver_rpoll(r, p_props, &pkt);
283 }
284 while(rc != NM_ESUCCESS);
285}
286
287static inline void nm_minidriver_send_rdv(struct puk_receptacle_NewMad_minidriver_s*r,
288 const struct nm_minidriver_properties_s*p_props,
289 const void*buf, size_t len,
290 struct puk_receptacle_NewMad_minidriver_s*rrdv,
291 const struct nm_minidriver_properties_s*p_props_rdv)
292{
293 struct nm_pkt_s pkt;
294 nm_minidriver_send_pkt_build(r, p_props, &pkt, buf, len);
295 nm_len_t rdv_data_size = -1;
296 nm_minidriver_recv(rrdv, p_props_rdv, &rdv_data_size, sizeof(nm_len_t));
297 if(rdv_data_size > 0)
298 {
299 pkt.rdv_data.p_content = padico_malloc(rdv_data_size);
300 nm_minidriver_recv(rrdv, p_props_rdv, pkt.rdv_data.p_content, rdv_data_size);
301 }
302 nm_minidriver_isend(r, p_props, &pkt);
303 int rc = -1;
304 do
305 {
306 rc = nm_minidriver_spoll(r, p_props, &pkt);
307 }
308 while(rc != NM_ESUCCESS);
309 padico_free(pkt.rdv_data.p_content);
310}
311
312
313#endif /* NM_MINIDRIVER_INTERFACE_H */
struct nm_core_event_s __attribute__
Definition nm_data.h:539
void nm_data_chunk_properties_compute(const struct nm_data_s *p_data, nm_len_t chunk_offset, nm_len_t chunk_len, struct nm_data_properties_s *p_props)
compute properties of the given chunk inside the data
@ NM_ENOTIMPL
not implemented
Definition nm_errno.h:38
@ NM_ESUCCESS
successful operation
Definition nm_errno.h:36
assert(p_data->ops.p_traversal !=NULL)
static void nm_data_contiguous_build(struct nm_data_s *p_data, void *ptr, nm_len_t len)
Definition nm_data.h:561
nm_len_t len
Definition nm_data.h:1007
This file contains error codes definitions.
Definition of the minidriver interface.
static void nm_pkt_init(struct nm_pkt_s *p_pkt)
static void nm_minidriver_properties_init(struct nm_minidriver_properties_s *p_props)
initialize all properties to 0
static void nm_minidriver_properties_normalize(struct nm_minidriver_properties_s *p_props)
ensure properties are in canonical form
static void nm_minidriver_recv(struct puk_receptacle_NewMad_minidriver_s *r, const struct nm_minidriver_properties_s *p_props, void *buf, size_t len)
static int nm_minidriver_recv_cancel(struct puk_receptacle_NewMad_minidriver_s *r, const struct nm_minidriver_properties_s *p_props __attribute__((unused)), struct nm_pkt_s *p_pkt)
static void nm_minidriver_close(const struct nm_minidriver_iface_s *p_minidriver, puk_context_t p_context)
static void nm_minidriver_send(struct puk_receptacle_NewMad_minidriver_s *r, const struct nm_minidriver_properties_s *p_props, const void *buf, size_t len)
static void nm_minidriver_irecv(struct puk_receptacle_NewMad_minidriver_s *r, const struct nm_minidriver_properties_s *p_props __attribute__((unused)), struct nm_pkt_s *p_pkt)
#define NM_MINIDRIVER_CHECK_RC(OP, RC)
static void nm_minidriver_init(const struct nm_minidriver_iface_s *p_minidriver, puk_context_t p_context, const void **drv_url, size_t *url_size)
static void nm_minidriver_recv_pkt_build(struct puk_receptacle_NewMad_minidriver_s *r, const struct nm_minidriver_properties_s *p_props __attribute__((unused)), struct nm_pkt_s *p_pkt, const void *buf, size_t len)
build a pkt suitable for receive on the given driver
static void nm_minidriver_send_rdv(struct puk_receptacle_NewMad_minidriver_s *r, const struct nm_minidriver_properties_s *p_props, const void *buf, size_t len, struct puk_receptacle_NewMad_minidriver_s *rrdv, const struct nm_minidriver_properties_s *p_props_rdv)
static void nm_minidriver_disconnect(struct puk_receptacle_NewMad_minidriver_s *r)
static void nm_minidriver_connect(struct puk_receptacle_NewMad_minidriver_s *r, const void *remote_url, size_t url_size)
static void nm_minidriver_send_pkt_build(struct puk_receptacle_NewMad_minidriver_s *r, const struct nm_minidriver_properties_s *p_props __attribute__((unused)), struct nm_pkt_s *p_pkt, const void *buf, size_t len)
build a pkt suitable for sending on the given driver
static void nm_minidriver_recv_probe_any(const struct nm_minidriver_iface_s *p_minidriver, puk_context_t p_context, void **_status)
static int nm_minidriver_rpoll(struct puk_receptacle_NewMad_minidriver_s *r, const struct nm_minidriver_properties_s *p_props __attribute__((unused)), struct nm_pkt_s *p_pkt)
static int nm_minidriver_spoll(struct puk_receptacle_NewMad_minidriver_s *r, const struct nm_minidriver_properties_s *p_props, struct nm_pkt_s *p_pkt)
static void nm_minidriver_recv_rdv(struct puk_receptacle_NewMad_minidriver_s *r, const struct nm_minidriver_properties_s *p_props __attribute__((unused)), void *buf, size_t len, struct puk_receptacle_NewMad_minidriver_s *rrdv, const struct nm_minidriver_properties_s *p_props_rdv)
static void nm_minidriver_isend(struct puk_receptacle_NewMad_minidriver_s *r, const struct nm_minidriver_properties_s *p_props __attribute__((unused)), struct nm_pkt_s *p_pkt)
static void nm_minidriver_getprops(const struct nm_minidriver_iface_s *p_minidriver, puk_context_t p_context, struct nm_minidriver_properties_s *p_props)
This is the common public header for NewMad.
#define NM_LEN_UNDEFINED
length is undefined
Definition nm_types.h:71
uint64_t nm_len_t
data length used by nmad
Definition nm_types.h:68
a data descriptor, used to pack/unpack data from app layout to/from contiguous buffers
Definition nm_data.h:200
Interface driver for the 'NewMad_minidriver' component interface.
void(* init)(puk_context_t context, const void **drv_url, size_t *url_size)
init the driver and get its url
void(* close)(puk_context_t context)
close the driver
int(* recv_probe_any)(puk_context_t p_context, void **_status) __attribute__((warn_unused_result))
poll the driver for a pending recv from any source; returns status of instance
void(* getprops)(puk_context_t context, struct nm_minidriver_properties_s *props)
get driver properties (profiling and capabilities)
a packet to submit to a driver
void * p_content
content of rdv_data; remains allocated until pkt completion
struct iovec * v
nm_len_t chunk_offset
struct nm_pkt_s::@27 iov
iovec data (with a single entry if supports_iovec == 0)
struct nm_data_properties_s chunk_props
pre-computed properties for the chunk of data
struct nm_pkt_s::@28 data
data iterator
struct nm_data_s * p_data
nm_len_t chunk_len
void * p_buf
nm_len_t size
nm_len_t len
struct nm_pkt_s::@29 rdv_data
rdv data, filled by receiver, read by sender, if needed
struct nm_pkt_s::@26 buf
buffer given by the driver