pax_global_header00006660000000000000000000000064132733343450014521gustar00rootroot0000000000000052 comment=16a45179a85268100af779c9b9f074b4912073c9 liblxi-1.13/000077500000000000000000000000001327333434500127305ustar00rootroot00000000000000liblxi-1.13/.gitignore000066400000000000000000000007301327333434500147200ustar00rootroot00000000000000*.tar.xz Makefile.in Makefile aclocal.m4 autom4te.cache/ configure compile depcomp install-sh missing src/Makefile.in src/Makefile config.log config.status .deps/ .libs/ src/include/config.h src/include/config.h.in src/include/config.h.in~ src/include/stamp-h1 src/include/vxi11core.h src/vxi11core_clnt.c src/vxi11core_svc.c src/vxi11core_xdr.c *.swp *.asc /ar-lib .dirstamp *.a *.o *.la *.lo /ltmain.sh /config.guess /config.sub /libtool /m4 liblxi-1.13/.travis.yml000066400000000000000000000003701327333434500150410ustar00rootroot00000000000000sudo: true language: c install: - sudo apt-get -qq update - sudo apt-get install -y libavahi-core-dev libavahi-common-dev libavahi-client-dev libxml2-dev libtirpc-dev before_script: ./autogen.sh script: ./configure && make && sudo make install liblxi-1.13/AUTHORS000066400000000000000000000004071327333434500140010ustar00rootroot00000000000000Maintainer: Martin Lund Contributors: Robert Scheck Jakub Wilk Dima Kogan Dmitri Goutnik Thanks to everyone who has contributed to this project. liblxi-1.13/COPYING000066400000000000000000000137101327333434500137650ustar00rootroot00000000000000*** BSD-3 ********************************************************************* Unless otherwise *explicitly* stated, liblxi is available for use under the following license, commonly known as the 3-clause (or "modified") BSD license: ----------------------------------------------------------------------- Copyright (c) 2016-2017, Martin Lund All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holders nor contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------- *** EPICS ********************************************************************* The following files: src/vxi11core.rpcl src/vxi11core_clnt.c (automatically generated during build) src/include/vxi11core.h (automatically generated during build) src/vxi11core.rpcl (automatically generated during build) src/vxi11core_svc.c (automatically generated during build) src/vxi11core_xdr.c (automatically generated during build) Are covered by this EPICS license: Copyright (c) 2002 University of Chicago, The Regents of the University of California, and Berliner Elektronenspeicherring Gesellschaft fuer Synchrotronstrahlung m.b.H. (BESSY) All rights reserved. Copyright (c) 2004 by Danfysik and Cosylab (Danfysik has funded the work performed by Cosylab). asynDriver is distributed subject to the following license conditions: SOFTWARE LICENSE AGREEMENT Software: asynDriver 1. The "Software", below, refers to asynDriver (in either source code, or binary form and accompanying documentation). Each licensee is addressed as "you" or "Licensee." 2. The copyright holders shown above and their third-party licensors hereby grant Licensee a royalty-free nonexclusive license, subject to the limitations stated herein and U.S. Government license rights. 3. You may modify and make a copy or copies of the Software for use within your organization, if you meet the following conditions: a. Copies in source code must include the copyright notice and this Software License Agreement. b. Copies in binary form must include the copyright notice and this Software License Agreement in the documentation and/or other materials provided with the copy. 4. You may modify a copy or copies of the Software or any portion of it, thus forming a work based on the Software, and distribute copies of such work outside your organization, if you meet all of the following conditions: a. Copies in source code must include the copyright notice and this Software License Agreement; b. Copies in binary form must include the copyright notice and this Software License Agreement in the documentation and/or other materials provided with the copy; c. Modified copies and works based on the Software must carry prominent notices stating that you changed specified portions of the Software. 5. Portions of the Software resulted from work developed under a U.S. Government contract and are subject to the following license: the Government is granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable worldwide license in this computer software to reproduce, prepare derivative works, and perform publicly and display publicly. 6. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDERS, THEIR THIRD PARTY LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL BE CORRECTED. 7. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT HOLDERS, THEIR THIRD PARTY LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGES. liblxi-1.13/ChangeLog000066400000000000000000000102461327333434500145050ustar00rootroot00000000000000=== liblxi v1.13 === Changes since liblxi v1.12: * Fix Sun RPC headers configure check The Sun RPC headers have been moved out of glibc into a separate library, libtirpc. Hence, check for glibc headers first and in case that fails search for headers in libtirpc via pkg-config. * Add const qualifier Because it is the right thing to do. * Update Travis * Use libtirpc for Sun RPC headers * Move test directory Changes since liblxi v1.11: * Add send/receive sanity checks * Strip CR from ID response string Fixes corrupted output from 'lxi discover'. Changes since liblxi v1.10: * Fix mDNS/DNS-SD discover feature Changes since liblxi v1.9: * Update Travis * Cleanup * Add --disable-avahi configure option Makes avahi mandatory unless --disable-avahi is provided. Changes since liblxi v1.8: * Update AUTHORS * Convert tabs to spaces * Make API usable in C++ As suggested by Dima Kogan, lets wrap the API so that it is usable in C++. * Only export lxi API specific functions Hide visibility of internal functions so that only the lxi API specific ones are exported/visible to applications linking with liblxi. These changes are applied on behalf of Dima Kogan. * Add discover fallback to request ID via HTTP/XML If retrieving the instrument ID fails via VXI-11 during discovery then try to retrieve the ID via the /lxi/identification XML file hosted by some instruments via HTTP. Adds dependency on libxml2. Dmitri Goutnik: * Make code clang friendly, fix warnings Changes since liblxi v1.7: * Fix lxi_connect() so it does not apply lock Some instruments fail to lock for exclusive access when creating a VXI-11 connection. So, to play it safe, we will simply not try to lock when setting up the connection. Changes since liblxi v1.6: * Update to new URL * Update README * Update AUTHORS * Use HTTPS in the configure script Jakub Wilk: * Fix typos Changes since liblxi v1.5: * Update README * Add authors section in README * Add README.md to prettify GitHub page Changes since liblxi v1.4: * Add support for mDNS/DNS-SD discovery Add parameter to lxi_discover() so it is possible to select discovery using VXI-11 or mDNS/DNS-SD. If detected available, Avahi is used as the mDNS/DNS-SD backend implementation. * Print errors to stderr * Update README Changes since liblxi v1.3: * Fix discover output strings Discovery of multiple LXI instruments revealed a bug in the id string handling which results in garbled output strings. Adding missing string termination fixes this. * Add timeout handling for raw/TCP * Update examples * Cleanup * Update README * Add support for configurable protocol backends Reworked the code to support configurable protocol backends. Currently supported protocols include VXI11 and raw TCP. In the future support for HiSlip can be added. Changes since liblxi v1.2: * Fix building with multiple jobs (make -jN, N>1) * Update README Changes since liblxi v1.1: * Added AUTHORS file * Update COPYING * Update README * Update connect test * Improve lxi_connect() with device name and timeout * Make timeout error message human readable Lets explain the most common error, that is timeout, in a human readable format. * Fix timeout handling * Use thread-safe version of VXI11 function calls * Autogenerate VXI11 RPC functions Automatically generate VXI11 RPC functions instead of using bundled or system provided VXI11 library. This allows us to generate thread-safe versions of the VXI11 RPC functions in the future. Changes since liblxi v1.0: * Fixed instrument not responding Use the default LAN Device Name of "inst0". Some instruments do not respond if this device name is not used. * Remove unused rpcgen tool check * Cleanup rpc header check * Add support for use of system VXI library Added configure option '--with-vxi=[internal/system]' which allows the user to decide whether to use the internally bundled VXI library or the VXI library provided by the system. By default the internal VXI library is used. liblxi v1.0: * First release (stable) liblxi-1.13/Makefile.am000066400000000000000000000000221327333434500147560ustar00rootroot00000000000000SUBDIRS = src man liblxi-1.13/README000066400000000000000000000067011327333434500136140ustar00rootroot00000000000000 === liblxi === 1. Introduction liblxi is an open source software library which offers a simple API for communicating with LXI compatible instruments. The API allows applications to discover instruments on your network, send SCPI commands, and receive responses. Currently the library supports VXI-11/TCP and RAW/TCP connections. Future work include adding support for the newer and more efficient HiSlip protocol which is used by next generation LXI instruments. The library is based on the VXI-11 RPC protocol implementation which is part of the asynDriver EPICS module, which, at time of writing, is available from: http://www.aps.anl.gov/epics/modules/soft/asyn/index.html 2. The liblxi API The API is small and simple. It includes functions required for discovering and communicating SCPI messages with LXI devices: int lxi_init(void); int lxi_discover(struct lxi_info_t *info, int timeout, lxi_discover_t type); int lxi_connect(const char *address, int port, const char *name, int timeout, lxi_protocol_t protocol); int lxi_send(int device, const char *message, int length, int timeout); int lxi_receive(int device, char *message, int length, int timeout); int lxi_disconnect(int device); Note: type is DISCOVER_VXI11 or DISCOVER_MDNS Note: protocol is VXI11 or RAW 3. API usage Here is a simple code example on how to use the liblxi API: #include #include #include int main() { char response[65536]; int device, length, timeout = 1000; char *command = "*IDN?"; // Initialize LXI library lxi_init(); // Connect to LXI device device = lxi_connect("10.42.0.42", 0, "inst0", timeout, VXI11); // Send SCPI command lxi_send(device, command, strlen(command), timeout); // Wait for response lxi_receive(device, response, sizeof(response), timeout); printf("%s\n", response); // Disconnect lxi_disconnect(device); } The example above prints the ID string of the LXI instrument. For example, a Rigol DS1104Z oscilloscope would respond: RIGOL TECHNOLOGIES,DS1104Z,DS1ZA1234567890,00.04.03 See src/test for more examples. 4. Installation The latest release version can be downloaded from https://lxi-tools.github.io 4.1 Installation using release tarball Install steps: $ ./configure $ make $ make install 4.2 Installation using package liblxi comes prepackaged for various GNU/Linux distributions. Visit https://lxi-tools.github.io to see list of supported distributions. 5. Contributing liblxi is open source. If you want to help out with the project please join in. All contributions (bug reports, code, doc, ideas, etc.) are welcome. Please use the github issue tracker and pull request features. Also, if you find this free open source software useful please consider making a donation: https://www.paypal.me/lundmar 6. Website Visit https://lxi-tools.github.io 7. License liblxi includes code covered by the following licenses: * BSD-3, commonly known as the 3-clause (or "modified") BSD license * EPICS Open software license For license details please see the COPYING file. 8. Authors Created by Martin Lund See the AUTHORS file for full list of authors. liblxi-1.13/README.md000066400000000000000000000070511327333434500142120ustar00rootroot00000000000000# liblxi [![Build Status](https://travis-ci.org/lxi-tools/liblxi.svg?branch=master)](https://travis-ci.org/lxi-tools/liblxi) ## 1. Introduction liblxi is an open source software library which offers a simple API for communicating with LXI compatible instruments. The API allows applications to discover instruments on your network, send SCPI commands, and receive responses. Currently the library supports VXI-11/TCP and RAW/TCP connections. Future work include adding support for the newer and more efficient HiSlip protocol which is used by next generation LXI instruments. The library is based on the VXI-11 RPC protocol implementation which is part of the asynDriver EPICS module, which, at time of writing, is available from: http://www.aps.anl.gov/epics/modules/soft/asyn/index.html ## 2. The liblxi API The API is small and simple. It includes functions required for discovering and communicating SCPI messages with LXI devices: ``` int lxi_init(void); int lxi_discover(struct lxi_info_t *info, int timeout, lxi_discover_t type); int lxi_connect(const char *address, int port, const char *name, int timeout, lxi_protocol_t protocol); int lxi_send(int device, const char *message, int length, int timeout); int lxi_receive(int device, char *message, int length, int timeout); int lxi_disconnect(int device); ``` Note: `type` is `DISCOVER_VXI11` or `DISCOVER_MDNS` Note: `protocol` is `VXI11` or `RAW` ## 3. API usage Here is a simple code example on how to use the liblxi API: ``` #include #include #include int main() { char response[65536]; int device, length, timeout = 1000; char *command = "*IDN?"; // Initialize LXI library lxi_init(); // Connect to LXI device device = lxi_connect("10.42.0.42", 0, "inst0", timeout, VXI11); // Send SCPI command lxi_send(device, command, strlen(command), timeout); // Wait for response lxi_receive(device, response, sizeof(response), timeout); printf("%s\n", response); // Disconnect lxi_disconnect(device); } ``` The example above prints the ID string of the LXI instrument. For example, a Rigol DS1104Z oscilloscope would respond: ``` RIGOL TECHNOLOGIES,DS1104Z,DS1ZA1234567890,00.04.03 ``` See src/test for more examples. ## 4. Installation The latest release version can be downloaded from https://lxi-tools.github.io ### 4.1 Installation using release tarball Install steps: ``` $ ./configure $ make $ make install ``` ### 4.2 Installation using package liblxi comes prepackaged for various GNU/Linux distributions. Visit https://lxi-tools.github.io to see list of supported distributions. ## 5. Contributing liblxi is open source. If you want to help out with the project please join in. All contributions (bug reports, code, doc, ideas, etc.) are welcome. Please use the github issue tracker and pull request features. Also, if you find this free open source software useful please consider making a donation: [![Donate](https://www.paypal.com/en_US/i/btn/x-click-but21.gif)](https://www.paypal.me/lundmar) ## 6. Website Visit https://lxi-tools.github.io ## 7. License liblxi includes code covered by the following licenses: * BSD-3, commonly known as the 3-clause (or "modified") BSD license * EPICS Open software license For license details please see the COPYING file. ## 8. Authors Created by Martin Lund \ See the AUTHORS file for full list of authors. liblxi-1.13/autogen.sh000077500000000000000000000000401327333434500147230ustar00rootroot00000000000000autoreconf --force -v --install liblxi-1.13/configure.ac000066400000000000000000000044601327333434500152220ustar00rootroot00000000000000AC_PREREQ([2.68]) AC_INIT([liblxi], [1.13], [], [liblxi], [https://lxi-tools.github.io]) AC_CONFIG_HEADERS([src/include/config.h]) AM_INIT_AUTOMAKE([1.11 foreign dist-xz no-dist-gzip -Wall -Werror]) AM_SILENT_RULES([yes]) AM_PROG_AR LT_PREREQ([2.2]) LT_INIT # Before making a release, the LIBLXI_LT_VERSION string should be # modified. # The string is of the form C:R:A (Current, Revision, Age). # - If interfaces have been changed or added, but binary compatibility has # been preserved, change to C+1:0:A+1 # - If binary compatibility has been broken (e.g. removed or changed interfaces) # change to C+1:0:0 # - If the interface is the same as the previous version, change to C:R+1:A LIBLXI_LT_VERSION=1:0:0 AC_SUBST(LIBLXI_LT_VERSION) AC_ENABLE_SHARED AC_ENABLE_STATIC AC_PROG_CC AC_LANG([C]) AC_PROG_INSTALL PKG_PROG_PKG_CONFIG # Check for rpc headers rpc_headers_found=1 AC_CHECK_HEADERS(rpc/rpc.h, [], [rpc_headers_found=0]) if test $rpc_headers_found == 0 then # Check for libtirpc (Sun RPC, includes rpc.h etc.) PKG_CHECK_MODULES([libtirpc], [libtirpc]) fi # Check for rpcgen tool AC_PATH_PROG([RPCGEN], [rpcgen]) AC_ARG_VAR([RPCGEN], [RPC compiler command]) if test x$RPCGEN = x ; then AC_MSG_ERROR([could not locate rpcgen]) fi # Check for Avahi (mDNS/DNS-SD implementation) AC_ARG_ENABLE([avahi], AS_HELP_STRING([--disable-avahi], [Disable avahi mDNS feature])) AS_IF([test "x$enable_avahi" != "xno"], [ AC_CHECK_LIB([avahi-client], [avahi_client_new], [have_avahi_client=yes], [AC_ERROR(Missing avahi-client library)]) AC_CHECK_LIB([avahi-common], [avahi_simple_poll_new], [have_avahi_common=yes], [AC_ERROR(Missing avahi-common library)]) ]) if test x$have_avahi_client = xyes ; then if test x$have_avahi_common = xyes ; then have_avahi=yes AC_DEFINE([HAVE_AVAHI],[1],[Avahi available]) fi fi AM_CONDITIONAL([HAVE_AVAHI],[test "x$have_avahi" == "xyes"]) # Check for libxml2 PKG_CHECK_MODULES(LIBXML2_PC, [libxml-2.0], [CPPFLAGS="${CPPFLAGS} ${LIBXML2_PC_CFLAGS}" LIBS="${LIBS} ${LIBXML2_PC_LIBS}" AC_CHECK_LIB(xml2, xmlInitParser, [], AC_ERROR(Missing xml2 library)) ], [AC_ERROR(Missing xml2 library)]) AC_CHECK_HEADERS([libxml/xmlreader.h libxml/xmlwriter.h]) AC_CONFIG_FILES([Makefile]) AC_CONFIG_FILES([src/Makefile]) AC_CONFIG_FILES([man/Makefile]) AC_OUTPUT liblxi-1.13/man/000077500000000000000000000000001327333434500135035ustar00rootroot00000000000000liblxi-1.13/man/Makefile.am000066400000000000000000000001421327333434500155340ustar00rootroot00000000000000dist_man_MANS = lxi_init.3 lxi_connect.3 lxi_disconnect.3 lxi_send.3 lxi_receive.3 lxi_discover.3 liblxi-1.13/man/lxi_connect.3000066400000000000000000000014341327333434500160760ustar00rootroot00000000000000.TH "lxi_connect" "3" "October 2017" .SH "NAME" lxi_connect \- connect to LXI device .SH "SYNOPSIS" .PP .B #include .B int lxi_connect(char *address, int port, char *name, int timeout, lxi_protocol_t protocol); .SH "DESCRIPTION" .PP The .BR lxi_connect() function connects to a LXI device with .I name at IP address pointed to by .I address .PP If .I name is NULL then the default name "inst0" will be used. .PP .I protocol is either VXI11 or RAW. .PP If .I protocol is RAW then .I port will be used as destination port. .PP The .I timeout is in milliseconds. .SH "RETURN VALUE" Upon successful completion .BR lxi_connect() returns a new connection handle, or .BR LXI_ERROR if an error occurred. .SH "SEE ALSO" .BR lxi_send (3), .BR lxi_receive (3), .BR lxi_disconnect (3), liblxi-1.13/man/lxi_disconnect.3000066400000000000000000000010161327333434500165720ustar00rootroot00000000000000.TH "lxi_disconnect" "3" "October 2017" .SH "NAME" lxi_disconnect \- disconnect a LXI connection .SH "SYNOPSIS" .PP .B #include .B int lxi_disconnect(int device); .SH "DESCRIPTION" .PP The .BR lxi_disconnect() function disconnects an existing LXI connection handle pointed to by .I device .SH "RETURN VALUE" Upon successful completion .BR lxi_disconnect() returns .BR LXI_OK , else .BR LXI_ERROR is returned if an error occurred. .SH "SEE ALSO" .BR lxi_send (3), .BR lxi_receive (3), .BR lxi_disconnect (3), liblxi-1.13/man/lxi_discover.3000066400000000000000000000042011327333434500162560ustar00rootroot00000000000000.TH "lxi_discover" "3" "October 2017" .SH "NAME" lxi_discover \- search for LXI devices on network .SH "SYNOPSIS" .PP .B #include .B int lxi_discover(lxi_info_t *info, int timeout, lxi_discover_t type); .SH "DESCRIPTION" .PP The .BR lxi_discover() function searches for LXI devices or services on the local network using VXI-11 or mDNS/DNS-SD respectively. Which discover .I type is used is defined as follows: .sp .nf typedef enum { DISCOVER_VXI11, DISCOVER_MDNS } lxi_discover_t; .fi .PP During the discover operation events and results are returned by callbacks registered via the .I info structure, defined as follows: .sp .nf typedef struct { void (*broadcast)(char *address, char *interface); void (*device)(char *address, char *id); void (*service)(char *address, char *id, char *service, int port); } lxi_info_t; .fi .PP The .I broadcast callback is called whenever a new network interface is searched (DISCOVER_VXI11 only). The .I device callback is called whenever a new LXI device is found (DISCOVER_VXI11 only). The .I service callback is called whenever a new LXI service is found (DISCOVER_MDNS only). .PP The .I timeout is in milliseconds. .SH "RETURN VALUE" Upon successful completion .BR lxi_discover() returns .BR LXI_OK , or .BR LXI_ERROR if an error occurred. .SH EXAMPLE .PP The following example searches for LXI devices using VXI-11 and prints the ID and IP addresses of found devices: .nf #include #include void broadcast(char *address, char *interface) { printf("Broadcasting on interface %s\\n", interface); } void device(char *address, char *id) { printf(" Found %s on address %s\\n", id, address); } int main() { lxi_info_t info; // Initialize LXI library lxi_init(); // Set up search information callbacks info.broadcast = &broadcast; info.device = &device; printf("Searching for LXI devices - please wait...\\n"); // Search for LXI devices, 1 second timeout lxi_discover(&info, 1000, DISCOVER_VXI11); return 0; } .fi .SH "SEE ALSO" .BR lxi_init (3) .BR lxi_open (3), .BR lxi_close (3) .BR lxi_receive (3), .BR lxi_disconnect (3), liblxi-1.13/man/lxi_init.3000066400000000000000000000010071327333434500154040ustar00rootroot00000000000000.TH "lxi_init" "3" "October 2017" .SH "NAME" lxi_init \- initialize LXI library .SH "SYNOPSIS" .PP .B #include .B int lxi_init(void); .SH "DESCRIPTION" .PP The .BR lxi_init() function initializes the LXI library. This is required before calling any other available lxi functions. .SH "RETURN VALUE" Upon successful completion .BR lxi_init() returns .BR LXI_OK , or .BR LXI_ERROR if an error occurred. .SH "SEE ALSO" .BR lxi_connect (3), .BR lxi_send (3), .BR lxi_receive (3), .BR lxi_disconnect (3), liblxi-1.13/man/lxi_receive.3000066400000000000000000000011471327333434500160700ustar00rootroot00000000000000.TH "lxi_send" "3" "October 2017" .SH "NAME" lxi_receive \- receive message from LXI device .SH "SYNOPSIS" .PP .B #include .B int lxi_receive(int device, char *message, int length, int timeout); .SH "DESCRIPTION" .PP The . .BR lxi_receive() function receives up to .I length bytes in the message buffer pointed to by .I message .PP The .I timeout is in milliseconds. .SH "RETURN VALUE" Upon successful completion .BR lxi_receive() returns the number of bytes successfully received, or .BR LXI_ERROR if an error occurred. .SH "SEE ALSO" .BR lxi_open (3), .BR lxi_send (3), .BR lxi_disconnect (3), liblxi-1.13/man/lxi_send.3000066400000000000000000000011141327333434500153710ustar00rootroot00000000000000.TH "lxi_send" "3" "October 2017" .SH "NAME" lxi_send \- send message to LXI device .SH "SYNOPSIS" .PP .B #include .B int lxi_send(int device, char *message, int length, int timeout); .SH "DESCRIPTION" .PP The .BR lxi_send() function sends .I length bytes from the message buffer pointed to by .I message .PP The .I timeout is in milliseconds. .SH "RETURN VALUE" Upon successful completion .BR lxi_send() returns the number of bytes successfully sent, or .BR LXI_ERROR if an error occurred. .SH "SEE ALSO" .BR lxi_open (3), .BR lxi_receive (3), .BR lxi_disconnect (3), liblxi-1.13/src/000077500000000000000000000000001327333434500135175ustar00rootroot00000000000000liblxi-1.13/src/Makefile.am000066400000000000000000000024421327333434500155550ustar00rootroot00000000000000lib_LTLIBRARIES = liblxi.la EXTRA_DIST = vxi11core.rpcl liblxidir = $(includedir) liblxi_HEADERS = include/lxi.h nodist_liblxi_la_SOURCES = vxi11core_clnt.c \ vxi11core_xdr.c \ include/vxi11core.h liblxi_la_SOURCES = include/lxi.h \ include/session.h \ include/vxi11.h \ include/tcp.h \ include/error.h \ include/mdns.h \ lxi.c \ vxi11.c \ tcp.c \ mdns.c if HAVE_AVAHI liblxi_la_SOURCES += avahi.c \ include/avahi.h endif BUILT_SOURCES = vxi11core_clnt.c \ vxi11core_xdr.c \ include/vxi11core.h CLEANFILES = vxi11core_clnt.c \ vxi11core_xdr.c \ vxi11core_svc.c \ include/vxi11core.h liblxi_la_CFLAGS = -I$(top_srcdir)/src/include -fvisibility=hidden -D_GNU_SOURCE @libtirpc_CFLAGS@ liblxi_la_LDFLAGS = -version-info $(LIBLXI_LT_VERSION) -init,init @libtirpc_LIBS@ if HAVE_AVAHI liblxi_la_LDFLAGS += -lavahi-client -lavahi-common endif .NOTPARALLEL: vxi11core_clnt.c vxi11core_xdr.c include/vxi11core.h: rpcgen -M vxi11core.rpcl mv vxi11core.h include liblxi-1.13/src/avahi.c000066400000000000000000000177761327333434500147750ustar00rootroot00000000000000/* * Copyright (c) 2017 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "error.h" #include "avahi.h" static AvahiSimplePoll *simple_poll = NULL; static AvahiServiceBrowser *sb[10] = {}; static lxi_info_t *lxi_info; static int timeout_discover = 0; static int count = 0; static void avahi_resolve_callback( AvahiServiceResolver *r, AVAHI_GCC_UNUSED AvahiIfIndex interface, AVAHI_GCC_UNUSED AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host_name, const AvahiAddress *address, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, AVAHI_GCC_UNUSED void* userdata) { assert(r); /* Called whenever a service has been resolved successfully or timed out */ switch (event) { case AVAHI_RESOLVER_FAILURE: error_printf("(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r)))); break; case AVAHI_RESOLVER_FOUND: { char a[AVAHI_ADDRESS_STR_MAX] = "Unknown"; char *service_type = "Unknown"; // Pretty print service type if (strcmp(type, "_lxi._tcp") == 0) service_type = "lxi"; else if (strcmp(type, "_vxi-11._tcp") == 0) service_type = "vxi-11"; else if (strcmp(type, "_scpi-raw._tcp") == 0) service_type = "scpi-raw"; else if (strcmp(type, "_scpi-telnet._tcp") == 0) service_type = "scpi-telnet"; else if (strcmp(type, "_hislip._tcp") == 0) service_type = "hislip"; avahi_address_snprint(a, sizeof(a), address); lxi_info->service(a, (char *) name, service_type, port); } } avahi_service_resolver_free(r); } static void avahi_browse_callback( AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, void* userdata) { AvahiClient *c = userdata; assert(b); /* Called whenever a new services becomes available on the LAN or is removed from the LAN */ switch (event) { case AVAHI_BROWSER_FAILURE: error_printf("(Avahi) %s\n", avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b)))); avahi_simple_poll_quit(simple_poll); return; case AVAHI_BROWSER_NEW: if (!(avahi_service_resolver_new(c, interface, protocol, name, type, domain, AVAHI_PROTO_INET, 0, avahi_resolve_callback, c))) error_printf("Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(c))); break; case AVAHI_BROWSER_REMOVE: case AVAHI_BROWSER_ALL_FOR_NOW: case AVAHI_BROWSER_CACHE_EXHAUSTED: break; } } static void avahi_client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void * userdata) { assert(c); /* Called whenever the client or server state changes */ if (state == AVAHI_CLIENT_FAILURE) { error_printf("Server connection failure: %s\n", avahi_strerror(avahi_client_errno(c))); avahi_simple_poll_quit(simple_poll); } } static int create_service_browser(AvahiClient *client, char *service) { if (!(sb[count++] = avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_INET, service, NULL, 0, avahi_browse_callback, client))) { error_printf("Failed to create service browser: %s\n", avahi_strerror(avahi_client_errno(client))); return 1; } return 0; } int avahi_discover_(lxi_info_t *info, int timeout) { AvahiClient *client = NULL; int status = 1; int error; /* Setup callback structure and timeout for avahi service callback */ lxi_info = info; timeout_discover = timeout * 1000; /* Allocate main loop object */ if (!(simple_poll = avahi_simple_poll_new())) { error_printf("Failed to create simple poll object.\n"); goto fail; } /* Allocate a new client */ client = avahi_client_new(avahi_simple_poll_get(simple_poll), 0, avahi_client_callback, NULL, &error); /* Check whether creating the client object succeeded */ if (!client) { error_printf("Failed to create client: %s\n", avahi_strerror(error)); goto fail; } /* Create the service browsers */ if (create_service_browser(client, "_lxi._tcp")) goto fail_sb; if (create_service_browser(client, "_vxi-11._tcp")) goto fail_sb; if (create_service_browser(client, "_scpi-raw._tcp")) goto fail_sb; if (create_service_browser(client, "_scpi-telnet._tcp")) goto fail_sb; if (create_service_browser(client, "_hislip._tcp")) goto fail_sb; /* Run the main loop */ avahi_simple_poll_loop(simple_poll); status = 0; fail_sb: while (--count) avahi_service_browser_free(sb[count]); fail: if (client) avahi_client_free(client); if (simple_poll) avahi_simple_poll_free(simple_poll); return status; } typedef struct { lxi_info_t *info; int timeout; } data_t; void *discover(void *userdata) { data_t *data = userdata; avahi_discover_(data->info, data->timeout); } int avahi_discover(lxi_info_t *info, int timeout) { struct timespec ts; pthread_t thread; data_t data; int status; data.info = info; data.timeout = timeout; if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { error_printf("Failed to read system clock\n"); return -1; } ts.tv_sec += timeout / 1000; status = pthread_create(&thread, NULL, discover, (void*) &data); if (status != 0) { error_printf("Failed to create discover thread\n"); return -1; } pthread_timedjoin_np(thread, NULL, &ts); if (status != 0) { error_printf("Timeout waiting for discover thread\n"); return -1; } } liblxi-1.13/src/include/000077500000000000000000000000001327333434500151425ustar00rootroot00000000000000liblxi-1.13/src/include/avahi.h000066400000000000000000000032151327333434500164040ustar00rootroot00000000000000/* * Copyright (c) 2017 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef AVAHI_H #define AVAHI_H #include int avahi_discover(lxi_info_t *info, int timeout); #endif liblxi-1.13/src/include/error.h000066400000000000000000000032371327333434500164510ustar00rootroot00000000000000/* * Copyright (c) 2017 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef ERROR_H #define ERROR_H #define error_printf(format, args...) \ fprintf(stderr, "Error: " format, ## args) #endif liblxi-1.13/src/include/lxi.h000066400000000000000000000050031327333434500161050ustar00rootroot00000000000000/* * Copyright (c) 2016-2017, Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef LXI_H #define LXI_H #ifdef __cplusplus extern "C" { #endif #define LXI_OK 0 #define LXI_ERROR -1 typedef struct { void (*broadcast)(const char *address, const char *interface); void (*device)(const char *address, const char *id); void (*service)(const char *address, const char *id, const char *service, int port); } lxi_info_t; typedef enum { VXI11, RAW, HISLIP } lxi_protocol_t; typedef enum { DISCOVER_VXI11, DISCOVER_MDNS } lxi_discover_t; int lxi_init(void); int lxi_discover(lxi_info_t *info, int timeout, lxi_discover_t type); int lxi_discover_if(lxi_info_t *info, const char* ifname, int timeout, lxi_discover_t type); int lxi_connect(const char *address, int port, const char *name, int timeout, lxi_protocol_t protocol); int lxi_send(int device, const char *message, int length, int timeout); int lxi_receive(int device, char *message, int length, int timeout); int lxi_disconnect(int device); #ifdef __cplusplus } #endif #endif liblxi-1.13/src/include/mdns.h000066400000000000000000000031701327333434500162550ustar00rootroot00000000000000/* * Copyright (c) 2017 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef MDNS_H #define MDNS_H int mdns_discover(lxi_info_t *info, int timeout); #endif liblxi-1.13/src/include/session.h000066400000000000000000000037761327333434500170130ustar00rootroot00000000000000/* * Copyright (c) 2016-2017, Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef SESSION_H #define SESSION_H #include #include #define SESSIONS_MAX 256 struct session_t { bool allocated; bool connected; void *data; int (*connect)(void *data, const char *address, int port, const char *name, int timeout); int (*disconnect)(void *data); int (*send)(void *data, const char *message, int length, int timeout); int (*receive)(void *data, char *message, int length, int timeout); }; #endif liblxi-1.13/src/include/tcp.h000066400000000000000000000037221327333434500161050ustar00rootroot00000000000000/* * Copyright (c) 2016-2017, Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TCP_H #define TCP_H typedef struct { int server_socket; } tcp_data_t; int tcp_connect(void *data, const char *address, int port, const char *name, int timeout); int tcp_disconnect(void *data); int tcp_send(void *data, const char *message, int length, int timeout); int tcp_receive(void *data, char *message, int length, int timeout); int tcp_receive_wait(void *data, char *message, int length, int timeout); #endif liblxi-1.13/src/include/vxi11.h000066400000000000000000000040221327333434500162610ustar00rootroot00000000000000/* * Copyright (c) 2016-2017, Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef VXI11_H #define VXI11_H #include "vxi11core.h" #include typedef struct { CLIENT *rpc_client; Create_LinkResp link_resp; } vxi11_data_t; int vxi11_connect(void *data, const char *address, int port, const char *name, int timeout); int vxi11_disconnect(void *data); int vxi11_send(void *data, const char *message, int length, int timeout); int vxi11_receive(void *data, char *message, int length, int timeout); int vxi11_discover(lxi_info_t *info, int timeout); #endif liblxi-1.13/src/lxi.c000066400000000000000000000132121327333434500144560ustar00rootroot00000000000000/* * Copyright (c) 2016-2017, Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include "error.h" #include "session.h" #include "vxi11.h" #include "tcp.h" #include "mdns.h" #define EXPORT __attribute__((visibility("default"))) static struct session_t session[SESSIONS_MAX] = {}; static pthread_mutex_t session_mutex = PTHREAD_MUTEX_INITIALIZER; EXPORT int lxi_init(void) { int i; // Initialize session structures for (i = 0; i < SESSIONS_MAX; i++) { session[i].allocated = false; session[i].connected = false; } return LXI_OK; } EXPORT int lxi_connect(const char *address, int port, const char *name, int timeout, lxi_protocol_t protocol) { bool session_available = false; int i; pthread_mutex_lock(&session_mutex); // Find a free session entry for (i=0; i SESSIONS_MAX) return LXI_ERROR; pthread_mutex_lock(&session_mutex); // Disconnect if (session[device].connected) session[device].disconnect(session[device].data); // Free resources free(session[device].data); session[device].connected = false; session[device].allocated = false; pthread_mutex_unlock(&session_mutex); return LXI_OK; } EXPORT int lxi_send(int device, const char *message, int length, int timeout) { int bytes_sent; if (device < 0) return LXI_ERROR; if (session[device].connected == false) return LXI_ERROR; // Send bytes_sent = session[device].send(session[device].data, message, length, timeout); if (bytes_sent < 0) return LXI_ERROR; // Return number of bytes sent return bytes_sent; } EXPORT int lxi_receive(int device, char *message, int length, int timeout) { int bytes_received; if (device < 0) return LXI_ERROR; if (session[device].connected == false) return LXI_ERROR; // Receive bytes_received = session[device].receive(session[device].data, message, length, timeout); if (bytes_received < 0) return LXI_ERROR; // Return number of bytes received return bytes_received; } EXPORT int lxi_discover(lxi_info_t *info, int timeout, lxi_discover_t type) { switch (type) { case DISCOVER_VXI11: vxi11_discover(info, timeout); break; case DISCOVER_MDNS: mdns_discover(info, timeout); break; default: error_printf("Unknown discover type (%d)\n", type); return LXI_ERROR; } return LXI_OK; } liblxi-1.13/src/mdns.c000066400000000000000000000033641327333434500146320ustar00rootroot00000000000000/* * Copyright (c) 2017 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "config.h" #ifdef HAVE_AVAHI #include "avahi.h" #endif int mdns_discover(lxi_info_t *info, int timeout) { #ifdef HAVE_AVAHI avahi_discover(info, timeout); #endif return 0; } liblxi-1.13/src/tcp.c000066400000000000000000000122651327333434500144570ustar00rootroot00000000000000/* * Copyright (c) 2017, Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include "tcp.h" #include "error.h" int tcp_connect(void *data, const char *address, int port, const char *name, int timeout) { struct sockaddr_in server_address; struct hostent *host; tcp_data_t *tcp_data = (tcp_data_t *) data; // Create a TCP/IP stream socket if ((tcp_data->server_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { error_printf("socket() call failed\n"); return -1; } // Construct the server address structure memset(&server_address, 0, sizeof(server_address)); server_address.sin_family = AF_INET; server_address.sin_port = htons(port); server_address.sin_addr.s_addr = inet_addr(address); if (server_address.sin_addr.s_addr == (unsigned long) INADDR_NONE) { // Look up host address host = gethostbyname(address); if (host == (struct hostent *) NULL) { error_printf("Host not found\n"); close(tcp_data->server_socket); return -1; } memcpy(&server_address.sin_addr, host->h_addr, sizeof(server_address.sin_addr)); } // Establish connection to server if (connect(tcp_data->server_socket, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) { error_printf("connect() call failed\n"); close(tcp_data->server_socket); return -1; } return 0; } int tcp_disconnect(void *data) { tcp_data_t *tcp_data = (tcp_data_t *) data; close(tcp_data->server_socket); return 0; } int tcp_send(void *data, const char *message, int length, int timeout) { int status; struct timeval tv; fd_set wdfs; int n = 0, bytes_sent = 0; tcp_data_t *tcp_data = (tcp_data_t *) data; // Set timeout tv.tv_sec = 0; tv.tv_usec = timeout * 1000; FD_ZERO(&wdfs); FD_SET(tcp_data->server_socket, &wdfs); status = select(tcp_data->server_socket + 1, NULL, &wdfs, NULL, &tv); if (status == -1) return -1; else if (status) { // Send until all data is sent do { n = send(tcp_data->server_socket, message + n, length, 0); length -= n; bytes_sent += n; } while (length > 0); return bytes_sent; } else error_printf("Timeout\n"); return -1; } static int tcp_receive_(void *data, char *message, int length, int timeout, int flags) { int status; struct timeval tv; fd_set rdfs; int n = 0, bytes_received = 0; tcp_data_t *tcp_data = (tcp_data_t *) data; // Set timeout tv.tv_sec = 0; tv.tv_usec = timeout * 1000; FD_ZERO(&rdfs); FD_SET(tcp_data->server_socket, &rdfs); status = select(tcp_data->server_socket + 1, &rdfs, NULL, NULL, &tv); if (status == -1) return -1; else if (status) { // Receive until all data is received do { n = recv(tcp_data->server_socket, message + n, length, flags); if (n < 0) break; length -= n; bytes_received += n; } while (n > 0); return bytes_received; } else error_printf("Timeout\n"); return -1; } int tcp_receive(void *data, char *message, int length, int timeout) { return tcp_receive_(data, message, length, timeout, MSG_DONTWAIT); } int tcp_receive_wait(void *data, char *message, int length, int timeout) { return tcp_receive_(data, message, length, timeout, 0); } liblxi-1.13/src/vxi11.c000066400000000000000000000311021327333434500146300ustar00rootroot00000000000000/* * Copyright (c) 2016-2017, Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "vxi11core.h" #include "vxi11.h" #include "tcp.h" #include "error.h" #define PORT_HTTP 80 #define PORT_RPC 111 #define ID_REQ_HTTP "GET /lxi/identification HTTP/1.0\r\n\r\n"; #define ID_REQ_SCPI "*IDN?\n" #define ID_LENGTH_MAX 65536 #define RECEIVE_END_BIT 0x04 // Receive end indicator #define RECEIVE_TERM_CHAR_BIT 0x02 // Receive termination character // Payload representing GETPORT RPC call static char rpc_GETPORT_msg[] = { 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x86, 0xa0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x07, 0xaf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00 }; int vxi11_connect(void *data, const char *address, int port, const char *name, int timeout) { Create_LinkParms link_params; vxi11_data_t *vxi11_data = (vxi11_data_t *) data; // Set up client vxi11_data->rpc_client = clnt_create(address, DEVICE_CORE, DEVICE_CORE_VERSION, "tcp"); if (vxi11_data->rpc_client == NULL) goto error_client; // Set up link link_params.clientId = (unsigned long) vxi11_data->rpc_client; link_params.lockDevice = 0; // No lock link_params.lock_timeout = 0; if (name == NULL) link_params.device = "inst0"; // Use default device name else link_params.device = (char *) name; // Use provided device name if (create_link_1(&link_params, &vxi11_data->link_resp, vxi11_data->rpc_client) != RPC_SUCCESS) goto error_link; return 0; error_link: clnt_destroy(vxi11_data->rpc_client); error_client: return -1; } int vxi11_disconnect(void *data) { Device_Error device_error; vxi11_data_t *vxi11_data = (vxi11_data_t *) data; destroy_link_1(&vxi11_data->link_resp.lid, &device_error, vxi11_data->rpc_client); clnt_destroy(vxi11_data->rpc_client); return 0; } int vxi11_send(void *data, const char *message, int length, int timeout) { Device_WriteParms write_params; Device_WriteResp write_resp; vxi11_data_t *vxi11_data = (vxi11_data_t *) data; // Configure VXI11 write parameters write_params.lid = vxi11_data->link_resp.lid; write_params.lock_timeout = 0; write_params.io_timeout = timeout; write_params.flags = 0x9; write_params.data.data_len = length; write_params.data.data_val = (char *) message; // Send if (device_write_1(&write_params, &write_resp, vxi11_data->rpc_client) != RPC_SUCCESS) return -1; // Return number of bytes sent return write_resp.size; } int vxi11_receive(void *data, char *message, int length, int timeout) { Device_ReadParms read_params; Device_ReadResp read_resp; int response_length = 0; int offset = 0; vxi11_data_t *vxi11_data = (vxi11_data_t *) data; // Configure VXI11 read parameters read_params.lid = vxi11_data->link_resp.lid; read_params.lock_timeout = 0; read_params.io_timeout = timeout; read_params.flags = 0; read_params.termChar = 0; read_params.requestSize = length; // Receive until done do { // Prepare for (repeated) read operation memset(&read_resp, 0, sizeof(read_resp)); read_resp.data.data_val = message + offset; read_params.requestSize = length - offset; if (device_read_1(&read_params, &read_resp, vxi11_data->rpc_client) != RPC_SUCCESS) return -1; if (read_resp.error != 0) { if (read_resp.error == 15) error_printf("Read error (timeout)\n"); // Most common error explained else error_printf("Read error (response error code %d)\n", (int) read_resp.error); return -1; } if (read_resp.data.data_len > 0) { response_length += read_resp.data.data_len; // Return error if provided receive message buffer is too small if (response_length > length) { error_printf("Read error (receive message buffer too small)\n"); return -1; } offset += read_resp.data.data_len; } else return -1; // Stop if we have reached end of receive operation if ((read_resp.reason & RECEIVE_END_BIT) || (read_resp.reason & RECEIVE_TERM_CHAR_BIT)) break; } while (read_resp.reason == 0); // Return number of bytes received return response_length; } int vxi11_lock(void *data) { return 0; } int vxi11_unlock(void *data) { return 0; } static xmlChar *get_element_value(xmlDocPtr doc, xmlChar *element) { xmlNodePtr node; xmlChar *value = NULL; node = xmlDocGetRootElement(doc); node = node->xmlChildrenNode; while (node != NULL) { if ((!xmlStrcmp(node->name, element))) { value = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); break; } node = node->next; } return value; } static int get_device_id(char *address, char *id, int timeout) { vxi11_data_t data; int length; int device; FILE *fd; device = vxi11_connect(&data, address, 0, NULL, timeout); if (device < 0) goto error_connect; length = vxi11_send(&data, ID_REQ_SCPI, strlen(ID_REQ_SCPI), timeout); if (length < 0) goto error_send; length = vxi11_receive(&data, id, ID_LENGTH_MAX, timeout); if (length < 0) goto error_receive; vxi11_disconnect(&data); // Terminate string id[length] = 0; if (length > 0) { // Strip newline if (id[length-1] == '\n') id[--length] = 0; // Strip carriage return if (id[length-1] == '\r') id[--length] = 0; } else { // Fallback - try retrieve ID via HTTP/XML char *request = ID_REQ_HTTP; char response[4096]; char *response_xml; tcp_data_t tcp_data; xmlDocPtr doc; xmlChar *value; // Mute stderr temporarily fd = freopen("/dev/null", "w", stderr); // Get XML identification file tcp_connect(&tcp_data, address, PORT_HTTP, NULL, timeout); tcp_send(&tcp_data, request, strlen(request), timeout); tcp_receive_wait(&tcp_data, response, 4096, timeout); tcp_disconnect(&tcp_data); // Find start of XML response_xml = strstr(response, "sin_addr.s_addr; recv_addr.sin_port = htons(PORT_RPC); // Broadcast RPC GETPORT message sendto(sockfd, rpc_GETPORT_msg, sizeof(rpc_GETPORT_msg), 0, (struct sockaddr*)&recv_addr, sizeof(recv_addr)); addrlen = sizeof(recv_addr); // Go through received responses do { count = recvfrom(sockfd, buffer, ID_LENGTH_MAX, 0, (struct sockaddr*)&recv_addr, &addrlen); if (count > 0) { // Add device if an LXI ID string is returned char *address = inet_ntoa(recv_addr.sin_addr); if (get_device_id(address, id, timeout) == 0) { // Notify device found via callback if (info->device != NULL) info->device(address, id); } } } while (count > 0); return 0; socket_options_error: // Shutdown socket shutdown(sockfd, SHUT_RDWR); return -1; } int vxi11_discover(lxi_info_t *info, int timeout) { struct sockaddr_in *broadcast_addr; struct ifaddrs *ifap; int status; // Go through available broadcast addresses if (getifaddrs(&ifap) == 0) { struct ifaddrs *ifap_p = ifap; while (ifap_p) { if ((ifap_p->ifa_addr) && (ifap_p->ifa_addr->sa_family == AF_INET)) { broadcast_addr = (struct sockaddr_in *) ifap_p->ifa_broadaddr; // Notify current broadcast address and network interface via callback if (info->broadcast != NULL) info->broadcast(inet_ntoa(broadcast_addr->sin_addr), ifap_p->ifa_name); // Find VXI11 devices via broadcast address status = discover_devices(broadcast_addr, info, timeout); } ifap_p = ifap_p->ifa_next; } freeifaddrs(ifap); } return 0; } liblxi-1.13/src/vxi11core.rpcl000066400000000000000000000117111327333434500162230ustar00rootroot00000000000000/****************************************************************************** * * vxi11core.rpcl * * This file is best viewed with a tabwidth of 4 * ****************************************************************************** * * TODO: * ****************************************************************************** * * Original Author: someone from VXIbus Consortium * Current Author: Benjamin Franksen * Date: 03-06-97 * * RPCL description of the core- and abort-channel of the TCP/IP Instrument * Protocol Specification. * * * Modification Log: * ----------------- * .00 03-06-97 bfr created this file * ****************************************************************************** * * Notes: * * This stuff is literally from * * VXI-11, Ref 1.0 : TCP/IP Instrument Protocol Specification * */ typedef int Device_Link; enum Device_AddrFamily { DEVICE_TCP, DEVICE_UDP }; typedef int Device_Flags; typedef int Device_ErrorCode; struct Device_Error { Device_ErrorCode error; }; struct Create_LinkParms { int clientId; /* implementation specific value */ bool lockDevice; /* attempt to lock the device */ unsigned int lock_timeout; /* time to wait for lock */ string device<>; /* name of device */ }; struct Create_LinkResp { Device_ErrorCode error; Device_Link lid; unsigned short abortPort; /* for the abort RPC */ unsigned int maxRecvSize; /* max # of bytes accepted on write */ }; struct Device_WriteParms { Device_Link lid; /* link id from create_link */ unsigned int io_timeout; /* time to wait for I/O */ unsigned int lock_timeout; /* time to wait for lock */ Device_Flags flags; /* flags with options */ opaque data<>; /* the data length and the data itself */ }; struct Device_WriteResp { Device_ErrorCode error; unsigned int size; /* # of bytes written */ }; struct Device_ReadParms { Device_Link lid; /* link id from create_link */ unsigned int requestSize; /* # of bytes requested */ unsigned int io_timeout; /* time to wait for I/O */ unsigned int lock_timeout; /* time to wait for lock */ Device_Flags flags; /* flags with options */ char termChar; /* valid if flags & termchrset */ }; struct Device_ReadResp { Device_ErrorCode error; int reason; /* why read completed */ opaque data<>; /* the data length and the data itself */ }; struct Device_ReadStbResp { Device_ErrorCode error; unsigned char stb; /* the returned status byte */ }; struct Device_GenericParms { Device_Link lid; /* link id from create_link */ Device_Flags flags; /* flags with options */ unsigned int lock_timeout; /* time to wait for lock */ unsigned int io_timeout; /* time to wait for I/O */ }; struct Device_RemoteFunc { unsigned int hostAddr; /* host servicing interrupt */ unsigned int hostPort; /* valid port # on client */ unsigned int progNum; /* DEVICE_INTR */ unsigned int progVers; /* DEVICE_INTR_VERSION */ Device_AddrFamily progFamily; /* DEVICE_UDP | DEVICE_TCP */ }; struct Device_EnableSrqParms { Device_Link lid; /* link id from create_link */ bool enable; /* enable or disable intr's */ opaque handle<40>; /* host specific data */ }; struct Device_LockParms { Device_Link lid; /* link id from create_link */ Device_Flags flags; /* contains the waitlock flag */ unsigned int lock_timeout; /* time to wait for lock */ }; struct Device_DocmdParms { Device_Link lid; /* link id from create_link */ Device_Flags flags; /* flags with options */ unsigned int io_timeout; /* time to wait for I/O */ unsigned int lock_timeout; /* time to wait for lock */ int cmd; /* which command to execute */ bool network_order; /* client's byte order */ int datasize; /* size of individual data elements */ opaque data_in<>; /* docmd data parameters */ }; struct Device_DocmdResp { Device_ErrorCode error; opaque data_out<>; /* returned data parameters */ }; program DEVICE_ASYNC { version DEVICE_ASYNC_VERSION { Device_Error device_abort (Device_Link) = 1; } = 1; } = 0x0607B0; program DEVICE_CORE { version DEVICE_CORE_VERSION { Create_LinkResp create_link (Create_LinkParms) = 10; Device_WriteResp device_write (Device_WriteParms) = 11; Device_ReadResp device_read (Device_ReadParms) = 12; Device_ReadStbResp device_readstb (Device_GenericParms) = 13; Device_Error device_trigger (Device_GenericParms) = 14; Device_Error device_clear (Device_GenericParms) = 15; Device_Error device_remote (Device_GenericParms) = 16; Device_Error device_local (Device_GenericParms) = 17; Device_Error device_lock (Device_LockParms) = 18; Device_Error device_unlock (Device_Link) = 19; Device_Error device_enable_srq (Device_EnableSrqParms) = 20; Device_DocmdResp device_docmd (Device_DocmdParms) = 22; Device_Error destroy_link (Device_Link) = 23; Device_Error create_intr_chan (Device_RemoteFunc) = 25; Device_Error destroy_intr_chan (void) = 26; } = 1; } = 0x0607AF; liblxi-1.13/test/000077500000000000000000000000001327333434500137075ustar00rootroot00000000000000liblxi-1.13/test/scpi.c000066400000000000000000000011371327333434500150130ustar00rootroot00000000000000#include #include #include // Example - send SCPI to instrument using VXI-11 protocol int main() { char response[65536]; int device, timeout = 3000; char *command = "*IDN?"; // Initialize LXI library lxi_init(); // Connect LXI device device = lxi_connect("10.42.0.42", 0, NULL, timeout, VXI11); // Send SCPI command lxi_send(device, command, strlen(command), timeout); // Wait for response lxi_receive(device, response, sizeof(response), timeout); printf("%s\n", response); // Disconnect lxi_disconnect(device); } liblxi-1.13/test/search.c000066400000000000000000000012631327333434500153220ustar00rootroot00000000000000#include #include // Example - Search for LXI instruments using VXI-11 discovery void broadcast(const char *address, const char *interface) { printf("Broadcasting on interface %s\n", interface); } void device(const char *address, const char *id) { printf(" Found %s on address %s\n", id, address); } int main() { lxi_info_t info; // Initialize LXI library lxi_init(); // Set up search information callbacks info.broadcast = &broadcast; info.device = &device; printf("Searching for LXI devices - please wait...\n\n"); // Search for LXI devices, 1 second timeout lxi_discover(&info, 1000, DISCOVER_VXI11); return 0; }