diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-07-28 03:32:52 +0800 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-07-28 03:36:32 +0800 |
commit | 97f66e2b534e2a54c63360a3f8134a0189c54e25 (patch) | |
tree | 903e34443767b09ef1d11575f8a1502f6295c7fd /include |
Public release of the cellmgr_ng code to convert E1 to IPA SCCP
Diffstat (limited to 'include')
-rw-r--r-- | include/Makefile.am | 5 | ||||
-rw-r--r-- | include/bsc_data.h | 131 | ||||
-rw-r--r-- | include/bss_patch.h | 48 | ||||
-rw-r--r-- | include/bssap_sccp.h | 33 | ||||
-rw-r--r-- | include/ipaccess.h | 52 | ||||
-rw-r--r-- | include/mgcp/Makefile.am | 1 | ||||
-rw-r--r-- | include/mgcp/mgcp.h | 141 | ||||
-rw-r--r-- | include/mgcp/mgcp_internal.h | 89 | ||||
-rw-r--r-- | include/mgcp_ss7.h | 68 | ||||
-rw-r--r-- | include/mtp_data.h | 88 | ||||
-rw-r--r-- | include/mtp_level3.h | 164 | ||||
-rw-r--r-- | include/mtp_pcap.h | 29 | ||||
-rw-r--r-- | include/openbsc_nat/Makefile.am | 1 | ||||
-rw-r--r-- | include/openbsc_nat/bssap.h | 339 | ||||
-rw-r--r-- | include/openbsc_nat/tlv.h | 234 | ||||
-rw-r--r-- | include/snmp_mtp.h | 39 | ||||
-rw-r--r-- | include/thread.h | 59 | ||||
-rw-r--r-- | include/udp_input.h | 52 | ||||
-rw-r--r-- | include/write_queue.h | 48 |
19 files changed, 1621 insertions, 0 deletions
diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 0000000..7a2960e --- /dev/null +++ b/include/Makefile.am @@ -0,0 +1,5 @@ +noinst_HEADERS = mtp_level3.h mtp_data.h ipaccess.h thread.h mtp_pcap.h \ + mgcp_ss7.h bss_patch.h write_queue.h bssap_sccp.h bsc_data.h udp_input.h \ + snmp_mtp.h + +SUBDIRS = mgcp openbsc_nat diff --git a/include/bsc_data.h b/include/bsc_data.h new file mode 100644 index 0000000..6d61a22 --- /dev/null +++ b/include/bsc_data.h @@ -0,0 +1,131 @@ +/* Everything related to the BSC connection */ +/* + * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org> + * (C) 2010 by On-Waves + * All Rights Reserved + * + * 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. + * + */ + +#ifndef BSC_DATA_H +#define BSC_DATA_H + +#include <laf0rge1/linuxlist.h> +#include <laf0rge1/select.h> +#include <laf0rge1/timer.h> + +#include <sccp/sccp.h> + +#include "write_queue.h" + +#include <netinet/in.h> +#include <arpa/inet.h> + +struct bsc_data; +struct snmp_mtp_session; + +/** + * A link to the underlying MTP2 library or such + */ +struct link_data { + union { + struct { + struct thread_notifier *notifier; + struct llist_head mtp_queue; + struct timer_list mtp_timeout; + } c7; + struct { + struct write_queue write_queue; + struct sockaddr_in remote; + struct snmp_mtp_session *session; + int reset_timeout; + } udp; + }; + + int pcap_fd; + struct bsc_data *bsc; + struct mtp_link *the_link; + + struct timer_list link_activate; + int forced_down; + + int (*start)(struct link_data *); + int (*write)(struct link_data *, struct msgb *msg); + int (*shutdown)(struct link_data *); + int (*reset)(struct link_data *data); + int (*clear_queue)(struct link_data *data); +}; + + +struct bsc_data { + /* MSC */ + char *msc_address; + struct write_queue msc_connection; + struct timer_list reconnect_timer; + int first_contact; + int msc_time; + struct timer_list msc_timeout; + int msc_ip_dscp; + + int ping_time; + int pong_time; + struct timer_list ping_timeout; + struct timer_list pong_timeout; + + int closing; + struct llist_head sccp_connections; + struct timer_list reset_timeout; + int reset_count; + + struct timer_list start_timer; + + int setup; + + struct link_data link; + + const char *token; + + /* mgcp messgaes */ + struct write_queue mgcp_agent; +}; + +/* bsc related functions */ +void release_bsc_resources(struct bsc_data *bsc); +void bsc_link_down(struct link_data *data); +void bsc_link_up(struct link_data *data); + +/* msc related functions */ +int msc_init(struct bsc_data *bsc); +void msc_schedule_reconnect(struct bsc_data *bsc); +void msc_send_rlc(struct bsc_data *bsc, struct sccp_source_reference *src, struct sccp_source_reference *dest); +void msc_send_reset(struct bsc_data *bsc); +void msc_send_msg(struct bsc_data *bsc, int rc, struct sccp_parse_result *, struct msgb *msg); +void msc_clear_queue(struct bsc_data *data); + +/* connection tracking and action */ +void update_con_state(int rc, struct sccp_parse_result *result, struct msgb *msg, int from_msc, int sls); +unsigned int sls_for_src_ref(struct sccp_source_reference *ref); + +/* c7 init */ +int link_c7_init(struct link_data *data); + +/* udp init */ +int link_udp_init(struct link_data *data, int src_port, const char *dest_ip, int port); + +/* MGCP */ +void mgcp_forward(struct bsc_data *bsc, const u_int8_t *data, unsigned int length); + +#endif diff --git a/include/bss_patch.h b/include/bss_patch.h new file mode 100644 index 0000000..43dc5f1 --- /dev/null +++ b/include/bss_patch.h @@ -0,0 +1,48 @@ +/* Patch Messages to and from the MSC */ +/* + * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org> + * (C) 2010 by On-Waves + * All Rights Reserved + * + * 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. + * + */ +#ifndef bss_patch_h +#define bss_patch_h + +#include <laf0rge1/msgb.h> + +#include <sccp/sccp.h> + +#define BSS_FILTER_RESET 1 +#define BSS_FILTER_RESET_ACK 2 +#define BSS_FILTER_RLSD 3 +#define BSS_FILTER_RLC 4 +#define BSS_FILTER_CLEAR_COMPL 5 + +/** + * Error is < 0 + * Success is == 0 + * Filter is > 0 + */ +int bss_patch_filter_msg(struct msgb *msg, struct sccp_parse_result *result); + +/* + * Copy inpt->l2h to target->l2h but rewrite the SCCP header on the way + */ +void bss_rewrite_header_for_msc(int, struct msgb *target, struct msgb *inpt, struct sccp_parse_result *result); +int bss_rewrite_header_to_bsc(struct msgb *target, int opc, int dpc); + +#endif diff --git a/include/bssap_sccp.h b/include/bssap_sccp.h new file mode 100644 index 0000000..f2dd45c --- /dev/null +++ b/include/bssap_sccp.h @@ -0,0 +1,33 @@ +/* + * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org> + * (C) 2010 by On-Waves + * All Rights Reserved + * + * 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. + * + */ +#ifndef bssap_sccp_h +#define bssap_sccp_h + +#include <sys/types.h> +#include <sccp/sccp_types.h> + +struct msgb *create_clear_command(struct sccp_source_reference *dest_ref); +struct msgb *create_sccp_rlsd(struct sccp_source_reference *src_ref, struct sccp_source_reference *dst); +struct msgb *create_sccp_rlc(struct sccp_source_reference *src_ref, struct sccp_source_reference *dst); +struct msgb *create_sccp_refuse(struct sccp_source_reference *dest_ref); +struct msgb *create_reset(); + +#endif diff --git a/include/ipaccess.h b/include/ipaccess.h new file mode 100644 index 0000000..345ed3c --- /dev/null +++ b/include/ipaccess.h @@ -0,0 +1,52 @@ +#ifndef _IPACCESS_H +#define _IPACCESS_H + +#include <laf0rge1/linuxlist.h> + +#define IPA_TCP_PORT_OML 3002 +#define IPA_TCP_PORT_RSL 3003 + +struct ipaccess_head { + u_int16_t len; /* network byte order */ + u_int8_t proto; + u_int8_t data[0]; +} __attribute__ ((packed)); + +enum ipaccess_proto { + IPAC_PROTO_RSL = 0x00, + IPAC_PROTO_IPACCESS = 0xfe, + IPAC_PROTO_SCCP = 0xfd, + IPAC_PROTO_OML = 0xff, +}; + +enum ipaccess_msgtype { + IPAC_MSGT_PING = 0x00, + IPAC_MSGT_PONG = 0x01, + IPAC_MSGT_ID_GET = 0x04, + IPAC_MSGT_ID_RESP = 0x05, + IPAC_MSGT_ID_ACK = 0x06, +}; + +enum ipaccess_id_tags { + IPAC_IDTAG_SERNR = 0x00, + IPAC_IDTAG_UNITNAME = 0x01, + IPAC_IDTAG_LOCATION1 = 0x02, + IPAC_IDTAG_LOCATION2 = 0x03, + IPAC_IDTAG_EQUIPVERS = 0x04, + IPAC_IDTAG_SWVERSION = 0x05, + IPAC_IDTAG_IPADDR = 0x06, + IPAC_IDTAG_MACADDR = 0x07, + IPAC_IDTAG_UNIT = 0x08, +}; + +/* + * methods for parsing and sending a message + */ +int ipaccess_rcvmsg_base(struct msgb *msg, struct bsc_fd *bfd); +struct msgb *ipaccess_read_msg(struct bsc_fd *bfd, int *error); +void ipaccess_prepend_header(struct msgb *msg, int proto); +int ipaccess_send_id_ack(int fd); +int ipaccess_send_id_req(int fd); + + +#endif /* _IPACCESS_H */ diff --git a/include/mgcp/Makefile.am b/include/mgcp/Makefile.am new file mode 100644 index 0000000..55199ff --- /dev/null +++ b/include/mgcp/Makefile.am @@ -0,0 +1 @@ +noinst_HEADERS = mgcp.h mgcp_internal.h diff --git a/include/mgcp/mgcp.h b/include/mgcp/mgcp.h new file mode 100644 index 0000000..914571a --- /dev/null +++ b/include/mgcp/mgcp.h @@ -0,0 +1,141 @@ +/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */ + +/* + * (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org> + * (C) 2009-2010 by On-Waves + * All Rights Reserved + * + * 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. + * + */ + +#ifndef OPENBSC_MGCP_H +#define OPENBSC_MGCP_H + +#include <laf0rge1/msgb.h> + +#include <arpa/inet.h> + +#define RTP_PORT_DEFAULT 4000 +/** + * Calculate the RTP audio port for the given multiplex + * and the direction. This allows a semi static endpoint + * to port calculation removing the need for the BSC + * and the MediaGateway to communicate. + * + * Port usage explained: + * base + (multiplex * 2) + 0 == local port to wait for network packets + * base + (multiplex * 2) + 1 == local port for rtcp + * + * The above port will receive packets from the BTS that need + * to be patched and forwarded to the network. + * The above port will receive packets from the network that + * need to be patched and forwarded to the BTS. + * + * We assume to have a static BTS IP address so we can differentiate + * network and BTS. + * + */ +static inline int rtp_calculate_port(int multiplex, int base) +{ + return base + (multiplex * 2); +} + + +/* + * Handling of MGCP Endpoints and the MGCP Config + */ +struct mgcp_endpoint; +struct mgcp_config; + +#define MGCP_ENDP_CRCX 1 +#define MGCP_ENDP_DLCX 2 +#define MGCP_ENDP_MDCX 3 + +/* + * what to do with the msg? + * - continue as usual? + * - reject and send a failure code? + * - defer? do not send anything + */ +#define MGCP_POLICY_CONT 4 +#define MGCP_POLICY_REJECT 5 +#define MGCP_POLICY_DEFER 6 + +typedef int (*mgcp_change)(struct mgcp_config *cfg, int endpoint, int state, int local_rtp); +typedef int (*mgcp_policy)(struct mgcp_config *cfg, int endpoint, int state, const char *transactio_id); +typedef int (*mgcp_reset)(struct mgcp_config *cfg); + +struct mgcp_config { + /* common configuration */ + int source_port; + char *local_ip; + char *source_addr; + char *bts_ip; + char *call_agent_addr; + + /* default endpoint data */ + struct in_addr bts_in; + char *audio_name; + int audio_payload; + int audio_loop; + int early_bind; + int rtp_base_port; + int endp_dscp; + + /* only used in forward mode */ + char *forward_ip; + int forward_port; + + unsigned int last_call_id; + + /* endpoint configuration */ + unsigned int number_endpoints; + struct mgcp_endpoint *endpoints; + + /* spec handling */ + int force_realloc; + + /* callback functionality */ + mgcp_change change_cb; + mgcp_policy policy_cb; + mgcp_reset reset_cb; + void *data; +}; + +/* config management */ +struct mgcp_config *mgcp_config_alloc(void); +int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg); +int mgcp_vty_init(void); +int mgcp_endpoints_allocate(struct mgcp_config *cfg); +int mgcp_bind_rtp_port(struct mgcp_endpoint *endp, int rtp_port); +void mgcp_free_endp(struct mgcp_endpoint *endp); + +/* + * format helper functions + */ +struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg); +struct msgb *mgcp_create_response_with_data(int code, const char *msg, const char *trans, const char *data); + +/* adc helper */ +static inline int mgcp_timeslot_to_endpoint(int multiplex, int timeslot) +{ + if (timeslot == 0) + timeslot = 1; + return timeslot + (31 * multiplex); +} + + +#endif diff --git a/include/mgcp/mgcp_internal.h b/include/mgcp/mgcp_internal.h new file mode 100644 index 0000000..d1a6523 --- /dev/null +++ b/include/mgcp/mgcp_internal.h @@ -0,0 +1,89 @@ +/* MGCP Private Data */ + +/* + * (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org> + * (C) 2009-2010 by On-Waves + * All Rights Reserved + * + * 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. + * + */ + +#ifndef OPENBSC_MGCP_DATA_H +#define OPENBSC_MGCP_DATA_H + +#include <laf0rge1/select.h> + +#define CI_UNUSED 0 + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +#endif + +enum mgcp_connection_mode { + MGCP_CONN_NONE = 0, + MGCP_CONN_RECV_ONLY = 1, + MGCP_CONN_SEND_ONLY = 2, + MGCP_CONN_RECV_SEND = MGCP_CONN_RECV_ONLY | MGCP_CONN_SEND_ONLY, +}; + +struct mgcp_endpoint { + int ci; + char *callid; + char *local_options; + int conn_mode; + + int bts_payload_type; + int net_payload_type; + + /* the local rtp port we are binding to */ + int rtp_port; + + /* + * RTP mangling: + * - we get RTP and RTCP to us and need to forward to the BTS + * - we get RTP and RTCP from the BTS and forward to the network + */ + struct bsc_fd local_rtp; + struct bsc_fd local_rtcp; + + struct in_addr remote; + struct in_addr bts; + + /* in network byte order */ + int net_rtp, net_rtcp; + int bts_rtp, bts_rtcp; + + /* backpointer */ + struct mgcp_config *cfg; + + /* statistics */ + unsigned int in_bts; + unsigned int in_remote; +}; + +#define ENDPOINT_NUMBER(endp) abs(endp - endp->cfg->endpoints) + +struct mgcp_msg_ptr { + unsigned int start; + unsigned int length; +}; + +int mgcp_analyze_header(struct mgcp_config *cfg, struct msgb *msg, + struct mgcp_msg_ptr *ptr, int size, + const char **transaction_id, struct mgcp_endpoint **endp); +int mgcp_send_dummy(struct mgcp_endpoint *endp); + +#endif diff --git a/include/mgcp_ss7.h b/include/mgcp_ss7.h new file mode 100644 index 0000000..04eeb5e --- /dev/null +++ b/include/mgcp_ss7.h @@ -0,0 +1,68 @@ +/* mgcp_ss7 helper coder */ +/* + * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org> + * (C) 2010 by On-Waves + * All Rights Reserved + * + * 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. + * + */ + +#ifndef mgcp_ss7_h +#define mgcp_ss7_h + +#include <laf0rge1/timer.h> + +#include "write_queue.h" +#include "thread.h" + + +struct mgcp_ss7_endpoint; +struct mgcp_ss7 { + struct mgcp_config *cfg; + struct write_queue mgcp_fd; + struct msgb *mgcp_msg; + + struct mgcp_ss7_endpoint *mgw_end; + + /* timer */ + struct timer_list poll_timer; + + /* thread handling */ + struct thread_notifier *cmd_queue; + pthread_t thread; +}; + +enum { + MGCP_SS7_MUTE_STATUS, + MGCP_SS7_ALLOCATE, + MGCP_SS7_DELETE, + MGCP_SS7_SHUTDOWN, +}; + +struct mgcp_ss7_cmd { + struct llist_head entry; + u_int8_t type; + u_int32_t port; + u_int32_t param; +}; + +void mgcp_ss7_exec(struct mgcp_ss7 *mgcp, u_int8_t type, u_int32_t port, u_int32_t param); + +struct mgcp_ss7 *mgcp_ss7_init(int endpoints, const char *local_ip, const char *mgw_ip, int base_port, int payload); +void mgcp_ss7_reset(struct mgcp_ss7 *mgcp); +void mgcp_ss7_free(struct mgcp_ss7 *mgcp); + +#endif diff --git a/include/mtp_data.h b/include/mtp_data.h new file mode 100644 index 0000000..d8cdff3 --- /dev/null +++ b/include/mtp_data.h @@ -0,0 +1,88 @@ +/* + * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org> + * (C) 2010 by On-Waves + * All Rights Reserved + * + * 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. + * + */ +#ifndef mtp_data_h +#define mtp_data_h + +#include <laf0rge1/msgb.h> +#include <laf0rge1/timer.h> + +/* MTP Level3 timers */ + +/* Timers for SS7 */ +#define MTP_T1 12, 0 +#define MTP_T2 30, 0 +#define START_DELAY 8, 0 + +/** + * The state of the mtp_link in terms of layer3 and upwards + */ +struct mtp_link { + /* routing info.. */ + int dpc, opc; + + /* internal state */ + /* the MTP1 link is up */ + int available; + int running; + int sccp_up; + + /* misc data */ + u_int8_t test_ptrn[14]; + + int sltm_pending; + struct llist_head pending_msgs; + int sltm_once; + int was_up; + + + /* the associated link */ + int link; + + int slta_misses; + struct timer_list t1_timer; + struct timer_list t2_timer; + + struct timer_list delay_timer; +}; + + +struct mtp_link *mtp_link_alloc(void); +void mtp_link_stop(struct mtp_link *link); +void mtp_link_reset(struct mtp_link *link); +int mtp_link_data(struct mtp_link *link, struct msgb *msg); +int mtp_link_submit_sccp_data(struct mtp_link *link, int sls, const u_int8_t *data, unsigned int length); + + +/* one time init function */ +void mtp_link_init(void); + +/* to be implemented for MSU sending */ +void mtp_link_submit(struct mtp_link *link, struct msgb *msg); +void mtp_link_forward_sccp(struct mtp_link *link, struct msgb *msg, int sls); +void mtp_link_restart(struct mtp_link *link); +void mtp_link_slta_recv(struct mtp_link *link); +void mtp_link_sccp_down(struct mtp_link *link); + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +#endif + +#endif diff --git a/include/mtp_level3.h b/include/mtp_level3.h new file mode 100644 index 0000000..46cde40 --- /dev/null +++ b/include/mtp_level3.h @@ -0,0 +1,164 @@ +/* Q.701-Q.704, Q.706, Q.707 handling code */ +/* + * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org> + * (C) 2010 by On-Waves + * All Rights Reserved + * + * 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. + * + */ + +#ifndef mtp_level3_h +#define mtp_level3_h + +#include <endian.h> +#include <sys/types.h> + + +/* + * pssible service information octets.. + */ +#define MTP_NI_NATION_NET 0x02 + +#define MTP_SI_MNT_SNM_MSG 0x00 +#define MTP_SI_MNT_REG_MSG 0x01 +#define MTP_SI_MNT_SCCP 0x03 + +/* + * h0 contains the group, h1 the semantic of it + */ + +#define MTP_TST_MSG_GRP 0x01 +#define MTP_PROHIBIT_MSG_GRP 0x04 +#define MTP_TRF_RESTR_MSG_GRP 0x07 + +/* h1 values for different groups */ +#define MTP_TST_MSG_SLTM 0x01 +#define MTP_TST_MSG_SLTA 0x02 + +#define MTP_RESTR_MSG_ALLWED 0x01 + +#define MTP_PROHIBIT_MSG_SIG 0x01 + + +#define SCCP_SST 0x03 +#define SCCP_SSA 0x01 + +#define MTP_LINK_MASK 0x0F +#define MTP_ADDR_MASK 0x0FFF +#define MTP_APOC_MASK 0x3f + + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define MTP_LINK_SLS(addr) ((addr >>28) & MTP_LINK_MASK) +#define MTP_ADDR(link, dpc, opc) \ + (((dpc) & MTP_ADDR_MASK) << 0 | \ + ((opc) & MTP_ADDR_MASK) << 14| \ + ((link) & MTP_LINK_MASK) << 28) +#define MTP_MAKE_APOC(apoc) \ + (apoc & 0x3fff) +#elif __BYTE_ORDER == __BIG_ENDIAN +static inline u_int32_t c_swap_32(u_int32_t in) +{ + return (((in & 0x000000ff) << 24) | + ((in & 0x0000ff00) << 8) | + ((in & 0x00ff0000) >> 8) | + ((in & 0xff000000) >> 24)); +} +static inline u_int16_t c_swap_16(u_int16_t in) +{ + return (((in & 0x00ff) << 8) | + (in & 0xff00) >> 8); +} +#define MTP_LINK_SLS(addr) ((c_swap_32(addr)>>28) & MTP_LINK_MASK) +#define MTP_ADDR(link, dpc, opc) \ + c_swap_32(((dpc) & MTP_ADDR_MASK) << 0 | \ + ((opc) & MTP_ADDR_MASK) << 14| \ + ((link) & MTP_LINK_MASK) << 28) +#define MTP_MAKE_APOC(apoc) \ + c_swap_16((apoc & 0x3fff)) +#endif + + + +/* + * not the on wire address... + */ +struct mtp_addr { + u_int16_t dpc; + u_int16_t opc; + u_int8_t link; +} __attribute__((packed)); + +/* + * the struct is defined in Q.704 and can be seen in the + * wireshark dissectors too + */ +struct mtp_level_3_hdr { +#if __BYTE_ORDER == __LITTLE_ENDIAN + u_int8_t ser_ind : 4, + spare : 2, + ni : 2; +#elif __BYTE_ORDER == __BIG_ENDIAN + u_int8_t ni : 2, + spare : 2, + ser_ind : 4; +#endif + u_int32_t addr; + u_int8_t data[0]; +} __attribute__((packed)); + +struct mtp_level_3_cmn { +#if __BYTE_ORDER == __LITTLE_ENDIAN + u_int8_t h0 : 4, + h1 : 4; +#elif __BYTE_ORDER == __BIG_ENDIAN + u_int8_t h1 : 4, + h0 : 4; +#endif +} __attribute__((packed)); + +struct mtp_level_3_mng { + struct mtp_level_3_cmn cmn; +#if __BYTE_ORDER == __LITTLE_ENDIAN + u_int8_t spare : 4, + length : 4; +#elif __BYTE_ORDER == __BIG_ENDIAN + u_int8_t length : 4, + spare : 4; +#endif + u_int8_t data[0]; +} __attribute__((packed)); + +struct mtp_level_3_prohib { + struct mtp_level_3_cmn cmn; + + u_int16_t apoc; +} __attribute__((packed)); + +struct sccp_con_ctrl_prt_mgt { + u_int8_t sst; + u_int8_t assn; /* affected sub system number */ + u_int16_t apoc; +#if __BYTE_ORDER == __LITTLE_ENDIAN + u_int8_t mul_ind : 2, + spare : 6; +#elif __BYTE_ORDER == __BIG_ENDIAN + u_int8_t spare : 6, + mul_ind : 2; +#endif +} __attribute__((packed)); + +#endif diff --git a/include/mtp_pcap.h b/include/mtp_pcap.h new file mode 100644 index 0000000..9334393 --- /dev/null +++ b/include/mtp_pcap.h @@ -0,0 +1,29 @@ +/* + * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org> + * (C) 2010 by On-Waves + * All Rights Reserved + * + * 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. + * + */ +#ifndef mtp_pcap_h +#define mtp_pcap_h + +#include <sys/types.h> + +int mtp_pcap_write_header(int fd); +int mtp_pcap_write_msu(int fd, const u_int8_t *data, int length); + +#endif diff --git a/include/openbsc_nat/Makefile.am b/include/openbsc_nat/Makefile.am new file mode 100644 index 0000000..96bb305 --- /dev/null +++ b/include/openbsc_nat/Makefile.am @@ -0,0 +1 @@ +noinst_HEADERS = bssap.h tlv.h diff --git a/include/openbsc_nat/bssap.h b/include/openbsc_nat/bssap.h new file mode 100644 index 0000000..8c785bb --- /dev/null +++ b/include/openbsc_nat/bssap.h @@ -0,0 +1,339 @@ +/* From GSM08.08 */ + +#ifndef BSSAP_H +#define BSSAP_H + +#include <stdlib.h> + +#include <laf0rge1/msgb.h> +#include <sccp/sccp.h> + +struct gsm_network; +struct bss_sccp_connection_data; + +/* + * this is from GSM 03.03 CGI but is copied in GSM 08.08 + * in § 3.2.2.27 for Cell Identifier List + */ +enum CELL_IDENT { + CELL_IDENT_WHOLE_GLOBAL = 0, + CELL_IDENT_LAC_AND_CI = 1, + CELL_IDENT_CI = 2, + CELL_IDENT_NO_CELL = 3, + CELL_IDENT_LAI_AND_LAC = 4, + CELL_IDENT_LAC = 5, + CELL_IDENT_BSS = 6, + CELL_IDENT_UTRAN_PLMN_LAC_RNC = 8, + CELL_IDENT_UTRAN_RNC = 9, + CELL_IDENT_UTRAN_LAC_RNC = 10, +}; + + +/* GSM 08.06 § 6.3 */ +enum BSSAP_MSG_TYPE { + BSSAP_MSG_BSS_MANAGEMENT = 0x0, + BSSAP_MSG_DTAP = 0x1, +}; + +struct bssmap_header { + u_int8_t type; + u_int8_t length; +} __attribute__((packed)); + +struct dtap_header { + u_int8_t type; + u_int8_t link_id; + u_int8_t length; +} __attribute__((packed)); + + +enum BSS_MAP_MSG_TYPE { + BSS_MAP_MSG_RESERVED_0 = 0, + + /* ASSIGNMENT MESSAGES */ + BSS_MAP_MSG_ASSIGMENT_RQST = 1, + BSS_MAP_MSG_ASSIGMENT_COMPLETE = 2, + BSS_MAP_MSG_ASSIGMENT_FAILURE = 3, + + /* HANDOVER MESSAGES */ + BSS_MAP_MSG_HANDOVER_RQST = 16, + BSS_MAP_MSG_HANDOVER_REQUIRED = 17, + BSS_MAP_MSG_HANDOVER_RQST_ACKNOWLEDGE= 18, + BSS_MAP_MSG_HANDOVER_CMD = 19, + BSS_MAP_MSG_HANDOVER_COMPLETE = 20, + BSS_MAP_MSG_HANDOVER_SUCCEEDED = 21, + BSS_MAP_MSG_HANDOVER_FAILURE = 22, + BSS_MAP_MSG_HANDOVER_PERFORMED = 23, + BSS_MAP_MSG_HANDOVER_CANDIDATE_ENQUIRE = 24, + BSS_MAP_MSG_HANDOVER_CANDIDATE_RESPONSE = 25, + BSS_MAP_MSG_HANDOVER_REQUIRED_REJECT = 26, + BSS_MAP_MSG_HANDOVER_DETECT = 27, + + /* RELEASE MESSAGES */ + BSS_MAP_MSG_CLEAR_CMD = 32, + BSS_MAP_MSG_CLEAR_COMPLETE = 33, + BSS_MAP_MSG_CLEAR_RQST = 34, + BSS_MAP_MSG_RESERVED_1 = 35, + BSS_MAP_MSG_RESERVED_2 = 36, + BSS_MAP_MSG_SAPI_N_REJECT = 37, + BSS_MAP_MSG_CONFUSION = 38, + + /* OTHER CONNECTION RELATED MESSAGES */ + BSS_MAP_MSG_SUSPEND = 40, + BSS_MAP_MSG_RESUME = 41, + BSS_MAP_MSG_CONNECTION_ORIENTED_INFORMATION = 42, + BSS_MAP_MSG_PERFORM_LOCATION_RQST = 43, + BSS_MAP_MSG_LSA_INFORMATION = 44, + BSS_MAP_MSG_PERFORM_LOCATION_RESPONSE = 45, + BSS_MAP_MSG_PERFORM_LOCATION_ABORT = 46, + BSS_MAP_MSG_COMMON_ID = 47, + + /* GENERAL MESSAGES */ + BSS_MAP_MSG_RESET = 48, + BSS_MAP_MSG_RESET_ACKNOWLEDGE = 49, + BSS_MAP_MSG_OVERLOAD = 50, + BSS_MAP_MSG_RESERVED_3 = 51, + BSS_MAP_MSG_RESET_CIRCUIT = 52, + BSS_MAP_MSG_RESET_CIRCUIT_ACKNOWLEDGE = 53, + BSS_MAP_MSG_MSC_INVOKE_TRACE = 54, + BSS_MAP_MSG_BSS_INVOKE_TRACE = 55, + BSS_MAP_MSG_CONNECTIONLESS_INFORMATION = 58, + + /* TERRESTRIAL RESOURCE MESSAGES */ + BSS_MAP_MSG_BLOCK = 64, + BSS_MAP_MSG_BLOCKING_ACKNOWLEDGE = 65, + BSS_MAP_MSG_UNBLOCK = 66, + BSS_MAP_MSG_UNBLOCKING_ACKNOWLEDGE = 67, + BSS_MAP_MSG_CIRCUIT_GROUP_BLOCK = 68, + BSS_MAP_MSG_CIRCUIT_GROUP_BLOCKING_ACKNOWLEDGE = 69, + BSS_MAP_MSG_CIRCUIT_GROUP_UNBLOCK = 70, + BSS_MAP_MSG_CIRCUIT_GROUP_UNBLOCKING_ACKNOWLEDGE = 71, + BSS_MAP_MSG_UNEQUIPPED_CIRCUIT = 72, + BSS_MAP_MSG_CHANGE_CIRCUIT = 78, + BSS_MAP_MSG_CHANGE_CIRCUIT_ACKNOWLEDGE = 79, + + /* RADIO RESOURCE MESSAGES */ + BSS_MAP_MSG_RESOURCE_RQST = 80, + BSS_MAP_MSG_RESOURCE_INDICATION = 81, + BSS_MAP_MSG_PAGING = 82, + BSS_MAP_MSG_CIPHER_MODE_CMD = 83, + BSS_MAP_MSG_CLASSMARK_UPDATE = 84, + BSS_MAP_MSG_CIPHER_MODE_COMPLETE = 85, + BSS_MAP_MSG_QUEUING_INDICATION = 86, + BSS_MAP_MSG_COMPLETE_LAYER_3 = 87, + BSS_MAP_MSG_CLASSMARK_RQST = 88, + BSS_MAP_MSG_CIPHER_MODE_REJECT = 89, + BSS_MAP_MSG_LOAD_INDICATION = 90, + + /* VGCS/VBS */ + BSS_MAP_MSG_VGCS_VBS_SETUP = 4, + BSS_MAP_MSG_VGCS_VBS_SETUP_ACK = 5, + BSS_MAP_MSG_VGCS_VBS_SETUP_REFUSE = 6, + BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RQST = 7, + BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RESULT = 28, + BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_FAILURE = 29, + BSS_MAP_MSG_VGCS_VBS_QUEUING_INDICATION = 30, + BSS_MAP_MSG_UPLINK_RQST = 31, + BSS_MAP_MSG_UPLINK_RQST_ACKNOWLEDGE = 39, + BSS_MAP_MSG_UPLINK_RQST_CONFIRMATION = 73, + BSS_MAP_MSG_UPLINK_RELEASE_INDICATION = 74, + BSS_MAP_MSG_UPLINK_REJECT_CMD = 75, + BSS_MAP_MSG_UPLINK_RELEASE_CMD = 76, + BSS_MAP_MSG_UPLINK_SEIZED_CMD = 77, +}; + +enum GSM0808_IE_CODING { + GSM0808_IE_CIRCUIT_IDENTITY_CODE = 1, + GSM0808_IE_RESERVED_0 = 2, + GSM0808_IE_RESOURCE_AVAILABLE = 3, + GSM0808_IE_CAUSE = 4, + GSM0808_IE_CELL_IDENTIFIER = 5, + GSM0808_IE_PRIORITY = 6, + GSM0808_IE_LAYER_3_HEADER_INFORMATION = 7, + GSM0808_IE_IMSI = 8, + GSM0808_IE_TMSI = 9, + GSM0808_IE_ENCRYPTION_INFORMATION = 10, + GSM0808_IE_CHANNEL_TYPE = 11, + GSM0808_IE_PERIODICITY = 12, + GSM0808_IE_EXTENDED_RESOURCE_INDICATOR = 13, + GSM0808_IE_NUMBER_OF_MSS = 14, + GSM0808_IE_RESERVED_1 = 15, + GSM0808_IE_RESERVED_2 = 16, + GSM0808_IE_RESERVED_3 = 17, + GSM0808_IE_CLASSMARK_INFORMATION_T2 = 18, + GSM0808_IE_CLASSMARK_INFORMATION_T3 = 19, + GSM0808_IE_INTERFERENCE_BAND_TO_USE = 20, + GSM0808_IE_RR_CAUSE = 21, + GSM0808_IE_RESERVED_4 = 22, + GSM0808_IE_LAYER_3_INFORMATION = 23, + GSM0808_IE_DLCI = 24, + GSM0808_IE_DOWNLINK_DTX_FLAG = 25, + GSM0808_IE_CELL_IDENTIFIER_LIST = 26, + GSM0808_IE_RESPONSE_RQST = 27, + GSM0808_IE_RESOURCE_INDICATION_METHOD = 28, + GSM0808_IE_CLASSMARK_INFORMATION_TYPE_1 = 29, + GSM0808_IE_CIRCUIT_IDENTITY_CODE_LIST = 30, + GSM0808_IE_DIAGNOSTIC = 31, + GSM0808_IE_LAYER_3_MESSAGE_CONTENTS = 32, + GSM0808_IE_CHOSEN_CHANNEL = 33, + GSM0808_IE_TOTAL_RESOURCE_ACCESSIBLE = 34, + GSM0808_IE_CIPHER_RESPONSE_MODE = 35, + GSM0808_IE_CHANNEL_NEEDED = 36, + GSM0808_IE_TRACE_TYPE = 37, + GSM0808_IE_TRIGGERID = 38, + GSM0808_IE_TRACE_REFERENCE = 39, + GSM0808_IE_TRANSACTIONID = 40, + GSM0808_IE_MOBILE_IDENTITY = 41, + GSM0808_IE_OMCID = 42, + GSM0808_IE_FORWARD_INDICATOR = 43, + GSM0808_IE_CHOSEN_ENCR_ALG = 44, + GSM0808_IE_CIRCUIT_POOL = 45, + GSM0808_IE_CIRCUIT_POOL_LIST = 46, + GSM0808_IE_TIME_INDICATION = 47, + GSM0808_IE_RESOURCE_SITUATION = 48, + GSM0808_IE_CURRENT_CHANNEL_TYPE_1 = 49, + GSM0808_IE_QUEUEING_INDICATOR = 50, + GSM0808_IE_SPEECH_VERSION = 64, + GSM0808_IE_ASSIGNMENT_REQUIREMENT = 51, + GSM0808_IE_TALKER_FLAG = 53, + GSM0808_IE_CONNECTION_RELEASE_RQSTED = 54, + GSM0808_IE_GROUP_CALL_REFERENCE = 55, + GSM0808_IE_EMLPP_PRIORITY = 56, + GSM0808_IE_CONFIG_EVO_INDI = 57, + GSM0808_IE_OLD_BSS_TO_NEW_BSS_INFORMATION = 58, + GSM0808_IE_LSA_IDENTIFIER = 59, + GSM0808_IE_LSA_IDENTIFIER_LIST = 60, + GSM0808_IE_LSA_INFORMATION = 61, + GSM0808_IE_LCS_QOS = 62, + GSM0808_IE_LSA_ACCESS_CTRL_SUPPR = 63, + GSM0808_IE_LCS_PRIORITY = 67, + GSM0808_IE_LOCATION_TYPE = 68, + GSM0808_IE_LOCATION_ESTIMATE = 69, + GSM0808_IE_POSITIONING_DATA = 70, + GSM0808_IE_LCS_CAUSE = 71, + GSM0808_IE_LCS_CLIENT_TYPE = 72, + GSM0808_IE_APDU = 73, + GSM0808_IE_NETWORK_ELEMENT_IDENTITY = 74, + GSM0808_IE_GPS_ASSISTANCE_DATA = 75, + GSM0808_IE_DECIPHERING_KEYS = 76, + GSM0808_IE_RETURN_ERROR_RQST = 77, + GSM0808_IE_RETURN_ERROR_CAUSE = 78, + GSM0808_IE_SEGMENTATION = 79, + GSM0808_IE_SERVICE_HANDOVER = 80, + GSM0808_IE_SOURCE_RNC_TO_TARGET_RNC_TRANSPARENT_UMTS = 81, + GSM0808_IE_SOURCE_RNC_TO_TARGET_RNC_TRANSPARENT_CDMA2000= 82, + GSM0808_IE_RESERVED_5 = 65, + GSM0808_IE_RESERVED_6 = 66, +}; + +enum gsm0808_cause { + GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE = 0, + GSM0808_CAUSE_RADIO_INTERFACE_FAILURE = 1, + GSM0808_CAUSE_UPLINK_QUALITY = 2, + GSM0808_CAUSE_UPLINK_STRENGTH = 3, + GSM0808_CAUSE_DOWNLINK_QUALITY = 4, + GSM0808_CAUSE_DOWNLINK_STRENGTH = 5, + GSM0808_CAUSE_DISTANCE = 6, + GSM0808_CAUSE_O_AND_M_INTERVENTION = 7, + GSM0808_CAUSE_RESPONSE_TO_MSC_INVOCATION = 8, + GSM0808_CAUSE_CALL_CONTROL = 9, + GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION = 10, + GSM0808_CAUSE_HANDOVER_SUCCESSFUL = 11, + GSM0808_CAUSE_BETTER_CELL = 12, + GSM0808_CAUSE_DIRECTED_RETRY = 13, + GSM0808_CAUSE_JOINED_GROUP_CALL_CHANNEL = 14, + GSM0808_CAUSE_TRAFFIC = 15, + GSM0808_CAUSE_EQUIPMENT_FAILURE = 32, + GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE = 33, + GSM0808_CAUSE_RQSTED_TERRESTRIAL_RESOURCE_UNAVAILABLE = 34, + GSM0808_CAUSE_CCCH_OVERLOAD = 35, + GSM0808_CAUSE_PROCESSOR_OVERLOAD = 36, + GSM0808_CAUSE_BSS_NOT_EQUIPPED = 37, + GSM0808_CAUSE_MS_NOT_EQUIPPED = 38, + GSM0808_CAUSE_INVALID_CELL = 39, + GSM0808_CAUSE_TRAFFIC_LOAD = 40, + GSM0808_CAUSE_PREEMPTION = 41, + GSM0808_CAUSE_RQSTED_TRANSCODING_RATE_ADAPTION_UNAVAILABLE = 48, + GSM0808_CAUSE_CIRCUIT_POOL_MISMATCH = 49, + GSM0808_CAUSE_SWITCH_CIRCUIT_POOL = 50, + GSM0808_CAUSE_RQSTED_SPEECH_VERSION_UNAVAILABLE = 51, + GSM0808_CAUSE_LSA_NOT_ALLOWED = 52, + GSM0808_CAUSE_CIPHERING_ALGORITHM_NOT_SUPPORTED = 64, + GSM0808_CAUSE_TERRESTRIAL_CIRCUIT_ALREADY_ALLOCATED = 80, + GSM0808_CAUSE_INVALID_MESSAGE_CONTENTS = 81, + GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING = 82, + GSM0808_CAUSE_INCORRECT_VALUE = 83, + GSM0808_CAUSE_UNKNOWN_MESSAGE_TYPE = 84, + GSM0808_CAUSE_UNKNOWN_INFORMATION_ELEMENT = 85, + GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC = 96, +}; + +/* GSM 08.08 3.2.2.11 Channel Type */ +enum gsm0808_chan_indicator { + GSM0808_CHAN_SPEECH = 1, + GSM0808_CHAN_DATA = 2, + GSM0808_CHAN_SIGN = 3, +}; + +enum gsm0808_chan_rate_type_data { + GSM0808_DATA_FULL_BM = 0x8, + GSM0808_DATA_HALF_LM = 0x9, + GSM0808_DATA_FULL_RPREF = 0xa, + GSM0808_DATA_HALF_PREF = 0xb, + GSM0808_DATA_FULL_PREF_NO_CHANGE = 0x1a, + GSM0808_DATA_HALF_PREF_NO_CHANGE = 0x1b, + GSM0808_DATA_MULTI_MASK = 0x20, + GSM0808_DATA_MULTI_MASK_NO_CHANGE = 0x30, +}; + +enum gsm0808_chan_rate_type_speech { + GSM0808_SPEECH_FULL_BM = 0x8, + GSM0808_SPEECH_HALF_LM = 0x9, + GSM0808_SPEECH_FULL_PREF= 0xa, + GSM0808_SPEECH_HALF_PREF= 0xb, + GSM0808_SPEECH_FULL_PREF_NO_CHANGE = 0x1a, + GSM0808_SPEECH_HALF_PREF_NO_CHANGE = 0x1b, + GSM0808_SPEECH_PERM = 0xf, + GSM0808_SPEECH_PERM_NO_CHANGE = 0x1f, +}; + +enum gsm0808_permitted_speech { + GSM0808_PERM_FR1 = 0x01, + GSM0808_PERM_FR2 = 0x11, + GSM0808_PERM_FR3 = 0x21, + GSM0808_PERM_HR1 = GSM0808_PERM_FR1 | 0x4, + GSM0808_PERM_HR2 = GSM0808_PERM_FR2 | 0x4, + GSM0808_PERM_HR3 = GSM0808_PERM_FR3 | 0x4, +}; + +int bssmap_rcvmsg_dt1(struct sccp_connection *conn, struct msgb *msg, unsigned int length); +int bssmap_rcvmsg_udt(struct gsm_network *net, struct msgb *msg, unsigned int length); + +struct msgb *bssmap_create_layer3(struct msgb *msg); +struct msgb *bssmap_create_reset(void); +struct msgb *bssmap_create_clear_complete(void); +struct msgb *bssmap_create_cipher_complete(struct msgb *layer3); +struct msgb *bssmap_create_cipher_reject(u_int8_t cause); +struct msgb *bssmap_create_sapi_reject(u_int8_t link_id); +struct msgb *bssmap_create_assignment_completed(struct gsm_lchan *lchan, u_int8_t rr_cause); +struct msgb *bssmap_create_assignment_failure(u_int8_t cause, u_int8_t *rr_cause); +struct msgb *bssmap_create_classmark_update(const u_int8_t *classmark, u_int8_t length); + +void gsm0808_send_assignment_failure(struct gsm_lchan *l, u_int8_t cause, u_int8_t *rr_value); +void gsm0808_send_assignment_compl(struct gsm_lchan *l, u_int8_t rr_value); + +int dtap_rcvmsg(struct gsm_lchan *lchan, struct msgb *msg, unsigned int length); +struct msgb *dtap_create_msg(struct msgb *msg_l3, u_int8_t link_id); + +void bsc_queue_connection_write(struct sccp_connection *conn, struct msgb *msg); +void bsc_free_queued(struct sccp_connection *conn); +void bsc_send_queued(struct sccp_connection *conn); + +void bts_queue_send(struct msgb *msg, int link_id); +void bts_send_queued(struct bss_sccp_connection_data*); +void bts_free_queued(struct bss_sccp_connection_data*); +void bts_unblock_queue(struct bss_sccp_connection_data*); + +const struct tlv_definition *gsm0808_att_tlvdef(); + +#endif diff --git a/include/openbsc_nat/tlv.h b/include/openbsc_nat/tlv.h new file mode 100644 index 0000000..0fa8e40 --- /dev/null +++ b/include/openbsc_nat/tlv.h @@ -0,0 +1,234 @@ +#ifndef _TLV_H +#define _TLV_H + +#include <sys/types.h> +#include <string.h> + +#include <laf0rge1/msgb.h> + +/* Terminology / wording + tag length value (in bits) + + V - - 8 + LV - 8 N * 8 + TLV 8 8 N * 8 + TL16V 8 16 N * 8 + TLV16 8 8 N * 16 + TvLV 8 8/16 N * 8 + +*/ + +#define LV_GROSS_LEN(x) (x+1) +#define TLV_GROSS_LEN(x) (x+2) +#define TLV16_GROSS_LEN(x) ((2*x)+2) +#define TL16V_GROSS_LEN(x) (x+3) +#define L16TV_GROSS_LEN(x) (x+3) + +#define TVLV_MAX_ONEBYTE 0x7f + +static inline u_int16_t TVLV_GROSS_LEN(u_int16_t len) +{ + if (len <= TVLV_MAX_ONEBYTE) + return TLV_GROSS_LEN(len); + else + return TL16V_GROSS_LEN(len); +} + +/* TLV generation */ + +static inline u_int8_t *lv_put(u_int8_t *buf, u_int8_t len, + const u_int8_t *val) +{ + *buf++ = len; + memcpy(buf, val, len); + return buf + len; +} + +static inline u_int8_t *tlv_put(u_int8_t *buf, u_int8_t tag, u_int8_t len, + const u_int8_t *val) +{ + *buf++ = tag; + *buf++ = len; + memcpy(buf, val, len); + return buf + len; +} + +static inline u_int8_t *tlv16_put(u_int8_t *buf, u_int8_t tag, u_int8_t len, + const u_int16_t *val) +{ + *buf++ = tag; + *buf++ = len; + memcpy(buf, val, len*2); + return buf + len*2; +} + +static inline u_int8_t *tl16v_put(u_int8_t *buf, u_int8_t tag, u_int16_t len, + const u_int8_t *val) +{ + *buf++ = tag; + *buf++ = len >> 8; + *buf++ = len & 0xff; + memcpy(buf, val, len); + return buf + len*2; +} + +static inline u_int8_t *tvlv_put(u_int8_t *buf, u_int8_t tag, u_int16_t len, + const u_int8_t *val) +{ + u_int8_t *ret; + + if (len <= TVLV_MAX_ONEBYTE) { + ret = tlv_put(buf, tag, len, val); + buf[1] |= 0x80; + } else + ret = tl16v_put(buf, tag, len, val); + + return ret; +} + +static inline u_int8_t *msgb_tlv16_put(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int16_t *val) +{ + u_int8_t *buf = msgb_put(msg, TLV16_GROSS_LEN(len)); + return tlv16_put(buf, tag, len, val); +} + +static inline u_int8_t *msgb_tl16v_put(struct msgb *msg, u_int8_t tag, u_int16_t len, + const u_int8_t *val) +{ + u_int8_t *buf = msgb_put(msg, TL16V_GROSS_LEN(len)); + return tl16v_put(buf, tag, len, val); +} + +static inline u_int8_t *msgb_tvlv_put(struct msgb *msg, u_int8_t tag, u_int16_t len, + const u_int8_t *val) +{ + u_int8_t *buf = msgb_put(msg, TVLV_GROSS_LEN(len)); + return tvlv_put(buf, tag, len, val); +} + +static inline u_int8_t *msgb_l16tv_put(struct msgb *msg, u_int16_t len, u_int8_t tag, + const u_int8_t *val) +{ + u_int8_t *buf = msgb_put(msg, L16TV_GROSS_LEN(len)); + + *buf++ = len >> 8; + *buf++ = len & 0xff; + *buf++ = tag; + memcpy(buf, val, len); + return buf + len; +} + +static inline u_int8_t *v_put(u_int8_t *buf, u_int8_t val) +{ + *buf++ = val; + return buf; +} + +static inline u_int8_t *tv_put(u_int8_t *buf, u_int8_t tag, + u_int8_t val) +{ + *buf++ = tag; + *buf++ = val; + return buf; +} + +/* 'val' is still in host byte order! */ +static inline u_int8_t *tv16_put(u_int8_t *buf, u_int8_t tag, + u_int16_t val) +{ + *buf++ = tag; + *buf++ = val >> 8; + *buf++ = val & 0xff; + return buf; +} + +static inline u_int8_t *msgb_lv_put(struct msgb *msg, u_int8_t len, const u_int8_t *val) +{ + u_int8_t *buf = msgb_put(msg, LV_GROSS_LEN(len)); + return lv_put(buf, len, val); +} + +static inline u_int8_t *msgb_tlv_put(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int8_t *val) +{ + u_int8_t *buf = msgb_put(msg, TLV_GROSS_LEN(len)); + return tlv_put(buf, tag, len, val); +} + +static inline u_int8_t *msgb_tv_put(struct msgb *msg, u_int8_t tag, u_int8_t val) +{ + u_int8_t *buf = msgb_put(msg, 2); + return tv_put(buf, tag, val); +} + +static inline u_int8_t *msgb_v_put(struct msgb *msg, u_int8_t val) +{ + u_int8_t *buf = msgb_put(msg, 1); + return v_put(buf, val); +} + +static inline u_int8_t *msgb_tv16_put(struct msgb *msg, u_int8_t tag, u_int16_t val) +{ + u_int8_t *buf = msgb_put(msg, 3); + return tv16_put(buf, tag, val); +} + +static inline u_int8_t *msgb_tlv_push(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int8_t *val) +{ + u_int8_t *buf = msgb_push(msg, TLV_GROSS_LEN(len)); + return tlv_put(buf, tag, len, val); +} + +static inline u_int8_t *msgb_tv_push(struct msgb *msg, u_int8_t tag, u_int8_t val) +{ + u_int8_t *buf = msgb_push(msg, 2); + return tv_put(buf, tag, val); +} + +static inline u_int8_t *msgb_tv16_push(struct msgb *msg, u_int8_t tag, u_int16_t val) +{ + u_int8_t *buf = msgb_push(msg, 3); + return tv16_put(buf, tag, val); +} + +/* TLV parsing */ + +struct tlv_p_entry { + u_int16_t len; + const u_int8_t *val; +}; + +enum tlv_type { + TLV_TYPE_FIXED, + TLV_TYPE_T, + TLV_TYPE_TV, + TLV_TYPE_TLV, + TLV_TYPE_TL16V, + TLV_TYPE_TvLV, +}; + +struct tlv_def { + enum tlv_type type; + u_int8_t fixed_len; +}; + +struct tlv_definition { + struct tlv_def def[0xff]; +}; + +struct tlv_parsed { + struct tlv_p_entry lv[0xff]; +}; + +extern struct tlv_definition tvlv_att_def; + +int tlv_parse_one(u_int8_t *o_tag, u_int16_t *o_len, const u_int8_t **o_val, + const struct tlv_definition *def, + const u_int8_t *buf, int buf_len); +int tlv_parse(struct tlv_parsed *dec, const struct tlv_definition *def, + const u_int8_t *buf, int buf_len, u_int8_t lv_tag, u_int8_t lv_tag2); + +#define TLVP_PRESENT(x, y) ((x)->lv[y].val) +#define TLVP_LEN(x, y) (x)->lv[y].len +#define TLVP_VAL(x, y) (x)->lv[y].val + +#endif /* _TLV_H */ diff --git a/include/snmp_mtp.h b/include/snmp_mtp.h new file mode 100644 index 0000000..6a70a5c --- /dev/null +++ b/include/snmp_mtp.h @@ -0,0 +1,39 @@ +/* + * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org> + * (C) 2010 by On-Waves + * All Rights Reserved + * + * 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. + * + */ +#ifndef snmp_mtp_h +#define snmp_mtp_h + +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/utilities.h> +#include <net-snmp/net-snmp-includes.h> + +struct snmp_mtp_session { + netsnmp_session session, *ss; +}; + +void snmp_mtp_start_c7_datalink(struct snmp_mtp_session *, int link_id); +void snmp_mtp_stop_c7_datalink(struct snmp_mtp_session *, int link_id); + +struct snmp_mtp_session *snmp_mtp_session_create(char *host); +void snmp_mtp_deactivate(struct snmp_mtp_session *); +void snmp_mtp_activate(struct snmp_mtp_session *); + +#endif diff --git a/include/thread.h b/include/thread.h new file mode 100644 index 0000000..f23cae7 --- /dev/null +++ b/include/thread.h @@ -0,0 +1,59 @@ +/* + * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org> + * (C) 2010 by On-Waves + * All Rights Reserved + * + * 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. + * + */ +#ifndef thread_h +#define thread_h + +#include <laf0rge1/linuxlist.h> +#include <laf0rge1/select.h> + +#include <pthread.h> + +/** + * routines for dealing with threads + */ +struct thread_notifier { + struct bsc_fd bfd; + + int no_write; + int fd[2]; + + pthread_mutex_t guard; + struct llist_head *main_head; + struct llist_head *thread_head; + + struct llist_head __head1; + struct llist_head __head2; +}; + +struct thread_notifier *thread_notifier_alloc(); + +/** + * atomically swap two llist heads. This can be used + * to have two queues of data and then swap them for + * processing. + */ +void thread_swap(struct thread_notifier *); + +void thread_safe_add(struct thread_notifier *, struct llist_head *_new); + +void thread_init(void); + +#endif diff --git a/include/udp_input.h b/include/udp_input.h new file mode 100644 index 0000000..1715733 --- /dev/null +++ b/include/udp_input.h @@ -0,0 +1,52 @@ +/* + * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org> + * (C) 2010 by On-Waves + * All Rights Reserved + * + * 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. + * + */ +/* UDP Input for the SNMP On-Waves packets */ + +#ifndef c7_udp_input_h +#define c7_udp_input_h + +#include <stdint.h> +#include "write_queue.h" + +#define UDP_FORMAT_SIMPLE_UDP 2 +#define UDP_FORMAT_SIMPLE_TCP 3 + +#define UDP_DATA_MSU_PRIO_0 0 +#define UDP_DATA_MSU_PRIO_1 1 +#define UDP_DATA_MSU_PRIO_2 2 +#define UDP_DATA_MSU_PRIO_3 3 +#define UDP_DATA_RETR_PRIO_0 16 +#define UDP_DATA_RETR_PRIO_1 17 +#define UDP_DATA_RETR_PRIO_2 18 +#define UDP_DATA_RETR_PRIO_3 19 +#define UDP_DATA_RETR_COMPL 32 +#define UDP_DATA_RETR_IMPOS 33 + +struct udp_data_hdr { + uint8_t format_type; + uint8_t data_type; + uint16_t data_link_index; + uint32_t user_context; + uint32_t data_length; + uint8_t data[0]; +} __attribute__((packed)); + +#endif diff --git a/include/write_queue.h b/include/write_queue.h new file mode 100644 index 0000000..45191e0 --- /dev/null +++ b/include/write_queue.h @@ -0,0 +1,48 @@ +/* + * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org> + * (C) 2010 by On-Waves + * All Rights Reserved + * + * 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. + * + */ +/* Generic write queue implementation */ +#ifndef write_queue_h +#define write_queue_h + +#include <laf0rge1/select.h> +#include <laf0rge1/msgb.h> + +struct write_queue { + struct bsc_fd bfd; + unsigned int max_length; + unsigned int current_length; + + unsigned int paused; + + struct llist_head msg_queue; + + int (*read_cb)(struct bsc_fd *fd); + int (*write_cb)(struct bsc_fd *fd, struct msgb *msg); +}; + +void write_queue_init(struct write_queue *queue, int max_length); +int write_queue_enqueue(struct write_queue *queue, struct msgb *data); +int write_queue_bfd_cb(struct bsc_fd *fd, unsigned int what); + +void write_queue_pause(struct write_queue *queue); +void write_queue_unpause(struct write_queue *queue); + +#endif |