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

server.c

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

/*
 *      server.c  --  Transceiver control server object implementation (UNIX only).
 *
 *      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.
 *
 *  Please note that the GPL allows you to use the driver, NOT the radio.
 *  In order to use the radio, you need a license from the communications
 *  authority of your country.
 *
 *  History:
 *   0.1  19.09.2000  Created
 *   0.2  09.03.2001  Now requiring T7F firmware V1.44
 *
 */

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

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

#define _REENTRANT

#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif

#include "sysdeps.h"
#include "trxctrl.h"
#include "trx.h"

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

typedef struct trx_thread_state impl_POA_Trx_Control;

static CORBA_ORB orb;
static PortableServer_POA poa;

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

/*** Stub implementations ***/

CORBA_char *corba_strdup(const char *str)
{
      CORBA_char *s = CORBA_string_alloc(strlen(str));
      strcpy(s, str);
      return s;
}

static void raise_exception(CORBA_Environment *ev, const char *reason)
{
      Trx_TrxError *err = Trx_TrxError__alloc();
      err->reason = corba_strdup(reason);
      CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_Trx_TrxError, err);
}

static void raise_oom_exception(CORBA_Environment *ev)
{
      raise_exception(ev, "Out of memory");
}

static void
impl_Trx_Control_GetDescription(impl_POA_Trx_Control * servant,
                                Trx_TrxDescription ** desc,
                                CORBA_Environment * ev)
{
      Trx_TrxDescription *d = Trx_TrxDescription__alloc();
      *desc = d;
      if (!d) {
            raise_oom_exception(ev);
            return;
      }
      d->manufacturer = corba_strdup("Holger Eckart/Baycom");
      d->model = corba_strdup("T7F/Baycom USB");
      d->copyright = corba_strdup("(C) 1999-2000 Holger Eckart/Baycom");
      d->instid = corba_strdup(servant->serial);
      d->rssimin = RSSI_MIN;
      d->rssimax = RSSI_MAX;
      d->rxbands._maximum = d->rxbands._length = 1;
      d->rxbands._buffer = CORBA_sequence_Trx_TrxBandDescription_allocbuf(1);
      CORBA_sequence_set_release(&d->rxbands, CORBA_TRUE);
      d->rxbands._buffer[0].low  = 430000000;
      d->rxbands._buffer[0].high = 440000000;
      d->rxbands._buffer[0].step =     12500;
      d->txbands._maximum = d->txbands._length = 1;
      d->txbands._buffer = CORBA_sequence_Trx_TrxBandDescription_allocbuf(1);
      CORBA_sequence_set_release(&d->txbands, CORBA_TRUE);
      d->txbands._buffer[0].low  = 430000000;
      d->txbands._buffer[0].high = 440000000;
      d->txbands._buffer[0].step =     12500;
}




static void
impl_Trx_Control_GetState(impl_POA_Trx_Control * servant,
                          Trx_TrxState * state, CORBA_Environment * ev)
{
      acquire_trxdata_mutex(servant);
      switch (servant->mode) {
      case MODE_FSK:
      case MODE_AFSK:
      case MODE_EXTERNAL:
            state->mode = Trx_trxpacket;
            break;

      case MODE_AUDIO:
            state->mode = Trx_trxaudio;
            break;

      default:
            state->mode = Trx_trxunspec;
      }
      if (servant->flags & (FLG_T7FERROR | FLG_MODEMERROR)) {
            state->rxfreq = 0;
            state->txfreq = 0;
      } else {
            state->rxfreq = 430000000 + 12500*servant->rxdiv;
            state->txfreq = 430000000 + 12500*servant->txdiv;
      }
      state->ptt = servant->ptt ? CORBA_TRUE : CORBA_FALSE;
      state->manualptt = (servant->flags & FLG_MANUALPTT) ? CORBA_TRUE : CORBA_FALSE;
      state->dcd = servant->dcd ? CORBA_TRUE : CORBA_FALSE;
      state->rssi = RSSI_MIN+(servant->rssi*((RSSI_MAX-RSSI_MIN)/255.0));
      release_trxdata_mutex(servant);
}

static void
impl_Trx_Control_SetPTT(impl_POA_Trx_Control * servant,
                        CORBA_boolean ptt, CORBA_Environment * ev)
{
      acquire_trxdata_mutex(servant);
      if (ptt)
            servant->flags |= FLG_MANUALPTT;
      else
            servant->flags &= ~FLG_MANUALPTT;
      servant->flags |= FLG_SETPTT;
      release_trxdata_mutex(servant);
}

static void
impl_Trx_Control_SetFrequency(impl_POA_Trx_Control * servant,
                              Trx_frequency rx,
                              Trx_frequency tx, CORBA_Environment * ev)
{
      unsigned int dr, dt;

      if (rx < 430000000)
            rx = 0;
      else
            rx -= (430000000-12500/2);
      if (tx < 430000000)
            tx = 0;
      else
            tx -= (430000000-12500/2);
      if (rx > 10000000)
            dr = 800;
      else
            dr = ((unsigned int)rx) / 12500;
      if (tx > 10000000)
            dt = 800;
      else
            dt = ((unsigned int)tx) / 12500;
      acquire_trxdata_mutex(servant);
      servant->newrxdiv = dr;
      servant->newtxdiv = dt;
      servant->flags |= FLG_SETFREQ | FLG_SAVECONFIG;
      servant->cfg.freq.rx = 430000000 + 12500 * dr;
      servant->cfg.freq.tx = 430000000 + 12500 * dt;
      release_trxdata_mutex(servant);
}

