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 "trx.h"

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

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

static char configfile[256] = "/etc/ax25/baycomusb.conf";
static xmlDocPtr doc;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

#define FALSE 0
#define TRUE 1

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

int config_load(const char *name)
{
      if (name)
            strncpy(configfile, name, sizeof(configfile));
      pthread_mutex_lock(&mutex);
      if (!(doc = xmlParseFile(configfile))) {
            if (!(doc = xmlNewDoc("1.0")))
                  goto errmem;
            if (!(doc->root = xmlNewDocNode(doc, NULL, "baycomusb", NULL)))
                  goto errmem;
            goto retok;
      }
      if (strcmp(doc->root->name, "baycomusb")) {
            lprintf(1, "Config file does not contain baycomusb data\n");
            pthread_mutex_unlock(&mutex);
            return -1;
      }
  retok:
      pthread_mutex_unlock(&mutex);
      return 0;

  errmem:
      lprintf(1, "Configfile: out of memory\n");
      pthread_mutex_unlock(&mutex);
      return -1;
}

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

int config_save(void)
{
      int r = 0;

      pthread_mutex_lock(&mutex);
      if (!xmlSaveFile(configfile, doc)) 
            r = -1;
      pthread_mutex_unlock(&mutex);
      return r;
}

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

static xmlNodePtr getserialnode(const char *serial)
{
      xmlNodePtr node;
      const char *cp;

      for (node = doc->root->childs; node; node = node->next) {
                if (!node->name || strcmp(node->name, "device"))
                        continue;
            cp = xmlGetProp(node, "serial");
            if (!cp)
                  continue;
            if (strcmp(cp, serial))
                  continue;
            return node;
      }
      node = xmlNewChild(doc->root, NULL, "device", NULL);
      if (node)
            xmlSetProp(node, "serial", serial);
      return node;
}

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

static xmlNodePtr getsectionnode(xmlNodePtr sernode, const char *secname)
{
      xmlNodePtr node;

      for (node = sernode->childs; node; node = node->next) {
                if (!node->name)
                  continue;
            if (strcmp(node->name, secname))
                  continue;
            return node;
      }
      node = xmlNewChild(sernode, NULL, secname, NULL);
      return node;
}

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

static void parseip(trxapi_ip_address_t addr, const char *cp)
{
        unsigned int r1, r2, r3, r4;
        
        if (!cp || sscanf(cp, "%u.%u.%u.%u", &r1, &r2, &r3, &r4) != 4) {
                addr[0] = addr[1] = addr[2] = addr[3] = 0;
                return;
        }
        addr[0] = r1;
        addr[1] = r2;
        addr[2] = r3;
        addr[3] = r4;
}

