osmo-isdntap/src/q931.h

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);