Logo Search packages:      
Sourcecode: baycomusb version File versions  Download package

cfgunix.c

/*****************************************************************************/

/*
 *      cfgunix.c  --  UNIX configuration file IO.
 *
 *      Copyright (C) 1999-2001  Thomas Sailer (t.sailer@alumni.ethz.ch)
 *
 *      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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

/*****************************************************************************/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

#include "baycomusb.h"

/* libxml includes */
#include <tree.h>
#include <parser.h>

/* ---------------------------------------------------------------------- */

#define MAXCONFIGENTRIES  32

static char configfile[256] = "/etc/ax25/baycomusb.conf";

static struct configentry configs[MAXCONFIGENTRIES];

/* ---------------------------------------------------------------------- */

void config_setfile(const char *name)
{
      if (!name)
            name = "/etc/ax25/baycomusb.conf";
      strncpy(configfile, name, sizeof(configfile));
}

const char *config_getfile(void)
{
      return configfile;
}

struct configentry *config_entry(unsigned int index)
{
      struct configentry *cfg;
      unsigned int i;

      for (cfg = &configs[0], i = 0; i < MAXCONFIGENTRIES; i++, cfg++) {
            if (!cfg->serial[0])
                  continue;
            if (!index)
                  return cfg;
            index--;
      }
      return NULL;
}

struct configentry *config_findentry(const char *ser)
{
      struct configentry *cfg;
      unsigned int i;

      for (cfg = &configs[0], i = 0; i < MAXCONFIGENTRIES; i++, cfg++) {
            if (!cfg->serial[0])
                  continue;
            if (!strcmp(cfg->serial, ser))
                  return cfg;
      }
      return NULL;
}

struct configentry *config_lookup(const char *ser)
{
      struct configentry *cfg;
      unsigned int i;

      for (cfg = &configs[0], i = 0; i < MAXCONFIGENTRIES; i++, cfg++) {
            if (!cfg->serial[0])
                  continue;
            if (!strcmp(cfg->serial, ser))
                  return cfg;
      }
      return &configs[0];
}
struct configentry *config_newentry(void)
{
      struct configentry *cfg;
      unsigned int i;

      for (cfg = &configs[1], i = 1; i < MAXCONFIGENTRIES && cfg->serial[0]; i++, cfg++);
      if (i >= MAXCONFIGENTRIES)
            return NULL;
      config_default(&configs[i]);
      return &configs[i];
}

int config_deleteentry(struct configentry *cfg)
{
      if (!cfg)
            return -1;
      if (cfg == &configs[0])
            return -1;
      cfg->serial[0] = 0;
      return 0;
}

/* ---------------------------------------------------------------------- */