static void
impl_Trx_Control_UartSend(impl_POA_Trx_Control * servant,
                          CORBA_char * str, CORBA_Environment * ev)
{
      int r;

      if (!str)
            return;
      acquire_trxdata_mutex(servant);
      r = addtxfifo(servant, str, strlen(str));
      release_trxdata_mutex(servant);
      if (r)
            raise_exception(ev, "FIFO full");
}

static void
impl_Trx_Control_UartReceive(impl_POA_Trx_Control * servant,
                             CORBA_unsigned_long * ptr,
                             CORBA_char ** str, CORBA_Environment * ev)
{
      CORBA_char *cp;
      unsigned int i;

      cp = CORBA_string_alloc(512);
      acquire_trxdata_mutex(servant);
      i = getrxfifo(servant, ptr, cp, 512-1);
      release_trxdata_mutex(servant);
      cp[i] = 0;
      *str = cp;
}

static void
impl_Trx_Control_BaycomUSBAdapterGetConfig(impl_POA_Trx_Control * servant,
                                           Trx_BaycomUSBAdapterConfig * cfg,
                                           CORBA_Environment * ev)
{
      acquire_trxdata_mutex(servant);
      switch (servant->cfg.adapt.mode) {
      case trxapi_baycomusb_mode_external:
            cfg->mode = Trx_external;
              break;

      case trxapi_baycomusb_mode_afsk:
            cfg->mode = Trx_afsk;
              break;

      case trxapi_baycomusb_mode_audio:
            cfg->mode = Trx_audio;
              break;

      default:
            cfg->mode = Trx_fsk;
              break;
      }
      cfg->fclk = servant->cfg.adapt.fclk;
      cfg->bitraterx = servant->cfg.adapt.bitraterx;
      cfg->bitratetx = servant->cfg.adapt.bitratetx;
      switch (servant->cfg.adapt.loopback) {
      default:
            cfg->loopback = Trx_loopback_off;
            break;

      case trxapi_baycomusb_loopback_scrambler:
            cfg->loopback = Trx_loopback_scrambler;
            break;

      case trxapi_baycomusb_loopback_modem:
            cfg->loopback = Trx_loopback_modem;
            break;
      }
      cfg->pttmute = servant->cfg.adapt.pttmute;
      cfg->filtmode = servant->cfg.adapt.filtmode;
      cfg->samplerate = servant->cfg.adapt.samplerate;
      cfg->gain = servant->cfg.adapt.gain;
      strncpy(cfg->audiodevin, servant->cfg.adapt.audiodevin, sizeof(cfg->audiodevin));
      cfg->audiodevin[sizeof(cfg->audiodevin)-1] = 0;
      strncpy(cfg->audiodevout, servant->cfg.adapt.audiodevout, sizeof(cfg->audiodevout));
      cfg->audiodevout[sizeof(cfg->audiodevout)-1] = 0;
      cfg->rfsquelch = servant->cfg.adapt.rfsquelch;
      cfg->audiosquelch = servant->cfg.adapt.audiosquelch;
      release_trxdata_mutex(servant);
}

static void
impl_Trx_Control_BaycomUSBAdapterSetConfig(impl_POA_Trx_Control * servant,
                                           Trx_BaycomUSBAdapterConfig * cfg,
                                           CORBA_Environment * ev)
{
      struct trxapi_baycomusb_adapter_config cf;
      unsigned char rfsq;

      acquire_trxdata_mutex(servant);
      /* clamp values */
      if (cfg->rfsquelch <= RSSI_MIN) {
            cfg->rfsquelch = RSSI_MIN;
            rfsq = 0;
      } else if (cfg->rfsquelch >= RSSI_MAX) {
            cfg->rfsquelch = RSSI_MAX;
            rfsq = 255;
      } else
            rfsq = (cfg->rfsquelch - RSSI_MIN) * (255.0/(RSSI_MAX-RSSI_MIN));
#if defined(WIN32) || defined(USERMODEDRV)
      servant->audioparam.rfsquelch = rfsq;
#endif
      /* check for significant changes requiring modem reboot */
      servant->flags |= FLG_SAVECONFIG;
      switch (cfg->mode) {
      case Trx_external:
            cf.mode = trxapi_baycomusb_mode_external;
            break;

      case Trx_afsk:
            cf.mode = trxapi_baycomusb_mode_afsk;
            break;

      case Trx_audio:
            cf.mode = trxapi_baycomusb_mode_audio;
            break;

      default:
            cf.mode = trxapi_baycomusb_mode_fsk;
            break;
      }
      cf.fclk = cfg->fclk;
      cf.bitraterx = cfg->bitraterx;
      cf.bitratetx = cfg->bitratetx;
      switch (cfg->loopback) {
      default:
            cf.loopback = trxapi_baycomusb_loopback_off;
            break;

      case Trx_loopback_scrambler:
            cf.loopback = trxapi_baycomusb_loopback_scrambler;
            break;

      case Trx_loopback_modem:
            cf.loopback = trxapi_baycomusb_loopback_modem;
            break;
      }
      cf.pttmute = cfg->pttmute;
      cf.filtmode = cfg->filtmode;
      cf.samplerate = cfg->samplerate;
      cf.gain = cfg->gain;
      strncpy(cf.audiodevin, cfg->audiodevin, sizeof(cf.audiodevin));
      cf.audiodevin[sizeof(cf.audiodevin)-1] = 0;
      strncpy(cf.audiodevout, cfg->audiodevout, sizeof(cf.audiodevout));
      cf.audiodevout[sizeof(cf.audiodevout)-1] = 0;
      cf.rfsquelch = cfg->rfsquelch;
      cf.audiosquelch = cfg->audiosquelch;
      if (checkreload_adapt(servant, &cf))
            servant->flags |= FLG_RELOADMODEM;
      servant->cfg.adapt = cf;
      release_trxdata_mutex(servant);
}

