/* $Id$ */ /*** This file is part of ivam2. ivam2 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. ivam2 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 ivam2; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ***/ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include "modemman.h" #include "modem.h" #include "main.h" #define MAX_CHANNELS 10 #define TTY_START 12 struct llist { struct modem *modem; struct llist *next; }; static struct llist *llist = NULL; static int n_llist = 0; static void modem_try_open(const char *dev, const char *msn) { struct modem *m; if ((m = modem_open(dev, msn))) { struct llist *l = malloc(sizeof(struct llist)); assert(l); l->modem = m; l->next = llist; llist = l; n_llist++; } } const char *get_listen_msn(int i) { static int buf_valid = 0; static char buf[256]; static char *buf_ptr[MAX_CHANNELS]; static int n_buf_ptr; if (!args.listen_arg) return "*"; if (!buf_valid) { char *p; strncpy(buf, args.listen_arg, sizeof(buf)-1); buf[sizeof(buf)-1] = 0; for (p = buf; *p; p++) if (*p == ',') *p = ';'; for (p = buf, n_buf_ptr = 0; n_buf_ptr < MAX_CHANNELS;) { int l; buf_ptr[n_buf_ptr++] = p; l = strcspn(p, ":"); if (p[l] == 0) break; p[l] = 0; p+=l+1; } buf_valid = 1; } assert(n_buf_ptr > 0); if (i >= n_buf_ptr) i = n_buf_ptr -1; return buf_ptr[i]; } int modem_manager_init(int channels) { int i; assert(channels <= MAX_CHANNELS && channels > 0); assert(n_llist == 0); daemon_log(LOG_INFO, "Allocating %i channels.", channels); if (args.device_arg) { char *p = args.device_arg; for (;;) { char dev[PATH_MAX]; size_t l, n = strcspn(p, ":"); l = n; if (sizeof(dev)-1 < l) l = sizeof(dev)-1; strncpy(dev, p, l); dev[l] = 0; modem_try_open(dev, get_listen_msn(n_llist)); if (p[n] == 0) break; p[n] = 0; p+=n+1; } } for (i = TTY_START; i < TTY_START+MAX_CHANNELS && n_llist < channels; i++) { char d[PATH_MAX]; snprintf(d, sizeof(d), "/dev/ttyI%i", i); modem_try_open(d, get_listen_msn(n_llist)); } if (n_llist < channels) { daemon_log(LOG_ERR, "Failed to allocate the requested channels. Got %i of %i.", n_llist, channels); modem_manager_done(); return -1; } return 0; } void modem_manager_done(void) { while (llist) { struct llist *l; modem_close(llist->modem); l = llist; llist = llist->next; free(l); n_llist--; } assert(!n_llist && !llist); }