working state up to location update and classmark inquiry
This commit is contained in:
parent
fdd0a6c157
commit
255539c742
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <openbsc/timer.h>
|
||||||
|
|
||||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
|
||||||
#define GSM_MAX_BTS 8
|
#define GSM_MAX_BTS 8
|
||||||
|
@ -67,6 +69,8 @@ struct gsm_lchan {
|
||||||
enum gsm_chan_t type;
|
enum gsm_chan_t type;
|
||||||
/* To whom we are allocated at the moment */
|
/* To whom we are allocated at the moment */
|
||||||
struct gsm_subscriber *subscr;
|
struct gsm_subscriber *subscr;
|
||||||
|
/* Universal timer, undefined use ;) */
|
||||||
|
struct timer_list timer;
|
||||||
|
|
||||||
/* local end of a call, if any */
|
/* local end of a call, if any */
|
||||||
struct gsm_call call;
|
struct gsm_call call;
|
||||||
|
|
|
@ -374,7 +374,7 @@ int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
|
||||||
dh->chan_nr = RSL_CHAN_PCH_AGCH;
|
dh->chan_nr = RSL_CHAN_PCH_AGCH;
|
||||||
|
|
||||||
msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
|
msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
|
||||||
msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len, ms_ident);
|
msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
|
||||||
msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
|
msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
|
||||||
|
|
||||||
msg->trx = bts->c0;
|
msg->trx = bts->c0;
|
||||||
|
|
|
@ -30,7 +30,10 @@
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
|
||||||
|
#include <openbsc/db.h>
|
||||||
|
#include <openbsc/timer.h>
|
||||||
#include <openbsc/gsm_data.h>
|
#include <openbsc/gsm_data.h>
|
||||||
|
#include <openbsc/gsm_04_08.h>
|
||||||
#include <openbsc/select.h>
|
#include <openbsc/select.h>
|
||||||
#include <openbsc/abis_rsl.h>
|
#include <openbsc/abis_rsl.h>
|
||||||
#include <openbsc/abis_nm.h>
|
#include <openbsc/abis_nm.h>
|
||||||
|
@ -631,6 +634,74 @@ static void handle_options(int argc, char** argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct timer_list pag_timer;
|
||||||
|
|
||||||
|
/* handles uppercase decimal and hexadecimal */
|
||||||
|
static u_int8_t char2bcd(char c)
|
||||||
|
{
|
||||||
|
if (c <= '9')
|
||||||
|
return c - '0';
|
||||||
|
else
|
||||||
|
return c - 'A';
|
||||||
|
}
|
||||||
|
|
||||||
|
static int string_to_mi(u_int8_t *mi, const char *string,
|
||||||
|
u_int8_t type)
|
||||||
|
{
|
||||||
|
u_int8_t *cur = mi+3;
|
||||||
|
|
||||||
|
mi[0] = GSM48_IE_MOBILE_ID;
|
||||||
|
//mi[1] = TMSI_LEN;
|
||||||
|
mi[2] = type & GSM_MI_TYPE_MASK;
|
||||||
|
|
||||||
|
if (strlen(string) & 0x01)
|
||||||
|
mi[2] |= char2bcd(*string++) << 4;
|
||||||
|
else
|
||||||
|
mi[2] |= 0xf0;
|
||||||
|
|
||||||
|
while (*string && *(string+1))
|
||||||
|
*cur++ = char2bcd(*string++) | (char2bcd(*string++) << 4);
|
||||||
|
|
||||||
|
mi[1] = cur - mi;
|
||||||
|
|
||||||
|
return cur - mi;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *nokia_imsi = "7240311131388";
|
||||||
|
static const char *rokr_imsi = "4660198001300";
|
||||||
|
|
||||||
|
void pag_timer_cb(void *data)
|
||||||
|
{
|
||||||
|
struct gsm_bts *bts = &gsmnet->bts[0];
|
||||||
|
u_int8_t mi[128];
|
||||||
|
struct gsm_subscriber _subscr, *subscr = &_subscr;
|
||||||
|
unsigned int paging_group, mi_len;
|
||||||
|
u_int64_t num_imsi;
|
||||||
|
const char *imsi = nokia_imsi;
|
||||||
|
|
||||||
|
printf("FEUER\n");
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
memset(subscr, 0, sizeof(*subscr));
|
||||||
|
strcpy(subscr->imsi, imsi);
|
||||||
|
db_get_subscriber(GSM_SUBSCRIBER_IMSI, subscr);
|
||||||
|
if (!subscr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mi_len = generate_mid_from_tmsi(mi, strtoul(subscr->tmsi, NULL, 10));
|
||||||
|
#else
|
||||||
|
mi_len = string_to_mi(mi, imsi, GSM_MI_TYPE_IMSI);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
num_imsi = strtoull(imsi, NULL, 10);
|
||||||
|
paging_group = get_paging_group(num_imsi, 1, 3);
|
||||||
|
|
||||||
|
for (paging_group = 0; paging_group < 3; paging_group++)
|
||||||
|
rsl_paging_cmd(bts, paging_group, mi_len, mi, RSL_CHANNEED_TCH_F);
|
||||||
|
|
||||||
|
schedule_timer(&pag_timer, 10, 0);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
/* parse options */
|
/* parse options */
|
||||||
|
@ -650,6 +721,9 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
bootstrap_network();
|
bootstrap_network();
|
||||||
|
|
||||||
|
pag_timer.cb = pag_timer_cb;
|
||||||
|
schedule_timer(&pag_timer, 10, 0);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
bsc_select_main();
|
bsc_select_main();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
||||||
|
|
|
@ -97,15 +97,19 @@ static void generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc,
|
||||||
lai48->lac = htons(lac);
|
lai48->lac = htons(lac);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TMSI_LEN 4
|
#define TMSI_LEN 5
|
||||||
#define MID_TMSI_LEN (TMSI_LEN + 2)
|
#define MID_TMSI_LEN (TMSI_LEN + 2)
|
||||||
|
|
||||||
static void generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi)
|
int generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi)
|
||||||
{
|
{
|
||||||
|
u_int32_t *tptr = &buf[3];
|
||||||
|
|
||||||
buf[0] = GSM48_IE_MOBILE_ID;
|
buf[0] = GSM48_IE_MOBILE_ID;
|
||||||
buf[1] = TMSI_LEN;
|
buf[1] = TMSI_LEN;
|
||||||
buf[2] = 0xf0 | GSM_MI_TYPE_TMSI;
|
buf[2] = 0xf0 | GSM_MI_TYPE_TMSI;
|
||||||
*((u_int32_t *) &buf[3]) = htonl(tmsi);
|
*tptr = htonl(tmsi);
|
||||||
|
|
||||||
|
return 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct msgb *gsm48_msgb_alloc(void)
|
static struct msgb *gsm48_msgb_alloc(void)
|
||||||
|
@ -256,11 +260,12 @@ static int mm_rx_id_resp(struct msgb *msg)
|
||||||
if (lchan->subscr && lchan->subscr->authorized) {
|
if (lchan->subscr && lchan->subscr->authorized) {
|
||||||
/* FIXME: check if we've recently received UPDATE REQUEST */
|
/* FIXME: check if we've recently received UPDATE REQUEST */
|
||||||
db_subscriber_alloc_tmsi(lchan->subscr);
|
db_subscriber_alloc_tmsi(lchan->subscr);
|
||||||
tmsi = strtoul(lchan->subscr->tmsi, NULL, 16);
|
tmsi = strtoul(lchan->subscr->tmsi, NULL, 10);
|
||||||
return gsm0408_loc_upd_acc(msg->lchan, tmsi);
|
return gsm0408_loc_upd_acc(msg->lchan, tmsi);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GSM_MI_TYPE_IMEI:
|
case GSM_MI_TYPE_IMEI:
|
||||||
|
case GSM_MI_TYPE_IMEISV:
|
||||||
/* update subscribe <-> IMEI mapping */
|
/* update subscribe <-> IMEI mapping */
|
||||||
if (lchan->subscr)
|
if (lchan->subscr)
|
||||||
db_subscriber_assoc_imei(lchan->subscr, mi_string);
|
db_subscriber_assoc_imei(lchan->subscr, mi_string);
|
||||||
|
@ -269,6 +274,15 @@ static int mm_rx_id_resp(struct msgb *msg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void loc_upd_rej_cb(void *data)
|
||||||
|
{
|
||||||
|
struct gsm_lchan *lchan = data;
|
||||||
|
|
||||||
|
gsm0408_loc_upd_rej(lchan, 0x16);
|
||||||
|
rsl_chan_release(lchan);
|
||||||
|
}
|
||||||
|
|
||||||
#define MI_SIZE 32
|
#define MI_SIZE 32
|
||||||
/* Chapter 9.2.15 */
|
/* Chapter 9.2.15 */
|
||||||
static int mm_rx_loc_upd_req(struct msgb *msg)
|
static int mm_rx_loc_upd_req(struct msgb *msg)
|
||||||
|
@ -277,6 +291,7 @@ static int mm_rx_loc_upd_req(struct msgb *msg)
|
||||||
struct gsm_bts *bts = msg->trx->bts;
|
struct gsm_bts *bts = msg->trx->bts;
|
||||||
struct gsm48_loc_upd_req *lu;
|
struct gsm48_loc_upd_req *lu;
|
||||||
struct gsm_subscriber *subscr;
|
struct gsm_subscriber *subscr;
|
||||||
|
struct gsm_lchan *lchan = msg->lchan;
|
||||||
u_int8_t mi_type;
|
u_int8_t mi_type;
|
||||||
u_int32_t tmsi;
|
u_int32_t tmsi;
|
||||||
char mi_string[MI_SIZE];
|
char mi_string[MI_SIZE];
|
||||||
|
@ -292,18 +307,18 @@ static int mm_rx_loc_upd_req(struct msgb *msg)
|
||||||
switch (mi_type) {
|
switch (mi_type) {
|
||||||
case GSM_MI_TYPE_IMSI:
|
case GSM_MI_TYPE_IMSI:
|
||||||
/* we always want the IMEI, too */
|
/* we always want the IMEI, too */
|
||||||
rc = mm_tx_identity_req(msg->lchan, GSM_MI_TYPE_IMEISV);
|
rc = mm_tx_identity_req(lchan, GSM_MI_TYPE_IMEISV);
|
||||||
/* look up subscriber based on IMSI */
|
/* look up subscriber based on IMSI */
|
||||||
subscr = db_create_subscriber(mi_string);
|
subscr = db_create_subscriber(mi_string);
|
||||||
break;
|
break;
|
||||||
case GSM_MI_TYPE_TMSI:
|
case GSM_MI_TYPE_TMSI:
|
||||||
/* we always want the IMEI, too */
|
/* we always want the IMEI, too */
|
||||||
rc = mm_tx_identity_req(msg->lchan, GSM_MI_TYPE_IMEISV);
|
rc = mm_tx_identity_req(lchan, GSM_MI_TYPE_IMEISV);
|
||||||
/* look up the subscriber based on TMSI, request IMSI if it fails */
|
/* look up the subscriber based on TMSI, request IMSI if it fails */
|
||||||
subscr = subscr_get_by_tmsi(lu->mi);
|
subscr = subscr_get_by_tmsi(lu->mi);
|
||||||
if (!subscr) {
|
if (!subscr) {
|
||||||
/* send IDENTITY REQUEST message to get IMSI */
|
/* send IDENTITY REQUEST message to get IMSI */
|
||||||
rc = mm_tx_identity_req(msg->lchan, GSM_MI_TYPE_IMSI);
|
rc = mm_tx_identity_req(lchan, GSM_MI_TYPE_IMSI);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GSM_MI_TYPE_IMEI:
|
case GSM_MI_TYPE_IMEI:
|
||||||
|
@ -316,20 +331,22 @@ static int mm_rx_loc_upd_req(struct msgb *msg)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lchan->subscr = subscr;
|
||||||
|
|
||||||
if (!subscr || !subscr->authorized) {
|
if (!subscr || !subscr->authorized) {
|
||||||
/* 0x16 is congestion */
|
/* 0x16 is congestion */
|
||||||
gsm0408_loc_upd_rej(msg->lchan, 0x16);
|
lchan->timer.cb = loc_upd_rej_cb;
|
||||||
rsl_chan_release(msg->lchan);
|
lchan->timer.data = lchan;
|
||||||
return -EINVAL;
|
schedule_timer(&lchan->timer, 1, 0);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
db_subscriber_alloc_tmsi(subscr);
|
db_subscriber_alloc_tmsi(subscr);
|
||||||
|
|
||||||
msg->lchan->subscr = subscr;
|
|
||||||
subscr_update(subscr, bts);
|
subscr_update(subscr, bts);
|
||||||
tmsi = strtoul(subscr->tmsi, NULL, 16);
|
|
||||||
|
|
||||||
return gsm0408_loc_upd_acc(msg->lchan, tmsi);
|
tmsi = strtoul(subscr->tmsi, NULL, 10);
|
||||||
|
|
||||||
|
return gsm0408_loc_upd_acc(lchan, tmsi);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gsm48_tx_mm_serv_ack(struct gsm_lchan *lchan)
|
static int gsm48_tx_mm_serv_ack(struct gsm_lchan *lchan)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
03 02 01 0a 02 43 0b 00 1d 39 01 1a 00 01 00 07 91 55 11 18 31 28 00 0e 31 20 04 81 21 43 00 00 ff 04 d4 f2 9c 0e
|
03 02 01 0a 02 43 0b 00 1d 39 01 1a 00 01 00 07 91 55 11 18 31 28 00 0e 31 20 04 81 21 43 00 00 ff 04 d4 f2 9c 0e
|
||||||
|
|
||||||
|
03 02 01 0a 02 43 0b 00 9f 09 01 9c 00 da 00 07 91 88 96 13 00 00 99 90 11 7b 04 81 22 22 00 08 ff 86 6c 38 8c 50 92 80 88 4c 00 4d 00 4d 00 41 6a 19 67 03 74 06 8c a1 7d b2 00 20 00 20 51 68 74 03 99 96 52 75 7d b2 8d ef 6a 19 67 03 ff 0c 6a 19 67 03 96 f6 98 a8 96 aa ff 01 8b 93 60 a8 80 70 66 0e 51 32 84 c4 ff 0c 97 48 6d 3b 62 95 8c c7 ff 01 73 fe 57 28 52 a0 51 65 90 01 96 50 91 cf 59 27 80 6f 76 df 6d 0b 57 fa 96 8a 91 77 5e 63 53 61 ff 0c 8a cb 4e 0a 7d b2 64 1c 5c 0b 30 0c 6a 19 67 03 30 0d
|
||||||
|
|
||||||
03 -
|
03 -
|
||||||
02 -
|
02 -
|
||||||
01 -
|
01 -
|
||||||
|
|
Loading…
Reference in New Issue