static void
impl_Trx_Control_BaycomUSBAdapterGetAudioDevices(impl_POA_Trx_Control *
                                                 servant,
                                                 Trx_BaycomUSBAdapterAudioDevs
                                                 ** devs,
                                                 CORBA_Environment * ev)
{
      Trx_BaycomUSBAdapterAudioDevs *d;
      struct trxapi_baycomusb_adapter_audio_devs *ad;
      unsigned int i;

      *devs = NULL;
      ad = audio_get_device_list();
      if (!ad) {
            raise_exception(ev, "not implemented");
            return;
      }
      *devs = d = Trx_BaycomUSBAdapterAudioDevs__alloc();
      if (!d) {
            free(ad);
            raise_exception(ev, "out of memory");
            return;
      }
      d->audiodevsin._maximum = d->audiodevsin._length = ad->nraudiodevsin;
      d->audiodevsout._maximum = d->audiodevsout._length = ad->nraudiodevsout;
      d->audiodevsin._buffer = CORBA_sequence_Trx_BaycomUSBAdapterAudioDev_allocbuf(d->audiodevsin._length);
      CORBA_sequence_set_release(&d->audiodevsin, CORBA_TRUE);
      d->audiodevsout._buffer = CORBA_sequence_Trx_BaycomUSBAdapterAudioDev_allocbuf(d->audiodevsout._length);
      CORBA_sequence_set_release(&d->audiodevsout, CORBA_TRUE);
      for (i = 0; i < d->audiodevsin._length; i++)
            strncpy(d->audiodevsin._buffer[i], ad->audiodevsin[i], sizeof(d->audiodevsin._buffer[i]));
      for (i = 0; i < d->audiodevsout._length; i++)
            strncpy(d->audiodevsout._buffer[i], ad->audiodevsout[i], sizeof(d->audiodevsout._buffer[i]));
      free(ad);
}

static void
impl_Trx_Control_ModemDisconnectGetConfig(impl_POA_Trx_Control * servant,
                                          Trx_ModemDisconnectConfig * cfg,
                                          CORBA_Environment * ev)
{
      acquire_trxdata_mutex(servant);
      cfg->output = servant->cfg.mdisc.output;
      cfg->direction = servant->cfg.mdisc.direction;
      switch (servant->cfg.mdisc.rxc) {
      default:
            cfg->rxc = Trx_mdisc_rxc_normal;
            break;

      case trxapi_modem_disconnect_rxc_rxclock:
            cfg->rxc = Trx_mdisc_rxc_rxclock;
            break;
      }
      switch (servant->cfg.mdisc.txc) {
      default:
            cfg->txc = Trx_mdisc_txc_normal;
            break;

      case trxapi_modem_disconnect_txc_txclock:
            cfg->txc = Trx_mdisc_txc_txclock;
            break;
      }
      switch (servant->cfg.mdisc.txd) {
      default:
            cfg->txd = Trx_mdisc_txd_normal;
            break;

      case trxapi_modem_disconnect_txd_txdata:
            cfg->txd = Trx_mdisc_txd_txdata;
            break;
      }
      release_trxdata_mutex(servant);
}