void config_loaddevice(struct trx_thread_state *state)
{
      xmlNodePtr sernode, node;
      const char *cp;

      /* set default */
      state->cfg.adapt.mode = trxapi_baycomusb_mode_fsk;
      state->cfg.adapt.fclk = 19666600;
      state->cfg.adapt.bitraterx = state->cfg.adapt.bitratetx = 9600;
      state->cfg.adapt.loopback = trxapi_baycomusb_loopback_off;
      state->cfg.adapt.pttmute = TRUE;
      state->cfg.adapt.filtmode = 0;
      state->cfg.adapt.samplerate = 8000;
      state->cfg.adapt.gain = 1;
      strncpy(state->cfg.adapt.audiodevin, "/dev/dsp", sizeof(state->cfg.adapt.audiodevin));
      strncpy(state->cfg.adapt.audiodevout, "/dev/dsp", sizeof(state->cfg.adapt.audiodevout));
      state->cfg.adapt.rfsquelch = RSSI_MIN;
      state->cfg.adapt.audiosquelch = FALSE;
      state->cfg.chacc.txdelay = 150;
      state->cfg.chacc.slottime = 100;
      state->cfg.chacc.ppersistence = 40;
      state->cfg.chacc.txtail = 10;
      state->cfg.chacc.fullduplex = FALSE;
      strncpy(state->cfg.intf.ifname, "bcu0", sizeof(state->cfg.intf.ifname));
      strncpy(state->cfg.intf.hwaddr, "N0CALL", sizeof(state->cfg.intf.hwaddr));
      state->cfg.intf.ipaddr[0] = 10;
      state->cfg.intf.ipaddr[1] = 0;
      state->cfg.intf.ipaddr[2] = 0;
      state->cfg.intf.ipaddr[3] = 1;
      state->cfg.intf.netmask[0] = 255;
      state->cfg.intf.netmask[1] = 255;
      state->cfg.intf.netmask[2] = 255;
      state->cfg.intf.netmask[3] = 0;
      state->cfg.intf.broadcast[0] = 10;
      state->cfg.intf.broadcast[1] = 0;
      state->cfg.intf.broadcast[2] = 0;
      state->cfg.intf.broadcast[3] = 255;
      state->cfg.intf.gwhwaddr[0] = 0;
      state->cfg.intf.gwipaddr[0] = 0;
      state->cfg.intf.gwipaddr[1] = 0;
      state->cfg.intf.gwipaddr[2] = 0;
      state->cfg.intf.gwipaddr[3] = 0;
      state->cfg.intf.gwnetmask[0] = 255;
      state->cfg.intf.gwnetmask[1] = 0;
      state->cfg.intf.gwnetmask[2] = 0;
      state->cfg.intf.gwnetmask[3] = 0;
      state->cfg.intf.gwipmode = ' ';
      state->cfg.mdisc.output = 0;
      state->cfg.mdisc.direction = 0xff;
      state->cfg.mdisc.rxc = trxapi_modem_disconnect_rxc_normal;
      state->cfg.mdisc.txc = trxapi_modem_disconnect_txc_normal;
      state->cfg.mdisc.txd = trxapi_modem_disconnect_txd_normal;
      pthread_mutex_lock(&mutex);
      if (!(sernode = getserialnode(state->serial))) {
            pthread_mutex_unlock(&mutex);
            return;
      }
      if ((node = getsectionnode(sernode, "adapter"))) {
            if ((cp = xmlGetProp(node, "mode"))) {
                  if (!strcmp(cp, "fsk")) {
                        state->cfg.adapt.mode = trxapi_baycomusb_mode_fsk;
                  } else if (!strcmp(cp, "external")) {
                        state->cfg.adapt.mode = trxapi_baycomusb_mode_external;
                  } else if (!strcmp(cp, "afsk")) {
                        state->cfg.adapt.mode = trxapi_baycomusb_mode_afsk;
                  } else if (!strcmp(cp, "audio")) {
                        state->cfg.adapt.mode = trxapi_baycomusb_mode_audio;
                  }
            }
            if ((cp = xmlGetProp(node, "fclk")))
                  state->cfg.adapt.fclk = strtoul(cp, NULL, 0);
            if ((cp = xmlGetProp(node, "bitrate")))
                  state->cfg.adapt.bitraterx = state->cfg.adapt.bitratetx = strtoul(cp, NULL, 0);
            if ((cp = xmlGetProp(node, "bitraterx")))
                  state->cfg.adapt.bitraterx = strtoul(cp, NULL, 0);
            if ((cp = xmlGetProp(node, "bitratetx")))
                  state->cfg.adapt.bitratetx = strtoul(cp, NULL, 0);
            if ((cp = xmlGetProp(node, "loopback")))
                  state->cfg.adapt.loopback = strtoul(cp, NULL, 0);
            if ((cp = xmlGetProp(node, "pttmute")))
                  state->cfg.adapt.pttmute = (cp[0] == '0' || cp[0] == 'n' || cp[0] == 'N') ? FALSE : TRUE;
            if ((cp = xmlGetProp(node, "filtmode")))
                  state->cfg.adapt.filtmode = strtoul(cp, NULL, 0);
            if ((cp = xmlGetProp(node, "samplerate")))
                  state->cfg.adapt.samplerate = strtoul(cp, NULL, 0);
            if ((cp = xmlGetProp(node, "gain")))
                  state->cfg.adapt.gain = strtod(cp, NULL);
            if ((cp = xmlGetProp(node, "audiodevin")))
                  strncpy(state->cfg.adapt.audiodevin, cp, sizeof(state->cfg.adapt.audiodevin));
            if ((cp = xmlGetProp(node, "audiodevout")))
                  strncpy(state->cfg.adapt.audiodevout, cp, sizeof(state->cfg.adapt.audiodevout));
            if ((cp = xmlGetProp(node, "rfsquelch")))
                  state->cfg.adapt.rfsquelch = strtod(cp, NULL);
            if ((cp = xmlGetProp(node, "audiosquelch")))
                  state->cfg.adapt.audiosquelch = (cp[0] == '0' || cp[0] == 'n' || cp[0] == 'N') ? FALSE : TRUE;
      }
      if ((node = getsectionnode(sernode, "chaccess"))) {
            if ((cp = xmlGetProp(node, "txdelay")))
                  state->cfg.chacc.txdelay = strtoul(cp, NULL, 0);
            if ((cp = xmlGetProp(node, "slottime")))
                  state->cfg.chacc.slottime = strtoul(cp, NULL, 0);
            if ((cp = xmlGetProp(node, "ppersistence")))
                  state->cfg.chacc.ppersistence = strtoul(cp, NULL, 0);
            if ((cp = xmlGetProp(node, "txtail")))
                  state->cfg.chacc.txtail = strtoul(cp, NULL, 0);
            if ((cp = xmlGetProp(node, "fullduplex")))
                  state->cfg.chacc.fullduplex = (cp[0] == '0' || cp[0] == 'n' || cp[0] == 'N') ? FALSE : TRUE;
      }
      if ((node = getsectionnode(sernode, "interface"))) {
            if ((cp = xmlGetProp(node, "ifname")))
                  strncpy(state->cfg.intf.ifname, cp, sizeof(state->cfg.intf.ifname));
            if ((cp = xmlGetProp(node, "hwaddr")))
                  strncpy(state->cfg.intf.hwaddr, cp, sizeof(state->cfg.intf.hwaddr));
            if ((cp = xmlGetProp(node, "ipaddr")))
                  parseip(state->cfg.intf.ipaddr, cp);
            if ((cp = xmlGetProp(node, "netmask")))
                  parseip(state->cfg.intf.netmask, cp);
            if ((cp = xmlGetProp(node, "broadcast")))
                  parseip(state->cfg.intf.broadcast, cp);
            if ((cp = xmlGetProp(node, "gwhwaddr")))
                  strncpy(state->cfg.intf.gwhwaddr, cp, sizeof(state->cfg.intf.gwhwaddr));
            if ((cp = xmlGetProp(node, "gwipaddr")))
                  parseip(state->cfg.intf.gwipaddr, cp);
            if ((cp = xmlGetProp(node, "gwnetmask")))
                  parseip(state->cfg.intf.gwnetmask, cp);
            if ((cp = xmlGetProp(node, "gwipmode")))
                  state->cfg.intf.gwipmode = *cp;
      }
      if ((node = getsectionnode(sernode, "modemdisc"))) {
            if ((cp = xmlGetProp(node, "output")))
                  state->cfg.mdisc.output = strtoul(cp, NULL, 0);
            if ((cp = xmlGetProp(node, "direction")))
                  state->cfg.mdisc.direction = strtoul(cp, NULL, 0);
            if ((cp = xmlGetProp(node, "rxc")))
                  state->cfg.mdisc.rxc = strtoul(cp, NULL, 0);
            if ((cp = xmlGetProp(node, "txc")))
                  state->cfg.mdisc.txc = strtoul(cp, NULL, 0);
            if ((cp = xmlGetProp(node, "txd")))
                  state->cfg.mdisc.txd = strtoul(cp, NULL, 0);
      }
      if ((node = getsectionnode(sernode, "frequency"))) {
            if ((cp = xmlGetProp(node, "rx")))
                  state->cfg.freq.rx = strtoull(cp, NULL, 0);
            if ((cp = xmlGetProp(node, "tx")))
                  state->cfg.freq.tx = strtoull(cp, NULL, 0);
      }
      pthread_mutex_unlock(&mutex);
}

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

