wavecom/sysmocom: use AT@COPS if available, instead of AT+COPS
In certain sysmocom proprietary versions of the wavecom modem, we have a non-blocking operator scan command called AT@COPS=?, which we can use instead of AT+COPS=?. The wavecom vendor plugin checks at start time if the command is available. If yes, iti s used in case a libgsm client is asking for an operator scan, instead of the standard AT+COPS=? variant.
This commit is contained in:
parent
58a9b679e9
commit
2aa67b809f
|
@ -24,6 +24,14 @@ extern int gsmd_vendor_plugin_register(struct gsmd_vendor_plugin *pl);
|
|||
extern void gsmd_vendor_plugin_unregister(struct gsmd_vendor_plugin *pl);
|
||||
extern int gsmd_vendor_plugin_find(struct gsmd *g);
|
||||
|
||||
/* should we use AT@COPS=? instead of AT+COPS=? */
|
||||
extern int g_use_ATatCOPS;
|
||||
/* the last user that requested an AT@COPS=? scan */
|
||||
extern struct gsmd_user *g_last_cops_user;
|
||||
extern int g_last_cops_id;
|
||||
struct gsmd_atcmd;
|
||||
int network_opers_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp);
|
||||
|
||||
#endif /* __GSMD__ */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1062,7 +1062,14 @@ static int network_opers_parse(const char *str, struct gsmd_msg_oper **out)
|
|||
return len;
|
||||
}
|
||||
|
||||
static int network_opers_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
|
||||
/* should we use AT@COPS=? instead of AT+COPS=? */
|
||||
int g_use_ATatCOPS;
|
||||
|
||||
/* the last user that requested an AT@COPS=? scan */
|
||||
struct gsmd_user *g_last_cops_user;
|
||||
int g_last_cops_id;
|
||||
|
||||
int network_opers_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
|
||||
{
|
||||
struct gsmd_user *gu = ctx;
|
||||
struct gsmd_msg_oper *buf = NULL;
|
||||
|
@ -1206,7 +1213,12 @@ static int usock_rcv_network(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
|
|||
cmd = atcmd_fill("AT+COPS?", 8+1, &network_oper_n_cb, gu, 0, NULL);
|
||||
break;
|
||||
case GSMD_NETWORK_OPER_LIST:
|
||||
cmd = atcmd_fill("AT+COPS=?", 9+1, &network_opers_cb, gu, 0, NULL);
|
||||
if (g_use_ATatCOPS) {
|
||||
g_last_cops_user = gu;
|
||||
g_last_cops_id = cmd->id;
|
||||
cmd = atcmd_fill("AT@COPS=?", 9+1, &network_opers_cb, gu, 0, NULL);
|
||||
} else
|
||||
cmd = atcmd_fill("AT+COPS=?", 9+1, &network_opers_cb, gu, 0, NULL);
|
||||
break;
|
||||
case GSMD_NETWORK_PREF_LIST:
|
||||
/* Set long alphanumeric format */
|
||||
|
|
|
@ -213,10 +213,34 @@ static int sais_parse(const char *buf, int len, const char *param,
|
|||
return 0;
|
||||
};
|
||||
|
||||
static int cops_parse(const char *buf, int len, const char *param,
|
||||
struct gsmd *gsmd)
|
||||
{
|
||||
struct gsmd_atcmd fake_atcmd;
|
||||
|
||||
if (!g_use_ATatCOPS)
|
||||
return 0;
|
||||
|
||||
if (!strcmp(buf, "+COPS: ERROR\r\n"))
|
||||
return 0;
|
||||
|
||||
if (!g_use_ATatCOPS || !g_last_cops_user)
|
||||
return 0;
|
||||
|
||||
fake_atcmd.id = g_last_cops_id;
|
||||
|
||||
network_opers_cb(&fake_atcmd, g_last_cops_user, buf);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
static const struct gsmd_unsolicit wavecom_unsolicit[] = {
|
||||
{ "+CCED", &cced_parse }, /* Cell Environment Report */
|
||||
{ "+SYSMOCOM_GPS", &sgps_parse },
|
||||
{ "+SYSMOCOM_AIS", &sais_parse },
|
||||
/* proprietary non-blocking response to AT@COPS=? */
|
||||
{ "+COPS", &cops_parse },
|
||||
};
|
||||
|
||||
static int wavecom_detect(struct gsmd *g)
|
||||
|
@ -225,6 +249,15 @@ static int wavecom_detect(struct gsmd *g)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int at_atcops_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
|
||||
{
|
||||
/* if the result is successful, at@cops is supported */
|
||||
if (cmd->ret == 0)
|
||||
g_use_ATatCOPS = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wavecom_initsettings(struct gsmd *g)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@ -255,6 +288,9 @@ static int wavecom_initsettings(struct gsmd *g)
|
|||
rc |= gsmd_simplecmd(g, "AT+WREGC=0");
|
||||
rc |= gsmd_simplecmd(g, "AT+CCED=1,3");
|
||||
|
||||
cmd = atcmd_fill("AT@COPS=?", 9+1, &at_atcops_cb, NULL, 0, NULL);
|
||||
rc |= atcmd_submit(g, cmd);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue