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

eiconctrl.c

/* $Id: eiconctrl.c,v 1.22 2001/03/01 14:59:12 paul Exp $
 *
 * Eicon-ISDN driver for Linux. (Control-Utility)
 *
 * Copyright 1998      by Fritz Elfert (fritz@isdn4linux.de)
 * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
 * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
 *
 * 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, 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. 
 *
 * $Log: eiconctrl.c,v $
 * Revision 1.22  2001/03/01 14:59:12  paul
 * Various patches to fix errors when using the newest glibc,
 * replaced use of insecure tempnam() function
 * and to remove warnings etc.
 *
 * Revision 1.21  2000/12/02 21:39:42  armin
 * Update of load and log utility.
 * New firmware and NT mode for PRI card.
 *
 * Revision 1.20  2000/07/08 14:18:52  armin
 * Changes for devfs.
 *
 * Revision 1.19  2000/06/12 12:29:06  armin
 * removed compiler warnings.
 *
 * Revision 1.18  2000/06/08 20:56:42  armin
 * added checking for card id.
 *
 * Revision 1.17  2000/06/08 08:31:03  armin
 * corrected tei parameter option
 *
 * Revision 1.16  2000/06/07 21:08:35  armin
 * Fixed OAD, OSA and SPID parameter setting.
 *
 * Revision 1.15  2000/04/24 07:53:03  armin
 * Extended interface to divaload.
 *
 * Revision 1.14  2000/03/25 12:56:40  armin
 * First checkin of new version 2.0
 * - support for 4BRI, includes orig Eicon
 *   divautil files and firmware updated (only etsi).
 *
 * Revision 1.13  2000/02/12 14:01:32  armin
 * Version 1.2
 * Added write function to management interface.
 * Fixed too small log buffer for isdnlog.
 *
 * Revision 1.12  2000/01/26 18:35:05  armin
 * New version of control utility.
 * Added activate-function for isdnlog trace information.
 *
 * Revision 1.11  2000/01/24 19:57:37  armin
 * Added INSTALL and README file.
 * Some updates and new option for configure script.
 *
 * Revision 1.10  2000/01/12 07:05:09  armin
 * Fixed error on loading old S card.
 *
 * Revision 1.9  1999/11/21 12:41:25  armin
 * Added further check for future driver changes.
 *
 * Revision 1.8  1999/10/12 18:01:52  armin
 * Backward compatible to older driver versions.
 *
 * Revision 1.7  1999/09/06 08:03:24  fritz
 * Changed my mail-address.
 *
 * Revision 1.6  1999/08/18 20:20:45  armin
 * Added XLOG functions for all cards.
 *
 * Revision 1.5  1999/03/29 11:05:23  armin
 * Installing and Loading the old type Eicon ISA-cards.
 * New firmware in one tgz-file.
 * Commandline Management Interface.
 *
 * Revision 1.4  1999/03/02 11:35:57  armin
 * Change of email address.
 *
 * Revision 1.3  1999/02/25 22:35:14  armin
 * Did not compile with new version.
 *
 * Revision 1.2  1999/01/20 21:16:45  armin
 * Added some debugging features.
 *
 * Revision 1.1  1999/01/01 17:27:57  armin
 * First checkin of new created control utility for Eicon.Diehl driver.
 * diehlctrl is obsolete.
 *
 *
 */

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <malloc.h>
#include <ctype.h>
#include <signal.h>
#ifdef HAVE_NCURSES_H
#     include <ncurses.h>
#endif
#ifdef HAVE_CURSES_H
#     include <curses.h>
#endif
#ifdef HAVE_CURSES_NCURSES_H
#     include <curses/ncurses.h>
#endif
#ifdef HAVE_NCURSES_CURSES_H
#     include <ncurses/curses.h>
#endif


#include <linux/types.h>
#include <linux/isdn.h>
#include <eicon.h>


#define COMBIFILE "dspdload.bin"

#define MIN(a,b) ((a)>(b) ? (b) : (a))

#define EICON_CTRL_VERSION 2 

char *cmd;
int verbose = 0;
eicon_manifbuf *mb;

WINDOW *statwin;
WINDOW *headwin;
static int h_line;
static int stat_y;

#ifdef HAVE_NPCI 
/* old driver Release < 2.0 */

int num_directory_entries;
int usage_mask_size;
int download_count;
int directory_size;
int usage_bit;
int usage_byte;
__u32 table_count = 0;
unsigned int no_of_downloads = 0;
int total_bytes_in_download = 0;
__u32 download_pos;
t_dsp_download_desc p_download_table[35];
char *no_of_tables;

#else
/* new driver Release >= 2.0 */

extern char DrvID[];

extern int Divaload_main(int, char **); 
#include <divas.h>

#endif

int fd;
isdn_ioctl_struct ioctl_s;

char protoname[1024];
char Man_Path[160];
int  man_ent_count;

00185 struct man_s {
      u_char type;
      u_char attribute;
      u_char status;
      u_char var_length;
      u_char path_length;
      char   Name[180];
      char   Var[180];
} man_ent[60];

char *spid_state[] =
{
  "Idle",
  "Up",
  "Disconnecting",
  "Connecting",
  "SPID Initializing",
  "SPID Initialized",
  "UNKNOWN STATE"
};


#if HAVE_XLOG || HAVE_TRACE
/*********** XLOG stuff **********/

#define byte __u8
#define word __u16
#define dword __u32

/* #define SWAP(a) ((((a) & 0xff) << 8) | (((a) &0xff00)>>8)) */
#define SWAP(a) (a)

/*********** XLOG stuff end **********/
#endif /* XLOG */

__u16 xlog(FILE * stream,void * buffer);

void eiconctrl_usage() {
  fprintf(stderr,"Eiconctrl Utility Version 2.3                      (c) 2000 Cytronics & Melware\n");
  fprintf(stderr,"usage: %s add <DriverID> <membase> <irq>              (add card)\n",cmd);
  fprintf(stderr,"   or: %s [-d <DriverID>] membase [membase-addr]      (get/set memaddr)\n",cmd);
  fprintf(stderr,"   or: %s [-d <DriverID>] irq   [irq-nr]              (get/set irq)\n",cmd);
  fprintf(stderr,"   or: %s [-d <DriverID>] [-v] load <protocol> [options]\n",cmd);
  fprintf(stderr,"   or: %s [-d <DriverID>] debug [<debug value>]\n",cmd);
  fprintf(stderr,"   or: %s [-d <DriverID>] manage [read|exec <path>]   (management-tool)\n",cmd);
#ifdef HAVE_TRACE
  fprintf(stderr,"   or: %s [-d <DriverID>] xlog [cont|<filename>]      (retrieve XLOG)\n",cmd);
  fprintf(stderr,"   or: %s [-d <DriverID>] isdnlog [on|off]            (D-Channel log)\n",cmd);
#else
#ifdef HAVE_XLOG
  fprintf(stderr,"   or: %s [-d <DriverID>] xlog [cont]                 (request XLOG)\n",cmd);
#endif
#endif
  fprintf(stderr,"load firmware:\n");
  fprintf(stderr," basics  : -d <DriverID> ID defined when eicon module was loaded/card added\n");
  fprintf(stderr,"         : -v            verbose\n");
  fprintf(stderr," options : -l[channel#]  channel allocation policy\n");
  fprintf(stderr,"         : -e            CRC4 Multiframe usage\n");
  fprintf(stderr,"         : -tTEI         use the fixed TEI\n");
  fprintf(stderr,"         : -h            no HSCX 30 mode (PRI only)\n");
  fprintf(stderr,"         : -n            NT2 mode\n");
  fprintf(stderr,"         : -p            leased line D channel\n");
  fprintf(stderr,"         : -s[0|1|2]     LAPD layer 2 session strategy\n");
  fprintf(stderr,"         : -o            allow disordered info elements\n");
  fprintf(stderr,"         : -z            switch to loopback mode\n");
#ifndef HAVE_NPCI
  fprintf(stderr,"Please use 'divaload' for DIVA Server options.\n");
#endif
  exit(-1);
}


#ifdef HAVE_NPCI
/*--------------------------------------------------------------
 * display_combifile_details()
 *
 * Displays the information in the combifile header
 * Arguments: Pointer to the combifile structure in memory
 * Returns:   The address of the begining of directory which is
 *            directly after the file description.
 *-------------------------------------------------------------*/

t_dsp_combifile_directory_entry *display_combifile_details(char *details)
{
        __u32 offset=0;
        t_dsp_combifile_header *file_header;
        char *description;
        t_dsp_combifile_directory_entry *return_ptr = NULL;

        file_header = (t_dsp_combifile_header *)details;

        printf("%s\n", file_header->format_identification);
#ifdef DEBUG 
        printf("\tFormat Version: 0x%.4x\n", file_header->format_version_bcd);
        printf("\tNumber of directory entries : %d\n", file_header->directory_entries);
        printf("\tDownload count: %d\n", file_header->download_count);
#endif

        description = (char *)file_header + (file_header->header_size);

        printf("%s\n", description);

        num_directory_entries = file_header->directory_entries;
        usage_mask_size = file_header->usage_mask_size;
        download_count = file_header->download_count;
        directory_size = file_header->directory_size;

        return_ptr = (t_dsp_combifile_directory_entry *) (unsigned long)file_header ;
        offset  += (file_header->header_size);
        offset  += (file_header->combifile_description_size);
        offset += (__u32)(unsigned long)return_ptr;

        return (t_dsp_combifile_directory_entry *)(unsigned long)offset;

}


