Commit bc8ec3a3d6c2411d1718b5485aa2e4655cbbb04d
add NetworkCommon/NetworkMessage, and start using it for discovery
Added support for 'Library' plugins, and put NetworkCommon after
NetworkClient/NetworkServer in the link order.
| |   |
| 25 | 25 | Boffin |
| 26 | 26 | # WIP: |
| 27 | 27 | NetworkClient |
| NetworkCommon |
| 29 | 28 | NetworkServer |
| 30 | 29 | ) |
| 31 | 30 | |
| … | … | |
| 52 | 52 | ENDIF() |
| 53 | 53 | ENDFOREACH() |
| 54 | 54 | |
| # Library plugins |
| IF(WITH_NetworkClient_PLUGIN OR WITH_NetworkServer_PLUGIN) |
| LIST(APPEND ACTIVE_PLUGINS NetworkCommon) |
| ENDIF() |
|
| # Write the header file defining our plugins |
| 55 | 61 | SET(STATIC_PLUGINS_H "${CMAKE_CURRENT_BINARY_DIR}/StaticPlugins.h") |
| 56 | 62 | FILE(WRITE ${STATIC_PLUGINS_H} "#include <QtPlugin>\n") |
| 57 | 63 | FOREACH(plugin ${ACTIVE_PLUGINS}) |
| |   |
| 1 | 1 | SET( |
| 2 | 2 | CLASSES |
| 3 | 3 | NetworkCommon |
| NetworkMessage |
| 4 | 5 | ) |
| 5 | 6 | |
| 6 | 7 | SET(SOURCES) |
| |   |
| #include "NetworkMessage.h" |
|
| NetworkMessage::NetworkMessage(const QByteArray& command, const QByteArray& payload, MessageType messageType) |
| { |
| m_command = command; |
| m_payload = payload; |
| m_messageType = messageType; |
| } |
|
| void NetworkMessage::updateSerialization() const |
| { |
| // netstrings-influenced |
| // CommandLength,Command,PayloadLength,Payload,{U|S,timestamp-length,timestamp,message-uuid,signature}; |
| // |
| // Examples: |
| // 3,foo,0,,U; |
| // 3,bar,3,baz,S,10,1266356591,{fc8d8c6c-2ede-4bb8-8685-2cc47cdd8b2b},0000000000000000000000000000000000000000 |
| // |
| // Where: |
| // - timestamp is the number of seconds since 1970-01-01T00:00:00 UTC |
| // - message-uuid is a per-message UUID to prevent replays |
| // - signature is an HMAC-SHA1 of everything up to and including the previous comma |
| QByteArray& out = m_serialized; |
| m_serialized.clear(); |
| Q_ASSERT(m_messageType == UnsignedMessage); |
|
| out.append(QString::number(m_command.length()).toLatin1()); |
| out.append(','); |
| out.append(m_command); |
| out.append(','); |
| out.append(QString::number(m_payload.length()).toLatin1()); |
| out.append(','); |
| out.append(m_payload); |
| out.append(",U;"); |
| } |
|
| QByteArray NetworkMessage::toByteArray() const |
| { |
| if(m_serialized.isNull()) |
| { |
| updateSerialization(); |
| } |
| return m_serialized; |
| } |
| |   |
| #pragma once |
|
| #include <QByteArray> |
| #include <QIODevice> |
|
| class NetworkMessage |
| { |
| public: |
| enum MessageType |
| { |
| UnsignedMessage, |
| SignedMessage |
| }; |
| NetworkMessage(const QByteArray& command, const QByteArray& payload, MessageType messageType); |
| QByteArray toByteArray() const; |
| private: |
| void updateSerialization() const; // cache |
|
| QByteArray m_command; |
| QByteArray m_payload; |
| MessageType m_messageType; |
|
| mutable QByteArray m_serialized; // used as a cache |
| }; |
| |   |
| 11 | 11 | LIST(APPEND HEADERS ${class}.h) |
| 12 | 12 | ENDFOREACH() |
| 13 | 13 | |
| INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) |
| INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ../NetworkCommon) |
| 15 | 15 | QT4_WRAP_CPP(MOC_SOURCES ${HEADERS}) |
| 16 | 16 | ADD_LIBRARY( |
| 17 | 17 | NetworkServer |
| |   |
| 1 | 1 | #include "NetworkServer_Implementation.h" |
| 2 | 2 | |
| #include "../NetworkCommon/NetworkCommon.h" |
| #include "NetworkCommon.h" |
| #include "NetworkMessage.h" |
| 4 | 5 | |
| 5 | 6 | #include "Uuid.h" |
| 6 | 7 | |
| … | … | |
| 67 | 67 | payload.append(port); |
| 68 | 68 | payload.append(','); |
| 69 | 69 | |
| m_discoveryResponse = createMessage("ANNOUNCE", payload, UnsignedMessage); |
| m_discoveryResponse = NetworkMessage("ANNOUNCE", payload, NetworkMessage::UnsignedMessage).toByteArray(); |
| 71 | 71 | } |
| } |
|
| QByteArray NetworkServer::Implementation::createMessage(const QByteArray& command, const QByteArray& payload, MessageType messageType) const |
| { |
| // netstrings-influenced |
| // CommandLength,Command,PayloadLength,Payload,{U|S,timestamp-length,timestamp,message-uuid,signature}; |
| // |
| // Examples: |
| // 3,foo,0,,U; |
| // 3,bar,3,baz,S,10,1266356591,{fc8d8c6c-2ede-4bb8-8685-2cc47cdd8b2b},0000000000000000000000000000000000000000 |
| // |
| // Where: |
| // - timestamp is the number of seconds since 1970-01-01T00:00:00 UTC |
| // - message-uuid is a per-message UUID to prevent replays |
| // - signature is an HMAC-SHA1 of everything up to and including the previous comma |
| QByteArray out; |
| Q_ASSERT(messageType == UnsignedMessage); |
| Q_UNUSED(messageType); |
|
| out.append(QString::number(command.length()).toLatin1()); |
| out.append(','); |
| out.append(command); |
| out.append(','); |
| out.append(QString::number(payload.length()).toLatin1()); |
| out.append(','); |
| out.append(payload); |
| out.append(",U;"); |
| return out; |
| 100 | 72 | } |
| 101 | 73 | |
| 102 | 74 | void NetworkServer::Implementation::sendDiscoveryResponses() |
| |   |
| 20 | 20 | private slots: |
| 21 | 21 | void sendDiscoveryResponses(); |
| 22 | 22 | private: |
| enum MessageType |
| { |
| UnsignedMessage, |
| SignedMessage |
| }; |
| QByteArray createMessage(const QByteArray& command, const QByteArray& payload, MessageType messageType) const; |
|
| 30 | 23 | Jerboa::CollectionInterface* m_collection; |
| 31 | 24 | Jerboa::PlayerInterface* m_player; |
| 32 | 25 | Jerboa::PlaylistInterface* m_playlist; |