Skip to content

Commit 4905530

Browse files
Merge pull request zephyrproject-rtos#6 from converge-io/david/fix_cfun
David/fix cfun
2 parents caafb8c + b5c0e2a commit 4905530

File tree

3 files changed

+394
-25
lines changed

3 files changed

+394
-25
lines changed

drivers/modem/modem_cellular.c

Lines changed: 192 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <zephyr/kernel.h>
88
#include <zephyr/device.h>
99
#include <zephyr/drivers/gpio.h>
10+
#include <zephyr/drivers/cellular.h>
1011
#include <zephyr/modem/chat.h>
1112
#include <zephyr/modem/cmux.h>
1213
#include <zephyr/modem/pipe.h>
@@ -84,11 +85,16 @@ struct modem_cellular_data {
8485
uint8_t *chat_argv[32];
8586

8687
/* Status */
87-
uint8_t imei[15];
88-
uint8_t hwinfo[64];
8988
uint8_t registration_status_gsm;
9089
uint8_t registration_status_gprs;
9190
uint8_t registration_status_lte;
91+
int8_t rssi;
92+
uint8_t imei[15];
93+
uint8_t model_id[64];
94+
uint8_t imsi[15];
95+
uint8_t iccid[22];
96+
uint8_t manufacturer[64];
97+
uint8_t fw_version[64];
9298

9399
/* PPP */
94100
struct modem_ppp *ppp;
@@ -120,6 +126,7 @@ struct modem_cellular_config {
120126
const struct modem_chat_script *dial_chat_script;
121127
const struct modem_chat_script *periodic_chat_script;
122128
const struct modem_chat_script *power_down_script;
129+
const struct modem_chat_script *get_signal_chat_script;
123130
};
124131

125132
static const char *modem_cellular_state_str(enum modem_cellular_state state)
@@ -280,16 +287,34 @@ static void modem_cellular_chat_on_imei(struct modem_chat *chat, char **argv, ui
280287
return;
281288
}
282289

283-
if (strlen(argv[1]) != 15) {
290+
strncpy(data->imei, argv[1], sizeof(data->imei));
291+
}
292+
293+
static void modem_cellular_chat_on_cgmm(struct modem_chat *chat, char **argv, uint16_t argc,
294+
void *user_data)
295+
{
296+
struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
297+
298+
if (argc != 2) {
284299
return;
285300
}
286301

287-
for (uint8_t i = 0; i < 15; i++) {
288-
data->imei[i] = argv[1][i] - '0';
302+
strncpy(data->model_id, argv[1], sizeof(data->model_id));
303+
}
304+
305+
static void modem_cellular_chat_on_cgmi(struct modem_chat *chat, char **argv, uint16_t argc,
306+
void *user_data)
307+
{
308+
struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
309+
310+
if (argc != 2) {
311+
return;
289312
}
313+
314+
strncpy(data->manufacturer, argv[1], sizeof(data->manufacturer));
290315
}
291316

292-
static void modem_cellular_chat_on_cgmm(struct modem_chat *chat, char **argv, uint16_t argc,
317+
static void modem_cellular_chat_on_cgmr(struct modem_chat *chat, char **argv, uint16_t argc,
293318
void *user_data)
294319
{
295320
struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
@@ -298,7 +323,48 @@ static void modem_cellular_chat_on_cgmm(struct modem_chat *chat, char **argv, ui
298323
return;
299324
}
300325

301-
strncpy(data->hwinfo, argv[1], sizeof(data->hwinfo) - 1);
326+
strncpy(data->fw_version, argv[1], sizeof(data->fw_version));
327+
}
328+
329+
static void modem_cellular_chat_on_csq(struct modem_chat *chat, char **argv, uint16_t argc,
330+
void *user_data)
331+
{
332+
/* AT+CSQ returns a response +CSQ: <rssi>,<ber> where:
333+
* - rssi is a integer from 0 to 31 whose values describes a signal strength
334+
* between -113 dBm for 0 and -51dbM for 31 or unknown for 99
335+
* - ber is an integer from 0 to 7 that describes the error rate, it can also
336+
* be 99 for an unknown error rate
337+
*/
338+
struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
339+
340+
if (argc != 3) {
341+
return;
342+
}
343+
344+
/* Read rssi */
345+
uint8_t rssi = atoi(argv[1]);
346+
347+
if (rssi == 99) {
348+
return;
349+
}
350+
351+
data->rssi = (-113 + (2 * rssi));
352+
}
353+
354+
static void modem_cellular_chat_on_imsi(struct modem_chat *chat, char **argv, uint16_t argc,
355+
void *user_data)
356+
{
357+
struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
358+
359+
strncpy(data->imsi, (char *)argv[1], sizeof(data->imsi));
360+
}
361+
362+
static void modem_cellular_chat_on_iccid(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+
strncpy(data->iccid, (char *)argv[1], sizeof(data->iccid));
302368
}
303369

304370
static bool modem_cellular_is_registered(struct modem_cellular_data *data)
@@ -350,6 +416,11 @@ MODEM_CHAT_MATCHES_DEFINE(allow_match,
350416

351417
MODEM_CHAT_MATCH_DEFINE(imei_match, "", "", modem_cellular_chat_on_imei);
352418
MODEM_CHAT_MATCH_DEFINE(cgmm_match, "", "", modem_cellular_chat_on_cgmm);
419+
MODEM_CHAT_MATCH_DEFINE(csq_match, "+CSQ: ", ",", modem_cellular_chat_on_csq);
420+
MODEM_CHAT_MATCH_DEFINE(cimi_match, "", "", modem_cellular_chat_on_imsi);
421+
MODEM_CHAT_MATCH_DEFINE(ccid_match, "+QCCID: ", "", modem_cellular_chat_on_iccid);
422+
MODEM_CHAT_MATCH_DEFINE(cgmi_match, "", "", modem_cellular_chat_on_cgmi);
423+
MODEM_CHAT_MATCH_DEFINE(cgmr_match, "", "", modem_cellular_chat_on_cgmr);
353424

354425
MODEM_CHAT_MATCHES_DEFINE(unsol_matches,
355426
MODEM_CHAT_MATCH("+CREG: ", ",", modem_cellular_chat_on_cxreg),
@@ -1371,6 +1442,14 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_bg95_init_chat_script_cmds,
13711442
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
13721443
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
13731444
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1445+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMI", cgmi_match),
1446+
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1447+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match),
1448+
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1449+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CIMI", cimi_match),
1450+
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1451+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+QCCID", ccid_match),
1452+
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
13741453
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127", 300));
13751454

13761455
MODEM_CHAT_SCRIPT_DEFINE(quectel_bg95_init_chat_script, quectel_bg95_init_chat_script_cmds,
@@ -1390,29 +1469,38 @@ MODEM_CHAT_SCRIPT_DEFINE(quectel_bg95_dial_chat_script, quectel_bg95_dial_chat_s
13901469
MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_bg95_periodic_chat_script_cmds,
13911470
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
13921471
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1393-
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match));
1472+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
1473+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CSQ", csq_match));
13941474

13951475
MODEM_CHAT_SCRIPT_DEFINE(quectel_bg95_periodic_chat_script,
13961476
quectel_bg95_periodic_chat_script_cmds, abort_matches,
13971477
modem_cellular_chat_callback_handler, 4);
13981478
#endif
13991479

14001480
#if DT_HAS_COMPAT_STATUS_OKAY(quectel_eg25_g)
1401-
MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_eg25_g_init_chat_script_cmds,
1402-
MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
1403-
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
1404-
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
1405-
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
1406-
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match),
1407-
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
1408-
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1409-
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1410-
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
1411-
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
1412-
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1413-
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
1414-
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2",
1415-
100));
1481+
MODEM_CHAT_SCRIPT_CMDS_DEFINE(
1482+
quectel_eg25_g_init_chat_script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
1483+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
1484+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
1485+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
1486+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match),
1487+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
1488+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1489+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1490+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
1491+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
1492+
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1493+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
1494+
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1495+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMI", cgmi_match),
1496+
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1497+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match),
1498+
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1499+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CIMI", cimi_match),
1500+
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1501+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+QCCID", ccid_match),
1502+
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1503+
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2", 100));
14161504

