aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2009-09-28 12:57:27 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2009-09-28 12:57:27 +0200
commit1e35cec031dd07fa30e67dd697cb2011f55603ba (patch)
treef6f3fdf19465ee8f5d0f33f722cc768a8bf5d77a
parent6b0b103bdcfaf15ca1c33d3c61f211cb40661e92 (diff)
parent927f056f34ea8c1e29ba2ced246e7e9b3f5d688e (diff)
Merge branch 'holger/merge-on-waves-msc'
-rw-r--r--openbsc/include/openbsc/gsm_04_08.h6
-rw-r--r--openbsc/include/openbsc/gsm_data.h2
-rw-r--r--openbsc/include/openbsc/gsm_subscriber.h9
-rw-r--r--openbsc/src/bsc_init.c4
-rw-r--r--openbsc/src/db.c24
-rw-r--r--openbsc/src/gsm_04_08.c67
-rw-r--r--openbsc/src/gsm_04_08_utils.c62
-rw-r--r--openbsc/src/gsm_data.c2
-rw-r--r--openbsc/src/gsm_subscriber.c8
-rw-r--r--openbsc/src/gsm_subscriber_base.c17
-rw-r--r--openbsc/src/openbsc.cfg.1-11
-rw-r--r--openbsc/src/openbsc.cfg.1-21
-rw-r--r--openbsc/src/openbsc.cfg.2-21
-rw-r--r--openbsc/src/paging.c20
-rw-r--r--openbsc/src/transaction.c10
-rw-r--r--openbsc/src/vty_interface.c27
-rw-r--r--openbsc/tests/db/db_test.c4
17 files changed, 167 insertions, 98 deletions
diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h
index acca100e0..d0d5996c2 100644
--- a/openbsc/include/openbsc/gsm_04_08.h
+++ b/openbsc/include/openbsc/gsm_04_08.h
@@ -203,7 +203,7 @@ struct gsm48_system_information_type_6 {
u_int8_t rr_protocol_discriminator :4,
skip_indicator:4;
u_int8_t system_information;
- u_int8_t cell_identity[2];
+ u_int16_t cell_identity;
struct gsm48_loc_area_id lai;
u_int8_t cell_options;
u_int8_t ncc_permitted;
@@ -736,4 +736,8 @@ int decode_bcd_number(char *output, int output_len, const u_int8_t *bcd_lv,
extern const char *gsm0408_cc_msg_names[];
+int send_siemens_mrpci(struct gsm_lchan *lchan, u_int8_t *classmark2_lv);
+int gsm48_paging_extract_mi(struct msgb *msg, char *mi_string, u_int8_t *mi_type);
+int gsm48_handle_paging_resp(struct msgb *msg, struct gsm_subscriber *subscr);
+
#endif
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 1ceb105df..918f30715 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -298,6 +298,8 @@ struct gsm_bts {
struct gsm_network *network;
/* number of ths BTS in network */
u_int8_t nr;
+ /* Cell Identity */
+ u_int16_t cell_identity;
/* location area code of this BTS */
u_int8_t location_area_code;
/* Training Sequence Code */
diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h
index aaf261eda..ea70c3aa2 100644
--- a/openbsc/include/openbsc/gsm_subscriber.h
+++ b/openbsc/include/openbsc/gsm_subscriber.h
@@ -7,14 +7,17 @@
#define GSM_IMEI_LENGTH 17
#define GSM_IMSI_LENGTH 17
-#define GSM_TMSI_LENGTH 17
#define GSM_NAME_LENGTH 128
#define GSM_EXTENSION_LENGTH 128
+/* reserved according to GSM 03.03 ยง 2.4 */
+#define GSM_RESERVED_TMSI 0xFFFFFFFF
+
#define GSM_MIN_EXTEN 20000
#define GSM_MAX_EXTEN 49999
#define GSM_SUBSCRIBER_FIRST_CONTACT 0x00000001
+#define tmsi_from_string(str) strtoul(str, NULL, 10)
struct gsm_equipment {
long long unsigned int id;
@@ -32,7 +35,7 @@ struct gsm_subscriber {
struct gsm_network *net;
long long unsigned int id;
char imsi[GSM_IMSI_LENGTH];
- char tmsi[GSM_TMSI_LENGTH];
+ u_int32_t tmsi;
u_int16_t lac;
char name[GSM_NAME_LENGTH];
char extension[GSM_EXTENSION_LENGTH];
@@ -70,7 +73,7 @@ enum gsm_subscriber_update_reason {
struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr);
struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr);
struct gsm_subscriber *subscr_get_by_tmsi(struct gsm_network *net,
- const char *tmsi);
+ u_int32_t tmsi);
struct gsm_subscriber *subscr_get_by_imsi(struct gsm_network *net,
const char *imsi);
struct gsm_subscriber *subscr_get_by_extension(struct gsm_network *net,
diff --git a/openbsc/src/bsc_init.c b/openbsc/src/bsc_init.c
index 9fff4feed..c626415d3 100644
--- a/openbsc/src/bsc_init.c
+++ b/openbsc/src/bsc_init.c
@@ -916,6 +916,10 @@ static void patch_si_tables(struct gsm_bts *bts)
type_4->lai = lai;
type_6->lai = lai;
+ /* set the CI */
+ type_3->cell_identity = htons(bts->cell_identity);
+ type_6->cell_identity = htons(bts->cell_identity);
+
type_4->data[2] &= 0xf0;
type_4->data[2] |= arfcn_high;
type_4->data[3] = arfcn_low;
diff --git a/openbsc/src/db.c b/openbsc/src/db.c
index 45c55aff9..270d4d90b 100644
--- a/openbsc/src/db.c
+++ b/openbsc/src/db.c
@@ -376,7 +376,7 @@ struct gsm_subscriber *db_get_subscriber(struct gsm_network *net,
string = dbi_result_get_string(result, "tmsi");
if (string)
- strncpy(subscr->tmsi, string, GSM_TMSI_LENGTH);
+ subscr->tmsi = tmsi_from_string(string);
string = dbi_result_get_string(result, "name");
if (string)
@@ -388,7 +388,7 @@ struct gsm_subscriber *db_get_subscriber(struct gsm_network *net,
subscr->lac = dbi_result_get_uint(result, "lac");
subscr->authorized = dbi_result_get_uint(result, "authorized");
- printf("DB: Found Subscriber: ID %llu, IMSI %s, NAME '%s', TMSI %s, EXTEN '%s', LAC %hu, AUTH %u\n",
+ printf("DB: Found Subscriber: ID %llu, IMSI %s, NAME '%s', TMSI %u, EXTEN '%s', LAC %hu, AUTH %u\n",
subscr->id, subscr->imsi, subscr->name, subscr->tmsi, subscr->extension,
subscr->lac, subscr->authorized);
dbi_result_free(result);
@@ -400,12 +400,15 @@ struct gsm_subscriber *db_get_subscriber(struct gsm_network *net,
int db_sync_subscriber(struct gsm_subscriber* subscriber) {
dbi_result result;
+ char tmsi[14];
char *q_tmsi;
- if (subscriber->tmsi[0])
+
+ if (subscriber->tmsi != GSM_RESERVED_TMSI) {
+ sprintf(tmsi, "%u", subscriber->tmsi);
dbi_conn_quote_string_copy(conn,
- subscriber->tmsi,
+ tmsi,
&q_tmsi);
- else
+ } else
q_tmsi = strdup("NULL");
result = dbi_conn_queryf(conn,
"UPDATE Subscriber "
@@ -475,10 +478,15 @@ int db_sync_equipment(struct gsm_equipment *equip)
int db_subscriber_alloc_tmsi(struct gsm_subscriber* subscriber) {
dbi_result result=NULL;
+ char tmsi[14];
char* tmsi_quoted;
for (;;) {
- sprintf(subscriber->tmsi, "%i", rand());
- dbi_conn_quote_string_copy(conn, subscriber->tmsi, &tmsi_quoted);
+ subscriber->tmsi = rand();
+ if (subscriber->tmsi == GSM_RESERVED_TMSI)
+ continue;
+
+ sprintf(tmsi, "%u", subscriber->tmsi);
+ dbi_conn_quote_string_copy(conn, tmsi, &tmsi_quoted);
result = dbi_conn_queryf(conn,
"SELECT * FROM Subscriber "
"WHERE tmsi = %s ",
@@ -495,7 +503,7 @@ int db_subscriber_alloc_tmsi(struct gsm_subscriber* subscriber) {
}
if (!dbi_result_next_row(result)) {
dbi_result_free(result);
- printf("DB: Allocated TMSI %s for IMSI %s.\n", subscriber->tmsi, subscriber->imsi);
+ printf("DB: Allocated TMSI %u for IMSI %s.\n", subscriber->tmsi, subscriber->imsi);
return db_sync_subscriber(subscriber);
}
dbi_result_free(result);
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c
index d6fe09fa2..bac920e31 100644
--- a/openbsc/src/gsm_04_08.c
+++ b/openbsc/src/gsm_04_08.c
@@ -291,15 +291,12 @@ static void allocate_loc_updating_req(struct gsm_lchan *lchan)
static int gsm0408_authorize(struct gsm_lchan *lchan, struct msgb *msg)
{
- u_int32_t tmsi;
-
if (authorize_subscriber(lchan->loc_operation, lchan->subscr)) {
int rc;
db_subscriber_alloc_tmsi(lchan->subscr);
- tmsi = strtoul(lchan->subscr->tmsi, NULL, 10);
release_loc_updating_req(lchan);
- rc = gsm0408_loc_upd_acc(msg->lchan, tmsi);
+ rc = gsm0408_loc_upd_acc(msg->lchan, lchan->subscr->tmsi);
/* call subscr_update after putting the loc_upd_acc
* in the transmit queue, since S_SUBSCR_ATTACHED might
* trigger further action like SMS delivery */
@@ -1054,7 +1051,8 @@ static int mm_rx_loc_upd_req(struct msgb *msg)
lchan->loc_operation->waiting_for_imei = 1;
/* look up the subscriber based on TMSI, request IMSI if it fails */
- subscr = subscr_get_by_tmsi(bts->network, mi_string);
+ subscr = subscr_get_by_tmsi(bts->network,
+ tmsi_from_string(mi_string));
if (!subscr) {
/* send IDENTITY REQUEST message to get IMSI */
rc = mm_tx_identity_req(lchan, GSM_MI_TYPE_IMSI);
@@ -1284,22 +1282,6 @@ static int gsm48_tx_mm_serv_rej(struct gsm_lchan *lchan,
return gsm48_sendmsg(msg, NULL);
}
-static int send_siemens_mrpci(struct gsm_lchan *lchan,
- u_int8_t *classmark2_lv)
-{
- struct rsl_mrpci mrpci;
-
- if (classmark2_lv[0] < 2)
- return -EINVAL;
-
- mrpci.power_class = classmark2_lv[1] & 0x7;
- mrpci.vgcs_capable = classmark2_lv[2] & (1 << 1);
- mrpci.vbs_capable = classmark2_lv[2] & (1 <<2);
- mrpci.gsm_phase = (classmark2_lv[1]) >> 5 & 0x3;
-
- return rsl_siemens_mrpci(lchan, &mrpci);
-}
-
/*
* Handle CM Service Requests
* a) Verify that the packet is long enough to contain the information
@@ -1352,7 +1334,8 @@ static int gsm48_rx_mm_serv_req(struct msgb *msg)
if (is_siemens_bts(bts))
send_siemens_mrpci(msg->lchan, classmark2-1);
- subscr = subscr_get_by_tmsi(bts->network, mi_string);
+ subscr = subscr_get_by_tmsi(bts->network,
+ tmsi_from_string(mi_string));
/* FIXME: if we don't know the TMSI, inquire abit IMSI and allocate new TMSI */
if (!subscr)
@@ -1389,7 +1372,8 @@ static int gsm48_rx_mm_imsi_detach_ind(struct msgb *msg)
switch (mi_type) {
case GSM_MI_TYPE_TMSI:
- subscr = subscr_get_by_tmsi(bts->network, mi_string);
+ subscr = subscr_get_by_tmsi(bts->network,
+ tmsi_from_string(mi_string));
break;
case GSM_MI_TYPE_IMSI:
subscr = subscr_get_by_imsi(bts->network, mi_string);
@@ -1479,23 +1463,19 @@ static int gsm48_rr_rx_pag_resp(struct msgb *msg)
struct gsm_bts *bts = msg->lchan->ts->trx->bts;
struct gsm48_hdr *gh = msgb_l3(msg);
u_int8_t *classmark2_lv = gh->data + 1;
- u_int8_t *mi_lv = gh->data + 2 + *classmark2_lv;
- u_int8_t mi_type = mi_lv[1] & GSM_MI_TYPE_MASK;
+ u_int8_t mi_type;
char mi_string[GSM48_MI_SIZE];
struct gsm_subscriber *subscr = NULL;
- struct paging_signal_data sig_data;
int rc = 0;
- gsm48_mi_to_string(mi_string, sizeof(mi_string), mi_lv+1, *mi_lv);
+ gsm48_paging_extract_mi(msg, mi_string, &mi_type);
DEBUGP(DRR, "PAGING RESPONSE: mi_type=0x%02x MI(%s)\n",
mi_type, mi_string);
- if (is_siemens_bts(bts))
- send_siemens_mrpci(msg->lchan, classmark2_lv);
-
switch (mi_type) {
case GSM_MI_TYPE_TMSI:
- subscr = subscr_get_by_tmsi(bts->network, mi_string);
+ subscr = subscr_get_by_tmsi(bts->network,
+ tmsi_from_string(mi_string));
break;
case GSM_MI_TYPE_IMSI:
subscr = subscr_get_by_imsi(bts->network, mi_string);
@@ -1514,30 +1494,7 @@ static int gsm48_rr_rx_pag_resp(struct msgb *msg)
memcpy(subscr->equipment.classmark2, classmark2_lv+1, *classmark2_lv);
db_sync_equipment(&subscr->equipment);
- if (!msg->lchan->subscr) {
- msg->lchan->subscr = subscr;
- } else if (msg->lchan->subscr != subscr) {
- DEBUGP(DRR, "<- Channel already owned by someone else?\n");
- subscr_put(subscr);
- return -EINVAL;
- } else {
- DEBUGP(DRR, "<- Channel already owned by us\n");
- subscr_put(subscr);
- subscr = msg->lchan->subscr;
- }
-
- sig_data.subscr = subscr;
- sig_data.bts = msg->lchan->ts->trx->bts;
- sig_data.lchan = msg->lchan;
-
- dispatch_signal(SS_PAGING, S_PAGING_COMPLETED, &sig_data);
-
- /* Stop paging on the bts we received the paging response */
- paging_request_stop(msg->trx->bts, subscr, msg->lchan);
-
- /* FIXME: somehow signal the completion of the PAGING to
- * the entity that requested the paging */
-
+ rc = gsm48_handle_paging_resp(msg, subscr);
return rc;
}
diff --git a/openbsc/src/gsm_04_08_utils.c b/openbsc/src/gsm_04_08_utils.c
index c62f04d57..47ec8ab0e 100644
--- a/openbsc/src/gsm_04_08_utils.c
+++ b/openbsc/src/gsm_04_08_utils.c
@@ -25,12 +25,15 @@
*/
#include <stdio.h>
#include <stdlib.h>
+#include <errno.h>
#include <netinet/in.h>
#include <openbsc/msgb.h>
#include <openbsc/debug.h>
#include <openbsc/gsm_04_08.h>
#include <openbsc/transaction.h>
+#include <openbsc/paging.h>
+#include <openbsc/signal.h>
#define GSM48_ALLOC_SIZE 1024
#define GSM48_ALLOC_HEADROOM 128
@@ -395,3 +398,62 @@ int gsm48_mi_to_string(char *string, const int str_len, const u_int8_t *mi, cons
return str_cur - string;
}
+
+int send_siemens_mrpci(struct gsm_lchan *lchan,
+ u_int8_t *classmark2_lv)
+{
+ struct rsl_mrpci mrpci;
+
+ if (classmark2_lv[0] < 2)
+ return -EINVAL;
+
+ mrpci.power_class = classmark2_lv[1] & 0x7;
+ mrpci.vgcs_capable = classmark2_lv[2] & (1 << 1);
+ mrpci.vbs_capable = classmark2_lv[2] & (1 <<2);
+ mrpci.gsm_phase = (classmark2_lv[1]) >> 5 & 0x3;
+
+ return rsl_siemens_mrpci(lchan, &mrpci);
+}
+
+int gsm48_paging_extract_mi(struct msgb *msg, char *mi_string, u_int8_t *mi_type)
+{
+ struct gsm48_hdr *gh = msgb_l3(msg);
+ u_int8_t *classmark2_lv = gh->data + 1;
+ u_int8_t *mi_lv = gh->data + 2 + *classmark2_lv;
+ *mi_type = mi_lv[1] & GSM_MI_TYPE_MASK;
+
+ return gsm48_mi_to_string(mi_string, GSM48_MI_SIZE, mi_lv+1, *mi_lv);
+}
+
+int gsm48_handle_paging_resp(struct msgb *msg, struct gsm_subscriber *subscr)
+{
+ struct gsm_bts *bts = msg->lchan->ts->trx->bts;
+ struct gsm48_hdr *gh = msgb_l3(msg);
+ u_int8_t *classmark2_lv = gh->data + 1;
+ struct paging_signal_data sig_data;
+
+ if (is_siemens_bts(bts))
+ send_siemens_mrpci(msg->lchan, classmark2_lv);
+
+ if (!msg->lchan->subscr) {
+ msg->lchan->subscr = subscr;
+ } else if (msg->lchan->subscr != subscr) {
+ DEBUGP(DRR, "<- Channel already owned by someone else?\n");
+ subscr_put(subscr);
+ return -EINVAL;
+ } else {
+ DEBUGP(DRR, "<- Channel already owned by us\n");
+ subscr_put(subscr);
+ subscr = msg->lchan->subscr;
+ }
+
+ sig_data.subscr = subscr;
+ sig_data.bts = msg->lchan->ts->trx->bts;
+ sig_data.lchan = msg->lchan;
+
+ dispatch_signal(SS_PAGING, S_PAGING_COMPLETED, &sig_data);
+
+ /* Stop paging on the bts we received the paging response */
+ paging_request_stop(msg->trx->bts, subscr, msg->lchan);
+ return 0;
+}
diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c
index 7e8100dcb..9db246cec 100644
--- a/openbsc/src/gsm_data.c
+++ b/openbsc/src/gsm_data.c
@@ -274,7 +274,7 @@ struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac,
continue;
}
- if (bts->location_area_code == lac)
+ if (lac == 0 || bts->location_area_code == lac)
return bts;
}
return NULL;
diff --git a/openbsc/src/gsm_subscriber.c b/openbsc/src/gsm_subscriber.c
index 84e14a0ea..a4e35c7b1 100644
--- a/openbsc/src/gsm_subscriber.c
+++ b/openbsc/src/gsm_subscriber.c
@@ -35,17 +35,19 @@
extern struct llist_head *subscr_bsc_active_subscriber(void);
struct gsm_subscriber *subscr_get_by_tmsi(struct gsm_network *net,
- const char *tmsi)
+ u_int32_t tmsi)
{
+ char tmsi_string[14];
struct gsm_subscriber *subscr;
/* we might have a record in memory already */
llist_for_each_entry(subscr, subscr_bsc_active_subscriber(), entry) {
- if (strcmp(subscr->tmsi, tmsi) == 0)
+ if (tmsi == subscr->tmsi)
return subscr_get(subscr);
}
- return db_get_subscriber(net, GSM_SUBSCRIBER_TMSI, tmsi);
+ sprintf(tmsi_string, "%u", tmsi);
+ return db_get_subscriber(net, GSM_SUBSCRIBER_TMSI, tmsi_string);
}
struct gsm_subscriber *subscr_get_by_imsi(struct gsm_network *net,
diff --git a/openbsc/src/gsm_subscriber_base.c b/openbsc/src/gsm_subscriber_base.c
index d6a179b5c..868b35599 100644
--- a/openbsc/src/gsm_subscriber_base.c
+++ b/openbsc/src/gsm_subscriber_base.c
@@ -73,7 +73,9 @@ static int subscr_paging_cb(unsigned int hooknum, unsigned int event,
struct subscr_request *request;
struct gsm_subscriber *subscr = (struct gsm_subscriber *)param;
- assert(!llist_empty(&subscr->requests));
+ /* There is no request anymore... */
+ if (llist_empty(&subscr->requests))
+ return -1;
/*
* FIXME: What to do with paging requests coming during
@@ -94,11 +96,19 @@ static int subscr_paging_cb(unsigned int hooknum, unsigned int event,
static void subscr_send_paging_request(struct gsm_subscriber *subscr)
{
struct subscr_request *request;
+ int rc;
+
assert(!llist_empty(&subscr->requests));
request = (struct subscr_request *)subscr->requests.next;
- paging_request(subscr->net, subscr, request->channel_type,
- subscr_paging_cb, subscr);
+ rc = paging_request(subscr->net, subscr, request->channel_type,
+ subscr_paging_cb, subscr);
+
+ /* paging failed, quit now */
+ if (rc <= 0) {
+ subscr_paging_cb(GSM_HOOK_RR_PAGING, GSM_PAGING_EXPIRED,
+ NULL, NULL, request->param);
+ }
}
struct gsm_subscriber *subscr_alloc(void)
@@ -112,6 +122,7 @@ struct gsm_subscriber *subscr_alloc(void)
memset(s, 0, sizeof(*s));
llist_add_tail(&s->entry, &active_subscribers);
s->use_count = 1;
+ s->tmsi = GSM_RESERVED_TMSI;
INIT_LLIST_HEAD(&s->requests);
diff --git a/openbsc/src/openbsc.cfg.1-1 b/openbsc/src/openbsc.cfg.1-1
index acd6681dc..a8331ddbd 100644
--- a/openbsc/src/openbsc.cfg.1-1
+++ b/openbsc/src/openbsc.cfg.1-1
@@ -14,6 +14,7 @@ network
bts 0
type bs11
band GSM900
+ cell_identity 1
location_area_code 1
training_sequence_code 7
base_station_id_code 63
diff --git a/openbsc/src/openbsc.cfg.1-2 b/openbsc/src/openbsc.cfg.1-2
index 6bb6522df..10aa7b48b 100644
--- a/openbsc/src/openbsc.cfg.1-2
+++ b/openbsc/src/openbsc.cfg.1-2
@@ -14,6 +14,7 @@ network
bts 0
type bs11
band GSM900
+ cell_identity 1
location_area_code 1
training_sequence_code 7
base_station_id_code 63
diff --git a/openbsc/src/openbsc.cfg.2-2 b/openbsc/src/openbsc.cfg.2-2
index 461f8e921..0dd9d9b5d 100644
--- a/openbsc/src/openbsc.cfg.2-2
+++ b/openbsc/src/openbsc.cfg.2-2
@@ -14,6 +14,7 @@ network
bts 0
type bs11
band GSM900
+ cell_identity 1
location_area_code 1
training_sequence_code 7
base_station_id_code 63
diff --git a/openbsc/src/paging.c b/openbsc/src/paging.c
index fd0611a14..87c7e7d38 100644
--- a/openbsc/src/paging.c
+++ b/openbsc/src/paging.c
@@ -46,9 +46,6 @@
#include <openbsc/abis_rsl.h>
#include <openbsc/gsm_data.h>
-#define PAGING_TIMEOUT 1, 75000
-#define MAX_PAGING_REQUEST 750
-
void *tall_paging_ctx;
static unsigned int calculate_group(struct gsm_bts *bts, struct gsm_subscriber *subscr)
@@ -90,16 +87,18 @@ static void paging_remove_request(struct gsm_bts_paging_state *paging_bts,
static void page_ms(struct gsm_paging_request *request)
{
u_int8_t mi[128];
- unsigned long int tmsi;
unsigned int mi_len;
unsigned int page_group;
- DEBUGP(DPAG, "Going to send paging commands: '%s'\n",
- request->subscr->imsi);
+ DEBUGP(DPAG, "Going to send paging commands: imsi: '%s' tmsi: '0x%x'\n",
+ request->subscr->imsi, request->subscr->tmsi);
+
+ if (request->subscr->tmsi == GSM_RESERVED_TMSI)
+ mi_len = gsm48_generate_mid_from_imsi(mi, request->subscr->imsi);
+ else
+ mi_len = gsm48_generate_mid_from_tmsi(mi, request->subscr->tmsi);
page_group = calculate_group(request->bts, request->subscr);
- tmsi = strtoul(request->subscr->tmsi, NULL, 10);
- mi_len = gsm48_generate_mid_from_tmsi(mi, tmsi);
rsl_paging_cmd(request->bts, page_group, mi_len, mi,
request->chan_type);
}
@@ -296,7 +295,8 @@ void paging_request_stop(struct gsm_bts *_bts, struct gsm_subscriber *subscr,
{
struct gsm_bts *bts = NULL;
- _paging_request_stop(_bts, subscr, lchan);
+ if (_bts)
+ _paging_request_stop(_bts, subscr, lchan);
do {
/*
@@ -305,7 +305,7 @@ void paging_request_stop(struct gsm_bts *_bts, struct gsm_subscriber *subscr,
* location area of the _bts as reconfiguration of the
* network is probably happening less often.
*/
- bts = gsm_bts_by_lac(_bts->network, subscr->lac, bts);
+ bts = gsm_bts_by_lac(subscr->net, subscr->lac, bts);
if (!bts)
break;
diff --git a/openbsc/src/transaction.c b/openbsc/src/transaction.c
index 8e2b0b638..950faa2f1 100644
--- a/openbsc/src/transaction.c
+++ b/openbsc/src/transaction.c
@@ -102,15 +102,7 @@ void trans_free(struct gsm_trans *trans)
if (!trans->lchan && trans->subscr && trans->subscr->net) {
/* Stop paging on all bts' */
- bts = NULL;
- do {
- bts = gsm_bts_by_lac(trans->subscr->net,
- trans->subscr->lac, bts);
- if (!bts)
- break;
- /* Stop paging */
- paging_request_stop(bts, trans->subscr, NULL);
- } while (1);
+ paging_request_stop(NULL, trans->subscr, NULL);
}
if (trans->subscr)
diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c
index f75cfaf8a..b6a9deaba 100644
--- a/openbsc/src/vty_interface.c
+++ b/openbsc/src/vty_interface.c
@@ -118,9 +118,10 @@ static void e1isl_dump_vty(struct vty *vty, struct e1inp_sign_link *e1l)
static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
{
- vty_out(vty, "BTS %u is of %s type in band %s, has LAC %u, "
+ vty_out(vty, "BTS %u is of %s type in band %s, has CI %u LAC %u, "
"BSIC %u, TSC %u and %u TRX%s",
bts->nr, btstype2str(bts->type), gsm_band_name(bts->band),
+ bts->cell_identity,
bts->location_area_code, bts->bsic, bts->tsc,
bts->num_trx, VTY_NEWLINE);
if (bts->cell_barred)
@@ -223,6 +224,7 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
vty_out(vty, " bts %u%s", bts->nr, VTY_NEWLINE);
vty_out(vty, " type %s%s", btstype2str(bts->type), VTY_NEWLINE);
vty_out(vty, " band %s%s", gsm_band_name(bts->band), VTY_NEWLINE);
+ vty_out(vty, " cell_identity %u%s", bts->cell_identity, VTY_NEWLINE);
vty_out(vty, " location_area_code %u%s", bts->location_area_code,
VTY_NEWLINE);
vty_out(vty, " training_sequence_code %u%s", bts->tsc, VTY_NEWLINE);
@@ -427,8 +429,8 @@ void subscr_dump_vty(struct vty *vty, struct gsm_subscriber *subscr)
VTY_NEWLINE);
if (subscr->imsi)
vty_out(vty, " IMSI: %s%s", subscr->imsi, VTY_NEWLINE);
- if (subscr->tmsi)
- vty_out(vty, " TMSI: %08X%s", atoi(subscr->tmsi),
+ if (subscr->tmsi != GSM_RESERVED_TMSI)
+ vty_out(vty, " TMSI: %08X%s", subscr->tmsi,
VTY_NEWLINE);
vty_out(vty, " Use count: %u%s", subscr->use_count, VTY_NEWLINE);
}
@@ -839,6 +841,24 @@ DEFUN(cfg_bts_band,
return CMD_SUCCESS;
}
+DEFUN(cfg_bts_ci,
+ cfg_bts_ci_cmd,
+ "cell_identity <0-65535>",
+ "Set the Cell identity of this BTS\n")
+{
+ struct gsm_bts *bts = vty->index;
+ int ci = atoi(argv[0]);
+
+ if (ci < 0 || ci > 0xffff) {
+ vty_out(vty, "%% CI %d is not in the valid range (0-65535)%s",
+ ci, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ bts->cell_identity = ci;
+
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_bts_lac,
cfg_bts_lac_cmd,
"location_area_code <0-255>",
@@ -1175,6 +1195,7 @@ int bsc_vty_init(struct gsm_network *net)
install_default(BTS_NODE);
install_element(BTS_NODE, &cfg_bts_type_cmd);
install_element(BTS_NODE, &cfg_bts_band_cmd);
+ install_element(BTS_NODE, &cfg_bts_ci_cmd);
install_element(BTS_NODE, &cfg_bts_lac_cmd);
install_element(BTS_NODE, &cfg_bts_tsc_cmd);
install_element(BTS_NODE, &cfg_bts_bsic_cmd);
diff --git a/openbsc/tests/db/db_test.c b/openbsc/tests/db/db_test.c
index a248e6025..f168acb64 100644
--- a/openbsc/tests/db/db_test.c
+++ b/openbsc/tests/db/db_test.c
@@ -38,8 +38,8 @@
if (strcmp(original->imsi, copy->imsi) != 0) \
fprintf(stderr, "IMSIs do not match in %s:%d '%s' '%s'\n", \
__FUNCTION__, __LINE__, original->imsi, copy->imsi); \
- if (strcmp(original->tmsi, copy->tmsi) != 0) \
- fprintf(stderr, "TMSIs do not match in %s:%d '%s' '%s'\n", \
+ if (original->tmsi != copy->tmsi) \
+ fprintf(stderr, "TMSIs do not match in %s:%d '%u' '%u'\n", \
__FUNCTION__, __LINE__, original->tmsi, copy->tmsi); \
if (strcmp(original->name, copy->name) != 0) \
fprintf(stderr, "names do not match in %s:%d '%s' '%s'\n", \