__u32 store_download(char *data, __u16 size, char *store)
{
        __u16 real_size;
        static int first = 1;
        static char* position;
        static char* initial;
        static __u32 addr;
        __u32 data_start_addr;
        __u32 align;

#ifdef DEBUG
        printf("Writing Data to memory block\n");
#endif
                if(first)
                {
                addr = 0xa03a0000 + (((sizeof(__u32)+sizeof(p_download_table)) + ~0xfffffffc) & 0xfffffffc);
                position = initial = (char *)store;
                first = 0;
                }

/*Starting address to where the data is written in the download_block*/
      data_start_addr = addr;

        real_size = size;

        align = ((addr + (real_size + ~0xfffffffc)) & 0xfffffffc) -
                        (addr + real_size);

        memcpy(position, data, real_size);

        position += real_size;
        addr += real_size;

        bzero(position, align);

        position += align;
        addr += align;

        total_bytes_in_download = position - initial;

#ifdef DEBUG
        printf("total_bytes written so far is 0x%x\n",total_bytes_in_download);
      printf("align value for this download is: %d\n",align);
#endif
        return (data_start_addr);
}



__u32 get_download(char *download_block, char *download_area)
{
        int n, i;
      char Text[100];
        char *usage_mask;
        char test_byte=0;
        __u32 length=0;
        __u32 addr;
      unsigned int table_index;
        t_dsp_file_header *file_header;

        t_dsp_download_desc *p_download_desc;
        char *data;

      i=0;
        no_of_downloads = 0;
        test_byte = 0x01;
        test_byte <<= usage_bit;
        usage_mask = malloc(usage_mask_size);

        if(!usage_mask)
        {
                printf("Error allocating memory for usage mask");
                return 0;
        }
        bzero(usage_mask, usage_mask_size);

        for(n = 0; n < download_count; n++)
        {
                memcpy(usage_mask, download_area, usage_mask_size);
#ifdef DEBUG 
        printf("  \n");
                printf("Usage mask = 0x%.2x ", usage_mask[0]);
                if(usage_mask_size > 1)
                {
                        for(i=1; i<usage_mask_size; i++)
                        {
                                printf("0x%.2x ", usage_mask[i]);
                        }
                }
#endif
                download_area += usage_mask_size;

                file_header = (t_dsp_file_header *)download_area;
#ifdef DEBUG
                printf("%s %d\n", file_header->format_identification,n);
#endif

                if( test_byte & usage_mask[usage_byte] )
                {
                no_of_downloads++;
              table_index = (no_of_downloads - 1);

#ifdef DEBUG
                  printf("*****DSP DOWNLOAD %d REQUIRED******\n", n);
                printf("download required count is now %d\n",no_of_downloads);
                  printf("   \n");
#endif


                  /*This is the length of the memory to malloc */

                        length += ((__u32)((__u16)((file_header->header_size)
                                                - sizeof(t_dsp_file_header))))
                        + ((__u32)(file_header->download_description_size))
                        + ((__u32)(file_header->memory_block_table_size))
                        + ((__u32)(file_header->segment_table_size))
                        + ((__u32)(file_header->symbol_table_size))
                        + ((__u32)(file_header->total_data_size_dm))
                        + ((__u32)(file_header->total_data_size_pm));

                        if(download_block)
                        {
                        data = (char *)file_header;
                        data += ((__u32)(file_header->header_size));

                                p_download_desc = &(p_download_table[table_index]);
                                p_download_desc->download_id = file_header->download_id;
                                p_download_desc->download_flags = file_header->download_flags;
                                p_download_desc->required_processing_power = file_header->required_processing_power;
                                p_download_desc->interface_channel_count = file_header->interface_channel_count;
                                p_download_desc->excess_header_size = ((__u16)((file_header->header_size) - (__u16)sizeof(t_dsp_file_header)));
                                p_download_desc->memory_block_count = file_header->memory_block_count;
                                p_download_desc->segment_count = file_header->segment_count;
                                p_download_desc->symbol_count = file_header->symbol_count;
                                p_download_desc->data_block_count_dm = file_header->data_block_count_dm;
                                p_download_desc->data_block_count_pm = file_header->data_block_count_pm;

                                p_download_desc->p_excess_header_data = NULL;
                                if (((p_download_desc->excess_header_size) != 0))
                                {
#ifdef DEBUG
                        printf("1.store_download called from get_download\n");
#endif
                                        addr = store_download(data, p_download_desc->excess_header_size,
                                                                                        download_block);
                                        p_download_desc->p_excess_header_data = (char *)(unsigned long)addr;
                                        data += ((p_download_desc->excess_header_size));
                                }
                                p_download_desc->p_download_description = NULL;
                                if (((file_header->download_description_size) != 0))
                                {
#ifdef DEBUG
                        printf("2.store_download called from get_download\n");
#endif
                                        addr = store_download(data, file_header->download_description_size,
                                                                                        download_block);
                        /* Showing details of DSP-Task */
                  if (verbose) {
                        strncpy(Text, data, file_header->download_description_size);
                        Text[file_header->download_description_size] = 0;
                        printf("\t%s\n", Text);
                  }

                                        p_download_desc->p_download_description = (char *)(unsigned long)addr;
                                        data += ((file_header->download_description_size));
                                }
                                p_download_desc->p_memory_block_table = NULL;
                                if ((file_header->memory_block_table_size) != 0)
                                {
#ifdef DEBUG
                        printf("3.store_download called from get_download\n");
#endif
                                        addr = store_download(data, file_header->memory_block_table_size,
                                                                                        download_block);
                                        p_download_desc->p_memory_block_table = (t_dsp_memory_block_desc *)(unsigned long)addr;
                                        data += ((file_header->memory_block_table_size));
                                }
                                p_download_desc->p_segment_table = NULL;
                                if ((file_header->segment_table_size) != 0)
                                {
#ifdef DEBUG
                        printf("4.store_download called from get_download\n");
#endif
                                        addr = store_download(data, file_header->segment_table_size,
                                                                                        download_block);
                                        p_download_desc->p_segment_table = (t_dsp_segment_desc *)(unsigned long)addr;
                                        data += (file_header->segment_table_size);
                                }
                                p_download_desc->p_symbol_table = NULL;
                                if ((file_header->symbol_table_size) != 0)
                                {
#ifdef DEBUG
                        printf("5.store_download called from get_download\n");
#endif
                                        addr = store_download(data, file_header->symbol_table_size,
                                                                                        download_block);
                                        p_download_desc->p_symbol_table = (t_dsp_symbol_desc *)(unsigned long)addr;
                                        data += (file_header->symbol_table_size);
                                }
                                p_download_desc->p_data_blocks_dm = NULL;
                                if ((file_header->total_data_size_dm) != 0)
                                {
#ifdef DEBUG
                        printf("6.store_download called from get_download\n");
#endif
                                        addr = store_download(data, file_header->total_data_size_dm,
                                                                                        download_block);
                                        p_download_desc->p_data_blocks_dm = (__u16 *)(unsigned long)addr;
                                        data += (file_header->total_data_size_dm);
                                }
                                p_download_desc->p_data_blocks_pm = NULL;
                                if ((file_header->total_data_size_pm) != 0)
                                {
#ifdef DEBUG
                        printf("7.store_download called from get_download\n");
#endif
                                        addr = store_download(data, file_header->total_data_size_pm,
                                                                                        download_block);
                                        p_download_desc->p_data_blocks_pm = (__u16 *)(unsigned long)addr;
                                        data += (file_header->total_data_size_pm);
                                }
                        }
                }

                download_area += ((__u32)((__u16)((file_header->header_size))));
                download_area += ((__u32)((file_header->download_description_size)));
                download_area += ((__u32)((file_header->memory_block_table_size)));
                download_area += ((__u32)((file_header->segment_table_size)));
                download_area += ((__u32)((file_header->symbol_table_size)));
                download_area += ((__u32)((file_header->total_data_size_dm)));
                download_area += ((__u32)((file_header->total_data_size_pm)));


        }

      table_count=no_of_downloads;
      /**no_of_tables=table_count;*/
      bzero(no_of_tables,sizeof(__u32));
      memcpy(no_of_tables,&table_count,sizeof(__u32));

#ifdef DEBUG
    printf("***0x%x bytes of memory required for %d downloads***\n", length, no_of_downloads);
#endif
        free(usage_mask);
        return length;
}


