mirror of
https://gerrit.osmocom.org/osmo-gbproxy
synced 2024-08-18 08:56:23 +00:00
Merge branch 'holger/merge-on-waves-msc'
This commit is contained in:
commit
51a7b9a973
17 changed files with 167 additions and 98 deletions
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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", \
|
||||
|
|
Loading…
Reference in a new issue