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

cfgwin32.c

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

/*
 *      cfgwin32.c  --  Windows (registry) configuration IO.
 *
 *      Copyright (C) 2000-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"

#include <windows.h>

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

#define MAXCONFIGENTRIES  32

#define REGISTRYPATH "SOFTWARE\\FlexNet\\BaycomUSB"
#define REGHKEY      HKEY_LOCAL_MACHINE

static char configfile[256] = REGISTRYPATH;

static struct configentry configs[MAXCONFIGENTRIES];

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

void config_setfile(const char *name)
{
      if (!name)
            name = REGISTRYPATH;
      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 int deletekeyx(HKEY key)
{
        char name[128];
        LONG err;
        DWORD len;
        HKEY key2;
        int ret = 0;
        
        for (;;) {
                len = sizeof(name);
                if ((RegEnumKeyEx(key, 0, name, &len, NULL, NULL, NULL, NULL)) != ERROR_SUCCESS)
                        return ret;
                if ((err = RegOpenKeyEx(key, name, 0, KEY_ALL_ACCESS, &key2)) != ERROR_SUCCESS) {
                        lprintf(10, "RegOpenKeyEx(%s) returned 0x%lx\n", name, err);
                        return -1;
                }
                ret |= deletekeyx(key2);
                RegCloseKey(key2);
                RegDeleteKey(key, name);
        }
        return ret;
}

static int deletekey(const char *name)
{
        HKEY key;
        int ret;
        DWORD err;
        
        if ((err = RegOpenKeyEx(REGHKEY, name, 0, KEY_ALL_ACCESS, &key)) != ERROR_SUCCESS) {
                lprintf(10, "RegOpenKeyEx(%s) returned 0x%lx\n", name, err);
                return -1;
        }
        ret = deletekeyx(key);
        RegCloseKey(key);
        RegDeleteKey(REGHKEY, name);
        return ret;
}

static int setprop(const char *serial, const char *section, const char *propname, const char *value)
{
      char name[256];
        HKEY key;
        DWORD err;
        
      snprintf(name, sizeof(name), "%s\\%s\\%s", configfile, serial, section);
      if ((err = RegCreateKeyEx(REGHKEY, name, 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &key, NULL)) != ERROR_SUCCESS) {
            lprintf(10, "RegCreateKeyEx(%s,%s) returned 0x%lx\n", serial, section, err);
                return -1;
        }
        err = RegSetValueEx(key, propname, 0, REG_SZ, value, strlen(value)+1);
        RegCloseKey(key);
        if (err != ERROR_SUCCESS) {
                lprintf(10, "RegSetValueEx(%s,%s,%s,%s) returned 0x%lx\n", serial, section, propname, value, err);
                return -1;
        }
        return 0;
}

static int getprop(const char *serial, const char *section, const char *propname, char *value, size_t vsize)
{
      char name[256];
        HKEY key;
        DWORD err, vtype, len;
        
      snprintf(name, sizeof(name), "%s\\%s\\%s", configfile, serial, section);
        if ((err = RegCreateKeyEx(REGHKEY, name, 0, "", REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &key, NULL)) != ERROR_SUCCESS) {
            lprintf(10, "RegCreateKeyEx(%s,%s) returned 0x%lx\n", serial, section, err);
                return -1;
        }
        len = vsize;
        err = RegQueryValueEx(key, propname, NULL, &vtype, value, &len);
        RegCloseKey(key);
        if (err != ERROR_SUCCESS) {
                lprintf(10, "RegQueryValueEx(%s,%s,%s) returned 0x%lx\n", serial, section, propname, err);
            value[0] = 0;
                return -1;
        }
        if (vtype != REG_SZ) {
            value[0] = 0;
                return -1;
      }
        if (len >= vsize)
                len = vsize;
        value[len] = 0;
      return 0;
}

int config_setvalue(const char *propname, const char *value)
{
      char name[256];
        HKEY key;
        DWORD err;
        
      snprintf(name, sizeof(name), "%s\\misc", configfile);
      if ((err = RegCreateKeyEx(REGHKEY, name, 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &key, NULL)) != ERROR_SUCCESS) {
            lprintf(10, "RegCreateKeyEx(misc) returned 0x%lx\n", err);
                return -1;
        }
        err = RegSetValueEx(key, propname, 0, REG_SZ, value, strlen(value)+1);
        RegCloseKey(key);
        if (err != ERROR_SUCCESS) {
                lprintf(10, "RegSetValueEx(misc,%s,%s) returned 0x%lx\n", propname, value, err);
                return -1;
        }
        return 0;
}

int config_getvalue(const char *propname, char *value, size_t vsize)
{
      char name[256];
        HKEY key;
        DWORD err, vtype, len;

      snprintf(name, sizeof(name), "%s\\misc", configfile);
        if ((err = RegCreateKeyEx(REGHKEY, name, 0, "", REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &key, NULL)) != ERROR_SUCCESS) {
            lprintf(10, "RegCreateKeyEx(misc) returned 0x%lx\n", err);
                return -1;
        }
        len = vsize;
        err = RegQueryValueEx(key, propname, NULL, &vtype, value, &len);
        RegCloseKey(key);
        if (err != ERROR_SUCCESS) {
                lprintf(10, "RegQueryValueEx(misc,%s) returned 0x%lx\n", propname, err);
            value[0] = 0;
                return -1;
        }
        if (vtype != REG_SZ) {
            value[0] = 0;
                return -1;
      }
        if (len >= vsize)
                len = vsize;
        value[len] = 0;
      return 0;
}

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

static void parseone(struct configentry *cfg)
{
      char buf[128];

      if (!getprop(cfg->serial, "adapter", "mode", buf, sizeof(buf))) {
            if (!strcmp(buf, "fsk")) {
                  cfg->adapter.mode = MODE_FSK;
            } else if (!strcmp(buf, "external")) {
                  cfg->adapter.mode = MODE_EXTERNAL;
            } else if (!strcmp(buf, "afsk")) {
                  cfg->adapter.mode = MODE_AFSK;
            } else if (!strcmp(buf, "audio")) {
                  cfg->adapter.mode = MODE_AUDIO;
            } else if (!strcmp(buf, "bscan")) {
                  cfg->adapter.mode = MODE_BSCAN;
            }
      }
      if (!getprop(cfg->serial, "adapter", "fclk", buf, sizeof(buf)))
            cfg->adapter.fclk = strtoul(buf, NULL, 0);
      if (!getprop(cfg->serial, "adapter", "bitrate", buf, sizeof(buf)))
            cfg->adapter.bitraterx = cfg->adapter.bitratetx = strtoul(buf, NULL, 0);
      if (!getprop(cfg->serial, "adapter", "bitraterx", buf, sizeof(buf)))
            cfg->adapter.bitraterx = strtoul(buf, NULL, 0);
      if (!getprop(cfg->serial, "adapter", "bitratetx", buf, sizeof(buf)))
            cfg->adapter.bitratetx = strtoul(buf, NULL, 0);
      if (!getprop(cfg->serial, "adapter", "samplerate", buf, sizeof(buf)))
            cfg->adapter.samplerate = strtoul(buf, NULL, 0);
      if (!getprop(cfg->serial, "adapter", "loopback", buf, sizeof(buf)))
            cfg->adapter.loopback = strtoul(buf, NULL, 0);
      if (!getprop(cfg->serial, "adapter", "pttmute", buf, sizeof(buf)))
            cfg->adapter.pttmute = !(buf[0] == '0' || buf[0] == 'n' || buf[0] == 'N');
      if (!getprop(cfg->serial, "adapter", "filtmode", buf, sizeof(buf)))
            cfg->adapter.filtmode = strtoul(buf, NULL, 0);
      if (!getprop(cfg->serial, "adapter", "gain", buf, sizeof(buf)))
            cfg->adapter.gain = strtoul(buf, NULL, 0);
      if (!getprop(cfg->serial, "chaccess", "txdelay", buf, sizeof(buf)))
            cfg->chaccess.txdelay = strtoul(buf, NULL, 0);
      if (!getprop(cfg->serial, "chaccess", "slottime", buf, sizeof(buf)))
            cfg->chaccess.slottime = strtoul(buf, NULL, 0);
      if (!getprop(cfg->serial, "chaccess", "ppersistence", buf, sizeof(buf)))
            cfg->chaccess.ppersistence = strtoul(buf, NULL, 0);
      if (!getprop(cfg->serial, "chaccess", "txtail", buf, sizeof(buf)))
            cfg->chaccess.txtail = strtoul(buf, NULL, 0);
      if (!getprop(cfg->serial, "chaccess", "fullduplex", buf, sizeof(buf)))
            cfg->chaccess.fullduplex = !(buf[0] == '0' || buf[0] == 'n' || buf[0] == 'N');
      if (!getprop(cfg->serial, "interface", "ifname", buf, sizeof(buf)))
            strncpy(cfg->ifcfg.ifname, buf, sizeof(cfg->ifcfg.ifname));
      if (!getprop(cfg->serial, "interface", "hwaddr", buf, sizeof(buf)))
            strncpy(cfg->ifcfg.hwaddr, buf, sizeof(cfg->ifcfg.hwaddr));
      if (!getprop(cfg->serial, "interface", "ipaddr", buf, sizeof(buf)))
            strncpy(cfg->ifcfg.ipaddr, buf, sizeof(cfg->ifcfg.ipaddr));
      if (!getprop(cfg->serial, "interface", "netmask", buf, sizeof(buf)))
            strncpy(cfg->ifcfg.netmask, buf, sizeof(cfg->ifcfg.netmask));
      if (!getprop(cfg->serial, "interface", "broadcast", buf, sizeof(buf)))
            strncpy(cfg->ifcfg.broadcast, buf, sizeof(cfg->ifcfg.broadcast));
      if (!getprop(cfg->serial, "modemdisc", "output", buf, sizeof(buf)))
            cfg->mdisc.output = strtoul(buf, NULL, 0);
      if (!getprop(cfg->serial, "modemdisc", "direction", buf, sizeof(buf)))
            cfg->mdisc.direction = strtoul(buf, NULL, 0);
      if (!getprop(cfg->serial, "modemdisc", "rxc", buf, sizeof(buf)))
            cfg->mdisc.rxc = strtoul(buf, NULL, 0);
      if (!getprop(cfg->serial, "modemdisc", "txc", buf, sizeof(buf)))
            cfg->mdisc.txc = strtoul(buf, NULL, 0);
      if (!getprop(cfg->serial, "modemdisc", "txd", buf, sizeof(buf)))
            cfg->mdisc.txd = strtoul(buf, NULL, 0);
      if (!getprop(cfg->serial, "t7f", "ctrl", buf, sizeof(buf)))
            cfg->t7f.ctrl =strtoul(buf, NULL, 0) ;
}

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)
{
        HKEY regkey;
        LONG err;
        DWORD len;
        DWORD index = 0;
        char buf[256];
      struct configentry *cfg;
      unsigned int i;

      /* default configuration */
      for (i = 0; i < MAXCONFIGENTRIES; i++) {
            cfg = &configs[i];
            config_default(cfg);
      }
      strncpy(configs[0].serial, "default", sizeof(configs[0].serial));
      /* enumerate registry keys */
        if ((err = RegOpenKeyEx(REGHKEY, configfile, 0, KEY_READ, &regkey)) != ERROR_SUCCESS) {
                lprintf(10, "RegOpenKeyEx(%s) returned 0x%lx\n", configfile, err);
                return -1;
        }
      for (;;) {
                len = sizeof(buf);
                if ((RegEnumKeyEx(regkey, index, buf, &len, NULL, NULL, NULL, NULL)) != ERROR_SUCCESS)
                        break;
                index++;
            if (!strcmp(buf, "default"))
                  cfg = &configs[0];
            else if (buf[0] >= '0' && buf[0] <= '9') {
                  cfg = config_findentry(buf);
                  if (!cfg) {
                        cfg = config_newentry();
                        if (!cfg) {
                              lprintf(10, "Too many configurations, ignoring serial %s\n", buf);
                              continue;
                        }
                        strncpy(cfg->serial, buf, sizeof(cfg->serial));
                  }
            }
            parseone(cfg);
#if 0
                lprintf(10, "Read Configuration: Serial %s, Mode %u\n", cfg->serial, cfg->adapter.mode);
#endif
        }
        RegCloseKey(regkey);
      return 0;
}

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

