/* * muxio.c - functions to open, read and write to mux devices * * Copyright (c) 2007 Daniel Ribeiro * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include "ezxd.h" extern int eval_cmd(unsigned int, char *, struct sb *); int mux_read_cmd (struct sb *mux, int m) { int l, s = sizeof(mux->inb); char *sep; int r = 0; if (!mux->inp) mux->inp = mux->inb; l = read(mux->fd, mux->inp, s-(mux->inp-mux->inb)); if (l < 1) { // cmdui_close_connection(mux->fd); return -1; } mux->inp += l; while (mux->inp && (sep = strstr(mux->inb, "\r\n")) != NULL) { sep[0] = 0; sep[1] = 0; sep+=2; if (strlen(mux->inb)) { if (strstr(mux->inb, "ERROR")) r = -1; eval_cmd(MUX(m), mux->inb, NULL); } if(mux->inp <= sep) mux->inp = NULL; else { memmove(mux->inb, sep, mux->inp-sep); mux->inp = mux->inb + (mux->inp-sep); mux->inp[0] = 0; } } /* prevent buffer overflow condition */ if (mux->inp == (mux->inb+s)) { // cmdui_close_connection(mux->fd); return -1; } return r; } int mux_real_write(struct sb *mux) { int l, s = strlen(mux->outb); if (!mux->outp) mux->outp = mux->outb; l = write (mux->fd, mux->outp, s-(mux->outp-mux->outb)); if (l < 1) { // mux_close_connection(mux->fd); return -1; } if (l == (s-(mux->outp-mux->outb))) { mux->outb[0] = 0; mux->outp = NULL; } else mux->outp += l; return 0; } int mux_write(unsigned int m, char *str) { int s = strlen(str)+1; int l, c, ret = 0; for (c = 1; c <= N_MUX; c++) { if (m & muxes[c]->flags) { l = strlen(muxes[c]->outb); if ((s+l) > sizeof(muxes[c]->outb)) ret |= MUX(c); memmove(muxes[c]->outb+l, str, s); } } return ret; } int mux_cmd(int m, char *str) { int r; if (mux_write(MUX(m), str)) return -1; while(((r = mux_real_write(muxes[m])) == 0) && muxes[m]->outp != NULL); if (r) return -1; while(((r = mux_read_cmd(muxes[m], m)) == 0) && muxes[m]->inp != NULL); if (r) return -1; return 0; } static int mux_open(int m) { int f; char tmp[64]; #ifdef DEBUG char *error; #endif if (muxes[m] != NULL) { error("mux already opened"); goto ret; } sprintf(tmp, "/dev/mux%d", m); f = open(tmp, O_RDWR|O_NOCTTY); if (f < 0) { error("cant open mux file"); goto ret; } if ((muxes[m] = malloc(sizeof(struct sb))) == NULL) { error("cant malloc"); goto close; } muxes[m]->inp = NULL; muxes[m]->outp = NULL; muxes[m]->fd = f; muxes[m]->flags = MUX(m); memset(muxes[m]->inb, 0, sizeof(muxes[m]->inb)); memset(muxes[m]->outb, 0, sizeof(muxes[m]->outb)); return 0; close: close(f); ret: dbg("failed opening mux device %d (%s)\n", m, error); return -1; } int mux_open_all() { int c; int ipc; int line; int ret; /* some tolerance when opening /dev/ttyIPC0 */ int counter = 10; do { fprintf(stderr, "Trying to open %s...\n", SERIAL_DEVICE); ipc = open(SERIAL_DEVICE, O_RDWR); if (ipc < 0) { perror(SERIAL_DEVICE); sleep(1); } } while (ipc < 0 && errno == ENODEV && counter--); if (ipc < 0) { perror(SERIAL_DEVICE); return -1; } line = TS0710_LDISC; ret = ioctl(ipc, TIOCSETD, &line); if (ret < 0) { perror("ioctl"); return -1; } for (c = 0; c <= N_MUX; c++) if (mux_open(c)) return -1; return 0; }