static void
impl_Trx_Control_ModemDisconnectSetConfig(impl_POA_Trx_Control * servant,
                                          Trx_ModemDisconnectConfig * cfg,
                                          CORBA_Environment * ev)
{
      struct trxapi_modem_disconnect_config cf;

      cf.output = cfg->output;
      cf.direction = cfg->direction;
      switch (cfg->rxc) {
      default:
            cf.rxc = trxapi_modem_disconnect_rxc_normal;
            break;

      case Trx_mdisc_rxc_rxclock:
            cf.rxc = trxapi_modem_disconnect_rxc_rxclock;
            break;
      }
      switch (cfg->txc) {
      default:
            cf.txc = trxapi_modem_disconnect_txc_normal;
            break;

      case Trx_mdisc_txc_txclock:
            cf.txc = trxapi_modem_disconnect_txc_txclock;
            break;
      }
      switch (cfg->txd) {
      default:
            cf.txd = trxapi_modem_disconnect_txd_normal;
            break;

      case Trx_mdisc_txd_txdata:
            cf.txd = trxapi_modem_disconnect_txd_txdata;
            break;
      }
      acquire_trxdata_mutex(servant);
      if (checkreload_mdisc(servant, &cf))
            servant->flags |= FLG_RELOADMODEM;
      servant->cfg.mdisc = cf;
      servant->flags |= FLG_SETMDISCDIR | FLG_SETMDISCOUT;
      release_trxdata_mutex(servant);
}

#if !defined(WIN32)

static void
impl_Trx_Control_ChannelAccessGetConfig(impl_POA_Trx_Control * servant,
                                        Trx_ChannelAccessConfig * cfg,
                                        CORBA_Environment * ev)
{
      acquire_trxdata_mutex(servant);
      cfg->txdelay = servant->cfg.chacc.txdelay;
      cfg->slottime = servant->cfg.chacc.slottime;
      cfg->ppersistence = servant->cfg.chacc.ppersistence;
      cfg->txtail = servant->cfg.chacc.txtail;
      cfg->fullduplex = servant->cfg.chacc.fullduplex;
      release_trxdata_mutex(servant);
}

static void
impl_Trx_Control_ChannelAccessSetConfig(impl_POA_Trx_Control * servant,
                                        Trx_ChannelAccessConfig * cfg,
                                        CORBA_Environment * ev)
{
      acquire_trxdata_mutex(servant);
      servant->cfg.chacc.txdelay = cfg->txdelay;
      servant->cfg.chacc.slottime = cfg->slottime;
      servant->cfg.chacc.ppersistence = cfg->ppersistence;
      servant->cfg.chacc.txtail = cfg->txtail;
      servant->cfg.chacc.fullduplex = cfg->fullduplex;
      servant->flags |= FLG_RECONFCHACC | FLG_SAVECONFIG;
      release_trxdata_mutex(servant);
}

static void
impl_Trx_Control_InterfaceGetConfig(impl_POA_Trx_Control * servant,
                                    Trx_InterfaceConfig * cfg,
                                    CORBA_Environment * ev)
{
      acquire_trxdata_mutex(servant);
      strncpy(cfg->ifname, servant->cfg.intf.ifname, sizeof(cfg->ifname));
      cfg->ifname[sizeof(cfg->ifname)-1] = 0;
      strncpy(cfg->hwaddr, servant->cfg.intf.hwaddr, sizeof(cfg->hwaddr));
      cfg->hwaddr[sizeof(cfg->hwaddr)-1] = 0;
      cfg->ipaddr[0] = servant->cfg.intf.ipaddr[0];
      cfg->ipaddr[1] = servant->cfg.intf.ipaddr[1];
      cfg->ipaddr[2] = servant->cfg.intf.ipaddr[2];
      cfg->ipaddr[3] = servant->cfg.intf.ipaddr[3];
      cfg->netmask[0] = servant->cfg.intf.netmask[0];
      cfg->netmask[1] = servant->cfg.intf.netmask[1];
      cfg->netmask[2] = servant->cfg.intf.netmask[2];
      cfg->netmask[3] = servant->cfg.intf.netmask[3];
      cfg->broadcast[0] = servant->cfg.intf.broadcast[0];
      cfg->broadcast[1] = servant->cfg.intf.broadcast[1];
      cfg->broadcast[2] = servant->cfg.intf.broadcast[2];
      cfg->broadcast[3] = servant->cfg.intf.broadcast[3];
      strncpy(cfg->gwhwaddr, servant->cfg.intf.gwhwaddr, sizeof(cfg->gwhwaddr));
      cfg->gwhwaddr[sizeof(cfg->gwhwaddr)-1] = 0;
      cfg->gwipaddr[0] = servant->cfg.intf.gwipaddr[0];
      cfg->gwipaddr[1] = servant->cfg.intf.gwipaddr[1];
      cfg->gwipaddr[2] = servant->cfg.intf.gwipaddr[2];
      cfg->gwipaddr[3] = servant->cfg.intf.gwipaddr[3];
      cfg->gwnetmask[0] = servant->cfg.intf.gwnetmask[0];
      cfg->gwnetmask[1] = servant->cfg.intf.gwnetmask[1];
      cfg->gwnetmask[2] = servant->cfg.intf.gwnetmask[2];
      cfg->gwnetmask[3] = servant->cfg.intf.gwnetmask[3];
      cfg->gwipmode = servant->cfg.intf.gwipmode;
      release_trxdata_mutex(servant);
}