static void parseone(xmlNodePtr node, struct configentry *cfg)
{
      const char *cp;

      for (; node; node = node->next) {
                if (!node->name) {
                  lprintf(10, "Node has no name\n");
                  continue;
            }
            if (!strcmp(node->name, "adapter")) {
                  if ((cp = xmlGetProp(node, "mode"))) {
                        if (!strcmp(cp, "fsk")) {
                              cfg->adapter.mode = MODE_FSK;
                        } else if (!strcmp(cp, "external")) {
                              cfg->adapter.mode = MODE_EXTERNAL;
                        } else if (!strcmp(cp, "afsk")) {
                              cfg->adapter.mode = MODE_AFSK;
                        } else if (!strcmp(cp, "audio")) {
                              cfg->adapter.mode = MODE_AUDIO;
                        } else if (!strcmp(cp, "bscan")) {
                              cfg->adapter.mode = MODE_BSCAN;
                        }
                  }
                  if ((cp = xmlGetProp(node, "fclk")))
                        cfg->adapter.fclk = strtoul(cp, NULL, 0);
                  /* legacy */
                  if ((cp = xmlGetProp(node, "bitrate")))
                        cfg->adapter.bitraterx = cfg->adapter.bitratetx = strtoul(cp, NULL, 0);
                  if ((cp = xmlGetProp(node, "bitraterx")))
                        cfg->adapter.bitraterx = strtoul(cp, NULL, 0);
                  if ((cp = xmlGetProp(node, "bitratetx")))
                        cfg->adapter.bitratetx = strtoul(cp, NULL, 0);
                  if ((cp = xmlGetProp(node, "samplerate")))
                        cfg->adapter.samplerate = strtoul(cp, NULL, 0);
                  if ((cp = xmlGetProp(node, "loopback")))
                        cfg->adapter.loopback = strtoul(cp, NULL, 0);
                  if ((cp = xmlGetProp(node, "pttmute")))
                        cfg->adapter.pttmute = !(cp[0] == '0' || cp[0] == 'n' || cp[0] == 'N');
                  if ((cp = xmlGetProp(node, "filtmode")))
                        cfg->adapter.filtmode = strtoul(cp, NULL, 0);
                  if ((cp = xmlGetProp(node, "gain")))
                        cfg->adapter.gain = strtoul(cp, NULL, 0);
            } else if (!strcmp(node->name, "chaccess")) {
                  if ((cp = xmlGetProp(node, "txdelay")))
                        cfg->chaccess.txdelay = strtoul(cp, NULL, 0);
                  if ((cp = xmlGetProp(node, "slottime")))
                        cfg->chaccess.slottime = strtoul(cp, NULL, 0);
                  if ((cp = xmlGetProp(node, "ppersistence")))
                        cfg->chaccess.ppersistence = strtoul(cp, NULL, 0);
                  if ((cp = xmlGetProp(node, "txtail")))
                        cfg->chaccess.txtail = strtoul(cp, NULL, 0);
                  if ((cp = xmlGetProp(node, "fullduplex")))
                        cfg->chaccess.fullduplex = !(cp[0] == '0' || cp[0] == 'n' || cp[0] == 'N');
            } else if (!strcmp(node->name, "interface")) {
                  if ((cp = xmlGetProp(node, "ifname")))
                        strncpy(cfg->ifcfg.ifname, cp, sizeof(cfg->ifcfg.ifname));
                  if ((cp = xmlGetProp(node, "hwaddr")))
                        strncpy(cfg->ifcfg.hwaddr, cp, sizeof(cfg->ifcfg.hwaddr));
                  if ((cp = xmlGetProp(node, "ipaddr")))
                        strncpy(cfg->ifcfg.ipaddr, cp, sizeof(cfg->ifcfg.ipaddr));
                  if ((cp = xmlGetProp(node, "netmask")))
                        strncpy(cfg->ifcfg.netmask, cp, sizeof(cfg->ifcfg.netmask));
                  if ((cp = xmlGetProp(node, "broadcast")))
                        strncpy(cfg->ifcfg.broadcast, cp, sizeof(cfg->ifcfg.broadcast));
            } else if (!strcmp(node->name, "modemdisc")) {
                  if ((cp = xmlGetProp(node, "output")))
                        cfg->mdisc.output = strtoul(cp, NULL, 0);
                  if ((cp = xmlGetProp(node, "direction")))
                        cfg->mdisc.direction = strtoul(cp, NULL, 0);
                  if ((cp = xmlGetProp(node, "rxc")))
                        cfg->mdisc.rxc = strtoul(cp, NULL, 0);
                  if ((cp = xmlGetProp(node, "txc")))
                        cfg->mdisc.txc = strtoul(cp, NULL, 0);
                  if ((cp = xmlGetProp(node, "txd")))
                        cfg->mdisc.txd = strtoul(cp, NULL, 0);
            } else if (!strcmp(node->name, "t7f")) {
                  if ((cp = xmlGetProp(node, "ctrl")))
                        cfg->t7f.ctrl =strtoul(cp, NULL, 0) ;
            } else {
                  lprintf(10, "Unknown node %s\n", node->name);
                  continue;
            }
      }
}