14171505
MODEM_CHAT_SCRIPT_DEFINE(quectel_eg25_g_init_chat_script, quectel_eg25_g_init_chat_script_cmds,
14181506
abort_matches, modem_cellular_chat_callback_handler, 10);
@@ -1429,7 +1517,7 @@ MODEM_CHAT_SCRIPT_DEFINE(quectel_eg25_g_dial_chat_script, quectel_eg25_g_dial_ch
14291517
dial_abort_matches, modem_cellular_chat_callback_handler, 10);
14301518

14311519
MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_eg25_g_power_down_script_cmds,
1432-
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
1520+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=0", ok_match),
14331521
MODEM_CHAT_SCRIPT_CMD_RESP("AT+QSCLK=1", ok_match),);
14341522

14351523
MODEM_CHAT_SCRIPT_DEFINE(quectel_eg25_g_power_down_script, quectel_eg25_g_power_down_script_cmds,
@@ -1438,11 +1526,19 @@ MODEM_CHAT_SCRIPT_DEFINE(quectel_eg25_g_power_down_script, quectel_eg25_g_power_
14381526
MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_eg25_g_periodic_chat_script_cmds,
14391527
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
14401528
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1441-
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match));
1529+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
1530+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CSQ", csq_match));
14421531

14431532
MODEM_CHAT_SCRIPT_DEFINE(quectel_eg25_g_periodic_chat_script,
14441533
quectel_eg25_g_periodic_chat_script_cmds, abort_matches,
14451534
modem_cellular_chat_callback_handler, 4);
1535+
1536+
MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_eg25_g_get_signal_chat_script_cmds,
1537+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CSQ", csq_match));
1538+
1539+
MODEM_CHAT_SCRIPT_DEFINE(quectel_eg25_g_get_signal_chat_script,
1540+
quectel_eg25_g_get_signal_chat_script_cmds, abort_matches,
1541+
modem_cellular_chat_callback_handler, 4);
14461542
#endif
14471543