static void
impl_Trx_Control_InterfaceSetConfig(impl_POA_Trx_Control * servant,
                                    Trx_InterfaceConfig * cfg,
                                    CORBA_Environment * ev)
{
      acquire_trxdata_mutex(servant);
      strncpy(servant->cfg.intf.ifname, cfg->ifname, sizeof(servant->cfg.intf.ifname));
      servant->cfg.intf.ifname[sizeof(servant->cfg.intf.ifname)-1] = 0;
      strncpy(servant->cfg.intf.hwaddr, cfg->hwaddr, sizeof(servant->cfg.intf.hwaddr));
      servant->cfg.intf.hwaddr[sizeof(servant->cfg.intf.hwaddr)-1] = 0;
      servant->cfg.intf.ipaddr[0] = cfg->ipaddr[0];
      servant->cfg.intf.ipaddr[1] = cfg->ipaddr[1];
      servant->cfg.intf.ipaddr[2] = cfg->ipaddr[2];
      servant->cfg.intf.ipaddr[3] = cfg->ipaddr[3];
      servant->cfg.intf.netmask[0] = cfg->netmask[0];
      servant->cfg.intf.netmask[1] = cfg->netmask[1];
      servant->cfg.intf.netmask[2] = cfg->netmask[2];
      servant->cfg.intf.netmask[3] = cfg->netmask[3];
      servant->cfg.intf.broadcast[0] = cfg->broadcast[0];
      servant->cfg.intf.broadcast[1] = cfg->broadcast[1];
      servant->cfg.intf.broadcast[2] = cfg->broadcast[2];
      servant->cfg.intf.broadcast[3] = cfg->broadcast[3];
      strncpy(servant->cfg.intf.gwhwaddr, cfg->gwhwaddr, sizeof(servant->cfg.intf.gwhwaddr));
      servant->cfg.intf.gwhwaddr[sizeof(servant->cfg.intf.gwhwaddr)-1] = 0;
      servant->cfg.intf.gwipaddr[0] = cfg->gwipaddr[0];
      servant->cfg.intf.gwipaddr[1] = cfg->gwipaddr[1];
      servant->cfg.intf.gwipaddr[2] = cfg->gwipaddr[2];
      servant->cfg.intf.gwipaddr[3] = cfg->gwipaddr[3];
      servant->cfg.intf.gwnetmask[0] = cfg->gwnetmask[0];
      servant->cfg.intf.gwnetmask[1] = cfg->gwnetmask[1];
      servant->cfg.intf.gwnetmask[2] = cfg->gwnetmask[2];
      servant->cfg.intf.gwnetmask[3] = cfg->gwnetmask[3];
      servant->cfg.intf.gwipmode = cfg->gwipmode;
      servant->flags |= FLG_RECONFINTF | FLG_SAVECONFIG;
      release_trxdata_mutex(servant);
}

#else

static void
impl_Trx_Control_ChannelAccessGetConfig(impl_POA_Trx_Control * servant,
                                        Trx_ChannelAccessConfig * cfg,
                                        CORBA_Environment * ev)
{
      raise_exception(ev, "not implemented");
}

static void
impl_Trx_Control_ChannelAccessSetConfig(impl_POA_Trx_Control * servant,
                                        Trx_ChannelAccessConfig * cfg,
                                        CORBA_Environment * ev)
{
      raise_exception(ev, "not implemented");
}

static void
impl_Trx_Control_InterfaceGetConfig(impl_POA_Trx_Control * servant,
                                    Trx_InterfaceConfig * cfg,
                                    CORBA_Environment * ev)
{
      raise_exception(ev, "not implemented");
}

static void
impl_Trx_Control_InterfaceSetConfig(impl_POA_Trx_Control * servant,
                                    Trx_InterfaceConfig * cfg,
                                    CORBA_Environment * ev)
{
      raise_exception(ev, "not implemented");
}

#endif

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

#if !defined(WIN32) && !defined(USERMODEDRV)

static void
impl_Trx_Control_GetAudioState(impl_POA_Trx_Control * servant,
                               Trx_TrxAudioState * state,
                               CORBA_Environment * ev)
{
      raise_exception(ev, "not implemented");
}

static void
impl_Trx_Control_GetAudioMicSamples(impl_POA_Trx_Control * servant,
                                    CORBA_unsigned_long ptr,
                                    CORBA_unsigned_long len,
                                    Trx_TrxAudioSamples ** samples,
                                    CORBA_Environment * ev)
{
      raise_exception(ev, "not implemented");
}

static void
impl_Trx_Control_GetAudioSpkSamples(impl_POA_Trx_Control * servant,
                                    CORBA_unsigned_long ptr,
                                    CORBA_unsigned_long len,
                                    Trx_TrxAudioSamples ** samples,
                                    CORBA_Environment * ev)
{
      raise_exception(ev, "not implemented");
}

static void
impl_Trx_Control_SetAudioDTMF(impl_POA_Trx_Control * servant,
                              CORBA_long ch, CORBA_Environment * ev)
{
      raise_exception(ev, "not implemented");
}

static void
impl_Trx_Control_SetAudioParams(impl_POA_Trx_Control * servant,
                                Trx_TrxAudioParams * params,
                                CORBA_Environment * ev)
{
      raise_exception(ev, "not implemented");
}

#else

