930d74d5059608c5ec480bd91a247e1a45e3ec8b
[ric-plt/lib/rmr.git] / src / common / src / mbuf_api.c
1 // : vi ts=4 sw=4 noet :
2 /*
3 ==================================================================================
4         Copyright (c) 2019 Nokia 
5         Copyright (c) 2018-2019 AT&T Intellectual Property.
6
7    Licensed under the Apache License, Version 2.0 (the "License");
8    you may not use this file except in compliance with the License.
9    You may obtain a copy of the License at
10
11        http://www.apache.org/licenses/LICENSE-2.0
12
13    Unless required by applicable law or agreed to in writing, software
14    distributed under the License is distributed on an "AS IS" BASIS,
15    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16    See the License for the specific language governing permissions and
17    limitations under the License.
18 ==================================================================================
19 */
20
21 /*
22         Mnemonic:       mbuf_api.c
23         Abstract:       These are common functions which work only on the mbuf and 
24                                 thus (because they do not touch an endpoint or context) 
25                                 can be agnostic to the underlying transport.
26
27         Author:         E. Scott Daniels
28         Date:           8 February 2019
29 */
30
31 #include <stdlib.h>
32 #include <netdb.h>                      // uint* types
33 #include <errno.h>
34 #include <string.h>
35 #include <unistd.h>
36
37 #include "rmr.h"                                // things the users see
38 #include "rmr_agnostic.h"               // agnostic things (must be included before private)
39
40
41 // ---------- some wrappers need explicit copy-in functions, also header field setters -----
42
43 /*
44         Allow the user programme to set the meid in the header.  The meid is a fixed 
45         length buffer in the header and thus we must ensure it is not overrun. If
46         the  user gives a source buffer that is too large, we truncate. The return
47         value is the number of bytes copied, or -1 for absolute failure (bad pointer
48         etc.).  Errno is set:
49                 EINVAL id poitner, buf or buf header are bad.
50                 EOVERFLOW if the bytes given would have overrun
51         
52 */
53 extern int rmr_bytes2meid( rmr_mbuf_t* mbuf, unsigned char const* src, int len ) {
54         uta_mhdr_t* hdr;
55
56         if( src == NULL  ||  mbuf == NULL || mbuf->header == NULL ) {
57                 errno = EINVAL;
58                 return -1;
59         }
60
61         errno = 0;
62         if( len > RMR_MAX_MEID ) {
63                 len = RMR_MAX_MEID;
64                 errno = EOVERFLOW;
65         }
66
67         hdr = (uta_mhdr_t *) mbuf->header;
68         memcpy( hdr->meid, src, len );
69
70         return len;
71 }
72
73 /*
74         Allows the user programme to set the meid from a string. The end of string
75         (nil) will be included UNLESS the total length including the end of string
76         would exceed the size of the space in the header for the meid.  The return
77         value is RMR_OK for success and !RMR_OK on failure. Errno will be set
78         on error.
79 */
80 extern int rmr_str2meid( rmr_mbuf_t* mbuf, unsigned char const* str ) {
81         int len;                // len moved -- we do validate
82
83         if( str == NULL  ||  mbuf == NULL || mbuf->header == NULL ) {
84                 errno = EINVAL;
85                 return RMR_ERR_BADARG;
86         }
87
88         errno = 0;
89         if( (len = strlen( (char *) str )) > RMR_MAX_MEID-1 ) {
90                 errno = EOVERFLOW;
91                 return RMR_ERR_OVERFLOW;
92         }
93         
94         rmr_bytes2meid( mbuf, str, len+1 );
95         return RMR_OK;
96 }
97
98
99
100 /*
101         This will copy n bytes from source into the payload. If len is larger than
102         the payload only the bytes which will fit are copied, The user should 
103         check errno on return to determine success or failure.
104 */
105 extern void rmr_bytes2payload( rmr_mbuf_t* mbuf, unsigned char const* src, int len ) {
106         if( src == NULL  ||  mbuf == NULL || mbuf->payload == NULL ) {
107                 errno = EINVAL;
108                 return;
109         }
110
111         errno = 0;
112         mbuf->state = RMR_OK;
113         if( len > mbuf->alloc_len - sizeof( uta_mhdr_t ) ) {
114                 mbuf->state = RMR_ERR_OVERFLOW;
115                 errno = EMSGSIZE;
116                 len = mbuf->alloc_len - sizeof( uta_mhdr_t );
117         }
118
119         mbuf->len = len;
120         memcpy( mbuf->payload, src, len );
121 }
122
123 /*
124         This will copy a nil terminated string to the mbuf payload. The buffer length
125         is set to the string length.
126 */
127 extern void rmr_str2payload( rmr_mbuf_t* mbuf, unsigned char const* str ) {
128         rmr_bytes2payload( mbuf, str, strlen( (char *) str ) + 1 );
129 }
130
131
132 /*
133         Allow the user programme to set the xaction field in the header.  The xaction
134         is a fixed length buffer in the header and thus we must ensure it is not overrun.
135         If the  user gives a source buffer that is too large, we truncate. The return
136         value is the number of bytes copied, or -1 for absolute failure (bad pointer
137         etc.).  Errno is set:
138                 EINVAL id poitner, buf or buf header are bad.
139                 EOVERFLOW if the bytes given would have overrun
140         
141 */
142 extern int rmr_bytes2xact( rmr_mbuf_t* mbuf, unsigned char const* src, int len ) {
143         uta_mhdr_t* hdr;
144
145         if( src == NULL  ||  mbuf == NULL || mbuf->header == NULL ) {
146                 errno = EINVAL;
147                 return -1;
148         }
149
150         errno = 0;
151         if( len > RMR_MAX_XID ) {
152                 len = RMR_MAX_XID;
153                 errno = EOVERFLOW;
154         }
155
156         hdr = (uta_mhdr_t *) mbuf->header;
157         memcpy( hdr->xid, src, len );
158
159         return len;
160 }
161
162
163
164 /*
165         Allows the user programme to set the xaction (xid) field from a string. The end
166         of string (nil) will be included UNLESS the total length including the end of string
167         would exceed the size of the space in the header for the xaction.  The return
168         value is RMR_OK for success and !RMR_OK on failure. Errno will be set
169         on error.
170 */
171 extern int rmr_str2xact( rmr_mbuf_t* mbuf, unsigned char const* str ) {
172         int len;                // len moved -- we do validate
173
174         if( str == NULL  ||  mbuf == NULL || mbuf->header == NULL ) {
175                 errno = EINVAL;
176                 return RMR_ERR_BADARG;
177         }
178
179         errno = 0;
180         if( (len = strlen( (char *) str )) > RMR_MAX_XID-1 ) {
181                 errno = EOVERFLOW;
182                 return RMR_ERR_OVERFLOW;
183         }
184         
185         rmr_bytes2xact( mbuf, str, len+1 );
186         return RMR_OK;
187 }
188
189 /*
190         Extracts the meid (managed equipment) from the header and copies the bytes
191         to the user supplied area. If the user supplied pointer is nil, then
192         a buffer will be allocated and it is the user's responsibilty to free.
193         A pointer is returned to the destination memory (allocated or not)
194         for consistency. If the user programme supplies a destination it is
195         the responsibility of the programme to ensure that the space is large
196         enough.
197 */
198 extern unsigned char*  rmr_get_meid( rmr_mbuf_t* mbuf, unsigned char* dest ) {
199         uta_mhdr_t* hdr;
200
201         if( mbuf == NULL || mbuf->header == NULL ) {
202                 errno = EINVAL;
203                 return NULL;
204         }
205
206         if( ! dest ) {
207                 if( (dest = (unsigned char *) malloc( sizeof( unsigned char ) * RMR_MAX_MEID )) == NULL ) {
208                         errno = ENOMEM;
209                         return NULL;
210                 }
211         }
212
213         hdr = (uta_mhdr_t *) mbuf->header;
214         memcpy( dest, hdr->meid, RMR_MAX_XID );
215
216         return dest;
217 }