void config_savedevice(struct trx_thread_state *state)
{
      xmlNodePtr sernode, node;
      char buf[128];

        if (!state->serial[0])
                return;
      pthread_mutex_lock(&mutex);
      if (!(sernode = getserialnode(state->serial))) {
            lprintf(1, "Config %s out of memory\n", state->serial);
            pthread_mutex_unlock(&mutex);
            return;
      }
      if ((node = getsectionnode(sernode, "adapter"))) {
            xmlSetProp(node, "mode", 
                     (state->cfg.adapt.mode == trxapi_baycomusb_mode_external) ? "external" :
                     (state->cfg.adapt.mode == trxapi_baycomusb_mode_afsk) ? "afsk" :
                     (state->cfg.adapt.mode == trxapi_baycomusb_mode_audio) ? "audio" : "fsk");
            snprintf(buf, sizeof(buf), "%ld", state->cfg.adapt.fclk);
            xmlSetProp(node, "fclk", buf);
            snprintf(buf, sizeof(buf), "%ld", state->cfg.adapt.bitraterx);
            xmlSetProp(node, "bitraterx", buf);
            snprintf(buf, sizeof(buf), "%ld", state->cfg.adapt.bitratetx);
            xmlSetProp(node, "bitratetx", buf);
            snprintf(buf, sizeof(buf), "%d", state->cfg.adapt.loopback);
            xmlSetProp(node, "loopback", buf);
            snprintf(buf, sizeof(buf), "%d", !!state->cfg.adapt.pttmute);
            xmlSetProp(node, "pttmute", buf);
            snprintf(buf, sizeof(buf), "%ld", state->cfg.adapt.filtmode);
            xmlSetProp(node, "filtmode", buf);
            snprintf(buf, sizeof(buf), "%ld", state->cfg.adapt.samplerate);
            xmlSetProp(node, "samplerate", buf);
            snprintf(buf, sizeof(buf), "%f", state->cfg.adapt.gain);
            xmlSetProp(node, "gain", buf);
            xmlSetProp(node, "audiodevin", state->cfg.adapt.audiodevin);
            xmlSetProp(node, "audiodevout", state->cfg.adapt.audiodevout);
            snprintf(buf, sizeof(buf), "%f", state->cfg.adapt.rfsquelch);
            xmlSetProp(node, "rfsquelch", buf);
            snprintf(buf, sizeof(buf), "%d", !!state->cfg.adapt.audiosquelch);
            xmlSetProp(node, "audiosquelch", buf);
      } else
            lprintf(1, "Config %s node adapter out of memory\n", state->serial);
      if ((node = getsectionnode(sernode, "chaccess"))) {
            snprintf(buf, sizeof(buf), "%ld", state->cfg.chacc.txdelay);
            xmlSetProp(node, "txdelay", buf);
            snprintf(buf, sizeof(buf), "%ld", state->cfg.chacc.slottime);
            xmlSetProp(node, "slottime", buf);
            snprintf(buf, sizeof(buf), "%ld", state->cfg.chacc.ppersistence);
            xmlSetProp(node, "ppersistence", buf);
            snprintf(buf, sizeof(buf), "%ld", state->cfg.chacc.txtail);
            xmlSetProp(node, "txtail", buf);
            snprintf(buf, sizeof(buf), "%d", !!state->cfg.chacc.fullduplex);
            xmlSetProp(node, "fullduplex", buf);
      } else
            lprintf(1, "Config %s node chaccess out of memory\n", state->serial);
      if ((node = getsectionnode(sernode, "interface"))) {
            xmlSetProp(node, "ifname", state->cfg.intf.ifname);
            xmlSetProp(node, "hwaddr", state->cfg.intf.hwaddr);
            snprintf(buf, sizeof(buf), "%u.%u.%u.%u", state->cfg.intf.ipaddr[0], state->cfg.intf.ipaddr[1],
                   state->cfg.intf.ipaddr[2], state->cfg.intf.ipaddr[3]);
            xmlSetProp(node, "ipaddr", buf);
            snprintf(buf, sizeof(buf), "%u.%u.%u.%u", state->cfg.intf.netmask[0], state->cfg.intf.netmask[1],
                   state->cfg.intf.netmask[2], state->cfg.intf.netmask[3]);
            xmlSetProp(node, "netmask", buf);
            snprintf(buf, sizeof(buf), "%u.%u.%u.%u", state->cfg.intf.broadcast[0], state->cfg.intf.broadcast[1],
                   state->cfg.intf.broadcast[2], state->cfg.intf.broadcast[3]);
            xmlSetProp(node, "broadcast", buf);
            xmlSetProp(node, "gwhwaddr", state->cfg.intf.gwhwaddr);
            snprintf(buf, sizeof(buf), "%u.%u.%u.%u", state->cfg.intf.gwipaddr[0], state->cfg.intf.gwipaddr[1],
                   state->cfg.intf.gwipaddr[2], state->cfg.intf.gwipaddr[3]);
            xmlSetProp(node, "gwipaddr", buf);
            snprintf(buf, sizeof(buf), "%u.%u.%u.%u", state->cfg.intf.gwnetmask[0], state->cfg.intf.gwnetmask[1],
                   state->cfg.intf.gwnetmask[2], state->cfg.intf.gwnetmask[3]);
            xmlSetProp(node, "gwnetmask", buf);
            snprintf(buf, sizeof(buf), "%c", state->cfg.intf.gwipmode);
            xmlSetProp(node, "gwipmode", buf);
      } else
            lprintf(1, "Config %s node interface out of memory\n", state->serial);
      if ((node = getsectionnode(sernode, "modemdisc"))) {
            snprintf(buf, sizeof(buf), "0x%02lx", state->cfg.mdisc.output & 0xff);
            xmlSetProp(node, "output", buf);
            snprintf(buf, sizeof(buf), "0x%02lx", state->cfg.mdisc.direction & 0xff);
            xmlSetProp(node, "direction", buf);
            snprintf(buf, sizeof(buf), "%u", state->cfg.mdisc.rxc);
            xmlSetProp(node, "rxc", buf);
            snprintf(buf, sizeof(buf), "%u", state->cfg.mdisc.txc);
            xmlSetProp(node, "txc", buf);
            snprintf(buf, sizeof(buf), "%u", state->cfg.mdisc.txd);
            xmlSetProp(node, "txd", buf);
      } else
            lprintf(1, "Config %s node modemdisc out of memory\n", state->serial);  
      if ((node = getsectionnode(sernode, "frequency"))) {
            snprintf(buf, sizeof(buf), "%llu", state->cfg.freq.rx);
            xmlSetProp(node, "rx", buf);
            snprintf(buf, sizeof(buf), "%llu", state->cfg.freq.tx);
            xmlSetProp(node, "tx", buf);
      } else
            lprintf(1, "Config %s node frequency out of memory\n", state->serial);
      pthread_mutex_unlock(&mutex);
}

Generated by  Doxygen 1.6.0   Back to index