mirror of https://gerrit.osmocom.org/libosmocore
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:
parent
a73e2f9acb
commit
61e2bfc5f4
|
@ -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
|
||||
|
|
142
src/gsm48.c
142
src/gsm48.c
|
@ -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];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue