diff options
author | Harald Welte <laforge@gnumonks.org> | 2009-01-10 01:49:35 +0000 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2009-01-10 01:49:35 +0000 |
commit | ba4cf164b0795dd2a13d2de04d2c1be676b01ba3 (patch) | |
tree | 7cafb7704bcb8e311d1a79a2931e0b3fab19934b /src/gsm_04_08.c | |
parent | c627afceaa07dae35a474a3e32e1ae133f221895 (diff) |
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.
Diffstat (limited to 'src/gsm_04_08.c')
-rw-r--r-- | src/gsm_04_08.c | 56 |
1 files changed, 51 insertions, 5 deletions
diff --git a/src/gsm_04_08.c b/src/gsm_04_08.c index f8559b8e2..381e5c8ba 100644 --- a/src/gsm_04_08.c +++ b/src/gsm_04_08.c @@ -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) { + u_int8_t mi_type; + + struct gsm_subscriber *subscr; struct gsm48_hdr *gh = msgb_l3(msg); - u_int8_t serv_type = gh->data[0] & 0x0f; + 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); + } - DEBUGP(DMM, "<- CM SERVICE REQUEST serv_type=0x%02x\n", serv_type); + 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); } |