How could I create an AVAHI client & server using C++? - c++

I'm coding a C++ library that, among other things, needs to:
Search for a specific service in a network using AVAHI
Publish itself as a service using AVAHI
I've been searching for existent options. I've found that the creators of POCO C++ offer a DNS-SD library integrated with POCO C++. That would work, because I'm actually using POCO C++, but it's a commercial library, and I can't afford it.
Apart from that, avahi-daemon offers a client interface that allows browsing services and publishing new ones. It also sounds good, but I need my code to be portable, and work in major Linux distributions, Mac OS X and Windows. AFAIK, this solution would only cover Linux (where avahi-daemon is available).
I guess as partial solution, I could just send a properly formatted message via socket and process the raw response. That way, I could search for services published using AVAHI. But I think that's ugly and unmaintainable.
So, is there any good-enough solution for this without buying a software? I know this can be done using Python, but I need to do it in C++.
Many thanks in advance

There is an Open Source library (released under the LGPL) available over at http://avahi.org/. It exposes a C interface that can be very easily used in a c++ program.
There are also prebuilt binary version available for all major distros.

Related

Cross Platform C++ Networking (without big library)

I think it is better if I explain the situation so this doesn't seem too arcane a question. I want to release some starter code for a project I want some of my students to work on. The project involves scraping through some internet webpages and as such, I want to provide them with a URLStream class that will download the html of an input url and return it as a string to them.
The issue is that I can't seem to find a particularly nice way to deal with networking in a way that will be cross platform (the students have mac/windows/linux machines). I know of libraries like Boost asio and libCurl, but the issue with using these is that I can't enforce all my students download them. So my question is twofold:
Is there any nice way to provide them this cross platform networking code?
If a library is the only way to do this, is there any way to attach the library to the starter project so that students don't have to download it? I know this might be a stupid question but I can't seem to find out if this is possible.
Boost.Asio is really not suitable for your needs as it involves huge Boost and building at least some of its non-header-only libs. You can still consider Asio lib that can be used w/o Boost and is header-only lib, so much less hassle for you and your students. As it's probably the most popular and modern networking C++ lib this exercise can provide some useful experience to the students. Asio examples also have a simple HTTP client.
As a side note, are you bound to C++ for this assignment? It would be much simpler in Python or similar languages that provide networking out of the box.
The Berkeley sockets API is the most common low-level socket API. It is supported on all POSIX platforms which means both Linux and macOS will have it.
Even Windows have it, but with a slight twist since sockets aren't descriptors like they are on POSIX systems.
Using sockets directly will lead to more boiler-plate code, but it is definitely possible to use it to make a simple HTTP client that supports only simple GET requests.
There are many tutorials and references on using sockets. Beej's Guide to Network Programming seems to be a popular tutorial, which should have notes about the tweaks needed for Windows.
cross-platform C++ library for network programming
asio is a cross-platform C++ library for network programming that provides
developers with a consistent asynchronous I/O model using a modern C++
approach. It has recently been accepted into Boost.
I copied that from the info window in Synaptic. If you're using Linux, install the library (and its documentation) thus:
sudo apt-get install libasio-dev libasio-doc

Communicate with CoDeSys program on a Linux-based WAGO PFC200 PLC

