now we get up to the SETUP of MO calls
diff --git a/src/gsm_04_08.c b/src/gsm_04_08.c
index 212b4ad..b478bc7 100644
--- a/src/gsm_04_08.c
+++ b/src/gsm_04_08.c
@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <netinet/in.h>
#include <openbsc/msgb.h>
#include <openbsc/debug.h>
@@ -64,11 +65,11 @@
static void to_bcd(u_int8_t *bcd, u_int16_t val)
{
- bcd[0] = val % 10;
+ bcd[2] = val % 10;
val = val / 10;
bcd[1] = val % 10;
val = val / 10;
- bcd[2] = val % 10;
+ bcd[0] = val % 10;
val = val / 10;
}
@@ -82,10 +83,16 @@
lai48->digits[1] = bcd[2];
to_bcd(bcd, mnc);
+ /* FIXME: do we need three-digit MNC? See Table 10.5.3 */
+#if 0
lai48->digits[1] |= bcd[2] << 4;
lai48->digits[2] = bcd[0] | (bcd[1] << 4);
+#else
+ lai48->digits[1] |= 0xf << 4;
+ lai48->digits[2] = bcd[1] | (bcd[2] << 4);
+#endif
- lai48->lac = lac;
+ lai48->lac = htons(lac);
}
#define TMSI_LEN 4
@@ -93,12 +100,13 @@
static void generate_mid_from_tmsi(u_int8_t *buf, u_int8_t *tmsi_bcd)
{
- buf[0] = MID_TMSI_LEN;
- buf[1] = 0xf0 | GSM_MI_TYPE_TMSI;
- buf[2] = tmsi_bcd[0];
- buf[3] = tmsi_bcd[1];
- buf[4] = tmsi_bcd[2];
- buf[5] = tmsi_bcd[3];
+ buf[0] = GSM48_IE_MOBILE_ID;
+ buf[1] = MID_TMSI_LEN;
+ buf[2] = 0xf0 | GSM_MI_TYPE_TMSI;
+ buf[3] = tmsi_bcd[0];
+ buf[4] = tmsi_bcd[1];
+ buf[5] = tmsi_bcd[2];
+ buf[6] = tmsi_bcd[3];
}
static struct msgb *gsm48_msgb_alloc(void)
@@ -111,14 +119,45 @@
if (msg->lchan)
msg->trx = msg->lchan->ts->trx;
+ msg->l3h = msg->data;
+
return rsl_data_request(msg, 0);
}
+static int gsm48_cc_tx_status(struct gsm_lchan *lchan)
+{
+ struct msgb *msg = gsm48_msgb_alloc();
+ struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+ u_int8_t *cause, *call_state;
+
+ msg->lchan = lchan;
+
+ gh->proto_discr = GSM48_PDISC_CC;
+ gh->msg_type = GSM48_MT_CC_STATUS;
+
+ cause = msgb_put(msg, 3);
+ cause[0] = 2;
+ cause[1] = GSM48_CAUSE_CS_GSM | GSM48_CAUSE_LOC_USER;
+ cause[2] = 0x80 | 30; /* response to status inquiry */
+
+ call_state = msgb_put(msg, 1);
+ call_state[0] = 0xc0 | 0x00;
+
+ return gsm0408_sendmsg(msg);
+}
+
+static int gsm48_cc_rx_status_enq(struct msgb *msg)
+{
+ return gsm48_cc_tx_status(msg->lchan);
+}
+
static int gsm0408_rcv_cc(struct msgb *msg)
{
struct gsm48_hdr *gh = msgb_l3(msg);
+ u_int8_t msg_type = gh->msg_type & 0xbf;
+ int rc = 0;
- switch (gh->msg_type & 0xbf) {
+ switch (msg_type) {
case GSM48_MT_CC_CALL_CONF:
/* Response to SETUP */
DEBUGP(DCC, "CALL CONFIRM\n");
@@ -137,18 +176,27 @@
DEBUGP(DCC, "RELEASE\n");
/* need to respond with RELEASE_COMPLETE */
break;
- case GSM48_MT_CC_EMERG_SETUP:
- //DEBUGP(DCC, "EMERGENCY SETUP\n");
+ case GSM48_MT_CC_STATUS_ENQ:
+ rc = gsm48_cc_rx_status_enq(msg);
+ break;
+ case GSM48_MT_CC_DISCONNECT:
+ DEBUGP(DCC, "DISCONNECT\n");
+ break;
case GSM48_MT_CC_SETUP:
- //DEBUGP(DCC, "SETUP\n");
+ DEBUGP(DCC, "SETUP\n");
/* FIXME: continue with CALL_PROCEEDING, ALERTING, CONNECT, RELEASE_COMPLETE */
+ break;
+ case GSM48_MT_CC_EMERG_SETUP:
+ DEBUGP(DCC, "EMERGENCY SETUP\n");
+ /* FIXME: continue with CALL_PROCEEDING, ALERTING, CONNECT, RELEASE_COMPLETE */
+ break;
default:
fprintf(stderr, "Unimplemented GSM 04.08 msg type 0x%02x\n",
- gh->msg_type);
+ msg_type);
break;
}
- return 0;
+ return rc;
}
/* Chapter 9.2.14 : Send LOCATION UPDATE REJECT */
@@ -209,11 +257,12 @@
mi_type = lu->mi[0] & GSM_MI_TYPE_MASK;
+ DEBUGP(DMM, "LUPDREQ: mi_type = 0x%02x\n", mi_type);
switch (mi_type) {
case GSM_MI_TYPE_IMSI:
/* look up subscriber based on IMSI */
subscr = subscr_get_by_imsi(&lu->mi[1]);
- break;
+ break;
case GSM_MI_TYPE_TMSI:
/* look up the subscriber based on TMSI, request IMSI if it fails */
subscr = subscr_get_by_tmsi(&lu->mi[1]);
@@ -244,6 +293,29 @@
return gsm0408_loc_upd_acc(msg->lchan, subscr->tmsi);
}
+static int gsm48_tx_mm_serv_ack(struct gsm_lchan *lchan)
+{
+ struct msgb *msg = gsm48_msgb_alloc();
+ struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+ msg->lchan = lchan;
+
+ gh->proto_discr = GSM48_PDISC_MM;
+ gh->msg_type = GSM48_MT_MM_CM_SERV_ACC;
+
+ DEBUGP(DMM, "-> CM SERVICE ACK\n");
+
+ return gsm0408_sendmsg(msg);
+}
+
+static int gsm48_rx_mm_serv_req(struct msgb *msg)
+{
+ struct gsm48_hdr *gh = msgb_l3(msg);
+
+ DEBUGP(DMM, "CM SERVICE REQUEST\n");
+ return gsm48_tx_mm_serv_ack(msg->lchan);
+}
+
static int gsm0408_rcv_mm(struct msgb *msg)
{
struct gsm48_hdr *gh = msgb_l3(msg);
@@ -259,6 +331,8 @@
case GSM48_MT_MM_AUTH_RESP:
case GSM48_MT_MM_IMSI_DETACH_IND:
case GSM48_MT_MM_CM_SERV_REQ:
+ rc = gsm48_rx_mm_serv_req(msg);
+ break;
case GSM48_MT_MM_CM_REEST_REQ:
fprintf(stderr, "Unimplemented GSM 04.08 MM msg type 0x%02x\n",
gh->msg_type);