static void
impl_Trx_Control_GetAudioState(impl_POA_Trx_Control * servant,
                               Trx_TrxAudioState * state,
                               CORBA_Environment * ev)
{
      acquire_trxdata_mutex(servant);
      if (servant->mode != MODE_AUDIO) {
            raise_exception(ev, "invalid mode");
            goto out;
      }
      state->samplerate = AUDIOSAMPLINGRATE;
      state->micbufsz = sizeof(servant->du.a.isrc.abuf);
      state->micbufptr = servant->du.a.isrc.aptr;
      state->spkbufsz = sizeof(servant->du.a.osrc.abuf);
      state->spkbufptr = servant->du.a.osrc.aptr;
      state->micsigpwr = servant->du.a.isrc.sigpwr;
      state->spksigpwr = servant->du.a.osrc.sigpwr;
      state->spknoisepwr = servant->du.a.osrc.noisepwr;
  out:
      release_trxdata_mutex(servant);
}

static void
impl_Trx_Control_GetAudioSpkSamples(impl_POA_Trx_Control * servant,
                                    CORBA_unsigned_long ptr,
                                    CORBA_unsigned_long len,
                                    Trx_TrxAudioSamples ** samples,
                                    CORBA_Environment * ev)
{
      Trx_TrxAudioSamples *buf;
      unsigned int x;

      acquire_trxdata_mutex(servant);
      if (servant->mode != MODE_AUDIO) {
            raise_exception(ev, "invalid mode");
            goto out;
      }
      if (len > sizeof(servant->du.a.osrc.abuf) || ptr >= sizeof(servant->du.a.osrc.abuf)) {
            raise_exception(ev, "invalid parameter");
            goto out;
      }
      if (!(buf = Trx_TrxAudioSamples__alloc())) {
            raise_exception(ev, "out of memory");
            goto out;
      }
      *samples = buf;
      if (!len) {
            buf->_maximum = buf->_length = 0;
            buf->_buffer = NULL;
            CORBA_sequence_set_release(buf, CORBA_FALSE);
            goto out;
      }
      buf->_maximum = buf->_length = len;
      buf->_buffer = CORBA_sequence_CORBA_octet_allocbuf(len);
      CORBA_sequence_set_release(buf, CORBA_TRUE);
      x = sizeof(servant->du.a.osrc.abuf) - ptr;
      if (x > len)
            x = len;
            memcpy(buf->_buffer, &servant->du.a.osrc.abuf[ptr], x);
      len -= x;
      if (len)
            memcpy(&buf->_buffer[x], servant->du.a.osrc.abuf, len);
  out:
      release_trxdata_mutex(servant);
}

static void
impl_Trx_Control_GetAudioMicSamples(impl_POA_Trx_Control * servant,
                                    CORBA_unsigned_long ptr,
                                    CORBA_unsigned_long len,
                                    Trx_TrxAudioSamples ** samples,
                                    CORBA_Environment * ev)
{
      Trx_TrxAudioSamples *buf;
      unsigned int x;

      acquire_trxdata_mutex(servant);
      if (servant->mode != MODE_AUDIO) {
            raise_exception(ev, "invalid mode");
            goto out;
      }
      if (len > sizeof(servant->du.a.isrc.abuf) || ptr >= sizeof(servant->du.a.isrc.abuf)) {
            raise_exception(ev, "invalid parameter");
            goto out;
      }
      if (!(buf = Trx_TrxAudioSamples__alloc())) {
            raise_exception(ev, "out of memory");
            goto out;
      }
      *samples = buf;
      if (!len) {
            buf->_maximum = buf->_length = 0;
            buf->_buffer = NULL;
            CORBA_sequence_set_release(buf, CORBA_FALSE);
            goto out;
      }
      buf->_maximum = buf->_length = len;
      buf->_buffer = CORBA_sequence_CORBA_octet_allocbuf(len);
      CORBA_sequence_set_release(buf, CORBA_TRUE);
      x = sizeof(servant->du.a.isrc.abuf) - ptr;
      if (x > len)
            x = len;
            memcpy(buf->_buffer, &servant->du.a.isrc.abuf[ptr], x);
      len -= x;
      if (len)
            memcpy(&buf->_buffer[x], servant->du.a.isrc.abuf, len);
  out:
      release_trxdata_mutex(servant);
}

/*
 * char:
 * -1     off
 * 0..15  DTMF
 * 16     1750
 */

/*
 *
 * DTMF frequencies
 *
 *      1209 1336 1477 1633
 *  697   1    2    3    A
 *  770   4    5    6    B
 *  852   7    8    9    C
 *  941   *    0    #    D
 * 
 */

