1 /*
2  * Copyright (c) 2023 Bjarki Arge Andreasen
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/device.h>
9 #include <zephyr/drivers/gpio.h>
10 #include <zephyr/drivers/cellular.h>
11 #include <zephyr/drivers/uart.h>
12 #include <zephyr/modem/chat.h>
13 #include <zephyr/modem/cmux.h>
14 #include <zephyr/modem/pipe.h>
15 #include <zephyr/modem/pipelink.h>
16 #include <zephyr/modem/ppp.h>
17 #include <zephyr/modem/backend/uart.h>
18 #include <zephyr/net/ppp.h>
19 #include <zephyr/pm/device.h>
20 #include <zephyr/sys/atomic.h>
21 
22 #include <zephyr/logging/log.h>
23 LOG_MODULE_REGISTER(modem_cellular, CONFIG_MODEM_LOG_LEVEL);
24 
25 #include <string.h>
26 #include <stdlib.h>
27 
28 #define MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT \
29 	K_MSEC(CONFIG_MODEM_CELLULAR_PERIODIC_SCRIPT_MS)
30 
31 #define MODEM_CELLULAR_DATA_IMEI_LEN         (16)
32 #define MODEM_CELLULAR_DATA_MODEL_ID_LEN     (65)
33 #define MODEM_CELLULAR_DATA_IMSI_LEN         (23)
34 #define MODEM_CELLULAR_DATA_ICCID_LEN        (22)
35 #define MODEM_CELLULAR_DATA_MANUFACTURER_LEN (65)
36 #define MODEM_CELLULAR_DATA_FW_VERSION_LEN   (65)
37 
38 #define MODEM_CELLULAR_RESERVED_DLCIS        (2)
39 
40 /* Magic constants */
41 #define CSQ_RSSI_UNKNOWN		     (99)
42 #define CESQ_RSRP_UNKNOWN		     (255)
43 #define CESQ_RSRQ_UNKNOWN		     (255)
44 
45 /* Magic numbers to units conversions */
46 #define CSQ_RSSI_TO_DB(v) (-113 + (2 * (rssi)))
47 #define CESQ_RSRP_TO_DB(v) (-140 + (v))
48 #define CESQ_RSRQ_TO_DB(v) (-20 + ((v) / 2))
49 
50 enum modem_cellular_state {
51 	MODEM_CELLULAR_STATE_IDLE = 0,
52 	MODEM_CELLULAR_STATE_RESET_PULSE,
53 	MODEM_CELLULAR_STATE_POWER_ON_PULSE,
54 	MODEM_CELLULAR_STATE_AWAIT_POWER_ON,
55 	MODEM_CELLULAR_STATE_SET_BAUDRATE,
56 	MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT,
57 	MODEM_CELLULAR_STATE_CONNECT_CMUX,
58 	MODEM_CELLULAR_STATE_OPEN_DLCI1,
59 	MODEM_CELLULAR_STATE_OPEN_DLCI2,
60 	MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT,
61 	MODEM_CELLULAR_STATE_AWAIT_REGISTERED,
62 	MODEM_CELLULAR_STATE_CARRIER_ON,
63 	MODEM_CELLULAR_STATE_INIT_POWER_OFF,
64 	MODEM_CELLULAR_STATE_RUN_SHUTDOWN_SCRIPT,
65 	MODEM_CELLULAR_STATE_POWER_OFF_PULSE,
66 	MODEM_CELLULAR_STATE_AWAIT_POWER_OFF,
67 };
68 
69 enum modem_cellular_event {
70 	MODEM_CELLULAR_EVENT_RESUME = 0,
71 	MODEM_CELLULAR_EVENT_SUSPEND,
72 	MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS,
73 	MODEM_CELLULAR_EVENT_SCRIPT_FAILED,
74 	MODEM_CELLULAR_EVENT_CMUX_CONNECTED,
75 	MODEM_CELLULAR_EVENT_DLCI1_OPENED,
76 	MODEM_CELLULAR_EVENT_DLCI2_OPENED,
77 	MODEM_CELLULAR_EVENT_TIMEOUT,
78 	MODEM_CELLULAR_EVENT_REGISTERED,
79 	MODEM_CELLULAR_EVENT_DEREGISTERED,
80 	MODEM_CELLULAR_EVENT_BUS_OPENED,
81 	MODEM_CELLULAR_EVENT_BUS_CLOSED,
82 };
83 
84 struct modem_cellular_data {
85 	/* UART backend */
86 	struct modem_pipe *uart_pipe;
87 	struct modem_backend_uart uart_backend;
88 	uint8_t uart_backend_receive_buf[CONFIG_MODEM_CELLULAR_UART_BUFFER_SIZES];
89 	uint8_t uart_backend_transmit_buf[CONFIG_MODEM_CELLULAR_UART_BUFFER_SIZES];
90 
91 	/* CMUX */
92 	struct modem_cmux cmux;
93 	uint8_t cmux_receive_buf[CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE];
94 	uint8_t cmux_transmit_buf[2 * CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE];
95 
96 	struct modem_cmux_dlci dlci1;
97 	struct modem_cmux_dlci dlci2;
98 	struct modem_pipe *dlci1_pipe;
99 	struct modem_pipe *dlci2_pipe;
100 	/* Points to dlci2_pipe or NULL. Used for shutdown script if not NULL */
101 	struct modem_pipe *cmd_pipe;
102 	uint8_t dlci1_receive_buf[CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE];
103 	/* DLCI 2 is only used for chat scripts. */
104 	uint8_t dlci2_receive_buf[CONFIG_MODEM_CELLULAR_CHAT_BUFFER_SIZES];
105 
106 	/* Modem chat */
107 	struct modem_chat chat;
108 	uint8_t chat_receive_buf[CONFIG_MODEM_CELLULAR_CHAT_BUFFER_SIZES];
109 	uint8_t *chat_delimiter;
110 	uint8_t *chat_filter;
111 	uint8_t *chat_argv[32];
112 
113 	/* Status */
114 	enum cellular_registration_status registration_status_gsm;
115 	enum cellular_registration_status registration_status_gprs;
116 	enum cellular_registration_status registration_status_lte;
117 	uint8_t rssi;
118 	uint8_t rsrp;
119 	uint8_t rsrq;
120 	uint8_t imei[MODEM_CELLULAR_DATA_IMEI_LEN];
121 	uint8_t model_id[MODEM_CELLULAR_DATA_MODEL_ID_LEN];
122 	uint8_t imsi[MODEM_CELLULAR_DATA_IMSI_LEN];
123 	uint8_t iccid[MODEM_CELLULAR_DATA_ICCID_LEN];
124 	uint8_t manufacturer[MODEM_CELLULAR_DATA_MANUFACTURER_LEN];
125 	uint8_t fw_version[MODEM_CELLULAR_DATA_FW_VERSION_LEN];
126 
127 	/* PPP */
128 	struct modem_ppp *ppp;
129 
130 	enum modem_cellular_state state;
131 	const struct device *dev;
132 	struct k_work_delayable timeout_work;
133 
134 	/* Power management */
135 	struct k_sem suspended_sem;
136 
137 	/* Event dispatcher */
138 	struct k_work event_dispatch_work;
139 	uint8_t event_buf[8];
140 	struct ring_buf event_rb;
141 	struct k_mutex event_rb_lock;
142 };
143 
144 struct modem_cellular_user_pipe {
145 	struct modem_cmux_dlci dlci;
146 	uint8_t dlci_address;
147 	uint8_t *dlci_receive_buf;
148 	uint16_t dlci_receive_buf_size;
149 	struct modem_pipe *pipe;
150 	struct modem_pipelink *pipelink;
151 };
152 
153 struct modem_cellular_config {
154 	const struct device *uart;
155 	struct gpio_dt_spec power_gpio;
156 	struct gpio_dt_spec reset_gpio;
157 	uint16_t power_pulse_duration_ms;
158 	uint16_t reset_pulse_duration_ms;
159 	uint16_t startup_time_ms;
160 	uint16_t shutdown_time_ms;
161 	bool autostarts;
162 	const struct modem_chat_script *init_chat_script;
163 	const struct modem_chat_script *dial_chat_script;
164 	const struct modem_chat_script *periodic_chat_script;
165 	const struct modem_chat_script *shutdown_chat_script;
166 	const struct modem_chat_script *set_baudrate_chat_script;
167 	struct modem_cellular_user_pipe *user_pipes;
168 	uint8_t user_pipes_size;
169 };
170 
modem_cellular_state_str(enum modem_cellular_state state)171 static const char *modem_cellular_state_str(enum modem_cellular_state state)
172 {
173 	switch (state) {
174 	case MODEM_CELLULAR_STATE_IDLE:
175 		return "idle";
176 	case MODEM_CELLULAR_STATE_RESET_PULSE:
177 		return "reset pulse";
178 	case MODEM_CELLULAR_STATE_POWER_ON_PULSE:
179 		return "power pulse";
180 	case MODEM_CELLULAR_STATE_AWAIT_POWER_ON:
181 		return "await power on";
182 	case MODEM_CELLULAR_STATE_SET_BAUDRATE:
183 		return "set baudrate";
184 	case MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT:
185 		return "run init script";
186 	case MODEM_CELLULAR_STATE_CONNECT_CMUX:
187 		return "connect cmux";
188 	case MODEM_CELLULAR_STATE_OPEN_DLCI1:
189 		return "open dlci1";
190 	case MODEM_CELLULAR_STATE_OPEN_DLCI2:
191 		return "open dlci2";
192 	case MODEM_CELLULAR_STATE_AWAIT_REGISTERED:
193 		return "await registered";
194 	case MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT:
195 		return "run dial script";
196 	case MODEM_CELLULAR_STATE_CARRIER_ON:
197 		return "carrier on";
198 	case MODEM_CELLULAR_STATE_INIT_POWER_OFF:
199 		return "init power off";
200 	case MODEM_CELLULAR_STATE_RUN_SHUTDOWN_SCRIPT:
201 		return "run shutdown script";
202 	case MODEM_CELLULAR_STATE_POWER_OFF_PULSE:
203 		return "power off pulse";
204 	case MODEM_CELLULAR_STATE_AWAIT_POWER_OFF:
205 		return "await power off";
206 	}
207 
208 	return "";
209 }
210 
modem_cellular_event_str(enum modem_cellular_event event)211 static const char *modem_cellular_event_str(enum modem_cellular_event event)
212 {
213 	switch (event) {
214 	case MODEM_CELLULAR_EVENT_RESUME:
215 		return "resume";
216 	case MODEM_CELLULAR_EVENT_SUSPEND:
217 		return "suspend";
218 	case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS:
219 		return "script success";
220 	case MODEM_CELLULAR_EVENT_SCRIPT_FAILED:
221 		return "script failed";
222 	case MODEM_CELLULAR_EVENT_CMUX_CONNECTED:
223 		return "cmux connected";
224 	case MODEM_CELLULAR_EVENT_DLCI1_OPENED:
225 		return "dlci1 opened";
226 	case MODEM_CELLULAR_EVENT_DLCI2_OPENED:
227 		return "dlci2 opened";
228 	case MODEM_CELLULAR_EVENT_TIMEOUT:
229 		return "timeout";
230 	case MODEM_CELLULAR_EVENT_REGISTERED:
231 		return "registered";
232 	case MODEM_CELLULAR_EVENT_DEREGISTERED:
233 		return "deregistered";
234 	case MODEM_CELLULAR_EVENT_BUS_OPENED:
235 		return "bus opened";
236 	case MODEM_CELLULAR_EVENT_BUS_CLOSED:
237 		return "bus closed";
238 	}
239 
240 	return "";
241 }
242 
modem_cellular_gpio_is_enabled(const struct gpio_dt_spec * gpio)243 static bool modem_cellular_gpio_is_enabled(const struct gpio_dt_spec *gpio)
244 {
245 	return gpio->port != NULL;
246 }
247 
modem_cellular_notify_user_pipes_connected(struct modem_cellular_data * data)248 static void modem_cellular_notify_user_pipes_connected(struct modem_cellular_data *data)
249 {
250 	const struct modem_cellular_config *config =
251 		(const struct modem_cellular_config *)data->dev->config;
252 	struct modem_cellular_user_pipe *user_pipe;
253 	struct modem_pipelink *pipelink;
254 
255 	for (uint8_t i = 0; i < config->user_pipes_size; i++) {
256 		user_pipe = &config->user_pipes[i];
257 		pipelink = user_pipe->pipelink;
258 		modem_pipelink_notify_connected(pipelink);
259 	}
260 }
261 
modem_cellular_notify_user_pipes_disconnected(struct modem_cellular_data * data)262 static void modem_cellular_notify_user_pipes_disconnected(struct modem_cellular_data *data)
263 {
264 	const struct modem_cellular_config *config =
265 		(const struct modem_cellular_config *)data->dev->config;
266 	struct modem_cellular_user_pipe *user_pipe;
267 	struct modem_pipelink *pipelink;
268 
269 	for (uint8_t i = 0; i < config->user_pipes_size; i++) {
270 		user_pipe = &config->user_pipes[i];
271 		pipelink = user_pipe->pipelink;
272 		modem_pipelink_notify_disconnected(pipelink);
273 	}
274 }
275 
276 static void modem_cellular_enter_state(struct modem_cellular_data *data,
277 				       enum modem_cellular_state state);
278 
279 static void modem_cellular_delegate_event(struct modem_cellular_data *data,
280 					  enum modem_cellular_event evt);
281 
282 static void modem_cellular_event_handler(struct modem_cellular_data *data,
283 					 enum modem_cellular_event evt);
284 
modem_cellular_bus_pipe_handler(struct modem_pipe * pipe,enum modem_pipe_event event,void * user_data)285 static void modem_cellular_bus_pipe_handler(struct modem_pipe *pipe,
286 					    enum modem_pipe_event event,
287 					    void *user_data)
288 {
289 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
290 
291 	switch (event) {
292 	case MODEM_PIPE_EVENT_OPENED:
293 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_BUS_OPENED);
294 		break;
295 
296 	case MODEM_PIPE_EVENT_CLOSED:
297 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_BUS_CLOSED);
298 		break;
299 
300 	default:
301 		break;
302 	}
303 }
304 
modem_cellular_dlci1_pipe_handler(struct modem_pipe * pipe,enum modem_pipe_event event,void * user_data)305 static void modem_cellular_dlci1_pipe_handler(struct modem_pipe *pipe,
306 					      enum modem_pipe_event event,
307 					      void *user_data)
308 {
309 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
310 
311 	switch (event) {
312 	case MODEM_PIPE_EVENT_OPENED:
313 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_DLCI1_OPENED);
314 		break;
315 
316 	default:
317 		break;
318 	}
319 }
320 
modem_cellular_dlci2_pipe_handler(struct modem_pipe * pipe,enum modem_pipe_event event,void * user_data)321 static void modem_cellular_dlci2_pipe_handler(struct modem_pipe *pipe,
322 					      enum modem_pipe_event event,
323 					      void *user_data)
324 {
325 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
326 
327 	switch (event) {
328 	case MODEM_PIPE_EVENT_OPENED:
329 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_DLCI2_OPENED);
330 		break;
331 
332 	default:
333 		break;
334 	}
335 }
336 
modem_cellular_chat_callback_handler(struct modem_chat * chat,enum modem_chat_script_result result,void * user_data)337 static void modem_cellular_chat_callback_handler(struct modem_chat *chat,
338 						 enum modem_chat_script_result result,
339 						 void *user_data)
340 {
341 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
342 
343 	if (result == MODEM_CHAT_SCRIPT_RESULT_SUCCESS) {
344 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS);
345 	} else {
346 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_SCRIPT_FAILED);
347 	}
348 }
349 
modem_cellular_chat_on_imei(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)350 static void modem_cellular_chat_on_imei(struct modem_chat *chat, char **argv, uint16_t argc,
351 					void *user_data)
352 {
353 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
354 
355 	if (argc != 2) {
356 		return;
357 	}
358 
359 	strncpy(data->imei, argv[1], sizeof(data->imei) - 1);
360 }
361 
modem_cellular_chat_on_cgmm(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)362 static void modem_cellular_chat_on_cgmm(struct modem_chat *chat, char **argv, uint16_t argc,
363 					void *user_data)
364 {
365 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
366 
367 	if (argc != 2) {
368 		return;
369 	}
370 
371 	strncpy(data->model_id, argv[1], sizeof(data->model_id) - 1);
372 }
373 
modem_cellular_chat_on_cgmi(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)374 static void modem_cellular_chat_on_cgmi(struct modem_chat *chat, char **argv, uint16_t argc,
375 					void *user_data)
376 {
377 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
378 
379 	if (argc != 2) {
380 		return;
381 	}
382 
383 	strncpy(data->manufacturer, argv[1], sizeof(data->manufacturer) - 1);
384 }
385 
modem_cellular_chat_on_cgmr(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)386 static void modem_cellular_chat_on_cgmr(struct modem_chat *chat, char **argv, uint16_t argc,
387 					void *user_data)
388 {
389 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
390 
391 	if (argc != 2) {
392 		return;
393 	}
394 
395 	strncpy(data->fw_version, argv[1], sizeof(data->fw_version) - 1);
396 }
397 
modem_cellular_chat_on_csq(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)398 static void modem_cellular_chat_on_csq(struct modem_chat *chat, char **argv, uint16_t argc,
399 				       void *user_data)
400 {
401 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
402 
403 	if (argc != 3) {
404 		return;
405 	}
406 
407 	data->rssi = (uint8_t)atoi(argv[1]);
408 }
409 
modem_cellular_chat_on_cesq(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)410 static void modem_cellular_chat_on_cesq(struct modem_chat *chat, char **argv, uint16_t argc,
411 					void *user_data)
412 {
413 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
414 
415 	if (argc != 7) {
416 		return;
417 	}
418 
419 	data->rsrq = (uint8_t)atoi(argv[5]);
420 	data->rsrp = (uint8_t)atoi(argv[6]);
421 }
422 
modem_cellular_chat_on_iccid(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)423 static void modem_cellular_chat_on_iccid(struct modem_chat *chat, char **argv, uint16_t argc,
424 					void *user_data)
425 {
426 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
427 
428 	if (argc != 2) {
429 		return;
430 	}
431 
432 	strncpy(data->iccid, argv[1], sizeof(data->iccid) - 1);
433 }
434 
modem_cellular_chat_on_imsi(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)435 static void modem_cellular_chat_on_imsi(struct modem_chat *chat, char **argv, uint16_t argc,
436 					void *user_data)
437 {
438 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
439 
440 	if (argc != 2) {
441 		return;
442 	}
443 
444 	strncpy(data->imsi, argv[1], sizeof(data->imsi) - 1);
445 }
446 
modem_cellular_is_registered(struct modem_cellular_data * data)447 static bool modem_cellular_is_registered(struct modem_cellular_data *data)
448 {
449 	return (data->registration_status_gsm == CELLULAR_REGISTRATION_REGISTERED_HOME)
450 		|| (data->registration_status_gsm == CELLULAR_REGISTRATION_REGISTERED_ROAMING)
451 		|| (data->registration_status_gprs == CELLULAR_REGISTRATION_REGISTERED_HOME)
452 		|| (data->registration_status_gprs == CELLULAR_REGISTRATION_REGISTERED_ROAMING)
453 		|| (data->registration_status_lte == CELLULAR_REGISTRATION_REGISTERED_HOME)
454 		|| (data->registration_status_lte == CELLULAR_REGISTRATION_REGISTERED_ROAMING);
455 }
456 
modem_cellular_chat_on_cxreg(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)457 static void modem_cellular_chat_on_cxreg(struct modem_chat *chat, char **argv, uint16_t argc,
458 					void *user_data)
459 {
460 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
461 	enum cellular_registration_status registration_status = 0;
462 
463 	/* This receives both +C*REG? read command answers and unsolicited notifications.
464 	 * Their syntax differs in that the former has one more parameter, <n>, which is first.
465 	 */
466 	if (argc >= 3 && argv[2][0] != '"') {
467 		/* +CEREG: <n>,<stat>[,<tac>[...]] */
468 		registration_status = atoi(argv[2]);
469 	} else if (argc >= 2) {
470 		/* +CEREG: <stat>[,<tac>[...]] */
471 		registration_status = atoi(argv[1]);
472 	} else {
473 		return;
474 	}
475 
476 	if (strcmp(argv[0], "+CREG: ") == 0) {
477 		data->registration_status_gsm = registration_status;
478 	} else if (strcmp(argv[0], "+CGREG: ") == 0) {
479 		data->registration_status_gprs = registration_status;
480 	} else { /* CEREG */
481 		data->registration_status_lte = registration_status;
482 	}
483 
484 	if (modem_cellular_is_registered(data)) {
485 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_REGISTERED);
486 	} else {
487 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_DEREGISTERED);
488 	}
489 }
490 
491 MODEM_CHAT_MATCH_DEFINE(ok_match, "OK", "", NULL);
492 MODEM_CHAT_MATCHES_DEFINE(allow_match,
493 			  MODEM_CHAT_MATCH("OK", "", NULL),
494 			  MODEM_CHAT_MATCH("ERROR", "", NULL));
495 
496 MODEM_CHAT_MATCH_DEFINE(imei_match, "", "", modem_cellular_chat_on_imei);
497 MODEM_CHAT_MATCH_DEFINE(cgmm_match, "", "", modem_cellular_chat_on_cgmm);
498 MODEM_CHAT_MATCH_DEFINE(csq_match, "+CSQ: ", ",", modem_cellular_chat_on_csq);
499 MODEM_CHAT_MATCH_DEFINE(cesq_match, "+CESQ: ", ",", modem_cellular_chat_on_cesq);
500 MODEM_CHAT_MATCH_DEFINE(qccid_match __maybe_unused, "+QCCID: ", "", modem_cellular_chat_on_iccid);
501 MODEM_CHAT_MATCH_DEFINE(iccid_match __maybe_unused, "+ICCID: ", "", modem_cellular_chat_on_iccid);
502 MODEM_CHAT_MATCH_DEFINE(cimi_match __maybe_unused, "", "", modem_cellular_chat_on_imsi);
503 MODEM_CHAT_MATCH_DEFINE(cgmi_match __maybe_unused, "", "", modem_cellular_chat_on_cgmi);
504 MODEM_CHAT_MATCH_DEFINE(cgmr_match __maybe_unused, "", "", modem_cellular_chat_on_cgmr);
505 
506 MODEM_CHAT_MATCHES_DEFINE(unsol_matches,
507 			  MODEM_CHAT_MATCH("+CREG: ", ",", modem_cellular_chat_on_cxreg),
508 			  MODEM_CHAT_MATCH("+CEREG: ", ",", modem_cellular_chat_on_cxreg),
509 			  MODEM_CHAT_MATCH("+CGREG: ", ",", modem_cellular_chat_on_cxreg));
510 
511 MODEM_CHAT_MATCHES_DEFINE(abort_matches, MODEM_CHAT_MATCH("ERROR", "", NULL));
512 
513 MODEM_CHAT_MATCHES_DEFINE(dial_abort_matches,
514 			  MODEM_CHAT_MATCH("ERROR", "", NULL),
515 			  MODEM_CHAT_MATCH("BUSY", "", NULL),
516 			  MODEM_CHAT_MATCH("NO ANSWER", "", NULL),
517 			  MODEM_CHAT_MATCH("NO CARRIER", "", NULL),
518 			  MODEM_CHAT_MATCH("NO DIALTONE", "", NULL));
519 
520 #if DT_HAS_COMPAT_STATUS_OKAY(swir_hl7800) || DT_HAS_COMPAT_STATUS_OKAY(sqn_gm02s)
521 MODEM_CHAT_MATCH_DEFINE(connect_match, "CONNECT", "", NULL);
522 #endif
523 
modem_cellular_log_state_changed(enum modem_cellular_state last_state,enum modem_cellular_state new_state)524 static void modem_cellular_log_state_changed(enum modem_cellular_state last_state,
525 					     enum modem_cellular_state new_state)
526 {
527 	LOG_DBG("switch from %s to %s", modem_cellular_state_str(last_state),
528 		modem_cellular_state_str(new_state));
529 }
530 
modem_cellular_log_event(enum modem_cellular_event evt)531 static void modem_cellular_log_event(enum modem_cellular_event evt)
532 {
533 	LOG_DBG("event %s", modem_cellular_event_str(evt));
534 }
535 
modem_cellular_start_timer(struct modem_cellular_data * data,k_timeout_t timeout)536 static void modem_cellular_start_timer(struct modem_cellular_data *data, k_timeout_t timeout)
537 {
538 	k_work_schedule(&data->timeout_work, timeout);
539 }
540 
modem_cellular_stop_timer(struct modem_cellular_data * data)541 static void modem_cellular_stop_timer(struct modem_cellular_data *data)
542 {
543 	k_work_cancel_delayable(&data->timeout_work);
544 }
545 
modem_cellular_timeout_handler(struct k_work * item)546 static void modem_cellular_timeout_handler(struct k_work *item)
547 {
548 	struct k_work_delayable *dwork = k_work_delayable_from_work(item);
549 	struct modem_cellular_data *data =
550 		CONTAINER_OF(dwork, struct modem_cellular_data, timeout_work);
551 
552 	modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_TIMEOUT);
553 }
554 
modem_cellular_event_dispatch_handler(struct k_work * item)555 static void modem_cellular_event_dispatch_handler(struct k_work *item)
556 {
557 	struct modem_cellular_data *data =
558 		CONTAINER_OF(item, struct modem_cellular_data, event_dispatch_work);
559 
560 	uint8_t events[sizeof(data->event_buf)];
561 	uint8_t events_cnt;
562 
563 	k_mutex_lock(&data->event_rb_lock, K_FOREVER);
564 
565 	events_cnt = (uint8_t)ring_buf_get(&data->event_rb, events, sizeof(data->event_buf));
566 
567 	k_mutex_unlock(&data->event_rb_lock);
568 
569 	for (uint8_t i = 0; i < events_cnt; i++) {
570 		modem_cellular_event_handler(data, (enum modem_cellular_event)events[i]);
571 	}
572 }
573 
modem_cellular_delegate_event(struct modem_cellular_data * data,enum modem_cellular_event evt)574 static void modem_cellular_delegate_event(struct modem_cellular_data *data,
575 					  enum modem_cellular_event evt)
576 {
577 	k_mutex_lock(&data->event_rb_lock, K_FOREVER);
578 	ring_buf_put(&data->event_rb, (uint8_t *)&evt, 1);
579 	k_mutex_unlock(&data->event_rb_lock);
580 	k_work_submit(&data->event_dispatch_work);
581 }
582 
modem_cellular_begin_power_off_pulse(struct modem_cellular_data * data)583 static void modem_cellular_begin_power_off_pulse(struct modem_cellular_data *data)
584 {
585 	const struct modem_cellular_config *config =
586 		(const struct modem_cellular_config *)data->dev->config;
587 
588 	modem_pipe_close_async(data->uart_pipe);
589 
590 	if (modem_cellular_gpio_is_enabled(&config->power_gpio)) {
591 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_POWER_OFF_PULSE);
592 	} else {
593 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
594 	}
595 }
596 
modem_cellular_on_idle_state_enter(struct modem_cellular_data * data)597 static int modem_cellular_on_idle_state_enter(struct modem_cellular_data *data)
598 {
599 	const struct modem_cellular_config *config =
600 		(const struct modem_cellular_config *)data->dev->config;
601 
602 	if (modem_cellular_gpio_is_enabled(&config->reset_gpio)) {
603 		gpio_pin_set_dt(&config->reset_gpio, 1);
604 	}
605 
606 	modem_cellular_notify_user_pipes_disconnected(data);
607 	modem_chat_release(&data->chat);
608 	modem_ppp_release(data->ppp);
609 	modem_cmux_release(&data->cmux);
610 	modem_pipe_close_async(data->uart_pipe);
611 	k_sem_give(&data->suspended_sem);
612 	return 0;
613 }
614 
modem_cellular_idle_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)615 static void modem_cellular_idle_event_handler(struct modem_cellular_data *data,
616 					      enum modem_cellular_event evt)
617 {
618 	const struct modem_cellular_config *config =
619 		(const struct modem_cellular_config *)data->dev->config;
620 
621 	switch (evt) {
622 	case MODEM_CELLULAR_EVENT_RESUME:
623 		if (config->autostarts) {
624 			modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_POWER_ON);
625 			break;
626 		}
627 
628 		if (modem_cellular_gpio_is_enabled(&config->power_gpio)) {
629 			modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_POWER_ON_PULSE);
630 			break;
631 		}
632 
633 		if (modem_cellular_gpio_is_enabled(&config->reset_gpio)) {
634 			modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_POWER_ON);
635 			break;
636 		}
637 
638 		if (config->set_baudrate_chat_script != NULL) {
639 			modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_SET_BAUDRATE);
640 		} else {
641 			modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT);
642 		}
643 		break;
644 
645 	case MODEM_CELLULAR_EVENT_SUSPEND:
646 		k_sem_give(&data->suspended_sem);
647 		break;
648 
649 	default:
650 		break;
651 	}
652 }
653 
modem_cellular_on_idle_state_leave(struct modem_cellular_data * data)654 static int modem_cellular_on_idle_state_leave(struct modem_cellular_data *data)
655 {
656 	const struct modem_cellular_config *config =
657 		(const struct modem_cellular_config *)data->dev->config;
658 
659 	k_sem_take(&data->suspended_sem, K_NO_WAIT);
660 
661 	if (modem_cellular_gpio_is_enabled(&config->reset_gpio)) {
662 		gpio_pin_set_dt(&config->reset_gpio, 0);
663 	}
664 
665 	return 0;
666 }
667 
modem_cellular_on_reset_pulse_state_enter(struct modem_cellular_data * data)668 static int modem_cellular_on_reset_pulse_state_enter(struct modem_cellular_data *data)
669 {
670 	const struct modem_cellular_config *config =
671 		(const struct modem_cellular_config *)data->dev->config;
672 
673 	gpio_pin_set_dt(&config->reset_gpio, 1);
674 	modem_cellular_start_timer(data, K_MSEC(config->reset_pulse_duration_ms));
675 	return 0;
676 }
677 
modem_cellular_reset_pulse_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)678 static void modem_cellular_reset_pulse_event_handler(struct modem_cellular_data *data,
679 							enum modem_cellular_event evt)
680 {
681 	switch (evt) {
682 	case MODEM_CELLULAR_EVENT_TIMEOUT:
683 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_POWER_ON);
684 		break;
685 
686 	case MODEM_CELLULAR_EVENT_SUSPEND:
687 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
688 		break;
689 
690 	default:
691 		break;
692 	}
693 }
694 
modem_cellular_on_reset_pulse_state_leave(struct modem_cellular_data * data)695 static int modem_cellular_on_reset_pulse_state_leave(struct modem_cellular_data *data)
696 {
697 	const struct modem_cellular_config *config =
698 		(const struct modem_cellular_config *)data->dev->config;
699 
700 	gpio_pin_set_dt(&config->reset_gpio, 0);
701 	modem_cellular_stop_timer(data);
702 	return 0;
703 }
704 
modem_cellular_on_power_on_pulse_state_enter(struct modem_cellular_data * data)705 static int modem_cellular_on_power_on_pulse_state_enter(struct modem_cellular_data *data)
706 {
707 	const struct modem_cellular_config *config =
708 		(const struct modem_cellular_config *)data->dev->config;
709 
710 	gpio_pin_set_dt(&config->power_gpio, 1);
711 	modem_cellular_start_timer(data, K_MSEC(config->power_pulse_duration_ms));
712 	return 0;
713 }
714 
modem_cellular_power_on_pulse_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)715 static void modem_cellular_power_on_pulse_event_handler(struct modem_cellular_data *data,
716 							enum modem_cellular_event evt)
717 {
718 	switch (evt) {
719 	case MODEM_CELLULAR_EVENT_TIMEOUT:
720 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_POWER_ON);
721 		break;
722 
723 	case MODEM_CELLULAR_EVENT_SUSPEND:
724 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
725 		break;
726 
727 	default:
728 		break;
729 	}
730 }
731 
modem_cellular_on_power_on_pulse_state_leave(struct modem_cellular_data * data)732 static int modem_cellular_on_power_on_pulse_state_leave(struct modem_cellular_data *data)
733 {
734 	const struct modem_cellular_config *config =
735 		(const struct modem_cellular_config *)data->dev->config;
736 
737 	gpio_pin_set_dt(&config->power_gpio, 0);
738 	modem_cellular_stop_timer(data);
739 	return 0;
740 }
741 
modem_cellular_on_await_power_on_state_enter(struct modem_cellular_data * data)742 static int modem_cellular_on_await_power_on_state_enter(struct modem_cellular_data *data)
743 {
744 	const struct modem_cellular_config *config =
745 		(const struct modem_cellular_config *)data->dev->config;
746 
747 	modem_cellular_start_timer(data, K_MSEC(config->startup_time_ms));
748 	return 0;
749 }
750 
modem_cellular_await_power_on_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)751 static void modem_cellular_await_power_on_event_handler(struct modem_cellular_data *data,
752 							enum modem_cellular_event evt)
753 {
754 	const struct modem_cellular_config *config =
755 		(const struct modem_cellular_config *)data->dev->config;
756 
757 	switch (evt) {
758 	case MODEM_CELLULAR_EVENT_TIMEOUT:
759 		if (config->set_baudrate_chat_script != NULL) {
760 			modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_SET_BAUDRATE);
761 		} else {
762 			modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT);
763 		}
764 		break;
765 
766 	case MODEM_CELLULAR_EVENT_SUSPEND:
767 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
768 		break;
769 
770 	default:
771 		break;
772 	}
773 }
774 
modem_cellular_on_set_baudrate_state_enter(struct modem_cellular_data * data)775 static int modem_cellular_on_set_baudrate_state_enter(struct modem_cellular_data *data)
776 {
777 	modem_pipe_attach(data->uart_pipe, modem_cellular_bus_pipe_handler, data);
778 	return modem_pipe_open_async(data->uart_pipe);
779 }
780 
modem_cellular_set_baudrate_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)781 static void modem_cellular_set_baudrate_event_handler(struct modem_cellular_data *data,
782 						      enum modem_cellular_event evt)
783 {
784 	const struct modem_cellular_config *config =
785 		(const struct modem_cellular_config *)data->dev->config;
786 	struct uart_config cfg = {0};
787 	int ret;
788 
789 	switch (evt) {
790 	case MODEM_CELLULAR_EVENT_BUS_OPENED:
791 		modem_chat_attach(&data->chat, data->uart_pipe);
792 		modem_chat_run_script_async(&data->chat, config->set_baudrate_chat_script);
793 		break;
794 
795 	case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS:
796 		/* Let modem reconfigure */
797 		modem_cellular_start_timer(data, K_MSEC(CONFIG_MODEM_CELLULAR_NEW_BAUDRATE_DELAY));
798 		break;
799 	case MODEM_CELLULAR_EVENT_SCRIPT_FAILED:
800 		/* Some modems save the new speed on first change, meaning the
801 		 * modem is already at the new baudrate, meaning no reply. So
802 		 * ignore any failures and continue as if baudrate is already set
803 		 */
804 		LOG_DBG("no reply from modem, assuming baudrate is already set");
805 		__fallthrough;
806 	case MODEM_CELLULAR_EVENT_TIMEOUT:
807 		modem_chat_release(&data->chat);
808 		modem_pipe_attach(data->uart_pipe, modem_cellular_bus_pipe_handler, data);
809 		modem_pipe_close_async(data->uart_pipe);
810 
811 		ret = uart_config_get(config->uart, &cfg);
812 		if (ret < 0) {
813 			LOG_ERR("Failed to get UART configuration (%d)", ret);
814 			break;
815 		}
816 		cfg.baudrate = CONFIG_MODEM_CELLULAR_NEW_BAUDRATE;
817 		ret = uart_configure(config->uart, &cfg);
818 		if (ret < 0) {
819 			LOG_ERR("Failed to set new baudrate (%d)", ret);
820 			break;
821 		}
822 		break;
823 
824 	case MODEM_CELLULAR_EVENT_BUS_CLOSED:
825 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT);
826 		break;
827 
828 	case MODEM_CELLULAR_EVENT_SUSPEND:
829 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
830 		break;
831 
832 	default:
833 		break;
834 	}
835 }
836 
modem_cellular_on_run_init_script_state_enter(struct modem_cellular_data * data)837 static int modem_cellular_on_run_init_script_state_enter(struct modem_cellular_data *data)
838 {
839 	modem_pipe_attach(data->uart_pipe, modem_cellular_bus_pipe_handler, data);
840 	return modem_pipe_open_async(data->uart_pipe);
841 }
842 
modem_cellular_run_init_script_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)843 static void modem_cellular_run_init_script_event_handler(struct modem_cellular_data *data,
844 							 enum modem_cellular_event evt)
845 {
846 	const struct modem_cellular_config *config =
847 		(const struct modem_cellular_config *)data->dev->config;
848 
849 	switch (evt) {
850 	case MODEM_CELLULAR_EVENT_BUS_OPENED:
851 		modem_chat_attach(&data->chat, data->uart_pipe);
852 		modem_chat_run_script_async(&data->chat, config->init_chat_script);
853 		break;
854 
855 	case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS:
856 		net_if_set_link_addr(modem_ppp_get_iface(data->ppp), data->imei,
857 				     ARRAY_SIZE(data->imei), NET_LINK_UNKNOWN);
858 
859 		modem_chat_release(&data->chat);
860 		modem_pipe_attach(data->uart_pipe, modem_cellular_bus_pipe_handler, data);
861 		modem_pipe_close_async(data->uart_pipe);
862 		break;
863 
864 	case MODEM_CELLULAR_EVENT_BUS_CLOSED:
865 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_CONNECT_CMUX);
866 		break;
867 
868 	case MODEM_CELLULAR_EVENT_SUSPEND:
869 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
870 		break;
871 
872 	case MODEM_CELLULAR_EVENT_SCRIPT_FAILED:
873 		if (modem_cellular_gpio_is_enabled(&config->power_gpio)) {
874 			modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_POWER_ON_PULSE);
875 			break;
876 		}
877 
878 		if (modem_cellular_gpio_is_enabled(&config->reset_gpio)) {
879 			modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_RESET_PULSE);
880 			break;
881 		}
882 
883 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
884 		break;
885 
886 	default:
887 		break;
888 	}
889 }
890 
modem_cellular_on_connect_cmux_state_enter(struct modem_cellular_data * data)891 static int modem_cellular_on_connect_cmux_state_enter(struct modem_cellular_data *data)
892 {
893 	/*
894 	 * Allow modem to switch bus into CMUX mode. Some modems disable UART RX while
895 	 * switching, resulting in UART RX errors as bus is no longer pulled up by modem.
896 	 */
897 	modem_cellular_start_timer(data, K_MSEC(100));
898 	return 0;
899 }
900 
modem_cellular_connect_cmux_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)901 static void modem_cellular_connect_cmux_event_handler(struct modem_cellular_data *data,
902 						      enum modem_cellular_event evt)
903 {
904 	switch (evt) {
905 	case MODEM_CELLULAR_EVENT_TIMEOUT:
906 		modem_pipe_attach(data->uart_pipe, modem_cellular_bus_pipe_handler, data);
907 		modem_pipe_open_async(data->uart_pipe);
908 		break;
909 
910 	case MODEM_CELLULAR_EVENT_BUS_OPENED:
911 		modem_cmux_attach(&data->cmux, data->uart_pipe);
912 		modem_cmux_connect_async(&data->cmux);
913 		break;
914 
915 	case MODEM_CELLULAR_EVENT_CMUX_CONNECTED:
916 		modem_cellular_notify_user_pipes_connected(data);
917 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_OPEN_DLCI1);
918 		break;
919 
920 	case MODEM_CELLULAR_EVENT_SUSPEND:
921 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_INIT_POWER_OFF);
922 		break;
923 
924 	default:
925 		break;
926 	}
927 }
928 
modem_cellular_on_open_dlci1_state_enter(struct modem_cellular_data * data)929 static int modem_cellular_on_open_dlci1_state_enter(struct modem_cellular_data *data)
930 {
931 	modem_pipe_attach(data->dlci1_pipe, modem_cellular_dlci1_pipe_handler, data);
932 	return modem_pipe_open_async(data->dlci1_pipe);
933 }
934 
modem_cellular_open_dlci1_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)935 static void modem_cellular_open_dlci1_event_handler(struct modem_cellular_data *data,
936 						    enum modem_cellular_event evt)
937 {
938 	switch (evt) {
939 	case MODEM_CELLULAR_EVENT_DLCI1_OPENED:
940 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_OPEN_DLCI2);
941 		break;
942 
943 	case MODEM_CELLULAR_EVENT_SUSPEND:
944 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_INIT_POWER_OFF);
945 		break;
946 
947 	default:
948 		break;
949 	}
950 }
951 
modem_cellular_on_open_dlci1_state_leave(struct modem_cellular_data * data)952 static int modem_cellular_on_open_dlci1_state_leave(struct modem_cellular_data *data)
953 {
954 	modem_pipe_release(data->dlci1_pipe);
955 	return 0;
956 }
957 
modem_cellular_on_open_dlci2_state_enter(struct modem_cellular_data * data)958 static int modem_cellular_on_open_dlci2_state_enter(struct modem_cellular_data *data)
959 {
960 	modem_pipe_attach(data->dlci2_pipe, modem_cellular_dlci2_pipe_handler, data);
961 	return modem_pipe_open_async(data->dlci2_pipe);
962 }
963 
modem_cellular_open_dlci2_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)964 static void modem_cellular_open_dlci2_event_handler(struct modem_cellular_data *data,
965 						    enum modem_cellular_event evt)
966 {
967 	switch (evt) {
968 	case MODEM_CELLULAR_EVENT_DLCI2_OPENED:
969 		data->cmd_pipe = data->dlci2_pipe;
970 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT);
971 		break;
972 
973 	case MODEM_CELLULAR_EVENT_SUSPEND:
974 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_INIT_POWER_OFF);
975 		break;
976 
977 	default:
978 		break;
979 	}
980 }
981 
modem_cellular_on_open_dlci2_state_leave(struct modem_cellular_data * data)982 static int modem_cellular_on_open_dlci2_state_leave(struct modem_cellular_data *data)
983 {
984 	modem_pipe_release(data->dlci2_pipe);
985 	return 0;
986 }
987 
modem_cellular_on_run_dial_script_state_enter(struct modem_cellular_data * data)988 static int modem_cellular_on_run_dial_script_state_enter(struct modem_cellular_data *data)
989 {
990 	/* Allow modem time to enter command mode before running dial script */
991 	modem_cellular_start_timer(data, K_MSEC(100));
992 	return 0;
993 }
994 
modem_cellular_run_dial_script_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)995 static void modem_cellular_run_dial_script_event_handler(struct modem_cellular_data *data,
996 							 enum modem_cellular_event evt)
997 {
998 	const struct modem_cellular_config *config =
999 		(const struct modem_cellular_config *)data->dev->config;
1000 
1001 	switch (evt) {
1002 	case MODEM_CELLULAR_EVENT_TIMEOUT:
1003 		modem_chat_attach(&data->chat, data->dlci1_pipe);
1004 		modem_chat_run_script_async(&data->chat, config->dial_chat_script);
1005 		break;
1006 
1007 	case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS:
1008 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_REGISTERED);
1009 		break;
1010 
1011 	case MODEM_CELLULAR_EVENT_SUSPEND:
1012 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_INIT_POWER_OFF);
1013 		break;
1014 
1015 	default:
1016 		break;
1017 	}
1018 }
1019 
modem_cellular_on_run_dial_script_state_leave(struct modem_cellular_data * data)1020 static int modem_cellular_on_run_dial_script_state_leave(struct modem_cellular_data *data)
1021 {
1022 	modem_chat_release(&data->chat);
1023 	return 0;
1024 }
1025 
modem_cellular_on_await_registered_state_enter(struct modem_cellular_data * data)1026 static int modem_cellular_on_await_registered_state_enter(struct modem_cellular_data *data)
1027 {
1028 	if (modem_ppp_attach(data->ppp, data->dlci1_pipe) < 0) {
1029 		return -EAGAIN;
1030 	}
1031 
1032 	modem_cellular_start_timer(data, MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT);
1033 	return modem_chat_attach(&data->chat, data->dlci2_pipe);
1034 }
1035 
modem_cellular_await_registered_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)1036 static void modem_cellular_await_registered_event_handler(struct modem_cellular_data *data,
1037 						  enum modem_cellular_event evt)
1038 {
1039 	const struct modem_cellular_config *config =
1040 		(const struct modem_cellular_config *)data->dev->config;
1041 
1042 	switch (evt) {
1043 	case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS:
1044 	case MODEM_CELLULAR_EVENT_SCRIPT_FAILED:
1045 		modem_cellular_start_timer(data, MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT);
1046 		break;
1047 
1048 	case MODEM_CELLULAR_EVENT_TIMEOUT:
1049 		modem_chat_run_script_async(&data->chat, config->periodic_chat_script);
1050 		break;
1051 
1052 	case MODEM_CELLULAR_EVENT_REGISTERED:
1053 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_CARRIER_ON);
1054 		break;
1055 
1056 	case MODEM_CELLULAR_EVENT_SUSPEND:
1057 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_INIT_POWER_OFF);
1058 		break;
1059 
1060 	default:
1061 		break;
1062 	}
1063 }
1064 
modem_cellular_on_await_registered_state_leave(struct modem_cellular_data * data)1065 static int modem_cellular_on_await_registered_state_leave(struct modem_cellular_data *data)
1066 {
1067 	modem_cellular_stop_timer(data);
1068 	return 0;
1069 }
1070 
modem_cellular_on_carrier_on_state_enter(struct modem_cellular_data * data)1071 static int modem_cellular_on_carrier_on_state_enter(struct modem_cellular_data *data)
1072 {
1073 	net_if_carrier_on(modem_ppp_get_iface(data->ppp));
1074 	modem_cellular_start_timer(data, MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT);
1075 	return 0;
1076 }
1077 
modem_cellular_carrier_on_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)1078 static void modem_cellular_carrier_on_event_handler(struct modem_cellular_data *data,
1079 						    enum modem_cellular_event evt)
1080 {
1081 	const struct modem_cellular_config *config =
1082 		(const struct modem_cellular_config *)data->dev->config;
1083 
1084 	switch (evt) {
1085 	case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS:
1086 	case MODEM_CELLULAR_EVENT_SCRIPT_FAILED:
1087 		modem_cellular_start_timer(data, MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT);
1088 		break;
1089 
1090 	case MODEM_CELLULAR_EVENT_TIMEOUT:
1091 		modem_chat_run_script_async(&data->chat, config->periodic_chat_script);
1092 		break;
1093 
1094 	case MODEM_CELLULAR_EVENT_DEREGISTERED:
1095 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT);
1096 		break;
1097 
1098 	case MODEM_CELLULAR_EVENT_SUSPEND:
1099 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_INIT_POWER_OFF);
1100 		break;
1101 
1102 	default:
1103 		break;
1104 	}
1105 }
1106 
modem_cellular_on_carrier_on_state_leave(struct modem_cellular_data * data)1107 static int modem_cellular_on_carrier_on_state_leave(struct modem_cellular_data *data)
1108 {
1109 	modem_cellular_stop_timer(data);
1110 	net_if_carrier_off(modem_ppp_get_iface(data->ppp));
1111 	modem_chat_release(&data->chat);
1112 	modem_ppp_release(data->ppp);
1113 	return 0;
1114 }
1115 
modem_cellular_on_init_power_off_state_enter(struct modem_cellular_data * data)1116 static int modem_cellular_on_init_power_off_state_enter(struct modem_cellular_data *data)
1117 {
1118 	modem_cellular_start_timer(data, K_MSEC(2000));
1119 	return 0;
1120 }
1121 
modem_cellular_init_power_off_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)1122 static void modem_cellular_init_power_off_event_handler(struct modem_cellular_data *data,
1123 							enum modem_cellular_event evt)
1124 {
1125 	const struct modem_cellular_config *config =
1126 		(const struct modem_cellular_config *)data->dev->config;
1127 
1128 	switch (evt) {
1129 	case MODEM_CELLULAR_EVENT_TIMEOUT:
1130 		/* Shutdown script can only be used if cmd_pipe is available, i.e. we are not in
1131 		 * some intermediary state without a pipe for commands available
1132 		 */
1133 		if (config->shutdown_chat_script != NULL && data->cmd_pipe != NULL) {
1134 			modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_RUN_SHUTDOWN_SCRIPT);
1135 			break;
1136 		}
1137 
1138 		modem_cellular_begin_power_off_pulse(data);
1139 		break;
1140 
1141 	default:
1142 		break;
1143 	}
1144 }
1145 
modem_cellular_on_init_power_off_state_leave(struct modem_cellular_data * data)1146 static int modem_cellular_on_init_power_off_state_leave(struct modem_cellular_data *data)
1147 {
1148 	modem_cellular_notify_user_pipes_disconnected(data);
1149 	modem_chat_release(&data->chat);
1150 	modem_ppp_release(data->ppp);
1151 	return 0;
1152 }
1153 
modem_cellular_on_run_shutdown_script_state_enter(struct modem_cellular_data * data)1154 static int modem_cellular_on_run_shutdown_script_state_enter(struct modem_cellular_data *data)
1155 {
1156 	const struct modem_cellular_config *config =
1157 		(const struct modem_cellular_config *)data->dev->config;
1158 
1159 	modem_chat_attach(&data->chat, data->cmd_pipe);
1160 	return modem_chat_run_script_async(&data->chat, config->shutdown_chat_script);
1161 }
1162 
modem_cellular_run_shutdown_script_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)1163 static void modem_cellular_run_shutdown_script_event_handler(struct modem_cellular_data *data,
1164 							     enum modem_cellular_event evt)
1165 {
1166 	switch (evt) {
1167 	case MODEM_CELLULAR_EVENT_SCRIPT_FAILED:
1168 		data->cmd_pipe = NULL;
1169 
1170 		/* If shutdown by software failed, try by power pulse if possible */
1171 		modem_cellular_begin_power_off_pulse(data);
1172 
1173 		break;
1174 
1175 	case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS:
1176 		modem_pipe_close_async(data->uart_pipe);
1177 		data->cmd_pipe = NULL;
1178 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
1179 		break;
1180 
1181 	default:
1182 		break;
1183 	}
1184 }
1185 
modem_cellular_on_run_shutdown_script_state_leave(struct modem_cellular_data * data)1186 static int modem_cellular_on_run_shutdown_script_state_leave(struct modem_cellular_data *data)
1187 {
1188 	modem_chat_release(&data->chat);
1189 	return 0;
1190 }
1191 
modem_cellular_on_power_off_pulse_state_enter(struct modem_cellular_data * data)1192 static int modem_cellular_on_power_off_pulse_state_enter(struct modem_cellular_data *data)
1193 {
1194 	const struct modem_cellular_config *config =
1195 		(const struct modem_cellular_config *)data->dev->config;
1196 
1197 	data->cmd_pipe = NULL;
1198 	gpio_pin_set_dt(&config->power_gpio, 1);
1199 	modem_cellular_start_timer(data, K_MSEC(config->power_pulse_duration_ms));
1200 	return 0;
1201 }
1202 
modem_cellular_power_off_pulse_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)1203 static void modem_cellular_power_off_pulse_event_handler(struct modem_cellular_data *data,
1204 							enum modem_cellular_event evt)
1205 {
1206 	switch (evt) {
1207 	case MODEM_CELLULAR_EVENT_TIMEOUT:
1208 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_POWER_OFF);
1209 		break;
1210 
1211 	default:
1212 		break;
1213 	}
1214 }
1215 
modem_cellular_on_power_off_pulse_state_leave(struct modem_cellular_data * data)1216 static int modem_cellular_on_power_off_pulse_state_leave(struct modem_cellular_data *data)
1217 {
1218 	const struct modem_cellular_config *config =
1219 		(const struct modem_cellular_config *)data->dev->config;
1220 
1221 	gpio_pin_set_dt(&config->power_gpio, 0);
1222 	modem_cellular_stop_timer(data);
1223 	return 0;
1224 }
1225 
modem_cellular_on_await_power_off_state_enter(struct modem_cellular_data * data)1226 static int modem_cellular_on_await_power_off_state_enter(struct modem_cellular_data *data)
1227 {
1228 	const struct modem_cellular_config *config =
1229 		(const struct modem_cellular_config *)data->dev->config;
1230 
1231 	modem_cellular_start_timer(data, K_MSEC(config->shutdown_time_ms));
1232 	return 0;
1233 }
1234 
modem_cellular_await_power_off_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)1235 static void modem_cellular_await_power_off_event_handler(struct modem_cellular_data *data,
1236 							enum modem_cellular_event evt)
1237 {
1238 	switch (evt) {
1239 	case MODEM_CELLULAR_EVENT_TIMEOUT:
1240 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
1241 		break;
1242 
1243 	default:
1244 		break;
1245 	}
1246 }
1247 
modem_cellular_on_state_enter(struct modem_cellular_data * data)1248 static int modem_cellular_on_state_enter(struct modem_cellular_data *data)
1249 {
1250 	int ret;
1251 
1252 	switch (data->state) {
1253 	case MODEM_CELLULAR_STATE_IDLE:
1254 		ret = modem_cellular_on_idle_state_enter(data);
1255 		break;
1256 
1257 	case MODEM_CELLULAR_STATE_RESET_PULSE:
1258 		ret = modem_cellular_on_reset_pulse_state_enter(data);
1259 		break;
1260 
1261 	case MODEM_CELLULAR_STATE_POWER_ON_PULSE:
1262 		ret = modem_cellular_on_power_on_pulse_state_enter(data);
1263 		break;
1264 
1265 	case MODEM_CELLULAR_STATE_AWAIT_POWER_ON:
1266 		ret = modem_cellular_on_await_power_on_state_enter(data);
1267 		break;
1268 
1269 	case MODEM_CELLULAR_STATE_SET_BAUDRATE:
1270 		ret = modem_cellular_on_set_baudrate_state_enter(data);
1271 		break;
1272 
1273 	case MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT:
1274 		ret = modem_cellular_on_run_init_script_state_enter(data);
1275 		break;
1276 
1277 	case MODEM_CELLULAR_STATE_CONNECT_CMUX:
1278 		ret = modem_cellular_on_connect_cmux_state_enter(data);
1279 		break;
1280 
1281 	case MODEM_CELLULAR_STATE_OPEN_DLCI1:
1282 		ret = modem_cellular_on_open_dlci1_state_enter(data);
1283 		break;
1284 
1285 	case MODEM_CELLULAR_STATE_OPEN_DLCI2:
1286 		ret = modem_cellular_on_open_dlci2_state_enter(data);
1287 		break;
1288 
1289 	case MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT:
1290 		ret = modem_cellular_on_run_dial_script_state_enter(data);
1291 		break;
1292 
1293 	case MODEM_CELLULAR_STATE_AWAIT_REGISTERED:
1294 		ret = modem_cellular_on_await_registered_state_enter(data);
1295 		break;
1296 
1297 	case MODEM_CELLULAR_STATE_CARRIER_ON:
1298 		ret = modem_cellular_on_carrier_on_state_enter(data);
1299 		break;
1300 
1301 	case MODEM_CELLULAR_STATE_INIT_POWER_OFF:
1302 		ret = modem_cellular_on_init_power_off_state_enter(data);
1303 		break;
1304 
1305 	case MODEM_CELLULAR_STATE_RUN_SHUTDOWN_SCRIPT:
1306 		ret = modem_cellular_on_run_shutdown_script_state_enter(data);
1307 		break;
1308 
1309 	case MODEM_CELLULAR_STATE_POWER_OFF_PULSE:
1310 		ret = modem_cellular_on_power_off_pulse_state_enter(data);
1311 		break;
1312 
1313 	case MODEM_CELLULAR_STATE_AWAIT_POWER_OFF:
1314 		ret = modem_cellular_on_await_power_off_state_enter(data);
1315 		break;
1316 
1317 	default:
1318 		ret = 0;
1319 		break;
1320 	}
1321 
1322 	return ret;
1323 }
1324 
modem_cellular_on_state_leave(struct modem_cellular_data * data)1325 static int modem_cellular_on_state_leave(struct modem_cellular_data *data)
1326 {
1327 	int ret;
1328 
1329 	switch (data->state) {
1330 	case MODEM_CELLULAR_STATE_IDLE:
1331 		ret = modem_cellular_on_idle_state_leave(data);
1332 		break;
1333 
1334 	case MODEM_CELLULAR_STATE_RESET_PULSE:
1335 		ret = modem_cellular_on_reset_pulse_state_leave(data);
1336 		break;
1337 
1338 	case MODEM_CELLULAR_STATE_POWER_ON_PULSE:
1339 		ret = modem_cellular_on_power_on_pulse_state_leave(data);
1340 		break;
1341 
1342 	case MODEM_CELLULAR_STATE_OPEN_DLCI1:
1343 		ret = modem_cellular_on_open_dlci1_state_leave(data);
1344 		break;
1345 
1346 	case MODEM_CELLULAR_STATE_OPEN_DLCI2:
1347 		ret = modem_cellular_on_open_dlci2_state_leave(data);
1348 		break;
1349 
1350 	case MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT:
1351 		ret = modem_cellular_on_run_dial_script_state_leave(data);
1352 		break;
1353 
1354 	case MODEM_CELLULAR_STATE_AWAIT_REGISTERED:
1355 		ret = modem_cellular_on_await_registered_state_leave(data);
1356 		break;
1357 
1358 	case MODEM_CELLULAR_STATE_CARRIER_ON:
1359 		ret = modem_cellular_on_carrier_on_state_leave(data);
1360 		break;
1361 
1362 	case MODEM_CELLULAR_STATE_INIT_POWER_OFF:
1363 		ret = modem_cellular_on_init_power_off_state_leave(data);
1364 		break;
1365 
1366 	case MODEM_CELLULAR_STATE_RUN_SHUTDOWN_SCRIPT:
1367 		ret = modem_cellular_on_run_shutdown_script_state_leave(data);
1368 		break;
1369 
1370 	case MODEM_CELLULAR_STATE_POWER_OFF_PULSE:
1371 		ret = modem_cellular_on_power_off_pulse_state_leave(data);
1372 		break;
1373 
1374 	default:
1375 		ret = 0;
1376 		break;
1377 	}
1378 
1379 	return ret;
1380 }
1381 
modem_cellular_enter_state(struct modem_cellular_data * data,enum modem_cellular_state state)1382 static void modem_cellular_enter_state(struct modem_cellular_data *data,
1383 				       enum modem_cellular_state state)
1384 {
1385 	int ret;
1386 
1387 	ret = modem_cellular_on_state_leave(data);
1388 
1389 	if (ret < 0) {
1390 		LOG_WRN("failed to leave state, error: %i", ret);
1391 
1392 		return;
1393 	}
1394 
1395 	data->state = state;
1396 	ret = modem_cellular_on_state_enter(data);
1397 
1398 	if (ret < 0) {
1399 		LOG_WRN("failed to enter state error: %i", ret);
1400 	}
1401 }
1402 
modem_cellular_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)1403 static void modem_cellular_event_handler(struct modem_cellular_data *data,
1404 					 enum modem_cellular_event evt)
1405 {
1406 	enum modem_cellular_state state;
1407 
1408 	state = data->state;
1409 
1410 	modem_cellular_log_event(evt);
1411 
1412 	switch (data->state) {
1413 	case MODEM_CELLULAR_STATE_IDLE:
1414 		modem_cellular_idle_event_handler(data, evt);
1415 		break;
1416 
1417 	case MODEM_CELLULAR_STATE_RESET_PULSE:
1418 		modem_cellular_reset_pulse_event_handler(data, evt);
1419 		break;
1420 
1421 	case MODEM_CELLULAR_STATE_POWER_ON_PULSE:
1422 		modem_cellular_power_on_pulse_event_handler(data, evt);
1423 		break;
1424 
1425 	case MODEM_CELLULAR_STATE_AWAIT_POWER_ON:
1426 		modem_cellular_await_power_on_event_handler(data, evt);
1427 		break;
1428 
1429 	case MODEM_CELLULAR_STATE_SET_BAUDRATE:
1430 		modem_cellular_set_baudrate_event_handler(data, evt);
1431 		break;
1432 
1433 	case MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT:
1434 		modem_cellular_run_init_script_event_handler(data, evt);
1435 		break;
1436 
1437 	case MODEM_CELLULAR_STATE_CONNECT_CMUX:
1438 		modem_cellular_connect_cmux_event_handler(data, evt);
1439 		break;
1440 
1441 	case MODEM_CELLULAR_STATE_OPEN_DLCI1:
1442 		modem_cellular_open_dlci1_event_handler(data, evt);
1443 		break;
1444 
1445 	case MODEM_CELLULAR_STATE_OPEN_DLCI2:
1446 		modem_cellular_open_dlci2_event_handler(data, evt);
1447 		break;
1448 
1449 	case MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT:
1450 		modem_cellular_run_dial_script_event_handler(data, evt);
1451 		break;
1452 
1453 	case MODEM_CELLULAR_STATE_AWAIT_REGISTERED:
1454 		modem_cellular_await_registered_event_handler(data, evt);
1455 		break;
1456 
1457 	case MODEM_CELLULAR_STATE_CARRIER_ON:
1458 		modem_cellular_carrier_on_event_handler(data, evt);
1459 		break;
1460 
1461 	case MODEM_CELLULAR_STATE_INIT_POWER_OFF:
1462 		modem_cellular_init_power_off_event_handler(data, evt);
1463 		break;
1464 
1465 	case MODEM_CELLULAR_STATE_RUN_SHUTDOWN_SCRIPT:
1466 		modem_cellular_run_shutdown_script_event_handler(data, evt);
1467 		break;
1468 
1469 	case MODEM_CELLULAR_STATE_POWER_OFF_PULSE:
1470 		modem_cellular_power_off_pulse_event_handler(data, evt);
1471 		break;
1472 
1473 	case MODEM_CELLULAR_STATE_AWAIT_POWER_OFF:
1474 		modem_cellular_await_power_off_event_handler(data, evt);
1475 		break;
1476 	}
1477 
1478 	if (state != data->state) {
1479 		modem_cellular_log_state_changed(state, data->state);
1480 	}
1481 }
1482 
modem_cellular_cmux_handler(struct modem_cmux * cmux,enum modem_cmux_event event,void * user_data)1483 static void modem_cellular_cmux_handler(struct modem_cmux *cmux, enum modem_cmux_event event,
1484 					void *user_data)
1485 {
1486 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
1487 
1488 	switch (event) {
1489 	case MODEM_CMUX_EVENT_CONNECTED:
1490 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_CMUX_CONNECTED);
1491 		break;
1492 
1493 	default:
1494 		break;
1495 	}
1496 }
1497 
1498 MODEM_CHAT_SCRIPT_CMDS_DEFINE(get_signal_csq_chat_script_cmds,
1499 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CSQ", csq_match),
1500 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match));
1501 
1502 MODEM_CHAT_SCRIPT_DEFINE(get_signal_csq_chat_script, get_signal_csq_chat_script_cmds,
1503 			 abort_matches, modem_cellular_chat_callback_handler, 2);
1504 
modem_cellular_csq_parse_rssi(uint8_t rssi,int16_t * value)1505 static inline int modem_cellular_csq_parse_rssi(uint8_t rssi, int16_t *value)
1506 {
1507 	/* AT+CSQ returns a response +CSQ: <rssi>,<ber> where:
1508 	 * - rssi is a integer from 0 to 31 whose values describes a signal strength
1509 	 *   between -113 dBm for 0 and -51dbM for 31 or unknown for 99
1510 	 * - ber is an integer from 0 to 7 that describes the error rate, it can also
1511 	 *   be 99 for an unknown error rate
1512 	 */
1513 	if (rssi == CSQ_RSSI_UNKNOWN) {
1514 		return -EINVAL;
1515 	}
1516 
1517 	*value = (int16_t)CSQ_RSSI_TO_DB(rssi);
1518 	return 0;
1519 }
1520 
1521 MODEM_CHAT_SCRIPT_CMDS_DEFINE(get_signal_cesq_chat_script_cmds,
1522 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CESQ", cesq_match),
1523 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match));
1524 
1525 MODEM_CHAT_SCRIPT_DEFINE(get_signal_cesq_chat_script, get_signal_cesq_chat_script_cmds,
1526 			 abort_matches, modem_cellular_chat_callback_handler, 2);
1527 
1528 /* AT+CESQ returns a response +CESQ: <rxlev>,<ber>,<rscp>,<ecn0>,<rsrq>,<rsrp> where:
1529  * - rsrq is a integer from 0 to 34 whose values describes the Reference Signal Receive
1530  *   Quality between -20 dB for 0 and -3 dB for 34 (0.5 dB steps), or unknown for 255
1531  * - rsrp is an integer from 0 to 97 that describes the Reference Signal Receive Power
1532  *   between -140 dBm for 0 and -44 dBm for 97 (1 dBm steps), or unknown for 255
1533  */
modem_cellular_cesq_parse_rsrp(uint8_t rsrp,int16_t * value)1534 static inline int modem_cellular_cesq_parse_rsrp(uint8_t rsrp, int16_t *value)
1535 {
1536 	if (rsrp == CESQ_RSRP_UNKNOWN) {
1537 		return -EINVAL;
1538 	}
1539 
1540 	*value = (int16_t)CESQ_RSRP_TO_DB(rsrp);
1541 	return 0;
1542 }
1543 
modem_cellular_cesq_parse_rsrq(uint8_t rsrq,int16_t * value)1544 static inline int modem_cellular_cesq_parse_rsrq(uint8_t rsrq, int16_t *value)
1545 {
1546 	if (rsrq == CESQ_RSRQ_UNKNOWN) {
1547 		return -EINVAL;
1548 	}
1549 
1550 	*value = (int16_t)CESQ_RSRQ_TO_DB(rsrq);
1551 	return 0;
1552 }
1553 
modem_cellular_get_signal(const struct device * dev,const enum cellular_signal_type type,int16_t * value)1554 static int modem_cellular_get_signal(const struct device *dev,
1555 				     const enum cellular_signal_type type,
1556 				     int16_t *value)
1557 {
1558 	int ret = -ENOTSUP;
1559 	struct modem_cellular_data *data = (struct modem_cellular_data *)dev->data;
1560 
1561 	if ((data->state != MODEM_CELLULAR_STATE_AWAIT_REGISTERED) &&
1562 	    (data->state != MODEM_CELLULAR_STATE_CARRIER_ON)) {
1563 		return -ENODATA;
1564 	}
1565 
1566 	/* Run chat script */
1567 	switch (type) {
1568 	case CELLULAR_SIGNAL_RSSI:
1569 		ret = modem_chat_run_script(&data->chat, &get_signal_csq_chat_script);
1570 		break;
1571 
1572 	case CELLULAR_SIGNAL_RSRP:
1573 	case CELLULAR_SIGNAL_RSRQ:
1574 		ret = modem_chat_run_script(&data->chat, &get_signal_cesq_chat_script);
1575 		break;
1576 
1577 	default:
1578 		ret = -ENOTSUP;
1579 		break;
1580 	}
1581 
1582 	/* Verify chat script ran successfully */
1583 	if (ret < 0) {
1584 		return ret;
1585 	}
1586 
1587 	/* Parse received value */
1588 	switch (type) {
1589 	case CELLULAR_SIGNAL_RSSI:
1590 		ret = modem_cellular_csq_parse_rssi(data->rssi, value);
1591 		break;
1592 
1593 	case CELLULAR_SIGNAL_RSRP:
1594 		ret = modem_cellular_cesq_parse_rsrp(data->rsrp, value);
1595 		break;
1596 
1597 	case CELLULAR_SIGNAL_RSRQ:
1598 		ret = modem_cellular_cesq_parse_rsrq(data->rsrq, value);
1599 		break;
1600 
1601 	default:
1602 		ret = -ENOTSUP;
1603 		break;
1604 	}
1605 
1606 	return ret;
1607 }
1608 
modem_cellular_get_modem_info(const struct device * dev,enum cellular_modem_info_type type,char * info,size_t size)1609 static int modem_cellular_get_modem_info(const struct device *dev,
1610 					 enum cellular_modem_info_type type,
1611 					 char *info, size_t size)
1612 {
1613 	int ret = 0;
1614 	struct modem_cellular_data *data = (struct modem_cellular_data *)dev->data;
1615 
1616 	switch (type) {
1617 	case CELLULAR_MODEM_INFO_IMEI:
1618 		strncpy(info, &data->imei[0], MIN(size, sizeof(data->imei)));
1619 		break;
1620 	case CELLULAR_MODEM_INFO_SIM_IMSI:
1621 		strncpy(info, &data->imsi[0], MIN(size, sizeof(data->imsi)));
1622 		break;
1623 	case CELLULAR_MODEM_INFO_MANUFACTURER:
1624 		strncpy(info, &data->manufacturer[0], MIN(size, sizeof(data->manufacturer)));
1625 		break;
1626 	case CELLULAR_MODEM_INFO_FW_VERSION:
1627 		strncpy(info, &data->fw_version[0], MIN(size, sizeof(data->fw_version)));
1628 		break;
1629 	case CELLULAR_MODEM_INFO_MODEL_ID:
1630 		strncpy(info, &data->model_id[0], MIN(size, sizeof(data->model_id)));
1631 		break;
1632 	case CELLULAR_MODEM_INFO_SIM_ICCID:
1633 		strncpy(info, &data->iccid[0], MIN(size, sizeof(data->iccid)));
1634 		break;
1635 	default:
1636 		ret = -ENODATA;
1637 		break;
1638 	}
1639 
1640 	return ret;
1641 }
modem_cellular_get_registration_status(const struct device * dev,enum cellular_access_technology tech,enum cellular_registration_status * status)1642 static int modem_cellular_get_registration_status(const struct device *dev,
1643 						  enum cellular_access_technology tech,
1644 						  enum cellular_registration_status *status)
1645 {
1646 	int ret = 0;
1647 	struct modem_cellular_data *data = (struct modem_cellular_data *)dev->data;
1648 
1649 	switch (tech) {
1650 	case CELLULAR_ACCESS_TECHNOLOGY_GSM:
1651 		*status = data->registration_status_gsm;
1652 		break;
1653 	case CELLULAR_ACCESS_TECHNOLOGY_GPRS:
1654 	case CELLULAR_ACCESS_TECHNOLOGY_UMTS:
1655 	case CELLULAR_ACCESS_TECHNOLOGY_EDGE:
1656 		*status = data->registration_status_gprs;
1657 		break;
1658 	case CELLULAR_ACCESS_TECHNOLOGY_LTE:
1659 	case CELLULAR_ACCESS_TECHNOLOGY_LTE_CAT_M1:
1660 	case CELLULAR_ACCESS_TECHNOLOGY_LTE_CAT_M2:
1661 	case CELLULAR_ACCESS_TECHNOLOGY_NB_IOT:
1662 		*status = data->registration_status_lte;
1663 		break;
1664 	default:
1665 		ret = -ENODATA;
1666 		break;
1667 	}
1668 
1669 	return ret;
1670 }
1671 
1672 static DEVICE_API(cellular, modem_cellular_api) = {
1673 	.get_signal = modem_cellular_get_signal,
1674 	.get_modem_info = modem_cellular_get_modem_info,
1675 	.get_registration_status = modem_cellular_get_registration_status,
1676 };
1677 
1678 #ifdef CONFIG_PM_DEVICE
modem_cellular_pm_action(const struct device * dev,enum pm_device_action action)1679 static int modem_cellular_pm_action(const struct device *dev, enum pm_device_action action)
1680 {
1681 	struct modem_cellular_data *data = (struct modem_cellular_data *)dev->data;
1682 	int ret;
1683 
1684 	switch (action) {
1685 	case PM_DEVICE_ACTION_RESUME:
1686 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_RESUME);
1687 		ret = 0;
1688 		break;
1689 
1690 	case PM_DEVICE_ACTION_SUSPEND:
1691 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_SUSPEND);
1692 		ret = k_sem_take(&data->suspended_sem, K_SECONDS(30));
1693 		break;
1694 
1695 	default:
1696 		ret = -ENOTSUP;
1697 		break;
1698 	}
1699 
1700 	return ret;
1701 }
1702 #endif /* CONFIG_PM_DEVICE */
1703 
modem_cellular_init(const struct device * dev)1704 static int modem_cellular_init(const struct device *dev)
1705 {
1706 	struct modem_cellular_data *data = (struct modem_cellular_data *)dev->data;
1707 	struct modem_cellular_config *config = (struct modem_cellular_config *)dev->config;
1708 
1709 	data->dev = dev;
1710 
1711 	k_work_init_delayable(&data->timeout_work, modem_cellular_timeout_handler);
1712 
1713 	k_work_init(&data->event_dispatch_work, modem_cellular_event_dispatch_handler);
1714 	ring_buf_init(&data->event_rb, sizeof(data->event_buf), data->event_buf);
1715 
1716 	k_sem_init(&data->suspended_sem, 0, 1);
1717 
1718 	if (modem_cellular_gpio_is_enabled(&config->power_gpio)) {
1719 		gpio_pin_configure_dt(&config->power_gpio, GPIO_OUTPUT_INACTIVE);
1720 	}
1721 
1722 	if (modem_cellular_gpio_is_enabled(&config->reset_gpio)) {
1723 		gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_ACTIVE);
1724 	}
1725 
1726 	{
1727 		const struct modem_backend_uart_config uart_backend_config = {
1728 			.uart = config->uart,
1729 			.receive_buf = data->uart_backend_receive_buf,
1730 			.receive_buf_size = ARRAY_SIZE(data->uart_backend_receive_buf),
1731 			.transmit_buf = data->uart_backend_transmit_buf,
1732 			.transmit_buf_size = ARRAY_SIZE(data->uart_backend_transmit_buf),
1733 		};
1734 
1735 		data->uart_pipe = modem_backend_uart_init(&data->uart_backend,
1736 							  &uart_backend_config);
1737 
1738 		data->cmd_pipe = NULL;
1739 	}
1740 
1741 	{
1742 		const struct modem_cmux_config cmux_config = {
1743 			.callback = modem_cellular_cmux_handler,
1744 			.user_data = data,
1745 			.receive_buf = data->cmux_receive_buf,
1746 			.receive_buf_size = ARRAY_SIZE(data->cmux_receive_buf),
1747 			.transmit_buf = data->cmux_transmit_buf,
1748 			.transmit_buf_size = ARRAY_SIZE(data->cmux_transmit_buf),
1749 		};
1750 
1751 		modem_cmux_init(&data->cmux, &cmux_config);
1752 	}
1753 
1754 	{
1755 		const struct modem_cmux_dlci_config dlci1_config = {
1756 			.dlci_address = 1,
1757 			.receive_buf = data->dlci1_receive_buf,
1758 			.receive_buf_size = ARRAY_SIZE(data->dlci1_receive_buf),
1759 		};
1760 
1761 		data->dlci1_pipe = modem_cmux_dlci_init(&data->cmux, &data->dlci1,
1762 							&dlci1_config);
1763 	}
1764 
1765 	{
1766 		const struct modem_cmux_dlci_config dlci2_config = {
1767 			.dlci_address = 2,
1768 			.receive_buf = data->dlci2_receive_buf,
1769 			.receive_buf_size = ARRAY_SIZE(data->dlci2_receive_buf),
1770 		};
1771 
1772 		data->dlci2_pipe = modem_cmux_dlci_init(&data->cmux, &data->dlci2,
1773 							&dlci2_config);
1774 	}
1775 
1776 	for (uint8_t i = 0; i < config->user_pipes_size; i++) {
1777 		struct modem_cellular_user_pipe *user_pipe = &config->user_pipes[i];
1778 		const struct modem_cmux_dlci_config user_dlci_config = {
1779 			.dlci_address = user_pipe->dlci_address,
1780 			.receive_buf = user_pipe->dlci_receive_buf,
1781 			.receive_buf_size = user_pipe->dlci_receive_buf_size,
1782 		};
1783 
1784 		user_pipe->pipe = modem_cmux_dlci_init(&data->cmux, &user_pipe->dlci,
1785 						       &user_dlci_config);
1786 
1787 		modem_pipelink_init(user_pipe->pipelink, user_pipe->pipe);
1788 	}
1789 
1790 	{
1791 		const struct modem_chat_config chat_config = {
1792 			.user_data = data,
1793 			.receive_buf = data->chat_receive_buf,
1794 			.receive_buf_size = ARRAY_SIZE(data->chat_receive_buf),
1795 			.delimiter = data->chat_delimiter,
1796 			.delimiter_size = strlen(data->chat_delimiter),
1797 			.filter = data->chat_filter,
1798 			.filter_size = data->chat_filter ? strlen(data->chat_filter) : 0,
1799 			.argv = data->chat_argv,
1800 			.argv_size = ARRAY_SIZE(data->chat_argv),
1801 			.unsol_matches = unsol_matches,
1802 			.unsol_matches_size = ARRAY_SIZE(unsol_matches),
1803 		};
1804 
1805 		modem_chat_init(&data->chat, &chat_config);
1806 	}
1807 
1808 #ifndef CONFIG_PM_DEVICE
1809 	modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_RESUME);
1810 #else
1811 	pm_device_init_suspended(dev);
1812 #endif /* CONFIG_PM_DEVICE */
1813 
1814 	return 0;
1815 }
1816 
1817 /*
1818  * Every modem uses two custom scripts to initialize the modem and dial out.
1819  *
1820  * The first script is named <dt driver compatible>_init_chat_script, with its
1821  * script commands named <dt driver compatible>_init_chat_script_cmds. This
1822  * script is sent to the modem after it has started up, and must configure the
1823  * modem to use CMUX.
1824  *
1825  * The second script is named <dt driver compatible>_dial_chat_script, with its
1826  * script commands named <dt driver compatible>_dial_chat_script_cmds. This
1827  * script is sent on a DLCI channel in command mode, and must request the modem
1828  * dial out and put the DLCI channel into data mode.
1829  */
1830 
1831 #if DT_HAS_COMPAT_STATUS_OKAY(quectel_bg95)
1832 MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_bg95_init_chat_script_cmds,
1833 			      MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
1834 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
1835 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
1836 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
1837 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match),
1838 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
1839 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1840 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1841 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
1842 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
1843 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1844 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
1845 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1846 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMI", cgmi_match),
1847 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1848 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match),
1849 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1850 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CIMI", cimi_match),
1851 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1852 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+QCCID", qccid_match),
1853 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1854 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127", 300));
1855 
1856 MODEM_CHAT_SCRIPT_DEFINE(quectel_bg95_init_chat_script, quectel_bg95_init_chat_script_cmds,
1857 			 abort_matches, modem_cellular_chat_callback_handler, 10);
1858 
1859 MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_bg95_dial_chat_script_cmds,
1860 			      MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0,1", allow_match),
1861 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
1862 							 "\""CONFIG_MODEM_CELLULAR_APN"\"",
1863 							 ok_match),
1864 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
1865 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0),);
1866 
1867 MODEM_CHAT_SCRIPT_DEFINE(quectel_bg95_dial_chat_script, quectel_bg95_dial_chat_script_cmds,
1868 			 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
1869 
1870 MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_bg95_periodic_chat_script_cmds,
1871 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1872 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1873 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match));
1874 
1875 MODEM_CHAT_SCRIPT_DEFINE(quectel_bg95_periodic_chat_script,
1876 			 quectel_bg95_periodic_chat_script_cmds, abort_matches,
1877 			 modem_cellular_chat_callback_handler, 4);
1878 #endif
1879 
1880 #if DT_HAS_COMPAT_STATUS_OKAY(quectel_eg25_g)
1881 MODEM_CHAT_SCRIPT_CMDS_DEFINE(
1882 	quectel_eg25_g_init_chat_script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
1883 	MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
1884 	MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
1885 	MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
1886 	MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match),
1887 	MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
1888 	MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1889 	MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1890 	MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
1891 	MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
1892 	MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1893 	MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
1894 	MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1895 	MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMI", cgmi_match),
1896 	MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1897 	MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match),
1898 	MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1899 	MODEM_CHAT_SCRIPT_CMD_RESP("AT+CIMI", cimi_match),
1900 	MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1901 	MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2", 100));
1902 
1903 MODEM_CHAT_SCRIPT_DEFINE(quectel_eg25_g_init_chat_script, quectel_eg25_g_init_chat_script_cmds,
1904 			 abort_matches, modem_cellular_chat_callback_handler, 10);
1905 
1906 MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_eg25_g_dial_chat_script_cmds,
1907 			      MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0,1", allow_match),
1908 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
1909 							 "\""CONFIG_MODEM_CELLULAR_APN"\"",
1910 							 ok_match),
1911 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
1912 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0),);
1913 
1914 MODEM_CHAT_SCRIPT_DEFINE(quectel_eg25_g_dial_chat_script, quectel_eg25_g_dial_chat_script_cmds,
1915 			 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
1916 
1917 MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_eg25_g_periodic_chat_script_cmds,
1918 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1919 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1920 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
1921 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CSQ", csq_match));
1922 
1923 MODEM_CHAT_SCRIPT_DEFINE(quectel_eg25_g_periodic_chat_script,
1924 			 quectel_eg25_g_periodic_chat_script_cmds, abort_matches,
1925 			 modem_cellular_chat_callback_handler, 4);
1926 #endif
1927 
1928 #if DT_HAS_COMPAT_STATUS_OKAY(simcom_sim7080)
1929 MODEM_CHAT_SCRIPT_CMDS_DEFINE(simcom_sim7080_init_chat_script_cmds,
1930 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1931 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1932 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1933 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1934 			      MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
1935 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
1936 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
1937 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
1938 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match),
1939 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
1940 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1941 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1942 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
1943 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
1944 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1945 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
1946 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1947 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127", 300));
1948 
1949 MODEM_CHAT_SCRIPT_DEFINE(simcom_sim7080_init_chat_script, simcom_sim7080_init_chat_script_cmds,
1950 			 abort_matches, modem_cellular_chat_callback_handler, 10);
1951 
1952 MODEM_CHAT_SCRIPT_CMDS_DEFINE(simcom_sim7080_dial_chat_script_cmds,
1953 			      MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0,1", allow_match),
1954 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
1955 							 "\""CONFIG_MODEM_CELLULAR_APN"\"",
1956 							 ok_match),
1957 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
1958 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0),);
1959 
1960 MODEM_CHAT_SCRIPT_DEFINE(simcom_sim7080_dial_chat_script, simcom_sim7080_dial_chat_script_cmds,
1961 			 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
1962 
1963 MODEM_CHAT_SCRIPT_CMDS_DEFINE(simcom_sim7080_periodic_chat_script_cmds,
1964 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1965 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1966 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match));
1967 
1968 MODEM_CHAT_SCRIPT_DEFINE(simcom_sim7080_periodic_chat_script,
1969 			 simcom_sim7080_periodic_chat_script_cmds, abort_matches,
1970 			 modem_cellular_chat_callback_handler, 4);
1971 #endif
1972 
1973 #if DT_HAS_COMPAT_STATUS_OKAY(u_blox_sara_r4)
1974 MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r4_init_chat_script_cmds,
1975 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1976 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1977 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1978 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1979 			      MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
1980 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
1981 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
1982 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
1983 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match),
1984 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
1985 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1986 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1987 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
1988 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
1989 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1990 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
1991 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1992 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMUX=0,0,5,127", ok_match));
1993 
1994 MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r4_init_chat_script, u_blox_sara_r4_init_chat_script_cmds,
1995 			 abort_matches, modem_cellular_chat_callback_handler, 10);
1996 
1997 MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r4_dial_chat_script_cmds,
1998 			      MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0,1", allow_match),
1999 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
2000 							 "\""CONFIG_MODEM_CELLULAR_APN"\"",
2001 							 ok_match),
2002 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
2003 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0),);
2004 
2005 MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r4_dial_chat_script, u_blox_sara_r4_dial_chat_script_cmds,
2006 			 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
2007 
2008 MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r4_periodic_chat_script_cmds,
2009 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
2010 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
2011 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match));
2012 
2013 MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r4_periodic_chat_script,
2014 			 u_blox_sara_r4_periodic_chat_script_cmds, abort_matches,
2015 			 modem_cellular_chat_callback_handler, 4);
2016 #endif
2017 
2018 #if DT_HAS_COMPAT_STATUS_OKAY(u_blox_sara_r5)
2019 MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r5_init_chat_script_cmds,
2020 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
2021 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
2022 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
2023 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
2024 			      MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
2025 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
2026 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
2027 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
2028 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match),
2029 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
2030 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
2031 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
2032 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
2033 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
2034 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2035 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
2036 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2037 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMI", cgmi_match),
2038 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2039 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match),
2040 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2041 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CIMI", cimi_match),
2042 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2043 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMUX=0,0,5,127", ok_match));
2044 
2045 MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r5_init_chat_script, u_blox_sara_r5_init_chat_script_cmds,
2046 			 abort_matches, modem_cellular_chat_callback_handler, 10);
2047 
2048 MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r5_dial_chat_script_cmds,
2049 			      MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0,1", allow_match),
2050 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
2051 							 "\""CONFIG_MODEM_CELLULAR_APN"\"",
2052 							 ok_match),
2053 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
2054 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0),);
2055 
2056 MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r5_dial_chat_script, u_blox_sara_r5_dial_chat_script_cmds,
2057 			 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
2058 
2059 MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r5_periodic_chat_script_cmds,
2060 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
2061 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
2062 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match));
2063 
2064 MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r5_periodic_chat_script,
2065 			 u_blox_sara_r5_periodic_chat_script_cmds, abort_matches,
2066 			 modem_cellular_chat_callback_handler, 4);
2067 #endif
2068 
2069 #if DT_HAS_COMPAT_STATUS_OKAY(u_blox_lara_r6)
2070 MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_lara_r6_set_baudrate_chat_script_cmds,
2071 			      MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
2072 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+IPR="
2073 					STRINGIFY(CONFIG_MODEM_CELLULAR_NEW_BAUDRATE), ok_match));
2074 
2075 MODEM_CHAT_SCRIPT_DEFINE(u_blox_lara_r6_set_baudrate_chat_script,
2076 			 u_blox_lara_r6_set_baudrate_chat_script_cmds,
2077 			 abort_matches, modem_cellular_chat_callback_handler, 1);
2078 
2079 /* NOTE: For some reason, a CMUX max frame size of 127 causes FCS errors in
2080  * this modem; larger or smaller doesn't. The modem's default value is 31,
2081  * which works well
2082  */
2083 MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_lara_r6_init_chat_script_cmds,
2084 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
2085 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
2086 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
2087 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match),
2088 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
2089 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
2090 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
2091 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
2092 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
2093 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2094 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
2095 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2096 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMI", cgmi_match),
2097 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2098 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match),
2099 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2100 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CIMI", cimi_match),
2101 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2102 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMUX=0,0,5,31", ok_match));
2103 
2104 MODEM_CHAT_SCRIPT_DEFINE(u_blox_lara_r6_init_chat_script, u_blox_lara_r6_init_chat_script_cmds,
2105 			 abort_matches, modem_cellular_chat_callback_handler, 10);
2106 
2107 MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_lara_r6_dial_chat_script_cmds,
2108 			      MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0,1", allow_match),
2109 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
2110 							 "\""CONFIG_MODEM_CELLULAR_APN"\"",
2111 							 ok_match),
2112 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
2113 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0),);
2114 
2115 MODEM_CHAT_SCRIPT_DEFINE(u_blox_lara_r6_dial_chat_script, u_blox_lara_r6_dial_chat_script_cmds,
2116 			 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
2117 
2118 MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_lara_r6_periodic_chat_script_cmds,
2119 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
2120 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
2121 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match));
2122 
2123 MODEM_CHAT_SCRIPT_DEFINE(u_blox_lara_r6_periodic_chat_script,
2124 			 u_blox_lara_r6_periodic_chat_script_cmds, abort_matches,
2125 			 modem_cellular_chat_callback_handler, 4);
2126 #endif
2127 
2128 #if DT_HAS_COMPAT_STATUS_OKAY(swir_hl7800)
2129 MODEM_CHAT_SCRIPT_CMDS_DEFINE(swir_hl7800_init_chat_script_cmds,
2130 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
2131 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
2132 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
2133 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
2134 			      MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
2135 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
2136 			      MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0", allow_match),
2137 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
2138 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
2139 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
2140 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
2141 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
2142 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
2143 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
2144 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2145 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
2146 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2147 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMI", cgmi_match),
2148 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2149 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match),
2150 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2151 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CIMI", cimi_match),
2152 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2153 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMUX=0,0,5,127", ok_match));
2154 
2155 MODEM_CHAT_SCRIPT_DEFINE(swir_hl7800_init_chat_script, swir_hl7800_init_chat_script_cmds,
2156 			 abort_matches, modem_cellular_chat_callback_handler, 10);
2157 
2158 MODEM_CHAT_SCRIPT_CMDS_DEFINE(swir_hl7800_dial_chat_script_cmds,
2159 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
2160 							 "\""CONFIG_MODEM_CELLULAR_APN"\"",
2161 							 ok_match),
2162 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+KCNXCFG=1,\"GPRS\",\""
2163 							 CONFIG_MODEM_CELLULAR_APN
2164 							 "\",,,\"IPV4\"",
2165 							 ok_match),
2166 				  MODEM_CHAT_SCRIPT_CMD_RESP("AT+WPPP=0", ok_match),
2167 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
2168 			      MODEM_CHAT_SCRIPT_CMD_RESP("ATD*99***1#", connect_match));
2169 
2170 MODEM_CHAT_SCRIPT_CMDS_DEFINE(swir_hl7800_periodic_chat_script_cmds,
2171 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
2172 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match));
2173 
2174 MODEM_CHAT_SCRIPT_DEFINE(swir_hl7800_periodic_chat_script,
2175 			 swir_hl7800_periodic_chat_script_cmds, abort_matches,
2176 			 modem_cellular_chat_callback_handler, 4);
2177 
2178 MODEM_CHAT_SCRIPT_DEFINE(swir_hl7800_dial_chat_script, swir_hl7800_dial_chat_script_cmds,
2179 			 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
2180 #endif
2181 
2182 #if DT_HAS_COMPAT_STATUS_OKAY(telit_me910g1) || DT_HAS_COMPAT_STATUS_OKAY(telit_me310g1)
2183 MODEM_CHAT_SCRIPT_CMDS_DEFINE(telit_mex10g1_init_chat_script_cmds,
2184 				  MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
2185 				  MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
2186 				  MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
2187 				  MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
2188 				  MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
2189 				  MODEM_CHAT_SCRIPT_CMD_RESP("AT+ICCID", iccid_match),
2190 				  MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2191 				  MODEM_CHAT_SCRIPT_CMD_RESP("AT+CIMI", cimi_match),
2192 				  MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2193 				  /* The Telit me910g1 often has an error trying
2194 				   * to set the PDP context. The radio must be on to set
2195 				   * the context, and this step must be successful.
2196 				   * It is moved to the init script to allow retries.
2197 				   */
2198 				  MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
2199 							 "\"" CONFIG_MODEM_CELLULAR_APN "\"",
2200 							 ok_match),
2201 				  MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
2202 				  MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
2203 				  MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
2204 				  MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match),
2205 				  MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
2206 				  MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
2207 				  MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
2208 				  MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
2209 				  MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
2210 				  MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2211 				  MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
2212 				  MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2213 				  MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMI", cgmi_match),
2214 				  MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2215 				  MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match),
2216 				  MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2217 				  MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
2218 				  MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2",
2219 								  300));
2220 
2221 MODEM_CHAT_SCRIPT_DEFINE(telit_mex10g1_init_chat_script, telit_mex10g1_init_chat_script_cmds,
2222 			 abort_matches, modem_cellular_chat_callback_handler, 10);
2223 
2224 MODEM_CHAT_SCRIPT_CMDS_DEFINE(telit_mex10g1_dial_chat_script_cmds,
2225 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT", ok_match),
2226 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0));
2227 
2228 MODEM_CHAT_SCRIPT_DEFINE(telit_mex10g1_dial_chat_script, telit_mex10g1_dial_chat_script_cmds,
2229 			 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
2230 
2231 MODEM_CHAT_SCRIPT_CMDS_DEFINE(telit_mex10g1_periodic_chat_script_cmds,
2232 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
2233 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
2234 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match));
2235 
2236 MODEM_CHAT_SCRIPT_DEFINE(telit_mex10g1_periodic_chat_script,
2237 			 telit_mex10g1_periodic_chat_script_cmds, abort_matches,
2238 			 modem_cellular_chat_callback_handler, 4);
2239 
2240 #endif
2241 
2242 #if DT_HAS_COMPAT_STATUS_OKAY(telit_me310g1)
2243 MODEM_CHAT_SCRIPT_CMDS_DEFINE(telit_me310g1_shutdown_chat_script_cmds,
2244 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT#SHDN", ok_match));
2245 
2246 MODEM_CHAT_SCRIPT_DEFINE(telit_me310g1_shutdown_chat_script,
2247 			 telit_me310g1_shutdown_chat_script_cmds, abort_matches,
2248 			 modem_cellular_chat_callback_handler, 15);
2249 
2250 #endif
2251 
2252 #if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf91_slm)
2253 MODEM_CHAT_SCRIPT_CMDS_DEFINE(nordic_nrf91_slm_init_chat_script_cmds,
2254 			      MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT", allow_match),
2255 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
2256 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
2257 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
2258 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
2259 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2260 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
2261 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2262 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMI", cgmi_match),
2263 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2264 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match),
2265 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2266 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT#XCMUX=1", ok_match));
2267 
2268 MODEM_CHAT_SCRIPT_DEFINE(nordic_nrf91_slm_init_chat_script, nordic_nrf91_slm_init_chat_script_cmds,
2269 			 abort_matches, modem_cellular_chat_callback_handler, 10);
2270 
2271 MODEM_CHAT_SCRIPT_CMDS_DEFINE(nordic_nrf91_slm_dial_chat_script_cmds,
2272 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
2273 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
2274 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT#XCMUX=2", ok_match));
2275 
2276 MODEM_CHAT_SCRIPT_DEFINE(nordic_nrf91_slm_dial_chat_script, nordic_nrf91_slm_dial_chat_script_cmds,
2277 			 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
2278 
2279 MODEM_CHAT_SCRIPT_CMDS_DEFINE(nordic_nrf91_slm_periodic_chat_script_cmds,
2280 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match));
2281 
2282 MODEM_CHAT_SCRIPT_DEFINE(nordic_nrf91_slm_periodic_chat_script,
2283 			 nordic_nrf91_slm_periodic_chat_script_cmds, abort_matches,
2284 			 modem_cellular_chat_callback_handler, 4);
2285 #endif
2286 
2287 #if DT_HAS_COMPAT_STATUS_OKAY(sqn_gm02s)
2288 MODEM_CHAT_SCRIPT_CMDS_DEFINE(sqn_gm02s_init_chat_script_cmds,
2289 			      MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
2290 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
2291 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
2292 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
2293 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
2294 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
2295 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2296 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
2297 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2298 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMI", cgmi_match),
2299 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2300 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match),
2301 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2302 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMUX=0,0,5,127", ok_match));
2303 
2304 MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_init_chat_script, sqn_gm02s_init_chat_script_cmds,
2305 			 abort_matches, modem_cellular_chat_callback_handler, 10);
2306 
2307 MODEM_CHAT_SCRIPT_CMDS_DEFINE(sqn_gm02s_dial_chat_script_cmds,
2308 			      MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0,1", allow_match),
2309 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
2310 							 "\""CONFIG_MODEM_CELLULAR_APN"\"",
2311 							 ok_match),
2312 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CFUN=1", 10000),
2313 			      MODEM_CHAT_SCRIPT_CMD_RESP("ATD*99***1#", connect_match));
2314 
2315 MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_dial_chat_script, sqn_gm02s_dial_chat_script_cmds,
2316 			 dial_abort_matches, modem_cellular_chat_callback_handler, 15);
2317 
2318 MODEM_CHAT_SCRIPT_CMDS_DEFINE(sqn_gm02s_periodic_chat_script_cmds,
2319 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match));
2320 
2321 MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script,
2322 			 sqn_gm02s_periodic_chat_script_cmds, abort_matches,
2323 			 modem_cellular_chat_callback_handler, 4);
2324 #endif
2325 
2326 #define MODEM_CELLULAR_INST_NAME(name, inst) \
2327 	_CONCAT_4(name, _, DT_DRV_COMPAT, inst)
2328 
2329 #define MODEM_CELLULAR_DEFINE_USER_PIPE_DATA(inst, name, size)                                     \
2330 	MODEM_PIPELINK_DT_INST_DEFINE(inst, name);                                                 \
2331 	static uint8_t MODEM_CELLULAR_INST_NAME(name, inst)[size]                                  \
2332 
2333 #define MODEM_CELLULAR_INIT_USER_PIPE(_inst, _name, _dlci_address)                                 \
2334 	{                                                                                          \
2335 		.dlci_address = _dlci_address,                                                     \
2336 		.dlci_receive_buf = MODEM_CELLULAR_INST_NAME(_name, _inst),                        \
2337 		.dlci_receive_buf_size = sizeof(MODEM_CELLULAR_INST_NAME(_name, _inst)),           \
2338 		.pipelink = MODEM_PIPELINK_DT_INST_GET(_inst, _name),                              \
2339 	}
2340 
2341 #define MODEM_CELLULAR_DEFINE_USER_PIPES(inst, ...)                                                \
2342 	static struct modem_cellular_user_pipe MODEM_CELLULAR_INST_NAME(user_pipes, inst)[] = {    \
2343 		__VA_ARGS__                                                                        \
2344 	}
2345 
2346 #define MODEM_CELLULAR_GET_USER_PIPES(inst) \
2347 	MODEM_CELLULAR_INST_NAME(user_pipes, inst)
2348 
2349 /* Extract the first argument (pipe name) from a pair */
2350 #define MODEM_CELLULAR_GET_PIPE_NAME_ARG(arg1, ...) arg1
2351 
2352 /* Extract the second argument (DLCI address) from a pair */
2353 #define MODEM_CELLULAR_GET_DLCI_ADDRESS_ARG(arg1, arg2, ...) arg2
2354 
2355 /* Define user pipe data using instance and extracted pipe name */
2356 #define MODEM_CELLULAR_DEFINE_USER_PIPE_DATA_HELPER(_args, inst)                                   \
2357 	MODEM_CELLULAR_DEFINE_USER_PIPE_DATA(inst,                                                 \
2358 					     MODEM_CELLULAR_GET_PIPE_NAME_ARG _args,               \
2359 					     CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES)
2360 
2361 /* Initialize user pipe using instance, extracted pipe name, and DLCI address */
2362 #define MODEM_CELLULAR_INIT_USER_PIPE_HELPER(_args, inst)                                          \
2363 	MODEM_CELLULAR_INIT_USER_PIPE(inst,                                                        \
2364 				      MODEM_CELLULAR_GET_PIPE_NAME_ARG _args,                      \
2365 				      MODEM_CELLULAR_GET_DLCI_ADDRESS_ARG _args)
2366 
2367 /*
2368  * Define and initialize user pipes dynamically
2369  * Takes an instance and pairs of (pipe name, DLCI address)
2370  */
2371 #define MODEM_CELLULAR_DEFINE_AND_INIT_USER_PIPES(inst, ...)                                       \
2372 	FOR_EACH_FIXED_ARG(MODEM_CELLULAR_DEFINE_USER_PIPE_DATA_HELPER,                            \
2373 			   (;), inst, __VA_ARGS__);                                                \
2374 	MODEM_CELLULAR_DEFINE_USER_PIPES(                                                          \
2375 		inst,                                                                              \
2376 		FOR_EACH_FIXED_ARG(MODEM_CELLULAR_INIT_USER_PIPE_HELPER,                           \
2377 				   (,), inst, __VA_ARGS__)                                         \
2378 	);
2379 
2380 /* Helper to define modem instance */
2381 #define MODEM_CELLULAR_DEFINE_INSTANCE(inst, power_ms, reset_ms, startup_ms, shutdown_ms, start,   \
2382 				       set_baudrate_script,                                        \
2383 				       init_script,                                                \
2384 				       dial_script,                                                \
2385 				       periodic_script,                                            \
2386 				       shutdown_script)                                            \
2387 	static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = {       \
2388 		.uart = DEVICE_DT_GET(DT_INST_BUS(inst)),                                          \
2389 		.power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}),                 \
2390 		.reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}),                 \
2391 		.power_pulse_duration_ms = (power_ms),                                             \
2392 		.reset_pulse_duration_ms = (reset_ms),                                             \
2393 		.startup_time_ms  = (startup_ms),                                                  \
2394 		.shutdown_time_ms = (shutdown_ms),                                                 \
2395 		.autostarts       = (start),                                                       \
2396 		.set_baudrate_chat_script    = (set_baudrate_script),                              \
2397 		.init_chat_script            = (init_script),                                      \
2398 		.dial_chat_script            = (dial_script),                                      \
2399 		.periodic_chat_script = (periodic_script),                                         \
2400 		.shutdown_chat_script  = (shutdown_script),                                        \
2401 		.user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst),                                 \
2402 		.user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)),                \
2403 	};                                                                                         \
2404                                                                                                    \
2405 	PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action);                                  \
2406                                                                                                    \
2407 	DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst),              \
2408 			      &MODEM_CELLULAR_INST_NAME(data, inst),                               \
2409 			      &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99,            \
2410 			      &modem_cellular_api);
2411 
2412 #define MODEM_CELLULAR_DEVICE_QUECTEL_BG95(inst)                                                   \
2413 	MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64);                 \
2414                                                                                                    \
2415 	static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = {                 \
2416 		.chat_delimiter = "\r",                                                            \
2417 		.chat_filter = "\n",                                                               \
2418 		.ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst),                                       \
2419 	};                                                                                         \
2420                                                                                                    \
2421 	MODEM_CELLULAR_DEFINE_AND_INIT_USER_PIPES(inst,                                            \
2422 						  (user_pipe_0, 3),                                \
2423 						  (user_pipe_1, 4))                                \
2424                                                                                                    \
2425 	MODEM_CELLULAR_DEFINE_INSTANCE(inst, 1500, 100, 10000, 5000, false,                        \
2426 				       NULL,                                                       \
2427 				       &quectel_bg95_init_chat_script,                             \
2428 				       &quectel_bg95_dial_chat_script,                             \
2429 				       &quectel_bg95_periodic_chat_script, NULL)
2430 
2431 #define MODEM_CELLULAR_DEVICE_QUECTEL_EG25_G(inst)                                                 \
2432 	MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64);                 \
2433                                                                                                    \
2434 	static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = {                 \
2435 		.chat_delimiter = "\r",                                                            \
2436 		.chat_filter = "\n",                                                               \
2437 		.ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst),                                       \
2438 	};                                                                                         \
2439                                                                                                    \
2440 	MODEM_CELLULAR_DEFINE_AND_INIT_USER_PIPES(inst,                                            \
2441 						  (user_pipe_0, 3),                                \
2442 						  (user_pipe_1, 4))                                \
2443                                                                                                    \
2444 	MODEM_CELLULAR_DEFINE_INSTANCE(inst, 1500, 500, 15000, 5000, false,                        \
2445 				       NULL,                                                       \
2446 				       &quectel_eg25_g_init_chat_script,                           \
2447 				       &quectel_eg25_g_dial_chat_script,                           \
2448 				       &quectel_eg25_g_periodic_chat_script, NULL)
2449 
2450 #define MODEM_CELLULAR_DEVICE_SIMCOM_SIM7080(inst)                                                 \
2451 	MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64);                 \
2452                                                                                                    \
2453 	static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = {                 \
2454 		.chat_delimiter = "\r",                                                            \
2455 		.chat_filter = "\n",                                                               \
2456 		.ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst),                                       \
2457 	};                                                                                         \
2458                                                                                                    \
2459 	MODEM_CELLULAR_DEFINE_AND_INIT_USER_PIPES(inst,                                            \
2460 						  (user_pipe_0, 3),                                \
2461 						  (user_pipe_1, 4))                                \
2462                                                                                                    \
2463 	MODEM_CELLULAR_DEFINE_INSTANCE(inst, 1500, 100, 10000, 5000, false,                        \
2464 				       NULL,                                                       \
2465 				       &simcom_sim7080_init_chat_script,                           \
2466 				       &simcom_sim7080_dial_chat_script,                           \
2467 				       &simcom_sim7080_periodic_chat_script, NULL)
2468 
2469 #define MODEM_CELLULAR_DEVICE_U_BLOX_SARA_R4(inst)                                                 \
2470 	MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64);                 \
2471                                                                                                    \
2472 	static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = {                 \
2473 		.chat_delimiter = "\r",                                                            \
2474 		.chat_filter = "\n",                                                               \
2475 		.ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst),                                       \
2476 	};                                                                                         \
2477                                                                                                    \
2478 	MODEM_CELLULAR_DEFINE_AND_INIT_USER_PIPES(inst,                                            \
2479 						  (gnss_pipe, 3),                                  \
2480 						  (user_pipe_0, 4))                                \
2481                                                                                                    \
2482 	MODEM_CELLULAR_DEFINE_INSTANCE(inst, 1500, 100, 10000, 5000, false,                        \
2483 				       NULL,                                                       \
2484 				       &u_blox_sara_r4_init_chat_script,                           \
2485 				       &u_blox_sara_r4_dial_chat_script,                           \
2486 				       &u_blox_sara_r4_periodic_chat_script, NULL)
2487 
2488 #define MODEM_CELLULAR_DEVICE_U_BLOX_SARA_R5(inst)                                                 \
2489 	MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64);                 \
2490                                                                                                    \
2491 	static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = {                 \
2492 		.chat_delimiter = "\r",                                                            \
2493 		.chat_filter = "\n",                                                               \
2494 		.ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst),                                       \
2495 	};                                                                                         \
2496                                                                                                    \
2497 	MODEM_CELLULAR_DEFINE_AND_INIT_USER_PIPES(inst,                                            \
2498 						  (gnss_pipe, 4),                                  \
2499 						  (user_pipe_0, 3))                                \
2500                                                                                                    \
2501 	MODEM_CELLULAR_DEFINE_INSTANCE(inst, 1500, 100, 1500, 13000, true,                         \
2502 				       NULL,                                                       \
2503 				       &u_blox_sara_r5_init_chat_script,                           \
2504 				       &u_blox_sara_r5_dial_chat_script,                           \
2505 				       &u_blox_sara_r5_periodic_chat_script, NULL)
2506 
2507 #define MODEM_CELLULAR_DEVICE_U_BLOX_LARA_R6(inst)                                                 \
2508 	MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64);                 \
2509                                                                                                    \
2510 	static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = {                 \
2511 		.chat_delimiter = "\r",                                                            \
2512 		.chat_filter = "\n",                                                               \
2513 		.ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst),                                       \
2514 	};                                                                                         \
2515                                                                                                    \
2516 	MODEM_CELLULAR_DEFINE_AND_INIT_USER_PIPES(inst,                                            \
2517 						  (gnss_pipe, 3),                                  \
2518 						  (user_pipe_0, 4))                                \
2519                                                                                                    \
2520 	MODEM_CELLULAR_DEFINE_INSTANCE(inst, 1500, 100, 9000, 5000, false,                         \
2521 				       &u_blox_lara_r6_set_baudrate_chat_script,                   \
2522 				       &u_blox_lara_r6_init_chat_script,                           \
2523 				       &u_blox_lara_r6_dial_chat_script,                           \
2524 				       &u_blox_lara_r6_periodic_chat_script,                       \
2525 				       NULL)
2526 
2527 #define MODEM_CELLULAR_DEVICE_SWIR_HL7800(inst)                                                    \
2528 	MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64);                 \
2529                                                                                                    \
2530 	static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = {                 \
2531 		.chat_delimiter = "\r",                                                            \
2532 		.chat_filter = "\n",                                                               \
2533 		.ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst),                                       \
2534 	};                                                                                         \
2535                                                                                                    \
2536 	MODEM_CELLULAR_DEFINE_AND_INIT_USER_PIPES(inst,                                            \
2537 						  (user_pipe_0, 3),                                \
2538 						  (user_pipe_1, 4))                                \
2539                                                                                                    \
2540 	MODEM_CELLULAR_DEFINE_INSTANCE(inst, 1500, 100, 10000, 5000, false,                        \
2541 				       NULL,                                                       \
2542 				       &swir_hl7800_init_chat_script,                              \
2543 				       &swir_hl7800_dial_chat_script,                              \
2544 				       &swir_hl7800_periodic_chat_script, NULL)
2545 
2546 #define MODEM_CELLULAR_DEVICE_TELIT_ME910G1(inst)                                                  \
2547 	MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64);                 \
2548                                                                                                    \
2549 	static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = {                 \
2550 		.chat_delimiter = "\r",                                                            \
2551 		.chat_filter = "\n",                                                               \
2552 		.ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst),                                       \
2553 	};                                                                                         \
2554                                                                                                    \
2555 	MODEM_CELLULAR_DEFINE_AND_INIT_USER_PIPES(inst,                                            \
2556 						  (user_pipe_0, 3))                                \
2557                                                                                                    \
2558 	MODEM_CELLULAR_DEFINE_INSTANCE(inst, 5050, 250, 15000, 5000, false,                        \
2559 				       NULL,                                                       \
2560 				       &telit_mex10g1_init_chat_script,                            \
2561 				       &telit_mex10g1_dial_chat_script,                            \
2562 				       &telit_mex10g1_periodic_chat_script,                        \
2563 				       NULL)
2564 
2565 #define MODEM_CELLULAR_DEVICE_TELIT_ME310G1(inst)                                                  \
2566 	MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64);                 \
2567                                                                                                    \
2568 	static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = {                 \
2569 		.chat_delimiter = "\r",                                                            \
2570 		.chat_filter = "\n",                                                               \
2571 		.ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst),                                       \
2572 	};                                                                                         \
2573                                                                                                    \
2574 	MODEM_CELLULAR_DEFINE_AND_INIT_USER_PIPES(inst,                                            \
2575 						  (user_pipe_0, 3))                                \
2576                                                                                                    \
2577 	MODEM_CELLULAR_DEFINE_INSTANCE(inst, 5050, 0 /* unused */, 1000, 15000, false,             \
2578 				       NULL,                                                       \
2579 				       &telit_mex10g1_init_chat_script,                            \
2580 				       &telit_mex10g1_dial_chat_script,                            \
2581 				       &telit_mex10g1_periodic_chat_script,                        \
2582 				       &telit_me310g1_shutdown_chat_script)
2583 
2584 #define MODEM_CELLULAR_DEVICE_NORDIC_NRF91_SLM(inst)						   \
2585 	MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 1500);               \
2586                                                                                                    \
2587 	static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = {                 \
2588 		.chat_delimiter = "\r\n",                                                          \
2589 		.ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst),                                       \
2590 	};                                                                                         \
2591                                                                                                    \
2592 	MODEM_CELLULAR_DEFINE_AND_INIT_USER_PIPES(inst,                                            \
2593 						  (gnss_pipe, 3))                                  \
2594                                                                                                    \
2595 	MODEM_CELLULAR_DEFINE_INSTANCE(inst, 100, 100, 2000, 10000, false,                         \
2596 				       NULL,                                                       \
2597 				       &nordic_nrf91_slm_init_chat_script,                         \
2598 				       &nordic_nrf91_slm_dial_chat_script,                         \
2599 				       &nordic_nrf91_slm_periodic_chat_script, NULL)
2600 
2601 #define MODEM_CELLULAR_DEVICE_SQN_GM02S(inst)                                                      \
2602 	MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64);                 \
2603                                                                                                    \
2604 	static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = {                 \
2605 		.chat_delimiter = "\r",                                                            \
2606 		.chat_filter = "\n",                                                               \
2607 		.ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst),                                       \
2608 	};                                                                                         \
2609                                                                                                    \
2610 	MODEM_CELLULAR_DEFINE_AND_INIT_USER_PIPES(inst,                                            \
2611 						  (user_pipe_0, 3),                                \
2612 						  (user_pipe_1, 4))                                \
2613                                                                                                    \
2614 	MODEM_CELLULAR_DEFINE_INSTANCE(inst, 1500, 100, 2000, 5000, true,                          \
2615 				       NULL,                                                       \
2616 				       &sqn_gm02s_init_chat_script,                                \
2617 				       &sqn_gm02s_dial_chat_script,                                \
2618 				       &sqn_gm02s_periodic_chat_script, NULL)
2619 
2620 #define DT_DRV_COMPAT quectel_bg95
2621 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_QUECTEL_BG95)
2622 #undef DT_DRV_COMPAT
2623 
2624 #define DT_DRV_COMPAT quectel_eg25_g
2625 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_QUECTEL_EG25_G)
2626 #undef DT_DRV_COMPAT
2627 
2628 #define DT_DRV_COMPAT simcom_sim7080
2629 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_SIMCOM_SIM7080)
2630 #undef DT_DRV_COMPAT
2631 
2632 #define DT_DRV_COMPAT u_blox_sara_r4
2633 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_U_BLOX_SARA_R4)
2634 #undef DT_DRV_COMPAT
2635 
2636 #define DT_DRV_COMPAT u_blox_sara_r5
2637 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_U_BLOX_SARA_R5)
2638 #undef DT_DRV_COMPAT
2639 
2640 #define DT_DRV_COMPAT u_blox_lara_r6
2641 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_U_BLOX_LARA_R6)
2642 #undef DT_DRV_COMPAT
2643 
2644 #define DT_DRV_COMPAT swir_hl7800
2645 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_SWIR_HL7800)
2646 #undef DT_DRV_COMPAT
2647 
2648 #define DT_DRV_COMPAT telit_me910g1
2649 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_TELIT_ME910G1)
2650 #undef DT_DRV_COMPAT
2651 
2652 #define DT_DRV_COMPAT telit_me310g1
2653 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_TELIT_ME310G1)
2654 #undef DT_DRV_COMPAT
2655 
2656 #define DT_DRV_COMPAT nordic_nrf91_slm
2657 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_NORDIC_NRF91_SLM)
2658 #undef DT_DRV_COMPAT
2659 
2660 #define DT_DRV_COMPAT sqn_gm02s
2661 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_SQN_GM02S)
2662 #undef DT_DRV_COMPAT
2663