even more gsmtap wip
Change-Id: Icf18039117df2bf1548f8c02bccabe3c45bad99d
This commit is contained in:
parent
07be00afd0
commit
83912d7d40
|
@ -109,11 +109,53 @@ enum q931_iei {
|
||||||
/* TODO */
|
/* TODO */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct q931_call_state {
|
||||||
|
struct llist_head list;
|
||||||
|
uint32_t call_ref; /* decoded call reference */
|
||||||
|
bool net2user; /* call established in Net->User direction? */
|
||||||
|
time_t create_time; /* time at which call was created */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Q.931 Section 4.3 */
|
||||||
|
static uint32_t q931_decode_callref(const uint8_t *data, uint8_t len)
|
||||||
|
{
|
||||||
|
uint8_t len_of_callref;
|
||||||
|
uint32_t callref = 0;
|
||||||
|
bool flag;
|
||||||
|
|
||||||
|
if (len < 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
len_of_callref = data[0] & 0x0f;
|
||||||
|
if (len_of_callref = 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (len_of_callref > 4)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (len - 1 < len_of_callref)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* first octet contains flag, needs special handling */
|
||||||
|
if (data[1] & 0x80)
|
||||||
|
flag = 1;
|
||||||
|
callref = data[1] & 0x7f;
|
||||||
|
|
||||||
|
/* all further octets ... */
|
||||||
|
for (i = 1; i < len_of_callref; i++)
|
||||||
|
callref = (callref << 8) | data[i];
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
callref |= 0x80000000;
|
||||||
|
|
||||||
|
return callref;
|
||||||
|
}
|
||||||
|
|
||||||
/* receive one Q.931 message for signaling analysis */
|
/* receive one Q.931 message for signaling analysis */
|
||||||
static void e1tap_q931_rx(struct e1tap_line *line, bool net2user, const uint8_t *buf, size_t len)
|
static void e1tap_q931_rx(struct e1tap_line *line, bool net2user, const uint8_t *buf, size_t len)
|
||||||
{
|
{
|
||||||
uint8_t cref_len
|
uint8_t cref_len;
|
||||||
|
uint32_t cref;
|
||||||
|
|
||||||
if (len < 2)
|
if (len < 2)
|
||||||
return;
|
return;
|
||||||
|
@ -126,35 +168,50 @@ static void e1tap_q931_rx(struct e1tap_line *line, bool net2user, const uint8_t
|
||||||
cref_len = buf[1] & 0x0F;
|
cref_len = buf[1] & 0x0F;
|
||||||
if (len < 2 + cref_len)
|
if (len < 2 + cref_len)
|
||||||
return;
|
return;
|
||||||
|
cref = q931_decode_callref(buf+1, len-1);
|
||||||
|
|
||||||
msg_type = buf[2+cref_len] & 0x7f;
|
msg_type = buf[2+cref_len] & 0x7f;
|
||||||
|
|
||||||
/* TODO: dispatch by message type; look in those that contain a ChannelIndicator */
|
/* TODO: dispatch by message type; look in those that contain a ChannelIndicator */
|
||||||
|
switch (msg_type) {
|
||||||
|
case Q931_MSGT_SETUP:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* trace one Q.921 / LAPD frame for signaling analysis */
|
/* trace one Q.921 / LAPD frame for signaling analysis */
|
||||||
static void e1tap_q921_rx(struct e1tap_line *line, bool net2user, const uint8_t *buf, size_t len)
|
static void e1tap_q921_rx(struct e1tap_line *line, bool net2user, const uint8_t *buf, size_t len)
|
||||||
{
|
{
|
||||||
uint8_t sapi, tei;
|
uint8_t sapi, tei;
|
||||||
|
/* Parse LAPD header; Ignore anything != I frames */
|
||||||
|
/* Q.921 header: 2 bytes address; 1-2 byte control; [optional] information */
|
||||||
|
|
||||||
if (len < 2)
|
if (len < 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Parse LAPD header; Ignore anything != I frames */
|
/* Address field: Figure 5 / Q.921 */
|
||||||
sapi = buf[0] >> 2;
|
sapi = buf[0] >> 2;
|
||||||
tei = buf[1] >> 1;
|
tei = buf[1] >> 1;
|
||||||
|
|
||||||
/* skip unknown SAPI */
|
/* SAPI value for circuit-switched call control (Table 2/Q.921) */
|
||||||
if (sapi != 0)
|
if (sapi != 0) {
|
||||||
|
/* skip unknown SAPI */
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (len < 3)
|
if (len < 3)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* skip frames != I-frame */
|
/* Control field: Table 4/Q.921 */
|
||||||
if (buf[2] & 0x01)
|
if (buf[2] & 0x01) {
|
||||||
|
/* skip frames != I-frame (which have 0 as lsb of 1st octet) */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len < 4)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* skip N(R) / N(S) and go directly to Q.931 payload */
|
||||||
e1tap_q931_rx(buf + 4, len - 4);
|
e1tap_q931_rx(buf + 4, len - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,6 +244,7 @@ void e1tap_trace_ts(struct e1tap_ts *ts, const uint8_t *tsbuf, size_t frame_coun
|
||||||
gsmtap_send_ex(line->gti, GSMTAP_TYPE_E1T1, flags,
|
gsmtap_send_ex(line->gti, GSMTAP_TYPE_E1T1, flags,
|
||||||
ts->num, ts->gsmtap_subtype, 0, 0, 0, 0,
|
ts->num, ts->gsmtap_subtype, 0, 0, 0, 0,
|
||||||
ts->hdlc.state[hdlc_idx].out, rc);
|
ts->hdlc.state[hdlc_idx].out, rc);
|
||||||
|
/* feed D-channel into higher level analysis */
|
||||||
if (ts->mode == E1_TS_TRACE_MODE_ISDN_D)
|
if (ts->mode == E1_TS_TRACE_MODE_ISDN_D)
|
||||||
e1tap_q921_rx(line, hdlc_idx, ts->hdlc.state[hdlc_idx].out, rc);
|
e1tap_q921_rx(line, hdlc_idx, ts->hdlc.state[hdlc_idx].out, rc);
|
||||||
} else if (rc < 0) {
|
} else if (rc < 0) {
|
||||||
|
|
Loading…
Reference in New Issue