eicon_codebuf *load_combifile(int card_type, u_char *protobuf, int *plen)
{
        int fd;
      int tmp[9];
      char combifilename[100];
        int count, j;
        int file_set_number = 0;
        struct stat file_info;
        char *combifile_start;
        char *usage_mask_ptr;
        char *download_block;
        t_dsp_combifile_directory_entry *directory;
        t_dsp_combifile_directory_entry *tmp_directory;
        __u32 download_size;
      eicon_codebuf *cb;

      sprintf(combifilename, "%s/%s", DATADIR, COMBIFILE);
        if ((fd = open(combifilename, O_RDONLY, 0)) == -1)
        {
                perror("Error opening Eicon combifile");
                return(0);
        }

        if (fstat(fd, &file_info))
        {
                perror("Error geting file details of Eicon combifile");
                close(fd);
                return(0);
        }

        if ( file_info.st_size <= 0 )
        {
                perror("Invalid file length in Eicon combifile");
                close(fd);
                return(0);
        }

        combifile_start = malloc(file_info.st_size);

        if(!combifile_start)
        {
                perror("Error allocating memory for Eicon combifile");
                close(fd);
                return(0);
        }

#ifdef DEBUG
                printf("File mapped to address 0x%x\n", (__u32)combifile_start);
#endif


        if((read(fd, combifile_start, file_info.st_size)) != file_info.st_size)
        {
                perror("Error reading Eicon combifile into memory");
                free(combifile_start);
                close(fd);
                return(0);
        }

        close(fd); /* We're done with the file */

        directory = display_combifile_details(combifile_start);

#ifdef DEBUG
        printf("Directory mapped to address 0x%x, offset = 0x%x\n", (__u32)directory,
                                                ((unsigned int)directory - (unsigned int)combifile_start));
#endif

        tmp_directory = directory;

        for(count = 0; count < num_directory_entries; count++)
        {
                if((tmp_directory->card_type_number) == card_type)
                {
#ifdef DEBUG
                        printf("Found entry in directory slot %d\n", count);
                        printf("Matched Card %d is %d. Fileset number is %d\n", count,
                              (tmp_directory->card_type_number),
                              (tmp_directory->file_set_number));

#endif
                        file_set_number = tmp_directory->file_set_number;
                        break;
                }
#ifdef DEBUG
                printf("Card %d is %d. Fileset number is %d\n", count,
                                                (tmp_directory->card_type_number),
                                                (tmp_directory->file_set_number));
#endif
                tmp_directory++; 
        }

        if(count == num_directory_entries)
        {
                printf("Card not found in directory\n");
                free(combifile_start);
                return(0);
        }

        usage_bit = file_set_number%8;
        usage_byte= file_set_number/8;

#ifdef DEBUG
        printf("Bit field is bit %d in byte %d of the usage mask\n",
                                usage_bit,
                                usage_byte);
#endif

        usage_mask_ptr = (char *)(directory);
        usage_mask_ptr += directory_size;

#ifdef DEBUG
        printf("First mask at address 0x%x, offset = 0x%x\n", (__u32)usage_mask_ptr,
                                                (__u32)(usage_mask_ptr - combifile_start));
#endif

        no_of_tables = malloc((sizeof(__u32)));
        download_size = get_download(NULL, usage_mask_ptr);

#ifdef DEBUG
        printf("Initial size of download_size is 0x%x\n",download_size);
#endif

        if(!download_size)
        {
                printf("Error getting details on DSP downloads\n");
                free(combifile_start);
                return(0);
        }

        download_block = malloc((download_size + (no_of_downloads * 100)));

#ifdef DEBUG
        printf("download_block size = (download_size + alignments) is: 0x%x\n",(download_size + (no_of_downloads*100)));
#endif

        if(!download_block)
        {
                printf("Error allocating memory for download\n");
                free(combifile_start);
                return(0);
        }

#ifdef DEBUG
        printf("Calling get_download to write into download_block\n");
#endif

        if(!(get_download(download_block, usage_mask_ptr)))
        {
                printf("Error getting data for DSP download\n");
                free(download_block);
                free(combifile_start);
              free(no_of_tables);
                return(0);
        }

      tmp[0] = *plen;

      memcpy(protobuf + *plen, download_block, total_bytes_in_download);
      tmp[1] = total_bytes_in_download;
      *plen +=  total_bytes_in_download;

      memcpy(protobuf + *plen, no_of_tables, sizeof(table_count));
      tmp[2] = sizeof(table_count);
      *plen +=  sizeof(table_count);

      memcpy(protobuf + *plen, (char *)p_download_table, sizeof(p_download_table));
      tmp[3] = sizeof(p_download_table);
      *plen +=  sizeof(p_download_table);

      cb = malloc(sizeof(eicon_codebuf) + *plen);
      memset(cb, 0, sizeof(eicon_codebuf));
        memcpy(&cb->pci.code, protobuf, *plen);
      for (j=0; j < 4; j++) {
            if (j==0) cb->pci.protocol_len = tmp[0];
            else cb->pci.dsp_code_len[j] = tmp[j];
      }
      cb->pci.dsp_code_num = 3;

 free(no_of_tables);
 free(download_block);
 free(combifile_start);
 return (cb);
}
#endif /* NPCI */

void beep2(void)
{
 beep();
 fflush(stdout);
 refresh();
}

int write_manage_element(char *m_dir, int request, char *bval, int vlen, int type)
{
      int len, ret, i, j;
      long lval;
      byte *buf;

      if (strlen(m_dir)) {
            if (m_dir[0] == '\\') m_dir++;
      }
      len = strlen(m_dir);
        mb->count = request;
        mb->pos = 0;
        mb->length[0] = len + vlen + 5;
        memset(&mb->data, 0, 690);

      if (len)
              strncpy(&mb->data[5], m_dir, len);
        mb->data[4] = len;
        mb->data[3] = vlen;
      buf = &mb->data[5 + len];
      switch(type) {
            case 0x81:
                  if (1 != sscanf(bval, "%ld", &lval))
                        return(-1);
                  for (i=0; i<vlen; i++) buf[i] = (byte)(lval >> (8*i));
                  break;
            case 0x82:
                  if (1 != sscanf(bval, "%lu", &lval))
                        return(-1);
                  for (i=0; i<vlen; i++) buf[i] = (byte)(lval >> (8*i));
                  break;
            case 0x83:
                  if (1 != sscanf(bval, "%lx", &lval))
                        return(-1);
                  for (i=0; i<vlen; i++) buf[i] = (byte)(lval >> (8*i));
                  break;
            case 0x85:
                  if (1 != sscanf(bval, "%lu", &lval))
                        return(-1);
                  if ((lval < 0) || (lval > 1))
                        return(-1);
                  for (i=0; i<(vlen-1); i++) buf[i] = 0;
                  buf[i] = (byte)lval;
                  break;
            case 0x87:
                  for(i=0; i<vlen; i++) {
                        buf[vlen-i-1] = 0;
                        for(j=0; j<8; j++) {
                              buf[vlen-i-1] |= (bval[i*9+j] - '0') << (7-j);
                        }
                  }
                  break;
            default:
                  return(-1);
      }
        mb->data[0] = type;
        ioctl_s.arg = (ulong)mb;
        ret = ioctl(fd, EICON_IOCTL_MANIF + IIOCDRVCTL, &ioctl_s);
      return(ret);
}

int get_manage_element(char *m_dir, int request)
{
      int i,j,o,k,tmp;
      int len, vlen = 0;
      long unsigned duint;
      u_char buf[100];

      if (strlen(m_dir)) {
            if (m_dir[0] == '\\') m_dir++;
      }
      len = strlen(m_dir);
        mb->count = request;
        mb->pos = 0;
        mb->length[0] = len + 5;
        memset(&mb->data, 0, 690);

      if (len)
              strncpy(&mb->data[5], m_dir, len);
        mb->data[4] = len;

        ioctl_s.arg = (ulong)mb;
        if (ioctl(fd, EICON_IOCTL_MANIF + IIOCDRVCTL, &ioctl_s) < 0) {
            return(-1);
        }
      if (request == 0x04) return 0;

      mb->pos = 0;
      man_ent_count = mb->count;
        for (i = 0; i < mb->count; i++) {
            man_ent[i].type = mb->data[mb->pos++];
            man_ent[i].attribute = mb->data[mb->pos++];
            man_ent[i].status = mb->data[mb->pos++];
            man_ent[i].var_length = mb->data[mb->pos++];
            man_ent[i].path_length = mb->data[mb->pos++];

            memcpy(man_ent[i].Name, &mb->data[mb->pos] + len, man_ent[i].path_length - len);
            man_ent[i].Name[man_ent[i].path_length - len] = 0;
            if (man_ent[i].Name[0] == '\\') strcpy(man_ent[i].Name, man_ent[i].Name + 1);
            mb->pos += man_ent[i].path_length;

            if (man_ent[i].type &0x80) 
                  vlen = man_ent[i].var_length;
            else
                  vlen = mb->length[i] - man_ent[i].path_length - 5; 

            memcpy(man_ent[i].Var, &mb->data[mb->pos], vlen); 
            man_ent[i].Var[vlen] = 0;
            mb->pos += (mb->length[i]  - man_ent[i].path_length - 5);
            o = 0;
            if (vlen) {
                  switch(man_ent[i].type) {
                        case 0x04:
                              if (man_ent[i].Var[0])
                              {
                                    j=0;
                                    do
                                    {
                                          buf[o++] = man_ent[i].Var[++j];
                                          buf[o] = 0;
                                    }
                                    while (j < man_ent[i].Var[0]);
                                    strcpy(man_ent[i].Var, buf);
                              }
                              break;
                        case 0x05:
                              if (man_ent[i].Var[0])
                              {
                                    j=0;
                                    do
                                    {
                                          o+=sprintf(&buf[o],"%02x ",(__u8)man_ent[i].Var[++j]);
                                    }
                                    while (j < man_ent[i].Var[0]);
                                    strcpy(man_ent[i].Var, buf);
                              }
                              break;
                        case 0x81:
                              duint = man_ent[i].Var[vlen-1]&0x80 ? -1 : 0; 
                              for (j=0; j<vlen; j++) ((__u8 *)&duint)[j] = man_ent[i].Var[j];
                              sprintf(man_ent[i].Var,"%ld",(long)duint);
                              break;
                        case 0x82:
                              for (j=0,duint=0; j<vlen; j++) 
                                    duint += ((unsigned char)man_ent[i].Var[j]) << (8 * j);
                              sprintf(man_ent[i].Var,"%lu", duint);
                              break;
                        case 0x83:
                              for (j=0,duint=0; j<vlen; j++)
                                    duint += ((unsigned char)man_ent[i].Var[j]) << (8 * j);
                              sprintf(man_ent[i].Var,"%lx", duint);
                              break;
                        case 0x84:
                              for (j=0; j<vlen; j++) o+=sprintf(&buf[o], "%02x", man_ent[i].Var[j]);
                              strcpy(man_ent[i].Var, buf);
                              break;
                        case 0x85:
                              for (j=0,duint=0; j<vlen; j++)
                                    duint += ((unsigned char) man_ent[i].Var[j]) << (8 * j);
                              if (duint) sprintf(man_ent[i].Var,"TRUE");
                              else sprintf(man_ent[i].Var,"FALSE");
                              break;
                        case 0x86:
                              for (j=0; j<vlen; j++)
                              {
                                    if (j) o+=sprintf(&buf[o], ".");
                                    o+=sprintf(&buf[o], "%03i", man_ent[i].Var[j]);
                              }
                              strcpy(man_ent[i].Var, buf);
                              break;
                        case 0x87:
                              for (j=0,duint=0; j<vlen; j++)
                                    duint += ((unsigned char) man_ent[i].Var[j]) << (8 * j);
                              for (j=0; j<vlen; j++)
                              {
                                    if (j) o+=sprintf(&buf[o], " ");
                                    tmp = (__u8)(duint >> (vlen-j-1)*8);
                                    for (k=0; k<8; k++)
                                    {
                                          o+=sprintf(&buf[o], "%d", (tmp >> (7-k)) &0x1);
                                    }
                              }
                              strcpy(man_ent[i].Var, buf);
                              break;
                        case 0x88:
                              j = MIN(sizeof(spid_state)/sizeof(__u8 *)-1, man_ent[i].Var[0]);
                              sprintf(man_ent[i].Var, "%s", spid_state[j]);
                              break;
                  }
            }
            else 
            if (man_ent[i].type == 0x02) strcpy(man_ent[i].Var, "COMMAND");
      }
  return(0);
}

