osmo-v5/src/v5x_internal.h

216 lines
7.2 KiB
C

#pragma once
/* (C) 2021 by Harald Welte <laforge@gnumonks.org>
* (C) 2022 by Andreas Eversberg <jolly@eversberg.eu>
*
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include <stdint.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/fsm.h>
#include <osmocom/core/select.h>
#include <osmocom/gsm/lapd_core.h>
#include "ph_socket.h"
/* Table 35/G.964 */
enum v5x_mph_prim {
MPH_UBR, /* Unblock (req) */
MPH_UBI, /* Unblock (ind) */
MPH_BR, /* Block (req) */
MPH_BI, /* Block (ind) */
MPH_AR, /* Activate (req) */
MPH_AI, /* Activate (ind) */
MPH_AWI, /* Access activation by user (ind) */
MPH_DSAI, /* DS Activated (ind) */
MPH_DR, /* Deactivate (req) */
MPH_DI, /* Deactivate (ind) */
MPH_GI, /* Grading Information */
MPH_DB, /* Block D-Channel from user port */
MPH_DU, /* Unblock D-Channel from user port */
};
/* Table 3/G.964 */
enum v5x_fe_prim {
FE_establish_req = 0x00,
FE_establish_ack_ind = 0x03,
FE_establish_ind = 0x01,
FE_establish_ack_req = 0x02,
FE_line_signal_req = 0x10,
FE_line_signal_ind = 0x11,
FE_protocol_param_req = 0x20,
FE_disconnect_req = 0x30,
FE_disconnect_compl_req = 0x32,
FE_disconnect_compl_ind = 0x33,
};
/* Table 3/G.964 */
enum v5x_mgmt_prim {
MDU_CTRL_port_blocked,
MDU_CTRL_port_unblocked,
MDU_CTRL_port_restart_req,
MDU_CTRL_port_restart_ack,
MDU_CTRL_port_restart_compl,
MDU_error_ind,
};
struct osmo_fsm_inst;
enum v5x_dialect {
V5X_DIALECT_V51 = 1,
V5X_DIALECT_V52 = 2,
};
enum v5x_user_type {
V5X_USER_TYPE_ISDN = 1,
V5X_USER_TYPE_PSTN = 2,
};
/* forward-declarations */
struct v5x_interface;
struct v5x_instance;
struct v5x_user_port;
struct v5x_link;
/* A C-channel is a 64k timeslot used for signalling */
struct v5x_c_channel {
struct v5x_link *link; /* back-pointer */
struct v5x_timeslot *ts; /* E1 link timeslot. NULL = C-channel doesn't exist */
bool active; /* false == standby */
};
/* one physical E1 timeslot used on an E1 interface part of a V5.2 interface */
struct v5x_timeslot {
uint8_t nr;
struct v5x_link *link; /* back-pointer */
struct v5x_user_port *v5up; /* user port that this TS is assigned to */
uint16_t l3_address;
};
/* one physical E1 interface used within a V5.2 interface */
struct v5x_link {
uint8_t id;
struct v5x_interface *interface; /* back-pointer */
struct v5x_timeslot ts[32]; /* 32 E1 slots; 0 not available */
struct v5x_c_channel c_channel[3]; /* 64k signaling possible on TS16, TS15 and TS31 */
struct osmo_fsm_inst *l1_link_fi; /* Layer 1 Link FSM instance */
};
/* one V5.x interface between AN (Access Network) and LE (Local Exchange) */
struct v5x_interface {
struct llist_head list; /* instance.interfaces */
struct v5x_instance *instance; /* back-pointer */
enum v5x_dialect dialect;
uint32_t id; /* interface id */
uint8_t variant; /* provitioning variant */
struct v5x_link *primary_link; /* one of the links below */
struct v5x_link *secondary_link; /* one of the links below */
/* 1..16 links in one interface */
struct v5x_link links[16];
struct {
struct v5x_ctrl_proto *ctrl; /* common control protocol instance */
struct lapv5_instance *li; /* Control data link */
bool established; /* track if link is up or down */
struct v5x_c_channel *c_chan; /* pointer to active C-channel */
} control;
struct {
struct lapv5_instance *li; /* Link control data link */
struct v5x_c_channel *c_chan; /* pointer to active C-channel */
struct osmo_fsm_inst *fi; /* Link Control FSM instance */
} lcp;
struct {
struct lapv5_instance *li; /* PSTN data link */
struct v5x_c_channel *c_chan; /* pointer to active C-channel */
} pstn;
struct {
struct lapv5_instance *li; /* BCC data link */
struct v5x_c_channel *c_chan; /* pointer to active C-channel */
} bcc;
struct {
struct lapv5_instance *li; /* Protection data link 1 + 2 */
struct v5x_c_channel *c_chan; /* pointer to active C-channel */
} protection[2];
struct llist_head user_ports; /* list of v5x_user_port */
};
struct v5x_ctrl_proto {
struct v5x_user_port *v5up; /* back pointer, if port control is used */
struct v5x_interface *v5if; /* back pointer, if common control is used */
struct osmo_fsm_inst *fi; /* control FSM */
struct llist_head tx_queue; /* list of message to be transmitted */
struct msgb *tx_msg; /* copy of unacked message, for second try */
};
struct v5x_pstn_proto {
struct v5x_user_port *v5up; /* back pointer, if port control is used */
struct osmo_fsm_inst *fi; /* control FSM */
uint8_t S_s, S_a, S_r; /* sequence numbers */
struct msgb *tx_msg; /* copy of unacked message, for repitition */
int timeout_event; /* event when timer times out */
int timeout_count; /* how many times the timer was started/timed out */
struct osmo_timer_list timer_Tr; /* extra timer for receive sequence ack */
struct osmo_timer_list timer_Tt; /* extra timer for transmit sequence ack */
};
/* one user-facing port (subscriber line) */
struct v5x_user_port {
struct llist_head list; /* part of v5x_instance.ports */
struct v5x_interface *inst; /* back-pointer to instance we're part of */
uint16_t nr; /* port-number in decoded form (0..32767) */
char ifname[64]; /* name of interface, also used for PH-socket */
enum v5x_user_type type; /* type of port (ISDN/PSTN) */
struct v5x_ctrl_proto *ctrl; /* port control protocol instance */
struct osmo_fsm_inst *port_fi; /* port FSM */
uint8_t ts_nr[2]; /* time slots used (one for PSTN, two for ISDN) */
uint8_t link_nr[2]; /* link used */
uint8_t ts_activated[2]; /* set if data stream is active */
struct {
} isdn;
struct {
struct v5x_pstn_proto *proto;
} pstn;
ph_socket_t ph_socket; /* unix socket to connect port to */
bool le_unblocked; /* if port is not blocked by LE */
bool an_unblocked; /* if port is not blocked by AN */
};
struct v5x_instance {
struct llist_head list; /* part of global list of instances */
struct llist_head interfaces; /* v5x_interface.list */
};
struct v5x_instance *v5x_instance_alloc(void *ctx);
struct v5x_interface *v5x_interface_alloc(struct v5x_instance *v5i, enum v5x_dialect dialect,
int (*ph_data_req_cb)(struct msgb *msg, void *cbdata));
struct v5x_user_port *v5x_user_port_create(struct v5x_interface *v5if, uint16_t nr, enum v5x_user_type,
uint8_t ts1, uint8_t ts2);
void v5x_interface_free(struct v5x_interface *v5if);
struct v5x_user_port *v5x_user_port_find(struct v5x_interface *v5if, uint16_t nr, bool is_isdn);
void v5x_user_port_destroy(struct v5x_user_port *v5up);
//FIXME: move this
void ph_socket_rx_cb(ph_socket_t *s, int channel, uint8_t prim, uint8_t *data, int length);