* fix IMSI parsing of last two digits
* add MM INFO packet support and send it after LOCATION ACCEPT * send 'ALL YOUR BASE ARE BELONG TO US'
This commit is contained in:
parent
89824fc466
commit
db253af1aa
116
src/gsm_04_08.c
116
src/gsm_04_08.c
|
@ -27,6 +27,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <time.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#include <openbsc/db.h>
|
#include <openbsc/db.h>
|
||||||
|
@ -99,6 +100,17 @@ static void to_bcd(u_int8_t *bcd, u_int16_t val)
|
||||||
val = val / 10;
|
val = val / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u_int8_t to_bcd8(unsigned int val)
|
||||||
|
{
|
||||||
|
u_int8_t bcd;
|
||||||
|
|
||||||
|
bcd = (val % 10) & 0x0f;
|
||||||
|
val = val / 10;
|
||||||
|
bcd |= (val % 10) << 4;
|
||||||
|
|
||||||
|
return bcd;
|
||||||
|
}
|
||||||
|
|
||||||
void gsm0408_generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc,
|
void gsm0408_generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc,
|
||||||
u_int16_t mnc, u_int16_t lac)
|
u_int16_t mnc, u_int16_t lac)
|
||||||
{
|
{
|
||||||
|
@ -183,7 +195,9 @@ int gsm0408_loc_upd_rej(struct gsm_lchan *lchan, u_int8_t cause)
|
||||||
gh->msg_type = GSM48_MT_MM_LOC_UPD_REJECT;
|
gh->msg_type = GSM48_MT_MM_LOC_UPD_REJECT;
|
||||||
gh->data[0] = cause;
|
gh->data[0] = cause;
|
||||||
|
|
||||||
DEBUGP(DMM, "-> LOCATION UPDATING REJECT\n");
|
DEBUGP(DMM, "-> LOCATION UPDATING REJECT on channel: %d\n", lchan->nr);
|
||||||
|
|
||||||
|
//gsm0411_send_sms(lchan, NULL);
|
||||||
|
|
||||||
return gsm48_sendmsg(msg);
|
return gsm48_sendmsg(msg);
|
||||||
}
|
}
|
||||||
|
@ -214,12 +228,16 @@ int gsm0408_loc_upd_acc(struct gsm_lchan *lchan, u_int32_t tmsi)
|
||||||
lchan->pending_update_request = 0;
|
lchan->pending_update_request = 0;
|
||||||
DEBUGP(DMM, "-> LOCATION UPDATE ACCEPT\n");
|
DEBUGP(DMM, "-> LOCATION UPDATE ACCEPT\n");
|
||||||
|
|
||||||
ret = gsm48_sendmsg(msg);
|
|
||||||
|
|
||||||
/* inform the upper layer on the progress */
|
/* inform the upper layer on the progress */
|
||||||
if (bts->network->update_request)
|
if (bts->network->update_request)
|
||||||
(*bts->network->update_request)(bts, tmsi, 1);
|
(*bts->network->update_request)(bts, tmsi, 1);
|
||||||
|
|
||||||
|
ret = gsm48_sendmsg(msg);
|
||||||
|
|
||||||
|
/* return gsm48_cc_tx_setup(lchan); */
|
||||||
|
ret = gsm48_tx_mm_info(lchan);
|
||||||
|
ret = gsm0411_send_sms(lchan, NULL);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,7 +262,8 @@ static int mi_to_string(char *string, int str_len, u_int8_t *mi, int mi_len)
|
||||||
case GSM_MI_TYPE_NONE:
|
case GSM_MI_TYPE_NONE:
|
||||||
break;
|
break;
|
||||||
case GSM_MI_TYPE_TMSI:
|
case GSM_MI_TYPE_TMSI:
|
||||||
for (i = 1; i < mi_len - 1; i++) {
|
/* skip padding nibble at the beginning, start at offset 1... */
|
||||||
|
for (i = 1; i < mi_len; i++) {
|
||||||
if (str_cur + 2 >= string + str_len)
|
if (str_cur + 2 >= string + str_len)
|
||||||
return str_cur - string;
|
return str_cur - string;
|
||||||
*str_cur++ = bcd2char(mi[i] >> 4);
|
*str_cur++ = bcd2char(mi[i] >> 4);
|
||||||
|
@ -254,21 +273,22 @@ static int mi_to_string(char *string, int str_len, u_int8_t *mi, int mi_len)
|
||||||
case GSM_MI_TYPE_IMSI:
|
case GSM_MI_TYPE_IMSI:
|
||||||
case GSM_MI_TYPE_IMEI:
|
case GSM_MI_TYPE_IMEI:
|
||||||
case GSM_MI_TYPE_IMEISV:
|
case GSM_MI_TYPE_IMEISV:
|
||||||
if (mi[0] & GSM_MI_ODD)
|
*str_cur++ = bcd2char(mi[0] >> 4);
|
||||||
*str_cur++ = bcd2char(mi[0] >> 4);
|
|
||||||
|
for (i = 1; i < mi_len; i++) {
|
||||||
for (i = 1; i < mi_len - 1; i++) {
|
|
||||||
if (str_cur + 2 >= string + str_len)
|
if (str_cur + 2 >= string + str_len)
|
||||||
return str_cur - string;
|
return str_cur - string;
|
||||||
*str_cur++ = bcd2char(mi[i] & 0xf);
|
*str_cur++ = bcd2char(mi[i] & 0xf);
|
||||||
*str_cur++ = bcd2char(mi[i] >> 4);
|
/* skip last nibble in last input byte when GSM_EVEN */
|
||||||
|
if( (i != mi_len-1) || (mi[0] & GSM_MI_ODD))
|
||||||
|
*str_cur++ = bcd2char(mi[i] >> 4);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
*str_cur++ = '\0';
|
*str_cur++ = '\0';
|
||||||
|
|
||||||
return str_cur - string;
|
return str_cur - string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,6 +333,7 @@ static int mm_rx_id_resp(struct msgb *msg)
|
||||||
if (authorize_subscriber(lchan->subscr)) {
|
if (authorize_subscriber(lchan->subscr)) {
|
||||||
db_subscriber_alloc_tmsi(lchan->subscr);
|
db_subscriber_alloc_tmsi(lchan->subscr);
|
||||||
tmsi = strtoul(lchan->subscr->tmsi, NULL, 10);
|
tmsi = strtoul(lchan->subscr->tmsi, NULL, 10);
|
||||||
|
del_timer(&lchan->timer);
|
||||||
return gsm0408_loc_upd_acc(msg->lchan, tmsi);
|
return gsm0408_loc_upd_acc(msg->lchan, tmsi);
|
||||||
} else {
|
} else {
|
||||||
schedule_reject(lchan);
|
schedule_reject(lchan);
|
||||||
|
@ -334,7 +355,8 @@ static void loc_upd_rej_cb(void *data)
|
||||||
{
|
{
|
||||||
struct gsm_lchan *lchan = data;
|
struct gsm_lchan *lchan = data;
|
||||||
|
|
||||||
gsm0408_loc_upd_rej(lchan, 0x16);
|
/* 0x16 is congestion */
|
||||||
|
gsm0408_loc_upd_rej(lchan, 0x04);
|
||||||
rsl_chan_release(lchan);
|
rsl_chan_release(lchan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,9 +434,81 @@ static int mm_rx_loc_upd_req(struct msgb *msg)
|
||||||
|
|
||||||
tmsi = strtoul(subscr->tmsi, NULL, 10);
|
tmsi = strtoul(subscr->tmsi, NULL, 10);
|
||||||
|
|
||||||
|
del_timer(&lchan->timer);
|
||||||
return gsm0408_loc_upd_acc(lchan, tmsi);
|
return gsm0408_loc_upd_acc(lchan, tmsi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Section 9.2.15a */
|
||||||
|
int gsm48_tx_mm_info(struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
struct msgb *msg = gsm48_msgb_alloc();
|
||||||
|
struct gsm48_hdr *gh;
|
||||||
|
struct gsm_network *net = lchan->ts->trx->bts->network;
|
||||||
|
time_t cur_t;
|
||||||
|
struct tm* cur_time;
|
||||||
|
u_int8_t *ptr8;
|
||||||
|
u_int16_t *ptr16;
|
||||||
|
int name_len;
|
||||||
|
int tz15min;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
msg->lchan = lchan;
|
||||||
|
|
||||||
|
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
|
||||||
|
gh->proto_discr = GSM48_PDISC_MM;
|
||||||
|
gh->msg_type = GSM48_MT_MM_INFO;
|
||||||
|
|
||||||
|
if (net->name_long) {
|
||||||
|
name_len = strlen(net->name_long);
|
||||||
|
/* 10.5.3.5a */
|
||||||
|
ptr8 = msgb_put(msg, 3);
|
||||||
|
ptr8[0] = GSM48_IE_NAME_LONG;
|
||||||
|
ptr8[1] = name_len*2 +1;
|
||||||
|
ptr8[2] = 0x90; /* UCS2, no spare bits, no CI */
|
||||||
|
|
||||||
|
ptr16 = (u_int16_t *) msgb_put(msg, name_len*2);
|
||||||
|
for (i = 0; i < name_len; i++)
|
||||||
|
ptr16[i] = net->name_long[i];
|
||||||
|
|
||||||
|
/* FIXME: Use Cell Broadcast, not UCS-2, since
|
||||||
|
* UCS-2 is only supported by later revisions of the spec */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (net->name_short) {
|
||||||
|
name_len = strlen(net->name_short);
|
||||||
|
/* 10.5.3.5a */
|
||||||
|
ptr8 = (u_int8_t *) msgb_put(msg, 3);
|
||||||
|
ptr8[0] = GSM48_IE_NAME_LONG;
|
||||||
|
ptr8[1] = name_len*2 + 1;
|
||||||
|
ptr8[2] = 0x90; /* UCS2, no spare bits, no CI */
|
||||||
|
|
||||||
|
ptr16 = msgb_put(msg, name_len*2);
|
||||||
|
for (i = 0; i < name_len; i++)
|
||||||
|
ptr16[i] = net->name_short[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* Section 10.5.3.9 */
|
||||||
|
cur_t = time(NULL);
|
||||||
|
cur_time = gmtime(cur_t);
|
||||||
|
ptr8 = msgb_put(msg, 8);
|
||||||
|
ptr8[0] = GSM48_IE_NET_TIME_TZ;
|
||||||
|
ptr8[1] = to_bcd8(cur_time->tm_year % 100);
|
||||||
|
ptr8[2] = to_bcd8(cur_time->tm_mon);
|
||||||
|
ptr8[3] = to_bcd8(cur_time->tm_mday);
|
||||||
|
ptr8[4] = to_bcd8(cur_time->tm_hour);
|
||||||
|
ptr8[5] = to_bcd8(cur_time->tm_min);
|
||||||
|
ptr8[6] = to_bcd8(cur_time->tm_sec);
|
||||||
|
/* 02.42: coded as BCD encoded signed value in units of 15 minutes */
|
||||||
|
tz15min = (cur_time->tm_gmtoff)/(60*15);
|
||||||
|
ptr8[6] = to_bcd8(tz15min);
|
||||||
|
if (tz15min < 0)
|
||||||
|
ptr8[6] |= 0x80;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return gsm48_sendmsg(msg);
|
||||||
|
}
|
||||||
|
|
||||||
static int gsm48_tx_mm_serv_ack(struct gsm_lchan *lchan)
|
static int gsm48_tx_mm_serv_ack(struct gsm_lchan *lchan)
|
||||||
{
|
{
|
||||||
DEBUGP(DMM, "-> CM SERVICE ACK\n");
|
DEBUGP(DMM, "-> CM SERVICE ACK\n");
|
||||||
|
|
Loading…
Reference in New Issue