142 lines
4.0 KiB
C
142 lines
4.0 KiB
C
#pragma once
|
|
/* q931.c - Q.931 protocol definitions
|
|
*
|
|
* (C) 2022 by Harald Welte <laforge@osmocom.org>
|
|
*
|
|
* All Rights Reserved
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <osmocom/gsm/tlv.h>
|
|
|
|
/* Table 4-2/Q.931 - Message types */
|
|
enum q931_msg_type {
|
|
/* Call establishment messages */
|
|
Q931_MSGT_ALERTING = 0x01,
|
|
Q931_MSGT_CALL_PROCEEDING = 0x02,
|
|
Q931_MSGT_CONNECT = 0x07,
|
|
Q931_MSGT_CONNECT_ACK = 0x0f,
|
|
Q931_MSGT_PROGRESS = 0x03,
|
|
Q931_MSGT_SETUP = 0x05,
|
|
Q931_MSGT_SETUP_ACK = 0x0d,
|
|
/* Call information phase messages */
|
|
Q931_MSGT_RESUME = 0x26,
|
|
Q931_MSGT_RESUME_ACK = 0x2e,
|
|
Q931_MSGT_RESUME_REJ = 0x22,
|
|
Q931_MSGT_SUSPEND = 0x25,
|
|
Q931_MSGT_SUSPEND_ACK = 0x2d,
|
|
Q931_MSGT_SUSPEND_REJ = 0x21,
|
|
Q931_MSGT_USER_INFO = 0x20,
|
|
/* Call clearing messages */
|
|
Q931_MSGT_DISCONNECT = 0x45,
|
|
Q931_MSGT_RELEASE = 0x4d,
|
|
Q931_MSGT_RELEASE_COMPLETE = 0x5a,
|
|
Q931_MSGT_RESTART = 0x46,
|
|
Q931_MSGT_RESTART_ACK = 0x4e,
|
|
/* Miscellaneous messages */
|
|
Q931_MSGT_SEGMENT = 0x60,
|
|
Q931_MSGT_CONGESTION_CTRL = 0x79,
|
|
Q931_MSGT_INFORMATION = 0x7b,
|
|
Q931_MSGT_NOTIFY = 0x6e,
|
|
Q931_MSGT_STATUS = 0x7d,
|
|
Q931_MSGT_STATUS_ENQIURY = 0x75,
|
|
};
|
|
|
|
extern const struct value_string q931_msg_type_vals[];
|
|
|
|
/* Table 4-3/Q.931 */
|
|
enum q931_iei {
|
|
/* reserved */
|
|
/* shift */
|
|
Q931_IEI_MORE_DATA = 0xa0,
|
|
Q931_IEI_SENDING_COMPLETE = 0xa1,
|
|
/* contentionlevel */
|
|
/* repeat indicator */
|
|
/* Veriable length IEs */
|
|
Q931_IEI_SEGMENTED_MSG = 0x00,
|
|
Q931_IEI_BEARER_CAP = 0x04,
|
|
Q931_IEI_CAUSE = 0x08,
|
|
Q931_IEI_CALL_ID = 0x10,
|
|
Q931_IEI_CALL_STATE = 0x14,
|
|
Q931_IEI_CHANNEL_ID = 0x18,
|
|
Q931_IEI_PROGRESS_IND = 0x1e,
|
|
Q931_IEI_NETWORK_SPEC_FAC = 0x20,
|
|
Q931_IEI_NOTIFICATION_IND = 0x27,
|
|
Q931_IEI_DISPLAY = 0x28,
|
|
Q931_IEI_DATE_TIME = 0x29,
|
|
Q931_IEI_KEYPAD_FACILITY = 0x2c,
|
|
Q931_IEI_SIGNAL = 0x34,
|
|
Q931_IEI_INFORMATION_RATE = 0x40,
|
|
Q931_IEI_E2E_TRANSIT_DELAY = 0x42,
|
|
Q931_IEI_TRANSIT_DELAY_SEL_AND_IND = 0x43,
|
|
Q931_IEI_PKT_LAYER_BIN_PARAMS = 0x44,
|
|
Q931_IEI_PKT_LAYER_WIN_SIZE = 0x45,
|
|
Q931_IEI_PACKET_SIZE = 0x46,
|
|
Q931_IEI_CLOSED_USER_GROUP = 0x47,
|
|
Q931_IEI_REV_CHARGING_IND = 0x4a,
|
|
Q931_IEI_CALLING_PARTY_NUM = 0x6c,
|
|
Q931_IEI_CALLING_PARTY_SUBADDR = 0x6d,
|
|
Q931_IEI_CALLED_PARTY_NUM = 0x70,
|
|
Q931_IEI_CALLED_PARTY_SUBADDR = 0x71,
|
|
Q931_IEI_TRANSIT_NET_SEL = 0x78,
|
|
Q931_IEI_RESTART_IND = 0x79,
|
|
Q931_IEI_LOW_LAYER_COMPAT = 0x7c,
|
|
Q931_IEI_HIGH_LAYER_COMPAT = 0x7d,
|
|
Q931_IEI_ESCAPE_FOR_EXT = 0x7f,
|
|
};
|
|
|
|
struct q931_msg_parsed {
|
|
uint8_t msg_type;
|
|
uint32_t call_ref;
|
|
struct tlv_parsed ies;
|
|
};
|
|
|
|
int q931_msg_parse(struct q931_msg_parsed *out, const uint8_t *buf, size_t len);
|
|
|
|
uint32_t q931_decode_callref(const uint8_t *data, uint8_t len);
|
|
|
|
/* Q.931 Section 4.5.13 */
|
|
enum q931_info_chan_type {
|
|
Q931_INFO_CHAN_T_NONE,
|
|
Q931_INFO_CHAN_T_ANY,
|
|
Q931_INFO_CHAN_T_SPECIFIC,
|
|
};
|
|
|
|
/* decoded version of (simplified) Q.931 Channel Identification IE */
|
|
struct q931_channel_id {
|
|
bool interface_id_present;
|
|
uint32_t interface_id;
|
|
bool interface_type_pri;
|
|
bool exclusive;
|
|
bool d_channel;
|
|
enum q931_info_chan_type info_chan_type;
|
|
uint32_t b_channel; /* 1..2 on BRI; 1..31 on PRI */
|
|
};
|
|
|
|
|
|
int q931_decode_channel_id(struct q931_channel_id *out, const uint8_t *data, uint8_t len);
|
|
|
|
struct q931_party_number {
|
|
uint8_t type_of_number;
|
|
uint8_t numbering_plan_id;
|
|
uint8_t presentation_ind;
|
|
uint8_t screening_ind;
|
|
char digits[32];
|
|
};
|
|
|
|
int q931_decode_called_party(struct q931_party_number *out, const uint8_t *buf, size_t len);
|
|
int q931_decode_calling_party(struct q931_party_number *out, const uint8_t *buf, size_t len);
|