How to make a service or control point using libupnp SDK?!
I didn't understand the documentation attached with this SDK, I don't know from where to start ?!
Can you help me in that and refer me to some helping tutorials ?!
Thanks!
Yes I know, this is a very old question but still had no answer. I came here from google because I also was looking for an entry to use the libupnp SDK aka Portable SDK for UPnP* Devices, but without success. So I will share how I got it with some effort to find things.
I'm using Debian Stretch. So first I installed:
~$ sudo apt install libupnp6 libupnp6-dev libupnp6-doc
Then have a look at the documentation (of course ;) in /usr/share/doc/libupnp6-doc/html/modules.html. One of the problems was that I wasn't able to find this document online. With the UPnP API I started with this simple program, that searches for upnp devices on the local network. Just set INTERFACE[] and SEARCH_DURATION_SECONDS for what you need.
#include <string>
#include <iostream>
#include <thread>
#include <chrono>
#include <upnp/upnp.h>
constexpr char INTERFACE[] = "eth0";
constexpr int SEARCH_DURATION_SECONDS = 5;
int callback_event_handler(Upnp_EventType event_type, void* event, void* cookie)
{
std::string str;
switch (event_type) {
case UPNP_DISCOVERY_SEARCH_RESULT:
str = "UPNP_DISCOVERY_SEARCH_RESULT";
break;
case UPNP_DISCOVERY_SEARCH_TIMEOUT:
str = "UPNP_DISCOVERY_SEARCH_TIMEOUT";
break;
default:
std::cout << "Called callback_event_handler with ignored event" << std::endl;
return 0;
}
std::cout << "Executing callback_event_handler with event type " << str << std::endl;
std::cout << (char*)cookie << std::endl;
return 0;
}
int main()
{
constexpr char cookie[] = "Free custom data, usable in the callback function.";
UpnpClient_Handle client_handle = -1;
UpnpInit2(INTERFACE, 0);
UpnpRegisterClient(callback_event_handler, &cookie, &client_handle);
UpnpSearchAsync(client_handle, SEARCH_DURATION_SECONDS, "upnp:rootdevice", cookie);
std::this_thread::sleep_for(std::chrono::seconds(SEARCH_DURATION_SECONDS + 1));
UpnpFinish();
}
The search target (ST) upnp:rootdevice at UpnpSearchAsync(..) determins what to search. For other search targets look at UPnP Device Architecture 1.0, chapter 1.2.2 Discovery: Search: Request with M-SEARCH.
I compiled the program with:
~$ g++ -std=c++11 -pedantic-errors -Wall -lpthread -lupnp upnpsearch.cpp -o upnpsearch
If you execute it and you have UPnP devices on your local network you should get an output something like this:
Executing callback_event_handler with event type UPNP_DISCOVERY_SEARCH_RESULT
Free custom data, usable in the callback function.
Called callback_event_handler with ignored event
Called callback_event_handler with ignored event
Executing callback_event_handler with event type UPNP_DISCOVERY_SEARCH_RESULT
Free custom data, usable in the callback function.
Executing callback_event_handler with event type UPNP_DISCOVERY_SEARCH_TIMEOUT
Free custom data, usable in the callback function.
Here you see that two UPnP devices are online.
Related
I'm trying to analyze functions by using clang libtooling.
Here is the source code that I want to analyze:
#include <stdio.h>
int main(){
int a = 100;
printf("a==%d", a);
}
when I run my tool to get all the function decl in above files, I found there are a lot of build-in / system functions, like:
decls:
_IO_cookie_init
__underflow
__uflow
__overflow
_IO_getc
_IO_putc
_IO_feof
_IO_ferror
_IO_peekc_locked
_IO_flockfile
_IO_funlockfile
_IO_ftrylockfile
_IO_vfscanf
_IO_vfprintf
_IO_padn
_IO_sgetn
_IO_seekoff
_IO_seekpos
_IO_free_backup_area
remove
rename
renameat
tmpfile
tmpfile64
tmpnam
tmpnam_r
tempnam
fclose
fflush
fflush_unlocked
fcloseall
fopen
(I think they are introduced by the header file "stdio.h" )
my question is:
How can I get rid of all these built-in/system functions from the "stdio.h" file, or other (system) header files?
Thanks in advance!!!
When you visit a function, check if its location (startLoc or endLoc) is in system header using SourceManagers api 'isInSystemHeader(loc)'
e.g.:
Bool VisitFunctionDecl(FunctionDecl * D)
{
If(sourceManager.isInSystemHeader(D->getLocStart()))
return true;
}
Thanks,
Hemant
I am working on MT4 and used wrapper mql4zmq.dll as given in link
https://github.com/AustenConrad/mql4zmq
As I have followed all instruction and successfully loaded DLL as well as lib file at specific locations from pre-compiled. But it can not bind or connect with socket through zmq_connect(,) or zmq_bind(,). Please some one help me to solve this problem. I am posting my code here
// Include the libzmq.dll abstraction wrapper.
#include <mql4zmq.mqh>
//+------------------------------------------------------------------+
//| variable definitions |
//+------------------------------------------------------------------+
int speaker,listener,contextt;
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
int major[1];int minor[1];int patch[1];
zmq_version(major,minor,patch);
Print("Using zeromq version " + major[0] + "." + minor[0] + "." + patch[0]);
Print(ping("Hello World"));
Print("NOTE: to use the precompiled libraries you will need to have the Microsoft Visual C++ 2010 Redistributable Package installed. To Download: http://www.microsoft.com/download/en/details.aspx?id=5555");
contextt = zmq_init(1);
speaker = zmq_socket(contextt, ZMQ_PUB);
listener = zmq_socket(contextt, ZMQ_SUB);
// Subscribe to the command channel (i.e. "cmd").
// NOTE: to subscribe to multiple channels call zmq_setsockopt multiple times.
zmq_setsockopt(listener, ZMQ_SUBSCRIBE, "");
if (zmq_bind(speaker,"tcp://127.0.0.1:5555") == -1)
{
Print("Error binding the speaker!");
return(-1);
}
There is problem in
if ( zmq_bind( speaker, "tcp://127.0.0.1:5555" ) == -1 )
It returns -1 and does not bind.
I have tried every possible thing to solve this mystery but failed.
Please let me know if I am mistaken!!!
Yes, address/port-in use may block .bind() / .connect()
As solved in the comments above, there is
another post with a similar solution of the same root-cause why the well-formed ZeroMQ-code was still not able to .bind()
Address/port release/re-use is O/S-dependent resource-management issue. Be carefull once developing for a production-grade operations.
I have a callback implementation in which an unknown third party calls a function pointer in my code.
However, an issue in a lot languages is triggering code after a function returns. For instance, when a callback is called and I have to delete the calling object (and, in this case, re-initialize it), returning from the callback would cause an exception.
Assuming I cannot hook and that I do not own/cannot modify the code calling the callback, what is the best way to execute code after a function returns?
The only real way I can think of doing this is to set up some sort of state machine and have a worker thread check the state. However, the issue I foresee with this is that of a race condition, where a callback is called between the time the reset callback returns and the point the calling object is reset.
Is there any sort of functionality I'm not aware of, or would this be the most efficient way of achieving such a result?
It requires c++11 or newer though. But this is how i would do it.
You can rewrite it to use function pointers instead so that it works on older c++ versions
#include <functional>
#include <iostream>
#define CONCACT_IMPL(x , y) x##y
#define CONCAT(x, y) CONCACT_IMPL(x, y)
#define deffered(x) auto CONCAT(__deffered, __COUNTER__) = Defer(x);
struct Defer {
Defer(std::function<void(void)> pFunc) : func(pFunc) {};
std::function<void(void)> func;
virtual ~Defer(){
func();
}
};
int main() {
deffered([] () {
std::cout << "deffered" << std::endl;
});
std::cout << "now" << std::endl;
}
outputs -->
now
deffered
I'm trying to go through the tutorial with luabind here, http://www.rasterbar.com/products/luabind/docs.html, however i'm having trouble loading the library. I'm currently using version 5.1 of lua, so I believe I would use package.loadlib instead of loadlib. I made a simple dll which is this:
#include <iostream>
#include <luabind\luabind.hpp>
void greet()
{
std::cout << "Hello world!\n";
}
extern "C" int init(lua_State* L)
{
luabind::open(L);
luabind::module(L)
[
luabind::def("greet", &greet)
];
return 0;
}
This builds just fine. However I get an error in lua when I try to run this code:
package.loadlib("LuaTestLib.dll", "init")
greet()
It states that greet is nil. How do I load the functions from the dll properly?
From the first two sentences of package.loadlib's documentation:
Dynamically links the host program with the C library libname. Inside this library, looks for a function funcname and returns this function as a C function.
(emphasis added)
This doesn't execute funcname. It simply returns it as a function for you to call. You still have to call it:
package.loadlib("LuaTestLib.dll", "init")()
In the tutorial provided at:
http://www.erlang.org/doc/tutorial/cnode.html
There is the following example:
/* cnode_s.c */
#include
#include
#include
#include
#include "erl_interface.h"
#include "ei.h"
#define BUFSIZE 1000
int main(int argc, char **argv) {
int port; /* Listen port number */
int listen; /* Listen socket */
int fd; /* fd to Erlang node */
ErlConnect conn; /* Connection data */
int loop = 1; /* Loop flag */
int got; /* Result of receive */
unsigned char buf[BUFSIZE]; /* Buffer for incoming message */
ErlMessage emsg; /* Incoming message */
ETERM *fromp, *tuplep, *fnp, *argp, *resp;
int res;
port = atoi(argv[1]);
erl_init(NULL, 0);
if (erl_connect_init(1, "secretcookie", 0) == -1)
erl_err_quit("erl_connect_init");
/* Make a listen socket */
if ((listen = my_listen(port))
I suspect that erl_receive_msg is a blocking call, and I don't know how to overcome this. In C network programming there is the "select" statement but in the Erlang EI API I don't know whether there is such a statement.
Basically I want to build a C node, that continuously sends messages to Erlang nodes. For simplicity suppose there is only one Erlang node.
The Erlang node has to process the messages it receives from the C node. The Erlang node is not supposed to ensure that it has received the message, not does it have to reply with the result of processing. Therefore once the message is sent I don't care about it faith.
One might think that one could modify the code as:
...
if (emsg.type == ERL_REG_SEND) {
...
while(1) {
//generate tuple
erl_send(fd, fromp, tuple);
//free alloc resources
}
...
}
This will produce an infinite loop in which we produce and consume (send) messages.
But there is an important problem: if I do this, then the C node might send too many messages to the Erlang node (so there should be a way to send a message from the Erlang node to the C node to slow down), or the Erlang node might think that the C node is down.
I know that the questions must be short an suite (this is long and ugly), but summing up:
What mechanism (procedure call, algorithm) one might use to develop an eager producer in C for a lazy consumer in Erlang, such that both parties are aware of the underlying context ?
I use Port Drivers myself for the case you are describing (haven't touched the C nodes because I'd rather have more decoupling).
Have a look at the Port Driver library for Erlang: EPAPI. There is a project that leverages this library: Erland DBus.
Did you check the ei_receive_msg_tmo function? I suppose it works similar to the receive after construct of Erlang, so if you set timeout to 0, it will be non-blocking.
I believe erl_interface is deprecated, and ei should be used instead. This might be a complete misinformation though...
you need to take a closer look at the tutorial link that you posted. (search for "And finally we have the code for the C node client.") You will see that the author provided a client cnode implementation. It looks rational.