int config_save(void)
{
      struct configentry *cfg;
        HKEY regkey;
        LONG err;
        DWORD len, index;
        char buf[32];
      char buf2[256];
      unsigned int i;

      /* first delete all nonexisting serials */
  delloop:
      /* enumerate registry keys */
        if ((err = RegOpenKeyEx(REGHKEY, configfile, 0, KEY_READ, &regkey)) != ERROR_SUCCESS) {
                lprintf(10, "RegOpenKeyEx(%s) returned 0x%lx\n", configfile, err);
                goto dosave;
        }
      index = 0;
      for (;;) {
                len = sizeof(buf);
                if ((RegEnumKeyEx(regkey, index, buf, &len, NULL, NULL, NULL, NULL)) != ERROR_SUCCESS)
                        break;
                index++;
                if (buf[0] < '0' || buf[0] > '9')
                        continue;
            for (i = 0; i < MAXCONFIGENTRIES && (!configs[i].serial[0] || strcmp(buf, configs[i].serial)); i++);
            if (i >= MAXCONFIGENTRIES) {
                  RegCloseKey(regkey);
                  snprintf(buf2, sizeof(buf2), "%s\\%s", configfile, buf);
                  deletekey(buf2);
                  lprintf(10, "Deleting Key %s\n", buf2);
                  goto delloop;
            }
      }
      RegCloseKey(regkey);
      /* save existing serials */
  dosave:
      for (i = 0, cfg = configs; i < MAXCONFIGENTRIES; i++, cfg++) {
            if (!cfg->serial[0])
                  continue;
            setprop(cfg->serial, "adapter", "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);
            setprop(cfg->serial, "adapter", "fclk", buf);
            snprintf(buf, sizeof(buf), "%d", cfg->adapter.bitraterx);
            setprop(cfg->serial, "adapter", "bitraterx", buf);
            snprintf(buf, sizeof(buf), "%d", cfg->adapter.bitratetx);
            setprop(cfg->serial, "adapter", "bitratetx", buf);
            snprintf(buf, sizeof(buf), "%d", cfg->adapter.samplerate);
            setprop(cfg->serial, "adapter", "samplerate", buf);
            snprintf(buf, sizeof(buf), "%d", cfg->adapter.loopback);
            setprop(cfg->serial, "adapter", "loopback", buf);
            snprintf(buf, sizeof(buf), "%d", !!cfg->adapter.pttmute);
            setprop(cfg->serial, "adapter", "pttmute", buf);
            snprintf(buf, sizeof(buf), "%d", cfg->adapter.filtmode);
            setprop(cfg->serial, "adapter", "filtmode", buf);
            snprintf(buf, sizeof(buf), "%d", cfg->adapter.gain);
            setprop(cfg->serial, "adapter", "gain", buf);
            snprintf(buf, sizeof(buf), "%d", cfg->chaccess.txdelay);
            setprop(cfg->serial, "chaccess", "txdelay", buf);
            snprintf(buf, sizeof(buf), "%d", cfg->chaccess.slottime);
            setprop(cfg->serial, "chaccess", "slottime", buf);
            snprintf(buf, sizeof(buf), "%d", cfg->chaccess.ppersistence);
            setprop(cfg->serial, "chaccess", "ppersistence", buf);
            snprintf(buf, sizeof(buf), "%d", cfg->chaccess.txtail);
            setprop(cfg->serial, "chaccess", "txtail", buf);
            snprintf(buf, sizeof(buf), "%d", !!cfg->chaccess.fullduplex);
            setprop(cfg->serial, "chaccess", "fullduplex", buf);
            setprop(cfg->serial, "interface", "ifname", cfg->ifcfg.ifname);
            setprop(cfg->serial, "interface", "hwaddr", cfg->ifcfg.hwaddr);
            setprop(cfg->serial, "interface", "ipaddr", cfg->ifcfg.ipaddr);
            setprop(cfg->serial, "interface", "netmask", cfg->ifcfg.netmask);
            setprop(cfg->serial, "interface", "broadcast", cfg->ifcfg.broadcast);
            snprintf(buf, sizeof(buf), "0x%02x", cfg->mdisc.output & 0xff);
            setprop(cfg->serial, "modemdisc", "output", buf);
            snprintf(buf, sizeof(buf), "0x%02x", cfg->mdisc.direction & 0xff);
            setprop(cfg->serial, "modemdisc", "direction", buf);
            snprintf(buf, sizeof(buf), "%u", cfg->mdisc.rxc);
            setprop(cfg->serial, "modemdisc", "rxc", buf);
            snprintf(buf, sizeof(buf), "%u", cfg->mdisc.txc);
            setprop(cfg->serial, "modemdisc", "txc", buf);
            snprintf(buf, sizeof(buf), "%u", cfg->mdisc.txd);
            setprop(cfg->serial, "modemdisc", "txd", buf);
            snprintf(buf, sizeof(buf), "0x%02x", cfg->t7f.ctrl & 0x1f);
            setprop(cfg->serial, "t7f", "ctrl", buf);
      }
      return 0;
}

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


Generated by  Doxygen 1.6.0   Back to index