aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/abis_rsl.c6
-rw-r--r--src/bsc_hack.c12
-rw-r--r--src/chan_alloc.c20
-rw-r--r--src/db.c15
-rw-r--r--src/gsm_04_08.c41
-rw-r--r--src/gsm_subscriber.c57
-rw-r--r--src/misdn.c2
7 files changed, 127 insertions, 26 deletions
diff --git a/src/abis_rsl.c b/src/abis_rsl.c
index 60713785b..54b706936 100644
--- a/src/abis_rsl.c
+++ b/src/abis_rsl.c
@@ -610,9 +610,6 @@ static int rsl_rx_chan_rqd(struct msgb *msg)
arfcn = lchan->ts->trx->arfcn;
subch = lchan->nr;
- DEBUGP(DRSL, "Activating ARFCN(%u) TS(%u) SS(%u) lctype %u\n",
- arfcn, ts_number, subch, lchan->type);
-
rsl_chan_activate_lchan(lchan, 0x00, rqd_ta);
/* create IMMEDIATE ASSIGN 04.08 messge */
@@ -631,6 +628,9 @@ static int rsl_rx_chan_rqd(struct msgb *msg)
ia.timing_advance = rqd_ta;
ia.mob_alloc_len = 0;
+ DEBUGP(DRSL, "Activating ARFCN(%u) TS(%u) SS(%u) lctype %u chan_nr=0x%02x\n",
+ arfcn, ts_number, subch, lchan->type, ia.chan_desc.chan_nr);
+
/* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
return rsl_imm_assign_cmd(bts, sizeof(ia), (u_int8_t *) &ia);
}
diff --git a/src/bsc_hack.c b/src/bsc_hack.c
index a8f5a8962..b9b9f8beb 100644
--- a/src/bsc_hack.c
+++ b/src/bsc_hack.c
@@ -636,6 +636,18 @@ int main(int argc, char **argv)
/* parse options */
handle_options(argc, argv);
+ if (db_init()) {
+ printf("DB: Failed to init database. Please check the option settings.\n");
+ return 1;
+ }
+ printf("DB: Database initialized.\n");
+
+ if (db_prepare()) {
+ printf("DB: Failed to prepare database.\n");
+ return 1;
+ }
+ printf("DB: Database prepared.\n");
+
bootstrap_network();
while (1) {
diff --git a/src/chan_alloc.c b/src/chan_alloc.c
index 4ef5ff902..3ef8b4d24 100644
--- a/src/chan_alloc.c
+++ b/src/chan_alloc.c
@@ -63,7 +63,25 @@ struct gsm_bts_trx_ts *ts_alloc(struct gsm_bts *bts,
int i, j;
for (i = 0; i < bts->num_trx; i++) {
struct gsm_bts_trx *trx = &bts->trx[i];
- for (j = 0; j < 8; j++) {
+ int from, to;
+
+ /* the following constraints are pure policy,
+ * no requirement to put this restriction in place */
+ switch (pchan) {
+ case GSM_PCHAN_CCCH:
+ case GSM_PCHAN_CCCH_SDCCH4:
+ from = 0; to = 0;
+ break;
+ case GSM_PCHAN_SDCCH8_SACCH8C:
+ from = 1; to = 1;
+ break;
+ case GSM_PCHAN_TCH_F:
+ case GSM_PCHAN_TCH_H:
+ from = 2; to = 7;
+ break;
+ }
+
+ for (j = from; j <= to; j++) {
struct gsm_bts_trx_ts *ts = &trx->ts[j];
if (ts->pchan == GSM_PCHAN_NONE) {
ts->pchan = pchan;
diff --git a/src/db.c b/src/db.c
index 2e0042a6e..679899b4b 100644
--- a/src/db.c
+++ b/src/db.c
@@ -69,7 +69,7 @@ int db_prepare() {
"created TIMESTAMP NOT NULL, "
"updated TIMESTAMP NOT NULL, "
"imsi NUMERIC UNIQUE NOT NULL, "
- "tmsi NUMERIC UNIQUE, "
+ "tmsi TEXT UNIQUE, "
"extension TEXT UNIQUE, "
"lac INTEGER NOT NULL DEFAULT 0, "
"authorized INTEGER NOT NULL DEFAULT 0"
@@ -146,6 +146,8 @@ struct gsm_subscriber* db_create_subscriber(char imsi[GSM_IMSI_LENGTH]) {
int db_get_subscriber(enum gsm_subscriber_field field, struct gsm_subscriber* subscriber) {
dbi_result result;
+ char *string;
+
switch (field) {
case GSM_SUBSCRIBER_IMSI:
result = dbi_conn_queryf(conn,
@@ -174,9 +176,16 @@ int db_get_subscriber(enum gsm_subscriber_field field, struct gsm_subscriber* su
dbi_result_free(result);
return 1;
}
+ memset(subscriber, 0, sizeof(*subscriber));
subscriber->id = dbi_result_get_ulonglong(result, "id");
- strncpy(subscriber->imsi, dbi_result_get_string(result, "imsi"), GSM_IMSI_LENGTH);
- strncpy(subscriber->tmsi, dbi_result_get_string(result, "tmsi"), GSM_TMSI_LENGTH);
+ string = dbi_result_get_string(result, "imsi");
+ if (string)
+ strncpy(subscriber->imsi, string, GSM_IMSI_LENGTH);
+
+ string = dbi_result_get_string(result, "tmsi");
+ if (string)
+ strncpy(subscriber->tmsi, string, GSM_TMSI_LENGTH);
+
// FIXME handle extension
subscriber->lac = dbi_result_get_uint(result, "lac");
subscriber->authorized = dbi_result_get_uint(result, "authorized");
diff --git a/src/gsm_04_08.c b/src/gsm_04_08.c
index 447c2631e..83399d021 100644
--- a/src/gsm_04_08.c
+++ b/src/gsm_04_08.c
@@ -28,6 +28,7 @@
#include <errno.h>
#include <netinet/in.h>
+#include <openbsc/db.h>
#include <openbsc/msgb.h>
#include <openbsc/debug.h>
#include <openbsc/gsm_data.h>
@@ -98,15 +99,12 @@ static void generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc,
#define TMSI_LEN 4
#define MID_TMSI_LEN (TMSI_LEN + 2)
-static void generate_mid_from_tmsi(u_int8_t *buf, u_int8_t *tmsi_bcd)
+static void generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi)
{
buf[0] = GSM48_IE_MOBILE_ID;
buf[1] = MID_TMSI_LEN;
buf[2] = 0xf0 | GSM_MI_TYPE_TMSI;
- buf[3] = tmsi_bcd[0];
- buf[4] = tmsi_bcd[1];
- buf[5] = tmsi_bcd[2];
- buf[6] = tmsi_bcd[3];
+ *((u_int32_t *) &buf[3]) = htonl(tmsi);
}
static struct msgb *gsm48_msgb_alloc(void)
@@ -144,7 +142,7 @@ int gsm0408_loc_upd_rej(struct gsm_lchan *lchan, u_int8_t cause)
}
/* Chapter 9.2.13 : Send LOCATION UPDATE ACCEPT */
-int gsm0408_loc_upd_acc(struct gsm_lchan *lchan, u_int8_t *tmsi)
+int gsm0408_loc_upd_acc(struct gsm_lchan *lchan, u_int32_t tmsi)
{
struct gsm_bts *bts = lchan->ts->trx->bts;
struct msgb *msg = gsm48_msgb_alloc();
@@ -241,14 +239,33 @@ static int mm_tx_identity_req(struct gsm_lchan *lchan, u_int8_t id_type)
static int mm_rx_id_resp(struct msgb *msg)
{
struct gsm48_hdr *gh = msgb_l3(msg);
+ struct gsm_lchan *lchan = msg->lchan;
u_int8_t mi_type = gh->data[1] & GSM_MI_TYPE_MASK;
char mi_string[MI_SIZE];
+ u_int32_t tmsi;
mi_to_string(mi_string, sizeof(mi_string), &gh->data[1], gh->data[0]);
DEBUGP(DMM, "IDENTITY RESPONSE: mi_type=0x%02x MI(%s)\n",
mi_type, mi_string);
- /* FIXME: update subscribe <-> IMEI mapping */
+ switch (mi_type) {
+ case GSM_MI_TYPE_IMSI:
+ if (!lchan->subscr)
+ lchan->subscr = db_create_subscriber(mi_string);
+ if (lchan->subscr && lchan->subscr->authorized) {
+ /* FIXME: check if we've recently received UPDATE REQUEST */
+ db_subscriber_alloc_tmsi(lchan->subscr);
+ tmsi = strtoul(lchan->subscr->tmsi, NULL, 16);
+ return gsm0408_loc_upd_acc(msg->lchan, tmsi);
+ }
+ break;
+ case GSM_MI_TYPE_IMEI:
+ /* update subscribe <-> IMEI mapping */
+ if (lchan->subscr)
+ db_subscriber_assoc_imei(lchan->subscr, mi_string);
+ break;
+ }
+ return 0;
}
#define MI_SIZE 32
@@ -260,6 +277,7 @@ static int mm_rx_loc_upd_req(struct msgb *msg)
struct gsm48_loc_upd_req *lu;
struct gsm_subscriber *subscr;
u_int8_t mi_type;
+ u_int32_t tmsi;
char mi_string[MI_SIZE];
int rc;
@@ -275,7 +293,7 @@ static int mm_rx_loc_upd_req(struct msgb *msg)
/* we always want the IMEI, too */
rc = mm_tx_identity_req(msg->lchan, GSM_MI_TYPE_IMEISV);
/* look up subscriber based on IMSI */
- subscr = subscr_get_by_imsi(lu->mi);
+ subscr = db_create_subscriber(mi_string);
break;
case GSM_MI_TYPE_TMSI:
/* we always want the IMEI, too */
@@ -297,17 +315,20 @@ static int mm_rx_loc_upd_req(struct msgb *msg)
break;
}
- if (!subscr) {
+ if (!subscr || !subscr->authorized) {
/* 0x16 is congestion */
gsm0408_loc_upd_rej(msg->lchan, 0x16);
rsl_chan_release(msg->lchan);
return -EINVAL;
}
+ db_subscriber_alloc_tmsi(subscr);
+
msg->lchan->subscr = subscr;
subscr_update(subscr, bts);
+ tmsi = strtoul(subscr->tmsi, NULL, 16);
- return gsm0408_loc_upd_acc(msg->lchan, subscr->tmsi);
+ return gsm0408_loc_upd_acc(msg->lchan, tmsi);
}
static int gsm48_tx_mm_serv_ack(struct gsm_lchan *lchan)
diff --git a/src/gsm_subscriber.c b/src/gsm_subscriber.c
index 6a67c49e3..fcf91ae51 100644
--- a/src/gsm_subscriber.c
+++ b/src/gsm_subscriber.c
@@ -20,24 +20,63 @@
*
*/
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
#include <openbsc/gsm_subscriber.h>
+#include <openbsc/db.h>
-static struct gsm_subscriber subscr = {
- .name = "Test User 1",
- .tmsi = { 0x22, 0x33, 0x44, 0x55 },
-};
+struct gsm_subscriber *subscr_alloc(void)
+{
+ struct gsm_subscriber *s;
+
+ s = malloc(sizeof(struct gsm_subscriber));
+ if (!s)
+ return NULL;
+
+ memset(s, 0, sizeof(*s));
+
+ return s;
+}
-struct gsm_subscriber *subscr_get_by_tmsi(u_int8_t *tmsi)
+void subscr_free(struct gsm_subscriber *subscr)
{
- return &subscr;
+ free(subscr);
}
-struct gsm_subscriber *subscr_get_by_imsi(u_int8_t *imsi)
+
+struct gsm_subscriber *subscr_get_by_tmsi(char *tmsi)
{
- return &subscr;
+ struct gsm_subscriber *subscr = subscr_alloc();
+
+ strncpy(subscr->tmsi, tmsi, sizeof(subscr->tmsi));
+ subscr->tmsi[sizeof(subscr->tmsi)-1] = '\0';
+
+ if (db_get_subscriber(GSM_SUBSCRIBER_TMSI, subscr) != 0) {
+ subscr_free(subscr);
+ subscr = NULL;
+ }
+
+ return subscr;
+}
+
+struct gsm_subscriber *subscr_get_by_imsi(char *imsi)
+{
+ struct gsm_subscriber *subscr = subscr_alloc();
+
+ strncpy(subscr->imsi, imsi, sizeof(subscr->imsi));
+ subscr->imsi[sizeof(subscr->imsi)-1] = '\0';
+
+ if (db_get_subscriber(GSM_SUBSCRIBER_IMSI, subscr) != 0) {
+ subscr_free(subscr);
+ subscr = NULL;
+ }
+
+ return subscr;
}
int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts)
{
- return 0;
+ return db_set_subscriber(s);
}
diff --git a/src/misdn.c b/src/misdn.c
index fae6b0ddc..a8e5dca9b 100644
--- a/src/misdn.c
+++ b/src/misdn.c
@@ -286,8 +286,10 @@ static int handle_tsX_read(struct bsc_fd *bfd)
msg->l2h = msg->data + MISDN_HEADER_LEN;
+#if 0
fprintf(stdout, "BCHAN RX: ");
hexdump(msgb_l2(msg), ret - MISDN_HEADER_LEN);
+#endif
if (!e1h->ts2_fd)
e1h->ts2_fd = open("/tmp/ts2.dump", O_WRONLY|O_APPEND|O_CREAT, 0660);