summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/atcmd.c88
-rw-r--r--src/atcmd.h4
-rw-r--r--src/global.h12
-rw-r--r--src/sms_main.c3
4 files changed, 98 insertions, 9 deletions
diff --git a/src/atcmd.c b/src/atcmd.c
index 595a91a..a216ab6 100644
--- a/src/atcmd.c
+++ b/src/atcmd.c
@@ -1229,8 +1229,7 @@ int atcmd_plus_gmm_read(int fd)
log_debug("atcmd_value_tok model");
return -1;
}
- free(Global.core.model);
- Global.core.model = strdup(token);
+ strncpy(Global.core.model, token, MODEL_LEN);
log_debug("model: %s", Global.core.model);
@@ -1243,6 +1242,49 @@ int atcmd_plus_gmm_read(int fd)
return 0;
}
+/* Manufacturer identification is needed to pick proper manufacturer-specific commands.
+ * For example, in atcmd_plus_iccid_read() function. */
+int atcmd_plus_gmi_read(int fd)
+{
+ char buf[ATCMD_LINE_SIZE];
+ char *save;
+ char *token;
+ int tmp;
+
+ atcmd_writeline(fd, "AT+GMI");
+ //Swallow extra "\r\n"
+ tmp = atcmd_readline(fd, buf, sizeof(buf));
+ if (tmp <= 0) {
+ log_debug("expected \\r\\n but it was not received");
+ return -1;
+ }
+
+ //Read manufacturer string
+ tmp = atcmd_readline(fd, buf, sizeof(buf));
+ if (tmp <= 0) {
+ log_debug("expected manufacturer but it was not received");
+ return -1;
+ }
+
+ save = buf;
+ token = atcmd_value_tok(&save);
+ if (!token) {
+ log_debug("atcmd_value_tok manufacturer");
+ return -1;
+ }
+ strncpy(Global.core.manufacturer, token, MANUFACTURER_LEN);
+
+ log_debug("manufacturer: %s", Global.core.manufacturer);
+
+ tmp = atcmd_expect_line(fd, buf, sizeof(buf), "OK");
+ if (tmp <= 0) {
+ log_debug("expected OK but it was not received");
+ return -1;
+ }
+
+ return 0;
+}
+
/* ICCID needed for LNA3 to determine carrier */
int atcmd_plus_iccid_read(int fd)
{
@@ -1250,8 +1292,18 @@ int atcmd_plus_iccid_read(int fd)
char *save;
char *token;
int tmp;
+ char* command;
- atcmd_writeline(fd, "AT#CCID");
+ if (is_telit_model()) {
+ command = "AT#CCID";
+ } else if (is_quectel_model()) {
+ command = "AT+QCCID";
+ } else {
+ log_error("unsupported modem manufacturer, unable to detect ICCID");
+ return -1;
+ }
+
+ atcmd_writeline(fd, command);
//Swallow extra "\r\n"
tmp = atcmd_readline(fd, buf, sizeof(buf));
if (tmp <= 0) {
@@ -1286,8 +1338,7 @@ int atcmd_plus_iccid_read(int fd)
token = ++tmp;
}
log_debug("token[0]=%2.2x token[1]=%2.2x",token[0],token[1]);
- free(Global.core.iccid);
- Global.core.iccid = strdup(token);
+ strncpy(Global.core.iccid, token, ICCID_LEN);
log_debug("iccid: %s", Global.core.iccid);
@@ -1348,12 +1399,18 @@ static int sms_atcmd_init(int fd)
return -1;
}
- tmp = atcmd_plus_gmm_read(fd);
+ tmp = atcmd_plus_gmm_read(fd);
if (tmp < 0) {
log_error("failed to read radio model");
return -1;
}
+ tmp = atcmd_plus_gmi_read(fd);
+ if (tmp < 0) {
+ log_error("failed to read radio manufacturer");
+ return -1;
+ }
+
tmp = atcmd_plus_iccid_read(fd);
if (tmp < 0) {
log_error("failed to read SIM ICCID");
@@ -1494,3 +1551,22 @@ int isCdmaTypeModel()
!strcmp(Global.core.model, "CE910-DUAL"));
}
+int is_telit_model()
+{
+ if (!strncmp(Global.core.manufacturer, "Telit", MANUFACTURER_LEN)) {
+ log_debug("Found Telit model");
+ return 1;
+ }
+
+ return 0;
+}
+
+int is_quectel_model()
+{
+ if (!strncmp(Global.core.manufacturer, "Quectel", MANUFACTURER_LEN)) {
+ log_debug("Found Quectel model");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/src/atcmd.h b/src/atcmd.h
index c13866e..dc3d5d9 100644
--- a/src/atcmd.h
+++ b/src/atcmd.h
@@ -3,6 +3,7 @@
#include <termios.h>
#include <stdarg.h>
+#include <stddef.h>
#ifdef __ATCMD_C
#define ATCMD_EXTERN
@@ -113,11 +114,14 @@ int atcmd_plus_cpbs_write(int fd, const char *name);
int atcmd_plus_cpbr_test(int fd, struct phonebook_store *store);
int atcmd_plus_gmm_read(int fd);
+int atcmd_plus_gmi_read(int fd);
int atcmd_init(int fd, int read_timeout);
int sms_device_close(int fd);
int sms_device_open(void);
int is_vzw_lte(void);
+int is_telit_model(void);
+int is_quectel_model(void);
#if __ATCMD_C
const char *abort_dfl[] = {
diff --git a/src/global.h b/src/global.h
index fc8df6f..a6073dd 100644
--- a/src/global.h
+++ b/src/global.h
@@ -12,6 +12,13 @@
#define GLOBAL_EXTERN extern
#endif
+#define ICCID_LEN 23
+#define ICCID_SIZE (ICCID_LEN + 1)
+#define MODEL_LEN 1023
+#define MODEL_SIZE (MODEL_LEN + 1)
+#define MANUFACTURER_LEN 1023
+#define MANUFACTURER_SIZE (MANUFACTURER_LEN + 1)
+
struct global_user {
char *name;
char *email;
@@ -29,8 +36,9 @@ struct global_core {
char *msg_store_send;
char *msg_store_new;
char *pb_store;
- char *model;
- char *iccid; /* Needed for LNA3/Verizon */
+ char model[MODEL_SIZE];
+ char iccid[ICCID_SIZE]; /* Needed for LNA3/Verizon */
+ char manufacturer[MANUFACTURER_SIZE]; /* Needed to pick proper manufacturer-specific commands */
char *editor;
char *edit_file;
diff --git a/src/sms_main.c b/src/sms_main.c
index e91aaba..86116a7 100644
--- a/src/sms_main.c
+++ b/src/sms_main.c
@@ -59,7 +59,8 @@ static int global_init(void)
Global.core.msg_store_send = strdup("SM");
Global.core.msg_store_new = strdup("SM");
Global.core.pb_store = strdup("SM");
- Global.core.model = strdup("UNKNOWNMODEL");
+ strncpy(Global.core.model, "UNKNOWNMODEL", MODEL_LEN);
+ strncpy(Global.core.manufacturer, "UNKNOWNMANUFACTURER", MANUFACTURER_LEN);
Global.core.editor = strdup("vi");
Global.core.edit_file = strdup("${HOME}/.smsmsg");