/// <summary>
        /// Deserializes a byte stream into a <see cref="WearableDeviceConfig"/>. Allocates the return object if one
        /// is not provided.
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="index"></param>
        /// <param name="config">The config to fill into, or null to allocate a new one.</param>
        /// <returns></returns>
        protected static WearableDeviceConfig DeserializeDeviceConfig(byte[] buffer, ref int index, WearableDeviceConfig config = null)
        {
            if (config == null)
            {
                config = new WearableDeviceConfig();
            }

            // Decode header
            DeviceConfigPacketHeader header = DeserializeGenericPacket <DeviceConfigPacketHeader>(buffer, ref index);

            config.updateInterval = header.updateInterval;

            // Decode sensor configs
            for (int i = 0; i < header.sensorCount; i++)
            {
                SensorConfigPacket sensorConfig = DeserializeGenericPacket <SensorConfigPacket>(buffer, ref index);
                config.GetSensorConfig(sensorConfig.sensorId).isEnabled = sensorConfig.enabled != 0;
            }

            // Decode gesture configs
            for (int i = 0; i < header.gestureCount; i++)
            {
                GestureConfigPacket gestureConfig = DeserializeGenericPacket <GestureConfigPacket>(buffer, ref index);
                config.GetGestureConfig(gestureConfig.gestureId).isEnabled = gestureConfig.enabled != 0;
            }

            return(config);
        }
        /// <summary>
        /// Serialize a <see cref="WearableDeviceConfig"/> into a byte buffer.
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="index"></param>
        /// <param name="config"></param>
        protected static void SerializeDeviceConfig(byte[] buffer, ref int index, WearableDeviceConfig config)
        {
            // Encode sub-header
            SerializeGenericPacket(buffer, ref index, new DeviceConfigPacketHeader
            {
                sensorCount    = WearableConstants.SensorIds.Length,
                gestureCount   = WearableConstants.GestureIds.Length - 1,                // Subtract 1 for "None"
                updateInterval = config.updateInterval
            });

            // Encode payload
            for (int i = 0; i < WearableConstants.SensorIds.Length; i++)
            {
                SensorId sensorId = WearableConstants.SensorIds[i];

                var sensorConfigPacket = new SensorConfigPacket
                {
                    sensorId = sensorId,
                    enabled  = (byte)(config.GetSensorConfig(sensorId).isEnabled ? 1 : 0)
                };

                SerializeGenericPacket(buffer, ref index, sensorConfigPacket);
            }

            for (int i = 0; i < WearableConstants.GestureIds.Length; i++)
            {
                GestureId gestureId = WearableConstants.GestureIds[i];

                if (gestureId == GestureId.None)
                {
                    continue;
                }

                var gestureConfigPacket = new GestureConfigPacket
                {
                    gestureId = gestureId,
                    enabled   = (byte)(config.GetGestureConfig(gestureId).isEnabled ? 1 : 0)
                };

                SerializeGenericPacket(buffer, ref index, gestureConfigPacket);
            }
        }