static void
impl_Trx_Control_SetAudioDTMF(impl_POA_Trx_Control * servant,
                              CORBA_long ch, CORBA_Environment * ev)
{
      static const unsigned char dtmftransl[0x10] = {
            0x13, 0x00, 0x10, 0x20, 0x01, 0x11, 0x21, 0x02,
            0x12, 0x22, 0x30, 0x31, 0x32, 0x33, 0x03, 0x23
      };
      static const unsigned int freqlogrp[4] = { 697, 770, 852, 941 };
      static const unsigned int freqhigrp[4] = { 1209, 1336, 1477, 1633 };
      unsigned int sr = servant->du.a.p.srateusb, freq0 = 0, freq1 = 0, tr;

      acquire_trxdata_mutex(servant);
      if (servant->mode != MODE_AUDIO) {
            raise_exception(ev, "invalid mode");
            goto out;
      }
      if (ch == 16) {
            if (sr > 0)
                  freq0 = (1750*65536 + sr/2) / sr;
      } else if (ch >= 0 && ch <= 15) {
            tr = dtmftransl[ch & 15];
            freq0 = (freqlogrp[tr & 15]*65536+sr/2)/sr;
            freq1 = (freqhigrp[tr >> 4]*65536+sr/2)/sr;
      } else if (ch != -1) {
            raise_exception(ev, "invalid parameter");
            goto out;
      }
      servant->du.a.isrc.freq0 = freq0;
      servant->du.a.isrc.freq1 = freq1;
      servant->du.a.isrc.ph0 = 0;
      servant->du.a.isrc.ph1 = 0;
  out:
      release_trxdata_mutex(servant);
}

static void
impl_Trx_Control_SetAudioParams(impl_POA_Trx_Control * servant,
                                Trx_TrxAudioParams * params,
                                CORBA_Environment * ev)
{
      if (params->rfsquelch <= RSSI_MIN)
            servant->audioparam.rfsquelch = 0;
      else if (params->rfsquelch >= RSSI_MAX)
            servant->audioparam.rfsquelch = 255;
      else
            servant->audioparam.rfsquelch = (params->rfsquelch - RSSI_MIN) * (255.0/(RSSI_MAX-RSSI_MIN));
      servant->audioparam.audiosquelch = params->audiosquelch;
}

#endif

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

/*** epv structures ***/

static PortableServer_ServantBase__epv impl_Trx_Control_base_epv = {
      NULL,                        /* _private data */
      NULL,                        /* finalize routine */
      NULL,                        /* default_POA routine */
};

static POA_Trx_Control__epv impl_Trx_Control_epv = {
      NULL,                        /* _private */
        (gpointer) & impl_Trx_Control_GetDescription,
        (gpointer) & impl_Trx_Control_GetState,
        (gpointer) & impl_Trx_Control_SetPTT,
        (gpointer) & impl_Trx_Control_SetFrequency,
        (gpointer) & impl_Trx_Control_UartSend,
        (gpointer) & impl_Trx_Control_UartReceive,
      (gpointer) & impl_Trx_Control_BaycomUSBAdapterGetConfig,
        (gpointer) & impl_Trx_Control_BaycomUSBAdapterSetConfig,
      (gpointer) & impl_Trx_Control_BaycomUSBAdapterGetAudioDevices,
        (gpointer) & impl_Trx_Control_ChannelAccessGetConfig,
        (gpointer) & impl_Trx_Control_ChannelAccessSetConfig,
        (gpointer) & impl_Trx_Control_InterfaceGetConfig,
        (gpointer) & impl_Trx_Control_InterfaceSetConfig,
        (gpointer) & impl_Trx_Control_ModemDisconnectGetConfig,
        (gpointer) & impl_Trx_Control_ModemDisconnectSetConfig,
      (gpointer) & impl_Trx_Control_GetAudioState,
      (gpointer) & impl_Trx_Control_GetAudioMicSamples,
      (gpointer) & impl_Trx_Control_GetAudioSpkSamples,
      (gpointer) & impl_Trx_Control_SetAudioDTMF,
      (gpointer) & impl_Trx_Control_SetAudioParams,
};

/*** vepv structures ***/

static POA_Trx_Control__vepv impl_Trx_Control_vepv = {
      &impl_Trx_Control_base_epv,
      &impl_Trx_Control_epv,
};

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

#if defined(WIN32)

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(1, "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(IORREGHKEY, name, 0, KEY_ALL_ACCESS, &key)) != ERROR_SUCCESS) {
                lprintf(1, "RegOpenKeyEx(%s) returned 0x%lx\n", name, err);
                return -1;
        }
        ret = deletekeyx(key);
        RegCloseKey(key);
        RegDeleteKey(IORREGHKEY, name);
        return ret;
}

int publishior(struct trx_thread_state *state)
{
        HKEY key, key2;
        DWORD err;


      snprintf(state->iorrname, sizeof(state->iorrname), "%08X", g_str_hash(state->ior));
        if ((err = RegCreateKeyEx(IORREGHKEY, IORREGPATH, 0, "", 0, KEY_ALL_ACCESS, NULL, &key, NULL)) != ERROR_SUCCESS) {
                lprintf(1, "RegCreateKeyEx(" IORREGPATH ") returned 0x%lx\n", err);
                return -1;
        }
      if ((err = RegCreateKeyEx(key, state->iorrname, 0, "", REG_OPTION_VOLATILE, KEY_WRITE, NULL, &key2, NULL)) != ERROR_SUCCESS) {
                lprintf(1, "RegCreateKeyEx(%s) returned 0x%lx\n", state->ior, err);
                return -1;
        }
        err = RegSetValueEx(key2, "IOR", 0, REG_SZ, state->ior, strlen(state->ior)+1);
        RegCloseKey(key2);
        RegCloseKey(key);
        if (err != ERROR_SUCCESS) {
                lprintf(1, "RegSetValueEx(IOR,%s) returned 0x%lx\n", state->ior, err);
                return -1;
        }
      return 0;
}