void eicon_manage_head(void)
{
      int ctype;
        mvwaddstr(headwin, 0,0,"Management for Eicon DIVA Server cards                      Cytronics & Melware");
        if ((ctype = ioctl(fd, EICON_IOCTL_GETTYPE + IIOCDRVCTL, &ioctl_s)) < 0) {
                return;
        }
        switch (ctype) {
                case EICON_CTYPE_MAESTRAP:
                        mvwaddstr(headwin, 1,0,"Adapter-type is Diva Server PRI/PCI");
                        break;
                case EICON_CTYPE_MAESTRAQ:
                        mvwaddstr(headwin, 1,0,"Adapter-type is Diva Server 4BRI/PCI");
                        break;
                case EICON_CTYPE_MAESTRA:
                        mvwaddstr(headwin, 1,0,"Adapter-type is Diva Server BRI/PCI");
                        break;
                default:
                        mvwaddstr(headwin, 1,0,"Adapter-type is unknown");
                        return;
        }
}

void eicon_manage_init_ncurses(void)
{
        initscr();
        noecho();
        nonl();
        refresh();
        cbreak();
        keypad(stdscr,TRUE);
      curs_set(0);
      statwin = newpad(50,80);
      headwin = newpad(5,80);
        start_color();
      
}

void show_man_entries(void)
{
      int i;
      char MLine[80];
      char AttSt[7];

        for(i = 0; i < man_ent_count; i++) {
                if (man_ent[i].type == 0x01) {
                        sprintf(AttSt, "<DIR>");
                } else {
                        sprintf(AttSt,"%c%c%c%c%c",
                                (man_ent[i].attribute &0x01) ? 'w' : '-',
                                (man_ent[i].attribute &0x02) ? 'e' : '-',
                                (man_ent[i].status &0x01) ? 'l' : '-',
                                (man_ent[i].status &0x02) ? 'e' : '-',
                                (man_ent[i].status &0x04) ? 'p' : '-');
                }
                sprintf(MLine, "%-17s %s %s\n",
                        man_ent[i].Name,
                        AttSt,
                        man_ent[i].Var);
                printf(MLine);
        }
}

void eicon_manage_draw(void)
{
      int i;
      int max_line = 0;
      char MLine[80];
      char AttSt[7];

      mvwaddstr(headwin, 2, 0, "                                                                                ");
        mvwaddstr(headwin, 3,0,"Name              Flags Variable");
        mvwaddstr(headwin, 4,0,"-------------------------------------------------------------------------------");

        max_line =  man_ent_count;
        for(i = 0; i < max_line; i++) {
                if (man_ent[i].type == 0x01) {
                        sprintf(AttSt, "<DIR>");
                } else {
                        sprintf(AttSt,"%c%c%c%c%c",
                                (man_ent[i].attribute &0x01) ? 'w' : '-',
                                (man_ent[i].attribute &0x02) ? 'e' : '-',
                                (man_ent[i].status &0x01) ? 'l' : '-',
                                (man_ent[i].status &0x02) ? 'e' : '-',
                                (man_ent[i].status &0x04) ? 'p' : '-');
                }
                sprintf(MLine, "%-17s %s %-56s",
                        man_ent[i].Name,
                        AttSt,
                        man_ent[i].Var);
                if (i == h_line) wattron(statwin, A_REVERSE);
                mvwaddstr(statwin, i, 0, MLine);
                wattroff(statwin, A_REVERSE);
        }
        for(i = max_line; i < 50; i++) {
            mvwaddstr(statwin, i, 0, "                                                                                ");
      }
        prefresh(statwin, stat_y, 0, 5, 0, LINES-4, COLS);
        mvwaddstr(headwin, 2,0,"Directory : ");
        waddstr(headwin, Man_Path);
        prefresh(headwin, 0, 0, 0, 0, 5, COLS);
      refresh();
}

void do_manage_resize(int dummy) {
        endwin();
      eicon_manage_init_ncurses();
      eicon_manage_head();
      eicon_manage_draw();
      eicon_manage_draw();
      refresh();
      signal(SIGWINCH, do_manage_resize);
}

void rmws(char *text)
{
      int c;
      for (c=strlen(text)-1;c>=0;c--)
      {
            if (text[c]!=' ') return;
            text[c]='\0';
      }
      return;
}

int l_edit(char *buevar, char *uevar, int length)
{
      int ca,yq,xq,x,y;
      int ilen=0;
      int bilen=0;
      getyx(statwin,yq,xq);
      for(ca = 0; ca < length; ca++) uevar[ca]=32;
      uevar[ca]='\0';
      strcpy(uevar,buevar);
      ilen=strlen(buevar);
      uevar[ilen]=32;
      uevar[length]='\0';
      waddstr(statwin,uevar);
      wmove(statwin,yq,xq);
      laby01:
        prefresh(statwin, stat_y, 0, 5, 0, LINES-4, COLS);
      ca=getch();
      switch(ca)
      {
            case KEY_LEFT:
                  if (bilen<=0) goto laby02;
                  getyx(statwin,y,x);
                  x--;
                  bilen--;
                  wmove(statwin,y,x);
                  goto laby01;
            case KEY_RIGHT:
                  if (bilen>=length) goto laby02;
                  getyx(statwin,y,x);
                  x++;
                  bilen++;
                  wmove(statwin,y,x);
                  goto laby01;
            case KEY_BACKSPACE:
            case 8:
                  if (bilen<1) goto laby02;
                  getyx(statwin,y,x);
                  x--; bilen--;
                  for (ca=bilen;ca<(length-1);ca++) uevar[ca]=uevar[ca+1];
                  uevar[length-1]=32;
                  mvwaddstr(statwin,yq,xq,uevar);
                  wmove(statwin,y,x);
                  goto laby01;
            case 10:
            case 13:
                  rmws(uevar);
                  return(1);
            case 27:
                  rmws(uevar);
                  return(2);
      }
      if ((ca > 31) && (ca < 123))
      {
            if (length <= bilen) goto laby02;
            uevar[bilen]=ca;
            bilen++;
            getyx(statwin,y,x);
            x++;
            mvwaddstr(statwin,yq,xq,uevar);
            wmove(statwin,y,x);
            goto laby01;
      }
      laby02:
      beep2();
      goto laby01;
}