14481544
#if DT_HAS_COMPAT_STATUS_OKAY(zephyr_gsm_ppp)
@@ -1697,6 +1793,7 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_dial_chat_script, telit_me910g1_dial_chat
16971793
.init_chat_script = &quectel_bg95_init_chat_script, \
16981794
.dial_chat_script = &quectel_bg95_dial_chat_script, \
16991795
.periodic_chat_script = &_CONCAT(DT_DRV_COMPAT, _periodic_chat_script), \
1796+
.get_signal_chat_script = &_CONCAT(DT_DRV_COMPAT, _get_signal_chat_script), \
17001797
}; \
17011798
\
17021799
PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \
@@ -1727,6 +1824,7 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_dial_chat_script, telit_me910g1_dial_chat
17271824
.dial_chat_script = &quectel_eg25_g_dial_chat_script, \
17281825
.periodic_chat_script = &_CONCAT(DT_DRV_COMPAT, _periodic_chat_script), \
17291826
.power_down_script = &quectel_eg25_g_power_down_script, \
1827+
.get_signal_chat_script = &_CONCAT(DT_DRV_COMPAT, _get_signal_chat_script), \
17301828
}; \
17311829
\
17321830
PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \
@@ -1903,3 +2001,72 @@ DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_SWIR_HL7800)
19032001
#define DT_DRV_COMPAT telit_me910g1
19042002
DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_TELIT_ME910G1)
19052003
#undef DT_DRV_COMPAT
2004+
2005+
int cellular_get_modem_info(const struct device *dev, enum cellular_modem_info_type type,
2006+
char *info, size_t size)
2007+
{
2008+
int ret = 0;
2009+
2010+
struct modem_cellular_data *data = (struct modem_cellular_data *)dev->data;
2011+
2012+
switch (type) {
2013+
case CELLULAR_MODEM_INFO_IMEI:
2014+
strncpy(info, &data->imei[0], MIN(size, sizeof(data->imei)));
2015+
break;
2016+
case CELLULAR_MODEM_INFO_SIM_IMSI:
2017+
strncpy(info, &data->imsi[0], MIN(size, sizeof(data->imsi)));
2018+
break;
2019+
case CELLULAR_MODEM_INFO_SIM_ICCID:
2020+
strncpy(info, &data->iccid[0], MIN(size, sizeof(data->iccid)));
2021+
break;
2022+
case CELLULAR_MODEM_INFO_MANUFACTURER:
2023+
strncpy(info, &data->manufacturer[0], MIN(size, sizeof(data->manufacturer)));
2024+
break;
2025+
case CELLULAR_MODEM_INFO_FW_VERSION:
2026+
strncpy(info, &data->fw_version[0], MIN(size, sizeof(data->fw_version)));
2027+
break;
2028+
case CELLULAR_MODEM_INFO_MODEL_ID:
2029+
strncpy(info, &data->model_id[0], MIN(size, sizeof(data->model_id)));
2030+
break;
2031+
default:
2032+
ret = -ENODATA;
2033+
break;
2034+
}
2035+
2036+
return ret;
2037+
}
2038+
2039+
int cellular_get_signal(const struct device *dev, const enum cellular_signal_type type,
2040+
int16_t *value)
2041+
{
2042+
int ret = 0;
2043+
2044+
struct modem_cellular_data *data = (struct modem_cellular_data *)dev->data;
2045+
const struct modem_cellular_config *config = (struct modem_cellular_config *)dev->config;
2046+
2047+
if (config->get_signal_chat_script == NULL) {
2048+
return -ENOTSUP;
2049+
}
2050+
2051+
if ((data->state != MODEM_CELLULAR_STATE_AWAIT_REGISTERED) &&
2052+
(data->state != MODEM_CELLULAR_STATE_CARRIER_ON)) {
2053+
return -ENODATA;
2054+
}
2055+
2056+
ret = modem_chat_run_script(&data->chat, config->get_signal_chat_script);
2057+
if (ret != 0) {
2058+
return ret;
2059+
}
2060+
2061+
switch (type) {
2062+
case CELLULAR_SIGNAL_RSSI: {
2063+
*value = data->rssi;
2064+
} break;
2065+
case CELLULAR_SIGNAL_RSRP:
2066+
return -ENOTSUP;
2067+
case CELLULAR_SIGNAL_RSRQ:
2068+
return -ENOTSUP;
2069+
}
2070+
2071+
return ret;
2072+
}

0 commit comments

Comments
 (0)