summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2011-11-01 16:29:18 +0100
committerSylvain Munaut <tnt@246tNt.com>2011-11-13 20:25:20 +0100
commitfe2e57bc800448703208ab52688b34ffb65bb386 (patch)
treebe456cb7e25ce2f1d3d2f5cfc54ad67be2436c21
parentfb7be589e6f2a7e8dcbd560a0b0fdbda7d1fd316 (diff)
host/mobile: Mobile will use SMS Service Center Address from SIM
In case the SMS Service Center Address is not set in the config, the Address from the SIM card is used. The mobile checks if either one is defined, otherwise it will refuse sending SMS. Since records of SIM are read, this patch includes fixes to talk correctly with the SIM client. Written-by: Andreas Eversberg <jolly@eversberg.eu> Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
-rw-r--r--src/host/layer23/include/osmocom/bb/common/sim.h10
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/gsm411_sms.h4
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/settings.h2
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/subscriber.h3
-rw-r--r--src/host/layer23/src/mobile/gsm411_sms.c15
-rw-r--r--src/host/layer23/src/mobile/subscriber.c65
-rw-r--r--src/host/layer23/src/mobile/vty_interface.c15
7 files changed, 85 insertions, 29 deletions
diff --git a/src/host/layer23/include/osmocom/bb/common/sim.h b/src/host/layer23/include/osmocom/bb/common/sim.h
index a676b92b..95d2147c 100644
--- a/src/host/layer23/include/osmocom/bb/common/sim.h
+++ b/src/host/layer23/include/osmocom/bb/common/sim.h
@@ -266,6 +266,16 @@ struct gsm1111_ef_adn {
uint8_t ext_id;
} __attribute__ ((packed));
+/* Section 10.5.6 */
+struct gsm1111_ef_smsp {
+ uint8_t par_ind;
+ uint8_t tp_da[12];
+ uint8_t ts_sca[12];
+ uint8_t tp_proto;
+ uint8_t tp_dcs;
+ uint8_t tp_vp;
+} __attribute__ ((packed));
+
int sim_apdu_resp(struct osmocom_ms *ms, struct msgb *msg);
int gsm_sim_init(struct osmocom_ms *ms);
int gsm_sim_exit(struct osmocom_ms *ms);
diff --git a/src/host/layer23/include/osmocom/bb/mobile/gsm411_sms.h b/src/host/layer23/include/osmocom/bb/mobile/gsm411_sms.h
index 61019de6..d14e6db8 100644
--- a/src/host/layer23/include/osmocom/bb/mobile/gsm411_sms.h
+++ b/src/host/layer23/include/osmocom/bb/mobile/gsm411_sms.h
@@ -26,8 +26,8 @@ int gsm411_sms_exit(struct osmocom_ms *ms);
struct gsm_sms *sms_alloc(void);
void sms_free(struct gsm_sms *sms);
struct gsm_sms *sms_from_text(const char *receiver, int dcs, const char *text);
-int gsm411_tx_sms_submit(struct osmocom_ms *ms, struct gsm_sms *sms);
int gsm411_rcv_sms(struct osmocom_ms *ms, struct msgb *msg);
-int sms_send(struct osmocom_ms *ms, const char *number, const char *text);
+int sms_send(struct osmocom_ms *ms, const char *sms_sca, const char *number,
+ const char *text);
#endif /* _GSM411_SMS_H */
diff --git a/src/host/layer23/include/osmocom/bb/mobile/settings.h b/src/host/layer23/include/osmocom/bb/mobile/settings.h
index 8442f038..e09d9084 100644
--- a/src/host/layer23/include/osmocom/bb/mobile/settings.h
+++ b/src/host/layer23/include/osmocom/bb/mobile/settings.h
@@ -24,7 +24,7 @@ struct gsm_settings {
char emergency_imsi[16];
/* SMS */
- char sms_sca[12];
+ char sms_sca[22];
/* test card simulator settings */
char test_imsi[16];
diff --git a/src/host/layer23/include/osmocom/bb/mobile/subscriber.h b/src/host/layer23/include/osmocom/bb/mobile/subscriber.h
index cc0cfac6..50c305a8 100644
--- a/src/host/layer23/include/osmocom/bb/mobile/subscriber.h
+++ b/src/host/layer23/include/osmocom/bb/mobile/subscriber.h
@@ -77,6 +77,9 @@ struct gsm_subscriber {
uint32_t sim_handle_query;
uint32_t sim_handle_update;
uint32_t sim_handle_key;
+
+ /* SMS */
+ char sms_sca[22];
};
int gsm_subscr_init(struct osmocom_ms *ms);
diff --git a/src/host/layer23/src/mobile/gsm411_sms.c b/src/host/layer23/src/mobile/gsm411_sms.c
index a08984d1..4347e86a 100644
--- a/src/host/layer23/src/mobile/gsm411_sms.c
+++ b/src/host/layer23/src/mobile/gsm411_sms.c
@@ -210,7 +210,7 @@ fail:
fp = fopen(sms_file, "a");
if (!fp)
goto fail;
- fprintf(fp, "[SMS %s]\n%s\n", gsms->address, gsms->text);
+ fprintf(fp, "[SMS from %s]\n%s\n", gsms->address, gsms->text);
fclose(fp);
talloc_free(sms_file);
@@ -617,9 +617,9 @@ static int gsm340_gen_tpdu(struct msgb *msg, struct gsm_sms *sms)
}
/* Take a SMS in gsm_sms structure and send it. */
-int gsm411_tx_sms_submit(struct osmocom_ms *ms, struct gsm_sms *sms)
+static int gsm411_tx_sms_submit(struct osmocom_ms *ms, const char *sms_sca,
+ struct gsm_sms *sms)
{
- struct gsm_settings *set = &ms->settings;
struct msgb *msg;
struct gsm_trans *trans;
uint8_t *data, *rp_ud_len;
@@ -668,11 +668,11 @@ int gsm411_tx_sms_submit(struct osmocom_ms *ms, struct gsm_sms *sms)
/* Destination Address */
sca[1] = 0x80; /* no extension */
- sca[1] |= ((set->sms_sca[0] == '+') ? 0x01 : 0x00) << 4; /* type */
+ sca[1] |= ((sms_sca[0] == '+') ? 0x01 : 0x00) << 4; /* type */
sca[1] |= 0x1; /* plan*/
rc = gsm48_encode_bcd_number(sca, sizeof(sca), 1,
- set->sms_sca + (set->sms_sca[0] == '+'));
+ sms_sca + (sms_sca[0] == '+'));
if (rc < 0) {
error:
gsm411_sms_report(ms, sms, GSM411_RP_CAUSE_SEMANT_INC_MSG);
@@ -700,14 +700,15 @@ error:
}
/* create and send SMS */
-int sms_send(struct osmocom_ms *ms, const char *number, const char *text)
+int sms_send(struct osmocom_ms *ms, const char *sms_sca, const char *number,
+ const char *text)
{
struct gsm_sms *sms = sms_from_text(number, 0, text);
if (!sms)
return -ENOMEM;
- return gsm411_tx_sms_submit(ms, sms);
+ return gsm411_tx_sms_submit(ms, sms_sca, sms);
}
/*
diff --git a/src/host/layer23/src/mobile/subscriber.c b/src/host/layer23/src/mobile/subscriber.c
index 6de742aa..b6dfc2f0 100644
--- a/src/host/layer23/src/mobile/subscriber.c
+++ b/src/host/layer23/src/mobile/subscriber.c
@@ -320,9 +320,9 @@ static int subscr_sim_msisdn(struct osmocom_ms *ms, uint8_t *data,
return 0;
/* number */
- if (adn->ton_npi == 1)
+ if (((adn->ton_npi & 0x70) >> 4) == 1)
strcpy(subscr->msisdn, "+");
- if (adn->ton_npi == 2)
+ if (((adn->ton_npi & 0x70) >> 4) == 2)
strcpy(subscr->msisdn, "0");
strncat(subscr->msisdn, sim_decode_bcd(adn->number, adn->len_bcd - 1),
sizeof(subscr->msisdn) - 2);
@@ -332,6 +332,36 @@ static int subscr_sim_msisdn(struct osmocom_ms *ms, uint8_t *data,
return 0;
}
+static int subscr_sim_smsp(struct osmocom_ms *ms, uint8_t *data,
+ uint8_t length)
+{
+ struct gsm_subscriber *subscr = &ms->subscr;
+ struct gsm1111_ef_smsp *smsp;
+
+ if (length < sizeof(*smsp))
+ return -EINVAL;
+ smsp = (struct gsm1111_ef_smsp *) (data + length - sizeof(*smsp));
+
+ /* empty */
+ subscr->sms_sca[0] = '\0';
+
+ /* TS-Service Centre Address */
+ if (!(smsp->par_ind & 0x02) && smsp->ts_sca[0] <= 11) {
+ if (((smsp->ts_sca[1] & 0x70) >> 4) == 1)
+ strcpy(subscr->sms_sca, "+");
+ if (((smsp->ts_sca[1] & 0x70) >> 4) == 2)
+ strcpy(subscr->sms_sca, "0");
+ gsm48_decode_bcd_number(subscr->sms_sca +
+ strlen(subscr->sms_sca), sizeof(subscr->sms_sca)
+ - strlen(subscr->sms_sca), smsp->ts_sca, 1);
+ }
+
+ LOGP(DMM, LOGL_INFO, "received SMSP from SIM (sca=%s)\n",
+ subscr->sms_sca);
+
+ return 0;
+}
+
static int subscr_sim_kc(struct osmocom_ms *ms, uint8_t *data,
uint8_t length)
{
@@ -497,20 +527,22 @@ static struct subscr_sim_file {
uint8_t mandatory;
uint16_t path[MAX_SIM_PATH_LENGTH];
uint16_t file;
+ uint8_t sim_job;
int (*func)(struct osmocom_ms *ms, uint8_t *data,
uint8_t length);
} subscr_sim_files[] = {
- { 1, { 0 }, 0x2fe2, subscr_sim_iccid },
- { 1, { 0x7f20, 0 }, 0x6f07, subscr_sim_imsi },
- { 1, { 0x7f20, 0 }, 0x6f7e, subscr_sim_loci },
- { 0, { 0x7f10, 0 }, 0x6f40, subscr_sim_msisdn },
- { 0, { 0x7f20, 0 }, 0x6f20, subscr_sim_kc },
- { 0, { 0x7f20, 0 }, 0x6f30, subscr_sim_plmnsel },
- { 0, { 0x7f20, 0 }, 0x6f31, subscr_sim_hpplmn },
- { 0, { 0x7f20, 0 }, 0x6f46, subscr_sim_spn },
- { 0, { 0x7f20, 0 }, 0x6f78, subscr_sim_acc },
- { 0, { 0x7f20, 0 }, 0x6f7b, subscr_sim_fplmn },
- { 0, { 0 }, 0, NULL }
+ { 1, { 0 }, 0x2fe2, SIM_JOB_READ_BINARY, subscr_sim_iccid },
+ { 1, { 0x7f20, 0 }, 0x6f07, SIM_JOB_READ_BINARY, subscr_sim_imsi },
+ { 1, { 0x7f20, 0 }, 0x6f7e, SIM_JOB_READ_BINARY, subscr_sim_loci },
+ { 0, { 0x7f20, 0 }, 0x6f20, SIM_JOB_READ_BINARY, subscr_sim_kc },
+ { 0, { 0x7f20, 0 }, 0x6f30, SIM_JOB_READ_BINARY, subscr_sim_plmnsel },
+ { 0, { 0x7f20, 0 }, 0x6f31, SIM_JOB_READ_BINARY, subscr_sim_hpplmn },
+ { 0, { 0x7f20, 0 }, 0x6f46, SIM_JOB_READ_BINARY, subscr_sim_spn },
+ { 0, { 0x7f20, 0 }, 0x6f78, SIM_JOB_READ_BINARY, subscr_sim_acc },
+ { 0, { 0x7f20, 0 }, 0x6f7b, SIM_JOB_READ_BINARY, subscr_sim_fplmn },
+ { 0, { 0x7f10, 0 }, 0x6f40, SIM_JOB_READ_RECORD, subscr_sim_msisdn },
+ { 0, { 0x7f10, 0 }, 0x6f42, SIM_JOB_READ_RECORD, subscr_sim_smsp },
+ { 0, { 0 }, 0, 0, NULL }
};
/* request file from SIM */
@@ -553,7 +585,7 @@ static int subscr_sim_request(struct osmocom_ms *ms)
/* trigger SIM reading */
nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_query,
- SIM_JOB_READ_BINARY);
+ sf->sim_job);
if (!nmsg)
return -ENOMEM;
nsh = (struct sim_hdr *) nmsg->data;
@@ -564,6 +596,8 @@ static int subscr_sim_request(struct osmocom_ms *ms)
}
nsh->path[i] = 0; /* end of path */
nsh->file = sf->file;
+ nsh->rec_no = 1;
+ nsh->rec_mode = 0x04;
LOGP(DMM, LOGL_INFO, "Requesting SIM file 0x%04x\n", nsh->file);
sim_job(ms, nmsg);
@@ -1148,6 +1182,9 @@ void gsm_subscr_dump(struct gsm_subscriber *subscr,
print(priv, " Service Provider Name: %s\n", subscr->sim_spn);
if (subscr->msisdn[0])
print(priv, " MSISDN: %s\n", subscr->msisdn);
+ if (subscr->sms_sca[0])
+ print(priv, " SMS Service Center Address: %s\n",
+ subscr->sms_sca);
print(priv, " Status: %s IMSI %s", subscr_ustate_names[subscr->ustate],
(subscr->imsi_attached) ? "attached" : "detached");
if (subscr->tmsi != 0xffffffff)
diff --git a/src/host/layer23/src/mobile/vty_interface.c b/src/host/layer23/src/mobile/vty_interface.c
index aed6cfa5..5c8d60b7 100644
--- a/src/host/layer23/src/mobile/vty_interface.c
+++ b/src/host/layer23/src/mobile/vty_interface.c
@@ -846,7 +846,7 @@ DEFUN(sms, sms_cmd, "sms MS_NAME NUMBER .LINE",
struct osmocom_ms *ms;
struct gsm_settings *set;
struct gsm_settings_abbrev *abbrev;
- char *number;
+ char *number, *sms_sca = NULL;
ms = get_ms(argv[0], vty);
if (!ms)
@@ -859,9 +859,14 @@ DEFUN(sms, sms_cmd, "sms MS_NAME NUMBER .LINE",
return CMD_WARNING;
}
- if (!set->sms_sca[0]) {
- vty_out(vty, "SMS sms-service-center not defined in settings%s",
- VTY_NEWLINE);
+ if (ms->subscr.sms_sca[0])
+ sms_sca = ms->subscr.sms_sca;
+ else if (set->sms_sca[0])
+ sms_sca = set->sms_sca;
+
+ if (!sms_sca) {
+ vty_out(vty, "SMS sms-service-center not defined on SIM card, "
+ "please define one at settings.%s", VTY_NEWLINE);
return CMD_WARNING;
}
@@ -877,7 +882,7 @@ DEFUN(sms, sms_cmd, "sms MS_NAME NUMBER .LINE",
if (vty_check_number(vty, number))
return CMD_WARNING;
- sms_send(ms, number, argv_concat(argv, argc, 2));
+ sms_send(ms, sms_sca, number, argv_concat(argv, argc, 2));
return CMD_SUCCESS;
}