On 14/04/2015 18:35, SM0THU wrote: > Hi Bill, Hi Anders, > > That sounds great. > > One of the reasons for creating my application was to learn Apples new Swift > language and Xcode, so that is what I’m using. OK, I quite like Objective C and Swift is interesting but beware disappearing down the Apple proprietary language Rabbit hole ;) > I’ll have to look into QDataStream and see how I can do that with Swift. Here is the key information: http://doc.qt.io/qt-5/datastreamformat.html
That page lists how the various supported data types are serialized. All the numbers are Big Endian i.e. normal network byte ordering. There will be a header and the message formats are implicit i.e. no type ids or framing, just read the expected fields in the expected order. Simple and compact. Strings will all be encoded as utf-8 and serialized as QByteArray types i.e. 32-bit count followed by the string content converted to utf-8. There will be a C++ header file that documents the message format, headers, various message types and, content. Here is a provisional snapshot of that: #include <QDataStream> #include "pimpl_h.hpp" class QIODevice; class QByteArray; class QString; /* * WSJT-X Message Formats * ====================== * * All messages are written or read using the QDataStream derivatives * defined below. * * Type utf8 is a utf-8 byte string formatted as a QByteArray for * serialization purposes (currently a quint32 size followed by size * bytes, no terminator is present or counted). * * Schema Version 1: * ----------------- * * Message Direction Value Type * ------------- --------- ---------------------- ----------- * Heartbeat Out 0 quint32 * Id (unique key) utf8 * * Status Out 1 quint32 * Id (unique key) utf8 * Dial Frequency (Hz) quint64 * Mode utf8 * DX call utf8 * Report utf8 * Tx Mode utf8 * * Decode Out 2 quint32 * Id (unique key) utf8 * Time QTime * snr qint32 * Delta time (S) float * Delta frequency (Hz) quint32 * Mode utf8 * Message utf8 * * Clear Out 3 quint32 * Id (unique key) utf8 * * Reply In 4 quint32 * Id (target unique key) utf8 * Time QTime * snr qint32 * Delta time (S) float * Delta frequency (Hz) quint32 * Mode utf8 * Message utf8 * * QSO Logged Out 5 quint32 * Id (unique key) utf8 * Date & Time QDateTime * DX call utf8 * DX grid utf8 * Dial frequency (Hz) quint64 * Mode utf8 * Report send utf8 * Report received utf8 * Tx power utf8 * Comments utf8 * Name utf8 * * Close Out 6 quint32 * Id (unique key) utf8 */ namespace NetworkMessage { // NEVER DELETE MESSAGE TYPES enum Type { Heartbeat, Status, Decode, Clear, Reply, QSOLogged, Close, maximum_message_type_ // add new message types before here }; quint32 constexpr pulse {15}; // seconds // // NetworkMessage::Build - build a message containing serialized Qt types // // Message is big endian format // // Header format: // // 32-bit unsigned integer magic number 0xadbccbda // 32-bit unsigned integer schema number // // Payload format: // // As per the QDataStream format, see below for version used and // here: // // http://doc.qt.io/qt-5/datastreamformat.html // // for the serialization details for each type. // class Builder : public QDataStream { public: static quint32 constexpr magic {0xadbccbda}; // never change this // increment this if a newer Qt schema is required and add decode // logic to InputMessageStream below static quint32 constexpr schema_number {1}; explicit Builder (QIODevice *, Type, QString const& id); explicit Builder (QByteArray *, Type, QString const& id); Builder (Builder const&) = delete; Builder& operator = (Builder const&) = delete; private: void common_initialization (Type type, QString const& id); }; // // NetworkMessage::Reader - read a message containing serialized Qt types // // Message is as per NetworkMessage::Builder above, the schema() // member may be used to determine the schema of the original // message. // class Reader : public QDataStream { public: explicit Reader (QIODevice *); explicit Reader (QByteArray const&); Reader (Reader const&) = delete; Reader& operator = (Reader const&) = delete; ~Reader (); quint32 schema () const; Type type () const; QString id () const; private: class impl; pimpl<impl> m_; }; } So a message will be like: Magic number id: 0xabbccbda Schema number: 0x00000001 followed by the serialized payload. So for example a two field payload of a single string of length 10 that maps to a 10 byte utf-8 sequence and a 32 bit number would form a message of length 26 bytes: the eight byte header above a string count of 10 serialized as a 32 bit unsigned BE number (4 bytes) the 10 utf-8 bytes 4 bytes of the number in BE format. The real messages have a payload header as well which is an unsigned 32-bit number for the message type followed by a utf-8 string that identifies the "arena" of the message. This last field the the same unique string that identifies the instance of WSJT-X i.e. "WSJT-X" for the default instance or "WSJT-X - rigname" for a WSJT-X instance started as: wsjtx --rig-name=rigname The message server (your application) cannot broadcast messages but it can reply to a client (a WSJT-X instance) that it has received messages from beforehand. This is sort of similar to a web server that serves many clients except that the bulk of the data flows from client to server and the protocol is UDP. > > 73 > /Anders 73 Bill G4WJS. > >> On 14 Apr 2015, at 19:23, Bill Somerville <g4...@classdesign.com> wrote: >> >> On 14/04/2015 17:57, Anders Östlund wrote: >>> Hi, >> Hi Anders, >>> I'm writing a program that is kind of a JT-Alert alternative, but for Mac >>> OS X. >>> Being able to trigger a reply to a CQ from externally would be a great >>> feature. >>> >>> I've got Mike's patch to work on r5068. Before trying to get it to work on a >>> more recent commit, I just want to ask if there has been more work done on >>> this already. >> Yes, I am close to committing a full functioning version with a formal >> message protocol that is extensible. I am adding some other messages >> (outgoing from WSJT-X) that should be useful to applications like >> JTAlert and yours such as status updates, WSJT-X closedown and >> notification of QSOs logged. >> >> The protocol is binary and pretty simple, based on the Qt QDataStream >> serialization capability. I am testing my changes right now after a >> final clean up before check in, currently it is broken but I should have >> it all working again shortly. >>> I'd be happy to help out with testing or coding, if needed. >> OK. What is your choice of implementation language and tools for your >> application? I would like to have some reference code for various >> platforms for usage of the message protocol. C++ with Qt I have in hand >> already. >>> 73 >>> /Anders - SM0THU >>> http://jt-bridge.eller.nu >> 73 >> Bill >> G4WJS. >>> Bill Somerville <g4wjs@...> writes: >>> >>>> Hi Mike, >>>> >>>> some more comments: >>>> >>>> I think it would be sensible to include the instance name in the >>>> broadcast datagram as a third field. You can use the method >>>> QApplication::applicationName() result as the instance name. >>>> >>>> There is no need to call member functions with an explicit this pointer, >>>> that is not idiomatic C++, so: >>>> >>>> this->member(); >>>> >>>> becomes: >>>> >>>> member(); >>>> >>>> In MainWindow::doCallCQ() there is no need to write to the RHS decoded >>>> text window, MainWindow::doubleClickOnCall() does that for you. >>> [...] >>> >> >> ------------------------------------------------------------------------------ >> BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT >> Develop your own process in accordance with the BPMN 2 standard >> Learn Process modeling best practices with Bonita BPM through live exercises >> http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual- event?utm_ >> source=Sourceforge_BPM_Camp_5_6_15&utm_medium=email&utm_campaign=VA_SF >> _______________________________________________ >> wsjt-devel mailing list >> wsjt-devel@lists.sourceforge.net >> https://lists.sourceforge.net/lists/listinfo/wsjt-devel > > ------------------------------------------------------------------------------ > BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT > Develop your own process in accordance with the BPMN 2 standard > Learn Process modeling best practices with Bonita BPM through live exercises > http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual- event?utm_ > source=Sourceforge_BPM_Camp_5_6_15&utm_medium=email&utm_campaign=VA_SF > _______________________________________________ > wsjt-devel mailing list > wsjt-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/wsjt-devel ------------------------------------------------------------------------------ BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT Develop your own process in accordance with the BPMN 2 standard Learn Process modeling best practices with Bonita BPM through live exercises http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual- event?utm_ source=Sourceforge_BPM_Camp_5_6_15&utm_medium=email&utm_campaign=VA_SF _______________________________________________ wsjt-devel mailing list wsjt-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/wsjt-devel