12 #ifndef ZEPHYR_INCLUDE_DRIVERS_CELLULAR_INTERNAL_H_
13 #define ZEPHYR_INCLUDE_DRIVERS_CELLULAR_INTERNAL_H_
47#define MODEM_CELLULAR_DATA_IMEI_LEN (16)
48#define MODEM_CELLULAR_DATA_MODEL_ID_LEN (65)
49#define MODEM_CELLULAR_DATA_IMSI_LEN (23)
50#define MODEM_CELLULAR_DATA_ICCID_LEN (22)
51#define MODEM_CELLULAR_DATA_MANUFACTURER_LEN (65)
52#define MODEM_CELLULAR_DATA_FW_VERSION_LEN (65)
53#define MODEM_CELLULAR_DATA_APN_LEN (32)
54#define MODEM_CELLULAR_MAX_APN_CMDS (2)
55#define MODEM_CELLULAR_APN_BUF_SIZE (64)
61enum modem_cellular_state {
62 MODEM_CELLULAR_STATE_IDLE = 0,
63 MODEM_CELLULAR_STATE_RESET_PULSE,
64 MODEM_CELLULAR_STATE_AWAIT_RESET,
65 MODEM_CELLULAR_STATE_POWER_ON_PULSE,
66 MODEM_CELLULAR_STATE_AWAIT_POWER_ON,
67 MODEM_CELLULAR_STATE_SET_BAUDRATE,
68 MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT,
69 MODEM_CELLULAR_STATE_CONNECT_CMUX,
70 MODEM_CELLULAR_STATE_OPEN_DLCI1,
71 MODEM_CELLULAR_STATE_OPEN_DLCI2,
72 MODEM_CELLULAR_STATE_WAIT_FOR_APN,
73 MODEM_CELLULAR_STATE_RUN_APN_SCRIPT,
74 MODEM_CELLULAR_STATE_RUN_NETWORK_SCRIPT,
75 MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT,
76 MODEM_CELLULAR_STATE_AWAIT_REGISTERED,
77 MODEM_CELLULAR_STATE_REGISTERED,
78 MODEM_CELLULAR_STATE_AWAIT_PPP_DEAD,
79 MODEM_CELLULAR_STATE_INIT_POWER_OFF,
80 MODEM_CELLULAR_STATE_RUN_SHUTDOWN_SCRIPT,
81 MODEM_CELLULAR_STATE_POWER_OFF_PULSE,
82 MODEM_CELLULAR_STATE_AWAIT_POWER_OFF,
85enum modem_cellular_event {
86 MODEM_CELLULAR_EVENT_RESUME = 0,
87 MODEM_CELLULAR_EVENT_SUSPEND,
88 MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS,
89 MODEM_CELLULAR_EVENT_SCRIPT_FAILED,
90 MODEM_CELLULAR_EVENT_CMUX_CONNECTED,
91 MODEM_CELLULAR_EVENT_CMUX_DISCONNECTED,
92 MODEM_CELLULAR_EVENT_DLCI1_OPENED,
93 MODEM_CELLULAR_EVENT_DLCI2_OPENED,
94 MODEM_CELLULAR_EVENT_TIMEOUT,
95 MODEM_CELLULAR_EVENT_REGISTERED,
96 MODEM_CELLULAR_EVENT_DEREGISTERED,
97 MODEM_CELLULAR_EVENT_BUS_OPENED,
98 MODEM_CELLULAR_EVENT_BUS_CLOSED,
99 MODEM_CELLULAR_EVENT_PPP_DEAD,
100 MODEM_CELLULAR_EVENT_MODEM_READY,
101 MODEM_CELLULAR_EVENT_APN_SET,
102 MODEM_CELLULAR_EVENT_RING,
103 MODEM_CELLULAR_EVENT_PERIODIC_KICK,
106struct modem_cellular_event_cb {
112struct modem_cellular_data {
114 struct modem_pipe *uart_pipe;
115 struct modem_backend_uart uart_backend;
116 uint8_t uart_backend_receive_buf[CONFIG_MODEM_CELLULAR_UART_BUFFER_SIZES];
117 uint8_t uart_backend_transmit_buf[CONFIG_MODEM_CELLULAR_UART_BUFFER_SIZES];
121 struct modem_cmux cmux;
122 uint8_t cmux_receive_buf[MODEM_CMUX_WORK_BUFFER_SIZE];
123 uint8_t cmux_transmit_buf[MODEM_CMUX_WORK_BUFFER_SIZE];
125 struct modem_cmux_dlci dlci1;
126 struct modem_cmux_dlci dlci2;
127 struct modem_pipe *dlci1_pipe;
128 struct modem_pipe *dlci2_pipe;
130 struct modem_pipe *cmd_pipe;
131 uint8_t dlci1_receive_buf[MODEM_CMUX_WORK_BUFFER_SIZE];
133 uint8_t dlci2_receive_buf[MODEM_CMUX_WORK_BUFFER_SIZE];
136 struct modem_chat chat;
137 uint8_t chat_receive_buf[CONFIG_MODEM_CELLULAR_CHAT_BUFFER_SIZE];
141 uint8_t script_failure_counter;
151 uint8_t imei[MODEM_CELLULAR_DATA_IMEI_LEN];
152 uint8_t model_id[MODEM_CELLULAR_DATA_MODEL_ID_LEN];
153 uint8_t imsi[MODEM_CELLULAR_DATA_IMSI_LEN];
154 uint8_t iccid[MODEM_CELLULAR_DATA_ICCID_LEN];
155 uint8_t manufacturer[MODEM_CELLULAR_DATA_MANUFACTURER_LEN];
156 uint8_t fw_version[MODEM_CELLULAR_DATA_FW_VERSION_LEN];
157 uint8_t apn[MODEM_CELLULAR_DATA_APN_LEN];
159 struct modem_chat_script_chat apn_chats[MODEM_CELLULAR_MAX_APN_CMDS];
160 struct modem_chat_script apn_script;
161 char apn_buf[MODEM_CELLULAR_MAX_APN_CMDS][MODEM_CELLULAR_APN_BUF_SIZE];
164 struct modem_ppp *ppp;
165 struct net_mgmt_event_callback net_mgmt_event_callback;
167 enum modem_cellular_state
state;
168 const struct device *dev;
169 struct k_work_delayable timeout_work;
172 struct k_sem suspended_sem;
175 struct k_work event_dispatch_work;
177 struct k_pipe event_pipe;
179 struct k_mutex api_lock;
180 struct modem_cellular_event_cb cb;
183 struct gpio_callback ring_gpio_cb;
188 bool periodic_timeout_skipped;
191struct modem_cellular_user_pipe {
192 struct modem_cmux_dlci dlci;
196 struct modem_pipe *pipe;
197 struct modem_pipelink *pipelink;
213struct modem_cellular_config_scripts {
214 const struct modem_chat_script *set_baudrate;
215 const struct modem_chat_script *init;
216 const struct modem_chat_script *network;
217 const struct modem_chat_script *dial;
218 const struct modem_chat_script *periodic;
219 const struct modem_chat_script *
shutdown;
225struct modem_cellular_vendor_config {
226 struct modem_cellular_config_scripts scripts;
228 const struct modem_chat_match *matches;
236 bool force_autostart;
239struct modem_cellular_config {
240 const struct device *uart;
241 const struct modem_cellular_vendor_config *vendor;
242 struct gpio_dt_spec power_gpio;
243 struct gpio_dt_spec reset_gpio;
244 struct gpio_dt_spec wake_gpio;
245 struct gpio_dt_spec ring_gpio;
246 struct gpio_dt_spec dtr_gpio;
248 bool hold_reset_on_suspend;
249 bool reset_on_resume;
250 bool reset_on_recovery;
251 bool cmux_enable_runtime_power_save;
252 bool cmux_close_pipe_on_power_save;
253 bool cmux_no_powersave_handshake;
254 bool use_default_pdp_context;
255 bool use_default_apn;
256 k_timeout_t cmux_idle_timeout;
257 struct modem_cellular_user_pipe *user_pipes;
264int modem_cellular_init(
const struct device *dev);
270void modem_cellular_emit_event(
struct modem_cellular_data *data,
enum cellular_event evt,
271 const void *payload);
273void modem_cellular_chat_callback_handler(
struct modem_chat *chat,
297void modem_cellular_chat_on_modem_ready(
struct modem_chat *chat,
char **argv,
uint16_t argc,
311#define MODEM_CELLULAR_INST_NAME(name, inst) \
312 CONCAT(name, _, DT_DRV_COMPAT, inst)
314#define MODEM_CELLULAR_DEFINE_USER_PIPE_DATA(inst, name, size) \
315 MODEM_PIPELINK_DT_INST_DEFINE(inst, name); \
316 static uint8_t MODEM_CELLULAR_INST_NAME(name, inst)[size] \
318#define MODEM_CELLULAR_INIT_USER_PIPE(_inst, _name, _dlci_address) \
320 .dlci_address = _dlci_address, \
321 .dlci_receive_buf = MODEM_CELLULAR_INST_NAME(_name, _inst), \
322 .dlci_receive_buf_size = sizeof(MODEM_CELLULAR_INST_NAME(_name, _inst)), \
323 .pipelink = MODEM_PIPELINK_DT_INST_GET(_inst, _name), \
326#define MODEM_CELLULAR_DEFINE_USER_PIPES(inst, ...) \
327 static struct modem_cellular_user_pipe MODEM_CELLULAR_INST_NAME(user_pipes, inst)[] = { \
331#define MODEM_CELLULAR_GET_USER_PIPES(inst) \
332 MODEM_CELLULAR_INST_NAME(user_pipes, inst)
335#define MODEM_CELLULAR_GET_PIPE_NAME_ARG(arg1, ...) arg1
338#define MODEM_CELLULAR_GET_DLCI_ADDRESS_ARG(arg1, arg2, ...) arg2
341#define MODEM_CELLULAR_DEFINE_USER_PIPE_DATA_HELPER(_args, inst) \
342 MODEM_CELLULAR_DEFINE_USER_PIPE_DATA(inst, \
343 MODEM_CELLULAR_GET_PIPE_NAME_ARG _args, \
344 CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES)
347#define MODEM_CELLULAR_INIT_USER_PIPE_HELPER(_args, inst) \
348 MODEM_CELLULAR_INIT_USER_PIPE(inst, \
349 MODEM_CELLULAR_GET_PIPE_NAME_ARG _args, \
350 MODEM_CELLULAR_GET_DLCI_ADDRESS_ARG _args)
356#define MODEM_CELLULAR_DEFINE_AND_INIT_USER_PIPES(inst, ...) \
357 FOR_EACH_FIXED_ARG(MODEM_CELLULAR_DEFINE_USER_PIPE_DATA_HELPER, \
358 (;), inst, __VA_ARGS__); \
359 MODEM_CELLULAR_DEFINE_USER_PIPES( \
361 FOR_EACH_FIXED_ARG(MODEM_CELLULAR_INIT_USER_PIPE_HELPER, \
362 (,), inst, __VA_ARGS__) \
366#define MODEM_CELLULAR_COMMON_CHAT_MATCHES() \
367 MODEM_CHAT_MATCH_DEFINE(ok_match, "OK", "", NULL); \
368 MODEM_CHAT_MATCHES_DEFINE(__maybe_unused allow_match, \
369 MODEM_CHAT_MATCH("OK", "", NULL), \
370 MODEM_CHAT_MATCH("ERROR", "", NULL)); \
371 MODEM_CHAT_MATCH_DEFINE(imei_match __maybe_unused, \
372 "", "", modem_cellular_chat_on_imei); \
373 MODEM_CHAT_MATCH_DEFINE(cgmm_match __maybe_unused, \
374 "", "", modem_cellular_chat_on_cgmm); \
375 MODEM_CHAT_MATCH_DEFINE(csq_match __maybe_unused, \
376 "+CSQ: ", ",", modem_cellular_chat_on_csq); \
377 MODEM_CHAT_MATCH_DEFINE(cesq_match __maybe_unused, \
378 "+CESQ: ", ",", modem_cellular_chat_on_cesq); \
379 MODEM_CHAT_MATCH_DEFINE(qccid_match __maybe_unused, \
380 "+QCCID: ", "", modem_cellular_chat_on_iccid); \
381 MODEM_CHAT_MATCH_DEFINE(iccid_match __maybe_unused, \
382 "+ICCID: ", "", modem_cellular_chat_on_iccid); \
383 MODEM_CHAT_MATCH_DEFINE(ccid_match __maybe_unused, \
384 "+CCID: ", "", modem_cellular_chat_on_iccid); \
385 MODEM_CHAT_MATCH_DEFINE(cimi_match __maybe_unused, \
386 "", "", modem_cellular_chat_on_imsi); \
387 MODEM_CHAT_MATCH_DEFINE(cgmi_match __maybe_unused, \
388 "", "", modem_cellular_chat_on_cgmi); \
389 MODEM_CHAT_MATCH_DEFINE(cgmr_match __maybe_unused, \
390 "", "", modem_cellular_chat_on_cgmr); \
391 MODEM_CHAT_MATCH_DEFINE(connect_match __maybe_unused, \
392 "CONNECT", "", NULL); \
393 MODEM_CHAT_MATCHES_DEFINE(__maybe_unused abort_matches, \
394 MODEM_CHAT_MATCH("ERROR", "", NULL)); \
395 MODEM_CHAT_MATCHES_DEFINE(__maybe_unused dial_abort_matches, \
396 MODEM_CHAT_MATCH("ERROR", "", NULL), \
397 MODEM_CHAT_MATCH("BUSY", "", NULL), \
398 MODEM_CHAT_MATCH("NO ANSWER", "", NULL), \
399 MODEM_CHAT_MATCH("NO CARRIER", "", NULL), \
400 MODEM_CHAT_MATCH("NO DIALTONE", "", NULL))
406#define MODEM_CELLULAR_COMMON_UNSOL_MATCHES \
407 MODEM_CHAT_MATCH("+CREG: ", ",", modem_cellular_chat_on_cxreg), \
408 MODEM_CHAT_MATCH("+CEREG: ", ",", modem_cellular_chat_on_cxreg), \
409 MODEM_CHAT_MATCH("+CGREG: ", ",", modem_cellular_chat_on_cxreg), \
410 MODEM_CHAT_MATCH("+CGEV: ", ",", modem_cellular_chat_on_cgev), \
411 MODEM_CHAT_MATCH("APP RDY", "", modem_cellular_chat_on_modem_ready), \
412 MODEM_CHAT_MATCH("Ready", "", modem_cellular_chat_on_modem_ready)
415#define MODEM_CELLULAR_DEFINE_INSTANCE(inst, vendor_config) \
416 BUILD_ASSERT(vendor_config != NULL, "vendor_config must be non-NULL"); \
417 static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \
418 .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \
419 .vendor = vendor_config, \
420 .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \
421 .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \
422 .wake_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_wake_gpios, {}), \
423 .ring_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_ring_gpios, {}), \
424 .dtr_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_dtr_gpios, {}), \
425 .autostarts = DT_INST_PROP(inst, autostarts), \
426 .hold_reset_on_suspend = \
427 DT_INST_ENUM_HAS_VALUE(inst, zephyr_mdm_reset_behavior, hold_on_suspend), \
428 .reset_on_resume = DT_INST_ENUM_HAS_VALUE(inst, zephyr_mdm_reset_behavior, \
430 .reset_on_recovery = DT_INST_ENUM_HAS_VALUE(inst, zephyr_mdm_reset_behavior, \
431 toggle_on_recovery), \
432 .cmux_enable_runtime_power_save = \
433 DT_INST_PROP_OR(inst, cmux_enable_runtime_power_save, 0), \
434 .cmux_close_pipe_on_power_save = \
435 DT_INST_PROP_OR(inst, cmux_close_pipe_on_power_save, 0), \
436 .cmux_no_powersave_handshake = \
437 DT_INST_PROP_OR(inst, cmux_no_powersave_handshake, 0), \
438 .use_default_pdp_context = DT_INST_PROP_OR(inst, zephyr_use_default_pdp_ctx, 0), \
439 .use_default_apn = DT_INST_PROP_OR(inst, zephyr_use_default_apn, 0), \
440 .cmux_idle_timeout = K_MSEC(DT_INST_PROP_OR(inst, cmux_idle_timeout_ms, 0)), \
441 .user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst), \
442 .user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)), \
445 PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \
447 DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst), \
448 &MODEM_CELLULAR_INST_NAME(data, inst), \
449 &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, \
450 CONFIG_MODEM_CELLULAR_INIT_PRIORITY, &modem_cellular_api);
Header file for the Atomic operations API.
Main header file for cellular modem driver API.
Main header file for GPIO driver API.
Main header file for UART driver API.
long atomic_t
Atomic integer variable.
Definition atomic_types.h:31
cellular_access_technology
Cellular access technologies (3GPP TS 27.007 AcT).
Definition cellular.h:33
cellular_event
Events emitted asynchronously by a cellular driver.
Definition cellular.h:137
cellular_registration_status
Cellular registration status (3GPP TS 27.007).
Definition cellular.h:109
uint32_t cellular_event_mask_t
Definition cellular.h:149
void(* cellular_event_cb_t)(const struct device *dev, enum cellular_event event, const void *payload, void *user_data)
Prototype for cellular event callbacks.
Definition cellular.h:202
int cellular_modem_pause_periodic_script(const struct device *dev)
Pause the cellular_modem driver's periodic chat script.
int cellular_modem_resume_periodic_script(const struct device *dev)
Resume the cellular_modem driver's periodic chat script.
modem_chat_script_result
Definition chat.h:156
pm_device_action
Device PM actions.
Definition device.h:144
state
Definition parser_state.h:29
int shutdown(int sock, int how)
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
__UINT8_TYPE__ uint8_t
Definition stdint.h:88
__UINT16_TYPE__ uint16_t
Definition stdint.h:89
Cellular driver API.
Definition cellular.h:237
Runtime device structure (in ROM) per driver instance.
Definition device.h:513
Chat instance internal context.
Definition chat.h:223