2021-12-28 10:32:53 +00:00
|
|
|
#pragma once
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <osmocom/core/utils.h>
|
|
|
|
#include <osmocom/gsm/tlv.h>
|
|
|
|
|
|
|
|
/* Definitions related to the V5.1 and V5.2 interface between AN (access
|
|
|
|
* network) and LE (local exchange) as per ITU-T G.964 + G.965.
|
|
|
|
*
|
|
|
|
* (C) 2021 by Harald Welte <laforge@gnumonks.org>
|
|
|
|
*/
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
/* protocol wire format */
|
|
|
|
/***********************************************************************/
|
|
|
|
|
|
|
|
/* Table 14/G.964 */
|
|
|
|
#define V51_CTRL_PDISC 0x48
|
|
|
|
|
|
|
|
/* Table 1/G.965 + Table 1/G.964 */
|
|
|
|
#define V51_DLADDR_PSTN 8176
|
|
|
|
#define V51_DLADDR_CTRL 8177
|
|
|
|
#define V52_DLADDR_BCC 8178
|
|
|
|
#define V52_DLADDR_PROTECTION 8179
|
|
|
|
#define V52_DLADDR_LCP 8180
|
|
|
|
|
|
|
|
/* G.965 Section 13.1 */
|
|
|
|
struct v51_l3_hdr {
|
|
|
|
uint8_t pdisc;
|
|
|
|
uint16_t l3_addr; /* with C/R and EA bits! */
|
|
|
|
uint8_t msg_type;
|
|
|
|
uint8_t payload[0];
|
|
|
|
} __attribute__ ((packed));
|
|
|
|
|
|
|
|
/* G.964 Section 14.4.2.3 Figure 33 + 34 */
|
|
|
|
static inline bool v51_l3_addr_is_isdn(uint16_t in)
|
|
|
|
{
|
|
|
|
/* extract two bytes */
|
|
|
|
uint8_t b1 = in >> 8;
|
|
|
|
uint8_t b2 = in & 0xff;
|
|
|
|
|
2022-09-11 14:59:42 +00:00
|
|
|
if ((b1 & 0x03) == 0x00 && (b2 & 0x01))
|
2021-12-28 10:32:53 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint16_t v51_l3_addr_dec(uint16_t in, bool *is_isdn)
|
|
|
|
{
|
|
|
|
/* extract two bytes */
|
|
|
|
uint8_t b1 = in >> 8;
|
|
|
|
uint8_t b2 = in & 0xff;
|
|
|
|
|
|
|
|
if (v51_l3_addr_is_isdn(in)) {
|
|
|
|
/* remove EA/C/R bits */
|
|
|
|
uint8_t upper = b1 >> 2;
|
|
|
|
uint8_t lower = b2 >> 1;
|
|
|
|
if (is_isdn)
|
|
|
|
*is_isdn = true;
|
|
|
|
/* shift them together */
|
|
|
|
return lower | (upper << 7);
|
|
|
|
} else{
|
|
|
|
uint8_t upper = b1 >> 1;
|
|
|
|
uint8_t lower = b2;
|
|
|
|
if (is_isdn)
|
|
|
|
*is_isdn = false;
|
|
|
|
return lower | (upper << 8);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint16_t v51_l3_addr_enc(uint16_t in, bool is_isdn)
|
|
|
|
{
|
|
|
|
uint8_t b1, b2;
|
|
|
|
if (is_isdn) {
|
|
|
|
uint8_t upper = in >> 7;
|
|
|
|
uint8_t lower = in & 0x7f;
|
|
|
|
b1 = upper << 2;
|
|
|
|
b2 = (lower << 1) | 0x01;
|
|
|
|
} else {
|
|
|
|
uint8_t upper = in >> 8;
|
|
|
|
uint8_t lower = in & 0xff;
|
|
|
|
b1 = (upper << 1) | 0x01;
|
|
|
|
b2 = lower;
|
|
|
|
}
|
|
|
|
return (b1 << 8) | b2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Table 15 + 52/G.964 */
|
|
|
|
enum v51_ctrl_msg_type {
|
|
|
|
/* 000xxxx: PSTN protocol message types */
|
|
|
|
V51_CTRL_MSGT_ESTABLISH = 0x00,
|
|
|
|
V51_CTRL_MSGT_ESTABLISH_ACK = 0x01,
|
|
|
|
V51_CTRL_MSGT_SIGNAL = 0x02,
|
|
|
|
V51_CTRL_MSGT_SIGNAL_ACK = 0x03,
|
|
|
|
V51_CTRL_MSGT_DISCONNECT = 0x08,
|
|
|
|
V51_CTRL_MSGT_DISCONNECT_ACK = 0x09,
|
|
|
|
V51_CTRL_MSGT_STATUS_ENQUIRY = 0x0c,
|
|
|
|
V51_CTRL_MSGT_STATUS = 0x0d,
|
|
|
|
V51_CTRL_MSGT_PROTOCOL_PARAMETER = 0x0e,
|
|
|
|
/* 0010xxx: Control protocol message types */
|
|
|
|
V51_CTRL_MSGT_PORT_CTRL = 0x10,
|
|
|
|
V51_CTRL_MSGT_PORT_CTRL_ACK = 0x11,
|
|
|
|
V51_CTRL_MSGT_COMMON_CTRL = 0x12,
|
|
|
|
V51_CTRL_MSGT_COMMON_CTRL_ACK = 0x13,
|
|
|
|
/* 0011xxx: Protection protocol message types */
|
|
|
|
V52_CTRL_MSGT_PP_SWITCH_OVER_REQ = 0x18,
|
|
|
|
V52_CTRL_MSGT_PP_SWITCH_OVER_COM = 0x19,
|
|
|
|
V52_CTRL_MSGT_PP_OS_SWITCH_OVER_COM = 0x1a,
|
|
|
|
V52_CTRL_MSGT_PP_SWITCH_OVER_ACK = 0x1b,
|
|
|
|
V52_CTRL_MSGT_PP_SWITCH_OVER_REJECT = 0x1c,
|
|
|
|
V52_CTRL_MSGT_PP_PROTOCOL_ERROR = 0x1d,
|
|
|
|
V52_CTRL_MSGT_PP_RESET_SN_COM = 0x1e,
|
|
|
|
V52_CTRL_MSGT_PP_RESET_SN_ACK = 0x1f,
|
|
|
|
/* 010xxxx: BCC protocol message types */
|
|
|
|
V52_CTRL_MSGT_ALLOCATION = 0x20,
|
|
|
|
V52_CTRL_MSGT_ALLOCATION_COMPLETE = 0x21,
|
|
|
|
V52_CTRL_MSGT_ALLOCATION_REJECT = 0x22,
|
|
|
|
V52_CTRL_MSGT_DE_ALLOCATION = 0x23,
|
|
|
|
V52_CTRL_MSGT_DE_ALLOCATION_COMPLETE = 0x24,
|
|
|
|
V52_CTRL_MSGT_DE_ALLOCATION_REJECT = 0x25,
|
|
|
|
V52_CTRL_MSGT_AUDIT = 0x26,
|
|
|
|
V52_CTRL_MSGT_AUDIT_COMPLETE = 0x27,
|
|
|
|
V52_CTRL_MSGT_AN_FAULT = 0x28,
|
|
|
|
V52_CTRL_MSGT_AN_FAULT_ACK = 0x29,
|
|
|
|
V52_CTRL_MSGT_PROTOCOL_ERROR = 0x2a,
|
|
|
|
/* 0110xxx: Link control protocol message types */
|
|
|
|
V52_CTRL_MSGT_LCP_LINK_CTRL = 0x30,
|
|
|
|
V52_CTRL_MSGT_LCP_LINK_CTRL_ACK = 0x31,
|
|
|
|
};
|
|
|
|
|
|
|
|
extern const struct value_string v51_ctrl_msg_typ_str[];
|
|
|
|
|
|
|
|
|
|
|
|
/* Table 17 + 53/G.964 */
|
|
|
|
enum v51_ctrl_iei {
|
|
|
|
/* single byte, only upper nibble matches IEI */
|
|
|
|
V51_CTRL_IEI_PULSE_NOTIFICATION = 0xc0,
|
2022-11-27 13:03:58 +00:00
|
|
|
V51_CTRL_IEI_LINE_NOTIFICATION = 0x80,
|
|
|
|
V51_CTRL_IEI_STATE = 0x90,
|
|
|
|
V51_CTRL_IEI_AUTONOMOUS_SIG_SEQ = 0xa0,
|
|
|
|
V51_CTRL_IEI_SEQUENCE_RESPONSE = 0xb0,
|
2021-12-28 10:32:53 +00:00
|
|
|
/* single byte: ISDN */
|
|
|
|
V51_CTRL_IEI_PERFORMANCE_GRADING = 0xe0,
|
|
|
|
V51_CTRL_IEI_REJECTION_CAUSE = 0xf0,
|
|
|
|
/* variable length: PSTN */
|
|
|
|
V51_CTRL_IEI_SEQUENCE_NR = 0x00,
|
|
|
|
V51_CTRL_IEI_CADENCED_RINGING = 0x01,
|
|
|
|
V51_CTRL_IEI_PULSED_SIGNAL = 0x02,
|
|
|
|
V51_CTRL_IEI_STEADY_SIGNAL = 0x03,
|
|
|
|
V51_CTRL_IEI_DIGIT_SIGNAL = 0x04,
|
|
|
|
V51_CTRL_IEI_RECOGNITION_TIME = 0x10,
|
|
|
|
V51_CTRL_IEI_ENABLE_AUTONOMOUS_ACK = 0x11,
|
|
|
|
V51_CTRL_IEI_DISABLE_AUTONOMOUS_ACK = 0x12,
|
|
|
|
V51_CTRL_IEI_CAUSE = 0x13,
|
|
|
|
V51_CTRL_IEI_RESOURCE_UNAVAILABLE = 0x14,
|
|
|
|
V51_CTRL_IEI_ENABLE_METERING = 0x32,
|
|
|
|
V51_CTRL_IEI_METERING_REPORT = 0x33,
|
|
|
|
V51_CTRL_IEI_ATTENUATION = 0x34,
|
|
|
|
/* variable length: ISDN */
|
|
|
|
V51_CTRL_IEI_CTRL_F_ELEMENT = 0x20,
|
|
|
|
V51_CTRL_IEI_CTRL_F_ID = 0x21,
|
|
|
|
V51_CTRL_IEI_VARIANT = 0x22,
|
|
|
|
V51_CTRL_IEI_INTERFACE_ID = 0x23,
|
|
|
|
/* variable length: LCP */
|
|
|
|
V52_CTRL_IEI_LCP_LINK_CTRL_FUNCTION = 0x30,
|
|
|
|
/* variable length: BCC */
|
|
|
|
V52_CTRL_IEI_BCC_USER_PORT_ID = 0x40,
|
|
|
|
V52_CTRL_IEI_BCC_ISDN_PORT_TS_ID = 0x41,
|
|
|
|
V52_CTRL_IEI_BCC_V5_TS_ID = 0x42,
|
|
|
|
V52_CTRL_IEI_BCC_MULTI_TS_MAP = 0x43,
|
|
|
|
V52_CTRL_IEI_BCC_REJECT_CAUSE = 0x44,
|
|
|
|
V52_CTRL_IEI_BCC_PROTOCOL_ERROR_CAUSE = 0x45,
|
|
|
|
V52_CTRL_IEI_BCC_CONNECTION_INCOMPLETE = 0x46,
|
|
|
|
V52_CTRL_IEI_BCC_INFO_TRANSFER_CAPABILITY = 0x47,
|
|
|
|
/* variable-length: Protection */
|
|
|
|
V52_CTRL_IEI_PP_SEQUENCE_NR = 0x50,
|
|
|
|
V52_CTRL_IEI_PP_PHYSICAL_C_CHAN_ID = 0x51,
|
|
|
|
V52_CTRL_IEI_PP_REJECTION_CAUSE = 0x52,
|
|
|
|
V52_CTRL_IEI_PP_PROTOCOL_ERROR_CAUSE = 0x53,
|
|
|
|
};
|
|
|
|
|
|
|
|
extern const struct value_string v51_ctrl_iei_str[];
|
|
|
|
|
2022-11-27 13:03:58 +00:00
|
|
|
extern const struct tlv_definition v51_ctrl_tlv_def;
|
2021-12-28 10:32:53 +00:00
|
|
|
|
|
|
|
extern const struct osmo_tlv_prot_def v51_ctrl_msg_tlv;
|
|
|
|
|
|
|
|
/* 14.4.2.5.4 Table 56/G.964 - Coding of Control Function Element */
|
|
|
|
enum v51_ctrl_func_el {
|
|
|
|
V51_CTRL_FE101_ACTIVATE_ACCESS = 0x01,
|
|
|
|
V51_CTRL_FE102_ACT_INIT_BY_USER = 0x02,
|
|
|
|
V51_CTRL_FE103_DS_ACTIVATED = 0x03,
|
|
|
|
V51_CTRL_FE104_ACCESS_ACTIVATED = 0x04,
|
|
|
|
V51_CTRL_FE105_DEACTIVATE_ACCESS = 0x05,
|
|
|
|
V51_CTRL_FE106_ACCESS_DEACTIVATED = 0x06,
|
|
|
|
V51_CTRL_FE201_UNBLOCK = 0x11,
|
|
|
|
V51_CTRL_FE203_BLOCK = 0x13,
|
|
|
|
V51_CTRL_FE205_BLOCK_REQ = 0x15,
|
|
|
|
V51_CTRL_FE206_PERFORMANCE_GRADING = 0x16,
|
|
|
|
V51_CTRL_FE207_D_CHANNEL_BLOCK = 0x17,
|
|
|
|
V51_CTRL_FE208_D_CHANNEL_UNBLOCK = 0x18,
|
|
|
|
};
|
|
|
|
|
|
|
|
extern const struct value_string v51_ctrl_func_el_str[];
|
|
|
|
|
|
|
|
/* 14.4.2.5.5 Table 57/G.964 - Coding of Control Function ID */
|
|
|
|
enum v51_ctrl_func_id {
|
|
|
|
V51_CTRL_ID_VERIFY_RE_PROVISIONING = 0x00,
|
|
|
|
V51_CTRL_ID_READY_FOR_RE_PROVISIONING = 0x01,
|
|
|
|
V51_CTRL_ID_NOT_READY_FOR_RE_PROVISIONING = 0x02,
|
|
|
|
V51_CTRL_ID_SWITCH_OVER_TO_NEW_VARIANT = 0x03,
|
|
|
|
V51_CTRL_ID_RE_PROVISIONING_STARTED = 0x04,
|
|
|
|
V51_CTRL_ID_CANNOT_RE_PROVISION = 0x05,
|
|
|
|
V51_CTRL_ID_REQUEST_VARIANT_AND_INTERFACE_ID = 0x06,
|
|
|
|
V51_CTRL_ID_VARIANT_AND_INTERFACE_ID = 0x07,
|
|
|
|
V51_CTRL_ID_BLOCKING_STARTED = 0x08,
|
|
|
|
V51_CTRL_ID_RESTART_REQUEST = 0x10,
|
|
|
|
V51_CTRL_ID_RESTART_COMPLETE = 0x11,
|
|
|
|
};
|
|
|
|
|
|
|
|
extern const struct value_string v51_ctrl_func_id_str[];
|
|
|
|
|
|
|
|
/* 13.4.7.9 Cause */
|
|
|
|
enum v51_cause_type {
|
|
|
|
V51_CTRL_CAUSE_T_RESP_TO_STATUS_ENQ = 0x00,
|
|
|
|
V51_CTRL_CAUSE_T_L3_ADDRESS_ERROR = 0x03,
|
|
|
|
V51_CTRL_CAUSE_T_MSG_TYPE_UNRECOGNIZED = 0x04,
|
|
|
|
V51_CTRL_CAUSE_T_OUT_OF_SEQUENCE_IE = 0x05,
|
|
|
|
V51_CTRL_CAUSE_T_REPEATED_OPT_IE = 0x06,
|
|
|
|
V51_CTRL_CAUSE_T_MAND_IE_MISSING = 0x07,
|
|
|
|
V51_CTRL_CAUSE_T_UNRECOGNIZED_IE = 0x08,
|
|
|
|
V51_CTRL_CAUSE_T_MAND_IE_CONTENT_ERROR = 0x09,
|
|
|
|
V51_CTRL_CAUSE_T_OPT_IE_CONTENT_ERROR = 0x0a,
|
|
|
|
V51_CTRL_CAUSE_T_MSG_INCOMP_PATH_STATE = 0x0b,
|
|
|
|
V51_CTRL_CAUSE_T_REPEATED_MAND_IE = 0x0c,
|
|
|
|
V51_CTRL_CAUSE_T_TOO_MANY_IE = 0x0d,
|
|
|
|
};
|
|
|
|
|
|
|
|
extern const struct value_string v51_cause_type_str[];
|
|
|
|
|
2022-11-27 13:03:58 +00:00
|
|
|
//const struct osmo_tlv_prot_def v51_ctrl_msg_tlv;
|
2021-12-28 10:32:53 +00:00
|
|
|
|
|
|
|
/* 16.3.2.2 Table 22/G.965 */
|
|
|
|
enum v52_link_ctrl_func {
|
|
|
|
V52_LCP_FE_IDReq = 0,
|
|
|
|
V52_LCP_FE_IDAck = 1,
|
|
|
|
V52_LCP_FE_IDRel = 2,
|
|
|
|
V52_LCP_FE_IDRej = 3,
|
|
|
|
V52_LCP_FE_301_302_LINK_UNBLOCK = 4,
|
|
|
|
V52_LCP_FE_303_304_LINK_BLOCK = 5,
|
|
|
|
V52_LCP_FE_305_DEF_LINK_BLOCK_REQ = 6,
|
|
|
|
V52_LCP_FE_306_NON_DEF_LINK_BLOCK_REQ = 7,
|
|
|
|
};
|
2022-11-27 13:03:58 +00:00
|
|
|
|
|
|
|
int v5x_rcv(struct osmo_dlsap_prim *odp, uint16_t dladdr, void *rx_cbdata);
|
|
|
|
int v5x_snd(struct v5x_interface *v5if, uint16_t dladdr, struct msgb *msg);
|
|
|
|
struct msgb *msgb_alloc_v5x(void);
|