import gsm48 utility functions from OpenBSC

* gsm48_generate_lai() gsm48_generate_mid_from_tmsi() gsm48_generate_mid_from_imsi()
* gsm48_cc_msg_names[]
This commit is contained in:
Harald Welte 2010-03-04 10:53:03 +01:00
parent a73e2f9acb
commit 61e2bfc5f4
2 changed files with 149 additions and 2 deletions

View File

@ -1,9 +1,16 @@
#ifndef _OSMOCORE_GSM48_H
#include <osmocore/tlv.h>
#include <osmocore/protocol/gsm_04_08.h>
extern const struct tlv_definition gsm48_att_tlvdef;
extern const char *cc_state_names[];
extern const char *cc_state_names[32];
const char *gsm48_cc_msg_names[0x40];
const char *rr_cause_name(uint8_t cause);
void gsm48_generate_lai(struct gsm48_loc_area_id *lai48, uint16_t mcc,
uint16_t mnc, uint16_t lac);
int gsm48_generate_mid_from_tmsi(uint8_t *buf, uint32_t tmsi);
int gsm48_generate_mid_from_imsi(uint8_t *buf, const char *imsi);
#endif

View File

@ -26,6 +26,8 @@
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <osmocore/utils.h>
#include <osmocore/tlv.h>
#include <osmocore/gsm48.h>
@ -93,7 +95,7 @@ static const char *rr_cause_names[] = {
[GSM48_RR_CAUSE_PROT_ERROR_UNSPC] = "Protocol error unspecified",
};
const char *cc_state_names[] = {
const char *cc_state_names[32] = {
"NULL",
"INITIATED",
"illegal state 2",
@ -128,6 +130,73 @@ const char *cc_state_names[] = {
"illegal state 31",
};
const char *gsm48_cc_msg_names[0x40] = {
"unknown 0x00",
"ALERTING",
"CALL_PROC",
"PROGRESS",
"ESTAB",
"SETUP",
"ESTAB_CONF",
"CONNECT",
"CALL_CONF",
"START_CC",
"unknown 0x0a",
"RECALL",
"unknown 0x0c",
"unknown 0x0d",
"EMERG_SETUP",
"CONNECT_ACK",
"USER_INFO",
"unknown 0x11",
"unknown 0x12",
"MODIFY_REJECT",
"unknown 0x14",
"unknown 0x15",
"unknown 0x16",
"MODIFY",
"HOLD",
"HOLD_ACK",
"HOLD_REJ",
"unknown 0x1b",
"RETR",
"RETR_ACK",
"RETR_REJ",
"MODIFY_COMPL",
"unknown 0x20",
"unknown 0x21",
"unknown 0x22",
"unknown 0x23",
"unknown 0x24",
"DISCONNECT",
"unknown 0x26",
"unknown 0x27",
"unknown 0x28",
"unknown 0x29",
"RELEASE_COMPL",
"unknown 0x2b",
"unknown 0x2c",
"RELEASE",
"unknown 0x2e",
"unknown 0x2f",
"unknown 0x30",
"STOP_DTMF",
"STOP_DTMF_ACK",
"unknown 0x33",
"STATUS_ENQ",
"START_DTMF",
"START_DTMF_ACK",
"START_DTMF_REJ",
"unknown 0x38",
"CONG_CTRL",
"FACILITY",
"unknown 0x3b",
"STATUS",
"unknown 0x3d",
"NOTIFY",
"unknown 0x3f",
};
static char strbuf[64];
const char *rr_cause_name(uint8_t cause)
@ -140,4 +209,75 @@ const char *rr_cause_name(uint8_t cause)
return strbuf;
}
static void to_bcd(uint8_t *bcd, uint16_t val)
{
bcd[2] = val % 10;
val = val / 10;
bcd[1] = val % 10;
val = val / 10;
bcd[0] = val % 10;
val = val / 10;
}
void gsm48_generate_lai(struct gsm48_loc_area_id *lai48, uint16_t mcc,
uint16_t mnc, uint16_t lac)
{
uint8_t bcd[3];
to_bcd(bcd, mcc);
lai48->digits[0] = bcd[0] | (bcd[1] << 4);
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 = htons(lac);
}
int gsm48_generate_mid_from_tmsi(uint8_t *buf, uint32_t tmsi)
{
uint32_t *tptr = (uint32_t *) &buf[3];
buf[0] = GSM48_IE_MOBILE_ID;
buf[1] = GSM48_TMSI_LEN;
buf[2] = 0xf0 | GSM_MI_TYPE_TMSI;
*tptr = htonl(tmsi);
return 7;
}
int gsm48_generate_mid_from_imsi(uint8_t *buf, const char *imsi)
{
unsigned int length = strlen(imsi), i, off = 0;
uint8_t odd = (length & 0x1) == 1;
buf[0] = GSM48_IE_MOBILE_ID;
buf[2] = char2bcd(imsi[0]) << 4 | GSM_MI_TYPE_IMSI | (odd << 3);
/* if the length is even we will fill half of the last octet */
if (odd)
buf[1] = (length + 1) >> 1;
else
buf[1] = (length + 2) >> 1;
for (i = 1; i < buf[1]; ++i) {
uint8_t lower, upper;
lower = char2bcd(imsi[++off]);
if (!odd && off + 1 == length)
upper = 0x0f;
else
upper = char2bcd(imsi[++off]) & 0x0f;
buf[2 + i] = (upper << 4) | lower;
}
return 2 + buf[1];
}