Start working on CM Service Request

Be able to send Accept/Reject the Service Request. Use mi_string
instead of the the msgb buffer (even if it is memsetted and such)...

The TMSI allocation seems to be a bit problematic and needs some
further checking. The rough idea is that we try to find the subscriber
for a CM Service Request and then decide based on the subscriber
if we want to handle the call.
This commit is contained in:
Harald Welte 2009-01-10 01:49:35 +00:00
parent c627afceaa
commit ba4cf164b0
2 changed files with 63 additions and 6 deletions

View File

@ -86,6 +86,17 @@ struct gsm48_rach_control {
u_int8_t t3;
} __attribute__ ((packed));
/* Section 9.2.9 CM service request */
struct gsm48_service_request {
u_int8_t cm_service_type : 4,
cipher_key_seq : 4;
/* length + 3 bytes */
u_int32_t classmark;
u_int8_t mi_len;
u_int8_t mi[0];
/* optional priority level */
} __attribute__ ((packed));
/* Section 9.1.31 System information Type 1 */
struct gsm48_system_information_type_1 {
struct gsm48_system_information_type_header header;

View File

@ -237,9 +237,9 @@ int gsm0408_loc_upd_acc(struct gsm_lchan *lchan, u_int32_t tmsi)
ret = gsm48_sendmsg(msg);
/* return gsm48_cc_tx_setup(lchan); */
ret = gsm48_cc_tx_setup(lchan);
ret = gsm48_tx_mm_info(lchan);
ret = gsm0411_send_sms(lchan, NULL);
//ret = gsm0411_send_sms(lchan, NULL);
return ret;
}
@ -417,7 +417,7 @@ 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((char *)lu->mi);
subscr = subscr_get_by_tmsi(mi_string);
if (!subscr) {
/* send IDENTITY REQUEST message to get IMSI */
use_lchan(lchan);
@ -532,13 +532,59 @@ static int gsm48_tx_mm_serv_ack(struct gsm_lchan *lchan)
DEBUGP(DMM, "-> CM SERVICE ACK\n");
return gsm48_tx_simple(lchan, GSM48_PDISC_MM, GSM48_MT_MM_CM_SERV_ACC);
}
/* 9.2.6 CM service reject */
static int gsm48_tx_mm_serv_rej(struct gsm_lchan *lchan,
enum gsm48_reject_value value)
{
struct msgb *msg = gsm48_msgb_alloc();
struct gsm48_hdr *gh;
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
msg->lchan = lchan;
use_lchan(lchan);
gh->proto_discr = GSM48_PDISC_MM;
gh->msg_type = GSM48_MT_MM_CM_SERV_REJ;
gh->data[0] = value;
DEBUGP(DMM, "-> CM SERVICE Reject cause: %d\n", value);
return gsm48_sendmsg(msg);
}
static int gsm48_rx_mm_serv_req(struct msgb *msg)
{
struct gsm48_hdr *gh = msgb_l3(msg);
u_int8_t serv_type = gh->data[0] & 0x0f;
u_int8_t mi_type;
DEBUGP(DMM, "<- CM SERVICE REQUEST serv_type=0x%02x\n", serv_type);
struct gsm_subscriber *subscr;
struct gsm48_hdr *gh = msgb_l3(msg);
struct gsm48_service_request *req =
(struct gsm48_service_request *)gh->data;
if (msg->data_len < sizeof(struct gsm48_service_request*)) {
DEBUGP(DMM, "<- CM SERVICE REQUEST wrong sized message\n");
return gsm48_tx_mm_serv_rej(msg->lchan,
GSM48_REJECT_INCORRECT_MESSAGE);
}
if (msg->data_len < req->mi_len + 6) {
DEBUGP(DMM, "<- CM SERVICE REQUEST MI does not fit in package\n");
return gsm48_tx_mm_serv_rej(msg->lchan,
GSM48_REJECT_INCORRECT_MESSAGE);
}
mi_type = req->mi[0] & GSM_MI_TYPE_MASK;
if (mi_type != GSM_MI_TYPE_TMSI) {
DEBUGP(DMM, "<- CM SERVICE REQUEST mi type is not TMSI: %d\n", mi_type);
return gsm48_tx_mm_serv_rej(msg->lchan,
GSM48_REJECT_INCORRECT_MESSAGE);
}
subscr = subscr_get_by_tmsi((char *)req->mi);
DEBUGP(DMM, "<- CM SERVICE REQUEST serv_type=0x%02x mi_type=0x%02x Subscriber(%p)\n",
req->cm_service_type, mi_type, subscr);
return gsm48_tx_mm_serv_ack(msg->lchan);
}