/*

   piconfig.c: pi-ifconfig program for the Ottawa Amateur Radio Club
   PI and PI2 interface card. 
   Copyright (c) 1994 John Paul Morrison (VE7JPM).

   version 0.2(dp)
 
   piconfig is a quick hack to set PI card parameters by using driver
   ioctls.  piconfig will no doubt be revised many times as the Linux
   PI driver and Linux 1.1 mutates.

   notes:

   July 16/94 (dp) - corrected some code related to setting the baud rate for
          the current version of pi2.c

   Setting of IRQ and DMA is untested, and probably doesn't work. see
   the kernel code (pi2.c) for details.

*/

/*
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2, as
   published by the Free Software Foundation.

   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.
*/

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <linux/sockios.h>
#include </usr/src/linux/drivers/net/hamradio/pi2.c>

#define DEBUG 1

int opt_a = 0;
int opt_i = 0;
int opt_v = 0;
int skfd = -1;

struct ifreq ifr;
struct pi_req pi;

void usage(void)
{
    fprintf(stderr, "Usage: piconfig [-a] [-i] [-v] interface\n");
    fprintf(stderr, "                [speed NN] [clockmode NN]\n");
    fprintf(stderr, "                [txdelay NN] [persist NN]\n");
    fprintf(stderr, "                [slot NN] [squelch NN]\n");
    fprintf(stderr, "                [irq NN] [dma NN]\n");
    exit(-1);
}

void print_pi(void)
{
    printf("%s\tspeed %d baud  clockmode %d\n",
        ifr.ifr_name, pi.speed, pi.clockmode);
    printf("\ttxdelay %d  persist %d  slotime %d  squeldelay %d\n",
        pi.txdelay, pi.persist, pi.slotime, pi.squeldelay);

    printf("\tirq %d  dma %d\n", pi.irq, pi.dmachan);
}


int main(int argc, char **argv)
{
    int ret = 0;
    char **spp;

    if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
	perror("socket");
	exit(-1);
    }

    if (argc < 2)
	usage();

    /* Find any options. */
    argc--;
    argv++;
    while (*argv[0] == '-') {
	if (!strcmp(*argv, "-a"))
	    opt_a = 1;
	if (!strcmp(*argv, "-v"))
	    opt_v = 1;
	argv++;
	argc--;
    }

    spp = argv;
    strncpy(ifr.ifr_name, *spp++, IFNAMSIZ);
    memset(&pi, 0, sizeof(struct pi_req));
    ifr.ifr_data = (caddr_t) & pi;

    pi.cmd = SIOCGPIPARAM;	/* get current settings for device */
    if (ioctl(skfd, SIOCDEVPRIVATE, &ifr) < 0) {
	perror("ioctl");
	/* exit(-1); */
    }
    if (*spp == (char *) NULL) {
	print_pi();
	(void) close(skfd);
	exit(0);
    }
    while (*spp != (char *) NULL) {
	if (!strcmp(*spp, "speed")) {
	    if (*++spp == NULL)
		usage();
	    pi.speed = atoi(*spp);
	    spp++;
	    continue;
	}
	if (!strcmp(*spp, "clockmode")) {
	    if (*++spp == NULL)
		usage();
	    pi.clockmode = atoi(*spp);
	    spp++;
	    continue;
	}
	if (!strcmp(*spp, "txdelay")) {
	    if (*++spp == NULL)
		usage();
	    pi.txdelay = atoi(*spp);
	    spp++;
	    continue;
	}
	if (!strcmp(*spp, "persist")) {
	    if (*++spp == NULL)
		usage();
	    pi.persist = atoi(*spp);
	    spp++;
	    continue;
	}
	if (!strcmp(*spp, "slot")) {
	    if (*++spp == NULL)
		usage();
	    pi.slotime = atoi(*spp);
	    spp++;
	    continue;
	}
	if (!strcmp(*spp, "squelch")) {
	    if (*++spp == NULL)
		usage();
	    pi.squeldelay = atoi(*spp);
	    spp++;
	    continue;
	}
	if (!strcmp(*spp, "dma")) {
	    if (*++spp == NULL)
		usage();
	    pi.dmachan = atoi(*spp);
	    pi.cmd = SIOCSPIDMA;
	    if (ioctl(skfd, SIOCDEVPRIVATE, &ifr) < 0) {
		fprintf(stderr, "SIOCSPIDMA: %s\n", strerror(errno));
		ret = 1;
	    }
	    spp++;
	    continue;
	}
	if (!strcmp(*spp, "irq")) {
	    if (*++spp == NULL)
		usage();
	    pi.irq = atoi(*spp);
	    pi.cmd = SIOCSPIIRQ;
	    if (ioctl(skfd, SIOCDEVPRIVATE, &ifr) < 0) {
		fprintf(stderr, "SIOCSPIIRQ: %s\n", strerror(errno));
		ret = 1;
	    }
	    spp++;
	    continue;
	}
	spp++;
    }

    pi.cmd = SIOCSPIPARAM;
    if (ioctl(skfd, SIOCDEVPRIVATE, &ifr) < 0)
	perror("ioctl");

#if DEBUG
    print_pi();
#endif

    /* Close the socket. */
    (void) close(skfd);

    return (ret);
}
