>> how does "properly formed message interceptor message" looks like..
this may not be so easy at present. the logic is entirely in DCE/Message.cpp. It uses our own SerializeClass/SerializeClass.cpp library. it was written for peak efficiency with C++ applications, so DCE router can process as many messages as possible, and it can run on low-power devices like PDAs. SerializeClass works across all operating systems (Linux/Windows/Symbian/Smartphone/etc)., that may not be friendly across languages like Perl. An integer is just past out as the 4 bytes. ie, like int myInt=28818128; Send((void *)&myInt,4);. in C++ this works and is very efficient, and since a single common class is used throughout the entire program there is no risk of errors.
if Perl uses a completely different way of representing integers internally, you probably will not be able to do it the same way. of course we could change Message to use a more portable format--since that one class is the only one used, it wouldn't be difficult. However if we use a different format, say XML, ie Send("<device id from>28818128</device id from>"); that would make it easier for you Perl guys, however I suspect it would drastically reduce DCERouter's efficiency and the speed at which it can parse and process messages. this is important since there is a huge volume of messages. For example if you set your media player to report Time code every second, that message gets broadcast every second, media plug-in needs to see what orbiter's and VFD displays are currently controlling that media and bound to remote controls, and send them all messages to update the time code. Picture a big home with media playing in 10 rooms, five people on the phone, etc., you can see why DCE router needs to be very efficient and parsing XML would slow it down.
On to DCE Messages the way they work now... First, the basic wrappers are in plain text so it is easy to follow in the logs. There are a few special text messages, such as RELOAD, etc., but the only one that really matters for sending messages is MESSAGE. Basically you just send MESSAGE xxx
Where xxx is the size in bytes of the binary data that will follow. The binary data contains the actual message. All messages contain a from device and a to device, type and an ID. The most common type is 1, which means command. In that case the ID is the command's number. The second most common type is 2, which is the event, and the ID the events number. Each message also has an optional number of parameters.
What the commands and events are is defined in the database--DCERouter doesn't care. It just sends a message to the destination. In your Pluto admin web site, if you click advanced, DCE, you can see a list of all the commands and events and the parameters they take. Our utility DCEGen uses this database to build a pregenerated C++ program that encapsulates everything. So for example the command “MH Move Media” is ID 241. It expects 2 parameters: “PK_EntertainArea” is parameter ID 45, and “StreamID” is parameter ID 41.
Media_Plugin is a DCEDevice that implements that command. So DCEGen builds a base class for media plug-in that listens for incoming messages on a socket, automatically parses them and deserializes them, and then passes them to a switch block which will include a case 241, that will then extract the parameters, and call a virtual function called: “MH_Move_Media(string sPK_EntertainArea,int iStreamID)”.
So for C++ it's really simple, the programmer has nothing to do. It he wants to send the command he just types in DCE:: and then auto complete gives them a list of all the commands, and when he chooses the move media command, auto complete gives all the parameters, and when he calls SendCommand(), the command goes through and in media plug-in the MH_Move_Media() function gets called automatically.
We don't have a formal document showing the binary structure of the message, but if you look at the source in Message.cpp, you can see it's just a bunch of serialized values.
Here is a sample binary file containing the move media command going from device 123 to device for 83, with the stream ID of 382 and an entertainment area of “abc”.
http://plutohome.com/download/mh_move_mediaIf you do: DCE::MH_MoveMedia(...), and then call SendCommand(); the resulting binary data is what's in that file. If you cat that to a socket the message goes through.
I am assuming we only need to implement the same message serialization in Perl. Of course the other possibility is to do like we did in Ruby. there is a C++ to Ruby Gateway, so Ruby does never parse actual binary data, that's all done in the same C++ code. to the advantage to this technique is that all the logic is in one place, however I'm not certain if the same Perl to C++ interaction is available.