void eicon_management(void)
{
      int Key;
      int i;
      h_line = 0;
      stat_y = 0;

      signal(SIGWINCH, do_manage_resize);

      eicon_manage_init_ncurses();
      eicon_manage_head();
      eicon_manage_draw();
      redraw1:
      eicon_manage_draw();
      Keyboard:
      Key = getch();
      switch(Key) {
            case 27:
            case 'q':
            case 'Q':
                    move(22,0);
                  refresh();
                  endwin();

                        close(fd); 
                        exit(0);
                  break;
            case KEY_UP:
                  if (h_line) {
                        h_line--;
                        if (stat_y > h_line) stat_y--;
                  }
                  goto redraw1;
            case KEY_DOWN:
                  if (h_line < man_ent_count - 1) {
                        h_line++;
                        if ((stat_y + LINES - 9) < h_line) stat_y++;
                  }
                  goto redraw1;
            case KEY_LEFT:
                  if ((strcmp(Man_Path,"\\")) && (strlen(Man_Path) > 1)) {
                        for(i=strlen(Man_Path); i >= 0; i--) {
                              if (Man_Path[i] == '\\') {
                                    Man_Path[i] = 0;
                                    break;
                              }
                        }
                        if (strlen(Man_Path) == 0) strcpy(Man_Path,"\\");
                        if (get_manage_element(Man_Path, 0x02) < 0) {
                              clear();
                                        mvaddstr(0,0, "Error ioctl Management-interface");
                              refresh();
                                      return;
                        }
                        h_line = 0;
                        stat_y = 0;
                        goto redraw1;
                  }
                  beep2();
                  goto Keyboard;
            case 10:
            case 13:
            case KEY_RIGHT:
                  if (man_ent[h_line].type == 0x01) { /* Directory */
                        if (Man_Path[strlen(Man_Path)-1] != '\\') strcat(Man_Path, "\\");
                        strcat(Man_Path, man_ent[h_line].Name);
                        if (get_manage_element(Man_Path, 0x02) < 0) {
                              clear();
                                        mvaddstr(0,0, "Error ioctl Management-interface");
                              refresh();
                                      return;
                        }
                        h_line = 0;
                        stat_y = 0;
                        goto redraw1;
                  }
                  if (man_ent[h_line].type == 0x02) { /* Executable function */
                        i = strlen(Man_Path);
                        if (Man_Path[strlen(Man_Path)-1] != '\\') strcat(Man_Path, "\\");
                        strcat(Man_Path, man_ent[h_line].Name);
                        if (get_manage_element(Man_Path, 0x04) < 0) {
                              clear();
                                        mvaddstr(0,0, "Error ioctl Management-interface");
                              refresh();
                                      return;
                        }
                        Man_Path[i] = 0;
                        if (get_manage_element(Man_Path, 0x02) < 0) {
                              clear();
                                        mvaddstr(0,0, "Error ioctl Management-interface");
                              refresh();
                                      return;
                        }
                        goto redraw1;

                  }
                        if (man_ent[h_line].type == 0x06) { /* Trace Event */
                                int tcmd = 0x05;
                                i = strlen(Man_Path);
                                if (Man_Path[strlen(Man_Path)-1] != '\\') strcat(Man_Path, "\\");
                                strcat(Man_Path, man_ent[h_line].Name);
                                if (man_ent[h_line].status & 0x02)                                                                                                tcmd = 0x06;
                                if (get_manage_element(Man_Path, tcmd) < 0) {
                                        clear();
                                        mvaddstr(0,0, "Error ioctl Management-interface");
                                        refresh();
                                        return;
                                }
                                Man_Path[i] = 0;
                                if (get_manage_element(Man_Path, 0x02) < 0) {
                                        clear();
                                        mvaddstr(0,0, "Error ioctl Management-interface");
                                        refresh();
                                        return;
                                }
                                goto redraw1;

                        }
                  if (man_ent[h_line].attribute & 0x01) { /* Writetable function */
                        unsigned char eline[200];
                        int ltmp;
                        sprintf(eline, "%-17s ", man_ent[h_line].Name);
                        wattron(statwin, A_BLINK|A_REVERSE);
                        mvwaddstr(statwin, h_line, 0, eline);
                        wattroff(statwin, A_BLINK|A_REVERSE);
                        curs_set(1);
                        wmove(statwin,h_line,24);
                        wattron(statwin, A_REVERSE);
                        ltmp = l_edit(man_ent[h_line].Var, eline, 40);
                        if ((strlen(eline) < 1) || (ltmp != 1)) {
                              wattroff(statwin, A_REVERSE);
                              curs_set(0);
                              goto redraw1;
                        }
                        wattroff(statwin, A_REVERSE);
                        curs_set(0);
                        i = strlen(Man_Path);
                        if (Man_Path[strlen(Man_Path)-1] != '\\') strcat(Man_Path, "\\");
                        strcat(Man_Path, man_ent[h_line].Name);
                        if (write_manage_element(Man_Path, 0x03, eline,
                              man_ent[h_line].var_length, man_ent[h_line].type) < 0) {
                              beep2();
                        }
                        Man_Path[i] = 0;
                        if (get_manage_element(Man_Path, 0x02) < 0) {
                              clear();
                                        mvaddstr(0,0, "Error ioctl Management-interface");
                              refresh();
                                      return;
                        }
                        goto redraw1;

                  }
                  beep2();
                  goto Keyboard;
            case 'r':
                  if (get_manage_element(Man_Path, 0x02) < 0) {
                        clear();
                                  mvaddstr(0,0, "Error ioctl Management-interface");
                        refresh();
                                return;
                  }
                  goto redraw1;
            default:
                  beep2();
                  goto Keyboard;
      }

}

void filter_slash(char *s)
{
      int i;
      for (i=0; i < strlen(s); i++)
            if (s[i] == '/') s[i] = '\\';
}

void load_startup_code(char *startupcode, char *fileext)
{
      FILE *code;
      u_char bootbuf[0x1000];
      char filename[100];
      int tmp;
      eicon_codebuf *cb;

      sprintf(filename, "%s/%s", DATADIR, startupcode);

      if (!(code = fopen(filename,"r"))) {
            perror(filename);
            exit(-1);
      }
      if ((tmp = fread(bootbuf, 1, sizeof(bootbuf), code))<1) {
            fprintf(stderr, "Read error on %s\n", filename);
            exit(-1);
      }
      fclose(code);
      cb = malloc(sizeof(eicon_codebuf) + tmp);
      memset(cb, 0, sizeof(eicon_codebuf));
      memcpy(&cb->isa.code, bootbuf, tmp);
      cb->isa.bootstrap_len = tmp;
      cb->isa.boot_opt = EICON_ISA_BOOT_NORMAL;
      printf("Loading Startup Code (%s %d bytes)...\n", startupcode, tmp);
      ioctl_s.arg = (ulong)cb;
      if (ioctl(fd, EICON_IOCTL_LOADBOOT + IIOCDRVCTL, &ioctl_s) < 0) {
            perror("ioctl LOADBOOT");
            exit(-1);
      }
      if ((tmp = ioctl(fd, EICON_IOCTL_GETTYPE + IIOCDRVCTL, &ioctl_s)) < 0) {
            perror("ioctl GETTYPE");
            exit(-1);
      }
      switch (tmp) {
            case EICON_CTYPE_S:
                  strcpy(fileext,".bin");
                  printf("Adapter-type is Eicon-S\n");
                  break;
            case EICON_CTYPE_SX:
                  strcpy(fileext,".sx");
                  printf("Adapter-type is Eicon-SX\n");
                  break;
            case EICON_CTYPE_SCOM:
                  strcpy(fileext,".sy");
                  printf("Adapter-type is Eicon-SCOM\n");
                  break;
            case EICON_CTYPE_QUADRO:
                  strcpy(fileext,".sq");
                  printf("Adapter-type is Eicon-QUADRO\n");
                  break;
            case EICON_CTYPE_S2M:
                  strcpy(fileext,".p");
                  printf("Adapter-type is Eicon-S2M\n");
                  break;
            default:
                  fprintf(stderr, "Unknown Adapter type %d for ISA-load\n", tmp);
                  exit(-1);
      }
}


