1 /******************************************************************************
2 
3 			  L I B R M N E T C T L . H
4 
5 Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are
9 met:
10 	* Redistributions of source code must retain the above copyright
11 	  notice, this list of conditions and the following disclaimer.
12 	* Redistributions in binary form must reproduce the above
13 	  copyright notice, this list of conditions and the following
14 	  disclaimer in the documentation and/or other materials provided
15 	  with the distribution.
16 	* Neither the name of The Linux Foundation nor the names of its
17 	  contributors may be used to endorse or promote products derived
18 	  from this software without specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
21 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
23 ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
24 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
30 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 
32 ******************************************************************************/
33 
34 /*!
35 *  @file    librmnetctl.h
36 *  @brief   rmnet control API's header file
37 */
38 
39 #ifndef LIBRMNETCTL_H
40 #define LIBRMNETCTL_H
41 
42 /* RMNET API succeeded */
43 #define RMNETCTL_SUCCESS 0
44 /* RMNET API encountered an error while executing within the library. Check the
45 * error code in this case */
46 #define RMNETCTL_LIB_ERR 1
47 /* RMNET API encountered an error while executing in the kernel. Check the
48 * error code in this case */
49 #define RMNETCTL_KERNEL_ERR 2
50 /* RMNET API encountered an error because of invalid arguments*/
51 #define RMNETCTL_INVALID_ARG 3
52 
53 /* Flag to associate a network device*/
54 #define RMNETCTL_DEVICE_ASSOCIATE 1
55 /* Flag to unassociate a network device*/
56 #define RMNETCTL_DEVICE_UNASSOCIATE 0
57 /* Flag to create a new virtual network device*/
58 #define RMNETCTL_NEW_VND 1
59 /* Flag to free a new virtual network device*/
60 #define RMNETCTL_FREE_VND 0
61 /* Flag to add a new flow*/
62 #define RMNETCTL_ADD_FLOW 1
63 /* Flag to delete an existing flow*/
64 #define RMNETCTL_DEL_FLOW 0
65 
66 enum rmnetctl_error_codes_e {
67 	/* API succeeded. This should always be the first element. */
68 	RMNETCTL_API_SUCCESS,
69 	/* API failed because not enough memory to create buffer to send
70 	 * message */
71 	RMNETCTL_API_ERR_REQUEST_INVALID,
72 	/* API failed because not enough memory to create buffer for the
73 	 *  response message */
74 	RMNETCTL_API_ERR_RESPONSE_INVALID,
75 	/* API failed because could not send the message to kernel */
76 	RMNETCTL_API_ERR_MESSAGE_SEND,
77 	/* API failed because could not receive message from the kernel */
78 	RMNETCTL_API_ERR_MESSAGE_RECEIVE,
79 	/* Invalid process id. So return an error. */
80 	RMNETCTL_INIT_ERR_PROCESS_ID,
81 	/* Invalid socket descriptor id. So return an error. */
82 	RMNETCTL_INIT_ERR_NETLINK_FD,
83 	/* Could not bind the socket to the Netlink file descriptor */
84 	RMNETCTL_INIT_ERR_BIND,
85 	/* Invalid user id. Only root has access to this function. (NA) */
86 	RMNETCTL_INIT_ERR_INVALID_USER,
87 	/* API failed because the RmNet handle for the transaction was NULL */
88 	RMNETCTL_API_ERR_HNDL_INVALID,
89 	/* API failed because the request buffer for the transaction was NULL */
90 	RMNETCTL_API_ERR_REQUEST_NULL,
91 	/* API failed because the response buffer for the transaction was NULL*/
92 	RMNETCTL_API_ERR_RESPONSE_NULL,
93 	/* API failed because the request and response type do not match*/
94 	RMNETCTL_API_ERR_MESSAGE_TYPE,
95 	/* API failed because the return type is invalid */
96 	RMNETCTL_API_ERR_RETURN_TYPE,
97 	/* API failed because the string was truncated */
98 	RMNETCTL_API_ERR_STRING_TRUNCATION,
99 	/* This should always be the last element */
100 	RMNETCTL_API_ERR_ENUM_LENGTH
101 };
102 
103 #define RMNETCTL_ERR_MSG_SIZE 100
104 
105 /*!
106 * @brief Contains a list of error message from API
107 */
108 char rmnetctl_error_code_text
109 [RMNETCTL_API_ERR_ENUM_LENGTH][RMNETCTL_ERR_MSG_SIZE] = {
110 	"ERROR: API succeeded\n",
111 	"ERROR: Unable to allocate the buffer to send message\n",
112 	"ERROR: Unable to allocate the buffer to receive message\n",
113 	"ERROR: Could not send the message to kernel\n",
114 	"ERROR: Unable to receive message from the kernel\n",
115 	"ERROR: Invalid process id\n",
116 	"ERROR: Invalid socket descriptor id\n",
117 	"ERROR: Could not bind to netlink socket\n",
118 	"ERROR: Only root can access this API\n",
119 	"ERROR: RmNet handle for the transaction was NULL\n",
120 	"ERROR: Request buffer for the transaction was NULL\n",
121 	"ERROR: Response buffer for the transaction was NULL\n",
122 	"ERROR: Request and response type do not match\n",
123 	"ERROR: Return type is invalid\n",
124 	"ERROR: String was truncated\n"
125 };
126 
127 /*===========================================================================
128 			 DEFINITIONS AND DECLARATIONS
129 ===========================================================================*/
130 typedef struct rmnetctl_hndl_s rmnetctl_hndl_t;
131 
132 /*!
133 * @brief Public API to initialize the RMNET control driver
134 * @details Allocates memory for the RmNet handle. Creates and binds to a   and
135 * netlink socket if successful
136 * @param **rmnetctl_hndl_t_val RmNet handle to be initialized
137 * @return RMNETCTL_SUCCESS if successful
138 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
139 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
140 * Check error_code
141 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
142 */
143 int rmnetctl_init(rmnetctl_hndl_t **hndl, uint16_t *error_code);
144 
145 /*!
146 * @brief Public API to clean up the RmNeT control handle
147 * @details Close the socket and free the RmNet handle
148 * @param *rmnetctl_hndl_t_val RmNet handle to be initialized
149 * @return void
150 */
151 void rmnetctl_cleanup(rmnetctl_hndl_t *hndl);
152 
153 /*!
154 * @brief Public API to register/unregister a RMNET driver on a particular device
155 * @details Message type is RMNET_NETLINK_ASSOCIATE_NETWORK_DEVICE or
156 * RMNET_NETLINK_UNASSOCIATE_NETWORK_DEVICE based on the flag for assoc_dev
157 * @param *rmnetctl_hndl_t_val RmNet handle for the Netlink message
158 * @param dev_name Device on which to register the RmNet driver
159 * @param error_code Status code of this operation
160 * @param assoc_dev registers the device if RMNETCTL_DEVICE_ASSOCIATE or
161 * unregisters the device if RMNETCTL_DEVICE_UNASSOCIATE
162 * @return RMNETCTL_SUCCESS if successful
163 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
164 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
165 * Check error_code
166 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
167 */
168 int rmnet_associate_network_device(rmnetctl_hndl_t *hndl,
169 				   const char *dev_name,
170 				   uint16_t *error_code,
171 				   uint8_t assoc_dev);
172 
173 /*!
174 * @brief Public API to get if a RMNET driver is registered on a particular
175 * device
176 * @details Message type is RMNET_NETLINK_GET_NETWORK_DEVICE_ASSOCIATED.
177 * @param *rmnetctl_hndl_t_val RmNet handle for the Netlink message
178 * @param dev_name Device on which to check if the RmNet driver is registered
179 * @param register_status 1 if RmNet data driver is registered on a particular
180 * device, 0 if not
181 * @param error_code Status code of this operation
182 * @return RMNETCTL_SUCCESS if successful
183 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
184 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
185 * Check error_code
186 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
187 */
188 int rmnet_get_network_device_associated(rmnetctl_hndl_t *hndl,
189 					const char *dev_name,
190 					int *register_status,
191 					uint16_t *error_code);
192 
193 /*!
194 * @brief Public API to set the egress data format for a particular link.
195 * @details Message type is RMNET_NETLINK_SET_LINK_EGRESS_DATA_FORMAT.
196 * @param *rmnetctl_hndl_t_val RmNet handle for the Netlink message
197 * @param egress_flags Egress flags to be set on the device
198 * @param agg_size Max size of aggregated packets
199 * @param agg_count Number of packets to be aggregated
200 * @param dev_name Device on which to set the egress data format
201 * @param error_code Status code of this operation returned from the kernel
202 * @return RMNETCTL_SUCCESS if successful
203 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
204 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
205 * Check error_code
206 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
207 */
208 int rmnet_set_link_egress_data_format(rmnetctl_hndl_t *hndl,
209 				      uint32_t egress_flags,
210 				      uint16_t agg_size,
211 				      uint16_t agg_count,
212 				      const char *dev_name,
213 				      uint16_t *error_code);
214 
215 /*!
216 * @brief Public API to get the egress data format for a particular link.
217 * @details Message type is RMNET_NETLINK_GET_LINK_EGRESS_DATA_FORMAT.
218 * @param *rmnetctl_hndl_t_val RmNet handle for the Netlink message
219 * @param dev_name Device on which to get the egress data format
220 * @param egress_flags Egress flags from the device
221 * @param agg_count Number of packets to be aggregated
222 * @param error_code Status code of this operation returned from the kernel
223 * @return RMNETCTL_SUCCESS if successful
224 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
225 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
226 * Check error_code
227 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
228 */
229 int rmnet_get_link_egress_data_format(rmnetctl_hndl_t *hndl,
230 				      const char *dev_name,
231 				      uint32_t *egress_flags,
232 				      uint16_t *agg_size,
233 				      uint16_t *agg_count,
234 				      uint16_t *error_code);
235 
236 /*!
237 * @brief Public API to set the ingress data format for a particular link.
238 * @details Message type is RMNET_NETLINK_SET_LINK_INGRESS_DATA_FORMAT.
239 * @param *rmnetctl_hndl_t_val RmNet handle for the Netlink message
240 * @param ingress_flags Ingress flags from the device
241 * @param tail_spacing Tail spacing needed for the packet
242 * @param dev_name Device on which to set the ingress data format
243 * @param error_code Status code of this operation returned from the kernel
244 * @return RMNETCTL_SUCCESS if successful
245 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
246 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
247 * Check error_code
248 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
249 */
250 int rmnet_set_link_ingress_data_format_tailspace(rmnetctl_hndl_t *hndl,
251 						 uint32_t ingress_flags,
252 						 uint8_t  tail_spacing,
253 						 const char *dev_name,
254 						 uint16_t *error_code);
255 
256 /*!
257 * @brief Public API to get the ingress data format for a particular link.
258 * @details Message type is RMNET_NETLINK_GET_LINK_INGRESS_DATA_FORMAT.
259 * @param *rmnetctl_hndl_t_val RmNet handle for the Netlink message
260 * @param dev_name Device on which to get the ingress data format
261 * @param ingress_flags Ingress flags from the device
262 * @param tail_spacing Tail spacing needed for the packet
263 * @param error_code Status code of this operation returned from the kernel
264 * @return RMNETCTL_SUCCESS if successful
265 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
266 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
267 * Check error_code
268 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
269 */
270 int rmnet_get_link_ingress_data_format_tailspace(rmnetctl_hndl_t *hndl,
271 						const char *dev_name,
272 						uint32_t *ingress_flags,
273 						uint8_t  *tail_spacing,
274 						uint16_t *error_code);
275 
rmnet_set_link_ingress_data_format(rmnetctl_hndl_t * hndl,uint32_t ingress_flags,const char * dev_name,uint16_t * error_code)276 inline int rmnet_set_link_ingress_data_format(rmnetctl_hndl_t *hndl,
277 					      uint32_t ingress_flags,
278 					      const char *dev_name,
279 					      uint16_t *error_code)
280 {
281 	return rmnet_set_link_ingress_data_format_tailspace(hndl,
282 							    ingress_flags,
283 							    0,
284 							    dev_name,
285 							    error_code);
286 }
287 
rmnet_get_link_ingress_data_format(rmnetctl_hndl_t * hndl,const char * dev_name,uint32_t * ingress_flags,uint16_t * error_code)288 inline int rmnet_get_link_ingress_data_format(rmnetctl_hndl_t *hndl,
289 					      const char *dev_name,
290 					      uint32_t *ingress_flags,
291 					      uint16_t *error_code)
292 {
293 	return rmnet_get_link_ingress_data_format_tailspace(hndl,
294 							    dev_name,
295 							    ingress_flags,
296 							    0,
297 							    error_code);
298 }
299 
300 /*!
301 * @brief Public API to set the logical endpoint configuration for a
302 * particular link.
303 * @details Message type is RMNET_NETLINK_SET_LOGICAL_EP_CONFIG.
304 * @param *rmnetctl_hndl_t_val RmNet handle for the Netlink message
305 * @param logical_ep_id Logical end point id on which the configuration is to be
306 * set
307 * @param rmnet_mode RmNet mode to be set on the device
308 * @param dev_name Device on which to set the logical end point configuration
309 * @param egress_dev_name Egress Device if operating in bridge mode
310 * @param error_code Status code of this operation returned from the kernel
311 * @return RMNETCTL_SUCCESS if successful
312 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
313 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
314 * Check error_code
315 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
316 */
317 int rmnet_set_logical_ep_config(rmnetctl_hndl_t *hndl,
318 				int32_t ep_id,
319 				uint8_t operating_mode,
320 				const char *dev_name,
321 				const char *next_dev,
322 				uint16_t *error_code);
323 
324 /*!
325 * @brief Public API to un-set the logical endpoint configuration for a
326 * particular link.
327 * @details Message type is RMNET_NETLINK_UNSET_LOGICAL_EP_CONFIG.
328 * @param *rmnetctl_hndl_t_val RmNet handle for the Netlink message
329 * @param logical_ep_id Logical end point id on which the configuration is to be
330 * un-set
331 * @param dev_name Device on which to un-set the logical end point configuration
332 * @param error_code Status code of this operation returned from the kernel
333 * @return RMNETCTL_SUCCESS if successful
334 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
335 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
336 * Check error_code
337 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
338 */
339 int rmnet_unset_logical_ep_config(rmnetctl_hndl_t *hndl,
340 				  int32_t ep_id,
341 				  const char *dev_name,
342 				  uint16_t *error_code);
343 /*!
344 * @brief Public API to get the logical endpoint configuration for a
345 * particular link.
346 * @details Message type is RMNET_NETLINK_GET_LOGICAL_EP_CONFIG.
347 * @param *rmnetctl_hndl_t_val RmNet handle for the Netlink message
348 * @param logical_ep_id Logical end point id from which to get the configuration
349 * @param dev_name Device on which to get the logical end point configuration
350 * @param rmnet_mode RmNet mode from the device
351 * @param egress_dev_name Egress Device if operating in bridge mode
352 * @param error_code Status code of this operation returned from the kernel
353 * @return RMNETCTL_SUCCESS if successful
354 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
355 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
356 * Check error_code
357 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
358 */
359 int rmnet_get_logical_ep_config(rmnetctl_hndl_t *hndl,
360 				int32_t ep_id,
361 				const char *dev_name,
362 				uint8_t *operating_mode,
363 				char **next_dev,
364 				uint16_t *error_code);
365 
366 /*!
367 * @brief Public API to create a new virtual device node
368 * @details Message type is RMNET_NETLINK_NEW_VND or
369 * RMNETCTL_FREE_VND based on the flag for new_vnd
370 * @param hndl RmNet handle for the Netlink message
371 * @param id Node number to create the virtual network device node
372 * @param error_code Status code of this operation returned from the kernel
373 * @param new_vnd creates a new virtual network device if  RMNETCTL_NEW_VND or
374 * frees the device if RMNETCTL_FREE_VND
375 * @return RMNETCTL_SUCCESS if successful
376 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
377 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
378 * Check error_code
379 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
380 */
381 int rmnet_new_vnd(rmnetctl_hndl_t *hndl,
382 		  uint32_t id,
383 		  uint16_t *error_code,
384 		  uint8_t new_vnd);
385 
386 /*!
387  * @brief Public API to create a new virtual device node with a custom prefix
388  * @details Message type is RMNET_NETLINK_NEW_VND or
389  * RMNETCTL_FREE_VND based on the flag for new_vnd
390  * @param hndl RmNet handle for the Netlink message
391  * @param id Node number to create the virtual network device node
392  * @param error_code Status code of this operation returned from the kernel
393  * @param new_vnd creates a new virtual network device if  RMNETCTL_NEW_VND or
394  * frees the device if RMNETCTL_FREE_VND
395  * @param prefix Prefix to be used when naming the network interface
396  * @return RMNETCTL_SUCCESS if successful
397  * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
398  * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
399  * Check error_code
400  * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
401  */
402 int rmnet_new_vnd_prefix(rmnetctl_hndl_t *hndl,
403 			 uint32_t id,
404 			 uint16_t *error_code,
405 			 uint8_t new_vnd,
406 			 const char *prefix);
407 /*!
408  * @brief API to get the ASCII name of a virtual network device from its ID
409  * @param hndl RmNet handle for the Netlink message
410  * @param id Node number to create the virtual network device node
411  * @param error_code Status code of this operation returned from the kernel
412  * @param buf Buffer to store ASCII representation of device name
413  * @param buflen Length of the buffer
414  * @param prefix Prefix to be used when naming the network interface
415  * @return RMNETCTL_SUCCESS if successful
416  * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
417  * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
418  * Check error_code
419  * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
420  */
421 
422 int rmnet_get_vnd_name(rmnetctl_hndl_t *hndl,
423                       uint32_t id,
424                       uint16_t *error_code,
425                       char *buf,
426                       uint32_t buflen);
427 
428 /*!
429 * @brief Public API to set or clear a flow
430 * @details Message type is RMNET_NETLINK_ADD_VND_TC_FLOW or
431 * RMNET_NETLINK_DEL_VND_TC_FLOW based on the flag for set_flow
432 * @param *rmnetctl_hndl_t_val RmNet handle for the Netlink message
433 * @param id Node number to set or clear the flow on the virtual network
434 * device node
435 * @param map_flow_id Flow handle of the modem
436 * @param tc_flow_id Software flow handle
437 * @param set_flow sets the flow if  RMNET_NETLINK_SET_FLOW or
438 * clears the flow if RMNET_NETLINK_CLEAR_FLOW
439 * @return RMNETCTL_SUCCESS if successful
440 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
441 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
442 * Check error_code
443 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
444 */
445 int rmnet_add_del_vnd_tc_flow(rmnetctl_hndl_t *hndl,
446 			      uint32_t id,
447 			      uint32_t map_flow_id,
448 			      uint32_t tc_flow_id,
449 			      uint8_t set_flow,
450 			      uint16_t *error_code);
451 
452 #endif /* not defined LIBRMNETCTL_H */
453 
454