void config_default(struct configentry *cfg)
{
      cfg->serial[0] = 0;
      cfg->adapter.mode = MODE_FSK;
      cfg->adapter.fclk = 19666600;
      cfg->adapter.bitraterx = cfg->adapter.bitratetx = 9600;
      cfg->adapter.samplerate = 8000;
      cfg->adapter.loopback = 0;
      cfg->adapter.pttmute = 1;
      cfg->adapter.filtmode = 0;
      cfg->adapter.gain = 0;
      cfg->chaccess.txdelay = 150;
      cfg->chaccess.slottime = 100;
      cfg->chaccess.ppersistence = 40;
      cfg->chaccess.txtail = 10;
      cfg->chaccess.fullduplex = 0;
      strncpy(cfg->ifcfg.ifname, "bcu0", sizeof(cfg->ifcfg.ifname));
      strncpy(cfg->ifcfg.hwaddr, "N0CALL", sizeof(cfg->ifcfg.hwaddr));
      strncpy(cfg->ifcfg.ipaddr, "10.0.0.1", sizeof(cfg->ifcfg.ipaddr));
      strncpy(cfg->ifcfg.netmask, "255.255.255.0", sizeof(cfg->ifcfg.netmask));
      strncpy(cfg->ifcfg.broadcast, "10.0.0.255", sizeof(cfg->ifcfg.broadcast));
      cfg->mdisc.output = 0;
      cfg->mdisc.direction = 0xff;
      cfg->mdisc.rxc = 0;
      cfg->mdisc.txc = 0;
      cfg->mdisc.txd = 0;
      cfg->t7f.ctrl = 0;
}

int config_parse(void)
{
      xmlDocPtr doc;
      xmlNodePtr node;
      struct configentry *cfg;
      unsigned int i;
      const char *cp;

      /* default configuration */
      for (i = 0; i < MAXCONFIGENTRIES; i++) {
            cfg = &configs[i];
            config_default(cfg);
      }
      strncpy(configs[0].serial, "default", sizeof(configs[0].serial));
      /* parse config file */
      doc = xmlParseFile(configfile);
      if (!doc)
            goto err;
      if (strcmp(doc->root->name, "baycomusb")) {
            lprintf(10, "Config file does not contain baycomusb data\n");
            goto err2;
      }
      for (node = doc->root->childs; node; node = node->next) {
                if (!node->name || strcmp(node->name, "device"))
                        continue;
            cp = xmlGetProp(node, "serial");
            if (!cp || !strcmp(cp, "default"))
                  cfg = &configs[0];
            else {
                  cfg = config_findentry(cp);
                  if (!cfg) {
                        cfg = config_newentry();
                        if (!cfg) {
                              lprintf(10, "Too many configurations, ignoring serial %s\n", cp);
                              continue;
                        }
                        strncpy(cfg->serial, cp, sizeof(cfg->serial));
                  }
            }
            parseone(node->childs, cfg);
      }
      xmlFreeDoc(doc);
      return 0;

 err2:
      xmlFreeDoc(doc);
 err:
      return -1;
}

/* ---------------------------------------------------------------------- */

