12 #ifndef ZEPHYR_INCLUDE_DRIVERS_CELLULAR_INTERNAL_H_
13 #define ZEPHYR_INCLUDE_DRIVERS_CELLULAR_INTERNAL_H_
46#define MODEM_CELLULAR_DATA_IMEI_LEN (16)
47#define MODEM_CELLULAR_DATA_MODEL_ID_LEN (65)
48#define MODEM_CELLULAR_DATA_IMSI_LEN (23)
49#define MODEM_CELLULAR_DATA_ICCID_LEN (22)
50#define MODEM_CELLULAR_DATA_MANUFACTURER_LEN (65)
51#define MODEM_CELLULAR_DATA_FW_VERSION_LEN (65)
52#define MODEM_CELLULAR_DATA_APN_LEN (32)
53#define MODEM_CELLULAR_MAX_APN_CMDS (2)
54#define MODEM_CELLULAR_APN_BUF_SIZE (64)
60enum modem_cellular_state {
61 MODEM_CELLULAR_STATE_IDLE = 0,
62 MODEM_CELLULAR_STATE_RESET_PULSE,
63 MODEM_CELLULAR_STATE_AWAIT_RESET,
64 MODEM_CELLULAR_STATE_POWER_ON_PULSE,
65 MODEM_CELLULAR_STATE_AWAIT_POWER_ON,
66 MODEM_CELLULAR_STATE_SET_BAUDRATE,
67 MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT,
68 MODEM_CELLULAR_STATE_CONNECT_CMUX,
69 MODEM_CELLULAR_STATE_OPEN_DLCI1,
70 MODEM_CELLULAR_STATE_OPEN_DLCI2,
71 MODEM_CELLULAR_STATE_WAIT_FOR_APN,
72 MODEM_CELLULAR_STATE_RUN_APN_SCRIPT,
73 MODEM_CELLULAR_STATE_RUN_NETWORK_SCRIPT,
74 MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT,
75 MODEM_CELLULAR_STATE_AWAIT_REGISTERED,
76 MODEM_CELLULAR_STATE_REGISTERED,
77 MODEM_CELLULAR_STATE_AWAIT_PPP_DEAD,
78 MODEM_CELLULAR_STATE_INIT_POWER_OFF,
79 MODEM_CELLULAR_STATE_RUN_SHUTDOWN_SCRIPT,
80 MODEM_CELLULAR_STATE_POWER_OFF_PULSE,
81 MODEM_CELLULAR_STATE_AWAIT_POWER_OFF,
84enum modem_cellular_event {
85 MODEM_CELLULAR_EVENT_RESUME = 0,
86 MODEM_CELLULAR_EVENT_SUSPEND,
87 MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS,
88 MODEM_CELLULAR_EVENT_SCRIPT_FAILED,
89 MODEM_CELLULAR_EVENT_CMUX_CONNECTED,
90 MODEM_CELLULAR_EVENT_CMUX_DISCONNECTED,
91 MODEM_CELLULAR_EVENT_DLCI1_OPENED,
92 MODEM_CELLULAR_EVENT_DLCI2_OPENED,
93 MODEM_CELLULAR_EVENT_TIMEOUT,
94 MODEM_CELLULAR_EVENT_REGISTERED,
95 MODEM_CELLULAR_EVENT_DEREGISTERED,
96 MODEM_CELLULAR_EVENT_BUS_OPENED,
97 MODEM_CELLULAR_EVENT_BUS_CLOSED,
98 MODEM_CELLULAR_EVENT_PPP_DEAD,
99 MODEM_CELLULAR_EVENT_MODEM_READY,
100 MODEM_CELLULAR_EVENT_APN_SET,
101 MODEM_CELLULAR_EVENT_RING,
104struct modem_cellular_event_cb {
110struct modem_cellular_data {
112 struct modem_pipe *uart_pipe;
113 struct modem_backend_uart uart_backend;
114 uint8_t uart_backend_receive_buf[CONFIG_MODEM_CELLULAR_UART_BUFFER_SIZES];
115 uint8_t uart_backend_transmit_buf[CONFIG_MODEM_CELLULAR_UART_BUFFER_SIZES];
119 struct modem_cmux cmux;
120 uint8_t cmux_receive_buf[MODEM_CMUX_WORK_BUFFER_SIZE];
121 uint8_t cmux_transmit_buf[MODEM_CMUX_WORK_BUFFER_SIZE];
123 struct modem_cmux_dlci dlci1;
124 struct modem_cmux_dlci dlci2;
125 struct modem_pipe *dlci1_pipe;
126 struct modem_pipe *dlci2_pipe;
128 struct modem_pipe *cmd_pipe;
129 uint8_t dlci1_receive_buf[MODEM_CMUX_WORK_BUFFER_SIZE];
131 uint8_t dlci2_receive_buf[MODEM_CMUX_WORK_BUFFER_SIZE];
134 struct modem_chat chat;
135 uint8_t chat_receive_buf[CONFIG_MODEM_CELLULAR_CHAT_BUFFER_SIZE];
139 uint8_t script_failure_counter;
148 uint8_t imei[MODEM_CELLULAR_DATA_IMEI_LEN];
149 uint8_t model_id[MODEM_CELLULAR_DATA_MODEL_ID_LEN];
150 uint8_t imsi[MODEM_CELLULAR_DATA_IMSI_LEN];
151 uint8_t iccid[MODEM_CELLULAR_DATA_ICCID_LEN];
152 uint8_t manufacturer[MODEM_CELLULAR_DATA_MANUFACTURER_LEN];
153 uint8_t fw_version[MODEM_CELLULAR_DATA_FW_VERSION_LEN];
154 uint8_t apn[MODEM_CELLULAR_DATA_APN_LEN];
156 struct modem_chat_script_chat apn_chats[MODEM_CELLULAR_MAX_APN_CMDS];
157 struct modem_chat_script apn_script;
158 char apn_buf[MODEM_CELLULAR_MAX_APN_CMDS][MODEM_CELLULAR_APN_BUF_SIZE];
161 struct modem_ppp *ppp;
162 struct net_mgmt_event_callback net_mgmt_event_callback;
164 enum modem_cellular_state
state;
165 const struct device *dev;
166 struct k_work_delayable timeout_work;
169 struct k_sem suspended_sem;
172 struct k_work event_dispatch_work;
174 struct k_pipe event_pipe;
176 struct k_mutex api_lock;
177 struct modem_cellular_event_cb cb;
180 struct gpio_callback ring_gpio_cb;
183struct modem_cellular_user_pipe {
184 struct modem_cmux_dlci dlci;
188 struct modem_pipe *pipe;
189 struct modem_pipelink *pipelink;
205struct modem_cellular_config_scripts {
206 const struct modem_chat_script *set_baudrate;
207 const struct modem_chat_script *init;
208 const struct modem_chat_script *network;
209 const struct modem_chat_script *dial;
210 const struct modem_chat_script *periodic;
211 const struct modem_chat_script *
shutdown;
217struct modem_cellular_vendor_config {
218 struct modem_cellular_config_scripts scripts;
220 const struct modem_chat_match *matches;
228 bool force_autostart;
231struct modem_cellular_config {
232 const struct device *uart;
233 const struct modem_cellular_vendor_config *vendor;
234 struct gpio_dt_spec power_gpio;
235 struct gpio_dt_spec reset_gpio;
236 struct gpio_dt_spec wake_gpio;
237 struct gpio_dt_spec ring_gpio;
238 struct gpio_dt_spec dtr_gpio;
240 bool hold_reset_on_suspend;
241 bool reset_on_resume;
242 bool reset_on_recovery;
243 bool cmux_enable_runtime_power_save;
244 bool cmux_close_pipe_on_power_save;
245 bool use_default_pdp_context;
246 bool use_default_apn;
247 k_timeout_t cmux_idle_timeout;
248 struct modem_cellular_user_pipe *user_pipes;
255int modem_cellular_init(
const struct device *dev);
261void modem_cellular_emit_event(
struct modem_cellular_data *data,
enum cellular_event evt,
262 const void *payload);
264void modem_cellular_chat_callback_handler(
struct modem_chat *chat,
288void modem_cellular_chat_on_modem_ready(
struct modem_chat *chat,
char **argv,
uint16_t argc,
302#define MODEM_CELLULAR_INST_NAME(name, inst) \
303 CONCAT(name, _, DT_DRV_COMPAT, inst)
305#define MODEM_CELLULAR_DEFINE_USER_PIPE_DATA(inst, name, size) \
306 MODEM_PIPELINK_DT_INST_DEFINE(inst, name); \
307 static uint8_t MODEM_CELLULAR_INST_NAME(name, inst)[size] \
309#define MODEM_CELLULAR_INIT_USER_PIPE(_inst, _name, _dlci_address) \
311 .dlci_address = _dlci_address, \
312 .dlci_receive_buf = MODEM_CELLULAR_INST_NAME(_name, _inst), \
313 .dlci_receive_buf_size = sizeof(MODEM_CELLULAR_INST_NAME(_name, _inst)), \
314 .pipelink = MODEM_PIPELINK_DT_INST_GET(_inst, _name), \
317#define MODEM_CELLULAR_DEFINE_USER_PIPES(inst, ...) \
318 static struct modem_cellular_user_pipe MODEM_CELLULAR_INST_NAME(user_pipes, inst)[] = { \
322#define MODEM_CELLULAR_GET_USER_PIPES(inst) \
323 MODEM_CELLULAR_INST_NAME(user_pipes, inst)
326#define MODEM_CELLULAR_GET_PIPE_NAME_ARG(arg1, ...) arg1
329#define MODEM_CELLULAR_GET_DLCI_ADDRESS_ARG(arg1, arg2, ...) arg2
332#define MODEM_CELLULAR_DEFINE_USER_PIPE_DATA_HELPER(_args, inst) \
333 MODEM_CELLULAR_DEFINE_USER_PIPE_DATA(inst, \
334 MODEM_CELLULAR_GET_PIPE_NAME_ARG _args, \
335 CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES)
338#define MODEM_CELLULAR_INIT_USER_PIPE_HELPER(_args, inst) \
339 MODEM_CELLULAR_INIT_USER_PIPE(inst, \
340 MODEM_CELLULAR_GET_PIPE_NAME_ARG _args, \
341 MODEM_CELLULAR_GET_DLCI_ADDRESS_ARG _args)
347#define MODEM_CELLULAR_DEFINE_AND_INIT_USER_PIPES(inst, ...) \
348 FOR_EACH_FIXED_ARG(MODEM_CELLULAR_DEFINE_USER_PIPE_DATA_HELPER, \
349 (;), inst, __VA_ARGS__); \
350 MODEM_CELLULAR_DEFINE_USER_PIPES( \
352 FOR_EACH_FIXED_ARG(MODEM_CELLULAR_INIT_USER_PIPE_HELPER, \
353 (,), inst, __VA_ARGS__) \
357#define MODEM_CELLULAR_COMMON_CHAT_MATCHES() \
358 MODEM_CHAT_MATCH_DEFINE(ok_match, "OK", "", NULL); \
359 MODEM_CHAT_MATCHES_DEFINE(__maybe_unused allow_match, \
360 MODEM_CHAT_MATCH("OK", "", NULL), \
361 MODEM_CHAT_MATCH("ERROR", "", NULL)); \
362 MODEM_CHAT_MATCH_DEFINE(imei_match __maybe_unused, \
363 "", "", modem_cellular_chat_on_imei); \
364 MODEM_CHAT_MATCH_DEFINE(cgmm_match __maybe_unused, \
365 "", "", modem_cellular_chat_on_cgmm); \
366 MODEM_CHAT_MATCH_DEFINE(csq_match __maybe_unused, \
367 "+CSQ: ", ",", modem_cellular_chat_on_csq); \
368 MODEM_CHAT_MATCH_DEFINE(cesq_match __maybe_unused, \
369 "+CESQ: ", ",", modem_cellular_chat_on_cesq); \
370 MODEM_CHAT_MATCH_DEFINE(qccid_match __maybe_unused, \
371 "+QCCID: ", "", modem_cellular_chat_on_iccid); \
372 MODEM_CHAT_MATCH_DEFINE(iccid_match __maybe_unused, \
373 "+ICCID: ", "", modem_cellular_chat_on_iccid); \
374 MODEM_CHAT_MATCH_DEFINE(ccid_match __maybe_unused, \
375 "+CCID: ", "", modem_cellular_chat_on_iccid); \
376 MODEM_CHAT_MATCH_DEFINE(cimi_match __maybe_unused, \
377 "", "", modem_cellular_chat_on_imsi); \
378 MODEM_CHAT_MATCH_DEFINE(cgmi_match __maybe_unused, \
379 "", "", modem_cellular_chat_on_cgmi); \
380 MODEM_CHAT_MATCH_DEFINE(cgmr_match __maybe_unused, \
381 "", "", modem_cellular_chat_on_cgmr); \
382 MODEM_CHAT_MATCH_DEFINE(connect_match __maybe_unused, \
383 "CONNECT", "", NULL); \
384 MODEM_CHAT_MATCHES_DEFINE(__maybe_unused abort_matches, \
385 MODEM_CHAT_MATCH("ERROR", "", NULL)); \
386 MODEM_CHAT_MATCHES_DEFINE(__maybe_unused dial_abort_matches, \
387 MODEM_CHAT_MATCH("ERROR", "", NULL), \
388 MODEM_CHAT_MATCH("BUSY", "", NULL), \
389 MODEM_CHAT_MATCH("NO ANSWER", "", NULL), \
390 MODEM_CHAT_MATCH("NO CARRIER", "", NULL), \
391 MODEM_CHAT_MATCH("NO DIALTONE", "", NULL))
397#define MODEM_CELLULAR_COMMON_UNSOL_MATCHES \
398 MODEM_CHAT_MATCH("+CREG: ", ",", modem_cellular_chat_on_cxreg), \
399 MODEM_CHAT_MATCH("+CEREG: ", ",", modem_cellular_chat_on_cxreg), \
400 MODEM_CHAT_MATCH("+CGREG: ", ",", modem_cellular_chat_on_cxreg), \
401 MODEM_CHAT_MATCH("+CGEV: ", ",", modem_cellular_chat_on_cgev), \
402 MODEM_CHAT_MATCH("APP RDY", "", modem_cellular_chat_on_modem_ready), \
403 MODEM_CHAT_MATCH("Ready", "", modem_cellular_chat_on_modem_ready)
406#define MODEM_CELLULAR_DEFINE_INSTANCE(inst, vendor_config) \
407 BUILD_ASSERT(vendor_config != NULL, "vendor_config must be non-NULL"); \
408 static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \
409 .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \
410 .vendor = vendor_config, \
411 .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \
412 .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \
413 .wake_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_wake_gpios, {}), \
414 .ring_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_ring_gpios, {}), \
415 .dtr_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_dtr_gpios, {}), \
416 .autostarts = DT_INST_PROP(inst, autostarts), \
417 .hold_reset_on_suspend = \
418 DT_INST_ENUM_HAS_VALUE(inst, zephyr_mdm_reset_behavior, hold_on_suspend), \
419 .reset_on_resume = DT_INST_ENUM_HAS_VALUE(inst, zephyr_mdm_reset_behavior, \
421 .reset_on_recovery = DT_INST_ENUM_HAS_VALUE(inst, zephyr_mdm_reset_behavior, \
422 toggle_on_recovery), \
423 .cmux_enable_runtime_power_save = \
424 DT_INST_PROP_OR(inst, cmux_enable_runtime_power_save, 0), \
425 .cmux_close_pipe_on_power_save = \
426 DT_INST_PROP_OR(inst, cmux_close_pipe_on_power_save, 0), \
427 .use_default_pdp_context = DT_INST_PROP_OR(inst, zephyr_use_default_pdp_ctx, 0), \
428 .use_default_apn = DT_INST_PROP_OR(inst, zephyr_use_default_apn, 0), \
429 .cmux_idle_timeout = K_MSEC(DT_INST_PROP_OR(inst, cmux_idle_timeout_ms, 0)), \
430 .user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst), \
431 .user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)), \
434 PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \
436 DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst), \
437 &MODEM_CELLULAR_INST_NAME(data, inst), \
438 &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, \
439 CONFIG_MODEM_CELLULAR_INIT_PRIORITY, &modem_cellular_api);
Main header file for cellular modem driver API.
Main header file for GPIO driver API.
Main header file for UART driver API.
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:147
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:176
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:211
Runtime device structure (in ROM) per driver instance.
Definition device.h:513
Chat instance internal context.
Definition chat.h:223