#define NR_MUX 16 static char mux_send_info_flags[NR_MUX]; static void *mux_send_info[NR_MUX]; static char iscmdtty[] = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; static char tty2dlci[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x-c, 0x0d }; /* The crctable for the FEC field */ static u8 crctable[256]; /* Functions for the crc-check and calculation */ /* Calculates a reversed CRC table for the FCS check */ void create_crctable(u8 table[]) { s32 i,j; u8 data; u8 code_word = (u8) 0xe0; /* pol = x8+x2+x1+1 */ u8 sr = (u8) 0; /* Shiftregister initiated to zero */ for (j = 0; j < 256; j++) { data = (u8) j; for (i = 0; i < 8; i++) { if ((data & 0x1)^(sr & 0x1)) { sr >>= 1; sr ^= code_word; } else { sr >>= 1; } data >>= 1; sr &= 0xff; } table[j] = sr; sr = 0; } } #define CRC_VALID 0xcf /* This functions check whether the checksum is correct or not. Length is the number of bytes in the message, data points to the beginning of the message */ u32 crc_check(u8 *data, u32 length, u8 check_sum) { u8 fcs = 0xff; RF_DATA(FNC, data, length); while (length--) { fcs = crctable[fcs ^ *data++]; } fcs = crctable[fcs ^ check_sum]; D_REC(FNC"fcs : %d\n", fcs); if (fcs == (uint) 0xcf) /* CRC_VALID) */ { D_REC(FNC"CRC check OK\n"); return 0; } else { D_WARN(FNC"CRC check failed, data will be discarded\n"); return -1; } } /* Calculates the checksum according to the RFCOMM specification */ u8 crc_calc(u8 *data, u32 length) { u8 fcs = 0xff; while (length--) { fcs = crctable[fcs^*data++]; } /*Ones complement*/ return 0xff-fcs; } /* Calculates a reversed CRC table for the FCS check */ void create_crctable(u8 table[]) { s32 i,j; u8 data; u8 code_word = (u8) 0xe0; /* pol = x8+x2+x1+1 */ u8 sr = (u8) 0; /* Shiftregister initiated to zero */ for (j = 0; j < 256; j++) { data = (u8) j; for (i = 0; i < 8; i++) { if ((data & 0x1)^(sr & 0x1)) { sr >>= 1; sr ^= code_word; } else { sr >>= 1; } data >>= 1; sr &= 0xff; } table[j] = sr; sr = 0; } } static int valid_dlci(unsigned char r0) { if (r0 > 13) return 0; else return 1; } /* send SIGUSR2 to aplogd */ static int TS0710_SIG2APLOGD() { } static int ts0710_exec_test_cmd() { } static int ts0710_reset_con() { /* FIXME */ ts0710_reset_dlci(); } static int ts0710_init() { create_crctable(&crctable); ts0710_reset_con(); } static int basic_write() { int ret; if (!usb_for_mux_driver || !usb_for_mux_tty) { printk("MUX basic_write: (COMM_FOR_MUX_DRIVER == 0 || (COMM_FOR_MUX_TTY == 0)\n"); return -1; } ret = usb_for_mux_driver(); if (ret != 0) print("MUX basic_write: Write Error!\n"); return ret; } /* TS 07.10 5.3.2 Unnumbered Acknowledgement (UA) response */ static int send_ua() { crc_calc(); basic_write(); } /* TS 07.10 5.3.3 Disconnected Mode (DM) response */ static int send_dm() { crc_calc(); basic_write(); } /* TS 07.10 5.3.1 Set ASynchronous Balanced Mode (SABM) command */ static int send_sabm() { crc_calc(); basic_write(); } /* TS 07.10 5.3.4 Disconnect (DISC) command */ static int send_disc() { crc_calc(); basic_write(); } static struct tty_driver mux_driver; static int mux_sched_send() { } static int mux_open(struct tty_struct * tty, struct file * filp) { int ret; int dlci_num; MOD_INC_USE_COUNT; if (!usb_for_mux_driver) { printk("MUX: please install and open IPC-USB first\n"); goto out_dec_use; } if (!tty) goto out_dec_use; tty->driver_data; ret = ts0710_open_channel(0); if (ret != 0) { printk("MUX: Can't connect server channel 0!\n"); ts0810_init(); decrement_something; goto out_dec_use; } if (mux_send_info_flags[dlci_num] == 0) { foo = kmalloc(0x138, GFP_KERNEL); if (!foo) { ret = -ENOMEM; goto out_dec_use; } mux_send_info[dlci_num] = foo; mux_send_info_flags[dlci_num] = 1; } if (mux_recv_info_flags[dlci_num] == 0) { foo = kmalloc(0x144, GFP_KERNEL); if (!foo) { ret = -ENOMEM; mux_send_info_flags[dlci_num] = 0; kfree(mux_send_info[dlci_num]); goto out_dec_use; } foo + 0x140 = 0; foo + 0x138 = 0; foo + 0x134 = 0; foo + 0x130 = 0; foo + 0x12c = 0; foo + 0x13c = dlci_num; mux_recv_info[dlci_num] = foo; mux_recv_info_flags[dlci_num] = 1; } dlci2tty out_dec_use: MOD_DEC_USE_COUNT; return ret; } static int mux_close(struct tty_struct * tty, struct file * filp) { int dlci_num; if (dlci_num == 7) { printk("MUX mux_close: tapisrv might be down!!! Close DLCI 1\n"); TS0710_SIG2APLOGD(); } ts0710_close_channel(dlci_num); /* FIXME: lots of stuff */ } static int mux_write(struct tty_struct * tty, int from_user, const unsigned char *buf, int count) { } static int mux_write_room(struct tty_struct *tty) { } static void mux_flush_buffer(struct tty_struct *tty) { } mux_chars_in_buffer static void mux_throttle(struct tty_struct * tty) { if (!tty) return; if (!tty->driver_data) return; if (whatever > 0xf) return; /* FIXME */ } static void mux_unthrottle(struct tty_struct * tty) { } static int mux_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) { } static mux_dispatcher() { } static mux_sender() { } static int get_count() { } ssize_t file_proc_read(struct file *file, char __user *buf, size_t len, loff_t *ofs) { } ssize_t file_proc_write(struct file *file, const char __user *buf, size_t len, loff_t *ofs) { } static struct proc_entry *gprs_proc_file; static struct file_proc_operations = { .owner = THIS_MODULE, .read = file_proc_read, .write = file_proc_write, }; static int gprs_proc_init() { gprs_proc_file = create_proc_entry("gprsbytes", 0x180, 0); gprs_proc_file->proc_fops = file_proc_operations; } int __init mux_init(void) { if (!usb_for_mux_driver) panic("Please install IPC-USB first"); ts0710_init(); /* FIXME: missing */ memset(&send_tqueue, 0, 0x14); memset(&receive_tqueue, 0, 0x14); memset(&post_recv_tqueue, 0, 0x14); memset(&mux_driver, 0, sizeof(mux_driver)); memset(&mux_tty, 0, sizeof(mux_tty)); /* FIXME: missing */ mux_driver.magic = 0x5402; mux_driver.driver_name = "ts0710mux"; mux_driver.name = "ts0710mux"; mux_driver.major = 250; mux_driver.minor_start = 0; mux_driver.num = 16; mux_driver.init_termios.c_iflag = 0x00; mux_driver.init_termios.c_oflag = 0xbf; mux_driver.init_termios.c_cflag = 0x00; mux_driver.refcount = &mux_refcount; mux_driver.other = NULL; mux_driver.table = &mux_table; mux_driver.termios = &mux_termios; mux_driver.termios_locked = &mux_termios_locked; mux_driver.open = &mux_open; mux_driver.close = &mux_close; mux_driver.write = &mux_write; mux_driver.write_room = &mux_write_room; mux_driver.flush_buffer = &mux_flush_buffer; mux_driver.chars_in_buffer = &mux_chars_in_buffer; mux_driver.throttle = &mux_throttle; mux_driver.unthrottle = &mux_unthrottle; mux_driver.ioctl = &mux_ioctl; if (!tty_register_driver(&mux_driver)) panic("Couldn't register mux driver"); usb_mux_dispatcher = &mux_dispatcher; usb_mux_sender = &mux_sender; gprs_proc_init(); return 0; } void __exit mux_exit(void) { /* FIXME */ } module_init(mux_init); module_init(mux_init);