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

ppdev.c

/*
    Tucnak - VHF contest log
    Copyright (C) 2002-2006  Ladislav Vaiz <ok1zia@nagano.cz>

    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.

*/

#include "header.h"

#ifdef HAVE_LINUX_PPDEV_H


int parport_init(struct cwdaemon *cwda){
    cwda->fd = -1;
    parport_open(cwda, 1);
    return 0;
}

int parport_open(struct cwdaemon *cwda, int verbose){
      int mode;
      struct ppdev_frob_struct frob;
    char errbuf[1024];

    if (cwda->fd >=0 ) return 0;

    cwda->fd = open(cfg->cwda_device, O_RDWR|O_NONBLOCK);
    if (cwda->fd<0){
        if (verbose) log_addf("Can't open %s %s", cfg->cwda_device, strerror_r(errno, errbuf, sizeof(errbuf)));
        if (errno==ENOENT) {
            int len, devno;
            len=strcspn(cfg->cwda_device, "01234567890");
            if (len<strlen(cfg->cwda_device))
                devno=atoi(cfg->cwda_device+len);
            else
                devno=0;
            if (verbose) log_addf("Tip: try to run as root \"mknod %s c 99 %d; chmod a+rw %s\"", cfg->cwda_device, devno, cfg->cwda_device); 
        }
        if (errno==EACCES && verbose) {
            log_addf("Tip: try to run as root \"chmod a+rw %s\"", cfg->cwda_device); 
        }
        close(cwda->fd);
        cwda->fd=-1;
        return -1;
    }

    mode=PARPORT_MODE_PCSPP;
    if (ioctl(cwda->fd, PPSETMODE, &mode)<0){
        if (verbose) log_addf("Can't set %s to EPP mode %s", cfg->cwda_device, cfg->cwda_device, errno, strerror_r(errno, errbuf, sizeof(errbuf)));
        close(cwda->fd);
        cwda->fd=-1;
    return -1;
    }

    if (ioctl(cwda->fd, PPEXCL, NULL)<0){
        if (verbose) log_addf("Can't exclusive access to %s %s", cfg->cwda_device, cfg->cwda_device, errno, strerror_r(errno, errbuf, sizeof(errbuf)));
        close(cwda->fd);
        cwda->fd=-1;
        return -1;
    }

    if (ioctl(cwda->fd, PPCLAIM, NULL)<0){
        if (verbose) log_addf("Can't claim %s %s", cfg->cwda_device, strerror_r(errno, errbuf, sizeof(errbuf)));
        if (errno==ENXIO && verbose){
            log_addf("Tip: try to run as root \"rmmod lp\"");
            log_addf("Tip: or kill process listed in \"lsof %s\"", cfg->cwda_device);
        }
        close(cwda->fd);
        cwda->fd=-1;
        return -1;
    }
    
    
      frob.mask = PARPORT_CONTROL_STROBE;
      frob.val = PARPORT_CONTROL_STROBE;
      if (ioctl(cwda->fd, PPFCONTROL, &frob)<0){
        if (verbose) log_addf("Can't set parport_STROBE %s", strerror_r(errno, errbuf, sizeof(errbuf))); 
        close(cwda->fd);
        cwda->fd=-1;
        return 1;
    }
    parport_reset(cwda);
    return 0;
}

/* linux ppdev */
int parport_free(struct cwdaemon *cwda){
      struct ppdev_frob_struct frob;
    char errbuf[1024];
    
    if (!cwda) return 0;
      
    if (cwda->fd>=0){
        frob.mask = PARPORT_CONTROL_STROBE;
        frob.val = 0;
        if (ioctl(cwda->fd, PPFCONTROL, &frob)<0){
            dbg("Can't clear parport_STROBE %s\n", strerror_r(errno, errbuf, sizeof(errbuf))); 
        }
        close(cwda->fd);
        cwda->fd=-1;
    }
      return 0;
}

/* linux ppdev */
int parport_reset(struct cwdaemon *cwda){
    parport_ptt(cwda, 0);
    parport_cw(cwda, 0);
    parport_ssbway(cwda, 0);
      return 0;
}

/* linux ppdev */
int parport_cw(struct cwdaemon *cwda, int onoff){
      struct ppdev_frob_struct frob;
    char errbuf[1024];
    
    if (!cwda || cwda->fd<0) return 1;
    
      frob.mask = PARPORT_CONTROL_SELECT;
      frob.val = !onoff?PARPORT_CONTROL_SELECT:0;
      if (ioctl(cwda->fd, PPFCONTROL, &frob)<0){
        dbg("Can't %s parport_SELECT %s\n", onoff?"set":"clear", strerror_r(errno, errbuf, sizeof(errbuf))); 
        close(cwda->fd);
        cwda->fd=-1;
        return 1;
    }
    return 0;
}

