mirror of
https://github.com/Silicondust/libhdhomerun
synced 2025-07-05 12:36:48 -07:00
175 lines
7.9 KiB
C
175 lines
7.9 KiB
C
/*
|
|
* hdhomerun_pkt.h
|
|
*
|
|
* Copyright © 2006-2022 Silicondust USA Inc. <www.silicondust.com>.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*
|
|
* The discover protocol (UDP port 65001) and control protocol (TCP port 65001)
|
|
* both use the same packet based format:
|
|
* uint16_t Packet type
|
|
* uint16_t Payload length (bytes)
|
|
* uint8_t[] Payload data (0-n bytes).
|
|
* uint32_t CRC (Ethernet style 32-bit CRC)
|
|
*
|
|
* All variables are big-endian except for the crc which is little-endian.
|
|
*
|
|
* Valid values for the packet type are listed below as defines prefixed
|
|
* with "HDHOMERUN_TYPE_"
|
|
*
|
|
* Discovery:
|
|
*
|
|
* The payload for a discovery request or reply is a simple sequence of
|
|
* tag-length-value data:
|
|
* uint8_t Tag
|
|
* varlen Length
|
|
* uint8_t[] Value (0-n bytes)
|
|
*
|
|
* The length field can be one or two bytes long.
|
|
* For a length <= 127 bytes the length is expressed as a single byte. The
|
|
* most-significant-bit is clear indicating a single-byte length.
|
|
* For a length >= 128 bytes the length is expressed as a sequence of two bytes as follows:
|
|
* The first byte is contains the least-significant 7-bits of the length. The
|
|
* most-significant bit is then set (add 0x80) to indicate that it is a two byte length.
|
|
* The second byte contains the length shifted down 7 bits.
|
|
*
|
|
* A discovery request packet has a packet type of HDHOMERUN_TYPE_DISCOVER_REQ and should
|
|
* contain two tags: HDHOMERUN_TAG_DEVICE_TYPE and HDHOMERUN_TAG_DEVICE_ID.
|
|
* The HDHOMERUN_TAG_DEVICE_TYPE value should be set to HDHOMERUN_DEVICE_TYPE_TUNER.
|
|
* The HDHOMERUN_TAG_DEVICE_ID value should be set to HDHOMERUN_DEVICE_ID_WILDCARD to match
|
|
* all devices, or to the 32-bit device id number to match a single device.
|
|
*
|
|
* The discovery response packet has a packet type of HDHOMERUN_TYPE_DISCOVER_RPY and has the
|
|
* same format as the discovery request packet with the two tags: HDHOMERUN_TAG_DEVICE_TYPE and
|
|
* HDHOMERUN_TAG_DEVICE_ID. In the future additional tags may also be returned - unknown tags
|
|
* should be skipped and not treated as an error.
|
|
*
|
|
* Control get/set:
|
|
*
|
|
* The payload for a control get/set request is a simple sequence of tag-length-value data
|
|
* following the same format as for discover packets.
|
|
*
|
|
* A get request packet has a packet type of HDHOMERUN_TYPE_GETSET_REQ and should contain
|
|
* the tag: HDHOMERUN_TAG_GETSET_NAME. The HDHOMERUN_TAG_GETSET_NAME value should be a sequence
|
|
* of bytes forming a null-terminated string, including the NULL. The TLV length must include
|
|
* the NULL character so the length field should be set to strlen(str) + 1.
|
|
*
|
|
* A set request packet has a packet type of HDHOMERUN_TYPE_GETSET_REQ (same as a get request)
|
|
* and should contain two tags: HDHOMERUN_TAG_GETSET_NAME and HDHOMERUN_TAG_GETSET_VALUE.
|
|
* The HDHOMERUN_TAG_GETSET_NAME value should be a sequence of bytes forming a null-terminated
|
|
* string, including the NULL.
|
|
* The HDHOMERUN_TAG_GETSET_VALUE value should be a sequence of bytes forming a null-terminated
|
|
* string, including the NULL.
|
|
*
|
|
* The get and set reply packets have the packet type HDHOMERUN_TYPE_GETSET_RPY and have the same
|
|
* format as the set request packet with the two tags: HDHOMERUN_TAG_GETSET_NAME and
|
|
* HDHOMERUN_TAG_GETSET_VALUE. A set request is also implicit get request so the updated value is
|
|
* returned.
|
|
*
|
|
* If the device encounters an error handling the get or set request then the get/set reply packet
|
|
* will contain the tag HDHOMERUN_TAG_ERROR_MESSAGE. The format of the value is a sequence of
|
|
* bytes forming a null-terminated string, including the NULL.
|
|
*
|
|
* In the future additional tags may also be returned - unknown tags should be skipped and not
|
|
* treated as an error.
|
|
*
|
|
* Security note: The application should not rely on the NULL character being present. The
|
|
* application should write a NULL character based on the TLV length to protect the application
|
|
* from a potential attack.
|
|
*
|
|
* Firmware Upgrade:
|
|
*
|
|
* A firmware upgrade packet has a packet type of HDHOMERUN_TYPE_UPGRADE_REQ and has a fixed format:
|
|
* uint32_t Position in bytes from start of file.
|
|
* uint8_t[256] Firmware data (256 bytes)
|
|
*
|
|
* The data must be uploaded in 256 byte chunks and must be uploaded in order.
|
|
* The position number is in bytes so will increment by 256 each time.
|
|
*
|
|
* When all data is uploaded it should be signaled complete by sending another packet of type
|
|
* HDHOMERUN_TYPE_UPGRADE_REQ with payload of a single uint32_t with the value 0xFFFFFFFF.
|
|
*/
|
|
|
|
#define HDHOMERUN_DISCOVER_UDP_PORT 65001
|
|
#define HDHOMERUN_CONTROL_TCP_PORT 65001
|
|
|
|
#define HDHOMERUN_MAX_PACKET_SIZE 1460
|
|
#define HDHOMERUN_MAX_PAYLOAD_SIZE 1452
|
|
|
|
#define HDHOMERUN_TYPE_DISCOVER_REQ 0x0002
|
|
#define HDHOMERUN_TYPE_DISCOVER_RPY 0x0003
|
|
#define HDHOMERUN_TYPE_GETSET_REQ 0x0004
|
|
#define HDHOMERUN_TYPE_GETSET_RPY 0x0005
|
|
#define HDHOMERUN_TYPE_UPGRADE_REQ 0x0006
|
|
#define HDHOMERUN_TYPE_UPGRADE_RPY 0x0007
|
|
|
|
#define HDHOMERUN_TAG_DEVICE_TYPE 0x01
|
|
#define HDHOMERUN_TAG_DEVICE_ID 0x02
|
|
#define HDHOMERUN_TAG_GETSET_NAME 0x03
|
|
#define HDHOMERUN_TAG_GETSET_VALUE 0x04
|
|
#define HDHOMERUN_TAG_GETSET_LOCKKEY 0x15
|
|
#define HDHOMERUN_TAG_ERROR_MESSAGE 0x05
|
|
#define HDHOMERUN_TAG_TUNER_COUNT 0x10
|
|
#define HDHOMERUN_TAG_LINEUP_URL 0x27
|
|
#define HDHOMERUN_TAG_STORAGE_URL 0x28
|
|
#define HDHOMERUN_TAG_DEVICE_AUTH_BIN_DEPRECATED 0x29
|
|
#define HDHOMERUN_TAG_BASE_URL 0x2A
|
|
#define HDHOMERUN_TAG_DEVICE_AUTH_STR 0x2B
|
|
#define HDHOMERUN_TAG_STORAGE_ID 0x2C
|
|
#define HDHOMERUN_TAG_MULTI_TYPE 0x2D
|
|
|
|
#define HDHOMERUN_DEVICE_TYPE_WILDCARD 0xFFFFFFFF
|
|
#define HDHOMERUN_DEVICE_TYPE_TUNER 0x00000001
|
|
#define HDHOMERUN_DEVICE_TYPE_STORAGE 0x00000005
|
|
#define HDHOMERUN_DEVICE_ID_WILDCARD 0xFFFFFFFF
|
|
|
|
#define HDHOMERUN_MIN_PEEK_LENGTH 4
|
|
|
|
struct hdhomerun_pkt_t {
|
|
uint8_t *pos;
|
|
uint8_t *start;
|
|
uint8_t *end;
|
|
uint8_t *limit;
|
|
uint8_t buffer[3074];
|
|
};
|
|
|
|
extern LIBHDHOMERUN_API struct hdhomerun_pkt_t *hdhomerun_pkt_create(void);
|
|
extern LIBHDHOMERUN_API void hdhomerun_pkt_destroy(struct hdhomerun_pkt_t *pkt);
|
|
extern LIBHDHOMERUN_API void hdhomerun_pkt_reset(struct hdhomerun_pkt_t *pkt);
|
|
|
|
extern LIBHDHOMERUN_API uint8_t hdhomerun_pkt_read_u8(struct hdhomerun_pkt_t *pkt);
|
|
extern LIBHDHOMERUN_API uint16_t hdhomerun_pkt_read_u16(struct hdhomerun_pkt_t *pkt);
|
|
extern LIBHDHOMERUN_API uint32_t hdhomerun_pkt_read_u32(struct hdhomerun_pkt_t *pkt);
|
|
extern LIBHDHOMERUN_API size_t hdhomerun_pkt_read_var_length(struct hdhomerun_pkt_t *pkt);
|
|
extern LIBHDHOMERUN_API uint8_t *hdhomerun_pkt_read_tlv(struct hdhomerun_pkt_t *pkt, uint8_t *ptag, size_t *plength);
|
|
extern LIBHDHOMERUN_API void hdhomerun_pkt_read_mem(struct hdhomerun_pkt_t *pkt, void *mem, size_t length);
|
|
|
|
extern LIBHDHOMERUN_API void hdhomerun_pkt_write_u8(struct hdhomerun_pkt_t *pkt, uint8_t v);
|
|
extern LIBHDHOMERUN_API void hdhomerun_pkt_write_u16(struct hdhomerun_pkt_t *pkt, uint16_t v);
|
|
extern LIBHDHOMERUN_API void hdhomerun_pkt_write_u32(struct hdhomerun_pkt_t *pkt, uint32_t v);
|
|
extern LIBHDHOMERUN_API void hdhomerun_pkt_write_var_length(struct hdhomerun_pkt_t *pkt, size_t v);
|
|
extern LIBHDHOMERUN_API void hdhomerun_pkt_write_mem(struct hdhomerun_pkt_t *pkt, const void *mem, size_t length);
|
|
|
|
extern LIBHDHOMERUN_API int hdhomerun_pkt_open_frame(struct hdhomerun_pkt_t *pkt, uint16_t *ptype);
|
|
extern LIBHDHOMERUN_API void hdhomerun_pkt_seal_frame(struct hdhomerun_pkt_t *pkt, uint16_t frame_type);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|