mirror of git://git.sysmocom.de/ofono
Change MNC and MCC variable types to string
This is to make sure both 2 and 3-digit MNC values are correctly handled. Both the modem plugin API as well as the D-Bus API are affected.
This commit is contained in:
parent
683b00de1b
commit
ba8828c095
|
@ -45,28 +45,20 @@ static const char *csq_prefix[] = { "+CSQ:", NULL };
|
||||||
|
|
||||||
struct netreg_data {
|
struct netreg_data {
|
||||||
gboolean supports_tech;
|
gboolean supports_tech;
|
||||||
short mnc;
|
char mnc[OFONO_MAX_MNC_MCC_LENGTH + 1];
|
||||||
short mcc;
|
char mcc[OFONO_MAX_MNC_MCC_LENGTH + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
static void extract_mcc_mnc(const char *str, short *mcc, short *mnc)
|
static void extract_mcc_mnc(const char *str, char *mcc, char *mnc)
|
||||||
{
|
{
|
||||||
int num = 0;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
/* Three digit country code */
|
/* Three digit country code */
|
||||||
for (i = 0; i < 3; i++)
|
strncpy(mcc, str, OFONO_MAX_MNC_MCC_LENGTH);
|
||||||
num = num * 10 + (int)(str[i] - '0');
|
mcc[OFONO_MAX_MNC_MCC_LENGTH] = '\0';
|
||||||
|
|
||||||
*mcc = num;
|
|
||||||
|
|
||||||
num = 0;
|
|
||||||
|
|
||||||
/* Usually a 2 but sometimes 3 digit network code */
|
/* Usually a 2 but sometimes 3 digit network code */
|
||||||
for (; i < strlen(str); i++)
|
strncpy(mnc, str + OFONO_MAX_MNC_MCC_LENGTH,
|
||||||
num = num * 10 + (int)(str[i] - '0');
|
OFONO_MAX_MNC_MCC_LENGTH);
|
||||||
|
mnc[OFONO_MAX_MNC_MCC_LENGTH] = '\0';
|
||||||
*mnc = num;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void at_creg_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
static void at_creg_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||||
|
@ -154,7 +146,7 @@ static void cops_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||||
dump_response("cops_cb", ok, result);
|
dump_response("cops_cb", ok, result);
|
||||||
decode_at_error(&error, g_at_result_final_response(result));
|
decode_at_error(&error, g_at_result_final_response(result));
|
||||||
|
|
||||||
if (!ok || at->netreg->mcc == -1 || at->netreg->mnc == -1) {
|
if (!ok || *at->netreg->mcc == '\0' || *at->netreg->mnc == '\0') {
|
||||||
cb(&error, NULL, cbd->data);
|
cb(&error, NULL, cbd->data);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -181,12 +173,16 @@ static void cops_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||||
strncpy(op.name, name, OFONO_MAX_OPERATOR_NAME_LENGTH);
|
strncpy(op.name, name, OFONO_MAX_OPERATOR_NAME_LENGTH);
|
||||||
op.name[OFONO_MAX_OPERATOR_NAME_LENGTH] = '\0';
|
op.name[OFONO_MAX_OPERATOR_NAME_LENGTH] = '\0';
|
||||||
|
|
||||||
op.mcc = at->netreg->mcc;
|
strncpy(op.mcc, at->netreg->mcc, OFONO_MAX_MNC_MCC_LENGTH);
|
||||||
op.mnc = at->netreg->mnc;
|
op.mcc[OFONO_MAX_MNC_MCC_LENGTH] = '\0';
|
||||||
|
|
||||||
|
strncpy(op.mnc, at->netreg->mnc, OFONO_MAX_MNC_MCC_LENGTH);
|
||||||
|
op.mnc[OFONO_MAX_MNC_MCC_LENGTH] = '\0';
|
||||||
|
|
||||||
op.status = -1;
|
op.status = -1;
|
||||||
op.tech = tech;
|
op.tech = tech;
|
||||||
|
|
||||||
ofono_debug("cops_cb: %s, %hd %hd %d", name, at->netreg->mcc,
|
ofono_debug("cops_cb: %s, %s %s %d", name, at->netreg->mcc,
|
||||||
at->netreg->mnc, tech);
|
at->netreg->mnc, tech);
|
||||||
|
|
||||||
cb(&error, &op, cbd->data);
|
cb(&error, &op, cbd->data);
|
||||||
|
@ -235,15 +231,16 @@ static void cops_numeric_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||||
strlen(str) == 0)
|
strlen(str) == 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
extract_mcc_mnc(str, &at->netreg->mcc, &at->netreg->mnc);
|
extract_mcc_mnc(str, at->netreg->mcc, at->netreg->mnc);
|
||||||
|
|
||||||
ofono_debug("Cops numeric got mcc: %hd, mnc: %hd",
|
ofono_debug("Cops numeric got mcc: %s, mnc: %s",
|
||||||
at->netreg->mcc, at->netreg->mnc);
|
at->netreg->mcc, at->netreg->mnc);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
at->netreg->mcc = at->netreg->mnc = -1;
|
*at->netreg->mcc = '\0';
|
||||||
|
*at->netreg->mnc = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
static void at_current_operator(struct ofono_modem *modem,
|
static void at_current_operator(struct ofono_modem *modem,
|
||||||
|
@ -356,7 +353,7 @@ static void cops_list_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||||
if (!g_at_result_iter_next_string(&iter, &n))
|
if (!g_at_result_iter_next_string(&iter, &n))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
extract_mcc_mnc(n, &list[num].mcc, &list[num].mnc);
|
extract_mcc_mnc(n, list[num].mcc, list[num].mnc);
|
||||||
|
|
||||||
if (!g_at_result_iter_next_number(&iter, &tech))
|
if (!g_at_result_iter_next_number(&iter, &tech))
|
||||||
tech = 0;
|
tech = 0;
|
||||||
|
@ -376,7 +373,7 @@ static void cops_list_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for (; i < num; i++) {
|
for (; i < num; i++) {
|
||||||
ofono_debug("Operator: %s, %hd, %hd, status: %d, %d",
|
ofono_debug("Operator: %s, %s, %s, status: %d, %d",
|
||||||
list[i].name, list[i].mcc, list[i].mnc,
|
list[i].name, list[i].mcc, list[i].mnc,
|
||||||
list[i].status, list[i].tech);
|
list[i].status, list[i].tech);
|
||||||
}
|
}
|
||||||
|
@ -457,12 +454,12 @@ static void at_register_manual(struct ofono_modem *modem,
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (at->netreg->supports_tech && oper->tech != -1)
|
if (at->netreg->supports_tech && oper->tech != -1)
|
||||||
sprintf(buf, "AT+COPS=1,2,\"%03hd%02hd\",%1d", oper->mcc,
|
sprintf(buf, "AT+COPS=1,2,\"%s%s\",%1d", oper->mcc,
|
||||||
oper->mnc,
|
oper->mnc,
|
||||||
oper->tech);
|
oper->tech);
|
||||||
else
|
else
|
||||||
sprintf(buf, "AT+COPS=1,2,\"%03hd%02hd\"", oper->mcc,
|
sprintf(buf, "AT+COPS=1,2,\"%s%s\"", oper->mcc,
|
||||||
oper->mnc);
|
oper->mnc);
|
||||||
|
|
||||||
if (g_at_chat_send(at->parser, buf, none_prefix,
|
if (g_at_chat_send(at->parser, buf, none_prefix,
|
||||||
register_cb, cbd, g_free) > 0)
|
register_cb, cbd, g_free) > 0)
|
||||||
|
|
|
@ -74,10 +74,13 @@ struct ofono_call {
|
||||||
* */
|
* */
|
||||||
#define OFONO_MAX_OPERATOR_NAME_LENGTH 63
|
#define OFONO_MAX_OPERATOR_NAME_LENGTH 63
|
||||||
|
|
||||||
|
/* MCC is always three digits. MNC is either two or three digits */
|
||||||
|
#define OFONO_MAX_MNC_MCC_LENGTH 3
|
||||||
|
|
||||||
struct ofono_network_operator {
|
struct ofono_network_operator {
|
||||||
char name[OFONO_MAX_OPERATOR_NAME_LENGTH + 1];
|
char name[OFONO_MAX_OPERATOR_NAME_LENGTH + 1];
|
||||||
short mcc;
|
char mcc[OFONO_MAX_MNC_MCC_LENGTH + 1];
|
||||||
short mnc;
|
char mnc[OFONO_MAX_MNC_MCC_LENGTH + 1];
|
||||||
int status;
|
int status;
|
||||||
int tech;
|
int tech;
|
||||||
};
|
};
|
||||||
|
|
|
@ -180,8 +180,9 @@ static void network_operator_populate_registered(struct ofono_modem *modem,
|
||||||
int modem_len;
|
int modem_len;
|
||||||
int num_children;
|
int num_children;
|
||||||
GSList *l;
|
GSList *l;
|
||||||
int *mccmnc;
|
|
||||||
char path[MAX_DBUS_PATH_LEN];
|
char path[MAX_DBUS_PATH_LEN];
|
||||||
|
char mnc[4];
|
||||||
|
char mcc[4];
|
||||||
|
|
||||||
modem_len = snprintf(path, MAX_DBUS_PATH_LEN, "%s/operator",
|
modem_len = snprintf(path, MAX_DBUS_PATH_LEN, "%s/operator",
|
||||||
modem->path);
|
modem->path);
|
||||||
|
@ -199,10 +200,6 @@ static void network_operator_populate_registered(struct ofono_modem *modem,
|
||||||
|
|
||||||
*network_operators = g_try_new0(char *, num_children + 1);
|
*network_operators = g_try_new0(char *, num_children + 1);
|
||||||
|
|
||||||
mccmnc = g_try_new0(int, num_children * 2);
|
|
||||||
for (i = 0; i < num_children; i++)
|
|
||||||
sscanf(children[i], "%3d%3d", &mccmnc[i*2], &mccmnc[i*2+1]);
|
|
||||||
|
|
||||||
/* Quoting 27.007: "The list of operators shall be in order: home
|
/* Quoting 27.007: "The list of operators shall be in order: home
|
||||||
* network, networks referenced in SIM or active application in the
|
* network, networks referenced in SIM or active application in the
|
||||||
* UICC (GSM or USIM) in the following order: HPLMN selector, User
|
* UICC (GSM or USIM) in the following order: HPLMN selector, User
|
||||||
|
@ -217,18 +214,17 @@ static void network_operator_populate_registered(struct ofono_modem *modem,
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
for (j = 0; children[j]; j++) {
|
for (j = 0; children[j]; j++) {
|
||||||
if (op->mcc == mccmnc[j*2] && op->mnc == mccmnc[j*2+1]) {
|
sscanf(children[j], "%3[0-9]%[0-9]", mcc, mnc);
|
||||||
/* Enough to store '/' + 3 char wide MCC + 3 char wide MNC + null */
|
if (strcmp(op->mcc, mcc) == 0 && strcmp(op->mnc, mnc) == 0) {
|
||||||
(*network_operators)[i] = g_try_new(char, modem_len + 8);
|
/* Enough to store '/' + MCC + '_' + MNC + null */
|
||||||
snprintf((*network_operators)[i], modem_len + 8, "%s/%s",
|
(*network_operators)[i] = g_try_new(char, modem_len + 9);
|
||||||
|
snprintf((*network_operators)[i], modem_len + 9, "%s/%s",
|
||||||
path, children[j]);
|
path, children[j]);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(mccmnc);
|
|
||||||
|
|
||||||
dbus_free_string_array(children);
|
dbus_free_string_array(children);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,19 +240,13 @@ static gint network_operator_compare(gconstpointer a, gconstpointer b)
|
||||||
const struct ofono_network_operator *opa = a;
|
const struct ofono_network_operator *opa = a;
|
||||||
const struct ofono_network_operator *opb = b;
|
const struct ofono_network_operator *opb = b;
|
||||||
|
|
||||||
if (opa->mcc < opb->mcc)
|
int comp1;
|
||||||
return -1;
|
int comp2;
|
||||||
|
|
||||||
if (opa->mcc > opb->mcc)
|
comp1 = strcmp(opa->mcc, opb->mcc);
|
||||||
return 1;
|
comp2 = strcmp(opa->mnc, opb->mnc);
|
||||||
|
|
||||||
if (opa->mnc < opb->mnc)
|
return comp1 != 0 ? comp1 : comp2;
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (opa->mnc > opb->mnc)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const char *network_operator_build_path(struct ofono_modem *modem,
|
static inline const char *network_operator_build_path(struct ofono_modem *modem,
|
||||||
|
@ -264,7 +254,7 @@ static inline const char *network_operator_build_path(struct ofono_modem *modem,
|
||||||
{
|
{
|
||||||
static char path[MAX_DBUS_PATH_LEN];
|
static char path[MAX_DBUS_PATH_LEN];
|
||||||
|
|
||||||
snprintf(path, MAX_DBUS_PATH_LEN, "%s/operator/%03d%03d",
|
snprintf(path, MAX_DBUS_PATH_LEN, "%s/operator/%s%s",
|
||||||
modem->path, oper->mcc, oper->mnc);
|
modem->path, oper->mcc, oper->mnc);
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
|
@ -427,16 +417,16 @@ static DBusMessage *network_operator_get_properties(DBusConnection *conn,
|
||||||
|
|
||||||
dbus_gsm_dict_append(&dict, "Status", DBUS_TYPE_STRING, &status);
|
dbus_gsm_dict_append(&dict, "Status", DBUS_TYPE_STRING, &status);
|
||||||
|
|
||||||
if (op->operator->mcc != -1) {
|
if (*op->operator->mcc != '\0') {
|
||||||
dbus_uint16_t mcc = op->operator->mcc;
|
const char *mcc = op->operator->mcc;
|
||||||
dbus_gsm_dict_append(&dict, "MobileCountryCode",
|
dbus_gsm_dict_append(&dict, "MobileCountryCode",
|
||||||
DBUS_TYPE_UINT16, &mcc);
|
DBUS_TYPE_STRING, &mcc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op->operator->mnc != -1) {
|
if (*op->operator->mnc != '\0') {
|
||||||
dbus_uint16_t mnc = op->operator->mnc;
|
const char *mnc = op->operator->mnc;
|
||||||
dbus_gsm_dict_append(&dict, "MobileNetworkCode",
|
dbus_gsm_dict_append(&dict, "MobileNetworkCode",
|
||||||
DBUS_TYPE_UINT16, &mnc);
|
DBUS_TYPE_STRING, &mnc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op->operator->tech != -1) {
|
if (op->operator->tech != -1) {
|
||||||
|
|
Loading…
Reference in New Issue