1 /*
2  * Copyright (c) 2023 Bjarki Arge Andreasen
3  * Copyright (c) 2023 Lucas Denefle
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 /**
9  * @file drivers/cellular.h
10  * @brief Public cellular network API
11  */
12 
13 #ifndef ZEPHYR_INCLUDE_DRIVERS_CELLULAR_H_
14 #define ZEPHYR_INCLUDE_DRIVERS_CELLULAR_H_
15 
16 /**
17  * @brief Cellular interface
18  * @defgroup cellular_interface Cellular Interface
19  * @ingroup io_interfaces
20  * @{
21  */
22 
23 #include <zephyr/types.h>
24 #include <zephyr/device.h>
25 #include <errno.h>
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 /** Cellular access technologies */
32 enum cellular_access_technology {
33 	CELLULAR_ACCESS_TECHNOLOGY_GSM = 0,
34 	CELLULAR_ACCESS_TECHNOLOGY_GPRS,
35 	CELLULAR_ACCESS_TECHNOLOGY_UMTS,
36 	CELLULAR_ACCESS_TECHNOLOGY_EDGE,
37 	CELLULAR_ACCESS_TECHNOLOGY_LTE,
38 	CELLULAR_ACCESS_TECHNOLOGY_LTE_CAT_M1,
39 	CELLULAR_ACCESS_TECHNOLOGY_LTE_CAT_M2,
40 	CELLULAR_ACCESS_TECHNOLOGY_NB_IOT,
41 };
42 
43 /** Cellular network structure */
44 struct cellular_network {
45 	/** Cellular access technology */
46 	enum cellular_access_technology technology;
47 	/**
48 	 * List of bands, as defined by the specified cellular access technology,
49 	 * to enables. All supported bands are enabled if none are provided.
50 	 */
51 	uint16_t *bands;
52 	/** Size of bands */
53 	uint16_t size;
54 };
55 
56 /** Cellular signal type */
57 enum cellular_signal_type {
58 	CELLULAR_SIGNAL_RSSI,
59 	CELLULAR_SIGNAL_RSRP,
60 	CELLULAR_SIGNAL_RSRQ,
61 };
62 
63 /** Cellular modem info type */
64 enum cellular_modem_info_type {
65 	/** International Mobile Equipment Identity */
66 	CELLULAR_MODEM_INFO_IMEI,
67 	/** Modem model ID */
68 	CELLULAR_MODEM_INFO_MODEL_ID,
69 	/** Modem manufacturer */
70 	CELLULAR_MODEM_INFO_MANUFACTURER,
71 	/** Modem fw version */
72 	CELLULAR_MODEM_INFO_FW_VERSION,
73 	/** International Mobile Subscriber Identity */
74 	CELLULAR_MODEM_INFO_SIM_IMSI,
75 	/** Integrated Circuit Card Identification Number (SIM) */
76 	CELLULAR_MODEM_INFO_SIM_ICCID,
77 };
78 
79 enum cellular_registration_status {
80 	CELLULAR_REGISTRATION_NOT_REGISTERED = 0,
81 	CELLULAR_REGISTRATION_REGISTERED_HOME,
82 	CELLULAR_REGISTRATION_SEARCHING,
83 	CELLULAR_REGISTRATION_DENIED,
84 	CELLULAR_REGISTRATION_UNKNOWN,
85 	CELLULAR_REGISTRATION_REGISTERED_ROAMING,
86 };
87 
88 /** API for configuring networks */
89 typedef int (*cellular_api_configure_networks)(const struct device *dev,
90 					       const struct cellular_network *networks,
91 					       uint8_t size);
92 
93 /** API for getting supported networks */
94 typedef int (*cellular_api_get_supported_networks)(const struct device *dev,
95 						   const struct cellular_network **networks,
96 						   uint8_t *size);
97 
98 /** API for getting network signal strength */
99 typedef int (*cellular_api_get_signal)(const struct device *dev,
100 				       const enum cellular_signal_type type, int16_t *value);
101 
102 /** API for getting modem information */
103 typedef int (*cellular_api_get_modem_info)(const struct device *dev,
104 					   const enum cellular_modem_info_type type,
105 					   char *info, size_t size);
106 
107 /** API for getting registration status */
108 typedef int (*cellular_api_get_registration_status)(const struct device *dev,
109 						    enum cellular_access_technology tech,
110 						    enum cellular_registration_status *status);
111 
112 /** Cellular driver API */
113 __subsystem struct cellular_driver_api {
114 	cellular_api_configure_networks configure_networks;
115 	cellular_api_get_supported_networks get_supported_networks;
116 	cellular_api_get_signal get_signal;
117 	cellular_api_get_modem_info get_modem_info;
118 	cellular_api_get_registration_status get_registration_status;
119 };
120 
121 /**
122  * @brief Configure cellular networks for the device
123  *
124  * @details Cellular network devices support at least one cellular access technology.
125  * Each cellular access technology defines a set of bands, of which the cellular device
126  * will support all or a subset of.
127  *
128  * The cellular device can only use one cellular network technology at a time. It must
129  * exclusively use the cellular network configurations provided, and will prioritize
130  * the cellular network configurations in the order they are provided in case there are
131  * multiple (the first cellular network configuration has the highest priority).
132  *
133  * @param dev Cellular network device instance.
134  * @param networks List of cellular network configurations to apply.
135  * @param size Size of list of cellular network configurations.
136  *
137  * @retval 0 if successful.
138  * @retval -EINVAL if any provided cellular network configuration is invalid or unsupported.
139  * @retval -ENOTSUP if API is not supported by cellular network device.
140  * @retval Negative errno-code otherwise.
141  */
cellular_configure_networks(const struct device * dev,const struct cellular_network * networks,uint8_t size)142 static inline int cellular_configure_networks(const struct device *dev,
143 					      const struct cellular_network *networks, uint8_t size)
144 {
145 	const struct cellular_driver_api *api = (const struct cellular_driver_api *)dev->api;
146 
147 	if (api->configure_networks == NULL) {
148 		return -ENOSYS;
149 	}
150 
151 	return api->configure_networks(dev, networks, size);
152 }
153 
154 /**
155  * @brief Get supported cellular networks for the device
156  *
157  * @param dev Cellular network device instance
158  * @param networks Pointer to list of supported cellular network configurations.
159  * @param size Size of list of cellular network configurations.
160  *
161  * @retval 0 if successful.
162  * @retval -ENOTSUP if API is not supported by cellular network device.
163  * @retval Negative errno-code otherwise.
164  */
cellular_get_supported_networks(const struct device * dev,const struct cellular_network ** networks,uint8_t * size)165 static inline int cellular_get_supported_networks(const struct device *dev,
166 						  const struct cellular_network **networks,
167 						  uint8_t *size)
168 {
169 	const struct cellular_driver_api *api = (const struct cellular_driver_api *)dev->api;
170 
171 	if (api->get_supported_networks == NULL) {
172 		return -ENOSYS;
173 	}
174 
175 	return api->get_supported_networks(dev, networks, size);
176 }
177 
178 /**
179  * @brief Get signal for the device
180  *
181  * @param dev Cellular network device instance
182  * @param type Type of the signal information requested
183  * @param value Signal strength destination (one of RSSI, RSRP, RSRQ)
184  *
185  * @retval 0 if successful.
186  * @retval -ENOTSUP if API is not supported by cellular network device.
187  * @retval -ENODATA if device is not in a state where signal can be polled
188  * @retval Negative errno-code otherwise.
189  */
cellular_get_signal(const struct device * dev,const enum cellular_signal_type type,int16_t * value)190 static inline int cellular_get_signal(const struct device *dev,
191 				      const enum cellular_signal_type type, int16_t *value)
192 {
193 	const struct cellular_driver_api *api = (const struct cellular_driver_api *)dev->api;
194 
195 	if (api->get_signal == NULL) {
196 		return -ENOSYS;
197 	}
198 
199 	return api->get_signal(dev, type, value);
200 }
201 
202 /**
203  * @brief Get modem info for the device
204  *
205  * @param dev Cellular network device instance
206  * @param type Type of the modem info requested
207  * @param info Info string destination
208  * @param size Info string size
209  *
210  * @retval 0 if successful.
211  * @retval -ENOTSUP if API is not supported by cellular network device.
212  * @retval -ENODATA if modem does not provide info requested
213  * @retval Negative errno-code from chat module otherwise.
214  */
cellular_get_modem_info(const struct device * dev,const enum cellular_modem_info_type type,char * info,size_t size)215 static inline int cellular_get_modem_info(const struct device *dev,
216 					  const enum cellular_modem_info_type type, char *info,
217 					  size_t size)
218 {
219 	const struct cellular_driver_api *api = (const struct cellular_driver_api *)dev->api;
220 
221 	if (api->get_modem_info == NULL) {
222 		return -ENOSYS;
223 	}
224 
225 	return api->get_modem_info(dev, type, info, size);
226 }
227 
228 /**
229  * @brief Get network registration status for the device
230  *
231  * @param dev Cellular network device instance
232  * @param tech Which access technology to get status for
233  * @param status Registration status for given access technology
234  *
235  * @retval 0 if successful.
236  * @retval -ENOSYS if API is not supported by cellular network device.
237  * @retval -ENODATA if modem does not provide info requested
238  * @retval Negative errno-code from chat module otherwise.
239  */
cellular_get_registration_status(const struct device * dev,enum cellular_access_technology tech,enum cellular_registration_status * status)240 static inline int cellular_get_registration_status(const struct device *dev,
241 						   enum cellular_access_technology tech,
242 						   enum cellular_registration_status *status)
243 {
244 	const struct cellular_driver_api *api = (const struct cellular_driver_api *)dev->api;
245 
246 	if (api->get_registration_status == NULL) {
247 		return -ENOSYS;
248 	}
249 
250 	return api->get_registration_status(dev, tech, status);
251 }
252 
253 #ifdef __cplusplus
254 }
255 #endif
256 
257 /**
258  * @}
259  */
260 
261 #endif /* ZEPHYR_INCLUDE_DRIVERS_CELLULAR_H_ */
262