int config_save(void)
{
      xmlDocPtr doc;
      xmlNodePtr node, node2;
      struct configentry *cfg;
      unsigned int i;
      char buf[128];

      if (!(doc = xmlNewDoc("1.0")))
            return -1;
      doc->root = xmlNewDocNode(doc, NULL, "baycomusb", NULL);
      for (i = 0, cfg = configs; i < MAXCONFIGENTRIES; i++, cfg++) {
            if (!cfg->serial[0])
                  continue;
            node = xmlNewChild(doc->root, NULL, "device", NULL);
            xmlSetProp(node, "serial", cfg->serial);
            node2 = xmlNewChild(node, NULL, "adapter", NULL);
            xmlSetProp(node2, "mode", 
                     (cfg->adapter.mode == MODE_EXTERNAL) ? "external" :
                     (cfg->adapter.mode == MODE_AFSK) ? "afsk" :
                     (cfg->adapter.mode == MODE_AUDIO) ? "audio" : 
                     (cfg->adapter.mode == MODE_BSCAN) ? "bscan" : "fsk");
            snprintf(buf, sizeof(buf), "%d", cfg->adapter.fclk);
            xmlSetProp(node2, "fclk", buf);
            snprintf(buf, sizeof(buf), "%d", cfg->adapter.bitraterx);
            xmlSetProp(node2, "bitraterx", buf);
            snprintf(buf, sizeof(buf), "%d", cfg->adapter.bitratetx);
            xmlSetProp(node2, "bitratetx", buf);
            snprintf(buf, sizeof(buf), "%d", cfg->adapter.samplerate);
            xmlSetProp(node2, "samplerate", buf);
            snprintf(buf, sizeof(buf), "%d", cfg->adapter.loopback);
            xmlSetProp(node2, "loopback", buf);
            snprintf(buf, sizeof(buf), "%d", !!cfg->adapter.pttmute);
            xmlSetProp(node2, "pttmute", buf);
            snprintf(buf, sizeof(buf), "%d", cfg->adapter.filtmode);
            xmlSetProp(node2, "filtmode", buf);
            snprintf(buf, sizeof(buf), "%d", cfg->adapter.gain);
            xmlSetProp(node2, "gain", buf);
            node2 = xmlNewChild(node, NULL, "chaccess", NULL);
            snprintf(buf, sizeof(buf), "%d", cfg->chaccess.txdelay);
            xmlSetProp(node2, "txdelay", buf);
            snprintf(buf, sizeof(buf), "%d", cfg->chaccess.slottime);
            xmlSetProp(node2, "slottime", buf);
            snprintf(buf, sizeof(buf), "%d", cfg->chaccess.ppersistence);
            xmlSetProp(node2, "ppersistence", buf);
            snprintf(buf, sizeof(buf), "%d", cfg->chaccess.txtail);
            xmlSetProp(node2, "txtail", buf);
            snprintf(buf, sizeof(buf), "%d", !!cfg->chaccess.fullduplex);
            xmlSetProp(node2, "fullduplex", buf);
            node2 = xmlNewChild(node, NULL, "interface", NULL);
            xmlSetProp(node2, "ifname", cfg->ifcfg.ifname);
            xmlSetProp(node2, "hwaddr", cfg->ifcfg.hwaddr);
            xmlSetProp(node2, "ipaddr", cfg->ifcfg.ipaddr);
            xmlSetProp(node2, "netmask", cfg->ifcfg.netmask);
            xmlSetProp(node2, "broadcast", cfg->ifcfg.broadcast);
            node2 = xmlNewChild(node, NULL, "modemdisc", NULL);
            snprintf(buf, sizeof(buf), "0x%02x", cfg->mdisc.output & 0xff);
            xmlSetProp(node2, "output", buf);
            snprintf(buf, sizeof(buf), "0x%02x", cfg->mdisc.direction & 0xff);
            xmlSetProp(node2, "direction", buf);
            snprintf(buf, sizeof(buf), "%u", cfg->mdisc.rxc);
            xmlSetProp(node2, "rxc", buf);
            snprintf(buf, sizeof(buf), "%u", cfg->mdisc.txc);
            xmlSetProp(node2, "txc", buf);
            snprintf(buf, sizeof(buf), "%u", cfg->mdisc.txd);
            xmlSetProp(node2, "txd", buf);
            node2 = xmlNewChild(node, NULL, "t7f", NULL);
            snprintf(buf, sizeof(buf), "0x%02x", cfg->t7f.ctrl & 0x1f);
            xmlSetProp(node2, "ctrl", buf);
      }
      if (!xmlSaveFile(configfile, doc)) 
            goto err;
      xmlFreeDoc(doc);
      return 0;

 err:
      xmlFreeDoc(doc);
      return -1;
}

/* ---------------------------------------------------------------------- */

Generated by  Doxygen 1.6.0   Back to index