summaryrefslogtreecommitdiffstats
path: root/src/host/layer23
diff options
context:
space:
mode:
Diffstat (limited to 'src/host/layer23')
-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;
}