From a386b0a960a724f9b735b22afcb3d314358a4612 Mon Sep 17 00:00:00 2001 From: Alessandro Zummo Date: Wed, 26 Dec 2007 11:18:26 +0000 Subject: [PATCH] added udp support functions --- include/sane/sanei_udp.h | 34 +++++++ sanei/Makefile.in | 6 +- sanei/sanei_udp.c | 196 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 233 insertions(+), 3 deletions(-) create mode 100644 include/sane/sanei_udp.h create mode 100644 sanei/sanei_udp.c diff --git a/include/sane/sanei_udp.h b/include/sane/sanei_udp.h new file mode 100644 index 000000000..b84c678cd --- /dev/null +++ b/include/sane/sanei_udp.h @@ -0,0 +1,34 @@ +/* sane - Scanner Access Now Easy. + * Copyright (C) 2007 Tower Technologies + * Author: Alessandro Zummo + * This file is part of the SANE package. + * + * This file is in the public domain. You may use and modify it as + * you see fit, as long as this copyright message is included and + * that there is an indication as to what modifications have been + * made (if any). + * + * SANE 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. + * + * Header file for UDP/IP communications. + */ + +#ifndef sanei_udp_h +#define sanei_udp_h + +#include + +#include +#include + +extern SANE_Status sanei_udp_open(const char *host, int port, int *fdp); +extern SANE_Status sanei_udp_open_broadcast(int *fdp); +extern void sanei_udp_close(int fd); +extern ssize_t sanei_udp_write(int fd, const u_char * buf, int count); +extern ssize_t sanei_udp_read(int fd, u_char * buf, int count); +extern ssize_t sanei_udp_write_broadcast(int fd, int port, const u_char * buf, int count); +extern ssize_t sanei_udp_recvfrom(int fd, u_char * buf, int count, char **fromp); + +#endif /* sanei_udp_h */ diff --git a/sanei/Makefile.in b/sanei/Makefile.in index 52fe658ad..3f3870990 100644 --- a/sanei/Makefile.in +++ b/sanei/Makefile.in @@ -52,14 +52,14 @@ LIBSANEI_OBJS = sanei_ab306.o sanei_constrain_value.o sanei_init_debug.o \ sanei_net.o sanei_wire.o sanei_codec_ascii.o sanei_codec_bin.o \ sanei_scsi.o sanei_config.o sanei_config2.o sanei_pio.o sanei_pa4s2.o \ sanei_auth.o sanei_usb.o sanei_thread.o sanei_pv8630.o sanei_pp.o \ - sanei_lm983x.o sanei_access.o @SANEI_JPEG@ sanei_tcp.o + sanei_lm983x.o sanei_access.o @SANEI_JPEG@ sanei_tcp.o sanei_udp.o LIBSANEI_LTOBJS = sanei_ab306.lo sanei_constrain_value.lo sanei_init_debug.lo \ sanei_net.lo sanei_wire.lo sanei_codec_ascii.lo sanei_codec_bin.lo \ sanei_scsi.lo sanei_config.lo sanei_config2.lo sanei_pio.lo \ sanei_pa4s2.lo sanei_auth.lo sanei_usb.lo sanei_thread.lo \ sanei_pv8630.lo sanei_lm983x.lo sanei_pp.lo sanei_access.lo @SANEI_JPEG_LO@ \ - sanei_tcp.lo + sanei_tcp.lo sanei_udp.lo TARGETS = libsanei.a $(LIBSANEI_LTOBJS) TESTPROGRAMS = test_wire @@ -70,7 +70,7 @@ DISTFILES = Makefile.in linux_sg3_err.h os2_srb.h sanei_DomainOS.c \ sanei_constrain_value.c sanei_init_debug.c sanei_jpeg.c \ sanei_net.c sanei_pa4s2.c sanei_pio.c sanei_pv8630.c sanei_lm983x.c \ sanei_scsi.c sanei_thread.c sanei_usb.c sanei_pp.c \ - sanei_wire.c test_wire.c sanei_access.c sanei_tcp.c + sanei_wire.c test_wire.c sanei_access.c sanei_tcp.c sanei_udp.c .PHONY: all check clean depend dist distclean install uninstall diff --git a/sanei/sanei_udp.c b/sanei/sanei_udp.c new file mode 100644 index 000000000..fd067113f --- /dev/null +++ b/sanei/sanei_udp.c @@ -0,0 +1,196 @@ +/* sane - Scanner Access Now Easy. + Copyright (C) 2006 Tower Technologies + Author: Alessandro Zummo + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. */ + +#include "../include/sane/config.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +#define BACKEND_NAME sanei_udp + +#include "../include/sane/sane.h" +#include "../include/sane/sanei_debug.h" +#include "../include/sane/sanei_udp.h" + +static SANE_Status +sanei_udp_socket(int *fdp, int broadcast) +{ + int fd; + + if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) + return SANE_STATUS_INVAL; + + if (broadcast) { + int opt = 1; + if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, + (char *) &opt, sizeof(opt)) < 0) { + close(fd); + return SANE_STATUS_INVAL; + } + } + + *fdp = fd; + + return SANE_STATUS_GOOD; +} + +static SANE_Status +sanei_udp_connect(int fd, const char *host, int port) +{ + int err; + struct sockaddr_in saddr; + struct hostent *h; + + h = gethostbyname(host); + + if (h == NULL || h->h_addr_list[0] == NULL + || h->h_addrtype != AF_INET) + return SANE_STATUS_INVAL; + + memset(&saddr, 0x00, sizeof(struct sockaddr_in)); + + saddr.sin_family = AF_INET; + saddr.sin_port = htons(port); + memcpy(&saddr.sin_addr, h->h_addr_list[0], h->h_length); + + if ((err = connect(fd, (struct sockaddr *) &saddr, + sizeof(struct sockaddr_in))) != 0) { + return SANE_STATUS_INVAL; + } + + return SANE_STATUS_GOOD; +} + +SANE_Status +sanei_udp_open(const char *host, int port, int *fdp) +{ + int status; + + DBG_INIT(); + DBG(1, "%s\n", __func__); + + status = sanei_udp_socket(fdp, 0); + if (status != SANE_STATUS_GOOD) + return status; + + status = sanei_udp_connect(*fdp, host, port); + if (status != SANE_STATUS_GOOD) { + close(*fdp); + return status; + } + + return status; +} + +SANE_Status +sanei_udp_open_broadcast(int *fdp) +{ + int status; + + DBG_INIT(); + DBG(1, "%s\n", __func__); + + status = sanei_udp_socket(fdp, 1); + if (status != SANE_STATUS_GOOD) + return status; + + return status; +} + +void +sanei_udp_close(int fd) +{ + close(fd); +} + +ssize_t +sanei_udp_write(int fd, const u_char * buf, int count) +{ + return send(fd, buf, count, 0); +} + +ssize_t +sanei_udp_write_broadcast(int fd, int port, const u_char * buf, int count) +{ + struct sockaddr_in saddr; + + memset(&saddr, 0x00, sizeof(struct sockaddr_in)); + + saddr.sin_family = AF_INET; + saddr.sin_port = htons(port); + saddr.sin_addr.s_addr = htonl(INADDR_BROADCAST); + + return sendto(fd, buf, count, 0, + (struct sockaddr *)&saddr, sizeof(saddr)); +} + +ssize_t +sanei_udp_read(int fd, u_char * buf, int count) +{ + return recv(fd, buf, count, MSG_WAITALL); +} + +ssize_t +sanei_udp_recvfrom(int fd, u_char * buf, int count, char **fromp) +{ + ssize_t l; + socklen_t fl; + struct sockaddr_in from; + + fl = sizeof(from); + + l = recvfrom(fd, buf, count, MSG_DONTWAIT, + (struct sockaddr *) &from, &fl); + + if (l > 0 && fromp) { + *fromp = inet_ntoa(from.sin_addr); + } + + return l; +} +