I'm currently getting familiar with PLC's, the WAGO 750-8206 PLC in particular. It offers a linux OS and can run CoDeSys programs. There are some I/O modules attached to the controller: 750-530, 750-430 and 750-600. What I would like to know is this:
Is it possible to write a C++ linux application that runs on the PLC and gets/sets the digital inputs and outputs?
Even better: can I write a CoDeSys program that "talks to the I/O's" and handles all the logic and at the same time can be accessed by a C++ linux program? THe idea is this: I would like the CoDeSys program to check for let's say two digital inputs. If both are high, a variable should be set to a defined value. The linux application should be able to read that variable and conduct further processing (such as sending JSon data to a server or similar).
Also, I would need to be able to send commands from the linux application to the CoDeSys program in order to switch digital outputs (or set values on analog outputs etc) when the linux application receives a message that triggers the command.
Any thoughts and comments on this topic are greatly appreciated as I am completely new to this topic. Thanks in advance!
The answer you might want
The actual situation has changed into the opposite of the previous answer.
WAGO's recent Board Support Packages and Documentation actively support you in making changes and extensions to the PLC200 line. Specifically the WAGO 750-8206 and 17 (as of March 2016) other PLCs :
wago.us -> Products -> Components for Automation -> Modular WAGO-I/O-SYSTEM, IP 20 (750/753 Series)
What you have to do is get in touch with them and ask for their latest Board Support Package (BSP) for the PLC200 line.
I quote from the previous answer and mark the changes, my additions are in bold.
Synopsis
Could you hack a PFC200 and get custom binaries executed? Probably Absolutely yes. As long as the program is content to run on the Linux-3.6.11 kernel and glibc-2.16 and is compiled for the "armhf" API, any existing ARM application, provided you also copy the libraries it uses as well, will just run without even compiling it specifically for the PFC200.
Would it be easy or quick? No. Yes, if you have no fear of the Linux Command line. It is as easy as using the Cross Compiler provided by the Board Support Package (BSP) with the provided C-libraries and then run this to transfer your program to the PFC's flash and run it: scp your-program root#PFC200:/usr/bin
ssh root#FC200 /usr/bin/your-programOf course, you can use Eclipse CDT with the Cross Toolchain for the PFC200 and configure Eclipse to do do remote run and debug.
Will this change in the future? Maybe. Remember that PFC200 is fairly new in North America.It has, PFC200 has appeared in September 2014
The public HOWTO Building FORTE for Wago describes how to use the initial BSP to run FORTE, which is the IEC 61499 run-time environment of 4DIAC (link: sf.net/projects/fordiac ), an open source PLC environment allowing to implement industrial control solutions in a vendor neutral way. 4DIAC implements IEC 61499 extending IEC 61131-3 with better support for controller to controller communication and dynamic reconfiguration.
In case you want to access the KBUS (which talks to the I/Os) directly, you have to know that currently only one application can be in charge of KBUS.
So either CODESYS, or FORTE, or your own KBUS application can be in charge of the KBUS.
The BSP from 2015 has many examples and demos how to use all the I/O of the PLC200 (KBUS, CAN, MODBUS, PROFIBUS as well as the Switches and LEDs on the PFC200 directly). Sources for the kernel and with all kernel drivers and the other Open Source components is provided and compiled in the Board Support Package (BSP).
But, the sources for the libraries and tools developed from scratch by WAGO and are not based on GPL/Open Source code are not provided: These include the Application Device Interface(ADI)/Device Abstraction Layer(DAL) libraries which do CANopen, PROFIBUS-Slave and KBus (which is used all PLC I/O modules connected to the main PLC unit)
While CANopen is using the standard Linux Socketcan API to talk to the kernel and you could just write a normal socketcan program using the provided libsocketcan, the KBus API is an WAGO-specific invention and there, you'd have to do some reverse-engineering if you'd not want to use WAGO's DAL for accessing all the electrical I/O of the PLC, but the DAL is documented and examples how to use it are provided in the BSP.
If you use CODESYS however, there is an "codesys_lib_demo-0.1" example library which shows how to provide a library for CODESYS to use.
Outdated Answer
This answer was very specific to circumstances in 2014 and 2015. As of 2016, it contains incorrect information. Still going to leave as-is for now to provide background.
The quick answer you probably don't want
You could very reasonably write code using Codesys that put together a JSON packet and sent it off to a server elsewhere. JSON is just text, and Codesys can manipulate text in a fashion very similar to C. And there are many ethernet protocols available from within Codesys using addon libraries provided by Wago.
Now the long Answers
First some background
Since you seem to be new to Wago and the philosophy of Codesys in general... a short history.
Codesys is used to build and deploy Hard Realtime execution environments, and it is important to understand that utilizing libraries without fully understanding the consequences can destabilize performance of the entire system (bringing Codesys to its knees and throwing watchdog errors in the program). Remember, many PLC's are controlling equipment that could kill someone if it ever crashed.
Wago is fond of using Linux to provide the preemptive RT kernel for the low level task scheduling and then configuring Codesys to utilize much of the standard C-libraries that often accompany linux. Wago has been doing this for quite some time, but they would never allow you to peel back the covers without going through Codesys (which means using IEC 61131 languages, of which C++ is not included), and this was for your own safety (and their product image). If you wanted the power of linux on a Wago, you had to get a special PLC with a completely naked OS, practically no manual or support, and forfeit the entire Codesys runtime.
The new PFC200's have much more RAM and memory available than recent models, allowing for more of the standard linux userland stack (ssh, ftp, http,...) to be included without compromising the Codesys runtime, and they advertise this. BUT... they are still keeping a lid on compilation tools and required header files needed to compile and link to Codesys libraries or access specialized hardware (the Wago KBUS, which interfaces your I/O modules).
The Synapsis
Could you hack a PFC200 and get custom binaries executed? Probably yes.
Would it be easy or quick? No.
Will this change in the future? Maybe. Remember that PFC200 is fairly new in North America.
Things you may not know
Codesys does not necessarily know or care about Wago. You can get Target Platforms for Codesys that do target Intel processors running a linux os. Codesys DOES SUPPORT accessing external libraries (communication in the reverse direction is dangerous), but they often expect a C style interface, and you can only access those libraries by defining C-headers that Codesys will analyze, so you may need to do some magic to get C++ working seemlessly. What you can do is create a segment of shared memory that both C++ and Codesys access, and that is how they pass information (synchronization is another problem).
You can get an Open Wago PLC, running Codesys on Linux. Wago's IPC are made specifically for this purpose. They have more power, memory, and communication capabilities in general; but they do cost more than double your typical Wago PLC.
If you feel like toying with the idea of hacking a Wago, you will need to tear apart the manuals for Codesys (it has its own), the manuals for the Wago IPC's, and already be familiar with linux style inter-process-communication and/or dynamic libraries.
Also, there is an older Wago PLC that had the naked Linux on it 750-8??. It also has a very good manual on how to access the Wago hardware using supplied headers.
You must first understand how Codesys expects to talk to its target operating system. Then you work backwards to make it talk to Wago specific libraries living on that operating system. You must be careful not to hijack Codesys.
Your extra C++ libs should assist Codesys, not take it over. For instance, host a sqlite database on the same device, and use C++ to manage the database and provide a very simple interface that Codesys can utilize. All Codesys would do is call a function and pass some values, but your C++ would actually build an SQL query and issue it to the database (Codesys doesn't need to know why or how this is happening).
I hope at least one paragraph is helpful in some way.

WCF-like Native C++ Library

I am looking for a library for native C++ (library source code has to be gcc compatible and portable across Linux and Windows) that does what WCF does in its very basic form - i.e. OperationContracts and DataContracts in a client-server environment, with data exchanges in binary format (binary serialization).
Ideally I'd like to use a library to achieve this. So if there's a library already available that compiles OperationContracts and DataContracts into rich C++ classes with metadata for reflection which can be consumed in our code and with client-server TCP communications built-in (i.e. a rudimentary implementation of WCF's functionality without the need to be compatible with WCF at all), please point me to it.
If not, implementing them myself (unlikely due to time constraints), I could use boost::serialization for DataContracts but how would I implement OperationContracts?
It's not necessarily compatible with gcc--so it's somewhat tangential to the precise question asked here--but I'd like to include a reference to the Windows Web Services API, Microsoft's native-code counterpart to WCF (for Windows systems).
From this secondary article:
WWS is designed from the ground up to be a completely native-code implementation of SOAP, including support for many of the WS-* protocols. WWS is, strictly speaking, exposed through a C API, making interoperability with other languages and runtimes very straightforward, but it is the C++ developer who will likely benefit the most.
I have found one that fits the purpose called "RCF" (Remote Call Framework) by Delta V Software. It's open source (GPLv2 or US$195 closed source). So far in my testing, it's working very well. According to the site, companies like HP, Ericsson and Siemens are users of the library.
Apache Thrift is another option you might consider,
http://en.wikipedia.org/wiki/Apache_Thrift

Whats the most basic way to go online in c++?

What is the most basic way to go to a webpage and download its contents? the webpage i wish to get only has text, most of which is in tables.
is there a std library that does it (like urllib in python)?
There's no official C++ network library, no. There are many different APIs available, though. Which is best for you would depend on what platform(s) you were targeting and what framework(s) you might already be using.
That said, cpp-netlib is a platform-neutral API that follows C++ idioms nicely. I've used it and it works.
A large number of tasks that are not covered by the C++ standard library can be done using boost, the collection of peer-reviewed portable libraries, which are used by pretty much every C++ project today. For networking, we use boost.asio.
Their tutorials include HTTP clients: http://www.boost.org/doc/libs/1_46_1/doc/html/boost_asio/example/http/client/sync_client.cpp and http://www.boost.org/doc/libs/1_46_1/doc/html/boost_asio/example/http/client/async_client.cpp
However, although this is highly portable and may end up becoming part of the C++ standard library in future, it is a bit too low-level for your task. libCURL is the today's default library for HTTP downloads.

Using XmlRpc in C++ and Windows

I need to use XmlRpc in C++ on a Windows platform. Despite the fact that my friends assure me that XmlRpc is a "widely available standard technology", there are not many libraries available for it. In fact I only found one library to do this on Windows, (plus another one that claims "you'll have to do a lot of work to get this to compile on Windows). The library I found was Chris Morley's "XmlRpc++". However, it doesn't have support for SSL.
My question therefore is: what library should I be using?
I've written my own C++ library. It's available at sourceforge:
xmlrpcc4win
The reason I wrote it rather than using Chris Morley's was that:
The Windows "wininet.lib" library gives you all the functionality for handling Http requests, so I'd rather use that. As a result, I only needed 1700 LOC.
"wininet.lib", and therefore my implementation, supports HTTPS
Chris Morley's use of STL containers was quite inefficient (Chris, mail me if you read this).
Until I wrote my own library, (see above) here was my answer:
Currently, the XmlRpc++ library by Chris Morley is the only public domain/LPGL XmlRpc implementation for C++ on Windows.
There are a couple of C++ implementations for Linux, either of which could be presumably easily ported to Windows, but the fact seems to be that no-one has yet done so and made it publicly available. Also, as eczamy says, "The XML-RPC specification is somewhat simple and it would not be difficult to implement your own XML-RPC client."
I'm using Chris Morley's library successfully, despite having had to find and fix quite a number of bugs. The Help Forum for this project seems to be somewhat active, but no-one has fixed these bugs and done a new release. I have been in correspondence with Chris Morley and he has vague hopes to do a new release, and he has contributed to this stackOverflow question (see below/above) and he claims to have fixed most of the bugs, but so far he has not made a release that fixes the many bugs. The last release was in 2003.
It is disappointing to me that a supposed widely supported (and simple!) protocol has such poor support on Windows + C++. Please can someone reading this page pick up the baton and e.g. take over XmlRpc++ or properly port one of the Linux implementations.
There are dozens of implementations of the XML-RPC implementations, some in C++, but most in other languages. For example, besides XmlRpc++ there is also XML-RPC for C and C++. Here is a HOWTO on how the XML-RPC for C and C++ library can be used.
The XML-RPC specification is somewhat simple and it would not be difficult to implement your own XML-RPC client. Not to mention, it would also be possible to take an existing XML-RPC implementation in C and bring into your C++ project.
The XML-RPC home page also provides a lot of useful information.
Just wanted to note a couple of items:
The source in the cvs repository for XmlRpc++ has support for OpenSSL (although I have not tried it, it was contributed by another developer).
Most of the reported bugs are fixed in cvs; I don't have access to a linux machine at the moment, so I haven't made an official release.
XmlRpc++ is not public domain. It is copyrighted and licensed (LGPL).
Thanks,
Chris Morley
I was able to get Tim's version of xml rpc working with https and with basic username / password authentication.
For the authentication:
1) the username and password need to be passed to the InternetConnect(...) function
2) an http request header of "Authorization: Basic base64encoded(user:pass)" needs to be added prior to sending the HttpSendRequest(...) command.