/* linux ppdev */
int parport_ptt(struct cwdaemon *cwda, int onoff){
      struct ppdev_frob_struct frob;
    char errbuf[1024];
    
    if (!cwda) return 1;
    if (cwda->fd<0 && parport_open(cwda, 0)) return 1;
    
      frob.mask = PARPORT_CONTROL_INIT;
      frob.val = onoff?PARPORT_CONTROL_INIT:0;
      if (ioctl(cwda->fd, PPFCONTROL, &frob)<0){
        dbg("Can't %s parport_INIT %s\n", onoff?"set":"clear", strerror_r(errno, errbuf, sizeof(errbuf))); 
        close(cwda->fd);
        cwda->fd=-1;
        return 1;
    }
    return 0;
}

/* linux ppdev */
int parport_ssbway(struct cwdaemon *cwda, int onoff){
      struct ppdev_frob_struct frob;
    char errbuf[1024];
    
    /*dbg("ssbway(%d)\n", onoff);*/

    if (!cwda) return 1;
    if (cwda->fd<0 && parport_open(cwda, 0)) return 1;
    
      frob.mask = PARPORT_CONTROL_AUTOFD;
      frob.val = onoff?PARPORT_CONTROL_AUTOFD:0;
      if (ioctl(cwda->fd, PPFCONTROL, &frob)<0){
        dbg("Can't %s parport_AUTOFD %s\n", onoff?"set":"clear", strerror_r(errno, errbuf, sizeof(errbuf))); 
        close(cwda->fd);
        cwda->fd=-1;
        return 1;
    }
    return 0;
}

void parport_info(){
    int port;
    int fd;
    char s[1024];
    char errbuf[1024];
    unsigned int modes;
    int mode;

    printf("\n  parport_info:\n");
    for (port=0;port<4;port++){
        sprintf(s, "/dev/parport%d", port);
        fd=open(s, O_RDWR|O_NONBLOCK);
        if (fd<0){
            if (errno==ENOENT) continue;
            printf("Found /dev/parport%d but cannot open it: %s\n", port, strerror_r(errno, errbuf, sizeof(errbuf)));
            continue;
        }
        if (ioctl(fd, PPGETMODES, &modes)<0){
            if (errno==ENODEV) continue;
            printf("Can't get modes for /dev/parport%d: %s\n", port, strerror_r(errno, errbuf, sizeof(errbuf)));
            close(fd);
            continue;
        }
        printf("Found /dev/parport%d\n", port);
        
        printf(" modes: 0x%x ", modes);
        if (modes&PARPORT_MODE_PCSPP)     printf("SPP ");
        if (modes&PARPORT_MODE_TRISTATE)  printf("TRISTATE ");
        if (modes&PARPORT_MODE_EPP)       printf("EPP ");
        if (modes&PARPORT_MODE_ECP)       printf("ECP ");
        if (modes&PARPORT_MODE_COMPAT)    printf("COMPAT ");
        if (modes&PARPORT_MODE_DMA)       printf("DMA ");
        if (modes&PARPORT_MODE_SAFEININT) printf("SAFEINIT ");
        printf("\n");
        
        if (ioctl(fd, PPGETMODE, &mode)<0){
            close(fd);
            continue;
        }
        printf(" mode: 0x%x ", mode);
        if (mode==0) printf("NIBBLE ");
        if (mode&IEEE1284_MODE_BYTE)   printf("BYTE ");
        if (mode&IEEE1284_MODE_COMPAT) printf("COMPAT ");
        if (mode&IEEE1284_MODE_BECP)   printf("Bounded_ECP ");
        if (mode&IEEE1284_MODE_ECP)    printf("ECP ");
        if (mode&IEEE1284_MODE_ECPRLE) printf("ECP_RLE ");
        if (mode&IEEE1284_MODE_ECPSWE) printf("Software_ECP ");
        if (mode&IEEE1284_MODE_EPP)    printf("EPP ");
        if (mode&IEEE1284_MODE_EPPSL)  printf("EPP_1.7 ");
        if (mode&IEEE1284_MODE_EPPSWE) printf("Software_EPP ");
        if (mode&IEEE1284_DEVICEID)    printf("DEVICEID ");
        printf("\n");
        close(fd);
    }
    printf("\n");
}
#endif

Generated by  Doxygen 1.6.0   Back to index