int unpublishior(struct trx_thread_state *state)
{
        char name[256];

      snprintf(name, sizeof(name), "%s\\%s", IORREGPATH, state->iorrname);
      deletekey(name);
      return 0;
}

#else

int publishior(struct trx_thread_state *state)
{
      int fd;
      FILE *f;

      strncpy(state->iorfname, IORIDPATH "/trx-XXXXXX", sizeof(state->iorfname));
      fd = mkstemp(state->iorfname);
      if (fd == -1) {
            state->iorfname[0] = 0;
            lprintf(1, "publish IOR %s failed %s (%u)\n", state->ior, strerror(errno), errno);
            return -1;
      }
      fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
      if (!(f = fdopen(fd, "w"))) {
            lprintf(1, "publish IOR %s failed %s (%u)\n", state->ior, strerror(errno), errno);
            close(fd);
            return -1;
      }
      fprintf(f, "%s\n", state->ior);
      fclose(f);
      return 0;
}

int unpublishior(struct trx_thread_state *state)
{
      if (unlink(state->iorfname) == -1) {
            lprintf(1, "unpublish IOR %s failed %s (%u)\n", state->ior, strerror(errno), errno);
            return -1;
      }
      return 0;
}

#endif

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

void init_object(struct trx_thread_state *state)
{
      Trx_Control obj;
      PortableServer_ObjectId *objid;
      CORBA_Environment ev;
      char *str;

      state->servant.vepv = &impl_Trx_Control_vepv;
      state->poa = poa;
      acquire_orbit_mutex();
      CORBA_exception_init(&ev);
      POA_Trx_Control__init((PortableServer_Servant)state, &ev);
      objid = PortableServer_POA_activate_object(poa, state, &ev);
      CORBA_free(objid);
      obj = PortableServer_POA_servant_to_reference(poa, state, &ev);
      str = CORBA_ORB_object_to_string(orb, obj, &ev);
      strncpy(state->ior, str, sizeof(state->ior));
      CORBA_free(str);
      lprintf(5, "New object: %s\n", state->ior);
      publishior(state);
      CORBA_Object_release(obj, &ev);
      if (ev._major != CORBA_NO_EXCEPTION)
            lprintf(1, "Error during object initialization\n");
      release_orbit_mutex();
}

void destroy_object(struct trx_thread_state *state)
{
      PortableServer_ObjectId *objid;
      CORBA_Environment ev;

      acquire_orbit_mutex();
      CORBA_exception_init(&ev);
      lprintf(5, "Destroying object: %s\n", state->ior);
      unpublishior(state);
      objid = PortableServer_POA_servant_to_id(state->poa, state, &ev);
      PortableServer_POA_deactivate_object(state->poa, objid, &ev);
      CORBA_free(objid);
      POA_Trx_Control__fini((PortableServer_Servant)state, &ev);
      if (ev._major != CORBA_NO_EXCEPTION)
            lprintf(1, "Error during object finalization\n");
      release_orbit_mutex();

}

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

int server_init1(int *argc, char **argv)
{
      CORBA_Environment ev;
      PortableServer_POAManager poamgr;

      /* init CORBA exception handling */
      CORBA_exception_init(&ev);
      /* normal ORB init */
      orb = CORBA_ORB_init(argc, argv, "orbit-local-orb", &ev);
      if (ev._major != CORBA_NO_EXCEPTION) {
            lprintf(0, "cannot initialize CORBA ORB\n");
            return -1;
      }
      poa = (PortableServer_POA)CORBA_ORB_resolve_initial_references(orb, "RootPOA", &ev);
      if (ev._major != CORBA_NO_EXCEPTION) {
            lprintf(0, "cannot resolve initial CORBA references\n");
            return -1;
      }
      poamgr = PortableServer_POA__get_the_POAManager(poa, &ev);
      if (ev._major != CORBA_NO_EXCEPTION) {
            lprintf(0, "cannot get the CORBA POA manager\n");
            return -1;
      }
      PortableServer_POAManager_activate(poamgr, &ev);
      if (ev._major != CORBA_NO_EXCEPTION) {
            lprintf(0, "cannot activate CORBA POA manager\n");
            return -1;
      }
            return 0;
}

int server_init2(void)
{
      CORBA_Environment ev;
      
#if defined(WIN32)
      deletekey(IORREGPATH);
#endif
      CORBA_exception_init(&ev);
        acquire_orbit_mutex();
        ORBit_custom_run_setup(orb, &ev);
        release_orbit_mutex();
      if (ev._major == CORBA_NO_EXCEPTION)
            return 0;
      CORBA_exception_free(&ev);
      return 1;
}

Generated by  Doxygen 1.6.0   Back to index