[tmsi] Make the tmsi a 4 octet number
tmsi is four octets long, there is no need to make it a string and then jump through hoops to convert it to a number. Keep the database using it as a string to benefit from the NULL handling of the db. Introduce the reserved tmsi which has all bits set to 1 according to GSM 03.03 §2.4 and start checking for it and make sure the db code will never allocate such a tmsi.
This commit is contained in:
parent
6b0b103bdc
commit
2223025e21
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
@ -1352,7 +1350,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 +1388,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);
|
||||
|
@ -1495,7 +1495,8 @@ static int gsm48_rr_rx_pag_resp(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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -112,6 +112,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);
|
||||
|
||||
|
|
|
@ -90,7 +90,6 @@ 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;
|
||||
|
||||
|
@ -98,8 +97,7 @@ static void page_ms(struct gsm_paging_request *request)
|
|||
request->subscr->imsi);
|
||||
|
||||
page_group = calculate_group(request->bts, request->subscr);
|
||||
tmsi = strtoul(request->subscr->tmsi, NULL, 10);
|
||||
mi_len = gsm48_generate_mid_from_tmsi(mi, tmsi);
|
||||
mi_len = gsm48_generate_mid_from_tmsi(mi, request->subscr->tmsi);
|
||||
rsl_paging_cmd(request->bts, page_group, mi_len, mi,
|
||||
request->chan_type);
|
||||
}
|
||||
|
|
|
@ -427,8 +427,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);
|
||||
}
|
||||
|
|
|
@ -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 New Issue