···2323 and get more informations about this module and it's usage.2424 If unsure, say 'N'.25252626- source "drivers/isdn/hardware/mISDN/Kconfig"2626+config MISDN_L1OIP2727+ tristate "ISDN over IP tunnel"2828+ depends on MISDN2929+ help3030+ Enable support for ISDN over IP tunnel.3131+3232+ It features:3333+ - dynamic IP exchange, if one or both peers have dynamic IPs3434+ - BRI (S0) and PRI (S2M) interface3535+ - layer 1 control via network keepalive frames3636+ - direct tunneling of physical interface via IP3737+3838+ NOTE: This protocol is called 'Layer 1 over IP' and is not3939+ compatible with ISDNoIP (Agfeo) or TDMoIP. Protocol description is4040+ provided in the source code.4141+4242+source "drivers/isdn/hardware/mISDN/Kconfig"4343+2744endif #MISDN
···11+/*22+ * see notice in l1oip.c33+ */44+55+/* debugging */66+#define DEBUG_L1OIP_INIT 0x0001000077+#define DEBUG_L1OIP_SOCKET 0x0002000088+#define DEBUG_L1OIP_MGR 0x0004000099+#define DEBUG_L1OIP_MSG 0x000800001010+1111+/* enable to disorder received bchannels by sequence 2143658798... */1212+/*1313+#define REORDER_DEBUG1414+*/1515+1616+/* frames */1717+#define L1OIP_MAX_LEN 2048 /* max packet size form l2 */1818+#define L1OIP_MAX_PERFRAME 1400 /* max data size in one frame */1919+2020+2121+/* timers */2222+#define L1OIP_KEEPALIVE 152323+#define L1OIP_TIMEOUT 652424+2525+2626+/* socket */2727+#define L1OIP_DEFAULTPORT 9312828+2929+3030+/* channel structure */3131+struct l1oip_chan {3232+ struct dchannel *dch;3333+ struct bchannel *bch;3434+ u32 tx_counter; /* counts xmit bytes/packets */3535+ u32 rx_counter; /* counts recv bytes/packets */3636+ u32 codecstate; /* used by codec to save data */3737+#ifdef REORDER_DEBUG3838+ int disorder_flag;3939+ struct sk_buff *disorder_skb;4040+ u32 disorder_cnt;4141+#endif4242+};4343+4444+4545+/* card structure */4646+struct l1oip {4747+ struct list_head list;4848+4949+ /* card */5050+ int registered; /* if registered with mISDN */5151+ char name[MISDN_MAX_IDLEN];5252+ int idx; /* card index */5353+ int pri; /* 1=pri, 0=bri */5454+ int d_idx; /* current dchannel number */5555+ int b_num; /* number of bchannels */5656+ u32 id; /* id of connection */5757+ int ondemand; /* if transmis. is on demand */5858+ int bundle; /* bundle channels in one frm */5959+ int codec; /* codec to use for transmis. */6060+ int limit; /* limit number of bchannels */6161+6262+ /* timer */6363+ struct timer_list keep_tl;6464+ struct timer_list timeout_tl;6565+ int timeout_on;6666+ struct work_struct workq;6767+6868+ /* socket */6969+ struct socket *socket; /* if set, socket is created */7070+ struct completion socket_complete;/* completion of sock thread */7171+ struct task_struct *socket_thread;7272+ spinlock_t socket_lock; /* access sock outside thread */7373+ u32 remoteip; /* if all set, ip is assigned */7474+ u16 localport; /* must always be set */7575+ u16 remoteport; /* must always be set */7676+ struct sockaddr_in sin_local; /* local socket name */7777+ struct sockaddr_in sin_remote; /* remote socket name */7878+ struct msghdr sendmsg; /* ip message to send */7979+ struct iovec sendiov; /* iov for message */8080+8181+ /* frame */8282+ struct l1oip_chan chan[128]; /* channel instances */8383+};8484+8585+extern int l1oip_law_to_4bit(u8 *data, int len, u8 *result, u32 *state);8686+extern int l1oip_4bit_to_law(u8 *data, int len, u8 *result);8787+extern int l1oip_alaw_to_ulaw(u8 *data, int len, u8 *result);8888+extern int l1oip_ulaw_to_alaw(u8 *data, int len, u8 *result);8989+extern void l1oip_4bit_free(void);9090+extern int l1oip_4bit_alloc(int ulaw);9191+
+374
drivers/isdn/mISDN/l1oip_codec.c
···11+/*22+33+ * l1oip_codec.c generic codec using lookup table44+ * -> conversion from a-Law to u-Law55+ * -> conversion from u-Law to a-Law66+ * -> compression by reducing the number of sample resolution to 477+ *88+ * NOTE: It is not compatible with any standard codec like ADPCM.99+ *1010+ * Author Andreas Eversberg (jolly@eversberg.eu)1111+ *1212+ * This program is free software; you can redistribute it and/or modify1313+ * it under the terms of the GNU General Public License as published by1414+ * the Free Software Foundation; either version 2, or (at your option)1515+ * any later version.1616+ *1717+ * This program is distributed in the hope that it will be useful,1818+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1919+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the2020+ * GNU General Public License for more details.2121+ *2222+ * You should have received a copy of the GNU General Public License2323+ * along with this program; if not, write to the Free Software2424+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.2525+2626+ */2727+2828+/*2929+3030+How the codec works:3131+--------------------3232+3333+The volume is increased to increase the dynamic range of the audio signal.3434+Each sample is converted to a-LAW with only 16 steps of level resolution.3535+A pair of two samples are stored in one byte.3636+3737+The first byte is stored in the upper bits, the second byte is stored in the3838+lower bits.3939+4040+To speed up compression and decompression, two lookup tables are formed:4141+4242+- 16 bits index for two samples (law encoded) with 8 bit compressed result.4343+- 8 bits index for one compressed data with 16 bits decompressed result.4444+4545+NOTE: The bytes are handled as they are law-encoded.4646+4747+*/4848+4949+#include <linux/vmalloc.h>5050+#include <linux/mISDNif.h>5151+#include "core.h"5252+5353+/* definitions of codec. don't use calculations, code may run slower. */5454+5555+static u8 *table_com;5656+static u16 *table_dec;5757+5858+5959+/* alaw -> ulaw */6060+static u8 alaw_to_ulaw[256] =6161+{6262+ 0xab, 0x2b, 0xe3, 0x63, 0x8b, 0x0b, 0xc9, 0x49,6363+ 0xba, 0x3a, 0xf6, 0x76, 0x9b, 0x1b, 0xd7, 0x57,6464+ 0xa3, 0x23, 0xdd, 0x5d, 0x83, 0x03, 0xc1, 0x41,6565+ 0xb2, 0x32, 0xeb, 0x6b, 0x93, 0x13, 0xcf, 0x4f,6666+ 0xaf, 0x2f, 0xe7, 0x67, 0x8f, 0x0f, 0xcd, 0x4d,6767+ 0xbe, 0x3e, 0xfe, 0x7e, 0x9f, 0x1f, 0xdb, 0x5b,6868+ 0xa7, 0x27, 0xdf, 0x5f, 0x87, 0x07, 0xc5, 0x45,6969+ 0xb6, 0x36, 0xef, 0x6f, 0x97, 0x17, 0xd3, 0x53,7070+ 0xa9, 0x29, 0xe1, 0x61, 0x89, 0x09, 0xc7, 0x47,7171+ 0xb8, 0x38, 0xf2, 0x72, 0x99, 0x19, 0xd5, 0x55,7272+ 0xa1, 0x21, 0xdc, 0x5c, 0x81, 0x01, 0xbf, 0x3f,7373+ 0xb0, 0x30, 0xe9, 0x69, 0x91, 0x11, 0xce, 0x4e,7474+ 0xad, 0x2d, 0xe5, 0x65, 0x8d, 0x0d, 0xcb, 0x4b,7575+ 0xbc, 0x3c, 0xfa, 0x7a, 0x9d, 0x1d, 0xd9, 0x59,7676+ 0xa5, 0x25, 0xde, 0x5e, 0x85, 0x05, 0xc3, 0x43,7777+ 0xb4, 0x34, 0xed, 0x6d, 0x95, 0x15, 0xd1, 0x51,7878+ 0xac, 0x2c, 0xe4, 0x64, 0x8c, 0x0c, 0xca, 0x4a,7979+ 0xbb, 0x3b, 0xf8, 0x78, 0x9c, 0x1c, 0xd8, 0x58,8080+ 0xa4, 0x24, 0xde, 0x5e, 0x84, 0x04, 0xc2, 0x42,8181+ 0xb3, 0x33, 0xec, 0x6c, 0x94, 0x14, 0xd0, 0x50,8282+ 0xb0, 0x30, 0xe8, 0x68, 0x90, 0x10, 0xce, 0x4e,8383+ 0xbf, 0x3f, 0xfe, 0x7e, 0xa0, 0x20, 0xdc, 0x5c,8484+ 0xa8, 0x28, 0xe0, 0x60, 0x88, 0x08, 0xc6, 0x46,8585+ 0xb7, 0x37, 0xf0, 0x70, 0x98, 0x18, 0xd4, 0x54,8686+ 0xaa, 0x2a, 0xe2, 0x62, 0x8a, 0x0a, 0xc8, 0x48,8787+ 0xb9, 0x39, 0xf4, 0x74, 0x9a, 0x1a, 0xd6, 0x56,8888+ 0xa2, 0x22, 0xdd, 0x5d, 0x82, 0x02, 0xc0, 0x40,8989+ 0xb1, 0x31, 0xea, 0x6a, 0x92, 0x12, 0xcf, 0x4f,9090+ 0xae, 0x2e, 0xe6, 0x66, 0x8e, 0x0e, 0xcc, 0x4c,9191+ 0xbd, 0x3d, 0xfc, 0x7c, 0x9e, 0x1e, 0xda, 0x5a,9292+ 0xa6, 0x26, 0xdf, 0x5f, 0x86, 0x06, 0xc4, 0x44,9393+ 0xb5, 0x35, 0xee, 0x6e, 0x96, 0x16, 0xd2, 0x529494+};9595+9696+/* ulaw -> alaw */9797+static u8 ulaw_to_alaw[256] =9898+{9999+ 0xab, 0x55, 0xd5, 0x15, 0x95, 0x75, 0xf5, 0x35,100100+ 0xb5, 0x45, 0xc5, 0x05, 0x85, 0x65, 0xe5, 0x25,101101+ 0xa5, 0x5d, 0xdd, 0x1d, 0x9d, 0x7d, 0xfd, 0x3d,102102+ 0xbd, 0x4d, 0xcd, 0x0d, 0x8d, 0x6d, 0xed, 0x2d,103103+ 0xad, 0x51, 0xd1, 0x11, 0x91, 0x71, 0xf1, 0x31,104104+ 0xb1, 0x41, 0xc1, 0x01, 0x81, 0x61, 0xe1, 0x21,105105+ 0x59, 0xd9, 0x19, 0x99, 0x79, 0xf9, 0x39, 0xb9,106106+ 0x49, 0xc9, 0x09, 0x89, 0x69, 0xe9, 0x29, 0xa9,107107+ 0xd7, 0x17, 0x97, 0x77, 0xf7, 0x37, 0xb7, 0x47,108108+ 0xc7, 0x07, 0x87, 0x67, 0xe7, 0x27, 0xa7, 0xdf,109109+ 0x9f, 0x7f, 0xff, 0x3f, 0xbf, 0x4f, 0xcf, 0x0f,110110+ 0x8f, 0x6f, 0xef, 0x2f, 0x53, 0x13, 0x73, 0x33,111111+ 0xb3, 0x43, 0xc3, 0x03, 0x83, 0x63, 0xe3, 0x23,112112+ 0xa3, 0x5b, 0xdb, 0x1b, 0x9b, 0x7b, 0xfb, 0x3b,113113+ 0xbb, 0xbb, 0x4b, 0x4b, 0xcb, 0xcb, 0x0b, 0x0b,114114+ 0x8b, 0x8b, 0x6b, 0x6b, 0xeb, 0xeb, 0x2b, 0x2b,115115+ 0xab, 0x54, 0xd4, 0x14, 0x94, 0x74, 0xf4, 0x34,116116+ 0xb4, 0x44, 0xc4, 0x04, 0x84, 0x64, 0xe4, 0x24,117117+ 0xa4, 0x5c, 0xdc, 0x1c, 0x9c, 0x7c, 0xfc, 0x3c,118118+ 0xbc, 0x4c, 0xcc, 0x0c, 0x8c, 0x6c, 0xec, 0x2c,119119+ 0xac, 0x50, 0xd0, 0x10, 0x90, 0x70, 0xf0, 0x30,120120+ 0xb0, 0x40, 0xc0, 0x00, 0x80, 0x60, 0xe0, 0x20,121121+ 0x58, 0xd8, 0x18, 0x98, 0x78, 0xf8, 0x38, 0xb8,122122+ 0x48, 0xc8, 0x08, 0x88, 0x68, 0xe8, 0x28, 0xa8,123123+ 0xd6, 0x16, 0x96, 0x76, 0xf6, 0x36, 0xb6, 0x46,124124+ 0xc6, 0x06, 0x86, 0x66, 0xe6, 0x26, 0xa6, 0xde,125125+ 0x9e, 0x7e, 0xfe, 0x3e, 0xbe, 0x4e, 0xce, 0x0e,126126+ 0x8e, 0x6e, 0xee, 0x2e, 0x52, 0x12, 0x72, 0x32,127127+ 0xb2, 0x42, 0xc2, 0x02, 0x82, 0x62, 0xe2, 0x22,128128+ 0xa2, 0x5a, 0xda, 0x1a, 0x9a, 0x7a, 0xfa, 0x3a,129129+ 0xba, 0xba, 0x4a, 0x4a, 0xca, 0xca, 0x0a, 0x0a,130130+ 0x8a, 0x8a, 0x6a, 0x6a, 0xea, 0xea, 0x2a, 0x2a131131+};132132+133133+/* alaw -> 4bit compression */134134+static u8 alaw_to_4bit[256] = {135135+ 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,136136+ 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,137137+ 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,138138+ 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,139139+ 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,140140+ 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,141141+ 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,142142+ 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,143143+ 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,144144+ 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,145145+ 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0d, 0x02,146146+ 0x0e, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,147147+ 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,148148+ 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,149149+ 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,150150+ 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,151151+ 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,152152+ 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,153153+ 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,154154+ 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,155155+ 0x0e, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,156156+ 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x01, 0x0a, 0x05,157157+ 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,158158+ 0x0d, 0x02, 0x09, 0x07, 0x0f, 0x00, 0x0b, 0x04,159159+ 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,160160+ 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,161161+ 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,162162+ 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,163163+ 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,164164+ 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,165165+ 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,166166+ 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,167167+};168168+169169+/* 4bit -> alaw decompression */170170+static u8 _4bit_to_alaw[16] = {171171+ 0x5d, 0x51, 0xd9, 0xd7, 0x5f, 0x53, 0xa3, 0x4b,172172+ 0x2a, 0x3a, 0x22, 0x2e, 0x26, 0x56, 0x20, 0x2c,173173+};174174+175175+/* ulaw -> 4bit compression */176176+static u8 ulaw_to_4bit[256] = {177177+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,178178+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,179179+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,180180+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,181181+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,182182+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,183183+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,184184+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,185185+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,186186+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04,187187+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,188188+ 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,189189+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,190190+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,191191+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,192192+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08,193193+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,194194+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,195195+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,196196+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,197197+ 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,198198+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,199199+ 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,200200+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,201201+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,202202+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b,203203+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,204204+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x0a,205205+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,206206+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,207207+ 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,208208+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,209209+};210210+211211+/* 4bit -> ulaw decompression */212212+static u8 _4bit_to_ulaw[16] = {213213+ 0x11, 0x21, 0x31, 0x40, 0x4e, 0x5c, 0x68, 0x71,214214+ 0xfe, 0xef, 0xe7, 0xdb, 0xcd, 0xbf, 0xaf, 0x9f,215215+};216216+217217+218218+/*219219+ * Compresses data to the result buffer220220+ * The result size must be at least half of the input buffer.221221+ * The number of samples also must be even!222222+ */223223+int224224+l1oip_law_to_4bit(u8 *data, int len, u8 *result, u32 *state)225225+{226226+ int ii, i = 0, o = 0;227227+228228+ if (!len)229229+ return 0;230230+231231+ /* send saved byte and first input byte */232232+ if (*state) {233233+ *result++ = table_com[(((*state)<<8)&0xff00) | (*data++)];234234+ len--;235235+ o++;236236+ }237237+238238+ ii = len >> 1;239239+240240+ while (i < ii) {241241+ *result++ = table_com[(data[0]<<8) | (data[1])];242242+ data += 2;243243+ i++;244244+ o++;245245+ }246246+247247+ /* if len has an odd number, we save byte for next call */248248+ if (len & 1)249249+ *state = 0x100 + *data;250250+ else251251+ *state = 0;252252+253253+ return o;254254+}255255+256256+/* Decompress data to the result buffer257257+ * The result size must be the number of sample in packet. (2 * input data)258258+ * The number of samples in the result are even!259259+ */260260+int261261+l1oip_4bit_to_law(u8 *data, int len, u8 *result)262262+{263263+ int i = 0;264264+ u16 r;265265+266266+ while (i < len) {267267+ r = table_dec[*data++];268268+ *result++ = r>>8;269269+ *result++ = r;270270+ i++;271271+ }272272+273273+ return len << 1;274274+}275275+276276+277277+/*278278+ * law conversion279279+ */280280+int281281+l1oip_alaw_to_ulaw(u8 *data, int len, u8 *result)282282+{283283+ int i = 0;284284+285285+ while (i < len) {286286+ *result++ = alaw_to_ulaw[*data++];287287+ i++;288288+ }289289+290290+ return len;291291+}292292+293293+int294294+l1oip_ulaw_to_alaw(u8 *data, int len, u8 *result)295295+{296296+ int i = 0;297297+298298+ while (i < len) {299299+ *result++ = ulaw_to_alaw[*data++];300300+ i++;301301+ }302302+303303+ return len;304304+}305305+306306+307307+/*308308+ * generate/free compression and decompression table309309+ */310310+void311311+l1oip_4bit_free(void)312312+{313313+ if (table_dec)314314+ vfree(table_dec);315315+ if (table_com)316316+ vfree(table_com);317317+ table_com = NULL;318318+ table_dec = NULL;319319+}320320+321321+int322322+l1oip_4bit_alloc(int ulaw)323323+{324324+ int i1, i2, c, sample;325325+326326+ /* in case, it is called again */327327+ if (table_dec)328328+ return 0;329329+330330+ /* alloc conversion tables */331331+ table_com = vmalloc(65536);332332+ table_dec = vmalloc(512);333333+ if (!table_com | !table_dec) {334334+ l1oip_4bit_free();335335+ return -ENOMEM;336336+ }337337+ memset(table_com, 0, 65536);338338+ memset(table_dec, 0, 512);339339+ /* generate compression table */340340+ i1 = 0;341341+ while (i1 < 256) {342342+ if (ulaw)343343+ c = ulaw_to_4bit[i1];344344+ else345345+ c = alaw_to_4bit[i1];346346+ i2 = 0;347347+ while (i2 < 256) {348348+ table_com[(i1<<8) | i2] |= (c<<4);349349+ table_com[(i2<<8) | i1] |= c;350350+ i2++;351351+ }352352+ i1++;353353+ }354354+355355+ /* generate decompression table */356356+ i1 = 0;357357+ while (i1 < 16) {358358+ if (ulaw)359359+ sample = _4bit_to_ulaw[i1];360360+ else361361+ sample = _4bit_to_alaw[i1];362362+ i2 = 0;363363+ while (i2 < 16) {364364+ table_dec[(i1<<4) | i2] |= (sample<<8);365365+ table_dec[(i2<<4) | i1] |= sample;366366+ i2++;367367+ }368368+ i1++;369369+ }370370+371371+ return 0;372372+}373373+374374+
+1518
drivers/isdn/mISDN/l1oip_core.c
···11+/*22+33+ * l1oip.c low level driver for tunneling layer 1 over IP44+ *55+ * NOTE: It is not compatible with TDMoIP nor "ISDN over IP".66+ *77+ * Author Andreas Eversberg (jolly@eversberg.eu)88+ *99+ * This program is free software; you can redistribute it and/or modify1010+ * it under the terms of the GNU General Public License as published by1111+ * the Free Software Foundation; either version 2, or (at your option)1212+ * any later version.1313+ *1414+ * This program is distributed in the hope that it will be useful,1515+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1616+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1717+ * GNU General Public License for more details.1818+ *1919+ * You should have received a copy of the GNU General Public License2020+ * along with this program; if not, write to the Free Software2121+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.2222+ *2323+ */2424+2525+/* module parameters:2626+ * type:2727+ Value 1 = BRI2828+ Value 2 = PRI2929+ Value 3 = BRI (multi channel frame, not supported yet)3030+ Value 4 = PRI (multi channel frame, not supported yet)3131+ A multi channel frame reduces overhead to a single frame for all3232+ b-channels, but increases delay.3333+ (NOTE: Multi channel frames are not implemented yet.)3434+3535+ * codec:3636+ Value 0 = transparent (default)3737+ Value 1 = transfer ALAW3838+ Value 2 = transfer ULAW3939+ Value 3 = transfer generic 4 bit compression.4040+4141+ * ulaw:4242+ 0 = we use a-Law (default)4343+ 1 = we use u-Law4444+4545+ * limit:4646+ limitation of B-channels to control bandwidth (1...126)4747+ BRI: 1 or 24848+ PRI: 1-30, 31-126 (126, because dchannel ist not counted here)4949+ Also limited ressources are used for stack, resulting in less channels.5050+ It is possible to have more channels than 30 in PRI mode, this must5151+ be supported by the application.5252+5353+ * ip:5454+ byte representation of remote ip address (127.0.0.1 -> 127,0,0,1)5555+ If not given or four 0, no remote address is set.5656+ For multiple interfaces, concat ip addresses. (127,0,0,1,127,0,0,1)5757+5858+ * port:5959+ port number (local interface)6060+ If not given or 0, port 931 is used for fist instance, 932 for next...6161+ For multiple interfaces, different ports must be given.6262+6363+ * remoteport:6464+ port number (remote interface)6565+ If not given or 0, remote port equals local port6666+ For multiple interfaces on equal sites, different ports must be given.6767+6868+ * ondemand:6969+ 0 = fixed (always transmit packets, even when remote side timed out)7070+ 1 = on demand (only transmit packets, when remote side is detected)7171+ the default is 07272+ NOTE: ID must also be set for on demand.7373+7474+ * id:7575+ optional value to identify frames. This value must be equal on both7676+ peers and should be random. If omitted or 0, no ID is transmitted.7777+7878+ * debug:7979+ NOTE: only one debug value must be given for all cards8080+ enable debugging (see l1oip.h for debug options)8181+8282+8383+Special mISDN controls:8484+8585+ op = MISDN_CTRL_SETPEER*8686+ p1 = bytes 0-3 : remote IP address in network order (left element first)8787+ p2 = bytes 1-2 : remote port in network order (high byte first)8888+ optional:8989+ p2 = bytes 3-4 : local port in network order (high byte first)9090+9191+ op = MISDN_CTRL_UNSETPEER*9292+9393+ * Use l1oipctrl for comfortable setting or removing ip address.9494+ (Layer 1 Over IP CTRL)9595+9696+9797+L1oIP-Protocol9898+--------------9999+100100+Frame Header:101101+102102+ 7 6 5 4 3 2 1 0103103++---------------+104104+|Ver|T|I|Coding |105105++---------------+106106+| ID byte 3 * |107107++---------------+108108+| ID byte 2 * |109109++---------------+110110+| ID byte 1 * |111111++---------------+112112+| ID byte 0 * |113113++---------------+114114+|M| Channel |115115++---------------+116116+| Length * |117117++---------------+118118+| Time Base MSB |119119++---------------+120120+| Time Base LSB |121121++---------------+122122+| Data.... |123123+124124+...125125+126126+| |127127++---------------+128128+|M| Channel |129129++---------------+130130+| Length * |131131++---------------+132132+| Time Base MSB |133133++---------------+134134+| Time Base LSB |135135++---------------+136136+| Data.... |137137+138138+...139139+140140+141141+* Only included in some cases.142142+143143+- Ver = Version144144+If version is missmatch, the frame must be ignored.145145+146146+- T = Type of interface147147+Must be 0 for S0 or 1 for E1.148148+149149+- I = Id present150150+If bit is set, four ID bytes are included in frame.151151+152152+- ID = Connection ID153153+Additional ID to prevent Denial of Service attacs. Also it prevents hijacking154154+connections with dynamic IP. The ID should be random and must not be 0.155155+156156+- Coding = Type of codec157157+Must be 0 for no transcoding. Also for D-channel and other HDLC frames.158158+ 1 and 2 are reserved for explicitly use of a-LAW or u-LAW codec.159159+ 3 is used for generic table compressor.160160+161161+- M = More channels to come. If this flag is 1, the following byte contains162162+the length of the channel data. After the data block, the next channel will163163+be defined. The flag for the last channel block (or if only one channel is164164+transmitted), must be 0 and no length is given.165165+166166+- Channel = Channel number167167+0 reserved168168+1-3 channel data for S0 (3 is D-channel)169169+1-31 channel data for E1 (16 is D-channel)170170+32-127 channel data for extended E1 (16 is D-channel)171171+172172+- The length is used if the M-flag is 1. It is used to find the next channel173173+inside frame.174174+NOTE: A value of 0 equals 256 bytes of data.175175+ -> For larger data blocks, a single frame must be used.176176+ -> For larger streams, a single frame or multiple blocks with same channel ID177177+ must be used.178178+179179+- Time Base = Timestamp of first sample in frame180180+The "Time Base" is used to rearange packets and to detect packet loss.181181+The 16 bits are sent in network order (MSB first) and count 1/8000 th of a182182+second. This causes a wrap arround each 8,192 seconds. There is no requirement183183+for the initial "Time Base", but 0 should be used for the first packet.184184+In case of HDLC data, this timestamp counts the packet or byte number.185185+186186+187187+Two Timers:188188+189189+After initialisation, a timer of 15 seconds is started. Whenever a packet is190190+transmitted, the timer is reset to 15 seconds again. If the timer expires, an191191+empty packet is transmitted. This keep the connection alive.192192+193193+When a valid packet is received, a timer 65 seconds is started. The interface194194+become ACTIVE. If the timer expires, the interface becomes INACTIVE.195195+196196+197197+Dynamic IP handling:198198+199199+To allow dynamic IP, the ID must be non 0. In this case, any packet with the200200+correct port number and ID will be accepted. If the remote side changes its IP201201+the new IP is used for all transmitted packets until it changes again.202202+203203+204204+On Demand:205205+206206+If the ondemand parameter is given, the remote IP is set to 0 on timeout.207207+This will stop keepalive traffic to remote. If the remote is online again,208208+traffic will continue to the remote address. This is usefull for road warriors.209209+This feature only works with ID set, otherwhise it is highly unsecure.210210+211211+212212+Socket and Thread213213+-----------------214214+215215+The complete socket opening and closing is done by a thread.216216+When the thread opened a socket, the hc->socket descriptor is set. Whenever a217217+packet shall be sent to the socket, the hc->socket must be checked wheter not218218+NULL. To prevent change in socket descriptor, the hc->socket_lock must be used.219219+To change the socket, a recall of l1oip_socket_open() will safely kill the220220+socket process and create a new one.221221+222222+*/223223+224224+#define L1OIP_VERSION 0 /* 0...3 */225225+226226+#include <linux/module.h>227227+#include <linux/delay.h>228228+#include <linux/mISDNif.h>229229+#include <linux/mISDNhw.h>230230+#include <linux/mISDNdsp.h>231231+#include <linux/init.h>232232+#include <linux/in.h>233233+#include <linux/inet.h>234234+#include <linux/workqueue.h>235235+#include <linux/kthread.h>236236+#include <net/sock.h>237237+#include "core.h"238238+#include "l1oip.h"239239+240240+static const char *l1oip_revision = "2.00";241241+242242+static int l1oip_cnt;243243+static spinlock_t l1oip_lock;244244+static struct list_head l1oip_ilist;245245+246246+#define MAX_CARDS 16247247+static u_int type[MAX_CARDS];248248+static u_int codec[MAX_CARDS];249249+static u_int ip[MAX_CARDS*4];250250+static u_int port[MAX_CARDS];251251+static u_int remoteport[MAX_CARDS];252252+static u_int ondemand[MAX_CARDS];253253+static u_int limit[MAX_CARDS];254254+static u_int id[MAX_CARDS];255255+static int debug;256256+static int ulaw;257257+258258+MODULE_AUTHOR("Andreas Eversberg");259259+MODULE_LICENSE("GPL");260260+module_param_array(type, uint, NULL, S_IRUGO | S_IWUSR);261261+module_param_array(codec, uint, NULL, S_IRUGO | S_IWUSR);262262+module_param_array(ip, uint, NULL, S_IRUGO | S_IWUSR);263263+module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR);264264+module_param_array(remoteport, uint, NULL, S_IRUGO | S_IWUSR);265265+module_param_array(ondemand, uint, NULL, S_IRUGO | S_IWUSR);266266+module_param_array(limit, uint, NULL, S_IRUGO | S_IWUSR);267267+module_param_array(id, uint, NULL, S_IRUGO | S_IWUSR);268268+module_param(ulaw, uint, S_IRUGO | S_IWUSR);269269+module_param(debug, uint, S_IRUGO | S_IWUSR);270270+271271+/*272272+ * send a frame via socket, if open and restart timer273273+ */274274+static int275275+l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,276276+ u16 timebase, u8 *buf, int len)277277+{278278+ u8 *p;279279+ int multi = 0;280280+ u8 frame[len+32];281281+ struct socket *socket = NULL;282282+ mm_segment_t oldfs;283283+284284+ if (debug & DEBUG_L1OIP_MSG)285285+ printk(KERN_DEBUG "%s: sending data to socket (len = %d)\n",286286+ __func__, len);287287+288288+ p = frame;289289+290290+ /* restart timer */291291+ if ((int)(hc->keep_tl.expires-jiffies) < 5*HZ) {292292+ del_timer(&hc->keep_tl);293293+ hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE*HZ;294294+ add_timer(&hc->keep_tl);295295+ } else296296+ hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE*HZ;297297+298298+ if (debug & DEBUG_L1OIP_MSG)299299+ printk(KERN_DEBUG "%s: resetting timer\n", __func__);300300+301301+ /* drop if we have no remote ip or port */302302+ if (!hc->sin_remote.sin_addr.s_addr || !hc->sin_remote.sin_port) {303303+ if (debug & DEBUG_L1OIP_MSG)304304+ printk(KERN_DEBUG "%s: dropping frame, because remote "305305+ "IP is not set.\n", __func__);306306+ return len;307307+ }308308+309309+ /* assemble frame */310310+ *p++ = (L1OIP_VERSION<<6) /* version and coding */311311+ | (hc->pri?0x20:0x00) /* type */312312+ | (hc->id?0x10:0x00) /* id */313313+ | localcodec;314314+ if (hc->id) {315315+ *p++ = hc->id>>24; /* id */316316+ *p++ = hc->id>>16;317317+ *p++ = hc->id>>8;318318+ *p++ = hc->id;319319+ }320320+ *p++ = (multi == 1)?0x80:0x00 + channel; /* m-flag, channel */321321+ if (multi == 1)322322+ *p++ = len; /* length */323323+ *p++ = timebase>>8; /* time base */324324+ *p++ = timebase;325325+326326+ if (buf && len) { /* add data to frame */327327+ if (localcodec == 1 && ulaw)328328+ l1oip_ulaw_to_alaw(buf, len, p);329329+ else if (localcodec == 2 && !ulaw)330330+ l1oip_alaw_to_ulaw(buf, len, p);331331+ else if (localcodec == 3)332332+ len = l1oip_law_to_4bit(buf, len, p,333333+ &hc->chan[channel].codecstate);334334+ else335335+ memcpy(p, buf, len);336336+ }337337+ len += p - frame;338338+339339+ /* check for socket in safe condition */340340+ spin_lock(&hc->socket_lock);341341+ if (!hc->socket) {342342+ spin_unlock(&hc->socket_lock);343343+ return 0;344344+ }345345+ /* seize socket */346346+ socket = hc->socket;347347+ hc->socket = NULL;348348+ spin_unlock(&hc->socket_lock);349349+ /* send packet */350350+ if (debug & DEBUG_L1OIP_MSG)351351+ printk(KERN_DEBUG "%s: sending packet to socket (len "352352+ "= %d)\n", __func__, len);353353+ hc->sendiov.iov_base = frame;354354+ hc->sendiov.iov_len = len;355355+ oldfs = get_fs();356356+ set_fs(KERNEL_DS);357357+ len = sock_sendmsg(socket, &hc->sendmsg, len);358358+ set_fs(oldfs);359359+ /* give socket back */360360+ hc->socket = socket; /* no locking required */361361+362362+ return len;363363+}364364+365365+366366+/*367367+ * receive channel data from socket368368+ */369369+static void370370+l1oip_socket_recv(struct l1oip *hc, u8 remotecodec, u8 channel, u16 timebase,371371+ u8 *buf, int len)372372+{373373+ struct sk_buff *nskb;374374+ struct bchannel *bch;375375+ struct dchannel *dch;376376+ u8 *p;377377+ u32 rx_counter;378378+379379+ if (len == 0) {380380+ if (debug & DEBUG_L1OIP_MSG)381381+ printk(KERN_DEBUG "%s: received empty keepalive data, "382382+ "ignoring\n", __func__);383383+ return;384384+ }385385+386386+ if (debug & DEBUG_L1OIP_MSG)387387+ printk(KERN_DEBUG "%s: received data, sending to mISDN (%d)\n",388388+ __func__, len);389389+390390+ if (channel < 1 || channel > 127) {391391+ printk(KERN_WARNING "%s: packet error - channel %d out of "392392+ "range\n", __func__, channel);393393+ return;394394+ }395395+ dch = hc->chan[channel].dch;396396+ bch = hc->chan[channel].bch;397397+ if (!dch && !bch) {398398+ printk(KERN_WARNING "%s: packet error - channel %d not in "399399+ "stack\n", __func__, channel);400400+ return;401401+ }402402+403403+ /* prepare message */404404+ nskb = mI_alloc_skb((remotecodec == 3)?(len<<1):len, GFP_ATOMIC);405405+ if (!nskb) {406406+ printk(KERN_ERR "%s: No mem for skb.\n", __func__);407407+ return;408408+ }409409+ p = skb_put(nskb, (remotecodec == 3)?(len<<1):len);410410+411411+ if (remotecodec == 1 && ulaw)412412+ l1oip_alaw_to_ulaw(buf, len, p);413413+ else if (remotecodec == 2 && !ulaw)414414+ l1oip_ulaw_to_alaw(buf, len, p);415415+ else if (remotecodec == 3)416416+ len = l1oip_4bit_to_law(buf, len, p);417417+ else418418+ memcpy(p, buf, len);419419+420420+ /* send message up */421421+ if (dch && len >= 2) {422422+ dch->rx_skb = nskb;423423+ recv_Dchannel(dch);424424+ }425425+ if (bch) {426426+ /* expand 16 bit sequence number to 32 bit sequence number */427427+ rx_counter = hc->chan[channel].rx_counter;428428+ if (((s16)(timebase - rx_counter)) >= 0) {429429+ /* time has changed forward */430430+ if (timebase >= (rx_counter & 0xffff))431431+ rx_counter =432432+ (rx_counter & 0xffff0000) | timebase;433433+ else434434+ rx_counter = ((rx_counter & 0xffff0000)+0x10000)435435+ | timebase;436436+ } else {437437+ /* time has changed backwards */438438+ if (timebase < (rx_counter & 0xffff))439439+ rx_counter =440440+ (rx_counter & 0xffff0000) | timebase;441441+ else442442+ rx_counter = ((rx_counter & 0xffff0000)-0x10000)443443+ | timebase;444444+ }445445+ hc->chan[channel].rx_counter = rx_counter;446446+447447+#ifdef REORDER_DEBUG448448+ if (hc->chan[channel].disorder_flag) {449449+ struct sk_buff *skb;450450+ int cnt;451451+ skb = hc->chan[channel].disorder_skb;452452+ hc->chan[channel].disorder_skb = nskb;453453+ nskb = skb;454454+ cnt = hc->chan[channel].disorder_cnt;455455+ hc->chan[channel].disorder_cnt = rx_counter;456456+ rx_counter = cnt;457457+ }458458+ hc->chan[channel].disorder_flag ^= 1;459459+ if (nskb)460460+#endif461461+ queue_ch_frame(&bch->ch, PH_DATA_IND, rx_counter, nskb);462462+ }463463+}464464+465465+466466+/*467467+ * parse frame and extract channel data468468+ */469469+static void470470+l1oip_socket_parse(struct l1oip *hc, struct sockaddr_in *sin, u8 *buf, int len)471471+{472472+ u32 id;473473+ u8 channel;474474+ u8 remotecodec;475475+ u16 timebase;476476+ int m, mlen;477477+ int len_start = len; /* initial frame length */478478+ struct dchannel *dch = hc->chan[hc->d_idx].dch;479479+480480+ if (debug & DEBUG_L1OIP_MSG)481481+ printk(KERN_DEBUG "%s: received frame, parsing... (%d)\n",482482+ __func__, len);483483+484484+ /* check lenght */485485+ if (len < 1+1+2) {486486+ printk(KERN_WARNING "%s: packet error - length %d below "487487+ "4 bytes\n", __func__, len);488488+ return;489489+ }490490+491491+ /* check version */492492+ if (((*buf)>>6) != L1OIP_VERSION) {493493+ printk(KERN_WARNING "%s: packet error - unknown version %d\n",494494+ __func__, buf[0]>>6);495495+ return;496496+ }497497+498498+ /* check type */499499+ if (((*buf)&0x20) && !hc->pri) {500500+ printk(KERN_WARNING "%s: packet error - received E1 packet "501501+ "on S0 interface\n", __func__);502502+ return;503503+ }504504+ if (!((*buf)&0x20) && hc->pri) {505505+ printk(KERN_WARNING "%s: packet error - received S0 packet "506506+ "on E1 interface\n", __func__);507507+ return;508508+ }509509+510510+ /* get id flag */511511+ id = (*buf>>4)&1;512512+513513+ /* check coding */514514+ remotecodec = (*buf) & 0x0f;515515+ if (remotecodec > 3) {516516+ printk(KERN_WARNING "%s: packet error - remotecodec %d "517517+ "unsupported\n", __func__, remotecodec);518518+ return;519519+ }520520+ buf++;521521+ len--;522522+523523+ /* check id */524524+ if (id) {525525+ if (!hc->id) {526526+ printk(KERN_WARNING "%s: packet error - packet has id "527527+ "0x%x, but we have not\n", __func__, id);528528+ return;529529+ }530530+ if (len < 4) {531531+ printk(KERN_WARNING "%s: packet error - packet too "532532+ "short for ID value\n", __func__);533533+ return;534534+ }535535+ id = (*buf++) << 24;536536+ id += (*buf++) << 16;537537+ id += (*buf++) << 8;538538+ id += (*buf++);539539+ len -= 4;540540+541541+ if (id != hc->id) {542542+ printk(KERN_WARNING "%s: packet error - ID mismatch, "543543+ "got 0x%x, we 0x%x\n",544544+ __func__, id, hc->id);545545+ return;546546+ }547547+ } else {548548+ if (hc->id) {549549+ printk(KERN_WARNING "%s: packet error - packet has no "550550+ "ID, but we have\n", __func__);551551+ return;552552+ }553553+ }554554+555555+multiframe:556556+ if (len < 1) {557557+ printk(KERN_WARNING "%s: packet error - packet too short, "558558+ "channel expected at position %d.\n",559559+ __func__, len-len_start+1);560560+ return;561561+ }562562+563563+ /* get channel and multiframe flag */564564+ channel = *buf&0x7f;565565+ m = *buf >> 7;566566+ buf++;567567+ len--;568568+569569+ /* check length on multiframe */570570+ if (m) {571571+ if (len < 1) {572572+ printk(KERN_WARNING "%s: packet error - packet too "573573+ "short, length expected at position %d.\n",574574+ __func__, len_start-len-1);575575+ return;576576+ }577577+578578+ mlen = *buf++;579579+ len--;580580+ if (mlen == 0)581581+ mlen = 256;582582+ if (len < mlen+3) {583583+ printk(KERN_WARNING "%s: packet error - length %d at "584584+ "position %d exceeds total length %d.\n",585585+ __func__, mlen, len_start-len-1, len_start);586586+ return;587587+ }588588+ if (len == mlen+3) {589589+ printk(KERN_WARNING "%s: packet error - length %d at "590590+ "position %d will not allow additional "591591+ "packet.\n",592592+ __func__, mlen, len_start-len+1);593593+ return;594594+ }595595+ } else596596+ mlen = len-2; /* single frame, substract timebase */597597+598598+ if (len < 2) {599599+ printk(KERN_WARNING "%s: packet error - packet too short, time "600600+ "base expected at position %d.\n",601601+ __func__, len-len_start+1);602602+ return;603603+ }604604+605605+ /* get time base */606606+ timebase = (*buf++) << 8;607607+ timebase |= (*buf++);608608+ len -= 2;609609+610610+ /* if inactive, we send up a PH_ACTIVATE and activate */611611+ if (!test_bit(FLG_ACTIVE, &dch->Flags)) {612612+ if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))613613+ printk(KERN_DEBUG "%s: interface become active due to "614614+ "received packet\n", __func__);615615+ test_and_set_bit(FLG_ACTIVE, &dch->Flags);616616+ _queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,617617+ NULL, GFP_ATOMIC);618618+ }619619+620620+ /* distribute packet */621621+ l1oip_socket_recv(hc, remotecodec, channel, timebase, buf, mlen);622622+ buf += mlen;623623+ len -= mlen;624624+625625+ /* multiframe */626626+ if (m)627627+ goto multiframe;628628+629629+ /* restart timer */630630+ if ((int)(hc->timeout_tl.expires-jiffies) < 5*HZ || !hc->timeout_on) {631631+ hc->timeout_on = 1;632632+ del_timer(&hc->timeout_tl);633633+ hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT*HZ;634634+ add_timer(&hc->timeout_tl);635635+ } else /* only adjust timer */636636+ hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT*HZ;637637+638638+ /* if ip or source port changes */639639+ if ((hc->sin_remote.sin_addr.s_addr != sin->sin_addr.s_addr)640640+ || (hc->sin_remote.sin_port != sin->sin_port)) {641641+ if (debug & DEBUG_L1OIP_SOCKET)642642+ printk(KERN_DEBUG "%s: remote address changes from "643643+ "0x%08x to 0x%08x (port %d to %d)\n", __func__,644644+ ntohl(hc->sin_remote.sin_addr.s_addr),645645+ ntohl(sin->sin_addr.s_addr),646646+ ntohs(hc->sin_remote.sin_port),647647+ ntohs(sin->sin_port));648648+ hc->sin_remote.sin_addr.s_addr = sin->sin_addr.s_addr;649649+ hc->sin_remote.sin_port = sin->sin_port;650650+ }651651+}652652+653653+654654+/*655655+ * socket stuff656656+ */657657+static int658658+l1oip_socket_thread(void *data)659659+{660660+ struct l1oip *hc = (struct l1oip *)data;661661+ int ret = 0;662662+ struct msghdr msg;663663+ struct iovec iov;664664+ mm_segment_t oldfs;665665+ struct sockaddr_in sin_rx;666666+ unsigned char recvbuf[1500];667667+ int recvlen;668668+ struct socket *socket = NULL;669669+ DECLARE_COMPLETION(wait);670670+671671+ /* make daemon */672672+ allow_signal(SIGTERM);673673+674674+ /* create socket */675675+ if (sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &socket)) {676676+ printk(KERN_ERR "%s: Failed to create socket.\n", __func__);677677+ return -EIO;678678+ }679679+680680+ /* set incoming address */681681+ hc->sin_local.sin_family = AF_INET;682682+ hc->sin_local.sin_addr.s_addr = INADDR_ANY;683683+ hc->sin_local.sin_port = htons((unsigned short)hc->localport);684684+685685+ /* set outgoing address */686686+ hc->sin_remote.sin_family = AF_INET;687687+ hc->sin_remote.sin_addr.s_addr = htonl(hc->remoteip);688688+ hc->sin_remote.sin_port = htons((unsigned short)hc->remoteport);689689+690690+ /* bind to incomming port */691691+ if (socket->ops->bind(socket, (struct sockaddr *)&hc->sin_local,692692+ sizeof(hc->sin_local))) {693693+ printk(KERN_ERR "%s: Failed to bind socket to port %d.\n",694694+ __func__, hc->localport);695695+ ret = -EINVAL;696696+ goto fail;697697+ }698698+699699+ /* check sk */700700+ if (socket->sk == NULL) {701701+ printk(KERN_ERR "%s: socket->sk == NULL\n", __func__);702702+ ret = -EIO;703703+ goto fail;704704+ }705705+706706+ /* build receive message */707707+ msg.msg_name = &sin_rx;708708+ msg.msg_namelen = sizeof(sin_rx);709709+ msg.msg_control = NULL;710710+ msg.msg_controllen = 0;711711+ msg.msg_iov = &iov;712712+ msg.msg_iovlen = 1;713713+714714+ /* build send message */715715+ hc->sendmsg.msg_name = &hc->sin_remote;716716+ hc->sendmsg.msg_namelen = sizeof(hc->sin_remote);717717+ hc->sendmsg.msg_control = NULL;718718+ hc->sendmsg.msg_controllen = 0;719719+ hc->sendmsg.msg_iov = &hc->sendiov;720720+ hc->sendmsg.msg_iovlen = 1;721721+722722+ /* give away socket */723723+ spin_lock(&hc->socket_lock);724724+ hc->socket = socket;725725+ spin_unlock(&hc->socket_lock);726726+727727+ /* read loop */728728+ if (debug & DEBUG_L1OIP_SOCKET)729729+ printk(KERN_DEBUG "%s: socket created and open\n",730730+ __func__);731731+ while (!signal_pending(current)) {732732+ iov.iov_base = recvbuf;733733+ iov.iov_len = sizeof(recvbuf);734734+ oldfs = get_fs();735735+ set_fs(KERNEL_DS);736736+ recvlen = sock_recvmsg(socket, &msg, sizeof(recvbuf), 0);737737+ set_fs(oldfs);738738+ if (recvlen > 0) {739739+ l1oip_socket_parse(hc, &sin_rx, recvbuf, recvlen);740740+ } else {741741+ if (debug & DEBUG_L1OIP_SOCKET)742742+ printk(KERN_WARNING "%s: broken pipe on socket\n",743743+ __func__);744744+ }745745+ }746746+747747+ /* get socket back, check first if in use, maybe by send function */748748+ spin_lock(&hc->socket_lock);749749+ /* if hc->socket is NULL, it is in use until it is given back */750750+ while (!hc->socket) {751751+ spin_unlock(&hc->socket_lock);752752+ schedule_timeout(HZ/10);753753+ spin_lock(&hc->socket_lock);754754+ }755755+ hc->socket = NULL;756756+ spin_unlock(&hc->socket_lock);757757+758758+ if (debug & DEBUG_L1OIP_SOCKET)759759+ printk(KERN_DEBUG "%s: socket thread terminating\n",760760+ __func__);761761+762762+fail:763763+ /* close socket */764764+ if (socket)765765+ sock_release(socket);766766+767767+ /* if we got killed, signal completion */768768+ complete(&hc->socket_complete);769769+ hc->socket_thread = NULL; /* show termination of thread */770770+771771+ if (debug & DEBUG_L1OIP_SOCKET)772772+ printk(KERN_DEBUG "%s: socket thread terminated\n",773773+ __func__);774774+ return ret;775775+}776776+777777+static void778778+l1oip_socket_close(struct l1oip *hc)779779+{780780+ /* kill thread */781781+ if (hc->socket_thread) {782782+ if (debug & DEBUG_L1OIP_SOCKET)783783+ printk(KERN_DEBUG "%s: socket thread exists, "784784+ "killing...\n", __func__);785785+ send_sig(SIGTERM, hc->socket_thread, 0);786786+ wait_for_completion(&hc->socket_complete);787787+ }788788+}789789+790790+static int791791+l1oip_socket_open(struct l1oip *hc)792792+{793793+ /* in case of reopen, we need to close first */794794+ l1oip_socket_close(hc);795795+796796+ init_completion(&hc->socket_complete);797797+798798+ /* create receive process */799799+ hc->socket_thread = kthread_run(l1oip_socket_thread, hc, "l1oip_%s",800800+ hc->name);801801+ if (IS_ERR(hc->socket_thread)) {802802+ int err = PTR_ERR(hc->socket_thread);803803+ printk(KERN_ERR "%s: Failed (%d) to create socket process.\n",804804+ __func__, err);805805+ hc->socket_thread = NULL;806806+ sock_release(hc->socket);807807+ return err;808808+ }809809+ if (debug & DEBUG_L1OIP_SOCKET)810810+ printk(KERN_DEBUG "%s: socket thread created\n", __func__);811811+812812+ return 0;813813+}814814+815815+816816+static void817817+l1oip_send_bh(struct work_struct *work)818818+{819819+ struct l1oip *hc = container_of(work, struct l1oip, workq);820820+821821+ if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))822822+ printk(KERN_DEBUG "%s: keepalive timer expired, sending empty "823823+ "frame on dchannel\n", __func__);824824+825825+ /* send an empty l1oip frame at D-channel */826826+ l1oip_socket_send(hc, 0, hc->d_idx, 0, 0, NULL, 0);827827+}828828+829829+830830+/*831831+ * timer stuff832832+ */833833+static void834834+l1oip_keepalive(void *data)835835+{836836+ struct l1oip *hc = (struct l1oip *)data;837837+838838+ schedule_work(&hc->workq);839839+}840840+841841+static void842842+l1oip_timeout(void *data)843843+{844844+ struct l1oip *hc = (struct l1oip *)data;845845+ struct dchannel *dch = hc->chan[hc->d_idx].dch;846846+847847+ if (debug & DEBUG_L1OIP_MSG)848848+ printk(KERN_DEBUG "%s: timeout timer expired, turn layer one "849849+ "down.\n", __func__);850850+851851+ hc->timeout_on = 0; /* state that timer must be initialized next time */852852+853853+ /* if timeout, we send up a PH_DEACTIVATE and deactivate */854854+ if (test_bit(FLG_ACTIVE, &dch->Flags)) {855855+ if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))856856+ printk(KERN_DEBUG "%s: interface become deactivated "857857+ "due to timeout\n", __func__);858858+ test_and_clear_bit(FLG_ACTIVE, &dch->Flags);859859+ _queue_data(&dch->dev.D, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,860860+ NULL, GFP_ATOMIC);861861+ }862862+863863+ /* if we have ondemand set, we remove ip address */864864+ if (hc->ondemand) {865865+ if (debug & DEBUG_L1OIP_MSG)866866+ printk(KERN_DEBUG "%s: on demand causes ip address to "867867+ "be removed\n", __func__);868868+ hc->sin_remote.sin_addr.s_addr = 0;869869+ }870870+}871871+872872+873873+/*874874+ * message handling875875+ */876876+static int877877+handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)878878+{879879+ struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);880880+ struct dchannel *dch = container_of(dev, struct dchannel, dev);881881+ struct l1oip *hc = dch->hw;882882+ struct mISDNhead *hh = mISDN_HEAD_P(skb);883883+ int ret = -EINVAL;884884+ int l, ll;885885+ unsigned char *p;886886+887887+ switch (hh->prim) {888888+ case PH_DATA_REQ:889889+ if (skb->len < 1) {890890+ printk(KERN_WARNING "%s: skb too small\n",891891+ __func__);892892+ break;893893+ }894894+ if (skb->len > MAX_DFRAME_LEN_L1 || skb->len > L1OIP_MAX_LEN) {895895+ printk(KERN_WARNING "%s: skb too large\n",896896+ __func__);897897+ break;898898+ }899899+ /* send frame */900900+ p = skb->data;901901+ l = skb->len;902902+ while (l) {903903+ ll = (l < L1OIP_MAX_PERFRAME)?l:L1OIP_MAX_PERFRAME;904904+ l1oip_socket_send(hc, 0, dch->slot, 0,905905+ hc->chan[dch->slot].tx_counter++, p, ll);906906+ p += ll;907907+ l -= ll;908908+ }909909+ skb_trim(skb, 0);910910+ queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb);911911+ return 0;912912+ case PH_ACTIVATE_REQ:913913+ if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))914914+ printk(KERN_DEBUG "%s: PH_ACTIVATE channel %d (1..%d)\n"915915+ , __func__, dch->slot, hc->b_num+1);916916+ skb_trim(skb, 0);917917+ if (test_bit(FLG_ACTIVE, &dch->Flags))918918+ queue_ch_frame(ch, PH_ACTIVATE_IND, hh->id, skb);919919+ else920920+ queue_ch_frame(ch, PH_DEACTIVATE_IND, hh->id, skb);921921+ return 0;922922+ case PH_DEACTIVATE_REQ:923923+ if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))924924+ printk(KERN_DEBUG "%s: PH_DEACTIVATE channel %d "925925+ "(1..%d)\n", __func__, dch->slot,926926+ hc->b_num+1);927927+ skb_trim(skb, 0);928928+ if (test_bit(FLG_ACTIVE, &dch->Flags))929929+ queue_ch_frame(ch, PH_ACTIVATE_IND, hh->id, skb);930930+ else931931+ queue_ch_frame(ch, PH_DEACTIVATE_IND, hh->id, skb);932932+ return 0;933933+ }934934+ if (!ret)935935+ dev_kfree_skb(skb);936936+ return ret;937937+}938938+939939+static int940940+channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)941941+{942942+ int ret = 0;943943+ struct l1oip *hc = dch->hw;944944+945945+ switch (cq->op) {946946+ case MISDN_CTRL_GETOP:947947+ cq->op = MISDN_CTRL_SETPEER | MISDN_CTRL_UNSETPEER;948948+ break;949949+ case MISDN_CTRL_SETPEER:950950+ hc->remoteip = (u32)cq->p1;951951+ hc->remoteport = cq->p2 & 0xffff;952952+ hc->localport = cq->p2 >> 16;953953+ if (!hc->remoteport)954954+ hc->remoteport = hc->localport;955955+ if (debug & DEBUG_L1OIP_SOCKET)956956+ printk(KERN_DEBUG "%s: got new ip address from user "957957+ "space.\n", __func__);958958+ l1oip_socket_open(hc);959959+ break;960960+ case MISDN_CTRL_UNSETPEER:961961+ if (debug & DEBUG_L1OIP_SOCKET)962962+ printk(KERN_DEBUG "%s: removing ip address.\n",963963+ __func__);964964+ hc->remoteip = 0;965965+ l1oip_socket_open(hc);966966+ break;967967+ default:968968+ printk(KERN_WARNING "%s: unknown Op %x\n",969969+ __func__, cq->op);970970+ ret = -EINVAL;971971+ break;972972+ }973973+ return ret;974974+}975975+976976+static int977977+open_dchannel(struct l1oip *hc, struct dchannel *dch, struct channel_req *rq)978978+{979979+ if (debug & DEBUG_HW_OPEN)980980+ printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__,981981+ dch->dev.id, __builtin_return_address(0));982982+ if (rq->protocol == ISDN_P_NONE)983983+ return -EINVAL;984984+ if ((dch->dev.D.protocol != ISDN_P_NONE) &&985985+ (dch->dev.D.protocol != rq->protocol)) {986986+ if (debug & DEBUG_HW_OPEN)987987+ printk(KERN_WARNING "%s: change protocol %x to %x\n",988988+ __func__, dch->dev.D.protocol, rq->protocol);989989+ }990990+ if (dch->dev.D.protocol != rq->protocol)991991+ dch->dev.D.protocol = rq->protocol;992992+993993+ if (test_bit(FLG_ACTIVE, &dch->Flags)) {994994+ _queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY,995995+ 0, NULL, GFP_KERNEL);996996+ }997997+ rq->ch = &dch->dev.D;998998+ if (!try_module_get(THIS_MODULE))999999+ printk(KERN_WARNING "%s:cannot get module\n", __func__);10001000+ return 0;10011001+}10021002+10031003+static int10041004+open_bchannel(struct l1oip *hc, struct dchannel *dch, struct channel_req *rq)10051005+{10061006+ struct bchannel *bch;10071007+ int ch;10081008+10091009+ if (!test_bit(rq->adr.channel & 0x1f,10101010+ &dch->dev.channelmap[rq->adr.channel >> 5]))10111011+ return -EINVAL;10121012+ if (rq->protocol == ISDN_P_NONE)10131013+ return -EINVAL;10141014+ ch = rq->adr.channel; /* BRI: 1=B1 2=B2 PRI: 1..15,17.. */10151015+ bch = hc->chan[ch].bch;10161016+ if (!bch) {10171017+ printk(KERN_ERR "%s:internal error ch %d has no bch\n",10181018+ __func__, ch);10191019+ return -EINVAL;10201020+ }10211021+ if (test_and_set_bit(FLG_OPEN, &bch->Flags))10221022+ return -EBUSY; /* b-channel can be only open once */10231023+ bch->ch.protocol = rq->protocol;10241024+ rq->ch = &bch->ch;10251025+ if (!try_module_get(THIS_MODULE))10261026+ printk(KERN_WARNING "%s:cannot get module\n", __func__);10271027+ return 0;10281028+}10291029+10301030+static int10311031+l1oip_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)10321032+{10331033+ struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);10341034+ struct dchannel *dch = container_of(dev, struct dchannel, dev);10351035+ struct l1oip *hc = dch->hw;10361036+ struct channel_req *rq;10371037+ int err = 0;10381038+10391039+ if (dch->debug & DEBUG_HW)10401040+ printk(KERN_DEBUG "%s: cmd:%x %p\n",10411041+ __func__, cmd, arg);10421042+ switch (cmd) {10431043+ case OPEN_CHANNEL:10441044+ rq = arg;10451045+ switch (rq->protocol) {10461046+ case ISDN_P_TE_S0:10471047+ case ISDN_P_NT_S0:10481048+ if (hc->pri) {10491049+ err = -EINVAL;10501050+ break;10511051+ }10521052+ err = open_dchannel(hc, dch, rq);10531053+ break;10541054+ case ISDN_P_TE_E1:10551055+ case ISDN_P_NT_E1:10561056+ if (!hc->pri) {10571057+ err = -EINVAL;10581058+ break;10591059+ }10601060+ err = open_dchannel(hc, dch, rq);10611061+ break;10621062+ default:10631063+ err = open_bchannel(hc, dch, rq);10641064+ }10651065+ break;10661066+ case CLOSE_CHANNEL:10671067+ if (debug & DEBUG_HW_OPEN)10681068+ printk(KERN_DEBUG "%s: dev(%d) close from %p\n",10691069+ __func__, dch->dev.id,10701070+ __builtin_return_address(0));10711071+ module_put(THIS_MODULE);10721072+ break;10731073+ case CONTROL_CHANNEL:10741074+ err = channel_dctrl(dch, arg);10751075+ break;10761076+ default:10771077+ if (dch->debug & DEBUG_HW)10781078+ printk(KERN_DEBUG "%s: unknown command %x\n",10791079+ __func__, cmd);10801080+ err = -EINVAL;10811081+ }10821082+ return err;10831083+}10841084+10851085+static int10861086+handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)10871087+{10881088+ struct bchannel *bch = container_of(ch, struct bchannel, ch);10891089+ struct l1oip *hc = bch->hw;10901090+ int ret = -EINVAL;10911091+ struct mISDNhead *hh = mISDN_HEAD_P(skb);10921092+ int l, ll, i;10931093+ unsigned char *p;10941094+10951095+ switch (hh->prim) {10961096+ case PH_DATA_REQ:10971097+ if (skb->len <= 0) {10981098+ printk(KERN_WARNING "%s: skb too small\n",10991099+ __func__);11001100+ break;11011101+ }11021102+ if (skb->len > MAX_DFRAME_LEN_L1 || skb->len > L1OIP_MAX_LEN) {11031103+ printk(KERN_WARNING "%s: skb too large\n",11041104+ __func__);11051105+ break;11061106+ }11071107+ /* check for AIS / ulaw-silence */11081108+ p = skb->data;11091109+ l = skb->len;11101110+ for (i = 0; i < l; i++) {11111111+ if (*p++ != 0xff)11121112+ break;11131113+ }11141114+ if (i == l) {11151115+ if (debug & DEBUG_L1OIP_MSG)11161116+ printk(KERN_DEBUG "%s: got AIS, not sending, "11171117+ "but counting\n", __func__);11181118+ hc->chan[bch->slot].tx_counter += l;11191119+ skb_trim(skb, 0);11201120+ queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb);11211121+ return 0;11221122+ }11231123+ /* check for silence */11241124+ p = skb->data;11251125+ l = skb->len;11261126+ for (i = 0; i < l; i++) {11271127+ if (*p++ != 0x2a)11281128+ break;11291129+ }11301130+ if (i == l) {11311131+ if (debug & DEBUG_L1OIP_MSG)11321132+ printk(KERN_DEBUG "%s: got silence, not sending"11331133+ ", but counting\n", __func__);11341134+ hc->chan[bch->slot].tx_counter += l;11351135+ skb_trim(skb, 0);11361136+ queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb);11371137+ return 0;11381138+ }11391139+11401140+ /* send frame */11411141+ p = skb->data;11421142+ l = skb->len;11431143+ while (l) {11441144+ ll = (l < L1OIP_MAX_PERFRAME)?l:L1OIP_MAX_PERFRAME;11451145+ l1oip_socket_send(hc, hc->codec, bch->slot, 0,11461146+ hc->chan[bch->slot].tx_counter, p, ll);11471147+ hc->chan[bch->slot].tx_counter += ll;11481148+ p += ll;11491149+ l -= ll;11501150+ }11511151+ skb_trim(skb, 0);11521152+ queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb);11531153+ return 0;11541154+ case PH_ACTIVATE_REQ:11551155+ if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))11561156+ printk(KERN_DEBUG "%s: PH_ACTIVATE channel %d (1..%d)\n"11571157+ , __func__, bch->slot, hc->b_num+1);11581158+ hc->chan[bch->slot].codecstate = 0;11591159+ test_and_set_bit(FLG_ACTIVE, &bch->Flags);11601160+ skb_trim(skb, 0);11611161+ queue_ch_frame(ch, PH_ACTIVATE_IND, hh->id, skb);11621162+ return 0;11631163+ case PH_DEACTIVATE_REQ:11641164+ if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))11651165+ printk(KERN_DEBUG "%s: PH_DEACTIVATE channel %d "11661166+ "(1..%d)\n", __func__, bch->slot,11671167+ hc->b_num+1);11681168+ test_and_clear_bit(FLG_ACTIVE, &bch->Flags);11691169+ skb_trim(skb, 0);11701170+ queue_ch_frame(ch, PH_DEACTIVATE_IND, hh->id, skb);11711171+ return 0;11721172+ }11731173+ if (!ret)11741174+ dev_kfree_skb(skb);11751175+ return ret;11761176+}11771177+11781178+static int11791179+channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)11801180+{11811181+ int ret = 0;11821182+ struct dsp_features *features =11831183+ (struct dsp_features *)(*((u_long *)&cq->p1));11841184+11851185+ switch (cq->op) {11861186+ case MISDN_CTRL_GETOP:11871187+ cq->op = MISDN_CTRL_HW_FEATURES_OP;11881188+ break;11891189+ case MISDN_CTRL_HW_FEATURES: /* fill features structure */11901190+ if (debug & DEBUG_L1OIP_MSG)11911191+ printk(KERN_DEBUG "%s: HW_FEATURE request\n",11921192+ __func__);11931193+ /* create confirm */11941194+ features->unclocked = 1;11951195+ features->unordered = 1;11961196+ break;11971197+ default:11981198+ printk(KERN_WARNING "%s: unknown Op %x\n",11991199+ __func__, cq->op);12001200+ ret = -EINVAL;12011201+ break;12021202+ }12031203+ return ret;12041204+}12051205+12061206+static int12071207+l1oip_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)12081208+{12091209+ struct bchannel *bch = container_of(ch, struct bchannel, ch);12101210+ int err = -EINVAL;12111211+12121212+ if (bch->debug & DEBUG_HW)12131213+ printk(KERN_DEBUG "%s: cmd:%x %p\n",12141214+ __func__, cmd, arg);12151215+ switch (cmd) {12161216+ case CLOSE_CHANNEL:12171217+ test_and_clear_bit(FLG_OPEN, &bch->Flags);12181218+ test_and_clear_bit(FLG_ACTIVE, &bch->Flags);12191219+ ch->protocol = ISDN_P_NONE;12201220+ ch->peer = NULL;12211221+ module_put(THIS_MODULE);12221222+ err = 0;12231223+ break;12241224+ case CONTROL_CHANNEL:12251225+ err = channel_bctrl(bch, arg);12261226+ break;12271227+ default:12281228+ printk(KERN_WARNING "%s: unknown prim(%x)\n",12291229+ __func__, cmd);12301230+ }12311231+ return err;12321232+}12331233+12341234+12351235+/*12361236+ * cleanup module and stack12371237+ */12381238+static void12391239+release_card(struct l1oip *hc)12401240+{12411241+ int ch;12421242+12431243+ if (timer_pending(&hc->keep_tl))12441244+ del_timer(&hc->keep_tl);12451245+12461246+ if (timer_pending(&hc->timeout_tl))12471247+ del_timer(&hc->timeout_tl);12481248+12491249+ if (hc->socket_thread)12501250+ l1oip_socket_close(hc);12511251+12521252+ if (hc->registered && hc->chan[hc->d_idx].dch)12531253+ mISDN_unregister_device(&hc->chan[hc->d_idx].dch->dev);12541254+ for (ch = 0; ch < 128; ch++) {12551255+ if (hc->chan[ch].dch) {12561256+ mISDN_freedchannel(hc->chan[ch].dch);12571257+ kfree(hc->chan[ch].dch);12581258+ }12591259+ if (hc->chan[ch].bch) {12601260+ mISDN_freebchannel(hc->chan[ch].bch);12611261+ kfree(hc->chan[ch].bch);12621262+#ifdef REORDER_DEBUG12631263+ if (hc->chan[ch].disorder_skb)12641264+ dev_kfree_skb(hc->chan[ch].disorder_skb);12651265+#endif12661266+ }12671267+ }12681268+12691269+ spin_lock(&l1oip_lock);12701270+ list_del(&hc->list);12711271+ spin_unlock(&l1oip_lock);12721272+12731273+ kfree(hc);12741274+}12751275+12761276+static void12771277+l1oip_cleanup(void)12781278+{12791279+ struct l1oip *hc, *next;12801280+12811281+ list_for_each_entry_safe(hc, next, &l1oip_ilist, list)12821282+ release_card(hc);12831283+12841284+ l1oip_4bit_free();12851285+}12861286+12871287+12881288+/*12891289+ * module and stack init12901290+ */12911291+static int12921292+init_card(struct l1oip *hc, int pri, int bundle)12931293+{12941294+ struct dchannel *dch;12951295+ struct bchannel *bch;12961296+ int ret;12971297+ int i, ch;12981298+12991299+ spin_lock_init(&hc->socket_lock);13001300+ hc->idx = l1oip_cnt;13011301+ hc->pri = pri;13021302+ hc->d_idx = pri?16:3;13031303+ hc->b_num = pri?30:2;13041304+ hc->bundle = bundle;13051305+ if (hc->pri)13061306+ sprintf(hc->name, "l1oip-e1.%d", l1oip_cnt + 1);13071307+ else13081308+ sprintf(hc->name, "l1oip-s0.%d", l1oip_cnt + 1);13091309+13101310+ switch (codec[l1oip_cnt]) {13111311+ case 0: /* as is */13121312+ case 1: /* alaw */13131313+ case 2: /* ulaw */13141314+ case 3: /* 4bit */13151315+ break;13161316+ default:13171317+ printk(KERN_ERR "Codec(%d) not supported.\n",13181318+ codec[l1oip_cnt]);13191319+ return -EINVAL;13201320+ }13211321+ hc->codec = codec[l1oip_cnt];13221322+ if (debug & DEBUG_L1OIP_INIT)13231323+ printk(KERN_DEBUG "%s: using codec %d\n",13241324+ __func__, hc->codec);13251325+13261326+ if (id[l1oip_cnt] == 0) {13271327+ printk(KERN_WARNING "Warning: No 'id' value given or "13281328+ "0, this is highly unsecure. Please use 32 "13291329+ "bit randmom number 0x...\n");13301330+ }13311331+ hc->id = id[l1oip_cnt];13321332+ if (debug & DEBUG_L1OIP_INIT)13331333+ printk(KERN_DEBUG "%s: using id 0x%x\n", __func__, hc->id);13341334+13351335+ hc->ondemand = ondemand[l1oip_cnt];13361336+ if (hc->ondemand && !hc->id) {13371337+ printk(KERN_ERR "%s: ondemand option only allowed in "13381338+ "conjunction with non 0 ID\n", __func__);13391339+ return -EINVAL;13401340+ }13411341+13421342+ if (limit[l1oip_cnt])13431343+ hc->b_num = limit[l1oip_cnt];13441344+ if (!pri && hc->b_num > 2) {13451345+ printk(KERN_ERR "Maximum limit for BRI interface is 2 "13461346+ "channels.\n");13471347+ return -EINVAL;13481348+ }13491349+ if (pri && hc->b_num > 126) {13501350+ printk(KERN_ERR "Maximum limit for PRI interface is 126 "13511351+ "channels.\n");13521352+ return -EINVAL;13531353+ }13541354+ if (pri && hc->b_num > 30) {13551355+ printk(KERN_WARNING "Maximum limit for BRI interface is 30 "13561356+ "channels.\n");13571357+ printk(KERN_WARNING "Your selection of %d channels must be "13581358+ "supported by application.\n", hc->limit);13591359+ }13601360+13611361+ hc->remoteip = ip[l1oip_cnt<<2] << 2413621362+ | ip[(l1oip_cnt<<2)+1] << 1613631363+ | ip[(l1oip_cnt<<2)+2] << 813641364+ | ip[(l1oip_cnt<<2)+3];13651365+ hc->localport = port[l1oip_cnt]?:(L1OIP_DEFAULTPORT+l1oip_cnt);13661366+ if (remoteport[l1oip_cnt])13671367+ hc->remoteport = remoteport[l1oip_cnt];13681368+ else13691369+ hc->remoteport = hc->localport;13701370+ if (debug & DEBUG_L1OIP_INIT)13711371+ printk(KERN_DEBUG "%s: using local port %d remote ip "13721372+ "%d.%d.%d.%d port %d ondemand %d\n", __func__,13731373+ hc->localport, hc->remoteip >> 24,13741374+ (hc->remoteip >> 16) & 0xff,13751375+ (hc->remoteip >> 8) & 0xff, hc->remoteip & 0xff,13761376+ hc->remoteport, hc->ondemand);13771377+13781378+ dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL);13791379+ if (!dch)13801380+ return -ENOMEM;13811381+ dch->debug = debug;13821382+ mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, NULL);13831383+ dch->hw = hc;13841384+ if (pri)13851385+ dch->dev.Dprotocols = (1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1);13861386+ else13871387+ dch->dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0);13881388+ dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |13891389+ (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));13901390+ dch->dev.D.send = handle_dmsg;13911391+ dch->dev.D.ctrl = l1oip_dctrl;13921392+ dch->dev.nrbchan = hc->b_num;13931393+ dch->slot = hc->d_idx;13941394+ hc->chan[hc->d_idx].dch = dch;13951395+ i = 1;13961396+ for (ch = 0; ch < dch->dev.nrbchan; ch++) {13971397+ if (ch == 15)13981398+ i++;13991399+ bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);14001400+ if (!bch) {14011401+ printk(KERN_ERR "%s: no memory for bchannel\n",14021402+ __func__);14031403+ return -ENOMEM;14041404+ }14051405+ bch->nr = i + ch;14061406+ bch->slot = i + ch;14071407+ bch->debug = debug;14081408+ mISDN_initbchannel(bch, MAX_DATA_MEM);14091409+ bch->hw = hc;14101410+ bch->ch.send = handle_bmsg;14111411+ bch->ch.ctrl = l1oip_bctrl;14121412+ bch->ch.nr = i + ch;14131413+ list_add(&bch->ch.list, &dch->dev.bchannels);14141414+ hc->chan[i + ch].bch = bch;14151415+ test_and_set_bit(bch->nr & 0x1f,14161416+ &dch->dev.channelmap[bch->nr >> 5]);14171417+ }14181418+ ret = mISDN_register_device(&dch->dev, hc->name);14191419+ if (ret)14201420+ return ret;14211421+ hc->registered = 1;14221422+14231423+ if (debug & DEBUG_L1OIP_INIT)14241424+ printk(KERN_DEBUG "%s: Setting up network card(%d)\n",14251425+ __func__, l1oip_cnt + 1);14261426+ ret = l1oip_socket_open(hc);14271427+ if (ret)14281428+ return ret;14291429+14301430+ hc->keep_tl.function = (void *)l1oip_keepalive;14311431+ hc->keep_tl.data = (ulong)hc;14321432+ init_timer(&hc->keep_tl);14331433+ hc->keep_tl.expires = jiffies + 2*HZ; /* two seconds first time */14341434+ add_timer(&hc->keep_tl);14351435+14361436+ hc->timeout_tl.function = (void *)l1oip_timeout;14371437+ hc->timeout_tl.data = (ulong)hc;14381438+ init_timer(&hc->timeout_tl);14391439+ hc->timeout_on = 0; /* state that we have timer off */14401440+14411441+ return 0;14421442+}14431443+14441444+static int __init14451445+l1oip_init(void)14461446+{14471447+ int pri, bundle;14481448+ struct l1oip *hc;14491449+ int ret;14501450+14511451+ printk(KERN_INFO "mISDN: Layer-1-over-IP driver Rev. %s\n",14521452+ l1oip_revision);14531453+14541454+ INIT_LIST_HEAD(&l1oip_ilist);14551455+ spin_lock_init(&l1oip_lock);14561456+14571457+ if (l1oip_4bit_alloc(ulaw))14581458+ return -ENOMEM;14591459+14601460+ l1oip_cnt = 0;14611461+ while (type[l1oip_cnt] && l1oip_cnt < MAX_CARDS) {14621462+ switch (type[l1oip_cnt] & 0xff) {14631463+ case 1:14641464+ pri = 0;14651465+ bundle = 0;14661466+ break;14671467+ case 2:14681468+ pri = 1;14691469+ bundle = 0;14701470+ break;14711471+ case 3:14721472+ pri = 0;14731473+ bundle = 1;14741474+ break;14751475+ case 4:14761476+ pri = 1;14771477+ bundle = 1;14781478+ break;14791479+ default:14801480+ printk(KERN_ERR "Card type(%d) not supported.\n",14811481+ type[l1oip_cnt] & 0xff);14821482+ l1oip_cleanup();14831483+ return -EINVAL;14841484+ }14851485+14861486+ if (debug & DEBUG_L1OIP_INIT)14871487+ printk(KERN_DEBUG "%s: interface %d is %s with %s.\n",14881488+ __func__, l1oip_cnt, pri?"PRI":"BRI",14891489+ bundle?"bundled IP packet for all B-channels"14901490+ :"seperate IP packets for every B-channel");14911491+14921492+ hc = kzalloc(sizeof(struct l1oip), GFP_ATOMIC);14931493+ if (!hc) {14941494+ printk(KERN_ERR "No kmem for L1-over-IP driver.\n");14951495+ l1oip_cleanup();14961496+ return -ENOMEM;14971497+ }14981498+ INIT_WORK(&hc->workq, (void *)l1oip_send_bh);14991499+15001500+ spin_lock(&l1oip_lock);15011501+ list_add_tail(&hc->list, &l1oip_ilist);15021502+ spin_unlock(&l1oip_lock);15031503+15041504+ ret = init_card(hc, pri, bundle);15051505+ if (ret) {15061506+ l1oip_cleanup();15071507+ return ret;15081508+ }15091509+15101510+ l1oip_cnt++;15111511+ }15121512+ printk(KERN_INFO "%d virtual devices registered\n", l1oip_cnt);15131513+ return 0;15141514+}15151515+15161516+module_init(l1oip_init);15171517+module_exit(l1oip_cleanup);15181518+