int main(int argc, char **argv) {
      int tmp;
      int ac;
      int arg_ofs=1;
      int card_id;

      cmd = argv[0];
      if (argc > 1) {
            if (!strcmp(argv[arg_ofs], "-h"))
                  eiconctrl_usage();
            if (!strcmp(argv[arg_ofs], "--help"))
                  eiconctrl_usage();
            
            if (!strcmp(argv[arg_ofs], "-d")) {
                  arg_ofs++;
                  if (arg_ofs >= argc)
                        eiconctrl_usage();
                  strcpy(ioctl_s.drvid, argv[arg_ofs++]);
                  if (arg_ofs >= argc)
                        eiconctrl_usage();
                  if (!strcmp(argv[arg_ofs], "-v")) {
                        arg_ofs++;
                        verbose = 1;
                  }
            } else {
                  ioctl_s.drvid[0] = '\0';
                  if (!strcmp(argv[arg_ofs], "-v")) {
                        arg_ofs++;
                        verbose = 1;
                  }
            }
      } else
            eiconctrl_usage();

#ifndef HAVE_NPCI
      strcpy(DrvID, ioctl_s.drvid);
#endif

      ac = argc - (arg_ofs - 1);
      if (arg_ofs >= argc)
            eiconctrl_usage();
      fd = open("/dev/isdn/isdnctrl",O_RDWR | O_NONBLOCK);
      if (fd < 0)
            fd = open("/dev/isdnctrl",O_RDWR | O_NONBLOCK);
      if (fd < 0) {
            perror("/dev/isdnctrl");
            exit(-1);
      }

      if ((tmp = ioctl(fd, EICON_IOCTL_GETVER + IIOCDRVCTL, &ioctl_s)) < 0) {
            fprintf(stderr, "Driver ID %s not found or\n", ioctl_s.drvid);
            fprintf(stderr, "Eicon kernel driver is too old !\n"); 
            exit(-1);
      }
      if (tmp < EICON_CTRL_VERSION) {
            fprintf(stderr, "Eicon kernel driver is older than eiconctrl !\n"); 
            fprintf(stderr, "Please update !\n");
      }
      if (tmp > EICON_CTRL_VERSION) {
            fprintf(stderr, "Eicon kernel driver is newer than eiconctrl !\n"); 
            fprintf(stderr, "Please update !\n");
      }

      if (!strcmp(argv[arg_ofs], "add")) {
            eicon_cdef *cdef;
            if (ac != 5) 
                  eiconctrl_usage();
            cdef = malloc(sizeof(eicon_cdef));
            strcpy(cdef->id, argv[arg_ofs + 1]);
            if (strlen(cdef->id) < 1)
                  eiconctrl_usage();
            if (sscanf(argv[arg_ofs + 2], "%i", &cdef->membase) !=1 )
                  eiconctrl_usage();
            if (sscanf(argv[arg_ofs + 3], "%i", &cdef->irq) !=1 )
                  eiconctrl_usage();
            ioctl_s.arg = (ulong)cdef;
            if (ioctl(fd, EICON_IOCTL_ADDCARD + IIOCDRVCTL, &ioctl_s) < 0) {
                  perror("ioctl ADDCARD");
                  exit(-1);
            }
            printf("Card added.\n");
            close(fd);
            return 0;
      }
      if (!strcmp(argv[arg_ofs], "membase")) {
            if (ac == 3) {
                  if (sscanf(argv[arg_ofs + 1], "%i", &tmp) !=1 )
                        eiconctrl_usage();
                  ioctl_s.arg = tmp;
                  if (ioctl(fd, EICON_IOCTL_SETMMIO + IIOCDRVCTL, &ioctl_s) < 0) {
                        perror("ioctl SETMMIO");
                        exit(-1);
                  }
            }
            if ((tmp = ioctl(fd, EICON_IOCTL_GETMMIO + IIOCDRVCTL, &ioctl_s)) < 0) {
                  perror("ioctl GETMMIO");
                  exit(-1);
            }
            printf("Shared memory at 0x%x\n", tmp);
            close(fd);
            return 0;
      }
      if (!strcmp(argv[arg_ofs], "irq")) {
            if (ac == 3) {
                  if (sscanf(argv[arg_ofs + 1], "%i", &tmp) != 1)
                        eiconctrl_usage();
                  ioctl_s.arg = tmp;
                  if (ioctl(fd, EICON_IOCTL_SETIRQ + IIOCDRVCTL, &ioctl_s) < 0) {
                        perror("ioctl SETIRQ");
                        exit(-1);
                  }
            }
            if ((tmp = ioctl(fd, EICON_IOCTL_GETIRQ + IIOCDRVCTL, &ioctl_s)) < 0) {
                  perror("ioctl GETIRQ");
                  exit(-1);
            }
            printf("Irq is %d\n", tmp);
            close(fd);
            return 0;
      }

#ifndef HAVE_NPCI
        if (!strcmp(argv[arg_ofs], "divaload")) {
            int ret;
            int i, dlen;
            int lcard;
            int have, haves;
            char *newargv[35];
            int  newarg;

            labload:
            ret = 0;
            i = arg_ofs + 1;
            have = 0;
            haves = 0;

            newarg = 0;
            newargv[0] = malloc(50);
            strcpy(newargv[0], "eiconctrl.divaload");
            newarg++;

            card_id = -1;
            ioctl_s.arg = (ulong) &card_id;
            if ((ioctl(fd, EICON_IOCTL_GETTYPE + IIOCDRVCTL, &ioctl_s)) < 1) {
                  perror("ioctl GETTYPE");
                  exit(-1);
            }

            if (card_id > 0) {
                  lcard = card_id - 1;
                  printf("Card-ID = %d\n", card_id);
            } else {
                  lcard = 0;
                  dlen = strlen(ioctl_s.drvid);
                  if (dlen) {
                        if (isdigit(ioctl_s.drvid[dlen - 1])) {
                              lcard = ioctl_s.drvid[dlen - 1] - '0';
                        }
                  }
            }

            while(argv[i]) {
                  if ((!(strncmp(argv[i], "-t", 2))) && (strlen(argv[i]) > 2)){
                        newargv[newarg] = malloc(4);
                        strcpy(newargv[newarg], "-t");
                        newarg++;
                        newargv[newarg] = malloc(strlen(argv[i]) + 1);
                        strcpy(newargv[newarg], argv[i] + 2);
                  } else
                  if ((!(strncmp(argv[i], "-l", 2))) && (strlen(argv[i]) > 2)){
                        newargv[newarg] = malloc(4);
                        strcpy(newargv[newarg], "-l");
                        newarg++;
                        newargv[newarg] = malloc(strlen(argv[i]) + 1);
                        strcpy(newargv[newarg], argv[i] + 2);
                  } else
                  if ((!(strncmp(argv[i], "-s", 2))) && (strlen(argv[i]) > 2)){
                        newargv[newarg] = malloc(4);
                        strcpy(newargv[newarg], "-s");
                        newarg++;
                        newargv[newarg] = malloc(strlen(argv[i]) + 1);
                        strcpy(newargv[newarg], argv[i] + 2);
                  } else
                  {
                        newargv[newarg] = malloc(strlen(argv[i]) + 1);
                        strcpy(newargv[newarg], argv[i]);
                  }
                  if ((!(strcmp(argv[i],"-c"))) || (!(strcmp(argv[i],"-all")))) {
                        have = 1;
                  }
                  if (!(strcmp(argv[i],"-f"))) {
                        haves = 1;
                  }
                  i++;
                  newarg++;
            }

            if (!have) {
                  newargv[newarg] = malloc(4);
                  strcpy(newargv[newarg], "-c");
                  newarg++;
                  newargv[newarg] = malloc(4);
                  sprintf(newargv[newarg], "%d", lcard + 1);
                  newarg++;
            }
            if (!haves) {
                  newargv[newarg] = malloc(4);
                  strcpy(newargv[newarg], "-f");
                  newarg++;
                  newargv[newarg] = malloc(strlen(protoname) + 1);
                  strcpy(newargv[newarg], protoname);
                  newarg++;
            }
            newargv[newarg] = NULL;
            printf("Using Eicon's divaload...\n");
            ret = Divaload_main(newarg, newargv);
            return ret;
      }
#endif

        if ((!strcmp(argv[arg_ofs], "load")) || (!strcmp(argv[arg_ofs], "loadpci"))) {
                FILE *code;
            int isabus = 0;
                int plen = 0;
            int ctype = 0;
            int card_type = 0;
            int tmp, i;
            int tei = 255;
            char fileext[5];
                char filename[1024];
                u_char protobuf[0x100000];
                eicon_codebuf *cb = NULL;

            card_id = -1;

            if (argc <= (arg_ofs + 1))
                        strcpy(protoname,"etsi");
            else {
                  if (argv[arg_ofs + 1][0] == '-')
                              strcpy(protoname,"etsi");
                  else  
                              strcpy(protoname,argv[++arg_ofs]);
            }
            
            if ((ctype = ioctl(fd, EICON_IOCTL_GETTYPE + IIOCDRVCTL, &ioctl_s)) < 1) {
                  perror("ioctl GETTYPE");
                  exit(-1);
            }
            switch (ctype) {
                  case EICON_CTYPE_MAESTRAP:
                        printf("Adapter-type is Diva Server PRI/PCI\n");
                        card_type = 23;
#ifdef HAVE_NPCI
                        strcpy(fileext, ".pm");
                        tei = 1;
                        break;
#else
                        goto labload;
#endif
                  case EICON_CTYPE_MAESTRA:
                        printf("Adapter-type is Diva Server BRI/PCI\n");
                        card_type = 21;
#ifdef HAVE_NPCI
                        strcpy(fileext, ".sm");
                        tei = 0;
                        break;
#else
                        goto labload;
#endif
#ifndef HAVE_NPCI
                  case EICON_CTYPE_MAESTRAQ:
                        printf("Adapter-type is Diva Server 4BRI/PCI\n");
                        goto labload;
#endif
                  case EICON_CTYPE_S:
                  case EICON_CTYPE_SX:
                  case EICON_CTYPE_SCOM:
                  case EICON_CTYPE_QUADRO:
                  case EICON_CTYPE_ISABRI:
                        isabus = 1;
                        tei = 0;
                        load_startup_code("dnload.bin", fileext);
                        break;
                  case EICON_CTYPE_S2M:
                  case EICON_CTYPE_ISAPRI:
                        isabus = 1;
                        tei = 1;
                        load_startup_code("prload.bin", fileext);
                        break;
                  default:
                        fprintf(stderr, "Adapter type %d not supported\n", ctype);
                              exit(-1);
            }

            sprintf(filename, "%s/te_%s%s", DATADIR, protoname, fileext);
                  if (!(code = fopen(filename,"r"))) {
                                    perror(filename);
                                    exit(-1);
                  }
            printf("Protocol File : %s ", filename);
            if ((tmp = fread(protobuf, 1, sizeof(protobuf), code))<1) {
                  fclose(code);
                  fprintf(stderr, "Read error on %s\n", filename);
                            exit(-1);
            }
                  fclose(code);
                  printf("(%d bytes)\n", tmp);
            plen += tmp;
                  
            if (verbose) {
                  if (isabus) {
                        printf("Protocol: %s\n", &protobuf[4]);
                        plen = (plen % 256)?((plen/256)+1)*256:plen;
                  } else {
                        strncpy(filename, &protobuf[0x80], 100);
                        for (i=0; filename[i] && filename[i]!='\r' && filename[i]!='\n'; i++);
                        filename[i] = 0;
                        printf("%s\n", filename);
                  }
            }

            if (isabus) {
                  if(!(cb = malloc(sizeof(eicon_codebuf) + plen ))) {
                            fprintf(stderr, "Out of Memory\n");
                                exit(-1);
                  }
                  memset(cb, 0, sizeof(eicon_codebuf));
                  memcpy(&cb->isa.code, protobuf, plen);
                  cb->isa.firmware_len = plen;
            } else {
#ifdef HAVE_NPCI
                  if (!(cb = load_combifile(card_type, protobuf, &plen))) {
                            fprintf(stderr, "Error loading Combifile\n");
                                exit(-1);
                  }
#endif
            }

            if (isabus) {
                  cb->isa.tei = tei;
                  cb->isa.nt2 = 0;
                  cb->isa.WatchDog = 0;
                  cb->isa.Permanent = 0;
                  cb->isa.XInterface = 0;
                  cb->isa.StableL2 = 0;
                  cb->isa.NoOrderCheck = 0;
                  cb->isa.HandsetType = 0;
                  cb->isa.LowChannel = 0;
                  cb->isa.ProtVersion = 0;
                  cb->isa.Crc4 = 0;
                  cb->isa.Loopback = 0;
            } else {
#ifdef HAVE_NPCI
                  cb->pci.tei = tei;
                  cb->pci.nt2 = 0;
                  cb->pci.WatchDog = 0;
                  cb->pci.Permanent = 0;
                  cb->pci.XInterface = 0;
                  cb->pci.StableL2 = 0;
                  cb->pci.NoOrderCheck = 0;
                  cb->pci.HandsetType = 0;
                  cb->pci.LowChannel = 0;
                  cb->pci.ProtVersion = 0;
                  cb->pci.Crc4 = 0;
                  cb->pci.Loopback = 0;
                  cb->pci.NoHscx30Mode = 0;
#endif /* NPCI */
            }

            /* parse extented options */
            while(ac > (arg_ofs + 1)) {
                  arg_ofs++;
                  if (!strncmp(argv[arg_ofs], "-l", 2)) {
                        if (isabus) {
                              cb->isa.LowChannel = atoi(argv[arg_ofs] + 2);
                              if (!cb->isa.LowChannel) cb->isa.LowChannel = 1;
                        } else {
#ifdef HAVE_NPCI
                              cb->pci.LowChannel = atoi(argv[arg_ofs] + 2);
                              if (!cb->pci.LowChannel) cb->pci.LowChannel = 1;
#endif /* NPCI */
                        }
                                continue;
                        }
                        if (!strncmp(argv[arg_ofs], "-t", 2)) {
                        if (isabus) {
                                    cb->isa.tei = atoi(argv[arg_ofs] + 2);
                        } else {
#ifdef HAVE_NPCI
                                    cb->pci.tei = atoi(argv[arg_ofs] + 2);
#endif
                        }
                                continue;
                        }
                        if (!strcmp(argv[arg_ofs], "-z")) {
                        if (isabus) 
                                      cb->isa.Loopback = 1;
#ifdef HAVE_NPCI
                        else
                                      cb->pci.Loopback = 1;
#endif
                                continue;
                        }
                        if (!strcmp(argv[arg_ofs], "-p")) {
                        if (isabus) 
                                    cb->isa.Permanent = 1;
#ifdef HAVE_NPCI
                        else
                                    cb->pci.Permanent = 1;
#endif
                                continue;
                        }
                        if (!strcmp(argv[arg_ofs], "-w")) {
                        if (isabus) 
                                      cb->isa.WatchDog = 1;
#ifdef HAVE_NPCI
                        else
                                      cb->pci.WatchDog = 1;
#endif
                                continue;
                        }
                        if (!strcmp(argv[arg_ofs], "-e")) {
                        if (isabus) 
                                  cb->isa.Crc4 = 1;
#ifdef HAVE_NPCI
                        else
                                  cb->pci.Crc4 = 1;
#endif
                                continue;
                        }
                        if (!strcmp(argv[arg_ofs], "-e1")) {
                        if (isabus) 
                                    cb->isa.Crc4 = 1;
#ifdef HAVE_NPCI
                        else
                                    cb->pci.Crc4 = 1;
#endif
                                continue;
                        }
                        if (!strcmp(argv[arg_ofs], "-e2")) {
                        if (isabus) 
                                      cb->isa.Crc4 = 2;
#ifdef HAVE_NPCI
                        else
                                      cb->pci.Crc4 = 2;
#endif
                                continue;
                        }
                        if (!strcmp(argv[arg_ofs], "-n")) {
                        if (isabus) 
                                    cb->isa.nt2 = 1;
#ifdef HAVE_NPCI
                        else
                                    cb->pci.nt2 = 1;
#endif
                                continue;
                        }
                        if (!strcmp(argv[arg_ofs], "-p")) {
                        if (isabus) 
                                      cb->isa.Permanent = 1;
#ifdef HAVE_NPCI
                        else
                                      cb->pci.Permanent = 1;
#endif
                                continue;
                        }
                        if (!strcmp(argv[arg_ofs], "-h")) {
#ifdef HAVE_NPCI
                                if (!isabus) cb->pci.NoHscx30Mode = 1;
#endif
                                continue;
                        }
                        if (!strcmp(argv[arg_ofs], "-o")) {
                        if (isabus) 
                                  cb->isa.NoOrderCheck = 1;
#ifdef HAVE_NPCI
                        else
                                  cb->pci.NoOrderCheck = 1;
#endif
                                continue;
                        }
                        if (!strcmp(argv[arg_ofs], "-s")) {
                        if (isabus) 
                                    cb->isa.StableL2 = 1;
#ifdef HAVE_NPCI
                        else
                                    cb->pci.StableL2 = 1;
#endif
                                continue;
                        }
                        if (!strcmp(argv[arg_ofs], "-s1")) {
                        if (isabus) 
                                      cb->isa.StableL2 = 1;
#ifdef HAVE_NPCI
                        else
                                      cb->pci.StableL2 = 1;
#endif
                                continue;
                        }
                        if (!strcmp(argv[arg_ofs], "-s2")) {
                        if (isabus) 
                                    cb->isa.StableL2 = 2;
#ifdef HAVE_NPCI
                        else
                                    cb->pci.StableL2 = 2;
#endif
                                continue;
                        }
                        if (!strcmp(argv[arg_ofs], "-s0")) {
                        if (isabus) 
                                    cb->isa.StableL2 = 0;
#ifdef HAVE_NPCI
                        else
                                    cb->pci.StableL2 = 0;
#endif
                                continue;
                        }
            }
            printf("Downloading Code (%d bytes)...\n", plen);
            ioctl_s.arg = (ulong)cb;
            tmp = (isabus) ? EICON_IOCTL_LOADISA : EICON_IOCTL_LOADPCI;
            if (ioctl(fd, tmp + IIOCDRVCTL, &ioctl_s) < 0) {
                  printf("\nError, possibly updated driver, try re-compile utility !\n");
                  perror("ioctl LOAD");
                  exit(-1);
            }
            printf("completed.\n");
            close(fd);
            return 0;
        }

        if (!strcmp(argv[arg_ofs], "debug")) {
            if (argc <= (arg_ofs + 1))
                  ioctl_s.arg = 1;
            else  
                  ioctl_s.arg = atol(argv[arg_ofs + 1]);
            if (ioctl(fd, EICON_IOCTL_DEBUGVAR + IIOCDRVCTL, &ioctl_s) < 0) {
                  perror("ioctl DEBUG VALUE");
                  exit(-1);
            }
            return 0;
      }

        if (!strcmp(argv[arg_ofs], "freeit")) {
            if (ioctl(fd, EICON_IOCTL_FREEIT + IIOCDRVCTL, &ioctl_s) < 0) {
                  perror("ioctl FREEIT");
                  exit(-1);
            }
            return 0;
      }

#ifdef HAVE_TRACE
      if (!strcmp(argv[arg_ofs], "xlog")) {
            int dfd = fd;
            int cont = 0;
            char file[300];
            unsigned char buffer[1000];
            unsigned char inbuffer[1000];
            int pos = 0, ret = 1;
            unsigned char byte = 0;
            char *p, *q;
            unsigned long val, sec;

            if (argc > (++arg_ofs)) {
                  if (!strcmp(argv[arg_ofs], "cont"))
                        cont = 1;
                  else {
                        strcpy(file, argv[arg_ofs]);
                        cont = 2;
                        dfd = open(file, O_RDWR);
                        if (dfd < 0) {
                              fprintf(stderr, "File not found.\n");
                              exit(-1);
                        }
                  }
            }
            mb = malloc(sizeof(eicon_manifbuf));
            strcpy (Man_Path, "\\Trace\\Log Buffer");
            if (cont < 2)
            get_manage_element(Man_Path, 0x05);
            while(1) {
                  memset(buffer, 0, sizeof(buffer));
                  memset(inbuffer, 0, sizeof(inbuffer));
                  fflush(stdout);
                  while((byte != 13) && (byte != 10) && (pos < 998) && (ret > 0)) {
                        if ((ret = read(dfd, &byte, 1)) == 1) {
                              inbuffer[pos++] = byte;
                        }
                  }
                  byte = 0;
                  pos = 0;
                  if ((strlen(inbuffer) > 10) && (strncmp(inbuffer, "XLOG: ", 6) == 0)) {
                        p = inbuffer + 6;
                        val = strtol(p, &q, 16);
                        sec=val/1000;
                        printf("%5ld:%04ld:%03ld - ",
                              (long)sec/3600,
                              (long)sec%3600,
                              (long)val%1000 );
                        p = q;
                        val = strtol(p, &q, 16);
                        p = q;
                        val = strtol(p, &q, 16);
                        (unsigned short) *buffer = (unsigned short) val;
                        pos = 2;
                        while ((p != q) && (*q != 0)) {
                              p = q;
                              val = strtol(p, &q, 16);
                              buffer[pos++] = val;
                        }
                        pos = 0;
                        xlog(stdout, buffer);
                  }
                  if ((ret == 0) && (cont == 2))
                        break;
                  if ((ret < 0) && (cont != 1))
                        break;
                  if ((ret < 0) && (cont == 1))
                        usleep(10000);
                  ret = 1;
            }
            if (cont < 2)
                  get_manage_element(Man_Path, 0x06);
            close(fd);
            return 0;
      }
#else
#ifdef HAVE_XLOG
      if (!strcmp(argv[arg_ofs], "xlog")) {
            int cont = 0;
            int ii;
            int ret_val;
            int end = 0;
            __u32 sec, msec;
            mi_pc_maint_t *pcm;
            xlogreq_t xlogreq;
            xlog_entry_t xlog_entry;
            xlog_entry_t swap_entry;
            __u8 *xlog_byte, *swap_byte;

            xlog_byte = (__u8 *)&xlog_entry;
            swap_byte = (__u8 *)&swap_entry;

            if ((argc > (++arg_ofs)) && (!strcmp(argv[arg_ofs], "cont")))
                  cont = 1;
            printf("Getting log%s...\n", ((cont) ? ", CTRL-C to quit" : ""));

            pcm = &xlogreq.pcm;

            while(1)
            {
                  fflush(stdout);

                  memset(&xlogreq, 0, sizeof(xlogreq_t));
                  xlogreq.command = 1;
                  ioctl_s.arg = (ulong)&xlogreq;
                  if ((ret_val = ioctl(fd, EICON_IOCTL_GETXLOG + IIOCDRVCTL, &ioctl_s)) < 0) {
                        perror("ioctl XLOG");
                        close(fd); 
                        exit(-1);
                  }

                  *(MIPS_BUFFER *)&xlog_entry = pcm->data;
                  msec = (((__u32)xlog_entry.timeh)<<16)+xlog_entry.timel;
                  sec=msec/1000;
                  switch (ret_val)
                  {
                        case XLOG_OK:
                              for(ii = 0; ii < MIPS_BUFFER_SZ; ii += 2)
                              {
                                    swap_byte[ii] = xlog_byte[ii+1];
                                    swap_byte[ii+1] = xlog_byte[ii];
                              }

                              switch(xlog_entry.code)
                              {
                                    case 1:
                                          msec = (((__u32)SWAP(xlog_entry.timeh))<<16)+SWAP(xlog_entry.timel);
                                          sec=msec/1000;
                                          printf("%5ld:%04ld:%03ld - ",
                                                (long)sec/3600,
                                                (long)sec%3600,
                                                (long)msec%1000 );
                                          printf("%s\n", xlog_entry.buffer );
                                          break;

                                    case 2:
                                          msec = (((__u32)SWAP(xlog_entry.timeh))<<16)+SWAP(xlog_entry.timel);
                                          sec=msec/1000;
                                          printf("%5ld:%04ld:%03ld - ",
                                                (long)sec/3600,
                                                (long)sec%3600,
                                                (long)msec%1000 );
                                          xlog(stdout, xlog_entry.buffer);
                                          break;

                                    default:
                                          printf("\n unknown code %d\n", SWAP(xlog_entry.code));
                                          end++;
                                          break;
                              }

                              break;
                        case XLOG_ERR_DONE:
                              if(cont) {
                                    sleep(2);
                              } else {
                                    end++;
                              }
                              break;

                        case XLOG_ERR_CARD_STATE:
                              printf("Card in wrong state for tracing\n");
                              end++;
                              break;

                        case XLOG_ERR_CMD:
                              printf("Command error doing ioctl\n");
                              end++;
                              break;

                        case XLOG_ERR_TIMEOUT:
                              if(cont) {
                                    sleep(2);
                              } else {
                                    printf("Xlog timeout\n");
                                    end++;
                              }
                              break;

                        case XLOG_ERR_UNKNOWN:
                              printf("Unknown error during ioctl\n");
                              end++;
                              break;

                         default:
                              printf("Returned (%d)\n", ret_val);
                              perror("Error doing ioctl");
                              end++;
                              break;
                  }
                  if( end )
                        break;
            }
                close(fd); 
            return 0;
      }
#endif /* XLOG */
#endif /* TRACE */

#ifdef HAVE_TRACE
      if (!strcmp(argv[arg_ofs], "isdnlog")) {
            int tcmd = 0x05;
            int dval = 513;
            int ctype = -1;
            char LogLength[10];
            char EventEnable[50];

            strcpy(LogLength, "80");
            strcpy(EventEnable, "00000000 00000001");

            if ((ctype = ioctl(fd, EICON_IOCTL_GETTYPE + IIOCDRVCTL, &ioctl_s)) < 1) {
                  perror("ioctl GETTYPE");
                  exit(-1);
            }
            switch (ctype) {
                  case EICON_CTYPE_MAESTRAP:
                  case EICON_CTYPE_MAESTRAQ:
                  case EICON_CTYPE_MAESTRA:
                        break;
                  default:
                        fprintf(stderr, "Adapter type %d does not supported this.\n", ctype);
                        exit(-1);
            }
            mb = malloc(sizeof(eicon_manifbuf));

            if (argc > (++arg_ofs)) {
            if (!strcmp(argv[arg_ofs++], "off")) {
                        tcmd = 0x06;
                        dval = 1;
                        strcpy(LogLength, "30");
                        strcpy(EventEnable, "00000000 11111111");
                  }
            }
            ioctl_s.arg = dval;
            if (ioctl(fd, EICON_IOCTL_DEBUGVAR + IIOCDRVCTL, &ioctl_s) < 0) {
                  perror("Error changing debug value.");
                  exit(-1);
            }
            strcpy (Man_Path, "\\Trace\\Log Buffer");
            if (get_manage_element(Man_Path, tcmd) < 0) {
                  fprintf(stderr, "Error or already in that state.\n");
                  exit(-1);
            }
            strcpy (Man_Path, "\\Trace\\Max Log Length");
            if (write_manage_element(Man_Path, 0x03, LogLength, 2, 0x82) < 0) {
                  fprintf(stderr, "Error changing Log Length.\n");
                  exit(-1);
            }
            strcpy (Man_Path, "\\Trace\\Event Enable");
            if (write_manage_element(Man_Path, 0x03, EventEnable, 2, 0x87) < 0) {
                  fprintf(stderr, "Error changing Event Enable.\n");
                  exit(-1);
            }
            close(fd);
            return 0;
      }
#endif /* TRACE */

        if (!strcmp(argv[arg_ofs], "manage")) {
            mb = malloc(sizeof(eicon_manifbuf));

            if (argc > (++arg_ofs)) {
                  if (!strcmp(argv[arg_ofs], "read")) {
                        if (argc <= (arg_ofs + 1)) {
                              fprintf(stderr, "Path to be read is missing\n");
                              exit(-1);
                        }
                        strcpy(Man_Path, argv[arg_ofs + 1]);
                        filter_slash(Man_Path);
                        if (get_manage_element(Man_Path, 0x02) < 0) {
                                        fprintf(stderr, "Error ioctl Management-interface\n");
                                      exit(-1);
                        }
                        show_man_entries();
                        close(fd);
                        return 0;
                  }
                  if (!strcmp(argv[arg_ofs], "exec")) {
                        if (argc <= (arg_ofs + 1)) {
                              fprintf(stderr, "Path to be executed is missing\n");
                              exit(-1);
                        }
                        strcpy(Man_Path, argv[arg_ofs + 1]);
                        filter_slash(Man_Path);
                        if (get_manage_element(Man_Path, 0x04) < 0) {
                                        fprintf(stderr, "Error ioctl Management-interface\n");
                                      exit(-1);
                        }
                        close(fd);
                        return 0;
                  }
                  fprintf(stderr, "Unknown command for Management-interface\n");
                  exit(-1);
            }

            strcpy (Man_Path, "\\");

            if (get_manage_element(Man_Path, 0x02) < 0) {
                            fprintf(stderr, "Error ioctl Management-interface\n");
                          exit(-1);
            }

            eicon_management();
            move(22,0);
            refresh();
            endwin();

                close(fd); 
            exit(0);
      }

      fprintf(stderr, "unknown command\n");
      exit(-1);
}

Generated by  Doxygen 1.6.0   Back to index