diff --git a/README.md b/README.md index c41a37dd..40705a4a 100644 Binary files a/README.md and b/README.md differ diff --git a/README_CN.md b/README_CN.md index 865d466e..527d9b30 100644 Binary files a/README_CN.md and b/README_CN.md differ diff --git a/docs/MESHCORE_PROTOCOL.md b/docs/MESHCORE_PROTOCOL.md new file mode 100644 index 00000000..3b2122f3 --- /dev/null +++ b/docs/MESHCORE_PROTOCOL.md @@ -0,0 +1,224 @@ +# MeshCore 通信协议介绍 + +## 📋 概述 + +MeshCore是一个轻量级的C++ LoRa Mesh网络协议库,专注于多跳包路由。与Meshtastic相比,MeshCore更注重**简洁性**和**可扩展性**,适合嵌入式项目的定制开发。 + +## 🔧 协议架构 + +### 核心特性 +- **多跳路由**: 支持Flood和Direct两种路由模式 +- **自定义二进制格式**: 不使用Google Protocol Buffers +- **Ed25519加密**: 完整的端到端安全支持 +- **轻量级设计**: 适合资源受限的嵌入式设备 + +### 架构优势 +- **紧凑包结构**: 最小化空中传输时间 +- **灵活路由策略**: 支持多种路由算法 +- **强加密保证**: 完整的节点身份验证 +- **易于扩展**: 支持自定义负载类型 + +## 📦 数据包结构 + +### 包头格式 (1字节) + +``` +Bits: 7 6 5 4 3 2 1 0 + [版本:2][类型:4][路由:2] +``` + +**字段说明**: +- **路由类型** (Bits 0-1): 决定包的路由方式 +- **负载类型** (Bits 2-5): 指定负载的数据类型 +- **版本号** (Bits 6-7): 协议版本控制 + +### 完整包结构 + +| 字段 | 大小 | 描述 | +|------|------|------| +| `header` | 1字节 | 路由类型 + 负载类型 + 版本 | +| `transport_codes` | 4字节* | 传输层路由优化代码 | +| `path_len` | 1字节 | 路径字段长度 | +| `path` | 最多64字节 | 路由路径数据 | +| `payload` | 最多184字节 | 实际传输数据 | + +* 仅在特定路由类型时存在 + +## 🛣️ 路由类型 + +### 1. Flood路由 (`ROUTE_TYPE_FLOOD = 0x01`) +- **动态路径构建**: 在传输过程中建立路由路径 +- **网络发现**: 自动探索网络拓扑 +- **适用场景**: 网络初始化、广播消息 + +### 2. Direct路由 (`ROUTE_TYPE_DIRECT = 0x02`) +- **预设路径**: 使用指定的路由路径 +- **高效传输**: 减少路由开销 +- **适用场景**: 点对点通信、已知路径 + +### 3. Transport路由 (扩展模式) +- **Flood+Transport**: 带传输编码的Flood路由 +- **Direct+Transport**: 带传输编码的Direct路由 +- **优化传输**: 通过编码提高可靠性 + +## 📄 负载类型 (16种) + +### 基础通信类型 +| 值 | 名称 | 描述 | +|----|------|------| +| `0x00` | `PAYLOAD_TYPE_REQ` | 请求消息 (带哈希和MAC) | +| `0x01` | `PAYLOAD_TYPE_RESPONSE` | 响应消息 | +| `0x02` | `PAYLOAD_TYPE_TXT_MSG` | 纯文本消息 | +| `0x03` | `PAYLOAD_TYPE_ACK` | 确认消息 | + +### 高级功能类型 +| 值 | 名称 | 描述 | +|----|------|------| +| `0x04` | `PAYLOAD_TYPE_ADVERT` | 节点广告 | +| `0x05` | `PAYLOAD_TYPE_GRP_TXT` | 组文本消息 (未验证) | +| `0x06` | `PAYLOAD_TYPE_GRP_DATA` | 组数据报 (未验证) | +| `0x08` | `PAYLOAD_TYPE_PATH` | 返回路径 | +| `0x09` | `PAYLOAD_TYPE_TRACE` | 路由跟踪 | + +### 扩展类型 +| 值 | 名称 | 描述 | +|----|------|------| +| `0x0A` | `PAYLOAD_TYPE_MULTIPART` | 多段包 | +| `0x0B` | `PAYLOAD_TYPE_CONTROL` | 控制包 | +| `0x0F` | `PAYLOAD_TYPE_RAW_CUSTOM` | 自定义包 | + +## 🔐 安全机制 + +### 加密架构 +- **Ed25519公钥**: 32字节公钥用于节点身份 +- **消息认证**: 2字节MAC保证数据完整性 +- **端到端加密**: 支持敏感数据加密传输 +- **节点指纹**: 1字节公钥哈希用于路由决策 + +### 密钥管理 +- **节点公钥**: 首次通信时交换 +- **会话密钥**: 基于节点公钥派生 +- **密钥缓存**: 本地存储已知节点的公钥 + +## 💬 通信流程 + +### 1. 节点发现 (Advertising) +```cpp +// 节点广告包结构 +struct NodeAdvert { + uint8_t public_key[32]; // Ed25519公钥 + uint32_t timestamp; // 发送时间戳 + uint8_t signature[64]; // 数字签名 + uint8_t appdata[]; // 可选应用数据 +}; +``` + +### 2. 文本消息通信 +```cpp +// 文本消息负载结构 +struct TextMessage { + uint32_t timestamp; // 发送时间戳 + uint8_t flags; // 消息标志 + uint8_t text[]; // UTF-8编码的文本 +}; +``` + +### 3. 路由跟踪 (Trace) +- **收集SNR**: 每个跳收集信号质量数据 +- **路径记录**: 记录完整的路由路径 +- **诊断信息**: 提供网络状态分析 + +## 🆚 与Meshtastic对比 + +| 特性 | MeshCore | Meshtastic | +|------|----------|------------| +| **数据格式** | 自定义二进制 | Google Protocol Buffers | +| **包大小** | 更紧凑 | 相对较大 | +| **扩展性** | 高 (自定义) | 中等 (proto定义) | +| **解析速度** | 快 | 中等 | +| **跨平台性** | C++专用 | 多语言支持 | + +## 🛠️ 协议实现要点 + +### 包编解码 +```cpp +// 包序列化 +uint8_t Packet::writeTo(uint8_t dest[]) const { + uint8_t i = 0; + dest[i++] = header; + if (hasTransportCodes()) { + memcpy(&dest[i], &transport_codes[0], 2); i += 2; + memcpy(&dest[i], &transport_codes[1], 2); i += 2; + } + dest[i++] = path_len; + memcpy(&dest[i], path, path_len); i += path_len; + memcpy(&dest[i], payload, payload_len); i += payload_len; + return i; +} + +// 包反序列化 +bool Packet::readFrom(const uint8_t src[], uint8_t len) { + // 实现包解析逻辑 +} +``` + +### 路由决策 +- **Flood模式**: 广播到所有邻居节点 +- **Direct模式**: 根据路径字段直接转发 +- **Transport模式**: 使用编码优化传输 + +### 去重机制 +- **包哈希**: SHA256哈希用于包唯一标识 +- **时间窗口**: 基于时间戳的去重检查 +- **节点过滤**: 避免向源节点回传 + +## 🎯 使用场景 + +### 1. 离线通信网络 +- **应急通信**: 灾难情况下保持连接 +- **户外活动**: 徒步、露营团队通信 +- **战术应用**: 军事和安全场景 + +### 2. 传感器网络 +- **环境监测**: 远程传感器数据收集 +- **工业物联网**: 设备状态监控 +- **农业应用**: 田间设备通信 + +### 3. 自定义Mesh应用 +- **专用协议**: 特定应用场景优化 +- **轻量级实现**: 资源受限设备 +- **灵活扩展**: 支持自定义负载类型 + +## 📊 性能特点 + +### 网络指标 +- **最大跳数**: 可配置,通常3-5跳 +- **包大小**: 最小20字节,最大256字节 +- **传输延迟**: 取决于跳数和传播时间 + +### 可靠性特性 +- **自动重试**: 失败包自动重传 +- **路径优化**: 动态选择最佳路由 +- **拥塞控制**: 避免网络过载 + +## 🔄 协议扩展 + +### 自定义负载类型 +MeshCore支持扩展到16种以上的负载类型,开发者可以: +1. 定义新的负载格式 +2. 实现对应的编解码逻辑 +3. 添加处理函数 + +### 路由算法扩展 +- **自定义路由策略**: 实现新的路由算法 +- **QoS支持**: 服务质量保证 +- **多路径路由**: 并行传输优化 + +## 📚 参考资源 + +- **协议规范**: `docs/packet_structure.md` +- **负载格式**: `docs/payloads.md` +- **示例代码**: `examples/` 目录 +- **API文档**: `include/MeshCore.h` + +这个协议设计非常适合需要定制LoRa Mesh网络的嵌入式项目,既保持了简洁性又提供了强大的功能扩展能力。 \ No newline at end of file diff --git a/docs/MESHTASTIC_PROTOBUF_USAGE.md b/docs/MESHTASTIC_PROTOBUF_USAGE.md new file mode 100644 index 00000000..acfd81a3 --- /dev/null +++ b/docs/MESHTASTIC_PROTOBUF_USAGE.md @@ -0,0 +1,275 @@ +# Meshtastic Protobuf 使用情况 + +本文档说明 trail-mate 项目中实际使用的 Meshtastic protobuf 报文类型,以及未使用的类型。 + +## 项目概述 + +trail-mate 是一个基于 LilyGo T-LoRa Pager 的 Meshtastic 兼容聊天应用,实现了基本的文本消息传递、节点发现和路由功能。 + +## 已使用的 Protobuf 类型 + +### 核心数据结构 + +#### `meshtastic_Data` +- **用途**: 核心数据消息载体 +- **使用位置**: `mt_codec_pb.cpp`, `mt_adapter.cpp` +- **字段**: portnum, payload, want_response, bitfield +- **功能**: 承载所有应用层数据 (文本消息、用户信息、路由消息等) + +#### `meshtastic_User` +- **用途**: 用户/节点信息 +- **使用位置**: `mt_codec_pb.cpp`, `mt_adapter.cpp` +- **字段**: id, short_name, long_name, macaddr, public_key, hw_model, role +- **功能**: 节点发现和用户信息广播 + +### 端口号枚举 + +#### 已使用的端口 +- `meshtastic_PortNum_TEXT_MESSAGE_APP` - 文本消息 ([portnums.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.h)) +- `meshtastic_PortNum_TEXT_MESSAGE_COMPRESSED_APP` - 压缩文本消息 ([portnums.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.h)) +- `meshtastic_PortNum_NODEINFO_APP` - 节点信息广播 ([portnums.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.h)) +- `meshtastic_PortNum_ROUTING_APP` - 路由确认消息 ([portnums.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.h)) + +### 数据结构 + +#### `meshtastic_Data` - 核心数据消息载体 +- **用途**: 承载所有应用层数据 (文本消息、用户信息、路由消息等) +- **使用位置**: `mt_codec_pb.cpp`, `mt_adapter.cpp` +- **文件**: [mesh.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/mesh.pb.h) +- **字段**: portnum, payload, want_response, bitfield + +#### `meshtastic_User` - 用户信息 +- **用途**: 用户/节点信息和公钥 +- **使用位置**: `mt_codec_pb.cpp`, `mt_adapter.cpp` +- **文件**: [mesh.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/mesh.pb.h) +- **字段**: id, short_name, long_name, macaddr, public_key, hw_model, role + +### 路由相关 + +#### `meshtastic_Routing` - 路由消息 +- **用途**: 路由消息和错误处理 +- **使用位置**: `mt_adapter.cpp` (sendRoutingAck函数) +- **文件**: [mesh.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/mesh.pb.h) +- **字段**: error_reason +- **功能**: 消息传递确认和错误报告 + +#### `meshtastic_Routing_Error` - 路由错误枚举 +- `meshtastic_Routing_Error_NONE` - 无错误确认 +- **文件**: [mesh.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/mesh.pb.h) + +### 硬件模型 + +#### `meshtastic_HardwareModel` - 硬件型号枚举 +- `meshtastic_HardwareModel_T_LORA_PAGER` - LilyGo T-LoRa Pager +- **文件**: [mesh.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/mesh.pb.h) + +### 设备配置 + +#### `meshtastic_Config_DeviceConfig_Role` - 设备角色 +- `meshtastic_Config_DeviceConfig_Role_CLIENT` - 客户端角色 +- **文件**: [config.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/config.pb.h) + +## 未使用的 Protobuf 类型详解 + +### 位置和导航相关 + +#### `meshtastic_PortNum_POSITION_APP` - GPS位置信息 +- **用途**: 广播设备的GPS位置坐标 +- **文件**: [portnums.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.h) +- **使用场景**: + - 实时位置共享和跟踪 + - 地图应用显示节点位置 + - 紧急情况下的位置报告 + - 导航和集合点协调 + +#### `meshtastic_PortNum_WAYPOINT_APP` - 航点信息 +- **用途**: 定义和管理导航航点 +- **文件**: [portnums.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.h) +- **使用场景**: + - 户外探险路线规划 + - 搜索和救援行动 + - 共享兴趣点 (POI) + - 团队协调导航目标 + +#### `meshtastic_Position` - 位置数据结构 +- **用途**: 存储GPS坐标、精度、时间戳等位置信息 +- **文件**: [mesh.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/mesh.pb.h) +- **字段**: latitude, longitude, altitude, precision, timestamp等 + +#### `meshtastic_Waypoint` - 航点数据结构 +- **用途**: 定义导航点的信息 +- **文件**: [mesh.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/mesh.pb.h) +- **字段**: name, description, position, icon等 + +### 遥测和传感器数据 + +#### `meshtastic_PortNum_TELEMETRY_APP` - 遥测数据 +- **用途**: 收集和广播设备传感器数据 +- **文件**: [portnums.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.h) +- **使用场景**: + - 环境监测 (温度、湿度、大气压) + - 设备状态监控 (电池电量、信号强度) + - 气象数据收集 + - 农业和工业物联网应用 + +#### `meshtastic_Telemetry` - 传感器数据结构 +- **用途**: 封装各种传感器测量值 +- **文件**: [telemetry.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/telemetry.pb.h) +- **支持的传感器类型**: + - 环境传感器 (温度、湿度、气压) + - 运动传感器 (加速度计、陀螺仪) + - 电源管理 (电池电压、电流) + - 无线电性能 (SNR、RSSI) + +### 远程硬件控制 + +#### `meshtastic_PortNum_REMOTE_HARDWARE_APP` - 远程硬件控制 +- **用途**: 远程控制连接到Meshtastic节点的硬件设备 +- **文件**: [portnums.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.h) +- **使用场景**: + - 远程开关控制 (继电器、LED) + - 传感器数据读取 + - 执行器控制 (电机、阀门) + - 物联网设备集成 + +#### `meshtastic_RemoteHardware` - 硬件控制消息 +- **用途**: 定义硬件控制命令和响应 +- **文件**: [remote_hardware.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/remote_hardware.pb.h) +- **支持的操作**: GPIO读写、ADC读取、PWM控制等 + +### 网络诊断 + +#### `meshtastic_PortNum_TRACEROUTE_APP` - 路由跟踪 +- **用途**: 诊断网络路径和性能 +- **文件**: [portnums.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.h) +- **使用场景**: + - 网络故障排查 + - 路由优化分析 + - 网络拓扑发现 + - 连接质量评估 + +#### `meshtastic_TraceRoute` - 路由跟踪数据 +- **用途**: 记录消息经过的节点路径 +- **文件**: [mesh.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/mesh.pb.h) +- **字段**: hop列表、延迟时间、信号质量等 + +### 高级消息类型 + +#### `meshtastic_PortNum_STORE_FORWARD_APP` - 存储转发 +- **用途**: 在节点离线时存储消息,待上线后转发 +- **文件**: [portnums.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.h) +- **Protobuf**: [storeforward.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/storeforward.pb.h) +- **使用场景**: + - 间歇性连接的网络 + - 移动节点的离线通信 + - 延迟容忍网络应用 + +#### `meshtastic_PortNum_RANGE_TEST_APP` - 距离测试 +- **用途**: 测试节点间的通信距离和信号质量 +- **文件**: [portnums.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.h) +- **编码格式**: 简单文本消息 (无需专用 protobuf) +- **使用场景**: + - 网络覆盖范围评估 + - 天线性能测试 + - 通信距离优化 + +#### `meshtastic_PortNum_PAXCOUNTER_APP` - 人群计数器 +- **用途**: 使用WiFi嗅探统计附近设备数量 +- **文件**: [portnums.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.h) +- **Protobuf**: [paxcount.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/paxcount.pb.h) +- **使用场景**: + - 人群密度监测 + - 交通流量分析 + - 商业场所客流量统计 + +#### `meshtastic_PortNum_ATAK_PLUGIN` - ATAK插件 +- **用途**: 与Android Team Awareness Kit (ATAK) 集成 +- **文件**: [portnums.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.h) +- **Protobuf**: [atak.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/atak.pb.h) +- **使用场景**: + - 军事和应急响应通信 + - 专业团队协调 + - GIS数据集成 + +#### `meshtastic_PortNum_AUDIO_APP` - 音频消息 +- **用途**: 传输 codec2 编码的音频数据 +- **文件**: [portnums.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.h) +- **编码格式**: codec2 音频帧 (非 protobuf,直接二进制) +- **使用场景**: + - 语音通信 (仅限 2.4GHz 带宽) + - 音频数据传输 +- **相关配置**: `meshtastic_ModuleConfig_AudioConfig` ([module_config.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/module_config.pb.h)) + +### 配置和设置 + +#### `meshtastic_Config` - 完整配置结构 +- **用途**: 设备的完整配置管理 +- **文件**: [config.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/config.pb.h) +- **包含的配置类型**: LoRa、WiFi、蓝牙、显示等所有模块配置 + +#### `meshtastic_Config_LoRaConfig` - LoRa配置 +- **用途**: LoRa无线电参数配置 +- **文件**: [config.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/config.pb.h) +- **配置项**: 频率、调制参数、发射功率、区域设置等 + +#### `meshtastic_ModuleConfig` - 模块配置 +- **用途**: 各功能模块的配置 (MQTT、遥测、位置等) +- **文件**: [module_config.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/module_config.pb.h) +- **使用场景**: 通过网络远程配置设备 + +#### `meshtastic_Channel` - 频道设置 +- **用途**: 定义通信频道和加密设置 +- **文件**: [channel.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/channel.pb.h) +- **字段**: 频道名称、PSK密钥、设置等 + +### 高级网络功能 + +#### `meshtastic_NodeInfo` - 扩展节点信息 +- **用途**: 比User更详细的节点信息 +- **文件**: [mesh.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/mesh.pb.h) +- **额外字段**: 设备状态、邻居节点、路由表等 + +#### `meshtastic_DeviceState` - 设备状态 +- **用途**: 报告设备运行状态 +- **文件**: [mesh.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/mesh.pb.h) +- **字段**: 电池状态、内存使用、温度等 + +#### `meshtastic_MqttClientProxyMessage` - MQTT代理消息 +- **用途**: 通过MQTT网关连接到互联网服务 +- **文件**: [mqtt.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/mqtt.pb.h) +- **使用场景**: 云服务集成、远程监控、数据转发 + +#### `meshtastic_AdminMessage` - 管理消息 +- **用途**: 远程设备管理和配置 +- **文件**: [admin.pb.h](../src/chat/infra/meshtastic/generated/meshtastic/admin.pb.h) +- **支持的操作**: 重启、配置更新、固件升级等 + +## 架构说明 + +### 应用层抽象 +项目使用 domain types (`ChatMessage`, `NodeInfo`, `MeshConfig` 等) 而不是直接使用 Meshtastic protobuf,这样提供了更好的抽象和可维护性。 + +### 协议兼容性 +通过 `mt_codec_pb.cpp` 实现 domain types 与 Meshtastic protobuf 之间的转换,确保与 Meshtastic 网络的兼容性。 + +### 功能范围限制 +当前实现专注于基本的聊天功能, deliberately 不实现以下高级功能: +- GPS位置共享 +- 传感器数据收集 +- 远程硬件控制 +- 复杂网络管理功能 + +这使得代码更简洁,内存占用更少,适合资源受限的嵌入式设备。 + +## 扩展建议 + +如果将来需要添加更多功能,可以考虑实现: + +1. **位置服务**: 使用 `meshtastic_Position` 和相关端口 +2. **遥测功能**: 使用 `meshtastic_Telemetry` 收集传感器数据 +3. **远程控制**: 使用 `meshtastic_RemoteHardware` 实现硬件控制 +4. **网络诊断**: 使用 `meshtastic_TraceRoute` 进行网络分析 + +## 总结 + +trail-mate 项目仅使用了 Meshtastic protobuf 的核心子集,专注于提供可靠的文本通信功能。这种设计选择既保证了与 Meshtastic 网络的兼容性,又保持了代码的简洁性和设备的轻量化。 \ No newline at end of file diff --git a/docs/MULTI_PROTOCOL_SUPPORT.md b/docs/MULTI_PROTOCOL_SUPPORT.md new file mode 100644 index 00000000..fcac113f --- /dev/null +++ b/docs/MULTI_PROTOCOL_SUPPORT.md @@ -0,0 +1,72 @@ +# 多协议支持实现说明 + +本文档说明当前 Trail Mate 在 "Meshtastic + MeshCore" 双协议场景下的实现方式。 +**协议不会在运行中自动判定或切换**,而是通过设置明确选择其中一个协议运行。 + +--- + +## 1) 协议选择方式 + +当前协议由设置项确定: +- `AppConfig::mesh_protocol` +- 持久化键:`mesh_protocol` +- 取值: + - `Meshtastic` + - `MeshCore` + +系统启动时读取配置,并通过 `ProtocolFactory` 创建对应的 adapter。运行期间不会动态切换。 + +--- + +## 2) 代码结构(单协议运行) + +核心思路: +- **UI 层只与 `IMeshAdapter` 交互,不感知协议** +- 只创建一个 adapter(Meshtastic 或 MeshCore) +- Radio 任务的原始数据直接交给选定 adapter 处理 + +### 结构 ASCII 图 + +``` ++------------------+ +| UI / UseCase | ++------------------+ + | + v ++-------------------------+ +| IMeshAdapter | ++-------------------------+ + | + v ++------------------+ +| Meshtastic OR | +| MeshCore Adapter | ++------------------+ +``` + +--- + +## 3) 接收流程(无动态判定) + +1. Radio 任务收到原始包 +2. 直接调用当前 adapter 的 `handleRawPacket()` +3. 解析出的文本消息进入 `ChatService` + +> 不再进行协议预判,也不维护节点协议映射。 + +--- + +## 当前实现状态说明 + +- Meshtastic:功能完整(含 NodeInfo 解析) +- MeshCore:目前只实现了 RAW_CUSTOM 文本收发(最小闭环) +- TXT_MSG / 加密 / 认证:待实现 + +--- + +## 扩展建议 + +如需支持更多协议: +- 在 Settings 中新增协议选项 +- 新建对应 adapter +- 仍保持“运行时单协议”的策略,避免混跑与误判 diff --git a/docs/meshcore/packet_structure.md b/docs/meshcore/packet_structure.md new file mode 100644 index 00000000..92c410be --- /dev/null +++ b/docs/meshcore/packet_structure.md @@ -0,0 +1,60 @@ +# Packet Structure + +| Field | Size (bytes) | Description | +|-----------------|----------------------------------|-----------------------------------------------------------| +| header | 1 | Contains routing type, payload type, and payload version. | +| transport_codes | 4 (optional) | 2x 16-bit transport codes (if ROUTE_TYPE_TRANSPORT_*) | +| path_len | 1 | Length of the path field in bytes. | +| path | up to 64 (`MAX_PATH_SIZE`) | Stores the routing path if applicable. | +| payload | up to 184 (`MAX_PACKET_PAYLOAD`) | The actual data being transmitted. | + +Note: see the [payloads doc](./payloads.md) for more information about the content of payload. + +## Header Breakdown + +bit 0 means the lowest bit (1s place) + +| Bits | Mask | Field | Description | +|-------|--------|-----------------|-----------------------------------------------| +| 0-1 | `0x03` | Route Type | Flood, Direct, Reserved - see below. | +| 2-5 | `0x3C` | Payload Type | Request, Response, ACK, etc. - see below. | +| 6-7 | `0xC0` | Payload Version | Versioning of the payload format - see below. | + +## Route Type Values + +| Value | Name | Description | +|--------|-------------------------------|--------------------------------------| +| `0x00` | `ROUTE_TYPE_TRANSPORT_FLOOD` | Flood routing mode + transport codes | +| `0x01` | `ROUTE_TYPE_FLOOD` | Flood routing mode (builds up path). | +| `0x02` | `ROUTE_TYPE_DIRECT` | Direct route (path is supplied). | +| `0x03` | `ROUTE_TYPE_TRANSPORT_DIRECT` | direct route + transport codes | + +## Payload Type Values + +| Value | Name | Description | +|--------|---------------------------|-----------------------------------------------| +| `0x00` | `PAYLOAD_TYPE_REQ` | Request (destination/source hashes + MAC). | +| `0x01` | `PAYLOAD_TYPE_RESPONSE` | Response to REQ or ANON_REQ. | +| `0x02` | `PAYLOAD_TYPE_TXT_MSG` | Plain text message. | +| `0x03` | `PAYLOAD_TYPE_ACK` | Acknowledgment. | +| `0x04` | `PAYLOAD_TYPE_ADVERT` | Node advertisement. | +| `0x05` | `PAYLOAD_TYPE_GRP_TXT` | Group text message (unverified). | +| `0x06` | `PAYLOAD_TYPE_GRP_DATA` | Group datagram (unverified). | +| `0x07` | `PAYLOAD_TYPE_ANON_REQ` | Anonymous request. | +| `0x08` | `PAYLOAD_TYPE_PATH` | Returned path. | +| `0x09` | `PAYLOAD_TYPE_TRACE` | trace a path, collecting SNI for each hop. | +| `0x0A` | `PAYLOAD_TYPE_MULTIPART` | packet is part of a sequence of packets. | +| `0x0B` | `PAYLOAD_TYPE_CONTROL` | control packet data (unencrypted) | +| `0x0C` | . | reserved | +| `0x0D` | . | reserved | +| `0x0E` | . | reserved | +| `0x0F` | `PAYLOAD_TYPE_RAW_CUSTOM` | Custom packet (raw bytes, custom encryption). | + +## Payload Version Values + +| Value | Version | Description | +|--------|---------|---------------------------------------------------| +| `0x00` | 1 | 1-byte src/dest hashes, 2-byte MAC. | +| `0x01` | 2 | Future version (e.g., 2-byte hashes, 4-byte MAC). | +| `0x02` | 3 | Future version. | +| `0x03` | 4 | Future version. | diff --git a/docs/meshcore/payloads.md b/docs/meshcore/payloads.md new file mode 100644 index 00000000..f86a70bc --- /dev/null +++ b/docs/meshcore/payloads.md @@ -0,0 +1,221 @@ +# Meshcore payloads +Inside of each [meshcore packet](./packet_structure.md) is a payload, identified by the payload type in the packet header. The types of payloads are: + +* Node advertisement. +* Acknowledgment. +* Returned path. +* Request (destination/source hashes + MAC). +* Response to REQ or ANON_REQ. +* Plain text message. +* Anonymous request. +* Group text message (unverified). +* Group datagram (unverified). +* Multi-part packet +* Control data packet +* Custom packet (raw bytes, custom encryption). + +This document defines the structure of each of these payload types. + +NOTE: all 16 and 32-bit integer fields are Little Endian. + +## Important concepts: + +* Node hash: the first byte of the node's public key + +# Node advertisement +This kind of payload notifies receivers that a node exists, and gives information about the node + +| Field | Size (bytes) | Description | +|---------------|-----------------|----------------------------------------------------------| +| public key | 32 | Ed25519 public key of the node | +| timestamp | 4 | unix timestamp of advertisement | +| signature | 64 | Ed25519 signature of public key, timestamp, and app data | +| appdata | rest of payload | optional, see below | + +Appdata + +| Field | Size (bytes) | Description | +|---------------|-----------------|-------------------------------------------------------| +| flags | 1 | specifies which of the fields are present, see below | +| latitude | 4 (optional) | decimal latitude multiplied by 1000000, integer | +| longitude | 4 (optional) | decimal longitude multiplied by 1000000, integer | +| feature 1 | 2 (optional) | reserved for future use | +| feature 2 | 2 (optional) | reserved for future use | +| name | rest of appdata | name of the node | + +Appdata Flags + +| Value | Name | Description | +|--------|----------------|---------------------------------------| +| `0x01` | is chat node | advert is for a chat node | +| `0x02` | is repeater | advert is for a repeater | +| `0x03` | is room server | advert is for a room server | +| `0x04` | is sensor | advert is for a sensor server | +| `0x10` | has location | appdata contains lat/long information | +| `0x20` | has feature 1 | Reserved for future use. | +| `0x40` | has feature 2 | Reserved for future use. | +| `0x80` | has name | appdata contains a node name | + +# Acknowledgement + +An acknowledgement that a message was received. Note that for returned path messages, an acknowledgement can be sent in the "extra" payload (see [Returned Path](#returned-path)) instead of as a separate ackowledgement packet. CLI commands do not cause acknowledgement responses, neither discrete nor extra. + +| Field | Size (bytes) | Description | +|----------|--------------|------------------------------------------------------------| +| checksum | 4 | CRC checksum of message timestamp, text, and sender pubkey | + + +# Returned path, request, response, and plain text message + +Returned path, request, response, and plain text messages are all formatted in the same way. See the subsection for more details about the ciphertext's associated plaintext representation. + +| Field | Size (bytes) | Description | +|------------------|-----------------|------------------------------------------------------| +| destination hash | 1 | first byte of destination node public key | +| source hash | 1 | first byte of source node public key | +| cipher MAC | 2 | MAC for encrypted data in next field | +| ciphertext | rest of payload | encrypted message, see subsections below for details | + +## Returned path + +Returned path messages provide a description of the route a packet took from the original author. Receivers will send returned path messages to the author of the original message. + +| Field | Size (bytes) | Description | +|-------------|--------------|----------------------------------------------------------------------------------------------| +| path length | 1 | length of next field | +| path | see above | a list of node hashes (one byte each) | +| extra type | 1 | extra, bundled payload type, eg., acknowledgement or response. Same values as in [packet structure](./packet_structure.md) | +| extra | rest of data | extra, bundled payload content, follows same format as main content defined by this document | + +## Request + +| Field | Size (bytes) | Description | +|--------------|-----------------|----------------------------| +| timestamp | 4 | send time (unix timestamp) | +| request type | 1 | see below | +| request data | rest of payload | depends on request type | + +Request type + +| Value | Name | Description | +|--------|----------------------|---------------------------------------| +| `0x01` | get stats | get stats of repeater or room server | +| `0x02` | keepalive | (deprecated) | +| `0x03` | get telemetry data | TODO | +| `0x04` | get min,max,avg data | sensor nodes - get min, max, average for given time span | +| `0x05` | get access list | get node's approved access list | + +### Get stats + +Gets information about the node, possibly including the following: + +* Battery level (millivolts) +* Current transmit queue length +* Current free queue length +* Last RSSI value +* Number of received packets +* Number of sent packets +* Total airtime (seconds) +* Total uptime (seconds) +* Number of packets sent as flood +* Number of packets sent directly +* Number of packets received as flood +* Number of packets received directly +* Error flags +* Last SNR value +* Number of direct route duplicates +* Number of flood route duplicates +* Number posted (?) +* Number of post pushes (?) + +### Get telemetry data + +Request data about sensors on the node, including battery level. + +## Response + +| Field | Size (bytes) | Description | +|---------|-----------------|-------------| +| tag | 4 | TODO | +| content | rest of payload | TODO | + +## Plain text message + +| Field | Size (bytes) | Description | +|--------------------|-----------------|--------------------------------------------------------------| +| timestamp | 4 | send time (unix timestamp) | +| txt_type + attempt | 1 | upper six bits are txt_type (see below), lower two bits are attempt number (0..3) | +| message | rest of payload | the message content, see next table | + +txt_type + +| Value | Description | Message content | +|--------|---------------------------|------------------------------------------------------------| +| `0x00` | plain text message | the plain text of the message | +| `0x01` | CLI command | the command text of the message | +| `0x02` | signed plain text message | first four bytes is sender pubkey prefix, followed by plain text message | + +# Anonymous request + +| Field | Size (bytes) | Description | +|------------------|-----------------|-------------------------------------------| +| destination hash | 1 | first byte of destination node public key | +| public key | 32 | sender's Ed25519 public key | +| cipher MAC | 2 | MAC for encrypted data in next field | +| ciphertext | rest of payload | encrypted message, see below for details | + +## Room server login + +| Field | Size (bytes) | Description | +|----------------|-----------------|-------------------------------------------------------------------------------| +| timestamp | 4 | sender time (unix timestamp) | +| sync timestamp | 4 | sender's "sync messages SINCE x" timestamp | +| password | rest of message | password for room | + +## Repeater/Sensor login + +| Field | Size (bytes) | Description | +|----------------|-----------------|-------------------------------------------------------------------------------| +| timestamp | 4 | sender time (unix timestamp) | +| password | rest of message | password for repeater/sensor | + +# Group text message / datagram + +| Field | Size (bytes) | Description | +|--------------|-----------------|--------------------------------------------| +| channel hash | 1 | first byte of SHA256 of channel's shared key | +| cipher MAC | 2 | MAC for encrypted data in next field | +| ciphertext | rest of payload | encrypted message, see below for details | + +The plaintext contained in the ciphertext matches the format described in [plain text message](#plain-text-message). Specifically, it consists of a four byte timestamp, a flags byte, and the message. The flags byte will generally be `0x00` because it is a "plain text message". The message will be of the form `: ` (eg., `user123: I'm on my way`). + + +# Control data + +| Field | Size (bytes) | Description | +|--------------|-----------------|--------------------------------------------| +| flags | 1 | upper 4 bits is sub_type | +| data | rest of payload | typically unencrypted data | + +## DISCOVER_REQ (sub_type) + +| Field | Size (bytes) | Description | +|--------------|-----------------|----------------------------------------------| +| flags | 1 | 0x8 (upper 4 bits), prefix_only (lowest bit) | +| type_filter | 1 | bit for each ADV_TYPE_* | +| tag | 4 | randomly generate by sender | +| since | 4 | (optional) epoch timestamp (0 by default) | + +## DISCOVER_RESP (sub_type) + +| Field | Size (bytes) | Description | +|--------------|-----------------|--------------------------------------------| +| flags | 1 | 0x9 (upper 4 bits), node_type (lower 4) | +| snr | 1 | signed, SNR*4 | +| tag | 4 | reflected back from DISCOVER_REQ | +| pubkey | 8 or 32 | node's ID (or prefix) | + + +# Custom packet + +Custom packets have no defined format. diff --git a/platformio.ini b/platformio.ini index 625eca22..8d794777 100644 --- a/platformio.ini +++ b/platformio.ini @@ -37,6 +37,7 @@ build_flags = -D CORE_DEBUG_LEVEL=0 ; Increase Arduino loopTask stack to handle LVGL + GPS map rendering -D ARDUINO_LOOP_STACK_SIZE=16384 + -std=gnu++17 -D LV_CONF_INCLUDE_SIMPLE -D LV_USE_SNAPSHOT=1 -I${PROJECT_DIR}/src/ui @@ -90,26 +91,6 @@ lib_deps = https://github.com/lewisxhe/ST25R3916-fork.git#0c8e00f49d12881d1cff6d6f0879b90ce7ed4033 https://github.com/lewisxhe/NFC-RFAL-fork.git#7bde4587ea44c36c178a43d083d7a7345c1e4cfe -[env:tlora_pager_sx1262_jtag] -extends = arduino_base -board = lilygo-t-lora-pager -upload_protocol = jtag -debug_tool = olimex-arm-usb-ocd-h -build_flags = - ${arduino_base.build_flags} - -D DISPLAY_DRIVER_ST7796 - -D SCREEN_WIDTH=480 - -D SCREEN_HEIGHT=222 - -D ARDUINO_T_LORA_PAGER - -D ARDUINO_LILYGO_LORA_SX1262 - -I variants/lilygo_tlora_pager -lib_deps = - ${arduino_base.lib_deps} - adafruit/Adafruit TCA8418 @ 1.0.2 - adafruit/Adafruit BusIO @ 1.17.0 - https://github.com/lewisxhe/ST25R3916-fork.git#0c8e00f49d12881d1cff6d6f0879b90ce7ed4033 - https://github.com/lewisxhe/NFC-RFAL-fork.git#7bde4587ea44c36c178a43d083d7a7345c1e4cfe - [env:tlora_pager_sx1280] extends = arduino_base board = lilygo-t-lora-pager diff --git a/src/app/app_config.h b/src/app/app_config.h index fc391bda..bc8d4ad4 100644 --- a/src/app/app_config.h +++ b/src/app/app_config.h @@ -5,26 +5,29 @@ #pragma once +#include "../chat/domain/chat_policy.h" +#include "../chat/domain/chat_types.h" +#include "../gps/domain/motion_config.h" #include #include -#include "../chat/domain/chat_types.h" -#include "../chat/domain/chat_policy.h" -#include "../gps/domain/motion_config.h" -namespace app { +namespace app +{ /** * @brief Application configuration */ -struct AppConfig { +struct AppConfig +{ // Chat settings chat::ChatPolicy chat_policy; chat::MeshConfig mesh_config; - + chat::MeshProtocol mesh_protocol; + // Device settings char node_name[32]; char short_name[16]; - + // Channel settings bool primary_enabled; bool secondary_enabled; @@ -33,10 +36,12 @@ struct AppConfig { // GPS settings uint32_t gps_interval_ms; gps::MotionConfig motion_config; - - AppConfig() { + + AppConfig() + { chat_policy = chat::ChatPolicy::outdoor(); mesh_config = chat::MeshConfig(); + mesh_protocol = chat::MeshProtocol::Meshtastic; strcpy(node_name, "TrailMate"); strcpy(short_name, "TM"); primary_enabled = true; @@ -45,38 +50,42 @@ struct AppConfig { gps_interval_ms = 60000; motion_config = gps::MotionConfig(); } - + /** * @brief Load from Preferences */ - bool load(Preferences& prefs) { + bool load(Preferences& prefs) + { prefs.begin("chat", true); - + // Load policy chat_policy.enable_relay = prefs.getBool("relay", true); chat_policy.hop_limit_default = prefs.getUChar("hop_limit", 2); chat_policy.ack_for_broadcast = prefs.getBool("ack_bcast", false); chat_policy.ack_for_squad = prefs.getBool("ack_squad", true); chat_policy.max_tx_retries = prefs.getUChar("max_retries", 1); - + // Load mesh config mesh_config.region = prefs.getUChar("region", 0); mesh_config.modem_preset = prefs.getUChar("modem_preset", 0); mesh_config.tx_power = prefs.getChar("tx_power", 14); mesh_config.hop_limit = prefs.getUChar("mesh_hop_limit", 2); mesh_config.enable_relay = prefs.getBool("mesh_relay", true); - + mesh_protocol = static_cast( + prefs.getUChar("mesh_protocol", static_cast(chat::MeshProtocol::Meshtastic))); + // Load device name size_t len = prefs.getBytes("node_name", node_name, sizeof(node_name) - 1); node_name[len] = '\0'; len = prefs.getBytes("short_name", short_name, sizeof(short_name) - 1); short_name[len] = '\0'; - + // Load channel settings primary_enabled = prefs.getBool("primary_enabled", true); secondary_enabled = prefs.getBool("secondary_enabled", false); prefs.getBytes("secondary_key", secondary_key, 16); - + memcpy(mesh_config.secondary_key, secondary_key, sizeof(mesh_config.secondary_key)); + prefs.end(); prefs.begin("gps", true); @@ -86,36 +95,39 @@ struct AppConfig { prefs.end(); return true; } - + /** * @brief Save to Preferences */ - bool save(Preferences& prefs) { + bool save(Preferences& prefs) + { prefs.begin("chat", false); - + // Save policy prefs.putBool("relay", chat_policy.enable_relay); prefs.putUChar("hop_limit", chat_policy.hop_limit_default); prefs.putBool("ack_bcast", chat_policy.ack_for_broadcast); prefs.putBool("ack_squad", chat_policy.ack_for_squad); prefs.putUChar("max_retries", chat_policy.max_tx_retries); - + // Save mesh config prefs.putUChar("region", mesh_config.region); prefs.putUChar("modem_preset", mesh_config.modem_preset); prefs.putChar("tx_power", mesh_config.tx_power); prefs.putUChar("mesh_hop_limit", mesh_config.hop_limit); prefs.putBool("mesh_relay", mesh_config.enable_relay); - + prefs.putUChar("mesh_protocol", static_cast(mesh_protocol)); + // Save device name prefs.putBytes("node_name", node_name, strlen(node_name)); prefs.putBytes("short_name", short_name, strlen(short_name)); - + // Save channel settings prefs.putBool("primary_enabled", primary_enabled); prefs.putBool("secondary_enabled", secondary_enabled); + memcpy(secondary_key, mesh_config.secondary_key, sizeof(secondary_key)); prefs.putBytes("secondary_key", secondary_key, 16); - + prefs.end(); prefs.begin("gps", false); diff --git a/src/app/app_context.cpp b/src/app/app_context.cpp index f2f98730..1a8a76c3 100644 --- a/src/app/app_context.cpp +++ b/src/app/app_context.cpp @@ -4,23 +4,27 @@ */ #include "app_context.h" -#include "../sys/event_bus.h" +#include "../chat/infra/protocol_factory.h" #include "../gps/usecase/gps_service.h" -#include "app_tasks.h" +#include "../sys/event_bus.h" #include "../ui/widgets/system_notification.h" +#include "app_tasks.h" #include -namespace app { +namespace app +{ -bool AppContext::init(TLoRaPagerBoard& board, bool use_mock_adapter, uint32_t disable_hw_init) { +bool AppContext::init(TLoRaPagerBoard& board, bool use_mock_adapter, uint32_t disable_hw_init) +{ // Store board reference for hardware access board_ = &board; - + // Initialize event bus - if (!sys::EventBus::init()) { + if (!sys::EventBus::init()) + { return false; } - + // Load configuration config_.load(preferences_); @@ -28,66 +32,78 @@ bool AppContext::init(TLoRaPagerBoard& board, bool use_mock_adapter, uint32_t di board, disable_hw_init, config_.gps_interval_ms, - config_.motion_config - ); - + config_.motion_config); + // Create domain model chat_model_ = std::make_unique(); chat_model_->setPolicy(config_.chat_policy); - + // Create storage (flash-backed ring, 300 messages FIFO) auto flash_store = std::make_unique(); - if (flash_store->isReady()) { + if (flash_store->isReady()) + { flash_store_ = flash_store.get(); chat_store_ = std::move(flash_store); - } else { + } + else + { flash_store_ = nullptr; chat_store_ = std::make_unique(); } - - // Create mesh adapter - if (use_mock_adapter) { - mesh_adapter_ = std::make_unique(); - } else { - auto* mt_adapter = new chat::meshtastic::MtAdapter(board); - mt_adapter->applyConfig(config_.mesh_config); - mesh_adapter_.reset(mt_adapter); - - // Initialize tasks for real LoRa - if (!app::AppTasks::init(board, mt_adapter)) { - Serial.printf("[APP] WARNING: Failed to start LoRa tasks\n"); - } else { - Serial.printf("[APP] LoRa tasks started\n"); - } + + // Create mesh adapter (selected by config) + (void)use_mock_adapter; + auto adapter = chat::ProtocolFactory::createAdapter(config_.mesh_protocol, board); + if (adapter) + { + adapter->applyConfig(config_.mesh_config); + mesh_adapter_ = std::move(adapter); } - + chat::IMeshAdapter* adapter_raw = mesh_adapter_.get(); + + // Initialize tasks for real LoRa + if (!app::AppTasks::init(board, adapter_raw)) + { + Serial.printf("[APP] WARNING: Failed to start LoRa tasks\n"); + } + else + { + Serial.printf("[APP] LoRa tasks started\n"); + } + // Create chat service chat_service_ = std::make_unique( *chat_model_, *mesh_adapter_, *chat_store_); // Load persisted messages into model (no unread) - if (flash_store_) { + if (flash_store_) + { std::vector all_msgs = flash_store_->loadAll(); std::vector touched; touched.reserve(all_msgs.size()); - for (const auto& msg : all_msgs) { - if (msg.from == 0) { + for (const auto& msg : all_msgs) + { + if (msg.from == 0) + { chat_model_->onSendQueued(msg); - } else { + } + else + { chat_model_->onIncoming(msg); } chat::ConversationId conv(msg.channel, msg.peer ? msg.peer : msg.from); touched.push_back(conv); } - for (const auto& conv : touched) { + for (const auto& conv : touched) + { chat_model_->markRead(conv); } } - + // Create contact infrastructure node_store_ = std::make_unique(); contact_store_ = std::make_unique(); - + // Create contact service with dependency injection contact_service_ = std::make_unique( *node_store_, *contact_store_); @@ -96,69 +112,129 @@ bool AppContext::init(TLoRaPagerBoard& board, bool use_mock_adapter, uint32_t di return true; } -void AppContext::update() { +void AppContext::update() +{ // Update chat service (process incoming messages) - if (chat_service_) { + if (chat_service_) + { chat_service_->processIncoming(); } - + // Update UI controller - if (ui_controller_) { + if (ui_controller_) + { ui_controller_->update(); } - + // Process events sys::Event* event = nullptr; - while (sys::EventBus::subscribe(&event, 0)) { - if (!event) { + while (sys::EventBus::subscribe(&event, 0)) + { + if (!event) + { continue; } - + // Handle global events (like haptic feedback) before UI-specific handling - switch (event->type) { - case sys::EventType::ChatNewMessage: { - sys::ChatNewMessageEvent* msg_event = (sys::ChatNewMessageEvent*)event; - Serial.printf("[AppContext::update] ChatNewMessage received: channel=%d\n", msg_event->channel); - - // Global haptic feedback on incoming messages (works regardless of UI state) - if (board_) { - Serial.printf("[AppContext::update] Triggering haptic feedback...\n"); - board_->vibrator(); - Serial.printf("[AppContext::update] Haptic feedback triggered\n"); - } else { - Serial.printf("[AppContext::update] WARNING: board_ is nullptr, cannot trigger vibration\n"); - } - - // Show system notification - ui::SystemNotification::show(msg_event->text, 10000); - break; + switch (event->type) + { + case sys::EventType::ChatNewMessage: + { + sys::ChatNewMessageEvent* msg_event = (sys::ChatNewMessageEvent*)event; + Serial.printf("[AppContext::update] ChatNewMessage received: channel=%d\n", msg_event->channel); + + // Global haptic feedback on incoming messages (works regardless of UI state) + if (board_) + { + Serial.printf("[AppContext::update] Triggering haptic feedback...\n"); + board_->vibrator(); + Serial.printf("[AppContext::update] Haptic feedback triggered\n"); } - case sys::EventType::NodeInfoUpdate: { - sys::NodeInfoUpdateEvent* node_event = (sys::NodeInfoUpdateEvent*)event; - // Update ContactService with node info from event - if (contact_service_) { - contact_service_->updateNodeInfo( - node_event->node_id, - node_event->short_name, - node_event->long_name, - node_event->snr, - node_event->timestamp); - } - // Don't forward to UI - this is handled by ContactService - delete event; - continue; // Skip UI forwarding + else + { + Serial.printf("[AppContext::update] WARNING: board_ is nullptr, cannot trigger vibration\n"); } - default: - break; + + // Show system notification + ui::SystemNotification::show(msg_event->text, 10000); + break; } - + case sys::EventType::NodeInfoUpdate: + { + sys::NodeInfoUpdateEvent* node_event = (sys::NodeInfoUpdateEvent*)event; + // Update ContactService with node info from event + if (contact_service_) + { + contact_service_->updateNodeInfo( + node_event->node_id, + node_event->short_name, + node_event->long_name, + node_event->snr, + node_event->timestamp, + node_event->protocol); + } + // Don't forward to UI - this is handled by ContactService + delete event; + continue; // Skip UI forwarding + } + case sys::EventType::NodeProtocolUpdate: + { + sys::NodeProtocolUpdateEvent* node_event = (sys::NodeProtocolUpdateEvent*)event; + if (contact_service_) + { + contact_service_->updateNodeProtocol( + node_event->node_id, + node_event->protocol, + node_event->timestamp); + } + delete event; + continue; + } + default: + break; + } + // Forward event to UI controller if it exists - if (ui_controller_) { + if (ui_controller_) + { ui_controller_->onChatEvent(event); - } else { + } + else + { delete event; } } } +void AppContext::clearNodeDb() +{ + if (node_store_) + { + node_store_->clear(); + } + if (contact_service_) + { + contact_service_->clearCache(); + } +} + +void AppContext::clearMessageDb() +{ + if (chat_service_) + { + chat_service_->clearAllMessages(); + } + else if (chat_model_) + { + chat_model_->clearAll(); + if (chat_store_) + { + chat_store_->clearChannel(chat::ChannelId::PRIMARY); + chat_store_->clearChannel(chat::ChannelId::SECONDARY); + chat_store_->setUnread(chat::ChannelId::PRIMARY, 0); + chat_store_->setUnread(chat::ChannelId::SECONDARY, 0); + } + } +} + } // namespace app diff --git a/src/app/app_context.h b/src/app/app_context.h index 32c74933..7a463a27 100644 --- a/src/app/app_context.h +++ b/src/app/app_context.h @@ -9,103 +9,138 @@ #include "../chat/usecase/chat_service.h" #include "../chat/usecase/contact_service.h" - -namespace app { +namespace app +{ class AppContext; } -#include "../chat/ports/i_mesh_adapter.h" -#include "../chat/ports/i_chat_store.h" -#include "../chat/ports/i_node_store.h" -#include "../chat/ports/i_contact_store.h" -#include "../chat/infra/store/ram_store.h" -#include "../chat/infra/store/log_store.h" -#include "../chat/infra/store/flash_store.h" -#include "../chat/infra/mock_mesh_adapter.h" -#include "../chat/infra/meshtastic/mt_adapter.h" -#include "../chat/infra/meshtastic/node_store.h" #include "../chat/infra/contact_store.h" +#include "../chat/infra/meshtastic/node_store.h" +#include "../chat/infra/store/flash_store.h" +#include "../chat/infra/store/log_store.h" +#include "../chat/infra/store/ram_store.h" +#include "../chat/ports/i_chat_store.h" +#include "../chat/ports/i_contact_store.h" +#include "../chat/ports/i_mesh_adapter.h" +#include "../chat/ports/i_node_store.h" #include "../ui/ui_controller.h" #include "app_config.h" -#include "../board/TLoRaPagerBoard.h" #include -namespace app { +class TLoRaPagerBoard; + +namespace app +{ /** * @brief Application context * Manages all dependencies and provides singleton access */ -class AppContext { -public: - static AppContext& getInstance() { +class AppContext +{ + public: + static AppContext& getInstance() + { static AppContext instance; return instance; } - + /** * @brief Initialize application context * @param board Board instance * @param use_mock_adapter Use mock adapter instead of real LoRa */ bool init(TLoRaPagerBoard& board, bool use_mock_adapter = true, uint32_t disable_hw_init = 0); - + /** * @brief Get chat service */ - chat::ChatService& getChatService() { + chat::ChatService& getChatService() + { return *chat_service_; } - + /** * @brief Get contact service */ - chat::contacts::ContactService& getContactService() { + chat::contacts::ContactService& getContactService() + { return *contact_service_; } - + /** * @brief Get UI controller */ - chat::ui::UiController* getUiController() { + chat::ui::UiController* getUiController() + { return ui_controller_.get(); } - + /** * @brief Get configuration */ - AppConfig& getConfig() { + AppConfig& getConfig() + { return config_; } - void saveConfig() { + void saveConfig() + { config_.save(preferences_); } - + + void applyMeshConfig() + { + if (mesh_adapter_) + { + mesh_adapter_->applyConfig(config_.mesh_config); + } + } + + /** + * @brief Reset mesh config to defaults and apply + */ + void resetMeshConfig() + { + config_.mesh_config = chat::MeshConfig(); + saveConfig(); + applyMeshConfig(); + } + + /** + * @brief Clear all stored node info + */ + void clearNodeDb(); + + /** + * @brief Clear all stored chat messages + */ + void clearMessageDb(); + /** * @brief Update (call from main loop) */ void update(); -private: + private: AppContext() = default; ~AppContext() = default; AppContext(const AppContext&) = delete; AppContext& operator=(const AppContext&) = delete; - + // Domain std::unique_ptr chat_model_; - + // Infrastructure std::unique_ptr chat_store_; chat::FlashStore* flash_store_ = nullptr; std::unique_ptr mesh_adapter_; std::unique_ptr node_store_; std::unique_ptr contact_store_; - + // Use case std::unique_ptr chat_service_; std::unique_ptr contact_service_; - + // UI std::unique_ptr ui_controller_; @@ -114,7 +149,7 @@ private: // Config AppConfig config_; Preferences preferences_; - + // Board reference for hardware access (haptic feedback, etc.) TLoRaPagerBoard* board_ = nullptr; }; diff --git a/src/app/app_tasks.cpp b/src/app/app_tasks.cpp index d0975996..5994c7e9 100644 --- a/src/app/app_tasks.cpp +++ b/src/app/app_tasks.cpp @@ -13,10 +13,14 @@ #if LORA_LOG_ENABLE #define LORA_LOG(...) Serial.printf(__VA_ARGS__) #else -#define LORA_LOG(...) do {} while (0) +#define LORA_LOG(...) \ + do \ + { \ + } while (0) #endif -namespace app { +namespace app +{ // Static members QueueHandle_t AppTasks::radio_tx_queue_ = nullptr; @@ -25,62 +29,68 @@ QueueHandle_t AppTasks::mesh_queue_ = nullptr; TaskHandle_t AppTasks::radio_task_handle_ = nullptr; TaskHandle_t AppTasks::mesh_task_handle_ = nullptr; TLoRaPagerBoard* AppTasks::board_ = nullptr; -chat::meshtastic::MtAdapter* AppTasks::adapter_ = nullptr; +chat::IMeshAdapter* AppTasks::adapter_ = nullptr; -bool AppTasks::init(TLoRaPagerBoard& board, chat::meshtastic::MtAdapter* adapter) { +bool AppTasks::init(TLoRaPagerBoard& board, chat::IMeshAdapter* adapter) +{ board_ = &board; adapter_ = adapter; - + // Create queues radio_tx_queue_ = xQueueCreate(RADIO_QUEUE_SIZE, sizeof(RadioPacket)); radio_rx_queue_ = xQueueCreate(RADIO_QUEUE_SIZE, sizeof(RadioPacket)); mesh_queue_ = xQueueCreate(MESH_QUEUE_SIZE, sizeof(RadioPacket)); - - if (!radio_tx_queue_ || !radio_rx_queue_ || !mesh_queue_) { + + if (!radio_tx_queue_ || !radio_rx_queue_ || !mesh_queue_) + { return false; } - + // Create radio task (high priority) BaseType_t result = xTaskCreate( radioTask, "radio_task", - 4 * 1024, // Stack size + 4 * 1024, // Stack size nullptr, - 10, // High priority - &radio_task_handle_ - ); - - if (result != pdPASS) { + 10, // High priority + &radio_task_handle_); + + if (result != pdPASS) + { return false; } - + // Create mesh task (medium priority) result = xTaskCreate( meshTask, "mesh_task", - 6 * 1024, // Stack size + 6 * 1024, // Stack size nullptr, - 5, // Medium priority - &mesh_task_handle_ - ); - + 5, // Medium priority + &mesh_task_handle_); + return (result == pdPASS); } -void AppTasks::radioTask(void* pvParameters) { +void AppTasks::radioTask(void* pvParameters) +{ (void)pvParameters; - + const TickType_t poll_delay = pdMS_TO_TICKS(10); uint8_t rx_buffer[255]; bool rx_started = false; - - while (true) { + + while (true) + { // Process TX queue RadioPacket tx_packet; - if (xQueueReceive(radio_tx_queue_, &tx_packet, 0) == pdPASS) { - if (tx_packet.is_tx && tx_packet.data && tx_packet.size > 0) { + if (xQueueReceive(radio_tx_queue_, &tx_packet, 0) == pdPASS) + { + if (tx_packet.is_tx && tx_packet.data && tx_packet.size > 0) + { // Send packet - if (board_ && board_->isHardwareOnline(HW_RADIO_ONLINE)) { + if (board_ && board_->isHardwareOnline(HW_RADIO_ONLINE)) + { int state = RADIOLIB_ERR_NONE; #if defined(ARDUINO_LILYGO_LORA_SX1262) state = board_->radio.transmit(tx_packet.data, tx_packet.size); @@ -88,34 +98,46 @@ void AppTasks::radioTask(void* pvParameters) { state = board_->radio.transmit(tx_packet.data, tx_packet.size); #endif LORA_LOG("[LORA] TX queue len=%u state=%d\n", (unsigned)tx_packet.size, state); - if (state == RADIOLIB_ERR_NONE) { + if (state == RADIOLIB_ERR_NONE) + { #if defined(ARDUINO_LILYGO_LORA_SX1262) || defined(ARDUINO_LILYGO_LORA_SX1280) int rx_state = board_->radio.startReceive(); - if (rx_state == RADIOLIB_ERR_NONE) { + if (rx_state == RADIOLIB_ERR_NONE) + { rx_started = true; - } else { + } + else + { LORA_LOG("[LORA] RX start fail state=%d\n", rx_state); } #endif } // Free buffer (if allocated) - if (tx_packet.data) { + if (tx_packet.data) + { free(tx_packet.data); } - } else { + } + else + { LORA_LOG("[LORA] TX drop (radio offline) len=%u\n", (unsigned)tx_packet.size); } } } - + // Poll for RX (non-blocking) - if (board_ && board_->isHardwareOnline(HW_RADIO_ONLINE)) { - if (!rx_started) { + if (board_ && board_->isHardwareOnline(HW_RADIO_ONLINE)) + { + if (!rx_started) + { #if defined(ARDUINO_LILYGO_LORA_SX1262) || defined(ARDUINO_LILYGO_LORA_SX1280) int rx_state = board_->radio.startReceive(); - if (rx_state == RADIOLIB_ERR_NONE) { + if (rx_state == RADIOLIB_ERR_NONE) + { rx_started = true; - } else { + } + else + { LORA_LOG("[LORA] RX start fail state=%d\n", rx_state); } #endif @@ -124,93 +146,118 @@ void AppTasks::radioTask(void* pvParameters) { int packet_length = 0; #if defined(ARDUINO_LILYGO_LORA_SX1262) uint32_t irq = board_->radio.getIrqFlags(); - if (irq & RADIOLIB_SX126X_IRQ_RX_DONE) { + if (irq & RADIOLIB_SX126X_IRQ_RX_DONE) + { packet_length = static_cast(board_->radio.getPacketLength(true)); - if (packet_length > 0 && packet_length <= 255) { + if (packet_length > 0 && packet_length <= 255) + { int state = board_->radio.readData(rx_buffer, packet_length); - if (state == RADIOLIB_ERR_NONE) { + if (state == RADIOLIB_ERR_NONE) + { RadioPacket rx_packet; rx_packet.data = (uint8_t*)malloc(packet_length); - if (rx_packet.data) { + if (rx_packet.data) + { memcpy(rx_packet.data, rx_buffer, packet_length); rx_packet.size = packet_length; rx_packet.is_tx = false; - + LORA_LOG("[LORA] RX len=%d\n", packet_length); // Send to mesh queue xQueueSend(mesh_queue_, &rx_packet, portMAX_DELAY); } - } else { + } + else + { LORA_LOG("[LORA] RX read fail len=%d state=%d\n", packet_length, state); } } - } else if (irq) { + } + else if (irq) + { board_->radio.clearIrqFlags(irq); } #elif defined(ARDUINO_LILYGO_LORA_SX1280) uint32_t irq = board_->radio.getIrqFlags(); - if (irq & RADIOLIB_SX128X_IRQ_RX_DONE) { + if (irq & RADIOLIB_SX128X_IRQ_RX_DONE) + { packet_length = static_cast(board_->radio.getPacketLength(true)); - if (packet_length > 0 && packet_length <= 255) { + if (packet_length > 0 && packet_length <= 255) + { int state = board_->radio.readData(rx_buffer, packet_length); - if (state == RADIOLIB_ERR_NONE) { + if (state == RADIOLIB_ERR_NONE) + { RadioPacket rx_packet; rx_packet.data = (uint8_t*)malloc(packet_length); - if (rx_packet.data) { + if (rx_packet.data) + { memcpy(rx_packet.data, rx_buffer, packet_length); rx_packet.size = packet_length; rx_packet.is_tx = false; - + LORA_LOG("[LORA] RX len=%d\n", packet_length); // Send to mesh queue xQueueSend(mesh_queue_, &rx_packet, portMAX_DELAY); } - } else { + } + else + { LORA_LOG("[LORA] RX read fail len=%d state=%d\n", packet_length, state); } } - } else if (irq) { + } + else if (irq) + { board_->radio.clearIrqFlags(irq); } #endif - if (packet_length > 0) { + if (packet_length > 0) + { int rx_state = board_->radio.startReceive(); - if (rx_state == RADIOLIB_ERR_NONE) { + if (rx_state == RADIOLIB_ERR_NONE) + { rx_started = true; - } else { + } + else + { rx_started = false; LORA_LOG("[LORA] RX restart fail state=%d\n", rx_state); } } } - + vTaskDelay(poll_delay); } } -void AppTasks::meshTask(void* pvParameters) { +void AppTasks::meshTask(void* pvParameters) +{ (void)pvParameters; - + const TickType_t poll_delay = pdMS_TO_TICKS(50); - - while (true) { + + while (true) + { // Process received packets RadioPacket rx_packet; - if (xQueueReceive(mesh_queue_, &rx_packet, 0) == pdPASS) { - if (!rx_packet.is_tx && rx_packet.data && adapter_) { - // Decode and process - adapter_->processReceivedPacket(rx_packet.data, rx_packet.size); - + if (xQueueReceive(mesh_queue_, &rx_packet, 0) == pdPASS) + { + if (!rx_packet.is_tx && rx_packet.data && adapter_) + { + // Decode and process through configured mesh adapter + adapter_->handleRawPacket(rx_packet.data, rx_packet.size); + // Free buffer free(rx_packet.data); } } - + // Process send queue in adapter - if (adapter_) { + if (adapter_) + { adapter_->processSendQueue(); } - + vTaskDelay(poll_delay); } } diff --git a/src/app/app_tasks.h b/src/app/app_tasks.h index 982f2893..dcc35e22 100644 --- a/src/app/app_tasks.h +++ b/src/app/app_tasks.h @@ -5,68 +5,73 @@ #pragma once -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" #include "../board/TLoRaPagerBoard.h" -#include "../chat/infra/meshtastic/mt_adapter.h" +#include "../chat/ports/i_mesh_adapter.h" +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "freertos/task.h" #include -namespace app { +namespace app +{ /** * @brief Task management */ -class AppTasks { -public: +class AppTasks +{ + public: static constexpr size_t RADIO_QUEUE_SIZE = 10; static constexpr size_t MESH_QUEUE_SIZE = 10; - - struct RadioPacket { + + struct RadioPacket + { uint8_t* data; size_t size; - bool is_tx; // true for TX, false for RX + bool is_tx; // true for TX, false for RX }; - + /** * @brief Initialize tasks * @param board Board instance * @param adapter Mesh adapter */ - static bool init(TLoRaPagerBoard& board, chat::meshtastic::MtAdapter* adapter); - + static bool init(TLoRaPagerBoard& board, chat::IMeshAdapter* adapter); + /** * @brief Radio task (high priority) */ static void radioTask(void* pvParameters); - + /** * @brief Mesh task (medium priority) */ static void meshTask(void* pvParameters); - + /** * @brief Get radio TX queue */ - static QueueHandle_t getRadioTxQueue() { + static QueueHandle_t getRadioTxQueue() + { return radio_tx_queue_; } - + /** * @brief Get radio RX queue */ - static QueueHandle_t getRadioRxQueue() { + static QueueHandle_t getRadioRxQueue() + { return radio_rx_queue_; } -private: + private: static QueueHandle_t radio_tx_queue_; static QueueHandle_t radio_rx_queue_; static QueueHandle_t mesh_queue_; static TaskHandle_t radio_task_handle_; static TaskHandle_t mesh_task_handle_; static TLoRaPagerBoard* board_; - static chat::meshtastic::MtAdapter* adapter_; + static chat::IMeshAdapter* adapter_; }; } // namespace app diff --git a/src/audio/codec/_wav_header.h b/src/audio/codec/_wav_header.h index 10b99542..b9150d18 100644 --- a/src/audio/codec/_wav_header.h +++ b/src/audio/codec/_wav_header.h @@ -1,6 +1,6 @@ #pragma once -#include #include +#include /** * @brief Header structure for WAV file with only one data chunk @@ -11,79 +11,85 @@ * (including Xtensa & RISC-V) */ -typedef struct { - char chunk_id[4]; /*!< Contains the letters "RIFF" in ASCII form */ - uint32_t chunk_size; /*!< This is the size of the rest of the chunk following this number */ - char chunk_format[4]; /*!< Contains the letters "WAVE" */ +typedef struct +{ + char chunk_id[4]; /*!< Contains the letters "RIFF" in ASCII form */ + uint32_t chunk_size; /*!< This is the size of the rest of the chunk following this number */ + char chunk_format[4]; /*!< Contains the letters "WAVE" */ } __attribute__((packed)) wav_descriptor_chunk_t; /*!< Canonical WAVE format starts with the RIFF header */ -typedef struct { - char subchunk_id[4]; /*!< Contains the letters "fmt " */ - uint32_t subchunk_size; /*!< PCM = 16, This is the size of the rest of the Subchunk which follows this number */ - uint16_t audio_format; /*!< PCM = 1, values other than 1 indicate some form of compression */ - uint16_t num_of_channels; /*!< Mono = 1, Stereo = 2, etc. */ - uint32_t sample_rate; /*!< 8000, 44100, etc. */ - uint32_t byte_rate; /*!< ==SampleRate * NumChannels * BitsPerSample s/ 8 */ - uint16_t block_align; /*!< ==NumChannels * BitsPerSample / 8 */ - uint16_t bits_per_sample; /*!< 8 bits = 8, 16 bits = 16, etc. */ +typedef struct +{ + char subchunk_id[4]; /*!< Contains the letters "fmt " */ + uint32_t subchunk_size; /*!< PCM = 16, This is the size of the rest of the Subchunk which follows this number */ + uint16_t audio_format; /*!< PCM = 1, values other than 1 indicate some form of compression */ + uint16_t num_of_channels; /*!< Mono = 1, Stereo = 2, etc. */ + uint32_t sample_rate; /*!< 8000, 44100, etc. */ + uint32_t byte_rate; /*!< ==SampleRate * NumChannels * BitsPerSample s/ 8 */ + uint16_t block_align; /*!< ==NumChannels * BitsPerSample / 8 */ + uint16_t bits_per_sample; /*!< 8 bits = 8, 16 bits = 16, etc. */ } __attribute__((packed)) pcm_wav_fmt_chunk_t; /*!< The "fmt " subchunk describes the sound data's format */ -typedef struct { - char subchunk_id[4]; /*!< Contains the letters "fmt " */ - uint32_t subchunk_size; /*!< ALAW/MULAW = 18, This is the size of the rest of the Subchunk which follows this number */ - uint16_t audio_format; /*!< ALAW = 6, MULAW = 7, values other than 1 indicate some form of compression */ - uint16_t num_of_channels; /*!< ALAW/MULAW = 1, Mono = 1, Stereo = 2, etc. */ - uint32_t sample_rate; /*!< ALAW/MULAW = 8000, 8000, 44100, etc. */ - uint32_t byte_rate; /*!< ALAW/MULAW = 8000, ==SampleRate * NumChannels * BitsPerSample s/ 8 */ - uint16_t block_align; /*!< ALAW/MULAW = 1, ==NumChannels * BitsPerSample / 8 */ - uint16_t bits_per_sample; /*!< ALAW/MULAW = 8, 8 bits = 8, 16 bits = 16, etc. */ - uint16_t ext_size; /*!< ALAW/MULAW = 0, Size of the extension (0 or 22) */ +typedef struct +{ + char subchunk_id[4]; /*!< Contains the letters "fmt " */ + uint32_t subchunk_size; /*!< ALAW/MULAW = 18, This is the size of the rest of the Subchunk which follows this number */ + uint16_t audio_format; /*!< ALAW = 6, MULAW = 7, values other than 1 indicate some form of compression */ + uint16_t num_of_channels; /*!< ALAW/MULAW = 1, Mono = 1, Stereo = 2, etc. */ + uint32_t sample_rate; /*!< ALAW/MULAW = 8000, 8000, 44100, etc. */ + uint32_t byte_rate; /*!< ALAW/MULAW = 8000, ==SampleRate * NumChannels * BitsPerSample s/ 8 */ + uint16_t block_align; /*!< ALAW/MULAW = 1, ==NumChannels * BitsPerSample / 8 */ + uint16_t bits_per_sample; /*!< ALAW/MULAW = 8, 8 bits = 8, 16 bits = 16, etc. */ + uint16_t ext_size; /*!< ALAW/MULAW = 0, Size of the extension (0 or 22) */ } __attribute__((packed)) non_pcm_wav_fmt_chunk_t; /*!< The "fmt " subchunk describes the sound data's format */ -typedef struct { - char subchunk_id[4]; /*!< Contains the letters "data" */ - uint32_t subchunk_size; /*!< ==NumSamples * NumChannels * BitsPerSample / 8 */ +typedef struct +{ + char subchunk_id[4]; /*!< Contains the letters "data" */ + uint32_t subchunk_size; /*!< ==NumSamples * NumChannels * BitsPerSample / 8 */ } __attribute__((packed)) wav_data_chunk_t; /*!< The "data" subchunk contains the size of the data and the actual sound */ -typedef struct { +typedef struct +{ wav_descriptor_chunk_t descriptor_chunk; /*!< Canonical WAVE format starts with the RIFF header */ pcm_wav_fmt_chunk_t fmt_chunk; /*!< The "fmt " subchunk describes the sound data's format */ wav_data_chunk_t data_chunk; /*!< The "data" subchunk contains the size of the data and the actual sound */ } __attribute__((packed)) pcm_wav_header_t; -typedef struct { +typedef struct +{ wav_descriptor_chunk_t descriptor_chunk; /*!< Canonical WAVE format starts with the RIFF header */ non_pcm_wav_fmt_chunk_t fmt_chunk; /*!< The "fmt " subchunk describes the sound data's format */ wav_data_chunk_t data_chunk; /*!< The "data" subchunk contains the size of the data and the actual sound */ } __attribute__((packed)) non_pcm_wav_header_t; -#define WAVE_FORMAT_PCM 1 // PCM -#define WAVE_FORMAT_IEEE_FLOAT 3 // IEEE float -#define WAVE_FORMAT_ALAW 6 // 8-bit ITU-T G.711 A-law -#define WAVE_FORMAT_MULAW 7 // 8-bit ITU-T G.711 µ-law +#define WAVE_FORMAT_PCM 1 // PCM +#define WAVE_FORMAT_IEEE_FLOAT 3 // IEEE float +#define WAVE_FORMAT_ALAW 6 // 8-bit ITU-T G.711 A-law +#define WAVE_FORMAT_MULAW 7 // 8-bit ITU-T G.711 µ-law -#define PCM_WAV_HEADER_SIZE 44 +#define PCM_WAV_HEADER_SIZE 44 #define NON_PCM_WAV_HEADER_SIZE 46 /** * @brief Default header for PCM format WAV files * */ -#define PCM_WAV_HEADER_DEFAULT(wav_sample_size, wav_sample_bits, wav_sample_rate, wav_channel_num) \ - { \ - .descriptor_chunk = \ - {.chunk_id = {'R', 'I', 'F', 'F'}, .chunk_size = (wav_sample_size) + sizeof(pcm_wav_header_t) - 8, .chunk_format = {'W', 'A', 'V', 'E'}}, \ - .fmt_chunk = \ - {.subchunk_id = {'f', 'm', 't', ' '}, \ - .subchunk_size = 16, /* 16 for PCM */ \ - .audio_format = WAVE_FORMAT_PCM, /* 1 for PCM */ \ - .num_of_channels = (uint16_t)(wav_channel_num), \ - .sample_rate = (wav_sample_rate), \ - .byte_rate = (uint32_t)((wav_sample_bits) * (wav_sample_rate) * (wav_channel_num) / 8), \ - .block_align = (uint16_t)((wav_sample_bits) * (wav_channel_num) / 8), \ - .bits_per_sample = (uint16_t)(wav_sample_bits)}, \ - .data_chunk = { \ - .subchunk_id = {'d', 'a', 't', 'a'}, \ - .subchunk_size = (wav_sample_size) \ - } \ - } +#define PCM_WAV_HEADER_DEFAULT(wav_sample_size, wav_sample_bits, wav_sample_rate, wav_channel_num) \ + { \ + .descriptor_chunk = \ + {.chunk_id = {'R', 'I', 'F', 'F'}, .chunk_size = (wav_sample_size) + sizeof(pcm_wav_header_t) - 8, .chunk_format = {'W', 'A', 'V', 'E'}}, \ + .fmt_chunk = \ + {.subchunk_id = {'f', 'm', 't', ' '}, \ + .subchunk_size = 16, /* 16 for PCM */ \ + .audio_format = WAVE_FORMAT_PCM, /* 1 for PCM */ \ + .num_of_channels = (uint16_t)(wav_channel_num), \ + .sample_rate = (wav_sample_rate), \ + .byte_rate = (uint32_t)((wav_sample_bits) * (wav_sample_rate) * (wav_channel_num) / 8), \ + .block_align = (uint16_t)((wav_sample_bits) * (wav_channel_num) / 8), \ + .bits_per_sample = (uint16_t)(wav_sample_bits)}, \ + .data_chunk = { \ + .subchunk_id = {'d', 'a', 't', 'a'}, \ + .subchunk_size = (wav_sample_size) \ + } \ + } diff --git a/src/audio/codec/audio_codec_sw_vol.c b/src/audio/codec/audio_codec_sw_vol.c index 399f35c3..0d604152 100644 --- a/src/audio/codec/audio_codec_sw_vol.c +++ b/src/audio/codec/audio_codec_sw_vol.c @@ -3,41 +3,45 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#include "audio_codec_sw_vol.h" #include #include #include -#include "audio_codec_sw_vol.h" #define GAIN_0DB_SHIFT (15) -typedef struct { - audio_codec_vol_if_t base; +typedef struct +{ + audio_codec_vol_if_t base; esp_codec_dev_sample_info_t fs; - uint16_t gain; - bool is_open; - int cur; - int step; - int block_size; - int duration; + uint16_t gain; + bool is_open; + int cur; + int step; + int block_size; + int duration; } audio_vol_t; -static int _sw_vol_close(const audio_codec_vol_if_t *h) +static int _sw_vol_close(const audio_codec_vol_if_t* h) { - audio_vol_t *vol = (audio_vol_t *)h; - if (h) { + audio_vol_t* vol = (audio_vol_t*)h; + if (h) + { vol->is_open = false; return ESP_CODEC_DEV_OK; } return ESP_CODEC_DEV_INVALID_ARG; } -static int _sw_vol_open(const audio_codec_vol_if_t *h, esp_codec_dev_sample_info_t *fs, int duration) +static int _sw_vol_open(const audio_codec_vol_if_t* h, esp_codec_dev_sample_info_t* fs, int duration) { - audio_vol_t *vol = (audio_vol_t *)h; - if (vol == NULL || fs == NULL) { + audio_vol_t* vol = (audio_vol_t*)h; + if (vol == NULL || fs == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } - if (fs->bits_per_sample != 16) { + if (fs->bits_per_sample != 16) + { return ESP_CODEC_DEV_NOT_SUPPORT; } vol->fs = *fs; @@ -47,46 +51,63 @@ static int _sw_vol_open(const audio_codec_vol_if_t *h, esp_codec_dev_sample_info return ESP_CODEC_DEV_OK; } -static int _sw_vol_process(const audio_codec_vol_if_t *h, uint8_t *in, int len, - uint8_t *out, int out_len) +static int _sw_vol_process(const audio_codec_vol_if_t* h, uint8_t* in, int len, + uint8_t* out, int out_len) { - audio_vol_t *vol = (audio_vol_t *) h; - if (vol == NULL) { + audio_vol_t* vol = (audio_vol_t*)h; + if (vol == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } - if (vol->is_open == false) { + if (vol->is_open == false) + { return ESP_CODEC_DEV_WRONG_STATE; } int sample = len / vol->block_size; - if (vol->fs.bits_per_sample == 16) { - int16_t *v_in = (int16_t *) in; - int16_t *v_out = (int16_t *) out; - if (vol->cur == vol->gain) { - if (vol->gain == 0) { + if (vol->fs.bits_per_sample == 16) + { + int16_t* v_in = (int16_t*)in; + int16_t* v_out = (int16_t*)out; + if (vol->cur == vol->gain) + { + if (vol->gain == 0) + { memset(out, 0, len); return 0; - } else { - for (int i = 0; i < sample; i++) { - for (int j = 0; j < vol->fs.channel; j++) { + } + else + { + for (int i = 0; i < sample; i++) + { + for (int j = 0; j < vol->fs.channel; j++) + { *(v_out++) = ((*v_in++) * vol->cur) >> GAIN_0DB_SHIFT; } } return 0; } } - for (int i = 0; i < sample; i++) { - for (int j = 0; j < vol->fs.channel; j++) { + for (int i = 0; i < sample; i++) + { + for (int j = 0; j < vol->fs.channel; j++) + { *(v_out++) = ((*v_in++) * vol->cur) >> GAIN_0DB_SHIFT; } - if (vol->step) { + if (vol->step) + { vol->cur += vol->step; - if (vol->step > 0) { - if (vol->cur > vol->gain) { + if (vol->step > 0) + { + if (vol->cur > vol->gain) + { vol->cur = vol->gain; vol->step = 0; } - } else { - if (vol->cur < vol->gain) { + } + else + { + if (vol->cur < vol->gain) + { vol->cur = vol->gain; vol->step = 0; } @@ -97,37 +118,46 @@ static int _sw_vol_process(const audio_codec_vol_if_t *h, uint8_t *in, int len, return 0; } -static int _sw_vol_set(const audio_codec_vol_if_t *h, float db_value) +static int _sw_vol_set(const audio_codec_vol_if_t* h, float db_value) { - audio_vol_t *vol = (audio_vol_t *) h; - if (vol == NULL) { + audio_vol_t* vol = (audio_vol_t*)h; + if (vol == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } // Support set volume when not opened int gain; - if (db_value <= -96.0) { + if (db_value <= -96.0) + { gain = 0; - } else { - gain = (int) (exp(db_value / 20 * log(10)) * (1 << GAIN_0DB_SHIFT)); + } + else + { + gain = (int)(exp(db_value / 20 * log(10)) * (1 << GAIN_0DB_SHIFT)); } vol->gain = gain; - if (vol->is_open) { - float step = (float) (vol->gain - vol->cur) * 1000 / vol->duration / vol->fs.sample_rate; - vol->step = (int) step; - if (step == 0) { + if (vol->is_open) + { + float step = (float)(vol->gain - vol->cur) * 1000 / vol->duration / vol->fs.sample_rate; + vol->step = (int)step; + if (step == 0) + { vol->cur = vol->gain; } - } else { + } + else + { vol->step = 0; vol->cur = vol->gain; } return ESP_CODEC_DEV_OK; } -const audio_codec_vol_if_t *audio_codec_new_sw_vol(void) +const audio_codec_vol_if_t* audio_codec_new_sw_vol(void) { - audio_vol_t *vol = calloc(1, sizeof(audio_vol_t)); - if (vol == NULL) { + audio_vol_t* vol = calloc(1, sizeof(audio_vol_t)); + if (vol == NULL) + { return NULL; } vol->base.open = _sw_vol_open; diff --git a/src/audio/codec/audio_codec_sw_vol.h b/src/audio/codec/audio_codec_sw_vol.h index 6a5d0a96..107b7cee 100644 --- a/src/audio/codec/audio_codec_sw_vol.h +++ b/src/audio/codec/audio_codec_sw_vol.h @@ -9,16 +9,17 @@ #include "./interface/audio_codec_vol_if.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -/** - * @brief New software volume processor interface - * Notes: currently only support 16bits input - * @return NULL: Memory not enough - * -Others: Software volume interface handle - */ -const audio_codec_vol_if_t* audio_codec_new_sw_vol(void); + /** + * @brief New software volume processor interface + * Notes: currently only support 16bits input + * @return NULL: Memory not enough + * -Others: Software volume interface handle + */ + const audio_codec_vol_if_t* audio_codec_new_sw_vol(void); #ifdef __cplusplus } diff --git a/src/audio/codec/device/es8311/es8311.c b/src/audio/codec/device/es8311/es8311.c index bc5bf50a..64447403 100644 --- a/src/audio/codec/device/es8311/es8311.c +++ b/src/audio/codec/device/es8311/es8311.c @@ -3,225 +3,229 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include "../include/es8311_codec.h" +#include "../priv_include/es_common.h" #include "es8311_reg.h" #include "esp_log.h" -#include "../priv_include/es_common.h" +#include -#define TAG "ES8311" +#define TAG "ES8311" -typedef struct { - audio_codec_if_t base; +typedef struct +{ + audio_codec_if_t base; es8311_codec_cfg_t cfg; - bool is_open; - bool enabled; - float hw_gain; + bool is_open; + bool enabled; + float hw_gain; } audio_codec_es8311_t; /* * Clock coefficient structure */ -struct _coeff_div { - uint32_t mclk; /* mclk frequency */ - uint32_t rate; /* sample rate */ - uint8_t pre_div; /* the pre divider with range from 1 to 8 */ - uint8_t pre_multi; /* the pre multiplier with x1, x2, x4 and x8 selection */ - uint8_t adc_div; /* adcclk divider */ - uint8_t dac_div; /* dacclk divider */ - uint8_t fs_mode; /* double speed or single speed, =0, ss, =1, ds */ - uint8_t lrck_h; /* adclrck divider and daclrck divider */ - uint8_t lrck_l; - uint8_t bclk_div; /* sclk divider */ - uint8_t adc_osr; /* adc osr */ - uint8_t dac_osr; /* dac osr */ +struct _coeff_div +{ + uint32_t mclk; /* mclk frequency */ + uint32_t rate; /* sample rate */ + uint8_t pre_div; /* the pre divider with range from 1 to 8 */ + uint8_t pre_multi; /* the pre multiplier with x1, x2, x4 and x8 selection */ + uint8_t adc_div; /* adcclk divider */ + uint8_t dac_div; /* dacclk divider */ + uint8_t fs_mode; /* double speed or single speed, =0, ss, =1, ds */ + uint8_t lrck_h; /* adclrck divider and daclrck divider */ + uint8_t lrck_l; + uint8_t bclk_div; /* sclk divider */ + uint8_t adc_osr; /* adc osr */ + uint8_t dac_osr; /* dac osr */ }; /* codec hifi mclk clock divider coefficients */ static const struct _coeff_div coeff_div[] = { - // mclk rate pre_div mult adc_div dac_div fs_mode lrch lrcl bckdiv osr - /* 8k */ - {12288000, 8000, 0x06, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {18432000, 8000, 0x03, 0x02, 0x03, 0x03, 0x00, 0x05, 0xff, 0x18, 0x10, 0x20}, - {16384000, 8000, 0x08, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {8192000, 8000, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {6144000, 8000, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {4096000, 8000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {3072000, 8000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {2048000, 8000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {1536000, 8000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {1024000, 8000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + // mclk rate pre_div mult adc_div dac_div fs_mode lrch lrcl bckdiv osr + /* 8k */ + {12288000, 8000, 0x06, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {18432000, 8000, 0x03, 0x02, 0x03, 0x03, 0x00, 0x05, 0xff, 0x18, 0x10, 0x20}, + {16384000, 8000, 0x08, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {8192000, 8000, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {6144000, 8000, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {4096000, 8000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {3072000, 8000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {2048000, 8000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {1536000, 8000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {1024000, 8000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - /* 11.025k */ + /* 11.025k */ {11289600, 11025, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {5644800, 11025, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {2822400, 11025, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {1411200, 11025, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {5644800, 11025, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {2822400, 11025, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {1411200, 11025, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - /* 12k */ + /* 12k */ {12288000, 12000, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {6144000, 12000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {3072000, 12000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {1536000, 12000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {6144000, 12000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {3072000, 12000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {1536000, 12000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - /* 16k */ + /* 16k */ {12288000, 16000, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, {18432000, 16000, 0x03, 0x02, 0x03, 0x03, 0x00, 0x02, 0xff, 0x0c, 0x10, 0x20}, {16384000, 16000, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {8192000, 16000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {6144000, 16000, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {4096000, 16000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {3072000, 16000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {2048000, 16000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {1536000, 16000, 0x03, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - {1024000, 16000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {8192000, 16000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {6144000, 16000, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {4096000, 16000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {3072000, 16000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {2048000, 16000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {1536000, 16000, 0x03, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, + {1024000, 16000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20}, - /* 22.05k */ + /* 22.05k */ {11289600, 22050, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {5644800, 22050, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {2822400, 22050, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {1411200, 22050, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {5644800, 22050, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {2822400, 22050, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1411200, 22050, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - /* 24k */ + /* 24k */ {12288000, 24000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, {18432000, 24000, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {6144000, 24000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {3072000, 24000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {1536000, 24000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {6144000, 24000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {3072000, 24000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1536000, 24000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - /* 32k */ + /* 32k */ {12288000, 32000, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, {18432000, 32000, 0x03, 0x04, 0x03, 0x03, 0x00, 0x02, 0xff, 0x0c, 0x10, 0x10}, {16384000, 32000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {8192000, 32000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {6144000, 32000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {4096000, 32000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {3072000, 32000, 0x03, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {2048000, 32000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {1536000, 32000, 0x03, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10}, - {1024000, 32000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {8192000, 32000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {6144000, 32000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {4096000, 32000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {3072000, 32000, 0x03, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {2048000, 32000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1536000, 32000, 0x03, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10}, + {1024000, 32000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - /* 44.1k */ + /* 44.1k */ {11289600, 44100, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {5644800, 44100, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {2822400, 44100, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {1411200, 44100, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {5644800, 44100, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {2822400, 44100, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1411200, 44100, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - /* 48k */ + /* 48k */ {12288000, 48000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, {18432000, 48000, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {6144000, 48000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {3072000, 48000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {1536000, 48000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {6144000, 48000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {3072000, 48000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1536000, 48000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - /* 64k */ + /* 64k */ {12288000, 64000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, {18432000, 64000, 0x03, 0x04, 0x03, 0x03, 0x01, 0x01, 0x7f, 0x06, 0x10, 0x10}, {16384000, 64000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {8192000, 64000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {6144000, 64000, 0x01, 0x04, 0x03, 0x03, 0x01, 0x01, 0x7f, 0x06, 0x10, 0x10}, - {4096000, 64000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {3072000, 64000, 0x01, 0x08, 0x03, 0x03, 0x01, 0x01, 0x7f, 0x06, 0x10, 0x10}, - {2048000, 64000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {1536000, 64000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0xbf, 0x03, 0x18, 0x18}, - {1024000, 64000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10}, + {8192000, 64000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {6144000, 64000, 0x01, 0x04, 0x03, 0x03, 0x01, 0x01, 0x7f, 0x06, 0x10, 0x10}, + {4096000, 64000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {3072000, 64000, 0x01, 0x08, 0x03, 0x03, 0x01, 0x01, 0x7f, 0x06, 0x10, 0x10}, + {2048000, 64000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1536000, 64000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0xbf, 0x03, 0x18, 0x18}, + {1024000, 64000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10}, - /* 88.2k */ + /* 88.2k */ {11289600, 88200, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {5644800, 88200, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {2822400, 88200, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {1411200, 88200, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10}, + {5644800, 88200, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {2822400, 88200, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1411200, 88200, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10}, - /* 96k */ + /* 96k */ {24576000, 96000, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, {12288000, 96000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, {18432000, 96000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {6144000, 96000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {3072000, 96000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, - {1536000, 96000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10}, + {6144000, 96000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {3072000, 96000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1536000, 96000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10}, }; static const esp_codec_dev_vol_range_t vol_range = { .min_vol = - { - .vol = 0x0, - .db_value = -95.5, - }, + { + .vol = 0x0, + .db_value = -95.5, + }, .max_vol = - { - .vol = 0xFF, - .db_value = 32.0, - }, + { + .vol = 0xFF, + .db_value = 32.0, + }, }; -static int es8311_write_reg(audio_codec_es8311_t *codec, int reg, int value) +static int es8311_write_reg(audio_codec_es8311_t* codec, int reg, int value) { return codec->cfg.ctrl_if->write_reg(codec->cfg.ctrl_if, reg, 1, &value, 1); } -static int es8311_read_reg(audio_codec_es8311_t *codec, int reg, int *value) +static int es8311_read_reg(audio_codec_es8311_t* codec, int reg, int* value) { *value = 0; return codec->cfg.ctrl_if->read_reg(codec->cfg.ctrl_if, reg, 1, value, 1); } -static int es8311_config_fmt(audio_codec_es8311_t *codec, es_i2s_fmt_t fmt) +static int es8311_config_fmt(audio_codec_es8311_t* codec, es_i2s_fmt_t fmt) { int ret = ESP_CODEC_DEV_OK; int adc_iface = 0, dac_iface = 0; ret = es8311_read_reg(codec, ES8311_SDPIN_REG09, &dac_iface); ret |= es8311_read_reg(codec, ES8311_SDPOUT_REG0A, &adc_iface); - switch (fmt) { - case ES_I2S_NORMAL: - ESP_LOGD(TAG, "ES8311 in I2S Format"); - dac_iface &= 0xFC; - adc_iface &= 0xFC; - break; - case ES_I2S_LEFT: - case ES_I2S_RIGHT: - ESP_LOGD(TAG, "ES8311 in LJ Format"); - adc_iface &= 0xFC; - dac_iface &= 0xFC; - adc_iface |= 0x01; - dac_iface |= 0x01; - break; - case ES_I2S_DSP: - ESP_LOGD(TAG, "ES8311 in DSP-A Format"); - adc_iface &= 0xDC; - dac_iface &= 0xDC; - adc_iface |= 0x03; - dac_iface |= 0x03; - break; - default: - dac_iface &= 0xFC; - adc_iface &= 0xFC; - break; + switch (fmt) + { + case ES_I2S_NORMAL: + ESP_LOGD(TAG, "ES8311 in I2S Format"); + dac_iface &= 0xFC; + adc_iface &= 0xFC; + break; + case ES_I2S_LEFT: + case ES_I2S_RIGHT: + ESP_LOGD(TAG, "ES8311 in LJ Format"); + adc_iface &= 0xFC; + dac_iface &= 0xFC; + adc_iface |= 0x01; + dac_iface |= 0x01; + break; + case ES_I2S_DSP: + ESP_LOGD(TAG, "ES8311 in DSP-A Format"); + adc_iface &= 0xDC; + dac_iface &= 0xDC; + adc_iface |= 0x03; + dac_iface |= 0x03; + break; + default: + dac_iface &= 0xFC; + adc_iface &= 0xFC; + break; } ret |= es8311_write_reg(codec, ES8311_SDPIN_REG09, dac_iface); ret |= es8311_write_reg(codec, ES8311_SDPOUT_REG0A, adc_iface); return ret; } -static int es8311_set_bits_per_sample(audio_codec_es8311_t *codec, int bits) +static int es8311_set_bits_per_sample(audio_codec_es8311_t* codec, int bits) { int ret = ESP_CODEC_DEV_OK; int adc_iface = 0, dac_iface = 0; ret |= es8311_read_reg(codec, ES8311_SDPIN_REG09, &dac_iface); ret |= es8311_read_reg(codec, ES8311_SDPOUT_REG0A, &adc_iface); - switch (bits) { - case 16: - default: - dac_iface |= 0x0c; - adc_iface |= 0x0c; - break; - case 24: - dac_iface &= ~0x1c; - adc_iface &= ~0x1c; - break; - case 32: - dac_iface |= 0x10; - adc_iface |= 0x10; - break; + switch (bits) + { + case 16: + default: + dac_iface |= 0x0c; + adc_iface |= 0x0c; + break; + case 24: + dac_iface &= ~0x1c; + adc_iface &= ~0x1c; + break; + case 32: + dac_iface |= 0x10; + adc_iface |= 0x10; + break; } ret |= es8311_write_reg(codec, ES8311_SDPIN_REG09, dac_iface); ret |= es8311_write_reg(codec, ES8311_SDPOUT_REG0A, adc_iface); @@ -231,14 +235,15 @@ static int es8311_set_bits_per_sample(audio_codec_es8311_t *codec, int bits) static int get_coeff(uint32_t mclk, uint32_t rate) { - for (int i = 0; i < (sizeof(coeff_div) / sizeof(coeff_div[0])); i++) { + for (int i = 0; i < (sizeof(coeff_div) / sizeof(coeff_div[0])); i++) + { if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) return i; } return ESP_CODEC_DEV_NOT_FOUND; } -static int es8311_suspend(audio_codec_es8311_t *codec) +static int es8311_suspend(audio_codec_es8311_t* codec) { int ret = es8311_write_reg(codec, ES8311_DAC_REG32, 0x00); ret |= es8311_write_reg(codec, ES8311_ADC_REG17, 0x00); @@ -258,33 +263,43 @@ static int es8311_suspend(audio_codec_es8311_t *codec) return ret; } -static int es8311_start(audio_codec_es8311_t *codec) +static int es8311_start(audio_codec_es8311_t* codec) { int ret = ESP_CODEC_DEV_OK; int adc_iface = 0, dac_iface = 0; int regv = 0x80; - if (codec->cfg.master_mode) { + if (codec->cfg.master_mode) + { regv |= 0x40; - } else { + } + else + { regv &= 0xBF; } ret |= es8311_write_reg(codec, ES8311_RESET_REG00, regv); regv = 0x3F; - if (codec->cfg.use_mclk) { + if (codec->cfg.use_mclk) + { regv &= 0x7F; - } else { + } + else + { regv |= 0x80; } - if (codec->cfg.invert_mclk) { + if (codec->cfg.invert_mclk) + { regv |= 0x40; - } else { + } + else + { regv &= ~(0x40); } ret |= es8311_write_reg(codec, ES8311_CLK_MANAGER_REG01, regv); ret = es8311_read_reg(codec, ES8311_SDPIN_REG09, &dac_iface); ret |= es8311_read_reg(codec, ES8311_SDPOUT_REG0A, &adc_iface); - if (ret != ESP_CODEC_DEV_OK) { + if (ret != ESP_CODEC_DEV_OK) + { return ret; } dac_iface &= 0xBF; @@ -292,14 +307,17 @@ static int es8311_start(audio_codec_es8311_t *codec) adc_iface |= BITS(6); dac_iface |= BITS(6); int codec_mode = codec->cfg.codec_mode; - if (codec_mode == ESP_CODEC_DEV_WORK_MODE_LINE) { + if (codec_mode == ESP_CODEC_DEV_WORK_MODE_LINE) + { ESP_LOGE(TAG, "Codec not support LINE mode"); return ESP_CODEC_DEV_NOT_SUPPORT; } - if (codec_mode == ESP_CODEC_DEV_WORK_MODE_ADC || codec_mode == ESP_CODEC_DEV_WORK_MODE_BOTH) { + if (codec_mode == ESP_CODEC_DEV_WORK_MODE_ADC || codec_mode == ESP_CODEC_DEV_WORK_MODE_BOTH) + { adc_iface &= ~(BITS(6)); } - if (codec_mode == ESP_CODEC_DEV_WORK_MODE_DAC || codec_mode == ESP_CODEC_DEV_WORK_MODE_BOTH) { + if (codec_mode == ESP_CODEC_DEV_WORK_MODE_DAC || codec_mode == ESP_CODEC_DEV_WORK_MODE_BOTH) + { dac_iface &= ~(BITS(6)); } @@ -314,9 +332,12 @@ static int es8311_start(audio_codec_es8311_t *codec) // pdm dmic enable or disable regv = 0; ret |= es8311_read_reg(codec, ES8311_SYSTEM_REG14, ®v); - if (codec->cfg.digital_mic) { + if (codec->cfg.digital_mic) + { regv |= 0x40; - } else { + } + else + { regv &= ~(0x40); } ret |= es8311_write_reg(codec, ES8311_SYSTEM_REG14, regv); @@ -327,91 +348,119 @@ static int es8311_start(audio_codec_es8311_t *codec) return ret; } -static int es8311_set_mute(const audio_codec_if_t *h, bool mute) +static int es8311_set_mute(const audio_codec_if_t* h, bool mute) { - audio_codec_es8311_t *codec = (audio_codec_es8311_t *) h; - if (codec == NULL || codec->is_open == false) { + audio_codec_es8311_t* codec = (audio_codec_es8311_t*)h; + if (codec == NULL || codec->is_open == false) + { return ESP_CODEC_DEV_INVALID_ARG; } int regv; int ret = es8311_read_reg(codec, ES8311_DAC_REG31, ®v); regv &= 0x9f; - if (mute) { + if (mute) + { es8311_write_reg(codec, ES8311_DAC_REG31, regv | 0x60); - } else { + } + else + { es8311_write_reg(codec, ES8311_DAC_REG31, regv); } return ret; } -static int es8311_set_vol(const audio_codec_if_t *h, float db_value) +static int es8311_set_vol(const audio_codec_if_t* h, float db_value) { - audio_codec_es8311_t *codec = (audio_codec_es8311_t *) h; - if (codec == NULL) { + audio_codec_es8311_t* codec = (audio_codec_es8311_t*)h; + if (codec == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } - if (codec->is_open == false) { + if (codec->is_open == false) + { return ESP_CODEC_DEV_WRONG_STATE; } db_value -= codec->hw_gain; int reg = esp_codec_dev_vol_calc_reg(&vol_range, db_value); - ESP_LOGD(TAG, "Set volume reg:%x db:%d", reg, (int) db_value); - return es8311_write_reg(codec, ES8311_DAC_REG32, (uint8_t) reg); + ESP_LOGD(TAG, "Set volume reg:%x db:%d", reg, (int)db_value); + return es8311_write_reg(codec, ES8311_DAC_REG32, (uint8_t)reg); } -static int es8311_set_mic_gain(const audio_codec_if_t *h, float db) +static int es8311_set_mic_gain(const audio_codec_if_t* h, float db) { - audio_codec_es8311_t *codec = (audio_codec_es8311_t *) h; - if (codec == NULL) { + audio_codec_es8311_t* codec = (audio_codec_es8311_t*)h; + if (codec == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } - if (codec->is_open == false) { + if (codec->is_open == false) + { return ESP_CODEC_DEV_WRONG_STATE; } es8311_mic_gain_t gain_db = ES8311_MIC_GAIN_0DB; - if (db < 6) { - } else if (db < 12) { + if (db < 6) + { + } + else if (db < 12) + { gain_db = ES8311_MIC_GAIN_6DB; - } else if (db < 18) { + } + else if (db < 18) + { gain_db = ES8311_MIC_GAIN_12DB; - } else if (db < 24) { + } + else if (db < 24) + { gain_db = ES8311_MIC_GAIN_18DB; - } else if (db < 30) { + } + else if (db < 30) + { gain_db = ES8311_MIC_GAIN_24DB; - } else if (db < 36) { + } + else if (db < 36) + { gain_db = ES8311_MIC_GAIN_30DB; - } else if (db < 42) { + } + else if (db < 42) + { gain_db = ES8311_MIC_GAIN_36DB; - } else { + } + else + { gain_db = ES8311_MIC_GAIN_42DB; } int ret = es8311_write_reg(codec, ES8311_ADC_REG16, gain_db); // MIC gain scale return ret == 0 ? ESP_CODEC_DEV_OK : ESP_CODEC_DEV_WRITE_FAIL; } -static void es8311_pa_power(audio_codec_es8311_t *codec, es_pa_setting_t pa_setting) +static void es8311_pa_power(audio_codec_es8311_t* codec, es_pa_setting_t pa_setting) { int16_t pa_pin = codec->cfg.pa_pin; - if (pa_pin == -1 || codec->cfg.gpio_if == NULL) { + if (pa_pin == -1 || codec->cfg.gpio_if == NULL) + { return; } - if (pa_setting & ES_PA_SETUP) { + if (pa_setting & ES_PA_SETUP) + { codec->cfg.gpio_if->setup(pa_pin, AUDIO_GPIO_DIR_OUT, AUDIO_GPIO_MODE_FLOAT); - } - if (pa_setting & ES_PA_ENABLE) { + } + if (pa_setting & ES_PA_ENABLE) + { codec->cfg.gpio_if->set(pa_pin, codec->cfg.pa_reverted ? false : true); } - if (pa_setting & ES_PA_DISABLE) { + if (pa_setting & ES_PA_DISABLE) + { codec->cfg.gpio_if->set(pa_pin, codec->cfg.pa_reverted ? true : false); } } -static int es8311_config_sample(audio_codec_es8311_t *codec, int sample_rate) +static int es8311_config_sample(audio_codec_es8311_t* codec, int sample_rate) { int datmp, regv; int mclk_fre = sample_rate * codec->cfg.mclk_div; int coeff = get_coeff(mclk_fre, sample_rate); - if (coeff < 0) { + if (coeff < 0) + { ESP_LOGE(TAG, "Unable to configure sample rate %dHz with %dHz MCLK", sample_rate, mclk_fre); return ESP_CODEC_DEV_NOT_SUPPORT; } @@ -420,23 +469,25 @@ static int es8311_config_sample(audio_codec_es8311_t *codec, int sample_rate) regv &= 0x7; regv |= (coeff_div[coeff].pre_div - 1) << 5; datmp = 0; - switch (coeff_div[coeff].pre_multi) { - case 1: - datmp = 0; - break; - case 2: - datmp = 1; - break; - case 4: - datmp = 2; - break; - case 8: - datmp = 3; - break; - default: - break; + switch (coeff_div[coeff].pre_multi) + { + case 1: + datmp = 0; + break; + case 2: + datmp = 1; + break; + case 4: + datmp = 2; + break; + case 8: + datmp = 3; + break; + default: + break; } - if (codec->cfg.use_mclk == false) { + if (codec->cfg.use_mclk == false) + { datmp = 3; } regv |= (datmp) << 3; @@ -469,24 +520,29 @@ static int es8311_config_sample(audio_codec_es8311_t *codec, int sample_rate) ret = es8311_read_reg(codec, ES8311_CLK_MANAGER_REG06, ®v); regv &= 0xE0; - if (coeff_div[coeff].bclk_div < 19) { + if (coeff_div[coeff].bclk_div < 19) + { regv |= (coeff_div[coeff].bclk_div - 1) << 0; - } else { + } + else + { regv |= (coeff_div[coeff].bclk_div) << 0; } ret |= es8311_write_reg(codec, ES8311_CLK_MANAGER_REG06, regv); return ret == 0 ? ESP_CODEC_DEV_OK : ESP_CODEC_DEV_WRITE_FAIL; } -static int es8311_open(const audio_codec_if_t *h, void *cfg, int cfg_size) +static int es8311_open(const audio_codec_if_t* h, void* cfg, int cfg_size) { - audio_codec_es8311_t *codec = (audio_codec_es8311_t *) h; - es8311_codec_cfg_t *codec_cfg = (es8311_codec_cfg_t *) cfg; - if (codec == NULL || codec_cfg == NULL || codec_cfg->ctrl_if == NULL || cfg_size != sizeof(es8311_codec_cfg_t)) { + audio_codec_es8311_t* codec = (audio_codec_es8311_t*)h; + es8311_codec_cfg_t* codec_cfg = (es8311_codec_cfg_t*)cfg; + if (codec == NULL || codec_cfg == NULL || codec_cfg->ctrl_if == NULL || cfg_size != sizeof(es8311_codec_cfg_t)) + { return ESP_CODEC_DEV_INVALID_ARG; } memcpy(&codec->cfg, cfg, sizeof(es8311_codec_cfg_t)); - if (codec->cfg.mclk_div == 0) { + if (codec->cfg.mclk_div == 0) + { codec->cfg.mclk_div = MCLK_DEFAULT_DIV; } int regv; @@ -510,10 +566,13 @@ static int es8311_open(const audio_codec_if_t *h, void *cfg, int cfg_size) ret |= es8311_write_reg(codec, ES8311_RESET_REG00, 0x80); ret = es8311_read_reg(codec, ES8311_RESET_REG00, ®v); - if (codec_cfg->master_mode) { + if (codec_cfg->master_mode) + { ESP_LOGI(TAG, "Work in Master mode"); regv |= 0x40; - } else { + } + else + { ESP_LOGI(TAG, "Work in Slave mode"); regv &= 0xBF; } @@ -521,23 +580,32 @@ static int es8311_open(const audio_codec_if_t *h, void *cfg, int cfg_size) // Select clock source for internal mclk regv = 0x3F; - if (codec_cfg->use_mclk) { + if (codec_cfg->use_mclk) + { regv &= 0x7F; - } else { + } + else + { regv |= 0x80; } // MCLK inverted or not - if (codec_cfg->invert_mclk) { + if (codec_cfg->invert_mclk) + { regv |= 0x40; - } else { + } + else + { regv &= ~(0x40); } ret |= es8311_write_reg(codec, ES8311_CLK_MANAGER_REG01, regv); // SCLK inverted or not ret |= es8311_read_reg(codec, ES8311_CLK_MANAGER_REG06, ®v); - if (codec_cfg->invert_sclk) { + if (codec_cfg->invert_sclk) + { regv |= 0x20; - } else { + } + else + { regv &= ~(0x20); } ret |= es8311_write_reg(codec, ES8311_CLK_MANAGER_REG06, regv); @@ -545,13 +613,17 @@ static int es8311_open(const audio_codec_if_t *h, void *cfg, int cfg_size) ret |= es8311_write_reg(codec, ES8311_SYSTEM_REG13, 0x10); ret |= es8311_write_reg(codec, ES8311_ADC_REG1B, 0x0A); ret |= es8311_write_reg(codec, ES8311_ADC_REG1C, 0x6A); - if (codec_cfg->no_dac_ref == false) { + if (codec_cfg->no_dac_ref == false) + { /* set internal reference signal (ADCL + DACR) */ ret |= es8311_write_reg(codec, ES8311_GPIO_REG44, 0x58); - } else { + } + else + { ret |= es8311_write_reg(codec, ES8311_GPIO_REG44, 0x08); } - if (ret != 0) { + if (ret != 0) + { return ESP_CODEC_DEV_WRITE_FAIL; } es8311_pa_power(codec, ES_PA_SETUP | ES_PA_ENABLE); @@ -559,13 +631,15 @@ static int es8311_open(const audio_codec_if_t *h, void *cfg, int cfg_size) return ESP_CODEC_DEV_OK; } -static int es8311_close(const audio_codec_if_t *h) +static int es8311_close(const audio_codec_if_t* h) { - audio_codec_es8311_t *codec = (audio_codec_es8311_t *) h; - if (codec == NULL) { + audio_codec_es8311_t* codec = (audio_codec_es8311_t*)h; + if (codec == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } - if (codec->is_open) { + if (codec->is_open) + { es8311_suspend(codec); es8311_pa_power(codec, ES_PA_DISABLE); codec->is_open = false; @@ -573,10 +647,11 @@ static int es8311_close(const audio_codec_if_t *h) return ESP_CODEC_DEV_OK; } -static int es8311_set_fs(const audio_codec_if_t *h, esp_codec_dev_sample_info_t *fs) +static int es8311_set_fs(const audio_codec_if_t* h, esp_codec_dev_sample_info_t* fs) { - audio_codec_es8311_t *codec = (audio_codec_es8311_t *) h; - if (codec == NULL || codec->is_open == false) { + audio_codec_es8311_t* codec = (audio_codec_es8311_t*)h; + if (codec == NULL || codec->is_open == false) + { return ESP_CODEC_DEV_INVALID_ARG; } es8311_set_bits_per_sample(codec, fs->bits_per_sample); @@ -585,85 +660,102 @@ static int es8311_set_fs(const audio_codec_if_t *h, esp_codec_dev_sample_info_t return ESP_CODEC_DEV_OK; } -static int es8311_enable(const audio_codec_if_t *h, bool enable) +static int es8311_enable(const audio_codec_if_t* h, bool enable) { int ret = ESP_CODEC_DEV_OK; - audio_codec_es8311_t *codec = (audio_codec_es8311_t *) h; - if (codec == NULL) { + audio_codec_es8311_t* codec = (audio_codec_es8311_t*)h; + if (codec == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } - if (codec->is_open == false) { + if (codec->is_open == false) + { return ESP_CODEC_DEV_WRONG_STATE; } - if (enable == codec->enabled) { + if (enable == codec->enabled) + { return ESP_CODEC_DEV_OK; } - if (enable) { + if (enable) + { ret = es8311_start(codec); es8311_pa_power(codec, ES_PA_ENABLE); - } else { + } + else + { es8311_pa_power(codec, ES_PA_DISABLE); ret = es8311_suspend(codec); } - if (ret == ESP_CODEC_DEV_OK) { + if (ret == ESP_CODEC_DEV_OK) + { codec->enabled = enable; ESP_LOGD(TAG, "Codec is %s", enable ? "enabled" : "disabled"); } return ret; } -static int es8311_set_reg(const audio_codec_if_t *h, int reg, int value) +static int es8311_set_reg(const audio_codec_if_t* h, int reg, int value) { - audio_codec_es8311_t *codec = (audio_codec_es8311_t *) h; - if (codec == NULL) { + audio_codec_es8311_t* codec = (audio_codec_es8311_t*)h; + if (codec == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } - if (codec->is_open == false) { + if (codec->is_open == false) + { return ESP_CODEC_DEV_WRONG_STATE; } return es8311_write_reg(codec, reg, value); } -static int es8311_get_reg(const audio_codec_if_t *h, int reg, int *value) +static int es8311_get_reg(const audio_codec_if_t* h, int reg, int* value) { - audio_codec_es8311_t *codec = (audio_codec_es8311_t *) h; - if (codec == NULL) { + audio_codec_es8311_t* codec = (audio_codec_es8311_t*)h; + if (codec == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } - if (codec->is_open == false) { + if (codec->is_open == false) + { return ESP_CODEC_DEV_WRONG_STATE; } return es8311_read_reg(codec, reg, value); } -static void es8311_dump(const audio_codec_if_t *h) +static void es8311_dump(const audio_codec_if_t* h) { - audio_codec_es8311_t *codec = (audio_codec_es8311_t *) h; - if (codec == NULL || codec->is_open == false) { + audio_codec_es8311_t* codec = (audio_codec_es8311_t*)h; + if (codec == NULL || codec->is_open == false) + { return; } - for (int i = 0; i < ES8311_MAX_REGISTER; i++) { + for (int i = 0; i < ES8311_MAX_REGISTER; i++) + { int value = 0; int ret = es8311_read_reg(codec, i, &value); - if (ret != ESP_CODEC_DEV_OK) { + if (ret != ESP_CODEC_DEV_OK) + { break; } ESP_LOGI(TAG, "%02x: %02x", i, value); } } -const audio_codec_if_t *es8311_codec_new(es8311_codec_cfg_t *codec_cfg) +const audio_codec_if_t* es8311_codec_new(es8311_codec_cfg_t* codec_cfg) { - if (codec_cfg == NULL || codec_cfg->ctrl_if == NULL) { + if (codec_cfg == NULL || codec_cfg->ctrl_if == NULL) + { ESP_LOGE(TAG, "Wrong codec config"); return NULL; } - if (codec_cfg->ctrl_if->is_open(codec_cfg->ctrl_if) == false) { + if (codec_cfg->ctrl_if->is_open(codec_cfg->ctrl_if) == false) + { ESP_LOGE(TAG, "Control interface not open yet"); return NULL; } - audio_codec_es8311_t *codec = (audio_codec_es8311_t *) calloc(1, sizeof(audio_codec_es8311_t)); - if (codec == NULL) { + audio_codec_es8311_t* codec = (audio_codec_es8311_t*)calloc(1, sizeof(audio_codec_es8311_t)); + if (codec == NULL) + { CODEC_MEM_CHECK(codec); return NULL; } @@ -678,15 +770,18 @@ const audio_codec_if_t *es8311_codec_new(es8311_codec_cfg_t *codec_cfg) codec->base.dump_reg = es8311_dump; codec->base.close = es8311_close; codec->hw_gain = esp_codec_dev_col_calc_hw_gain(&codec_cfg->hw_gain); - do { + do + { int ret = codec->base.open(&codec->base, codec_cfg, sizeof(es8311_codec_cfg_t)); - if (ret != 0) { + if (ret != 0) + { ESP_LOGE(TAG, "Open fail"); break; } return &codec->base; } while (0); - if (codec) { + if (codec) + { free(codec); } return NULL; diff --git a/src/audio/codec/device/es8311/es8311_reg.h b/src/audio/codec/device/es8311/es8311_reg.h index a45f3131..b66fd71c 100644 --- a/src/audio/codec/device/es8311/es8311_reg.h +++ b/src/audio/codec/device/es8311/es8311_reg.h @@ -7,13 +7,14 @@ #define _ES8311_REG_H_ #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* * ES8311_REGISTER NAME_REG_REGISTER ADDRESS */ -#define ES8311_RESET_REG00 0x00 /*reset digital,csm,clock manager etc.*/ +#define ES8311_RESET_REG00 0x00 /*reset digital,csm,clock manager etc.*/ /* * Clock Scheme Register definition @@ -29,68 +30,69 @@ extern "C" { /* * SDP */ -#define ES8311_SDPIN_REG09 0x09 /* dac serial digital port */ -#define ES8311_SDPOUT_REG0A 0x0A /* adc serial digital port */ +#define ES8311_SDPIN_REG09 0x09 /* dac serial digital port */ +#define ES8311_SDPOUT_REG0A 0x0A /* adc serial digital port */ /* * SYSTEM */ -#define ES8311_SYSTEM_REG0B 0x0B /* system */ -#define ES8311_SYSTEM_REG0C 0x0C /* system */ -#define ES8311_SYSTEM_REG0D 0x0D /* system, power up/down */ -#define ES8311_SYSTEM_REG0E 0x0E /* system, power up/down */ -#define ES8311_SYSTEM_REG0F 0x0F /* system, low power */ -#define ES8311_SYSTEM_REG10 0x10 /* system */ -#define ES8311_SYSTEM_REG11 0x11 /* system */ -#define ES8311_SYSTEM_REG12 0x12 /* system, Enable DAC */ -#define ES8311_SYSTEM_REG13 0x13 /* system */ -#define ES8311_SYSTEM_REG14 0x14 /* system, select DMIC, select analog pga gain */ +#define ES8311_SYSTEM_REG0B 0x0B /* system */ +#define ES8311_SYSTEM_REG0C 0x0C /* system */ +#define ES8311_SYSTEM_REG0D 0x0D /* system, power up/down */ +#define ES8311_SYSTEM_REG0E 0x0E /* system, power up/down */ +#define ES8311_SYSTEM_REG0F 0x0F /* system, low power */ +#define ES8311_SYSTEM_REG10 0x10 /* system */ +#define ES8311_SYSTEM_REG11 0x11 /* system */ +#define ES8311_SYSTEM_REG12 0x12 /* system, Enable DAC */ +#define ES8311_SYSTEM_REG13 0x13 /* system */ +#define ES8311_SYSTEM_REG14 0x14 /* system, select DMIC, select analog pga gain */ /* * ADC */ -#define ES8311_ADC_REG15 0x15 /* ADC, adc ramp rate, dmic sense */ -#define ES8311_ADC_REG16 0x16 /* ADC */ -#define ES8311_ADC_REG17 0x17 /* ADC, volume */ -#define ES8311_ADC_REG18 0x18 /* ADC, alc enable and winsize */ -#define ES8311_ADC_REG19 0x19 /* ADC, alc maxlevel */ -#define ES8311_ADC_REG1A 0x1A /* ADC, alc automute */ -#define ES8311_ADC_REG1B 0x1B /* ADC, alc automute, adc hpf s1 */ -#define ES8311_ADC_REG1C 0x1C /* ADC, equalizer, hpf s2 */ +#define ES8311_ADC_REG15 0x15 /* ADC, adc ramp rate, dmic sense */ +#define ES8311_ADC_REG16 0x16 /* ADC */ +#define ES8311_ADC_REG17 0x17 /* ADC, volume */ +#define ES8311_ADC_REG18 0x18 /* ADC, alc enable and winsize */ +#define ES8311_ADC_REG19 0x19 /* ADC, alc maxlevel */ +#define ES8311_ADC_REG1A 0x1A /* ADC, alc automute */ +#define ES8311_ADC_REG1B 0x1B /* ADC, alc automute, adc hpf s1 */ +#define ES8311_ADC_REG1C 0x1C /* ADC, equalizer, hpf s2 */ /* * DAC */ -#define ES8311_DAC_REG31 0x31 /* DAC, mute */ -#define ES8311_DAC_REG32 0x32 /* DAC, volume */ -#define ES8311_DAC_REG33 0x33 /* DAC, offset */ -#define ES8311_DAC_REG34 0x34 /* DAC, drc enable, drc winsize */ -#define ES8311_DAC_REG35 0x35 /* DAC, drc maxlevel, minilevel */ -#define ES8311_DAC_REG37 0x37 /* DAC, ramprate */ +#define ES8311_DAC_REG31 0x31 /* DAC, mute */ +#define ES8311_DAC_REG32 0x32 /* DAC, volume */ +#define ES8311_DAC_REG33 0x33 /* DAC, offset */ +#define ES8311_DAC_REG34 0x34 /* DAC, drc enable, drc winsize */ +#define ES8311_DAC_REG35 0x35 /* DAC, drc maxlevel, minilevel */ +#define ES8311_DAC_REG37 0x37 /* DAC, ramprate */ /* *GPIO */ -#define ES8311_GPIO_REG44 0x44 /* GPIO, dac2adc for test */ -#define ES8311_GP_REG45 0x45 /* GP CONTROL */ +#define ES8311_GPIO_REG44 0x44 /* GPIO, dac2adc for test */ +#define ES8311_GP_REG45 0x45 /* GP CONTROL */ /* * CHIP */ -#define ES8311_CHD1_REGFD 0xFD /* CHIP ID1 */ -#define ES8311_CHD2_REGFE 0xFE /* CHIP ID2 */ -#define ES8311_CHVER_REGFF 0xFF /* VERSION */ -#define ES8311_CHD1_REGFD 0xFD /* CHIP ID1 */ +#define ES8311_CHD1_REGFD 0xFD /* CHIP ID1 */ +#define ES8311_CHD2_REGFE 0xFE /* CHIP ID2 */ +#define ES8311_CHVER_REGFF 0xFF /* VERSION */ +#define ES8311_CHD1_REGFD 0xFD /* CHIP ID1 */ -#define ES8311_MAX_REGISTER 0xFF +#define ES8311_MAX_REGISTER 0xFF -typedef enum { - ES8311_MIC_GAIN_MIN = -1, - ES8311_MIC_GAIN_0DB, - ES8311_MIC_GAIN_6DB, - ES8311_MIC_GAIN_12DB, - ES8311_MIC_GAIN_18DB, - ES8311_MIC_GAIN_24DB, - ES8311_MIC_GAIN_30DB, - ES8311_MIC_GAIN_36DB, - ES8311_MIC_GAIN_42DB, - ES8311_MIC_GAIN_MAX -} es8311_mic_gain_t; + typedef enum + { + ES8311_MIC_GAIN_MIN = -1, + ES8311_MIC_GAIN_0DB, + ES8311_MIC_GAIN_6DB, + ES8311_MIC_GAIN_12DB, + ES8311_MIC_GAIN_18DB, + ES8311_MIC_GAIN_24DB, + ES8311_MIC_GAIN_30DB, + ES8311_MIC_GAIN_36DB, + ES8311_MIC_GAIN_42DB, + ES8311_MIC_GAIN_MAX + } es8311_mic_gain_t; #ifdef __cplusplus } diff --git a/src/audio/codec/device/include/es8311_codec.h b/src/audio/codec/device/include/es8311_codec.h index 6bdab65a..735f03e1 100644 --- a/src/audio/codec/device/include/es8311_codec.h +++ b/src/audio/codec/device/include/es8311_codec.h @@ -6,46 +6,48 @@ #ifndef _ES8311_CODEC_H_ #define _ES8311_CODEC_H_ -#include "../../interface/audio_codec_if.h" +#include "../../include/esp_codec_dev_vol.h" #include "../../interface/audio_codec_ctrl_if.h" #include "../../interface/audio_codec_gpio_if.h" -#include "../../include/esp_codec_dev_vol.h" +#include "../../interface/audio_codec_if.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #define ES8311_CODEC_DEFAULT_ADDR ((uint8_t)(0x30)) -/** - * @brief ES8311 codec configuration - */ -typedef struct { - const audio_codec_ctrl_if_t *ctrl_if; /*!< Codec Control interface */ - const audio_codec_gpio_if_t *gpio_if; /*!< Codec GPIO interface */ - esp_codec_dec_work_mode_t codec_mode; /*!< Codec work mode: ADC or DAC */ - int16_t pa_pin; /*!< PA chip power pin */ - bool pa_reverted; /*!< false: enable PA when pin set to 1, true: enable PA when pin set to 0 */ - bool master_mode; /*!< Whether codec works as I2S master or not */ - bool use_mclk; /*!< Whether use external MCLK clock */ - bool digital_mic; /*!< Whether use digital microphone */ - bool invert_mclk; /*!< MCLK clock signal inverted or not */ - bool invert_sclk; /*!< SCLK clock signal inverted or not */ - esp_codec_dev_hw_gain_t hw_gain; /*!< Hardware gain */ - bool no_dac_ref; /*!< When record 2 channel data + /** + * @brief ES8311 codec configuration + */ + typedef struct + { + const audio_codec_ctrl_if_t* ctrl_if; /*!< Codec Control interface */ + const audio_codec_gpio_if_t* gpio_if; /*!< Codec GPIO interface */ + esp_codec_dec_work_mode_t codec_mode; /*!< Codec work mode: ADC or DAC */ + int16_t pa_pin; /*!< PA chip power pin */ + bool pa_reverted; /*!< false: enable PA when pin set to 1, true: enable PA when pin set to 0 */ + bool master_mode; /*!< Whether codec works as I2S master or not */ + bool use_mclk; /*!< Whether use external MCLK clock */ + bool digital_mic; /*!< Whether use digital microphone */ + bool invert_mclk; /*!< MCLK clock signal inverted or not */ + bool invert_sclk; /*!< SCLK clock signal inverted or not */ + esp_codec_dev_hw_gain_t hw_gain; /*!< Hardware gain */ + bool no_dac_ref; /*!< When record 2 channel data false: right channel filled with dac output true: right channel leave empty */ - uint16_t mclk_div; /*!< MCLK/LRCK default is 256 if not provided */ -} es8311_codec_cfg_t; + uint16_t mclk_div; /*!< MCLK/LRCK default is 256 if not provided */ + } es8311_codec_cfg_t; -/** - * @brief New ES8311 codec interface - * @param codec_cfg: ES8311 codec configuration - * @return NULL: Fail to new ES8311 codec interface - * -Others: ES8311 codec interface - */ -const audio_codec_if_t *es8311_codec_new(es8311_codec_cfg_t *codec_cfg); + /** + * @brief New ES8311 codec interface + * @param codec_cfg: ES8311 codec configuration + * @return NULL: Fail to new ES8311 codec interface + * -Others: ES8311 codec interface + */ + const audio_codec_if_t* es8311_codec_new(es8311_codec_cfg_t* codec_cfg); #ifdef __cplusplus } diff --git a/src/audio/codec/device/priv_include/es_common.h b/src/audio/codec/device/priv_include/es_common.h index a1e6bcaa..20863527 100644 --- a/src/audio/codec/device/priv_include/es_common.h +++ b/src/audio/codec/device/priv_include/es_common.h @@ -9,172 +9,186 @@ #include "esp_log.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -#define CODEC_MEM_CHECK(ptr) \ -if (ptr == NULL) { \ - ESP_LOGE(TAG, "Fail to alloc memory at %s:%d", __FUNCTION__, __LINE__);\ -} +#define CODEC_MEM_CHECK(ptr) \ + if (ptr == NULL) \ + { \ + ESP_LOGE(TAG, "Fail to alloc memory at %s:%d", __FUNCTION__, __LINE__); \ + } -#define BITS(n) (1 << n) +#define BITS(n) (1 << n) #define MCLK_DEFAULT_DIV (256) -typedef enum { - BIT_LENGTH_MIN = -1, - BIT_LENGTH_16BITS = 0x03, - BIT_LENGTH_18BITS = 0x02, - BIT_LENGTH_20BITS = 0x01, - BIT_LENGTH_24BITS = 0x00, - BIT_LENGTH_32BITS = 0x04, - BIT_LENGTH_MAX, -} es_bits_length_t; + typedef enum + { + BIT_LENGTH_MIN = -1, + BIT_LENGTH_16BITS = 0x03, + BIT_LENGTH_18BITS = 0x02, + BIT_LENGTH_20BITS = 0x01, + BIT_LENGTH_24BITS = 0x00, + BIT_LENGTH_32BITS = 0x04, + BIT_LENGTH_MAX, + } es_bits_length_t; -typedef enum { - MCLK_DIV_MIN = -1, - MCLK_DIV_1 = 1, - MCLK_DIV_2 = 2, - MCLK_DIV_3 = 3, - MCLK_DIV_4 = 4, - MCLK_DIV_6 = 5, - MCLK_DIV_8 = 6, - MCLK_DIV_9 = 7, - MCLK_DIV_11 = 8, - MCLK_DIV_12 = 9, - MCLK_DIV_16 = 10, - MCLK_DIV_18 = 11, - MCLK_DIV_22 = 12, - MCLK_DIV_24 = 13, - MCLK_DIV_33 = 14, - MCLK_DIV_36 = 15, - MCLK_DIV_44 = 16, - MCLK_DIV_48 = 17, - MCLK_DIV_66 = 18, - MCLK_DIV_72 = 19, - MCLK_DIV_5 = 20, - MCLK_DIV_10 = 21, - MCLK_DIV_15 = 22, - MCLK_DIV_17 = 23, - MCLK_DIV_20 = 24, - MCLK_DIV_25 = 25, - MCLK_DIV_30 = 26, - MCLK_DIV_32 = 27, - MCLK_DIV_34 = 28, - MCLK_DIV_7 = 29, - MCLK_DIV_13 = 30, - MCLK_DIV_14 = 31, - MCLK_DIV_MAX, -} es_sclk_div_t; + typedef enum + { + MCLK_DIV_MIN = -1, + MCLK_DIV_1 = 1, + MCLK_DIV_2 = 2, + MCLK_DIV_3 = 3, + MCLK_DIV_4 = 4, + MCLK_DIV_6 = 5, + MCLK_DIV_8 = 6, + MCLK_DIV_9 = 7, + MCLK_DIV_11 = 8, + MCLK_DIV_12 = 9, + MCLK_DIV_16 = 10, + MCLK_DIV_18 = 11, + MCLK_DIV_22 = 12, + MCLK_DIV_24 = 13, + MCLK_DIV_33 = 14, + MCLK_DIV_36 = 15, + MCLK_DIV_44 = 16, + MCLK_DIV_48 = 17, + MCLK_DIV_66 = 18, + MCLK_DIV_72 = 19, + MCLK_DIV_5 = 20, + MCLK_DIV_10 = 21, + MCLK_DIV_15 = 22, + MCLK_DIV_17 = 23, + MCLK_DIV_20 = 24, + MCLK_DIV_25 = 25, + MCLK_DIV_30 = 26, + MCLK_DIV_32 = 27, + MCLK_DIV_34 = 28, + MCLK_DIV_7 = 29, + MCLK_DIV_13 = 30, + MCLK_DIV_14 = 31, + MCLK_DIV_MAX, + } es_sclk_div_t; -typedef enum { - LCLK_DIV_MIN = -1, - LCLK_DIV_128 = 0, - LCLK_DIV_192 = 1, - LCLK_DIV_256 = 2, - LCLK_DIV_384 = 3, - LCLK_DIV_512 = 4, - LCLK_DIV_576 = 5, - LCLK_DIV_768 = 6, - LCLK_DIV_1024 = 7, - LCLK_DIV_1152 = 8, - LCLK_DIV_1408 = 9, - LCLK_DIV_1536 = 10, - LCLK_DIV_2112 = 11, - LCLK_DIV_2304 = 12, + typedef enum + { + LCLK_DIV_MIN = -1, + LCLK_DIV_128 = 0, + LCLK_DIV_192 = 1, + LCLK_DIV_256 = 2, + LCLK_DIV_384 = 3, + LCLK_DIV_512 = 4, + LCLK_DIV_576 = 5, + LCLK_DIV_768 = 6, + LCLK_DIV_1024 = 7, + LCLK_DIV_1152 = 8, + LCLK_DIV_1408 = 9, + LCLK_DIV_1536 = 10, + LCLK_DIV_2112 = 11, + LCLK_DIV_2304 = 12, - LCLK_DIV_125 = 16, - LCLK_DIV_136 = 17, - LCLK_DIV_250 = 18, - LCLK_DIV_272 = 19, - LCLK_DIV_375 = 20, - LCLK_DIV_500 = 21, - LCLK_DIV_544 = 22, - LCLK_DIV_750 = 23, - LCLK_DIV_1000 = 24, - LCLK_DIV_1088 = 25, - LCLK_DIV_1496 = 26, - LCLK_DIV_1500 = 27, - LCLK_DIV_MAX, -} es_lclk_div_t; + LCLK_DIV_125 = 16, + LCLK_DIV_136 = 17, + LCLK_DIV_250 = 18, + LCLK_DIV_272 = 19, + LCLK_DIV_375 = 20, + LCLK_DIV_500 = 21, + LCLK_DIV_544 = 22, + LCLK_DIV_750 = 23, + LCLK_DIV_1000 = 24, + LCLK_DIV_1088 = 25, + LCLK_DIV_1496 = 26, + LCLK_DIV_1500 = 27, + LCLK_DIV_MAX, + } es_lclk_div_t; -typedef enum { - D2SE_PGA_GAIN_MIN = -1, - D2SE_PGA_GAIN_DIS = 0, - D2SE_PGA_GAIN_EN = 1, - D2SE_PGA_GAIN_MAX = 2, -} es_d2se_pga_t; + typedef enum + { + D2SE_PGA_GAIN_MIN = -1, + D2SE_PGA_GAIN_DIS = 0, + D2SE_PGA_GAIN_EN = 1, + D2SE_PGA_GAIN_MAX = 2, + } es_d2se_pga_t; -typedef enum { - ADC_INPUT_MIN = -1, - ADC_INPUT_LINPUT1_RINPUT1 = 0x00, - ADC_INPUT_MIC1 = 0x05, - ADC_INPUT_MIC2 = 0x06, - ADC_INPUT_LINPUT2_RINPUT2 = 0x50, - ADC_INPUT_DIFFERENCE = 0xf0, - ADC_INPUT_MAX, -} es_adc_input_t; + typedef enum + { + ADC_INPUT_MIN = -1, + ADC_INPUT_LINPUT1_RINPUT1 = 0x00, + ADC_INPUT_MIC1 = 0x05, + ADC_INPUT_MIC2 = 0x06, + ADC_INPUT_LINPUT2_RINPUT2 = 0x50, + ADC_INPUT_DIFFERENCE = 0xf0, + ADC_INPUT_MAX, + } es_adc_input_t; -typedef enum { - DAC_OUTPUT_MIN = -1, - DAC_OUTPUT_LOUT1 = 0x04, - DAC_OUTPUT_LOUT2 = 0x08, - DAC_OUTPUT_SPK = 0x09, - DAC_OUTPUT_ROUT1 = 0x10, - DAC_OUTPUT_ROUT2 = 0x20, - DAC_OUTPUT_ALL = 0x3c, - DAC_OUTPUT_MAX, -} es_dac_output_t; + typedef enum + { + DAC_OUTPUT_MIN = -1, + DAC_OUTPUT_LOUT1 = 0x04, + DAC_OUTPUT_LOUT2 = 0x08, + DAC_OUTPUT_SPK = 0x09, + DAC_OUTPUT_ROUT1 = 0x10, + DAC_OUTPUT_ROUT2 = 0x20, + DAC_OUTPUT_ALL = 0x3c, + DAC_OUTPUT_MAX, + } es_dac_output_t; -typedef enum { - MIC_GAIN_MIN = -1, - MIC_GAIN_0DB = 0, - MIC_GAIN_3DB = 3, - MIC_GAIN_6DB = 6, - MIC_GAIN_9DB = 9, - MIC_GAIN_12DB = 12, - MIC_GAIN_15DB = 15, - MIC_GAIN_18DB = 18, - MIC_GAIN_21DB = 21, - MIC_GAIN_24DB = 24, - MIC_GAIN_MAX, -} es_mic_gain_t; + typedef enum + { + MIC_GAIN_MIN = -1, + MIC_GAIN_0DB = 0, + MIC_GAIN_3DB = 3, + MIC_GAIN_6DB = 6, + MIC_GAIN_9DB = 9, + MIC_GAIN_12DB = 12, + MIC_GAIN_15DB = 15, + MIC_GAIN_18DB = 18, + MIC_GAIN_21DB = 21, + MIC_GAIN_24DB = 24, + MIC_GAIN_MAX, + } es_mic_gain_t; -typedef enum { - ES_MODULE_MIN = -1, - ES_MODULE_ADC = 0x01, - ES_MODULE_DAC = 0x02, - ES_MODULE_ADC_DAC = 0x03, - ES_MODULE_LINE = 0x04, - ES_MODULE_MAX -} es_module_t; + typedef enum + { + ES_MODULE_MIN = -1, + ES_MODULE_ADC = 0x01, + ES_MODULE_DAC = 0x02, + ES_MODULE_ADC_DAC = 0x03, + ES_MODULE_LINE = 0x04, + ES_MODULE_MAX + } es_module_t; -typedef enum { - ES_MODE_MIN = -1, - ES_MODE_SLAVE = 0x00, - ES_MODE_MASTER = 0x01, - ES_MODE_MAX, -} es_mode_t; + typedef enum + { + ES_MODE_MIN = -1, + ES_MODE_SLAVE = 0x00, + ES_MODE_MASTER = 0x01, + ES_MODE_MAX, + } es_mode_t; -typedef enum { - ES_I2S_MIN = -1, - ES_I2S_NORMAL = 0, - ES_I2S_LEFT = 1, - ES_I2S_RIGHT = 2, - ES_I2S_DSP = 3, - ES_I2S_MAX -} es_i2s_fmt_t; + typedef enum + { + ES_I2S_MIN = -1, + ES_I2S_NORMAL = 0, + ES_I2S_LEFT = 1, + ES_I2S_RIGHT = 2, + ES_I2S_DSP = 3, + ES_I2S_MAX + } es_i2s_fmt_t; -typedef struct { - es_sclk_div_t sclk_div; /*!< bits clock divide */ - es_lclk_div_t lclk_div; /*!< WS clock divide */ -} es_i2s_clock_t; + typedef struct + { + es_sclk_div_t sclk_div; /*!< bits clock divide */ + es_lclk_div_t lclk_div; /*!< WS clock divide */ + } es_i2s_clock_t; -typedef enum { - ES_PA_SETUP = 1, - ES_PA_ENABLE = (1 << 1), - ES_PA_DISABLE = (1 << 2), -} es_pa_setting_t; + typedef enum + { + ES_PA_SETUP = 1, + ES_PA_ENABLE = (1 << 1), + ES_PA_DISABLE = (1 << 2), + } es_pa_setting_t; #ifdef __cplusplus } diff --git a/src/audio/codec/esp_codec.cpp b/src/audio/codec/esp_codec.cpp index 3c4ee156..0c3368d7 100644 --- a/src/audio/codec/esp_codec.cpp +++ b/src/audio/codec/esp_codec.cpp @@ -19,22 +19,22 @@ #include "driver/i2s_pdm.h" #endif -#define I2S_DUPLEX_MONO_DEFAULT_CFG(_sample_rate,_mclk,_bclk,_ws,_dout,_din) \ +#define I2S_DUPLEX_MONO_DEFAULT_CFG(_sample_rate, _mclk, _bclk, _ws, _dout, _din) \ { \ .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(_sample_rate), \ .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO), \ - .gpio_cfg = { \ - .mclk = (gpio_num_t)_mclk, \ - .bclk = (gpio_num_t)_bclk, \ - .ws = (gpio_num_t)_ws, \ - .dout = (gpio_num_t)_dout, \ - .din = (gpio_num_t)_din, \ - .invert_flags = { \ - .mclk_inv = false, \ - .bclk_inv = false, \ - .ws_inv = false, \ - } \ - } \ + .gpio_cfg = { \ + .mclk = (gpio_num_t)_mclk, \ + .bclk = (gpio_num_t)_bclk, \ + .ws = (gpio_num_t)_ws, \ + .dout = (gpio_num_t)_dout, \ + .din = (gpio_num_t)_din, \ + .invert_flags = { \ + .mclk_inv = false, \ + .bclk_inv = false, \ + .ws_inv = false, \ + } \ + } \ } #else #include "driver/i2s.h" @@ -64,7 +64,7 @@ void EspCodec::setPaParams(int pa_pin, float pa_voltage) _pa_voltage = pa_voltage; } -void EspCodec::setPaPinCallback(EspCodecPaPinCallback_t cb, void *user_data) +void EspCodec::setPaPinCallback(EspCodecPaPinCallback_t cb, void* user_data) { paPinCb = cb; paPinUserData = user_data; @@ -79,15 +79,17 @@ void EspCodec::setPins(int mclk, int sck, int ws, int data_out, int data_in) _data_in_num = data_in; } -bool EspCodec::begin(TwoWire&wire, uint8_t address, EspCodecType type) +bool EspCodec::begin(TwoWire& wire, uint8_t address, EspCodecType type) { wire.beginTransmission(address); - if (wire.endTransmission() != 0) { + if (wire.endTransmission() != 0) + { log_e("I2C device not found at address 0x%02X", address); return false; } - if (_i2s_init() != ESP_OK) { + if (_i2s_init() != ESP_OK) + { log_e("I2S init failed!"); return false; } @@ -95,7 +97,8 @@ bool EspCodec::begin(TwoWire&wire, uint8_t address, EspCodecType type) this->wire = &wire; gpio_if = audio_codec_new_gpio(); - if (gpio_if == NULL) { + if (gpio_if == NULL) + { log_e("new gpio failed!"); return false; } @@ -103,10 +106,11 @@ bool EspCodec::begin(TwoWire&wire, uint8_t address, EspCodecType type) audio_codec_i2c_cfg_t i2c_cfg = { .port = 0, .addr = address, - .bus_handle = (void*) &Wire, + .bus_handle = (void*)&Wire, }; i2c_ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg); - if (i2c_ctrl_if == NULL) { + if (i2c_ctrl_if == NULL) + { log_e("new i2c ctrl failed!"); audio_codec_delete_gpio_if(gpio_if); return false; @@ -117,7 +121,8 @@ bool EspCodec::begin(TwoWire&wire, uint8_t address, EspCodecType type) .codec_dac_voltage = 3.3, }; - switch (type) { + switch (type) + { case CODEC_TYPE_ES8311: #ifdef CONFIG_CODEC_ES8311_SUPPORT { @@ -143,7 +148,8 @@ bool EspCodec::begin(TwoWire&wire, uint8_t address, EspCodecType type) break; } - if (codec_if == NULL) { + if (codec_if == NULL) + { log_e("new codec failed!"); audio_codec_delete_gpio_if(gpio_if); audio_codec_delete_ctrl_if(i2c_ctrl_if); @@ -156,8 +162,9 @@ bool EspCodec::begin(TwoWire&wire, uint8_t address, EspCodecType type) .data_if = i2s_data_if, }; - codec_dev = esp_codec_dev_new(&codec_dev_cfg); - if (codec_dev == NULL) { + codec_dev = esp_codec_dev_new(&codec_dev_cfg); + if (codec_dev == NULL) + { log_e("new codec dev failed!"); audio_codec_delete_gpio_if(gpio_if); audio_codec_delete_ctrl_if(i2c_ctrl_if); @@ -165,7 +172,8 @@ bool EspCodec::begin(TwoWire&wire, uint8_t address, EspCodecType type) return false; } - if (open(16, 2, 16000) != ESP_OK) { + if (open(16, 2, 16000) != ESP_OK) + { audio_codec_delete_gpio_if(gpio_if); audio_codec_delete_ctrl_if(i2c_ctrl_if); audio_codec_delete_codec_if(codec_if); @@ -204,9 +212,9 @@ void EspCodec::setVolume(uint8_t level) esp_codec_dev_set_out_vol(codec_dev, level); } -int EspCodec::getVolume() +int EspCodec::getVolume() { - int level = 0; + int level = 0; esp_codec_dev_get_out_vol(codec_dev, &level); return level; } @@ -218,7 +226,7 @@ void EspCodec::setGain(float db_value) float EspCodec::getGain() { - float db_value = 0; + float db_value = 0; esp_codec_dev_get_in_gain(codec_dev, &db_value); return db_value; } @@ -229,10 +237,10 @@ int EspCodec::open(uint8_t bits_per_sample, uint8_t channel, uint32_t sample_rat .bits_per_sample = bits_per_sample, .channel = channel, .channel_mask = 0, - .sample_rate = sample_rate - }; - int rlst = esp_codec_dev_open(codec_dev, &fs); - if (rlst == 0 && paPinCb) { + .sample_rate = sample_rate}; + int rlst = esp_codec_dev_open(codec_dev, &fs); + if (rlst == 0 && paPinCb) + { paPinCb(true, paPinUserData); } return rlst; @@ -241,17 +249,18 @@ int EspCodec::open(uint8_t bits_per_sample, uint8_t channel, uint32_t sample_rat void EspCodec::close() { esp_codec_dev_close(codec_dev); - if (paPinCb) { + if (paPinCb) + { paPinCb(false, paPinUserData); } } -int EspCodec::write(uint8_t * buffer, size_t size) +int EspCodec::write(uint8_t* buffer, size_t size) { return esp_codec_dev_write(codec_dev, buffer, size); } -int EspCodec::read(uint8_t * buffer, size_t size) +int EspCodec::read(uint8_t* buffer, size_t size) { return esp_codec_dev_read(codec_dev, buffer, size); } @@ -265,7 +274,7 @@ esp_err_t EspCodec::_i2s_init() static i2s_chan_handle_t rx_channel; /* Setup I2S peripheral */ - i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG((i2s_port_t )_i2s_num, I2S_ROLE_MASTER); + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG((i2s_port_t)_i2s_num, I2S_ROLE_MASTER); chan_cfg.auto_clear = true; // Auto clear the legacy data in the DMA buffer ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_channel, &rx_channel)); @@ -280,7 +289,7 @@ esp_err_t EspCodec::_i2s_init() #else i2s_config_t i2s_config = { - .mode = (i2s_mode_t) (I2S_MODE_TX | I2S_MODE_RX | I2S_MODE_MASTER), + .mode = (i2s_mode_t)(I2S_MODE_TX | I2S_MODE_RX | I2S_MODE_MASTER), .sample_rate = 44100, .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, @@ -291,7 +300,7 @@ esp_err_t EspCodec::_i2s_init() .use_apll = true, .tx_desc_auto_clear = true, }; - esp_err_t ret = i2s_driver_install((i2s_port_t )_i2s_num, &i2s_config, 0, NULL); + esp_err_t ret = i2s_driver_install((i2s_port_t)_i2s_num, &i2s_config, 0, NULL); ESP_ERROR_CHECK(ret); i2s_pin_config_t i2s_pin_cfg = { @@ -299,9 +308,8 @@ esp_err_t EspCodec::_i2s_init() .bck_io_num = _bck_io_num, .ws_io_num = _ws_io_num, .data_out_num = _data_out_num, - .data_in_num = _data_in_num - }; - ret = i2s_set_pin((i2s_port_t )_i2s_num, &i2s_pin_cfg); + .data_in_num = _data_in_num}; + ret = i2s_set_pin((i2s_port_t)_i2s_num, &i2s_pin_cfg); ESP_ERROR_CHECK(ret); #endif @@ -318,17 +326,16 @@ esp_err_t EspCodec::_i2s_init() }; i2s_data_if = audio_codec_new_i2s_data(&i2s_cfg); - return i2s_data_if != NULL ? ESP_OK : ESP_FAIL; + return i2s_data_if != NULL ? ESP_OK : ESP_FAIL; } - void EspCodec::_i2s_deinit() { #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) - //TODO: Deinitialize I2S for IDF 5.x + // TODO: Deinitialize I2S for IDF 5.x #else - i2s_driver_uninstall((i2s_port_t )_i2s_num); + i2s_driver_uninstall((i2s_port_t)_i2s_num); pinMode(_mck_io_num, INPUT); pinMode(_bck_io_num, INPUT); @@ -340,30 +347,31 @@ void EspCodec::_i2s_deinit() const int WAVE_HEADER_SIZE = PCM_WAV_HEADER_SIZE; -bool EspCodec::playWAV(uint8_t *data, size_t len) +bool EspCodec::playWAV(uint8_t* data, size_t len) { - pcm_wav_header_t *header = (pcm_wav_header_t *)data; - if (header->fmt_chunk.audio_format != 1) { + pcm_wav_header_t* header = (pcm_wav_header_t*)data; + if (header->fmt_chunk.audio_format != 1) + { log_e("Audio format is not PCM!"); return false; } - wav_data_chunk_t *data_chunk = &header->data_chunk; + wav_data_chunk_t* data_chunk = &header->data_chunk; size_t data_offset = 0; - while (memcmp(data_chunk->subchunk_id, "data", 4) != 0) { + while (memcmp(data_chunk->subchunk_id, "data", 4) != 0) + { log_d( "Skip chunk: %c%c%c%c, len: %lu", data_chunk->subchunk_id[0], data_chunk->subchunk_id[1], data_chunk->subchunk_id[2], data_chunk->subchunk_id[3], - data_chunk->subchunk_size + 8 - ); + data_chunk->subchunk_size + 8); data_offset += data_chunk->subchunk_size + 8; - data_chunk = (wav_data_chunk_t *)(data + WAVE_HEADER_SIZE + data_offset - 8); + data_chunk = (wav_data_chunk_t*)(data + WAVE_HEADER_SIZE + data_offset - 8); } log_d( "Play WAV: rate:%lu, bits:%d, channels:%d, size:%lu", header->fmt_chunk.sample_rate, header->fmt_chunk.bits_per_sample, header->fmt_chunk.num_of_channels, - data_chunk->subchunk_size - ); + data_chunk->subchunk_size); int ret = open(header->fmt_chunk.bits_per_sample, header->fmt_chunk.num_of_channels, header->fmt_chunk.sample_rate); - if (ret < 0) { + if (ret < 0) + { log_e("Open audio device failed"); return false; } @@ -372,8 +380,7 @@ bool EspCodec::playWAV(uint8_t *data, size_t len) return true; } - -bool EspCodec::recordWAV(size_t rec_seconds, uint8_t**output, size_t *out_size, uint16_t sample_rate, uint8_t num_channels) +bool EspCodec::recordWAV(size_t rec_seconds, uint8_t** output, size_t* out_size, uint16_t sample_rate, uint8_t num_channels) { uint16_t sample_width = 16; size_t rec_size = rec_seconds * ((sample_rate * (sample_width / 8)) * num_channels); @@ -382,20 +389,23 @@ bool EspCodec::recordWAV(size_t rec_seconds, uint8_t**output, size_t *out_size, log_d("Record WAV: rate:%lu, bits:%u, channels:%u, size:%lu", sample_rate, sample_width, num_channels, rec_size); - uint8_t *wav_buf = (uint8_t *)malloc(rec_size + PCM_WAV_HEADER_SIZE); - if (wav_buf == NULL) { + uint8_t* wav_buf = (uint8_t*)malloc(rec_size + PCM_WAV_HEADER_SIZE); + if (wav_buf == NULL) + { log_e("Failed to allocate WAV buffer with size %u", rec_size + PCM_WAV_HEADER_SIZE); return false; } memcpy(wav_buf, &wav_header, PCM_WAV_HEADER_SIZE); int rlst = this->open(sample_width, num_channels, sample_rate); - if (rlst != ESP_CODEC_DEV_OK) { + if (rlst != ESP_CODEC_DEV_OK) + { free(wav_buf); return false; } rlst = this->read(wav_buf + PCM_WAV_HEADER_SIZE, rec_size); - if (rlst != ESP_CODEC_DEV_OK ) { + if (rlst != ESP_CODEC_DEV_OK) + { log_e("Recorded failed,error code : %d", rlst); free(wav_buf); this->close(); @@ -406,4 +416,3 @@ bool EspCodec::recordWAV(size_t rec_seconds, uint8_t**output, size_t *out_size, *output = wav_buf; return true; } - diff --git a/src/audio/codec/esp_codec.h b/src/audio/codec/esp_codec.h index 14e17a8e..97796068 100644 --- a/src/audio/codec/esp_codec.h +++ b/src/audio/codec/esp_codec.h @@ -17,15 +17,15 @@ #endif #include - /** * @enum EspCodecType * @brief Enumeration of supported audio codec types. * @details This enum lists different audio codec models supported by the EspCodec class. * Each value corresponds to a specific codec chip model. */ -typedef enum { - CODEC_TYPE_ES8311, /**< ES8311 audio codec chip */ +typedef enum +{ + CODEC_TYPE_ES8311, /**< ES8311 audio codec chip */ } EspCodecType; /** @@ -34,7 +34,7 @@ typedef enum { * @param enable True to enable the PA pin, false to disable it. * @param user_data User-provided data pointer passed to the callback. */ -using EspCodecPaPinCallback_t = void(*)(bool enable, void *user_data); +using EspCodecPaPinCallback_t = void (*)(bool enable, void* user_data); /** * @class EspCodec @@ -45,7 +45,7 @@ using EspCodecPaPinCallback_t = void(*)(bool enable, void *user_data); */ class EspCodec { -public: + public: /** * @brief Set power amplifier (PA) parameters. * @param pa_pin GPIO pin number for the PA control. @@ -58,7 +58,7 @@ public: * @param cb Callback function to be called when PA state changes. * @param user_data User-specific data to pass to the callback. */ - void setPaPinCallback(EspCodecPaPinCallback_t cb, void *user_data); + void setPaPinCallback(EspCodecPaPinCallback_t cb, void* user_data); /** * @brief Configure I2S interface pins. @@ -104,7 +104,7 @@ public: * @param size Size of the data buffer in bytes. * @return Number of bytes written, or negative error code on failure. */ - int write(uint8_t * buffer, size_t size); + int write(uint8_t* buffer, size_t size); /** * @brief Read audio data from the codec during recording. @@ -112,7 +112,7 @@ public: * @param size Maximum number of bytes to read. * @return Number of bytes read, or negative error code on failure. */ - int read(uint8_t * buffer, size_t size); + int read(uint8_t* buffer, size_t size); /** * @brief Set the audio volume level. @@ -158,7 +158,7 @@ public: * @param out_size Pointer to receive the size of the recorded data. * @return True if recording succeeds, false otherwise. */ - bool recordWAV(size_t rec_seconds, uint8_t**output, size_t *out_size, uint16_t sample_rate = 16000, uint8_t num_channels = 1); + bool recordWAV(size_t rec_seconds, uint8_t** output, size_t* out_size, uint16_t sample_rate = 16000, uint8_t num_channels = 1); /** * @brief Play a WAV audio file from buffer. @@ -167,7 +167,7 @@ public: * @param len Length of the WAV data buffer in bytes. * @return True if playback starts successfully, false otherwise. */ - bool playWAV(uint8_t *data, size_t len); + bool playWAV(uint8_t* data, size_t len); /** * @brief Constructor for EspCodec. @@ -181,7 +181,7 @@ public: */ ~EspCodec(); -private: + private: /** * @brief Internal function to initialize the I2S peripheral. * @return ESP_OK on success, or other ESP error codes on failure. @@ -193,23 +193,22 @@ private: */ void _i2s_deinit(); - int _mck_io_num; /**< Master clock (MCK) pin number (limited to GPIO0/GPIO1/GPIO3 on ESP32) */ - int _bck_io_num; /**< Bit clock (BCK) pin number */ - int _ws_io_num; /**< Word select (WS) pin number */ - int _data_out_num; /**< Data output (DOUT) pin number */ - int _data_in_num; /**< Data input (DIN) pin number */ - int _pa_num; /**< Power amplifier (PA) control pin number */ - float _pa_voltage; /**< PA voltage setting */ - uint8_t _i2s_num; /**< I2S peripheral number (0 or 1) */ - const audio_codec_gpio_if_t *gpio_if; /**< GPIO interface for codec control */ - const audio_codec_ctrl_if_t *i2c_ctrl_if; /**< I2C control interface for codec */ - const audio_codec_if_t *codec_if; /**< Core codec interface */ - const audio_codec_data_if_t *i2s_data_if; /**< I2S data transfer interface */ - esp_codec_dev_handle_t codec_dev; /**< Handle to the codec device */ - TwoWire *wire; /**< Pointer to the I2C interface object */ - EspCodecPaPinCallback_t paPinCb; /**< Callback function for PA pin control */ - void *paPinUserData; /**< User data for PA pin callback */ + int _mck_io_num; /**< Master clock (MCK) pin number (limited to GPIO0/GPIO1/GPIO3 on ESP32) */ + int _bck_io_num; /**< Bit clock (BCK) pin number */ + int _ws_io_num; /**< Word select (WS) pin number */ + int _data_out_num; /**< Data output (DOUT) pin number */ + int _data_in_num; /**< Data input (DIN) pin number */ + int _pa_num; /**< Power amplifier (PA) control pin number */ + float _pa_voltage; /**< PA voltage setting */ + uint8_t _i2s_num; /**< I2S peripheral number (0 or 1) */ + const audio_codec_gpio_if_t* gpio_if; /**< GPIO interface for codec control */ + const audio_codec_ctrl_if_t* i2c_ctrl_if; /**< I2C control interface for codec */ + const audio_codec_if_t* codec_if; /**< Core codec interface */ + const audio_codec_data_if_t* i2s_data_if; /**< I2S data transfer interface */ + esp_codec_dev_handle_t codec_dev; /**< Handle to the codec device */ + TwoWire* wire; /**< Pointer to the I2C interface object */ + EspCodecPaPinCallback_t paPinCb; /**< Callback function for PA pin control */ + void* paPinUserData; /**< User data for PA pin callback */ }; #endif - diff --git a/src/audio/codec/esp_codec_config.h b/src/audio/codec/esp_codec_config.h index 229788d2..a5cddc5c 100644 --- a/src/audio/codec/esp_codec_config.h +++ b/src/audio/codec/esp_codec_config.h @@ -6,4 +6,3 @@ #pragma once #define CONFIG_CODEC_ES8311_SUPPORT - diff --git a/src/audio/codec/esp_codec_dev.c b/src/audio/codec/esp_codec_dev.c index 96eb01db..952a40d8 100644 --- a/src/audio/codec/esp_codec_dev.c +++ b/src/audio/codec/esp_codec_dev.c @@ -3,81 +3,91 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include -#include #include "./include/esp_codec_dev.h" -#include "./interface/audio_codec_if.h" #include "./interface/audio_codec_data_if.h" +#include "./interface/audio_codec_if.h" #include "audio_codec_sw_vol.h" #include "esp_log.h" +#include +#include -#define TAG "Adev_Codec" +#define TAG "Adev_Codec" #define VOL_TRANSITION_TIME (50) -typedef struct { - const audio_codec_if_t *codec_if; - const audio_codec_data_if_t *data_if; - const audio_codec_vol_if_t *sw_vol; - esp_codec_dev_type_t dev_caps; - bool input_opened; - bool output_opened; - int volume; - float mic_gain; - bool muted; - bool mic_muted; - bool sw_vol_alloced; - esp_codec_dev_vol_curve_t vol_curve; - bool disable_when_closed; +typedef struct +{ + const audio_codec_if_t* codec_if; + const audio_codec_data_if_t* data_if; + const audio_codec_vol_if_t* sw_vol; + esp_codec_dev_type_t dev_caps; + bool input_opened; + bool output_opened; + int volume; + float mic_gain; + bool muted; + bool mic_muted; + bool sw_vol_alloced; + esp_codec_dev_vol_curve_t vol_curve; + bool disable_when_closed; } codec_dev_t; -static bool _verify_codec_ready(codec_dev_t *dev) +static bool _verify_codec_ready(codec_dev_t* dev) { - if (dev->codec_if && dev->codec_if->is_open) { - if (dev->codec_if->is_open(dev->codec_if) == false) { + if (dev->codec_if && dev->codec_if->is_open) + { + if (dev->codec_if->is_open(dev->codec_if) == false) + { return false; } } return true; } -static bool _verify_drv_ready(codec_dev_t *dev, bool playback) +static bool _verify_drv_ready(codec_dev_t* dev, bool playback) { - if (_verify_codec_ready(dev) == false) { + if (_verify_codec_ready(dev) == false) + { ESP_LOGE(TAG, "Codec is not open yet"); return false; } - if (dev->data_if->is_open && dev->data_if->is_open(dev->data_if) == false) { + if (dev->data_if->is_open && dev->data_if->is_open(dev->data_if) == false) + { ESP_LOGE(TAG, "Codec data interface not open"); return false; } - if (playback && dev->data_if->write == NULL) { + if (playback && dev->data_if->write == NULL) + { ESP_LOGE(TAG, "Need provide write API"); return false; } - if (playback == false && dev->data_if->read == NULL) { + if (playback == false && dev->data_if->read == NULL) + { ESP_LOGE(TAG, "Need provide read API"); return false; } return true; } -static int _verify_codec_setting(codec_dev_t *dev, bool playback) +static int _verify_codec_setting(codec_dev_t* dev, bool playback) { if ((playback && (dev->dev_caps & ESP_CODEC_DEV_TYPE_OUT) == 0) || - (!playback && (dev->dev_caps & ESP_CODEC_DEV_TYPE_IN) == 0)) { + (!playback && (dev->dev_caps & ESP_CODEC_DEV_TYPE_IN) == 0)) + { return ESP_CODEC_DEV_NOT_SUPPORT; } - if (_verify_codec_ready(dev) == false) { + if (_verify_codec_ready(dev) == false) + { return ESP_CODEC_DEV_WRONG_STATE; } return ESP_CODEC_DEV_OK; } -static int _get_default_vol_curve(esp_codec_dev_vol_curve_t *curve) +static int _get_default_vol_curve(esp_codec_dev_vol_curve_t* curve) { - curve->vol_map = (esp_codec_dev_vol_map_t *) malloc(2 * sizeof(esp_codec_dev_vol_map_t)); - if (curve->vol_map) { + curve->vol_map = (esp_codec_dev_vol_map_t*)malloc(2 * sizeof(esp_codec_dev_vol_map_t)); + if (curve->vol_map) + { curve->count = 2; curve->vol_map[0].vol = 0; curve->vol_map[0].db_value = -50.0; @@ -87,21 +97,27 @@ static int _get_default_vol_curve(esp_codec_dev_vol_curve_t *curve) return ESP_CODEC_DEV_OK; } -static float _get_vol_db(esp_codec_dev_vol_curve_t *curve, int vol) +static float _get_vol_db(esp_codec_dev_vol_curve_t* curve, int vol) { - if (vol == 0) { + if (vol == 0) + { return -96.0; } int n = curve->count; - if (n == 0) { + if (n == 0) + { return 0.0; } - if (vol >= curve->vol_map[n - 1].vol) { + if (vol >= curve->vol_map[n - 1].vol) + { return curve->vol_map[n - 1].db_value; } - for (int i = 0; i < n - 1; i++) { - if (vol < curve->vol_map[i + 1].vol) { - if (curve->vol_map[i].vol != curve->vol_map[i + 1].vol) { + for (int i = 0; i < n - 1; i++) + { + if (vol < curve->vol_map[i + 1].vol) + { + if (curve->vol_map[i].vol != curve->vol_map[i + 1].vol) + { float ratio = (curve->vol_map[i + 1].db_value - curve->vol_map[i].db_value) / (curve->vol_map[i + 1].vol - curve->vol_map[i].vol); return curve->vol_map[i].db_value + (vol - curve->vol_map[i].vol) * ratio; @@ -112,97 +128,124 @@ static float _get_vol_db(esp_codec_dev_vol_curve_t *curve, int vol) return 0.0; } -static void _update_codec_setting(codec_dev_t *dev) +static void _update_codec_setting(codec_dev_t* dev) { - esp_codec_dev_handle_t h = (esp_codec_dev_handle_t) dev; - if (dev->output_opened) { + esp_codec_dev_handle_t h = (esp_codec_dev_handle_t)dev; + if (dev->output_opened) + { esp_codec_dev_set_out_vol(h, dev->volume); esp_codec_dev_set_out_mute(h, dev->muted); } - if (dev->input_opened) { + if (dev->input_opened) + { esp_codec_dev_set_in_gain(h, dev->mic_gain); esp_codec_dev_set_in_mute(h, dev->mic_muted); } } -esp_codec_dev_handle_t esp_codec_dev_new(esp_codec_dev_cfg_t *cfg) +esp_codec_dev_handle_t esp_codec_dev_new(esp_codec_dev_cfg_t* cfg) { - if (cfg == NULL || cfg->data_if == NULL || cfg->dev_type == ESP_CODEC_DEV_TYPE_NONE) { + if (cfg == NULL || cfg->data_if == NULL || cfg->dev_type == ESP_CODEC_DEV_TYPE_NONE) + { return NULL; } - codec_dev_t *dev = (codec_dev_t *) calloc(1, sizeof(codec_dev_t)); - if (dev == NULL) { + codec_dev_t* dev = (codec_dev_t*)calloc(1, sizeof(codec_dev_t)); + if (dev == NULL) + { return NULL; } dev->dev_caps = cfg->dev_type; dev->codec_if = cfg->codec_if; dev->data_if = cfg->data_if; - if (cfg->dev_type & ESP_CODEC_DEV_TYPE_OUT) { + if (cfg->dev_type & ESP_CODEC_DEV_TYPE_OUT) + { _get_default_vol_curve(&dev->vol_curve); } dev->disable_when_closed = true; - return (esp_codec_dev_handle_t) dev; + return (esp_codec_dev_handle_t)dev; } -int esp_codec_dev_open(esp_codec_dev_handle_t handle, esp_codec_dev_sample_info_t *fs) +int esp_codec_dev_open(esp_codec_dev_handle_t handle, esp_codec_dev_sample_info_t* fs) { - codec_dev_t *dev = (codec_dev_t *) handle; - if (dev == NULL || fs == NULL) { + codec_dev_t* dev = (codec_dev_t*)handle; + if (dev == NULL || fs == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } - if (dev->input_opened || dev->output_opened) { + if (dev->input_opened || dev->output_opened) + { ESP_LOGI(TAG, "Input already open"); return ESP_CODEC_DEV_OK; } - if ((dev->dev_caps & ESP_CODEC_DEV_TYPE_IN)) { + if ((dev->dev_caps & ESP_CODEC_DEV_TYPE_IN)) + { // check record - if (_verify_drv_ready(dev, false) == false) { + if (_verify_drv_ready(dev, false) == false) + { ESP_LOGE(TAG, "Codec not support input"); - } else { + } + else + { dev->input_opened = true; } } - if ((dev->dev_caps & ESP_CODEC_DEV_TYPE_OUT)) { + if ((dev->dev_caps & ESP_CODEC_DEV_TYPE_OUT)) + { // check record - if (_verify_drv_ready(dev, true) == false) { + if (_verify_drv_ready(dev, true) == false) + { ESP_LOGE(TAG, "Codec not support output"); - } else { + } + else + { dev->output_opened = true; } } - if (dev->input_opened == false && dev->output_opened == false) { + if (dev->input_opened == false && dev->output_opened == false) + { return ESP_CODEC_DEV_NOT_SUPPORT; } - const audio_codec_if_t *codec = dev->codec_if; - const audio_codec_data_if_t *data_if = dev->data_if; - if (data_if->set_fmt) { + const audio_codec_if_t* codec = dev->codec_if; + const audio_codec_data_if_t* data_if = dev->data_if; + if (data_if->set_fmt) + { data_if->set_fmt(data_if, dev->dev_caps, fs); } - if (data_if->enable) { + if (data_if->enable) + { data_if->enable(data_if, dev->dev_caps, true); } - if (codec) { + if (codec) + { // TODO not set codec fs - if (codec->set_fs) { - if (codec->set_fs(codec, fs) != 0) { + if (codec->set_fs) + { + if (codec->set_fs(codec, fs) != 0) + { return ESP_CODEC_DEV_NOT_SUPPORT; } } - if (codec->enable) { - if (codec->enable(codec, true) != ESP_CODEC_DEV_OK) { + if (codec->enable) + { + if (codec->enable(codec, true) != ESP_CODEC_DEV_OK) + { ESP_LOGE(TAG, "Fail to enable codec"); return ESP_CODEC_DEV_DRV_ERR; } } } - if (dev->output_opened) { - if (codec == NULL || codec->set_vol == NULL) { - if (dev->sw_vol == NULL) { + if (dev->output_opened) + { + if (codec == NULL || codec->set_vol == NULL) + { + if (dev->sw_vol == NULL) + { dev->sw_vol = audio_codec_new_sw_vol(); dev->sw_vol_alloced = true; } } - if (dev->sw_vol) { + if (dev->sw_vol) + { dev->sw_vol->open(dev->sw_vol, fs, VOL_TRANSITION_TIME); } } @@ -212,55 +255,65 @@ int esp_codec_dev_open(esp_codec_dev_handle_t handle, esp_codec_dev_sample_info_ return ESP_CODEC_DEV_OK; } -int esp_codec_dev_read(esp_codec_dev_handle_t handle, void *data, int len) +int esp_codec_dev_read(esp_codec_dev_handle_t handle, void* data, int len) { - codec_dev_t *dev = (codec_dev_t *) handle; - if (dev == NULL || data == NULL) { + codec_dev_t* dev = (codec_dev_t*)handle; + if (dev == NULL || data == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } - if (dev->input_opened == false) { + if (dev->input_opened == false) + { return ESP_CODEC_DEV_WRONG_STATE; } - const audio_codec_data_if_t *data_if = dev->data_if; - if (data_if->read) { - return data_if->read(data_if, (uint8_t *) data, len); + const audio_codec_data_if_t* data_if = dev->data_if; + if (data_if->read) + { + return data_if->read(data_if, (uint8_t*)data, len); } return ESP_CODEC_DEV_NOT_SUPPORT; } -int esp_codec_dev_write(esp_codec_dev_handle_t handle, void *data, int len) +int esp_codec_dev_write(esp_codec_dev_handle_t handle, void* data, int len) { - codec_dev_t *dev = (codec_dev_t *) handle; - if (dev == NULL || data == NULL) { + codec_dev_t* dev = (codec_dev_t*)handle; + if (dev == NULL || data == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } - if (dev->output_opened == false) { + if (dev->output_opened == false) + { return ESP_CODEC_DEV_WRONG_STATE; } - const audio_codec_data_if_t *data_if = dev->data_if; - if (data_if->write) { + const audio_codec_data_if_t* data_if = dev->data_if; + if (data_if->write) + { // Soft volume process firstly - if (dev->sw_vol) { - dev->sw_vol->process(dev->sw_vol, (uint8_t *) data, len, (uint8_t *) data, len); + if (dev->sw_vol) + { + dev->sw_vol->process(dev->sw_vol, (uint8_t*)data, len, (uint8_t*)data, len); } - return data_if->write(data_if, (uint8_t *) data, len); + return data_if->write(data_if, (uint8_t*)data, len); } return ESP_CODEC_DEV_NOT_SUPPORT; } -int esp_codec_dev_set_vol_curve(esp_codec_dev_handle_t handle, esp_codec_dev_vol_curve_t *curve) +int esp_codec_dev_set_vol_curve(esp_codec_dev_handle_t handle, esp_codec_dev_vol_curve_t* curve) { - codec_dev_t *dev = (codec_dev_t *) handle; - if (dev == NULL || curve == NULL || curve->vol_map == NULL) { + codec_dev_t* dev = (codec_dev_t*)handle; + if (dev == NULL || curve == NULL || curve->vol_map == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } int ret = _verify_codec_setting(dev, true); - if (ret != ESP_CODEC_DEV_OK) { + if (ret != ESP_CODEC_DEV_OK) + { return ret; } int size = curve->count * sizeof(esp_codec_dev_vol_map_t); - esp_codec_dev_vol_map_t *new_map = (esp_codec_dev_vol_map_t *) realloc(dev->vol_curve.vol_map, size); - if (new_map == NULL) { + esp_codec_dev_vol_map_t* new_map = (esp_codec_dev_vol_map_t*)realloc(dev->vol_curve.vol_map, size); + if (new_map == NULL) + { return ESP_CODEC_DEV_NO_MEM; } dev->vol_curve.vol_map = new_map; @@ -271,44 +324,53 @@ int esp_codec_dev_set_vol_curve(esp_codec_dev_handle_t handle, esp_codec_dev_vol int esp_codec_dev_set_out_vol(esp_codec_dev_handle_t handle, int volume) { - codec_dev_t *dev = (codec_dev_t *) handle; - if (dev == NULL) { + codec_dev_t* dev = (codec_dev_t*)handle; + if (dev == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } int ret = _verify_codec_setting(dev, true); - if (ret != ESP_CODEC_DEV_OK) { + if (ret != ESP_CODEC_DEV_OK) + { return ret; } - const audio_codec_if_t *codec = dev->codec_if; + const audio_codec_if_t* codec = dev->codec_if; float db_value = _get_vol_db(&dev->vol_curve, volume); dev->volume = volume; // Prefer to use software volume setting - if (dev->sw_vol) { + if (dev->sw_vol) + { dev->sw_vol->set_vol(dev->sw_vol, db_value); return ESP_CODEC_DEV_OK; } - if (codec && codec->set_vol) { + if (codec && codec->set_vol) + { codec->set_vol(codec, db_value); return ESP_CODEC_DEV_OK; } return ESP_CODEC_DEV_NOT_SUPPORT; } -int esp_codec_dev_set_vol_handler(esp_codec_dev_handle_t handle, const audio_codec_vol_if_t *vol_handler) +int esp_codec_dev_set_vol_handler(esp_codec_dev_handle_t handle, const audio_codec_vol_if_t* vol_handler) { - codec_dev_t *dev = (codec_dev_t *) handle; - if (dev == NULL || vol_handler == NULL) { + codec_dev_t* dev = (codec_dev_t*)handle; + if (dev == NULL || vol_handler == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } int ret = _verify_codec_setting(dev, true); - if (ret != ESP_CODEC_DEV_OK) { + if (ret != ESP_CODEC_DEV_OK) + { return ret; } - if (dev->sw_vol == vol_handler) { + if (dev->sw_vol == vol_handler) + { return ESP_CODEC_DEV_OK; } - if (dev->sw_vol) { - if (dev->sw_vol_alloced) { + if (dev->sw_vol) + { + if (dev->sw_vol_alloced) + { audio_codec_delete_vol_if(dev->sw_vol); dev->sw_vol_alloced = false; } @@ -317,14 +379,16 @@ int esp_codec_dev_set_vol_handler(esp_codec_dev_handle_t handle, const audio_cod return ESP_CODEC_DEV_OK; } -int esp_codec_dev_get_out_vol(esp_codec_dev_handle_t handle, int *volume) +int esp_codec_dev_get_out_vol(esp_codec_dev_handle_t handle, int* volume) { - codec_dev_t *dev = (codec_dev_t *) handle; - if (dev == NULL) { + codec_dev_t* dev = (codec_dev_t*)handle; + if (dev == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } int ret = _verify_codec_setting(dev, true); - if (ret != ESP_CODEC_DEV_OK) { + if (ret != ESP_CODEC_DEV_OK) + { return ret; } *volume = dev->volume; @@ -333,36 +397,42 @@ int esp_codec_dev_get_out_vol(esp_codec_dev_handle_t handle, int *volume) int esp_codec_dev_set_out_mute(esp_codec_dev_handle_t handle, bool mute) { - codec_dev_t *dev = (codec_dev_t *) handle; - if (dev == NULL) { + codec_dev_t* dev = (codec_dev_t*)handle; + if (dev == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } int ret = _verify_codec_setting(dev, true); - if (ret != ESP_CODEC_DEV_OK) { + if (ret != ESP_CODEC_DEV_OK) + { return ret; } - const audio_codec_if_t *codec = dev->codec_if; + const audio_codec_if_t* codec = dev->codec_if; dev->muted = mute; - if (codec && codec->mute) { + if (codec && codec->mute) + { codec->mute(codec, mute); return ESP_CODEC_DEV_OK; } // When codec not support mute set volume instead - if (dev->sw_vol) { + if (dev->sw_vol) + { float db_value = mute ? -100.0 : _get_vol_db(&dev->vol_curve, dev->volume); dev->sw_vol->set_vol(dev->sw_vol, db_value); } return ESP_CODEC_DEV_NOT_SUPPORT; } -int esp_codec_dev_get_out_mute(esp_codec_dev_handle_t handle, bool *muted) +int esp_codec_dev_get_out_mute(esp_codec_dev_handle_t handle, bool* muted) { - codec_dev_t *dev = (codec_dev_t *) handle; - if (dev == NULL) { + codec_dev_t* dev = (codec_dev_t*)handle; + if (dev == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } int ret = _verify_codec_setting(dev, true); - if (ret != ESP_CODEC_DEV_OK) { + if (ret != ESP_CODEC_DEV_OK) + { return ret; } *muted = dev->muted; @@ -371,17 +441,20 @@ int esp_codec_dev_get_out_mute(esp_codec_dev_handle_t handle, bool *muted) int esp_codec_dev_set_in_gain(esp_codec_dev_handle_t handle, float db) { - codec_dev_t *dev = (codec_dev_t *) handle; - if (dev == NULL) { + codec_dev_t* dev = (codec_dev_t*)handle; + if (dev == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } int ret = _verify_codec_setting(dev, false); - if (ret != ESP_CODEC_DEV_OK) { + if (ret != ESP_CODEC_DEV_OK) + { return ret; } - const audio_codec_if_t *codec = dev->codec_if; - if (codec && codec->set_mic_gain) { - codec->set_mic_gain(codec, (int) db); + const audio_codec_if_t* codec = dev->codec_if; + if (codec && codec->set_mic_gain) + { + codec->set_mic_gain(codec, (int)db); dev->mic_gain = db; return ESP_CODEC_DEV_OK; } @@ -390,30 +463,35 @@ int esp_codec_dev_set_in_gain(esp_codec_dev_handle_t handle, float db) int esp_codec_dev_set_in_channel_gain(esp_codec_dev_handle_t handle, uint16_t channel_mask, float db) { - codec_dev_t *dev = (codec_dev_t *) handle; - if (dev == NULL || channel_mask == 0) { + codec_dev_t* dev = (codec_dev_t*)handle; + if (dev == NULL || channel_mask == 0) + { return ESP_CODEC_DEV_INVALID_ARG; } int ret = _verify_codec_setting(dev, false); - if (ret != ESP_CODEC_DEV_OK) { + if (ret != ESP_CODEC_DEV_OK) + { return ret; } - const audio_codec_if_t *codec = dev->codec_if; - if (codec && codec->set_mic_channel_gain) { - codec->set_mic_channel_gain(codec, channel_mask, (int) db); + const audio_codec_if_t* codec = dev->codec_if; + if (codec && codec->set_mic_channel_gain) + { + codec->set_mic_channel_gain(codec, channel_mask, (int)db); return ESP_CODEC_DEV_OK; } return ESP_CODEC_DEV_NOT_SUPPORT; } -int esp_codec_dev_get_in_gain(esp_codec_dev_handle_t handle, float *db_value) +int esp_codec_dev_get_in_gain(esp_codec_dev_handle_t handle, float* db_value) { - codec_dev_t *dev = (codec_dev_t *) handle; - if (dev == NULL) { + codec_dev_t* dev = (codec_dev_t*)handle; + if (dev == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } int ret = _verify_codec_setting(dev, false); - if (ret != ESP_CODEC_DEV_OK) { + if (ret != ESP_CODEC_DEV_OK) + { return ret; } *db_value = dev->mic_gain; @@ -422,16 +500,19 @@ int esp_codec_dev_get_in_gain(esp_codec_dev_handle_t handle, float *db_value) int esp_codec_dev_set_in_mute(esp_codec_dev_handle_t handle, bool mute) { - codec_dev_t *dev = (codec_dev_t *) handle; - if (dev == NULL) { + codec_dev_t* dev = (codec_dev_t*)handle; + if (dev == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } int ret = _verify_codec_setting(dev, false); - if (ret != ESP_CODEC_DEV_OK) { + if (ret != ESP_CODEC_DEV_OK) + { return ret; } - const audio_codec_if_t *codec = dev->codec_if; - if (codec && codec->mute_mic) { + const audio_codec_if_t* codec = dev->codec_if; + if (codec && codec->mute_mic) + { codec->mute_mic(codec, mute); dev->mic_muted = mute; return ESP_CODEC_DEV_OK; @@ -439,14 +520,16 @@ int esp_codec_dev_set_in_mute(esp_codec_dev_handle_t handle, bool mute) return ESP_CODEC_DEV_NOT_SUPPORT; } -int esp_codec_dev_get_in_mute(esp_codec_dev_handle_t handle, bool *muted) +int esp_codec_dev_get_in_mute(esp_codec_dev_handle_t handle, bool* muted) { - codec_dev_t *dev = (codec_dev_t *) handle; - if (dev == NULL) { + codec_dev_t* dev = (codec_dev_t*)handle; + if (dev == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } int ret = _verify_codec_setting(dev, false); - if (ret != ESP_CODEC_DEV_OK) { + if (ret != ESP_CODEC_DEV_OK) + { return ret; } *muted = dev->mic_muted; @@ -455,8 +538,9 @@ int esp_codec_dev_get_in_mute(esp_codec_dev_handle_t handle, bool *muted) int esp_codec_set_disable_when_closed(esp_codec_dev_handle_t handle, bool disable) { - codec_dev_t *dev = (codec_dev_t *) handle; - if (dev == NULL) { + codec_dev_t* dev = (codec_dev_t*)handle; + if (dev == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } dev->disable_when_closed = disable; @@ -465,24 +549,30 @@ int esp_codec_set_disable_when_closed(esp_codec_dev_handle_t handle, bool disabl int esp_codec_dev_close(esp_codec_dev_handle_t handle) { - codec_dev_t *dev = (codec_dev_t *) handle; - if (dev == NULL) { + codec_dev_t* dev = (codec_dev_t*)handle; + if (dev == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } - if (dev->output_opened == false && dev->input_opened == false) { + if (dev->output_opened == false && dev->input_opened == false) + { return ESP_CODEC_DEV_OK; } - const audio_codec_if_t *codec = dev->codec_if; - if (dev->disable_when_closed && codec) { - if (codec->enable) { + const audio_codec_if_t* codec = dev->codec_if; + if (dev->disable_when_closed && codec) + { + if (codec->enable) + { codec->enable(codec, false); } } - const audio_codec_data_if_t *data_if = dev->data_if; - if (data_if->enable) { + const audio_codec_data_if_t* data_if = dev->data_if; + if (data_if->enable) + { data_if->enable(data_if, dev->dev_caps, false); } - if (dev->sw_vol) { + if (dev->sw_vol) + { dev->sw_vol->close(dev->sw_vol); } dev->output_opened = dev->input_opened = false; @@ -491,21 +581,24 @@ int esp_codec_dev_close(esp_codec_dev_handle_t handle) void esp_codec_dev_delete(esp_codec_dev_handle_t handle) { - codec_dev_t *dev = (codec_dev_t *) handle; - if (dev) { + codec_dev_t* dev = (codec_dev_t*)handle; + if (dev) + { esp_codec_dev_close(handle); - if (dev->vol_curve.vol_map) { + if (dev->vol_curve.vol_map) + { free(dev->vol_curve.vol_map); } // Only delete software vol when alloced internally - if (dev->sw_vol && dev->sw_vol_alloced) { + if (dev->sw_vol && dev->sw_vol_alloced) + { audio_codec_delete_vol_if(dev->sw_vol); } free(dev); } } -const char *esp_codec_dev_get_version(void) +const char* esp_codec_dev_get_version(void) { return ESP_CODEC_DEV_VERSION; } diff --git a/src/audio/codec/esp_codec_dev_if.c b/src/audio/codec/esp_codec_dev_if.c index 6393b5f2..c9de9e13 100644 --- a/src/audio/codec/esp_codec_dev_if.c +++ b/src/audio/codec/esp_codec_dev_if.c @@ -3,70 +3,79 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include "./interface/audio_codec_if.h" #include "./interface/audio_codec_ctrl_if.h" #include "./interface/audio_codec_data_if.h" #include "./interface/audio_codec_gpio_if.h" +#include "./interface/audio_codec_if.h" #include "./interface/audio_codec_vol_if.h" +#include +#include -int audio_codec_delete_codec_if(const audio_codec_if_t *h) +int audio_codec_delete_codec_if(const audio_codec_if_t* h) { - if (h) { + if (h) + { int ret = 0; - if (h->close) { + if (h->close) + { ret = h->close(h); } - free((void *) h); + free((void*)h); return ret; } return ESP_CODEC_DEV_INVALID_ARG; } -int audio_codec_delete_ctrl_if(const audio_codec_ctrl_if_t *h) +int audio_codec_delete_ctrl_if(const audio_codec_ctrl_if_t* h) { - if (h) { + if (h) + { int ret = 0; - if (h->close) { + if (h->close) + { ret = h->close(h); } - free((void *) h); + free((void*)h); return ret; } return ESP_CODEC_DEV_INVALID_ARG; } -int audio_codec_delete_data_if(const audio_codec_data_if_t *h) +int audio_codec_delete_data_if(const audio_codec_data_if_t* h) { - if (h) { + if (h) + { int ret = 0; - if (h->close) { + if (h->close) + { ret = h->close(h); } - free((void *) h); + free((void*)h); return ret; } return ESP_CODEC_DEV_INVALID_ARG; } -int audio_codec_delete_gpio_if(const audio_codec_gpio_if_t *gpio_if) +int audio_codec_delete_gpio_if(const audio_codec_gpio_if_t* gpio_if) { - if (gpio_if) { - free((void *) gpio_if); + if (gpio_if) + { + free((void*)gpio_if); return ESP_CODEC_DEV_OK; } return ESP_CODEC_DEV_INVALID_ARG; } -int audio_codec_delete_vol_if(const audio_codec_vol_if_t *h) +int audio_codec_delete_vol_if(const audio_codec_vol_if_t* h) { - if (h) { + if (h) + { int ret = 0; - if (h->close) { + if (h->close) + { ret = h->close(h); } - free((void *) h); + free((void*)h); return ret; } return ESP_CODEC_DEV_INVALID_ARG; diff --git a/src/audio/codec/esp_codec_dev_vol.c b/src/audio/codec/esp_codec_dev_vol.c index e6476591..f3e63eed 100644 --- a/src/audio/codec/esp_codec_dev_vol.c +++ b/src/audio/codec/esp_codec_dev_vol.c @@ -3,42 +3,53 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include "./include/esp_codec_dev_vol.h" +#include -int esp_codec_dev_vol_calc_reg(const esp_codec_dev_vol_range_t *vol_range, float db) +int esp_codec_dev_vol_calc_reg(const esp_codec_dev_vol_range_t* vol_range, float db) { - if (vol_range->max_vol.db_value == vol_range->min_vol.db_value) { + if (vol_range->max_vol.db_value == vol_range->min_vol.db_value) + { return vol_range->max_vol.vol; } - if (db >= vol_range->max_vol.db_value) { + if (db >= vol_range->max_vol.db_value) + { return vol_range->max_vol.vol; } - if (db <= vol_range->min_vol.db_value) { + if (db <= vol_range->min_vol.db_value) + { return vol_range->min_vol.vol; } float ratio = (vol_range->max_vol.vol - vol_range->min_vol.vol) / (vol_range->max_vol.db_value - vol_range->min_vol.db_value); - return (int) ((db - vol_range->min_vol.db_value) * ratio + vol_range->min_vol.vol); + return (int)((db - vol_range->min_vol.db_value) * ratio + vol_range->min_vol.vol); } -float esp_codec_dev_vol_calc_db(const esp_codec_dev_vol_range_t *vol_range, int vol) +float esp_codec_dev_vol_calc_db(const esp_codec_dev_vol_range_t* vol_range, int vol) { - if (vol_range->max_vol.vol == vol_range->min_vol.vol) { + if (vol_range->max_vol.vol == vol_range->min_vol.vol) + { return vol_range->max_vol.db_value; } - if (vol_range->max_vol.vol > vol_range->min_vol.vol) { - if (vol >= vol_range->max_vol.vol) { + if (vol_range->max_vol.vol > vol_range->min_vol.vol) + { + if (vol >= vol_range->max_vol.vol) + { return vol_range->max_vol.db_value; } - if (vol <= vol_range->min_vol.vol) { + if (vol <= vol_range->min_vol.vol) + { return vol_range->min_vol.db_value; } - } else { - if (vol <= vol_range->max_vol.vol) { + } + else + { + if (vol <= vol_range->max_vol.vol) + { return vol_range->max_vol.db_value; } - if (vol >= vol_range->min_vol.vol) { + if (vol >= vol_range->min_vol.vol) + { return vol_range->min_vol.db_value; } } @@ -47,14 +58,16 @@ float esp_codec_dev_vol_calc_db(const esp_codec_dev_vol_range_t *vol_range, int return ((vol - vol_range->min_vol.vol) * ratio + vol_range->min_vol.db_value); } -float esp_codec_dev_col_calc_hw_gain(esp_codec_dev_hw_gain_t *hw_gain) +float esp_codec_dev_col_calc_hw_gain(esp_codec_dev_hw_gain_t* hw_gain) { float pa_voltage = hw_gain->pa_voltage; float dac_voltage = hw_gain->codec_dac_voltage; - if (pa_voltage == 0.0) { + if (pa_voltage == 0.0) + { pa_voltage = 5.0; } - if (dac_voltage == 0.0) { + if (dac_voltage == 0.0) + { dac_voltage = 3.3; } return 20 * log10(dac_voltage / pa_voltage) + hw_gain->pa_gain; diff --git a/src/audio/codec/include/esp_codec_dev.h b/src/audio/codec/include/esp_codec_dev.h index 40238b44..a3b1e70f 100644 --- a/src/audio/codec/include/esp_codec_dev.h +++ b/src/audio/codec/include/esp_codec_dev.h @@ -6,230 +6,232 @@ #ifndef _ESP_CODEC_DEV_H_ #define _ESP_CODEC_DEV_H_ -#include "../interface/audio_codec_if.h" #include "../interface/audio_codec_data_if.h" +#include "../interface/audio_codec_if.h" #include "../interface/audio_codec_vol_if.h" #include "esp_codec_dev_types.h" #include "esp_codec_dev_vol.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -/** - * @brief Codec device configuration - */ -typedef struct { - esp_codec_dev_type_t dev_type; /*!< Codec device type */ - const audio_codec_if_t *codec_if; /*!< Codec interface */ - const audio_codec_data_if_t *data_if; /*!< Codec data interface */ -} esp_codec_dev_cfg_t; + /** + * @brief Codec device configuration + */ + typedef struct + { + esp_codec_dev_type_t dev_type; /*!< Codec device type */ + const audio_codec_if_t* codec_if; /*!< Codec interface */ + const audio_codec_data_if_t* data_if; /*!< Codec data interface */ + } esp_codec_dev_cfg_t; -/** - * @brief Codec device handle - */ -typedef void *esp_codec_dev_handle_t; + /** + * @brief Codec device handle + */ + typedef void* esp_codec_dev_handle_t; -/** - * @brief Get `esp_codec_dev` version string - * @return Version information - */ -const char *esp_codec_dev_get_version(void); + /** + * @brief Get `esp_codec_dev` version string + * @return Version information + */ + const char* esp_codec_dev_get_version(void); -/** - * @brief New codec device - * @param codec_dev_cfg: Codec device configuration - * @return NULL: Fail to new codec device - * -Others: Codec device handle - */ -esp_codec_dev_handle_t esp_codec_dev_new(esp_codec_dev_cfg_t *codec_dev_cfg); + /** + * @brief New codec device + * @param codec_dev_cfg: Codec device configuration + * @return NULL: Fail to new codec device + * -Others: Codec device handle + */ + esp_codec_dev_handle_t esp_codec_dev_new(esp_codec_dev_cfg_t* codec_dev_cfg); -/** - * @brief Open codec device - * @param codec: Codec device handle - * @param fs: Audio sample information - * @return ESP_CODEC_DEV_OK: Open success - * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments - * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support or driver not ready yet - */ -int esp_codec_dev_open(esp_codec_dev_handle_t codec, esp_codec_dev_sample_info_t *fs); + /** + * @brief Open codec device + * @param codec: Codec device handle + * @param fs: Audio sample information + * @return ESP_CODEC_DEV_OK: Open success + * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments + * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support or driver not ready yet + */ + int esp_codec_dev_open(esp_codec_dev_handle_t codec, esp_codec_dev_sample_info_t* fs); -/** - * @brief Read data from codec - * @param codec: Codec device handle - * @param data: Data to be read - * @param len: Data length to be read - * @return ESP_CODEC_DEV_OK: Read success - * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments - * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support - * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet - */ -int esp_codec_dev_read(esp_codec_dev_handle_t codec, void *data, int len); + /** + * @brief Read data from codec + * @param codec: Codec device handle + * @param data: Data to be read + * @param len: Data length to be read + * @return ESP_CODEC_DEV_OK: Read success + * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments + * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support + * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet + */ + int esp_codec_dev_read(esp_codec_dev_handle_t codec, void* data, int len); -/** - * @brief Write data to codec - * Notes: when enable software volume, it will change input data level directly without copy - * Make sure that input data is writable - * @param codec: Codec device handle - * @param data: Data to be wrote - * @param len: Data length to be wrote - * @return ESP_CODEC_DEV_OK: Write success - * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments - * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support - * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet - */ -int esp_codec_dev_write(esp_codec_dev_handle_t codec, void *data, int len); + /** + * @brief Write data to codec + * Notes: when enable software volume, it will change input data level directly without copy + * Make sure that input data is writable + * @param codec: Codec device handle + * @param data: Data to be wrote + * @param len: Data length to be wrote + * @return ESP_CODEC_DEV_OK: Write success + * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments + * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support + * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet + */ + int esp_codec_dev_write(esp_codec_dev_handle_t codec, void* data, int len); -/** - * @brief Set codec hardware gain - * @param codec: Codec device handle - * @param volume: Volume setting - * @return ESP_CODEC_DEV_OK: Set output volume success - * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments - * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support output mode - * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet - */ -int esp_codec_dev_set_out_vol(esp_codec_dev_handle_t codec, int volume); + /** + * @brief Set codec hardware gain + * @param codec: Codec device handle + * @param volume: Volume setting + * @return ESP_CODEC_DEV_OK: Set output volume success + * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments + * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support output mode + * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet + */ + int esp_codec_dev_set_out_vol(esp_codec_dev_handle_t codec, int volume); -/** - * @brief Set codec software volume handler - * Notes: it is not needed when codec support volume adjust in hardware - * If not provided, it will use internally software volume process handler instead - * @param codec: Codec device handle - * @param vol_handler: Software volume process interface - * @return ESP_CODEC_DEV_OK: Set volume handler success - * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments - * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support output mode - * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet - */ -int esp_codec_dev_set_vol_handler(esp_codec_dev_handle_t codec, const audio_codec_vol_if_t* vol_handler); + /** + * @brief Set codec software volume handler + * Notes: it is not needed when codec support volume adjust in hardware + * If not provided, it will use internally software volume process handler instead + * @param codec: Codec device handle + * @param vol_handler: Software volume process interface + * @return ESP_CODEC_DEV_OK: Set volume handler success + * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments + * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support output mode + * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet + */ + int esp_codec_dev_set_vol_handler(esp_codec_dev_handle_t codec, const audio_codec_vol_if_t* vol_handler); -/** - * @brief Set codec volume curve - * Notes: When volume curve not provided, it will use internally volume curve which is: - * 1 - "-49.5dB", 100 - "0dB" - * Need to call this API if you want to customize volume curve - * @param codec: Codec device handle - * @param curve: Volume curve setting - * @return ESP_CODEC_DEV_OK: Set curve success - * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments - * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support output mode - * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet - * ESP_CODEC_DEV_NO_MEM: Not enough memory to hold volume curve - */ -int esp_codec_dev_set_vol_curve(esp_codec_dev_handle_t codec, esp_codec_dev_vol_curve_t *curve); + /** + * @brief Set codec volume curve + * Notes: When volume curve not provided, it will use internally volume curve which is: + * 1 - "-49.5dB", 100 - "0dB" + * Need to call this API if you want to customize volume curve + * @param codec: Codec device handle + * @param curve: Volume curve setting + * @return ESP_CODEC_DEV_OK: Set curve success + * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments + * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support output mode + * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet + * ESP_CODEC_DEV_NO_MEM: Not enough memory to hold volume curve + */ + int esp_codec_dev_set_vol_curve(esp_codec_dev_handle_t codec, esp_codec_dev_vol_curve_t* curve); -/** - * @brief Get codec output volume - * @param codec: Codec device handle - * @param[out] volume: Volume to get - * @return ESP_CODEC_DEV_OK: Get volume success - * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments - * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support output mode - * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet - */ -int esp_codec_dev_get_out_vol(esp_codec_dev_handle_t codec, int *volume); + /** + * @brief Get codec output volume + * @param codec: Codec device handle + * @param[out] volume: Volume to get + * @return ESP_CODEC_DEV_OK: Get volume success + * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments + * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support output mode + * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet + */ + int esp_codec_dev_get_out_vol(esp_codec_dev_handle_t codec, int* volume); -/** - * @brief Set codec output mute - * @param codec: Codec device handle - * @param mute: Whether mute output or not - * @return ESP_CODEC_DEV_OK: Set output mute success - * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments - * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support output mode - * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet - */ -int esp_codec_dev_set_out_mute(esp_codec_dev_handle_t codec, bool mute); + /** + * @brief Set codec output mute + * @param codec: Codec device handle + * @param mute: Whether mute output or not + * @return ESP_CODEC_DEV_OK: Set output mute success + * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments + * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support output mode + * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet + */ + int esp_codec_dev_set_out_mute(esp_codec_dev_handle_t codec, bool mute); -/** - * @brief Get codec output mute setting - * @param codec: Codec device handle - * @param[out] muted: Mute status to get - * @return ESP_CODEC_DEV_OK: Get output mute success - * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments - * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support output mode - * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet - */ -int esp_codec_dev_get_out_mute(esp_codec_dev_handle_t codec, bool *muted); + /** + * @brief Get codec output mute setting + * @param codec: Codec device handle + * @param[out] muted: Mute status to get + * @return ESP_CODEC_DEV_OK: Get output mute success + * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments + * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support output mode + * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet + */ + int esp_codec_dev_get_out_mute(esp_codec_dev_handle_t codec, bool* muted); -/** - * @brief Set codec input gain - * @param codec: Codec device handle - * @param db_value: Input gain setting - * @return ESP_CODEC_DEV_OK: Set input gain success - * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments - * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support input mode - * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet - */ -int esp_codec_dev_set_in_gain(esp_codec_dev_handle_t codec, float db_value); + /** + * @brief Set codec input gain + * @param codec: Codec device handle + * @param db_value: Input gain setting + * @return ESP_CODEC_DEV_OK: Set input gain success + * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments + * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support input mode + * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet + */ + int esp_codec_dev_set_in_gain(esp_codec_dev_handle_t codec, float db_value); -/** - * @brief Set codec input gain by channel - * @param codec: Codec device handle - * @param channel_mask: Mask for channel to be set - * @param db_value: Input gain setting - * @return ESP_CODEC_DEV_OK: Set input gain success - * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments - * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support input mode - * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet - */ -int esp_codec_dev_set_in_channel_gain(esp_codec_dev_handle_t codec, uint16_t channel_mask, float db_value); + /** + * @brief Set codec input gain by channel + * @param codec: Codec device handle + * @param channel_mask: Mask for channel to be set + * @param db_value: Input gain setting + * @return ESP_CODEC_DEV_OK: Set input gain success + * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments + * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support input mode + * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet + */ + int esp_codec_dev_set_in_channel_gain(esp_codec_dev_handle_t codec, uint16_t channel_mask, float db_value); -/** - * @brief Get codec input gain - * @param codec: Codec device handle - * @param db_value: Input gain to get - * @return ESP_CODEC_DEV_OK: Get input gain success - * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments - * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support input mode - * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet - */ -int esp_codec_dev_get_in_gain(esp_codec_dev_handle_t codec, float *db_value); + /** + * @brief Get codec input gain + * @param codec: Codec device handle + * @param db_value: Input gain to get + * @return ESP_CODEC_DEV_OK: Get input gain success + * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments + * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support input mode + * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet + */ + int esp_codec_dev_get_in_gain(esp_codec_dev_handle_t codec, float* db_value); -/** - * @brief Set codec input mute - * @param codec: Codec device handle - * @param mute: Whether mute code input or not - * @return ESP_CODEC_DEV_OK: Set input mute success - * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments - * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support input mode - * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet - */ -int esp_codec_dev_set_in_mute(esp_codec_dev_handle_t codec, bool mute); + /** + * @brief Set codec input mute + * @param codec: Codec device handle + * @param mute: Whether mute code input or not + * @return ESP_CODEC_DEV_OK: Set input mute success + * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments + * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support input mode + * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet + */ + int esp_codec_dev_set_in_mute(esp_codec_dev_handle_t codec, bool mute); -/** - * @brief Get codec input mute - * @param codec: Codec device handle - * @param muted: Mute value to get - * @return ESP_CODEC_DEV_OK: Set input mute success - * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments - * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support input mode - * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet - */ -int esp_codec_dev_get_in_mute(esp_codec_dev_handle_t codec, bool *muted); + /** + * @brief Get codec input mute + * @param codec: Codec device handle + * @param muted: Mute value to get + * @return ESP_CODEC_DEV_OK: Set input mute success + * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments + * ESP_CODEC_DEV_NOT_SUPPORT: Codec not support input mode + * ESP_CODEC_DEV_WRONG_STATE: Driver not open yet + */ + int esp_codec_dev_get_in_mute(esp_codec_dev_handle_t codec, bool* muted); -/** - * @brief Whether disable codec when closed - * @param codec: Codec device handle - * @param disable: Disable when closed (default is true) - * @return ESP_CODEC_DEV_OK: Setting success - * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments - */ -int esp_codec_set_disable_when_closed(esp_codec_dev_handle_t codec, bool disable); + /** + * @brief Whether disable codec when closed + * @param codec: Codec device handle + * @param disable: Disable when closed (default is true) + * @return ESP_CODEC_DEV_OK: Setting success + * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments + */ + int esp_codec_set_disable_when_closed(esp_codec_dev_handle_t codec, bool disable); -/** - * @brief Close codec device - * @param codec: Codec device handle - * @return ESP_CODEC_DEV_OK: Close success - * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments - */ -int esp_codec_dev_close(esp_codec_dev_handle_t codec); + /** + * @brief Close codec device + * @param codec: Codec device handle + * @return ESP_CODEC_DEV_OK: Close success + * ESP_CODEC_DEV_INVALID_ARG: Invalid arguments + */ + int esp_codec_dev_close(esp_codec_dev_handle_t codec); -/** - * @brief Delete the specified codec device instance - * @param codec: Codec device handle - */ -void esp_codec_dev_delete(esp_codec_dev_handle_t codec); + /** + * @brief Delete the specified codec device instance + * @param codec: Codec device handle + */ + void esp_codec_dev_delete(esp_codec_dev_handle_t codec); #ifdef __cplusplus } diff --git a/src/audio/codec/include/esp_codec_dev_defaults.h b/src/audio/codec/include/esp_codec_dev_defaults.h index 8cb87697..a674cad6 100644 --- a/src/audio/codec/include/esp_codec_dev_defaults.h +++ b/src/audio/codec/include/esp_codec_dev_defaults.h @@ -5,11 +5,11 @@ */ #ifndef _ESP_CODEC_DEV_DEFAULTS_H_ #define _ESP_CODEC_DEV_DEFAULTS_H_ -#include "../interface/audio_codec_if.h" +#include "../esp_codec_config.h" #include "../interface/audio_codec_ctrl_if.h" #include "../interface/audio_codec_data_if.h" #include "../interface/audio_codec_gpio_if.h" -#include "../esp_codec_config.h" +#include "../interface/audio_codec_if.h" #ifdef CONFIG_CODEC_ES8311_SUPPORT #include "../device/include/es8311_codec.h" @@ -43,63 +43,67 @@ #endif #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -/** - * @brief Codec I2C configuration - */ -typedef struct { - uint8_t port; /*!< I2C port, this port need pre-installed by other modules */ - uint8_t addr; /*!< I2C address, default address can be gotten from codec head files */ - void *bus_handle; /*!< I2C Master bus handle (for IDFv5.3 or higher version) */ -} audio_codec_i2c_cfg_t; + /** + * @brief Codec I2C configuration + */ + typedef struct + { + uint8_t port; /*!< I2C port, this port need pre-installed by other modules */ + uint8_t addr; /*!< I2C address, default address can be gotten from codec head files */ + void* bus_handle; /*!< I2C Master bus handle (for IDFv5.3 or higher version) */ + } audio_codec_i2c_cfg_t; -/** - * @brief Codec I2S configuration - */ -typedef struct { - uint8_t port; /*!< I2S port, this port need pre-installed by other modules */ - void *rx_handle; /*!< I2S rx handle, need provide on IDF 5.x */ - void *tx_handle; /*!< I2S tx handle, need provide on IDF 5.x */ -} audio_codec_i2s_cfg_t; + /** + * @brief Codec I2S configuration + */ + typedef struct + { + uint8_t port; /*!< I2S port, this port need pre-installed by other modules */ + void* rx_handle; /*!< I2S rx handle, need provide on IDF 5.x */ + void* tx_handle; /*!< I2S tx handle, need provide on IDF 5.x */ + } audio_codec_i2s_cfg_t; -/** - * @brief Codec SPI configuration - */ -typedef struct { - uint8_t spi_port; /*!< SPI port, this port need pre-installed by other modules */ - int16_t cs_pin; /*!< SPI CS GPIO pin setting */ - int clock_speed; /*!< SPI clock unit hz (use 10MHZif set to 0)*/ -} audio_codec_spi_cfg_t; + /** + * @brief Codec SPI configuration + */ + typedef struct + { + uint8_t spi_port; /*!< SPI port, this port need pre-installed by other modules */ + int16_t cs_pin; /*!< SPI CS GPIO pin setting */ + int clock_speed; /*!< SPI clock unit hz (use 10MHZif set to 0)*/ + } audio_codec_spi_cfg_t; -/** - * @brief Get default codec GPIO interface - * @return NULL: Failed - * Others: Codec GPIO interface - */ -const audio_codec_gpio_if_t *audio_codec_new_gpio(void); + /** + * @brief Get default codec GPIO interface + * @return NULL: Failed + * Others: Codec GPIO interface + */ + const audio_codec_gpio_if_t* audio_codec_new_gpio(void); -/** - * @brief Get default SPI control interface - * @return NULL: Failed - * Others: SPI control interface - */ -const audio_codec_ctrl_if_t *audio_codec_new_spi_ctrl(audio_codec_spi_cfg_t *spi_cfg); + /** + * @brief Get default SPI control interface + * @return NULL: Failed + * Others: SPI control interface + */ + const audio_codec_ctrl_if_t* audio_codec_new_spi_ctrl(audio_codec_spi_cfg_t* spi_cfg); -/** - * @brief Get default I2C control interface - * @return NULL: Failed - * Others: I2C control interface - */ -const audio_codec_ctrl_if_t *audio_codec_new_i2c_ctrl(audio_codec_i2c_cfg_t *i2c_cfg); + /** + * @brief Get default I2C control interface + * @return NULL: Failed + * Others: I2C control interface + */ + const audio_codec_ctrl_if_t* audio_codec_new_i2c_ctrl(audio_codec_i2c_cfg_t* i2c_cfg); -/** - * @brief Get default I2S data interface - * @return NULL: Failed - * Others: I2S data interface - */ -const audio_codec_data_if_t *audio_codec_new_i2s_data(audio_codec_i2s_cfg_t *i2s_cfg); + /** + * @brief Get default I2S data interface + * @return NULL: Failed + * Others: I2S data interface + */ + const audio_codec_data_if_t* audio_codec_new_i2s_data(audio_codec_i2s_cfg_t* i2s_cfg); #ifdef __cplusplus } diff --git a/src/audio/codec/include/esp_codec_dev_os.h b/src/audio/codec/include/esp_codec_dev_os.h index 089df14c..73801fae 100644 --- a/src/audio/codec/include/esp_codec_dev_os.h +++ b/src/audio/codec/include/esp_codec_dev_os.h @@ -7,14 +7,15 @@ #define _ESP_CODEC_DEV_OS_H_ #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -/** - * @brief Sleep in milliseconds - * @param ms: Sleep time (unit ms) - */ -void esp_codec_dev_sleep(int ms); + /** + * @brief Sleep in milliseconds + * @param ms: Sleep time (unit ms) + */ + void esp_codec_dev_sleep(int ms); #ifdef __cplusplus } diff --git a/src/audio/codec/include/esp_codec_dev_types.h b/src/audio/codec/include/esp_codec_dev_types.h index 8499d347..4e19ee28 100644 --- a/src/audio/codec/include/esp_codec_dev_types.h +++ b/src/audio/codec/include/esp_codec_dev_types.h @@ -6,71 +6,75 @@ #ifndef _ESP_CODEC_DEV_TYPES_H_ #define _ESP_CODEC_DEV_TYPES_H_ -#include -#include #include "esp_err.h" +#include +#include #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -#define ESP_CODEC_DEV_VERSION "1.3.1" +#define ESP_CODEC_DEV_VERSION "1.3.1" /** * @brief Define error number of codec device module * Inherit from `esp_err_t` */ -#define ESP_CODEC_DEV_OK (0) -#define ESP_CODEC_DEV_DRV_ERR (ESP_FAIL) +#define ESP_CODEC_DEV_OK (0) +#define ESP_CODEC_DEV_DRV_ERR (ESP_FAIL) #define ESP_CODEC_DEV_INVALID_ARG (ESP_ERR_INVALID_ARG) -#define ESP_CODEC_DEV_NO_MEM (ESP_ERR_NO_MEM) +#define ESP_CODEC_DEV_NO_MEM (ESP_ERR_NO_MEM) #define ESP_CODEC_DEV_NOT_SUPPORT (ESP_ERR_NOT_SUPPORTED) -#define ESP_CODEC_DEV_NOT_FOUND (ESP_ERR_NOT_FOUND) +#define ESP_CODEC_DEV_NOT_FOUND (ESP_ERR_NOT_FOUND) #define ESP_CODEC_DEV_WRONG_STATE (ESP_ERR_INVALID_STATE) -#define ESP_CODEC_DEV_WRITE_FAIL (0x10D) -#define ESP_CODEC_DEV_READ_FAIL (0x10E) +#define ESP_CODEC_DEV_WRITE_FAIL (0x10D) +#define ESP_CODEC_DEV_READ_FAIL (0x10E) #define ESP_CODEC_DEV_MAKE_CHANNEL_MASK(channel) ((uint16_t)1 << (channel)) -/** - * @brief Codec Device type - */ -typedef enum { - ESP_CODEC_DEV_TYPE_NONE, - ESP_CODEC_DEV_TYPE_IN = (1 << 0), /*!< Codec input device like ADC (capture data from microphone) */ - ESP_CODEC_DEV_TYPE_OUT = (1 << 1), /*!< Codec output device like DAC (output analog signal to speaker) */ - ESP_CODEC_DEV_TYPE_IN_OUT = (ESP_CODEC_DEV_TYPE_IN | ESP_CODEC_DEV_TYPE_OUT), /*!< Codec input and output device */ -} esp_codec_dev_type_t; + /** + * @brief Codec Device type + */ + typedef enum + { + ESP_CODEC_DEV_TYPE_NONE, + ESP_CODEC_DEV_TYPE_IN = (1 << 0), /*!< Codec input device like ADC (capture data from microphone) */ + ESP_CODEC_DEV_TYPE_OUT = (1 << 1), /*!< Codec output device like DAC (output analog signal to speaker) */ + ESP_CODEC_DEV_TYPE_IN_OUT = (ESP_CODEC_DEV_TYPE_IN | ESP_CODEC_DEV_TYPE_OUT), /*!< Codec input and output device */ + } esp_codec_dev_type_t; -/** - * @brief Codec audio sample information - * Notes: channel_mask is used to filter wanted channels in driver side - * when set to 0, default filter all channels - * when channel is 2, can filter channel 0 (set to 1) or channel 1 (set to 2) - * when channel is 4, can filter either 3,2 channels or 1 channel - */ -typedef struct { - uint8_t bits_per_sample; /*!< Bit lengths of one channel data */ - uint8_t channel; /*!< Channels of sample */ - uint16_t channel_mask; /*!< Channel mask indicate which channel to be selected */ - uint32_t sample_rate; /*!< Sample rate of sample */ - int mclk_multiple; /*!< The multiple of MCLK to the sample rate - If value is 0, mclk = sample_rate * 256 - If bits_per_sample is 24bit, mclk_multiple should be the multiple of 3 - */ -} esp_codec_dev_sample_info_t; + /** + * @brief Codec audio sample information + * Notes: channel_mask is used to filter wanted channels in driver side + * when set to 0, default filter all channels + * when channel is 2, can filter channel 0 (set to 1) or channel 1 (set to 2) + * when channel is 4, can filter either 3,2 channels or 1 channel + */ + typedef struct + { + uint8_t bits_per_sample; /*!< Bit lengths of one channel data */ + uint8_t channel; /*!< Channels of sample */ + uint16_t channel_mask; /*!< Channel mask indicate which channel to be selected */ + uint32_t sample_rate; /*!< Sample rate of sample */ + int mclk_multiple; /*!< The multiple of MCLK to the sample rate + If value is 0, mclk = sample_rate * 256 + If bits_per_sample is 24bit, mclk_multiple should be the multiple of 3 + */ + } esp_codec_dev_sample_info_t; -/** - * @brief Codec working mode - */ -typedef enum { - ESP_CODEC_DEV_WORK_MODE_NONE, - ESP_CODEC_DEV_WORK_MODE_ADC = (1 << 0), /*!< Enable ADC, only support input */ - ESP_CODEC_DEV_WORK_MODE_DAC = (1 << 1), /*!< Enable DAC, only support output */ - ESP_CODEC_DEV_WORK_MODE_BOTH = - (ESP_CODEC_DEV_WORK_MODE_ADC | ESP_CODEC_DEV_WORK_MODE_DAC), /*!< Support both DAC and ADC */ - ESP_CODEC_DEV_WORK_MODE_LINE = (1 << 2), /*!< Line mode */ -} esp_codec_dec_work_mode_t; + /** + * @brief Codec working mode + */ + typedef enum + { + ESP_CODEC_DEV_WORK_MODE_NONE, + ESP_CODEC_DEV_WORK_MODE_ADC = (1 << 0), /*!< Enable ADC, only support input */ + ESP_CODEC_DEV_WORK_MODE_DAC = (1 << 1), /*!< Enable DAC, only support output */ + ESP_CODEC_DEV_WORK_MODE_BOTH = + (ESP_CODEC_DEV_WORK_MODE_ADC | ESP_CODEC_DEV_WORK_MODE_DAC), /*!< Support both DAC and ADC */ + ESP_CODEC_DEV_WORK_MODE_LINE = (1 << 2), /*!< Line mode */ + } esp_codec_dec_work_mode_t; #ifdef __cplusplus } diff --git a/src/audio/codec/include/esp_codec_dev_vol.h b/src/audio/codec/include/esp_codec_dev_vol.h index 2ec202b5..1f2f2204 100644 --- a/src/audio/codec/include/esp_codec_dev_vol.h +++ b/src/audio/codec/include/esp_codec_dev_vol.h @@ -9,95 +9,100 @@ #include "esp_codec_dev_types.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -/** - * @brief Codec volume map to decibel - */ -typedef struct { - int vol; /*!< Volume value */ - float db_value; /*!< Volume decibel value */ -} esp_codec_dev_vol_map_t; + /** + * @brief Codec volume map to decibel + */ + typedef struct + { + int vol; /*!< Volume value */ + float db_value; /*!< Volume decibel value */ + } esp_codec_dev_vol_map_t; -/** - * @brief Codec volume range setting - */ -typedef struct { - esp_codec_dev_vol_map_t min_vol; /*!< Minimum volume setting */ - esp_codec_dev_vol_map_t max_vol; /*!< Maximum volume setting */ -} esp_codec_dev_vol_range_t; + /** + * @brief Codec volume range setting + */ + typedef struct + { + esp_codec_dev_vol_map_t min_vol; /*!< Minimum volume setting */ + esp_codec_dev_vol_map_t max_vol; /*!< Maximum volume setting */ + } esp_codec_dev_vol_range_t; -/** - * @brief Codec volume curve configuration - */ -typedef struct { - esp_codec_dev_vol_map_t *vol_map; /*!< Point of volume curve */ - int count; /*!< Curve point number */ -} esp_codec_dev_vol_curve_t; + /** + * @brief Codec volume curve configuration + */ + typedef struct + { + esp_codec_dev_vol_map_t* vol_map; /*!< Point of volume curve */ + int count; /*!< Curve point number */ + } esp_codec_dev_vol_curve_t; -/* - * Audio gain overview: - * |----------------Software Gain--------------|--Hardware Gain--| - * - * |--------------------| |--------------------| |------------------| |---------| |----------------| - * | Digital Audio Data |-->| Audio Process Gain |-->| Codec DAC Volume |-->| PA Gain |-->| Speaker Output | - * |--------------------| |--------------------| |------------------| |---------| |----------------| - * - * Final speaker loudness is affected by both Software Gain and Hardware Gain. - * - * Software Gain (Adjustable): - * Audio Process Gain: Gain by audio post processor, such as ALC, AGC, DRC target MAX Gain. - * Codec DAC Volume: The audio codec DAC volume control, such as ES8311 DAC_Volume control register. - * - * Hardware Gain (Fixed): - * PA Gain: The speaker power amplifier Gain, which is determined by the hardware circuit. - * - * The speaker playback route gain (Audio Process Gain + Codec DAC Volume + PA Gain) needs to ensure that the - * speaker PA output is not saturated and exceeds the speaker rated power. We define the maximum route gain - * as MAX_GAIN. To ensure the speaker PA output is not saturated, MAX_GAIN can be calculated simply by the formula. - * MAX_GAIN = 20 * log(Vpa/Vdac) - * Vpa: PA power supply - * Vdac: Codec DAC power supply - * e.g., Vpa = 5V, Vdac = 3.3V, then MAX_GAIN = 20 * log(5/3.3) = 3.6 dB. - * If the speaker rated power is lower than the speaker PA MAX power, MAX_GAIN should be defined according to - * the speaker rated power. - */ + /* + * Audio gain overview: + * |----------------Software Gain--------------|--Hardware Gain--| + * + * |--------------------| |--------------------| |------------------| |---------| |----------------| + * | Digital Audio Data |-->| Audio Process Gain |-->| Codec DAC Volume |-->| PA Gain |-->| Speaker Output | + * |--------------------| |--------------------| |------------------| |---------| |----------------| + * + * Final speaker loudness is affected by both Software Gain and Hardware Gain. + * + * Software Gain (Adjustable): + * Audio Process Gain: Gain by audio post processor, such as ALC, AGC, DRC target MAX Gain. + * Codec DAC Volume: The audio codec DAC volume control, such as ES8311 DAC_Volume control register. + * + * Hardware Gain (Fixed): + * PA Gain: The speaker power amplifier Gain, which is determined by the hardware circuit. + * + * The speaker playback route gain (Audio Process Gain + Codec DAC Volume + PA Gain) needs to ensure that the + * speaker PA output is not saturated and exceeds the speaker rated power. We define the maximum route gain + * as MAX_GAIN. To ensure the speaker PA output is not saturated, MAX_GAIN can be calculated simply by the formula. + * MAX_GAIN = 20 * log(Vpa/Vdac) + * Vpa: PA power supply + * Vdac: Codec DAC power supply + * e.g., Vpa = 5V, Vdac = 3.3V, then MAX_GAIN = 20 * log(5/3.3) = 3.6 dB. + * If the speaker rated power is lower than the speaker PA MAX power, MAX_GAIN should be defined according to + * the speaker rated power. + */ -/** - * @brief Codec hardware gain setting - * Notes: Hardware gain generally consists of 2 parts - * 1. Codec DAC voltage and PA voltage to get MAX_GAIN - * 2. PA gain can be calculate by connected resistors - */ -typedef struct { - float pa_voltage; /*!< PA voltage: typical 5.0v */ - float codec_dac_voltage; /*!< Codec chip DAC voltage: typical 3.3v */ - float pa_gain; /*!< PA amplify coefficient in decibel unit */ -} esp_codec_dev_hw_gain_t; + /** + * @brief Codec hardware gain setting + * Notes: Hardware gain generally consists of 2 parts + * 1. Codec DAC voltage and PA voltage to get MAX_GAIN + * 2. PA gain can be calculate by connected resistors + */ + typedef struct + { + float pa_voltage; /*!< PA voltage: typical 5.0v */ + float codec_dac_voltage; /*!< Codec chip DAC voltage: typical 3.3v */ + float pa_gain; /*!< PA amplify coefficient in decibel unit */ + } esp_codec_dev_hw_gain_t; -/** - * @brief Convert decibel value to register settings - * @param vol_range: Volume range - * @param db: Volume decibel - * @return Codec register value - */ -int esp_codec_dev_vol_calc_reg(const esp_codec_dev_vol_range_t *vol_range, float db); + /** + * @brief Convert decibel value to register settings + * @param vol_range: Volume range + * @param db: Volume decibel + * @return Codec register value + */ + int esp_codec_dev_vol_calc_reg(const esp_codec_dev_vol_range_t* vol_range, float db); -/** - * @brief Convert codec register setting to decibel value - * @param vol_range: Volume range - * @param vol: Volume register setting - * @return Codec volume in decibel unit - */ -float esp_codec_dev_vol_calc_db(const esp_codec_dev_vol_range_t *vol_range, int vol); + /** + * @brief Convert codec register setting to decibel value + * @param vol_range: Volume range + * @param vol: Volume register setting + * @return Codec volume in decibel unit + */ + float esp_codec_dev_vol_calc_db(const esp_codec_dev_vol_range_t* vol_range, int vol); -/** - * @brief Calculate codec hardware gain value - * @param hw_gain: Hardware gain settings - * @return Codec hardware gain in decibel unit - */ -float esp_codec_dev_col_calc_hw_gain(esp_codec_dev_hw_gain_t* hw_gain); + /** + * @brief Calculate codec hardware gain value + * @param hw_gain: Hardware gain settings + * @return Codec hardware gain in decibel unit + */ + float esp_codec_dev_col_calc_hw_gain(esp_codec_dev_hw_gain_t* hw_gain); #ifdef __cplusplus } diff --git a/src/audio/codec/interface/audio_codec_ctrl_if.h b/src/audio/codec/interface/audio_codec_ctrl_if.h index dd41ff02..7e20fa89 100644 --- a/src/audio/codec/interface/audio_codec_ctrl_if.h +++ b/src/audio/codec/interface/audio_codec_ctrl_if.h @@ -9,31 +9,33 @@ #include "../include/esp_codec_dev_types.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -typedef struct audio_codec_ctrl_if_t audio_codec_ctrl_if_t; + typedef struct audio_codec_ctrl_if_t audio_codec_ctrl_if_t; -/** - * @brief Audio codec control interface structure - */ -struct audio_codec_ctrl_if_t { - int (*open)(const audio_codec_ctrl_if_t *ctrl, void *cfg, int cfg_size); /*!< Open codec control interface */ - bool (*is_open)(const audio_codec_ctrl_if_t *ctrl); /*!< Check whether codec control opened or not */ - int (*read_reg)(const audio_codec_ctrl_if_t *ctrl, - int reg, int reg_len, void *data, int data_len); /*!< Read data from codec device register */ - int (*write_reg)(const audio_codec_ctrl_if_t *ctrl, - int reg, int reg_len, void *data, int data_len); /*!< Write data to codec device register */ - int (*close)(const audio_codec_ctrl_if_t *ctrl); /*!< Close codec control interface */ -}; + /** + * @brief Audio codec control interface structure + */ + struct audio_codec_ctrl_if_t + { + int (*open)(const audio_codec_ctrl_if_t* ctrl, void* cfg, int cfg_size); /*!< Open codec control interface */ + bool (*is_open)(const audio_codec_ctrl_if_t* ctrl); /*!< Check whether codec control opened or not */ + int (*read_reg)(const audio_codec_ctrl_if_t* ctrl, + int reg, int reg_len, void* data, int data_len); /*!< Read data from codec device register */ + int (*write_reg)(const audio_codec_ctrl_if_t* ctrl, + int reg, int reg_len, void* data, int data_len); /*!< Write data to codec device register */ + int (*close)(const audio_codec_ctrl_if_t* ctrl); /*!< Close codec control interface */ + }; -/** - * @brief Delete codec control interface instance - * @param ctrl_if: Audio codec interface - * @return ESP_CODEC_DEV_OK: Delete success - * ESP_CODEC_DEV_INVALID_ARG: Input is NULL pointer - */ -int audio_codec_delete_ctrl_if(const audio_codec_ctrl_if_t *ctrl_if); + /** + * @brief Delete codec control interface instance + * @param ctrl_if: Audio codec interface + * @return ESP_CODEC_DEV_OK: Delete success + * ESP_CODEC_DEV_INVALID_ARG: Input is NULL pointer + */ + int audio_codec_delete_ctrl_if(const audio_codec_ctrl_if_t* ctrl_if); #ifdef __cplusplus } diff --git a/src/audio/codec/interface/audio_codec_data_if.h b/src/audio/codec/interface/audio_codec_data_if.h index 59565178..dbbc8f44 100644 --- a/src/audio/codec/interface/audio_codec_data_if.h +++ b/src/audio/codec/interface/audio_codec_data_if.h @@ -9,35 +9,37 @@ #include "../include/esp_codec_dev_types.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -typedef struct audio_codec_data_if_t audio_codec_data_if_t; + typedef struct audio_codec_data_if_t audio_codec_data_if_t; -/** - * @brief Audio codec data interface structure - */ -struct audio_codec_data_if_t { - int (*open)(const audio_codec_data_if_t *h, void *data_cfg, int cfg_size); /*!< Open data interface */ - bool (*is_open)(const audio_codec_data_if_t *h); /*!< Check whether data interface is opened */ - int (*enable)(const audio_codec_data_if_t *h, - esp_codec_dev_type_t dev_type, - bool enable); /*!< Enable input or output channel */ - int (*set_fmt)(const audio_codec_data_if_t *h, - esp_codec_dev_type_t dev_type, - esp_codec_dev_sample_info_t *fs); /*!< Set audio format to data interface */ - int (*read)(const audio_codec_data_if_t *h, uint8_t *data, int size); /*!< Read data from data interface */ - int (*write)(const audio_codec_data_if_t *h, uint8_t *data, int size); /*!< Write data to data interface */ - int (*close)(const audio_codec_data_if_t *h); /*!< Close data interface */ -}; + /** + * @brief Audio codec data interface structure + */ + struct audio_codec_data_if_t + { + int (*open)(const audio_codec_data_if_t* h, void* data_cfg, int cfg_size); /*!< Open data interface */ + bool (*is_open)(const audio_codec_data_if_t* h); /*!< Check whether data interface is opened */ + int (*enable)(const audio_codec_data_if_t* h, + esp_codec_dev_type_t dev_type, + bool enable); /*!< Enable input or output channel */ + int (*set_fmt)(const audio_codec_data_if_t* h, + esp_codec_dev_type_t dev_type, + esp_codec_dev_sample_info_t* fs); /*!< Set audio format to data interface */ + int (*read)(const audio_codec_data_if_t* h, uint8_t* data, int size); /*!< Read data from data interface */ + int (*write)(const audio_codec_data_if_t* h, uint8_t* data, int size); /*!< Write data to data interface */ + int (*close)(const audio_codec_data_if_t* h); /*!< Close data interface */ + }; -/** - * @brief Delete codec data interface instance - * @param data_if: Codec data interface - * @return ESP_CODEC_DEV_OK: Delete success - * ESP_CODEC_DEV_INVALID_ARG: Input is NULL pointer - */ -int audio_codec_delete_data_if(const audio_codec_data_if_t *data_if); + /** + * @brief Delete codec data interface instance + * @param data_if: Codec data interface + * @return ESP_CODEC_DEV_OK: Delete success + * ESP_CODEC_DEV_INVALID_ARG: Input is NULL pointer + */ + int audio_codec_delete_data_if(const audio_codec_data_if_t* data_if); #ifdef __cplusplus } diff --git a/src/audio/codec/interface/audio_codec_gpio_if.h b/src/audio/codec/interface/audio_codec_gpio_if.h index 56b6b96d..1548682b 100644 --- a/src/audio/codec/interface/audio_codec_gpio_if.h +++ b/src/audio/codec/interface/audio_codec_gpio_if.h @@ -6,46 +6,50 @@ #ifndef _AUDIO_CODEC_GPIO_IF_H_ #define _AUDIO_CODEC_GPIO_IF_H_ -#include #include +#include #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -/** - * @brief GPIO drive mode - */ -typedef enum { - AUDIO_GPIO_MODE_FLOAT, /*!< Float */ - AUDIO_GPIO_MODE_PULL_UP = (1 << 0), /*!< Internally pullup */ - AUDIO_GPIO_MODE_PULL_DOWN = (1 << 1), /*!< Internally pulldown */ -} audio_gpio_mode_t; + /** + * @brief GPIO drive mode + */ + typedef enum + { + AUDIO_GPIO_MODE_FLOAT, /*!< Float */ + AUDIO_GPIO_MODE_PULL_UP = (1 << 0), /*!< Internally pullup */ + AUDIO_GPIO_MODE_PULL_DOWN = (1 << 1), /*!< Internally pulldown */ + } audio_gpio_mode_t; -/** - * @brief GPIO direction type - */ -typedef enum { - AUDIO_GPIO_DIR_OUT, /*!< Output GPIO */ - AUDIO_GPIO_DIR_IN, /*!< Input GPIO */ -} audio_gpio_dir_t; + /** + * @brief GPIO direction type + */ + typedef enum + { + AUDIO_GPIO_DIR_OUT, /*!< Output GPIO */ + AUDIO_GPIO_DIR_IN, /*!< Input GPIO */ + } audio_gpio_dir_t; -/** - * @brief Codec GPIO interface structure - */ -typedef struct { - int (*setup)(int16_t gpio, audio_gpio_dir_t dir, audio_gpio_mode_t mode); /*!< Setup GPIO */ - int (*set)(int16_t gpio, bool high); /*!< Set GPIO level */ - bool (*get)(int16_t gpio); /*!< Get GPIO level */ -} audio_codec_gpio_if_t; + /** + * @brief Codec GPIO interface structure + */ + typedef struct + { + int (*setup)(int16_t gpio, audio_gpio_dir_t dir, audio_gpio_mode_t mode); /*!< Setup GPIO */ + int (*set)(int16_t gpio, bool high); /*!< Set GPIO level */ + bool (*get)(int16_t gpio); /*!< Get GPIO level */ + } audio_codec_gpio_if_t; -/** - * @brief Delete GPIO interface instance - * @param gpio_if: GPIO interface - * @return ESP_CODEC_DEV_OK: Delete success - * ESP_CODEC_DEV_INVALID_ARG: Input is NULL pointer - */ -int audio_codec_delete_gpio_if(const audio_codec_gpio_if_t *gpio_if); + /** + * @brief Delete GPIO interface instance + * @param gpio_if: GPIO interface + * @return ESP_CODEC_DEV_OK: Delete success + * ESP_CODEC_DEV_INVALID_ARG: Input is NULL pointer + */ + int audio_codec_delete_gpio_if(const audio_codec_gpio_if_t* gpio_if); #ifdef __cplusplus } diff --git a/src/audio/codec/interface/audio_codec_if.h b/src/audio/codec/interface/audio_codec_if.h index 141a326a..dab753f9 100644 --- a/src/audio/codec/interface/audio_codec_if.h +++ b/src/audio/codec/interface/audio_codec_if.h @@ -9,38 +9,40 @@ #include "../include/esp_codec_dev_types.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -typedef struct audio_codec_if_t audio_codec_if_t; + typedef struct audio_codec_if_t audio_codec_if_t; -/** - * @brief Structure for codec interface - */ -struct audio_codec_if_t { - int (*open)(const audio_codec_if_t *h, void *cfg, int cfg_size); /*!< Open codec */ - bool (*is_open)(const audio_codec_if_t *h); /*!< Check whether codec is opened */ - int (*enable)(const audio_codec_if_t *h, bool enable); /*!< Enable codec, when codec disabled it can use less power if provided */ - int (*set_fs)(const audio_codec_if_t *h, esp_codec_dev_sample_info_t *fs); /*!< Set audio format to codec */ - int (*mute)(const audio_codec_if_t *h, bool mute); /*!< Mute and un-mute DAC output */ - int (*set_vol)(const audio_codec_if_t *h, float db); /*!< Set DAC volume in decibel */ - int (*set_mic_gain)(const audio_codec_if_t *h, float db); /*!< Set microphone gain in decibel */ - int (*set_mic_channel_gain)(const audio_codec_if_t *h, - uint16_t channel_mask, float db); /*!< Set microphone gain in decibel by channel */ - int (*mute_mic)(const audio_codec_if_t *h, bool mute); /*!< Mute and un-mute microphone */ - int (*set_reg)(const audio_codec_if_t *h, int reg, int value); /*!< Set register value to codec */ - int (*get_reg)(const audio_codec_if_t *h, int reg, int *value); /*!< Get register value from codec */ - void (*dump_reg)(const audio_codec_if_t *h); /*!< Dump all register settings */ - int (*close)(const audio_codec_if_t *h); /*!< Close codec */ -}; + /** + * @brief Structure for codec interface + */ + struct audio_codec_if_t + { + int (*open)(const audio_codec_if_t* h, void* cfg, int cfg_size); /*!< Open codec */ + bool (*is_open)(const audio_codec_if_t* h); /*!< Check whether codec is opened */ + int (*enable)(const audio_codec_if_t* h, bool enable); /*!< Enable codec, when codec disabled it can use less power if provided */ + int (*set_fs)(const audio_codec_if_t* h, esp_codec_dev_sample_info_t* fs); /*!< Set audio format to codec */ + int (*mute)(const audio_codec_if_t* h, bool mute); /*!< Mute and un-mute DAC output */ + int (*set_vol)(const audio_codec_if_t* h, float db); /*!< Set DAC volume in decibel */ + int (*set_mic_gain)(const audio_codec_if_t* h, float db); /*!< Set microphone gain in decibel */ + int (*set_mic_channel_gain)(const audio_codec_if_t* h, + uint16_t channel_mask, float db); /*!< Set microphone gain in decibel by channel */ + int (*mute_mic)(const audio_codec_if_t* h, bool mute); /*!< Mute and un-mute microphone */ + int (*set_reg)(const audio_codec_if_t* h, int reg, int value); /*!< Set register value to codec */ + int (*get_reg)(const audio_codec_if_t* h, int reg, int* value); /*!< Get register value from codec */ + void (*dump_reg)(const audio_codec_if_t* h); /*!< Dump all register settings */ + int (*close)(const audio_codec_if_t* h); /*!< Close codec */ + }; -/** - * @brief Delete codec interface instance - * @param codec_if: Codec interface - * @return ESP_CODEC_DEV_OK: Delete success - * ESP_CODEC_DEV_INVALID_ARG: Input is NULL pointer - */ -int audio_codec_delete_codec_if(const audio_codec_if_t *codec_if); + /** + * @brief Delete codec interface instance + * @param codec_if: Codec interface + * @return ESP_CODEC_DEV_OK: Delete success + * ESP_CODEC_DEV_INVALID_ARG: Input is NULL pointer + */ + int audio_codec_delete_codec_if(const audio_codec_if_t* codec_if); #ifdef __cplusplus } diff --git a/src/audio/codec/interface/audio_codec_vol_if.h b/src/audio/codec/interface/audio_codec_vol_if.h index 336f896f..7cc19fdf 100644 --- a/src/audio/codec/interface/audio_codec_vol_if.h +++ b/src/audio/codec/interface/audio_codec_vol_if.h @@ -9,30 +9,32 @@ #include "../include/esp_codec_dev_types.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -typedef struct audio_codec_vol_if_t audio_codec_vol_if_t; + typedef struct audio_codec_vol_if_t audio_codec_vol_if_t; -/** - * @brief Structure for volume interface - */ -struct audio_codec_vol_if_t { - int (*open)(const audio_codec_vol_if_t *h, - esp_codec_dev_sample_info_t *fs, int fade_time); /*!< Open for software volume processor */ - int (*set_vol)(const audio_codec_vol_if_t *h, float db_value); /*!< Set volume in decibel unit */ - int (*process)(const audio_codec_vol_if_t *h, - uint8_t *in, int len, uint8_t *out, int out_len); /*!< Process data */ - int (*close)(const audio_codec_vol_if_t *h); /*!< Close volume processor */ -}; + /** + * @brief Structure for volume interface + */ + struct audio_codec_vol_if_t + { + int (*open)(const audio_codec_vol_if_t* h, + esp_codec_dev_sample_info_t* fs, int fade_time); /*!< Open for software volume processor */ + int (*set_vol)(const audio_codec_vol_if_t* h, float db_value); /*!< Set volume in decibel unit */ + int (*process)(const audio_codec_vol_if_t* h, + uint8_t* in, int len, uint8_t* out, int out_len); /*!< Process data */ + int (*close)(const audio_codec_vol_if_t* h); /*!< Close volume processor */ + }; -/** - * @brief Delete volume interface instance - * @param vol_if: Volume interface - * @return ESP_CODEC_DEV_OK: Delete success - * ESP_CODEC_DEV_INVALID_ARG: Input is NULL pointer - */ -int audio_codec_delete_vol_if(const audio_codec_vol_if_t *vol_if); + /** + * @brief Delete volume interface instance + * @param vol_if: Volume interface + * @return ESP_CODEC_DEV_OK: Delete success + * ESP_CODEC_DEV_INVALID_ARG: Input is NULL pointer + */ + int audio_codec_delete_vol_if(const audio_codec_vol_if_t* vol_if); #ifdef __cplusplus } diff --git a/src/audio/codec/platform/audio_codec_ctrl_i2c_arduino.cpp b/src/audio/codec/platform/audio_codec_ctrl_i2c_arduino.cpp index dac0015b..726d8836 100644 --- a/src/audio/codec/platform/audio_codec_ctrl_i2c_arduino.cpp +++ b/src/audio/codec/platform/audio_codec_ctrl_i2c_arduino.cpp @@ -4,30 +4,33 @@ * @license MIT * @copyright Copyright (c) 2025 ShenZhen XinYuan Electronic Technology Co., Ltd * @date 2025-03-02 - * + * */ #ifdef ARDUINO #include #include -#include "../interface/audio_codec_ctrl_if.h" #include "../include/esp_codec_dev_defaults.h" +#include "../interface/audio_codec_ctrl_if.h" -typedef struct { - audio_codec_ctrl_if_t base; - bool is_open; - uint8_t addr; - TwoWire *wire; +typedef struct +{ + audio_codec_ctrl_if_t base; + bool is_open; + uint8_t addr; + TwoWire* wire; } i2c_ctrl_t; -static int _i2c_ctrl_open(const audio_codec_ctrl_if_t *ctrl, void *cfg, int cfg_size) +static int _i2c_ctrl_open(const audio_codec_ctrl_if_t* ctrl, void* cfg, int cfg_size) { - if (ctrl == NULL || cfg == NULL || cfg_size != sizeof(audio_codec_i2c_cfg_t)) { + if (ctrl == NULL || cfg == NULL || cfg_size != sizeof(audio_codec_i2c_cfg_t)) + { return ESP_CODEC_DEV_INVALID_ARG; } - i2c_ctrl_t *i2c_ctrl = (i2c_ctrl_t *) ctrl; - audio_codec_i2c_cfg_t *i2c_cfg = (audio_codec_i2c_cfg_t *) cfg; - if (i2c_cfg->bus_handle == NULL) { + i2c_ctrl_t* i2c_ctrl = (i2c_ctrl_t*)ctrl; + audio_codec_i2c_cfg_t* i2c_cfg = (audio_codec_i2c_cfg_t*)cfg; + if (i2c_cfg->bus_handle == NULL) + { return ESP_ERR_INVALID_ARG; } i2c_ctrl->addr = i2c_cfg->addr; @@ -35,25 +38,28 @@ static int _i2c_ctrl_open(const audio_codec_ctrl_if_t *ctrl, void *cfg, int cfg_ i2c_ctrl->wire->begin(); i2c_ctrl->wire->beginTransmission(i2c_ctrl->addr); uint8_t ret = i2c_ctrl->wire->endTransmission(); - return ret == 0 ? ESP_OK : ESP_FAIL; + return ret == 0 ? ESP_OK : ESP_FAIL; } -static bool _i2c_ctrl_is_open(const audio_codec_ctrl_if_t *ctrl) +static bool _i2c_ctrl_is_open(const audio_codec_ctrl_if_t* ctrl) { - if (ctrl) { - i2c_ctrl_t *i2c_ctrl = (i2c_ctrl_t *) ctrl; + if (ctrl) + { + i2c_ctrl_t* i2c_ctrl = (i2c_ctrl_t*)ctrl; return i2c_ctrl->is_open; } return false; } -static int _i2c_ctrl_read_reg(const audio_codec_ctrl_if_t *ctrl, int addr, int addr_len, void *data, int data_len) +static int _i2c_ctrl_read_reg(const audio_codec_ctrl_if_t* ctrl, int addr, int addr_len, void* data, int data_len) { - if (ctrl == NULL || data == NULL) { + if (ctrl == NULL || data == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } - i2c_ctrl_t *i2c_ctrl = (i2c_ctrl_t *) ctrl; - if (i2c_ctrl->is_open == false) { + i2c_ctrl_t* i2c_ctrl = (i2c_ctrl_t*)ctrl; + if (i2c_ctrl->is_open == false) + { return ESP_CODEC_DEV_WRONG_STATE; } esp_err_t ret = ESP_OK; @@ -65,13 +71,15 @@ static int _i2c_ctrl_read_reg(const audio_codec_ctrl_if_t *ctrl, int addr, int a return ret ? ESP_CODEC_DEV_READ_FAIL : ESP_CODEC_DEV_OK; } -static int _i2c_ctrl_write_reg(const audio_codec_ctrl_if_t *ctrl, int addr, int addr_len, void *data, int data_len) +static int _i2c_ctrl_write_reg(const audio_codec_ctrl_if_t* ctrl, int addr, int addr_len, void* data, int data_len) { - i2c_ctrl_t *i2c_ctrl = (i2c_ctrl_t *) ctrl; - if (ctrl == NULL || data == NULL) { + i2c_ctrl_t* i2c_ctrl = (i2c_ctrl_t*)ctrl; + if (ctrl == NULL || data == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } - if (i2c_ctrl->is_open == false) { + if (i2c_ctrl->is_open == false) + { return ESP_CODEC_DEV_WRONG_STATE; } esp_err_t ret = ESP_OK; @@ -82,24 +90,27 @@ static int _i2c_ctrl_write_reg(const audio_codec_ctrl_if_t *ctrl, int addr, int return ret ? ESP_CODEC_DEV_WRITE_FAIL : ESP_CODEC_DEV_OK; } -static int _i2c_ctrl_close(const audio_codec_ctrl_if_t *ctrl) +static int _i2c_ctrl_close(const audio_codec_ctrl_if_t* ctrl) { - if (ctrl == NULL) { + if (ctrl == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } - i2c_ctrl_t *i2c_ctrl = (i2c_ctrl_t *) ctrl; + i2c_ctrl_t* i2c_ctrl = (i2c_ctrl_t*)ctrl; i2c_ctrl->is_open = false; return 0; } -extern "C" const audio_codec_ctrl_if_t *audio_codec_new_i2c_ctrl(audio_codec_i2c_cfg_t *i2c_cfg) +extern "C" const audio_codec_ctrl_if_t* audio_codec_new_i2c_ctrl(audio_codec_i2c_cfg_t* i2c_cfg) { - if (i2c_cfg == NULL) { + if (i2c_cfg == NULL) + { log_e("Bad configuration"); return NULL; } - i2c_ctrl_t *ctrl = (i2c_ctrl_t*)calloc(1, sizeof(i2c_ctrl_t)); - if (ctrl == NULL) { + i2c_ctrl_t* ctrl = (i2c_ctrl_t*)calloc(1, sizeof(i2c_ctrl_t)); + if (ctrl == NULL) + { log_e("No memory for instance"); return NULL; } @@ -109,7 +120,8 @@ extern "C" const audio_codec_ctrl_if_t *audio_codec_new_i2c_ctrl(audio_codec_i2c ctrl->base.write_reg = _i2c_ctrl_write_reg; ctrl->base.close = _i2c_ctrl_close; int ret = _i2c_ctrl_open(&ctrl->base, i2c_cfg, sizeof(audio_codec_i2c_cfg_t)); - if (ret != 0) { + if (ret != 0) + { free(ctrl); return NULL; } @@ -118,4 +130,3 @@ extern "C" const audio_codec_ctrl_if_t *audio_codec_new_i2c_ctrl(audio_codec_i2c } #endif - diff --git a/src/audio/codec/platform/audio_codec_data_i2s.c b/src/audio/codec/platform/audio_codec_data_i2s.c index 56f5d58c..5e49aa19 100644 --- a/src/audio/codec/platform/audio_codec_data_i2s.c +++ b/src/audio/codec/platform/audio_codec_data_i2s.c @@ -3,16 +3,16 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include "../interface/audio_codec_ctrl_if.h" #include "../include/esp_codec_dev_defaults.h" -#include "freertos/FreeRTOS.h" +#include "../interface/audio_codec_ctrl_if.h" #include "esp_idf_version.h" +#include "freertos/FreeRTOS.h" +#include +#include #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) +#include "driver/i2s_pdm.h" #include "driver/i2s_std.h" #include "driver/i2s_tdm.h" -#include "driver/i2s_pdm.h" #else #include "driver/i2s.h" #endif @@ -21,54 +21,61 @@ #define TAG "I2S_IF" -typedef struct { - audio_codec_data_if_t base; - bool is_open; - uint8_t port; - void *out_handle; - void *in_handle; - bool out_enable; - bool in_enable; - bool in_disable_pending; - bool out_disable_pending; - bool in_reconfig; - bool out_reconfig; +typedef struct +{ + audio_codec_data_if_t base; + bool is_open; + uint8_t port; + void* out_handle; + void* in_handle; + bool out_enable; + bool in_enable; + bool in_disable_pending; + bool out_disable_pending; + bool in_reconfig; + bool out_reconfig; esp_codec_dev_sample_info_t in_fs; esp_codec_dev_sample_info_t out_fs; esp_codec_dev_sample_info_t fs; } i2s_data_t; -static bool _i2s_valid_fmt(esp_codec_dev_sample_info_t *fs) +static bool _i2s_valid_fmt(esp_codec_dev_sample_info_t* fs) { if (fs->sample_rate == 0 || - fs->sample_rate >= 192000) { - ESP_LOGE(TAG, "Bad sample_rate %d", (int) fs->sample_rate); + fs->sample_rate >= 192000) + { + ESP_LOGE(TAG, "Bad sample_rate %d", (int)fs->sample_rate); } if (fs->channel == 0 || - (fs->channel >> 1 << 1) != fs->channel) { + (fs->channel >> 1 << 1) != fs->channel) + { ESP_LOGE(TAG, "Not support channel %d", fs->channel); return false; } if (fs->bits_per_sample < 8 || fs->bits_per_sample > 32 || - (fs->bits_per_sample >> 3 << 3) != fs->bits_per_sample) { + (fs->bits_per_sample >> 3 << 3) != fs->bits_per_sample) + { ESP_LOGE(TAG, "Not support bits_per_sample %d", fs->bits_per_sample); return false; } return true; } -static int _i2s_drv_enable(i2s_data_t *i2s_data, bool playback, bool enable) +static int _i2s_drv_enable(i2s_data_t* i2s_data, bool playback, bool enable) { #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) - i2s_chan_handle_t channel = (i2s_chan_handle_t) ( - playback ? i2s_data->out_handle : i2s_data->in_handle); - if (channel == NULL) { + i2s_chan_handle_t channel = (i2s_chan_handle_t)(playback ? i2s_data->out_handle : i2s_data->in_handle); + if (channel == NULL) + { return ESP_CODEC_DEV_NOT_FOUND; } int ret; - if (enable) { + if (enable) + { ret = i2s_channel_enable(channel); - } else { + } + else + { ret = i2s_channel_disable(channel); } return ret == ESP_OK ? ESP_CODEC_DEV_OK : ESP_CODEC_DEV_DRV_ERR; @@ -77,15 +84,18 @@ static int _i2s_drv_enable(i2s_data_t *i2s_data, bool playback, bool enable) } #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) -static uint8_t get_active_channel(esp_codec_dev_sample_info_t *fs) +static uint8_t get_active_channel(esp_codec_dev_sample_info_t* fs) { - if (fs->channel_mask == 0) { + if (fs->channel_mask == 0) + { return fs->channel; } int channel = 0; uint16_t mask = fs->channel_mask; - while (mask > 0) { - if (mask & 1) { + while (mask > 0) + { + if (mask & 1) + { channel++; } mask >>= 1; @@ -93,171 +103,195 @@ static uint8_t get_active_channel(esp_codec_dev_sample_info_t *fs) return channel; } -static uint8_t get_bits(i2s_data_t *i2s_data, bool playback) +static uint8_t get_bits(i2s_data_t* i2s_data, bool playback) { uint8_t total_bits = i2s_data->fs.bits_per_sample * i2s_data->fs.channel; - if (playback) { + if (playback) + { return total_bits / i2s_data->out_fs.channel; } return total_bits / i2s_data->in_fs.channel; } -static int set_drv_fs(i2s_chan_handle_t channel, bool playback, uint8_t slot_bits, esp_codec_dev_sample_info_t *fs) +static int set_drv_fs(i2s_chan_handle_t channel, bool playback, uint8_t slot_bits, esp_codec_dev_sample_info_t* fs) { i2s_chan_info_t channel_info = {0}; int ret = ESP_CODEC_DEV_OK; i2s_channel_get_info(channel, &channel_info); ESP_LOGI(TAG, "channel mode %d bits:%d/%d channel:%d mask:%x", - channel_info.mode, fs->bits_per_sample, slot_bits, (int)fs->channel, (int)fs->channel_mask); - switch (channel_info.mode) { - case I2S_COMM_MODE_STD: { - uint8_t bits = fs->bits_per_sample; - uint8_t active_channel = get_active_channel(fs); - uint16_t channel_mask = fs->channel_mask; - if (fs->channel > 2) { - slot_bits = slot_bits * fs->channel / 2; - active_channel = 2; - bits = slot_bits; - channel_mask = 0; - } - i2s_std_slot_mask_t slot_mask = fs->channel_mask ? - (i2s_std_slot_mask_t) fs->channel_mask : I2S_STD_SLOT_BOTH; - i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(slot_bits, active_channel); - slot_cfg.slot_mask = slot_mask; - if (slot_bits > bits) { - slot_cfg.data_bit_width = bits; - slot_cfg.slot_bit_width = slot_bits; - } - i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(fs->sample_rate); - if (fs->mclk_multiple) { - clk_cfg.mclk_multiple = fs->mclk_multiple; - } - if (slot_bits == 24 && (clk_cfg.mclk_multiple % 3) != 0) { - clk_cfg.mclk_multiple = I2S_MCLK_MULTIPLE_384; - } - ret = i2s_channel_reconfig_std_slot(channel, &slot_cfg); - if (ret != ESP_OK) { - *(int *) 0 = 0; - return ESP_CODEC_DEV_DRV_ERR; - } - ret = i2s_channel_reconfig_std_clock(channel, &clk_cfg); - ESP_LOGI(TAG, "STD Mode %d bits:%d/%d channel:%d sample_rate:%d mask:%x", - playback, bits, slot_bits, fs->channel, - (int)fs->sample_rate, channel_mask); - } - break; -#if SOC_I2S_SUPPORTS_PDM - case I2S_COMM_MODE_PDM: { - if (playback == false) { -#if SOC_I2S_SUPPORTS_PDM_RX - i2s_pdm_rx_clk_config_t clk_cfg = I2S_PDM_RX_CLK_DEFAULT_CONFIG(fs->sample_rate); - i2s_pdm_rx_slot_config_t slot_cfg = I2S_PDM_RX_SLOT_DEFAULT_CONFIG(slot_bits, I2S_SLOT_MODE_STEREO); - i2s_pdm_slot_mask_t slot_mask = fs->channel_mask ? - (i2s_pdm_slot_mask_t) fs->channel_mask : I2S_PDM_SLOT_BOTH; - // Stereo channel mask is ignored in driver, need use mono instead - if (fs->channel_mask && fs->channel_mask < 3) { - slot_cfg.slot_mode = I2S_SLOT_MODE_MONO; - } - slot_cfg.slot_mask = slot_mask; - if (slot_bits > fs->bits_per_sample) { - slot_cfg.data_bit_width = fs->bits_per_sample; - slot_cfg.slot_bit_width = slot_bits; - } - ret = i2s_channel_reconfig_pdm_rx_clock(channel, &clk_cfg); - if (ret != ESP_OK) { - return ESP_CODEC_DEV_DRV_ERR; - } - ret = i2s_channel_reconfig_pdm_rx_slot(channel, &slot_cfg); - if (ret != ESP_OK) { - return ESP_CODEC_DEV_DRV_ERR; - } -#else - ESP_LOGE(TAG, "PDM RX not supported"); - return ESP_CODEC_DEV_NOT_SUPPORT; -#endif - } else { -#if SOC_I2S_SUPPORTS_PDM_TX - i2s_pdm_tx_clk_config_t clk_cfg = I2S_PDM_TX_CLK_DEFAULT_CONFIG(fs->sample_rate); - i2s_pdm_tx_slot_config_t slot_cfg = I2S_PDM_TX_SLOT_DEFAULT_CONFIG(slot_bits, I2S_SLOT_MODE_STEREO); - // Stereo channel mask is ignored, need use mono instead - if (fs->channel_mask && fs->channel_mask < 3) { - slot_cfg.slot_mode = I2S_SLOT_MODE_MONO; - } -#if SOC_I2S_HW_VERSION_1 - i2s_pdm_slot_mask_t slot_mask = fs->channel_mask ? - (i2s_pdm_slot_mask_t) fs->channel_mask : I2S_PDM_SLOT_BOTH; - slot_cfg.slot_mask = slot_mask; -#endif - if (slot_bits > fs->bits_per_sample) { - slot_cfg.data_bit_width = fs->bits_per_sample; - slot_cfg.slot_bit_width = slot_bits; - } - ret = i2s_channel_reconfig_pdm_tx_clock(channel, &clk_cfg); - if (ret != ESP_OK) { - return ESP_CODEC_DEV_DRV_ERR; - } - ret = i2s_channel_reconfig_pdm_tx_slot(channel, &slot_cfg); - if (ret != ESP_OK) { - return ESP_CODEC_DEV_DRV_ERR; - } -#else - ESP_LOGE(TAG, "PDM TX not supported"); - return ESP_CODEC_DEV_NOT_SUPPORT; -#endif - } + channel_info.mode, fs->bits_per_sample, slot_bits, (int)fs->channel, (int)fs->channel_mask); + switch (channel_info.mode) + { + case I2S_COMM_MODE_STD: + { + uint8_t bits = fs->bits_per_sample; + uint8_t active_channel = get_active_channel(fs); + uint16_t channel_mask = fs->channel_mask; + if (fs->channel > 2) + { + slot_bits = slot_bits * fs->channel / 2; + active_channel = 2; + bits = slot_bits; + channel_mask = 0; } - break; -#endif -#if SOC_I2S_SUPPORTS_TDM - case I2S_COMM_MODE_TDM: { - i2s_tdm_clk_config_t clk_cfg = I2S_TDM_CLK_DEFAULT_CONFIG(fs->sample_rate); - if (slot_bits == 24) { - clk_cfg.mclk_multiple = I2S_MCLK_MULTIPLE_384; + i2s_std_slot_mask_t slot_mask = fs->channel_mask ? (i2s_std_slot_mask_t)fs->channel_mask : I2S_STD_SLOT_BOTH; + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(slot_bits, active_channel); + slot_cfg.slot_mask = slot_mask; + if (slot_bits > bits) + { + slot_cfg.data_bit_width = bits; + slot_cfg.slot_bit_width = slot_bits; + } + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(fs->sample_rate); + if (fs->mclk_multiple) + { + clk_cfg.mclk_multiple = fs->mclk_multiple; + } + if (slot_bits == 24 && (clk_cfg.mclk_multiple % 3) != 0) + { + clk_cfg.mclk_multiple = I2S_MCLK_MULTIPLE_384; + } + ret = i2s_channel_reconfig_std_slot(channel, &slot_cfg); + if (ret != ESP_OK) + { + *(int*)0 = 0; + return ESP_CODEC_DEV_DRV_ERR; + } + ret = i2s_channel_reconfig_std_clock(channel, &clk_cfg); + ESP_LOGI(TAG, "STD Mode %d bits:%d/%d channel:%d sample_rate:%d mask:%x", + playback, bits, slot_bits, fs->channel, + (int)fs->sample_rate, channel_mask); + } + break; +#if SOC_I2S_SUPPORTS_PDM + case I2S_COMM_MODE_PDM: + { + if (playback == false) + { +#if SOC_I2S_SUPPORTS_PDM_RX + i2s_pdm_rx_clk_config_t clk_cfg = I2S_PDM_RX_CLK_DEFAULT_CONFIG(fs->sample_rate); + i2s_pdm_rx_slot_config_t slot_cfg = I2S_PDM_RX_SLOT_DEFAULT_CONFIG(slot_bits, I2S_SLOT_MODE_STEREO); + i2s_pdm_slot_mask_t slot_mask = fs->channel_mask ? (i2s_pdm_slot_mask_t)fs->channel_mask : I2S_PDM_SLOT_BOTH; + // Stereo channel mask is ignored in driver, need use mono instead + if (fs->channel_mask && fs->channel_mask < 3) + { + slot_cfg.slot_mode = I2S_SLOT_MODE_MONO; } - i2s_tdm_slot_config_t slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG( - slot_bits, - I2S_SLOT_MODE_STEREO, - (i2s_tdm_slot_mask_t)fs->channel_mask); - slot_cfg.total_slot = fs->channel; - if (slot_bits > fs->bits_per_sample) { + slot_cfg.slot_mask = slot_mask; + if (slot_bits > fs->bits_per_sample) + { slot_cfg.data_bit_width = fs->bits_per_sample; slot_cfg.slot_bit_width = slot_bits; } - ret = i2s_channel_reconfig_tdm_slot(channel, &slot_cfg); - if (ret != ESP_OK) { + ret = i2s_channel_reconfig_pdm_rx_clock(channel, &clk_cfg); + if (ret != ESP_OK) + { return ESP_CODEC_DEV_DRV_ERR; } - ret = i2s_channel_reconfig_tdm_clock(channel, &clk_cfg); - if (ret != ESP_OK) { + ret = i2s_channel_reconfig_pdm_rx_slot(channel, &slot_cfg); + if (ret != ESP_OK) + { return ESP_CODEC_DEV_DRV_ERR; } - ESP_LOGI(TAG, "TDM Mode %d bits:%d/%d channel:%d sample_rate:%d mask:%x", - playback, fs->bits_per_sample, slot_bits, fs->channel, - (int)fs->sample_rate, fs->channel_mask); - } - break; -#endif - default: +#else + ESP_LOGE(TAG, "PDM RX not supported"); return ESP_CODEC_DEV_NOT_SUPPORT; +#endif + } + else + { +#if SOC_I2S_SUPPORTS_PDM_TX + i2s_pdm_tx_clk_config_t clk_cfg = I2S_PDM_TX_CLK_DEFAULT_CONFIG(fs->sample_rate); + i2s_pdm_tx_slot_config_t slot_cfg = I2S_PDM_TX_SLOT_DEFAULT_CONFIG(slot_bits, I2S_SLOT_MODE_STEREO); + // Stereo channel mask is ignored, need use mono instead + if (fs->channel_mask && fs->channel_mask < 3) + { + slot_cfg.slot_mode = I2S_SLOT_MODE_MONO; + } +#if SOC_I2S_HW_VERSION_1 + i2s_pdm_slot_mask_t slot_mask = fs->channel_mask ? (i2s_pdm_slot_mask_t)fs->channel_mask : I2S_PDM_SLOT_BOTH; + slot_cfg.slot_mask = slot_mask; +#endif + if (slot_bits > fs->bits_per_sample) + { + slot_cfg.data_bit_width = fs->bits_per_sample; + slot_cfg.slot_bit_width = slot_bits; + } + ret = i2s_channel_reconfig_pdm_tx_clock(channel, &clk_cfg); + if (ret != ESP_OK) + { + return ESP_CODEC_DEV_DRV_ERR; + } + ret = i2s_channel_reconfig_pdm_tx_slot(channel, &slot_cfg); + if (ret != ESP_OK) + { + return ESP_CODEC_DEV_DRV_ERR; + } +#else + ESP_LOGE(TAG, "PDM TX not supported"); + return ESP_CODEC_DEV_NOT_SUPPORT; +#endif + } + } + break; +#endif +#if SOC_I2S_SUPPORTS_TDM + case I2S_COMM_MODE_TDM: + { + i2s_tdm_clk_config_t clk_cfg = I2S_TDM_CLK_DEFAULT_CONFIG(fs->sample_rate); + if (slot_bits == 24) + { + clk_cfg.mclk_multiple = I2S_MCLK_MULTIPLE_384; + } + i2s_tdm_slot_config_t slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG( + slot_bits, + I2S_SLOT_MODE_STEREO, + (i2s_tdm_slot_mask_t)fs->channel_mask); + slot_cfg.total_slot = fs->channel; + if (slot_bits > fs->bits_per_sample) + { + slot_cfg.data_bit_width = fs->bits_per_sample; + slot_cfg.slot_bit_width = slot_bits; + } + ret = i2s_channel_reconfig_tdm_slot(channel, &slot_cfg); + if (ret != ESP_OK) + { + return ESP_CODEC_DEV_DRV_ERR; + } + ret = i2s_channel_reconfig_tdm_clock(channel, &clk_cfg); + if (ret != ESP_OK) + { + return ESP_CODEC_DEV_DRV_ERR; + } + ESP_LOGI(TAG, "TDM Mode %d bits:%d/%d channel:%d sample_rate:%d mask:%x", + playback, fs->bits_per_sample, slot_bits, fs->channel, + (int)fs->sample_rate, fs->channel_mask); + } + break; +#endif + default: + return ESP_CODEC_DEV_NOT_SUPPORT; } return ret; } -static int set_fs(i2s_data_t *i2s_data, bool playback, bool skip) +static int set_fs(i2s_data_t* i2s_data, bool playback, bool skip) { - i2s_chan_handle_t channel = (i2s_chan_handle_t) playback ? i2s_data->out_handle : i2s_data->in_handle; + i2s_chan_handle_t channel = (i2s_chan_handle_t)playback ? i2s_data->out_handle : i2s_data->in_handle; i2s_chan_info_t channel_info = {0}; - esp_codec_dev_sample_info_t *fs = playback ? &i2s_data->out_fs : &i2s_data->in_fs; + esp_codec_dev_sample_info_t* fs = playback ? &i2s_data->out_fs : &i2s_data->in_fs; uint8_t bits_per_sample = get_bits(i2s_data, playback); i2s_channel_get_info(channel, &channel_info); int ret = set_drv_fs(channel, playback, bits_per_sample, fs); - if (ret != ESP_CODEC_DEV_OK) { + if (ret != ESP_CODEC_DEV_OK) + { return ret; } // Set RX clock will not take effect if in full duplex mode, need update TX clock also - if (skip == false && playback == false && i2s_data->out_handle != NULL && i2s_data->out_enable == false) { + if (skip == false && playback == false && i2s_data->out_handle != NULL && i2s_data->out_enable == false) + { // TX is master, set to RX not take effect need reconfig TX also - channel = (i2s_chan_handle_t) i2s_data->out_handle; + channel = (i2s_chan_handle_t)i2s_data->out_handle; _i2s_drv_enable(i2s_data, true, false); ret = set_drv_fs(channel, true, bits_per_sample, fs); _i2s_drv_enable(i2s_data, true, true); @@ -265,24 +299,27 @@ static int set_fs(i2s_data_t *i2s_data, bool playback, bool skip) return ret; } -static int check_fs_compatible(i2s_data_t *i2s_data, bool playback, esp_codec_dev_sample_info_t *fs) +static int check_fs_compatible(i2s_data_t* i2s_data, bool playback, esp_codec_dev_sample_info_t* fs) { // Set fs directly when only enable one channel - esp_codec_dev_sample_info_t *channel_fs = playback ? &i2s_data->out_fs : &i2s_data->in_fs; + esp_codec_dev_sample_info_t* channel_fs = playback ? &i2s_data->out_fs : &i2s_data->in_fs; if ((playback && i2s_data->in_enable == false) || - (!playback && i2s_data->out_enable == false)) { + (!playback && i2s_data->out_enable == false)) + { memcpy(&i2s_data->fs, fs, sizeof(esp_codec_dev_sample_info_t)); memcpy(channel_fs, fs, sizeof(esp_codec_dev_sample_info_t)); return set_fs(i2s_data, playback, false); } - if (fs->sample_rate != i2s_data->fs.sample_rate) { - ESP_LOGE(TAG, "Mode %d conflict sample_rate %d with %d", - playback, (int)fs->sample_rate, (int)i2s_data->fs.sample_rate); + if (fs->sample_rate != i2s_data->fs.sample_rate) + { + ESP_LOGE(TAG, "Mode %d conflict sample_rate %d with %d", + playback, (int)fs->sample_rate, (int)i2s_data->fs.sample_rate); return ESP_CODEC_DEV_NOT_SUPPORT; } // Channel and bits same, set directly if (fs->channel == i2s_data->fs.channel && - fs->bits_per_sample == i2s_data->fs.bits_per_sample) { + fs->bits_per_sample == i2s_data->fs.bits_per_sample) + { memcpy(channel_fs, fs, sizeof(esp_codec_dev_sample_info_t)); return set_fs(i2s_data, playback, false); } @@ -292,31 +329,41 @@ static int check_fs_compatible(i2s_data_t *i2s_data, bool playback, esp_codec_de int ret; // Need expand peer channel bits ESP_LOGI(TAG, "Mode %d need extend bits %d to %d", !playback, run_bits, want_bits); - do { - if (want_bits > run_bits) { - if (playback == false) { + do + { + if (want_bits > run_bits) + { + if (playback == false) + { i2s_data->out_reconfig = true; - } else { + } + else + { i2s_data->in_reconfig = true; } ret = _i2s_drv_enable(i2s_data, !playback, false); - if (ret != ESP_CODEC_DEV_OK) { + if (ret != ESP_CODEC_DEV_OK) + { break; } memcpy(&i2s_data->fs, fs, sizeof(esp_codec_dev_sample_info_t)); } // Need set fs before enable ret = set_fs(i2s_data, playback, false); - if (ret != ESP_CODEC_DEV_OK) { + if (ret != ESP_CODEC_DEV_OK) + { break; } - if (want_bits > run_bits) { + if (want_bits > run_bits) + { ret = set_fs(i2s_data, !playback, true); - if (ret != ESP_CODEC_DEV_OK) { + if (ret != ESP_CODEC_DEV_OK) + { break; } ret = _i2s_drv_enable(i2s_data, !playback, true); - if (ret != ESP_CODEC_DEV_OK) { + if (ret != ESP_CODEC_DEV_OK) + { break; } } @@ -326,13 +373,14 @@ static int check_fs_compatible(i2s_data_t *i2s_data, bool playback, esp_codec_de } #endif -static int _i2s_data_open(const audio_codec_data_if_t *h, void *data_cfg, int cfg_size) +static int _i2s_data_open(const audio_codec_data_if_t* h, void* data_cfg, int cfg_size) { - i2s_data_t *i2s_data = (i2s_data_t *) h; - if (h == NULL || data_cfg == NULL || cfg_size != sizeof(audio_codec_i2s_cfg_t)) { + i2s_data_t* i2s_data = (i2s_data_t*)h; + if (h == NULL || data_cfg == NULL || cfg_size != sizeof(audio_codec_i2s_cfg_t)) + { return ESP_CODEC_DEV_INVALID_ARG; } - audio_codec_i2s_cfg_t *i2s_cfg = (audio_codec_i2s_cfg_t *) data_cfg; + audio_codec_i2s_cfg_t* i2s_cfg = (audio_codec_i2s_cfg_t*)data_cfg; i2s_data->is_open = true; i2s_data->port = i2s_cfg->port; i2s_data->out_handle = i2s_cfg->tx_handle; @@ -340,77 +388,94 @@ static int _i2s_data_open(const audio_codec_data_if_t *h, void *data_cfg, int cf return ESP_CODEC_DEV_OK; } -static bool _i2s_data_is_open(const audio_codec_data_if_t *h) +static bool _i2s_data_is_open(const audio_codec_data_if_t* h) { - i2s_data_t *i2s_data = (i2s_data_t *) h; - if (i2s_data) { + i2s_data_t* i2s_data = (i2s_data_t*)h; + if (i2s_data) + { return i2s_data->is_open; } return false; } -static int _i2s_data_enable(const audio_codec_data_if_t *h, esp_codec_dev_type_t dev_type, bool enable) +static int _i2s_data_enable(const audio_codec_data_if_t* h, esp_codec_dev_type_t dev_type, bool enable) { - i2s_data_t *i2s_data = (i2s_data_t *) h; - if (i2s_data == NULL) { + i2s_data_t* i2s_data = (i2s_data_t*)h; + if (i2s_data == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } - if (i2s_data->is_open == false) { + if (i2s_data->is_open == false) + { return ESP_CODEC_DEV_WRONG_STATE; } int ret = ESP_CODEC_DEV_OK; - if (dev_type == ESP_CODEC_DEV_TYPE_IN_OUT) { + if (dev_type == ESP_CODEC_DEV_TYPE_IN_OUT) + { ret = _i2s_drv_enable(i2s_data, true, enable); ret = _i2s_drv_enable(i2s_data, false, enable); - } else { + } + else + { bool playback = dev_type & ESP_CODEC_DEV_TYPE_OUT ? true : false; // When RX is working TX disable should be blocked - if (enable == false && i2s_data->in_enable && playback && i2s_data->out_handle) { + if (enable == false && i2s_data->in_enable && playback && i2s_data->out_handle) + { ESP_LOGI(TAG, "Pending out channel for in channel running"); i2s_data->out_disable_pending = true; } - #if SOC_I2S_HW_VERSION_1 +#if SOC_I2S_HW_VERSION_1 // For ESP32 and ESP32S3 if disable RX, TX also not work need pending until TX not used - else if (enable == false && i2s_data->out_enable && playback == false && i2s_data->in_handle) { + else if (enable == false && i2s_data->out_enable && playback == false && i2s_data->in_handle) + { ESP_LOGI(TAG, "Pending in channel for out channel running"); i2s_data->in_disable_pending = true; } - #endif - else { +#endif + else + { ret = _i2s_drv_enable(i2s_data, playback, enable); // Disable TX when RX disable if TX disable is pending - if (enable == false) { - if (playback == false && i2s_data->out_disable_pending) { + if (enable == false) + { + if (playback == false && i2s_data->out_disable_pending) + { ret = _i2s_drv_enable(i2s_data, true, enable); i2s_data->out_disable_pending = false; } - if (playback == true && i2s_data->in_disable_pending) { + if (playback == true && i2s_data->in_disable_pending) + { ret = _i2s_drv_enable(i2s_data, false, enable); i2s_data->in_disable_pending = false; } } } } - if (dev_type & ESP_CODEC_DEV_TYPE_IN) { + if (dev_type & ESP_CODEC_DEV_TYPE_IN) + { i2s_data->in_enable = enable; } - if (dev_type & ESP_CODEC_DEV_TYPE_OUT) { + if (dev_type & ESP_CODEC_DEV_TYPE_OUT) + { i2s_data->out_enable = enable; } return ret; } -static int _i2s_data_set_fmt(const audio_codec_data_if_t *h, esp_codec_dev_type_t dev_type, esp_codec_dev_sample_info_t *fs) +static int _i2s_data_set_fmt(const audio_codec_data_if_t* h, esp_codec_dev_type_t dev_type, esp_codec_dev_sample_info_t* fs) { - i2s_data_t *i2s_data = (i2s_data_t *) h; - if (i2s_data == NULL) { + i2s_data_t* i2s_data = (i2s_data_t*)h; + if (i2s_data == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } - if (i2s_data->is_open == false) { + if (i2s_data->is_open == false) + { return ESP_CODEC_DEV_WRONG_STATE; } esp_codec_dev_sample_info_t eq_fs; - if (fs->channel == 1) { + if (fs->channel == 1) + { // When using one channel replace to select channel 0 in default memcpy(&eq_fs, fs, sizeof(esp_codec_dev_sample_info_t)); fs = &eq_fs; @@ -418,55 +483,69 @@ static int _i2s_data_set_fmt(const audio_codec_data_if_t *h, esp_codec_dev_type_ fs->channel_mask = ESP_CODEC_DEV_MAKE_CHANNEL_MASK(0); } #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) - if (fs->channel_mask == 0) { + if (fs->channel_mask == 0) + { // Add channel mask automatically when not set memcpy(&eq_fs, fs, sizeof(esp_codec_dev_sample_info_t)); fs = &eq_fs; - for (int i = 0; i < fs->channel; i++) { + for (int i = 0; i < fs->channel; i++) + { fs->channel_mask |= ESP_CODEC_DEV_MAKE_CHANNEL_MASK(i); } } #endif - if (_i2s_valid_fmt(fs) == false) { + if (_i2s_valid_fmt(fs) == false) + { return ESP_CODEC_DEV_NOT_SUPPORT; } #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) // disable internally - if (dev_type & ESP_CODEC_DEV_TYPE_OUT) { + if (dev_type & ESP_CODEC_DEV_TYPE_OUT) + { _i2s_drv_enable(i2s_data, true, false); } - if (dev_type & ESP_CODEC_DEV_TYPE_IN) { + if (dev_type & ESP_CODEC_DEV_TYPE_IN) + { _i2s_drv_enable(i2s_data, false, false); } int ret; if ((dev_type & ESP_CODEC_DEV_TYPE_IN) != 0 && - (dev_type & ESP_CODEC_DEV_TYPE_OUT) != 0) { + (dev_type & ESP_CODEC_DEV_TYPE_OUT) != 0) + { // Device support playback and record at same time memcpy(&i2s_data->fs, fs, sizeof(esp_codec_dev_sample_info_t)); memcpy(&i2s_data->in_fs, fs, sizeof(esp_codec_dev_sample_info_t)); memcpy(&i2s_data->out_fs, fs, sizeof(esp_codec_dev_sample_info_t)); ret = set_fs(i2s_data, true, true); ret = set_fs(i2s_data, false, true); - } else { + } + else + { ret = check_fs_compatible(i2s_data, dev_type & ESP_CODEC_DEV_TYPE_OUT ? true : false, fs); } return ret; #else // When use multichannel data - if (fs->channel_mask) { + if (fs->channel_mask) + { i2s_channel_t sel_channel = 0; #if SOC_I2S_SUPPORTS_TDM sel_channel = (i2s_channel_t)(fs->channel_mask << 16); #else - if (fs->channel_mask == ESP_CODEC_DEV_MAKE_CHANNEL_MASK(0)) { + if (fs->channel_mask == ESP_CODEC_DEV_MAKE_CHANNEL_MASK(0)) + { sel_channel = 1; - } else { + } + else + { ESP_LOGE(TAG, "IC not support TDM"); return ESP_CODEC_DEV_NOT_FOUND; } #endif i2s_set_clk(i2s_data->port, fs->sample_rate, fs->bits_per_sample, sel_channel); - } else { + } + else + { i2s_set_clk(i2s_data->port, fs->sample_rate, fs->bits_per_sample, fs->channel); } i2s_zero_dma_buffer(i2s_data->port); @@ -475,22 +554,26 @@ static int _i2s_data_set_fmt(const audio_codec_data_if_t *h, esp_codec_dev_type_ return ESP_CODEC_DEV_OK; } -static int _i2s_data_read(const audio_codec_data_if_t *h, uint8_t *data, int size) +static int _i2s_data_read(const audio_codec_data_if_t* h, uint8_t* data, int size) { - i2s_data_t *i2s_data = (i2s_data_t *) h; - if (i2s_data == NULL) { + i2s_data_t* i2s_data = (i2s_data_t*)h; + if (i2s_data == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } - if (i2s_data->is_open == false) { + if (i2s_data->is_open == false) + { return ESP_CODEC_DEV_WRONG_STATE; } size_t bytes_read = 0; #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) - i2s_chan_handle_t rx_chan = (i2s_chan_handle_t) i2s_data->in_handle; - if (rx_chan == NULL) { + i2s_chan_handle_t rx_chan = (i2s_chan_handle_t)i2s_data->in_handle; + if (rx_chan == NULL) + { return ESP_CODEC_DEV_DRV_ERR; } - if (i2s_data->in_reconfig) { + if (i2s_data->in_reconfig) + { memset(data, 0, size); esp_codec_dev_sleep(10); return ESP_CODEC_DEV_OK; @@ -502,22 +585,26 @@ static int _i2s_data_read(const audio_codec_data_if_t *h, uint8_t *data, int siz return ret == 0 ? ESP_CODEC_DEV_OK : ESP_CODEC_DEV_DRV_ERR; } -static int _i2s_data_write(const audio_codec_data_if_t *h, uint8_t *data, int size) +static int _i2s_data_write(const audio_codec_data_if_t* h, uint8_t* data, int size) { - i2s_data_t *i2s_data = (i2s_data_t *) h; - if (i2s_data == NULL) { + i2s_data_t* i2s_data = (i2s_data_t*)h; + if (i2s_data == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } - if (i2s_data->is_open == false) { + if (i2s_data->is_open == false) + { return ESP_CODEC_DEV_WRONG_STATE; } size_t bytes_written = 0; #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) - i2s_chan_handle_t tx_chan = (i2s_chan_handle_t) i2s_data->out_handle; - if (tx_chan == NULL) { + i2s_chan_handle_t tx_chan = (i2s_chan_handle_t)i2s_data->out_handle; + if (tx_chan == NULL) + { return ESP_CODEC_DEV_DRV_ERR; } - if (i2s_data->out_reconfig) { + if (i2s_data->out_reconfig) + { esp_codec_dev_sleep(10); return ESP_CODEC_DEV_OK; } @@ -528,10 +615,11 @@ static int _i2s_data_write(const audio_codec_data_if_t *h, uint8_t *data, int si return ret == 0 ? ESP_CODEC_DEV_OK : ESP_CODEC_DEV_DRV_ERR; } -static int _i2s_data_close(const audio_codec_data_if_t *h) +static int _i2s_data_close(const audio_codec_data_if_t* h) { - i2s_data_t *i2s_data = (i2s_data_t *) h; - if (i2s_data == NULL) { + i2s_data_t* i2s_data = (i2s_data_t*)h; + if (i2s_data == NULL) + { return ESP_CODEC_DEV_INVALID_ARG; } memset(&i2s_data->fs, 0, sizeof(esp_codec_dev_sample_info_t)); @@ -541,10 +629,11 @@ static int _i2s_data_close(const audio_codec_data_if_t *h) return ESP_CODEC_DEV_OK; } -const audio_codec_data_if_t *audio_codec_new_i2s_data(audio_codec_i2s_cfg_t *i2s_cfg) +const audio_codec_data_if_t* audio_codec_new_i2s_data(audio_codec_i2s_cfg_t* i2s_cfg) { - i2s_data_t *i2s_data = calloc(1, sizeof(i2s_data_t)); - if (i2s_data == NULL) { + i2s_data_t* i2s_data = calloc(1, sizeof(i2s_data_t)); + if (i2s_data == NULL) + { ESP_LOGE(TAG, "No memory for instance"); return NULL; } @@ -556,7 +645,8 @@ const audio_codec_data_if_t *audio_codec_new_i2s_data(audio_codec_i2s_cfg_t *i2s i2s_data->base.set_fmt = _i2s_data_set_fmt; i2s_data->base.close = _i2s_data_close; int ret = _i2s_data_open(&i2s_data->base, i2s_cfg, sizeof(audio_codec_i2s_cfg_t)); - if (ret != 0) { + if (ret != 0) + { free(i2s_data); return NULL; } diff --git a/src/audio/codec/platform/audio_codec_gpio.c b/src/audio/codec/platform/audio_codec_gpio.c index b5ca3f1e..1a5ab619 100644 --- a/src/audio/codec/platform/audio_codec_gpio.c +++ b/src/audio/codec/platform/audio_codec_gpio.c @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include "../interface/audio_codec_ctrl_if.h" #include "../include/esp_codec_dev_defaults.h" -#include "esp_err.h" +#include "../interface/audio_codec_ctrl_if.h" #include "driver/gpio.h" +#include "esp_err.h" #include "esp_log.h" #include @@ -14,7 +14,8 @@ static int _gpio_cfg(int16_t gpio, audio_gpio_dir_t dir, audio_gpio_mode_t mode) { - if (gpio == -1) { + if (gpio == -1) + { return ESP_CODEC_DEV_INVALID_ARG; } gpio_config_t io_conf; @@ -29,25 +30,28 @@ static int _gpio_cfg(int16_t gpio, audio_gpio_dir_t dir, audio_gpio_mode_t mode) } static int _gpio_set(int16_t gpio, bool high) { - if (gpio == -1) { + if (gpio == -1) + { return ESP_CODEC_DEV_INVALID_ARG; } - int ret = gpio_set_level((gpio_num_t) gpio, high ? 1 : 0); + int ret = gpio_set_level((gpio_num_t)gpio, high ? 1 : 0); return ret == 0 ? ESP_CODEC_DEV_OK : ESP_CODEC_DEV_DRV_ERR; } static bool _gpio_get(int16_t gpio) { - if (gpio == -1) { + if (gpio == -1) + { return false; } - return (bool) gpio_get_level((gpio_num_t) gpio); + return (bool)gpio_get_level((gpio_num_t)gpio); } -const audio_codec_gpio_if_t *audio_codec_new_gpio(void) +const audio_codec_gpio_if_t* audio_codec_new_gpio(void) { - audio_codec_gpio_if_t *gpio_if = (audio_codec_gpio_if_t *) calloc(1, sizeof(audio_codec_gpio_if_t)); - if (gpio_if == NULL) { + audio_codec_gpio_if_t* gpio_if = (audio_codec_gpio_if_t*)calloc(1, sizeof(audio_codec_gpio_if_t)); + if (gpio_if == NULL) + { ESP_LOGE(TAG, "No memory for instance"); return NULL; } diff --git a/src/audio/codec/platform/esp_codec_dev_os.c b/src/audio/codec/platform/esp_codec_dev_os.c index 8d585bea..764cc04e 100644 --- a/src/audio/codec/platform/esp_codec_dev_os.c +++ b/src/audio/codec/platform/esp_codec_dev_os.c @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#include "esp_idf_version.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "esp_idf_version.h" #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) #define TICK_PER_MS portTICK_PERIOD_MS #else diff --git a/src/board/LilyGoKeyboard.cpp b/src/board/LilyGoKeyboard.cpp index 1ec5d9a3..062d5f4a 100644 --- a/src/board/LilyGoKeyboard.cpp +++ b/src/board/LilyGoKeyboard.cpp @@ -15,18 +15,17 @@ extern "C" bool ui_ime_is_active(); bool ui_take_screenshot_to_sd(); #ifndef LEDC_BACKLIGHT_CHANNEL -#define LEDC_BACKLIGHT_CHANNEL 4 +#define LEDC_BACKLIGHT_CHANNEL 4 #endif #ifndef LEDC_BACKLIGHT_BIT_WIDTH -#define LEDC_BACKLIGHT_BIT_WIDTH 8 +#define LEDC_BACKLIGHT_BIT_WIDTH 8 #endif #ifndef LEDC_BACKLIGHT_FREQ -#define LEDC_BACKLIGHT_FREQ 1000 //HZ +#define LEDC_BACKLIGHT_FREQ 1000 // HZ #endif - static bool keyboard_interrupted = false; static void keyboard_isr() @@ -38,7 +37,7 @@ LilyGoKeyboard::LilyGoKeyboard() : _backlight(-1), _brightness(0), _irq(0), cb(nullptr), repeat_function(false), symbol_key_pressed(false), cap_key_pressed(false), alt_key_pressed(false), - lastState(false), lastKeyVal('\0'), lastPressedTime(0) + lastState(false), lastKeyVal('\0'), lastPressedTime(0) { } @@ -53,15 +52,17 @@ void LilyGoKeyboard::setPins(int backlight) void LilyGoKeyboard::setBrightness(uint8_t level) { - if (this->bl_cb) { + if (this->bl_cb) + { this->bl_cb(level); return; } - if (_backlight == -1) { + if (_backlight == -1) + { return; } _brightness = level; -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) ledcWrite(_backlight, _brightness); #else ledcWrite(LEDC_BACKLIGHT_CHANNEL, _brightness); @@ -73,13 +74,14 @@ uint8_t LilyGoKeyboard::getBrightness() return _brightness; } -bool LilyGoKeyboard::begin(const LilyGoKeyboardConfigure_t &config, TwoWire &w, uint8_t irq, uint8_t sda, uint8_t scl) +bool LilyGoKeyboard::begin(const LilyGoKeyboardConfigure_t& config, TwoWire& w, uint8_t irq, uint8_t sda, uint8_t scl) { - if (_backlight != -1) { + if (_backlight != -1) + { ::pinMode(_backlight, OUTPUT); ::digitalWrite(_backlight, LOW); -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) ledcAttach(_backlight, LEDC_BACKLIGHT_FREQ, LEDC_BACKLIGHT_BIT_WIDTH); #else ledcSetup(LEDC_BACKLIGHT_CHANNEL, LEDC_BACKLIGHT_FREQ, LEDC_BACKLIGHT_BIT_WIDTH); @@ -88,9 +90,9 @@ bool LilyGoKeyboard::begin(const LilyGoKeyboardConfigure_t &config, TwoWire &w, setBrightness(127); } - bool res = Adafruit_TCA8418::begin(TCA8418_DEFAULT_ADDR, &w); - if (!res) { + if (!res) + { log_e("Failed to find Keyboard"); return false; } @@ -111,7 +113,8 @@ bool LilyGoKeyboard::begin(const LilyGoKeyboardConfigure_t &config, TwoWire &w, this->matrix(_config->kb_rows, _config->kb_cols); this->flush(); - if (irq > 0) { + if (irq > 0) + { _irq = irq; ::pinMode(_irq, INPUT_PULLUP); attachInterrupt(_irq, keyboard_isr, CHANGE); @@ -124,21 +127,24 @@ bool LilyGoKeyboard::begin(const LilyGoKeyboardConfigure_t &config, TwoWire &w, void LilyGoKeyboard::end() { setBrightness(0); - - if (_irq > 0) { + + if (_irq > 0) + { this->disableInterrupts(); detachInterrupt(_irq); ::pinMode(_irq, OPEN_DRAIN); } - if (_backlight != -1) { -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) + if (_backlight != -1) + { +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) ledcDetach(_backlight); #else ledcDetachPin(_backlight); #endif ::pinMode(_backlight, OPEN_DRAIN); } - for (int pin = 0; pin < 18; pin++) { + for (int pin = 0; pin < 18; pin++) + { this->pinMode(pin, INPUT); } } @@ -168,38 +174,46 @@ void LilyGoKeyboard::setRepeat(bool enable) repeat_function = enable; } -int LilyGoKeyboard::getKey(char *c) +int LilyGoKeyboard::getKey(char* c) { const uint32_t REPEAT_INTERVAL = 300; static char output; static uint32_t interval = 0; int val = -1; - if (millis() - interval > 100) { + if (millis() - interval > 100) + { // Polling detects whether there is an ignored state in the interrupt status that has not been processed. // The polling speed affects the response speed of the keyboard. interval = millis(); this->readRegister(TCA8418_REG_INT_STAT); - if (this->available() != 0 && !keyboard_interrupted) { + if (this->available() != 0 && !keyboard_interrupted) + { keyboard_interrupted = true; } } - if (repeat_function) { - if (lastState) { - if (millis() - lastPressedTime > REPEAT_INTERVAL) { + if (repeat_function) + { + if (lastState) + { + if (millis() - lastPressedTime > REPEAT_INTERVAL) + { // The space key conflicts with the symbol function, // so the space key is not processed as a continuous key. - if (lastKeyVal == 0 || lastKeyVal == ' ') { + if (lastKeyVal == 0 || lastKeyVal == ' ') + { lastState = false; return -1; } log_d("Pressed repeat %c\n", output); lastPressedTime = millis(); - if (c) { + if (c) + { *c = output; } - if (cb) { + if (cb) + { cb(KB_PRESSED, output); } return KB_PRESSED; @@ -207,12 +221,14 @@ int LilyGoKeyboard::getKey(char *c) } } - if (!keyboard_interrupted) { + if (!keyboard_interrupted) + { return val; } int intStat = this->readRegister(TCA8418_REG_INT_STAT); - if (intStat & 0x02) { + if (intStat & 0x02) + { // reading the registers is mandatory to clear IRQ flag // can also be used to find the GPIO changed // as these registers are a bitmap of the gpio pins. @@ -223,64 +239,80 @@ int LilyGoKeyboard::getKey(char *c) this->writeRegister(TCA8418_REG_INT_STAT, 2); } - // Clear IRQ flag this->writeRegister(TCA8418_REG_INT_STAT, 1); uint8_t intstat = this->readRegister(TCA8418_REG_INT_STAT); - if ((intstat & 0x01) == 0) { + if ((intstat & 0x01) == 0) + { keyboard_interrupted = false; } int ret = update(&output); - if (cb) { + if (cb) + { cb(ret, output); } - if (c) { + if (c) + { *c = output; } // Serial.printf("Update \"%c\" sate:%s\n", output, ret > 0 ? "Pressed" : "Released"); return ret; } - -int LilyGoKeyboard::handleSpecialKeys(uint8_t k, bool pressed, char *c) +int LilyGoKeyboard::handleSpecialKeys(uint8_t k, bool pressed, char* c) { static uint32_t last_alt_press_ms = 0; static constexpr uint32_t kAltDoublePressMs = 350; Serial.printf("[Keyboard] special key=%u pressed=%d\n", static_cast(k), pressed ? 1 : 0); - if (k == _config->symbol_key_value) { + if (k == _config->symbol_key_value) + { symbol_key_pressed = !symbol_key_pressed; // Switch symbol mode return _config->has_symbol_key ? -1 : 0; - } else if (k == _config->caps_key_value || k == _config->caps_b_key_value) { + } + else if (k == _config->caps_key_value || k == _config->caps_b_key_value) + { cap_key_pressed = !cap_key_pressed; // Switch to uppercase mode return -1; - } else if (k == _config->alt_key_value) { - if (pressed) { + } + else if (k == _config->alt_key_value) + { + if (pressed) + { uint32_t now = millis(); if (last_alt_press_ms != 0 && - (now - last_alt_press_ms) <= kAltDoublePressMs) { + (now - last_alt_press_ms) <= kAltDoublePressMs) + { ui_take_screenshot_to_sd(); last_alt_press_ms = 0; return -1; } last_alt_press_ms = now; - if (ui_ime_is_active()) { + if (ui_ime_is_active()) + { ui_ime_toggle_mode(); - } else { + } + else + { alt_key_pressed = !alt_key_pressed; // Switch ALT mode } } return -1; - } else if (k == _config->backspace_value) { - if (pressed) { + } + else if (k == _config->backspace_value) + { + if (pressed) + { *c = '\b'; // Backspace character lastKeyVal = '\b'; lastState = true; lastPressedTime = millis(); return KB_PRESSED; - } else { + } + else + { lastState = false; lastPressedTime = 0; } @@ -292,21 +324,29 @@ int LilyGoKeyboard::handleSpecialKeys(uint8_t k, bool pressed, char *c) bool LilyGoKeyboard::handleBrightnessAdjustment(uint8_t k, bool pressed) { static bool adjust_brightness_pressed = false; - if (pressed) { - if (alt_key_pressed && k == _config->char_b_value) { - if (_backlight != -1 || (this->bl_cb != NULL)) { + if (pressed) + { + if (alt_key_pressed && k == _config->char_b_value) + { + if (_backlight != -1 || (this->bl_cb != NULL)) + { // ALT+B toggle brightness _brightness = (_brightness > 0) ? 0 : 127; - if (this->bl_cb) { + if (this->bl_cb) + { this->bl_cb(_brightness); - } else if (_backlight != -1) { + } + else if (_backlight != -1) + { setBrightness(_brightness); } adjust_brightness_pressed = true; return true; } } - } else if (adjust_brightness_pressed) { + } + else if (adjust_brightness_pressed) + { adjust_brightness_pressed = false; return true; } @@ -318,27 +358,32 @@ char LilyGoKeyboard::getKeyChar(uint8_t k) uint8_t row = k / 10; uint8_t col = k % 10; - if (row >= _config->kb_rows || col >= _config->kb_cols) { + if (row >= _config->kb_rows || col >= _config->kb_cols) + { log_e("Returns a null character if out of bounds"); return '\0'; // Return empty character if out of bounds } char keyVal; - if (symbol_key_pressed) { + if (symbol_key_pressed) + { // Symbol mode: access the current symbol map (first address + offset) keyVal = *(_config->current_symbol_map + row * _config->kb_cols + col); - } else { + } + else + { // Character mode: access the current character map keyVal = *(_config->current_keymap + row * _config->kb_cols + col); // Uppercase conversion (skipping null characters) - if (cap_key_pressed && keyVal != '\0') { + if (cap_key_pressed && keyVal != '\0') + { keyVal = toupper(keyVal); } } return keyVal; } -char LilyGoKeyboard::handleSpaceAndNullChar(char keyVal, char &lastKeyVal, bool &pressed) +char LilyGoKeyboard::handleSpaceAndNullChar(char keyVal, char& lastKeyVal, bool& pressed) { #if 0 @@ -362,19 +407,24 @@ char LilyGoKeyboard::handleSpaceAndNullChar(char keyVal, char &lastKeyVal, bool } #else // 符号模式下空格无效,统一转换为'\0' - if (symbol_key_pressed && keyVal == ' ') { + if (symbol_key_pressed && keyVal == ' ') + { keyVal = '\0'; } // 非符号模式下处理空格逻辑 - else if (!symbol_key_pressed) { + else if (!symbol_key_pressed) + { // 有符号键的配置:连续空字符视为空格 - if (_config->has_symbol_key) { - if (keyVal == '\0' && lastKeyVal == '\0' && pressed) { + if (_config->has_symbol_key) + { + if (keyVal == '\0' && lastKeyVal == '\0' && pressed) + { keyVal = ' '; } } // 无符号键的配置:上一个键为空字符则当前转换为空格 - else if (lastKeyVal == '\0') { + else if (lastKeyVal == '\0') + { keyVal = ' '; pressed = true; } @@ -393,27 +443,31 @@ void LilyGoKeyboard::printDebugInfo(bool pressed, uint8_t k, char keyVal) Serial.printf("Char:'%c' (0x%X)\n", keyVal, keyVal); } -int LilyGoKeyboard::update(char *c) +int LilyGoKeyboard::update(char* c) { char keyVal = '\0'; uint8_t k = this->getEvent(); - if (k == 0) { + if (k == 0) + { return -1; // No event } - bool pressed = (k & 0x80) != 0; //The highest bit indicates the pressed state - k &= 0x7F; // Clear the status bit and keep the original key value + bool pressed = (k & 0x80) != 0; // The highest bit indicates the pressed state + k &= 0x7F; // Clear the status bit and keep the original key value // When this callback is set, the program only returns the original key // value and does not continue with subsequent processing. The user needs to handle it by himself. - if (this->raw_cb) { + if (this->raw_cb) + { this->raw_cb(pressed, k); return -1; } - if (k > 96) { + if (k > 96) + { uint8_t idx = k - 97; - if (this->gpio_cb) { + if (this->gpio_cb) + { this->gpio_cb(pressed, idx); } return -1; @@ -424,20 +478,23 @@ int LilyGoKeyboard::update(char *c) // Check if the key value is within the current mapping range uint8_t row = k / 10; - if (row >= _config->kb_rows) { + if (row >= _config->kb_rows) + { log_e("Key values out of range are ignored,current row:%d k:%d , _config->kb_cols:%d\n", row, k, _config->kb_cols); return -1; } // Handling special keys int specialKeyResult = handleSpecialKeys(k, pressed, c); - if (specialKeyResult != 0) { + if (specialKeyResult != 0) + { Serial.println("return specialKeyResult"); return specialKeyResult; } // Handling brightness adjustments - if (handleBrightnessAdjustment(k, pressed)) { + if (handleBrightnessAdjustment(k, pressed)) + { Serial.println("return handleBrightnessAdjustment"); return -1; } @@ -452,7 +509,8 @@ int LilyGoKeyboard::update(char *c) // Update state variables lastKeyVal = keyVal; - if (c) { + if (c) + { *c = keyVal; } @@ -462,7 +520,4 @@ int LilyGoKeyboard::update(char *c) return pressed ? KB_PRESSED : KB_RELEASED; } - #endif // USING_INPUT_DEV_KEYBOARD - - diff --git a/src/board/LilyGoKeyboard.h b/src/board/LilyGoKeyboard.h index f3e9dea0..22cb8a24 100644 --- a/src/board/LilyGoKeyboard.h +++ b/src/board/LilyGoKeyboard.h @@ -13,15 +13,16 @@ #ifdef USING_INPUT_DEV_KEYBOARD #include -#define KB_NONE -1 -#define KB_PRESSED 1 +#define KB_NONE -1 +#define KB_PRESSED 1 #define KB_RELEASED 0 -typedef struct LilyGoKeyboardConfigure { +typedef struct LilyGoKeyboardConfigure +{ uint8_t kb_rows; uint8_t kb_cols; - const char *current_keymap; - const char *current_symbol_map; + const char* current_keymap; + const char* current_symbol_map; uint8_t symbol_key_value; uint8_t alt_key_value; uint8_t caps_key_value; @@ -30,15 +31,16 @@ typedef struct LilyGoKeyboardConfigure { uint8_t backspace_value; // Is there a symbol combination key? bool has_symbol_key; -} LilyGoKeyboardConfigure_t;; +} LilyGoKeyboardConfigure_t; +; // This class, LilyGoKeyboard, inherits from Adafruit_TCA8418 and is designed to handle keyboard operations. class LilyGoKeyboard : public Adafruit_TCA8418 { -public: + public: // Typedef for a callback function that is invoked when a key is read. // It takes an integer representing the key state and a reference to a character to store the key value. - using KeyboardReadCallback = void (*)(int state, char &c); + using KeyboardReadCallback = void (*)(int state, char& c); // Typedef for a callback function that is called when defined as a gpio. using GpioEventCallback = void (*)(bool pressed, uint8_t gpio_idx); @@ -84,7 +86,7 @@ public: * @param scl The I2C clock line pin number. Defaults to the SCL macro. * @return true if the initialization is successful, false otherwise. */ - bool begin(const LilyGoKeyboardConfigure_t &config, TwoWire &w, uint8_t irq, uint8_t sda = SDA, uint8_t scl = SCL); + bool begin(const LilyGoKeyboardConfigure_t& config, TwoWire& w, uint8_t irq, uint8_t sda = SDA, uint8_t scl = SCL); /** * @brief Ends the keyboard operation and releases associated resources. @@ -97,7 +99,7 @@ public: * @param c A pointer to a character where the key value will be stored. * @return An integer representing the state of the key press. */ - int getKey(char *c); + int getKey(char* c); /** * @brief Sets the brightness level of the keyboard backlight. @@ -152,14 +154,14 @@ public: */ void setRepeat(bool enable); -private: + private: /** * @brief Updates the keyboard state and retrieves the currently pressed key. * * @param c A pointer to a character where the key value will be stored. * @return An integer representing the state of the key press. */ - int update(char *c); + int update(char* c); /** * @brief Prints debug information about the key press event. @@ -178,7 +180,7 @@ private: * @param pressed A reference to a boolean indicating if the key is pressed. * @return The processed character value. */ - char handleSpaceAndNullChar(char keyVal, char &lastKeyVal, bool &pressed); + char handleSpaceAndNullChar(char keyVal, char& lastKeyVal, bool& pressed); /** * @brief Converts a key code to its corresponding character value. @@ -205,7 +207,7 @@ private: * @param c A pointer to a character to store the result of the special key action. * @return An integer representing the state of the special key action. */ - int handleSpecialKeys(uint8_t k, bool pressed, char *c); + int handleSpecialKeys(uint8_t k, bool pressed, char* c); // Stores the last key value. char lastKeyVal = '\n'; @@ -236,8 +238,6 @@ private: // The time when the last key was pressed. uint32_t lastPressedTime = 0; // Pointer to the storage keyboard config - const LilyGoKeyboardConfigure_t *_config; - + const LilyGoKeyboardConfigure_t* _config; }; #endif - diff --git a/src/board/TLoRaPagerBoard.cpp b/src/board/TLoRaPagerBoard.cpp index 3a8dec46..9669fa63 100644 --- a/src/board/TLoRaPagerBoard.cpp +++ b/src/board/TLoRaPagerBoard.cpp @@ -6,13 +6,13 @@ #include "freertos/task.h" #include "freertos/timers.h" -#include #include +#include #include "display/drivers/ST7796.h" #include "pins_arduino.h" -#include #include "ui/widgets/system_notification.h" +#include // ------------------------------ // I2C addresses from board configuration @@ -43,15 +43,13 @@ static constexpr char keymap[4][10] = { {'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'}, {'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '\n'}, {'\0', 'z', 'x', 'c', 'v', 'b', 'n', 'm', '\0', '\0'}, - {' ',/*Space*/ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'} -}; + {' ', /*Space*/ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'}}; // 4x10 symbol map static constexpr char symbol_map[4][10] = { {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}, {'*', '/', '+', '-', '=', ':', '\'', '"', '@', '\0'}, {'\0', '_', '$', ';', '?', '!', ',', '.', '\0', '\0'}, - {' '/*Space*/, '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'} -}; + {' ' /*Space*/, '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'}}; static const LilyGoKeyboardConfigure_t keyboardConfig = { .kb_rows = 4, @@ -64,8 +62,7 @@ static const LilyGoKeyboardConfigure_t keyboardConfig = { .caps_b_key_value = 0xFF, .char_b_value = 0x19, .backspace_value = 0x1D, - .has_symbol_key = false -}; + .has_symbol_key = false}; #endif #ifdef USING_ST25R3916 @@ -80,8 +77,9 @@ static TimerHandle_t hapticStopTimer; static void hapticStopCallback(TimerHandle_t timer) { - auto *board = static_cast(pvTimerGetTimerID(timer)); - if (board) { + auto* board = static_cast(pvTimerGetTimerID(timer)); + if (board) + { board->stopVibrator(); } } @@ -89,7 +87,7 @@ static void hapticStopCallback(TimerHandle_t timer) /** * @brief Read rotary encoder center button state with debouncing * @return true if button is pressed (LOW), false otherwise - * + * * This function implements debouncing logic to filter out mechanical switch bounce. * It also handles the TASK_ROTARY_START_PRESSED_FLAG to prevent multiple triggers. */ @@ -98,55 +96,64 @@ static bool getButtonState() static uint8_t buttonState = HIGH; static uint8_t lastButtonState = HIGH; static uint32_t lastDebounceTime = 0; - const uint8_t debounceDelay = 20; // Debounce delay in milliseconds - + const uint8_t debounceDelay = 20; // Debounce delay in milliseconds + int reading = digitalRead(ROTARY_C); // Check if button press flag is set (prevents multiple triggers) EventBits_t eventBits = xEventGroupGetBits(rotaryTaskFlag); - if (eventBits & TASK_ROTARY_START_PRESSED_FLAG) { - if (reading == HIGH) { + if (eventBits & TASK_ROTARY_START_PRESSED_FLAG) + { + if (reading == HIGH) + { // Button released, clear the flag xEventGroupClearBits(rotaryTaskFlag, TASK_ROTARY_START_PRESSED_FLAG); - } else { + } + else + { // Button still pressed, don't trigger again return false; } } // Debouncing logic - if (reading != lastButtonState) { + if (reading != lastButtonState) + { // State changed, reset debounce timer lastDebounceTime = millis(); } - - if (millis() - lastDebounceTime > debounceDelay) { + + if (millis() - lastDebounceTime > debounceDelay) + { // Debounce period elapsed, update state if changed - if (reading != buttonState) { + if (reading != buttonState) + { buttonState = reading; - if (buttonState == LOW) { + if (buttonState == LOW) + { // Button pressed (LOW = pressed due to pull-up) lastButtonState = reading; return true; } } } - + lastButtonState = reading; return false; } TLoRaPagerBoard::TLoRaPagerBoard() : LilyGo_Display(SPI_DRIVER, false), - LilyGoDispArduinoSPI(DISP_WIDTH, DISP_HEIGHT, - display::drivers::ST7796::getInitCommands(), - display::drivers::ST7796::getInitCommandsCount(), - // T-LoRa-Pager specific offsets: - // - Landscape orientations (90°, 270°): landscape_offset_x = 49 - // - Portrait orientations (0°, 180°): portrait_offset_y = 49 - display::drivers::ST7796::getRotationConfig(DISP_WIDTH, DISP_HEIGHT, 49, 49)) + LilyGoDispArduinoSPI(DISP_WIDTH, DISP_HEIGHT, + display::drivers::ST7796::getInitCommands(), + display::drivers::ST7796::getInitCommandsCount(), + // T-LoRa-Pager specific offsets: + // - Landscape orientations (90°, 270°): landscape_offset_x = 49 + // - Portrait orientations (0°, 180°): portrait_offset_y = 49 + display::drivers::ST7796::getRotationConfig(DISP_WIDTH, DISP_HEIGHT, 49, 49)) #ifdef USING_ST25R3916 - , nfc(&NFCReader) + , + nfc(&NFCReader) #endif { devices_probe = 0; @@ -156,7 +163,7 @@ TLoRaPagerBoard::~TLoRaPagerBoard() { } -TLoRaPagerBoard *TLoRaPagerBoard::getInstance() +TLoRaPagerBoard* TLoRaPagerBoard::getInstance() { static TLoRaPagerBoard instance; return &instance; @@ -170,7 +177,8 @@ void TLoRaPagerBoard::initShareSPIPins() SD_CS, LORA_RST, }; - for (auto pin : share_spi_bus_devices_cs_pins) { + for (auto pin : share_spi_bus_devices_cs_pins) + { pinMode(pin, OUTPUT); digitalWrite(pin, HIGH); } @@ -181,9 +189,10 @@ uint32_t TLoRaPagerBoard::begin(uint32_t disable_hw_init) Serial.printf("[TLoRaPagerBoard::begin] ===== HARDWARE INITIALIZATION START =====\n"); Serial.printf("[TLoRaPagerBoard::begin] disable_hw_init=0x%08X\n", disable_hw_init); Serial.printf("[TLoRaPagerBoard::begin] NO_HW_GPS flag: %s\n", (disable_hw_init & NO_HW_GPS) ? "SET (GPS will be SKIPPED)" : "NOT SET (GPS will be initialized)"); - + static bool initialized = false; - if (initialized) { + if (initialized) + { Serial.printf("[TLoRaPagerBoard::begin] Already initialized, returning devices_probe=0x%08X\n", devices_probe); return devices_probe; } @@ -193,8 +202,9 @@ uint32_t TLoRaPagerBoard::begin(uint32_t disable_hw_init) devices_probe = 0x00; - while (!psramFound()) { - log_d("ERROR:PSRAM NOT FOUND!"); + while (!psramFound()) + { + log_d("ERROR:PSRAM NOT FOUND!"); delay(1000); } @@ -203,9 +213,12 @@ uint32_t TLoRaPagerBoard::begin(uint32_t disable_hw_init) Wire.begin(SDA, SCL); // Initialize battery gauge (BQ27220) - if (!gauge.begin(Wire, SDA, SCL)) { + if (!gauge.begin(Wire, SDA, SCL)) + { log_w("Battery gauge (BQ27220) not found"); - } else { + } + else + { log_d("Battery gauge initialized successfully"); devices_probe |= HW_GAUGE_ONLINE; // Configure battery capacity (1500mAh for T-LoRa-Pager) @@ -217,57 +230,66 @@ uint32_t TLoRaPagerBoard::begin(uint32_t disable_hw_init) // Initialize PMU (BQ25896 power management) res = initPMU(); - if (!res) { + if (!res) + { log_w("PMU (BQ25896) not found"); - } else { + } + else + { log_d("PMU initialized successfully"); devices_probe |= HW_PMU_ONLINE; } // Initialize GPIO expander (XL9555) - controls power for various peripherals #ifdef USING_XL9555_EXPANDS - if (io.begin(Wire, 0x20)) { + if (io.begin(Wire, 0x20)) + { log_d("GPIO expander (XL9555) initialized successfully"); devices_probe |= HW_EXPAND_ONLINE; - + // Configure GPIO expander pins as outputs and set them HIGH (enable peripherals) const uint8_t expand_pins[] = { - EXPANDS_KB_RST, // Keyboard reset - EXPANDS_LORA_EN, // LoRa enable - EXPANDS_GPS_EN, // GPS enable - EXPANDS_DRV_EN, // Haptic driver enable - EXPANDS_AMP_EN, // Audio amplifier enable - EXPANDS_NFC_EN, // NFC enable + EXPANDS_KB_RST, // Keyboard reset + EXPANDS_LORA_EN, // LoRa enable + EXPANDS_GPS_EN, // GPS enable + EXPANDS_DRV_EN, // Haptic driver enable + EXPANDS_AMP_EN, // Audio amplifier enable + EXPANDS_NFC_EN, // NFC enable #ifdef EXPANDS_GPS_RST - EXPANDS_GPS_RST, // GPS reset + EXPANDS_GPS_RST, // GPS reset #endif #ifdef EXPANDS_KB_EN - EXPANDS_KB_EN, // Keyboard enable + EXPANDS_KB_EN, // Keyboard enable #endif #ifdef EXPANDS_GPIO_EN - EXPANDS_GPIO_EN, // GPIO enable + EXPANDS_GPIO_EN, // GPIO enable #endif #ifdef EXPANDS_SD_EN - EXPANDS_SD_EN, // SD card enable + EXPANDS_SD_EN, // SD card enable #endif }; - - for (auto pin : expand_pins) { + + for (auto pin : expand_pins) + { io.pinMode(pin, OUTPUT); - io.digitalWrite(pin, HIGH); // Enable peripheral power - delay(1); // Small delay for power stabilization + io.digitalWrite(pin, HIGH); // Enable peripheral power + delay(1); // Small delay for power stabilization } - + // SD card pull-up enable (input pin) io.pinMode(EXPANDS_SD_PULLEN, INPUT); - } else { + } + else + { log_w("GPIO expander (XL9555) initialization failed"); } #endif // Initialize sensor (BHI260AP) - optional, can be disabled - if (!(disable_hw_init & NO_HW_SENSOR)) { - if (initSensor()) { + if (!(disable_hw_init & NO_HW_SENSOR)) + { + if (initSensor()) + { log_d("Sensor (BHI260AP) initialized successfully"); } } @@ -291,29 +313,37 @@ uint32_t TLoRaPagerBoard::begin(uint32_t disable_hw_init) pinMode(NFC_INT, INPUT); // Initialize RTC (PCF85063) - optional - if (!(disable_hw_init & NO_HW_RTC)) { - if (initRTC()) { + if (!(disable_hw_init & NO_HW_RTC)) + { + if (initRTC()) + { log_d("RTC (PCF85063) initialized successfully"); } } // Initialize NFC (ST25R3916) - optional - if (!(disable_hw_init & NO_HW_NFC)) { - if (initNFC()) { + if (!(disable_hw_init & NO_HW_NFC)) + { + if (initNFC()) + { log_d("NFC (ST25R3916) initialized successfully"); } } // Initialize keyboard (TCA8418) - optional - if (!(disable_hw_init & NO_HW_KEYBOARD)) { - if (initKeyboard()) { + if (!(disable_hw_init & NO_HW_KEYBOARD)) + { + if (initKeyboard()) + { log_d("Keyboard (TCA8418) initialized successfully"); } } // Initialize haptic driver (DRV2605) - optional - if (!(disable_hw_init & NO_HW_DRV)) { - if (initDrv()) { + if (!(disable_hw_init & NO_HW_DRV)) + { + if (initDrv()) + { log_d("Haptic driver (DRV2605) initialized successfully"); } } @@ -321,24 +351,33 @@ uint32_t TLoRaPagerBoard::begin(uint32_t disable_hw_init) // GPS service is initialized by AppContext after configuration is loaded // Initialize LoRa radio - optional - if (!(disable_hw_init & NO_HW_LORA)) { - if (initLoRa()) { + if (!(disable_hw_init & NO_HW_LORA)) + { + if (initLoRa()) + { log_d("LoRa radio initialized successfully"); } } // Initialize SD card - optional, with retry - if (!(disable_hw_init & NO_HW_SD)) { + if (!(disable_hw_init & NO_HW_SD)) + { const int max_retries = 2; - for (int retry = 0; retry < max_retries; retry++) { - if (installSD()) { + for (int retry = 0; retry < max_retries; retry++) + { + if (installSD()) + { log_d("SD card initialized successfully"); devices_probe |= HW_SD_ONLINE; break; - } else if (retry < max_retries - 1) { + } + else if (retry < max_retries - 1) + { log_w("SD card initialization failed, retrying... (%d/%d)", retry + 1, max_retries); - delay(100); // Small delay before retry - } else { + delay(100); // Small delay before retry + } + else + { log_w("SD card not found after %d attempts", max_retries); } } @@ -346,17 +385,21 @@ uint32_t TLoRaPagerBoard::begin(uint32_t disable_hw_init) // Initialize audio codec (ES8311) - optional #ifdef USING_AUDIO_CODEC - if (!(disable_hw_init & NO_HW_CODEC)) { + if (!(disable_hw_init & NO_HW_CODEC)) + { codec.setPins(I2S_MCLK, I2S_SCK, I2S_WS, I2S_SDOUT, I2S_SDIN); - if (codec.begin(Wire, 0x18, CODEC_TYPE_ES8311)) { + if (codec.begin(Wire, 0x18, CODEC_TYPE_ES8311)) + { devices_probe |= HW_CODEC_ONLINE; log_d("Audio codec (ES8311) initialized successfully"); - + // Set power amplifier control callback - codec.setPaPinCallback([](bool enable, void *user_data) { - ((ExtensionIOXL9555 *)user_data)->digitalWrite(EXPANDS_AMP_EN, enable); - }, &io); - } else { + codec.setPaPinCallback([](bool enable, void* user_data) + { ((ExtensionIOXL9555*)user_data)->digitalWrite(EXPANDS_AMP_EN, enable); }, + &io); + } + else + { log_w("Audio codec (ES8311) not found"); } } @@ -364,29 +407,37 @@ uint32_t TLoRaPagerBoard::begin(uint32_t disable_hw_init) // Create rotary encoder message queue and task rotaryMsg = xQueueCreate(5, sizeof(RotaryMsg_t)); - if (rotaryMsg == nullptr) { + if (rotaryMsg == nullptr) + { log_e("Failed to create rotary encoder message queue"); } rotaryTaskFlag = xEventGroupCreate(); - if (rotaryTaskFlag == nullptr) { + if (rotaryTaskFlag == nullptr) + { log_e("Failed to create rotary encoder event group"); } BaseType_t task_result = xTaskCreate(rotaryTask, "rotary", 2 * 1024, NULL, 10, &rotaryHandler); - if (task_result != pdPASS) { + if (task_result != pdPASS) + { log_e("Failed to create rotary encoder task"); - } else { + } + else + { log_d("Rotary encoder task created successfully"); } // Initialize power button handling - if (!initPowerButton()) { + if (!initPowerButton()) + { log_w("Power button initialization failed"); - } else { + } + else + { log_d("Power button initialized successfully"); } - + log_d("Board initialization complete. Hardware online: 0x%08X", devices_probe); Serial.printf("[TLoRaPagerBoard::begin] ===== HARDWARE INITIALIZATION COMPLETE =====\n"); Serial.printf("[TLoRaPagerBoard::begin] devices_probe=0x%08X\n", devices_probe); @@ -400,8 +451,10 @@ void TLoRaPagerBoard::loop() { // Process NFC worker if NFC is online #ifdef USING_ST25R3916 - if (devices_probe & HW_NFC_ONLINE) { - if (LilyGoDispArduinoSPI::lock(0)) { // Try to lock, don't wait + if (devices_probe & HW_NFC_ONLINE) + { + if (LilyGoDispArduinoSPI::lock(0)) + { // Try to lock, don't wait NFCReader.rfalNfcWorker(); LilyGoDispArduinoSPI::unlock(); } @@ -412,7 +465,8 @@ void TLoRaPagerBoard::loop() bool TLoRaPagerBoard::initPMU() { bool res = pmu.init(Wire, SDA, SCL); - if (!res) { + if (!res) + { return false; } // Reset PMU @@ -439,9 +493,12 @@ bool TLoRaPagerBoard::initSensor() sensor.setFirmware(bosch_firmware_image, bosch_firmware_size, bosch_firmware_type); sensor.setBootFromFlash(false); res = sensor.begin(Wire); - if (!res) { + if (!res) + { log_e("Failed to find BHI260AP"); - } else { + } + else + { log_d("Initializing BHI260AP succeeded"); devices_probe |= HW_BHI260AP_ONLINE; sensor.setRemapAxes(SensorBHI260AP::BOTTOM_LAYER_TOP_LEFT_CORNER); @@ -456,12 +513,15 @@ bool TLoRaPagerBoard::initRTC() bool res = false; log_d("Init PCF85063 RTC"); res = rtc.begin(Wire); - if (!res) { + if (!res) + { log_e("Failed to find PCF85063"); - } else { + } + else + { devices_probe |= HW_RTC_ONLINE; log_d("Initializing PCF85063 succeeded"); - rtc.hwClockRead(); // Synchronize RTC clock to system clock + rtc.hwClockRead(); // Synchronize RTC clock to system clock rtc.setClockOutput(SensorPCF85063::CLK_LOW); pinMode(RTC_INT, INPUT_PULLUP); @@ -478,10 +538,13 @@ bool TLoRaPagerBoard::initDrv() powerControl(POWER_HAPTIC_DRIVER, true); delay(5); res = drv.begin(Wire); - if (!res) { + if (!res) + { log_e("Failed to find DRV2605"); powerControl(POWER_HAPTIC_DRIVER, false); - } else { + } + else + { log_d("Initializing DRV2605 succeeded"); drv.selectLibrary(1); drv.setMode(SensorDRV2605::MODE_INTTRIG); @@ -500,17 +563,20 @@ bool TLoRaPagerBoard::initNFC() #ifdef USING_ST25R3916 bool res = false; log_d("Init NFC"); - + // Enable NFC power before initialization powerControl(POWER_NFC, true); - delay(10); // Wait for power to stabilize - + delay(10); // Wait for power to stabilize + // Initialize NFC reader res = NFCReader.rfalNfcInitialize() == ST_ERR_NONE; - if (!res) { + if (!res) + { log_e("Failed to find NFC Reader"); powerControl(POWER_NFC, false); - } else { + } + else + { log_d("Initializing NFC Reader succeeded"); devices_probe |= HW_NFC_ONLINE; // Turn off NFC power after initialization (will be enabled when needed) @@ -527,14 +593,15 @@ bool TLoRaPagerBoard::initKeyboard() #ifdef USING_INPUT_DEV_KEYBOARD // Configure keyboard backlight pin kb.setPins(KB_BACKLIGHT); - + // Initialize keyboard (TCA8418 I2C keyboard controller) bool res = kb.begin(keyboardConfig, Wire, KB_INT); - if (!res) { + if (!res) + { log_w("Keyboard (TCA8418) not found"); return false; } - + log_d("Keyboard (TCA8418) initialized successfully"); devices_probe |= HW_KEYBOARD_ONLINE; return true; @@ -549,7 +616,8 @@ bool TLoRaPagerBoard::initLoRa() int state = radio.begin(); - if (state != RADIOLIB_ERR_NONE) { + if (state != RADIOLIB_ERR_NONE) + { devices_probe &= ~HW_RADIO_ONLINE; log_e("❌Radio init failed, code :%d", state); return false; @@ -564,9 +632,11 @@ bool TLoRaPagerBoard::installSD() { // Check SD card detection pin (if available) #ifdef EXPANDS_SD_DET - if (devices_probe & HW_EXPAND_ONLINE) { + if (devices_probe & HW_EXPAND_ONLINE) + { io.pinMode(EXPANDS_SD_DET, INPUT); - if (io.digitalRead(EXPANDS_SD_DET)) { + if (io.digitalRead(EXPANDS_SD_DET)) + { log_d("SD card detection pin indicates no card present"); return false; } @@ -575,20 +645,22 @@ bool TLoRaPagerBoard::installSD() // Ensure SPI pins are initialized initShareSPIPins(); - + // Initialize SD card with 4MHz SPI speed, mount point: /sd - if (!SD.begin(SD_CS, SPI, 4000000U, "/sd")) { + if (!SD.begin(SD_CS, SPI, 4000000U, "/sd")) + { log_w("SD card initialization failed"); return false; } - + // Verify card is actually present - if (SD.cardType() != CARD_NONE) { + if (SD.cardType() != CARD_NONE) + { uint64_t cardSizeMB = SD.cardSize() / (1024 * 1024); log_d("SD card detected, size: %llu MB", cardSizeMB); return true; } - + log_w("SD card type is NONE"); return false; } @@ -596,11 +668,14 @@ bool TLoRaPagerBoard::installSD() void TLoRaPagerBoard::uninstallSD() { // Safely unmount SD card (requires SPI lock) - if (LilyGoDispArduinoSPI::lock(portMAX_DELAY)) { + if (LilyGoDispArduinoSPI::lock(portMAX_DELAY)) + { SD.end(); LilyGoDispArduinoSPI::unlock(); log_d("SD card unmounted"); - } else { + } + else + { log_w("Failed to acquire SPI lock for SD card unmount"); } } @@ -609,7 +684,8 @@ bool TLoRaPagerBoard::isCardReady() { // Check if SD card is ready (requires SPI lock) bool ready = false; - if (LilyGoDispArduinoSPI::lock(pdTICKS_TO_MS(100))) { + if (LilyGoDispArduinoSPI::lock(pdTICKS_TO_MS(100))) + { ready = (SD.sectorSize() != 0); LilyGoDispArduinoSPI::unlock(); } @@ -618,7 +694,8 @@ bool TLoRaPagerBoard::isCardReady() void TLoRaPagerBoard::powerControl(PowerCtrlChannel_t ch, bool enable) { - switch (ch) { + switch (ch) + { case POWER_DISPLAY_BACKLIGHT: break; case POWER_RADIO: @@ -665,26 +742,32 @@ void TLoRaPagerBoard::vibrator() { log_d("[vibrator] Called, devices_probe=0x%08X, HW_DRV_ONLINE=%s, _haptic_effects=%d", devices_probe, (devices_probe & HW_DRV_ONLINE) ? "YES" : "NO", _haptic_effects); - + // Lazy re-init if needed - if (!(devices_probe & HW_DRV_ONLINE)) { + if (!(devices_probe & HW_DRV_ONLINE)) + { log_d("[vibrator] Device not online, attempting re-initialization..."); powerControl(POWER_HAPTIC_DRIVER, true); delay(5); log_d("[vibrator] Power enabled, calling drv.begin(Wire)..."); - if (drv.begin(Wire)) { + if (drv.begin(Wire)) + { log_d("[vibrator] drv.begin() succeeded, configuring driver..."); drv.selectLibrary(1); drv.setMode(SensorDRV2605::MODE_INTTRIG); drv.useERM(); devices_probe |= HW_DRV_ONLINE; log_d("[vibrator] Driver re-initialized successfully, devices_probe=0x%08X", devices_probe); - } else { + } + else + { powerControl(POWER_HAPTIC_DRIVER, false); log_e("[vibrator] Haptic driver re-initialization FAILED, skip vibrate"); return; } - } else { + } + else + { log_d("[vibrator] Device already online, skipping re-initialization"); } @@ -694,36 +777,48 @@ void TLoRaPagerBoard::vibrator() drv.setWaveform(1, 0); drv.run(); log_d("[vibrator] Vibration started, setting up stop timer..."); - - if (hapticStopTimer == nullptr) { + + if (hapticStopTimer == nullptr) + { log_d("[vibrator] Creating haptic stop timer..."); hapticStopTimer = xTimerCreate("haptic_stop", pdMS_TO_TICKS(2000), pdFALSE, this, hapticStopCallback); - if (hapticStopTimer == nullptr) { + if (hapticStopTimer == nullptr) + { log_e("[vibrator] FAILED to create haptic stop timer!"); - } else { + } + else + { log_d("[vibrator] Haptic stop timer created successfully"); } - } else { + } + else + { log_d("[vibrator] Haptic stop timer already exists, reusing it"); } - - if (hapticStopTimer != nullptr) { + + if (hapticStopTimer != nullptr) + { xTimerStop(hapticStopTimer, 0); xTimerChangePeriod(hapticStopTimer, pdMS_TO_TICKS(2000), 0); BaseType_t timer_result = xTimerStart(hapticStopTimer, 0); - if (timer_result == pdPASS) { + if (timer_result == pdPASS) + { log_d("[vibrator] Haptic stop timer started successfully (2s delay)"); - } else { + } + else + { log_e("[vibrator] FAILED to start haptic stop timer! result=%d", timer_result); } - } else { + } + else + { log_e("[vibrator] Cannot start timer - timer is nullptr!"); } - + log_d("[vibrator] Function completed"); } @@ -731,14 +826,17 @@ void TLoRaPagerBoard::stopVibrator() { log_d("[stopVibrator] Called, devices_probe=0x%08X, HW_DRV_ONLINE=%s", devices_probe, (devices_probe & HW_DRV_ONLINE) ? "YES" : "NO"); - - if (devices_probe & HW_DRV_ONLINE) { + + if (devices_probe & HW_DRV_ONLINE) + { log_d("[stopVibrator] Stopping driver..."); drv.stop(); - } else { + } + else + { log_w("[stopVibrator] Device not online, skipping drv.stop()"); } - + log_d("[stopVibrator] Disabling power..."); powerControl(POWER_HAPTIC_DRIVER, false); log_d("[stopVibrator] Power disabled, function completed"); @@ -755,17 +853,18 @@ uint8_t TLoRaPagerBoard::getHapticEffects() return _haptic_effects; } -int TLoRaPagerBoard::getKey(char *c) +int TLoRaPagerBoard::getKey(char* c) { #ifdef USING_INPUT_DEV_KEYBOARD - if (devices_probe & HW_KEYBOARD_ONLINE) { + if (devices_probe & HW_KEYBOARD_ONLINE) + { return kb.getKey(c); } #endif return -1; } -int TLoRaPagerBoard::getKeyChar(char *c) +int TLoRaPagerBoard::getKeyChar(char* c) { return getKey(c); } @@ -773,17 +872,19 @@ int TLoRaPagerBoard::getKeyChar(char *c) #ifdef USING_ST25R3916 bool TLoRaPagerBoard::startNFCDiscovery(uint8_t techs2Find, uint16_t totalDuration) { - if (!(devices_probe & HW_NFC_ONLINE)) { + if (!(devices_probe & HW_NFC_ONLINE)) + { log_e("NFC not initialized"); return false; } // Enable NFC power powerControl(POWER_NFC, true); - delay(10); // Wait for power to stabilize + delay(10); // Wait for power to stabilize // Reinitialize NFC reader - if (NFCReader.rfalNfcInitialize() != ST_ERR_NONE) { + if (NFCReader.rfalNfcInitialize() != ST_ERR_NONE) + { log_e("Failed to reinitialize NFC"); powerControl(POWER_NFC, false); return false; @@ -794,12 +895,13 @@ bool TLoRaPagerBoard::startNFCDiscovery(uint8_t techs2Find, uint16_t totalDurati discover_params.devLimit = 1; discover_params.techs2Find = techs2Find; discover_params.GBLen = RFAL_NFCDEP_GB_MAX_LEN; - discover_params.notifyCb = nullptr; // Can be set by user if needed + discover_params.notifyCb = nullptr; // Can be set by user if needed discover_params.totalDuration = totalDuration; discover_params.wakeupEnabled = false; // Start discovery - if (NFCReader.rfalNfcDiscover(&discover_params) != ST_ERR_NONE) { + if (NFCReader.rfalNfcDiscover(&discover_params) != ST_ERR_NONE) + { log_e("Failed to start NFC discovery"); powerControl(POWER_NFC, false); return false; @@ -811,16 +913,17 @@ bool TLoRaPagerBoard::startNFCDiscovery(uint8_t techs2Find, uint16_t totalDurati void TLoRaPagerBoard::stopNFCDiscovery() { - if (!(devices_probe & HW_NFC_ONLINE)) { + if (!(devices_probe & HW_NFC_ONLINE)) + { return; } // Deactivate NFC NFCReader.rfalNfcDeactivate(true); - + // Turn off NFC power powerControl(POWER_NFC, false); - + log_d("NFC discovery stopped"); } #endif @@ -829,21 +932,24 @@ bool TLoRaPagerBoard::initGPS() { Serial.printf("[TLoRaPagerBoard::initGPS] Starting GPS initialization...\n"); Serial.printf("[TLoRaPagerBoard::initGPS] Opening Serial1: baud=38400, RX=%d, TX=%d\n", GPS_RX, GPS_TX); - + // Clear HW_GPS_ONLINE flag before attempting initialization // This ensures we don't have stale state if reinitializing devices_probe &= ~HW_GPS_ONLINE; - + Serial1.begin(38400, SERIAL_8N1, GPS_RX, GPS_TX); - delay(100); // Give Serial1 time to initialize + delay(100); // Give Serial1 time to initialize Serial.printf("[TLoRaPagerBoard::initGPS] Serial1 opened, calling gps.init(&Serial1)...\n"); bool result = gps.init(&Serial1); Serial.printf("[TLoRaPagerBoard::initGPS] gps.init() returned: %d\n", result); - if (result) { + if (result) + { Serial.printf("[TLoRaPagerBoard::initGPS] GPS initialized successfully, model: %s\n", gps.getModel().c_str()); devices_probe |= HW_GPS_ONLINE; Serial.printf("[TLoRaPagerBoard::initGPS] Set HW_GPS_ONLINE flag, devices_probe=0x%08X\n", devices_probe); - } else { + } + else + { Serial.printf("[TLoRaPagerBoard::initGPS] GPS initialization FAILED\n"); // Ensure flag is cleared on failure devices_probe &= ~HW_GPS_ONLINE; @@ -881,7 +987,7 @@ uint16_t TLoRaPagerBoard::height() return LilyGoDispArduinoSPI::_height; } -void TLoRaPagerBoard::pushColors(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *color) +void TLoRaPagerBoard::pushColors(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t* color) { LilyGoDispArduinoSPI::pushColors(x1, y1, x2, y2, color); } @@ -903,21 +1009,23 @@ bool TLoRaPagerBoard::hasKeyboard() bool TLoRaPagerBoard::syncTimeFromGPS(uint32_t gps_task_interval_ms) { // Check if GPS time is valid - if (!gps.date.isValid() || !gps.time.isValid()) { + if (!gps.date.isValid() || !gps.time.isValid()) + { Serial.printf("[TLoRaPagerBoard::syncTimeFromGPS] GPS time not valid (date valid=%d, time valid=%d)\n", - gps.date.isValid(), gps.time.isValid()); + gps.date.isValid(), gps.time.isValid()); return false; } - + // Check if RTC is ready - if (!isRTCReady()) { + if (!isRTCReady()) + { Serial.printf("[TLoRaPagerBoard::syncTimeFromGPS] RTC not ready\n"); return false; } - + // Record timestamp when we start reading GPS time (for delay compensation) uint32_t read_start_ms = millis(); - + // Get GPS date and time uint16_t year = gps.date.year(); uint8_t month = gps.date.month(); @@ -925,21 +1033,22 @@ bool TLoRaPagerBoard::syncTimeFromGPS(uint32_t gps_task_interval_ms) uint8_t hour = gps.time.hour(); uint8_t minute = gps.time.minute(); uint8_t second = gps.time.second(); - + // Get satellite count for logging (may be 0 even if time is valid) uint8_t sat_count = gps.satellites.value(); bool has_fix = gps.location.isValid(); - + // Validate date/time values (basic sanity check) - if (year < 2020 || year > 2100 || - month < 1 || month > 12 || + if (year < 2020 || year > 2100 || + month < 1 || month > 12 || day < 1 || day > 31 || - hour >= 24 || minute >= 60 || second >= 60) { + hour >= 24 || minute >= 60 || second >= 60) + { Serial.printf("[TLoRaPagerBoard::syncTimeFromGPS] Invalid GPS time values: %04d-%02d-%02d %02d:%02d:%02d\n", - year, month, day, hour, minute, second); + year, month, day, hour, minute, second); return false; } - + // Calculate delay compensation: // The GPS task runs periodically, so we need to compensate for various delays: // 1. GPS NMEA message age: NMEA messages are typically 0.5-2 seconds old when received @@ -948,171 +1057,190 @@ bool TLoRaPagerBoard::syncTimeFromGPS(uint32_t gps_task_interval_ms) // However, GPS module updates time every second, so worst case is ~1s old (not N seconds) // 3. Processing delay: time from reading GPS data to setting RTC (typically < 100ms) // 4. RTC write delay: I2C communication time (typically < 50ms) - + uint32_t processing_delay_ms = millis() - read_start_ms; - + // Estimate GPS message age: NMEA messages are typically 1 second old (1Hz update rate) // For higher update rates (5Hz, 10Hz), this would be smaller, but 1Hz is most common // Note: Even if GPS task runs every 60s, GPS module itself updates time every second, // so the time data is at most ~1 second old (worst case: we read just before next update) - const uint32_t estimated_gps_message_age_ms = 1000; // Typical NMEA 1Hz update = 1 second old - + const uint32_t estimated_gps_message_age_ms = 1000; // Typical NMEA 1Hz update = 1 second old + // However, we should also consider that GPS time might not be perfectly synchronized // with the actual current time. GPS time from satellites can have some inherent delay. // For better accuracy, we use a more conservative estimate: 2 seconds total // But if GPS task interval is very large (e.g., 60s), we should be more conservative - const uint32_t base_delay_ms = 2000; // Base conservative estimate: 2 seconds - + const uint32_t base_delay_ms = 2000; // Base conservative estimate: 2 seconds + // If GPS task interval is provided and is large, add additional compensation // (though GPS module updates every second, large task intervals mean we might miss // the most recent update, so add half the interval as additional safety margin) // However, we cap this at a reasonable maximum (e.g., 5 seconds) to avoid over-compensation uint32_t task_interval_compensation_ms = 0; - if (gps_task_interval_ms > 0 && gps_task_interval_ms > 5000) { + if (gps_task_interval_ms > 0 && gps_task_interval_ms > 5000) + { // For large intervals (>5s), add compensation, but cap at 5 seconds // This accounts for the possibility that we read GPS data just before it updates task_interval_compensation_ms = (gps_task_interval_ms / 2); - if (task_interval_compensation_ms > 5000) { - task_interval_compensation_ms = 5000; // Cap at 5 seconds + if (task_interval_compensation_ms > 5000) + { + task_interval_compensation_ms = 5000; // Cap at 5 seconds } } - + // Total delay = base delay + task interval compensation + processing delay uint32_t total_delay_ms = base_delay_ms + task_interval_compensation_ms + processing_delay_ms; - + // Log original GPS time before compensation for debugging Serial.printf("[TLoRaPagerBoard::syncTimeFromGPS] Original GPS time: %04d-%02d-%02d %02d:%02d:%02d\n", - year, month, day, hour, minute, second); - + year, month, day, hour, minute, second); + // Add delay compensation to seconds (round to nearest second) uint32_t total_seconds = (uint32_t)hour * 3600 + (uint32_t)minute * 60 + (uint32_t)second; - uint32_t delay_seconds = (total_delay_ms + 500) / 1000; // Round to nearest second + uint32_t delay_seconds = (total_delay_ms + 500) / 1000; // Round to nearest second total_seconds += delay_seconds; - + // Handle day overflow - if (total_seconds >= 86400) { + if (total_seconds >= 86400) + { total_seconds -= 86400; day++; // Handle month overflow (simplified - doesn't handle all edge cases like Feb 29) uint8_t days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; uint8_t max_days = days_in_month[month - 1]; // Handle leap year for February - if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) { + if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) + { max_days = 29; } - if (day > max_days) { + if (day > max_days) + { day = 1; month++; - if (month > 12) { + if (month > 12) + { month = 1; year++; } } } - + // Convert back to hour, minute, second hour = (total_seconds / 3600) % 24; minute = (total_seconds / 60) % 60; second = total_seconds % 60; - + // Set RTC time from GPS (with delay compensation) rtc.setDateTime(year, month, day, hour, minute, second); - + // Record timestamp after RTC write (for logging) uint32_t write_end_ms = millis(); uint32_t total_operation_ms = write_end_ms - read_start_ms; - + // Note: GPS time can be valid even without location fix // Time information requires fewer satellites than location fix (typically 1-2 vs 4+) Serial.printf("[TLoRaPagerBoard::syncTimeFromGPS] Time synced: %04d-%02d-%02d %02d:%02d:%02d (sat=%d, has_fix=%d, base_delay=%lums, task_comp=%lums, proc_delay=%lums, total_delay=%lums, op_time=%lums)\n", - year, month, day, hour, minute, second, sat_count, has_fix, - base_delay_ms, task_interval_compensation_ms, processing_delay_ms, total_delay_ms, total_operation_ms); + year, month, day, hour, minute, second, sat_count, has_fix, + base_delay_ms, task_interval_compensation_ms, processing_delay_ms, total_delay_ms, total_operation_ms); return true; } -bool TLoRaPagerBoard::getRTCTimeString(char *buffer, size_t buffer_size, bool show_seconds) +bool TLoRaPagerBoard::getRTCTimeString(char* buffer, size_t buffer_size, bool show_seconds) { - if (!isRTCReady() || buffer == nullptr) { + if (!isRTCReady() || buffer == nullptr) + { return false; } - + // Check buffer size based on format - if (show_seconds && buffer_size < 9) { - return false; // Need at least 9 bytes for "HH:MM:SS\0" + if (show_seconds && buffer_size < 9) + { + return false; // Need at least 9 bytes for "HH:MM:SS\0" } - if (!show_seconds && buffer_size < 6) { - return false; // Need at least 6 bytes for "HH:MM\0" + if (!show_seconds && buffer_size < 6) + { + return false; // Need at least 6 bytes for "HH:MM\0" } - + // Read the time registers directly via I2C // PCF85063 time registers (I2C address 0x51, registers 0x04-0x06) // Register 0x04: Seconds (BCD format) - // Register 0x05: Minutes (BCD format) + // Register 0x05: Minutes (BCD format) // Register 0x06: Hours (BCD format) - + uint8_t hour, minute, second = 0; - + // Use the same Wire instance that RTC uses // For minimum resource usage, start reading from minutes register (0x05) if not showing seconds - uint8_t start_register = show_seconds ? 0x04 : 0x05; // Start at seconds or minutes - uint8_t bytes_to_read = show_seconds ? 3 : 2; // Read 3 bytes (sec,min,hour) or 2 bytes (min,hour) - - Wire.beginTransmission(0x51); // PCF85063 I2C address (0x51 = 0xA2 >> 1) + uint8_t start_register = show_seconds ? 0x04 : 0x05; // Start at seconds or minutes + uint8_t bytes_to_read = show_seconds ? 3 : 2; // Read 3 bytes (sec,min,hour) or 2 bytes (min,hour) + + Wire.beginTransmission(0x51); // PCF85063 I2C address (0x51 = 0xA2 >> 1) Wire.write(start_register); uint8_t error = Wire.endTransmission(); - if (error != 0) { + if (error != 0) + { // I2C communication failed - try alternative address // Some PCF85063 modules use 0x68 instead of 0x51 Wire.beginTransmission(0x68); Wire.write(start_register); error = Wire.endTransmission(); - if (error != 0) { + if (error != 0) + { return false; } Wire.requestFrom((uint8_t)0x68, (uint8_t)bytes_to_read); - } else { + } + else + { Wire.requestFrom((uint8_t)0x51, (uint8_t)bytes_to_read); } - - if (Wire.available() < bytes_to_read) { + + if (Wire.available() < bytes_to_read) + { return false; } - - if (show_seconds) { + + if (show_seconds) + { uint8_t sec_bcd = Wire.read(); uint8_t min_bcd = Wire.read(); uint8_t hour_bcd = Wire.read(); - + // Convert BCD to decimal second = ((sec_bcd >> 4) & 0x07) * 10 + (sec_bcd & 0x0F); minute = ((min_bcd >> 4) & 0x07) * 10 + (min_bcd & 0x0F); hour = ((hour_bcd >> 4) & 0x03) * 10 + (hour_bcd & 0x0F); - + // Validate values - if (hour >= 24 || minute >= 60 || second >= 60) { + if (hour >= 24 || minute >= 60 || second >= 60) + { return false; } - + // Format time string as HH:MM:SS snprintf(buffer, buffer_size, "%02d:%02d:%02d", hour, minute, second); - } else { + } + else + { // Read only minutes and hours (skip seconds register entirely) uint8_t min_bcd = Wire.read(); uint8_t hour_bcd = Wire.read(); - + // Convert BCD to decimal minute = ((min_bcd >> 4) & 0x07) * 10 + (min_bcd & 0x0F); hour = ((hour_bcd >> 4) & 0x03) * 10 + (hour_bcd & 0x0F); - + // Validate values - if (hour >= 24 || minute >= 60) { + if (hour >= 24 || minute >= 60) + { return false; } - + // Format time string as HH:MM (minimum resource usage) snprintf(buffer, buffer_size, "%02d:%02d", hour, minute); } - + return true; } @@ -1131,7 +1259,8 @@ static int daysInMonth(int year, int month) static const int kDaysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int days = kDaysInMonth[month - 1]; bool leap = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); - if (month == 2 && leap) { + if (month == 2 && leap) + { days = 29; } return days; @@ -1139,36 +1268,44 @@ static int daysInMonth(int year, int month) bool TLoRaPagerBoard::adjustRTCByOffsetMinutes(int offset_minutes) { - if (!isRTCReady()) { + if (!isRTCReady()) + { return false; } - if (offset_minutes == 0) { + if (offset_minutes == 0) + { return true; } uint8_t start_register = 0x04; - uint8_t bytes_to_read = 7; // sec, min, hour, day, weekday, month, year + uint8_t bytes_to_read = 7; // sec, min, hour, day, weekday, month, year uint8_t buf[7] = {0}; Wire.beginTransmission(0x51); Wire.write(start_register); uint8_t error = Wire.endTransmission(); - if (error != 0) { + if (error != 0) + { Wire.beginTransmission(0x68); Wire.write(start_register); error = Wire.endTransmission(); - if (error != 0) { + if (error != 0) + { return false; } Wire.requestFrom((uint8_t)0x68, bytes_to_read); - } else { + } + else + { Wire.requestFrom((uint8_t)0x51, bytes_to_read); } - if (Wire.available() < bytes_to_read) { + if (Wire.available() < bytes_to_read) + { return false; } - for (uint8_t i = 0; i < bytes_to_read; ++i) { + for (uint8_t i = 0; i < bytes_to_read; ++i) + { buf[i] = Wire.read(); } @@ -1180,26 +1317,32 @@ bool TLoRaPagerBoard::adjustRTCByOffsetMinutes(int offset_minutes) int year = 2000 + bcdToDec(buf[6]); int total_minutes = hour * 60 + minute + offset_minutes; - while (total_minutes < 0) { + while (total_minutes < 0) + { total_minutes += 1440; day -= 1; - if (day < 1) { + if (day < 1) + { month -= 1; - if (month < 1) { + if (month < 1) + { month = 12; year -= 1; } day = daysInMonth(year, month); } } - while (total_minutes >= 1440) { + while (total_minutes >= 1440) + { total_minutes -= 1440; day += 1; int dim = daysInMonth(year, month); - if (day > dim) { + if (day > dim) + { day = 1; month += 1; - if (month > 12) { + if (month > 12) + { month = 1; year += 1; } @@ -1220,77 +1363,88 @@ bool board_adjust_rtc_by_offset_minutes(int offset_minutes) int TLoRaPagerBoard::getBatteryLevel() { - if (!isGaugeReady()) { + if (!isGaugeReady()) + { return -1; } - + // Get battery state of charge (percentage) from BQ27220 // Try library methods first, then fallback to direct I2C read - + int level = -1; - + // Attempt 1: Try common library methods (uncomment if library supports): // level = gauge.getSOC(); // level = gauge.getPercentage(); // level = gauge.stateOfCharge(); // level = gauge.getStateOfCharge(); // level = gauge.readSOC(); - + // Attempt 2: Direct I2C read if library methods don't work // BQ27220 I2C address: 0x55 (7-bit address) // SOC (State of Charge) register: 0x2C (according to BQ27220 datasheet) // Note: BQ27220 uses 16-bit registers, so we need to read 2 bytes - - if (level < 0) { + + if (level < 0) + { // Try direct I2C read // BQ27220 SOC register is at 0x2C (16-bit value, percentage 0-100) - uint8_t i2c_addr = 0x55; // BQ27220 default I2C address (7-bit) - + uint8_t i2c_addr = 0x55; // BQ27220 default I2C address (7-bit) + Wire.beginTransmission(i2c_addr); - Wire.write(0x2C); // SOC register (0x2C = StateOfCharge) + Wire.write(0x2C); // SOC register (0x2C = StateOfCharge) uint8_t error = Wire.endTransmission(); - if (error != 0) { + if (error != 0) + { // I2C communication failed return -1; } - + // BQ27220 registers are 16-bit, read 2 bytes Wire.requestFrom(i2c_addr, (uint8_t)2); - if (Wire.available() < 2) { + if (Wire.available() < 2) + { return -1; } - + // Read 16-bit value (little-endian: LSB first, then MSB) uint8_t lsb = Wire.read(); uint8_t msb = Wire.read(); uint16_t soc_raw = (uint16_t)msb << 8 | lsb; - + // BQ27220 SOC register (0x2C) format: // Returns percentage directly (0-100) as 16-bit value // Value represents remaining capacity as percentage of full charge capacity - - if (soc_raw <= 100) { - level = (int)soc_raw; // Already in percentage (0-100) - } else if (soc_raw <= 1000) { - level = (int)(soc_raw / 10); // Convert from 0.1% units (0-1000 -> 0-100) - } else { + + if (soc_raw <= 100) + { + level = (int)soc_raw; // Already in percentage (0-100) + } + else if (soc_raw <= 1000) + { + level = (int)(soc_raw / 10); // Convert from 0.1% units (0-1000 -> 0-100) + } + else + { // If value is very large, it might be capacity in mAh, not percentage // Try to convert: if it's around 1500 (battery capacity), it's not percentage - return -1; // Invalid value for percentage + return -1; // Invalid value for percentage } - + // Validate final value - if (level < 0 || level > 100) { + if (level < 0 || level > 100) + { return -1; } } - + return level; } bool TLoRaPagerBoard::isCharging() { - if (!isPMUReady()) { + if (!isPMUReady()) + { return false; } return false; @@ -1299,30 +1453,33 @@ bool TLoRaPagerBoard::isCharging() int TLoRaPagerBoard::readADC(uint8_t pin, uint8_t samples) { // Validate sample count (optimal: 8 samples for accuracy vs speed balance) - if (samples == 0 || samples > 64) { - samples = 8; // Default to 8 samples (optimal balance: accurate but fast) + if (samples == 0 || samples > 64) + { + samples = 8; // Default to 8 samples (optimal balance: accurate but fast) } - + // ESP32 ADC notes: // - ADC1: GPIO 32-39 (safe, no WiFi conflict) // - ADC2: GPIO 0, 2, 4, 12-15, 25-27 (conflicts with WiFi, avoid if WiFi is used) // - Use analogRead() which handles pin validation and attenuation setup - + // Multiple sampling with averaging for accuracy // This reduces noise while keeping resource usage minimal // 8 samples is optimal: good accuracy (~3-5% noise reduction) with minimal overhead (~1-2ms) uint32_t sum = 0; - + // Read multiple samples and sum them // No delay needed between samples - analogRead() has internal settling time - for (uint8_t i = 0; i < samples; i++) { + for (uint8_t i = 0; i < samples; i++) + { int value = analogRead(pin); - if (value < 0) { - return -1; // Invalid pin + if (value < 0) + { + return -1; // Invalid pin } sum += (uint32_t)value; } - + // Return average (rounded to nearest integer) return (int)((sum + samples / 2) / samples); } @@ -1331,42 +1488,45 @@ int TLoRaPagerBoard::readADCVoltage(uint8_t pin, uint8_t samples, uint8_t attenu { // Read raw ADC value (0-4095 for 12-bit ESP32 ADC) int adc_value = readADC(pin, samples); - if (adc_value < 0) { + if (adc_value < 0) + { return -1; } - + // Convert ADC value to voltage in millivolts based on attenuation // ESP32 ADC attenuation settings: // 0 = 0dB: 0-1.1V range (reference ~1.1V) // 1 = 2.5dB: 0-1.5V range (reference ~1.5V) // 2 = 6dB: 0-2.2V range (reference ~2.2V) // 3 = 11dB: 0-3.3V range (reference ~3.3V, most common for battery voltage) - + uint32_t voltage_mv = 0; - - switch (attenuation) { - case 0: // 0dB - voltage_mv = ((uint32_t)adc_value * 1100) / 4095; // 0-1.1V range - break; - case 1: // 2.5dB - voltage_mv = ((uint32_t)adc_value * 1500) / 4095; // 0-1.5V range - break; - case 2: // 6dB - voltage_mv = ((uint32_t)adc_value * 2200) / 4095; // 0-2.2V range - break; - case 3: // 11dB (default, most common) - default: - voltage_mv = ((uint32_t)adc_value * 3300) / 4095; // 0-3.3V range - break; + + switch (attenuation) + { + case 0: // 0dB + voltage_mv = ((uint32_t)adc_value * 1100) / 4095; // 0-1.1V range + break; + case 1: // 2.5dB + voltage_mv = ((uint32_t)adc_value * 1500) / 4095; // 0-1.5V range + break; + case 2: // 6dB + voltage_mv = ((uint32_t)adc_value * 2200) / 4095; // 0-2.2V range + break; + case 3: // 11dB (default, most common) + default: + voltage_mv = ((uint32_t)adc_value * 3300) / 4095; // 0-3.3V range + break; } - + return (int)voltage_mv; } RotaryMsg_t TLoRaPagerBoard::getRotary() { static RotaryMsg_t msg; - if (xQueueReceive(rotaryMsg, &msg, pdMS_TO_TICKS(50)) == pdPASS) { + if (xQueueReceive(rotaryMsg, &msg, pdMS_TO_TICKS(50)) == pdPASS) + { return msg; } msg.centerBtnPressed = false; @@ -1374,17 +1534,17 @@ RotaryMsg_t TLoRaPagerBoard::getRotary() return msg; } -void TLoRaPagerBoard::feedback(void *args) +void TLoRaPagerBoard::feedback(void* args) { (void)args; } // Power button handling variables static volatile bool power_button_event = false; -static volatile bool power_button_state = false; // true = pressed, false = released +static volatile bool power_button_state = false; // true = pressed, false = released static volatile uint32_t power_button_press_start = 0; -static const uint32_t POWER_BUTTON_LONG_PRESS_MS = 3000; // 3 seconds for shutdown -static const uint32_t POWER_BUTTON_DEBOUNCE_MS = 50; // Debounce delay +static const uint32_t POWER_BUTTON_LONG_PRESS_MS = 3000; // 3 seconds for shutdown +static const uint32_t POWER_BUTTON_DEBOUNCE_MS = 50; // Debounce delay /** * @brief Power button interrupt handler @@ -1393,22 +1553,25 @@ static const uint32_t POWER_BUTTON_DEBOUNCE_MS = 50; // Debounce delay static void IRAM_ATTR powerButtonISR() { static uint32_t last_interrupt_time = 0; - uint32_t current_time = micros() / 1000; // Convert to milliseconds + uint32_t current_time = micros() / 1000; // Convert to milliseconds // Debounce: ignore interrupts too close together - if (current_time - last_interrupt_time < POWER_BUTTON_DEBOUNCE_MS) { + if (current_time - last_interrupt_time < POWER_BUTTON_DEBOUNCE_MS) + { return; } last_interrupt_time = current_time; - bool current_button_state = (digitalRead(POWER_KEY) == LOW); // Active low + bool current_button_state = (digitalRead(POWER_KEY) == LOW); // Active low // Only trigger event on state change - if (current_button_state != power_button_state) { + if (current_button_state != power_button_state) + { power_button_state = current_button_state; power_button_event = true; - if (current_button_state) { + if (current_button_state) + { // Button pressed power_button_press_start = current_time; } @@ -1437,24 +1600,31 @@ void TLoRaPagerBoard::handlePowerButton() // 根据LilyGo文档:POWER键只负责从Power OFF状态唤醒,不负责关机 // "The power button is only valid when the device is turned off" - if (power_button_event) { - power_button_event = false; // Clear the event flag + if (power_button_event) + { + power_button_event = false; // Clear the event flag - if (power_button_state) { + if (power_button_state) + { // POWER键按下 - 这是一个唤醒信号 log_d("POWER button pressed - wake up signal"); // 检查是否从deep sleep唤醒 esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause(); - if (wakeup_reason == ESP_SLEEP_WAKEUP_EXT0) { + if (wakeup_reason == ESP_SLEEP_WAKEUP_EXT0) + { log_d("Waking up from deep sleep via POWER button"); wakeUp(); - } else { + } + else + { // 设备已经在运行状态 - POWER键按下可能用于其他功能 log_d("POWER button pressed while device is running"); // 可以在这里添加屏幕开关或其他功能 } - } else { + } + else + { // POWER键释放 log_d("POWER button released"); } @@ -1468,13 +1638,15 @@ void TLoRaPagerBoard::shutdown(bool save_data) (void)save_data; // 1) Stop rotary task (LilyGo: vTaskDelete(rotaryHandler)) - if (rotaryHandler != nullptr) { + if (rotaryHandler != nullptr) + { vTaskDelete(rotaryHandler); rotaryHandler = nullptr; } // 2) Disable keyboard if online - if (devices_probe & HW_KEYBOARD_ONLINE) { + if (devices_probe & HW_KEYBOARD_ONLINE) + { kb.end(); } @@ -1511,7 +1683,8 @@ void TLoRaPagerBoard::shutdown(bool save_data) EXPANDS_SD_DET, #endif /*EXPANDS_SD_DET*/ }; - for (auto pin : expands) { + for (auto pin : expands) + { io.digitalWrite(pin, LOW); delay(1); } @@ -1529,16 +1702,20 @@ void TLoRaPagerBoard::shutdown(bool save_data) // 9) LilyGo 3-second countdown int i = 3; - while (i--) { + while (i--) + { log_d("%d second sleep ...", i); delay(1000); } #if defined(USING_XL9555_EXPANDS) // 10) Handle SD card power - if (io.digitalRead(EXPANDS_SD_DET)) { + if (io.digitalRead(EXPANDS_SD_DET)) + { uninstallSD(); - } else { + } + else + { powerControl(POWER_SD_CARD, false); } #endif @@ -1593,8 +1770,10 @@ void TLoRaPagerBoard::shutdown(bool save_data) LORA_IRQ }; - for (auto pin : pins) { - if (pin == POWER_KEY) { + for (auto pin : pins) + { + if (pin == POWER_KEY) + { // Keep boot/power wake pin as input for EXT1 wakeup (LilyGo uses GPIO0) continue; } @@ -1611,7 +1790,7 @@ void TLoRaPagerBoard::shutdown(bool save_data) // 13) Configure wakeup source (LilyGo: BOOT button on GPIO0 only) pinMode(POWER_KEY, INPUT_PULLUP); // ensure stable HIGH when not pressed uint64_t wakeup_pin = (1ULL << POWER_KEY); -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) esp_sleep_enable_ext1_wakeup_io(wakeup_pin, ESP_EXT1_WAKEUP_ANY_LOW); #else esp_sleep_enable_ext1_wakeup(wakeup_pin, ESP_EXT1_WAKEUP_ANY_LOW); @@ -1621,7 +1800,8 @@ void TLoRaPagerBoard::shutdown(bool save_data) esp_deep_sleep_start(); // Code will not reach here - while (true) { + while (true) + { delay(1000); } } @@ -1629,7 +1809,8 @@ void TLoRaPagerBoard::shutdown(bool save_data) void TLoRaPagerBoard::softwareShutdown() { // 检查USB连接状态 - if (isUsbPresent_bestEffort()) { + if (isUsbPresent_bestEffort()) + { log_w("Cannot shutdown: USB is connected (PMIC will maintain power)"); // 显示用户提示 @@ -1646,21 +1827,23 @@ void TLoRaPagerBoard::wakeUp() { // Re-initialize power button interrupt after wake up initPowerButton(); - } -void TLoRaPagerBoard::rotaryTask(void *p) +void TLoRaPagerBoard::rotaryTask(void* p) { (void)p; RotaryMsg_t msg; bool last_btn_state = false; instance.rotary.begin(); pinMode(ROTARY_C, INPUT); - while (true) { + while (true) + { msg.centerBtnPressed = getButtonState(); uint8_t result = instance.rotary.process(); - if (result || msg.centerBtnPressed != last_btn_state) { - switch (result) { + if (result || msg.centerBtnPressed != last_btn_state) + { + switch (result) + { case DIR_CW: msg.dir = ROTARY_DIR_UP; break; @@ -1672,20 +1855,21 @@ void TLoRaPagerBoard::rotaryTask(void *p) break; } last_btn_state = msg.centerBtnPressed; - xQueueSend(rotaryMsg, (void *)&msg, portMAX_DELAY); + xQueueSend(rotaryMsg, (void*)&msg, portMAX_DELAY); } delay(2); } } - // ------------------------------ // USB present detection (best effort) // ------------------------------ -bool TLoRaPagerBoard::isUsbPresent_bestEffort() { +bool TLoRaPagerBoard::isUsbPresent_bestEffort() +{ // Try to detect USB by checking PMU status if available TLoRaPagerBoard* board = TLoRaPagerBoard::getInstance(); - if (board && board->isPMUReady()) { + if (board && board->isPMUReady()) + { // Check if PMU reports VBUS present // Note: XPowersLib may have methods to check this // For now, assume we can check via PMU status @@ -1699,11 +1883,12 @@ bool TLoRaPagerBoard::isUsbPresent_bestEffort() { // Note: active-high vs active-low depends on how EN pins are wired. // Based on typical designs, EN=1 means ON, so we set to 0 to OFF. // ------------------------------ -namespace { -TLoRaPagerBoard &getInstanceRef() +namespace +{ +TLoRaPagerBoard& getInstanceRef() { return *TLoRaPagerBoard::getInstance(); } -} +} // namespace -TLoRaPagerBoard &instance = getInstanceRef(); +TLoRaPagerBoard& instance = getInstanceRef(); diff --git a/src/board/TLoRaPagerBoard.h b/src/board/TLoRaPagerBoard.h index 6a07b62f..af070a07 100644 --- a/src/board/TLoRaPagerBoard.h +++ b/src/board/TLoRaPagerBoard.h @@ -1,37 +1,37 @@ /** * @file TLoRaPagerBoard.h * @brief T-LoRa-Pager board hardware abstraction layer - * + * * This class provides a unified interface to all hardware components on the * LilyGo T-LoRa-Pager board, including display, GPS, LoRa, NFC, sensors, etc. */ #pragma once -#include -#include -#include -#include -#include #include - +#include +#include +#include +#include +#include // Forward declaration to avoid circular includes -namespace app { +namespace app +{ class AppContext; } // Power management and battery #define XPOWERS_CHIP_BQ25896 -#include #include +#include // Sensors and peripherals -#include -#include -#include #include #include +#include +#include +#include // Audio codec #include "audio/codec/esp_codec.h" @@ -53,12 +53,12 @@ class AppContext; #include "input/rotary/Rotary.h" #include "pins_arduino.h" -#define newModule() new Module(LORA_CS, LORA_IRQ, LORA_RST, LORA_BUSY) +#define newModule() new Module(LORA_CS, LORA_IRQ, LORA_RST, LORA_BUSY) /** * @class TLoRaPagerBoard * @brief Main board class for T-LoRa-Pager hardware - * + * * This class manages all hardware components on the T-LoRa-Pager board. * It provides initialization, control, and status query functions for each component. */ @@ -66,12 +66,12 @@ class TLoRaPagerBoard : public LilyGo_Display, public LilyGoDispArduinoSPI, public BrightnessController { -public: + public: /** * @brief Get the singleton instance of TLoRaPagerBoard * @return Pointer to the singleton instance */ - static TLoRaPagerBoard *getInstance(); + static TLoRaPagerBoard* getInstance(); /** * @brief Initialize the board and all hardware components @@ -80,10 +80,10 @@ public: * @return Bitmask indicating which hardware components are online (HW_* flags) */ uint32_t begin(uint32_t disable_hw_init = 0); - + /** * @brief Main loop function - call this periodically in your main loop - * + * * This function processes background tasks such as NFC worker. */ void loop(); @@ -100,7 +100,7 @@ public: bool installSD(); void uninstallSD(); bool isCardReady(); - + /** * @brief Sync RTC time from GPS (if GPS time is valid) * @param gps_task_interval_ms Optional: GPS task interval in milliseconds (for delay compensation) @@ -109,23 +109,26 @@ public: * This function checks if GPS date and time are valid, and if RTC is ready. * If both conditions are met, it sets the RTC time from GPS with delay compensation. * Can be called from GPS task or from UI (e.g., clock settings page). - * + * * Delay compensation accounts for: * - GPS NMEA message age (typically 0.5-2 seconds) * - GPS task interval (if provided, for better accuracy) * - Processing and RTC write delays */ bool syncTimeFromGPS(uint32_t gps_task_interval_ms = 0); - + /** * @brief Update GPS online flag * @param online true to set HW_GPS_ONLINE, false to clear it */ void setGPSOnline(bool online) { - if (online) { + if (online) + { devices_probe |= HW_GPS_ONLINE; - } else { + } + else + { devices_probe &= ~HW_GPS_ONLINE; } } @@ -163,7 +166,6 @@ public: */ void wakeUp(); - // Display void setBrightness(uint8_t level); uint8_t getBrightness(); @@ -171,12 +173,12 @@ public: uint8_t getRotation() override; uint16_t width() override; uint16_t height() override; - void pushColors(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *color) override; + void pushColors(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t* color) override; // Rotary encoder bool hasEncoder() override; RotaryMsg_t getRotary() override; - void feedback(void *args = NULL) override; + void feedback(void* args = NULL) override; // Touch (not available on T-LoRa-Pager) bool hasTouch() override { return false; } @@ -191,13 +193,13 @@ public: * @brief Stop haptic feedback */ void stopVibrator(); - + /** * @brief Set haptic effect waveform * @param effects Effect number (0-127, see DRV2605 documentation) */ void setHapticEffects(uint8_t effects); - + /** * @brief Get current haptic effect * @return Effect number (0-127) @@ -206,8 +208,8 @@ public: // Keyboard bool hasKeyboard() override; - int getKey(char *c); - int getKeyChar(char *c) override; + int getKey(char* c); + int getKeyChar(char* c) override; // NFC functions #ifdef USING_ST25R3916 @@ -218,12 +220,12 @@ public: * @return true if successful, false otherwise */ bool startNFCDiscovery(uint8_t techs2Find = RFAL_NFC_POLL_TECH_A, uint16_t totalDuration = 1000); - + /** * @brief Stop NFC discovery mode */ void stopNFCDiscovery(); - + /** * @brief Check if NFC is ready * @return true if NFC is initialized and online @@ -237,34 +239,34 @@ public: * @return Bitmask with HW_* flags indicating which devices are online */ uint32_t getDevicesProbe() const { return devices_probe; } - + /** * @brief Check if a specific hardware component is online * @param flag Hardware flag (e.g., HW_GPS_ONLINE, HW_LORA_ONLINE) * @return true if the hardware is online, false otherwise */ bool isHardwareOnline(uint32_t flag) const { return (devices_probe & flag) != 0; } - + /** * @brief Check if GPS is initialized and online */ bool isGPSReady() const { return isHardwareOnline(HW_GPS_ONLINE); } - + /** * @brief Check if LoRa is initialized and online */ bool isLoRaReady() const { return isHardwareOnline(HW_RADIO_ONLINE); } - + /** * @brief Check if SD card is ready */ bool isSDReady() const { return isHardwareOnline(HW_SD_ONLINE); } - + /** * @brief Check if RTC is initialized and online */ bool isRTCReady() const { return isHardwareOnline(HW_RTC_ONLINE); } - + /** * @brief Get current time string from RTC * @param buffer Buffer to store the time string @@ -272,7 +274,7 @@ public: * @param show_seconds If true, format as HH:MM:SS, else HH:MM (more efficient) * @return true if time was retrieved successfully, false otherwise */ - bool getRTCTimeString(char *buffer, size_t buffer_size, bool show_seconds = true); + bool getRTCTimeString(char* buffer, size_t buffer_size, bool show_seconds = true); /** * @brief Adjust RTC time by offset minutes (e.g., timezone change) @@ -280,52 +282,52 @@ public: * @return true if RTC updated successfully */ bool adjustRTCByOffsetMinutes(int offset_minutes); - + /** * @brief Check if sensor is initialized and online */ bool isSensorReady() const { return isHardwareOnline(HW_BHI260AP_ONLINE); } - + /** * @brief Check if haptic driver is initialized and online */ bool isHapticReady() const { return isHardwareOnline(HW_DRV_ONLINE); } - + /** * @brief Check if PMU is initialized and online */ bool isPMUReady() const { return isHardwareOnline(HW_PMU_ONLINE); } - + /** * @brief Check if battery gauge is initialized and online */ bool isGaugeReady() const { return isHardwareOnline(HW_GAUGE_ONLINE); } - + /** * @brief Get battery level percentage (0-100) * @return Battery percentage, or -1 if gauge is not ready */ int getBatteryLevel(); - + /** * @brief Check if battery is currently charging * @return true if charging, false if not charging or PMU is not ready */ bool isCharging(); - + /** * @brief Read ADC value with optimal accuracy and minimal resource usage * @param pin GPIO pin number (must be ADC-capable) * @param samples Number of samples to average (default: 8, range: 1-64) * More samples = more accurate but slower. 8 is usually optimal. * @return ADC value (0-4095 for 12-bit), or -1 if pin is invalid - * + * * This function uses multiple sampling and averaging to reduce noise, * while keeping resource usage minimal by using a small sample count. * For best accuracy with minimal overhead, use 8 samples (default). */ int readADC(uint8_t pin, uint8_t samples = 8); - + /** * @brief Read ADC voltage in millivolts * @param pin GPIO pin number (must be ADC-capable) @@ -333,7 +335,7 @@ public: * @param attenuation ADC attenuation (0-3, default: 3 for 11dB = 0-3.3V range) * 0 = 0dB (0-1.1V), 1 = 2.5dB (0-1.5V), 2 = 6dB (0-2.2V), 3 = 11dB (0-3.3V) * @return Voltage in millivolts, or -1 if pin is invalid - * + * * This function reads ADC and converts to voltage. * Default attenuation (3 = 11dB) allows 0-3.3V range. */ @@ -355,10 +357,9 @@ public: #endif #ifdef USING_ST25R3916 - RfalNfcClass *nfc; + RfalNfcClass* nfc; #endif - #ifdef USING_AUDIO_CODEC EspCodec codec; #endif @@ -375,33 +376,33 @@ public: Si4432 radio = newModule(); #endif -private: + private: // Singleton pattern - prevent copy and assignment TLoRaPagerBoard(); ~TLoRaPagerBoard(); - TLoRaPagerBoard(const TLoRaPagerBoard &) = delete; - TLoRaPagerBoard &operator=(const TLoRaPagerBoard &) = delete; + TLoRaPagerBoard(const TLoRaPagerBoard&) = delete; + TLoRaPagerBoard& operator=(const TLoRaPagerBoard&) = delete; /** * @brief Initialize shared SPI bus CS pins */ void initShareSPIPins(); - + /** * @brief Rotary encoder task (FreeRTOS task) * @param p Task parameter (unused) */ - static void rotaryTask(void *p); + static void rotaryTask(void* p); -private: + private: // Two-stage power-off implementation bool isUsbPresent_bestEffort(); - uint32_t devices_probe = 0; ///< Hardware detection status bitmask - uint8_t _haptic_effects = 100; ///< Default haptic effect (very strong buzz for message notification) + uint32_t devices_probe = 0; ///< Hardware detection status bitmask + uint8_t _haptic_effects = 100; ///< Default haptic effect (very strong buzz for message notification) }; -extern TLoRaPagerBoard &instance; +extern TLoRaPagerBoard& instance; #define DEVICE_MAX_BRIGHTNESS_LEVEL 16 #define DEVICE_MIN_BRIGHTNESS_LEVEL 0 diff --git a/src/board/TLoRaPagerTypes.h b/src/board/TLoRaPagerTypes.h index 1704caac..bc6e2f25 100644 --- a/src/board/TLoRaPagerTypes.h +++ b/src/board/TLoRaPagerTypes.h @@ -3,46 +3,47 @@ #include /* Hardware presence mask */ -#define HW_RADIO_ONLINE (_BV(0)) -#define HW_TOUCH_ONLINE (_BV(1)) -#define HW_DRV_ONLINE (_BV(2)) -#define HW_PMU_ONLINE (_BV(3)) -#define HW_RTC_ONLINE (_BV(4)) -#define HW_PSRAM_ONLINE (_BV(5)) -#define HW_GPS_ONLINE (_BV(6)) -#define HW_SD_ONLINE (_BV(7)) -#define HW_NFC_ONLINE (_BV(8)) -#define HW_BHI260AP_ONLINE (_BV(9)) -#define HW_KEYBOARD_ONLINE (_BV(10)) -#define HW_GAUGE_ONLINE (_BV(11)) -#define HW_EXPAND_ONLINE (_BV(12)) -#define HW_CODEC_ONLINE (_BV(13)) +#define HW_RADIO_ONLINE (_BV(0)) +#define HW_TOUCH_ONLINE (_BV(1)) +#define HW_DRV_ONLINE (_BV(2)) +#define HW_PMU_ONLINE (_BV(3)) +#define HW_RTC_ONLINE (_BV(4)) +#define HW_PSRAM_ONLINE (_BV(5)) +#define HW_GPS_ONLINE (_BV(6)) +#define HW_SD_ONLINE (_BV(7)) +#define HW_NFC_ONLINE (_BV(8)) +#define HW_BHI260AP_ONLINE (_BV(9)) +#define HW_KEYBOARD_ONLINE (_BV(10)) +#define HW_GAUGE_ONLINE (_BV(11)) +#define HW_EXPAND_ONLINE (_BV(12)) +#define HW_CODEC_ONLINE (_BV(13)) /* Selectively disable some initialisation */ -#define NO_HW_RTC (_BV(0)) -#define NO_HW_I2C_SCAN (_BV(1)) -#define NO_SCAN_I2C_DEV (_BV(2)) -#define NO_HW_TOUCH (_BV(3)) -#define NO_HW_SENSOR (_BV(4)) -#define NO_HW_NFC (_BV(5)) -#define NO_HW_DRV (_BV(6)) -#define NO_HW_GPS (_BV(7)) -#define NO_HW_SD (_BV(8)) -#define NO_HW_MIC (_BV(9)) -#define NO_INIT_DELAY (_BV(10)) -#define NO_HW_LORA (_BV(11)) -#define NO_HW_KEYBOARD (_BV(12)) -#define NO_INIT_FATFS (_BV(13)) -#define NO_HW_CODEC (_BV(17)) +#define NO_HW_RTC (_BV(0)) +#define NO_HW_I2C_SCAN (_BV(1)) +#define NO_SCAN_I2C_DEV (_BV(2)) +#define NO_HW_TOUCH (_BV(3)) +#define NO_HW_SENSOR (_BV(4)) +#define NO_HW_NFC (_BV(5)) +#define NO_HW_DRV (_BV(6)) +#define NO_HW_GPS (_BV(7)) +#define NO_HW_SD (_BV(8)) +#define NO_HW_MIC (_BV(9)) +#define NO_INIT_DELAY (_BV(10)) +#define NO_HW_LORA (_BV(11)) +#define NO_HW_KEYBOARD (_BV(12)) +#define NO_INIT_FATFS (_BV(13)) +#define NO_HW_CODEC (_BV(17)) /* Hardware interrupt mask */ -#define HW_IRQ_TOUCHPAD (_BV(0)) -#define HW_IRQ_RTC (_BV(1)) -#define HW_IRQ_POWER (_BV(2)) -#define HW_IRQ_SENSOR (_BV(3)) -#define HW_IRQ_EXPAND (_BV(4)) +#define HW_IRQ_TOUCHPAD (_BV(0)) +#define HW_IRQ_RTC (_BV(1)) +#define HW_IRQ_POWER (_BV(2)) +#define HW_IRQ_SENSOR (_BV(3)) +#define HW_IRQ_EXPAND (_BV(4)) -typedef enum PowerCtrlChannel { +typedef enum PowerCtrlChannel +{ // None - for components that don't require power control POWER_NONE, // Display and touch power supply @@ -74,4 +75,3 @@ typedef enum PowerCtrlChannel { } PowerCtrlChannel_t; typedef bool (*lock_callback_t)(void); - diff --git a/src/board/nfc_include.h b/src/board/nfc_include.h index 7d92a513..3f7e787e 100644 --- a/src/board/nfc_include.h +++ b/src/board/nfc_include.h @@ -4,7 +4,7 @@ * @license MIT * @copyright Copyright (c) 2024 ShenZhen XinYuan Electronic Technology Co., Ltd * @date 2024-12-04 - * + * */ #pragma once @@ -28,13 +28,12 @@ #include #include #include +#include #include #include #include #include #include #include -#include #endif - diff --git a/src/chat/domain/chat_model.cpp b/src/chat/domain/chat_model.cpp index bd3e634b..8f9e1464 100644 --- a/src/chat/domain/chat_model.cpp +++ b/src/chat/domain/chat_model.cpp @@ -7,14 +7,17 @@ #include #include -namespace chat { +namespace chat +{ ChatModel::ChatModel() : policy_(ChatPolicy::defaults()), next_msg_id_(1) {} -ChatModel::~ChatModel() { +ChatModel::~ChatModel() +{ } -void ChatModel::onIncoming(const ChatMessage& msg) { +void ChatModel::onIncoming(const ChatMessage& msg) +{ ConversationId conv(msg.channel, msg.peer ? msg.peer : msg.from); ConversationData& data = getConvData(conv); @@ -22,17 +25,20 @@ void ChatModel::onIncoming(const ChatMessage& msg) { data.preview = msg.text; data.last_ts = msg.timestamp; - if (!data.muted) { + if (!data.muted) + { data.unread_count++; } } -void ChatModel::onSendQueued(const ChatMessage& msg) { +void ChatModel::onSendQueued(const ChatMessage& msg) +{ ConversationId conv(msg.channel, msg.peer); ConversationData& data = getConvData(conv); ChatMessage copy = msg; - if (copy.msg_id == 0) { + if (copy.msg_id == 0) + { copy.msg_id = next_msg_id_++; } copy.status = MessageStatus::Queued; @@ -42,14 +48,19 @@ void ChatModel::onSendQueued(const ChatMessage& msg) { data.last_ts = copy.timestamp; } -void ChatModel::onSendResult(MessageId msg_id, bool ok) { +void ChatModel::onSendResult(MessageId msg_id, bool ok) +{ // Find message in all conversations - for (auto& pair : conversations_) { + for (auto& pair : conversations_) + { ConversationData& data = pair.second; - for (size_t i = 0; i < data.messages.count(); i++) { + for (size_t i = 0; i < data.messages.count(); i++) + { const ChatMessage* msg = data.messages.get(i); - if (msg && msg->msg_id == msg_id) { - if (!ok) { + if (msg && msg->msg_id == msg_id) + { + if (!ok) + { ChatMessage failed_msg = *msg; failed_msg.status = MessageStatus::Failed; failed_messages_.append(failed_msg); @@ -60,26 +71,31 @@ void ChatModel::onSendResult(MessageId msg_id, bool ok) { } } -int ChatModel::getUnread(const ConversationId& conv) const { +int ChatModel::getUnread(const ConversationId& conv) const +{ const ConversationData& data = getConvData(conv); return data.unread_count; } -void ChatModel::markRead(const ConversationId& conv) { +void ChatModel::markRead(const ConversationId& conv) +{ ConversationData& data = getConvData(conv); data.unread_count = 0; } -std::vector ChatModel::getRecent(const ConversationId& conv, size_t limit) const { +std::vector ChatModel::getRecent(const ConversationId& conv, size_t limit) const +{ const ConversationData& data = getConvData(conv); std::vector result; size_t count = data.messages.count(); size_t start = (count > limit) ? (count - limit) : 0; - for (size_t i = start; i < count; i++) { + for (size_t i = start; i < count; i++) + { const ChatMessage* msg = data.messages.get(i); - if (msg) { + if (msg) + { result.push_back(*msg); } } @@ -87,26 +103,33 @@ std::vector ChatModel::getRecent(const ConversationId& conv, size_t return result; } -std::vector ChatModel::getFailedMessages() const { +std::vector ChatModel::getFailedMessages() const +{ std::vector result; size_t count = failed_messages_.count(); - - for (size_t i = 0; i < count; i++) { + + for (size_t i = 0; i < count; i++) + { const ChatMessage* msg = failed_messages_.get(i); - if (msg) { + if (msg) + { result.push_back(*msg); } } - + return result; } -const ChatMessage* ChatModel::getMessage(MessageId msg_id) const { - for (const auto& pair : conversations_) { +const ChatMessage* ChatModel::getMessage(MessageId msg_id) const +{ + for (const auto& pair : conversations_) + { const ConversationData& data = pair.second; - for (size_t i = 0; i < data.messages.count(); i++) { + for (size_t i = 0; i < data.messages.count(); i++) + { const ChatMessage* msg = data.messages.get(i); - if (msg && msg->msg_id == msg_id) { + if (msg && msg->msg_id == msg_id) + { return msg; } } @@ -114,12 +137,21 @@ const ChatMessage* ChatModel::getMessage(MessageId msg_id) const { return nullptr; } -std::vector ChatModel::getConversations() const { +void ChatModel::clearAll() +{ + conversations_.clear(); + failed_messages_.clear(); +} + +std::vector ChatModel::getConversations() const +{ std::vector list; list.reserve(conversations_.size()); - for (const auto& pair : conversations_) { - if (pair.second.last_ts == 0) { + for (const auto& pair : conversations_) + { + if (pair.second.last_ts == 0) + { continue; // skip empty conversations } ConversationMeta meta; @@ -128,9 +160,12 @@ std::vector ChatModel::getConversations() const { meta.last_timestamp = pair.second.last_ts; meta.unread = pair.second.unread_count; // Naming: broadcast vs peer short id - if (pair.first.peer == 0) { + if (pair.first.peer == 0) + { meta.name = "Broadcast"; - } else { + } + else + { char buf[16]; snprintf(buf, sizeof(buf), "%04lX", static_cast(pair.first.peer & 0xFFFF)); meta.name = buf; @@ -138,25 +173,28 @@ std::vector ChatModel::getConversations() const { list.push_back(meta); } - std::sort(list.begin(), list.end(), [](const ConversationMeta& a, const ConversationMeta& b) { - return a.last_timestamp > b.last_timestamp; - }); + std::sort(list.begin(), list.end(), [](const ConversationMeta& a, const ConversationMeta& b) + { return a.last_timestamp > b.last_timestamp; }); return list; } -ChatModel::ConversationData& ChatModel::getConvData(const ConversationId& conv) { +ChatModel::ConversationData& ChatModel::getConvData(const ConversationId& conv) +{ auto it = conversations_.find(conv); - if (it == conversations_.end()) { + if (it == conversations_.end()) + { auto result = conversations_.emplace(conv, ConversationData()); return result.first->second; } return it->second; } -const ChatModel::ConversationData& ChatModel::getConvData(const ConversationId& conv) const { +const ChatModel::ConversationData& ChatModel::getConvData(const ConversationId& conv) const +{ auto it = conversations_.find(conv); - if (it == conversations_.end()) { + if (it == conversations_.end()) + { static ConversationData empty; return empty; } diff --git a/src/chat/domain/chat_model.h b/src/chat/domain/chat_model.h index 0ee058af..483277d7 100644 --- a/src/chat/domain/chat_model.h +++ b/src/chat/domain/chat_model.h @@ -5,36 +5,38 @@ #pragma once -#include "chat_types.h" -#include "chat_policy.h" #include "../sys/ringbuf.h" -#include +#include "chat_policy.h" +#include "chat_types.h" #include +#include -namespace chat { +namespace chat +{ /** * @brief Chat domain model * Manages chat state: messages, unread counts, channels */ -class ChatModel { -public: +class ChatModel +{ + public: static constexpr size_t MAX_MESSAGES_PER_CONV = 50; static constexpr size_t MAX_FAILED_MESSAGES = 5; - + ChatModel(); ~ChatModel(); - + void onIncoming(const ChatMessage& msg); void onSendQueued(const ChatMessage& msg); - + /** * @brief Handle send result * @param msg_id Message ID * @param ok true if sent successfully */ void onSendResult(MessageId msg_id, bool ok); - + int getUnread(const ConversationId& conv) const; void markRead(const ConversationId& conv); std::vector getRecent(const ConversationId& conv, size_t limit) const; @@ -43,33 +45,41 @@ public: * @brief Get conversation list metadata (sorted by last_timestamp desc) */ std::vector getConversations() const; - + /** * @brief Get failed messages */ std::vector getFailedMessages() const; - + /** * @brief Get message by ID */ const ChatMessage* getMessage(MessageId msg_id) const; - + + /** + * @brief Clear all conversations and failed messages + */ + void clearAll(); + /** * @brief Set policy */ - void setPolicy(const ChatPolicy& policy) { + void setPolicy(const ChatPolicy& policy) + { policy_ = policy; } - + /** * @brief Get current policy */ - const ChatPolicy& getPolicy() const { + const ChatPolicy& getPolicy() const + { return policy_; } -private: - struct ConversationData { + private: + struct ConversationData + { sys::RingBuffer messages; int unread_count; uint32_t last_ts; @@ -78,12 +88,12 @@ private: ConversationData() : unread_count(0), last_ts(0), muted(false) {} }; - + std::map conversations_; sys::RingBuffer failed_messages_; ChatPolicy policy_; MessageId next_msg_id_; - + ConversationData& getConvData(const ConversationId& conv); const ConversationData& getConvData(const ConversationId& conv) const; }; diff --git a/src/chat/domain/chat_policy.h b/src/chat/domain/chat_policy.h index eb03963c..cdeab101 100644 --- a/src/chat/domain/chat_policy.h +++ b/src/chat/domain/chat_policy.h @@ -7,39 +7,43 @@ #include -namespace chat { +namespace chat +{ /** * @brief Chat policy configuration * Defines behavior for outdoor/outdoor-optimized scenarios */ -struct ChatPolicy { - bool enable_relay; // Enable message relay/forwarding - uint8_t hop_limit_default; // Default hop limit (1-3) - bool ack_for_broadcast; // Require ACK for broadcast messages - bool ack_for_squad; // Require ACK for squad messages - uint8_t max_tx_retries; // Maximum TX retries (outdoor: keep low) - uint8_t max_channels; // Maximum number of channels - +struct ChatPolicy +{ + bool enable_relay; // Enable message relay/forwarding + uint8_t hop_limit_default; // Default hop limit (1-3) + bool ack_for_broadcast; // Require ACK for broadcast messages + bool ack_for_squad; // Require ACK for squad messages + uint8_t max_tx_retries; // Maximum TX retries (outdoor: keep low) + uint8_t max_channels; // Maximum number of channels + /** * @brief Get default outdoor policy * Optimized for low power, low frequency, event-driven communication */ - static ChatPolicy outdoor() { + static ChatPolicy outdoor() + { ChatPolicy policy; - policy.enable_relay = true; // Enable relay for mesh - policy.hop_limit_default = 2; // 2 hops default - policy.ack_for_broadcast = false; // No ACK for broadcast (save airtime) - policy.ack_for_squad = true; // ACK for squad (more reliable) - policy.max_tx_retries = 1; // Minimal retries (outdoor: be quiet) - policy.max_channels = 3; // Max 3 channels + policy.enable_relay = true; // Enable relay for mesh + policy.hop_limit_default = 2; // 2 hops default + policy.ack_for_broadcast = false; // No ACK for broadcast (save airtime) + policy.ack_for_squad = true; // ACK for squad (more reliable) + policy.max_tx_retries = 1; // Minimal retries (outdoor: be quiet) + policy.max_channels = 3; // Max 3 channels return policy; } - + /** * @brief Get default policy (same as outdoor for now) */ - static ChatPolicy defaults() { + static ChatPolicy defaults() + { return outdoor(); } }; diff --git a/src/chat/domain/chat_types.h b/src/chat/domain/chat_types.h index 415c0505..1eccb613 100644 --- a/src/chat/domain/chat_types.h +++ b/src/chat/domain/chat_types.h @@ -6,18 +6,20 @@ #pragma once #include -#include #include +#include -namespace chat { +namespace chat +{ /** * @brief Channel identifier * Primary channel (0) is the default public channel */ -enum class ChannelId : uint8_t { - PRIMARY = 0, // Public channel (default broadcast) - SECONDARY = 1, // Squad channel (encrypted) +enum class ChannelId : uint8_t +{ + PRIMARY = 0, // Public channel (default broadcast) + SECONDARY = 1, // Squad channel (encrypted) MAX_CHANNELS = 3 }; @@ -35,20 +37,24 @@ using MessageId = uint32_t; * @brief Conversation identifier (channel + peer) * peer = 0 means channel-wide/broadcast */ -struct ConversationId { +struct ConversationId +{ ChannelId channel; NodeId peer; // 0 for broadcast/channel thread ConversationId(ChannelId ch = ChannelId::PRIMARY, NodeId p = 0) : channel(ch), peer(p) {} - bool operator<(const ConversationId& other) const { - if (channel != other.channel) { + bool operator<(const ConversationId& other) const + { + if (channel != other.channel) + { return static_cast(channel) < static_cast(other.channel); } return peer < other.peer; } - bool operator==(const ConversationId& other) const { + bool operator==(const ConversationId& other) const + { return channel == other.channel && peer == other.peer; } }; @@ -56,33 +62,36 @@ struct ConversationId { /** * @brief Message status */ -enum class MessageStatus { - Incoming, // Received message - Queued, // Queued for sending - Sent, // Successfully sent - Failed // Failed to send +enum class MessageStatus +{ + Incoming, // Received message + Queued, // Queued for sending + Sent, // Successfully sent + Failed // Failed to send }; /** * @brief Chat message structure */ -struct ChatMessage { +struct ChatMessage +{ ChannelId channel; - NodeId from; // 0 for local messages - NodeId peer; // conversation peer (0 for broadcast) + NodeId from; // 0 for local messages + NodeId peer; // conversation peer (0 for broadcast) MessageId msg_id; - uint32_t timestamp; // Unix timestamp (seconds) + uint32_t timestamp; // Unix timestamp (seconds) std::string text; MessageStatus status; - - ChatMessage() : channel(ChannelId::PRIMARY), from(0), peer(0), msg_id(0), + + ChatMessage() : channel(ChannelId::PRIMARY), from(0), peer(0), msg_id(0), timestamp(0), status(MessageStatus::Incoming) {} }; /** * @brief Conversation metadata for UI */ -struct ConversationMeta { +struct ConversationMeta +{ ConversationId id; std::string name; std::string preview; @@ -95,35 +104,47 @@ struct ConversationMeta { /** * @brief Incoming text message from mesh */ -struct MeshIncomingText { +struct MeshIncomingText +{ ChannelId channel; NodeId from; MessageId msg_id; uint32_t timestamp; std::string text; - uint8_t hop_limit; // Remaining hops - bool encrypted; // Whether message was encrypted + uint8_t hop_limit; // Remaining hops + bool encrypted; // Whether message was encrypted }; /** * @brief Mesh configuration */ -struct MeshConfig { - uint8_t region; // LoRa region (0=US, 1=EU, etc.) - uint8_t modem_preset; // Modem preset index - int8_t tx_power; // TX power in dBm - uint8_t hop_limit; // Maximum hop limit (1-3) - bool enable_relay; // Enable message relay/forwarding - +struct MeshConfig +{ + uint8_t region; // LoRa region (0=US, 1=EU, etc.) + uint8_t modem_preset; // Modem preset index + int8_t tx_power; // TX power in dBm + uint8_t hop_limit; // Maximum hop limit (1-3) + bool enable_relay; // Enable message relay/forwarding + // Channel encryption keys (PSK for encrypted channels) uint8_t primary_key[16]; // Primary channel key (usually empty for public) uint8_t secondary_key[16]; // Secondary channel key (Squad PSK) - - MeshConfig() : region(0), modem_preset(0), tx_power(14), - hop_limit(2), enable_relay(true) { + + MeshConfig() : region(0), modem_preset(0), tx_power(14), + hop_limit(2), enable_relay(true) + { memset(primary_key, 0, 16); memset(secondary_key, 0, 16); } }; +/** + * @brief Mesh protocol selection + */ +enum class MeshProtocol : uint8_t +{ + Meshtastic = 1, + MeshCore = 2 +}; + } // namespace chat diff --git a/src/chat/domain/contact_types.h b/src/chat/domain/contact_types.h index ed63f9af..448f1777 100644 --- a/src/chat/domain/contact_types.h +++ b/src/chat/domain/contact_types.h @@ -8,21 +8,54 @@ #include #include -namespace chat { -namespace contacts { +namespace chat +{ +namespace contacts +{ + +/** + * @brief Node protocol type + */ +enum class NodeProtocolType : uint8_t +{ + Unknown = 0, + Meshtastic = 1, + MeshCore = 2 +}; + +/** + * @brief Base node information + */ +struct NodeInfoBase +{ + uint32_t node_id; + char short_name[10]; + char long_name[32]; + uint32_t last_seen; // Unix timestamp (seconds) + float snr; // Signal-to-Noise Ratio + bool is_contact; // true if user has assigned a nickname + std::string display_name; // nickname if contact, short_name otherwise + NodeProtocolType protocol; +}; + +/** + * @brief Meshtastic-specific node info (reserved for future extensions) + */ +struct MeshtasticNodeInfo : public NodeInfoBase +{ +}; + +/** + * @brief MeshCore-specific node info (reserved for future extensions) + */ +struct MeshCoreNodeInfo : public NodeInfoBase +{ +}; /** * @brief Node information (from mesh network) */ -struct NodeInfo { - uint32_t node_id; - char short_name[10]; - char long_name[32]; - uint32_t last_seen; // Unix timestamp (seconds) - float snr; // Signal-to-Noise Ratio - bool is_contact; // true if user has assigned a nickname - std::string display_name; // nickname if contact, short_name otherwise -}; +using NodeInfo = NodeInfoBase; } // namespace contacts } // namespace chat diff --git a/src/chat/infra/contact_store.cpp b/src/chat/infra/contact_store.cpp index 359cc19f..e85ab7d2 100644 --- a/src/chat/infra/contact_store.cpp +++ b/src/chat/infra/contact_store.cpp @@ -4,70 +4,86 @@ */ #include "contact_store.h" -#include #include +#include -namespace chat { -namespace contacts { +namespace chat +{ +namespace contacts +{ -void ContactStore::begin() { +void ContactStore::begin() +{ // Try to load from SD card first - if (loadFromSD()) { + if (loadFromSD()) + { use_sd_ = true; return; } - + // Fallback to Flash - if (loadFromFlash()) { + if (loadFromFlash()) + { use_sd_ = false; return; } - + // No existing data, start fresh entries_.clear(); use_sd_ = (SD.cardType() != CARD_NONE); } -std::string ContactStore::getNickname(uint32_t node_id) const { - for (const auto& e : entries_) { - if (e.node_id == node_id) { +std::string ContactStore::getNickname(uint32_t node_id) const +{ + for (const auto& e : entries_) + { + if (e.node_id == node_id) + { return std::string(e.nickname); } } return std::string(); } -bool ContactStore::setNickname(uint32_t node_id, const char* nickname) { - if (!nickname || strlen(nickname) == 0) { - return false; // Empty nickname not allowed +bool ContactStore::setNickname(uint32_t node_id, const char* nickname) +{ + if (!nickname || strlen(nickname) == 0) + { + return false; // Empty nickname not allowed } - - if (strlen(nickname) > 12) { - return false; // Too long + + if (strlen(nickname) > 12) + { + return false; // Too long } - + // Check for duplicate nickname (excluding current node_id) - for (const auto& e : entries_) { - if (e.node_id != node_id && strcmp(e.nickname, nickname) == 0) { - return false; // Duplicate name + for (const auto& e : entries_) + { + if (e.node_id != node_id && strcmp(e.nickname, nickname) == 0) + { + return false; // Duplicate name } } - + // Find existing entry - for (auto& e : entries_) { - if (e.node_id == node_id) { + for (auto& e : entries_) + { + if (e.node_id == node_id) + { strncpy(e.nickname, nickname, sizeof(e.nickname) - 1); e.nickname[sizeof(e.nickname) - 1] = '\0'; save(); return true; } } - + // Check capacity - if (entries_.size() >= kMaxContacts) { - return false; // Storage full + if (entries_.size() >= kMaxContacts) + { + return false; // Storage full } - + // Add new entry Entry e{}; e.node_id = node_id; @@ -78,9 +94,12 @@ bool ContactStore::setNickname(uint32_t node_id, const char* nickname) { return true; } -bool ContactStore::removeNickname(uint32_t node_id) { - for (auto it = entries_.begin(); it != entries_.end(); ++it) { - if (it->node_id == node_id) { +bool ContactStore::removeNickname(uint32_t node_id) +{ + for (auto it = entries_.begin(); it != entries_.end(); ++it) + { + if (it->node_id == node_id) + { entries_.erase(it); save(); return true; @@ -89,145 +108,183 @@ bool ContactStore::removeNickname(uint32_t node_id) { return false; } -bool ContactStore::hasNickname(const char* nickname) const { - if (!nickname) { +bool ContactStore::hasNickname(const char* nickname) const +{ + if (!nickname) + { return false; } - for (const auto& e : entries_) { - if (strcmp(e.nickname, nickname) == 0) { + for (const auto& e : entries_) + { + if (strcmp(e.nickname, nickname) == 0) + { return true; } } return false; } -std::vector ContactStore::getAllContactIds() const { +std::vector ContactStore::getAllContactIds() const +{ std::vector ids; ids.reserve(entries_.size()); - for (const auto& e : entries_) { + for (const auto& e : entries_) + { ids.push_back(e.node_id); } return ids; } -bool ContactStore::loadFromSD() { - if (SD.cardType() == CARD_NONE) { +bool ContactStore::loadFromSD() +{ + if (SD.cardType() == CARD_NONE) + { return false; } - + File file = SD.open(kSdPath, FILE_READ); - if (!file) { + if (!file) + { return false; } - + size_t file_size = file.size(); - if (file_size == 0 || file_size % sizeof(Entry) != 0) { + if (file_size == 0 || file_size % sizeof(Entry) != 0) + { file.close(); return false; } - + size_t count = file_size / sizeof(Entry); - if (count > kMaxContacts) { + if (count > kMaxContacts) + { count = kMaxContacts; } - + entries_.resize(count); size_t read_bytes = file.read((uint8_t*)entries_.data(), count * sizeof(Entry)); file.close(); - + return (read_bytes == count * sizeof(Entry)); } -bool ContactStore::saveToSD() { - if (SD.cardType() == CARD_NONE) { +bool ContactStore::saveToSD() +{ + if (SD.cardType() == CARD_NONE) + { return false; } - + // Remove old file if exists - if (SD.exists(kSdPath)) { + if (SD.exists(kSdPath)) + { SD.remove(kSdPath); } - + File file = SD.open(kSdPath, FILE_WRITE); - if (!file) { + if (!file) + { return false; } - - if (!entries_.empty()) { + + if (!entries_.empty()) + { size_t written = file.write((uint8_t*)entries_.data(), entries_.size() * sizeof(Entry)); file.close(); return (written == entries_.size() * sizeof(Entry)); - } else { + } + else + { file.close(); - return true; // Empty file is valid + return true; // Empty file is valid } } -bool ContactStore::loadFromFlash() { +bool ContactStore::loadFromFlash() +{ Preferences prefs; - if (!prefs.begin(kPrefNs, true)) { + if (!prefs.begin(kPrefNs, true)) + { return false; } - + size_t len = prefs.getBytesLength(kPrefKey); - if (len == 0 || len % sizeof(Entry) != 0) { + if (len == 0 || len % sizeof(Entry) != 0) + { prefs.end(); return false; } - + size_t count = len / sizeof(Entry); - if (count > kMaxContacts) { + if (count > kMaxContacts) + { count = kMaxContacts; } - + entries_.resize(count); size_t read_bytes = prefs.getBytes(kPrefKey, entries_.data(), count * sizeof(Entry)); prefs.end(); - + return (read_bytes == count * sizeof(Entry)); } -bool ContactStore::saveToFlash() { +bool ContactStore::saveToFlash() +{ Preferences prefs; - if (!prefs.begin(kPrefNs, false)) { + if (!prefs.begin(kPrefNs, false)) + { return false; } - - if (!entries_.empty()) { + + if (!entries_.empty()) + { bool ok = prefs.putBytes(kPrefKey, entries_.data(), entries_.size() * sizeof(Entry)); prefs.end(); return ok; - } else { + } + else + { prefs.remove(kPrefKey); prefs.end(); - return true; // Empty is valid + return true; // Empty is valid } } -void ContactStore::save() { +void ContactStore::save() +{ // Update storage preference based on SD card availability bool sd_available = (SD.cardType() != CARD_NONE); - - if (sd_available) { - if (saveToSD()) { + + if (sd_available) + { + if (saveToSD()) + { use_sd_ = true; // Also clear Flash backup if SD is working - if (!use_sd_) { + if (!use_sd_) + { Preferences prefs; - if (prefs.begin(kPrefNs, false)) { + if (prefs.begin(kPrefNs, false)) + { prefs.remove(kPrefKey); prefs.end(); } } - } else { + } + else + { // SD failed, try Flash - if (saveToFlash()) { + if (saveToFlash()) + { use_sd_ = false; } } - } else { + } + else + { // No SD, use Flash - if (saveToFlash()) { + if (saveToFlash()) + { use_sd_ = false; } } diff --git a/src/chat/infra/contact_store.h b/src/chat/infra/contact_store.h index 79a2803b..95b65b20 100644 --- a/src/chat/infra/contact_store.h +++ b/src/chat/infra/contact_store.h @@ -14,19 +14,23 @@ #include #include #include -#include #include +#include -namespace chat { -namespace contacts { +namespace chat +{ +namespace contacts +{ -class ContactStore : public IContactStore { -public: +class ContactStore : public IContactStore +{ + public: ContactStore() = default; - struct Entry { + struct Entry + { uint32_t node_id; - char nickname[13]; // 12 bytes + null terminator + char nickname[13]; // 12 bytes + null terminator }; /** @@ -72,11 +76,12 @@ public: /** * @brief Get number of contacts */ - size_t getCount() const override { + size_t getCount() const override + { return entries_.size(); } -private: + private: static constexpr size_t kMaxContacts = 100; static constexpr const char* kSdPath = "/sd/contacts.dat"; static constexpr const char* kPrefNs = "contacts"; diff --git a/src/chat/infra/meshcore/meshcore_adapter.cpp b/src/chat/infra/meshcore/meshcore_adapter.cpp new file mode 100644 index 00000000..4f4a40e8 --- /dev/null +++ b/src/chat/infra/meshcore/meshcore_adapter.cpp @@ -0,0 +1,283 @@ +/** + * @file meshcore_adapter.cpp + * @brief MeshCore protocol adapter implementation + */ + +#include "meshcore_adapter.h" +#include +#include + +namespace chat +{ +namespace meshcore +{ + +namespace +{ +constexpr uint8_t kRouteTypeFlood = 0x01; +constexpr uint8_t kPayloadTypeRawCustom = 0x0F; +constexpr uint8_t kPayloadTypeTxtMsg = 0x02; +constexpr uint8_t kPayloadVer1 = 0x00; + +#ifndef MESHCORE_LOG_ENABLE +#define MESHCORE_LOG_ENABLE 1 +#endif + +#if MESHCORE_LOG_ENABLE +#define MESHCORE_LOG(...) Serial.printf(__VA_ARGS__) +#else +#define MESHCORE_LOG(...) \ + do \ + { \ + } while (0) +#endif + +std::string toHex(const uint8_t* data, size_t len, size_t max_len = 128) +{ + if (!data || len == 0) + { + return {}; + } + size_t capped = (len > max_len) ? max_len : len; + static const char* kHex = "0123456789ABCDEF"; + std::string out; + out.reserve(capped * 2 + 2); + for (size_t i = 0; i < capped; ++i) + { + uint8_t b = data[i]; + out.push_back(kHex[b >> 4]); + out.push_back(kHex[b & 0x0F]); + } + if (capped < len) + { + out.append(".."); + } + return out; +} + +uint8_t buildHeader(uint8_t route_type, uint8_t payload_type, uint8_t payload_ver) +{ + return (route_type & 0x03) | ((payload_type & 0x0F) << 2) | ((payload_ver & 0x03) << 6); +} + +bool parsePacket(const uint8_t* data, size_t len, uint8_t& payload_type, const uint8_t*& payload, size_t& payload_len) +{ + if (!data || len < 2) + { + return false; + } + + uint8_t header = data[0]; + uint8_t route_type = header & 0x03; + payload_type = (header >> 2) & 0x0F; + + size_t index = 1; + if (route_type == 0 || route_type == 3) + { + if (len < index + 4 + 1) + { + return false; + } + index += 4; // transport codes + } + + if (index >= len) + { + return false; + } + + uint8_t path_len = data[index++]; + if (index + path_len > len) + { + return false; + } + index += path_len; + + if (index > len) + { + return false; + } + + payload = &data[index]; + payload_len = len - index; + return true; +} +} // namespace + +MeshCoreAdapter::MeshCoreAdapter(TLoRaPagerBoard& board) + : board_(board), + initialized_(false), + last_raw_packet_len_(0), + has_pending_raw_packet_(false), + next_msg_id_(1) +{ + // TODO: Initialize MeshCore library +} + +bool MeshCoreAdapter::sendText(ChannelId channel, const std::string& text, + MessageId* out_msg_id, NodeId peer) +{ + // TODO: Implement MeshCore message sending + // This is a placeholder implementation + + if (!initialized_) + { + return false; + } + + // Minimal implementation: send RAW_CUSTOM payload with plain text + // This does not provide MeshCore encryption/authentication. + (void)channel; + (void)peer; + + if (text.empty()) + { + return false; + } + + uint8_t buffer[256]; + size_t index = 0; + buffer[index++] = buildHeader(kRouteTypeFlood, kPayloadTypeRawCustom, kPayloadVer1); + buffer[index++] = 0; // path_len = 0 + + size_t max_payload = sizeof(buffer) - index; + size_t payload_len = text.size(); + if (payload_len > max_payload) + { + payload_len = max_payload; + } + memcpy(&buffer[index], text.data(), payload_len); + index += payload_len; + + int state = RADIOLIB_ERR_UNSUPPORTED; +#if defined(ARDUINO_LILYGO_LORA_SX1262) || defined(ARDUINO_LILYGO_LORA_SX1280) + if (board_.isHardwareOnline(HW_RADIO_ONLINE)) + { + state = board_.radio.transmit(buffer, index); + } +#endif + + MESHCORE_LOG("[MESHCORE] TX raw len=%u hex=%s\n", + static_cast(index), + toHex(buffer, index).c_str()); + + if (out_msg_id) + { + *out_msg_id = next_msg_id_++; + } + + return (state == RADIOLIB_ERR_NONE); +} + +bool MeshCoreAdapter::pollIncomingText(MeshIncomingText* out) +{ + // TODO: Implement MeshCore message receiving + // This is a placeholder implementation + + if (!initialized_ || !out) + { + return false; + } + + if (receive_queue_.empty()) + { + return false; + } + + *out = receive_queue_.front(); + receive_queue_.pop(); + return true; +} + +void MeshCoreAdapter::applyConfig(const MeshConfig& config) +{ + config_ = config; + + // TODO: Apply MeshCore-specific configuration + // - Radio frequency and modulation parameters + // - Network keys and authentication + // - Node identity and routing preferences + + // Mark as initialized once configuration is applied + initialized_ = true; +} + +bool MeshCoreAdapter::isReady() const +{ + // TODO: Check MeshCore radio and network status + return initialized_; +} + +bool MeshCoreAdapter::pollIncomingRawPacket(uint8_t* out_data, size_t& out_len, size_t max_len) +{ + // TODO: Implement MeshCore raw packet polling + // This is a placeholder implementation + + if (!initialized_ || !out_data || max_len == 0) + { + return false; + } + + // Placeholder - MeshCore integration needed + if (!has_pending_raw_packet_) + { + return false; + } + + size_t copy_len = (last_raw_packet_len_ < max_len) ? last_raw_packet_len_ : max_len; + memcpy(out_data, last_raw_packet_, copy_len); + out_len = copy_len; + has_pending_raw_packet_ = false; + return true; +} + +void MeshCoreAdapter::handleRawPacket(const uint8_t* data, size_t size) +{ + if (!data || size == 0) + { + return; + } + + if (size <= sizeof(last_raw_packet_)) + { + memcpy(last_raw_packet_, data, size); + last_raw_packet_len_ = size; + has_pending_raw_packet_ = true; + } + + MESHCORE_LOG("[MESHCORE] RX raw len=%u hex=%s\n", + static_cast(size), + toHex(data, size).c_str()); + + uint8_t payload_type = 0; + const uint8_t* payload = nullptr; + size_t payload_len = 0; + if (!parsePacket(data, size, payload_type, payload, payload_len)) + { + return; + } + + // Minimal parsing for RAW_CUSTOM (treat payload as plain text) + if (payload_type == kPayloadTypeRawCustom && payload && payload_len > 0) + { + MeshIncomingText incoming; + incoming.channel = ChannelId::PRIMARY; + incoming.from = 0; + incoming.msg_id = next_msg_id_++; + incoming.timestamp = millis() / 1000; + incoming.text.assign(reinterpret_cast(payload), payload_len); + incoming.hop_limit = 0; + incoming.encrypted = false; + receive_queue_.push(incoming); + } + + // TODO: Implement full MeshCore TXT_MSG parsing and decryption +} + +void MeshCoreAdapter::processSendQueue() +{ + // No queued sending for MeshCore in this placeholder +} + +} // namespace meshcore +} // namespace chat \ No newline at end of file diff --git a/src/chat/infra/meshcore/meshcore_adapter.h b/src/chat/infra/meshcore/meshcore_adapter.h new file mode 100644 index 00000000..2a637e1b --- /dev/null +++ b/src/chat/infra/meshcore/meshcore_adapter.h @@ -0,0 +1,90 @@ +/** + * @file meshcore_adapter.h + * @brief MeshCore protocol adapter (placeholder/stub implementation) + */ + +#pragma once + +#include "../../../board/TLoRaPagerBoard.h" +#include "../../ports/i_mesh_adapter.h" +#include + +namespace chat +{ +namespace meshcore +{ + +/** + * @brief MeshCore protocol adapter + * + * Placeholder implementation for MeshCore protocol support. + * This will be implemented once the MeshCore library integration is complete. + * + * TODO: Implement full MeshCore protocol support + */ +class MeshCoreAdapter : public IMeshAdapter +{ + public: + /** + * @brief Constructor + */ + MeshCoreAdapter(TLoRaPagerBoard& board); + + /** + * @brief Destructor + */ + ~MeshCoreAdapter() override = default; + + // IMeshAdapter interface implementation + bool sendText(ChannelId channel, const std::string& text, + MessageId* out_msg_id, NodeId peer = 0) override; + + bool pollIncomingText(MeshIncomingText* out) override; + + void applyConfig(const MeshConfig& config) override; + + bool isReady() const override; + + /** + * @brief Poll for incoming raw packet data + * @param out_data Output buffer for raw packet data + * @param out_len Output packet length + * @param max_len Maximum buffer size + * @return true if raw packet data is available + */ + bool pollIncomingRawPacket(uint8_t* out_data, size_t& out_len, size_t max_len) override; + + /** + * @brief Handle raw packet data (from radio task) + * @param data Raw packet data + * @param size Packet size + */ + void handleRawPacket(const uint8_t* data, size_t size) override; + + /** + * @brief Process send queue (no-op placeholder) + */ + void processSendQueue() override; + + private: + TLoRaPagerBoard& board_; + + // Configuration + MeshConfig config_; + + // Implementation state + bool initialized_; + + // Receive queue for parsed messages + std::queue receive_queue_; + + // Raw packet storage for debugging/inspection + uint8_t last_raw_packet_[256]; + size_t last_raw_packet_len_; + bool has_pending_raw_packet_; + + MessageId next_msg_id_; +}; + +} // namespace meshcore +} // namespace chat \ No newline at end of file diff --git a/src/chat/infra/meshtastic/compression/unishox2.cpp b/src/chat/infra/meshtastic/compression/unishox2.cpp index 9fc012a7..8d59f342 100644 --- a/src/chat/infra/meshtastic/compression/unishox2.cpp +++ b/src/chat/infra/meshtastic/compression/unishox2.cpp @@ -37,25 +37,33 @@ /// uint8_t is unsigned char typedef unsigned char uint8_t; -const char *USX_FREQ_SEQ_DFLT[] = {"\": \"", "\": ", ""}; -const char *USX_FREQ_SEQ_XML[] = {"", ""}; +const char* USX_FREQ_SEQ_XML[] = {"", "', ':', '\n', 0, '[', ']', '\\', ';', '\'', - '\t', '@', '*', '&', '?', '!', '^', '|', '\r', '~', '`', 0, 0, 0}, - {0, ',', '.', '0', '1', '9', '2', '5', '-', '/', '3', '4', '6', '7', - '8', '(', ')', ' ', '=', '+', '$', '%', '#', 0, 0, 0, 0, 0}}; + {'"', '{', '}', '_', '<', '>', ':', '\n', 0, '[', ']', '\\', ';', '\'', + '\t', '@', '*', '&', '?', '!', '^', '|', '\r', '~', '`', 0, 0, 0}, + {0, ',', '.', '0', '1', '9', '2', '5', '-', '/', '3', '4', '6', '7', + '8', '(', ')', ' ', '=', '+', '$', '%', '#', 0, 0, 0, 0, 0}}; /// Stores position of letter in usx_sets. /// First 3 bits - position in usx_hcodes @@ -130,10 +138,13 @@ void init_coder() if (is_inited) return; memset(usx_code_94, '\0', sizeof(usx_code_94)); - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 28; j++) { + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 28; j++) + { uint8_t c = usx_sets[i][j]; - if (c > 32) { + if (c > 32) + { usx_code_94[c - USX_OFFSET_94] = (i << 5) + j; if (c >= 'a' && c <= 'z') usx_code_94[c - USX_OFFSET_94 - ('a' - 'A')] = (i << 5) + j; @@ -149,12 +160,13 @@ unsigned int usx_mask[] = {0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF}; /// Appends specified number of bits to the output (out) \n /// If maximum limit (olen) is reached, -1 is returned \n /// Otherwise clen bits in code are appended to out starting with MSB -int append_bits(char *out, int olen, int ol, uint8_t code, int clen) +int append_bits(char* out, int olen, int ol, uint8_t code, int clen) { // printf("%d,%x,%d,%d\n", ol, code, clen, state); - while (clen > 0) { + while (clen > 0) + { int oidx; unsigned char a_byte; @@ -179,35 +191,40 @@ int append_bits(char *out, int olen, int ol, uint8_t code, int clen) } /// This is a safe call to append_bits() making sure it does not write past olen -#define SAFE_APPEND_BITS(exp) \ - do { \ - const int newidx = (exp); \ - if (newidx < 0) \ - return newidx; \ +#define SAFE_APPEND_BITS(exp) \ + do \ + { \ + const int newidx = (exp); \ + if (newidx < 0) \ + return newidx; \ } while (0) /// Appends switch code to out depending on the state (USX_DELTA or other) -int append_switch_code(char *out, int olen, int ol, uint8_t state) +int append_switch_code(char* out, int olen, int ol, uint8_t state) { - if (state == USX_DELTA) { + if (state == USX_DELTA) + { SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, UNI_STATE_SPL_CODE, UNI_STATE_SPL_CODE_LEN)); SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, UNI_STATE_SW_CODE, UNI_STATE_SW_CODE_LEN)); - } else + } + else SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, SW_CODE, SW_CODE_LEN)); return ol; } /// Appends given horizontal and veritical code bits to out -int append_code(char *out, int olen, int ol, uint8_t code, uint8_t *state, const uint8_t usx_hcodes[], +int append_code(char* out, int olen, int ol, uint8_t code, uint8_t* state, const uint8_t usx_hcodes[], const uint8_t usx_hcode_lens[]) { uint8_t hcode = code >> 5; uint8_t vcode = code & 0x1F; if (!usx_hcode_lens[hcode] && hcode != USX_ALPHA) return ol; - switch (hcode) { + switch (hcode) + { case USX_ALPHA: - if (*state != USX_ALPHA) { + if (*state != USX_ALPHA) + { SAFE_APPEND_BITS(ol = append_switch_code(out, olen, ol, *state)); SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, usx_hcodes[USX_ALPHA], usx_hcode_lens[USX_ALPHA])); *state = USX_ALPHA; @@ -218,7 +235,8 @@ int append_code(char *out, int olen, int ol, uint8_t code, uint8_t *state, const SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, usx_hcodes[USX_SYM], usx_hcode_lens[USX_SYM])); break; case USX_NUM: - if (*state != USX_NUM) { + if (*state != USX_NUM) + { SAFE_APPEND_BITS(ol = append_switch_code(out, olen, ol, *state)); SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, usx_hcodes[USX_NUM], usx_hcode_lens[USX_NUM])); if (usx_sets[hcode][vcode] >= '0' && usx_sets[hcode][vcode] <= '9') @@ -236,17 +254,21 @@ const int32_t count_adder[5] = {4, 20, 148, 2196, 67732}; /// Codes used to specify the level that the count belongs to const uint8_t count_codes[] = {0x01, 0x82, 0xC3, 0xE4, 0xF4}; /// Encodes given count to out -int encodeCount(char *out, int olen, int ol, int count) +int encodeCount(char* out, int olen, int ol, int count) { // First five bits are code and Last three bits of codes represent length - for (int i = 0; i < 5; i++) { - if (count < count_adder[i]) { + for (int i = 0; i < 5; i++) + { + if (count < count_adder[i]) + { SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, (count_codes[i] & 0xF8), count_codes[i] & 0x07)); uint16_t count16 = (count - (i ? count_adder[i - 1] : 0)) << (16 - count_bit_lens[i]); - if (count_bit_lens[i] > 8) { + if (count_bit_lens[i] > 8) + { SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, count16 >> 8, 8)); SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, count16 & 0xFF, count_bit_lens[i] - 8)); - } else + } + else SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, count16 >> 8, count_bit_lens[i])); return ol; } @@ -260,7 +282,7 @@ const uint8_t uni_bit_len[5] = {6, 12, 14, 16, 21}; const int32_t uni_adder[5] = {0, 64, 4160, 20544, 86080}; /// Encodes the unicode code point given by code to out. prev_code is used to calculate the delta -int encodeUnicode(char *out, int olen, int ol, int32_t code, int32_t prev_code) +int encodeUnicode(char* out, int olen, int ol, int32_t code, int32_t prev_code) { // First five bits are code and Last three bits of codes represent length // const uint8_t codes[8] = {0x00, 0x42, 0x83, 0xA3, 0xC3, 0xE4, 0xF5, 0xFD}; @@ -271,24 +293,31 @@ int encodeUnicode(char *out, int olen, int ol, int32_t code, int32_t prev_code) diff = -diff; // printf("%ld, ", code); // printf("Diff: %d\n", diff); - for (int i = 0; i < 5; i++) { + for (int i = 0; i < 5; i++) + { till += (1 << uni_bit_len[i]); - if (diff < till) { + if (diff < till) + { SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, (codes[i] & 0xF8), codes[i] & 0x07)); // if (diff) { SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, prev_code > code ? 0x80 : 0, 1)); int32_t val = diff - uni_adder[i]; // printf("Val: %d\n", val); - if (uni_bit_len[i] > 16) { + if (uni_bit_len[i] > 16) + { val <<= (24 - uni_bit_len[i]); SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, val >> 16, 8)); SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, (val >> 8) & 0xFF, 8)); SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, val & 0xFF, uni_bit_len[i] - 16)); - } else if (uni_bit_len[i] > 8) { + } + else if (uni_bit_len[i] > 8) + { val <<= (16 - uni_bit_len[i]); SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, val >> 8, 8)); SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, val & 0xFF, uni_bit_len[i] - 8)); - } else { + } + else + { val <<= (8 - uni_bit_len[i]); SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, val & 0xFF, uni_bit_len[i])); } @@ -299,17 +328,20 @@ int encodeUnicode(char *out, int olen, int ol, int32_t code, int32_t prev_code) } /// Reads UTF-8 character from in. Also returns the number of bytes occupied by the UTF-8 character in utf8len -int32_t readUTF8(const char *in, int len, int l, int *utf8len) +int32_t readUTF8(const char* in, int len, int l, int* utf8len) { int32_t ret = 0; - if (l < (len - 1) && (in[l] & 0xE0) == 0xC0 && (in[l + 1] & 0xC0) == 0x80) { + if (l < (len - 1) && (in[l] & 0xE0) == 0xC0 && (in[l + 1] & 0xC0) == 0x80) + { *utf8len = 2; ret = (in[l] & 0x1F); ret <<= 6; ret += (in[l + 1] & 0x3F); if (ret < 0x80) ret = 0; - } else if (l < (len - 2) && (in[l] & 0xF0) == 0xE0 && (in[l + 1] & 0xC0) == 0x80 && (in[l + 2] & 0xC0) == 0x80) { + } + else if (l < (len - 2) && (in[l] & 0xF0) == 0xE0 && (in[l + 1] & 0xC0) == 0x80 && (in[l + 2] & 0xC0) == 0x80) + { *utf8len = 3; ret = (in[l] & 0x0F); ret <<= 6; @@ -318,8 +350,10 @@ int32_t readUTF8(const char *in, int len, int l, int *utf8len) ret += (in[l + 2] & 0x3F); if (ret < 0x0800) ret = 0; - } else if (l < (len - 3) && (in[l] & 0xF8) == 0xF0 && (in[l + 1] & 0xC0) == 0x80 && (in[l + 2] & 0xC0) == 0x80 && - (in[l + 3] & 0xC0) == 0x80) { + } + else if (l < (len - 3) && (in[l] & 0xF8) == 0xF0 && (in[l + 1] & 0xC0) == 0x80 && (in[l + 2] & 0xC0) == 0x80 && + (in[l + 3] & 0xC0) == 0x80) + { *utf8len = 4; ret = (in[l] & 0x07); ret <<= 6; @@ -339,14 +373,16 @@ int32_t readUTF8(const char *in, int len, int l, int *utf8len) /// This is also used for Unicode strings \n /// This is a crude implementation that is not optimized. Assuming only short strings \n /// are encoded, this is not much of an issue. -int matchOccurance(const char *in, int len, int l, char *out, int olen, int *ol, const uint8_t *state, const uint8_t usx_hcodes[], +int matchOccurance(const char* in, int len, int l, char* out, int olen, int* ol, const uint8_t* state, const uint8_t usx_hcodes[], const uint8_t usx_hcode_lens[]) { int j, k; int longest_dist = 0; int longest_len = 0; - for (j = l - NICE_LEN; j >= 0; j--) { - for (k = l; k < len && j + k - l < l; k++) { + for (j = l - NICE_LEN; j >= 0; j--) + { + for (k = l; k < len && j + k - l < l; k++) + { if (in[k] != in[j + k - l]) break; } @@ -354,16 +390,19 @@ int matchOccurance(const char *in, int len, int l, char *out, int olen, int *ol, k--; // Skip partial UTF-8 matches // if ((in[k - 1] >> 3) == 0x1E || (in[k - 1] >> 4) == 0x0E || (in[k - 1] >> 5) == 0x06) // k--; - if ((k - l) > (NICE_LEN - 1)) { + if ((k - l) > (NICE_LEN - 1)) + { int match_len = k - l - NICE_LEN; int match_dist = l - j - NICE_LEN + 1; - if (match_len > longest_len) { + if (match_len > longest_len) + { longest_len = match_len; longest_dist = match_dist; } } } - if (longest_len) { + if (longest_len) + { SAFE_APPEND_BITS(*ol = append_switch_code(out, olen, *ol, *state)); SAFE_APPEND_BITS(*ol = append_bits(out, olen, *ol, usx_hcodes[USX_DICT], usx_hcode_lens[USX_DICT])); // printf("Len:%d / Dist:%d/%.*s\n", longest_len, longest_dist, longest_len + NICE_LEN, in + l - longest_dist - NICE_LEN + @@ -383,7 +422,7 @@ int matchOccurance(const char *in, int len, int l, char *out, int olen, int *ol, /// This is also used for Unicode strings \n /// This is a crude implementation that is not optimized. Assuming only short strings \n /// are encoded, this is not much of an issue. -int matchLine(const char *in, int len, int l, char *out, int olen, int *ol, struct us_lnk_lst *prev_lines, const uint8_t *state, +int matchLine(const char* in, int len, int l, char* out, int olen, int* ol, struct us_lnk_lst* prev_lines, const uint8_t* state, const uint8_t usx_hcodes[], const uint8_t usx_hcode_lens[]) { int last_ol = *ol; @@ -392,19 +431,24 @@ int matchLine(const char *in, int len, int l, char *out, int olen, int *ol, stru int last_ctx = 0; int line_ctr = 0; int j = 0; - do { + do + { int i, k; int line_len = (int)strlen(prev_lines->data); int limit = (line_ctr == 0 ? l : line_len); - for (; j < limit; j++) { - for (i = l, k = j; k < line_len && i < len; k++, i++) { + for (; j < limit; j++) + { + for (i = l, k = j; k < line_len && i < len; k++, i++) + { if (prev_lines->data[k] != in[i]) break; } while ((((unsigned char)prev_lines->data[k]) >> 6) == 2) k--; // Skip partial UTF-8 matches - if ((k - j) >= NICE_LEN) { - if (last_len) { + if ((k - j) >= NICE_LEN) + { + if (last_len) + { if (j > last_dist) continue; // int saving = ((k - j) - last_len) + (last_dist - j) + (last_ctx - line_ctr); @@ -434,7 +478,8 @@ int matchLine(const char *in, int len, int l, char *out, int olen, int *ol, stru line_ctr++; prev_lines = prev_lines->previous; } while (prev_lines && prev_lines->data != NULL); - if (last_len) { + if (last_len) + { l += last_len; l--; return l; @@ -458,7 +503,13 @@ uint8_t getBaseCode(char ch) /// Enum indicating nibble type - USX_NIB_NUM means ch is a number '0' to '9', \n /// USX_NIB_HEX_LOWER means ch is between 'a' to 'f', \n /// USX_NIB_HEX_UPPER means ch is between 'A' to 'F' -enum { USX_NIB_NUM = 0, USX_NIB_HEX_LOWER, USX_NIB_HEX_UPPER, USX_NIB_NOT }; +enum +{ + USX_NIB_NUM = 0, + USX_NIB_HEX_LOWER, + USX_NIB_HEX_UPPER, + USX_NIB_NOT +}; /// Gets 4 bit code assuming ch falls between '0' to '9', \n /// 'A' to 'F' or 'a' to 'f' char getNibbleType(char ch) @@ -473,7 +524,7 @@ char getNibbleType(char ch) } /// Starts coding of nibble sets -int append_nibble_escape(char *out, int olen, int ol, uint8_t state, const uint8_t usx_hcodes[], const uint8_t usx_hcode_lens[]) +int append_nibble_escape(char* out, int olen, int ol, uint8_t state, const uint8_t usx_hcodes[], const uint8_t usx_hcode_lens[]) { SAFE_APPEND_BITS(ol = append_switch_code(out, olen, ol, state)); SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, usx_hcodes[USX_NUM], usx_hcode_lens[USX_NUM])); @@ -488,18 +539,22 @@ long min_of(long c, long i) } /// Appends the terminator code depending on the state, preset and whether full terminator needs to be encoded to out or not \n -int append_final_bits(char *const out, const int olen, int ol, const uint8_t state, const uint8_t is_all_upper, +int append_final_bits(char* const out, const int olen, int ol, const uint8_t state, const uint8_t is_all_upper, const uint8_t usx_hcodes[], const uint8_t usx_hcode_lens[]) { - if (usx_hcode_lens[USX_ALPHA]) { - if (USX_NUM != state) { + if (usx_hcode_lens[USX_ALPHA]) + { + if (USX_NUM != state) + { // for num state, append TERM_CODE directly // for other state, switch to Num Set first SAFE_APPEND_BITS(ol = append_switch_code(out, olen, ol, state)); SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, usx_hcodes[USX_NUM], usx_hcode_lens[USX_NUM])); } SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, usx_vcodes[TERM_CODE & 0x1F], usx_vcode_lens[TERM_CODE & 0x1F])); - } else { + } + else + { // preset 1, terminate at 2 or 3 SW_CODE, i.e., 4 or 6 continuous 0 bits // see discussion: https://github.com/siara-cc/Unishox/issues/19#issuecomment-922435580 SAFE_APPEND_BITS(ol = append_bits(out, olen, ol, TERM_BYTE_PRESET_1, @@ -514,18 +569,19 @@ int append_final_bits(char *const out, const int olen, int ol, const uint8_t sta } /// Macro used in the main compress function so that if the output len exceeds given maximum length (olen) it can exit -#define SAFE_APPEND_BITS2(olen, exp) \ - do { \ - const int newidx = (exp); \ - const int __olen = (olen); \ - if (newidx < 0) \ - return __olen >= 0 ? __olen + 1 : (1 - __olen) * 4; \ +#define SAFE_APPEND_BITS2(olen, exp) \ + do \ + { \ + const int newidx = (exp); \ + const int __olen = (olen); \ + if (newidx < 0) \ + return __olen >= 0 ? __olen + 1 : (1 - __olen) * 4; \ } while (0) // Main API function. See unishox2.h for documentation -int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen), const uint8_t usx_hcodes[], - const uint8_t usx_hcode_lens[], const char *usx_freq_seq[], const char *usx_templates[], - struct us_lnk_lst *prev_lines) +int unishox2_compress_lines(const char* in, int len, UNISHOX_API_OUT_AND_LEN(char* out, int olen), const uint8_t usx_hcodes[], + const uint8_t usx_hcode_lens[], const char* usx_freq_seq[], const char* usx_templates[], + struct us_lnk_lst* prev_lines) { uint8_t state; @@ -541,7 +597,8 @@ int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(cha #else const int rawolen = olen; uint8_t need_full_term_codes = 0; - if (olen < 0) { + if (olen < 0) + { need_full_term_codes = 1; olen *= -1; } @@ -553,22 +610,33 @@ int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(cha state = USX_ALPHA; is_all_upper = 0; SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, UNISHOX_MAGIC_BITS, UNISHOX_MAGIC_BIT_LEN)); // magic bit(s) - for (l = 0; l < len; l++) { + for (l = 0; l < len; l++) + { - if (usx_hcode_lens[USX_DICT] && l < (len - NICE_LEN + 1)) { - if (prev_lines) { + if (usx_hcode_lens[USX_DICT] && l < (len - NICE_LEN + 1)) + { + if (prev_lines) + { l = matchLine(in, len, l, out, olen, &ol, prev_lines, &state, usx_hcodes, usx_hcode_lens); - if (l > 0) { + if (l > 0) + { continue; - } else if (l < 0 && ol < 0) { + } + else if (l < 0 && ol < 0) + { return olen + 1; } l = -l; - } else { + } + else + { l = matchOccurance(in, len, l, out, olen, &ol, &state, usx_hcodes, usx_hcode_lens); - if (l > 0) { + if (l > 0) + { continue; - } else if (l < 0 && ol < 0) { + } + else if (l < 0 && ol < 0) + { return olen + 1; } l = -l; @@ -576,8 +644,10 @@ int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(cha } c_in = in[l]; - if (l && len > 4 && l < (len - 4) && usx_hcode_lens[USX_NUM]) { - if (c_in == in[l - 1] && c_in == in[l + 1] && c_in == in[l + 2] && c_in == in[l + 3]) { + if (l && len > 4 && l < (len - 4) && usx_hcode_lens[USX_NUM]) + { + if (c_in == in[l - 1] && c_in == in[l + 1] && c_in == in[l + 2] && c_in == in[l + 3]) + { int rpt_count = l + 4; while (rpt_count < len && in[rpt_count] == c_in) rpt_count++; @@ -590,28 +660,34 @@ int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(cha } } - if (l <= (len - 36) && usx_hcode_lens[USX_NUM]) { - if (in[l + 8] == '-' && in[l + 13] == '-' && in[l + 18] == '-' && in[l + 23] == '-') { + if (l <= (len - 36) && usx_hcode_lens[USX_NUM]) + { + if (in[l + 8] == '-' && in[l + 13] == '-' && in[l + 18] == '-' && in[l + 23] == '-') + { char hex_type = USX_NIB_NUM; int uid_pos = l; - for (; uid_pos < l + 36; uid_pos++) { + for (; uid_pos < l + 36; uid_pos++) + { char c_uid = in[uid_pos]; if (c_uid == '-' && (uid_pos == 8 || uid_pos == 13 || uid_pos == 18 || uid_pos == 23)) continue; char nib_type = getNibbleType(c_uid); if (nib_type == USX_NIB_NOT) break; - if (nib_type != USX_NIB_NUM) { + if (nib_type != USX_NIB_NUM) + { if (hex_type != USX_NIB_NUM && hex_type != nib_type) break; hex_type = nib_type; } } - if (uid_pos == l + 36) { + if (uid_pos == l + 36) + { SAFE_APPEND_BITS2(rawolen, ol = append_nibble_escape(out, olen, ol, state, usx_hcodes, usx_hcode_lens)); SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, (hex_type == USX_NIB_HEX_LOWER ? 0xC0 : 0xF0), (hex_type == USX_NIB_HEX_LOWER ? 3 : 5))); - for (uid_pos = l; uid_pos < l + 36; uid_pos++) { + for (uid_pos = l; uid_pos < l + 36; uid_pos++) + { char c_uid = in[uid_pos]; if (c_uid != '-') SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, getBaseCode(c_uid), 4)); @@ -623,14 +699,17 @@ int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(cha } } - if (l < (len - 5) && usx_hcode_lens[USX_NUM]) { + if (l < (len - 5) && usx_hcode_lens[USX_NUM]) + { char hex_type = USX_NIB_NUM; int hex_len = 0; - do { + do + { char nib_type = getNibbleType(in[l + hex_len]); if (nib_type == USX_NIB_NOT) break; - if (nib_type != USX_NIB_NUM) { + if (nib_type != USX_NIB_NUM) + { if (hex_type != USX_NIB_NUM && hex_type != nib_type) break; hex_type = nib_type; @@ -639,12 +718,14 @@ int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(cha } while (l + hex_len < len); if (hex_len > 10 && hex_type == USX_NIB_NUM) hex_type = USX_NIB_HEX_LOWER; - if ((hex_type == USX_NIB_HEX_LOWER || hex_type == USX_NIB_HEX_UPPER) && hex_len > 3) { + if ((hex_type == USX_NIB_HEX_LOWER || hex_type == USX_NIB_HEX_UPPER) && hex_len > 3) + { SAFE_APPEND_BITS2(rawolen, ol = append_nibble_escape(out, olen, ol, state, usx_hcodes, usx_hcode_lens)); SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, (hex_type == USX_NIB_HEX_LOWER ? 0x80 : 0xE0), (hex_type == USX_NIB_HEX_LOWER ? 2 : 4))); SAFE_APPEND_BITS2(rawolen, ol = encodeCount(out, olen, ol, hex_len)); - do { + do + { SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, getBaseCode(in[l++]), 4)); } while (--hex_len); l--; @@ -652,27 +733,37 @@ int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(cha } } - if (usx_templates != NULL) { + if (usx_templates != NULL) + { int i; - for (i = 0; i < 5; i++) { - if (usx_templates[i]) { + for (i = 0; i < 5; i++) + { + if (usx_templates[i]) + { int rem = (int)strlen(usx_templates[i]); int j = 0; - for (; j < rem && l + j < len; j++) { + for (; j < rem && l + j < len; j++) + { char c_t = usx_templates[i][j]; c_in = in[l + j]; - if (c_t == 'f' || c_t == 'F') { + if (c_t == 'f' || c_t == 'F') + { if (getNibbleType(c_in) != (c_t == 'f' ? USX_NIB_HEX_LOWER : USX_NIB_HEX_UPPER) && - getNibbleType(c_in) != USX_NIB_NUM) { + getNibbleType(c_in) != USX_NIB_NUM) + { break; } - } else if (c_t == 'r' || c_t == 't' || c_t == 'o') { + } + else if (c_t == 'r' || c_t == 't' || c_t == 'o') + { if (c_in < '0' || c_in > (c_t == 'r' ? '7' : (c_t == 't' ? '3' : '1'))) break; - } else if (c_t != c_in) + } + else if (c_t != c_in) break; } - if (((float)j / rem) > 0.66) { + if (((float)j / rem) > 0.66) + { // printf("%s\n", usx_templates[i]); rem = rem - j; SAFE_APPEND_BITS2(rawolen, ol = append_nibble_escape(out, olen, ol, state, usx_hcodes, usx_hcode_lens)); @@ -680,11 +771,13 @@ int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(cha SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, (count_codes[i] & 0xF8), count_codes[i] & 0x07)); SAFE_APPEND_BITS2(rawolen, ol = encodeCount(out, olen, ol, rem)); - for (int k = 0; k < j; k++) { + for (int k = 0; k < j; k++) + { char c_t = usx_templates[i][k]; if (c_t == 'f' || c_t == 'F') SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, getBaseCode(in[l + k]), 4)); - else if (c_t == 'r' || c_t == 't' || c_t == 'o') { + else if (c_t == 'r' || c_t == 't' || c_t == 'o') + { c_t = (c_t == 'r' ? 3 : (c_t == 't' ? 2 : 1)); SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, (in[l + k] - '0') << (8 - c_t), c_t)); } @@ -699,12 +792,16 @@ int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(cha continue; } - if (usx_freq_seq != NULL) { + if (usx_freq_seq != NULL) + { int i; - for (i = 0; i < 6; i++) { + for (i = 0; i < 6; i++) + { int seq_len = (int)strlen(usx_freq_seq[i]); - if (len - seq_len >= 0 && l <= len - seq_len) { - if (memcmp(usx_freq_seq[i], in + l, seq_len) == 0 && usx_hcode_lens[usx_freq_codes[i] >> 5]) { + if (len - seq_len >= 0 && l <= len - seq_len) + { + if (memcmp(usx_freq_seq[i], in + l, seq_len) == 0 && usx_hcode_lens[usx_freq_codes[i] >> 5]) + { SAFE_APPEND_BITS2(rawolen, ol = append_code(out, olen, ol, usx_freq_codes[i], &state, usx_hcodes, usx_hcode_lens)); l += seq_len; @@ -722,23 +819,28 @@ int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(cha is_upper = 0; if (c_in >= 'A' && c_in <= 'Z') is_upper = 1; - else { - if (is_all_upper) { + else + { + if (is_all_upper) + { is_all_upper = 0; SAFE_APPEND_BITS2(rawolen, ol = append_switch_code(out, olen, ol, state)); SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, usx_hcodes[USX_ALPHA], usx_hcode_lens[USX_ALPHA])); state = USX_ALPHA; } } - if (is_upper && !is_all_upper) { - if (state == USX_NUM) { + if (is_upper && !is_all_upper) + { + if (state == USX_NUM) + { SAFE_APPEND_BITS2(rawolen, ol = append_switch_code(out, olen, ol, state)); SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, usx_hcodes[USX_ALPHA], usx_hcode_lens[USX_ALPHA])); state = USX_ALPHA; } SAFE_APPEND_BITS2(rawolen, ol = append_switch_code(out, olen, ol, state)); SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, usx_hcodes[USX_ALPHA], usx_hcode_lens[USX_ALPHA])); - if (state == USX_DELTA) { + if (state == USX_DELTA) + { state = USX_ALPHA; SAFE_APPEND_BITS2(rawolen, ol = append_switch_code(out, olen, ol, state)); SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, usx_hcodes[USX_ALPHA], usx_hcode_lens[USX_ALPHA])); @@ -748,22 +850,28 @@ int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(cha if (l + 1 < len) c_next = in[l + 1]; - if (c_in >= 32 && c_in <= 126) { - if (is_upper && !is_all_upper) { - for (ll = l + 4; ll >= l && ll < len; ll--) { + if (c_in >= 32 && c_in <= 126) + { + if (is_upper && !is_all_upper) + { + for (ll = l + 4; ll >= l && ll < len; ll--) + { if (in[ll] < 'A' || in[ll] > 'Z') break; } - if (ll == l - 1) { + if (ll == l - 1) + { SAFE_APPEND_BITS2(rawolen, ol = append_switch_code(out, olen, ol, state)); SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, usx_hcodes[USX_ALPHA], usx_hcode_lens[USX_ALPHA])); state = USX_ALPHA; is_all_upper = 1; } } - if (state == USX_DELTA && (c_in == ' ' || c_in == '.' || c_in == ',')) { + if (state == USX_DELTA && (c_in == ' ' || c_in == '.' || c_in == ',')) + { uint8_t spl_code = (c_in == ',' ? 0xC0 : (c_in == '.' ? 0xE0 : (c_in == ' ' ? 0 : 0xFF))); - if (spl_code != 0xFF) { + if (spl_code != 0xFF) + { uint8_t spl_code_len = (c_in == ',' ? 3 : (c_in == '.' ? 4 : (c_in == ' ' ? 1 : 4))); SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, UNI_STATE_SPL_CODE, UNI_STATE_SPL_CODE_LEN)); SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, spl_code, spl_code_len)); @@ -773,39 +881,58 @@ int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(cha c_in -= 32; if (is_all_upper && is_upper) c_in += 32; - if (c_in == 0) { + if (c_in == 0) + { if (state == USX_NUM) SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, usx_vcodes[NUM_SPC_CODE & 0x1F], usx_vcode_lens[NUM_SPC_CODE & 0x1F])); else SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, usx_vcodes[1], usx_vcode_lens[1])); - } else { + } + else + { c_in--; SAFE_APPEND_BITS2(rawolen, ol = append_code(out, olen, ol, usx_code_94[(int)c_in], &state, usx_hcodes, usx_hcode_lens)); } - } else if (c_in == 13 && c_next == 10) { + } + else if (c_in == 13 && c_next == 10) + { SAFE_APPEND_BITS2(rawolen, ol = append_code(out, olen, ol, CRLF_CODE, &state, usx_hcodes, usx_hcode_lens)); l++; - } else if (c_in == 10) { - if (state == USX_DELTA) { + } + else if (c_in == 10) + { + if (state == USX_DELTA) + { SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, UNI_STATE_SPL_CODE, UNI_STATE_SPL_CODE_LEN)); SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, 0xF0, 4)); - } else + } + else SAFE_APPEND_BITS2(rawolen, ol = append_code(out, olen, ol, LF_CODE, &state, usx_hcodes, usx_hcode_lens)); - } else if (c_in == 13) { + } + else if (c_in == 13) + { SAFE_APPEND_BITS2(rawolen, ol = append_code(out, olen, ol, CR_CODE, &state, usx_hcodes, usx_hcode_lens)); - } else if (c_in == '\t') { + } + else if (c_in == '\t') + { SAFE_APPEND_BITS2(rawolen, ol = append_code(out, olen, ol, TAB_CODE, &state, usx_hcodes, usx_hcode_lens)); - } else { + } + else + { int utf8len; int32_t uni = readUTF8(in, len, l, &utf8len); - if (uni) { + if (uni) + { l += utf8len; - if (state != USX_DELTA) { + if (state != USX_DELTA) + { int32_t uni2 = readUTF8(in, len, l, &utf8len); - if (uni2) { - if (state != USX_ALPHA) { + if (uni2) + { + if (state != USX_ALPHA) + { SAFE_APPEND_BITS2(rawolen, ol = append_switch_code(out, olen, ol, state)); SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, usx_hcodes[USX_ALPHA], usx_hcode_lens[USX_ALPHA])); @@ -816,7 +943,9 @@ int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(cha SAFE_APPEND_BITS2( rawolen, ol = append_bits(out, olen, ol, usx_vcodes[1], usx_vcode_lens[1])); // code for space (' ') state = USX_DELTA; - } else { + } + else + { SAFE_APPEND_BITS2(rawolen, ol = append_switch_code(out, olen, ol, state)); SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, usx_hcodes[USX_DELTA], usx_hcode_lens[USX_DELTA])); @@ -826,9 +955,12 @@ int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(cha // printf("%d:%d:%d\n", l, utf8len, uni); prev_uni = uni; l--; - } else { + } + else + { int bin_count = 1; - for (int bi = l + 1; bi < len; bi++) { + for (int bi = l + 1; bi < len; bi++) + { char c_bi = in[bi]; // if (c_bi > 0x1F && c_bi != 0x7F) // break; @@ -842,7 +974,8 @@ int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(cha SAFE_APPEND_BITS2(rawolen, ol = append_nibble_escape(out, olen, ol, state, usx_hcodes, usx_hcode_lens)); SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, 0xF8, 5)); SAFE_APPEND_BITS2(rawolen, ol = encodeCount(out, olen, ol, bin_count)); - do { + do + { SAFE_APPEND_BITS2(rawolen, ol = append_bits(out, olen, ol, in[l++], 8)); } while (--bin_count); l--; @@ -850,11 +983,14 @@ int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(cha } } - if (need_full_term_codes) { + if (need_full_term_codes) + { const int orig_ol = ol; SAFE_APPEND_BITS2(rawolen, ol = append_final_bits(out, olen, ol, state, is_all_upper, usx_hcodes, usx_hcode_lens)); return (ol / 8) * 4 + (((ol - orig_ol) / 8) & 3); - } else { + } + else + { const int rst = (ol + 7) / 8; append_final_bits(out, rst, ol, state, is_all_upper, usx_hcodes, usx_hcode_lens); return rst; @@ -862,37 +998,39 @@ int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(cha } // Main API function. See unishox2.h for documentation -int unishox2_compress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen), const uint8_t usx_hcodes[], - const uint8_t usx_hcode_lens[], const char *usx_freq_seq[], const char *usx_templates[]) +int unishox2_compress(const char* in, int len, UNISHOX_API_OUT_AND_LEN(char* out, int olen), const uint8_t usx_hcodes[], + const uint8_t usx_hcode_lens[], const char* usx_freq_seq[], const char* usx_templates[]) { return unishox2_compress_lines(in, len, UNISHOX_API_OUT_AND_LEN(out, olen), usx_hcodes, usx_hcode_lens, usx_freq_seq, usx_templates, NULL); } // Main API function. See unishox2.h for documentation -int unishox2_compress_simple(const char *in, int len, char *out) +int unishox2_compress_simple(const char* in, int len, char* out) { return unishox2_compress_lines(in, len, UNISHOX_API_OUT_AND_LEN(out, INT_MAX - 1), USX_HCODES_DFLT, USX_HCODE_LENS_DFLT, USX_FREQ_SEQ_DFLT, USX_TEMPLATES, NULL); } // Reads one bit from in -int readBit(const char *in, int bit_no) +int readBit(const char* in, int bit_no) { return in[bit_no >> 3] & (0x80 >> (bit_no % 8)); } // Reads next 8 bits, if available -int read8bitCode(const char *in, int len, int bit_no) +int read8bitCode(const char* in, int len, int bit_no) { int bit_pos = bit_no & 0x07; int char_pos = bit_no >> 3; len >>= 3; uint8_t code = (((uint8_t)in[char_pos]) << bit_pos); char_pos++; - if (char_pos < len) { + if (char_pos < len) + { code |= ((uint8_t)in[char_pos]) >> (8 - bit_pos); - } else + } + else code |= (0xFF >> (8 - bit_pos)); return code; } @@ -910,9 +1048,9 @@ uint8_t usx_vsection_shift[] = {5, 4, 3, 1, 0}; /// Vertical decoder lookup table - 3 bits code len, 5 bytes vertical pos /// code len is one less as 8 cannot be accommodated in 3 bits -uint8_t usx_vcode_lookup[36] = {(1 << 5) + 0, (1 << 5) + 0, (2 << 5) + 1, (2 << 5) + 2, // Section 1 - (3 << 5) + 3, (3 << 5) + 4, (3 << 5) + 5, (3 << 5) + 6, // Section 2 - (3 << 5) + 7, (3 << 5) + 7, (4 << 5) + 8, (4 << 5) + 9, // Section 3 +uint8_t usx_vcode_lookup[36] = {(1 << 5) + 0, (1 << 5) + 0, (2 << 5) + 1, (2 << 5) + 2, // Section 1 + (3 << 5) + 3, (3 << 5) + 4, (3 << 5) + 5, (3 << 5) + 6, // Section 2 + (3 << 5) + 7, (3 << 5) + 7, (4 << 5) + 8, (4 << 5) + 9, // Section 3 (5 << 5) + 10, (5 << 5) + 10, (5 << 5) + 11, (5 << 5) + 11, // Section 4 (5 << 5) + 12, (5 << 5) + 12, (6 << 5) + 13, (6 << 5) + 14, (6 << 5) + 15, (6 << 5) + 15, (6 << 5) + 16, (6 << 5) + 16, // Section 5 @@ -926,13 +1064,16 @@ uint8_t usx_vcode_lookup[36] = {(1 << 5) + 0, (1 << 5) + 0, (2 << 5) + 1, (2 /// Decoder is designed for using less memory, not speed. \n /// Returns the veritical code index or 99 if match could not be found. \n /// Also updates bit_no_p with how many ever bits used by the vertical code. -int readVCodeIdx(const char *in, int len, int *bit_no_p) +int readVCodeIdx(const char* in, int len, int* bit_no_p) { - if (*bit_no_p < len) { + if (*bit_no_p < len) + { uint8_t code = read8bitCode(in, len, *bit_no_p); int i = 0; - do { - if (code <= usx_vsections[i]) { + do + { + if (code <= usx_vsections[i]) + { uint8_t vcode = usx_vcode_lookup[usx_vsection_pos[i] + ((code & usx_vsection_mask[i]) >> usx_vsection_shift[i])]; (*bit_no_p) += ((vcode >> 5) + 1); if (*bit_no_p > len) @@ -951,14 +1092,17 @@ uint8_t len_masks[] = {0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF}; /// depending on the hcodes defined using usx_hcodes and usx_hcode_lens \n /// Returns the horizontal code index or 99 if match could not be found. \n /// Also updates bit_no_p with how many ever bits used by the horizontal code. -int readHCodeIdx(const char *in, int len, int *bit_no_p, const uint8_t usx_hcodes[], const uint8_t usx_hcode_lens[]) +int readHCodeIdx(const char* in, int len, int* bit_no_p, const uint8_t usx_hcodes[], const uint8_t usx_hcode_lens[]) { if (!usx_hcode_lens[USX_ALPHA]) return USX_ALPHA; - if (*bit_no_p < len) { + if (*bit_no_p < len) + { uint8_t code = read8bitCode(in, len, *bit_no_p); - for (int code_pos = 0; code_pos < 5; code_pos++) { - if (usx_hcode_lens[code_pos] && (code & len_masks[usx_hcode_lens[code_pos] - 1]) == usx_hcodes[code_pos]) { + for (int code_pos = 0; code_pos < 5; code_pos++) + { + if (usx_hcode_lens[code_pos] && (code & len_masks[usx_hcode_lens[code_pos] - 1]) == usx_hcodes[code_pos]) + { *bit_no_p += usx_hcode_lens[code_pos]; return code_pos; } @@ -969,10 +1113,11 @@ int readHCodeIdx(const char *in, int len, int *bit_no_p, const uint8_t usx_hcode // TODO: Last value check.. Also len check in readBit /// Returns the position of step code (0, 10, 110, etc.) encountered in the stream -int getStepCodeIdx(const char *in, int len, int *bit_no_p, int limit) +int getStepCodeIdx(const char* in, int len, int* bit_no_p, int limit) { int idx = 0; - while (*bit_no_p < len && readBit(in, *bit_no_p)) { + while (*bit_no_p < len && readBit(in, *bit_no_p)) + { idx++; (*bit_no_p)++; if (idx == limit) @@ -985,10 +1130,11 @@ int getStepCodeIdx(const char *in, int len, int *bit_no_p, int limit) } /// Reads specified number of bits and builds the corresponding integer -int32_t getNumFromBits(const char *in, int len, int bit_no, int count) +int32_t getNumFromBits(const char* in, int len, int bit_no, int count) { int32_t ret = 0; - while (count-- && bit_no < len) { + while (count-- && bit_no < len) + { ret += (readBit(in, bit_no) ? 1 << count : 0); bit_no++; } @@ -996,7 +1142,7 @@ int32_t getNumFromBits(const char *in, int len, int bit_no, int count) } /// Decodes the count from the given bit stream at in. Also updates bit_no_p -int32_t readCount(const char *in, int *bit_no_p, int len) +int32_t readCount(const char* in, int* bit_no_p, int len) { int idx = getStepCodeIdx(in, len, bit_no_p, 4); if (idx == 99) @@ -1010,16 +1156,18 @@ int32_t readCount(const char *in, int *bit_no_p, int len) /// Decodes the Unicode codepoint from the given bit stream at in. Also updates bit_no_p \n /// When the step code is 5, reads the next step code to find out the special code. -int32_t readUnicode(const char *in, int *bit_no_p, int len) +int32_t readUnicode(const char* in, int* bit_no_p, int len) { int idx = getStepCodeIdx(in, len, bit_no_p, 5); if (idx == 99) return 0x7FFFFF00 + 99; - if (idx == 5) { + if (idx == 5) + { idx = getStepCodeIdx(in, len, bit_no_p, 4); return 0x7FFFFF00 + idx; } - if (idx >= 0) { + if (idx >= 0) + { int sign = (*bit_no_p < len ? readBit(in, *bit_no_p) : 0); (*bit_no_p)++; if (*bit_no_p + uni_bit_len[idx] - 1 >= len) @@ -1034,39 +1182,46 @@ int32_t readUnicode(const char *in, int *bit_no_p, int len) } /// Macro to ensure that the decoder does not append more than olen bytes to out -#define DEC_OUTPUT_CHAR(out, olen, ol, c) \ - do { \ - char *const obuf = (out); \ - const int oidx = (ol); \ - const int limit = (olen); \ - if (limit <= oidx) \ - return limit + 1; \ - else if (oidx < 0) \ - return 0; \ - else \ - obuf[oidx] = (c); \ +#define DEC_OUTPUT_CHAR(out, olen, ol, c) \ + do \ + { \ + char* const obuf = (out); \ + const int oidx = (ol); \ + const int limit = (olen); \ + if (limit <= oidx) \ + return limit + 1; \ + else if (oidx < 0) \ + return 0; \ + else \ + obuf[oidx] = (c); \ } while (0) /// Macro to ensure that the decoder does not append more than olen bytes to out -#define DEC_OUTPUT_CHARS(olen, exp) \ - do { \ - const int newidx = (exp); \ - const int limit = (olen); \ - if (newidx > limit) \ - return limit + 1; \ +#define DEC_OUTPUT_CHARS(olen, exp) \ + do \ + { \ + const int newidx = (exp); \ + const int limit = (olen); \ + if (newidx > limit) \ + return limit + 1; \ } while (0) /// Write given unicode code point to out as a UTF-8 sequence -int writeUTF8(char *out, int olen, int ol, int uni) +int writeUTF8(char* out, int olen, int ol, int uni) { - if (uni < (1 << 11)) { + if (uni < (1 << 11)) + { DEC_OUTPUT_CHAR(out, olen, ol++, 0xC0 + (uni >> 6)); DEC_OUTPUT_CHAR(out, olen, ol++, 0x80 + (uni & 0x3F)); - } else if (uni < (1 << 16)) { + } + else if (uni < (1 << 16)) + { DEC_OUTPUT_CHAR(out, olen, ol++, 0xE0 + (uni >> 12)); DEC_OUTPUT_CHAR(out, olen, ol++, 0x80 + ((uni >> 6) & 0x3F)); DEC_OUTPUT_CHAR(out, olen, ol++, 0x80 + (uni & 0x3F)); - } else { + } + else + { DEC_OUTPUT_CHAR(out, olen, ol++, 0xF0 + (uni >> 18)); DEC_OUTPUT_CHAR(out, olen, ol++, 0x80 + ((uni >> 12) & 0x3F)); DEC_OUTPUT_CHAR(out, olen, ol++, 0x80 + ((uni >> 6) & 0x3F)); @@ -1076,9 +1231,10 @@ int writeUTF8(char *out, int olen, int ol, int uni) } /// Decode repeating sequence and appends to out -int decodeRepeat(const char *in, int len, char *out, int olen, int ol, int *bit_no, struct us_lnk_lst *prev_lines) +int decodeRepeat(const char* in, int len, char* out, int olen, int ol, int* bit_no, struct us_lnk_lst* prev_lines) { - if (prev_lines) { + if (prev_lines) + { int32_t dict_len = readCount(in, bit_no, len) + NICE_LEN; if (dict_len < NICE_LEN) return -1; @@ -1088,7 +1244,7 @@ int decodeRepeat(const char *in, int len, char *out, int olen, int ol, int *bit_ int32_t ctx = readCount(in, bit_no, len); if (ctx < 0) return -1; - struct us_lnk_lst *cur_line = prev_lines; + struct us_lnk_lst* cur_line = prev_lines; const int left = olen - ol; while (ctx-- && cur_line) cur_line = cur_line->previous; @@ -1102,7 +1258,9 @@ int decodeRepeat(const char *in, int len, char *out, int olen, int ol, int *bit_ if (left < dict_len) return olen + 1; ol += dict_len; - } else { + } + else + { int32_t dict_len = readCount(in, bit_no, len) + NICE_LEN; if (dict_len < NICE_LEN) return -1; @@ -1134,9 +1292,9 @@ char getHexChar(int32_t nibble, int hex_type) } // Main API function. See unishox2.h for documentation -int unishox2_decompress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen), const uint8_t usx_hcodes[], - const uint8_t usx_hcode_lens[], const char *usx_freq_seq[], const char *usx_templates[], - struct us_lnk_lst *prev_lines) +int unishox2_decompress_lines(const char* in, int len, UNISHOX_API_OUT_AND_LEN(char* out, int olen), const uint8_t usx_hcodes[], + const uint8_t usx_hcode_lens[], const char* usx_freq_seq[], const char* usx_templates[], + struct us_lnk_lst* prev_lines) { int dstate; @@ -1156,31 +1314,38 @@ int unishox2_decompress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(c int prev_uni = 0; len <<= 3; - while (bit_no < len) { + while (bit_no < len) + { int orig_bit_no = bit_no; - if (dstate == USX_DELTA || h == USX_DELTA) { + if (dstate == USX_DELTA || h == USX_DELTA) + { if (dstate != USX_DELTA) h = dstate; int32_t delta = readUnicode(in, &bit_no, len); - if ((delta >> 8) == 0x7FFFFF) { + if ((delta >> 8) == 0x7FFFFF) + { int spl_code_idx = delta & 0x000000FF; if (spl_code_idx == 99) break; - switch (spl_code_idx) { + switch (spl_code_idx) + { case 0: DEC_OUTPUT_CHAR(out, olen, ol++, ' '); continue; case 1: h = readHCodeIdx(in, len, &bit_no, usx_hcodes, usx_hcode_lens); - if (h == 99) { + if (h == 99) + { bit_no = len; continue; } - if (h == USX_DELTA || h == USX_ALPHA) { + if (h == USX_DELTA || h == USX_ALPHA) + { dstate = h; continue; } - if (h == USX_DICT) { + if (h == USX_DICT) + { int rpt_ret = decodeRepeat(in, len, out, olen, ol, &bit_no, prev_lines); if (rpt_ret < 0) return ol; // if we break here it will only break out of switch @@ -1199,87 +1364,112 @@ int unishox2_decompress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(c DEC_OUTPUT_CHAR(out, olen, ol++, 10); continue; } - } else { + } + else + { prev_uni += delta; DEC_OUTPUT_CHARS(olen, ol = writeUTF8(out, olen, ol, prev_uni)); // printf("%ld, ", prev_uni); } if (dstate == USX_DELTA && h == USX_DELTA) continue; - } else + } + else h = dstate; char c = 0; uint8_t is_upper = is_all_upper; v = readVCodeIdx(in, len, &bit_no); - if (v == 99 || h == 99) { + if (v == 99 || h == 99) + { bit_no = orig_bit_no; break; } - if (v == 0 && h != USX_SYM) { + if (v == 0 && h != USX_SYM) + { if (bit_no >= len) break; - if (h != USX_NUM || dstate != USX_DELTA) { + if (h != USX_NUM || dstate != USX_DELTA) + { h = readHCodeIdx(in, len, &bit_no, usx_hcodes, usx_hcode_lens); - if (h == 99 || bit_no >= len) { + if (h == 99 || bit_no >= len) + { bit_no = orig_bit_no; break; } } - if (h == USX_ALPHA) { - if (dstate == USX_ALPHA) { + if (h == USX_ALPHA) + { + if (dstate == USX_ALPHA) + { if (!usx_hcode_lens[USX_ALPHA] && TERM_BYTE_PRESET_1 == (read8bitCode(in, len, bit_no - SW_CODE_LEN) & (0xFF << (8 - (is_all_upper ? TERM_BYTE_PRESET_1_LEN_UPPER : TERM_BYTE_PRESET_1_LEN_LOWER))))) break; // Terminator for preset 1 - if (is_all_upper) { + if (is_all_upper) + { is_upper = is_all_upper = 0; continue; } v = readVCodeIdx(in, len, &bit_no); - if (v == 99) { + if (v == 99) + { bit_no = orig_bit_no; break; } - if (v == 0) { + if (v == 0) + { h = readHCodeIdx(in, len, &bit_no, usx_hcodes, usx_hcode_lens); - if (h == 99) { + if (h == 99) + { bit_no = orig_bit_no; break; } - if (h == USX_ALPHA) { + if (h == USX_ALPHA) + { is_all_upper = 1; continue; } } is_upper = 1; - } else { + } + else + { dstate = USX_ALPHA; continue; } - } else if (h == USX_DICT) { + } + else if (h == USX_DICT) + { int rpt_ret = decodeRepeat(in, len, out, olen, ol, &bit_no, prev_lines); if (rpt_ret < 0) break; DEC_OUTPUT_CHARS(olen, ol = rpt_ret); continue; - } else if (h == USX_DELTA) { + } + else if (h == USX_DELTA) + { // printf("Sign: %d, bitno: %d\n", sign, bit_no); // printf("Code: %d\n", prev_uni); // printf("BitNo: %d\n", bit_no); continue; - } else { + } + else + { if (h != USX_NUM || dstate != USX_DELTA) v = readVCodeIdx(in, len, &bit_no); - if (v == 99) { + if (v == 99) + { bit_no = orig_bit_no; break; } - if (h == USX_NUM && v == 0) { + if (h == USX_NUM && v == 0) + { int idx = getStepCodeIdx(in, len, &bit_no, 5); if (idx == 99) break; - if (idx == 0) { + if (idx == 0) + { idx = getStepCodeIdx(in, len, &bit_no, 4); if (idx >= 5) break; @@ -1293,30 +1483,37 @@ int unishox2_decompress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(c break; rem = tlen - rem; int eof = 0; - for (int j = 0; j < rem; j++) { + for (int j = 0; j < rem; j++) + { char c_t = usx_templates[idx][j]; - if (c_t == 'f' || c_t == 'r' || c_t == 't' || c_t == 'o' || c_t == 'F') { + if (c_t == 'f' || c_t == 'r' || c_t == 't' || c_t == 'o' || c_t == 'F') + { char nibble_len = (c_t == 'f' || c_t == 'F' ? 4 : (c_t == 'r' ? 3 : (c_t == 't' ? 2 : 1))); const int32_t raw_char = getNumFromBits(in, len, bit_no, nibble_len); - if (raw_char < 0) { + if (raw_char < 0) + { eof = 1; break; } DEC_OUTPUT_CHAR(out, olen, ol++, getHexChar((char)raw_char, c_t == 'f' ? USX_NIB_HEX_LOWER : USX_NIB_HEX_UPPER)); bit_no += nibble_len; - } else + } + else DEC_OUTPUT_CHAR(out, olen, ol++, c_t); } if (eof) break; // reach input eof - } else if (idx == 5) { + } + else if (idx == 5) + { int32_t bin_count = readCount(in, &bit_no, len); if (bin_count < 0) break; if (bin_count == 0) // invalid encoding break; - do { + do + { const int32_t raw_char = getNumFromBits(in, len, bit_no, 8); if (raw_char < 0) break; @@ -1325,18 +1522,22 @@ int unishox2_decompress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(c } while (--bin_count); if (bin_count > 0) break; // reach input eof - } else { + } + else + { int32_t nibble_count = 0; if (idx == 2 || idx == 4) nibble_count = 32; - else { + else + { nibble_count = readCount(in, &bit_no, len); if (nibble_count < 0) break; if (nibble_count == 0) // invalid encoding break; } - do { + do + { int32_t nibble = getNumFromBits(in, len, bit_no, 4); if (nibble < 0) break; @@ -1355,24 +1556,34 @@ int unishox2_decompress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(c } } } - if (is_upper && v == 1) { + if (is_upper && v == 1) + { h = dstate = USX_DELTA; // continuous delta coding continue; } if (h < 3 && v < 28) c = usx_sets[h][v]; - if (c >= 'a' && c <= 'z') { + if (c >= 'a' && c <= 'z') + { dstate = USX_ALPHA; if (is_upper) c -= 32; - } else { - if (c >= '0' && c <= '9') { + } + else + { + if (c >= '0' && c <= '9') + { dstate = USX_NUM; - } else if (c == 0) { - if (v == 8) { + } + else if (c == 0) + { + if (v == 8) + { DEC_OUTPUT_CHAR(out, olen, ol++, '\r'); DEC_OUTPUT_CHAR(out, olen, ol++, '\n'); - } else if (h == USX_NUM && v == 26) { + } + else if (h == USX_NUM && v == 26) + { int32_t count = readCount(in, &bit_no, len); if (count < 0) break; @@ -1382,7 +1593,9 @@ int unishox2_decompress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(c char rpt_c = out[ol - 1]; while (count--) DEC_OUTPUT_CHAR(out, olen, ol++, rpt_c); - } else if (h == USX_SYM && v > 24) { + } + else if (h == USX_SYM && v > 24) + { v -= 25; const int freqlen = (int)strlen(usx_freq_seq[v]); const int left = olen - ol; @@ -1392,7 +1605,9 @@ int unishox2_decompress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(c if (left < freqlen) return olen + 1; ol += freqlen; - } else if (h == USX_NUM && v > 22 && v < 26) { + } + else if (h == USX_NUM && v > 22 && v < 26) + { v -= (23 - 3); const int freqlen = (int)strlen(usx_freq_seq[v]); const int left = olen - ol; @@ -1402,7 +1617,8 @@ int unishox2_decompress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(c if (left < freqlen) return olen + 1; ol += freqlen; - } else + } + else break; // Terminator if (dstate == USX_DELTA) h = USX_DELTA; @@ -1418,15 +1634,15 @@ int unishox2_decompress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(c } // Main API function. See unishox2.h for documentation -int unishox2_decompress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen), const uint8_t usx_hcodes[], - const uint8_t usx_hcode_lens[], const char *usx_freq_seq[], const char *usx_templates[]) +int unishox2_decompress(const char* in, int len, UNISHOX_API_OUT_AND_LEN(char* out, int olen), const uint8_t usx_hcodes[], + const uint8_t usx_hcode_lens[], const char* usx_freq_seq[], const char* usx_templates[]) { return unishox2_decompress_lines(in, len, UNISHOX_API_OUT_AND_LEN(out, olen), usx_hcodes, usx_hcode_lens, usx_freq_seq, usx_templates, NULL); } // Main API function. See unishox2.h for documentation -int unishox2_decompress_simple(const char *in, int len, char *out) +int unishox2_decompress_simple(const char* in, int len, char* out) { return unishox2_decompress(in, len, UNISHOX_API_OUT_AND_LEN(out, INT_MAX - 1), USX_PSET_DFLT); } \ No newline at end of file diff --git a/src/chat/infra/meshtastic/compression/unishox2.h b/src/chat/infra/meshtastic/compression/unishox2.h index 823128f0..90822972 100644 --- a/src/chat/infra/meshtastic/compression/unishox2.h +++ b/src/chat/infra/meshtastic/compression/unishox2.h @@ -61,145 +61,145 @@ /// Default Horizontal codes. When composition of text is know beforehand, the other hcodes in this section can be used to achieve /// more compression. -#define USX_HCODES_DFLT \ - (const unsigned char[]) \ - { \ - 0x00, 0x40, 0x80, 0xC0, 0xE0 \ +#define USX_HCODES_DFLT \ + (const unsigned char[]) \ + { \ + 0x00, 0x40, 0x80, 0xC0, 0xE0 \ } /// Length of each default hcode -#define USX_HCODE_LENS_DFLT \ - (const unsigned char[]) \ - { \ - 2, 2, 2, 3, 3 \ +#define USX_HCODE_LENS_DFLT \ + (const unsigned char[]) \ + { \ + 2, 2, 2, 3, 3 \ } /// Horizontal codes preset for English Alphabet content only -#define USX_HCODES_ALPHA_ONLY \ - (const unsigned char[]) \ - { \ - 0x00, 0x00, 0x00, 0x00, 0x00 \ +#define USX_HCODES_ALPHA_ONLY \ + (const unsigned char[]) \ + { \ + 0x00, 0x00, 0x00, 0x00, 0x00 \ } /// Length of each Alpha only hcode -#define USX_HCODE_LENS_ALPHA_ONLY \ - (const unsigned char[]) \ - { \ - 0, 0, 0, 0, 0 \ +#define USX_HCODE_LENS_ALPHA_ONLY \ + (const unsigned char[]) \ + { \ + 0, 0, 0, 0, 0 \ } /// Horizontal codes preset for Alpha Numeric content only -#define USX_HCODES_ALPHA_NUM_ONLY \ - (const unsigned char[]) \ - { \ - 0x00, 0x00, 0x80, 0x00, 0x00 \ +#define USX_HCODES_ALPHA_NUM_ONLY \ + (const unsigned char[]) \ + { \ + 0x00, 0x00, 0x80, 0x00, 0x00 \ } /// Length of each Alpha numeric hcode -#define USX_HCODE_LENS_ALPHA_NUM_ONLY \ - (const unsigned char[]) \ - { \ - 1, 0, 1, 0, 0 \ +#define USX_HCODE_LENS_ALPHA_NUM_ONLY \ + (const unsigned char[]) \ + { \ + 1, 0, 1, 0, 0 \ } /// Horizontal codes preset for Alpha Numeric and Symbol content only -#define USX_HCODES_ALPHA_NUM_SYM_ONLY \ - (const unsigned char[]) \ - { \ - 0x00, 0x80, 0xC0, 0x00, 0x00 \ +#define USX_HCODES_ALPHA_NUM_SYM_ONLY \ + (const unsigned char[]) \ + { \ + 0x00, 0x80, 0xC0, 0x00, 0x00 \ } /// Length of each Alpha numeric and symbol hcodes -#define USX_HCODE_LENS_ALPHA_NUM_SYM_ONLY \ - (const unsigned char[]) \ - { \ - 1, 2, 2, 0, 0 \ +#define USX_HCODE_LENS_ALPHA_NUM_SYM_ONLY \ + (const unsigned char[]) \ + { \ + 1, 2, 2, 0, 0 \ } /// Horizontal codes preset favouring Alphabet content -#define USX_HCODES_FAVOR_ALPHA \ - (const unsigned char[]) \ - { \ - 0x00, 0x80, 0xA0, 0xC0, 0xE0 \ +#define USX_HCODES_FAVOR_ALPHA \ + (const unsigned char[]) \ + { \ + 0x00, 0x80, 0xA0, 0xC0, 0xE0 \ } /// Length of each hcode favouring Alpha content -#define USX_HCODE_LENS_FAVOR_ALPHA \ - (const unsigned char[]) \ - { \ - 1, 3, 3, 3, 3 \ +#define USX_HCODE_LENS_FAVOR_ALPHA \ + (const unsigned char[]) \ + { \ + 1, 3, 3, 3, 3 \ } /// Horizontal codes preset favouring repeating sequences -#define USX_HCODES_FAVOR_DICT \ - (const unsigned char[]) \ - { \ - 0x00, 0x40, 0xC0, 0x80, 0xE0 \ +#define USX_HCODES_FAVOR_DICT \ + (const unsigned char[]) \ + { \ + 0x00, 0x40, 0xC0, 0x80, 0xE0 \ } /// Length of each hcode favouring repeating sequences -#define USX_HCODE_LENS_FAVOR_DICT \ - (const unsigned char[]) \ - { \ - 2, 2, 3, 2, 3 \ +#define USX_HCODE_LENS_FAVOR_DICT \ + (const unsigned char[]) \ + { \ + 2, 2, 3, 2, 3 \ } /// Horizontal codes preset favouring symbols -#define USX_HCODES_FAVOR_SYM \ - (const unsigned char[]) \ - { \ - 0x80, 0x00, 0xA0, 0xC0, 0xE0 \ +#define USX_HCODES_FAVOR_SYM \ + (const unsigned char[]) \ + { \ + 0x80, 0x00, 0xA0, 0xC0, 0xE0 \ } /// Length of each hcode favouring symbols -#define USX_HCODE_LENS_FAVOR_SYM \ - (const unsigned char[]) \ - { \ - 3, 1, 3, 3, 3 \ +#define USX_HCODE_LENS_FAVOR_SYM \ + (const unsigned char[]) \ + { \ + 3, 1, 3, 3, 3 \ } // #define USX_HCODES_FAVOR_UMLAUT {0x00, 0x40, 0xE0, 0xC0, 0x80} // #define USX_HCODE_LENS_FAVOR_UMLAUT {2, 2, 3, 3, 2} /// Horizontal codes preset favouring umlaut letters -#define USX_HCODES_FAVOR_UMLAUT \ - (const unsigned char[]) \ - { \ - 0x80, 0xA0, 0xC0, 0xE0, 0x00 \ +#define USX_HCODES_FAVOR_UMLAUT \ + (const unsigned char[]) \ + { \ + 0x80, 0xA0, 0xC0, 0xE0, 0x00 \ } /// Length of each hcode favouring umlaut letters -#define USX_HCODE_LENS_FAVOR_UMLAUT \ - (const unsigned char[]) \ - { \ - 3, 3, 3, 3, 1 \ +#define USX_HCODE_LENS_FAVOR_UMLAUT \ + (const unsigned char[]) \ + { \ + 3, 3, 3, 3, 1 \ } /// Horizontal codes preset for no repeating sequences -#define USX_HCODES_NO_DICT \ - (const unsigned char[]) \ - { \ - 0x00, 0x40, 0x80, 0x00, 0xC0 \ +#define USX_HCODES_NO_DICT \ + (const unsigned char[]) \ + { \ + 0x00, 0x40, 0x80, 0x00, 0xC0 \ } /// Length of each hcode for no repeating sequences -#define USX_HCODE_LENS_NO_DICT \ - (const unsigned char[]) \ - { \ - 2, 2, 2, 0, 2 \ +#define USX_HCODE_LENS_NO_DICT \ + (const unsigned char[]) \ + { \ + 2, 2, 2, 0, 2 \ } /// Horizontal codes preset for no Unicode characters -#define USX_HCODES_NO_UNI \ - (const unsigned char[]) \ - { \ - 0x00, 0x40, 0x80, 0xC0, 0x00 \ +#define USX_HCODES_NO_UNI \ + (const unsigned char[]) \ + { \ + 0x00, 0x40, 0x80, 0xC0, 0x00 \ } /// Length of each hcode for no Unicode characters -#define USX_HCODE_LENS_NO_UNI \ - (const unsigned char[]) \ - { \ - 2, 2, 2, 2, 0 \ +#define USX_HCODE_LENS_NO_UNI \ + (const unsigned char[]) \ + { \ + 2, 2, 2, 2, 0 \ } -extern const char *USX_FREQ_SEQ_DFLT[]; -extern const char *USX_FREQ_SEQ_TXT[]; -extern const char *USX_FREQ_SEQ_URL[]; -extern const char *USX_FREQ_SEQ_JSON[]; -extern const char *USX_FREQ_SEQ_HTML[]; -extern const char *USX_FREQ_SEQ_XML[]; -extern const char *USX_TEMPLATES[]; +extern const char* USX_FREQ_SEQ_DFLT[]; +extern const char* USX_FREQ_SEQ_TXT[]; +extern const char* USX_FREQ_SEQ_URL[]; +extern const char* USX_FREQ_SEQ_JSON[]; +extern const char* USX_FREQ_SEQ_HTML[]; +extern const char* USX_FREQ_SEQ_XML[]; +extern const char* USX_TEMPLATES[]; /// Default preset parameter set. When composition of text is know beforehand, the other parameter sets in this section can be /// used to achieve more compression. @@ -209,10 +209,10 @@ extern const char *USX_TEMPLATES[]; /// Preset parameter set for Alpha numeric content #define USX_PSET_ALPHA_NUM_ONLY USX_HCODES_ALPHA_NUM_ONLY, USX_HCODE_LENS_ALPHA_NUM_ONLY, USX_FREQ_SEQ_TXT, USX_TEMPLATES /// Preset parameter set for Alpha numeric and symbol content -#define USX_PSET_ALPHA_NUM_SYM_ONLY \ +#define USX_PSET_ALPHA_NUM_SYM_ONLY \ USX_HCODES_ALPHA_NUM_SYM_ONLY, USX_HCODE_LENS_ALPHA_NUM_SYM_ONLY, USX_FREQ_SEQ_DFLT, USX_TEMPLATES /// Preset parameter set for Alpha numeric symbol content having predominantly text -#define USX_PSET_ALPHA_NUM_SYM_ONLY_TXT \ +#define USX_PSET_ALPHA_NUM_SYM_ONLY_TXT \ USX_HCODES_ALPHA_NUM_SYM_ONLY, USX_HCODE_LENS_ALPHA_NUM_SYM_ONLY, USX_FREQ_SEQ_DFLT, USX_TEMPLATES /// Preset parameter set favouring Alphabet content #define USX_PSET_FAVOR_ALPHA USX_HCODES_FAVOR_ALPHA, USX_HCODE_LENS_FAVOR_ALPHA, USX_FREQ_SEQ_TXT, USX_TEMPLATES @@ -243,9 +243,10 @@ extern const char *USX_TEMPLATES[]; * This structure is used when a string array needs to be compressed. * This is passed as a parameter to the unishox2_decompress_lines() function */ -struct us_lnk_lst { - char *data; - struct us_lnk_lst *previous; +struct us_lnk_lst +{ + char* data; + struct us_lnk_lst* previous; }; /** @@ -270,14 +271,14 @@ struct us_lnk_lst { * @param[in] len length in bytes * @param[out] out output buffer - should be large enough to hold compressed output */ -extern int unishox2_compress_simple(const char *in, int len, char *out); +extern int unishox2_compress_simple(const char* in, int len, char* out); /** * Simple API for decompressing a string * @param[in] in Input compressed bytes (output of unishox2_compress functions) * @param[in] len length of 'in' in bytes * @param[out] out output buffer for ASCII / UTF-8 string - should be large enough */ -extern int unishox2_decompress_simple(const char *in, int len, char *out); +extern int unishox2_decompress_simple(const char* in, int len, char* out); /** * Comprehensive API for compressing a string * @@ -294,9 +295,9 @@ extern int unishox2_decompress_simple(const char *in, int len, char *out); * @param[in] usx_freq_seq Frequently occurring sequences. See USX_FREQ_SEQ_* macros for samples * @param[in] usx_templates Templates of frequently occurring patterns. See USX_TEMPLATES macro. */ -extern int unishox2_compress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen), - const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[], const char *usx_freq_seq[], - const char *usx_templates[]); +extern int unishox2_compress(const char* in, int len, UNISHOX_API_OUT_AND_LEN(char* out, int olen), + const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[], const char* usx_freq_seq[], + const char* usx_templates[]); /** * Comprehensive API for de-compressing a string * @@ -313,9 +314,9 @@ extern int unishox2_compress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(ch * @param[in] usx_freq_seq Frequently occurring sequences. See USX_FREQ_SEQ_* macros for samples * @param[in] usx_templates Templates of frequently occurring patterns. See USX_TEMPLATES macro. */ -extern int unishox2_decompress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen), - const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[], const char *usx_freq_seq[], - const char *usx_templates[]); +extern int unishox2_decompress(const char* in, int len, UNISHOX_API_OUT_AND_LEN(char* out, int olen), + const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[], const char* usx_freq_seq[], + const char* usx_templates[]); /** * More Comprehensive API for compressing array of strings * @@ -326,9 +327,9 @@ extern int unishox2_decompress(const char *in, int len, UNISHOX_API_OUT_AND_LEN( * and stored in a compressed array of bytes for use as a constant in other programs \n * where each element of the array can be decompressed and used at runtime. */ -extern int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen), +extern int unishox2_compress_lines(const char* in, int len, UNISHOX_API_OUT_AND_LEN(char* out, int olen), const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[], - const char *usx_freq_seq[], const char *usx_templates[], struct us_lnk_lst *prev_lines); + const char* usx_freq_seq[], const char* usx_templates[], struct us_lnk_lst* prev_lines); /** * More Comprehensive API for de-compressing array of strings \n * This function is not be used in conjuction with unishox2_compress_lines() @@ -340,8 +341,8 @@ extern int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_ * routine which takes this compressed array as parameter and index to be \n * decompressed. */ -extern int unishox2_decompress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen), +extern int unishox2_decompress_lines(const char* in, int len, UNISHOX_API_OUT_AND_LEN(char* out, int olen), const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[], - const char *usx_freq_seq[], const char *usx_templates[], struct us_lnk_lst *prev_lines); + const char* usx_freq_seq[], const char* usx_templates[], struct us_lnk_lst* prev_lines); #endif diff --git a/src/chat/infra/meshtastic/generated/meshtastic/admin.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/admin.pb.cpp index 4c4d0e3d..45fec023 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/admin.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/admin.pb.cpp @@ -8,28 +8,12 @@ PB_BIND(meshtastic_AdminMessage, meshtastic_AdminMessage, 2) - PB_BIND(meshtastic_AdminMessage_InputEvent, meshtastic_AdminMessage_InputEvent, AUTO) - PB_BIND(meshtastic_HamParameters, meshtastic_HamParameters, AUTO) - PB_BIND(meshtastic_NodeRemoteHardwarePinsResponse, meshtastic_NodeRemoteHardwarePinsResponse, 2) - PB_BIND(meshtastic_SharedContact, meshtastic_SharedContact, AUTO) - PB_BIND(meshtastic_KeyVerificationAdmin, meshtastic_KeyVerificationAdmin, AUTO) - - - - - - - - - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/admin.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/admin.pb.h index a542cf29..05d4d747 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/admin.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/admin.pb.h @@ -3,13 +3,13 @@ #ifndef PB_MESHTASTIC_MESHTASTIC_ADMIN_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_ADMIN_PB_H_INCLUDED -#include #include "meshtastic/channel.pb.h" #include "meshtastic/config.pb.h" #include "meshtastic/connection_status.pb.h" #include "meshtastic/device_ui.pb.h" #include "meshtastic/mesh.pb.h" #include "meshtastic/module_config.pb.h" +#include #if PB_PROTO_HEADER_VERSION != 40 #error Regenerate this file with the current version of nanopb generator. @@ -17,7 +17,8 @@ /* Enum definitions */ /* TODO: REPLACE */ -typedef enum _meshtastic_AdminMessage_ConfigType { +typedef enum _meshtastic_AdminMessage_ConfigType +{ /* TODO: REPLACE */ meshtastic_AdminMessage_ConfigType_DEVICE_CONFIG = 0, /* TODO: REPLACE */ @@ -41,7 +42,8 @@ typedef enum _meshtastic_AdminMessage_ConfigType { } meshtastic_AdminMessage_ConfigType; /* TODO: REPLACE */ -typedef enum _meshtastic_AdminMessage_ModuleConfigType { +typedef enum _meshtastic_AdminMessage_ModuleConfigType +{ /* TODO: REPLACE */ meshtastic_AdminMessage_ModuleConfigType_MQTT_CONFIG = 0, /* TODO: REPLACE */ @@ -70,7 +72,8 @@ typedef enum _meshtastic_AdminMessage_ModuleConfigType { meshtastic_AdminMessage_ModuleConfigType_PAXCOUNTER_CONFIG = 12 } meshtastic_AdminMessage_ModuleConfigType; -typedef enum _meshtastic_AdminMessage_BackupLocation { +typedef enum _meshtastic_AdminMessage_BackupLocation +{ /* Backup to the internal flash */ meshtastic_AdminMessage_BackupLocation_FLASH = 0, /* Backup to the SD card */ @@ -78,7 +81,8 @@ typedef enum _meshtastic_AdminMessage_BackupLocation { } meshtastic_AdminMessage_BackupLocation; /* Three stages of this request. */ -typedef enum _meshtastic_KeyVerificationAdmin_MessageType { +typedef enum _meshtastic_KeyVerificationAdmin_MessageType +{ /* This is the first stage, where a client initiates */ meshtastic_KeyVerificationAdmin_MessageType_INITIATE_VERIFICATION = 0, /* After the nonce has been returned over the mesh, the client prompts for the security number @@ -92,7 +96,8 @@ typedef enum _meshtastic_KeyVerificationAdmin_MessageType { /* Struct definitions */ /* Input event message to be sent to the node. */ -typedef struct _meshtastic_AdminMessage_InputEvent { +typedef struct _meshtastic_AdminMessage_InputEvent +{ /* The input event code */ uint8_t event_code; /* Keyboard character code */ @@ -104,7 +109,8 @@ typedef struct _meshtastic_AdminMessage_InputEvent { } meshtastic_AdminMessage_InputEvent; /* Parameters for setting up Meshtastic for ameteur radio usage */ -typedef struct _meshtastic_HamParameters { +typedef struct _meshtastic_HamParameters +{ /* Amateur radio call sign, eg. KD2ABC */ char call_sign[8]; /* Transmit power in dBm at the LoRA transceiver, not including any amplification */ @@ -118,13 +124,15 @@ typedef struct _meshtastic_HamParameters { } meshtastic_HamParameters; /* Response envelope for node_remote_hardware_pins */ -typedef struct _meshtastic_NodeRemoteHardwarePinsResponse { +typedef struct _meshtastic_NodeRemoteHardwarePinsResponse +{ /* Nodes and their respective remote hardware GPIO pins */ pb_size_t node_remote_hardware_pins_count; meshtastic_NodeRemoteHardwarePin node_remote_hardware_pins[16]; } meshtastic_NodeRemoteHardwarePinsResponse; -typedef struct _meshtastic_SharedContact { +typedef struct _meshtastic_SharedContact +{ /* The node number of the contact */ uint32_t node_num; /* The User of the contact */ @@ -137,7 +145,8 @@ typedef struct _meshtastic_SharedContact { } meshtastic_SharedContact; /* This message is used by a client to initiate or complete a key verification */ -typedef struct _meshtastic_KeyVerificationAdmin { +typedef struct _meshtastic_KeyVerificationAdmin +{ meshtastic_KeyVerificationAdmin_MessageType message_type; /* The nodenum we're requesting */ uint32_t remote_nodenum; @@ -152,9 +161,11 @@ typedef PB_BYTES_ARRAY_T(8) meshtastic_AdminMessage_session_passkey_t; /* This message is handled by the Admin module and is responsible for all settings/channel read/write operations. This message is used to do settings operations to both remote AND local nodes. (Prior to 1.2 these operations were done via special ToRadio operations) */ -typedef struct _meshtastic_AdminMessage { +typedef struct _meshtastic_AdminMessage +{ pb_size_t which_payload_variant; - union { + union + { /* Send the specified channel in the response to this message NOTE: This field is sent with the channel index + 1 (to ensure we never try to send 'zero' - which protobufs treats as not present) */ uint32_t get_channel_request; @@ -282,27 +293,27 @@ typedef struct _meshtastic_AdminMessage { meshtastic_AdminMessage_session_passkey_t session_passkey; } meshtastic_AdminMessage; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Helper constants for enums */ #define _meshtastic_AdminMessage_ConfigType_MIN meshtastic_AdminMessage_ConfigType_DEVICE_CONFIG #define _meshtastic_AdminMessage_ConfigType_MAX meshtastic_AdminMessage_ConfigType_DEVICEUI_CONFIG -#define _meshtastic_AdminMessage_ConfigType_ARRAYSIZE ((meshtastic_AdminMessage_ConfigType)(meshtastic_AdminMessage_ConfigType_DEVICEUI_CONFIG+1)) +#define _meshtastic_AdminMessage_ConfigType_ARRAYSIZE ((meshtastic_AdminMessage_ConfigType)(meshtastic_AdminMessage_ConfigType_DEVICEUI_CONFIG + 1)) #define _meshtastic_AdminMessage_ModuleConfigType_MIN meshtastic_AdminMessage_ModuleConfigType_MQTT_CONFIG #define _meshtastic_AdminMessage_ModuleConfigType_MAX meshtastic_AdminMessage_ModuleConfigType_PAXCOUNTER_CONFIG -#define _meshtastic_AdminMessage_ModuleConfigType_ARRAYSIZE ((meshtastic_AdminMessage_ModuleConfigType)(meshtastic_AdminMessage_ModuleConfigType_PAXCOUNTER_CONFIG+1)) +#define _meshtastic_AdminMessage_ModuleConfigType_ARRAYSIZE ((meshtastic_AdminMessage_ModuleConfigType)(meshtastic_AdminMessage_ModuleConfigType_PAXCOUNTER_CONFIG + 1)) #define _meshtastic_AdminMessage_BackupLocation_MIN meshtastic_AdminMessage_BackupLocation_FLASH #define _meshtastic_AdminMessage_BackupLocation_MAX meshtastic_AdminMessage_BackupLocation_SD -#define _meshtastic_AdminMessage_BackupLocation_ARRAYSIZE ((meshtastic_AdminMessage_BackupLocation)(meshtastic_AdminMessage_BackupLocation_SD+1)) +#define _meshtastic_AdminMessage_BackupLocation_ARRAYSIZE ((meshtastic_AdminMessage_BackupLocation)(meshtastic_AdminMessage_BackupLocation_SD + 1)) #define _meshtastic_KeyVerificationAdmin_MessageType_MIN meshtastic_KeyVerificationAdmin_MessageType_INITIATE_VERIFICATION #define _meshtastic_KeyVerificationAdmin_MessageType_MAX meshtastic_KeyVerificationAdmin_MessageType_DO_NOT_VERIFY -#define _meshtastic_KeyVerificationAdmin_MessageType_ARRAYSIZE ((meshtastic_KeyVerificationAdmin_MessageType)(meshtastic_KeyVerificationAdmin_MessageType_DO_NOT_VERIFY+1)) +#define _meshtastic_KeyVerificationAdmin_MessageType_ARRAYSIZE ((meshtastic_KeyVerificationAdmin_MessageType)(meshtastic_KeyVerificationAdmin_MessageType_DO_NOT_VERIFY + 1)) #define meshtastic_AdminMessage_payload_variant_get_config_request_ENUMTYPE meshtastic_AdminMessage_ConfigType #define meshtastic_AdminMessage_payload_variant_get_module_config_request_ENUMTYPE meshtastic_AdminMessage_ModuleConfigType @@ -310,39 +321,76 @@ extern "C" { #define meshtastic_AdminMessage_payload_variant_restore_preferences_ENUMTYPE meshtastic_AdminMessage_BackupLocation #define meshtastic_AdminMessage_payload_variant_remove_backup_preferences_ENUMTYPE meshtastic_AdminMessage_BackupLocation - - - - #define meshtastic_KeyVerificationAdmin_message_type_ENUMTYPE meshtastic_KeyVerificationAdmin_MessageType - /* Initializer values for message structs */ -#define meshtastic_AdminMessage_init_default {0, {0}, {0, {0}}} -#define meshtastic_AdminMessage_InputEvent_init_default {0, 0, 0, 0} -#define meshtastic_HamParameters_init_default {"", 0, 0, ""} -#define meshtastic_NodeRemoteHardwarePinsResponse_init_default {0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}} -#define meshtastic_SharedContact_init_default {0, false, meshtastic_User_init_default, 0, 0} -#define meshtastic_KeyVerificationAdmin_init_default {_meshtastic_KeyVerificationAdmin_MessageType_MIN, 0, 0, false, 0} -#define meshtastic_AdminMessage_init_zero {0, {0}, {0, {0}}} -#define meshtastic_AdminMessage_InputEvent_init_zero {0, 0, 0, 0} -#define meshtastic_HamParameters_init_zero {"", 0, 0, ""} -#define meshtastic_NodeRemoteHardwarePinsResponse_init_zero {0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}} -#define meshtastic_SharedContact_init_zero {0, false, meshtastic_User_init_zero, 0, 0} -#define meshtastic_KeyVerificationAdmin_init_zero {_meshtastic_KeyVerificationAdmin_MessageType_MIN, 0, 0, false, 0} +#define meshtastic_AdminMessage_init_default \ + { \ + 0, {0}, \ + { \ + 0, { 0 } \ + } \ + } +#define meshtastic_AdminMessage_InputEvent_init_default \ + { \ + 0, 0, 0, 0 \ + } +#define meshtastic_HamParameters_init_default \ + { \ + "", 0, 0, "" \ + } +#define meshtastic_NodeRemoteHardwarePinsResponse_init_default \ + { \ + 0, { meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default } \ + } +#define meshtastic_SharedContact_init_default \ + { \ + 0, false, meshtastic_User_init_default, 0, 0 \ + } +#define meshtastic_KeyVerificationAdmin_init_default \ + { \ + _meshtastic_KeyVerificationAdmin_MessageType_MIN, 0, 0, false, 0 \ + } +#define meshtastic_AdminMessage_init_zero \ + { \ + 0, {0}, \ + { \ + 0, { 0 } \ + } \ + } +#define meshtastic_AdminMessage_InputEvent_init_zero \ + { \ + 0, 0, 0, 0 \ + } +#define meshtastic_HamParameters_init_zero \ + { \ + "", 0, 0, "" \ + } +#define meshtastic_NodeRemoteHardwarePinsResponse_init_zero \ + { \ + 0, { meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero } \ + } +#define meshtastic_SharedContact_init_zero \ + { \ + 0, false, meshtastic_User_init_zero, 0, 0 \ + } +#define meshtastic_KeyVerificationAdmin_init_zero \ + { \ + _meshtastic_KeyVerificationAdmin_MessageType_MIN, 0, 0, false, 0 \ + } /* Field tags (for use in manual encoding/decoding) */ #define meshtastic_AdminMessage_InputEvent_event_code_tag 1 #define meshtastic_AdminMessage_InputEvent_kb_char_tag 2 #define meshtastic_AdminMessage_InputEvent_touch_x_tag 3 #define meshtastic_AdminMessage_InputEvent_touch_y_tag 4 -#define meshtastic_HamParameters_call_sign_tag 1 -#define meshtastic_HamParameters_tx_power_tag 2 -#define meshtastic_HamParameters_frequency_tag 3 -#define meshtastic_HamParameters_short_name_tag 4 +#define meshtastic_HamParameters_call_sign_tag 1 +#define meshtastic_HamParameters_tx_power_tag 2 +#define meshtastic_HamParameters_frequency_tag 3 +#define meshtastic_HamParameters_short_name_tag 4 #define meshtastic_NodeRemoteHardwarePinsResponse_node_remote_hardware_pins_tag 1 -#define meshtastic_SharedContact_node_num_tag 1 -#define meshtastic_SharedContact_user_tag 2 +#define meshtastic_SharedContact_node_num_tag 1 +#define meshtastic_SharedContact_user_tag 2 #define meshtastic_SharedContact_should_ignore_tag 3 #define meshtastic_SharedContact_manually_verified_tag 4 #define meshtastic_KeyVerificationAdmin_message_type_tag 1 @@ -370,14 +418,14 @@ extern "C" { #define meshtastic_AdminMessage_get_node_remote_hardware_pins_response_tag 20 #define meshtastic_AdminMessage_enter_dfu_mode_request_tag 21 #define meshtastic_AdminMessage_delete_file_request_tag 22 -#define meshtastic_AdminMessage_set_scale_tag 23 +#define meshtastic_AdminMessage_set_scale_tag 23 #define meshtastic_AdminMessage_backup_preferences_tag 24 #define meshtastic_AdminMessage_restore_preferences_tag 25 #define meshtastic_AdminMessage_remove_backup_preferences_tag 26 #define meshtastic_AdminMessage_send_input_event_tag 27 -#define meshtastic_AdminMessage_set_owner_tag 32 -#define meshtastic_AdminMessage_set_channel_tag 33 -#define meshtastic_AdminMessage_set_config_tag 34 +#define meshtastic_AdminMessage_set_owner_tag 32 +#define meshtastic_AdminMessage_set_channel_tag 33 +#define meshtastic_AdminMessage_set_config_tag 34 #define meshtastic_AdminMessage_set_module_config_tag 35 #define meshtastic_AdminMessage_set_canned_message_module_messages_tag 36 #define meshtastic_AdminMessage_set_ringtone_message_tag 37 @@ -394,7 +442,7 @@ extern "C" { #define meshtastic_AdminMessage_remove_ignored_node_tag 48 #define meshtastic_AdminMessage_begin_edit_settings_tag 64 #define meshtastic_AdminMessage_commit_edit_settings_tag 65 -#define meshtastic_AdminMessage_add_contact_tag 66 +#define meshtastic_AdminMessage_add_contact_tag 66 #define meshtastic_AdminMessage_key_verification_tag 67 #define meshtastic_AdminMessage_factory_reset_device_tag 94 #define meshtastic_AdminMessage_reboot_ota_seconds_tag 95 @@ -406,62 +454,62 @@ extern "C" { #define meshtastic_AdminMessage_session_passkey_tag 101 /* Struct field encoding specification for nanopb */ -#define meshtastic_AdminMessage_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, UINT32, (payload_variant,get_channel_request,get_channel_request), 1) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_channel_response,get_channel_response), 2) \ -X(a, STATIC, ONEOF, BOOL, (payload_variant,get_owner_request,get_owner_request), 3) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_owner_response,get_owner_response), 4) \ -X(a, STATIC, ONEOF, UENUM, (payload_variant,get_config_request,get_config_request), 5) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_config_response,get_config_response), 6) \ -X(a, STATIC, ONEOF, UENUM, (payload_variant,get_module_config_request,get_module_config_request), 7) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_module_config_response,get_module_config_response), 8) \ -X(a, STATIC, ONEOF, BOOL, (payload_variant,get_canned_message_module_messages_request,get_canned_message_module_messages_request), 10) \ -X(a, STATIC, ONEOF, STRING, (payload_variant,get_canned_message_module_messages_response,get_canned_message_module_messages_response), 11) \ -X(a, STATIC, ONEOF, BOOL, (payload_variant,get_device_metadata_request,get_device_metadata_request), 12) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_device_metadata_response,get_device_metadata_response), 13) \ -X(a, STATIC, ONEOF, BOOL, (payload_variant,get_ringtone_request,get_ringtone_request), 14) \ -X(a, STATIC, ONEOF, STRING, (payload_variant,get_ringtone_response,get_ringtone_response), 15) \ -X(a, STATIC, ONEOF, BOOL, (payload_variant,get_device_connection_status_request,get_device_connection_status_request), 16) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_device_connection_status_response,get_device_connection_status_response), 17) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_ham_mode,set_ham_mode), 18) \ -X(a, STATIC, ONEOF, BOOL, (payload_variant,get_node_remote_hardware_pins_request,get_node_remote_hardware_pins_request), 19) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_node_remote_hardware_pins_response,get_node_remote_hardware_pins_response), 20) \ -X(a, STATIC, ONEOF, BOOL, (payload_variant,enter_dfu_mode_request,enter_dfu_mode_request), 21) \ -X(a, STATIC, ONEOF, STRING, (payload_variant,delete_file_request,delete_file_request), 22) \ -X(a, STATIC, ONEOF, UINT32, (payload_variant,set_scale,set_scale), 23) \ -X(a, STATIC, ONEOF, UENUM, (payload_variant,backup_preferences,backup_preferences), 24) \ -X(a, STATIC, ONEOF, UENUM, (payload_variant,restore_preferences,restore_preferences), 25) \ -X(a, STATIC, ONEOF, UENUM, (payload_variant,remove_backup_preferences,remove_backup_preferences), 26) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,send_input_event,send_input_event), 27) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_owner,set_owner), 32) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_channel,set_channel), 33) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_config,set_config), 34) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_module_config,set_module_config), 35) \ -X(a, STATIC, ONEOF, STRING, (payload_variant,set_canned_message_module_messages,set_canned_message_module_messages), 36) \ -X(a, STATIC, ONEOF, STRING, (payload_variant,set_ringtone_message,set_ringtone_message), 37) \ -X(a, STATIC, ONEOF, UINT32, (payload_variant,remove_by_nodenum,remove_by_nodenum), 38) \ -X(a, STATIC, ONEOF, UINT32, (payload_variant,set_favorite_node,set_favorite_node), 39) \ -X(a, STATIC, ONEOF, UINT32, (payload_variant,remove_favorite_node,remove_favorite_node), 40) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_fixed_position,set_fixed_position), 41) \ -X(a, STATIC, ONEOF, BOOL, (payload_variant,remove_fixed_position,remove_fixed_position), 42) \ -X(a, STATIC, ONEOF, FIXED32, (payload_variant,set_time_only,set_time_only), 43) \ -X(a, STATIC, ONEOF, BOOL, (payload_variant,get_ui_config_request,get_ui_config_request), 44) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_ui_config_response,get_ui_config_response), 45) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,store_ui_config,store_ui_config), 46) \ -X(a, STATIC, ONEOF, UINT32, (payload_variant,set_ignored_node,set_ignored_node), 47) \ -X(a, STATIC, ONEOF, UINT32, (payload_variant,remove_ignored_node,remove_ignored_node), 48) \ -X(a, STATIC, ONEOF, BOOL, (payload_variant,begin_edit_settings,begin_edit_settings), 64) \ -X(a, STATIC, ONEOF, BOOL, (payload_variant,commit_edit_settings,commit_edit_settings), 65) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,add_contact,add_contact), 66) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,key_verification,key_verification), 67) \ -X(a, STATIC, ONEOF, INT32, (payload_variant,factory_reset_device,factory_reset_device), 94) \ -X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_ota_seconds,reboot_ota_seconds), 95) \ -X(a, STATIC, ONEOF, BOOL, (payload_variant,exit_simulator,exit_simulator), 96) \ -X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_seconds,reboot_seconds), 97) \ -X(a, STATIC, ONEOF, INT32, (payload_variant,shutdown_seconds,shutdown_seconds), 98) \ -X(a, STATIC, ONEOF, INT32, (payload_variant,factory_reset_config,factory_reset_config), 99) \ -X(a, STATIC, ONEOF, BOOL, (payload_variant,nodedb_reset,nodedb_reset), 100) \ -X(a, STATIC, SINGULAR, BYTES, session_passkey, 101) +#define meshtastic_AdminMessage_FIELDLIST(X, a) \ + X(a, STATIC, ONEOF, UINT32, (payload_variant, get_channel_request, get_channel_request), 1) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, get_channel_response, get_channel_response), 2) \ + X(a, STATIC, ONEOF, BOOL, (payload_variant, get_owner_request, get_owner_request), 3) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, get_owner_response, get_owner_response), 4) \ + X(a, STATIC, ONEOF, UENUM, (payload_variant, get_config_request, get_config_request), 5) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, get_config_response, get_config_response), 6) \ + X(a, STATIC, ONEOF, UENUM, (payload_variant, get_module_config_request, get_module_config_request), 7) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, get_module_config_response, get_module_config_response), 8) \ + X(a, STATIC, ONEOF, BOOL, (payload_variant, get_canned_message_module_messages_request, get_canned_message_module_messages_request), 10) \ + X(a, STATIC, ONEOF, STRING, (payload_variant, get_canned_message_module_messages_response, get_canned_message_module_messages_response), 11) \ + X(a, STATIC, ONEOF, BOOL, (payload_variant, get_device_metadata_request, get_device_metadata_request), 12) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, get_device_metadata_response, get_device_metadata_response), 13) \ + X(a, STATIC, ONEOF, BOOL, (payload_variant, get_ringtone_request, get_ringtone_request), 14) \ + X(a, STATIC, ONEOF, STRING, (payload_variant, get_ringtone_response, get_ringtone_response), 15) \ + X(a, STATIC, ONEOF, BOOL, (payload_variant, get_device_connection_status_request, get_device_connection_status_request), 16) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, get_device_connection_status_response, get_device_connection_status_response), 17) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, set_ham_mode, set_ham_mode), 18) \ + X(a, STATIC, ONEOF, BOOL, (payload_variant, get_node_remote_hardware_pins_request, get_node_remote_hardware_pins_request), 19) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, get_node_remote_hardware_pins_response, get_node_remote_hardware_pins_response), 20) \ + X(a, STATIC, ONEOF, BOOL, (payload_variant, enter_dfu_mode_request, enter_dfu_mode_request), 21) \ + X(a, STATIC, ONEOF, STRING, (payload_variant, delete_file_request, delete_file_request), 22) \ + X(a, STATIC, ONEOF, UINT32, (payload_variant, set_scale, set_scale), 23) \ + X(a, STATIC, ONEOF, UENUM, (payload_variant, backup_preferences, backup_preferences), 24) \ + X(a, STATIC, ONEOF, UENUM, (payload_variant, restore_preferences, restore_preferences), 25) \ + X(a, STATIC, ONEOF, UENUM, (payload_variant, remove_backup_preferences, remove_backup_preferences), 26) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, send_input_event, send_input_event), 27) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, set_owner, set_owner), 32) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, set_channel, set_channel), 33) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, set_config, set_config), 34) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, set_module_config, set_module_config), 35) \ + X(a, STATIC, ONEOF, STRING, (payload_variant, set_canned_message_module_messages, set_canned_message_module_messages), 36) \ + X(a, STATIC, ONEOF, STRING, (payload_variant, set_ringtone_message, set_ringtone_message), 37) \ + X(a, STATIC, ONEOF, UINT32, (payload_variant, remove_by_nodenum, remove_by_nodenum), 38) \ + X(a, STATIC, ONEOF, UINT32, (payload_variant, set_favorite_node, set_favorite_node), 39) \ + X(a, STATIC, ONEOF, UINT32, (payload_variant, remove_favorite_node, remove_favorite_node), 40) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, set_fixed_position, set_fixed_position), 41) \ + X(a, STATIC, ONEOF, BOOL, (payload_variant, remove_fixed_position, remove_fixed_position), 42) \ + X(a, STATIC, ONEOF, FIXED32, (payload_variant, set_time_only, set_time_only), 43) \ + X(a, STATIC, ONEOF, BOOL, (payload_variant, get_ui_config_request, get_ui_config_request), 44) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, get_ui_config_response, get_ui_config_response), 45) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, store_ui_config, store_ui_config), 46) \ + X(a, STATIC, ONEOF, UINT32, (payload_variant, set_ignored_node, set_ignored_node), 47) \ + X(a, STATIC, ONEOF, UINT32, (payload_variant, remove_ignored_node, remove_ignored_node), 48) \ + X(a, STATIC, ONEOF, BOOL, (payload_variant, begin_edit_settings, begin_edit_settings), 64) \ + X(a, STATIC, ONEOF, BOOL, (payload_variant, commit_edit_settings, commit_edit_settings), 65) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, add_contact, add_contact), 66) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, key_verification, key_verification), 67) \ + X(a, STATIC, ONEOF, INT32, (payload_variant, factory_reset_device, factory_reset_device), 94) \ + X(a, STATIC, ONEOF, INT32, (payload_variant, reboot_ota_seconds, reboot_ota_seconds), 95) \ + X(a, STATIC, ONEOF, BOOL, (payload_variant, exit_simulator, exit_simulator), 96) \ + X(a, STATIC, ONEOF, INT32, (payload_variant, reboot_seconds, reboot_seconds), 97) \ + X(a, STATIC, ONEOF, INT32, (payload_variant, shutdown_seconds, shutdown_seconds), 98) \ + X(a, STATIC, ONEOF, INT32, (payload_variant, factory_reset_config, factory_reset_config), 99) \ + X(a, STATIC, ONEOF, BOOL, (payload_variant, nodedb_reset, nodedb_reset), 100) \ + X(a, STATIC, SINGULAR, BYTES, session_passkey, 101) #define meshtastic_AdminMessage_CALLBACK NULL #define meshtastic_AdminMessage_DEFAULT NULL #define meshtastic_AdminMessage_payload_variant_get_channel_response_MSGTYPE meshtastic_Channel @@ -484,50 +532,50 @@ X(a, STATIC, SINGULAR, BYTES, session_passkey, 101) #define meshtastic_AdminMessage_payload_variant_key_verification_MSGTYPE meshtastic_KeyVerificationAdmin #define meshtastic_AdminMessage_InputEvent_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, event_code, 1) \ -X(a, STATIC, SINGULAR, UINT32, kb_char, 2) \ -X(a, STATIC, SINGULAR, UINT32, touch_x, 3) \ -X(a, STATIC, SINGULAR, UINT32, touch_y, 4) + X(a, STATIC, SINGULAR, UINT32, event_code, 1) \ + X(a, STATIC, SINGULAR, UINT32, kb_char, 2) \ + X(a, STATIC, SINGULAR, UINT32, touch_x, 3) \ + X(a, STATIC, SINGULAR, UINT32, touch_y, 4) #define meshtastic_AdminMessage_InputEvent_CALLBACK NULL #define meshtastic_AdminMessage_InputEvent_DEFAULT NULL #define meshtastic_HamParameters_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, call_sign, 1) \ -X(a, STATIC, SINGULAR, INT32, tx_power, 2) \ -X(a, STATIC, SINGULAR, FLOAT, frequency, 3) \ -X(a, STATIC, SINGULAR, STRING, short_name, 4) + X(a, STATIC, SINGULAR, STRING, call_sign, 1) \ + X(a, STATIC, SINGULAR, INT32, tx_power, 2) \ + X(a, STATIC, SINGULAR, FLOAT, frequency, 3) \ + X(a, STATIC, SINGULAR, STRING, short_name, 4) #define meshtastic_HamParameters_CALLBACK NULL #define meshtastic_HamParameters_DEFAULT NULL #define meshtastic_NodeRemoteHardwarePinsResponse_FIELDLIST(X, a) \ -X(a, STATIC, REPEATED, MESSAGE, node_remote_hardware_pins, 1) + X(a, STATIC, REPEATED, MESSAGE, node_remote_hardware_pins, 1) #define meshtastic_NodeRemoteHardwarePinsResponse_CALLBACK NULL #define meshtastic_NodeRemoteHardwarePinsResponse_DEFAULT NULL #define meshtastic_NodeRemoteHardwarePinsResponse_node_remote_hardware_pins_MSGTYPE meshtastic_NodeRemoteHardwarePin -#define meshtastic_SharedContact_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, node_num, 1) \ -X(a, STATIC, OPTIONAL, MESSAGE, user, 2) \ -X(a, STATIC, SINGULAR, BOOL, should_ignore, 3) \ -X(a, STATIC, SINGULAR, BOOL, manually_verified, 4) +#define meshtastic_SharedContact_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UINT32, node_num, 1) \ + X(a, STATIC, OPTIONAL, MESSAGE, user, 2) \ + X(a, STATIC, SINGULAR, BOOL, should_ignore, 3) \ + X(a, STATIC, SINGULAR, BOOL, manually_verified, 4) #define meshtastic_SharedContact_CALLBACK NULL #define meshtastic_SharedContact_DEFAULT NULL #define meshtastic_SharedContact_user_MSGTYPE meshtastic_User #define meshtastic_KeyVerificationAdmin_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UENUM, message_type, 1) \ -X(a, STATIC, SINGULAR, UINT32, remote_nodenum, 2) \ -X(a, STATIC, SINGULAR, UINT64, nonce, 3) \ -X(a, STATIC, OPTIONAL, UINT32, security_number, 4) + X(a, STATIC, SINGULAR, UENUM, message_type, 1) \ + X(a, STATIC, SINGULAR, UINT32, remote_nodenum, 2) \ + X(a, STATIC, SINGULAR, UINT64, nonce, 3) \ + X(a, STATIC, OPTIONAL, UINT32, security_number, 4) #define meshtastic_KeyVerificationAdmin_CALLBACK NULL #define meshtastic_KeyVerificationAdmin_DEFAULT NULL -extern const pb_msgdesc_t meshtastic_AdminMessage_msg; -extern const pb_msgdesc_t meshtastic_AdminMessage_InputEvent_msg; -extern const pb_msgdesc_t meshtastic_HamParameters_msg; -extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePinsResponse_msg; -extern const pb_msgdesc_t meshtastic_SharedContact_msg; -extern const pb_msgdesc_t meshtastic_KeyVerificationAdmin_msg; + extern const pb_msgdesc_t meshtastic_AdminMessage_msg; + extern const pb_msgdesc_t meshtastic_AdminMessage_InputEvent_msg; + extern const pb_msgdesc_t meshtastic_HamParameters_msg; + extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePinsResponse_msg; + extern const pb_msgdesc_t meshtastic_SharedContact_msg; + extern const pb_msgdesc_t meshtastic_KeyVerificationAdmin_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_AdminMessage_fields &meshtastic_AdminMessage_msg @@ -539,12 +587,12 @@ extern const pb_msgdesc_t meshtastic_KeyVerificationAdmin_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_ADMIN_PB_H_MAX_SIZE meshtastic_AdminMessage_size -#define meshtastic_AdminMessage_InputEvent_size 14 -#define meshtastic_AdminMessage_size 511 -#define meshtastic_HamParameters_size 31 -#define meshtastic_KeyVerificationAdmin_size 25 +#define meshtastic_AdminMessage_InputEvent_size 14 +#define meshtastic_AdminMessage_size 511 +#define meshtastic_HamParameters_size 31 +#define meshtastic_KeyVerificationAdmin_size 25 #define meshtastic_NodeRemoteHardwarePinsResponse_size 496 -#define meshtastic_SharedContact_size 127 +#define meshtastic_SharedContact_size 127 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/apponly.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/apponly.pb.cpp index 8b1b3da1..6dca4a63 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/apponly.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/apponly.pb.cpp @@ -7,6 +7,3 @@ #endif PB_BIND(meshtastic_ChannelSet, meshtastic_ChannelSet, 2) - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/apponly.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/apponly.pb.h index f4c33bd7..e9087090 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/apponly.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/apponly.pb.h @@ -3,9 +3,9 @@ #ifndef PB_MESHTASTIC_MESHTASTIC_APPONLY_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_APPONLY_PB_H_INCLUDED -#include #include "meshtastic/channel.pb.h" #include "meshtastic/config.pb.h" +#include #if PB_PROTO_HEADER_VERSION != 40 #error Regenerate this file with the current version of nanopb generator. @@ -17,7 +17,8 @@ any SECONDARY channels. No DISABLED channels are included. This abstraction is used only on the the 'app side' of the world (ie python, javascript and android etc) to show a group of Channels as a (long) URL */ -typedef struct _meshtastic_ChannelSet { +typedef struct _meshtastic_ChannelSet +{ /* Channel list with settings */ pb_size_t settings_count; meshtastic_ChannelSettings settings[8]; @@ -26,36 +27,42 @@ typedef struct _meshtastic_ChannelSet { meshtastic_Config_LoRaConfig lora_config; } meshtastic_ChannelSet; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Initializer values for message structs */ -#define meshtastic_ChannelSet_init_default {0, {meshtastic_ChannelSettings_init_default, meshtastic_ChannelSettings_init_default, meshtastic_ChannelSettings_init_default, meshtastic_ChannelSettings_init_default, meshtastic_ChannelSettings_init_default, meshtastic_ChannelSettings_init_default, meshtastic_ChannelSettings_init_default, meshtastic_ChannelSettings_init_default}, false, meshtastic_Config_LoRaConfig_init_default} -#define meshtastic_ChannelSet_init_zero {0, {meshtastic_ChannelSettings_init_zero, meshtastic_ChannelSettings_init_zero, meshtastic_ChannelSettings_init_zero, meshtastic_ChannelSettings_init_zero, meshtastic_ChannelSettings_init_zero, meshtastic_ChannelSettings_init_zero, meshtastic_ChannelSettings_init_zero, meshtastic_ChannelSettings_init_zero}, false, meshtastic_Config_LoRaConfig_init_zero} +#define meshtastic_ChannelSet_init_default \ + { \ + 0, {meshtastic_ChannelSettings_init_default, meshtastic_ChannelSettings_init_default, meshtastic_ChannelSettings_init_default, meshtastic_ChannelSettings_init_default, meshtastic_ChannelSettings_init_default, meshtastic_ChannelSettings_init_default, meshtastic_ChannelSettings_init_default, meshtastic_ChannelSettings_init_default}, false, meshtastic_Config_LoRaConfig_init_default \ + } +#define meshtastic_ChannelSet_init_zero \ + { \ + 0, {meshtastic_ChannelSettings_init_zero, meshtastic_ChannelSettings_init_zero, meshtastic_ChannelSettings_init_zero, meshtastic_ChannelSettings_init_zero, meshtastic_ChannelSettings_init_zero, meshtastic_ChannelSettings_init_zero, meshtastic_ChannelSettings_init_zero, meshtastic_ChannelSettings_init_zero}, false, meshtastic_Config_LoRaConfig_init_zero \ + } /* Field tags (for use in manual encoding/decoding) */ -#define meshtastic_ChannelSet_settings_tag 1 -#define meshtastic_ChannelSet_lora_config_tag 2 +#define meshtastic_ChannelSet_settings_tag 1 +#define meshtastic_ChannelSet_lora_config_tag 2 /* Struct field encoding specification for nanopb */ -#define meshtastic_ChannelSet_FIELDLIST(X, a) \ -X(a, STATIC, REPEATED, MESSAGE, settings, 1) \ -X(a, STATIC, OPTIONAL, MESSAGE, lora_config, 2) +#define meshtastic_ChannelSet_FIELDLIST(X, a) \ + X(a, STATIC, REPEATED, MESSAGE, settings, 1) \ + X(a, STATIC, OPTIONAL, MESSAGE, lora_config, 2) #define meshtastic_ChannelSet_CALLBACK NULL #define meshtastic_ChannelSet_DEFAULT NULL #define meshtastic_ChannelSet_settings_MSGTYPE meshtastic_ChannelSettings #define meshtastic_ChannelSet_lora_config_MSGTYPE meshtastic_Config_LoRaConfig -extern const pb_msgdesc_t meshtastic_ChannelSet_msg; + extern const pb_msgdesc_t meshtastic_ChannelSet_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_ChannelSet_fields &meshtastic_ChannelSet_msg /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_APPONLY_PB_H_MAX_SIZE meshtastic_ChannelSet_size -#define meshtastic_ChannelSet_size 679 +#define meshtastic_ChannelSet_size 679 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/atak.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/atak.pb.cpp index a0368cf6..52baac78 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/atak.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/atak.pb.cpp @@ -8,24 +8,12 @@ PB_BIND(meshtastic_TAKPacket, meshtastic_TAKPacket, 2) - PB_BIND(meshtastic_GeoChat, meshtastic_GeoChat, 2) - PB_BIND(meshtastic_Group, meshtastic_Group, AUTO) - PB_BIND(meshtastic_Status, meshtastic_Status, AUTO) - PB_BIND(meshtastic_Contact, meshtastic_Contact, AUTO) - PB_BIND(meshtastic_PLI, meshtastic_PLI, AUTO) - - - - - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/atak.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/atak.pb.h index 8533bcbf..c1ead602 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/atak.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/atak.pb.h @@ -10,7 +10,8 @@ #endif /* Enum definitions */ -typedef enum _meshtastic_Team { +typedef enum _meshtastic_Team +{ /* Unspecifed */ meshtastic_Team_Unspecifed_Color = 0, /* White */ @@ -44,7 +45,8 @@ typedef enum _meshtastic_Team { } meshtastic_Team; /* Role of the group member */ -typedef enum _meshtastic_MemberRole { +typedef enum _meshtastic_MemberRole +{ /* Unspecifed */ meshtastic_MemberRole_Unspecifed = 0, /* Team Member */ @@ -67,7 +69,8 @@ typedef enum _meshtastic_MemberRole { /* Struct definitions */ /* ATAK GeoChat message */ -typedef struct _meshtastic_GeoChat { +typedef struct _meshtastic_GeoChat +{ /* The text message */ char message[200]; /* Uid recipient of the message */ @@ -80,7 +83,8 @@ typedef struct _meshtastic_GeoChat { /* ATAK Group <__group role='Team Member' name='Cyan'/> */ -typedef struct _meshtastic_Group { +typedef struct _meshtastic_Group +{ /* Role of the group member */ meshtastic_MemberRole role; /* Team (color) @@ -90,14 +94,16 @@ typedef struct _meshtastic_Group { /* ATAK EUD Status */ -typedef struct _meshtastic_Status { +typedef struct _meshtastic_Status +{ /* Battery level */ uint8_t battery; } meshtastic_Status; /* ATAK Contact */ -typedef struct _meshtastic_Contact { +typedef struct _meshtastic_Contact +{ /* Callsign */ char callsign[120]; /* Device callsign */ @@ -105,7 +111,8 @@ typedef struct _meshtastic_Contact { } meshtastic_Contact; /* Position Location Information from ATAK */ -typedef struct _meshtastic_PLI { +typedef struct _meshtastic_PLI +{ /* The new preferred location encoding, multiply by 1e-7 to get degrees in floating point */ int32_t latitude_i; @@ -122,7 +129,8 @@ typedef struct _meshtastic_PLI { typedef PB_BYTES_ARRAY_T(220) meshtastic_TAKPacket_detail_t; /* Packets for the official ATAK Plugin */ -typedef struct _meshtastic_TAKPacket { +typedef struct _meshtastic_TAKPacket +{ /* Are the payloads strings compressed for LoRA transport? */ bool is_compressed; /* The contact / callsign for ATAK user */ @@ -135,7 +143,8 @@ typedef struct _meshtastic_TAKPacket { bool has_status; meshtastic_Status status; pb_size_t which_payload_variant; - union { + union + { /* TAK position report */ meshtastic_PLI pli; /* ATAK GeoChat message */ @@ -146,74 +155,104 @@ typedef struct _meshtastic_TAKPacket { } payload_variant; } meshtastic_TAKPacket; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Helper constants for enums */ #define _meshtastic_Team_MIN meshtastic_Team_Unspecifed_Color #define _meshtastic_Team_MAX meshtastic_Team_Brown -#define _meshtastic_Team_ARRAYSIZE ((meshtastic_Team)(meshtastic_Team_Brown+1)) +#define _meshtastic_Team_ARRAYSIZE ((meshtastic_Team)(meshtastic_Team_Brown + 1)) #define _meshtastic_MemberRole_MIN meshtastic_MemberRole_Unspecifed #define _meshtastic_MemberRole_MAX meshtastic_MemberRole_K9 -#define _meshtastic_MemberRole_ARRAYSIZE ((meshtastic_MemberRole)(meshtastic_MemberRole_K9+1)) - - +#define _meshtastic_MemberRole_ARRAYSIZE ((meshtastic_MemberRole)(meshtastic_MemberRole_K9 + 1)) #define meshtastic_Group_role_ENUMTYPE meshtastic_MemberRole #define meshtastic_Group_team_ENUMTYPE meshtastic_Team - - - - /* Initializer values for message structs */ -#define meshtastic_TAKPacket_init_default {0, false, meshtastic_Contact_init_default, false, meshtastic_Group_init_default, false, meshtastic_Status_init_default, 0, {meshtastic_PLI_init_default}} -#define meshtastic_GeoChat_init_default {"", false, "", false, ""} -#define meshtastic_Group_init_default {_meshtastic_MemberRole_MIN, _meshtastic_Team_MIN} -#define meshtastic_Status_init_default {0} -#define meshtastic_Contact_init_default {"", ""} -#define meshtastic_PLI_init_default {0, 0, 0, 0, 0} -#define meshtastic_TAKPacket_init_zero {0, false, meshtastic_Contact_init_zero, false, meshtastic_Group_init_zero, false, meshtastic_Status_init_zero, 0, {meshtastic_PLI_init_zero}} -#define meshtastic_GeoChat_init_zero {"", false, "", false, ""} -#define meshtastic_Group_init_zero {_meshtastic_MemberRole_MIN, _meshtastic_Team_MIN} -#define meshtastic_Status_init_zero {0} -#define meshtastic_Contact_init_zero {"", ""} -#define meshtastic_PLI_init_zero {0, 0, 0, 0, 0} +#define meshtastic_TAKPacket_init_default \ + { \ + 0, false, meshtastic_Contact_init_default, false, meshtastic_Group_init_default, false, meshtastic_Status_init_default, 0, { meshtastic_PLI_init_default } \ + } +#define meshtastic_GeoChat_init_default \ + { \ + "", false, "", false, "" \ + } +#define meshtastic_Group_init_default \ + { \ + _meshtastic_MemberRole_MIN, _meshtastic_Team_MIN \ + } +#define meshtastic_Status_init_default \ + { \ + 0 \ + } +#define meshtastic_Contact_init_default \ + { \ + "", "" \ + } +#define meshtastic_PLI_init_default \ + { \ + 0, 0, 0, 0, 0 \ + } +#define meshtastic_TAKPacket_init_zero \ + { \ + 0, false, meshtastic_Contact_init_zero, false, meshtastic_Group_init_zero, false, meshtastic_Status_init_zero, 0, { meshtastic_PLI_init_zero } \ + } +#define meshtastic_GeoChat_init_zero \ + { \ + "", false, "", false, "" \ + } +#define meshtastic_Group_init_zero \ + { \ + _meshtastic_MemberRole_MIN, _meshtastic_Team_MIN \ + } +#define meshtastic_Status_init_zero \ + { \ + 0 \ + } +#define meshtastic_Contact_init_zero \ + { \ + "", "" \ + } +#define meshtastic_PLI_init_zero \ + { \ + 0, 0, 0, 0, 0 \ + } /* Field tags (for use in manual encoding/decoding) */ -#define meshtastic_GeoChat_message_tag 1 -#define meshtastic_GeoChat_to_tag 2 -#define meshtastic_GeoChat_to_callsign_tag 3 -#define meshtastic_Group_role_tag 1 -#define meshtastic_Group_team_tag 2 -#define meshtastic_Status_battery_tag 1 -#define meshtastic_Contact_callsign_tag 1 -#define meshtastic_Contact_device_callsign_tag 2 -#define meshtastic_PLI_latitude_i_tag 1 -#define meshtastic_PLI_longitude_i_tag 2 -#define meshtastic_PLI_altitude_tag 3 -#define meshtastic_PLI_speed_tag 4 -#define meshtastic_PLI_course_tag 5 -#define meshtastic_TAKPacket_is_compressed_tag 1 -#define meshtastic_TAKPacket_contact_tag 2 -#define meshtastic_TAKPacket_group_tag 3 -#define meshtastic_TAKPacket_status_tag 4 -#define meshtastic_TAKPacket_pli_tag 5 -#define meshtastic_TAKPacket_chat_tag 6 -#define meshtastic_TAKPacket_detail_tag 7 +#define meshtastic_GeoChat_message_tag 1 +#define meshtastic_GeoChat_to_tag 2 +#define meshtastic_GeoChat_to_callsign_tag 3 +#define meshtastic_Group_role_tag 1 +#define meshtastic_Group_team_tag 2 +#define meshtastic_Status_battery_tag 1 +#define meshtastic_Contact_callsign_tag 1 +#define meshtastic_Contact_device_callsign_tag 2 +#define meshtastic_PLI_latitude_i_tag 1 +#define meshtastic_PLI_longitude_i_tag 2 +#define meshtastic_PLI_altitude_tag 3 +#define meshtastic_PLI_speed_tag 4 +#define meshtastic_PLI_course_tag 5 +#define meshtastic_TAKPacket_is_compressed_tag 1 +#define meshtastic_TAKPacket_contact_tag 2 +#define meshtastic_TAKPacket_group_tag 3 +#define meshtastic_TAKPacket_status_tag 4 +#define meshtastic_TAKPacket_pli_tag 5 +#define meshtastic_TAKPacket_chat_tag 6 +#define meshtastic_TAKPacket_detail_tag 7 /* Struct field encoding specification for nanopb */ -#define meshtastic_TAKPacket_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, is_compressed, 1) \ -X(a, STATIC, OPTIONAL, MESSAGE, contact, 2) \ -X(a, STATIC, OPTIONAL, MESSAGE, group, 3) \ -X(a, STATIC, OPTIONAL, MESSAGE, status, 4) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,pli,payload_variant.pli), 5) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,chat,payload_variant.chat), 6) \ -X(a, STATIC, ONEOF, BYTES, (payload_variant,detail,payload_variant.detail), 7) +#define meshtastic_TAKPacket_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, BOOL, is_compressed, 1) \ + X(a, STATIC, OPTIONAL, MESSAGE, contact, 2) \ + X(a, STATIC, OPTIONAL, MESSAGE, group, 3) \ + X(a, STATIC, OPTIONAL, MESSAGE, status, 4) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, pli, payload_variant.pli), 5) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, chat, payload_variant.chat), 6) \ + X(a, STATIC, ONEOF, BYTES, (payload_variant, detail, payload_variant.detail), 7) #define meshtastic_TAKPacket_CALLBACK NULL #define meshtastic_TAKPacket_DEFAULT NULL #define meshtastic_TAKPacket_contact_MSGTYPE meshtastic_Contact @@ -222,45 +261,45 @@ X(a, STATIC, ONEOF, BYTES, (payload_variant,detail,payload_variant.detai #define meshtastic_TAKPacket_payload_variant_pli_MSGTYPE meshtastic_PLI #define meshtastic_TAKPacket_payload_variant_chat_MSGTYPE meshtastic_GeoChat -#define meshtastic_GeoChat_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, message, 1) \ -X(a, STATIC, OPTIONAL, STRING, to, 2) \ -X(a, STATIC, OPTIONAL, STRING, to_callsign, 3) +#define meshtastic_GeoChat_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, STRING, message, 1) \ + X(a, STATIC, OPTIONAL, STRING, to, 2) \ + X(a, STATIC, OPTIONAL, STRING, to_callsign, 3) #define meshtastic_GeoChat_CALLBACK NULL #define meshtastic_GeoChat_DEFAULT NULL -#define meshtastic_Group_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UENUM, role, 1) \ -X(a, STATIC, SINGULAR, UENUM, team, 2) +#define meshtastic_Group_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UENUM, role, 1) \ + X(a, STATIC, SINGULAR, UENUM, team, 2) #define meshtastic_Group_CALLBACK NULL #define meshtastic_Group_DEFAULT NULL #define meshtastic_Status_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, battery, 1) + X(a, STATIC, SINGULAR, UINT32, battery, 1) #define meshtastic_Status_CALLBACK NULL #define meshtastic_Status_DEFAULT NULL -#define meshtastic_Contact_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, callsign, 1) \ -X(a, STATIC, SINGULAR, STRING, device_callsign, 2) +#define meshtastic_Contact_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, STRING, callsign, 1) \ + X(a, STATIC, SINGULAR, STRING, device_callsign, 2) #define meshtastic_Contact_CALLBACK NULL #define meshtastic_Contact_DEFAULT NULL -#define meshtastic_PLI_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, SFIXED32, latitude_i, 1) \ -X(a, STATIC, SINGULAR, SFIXED32, longitude_i, 2) \ -X(a, STATIC, SINGULAR, INT32, altitude, 3) \ -X(a, STATIC, SINGULAR, UINT32, speed, 4) \ -X(a, STATIC, SINGULAR, UINT32, course, 5) +#define meshtastic_PLI_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, SFIXED32, latitude_i, 1) \ + X(a, STATIC, SINGULAR, SFIXED32, longitude_i, 2) \ + X(a, STATIC, SINGULAR, INT32, altitude, 3) \ + X(a, STATIC, SINGULAR, UINT32, speed, 4) \ + X(a, STATIC, SINGULAR, UINT32, course, 5) #define meshtastic_PLI_CALLBACK NULL #define meshtastic_PLI_DEFAULT NULL -extern const pb_msgdesc_t meshtastic_TAKPacket_msg; -extern const pb_msgdesc_t meshtastic_GeoChat_msg; -extern const pb_msgdesc_t meshtastic_Group_msg; -extern const pb_msgdesc_t meshtastic_Status_msg; -extern const pb_msgdesc_t meshtastic_Contact_msg; -extern const pb_msgdesc_t meshtastic_PLI_msg; + extern const pb_msgdesc_t meshtastic_TAKPacket_msg; + extern const pb_msgdesc_t meshtastic_GeoChat_msg; + extern const pb_msgdesc_t meshtastic_Group_msg; + extern const pb_msgdesc_t meshtastic_Status_msg; + extern const pb_msgdesc_t meshtastic_Contact_msg; + extern const pb_msgdesc_t meshtastic_PLI_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_TAKPacket_fields &meshtastic_TAKPacket_msg @@ -272,12 +311,12 @@ extern const pb_msgdesc_t meshtastic_PLI_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_ATAK_PB_H_MAX_SIZE meshtastic_TAKPacket_size -#define meshtastic_Contact_size 242 -#define meshtastic_GeoChat_size 444 -#define meshtastic_Group_size 4 -#define meshtastic_PLI_size 31 -#define meshtastic_Status_size 3 -#define meshtastic_TAKPacket_size 705 +#define meshtastic_Contact_size 242 +#define meshtastic_GeoChat_size 444 +#define meshtastic_Group_size 4 +#define meshtastic_PLI_size 31 +#define meshtastic_Status_size 3 +#define meshtastic_TAKPacket_size 705 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/cannedmessages.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/cannedmessages.pb.cpp index 1f4ebc92..eab0aaeb 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/cannedmessages.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/cannedmessages.pb.cpp @@ -7,6 +7,3 @@ #endif PB_BIND(meshtastic_CannedMessageModuleConfig, meshtastic_CannedMessageModuleConfig, AUTO) - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/cannedmessages.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/cannedmessages.pb.h index 8343c4d6..bd32edfd 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/cannedmessages.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/cannedmessages.pb.h @@ -11,30 +11,37 @@ /* Struct definitions */ /* Canned message module configuration. */ -typedef struct _meshtastic_CannedMessageModuleConfig { +typedef struct _meshtastic_CannedMessageModuleConfig +{ /* Predefined messages for canned message module separated by '|' characters. */ char messages[201]; } meshtastic_CannedMessageModuleConfig; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Initializer values for message structs */ -#define meshtastic_CannedMessageModuleConfig_init_default {""} -#define meshtastic_CannedMessageModuleConfig_init_zero {""} +#define meshtastic_CannedMessageModuleConfig_init_default \ + { \ + "" \ + } +#define meshtastic_CannedMessageModuleConfig_init_zero \ + { \ + "" \ + } /* Field tags (for use in manual encoding/decoding) */ #define meshtastic_CannedMessageModuleConfig_messages_tag 1 /* Struct field encoding specification for nanopb */ #define meshtastic_CannedMessageModuleConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, messages, 1) + X(a, STATIC, SINGULAR, STRING, messages, 1) #define meshtastic_CannedMessageModuleConfig_CALLBACK NULL #define meshtastic_CannedMessageModuleConfig_DEFAULT NULL -extern const pb_msgdesc_t meshtastic_CannedMessageModuleConfig_msg; + extern const pb_msgdesc_t meshtastic_CannedMessageModuleConfig_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_CannedMessageModuleConfig_fields &meshtastic_CannedMessageModuleConfig_msg diff --git a/src/chat/infra/meshtastic/generated/meshtastic/channel.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/channel.pb.cpp index 6670a40f..b4c3034c 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/channel.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/channel.pb.cpp @@ -8,13 +8,6 @@ PB_BIND(meshtastic_ChannelSettings, meshtastic_ChannelSettings, AUTO) - PB_BIND(meshtastic_ModuleSettings, meshtastic_ModuleSettings, AUTO) - PB_BIND(meshtastic_Channel, meshtastic_Channel, AUTO) - - - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/channel.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/channel.pb.h index 9dc757ab..92b02433 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/channel.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/channel.pb.h @@ -19,7 +19,8 @@ cross band routing as needed. If a device has only a single radio (the common case) only one channel can be PRIMARY at a time (but any number of SECONDARY channels can't be sent received on that common frequency) */ -typedef enum _meshtastic_Channel_Role { +typedef enum _meshtastic_Channel_Role +{ /* This channel is not in use right now */ meshtastic_Channel_Role_DISABLED = 0, /* This channel is used to set the frequency for the radio - all other enabled channels must be SECONDARY */ @@ -31,7 +32,8 @@ typedef enum _meshtastic_Channel_Role { /* Struct definitions */ /* This message is specifically for modules to store per-channel configuration data. */ -typedef struct _meshtastic_ModuleSettings { +typedef struct _meshtastic_ModuleSettings +{ /* Bits of precision for the location sent in position packets. */ uint32_t position_precision; /* Controls whether or not the client / device should mute the current channel @@ -55,7 +57,8 @@ typedef PB_BYTES_ARRAY_T(32) meshtastic_ChannelSettings_psk_t; FIXME: Add description of multi-channel support and how primary vs secondary channels are used. FIXME: explain how apps use channels for security. explain how remote settings and remote gpio are managed as an example */ -typedef struct _meshtastic_ChannelSettings { +typedef struct _meshtastic_ChannelSettings +{ /* Deprecated in favor of LoraConfig.channel_num */ uint32_t channel_num; /* A simple pre-shared key for now for crypto. @@ -100,7 +103,8 @@ typedef struct _meshtastic_ChannelSettings { } meshtastic_ChannelSettings; /* A pair of a channel number, mode and the (sharable) settings for that channel */ -typedef struct _meshtastic_Channel { +typedef struct _meshtastic_Channel +{ /* The index of this channel in the channel table (from 0 to MAX_NUM_CHANNELS-1) (Someday - not currently implemented) An index of -1 could be used to mean "set by name", in which case the target node will find and set the channel by settings.name. */ @@ -112,73 +116,88 @@ typedef struct _meshtastic_Channel { meshtastic_Channel_Role role; } meshtastic_Channel; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Helper constants for enums */ #define _meshtastic_Channel_Role_MIN meshtastic_Channel_Role_DISABLED #define _meshtastic_Channel_Role_MAX meshtastic_Channel_Role_SECONDARY -#define _meshtastic_Channel_Role_ARRAYSIZE ((meshtastic_Channel_Role)(meshtastic_Channel_Role_SECONDARY+1)) - - +#define _meshtastic_Channel_Role_ARRAYSIZE ((meshtastic_Channel_Role)(meshtastic_Channel_Role_SECONDARY + 1)) #define meshtastic_Channel_role_ENUMTYPE meshtastic_Channel_Role - /* Initializer values for message structs */ -#define meshtastic_ChannelSettings_init_default {0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_default} -#define meshtastic_ModuleSettings_init_default {0, 0} -#define meshtastic_Channel_init_default {0, false, meshtastic_ChannelSettings_init_default, _meshtastic_Channel_Role_MIN} -#define meshtastic_ChannelSettings_init_zero {0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_zero} -#define meshtastic_ModuleSettings_init_zero {0, 0} -#define meshtastic_Channel_init_zero {0, false, meshtastic_ChannelSettings_init_zero, _meshtastic_Channel_Role_MIN} +#define meshtastic_ChannelSettings_init_default \ + { \ + 0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_default \ + } +#define meshtastic_ModuleSettings_init_default \ + { \ + 0, 0 \ + } +#define meshtastic_Channel_init_default \ + { \ + 0, false, meshtastic_ChannelSettings_init_default, _meshtastic_Channel_Role_MIN \ + } +#define meshtastic_ChannelSettings_init_zero \ + { \ + 0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_zero \ + } +#define meshtastic_ModuleSettings_init_zero \ + { \ + 0, 0 \ + } +#define meshtastic_Channel_init_zero \ + { \ + 0, false, meshtastic_ChannelSettings_init_zero, _meshtastic_Channel_Role_MIN \ + } /* Field tags (for use in manual encoding/decoding) */ #define meshtastic_ModuleSettings_position_precision_tag 1 -#define meshtastic_ModuleSettings_is_muted_tag 2 +#define meshtastic_ModuleSettings_is_muted_tag 2 #define meshtastic_ChannelSettings_channel_num_tag 1 -#define meshtastic_ChannelSettings_psk_tag 2 -#define meshtastic_ChannelSettings_name_tag 3 -#define meshtastic_ChannelSettings_id_tag 4 +#define meshtastic_ChannelSettings_psk_tag 2 +#define meshtastic_ChannelSettings_name_tag 3 +#define meshtastic_ChannelSettings_id_tag 4 #define meshtastic_ChannelSettings_uplink_enabled_tag 5 #define meshtastic_ChannelSettings_downlink_enabled_tag 6 #define meshtastic_ChannelSettings_module_settings_tag 7 -#define meshtastic_Channel_index_tag 1 -#define meshtastic_Channel_settings_tag 2 -#define meshtastic_Channel_role_tag 3 +#define meshtastic_Channel_index_tag 1 +#define meshtastic_Channel_settings_tag 2 +#define meshtastic_Channel_role_tag 3 /* Struct field encoding specification for nanopb */ -#define meshtastic_ChannelSettings_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, channel_num, 1) \ -X(a, STATIC, SINGULAR, BYTES, psk, 2) \ -X(a, STATIC, SINGULAR, STRING, name, 3) \ -X(a, STATIC, SINGULAR, FIXED32, id, 4) \ -X(a, STATIC, SINGULAR, BOOL, uplink_enabled, 5) \ -X(a, STATIC, SINGULAR, BOOL, downlink_enabled, 6) \ -X(a, STATIC, OPTIONAL, MESSAGE, module_settings, 7) +#define meshtastic_ChannelSettings_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UINT32, channel_num, 1) \ + X(a, STATIC, SINGULAR, BYTES, psk, 2) \ + X(a, STATIC, SINGULAR, STRING, name, 3) \ + X(a, STATIC, SINGULAR, FIXED32, id, 4) \ + X(a, STATIC, SINGULAR, BOOL, uplink_enabled, 5) \ + X(a, STATIC, SINGULAR, BOOL, downlink_enabled, 6) \ + X(a, STATIC, OPTIONAL, MESSAGE, module_settings, 7) #define meshtastic_ChannelSettings_CALLBACK NULL #define meshtastic_ChannelSettings_DEFAULT NULL #define meshtastic_ChannelSettings_module_settings_MSGTYPE meshtastic_ModuleSettings -#define meshtastic_ModuleSettings_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, position_precision, 1) \ -X(a, STATIC, SINGULAR, BOOL, is_muted, 2) +#define meshtastic_ModuleSettings_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UINT32, position_precision, 1) \ + X(a, STATIC, SINGULAR, BOOL, is_muted, 2) #define meshtastic_ModuleSettings_CALLBACK NULL #define meshtastic_ModuleSettings_DEFAULT NULL -#define meshtastic_Channel_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, INT32, index, 1) \ -X(a, STATIC, OPTIONAL, MESSAGE, settings, 2) \ -X(a, STATIC, SINGULAR, UENUM, role, 3) +#define meshtastic_Channel_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, INT32, index, 1) \ + X(a, STATIC, OPTIONAL, MESSAGE, settings, 2) \ + X(a, STATIC, SINGULAR, UENUM, role, 3) #define meshtastic_Channel_CALLBACK NULL #define meshtastic_Channel_DEFAULT NULL #define meshtastic_Channel_settings_MSGTYPE meshtastic_ChannelSettings -extern const pb_msgdesc_t meshtastic_ChannelSettings_msg; -extern const pb_msgdesc_t meshtastic_ModuleSettings_msg; -extern const pb_msgdesc_t meshtastic_Channel_msg; + extern const pb_msgdesc_t meshtastic_ChannelSettings_msg; + extern const pb_msgdesc_t meshtastic_ModuleSettings_msg; + extern const pb_msgdesc_t meshtastic_Channel_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_ChannelSettings_fields &meshtastic_ChannelSettings_msg @@ -187,9 +206,9 @@ extern const pb_msgdesc_t meshtastic_Channel_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_CHANNEL_PB_H_MAX_SIZE meshtastic_Channel_size -#define meshtastic_ChannelSettings_size 72 -#define meshtastic_Channel_size 87 -#define meshtastic_ModuleSettings_size 8 +#define meshtastic_ChannelSettings_size 72 +#define meshtastic_Channel_size 87 +#define meshtastic_ModuleSettings_size 8 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/clientonly.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/clientonly.pb.cpp index 8f380a97..e0dfb521 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/clientonly.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/clientonly.pb.cpp @@ -7,6 +7,3 @@ #endif PB_BIND(meshtastic_DeviceProfile, meshtastic_DeviceProfile, 2) - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/clientonly.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/clientonly.pb.h index 5109e20b..aa62c9b6 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/clientonly.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/clientonly.pb.h @@ -3,9 +3,9 @@ #ifndef PB_MESHTASTIC_MESHTASTIC_CLIENTONLY_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_CLIENTONLY_PB_H_INCLUDED -#include #include "meshtastic/localonly.pb.h" #include "meshtastic/mesh.pb.h" +#include #if PB_PROTO_HEADER_VERSION != 40 #error Regenerate this file with the current version of nanopb generator. @@ -14,7 +14,8 @@ /* Struct definitions */ /* This abstraction is used to contain any configuration for provisioning a node on any client. It is useful for importing and exporting configurations. */ -typedef struct _meshtastic_DeviceProfile { +typedef struct _meshtastic_DeviceProfile +{ /* Long name for the node */ bool has_long_name; char long_name[40]; @@ -40,48 +41,54 @@ typedef struct _meshtastic_DeviceProfile { char canned_messages[201]; } meshtastic_DeviceProfile; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Initializer values for message structs */ -#define meshtastic_DeviceProfile_init_default {false, "", false, "", {{NULL}, NULL}, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default, false, meshtastic_Position_init_default, false, "", false, ""} -#define meshtastic_DeviceProfile_init_zero {false, "", false, "", {{NULL}, NULL}, false, meshtastic_LocalConfig_init_zero, false, meshtastic_LocalModuleConfig_init_zero, false, meshtastic_Position_init_zero, false, "", false, ""} +#define meshtastic_DeviceProfile_init_default \ + { \ + false, "", false, "", {{NULL}, NULL}, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default, false, meshtastic_Position_init_default, false, "", false, "" \ + } +#define meshtastic_DeviceProfile_init_zero \ + { \ + false, "", false, "", {{NULL}, NULL}, false, meshtastic_LocalConfig_init_zero, false, meshtastic_LocalModuleConfig_init_zero, false, meshtastic_Position_init_zero, false, "", false, "" \ + } /* Field tags (for use in manual encoding/decoding) */ -#define meshtastic_DeviceProfile_long_name_tag 1 -#define meshtastic_DeviceProfile_short_name_tag 2 +#define meshtastic_DeviceProfile_long_name_tag 1 +#define meshtastic_DeviceProfile_short_name_tag 2 #define meshtastic_DeviceProfile_channel_url_tag 3 -#define meshtastic_DeviceProfile_config_tag 4 +#define meshtastic_DeviceProfile_config_tag 4 #define meshtastic_DeviceProfile_module_config_tag 5 #define meshtastic_DeviceProfile_fixed_position_tag 6 -#define meshtastic_DeviceProfile_ringtone_tag 7 +#define meshtastic_DeviceProfile_ringtone_tag 7 #define meshtastic_DeviceProfile_canned_messages_tag 8 /* Struct field encoding specification for nanopb */ -#define meshtastic_DeviceProfile_FIELDLIST(X, a) \ -X(a, STATIC, OPTIONAL, STRING, long_name, 1) \ -X(a, STATIC, OPTIONAL, STRING, short_name, 2) \ -X(a, CALLBACK, OPTIONAL, STRING, channel_url, 3) \ -X(a, STATIC, OPTIONAL, MESSAGE, config, 4) \ -X(a, STATIC, OPTIONAL, MESSAGE, module_config, 5) \ -X(a, STATIC, OPTIONAL, MESSAGE, fixed_position, 6) \ -X(a, STATIC, OPTIONAL, STRING, ringtone, 7) \ -X(a, STATIC, OPTIONAL, STRING, canned_messages, 8) +#define meshtastic_DeviceProfile_FIELDLIST(X, a) \ + X(a, STATIC, OPTIONAL, STRING, long_name, 1) \ + X(a, STATIC, OPTIONAL, STRING, short_name, 2) \ + X(a, CALLBACK, OPTIONAL, STRING, channel_url, 3) \ + X(a, STATIC, OPTIONAL, MESSAGE, config, 4) \ + X(a, STATIC, OPTIONAL, MESSAGE, module_config, 5) \ + X(a, STATIC, OPTIONAL, MESSAGE, fixed_position, 6) \ + X(a, STATIC, OPTIONAL, STRING, ringtone, 7) \ + X(a, STATIC, OPTIONAL, STRING, canned_messages, 8) #define meshtastic_DeviceProfile_CALLBACK pb_default_field_callback #define meshtastic_DeviceProfile_DEFAULT NULL #define meshtastic_DeviceProfile_config_MSGTYPE meshtastic_LocalConfig #define meshtastic_DeviceProfile_module_config_MSGTYPE meshtastic_LocalModuleConfig #define meshtastic_DeviceProfile_fixed_position_MSGTYPE meshtastic_Position -extern const pb_msgdesc_t meshtastic_DeviceProfile_msg; + extern const pb_msgdesc_t meshtastic_DeviceProfile_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_DeviceProfile_fields &meshtastic_DeviceProfile_msg -/* Maximum encoded size of messages (where known) */ -/* meshtastic_DeviceProfile_size depends on runtime parameters */ + /* Maximum encoded size of messages (where known) */ + /* meshtastic_DeviceProfile_size depends on runtime parameters */ #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/config.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/config.pb.cpp index 52a591f3..343da779 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/config.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/config.pb.cpp @@ -8,65 +8,22 @@ PB_BIND(meshtastic_Config, meshtastic_Config, AUTO) - PB_BIND(meshtastic_Config_DeviceConfig, meshtastic_Config_DeviceConfig, AUTO) - PB_BIND(meshtastic_Config_PositionConfig, meshtastic_Config_PositionConfig, AUTO) - PB_BIND(meshtastic_Config_PowerConfig, meshtastic_Config_PowerConfig, AUTO) - PB_BIND(meshtastic_Config_NetworkConfig, meshtastic_Config_NetworkConfig, AUTO) - PB_BIND(meshtastic_Config_NetworkConfig_IpV4Config, meshtastic_Config_NetworkConfig_IpV4Config, AUTO) - PB_BIND(meshtastic_Config_DisplayConfig, meshtastic_Config_DisplayConfig, AUTO) - PB_BIND(meshtastic_Config_LoRaConfig, meshtastic_Config_LoRaConfig, 2) - PB_BIND(meshtastic_Config_BluetoothConfig, meshtastic_Config_BluetoothConfig, AUTO) - PB_BIND(meshtastic_Config_SecurityConfig, meshtastic_Config_SecurityConfig, AUTO) - PB_BIND(meshtastic_Config_SessionkeyConfig, meshtastic_Config_SessionkeyConfig, AUTO) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/config.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/config.pb.h index 32756831..b3c8d9be 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/config.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/config.pb.h @@ -3,8 +3,8 @@ #ifndef PB_MESHTASTIC_MESHTASTIC_CONFIG_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_CONFIG_PB_H_INCLUDED -#include #include "meshtastic/device_ui.pb.h" +#include #if PB_PROTO_HEADER_VERSION != 40 #error Regenerate this file with the current version of nanopb generator. @@ -12,7 +12,8 @@ /* Enum definitions */ /* Defines the device's role on the Mesh network */ -typedef enum _meshtastic_Config_DeviceConfig_Role { +typedef enum _meshtastic_Config_DeviceConfig_Role +{ /* Description: App connected or stand alone messaging device. Technical Details: Default Role */ meshtastic_Config_DeviceConfig_Role_CLIENT = 0, @@ -74,7 +75,8 @@ typedef enum _meshtastic_Config_DeviceConfig_Role { } meshtastic_Config_DeviceConfig_Role; /* Defines the device's behavior for how messages are rebroadcast */ -typedef enum _meshtastic_Config_DeviceConfig_RebroadcastMode { +typedef enum _meshtastic_Config_DeviceConfig_RebroadcastMode +{ /* Default behavior. Rebroadcast any observed message, if it was on our private channel or from another mesh with the same lora params. */ meshtastic_Config_DeviceConfig_RebroadcastMode_ALL = 0, @@ -95,7 +97,8 @@ typedef enum _meshtastic_Config_DeviceConfig_RebroadcastMode { } meshtastic_Config_DeviceConfig_RebroadcastMode; /* Defines buzzer behavior for audio feedback */ -typedef enum _meshtastic_Config_DeviceConfig_BuzzerMode { +typedef enum _meshtastic_Config_DeviceConfig_BuzzerMode +{ /* Default behavior. Buzzer is enabled for all audio feedback including button presses and alerts. */ meshtastic_Config_DeviceConfig_BuzzerMode_ALL_ENABLED = 0, @@ -121,7 +124,8 @@ typedef enum _meshtastic_Config_DeviceConfig_BuzzerMode { are always included (also time if GPS-synced) NOTE: the more fields are included, the larger the message will be - leading to longer airtime and a higher risk of packet loss */ -typedef enum _meshtastic_Config_PositionConfig_PositionFlags { +typedef enum _meshtastic_Config_PositionConfig_PositionFlags +{ /* Required for compilation */ meshtastic_Config_PositionConfig_PositionFlags_UNSET = 0, /* Include an altitude value (if available) */ @@ -150,7 +154,8 @@ typedef enum _meshtastic_Config_PositionConfig_PositionFlags { meshtastic_Config_PositionConfig_PositionFlags_SPEED = 512 } meshtastic_Config_PositionConfig_PositionFlags; -typedef enum _meshtastic_Config_PositionConfig_GpsMode { +typedef enum _meshtastic_Config_PositionConfig_GpsMode +{ /* GPS is present but disabled */ meshtastic_Config_PositionConfig_GpsMode_DISABLED = 0, /* GPS is present and enabled */ @@ -159,7 +164,8 @@ typedef enum _meshtastic_Config_PositionConfig_GpsMode { meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT = 2 } meshtastic_Config_PositionConfig_GpsMode; -typedef enum _meshtastic_Config_NetworkConfig_AddressMode { +typedef enum _meshtastic_Config_NetworkConfig_AddressMode +{ /* obtain ip address via DHCP */ meshtastic_Config_NetworkConfig_AddressMode_DHCP = 0, /* use static ip address */ @@ -167,7 +173,8 @@ typedef enum _meshtastic_Config_NetworkConfig_AddressMode { } meshtastic_Config_NetworkConfig_AddressMode; /* Available flags auxiliary network protocols */ -typedef enum _meshtastic_Config_NetworkConfig_ProtocolFlags { +typedef enum _meshtastic_Config_NetworkConfig_ProtocolFlags +{ /* Do not broadcast packets over any network protocol */ meshtastic_Config_NetworkConfig_ProtocolFlags_NO_BROADCAST = 0, /* Enable broadcasting packets via UDP over the local network */ @@ -175,12 +182,14 @@ typedef enum _meshtastic_Config_NetworkConfig_ProtocolFlags { } meshtastic_Config_NetworkConfig_ProtocolFlags; /* Deprecated in 2.7.4: Unused */ -typedef enum _meshtastic_Config_DisplayConfig_DeprecatedGpsCoordinateFormat { +typedef enum _meshtastic_Config_DisplayConfig_DeprecatedGpsCoordinateFormat +{ meshtastic_Config_DisplayConfig_DeprecatedGpsCoordinateFormat_UNUSED = 0 } meshtastic_Config_DisplayConfig_DeprecatedGpsCoordinateFormat; /* Unit display preference */ -typedef enum _meshtastic_Config_DisplayConfig_DisplayUnits { +typedef enum _meshtastic_Config_DisplayConfig_DisplayUnits +{ /* Metric (Default) */ meshtastic_Config_DisplayConfig_DisplayUnits_METRIC = 0, /* Imperial */ @@ -188,7 +197,8 @@ typedef enum _meshtastic_Config_DisplayConfig_DisplayUnits { } meshtastic_Config_DisplayConfig_DisplayUnits; /* Override OLED outo detect with this if it fails. */ -typedef enum _meshtastic_Config_DisplayConfig_OledType { +typedef enum _meshtastic_Config_DisplayConfig_OledType +{ /* Default / Autodetect */ meshtastic_Config_DisplayConfig_OledType_OLED_AUTO = 0, /* Default / Autodetect */ @@ -201,7 +211,8 @@ typedef enum _meshtastic_Config_DisplayConfig_OledType { meshtastic_Config_DisplayConfig_OledType_OLED_SH1107_128_128 = 4 } meshtastic_Config_DisplayConfig_OledType; -typedef enum _meshtastic_Config_DisplayConfig_DisplayMode { +typedef enum _meshtastic_Config_DisplayConfig_DisplayMode +{ /* Default. The old style for the 128x64 OLED screen */ meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT = 0, /* Rearrange display elements to cater for bicolor OLED displays */ @@ -212,7 +223,8 @@ typedef enum _meshtastic_Config_DisplayConfig_DisplayMode { meshtastic_Config_DisplayConfig_DisplayMode_COLOR = 3 } meshtastic_Config_DisplayConfig_DisplayMode; -typedef enum _meshtastic_Config_DisplayConfig_CompassOrientation { +typedef enum _meshtastic_Config_DisplayConfig_CompassOrientation +{ /* The compass and the display are in the same orientation. */ meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_0 = 0, /* Rotate the compass by 90 degrees. */ @@ -231,7 +243,8 @@ typedef enum _meshtastic_Config_DisplayConfig_CompassOrientation { meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270_INVERTED = 7 } meshtastic_Config_DisplayConfig_CompassOrientation; -typedef enum _meshtastic_Config_LoRaConfig_RegionCode { +typedef enum _meshtastic_Config_LoRaConfig_RegionCode +{ /* Region is not set */ meshtastic_Config_LoRaConfig_RegionCode_UNSET = 0, /* United States */ @@ -290,7 +303,8 @@ typedef enum _meshtastic_Config_LoRaConfig_RegionCode { /* Standard predefined channel settings Note: these mappings must match ModemPreset Choice in the device code. */ -typedef enum _meshtastic_Config_LoRaConfig_ModemPreset { +typedef enum _meshtastic_Config_LoRaConfig_ModemPreset +{ /* Long Range - Fast */ meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST = 0, /* Long Range - Slow */ @@ -314,7 +328,8 @@ typedef enum _meshtastic_Config_LoRaConfig_ModemPreset { meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO = 8 } meshtastic_Config_LoRaConfig_ModemPreset; -typedef enum _meshtastic_Config_BluetoothConfig_PairingMode { +typedef enum _meshtastic_Config_BluetoothConfig_PairingMode +{ /* Device generates a random PIN that will be shown on the screen of the device for pairing */ meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN = 0, /* Device requires a specified fixed PIN for pairing */ @@ -325,7 +340,8 @@ typedef enum _meshtastic_Config_BluetoothConfig_PairingMode { /* Struct definitions */ /* Configuration */ -typedef struct _meshtastic_Config_DeviceConfig { +typedef struct _meshtastic_Config_DeviceConfig +{ /* Sets the role of node */ meshtastic_Config_DeviceConfig_Role role; /* Disabling this will disable the SerialConsole by not initilizing the StreamAPI @@ -360,7 +376,8 @@ typedef struct _meshtastic_Config_DeviceConfig { } meshtastic_Config_DeviceConfig; /* Position Config */ -typedef struct _meshtastic_Config_PositionConfig { +typedef struct _meshtastic_Config_PositionConfig +{ /* We should send our position this often (but only if it has changed significantly) Defaults to 15 minutes */ uint32_t position_broadcast_secs; @@ -397,7 +414,8 @@ typedef struct _meshtastic_Config_PositionConfig { /* Power Config\ See [Power Config](/docs/settings/config/power) for additional power config details. */ -typedef struct _meshtastic_Config_PowerConfig { +typedef struct _meshtastic_Config_PowerConfig +{ /* Description: Will sleep everything as much as possible, for the tracker and sensor role this will also include the lora radio. Don't use this setting if you want to use your device with the phone apps or are using a device without a user button. Technical Details: Works for ESP32 devices and NRF52 devices in the Sensor or Tracker roles */ @@ -430,7 +448,8 @@ typedef struct _meshtastic_Config_PowerConfig { uint64_t powermon_enables; } meshtastic_Config_PowerConfig; -typedef struct _meshtastic_Config_NetworkConfig_IpV4Config { +typedef struct _meshtastic_Config_NetworkConfig_IpV4Config +{ /* Static IP address */ uint32_t ip; /* Static gateway address */ @@ -442,7 +461,8 @@ typedef struct _meshtastic_Config_NetworkConfig_IpV4Config { } meshtastic_Config_NetworkConfig_IpV4Config; /* Network Config */ -typedef struct _meshtastic_Config_NetworkConfig { +typedef struct _meshtastic_Config_NetworkConfig +{ /* Enable WiFi (disables Bluetooth) */ bool wifi_enabled; /* If set, this node will try to join the specified wifi network and @@ -468,7 +488,8 @@ typedef struct _meshtastic_Config_NetworkConfig { } meshtastic_Config_NetworkConfig; /* Display Config */ -typedef struct _meshtastic_Config_DisplayConfig { +typedef struct _meshtastic_Config_DisplayConfig +{ /* Number of seconds the screen stays on after pressing the user button or receiving a message 0 for default of one minute MAXUINT for always on */ uint32_t screen_on_secs; @@ -504,7 +525,8 @@ typedef struct _meshtastic_Config_DisplayConfig { } meshtastic_Config_DisplayConfig; /* Lora Config */ -typedef struct _meshtastic_Config_LoRaConfig { +typedef struct _meshtastic_Config_LoRaConfig +{ /* When enabled, the `modem_preset` fields will be adhered to, else the `bandwidth`/`spread_factor`/`coding_rate` will be taked from their respective manually defined fields */ bool use_preset; @@ -575,7 +597,8 @@ typedef struct _meshtastic_Config_LoRaConfig { bool config_ok_to_mqtt; } meshtastic_Config_LoRaConfig; -typedef struct _meshtastic_Config_BluetoothConfig { +typedef struct _meshtastic_Config_BluetoothConfig +{ /* Enable Bluetooth on the device */ bool enabled; /* Determines the pairing strategy for the device */ @@ -587,7 +610,8 @@ typedef struct _meshtastic_Config_BluetoothConfig { typedef PB_BYTES_ARRAY_T(32) meshtastic_Config_SecurityConfig_public_key_t; typedef PB_BYTES_ARRAY_T(32) meshtastic_Config_SecurityConfig_private_key_t; typedef PB_BYTES_ARRAY_T(32) meshtastic_Config_SecurityConfig_admin_key_t; -typedef struct _meshtastic_Config_SecurityConfig { +typedef struct _meshtastic_Config_SecurityConfig +{ /* The public key of the user's device. Sent out to other nodes on the mesh to allow them to compute a shared secret key. */ meshtastic_Config_SecurityConfig_public_key_t public_key; @@ -610,13 +634,16 @@ typedef struct _meshtastic_Config_SecurityConfig { } meshtastic_Config_SecurityConfig; /* Blank config request, strictly for getting the session key */ -typedef struct _meshtastic_Config_SessionkeyConfig { +typedef struct _meshtastic_Config_SessionkeyConfig +{ char dummy_field; } meshtastic_Config_SessionkeyConfig; -typedef struct _meshtastic_Config { +typedef struct _meshtastic_Config +{ pb_size_t which_payload_variant; - union { + union + { meshtastic_Config_DeviceConfig device; meshtastic_Config_PositionConfig position; meshtastic_Config_PowerConfig power; @@ -630,72 +657,71 @@ typedef struct _meshtastic_Config { } payload_variant; } meshtastic_Config; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Helper constants for enums */ #define _meshtastic_Config_DeviceConfig_Role_MIN meshtastic_Config_DeviceConfig_Role_CLIENT #define _meshtastic_Config_DeviceConfig_Role_MAX meshtastic_Config_DeviceConfig_Role_CLIENT_BASE -#define _meshtastic_Config_DeviceConfig_Role_ARRAYSIZE ((meshtastic_Config_DeviceConfig_Role)(meshtastic_Config_DeviceConfig_Role_CLIENT_BASE+1)) +#define _meshtastic_Config_DeviceConfig_Role_ARRAYSIZE ((meshtastic_Config_DeviceConfig_Role)(meshtastic_Config_DeviceConfig_Role_CLIENT_BASE + 1)) #define _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN meshtastic_Config_DeviceConfig_RebroadcastMode_ALL #define _meshtastic_Config_DeviceConfig_RebroadcastMode_MAX meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY -#define _meshtastic_Config_DeviceConfig_RebroadcastMode_ARRAYSIZE ((meshtastic_Config_DeviceConfig_RebroadcastMode)(meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY+1)) +#define _meshtastic_Config_DeviceConfig_RebroadcastMode_ARRAYSIZE ((meshtastic_Config_DeviceConfig_RebroadcastMode)(meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY + 1)) #define _meshtastic_Config_DeviceConfig_BuzzerMode_MIN meshtastic_Config_DeviceConfig_BuzzerMode_ALL_ENABLED #define _meshtastic_Config_DeviceConfig_BuzzerMode_MAX meshtastic_Config_DeviceConfig_BuzzerMode_DIRECT_MSG_ONLY -#define _meshtastic_Config_DeviceConfig_BuzzerMode_ARRAYSIZE ((meshtastic_Config_DeviceConfig_BuzzerMode)(meshtastic_Config_DeviceConfig_BuzzerMode_DIRECT_MSG_ONLY+1)) +#define _meshtastic_Config_DeviceConfig_BuzzerMode_ARRAYSIZE ((meshtastic_Config_DeviceConfig_BuzzerMode)(meshtastic_Config_DeviceConfig_BuzzerMode_DIRECT_MSG_ONLY + 1)) #define _meshtastic_Config_PositionConfig_PositionFlags_MIN meshtastic_Config_PositionConfig_PositionFlags_UNSET #define _meshtastic_Config_PositionConfig_PositionFlags_MAX meshtastic_Config_PositionConfig_PositionFlags_SPEED -#define _meshtastic_Config_PositionConfig_PositionFlags_ARRAYSIZE ((meshtastic_Config_PositionConfig_PositionFlags)(meshtastic_Config_PositionConfig_PositionFlags_SPEED+1)) +#define _meshtastic_Config_PositionConfig_PositionFlags_ARRAYSIZE ((meshtastic_Config_PositionConfig_PositionFlags)(meshtastic_Config_PositionConfig_PositionFlags_SPEED + 1)) #define _meshtastic_Config_PositionConfig_GpsMode_MIN meshtastic_Config_PositionConfig_GpsMode_DISABLED #define _meshtastic_Config_PositionConfig_GpsMode_MAX meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT -#define _meshtastic_Config_PositionConfig_GpsMode_ARRAYSIZE ((meshtastic_Config_PositionConfig_GpsMode)(meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT+1)) +#define _meshtastic_Config_PositionConfig_GpsMode_ARRAYSIZE ((meshtastic_Config_PositionConfig_GpsMode)(meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT + 1)) #define _meshtastic_Config_NetworkConfig_AddressMode_MIN meshtastic_Config_NetworkConfig_AddressMode_DHCP #define _meshtastic_Config_NetworkConfig_AddressMode_MAX meshtastic_Config_NetworkConfig_AddressMode_STATIC -#define _meshtastic_Config_NetworkConfig_AddressMode_ARRAYSIZE ((meshtastic_Config_NetworkConfig_AddressMode)(meshtastic_Config_NetworkConfig_AddressMode_STATIC+1)) +#define _meshtastic_Config_NetworkConfig_AddressMode_ARRAYSIZE ((meshtastic_Config_NetworkConfig_AddressMode)(meshtastic_Config_NetworkConfig_AddressMode_STATIC + 1)) #define _meshtastic_Config_NetworkConfig_ProtocolFlags_MIN meshtastic_Config_NetworkConfig_ProtocolFlags_NO_BROADCAST #define _meshtastic_Config_NetworkConfig_ProtocolFlags_MAX meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST -#define _meshtastic_Config_NetworkConfig_ProtocolFlags_ARRAYSIZE ((meshtastic_Config_NetworkConfig_ProtocolFlags)(meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST+1)) +#define _meshtastic_Config_NetworkConfig_ProtocolFlags_ARRAYSIZE ((meshtastic_Config_NetworkConfig_ProtocolFlags)(meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST + 1)) #define _meshtastic_Config_DisplayConfig_DeprecatedGpsCoordinateFormat_MIN meshtastic_Config_DisplayConfig_DeprecatedGpsCoordinateFormat_UNUSED #define _meshtastic_Config_DisplayConfig_DeprecatedGpsCoordinateFormat_MAX meshtastic_Config_DisplayConfig_DeprecatedGpsCoordinateFormat_UNUSED -#define _meshtastic_Config_DisplayConfig_DeprecatedGpsCoordinateFormat_ARRAYSIZE ((meshtastic_Config_DisplayConfig_DeprecatedGpsCoordinateFormat)(meshtastic_Config_DisplayConfig_DeprecatedGpsCoordinateFormat_UNUSED+1)) +#define _meshtastic_Config_DisplayConfig_DeprecatedGpsCoordinateFormat_ARRAYSIZE ((meshtastic_Config_DisplayConfig_DeprecatedGpsCoordinateFormat)(meshtastic_Config_DisplayConfig_DeprecatedGpsCoordinateFormat_UNUSED + 1)) #define _meshtastic_Config_DisplayConfig_DisplayUnits_MIN meshtastic_Config_DisplayConfig_DisplayUnits_METRIC #define _meshtastic_Config_DisplayConfig_DisplayUnits_MAX meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL -#define _meshtastic_Config_DisplayConfig_DisplayUnits_ARRAYSIZE ((meshtastic_Config_DisplayConfig_DisplayUnits)(meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL+1)) +#define _meshtastic_Config_DisplayConfig_DisplayUnits_ARRAYSIZE ((meshtastic_Config_DisplayConfig_DisplayUnits)(meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL + 1)) #define _meshtastic_Config_DisplayConfig_OledType_MIN meshtastic_Config_DisplayConfig_OledType_OLED_AUTO #define _meshtastic_Config_DisplayConfig_OledType_MAX meshtastic_Config_DisplayConfig_OledType_OLED_SH1107_128_128 -#define _meshtastic_Config_DisplayConfig_OledType_ARRAYSIZE ((meshtastic_Config_DisplayConfig_OledType)(meshtastic_Config_DisplayConfig_OledType_OLED_SH1107_128_128+1)) +#define _meshtastic_Config_DisplayConfig_OledType_ARRAYSIZE ((meshtastic_Config_DisplayConfig_OledType)(meshtastic_Config_DisplayConfig_OledType_OLED_SH1107_128_128 + 1)) #define _meshtastic_Config_DisplayConfig_DisplayMode_MIN meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT #define _meshtastic_Config_DisplayConfig_DisplayMode_MAX meshtastic_Config_DisplayConfig_DisplayMode_COLOR -#define _meshtastic_Config_DisplayConfig_DisplayMode_ARRAYSIZE ((meshtastic_Config_DisplayConfig_DisplayMode)(meshtastic_Config_DisplayConfig_DisplayMode_COLOR+1)) +#define _meshtastic_Config_DisplayConfig_DisplayMode_ARRAYSIZE ((meshtastic_Config_DisplayConfig_DisplayMode)(meshtastic_Config_DisplayConfig_DisplayMode_COLOR + 1)) #define _meshtastic_Config_DisplayConfig_CompassOrientation_MIN meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_0 #define _meshtastic_Config_DisplayConfig_CompassOrientation_MAX meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270_INVERTED -#define _meshtastic_Config_DisplayConfig_CompassOrientation_ARRAYSIZE ((meshtastic_Config_DisplayConfig_CompassOrientation)(meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270_INVERTED+1)) +#define _meshtastic_Config_DisplayConfig_CompassOrientation_ARRAYSIZE ((meshtastic_Config_DisplayConfig_CompassOrientation)(meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270_INVERTED + 1)) #define _meshtastic_Config_LoRaConfig_RegionCode_MIN meshtastic_Config_LoRaConfig_RegionCode_UNSET #define _meshtastic_Config_LoRaConfig_RegionCode_MAX meshtastic_Config_LoRaConfig_RegionCode_BR_902 -#define _meshtastic_Config_LoRaConfig_RegionCode_ARRAYSIZE ((meshtastic_Config_LoRaConfig_RegionCode)(meshtastic_Config_LoRaConfig_RegionCode_BR_902+1)) +#define _meshtastic_Config_LoRaConfig_RegionCode_ARRAYSIZE ((meshtastic_Config_LoRaConfig_RegionCode)(meshtastic_Config_LoRaConfig_RegionCode_BR_902 + 1)) #define _meshtastic_Config_LoRaConfig_ModemPreset_MIN meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST #define _meshtastic_Config_LoRaConfig_ModemPreset_MAX meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO -#define _meshtastic_Config_LoRaConfig_ModemPreset_ARRAYSIZE ((meshtastic_Config_LoRaConfig_ModemPreset)(meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO+1)) +#define _meshtastic_Config_LoRaConfig_ModemPreset_ARRAYSIZE ((meshtastic_Config_LoRaConfig_ModemPreset)(meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO + 1)) #define _meshtastic_Config_BluetoothConfig_PairingMode_MIN meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN #define _meshtastic_Config_BluetoothConfig_PairingMode_MAX meshtastic_Config_BluetoothConfig_PairingMode_NO_PIN -#define _meshtastic_Config_BluetoothConfig_PairingMode_ARRAYSIZE ((meshtastic_Config_BluetoothConfig_PairingMode)(meshtastic_Config_BluetoothConfig_PairingMode_NO_PIN+1)) - +#define _meshtastic_Config_BluetoothConfig_PairingMode_ARRAYSIZE ((meshtastic_Config_BluetoothConfig_PairingMode)(meshtastic_Config_BluetoothConfig_PairingMode_NO_PIN + 1)) #define meshtastic_Config_DeviceConfig_role_ENUMTYPE meshtastic_Config_DeviceConfig_Role #define meshtastic_Config_DeviceConfig_rebroadcast_mode_ENUMTYPE meshtastic_Config_DeviceConfig_RebroadcastMode @@ -703,10 +729,8 @@ extern "C" { #define meshtastic_Config_PositionConfig_gps_mode_ENUMTYPE meshtastic_Config_PositionConfig_GpsMode - #define meshtastic_Config_NetworkConfig_address_mode_ENUMTYPE meshtastic_Config_NetworkConfig_AddressMode - #define meshtastic_Config_DisplayConfig_gps_format_ENUMTYPE meshtastic_Config_DisplayConfig_DeprecatedGpsCoordinateFormat #define meshtastic_Config_DisplayConfig_units_ENUMTYPE meshtastic_Config_DisplayConfig_DisplayUnits #define meshtastic_Config_DisplayConfig_oled_ENUMTYPE meshtastic_Config_DisplayConfig_OledType @@ -718,35 +742,98 @@ extern "C" { #define meshtastic_Config_BluetoothConfig_mode_ENUMTYPE meshtastic_Config_BluetoothConfig_PairingMode - - - /* Initializer values for message structs */ -#define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}} -#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0, _meshtastic_Config_DeviceConfig_BuzzerMode_MIN} -#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN} -#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0} -#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, "", 0, 0} -#define meshtastic_Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0} -#define meshtastic_Config_DisplayConfig_init_default {0, _meshtastic_Config_DisplayConfig_DeprecatedGpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN, 0, 0} -#define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0} -#define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0} -#define meshtastic_Config_SecurityConfig_init_default {{0, {0}}, {0, {0}}, 0, {{0, {0}}, {0, {0}}, {0, {0}}}, 0, 0, 0, 0} -#define meshtastic_Config_SessionkeyConfig_init_default {0} -#define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}} -#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0, _meshtastic_Config_DeviceConfig_BuzzerMode_MIN} -#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN} -#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0} -#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, "", 0, 0} -#define meshtastic_Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0} -#define meshtastic_Config_DisplayConfig_init_zero {0, _meshtastic_Config_DisplayConfig_DeprecatedGpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN, 0, 0} -#define meshtastic_Config_LoRaConfig_init_zero {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0} -#define meshtastic_Config_BluetoothConfig_init_zero {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0} -#define meshtastic_Config_SecurityConfig_init_zero {{0, {0}}, {0, {0}}, 0, {{0, {0}}, {0, {0}}, {0, {0}}}, 0, 0, 0, 0} -#define meshtastic_Config_SessionkeyConfig_init_zero {0} +#define meshtastic_Config_init_default \ + { \ + 0, { meshtastic_Config_DeviceConfig_init_default } \ + } +#define meshtastic_Config_DeviceConfig_init_default \ + { \ + _meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0, _meshtastic_Config_DeviceConfig_BuzzerMode_MIN \ + } +#define meshtastic_Config_PositionConfig_init_default \ + { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN \ + } +#define meshtastic_Config_PowerConfig_init_default \ + { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0 \ + } +#define meshtastic_Config_NetworkConfig_init_default \ + { \ + 0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, "", 0, 0 \ + } +#define meshtastic_Config_NetworkConfig_IpV4Config_init_default \ + { \ + 0, 0, 0, 0 \ + } +#define meshtastic_Config_DisplayConfig_init_default \ + { \ + 0, _meshtastic_Config_DisplayConfig_DeprecatedGpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN, 0, 0 \ + } +#define meshtastic_Config_LoRaConfig_init_default \ + { \ + 0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0 \ + } +#define meshtastic_Config_BluetoothConfig_init_default \ + { \ + 0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0 \ + } +#define meshtastic_Config_SecurityConfig_init_default \ + { \ + {0, {0}}, {0, {0}}, 0, {{0, {0}}, {0, {0}}, {0, {0}}}, 0, 0, 0, 0 \ + } +#define meshtastic_Config_SessionkeyConfig_init_default \ + { \ + 0 \ + } +#define meshtastic_Config_init_zero \ + { \ + 0, { meshtastic_Config_DeviceConfig_init_zero } \ + } +#define meshtastic_Config_DeviceConfig_init_zero \ + { \ + _meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0, _meshtastic_Config_DeviceConfig_BuzzerMode_MIN \ + } +#define meshtastic_Config_PositionConfig_init_zero \ + { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN \ + } +#define meshtastic_Config_PowerConfig_init_zero \ + { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0 \ + } +#define meshtastic_Config_NetworkConfig_init_zero \ + { \ + 0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, "", 0, 0 \ + } +#define meshtastic_Config_NetworkConfig_IpV4Config_init_zero \ + { \ + 0, 0, 0, 0 \ + } +#define meshtastic_Config_DisplayConfig_init_zero \ + { \ + 0, _meshtastic_Config_DisplayConfig_DeprecatedGpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN, 0, 0 \ + } +#define meshtastic_Config_LoRaConfig_init_zero \ + { \ + 0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0 \ + } +#define meshtastic_Config_BluetoothConfig_init_zero \ + { \ + 0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0 \ + } +#define meshtastic_Config_SecurityConfig_init_zero \ + { \ + {0, {0}}, {0, {0}}, 0, {{0, {0}}, {0, {0}}, {0, {0}}}, 0, 0, 0, 0 \ + } +#define meshtastic_Config_SessionkeyConfig_init_zero \ + { \ + 0 \ + } /* Field tags (for use in manual encoding/decoding) */ -#define meshtastic_Config_DeviceConfig_role_tag 1 +#define meshtastic_Config_DeviceConfig_role_tag 1 #define meshtastic_Config_DeviceConfig_serial_enabled_tag 2 #define meshtastic_Config_DeviceConfig_button_gpio_tag 4 #define meshtastic_Config_DeviceConfig_buzzer_gpio_tag 5 @@ -813,7 +900,7 @@ extern "C" { #define meshtastic_Config_LoRaConfig_spread_factor_tag 4 #define meshtastic_Config_LoRaConfig_coding_rate_tag 5 #define meshtastic_Config_LoRaConfig_frequency_offset_tag 6 -#define meshtastic_Config_LoRaConfig_region_tag 7 +#define meshtastic_Config_LoRaConfig_region_tag 7 #define meshtastic_Config_LoRaConfig_hop_limit_tag 8 #define meshtastic_Config_LoRaConfig_tx_enabled_tag 9 #define meshtastic_Config_LoRaConfig_tx_power_tag 10 @@ -835,29 +922,29 @@ extern "C" { #define meshtastic_Config_SecurityConfig_serial_enabled_tag 5 #define meshtastic_Config_SecurityConfig_debug_log_api_enabled_tag 6 #define meshtastic_Config_SecurityConfig_admin_channel_enabled_tag 8 -#define meshtastic_Config_device_tag 1 -#define meshtastic_Config_position_tag 2 -#define meshtastic_Config_power_tag 3 -#define meshtastic_Config_network_tag 4 -#define meshtastic_Config_display_tag 5 -#define meshtastic_Config_lora_tag 6 -#define meshtastic_Config_bluetooth_tag 7 -#define meshtastic_Config_security_tag 8 -#define meshtastic_Config_sessionkey_tag 9 -#define meshtastic_Config_device_ui_tag 10 +#define meshtastic_Config_device_tag 1 +#define meshtastic_Config_position_tag 2 +#define meshtastic_Config_power_tag 3 +#define meshtastic_Config_network_tag 4 +#define meshtastic_Config_display_tag 5 +#define meshtastic_Config_lora_tag 6 +#define meshtastic_Config_bluetooth_tag 7 +#define meshtastic_Config_security_tag 8 +#define meshtastic_Config_sessionkey_tag 9 +#define meshtastic_Config_device_ui_tag 10 /* Struct field encoding specification for nanopb */ -#define meshtastic_Config_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,device,payload_variant.device), 1) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,position,payload_variant.position), 2) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,power,payload_variant.power), 3) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,network,payload_variant.network), 4) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,display,payload_variant.display), 5) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,lora,payload_variant.lora), 6) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,bluetooth,payload_variant.bluetooth), 7) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,security,payload_variant.security), 8) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,sessionkey,payload_variant.sessionkey), 9) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,device_ui,payload_variant.device_ui), 10) +#define meshtastic_Config_FIELDLIST(X, a) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, device, payload_variant.device), 1) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, position, payload_variant.position), 2) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, power, payload_variant.power), 3) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, network, payload_variant.network), 4) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, display, payload_variant.display), 5) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, lora, payload_variant.lora), 6) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, bluetooth, payload_variant.bluetooth), 7) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, security, payload_variant.security), 8) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, sessionkey, payload_variant.sessionkey), 9) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, device_ui, payload_variant.device_ui), 10) #define meshtastic_Config_CALLBACK NULL #define meshtastic_Config_DEFAULT NULL #define meshtastic_Config_payload_variant_device_MSGTYPE meshtastic_Config_DeviceConfig @@ -871,148 +958,148 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,device_ui,payload_variant.de #define meshtastic_Config_payload_variant_sessionkey_MSGTYPE meshtastic_Config_SessionkeyConfig #define meshtastic_Config_payload_variant_device_ui_MSGTYPE meshtastic_DeviceUIConfig -#define meshtastic_Config_DeviceConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UENUM, role, 1) \ -X(a, STATIC, SINGULAR, BOOL, serial_enabled, 2) \ -X(a, STATIC, SINGULAR, UINT32, button_gpio, 4) \ -X(a, STATIC, SINGULAR, UINT32, buzzer_gpio, 5) \ -X(a, STATIC, SINGULAR, UENUM, rebroadcast_mode, 6) \ -X(a, STATIC, SINGULAR, UINT32, node_info_broadcast_secs, 7) \ -X(a, STATIC, SINGULAR, BOOL, double_tap_as_button_press, 8) \ -X(a, STATIC, SINGULAR, BOOL, is_managed, 9) \ -X(a, STATIC, SINGULAR, BOOL, disable_triple_click, 10) \ -X(a, STATIC, SINGULAR, STRING, tzdef, 11) \ -X(a, STATIC, SINGULAR, BOOL, led_heartbeat_disabled, 12) \ -X(a, STATIC, SINGULAR, UENUM, buzzer_mode, 13) +#define meshtastic_Config_DeviceConfig_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UENUM, role, 1) \ + X(a, STATIC, SINGULAR, BOOL, serial_enabled, 2) \ + X(a, STATIC, SINGULAR, UINT32, button_gpio, 4) \ + X(a, STATIC, SINGULAR, UINT32, buzzer_gpio, 5) \ + X(a, STATIC, SINGULAR, UENUM, rebroadcast_mode, 6) \ + X(a, STATIC, SINGULAR, UINT32, node_info_broadcast_secs, 7) \ + X(a, STATIC, SINGULAR, BOOL, double_tap_as_button_press, 8) \ + X(a, STATIC, SINGULAR, BOOL, is_managed, 9) \ + X(a, STATIC, SINGULAR, BOOL, disable_triple_click, 10) \ + X(a, STATIC, SINGULAR, STRING, tzdef, 11) \ + X(a, STATIC, SINGULAR, BOOL, led_heartbeat_disabled, 12) \ + X(a, STATIC, SINGULAR, UENUM, buzzer_mode, 13) #define meshtastic_Config_DeviceConfig_CALLBACK NULL #define meshtastic_Config_DeviceConfig_DEFAULT NULL -#define meshtastic_Config_PositionConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, position_broadcast_secs, 1) \ -X(a, STATIC, SINGULAR, BOOL, position_broadcast_smart_enabled, 2) \ -X(a, STATIC, SINGULAR, BOOL, fixed_position, 3) \ -X(a, STATIC, SINGULAR, BOOL, gps_enabled, 4) \ -X(a, STATIC, SINGULAR, UINT32, gps_update_interval, 5) \ -X(a, STATIC, SINGULAR, UINT32, gps_attempt_time, 6) \ -X(a, STATIC, SINGULAR, UINT32, position_flags, 7) \ -X(a, STATIC, SINGULAR, UINT32, rx_gpio, 8) \ -X(a, STATIC, SINGULAR, UINT32, tx_gpio, 9) \ -X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_distance, 10) \ -X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_interval_secs, 11) \ -X(a, STATIC, SINGULAR, UINT32, gps_en_gpio, 12) \ -X(a, STATIC, SINGULAR, UENUM, gps_mode, 13) +#define meshtastic_Config_PositionConfig_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UINT32, position_broadcast_secs, 1) \ + X(a, STATIC, SINGULAR, BOOL, position_broadcast_smart_enabled, 2) \ + X(a, STATIC, SINGULAR, BOOL, fixed_position, 3) \ + X(a, STATIC, SINGULAR, BOOL, gps_enabled, 4) \ + X(a, STATIC, SINGULAR, UINT32, gps_update_interval, 5) \ + X(a, STATIC, SINGULAR, UINT32, gps_attempt_time, 6) \ + X(a, STATIC, SINGULAR, UINT32, position_flags, 7) \ + X(a, STATIC, SINGULAR, UINT32, rx_gpio, 8) \ + X(a, STATIC, SINGULAR, UINT32, tx_gpio, 9) \ + X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_distance, 10) \ + X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_interval_secs, 11) \ + X(a, STATIC, SINGULAR, UINT32, gps_en_gpio, 12) \ + X(a, STATIC, SINGULAR, UENUM, gps_mode, 13) #define meshtastic_Config_PositionConfig_CALLBACK NULL #define meshtastic_Config_PositionConfig_DEFAULT NULL -#define meshtastic_Config_PowerConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, is_power_saving, 1) \ -X(a, STATIC, SINGULAR, UINT32, on_battery_shutdown_after_secs, 2) \ -X(a, STATIC, SINGULAR, FLOAT, adc_multiplier_override, 3) \ -X(a, STATIC, SINGULAR, UINT32, wait_bluetooth_secs, 4) \ -X(a, STATIC, SINGULAR, UINT32, sds_secs, 6) \ -X(a, STATIC, SINGULAR, UINT32, ls_secs, 7) \ -X(a, STATIC, SINGULAR, UINT32, min_wake_secs, 8) \ -X(a, STATIC, SINGULAR, UINT32, device_battery_ina_address, 9) \ -X(a, STATIC, SINGULAR, UINT64, powermon_enables, 32) +#define meshtastic_Config_PowerConfig_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, BOOL, is_power_saving, 1) \ + X(a, STATIC, SINGULAR, UINT32, on_battery_shutdown_after_secs, 2) \ + X(a, STATIC, SINGULAR, FLOAT, adc_multiplier_override, 3) \ + X(a, STATIC, SINGULAR, UINT32, wait_bluetooth_secs, 4) \ + X(a, STATIC, SINGULAR, UINT32, sds_secs, 6) \ + X(a, STATIC, SINGULAR, UINT32, ls_secs, 7) \ + X(a, STATIC, SINGULAR, UINT32, min_wake_secs, 8) \ + X(a, STATIC, SINGULAR, UINT32, device_battery_ina_address, 9) \ + X(a, STATIC, SINGULAR, UINT64, powermon_enables, 32) #define meshtastic_Config_PowerConfig_CALLBACK NULL #define meshtastic_Config_PowerConfig_DEFAULT NULL -#define meshtastic_Config_NetworkConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, wifi_enabled, 1) \ -X(a, STATIC, SINGULAR, STRING, wifi_ssid, 3) \ -X(a, STATIC, SINGULAR, STRING, wifi_psk, 4) \ -X(a, STATIC, SINGULAR, STRING, ntp_server, 5) \ -X(a, STATIC, SINGULAR, BOOL, eth_enabled, 6) \ -X(a, STATIC, SINGULAR, UENUM, address_mode, 7) \ -X(a, STATIC, OPTIONAL, MESSAGE, ipv4_config, 8) \ -X(a, STATIC, SINGULAR, STRING, rsyslog_server, 9) \ -X(a, STATIC, SINGULAR, UINT32, enabled_protocols, 10) \ -X(a, STATIC, SINGULAR, BOOL, ipv6_enabled, 11) +#define meshtastic_Config_NetworkConfig_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, BOOL, wifi_enabled, 1) \ + X(a, STATIC, SINGULAR, STRING, wifi_ssid, 3) \ + X(a, STATIC, SINGULAR, STRING, wifi_psk, 4) \ + X(a, STATIC, SINGULAR, STRING, ntp_server, 5) \ + X(a, STATIC, SINGULAR, BOOL, eth_enabled, 6) \ + X(a, STATIC, SINGULAR, UENUM, address_mode, 7) \ + X(a, STATIC, OPTIONAL, MESSAGE, ipv4_config, 8) \ + X(a, STATIC, SINGULAR, STRING, rsyslog_server, 9) \ + X(a, STATIC, SINGULAR, UINT32, enabled_protocols, 10) \ + X(a, STATIC, SINGULAR, BOOL, ipv6_enabled, 11) #define meshtastic_Config_NetworkConfig_CALLBACK NULL #define meshtastic_Config_NetworkConfig_DEFAULT NULL #define meshtastic_Config_NetworkConfig_ipv4_config_MSGTYPE meshtastic_Config_NetworkConfig_IpV4Config #define meshtastic_Config_NetworkConfig_IpV4Config_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, FIXED32, ip, 1) \ -X(a, STATIC, SINGULAR, FIXED32, gateway, 2) \ -X(a, STATIC, SINGULAR, FIXED32, subnet, 3) \ -X(a, STATIC, SINGULAR, FIXED32, dns, 4) + X(a, STATIC, SINGULAR, FIXED32, ip, 1) \ + X(a, STATIC, SINGULAR, FIXED32, gateway, 2) \ + X(a, STATIC, SINGULAR, FIXED32, subnet, 3) \ + X(a, STATIC, SINGULAR, FIXED32, dns, 4) #define meshtastic_Config_NetworkConfig_IpV4Config_CALLBACK NULL #define meshtastic_Config_NetworkConfig_IpV4Config_DEFAULT NULL -#define meshtastic_Config_DisplayConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, screen_on_secs, 1) \ -X(a, STATIC, SINGULAR, UENUM, gps_format, 2) \ -X(a, STATIC, SINGULAR, UINT32, auto_screen_carousel_secs, 3) \ -X(a, STATIC, SINGULAR, BOOL, compass_north_top, 4) \ -X(a, STATIC, SINGULAR, BOOL, flip_screen, 5) \ -X(a, STATIC, SINGULAR, UENUM, units, 6) \ -X(a, STATIC, SINGULAR, UENUM, oled, 7) \ -X(a, STATIC, SINGULAR, UENUM, displaymode, 8) \ -X(a, STATIC, SINGULAR, BOOL, heading_bold, 9) \ -X(a, STATIC, SINGULAR, BOOL, wake_on_tap_or_motion, 10) \ -X(a, STATIC, SINGULAR, UENUM, compass_orientation, 11) \ -X(a, STATIC, SINGULAR, BOOL, use_12h_clock, 12) \ -X(a, STATIC, SINGULAR, BOOL, use_long_node_name, 13) +#define meshtastic_Config_DisplayConfig_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UINT32, screen_on_secs, 1) \ + X(a, STATIC, SINGULAR, UENUM, gps_format, 2) \ + X(a, STATIC, SINGULAR, UINT32, auto_screen_carousel_secs, 3) \ + X(a, STATIC, SINGULAR, BOOL, compass_north_top, 4) \ + X(a, STATIC, SINGULAR, BOOL, flip_screen, 5) \ + X(a, STATIC, SINGULAR, UENUM, units, 6) \ + X(a, STATIC, SINGULAR, UENUM, oled, 7) \ + X(a, STATIC, SINGULAR, UENUM, displaymode, 8) \ + X(a, STATIC, SINGULAR, BOOL, heading_bold, 9) \ + X(a, STATIC, SINGULAR, BOOL, wake_on_tap_or_motion, 10) \ + X(a, STATIC, SINGULAR, UENUM, compass_orientation, 11) \ + X(a, STATIC, SINGULAR, BOOL, use_12h_clock, 12) \ + X(a, STATIC, SINGULAR, BOOL, use_long_node_name, 13) #define meshtastic_Config_DisplayConfig_CALLBACK NULL #define meshtastic_Config_DisplayConfig_DEFAULT NULL -#define meshtastic_Config_LoRaConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, use_preset, 1) \ -X(a, STATIC, SINGULAR, UENUM, modem_preset, 2) \ -X(a, STATIC, SINGULAR, UINT32, bandwidth, 3) \ -X(a, STATIC, SINGULAR, UINT32, spread_factor, 4) \ -X(a, STATIC, SINGULAR, UINT32, coding_rate, 5) \ -X(a, STATIC, SINGULAR, FLOAT, frequency_offset, 6) \ -X(a, STATIC, SINGULAR, UENUM, region, 7) \ -X(a, STATIC, SINGULAR, UINT32, hop_limit, 8) \ -X(a, STATIC, SINGULAR, BOOL, tx_enabled, 9) \ -X(a, STATIC, SINGULAR, INT32, tx_power, 10) \ -X(a, STATIC, SINGULAR, UINT32, channel_num, 11) \ -X(a, STATIC, SINGULAR, BOOL, override_duty_cycle, 12) \ -X(a, STATIC, SINGULAR, BOOL, sx126x_rx_boosted_gain, 13) \ -X(a, STATIC, SINGULAR, FLOAT, override_frequency, 14) \ -X(a, STATIC, SINGULAR, BOOL, pa_fan_disabled, 15) \ -X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103) \ -X(a, STATIC, SINGULAR, BOOL, ignore_mqtt, 104) \ -X(a, STATIC, SINGULAR, BOOL, config_ok_to_mqtt, 105) +#define meshtastic_Config_LoRaConfig_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, BOOL, use_preset, 1) \ + X(a, STATIC, SINGULAR, UENUM, modem_preset, 2) \ + X(a, STATIC, SINGULAR, UINT32, bandwidth, 3) \ + X(a, STATIC, SINGULAR, UINT32, spread_factor, 4) \ + X(a, STATIC, SINGULAR, UINT32, coding_rate, 5) \ + X(a, STATIC, SINGULAR, FLOAT, frequency_offset, 6) \ + X(a, STATIC, SINGULAR, UENUM, region, 7) \ + X(a, STATIC, SINGULAR, UINT32, hop_limit, 8) \ + X(a, STATIC, SINGULAR, BOOL, tx_enabled, 9) \ + X(a, STATIC, SINGULAR, INT32, tx_power, 10) \ + X(a, STATIC, SINGULAR, UINT32, channel_num, 11) \ + X(a, STATIC, SINGULAR, BOOL, override_duty_cycle, 12) \ + X(a, STATIC, SINGULAR, BOOL, sx126x_rx_boosted_gain, 13) \ + X(a, STATIC, SINGULAR, FLOAT, override_frequency, 14) \ + X(a, STATIC, SINGULAR, BOOL, pa_fan_disabled, 15) \ + X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103) \ + X(a, STATIC, SINGULAR, BOOL, ignore_mqtt, 104) \ + X(a, STATIC, SINGULAR, BOOL, config_ok_to_mqtt, 105) #define meshtastic_Config_LoRaConfig_CALLBACK NULL #define meshtastic_Config_LoRaConfig_DEFAULT NULL #define meshtastic_Config_BluetoothConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ -X(a, STATIC, SINGULAR, UENUM, mode, 2) \ -X(a, STATIC, SINGULAR, UINT32, fixed_pin, 3) + X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ + X(a, STATIC, SINGULAR, UENUM, mode, 2) \ + X(a, STATIC, SINGULAR, UINT32, fixed_pin, 3) #define meshtastic_Config_BluetoothConfig_CALLBACK NULL #define meshtastic_Config_BluetoothConfig_DEFAULT NULL -#define meshtastic_Config_SecurityConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BYTES, public_key, 1) \ -X(a, STATIC, SINGULAR, BYTES, private_key, 2) \ -X(a, STATIC, REPEATED, BYTES, admin_key, 3) \ -X(a, STATIC, SINGULAR, BOOL, is_managed, 4) \ -X(a, STATIC, SINGULAR, BOOL, serial_enabled, 5) \ -X(a, STATIC, SINGULAR, BOOL, debug_log_api_enabled, 6) \ -X(a, STATIC, SINGULAR, BOOL, admin_channel_enabled, 8) +#define meshtastic_Config_SecurityConfig_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, BYTES, public_key, 1) \ + X(a, STATIC, SINGULAR, BYTES, private_key, 2) \ + X(a, STATIC, REPEATED, BYTES, admin_key, 3) \ + X(a, STATIC, SINGULAR, BOOL, is_managed, 4) \ + X(a, STATIC, SINGULAR, BOOL, serial_enabled, 5) \ + X(a, STATIC, SINGULAR, BOOL, debug_log_api_enabled, 6) \ + X(a, STATIC, SINGULAR, BOOL, admin_channel_enabled, 8) #define meshtastic_Config_SecurityConfig_CALLBACK NULL #define meshtastic_Config_SecurityConfig_DEFAULT NULL -#define meshtastic_Config_SessionkeyConfig_FIELDLIST(X, a) \ +#define meshtastic_Config_SessionkeyConfig_FIELDLIST(X, a) #define meshtastic_Config_SessionkeyConfig_CALLBACK NULL #define meshtastic_Config_SessionkeyConfig_DEFAULT NULL -extern const pb_msgdesc_t meshtastic_Config_msg; -extern const pb_msgdesc_t meshtastic_Config_DeviceConfig_msg; -extern const pb_msgdesc_t meshtastic_Config_PositionConfig_msg; -extern const pb_msgdesc_t meshtastic_Config_PowerConfig_msg; -extern const pb_msgdesc_t meshtastic_Config_NetworkConfig_msg; -extern const pb_msgdesc_t meshtastic_Config_NetworkConfig_IpV4Config_msg; -extern const pb_msgdesc_t meshtastic_Config_DisplayConfig_msg; -extern const pb_msgdesc_t meshtastic_Config_LoRaConfig_msg; -extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg; -extern const pb_msgdesc_t meshtastic_Config_SecurityConfig_msg; -extern const pb_msgdesc_t meshtastic_Config_SessionkeyConfig_msg; + extern const pb_msgdesc_t meshtastic_Config_msg; + extern const pb_msgdesc_t meshtastic_Config_DeviceConfig_msg; + extern const pb_msgdesc_t meshtastic_Config_PositionConfig_msg; + extern const pb_msgdesc_t meshtastic_Config_PowerConfig_msg; + extern const pb_msgdesc_t meshtastic_Config_NetworkConfig_msg; + extern const pb_msgdesc_t meshtastic_Config_NetworkConfig_IpV4Config_msg; + extern const pb_msgdesc_t meshtastic_Config_DisplayConfig_msg; + extern const pb_msgdesc_t meshtastic_Config_LoRaConfig_msg; + extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg; + extern const pb_msgdesc_t meshtastic_Config_SecurityConfig_msg; + extern const pb_msgdesc_t meshtastic_Config_SessionkeyConfig_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_Config_fields &meshtastic_Config_msg @@ -1029,17 +1116,17 @@ extern const pb_msgdesc_t meshtastic_Config_SessionkeyConfig_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_CONFIG_PB_H_MAX_SIZE meshtastic_Config_size -#define meshtastic_Config_BluetoothConfig_size 10 -#define meshtastic_Config_DeviceConfig_size 100 -#define meshtastic_Config_DisplayConfig_size 34 -#define meshtastic_Config_LoRaConfig_size 85 +#define meshtastic_Config_BluetoothConfig_size 10 +#define meshtastic_Config_DeviceConfig_size 100 +#define meshtastic_Config_DisplayConfig_size 34 +#define meshtastic_Config_LoRaConfig_size 85 #define meshtastic_Config_NetworkConfig_IpV4Config_size 20 -#define meshtastic_Config_NetworkConfig_size 204 -#define meshtastic_Config_PositionConfig_size 62 -#define meshtastic_Config_PowerConfig_size 52 -#define meshtastic_Config_SecurityConfig_size 178 -#define meshtastic_Config_SessionkeyConfig_size 0 -#define meshtastic_Config_size 207 +#define meshtastic_Config_NetworkConfig_size 204 +#define meshtastic_Config_PositionConfig_size 62 +#define meshtastic_Config_PowerConfig_size 52 +#define meshtastic_Config_SecurityConfig_size 178 +#define meshtastic_Config_SessionkeyConfig_size 0 +#define meshtastic_Config_size 207 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/connection_status.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/connection_status.pb.cpp index b0df459a..1386c5c2 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/connection_status.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/connection_status.pb.cpp @@ -8,20 +8,12 @@ PB_BIND(meshtastic_DeviceConnectionStatus, meshtastic_DeviceConnectionStatus, AUTO) - PB_BIND(meshtastic_WifiConnectionStatus, meshtastic_WifiConnectionStatus, AUTO) - PB_BIND(meshtastic_EthernetConnectionStatus, meshtastic_EthernetConnectionStatus, AUTO) - PB_BIND(meshtastic_NetworkConnectionStatus, meshtastic_NetworkConnectionStatus, AUTO) - PB_BIND(meshtastic_BluetoothConnectionStatus, meshtastic_BluetoothConnectionStatus, AUTO) - PB_BIND(meshtastic_SerialConnectionStatus, meshtastic_SerialConnectionStatus, AUTO) - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/connection_status.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/connection_status.pb.h index 55559dce..f974f137 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/connection_status.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/connection_status.pb.h @@ -11,7 +11,8 @@ /* Struct definitions */ /* Ethernet or WiFi connection status */ -typedef struct _meshtastic_NetworkConnectionStatus { +typedef struct _meshtastic_NetworkConnectionStatus +{ /* IP address of device */ uint32_t ip_address; /* Whether the device has an active connection or not */ @@ -23,7 +24,8 @@ typedef struct _meshtastic_NetworkConnectionStatus { } meshtastic_NetworkConnectionStatus; /* WiFi connection status */ -typedef struct _meshtastic_WifiConnectionStatus { +typedef struct _meshtastic_WifiConnectionStatus +{ /* Connection status */ bool has_status; meshtastic_NetworkConnectionStatus status; @@ -34,14 +36,16 @@ typedef struct _meshtastic_WifiConnectionStatus { } meshtastic_WifiConnectionStatus; /* Ethernet connection status */ -typedef struct _meshtastic_EthernetConnectionStatus { +typedef struct _meshtastic_EthernetConnectionStatus +{ /* Connection status */ bool has_status; meshtastic_NetworkConnectionStatus status; } meshtastic_EthernetConnectionStatus; /* Bluetooth connection status */ -typedef struct _meshtastic_BluetoothConnectionStatus { +typedef struct _meshtastic_BluetoothConnectionStatus +{ /* The pairing PIN for bluetooth */ uint32_t pin; /* RSSI of bluetooth connection */ @@ -51,14 +55,16 @@ typedef struct _meshtastic_BluetoothConnectionStatus { } meshtastic_BluetoothConnectionStatus; /* Serial connection status */ -typedef struct _meshtastic_SerialConnectionStatus { +typedef struct _meshtastic_SerialConnectionStatus +{ /* Serial baud rate */ uint32_t baud; /* Whether the device has an active connection or not */ bool is_connected; } meshtastic_SerialConnectionStatus; -typedef struct _meshtastic_DeviceConnectionStatus { +typedef struct _meshtastic_DeviceConnectionStatus +{ /* WiFi Status */ bool has_wifi; meshtastic_WifiConnectionStatus wifi; @@ -73,24 +79,60 @@ typedef struct _meshtastic_DeviceConnectionStatus { meshtastic_SerialConnectionStatus serial; } meshtastic_DeviceConnectionStatus; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Initializer values for message structs */ -#define meshtastic_DeviceConnectionStatus_init_default {false, meshtastic_WifiConnectionStatus_init_default, false, meshtastic_EthernetConnectionStatus_init_default, false, meshtastic_BluetoothConnectionStatus_init_default, false, meshtastic_SerialConnectionStatus_init_default} -#define meshtastic_WifiConnectionStatus_init_default {false, meshtastic_NetworkConnectionStatus_init_default, "", 0} -#define meshtastic_EthernetConnectionStatus_init_default {false, meshtastic_NetworkConnectionStatus_init_default} -#define meshtastic_NetworkConnectionStatus_init_default {0, 0, 0, 0} -#define meshtastic_BluetoothConnectionStatus_init_default {0, 0, 0} -#define meshtastic_SerialConnectionStatus_init_default {0, 0} -#define meshtastic_DeviceConnectionStatus_init_zero {false, meshtastic_WifiConnectionStatus_init_zero, false, meshtastic_EthernetConnectionStatus_init_zero, false, meshtastic_BluetoothConnectionStatus_init_zero, false, meshtastic_SerialConnectionStatus_init_zero} -#define meshtastic_WifiConnectionStatus_init_zero {false, meshtastic_NetworkConnectionStatus_init_zero, "", 0} -#define meshtastic_EthernetConnectionStatus_init_zero {false, meshtastic_NetworkConnectionStatus_init_zero} -#define meshtastic_NetworkConnectionStatus_init_zero {0, 0, 0, 0} -#define meshtastic_BluetoothConnectionStatus_init_zero {0, 0, 0} -#define meshtastic_SerialConnectionStatus_init_zero {0, 0} +#define meshtastic_DeviceConnectionStatus_init_default \ + { \ + false, meshtastic_WifiConnectionStatus_init_default, false, meshtastic_EthernetConnectionStatus_init_default, false, meshtastic_BluetoothConnectionStatus_init_default, false, meshtastic_SerialConnectionStatus_init_default \ + } +#define meshtastic_WifiConnectionStatus_init_default \ + { \ + false, meshtastic_NetworkConnectionStatus_init_default, "", 0 \ + } +#define meshtastic_EthernetConnectionStatus_init_default \ + { \ + false, meshtastic_NetworkConnectionStatus_init_default \ + } +#define meshtastic_NetworkConnectionStatus_init_default \ + { \ + 0, 0, 0, 0 \ + } +#define meshtastic_BluetoothConnectionStatus_init_default \ + { \ + 0, 0, 0 \ + } +#define meshtastic_SerialConnectionStatus_init_default \ + { \ + 0, 0 \ + } +#define meshtastic_DeviceConnectionStatus_init_zero \ + { \ + false, meshtastic_WifiConnectionStatus_init_zero, false, meshtastic_EthernetConnectionStatus_init_zero, false, meshtastic_BluetoothConnectionStatus_init_zero, false, meshtastic_SerialConnectionStatus_init_zero \ + } +#define meshtastic_WifiConnectionStatus_init_zero \ + { \ + false, meshtastic_NetworkConnectionStatus_init_zero, "", 0 \ + } +#define meshtastic_EthernetConnectionStatus_init_zero \ + { \ + false, meshtastic_NetworkConnectionStatus_init_zero \ + } +#define meshtastic_NetworkConnectionStatus_init_zero \ + { \ + 0, 0, 0, 0 \ + } +#define meshtastic_BluetoothConnectionStatus_init_zero \ + { \ + 0, 0, 0 \ + } +#define meshtastic_SerialConnectionStatus_init_zero \ + { \ + 0, 0 \ + } /* Field tags (for use in manual encoding/decoding) */ #define meshtastic_NetworkConnectionStatus_ip_address_tag 1 @@ -113,10 +155,10 @@ extern "C" { /* Struct field encoding specification for nanopb */ #define meshtastic_DeviceConnectionStatus_FIELDLIST(X, a) \ -X(a, STATIC, OPTIONAL, MESSAGE, wifi, 1) \ -X(a, STATIC, OPTIONAL, MESSAGE, ethernet, 2) \ -X(a, STATIC, OPTIONAL, MESSAGE, bluetooth, 3) \ -X(a, STATIC, OPTIONAL, MESSAGE, serial, 4) + X(a, STATIC, OPTIONAL, MESSAGE, wifi, 1) \ + X(a, STATIC, OPTIONAL, MESSAGE, ethernet, 2) \ + X(a, STATIC, OPTIONAL, MESSAGE, bluetooth, 3) \ + X(a, STATIC, OPTIONAL, MESSAGE, serial, 4) #define meshtastic_DeviceConnectionStatus_CALLBACK NULL #define meshtastic_DeviceConnectionStatus_DEFAULT NULL #define meshtastic_DeviceConnectionStatus_wifi_MSGTYPE meshtastic_WifiConnectionStatus @@ -125,46 +167,46 @@ X(a, STATIC, OPTIONAL, MESSAGE, serial, 4) #define meshtastic_DeviceConnectionStatus_serial_MSGTYPE meshtastic_SerialConnectionStatus #define meshtastic_WifiConnectionStatus_FIELDLIST(X, a) \ -X(a, STATIC, OPTIONAL, MESSAGE, status, 1) \ -X(a, STATIC, SINGULAR, STRING, ssid, 2) \ -X(a, STATIC, SINGULAR, INT32, rssi, 3) + X(a, STATIC, OPTIONAL, MESSAGE, status, 1) \ + X(a, STATIC, SINGULAR, STRING, ssid, 2) \ + X(a, STATIC, SINGULAR, INT32, rssi, 3) #define meshtastic_WifiConnectionStatus_CALLBACK NULL #define meshtastic_WifiConnectionStatus_DEFAULT NULL #define meshtastic_WifiConnectionStatus_status_MSGTYPE meshtastic_NetworkConnectionStatus #define meshtastic_EthernetConnectionStatus_FIELDLIST(X, a) \ -X(a, STATIC, OPTIONAL, MESSAGE, status, 1) + X(a, STATIC, OPTIONAL, MESSAGE, status, 1) #define meshtastic_EthernetConnectionStatus_CALLBACK NULL #define meshtastic_EthernetConnectionStatus_DEFAULT NULL #define meshtastic_EthernetConnectionStatus_status_MSGTYPE meshtastic_NetworkConnectionStatus #define meshtastic_NetworkConnectionStatus_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, FIXED32, ip_address, 1) \ -X(a, STATIC, SINGULAR, BOOL, is_connected, 2) \ -X(a, STATIC, SINGULAR, BOOL, is_mqtt_connected, 3) \ -X(a, STATIC, SINGULAR, BOOL, is_syslog_connected, 4) + X(a, STATIC, SINGULAR, FIXED32, ip_address, 1) \ + X(a, STATIC, SINGULAR, BOOL, is_connected, 2) \ + X(a, STATIC, SINGULAR, BOOL, is_mqtt_connected, 3) \ + X(a, STATIC, SINGULAR, BOOL, is_syslog_connected, 4) #define meshtastic_NetworkConnectionStatus_CALLBACK NULL #define meshtastic_NetworkConnectionStatus_DEFAULT NULL #define meshtastic_BluetoothConnectionStatus_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, pin, 1) \ -X(a, STATIC, SINGULAR, INT32, rssi, 2) \ -X(a, STATIC, SINGULAR, BOOL, is_connected, 3) + X(a, STATIC, SINGULAR, UINT32, pin, 1) \ + X(a, STATIC, SINGULAR, INT32, rssi, 2) \ + X(a, STATIC, SINGULAR, BOOL, is_connected, 3) #define meshtastic_BluetoothConnectionStatus_CALLBACK NULL #define meshtastic_BluetoothConnectionStatus_DEFAULT NULL #define meshtastic_SerialConnectionStatus_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, baud, 1) \ -X(a, STATIC, SINGULAR, BOOL, is_connected, 2) + X(a, STATIC, SINGULAR, UINT32, baud, 1) \ + X(a, STATIC, SINGULAR, BOOL, is_connected, 2) #define meshtastic_SerialConnectionStatus_CALLBACK NULL #define meshtastic_SerialConnectionStatus_DEFAULT NULL -extern const pb_msgdesc_t meshtastic_DeviceConnectionStatus_msg; -extern const pb_msgdesc_t meshtastic_WifiConnectionStatus_msg; -extern const pb_msgdesc_t meshtastic_EthernetConnectionStatus_msg; -extern const pb_msgdesc_t meshtastic_NetworkConnectionStatus_msg; -extern const pb_msgdesc_t meshtastic_BluetoothConnectionStatus_msg; -extern const pb_msgdesc_t meshtastic_SerialConnectionStatus_msg; + extern const pb_msgdesc_t meshtastic_DeviceConnectionStatus_msg; + extern const pb_msgdesc_t meshtastic_WifiConnectionStatus_msg; + extern const pb_msgdesc_t meshtastic_EthernetConnectionStatus_msg; + extern const pb_msgdesc_t meshtastic_NetworkConnectionStatus_msg; + extern const pb_msgdesc_t meshtastic_BluetoothConnectionStatus_msg; + extern const pb_msgdesc_t meshtastic_SerialConnectionStatus_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_DeviceConnectionStatus_fields &meshtastic_DeviceConnectionStatus_msg @@ -177,11 +219,11 @@ extern const pb_msgdesc_t meshtastic_SerialConnectionStatus_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_CONNECTION_STATUS_PB_H_MAX_SIZE meshtastic_DeviceConnectionStatus_size #define meshtastic_BluetoothConnectionStatus_size 19 -#define meshtastic_DeviceConnectionStatus_size 106 +#define meshtastic_DeviceConnectionStatus_size 106 #define meshtastic_EthernetConnectionStatus_size 13 -#define meshtastic_NetworkConnectionStatus_size 11 -#define meshtastic_SerialConnectionStatus_size 8 -#define meshtastic_WifiConnectionStatus_size 58 +#define meshtastic_NetworkConnectionStatus_size 11 +#define meshtastic_SerialConnectionStatus_size 8 +#define meshtastic_WifiConnectionStatus_size 58 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/device_ui.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/device_ui.pb.cpp index 01940265..2f434723 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/device_ui.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/device_ui.pb.cpp @@ -8,25 +8,10 @@ PB_BIND(meshtastic_DeviceUIConfig, meshtastic_DeviceUIConfig, AUTO) - PB_BIND(meshtastic_NodeFilter, meshtastic_NodeFilter, AUTO) - PB_BIND(meshtastic_NodeHighlight, meshtastic_NodeHighlight, AUTO) - PB_BIND(meshtastic_GeoPoint, meshtastic_GeoPoint, AUTO) - PB_BIND(meshtastic_Map, meshtastic_Map, AUTO) - - - - - - - - - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/device_ui.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/device_ui.pb.h index b99fb10b..ac783f80 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/device_ui.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/device_ui.pb.h @@ -10,7 +10,8 @@ #endif /* Enum definitions */ -typedef enum _meshtastic_CompassMode { +typedef enum _meshtastic_CompassMode +{ /* Compass with dynamic ring and heading */ meshtastic_CompassMode_DYNAMIC = 0, /* Compass with fixed ring and heading */ @@ -19,7 +20,8 @@ typedef enum _meshtastic_CompassMode { meshtastic_CompassMode_FREEZE_HEADING = 2 } meshtastic_CompassMode; -typedef enum _meshtastic_Theme { +typedef enum _meshtastic_Theme +{ /* Dark */ meshtastic_Theme_DARK = 0, /* Light */ @@ -29,7 +31,8 @@ typedef enum _meshtastic_Theme { } meshtastic_Theme; /* Localization */ -typedef enum _meshtastic_Language { +typedef enum _meshtastic_Language +{ /* English */ meshtastic_Language_ENGLISH = 0, /* French */ @@ -77,7 +80,8 @@ typedef enum _meshtastic_Language { } meshtastic_Language; /* How the GPS coordinates are displayed on the OLED screen. */ -typedef enum _meshtastic_DeviceUIConfig_GpsCoordinateFormat { +typedef enum _meshtastic_DeviceUIConfig_GpsCoordinateFormat +{ /* GPS coordinates are displayed in the normal decimal degrees format: DD.DDDDDD DDD.DDDDDD */ meshtastic_DeviceUIConfig_GpsCoordinateFormat_DEC = 0, @@ -103,7 +107,8 @@ typedef enum _meshtastic_DeviceUIConfig_GpsCoordinateFormat { } meshtastic_DeviceUIConfig_GpsCoordinateFormat; /* Struct definitions */ -typedef struct _meshtastic_NodeFilter { +typedef struct _meshtastic_NodeFilter +{ /* Filter unknown nodes */ bool unknown_switch; /* Filter offline nodes */ @@ -120,7 +125,8 @@ typedef struct _meshtastic_NodeFilter { int8_t channel; } meshtastic_NodeFilter; -typedef struct _meshtastic_NodeHighlight { +typedef struct _meshtastic_NodeHighlight +{ /* Hightlight nodes w/ active chat */ bool chat_switch; /* Highlight nodes w/ position */ @@ -133,7 +139,8 @@ typedef struct _meshtastic_NodeHighlight { char node_name[16]; } meshtastic_NodeHighlight; -typedef struct _meshtastic_GeoPoint { +typedef struct _meshtastic_GeoPoint +{ /* Zoom level */ int8_t zoom; /* Coordinate: latitude */ @@ -142,7 +149,8 @@ typedef struct _meshtastic_GeoPoint { int32_t longitude; } meshtastic_GeoPoint; -typedef struct _meshtastic_Map { +typedef struct _meshtastic_Map +{ /* Home coordinates */ bool has_home; meshtastic_GeoPoint home; @@ -153,7 +161,8 @@ typedef struct _meshtastic_Map { } meshtastic_Map; typedef PB_BYTES_ARRAY_T(16) meshtastic_DeviceUIConfig_calibration_data_t; -typedef struct _meshtastic_DeviceUIConfig { +typedef struct _meshtastic_DeviceUIConfig +{ /* A version integer used to invalidate saved files when we make incompatible changes. */ uint32_t version; /* TFT display brightness 1..255 */ @@ -195,156 +204,181 @@ typedef struct _meshtastic_DeviceUIConfig { meshtastic_DeviceUIConfig_GpsCoordinateFormat gps_format; } meshtastic_DeviceUIConfig; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Helper constants for enums */ #define _meshtastic_CompassMode_MIN meshtastic_CompassMode_DYNAMIC #define _meshtastic_CompassMode_MAX meshtastic_CompassMode_FREEZE_HEADING -#define _meshtastic_CompassMode_ARRAYSIZE ((meshtastic_CompassMode)(meshtastic_CompassMode_FREEZE_HEADING+1)) +#define _meshtastic_CompassMode_ARRAYSIZE ((meshtastic_CompassMode)(meshtastic_CompassMode_FREEZE_HEADING + 1)) #define _meshtastic_Theme_MIN meshtastic_Theme_DARK #define _meshtastic_Theme_MAX meshtastic_Theme_RED -#define _meshtastic_Theme_ARRAYSIZE ((meshtastic_Theme)(meshtastic_Theme_RED+1)) +#define _meshtastic_Theme_ARRAYSIZE ((meshtastic_Theme)(meshtastic_Theme_RED + 1)) #define _meshtastic_Language_MIN meshtastic_Language_ENGLISH #define _meshtastic_Language_MAX meshtastic_Language_TRADITIONAL_CHINESE -#define _meshtastic_Language_ARRAYSIZE ((meshtastic_Language)(meshtastic_Language_TRADITIONAL_CHINESE+1)) +#define _meshtastic_Language_ARRAYSIZE ((meshtastic_Language)(meshtastic_Language_TRADITIONAL_CHINESE + 1)) #define _meshtastic_DeviceUIConfig_GpsCoordinateFormat_MIN meshtastic_DeviceUIConfig_GpsCoordinateFormat_DEC #define _meshtastic_DeviceUIConfig_GpsCoordinateFormat_MAX meshtastic_DeviceUIConfig_GpsCoordinateFormat_MLS -#define _meshtastic_DeviceUIConfig_GpsCoordinateFormat_ARRAYSIZE ((meshtastic_DeviceUIConfig_GpsCoordinateFormat)(meshtastic_DeviceUIConfig_GpsCoordinateFormat_MLS+1)) +#define _meshtastic_DeviceUIConfig_GpsCoordinateFormat_ARRAYSIZE ((meshtastic_DeviceUIConfig_GpsCoordinateFormat)(meshtastic_DeviceUIConfig_GpsCoordinateFormat_MLS + 1)) #define meshtastic_DeviceUIConfig_theme_ENUMTYPE meshtastic_Theme #define meshtastic_DeviceUIConfig_language_ENUMTYPE meshtastic_Language #define meshtastic_DeviceUIConfig_compass_mode_ENUMTYPE meshtastic_CompassMode #define meshtastic_DeviceUIConfig_gps_format_ENUMTYPE meshtastic_DeviceUIConfig_GpsCoordinateFormat - - - - - /* Initializer values for message structs */ -#define meshtastic_DeviceUIConfig_init_default {0, 0, 0, 0, 0, 0, _meshtastic_Theme_MIN, 0, 0, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_default, false, meshtastic_NodeHighlight_init_default, {0, {0}}, false, meshtastic_Map_init_default, _meshtastic_CompassMode_MIN, 0, 0, _meshtastic_DeviceUIConfig_GpsCoordinateFormat_MIN} -#define meshtastic_NodeFilter_init_default {0, 0, 0, 0, 0, "", 0} -#define meshtastic_NodeHighlight_init_default {0, 0, 0, 0, ""} -#define meshtastic_GeoPoint_init_default {0, 0, 0} -#define meshtastic_Map_init_default {false, meshtastic_GeoPoint_init_default, "", 0} -#define meshtastic_DeviceUIConfig_init_zero {0, 0, 0, 0, 0, 0, _meshtastic_Theme_MIN, 0, 0, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_zero, false, meshtastic_NodeHighlight_init_zero, {0, {0}}, false, meshtastic_Map_init_zero, _meshtastic_CompassMode_MIN, 0, 0, _meshtastic_DeviceUIConfig_GpsCoordinateFormat_MIN} -#define meshtastic_NodeFilter_init_zero {0, 0, 0, 0, 0, "", 0} -#define meshtastic_NodeHighlight_init_zero {0, 0, 0, 0, ""} -#define meshtastic_GeoPoint_init_zero {0, 0, 0} -#define meshtastic_Map_init_zero {false, meshtastic_GeoPoint_init_zero, "", 0} +#define meshtastic_DeviceUIConfig_init_default \ + { \ + 0, 0, 0, 0, 0, 0, _meshtastic_Theme_MIN, 0, 0, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_default, false, meshtastic_NodeHighlight_init_default, {0, {0}}, false, meshtastic_Map_init_default, _meshtastic_CompassMode_MIN, 0, 0, _meshtastic_DeviceUIConfig_GpsCoordinateFormat_MIN \ + } +#define meshtastic_NodeFilter_init_default \ + { \ + 0, 0, 0, 0, 0, "", 0 \ + } +#define meshtastic_NodeHighlight_init_default \ + { \ + 0, 0, 0, 0, "" \ + } +#define meshtastic_GeoPoint_init_default \ + { \ + 0, 0, 0 \ + } +#define meshtastic_Map_init_default \ + { \ + false, meshtastic_GeoPoint_init_default, "", 0 \ + } +#define meshtastic_DeviceUIConfig_init_zero \ + { \ + 0, 0, 0, 0, 0, 0, _meshtastic_Theme_MIN, 0, 0, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_zero, false, meshtastic_NodeHighlight_init_zero, {0, {0}}, false, meshtastic_Map_init_zero, _meshtastic_CompassMode_MIN, 0, 0, _meshtastic_DeviceUIConfig_GpsCoordinateFormat_MIN \ + } +#define meshtastic_NodeFilter_init_zero \ + { \ + 0, 0, 0, 0, 0, "", 0 \ + } +#define meshtastic_NodeHighlight_init_zero \ + { \ + 0, 0, 0, 0, "" \ + } +#define meshtastic_GeoPoint_init_zero \ + { \ + 0, 0, 0 \ + } +#define meshtastic_Map_init_zero \ + { \ + false, meshtastic_GeoPoint_init_zero, "", 0 \ + } /* Field tags (for use in manual encoding/decoding) */ #define meshtastic_NodeFilter_unknown_switch_tag 1 #define meshtastic_NodeFilter_offline_switch_tag 2 #define meshtastic_NodeFilter_public_key_switch_tag 3 -#define meshtastic_NodeFilter_hops_away_tag 4 +#define meshtastic_NodeFilter_hops_away_tag 4 #define meshtastic_NodeFilter_position_switch_tag 5 -#define meshtastic_NodeFilter_node_name_tag 6 -#define meshtastic_NodeFilter_channel_tag 7 +#define meshtastic_NodeFilter_node_name_tag 6 +#define meshtastic_NodeFilter_channel_tag 7 #define meshtastic_NodeHighlight_chat_switch_tag 1 #define meshtastic_NodeHighlight_position_switch_tag 2 #define meshtastic_NodeHighlight_telemetry_switch_tag 3 -#define meshtastic_NodeHighlight_iaq_switch_tag 4 -#define meshtastic_NodeHighlight_node_name_tag 5 -#define meshtastic_GeoPoint_zoom_tag 1 -#define meshtastic_GeoPoint_latitude_tag 2 -#define meshtastic_GeoPoint_longitude_tag 3 -#define meshtastic_Map_home_tag 1 -#define meshtastic_Map_style_tag 2 -#define meshtastic_Map_follow_gps_tag 3 -#define meshtastic_DeviceUIConfig_version_tag 1 +#define meshtastic_NodeHighlight_iaq_switch_tag 4 +#define meshtastic_NodeHighlight_node_name_tag 5 +#define meshtastic_GeoPoint_zoom_tag 1 +#define meshtastic_GeoPoint_latitude_tag 2 +#define meshtastic_GeoPoint_longitude_tag 3 +#define meshtastic_Map_home_tag 1 +#define meshtastic_Map_style_tag 2 +#define meshtastic_Map_follow_gps_tag 3 +#define meshtastic_DeviceUIConfig_version_tag 1 #define meshtastic_DeviceUIConfig_screen_brightness_tag 2 #define meshtastic_DeviceUIConfig_screen_timeout_tag 3 #define meshtastic_DeviceUIConfig_screen_lock_tag 4 #define meshtastic_DeviceUIConfig_settings_lock_tag 5 -#define meshtastic_DeviceUIConfig_pin_code_tag 6 -#define meshtastic_DeviceUIConfig_theme_tag 7 +#define meshtastic_DeviceUIConfig_pin_code_tag 6 +#define meshtastic_DeviceUIConfig_theme_tag 7 #define meshtastic_DeviceUIConfig_alert_enabled_tag 8 #define meshtastic_DeviceUIConfig_banner_enabled_tag 9 #define meshtastic_DeviceUIConfig_ring_tone_id_tag 10 -#define meshtastic_DeviceUIConfig_language_tag 11 +#define meshtastic_DeviceUIConfig_language_tag 11 #define meshtastic_DeviceUIConfig_node_filter_tag 12 #define meshtastic_DeviceUIConfig_node_highlight_tag 13 #define meshtastic_DeviceUIConfig_calibration_data_tag 14 -#define meshtastic_DeviceUIConfig_map_data_tag 15 +#define meshtastic_DeviceUIConfig_map_data_tag 15 #define meshtastic_DeviceUIConfig_compass_mode_tag 16 #define meshtastic_DeviceUIConfig_screen_rgb_color_tag 17 #define meshtastic_DeviceUIConfig_is_clockface_analog_tag 18 #define meshtastic_DeviceUIConfig_gps_format_tag 19 /* Struct field encoding specification for nanopb */ -#define meshtastic_DeviceUIConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, version, 1) \ -X(a, STATIC, SINGULAR, UINT32, screen_brightness, 2) \ -X(a, STATIC, SINGULAR, UINT32, screen_timeout, 3) \ -X(a, STATIC, SINGULAR, BOOL, screen_lock, 4) \ -X(a, STATIC, SINGULAR, BOOL, settings_lock, 5) \ -X(a, STATIC, SINGULAR, UINT32, pin_code, 6) \ -X(a, STATIC, SINGULAR, UENUM, theme, 7) \ -X(a, STATIC, SINGULAR, BOOL, alert_enabled, 8) \ -X(a, STATIC, SINGULAR, BOOL, banner_enabled, 9) \ -X(a, STATIC, SINGULAR, UINT32, ring_tone_id, 10) \ -X(a, STATIC, SINGULAR, UENUM, language, 11) \ -X(a, STATIC, OPTIONAL, MESSAGE, node_filter, 12) \ -X(a, STATIC, OPTIONAL, MESSAGE, node_highlight, 13) \ -X(a, STATIC, SINGULAR, BYTES, calibration_data, 14) \ -X(a, STATIC, OPTIONAL, MESSAGE, map_data, 15) \ -X(a, STATIC, SINGULAR, UENUM, compass_mode, 16) \ -X(a, STATIC, SINGULAR, UINT32, screen_rgb_color, 17) \ -X(a, STATIC, SINGULAR, BOOL, is_clockface_analog, 18) \ -X(a, STATIC, SINGULAR, UENUM, gps_format, 19) +#define meshtastic_DeviceUIConfig_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UINT32, version, 1) \ + X(a, STATIC, SINGULAR, UINT32, screen_brightness, 2) \ + X(a, STATIC, SINGULAR, UINT32, screen_timeout, 3) \ + X(a, STATIC, SINGULAR, BOOL, screen_lock, 4) \ + X(a, STATIC, SINGULAR, BOOL, settings_lock, 5) \ + X(a, STATIC, SINGULAR, UINT32, pin_code, 6) \ + X(a, STATIC, SINGULAR, UENUM, theme, 7) \ + X(a, STATIC, SINGULAR, BOOL, alert_enabled, 8) \ + X(a, STATIC, SINGULAR, BOOL, banner_enabled, 9) \ + X(a, STATIC, SINGULAR, UINT32, ring_tone_id, 10) \ + X(a, STATIC, SINGULAR, UENUM, language, 11) \ + X(a, STATIC, OPTIONAL, MESSAGE, node_filter, 12) \ + X(a, STATIC, OPTIONAL, MESSAGE, node_highlight, 13) \ + X(a, STATIC, SINGULAR, BYTES, calibration_data, 14) \ + X(a, STATIC, OPTIONAL, MESSAGE, map_data, 15) \ + X(a, STATIC, SINGULAR, UENUM, compass_mode, 16) \ + X(a, STATIC, SINGULAR, UINT32, screen_rgb_color, 17) \ + X(a, STATIC, SINGULAR, BOOL, is_clockface_analog, 18) \ + X(a, STATIC, SINGULAR, UENUM, gps_format, 19) #define meshtastic_DeviceUIConfig_CALLBACK NULL #define meshtastic_DeviceUIConfig_DEFAULT NULL #define meshtastic_DeviceUIConfig_node_filter_MSGTYPE meshtastic_NodeFilter #define meshtastic_DeviceUIConfig_node_highlight_MSGTYPE meshtastic_NodeHighlight #define meshtastic_DeviceUIConfig_map_data_MSGTYPE meshtastic_Map -#define meshtastic_NodeFilter_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, unknown_switch, 1) \ -X(a, STATIC, SINGULAR, BOOL, offline_switch, 2) \ -X(a, STATIC, SINGULAR, BOOL, public_key_switch, 3) \ -X(a, STATIC, SINGULAR, INT32, hops_away, 4) \ -X(a, STATIC, SINGULAR, BOOL, position_switch, 5) \ -X(a, STATIC, SINGULAR, STRING, node_name, 6) \ -X(a, STATIC, SINGULAR, INT32, channel, 7) +#define meshtastic_NodeFilter_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, BOOL, unknown_switch, 1) \ + X(a, STATIC, SINGULAR, BOOL, offline_switch, 2) \ + X(a, STATIC, SINGULAR, BOOL, public_key_switch, 3) \ + X(a, STATIC, SINGULAR, INT32, hops_away, 4) \ + X(a, STATIC, SINGULAR, BOOL, position_switch, 5) \ + X(a, STATIC, SINGULAR, STRING, node_name, 6) \ + X(a, STATIC, SINGULAR, INT32, channel, 7) #define meshtastic_NodeFilter_CALLBACK NULL #define meshtastic_NodeFilter_DEFAULT NULL -#define meshtastic_NodeHighlight_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, chat_switch, 1) \ -X(a, STATIC, SINGULAR, BOOL, position_switch, 2) \ -X(a, STATIC, SINGULAR, BOOL, telemetry_switch, 3) \ -X(a, STATIC, SINGULAR, BOOL, iaq_switch, 4) \ -X(a, STATIC, SINGULAR, STRING, node_name, 5) +#define meshtastic_NodeHighlight_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, BOOL, chat_switch, 1) \ + X(a, STATIC, SINGULAR, BOOL, position_switch, 2) \ + X(a, STATIC, SINGULAR, BOOL, telemetry_switch, 3) \ + X(a, STATIC, SINGULAR, BOOL, iaq_switch, 4) \ + X(a, STATIC, SINGULAR, STRING, node_name, 5) #define meshtastic_NodeHighlight_CALLBACK NULL #define meshtastic_NodeHighlight_DEFAULT NULL -#define meshtastic_GeoPoint_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, INT32, zoom, 1) \ -X(a, STATIC, SINGULAR, INT32, latitude, 2) \ -X(a, STATIC, SINGULAR, INT32, longitude, 3) +#define meshtastic_GeoPoint_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, INT32, zoom, 1) \ + X(a, STATIC, SINGULAR, INT32, latitude, 2) \ + X(a, STATIC, SINGULAR, INT32, longitude, 3) #define meshtastic_GeoPoint_CALLBACK NULL #define meshtastic_GeoPoint_DEFAULT NULL -#define meshtastic_Map_FIELDLIST(X, a) \ -X(a, STATIC, OPTIONAL, MESSAGE, home, 1) \ -X(a, STATIC, SINGULAR, STRING, style, 2) \ -X(a, STATIC, SINGULAR, BOOL, follow_gps, 3) +#define meshtastic_Map_FIELDLIST(X, a) \ + X(a, STATIC, OPTIONAL, MESSAGE, home, 1) \ + X(a, STATIC, SINGULAR, STRING, style, 2) \ + X(a, STATIC, SINGULAR, BOOL, follow_gps, 3) #define meshtastic_Map_CALLBACK NULL #define meshtastic_Map_DEFAULT NULL #define meshtastic_Map_home_MSGTYPE meshtastic_GeoPoint -extern const pb_msgdesc_t meshtastic_DeviceUIConfig_msg; -extern const pb_msgdesc_t meshtastic_NodeFilter_msg; -extern const pb_msgdesc_t meshtastic_NodeHighlight_msg; -extern const pb_msgdesc_t meshtastic_GeoPoint_msg; -extern const pb_msgdesc_t meshtastic_Map_msg; + extern const pb_msgdesc_t meshtastic_DeviceUIConfig_msg; + extern const pb_msgdesc_t meshtastic_NodeFilter_msg; + extern const pb_msgdesc_t meshtastic_NodeHighlight_msg; + extern const pb_msgdesc_t meshtastic_GeoPoint_msg; + extern const pb_msgdesc_t meshtastic_Map_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_DeviceUIConfig_fields &meshtastic_DeviceUIConfig_msg @@ -355,11 +389,11 @@ extern const pb_msgdesc_t meshtastic_Map_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_DEVICE_UI_PB_H_MAX_SIZE meshtastic_DeviceUIConfig_size -#define meshtastic_DeviceUIConfig_size 204 -#define meshtastic_GeoPoint_size 33 -#define meshtastic_Map_size 58 -#define meshtastic_NodeFilter_size 47 -#define meshtastic_NodeHighlight_size 25 +#define meshtastic_DeviceUIConfig_size 204 +#define meshtastic_GeoPoint_size 33 +#define meshtastic_Map_size 58 +#define meshtastic_NodeFilter_size 47 +#define meshtastic_NodeHighlight_size 25 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/deviceonly.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/deviceonly.pb.cpp index 5a969570..67fa6882 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/deviceonly.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/deviceonly.pb.cpp @@ -8,23 +8,14 @@ PB_BIND(meshtastic_PositionLite, meshtastic_PositionLite, AUTO) - PB_BIND(meshtastic_UserLite, meshtastic_UserLite, AUTO) - PB_BIND(meshtastic_NodeInfoLite, meshtastic_NodeInfoLite, AUTO) - PB_BIND(meshtastic_DeviceState, meshtastic_DeviceState, 2) - PB_BIND(meshtastic_NodeDatabase, meshtastic_NodeDatabase, AUTO) - PB_BIND(meshtastic_ChannelFile, meshtastic_ChannelFile, 2) - PB_BIND(meshtastic_BackupPreferences, meshtastic_BackupPreferences, 2) - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/deviceonly.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/deviceonly.pb.h index 7fab82ff..260fe5ee 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/deviceonly.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/deviceonly.pb.h @@ -3,13 +3,13 @@ #ifndef PB_MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_INCLUDED -#include -#include #include "meshtastic/channel.pb.h" #include "meshtastic/config.pb.h" #include "meshtastic/localonly.pb.h" #include "meshtastic/mesh.pb.h" #include "meshtastic/telemetry.pb.h" +#include +#include #if PB_PROTO_HEADER_VERSION != 40 #error Regenerate this file with the current version of nanopb generator. @@ -17,7 +17,8 @@ /* Struct definitions */ /* Position with static location information only for NodeDBLite */ -typedef struct _meshtastic_PositionLite { +typedef struct _meshtastic_PositionLite +{ /* The new preferred location encoding, multiply by 1e-7 to get degrees in floating point */ int32_t latitude_i; @@ -36,7 +37,8 @@ typedef struct _meshtastic_PositionLite { } meshtastic_PositionLite; typedef PB_BYTES_ARRAY_T(32) meshtastic_UserLite_public_key_t; -typedef struct _meshtastic_UserLite { +typedef struct _meshtastic_UserLite +{ /* This is the addr of the radio. */ pb_byte_t macaddr[6]; /* A full name for this user, i.e. "Kevin Hester" */ @@ -63,7 +65,8 @@ typedef struct _meshtastic_UserLite { bool is_unmessagable; } meshtastic_UserLite; -typedef struct _meshtastic_NodeInfoLite { +typedef struct _meshtastic_NodeInfoLite +{ /* The node number */ uint32_t num; /* The user info for this node */ @@ -106,7 +109,8 @@ typedef struct _meshtastic_NodeInfoLite { FIXME, since we write this each time we enter deep sleep (and have infinite flash) it would be better to use some sort of append only data structure for the receive queue and use the preferences store for the other stuff */ -typedef struct _meshtastic_DeviceState { +typedef struct _meshtastic_DeviceState +{ /* Read only settings/info about this node */ bool has_my_node; meshtastic_MyNodeInfo my_node; @@ -142,7 +146,8 @@ typedef struct _meshtastic_DeviceState { meshtastic_NodeRemoteHardwarePin node_remote_hardware_pins[12]; } meshtastic_DeviceState; -typedef struct _meshtastic_NodeDatabase { +typedef struct _meshtastic_NodeDatabase +{ /* A version integer used to invalidate old save files when we make incompatible changes This integer is set at build time and is private to NodeDB.cpp in the device code. */ @@ -152,7 +157,8 @@ typedef struct _meshtastic_NodeDatabase { } meshtastic_NodeDatabase; /* The on-disk saved channels */ -typedef struct _meshtastic_ChannelFile { +typedef struct _meshtastic_ChannelFile +{ /* The channels our node knows about */ pb_size_t channels_count; meshtastic_Channel channels[8]; @@ -163,7 +169,8 @@ typedef struct _meshtastic_ChannelFile { } meshtastic_ChannelFile; /* The on-disk backup of the node's preferences */ -typedef struct _meshtastic_BackupPreferences { +typedef struct _meshtastic_BackupPreferences +{ /* The version of the backup */ uint32_t version; /* The timestamp of the backup (if node has time) */ @@ -182,126 +189,168 @@ typedef struct _meshtastic_BackupPreferences { meshtastic_User owner; } meshtastic_BackupPreferences; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Initializer values for message structs */ -#define meshtastic_PositionLite_init_default {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN} -#define meshtastic_UserLite_init_default {{0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}, false, 0} -#define meshtastic_NodeInfoLite_init_default {0, false, meshtastic_UserLite_init_default, false, meshtastic_PositionLite_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0, 0, 0, 0} -#define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default, 0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}} -#define meshtastic_NodeDatabase_init_default {0, {0}} -#define meshtastic_ChannelFile_init_default {0, {meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default}, 0} -#define meshtastic_BackupPreferences_init_default {0, 0, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default, false, meshtastic_ChannelFile_init_default, false, meshtastic_User_init_default} -#define meshtastic_PositionLite_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN} -#define meshtastic_UserLite_init_zero {{0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}, false, 0} -#define meshtastic_NodeInfoLite_init_zero {0, false, meshtastic_UserLite_init_zero, false, meshtastic_PositionLite_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0, 0, 0, 0} -#define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero, 0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}} -#define meshtastic_NodeDatabase_init_zero {0, {0}} -#define meshtastic_ChannelFile_init_zero {0, {meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero}, 0} -#define meshtastic_BackupPreferences_init_zero {0, 0, false, meshtastic_LocalConfig_init_zero, false, meshtastic_LocalModuleConfig_init_zero, false, meshtastic_ChannelFile_init_zero, false, meshtastic_User_init_zero} +#define meshtastic_PositionLite_init_default \ + { \ + 0, 0, 0, 0, _meshtastic_Position_LocSource_MIN \ + } +#define meshtastic_UserLite_init_default \ + { \ + {0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}, false, 0 \ + } +#define meshtastic_NodeInfoLite_init_default \ + { \ + 0, false, meshtastic_UserLite_init_default, false, meshtastic_PositionLite_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0, 0, 0, 0 \ + } +#define meshtastic_DeviceState_init_default \ + { \ + false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default, 0, { meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default } \ + } +#define meshtastic_NodeDatabase_init_default \ + { \ + 0, { 0 } \ + } +#define meshtastic_ChannelFile_init_default \ + { \ + 0, {meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default}, 0 \ + } +#define meshtastic_BackupPreferences_init_default \ + { \ + 0, 0, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default, false, meshtastic_ChannelFile_init_default, false, meshtastic_User_init_default \ + } +#define meshtastic_PositionLite_init_zero \ + { \ + 0, 0, 0, 0, _meshtastic_Position_LocSource_MIN \ + } +#define meshtastic_UserLite_init_zero \ + { \ + {0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}, false, 0 \ + } +#define meshtastic_NodeInfoLite_init_zero \ + { \ + 0, false, meshtastic_UserLite_init_zero, false, meshtastic_PositionLite_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0, 0, 0, 0 \ + } +#define meshtastic_DeviceState_init_zero \ + { \ + false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero, 0, { meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero } \ + } +#define meshtastic_NodeDatabase_init_zero \ + { \ + 0, { 0 } \ + } +#define meshtastic_ChannelFile_init_zero \ + { \ + 0, {meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero}, 0 \ + } +#define meshtastic_BackupPreferences_init_zero \ + { \ + 0, 0, false, meshtastic_LocalConfig_init_zero, false, meshtastic_LocalModuleConfig_init_zero, false, meshtastic_ChannelFile_init_zero, false, meshtastic_User_init_zero \ + } /* Field tags (for use in manual encoding/decoding) */ -#define meshtastic_PositionLite_latitude_i_tag 1 -#define meshtastic_PositionLite_longitude_i_tag 2 -#define meshtastic_PositionLite_altitude_tag 3 -#define meshtastic_PositionLite_time_tag 4 +#define meshtastic_PositionLite_latitude_i_tag 1 +#define meshtastic_PositionLite_longitude_i_tag 2 +#define meshtastic_PositionLite_altitude_tag 3 +#define meshtastic_PositionLite_time_tag 4 #define meshtastic_PositionLite_location_source_tag 5 -#define meshtastic_UserLite_macaddr_tag 1 -#define meshtastic_UserLite_long_name_tag 2 -#define meshtastic_UserLite_short_name_tag 3 -#define meshtastic_UserLite_hw_model_tag 4 -#define meshtastic_UserLite_is_licensed_tag 5 -#define meshtastic_UserLite_role_tag 6 -#define meshtastic_UserLite_public_key_tag 7 -#define meshtastic_UserLite_is_unmessagable_tag 9 -#define meshtastic_NodeInfoLite_num_tag 1 -#define meshtastic_NodeInfoLite_user_tag 2 -#define meshtastic_NodeInfoLite_position_tag 3 -#define meshtastic_NodeInfoLite_snr_tag 4 -#define meshtastic_NodeInfoLite_last_heard_tag 5 +#define meshtastic_UserLite_macaddr_tag 1 +#define meshtastic_UserLite_long_name_tag 2 +#define meshtastic_UserLite_short_name_tag 3 +#define meshtastic_UserLite_hw_model_tag 4 +#define meshtastic_UserLite_is_licensed_tag 5 +#define meshtastic_UserLite_role_tag 6 +#define meshtastic_UserLite_public_key_tag 7 +#define meshtastic_UserLite_is_unmessagable_tag 9 +#define meshtastic_NodeInfoLite_num_tag 1 +#define meshtastic_NodeInfoLite_user_tag 2 +#define meshtastic_NodeInfoLite_position_tag 3 +#define meshtastic_NodeInfoLite_snr_tag 4 +#define meshtastic_NodeInfoLite_last_heard_tag 5 #define meshtastic_NodeInfoLite_device_metrics_tag 6 -#define meshtastic_NodeInfoLite_channel_tag 7 -#define meshtastic_NodeInfoLite_via_mqtt_tag 8 -#define meshtastic_NodeInfoLite_hops_away_tag 9 -#define meshtastic_NodeInfoLite_is_favorite_tag 10 -#define meshtastic_NodeInfoLite_is_ignored_tag 11 -#define meshtastic_NodeInfoLite_next_hop_tag 12 -#define meshtastic_NodeInfoLite_bitfield_tag 13 -#define meshtastic_DeviceState_my_node_tag 2 -#define meshtastic_DeviceState_owner_tag 3 +#define meshtastic_NodeInfoLite_channel_tag 7 +#define meshtastic_NodeInfoLite_via_mqtt_tag 8 +#define meshtastic_NodeInfoLite_hops_away_tag 9 +#define meshtastic_NodeInfoLite_is_favorite_tag 10 +#define meshtastic_NodeInfoLite_is_ignored_tag 11 +#define meshtastic_NodeInfoLite_next_hop_tag 12 +#define meshtastic_NodeInfoLite_bitfield_tag 13 +#define meshtastic_DeviceState_my_node_tag 2 +#define meshtastic_DeviceState_owner_tag 3 #define meshtastic_DeviceState_receive_queue_tag 5 #define meshtastic_DeviceState_rx_text_message_tag 7 -#define meshtastic_DeviceState_version_tag 8 -#define meshtastic_DeviceState_no_save_tag 9 +#define meshtastic_DeviceState_version_tag 8 +#define meshtastic_DeviceState_no_save_tag 9 #define meshtastic_DeviceState_did_gps_reset_tag 11 -#define meshtastic_DeviceState_rx_waypoint_tag 12 +#define meshtastic_DeviceState_rx_waypoint_tag 12 #define meshtastic_DeviceState_node_remote_hardware_pins_tag 13 -#define meshtastic_NodeDatabase_version_tag 1 -#define meshtastic_NodeDatabase_nodes_tag 2 -#define meshtastic_ChannelFile_channels_tag 1 -#define meshtastic_ChannelFile_version_tag 2 +#define meshtastic_NodeDatabase_version_tag 1 +#define meshtastic_NodeDatabase_nodes_tag 2 +#define meshtastic_ChannelFile_channels_tag 1 +#define meshtastic_ChannelFile_version_tag 2 #define meshtastic_BackupPreferences_version_tag 1 #define meshtastic_BackupPreferences_timestamp_tag 2 -#define meshtastic_BackupPreferences_config_tag 3 +#define meshtastic_BackupPreferences_config_tag 3 #define meshtastic_BackupPreferences_module_config_tag 4 #define meshtastic_BackupPreferences_channels_tag 5 -#define meshtastic_BackupPreferences_owner_tag 6 +#define meshtastic_BackupPreferences_owner_tag 6 /* Struct field encoding specification for nanopb */ -#define meshtastic_PositionLite_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, SFIXED32, latitude_i, 1) \ -X(a, STATIC, SINGULAR, SFIXED32, longitude_i, 2) \ -X(a, STATIC, SINGULAR, INT32, altitude, 3) \ -X(a, STATIC, SINGULAR, FIXED32, time, 4) \ -X(a, STATIC, SINGULAR, UENUM, location_source, 5) +#define meshtastic_PositionLite_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, SFIXED32, latitude_i, 1) \ + X(a, STATIC, SINGULAR, SFIXED32, longitude_i, 2) \ + X(a, STATIC, SINGULAR, INT32, altitude, 3) \ + X(a, STATIC, SINGULAR, FIXED32, time, 4) \ + X(a, STATIC, SINGULAR, UENUM, location_source, 5) #define meshtastic_PositionLite_CALLBACK NULL #define meshtastic_PositionLite_DEFAULT NULL -#define meshtastic_UserLite_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, FIXED_LENGTH_BYTES, macaddr, 1) \ -X(a, STATIC, SINGULAR, STRING, long_name, 2) \ -X(a, STATIC, SINGULAR, STRING, short_name, 3) \ -X(a, STATIC, SINGULAR, UENUM, hw_model, 4) \ -X(a, STATIC, SINGULAR, BOOL, is_licensed, 5) \ -X(a, STATIC, SINGULAR, UENUM, role, 6) \ -X(a, STATIC, SINGULAR, BYTES, public_key, 7) \ -X(a, STATIC, OPTIONAL, BOOL, is_unmessagable, 9) +#define meshtastic_UserLite_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, FIXED_LENGTH_BYTES, macaddr, 1) \ + X(a, STATIC, SINGULAR, STRING, long_name, 2) \ + X(a, STATIC, SINGULAR, STRING, short_name, 3) \ + X(a, STATIC, SINGULAR, UENUM, hw_model, 4) \ + X(a, STATIC, SINGULAR, BOOL, is_licensed, 5) \ + X(a, STATIC, SINGULAR, UENUM, role, 6) \ + X(a, STATIC, SINGULAR, BYTES, public_key, 7) \ + X(a, STATIC, OPTIONAL, BOOL, is_unmessagable, 9) #define meshtastic_UserLite_CALLBACK NULL #define meshtastic_UserLite_DEFAULT NULL -#define meshtastic_NodeInfoLite_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, num, 1) \ -X(a, STATIC, OPTIONAL, MESSAGE, user, 2) \ -X(a, STATIC, OPTIONAL, MESSAGE, position, 3) \ -X(a, STATIC, SINGULAR, FLOAT, snr, 4) \ -X(a, STATIC, SINGULAR, FIXED32, last_heard, 5) \ -X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6) \ -X(a, STATIC, SINGULAR, UINT32, channel, 7) \ -X(a, STATIC, SINGULAR, BOOL, via_mqtt, 8) \ -X(a, STATIC, OPTIONAL, UINT32, hops_away, 9) \ -X(a, STATIC, SINGULAR, BOOL, is_favorite, 10) \ -X(a, STATIC, SINGULAR, BOOL, is_ignored, 11) \ -X(a, STATIC, SINGULAR, UINT32, next_hop, 12) \ -X(a, STATIC, SINGULAR, UINT32, bitfield, 13) +#define meshtastic_NodeInfoLite_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UINT32, num, 1) \ + X(a, STATIC, OPTIONAL, MESSAGE, user, 2) \ + X(a, STATIC, OPTIONAL, MESSAGE, position, 3) \ + X(a, STATIC, SINGULAR, FLOAT, snr, 4) \ + X(a, STATIC, SINGULAR, FIXED32, last_heard, 5) \ + X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6) \ + X(a, STATIC, SINGULAR, UINT32, channel, 7) \ + X(a, STATIC, SINGULAR, BOOL, via_mqtt, 8) \ + X(a, STATIC, OPTIONAL, UINT32, hops_away, 9) \ + X(a, STATIC, SINGULAR, BOOL, is_favorite, 10) \ + X(a, STATIC, SINGULAR, BOOL, is_ignored, 11) \ + X(a, STATIC, SINGULAR, UINT32, next_hop, 12) \ + X(a, STATIC, SINGULAR, UINT32, bitfield, 13) #define meshtastic_NodeInfoLite_CALLBACK NULL #define meshtastic_NodeInfoLite_DEFAULT NULL #define meshtastic_NodeInfoLite_user_MSGTYPE meshtastic_UserLite #define meshtastic_NodeInfoLite_position_MSGTYPE meshtastic_PositionLite #define meshtastic_NodeInfoLite_device_metrics_MSGTYPE meshtastic_DeviceMetrics -#define meshtastic_DeviceState_FIELDLIST(X, a) \ -X(a, STATIC, OPTIONAL, MESSAGE, my_node, 2) \ -X(a, STATIC, OPTIONAL, MESSAGE, owner, 3) \ -X(a, STATIC, REPEATED, MESSAGE, receive_queue, 5) \ -X(a, STATIC, OPTIONAL, MESSAGE, rx_text_message, 7) \ -X(a, STATIC, SINGULAR, UINT32, version, 8) \ -X(a, STATIC, SINGULAR, BOOL, no_save, 9) \ -X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 11) \ -X(a, STATIC, OPTIONAL, MESSAGE, rx_waypoint, 12) \ -X(a, STATIC, REPEATED, MESSAGE, node_remote_hardware_pins, 13) +#define meshtastic_DeviceState_FIELDLIST(X, a) \ + X(a, STATIC, OPTIONAL, MESSAGE, my_node, 2) \ + X(a, STATIC, OPTIONAL, MESSAGE, owner, 3) \ + X(a, STATIC, REPEATED, MESSAGE, receive_queue, 5) \ + X(a, STATIC, OPTIONAL, MESSAGE, rx_text_message, 7) \ + X(a, STATIC, SINGULAR, UINT32, version, 8) \ + X(a, STATIC, SINGULAR, BOOL, no_save, 9) \ + X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 11) \ + X(a, STATIC, OPTIONAL, MESSAGE, rx_waypoint, 12) \ + X(a, STATIC, REPEATED, MESSAGE, node_remote_hardware_pins, 13) #define meshtastic_DeviceState_CALLBACK NULL #define meshtastic_DeviceState_DEFAULT NULL #define meshtastic_DeviceState_my_node_MSGTYPE meshtastic_MyNodeInfo @@ -312,27 +361,27 @@ X(a, STATIC, REPEATED, MESSAGE, node_remote_hardware_pins, 13) #define meshtastic_DeviceState_node_remote_hardware_pins_MSGTYPE meshtastic_NodeRemoteHardwarePin #define meshtastic_NodeDatabase_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, version, 1) \ -X(a, CALLBACK, REPEATED, MESSAGE, nodes, 2) -extern bool meshtastic_NodeDatabase_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_t *field); + X(a, STATIC, SINGULAR, UINT32, version, 1) \ + X(a, CALLBACK, REPEATED, MESSAGE, nodes, 2) + extern bool meshtastic_NodeDatabase_callback(pb_istream_t* istream, pb_ostream_t* ostream, const pb_field_t* field); #define meshtastic_NodeDatabase_CALLBACK meshtastic_NodeDatabase_callback #define meshtastic_NodeDatabase_DEFAULT NULL #define meshtastic_NodeDatabase_nodes_MSGTYPE meshtastic_NodeInfoLite -#define meshtastic_ChannelFile_FIELDLIST(X, a) \ -X(a, STATIC, REPEATED, MESSAGE, channels, 1) \ -X(a, STATIC, SINGULAR, UINT32, version, 2) +#define meshtastic_ChannelFile_FIELDLIST(X, a) \ + X(a, STATIC, REPEATED, MESSAGE, channels, 1) \ + X(a, STATIC, SINGULAR, UINT32, version, 2) #define meshtastic_ChannelFile_CALLBACK NULL #define meshtastic_ChannelFile_DEFAULT NULL #define meshtastic_ChannelFile_channels_MSGTYPE meshtastic_Channel -#define meshtastic_BackupPreferences_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, version, 1) \ -X(a, STATIC, SINGULAR, FIXED32, timestamp, 2) \ -X(a, STATIC, OPTIONAL, MESSAGE, config, 3) \ -X(a, STATIC, OPTIONAL, MESSAGE, module_config, 4) \ -X(a, STATIC, OPTIONAL, MESSAGE, channels, 5) \ -X(a, STATIC, OPTIONAL, MESSAGE, owner, 6) +#define meshtastic_BackupPreferences_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UINT32, version, 1) \ + X(a, STATIC, SINGULAR, FIXED32, timestamp, 2) \ + X(a, STATIC, OPTIONAL, MESSAGE, config, 3) \ + X(a, STATIC, OPTIONAL, MESSAGE, module_config, 4) \ + X(a, STATIC, OPTIONAL, MESSAGE, channels, 5) \ + X(a, STATIC, OPTIONAL, MESSAGE, owner, 6) #define meshtastic_BackupPreferences_CALLBACK NULL #define meshtastic_BackupPreferences_DEFAULT NULL #define meshtastic_BackupPreferences_config_MSGTYPE meshtastic_LocalConfig @@ -340,13 +389,13 @@ X(a, STATIC, OPTIONAL, MESSAGE, owner, 6) #define meshtastic_BackupPreferences_channels_MSGTYPE meshtastic_ChannelFile #define meshtastic_BackupPreferences_owner_MSGTYPE meshtastic_User -extern const pb_msgdesc_t meshtastic_PositionLite_msg; -extern const pb_msgdesc_t meshtastic_UserLite_msg; -extern const pb_msgdesc_t meshtastic_NodeInfoLite_msg; -extern const pb_msgdesc_t meshtastic_DeviceState_msg; -extern const pb_msgdesc_t meshtastic_NodeDatabase_msg; -extern const pb_msgdesc_t meshtastic_ChannelFile_msg; -extern const pb_msgdesc_t meshtastic_BackupPreferences_msg; + extern const pb_msgdesc_t meshtastic_PositionLite_msg; + extern const pb_msgdesc_t meshtastic_UserLite_msg; + extern const pb_msgdesc_t meshtastic_NodeInfoLite_msg; + extern const pb_msgdesc_t meshtastic_DeviceState_msg; + extern const pb_msgdesc_t meshtastic_NodeDatabase_msg; + extern const pb_msgdesc_t meshtastic_ChannelFile_msg; + extern const pb_msgdesc_t meshtastic_BackupPreferences_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_PositionLite_fields &meshtastic_PositionLite_msg @@ -360,12 +409,12 @@ extern const pb_msgdesc_t meshtastic_BackupPreferences_msg; /* Maximum encoded size of messages (where known) */ /* meshtastic_NodeDatabase_size depends on runtime parameters */ #define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_BackupPreferences_size -#define meshtastic_BackupPreferences_size 2277 -#define meshtastic_ChannelFile_size 718 -#define meshtastic_DeviceState_size 1737 -#define meshtastic_NodeInfoLite_size 196 -#define meshtastic_PositionLite_size 28 -#define meshtastic_UserLite_size 98 +#define meshtastic_BackupPreferences_size 2277 +#define meshtastic_ChannelFile_size 718 +#define meshtastic_DeviceState_size 1737 +#define meshtastic_NodeInfoLite_size 196 +#define meshtastic_PositionLite_size 28 +#define meshtastic_UserLite_size 98 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/interdevice.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/interdevice.pb.cpp index e3913f78..4552284b 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/interdevice.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/interdevice.pb.cpp @@ -8,10 +8,4 @@ PB_BIND(meshtastic_SensorData, meshtastic_SensorData, AUTO) - PB_BIND(meshtastic_InterdeviceMessage, meshtastic_InterdeviceMessage, 2) - - - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/interdevice.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/interdevice.pb.h index c381438e..25f9e206 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/interdevice.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/interdevice.pb.h @@ -10,11 +10,12 @@ #endif /* Enum definitions */ -typedef enum _meshtastic_MessageType { +typedef enum _meshtastic_MessageType +{ meshtastic_MessageType_ACK = 0, meshtastic_MessageType_COLLECT_INTERVAL = 160, /* in ms */ - meshtastic_MessageType_BEEP_ON = 161, /* duration ms */ - meshtastic_MessageType_BEEP_OFF = 162, /* cancel prematurely */ + meshtastic_MessageType_BEEP_ON = 161, /* duration ms */ + meshtastic_MessageType_BEEP_OFF = 162, /* cancel prematurely */ meshtastic_MessageType_SHUTDOWN = 163, meshtastic_MessageType_POWER_ON = 164, meshtastic_MessageType_SCD41_TEMP = 176, @@ -26,68 +27,82 @@ typedef enum _meshtastic_MessageType { } meshtastic_MessageType; /* Struct definitions */ -typedef struct _meshtastic_SensorData { +typedef struct _meshtastic_SensorData +{ /* The message type */ meshtastic_MessageType type; pb_size_t which_data; - union { + union + { float float_value; uint32_t uint32_value; } data; } meshtastic_SensorData; -typedef struct _meshtastic_InterdeviceMessage { +typedef struct _meshtastic_InterdeviceMessage +{ pb_size_t which_data; - union { + union + { char nmea[1024]; meshtastic_SensorData sensor; } data; } meshtastic_InterdeviceMessage; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Helper constants for enums */ #define _meshtastic_MessageType_MIN meshtastic_MessageType_ACK #define _meshtastic_MessageType_MAX meshtastic_MessageType_TVOC_INDEX -#define _meshtastic_MessageType_ARRAYSIZE ((meshtastic_MessageType)(meshtastic_MessageType_TVOC_INDEX+1)) +#define _meshtastic_MessageType_ARRAYSIZE ((meshtastic_MessageType)(meshtastic_MessageType_TVOC_INDEX + 1)) #define meshtastic_SensorData_type_ENUMTYPE meshtastic_MessageType - - /* Initializer values for message structs */ -#define meshtastic_SensorData_init_default {_meshtastic_MessageType_MIN, 0, {0}} -#define meshtastic_InterdeviceMessage_init_default {0, {""}} -#define meshtastic_SensorData_init_zero {_meshtastic_MessageType_MIN, 0, {0}} -#define meshtastic_InterdeviceMessage_init_zero {0, {""}} +#define meshtastic_SensorData_init_default \ + { \ + _meshtastic_MessageType_MIN, 0, { 0 } \ + } +#define meshtastic_InterdeviceMessage_init_default \ + { \ + 0, { "" } \ + } +#define meshtastic_SensorData_init_zero \ + { \ + _meshtastic_MessageType_MIN, 0, { 0 } \ + } +#define meshtastic_InterdeviceMessage_init_zero \ + { \ + 0, { "" } \ + } /* Field tags (for use in manual encoding/decoding) */ -#define meshtastic_SensorData_type_tag 1 -#define meshtastic_SensorData_float_value_tag 2 -#define meshtastic_SensorData_uint32_value_tag 3 -#define meshtastic_InterdeviceMessage_nmea_tag 1 +#define meshtastic_SensorData_type_tag 1 +#define meshtastic_SensorData_float_value_tag 2 +#define meshtastic_SensorData_uint32_value_tag 3 +#define meshtastic_InterdeviceMessage_nmea_tag 1 #define meshtastic_InterdeviceMessage_sensor_tag 2 /* Struct field encoding specification for nanopb */ -#define meshtastic_SensorData_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UENUM, type, 1) \ -X(a, STATIC, ONEOF, FLOAT, (data,float_value,data.float_value), 2) \ -X(a, STATIC, ONEOF, UINT32, (data,uint32_value,data.uint32_value), 3) +#define meshtastic_SensorData_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UENUM, type, 1) \ + X(a, STATIC, ONEOF, FLOAT, (data, float_value, data.float_value), 2) \ + X(a, STATIC, ONEOF, UINT32, (data, uint32_value, data.uint32_value), 3) #define meshtastic_SensorData_CALLBACK NULL #define meshtastic_SensorData_DEFAULT NULL -#define meshtastic_InterdeviceMessage_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, STRING, (data,nmea,data.nmea), 1) \ -X(a, STATIC, ONEOF, MESSAGE, (data,sensor,data.sensor), 2) +#define meshtastic_InterdeviceMessage_FIELDLIST(X, a) \ + X(a, STATIC, ONEOF, STRING, (data, nmea, data.nmea), 1) \ + X(a, STATIC, ONEOF, MESSAGE, (data, sensor, data.sensor), 2) #define meshtastic_InterdeviceMessage_CALLBACK NULL #define meshtastic_InterdeviceMessage_DEFAULT NULL #define meshtastic_InterdeviceMessage_data_sensor_MSGTYPE meshtastic_SensorData -extern const pb_msgdesc_t meshtastic_SensorData_msg; -extern const pb_msgdesc_t meshtastic_InterdeviceMessage_msg; + extern const pb_msgdesc_t meshtastic_SensorData_msg; + extern const pb_msgdesc_t meshtastic_InterdeviceMessage_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_SensorData_fields &meshtastic_SensorData_msg @@ -95,8 +110,8 @@ extern const pb_msgdesc_t meshtastic_InterdeviceMessage_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_INTERDEVICE_PB_H_MAX_SIZE meshtastic_InterdeviceMessage_size -#define meshtastic_InterdeviceMessage_size 1026 -#define meshtastic_SensorData_size 9 +#define meshtastic_InterdeviceMessage_size 1026 +#define meshtastic_SensorData_size 9 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/localonly.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/localonly.pb.cpp index 34391df7..d9a1f83b 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/localonly.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/localonly.pb.cpp @@ -8,8 +8,4 @@ PB_BIND(meshtastic_LocalConfig, meshtastic_LocalConfig, 2) - PB_BIND(meshtastic_LocalModuleConfig, meshtastic_LocalModuleConfig, 2) - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/localonly.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/localonly.pb.h index 3ab6f02c..d9febad4 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/localonly.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/localonly.pb.h @@ -3,16 +3,17 @@ #ifndef PB_MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_INCLUDED -#include #include "meshtastic/config.pb.h" #include "meshtastic/module_config.pb.h" +#include #if PB_PROTO_HEADER_VERSION != 40 #error Regenerate this file with the current version of nanopb generator. #endif /* Struct definitions */ -typedef struct _meshtastic_LocalConfig { +typedef struct _meshtastic_LocalConfig +{ /* The part of the config that is specific to the Device */ bool has_device; meshtastic_Config_DeviceConfig device; @@ -43,7 +44,8 @@ typedef struct _meshtastic_LocalConfig { meshtastic_Config_SecurityConfig security; } meshtastic_LocalConfig; -typedef struct _meshtastic_LocalModuleConfig { +typedef struct _meshtastic_LocalModuleConfig +{ /* The part of the config that is specific to the MQTT module */ bool has_mqtt; meshtastic_ModuleConfig_MQTTConfig mqtt; @@ -89,36 +91,48 @@ typedef struct _meshtastic_LocalModuleConfig { meshtastic_ModuleConfig_PaxcounterConfig paxcounter; } meshtastic_LocalModuleConfig; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Initializer values for message structs */ -#define meshtastic_LocalConfig_init_default {false, meshtastic_Config_DeviceConfig_init_default, false, meshtastic_Config_PositionConfig_init_default, false, meshtastic_Config_PowerConfig_init_default, false, meshtastic_Config_NetworkConfig_init_default, false, meshtastic_Config_DisplayConfig_init_default, false, meshtastic_Config_LoRaConfig_init_default, false, meshtastic_Config_BluetoothConfig_init_default, 0, false, meshtastic_Config_SecurityConfig_init_default} -#define meshtastic_LocalModuleConfig_init_default {false, meshtastic_ModuleConfig_MQTTConfig_init_default, false, meshtastic_ModuleConfig_SerialConfig_init_default, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_default, false, meshtastic_ModuleConfig_StoreForwardConfig_init_default, false, meshtastic_ModuleConfig_RangeTestConfig_init_default, false, meshtastic_ModuleConfig_TelemetryConfig_init_default, false, meshtastic_ModuleConfig_CannedMessageConfig_init_default, 0, false, meshtastic_ModuleConfig_AudioConfig_init_default, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_default, false, meshtastic_ModuleConfig_NeighborInfoConfig_init_default, false, meshtastic_ModuleConfig_AmbientLightingConfig_init_default, false, meshtastic_ModuleConfig_DetectionSensorConfig_init_default, false, meshtastic_ModuleConfig_PaxcounterConfig_init_default} -#define meshtastic_LocalConfig_init_zero {false, meshtastic_Config_DeviceConfig_init_zero, false, meshtastic_Config_PositionConfig_init_zero, false, meshtastic_Config_PowerConfig_init_zero, false, meshtastic_Config_NetworkConfig_init_zero, false, meshtastic_Config_DisplayConfig_init_zero, false, meshtastic_Config_LoRaConfig_init_zero, false, meshtastic_Config_BluetoothConfig_init_zero, 0, false, meshtastic_Config_SecurityConfig_init_zero} -#define meshtastic_LocalModuleConfig_init_zero {false, meshtastic_ModuleConfig_MQTTConfig_init_zero, false, meshtastic_ModuleConfig_SerialConfig_init_zero, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero, false, meshtastic_ModuleConfig_StoreForwardConfig_init_zero, false, meshtastic_ModuleConfig_RangeTestConfig_init_zero, false, meshtastic_ModuleConfig_TelemetryConfig_init_zero, false, meshtastic_ModuleConfig_CannedMessageConfig_init_zero, 0, false, meshtastic_ModuleConfig_AudioConfig_init_zero, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero, false, meshtastic_ModuleConfig_NeighborInfoConfig_init_zero, false, meshtastic_ModuleConfig_AmbientLightingConfig_init_zero, false, meshtastic_ModuleConfig_DetectionSensorConfig_init_zero, false, meshtastic_ModuleConfig_PaxcounterConfig_init_zero} +#define meshtastic_LocalConfig_init_default \ + { \ + false, meshtastic_Config_DeviceConfig_init_default, false, meshtastic_Config_PositionConfig_init_default, false, meshtastic_Config_PowerConfig_init_default, false, meshtastic_Config_NetworkConfig_init_default, false, meshtastic_Config_DisplayConfig_init_default, false, meshtastic_Config_LoRaConfig_init_default, false, meshtastic_Config_BluetoothConfig_init_default, 0, false, meshtastic_Config_SecurityConfig_init_default \ + } +#define meshtastic_LocalModuleConfig_init_default \ + { \ + false, meshtastic_ModuleConfig_MQTTConfig_init_default, false, meshtastic_ModuleConfig_SerialConfig_init_default, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_default, false, meshtastic_ModuleConfig_StoreForwardConfig_init_default, false, meshtastic_ModuleConfig_RangeTestConfig_init_default, false, meshtastic_ModuleConfig_TelemetryConfig_init_default, false, meshtastic_ModuleConfig_CannedMessageConfig_init_default, 0, false, meshtastic_ModuleConfig_AudioConfig_init_default, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_default, false, meshtastic_ModuleConfig_NeighborInfoConfig_init_default, false, meshtastic_ModuleConfig_AmbientLightingConfig_init_default, false, meshtastic_ModuleConfig_DetectionSensorConfig_init_default, false, meshtastic_ModuleConfig_PaxcounterConfig_init_default \ + } +#define meshtastic_LocalConfig_init_zero \ + { \ + false, meshtastic_Config_DeviceConfig_init_zero, false, meshtastic_Config_PositionConfig_init_zero, false, meshtastic_Config_PowerConfig_init_zero, false, meshtastic_Config_NetworkConfig_init_zero, false, meshtastic_Config_DisplayConfig_init_zero, false, meshtastic_Config_LoRaConfig_init_zero, false, meshtastic_Config_BluetoothConfig_init_zero, 0, false, meshtastic_Config_SecurityConfig_init_zero \ + } +#define meshtastic_LocalModuleConfig_init_zero \ + { \ + false, meshtastic_ModuleConfig_MQTTConfig_init_zero, false, meshtastic_ModuleConfig_SerialConfig_init_zero, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero, false, meshtastic_ModuleConfig_StoreForwardConfig_init_zero, false, meshtastic_ModuleConfig_RangeTestConfig_init_zero, false, meshtastic_ModuleConfig_TelemetryConfig_init_zero, false, meshtastic_ModuleConfig_CannedMessageConfig_init_zero, 0, false, meshtastic_ModuleConfig_AudioConfig_init_zero, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero, false, meshtastic_ModuleConfig_NeighborInfoConfig_init_zero, false, meshtastic_ModuleConfig_AmbientLightingConfig_init_zero, false, meshtastic_ModuleConfig_DetectionSensorConfig_init_zero, false, meshtastic_ModuleConfig_PaxcounterConfig_init_zero \ + } /* Field tags (for use in manual encoding/decoding) */ -#define meshtastic_LocalConfig_device_tag 1 -#define meshtastic_LocalConfig_position_tag 2 -#define meshtastic_LocalConfig_power_tag 3 -#define meshtastic_LocalConfig_network_tag 4 -#define meshtastic_LocalConfig_display_tag 5 -#define meshtastic_LocalConfig_lora_tag 6 -#define meshtastic_LocalConfig_bluetooth_tag 7 -#define meshtastic_LocalConfig_version_tag 8 -#define meshtastic_LocalConfig_security_tag 9 -#define meshtastic_LocalModuleConfig_mqtt_tag 1 -#define meshtastic_LocalModuleConfig_serial_tag 2 +#define meshtastic_LocalConfig_device_tag 1 +#define meshtastic_LocalConfig_position_tag 2 +#define meshtastic_LocalConfig_power_tag 3 +#define meshtastic_LocalConfig_network_tag 4 +#define meshtastic_LocalConfig_display_tag 5 +#define meshtastic_LocalConfig_lora_tag 6 +#define meshtastic_LocalConfig_bluetooth_tag 7 +#define meshtastic_LocalConfig_version_tag 8 +#define meshtastic_LocalConfig_security_tag 9 +#define meshtastic_LocalModuleConfig_mqtt_tag 1 +#define meshtastic_LocalModuleConfig_serial_tag 2 #define meshtastic_LocalModuleConfig_external_notification_tag 3 #define meshtastic_LocalModuleConfig_store_forward_tag 4 #define meshtastic_LocalModuleConfig_range_test_tag 5 #define meshtastic_LocalModuleConfig_telemetry_tag 6 #define meshtastic_LocalModuleConfig_canned_message_tag 7 #define meshtastic_LocalModuleConfig_version_tag 8 -#define meshtastic_LocalModuleConfig_audio_tag 9 +#define meshtastic_LocalModuleConfig_audio_tag 9 #define meshtastic_LocalModuleConfig_remote_hardware_tag 10 #define meshtastic_LocalModuleConfig_neighbor_info_tag 11 #define meshtastic_LocalModuleConfig_ambient_lighting_tag 12 @@ -126,16 +140,16 @@ extern "C" { #define meshtastic_LocalModuleConfig_paxcounter_tag 14 /* Struct field encoding specification for nanopb */ -#define meshtastic_LocalConfig_FIELDLIST(X, a) \ -X(a, STATIC, OPTIONAL, MESSAGE, device, 1) \ -X(a, STATIC, OPTIONAL, MESSAGE, position, 2) \ -X(a, STATIC, OPTIONAL, MESSAGE, power, 3) \ -X(a, STATIC, OPTIONAL, MESSAGE, network, 4) \ -X(a, STATIC, OPTIONAL, MESSAGE, display, 5) \ -X(a, STATIC, OPTIONAL, MESSAGE, lora, 6) \ -X(a, STATIC, OPTIONAL, MESSAGE, bluetooth, 7) \ -X(a, STATIC, SINGULAR, UINT32, version, 8) \ -X(a, STATIC, OPTIONAL, MESSAGE, security, 9) +#define meshtastic_LocalConfig_FIELDLIST(X, a) \ + X(a, STATIC, OPTIONAL, MESSAGE, device, 1) \ + X(a, STATIC, OPTIONAL, MESSAGE, position, 2) \ + X(a, STATIC, OPTIONAL, MESSAGE, power, 3) \ + X(a, STATIC, OPTIONAL, MESSAGE, network, 4) \ + X(a, STATIC, OPTIONAL, MESSAGE, display, 5) \ + X(a, STATIC, OPTIONAL, MESSAGE, lora, 6) \ + X(a, STATIC, OPTIONAL, MESSAGE, bluetooth, 7) \ + X(a, STATIC, SINGULAR, UINT32, version, 8) \ + X(a, STATIC, OPTIONAL, MESSAGE, security, 9) #define meshtastic_LocalConfig_CALLBACK NULL #define meshtastic_LocalConfig_DEFAULT NULL #define meshtastic_LocalConfig_device_MSGTYPE meshtastic_Config_DeviceConfig @@ -147,21 +161,21 @@ X(a, STATIC, OPTIONAL, MESSAGE, security, 9) #define meshtastic_LocalConfig_bluetooth_MSGTYPE meshtastic_Config_BluetoothConfig #define meshtastic_LocalConfig_security_MSGTYPE meshtastic_Config_SecurityConfig -#define meshtastic_LocalModuleConfig_FIELDLIST(X, a) \ -X(a, STATIC, OPTIONAL, MESSAGE, mqtt, 1) \ -X(a, STATIC, OPTIONAL, MESSAGE, serial, 2) \ -X(a, STATIC, OPTIONAL, MESSAGE, external_notification, 3) \ -X(a, STATIC, OPTIONAL, MESSAGE, store_forward, 4) \ -X(a, STATIC, OPTIONAL, MESSAGE, range_test, 5) \ -X(a, STATIC, OPTIONAL, MESSAGE, telemetry, 6) \ -X(a, STATIC, OPTIONAL, MESSAGE, canned_message, 7) \ -X(a, STATIC, SINGULAR, UINT32, version, 8) \ -X(a, STATIC, OPTIONAL, MESSAGE, audio, 9) \ -X(a, STATIC, OPTIONAL, MESSAGE, remote_hardware, 10) \ -X(a, STATIC, OPTIONAL, MESSAGE, neighbor_info, 11) \ -X(a, STATIC, OPTIONAL, MESSAGE, ambient_lighting, 12) \ -X(a, STATIC, OPTIONAL, MESSAGE, detection_sensor, 13) \ -X(a, STATIC, OPTIONAL, MESSAGE, paxcounter, 14) +#define meshtastic_LocalModuleConfig_FIELDLIST(X, a) \ + X(a, STATIC, OPTIONAL, MESSAGE, mqtt, 1) \ + X(a, STATIC, OPTIONAL, MESSAGE, serial, 2) \ + X(a, STATIC, OPTIONAL, MESSAGE, external_notification, 3) \ + X(a, STATIC, OPTIONAL, MESSAGE, store_forward, 4) \ + X(a, STATIC, OPTIONAL, MESSAGE, range_test, 5) \ + X(a, STATIC, OPTIONAL, MESSAGE, telemetry, 6) \ + X(a, STATIC, OPTIONAL, MESSAGE, canned_message, 7) \ + X(a, STATIC, SINGULAR, UINT32, version, 8) \ + X(a, STATIC, OPTIONAL, MESSAGE, audio, 9) \ + X(a, STATIC, OPTIONAL, MESSAGE, remote_hardware, 10) \ + X(a, STATIC, OPTIONAL, MESSAGE, neighbor_info, 11) \ + X(a, STATIC, OPTIONAL, MESSAGE, ambient_lighting, 12) \ + X(a, STATIC, OPTIONAL, MESSAGE, detection_sensor, 13) \ + X(a, STATIC, OPTIONAL, MESSAGE, paxcounter, 14) #define meshtastic_LocalModuleConfig_CALLBACK NULL #define meshtastic_LocalModuleConfig_DEFAULT NULL #define meshtastic_LocalModuleConfig_mqtt_MSGTYPE meshtastic_ModuleConfig_MQTTConfig @@ -178,8 +192,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, paxcounter, 14) #define meshtastic_LocalModuleConfig_detection_sensor_MSGTYPE meshtastic_ModuleConfig_DetectionSensorConfig #define meshtastic_LocalModuleConfig_paxcounter_MSGTYPE meshtastic_ModuleConfig_PaxcounterConfig -extern const pb_msgdesc_t meshtastic_LocalConfig_msg; -extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg; + extern const pb_msgdesc_t meshtastic_LocalConfig_msg; + extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_LocalConfig_fields &meshtastic_LocalConfig_msg @@ -187,8 +201,8 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalConfig_size -#define meshtastic_LocalConfig_size 749 -#define meshtastic_LocalModuleConfig_size 673 +#define meshtastic_LocalConfig_size 749 +#define meshtastic_LocalModuleConfig_size 673 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/mesh.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/mesh.pb.cpp index 9966e52f..f88e0a8b 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/mesh.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/mesh.pb.cpp @@ -8,119 +8,62 @@ PB_BIND(meshtastic_Position, meshtastic_Position, AUTO) - PB_BIND(meshtastic_User, meshtastic_User, AUTO) - PB_BIND(meshtastic_RouteDiscovery, meshtastic_RouteDiscovery, AUTO) - PB_BIND(meshtastic_Routing, meshtastic_Routing, AUTO) - PB_BIND(meshtastic_Data, meshtastic_Data, 2) - PB_BIND(meshtastic_KeyVerification, meshtastic_KeyVerification, AUTO) - PB_BIND(meshtastic_Waypoint, meshtastic_Waypoint, AUTO) - PB_BIND(meshtastic_MqttClientProxyMessage, meshtastic_MqttClientProxyMessage, 2) - PB_BIND(meshtastic_MeshPacket, meshtastic_MeshPacket, 2) - PB_BIND(meshtastic_NodeInfo, meshtastic_NodeInfo, 2) - PB_BIND(meshtastic_MyNodeInfo, meshtastic_MyNodeInfo, AUTO) - PB_BIND(meshtastic_LogRecord, meshtastic_LogRecord, 2) - PB_BIND(meshtastic_QueueStatus, meshtastic_QueueStatus, AUTO) - PB_BIND(meshtastic_FromRadio, meshtastic_FromRadio, 2) - PB_BIND(meshtastic_ClientNotification, meshtastic_ClientNotification, 2) - PB_BIND(meshtastic_KeyVerificationNumberInform, meshtastic_KeyVerificationNumberInform, AUTO) - PB_BIND(meshtastic_KeyVerificationNumberRequest, meshtastic_KeyVerificationNumberRequest, AUTO) - PB_BIND(meshtastic_KeyVerificationFinal, meshtastic_KeyVerificationFinal, AUTO) - PB_BIND(meshtastic_DuplicatedPublicKey, meshtastic_DuplicatedPublicKey, AUTO) - PB_BIND(meshtastic_LowEntropyKey, meshtastic_LowEntropyKey, AUTO) - PB_BIND(meshtastic_FileInfo, meshtastic_FileInfo, AUTO) - PB_BIND(meshtastic_ToRadio, meshtastic_ToRadio, 2) - PB_BIND(meshtastic_Compressed, meshtastic_Compressed, AUTO) - PB_BIND(meshtastic_NeighborInfo, meshtastic_NeighborInfo, AUTO) - PB_BIND(meshtastic_Neighbor, meshtastic_Neighbor, AUTO) - PB_BIND(meshtastic_DeviceMetadata, meshtastic_DeviceMetadata, AUTO) - PB_BIND(meshtastic_Heartbeat, meshtastic_Heartbeat, AUTO) - PB_BIND(meshtastic_NodeRemoteHardwarePin, meshtastic_NodeRemoteHardwarePin, AUTO) - PB_BIND(meshtastic_ChunkedPayload, meshtastic_ChunkedPayload, AUTO) - PB_BIND(meshtastic_resend_chunks, meshtastic_resend_chunks, AUTO) - PB_BIND(meshtastic_ChunkedPayloadResponse, meshtastic_ChunkedPayloadResponse, AUTO) - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/mesh.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/mesh.pb.h index 0c48a789..84e6f3fb 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/mesh.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/mesh.pb.h @@ -3,7 +3,6 @@ #ifndef PB_MESHTASTIC_MESHTASTIC_MESH_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_MESH_PB_H_INCLUDED -#include #include "meshtastic/channel.pb.h" #include "meshtastic/config.pb.h" #include "meshtastic/device_ui.pb.h" @@ -11,6 +10,7 @@ #include "meshtastic/portnums.pb.h" #include "meshtastic/telemetry.pb.h" #include "meshtastic/xmodem.pb.h" +#include #if PB_PROTO_HEADER_VERSION != 40 #error Regenerate this file with the current version of nanopb generator. @@ -21,7 +21,8 @@ bin/build-all.sh script. Because they will be used to find firmware filenames in the android app for OTA updates. To match the old style filenames, _ is converted to -, p is converted to . */ -typedef enum _meshtastic_HardwareModel { +typedef enum _meshtastic_HardwareModel +{ /* TODO: REPLACE */ meshtastic_HardwareModel_UNSET = 0, /* TODO: REPLACE */ @@ -301,7 +302,8 @@ typedef enum _meshtastic_HardwareModel { } meshtastic_HardwareModel; /* Shared constants between device and phone */ -typedef enum _meshtastic_Constants { +typedef enum _meshtastic_Constants +{ /* First enum must be zero, and we are just using this enum to pass int constants between two very different environments */ meshtastic_Constants_ZERO = 0, @@ -315,7 +317,8 @@ typedef enum _meshtastic_Constants { The device might report these fault codes on the screen. If you encounter a fault code, please post on the meshtastic.discourse.group and we'll try to help. */ -typedef enum _meshtastic_CriticalErrorCode { +typedef enum _meshtastic_CriticalErrorCode +{ /* TODO: REPLACE */ meshtastic_CriticalErrorCode_NONE = 0, /* A software bug was detected while trying to send lora */ @@ -354,7 +357,8 @@ typedef enum _meshtastic_CriticalErrorCode { /* Enum to indicate to clients whether this firmware is a special firmware build, like an event. The first 16 values are reserved for non-event special firmwares, like the Smart Citizen use case. */ -typedef enum _meshtastic_FirmwareEdition { +typedef enum _meshtastic_FirmwareEdition +{ /* Vanilla firmware */ meshtastic_FirmwareEdition_VANILLA = 0, /* Firmware for use in the Smart Citizen environmental monitoring network */ @@ -374,7 +378,8 @@ typedef enum _meshtastic_FirmwareEdition { /* Enum for modules excluded from a device's configuration. Each value represents a ModuleConfigType that can be toggled as excluded by setting its corresponding bit in the `excluded_modules` bitmask field. */ -typedef enum _meshtastic_ExcludedModules { +typedef enum _meshtastic_ExcludedModules +{ /* Default value of 0 indicates no modules are excluded. */ meshtastic_ExcludedModules_EXCLUDED_NONE = 0, /* MQTT module */ @@ -410,7 +415,8 @@ typedef enum _meshtastic_ExcludedModules { } meshtastic_ExcludedModules; /* How the location was acquired: manual, onboard GPS, external (EUD) GPS */ -typedef enum _meshtastic_Position_LocSource { +typedef enum _meshtastic_Position_LocSource +{ /* TODO: REPLACE */ meshtastic_Position_LocSource_LOC_UNSET = 0, /* TODO: REPLACE */ @@ -423,7 +429,8 @@ typedef enum _meshtastic_Position_LocSource { /* How the altitude was acquired: manual, GPS int/ext, etc Default: same as location_source if present */ -typedef enum _meshtastic_Position_AltSource { +typedef enum _meshtastic_Position_AltSource +{ /* TODO: REPLACE */ meshtastic_Position_AltSource_ALT_UNSET = 0, /* TODO: REPLACE */ @@ -438,7 +445,8 @@ typedef enum _meshtastic_Position_AltSource { /* A failure in delivering a message (usually used for routing control messages, but might be provided in addition to ack.fail_id to provide details on the type of failure). */ -typedef enum _meshtastic_Routing_Error { +typedef enum _meshtastic_Routing_Error +{ /* This message is not a failure */ meshtastic_Routing_Error_NONE = 0, /* Our node doesn't have a route to the requested destination anymore. */ @@ -496,7 +504,8 @@ typedef enum _meshtastic_Routing_Error { So I bit the bullet and implemented a new (internal - not sent over the air) field in MeshPacket called 'priority'. And the transmission queue in the router object is now a priority queue. */ -typedef enum _meshtastic_MeshPacket_Priority { +typedef enum _meshtastic_MeshPacket_Priority +{ /* Treated as Priority.DEFAULT */ meshtastic_MeshPacket_Priority_UNSET = 0, /* TODO: REPLACE */ @@ -524,7 +533,8 @@ typedef enum _meshtastic_MeshPacket_Priority { } meshtastic_MeshPacket_Priority; /* Identify if this is a delayed packet */ -typedef enum _meshtastic_MeshPacket_Delayed { +typedef enum _meshtastic_MeshPacket_Delayed +{ /* If unset, the message is being sent in real time. */ meshtastic_MeshPacket_Delayed_NO_DELAY = 0, /* The message is delayed and was originally a broadcast */ @@ -534,7 +544,8 @@ typedef enum _meshtastic_MeshPacket_Delayed { } meshtastic_MeshPacket_Delayed; /* Enum to identify which transport mechanism this packet arrived over */ -typedef enum _meshtastic_MeshPacket_TransportMechanism { +typedef enum _meshtastic_MeshPacket_TransportMechanism +{ /* The default case is that the node generated a packet itself */ meshtastic_MeshPacket_TransportMechanism_TRANSPORT_INTERNAL = 0, /* Arrived via the primary LoRa radio */ @@ -554,7 +565,8 @@ typedef enum _meshtastic_MeshPacket_TransportMechanism { } meshtastic_MeshPacket_TransportMechanism; /* Log levels, chosen to match python logging conventions. */ -typedef enum _meshtastic_LogRecord_Level { +typedef enum _meshtastic_LogRecord_Level +{ /* Log levels, chosen to match python logging conventions. */ meshtastic_LogRecord_Level_UNSET = 0, /* Log levels, chosen to match python logging conventions. */ @@ -573,7 +585,8 @@ typedef enum _meshtastic_LogRecord_Level { /* Struct definitions */ /* A GPS Position */ -typedef struct _meshtastic_Position { +typedef struct _meshtastic_Position +{ /* The new preferred location encoding, multiply by 1e-7 to get degrees in floating point */ bool has_latitude_i; @@ -669,7 +682,8 @@ typedef PB_BYTES_ARRAY_T(32) meshtastic_User_public_key_t; A few nodenums are reserved and will never be requested: 0xff - broadcast 0 through 3 - for future use */ -typedef struct _meshtastic_User { +typedef struct _meshtastic_User +{ /* A globally unique ID string for this user. In the case of Signal that would mean +16504442323, for the default macaddr derived id it would be !<8 hexidecimal bytes>. Note: app developers are encouraged to also use the following standard @@ -704,7 +718,8 @@ typedef struct _meshtastic_User { } meshtastic_User; /* A message used in a traceroute */ -typedef struct _meshtastic_RouteDiscovery { +typedef struct _meshtastic_RouteDiscovery +{ /* The list of nodenums this packet has visited so far to the destination. */ pb_size_t route_count; uint32_t route[8]; @@ -720,9 +735,11 @@ typedef struct _meshtastic_RouteDiscovery { } meshtastic_RouteDiscovery; /* A Routing control Data packet handled by the routing module */ -typedef struct _meshtastic_Routing { +typedef struct _meshtastic_Routing +{ pb_size_t which_variant; - union { + union + { /* A route request going from the requester */ meshtastic_RouteDiscovery route_request; /* A route reply */ @@ -737,7 +754,8 @@ typedef PB_BYTES_ARRAY_T(233) meshtastic_Data_payload_t; /* (Formerly called SubPacket) The payload portion fo a packet, this is the actual bytes that are sent inside a radio packet (because from/to are broken out by the comms library) */ -typedef struct _meshtastic_Data { +typedef struct _meshtastic_Data +{ /* Formerly named typ and of type Type */ meshtastic_PortNum portnum; /* TODO: REPLACE */ @@ -772,7 +790,8 @@ typedef struct _meshtastic_Data { typedef PB_BYTES_ARRAY_T(32) meshtastic_KeyVerification_hash1_t; typedef PB_BYTES_ARRAY_T(32) meshtastic_KeyVerification_hash2_t; /* The actual over-the-mesh message doing KeyVerification */ -typedef struct _meshtastic_KeyVerification { +typedef struct _meshtastic_KeyVerification +{ /* random value Selected by the requesting node */ uint64_t nonce; /* The final authoritative hash, only to be sent by NodeA at the end of the handshake */ @@ -783,7 +802,8 @@ typedef struct _meshtastic_KeyVerification { } meshtastic_KeyVerification; /* Waypoint message, used to share arbitrary locations across the mesh */ -typedef struct _meshtastic_Waypoint { +typedef struct _meshtastic_Waypoint +{ /* Id of the waypoint */ uint32_t id; /* latitude_i */ @@ -807,11 +827,13 @@ typedef struct _meshtastic_Waypoint { typedef PB_BYTES_ARRAY_T(435) meshtastic_MqttClientProxyMessage_data_t; /* This message will be proxied over the PhoneAPI for the client to deliver to the MQTT server */ -typedef struct _meshtastic_MqttClientProxyMessage { +typedef struct _meshtastic_MqttClientProxyMessage +{ /* The MQTT topic this message will be sent /received on */ char topic[60]; pb_size_t which_payload_variant; - union { + union + { /* Bytes */ meshtastic_MqttClientProxyMessage_data_t data; /* Text */ @@ -826,7 +848,8 @@ typedef PB_BYTES_ARRAY_T(32) meshtastic_MeshPacket_public_key_t; /* A packet envelope sent/received over the mesh only payload_variant is sent in the payload portion of the LORA packet. The other fields are either not sent at all, or sent in the special 16 byte LORA header. */ -typedef struct _meshtastic_MeshPacket { +typedef struct _meshtastic_MeshPacket +{ /* The sending node number. Note: Our crypto implementation uses this field as well. See [crypto](/docs/overview/encryption) for details. */ @@ -846,7 +869,8 @@ typedef struct _meshtastic_MeshPacket { This 'trick' is only used while the payload_variant is an 'encrypted'. */ uint8_t channel; pb_size_t which_payload_variant; - union { + union + { /* TODO: REPLACE */ meshtastic_Data decoded; /* TODO: REPLACE */ @@ -931,7 +955,8 @@ typedef struct _meshtastic_MeshPacket { level etc) SET_CONFIG (switches device to a new set of radio params and preshared key, drops all existing nodes, force our node to rejoin this new group) Full information about a node on the mesh */ -typedef struct _meshtastic_NodeInfo { +typedef struct _meshtastic_NodeInfo +{ /* The node number */ uint32_t num; /* The user info for this node */ @@ -972,7 +997,8 @@ typedef PB_BYTES_ARRAY_T(16) meshtastic_MyNodeInfo_device_id_t; /* Unique local debugging info for this node Note: we don't include position or the user info, because that will come in the Sent to the phone in response to WantNodes. */ -typedef struct _meshtastic_MyNodeInfo { +typedef struct _meshtastic_MyNodeInfo +{ /* Tells the phone what our node number is, default starting value is lowbyte of macaddr, but it will be fixed if that is already in use */ uint32_t my_node_num; @@ -998,7 +1024,8 @@ typedef struct _meshtastic_MyNodeInfo { on the message it is assumed to be a continuation of the previously sent message. This allows the device code to use fixed maxlen 64 byte strings for messages, and then extend as needed by emitting multiple records. */ -typedef struct _meshtastic_LogRecord { +typedef struct _meshtastic_LogRecord +{ /* Log levels, chosen to match python logging conventions. */ char message[384]; /* Seconds since 1970 - or 0 for unknown/unset */ @@ -1009,7 +1036,8 @@ typedef struct _meshtastic_LogRecord { meshtastic_LogRecord_Level level; } meshtastic_LogRecord; -typedef struct _meshtastic_QueueStatus { +typedef struct _meshtastic_QueueStatus +{ /* Last attempt to queue status, ErrorCode */ int8_t res; /* Free entries in the outgoing queue */ @@ -1020,29 +1048,34 @@ typedef struct _meshtastic_QueueStatus { uint32_t mesh_packet_id; } meshtastic_QueueStatus; -typedef struct _meshtastic_KeyVerificationNumberInform { +typedef struct _meshtastic_KeyVerificationNumberInform +{ uint64_t nonce; char remote_longname[40]; uint32_t security_number; } meshtastic_KeyVerificationNumberInform; -typedef struct _meshtastic_KeyVerificationNumberRequest { +typedef struct _meshtastic_KeyVerificationNumberRequest +{ uint64_t nonce; char remote_longname[40]; } meshtastic_KeyVerificationNumberRequest; -typedef struct _meshtastic_KeyVerificationFinal { +typedef struct _meshtastic_KeyVerificationFinal +{ uint64_t nonce; char remote_longname[40]; bool isSender; char verification_characters[10]; } meshtastic_KeyVerificationFinal; -typedef struct _meshtastic_DuplicatedPublicKey { +typedef struct _meshtastic_DuplicatedPublicKey +{ char dummy_field; } meshtastic_DuplicatedPublicKey; -typedef struct _meshtastic_LowEntropyKey { +typedef struct _meshtastic_LowEntropyKey +{ char dummy_field; } meshtastic_LowEntropyKey; @@ -1050,7 +1083,8 @@ typedef struct _meshtastic_LowEntropyKey { To be used for important messages that should to be displayed to the user in the form of push notifications or validation messages when saving invalid configuration. */ -typedef struct _meshtastic_ClientNotification { +typedef struct _meshtastic_ClientNotification +{ /* The id of the packet we're notifying in response to */ bool has_reply_id; uint32_t reply_id; @@ -1061,7 +1095,8 @@ typedef struct _meshtastic_ClientNotification { /* The message body of the notification */ char message[400]; pb_size_t which_payload_variant; - union { + union + { meshtastic_KeyVerificationNumberInform key_verification_number_inform; meshtastic_KeyVerificationNumberRequest key_verification_number_request; meshtastic_KeyVerificationFinal key_verification_final; @@ -1071,7 +1106,8 @@ typedef struct _meshtastic_ClientNotification { } meshtastic_ClientNotification; /* Individual File info for the device */ -typedef struct _meshtastic_FileInfo { +typedef struct _meshtastic_FileInfo +{ /* The fully qualified path of the file */ char file_name[228]; /* The size of the file in bytes */ @@ -1080,7 +1116,8 @@ typedef struct _meshtastic_FileInfo { typedef PB_BYTES_ARRAY_T(233) meshtastic_Compressed_data_t; /* Compressed message payload */ -typedef struct _meshtastic_Compressed { +typedef struct _meshtastic_Compressed +{ /* PortNum to determine the how to handle the compressed payload. */ meshtastic_PortNum portnum; /* Compressed data. */ @@ -1088,7 +1125,8 @@ typedef struct _meshtastic_Compressed { } meshtastic_Compressed; /* A single edge in the mesh */ -typedef struct _meshtastic_Neighbor { +typedef struct _meshtastic_Neighbor +{ /* Node ID of neighbor */ uint32_t node_id; /* SNR of last heard message */ @@ -1102,7 +1140,8 @@ typedef struct _meshtastic_Neighbor { } meshtastic_Neighbor; /* Full info on edges for a single node */ -typedef struct _meshtastic_NeighborInfo { +typedef struct _meshtastic_NeighborInfo +{ /* The node ID of the node sending info on its neighbors */ uint32_t node_id; /* Field to pass neighbor info for the next sending cycle */ @@ -1115,7 +1154,8 @@ typedef struct _meshtastic_NeighborInfo { } meshtastic_NeighborInfo; /* Device metadata response */ -typedef struct _meshtastic_DeviceMetadata { +typedef struct _meshtastic_DeviceMetadata +{ /* Device firmware version string */ char firmware_version[18]; /* Device state version */ @@ -1147,12 +1187,14 @@ typedef struct _meshtastic_DeviceMetadata { It will support READ and NOTIFY. When a new packet arrives the device will BLE notify? It will sit in that descriptor until consumed by the phone, at which point the next item in the FIFO will be populated. */ -typedef struct _meshtastic_FromRadio { +typedef struct _meshtastic_FromRadio +{ /* The packet id, used to allow the phone to request missing read packets from the FIFO, see our bluetooth docs */ uint32_t id; pb_size_t which_payload_variant; - union { + union + { /* Log levels, chosen to match python logging conventions. */ meshtastic_MeshPacket packet; /* Tells the phone what our node number is, can be -1 if we've not yet joined a mesh. @@ -1198,16 +1240,19 @@ typedef struct _meshtastic_FromRadio { /* A heartbeat message is sent to the node from the client to keep the connection alive. This is currently only needed to keep serial connections alive, but can be used by any PhoneAPI. */ -typedef struct _meshtastic_Heartbeat { +typedef struct _meshtastic_Heartbeat +{ /* The nonce of the heartbeat message */ uint32_t nonce; } meshtastic_Heartbeat; /* Packets/commands to the radio will be written (reliably) to the toRadio characteristic. Once the write completes the phone can assume it is handled. */ -typedef struct _meshtastic_ToRadio { +typedef struct _meshtastic_ToRadio +{ pb_size_t which_payload_variant; - union { + union + { /* Send this packet on the mesh */ meshtastic_MeshPacket packet; /* Phone wants radio to send full node db to the phone, This is @@ -1232,7 +1277,8 @@ typedef struct _meshtastic_ToRadio { } meshtastic_ToRadio; /* RemoteHardwarePins associated with a node */ -typedef struct _meshtastic_NodeRemoteHardwarePin { +typedef struct _meshtastic_NodeRemoteHardwarePin +{ /* The node_num exposing the available gpio pin */ uint32_t node_num; /* The the available gpio pin for usage with RemoteHardware module */ @@ -1241,7 +1287,8 @@ typedef struct _meshtastic_NodeRemoteHardwarePin { } meshtastic_NodeRemoteHardwarePin; typedef PB_BYTES_ARRAY_T(228) meshtastic_ChunkedPayload_payload_chunk_t; -typedef struct _meshtastic_ChunkedPayload { +typedef struct _meshtastic_ChunkedPayload +{ /* The ID of the entire payload */ uint32_t payload_id; /* The total number of chunks in the payload */ @@ -1253,16 +1300,19 @@ typedef struct _meshtastic_ChunkedPayload { } meshtastic_ChunkedPayload; /* Wrapper message for broken repeated oneof support */ -typedef struct _meshtastic_resend_chunks { +typedef struct _meshtastic_resend_chunks +{ pb_callback_t chunks; } meshtastic_resend_chunks; /* Responses to a ChunkedPayload request */ -typedef struct _meshtastic_ChunkedPayloadResponse { +typedef struct _meshtastic_ChunkedPayloadResponse +{ /* The ID of the entire payload */ uint32_t payload_id; pb_size_t which_payload_variant; - union { + union + { /* Request to transfer chunked payload */ bool request_transfer; /* Accept the transfer chunked payload */ @@ -1272,59 +1322,59 @@ typedef struct _meshtastic_ChunkedPayloadResponse { } payload_variant; } meshtastic_ChunkedPayloadResponse; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Helper constants for enums */ #define _meshtastic_HardwareModel_MIN meshtastic_HardwareModel_UNSET #define _meshtastic_HardwareModel_MAX meshtastic_HardwareModel_PRIVATE_HW -#define _meshtastic_HardwareModel_ARRAYSIZE ((meshtastic_HardwareModel)(meshtastic_HardwareModel_PRIVATE_HW+1)) +#define _meshtastic_HardwareModel_ARRAYSIZE ((meshtastic_HardwareModel)(meshtastic_HardwareModel_PRIVATE_HW + 1)) #define _meshtastic_Constants_MIN meshtastic_Constants_ZERO #define _meshtastic_Constants_MAX meshtastic_Constants_DATA_PAYLOAD_LEN -#define _meshtastic_Constants_ARRAYSIZE ((meshtastic_Constants)(meshtastic_Constants_DATA_PAYLOAD_LEN+1)) +#define _meshtastic_Constants_ARRAYSIZE ((meshtastic_Constants)(meshtastic_Constants_DATA_PAYLOAD_LEN + 1)) #define _meshtastic_CriticalErrorCode_MIN meshtastic_CriticalErrorCode_NONE #define _meshtastic_CriticalErrorCode_MAX meshtastic_CriticalErrorCode_FLASH_CORRUPTION_UNRECOVERABLE -#define _meshtastic_CriticalErrorCode_ARRAYSIZE ((meshtastic_CriticalErrorCode)(meshtastic_CriticalErrorCode_FLASH_CORRUPTION_UNRECOVERABLE+1)) +#define _meshtastic_CriticalErrorCode_ARRAYSIZE ((meshtastic_CriticalErrorCode)(meshtastic_CriticalErrorCode_FLASH_CORRUPTION_UNRECOVERABLE + 1)) #define _meshtastic_FirmwareEdition_MIN meshtastic_FirmwareEdition_VANILLA #define _meshtastic_FirmwareEdition_MAX meshtastic_FirmwareEdition_DIY_EDITION -#define _meshtastic_FirmwareEdition_ARRAYSIZE ((meshtastic_FirmwareEdition)(meshtastic_FirmwareEdition_DIY_EDITION+1)) +#define _meshtastic_FirmwareEdition_ARRAYSIZE ((meshtastic_FirmwareEdition)(meshtastic_FirmwareEdition_DIY_EDITION + 1)) #define _meshtastic_ExcludedModules_MIN meshtastic_ExcludedModules_EXCLUDED_NONE #define _meshtastic_ExcludedModules_MAX meshtastic_ExcludedModules_NETWORK_CONFIG -#define _meshtastic_ExcludedModules_ARRAYSIZE ((meshtastic_ExcludedModules)(meshtastic_ExcludedModules_NETWORK_CONFIG+1)) +#define _meshtastic_ExcludedModules_ARRAYSIZE ((meshtastic_ExcludedModules)(meshtastic_ExcludedModules_NETWORK_CONFIG + 1)) #define _meshtastic_Position_LocSource_MIN meshtastic_Position_LocSource_LOC_UNSET #define _meshtastic_Position_LocSource_MAX meshtastic_Position_LocSource_LOC_EXTERNAL -#define _meshtastic_Position_LocSource_ARRAYSIZE ((meshtastic_Position_LocSource)(meshtastic_Position_LocSource_LOC_EXTERNAL+1)) +#define _meshtastic_Position_LocSource_ARRAYSIZE ((meshtastic_Position_LocSource)(meshtastic_Position_LocSource_LOC_EXTERNAL + 1)) #define _meshtastic_Position_AltSource_MIN meshtastic_Position_AltSource_ALT_UNSET #define _meshtastic_Position_AltSource_MAX meshtastic_Position_AltSource_ALT_BAROMETRIC -#define _meshtastic_Position_AltSource_ARRAYSIZE ((meshtastic_Position_AltSource)(meshtastic_Position_AltSource_ALT_BAROMETRIC+1)) +#define _meshtastic_Position_AltSource_ARRAYSIZE ((meshtastic_Position_AltSource)(meshtastic_Position_AltSource_ALT_BAROMETRIC + 1)) #define _meshtastic_Routing_Error_MIN meshtastic_Routing_Error_NONE #define _meshtastic_Routing_Error_MAX meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED -#define _meshtastic_Routing_Error_ARRAYSIZE ((meshtastic_Routing_Error)(meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED+1)) +#define _meshtastic_Routing_Error_ARRAYSIZE ((meshtastic_Routing_Error)(meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED + 1)) #define _meshtastic_MeshPacket_Priority_MIN meshtastic_MeshPacket_Priority_UNSET #define _meshtastic_MeshPacket_Priority_MAX meshtastic_MeshPacket_Priority_MAX -#define _meshtastic_MeshPacket_Priority_ARRAYSIZE ((meshtastic_MeshPacket_Priority)(meshtastic_MeshPacket_Priority_MAX+1)) +#define _meshtastic_MeshPacket_Priority_ARRAYSIZE ((meshtastic_MeshPacket_Priority)(meshtastic_MeshPacket_Priority_MAX + 1)) #define _meshtastic_MeshPacket_Delayed_MIN meshtastic_MeshPacket_Delayed_NO_DELAY #define _meshtastic_MeshPacket_Delayed_MAX meshtastic_MeshPacket_Delayed_DELAYED_DIRECT -#define _meshtastic_MeshPacket_Delayed_ARRAYSIZE ((meshtastic_MeshPacket_Delayed)(meshtastic_MeshPacket_Delayed_DELAYED_DIRECT+1)) +#define _meshtastic_MeshPacket_Delayed_ARRAYSIZE ((meshtastic_MeshPacket_Delayed)(meshtastic_MeshPacket_Delayed_DELAYED_DIRECT + 1)) #define _meshtastic_MeshPacket_TransportMechanism_MIN meshtastic_MeshPacket_TransportMechanism_TRANSPORT_INTERNAL #define _meshtastic_MeshPacket_TransportMechanism_MAX meshtastic_MeshPacket_TransportMechanism_TRANSPORT_API -#define _meshtastic_MeshPacket_TransportMechanism_ARRAYSIZE ((meshtastic_MeshPacket_TransportMechanism)(meshtastic_MeshPacket_TransportMechanism_TRANSPORT_API+1)) +#define _meshtastic_MeshPacket_TransportMechanism_ARRAYSIZE ((meshtastic_MeshPacket_TransportMechanism)(meshtastic_MeshPacket_TransportMechanism_TRANSPORT_API + 1)) #define _meshtastic_LogRecord_Level_MIN meshtastic_LogRecord_Level_UNSET #define _meshtastic_LogRecord_Level_MAX meshtastic_LogRecord_Level_CRITICAL -#define _meshtastic_LogRecord_Level_ARRAYSIZE ((meshtastic_LogRecord_Level)(meshtastic_LogRecord_Level_CRITICAL+1)) +#define _meshtastic_LogRecord_Level_ARRAYSIZE ((meshtastic_LogRecord_Level)(meshtastic_LogRecord_Level_CRITICAL + 1)) #define meshtastic_Position_location_source_ENUMTYPE meshtastic_Position_LocSource #define meshtastic_Position_altitude_source_ENUMTYPE meshtastic_Position_AltSource @@ -1332,222 +1382,408 @@ extern "C" { #define meshtastic_User_hw_model_ENUMTYPE meshtastic_HardwareModel #define meshtastic_User_role_ENUMTYPE meshtastic_Config_DeviceConfig_Role - #define meshtastic_Routing_variant_error_reason_ENUMTYPE meshtastic_Routing_Error #define meshtastic_Data_portnum_ENUMTYPE meshtastic_PortNum - - - #define meshtastic_MeshPacket_priority_ENUMTYPE meshtastic_MeshPacket_Priority #define meshtastic_MeshPacket_delayed_ENUMTYPE meshtastic_MeshPacket_Delayed #define meshtastic_MeshPacket_transport_mechanism_ENUMTYPE meshtastic_MeshPacket_TransportMechanism - #define meshtastic_MyNodeInfo_firmware_edition_ENUMTYPE meshtastic_FirmwareEdition #define meshtastic_LogRecord_level_ENUMTYPE meshtastic_LogRecord_Level - - #define meshtastic_ClientNotification_level_ENUMTYPE meshtastic_LogRecord_Level - - - - - - - #define meshtastic_Compressed_portnum_ENUMTYPE meshtastic_PortNum - - #define meshtastic_DeviceMetadata_role_ENUMTYPE meshtastic_Config_DeviceConfig_Role #define meshtastic_DeviceMetadata_hw_model_ENUMTYPE meshtastic_HardwareModel - - - - - - /* Initializer values for message structs */ -#define meshtastic_Position_init_default {false, 0, false, 0, false, 0, 0, _meshtastic_Position_LocSource_MIN, _meshtastic_Position_AltSource_MIN, 0, 0, false, 0, false, 0, 0, 0, 0, 0, false, 0, false, 0, 0, 0, 0, 0, 0, 0, 0} -#define meshtastic_User_init_default {"", "", "", {0}, _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}, false, 0} -#define meshtastic_RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}} -#define meshtastic_Routing_init_default {0, {meshtastic_RouteDiscovery_init_default}} -#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0} -#define meshtastic_KeyVerification_init_default {0, {0, {0}}, {0, {0}}} -#define meshtastic_Waypoint_init_default {0, false, 0, false, 0, 0, 0, "", "", 0} -#define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0} -#define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN} -#define meshtastic_NodeInfo_init_default {0, false, meshtastic_User_init_default, false, meshtastic_Position_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0, 0, 0} -#define meshtastic_MyNodeInfo_init_default {0, 0, 0, {0, {0}}, "", _meshtastic_FirmwareEdition_MIN, 0} -#define meshtastic_LogRecord_init_default {"", 0, "", _meshtastic_LogRecord_Level_MIN} -#define meshtastic_QueueStatus_init_default {0, 0, 0, 0} -#define meshtastic_FromRadio_init_default {0, 0, {meshtastic_MeshPacket_init_default}} -#define meshtastic_ClientNotification_init_default {false, 0, 0, _meshtastic_LogRecord_Level_MIN, "", 0, {meshtastic_KeyVerificationNumberInform_init_default}} -#define meshtastic_KeyVerificationNumberInform_init_default {0, "", 0} -#define meshtastic_KeyVerificationNumberRequest_init_default {0, ""} -#define meshtastic_KeyVerificationFinal_init_default {0, "", 0, ""} -#define meshtastic_DuplicatedPublicKey_init_default {0} -#define meshtastic_LowEntropyKey_init_default {0} -#define meshtastic_FileInfo_init_default {"", 0} -#define meshtastic_ToRadio_init_default {0, {meshtastic_MeshPacket_init_default}} -#define meshtastic_Compressed_init_default {_meshtastic_PortNum_MIN, {0, {0}}} -#define meshtastic_NeighborInfo_init_default {0, 0, 0, 0, {meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default}} -#define meshtastic_Neighbor_init_default {0, 0, 0, 0} -#define meshtastic_DeviceMetadata_init_default {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0, 0, 0} -#define meshtastic_Heartbeat_init_default {0} -#define meshtastic_NodeRemoteHardwarePin_init_default {0, false, meshtastic_RemoteHardwarePin_init_default} -#define meshtastic_ChunkedPayload_init_default {0, 0, 0, {0, {0}}} -#define meshtastic_resend_chunks_init_default {{{NULL}, NULL}} -#define meshtastic_ChunkedPayloadResponse_init_default {0, 0, {0}} -#define meshtastic_Position_init_zero {false, 0, false, 0, false, 0, 0, _meshtastic_Position_LocSource_MIN, _meshtastic_Position_AltSource_MIN, 0, 0, false, 0, false, 0, 0, 0, 0, 0, false, 0, false, 0, 0, 0, 0, 0, 0, 0, 0} -#define meshtastic_User_init_zero {"", "", "", {0}, _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}, false, 0} -#define meshtastic_RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}} -#define meshtastic_Routing_init_zero {0, {meshtastic_RouteDiscovery_init_zero}} -#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0} -#define meshtastic_KeyVerification_init_zero {0, {0, {0}}, {0, {0}}} -#define meshtastic_Waypoint_init_zero {0, false, 0, false, 0, 0, 0, "", "", 0} -#define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0} -#define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN} -#define meshtastic_NodeInfo_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_Position_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0, 0, 0} -#define meshtastic_MyNodeInfo_init_zero {0, 0, 0, {0, {0}}, "", _meshtastic_FirmwareEdition_MIN, 0} -#define meshtastic_LogRecord_init_zero {"", 0, "", _meshtastic_LogRecord_Level_MIN} -#define meshtastic_QueueStatus_init_zero {0, 0, 0, 0} -#define meshtastic_FromRadio_init_zero {0, 0, {meshtastic_MeshPacket_init_zero}} -#define meshtastic_ClientNotification_init_zero {false, 0, 0, _meshtastic_LogRecord_Level_MIN, "", 0, {meshtastic_KeyVerificationNumberInform_init_zero}} -#define meshtastic_KeyVerificationNumberInform_init_zero {0, "", 0} -#define meshtastic_KeyVerificationNumberRequest_init_zero {0, ""} -#define meshtastic_KeyVerificationFinal_init_zero {0, "", 0, ""} -#define meshtastic_DuplicatedPublicKey_init_zero {0} -#define meshtastic_LowEntropyKey_init_zero {0} -#define meshtastic_FileInfo_init_zero {"", 0} -#define meshtastic_ToRadio_init_zero {0, {meshtastic_MeshPacket_init_zero}} -#define meshtastic_Compressed_init_zero {_meshtastic_PortNum_MIN, {0, {0}}} -#define meshtastic_NeighborInfo_init_zero {0, 0, 0, 0, {meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero}} -#define meshtastic_Neighbor_init_zero {0, 0, 0, 0} -#define meshtastic_DeviceMetadata_init_zero {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0, 0, 0} -#define meshtastic_Heartbeat_init_zero {0} -#define meshtastic_NodeRemoteHardwarePin_init_zero {0, false, meshtastic_RemoteHardwarePin_init_zero} -#define meshtastic_ChunkedPayload_init_zero {0, 0, 0, {0, {0}}} -#define meshtastic_resend_chunks_init_zero {{{NULL}, NULL}} -#define meshtastic_ChunkedPayloadResponse_init_zero {0, 0, {0}} +#define meshtastic_Position_init_default \ + { \ + false, 0, false, 0, false, 0, 0, _meshtastic_Position_LocSource_MIN, _meshtastic_Position_AltSource_MIN, 0, 0, false, 0, false, 0, 0, 0, 0, 0, false, 0, false, 0, 0, 0, 0, 0, 0, 0, 0 \ + } +#define meshtastic_User_init_default \ + { \ + "", "", "", {0}, _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}, false, 0 \ + } +#define meshtastic_RouteDiscovery_init_default \ + { \ + 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } \ + } +#define meshtastic_Routing_init_default \ + { \ + 0, { meshtastic_RouteDiscovery_init_default } \ + } +#define meshtastic_Data_init_default \ + { \ + _meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0 \ + } +#define meshtastic_KeyVerification_init_default \ + { \ + 0, {0, {0}}, \ + { \ + 0, { 0 } \ + } \ + } +#define meshtastic_Waypoint_init_default \ + { \ + 0, false, 0, false, 0, 0, 0, "", "", 0 \ + } +#define meshtastic_MqttClientProxyMessage_init_default \ + { \ + "", 0, {{0, {0}}}, 0 \ + } +#define meshtastic_MeshPacket_init_default \ + { \ + 0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN \ + } +#define meshtastic_NodeInfo_init_default \ + { \ + 0, false, meshtastic_User_init_default, false, meshtastic_Position_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0, 0, 0 \ + } +#define meshtastic_MyNodeInfo_init_default \ + { \ + 0, 0, 0, {0, {0}}, "", _meshtastic_FirmwareEdition_MIN, 0 \ + } +#define meshtastic_LogRecord_init_default \ + { \ + "", 0, "", _meshtastic_LogRecord_Level_MIN \ + } +#define meshtastic_QueueStatus_init_default \ + { \ + 0, 0, 0, 0 \ + } +#define meshtastic_FromRadio_init_default \ + { \ + 0, 0, { meshtastic_MeshPacket_init_default } \ + } +#define meshtastic_ClientNotification_init_default \ + { \ + false, 0, 0, _meshtastic_LogRecord_Level_MIN, "", 0, { meshtastic_KeyVerificationNumberInform_init_default } \ + } +#define meshtastic_KeyVerificationNumberInform_init_default \ + { \ + 0, "", 0 \ + } +#define meshtastic_KeyVerificationNumberRequest_init_default \ + { \ + 0, "" \ + } +#define meshtastic_KeyVerificationFinal_init_default \ + { \ + 0, "", 0, "" \ + } +#define meshtastic_DuplicatedPublicKey_init_default \ + { \ + 0 \ + } +#define meshtastic_LowEntropyKey_init_default \ + { \ + 0 \ + } +#define meshtastic_FileInfo_init_default \ + { \ + "", 0 \ + } +#define meshtastic_ToRadio_init_default \ + { \ + 0, { meshtastic_MeshPacket_init_default } \ + } +#define meshtastic_Compressed_init_default \ + { \ + _meshtastic_PortNum_MIN, \ + { \ + 0, { 0 } \ + } \ + } +#define meshtastic_NeighborInfo_init_default \ + { \ + 0, 0, 0, 0, { meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default } \ + } +#define meshtastic_Neighbor_init_default \ + { \ + 0, 0, 0, 0 \ + } +#define meshtastic_DeviceMetadata_init_default \ + { \ + "", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0, 0, 0 \ + } +#define meshtastic_Heartbeat_init_default \ + { \ + 0 \ + } +#define meshtastic_NodeRemoteHardwarePin_init_default \ + { \ + 0, false, meshtastic_RemoteHardwarePin_init_default \ + } +#define meshtastic_ChunkedPayload_init_default \ + { \ + 0, 0, 0, \ + { \ + 0, { 0 } \ + } \ + } +#define meshtastic_resend_chunks_init_default \ + { \ + { \ + {NULL}, NULL \ + } \ + } +#define meshtastic_ChunkedPayloadResponse_init_default \ + { \ + 0, 0, { 0 } \ + } +#define meshtastic_Position_init_zero \ + { \ + false, 0, false, 0, false, 0, 0, _meshtastic_Position_LocSource_MIN, _meshtastic_Position_AltSource_MIN, 0, 0, false, 0, false, 0, 0, 0, 0, 0, false, 0, false, 0, 0, 0, 0, 0, 0, 0, 0 \ + } +#define meshtastic_User_init_zero \ + { \ + "", "", "", {0}, _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}, false, 0 \ + } +#define meshtastic_RouteDiscovery_init_zero \ + { \ + 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } \ + } +#define meshtastic_Routing_init_zero \ + { \ + 0, { meshtastic_RouteDiscovery_init_zero } \ + } +#define meshtastic_Data_init_zero \ + { \ + _meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0 \ + } +#define meshtastic_KeyVerification_init_zero \ + { \ + 0, {0, {0}}, \ + { \ + 0, { 0 } \ + } \ + } +#define meshtastic_Waypoint_init_zero \ + { \ + 0, false, 0, false, 0, 0, 0, "", "", 0 \ + } +#define meshtastic_MqttClientProxyMessage_init_zero \ + { \ + "", 0, {{0, {0}}}, 0 \ + } +#define meshtastic_MeshPacket_init_zero \ + { \ + 0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN \ + } +#define meshtastic_NodeInfo_init_zero \ + { \ + 0, false, meshtastic_User_init_zero, false, meshtastic_Position_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0, 0, 0 \ + } +#define meshtastic_MyNodeInfo_init_zero \ + { \ + 0, 0, 0, {0, {0}}, "", _meshtastic_FirmwareEdition_MIN, 0 \ + } +#define meshtastic_LogRecord_init_zero \ + { \ + "", 0, "", _meshtastic_LogRecord_Level_MIN \ + } +#define meshtastic_QueueStatus_init_zero \ + { \ + 0, 0, 0, 0 \ + } +#define meshtastic_FromRadio_init_zero \ + { \ + 0, 0, { meshtastic_MeshPacket_init_zero } \ + } +#define meshtastic_ClientNotification_init_zero \ + { \ + false, 0, 0, _meshtastic_LogRecord_Level_MIN, "", 0, { meshtastic_KeyVerificationNumberInform_init_zero } \ + } +#define meshtastic_KeyVerificationNumberInform_init_zero \ + { \ + 0, "", 0 \ + } +#define meshtastic_KeyVerificationNumberRequest_init_zero \ + { \ + 0, "" \ + } +#define meshtastic_KeyVerificationFinal_init_zero \ + { \ + 0, "", 0, "" \ + } +#define meshtastic_DuplicatedPublicKey_init_zero \ + { \ + 0 \ + } +#define meshtastic_LowEntropyKey_init_zero \ + { \ + 0 \ + } +#define meshtastic_FileInfo_init_zero \ + { \ + "", 0 \ + } +#define meshtastic_ToRadio_init_zero \ + { \ + 0, { meshtastic_MeshPacket_init_zero } \ + } +#define meshtastic_Compressed_init_zero \ + { \ + _meshtastic_PortNum_MIN, \ + { \ + 0, { 0 } \ + } \ + } +#define meshtastic_NeighborInfo_init_zero \ + { \ + 0, 0, 0, 0, { meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero } \ + } +#define meshtastic_Neighbor_init_zero \ + { \ + 0, 0, 0, 0 \ + } +#define meshtastic_DeviceMetadata_init_zero \ + { \ + "", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0, 0, 0 \ + } +#define meshtastic_Heartbeat_init_zero \ + { \ + 0 \ + } +#define meshtastic_NodeRemoteHardwarePin_init_zero \ + { \ + 0, false, meshtastic_RemoteHardwarePin_init_zero \ + } +#define meshtastic_ChunkedPayload_init_zero \ + { \ + 0, 0, 0, \ + { \ + 0, { 0 } \ + } \ + } +#define meshtastic_resend_chunks_init_zero \ + { \ + { \ + {NULL}, NULL \ + } \ + } +#define meshtastic_ChunkedPayloadResponse_init_zero \ + { \ + 0, 0, { 0 } \ + } /* Field tags (for use in manual encoding/decoding) */ -#define meshtastic_Position_latitude_i_tag 1 -#define meshtastic_Position_longitude_i_tag 2 -#define meshtastic_Position_altitude_tag 3 -#define meshtastic_Position_time_tag 4 -#define meshtastic_Position_location_source_tag 5 -#define meshtastic_Position_altitude_source_tag 6 -#define meshtastic_Position_timestamp_tag 7 +#define meshtastic_Position_latitude_i_tag 1 +#define meshtastic_Position_longitude_i_tag 2 +#define meshtastic_Position_altitude_tag 3 +#define meshtastic_Position_time_tag 4 +#define meshtastic_Position_location_source_tag 5 +#define meshtastic_Position_altitude_source_tag 6 +#define meshtastic_Position_timestamp_tag 7 #define meshtastic_Position_timestamp_millis_adjust_tag 8 -#define meshtastic_Position_altitude_hae_tag 9 +#define meshtastic_Position_altitude_hae_tag 9 #define meshtastic_Position_altitude_geoidal_separation_tag 10 -#define meshtastic_Position_PDOP_tag 11 -#define meshtastic_Position_HDOP_tag 12 -#define meshtastic_Position_VDOP_tag 13 -#define meshtastic_Position_gps_accuracy_tag 14 -#define meshtastic_Position_ground_speed_tag 15 -#define meshtastic_Position_ground_track_tag 16 -#define meshtastic_Position_fix_quality_tag 17 -#define meshtastic_Position_fix_type_tag 18 -#define meshtastic_Position_sats_in_view_tag 19 -#define meshtastic_Position_sensor_id_tag 20 -#define meshtastic_Position_next_update_tag 21 -#define meshtastic_Position_seq_number_tag 22 -#define meshtastic_Position_precision_bits_tag 23 -#define meshtastic_User_id_tag 1 -#define meshtastic_User_long_name_tag 2 -#define meshtastic_User_short_name_tag 3 -#define meshtastic_User_macaddr_tag 4 -#define meshtastic_User_hw_model_tag 5 -#define meshtastic_User_is_licensed_tag 6 -#define meshtastic_User_role_tag 7 -#define meshtastic_User_public_key_tag 8 -#define meshtastic_User_is_unmessagable_tag 9 -#define meshtastic_RouteDiscovery_route_tag 1 +#define meshtastic_Position_PDOP_tag 11 +#define meshtastic_Position_HDOP_tag 12 +#define meshtastic_Position_VDOP_tag 13 +#define meshtastic_Position_gps_accuracy_tag 14 +#define meshtastic_Position_ground_speed_tag 15 +#define meshtastic_Position_ground_track_tag 16 +#define meshtastic_Position_fix_quality_tag 17 +#define meshtastic_Position_fix_type_tag 18 +#define meshtastic_Position_sats_in_view_tag 19 +#define meshtastic_Position_sensor_id_tag 20 +#define meshtastic_Position_next_update_tag 21 +#define meshtastic_Position_seq_number_tag 22 +#define meshtastic_Position_precision_bits_tag 23 +#define meshtastic_User_id_tag 1 +#define meshtastic_User_long_name_tag 2 +#define meshtastic_User_short_name_tag 3 +#define meshtastic_User_macaddr_tag 4 +#define meshtastic_User_hw_model_tag 5 +#define meshtastic_User_is_licensed_tag 6 +#define meshtastic_User_role_tag 7 +#define meshtastic_User_public_key_tag 8 +#define meshtastic_User_is_unmessagable_tag 9 +#define meshtastic_RouteDiscovery_route_tag 1 #define meshtastic_RouteDiscovery_snr_towards_tag 2 #define meshtastic_RouteDiscovery_route_back_tag 3 -#define meshtastic_RouteDiscovery_snr_back_tag 4 -#define meshtastic_Routing_route_request_tag 1 -#define meshtastic_Routing_route_reply_tag 2 -#define meshtastic_Routing_error_reason_tag 3 -#define meshtastic_Data_portnum_tag 1 -#define meshtastic_Data_payload_tag 2 -#define meshtastic_Data_want_response_tag 3 -#define meshtastic_Data_dest_tag 4 -#define meshtastic_Data_source_tag 5 -#define meshtastic_Data_request_id_tag 6 -#define meshtastic_Data_reply_id_tag 7 -#define meshtastic_Data_emoji_tag 8 -#define meshtastic_Data_bitfield_tag 9 -#define meshtastic_KeyVerification_nonce_tag 1 -#define meshtastic_KeyVerification_hash1_tag 2 -#define meshtastic_KeyVerification_hash2_tag 3 -#define meshtastic_Waypoint_id_tag 1 -#define meshtastic_Waypoint_latitude_i_tag 2 -#define meshtastic_Waypoint_longitude_i_tag 3 -#define meshtastic_Waypoint_expire_tag 4 -#define meshtastic_Waypoint_locked_to_tag 5 -#define meshtastic_Waypoint_name_tag 6 -#define meshtastic_Waypoint_description_tag 7 -#define meshtastic_Waypoint_icon_tag 8 +#define meshtastic_RouteDiscovery_snr_back_tag 4 +#define meshtastic_Routing_route_request_tag 1 +#define meshtastic_Routing_route_reply_tag 2 +#define meshtastic_Routing_error_reason_tag 3 +#define meshtastic_Data_portnum_tag 1 +#define meshtastic_Data_payload_tag 2 +#define meshtastic_Data_want_response_tag 3 +#define meshtastic_Data_dest_tag 4 +#define meshtastic_Data_source_tag 5 +#define meshtastic_Data_request_id_tag 6 +#define meshtastic_Data_reply_id_tag 7 +#define meshtastic_Data_emoji_tag 8 +#define meshtastic_Data_bitfield_tag 9 +#define meshtastic_KeyVerification_nonce_tag 1 +#define meshtastic_KeyVerification_hash1_tag 2 +#define meshtastic_KeyVerification_hash2_tag 3 +#define meshtastic_Waypoint_id_tag 1 +#define meshtastic_Waypoint_latitude_i_tag 2 +#define meshtastic_Waypoint_longitude_i_tag 3 +#define meshtastic_Waypoint_expire_tag 4 +#define meshtastic_Waypoint_locked_to_tag 5 +#define meshtastic_Waypoint_name_tag 6 +#define meshtastic_Waypoint_description_tag 7 +#define meshtastic_Waypoint_icon_tag 8 #define meshtastic_MqttClientProxyMessage_topic_tag 1 #define meshtastic_MqttClientProxyMessage_data_tag 2 #define meshtastic_MqttClientProxyMessage_text_tag 3 #define meshtastic_MqttClientProxyMessage_retained_tag 4 -#define meshtastic_MeshPacket_from_tag 1 -#define meshtastic_MeshPacket_to_tag 2 -#define meshtastic_MeshPacket_channel_tag 3 -#define meshtastic_MeshPacket_decoded_tag 4 -#define meshtastic_MeshPacket_encrypted_tag 5 -#define meshtastic_MeshPacket_id_tag 6 -#define meshtastic_MeshPacket_rx_time_tag 7 -#define meshtastic_MeshPacket_rx_snr_tag 8 -#define meshtastic_MeshPacket_hop_limit_tag 9 -#define meshtastic_MeshPacket_want_ack_tag 10 -#define meshtastic_MeshPacket_priority_tag 11 -#define meshtastic_MeshPacket_rx_rssi_tag 12 -#define meshtastic_MeshPacket_delayed_tag 13 -#define meshtastic_MeshPacket_via_mqtt_tag 14 -#define meshtastic_MeshPacket_hop_start_tag 15 -#define meshtastic_MeshPacket_public_key_tag 16 -#define meshtastic_MeshPacket_pki_encrypted_tag 17 -#define meshtastic_MeshPacket_next_hop_tag 18 -#define meshtastic_MeshPacket_relay_node_tag 19 -#define meshtastic_MeshPacket_tx_after_tag 20 +#define meshtastic_MeshPacket_from_tag 1 +#define meshtastic_MeshPacket_to_tag 2 +#define meshtastic_MeshPacket_channel_tag 3 +#define meshtastic_MeshPacket_decoded_tag 4 +#define meshtastic_MeshPacket_encrypted_tag 5 +#define meshtastic_MeshPacket_id_tag 6 +#define meshtastic_MeshPacket_rx_time_tag 7 +#define meshtastic_MeshPacket_rx_snr_tag 8 +#define meshtastic_MeshPacket_hop_limit_tag 9 +#define meshtastic_MeshPacket_want_ack_tag 10 +#define meshtastic_MeshPacket_priority_tag 11 +#define meshtastic_MeshPacket_rx_rssi_tag 12 +#define meshtastic_MeshPacket_delayed_tag 13 +#define meshtastic_MeshPacket_via_mqtt_tag 14 +#define meshtastic_MeshPacket_hop_start_tag 15 +#define meshtastic_MeshPacket_public_key_tag 16 +#define meshtastic_MeshPacket_pki_encrypted_tag 17 +#define meshtastic_MeshPacket_next_hop_tag 18 +#define meshtastic_MeshPacket_relay_node_tag 19 +#define meshtastic_MeshPacket_tx_after_tag 20 #define meshtastic_MeshPacket_transport_mechanism_tag 21 -#define meshtastic_NodeInfo_num_tag 1 -#define meshtastic_NodeInfo_user_tag 2 -#define meshtastic_NodeInfo_position_tag 3 -#define meshtastic_NodeInfo_snr_tag 4 -#define meshtastic_NodeInfo_last_heard_tag 5 -#define meshtastic_NodeInfo_device_metrics_tag 6 -#define meshtastic_NodeInfo_channel_tag 7 -#define meshtastic_NodeInfo_via_mqtt_tag 8 -#define meshtastic_NodeInfo_hops_away_tag 9 -#define meshtastic_NodeInfo_is_favorite_tag 10 -#define meshtastic_NodeInfo_is_ignored_tag 11 +#define meshtastic_NodeInfo_num_tag 1 +#define meshtastic_NodeInfo_user_tag 2 +#define meshtastic_NodeInfo_position_tag 3 +#define meshtastic_NodeInfo_snr_tag 4 +#define meshtastic_NodeInfo_last_heard_tag 5 +#define meshtastic_NodeInfo_device_metrics_tag 6 +#define meshtastic_NodeInfo_channel_tag 7 +#define meshtastic_NodeInfo_via_mqtt_tag 8 +#define meshtastic_NodeInfo_hops_away_tag 9 +#define meshtastic_NodeInfo_is_favorite_tag 10 +#define meshtastic_NodeInfo_is_ignored_tag 11 #define meshtastic_NodeInfo_is_key_manually_verified_tag 12 -#define meshtastic_MyNodeInfo_my_node_num_tag 1 -#define meshtastic_MyNodeInfo_reboot_count_tag 8 +#define meshtastic_MyNodeInfo_my_node_num_tag 1 +#define meshtastic_MyNodeInfo_reboot_count_tag 8 #define meshtastic_MyNodeInfo_min_app_version_tag 11 -#define meshtastic_MyNodeInfo_device_id_tag 12 -#define meshtastic_MyNodeInfo_pio_env_tag 13 +#define meshtastic_MyNodeInfo_device_id_tag 12 +#define meshtastic_MyNodeInfo_pio_env_tag 13 #define meshtastic_MyNodeInfo_firmware_edition_tag 14 -#define meshtastic_MyNodeInfo_nodedb_count_tag 15 -#define meshtastic_LogRecord_message_tag 1 -#define meshtastic_LogRecord_time_tag 2 -#define meshtastic_LogRecord_source_tag 3 -#define meshtastic_LogRecord_level_tag 4 -#define meshtastic_QueueStatus_res_tag 1 -#define meshtastic_QueueStatus_free_tag 2 -#define meshtastic_QueueStatus_maxlen_tag 3 +#define meshtastic_MyNodeInfo_nodedb_count_tag 15 +#define meshtastic_LogRecord_message_tag 1 +#define meshtastic_LogRecord_time_tag 2 +#define meshtastic_LogRecord_source_tag 3 +#define meshtastic_LogRecord_level_tag 4 +#define meshtastic_QueueStatus_res_tag 1 +#define meshtastic_QueueStatus_free_tag 2 +#define meshtastic_QueueStatus_maxlen_tag 3 #define meshtastic_QueueStatus_mesh_packet_id_tag 4 #define meshtastic_KeyVerificationNumberInform_nonce_tag 1 #define meshtastic_KeyVerificationNumberInform_remote_longname_tag 2 @@ -1559,262 +1795,262 @@ extern "C" { #define meshtastic_KeyVerificationFinal_isSender_tag 3 #define meshtastic_KeyVerificationFinal_verification_characters_tag 4 #define meshtastic_ClientNotification_reply_id_tag 1 -#define meshtastic_ClientNotification_time_tag 2 -#define meshtastic_ClientNotification_level_tag 3 +#define meshtastic_ClientNotification_time_tag 2 +#define meshtastic_ClientNotification_level_tag 3 #define meshtastic_ClientNotification_message_tag 4 #define meshtastic_ClientNotification_key_verification_number_inform_tag 11 #define meshtastic_ClientNotification_key_verification_number_request_tag 12 #define meshtastic_ClientNotification_key_verification_final_tag 13 #define meshtastic_ClientNotification_duplicated_public_key_tag 14 #define meshtastic_ClientNotification_low_entropy_key_tag 15 -#define meshtastic_FileInfo_file_name_tag 1 -#define meshtastic_FileInfo_size_bytes_tag 2 -#define meshtastic_Compressed_portnum_tag 1 -#define meshtastic_Compressed_data_tag 2 -#define meshtastic_Neighbor_node_id_tag 1 -#define meshtastic_Neighbor_snr_tag 2 -#define meshtastic_Neighbor_last_rx_time_tag 3 +#define meshtastic_FileInfo_file_name_tag 1 +#define meshtastic_FileInfo_size_bytes_tag 2 +#define meshtastic_Compressed_portnum_tag 1 +#define meshtastic_Compressed_data_tag 2 +#define meshtastic_Neighbor_node_id_tag 1 +#define meshtastic_Neighbor_snr_tag 2 +#define meshtastic_Neighbor_last_rx_time_tag 3 #define meshtastic_Neighbor_node_broadcast_interval_secs_tag 4 -#define meshtastic_NeighborInfo_node_id_tag 1 +#define meshtastic_NeighborInfo_node_id_tag 1 #define meshtastic_NeighborInfo_last_sent_by_id_tag 2 #define meshtastic_NeighborInfo_node_broadcast_interval_secs_tag 3 -#define meshtastic_NeighborInfo_neighbors_tag 4 +#define meshtastic_NeighborInfo_neighbors_tag 4 #define meshtastic_DeviceMetadata_firmware_version_tag 1 #define meshtastic_DeviceMetadata_device_state_version_tag 2 #define meshtastic_DeviceMetadata_canShutdown_tag 3 -#define meshtastic_DeviceMetadata_hasWifi_tag 4 +#define meshtastic_DeviceMetadata_hasWifi_tag 4 #define meshtastic_DeviceMetadata_hasBluetooth_tag 5 #define meshtastic_DeviceMetadata_hasEthernet_tag 6 -#define meshtastic_DeviceMetadata_role_tag 7 +#define meshtastic_DeviceMetadata_role_tag 7 #define meshtastic_DeviceMetadata_position_flags_tag 8 -#define meshtastic_DeviceMetadata_hw_model_tag 9 +#define meshtastic_DeviceMetadata_hw_model_tag 9 #define meshtastic_DeviceMetadata_hasRemoteHardware_tag 10 -#define meshtastic_DeviceMetadata_hasPKC_tag 11 +#define meshtastic_DeviceMetadata_hasPKC_tag 11 #define meshtastic_DeviceMetadata_excluded_modules_tag 12 -#define meshtastic_FromRadio_id_tag 1 -#define meshtastic_FromRadio_packet_tag 2 -#define meshtastic_FromRadio_my_info_tag 3 -#define meshtastic_FromRadio_node_info_tag 4 -#define meshtastic_FromRadio_config_tag 5 -#define meshtastic_FromRadio_log_record_tag 6 +#define meshtastic_FromRadio_id_tag 1 +#define meshtastic_FromRadio_packet_tag 2 +#define meshtastic_FromRadio_my_info_tag 3 +#define meshtastic_FromRadio_node_info_tag 4 +#define meshtastic_FromRadio_config_tag 5 +#define meshtastic_FromRadio_log_record_tag 6 #define meshtastic_FromRadio_config_complete_id_tag 7 -#define meshtastic_FromRadio_rebooted_tag 8 -#define meshtastic_FromRadio_moduleConfig_tag 9 -#define meshtastic_FromRadio_channel_tag 10 -#define meshtastic_FromRadio_queueStatus_tag 11 -#define meshtastic_FromRadio_xmodemPacket_tag 12 -#define meshtastic_FromRadio_metadata_tag 13 +#define meshtastic_FromRadio_rebooted_tag 8 +#define meshtastic_FromRadio_moduleConfig_tag 9 +#define meshtastic_FromRadio_channel_tag 10 +#define meshtastic_FromRadio_queueStatus_tag 11 +#define meshtastic_FromRadio_xmodemPacket_tag 12 +#define meshtastic_FromRadio_metadata_tag 13 #define meshtastic_FromRadio_mqttClientProxyMessage_tag 14 -#define meshtastic_FromRadio_fileInfo_tag 15 +#define meshtastic_FromRadio_fileInfo_tag 15 #define meshtastic_FromRadio_clientNotification_tag 16 -#define meshtastic_FromRadio_deviceuiConfig_tag 17 -#define meshtastic_Heartbeat_nonce_tag 1 -#define meshtastic_ToRadio_packet_tag 1 -#define meshtastic_ToRadio_want_config_id_tag 3 -#define meshtastic_ToRadio_disconnect_tag 4 -#define meshtastic_ToRadio_xmodemPacket_tag 5 +#define meshtastic_FromRadio_deviceuiConfig_tag 17 +#define meshtastic_Heartbeat_nonce_tag 1 +#define meshtastic_ToRadio_packet_tag 1 +#define meshtastic_ToRadio_want_config_id_tag 3 +#define meshtastic_ToRadio_disconnect_tag 4 +#define meshtastic_ToRadio_xmodemPacket_tag 5 #define meshtastic_ToRadio_mqttClientProxyMessage_tag 6 -#define meshtastic_ToRadio_heartbeat_tag 7 +#define meshtastic_ToRadio_heartbeat_tag 7 #define meshtastic_NodeRemoteHardwarePin_node_num_tag 1 #define meshtastic_NodeRemoteHardwarePin_pin_tag 2 #define meshtastic_ChunkedPayload_payload_id_tag 1 #define meshtastic_ChunkedPayload_chunk_count_tag 2 #define meshtastic_ChunkedPayload_chunk_index_tag 3 #define meshtastic_ChunkedPayload_payload_chunk_tag 4 -#define meshtastic_resend_chunks_chunks_tag 1 +#define meshtastic_resend_chunks_chunks_tag 1 #define meshtastic_ChunkedPayloadResponse_payload_id_tag 1 #define meshtastic_ChunkedPayloadResponse_request_transfer_tag 2 #define meshtastic_ChunkedPayloadResponse_accept_transfer_tag 3 #define meshtastic_ChunkedPayloadResponse_resend_chunks_tag 4 /* Struct field encoding specification for nanopb */ -#define meshtastic_Position_FIELDLIST(X, a) \ -X(a, STATIC, OPTIONAL, SFIXED32, latitude_i, 1) \ -X(a, STATIC, OPTIONAL, SFIXED32, longitude_i, 2) \ -X(a, STATIC, OPTIONAL, INT32, altitude, 3) \ -X(a, STATIC, SINGULAR, FIXED32, time, 4) \ -X(a, STATIC, SINGULAR, UENUM, location_source, 5) \ -X(a, STATIC, SINGULAR, UENUM, altitude_source, 6) \ -X(a, STATIC, SINGULAR, FIXED32, timestamp, 7) \ -X(a, STATIC, SINGULAR, INT32, timestamp_millis_adjust, 8) \ -X(a, STATIC, OPTIONAL, SINT32, altitude_hae, 9) \ -X(a, STATIC, OPTIONAL, SINT32, altitude_geoidal_separation, 10) \ -X(a, STATIC, SINGULAR, UINT32, PDOP, 11) \ -X(a, STATIC, SINGULAR, UINT32, HDOP, 12) \ -X(a, STATIC, SINGULAR, UINT32, VDOP, 13) \ -X(a, STATIC, SINGULAR, UINT32, gps_accuracy, 14) \ -X(a, STATIC, OPTIONAL, UINT32, ground_speed, 15) \ -X(a, STATIC, OPTIONAL, UINT32, ground_track, 16) \ -X(a, STATIC, SINGULAR, UINT32, fix_quality, 17) \ -X(a, STATIC, SINGULAR, UINT32, fix_type, 18) \ -X(a, STATIC, SINGULAR, UINT32, sats_in_view, 19) \ -X(a, STATIC, SINGULAR, UINT32, sensor_id, 20) \ -X(a, STATIC, SINGULAR, UINT32, next_update, 21) \ -X(a, STATIC, SINGULAR, UINT32, seq_number, 22) \ -X(a, STATIC, SINGULAR, UINT32, precision_bits, 23) +#define meshtastic_Position_FIELDLIST(X, a) \ + X(a, STATIC, OPTIONAL, SFIXED32, latitude_i, 1) \ + X(a, STATIC, OPTIONAL, SFIXED32, longitude_i, 2) \ + X(a, STATIC, OPTIONAL, INT32, altitude, 3) \ + X(a, STATIC, SINGULAR, FIXED32, time, 4) \ + X(a, STATIC, SINGULAR, UENUM, location_source, 5) \ + X(a, STATIC, SINGULAR, UENUM, altitude_source, 6) \ + X(a, STATIC, SINGULAR, FIXED32, timestamp, 7) \ + X(a, STATIC, SINGULAR, INT32, timestamp_millis_adjust, 8) \ + X(a, STATIC, OPTIONAL, SINT32, altitude_hae, 9) \ + X(a, STATIC, OPTIONAL, SINT32, altitude_geoidal_separation, 10) \ + X(a, STATIC, SINGULAR, UINT32, PDOP, 11) \ + X(a, STATIC, SINGULAR, UINT32, HDOP, 12) \ + X(a, STATIC, SINGULAR, UINT32, VDOP, 13) \ + X(a, STATIC, SINGULAR, UINT32, gps_accuracy, 14) \ + X(a, STATIC, OPTIONAL, UINT32, ground_speed, 15) \ + X(a, STATIC, OPTIONAL, UINT32, ground_track, 16) \ + X(a, STATIC, SINGULAR, UINT32, fix_quality, 17) \ + X(a, STATIC, SINGULAR, UINT32, fix_type, 18) \ + X(a, STATIC, SINGULAR, UINT32, sats_in_view, 19) \ + X(a, STATIC, SINGULAR, UINT32, sensor_id, 20) \ + X(a, STATIC, SINGULAR, UINT32, next_update, 21) \ + X(a, STATIC, SINGULAR, UINT32, seq_number, 22) \ + X(a, STATIC, SINGULAR, UINT32, precision_bits, 23) #define meshtastic_Position_CALLBACK NULL #define meshtastic_Position_DEFAULT NULL -#define meshtastic_User_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, id, 1) \ -X(a, STATIC, SINGULAR, STRING, long_name, 2) \ -X(a, STATIC, SINGULAR, STRING, short_name, 3) \ -X(a, STATIC, SINGULAR, FIXED_LENGTH_BYTES, macaddr, 4) \ -X(a, STATIC, SINGULAR, UENUM, hw_model, 5) \ -X(a, STATIC, SINGULAR, BOOL, is_licensed, 6) \ -X(a, STATIC, SINGULAR, UENUM, role, 7) \ -X(a, STATIC, SINGULAR, BYTES, public_key, 8) \ -X(a, STATIC, OPTIONAL, BOOL, is_unmessagable, 9) +#define meshtastic_User_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, STRING, id, 1) \ + X(a, STATIC, SINGULAR, STRING, long_name, 2) \ + X(a, STATIC, SINGULAR, STRING, short_name, 3) \ + X(a, STATIC, SINGULAR, FIXED_LENGTH_BYTES, macaddr, 4) \ + X(a, STATIC, SINGULAR, UENUM, hw_model, 5) \ + X(a, STATIC, SINGULAR, BOOL, is_licensed, 6) \ + X(a, STATIC, SINGULAR, UENUM, role, 7) \ + X(a, STATIC, SINGULAR, BYTES, public_key, 8) \ + X(a, STATIC, OPTIONAL, BOOL, is_unmessagable, 9) #define meshtastic_User_CALLBACK NULL #define meshtastic_User_DEFAULT NULL -#define meshtastic_RouteDiscovery_FIELDLIST(X, a) \ -X(a, STATIC, REPEATED, FIXED32, route, 1) \ -X(a, STATIC, REPEATED, INT32, snr_towards, 2) \ -X(a, STATIC, REPEATED, FIXED32, route_back, 3) \ -X(a, STATIC, REPEATED, INT32, snr_back, 4) +#define meshtastic_RouteDiscovery_FIELDLIST(X, a) \ + X(a, STATIC, REPEATED, FIXED32, route, 1) \ + X(a, STATIC, REPEATED, INT32, snr_towards, 2) \ + X(a, STATIC, REPEATED, FIXED32, route_back, 3) \ + X(a, STATIC, REPEATED, INT32, snr_back, 4) #define meshtastic_RouteDiscovery_CALLBACK NULL #define meshtastic_RouteDiscovery_DEFAULT NULL -#define meshtastic_Routing_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, MESSAGE, (variant,route_request,route_request), 1) \ -X(a, STATIC, ONEOF, MESSAGE, (variant,route_reply,route_reply), 2) \ -X(a, STATIC, ONEOF, UENUM, (variant,error_reason,error_reason), 3) +#define meshtastic_Routing_FIELDLIST(X, a) \ + X(a, STATIC, ONEOF, MESSAGE, (variant, route_request, route_request), 1) \ + X(a, STATIC, ONEOF, MESSAGE, (variant, route_reply, route_reply), 2) \ + X(a, STATIC, ONEOF, UENUM, (variant, error_reason, error_reason), 3) #define meshtastic_Routing_CALLBACK NULL #define meshtastic_Routing_DEFAULT NULL #define meshtastic_Routing_variant_route_request_MSGTYPE meshtastic_RouteDiscovery #define meshtastic_Routing_variant_route_reply_MSGTYPE meshtastic_RouteDiscovery -#define meshtastic_Data_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UENUM, portnum, 1) \ -X(a, STATIC, SINGULAR, BYTES, payload, 2) \ -X(a, STATIC, SINGULAR, BOOL, want_response, 3) \ -X(a, STATIC, SINGULAR, FIXED32, dest, 4) \ -X(a, STATIC, SINGULAR, FIXED32, source, 5) \ -X(a, STATIC, SINGULAR, FIXED32, request_id, 6) \ -X(a, STATIC, SINGULAR, FIXED32, reply_id, 7) \ -X(a, STATIC, SINGULAR, FIXED32, emoji, 8) \ -X(a, STATIC, OPTIONAL, UINT32, bitfield, 9) +#define meshtastic_Data_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UENUM, portnum, 1) \ + X(a, STATIC, SINGULAR, BYTES, payload, 2) \ + X(a, STATIC, SINGULAR, BOOL, want_response, 3) \ + X(a, STATIC, SINGULAR, FIXED32, dest, 4) \ + X(a, STATIC, SINGULAR, FIXED32, source, 5) \ + X(a, STATIC, SINGULAR, FIXED32, request_id, 6) \ + X(a, STATIC, SINGULAR, FIXED32, reply_id, 7) \ + X(a, STATIC, SINGULAR, FIXED32, emoji, 8) \ + X(a, STATIC, OPTIONAL, UINT32, bitfield, 9) #define meshtastic_Data_CALLBACK NULL #define meshtastic_Data_DEFAULT NULL #define meshtastic_KeyVerification_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT64, nonce, 1) \ -X(a, STATIC, SINGULAR, BYTES, hash1, 2) \ -X(a, STATIC, SINGULAR, BYTES, hash2, 3) + X(a, STATIC, SINGULAR, UINT64, nonce, 1) \ + X(a, STATIC, SINGULAR, BYTES, hash1, 2) \ + X(a, STATIC, SINGULAR, BYTES, hash2, 3) #define meshtastic_KeyVerification_CALLBACK NULL #define meshtastic_KeyVerification_DEFAULT NULL -#define meshtastic_Waypoint_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, id, 1) \ -X(a, STATIC, OPTIONAL, SFIXED32, latitude_i, 2) \ -X(a, STATIC, OPTIONAL, SFIXED32, longitude_i, 3) \ -X(a, STATIC, SINGULAR, UINT32, expire, 4) \ -X(a, STATIC, SINGULAR, UINT32, locked_to, 5) \ -X(a, STATIC, SINGULAR, STRING, name, 6) \ -X(a, STATIC, SINGULAR, STRING, description, 7) \ -X(a, STATIC, SINGULAR, FIXED32, icon, 8) +#define meshtastic_Waypoint_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UINT32, id, 1) \ + X(a, STATIC, OPTIONAL, SFIXED32, latitude_i, 2) \ + X(a, STATIC, OPTIONAL, SFIXED32, longitude_i, 3) \ + X(a, STATIC, SINGULAR, UINT32, expire, 4) \ + X(a, STATIC, SINGULAR, UINT32, locked_to, 5) \ + X(a, STATIC, SINGULAR, STRING, name, 6) \ + X(a, STATIC, SINGULAR, STRING, description, 7) \ + X(a, STATIC, SINGULAR, FIXED32, icon, 8) #define meshtastic_Waypoint_CALLBACK NULL #define meshtastic_Waypoint_DEFAULT NULL -#define meshtastic_MqttClientProxyMessage_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, topic, 1) \ -X(a, STATIC, ONEOF, BYTES, (payload_variant,data,payload_variant.data), 2) \ -X(a, STATIC, ONEOF, STRING, (payload_variant,text,payload_variant.text), 3) \ -X(a, STATIC, SINGULAR, BOOL, retained, 4) +#define meshtastic_MqttClientProxyMessage_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, STRING, topic, 1) \ + X(a, STATIC, ONEOF, BYTES, (payload_variant, data, payload_variant.data), 2) \ + X(a, STATIC, ONEOF, STRING, (payload_variant, text, payload_variant.text), 3) \ + X(a, STATIC, SINGULAR, BOOL, retained, 4) #define meshtastic_MqttClientProxyMessage_CALLBACK NULL #define meshtastic_MqttClientProxyMessage_DEFAULT NULL -#define meshtastic_MeshPacket_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, FIXED32, from, 1) \ -X(a, STATIC, SINGULAR, FIXED32, to, 2) \ -X(a, STATIC, SINGULAR, UINT32, channel, 3) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,decoded,decoded), 4) \ -X(a, STATIC, ONEOF, BYTES, (payload_variant,encrypted,encrypted), 5) \ -X(a, STATIC, SINGULAR, FIXED32, id, 6) \ -X(a, STATIC, SINGULAR, FIXED32, rx_time, 7) \ -X(a, STATIC, SINGULAR, FLOAT, rx_snr, 8) \ -X(a, STATIC, SINGULAR, UINT32, hop_limit, 9) \ -X(a, STATIC, SINGULAR, BOOL, want_ack, 10) \ -X(a, STATIC, SINGULAR, UENUM, priority, 11) \ -X(a, STATIC, SINGULAR, INT32, rx_rssi, 12) \ -X(a, STATIC, SINGULAR, UENUM, delayed, 13) \ -X(a, STATIC, SINGULAR, BOOL, via_mqtt, 14) \ -X(a, STATIC, SINGULAR, UINT32, hop_start, 15) \ -X(a, STATIC, SINGULAR, BYTES, public_key, 16) \ -X(a, STATIC, SINGULAR, BOOL, pki_encrypted, 17) \ -X(a, STATIC, SINGULAR, UINT32, next_hop, 18) \ -X(a, STATIC, SINGULAR, UINT32, relay_node, 19) \ -X(a, STATIC, SINGULAR, UINT32, tx_after, 20) \ -X(a, STATIC, SINGULAR, UENUM, transport_mechanism, 21) +#define meshtastic_MeshPacket_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, FIXED32, from, 1) \ + X(a, STATIC, SINGULAR, FIXED32, to, 2) \ + X(a, STATIC, SINGULAR, UINT32, channel, 3) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, decoded, decoded), 4) \ + X(a, STATIC, ONEOF, BYTES, (payload_variant, encrypted, encrypted), 5) \ + X(a, STATIC, SINGULAR, FIXED32, id, 6) \ + X(a, STATIC, SINGULAR, FIXED32, rx_time, 7) \ + X(a, STATIC, SINGULAR, FLOAT, rx_snr, 8) \ + X(a, STATIC, SINGULAR, UINT32, hop_limit, 9) \ + X(a, STATIC, SINGULAR, BOOL, want_ack, 10) \ + X(a, STATIC, SINGULAR, UENUM, priority, 11) \ + X(a, STATIC, SINGULAR, INT32, rx_rssi, 12) \ + X(a, STATIC, SINGULAR, UENUM, delayed, 13) \ + X(a, STATIC, SINGULAR, BOOL, via_mqtt, 14) \ + X(a, STATIC, SINGULAR, UINT32, hop_start, 15) \ + X(a, STATIC, SINGULAR, BYTES, public_key, 16) \ + X(a, STATIC, SINGULAR, BOOL, pki_encrypted, 17) \ + X(a, STATIC, SINGULAR, UINT32, next_hop, 18) \ + X(a, STATIC, SINGULAR, UINT32, relay_node, 19) \ + X(a, STATIC, SINGULAR, UINT32, tx_after, 20) \ + X(a, STATIC, SINGULAR, UENUM, transport_mechanism, 21) #define meshtastic_MeshPacket_CALLBACK NULL #define meshtastic_MeshPacket_DEFAULT NULL #define meshtastic_MeshPacket_payload_variant_decoded_MSGTYPE meshtastic_Data -#define meshtastic_NodeInfo_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, num, 1) \ -X(a, STATIC, OPTIONAL, MESSAGE, user, 2) \ -X(a, STATIC, OPTIONAL, MESSAGE, position, 3) \ -X(a, STATIC, SINGULAR, FLOAT, snr, 4) \ -X(a, STATIC, SINGULAR, FIXED32, last_heard, 5) \ -X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6) \ -X(a, STATIC, SINGULAR, UINT32, channel, 7) \ -X(a, STATIC, SINGULAR, BOOL, via_mqtt, 8) \ -X(a, STATIC, OPTIONAL, UINT32, hops_away, 9) \ -X(a, STATIC, SINGULAR, BOOL, is_favorite, 10) \ -X(a, STATIC, SINGULAR, BOOL, is_ignored, 11) \ -X(a, STATIC, SINGULAR, BOOL, is_key_manually_verified, 12) +#define meshtastic_NodeInfo_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UINT32, num, 1) \ + X(a, STATIC, OPTIONAL, MESSAGE, user, 2) \ + X(a, STATIC, OPTIONAL, MESSAGE, position, 3) \ + X(a, STATIC, SINGULAR, FLOAT, snr, 4) \ + X(a, STATIC, SINGULAR, FIXED32, last_heard, 5) \ + X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6) \ + X(a, STATIC, SINGULAR, UINT32, channel, 7) \ + X(a, STATIC, SINGULAR, BOOL, via_mqtt, 8) \ + X(a, STATIC, OPTIONAL, UINT32, hops_away, 9) \ + X(a, STATIC, SINGULAR, BOOL, is_favorite, 10) \ + X(a, STATIC, SINGULAR, BOOL, is_ignored, 11) \ + X(a, STATIC, SINGULAR, BOOL, is_key_manually_verified, 12) #define meshtastic_NodeInfo_CALLBACK NULL #define meshtastic_NodeInfo_DEFAULT NULL #define meshtastic_NodeInfo_user_MSGTYPE meshtastic_User #define meshtastic_NodeInfo_position_MSGTYPE meshtastic_Position #define meshtastic_NodeInfo_device_metrics_MSGTYPE meshtastic_DeviceMetrics -#define meshtastic_MyNodeInfo_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, my_node_num, 1) \ -X(a, STATIC, SINGULAR, UINT32, reboot_count, 8) \ -X(a, STATIC, SINGULAR, UINT32, min_app_version, 11) \ -X(a, STATIC, SINGULAR, BYTES, device_id, 12) \ -X(a, STATIC, SINGULAR, STRING, pio_env, 13) \ -X(a, STATIC, SINGULAR, UENUM, firmware_edition, 14) \ -X(a, STATIC, SINGULAR, UINT32, nodedb_count, 15) +#define meshtastic_MyNodeInfo_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UINT32, my_node_num, 1) \ + X(a, STATIC, SINGULAR, UINT32, reboot_count, 8) \ + X(a, STATIC, SINGULAR, UINT32, min_app_version, 11) \ + X(a, STATIC, SINGULAR, BYTES, device_id, 12) \ + X(a, STATIC, SINGULAR, STRING, pio_env, 13) \ + X(a, STATIC, SINGULAR, UENUM, firmware_edition, 14) \ + X(a, STATIC, SINGULAR, UINT32, nodedb_count, 15) #define meshtastic_MyNodeInfo_CALLBACK NULL #define meshtastic_MyNodeInfo_DEFAULT NULL -#define meshtastic_LogRecord_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, message, 1) \ -X(a, STATIC, SINGULAR, FIXED32, time, 2) \ -X(a, STATIC, SINGULAR, STRING, source, 3) \ -X(a, STATIC, SINGULAR, UENUM, level, 4) +#define meshtastic_LogRecord_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, STRING, message, 1) \ + X(a, STATIC, SINGULAR, FIXED32, time, 2) \ + X(a, STATIC, SINGULAR, STRING, source, 3) \ + X(a, STATIC, SINGULAR, UENUM, level, 4) #define meshtastic_LogRecord_CALLBACK NULL #define meshtastic_LogRecord_DEFAULT NULL #define meshtastic_QueueStatus_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, INT32, res, 1) \ -X(a, STATIC, SINGULAR, UINT32, free, 2) \ -X(a, STATIC, SINGULAR, UINT32, maxlen, 3) \ -X(a, STATIC, SINGULAR, UINT32, mesh_packet_id, 4) + X(a, STATIC, SINGULAR, INT32, res, 1) \ + X(a, STATIC, SINGULAR, UINT32, free, 2) \ + X(a, STATIC, SINGULAR, UINT32, maxlen, 3) \ + X(a, STATIC, SINGULAR, UINT32, mesh_packet_id, 4) #define meshtastic_QueueStatus_CALLBACK NULL #define meshtastic_QueueStatus_DEFAULT NULL -#define meshtastic_FromRadio_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, id, 1) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,packet,packet), 2) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,my_info,my_info), 3) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,node_info,node_info), 4) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,config,config), 5) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,log_record,log_record), 6) \ -X(a, STATIC, ONEOF, UINT32, (payload_variant,config_complete_id,config_complete_id), 7) \ -X(a, STATIC, ONEOF, BOOL, (payload_variant,rebooted,rebooted), 8) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,moduleConfig,moduleConfig), 9) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,channel,channel), 10) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,queueStatus,queueStatus), 11) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,xmodemPacket,xmodemPacket), 12) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,metadata,metadata), 13) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,mqttClientProxyMessage,mqttClientProxyMessage), 14) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,fileInfo,fileInfo), 15) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,clientNotification,clientNotification), 16) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,deviceuiConfig,deviceuiConfig), 17) +#define meshtastic_FromRadio_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UINT32, id, 1) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, packet, packet), 2) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, my_info, my_info), 3) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, node_info, node_info), 4) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, config, config), 5) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, log_record, log_record), 6) \ + X(a, STATIC, ONEOF, UINT32, (payload_variant, config_complete_id, config_complete_id), 7) \ + X(a, STATIC, ONEOF, BOOL, (payload_variant, rebooted, rebooted), 8) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, moduleConfig, moduleConfig), 9) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, channel, channel), 10) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, queueStatus, queueStatus), 11) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, xmodemPacket, xmodemPacket), 12) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, metadata, metadata), 13) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, mqttClientProxyMessage, mqttClientProxyMessage), 14) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, fileInfo, fileInfo), 15) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, clientNotification, clientNotification), 16) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, deviceuiConfig, deviceuiConfig), 17) #define meshtastic_FromRadio_CALLBACK NULL #define meshtastic_FromRadio_DEFAULT NULL #define meshtastic_FromRadio_payload_variant_packet_MSGTYPE meshtastic_MeshPacket @@ -1832,16 +2068,16 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,deviceuiConfig,deviceuiConfi #define meshtastic_FromRadio_payload_variant_clientNotification_MSGTYPE meshtastic_ClientNotification #define meshtastic_FromRadio_payload_variant_deviceuiConfig_MSGTYPE meshtastic_DeviceUIConfig -#define meshtastic_ClientNotification_FIELDLIST(X, a) \ -X(a, STATIC, OPTIONAL, UINT32, reply_id, 1) \ -X(a, STATIC, SINGULAR, FIXED32, time, 2) \ -X(a, STATIC, SINGULAR, UENUM, level, 3) \ -X(a, STATIC, SINGULAR, STRING, message, 4) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,key_verification_number_inform,payload_variant.key_verification_number_inform), 11) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,key_verification_number_request,payload_variant.key_verification_number_request), 12) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,key_verification_final,payload_variant.key_verification_final), 13) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,duplicated_public_key,payload_variant.duplicated_public_key), 14) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,low_entropy_key,payload_variant.low_entropy_key), 15) +#define meshtastic_ClientNotification_FIELDLIST(X, a) \ + X(a, STATIC, OPTIONAL, UINT32, reply_id, 1) \ + X(a, STATIC, SINGULAR, FIXED32, time, 2) \ + X(a, STATIC, SINGULAR, UENUM, level, 3) \ + X(a, STATIC, SINGULAR, STRING, message, 4) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, key_verification_number_inform, payload_variant.key_verification_number_inform), 11) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, key_verification_number_request, payload_variant.key_verification_number_request), 12) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, key_verification_final, payload_variant.key_verification_final), 13) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, duplicated_public_key, payload_variant.duplicated_public_key), 14) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, low_entropy_key, payload_variant.low_entropy_key), 15) #define meshtastic_ClientNotification_CALLBACK NULL #define meshtastic_ClientNotification_DEFAULT NULL #define meshtastic_ClientNotification_payload_variant_key_verification_number_inform_MSGTYPE meshtastic_KeyVerificationNumberInform @@ -1851,49 +2087,49 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,low_entropy_key,payload_vari #define meshtastic_ClientNotification_payload_variant_low_entropy_key_MSGTYPE meshtastic_LowEntropyKey #define meshtastic_KeyVerificationNumberInform_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT64, nonce, 1) \ -X(a, STATIC, SINGULAR, STRING, remote_longname, 2) \ -X(a, STATIC, SINGULAR, UINT32, security_number, 3) + X(a, STATIC, SINGULAR, UINT64, nonce, 1) \ + X(a, STATIC, SINGULAR, STRING, remote_longname, 2) \ + X(a, STATIC, SINGULAR, UINT32, security_number, 3) #define meshtastic_KeyVerificationNumberInform_CALLBACK NULL #define meshtastic_KeyVerificationNumberInform_DEFAULT NULL #define meshtastic_KeyVerificationNumberRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT64, nonce, 1) \ -X(a, STATIC, SINGULAR, STRING, remote_longname, 2) + X(a, STATIC, SINGULAR, UINT64, nonce, 1) \ + X(a, STATIC, SINGULAR, STRING, remote_longname, 2) #define meshtastic_KeyVerificationNumberRequest_CALLBACK NULL #define meshtastic_KeyVerificationNumberRequest_DEFAULT NULL #define meshtastic_KeyVerificationFinal_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT64, nonce, 1) \ -X(a, STATIC, SINGULAR, STRING, remote_longname, 2) \ -X(a, STATIC, SINGULAR, BOOL, isSender, 3) \ -X(a, STATIC, SINGULAR, STRING, verification_characters, 4) + X(a, STATIC, SINGULAR, UINT64, nonce, 1) \ + X(a, STATIC, SINGULAR, STRING, remote_longname, 2) \ + X(a, STATIC, SINGULAR, BOOL, isSender, 3) \ + X(a, STATIC, SINGULAR, STRING, verification_characters, 4) #define meshtastic_KeyVerificationFinal_CALLBACK NULL #define meshtastic_KeyVerificationFinal_DEFAULT NULL -#define meshtastic_DuplicatedPublicKey_FIELDLIST(X, a) \ +#define meshtastic_DuplicatedPublicKey_FIELDLIST(X, a) #define meshtastic_DuplicatedPublicKey_CALLBACK NULL #define meshtastic_DuplicatedPublicKey_DEFAULT NULL -#define meshtastic_LowEntropyKey_FIELDLIST(X, a) \ +#define meshtastic_LowEntropyKey_FIELDLIST(X, a) #define meshtastic_LowEntropyKey_CALLBACK NULL #define meshtastic_LowEntropyKey_DEFAULT NULL -#define meshtastic_FileInfo_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, file_name, 1) \ -X(a, STATIC, SINGULAR, UINT32, size_bytes, 2) +#define meshtastic_FileInfo_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, STRING, file_name, 1) \ + X(a, STATIC, SINGULAR, UINT32, size_bytes, 2) #define meshtastic_FileInfo_CALLBACK NULL #define meshtastic_FileInfo_DEFAULT NULL -#define meshtastic_ToRadio_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,packet,packet), 1) \ -X(a, STATIC, ONEOF, UINT32, (payload_variant,want_config_id,want_config_id), 3) \ -X(a, STATIC, ONEOF, BOOL, (payload_variant,disconnect,disconnect), 4) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,xmodemPacket,xmodemPacket), 5) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,mqttClientProxyMessage,mqttClientProxyMessage), 6) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,heartbeat,heartbeat), 7) +#define meshtastic_ToRadio_FIELDLIST(X, a) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, packet, packet), 1) \ + X(a, STATIC, ONEOF, UINT32, (payload_variant, want_config_id, want_config_id), 3) \ + X(a, STATIC, ONEOF, BOOL, (payload_variant, disconnect, disconnect), 4) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, xmodemPacket, xmodemPacket), 5) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, mqttClientProxyMessage, mqttClientProxyMessage), 6) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, heartbeat, heartbeat), 7) #define meshtastic_ToRadio_CALLBACK NULL #define meshtastic_ToRadio_DEFAULT NULL #define meshtastic_ToRadio_payload_variant_packet_MSGTYPE meshtastic_MeshPacket @@ -1902,109 +2138,109 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,heartbeat,heartbeat), 7) #define meshtastic_ToRadio_payload_variant_heartbeat_MSGTYPE meshtastic_Heartbeat #define meshtastic_Compressed_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UENUM, portnum, 1) \ -X(a, STATIC, SINGULAR, BYTES, data, 2) + X(a, STATIC, SINGULAR, UENUM, portnum, 1) \ + X(a, STATIC, SINGULAR, BYTES, data, 2) #define meshtastic_Compressed_CALLBACK NULL #define meshtastic_Compressed_DEFAULT NULL -#define meshtastic_NeighborInfo_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, node_id, 1) \ -X(a, STATIC, SINGULAR, UINT32, last_sent_by_id, 2) \ -X(a, STATIC, SINGULAR, UINT32, node_broadcast_interval_secs, 3) \ -X(a, STATIC, REPEATED, MESSAGE, neighbors, 4) +#define meshtastic_NeighborInfo_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UINT32, node_id, 1) \ + X(a, STATIC, SINGULAR, UINT32, last_sent_by_id, 2) \ + X(a, STATIC, SINGULAR, UINT32, node_broadcast_interval_secs, 3) \ + X(a, STATIC, REPEATED, MESSAGE, neighbors, 4) #define meshtastic_NeighborInfo_CALLBACK NULL #define meshtastic_NeighborInfo_DEFAULT NULL #define meshtastic_NeighborInfo_neighbors_MSGTYPE meshtastic_Neighbor -#define meshtastic_Neighbor_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, node_id, 1) \ -X(a, STATIC, SINGULAR, FLOAT, snr, 2) \ -X(a, STATIC, SINGULAR, FIXED32, last_rx_time, 3) \ -X(a, STATIC, SINGULAR, UINT32, node_broadcast_interval_secs, 4) +#define meshtastic_Neighbor_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UINT32, node_id, 1) \ + X(a, STATIC, SINGULAR, FLOAT, snr, 2) \ + X(a, STATIC, SINGULAR, FIXED32, last_rx_time, 3) \ + X(a, STATIC, SINGULAR, UINT32, node_broadcast_interval_secs, 4) #define meshtastic_Neighbor_CALLBACK NULL #define meshtastic_Neighbor_DEFAULT NULL -#define meshtastic_DeviceMetadata_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, firmware_version, 1) \ -X(a, STATIC, SINGULAR, UINT32, device_state_version, 2) \ -X(a, STATIC, SINGULAR, BOOL, canShutdown, 3) \ -X(a, STATIC, SINGULAR, BOOL, hasWifi, 4) \ -X(a, STATIC, SINGULAR, BOOL, hasBluetooth, 5) \ -X(a, STATIC, SINGULAR, BOOL, hasEthernet, 6) \ -X(a, STATIC, SINGULAR, UENUM, role, 7) \ -X(a, STATIC, SINGULAR, UINT32, position_flags, 8) \ -X(a, STATIC, SINGULAR, UENUM, hw_model, 9) \ -X(a, STATIC, SINGULAR, BOOL, hasRemoteHardware, 10) \ -X(a, STATIC, SINGULAR, BOOL, hasPKC, 11) \ -X(a, STATIC, SINGULAR, UINT32, excluded_modules, 12) +#define meshtastic_DeviceMetadata_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, STRING, firmware_version, 1) \ + X(a, STATIC, SINGULAR, UINT32, device_state_version, 2) \ + X(a, STATIC, SINGULAR, BOOL, canShutdown, 3) \ + X(a, STATIC, SINGULAR, BOOL, hasWifi, 4) \ + X(a, STATIC, SINGULAR, BOOL, hasBluetooth, 5) \ + X(a, STATIC, SINGULAR, BOOL, hasEthernet, 6) \ + X(a, STATIC, SINGULAR, UENUM, role, 7) \ + X(a, STATIC, SINGULAR, UINT32, position_flags, 8) \ + X(a, STATIC, SINGULAR, UENUM, hw_model, 9) \ + X(a, STATIC, SINGULAR, BOOL, hasRemoteHardware, 10) \ + X(a, STATIC, SINGULAR, BOOL, hasPKC, 11) \ + X(a, STATIC, SINGULAR, UINT32, excluded_modules, 12) #define meshtastic_DeviceMetadata_CALLBACK NULL #define meshtastic_DeviceMetadata_DEFAULT NULL #define meshtastic_Heartbeat_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, nonce, 1) + X(a, STATIC, SINGULAR, UINT32, nonce, 1) #define meshtastic_Heartbeat_CALLBACK NULL #define meshtastic_Heartbeat_DEFAULT NULL #define meshtastic_NodeRemoteHardwarePin_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, node_num, 1) \ -X(a, STATIC, OPTIONAL, MESSAGE, pin, 2) + X(a, STATIC, SINGULAR, UINT32, node_num, 1) \ + X(a, STATIC, OPTIONAL, MESSAGE, pin, 2) #define meshtastic_NodeRemoteHardwarePin_CALLBACK NULL #define meshtastic_NodeRemoteHardwarePin_DEFAULT NULL #define meshtastic_NodeRemoteHardwarePin_pin_MSGTYPE meshtastic_RemoteHardwarePin -#define meshtastic_ChunkedPayload_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, payload_id, 1) \ -X(a, STATIC, SINGULAR, UINT32, chunk_count, 2) \ -X(a, STATIC, SINGULAR, UINT32, chunk_index, 3) \ -X(a, STATIC, SINGULAR, BYTES, payload_chunk, 4) +#define meshtastic_ChunkedPayload_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UINT32, payload_id, 1) \ + X(a, STATIC, SINGULAR, UINT32, chunk_count, 2) \ + X(a, STATIC, SINGULAR, UINT32, chunk_index, 3) \ + X(a, STATIC, SINGULAR, BYTES, payload_chunk, 4) #define meshtastic_ChunkedPayload_CALLBACK NULL #define meshtastic_ChunkedPayload_DEFAULT NULL #define meshtastic_resend_chunks_FIELDLIST(X, a) \ -X(a, CALLBACK, REPEATED, UINT32, chunks, 1) + X(a, CALLBACK, REPEATED, UINT32, chunks, 1) #define meshtastic_resend_chunks_CALLBACK pb_default_field_callback #define meshtastic_resend_chunks_DEFAULT NULL -#define meshtastic_ChunkedPayloadResponse_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, payload_id, 1) \ -X(a, STATIC, ONEOF, BOOL, (payload_variant,request_transfer,payload_variant.request_transfer), 2) \ -X(a, STATIC, ONEOF, BOOL, (payload_variant,accept_transfer,payload_variant.accept_transfer), 3) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,resend_chunks,payload_variant.resend_chunks), 4) +#define meshtastic_ChunkedPayloadResponse_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UINT32, payload_id, 1) \ + X(a, STATIC, ONEOF, BOOL, (payload_variant, request_transfer, payload_variant.request_transfer), 2) \ + X(a, STATIC, ONEOF, BOOL, (payload_variant, accept_transfer, payload_variant.accept_transfer), 3) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, resend_chunks, payload_variant.resend_chunks), 4) #define meshtastic_ChunkedPayloadResponse_CALLBACK NULL #define meshtastic_ChunkedPayloadResponse_DEFAULT NULL #define meshtastic_ChunkedPayloadResponse_payload_variant_resend_chunks_MSGTYPE meshtastic_resend_chunks -extern const pb_msgdesc_t meshtastic_Position_msg; -extern const pb_msgdesc_t meshtastic_User_msg; -extern const pb_msgdesc_t meshtastic_RouteDiscovery_msg; -extern const pb_msgdesc_t meshtastic_Routing_msg; -extern const pb_msgdesc_t meshtastic_Data_msg; -extern const pb_msgdesc_t meshtastic_KeyVerification_msg; -extern const pb_msgdesc_t meshtastic_Waypoint_msg; -extern const pb_msgdesc_t meshtastic_MqttClientProxyMessage_msg; -extern const pb_msgdesc_t meshtastic_MeshPacket_msg; -extern const pb_msgdesc_t meshtastic_NodeInfo_msg; -extern const pb_msgdesc_t meshtastic_MyNodeInfo_msg; -extern const pb_msgdesc_t meshtastic_LogRecord_msg; -extern const pb_msgdesc_t meshtastic_QueueStatus_msg; -extern const pb_msgdesc_t meshtastic_FromRadio_msg; -extern const pb_msgdesc_t meshtastic_ClientNotification_msg; -extern const pb_msgdesc_t meshtastic_KeyVerificationNumberInform_msg; -extern const pb_msgdesc_t meshtastic_KeyVerificationNumberRequest_msg; -extern const pb_msgdesc_t meshtastic_KeyVerificationFinal_msg; -extern const pb_msgdesc_t meshtastic_DuplicatedPublicKey_msg; -extern const pb_msgdesc_t meshtastic_LowEntropyKey_msg; -extern const pb_msgdesc_t meshtastic_FileInfo_msg; -extern const pb_msgdesc_t meshtastic_ToRadio_msg; -extern const pb_msgdesc_t meshtastic_Compressed_msg; -extern const pb_msgdesc_t meshtastic_NeighborInfo_msg; -extern const pb_msgdesc_t meshtastic_Neighbor_msg; -extern const pb_msgdesc_t meshtastic_DeviceMetadata_msg; -extern const pb_msgdesc_t meshtastic_Heartbeat_msg; -extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePin_msg; -extern const pb_msgdesc_t meshtastic_ChunkedPayload_msg; -extern const pb_msgdesc_t meshtastic_resend_chunks_msg; -extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg; + extern const pb_msgdesc_t meshtastic_Position_msg; + extern const pb_msgdesc_t meshtastic_User_msg; + extern const pb_msgdesc_t meshtastic_RouteDiscovery_msg; + extern const pb_msgdesc_t meshtastic_Routing_msg; + extern const pb_msgdesc_t meshtastic_Data_msg; + extern const pb_msgdesc_t meshtastic_KeyVerification_msg; + extern const pb_msgdesc_t meshtastic_Waypoint_msg; + extern const pb_msgdesc_t meshtastic_MqttClientProxyMessage_msg; + extern const pb_msgdesc_t meshtastic_MeshPacket_msg; + extern const pb_msgdesc_t meshtastic_NodeInfo_msg; + extern const pb_msgdesc_t meshtastic_MyNodeInfo_msg; + extern const pb_msgdesc_t meshtastic_LogRecord_msg; + extern const pb_msgdesc_t meshtastic_QueueStatus_msg; + extern const pb_msgdesc_t meshtastic_FromRadio_msg; + extern const pb_msgdesc_t meshtastic_ClientNotification_msg; + extern const pb_msgdesc_t meshtastic_KeyVerificationNumberInform_msg; + extern const pb_msgdesc_t meshtastic_KeyVerificationNumberRequest_msg; + extern const pb_msgdesc_t meshtastic_KeyVerificationFinal_msg; + extern const pb_msgdesc_t meshtastic_DuplicatedPublicKey_msg; + extern const pb_msgdesc_t meshtastic_LowEntropyKey_msg; + extern const pb_msgdesc_t meshtastic_FileInfo_msg; + extern const pb_msgdesc_t meshtastic_ToRadio_msg; + extern const pb_msgdesc_t meshtastic_Compressed_msg; + extern const pb_msgdesc_t meshtastic_NeighborInfo_msg; + extern const pb_msgdesc_t meshtastic_Neighbor_msg; + extern const pb_msgdesc_t meshtastic_DeviceMetadata_msg; + extern const pb_msgdesc_t meshtastic_Heartbeat_msg; + extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePin_msg; + extern const pb_msgdesc_t meshtastic_ChunkedPayload_msg; + extern const pb_msgdesc_t meshtastic_resend_chunks_msg; + extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_Position_fields &meshtastic_Position_msg @@ -2043,35 +2279,35 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg; /* meshtastic_resend_chunks_size depends on runtime parameters */ /* meshtastic_ChunkedPayloadResponse_size depends on runtime parameters */ #define MESHTASTIC_MESHTASTIC_MESH_PB_H_MAX_SIZE meshtastic_FromRadio_size -#define meshtastic_ChunkedPayload_size 245 -#define meshtastic_ClientNotification_size 482 -#define meshtastic_Compressed_size 239 -#define meshtastic_Data_size 269 -#define meshtastic_DeviceMetadata_size 54 -#define meshtastic_DuplicatedPublicKey_size 0 -#define meshtastic_FileInfo_size 236 -#define meshtastic_FromRadio_size 510 -#define meshtastic_Heartbeat_size 6 -#define meshtastic_KeyVerificationFinal_size 65 +#define meshtastic_ChunkedPayload_size 245 +#define meshtastic_ClientNotification_size 482 +#define meshtastic_Compressed_size 239 +#define meshtastic_Data_size 269 +#define meshtastic_DeviceMetadata_size 54 +#define meshtastic_DuplicatedPublicKey_size 0 +#define meshtastic_FileInfo_size 236 +#define meshtastic_FromRadio_size 510 +#define meshtastic_Heartbeat_size 6 +#define meshtastic_KeyVerificationFinal_size 65 #define meshtastic_KeyVerificationNumberInform_size 58 #define meshtastic_KeyVerificationNumberRequest_size 52 -#define meshtastic_KeyVerification_size 79 -#define meshtastic_LogRecord_size 426 -#define meshtastic_LowEntropyKey_size 0 -#define meshtastic_MeshPacket_size 381 -#define meshtastic_MqttClientProxyMessage_size 501 -#define meshtastic_MyNodeInfo_size 83 -#define meshtastic_NeighborInfo_size 258 -#define meshtastic_Neighbor_size 22 -#define meshtastic_NodeInfo_size 323 -#define meshtastic_NodeRemoteHardwarePin_size 29 -#define meshtastic_Position_size 144 -#define meshtastic_QueueStatus_size 23 -#define meshtastic_RouteDiscovery_size 256 -#define meshtastic_Routing_size 259 -#define meshtastic_ToRadio_size 504 -#define meshtastic_User_size 115 -#define meshtastic_Waypoint_size 165 +#define meshtastic_KeyVerification_size 79 +#define meshtastic_LogRecord_size 426 +#define meshtastic_LowEntropyKey_size 0 +#define meshtastic_MeshPacket_size 381 +#define meshtastic_MqttClientProxyMessage_size 501 +#define meshtastic_MyNodeInfo_size 83 +#define meshtastic_NeighborInfo_size 258 +#define meshtastic_Neighbor_size 22 +#define meshtastic_NodeInfo_size 323 +#define meshtastic_NodeRemoteHardwarePin_size 29 +#define meshtastic_Position_size 144 +#define meshtastic_QueueStatus_size 23 +#define meshtastic_RouteDiscovery_size 256 +#define meshtastic_Routing_size 259 +#define meshtastic_ToRadio_size 504 +#define meshtastic_User_size 115 +#define meshtastic_Waypoint_size 165 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/module_config.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/module_config.pb.cpp index f262df6a..a3caafed 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/module_config.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/module_config.pb.cpp @@ -8,62 +8,32 @@ PB_BIND(meshtastic_ModuleConfig, meshtastic_ModuleConfig, AUTO) - PB_BIND(meshtastic_ModuleConfig_MQTTConfig, meshtastic_ModuleConfig_MQTTConfig, AUTO) - PB_BIND(meshtastic_ModuleConfig_MapReportSettings, meshtastic_ModuleConfig_MapReportSettings, AUTO) - PB_BIND(meshtastic_ModuleConfig_RemoteHardwareConfig, meshtastic_ModuleConfig_RemoteHardwareConfig, AUTO) - PB_BIND(meshtastic_ModuleConfig_NeighborInfoConfig, meshtastic_ModuleConfig_NeighborInfoConfig, AUTO) - PB_BIND(meshtastic_ModuleConfig_DetectionSensorConfig, meshtastic_ModuleConfig_DetectionSensorConfig, AUTO) - PB_BIND(meshtastic_ModuleConfig_AudioConfig, meshtastic_ModuleConfig_AudioConfig, AUTO) - PB_BIND(meshtastic_ModuleConfig_PaxcounterConfig, meshtastic_ModuleConfig_PaxcounterConfig, AUTO) - PB_BIND(meshtastic_ModuleConfig_SerialConfig, meshtastic_ModuleConfig_SerialConfig, AUTO) - PB_BIND(meshtastic_ModuleConfig_ExternalNotificationConfig, meshtastic_ModuleConfig_ExternalNotificationConfig, AUTO) - PB_BIND(meshtastic_ModuleConfig_StoreForwardConfig, meshtastic_ModuleConfig_StoreForwardConfig, AUTO) - PB_BIND(meshtastic_ModuleConfig_RangeTestConfig, meshtastic_ModuleConfig_RangeTestConfig, AUTO) - PB_BIND(meshtastic_ModuleConfig_TelemetryConfig, meshtastic_ModuleConfig_TelemetryConfig, AUTO) - PB_BIND(meshtastic_ModuleConfig_CannedMessageConfig, meshtastic_ModuleConfig_CannedMessageConfig, AUTO) - PB_BIND(meshtastic_ModuleConfig_AmbientLightingConfig, meshtastic_ModuleConfig_AmbientLightingConfig, AUTO) - PB_BIND(meshtastic_RemoteHardwarePin, meshtastic_RemoteHardwarePin, AUTO) - - - - - - - - - - - - - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/module_config.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/module_config.pb.h index 47d3b5ba..a8d87e21 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/module_config.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/module_config.pb.h @@ -10,7 +10,8 @@ #endif /* Enum definitions */ -typedef enum _meshtastic_RemoteHardwarePinType { +typedef enum _meshtastic_RemoteHardwarePinType +{ /* Unset/unused */ meshtastic_RemoteHardwarePinType_UNKNOWN = 0, /* GPIO pin can be read (if it is high / low) */ @@ -19,7 +20,8 @@ typedef enum _meshtastic_RemoteHardwarePinType { meshtastic_RemoteHardwarePinType_DIGITAL_WRITE = 2 } meshtastic_RemoteHardwarePinType; -typedef enum _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType { +typedef enum _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType +{ /* Event is triggered if pin is low */ meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_LOW = 0, /* Event is triggered if pin is high */ @@ -37,7 +39,8 @@ typedef enum _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType { } meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType; /* Baudrate for codec2 voice */ -typedef enum _meshtastic_ModuleConfig_AudioConfig_Audio_Baud { +typedef enum _meshtastic_ModuleConfig_AudioConfig_Audio_Baud +{ meshtastic_ModuleConfig_AudioConfig_Audio_Baud_CODEC2_DEFAULT = 0, meshtastic_ModuleConfig_AudioConfig_Audio_Baud_CODEC2_3200 = 1, meshtastic_ModuleConfig_AudioConfig_Audio_Baud_CODEC2_2400 = 2, @@ -50,7 +53,8 @@ typedef enum _meshtastic_ModuleConfig_AudioConfig_Audio_Baud { } meshtastic_ModuleConfig_AudioConfig_Audio_Baud; /* TODO: REPLACE */ -typedef enum _meshtastic_ModuleConfig_SerialConfig_Serial_Baud { +typedef enum _meshtastic_ModuleConfig_SerialConfig_Serial_Baud +{ meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_DEFAULT = 0, meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_110 = 1, meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_300 = 2, @@ -70,7 +74,8 @@ typedef enum _meshtastic_ModuleConfig_SerialConfig_Serial_Baud { } meshtastic_ModuleConfig_SerialConfig_Serial_Baud; /* TODO: REPLACE */ -typedef enum _meshtastic_ModuleConfig_SerialConfig_Serial_Mode { +typedef enum _meshtastic_ModuleConfig_SerialConfig_Serial_Mode +{ meshtastic_ModuleConfig_SerialConfig_Serial_Mode_DEFAULT = 0, meshtastic_ModuleConfig_SerialConfig_Serial_Mode_SIMPLE = 1, meshtastic_ModuleConfig_SerialConfig_Serial_Mode_PROTO = 2, @@ -89,7 +94,8 @@ https://heltec.org/project/meshsolar/ */ } meshtastic_ModuleConfig_SerialConfig_Serial_Mode; /* TODO: REPLACE */ -typedef enum _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar { +typedef enum _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar +{ /* TODO: REPLACE */ meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE = 0, /* TODO: REPLACE */ @@ -110,7 +116,8 @@ typedef enum _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar { /* Struct definitions */ /* Settings for reporting unencrypted information about our node to a map via MQTT */ -typedef struct _meshtastic_ModuleConfig_MapReportSettings { +typedef struct _meshtastic_ModuleConfig_MapReportSettings +{ /* How often we should report our info to the map (in seconds) */ uint32_t publish_interval_secs; /* Bits of precision for the location sent (default of 32 is full precision). */ @@ -120,7 +127,8 @@ typedef struct _meshtastic_ModuleConfig_MapReportSettings { } meshtastic_ModuleConfig_MapReportSettings; /* MQTT Client Config */ -typedef struct _meshtastic_ModuleConfig_MQTTConfig { +typedef struct _meshtastic_ModuleConfig_MQTTConfig +{ /* If a meshtastic node is able to reach the internet it will normally attempt to gateway any channels that are marked as is_uplink_enabled or is_downlink_enabled. */ bool enabled; @@ -157,7 +165,8 @@ typedef struct _meshtastic_ModuleConfig_MQTTConfig { } meshtastic_ModuleConfig_MQTTConfig; /* NeighborInfoModule Config */ -typedef struct _meshtastic_ModuleConfig_NeighborInfoConfig { +typedef struct _meshtastic_ModuleConfig_NeighborInfoConfig +{ /* Whether the Module is enabled */ bool enabled; /* Interval in seconds of how often we should try to send our @@ -169,7 +178,8 @@ typedef struct _meshtastic_ModuleConfig_NeighborInfoConfig { } meshtastic_ModuleConfig_NeighborInfoConfig; /* Detection Sensor Module Config */ -typedef struct _meshtastic_ModuleConfig_DetectionSensorConfig { +typedef struct _meshtastic_ModuleConfig_DetectionSensorConfig +{ /* Whether the Module is enabled */ bool enabled; /* Interval in seconds of how often we can send a message to the mesh when a @@ -197,7 +207,8 @@ typedef struct _meshtastic_ModuleConfig_DetectionSensorConfig { } meshtastic_ModuleConfig_DetectionSensorConfig; /* Audio Config for codec2 voice */ -typedef struct _meshtastic_ModuleConfig_AudioConfig { +typedef struct _meshtastic_ModuleConfig_AudioConfig +{ /* Whether Audio is enabled */ bool codec2_enabled; /* PTT Pin */ @@ -215,7 +226,8 @@ typedef struct _meshtastic_ModuleConfig_AudioConfig { } meshtastic_ModuleConfig_AudioConfig; /* Config for the Paxcounter Module */ -typedef struct _meshtastic_ModuleConfig_PaxcounterConfig { +typedef struct _meshtastic_ModuleConfig_PaxcounterConfig +{ /* Enable the Paxcounter Module */ bool enabled; uint32_t paxcounter_update_interval; @@ -226,7 +238,8 @@ typedef struct _meshtastic_ModuleConfig_PaxcounterConfig { } meshtastic_ModuleConfig_PaxcounterConfig; /* Serial Config */ -typedef struct _meshtastic_ModuleConfig_SerialConfig { +typedef struct _meshtastic_ModuleConfig_SerialConfig +{ /* Preferences for the SerialModule */ bool enabled; /* TODO: REPLACE */ @@ -248,7 +261,8 @@ typedef struct _meshtastic_ModuleConfig_SerialConfig { } meshtastic_ModuleConfig_SerialConfig; /* External Notifications Config */ -typedef struct _meshtastic_ModuleConfig_ExternalNotificationConfig { +typedef struct _meshtastic_ModuleConfig_ExternalNotificationConfig +{ /* Enable the ExternalNotificationModule */ bool enabled; /* When using in On/Off mode, keep the output on for this many @@ -293,7 +307,8 @@ typedef struct _meshtastic_ModuleConfig_ExternalNotificationConfig { } meshtastic_ModuleConfig_ExternalNotificationConfig; /* Store and Forward Module Config */ -typedef struct _meshtastic_ModuleConfig_StoreForwardConfig { +typedef struct _meshtastic_ModuleConfig_StoreForwardConfig +{ /* Enable the Store and Forward Module */ bool enabled; /* TODO: REPLACE */ @@ -309,7 +324,8 @@ typedef struct _meshtastic_ModuleConfig_StoreForwardConfig { } meshtastic_ModuleConfig_StoreForwardConfig; /* Preferences for the RangeTestModule */ -typedef struct _meshtastic_ModuleConfig_RangeTestConfig { +typedef struct _meshtastic_ModuleConfig_RangeTestConfig +{ /* Enable the Range Test Module */ bool enabled; /* Send out range test messages from this node */ @@ -323,7 +339,8 @@ typedef struct _meshtastic_ModuleConfig_RangeTestConfig { } meshtastic_ModuleConfig_RangeTestConfig; /* Configuration for both device and environment metrics */ -typedef struct _meshtastic_ModuleConfig_TelemetryConfig { +typedef struct _meshtastic_ModuleConfig_TelemetryConfig +{ /* Interval in seconds of how often we should try to send our device metrics to the mesh */ uint32_t device_update_interval; @@ -362,7 +379,8 @@ typedef struct _meshtastic_ModuleConfig_TelemetryConfig { } meshtastic_ModuleConfig_TelemetryConfig; /* Canned Messages Module Config */ -typedef struct _meshtastic_ModuleConfig_CannedMessageConfig { +typedef struct _meshtastic_ModuleConfig_CannedMessageConfig +{ /* Enable the rotary encoder #1. This is a 'dumb' encoder sending pulses on both A and B pins while rotating. */ bool rotary1_enabled; /* GPIO pin for rotary encoder A port. */ @@ -391,7 +409,8 @@ typedef struct _meshtastic_ModuleConfig_CannedMessageConfig { /* Ambient Lighting Module - Settings for control of onboard LEDs to allow users to adjust the brightness levels and respective color levels. Initially created for the RAK14001 RGB LED module. */ -typedef struct _meshtastic_ModuleConfig_AmbientLightingConfig { +typedef struct _meshtastic_ModuleConfig_AmbientLightingConfig +{ /* Sets LED to on or off. */ bool led_state; /* Sets the current for the LED output. Default is 10. */ @@ -405,7 +424,8 @@ typedef struct _meshtastic_ModuleConfig_AmbientLightingConfig { } meshtastic_ModuleConfig_AmbientLightingConfig; /* A GPIO pin definition for remote hardware module */ -typedef struct _meshtastic_RemoteHardwarePin { +typedef struct _meshtastic_RemoteHardwarePin +{ /* GPIO Pin number (must match Arduino) */ uint8_t gpio_pin; /* Name for the GPIO pin (i.e. Front gate, mailbox, etc) */ @@ -415,7 +435,8 @@ typedef struct _meshtastic_RemoteHardwarePin { } meshtastic_RemoteHardwarePin; /* RemoteHardwareModule Config */ -typedef struct _meshtastic_ModuleConfig_RemoteHardwareConfig { +typedef struct _meshtastic_ModuleConfig_RemoteHardwareConfig +{ /* Whether the Module is enabled */ bool enabled; /* Whether the Module allows consumers to read / write to pins not defined in available_pins */ @@ -426,9 +447,11 @@ typedef struct _meshtastic_ModuleConfig_RemoteHardwareConfig { } meshtastic_ModuleConfig_RemoteHardwareConfig; /* Module Config */ -typedef struct _meshtastic_ModuleConfig { +typedef struct _meshtastic_ModuleConfig +{ pb_size_t which_payload_variant; - union { + union + { /* TODO: REPLACE */ meshtastic_ModuleConfig_MQTTConfig mqtt; /* TODO: REPLACE */ @@ -458,94 +481,178 @@ typedef struct _meshtastic_ModuleConfig { } payload_variant; } meshtastic_ModuleConfig; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Helper constants for enums */ #define _meshtastic_RemoteHardwarePinType_MIN meshtastic_RemoteHardwarePinType_UNKNOWN #define _meshtastic_RemoteHardwarePinType_MAX meshtastic_RemoteHardwarePinType_DIGITAL_WRITE -#define _meshtastic_RemoteHardwarePinType_ARRAYSIZE ((meshtastic_RemoteHardwarePinType)(meshtastic_RemoteHardwarePinType_DIGITAL_WRITE+1)) +#define _meshtastic_RemoteHardwarePinType_ARRAYSIZE ((meshtastic_RemoteHardwarePinType)(meshtastic_RemoteHardwarePinType_DIGITAL_WRITE + 1)) #define _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MIN meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_LOW #define _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MAX meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_EITHER_EDGE_ACTIVE_HIGH -#define _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_ARRAYSIZE ((meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType)(meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_EITHER_EDGE_ACTIVE_HIGH+1)) +#define _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_ARRAYSIZE ((meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType)(meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_EITHER_EDGE_ACTIVE_HIGH + 1)) #define _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN meshtastic_ModuleConfig_AudioConfig_Audio_Baud_CODEC2_DEFAULT #define _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MAX meshtastic_ModuleConfig_AudioConfig_Audio_Baud_CODEC2_700B -#define _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_ARRAYSIZE ((meshtastic_ModuleConfig_AudioConfig_Audio_Baud)(meshtastic_ModuleConfig_AudioConfig_Audio_Baud_CODEC2_700B+1)) +#define _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_ARRAYSIZE ((meshtastic_ModuleConfig_AudioConfig_Audio_Baud)(meshtastic_ModuleConfig_AudioConfig_Audio_Baud_CODEC2_700B + 1)) #define _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_DEFAULT #define _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MAX meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600 -#define _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_ARRAYSIZE ((meshtastic_ModuleConfig_SerialConfig_Serial_Baud)(meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600+1)) +#define _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_ARRAYSIZE ((meshtastic_ModuleConfig_SerialConfig_Serial_Baud)(meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600 + 1)) #define _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN meshtastic_ModuleConfig_SerialConfig_Serial_Mode_DEFAULT #define _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MAX meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MS_CONFIG -#define _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_ARRAYSIZE ((meshtastic_ModuleConfig_SerialConfig_Serial_Mode)(meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MS_CONFIG+1)) +#define _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_ARRAYSIZE ((meshtastic_ModuleConfig_SerialConfig_Serial_Mode)(meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MS_CONFIG + 1)) #define _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE #define _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MAX meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK -#define _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_ARRAYSIZE ((meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar)(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK+1)) - - - - - +#define _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_ARRAYSIZE ((meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar)(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK + 1)) #define meshtastic_ModuleConfig_DetectionSensorConfig_detection_trigger_type_ENUMTYPE meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType #define meshtastic_ModuleConfig_AudioConfig_bitrate_ENUMTYPE meshtastic_ModuleConfig_AudioConfig_Audio_Baud - #define meshtastic_ModuleConfig_SerialConfig_baud_ENUMTYPE meshtastic_ModuleConfig_SerialConfig_Serial_Baud #define meshtastic_ModuleConfig_SerialConfig_mode_ENUMTYPE meshtastic_ModuleConfig_SerialConfig_Serial_Mode - - - - #define meshtastic_ModuleConfig_CannedMessageConfig_inputbroker_event_cw_ENUMTYPE meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar #define meshtastic_ModuleConfig_CannedMessageConfig_inputbroker_event_ccw_ENUMTYPE meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar #define meshtastic_ModuleConfig_CannedMessageConfig_inputbroker_event_press_ENUMTYPE meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar - #define meshtastic_RemoteHardwarePin_type_ENUMTYPE meshtastic_RemoteHardwarePinType - /* Initializer values for message structs */ -#define meshtastic_ModuleConfig_init_default {0, {meshtastic_ModuleConfig_MQTTConfig_init_default}} -#define meshtastic_ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0, 0, 0, "", 0, 0, false, meshtastic_ModuleConfig_MapReportSettings_init_default} -#define meshtastic_ModuleConfig_MapReportSettings_init_default {0, 0, 0} -#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_default {0, 0, 0, {meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default}} -#define meshtastic_ModuleConfig_NeighborInfoConfig_init_default {0, 0, 0} -#define meshtastic_ModuleConfig_DetectionSensorConfig_init_default {0, 0, 0, 0, "", 0, _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MIN, 0} -#define meshtastic_ModuleConfig_AudioConfig_init_default {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0} -#define meshtastic_ModuleConfig_PaxcounterConfig_init_default {0, 0, 0, 0} -#define meshtastic_ModuleConfig_SerialConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0} -#define meshtastic_ModuleConfig_ExternalNotificationConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -#define meshtastic_ModuleConfig_StoreForwardConfig_init_default {0, 0, 0, 0, 0, 0} -#define meshtastic_ModuleConfig_RangeTestConfig_init_default {0, 0, 0, 0} -#define meshtastic_ModuleConfig_TelemetryConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -#define meshtastic_ModuleConfig_CannedMessageConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0} -#define meshtastic_ModuleConfig_AmbientLightingConfig_init_default {0, 0, 0, 0, 0} -#define meshtastic_RemoteHardwarePin_init_default {0, "", _meshtastic_RemoteHardwarePinType_MIN} -#define meshtastic_ModuleConfig_init_zero {0, {meshtastic_ModuleConfig_MQTTConfig_init_zero}} -#define meshtastic_ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0, 0, 0, "", 0, 0, false, meshtastic_ModuleConfig_MapReportSettings_init_zero} -#define meshtastic_ModuleConfig_MapReportSettings_init_zero {0, 0, 0} -#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero {0, 0, 0, {meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero}} -#define meshtastic_ModuleConfig_NeighborInfoConfig_init_zero {0, 0, 0} -#define meshtastic_ModuleConfig_DetectionSensorConfig_init_zero {0, 0, 0, 0, "", 0, _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MIN, 0} -#define meshtastic_ModuleConfig_AudioConfig_init_zero {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0} -#define meshtastic_ModuleConfig_PaxcounterConfig_init_zero {0, 0, 0, 0} -#define meshtastic_ModuleConfig_SerialConfig_init_zero {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0} -#define meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -#define meshtastic_ModuleConfig_StoreForwardConfig_init_zero {0, 0, 0, 0, 0, 0} -#define meshtastic_ModuleConfig_RangeTestConfig_init_zero {0, 0, 0, 0} -#define meshtastic_ModuleConfig_TelemetryConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -#define meshtastic_ModuleConfig_CannedMessageConfig_init_zero {0, 0, 0, 0, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0} -#define meshtastic_ModuleConfig_AmbientLightingConfig_init_zero {0, 0, 0, 0, 0} -#define meshtastic_RemoteHardwarePin_init_zero {0, "", _meshtastic_RemoteHardwarePinType_MIN} +#define meshtastic_ModuleConfig_init_default \ + { \ + 0, { meshtastic_ModuleConfig_MQTTConfig_init_default } \ + } +#define meshtastic_ModuleConfig_MQTTConfig_init_default \ + { \ + 0, "", "", "", 0, 0, 0, "", 0, 0, false, meshtastic_ModuleConfig_MapReportSettings_init_default \ + } +#define meshtastic_ModuleConfig_MapReportSettings_init_default \ + { \ + 0, 0, 0 \ + } +#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_default \ + { \ + 0, 0, 0, { meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default } \ + } +#define meshtastic_ModuleConfig_NeighborInfoConfig_init_default \ + { \ + 0, 0, 0 \ + } +#define meshtastic_ModuleConfig_DetectionSensorConfig_init_default \ + { \ + 0, 0, 0, 0, "", 0, _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MIN, 0 \ + } +#define meshtastic_ModuleConfig_AudioConfig_init_default \ + { \ + 0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0 \ + } +#define meshtastic_ModuleConfig_PaxcounterConfig_init_default \ + { \ + 0, 0, 0, 0 \ + } +#define meshtastic_ModuleConfig_SerialConfig_init_default \ + { \ + 0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0 \ + } +#define meshtastic_ModuleConfig_ExternalNotificationConfig_init_default \ + { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ + } +#define meshtastic_ModuleConfig_StoreForwardConfig_init_default \ + { \ + 0, 0, 0, 0, 0, 0 \ + } +#define meshtastic_ModuleConfig_RangeTestConfig_init_default \ + { \ + 0, 0, 0, 0 \ + } +#define meshtastic_ModuleConfig_TelemetryConfig_init_default \ + { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ + } +#define meshtastic_ModuleConfig_CannedMessageConfig_init_default \ + { \ + 0, 0, 0, 0, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0 \ + } +#define meshtastic_ModuleConfig_AmbientLightingConfig_init_default \ + { \ + 0, 0, 0, 0, 0 \ + } +#define meshtastic_RemoteHardwarePin_init_default \ + { \ + 0, "", _meshtastic_RemoteHardwarePinType_MIN \ + } +#define meshtastic_ModuleConfig_init_zero \ + { \ + 0, { meshtastic_ModuleConfig_MQTTConfig_init_zero } \ + } +#define meshtastic_ModuleConfig_MQTTConfig_init_zero \ + { \ + 0, "", "", "", 0, 0, 0, "", 0, 0, false, meshtastic_ModuleConfig_MapReportSettings_init_zero \ + } +#define meshtastic_ModuleConfig_MapReportSettings_init_zero \ + { \ + 0, 0, 0 \ + } +#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero \ + { \ + 0, 0, 0, { meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero } \ + } +#define meshtastic_ModuleConfig_NeighborInfoConfig_init_zero \ + { \ + 0, 0, 0 \ + } +#define meshtastic_ModuleConfig_DetectionSensorConfig_init_zero \ + { \ + 0, 0, 0, 0, "", 0, _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MIN, 0 \ + } +#define meshtastic_ModuleConfig_AudioConfig_init_zero \ + { \ + 0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0 \ + } +#define meshtastic_ModuleConfig_PaxcounterConfig_init_zero \ + { \ + 0, 0, 0, 0 \ + } +#define meshtastic_ModuleConfig_SerialConfig_init_zero \ + { \ + 0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0 \ + } +#define meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero \ + { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ + } +#define meshtastic_ModuleConfig_StoreForwardConfig_init_zero \ + { \ + 0, 0, 0, 0, 0, 0 \ + } +#define meshtastic_ModuleConfig_RangeTestConfig_init_zero \ + { \ + 0, 0, 0, 0 \ + } +#define meshtastic_ModuleConfig_TelemetryConfig_init_zero \ + { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ + } +#define meshtastic_ModuleConfig_CannedMessageConfig_init_zero \ + { \ + 0, 0, 0, 0, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0 \ + } +#define meshtastic_ModuleConfig_AmbientLightingConfig_init_zero \ + { \ + 0, 0, 0, 0, 0 \ + } +#define meshtastic_RemoteHardwarePin_init_zero \ + { \ + 0, "", _meshtastic_RemoteHardwarePinType_MIN \ + } /* Field tags (for use in manual encoding/decoding) */ #define meshtastic_ModuleConfig_MapReportSettings_publish_interval_secs_tag 1 @@ -648,40 +755,40 @@ extern "C" { #define meshtastic_ModuleConfig_AmbientLightingConfig_green_tag 4 #define meshtastic_ModuleConfig_AmbientLightingConfig_blue_tag 5 #define meshtastic_RemoteHardwarePin_gpio_pin_tag 1 -#define meshtastic_RemoteHardwarePin_name_tag 2 -#define meshtastic_RemoteHardwarePin_type_tag 3 +#define meshtastic_RemoteHardwarePin_name_tag 2 +#define meshtastic_RemoteHardwarePin_type_tag 3 #define meshtastic_ModuleConfig_RemoteHardwareConfig_enabled_tag 1 #define meshtastic_ModuleConfig_RemoteHardwareConfig_allow_undefined_pin_access_tag 2 #define meshtastic_ModuleConfig_RemoteHardwareConfig_available_pins_tag 3 -#define meshtastic_ModuleConfig_mqtt_tag 1 -#define meshtastic_ModuleConfig_serial_tag 2 +#define meshtastic_ModuleConfig_mqtt_tag 1 +#define meshtastic_ModuleConfig_serial_tag 2 #define meshtastic_ModuleConfig_external_notification_tag 3 #define meshtastic_ModuleConfig_store_forward_tag 4 -#define meshtastic_ModuleConfig_range_test_tag 5 -#define meshtastic_ModuleConfig_telemetry_tag 6 +#define meshtastic_ModuleConfig_range_test_tag 5 +#define meshtastic_ModuleConfig_telemetry_tag 6 #define meshtastic_ModuleConfig_canned_message_tag 7 -#define meshtastic_ModuleConfig_audio_tag 8 +#define meshtastic_ModuleConfig_audio_tag 8 #define meshtastic_ModuleConfig_remote_hardware_tag 9 #define meshtastic_ModuleConfig_neighbor_info_tag 10 #define meshtastic_ModuleConfig_ambient_lighting_tag 11 #define meshtastic_ModuleConfig_detection_sensor_tag 12 -#define meshtastic_ModuleConfig_paxcounter_tag 13 +#define meshtastic_ModuleConfig_paxcounter_tag 13 /* Struct field encoding specification for nanopb */ -#define meshtastic_ModuleConfig_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,mqtt,payload_variant.mqtt), 1) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,serial,payload_variant.serial), 2) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,external_notification,payload_variant.external_notification), 3) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,store_forward,payload_variant.store_forward), 4) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,range_test,payload_variant.range_test), 5) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,telemetry,payload_variant.telemetry), 6) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,canned_message,payload_variant.canned_message), 7) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,audio,payload_variant.audio), 8) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,remote_hardware,payload_variant.remote_hardware), 9) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,neighbor_info,payload_variant.neighbor_info), 10) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,ambient_lighting,payload_variant.ambient_lighting), 11) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,detection_sensor,payload_variant.detection_sensor), 12) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,paxcounter,payload_variant.paxcounter), 13) +#define meshtastic_ModuleConfig_FIELDLIST(X, a) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, mqtt, payload_variant.mqtt), 1) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, serial, payload_variant.serial), 2) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, external_notification, payload_variant.external_notification), 3) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, store_forward, payload_variant.store_forward), 4) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, range_test, payload_variant.range_test), 5) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, telemetry, payload_variant.telemetry), 6) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, canned_message, payload_variant.canned_message), 7) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, audio, payload_variant.audio), 8) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, remote_hardware, payload_variant.remote_hardware), 9) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, neighbor_info, payload_variant.neighbor_info), 10) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, ambient_lighting, payload_variant.ambient_lighting), 11) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, detection_sensor, payload_variant.detection_sensor), 12) \ + X(a, STATIC, ONEOF, MESSAGE, (payload_variant, paxcounter, payload_variant.paxcounter), 13) #define meshtastic_ModuleConfig_CALLBACK NULL #define meshtastic_ModuleConfig_DEFAULT NULL #define meshtastic_ModuleConfig_payload_variant_mqtt_MSGTYPE meshtastic_ModuleConfig_MQTTConfig @@ -698,189 +805,189 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,paxcounter,payload_variant.p #define meshtastic_ModuleConfig_payload_variant_detection_sensor_MSGTYPE meshtastic_ModuleConfig_DetectionSensorConfig #define meshtastic_ModuleConfig_payload_variant_paxcounter_MSGTYPE meshtastic_ModuleConfig_PaxcounterConfig -#define meshtastic_ModuleConfig_MQTTConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ -X(a, STATIC, SINGULAR, STRING, address, 2) \ -X(a, STATIC, SINGULAR, STRING, username, 3) \ -X(a, STATIC, SINGULAR, STRING, password, 4) \ -X(a, STATIC, SINGULAR, BOOL, encryption_enabled, 5) \ -X(a, STATIC, SINGULAR, BOOL, json_enabled, 6) \ -X(a, STATIC, SINGULAR, BOOL, tls_enabled, 7) \ -X(a, STATIC, SINGULAR, STRING, root, 8) \ -X(a, STATIC, SINGULAR, BOOL, proxy_to_client_enabled, 9) \ -X(a, STATIC, SINGULAR, BOOL, map_reporting_enabled, 10) \ -X(a, STATIC, OPTIONAL, MESSAGE, map_report_settings, 11) +#define meshtastic_ModuleConfig_MQTTConfig_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ + X(a, STATIC, SINGULAR, STRING, address, 2) \ + X(a, STATIC, SINGULAR, STRING, username, 3) \ + X(a, STATIC, SINGULAR, STRING, password, 4) \ + X(a, STATIC, SINGULAR, BOOL, encryption_enabled, 5) \ + X(a, STATIC, SINGULAR, BOOL, json_enabled, 6) \ + X(a, STATIC, SINGULAR, BOOL, tls_enabled, 7) \ + X(a, STATIC, SINGULAR, STRING, root, 8) \ + X(a, STATIC, SINGULAR, BOOL, proxy_to_client_enabled, 9) \ + X(a, STATIC, SINGULAR, BOOL, map_reporting_enabled, 10) \ + X(a, STATIC, OPTIONAL, MESSAGE, map_report_settings, 11) #define meshtastic_ModuleConfig_MQTTConfig_CALLBACK NULL #define meshtastic_ModuleConfig_MQTTConfig_DEFAULT NULL #define meshtastic_ModuleConfig_MQTTConfig_map_report_settings_MSGTYPE meshtastic_ModuleConfig_MapReportSettings #define meshtastic_ModuleConfig_MapReportSettings_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, publish_interval_secs, 1) \ -X(a, STATIC, SINGULAR, UINT32, position_precision, 2) \ -X(a, STATIC, SINGULAR, BOOL, should_report_location, 3) + X(a, STATIC, SINGULAR, UINT32, publish_interval_secs, 1) \ + X(a, STATIC, SINGULAR, UINT32, position_precision, 2) \ + X(a, STATIC, SINGULAR, BOOL, should_report_location, 3) #define meshtastic_ModuleConfig_MapReportSettings_CALLBACK NULL #define meshtastic_ModuleConfig_MapReportSettings_DEFAULT NULL #define meshtastic_ModuleConfig_RemoteHardwareConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ -X(a, STATIC, SINGULAR, BOOL, allow_undefined_pin_access, 2) \ -X(a, STATIC, REPEATED, MESSAGE, available_pins, 3) + X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ + X(a, STATIC, SINGULAR, BOOL, allow_undefined_pin_access, 2) \ + X(a, STATIC, REPEATED, MESSAGE, available_pins, 3) #define meshtastic_ModuleConfig_RemoteHardwareConfig_CALLBACK NULL #define meshtastic_ModuleConfig_RemoteHardwareConfig_DEFAULT NULL #define meshtastic_ModuleConfig_RemoteHardwareConfig_available_pins_MSGTYPE meshtastic_RemoteHardwarePin #define meshtastic_ModuleConfig_NeighborInfoConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ -X(a, STATIC, SINGULAR, UINT32, update_interval, 2) \ -X(a, STATIC, SINGULAR, BOOL, transmit_over_lora, 3) + X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ + X(a, STATIC, SINGULAR, UINT32, update_interval, 2) \ + X(a, STATIC, SINGULAR, BOOL, transmit_over_lora, 3) #define meshtastic_ModuleConfig_NeighborInfoConfig_CALLBACK NULL #define meshtastic_ModuleConfig_NeighborInfoConfig_DEFAULT NULL #define meshtastic_ModuleConfig_DetectionSensorConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ -X(a, STATIC, SINGULAR, UINT32, minimum_broadcast_secs, 2) \ -X(a, STATIC, SINGULAR, UINT32, state_broadcast_secs, 3) \ -X(a, STATIC, SINGULAR, BOOL, send_bell, 4) \ -X(a, STATIC, SINGULAR, STRING, name, 5) \ -X(a, STATIC, SINGULAR, UINT32, monitor_pin, 6) \ -X(a, STATIC, SINGULAR, UENUM, detection_trigger_type, 7) \ -X(a, STATIC, SINGULAR, BOOL, use_pullup, 8) + X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ + X(a, STATIC, SINGULAR, UINT32, minimum_broadcast_secs, 2) \ + X(a, STATIC, SINGULAR, UINT32, state_broadcast_secs, 3) \ + X(a, STATIC, SINGULAR, BOOL, send_bell, 4) \ + X(a, STATIC, SINGULAR, STRING, name, 5) \ + X(a, STATIC, SINGULAR, UINT32, monitor_pin, 6) \ + X(a, STATIC, SINGULAR, UENUM, detection_trigger_type, 7) \ + X(a, STATIC, SINGULAR, BOOL, use_pullup, 8) #define meshtastic_ModuleConfig_DetectionSensorConfig_CALLBACK NULL #define meshtastic_ModuleConfig_DetectionSensorConfig_DEFAULT NULL #define meshtastic_ModuleConfig_AudioConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, codec2_enabled, 1) \ -X(a, STATIC, SINGULAR, UINT32, ptt_pin, 2) \ -X(a, STATIC, SINGULAR, UENUM, bitrate, 3) \ -X(a, STATIC, SINGULAR, UINT32, i2s_ws, 4) \ -X(a, STATIC, SINGULAR, UINT32, i2s_sd, 5) \ -X(a, STATIC, SINGULAR, UINT32, i2s_din, 6) \ -X(a, STATIC, SINGULAR, UINT32, i2s_sck, 7) + X(a, STATIC, SINGULAR, BOOL, codec2_enabled, 1) \ + X(a, STATIC, SINGULAR, UINT32, ptt_pin, 2) \ + X(a, STATIC, SINGULAR, UENUM, bitrate, 3) \ + X(a, STATIC, SINGULAR, UINT32, i2s_ws, 4) \ + X(a, STATIC, SINGULAR, UINT32, i2s_sd, 5) \ + X(a, STATIC, SINGULAR, UINT32, i2s_din, 6) \ + X(a, STATIC, SINGULAR, UINT32, i2s_sck, 7) #define meshtastic_ModuleConfig_AudioConfig_CALLBACK NULL #define meshtastic_ModuleConfig_AudioConfig_DEFAULT NULL -#define meshtastic_ModuleConfig_PaxcounterConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ -X(a, STATIC, SINGULAR, UINT32, paxcounter_update_interval, 2) \ -X(a, STATIC, SINGULAR, INT32, wifi_threshold, 3) \ -X(a, STATIC, SINGULAR, INT32, ble_threshold, 4) +#define meshtastic_ModuleConfig_PaxcounterConfig_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ + X(a, STATIC, SINGULAR, UINT32, paxcounter_update_interval, 2) \ + X(a, STATIC, SINGULAR, INT32, wifi_threshold, 3) \ + X(a, STATIC, SINGULAR, INT32, ble_threshold, 4) #define meshtastic_ModuleConfig_PaxcounterConfig_CALLBACK NULL #define meshtastic_ModuleConfig_PaxcounterConfig_DEFAULT NULL #define meshtastic_ModuleConfig_SerialConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ -X(a, STATIC, SINGULAR, BOOL, echo, 2) \ -X(a, STATIC, SINGULAR, UINT32, rxd, 3) \ -X(a, STATIC, SINGULAR, UINT32, txd, 4) \ -X(a, STATIC, SINGULAR, UENUM, baud, 5) \ -X(a, STATIC, SINGULAR, UINT32, timeout, 6) \ -X(a, STATIC, SINGULAR, UENUM, mode, 7) \ -X(a, STATIC, SINGULAR, BOOL, override_console_serial_port, 8) + X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ + X(a, STATIC, SINGULAR, BOOL, echo, 2) \ + X(a, STATIC, SINGULAR, UINT32, rxd, 3) \ + X(a, STATIC, SINGULAR, UINT32, txd, 4) \ + X(a, STATIC, SINGULAR, UENUM, baud, 5) \ + X(a, STATIC, SINGULAR, UINT32, timeout, 6) \ + X(a, STATIC, SINGULAR, UENUM, mode, 7) \ + X(a, STATIC, SINGULAR, BOOL, override_console_serial_port, 8) #define meshtastic_ModuleConfig_SerialConfig_CALLBACK NULL #define meshtastic_ModuleConfig_SerialConfig_DEFAULT NULL #define meshtastic_ModuleConfig_ExternalNotificationConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ -X(a, STATIC, SINGULAR, UINT32, output_ms, 2) \ -X(a, STATIC, SINGULAR, UINT32, output, 3) \ -X(a, STATIC, SINGULAR, BOOL, active, 4) \ -X(a, STATIC, SINGULAR, BOOL, alert_message, 5) \ -X(a, STATIC, SINGULAR, BOOL, alert_bell, 6) \ -X(a, STATIC, SINGULAR, BOOL, use_pwm, 7) \ -X(a, STATIC, SINGULAR, UINT32, output_vibra, 8) \ -X(a, STATIC, SINGULAR, UINT32, output_buzzer, 9) \ -X(a, STATIC, SINGULAR, BOOL, alert_message_vibra, 10) \ -X(a, STATIC, SINGULAR, BOOL, alert_message_buzzer, 11) \ -X(a, STATIC, SINGULAR, BOOL, alert_bell_vibra, 12) \ -X(a, STATIC, SINGULAR, BOOL, alert_bell_buzzer, 13) \ -X(a, STATIC, SINGULAR, UINT32, nag_timeout, 14) \ -X(a, STATIC, SINGULAR, BOOL, use_i2s_as_buzzer, 15) + X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ + X(a, STATIC, SINGULAR, UINT32, output_ms, 2) \ + X(a, STATIC, SINGULAR, UINT32, output, 3) \ + X(a, STATIC, SINGULAR, BOOL, active, 4) \ + X(a, STATIC, SINGULAR, BOOL, alert_message, 5) \ + X(a, STATIC, SINGULAR, BOOL, alert_bell, 6) \ + X(a, STATIC, SINGULAR, BOOL, use_pwm, 7) \ + X(a, STATIC, SINGULAR, UINT32, output_vibra, 8) \ + X(a, STATIC, SINGULAR, UINT32, output_buzzer, 9) \ + X(a, STATIC, SINGULAR, BOOL, alert_message_vibra, 10) \ + X(a, STATIC, SINGULAR, BOOL, alert_message_buzzer, 11) \ + X(a, STATIC, SINGULAR, BOOL, alert_bell_vibra, 12) \ + X(a, STATIC, SINGULAR, BOOL, alert_bell_buzzer, 13) \ + X(a, STATIC, SINGULAR, UINT32, nag_timeout, 14) \ + X(a, STATIC, SINGULAR, BOOL, use_i2s_as_buzzer, 15) #define meshtastic_ModuleConfig_ExternalNotificationConfig_CALLBACK NULL #define meshtastic_ModuleConfig_ExternalNotificationConfig_DEFAULT NULL #define meshtastic_ModuleConfig_StoreForwardConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ -X(a, STATIC, SINGULAR, BOOL, heartbeat, 2) \ -X(a, STATIC, SINGULAR, UINT32, records, 3) \ -X(a, STATIC, SINGULAR, UINT32, history_return_max, 4) \ -X(a, STATIC, SINGULAR, UINT32, history_return_window, 5) \ -X(a, STATIC, SINGULAR, BOOL, is_server, 6) + X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ + X(a, STATIC, SINGULAR, BOOL, heartbeat, 2) \ + X(a, STATIC, SINGULAR, UINT32, records, 3) \ + X(a, STATIC, SINGULAR, UINT32, history_return_max, 4) \ + X(a, STATIC, SINGULAR, UINT32, history_return_window, 5) \ + X(a, STATIC, SINGULAR, BOOL, is_server, 6) #define meshtastic_ModuleConfig_StoreForwardConfig_CALLBACK NULL #define meshtastic_ModuleConfig_StoreForwardConfig_DEFAULT NULL #define meshtastic_ModuleConfig_RangeTestConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ -X(a, STATIC, SINGULAR, UINT32, sender, 2) \ -X(a, STATIC, SINGULAR, BOOL, save, 3) \ -X(a, STATIC, SINGULAR, BOOL, clear_on_reboot, 4) + X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ + X(a, STATIC, SINGULAR, UINT32, sender, 2) \ + X(a, STATIC, SINGULAR, BOOL, save, 3) \ + X(a, STATIC, SINGULAR, BOOL, clear_on_reboot, 4) #define meshtastic_ModuleConfig_RangeTestConfig_CALLBACK NULL #define meshtastic_ModuleConfig_RangeTestConfig_DEFAULT NULL -#define meshtastic_ModuleConfig_TelemetryConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, device_update_interval, 1) \ -X(a, STATIC, SINGULAR, UINT32, environment_update_interval, 2) \ -X(a, STATIC, SINGULAR, BOOL, environment_measurement_enabled, 3) \ -X(a, STATIC, SINGULAR, BOOL, environment_screen_enabled, 4) \ -X(a, STATIC, SINGULAR, BOOL, environment_display_fahrenheit, 5) \ -X(a, STATIC, SINGULAR, BOOL, air_quality_enabled, 6) \ -X(a, STATIC, SINGULAR, UINT32, air_quality_interval, 7) \ -X(a, STATIC, SINGULAR, BOOL, power_measurement_enabled, 8) \ -X(a, STATIC, SINGULAR, UINT32, power_update_interval, 9) \ -X(a, STATIC, SINGULAR, BOOL, power_screen_enabled, 10) \ -X(a, STATIC, SINGULAR, BOOL, health_measurement_enabled, 11) \ -X(a, STATIC, SINGULAR, UINT32, health_update_interval, 12) \ -X(a, STATIC, SINGULAR, BOOL, health_screen_enabled, 13) \ -X(a, STATIC, SINGULAR, BOOL, device_telemetry_enabled, 14) +#define meshtastic_ModuleConfig_TelemetryConfig_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UINT32, device_update_interval, 1) \ + X(a, STATIC, SINGULAR, UINT32, environment_update_interval, 2) \ + X(a, STATIC, SINGULAR, BOOL, environment_measurement_enabled, 3) \ + X(a, STATIC, SINGULAR, BOOL, environment_screen_enabled, 4) \ + X(a, STATIC, SINGULAR, BOOL, environment_display_fahrenheit, 5) \ + X(a, STATIC, SINGULAR, BOOL, air_quality_enabled, 6) \ + X(a, STATIC, SINGULAR, UINT32, air_quality_interval, 7) \ + X(a, STATIC, SINGULAR, BOOL, power_measurement_enabled, 8) \ + X(a, STATIC, SINGULAR, UINT32, power_update_interval, 9) \ + X(a, STATIC, SINGULAR, BOOL, power_screen_enabled, 10) \ + X(a, STATIC, SINGULAR, BOOL, health_measurement_enabled, 11) \ + X(a, STATIC, SINGULAR, UINT32, health_update_interval, 12) \ + X(a, STATIC, SINGULAR, BOOL, health_screen_enabled, 13) \ + X(a, STATIC, SINGULAR, BOOL, device_telemetry_enabled, 14) #define meshtastic_ModuleConfig_TelemetryConfig_CALLBACK NULL #define meshtastic_ModuleConfig_TelemetryConfig_DEFAULT NULL #define meshtastic_ModuleConfig_CannedMessageConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, rotary1_enabled, 1) \ -X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_a, 2) \ -X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_b, 3) \ -X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_press, 4) \ -X(a, STATIC, SINGULAR, UENUM, inputbroker_event_cw, 5) \ -X(a, STATIC, SINGULAR, UENUM, inputbroker_event_ccw, 6) \ -X(a, STATIC, SINGULAR, UENUM, inputbroker_event_press, 7) \ -X(a, STATIC, SINGULAR, BOOL, updown1_enabled, 8) \ -X(a, STATIC, SINGULAR, BOOL, enabled, 9) \ -X(a, STATIC, SINGULAR, STRING, allow_input_source, 10) \ -X(a, STATIC, SINGULAR, BOOL, send_bell, 11) + X(a, STATIC, SINGULAR, BOOL, rotary1_enabled, 1) \ + X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_a, 2) \ + X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_b, 3) \ + X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_press, 4) \ + X(a, STATIC, SINGULAR, UENUM, inputbroker_event_cw, 5) \ + X(a, STATIC, SINGULAR, UENUM, inputbroker_event_ccw, 6) \ + X(a, STATIC, SINGULAR, UENUM, inputbroker_event_press, 7) \ + X(a, STATIC, SINGULAR, BOOL, updown1_enabled, 8) \ + X(a, STATIC, SINGULAR, BOOL, enabled, 9) \ + X(a, STATIC, SINGULAR, STRING, allow_input_source, 10) \ + X(a, STATIC, SINGULAR, BOOL, send_bell, 11) #define meshtastic_ModuleConfig_CannedMessageConfig_CALLBACK NULL #define meshtastic_ModuleConfig_CannedMessageConfig_DEFAULT NULL #define meshtastic_ModuleConfig_AmbientLightingConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, led_state, 1) \ -X(a, STATIC, SINGULAR, UINT32, current, 2) \ -X(a, STATIC, SINGULAR, UINT32, red, 3) \ -X(a, STATIC, SINGULAR, UINT32, green, 4) \ -X(a, STATIC, SINGULAR, UINT32, blue, 5) + X(a, STATIC, SINGULAR, BOOL, led_state, 1) \ + X(a, STATIC, SINGULAR, UINT32, current, 2) \ + X(a, STATIC, SINGULAR, UINT32, red, 3) \ + X(a, STATIC, SINGULAR, UINT32, green, 4) \ + X(a, STATIC, SINGULAR, UINT32, blue, 5) #define meshtastic_ModuleConfig_AmbientLightingConfig_CALLBACK NULL #define meshtastic_ModuleConfig_AmbientLightingConfig_DEFAULT NULL #define meshtastic_RemoteHardwarePin_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, gpio_pin, 1) \ -X(a, STATIC, SINGULAR, STRING, name, 2) \ -X(a, STATIC, SINGULAR, UENUM, type, 3) + X(a, STATIC, SINGULAR, UINT32, gpio_pin, 1) \ + X(a, STATIC, SINGULAR, STRING, name, 2) \ + X(a, STATIC, SINGULAR, UENUM, type, 3) #define meshtastic_RemoteHardwarePin_CALLBACK NULL #define meshtastic_RemoteHardwarePin_DEFAULT NULL -extern const pb_msgdesc_t meshtastic_ModuleConfig_msg; -extern const pb_msgdesc_t meshtastic_ModuleConfig_MQTTConfig_msg; -extern const pb_msgdesc_t meshtastic_ModuleConfig_MapReportSettings_msg; -extern const pb_msgdesc_t meshtastic_ModuleConfig_RemoteHardwareConfig_msg; -extern const pb_msgdesc_t meshtastic_ModuleConfig_NeighborInfoConfig_msg; -extern const pb_msgdesc_t meshtastic_ModuleConfig_DetectionSensorConfig_msg; -extern const pb_msgdesc_t meshtastic_ModuleConfig_AudioConfig_msg; -extern const pb_msgdesc_t meshtastic_ModuleConfig_PaxcounterConfig_msg; -extern const pb_msgdesc_t meshtastic_ModuleConfig_SerialConfig_msg; -extern const pb_msgdesc_t meshtastic_ModuleConfig_ExternalNotificationConfig_msg; -extern const pb_msgdesc_t meshtastic_ModuleConfig_StoreForwardConfig_msg; -extern const pb_msgdesc_t meshtastic_ModuleConfig_RangeTestConfig_msg; -extern const pb_msgdesc_t meshtastic_ModuleConfig_TelemetryConfig_msg; -extern const pb_msgdesc_t meshtastic_ModuleConfig_CannedMessageConfig_msg; -extern const pb_msgdesc_t meshtastic_ModuleConfig_AmbientLightingConfig_msg; -extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg; + extern const pb_msgdesc_t meshtastic_ModuleConfig_msg; + extern const pb_msgdesc_t meshtastic_ModuleConfig_MQTTConfig_msg; + extern const pb_msgdesc_t meshtastic_ModuleConfig_MapReportSettings_msg; + extern const pb_msgdesc_t meshtastic_ModuleConfig_RemoteHardwareConfig_msg; + extern const pb_msgdesc_t meshtastic_ModuleConfig_NeighborInfoConfig_msg; + extern const pb_msgdesc_t meshtastic_ModuleConfig_DetectionSensorConfig_msg; + extern const pb_msgdesc_t meshtastic_ModuleConfig_AudioConfig_msg; + extern const pb_msgdesc_t meshtastic_ModuleConfig_PaxcounterConfig_msg; + extern const pb_msgdesc_t meshtastic_ModuleConfig_SerialConfig_msg; + extern const pb_msgdesc_t meshtastic_ModuleConfig_ExternalNotificationConfig_msg; + extern const pb_msgdesc_t meshtastic_ModuleConfig_StoreForwardConfig_msg; + extern const pb_msgdesc_t meshtastic_ModuleConfig_RangeTestConfig_msg; + extern const pb_msgdesc_t meshtastic_ModuleConfig_TelemetryConfig_msg; + extern const pb_msgdesc_t meshtastic_ModuleConfig_CannedMessageConfig_msg; + extern const pb_msgdesc_t meshtastic_ModuleConfig_AmbientLightingConfig_msg; + extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_ModuleConfig_fields &meshtastic_ModuleConfig_msg @@ -907,7 +1014,7 @@ extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg; #define meshtastic_ModuleConfig_CannedMessageConfig_size 49 #define meshtastic_ModuleConfig_DetectionSensorConfig_size 44 #define meshtastic_ModuleConfig_ExternalNotificationConfig_size 42 -#define meshtastic_ModuleConfig_MQTTConfig_size 224 +#define meshtastic_ModuleConfig_MQTTConfig_size 224 #define meshtastic_ModuleConfig_MapReportSettings_size 14 #define meshtastic_ModuleConfig_NeighborInfoConfig_size 10 #define meshtastic_ModuleConfig_PaxcounterConfig_size 30 @@ -916,8 +1023,8 @@ extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg; #define meshtastic_ModuleConfig_SerialConfig_size 28 #define meshtastic_ModuleConfig_StoreForwardConfig_size 24 #define meshtastic_ModuleConfig_TelemetryConfig_size 48 -#define meshtastic_ModuleConfig_size 227 -#define meshtastic_RemoteHardwarePin_size 21 +#define meshtastic_ModuleConfig_size 227 +#define meshtastic_RemoteHardwarePin_size 21 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/mqtt.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/mqtt.pb.cpp index 2c32ef2e..4058d677 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/mqtt.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/mqtt.pb.cpp @@ -8,8 +8,4 @@ PB_BIND(meshtastic_ServiceEnvelope, meshtastic_ServiceEnvelope, AUTO) - PB_BIND(meshtastic_MapReport, meshtastic_MapReport, AUTO) - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/mqtt.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/mqtt.pb.h index c5b10f1f..97ce249a 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/mqtt.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/mqtt.pb.h @@ -3,9 +3,9 @@ #ifndef PB_MESHTASTIC_MESHTASTIC_MQTT_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_MQTT_PB_H_INCLUDED -#include #include "meshtastic/config.pb.h" #include "meshtastic/mesh.pb.h" +#include #if PB_PROTO_HEADER_VERSION != 40 #error Regenerate this file with the current version of nanopb generator. @@ -13,19 +13,21 @@ /* Struct definitions */ /* This message wraps a MeshPacket with extra metadata about the sender and how it arrived. */ -typedef struct _meshtastic_ServiceEnvelope { +typedef struct _meshtastic_ServiceEnvelope +{ /* The (probably encrypted) packet */ - struct _meshtastic_MeshPacket *packet; + struct _meshtastic_MeshPacket* packet; /* The global channel ID it was sent on */ - char *channel_id; + char* channel_id; /* The sending gateway node ID. Can we use this to authenticate/prevent fake nodeid impersonation for senders? - i.e. use gateway/mesh id (which is authenticated) + local node id as the globally trusted nodenum */ - char *gateway_id; + char* gateway_id; } meshtastic_ServiceEnvelope; /* Information about a node intended to be reported unencrypted to a map using MQTT. */ -typedef struct _meshtastic_MapReport { +typedef struct _meshtastic_MapReport +{ /* A full name for this user, i.e. "Kevin Hester" */ char long_name[40]; /* A VERY short name, ideally two characters. @@ -59,65 +61,77 @@ typedef struct _meshtastic_MapReport { bool has_opted_report_location; } meshtastic_MapReport; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Initializer values for message structs */ -#define meshtastic_ServiceEnvelope_init_default {NULL, NULL, NULL} -#define meshtastic_MapReport_init_default {"", "", _meshtastic_Config_DeviceConfig_Role_MIN, _meshtastic_HardwareModel_MIN, "", _meshtastic_Config_LoRaConfig_RegionCode_MIN, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, 0, 0, 0} -#define meshtastic_ServiceEnvelope_init_zero {NULL, NULL, NULL} -#define meshtastic_MapReport_init_zero {"", "", _meshtastic_Config_DeviceConfig_Role_MIN, _meshtastic_HardwareModel_MIN, "", _meshtastic_Config_LoRaConfig_RegionCode_MIN, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, 0, 0, 0} +#define meshtastic_ServiceEnvelope_init_default \ + { \ + NULL, NULL, NULL \ + } +#define meshtastic_MapReport_init_default \ + { \ + "", "", _meshtastic_Config_DeviceConfig_Role_MIN, _meshtastic_HardwareModel_MIN, "", _meshtastic_Config_LoRaConfig_RegionCode_MIN, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, 0, 0, 0 \ + } +#define meshtastic_ServiceEnvelope_init_zero \ + { \ + NULL, NULL, NULL \ + } +#define meshtastic_MapReport_init_zero \ + { \ + "", "", _meshtastic_Config_DeviceConfig_Role_MIN, _meshtastic_HardwareModel_MIN, "", _meshtastic_Config_LoRaConfig_RegionCode_MIN, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, 0, 0, 0 \ + } /* Field tags (for use in manual encoding/decoding) */ -#define meshtastic_ServiceEnvelope_packet_tag 1 +#define meshtastic_ServiceEnvelope_packet_tag 1 #define meshtastic_ServiceEnvelope_channel_id_tag 2 #define meshtastic_ServiceEnvelope_gateway_id_tag 3 -#define meshtastic_MapReport_long_name_tag 1 -#define meshtastic_MapReport_short_name_tag 2 -#define meshtastic_MapReport_role_tag 3 -#define meshtastic_MapReport_hw_model_tag 4 +#define meshtastic_MapReport_long_name_tag 1 +#define meshtastic_MapReport_short_name_tag 2 +#define meshtastic_MapReport_role_tag 3 +#define meshtastic_MapReport_hw_model_tag 4 #define meshtastic_MapReport_firmware_version_tag 5 -#define meshtastic_MapReport_region_tag 6 -#define meshtastic_MapReport_modem_preset_tag 7 +#define meshtastic_MapReport_region_tag 6 +#define meshtastic_MapReport_modem_preset_tag 7 #define meshtastic_MapReport_has_default_channel_tag 8 -#define meshtastic_MapReport_latitude_i_tag 9 -#define meshtastic_MapReport_longitude_i_tag 10 -#define meshtastic_MapReport_altitude_tag 11 +#define meshtastic_MapReport_latitude_i_tag 9 +#define meshtastic_MapReport_longitude_i_tag 10 +#define meshtastic_MapReport_altitude_tag 11 #define meshtastic_MapReport_position_precision_tag 12 #define meshtastic_MapReport_num_online_local_nodes_tag 13 #define meshtastic_MapReport_has_opted_report_location_tag 14 /* Struct field encoding specification for nanopb */ #define meshtastic_ServiceEnvelope_FIELDLIST(X, a) \ -X(a, POINTER, OPTIONAL, MESSAGE, packet, 1) \ -X(a, POINTER, SINGULAR, STRING, channel_id, 2) \ -X(a, POINTER, SINGULAR, STRING, gateway_id, 3) + X(a, POINTER, OPTIONAL, MESSAGE, packet, 1) \ + X(a, POINTER, SINGULAR, STRING, channel_id, 2) \ + X(a, POINTER, SINGULAR, STRING, gateway_id, 3) #define meshtastic_ServiceEnvelope_CALLBACK NULL #define meshtastic_ServiceEnvelope_DEFAULT NULL #define meshtastic_ServiceEnvelope_packet_MSGTYPE meshtastic_MeshPacket -#define meshtastic_MapReport_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, long_name, 1) \ -X(a, STATIC, SINGULAR, STRING, short_name, 2) \ -X(a, STATIC, SINGULAR, UENUM, role, 3) \ -X(a, STATIC, SINGULAR, UENUM, hw_model, 4) \ -X(a, STATIC, SINGULAR, STRING, firmware_version, 5) \ -X(a, STATIC, SINGULAR, UENUM, region, 6) \ -X(a, STATIC, SINGULAR, UENUM, modem_preset, 7) \ -X(a, STATIC, SINGULAR, BOOL, has_default_channel, 8) \ -X(a, STATIC, SINGULAR, SFIXED32, latitude_i, 9) \ -X(a, STATIC, SINGULAR, SFIXED32, longitude_i, 10) \ -X(a, STATIC, SINGULAR, INT32, altitude, 11) \ -X(a, STATIC, SINGULAR, UINT32, position_precision, 12) \ -X(a, STATIC, SINGULAR, UINT32, num_online_local_nodes, 13) \ -X(a, STATIC, SINGULAR, BOOL, has_opted_report_location, 14) +#define meshtastic_MapReport_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, STRING, long_name, 1) \ + X(a, STATIC, SINGULAR, STRING, short_name, 2) \ + X(a, STATIC, SINGULAR, UENUM, role, 3) \ + X(a, STATIC, SINGULAR, UENUM, hw_model, 4) \ + X(a, STATIC, SINGULAR, STRING, firmware_version, 5) \ + X(a, STATIC, SINGULAR, UENUM, region, 6) \ + X(a, STATIC, SINGULAR, UENUM, modem_preset, 7) \ + X(a, STATIC, SINGULAR, BOOL, has_default_channel, 8) \ + X(a, STATIC, SINGULAR, SFIXED32, latitude_i, 9) \ + X(a, STATIC, SINGULAR, SFIXED32, longitude_i, 10) \ + X(a, STATIC, SINGULAR, INT32, altitude, 11) \ + X(a, STATIC, SINGULAR, UINT32, position_precision, 12) \ + X(a, STATIC, SINGULAR, UINT32, num_online_local_nodes, 13) \ + X(a, STATIC, SINGULAR, BOOL, has_opted_report_location, 14) #define meshtastic_MapReport_CALLBACK NULL #define meshtastic_MapReport_DEFAULT NULL -extern const pb_msgdesc_t meshtastic_ServiceEnvelope_msg; -extern const pb_msgdesc_t meshtastic_MapReport_msg; + extern const pb_msgdesc_t meshtastic_ServiceEnvelope_msg; + extern const pb_msgdesc_t meshtastic_MapReport_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_ServiceEnvelope_fields &meshtastic_ServiceEnvelope_msg @@ -126,7 +140,7 @@ extern const pb_msgdesc_t meshtastic_MapReport_msg; /* Maximum encoded size of messages (where known) */ /* meshtastic_ServiceEnvelope_size depends on runtime parameters */ #define MESHTASTIC_MESHTASTIC_MQTT_PB_H_MAX_SIZE meshtastic_MapReport_size -#define meshtastic_MapReport_size 110 +#define meshtastic_MapReport_size 110 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/paxcount.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/paxcount.pb.cpp index ff738bde..d1886672 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/paxcount.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/paxcount.pb.cpp @@ -7,6 +7,3 @@ #endif PB_BIND(meshtastic_Paxcount, meshtastic_Paxcount, AUTO) - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/paxcount.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/paxcount.pb.h index 06078aef..870f7b05 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/paxcount.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/paxcount.pb.h @@ -11,7 +11,8 @@ /* Struct definitions */ /* TODO: REPLACE */ -typedef struct _meshtastic_Paxcount { +typedef struct _meshtastic_Paxcount +{ /* seen Wifi devices */ uint32_t wifi; /* Seen BLE devices */ @@ -20,36 +21,42 @@ typedef struct _meshtastic_Paxcount { uint32_t uptime; } meshtastic_Paxcount; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Initializer values for message structs */ -#define meshtastic_Paxcount_init_default {0, 0, 0} -#define meshtastic_Paxcount_init_zero {0, 0, 0} +#define meshtastic_Paxcount_init_default \ + { \ + 0, 0, 0 \ + } +#define meshtastic_Paxcount_init_zero \ + { \ + 0, 0, 0 \ + } /* Field tags (for use in manual encoding/decoding) */ -#define meshtastic_Paxcount_wifi_tag 1 -#define meshtastic_Paxcount_ble_tag 2 -#define meshtastic_Paxcount_uptime_tag 3 +#define meshtastic_Paxcount_wifi_tag 1 +#define meshtastic_Paxcount_ble_tag 2 +#define meshtastic_Paxcount_uptime_tag 3 /* Struct field encoding specification for nanopb */ #define meshtastic_Paxcount_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, wifi, 1) \ -X(a, STATIC, SINGULAR, UINT32, ble, 2) \ -X(a, STATIC, SINGULAR, UINT32, uptime, 3) + X(a, STATIC, SINGULAR, UINT32, wifi, 1) \ + X(a, STATIC, SINGULAR, UINT32, ble, 2) \ + X(a, STATIC, SINGULAR, UINT32, uptime, 3) #define meshtastic_Paxcount_CALLBACK NULL #define meshtastic_Paxcount_DEFAULT NULL -extern const pb_msgdesc_t meshtastic_Paxcount_msg; + extern const pb_msgdesc_t meshtastic_Paxcount_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_Paxcount_fields &meshtastic_Paxcount_msg /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_PAXCOUNT_PB_H_MAX_SIZE meshtastic_Paxcount_size -#define meshtastic_Paxcount_size 18 +#define meshtastic_Paxcount_size 18 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.cpp index 15a6ba37..38f17446 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.cpp @@ -5,7 +5,3 @@ #if PB_PROTO_HEADER_VERSION != 40 #error Regenerate this file with the current version of nanopb generator. #endif - - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.h index 67adc60c..5066edbe 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/portnums.pb.h @@ -22,7 +22,8 @@ Note: This was formerly a Type enum named 'typ' with the same id # We have change to this 'portnum' based scheme for specifying app handlers for particular payloads. This change is backwards compatible by treating the legacy OPAQUE/CLEAR_TEXT values identically. */ -typedef enum _meshtastic_PortNum { +typedef enum _meshtastic_PortNum +{ /* Deprecated: do not use in new code (formerly called OPAQUE) A message sent from a device outside of the mesh, in a form the mesh does not understand NOTE: This must be 0, because it is documented in IMeshService.aidl to be so @@ -149,14 +150,14 @@ typedef enum _meshtastic_PortNum { } meshtastic_PortNum; #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Helper constants for enums */ #define _meshtastic_PortNum_MIN meshtastic_PortNum_UNKNOWN_APP #define _meshtastic_PortNum_MAX meshtastic_PortNum_MAX -#define _meshtastic_PortNum_ARRAYSIZE ((meshtastic_PortNum)(meshtastic_PortNum_MAX+1)) - +#define _meshtastic_PortNum_ARRAYSIZE ((meshtastic_PortNum)(meshtastic_PortNum_MAX + 1)) #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/powermon.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/powermon.pb.cpp index 8838e165..508ec6a3 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/powermon.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/powermon.pb.cpp @@ -8,12 +8,4 @@ PB_BIND(meshtastic_PowerMon, meshtastic_PowerMon, AUTO) - PB_BIND(meshtastic_PowerStressMessage, meshtastic_PowerStressMessage, AUTO) - - - - - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/powermon.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/powermon.pb.h index 3072b8ac..0769d2ef 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/powermon.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/powermon.pb.h @@ -12,7 +12,8 @@ /* Enum definitions */ /* Any significant power changing event in meshtastic should be tagged with a powermon state transition. If you are making new meshtastic features feel free to add new entries at the end of this definition. */ -typedef enum _meshtastic_PowerMon_State { +typedef enum _meshtastic_PowerMon_State +{ meshtastic_PowerMon_State_None = 0, meshtastic_PowerMon_State_CPU_DeepSleep = 1, meshtastic_PowerMon_State_CPU_LightSleep = 2, @@ -41,86 +42,99 @@ something like "S:PM:C,0x00001234,REASON" where the hex number is the bitmask of /* What operation would we like the UUT to perform. note: senders should probably set want_response in their request packets, so that they can know when the state machine has started processing their request */ -typedef enum _meshtastic_PowerStressMessage_Opcode { +typedef enum _meshtastic_PowerStressMessage_Opcode +{ /* Unset/unused */ meshtastic_PowerStressMessage_Opcode_UNSET = 0, - meshtastic_PowerStressMessage_Opcode_PRINT_INFO = 1, /* Print board version slog and send an ack that we are alive and ready to process commands */ - meshtastic_PowerStressMessage_Opcode_FORCE_QUIET = 2, /* Try to turn off all automatic processing of packets, screen, sleeping, etc (to make it easier to measure in isolation) */ - meshtastic_PowerStressMessage_Opcode_END_QUIET = 3, /* Stop powerstress processing - probably by just rebooting the board */ - meshtastic_PowerStressMessage_Opcode_SCREEN_ON = 16, /* Turn the screen on */ - meshtastic_PowerStressMessage_Opcode_SCREEN_OFF = 17, /* Turn the screen off */ - meshtastic_PowerStressMessage_Opcode_CPU_IDLE = 32, /* Let the CPU run but we assume mostly idling for num_seconds */ + meshtastic_PowerStressMessage_Opcode_PRINT_INFO = 1, /* Print board version slog and send an ack that we are alive and ready to process commands */ + meshtastic_PowerStressMessage_Opcode_FORCE_QUIET = 2, /* Try to turn off all automatic processing of packets, screen, sleeping, etc (to make it easier to measure in isolation) */ + meshtastic_PowerStressMessage_Opcode_END_QUIET = 3, /* Stop powerstress processing - probably by just rebooting the board */ + meshtastic_PowerStressMessage_Opcode_SCREEN_ON = 16, /* Turn the screen on */ + meshtastic_PowerStressMessage_Opcode_SCREEN_OFF = 17, /* Turn the screen off */ + meshtastic_PowerStressMessage_Opcode_CPU_IDLE = 32, /* Let the CPU run but we assume mostly idling for num_seconds */ meshtastic_PowerStressMessage_Opcode_CPU_DEEPSLEEP = 33, /* Force deep sleep for FIXME seconds */ - meshtastic_PowerStressMessage_Opcode_CPU_FULLON = 34, /* Spin the CPU as fast as possible for num_seconds */ - meshtastic_PowerStressMessage_Opcode_LED_ON = 48, /* Turn the LED on for num_seconds (and leave it on - for baseline power measurement purposes) */ - meshtastic_PowerStressMessage_Opcode_LED_OFF = 49, /* Force the LED off for num_seconds */ - meshtastic_PowerStressMessage_Opcode_LORA_OFF = 64, /* Completely turn off the LORA radio for num_seconds */ - meshtastic_PowerStressMessage_Opcode_LORA_TX = 65, /* Send Lora packets for num_seconds */ - meshtastic_PowerStressMessage_Opcode_LORA_RX = 66, /* Receive Lora packets for num_seconds (node will be mostly just listening, unless an external agent is helping stress this by sending packets on the current channel) */ - meshtastic_PowerStressMessage_Opcode_BT_OFF = 80, /* Turn off the BT radio for num_seconds */ - meshtastic_PowerStressMessage_Opcode_BT_ON = 81, /* Turn on the BT radio for num_seconds */ - meshtastic_PowerStressMessage_Opcode_WIFI_OFF = 96, /* Turn off the WIFI radio for num_seconds */ - meshtastic_PowerStressMessage_Opcode_WIFI_ON = 97, /* Turn on the WIFI radio for num_seconds */ - meshtastic_PowerStressMessage_Opcode_GPS_OFF = 112, /* Turn off the GPS radio for num_seconds */ - meshtastic_PowerStressMessage_Opcode_GPS_ON = 113 /* Turn on the GPS radio for num_seconds */ + meshtastic_PowerStressMessage_Opcode_CPU_FULLON = 34, /* Spin the CPU as fast as possible for num_seconds */ + meshtastic_PowerStressMessage_Opcode_LED_ON = 48, /* Turn the LED on for num_seconds (and leave it on - for baseline power measurement purposes) */ + meshtastic_PowerStressMessage_Opcode_LED_OFF = 49, /* Force the LED off for num_seconds */ + meshtastic_PowerStressMessage_Opcode_LORA_OFF = 64, /* Completely turn off the LORA radio for num_seconds */ + meshtastic_PowerStressMessage_Opcode_LORA_TX = 65, /* Send Lora packets for num_seconds */ + meshtastic_PowerStressMessage_Opcode_LORA_RX = 66, /* Receive Lora packets for num_seconds (node will be mostly just listening, unless an external agent is helping stress this by sending packets on the current channel) */ + meshtastic_PowerStressMessage_Opcode_BT_OFF = 80, /* Turn off the BT radio for num_seconds */ + meshtastic_PowerStressMessage_Opcode_BT_ON = 81, /* Turn on the BT radio for num_seconds */ + meshtastic_PowerStressMessage_Opcode_WIFI_OFF = 96, /* Turn off the WIFI radio for num_seconds */ + meshtastic_PowerStressMessage_Opcode_WIFI_ON = 97, /* Turn on the WIFI radio for num_seconds */ + meshtastic_PowerStressMessage_Opcode_GPS_OFF = 112, /* Turn off the GPS radio for num_seconds */ + meshtastic_PowerStressMessage_Opcode_GPS_ON = 113 /* Turn on the GPS radio for num_seconds */ } meshtastic_PowerStressMessage_Opcode; /* Struct definitions */ /* Note: There are no 'PowerMon' messages normally in use (PowerMons are sent only as structured logs - slogs). But we wrap our State enum in this message to effectively nest a namespace (without our linter yelling at us) */ -typedef struct _meshtastic_PowerMon { +typedef struct _meshtastic_PowerMon +{ char dummy_field; } meshtastic_PowerMon; /* PowerStress testing support via the C++ PowerStress module */ -typedef struct _meshtastic_PowerStressMessage { +typedef struct _meshtastic_PowerStressMessage +{ /* What type of HardwareMessage is this? */ meshtastic_PowerStressMessage_Opcode cmd; float num_seconds; } meshtastic_PowerStressMessage; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Helper constants for enums */ #define _meshtastic_PowerMon_State_MIN meshtastic_PowerMon_State_None #define _meshtastic_PowerMon_State_MAX meshtastic_PowerMon_State_GPS_Active -#define _meshtastic_PowerMon_State_ARRAYSIZE ((meshtastic_PowerMon_State)(meshtastic_PowerMon_State_GPS_Active+1)) +#define _meshtastic_PowerMon_State_ARRAYSIZE ((meshtastic_PowerMon_State)(meshtastic_PowerMon_State_GPS_Active + 1)) #define _meshtastic_PowerStressMessage_Opcode_MIN meshtastic_PowerStressMessage_Opcode_UNSET #define _meshtastic_PowerStressMessage_Opcode_MAX meshtastic_PowerStressMessage_Opcode_GPS_ON -#define _meshtastic_PowerStressMessage_Opcode_ARRAYSIZE ((meshtastic_PowerStressMessage_Opcode)(meshtastic_PowerStressMessage_Opcode_GPS_ON+1)) - +#define _meshtastic_PowerStressMessage_Opcode_ARRAYSIZE ((meshtastic_PowerStressMessage_Opcode)(meshtastic_PowerStressMessage_Opcode_GPS_ON + 1)) #define meshtastic_PowerStressMessage_cmd_ENUMTYPE meshtastic_PowerStressMessage_Opcode - /* Initializer values for message structs */ -#define meshtastic_PowerMon_init_default {0} -#define meshtastic_PowerStressMessage_init_default {_meshtastic_PowerStressMessage_Opcode_MIN, 0} -#define meshtastic_PowerMon_init_zero {0} -#define meshtastic_PowerStressMessage_init_zero {_meshtastic_PowerStressMessage_Opcode_MIN, 0} +#define meshtastic_PowerMon_init_default \ + { \ + 0 \ + } +#define meshtastic_PowerStressMessage_init_default \ + { \ + _meshtastic_PowerStressMessage_Opcode_MIN, 0 \ + } +#define meshtastic_PowerMon_init_zero \ + { \ + 0 \ + } +#define meshtastic_PowerStressMessage_init_zero \ + { \ + _meshtastic_PowerStressMessage_Opcode_MIN, 0 \ + } /* Field tags (for use in manual encoding/decoding) */ -#define meshtastic_PowerStressMessage_cmd_tag 1 +#define meshtastic_PowerStressMessage_cmd_tag 1 #define meshtastic_PowerStressMessage_num_seconds_tag 2 /* Struct field encoding specification for nanopb */ -#define meshtastic_PowerMon_FIELDLIST(X, a) \ +#define meshtastic_PowerMon_FIELDLIST(X, a) #define meshtastic_PowerMon_CALLBACK NULL #define meshtastic_PowerMon_DEFAULT NULL #define meshtastic_PowerStressMessage_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UENUM, cmd, 1) \ -X(a, STATIC, SINGULAR, FLOAT, num_seconds, 2) + X(a, STATIC, SINGULAR, UENUM, cmd, 1) \ + X(a, STATIC, SINGULAR, FLOAT, num_seconds, 2) #define meshtastic_PowerStressMessage_CALLBACK NULL #define meshtastic_PowerStressMessage_DEFAULT NULL -extern const pb_msgdesc_t meshtastic_PowerMon_msg; -extern const pb_msgdesc_t meshtastic_PowerStressMessage_msg; + extern const pb_msgdesc_t meshtastic_PowerMon_msg; + extern const pb_msgdesc_t meshtastic_PowerStressMessage_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_PowerMon_fields &meshtastic_PowerMon_msg @@ -128,8 +142,8 @@ extern const pb_msgdesc_t meshtastic_PowerStressMessage_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_POWERMON_PB_H_MAX_SIZE meshtastic_PowerStressMessage_size -#define meshtastic_PowerMon_size 0 -#define meshtastic_PowerStressMessage_size 7 +#define meshtastic_PowerMon_size 0 +#define meshtastic_PowerStressMessage_size 7 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/remote_hardware.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/remote_hardware.pb.cpp index 8942104b..20d79ee7 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/remote_hardware.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/remote_hardware.pb.cpp @@ -7,8 +7,3 @@ #endif PB_BIND(meshtastic_HardwareMessage, meshtastic_HardwareMessage, AUTO) - - - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/remote_hardware.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/remote_hardware.pb.h index 9ab3413c..bf4c18b4 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/remote_hardware.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/remote_hardware.pb.h @@ -11,7 +11,8 @@ /* Enum definitions */ /* TODO: REPLACE */ -typedef enum _meshtastic_HardwareMessage_Type { +typedef enum _meshtastic_HardwareMessage_Type +{ /* Unset/unused */ meshtastic_HardwareMessage_Type_UNSET = 0, /* Set gpio gpios based on gpio_mask/gpio_value */ @@ -38,7 +39,8 @@ typedef enum _meshtastic_HardwareMessage_Type { because no security yet (beyond the channel mechanism). It should be off by default and then protected based on some TBD mechanism (a special channel once multichannel support is included?) */ -typedef struct _meshtastic_HardwareMessage { +typedef struct _meshtastic_HardwareMessage +{ /* What type of HardwareMessage is this? */ meshtastic_HardwareMessage_Type type; /* What gpios are we changing. Not used for all MessageTypes, see MessageType for details */ @@ -48,44 +50,49 @@ typedef struct _meshtastic_HardwareMessage { uint64_t gpio_value; } meshtastic_HardwareMessage; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Helper constants for enums */ #define _meshtastic_HardwareMessage_Type_MIN meshtastic_HardwareMessage_Type_UNSET #define _meshtastic_HardwareMessage_Type_MAX meshtastic_HardwareMessage_Type_READ_GPIOS_REPLY -#define _meshtastic_HardwareMessage_Type_ARRAYSIZE ((meshtastic_HardwareMessage_Type)(meshtastic_HardwareMessage_Type_READ_GPIOS_REPLY+1)) +#define _meshtastic_HardwareMessage_Type_ARRAYSIZE ((meshtastic_HardwareMessage_Type)(meshtastic_HardwareMessage_Type_READ_GPIOS_REPLY + 1)) #define meshtastic_HardwareMessage_type_ENUMTYPE meshtastic_HardwareMessage_Type - /* Initializer values for message structs */ -#define meshtastic_HardwareMessage_init_default {_meshtastic_HardwareMessage_Type_MIN, 0, 0} -#define meshtastic_HardwareMessage_init_zero {_meshtastic_HardwareMessage_Type_MIN, 0, 0} +#define meshtastic_HardwareMessage_init_default \ + { \ + _meshtastic_HardwareMessage_Type_MIN, 0, 0 \ + } +#define meshtastic_HardwareMessage_init_zero \ + { \ + _meshtastic_HardwareMessage_Type_MIN, 0, 0 \ + } /* Field tags (for use in manual encoding/decoding) */ -#define meshtastic_HardwareMessage_type_tag 1 +#define meshtastic_HardwareMessage_type_tag 1 #define meshtastic_HardwareMessage_gpio_mask_tag 2 #define meshtastic_HardwareMessage_gpio_value_tag 3 /* Struct field encoding specification for nanopb */ #define meshtastic_HardwareMessage_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UENUM, type, 1) \ -X(a, STATIC, SINGULAR, UINT64, gpio_mask, 2) \ -X(a, STATIC, SINGULAR, UINT64, gpio_value, 3) + X(a, STATIC, SINGULAR, UENUM, type, 1) \ + X(a, STATIC, SINGULAR, UINT64, gpio_mask, 2) \ + X(a, STATIC, SINGULAR, UINT64, gpio_value, 3) #define meshtastic_HardwareMessage_CALLBACK NULL #define meshtastic_HardwareMessage_DEFAULT NULL -extern const pb_msgdesc_t meshtastic_HardwareMessage_msg; + extern const pb_msgdesc_t meshtastic_HardwareMessage_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_HardwareMessage_fields &meshtastic_HardwareMessage_msg /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_REMOTE_HARDWARE_PB_H_MAX_SIZE meshtastic_HardwareMessage_size -#define meshtastic_HardwareMessage_size 24 +#define meshtastic_HardwareMessage_size 24 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/rtttl.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/rtttl.pb.cpp index c994741f..c0eb6302 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/rtttl.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/rtttl.pb.cpp @@ -7,6 +7,3 @@ #endif PB_BIND(meshtastic_RTTTLConfig, meshtastic_RTTTLConfig, AUTO) - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/rtttl.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/rtttl.pb.h index b6e152db..2f446c1f 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/rtttl.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/rtttl.pb.h @@ -11,37 +11,44 @@ /* Struct definitions */ /* Canned message module configuration. */ -typedef struct _meshtastic_RTTTLConfig { +typedef struct _meshtastic_RTTTLConfig +{ /* Ringtone for PWM Buzzer in RTTTL Format. */ char ringtone[231]; } meshtastic_RTTTLConfig; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Initializer values for message structs */ -#define meshtastic_RTTTLConfig_init_default {""} -#define meshtastic_RTTTLConfig_init_zero {""} +#define meshtastic_RTTTLConfig_init_default \ + { \ + "" \ + } +#define meshtastic_RTTTLConfig_init_zero \ + { \ + "" \ + } /* Field tags (for use in manual encoding/decoding) */ -#define meshtastic_RTTTLConfig_ringtone_tag 1 +#define meshtastic_RTTTLConfig_ringtone_tag 1 /* Struct field encoding specification for nanopb */ #define meshtastic_RTTTLConfig_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, ringtone, 1) + X(a, STATIC, SINGULAR, STRING, ringtone, 1) #define meshtastic_RTTTLConfig_CALLBACK NULL #define meshtastic_RTTTLConfig_DEFAULT NULL -extern const pb_msgdesc_t meshtastic_RTTTLConfig_msg; + extern const pb_msgdesc_t meshtastic_RTTTLConfig_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_RTTTLConfig_fields &meshtastic_RTTTLConfig_msg /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_RTTTL_PB_H_MAX_SIZE meshtastic_RTTTLConfig_size -#define meshtastic_RTTTLConfig_size 233 +#define meshtastic_RTTTLConfig_size 233 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/storeforward.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/storeforward.pb.cpp index 82db566a..2c86262d 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/storeforward.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/storeforward.pb.cpp @@ -8,16 +8,8 @@ PB_BIND(meshtastic_StoreAndForward, meshtastic_StoreAndForward, AUTO) - PB_BIND(meshtastic_StoreAndForward_Statistics, meshtastic_StoreAndForward_Statistics, AUTO) - PB_BIND(meshtastic_StoreAndForward_History, meshtastic_StoreAndForward_History, AUTO) - PB_BIND(meshtastic_StoreAndForward_Heartbeat, meshtastic_StoreAndForward_Heartbeat, AUTO) - - - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/storeforward.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/storeforward.pb.h index 75cff520..53c94fc6 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/storeforward.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/storeforward.pb.h @@ -12,7 +12,8 @@ /* Enum definitions */ /* 001 - 063 = From Router 064 - 127 = From Client */ -typedef enum _meshtastic_StoreAndForward_RequestResponse { +typedef enum _meshtastic_StoreAndForward_RequestResponse +{ /* Unset/unused */ meshtastic_StoreAndForward_RequestResponse_UNSET = 0, /* Router is an in error state. */ @@ -51,7 +52,8 @@ typedef enum _meshtastic_StoreAndForward_RequestResponse { /* Struct definitions */ /* TODO: REPLACE */ -typedef struct _meshtastic_StoreAndForward_Statistics { +typedef struct _meshtastic_StoreAndForward_Statistics +{ /* Number of messages we have ever seen */ uint32_t messages_total; /* Number of messages we have currently saved our history. */ @@ -73,7 +75,8 @@ typedef struct _meshtastic_StoreAndForward_Statistics { } meshtastic_StoreAndForward_Statistics; /* TODO: REPLACE */ -typedef struct _meshtastic_StoreAndForward_History { +typedef struct _meshtastic_StoreAndForward_History +{ /* Number of that will be sent to the client */ uint32_t history_messages; /* The window of messages that was used to filter the history client requested */ @@ -84,7 +87,8 @@ typedef struct _meshtastic_StoreAndForward_History { } meshtastic_StoreAndForward_History; /* TODO: REPLACE */ -typedef struct _meshtastic_StoreAndForward_Heartbeat { +typedef struct _meshtastic_StoreAndForward_Heartbeat +{ /* Period in seconds that the heartbeat is sent out that will be sent to the client */ uint32_t period; /* If set, this is not the primary Store & Forward router on the mesh */ @@ -93,11 +97,13 @@ typedef struct _meshtastic_StoreAndForward_Heartbeat { typedef PB_BYTES_ARRAY_T(233) meshtastic_StoreAndForward_text_t; /* TODO: REPLACE */ -typedef struct _meshtastic_StoreAndForward { +typedef struct _meshtastic_StoreAndForward +{ /* TODO: REPLACE */ meshtastic_StoreAndForward_RequestResponse rr; pb_size_t which_variant; - union { + union + { /* TODO: REPLACE */ meshtastic_StoreAndForward_Statistics stats; /* TODO: REPLACE */ @@ -109,31 +115,51 @@ typedef struct _meshtastic_StoreAndForward { } variant; } meshtastic_StoreAndForward; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Helper constants for enums */ #define _meshtastic_StoreAndForward_RequestResponse_MIN meshtastic_StoreAndForward_RequestResponse_UNSET #define _meshtastic_StoreAndForward_RequestResponse_MAX meshtastic_StoreAndForward_RequestResponse_CLIENT_ABORT -#define _meshtastic_StoreAndForward_RequestResponse_ARRAYSIZE ((meshtastic_StoreAndForward_RequestResponse)(meshtastic_StoreAndForward_RequestResponse_CLIENT_ABORT+1)) +#define _meshtastic_StoreAndForward_RequestResponse_ARRAYSIZE ((meshtastic_StoreAndForward_RequestResponse)(meshtastic_StoreAndForward_RequestResponse_CLIENT_ABORT + 1)) #define meshtastic_StoreAndForward_rr_ENUMTYPE meshtastic_StoreAndForward_RequestResponse - - - - /* Initializer values for message structs */ -#define meshtastic_StoreAndForward_init_default {_meshtastic_StoreAndForward_RequestResponse_MIN, 0, {meshtastic_StoreAndForward_Statistics_init_default}} -#define meshtastic_StoreAndForward_Statistics_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0} -#define meshtastic_StoreAndForward_History_init_default {0, 0, 0} -#define meshtastic_StoreAndForward_Heartbeat_init_default {0, 0} -#define meshtastic_StoreAndForward_init_zero {_meshtastic_StoreAndForward_RequestResponse_MIN, 0, {meshtastic_StoreAndForward_Statistics_init_zero}} -#define meshtastic_StoreAndForward_Statistics_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0} -#define meshtastic_StoreAndForward_History_init_zero {0, 0, 0} -#define meshtastic_StoreAndForward_Heartbeat_init_zero {0, 0} +#define meshtastic_StoreAndForward_init_default \ + { \ + _meshtastic_StoreAndForward_RequestResponse_MIN, 0, { meshtastic_StoreAndForward_Statistics_init_default } \ + } +#define meshtastic_StoreAndForward_Statistics_init_default \ + { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0 \ + } +#define meshtastic_StoreAndForward_History_init_default \ + { \ + 0, 0, 0 \ + } +#define meshtastic_StoreAndForward_Heartbeat_init_default \ + { \ + 0, 0 \ + } +#define meshtastic_StoreAndForward_init_zero \ + { \ + _meshtastic_StoreAndForward_RequestResponse_MIN, 0, { meshtastic_StoreAndForward_Statistics_init_zero } \ + } +#define meshtastic_StoreAndForward_Statistics_init_zero \ + { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0 \ + } +#define meshtastic_StoreAndForward_History_init_zero \ + { \ + 0, 0, 0 \ + } +#define meshtastic_StoreAndForward_Heartbeat_init_zero \ + { \ + 0, 0 \ + } /* Field tags (for use in manual encoding/decoding) */ #define meshtastic_StoreAndForward_Statistics_messages_total_tag 1 @@ -150,19 +176,19 @@ extern "C" { #define meshtastic_StoreAndForward_History_last_request_tag 3 #define meshtastic_StoreAndForward_Heartbeat_period_tag 1 #define meshtastic_StoreAndForward_Heartbeat_secondary_tag 2 -#define meshtastic_StoreAndForward_rr_tag 1 -#define meshtastic_StoreAndForward_stats_tag 2 -#define meshtastic_StoreAndForward_history_tag 3 +#define meshtastic_StoreAndForward_rr_tag 1 +#define meshtastic_StoreAndForward_stats_tag 2 +#define meshtastic_StoreAndForward_history_tag 3 #define meshtastic_StoreAndForward_heartbeat_tag 4 -#define meshtastic_StoreAndForward_text_tag 5 +#define meshtastic_StoreAndForward_text_tag 5 /* Struct field encoding specification for nanopb */ -#define meshtastic_StoreAndForward_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UENUM, rr, 1) \ -X(a, STATIC, ONEOF, MESSAGE, (variant,stats,variant.stats), 2) \ -X(a, STATIC, ONEOF, MESSAGE, (variant,history,variant.history), 3) \ -X(a, STATIC, ONEOF, MESSAGE, (variant,heartbeat,variant.heartbeat), 4) \ -X(a, STATIC, ONEOF, BYTES, (variant,text,variant.text), 5) +#define meshtastic_StoreAndForward_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UENUM, rr, 1) \ + X(a, STATIC, ONEOF, MESSAGE, (variant, stats, variant.stats), 2) \ + X(a, STATIC, ONEOF, MESSAGE, (variant, history, variant.history), 3) \ + X(a, STATIC, ONEOF, MESSAGE, (variant, heartbeat, variant.heartbeat), 4) \ + X(a, STATIC, ONEOF, BYTES, (variant, text, variant.text), 5) #define meshtastic_StoreAndForward_CALLBACK NULL #define meshtastic_StoreAndForward_DEFAULT NULL #define meshtastic_StoreAndForward_variant_stats_MSGTYPE meshtastic_StoreAndForward_Statistics @@ -170,35 +196,35 @@ X(a, STATIC, ONEOF, BYTES, (variant,text,variant.text), 5) #define meshtastic_StoreAndForward_variant_heartbeat_MSGTYPE meshtastic_StoreAndForward_Heartbeat #define meshtastic_StoreAndForward_Statistics_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, messages_total, 1) \ -X(a, STATIC, SINGULAR, UINT32, messages_saved, 2) \ -X(a, STATIC, SINGULAR, UINT32, messages_max, 3) \ -X(a, STATIC, SINGULAR, UINT32, up_time, 4) \ -X(a, STATIC, SINGULAR, UINT32, requests, 5) \ -X(a, STATIC, SINGULAR, UINT32, requests_history, 6) \ -X(a, STATIC, SINGULAR, BOOL, heartbeat, 7) \ -X(a, STATIC, SINGULAR, UINT32, return_max, 8) \ -X(a, STATIC, SINGULAR, UINT32, return_window, 9) + X(a, STATIC, SINGULAR, UINT32, messages_total, 1) \ + X(a, STATIC, SINGULAR, UINT32, messages_saved, 2) \ + X(a, STATIC, SINGULAR, UINT32, messages_max, 3) \ + X(a, STATIC, SINGULAR, UINT32, up_time, 4) \ + X(a, STATIC, SINGULAR, UINT32, requests, 5) \ + X(a, STATIC, SINGULAR, UINT32, requests_history, 6) \ + X(a, STATIC, SINGULAR, BOOL, heartbeat, 7) \ + X(a, STATIC, SINGULAR, UINT32, return_max, 8) \ + X(a, STATIC, SINGULAR, UINT32, return_window, 9) #define meshtastic_StoreAndForward_Statistics_CALLBACK NULL #define meshtastic_StoreAndForward_Statistics_DEFAULT NULL #define meshtastic_StoreAndForward_History_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, history_messages, 1) \ -X(a, STATIC, SINGULAR, UINT32, window, 2) \ -X(a, STATIC, SINGULAR, UINT32, last_request, 3) + X(a, STATIC, SINGULAR, UINT32, history_messages, 1) \ + X(a, STATIC, SINGULAR, UINT32, window, 2) \ + X(a, STATIC, SINGULAR, UINT32, last_request, 3) #define meshtastic_StoreAndForward_History_CALLBACK NULL #define meshtastic_StoreAndForward_History_DEFAULT NULL #define meshtastic_StoreAndForward_Heartbeat_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, period, 1) \ -X(a, STATIC, SINGULAR, UINT32, secondary, 2) + X(a, STATIC, SINGULAR, UINT32, period, 1) \ + X(a, STATIC, SINGULAR, UINT32, secondary, 2) #define meshtastic_StoreAndForward_Heartbeat_CALLBACK NULL #define meshtastic_StoreAndForward_Heartbeat_DEFAULT NULL -extern const pb_msgdesc_t meshtastic_StoreAndForward_msg; -extern const pb_msgdesc_t meshtastic_StoreAndForward_Statistics_msg; -extern const pb_msgdesc_t meshtastic_StoreAndForward_History_msg; -extern const pb_msgdesc_t meshtastic_StoreAndForward_Heartbeat_msg; + extern const pb_msgdesc_t meshtastic_StoreAndForward_msg; + extern const pb_msgdesc_t meshtastic_StoreAndForward_Statistics_msg; + extern const pb_msgdesc_t meshtastic_StoreAndForward_History_msg; + extern const pb_msgdesc_t meshtastic_StoreAndForward_Heartbeat_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_StoreAndForward_fields &meshtastic_StoreAndForward_msg @@ -209,9 +235,9 @@ extern const pb_msgdesc_t meshtastic_StoreAndForward_Heartbeat_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_STOREFORWARD_PB_H_MAX_SIZE meshtastic_StoreAndForward_size #define meshtastic_StoreAndForward_Heartbeat_size 12 -#define meshtastic_StoreAndForward_History_size 18 +#define meshtastic_StoreAndForward_History_size 18 #define meshtastic_StoreAndForward_Statistics_size 50 -#define meshtastic_StoreAndForward_size 238 +#define meshtastic_StoreAndForward_size 238 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/telemetry.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/telemetry.pb.cpp index 345d7a15..518a2f16 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/telemetry.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/telemetry.pb.cpp @@ -8,31 +8,18 @@ PB_BIND(meshtastic_DeviceMetrics, meshtastic_DeviceMetrics, AUTO) - PB_BIND(meshtastic_EnvironmentMetrics, meshtastic_EnvironmentMetrics, AUTO) - PB_BIND(meshtastic_PowerMetrics, meshtastic_PowerMetrics, AUTO) - PB_BIND(meshtastic_AirQualityMetrics, meshtastic_AirQualityMetrics, AUTO) - PB_BIND(meshtastic_LocalStats, meshtastic_LocalStats, AUTO) - PB_BIND(meshtastic_HealthMetrics, meshtastic_HealthMetrics, AUTO) - PB_BIND(meshtastic_HostMetrics, meshtastic_HostMetrics, 2) - PB_BIND(meshtastic_Telemetry, meshtastic_Telemetry, 2) - PB_BIND(meshtastic_Nau7802Config, meshtastic_Nau7802Config, AUTO) - - - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/telemetry.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/telemetry.pb.h index dec89ba1..77bd076a 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/telemetry.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/telemetry.pb.h @@ -11,7 +11,8 @@ /* Enum definitions */ /* Supported I2C Sensors for telemetry in Meshtastic */ -typedef enum _meshtastic_TelemetrySensorType { +typedef enum _meshtastic_TelemetrySensorType +{ /* No external telemetry sensor explicitly set */ meshtastic_TelemetrySensorType_SENSOR_UNSET = 0, /* High accuracy temperature, pressure, humidity */ @@ -108,7 +109,8 @@ typedef enum _meshtastic_TelemetrySensorType { /* Struct definitions */ /* Key native device metrics such as battery level */ -typedef struct _meshtastic_DeviceMetrics { +typedef struct _meshtastic_DeviceMetrics +{ /* 0-100 (>100 means powered) */ bool has_battery_level; uint32_t battery_level; @@ -127,7 +129,8 @@ typedef struct _meshtastic_DeviceMetrics { } meshtastic_DeviceMetrics; /* Weather station or other environmental metrics */ -typedef struct _meshtastic_EnvironmentMetrics { +typedef struct _meshtastic_EnvironmentMetrics +{ /* Temperature measured */ bool has_temperature; float temperature; @@ -199,7 +202,8 @@ typedef struct _meshtastic_EnvironmentMetrics { } meshtastic_EnvironmentMetrics; /* Power Metrics (voltage / current / etc) */ -typedef struct _meshtastic_PowerMetrics { +typedef struct _meshtastic_PowerMetrics +{ /* Voltage (Ch1) */ bool has_ch1_voltage; float ch1_voltage; @@ -251,7 +255,8 @@ typedef struct _meshtastic_PowerMetrics { } meshtastic_PowerMetrics; /* Air quality metrics */ -typedef struct _meshtastic_AirQualityMetrics { +typedef struct _meshtastic_AirQualityMetrics +{ /* Concentration Units Standard PM1.0 in ug/m3 */ bool has_pm10_standard; uint32_t pm10_standard; @@ -330,7 +335,8 @@ typedef struct _meshtastic_AirQualityMetrics { } meshtastic_AirQualityMetrics; /* Local device mesh statistics */ -typedef struct _meshtastic_LocalStats { +typedef struct _meshtastic_LocalStats +{ /* How long the device has been running since the last reboot (in seconds) */ uint32_t uptime_seconds; /* Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise). */ @@ -364,7 +370,8 @@ typedef struct _meshtastic_LocalStats { } meshtastic_LocalStats; /* Health telemetry metrics */ -typedef struct _meshtastic_HealthMetrics { +typedef struct _meshtastic_HealthMetrics +{ /* Heart rate (beats per minute) */ bool has_heart_bpm; uint8_t heart_bpm; @@ -377,7 +384,8 @@ typedef struct _meshtastic_HealthMetrics { } meshtastic_HealthMetrics; /* Linux host metrics */ -typedef struct _meshtastic_HostMetrics { +typedef struct _meshtastic_HostMetrics +{ /* Host system uptime */ uint32_t uptime_seconds; /* Host system free memory */ @@ -403,11 +411,13 @@ typedef struct _meshtastic_HostMetrics { } meshtastic_HostMetrics; /* Types of Measurements the telemetry module is equipped to handle */ -typedef struct _meshtastic_Telemetry { +typedef struct _meshtastic_Telemetry +{ /* Seconds since 1970 - or 0 for unknown/unset */ uint32_t time; pb_size_t which_variant; - union { + union + { /* Key native device metrics such as battery level */ meshtastic_DeviceMetrics device_metrics; /* Weather station or other environmental metrics */ @@ -426,56 +436,101 @@ typedef struct _meshtastic_Telemetry { } meshtastic_Telemetry; /* NAU7802 Telemetry configuration, for saving to flash */ -typedef struct _meshtastic_Nau7802Config { +typedef struct _meshtastic_Nau7802Config +{ /* The offset setting for the NAU7802 */ int32_t zeroOffset; /* The calibration factor for the NAU7802 */ float calibrationFactor; } meshtastic_Nau7802Config; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Helper constants for enums */ #define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET #define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_BH1750 -#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_BH1750+1)) - - - - - - - - - - +#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_BH1750 + 1)) /* Initializer values for message structs */ -#define meshtastic_DeviceMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0} -#define meshtastic_EnvironmentMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} -#define meshtastic_PowerMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} -#define meshtastic_AirQualityMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} -#define meshtastic_LocalStats_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -#define meshtastic_HealthMetrics_init_default {false, 0, false, 0, false, 0} -#define meshtastic_HostMetrics_init_default {0, 0, 0, false, 0, false, 0, 0, 0, 0, false, ""} -#define meshtastic_Telemetry_init_default {0, 0, {meshtastic_DeviceMetrics_init_default}} -#define meshtastic_Nau7802Config_init_default {0, 0} -#define meshtastic_DeviceMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0} -#define meshtastic_EnvironmentMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} -#define meshtastic_PowerMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} -#define meshtastic_AirQualityMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} -#define meshtastic_LocalStats_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -#define meshtastic_HealthMetrics_init_zero {false, 0, false, 0, false, 0} -#define meshtastic_HostMetrics_init_zero {0, 0, 0, false, 0, false, 0, 0, 0, 0, false, ""} -#define meshtastic_Telemetry_init_zero {0, 0, {meshtastic_DeviceMetrics_init_zero}} -#define meshtastic_Nau7802Config_init_zero {0, 0} +#define meshtastic_DeviceMetrics_init_default \ + { \ + false, 0, false, 0, false, 0, false, 0, false, 0 \ + } +#define meshtastic_EnvironmentMetrics_init_default \ + { \ + false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0 \ + } +#define meshtastic_PowerMetrics_init_default \ + { \ + false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0 \ + } +#define meshtastic_AirQualityMetrics_init_default \ + { \ + false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0 \ + } +#define meshtastic_LocalStats_init_default \ + { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ + } +#define meshtastic_HealthMetrics_init_default \ + { \ + false, 0, false, 0, false, 0 \ + } +#define meshtastic_HostMetrics_init_default \ + { \ + 0, 0, 0, false, 0, false, 0, 0, 0, 0, false, "" \ + } +#define meshtastic_Telemetry_init_default \ + { \ + 0, 0, { meshtastic_DeviceMetrics_init_default } \ + } +#define meshtastic_Nau7802Config_init_default \ + { \ + 0, 0 \ + } +#define meshtastic_DeviceMetrics_init_zero \ + { \ + false, 0, false, 0, false, 0, false, 0, false, 0 \ + } +#define meshtastic_EnvironmentMetrics_init_zero \ + { \ + false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0 \ + } +#define meshtastic_PowerMetrics_init_zero \ + { \ + false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0 \ + } +#define meshtastic_AirQualityMetrics_init_zero \ + { \ + false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0 \ + } +#define meshtastic_LocalStats_init_zero \ + { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ + } +#define meshtastic_HealthMetrics_init_zero \ + { \ + false, 0, false, 0, false, 0 \ + } +#define meshtastic_HostMetrics_init_zero \ + { \ + 0, 0, 0, false, 0, false, 0, 0, 0, 0, false, "" \ + } +#define meshtastic_Telemetry_init_zero \ + { \ + 0, 0, { meshtastic_DeviceMetrics_init_zero } \ + } +#define meshtastic_Nau7802Config_init_zero \ + { \ + 0, 0 \ + } /* Field tags (for use in manual encoding/decoding) */ #define meshtastic_DeviceMetrics_battery_level_tag 1 -#define meshtastic_DeviceMetrics_voltage_tag 2 +#define meshtastic_DeviceMetrics_voltage_tag 2 #define meshtastic_DeviceMetrics_channel_utilization_tag 3 #define meshtastic_DeviceMetrics_air_util_tx_tag 4 #define meshtastic_DeviceMetrics_uptime_seconds_tag 5 @@ -485,9 +540,9 @@ extern "C" { #define meshtastic_EnvironmentMetrics_gas_resistance_tag 4 #define meshtastic_EnvironmentMetrics_voltage_tag 5 #define meshtastic_EnvironmentMetrics_current_tag 6 -#define meshtastic_EnvironmentMetrics_iaq_tag 7 +#define meshtastic_EnvironmentMetrics_iaq_tag 7 #define meshtastic_EnvironmentMetrics_distance_tag 8 -#define meshtastic_EnvironmentMetrics_lux_tag 9 +#define meshtastic_EnvironmentMetrics_lux_tag 9 #define meshtastic_EnvironmentMetrics_white_lux_tag 10 #define meshtastic_EnvironmentMetrics_ir_lux_tag 11 #define meshtastic_EnvironmentMetrics_uv_lux_tag 12 @@ -501,22 +556,22 @@ extern "C" { #define meshtastic_EnvironmentMetrics_rainfall_24h_tag 20 #define meshtastic_EnvironmentMetrics_soil_moisture_tag 21 #define meshtastic_EnvironmentMetrics_soil_temperature_tag 22 -#define meshtastic_PowerMetrics_ch1_voltage_tag 1 -#define meshtastic_PowerMetrics_ch1_current_tag 2 -#define meshtastic_PowerMetrics_ch2_voltage_tag 3 -#define meshtastic_PowerMetrics_ch2_current_tag 4 -#define meshtastic_PowerMetrics_ch3_voltage_tag 5 -#define meshtastic_PowerMetrics_ch3_current_tag 6 -#define meshtastic_PowerMetrics_ch4_voltage_tag 7 -#define meshtastic_PowerMetrics_ch4_current_tag 8 -#define meshtastic_PowerMetrics_ch5_voltage_tag 9 -#define meshtastic_PowerMetrics_ch5_current_tag 10 -#define meshtastic_PowerMetrics_ch6_voltage_tag 11 -#define meshtastic_PowerMetrics_ch6_current_tag 12 -#define meshtastic_PowerMetrics_ch7_voltage_tag 13 -#define meshtastic_PowerMetrics_ch7_current_tag 14 -#define meshtastic_PowerMetrics_ch8_voltage_tag 15 -#define meshtastic_PowerMetrics_ch8_current_tag 16 +#define meshtastic_PowerMetrics_ch1_voltage_tag 1 +#define meshtastic_PowerMetrics_ch1_current_tag 2 +#define meshtastic_PowerMetrics_ch2_voltage_tag 3 +#define meshtastic_PowerMetrics_ch2_current_tag 4 +#define meshtastic_PowerMetrics_ch3_voltage_tag 5 +#define meshtastic_PowerMetrics_ch3_current_tag 6 +#define meshtastic_PowerMetrics_ch4_voltage_tag 7 +#define meshtastic_PowerMetrics_ch4_current_tag 8 +#define meshtastic_PowerMetrics_ch5_voltage_tag 9 +#define meshtastic_PowerMetrics_ch5_current_tag 10 +#define meshtastic_PowerMetrics_ch6_voltage_tag 11 +#define meshtastic_PowerMetrics_ch6_current_tag 12 +#define meshtastic_PowerMetrics_ch7_voltage_tag 13 +#define meshtastic_PowerMetrics_ch7_current_tag 14 +#define meshtastic_PowerMetrics_ch8_voltage_tag 15 +#define meshtastic_PowerMetrics_ch8_current_tag 16 #define meshtastic_AirQualityMetrics_pm10_standard_tag 1 #define meshtastic_AirQualityMetrics_pm25_standard_tag 2 #define meshtastic_AirQualityMetrics_pm100_standard_tag 3 @@ -529,7 +584,7 @@ extern "C" { #define meshtastic_AirQualityMetrics_particles_25um_tag 10 #define meshtastic_AirQualityMetrics_particles_50um_tag 11 #define meshtastic_AirQualityMetrics_particles_100um_tag 12 -#define meshtastic_AirQualityMetrics_co2_tag 13 +#define meshtastic_AirQualityMetrics_co2_tag 13 #define meshtastic_AirQualityMetrics_co2_temperature_tag 14 #define meshtastic_AirQualityMetrics_co2_humidity_tag 15 #define meshtastic_AirQualityMetrics_form_formaldehyde_tag 16 @@ -544,173 +599,173 @@ extern "C" { #define meshtastic_AirQualityMetrics_particles_tps_tag 25 #define meshtastic_LocalStats_uptime_seconds_tag 1 #define meshtastic_LocalStats_channel_utilization_tag 2 -#define meshtastic_LocalStats_air_util_tx_tag 3 +#define meshtastic_LocalStats_air_util_tx_tag 3 #define meshtastic_LocalStats_num_packets_tx_tag 4 #define meshtastic_LocalStats_num_packets_rx_tag 5 #define meshtastic_LocalStats_num_packets_rx_bad_tag 6 #define meshtastic_LocalStats_num_online_nodes_tag 7 #define meshtastic_LocalStats_num_total_nodes_tag 8 -#define meshtastic_LocalStats_num_rx_dupe_tag 9 -#define meshtastic_LocalStats_num_tx_relay_tag 10 +#define meshtastic_LocalStats_num_rx_dupe_tag 9 +#define meshtastic_LocalStats_num_tx_relay_tag 10 #define meshtastic_LocalStats_num_tx_relay_canceled_tag 11 #define meshtastic_LocalStats_heap_total_bytes_tag 12 #define meshtastic_LocalStats_heap_free_bytes_tag 13 #define meshtastic_LocalStats_num_tx_dropped_tag 14 -#define meshtastic_HealthMetrics_heart_bpm_tag 1 -#define meshtastic_HealthMetrics_spO2_tag 2 +#define meshtastic_HealthMetrics_heart_bpm_tag 1 +#define meshtastic_HealthMetrics_spO2_tag 2 #define meshtastic_HealthMetrics_temperature_tag 3 #define meshtastic_HostMetrics_uptime_seconds_tag 1 #define meshtastic_HostMetrics_freemem_bytes_tag 2 #define meshtastic_HostMetrics_diskfree1_bytes_tag 3 #define meshtastic_HostMetrics_diskfree2_bytes_tag 4 #define meshtastic_HostMetrics_diskfree3_bytes_tag 5 -#define meshtastic_HostMetrics_load1_tag 6 -#define meshtastic_HostMetrics_load5_tag 7 -#define meshtastic_HostMetrics_load15_tag 8 -#define meshtastic_HostMetrics_user_string_tag 9 -#define meshtastic_Telemetry_time_tag 1 -#define meshtastic_Telemetry_device_metrics_tag 2 +#define meshtastic_HostMetrics_load1_tag 6 +#define meshtastic_HostMetrics_load5_tag 7 +#define meshtastic_HostMetrics_load15_tag 8 +#define meshtastic_HostMetrics_user_string_tag 9 +#define meshtastic_Telemetry_time_tag 1 +#define meshtastic_Telemetry_device_metrics_tag 2 #define meshtastic_Telemetry_environment_metrics_tag 3 #define meshtastic_Telemetry_air_quality_metrics_tag 4 -#define meshtastic_Telemetry_power_metrics_tag 5 -#define meshtastic_Telemetry_local_stats_tag 6 -#define meshtastic_Telemetry_health_metrics_tag 7 -#define meshtastic_Telemetry_host_metrics_tag 8 -#define meshtastic_Nau7802Config_zeroOffset_tag 1 +#define meshtastic_Telemetry_power_metrics_tag 5 +#define meshtastic_Telemetry_local_stats_tag 6 +#define meshtastic_Telemetry_health_metrics_tag 7 +#define meshtastic_Telemetry_host_metrics_tag 8 +#define meshtastic_Nau7802Config_zeroOffset_tag 1 #define meshtastic_Nau7802Config_calibrationFactor_tag 2 /* Struct field encoding specification for nanopb */ -#define meshtastic_DeviceMetrics_FIELDLIST(X, a) \ -X(a, STATIC, OPTIONAL, UINT32, battery_level, 1) \ -X(a, STATIC, OPTIONAL, FLOAT, voltage, 2) \ -X(a, STATIC, OPTIONAL, FLOAT, channel_utilization, 3) \ -X(a, STATIC, OPTIONAL, FLOAT, air_util_tx, 4) \ -X(a, STATIC, OPTIONAL, UINT32, uptime_seconds, 5) +#define meshtastic_DeviceMetrics_FIELDLIST(X, a) \ + X(a, STATIC, OPTIONAL, UINT32, battery_level, 1) \ + X(a, STATIC, OPTIONAL, FLOAT, voltage, 2) \ + X(a, STATIC, OPTIONAL, FLOAT, channel_utilization, 3) \ + X(a, STATIC, OPTIONAL, FLOAT, air_util_tx, 4) \ + X(a, STATIC, OPTIONAL, UINT32, uptime_seconds, 5) #define meshtastic_DeviceMetrics_CALLBACK NULL #define meshtastic_DeviceMetrics_DEFAULT NULL -#define meshtastic_EnvironmentMetrics_FIELDLIST(X, a) \ -X(a, STATIC, OPTIONAL, FLOAT, temperature, 1) \ -X(a, STATIC, OPTIONAL, FLOAT, relative_humidity, 2) \ -X(a, STATIC, OPTIONAL, FLOAT, barometric_pressure, 3) \ -X(a, STATIC, OPTIONAL, FLOAT, gas_resistance, 4) \ -X(a, STATIC, OPTIONAL, FLOAT, voltage, 5) \ -X(a, STATIC, OPTIONAL, FLOAT, current, 6) \ -X(a, STATIC, OPTIONAL, UINT32, iaq, 7) \ -X(a, STATIC, OPTIONAL, FLOAT, distance, 8) \ -X(a, STATIC, OPTIONAL, FLOAT, lux, 9) \ -X(a, STATIC, OPTIONAL, FLOAT, white_lux, 10) \ -X(a, STATIC, OPTIONAL, FLOAT, ir_lux, 11) \ -X(a, STATIC, OPTIONAL, FLOAT, uv_lux, 12) \ -X(a, STATIC, OPTIONAL, UINT32, wind_direction, 13) \ -X(a, STATIC, OPTIONAL, FLOAT, wind_speed, 14) \ -X(a, STATIC, OPTIONAL, FLOAT, weight, 15) \ -X(a, STATIC, OPTIONAL, FLOAT, wind_gust, 16) \ -X(a, STATIC, OPTIONAL, FLOAT, wind_lull, 17) \ -X(a, STATIC, OPTIONAL, FLOAT, radiation, 18) \ -X(a, STATIC, OPTIONAL, FLOAT, rainfall_1h, 19) \ -X(a, STATIC, OPTIONAL, FLOAT, rainfall_24h, 20) \ -X(a, STATIC, OPTIONAL, UINT32, soil_moisture, 21) \ -X(a, STATIC, OPTIONAL, FLOAT, soil_temperature, 22) +#define meshtastic_EnvironmentMetrics_FIELDLIST(X, a) \ + X(a, STATIC, OPTIONAL, FLOAT, temperature, 1) \ + X(a, STATIC, OPTIONAL, FLOAT, relative_humidity, 2) \ + X(a, STATIC, OPTIONAL, FLOAT, barometric_pressure, 3) \ + X(a, STATIC, OPTIONAL, FLOAT, gas_resistance, 4) \ + X(a, STATIC, OPTIONAL, FLOAT, voltage, 5) \ + X(a, STATIC, OPTIONAL, FLOAT, current, 6) \ + X(a, STATIC, OPTIONAL, UINT32, iaq, 7) \ + X(a, STATIC, OPTIONAL, FLOAT, distance, 8) \ + X(a, STATIC, OPTIONAL, FLOAT, lux, 9) \ + X(a, STATIC, OPTIONAL, FLOAT, white_lux, 10) \ + X(a, STATIC, OPTIONAL, FLOAT, ir_lux, 11) \ + X(a, STATIC, OPTIONAL, FLOAT, uv_lux, 12) \ + X(a, STATIC, OPTIONAL, UINT32, wind_direction, 13) \ + X(a, STATIC, OPTIONAL, FLOAT, wind_speed, 14) \ + X(a, STATIC, OPTIONAL, FLOAT, weight, 15) \ + X(a, STATIC, OPTIONAL, FLOAT, wind_gust, 16) \ + X(a, STATIC, OPTIONAL, FLOAT, wind_lull, 17) \ + X(a, STATIC, OPTIONAL, FLOAT, radiation, 18) \ + X(a, STATIC, OPTIONAL, FLOAT, rainfall_1h, 19) \ + X(a, STATIC, OPTIONAL, FLOAT, rainfall_24h, 20) \ + X(a, STATIC, OPTIONAL, UINT32, soil_moisture, 21) \ + X(a, STATIC, OPTIONAL, FLOAT, soil_temperature, 22) #define meshtastic_EnvironmentMetrics_CALLBACK NULL #define meshtastic_EnvironmentMetrics_DEFAULT NULL -#define meshtastic_PowerMetrics_FIELDLIST(X, a) \ -X(a, STATIC, OPTIONAL, FLOAT, ch1_voltage, 1) \ -X(a, STATIC, OPTIONAL, FLOAT, ch1_current, 2) \ -X(a, STATIC, OPTIONAL, FLOAT, ch2_voltage, 3) \ -X(a, STATIC, OPTIONAL, FLOAT, ch2_current, 4) \ -X(a, STATIC, OPTIONAL, FLOAT, ch3_voltage, 5) \ -X(a, STATIC, OPTIONAL, FLOAT, ch3_current, 6) \ -X(a, STATIC, OPTIONAL, FLOAT, ch4_voltage, 7) \ -X(a, STATIC, OPTIONAL, FLOAT, ch4_current, 8) \ -X(a, STATIC, OPTIONAL, FLOAT, ch5_voltage, 9) \ -X(a, STATIC, OPTIONAL, FLOAT, ch5_current, 10) \ -X(a, STATIC, OPTIONAL, FLOAT, ch6_voltage, 11) \ -X(a, STATIC, OPTIONAL, FLOAT, ch6_current, 12) \ -X(a, STATIC, OPTIONAL, FLOAT, ch7_voltage, 13) \ -X(a, STATIC, OPTIONAL, FLOAT, ch7_current, 14) \ -X(a, STATIC, OPTIONAL, FLOAT, ch8_voltage, 15) \ -X(a, STATIC, OPTIONAL, FLOAT, ch8_current, 16) +#define meshtastic_PowerMetrics_FIELDLIST(X, a) \ + X(a, STATIC, OPTIONAL, FLOAT, ch1_voltage, 1) \ + X(a, STATIC, OPTIONAL, FLOAT, ch1_current, 2) \ + X(a, STATIC, OPTIONAL, FLOAT, ch2_voltage, 3) \ + X(a, STATIC, OPTIONAL, FLOAT, ch2_current, 4) \ + X(a, STATIC, OPTIONAL, FLOAT, ch3_voltage, 5) \ + X(a, STATIC, OPTIONAL, FLOAT, ch3_current, 6) \ + X(a, STATIC, OPTIONAL, FLOAT, ch4_voltage, 7) \ + X(a, STATIC, OPTIONAL, FLOAT, ch4_current, 8) \ + X(a, STATIC, OPTIONAL, FLOAT, ch5_voltage, 9) \ + X(a, STATIC, OPTIONAL, FLOAT, ch5_current, 10) \ + X(a, STATIC, OPTIONAL, FLOAT, ch6_voltage, 11) \ + X(a, STATIC, OPTIONAL, FLOAT, ch6_current, 12) \ + X(a, STATIC, OPTIONAL, FLOAT, ch7_voltage, 13) \ + X(a, STATIC, OPTIONAL, FLOAT, ch7_current, 14) \ + X(a, STATIC, OPTIONAL, FLOAT, ch8_voltage, 15) \ + X(a, STATIC, OPTIONAL, FLOAT, ch8_current, 16) #define meshtastic_PowerMetrics_CALLBACK NULL #define meshtastic_PowerMetrics_DEFAULT NULL -#define meshtastic_AirQualityMetrics_FIELDLIST(X, a) \ -X(a, STATIC, OPTIONAL, UINT32, pm10_standard, 1) \ -X(a, STATIC, OPTIONAL, UINT32, pm25_standard, 2) \ -X(a, STATIC, OPTIONAL, UINT32, pm100_standard, 3) \ -X(a, STATIC, OPTIONAL, UINT32, pm10_environmental, 4) \ -X(a, STATIC, OPTIONAL, UINT32, pm25_environmental, 5) \ -X(a, STATIC, OPTIONAL, UINT32, pm100_environmental, 6) \ -X(a, STATIC, OPTIONAL, UINT32, particles_03um, 7) \ -X(a, STATIC, OPTIONAL, UINT32, particles_05um, 8) \ -X(a, STATIC, OPTIONAL, UINT32, particles_10um, 9) \ -X(a, STATIC, OPTIONAL, UINT32, particles_25um, 10) \ -X(a, STATIC, OPTIONAL, UINT32, particles_50um, 11) \ -X(a, STATIC, OPTIONAL, UINT32, particles_100um, 12) \ -X(a, STATIC, OPTIONAL, UINT32, co2, 13) \ -X(a, STATIC, OPTIONAL, FLOAT, co2_temperature, 14) \ -X(a, STATIC, OPTIONAL, FLOAT, co2_humidity, 15) \ -X(a, STATIC, OPTIONAL, FLOAT, form_formaldehyde, 16) \ -X(a, STATIC, OPTIONAL, FLOAT, form_humidity, 17) \ -X(a, STATIC, OPTIONAL, FLOAT, form_temperature, 18) \ -X(a, STATIC, OPTIONAL, UINT32, pm40_standard, 19) \ -X(a, STATIC, OPTIONAL, UINT32, particles_40um, 20) \ -X(a, STATIC, OPTIONAL, FLOAT, pm_temperature, 21) \ -X(a, STATIC, OPTIONAL, FLOAT, pm_humidity, 22) \ -X(a, STATIC, OPTIONAL, FLOAT, pm_voc_idx, 23) \ -X(a, STATIC, OPTIONAL, FLOAT, pm_nox_idx, 24) \ -X(a, STATIC, OPTIONAL, FLOAT, particles_tps, 25) +#define meshtastic_AirQualityMetrics_FIELDLIST(X, a) \ + X(a, STATIC, OPTIONAL, UINT32, pm10_standard, 1) \ + X(a, STATIC, OPTIONAL, UINT32, pm25_standard, 2) \ + X(a, STATIC, OPTIONAL, UINT32, pm100_standard, 3) \ + X(a, STATIC, OPTIONAL, UINT32, pm10_environmental, 4) \ + X(a, STATIC, OPTIONAL, UINT32, pm25_environmental, 5) \ + X(a, STATIC, OPTIONAL, UINT32, pm100_environmental, 6) \ + X(a, STATIC, OPTIONAL, UINT32, particles_03um, 7) \ + X(a, STATIC, OPTIONAL, UINT32, particles_05um, 8) \ + X(a, STATIC, OPTIONAL, UINT32, particles_10um, 9) \ + X(a, STATIC, OPTIONAL, UINT32, particles_25um, 10) \ + X(a, STATIC, OPTIONAL, UINT32, particles_50um, 11) \ + X(a, STATIC, OPTIONAL, UINT32, particles_100um, 12) \ + X(a, STATIC, OPTIONAL, UINT32, co2, 13) \ + X(a, STATIC, OPTIONAL, FLOAT, co2_temperature, 14) \ + X(a, STATIC, OPTIONAL, FLOAT, co2_humidity, 15) \ + X(a, STATIC, OPTIONAL, FLOAT, form_formaldehyde, 16) \ + X(a, STATIC, OPTIONAL, FLOAT, form_humidity, 17) \ + X(a, STATIC, OPTIONAL, FLOAT, form_temperature, 18) \ + X(a, STATIC, OPTIONAL, UINT32, pm40_standard, 19) \ + X(a, STATIC, OPTIONAL, UINT32, particles_40um, 20) \ + X(a, STATIC, OPTIONAL, FLOAT, pm_temperature, 21) \ + X(a, STATIC, OPTIONAL, FLOAT, pm_humidity, 22) \ + X(a, STATIC, OPTIONAL, FLOAT, pm_voc_idx, 23) \ + X(a, STATIC, OPTIONAL, FLOAT, pm_nox_idx, 24) \ + X(a, STATIC, OPTIONAL, FLOAT, particles_tps, 25) #define meshtastic_AirQualityMetrics_CALLBACK NULL #define meshtastic_AirQualityMetrics_DEFAULT NULL -#define meshtastic_LocalStats_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, uptime_seconds, 1) \ -X(a, STATIC, SINGULAR, FLOAT, channel_utilization, 2) \ -X(a, STATIC, SINGULAR, FLOAT, air_util_tx, 3) \ -X(a, STATIC, SINGULAR, UINT32, num_packets_tx, 4) \ -X(a, STATIC, SINGULAR, UINT32, num_packets_rx, 5) \ -X(a, STATIC, SINGULAR, UINT32, num_packets_rx_bad, 6) \ -X(a, STATIC, SINGULAR, UINT32, num_online_nodes, 7) \ -X(a, STATIC, SINGULAR, UINT32, num_total_nodes, 8) \ -X(a, STATIC, SINGULAR, UINT32, num_rx_dupe, 9) \ -X(a, STATIC, SINGULAR, UINT32, num_tx_relay, 10) \ -X(a, STATIC, SINGULAR, UINT32, num_tx_relay_canceled, 11) \ -X(a, STATIC, SINGULAR, UINT32, heap_total_bytes, 12) \ -X(a, STATIC, SINGULAR, UINT32, heap_free_bytes, 13) \ -X(a, STATIC, SINGULAR, UINT32, num_tx_dropped, 14) +#define meshtastic_LocalStats_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UINT32, uptime_seconds, 1) \ + X(a, STATIC, SINGULAR, FLOAT, channel_utilization, 2) \ + X(a, STATIC, SINGULAR, FLOAT, air_util_tx, 3) \ + X(a, STATIC, SINGULAR, UINT32, num_packets_tx, 4) \ + X(a, STATIC, SINGULAR, UINT32, num_packets_rx, 5) \ + X(a, STATIC, SINGULAR, UINT32, num_packets_rx_bad, 6) \ + X(a, STATIC, SINGULAR, UINT32, num_online_nodes, 7) \ + X(a, STATIC, SINGULAR, UINT32, num_total_nodes, 8) \ + X(a, STATIC, SINGULAR, UINT32, num_rx_dupe, 9) \ + X(a, STATIC, SINGULAR, UINT32, num_tx_relay, 10) \ + X(a, STATIC, SINGULAR, UINT32, num_tx_relay_canceled, 11) \ + X(a, STATIC, SINGULAR, UINT32, heap_total_bytes, 12) \ + X(a, STATIC, SINGULAR, UINT32, heap_free_bytes, 13) \ + X(a, STATIC, SINGULAR, UINT32, num_tx_dropped, 14) #define meshtastic_LocalStats_CALLBACK NULL #define meshtastic_LocalStats_DEFAULT NULL #define meshtastic_HealthMetrics_FIELDLIST(X, a) \ -X(a, STATIC, OPTIONAL, UINT32, heart_bpm, 1) \ -X(a, STATIC, OPTIONAL, UINT32, spO2, 2) \ -X(a, STATIC, OPTIONAL, FLOAT, temperature, 3) + X(a, STATIC, OPTIONAL, UINT32, heart_bpm, 1) \ + X(a, STATIC, OPTIONAL, UINT32, spO2, 2) \ + X(a, STATIC, OPTIONAL, FLOAT, temperature, 3) #define meshtastic_HealthMetrics_CALLBACK NULL #define meshtastic_HealthMetrics_DEFAULT NULL -#define meshtastic_HostMetrics_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, uptime_seconds, 1) \ -X(a, STATIC, SINGULAR, UINT64, freemem_bytes, 2) \ -X(a, STATIC, SINGULAR, UINT64, diskfree1_bytes, 3) \ -X(a, STATIC, OPTIONAL, UINT64, diskfree2_bytes, 4) \ -X(a, STATIC, OPTIONAL, UINT64, diskfree3_bytes, 5) \ -X(a, STATIC, SINGULAR, UINT32, load1, 6) \ -X(a, STATIC, SINGULAR, UINT32, load5, 7) \ -X(a, STATIC, SINGULAR, UINT32, load15, 8) \ -X(a, STATIC, OPTIONAL, STRING, user_string, 9) +#define meshtastic_HostMetrics_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UINT32, uptime_seconds, 1) \ + X(a, STATIC, SINGULAR, UINT64, freemem_bytes, 2) \ + X(a, STATIC, SINGULAR, UINT64, diskfree1_bytes, 3) \ + X(a, STATIC, OPTIONAL, UINT64, diskfree2_bytes, 4) \ + X(a, STATIC, OPTIONAL, UINT64, diskfree3_bytes, 5) \ + X(a, STATIC, SINGULAR, UINT32, load1, 6) \ + X(a, STATIC, SINGULAR, UINT32, load5, 7) \ + X(a, STATIC, SINGULAR, UINT32, load15, 8) \ + X(a, STATIC, OPTIONAL, STRING, user_string, 9) #define meshtastic_HostMetrics_CALLBACK NULL #define meshtastic_HostMetrics_DEFAULT NULL -#define meshtastic_Telemetry_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, FIXED32, time, 1) \ -X(a, STATIC, ONEOF, MESSAGE, (variant,device_metrics,variant.device_metrics), 2) \ -X(a, STATIC, ONEOF, MESSAGE, (variant,environment_metrics,variant.environment_metrics), 3) \ -X(a, STATIC, ONEOF, MESSAGE, (variant,air_quality_metrics,variant.air_quality_metrics), 4) \ -X(a, STATIC, ONEOF, MESSAGE, (variant,power_metrics,variant.power_metrics), 5) \ -X(a, STATIC, ONEOF, MESSAGE, (variant,local_stats,variant.local_stats), 6) \ -X(a, STATIC, ONEOF, MESSAGE, (variant,health_metrics,variant.health_metrics), 7) \ -X(a, STATIC, ONEOF, MESSAGE, (variant,host_metrics,variant.host_metrics), 8) +#define meshtastic_Telemetry_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, FIXED32, time, 1) \ + X(a, STATIC, ONEOF, MESSAGE, (variant, device_metrics, variant.device_metrics), 2) \ + X(a, STATIC, ONEOF, MESSAGE, (variant, environment_metrics, variant.environment_metrics), 3) \ + X(a, STATIC, ONEOF, MESSAGE, (variant, air_quality_metrics, variant.air_quality_metrics), 4) \ + X(a, STATIC, ONEOF, MESSAGE, (variant, power_metrics, variant.power_metrics), 5) \ + X(a, STATIC, ONEOF, MESSAGE, (variant, local_stats, variant.local_stats), 6) \ + X(a, STATIC, ONEOF, MESSAGE, (variant, health_metrics, variant.health_metrics), 7) \ + X(a, STATIC, ONEOF, MESSAGE, (variant, host_metrics, variant.host_metrics), 8) #define meshtastic_Telemetry_CALLBACK NULL #define meshtastic_Telemetry_DEFAULT NULL #define meshtastic_Telemetry_variant_device_metrics_MSGTYPE meshtastic_DeviceMetrics @@ -722,20 +777,20 @@ X(a, STATIC, ONEOF, MESSAGE, (variant,host_metrics,variant.host_metrics), #define meshtastic_Telemetry_variant_host_metrics_MSGTYPE meshtastic_HostMetrics #define meshtastic_Nau7802Config_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, INT32, zeroOffset, 1) \ -X(a, STATIC, SINGULAR, FLOAT, calibrationFactor, 2) + X(a, STATIC, SINGULAR, INT32, zeroOffset, 1) \ + X(a, STATIC, SINGULAR, FLOAT, calibrationFactor, 2) #define meshtastic_Nau7802Config_CALLBACK NULL #define meshtastic_Nau7802Config_DEFAULT NULL -extern const pb_msgdesc_t meshtastic_DeviceMetrics_msg; -extern const pb_msgdesc_t meshtastic_EnvironmentMetrics_msg; -extern const pb_msgdesc_t meshtastic_PowerMetrics_msg; -extern const pb_msgdesc_t meshtastic_AirQualityMetrics_msg; -extern const pb_msgdesc_t meshtastic_LocalStats_msg; -extern const pb_msgdesc_t meshtastic_HealthMetrics_msg; -extern const pb_msgdesc_t meshtastic_HostMetrics_msg; -extern const pb_msgdesc_t meshtastic_Telemetry_msg; -extern const pb_msgdesc_t meshtastic_Nau7802Config_msg; + extern const pb_msgdesc_t meshtastic_DeviceMetrics_msg; + extern const pb_msgdesc_t meshtastic_EnvironmentMetrics_msg; + extern const pb_msgdesc_t meshtastic_PowerMetrics_msg; + extern const pb_msgdesc_t meshtastic_AirQualityMetrics_msg; + extern const pb_msgdesc_t meshtastic_LocalStats_msg; + extern const pb_msgdesc_t meshtastic_HealthMetrics_msg; + extern const pb_msgdesc_t meshtastic_HostMetrics_msg; + extern const pb_msgdesc_t meshtastic_Telemetry_msg; + extern const pb_msgdesc_t meshtastic_Nau7802Config_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_DeviceMetrics_fields &meshtastic_DeviceMetrics_msg @@ -750,15 +805,15 @@ extern const pb_msgdesc_t meshtastic_Nau7802Config_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_TELEMETRY_PB_H_MAX_SIZE meshtastic_Telemetry_size -#define meshtastic_AirQualityMetrics_size 150 -#define meshtastic_DeviceMetrics_size 27 -#define meshtastic_EnvironmentMetrics_size 113 -#define meshtastic_HealthMetrics_size 11 -#define meshtastic_HostMetrics_size 264 -#define meshtastic_LocalStats_size 76 -#define meshtastic_Nau7802Config_size 16 -#define meshtastic_PowerMetrics_size 81 -#define meshtastic_Telemetry_size 272 +#define meshtastic_AirQualityMetrics_size 150 +#define meshtastic_DeviceMetrics_size 27 +#define meshtastic_EnvironmentMetrics_size 113 +#define meshtastic_HealthMetrics_size 11 +#define meshtastic_HostMetrics_size 264 +#define meshtastic_LocalStats_size 76 +#define meshtastic_Nau7802Config_size 16 +#define meshtastic_PowerMetrics_size 81 +#define meshtastic_Telemetry_size 272 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/meshtastic/xmodem.pb.cpp b/src/chat/infra/meshtastic/generated/meshtastic/xmodem.pb.cpp index 09ae41d3..7ae27214 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/xmodem.pb.cpp +++ b/src/chat/infra/meshtastic/generated/meshtastic/xmodem.pb.cpp @@ -7,8 +7,3 @@ #endif PB_BIND(meshtastic_XModem, meshtastic_XModem, AUTO) - - - - - diff --git a/src/chat/infra/meshtastic/generated/meshtastic/xmodem.pb.h b/src/chat/infra/meshtastic/generated/meshtastic/xmodem.pb.h index 3410fda0..7dfaec48 100644 --- a/src/chat/infra/meshtastic/generated/meshtastic/xmodem.pb.h +++ b/src/chat/infra/meshtastic/generated/meshtastic/xmodem.pb.h @@ -10,7 +10,8 @@ #endif /* Enum definitions */ -typedef enum _meshtastic_XModem_Control { +typedef enum _meshtastic_XModem_Control +{ meshtastic_XModem_Control_NUL = 0, meshtastic_XModem_Control_SOH = 1, meshtastic_XModem_Control_STX = 2, @@ -23,53 +24,65 @@ typedef enum _meshtastic_XModem_Control { /* Struct definitions */ typedef PB_BYTES_ARRAY_T(128) meshtastic_XModem_buffer_t; -typedef struct _meshtastic_XModem { +typedef struct _meshtastic_XModem +{ meshtastic_XModem_Control control; uint16_t seq; uint16_t crc16; meshtastic_XModem_buffer_t buffer; } meshtastic_XModem; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Helper constants for enums */ #define _meshtastic_XModem_Control_MIN meshtastic_XModem_Control_NUL #define _meshtastic_XModem_Control_MAX meshtastic_XModem_Control_CTRLZ -#define _meshtastic_XModem_Control_ARRAYSIZE ((meshtastic_XModem_Control)(meshtastic_XModem_Control_CTRLZ+1)) +#define _meshtastic_XModem_Control_ARRAYSIZE ((meshtastic_XModem_Control)(meshtastic_XModem_Control_CTRLZ + 1)) #define meshtastic_XModem_control_ENUMTYPE meshtastic_XModem_Control - /* Initializer values for message structs */ -#define meshtastic_XModem_init_default {_meshtastic_XModem_Control_MIN, 0, 0, {0, {0}}} -#define meshtastic_XModem_init_zero {_meshtastic_XModem_Control_MIN, 0, 0, {0, {0}}} +#define meshtastic_XModem_init_default \ + { \ + _meshtastic_XModem_Control_MIN, 0, 0, \ + { \ + 0, { 0 } \ + } \ + } +#define meshtastic_XModem_init_zero \ + { \ + _meshtastic_XModem_Control_MIN, 0, 0, \ + { \ + 0, { 0 } \ + } \ + } /* Field tags (for use in manual encoding/decoding) */ -#define meshtastic_XModem_control_tag 1 -#define meshtastic_XModem_seq_tag 2 -#define meshtastic_XModem_crc16_tag 3 -#define meshtastic_XModem_buffer_tag 4 +#define meshtastic_XModem_control_tag 1 +#define meshtastic_XModem_seq_tag 2 +#define meshtastic_XModem_crc16_tag 3 +#define meshtastic_XModem_buffer_tag 4 /* Struct field encoding specification for nanopb */ -#define meshtastic_XModem_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UENUM, control, 1) \ -X(a, STATIC, SINGULAR, UINT32, seq, 2) \ -X(a, STATIC, SINGULAR, UINT32, crc16, 3) \ -X(a, STATIC, SINGULAR, BYTES, buffer, 4) +#define meshtastic_XModem_FIELDLIST(X, a) \ + X(a, STATIC, SINGULAR, UENUM, control, 1) \ + X(a, STATIC, SINGULAR, UINT32, seq, 2) \ + X(a, STATIC, SINGULAR, UINT32, crc16, 3) \ + X(a, STATIC, SINGULAR, BYTES, buffer, 4) #define meshtastic_XModem_CALLBACK NULL #define meshtastic_XModem_DEFAULT NULL -extern const pb_msgdesc_t meshtastic_XModem_msg; + extern const pb_msgdesc_t meshtastic_XModem_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_XModem_fields &meshtastic_XModem_msg /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_XMODEM_PB_H_MAX_SIZE meshtastic_XModem_size -#define meshtastic_XModem_size 141 +#define meshtastic_XModem_size 141 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/pb.h b/src/chat/infra/meshtastic/generated/pb.h index ecbf2f45..6b1ee81a 100644 --- a/src/chat/infra/meshtastic/generated/pb.h +++ b/src/chat/infra/meshtastic/generated/pb.h @@ -65,7 +65,6 @@ * Feel free to look around and use the defined macros, though. * ******************************************************************/ - /* Version of the nanopb library. Just in case you want to check it in * your own program. */ #define NANOPB_VERSION "nanopb-1.0.0-dev" @@ -84,11 +83,11 @@ #ifdef PB_SYSTEM_HEADER #include PB_SYSTEM_HEADER #else -#include -#include -#include -#include #include +#include +#include +#include +#include #ifdef PB_ENABLE_MALLOC #include @@ -96,7 +95,8 @@ #endif #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Macro for defining packed structures (compiler dependent). @@ -104,47 +104,47 @@ extern "C" { */ #if defined(PB_NO_PACKED_STRUCTS) /* Disable struct packing */ -# define PB_PACKED_STRUCT_START -# define PB_PACKED_STRUCT_END -# define pb_packed +#define PB_PACKED_STRUCT_START +#define PB_PACKED_STRUCT_END +#define pb_packed #elif defined(__GNUC__) || defined(__clang__) - /* For GCC and clang */ -# define PB_PACKED_STRUCT_START -# define PB_PACKED_STRUCT_END -# define pb_packed __attribute__((packed)) +/* For GCC and clang */ +#define PB_PACKED_STRUCT_START +#define PB_PACKED_STRUCT_END +#define pb_packed __attribute__((packed)) #elif defined(__ICCARM__) || defined(__CC_ARM) - /* For IAR ARM and Keil MDK-ARM compilers */ -# define PB_PACKED_STRUCT_START _Pragma("pack(push, 1)") -# define PB_PACKED_STRUCT_END _Pragma("pack(pop)") -# define pb_packed +/* For IAR ARM and Keil MDK-ARM compilers */ +#define PB_PACKED_STRUCT_START _Pragma("pack(push, 1)") +#define PB_PACKED_STRUCT_END _Pragma("pack(pop)") +#define pb_packed #elif defined(_MSC_VER) && (_MSC_VER >= 1500) - /* For Microsoft Visual C++ */ -# define PB_PACKED_STRUCT_START __pragma(pack(push, 1)) -# define PB_PACKED_STRUCT_END __pragma(pack(pop)) -# define pb_packed +/* For Microsoft Visual C++ */ +#define PB_PACKED_STRUCT_START __pragma(pack(push, 1)) +#define PB_PACKED_STRUCT_END __pragma(pack(pop)) +#define pb_packed #else - /* Unknown compiler */ -# define PB_PACKED_STRUCT_START -# define PB_PACKED_STRUCT_END -# define pb_packed +/* Unknown compiler */ +#define PB_PACKED_STRUCT_START +#define PB_PACKED_STRUCT_END +#define pb_packed #endif /* Define for explicitly not inlining a given function */ #ifndef pb_noinline #if defined(__GNUC__) || defined(__clang__) /* For GCC and clang */ -# if defined(noinline) -# define pb_noinline noinline -# else -# define pb_noinline __attribute__((noinline)) -# endif +#if defined(noinline) +#define pb_noinline noinline +#else +#define pb_noinline __attribute__((noinline)) +#endif #elif defined(__ICCARM__) || defined(__CC_ARM) /* For IAR ARM and Keil MDK-ARM compilers */ -# define pb_noinline +#define pb_noinline #elif defined(_MSC_VER) && (_MSC_VER >= 1500) -# define pb_noinline __declspec(noinline) +#define pb_noinline __declspec(noinline) #else -# define pb_noinline +#define pb_noinline #endif #endif @@ -154,12 +154,12 @@ extern "C" { #endif #ifndef PB_LITTLE_ENDIAN_8BIT -#if ((defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) || \ +#if ((defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) || \ (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \ - defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || \ - defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || \ - defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM)) \ - && defined(CHAR_BIT) && CHAR_BIT == 8 + defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || \ + defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || \ + defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM)) && \ + defined(CHAR_BIT) && CHAR_BIT == 8 #define PB_LITTLE_ENDIAN_8BIT 1 #endif #endif @@ -174,11 +174,11 @@ extern "C" { #ifndef PB_PROGMEM #ifdef __AVR__ #include -#define PB_PROGMEM PROGMEM -#define PB_PROGMEM_READU32(x) pgm_read_dword(&x) +#define PB_PROGMEM PROGMEM +#define PB_PROGMEM_READU32(x) pgm_read_dword(&x) #else #define PB_PROGMEM -#define PB_PROGMEM_READU32(x) (x) +#define PB_PROGMEM_READU32(x) (x) #endif #endif @@ -192,38 +192,38 @@ extern "C" { * in the place where the PB_STATIC_ASSERT macro was called. */ #ifndef PB_NO_STATIC_ASSERT -# ifndef PB_STATIC_ASSERT -# if defined(__ICCARM__) - /* IAR has static_assert keyword but no _Static_assert */ -# define PB_STATIC_ASSERT(COND,MSG) static_assert(COND,#MSG); -# elif defined(_MSC_VER) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112) - /* MSVC in C89 mode supports static_assert() keyword anyway */ -# define PB_STATIC_ASSERT(COND,MSG) static_assert(COND,#MSG); -# elif defined(PB_C99_STATIC_ASSERT) - /* Classic negative-size-array static assert mechanism */ -# define PB_STATIC_ASSERT(COND,MSG) typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1]; -# define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) -# define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) pb_static_assertion_##MSG##_##LINE##_##COUNTER -# elif defined(__cplusplus) - /* C++11 standard static_assert mechanism */ -# define PB_STATIC_ASSERT(COND,MSG) static_assert(COND,#MSG); -# else - /* C11 standard _Static_assert mechanism */ -# define PB_STATIC_ASSERT(COND,MSG) _Static_assert(COND,#MSG); -# endif -# endif +#ifndef PB_STATIC_ASSERT +#if defined(__ICCARM__) + /* IAR has static_assert keyword but no _Static_assert */ +#define PB_STATIC_ASSERT(COND, MSG) static_assert(COND, #MSG); +#elif defined(_MSC_VER) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112) + /* MSVC in C89 mode supports static_assert() keyword anyway */ +#define PB_STATIC_ASSERT(COND, MSG) static_assert(COND, #MSG); +#elif defined(PB_C99_STATIC_ASSERT) + /* Classic negative-size-array static assert mechanism */ +#define PB_STATIC_ASSERT(COND, MSG) typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND) ? 1 : -1]; +#define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) +#define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) pb_static_assertion_##MSG##_##LINE##_##COUNTER +#elif defined(__cplusplus) + /* C++11 standard static_assert mechanism */ +#define PB_STATIC_ASSERT(COND, MSG) static_assert(COND, #MSG); #else - /* Static asserts disabled by PB_NO_STATIC_ASSERT */ -# define PB_STATIC_ASSERT(COND,MSG) + /* C11 standard _Static_assert mechanism */ +#define PB_STATIC_ASSERT(COND, MSG) _Static_assert(COND, #MSG); +#endif +#endif +#else +/* Static asserts disabled by PB_NO_STATIC_ASSERT */ +#define PB_STATIC_ASSERT(COND, MSG) #endif -/* Test that PB_STATIC_ASSERT works - * If you get errors here, you may need to do one of these: - * - Enable C11 standard support in your compiler - * - Define PB_C99_STATIC_ASSERT to enable C99 standard support - * - Define PB_NO_STATIC_ASSERT to disable static asserts altogether - */ -PB_STATIC_ASSERT(1, STATIC_ASSERT_IS_NOT_WORKING) + /* Test that PB_STATIC_ASSERT works + * If you get errors here, you may need to do one of these: + * - Enable C11 standard support in your compiler + * - Define PB_C99_STATIC_ASSERT to enable C99 standard support + * - Define PB_NO_STATIC_ASSERT to disable static asserts altogether + */ + PB_STATIC_ASSERT(1, STATIC_ASSERT_IS_NOT_WORKING) /* Number of required fields to keep track of. */ #ifndef PB_MAX_REQUIRED_FIELDS @@ -246,24 +246,24 @@ PB_STATIC_ASSERT(1, STATIC_ASSERT_IS_NOT_WORKING) * You can regard it as equivalent on uint8_t on other platforms. */ #if defined(PB_BYTE_T_OVERRIDE) -typedef PB_BYTE_T_OVERRIDE pb_byte_t; + typedef PB_BYTE_T_OVERRIDE pb_byte_t; #elif defined(UINT8_MAX) typedef uint8_t pb_byte_t; #else typedef uint_least8_t pb_byte_t; #endif -/* List of possible field types. These are used in the autogenerated code. - * Least-significant 4 bits tell the scalar type - * Most-significant 4 bits specify repeated/required/packed etc. - */ -typedef pb_byte_t pb_type_t; + /* List of possible field types. These are used in the autogenerated code. + * Least-significant 4 bits tell the scalar type + * Most-significant 4 bits specify repeated/required/packed etc. + */ + typedef pb_byte_t pb_type_t; /**** Field data types ****/ /* Numeric types */ -#define PB_LTYPE_BOOL 0x00U /* bool */ -#define PB_LTYPE_VARINT 0x01U /* int32, int64, enum, bool */ +#define PB_LTYPE_BOOL 0x00U /* bool */ +#define PB_LTYPE_VARINT 0x01U /* int32, int64, enum, bool */ #define PB_LTYPE_UVARINT 0x02U /* uint32, uint64 */ #define PB_LTYPE_SVARINT 0x03U /* sint32, sint64 */ #define PB_LTYPE_FIXED32 0x04U /* fixed32, sfixed32, float */ @@ -303,26 +303,26 @@ typedef pb_byte_t pb_type_t; #define PB_LTYPES_COUNT 0x0CU #define PB_LTYPE_MASK 0x0FU -/**** Field repetition rules ****/ + /**** Field repetition rules ****/ #define PB_HTYPE_REQUIRED 0x00U #define PB_HTYPE_OPTIONAL 0x10U #define PB_HTYPE_SINGULAR 0x10U #define PB_HTYPE_REPEATED 0x20U #define PB_HTYPE_FIXARRAY 0x20U -#define PB_HTYPE_ONEOF 0x30U -#define PB_HTYPE_MASK 0x30U +#define PB_HTYPE_ONEOF 0x30U +#define PB_HTYPE_MASK 0x30U -/**** Field allocation types ****/ + /**** Field allocation types ****/ -#define PB_ATYPE_STATIC 0x00U -#define PB_ATYPE_POINTER 0x80U +#define PB_ATYPE_STATIC 0x00U +#define PB_ATYPE_POINTER 0x80U #define PB_ATYPE_CALLBACK 0x40U -#define PB_ATYPE_MASK 0xC0U +#define PB_ATYPE_MASK 0xC0U -#define PB_ATYPE(x) ((x) & PB_ATYPE_MASK) -#define PB_HTYPE(x) ((x) & PB_HTYPE_MASK) -#define PB_LTYPE(x) ((x) & PB_LTYPE_MASK) +#define PB_ATYPE(x) ((x)&PB_ATYPE_MASK) +#define PB_HTYPE(x) ((x)&PB_HTYPE_MASK) +#define PB_LTYPE(x) ((x)&PB_LTYPE_MASK) #define PB_LTYPE_IS_SUBMSG(x) (PB_LTYPE(x) == PB_LTYPE_SUBMESSAGE || \ PB_LTYPE(x) == PB_LTYPE_SUBMSG_W_CB) @@ -333,56 +333,58 @@ typedef pb_byte_t pb_type_t; typedef uint32_t pb_size_t; typedef int32_t pb_ssize_t; #else - typedef uint_least16_t pb_size_t; - typedef int_least16_t pb_ssize_t; +typedef uint_least16_t pb_size_t; +typedef int_least16_t pb_ssize_t; #endif #define PB_SIZE_MAX ((pb_size_t)-1) -/* Forward declaration of struct types */ -typedef struct pb_istream_s pb_istream_t; -typedef struct pb_ostream_s pb_ostream_t; -typedef struct pb_field_iter_s pb_field_iter_t; + /* Forward declaration of struct types */ + typedef struct pb_istream_s pb_istream_t; + typedef struct pb_ostream_s pb_ostream_t; + typedef struct pb_field_iter_s pb_field_iter_t; -/* This structure is used in auto-generated constants - * to specify struct fields. - */ -typedef struct pb_msgdesc_s pb_msgdesc_t; -struct pb_msgdesc_s { - const uint32_t *field_info; - const pb_msgdesc_t * const * submsg_info; - const pb_byte_t *default_value; + /* This structure is used in auto-generated constants + * to specify struct fields. + */ + typedef struct pb_msgdesc_s pb_msgdesc_t; + struct pb_msgdesc_s + { + const uint32_t* field_info; + const pb_msgdesc_t* const* submsg_info; + const pb_byte_t* default_value; - bool (*field_callback)(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field); + bool (*field_callback)(pb_istream_t* istream, pb_ostream_t* ostream, const pb_field_iter_t* field); - pb_size_t field_count; - pb_size_t required_field_count; - pb_size_t largest_tag; -}; + pb_size_t field_count; + pb_size_t required_field_count; + pb_size_t largest_tag; + }; -/* Iterator for message descriptor */ -struct pb_field_iter_s { - const pb_msgdesc_t *descriptor; /* Pointer to message descriptor constant */ - void *message; /* Pointer to start of the structure */ + /* Iterator for message descriptor */ + struct pb_field_iter_s + { + const pb_msgdesc_t* descriptor; /* Pointer to message descriptor constant */ + void* message; /* Pointer to start of the structure */ - pb_size_t index; /* Index of the field */ - pb_size_t field_info_index; /* Index to descriptor->field_info array */ - pb_size_t required_field_index; /* Index that counts only the required fields */ - pb_size_t submessage_index; /* Index that counts only submessages */ + pb_size_t index; /* Index of the field */ + pb_size_t field_info_index; /* Index to descriptor->field_info array */ + pb_size_t required_field_index; /* Index that counts only the required fields */ + pb_size_t submessage_index; /* Index that counts only submessages */ - pb_size_t tag; /* Tag of current field */ - pb_size_t data_size; /* sizeof() of a single item */ - pb_size_t array_size; /* Number of array entries */ - pb_type_t type; /* Type of current field */ + pb_size_t tag; /* Tag of current field */ + pb_size_t data_size; /* sizeof() of a single item */ + pb_size_t array_size; /* Number of array entries */ + pb_type_t type; /* Type of current field */ - void *pField; /* Pointer to current field in struct */ - void *pData; /* Pointer to current data contents. Different than pField for arrays and pointers. */ - void *pSize; /* Pointer to count/has field */ + void* pField; /* Pointer to current field in struct */ + void* pData; /* Pointer to current data contents. Different than pField for arrays and pointers. */ + void* pSize; /* Pointer to count/has field */ - const pb_msgdesc_t *submsg_desc; /* For submessage fields, pointer to field descriptor for the submessage. */ -}; + const pb_msgdesc_t* submsg_desc; /* For submessage fields, pointer to field descriptor for the submessage. */ + }; -/* For compatibility with legacy code */ -typedef pb_field_iter_t pb_field_t; + /* For compatibility with legacy code */ + typedef pb_field_iter_t pb_field_t; /* Make sure that the standard integer types are of the expected sizes. * Otherwise fixed32/fixed64 fields can break. @@ -391,126 +393,140 @@ typedef pb_field_iter_t pb_field_t; * correct for your platform. */ #ifndef PB_WITHOUT_64BIT -PB_STATIC_ASSERT(sizeof(int64_t) == 2 * sizeof(int32_t), INT64_T_WRONG_SIZE) -PB_STATIC_ASSERT(sizeof(uint64_t) == 2 * sizeof(uint32_t), UINT64_T_WRONG_SIZE) + PB_STATIC_ASSERT(sizeof(int64_t) == 2 * sizeof(int32_t), INT64_T_WRONG_SIZE) + PB_STATIC_ASSERT(sizeof(uint64_t) == 2 * sizeof(uint32_t), UINT64_T_WRONG_SIZE) #endif /* This structure is used for 'bytes' arrays. * It has the number of bytes in the beginning, and after that an array. * Note that actual structs used will have a different length of bytes array. */ -#define PB_BYTES_ARRAY_T(n) struct { pb_size_t size; pb_byte_t bytes[n]; } +#define PB_BYTES_ARRAY_T(n) \ + struct \ + { \ + pb_size_t size; \ + pb_byte_t bytes[n]; \ + } #define PB_BYTES_ARRAY_T_ALLOCSIZE(n) ((size_t)n + offsetof(pb_bytes_array_t, bytes)) -struct pb_bytes_array_s { - pb_size_t size; - pb_byte_t bytes[1]; -}; -typedef struct pb_bytes_array_s pb_bytes_array_t; + struct pb_bytes_array_s + { + pb_size_t size; + pb_byte_t bytes[1]; + }; + typedef struct pb_bytes_array_s pb_bytes_array_t; -/* This structure is used for giving the callback function. - * It is stored in the message structure and filled in by the method that - * calls pb_decode. - * - * The decoding callback will be given a limited-length stream - * If the wire type was string, the length is the length of the string. - * If the wire type was a varint/fixed32/fixed64, the length is the length - * of the actual value. - * The function may be called multiple times (especially for repeated types, - * but also otherwise if the message happens to contain the field multiple - * times.) - * - * The encoding callback will receive the actual output stream. - * It should write all the data in one call, including the field tag and - * wire type. It can write multiple fields. - * - * The callback can be null if you want to skip a field. - */ -typedef struct pb_callback_s pb_callback_t; -struct pb_callback_s { - /* Callback functions receive a pointer to the arg field. - * You can access the value of the field as *arg, and modify it if needed. + /* This structure is used for giving the callback function. + * It is stored in the message structure and filled in by the method that + * calls pb_decode. + * + * The decoding callback will be given a limited-length stream + * If the wire type was string, the length is the length of the string. + * If the wire type was a varint/fixed32/fixed64, the length is the length + * of the actual value. + * The function may be called multiple times (especially for repeated types, + * but also otherwise if the message happens to contain the field multiple + * times.) + * + * The encoding callback will receive the actual output stream. + * It should write all the data in one call, including the field tag and + * wire type. It can write multiple fields. + * + * The callback can be null if you want to skip a field. */ - union { - bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void **arg); - bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, void * const *arg); - } funcs; + typedef struct pb_callback_s pb_callback_t; + struct pb_callback_s + { + /* Callback functions receive a pointer to the arg field. + * You can access the value of the field as *arg, and modify it if needed. + */ + union + { + bool (*decode)(pb_istream_t* stream, const pb_field_t* field, void** arg); + bool (*encode)(pb_ostream_t* stream, const pb_field_t* field, void* const* arg); + } funcs; - /* Free arg for use by callback */ - void *arg; -}; + /* Free arg for use by callback */ + void* arg; + }; -extern bool pb_default_field_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_t *field); + extern bool pb_default_field_callback(pb_istream_t* istream, pb_ostream_t* ostream, const pb_field_t* field); -/* Wire types. Library user needs these only in encoder callbacks. */ -typedef enum { - PB_WT_VARINT = 0, - PB_WT_64BIT = 1, - PB_WT_STRING = 2, - PB_WT_32BIT = 5, - PB_WT_PACKED = 255 /* PB_WT_PACKED is internal marker for packed arrays. */ -} pb_wire_type_t; + /* Wire types. Library user needs these only in encoder callbacks. */ + typedef enum + { + PB_WT_VARINT = 0, + PB_WT_64BIT = 1, + PB_WT_STRING = 2, + PB_WT_32BIT = 5, + PB_WT_PACKED = 255 /* PB_WT_PACKED is internal marker for packed arrays. */ + } pb_wire_type_t; -/* Structure for defining the handling of unknown/extension fields. - * Usually the pb_extension_type_t structure is automatically generated, - * while the pb_extension_t structure is created by the user. However, - * if you want to catch all unknown fields, you can also create a custom - * pb_extension_type_t with your own callback. - */ -typedef struct pb_extension_type_s pb_extension_type_t; -typedef struct pb_extension_s pb_extension_t; -struct pb_extension_type_s { - /* Called for each unknown field in the message. - * If you handle the field, read off all of its data and return true. - * If you do not handle the field, do not read anything and return true. - * If you run into an error, return false. - * Set to NULL for default handler. + /* Structure for defining the handling of unknown/extension fields. + * Usually the pb_extension_type_t structure is automatically generated, + * while the pb_extension_t structure is created by the user. However, + * if you want to catch all unknown fields, you can also create a custom + * pb_extension_type_t with your own callback. */ - bool (*decode)(pb_istream_t *stream, pb_extension_t *extension, - uint32_t tag, pb_wire_type_t wire_type); + typedef struct pb_extension_type_s pb_extension_type_t; + typedef struct pb_extension_s pb_extension_t; + struct pb_extension_type_s + { + /* Called for each unknown field in the message. + * If you handle the field, read off all of its data and return true. + * If you do not handle the field, do not read anything and return true. + * If you run into an error, return false. + * Set to NULL for default handler. + */ + bool (*decode)(pb_istream_t* stream, pb_extension_t* extension, + uint32_t tag, pb_wire_type_t wire_type); - /* Called once after all regular fields have been encoded. - * If you have something to write, do so and return true. - * If you do not have anything to write, just return true. - * If you run into an error, return false. - * Set to NULL for default handler. - */ - bool (*encode)(pb_ostream_t *stream, const pb_extension_t *extension); + /* Called once after all regular fields have been encoded. + * If you have something to write, do so and return true. + * If you do not have anything to write, just return true. + * If you run into an error, return false. + * Set to NULL for default handler. + */ + bool (*encode)(pb_ostream_t* stream, const pb_extension_t* extension); - /* Free field for use by the callback. */ - const void *arg; -}; + /* Free field for use by the callback. */ + const void* arg; + }; -struct pb_extension_s { - /* Type describing the extension field. Usually you'll initialize - * this to a pointer to the automatically generated structure. */ - const pb_extension_type_t *type; + struct pb_extension_s + { + /* Type describing the extension field. Usually you'll initialize + * this to a pointer to the automatically generated structure. */ + const pb_extension_type_t* type; - /* Destination for the decoded data. This must match the datatype - * of the extension field. */ - void *dest; + /* Destination for the decoded data. This must match the datatype + * of the extension field. */ + void* dest; - /* Pointer to the next extension handler, or NULL. - * If this extension does not match a field, the next handler is - * automatically called. */ - pb_extension_t *next; + /* Pointer to the next extension handler, or NULL. + * If this extension does not match a field, the next handler is + * automatically called. */ + pb_extension_t* next; - /* The decoder sets this to true if the extension was found. - * Ignored for encoding. */ - bool found; -}; + /* The decoder sets this to true if the extension was found. + * Ignored for encoding. */ + bool found; + }; -#define pb_extension_init_zero {NULL,NULL,NULL,false} +#define pb_extension_init_zero \ + { \ + NULL, NULL, NULL, false \ + } /* Memory allocation functions to use. You can define pb_realloc and * pb_free to custom functions if you want. */ #ifdef PB_ENABLE_MALLOC -# ifndef pb_realloc -# define pb_realloc(ptr, size) realloc(ptr, size) -# endif -# ifndef pb_free -# define pb_free(ptr) free(ptr) -# endif +#ifndef pb_realloc +#define pb_realloc(ptr, size) realloc(ptr, size) +#endif +#ifndef pb_free +#define pb_free(ptr) free(ptr) +#endif #endif /* This is used to inform about need to regenerate .pb.h/.pb.c files. */ @@ -518,7 +534,7 @@ struct pb_extension_s { /* These macros are used to declare pb_field_t's in the constant array. */ /* Size of a structure member, in bytes. */ -#define pb_membersize(st, m) (sizeof ((st*)0)->m) +#define pb_membersize(st, m) (sizeof((st*)0)->m) /* Number of entries in an array. */ #define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0])) /* Delta from start of one member to the start of another member. */ @@ -528,126 +544,123 @@ struct pb_extension_s { #define PB_EXPAND(x) x /* Binding of a message field set into a specific structure */ -#define PB_BIND(msgname, structname, width) \ - const uint32_t structname ## _field_info[] PB_PROGMEM = \ - { \ - msgname ## _FIELDLIST(PB_GEN_FIELD_INFO_ ## width, structname) \ - 0 \ - }; \ - const pb_msgdesc_t* const structname ## _submsg_info[] = \ - { \ - msgname ## _FIELDLIST(PB_GEN_SUBMSG_INFO, structname) \ - NULL \ - }; \ - const pb_msgdesc_t structname ## _msg = \ - { \ - structname ## _field_info, \ - structname ## _submsg_info, \ - msgname ## _DEFAULT, \ - msgname ## _CALLBACK, \ - 0 msgname ## _FIELDLIST(PB_GEN_FIELD_COUNT, structname), \ - 0 msgname ## _FIELDLIST(PB_GEN_REQ_FIELD_COUNT, structname), \ - 0 msgname ## _FIELDLIST(PB_GEN_LARGEST_TAG, structname), \ - }; \ - msgname ## _FIELDLIST(PB_GEN_FIELD_INFO_ASSERT_ ## width, structname) +#define PB_BIND(msgname, structname, width) \ + const uint32_t structname##_field_info[] PB_PROGMEM = \ + { \ + msgname##_FIELDLIST(PB_GEN_FIELD_INFO_##width, structname) 0}; \ + const pb_msgdesc_t* const structname##_submsg_info[] = \ + { \ + msgname##_FIELDLIST(PB_GEN_SUBMSG_INFO, structname) \ + NULL}; \ + const pb_msgdesc_t structname##_msg = \ + { \ + structname##_field_info, \ + structname##_submsg_info, \ + msgname##_DEFAULT, \ + msgname##_CALLBACK, \ + 0 msgname##_FIELDLIST(PB_GEN_FIELD_COUNT, structname), \ + 0 msgname##_FIELDLIST(PB_GEN_REQ_FIELD_COUNT, structname), \ + 0 msgname##_FIELDLIST(PB_GEN_LARGEST_TAG, structname), \ + }; \ + msgname##_FIELDLIST(PB_GEN_FIELD_INFO_ASSERT_##width, structname) #define PB_GEN_FIELD_COUNT(structname, atype, htype, ltype, fieldname, tag) +1 #define PB_GEN_REQ_FIELD_COUNT(structname, atype, htype, ltype, fieldname, tag) \ - + (PB_HTYPE_ ## htype == PB_HTYPE_REQUIRED) + +(PB_HTYPE_##htype == PB_HTYPE_REQUIRED) #define PB_GEN_LARGEST_TAG(structname, atype, htype, ltype, fieldname, tag) \ - * 0 + tag + *0 + tag /* X-macro for generating the entries in struct_field_info[] array. */ -#define PB_GEN_FIELD_INFO_1(structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_1(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ - PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) +#define PB_GEN_FIELD_INFO_1(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_1(tag, PB_ATYPE_##atype | PB_HTYPE_##htype | PB_LTYPE_MAP_##ltype, \ + PB_DATA_OFFSET_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_DATA_SIZE_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_SIZE_OFFSET_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_ARRAY_SIZE_##atype(_PB_HTYPE_##htype, structname, fieldname)) -#define PB_GEN_FIELD_INFO_2(structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_2(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ - PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) +#define PB_GEN_FIELD_INFO_2(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_2(tag, PB_ATYPE_##atype | PB_HTYPE_##htype | PB_LTYPE_MAP_##ltype, \ + PB_DATA_OFFSET_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_DATA_SIZE_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_SIZE_OFFSET_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_ARRAY_SIZE_##atype(_PB_HTYPE_##htype, structname, fieldname)) -#define PB_GEN_FIELD_INFO_4(structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_4(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ - PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) +#define PB_GEN_FIELD_INFO_4(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_4(tag, PB_ATYPE_##atype | PB_HTYPE_##htype | PB_LTYPE_MAP_##ltype, \ + PB_DATA_OFFSET_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_DATA_SIZE_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_SIZE_OFFSET_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_ARRAY_SIZE_##atype(_PB_HTYPE_##htype, structname, fieldname)) -#define PB_GEN_FIELD_INFO_8(structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_8(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ - PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) +#define PB_GEN_FIELD_INFO_8(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_8(tag, PB_ATYPE_##atype | PB_HTYPE_##htype | PB_LTYPE_MAP_##ltype, \ + PB_DATA_OFFSET_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_DATA_SIZE_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_SIZE_OFFSET_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_ARRAY_SIZE_##atype(_PB_HTYPE_##htype, structname, fieldname)) -#define PB_GEN_FIELD_INFO_AUTO(structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_AUTO2(PB_FIELDINFO_WIDTH_AUTO(_PB_ATYPE_ ## atype, _PB_HTYPE_ ## htype, _PB_LTYPE_ ## ltype), \ - tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ - PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) +#define PB_GEN_FIELD_INFO_AUTO(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_AUTO2(PB_FIELDINFO_WIDTH_AUTO(_PB_ATYPE_##atype, _PB_HTYPE_##htype, _PB_LTYPE_##ltype), \ + tag, PB_ATYPE_##atype | PB_HTYPE_##htype | PB_LTYPE_MAP_##ltype, \ + PB_DATA_OFFSET_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_DATA_SIZE_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_SIZE_OFFSET_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_ARRAY_SIZE_##atype(_PB_HTYPE_##htype, structname, fieldname)) #define PB_FIELDINFO_AUTO2(width, tag, type, data_offset, data_size, size_offset, array_size) \ PB_FIELDINFO_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) #define PB_FIELDINFO_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) \ - PB_FIELDINFO_ ## width(tag, type, data_offset, data_size, size_offset, array_size) + PB_FIELDINFO_##width(tag, type, data_offset, data_size, size_offset, array_size) /* X-macro for generating asserts that entries fit in struct_field_info[] array. * The structure of macros here must match the structure above in PB_GEN_FIELD_INFO_x(), * but it is not easily reused because of how macro substitutions work. */ -#define PB_GEN_FIELD_INFO_ASSERT_1(structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_ASSERT_1(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ - PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) +#define PB_GEN_FIELD_INFO_ASSERT_1(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_ASSERT_1(tag, PB_ATYPE_##atype | PB_HTYPE_##htype | PB_LTYPE_MAP_##ltype, \ + PB_DATA_OFFSET_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_DATA_SIZE_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_SIZE_OFFSET_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_ARRAY_SIZE_##atype(_PB_HTYPE_##htype, structname, fieldname)) -#define PB_GEN_FIELD_INFO_ASSERT_2(structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_ASSERT_2(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ - PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) +#define PB_GEN_FIELD_INFO_ASSERT_2(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_ASSERT_2(tag, PB_ATYPE_##atype | PB_HTYPE_##htype | PB_LTYPE_MAP_##ltype, \ + PB_DATA_OFFSET_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_DATA_SIZE_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_SIZE_OFFSET_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_ARRAY_SIZE_##atype(_PB_HTYPE_##htype, structname, fieldname)) -#define PB_GEN_FIELD_INFO_ASSERT_4(structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_ASSERT_4(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ - PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) +#define PB_GEN_FIELD_INFO_ASSERT_4(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_ASSERT_4(tag, PB_ATYPE_##atype | PB_HTYPE_##htype | PB_LTYPE_MAP_##ltype, \ + PB_DATA_OFFSET_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_DATA_SIZE_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_SIZE_OFFSET_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_ARRAY_SIZE_##atype(_PB_HTYPE_##htype, structname, fieldname)) -#define PB_GEN_FIELD_INFO_ASSERT_8(structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_ASSERT_8(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ - PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) +#define PB_GEN_FIELD_INFO_ASSERT_8(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_ASSERT_8(tag, PB_ATYPE_##atype | PB_HTYPE_##htype | PB_LTYPE_MAP_##ltype, \ + PB_DATA_OFFSET_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_DATA_SIZE_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_SIZE_OFFSET_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_ARRAY_SIZE_##atype(_PB_HTYPE_##htype, structname, fieldname)) -#define PB_GEN_FIELD_INFO_ASSERT_AUTO(structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_ASSERT_AUTO2(PB_FIELDINFO_WIDTH_AUTO(_PB_ATYPE_ ## atype, _PB_HTYPE_ ## htype, _PB_LTYPE_ ## ltype), \ - tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ - PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) +#define PB_GEN_FIELD_INFO_ASSERT_AUTO(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_ASSERT_AUTO2(PB_FIELDINFO_WIDTH_AUTO(_PB_ATYPE_##atype, _PB_HTYPE_##htype, _PB_LTYPE_##ltype), \ + tag, PB_ATYPE_##atype | PB_HTYPE_##htype | PB_LTYPE_MAP_##ltype, \ + PB_DATA_OFFSET_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_DATA_SIZE_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_SIZE_OFFSET_##atype(_PB_HTYPE_##htype, structname, fieldname), \ + PB_ARRAY_SIZE_##atype(_PB_HTYPE_##htype, structname, fieldname)) #define PB_FIELDINFO_ASSERT_AUTO2(width, tag, type, data_offset, data_size, size_offset, array_size) \ PB_FIELDINFO_ASSERT_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) #define PB_FIELDINFO_ASSERT_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) \ - PB_FIELDINFO_ASSERT_ ## width(tag, type, data_offset, data_size, size_offset, array_size) + PB_FIELDINFO_ASSERT_##width(tag, type, data_offset, data_size, size_offset, array_size) -#define PB_DATA_OFFSET_STATIC(htype, structname, fieldname) PB_DO ## htype(structname, fieldname) -#define PB_DATA_OFFSET_POINTER(htype, structname, fieldname) PB_DO ## htype(structname, fieldname) -#define PB_DATA_OFFSET_CALLBACK(htype, structname, fieldname) PB_DO ## htype(structname, fieldname) +#define PB_DATA_OFFSET_STATIC(htype, structname, fieldname) PB_DO##htype(structname, fieldname) +#define PB_DATA_OFFSET_POINTER(htype, structname, fieldname) PB_DO##htype(structname, fieldname) +#define PB_DATA_OFFSET_CALLBACK(htype, structname, fieldname) PB_DO##htype(structname, fieldname) #define PB_DO_PB_HTYPE_REQUIRED(structname, fieldname) offsetof(structname, fieldname) #define PB_DO_PB_HTYPE_SINGULAR(structname, fieldname) offsetof(structname, fieldname) #define PB_DO_PB_HTYPE_ONEOF(structname, fieldname) offsetof(structname, PB_ONEOF_NAME(FULL, fieldname)) @@ -655,16 +668,16 @@ struct pb_extension_s { #define PB_DO_PB_HTYPE_REPEATED(structname, fieldname) offsetof(structname, fieldname) #define PB_DO_PB_HTYPE_FIXARRAY(structname, fieldname) offsetof(structname, fieldname) -#define PB_SIZE_OFFSET_STATIC(htype, structname, fieldname) PB_SO ## htype(structname, fieldname) -#define PB_SIZE_OFFSET_POINTER(htype, structname, fieldname) PB_SO_PTR ## htype(structname, fieldname) -#define PB_SIZE_OFFSET_CALLBACK(htype, structname, fieldname) PB_SO_CB ## htype(structname, fieldname) +#define PB_SIZE_OFFSET_STATIC(htype, structname, fieldname) PB_SO##htype(structname, fieldname) +#define PB_SIZE_OFFSET_POINTER(htype, structname, fieldname) PB_SO_PTR##htype(structname, fieldname) +#define PB_SIZE_OFFSET_CALLBACK(htype, structname, fieldname) PB_SO_CB##htype(structname, fieldname) #define PB_SO_PB_HTYPE_REQUIRED(structname, fieldname) 0 #define PB_SO_PB_HTYPE_SINGULAR(structname, fieldname) 0 #define PB_SO_PB_HTYPE_ONEOF(structname, fieldname) PB_SO_PB_HTYPE_ONEOF2(structname, PB_ONEOF_NAME(FULL, fieldname), PB_ONEOF_NAME(UNION, fieldname)) #define PB_SO_PB_HTYPE_ONEOF2(structname, fullname, unionname) PB_SO_PB_HTYPE_ONEOF3(structname, fullname, unionname) -#define PB_SO_PB_HTYPE_ONEOF3(structname, fullname, unionname) pb_delta(structname, fullname, which_ ## unionname) -#define PB_SO_PB_HTYPE_OPTIONAL(structname, fieldname) pb_delta(structname, fieldname, has_ ## fieldname) -#define PB_SO_PB_HTYPE_REPEATED(structname, fieldname) pb_delta(structname, fieldname, fieldname ## _count) +#define PB_SO_PB_HTYPE_ONEOF3(structname, fullname, unionname) pb_delta(structname, fullname, which_##unionname) +#define PB_SO_PB_HTYPE_OPTIONAL(structname, fieldname) pb_delta(structname, fieldname, has_##fieldname) +#define PB_SO_PB_HTYPE_REPEATED(structname, fieldname) pb_delta(structname, fieldname, fieldname##_count) #define PB_SO_PB_HTYPE_FIXARRAY(structname, fieldname) 0 #define PB_SO_PTR_PB_HTYPE_REQUIRED(structname, fieldname) 0 #define PB_SO_PTR_PB_HTYPE_SINGULAR(structname, fieldname) 0 @@ -679,8 +692,8 @@ struct pb_extension_s { #define PB_SO_CB_PB_HTYPE_REPEATED(structname, fieldname) 0 #define PB_SO_CB_PB_HTYPE_FIXARRAY(structname, fieldname) 0 -#define PB_ARRAY_SIZE_STATIC(htype, structname, fieldname) PB_AS ## htype(structname, fieldname) -#define PB_ARRAY_SIZE_POINTER(htype, structname, fieldname) PB_AS_PTR ## htype(structname, fieldname) +#define PB_ARRAY_SIZE_STATIC(htype, structname, fieldname) PB_AS##htype(structname, fieldname) +#define PB_ARRAY_SIZE_POINTER(htype, structname, fieldname) PB_AS_PTR##htype(structname, fieldname) #define PB_ARRAY_SIZE_CALLBACK(htype, structname, fieldname) 1 #define PB_AS_PB_HTYPE_REQUIRED(structname, fieldname) 1 #define PB_AS_PB_HTYPE_SINGULAR(structname, fieldname) 1 @@ -695,9 +708,9 @@ struct pb_extension_s { #define PB_AS_PTR_PB_HTYPE_REPEATED(structname, fieldname) 1 #define PB_AS_PTR_PB_HTYPE_FIXARRAY(structname, fieldname) pb_arraysize(structname, fieldname[0]) -#define PB_DATA_SIZE_STATIC(htype, structname, fieldname) PB_DS ## htype(structname, fieldname) -#define PB_DATA_SIZE_POINTER(htype, structname, fieldname) PB_DS_PTR ## htype(structname, fieldname) -#define PB_DATA_SIZE_CALLBACK(htype, structname, fieldname) PB_DS_CB ## htype(structname, fieldname) +#define PB_DATA_SIZE_STATIC(htype, structname, fieldname) PB_DS##htype(structname, fieldname) +#define PB_DATA_SIZE_POINTER(htype, structname, fieldname) PB_DS_PTR##htype(structname, fieldname) +#define PB_DATA_SIZE_CALLBACK(htype, structname, fieldname) PB_DS_CB##htype(structname, fieldname) #define PB_DS_PB_HTYPE_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname) #define PB_DS_PB_HTYPE_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname) #define PB_DS_PB_HTYPE_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname) @@ -717,22 +730,22 @@ struct pb_extension_s { #define PB_DS_CB_PB_HTYPE_REPEATED(structname, fieldname) pb_membersize(structname, fieldname) #define PB_DS_CB_PB_HTYPE_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname) -#define PB_ONEOF_NAME(type, tuple) PB_EXPAND(PB_ONEOF_NAME_ ## type tuple) -#define PB_ONEOF_NAME_UNION(unionname,membername,fullname) unionname -#define PB_ONEOF_NAME_MEMBER(unionname,membername,fullname) membername -#define PB_ONEOF_NAME_FULL(unionname,membername,fullname) fullname +#define PB_ONEOF_NAME(type, tuple) PB_EXPAND(PB_ONEOF_NAME_##type tuple) +#define PB_ONEOF_NAME_UNION(unionname, membername, fullname) unionname +#define PB_ONEOF_NAME_MEMBER(unionname, membername, fullname) membername +#define PB_ONEOF_NAME_FULL(unionname, membername, fullname) fullname #define PB_GEN_SUBMSG_INFO(structname, atype, htype, ltype, fieldname, tag) \ - PB_SUBMSG_INFO_ ## htype(_PB_LTYPE_ ## ltype, structname, fieldname) + PB_SUBMSG_INFO_##htype(_PB_LTYPE_##ltype, structname, fieldname) -#define PB_SUBMSG_INFO_REQUIRED(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) -#define PB_SUBMSG_INFO_SINGULAR(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) -#define PB_SUBMSG_INFO_OPTIONAL(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) +#define PB_SUBMSG_INFO_REQUIRED(ltype, structname, fieldname) PB_SI##ltype(structname##_##fieldname##_MSGTYPE) +#define PB_SUBMSG_INFO_SINGULAR(ltype, structname, fieldname) PB_SI##ltype(structname##_##fieldname##_MSGTYPE) +#define PB_SUBMSG_INFO_OPTIONAL(ltype, structname, fieldname) PB_SI##ltype(structname##_##fieldname##_MSGTYPE) #define PB_SUBMSG_INFO_ONEOF(ltype, structname, fieldname) PB_SUBMSG_INFO_ONEOF2(ltype, structname, PB_ONEOF_NAME(UNION, fieldname), PB_ONEOF_NAME(MEMBER, fieldname)) #define PB_SUBMSG_INFO_ONEOF2(ltype, structname, unionname, membername) PB_SUBMSG_INFO_ONEOF3(ltype, structname, unionname, membername) -#define PB_SUBMSG_INFO_ONEOF3(ltype, structname, unionname, membername) PB_SI ## ltype(structname ## _ ## unionname ## _ ## membername ## _MSGTYPE) -#define PB_SUBMSG_INFO_REPEATED(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) -#define PB_SUBMSG_INFO_FIXARRAY(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) +#define PB_SUBMSG_INFO_ONEOF3(ltype, structname, unionname, membername) PB_SI##ltype(structname##_##unionname##_##membername##_MSGTYPE) +#define PB_SUBMSG_INFO_REPEATED(ltype, structname, fieldname) PB_SI##ltype(structname##_##fieldname##_MSGTYPE) +#define PB_SUBMSG_INFO_FIXARRAY(ltype, structname, fieldname) PB_SI##ltype(structname##_##fieldname##_MSGTYPE) #define PB_SI_PB_LTYPE_BOOL(t) #define PB_SI_PB_LTYPE_BYTES(t) #define PB_SI_PB_LTYPE_DOUBLE(t) @@ -743,7 +756,7 @@ struct pb_extension_s { #define PB_SI_PB_LTYPE_FLOAT(t) #define PB_SI_PB_LTYPE_INT32(t) #define PB_SI_PB_LTYPE_INT64(t) -#define PB_SI_PB_LTYPE_MESSAGE(t) PB_SUBMSG_DESCRIPTOR(t) +#define PB_SI_PB_LTYPE_MESSAGE(t) PB_SUBMSG_DESCRIPTOR(t) #define PB_SI_PB_LTYPE_MSG_W_CB(t) PB_SUBMSG_DESCRIPTOR(t) #define PB_SI_PB_LTYPE_SFIXED32(t) #define PB_SI_PB_LTYPE_SFIXED64(t) @@ -754,53 +767,53 @@ struct pb_extension_s { #define PB_SI_PB_LTYPE_UINT64(t) #define PB_SI_PB_LTYPE_EXTENSION(t) #define PB_SI_PB_LTYPE_FIXED_LENGTH_BYTES(t) -#define PB_SUBMSG_DESCRIPTOR(t) &(t ## _msg), +#define PB_SUBMSG_DESCRIPTOR(t) &(t##_msg), -/* The field descriptors use a variable width format, with width of either - * 1, 2, 4 or 8 of 32-bit words. The two lowest bytes of the first byte always - * encode the descriptor size, 6 lowest bits of field tag number, and 8 bits - * of the field type. - * - * Descriptor size is encoded as 0 = 1 word, 1 = 2 words, 2 = 4 words, 3 = 8 words. - * - * Formats, listed starting with the least significant bit of the first word. - * 1 word: [2-bit len] [6-bit tag] [8-bit type] [8-bit data_offset] [4-bit size_offset] [4-bit data_size] - * - * 2 words: [2-bit len] [6-bit tag] [8-bit type] [12-bit array_size] [4-bit size_offset] - * [16-bit data_offset] [12-bit data_size] [4-bit tag>>6] - * - * 4 words: [2-bit len] [6-bit tag] [8-bit type] [16-bit array_size] - * [8-bit size_offset] [24-bit tag>>6] - * [32-bit data_offset] - * [32-bit data_size] - * - * 8 words: [2-bit len] [6-bit tag] [8-bit type] [16-bit reserved] - * [8-bit size_offset] [24-bit tag>>6] - * [32-bit data_offset] - * [32-bit data_size] - * [32-bit array_size] - * [32-bit reserved] - * [32-bit reserved] - * [32-bit reserved] - */ + /* The field descriptors use a variable width format, with width of either + * 1, 2, 4 or 8 of 32-bit words. The two lowest bytes of the first byte always + * encode the descriptor size, 6 lowest bits of field tag number, and 8 bits + * of the field type. + * + * Descriptor size is encoded as 0 = 1 word, 1 = 2 words, 2 = 4 words, 3 = 8 words. + * + * Formats, listed starting with the least significant bit of the first word. + * 1 word: [2-bit len] [6-bit tag] [8-bit type] [8-bit data_offset] [4-bit size_offset] [4-bit data_size] + * + * 2 words: [2-bit len] [6-bit tag] [8-bit type] [12-bit array_size] [4-bit size_offset] + * [16-bit data_offset] [12-bit data_size] [4-bit tag>>6] + * + * 4 words: [2-bit len] [6-bit tag] [8-bit type] [16-bit array_size] + * [8-bit size_offset] [24-bit tag>>6] + * [32-bit data_offset] + * [32-bit data_size] + * + * 8 words: [2-bit len] [6-bit tag] [8-bit type] [16-bit reserved] + * [8-bit size_offset] [24-bit tag>>6] + * [32-bit data_offset] + * [32-bit data_size] + * [32-bit array_size] + * [32-bit reserved] + * [32-bit reserved] + * [32-bit reserved] + */ -#define PB_FIELDINFO_1(tag, type, data_offset, data_size, size_offset, array_size) \ - (0 | (((uint32_t)(tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(data_offset) & 0xFF) << 16) | \ - (((uint32_t)(size_offset) & 0x0F) << 24) | (((uint32_t)(data_size) & 0x0F) << 28)), +#define PB_FIELDINFO_1(tag, type, data_offset, data_size, size_offset, array_size) \ + (0 | (((uint32_t)(tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(data_offset)&0xFF) << 16) | \ + (((uint32_t)(size_offset)&0x0F) << 24) | (((uint32_t)(data_size)&0x0F) << 28)), -#define PB_FIELDINFO_2(tag, type, data_offset, data_size, size_offset, array_size) \ - (1 | (((uint32_t)(tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(array_size) & 0xFFF) << 16) | (((uint32_t)(size_offset) & 0x0F) << 28)), \ - (((uint32_t)(data_offset) & 0xFFFF) | (((uint32_t)(data_size) & 0xFFF) << 16) | (((uint32_t)(tag) & 0x3c0) << 22)), +#define PB_FIELDINFO_2(tag, type, data_offset, data_size, size_offset, array_size) \ + (1 | (((uint32_t)(tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(array_size)&0xFFF) << 16) | (((uint32_t)(size_offset)&0x0F) << 28)), \ + (((uint32_t)(data_offset)&0xFFFF) | (((uint32_t)(data_size)&0xFFF) << 16) | (((uint32_t)(tag)&0x3c0) << 22)), -#define PB_FIELDINFO_4(tag, type, data_offset, data_size, size_offset, array_size) \ - (2 | (((uint32_t)(tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(array_size) & 0xFFFF) << 16)), \ - ((uint32_t)(int_least8_t)(size_offset) | (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \ - (data_offset), (data_size), +#define PB_FIELDINFO_4(tag, type, data_offset, data_size, size_offset, array_size) \ + (2 | (((uint32_t)(tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(array_size)&0xFFFF) << 16)), \ + ((uint32_t)(int_least8_t)(size_offset) | (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \ + (data_offset), (data_size), -#define PB_FIELDINFO_8(tag, type, data_offset, data_size, size_offset, array_size) \ - (3 | (((uint32_t)(tag) << 2) & 0xFF) | ((type) << 8)), \ - ((uint32_t)(int_least8_t)(size_offset) | (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \ - (data_offset), (data_size), (array_size), 0, 0, 0, +#define PB_FIELDINFO_8(tag, type, data_offset, data_size, size_offset, array_size) \ + (3 | (((uint32_t)(tag) << 2) & 0xFF) | ((type) << 8)), \ + ((uint32_t)(int_least8_t)(size_offset) | (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \ + (data_offset), (data_size), (array_size), 0, 0, 0, /* These assertions verify that the field information fits in the allocated space. * The generator tries to automatically determine the correct width that can fit all @@ -809,92 +822,91 @@ struct pb_extension_s { * you can increase the descriptor width by defining PB_FIELDINFO_WIDTH or by setting * descriptorsize option in .options file. */ -#define PB_FITS(value,bits) ((uint32_t)(value) < ((uint32_t)1<2GB messages with nanopb anyway. */ #define PB_FIELDINFO_ASSERT_4(tag, type, data_offset, data_size, size_offset, array_size) \ - PB_STATIC_ASSERT(PB_FITS(tag,30) && PB_FITS(data_offset,31) && PB_FITS(size_offset,8) && PB_FITS(data_size,31) && PB_FITS(array_size,16), FIELDINFO_DOES_NOT_FIT_width4_field ## tag) + PB_STATIC_ASSERT(PB_FITS(tag, 30) && PB_FITS(data_offset, 31) && PB_FITS(size_offset, 8) && PB_FITS(data_size, 31) && PB_FITS(array_size, 16), FIELDINFO_DOES_NOT_FIT_width4_field##tag) #define PB_FIELDINFO_ASSERT_8(tag, type, data_offset, data_size, size_offset, array_size) \ - PB_STATIC_ASSERT(PB_FITS(tag,30) && PB_FITS(data_offset,31) && PB_FITS(size_offset,8) && PB_FITS(data_size,31) && PB_FITS(array_size,31), FIELDINFO_DOES_NOT_FIT_width8_field ## tag) + PB_STATIC_ASSERT(PB_FITS(tag, 30) && PB_FITS(data_offset, 31) && PB_FITS(size_offset, 8) && PB_FITS(data_size, 31) && PB_FITS(array_size, 31), FIELDINFO_DOES_NOT_FIT_width8_field##tag) #endif - /* Automatic picking of FIELDINFO width: * Uses width 1 when possible, otherwise resorts to width 2. * This is used when PB_BIND() is called with "AUTO" as the argument. * The generator will give explicit size argument when it knows that a message * structure grows beyond 1-word format limits. */ -#define PB_FIELDINFO_WIDTH_AUTO(atype, htype, ltype) PB_FI_WIDTH ## atype(htype, ltype) -#define PB_FI_WIDTH_PB_ATYPE_STATIC(htype, ltype) PB_FI_WIDTH ## htype(ltype) -#define PB_FI_WIDTH_PB_ATYPE_POINTER(htype, ltype) PB_FI_WIDTH ## htype(ltype) +#define PB_FIELDINFO_WIDTH_AUTO(atype, htype, ltype) PB_FI_WIDTH##atype(htype, ltype) +#define PB_FI_WIDTH_PB_ATYPE_STATIC(htype, ltype) PB_FI_WIDTH##htype(ltype) +#define PB_FI_WIDTH_PB_ATYPE_POINTER(htype, ltype) PB_FI_WIDTH##htype(ltype) #define PB_FI_WIDTH_PB_ATYPE_CALLBACK(htype, ltype) 2 -#define PB_FI_WIDTH_PB_HTYPE_REQUIRED(ltype) PB_FI_WIDTH ## ltype -#define PB_FI_WIDTH_PB_HTYPE_SINGULAR(ltype) PB_FI_WIDTH ## ltype -#define PB_FI_WIDTH_PB_HTYPE_OPTIONAL(ltype) PB_FI_WIDTH ## ltype -#define PB_FI_WIDTH_PB_HTYPE_ONEOF(ltype) PB_FI_WIDTH ## ltype +#define PB_FI_WIDTH_PB_HTYPE_REQUIRED(ltype) PB_FI_WIDTH##ltype +#define PB_FI_WIDTH_PB_HTYPE_SINGULAR(ltype) PB_FI_WIDTH##ltype +#define PB_FI_WIDTH_PB_HTYPE_OPTIONAL(ltype) PB_FI_WIDTH##ltype +#define PB_FI_WIDTH_PB_HTYPE_ONEOF(ltype) PB_FI_WIDTH##ltype #define PB_FI_WIDTH_PB_HTYPE_REPEATED(ltype) 2 #define PB_FI_WIDTH_PB_HTYPE_FIXARRAY(ltype) 2 -#define PB_FI_WIDTH_PB_LTYPE_BOOL 1 -#define PB_FI_WIDTH_PB_LTYPE_BYTES 2 -#define PB_FI_WIDTH_PB_LTYPE_DOUBLE 1 -#define PB_FI_WIDTH_PB_LTYPE_ENUM 1 -#define PB_FI_WIDTH_PB_LTYPE_UENUM 1 -#define PB_FI_WIDTH_PB_LTYPE_FIXED32 1 -#define PB_FI_WIDTH_PB_LTYPE_FIXED64 1 -#define PB_FI_WIDTH_PB_LTYPE_FLOAT 1 -#define PB_FI_WIDTH_PB_LTYPE_INT32 1 -#define PB_FI_WIDTH_PB_LTYPE_INT64 1 -#define PB_FI_WIDTH_PB_LTYPE_MESSAGE 2 -#define PB_FI_WIDTH_PB_LTYPE_MSG_W_CB 2 -#define PB_FI_WIDTH_PB_LTYPE_SFIXED32 1 -#define PB_FI_WIDTH_PB_LTYPE_SFIXED64 1 -#define PB_FI_WIDTH_PB_LTYPE_SINT32 1 -#define PB_FI_WIDTH_PB_LTYPE_SINT64 1 -#define PB_FI_WIDTH_PB_LTYPE_STRING 2 -#define PB_FI_WIDTH_PB_LTYPE_UINT32 1 -#define PB_FI_WIDTH_PB_LTYPE_UINT64 1 +#define PB_FI_WIDTH_PB_LTYPE_BOOL 1 +#define PB_FI_WIDTH_PB_LTYPE_BYTES 2 +#define PB_FI_WIDTH_PB_LTYPE_DOUBLE 1 +#define PB_FI_WIDTH_PB_LTYPE_ENUM 1 +#define PB_FI_WIDTH_PB_LTYPE_UENUM 1 +#define PB_FI_WIDTH_PB_LTYPE_FIXED32 1 +#define PB_FI_WIDTH_PB_LTYPE_FIXED64 1 +#define PB_FI_WIDTH_PB_LTYPE_FLOAT 1 +#define PB_FI_WIDTH_PB_LTYPE_INT32 1 +#define PB_FI_WIDTH_PB_LTYPE_INT64 1 +#define PB_FI_WIDTH_PB_LTYPE_MESSAGE 2 +#define PB_FI_WIDTH_PB_LTYPE_MSG_W_CB 2 +#define PB_FI_WIDTH_PB_LTYPE_SFIXED32 1 +#define PB_FI_WIDTH_PB_LTYPE_SFIXED64 1 +#define PB_FI_WIDTH_PB_LTYPE_SINT32 1 +#define PB_FI_WIDTH_PB_LTYPE_SINT64 1 +#define PB_FI_WIDTH_PB_LTYPE_STRING 2 +#define PB_FI_WIDTH_PB_LTYPE_UINT32 1 +#define PB_FI_WIDTH_PB_LTYPE_UINT64 1 #define PB_FI_WIDTH_PB_LTYPE_EXTENSION 1 #define PB_FI_WIDTH_PB_LTYPE_FIXED_LENGTH_BYTES 2 /* The mapping from protobuf types to LTYPEs is done using these macros. */ -#define PB_LTYPE_MAP_BOOL PB_LTYPE_BOOL -#define PB_LTYPE_MAP_BYTES PB_LTYPE_BYTES -#define PB_LTYPE_MAP_DOUBLE PB_LTYPE_FIXED64 -#define PB_LTYPE_MAP_ENUM PB_LTYPE_VARINT -#define PB_LTYPE_MAP_UENUM PB_LTYPE_UVARINT -#define PB_LTYPE_MAP_FIXED32 PB_LTYPE_FIXED32 -#define PB_LTYPE_MAP_FIXED64 PB_LTYPE_FIXED64 -#define PB_LTYPE_MAP_FLOAT PB_LTYPE_FIXED32 -#define PB_LTYPE_MAP_INT32 PB_LTYPE_VARINT -#define PB_LTYPE_MAP_INT64 PB_LTYPE_VARINT -#define PB_LTYPE_MAP_MESSAGE PB_LTYPE_SUBMESSAGE -#define PB_LTYPE_MAP_MSG_W_CB PB_LTYPE_SUBMSG_W_CB -#define PB_LTYPE_MAP_SFIXED32 PB_LTYPE_FIXED32 -#define PB_LTYPE_MAP_SFIXED64 PB_LTYPE_FIXED64 -#define PB_LTYPE_MAP_SINT32 PB_LTYPE_SVARINT -#define PB_LTYPE_MAP_SINT64 PB_LTYPE_SVARINT -#define PB_LTYPE_MAP_STRING PB_LTYPE_STRING -#define PB_LTYPE_MAP_UINT32 PB_LTYPE_UVARINT -#define PB_LTYPE_MAP_UINT64 PB_LTYPE_UVARINT -#define PB_LTYPE_MAP_EXTENSION PB_LTYPE_EXTENSION +#define PB_LTYPE_MAP_BOOL PB_LTYPE_BOOL +#define PB_LTYPE_MAP_BYTES PB_LTYPE_BYTES +#define PB_LTYPE_MAP_DOUBLE PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_ENUM PB_LTYPE_VARINT +#define PB_LTYPE_MAP_UENUM PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_FIXED32 PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_FIXED64 PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_FLOAT PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_INT32 PB_LTYPE_VARINT +#define PB_LTYPE_MAP_INT64 PB_LTYPE_VARINT +#define PB_LTYPE_MAP_MESSAGE PB_LTYPE_SUBMESSAGE +#define PB_LTYPE_MAP_MSG_W_CB PB_LTYPE_SUBMSG_W_CB +#define PB_LTYPE_MAP_SFIXED32 PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_SFIXED64 PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_SINT32 PB_LTYPE_SVARINT +#define PB_LTYPE_MAP_SINT64 PB_LTYPE_SVARINT +#define PB_LTYPE_MAP_STRING PB_LTYPE_STRING +#define PB_LTYPE_MAP_UINT32 PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_UINT64 PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_EXTENSION PB_LTYPE_EXTENSION #define PB_LTYPE_MAP_FIXED_LENGTH_BYTES PB_LTYPE_FIXED_LENGTH_BYTES /* These macros are used for giving out error messages. @@ -926,23 +938,25 @@ struct pb_extension_s { #ifdef __cplusplus #if __cplusplus >= 201103L #define PB_CONSTEXPR constexpr -#else // __cplusplus >= 201103L +#else // __cplusplus >= 201103L #define PB_CONSTEXPR -#endif // __cplusplus >= 201103L +#endif // __cplusplus >= 201103L #if __cplusplus >= 201703L #define PB_INLINE_CONSTEXPR inline constexpr -#else // __cplusplus >= 201703L +#else // __cplusplus >= 201703L #define PB_INLINE_CONSTEXPR PB_CONSTEXPR -#endif // __cplusplus >= 201703L +#endif // __cplusplus >= 201703L extern "C++" { -namespace nanopb { -// Each type will be partially specialized by the generator. -template struct MessageDescriptor; -} // namespace nanopb + namespace nanopb + { + // Each type will be partially specialized by the generator. + template + struct MessageDescriptor; + } // namespace nanopb } -#endif /* __cplusplus */ +#endif /* __cplusplus */ #endif diff --git a/src/chat/infra/meshtastic/generated/pb_common.c b/src/chat/infra/meshtastic/generated/pb_common.c index 6aee76b1..43ec41ff 100644 --- a/src/chat/infra/meshtastic/generated/pb_common.c +++ b/src/chat/infra/meshtastic/generated/pb_common.c @@ -5,7 +5,7 @@ #include "pb_common.h" -static bool load_descriptor_values(pb_field_iter_t *iter) +static bool load_descriptor_values(pb_field_iter_t* iter) { uint32_t word0; uint32_t data_offset; @@ -17,58 +17,62 @@ static bool load_descriptor_values(pb_field_iter_t *iter) word0 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index]); iter->type = (pb_type_t)((word0 >> 8) & 0xFF); - switch(word0 & 3) + switch (word0 & 3) { - case 0: { - /* 1-word format */ - iter->array_size = 1; - iter->tag = (pb_size_t)((word0 >> 2) & 0x3F); - size_offset = (int_least8_t)((word0 >> 24) & 0x0F); - data_offset = (word0 >> 16) & 0xFF; - iter->data_size = (pb_size_t)((word0 >> 28) & 0x0F); - break; - } + case 0: + { + /* 1-word format */ + iter->array_size = 1; + iter->tag = (pb_size_t)((word0 >> 2) & 0x3F); + size_offset = (int_least8_t)((word0 >> 24) & 0x0F); + data_offset = (word0 >> 16) & 0xFF; + iter->data_size = (pb_size_t)((word0 >> 28) & 0x0F); + break; + } - case 1: { - /* 2-word format */ - uint32_t word1 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 1]); + case 1: + { + /* 2-word format */ + uint32_t word1 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 1]); - iter->array_size = (pb_size_t)((word0 >> 16) & 0x0FFF); - iter->tag = (pb_size_t)(((word0 >> 2) & 0x3F) | ((word1 >> 28) << 6)); - size_offset = (int_least8_t)((word0 >> 28) & 0x0F); - data_offset = word1 & 0xFFFF; - iter->data_size = (pb_size_t)((word1 >> 16) & 0x0FFF); - break; - } + iter->array_size = (pb_size_t)((word0 >> 16) & 0x0FFF); + iter->tag = (pb_size_t)(((word0 >> 2) & 0x3F) | ((word1 >> 28) << 6)); + size_offset = (int_least8_t)((word0 >> 28) & 0x0F); + data_offset = word1 & 0xFFFF; + iter->data_size = (pb_size_t)((word1 >> 16) & 0x0FFF); + break; + } - case 2: { - /* 4-word format */ - uint32_t word1 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 1]); - uint32_t word2 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 2]); - uint32_t word3 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 3]); + case 2: + { + /* 4-word format */ + uint32_t word1 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 1]); + uint32_t word2 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 2]); + uint32_t word3 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 3]); - iter->array_size = (pb_size_t)(word0 >> 16); - iter->tag = (pb_size_t)(((word0 >> 2) & 0x3F) | ((word1 >> 8) << 6)); - size_offset = (int_least8_t)(word1 & 0xFF); - data_offset = word2; - iter->data_size = (pb_size_t)word3; - break; - } + iter->array_size = (pb_size_t)(word0 >> 16); + iter->tag = (pb_size_t)(((word0 >> 2) & 0x3F) | ((word1 >> 8) << 6)); + size_offset = (int_least8_t)(word1 & 0xFF); + data_offset = word2; + iter->data_size = (pb_size_t)word3; + break; + } - default: { - /* 8-word format */ - uint32_t word1 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 1]); - uint32_t word2 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 2]); - uint32_t word3 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 3]); - uint32_t word4 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 4]); + default: + { + /* 8-word format */ + uint32_t word1 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 1]); + uint32_t word2 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 2]); + uint32_t word3 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 3]); + uint32_t word4 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 4]); - iter->array_size = (pb_size_t)word4; - iter->tag = (pb_size_t)(((word0 >> 2) & 0x3F) | ((word1 >> 8) << 6)); - size_offset = (int_least8_t)(word1 & 0xFF); - data_offset = word2; - iter->data_size = (pb_size_t)word3; - break; - } + iter->array_size = (pb_size_t)word4; + iter->tag = (pb_size_t)(((word0 >> 2) & 0x3F) | ((word1 >> 8) << 6)); + size_offset = (int_least8_t)(word1 & 0xFF); + data_offset = word2; + iter->data_size = (pb_size_t)word3; + break; + } } if (!iter->message) @@ -119,7 +123,7 @@ static bool load_descriptor_values(pb_field_iter_t *iter) return true; } -static void advance_iterator(pb_field_iter_t *iter) +static void advance_iterator(pb_field_iter_t* iter) { iter->index++; @@ -153,7 +157,7 @@ static void advance_iterator(pb_field_iter_t *iter) } } -bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_msgdesc_t *desc, void *message) +bool pb_field_iter_begin(pb_field_iter_t* iter, const pb_msgdesc_t* desc, void* message) { memset(iter, 0, sizeof(*iter)); @@ -163,9 +167,9 @@ bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_msgdesc_t *desc, void * return load_descriptor_values(iter); } -bool pb_field_iter_begin_extension(pb_field_iter_t *iter, pb_extension_t *extension) +bool pb_field_iter_begin_extension(pb_field_iter_t* iter, pb_extension_t* extension) { - const pb_msgdesc_t *msg = (const pb_msgdesc_t*)extension->type->arg; + const pb_msgdesc_t* msg = (const pb_msgdesc_t*)extension->type->arg; bool status; uint32_t word0 = PB_PROGMEM_READU32(msg->field_info[0]); @@ -185,14 +189,14 @@ bool pb_field_iter_begin_extension(pb_field_iter_t *iter, pb_extension_t *extens return status; } -bool pb_field_iter_next(pb_field_iter_t *iter) +bool pb_field_iter_next(pb_field_iter_t* iter) { advance_iterator(iter); (void)load_descriptor_values(iter); return iter->index != 0; } -bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag) +bool pb_field_iter_find(pb_field_iter_t* iter, uint32_t tag) { if (iter->tag == tag) { @@ -243,7 +247,7 @@ bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag) } } -bool pb_field_iter_find_extension(pb_field_iter_t *iter) +bool pb_field_iter_find_extension(pb_field_iter_t* iter) { if (PB_LTYPE(iter->type) == PB_LTYPE_EXTENSION) { @@ -274,34 +278,35 @@ bool pb_field_iter_find_extension(pb_field_iter_t *iter) } } -static void *pb_const_cast(const void *p) +static void* pb_const_cast(const void* p) { /* Note: this casts away const, in order to use the common field iterator * logic for both encoding and decoding. The cast is done using union * to avoid spurious compiler warnings. */ - union { - void *p1; - const void *p2; + union + { + void* p1; + const void* p2; } t; t.p2 = p; return t.p1; } -bool pb_field_iter_begin_const(pb_field_iter_t *iter, const pb_msgdesc_t *desc, const void *message) +bool pb_field_iter_begin_const(pb_field_iter_t* iter, const pb_msgdesc_t* desc, const void* message) { return pb_field_iter_begin(iter, desc, pb_const_cast(message)); } -bool pb_field_iter_begin_extension_const(pb_field_iter_t *iter, const pb_extension_t *extension) +bool pb_field_iter_begin_extension_const(pb_field_iter_t* iter, const pb_extension_t* extension) { return pb_field_iter_begin_extension(iter, (pb_extension_t*)pb_const_cast(extension)); } -bool pb_default_field_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_t *field) +bool pb_default_field_callback(pb_istream_t* istream, pb_ostream_t* ostream, const pb_field_t* field) { if (field->data_size == sizeof(pb_callback_t)) { - pb_callback_t *pCallback = (pb_callback_t*)field->pData; + pb_callback_t* pCallback = (pb_callback_t*)field->pData; if (pCallback != NULL) { @@ -318,7 +323,6 @@ bool pb_default_field_callback(pb_istream_t *istream, pb_ostream_t *ostream, con } return true; /* Success, but didn't do anything */ - } #ifdef PB_VALIDATE_UTF8 @@ -331,9 +335,9 @@ bool pb_default_field_callback(pb_istream_t *istream, pb_ostream_t *ostream, con * any compatible with it. */ -bool pb_validate_utf8(const char *str) +bool pb_validate_utf8(const char* str) { - const pb_byte_t *s = (const pb_byte_t*)str; + const pb_byte_t* s = (const pb_byte_t*)str; while (*s) { if (*s < 0x80) @@ -345,7 +349,7 @@ bool pb_validate_utf8(const char *str) { /* 110XXXXx 10xxxxxx */ if ((s[1] & 0xc0) != 0x80 || - (s[0] & 0xfe) == 0xc0) /* overlong? */ + (s[0] & 0xfe) == 0xc0) /* overlong? */ return false; else s += 2; @@ -355,10 +359,10 @@ bool pb_validate_utf8(const char *str) /* 1110XXXX 10Xxxxxx 10xxxxxx */ if ((s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 || - (s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) || /* overlong? */ - (s[0] == 0xed && (s[1] & 0xe0) == 0xa0) || /* surrogate? */ + (s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) || /* overlong? */ + (s[0] == 0xed && (s[1] & 0xe0) == 0xa0) || /* surrogate? */ (s[0] == 0xef && s[1] == 0xbf && - (s[2] & 0xfe) == 0xbe)) /* U+FFFE or U+FFFF? */ + (s[2] & 0xfe) == 0xbe)) /* U+FFFE or U+FFFF? */ return false; else s += 3; @@ -385,4 +389,3 @@ bool pb_validate_utf8(const char *str) } #endif - diff --git a/src/chat/infra/meshtastic/generated/pb_common.h b/src/chat/infra/meshtastic/generated/pb_common.h index 58aa90f7..5c1a2d2b 100644 --- a/src/chat/infra/meshtastic/generated/pb_common.h +++ b/src/chat/infra/meshtastic/generated/pb_common.h @@ -8,37 +8,38 @@ #include "pb.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -/* Initialize the field iterator structure to beginning. - * Returns false if the message type is empty. */ -bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_msgdesc_t *desc, void *message); + /* Initialize the field iterator structure to beginning. + * Returns false if the message type is empty. */ + bool pb_field_iter_begin(pb_field_iter_t* iter, const pb_msgdesc_t* desc, void* message); -/* Get a field iterator for extension field. */ -bool pb_field_iter_begin_extension(pb_field_iter_t *iter, pb_extension_t *extension); + /* Get a field iterator for extension field. */ + bool pb_field_iter_begin_extension(pb_field_iter_t* iter, pb_extension_t* extension); -/* Same as pb_field_iter_begin(), but for const message pointer. - * Note that the pointers in pb_field_iter_t will be non-const but shouldn't - * be written to when using these functions. */ -bool pb_field_iter_begin_const(pb_field_iter_t *iter, const pb_msgdesc_t *desc, const void *message); -bool pb_field_iter_begin_extension_const(pb_field_iter_t *iter, const pb_extension_t *extension); + /* Same as pb_field_iter_begin(), but for const message pointer. + * Note that the pointers in pb_field_iter_t will be non-const but shouldn't + * be written to when using these functions. */ + bool pb_field_iter_begin_const(pb_field_iter_t* iter, const pb_msgdesc_t* desc, const void* message); + bool pb_field_iter_begin_extension_const(pb_field_iter_t* iter, const pb_extension_t* extension); -/* Advance the iterator to the next field. - * Returns false when the iterator wraps back to the first field. */ -bool pb_field_iter_next(pb_field_iter_t *iter); + /* Advance the iterator to the next field. + * Returns false when the iterator wraps back to the first field. */ + bool pb_field_iter_next(pb_field_iter_t* iter); -/* Advance the iterator until it points at a field with the given tag. - * Returns false if no such field exists. */ -bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag); + /* Advance the iterator until it points at a field with the given tag. + * Returns false if no such field exists. */ + bool pb_field_iter_find(pb_field_iter_t* iter, uint32_t tag); -/* Find a field with type PB_LTYPE_EXTENSION, or return false if not found. - * There can be only one extension range field per message. */ -bool pb_field_iter_find_extension(pb_field_iter_t *iter); + /* Find a field with type PB_LTYPE_EXTENSION, or return false if not found. + * There can be only one extension range field per message. */ + bool pb_field_iter_find_extension(pb_field_iter_t* iter); #ifdef PB_VALIDATE_UTF8 -/* Validate UTF-8 text string */ -bool pb_validate_utf8(const char *s); + /* Validate UTF-8 text string */ + bool pb_validate_utf8(const char* s); #endif #ifdef __cplusplus @@ -46,4 +47,3 @@ bool pb_validate_utf8(const char *s); #endif #endif - diff --git a/src/chat/infra/meshtastic/generated/pb_decode.c b/src/chat/infra/meshtastic/generated/pb_decode.c index 82affc6c..37cb7ff6 100644 --- a/src/chat/infra/meshtastic/generated/pb_decode.c +++ b/src/chat/infra/meshtastic/generated/pb_decode.c @@ -9,44 +9,44 @@ */ #if (defined(__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))) || \ (defined(__IAR_SYSTEMS_ICC__) && (__VER__ >= 9040001)) - #define checkreturn __attribute__((warn_unused_result)) +#define checkreturn __attribute__((warn_unused_result)) #else - #define checkreturn +#define checkreturn #endif -#include "pb.h" #include "pb_decode.h" +#include "pb.h" #include "pb_common.h" /************************************** * Declarations internal to this file * **************************************/ -static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); -static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size); -static bool checkreturn decode_basic_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field); -static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field); -static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field); -static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field); -static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field); -static bool checkreturn default_extension_decoder(pb_istream_t *stream, pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type); -static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_extension_t *extension); -static bool pb_field_set_to_default(pb_field_iter_t *field); -static bool pb_message_set_to_defaults(pb_field_iter_t *iter); -static bool checkreturn pb_dec_bool(pb_istream_t *stream, const pb_field_iter_t *field); -static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_iter_t *field); -static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_iter_t *field); -static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_iter_t *field); -static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_iter_t *field); -static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_iter_t *field); -static bool checkreturn pb_skip_varint(pb_istream_t *stream); -static bool checkreturn pb_skip_string(pb_istream_t *stream); +static bool checkreturn buf_read(pb_istream_t* stream, pb_byte_t* buf, size_t count); +static bool checkreturn read_raw_value(pb_istream_t* stream, pb_wire_type_t wire_type, pb_byte_t* buf, size_t* size); +static bool checkreturn decode_basic_field(pb_istream_t* stream, pb_wire_type_t wire_type, pb_field_iter_t* field); +static bool checkreturn decode_static_field(pb_istream_t* stream, pb_wire_type_t wire_type, pb_field_iter_t* field); +static bool checkreturn decode_pointer_field(pb_istream_t* stream, pb_wire_type_t wire_type, pb_field_iter_t* field); +static bool checkreturn decode_callback_field(pb_istream_t* stream, pb_wire_type_t wire_type, pb_field_iter_t* field); +static bool checkreturn decode_field(pb_istream_t* stream, pb_wire_type_t wire_type, pb_field_iter_t* field); +static bool checkreturn default_extension_decoder(pb_istream_t* stream, pb_extension_t* extension, uint32_t tag, pb_wire_type_t wire_type); +static bool checkreturn decode_extension(pb_istream_t* stream, uint32_t tag, pb_wire_type_t wire_type, pb_extension_t* extension); +static bool pb_field_set_to_default(pb_field_iter_t* field); +static bool pb_message_set_to_defaults(pb_field_iter_t* iter); +static bool checkreturn pb_dec_bool(pb_istream_t* stream, const pb_field_iter_t* field); +static bool checkreturn pb_dec_varint(pb_istream_t* stream, const pb_field_iter_t* field); +static bool checkreturn pb_dec_bytes(pb_istream_t* stream, const pb_field_iter_t* field); +static bool checkreturn pb_dec_string(pb_istream_t* stream, const pb_field_iter_t* field); +static bool checkreturn pb_dec_submessage(pb_istream_t* stream, const pb_field_iter_t* field); +static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t* stream, const pb_field_iter_t* field); +static bool checkreturn pb_skip_varint(pb_istream_t* stream); +static bool checkreturn pb_skip_string(pb_istream_t* stream); #ifdef PB_ENABLE_MALLOC -static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size); -static void initialize_pointer_field(void *pItem, pb_field_iter_t *field); -static bool checkreturn pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *field); -static void pb_release_single_field(pb_field_iter_t *field); +static bool checkreturn allocate_field(pb_istream_t* stream, void* pData, size_t data_size, size_t array_size); +static void initialize_pointer_field(void* pItem, pb_field_iter_t* field); +static bool checkreturn pb_release_union_field(pb_istream_t* stream, pb_field_iter_t* field); +static void pb_release_single_field(pb_field_iter_t* field); #endif #ifdef PB_WITHOUT_64BIT @@ -57,7 +57,8 @@ static void pb_release_single_field(pb_field_iter_t *field); #define pb_uint64_t uint64_t #endif -typedef struct { +typedef struct +{ uint32_t bitfield[(PB_MAX_REQUIRED_FIELDS + 31) / 32]; } pb_fields_seen_t; @@ -65,44 +66,44 @@ typedef struct { * pb_istream_t implementation * *******************************/ -static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) +static bool checkreturn buf_read(pb_istream_t* stream, pb_byte_t* buf, size_t count) { - const pb_byte_t *source = (const pb_byte_t*)stream->state; + const pb_byte_t* source = (const pb_byte_t*)stream->state; stream->state = (pb_byte_t*)stream->state + count; - + if (buf != NULL) { memcpy(buf, source, count * sizeof(pb_byte_t)); } - + return true; } -bool checkreturn pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) +bool checkreturn pb_read(pb_istream_t* stream, pb_byte_t* buf, size_t count) { if (count == 0) return true; #ifndef PB_BUFFER_ONLY - if (buf == NULL && stream->callback != buf_read) - { - /* Skip input bytes */ - pb_byte_t tmp[16]; - while (count > 16) - { - if (!pb_read(stream, tmp, 16)) - return false; - - count -= 16; - } - - return pb_read(stream, tmp, count); - } + if (buf == NULL && stream->callback != buf_read) + { + /* Skip input bytes */ + pb_byte_t tmp[16]; + while (count > 16) + { + if (!pb_read(stream, tmp, 16)) + return false; + + count -= 16; + } + + return pb_read(stream, tmp, count); + } #endif if (stream->bytes_left < count) PB_RETURN_ERROR(stream, "end-of-stream"); - + #ifndef PB_BUFFER_ONLY if (!stream->callback(stream, buf, count)) PB_RETURN_ERROR(stream, "io error"); @@ -110,7 +111,7 @@ bool checkreturn pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) if (!buf_read(stream, buf, count)) return false; #endif - + if (stream->bytes_left < count) stream->bytes_left = 0; else @@ -121,7 +122,7 @@ bool checkreturn pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) /* Read a single byte from input stream. buf may not be NULL. * This is an optimization for the varint decoding. */ -static bool checkreturn pb_readbyte(pb_istream_t *stream, pb_byte_t *buf) +static bool checkreturn pb_readbyte(pb_istream_t* stream, pb_byte_t* buf) { if (stream->bytes_left == 0) PB_RETURN_ERROR(stream, "end-of-stream"); @@ -135,19 +136,20 @@ static bool checkreturn pb_readbyte(pb_istream_t *stream, pb_byte_t *buf) #endif stream->bytes_left--; - - return true; + + return true; } -pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t msglen) +pb_istream_t pb_istream_from_buffer(const pb_byte_t* buf, size_t msglen) { pb_istream_t stream; /* Cast away the const from buf without a compiler error. We are * careful to use it only in a const manner in the callbacks. */ - union { - void *state; - const void *c_state; + union + { + void* state; + const void* c_state; } state; #ifdef PB_BUFFER_ONLY stream.callback = NULL; @@ -163,21 +165,20 @@ pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t msglen) return stream; } - /******************** * Helper functions * ********************/ -bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest) +bool checkreturn pb_decode_varint32(pb_istream_t* stream, uint32_t* dest) { pb_byte_t byte; uint32_t result; - + if (!pb_readbyte(stream, &byte)) { return false; } - + if ((byte & 0x80) == 0) { /* Quick case, 1 byte value */ @@ -188,18 +189,18 @@ bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest) /* Multibyte case */ uint_fast8_t bitpos = 7; result = byte & 0x7F; - + do { if (!pb_readbyte(stream, &byte)) return false; - + if (bitpos >= 32) { /* Note: The varint could have trailing 0x80 bytes, or 0xFF for negative. */ pb_byte_t sign_extension = (bitpos < 63) ? 0xFF : 0x01; bool valid_extension = ((byte & 0x7F) == 0x00 || - ((result >> 31) != 0 && byte == sign_extension)); + ((result >> 31) != 0 && byte == sign_extension)); if (bitpos >= 64 || !valid_extension) { @@ -220,19 +221,19 @@ bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest) } bitpos = (uint_fast8_t)(bitpos + 7); } while (byte & 0x80); - } - - *dest = result; - return true; + } + + *dest = result; + return true; } #ifndef PB_WITHOUT_64BIT -bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest) +bool checkreturn pb_decode_varint(pb_istream_t* stream, uint64_t* dest) { pb_byte_t byte; uint_fast8_t bitpos = 0; uint64_t result = 0; - + do { if (!pb_readbyte(stream, &byte)) @@ -244,13 +245,13 @@ bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest) result |= (uint64_t)(byte & 0x7F) << bitpos; bitpos = (uint_fast8_t)(bitpos + 7); } while (byte & 0x80); - + *dest = result; return true; } #endif -bool checkreturn pb_skip_varint(pb_istream_t *stream) +bool checkreturn pb_skip_varint(pb_istream_t* stream) { pb_byte_t byte; do @@ -261,12 +262,12 @@ bool checkreturn pb_skip_varint(pb_istream_t *stream) return true; } -bool checkreturn pb_skip_string(pb_istream_t *stream) +bool checkreturn pb_skip_string(pb_istream_t* stream) { uint32_t length; if (!pb_decode_varint32(stream, &length)) return false; - + if ((size_t)length != length) { PB_RETURN_ERROR(stream, "size too large"); @@ -275,11 +276,11 @@ bool checkreturn pb_skip_string(pb_istream_t *stream) return pb_read(stream, NULL, (size_t)length); } -bool checkreturn pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof) +bool checkreturn pb_decode_tag(pb_istream_t* stream, pb_wire_type_t* wire_type, uint32_t* tag, bool* eof) { uint32_t temp; *eof = false; - *wire_type = (pb_wire_type_t) 0; + *wire_type = (pb_wire_type_t)0; *tag = 0; if (stream->bytes_left == 0) @@ -309,95 +310,102 @@ bool checkreturn pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, #endif return false; } - + *tag = temp >> 3; *wire_type = (pb_wire_type_t)(temp & 7); return true; } -bool checkreturn pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type) +bool checkreturn pb_skip_field(pb_istream_t* stream, pb_wire_type_t wire_type) { switch (wire_type) { - case PB_WT_VARINT: return pb_skip_varint(stream); - case PB_WT_64BIT: return pb_read(stream, NULL, 8); - case PB_WT_STRING: return pb_skip_string(stream); - case PB_WT_32BIT: return pb_read(stream, NULL, 4); - case PB_WT_PACKED: - /* Calling pb_skip_field with a PB_WT_PACKED is an error. - * Explicitly handle this case and fallthrough to default to avoid - * compiler warnings. - */ - default: PB_RETURN_ERROR(stream, "invalid wire_type"); + case PB_WT_VARINT: + return pb_skip_varint(stream); + case PB_WT_64BIT: + return pb_read(stream, NULL, 8); + case PB_WT_STRING: + return pb_skip_string(stream); + case PB_WT_32BIT: + return pb_read(stream, NULL, 4); + case PB_WT_PACKED: + /* Calling pb_skip_field with a PB_WT_PACKED is an error. + * Explicitly handle this case and fallthrough to default to avoid + * compiler warnings. + */ + default: + PB_RETURN_ERROR(stream, "invalid wire_type"); } } /* Read a raw value to buffer, for the purpose of passing it to callback as * a substream. Size is maximum size on call, and actual size on return. */ -static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size) +static bool checkreturn read_raw_value(pb_istream_t* stream, pb_wire_type_t wire_type, pb_byte_t* buf, size_t* size) { size_t max_size = *size; switch (wire_type) { - case PB_WT_VARINT: - *size = 0; - do - { - (*size)++; - if (*size > max_size) - PB_RETURN_ERROR(stream, "varint overflow"); + case PB_WT_VARINT: + *size = 0; + do + { + (*size)++; + if (*size > max_size) + PB_RETURN_ERROR(stream, "varint overflow"); - if (!pb_read(stream, buf, 1)) - return false; - } while (*buf++ & 0x80); - return true; - - case PB_WT_64BIT: - *size = 8; - return pb_read(stream, buf, 8); - - case PB_WT_32BIT: - *size = 4; - return pb_read(stream, buf, 4); - - case PB_WT_STRING: - /* Calling read_raw_value with a PB_WT_STRING is an error. - * Explicitly handle this case and fallthrough to default to avoid - * compiler warnings. - */ + if (!pb_read(stream, buf, 1)) + return false; + } while (*buf++ & 0x80); + return true; - case PB_WT_PACKED: - /* Calling read_raw_value with a PB_WT_PACKED is an error. - * Explicitly handle this case and fallthrough to default to avoid - * compiler warnings. - */ + case PB_WT_64BIT: + *size = 8; + return pb_read(stream, buf, 8); - default: PB_RETURN_ERROR(stream, "invalid wire_type"); + case PB_WT_32BIT: + *size = 4; + return pb_read(stream, buf, 4); + + case PB_WT_STRING: + /* Calling read_raw_value with a PB_WT_STRING is an error. + * Explicitly handle this case and fallthrough to default to avoid + * compiler warnings. + */ + + case PB_WT_PACKED: + /* Calling read_raw_value with a PB_WT_PACKED is an error. + * Explicitly handle this case and fallthrough to default to avoid + * compiler warnings. + */ + + default: + PB_RETURN_ERROR(stream, "invalid wire_type"); } } /* Decode string length from stream and return a substream with limited length. * Remember to close the substream using pb_close_string_substream(). */ -bool checkreturn pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream) +bool checkreturn pb_make_string_substream(pb_istream_t* stream, pb_istream_t* substream) { uint32_t size; if (!pb_decode_varint32(stream, &size)) return false; - + *substream = *stream; if (substream->bytes_left < size) PB_RETURN_ERROR(stream, "parent stream too short"); - + substream->bytes_left = (size_t)size; stream->bytes_left -= (size_t)size; return true; } -bool checkreturn pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream) +bool checkreturn pb_close_string_substream(pb_istream_t* stream, pb_istream_t* substream) { - if (substream->bytes_left) { + if (substream->bytes_left) + { if (!pb_read(substream, NULL, substream->bytes_left)) return false; } @@ -414,164 +422,163 @@ bool checkreturn pb_close_string_substream(pb_istream_t *stream, pb_istream_t *s * Decode a single field * *************************/ -static bool checkreturn decode_basic_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) +static bool checkreturn decode_basic_field(pb_istream_t* stream, pb_wire_type_t wire_type, pb_field_iter_t* field) { switch (PB_LTYPE(field->type)) { - case PB_LTYPE_BOOL: - if (wire_type != PB_WT_VARINT && wire_type != PB_WT_PACKED) - PB_RETURN_ERROR(stream, "wrong wire type"); + case PB_LTYPE_BOOL: + if (wire_type != PB_WT_VARINT && wire_type != PB_WT_PACKED) + PB_RETURN_ERROR(stream, "wrong wire type"); - return pb_dec_bool(stream, field); + return pb_dec_bool(stream, field); - case PB_LTYPE_VARINT: - case PB_LTYPE_UVARINT: - case PB_LTYPE_SVARINT: - if (wire_type != PB_WT_VARINT && wire_type != PB_WT_PACKED) - PB_RETURN_ERROR(stream, "wrong wire type"); + case PB_LTYPE_VARINT: + case PB_LTYPE_UVARINT: + case PB_LTYPE_SVARINT: + if (wire_type != PB_WT_VARINT && wire_type != PB_WT_PACKED) + PB_RETURN_ERROR(stream, "wrong wire type"); - return pb_dec_varint(stream, field); + return pb_dec_varint(stream, field); - case PB_LTYPE_FIXED32: - if (wire_type != PB_WT_32BIT && wire_type != PB_WT_PACKED) - PB_RETURN_ERROR(stream, "wrong wire type"); + case PB_LTYPE_FIXED32: + if (wire_type != PB_WT_32BIT && wire_type != PB_WT_PACKED) + PB_RETURN_ERROR(stream, "wrong wire type"); - return pb_decode_fixed32(stream, field->pData); + return pb_decode_fixed32(stream, field->pData); - case PB_LTYPE_FIXED64: - if (wire_type != PB_WT_64BIT && wire_type != PB_WT_PACKED) - PB_RETURN_ERROR(stream, "wrong wire type"); + case PB_LTYPE_FIXED64: + if (wire_type != PB_WT_64BIT && wire_type != PB_WT_PACKED) + PB_RETURN_ERROR(stream, "wrong wire type"); #ifdef PB_CONVERT_DOUBLE_FLOAT - if (field->data_size == sizeof(float)) - { - return pb_decode_double_as_float(stream, (float*)field->pData); - } + if (field->data_size == sizeof(float)) + { + return pb_decode_double_as_float(stream, (float*)field->pData); + } #endif #ifdef PB_WITHOUT_64BIT - PB_RETURN_ERROR(stream, "invalid data_size"); + PB_RETURN_ERROR(stream, "invalid data_size"); #else - return pb_decode_fixed64(stream, field->pData); + return pb_decode_fixed64(stream, field->pData); #endif - case PB_LTYPE_BYTES: - if (wire_type != PB_WT_STRING) - PB_RETURN_ERROR(stream, "wrong wire type"); + case PB_LTYPE_BYTES: + if (wire_type != PB_WT_STRING) + PB_RETURN_ERROR(stream, "wrong wire type"); - return pb_dec_bytes(stream, field); + return pb_dec_bytes(stream, field); - case PB_LTYPE_STRING: - if (wire_type != PB_WT_STRING) - PB_RETURN_ERROR(stream, "wrong wire type"); + case PB_LTYPE_STRING: + if (wire_type != PB_WT_STRING) + PB_RETURN_ERROR(stream, "wrong wire type"); - return pb_dec_string(stream, field); + return pb_dec_string(stream, field); - case PB_LTYPE_SUBMESSAGE: - case PB_LTYPE_SUBMSG_W_CB: - if (wire_type != PB_WT_STRING) - PB_RETURN_ERROR(stream, "wrong wire type"); + case PB_LTYPE_SUBMESSAGE: + case PB_LTYPE_SUBMSG_W_CB: + if (wire_type != PB_WT_STRING) + PB_RETURN_ERROR(stream, "wrong wire type"); - return pb_dec_submessage(stream, field); + return pb_dec_submessage(stream, field); - case PB_LTYPE_FIXED_LENGTH_BYTES: - if (wire_type != PB_WT_STRING) - PB_RETURN_ERROR(stream, "wrong wire type"); + case PB_LTYPE_FIXED_LENGTH_BYTES: + if (wire_type != PB_WT_STRING) + PB_RETURN_ERROR(stream, "wrong wire type"); - return pb_dec_fixed_length_bytes(stream, field); + return pb_dec_fixed_length_bytes(stream, field); - default: - PB_RETURN_ERROR(stream, "invalid field type"); + default: + PB_RETURN_ERROR(stream, "invalid field type"); } } -static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) +static bool checkreturn decode_static_field(pb_istream_t* stream, pb_wire_type_t wire_type, pb_field_iter_t* field) { switch (PB_HTYPE(field->type)) { - case PB_HTYPE_REQUIRED: - return decode_basic_field(stream, wire_type, field); - - case PB_HTYPE_OPTIONAL: - if (field->pSize != NULL) - *(bool*)field->pSize = true; - return decode_basic_field(stream, wire_type, field); - - case PB_HTYPE_REPEATED: - if (wire_type == PB_WT_STRING - && PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) + case PB_HTYPE_REQUIRED: + return decode_basic_field(stream, wire_type, field); + + case PB_HTYPE_OPTIONAL: + if (field->pSize != NULL) + *(bool*)field->pSize = true; + return decode_basic_field(stream, wire_type, field); + + case PB_HTYPE_REPEATED: + if (wire_type == PB_WT_STRING && PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) + { + /* Packed array */ + bool status = true; + pb_istream_t substream; + pb_size_t* size = (pb_size_t*)field->pSize; + field->pData = (char*)field->pField + field->data_size * (*size); + + if (!pb_make_string_substream(stream, &substream)) + return false; + + while (substream.bytes_left > 0 && *size < field->array_size) { - /* Packed array */ - bool status = true; - pb_istream_t substream; - pb_size_t *size = (pb_size_t*)field->pSize; - field->pData = (char*)field->pField + field->data_size * (*size); - - if (!pb_make_string_substream(stream, &substream)) - return false; - - while (substream.bytes_left > 0 && *size < field->array_size) + if (!decode_basic_field(&substream, PB_WT_PACKED, field)) { - if (!decode_basic_field(&substream, PB_WT_PACKED, field)) - { - status = false; - break; - } - (*size)++; - field->pData = (char*)field->pData + field->data_size; + status = false; + break; } - - if (substream.bytes_left != 0) - PB_RETURN_ERROR(stream, "array overflow"); - if (!pb_close_string_substream(stream, &substream)) - return false; - - return status; - } - else - { - /* Repeated field */ - pb_size_t *size = (pb_size_t*)field->pSize; - field->pData = (char*)field->pField + field->data_size * (*size); - - if ((*size)++ >= field->array_size) - PB_RETURN_ERROR(stream, "array overflow"); - - return decode_basic_field(stream, wire_type, field); + (*size)++; + field->pData = (char*)field->pData + field->data_size; } - case PB_HTYPE_ONEOF: - if (PB_LTYPE_IS_SUBMSG(field->type) && - *(pb_size_t*)field->pSize != field->tag) - { - /* We memset to zero so that any callbacks are set to NULL. - * This is because the callbacks might otherwise have values - * from some other union field. - * If callbacks are needed inside oneof field, use .proto - * option submsg_callback to have a separate callback function - * that can set the fields before submessage is decoded. - * pb_dec_submessage() will set any default values. */ - memset(field->pData, 0, (size_t)field->data_size); + if (substream.bytes_left != 0) + PB_RETURN_ERROR(stream, "array overflow"); + if (!pb_close_string_substream(stream, &substream)) + return false; - /* Set default values for the submessage fields. */ - if (field->submsg_desc->default_value != NULL || - field->submsg_desc->field_callback != NULL || - field->submsg_desc->submsg_info[0] != NULL) + return status; + } + else + { + /* Repeated field */ + pb_size_t* size = (pb_size_t*)field->pSize; + field->pData = (char*)field->pField + field->data_size * (*size); + + if ((*size)++ >= field->array_size) + PB_RETURN_ERROR(stream, "array overflow"); + + return decode_basic_field(stream, wire_type, field); + } + + case PB_HTYPE_ONEOF: + if (PB_LTYPE_IS_SUBMSG(field->type) && + *(pb_size_t*)field->pSize != field->tag) + { + /* We memset to zero so that any callbacks are set to NULL. + * This is because the callbacks might otherwise have values + * from some other union field. + * If callbacks are needed inside oneof field, use .proto + * option submsg_callback to have a separate callback function + * that can set the fields before submessage is decoded. + * pb_dec_submessage() will set any default values. */ + memset(field->pData, 0, (size_t)field->data_size); + + /* Set default values for the submessage fields. */ + if (field->submsg_desc->default_value != NULL || + field->submsg_desc->field_callback != NULL || + field->submsg_desc->submsg_info[0] != NULL) + { + pb_field_iter_t submsg_iter; + if (pb_field_iter_begin(&submsg_iter, field->submsg_desc, field->pData)) { - pb_field_iter_t submsg_iter; - if (pb_field_iter_begin(&submsg_iter, field->submsg_desc, field->pData)) - { - if (!pb_message_set_to_defaults(&submsg_iter)) - PB_RETURN_ERROR(stream, "failed to set defaults"); - } + if (!pb_message_set_to_defaults(&submsg_iter)) + PB_RETURN_ERROR(stream, "failed to set defaults"); } } - *(pb_size_t*)field->pSize = field->tag; + } + *(pb_size_t*)field->pSize = field->tag; - return decode_basic_field(stream, wire_type, field); + return decode_basic_field(stream, wire_type, field); - default: - PB_RETURN_ERROR(stream, "invalid field type"); + default: + PB_RETURN_ERROR(stream, "invalid field type"); } } @@ -580,13 +587,13 @@ static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t * array_size is the number of entries to reserve in an array. * Zero size is not allowed, use pb_free() for releasing. */ -static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size) -{ - void *ptr = *(void**)pData; - +static bool checkreturn allocate_field(pb_istream_t* stream, void* pData, size_t data_size, size_t array_size) +{ + void* ptr = *(void**)pData; + if (data_size == 0 || array_size == 0) PB_RETURN_ERROR(stream, "invalid size"); - + #ifdef __AVR__ /* Workaround for AVR libc bug 53284: http://savannah.nongnu.org/bugs/?53284 * Realloc to size of 1 byte can cause corruption of the malloc structures. @@ -613,20 +620,20 @@ static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t } } } - + /* Allocate new or expand previous allocation */ /* Note: on failure the old pointer will remain in the structure, * the message must be freed by caller also on error return. */ ptr = pb_realloc(ptr, array_size * data_size); if (ptr == NULL) PB_RETURN_ERROR(stream, "realloc failed"); - + *(void**)pData = ptr; return true; } /* Clear a newly allocated item in case it contains a pointer, or is a submessage. */ -static void initialize_pointer_field(void *pItem, pb_field_iter_t *field) +static void initialize_pointer_field(void* pItem, pb_field_iter_t* field) { if (PB_LTYPE(field->type) == PB_LTYPE_STRING || PB_LTYPE(field->type) == PB_LTYPE_BYTES) @@ -642,7 +649,7 @@ static void initialize_pointer_field(void *pItem, pb_field_iter_t *field) } #endif -static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) +static bool checkreturn decode_pointer_field(pb_istream_t* stream, pb_wire_type_t wire_type, pb_field_iter_t* field) { #ifndef PB_ENABLE_MALLOC PB_UNUSED(wire_type); @@ -651,126 +658,125 @@ static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_ #else switch (PB_HTYPE(field->type)) { - case PB_HTYPE_REQUIRED: - case PB_HTYPE_OPTIONAL: - case PB_HTYPE_ONEOF: - if (PB_LTYPE_IS_SUBMSG(field->type) && *(void**)field->pField != NULL) - { - /* Duplicate field, have to release the old allocation first. */ - /* FIXME: Does this work correctly for oneofs? */ - pb_release_single_field(field); - } - - if (PB_HTYPE(field->type) == PB_HTYPE_ONEOF) - { - *(pb_size_t*)field->pSize = field->tag; - } + case PB_HTYPE_REQUIRED: + case PB_HTYPE_OPTIONAL: + case PB_HTYPE_ONEOF: + if (PB_LTYPE_IS_SUBMSG(field->type) && *(void**)field->pField != NULL) + { + /* Duplicate field, have to release the old allocation first. */ + /* FIXME: Does this work correctly for oneofs? */ + pb_release_single_field(field); + } - if (PB_LTYPE(field->type) == PB_LTYPE_STRING || - PB_LTYPE(field->type) == PB_LTYPE_BYTES) - { - /* pb_dec_string and pb_dec_bytes handle allocation themselves */ - field->pData = field->pField; - return decode_basic_field(stream, wire_type, field); - } - else - { - if (!allocate_field(stream, field->pField, field->data_size, 1)) - return false; - - field->pData = *(void**)field->pField; - initialize_pointer_field(field->pData, field); - return decode_basic_field(stream, wire_type, field); - } - - case PB_HTYPE_REPEATED: - if (wire_type == PB_WT_STRING - && PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) - { - /* Packed array, multiple items come in at once. */ - bool status = true; - pb_size_t *size = (pb_size_t*)field->pSize; - size_t allocated_size = *size; - pb_istream_t substream; - - if (!pb_make_string_substream(stream, &substream)) - return false; - - while (substream.bytes_left) - { - if (*size == PB_SIZE_MAX) - { -#ifndef PB_NO_ERRMSG - stream->errmsg = "too many array entries"; -#endif - status = false; - break; - } + if (PB_HTYPE(field->type) == PB_HTYPE_ONEOF) + { + *(pb_size_t*)field->pSize = field->tag; + } - if ((size_t)*size + 1 > allocated_size) - { - /* Allocate more storage. This tries to guess the - * number of remaining entries. Round the division - * upwards. */ - size_t remain = (substream.bytes_left - 1) / field->data_size + 1; - if (remain < PB_SIZE_MAX - allocated_size) - allocated_size += remain; - else - allocated_size += 1; - - if (!allocate_field(&substream, field->pField, field->data_size, allocated_size)) - { - status = false; - break; - } - } + if (PB_LTYPE(field->type) == PB_LTYPE_STRING || + PB_LTYPE(field->type) == PB_LTYPE_BYTES) + { + /* pb_dec_string and pb_dec_bytes handle allocation themselves */ + field->pData = field->pField; + return decode_basic_field(stream, wire_type, field); + } + else + { + if (!allocate_field(stream, field->pField, field->data_size, 1)) + return false; - /* Decode the array entry */ - field->pData = *(char**)field->pField + field->data_size * (*size); - if (field->pData == NULL) - { - /* Shouldn't happen, but satisfies static analyzers */ - status = false; - break; - } - initialize_pointer_field(field->pData, field); - if (!decode_basic_field(&substream, PB_WT_PACKED, field)) - { - status = false; - break; - } - - (*size)++; - } - if (!pb_close_string_substream(stream, &substream)) - return false; - - return status; - } - else + field->pData = *(void**)field->pField; + initialize_pointer_field(field->pData, field); + return decode_basic_field(stream, wire_type, field); + } + + case PB_HTYPE_REPEATED: + if (wire_type == PB_WT_STRING && PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) + { + /* Packed array, multiple items come in at once. */ + bool status = true; + pb_size_t* size = (pb_size_t*)field->pSize; + size_t allocated_size = *size; + pb_istream_t substream; + + if (!pb_make_string_substream(stream, &substream)) + return false; + + while (substream.bytes_left) { - /* Normal repeated field, i.e. only one item at a time. */ - pb_size_t *size = (pb_size_t*)field->pSize; - if (*size == PB_SIZE_MAX) - PB_RETURN_ERROR(stream, "too many array entries"); - - if (!allocate_field(stream, field->pField, field->data_size, (size_t)(*size + 1))) - return false; - - field->pData = *(char**)field->pField + field->data_size * (*size); - (*size)++; - initialize_pointer_field(field->pData, field); - return decode_basic_field(stream, wire_type, field); - } + { +#ifndef PB_NO_ERRMSG + stream->errmsg = "too many array entries"; +#endif + status = false; + break; + } - default: - PB_RETURN_ERROR(stream, "invalid field type"); + if ((size_t)*size + 1 > allocated_size) + { + /* Allocate more storage. This tries to guess the + * number of remaining entries. Round the division + * upwards. */ + size_t remain = (substream.bytes_left - 1) / field->data_size + 1; + if (remain < PB_SIZE_MAX - allocated_size) + allocated_size += remain; + else + allocated_size += 1; + + if (!allocate_field(&substream, field->pField, field->data_size, allocated_size)) + { + status = false; + break; + } + } + + /* Decode the array entry */ + field->pData = *(char**)field->pField + field->data_size * (*size); + if (field->pData == NULL) + { + /* Shouldn't happen, but satisfies static analyzers */ + status = false; + break; + } + initialize_pointer_field(field->pData, field); + if (!decode_basic_field(&substream, PB_WT_PACKED, field)) + { + status = false; + break; + } + + (*size)++; + } + if (!pb_close_string_substream(stream, &substream)) + return false; + + return status; + } + else + { + /* Normal repeated field, i.e. only one item at a time. */ + pb_size_t* size = (pb_size_t*)field->pSize; + + if (*size == PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "too many array entries"); + + if (!allocate_field(stream, field->pField, field->data_size, (size_t)(*size + 1))) + return false; + + field->pData = *(char**)field->pField + field->data_size * (*size); + (*size)++; + initialize_pointer_field(field->pData, field); + return decode_basic_field(stream, wire_type, field); + } + + default: + PB_RETURN_ERROR(stream, "invalid field type"); } #endif } -static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) +static bool checkreturn decode_callback_field(pb_istream_t* stream, pb_wire_type_t wire_type, pb_field_iter_t* field) { if (!field->descriptor->field_callback) return pb_skip_field(stream, wire_type); @@ -779,26 +785,28 @@ static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type { pb_istream_t substream; size_t prev_bytes_left; - + if (!pb_make_string_substream(stream, &substream)) return false; /* If the callback field is inside a submsg, first call the submsg_callback which * should set the decoder for the callback field. */ - if (PB_LTYPE(field->type) == PB_LTYPE_SUBMSG_W_CB && field->pSize != NULL) { + if (PB_LTYPE(field->type) == PB_LTYPE_SUBMSG_W_CB && field->pSize != NULL) + { pb_callback_t* callback; *(pb_size_t*)field->pSize = field->tag; callback = (pb_callback_t*)field->pSize - 1; if (callback->funcs.decode) { - if (!callback->funcs.decode(&substream, field, &callback->arg)) { + if (!callback->funcs.decode(&substream, field, &callback->arg)) + { PB_SET_ERROR(stream, substream.errmsg ? substream.errmsg : "submsg callback failed"); return false; } } } - + do { prev_bytes_left = substream.bytes_left; @@ -808,7 +816,7 @@ static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type return false; } } while (substream.bytes_left > 0 && substream.bytes_left < prev_bytes_left); - + if (!pb_close_string_substream(stream, &substream)) return false; @@ -823,16 +831,16 @@ static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type pb_istream_t substream; pb_byte_t buffer[10]; size_t size = sizeof(buffer); - + if (!read_raw_value(stream, wire_type, buffer, &size)) return false; substream = pb_istream_from_buffer(buffer, size); - + return field->descriptor->field_callback(&substream, NULL, field); } } -static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) +static bool checkreturn decode_field(pb_istream_t* stream, pb_wire_type_t wire_type, pb_field_iter_t* field) { #ifdef PB_ENABLE_MALLOC /* When decoding an oneof field, check if there is old data that must be @@ -846,25 +854,25 @@ static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_t switch (PB_ATYPE(field->type)) { - case PB_ATYPE_STATIC: - return decode_static_field(stream, wire_type, field); - - case PB_ATYPE_POINTER: - return decode_pointer_field(stream, wire_type, field); - - case PB_ATYPE_CALLBACK: - return decode_callback_field(stream, wire_type, field); - - default: - PB_RETURN_ERROR(stream, "invalid field type"); + case PB_ATYPE_STATIC: + return decode_static_field(stream, wire_type, field); + + case PB_ATYPE_POINTER: + return decode_pointer_field(stream, wire_type, field); + + case PB_ATYPE_CALLBACK: + return decode_callback_field(stream, wire_type, field); + + default: + PB_RETURN_ERROR(stream, "invalid field type"); } } /* Default handler for extension fields. Expects to have a pb_msgdesc_t * pointer in the extension->type->arg field, pointing to a message with * only one field in it. */ -static bool checkreturn default_extension_decoder(pb_istream_t *stream, - pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type) +static bool checkreturn default_extension_decoder(pb_istream_t* stream, + pb_extension_t* extension, uint32_t tag, pb_wire_type_t wire_type) { pb_field_iter_t iter; @@ -880,11 +888,11 @@ static bool checkreturn default_extension_decoder(pb_istream_t *stream, /* Try to decode an unknown field as an extension field. Tries each extension * decoder in turn, until one of them handles the field or loop ends. */ -static bool checkreturn decode_extension(pb_istream_t *stream, - uint32_t tag, pb_wire_type_t wire_type, pb_extension_t *extension) +static bool checkreturn decode_extension(pb_istream_t* stream, + uint32_t tag, pb_wire_type_t wire_type, pb_extension_t* extension) { size_t pos = stream->bytes_left; - + while (extension != NULL && pos == stream->bytes_left) { bool status; @@ -895,22 +903,22 @@ static bool checkreturn decode_extension(pb_istream_t *stream, if (!status) return false; - + extension = extension->next; } - + return true; } /* Initialize message fields to default values, recursively */ -static bool pb_field_set_to_default(pb_field_iter_t *field) +static bool pb_field_set_to_default(pb_field_iter_t* field) { pb_type_t type; type = field->type; if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) { - pb_extension_t *ext = *(pb_extension_t* const *)field->pData; + pb_extension_t* ext = *(pb_extension_t* const*)field->pData; while (ext != NULL) { pb_field_iter_t ext_iter; @@ -985,7 +993,7 @@ static bool pb_field_set_to_default(pb_field_iter_t *field) return true; } -static bool pb_message_set_to_defaults(pb_field_iter_t *iter) +static bool pb_message_set_to_defaults(pb_field_iter_t* iter) { pb_istream_t defstream = PB_ISTREAM_EMPTY; uint32_t tag = 0; @@ -1024,14 +1032,14 @@ static bool pb_message_set_to_defaults(pb_field_iter_t *iter) * Decode all fields * *********************/ -static bool checkreturn pb_decode_inner(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct, unsigned int flags) +static bool checkreturn pb_decode_inner(pb_istream_t* stream, const pb_msgdesc_t* fields, void* dest_struct, unsigned int flags) { /* If the message contains extension fields, the extension handlers * are called when tag number is >= extension_range_start. This precheck * is just for speed, and the handlers will check for precise match. */ uint32_t extension_range_start = 0; - pb_extension_t *extensions = NULL; + pb_extension_t* extensions = NULL; /* 'fixed_count_field' and 'fixed_count_size' track position of a repeated fixed * count field. This can only handle _one_ repeated fixed count field that @@ -1066,15 +1074,15 @@ static bool checkreturn pb_decode_inner(pb_istream_t *stream, const pb_msgdesc_t { if (tag == 0) { - if (flags & PB_DECODE_NULLTERMINATED) - { - eof = true; - break; - } - else - { - PB_RETURN_ERROR(stream, "zero tag"); - } + if (flags & PB_DECODE_NULLTERMINATED) + { + eof = true; + break; + } + else + { + PB_RETURN_ERROR(stream, "zero tag"); + } } if (!pb_field_iter_find(&iter, tag) || PB_LTYPE(iter.type) == PB_LTYPE_EXTENSION) @@ -1084,7 +1092,7 @@ static bool checkreturn pb_decode_inner(pb_istream_t *stream, const pb_msgdesc_t { if (pb_field_iter_find_extension(&iter)) { - extensions = *(pb_extension_t* const *)iter.pData; + extensions = *(pb_extension_t* const*)iter.pData; extension_range_start = iter.tag; } @@ -1119,7 +1127,8 @@ static bool checkreturn pb_decode_inner(pb_istream_t *stream, const pb_msgdesc_t */ if (PB_HTYPE(iter.type) == PB_HTYPE_REPEATED && iter.pSize == &iter.array_size) { - if (fixed_count_field != iter.index) { + if (fixed_count_field != iter.index) + { /* If the new fixed count field does not match the previous one, * check that the previous one is NULL or that it finished * receiving all the expected data. @@ -1138,8 +1147,7 @@ static bool checkreturn pb_decode_inner(pb_istream_t *stream, const pb_msgdesc_t iter.pSize = &fixed_count_size; } - if (PB_HTYPE(iter.type) == PB_HTYPE_REQUIRED - && iter.required_field_index < PB_MAX_REQUIRED_FIELDS) + if (PB_HTYPE(iter.type) == PB_HTYPE_REQUIRED && iter.required_field_index < PB_MAX_REQUIRED_FIELDS) { uint32_t tmp = ((uint32_t)1 << (iter.required_field_index & 31)); fields_seen.bitfield[iter.required_field_index >> 5] |= tmp; @@ -1195,35 +1203,35 @@ static bool checkreturn pb_decode_inner(pb_istream_t *stream, const pb_msgdesc_t return true; } -bool checkreturn pb_decode_ex(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct, unsigned int flags) +bool checkreturn pb_decode_ex(pb_istream_t* stream, const pb_msgdesc_t* fields, void* dest_struct, unsigned int flags) { bool status; if ((flags & PB_DECODE_DELIMITED) == 0) { - status = pb_decode_inner(stream, fields, dest_struct, flags); + status = pb_decode_inner(stream, fields, dest_struct, flags); } else { - pb_istream_t substream; - if (!pb_make_string_substream(stream, &substream)) - return false; + pb_istream_t substream; + if (!pb_make_string_substream(stream, &substream)) + return false; - status = pb_decode_inner(&substream, fields, dest_struct, flags); + status = pb_decode_inner(&substream, fields, dest_struct, flags); - if (!pb_close_string_substream(stream, &substream)) - status = false; + if (!pb_close_string_substream(stream, &substream)) + status = false; } - + #ifdef PB_ENABLE_MALLOC if (!status) pb_release(fields, dest_struct); #endif - + return status; } -bool checkreturn pb_decode(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct) +bool checkreturn pb_decode(pb_istream_t* stream, const pb_msgdesc_t* fields, void* dest_struct) { return pb_decode_ex(stream, fields, dest_struct, 0); } @@ -1231,11 +1239,11 @@ bool checkreturn pb_decode(pb_istream_t *stream, const pb_msgdesc_t *fields, voi #ifdef PB_ENABLE_MALLOC /* Given an oneof field, if there has already been a field inside this oneof, * release it before overwriting with a different one. */ -static bool pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *field) +static bool pb_release_union_field(pb_istream_t* stream, pb_field_iter_t* field) { pb_field_iter_t old_field = *field; pb_size_t old_tag = *(pb_size_t*)field->pSize; /* Previous which_ value */ - pb_size_t new_tag = field->tag; /* New which_ value */ + pb_size_t new_tag = field->tag; /* New which_ value */ if (old_tag == 0) return true; /* Ok, no old data in union */ @@ -1261,7 +1269,7 @@ static bool pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *field) return true; } -static void pb_release_single_field(pb_field_iter_t *field) +static void pb_release_single_field(pb_field_iter_t* field) { pb_type_t type; type = field->type; @@ -1278,7 +1286,7 @@ static void pb_release_single_field(pb_field_iter_t *field) if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) { /* Release fields from all extensions in the linked list */ - pb_extension_t *ext = *(pb_extension_t**)field->pData; + pb_extension_t* ext = *(pb_extension_t**)field->pData; while (ext != NULL) { pb_field_iter_t ext_iter; @@ -1293,7 +1301,7 @@ static void pb_release_single_field(pb_field_iter_t *field) { /* Release fields in submessage or submsg array */ pb_size_t count = 1; - + if (PB_ATYPE(type) == PB_ATYPE_POINTER) { field->pData = *(void**)field->pField; @@ -1302,7 +1310,7 @@ static void pb_release_single_field(pb_field_iter_t *field) { field->pData = field->pField; } - + if (PB_HTYPE(type) == PB_HTYPE_REPEATED) { count = *(pb_size_t*)field->pSize; @@ -1313,7 +1321,7 @@ static void pb_release_single_field(pb_field_iter_t *field) count = field->array_size; } } - + if (field->pData) { for (; count > 0; count--) @@ -1323,7 +1331,7 @@ static void pb_release_single_field(pb_field_iter_t *field) } } } - + if (PB_ATYPE(type) == PB_ATYPE_POINTER) { if (PB_HTYPE(type) == PB_HTYPE_REPEATED && @@ -1331,7 +1339,7 @@ static void pb_release_single_field(pb_field_iter_t *field) PB_LTYPE(type) == PB_LTYPE_BYTES)) { /* Release entries in repeated string or bytes array */ - void **pItem = *(void***)field->pField; + void** pItem = *(void***)field->pField; pb_size_t count = *(pb_size_t*)field->pSize; for (; count > 0; count--) { @@ -1339,36 +1347,36 @@ static void pb_release_single_field(pb_field_iter_t *field) *pItem++ = NULL; } } - + if (PB_HTYPE(type) == PB_HTYPE_REPEATED) { /* We are going to release the array, so set the size to 0 */ *(pb_size_t*)field->pSize = 0; } - + /* Release main pointer */ pb_free(*(void**)field->pField); *(void**)field->pField = NULL; } } -void pb_release(const pb_msgdesc_t *fields, void *dest_struct) +void pb_release(const pb_msgdesc_t* fields, void* dest_struct) { pb_field_iter_t iter; - + if (!dest_struct) return; /* Ignore NULL pointers, similar to free() */ if (!pb_field_iter_begin(&iter, fields, dest_struct)) return; /* Empty message type */ - + do { pb_release_single_field(&iter); } while (pb_field_iter_next(&iter)); } #else -void pb_release(const pb_msgdesc_t *fields, void *dest_struct) +void pb_release(const pb_msgdesc_t* fields, void* dest_struct) { /* Nothing to release without PB_ENABLE_MALLOC. */ PB_UNUSED(fields); @@ -1378,7 +1386,7 @@ void pb_release(const pb_msgdesc_t *fields, void *dest_struct) /* Field decoders */ -bool pb_decode_bool(pb_istream_t *stream, bool *dest) +bool pb_decode_bool(pb_istream_t* stream, bool* dest) { uint32_t value; if (!pb_decode_varint32(stream, &value)) @@ -1388,23 +1396,24 @@ bool pb_decode_bool(pb_istream_t *stream, bool *dest) return true; } -bool pb_decode_svarint(pb_istream_t *stream, pb_int64_t *dest) +bool pb_decode_svarint(pb_istream_t* stream, pb_int64_t* dest) { pb_uint64_t value; if (!pb_decode_varint(stream, &value)) return false; - + if (value & 1) *dest = (pb_int64_t)(~(value >> 1)); else *dest = (pb_int64_t)(value >> 1); - + return true; } -bool pb_decode_fixed32(pb_istream_t *stream, void *dest) +bool pb_decode_fixed32(pb_istream_t* stream, void* dest) { - union { + union + { uint32_t fixed32; pb_byte_t bytes[4]; } u; @@ -1425,9 +1434,10 @@ bool pb_decode_fixed32(pb_istream_t *stream, void *dest) } #ifndef PB_WITHOUT_64BIT -bool pb_decode_fixed64(pb_istream_t *stream, void *dest) +bool pb_decode_fixed64(pb_istream_t* stream, void* dest) { - union { + union + { uint64_t fixed64; pb_byte_t bytes[8]; } u; @@ -1452,12 +1462,12 @@ bool pb_decode_fixed64(pb_istream_t *stream, void *dest) } #endif -static bool checkreturn pb_dec_bool(pb_istream_t *stream, const pb_field_iter_t *field) +static bool checkreturn pb_dec_bool(pb_istream_t* stream, const pb_field_iter_t* field) { return pb_decode_bool(stream, (bool*)field->pData); } -static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_iter_t *field) +static bool checkreturn pb_dec_varint(pb_istream_t* stream, const pb_field_iter_t* field) { if (PB_LTYPE(field->type) == PB_LTYPE_UVARINT) { @@ -1499,11 +1509,11 @@ static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_iter_ return false; /* See issue 97: Google's C++ protobuf allows negative varint values to - * be cast as int32_t, instead of the int64_t that should be used when - * encoding. Nanopb versions before 0.2.5 had a bug in encoding. In order to - * not break decoding of such messages, we cast <=32 bit fields to - * int32_t first to get the sign correct. - */ + * be cast as int32_t, instead of the int64_t that should be used when + * encoding. Nanopb versions before 0.2.5 had a bug in encoding. In order to + * not break decoding of such messages, we cast <=32 bit fields to + * int32_t first to get the sign correct. + */ if (field->data_size == sizeof(pb_int64_t)) svalue = (pb_int64_t)value; else @@ -1529,22 +1539,22 @@ static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_iter_ } } -static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_iter_t *field) +static bool checkreturn pb_dec_bytes(pb_istream_t* stream, const pb_field_iter_t* field) { uint32_t size; size_t alloc_size; - pb_bytes_array_t *dest; - + pb_bytes_array_t* dest; + if (!pb_decode_varint32(stream, &size)) return false; - + if (size > PB_SIZE_MAX) PB_RETURN_ERROR(stream, "bytes overflow"); - + alloc_size = PB_BYTES_ARRAY_T_ALLOCSIZE(size); if (size > alloc_size) PB_RETURN_ERROR(stream, "size too large"); - + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) { #ifndef PB_ENABLE_MALLOC @@ -1569,11 +1579,11 @@ static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_iter_t return pb_read(stream, dest->bytes, (size_t)size); } -static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_iter_t *field) +static bool checkreturn pb_dec_string(pb_istream_t* stream, const pb_field_iter_t* field) { uint32_t size; size_t alloc_size; - pb_byte_t *dest = (pb_byte_t*)field->pData; + pb_byte_t* dest = (pb_byte_t*)field->pData; if (!pb_decode_varint32(stream, &size)) return false; @@ -1605,7 +1615,7 @@ static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_iter_ if (alloc_size > field->data_size) PB_RETURN_ERROR(stream, "string overflow"); } - + dest[size] = 0; if (!pb_read(stream, dest, (size_t)size)) @@ -1619,7 +1629,7 @@ static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_iter_ return true; } -static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_iter_t *field) +static bool checkreturn pb_dec_submessage(pb_istream_t* stream, const pb_field_iter_t* field) { bool status = true; bool submsg_consumed = false; @@ -1627,17 +1637,17 @@ static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_i if (!pb_make_string_substream(stream, &substream)) return false; - + if (field->submsg_desc == NULL) PB_RETURN_ERROR(stream, "invalid field descriptor"); - + /* Submessages can have a separate message-level callback that is called * before decoding the message. Typically it is used to set callback fields * inside oneofs. */ if (PB_LTYPE(field->type) == PB_LTYPE_SUBMSG_W_CB && field->pSize != NULL) { /* Message callback is stored right before pSize. */ - pb_callback_t *callback = (pb_callback_t*)field->pSize - 1; + pb_callback_t* callback = (pb_callback_t*)field->pSize - 1; if (callback->funcs.decode) { status = callback->funcs.decode(&substream, field, &callback->arg); @@ -1664,14 +1674,14 @@ static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_i status = pb_decode_inner(&substream, field->submsg_desc, field->pData, flags); } - + if (!pb_close_string_substream(stream, &substream)) return false; return status; } -static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_iter_t *field) +static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t* stream, const pb_field_iter_t* field) { uint32_t size; @@ -1695,13 +1705,17 @@ static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb } #ifdef PB_CONVERT_DOUBLE_FLOAT -bool pb_decode_double_as_float(pb_istream_t *stream, float *dest) +bool pb_decode_double_as_float(pb_istream_t* stream, float* dest) { uint_least8_t sign; int exponent; uint32_t mantissa; uint64_t value; - union { float f; uint32_t i; } out; + union + { + float f; + uint32_t i; + } out; if (!pb_decode_fixed64(stream, &value)) return false; diff --git a/src/chat/infra/meshtastic/generated/pb_decode.h b/src/chat/infra/meshtastic/generated/pb_decode.h index 3f392b29..2c707298 100644 --- a/src/chat/infra/meshtastic/generated/pb_decode.h +++ b/src/chat/infra/meshtastic/generated/pb_decode.h @@ -9,80 +9,87 @@ #include "pb.h" #ifdef __cplusplus -extern "C" { -#endif - -/* Structure for defining custom input streams. You will need to provide - * a callback function to read the bytes from your storage, which can be - * for example a file or a network socket. - * - * The callback must conform to these rules: - * - * 1) Return false on IO errors. This will cause decoding to abort. - * 2) You can use state to store your own data (e.g. buffer pointer), - * and rely on pb_read to verify that no-body reads past bytes_left. - * 3) Your callback may be used with substreams, in which case bytes_left - * is different than from the main stream. Don't use bytes_left to compute - * any pointers. - */ -struct pb_istream_s +extern "C" { +#endif + + /* Structure for defining custom input streams. You will need to provide + * a callback function to read the bytes from your storage, which can be + * for example a file or a network socket. + * + * The callback must conform to these rules: + * + * 1) Return false on IO errors. This will cause decoding to abort. + * 2) You can use state to store your own data (e.g. buffer pointer), + * and rely on pb_read to verify that no-body reads past bytes_left. + * 3) Your callback may be used with substreams, in which case bytes_left + * is different than from the main stream. Don't use bytes_left to compute + * any pointers. + */ + struct pb_istream_s + { #ifdef PB_BUFFER_ONLY - /* Callback pointer is not used in buffer-only configuration. - * Having an int pointer here allows binary compatibility but - * gives an error if someone tries to assign callback function. - */ - int *callback; + /* Callback pointer is not used in buffer-only configuration. + * Having an int pointer here allows binary compatibility but + * gives an error if someone tries to assign callback function. + */ + int* callback; #else - bool (*callback)(pb_istream_t *stream, pb_byte_t *buf, size_t count); + bool (*callback)(pb_istream_t* stream, pb_byte_t* buf, size_t count); #endif - /* state is a free field for use of the callback function defined above. - * Note that when pb_istream_from_buffer() is used, it reserves this field - * for its own use. - */ - void *state; + /* state is a free field for use of the callback function defined above. + * Note that when pb_istream_from_buffer() is used, it reserves this field + * for its own use. + */ + void* state; - /* Maximum number of bytes left in this stream. Callback can report - * EOF before this limit is reached. Setting a limit is recommended - * when decoding directly from file or network streams to avoid - * denial-of-service by excessively long messages. - */ - size_t bytes_left; - -#ifndef PB_NO_ERRMSG - /* Pointer to constant (ROM) string when decoding function returns error */ - const char *errmsg; -#endif -}; + /* Maximum number of bytes left in this stream. Callback can report + * EOF before this limit is reached. Setting a limit is recommended + * when decoding directly from file or network streams to avoid + * denial-of-service by excessively long messages. + */ + size_t bytes_left; #ifndef PB_NO_ERRMSG -#define PB_ISTREAM_EMPTY {0,0,0,0} + /* Pointer to constant (ROM) string when decoding function returns error */ + const char* errmsg; +#endif + }; + +#ifndef PB_NO_ERRMSG +#define PB_ISTREAM_EMPTY \ + { \ + 0, 0, 0, 0 \ + } #else -#define PB_ISTREAM_EMPTY {0,0,0} +#define PB_ISTREAM_EMPTY \ + { \ + 0, 0, 0 \ + } #endif -/*************************** - * Main decoding functions * - ***************************/ - -/* Decode a single protocol buffers message from input stream into a C structure. - * Returns true on success, false on any failure. - * The actual struct pointed to by dest must match the description in fields. - * Callback fields of the destination structure must be initialized by caller. - * All other fields will be initialized by this function. - * - * Example usage: - * MyMessage msg = {}; - * uint8_t buffer[64]; - * pb_istream_t stream; - * - * // ... read some data into buffer ... - * - * stream = pb_istream_from_buffer(buffer, count); - * pb_decode(&stream, MyMessage_fields, &msg); - */ -bool pb_decode(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct); + /*************************** + * Main decoding functions * + ***************************/ + + /* Decode a single protocol buffers message from input stream into a C structure. + * Returns true on success, false on any failure. + * The actual struct pointed to by dest must match the description in fields. + * Callback fields of the destination structure must be initialized by caller. + * All other fields will be initialized by this function. + * + * Example usage: + * MyMessage msg = {}; + * uint8_t buffer[64]; + * pb_istream_t stream; + * + * // ... read some data into buffer ... + * + * stream = pb_istream_from_buffer(buffer, count); + * pb_decode(&stream, MyMessage_fields, &msg); + */ + bool pb_decode(pb_istream_t* stream, const pb_msgdesc_t* fields, void* dest_struct); /* Extended version of pb_decode, with several options to control * the decoding process: @@ -107,95 +114,94 @@ bool pb_decode(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_stru * * Multiple flags can be combined with bitwise or (| operator) */ -#define PB_DECODE_NOINIT 0x01U -#define PB_DECODE_DELIMITED 0x02U -#define PB_DECODE_NULLTERMINATED 0x04U -bool pb_decode_ex(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct, unsigned int flags); +#define PB_DECODE_NOINIT 0x01U +#define PB_DECODE_DELIMITED 0x02U +#define PB_DECODE_NULLTERMINATED 0x04U + bool pb_decode_ex(pb_istream_t* stream, const pb_msgdesc_t* fields, void* dest_struct, unsigned int flags); /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ -#define pb_decode_noinit(s,f,d) pb_decode_ex(s,f,d, PB_DECODE_NOINIT) -#define pb_decode_delimited(s,f,d) pb_decode_ex(s,f,d, PB_DECODE_DELIMITED) -#define pb_decode_delimited_noinit(s,f,d) pb_decode_ex(s,f,d, PB_DECODE_DELIMITED | PB_DECODE_NOINIT) -#define pb_decode_nullterminated(s,f,d) pb_decode_ex(s,f,d, PB_DECODE_NULLTERMINATED) +#define pb_decode_noinit(s, f, d) pb_decode_ex(s, f, d, PB_DECODE_NOINIT) +#define pb_decode_delimited(s, f, d) pb_decode_ex(s, f, d, PB_DECODE_DELIMITED) +#define pb_decode_delimited_noinit(s, f, d) pb_decode_ex(s, f, d, PB_DECODE_DELIMITED | PB_DECODE_NOINIT) +#define pb_decode_nullterminated(s, f, d) pb_decode_ex(s, f, d, PB_DECODE_NULLTERMINATED) -/* Release any allocated pointer fields. If you use dynamic allocation, you should - * call this for any successfully decoded message when you are done with it. If - * pb_decode() returns with an error, the message is already released. - */ -void pb_release(const pb_msgdesc_t *fields, void *dest_struct); + /* Release any allocated pointer fields. If you use dynamic allocation, you should + * call this for any successfully decoded message when you are done with it. If + * pb_decode() returns with an error, the message is already released. + */ + void pb_release(const pb_msgdesc_t* fields, void* dest_struct); -/************************************** - * Functions for manipulating streams * - **************************************/ + /************************************** + * Functions for manipulating streams * + **************************************/ -/* Create an input stream for reading from a memory buffer. - * - * msglen should be the actual length of the message, not the full size of - * allocated buffer. - * - * Alternatively, you can use a custom stream that reads directly from e.g. - * a file or a network socket. - */ -pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t msglen); + /* Create an input stream for reading from a memory buffer. + * + * msglen should be the actual length of the message, not the full size of + * allocated buffer. + * + * Alternatively, you can use a custom stream that reads directly from e.g. + * a file or a network socket. + */ + pb_istream_t pb_istream_from_buffer(const pb_byte_t* buf, size_t msglen); -/* Function to read from a pb_istream_t. You can use this if you need to - * read some custom header data, or to read data in field callbacks. - */ -bool pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); + /* Function to read from a pb_istream_t. You can use this if you need to + * read some custom header data, or to read data in field callbacks. + */ + bool pb_read(pb_istream_t* stream, pb_byte_t* buf, size_t count); + /************************************************ + * Helper functions for writing field callbacks * + ************************************************/ -/************************************************ - * Helper functions for writing field callbacks * - ************************************************/ + /* Decode the tag for the next field in the stream. Gives the wire type and + * field tag. At end of the message, returns false and sets eof to true. */ + bool pb_decode_tag(pb_istream_t* stream, pb_wire_type_t* wire_type, uint32_t* tag, bool* eof); -/* Decode the tag for the next field in the stream. Gives the wire type and - * field tag. At end of the message, returns false and sets eof to true. */ -bool pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof); - -/* Skip the field payload data, given the wire type. */ -bool pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type); + /* Skip the field payload data, given the wire type. */ + bool pb_skip_field(pb_istream_t* stream, pb_wire_type_t wire_type); /* Decode an integer in the varint format. This works for enum, int32, * int64, uint32 and uint64 field types. */ #ifndef PB_WITHOUT_64BIT -bool pb_decode_varint(pb_istream_t *stream, uint64_t *dest); + bool pb_decode_varint(pb_istream_t* stream, uint64_t* dest); #else #define pb_decode_varint pb_decode_varint32 #endif -/* Decode an integer in the varint format. This works for enum, int32, - * and uint32 field types. */ -bool pb_decode_varint32(pb_istream_t *stream, uint32_t *dest); + /* Decode an integer in the varint format. This works for enum, int32, + * and uint32 field types. */ + bool pb_decode_varint32(pb_istream_t* stream, uint32_t* dest); -/* Decode a bool value in varint format. */ -bool pb_decode_bool(pb_istream_t *stream, bool *dest); + /* Decode a bool value in varint format. */ + bool pb_decode_bool(pb_istream_t* stream, bool* dest); /* Decode an integer in the zig-zagged svarint format. This works for sint32 * and sint64. */ #ifndef PB_WITHOUT_64BIT -bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest); + bool pb_decode_svarint(pb_istream_t* stream, int64_t* dest); #else -bool pb_decode_svarint(pb_istream_t *stream, int32_t *dest); +bool pb_decode_svarint(pb_istream_t* stream, int32_t* dest); #endif -/* Decode a fixed32, sfixed32 or float value. You need to pass a pointer to - * a 4-byte wide C variable. */ -bool pb_decode_fixed32(pb_istream_t *stream, void *dest); + /* Decode a fixed32, sfixed32 or float value. You need to pass a pointer to + * a 4-byte wide C variable. */ + bool pb_decode_fixed32(pb_istream_t* stream, void* dest); #ifndef PB_WITHOUT_64BIT -/* Decode a fixed64, sfixed64 or double value. You need to pass a pointer to - * a 8-byte wide C variable. */ -bool pb_decode_fixed64(pb_istream_t *stream, void *dest); + /* Decode a fixed64, sfixed64 or double value. You need to pass a pointer to + * a 8-byte wide C variable. */ + bool pb_decode_fixed64(pb_istream_t* stream, void* dest); #endif #ifdef PB_CONVERT_DOUBLE_FLOAT -/* Decode a double value into float variable. */ -bool pb_decode_double_as_float(pb_istream_t *stream, float *dest); + /* Decode a double value into float variable. */ + bool pb_decode_double_as_float(pb_istream_t* stream, float* dest); #endif -/* Make a limited-length substream for reading a PB_WT_STRING field. */ -bool pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream); -bool pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream); + /* Make a limited-length substream for reading a PB_WT_STRING field. */ + bool pb_make_string_substream(pb_istream_t* stream, pb_istream_t* substream); + bool pb_close_string_substream(pb_istream_t* stream, pb_istream_t* substream); #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/pb_encode.c b/src/chat/infra/meshtastic/generated/pb_encode.c index 4a6f49c5..17632e06 100644 --- a/src/chat/infra/meshtastic/generated/pb_encode.c +++ b/src/chat/infra/meshtastic/generated/pb_encode.c @@ -3,8 +3,8 @@ * 2011 Petteri Aimonen */ -#include "pb.h" #include "pb_encode.h" +#include "pb.h" #include "pb_common.h" /* Use the GCC warn_unused_result attribute to check that all return values @@ -13,30 +13,30 @@ */ #if (defined(__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))) || \ (defined(__IAR_SYSTEMS_ICC__) && (__VER__ >= 9040001)) - #define checkreturn __attribute__((warn_unused_result)) +#define checkreturn __attribute__((warn_unused_result)) #else - #define checkreturn +#define checkreturn #endif /************************************** * Declarations internal to this file * **************************************/ -static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); -static bool checkreturn encode_array(pb_ostream_t *stream, pb_field_iter_t *field); -static bool checkreturn pb_check_proto3_default_value(const pb_field_iter_t *field); -static bool checkreturn encode_basic_field(pb_ostream_t *stream, const pb_field_iter_t *field); -static bool checkreturn encode_callback_field(pb_ostream_t *stream, const pb_field_iter_t *field); -static bool checkreturn encode_field(pb_ostream_t *stream, pb_field_iter_t *field); -static pb_noinline bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_iter_t *field); -static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension); -static bool checkreturn pb_encode_varint_32(pb_ostream_t *stream, uint32_t low, uint32_t high); -static bool checkreturn pb_enc_bool(pb_ostream_t *stream, const pb_field_iter_t *field); -static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_iter_t *field); -static bool checkreturn pb_enc_fixed(pb_ostream_t *stream, const pb_field_iter_t *field); -static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_iter_t *field); -static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_iter_t *field); -static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_iter_t *field); -static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_iter_t *field); +static bool checkreturn buf_write(pb_ostream_t* stream, const pb_byte_t* buf, size_t count); +static bool checkreturn encode_array(pb_ostream_t* stream, pb_field_iter_t* field); +static bool checkreturn pb_check_proto3_default_value(const pb_field_iter_t* field); +static bool checkreturn encode_basic_field(pb_ostream_t* stream, const pb_field_iter_t* field); +static bool checkreturn encode_callback_field(pb_ostream_t* stream, const pb_field_iter_t* field); +static bool checkreturn encode_field(pb_ostream_t* stream, pb_field_iter_t* field); +static pb_noinline bool checkreturn encode_extension_field(pb_ostream_t* stream, const pb_field_iter_t* field); +static bool checkreturn default_extension_encoder(pb_ostream_t* stream, const pb_extension_t* extension); +static bool checkreturn pb_encode_varint_32(pb_ostream_t* stream, uint32_t low, uint32_t high); +static bool checkreturn pb_enc_bool(pb_ostream_t* stream, const pb_field_iter_t* field); +static bool checkreturn pb_enc_varint(pb_ostream_t* stream, const pb_field_iter_t* field); +static bool checkreturn pb_enc_fixed(pb_ostream_t* stream, const pb_field_iter_t* field); +static bool checkreturn pb_enc_bytes(pb_ostream_t* stream, const pb_field_iter_t* field); +static bool checkreturn pb_enc_string(pb_ostream_t* stream, const pb_field_iter_t* field); +static bool checkreturn pb_enc_submessage(pb_ostream_t* stream, const pb_field_iter_t* field); +static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t* stream, const pb_field_iter_t* field); #ifdef PB_WITHOUT_64BIT #define pb_int64_t int32_t @@ -50,17 +50,17 @@ static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb * pb_ostream_t implementation * *******************************/ -static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count) +static bool checkreturn buf_write(pb_ostream_t* stream, const pb_byte_t* buf, size_t count) { - pb_byte_t *dest = (pb_byte_t*)stream->state; + pb_byte_t* dest = (pb_byte_t*)stream->state; stream->state = dest + count; - + memcpy(dest, buf, count * sizeof(pb_byte_t)); - + return true; } -pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize) +pb_ostream_t pb_ostream_from_buffer(pb_byte_t* buf, size_t bufsize) { pb_ostream_t stream; #ifdef PB_BUFFER_ONLY @@ -81,7 +81,7 @@ pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize) return stream; } -bool checkreturn pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count) +bool checkreturn pb_write(pb_ostream_t* stream, const pb_byte_t* buf, size_t count) { if (count > 0 && stream->callback != NULL) { @@ -94,12 +94,12 @@ bool checkreturn pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t cou #ifdef PB_BUFFER_ONLY if (!buf_write(stream, buf, count)) PB_RETURN_ERROR(stream, "io error"); -#else +#else if (!stream->callback(stream, buf, count)) PB_RETURN_ERROR(stream, "io error"); #endif } - + stream->bytes_written += count; return true; } @@ -112,9 +112,9 @@ bool checkreturn pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t cou * is invalid. See issue #434 and * https://stackoverflow.com/questions/27661768/weird-results-for-conditional */ -static bool safe_read_bool(const void *pSize) +static bool safe_read_bool(const void* pSize) { - const char *p = (const char *)pSize; + const char* p = (const char*)pSize; size_t i; for (i = 0; i < sizeof(bool); i++) { @@ -125,7 +125,7 @@ static bool safe_read_bool(const void *pSize) } /* Encode a static array. Handles the size calculations and possible packing. */ -static bool checkreturn encode_array(pb_ostream_t *stream, pb_field_iter_t *field) +static bool checkreturn encode_array(pb_ostream_t* stream, pb_field_iter_t* field) { pb_size_t i; pb_size_t count; @@ -140,14 +140,14 @@ static bool checkreturn encode_array(pb_ostream_t *stream, pb_field_iter_t *fiel if (PB_ATYPE(field->type) != PB_ATYPE_POINTER && count > field->array_size) PB_RETURN_ERROR(stream, "array max size exceeded"); - + #ifndef PB_ENCODE_ARRAYS_UNPACKED /* We always pack arrays if the datatype allows it. */ if (PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) { if (!pb_encode_tag(stream, PB_WT_STRING, field->tag)) return false; - + /* Determine the total size of packed array. */ if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32) { @@ -158,9 +158,9 @@ static bool checkreturn encode_array(pb_ostream_t *stream, pb_field_iter_t *fiel size = 8 * (size_t)count; } else - { + { pb_ostream_t sizestream = PB_OSTREAM_SIZING; - void *pData_orig = field->pData; + void* pData_orig = field->pData; for (i = 0; i < count; i++) { if (!pb_enc_varint(&sizestream, field)) @@ -170,13 +170,13 @@ static bool checkreturn encode_array(pb_ostream_t *stream, pb_field_iter_t *fiel field->pData = pData_orig; size = sizestream.bytes_written; } - + if (!pb_encode_varint(stream, (pb_uint64_t)size)) return false; - + if (stream->callback == NULL) return pb_write(stream, NULL, size); /* Just sizing.. */ - + /* Write the data */ for (i = 0; i < count; i++) { @@ -208,7 +208,7 @@ static bool checkreturn encode_array(pb_ostream_t *stream, pb_field_iter_t *fiel PB_LTYPE(field->type) == PB_LTYPE_BYTES)) { bool status; - void *pData_orig = field->pData; + void* pData_orig = field->pData; field->pData = *(void* const*)field->pData; if (!field->pData) @@ -235,13 +235,13 @@ static bool checkreturn encode_array(pb_ostream_t *stream, pb_field_iter_t *fiel field->pData = (char*)field->pData + field->data_size; } } - + return true; } /* In proto3, all fields are optional and are only encoded if their value is "non-zero". * This function implements the check for the zero value. */ -static bool checkreturn pb_check_proto3_default_value(const pb_field_iter_t *field) +static bool checkreturn pb_check_proto3_default_value(const pb_field_iter_t* field) { pb_type_t type = field->type; @@ -283,7 +283,7 @@ static bool checkreturn pb_check_proto3_default_value(const pb_field_iter_t *fie { /* Simple integer / float fields */ pb_size_t i; - const char *p = (const char*)field->pData; + const char* p = (const char*)field->pData; for (i = 0; i < field->data_size; i++) { if (p[i] != 0) @@ -296,7 +296,7 @@ static bool checkreturn pb_check_proto3_default_value(const pb_field_iter_t *fie } else if (PB_LTYPE(type) == PB_LTYPE_BYTES) { - const pb_bytes_array_t *bytes = (const pb_bytes_array_t*)field->pData; + const pb_bytes_array_t* bytes = (const pb_bytes_array_t*)field->pData; return bytes->size == 0; } else if (PB_LTYPE(type) == PB_LTYPE_STRING) @@ -340,12 +340,12 @@ static bool checkreturn pb_check_proto3_default_value(const pb_field_iter_t *fie { if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) { - const pb_extension_t *extension = *(const pb_extension_t* const *)field->pData; + const pb_extension_t* extension = *(const pb_extension_t* const*)field->pData; return extension == NULL; } else if (field->descriptor->field_callback == pb_default_field_callback) { - pb_callback_t *pCallback = (pb_callback_t*)field->pData; + pb_callback_t* pCallback = (pb_callback_t*)field->pData; return pCallback->funcs.encode == NULL; } else @@ -359,7 +359,7 @@ static bool checkreturn pb_check_proto3_default_value(const pb_field_iter_t *fie /* Encode a field with static or pointer allocation, i.e. one whose data * is available to the encoder directly. */ -static bool checkreturn encode_basic_field(pb_ostream_t *stream, const pb_field_iter_t *field) +static bool checkreturn encode_basic_field(pb_ostream_t* stream, const pb_field_iter_t* field) { if (!field->pData) { @@ -372,39 +372,39 @@ static bool checkreturn encode_basic_field(pb_ostream_t *stream, const pb_field_ switch (PB_LTYPE(field->type)) { - case PB_LTYPE_BOOL: - return pb_enc_bool(stream, field); + case PB_LTYPE_BOOL: + return pb_enc_bool(stream, field); - case PB_LTYPE_VARINT: - case PB_LTYPE_UVARINT: - case PB_LTYPE_SVARINT: - return pb_enc_varint(stream, field); + case PB_LTYPE_VARINT: + case PB_LTYPE_UVARINT: + case PB_LTYPE_SVARINT: + return pb_enc_varint(stream, field); - case PB_LTYPE_FIXED32: - case PB_LTYPE_FIXED64: - return pb_enc_fixed(stream, field); + case PB_LTYPE_FIXED32: + case PB_LTYPE_FIXED64: + return pb_enc_fixed(stream, field); - case PB_LTYPE_BYTES: - return pb_enc_bytes(stream, field); + case PB_LTYPE_BYTES: + return pb_enc_bytes(stream, field); - case PB_LTYPE_STRING: - return pb_enc_string(stream, field); + case PB_LTYPE_STRING: + return pb_enc_string(stream, field); - case PB_LTYPE_SUBMESSAGE: - case PB_LTYPE_SUBMSG_W_CB: - return pb_enc_submessage(stream, field); + case PB_LTYPE_SUBMESSAGE: + case PB_LTYPE_SUBMSG_W_CB: + return pb_enc_submessage(stream, field); - case PB_LTYPE_FIXED_LENGTH_BYTES: - return pb_enc_fixed_length_bytes(stream, field); + case PB_LTYPE_FIXED_LENGTH_BYTES: + return pb_enc_fixed_length_bytes(stream, field); - default: - PB_RETURN_ERROR(stream, "invalid field type"); + default: + PB_RETURN_ERROR(stream, "invalid field type"); } } /* Encode a field with callback semantics. This means that a user function is * called to provide and encode the actual data. */ -static bool checkreturn encode_callback_field(pb_ostream_t *stream, const pb_field_iter_t *field) +static bool checkreturn encode_callback_field(pb_ostream_t* stream, const pb_field_iter_t* field) { if (field->descriptor->field_callback != NULL) { @@ -415,7 +415,7 @@ static bool checkreturn encode_callback_field(pb_ostream_t *stream, const pb_fie } /* Encode a single field of any callback, pointer or static type. */ -static bool checkreturn encode_field(pb_ostream_t *stream, pb_field_iter_t *field) +static bool checkreturn encode_field(pb_ostream_t* stream, pb_field_iter_t* field) { /* Check field presence */ if (PB_HTYPE(field->type) == PB_HTYPE_ONEOF) @@ -471,7 +471,7 @@ static bool checkreturn encode_field(pb_ostream_t *stream, pb_field_iter_t *fiel /* Default handler for extension fields. Expects to have a pb_msgdesc_t * pointer in the extension->type->arg field, pointing to a message with * only one field in it. */ -static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension) +static bool checkreturn default_extension_encoder(pb_ostream_t* stream, const pb_extension_t* extension) { pb_field_iter_t iter; @@ -481,12 +481,11 @@ static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb return encode_field(stream, &iter); } - /* Walk through all the registered extensions and give them a chance * to encode themselves. */ -static pb_noinline bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_iter_t *field) +static pb_noinline bool checkreturn encode_extension_field(pb_ostream_t* stream, const pb_field_iter_t* field) { - const pb_extension_t *extension = *(const pb_extension_t* const *)field->pData; + const pb_extension_t* extension = *(const pb_extension_t* const*)field->pData; while (extension) { @@ -498,10 +497,10 @@ static pb_noinline bool checkreturn encode_extension_field(pb_ostream_t *stream, if (!status) return false; - + extension = extension->next; } - + return true; } @@ -509,13 +508,14 @@ static pb_noinline bool checkreturn encode_extension_field(pb_ostream_t *stream, * Encode all fields * *********************/ -bool checkreturn pb_encode(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct) +bool checkreturn pb_encode(pb_ostream_t* stream, const pb_msgdesc_t* fields, const void* src_struct) { pb_field_iter_t iter; if (!pb_field_iter_begin_const(&iter, fields, src_struct)) return true; /* Empty message type */ - - do { + + do + { if (PB_LTYPE(iter.type) == PB_LTYPE_EXTENSION) { /* Special case for the extension field placeholder */ @@ -529,38 +529,38 @@ bool checkreturn pb_encode(pb_ostream_t *stream, const pb_msgdesc_t *fields, con return false; } } while (pb_field_iter_next(&iter)); - + return true; } -bool checkreturn pb_encode_ex(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct, unsigned int flags) +bool checkreturn pb_encode_ex(pb_ostream_t* stream, const pb_msgdesc_t* fields, const void* src_struct, unsigned int flags) { - if ((flags & PB_ENCODE_DELIMITED) != 0) - { - return pb_encode_submessage(stream, fields, src_struct); - } - else if ((flags & PB_ENCODE_NULLTERMINATED) != 0) - { - const pb_byte_t zero = 0; + if ((flags & PB_ENCODE_DELIMITED) != 0) + { + return pb_encode_submessage(stream, fields, src_struct); + } + else if ((flags & PB_ENCODE_NULLTERMINATED) != 0) + { + const pb_byte_t zero = 0; - if (!pb_encode(stream, fields, src_struct)) - return false; + if (!pb_encode(stream, fields, src_struct)) + return false; - return pb_write(stream, &zero, 1); - } - else - { - return pb_encode(stream, fields, src_struct); - } + return pb_write(stream, &zero, 1); + } + else + { + return pb_encode(stream, fields, src_struct); + } } -bool pb_get_encoded_size(size_t *size, const pb_msgdesc_t *fields, const void *src_struct) +bool pb_get_encoded_size(size_t* size, const pb_msgdesc_t* fields, const void* src_struct) { pb_ostream_t stream = PB_OSTREAM_SIZING; - + if (!pb_encode(&stream, fields, src_struct)) return false; - + *size = stream.bytes_written; return true; } @@ -570,7 +570,7 @@ bool pb_get_encoded_size(size_t *size, const pb_msgdesc_t *fields, const void *s ********************/ /* This function avoids 64-bit shifts as they are quite slow on many platforms. */ -static bool checkreturn pb_encode_varint_32(pb_ostream_t *stream, uint32_t low, uint32_t high) +static bool checkreturn pb_encode_varint_32(pb_ostream_t* stream, uint32_t low, uint32_t high) { size_t i = 0; pb_byte_t buffer[10]; @@ -604,7 +604,7 @@ static bool checkreturn pb_encode_varint_32(pb_ostream_t *stream, uint32_t low, return pb_write(stream, buffer, i); } -bool checkreturn pb_encode_varint(pb_ostream_t *stream, pb_uint64_t value) +bool checkreturn pb_encode_varint(pb_ostream_t* stream, pb_uint64_t value) { if (value <= 0x7F) { @@ -622,7 +622,7 @@ bool checkreturn pb_encode_varint(pb_ostream_t *stream, pb_uint64_t value) } } -bool checkreturn pb_encode_svarint(pb_ostream_t *stream, pb_int64_t value) +bool checkreturn pb_encode_svarint(pb_ostream_t* stream, pb_int64_t value) { pb_uint64_t zigzagged; pb_uint64_t mask = ((pb_uint64_t)-1) >> 1; /* Satisfy clang -fsanitize=integer */ @@ -630,11 +630,11 @@ bool checkreturn pb_encode_svarint(pb_ostream_t *stream, pb_int64_t value) zigzagged = ~(((pb_uint64_t)value & mask) << 1); else zigzagged = (pb_uint64_t)value << 1; - + return pb_encode_varint(stream, zigzagged); } -bool checkreturn pb_encode_fixed32(pb_ostream_t *stream, const void *value) +bool checkreturn pb_encode_fixed32(pb_ostream_t* stream, const void* value) { #if defined(PB_LITTLE_ENDIAN_8BIT) && PB_LITTLE_ENDIAN_8BIT == 1 /* Fast path if we know that we're on little endian */ @@ -651,7 +651,7 @@ bool checkreturn pb_encode_fixed32(pb_ostream_t *stream, const void *value) } #ifndef PB_WITHOUT_64BIT -bool checkreturn pb_encode_fixed64(pb_ostream_t *stream, const void *value) +bool checkreturn pb_encode_fixed64(pb_ostream_t* stream, const void* value) { #if defined(PB_LITTLE_ENDIAN_8BIT) && PB_LITTLE_ENDIAN_8BIT == 1 /* Fast path if we know that we're on little endian */ @@ -672,56 +672,56 @@ bool checkreturn pb_encode_fixed64(pb_ostream_t *stream, const void *value) } #endif -bool checkreturn pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number) +bool checkreturn pb_encode_tag(pb_ostream_t* stream, pb_wire_type_t wiretype, uint32_t field_number) { pb_uint64_t tag = ((pb_uint64_t)field_number << 3) | wiretype; return pb_encode_varint(stream, tag); } -bool pb_encode_tag_for_field ( pb_ostream_t* stream, const pb_field_iter_t* field ) +bool pb_encode_tag_for_field(pb_ostream_t* stream, const pb_field_iter_t* field) { pb_wire_type_t wiretype; switch (PB_LTYPE(field->type)) { - case PB_LTYPE_BOOL: - case PB_LTYPE_VARINT: - case PB_LTYPE_UVARINT: - case PB_LTYPE_SVARINT: - wiretype = PB_WT_VARINT; - break; - - case PB_LTYPE_FIXED32: - wiretype = PB_WT_32BIT; - break; - - case PB_LTYPE_FIXED64: - wiretype = PB_WT_64BIT; - break; - - case PB_LTYPE_BYTES: - case PB_LTYPE_STRING: - case PB_LTYPE_SUBMESSAGE: - case PB_LTYPE_SUBMSG_W_CB: - case PB_LTYPE_FIXED_LENGTH_BYTES: - wiretype = PB_WT_STRING; - break; - - default: - PB_RETURN_ERROR(stream, "invalid field type"); + case PB_LTYPE_BOOL: + case PB_LTYPE_VARINT: + case PB_LTYPE_UVARINT: + case PB_LTYPE_SVARINT: + wiretype = PB_WT_VARINT; + break; + + case PB_LTYPE_FIXED32: + wiretype = PB_WT_32BIT; + break; + + case PB_LTYPE_FIXED64: + wiretype = PB_WT_64BIT; + break; + + case PB_LTYPE_BYTES: + case PB_LTYPE_STRING: + case PB_LTYPE_SUBMESSAGE: + case PB_LTYPE_SUBMSG_W_CB: + case PB_LTYPE_FIXED_LENGTH_BYTES: + wiretype = PB_WT_STRING; + break; + + default: + PB_RETURN_ERROR(stream, "invalid field type"); } - + return pb_encode_tag(stream, wiretype, field->tag); } -bool checkreturn pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size) +bool checkreturn pb_encode_string(pb_ostream_t* stream, const pb_byte_t* buffer, size_t size) { if (!pb_encode_varint(stream, (pb_uint64_t)size)) return false; - + return pb_write(stream, buffer, size); } -bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct) +bool checkreturn pb_encode_submessage(pb_ostream_t* stream, const pb_msgdesc_t* fields, const void* src_struct) { /* First calculate the message size using a non-writing substream. */ pb_ostream_t substream = PB_OSTREAM_SIZING; @@ -729,7 +729,7 @@ bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_msgdesc_t * bool status; size_t size; #endif - + if (!pb_encode(&substream, fields, src_struct)) { #ifndef PB_NO_ERRMSG @@ -737,16 +737,16 @@ bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_msgdesc_t * #endif return false; } - + if (!pb_encode_varint(stream, (pb_uint64_t)substream.bytes_written)) return false; - + if (stream->callback == NULL) return pb_write(stream, NULL, substream.bytes_written); /* Just sizing */ - + if (stream->bytes_written + substream.bytes_written > stream->max_size) PB_RETURN_ERROR(stream, "stream full"); - + #if defined(PB_NO_ENCODE_SIZE_CHECK) && PB_NO_ENCODE_SIZE_CHECK == 1 return pb_encode(stream, fields, src_struct); #else @@ -760,15 +760,15 @@ bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_msgdesc_t * #ifndef PB_NO_ERRMSG substream.errmsg = NULL; #endif - + status = pb_encode(&substream, fields, src_struct); - + stream->bytes_written += substream.bytes_written; stream->state = substream.state; #ifndef PB_NO_ERRMSG stream->errmsg = substream.errmsg; #endif - + if (substream.bytes_written != size) PB_RETURN_ERROR(stream, "submsg size changed"); @@ -778,14 +778,14 @@ bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_msgdesc_t * /* Field encoders */ -static bool checkreturn pb_enc_bool(pb_ostream_t *stream, const pb_field_iter_t *field) +static bool checkreturn pb_enc_bool(pb_ostream_t* stream, const pb_field_iter_t* field) { uint32_t value = safe_read_bool(field->pData) ? 1 : 0; PB_UNUSED(field); return pb_encode_varint(stream, value); } -static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_iter_t *field) +static bool checkreturn pb_enc_varint(pb_ostream_t* stream, const pb_field_iter_t* field) { if (PB_LTYPE(field->type) == PB_LTYPE_UVARINT) { @@ -829,11 +829,10 @@ static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_iter_ #endif else return pb_encode_varint(stream, (pb_uint64_t)value); - } } -static bool checkreturn pb_enc_fixed(pb_ostream_t *stream, const pb_field_iter_t *field) +static bool checkreturn pb_enc_fixed(pb_ostream_t* stream, const pb_field_iter_t* field) { #ifdef PB_CONVERT_DOUBLE_FLOAT if (field->data_size == sizeof(float) && PB_LTYPE(field->type) == PB_LTYPE_FIXED64) @@ -858,33 +857,33 @@ static bool checkreturn pb_enc_fixed(pb_ostream_t *stream, const pb_field_iter_t } } -static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_iter_t *field) +static bool checkreturn pb_enc_bytes(pb_ostream_t* stream, const pb_field_iter_t* field) { - const pb_bytes_array_t *bytes = NULL; + const pb_bytes_array_t* bytes = NULL; bytes = (const pb_bytes_array_t*)field->pData; - + if (bytes == NULL) { /* Treat null pointer as an empty bytes field */ return pb_encode_string(stream, NULL, 0); } - + if (PB_ATYPE(field->type) == PB_ATYPE_STATIC && bytes->size > field->data_size - offsetof(pb_bytes_array_t, bytes)) { PB_RETURN_ERROR(stream, "bytes size exceeded"); } - + return pb_encode_string(stream, bytes->bytes, (size_t)bytes->size); } -static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_iter_t *field) +static bool checkreturn pb_enc_string(pb_ostream_t* stream, const pb_field_iter_t* field) { size_t size = 0; size_t max_size = (size_t)field->data_size; - const char *str = (const char*)field->pData; - + const char* str = (const char*)field->pData; + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) { max_size = (size_t)-1; @@ -902,14 +901,13 @@ static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_iter_ max_size -= 1; } - if (str == NULL) { size = 0; /* Treat null pointer as an empty string */ } else { - const char *p = str; + const char* p = str; /* strnlen() is not always available, so just use a loop */ while (size < max_size && *p != '\0') @@ -932,7 +930,7 @@ static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_iter_ return pb_encode_string(stream, (const pb_byte_t*)str, size); } -static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_iter_t *field) +static bool checkreturn pb_enc_submessage(pb_ostream_t* stream, const pb_field_iter_t* field) { if (field->submsg_desc == NULL) PB_RETURN_ERROR(stream, "invalid field descriptor"); @@ -940,26 +938,30 @@ static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_i if (PB_LTYPE(field->type) == PB_LTYPE_SUBMSG_W_CB && field->pSize != NULL) { /* Message callback is stored right before pSize. */ - pb_callback_t *callback = (pb_callback_t*)field->pSize - 1; + pb_callback_t* callback = (pb_callback_t*)field->pSize - 1; if (callback->funcs.encode) { if (!callback->funcs.encode(stream, field, &callback->arg)) return false; } } - + return pb_encode_submessage(stream, field->submsg_desc, field->pData); } -static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_iter_t *field) +static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t* stream, const pb_field_iter_t* field) { return pb_encode_string(stream, (const pb_byte_t*)field->pData, (size_t)field->data_size); } #ifdef PB_CONVERT_DOUBLE_FLOAT -bool pb_encode_float_as_double(pb_ostream_t *stream, float value) +bool pb_encode_float_as_double(pb_ostream_t* stream, float value) { - union { float f; uint32_t i; } in; + union + { + float f; + uint32_t i; + } in; uint_least8_t sign; int exponent; uint64_t mantissa; diff --git a/src/chat/infra/meshtastic/generated/pb_encode.h b/src/chat/infra/meshtastic/generated/pb_encode.h index 6dc089da..6772960d 100644 --- a/src/chat/infra/meshtastic/generated/pb_encode.h +++ b/src/chat/infra/meshtastic/generated/pb_encode.h @@ -9,72 +9,73 @@ #include "pb.h" #ifdef __cplusplus -extern "C" { -#endif - -/* Structure for defining custom output streams. You will need to provide - * a callback function to write the bytes to your storage, which can be - * for example a file or a network socket. - * - * The callback must conform to these rules: - * - * 1) Return false on IO errors. This will cause encoding to abort. - * 2) You can use state to store your own data (e.g. buffer pointer). - * 3) pb_write will update bytes_written after your callback runs. - * 4) Substreams will modify max_size and bytes_written. Don't use them - * to calculate any pointers. - */ -struct pb_ostream_s +extern "C" { +#endif + + /* Structure for defining custom output streams. You will need to provide + * a callback function to write the bytes to your storage, which can be + * for example a file or a network socket. + * + * The callback must conform to these rules: + * + * 1) Return false on IO errors. This will cause encoding to abort. + * 2) You can use state to store your own data (e.g. buffer pointer). + * 3) pb_write will update bytes_written after your callback runs. + * 4) Substreams will modify max_size and bytes_written. Don't use them + * to calculate any pointers. + */ + struct pb_ostream_s + { #ifdef PB_BUFFER_ONLY - /* Callback pointer is not used in buffer-only configuration. - * Having an int pointer here allows binary compatibility but - * gives an error if someone tries to assign callback function. - * Also, NULL pointer marks a 'sizing stream' that does not - * write anything. - */ - const int *callback; + /* Callback pointer is not used in buffer-only configuration. + * Having an int pointer here allows binary compatibility but + * gives an error if someone tries to assign callback function. + * Also, NULL pointer marks a 'sizing stream' that does not + * write anything. + */ + const int* callback; #else - bool (*callback)(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); + bool (*callback)(pb_ostream_t* stream, const pb_byte_t* buf, size_t count); #endif - /* state is a free field for use of the callback function defined above. - * Note that when pb_ostream_from_buffer() is used, it reserves this field - * for its own use. - */ - void *state; + /* state is a free field for use of the callback function defined above. + * Note that when pb_ostream_from_buffer() is used, it reserves this field + * for its own use. + */ + void* state; - /* Limit number of output bytes written. Can be set to SIZE_MAX. */ - size_t max_size; + /* Limit number of output bytes written. Can be set to SIZE_MAX. */ + size_t max_size; + + /* Number of bytes written so far. */ + size_t bytes_written; - /* Number of bytes written so far. */ - size_t bytes_written; - #ifndef PB_NO_ERRMSG - /* Pointer to constant (ROM) string when decoding function returns error */ - const char *errmsg; + /* Pointer to constant (ROM) string when decoding function returns error */ + const char* errmsg; #endif -}; + }; -/*************************** - * Main encoding functions * - ***************************/ + /*************************** + * Main encoding functions * + ***************************/ -/* Encode a single protocol buffers message from C structure into a stream. - * Returns true on success, false on any failure. - * The actual struct pointed to by src_struct must match the description in fields. - * All required fields in the struct are assumed to have been filled in. - * - * Example usage: - * MyMessage msg = {}; - * uint8_t buffer[64]; - * pb_ostream_t stream; - * - * msg.field1 = 42; - * stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); - * pb_encode(&stream, MyMessage_fields, &msg); - */ -bool pb_encode(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct); + /* Encode a single protocol buffers message from C structure into a stream. + * Returns true on success, false on any failure. + * The actual struct pointed to by src_struct must match the description in fields. + * All required fields in the struct are assumed to have been filled in. + * + * Example usage: + * MyMessage msg = {}; + * uint8_t buffer[64]; + * pb_ostream_t stream; + * + * msg.field1 = 42; + * stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + * pb_encode(&stream, MyMessage_fields, &msg); + */ + bool pb_encode(pb_ostream_t* stream, const pb_msgdesc_t* fields, const void* src_struct); /* Extended version of pb_encode, with several options to control the * encoding process: @@ -88,34 +89,34 @@ bool pb_encode(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src * protobuf implementations, so PB_ENCODE_DELIMITED * is a better option for compatibility. */ -#define PB_ENCODE_DELIMITED 0x02U -#define PB_ENCODE_NULLTERMINATED 0x04U -bool pb_encode_ex(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct, unsigned int flags); +#define PB_ENCODE_DELIMITED 0x02U +#define PB_ENCODE_NULLTERMINATED 0x04U + bool pb_encode_ex(pb_ostream_t* stream, const pb_msgdesc_t* fields, const void* src_struct, unsigned int flags); /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ -#define pb_encode_delimited(s,f,d) pb_encode_ex(s,f,d, PB_ENCODE_DELIMITED) -#define pb_encode_nullterminated(s,f,d) pb_encode_ex(s,f,d, PB_ENCODE_NULLTERMINATED) +#define pb_encode_delimited(s, f, d) pb_encode_ex(s, f, d, PB_ENCODE_DELIMITED) +#define pb_encode_nullterminated(s, f, d) pb_encode_ex(s, f, d, PB_ENCODE_NULLTERMINATED) -/* Encode the message to get the size of the encoded data, but do not store - * the data. */ -bool pb_get_encoded_size(size_t *size, const pb_msgdesc_t *fields, const void *src_struct); + /* Encode the message to get the size of the encoded data, but do not store + * the data. */ + bool pb_get_encoded_size(size_t* size, const pb_msgdesc_t* fields, const void* src_struct); -/************************************** - * Functions for manipulating streams * - **************************************/ + /************************************** + * Functions for manipulating streams * + **************************************/ -/* Create an output stream for writing into a memory buffer. - * The number of bytes written can be found in stream.bytes_written after - * encoding the message. - * - * Alternatively, you can use a custom stream that writes directly to e.g. - * a file or a network socket. - */ -pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize); + /* Create an output stream for writing into a memory buffer. + * The number of bytes written can be found in stream.bytes_written after + * encoding the message. + * + * Alternatively, you can use a custom stream that writes directly to e.g. + * a file or a network socket. + */ + pb_ostream_t pb_ostream_from_buffer(pb_byte_t* buf, size_t bufsize); /* Pseudo-stream for measuring the size of a message without actually storing * the encoded data. - * + * * Example usage: * MyMessage msg = {}; * pb_ostream_t stream = PB_OSTREAM_SIZING; @@ -123,70 +124,75 @@ pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize); * printf("Message size is %d\n", stream.bytes_written); */ #ifndef PB_NO_ERRMSG -#define PB_OSTREAM_SIZING {0,0,0,0,0} +#define PB_OSTREAM_SIZING \ + { \ + 0, 0, 0, 0, 0 \ + } #else -#define PB_OSTREAM_SIZING {0,0,0,0} +#define PB_OSTREAM_SIZING \ + { \ + 0, 0, 0, 0 \ + } #endif -/* Function to write into a pb_ostream_t stream. You can use this if you need - * to append or prepend some custom headers to the message. - */ -bool pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); + /* Function to write into a pb_ostream_t stream. You can use this if you need + * to append or prepend some custom headers to the message. + */ + bool pb_write(pb_ostream_t* stream, const pb_byte_t* buf, size_t count); + /************************************************ + * Helper functions for writing field callbacks * + ************************************************/ -/************************************************ - * Helper functions for writing field callbacks * - ************************************************/ + /* Encode field header based on type and field number defined in the field + * structure. Call this from the callback before writing out field contents. */ + bool pb_encode_tag_for_field(pb_ostream_t* stream, const pb_field_iter_t* field); -/* Encode field header based on type and field number defined in the field - * structure. Call this from the callback before writing out field contents. */ -bool pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_iter_t *field); - -/* Encode field header by manually specifying wire type. You need to use this - * if you want to write out packed arrays from a callback field. */ -bool pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number); + /* Encode field header by manually specifying wire type. You need to use this + * if you want to write out packed arrays from a callback field. */ + bool pb_encode_tag(pb_ostream_t* stream, pb_wire_type_t wiretype, uint32_t field_number); /* Encode an integer in the varint format. * This works for bool, enum, int32, int64, uint32 and uint64 field types. */ #ifndef PB_WITHOUT_64BIT -bool pb_encode_varint(pb_ostream_t *stream, uint64_t value); + bool pb_encode_varint(pb_ostream_t* stream, uint64_t value); #else -bool pb_encode_varint(pb_ostream_t *stream, uint32_t value); +bool pb_encode_varint(pb_ostream_t* stream, uint32_t value); #endif /* Encode an integer in the zig-zagged svarint format. * This works for sint32 and sint64. */ #ifndef PB_WITHOUT_64BIT -bool pb_encode_svarint(pb_ostream_t *stream, int64_t value); + bool pb_encode_svarint(pb_ostream_t* stream, int64_t value); #else -bool pb_encode_svarint(pb_ostream_t *stream, int32_t value); +bool pb_encode_svarint(pb_ostream_t* stream, int32_t value); #endif -/* Encode a string or bytes type field. For strings, pass strlen(s) as size. */ -bool pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size); + /* Encode a string or bytes type field. For strings, pass strlen(s) as size. */ + bool pb_encode_string(pb_ostream_t* stream, const pb_byte_t* buffer, size_t size); -/* Encode a fixed32, sfixed32 or float value. - * You need to pass a pointer to a 4-byte wide C variable. */ -bool pb_encode_fixed32(pb_ostream_t *stream, const void *value); + /* Encode a fixed32, sfixed32 or float value. + * You need to pass a pointer to a 4-byte wide C variable. */ + bool pb_encode_fixed32(pb_ostream_t* stream, const void* value); #ifndef PB_WITHOUT_64BIT -/* Encode a fixed64, sfixed64 or double value. - * You need to pass a pointer to a 8-byte wide C variable. */ -bool pb_encode_fixed64(pb_ostream_t *stream, const void *value); + /* Encode a fixed64, sfixed64 or double value. + * You need to pass a pointer to a 8-byte wide C variable. */ + bool pb_encode_fixed64(pb_ostream_t* stream, const void* value); #endif #ifdef PB_CONVERT_DOUBLE_FLOAT -/* Encode a float value so that it appears like a double in the encoded - * message. */ -bool pb_encode_float_as_double(pb_ostream_t *stream, float value); + /* Encode a float value so that it appears like a double in the encoded + * message. */ + bool pb_encode_float_as_double(pb_ostream_t* stream, float value); #endif -/* Encode a submessage field. - * You need to pass the pb_field_t array and pointer to struct, just like - * with pb_encode(). This internally encodes the submessage twice, first to - * calculate message size and then to actually write it out. - */ -bool pb_encode_submessage(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct); + /* Encode a submessage field. + * You need to pass the pb_field_t array and pointer to struct, just like + * with pb_encode(). This internally encodes the submessage twice, first to + * calculate message size and then to actually write it out. + */ + bool pb_encode_submessage(pb_ostream_t* stream, const pb_msgdesc_t* fields, const void* src_struct); #ifdef __cplusplus } /* extern "C" */ diff --git a/src/chat/infra/meshtastic/generated/proto_util.h b/src/chat/infra/meshtastic/generated/proto_util.h index 4f98393c..7d9bfa4a 100644 --- a/src/chat/infra/meshtastic/generated/proto_util.h +++ b/src/chat/infra/meshtastic/generated/proto_util.h @@ -7,12 +7,16 @@ inline void pb_put_varint(std::string& out, uint64_t v) { - while (true) { + while (true) + { uint8_t b = v & 0x7F; v >>= 7; - if (v) { + if (v) + { out.push_back(b | 0x80); - } else { + } + else + { out.push_back(b); break; } @@ -31,10 +35,12 @@ inline bool pb_read_varint(const uint8_t* buf, size_t len, size_t& off, uint64_t { uint64_t v = 0; int shift = 0; - while (off < len && shift < 64) { + while (off < len && shift < 64) + { uint8_t b = buf[off++]; v |= (uint64_t)(b & 0x7F) << shift; - if ((b & 0x80) == 0) { + if ((b & 0x80) == 0) + { out = v; return true; } diff --git a/src/chat/infra/meshtastic/mt_adapter.cpp b/src/chat/infra/meshtastic/mt_adapter.cpp index 5c0a9d25..b574cc1d 100644 --- a/src/chat/infra/meshtastic/mt_adapter.cpp +++ b/src/chat/infra/meshtastic/mt_adapter.cpp @@ -5,20 +5,22 @@ #include "mt_adapter.h" #include "../../../sys/event_bus.h" -#include +#include "../../domain/contact_types.h" #include -#include -#include -#include #include +#include +#include +#include +#include #define TEST_CURVE25519_FIELD_OPS -#include -#include -#include -#include -#include #include "../../../board/TLoRaPagerTypes.h" #include "generated/meshtastic/config.pb.h" +#include "mt_region.h" +#include +#include +#include +#include +#include #ifndef LORA_LOG_ENABLE #define LORA_LOG_ENABLE 1 @@ -27,10 +29,14 @@ #if LORA_LOG_ENABLE #define LORA_LOG(...) Serial.printf(__VA_ARGS__) #else -#define LORA_LOG(...) do {} while (0) +#define LORA_LOG(...) \ + do \ + { \ + } while (0) #endif -namespace { +namespace +{ constexpr uint8_t kDefaultPsk[16] = {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0x01}; constexpr uint8_t kDefaultPskIndex = 1; @@ -40,50 +46,47 @@ constexpr uint8_t kLoraSyncWord = 0x2b; constexpr uint16_t kLoraPreambleLen = 16; constexpr uint8_t kBitfieldWantResponseMask = 0x02; -static const char* portName(uint32_t portnum) { - switch (portnum) { - case meshtastic_PortNum_TEXT_MESSAGE_APP: return "TEXT"; - case meshtastic_PortNum_TEXT_MESSAGE_COMPRESSED_APP: return "TEXT_COMP"; - case meshtastic_PortNum_NODEINFO_APP: return "NODEINFO"; - case meshtastic_PortNum_POSITION_APP: return "POSITION"; - case meshtastic_PortNum_TELEMETRY_APP: return "TELEMETRY"; - case meshtastic_PortNum_REMOTE_HARDWARE_APP: return "REMOTEHW"; - case meshtastic_PortNum_TRACEROUTE_APP: return "TRACEROUTE"; - case meshtastic_PortNum_WAYPOINT_APP: return "WAYPOINT"; - default: return "UNKNOWN"; +static const char* portName(uint32_t portnum) +{ + switch (portnum) + { + case meshtastic_PortNum_TEXT_MESSAGE_APP: + return "TEXT"; + case meshtastic_PortNum_TEXT_MESSAGE_COMPRESSED_APP: + return "TEXT_COMP"; + case meshtastic_PortNum_NODEINFO_APP: + return "NODEINFO"; + case meshtastic_PortNum_POSITION_APP: + return "POSITION"; + case meshtastic_PortNum_TELEMETRY_APP: + return "TELEMETRY"; + case meshtastic_PortNum_REMOTE_HARDWARE_APP: + return "REMOTEHW"; + case meshtastic_PortNum_TRACEROUTE_APP: + return "TRACEROUTE"; + case meshtastic_PortNum_WAYPOINT_APP: + return "WAYPOINT"; + default: + return "UNKNOWN"; } } -struct RegionInfo { - meshtastic_Config_LoRaConfig_RegionCode code; - float freq_start_mhz; - float freq_end_mhz; - float spacing_khz; - bool wide_lora; -}; - -const RegionInfo kRegions[] = { - {meshtastic_Config_LoRaConfig_RegionCode_CN, 470.0f, 510.0f, 0.0f, false}, - {meshtastic_Config_LoRaConfig_RegionCode_US, 902.0f, 928.0f, 0.0f, false}, - {meshtastic_Config_LoRaConfig_RegionCode_EU_868, 869.4f, 869.65f, 0.0f, false}, - {meshtastic_Config_LoRaConfig_RegionCode_EU_433, 433.0f, 434.0f, 0.0f, false}, - {meshtastic_Config_LoRaConfig_RegionCode_JP, 920.5f, 923.5f, 0.0f, false}, - {meshtastic_Config_LoRaConfig_RegionCode_ANZ, 915.0f, 928.0f, 0.0f, false}, - {meshtastic_Config_LoRaConfig_RegionCode_IN, 865.0f, 867.0f, 0.0f, false}, - {meshtastic_Config_LoRaConfig_RegionCode_UNSET, 902.0f, 928.0f, 0.0f, false}, -}; - -uint8_t xorHash(const uint8_t* data, size_t len) { +uint8_t xorHash(const uint8_t* data, size_t len) +{ uint8_t out = 0; - for (size_t i = 0; i < len; ++i) { + for (size_t i = 0; i < len; ++i) + { out ^= data[i]; } return out; } -void expandShortPsk(uint8_t index, uint8_t* out, size_t* out_len) { - if (!out || !out_len || index == 0) { - if (out_len) { +void expandShortPsk(uint8_t index, uint8_t* out, size_t* out_len) +{ + if (!out || !out_len || index == 0) + { + if (out_len) + { *out_len = 0; } return; @@ -94,154 +97,118 @@ void expandShortPsk(uint8_t index, uint8_t* out, size_t* out_len) { *out_len = sizeof(kDefaultPsk); } -bool isZeroKey(const uint8_t* key, size_t len) { +bool isZeroKey(const uint8_t* key, size_t len) +{ if (!key || len == 0) return true; - for (size_t i = 0; i < len; ++i) { + for (size_t i = 0; i < len; ++i) + { if (key[i] != 0) return false; } return true; } -uint8_t computeChannelHash(const char* name, const uint8_t* key, size_t key_len) { +uint8_t computeChannelHash(const char* name, const uint8_t* key, size_t key_len) +{ uint8_t h = xorHash(reinterpret_cast(name), strlen(name)); - if (key && key_len > 0) { + if (key && key_len > 0) + { h ^= xorHash(key, key_len); } return h; } -std::string toHex(const uint8_t* data, size_t len, size_t max_len = 64) { - if (!data || len == 0) { +std::string toHex(const uint8_t* data, size_t len, size_t max_len = 64) +{ + if (!data || len == 0) + { return {}; } size_t capped = (len > max_len) ? max_len : len; static const char* kHex = "0123456789ABCDEF"; std::string out; out.reserve(capped * 2); - for (size_t i = 0; i < capped; ++i) { + for (size_t i = 0; i < capped; ++i) + { uint8_t b = data[i]; out.push_back(kHex[b >> 4]); out.push_back(kHex[b & 0x0F]); } - if (capped < len) { + if (capped < len) + { out.append(".."); } return out; } -uint32_t djb2Hash(const char* str) { - uint32_t hash = 5381; - int c; - while ((c = *str++) != 0) { - hash = ((hash << 5) + hash) + static_cast(c); - } - return hash; -} - -const RegionInfo* findRegion(meshtastic_Config_LoRaConfig_RegionCode code) { - for (const auto& region : kRegions) { - if (region.code == code) { - return ®ion; - } - } - return &kRegions[0]; -} - -const char* presetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset) { - switch (preset) { - case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST: - return "LongFast"; - case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE: - return "LongModerate"; - case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW: - return "LongSlow"; - case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW: - return "MediumSlow"; - case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST: - return "MediumFast"; - case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW: - return "ShortSlow"; - case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST: - return "ShortFast"; - case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO: - return "ShortTurbo"; - default: - return "LongFast"; - } -} - -float computeFrequencyMhz(const RegionInfo* region, float bw_khz, const char* channel_name) { - if (!region || !channel_name) { - return 0.0f; - } - float bw_mhz = bw_khz / 1000.0f; - float spacing_mhz = region->spacing_khz / 1000.0f; - float span_mhz = region->freq_end_mhz - region->freq_start_mhz; - uint32_t num_channels = static_cast(floor(span_mhz / (spacing_mhz + bw_mhz))); - if (num_channels < 1) { - num_channels = 1; - } - uint32_t channel_num = djb2Hash(channel_name) % num_channels; - return region->freq_start_mhz + (bw_khz / 2000.0f) + (channel_num * (bw_khz / 1000.0f)); -} - constexpr size_t kAesBlockSize = 16; -class AesCcmCipher { -public: - ~AesCcmCipher() { +class AesCcmCipher +{ + public: + ~AesCcmCipher() + { delete aes_; } - void setKey(const uint8_t* key, size_t key_len) { + void setKey(const uint8_t* key, size_t key_len) + { delete aes_; aes_ = nullptr; - if (key_len != 0) { + if (key_len != 0) + { aes_ = new AESSmall256(); aes_->setKey(key, key_len); } } - void encryptBlock(uint8_t* out, const uint8_t* in) { - if (!aes_) { + void encryptBlock(uint8_t* out, const uint8_t* in) + { + if (!aes_) + { memset(out, 0, kAesBlockSize); return; } aes_->encryptBlock(out, in); } -private: + private: AESSmall256* aes_ = nullptr; }; static AesCcmCipher g_aes_ccm; -static int constant_time_compare(const void* a_, const void* b_, size_t len) { +static int constant_time_compare(const void* a_, const void* b_, size_t len) +{ const volatile uint8_t* volatile a = (const volatile uint8_t* volatile)a_; const volatile uint8_t* volatile b = (const volatile uint8_t* volatile)b_; if (len == 0) return 0; if (!a || !b) return -1; volatile uint8_t d = 0U; - for (size_t i = 0; i < len; ++i) { + for (size_t i = 0; i < len; ++i) + { d |= (a[i] ^ b[i]); } return (1 & ((d - 1) >> 8)) - 1; } -static void put_be16(uint8_t* a, uint16_t val) { +static void put_be16(uint8_t* a, uint16_t val) +{ a[0] = val >> 8; a[1] = val & 0xff; } -static void xor_aes_block(uint8_t* dst, const uint8_t* src) { - for (size_t i = 0; i < kAesBlockSize; ++i) { +static void xor_aes_block(uint8_t* dst, const uint8_t* src) +{ + for (size_t i = 0; i < kAesBlockSize; ++i) + { dst[i] ^= src[i]; } } static void aes_ccm_auth_start(size_t m, size_t l, const uint8_t* nonce, const uint8_t* aad, size_t aad_len, size_t plain_len, - uint8_t* x) { + uint8_t* x) +{ uint8_t aad_buf[2 * kAesBlockSize]; uint8_t b[kAesBlockSize]; b[0] = aad_len ? 0x40 : 0; @@ -256,78 +223,95 @@ static void aes_ccm_auth_start(size_t m, size_t l, const uint8_t* nonce, memset(aad_buf + 2 + aad_len, 0, sizeof(aad_buf) - 2 - aad_len); xor_aes_block(aad_buf, x); g_aes_ccm.encryptBlock(x, aad_buf); - if (aad_len > kAesBlockSize - 2) { + if (aad_len > kAesBlockSize - 2) + { xor_aes_block(&aad_buf[kAesBlockSize], x); g_aes_ccm.encryptBlock(x, &aad_buf[kAesBlockSize]); } } -static void aes_ccm_auth(const uint8_t* data, size_t len, uint8_t* x) { +static void aes_ccm_auth(const uint8_t* data, size_t len, uint8_t* x) +{ size_t last = len % kAesBlockSize; - for (size_t i = 0; i < len / kAesBlockSize; ++i) { + for (size_t i = 0; i < len / kAesBlockSize; ++i) + { xor_aes_block(x, data); data += kAesBlockSize; g_aes_ccm.encryptBlock(x, x); } - if (last) { - for (size_t i = 0; i < last; ++i) { + if (last) + { + for (size_t i = 0; i < last; ++i) + { x[i] ^= *data++; } g_aes_ccm.encryptBlock(x, x); } } -static void aes_ccm_encr_start(size_t l, const uint8_t* nonce, uint8_t* a) { +static void aes_ccm_encr_start(size_t l, const uint8_t* nonce, uint8_t* a) +{ a[0] = l - 1; memcpy(&a[1], nonce, 15 - l); } -static void aes_ccm_encr(size_t l, const uint8_t* in, size_t len, uint8_t* out, uint8_t* a) { +static void aes_ccm_encr(size_t l, const uint8_t* in, size_t len, uint8_t* out, uint8_t* a) +{ size_t last = len % kAesBlockSize; size_t i = 0; - for (i = 1; i <= len / kAesBlockSize; ++i) { + for (i = 1; i <= len / kAesBlockSize; ++i) + { put_be16(&a[kAesBlockSize - 2], i); g_aes_ccm.encryptBlock(out, a); xor_aes_block(out, in); out += kAesBlockSize; in += kAesBlockSize; } - if (last) { + if (last) + { put_be16(&a[kAesBlockSize - 2], i); g_aes_ccm.encryptBlock(out, a); - for (size_t j = 0; j < last; ++j) { + for (size_t j = 0; j < last; ++j) + { *out++ ^= *in++; } } } -static void aes_ccm_encr_auth(size_t m, const uint8_t* x, uint8_t* a, uint8_t* auth) { +static void aes_ccm_encr_auth(size_t m, const uint8_t* x, uint8_t* a, uint8_t* auth) +{ uint8_t tmp[kAesBlockSize]; put_be16(&a[kAesBlockSize - 2], 0); g_aes_ccm.encryptBlock(tmp, a); - for (size_t i = 0; i < m; ++i) { + for (size_t i = 0; i < m; ++i) + { auth[i] = x[i] ^ tmp[i]; } } -static void aes_ccm_decr_auth(size_t m, uint8_t* a, const uint8_t* auth, uint8_t* t) { +static void aes_ccm_decr_auth(size_t m, uint8_t* a, const uint8_t* auth, uint8_t* t) +{ uint8_t tmp[kAesBlockSize]; put_be16(&a[kAesBlockSize - 2], 0); g_aes_ccm.encryptBlock(tmp, a); - for (size_t i = 0; i < m; ++i) { + for (size_t i = 0; i < m; ++i) + { t[i] = auth[i] ^ tmp[i]; } } -static void hashSharedKey(uint8_t* bytes, size_t num_bytes) { +static void hashSharedKey(uint8_t* bytes, size_t num_bytes) +{ SHA256 hash; size_t posn; uint8_t size = static_cast(num_bytes); uint8_t inc = 16; hash.reset(); - for (posn = 0; posn < size; posn += inc) { + for (posn = 0; posn < size; posn += inc) + { size_t len = size - posn; - if (len > inc) { + if (len > inc) + { len = inc; } hash.update(bytes + posn, len); @@ -337,7 +321,8 @@ static void hashSharedKey(uint8_t* bytes, size_t num_bytes) { static bool aes_ccm_ad(const uint8_t* key, size_t key_len, const uint8_t* nonce, size_t m, const uint8_t* crypt, size_t crypt_len, const uint8_t* aad, - size_t aad_len, const uint8_t* auth, uint8_t* plain) { + size_t aad_len, const uint8_t* auth, uint8_t* plain) +{ const size_t l = 2; uint8_t x[kAesBlockSize]; uint8_t a[kAesBlockSize]; @@ -352,27 +337,31 @@ static bool aes_ccm_ad(const uint8_t* key, size_t key_len, const uint8_t* nonce, return constant_time_compare(x, t, m) == 0; } -static void initPkiNonce(uint32_t from, uint64_t packet_id, uint32_t extra_nonce, uint8_t* nonce_out) { +static void initPkiNonce(uint32_t from, uint64_t packet_id, uint32_t extra_nonce, uint8_t* nonce_out) +{ memset(nonce_out, 0, kAesBlockSize); memcpy(nonce_out, &packet_id, sizeof(packet_id)); memcpy(nonce_out + sizeof(packet_id), &from, sizeof(from)); - if (extra_nonce) { + if (extra_nonce) + { memcpy(nonce_out + sizeof(uint32_t), &extra_nonce, sizeof(extra_nonce)); } } } // namespace // Use protobuf codec and wire packet functions -using chat::meshtastic::encodeTextMessage; -using chat::meshtastic::encodeNodeInfoMessage; -using chat::meshtastic::decodeTextMessage; using chat::meshtastic::buildWirePacket; -using chat::meshtastic::parseWirePacket; +using chat::meshtastic::decodeTextMessage; using chat::meshtastic::decryptPayload; +using chat::meshtastic::encodeNodeInfoMessage; +using chat::meshtastic::encodeTextMessage; using chat::meshtastic::PacketHeaderWire; +using chat::meshtastic::parseWirePacket; -namespace chat { -namespace meshtastic { +namespace chat +{ +namespace meshtastic +{ MtAdapter::MtAdapter(TLoRaPagerBoard& board) : board_(board), @@ -389,22 +378,28 @@ MtAdapter::MtAdapter(TLoRaPagerBoard& board) secondary_psk_len_(0), pki_ready_(false), pki_public_key_{}, - pki_private_key_{} { + pki_private_key_{}, + last_raw_packet_len_(0), + has_pending_raw_packet_(false) +{ config_ = MeshConfig(); // Default config initNodeIdentity(); initPkiKeys(); updateChannelKeys(); } -MtAdapter::~MtAdapter() { +MtAdapter::~MtAdapter() +{ } -bool MtAdapter::sendText(ChannelId channel, const std::string& text, - MessageId* out_msg_id, NodeId peer) { - if (!ready_ || text.empty()) { +bool MtAdapter::sendText(ChannelId channel, const std::string& text, + MessageId* out_msg_id, NodeId peer) +{ + if (!ready_ || text.empty()) + { return false; } - + PendingSend pending; pending.channel = channel; pending.text = text; @@ -412,51 +407,90 @@ bool MtAdapter::sendText(ChannelId channel, const std::string& text, pending.dest = (peer != 0) ? peer : 0xFFFFFFFF; pending.retry_count = 0; pending.last_attempt = 0; - + send_queue_.push(pending); LORA_LOG("[LORA] queue text ch=%u len=%u id=%lu\n", static_cast(channel), static_cast(text.size()), static_cast(pending.msg_id)); - - if (out_msg_id) { + + if (out_msg_id) + { *out_msg_id = pending.msg_id; } - + return true; } -bool MtAdapter::pollIncomingText(MeshIncomingText* out) { - if (receive_queue_.empty()) { +bool MtAdapter::pollIncomingText(MeshIncomingText* out) +{ + if (receive_queue_.empty()) + { return false; } - + *out = receive_queue_.front(); receive_queue_.pop(); return true; } -void MtAdapter::applyConfig(const MeshConfig& config) { +void MtAdapter::applyConfig(const MeshConfig& config) +{ config_ = config; updateChannelKeys(); configureRadio(); } -bool MtAdapter::isReady() const { +bool MtAdapter::isReady() const +{ return ready_ && board_.isHardwareOnline(HW_RADIO_ONLINE); } -void MtAdapter::processReceivedPacket(const uint8_t* data, size_t size) { - if (!data || size == 0) { +bool MtAdapter::pollIncomingRawPacket(uint8_t* out_data, size_t& out_len, size_t max_len) +{ + if (!has_pending_raw_packet_ || !out_data || max_len == 0) + { + return false; + } + + // Copy the stored raw packet data + size_t copy_len = (last_raw_packet_len_ < max_len) ? last_raw_packet_len_ : max_len; + memcpy(out_data, last_raw_packet_, copy_len); + out_len = copy_len; + + // Mark as consumed + has_pending_raw_packet_ = false; + + return true; +} + +void MtAdapter::handleRawPacket(const uint8_t* data, size_t size) +{ + processReceivedPacket(data, size); +} + +void MtAdapter::processReceivedPacket(const uint8_t* data, size_t size) +{ + if (!data || size == 0) + { return; } - + + // Store raw packet data for protocol detection + if (size <= sizeof(last_raw_packet_)) + { + memcpy(last_raw_packet_, data, size); + last_raw_packet_len_ = size; + has_pending_raw_packet_ = true; + } + // Parse wire packet header PacketHeaderWire header; uint8_t payload[256]; size_t payload_size = sizeof(payload); - - if (!parseWirePacket(data, size, &header, payload, &payload_size)) { + + if (!parseWirePacket(data, size, &header, payload, &payload_size)) + { std::string raw_hex = toHex(data, size); LORA_LOG("[LORA] RX parse fail len=%u hex=%s\n", (unsigned)size, @@ -464,6 +498,7 @@ void MtAdapter::processReceivedPacket(const uint8_t* data, size_t size) { return; } + std::string full_hex = toHex(data, size, size); LORA_LOG("[LORA] RX wire from=%08lX to=%08lX id=%08lX ch=0x%02X flags=0x%02X len=%u\n", (unsigned long)header.from, (unsigned long)header.to, @@ -471,36 +506,42 @@ void MtAdapter::processReceivedPacket(const uint8_t* data, size_t size) { header.channel, header.flags, (unsigned)payload_size); - if (header.from == node_id_) { + LORA_LOG("[LORA] RX full packet hex: %s\n", full_hex.c_str()); + if (header.from == node_id_) + { LORA_LOG("[LORA] RX self drop id=%08lX\n", (unsigned long)header.id); return; } - + // Check for duplicates - if (dedup_.isDuplicate(header.from, header.id)) { + if (dedup_.isDuplicate(header.from, header.id)) + { LORA_LOG("[LORA] RX dedup from=%08lX id=%08lX\n", (unsigned long)header.from, (unsigned long)header.id); return; // Duplicate, ignore } - + // Mark as seen dedup_.markSeen(header.from, header.id); - + // Decrypt payload if needed uint8_t plaintext[256]; size_t plaintext_len = sizeof(plaintext); - + const uint8_t* psk = nullptr; size_t psk_len = 0; bool unknown_channel = false; - if (header.channel == 0) { - if (header.to != node_id_ || header.to == 0xFFFFFFFF || payload_size <= 12 || !pki_ready_) { + if (header.channel == 0) + { + if (header.to != node_id_ || header.to == 0xFFFFFFFF || payload_size <= 12 || !pki_ready_) + { return; } - if (!decryptPkiPayload(header.from, header.id, payload, payload_size, plaintext, &plaintext_len)) { + if (!decryptPkiPayload(header.from, header.id, payload, payload_size, plaintext, &plaintext_len)) + { std::string cipher_hex = toHex(payload, payload_size); LORA_LOG("[LORA] RX PKI decrypt fail from=%08lX id=%08lX len=%u hex=%s\n", (unsigned long)header.from, @@ -509,14 +550,21 @@ void MtAdapter::processReceivedPacket(const uint8_t* data, size_t size) { cipher_hex.c_str()); return; } - } else { - if (header.channel == primary_channel_hash_) { + } + else + { + if (header.channel == primary_channel_hash_) + { psk = primary_psk_; psk_len = primary_psk_len_; - } else if (header.channel == secondary_channel_hash_) { + } + else if (header.channel == secondary_channel_hash_) + { psk = secondary_psk_; psk_len = secondary_psk_len_; - } else { + } + else + { std::string cipher_hex = toHex(payload, payload_size); LORA_LOG("[LORA] RX unknown channel hash=0x%02X from=%08lX id=%08lX len=%u hex=%s (skip decode)\n", header.channel, @@ -527,13 +575,16 @@ void MtAdapter::processReceivedPacket(const uint8_t* data, size_t size) { unknown_channel = true; } - if (unknown_channel) { + if (unknown_channel) + { return; } - if (psk && psk_len > 0) { - if (!decryptPayload(header, payload, payload_size, psk, psk_len, plaintext, &plaintext_len)) { - std::string cipher_hex = toHex(payload, payload_size); + if (psk && psk_len > 0) + { + if (!decryptPayload(header, payload, payload_size, psk, psk_len, plaintext, &plaintext_len)) + { + std::string cipher_hex = toHex(payload, payload_size, payload_size); LORA_LOG("[LORA] RX decrypt fail id=%08lX ch=0x%02X psk=%u len=%u hex=%s\n", (unsigned long)header.id, header.channel, @@ -542,102 +593,137 @@ void MtAdapter::processReceivedPacket(const uint8_t* data, size_t size) { cipher_hex.c_str()); return; } - } else { + } + else + { memcpy(plaintext, payload, payload_size); plaintext_len = payload_size; } + + // Log decrypted protobuf payload (meshtastic_Data wire format) + if (plaintext_len > 0) + { + std::string protobuf_hex = toHex(plaintext, plaintext_len, plaintext_len); + LORA_LOG("[LORA] RX protobuf hex: %s\n", protobuf_hex.c_str()); + } } meshtastic_Data decoded = meshtastic_Data_init_default; pb_istream_t stream = pb_istream_from_buffer(plaintext, plaintext_len); - if (pb_decode(&stream, meshtastic_Data_fields, &decoded)) { + if (pb_decode(&stream, meshtastic_Data_fields, &decoded)) + { LORA_LOG("[LORA] RX data portnum=%u (%s) payload=%u\n", (unsigned)decoded.portnum, portName(decoded.portnum), (unsigned)decoded.payload.size); + if (decoded.payload.size > 0) + { + std::string payload_hex = toHex(decoded.payload.bytes, decoded.payload.size, decoded.payload.size); + LORA_LOG("[LORA] RX data payload hex: %s\n", payload_hex.c_str()); + } - if (decoded.portnum == meshtastic_PortNum_NODEINFO_APP && decoded.payload.size > 0) { - meshtastic_User user = meshtastic_User_init_default; - pb_istream_t ustream = pb_istream_from_buffer(decoded.payload.bytes, decoded.payload.size); - if (pb_decode(&ustream, meshtastic_User_fields, &user)) { - const uint32_t node_id = header.from; - const char* short_name = user.short_name[0] ? user.short_name : ""; - const char* long_name = user.long_name[0] ? user.long_name : ""; - LORA_LOG("[LORA] RX User from %08lX id='%s' short='%s' long='%s'\n", - (unsigned long)node_id, user.id, short_name, long_name); - if (user.public_key.size == 32) { - std::array key{}; - memcpy(key.data(), user.public_key.bytes, 32); - node_public_keys_[node_id] = key; - LORA_LOG("[LORA] PKI key stored for %08lX\n", (unsigned long)node_id); - } - - // Publish NodeInfo update event (SNR not available in User message, use 0.0) - uint32_t now_secs = time(nullptr); - sys::NodeInfoUpdateEvent* event = new sys::NodeInfoUpdateEvent( - node_id, short_name, long_name, 0.0f, now_secs); - sys::EventBus::publish(event, 0); - - if (decoded.want_response) { - uint32_t now_ms = millis(); - auto it = nodeinfo_last_seen_ms_.find(node_id); - bool allow_reply = true; - if (it != nodeinfo_last_seen_ms_.end()) { - uint32_t since = now_ms - it->second; - if (since < NODEINFO_REPLY_SUPPRESS_MS) { - allow_reply = false; - } + if (decoded.portnum == meshtastic_PortNum_NODEINFO_APP && decoded.payload.size > 0) + { + meshtastic_User user = meshtastic_User_init_default; + pb_istream_t ustream = pb_istream_from_buffer(decoded.payload.bytes, decoded.payload.size); + if (pb_decode(&ustream, meshtastic_User_fields, &user)) + { + const uint32_t node_id = header.from; + const char* short_name = user.short_name[0] ? user.short_name : ""; + const char* long_name = user.long_name[0] ? user.long_name : ""; + LORA_LOG("[LORA] RX User from %08lX id='%s' short='%s' long='%s'\n", + (unsigned long)node_id, user.id, short_name, long_name); + if (user.public_key.size == 32) + { + std::array key{}; + memcpy(key.data(), user.public_key.bytes, 32); + node_public_keys_[node_id] = key; + LORA_LOG("[LORA] PKI key stored for %08lX\n", (unsigned long)node_id); } - nodeinfo_last_seen_ms_[node_id] = now_ms; - if (allow_reply && node_id != node_id_) { - sendNodeInfoTo(node_id, false); - } - } - } else { - LORA_LOG("[LORA] RX User decode fail from=%08lX err=%s\n", - (unsigned long)header.from, - PB_GET_ERROR(&ustream)); - meshtastic_NodeInfo node = meshtastic_NodeInfo_init_default; - pb_istream_t nstream = pb_istream_from_buffer(decoded.payload.bytes, decoded.payload.size); - if (pb_decode(&nstream, meshtastic_NodeInfo_fields, &node)) { - uint32_t node_id = node.num ? node.num : header.from; - const char* short_name = node.has_user ? node.user.short_name : ""; - const char* long_name = node.has_user ? node.user.long_name : ""; - float snr = node.snr; // Get SNR from NodeInfo - LORA_LOG("[LORA] RX NodeInfo from %08lX short='%s' long='%s' snr=%.1f\n", - (unsigned long)node_id, short_name, long_name, snr); - - // Publish NodeInfo update event (including SNR) + + // Publish NodeInfo update event (SNR not available in User message, use 0.0) uint32_t now_secs = time(nullptr); sys::NodeInfoUpdateEvent* event = new sys::NodeInfoUpdateEvent( - node_id, short_name, long_name, snr, now_secs); + node_id, short_name, long_name, 0.0f, now_secs, + static_cast(chat::contacts::NodeProtocolType::Meshtastic)); sys::EventBus::publish(event, 0); - } else { - LORA_LOG("[LORA] RX NodeInfo decode fail from=%08lX err=%s\n", + + if (decoded.want_response) + { + uint32_t now_ms = millis(); + auto it = nodeinfo_last_seen_ms_.find(node_id); + bool allow_reply = true; + if (it != nodeinfo_last_seen_ms_.end()) + { + uint32_t since = now_ms - it->second; + if (since < NODEINFO_REPLY_SUPPRESS_MS) + { + allow_reply = false; + } + } + nodeinfo_last_seen_ms_[node_id] = now_ms; + if (allow_reply && node_id != node_id_) + { + sendNodeInfoTo(node_id, false); + } + } + } + else + { + LORA_LOG("[LORA] RX User decode fail from=%08lX err=%s\n", (unsigned long)header.from, - PB_GET_ERROR(&nstream)); + PB_GET_ERROR(&ustream)); + meshtastic_NodeInfo node = meshtastic_NodeInfo_init_default; + pb_istream_t nstream = pb_istream_from_buffer(decoded.payload.bytes, decoded.payload.size); + if (pb_decode(&nstream, meshtastic_NodeInfo_fields, &node)) + { + uint32_t node_id = node.num ? node.num : header.from; + const char* short_name = node.has_user ? node.user.short_name : ""; + const char* long_name = node.has_user ? node.user.long_name : ""; + float snr = node.snr; // Get SNR from NodeInfo + LORA_LOG("[LORA] RX NodeInfo from %08lX short='%s' long='%s' snr=%.1f\n", + (unsigned long)node_id, short_name, long_name, snr); + + // Publish NodeInfo update event (including SNR) + uint32_t now_secs = time(nullptr); + sys::NodeInfoUpdateEvent* event = new sys::NodeInfoUpdateEvent( + node_id, short_name, long_name, snr, now_secs, + static_cast(chat::contacts::NodeProtocolType::Meshtastic)); + sys::EventBus::publish(event, 0); + } + else + { + LORA_LOG("[LORA] RX NodeInfo decode fail from=%08lX err=%s\n", + (unsigned long)header.from, + PB_GET_ERROR(&nstream)); + } } } - } bool want_ack_flag = (header.flags & PACKET_FLAGS_WANT_ACK_MASK) != 0; bool want_response = decoded.want_response || - (decoded.has_bitfield && ((decoded.bitfield & kBitfieldWantResponseMask) != 0)); + (decoded.has_bitfield && ((decoded.bitfield & kBitfieldWantResponseMask) != 0)); bool to_us = (header.to == node_id_); bool is_text_port = (decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP || decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_COMPRESSED_APP); - if ((want_ack_flag || want_response) && to_us && is_text_port) { - if (sendRoutingAck(header.from, header.id, header.channel, psk, psk_len)) { + if ((want_ack_flag || want_response) && to_us && is_text_port) + { + if (sendRoutingAck(header.from, header.id, header.channel, psk, psk_len)) + { LORA_LOG("[LORA] TX ack to=%08lX req=%08lX\n", (unsigned long)header.from, (unsigned long)header.id); - } else { + } + else + { LORA_LOG("[LORA] TX ack fail to=%08lX req=%08lX\n", (unsigned long)header.from, (unsigned long)header.id); } } - } else { + } + else + { std::string plain_hex = toHex(plaintext, plaintext_len); LORA_LOG("[LORA] RX data decode fail id=%08lX err=%s len=%u hex=%s\n", (unsigned long)header.id, @@ -645,63 +731,78 @@ void MtAdapter::processReceivedPacket(const uint8_t* data, size_t size) { (unsigned)plaintext_len, plain_hex.c_str()); } - + // Decode Data message MeshIncomingText incoming; - if (decodeTextMessage(plaintext, plaintext_len, &incoming)) { + if (decodeTextMessage(plaintext, plaintext_len, &incoming)) + { // Fill in packet info from header incoming.from = header.from; incoming.msg_id = header.id; - if (header.channel == secondary_channel_hash_) { + if (header.channel == secondary_channel_hash_) + { incoming.channel = ChannelId::SECONDARY; - } else { + } + else + { incoming.channel = ChannelId::PRIMARY; } incoming.hop_limit = header.flags & PACKET_FLAGS_HOP_LIMIT_MASK; incoming.encrypted = (psk != nullptr && psk_len > 0); - + receive_queue_.push(incoming); LORA_LOG("[LORA] RX text from=%08lX id=%08lX ch=%u len=%u\n", (unsigned long)incoming.from, (unsigned long)incoming.msg_id, static_cast(incoming.channel), (unsigned)incoming.text.size()); - if (!incoming.text.empty()) { + if (!incoming.text.empty()) + { LORA_LOG("[LORA] RX text msg='%s'\n", incoming.text.c_str()); } } } -void MtAdapter::processSendQueue() { +void MtAdapter::processSendQueue() +{ uint32_t now = millis(); maybeBroadcastNodeInfo(now); - if (!send_queue_.empty()) { + if (!send_queue_.empty()) + { LORA_LOG("[LORA] TX queue pending=%u\n", (unsigned)send_queue_.size()); } - - while (!send_queue_.empty()) { + + while (!send_queue_.empty()) + { PendingSend& pending = send_queue_.front(); - + // Check if ready to send - if (now - pending.last_attempt < RETRY_DELAY_MS && pending.retry_count > 0) { + if (now - pending.last_attempt < RETRY_DELAY_MS && pending.retry_count > 0) + { break; // Wait before retry } - + // Try to send - if (sendPacket(pending)) { + if (sendPacket(pending)) + { // Success, remove from queue send_queue_.pop(); - } else { + } + else + { // Failed, retry or drop pending.retry_count++; pending.last_attempt = now; - - if (pending.retry_count > MAX_RETRIES) { + + if (pending.retry_count > MAX_RETRIES) + { // Max retries reached, drop send_queue_.pop(); - } else { + } + else + { // Will retry later break; } @@ -709,21 +810,23 @@ void MtAdapter::processSendQueue() { } } -bool MtAdapter::sendPacket(const PendingSend& pending) { +bool MtAdapter::sendPacket(const PendingSend& pending) +{ // Create Data message payload uint8_t data_buffer[256]; size_t data_size = sizeof(data_buffer); - + NodeId from_node = node_id_; - if (!encodeTextMessage(pending.channel, pending.text, from_node, - pending.msg_id, data_buffer, &data_size)) { + if (!encodeTextMessage(pending.channel, pending.text, from_node, + pending.msg_id, data_buffer, &data_size)) + { return false; } - + // Build full wire packet (like M5Tab5-GPS) uint8_t wire_buffer[512]; size_t wire_size = sizeof(wire_buffer); - + uint8_t channel_hash = (pending.channel == ChannelId::SECONDARY) ? secondary_channel_hash_ : primary_channel_hash_; uint8_t hop_limit = config_.hop_limit; @@ -739,25 +842,32 @@ bool MtAdapter::sendPacket(const PendingSend& pending) { (node_public_keys_.find(dest) != node_public_keys_.end()); uint8_t pki_buf[256]; size_t pki_len = sizeof(pki_buf); - if (use_pki && encryptPkiPayload(dest, pending.msg_id, data_buffer, data_size, pki_buf, &pki_len)) { + if (use_pki && encryptPkiPayload(dest, pending.msg_id, data_buffer, data_size, pki_buf, &pki_len)) + { payload = pki_buf; payload_len = pki_len; channel_hash = 0; // PKI channel want_ack = true; - } else { + } + else + { // Fallback to PSK - if (pending.channel == ChannelId::SECONDARY) { + if (pending.channel == ChannelId::SECONDARY) + { psk = secondary_psk_; psk_len = secondary_psk_len_; - } else { + } + else + { psk = primary_psk_; psk_len = primary_psk_len_; } } - + if (!buildWirePacket(payload, payload_len, from_node, pending.msg_id, - dest, channel_hash, hop_limit, want_ack, - psk, psk_len, wire_buffer, &wire_size)) { + dest, channel_hash, hop_limit, want_ack, + psk, psk_len, wire_buffer, &wire_size)) + { return false; } LORA_LOG("[LORA] TX wire ch=0x%02X hop=%u ack=%d psk=%u wire=%u dest=%08lX\n", @@ -767,14 +877,17 @@ bool MtAdapter::sendPacket(const PendingSend& pending) { (unsigned)psk_len, (unsigned)wire_size, (unsigned long)dest); - + std::string tx_full_hex = toHex(wire_buffer, wire_size, wire_size); + LORA_LOG("[LORA] TX full packet hex: %s\n", tx_full_hex.c_str()); + // Send via LoRa using RadioLib int state = RADIOLIB_ERR_NONE; - - if (!board_.isHardwareOnline(HW_RADIO_ONLINE)) { + + if (!board_.isHardwareOnline(HW_RADIO_ONLINE)) + { return false; } - + #if defined(ARDUINO_LILYGO_LORA_SX1262) || defined(ARDUINO_LILYGO_LORA_SX1280) // For now, send directly (in production, use task queue) state = board_.radio.transmit(wire_buffer, wire_size); @@ -782,28 +895,32 @@ bool MtAdapter::sendPacket(const PendingSend& pending) { // Other radio types - implement as needed state = RADIOLIB_ERR_UNSUPPORTED; #endif - + bool ok = (state == RADIOLIB_ERR_NONE); LORA_LOG("[LORA] TX text id=%08lX ch=%u len=%u ok=%d\n", (unsigned long)pending.msg_id, static_cast(pending.channel), (unsigned)wire_size, ok ? 1 : 0); - if (ok) { + if (ok) + { startRadioReceive(); } return ok; } -bool MtAdapter::sendNodeInfo() { - if (!ready_) { +bool MtAdapter::sendNodeInfo() +{ + if (!ready_) + { return false; } return sendNodeInfoTo(0xFFFFFFFF, false); } -bool MtAdapter::sendNodeInfoTo(uint32_t dest, bool want_response) { +bool MtAdapter::sendNodeInfoTo(uint32_t dest, bool want_response) +{ uint8_t data_buffer[256]; size_t data_size = sizeof(data_buffer); @@ -826,7 +943,8 @@ bool MtAdapter::sendNodeInfoTo(uint32_t dest, bool want_response) { pki_ready_ ? pki_public_key_.size() : 0, want_response, data_buffer, - &data_size)) { + &data_size)) + { return false; } @@ -842,15 +960,19 @@ bool MtAdapter::sendNodeInfoTo(uint32_t dest, bool want_response) { if (!buildWirePacket(data_buffer, data_size, node_id_, next_packet_id_++, dest, channel_hash, hop_limit, want_ack, - primary_psk_, primary_psk_len_, wire_buffer, &wire_size)) { + primary_psk_, primary_psk_len_, wire_buffer, &wire_size)) + { return false; } LORA_LOG("[LORA] TX nodeinfo wire ch=0x%02X hop=%u wire=%u\n", channel_hash, hop_limit, (unsigned)wire_size); + std::string nodeinfo_full_hex = toHex(wire_buffer, wire_size, wire_size); + LORA_LOG("[LORA] TX nodeinfo full packet hex: %s\n", nodeinfo_full_hex.c_str()); - if (!board_.isHardwareOnline(HW_RADIO_ONLINE)) { + if (!board_.isHardwareOnline(HW_RADIO_ONLINE)) + { return false; } @@ -864,40 +986,48 @@ bool MtAdapter::sendNodeInfoTo(uint32_t dest, bool want_response) { (unsigned long)(next_packet_id_ - 1), (unsigned)wire_size, ok ? 1 : 0); - if (ok) { + if (ok) + { startRadioReceive(); } return ok; } -void MtAdapter::maybeBroadcastNodeInfo(uint32_t now_ms) { - if (!ready_) { +void MtAdapter::maybeBroadcastNodeInfo(uint32_t now_ms) +{ + if (!ready_) + { return; } - if (last_nodeinfo_ms_ == 0 || (now_ms - last_nodeinfo_ms_) >= NODEINFO_INTERVAL_MS) { - if (sendNodeInfo()) { + if (last_nodeinfo_ms_ == 0 || (now_ms - last_nodeinfo_ms_) >= NODEINFO_INTERVAL_MS) + { + if (sendNodeInfo()) + { last_nodeinfo_ms_ = now_ms; } } } -void MtAdapter::configureRadio() { +void MtAdapter::configureRadio() +{ // Configure LoRa radio based on config_ // This is a placeholder - actual configuration depends on RadioLib API // and Meshtastic region/preset settings - if (!board_.isHardwareOnline(HW_RADIO_ONLINE)) { + if (!board_.isHardwareOnline(HW_RADIO_ONLINE)) + { ready_ = false; return; } meshtastic_Config_LoRaConfig_RegionCode region_code = static_cast(config_.region); - if (region_code == meshtastic_Config_LoRaConfig_RegionCode_UNSET) { + if (region_code == meshtastic_Config_LoRaConfig_RegionCode_UNSET) + { region_code = meshtastic_Config_LoRaConfig_RegionCode_CN; } - const RegionInfo* region = findRegion(region_code); + const chat::meshtastic::RegionInfo* region = chat::meshtastic::findRegion(region_code); meshtastic_Config_LoRaConfig_ModemPreset preset = static_cast(config_.modem_preset); @@ -905,53 +1035,55 @@ void MtAdapter::configureRadio() { float bw_khz = 250.0f; uint8_t sf = 11; uint8_t cr_denom = 5; - switch (preset) { - case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO: - bw_khz = region->wide_lora ? 1625.0f : 500.0f; - cr_denom = 5; - sf = 7; - break; - case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST: - bw_khz = region->wide_lora ? 812.5f : 250.0f; - cr_denom = 5; - sf = 7; - break; - case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW: - bw_khz = region->wide_lora ? 812.5f : 250.0f; - cr_denom = 5; - sf = 8; - break; - case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST: - bw_khz = region->wide_lora ? 812.5f : 250.0f; - cr_denom = 5; - sf = 9; - break; - case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW: - bw_khz = region->wide_lora ? 812.5f : 250.0f; - cr_denom = 5; - sf = 10; - break; - case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE: - bw_khz = region->wide_lora ? 406.25f : 125.0f; - cr_denom = 8; - sf = 11; - break; - case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW: - bw_khz = region->wide_lora ? 406.25f : 125.0f; - cr_denom = 8; - sf = 12; - break; - case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST: - default: - bw_khz = region->wide_lora ? 812.5f : 250.0f; - cr_denom = 5; - sf = 11; - break; + switch (preset) + { + case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO: + bw_khz = region->wide_lora ? 1625.0f : 500.0f; + cr_denom = 5; + sf = 7; + break; + case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST: + bw_khz = region->wide_lora ? 812.5f : 250.0f; + cr_denom = 5; + sf = 7; + break; + case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW: + bw_khz = region->wide_lora ? 812.5f : 250.0f; + cr_denom = 5; + sf = 8; + break; + case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST: + bw_khz = region->wide_lora ? 812.5f : 250.0f; + cr_denom = 5; + sf = 9; + break; + case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW: + bw_khz = region->wide_lora ? 812.5f : 250.0f; + cr_denom = 5; + sf = 10; + break; + case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE: + bw_khz = region->wide_lora ? 406.25f : 125.0f; + cr_denom = 8; + sf = 11; + break; + case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW: + bw_khz = region->wide_lora ? 406.25f : 125.0f; + cr_denom = 8; + sf = 12; + break; + case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST: + default: + bw_khz = region->wide_lora ? 812.5f : 250.0f; + cr_denom = 5; + sf = 11; + break; } - const char* channel_name = presetDisplayName(preset); - float freq_mhz = computeFrequencyMhz(region, bw_khz, channel_name); - if (freq_mhz <= 0.0f) { + const char* channel_name = chat::meshtastic::presetDisplayName(preset); + float freq_mhz = chat::meshtastic::computeFrequencyMhz(region, bw_khz, channel_name); + if (freq_mhz <= 0.0f) + { freq_mhz = region->freq_start_mhz + (bw_khz / 2000.0f); } @@ -981,9 +1113,11 @@ void MtAdapter::configureRadio() { startRadioReceive(); } -void MtAdapter::initNodeIdentity() { +void MtAdapter::initNodeIdentity() +{ uint64_t mac = ESP.getEfuseMac(); - for (int i = 0; i < 6; i++) { + for (int i = 0; i < 6; i++) + { mac_addr_[5 - i] = (mac >> (8 * i)) & 0xFF; } node_id_ = (static_cast(mac_addr_[2]) << 24) | @@ -992,20 +1126,27 @@ void MtAdapter::initNodeIdentity() { static_cast(mac_addr_[5]); } -void MtAdapter::updateChannelKeys() { - if (isZeroKey(config_.primary_key, sizeof(config_.primary_key))) { +void MtAdapter::updateChannelKeys() +{ + if (isZeroKey(config_.primary_key, sizeof(config_.primary_key))) + { size_t len = 0; expandShortPsk(kDefaultPskIndex, primary_psk_, &len); primary_psk_len_ = len; - } else { + } + else + { memcpy(primary_psk_, config_.primary_key, sizeof(primary_psk_)); primary_psk_len_ = sizeof(primary_psk_); } - if (isZeroKey(config_.secondary_key, sizeof(config_.secondary_key))) { + if (isZeroKey(config_.secondary_key, sizeof(config_.secondary_key))) + { secondary_psk_len_ = 0; memset(secondary_psk_, 0, sizeof(secondary_psk_)); - } else { + } + else + { memcpy(secondary_psk_, config_.secondary_key, sizeof(secondary_psk_)); secondary_psk_len_ = sizeof(secondary_psk_); } @@ -1025,19 +1166,23 @@ void MtAdapter::updateChannelKeys() { (unsigned)secondary_psk_len_); } -void MtAdapter::startRadioReceive() { - if (!board_.isHardwareOnline(HW_RADIO_ONLINE)) { +void MtAdapter::startRadioReceive() +{ + if (!board_.isHardwareOnline(HW_RADIO_ONLINE)) + { return; } #if defined(ARDUINO_LILYGO_LORA_SX1262) || defined(ARDUINO_LILYGO_LORA_SX1280) int state = board_.radio.startReceive(); - if (state != RADIOLIB_ERR_NONE) { + if (state != RADIOLIB_ERR_NONE) + { LORA_LOG("[LORA] RX start fail state=%d\n", state); } #endif } -bool MtAdapter::initPkiKeys() { +bool MtAdapter::initPkiKeys() +{ Preferences prefs; prefs.begin("chat", false); size_t pub_len = prefs.getBytes("pki_pub", pki_public_key_.data(), pki_public_key_.size()); @@ -1045,7 +1190,8 @@ bool MtAdapter::initPkiKeys() { bool have_keys = (pub_len == pki_public_key_.size() && priv_len == pki_private_key_.size() && !isZeroKey(pki_private_key_.data(), pki_private_key_.size())); - if (!have_keys) { + if (!have_keys) + { RNG.begin("trail-mate"); RNG.stir(mac_addr_, sizeof(mac_addr_)); uint32_t noise = random(); @@ -1053,7 +1199,8 @@ bool MtAdapter::initPkiKeys() { Curve25519::dh1(pki_public_key_.data(), pki_private_key_.data()); have_keys = !isZeroKey(pki_private_key_.data(), pki_private_key_.size()); - if (have_keys) { + if (have_keys) + { prefs.putBytes("pki_pub", pki_public_key_.data(), pki_public_key_.size()); prefs.putBytes("pki_priv", pki_private_key_.data(), pki_private_key_.size()); } @@ -1061,9 +1208,12 @@ bool MtAdapter::initPkiKeys() { prefs.end(); pki_ready_ = have_keys; - if (pki_ready_) { + if (pki_ready_) + { LORA_LOG("[LORA] PKI ready, public key set\n"); - } else { + } + else + { LORA_LOG("[LORA] PKI init failed\n"); } return pki_ready_; @@ -1071,15 +1221,19 @@ bool MtAdapter::initPkiKeys() { bool MtAdapter::decryptPkiPayload(uint32_t from, uint32_t packet_id, const uint8_t* cipher, size_t cipher_len, - uint8_t* out_plain, size_t* out_plain_len) { - if (!cipher || cipher_len <= 12 || !out_plain || !out_plain_len) { + uint8_t* out_plain, size_t* out_plain_len) +{ + if (!cipher || cipher_len <= 12 || !out_plain || !out_plain_len) + { return false; } - if (!pki_ready_) { + if (!pki_ready_) + { return false; } auto it = node_public_keys_.find(from); - if (it == node_public_keys_.end()) { + if (it == node_public_keys_.end()) + { LORA_LOG("[LORA] PKI key missing for %08lX\n", (unsigned long)from); return false; } @@ -1088,7 +1242,8 @@ bool MtAdapter::decryptPkiPayload(uint32_t from, uint32_t packet_id, uint8_t local_priv[32]; memcpy(shared, it->second.data(), sizeof(shared)); memcpy(local_priv, pki_private_key_.data(), sizeof(local_priv)); - if (!Curve25519::dh2(shared, local_priv)) { + if (!Curve25519::dh2(shared, local_priv)) + { return false; } @@ -1103,13 +1258,15 @@ bool MtAdapter::decryptPkiPayload(uint32_t from, uint32_t packet_id, initPkiNonce(from, packet_id64, extra_nonce, nonce); size_t plain_len = cipher_len - 12; - if (*out_plain_len < plain_len) { + if (*out_plain_len < plain_len) + { *out_plain_len = plain_len; return false; } if (!aes_ccm_ad(shared, sizeof(shared), nonce, 8, - cipher, plain_len, nullptr, 0, auth, out_plain)) { + cipher, plain_len, nullptr, 0, auth, out_plain)) + { return false; } @@ -1119,11 +1276,13 @@ bool MtAdapter::decryptPkiPayload(uint32_t from, uint32_t packet_id, bool MtAdapter::encryptPkiPayload(uint32_t dest, uint32_t packet_id, const uint8_t* plain, size_t plain_len, - uint8_t* out_cipher, size_t* out_cipher_len) { + uint8_t* out_cipher, size_t* out_cipher_len) +{ if (!plain || !out_cipher || !out_cipher_len) return false; if (!pki_ready_) return false; auto it = node_public_keys_.find(dest); - if (it == node_public_keys_.end()) { + if (it == node_public_keys_.end()) + { LORA_LOG("[LORA] PKI key missing for %08lX\n", (unsigned long)dest); return false; } @@ -1132,7 +1291,8 @@ bool MtAdapter::encryptPkiPayload(uint32_t dest, uint32_t packet_id, uint8_t local_priv[32]; memcpy(shared, it->second.data(), sizeof(shared)); memcpy(local_priv, pki_private_key_.data(), sizeof(local_priv)); - if (!Curve25519::dh2(shared, local_priv)) { + if (!Curve25519::dh2(shared, local_priv)) + { return false; } hashSharedKey(shared, sizeof(shared)); @@ -1145,7 +1305,8 @@ bool MtAdapter::encryptPkiPayload(uint32_t dest, uint32_t packet_id, const size_t m = 8; const size_t l = 2; size_t needed = plain_len + m + sizeof(extra_nonce); - if (*out_cipher_len < needed) { + if (*out_cipher_len < needed) + { *out_cipher_len = needed; return false; } @@ -1165,12 +1326,15 @@ bool MtAdapter::encryptPkiPayload(uint32_t dest, uint32_t packet_id, } bool MtAdapter::sendRoutingAck(uint32_t dest, uint32_t request_id, uint8_t channel_hash, - const uint8_t* psk, size_t psk_len) { - if (!board_.isHardwareOnline(HW_RADIO_ONLINE)) { + const uint8_t* psk, size_t psk_len) +{ + if (!board_.isHardwareOnline(HW_RADIO_ONLINE)) + { return false; } - if (channel_hash == 0) { + if (channel_hash == 0) + { channel_hash = primary_channel_hash_; psk = primary_psk_; psk_len = primary_psk_len_; @@ -1182,7 +1346,8 @@ bool MtAdapter::sendRoutingAck(uint32_t dest, uint32_t request_id, uint8_t chann uint8_t routing_buf[64]; pb_ostream_t rstream = pb_ostream_from_buffer(routing_buf, sizeof(routing_buf)); - if (!pb_encode(&rstream, meshtastic_Routing_fields, &routing)) { + if (!pb_encode(&rstream, meshtastic_Routing_fields, &routing)) + { return false; } @@ -1195,14 +1360,16 @@ bool MtAdapter::sendRoutingAck(uint32_t dest, uint32_t request_id, uint8_t chann data.has_bitfield = true; data.bitfield = 0; data.payload.size = rstream.bytes_written; - if (data.payload.size > sizeof(data.payload.bytes)) { + if (data.payload.size > sizeof(data.payload.bytes)) + { return false; } memcpy(data.payload.bytes, routing_buf, data.payload.size); uint8_t data_buf[128]; pb_ostream_t dstream = pb_ostream_from_buffer(data_buf, sizeof(data_buf)); - if (!pb_encode(&dstream, meshtastic_Data_fields, &data)) { + if (!pb_encode(&dstream, meshtastic_Data_fields, &data)) + { return false; } @@ -1212,16 +1379,21 @@ bool MtAdapter::sendRoutingAck(uint32_t dest, uint32_t request_id, uint8_t chann bool want_ack = false; if (!buildWirePacket(data_buf, dstream.bytes_written, node_id_, next_packet_id_++, dest, channel_hash, hop_limit, want_ack, - psk, psk_len, wire_buffer, &wire_size)) { + psk, psk_len, wire_buffer, &wire_size)) + { return false; } + std::string ack_full_hex = toHex(wire_buffer, wire_size, wire_size); + LORA_LOG("[LORA] TX ack full packet hex: %s\n", ack_full_hex.c_str()); + #if defined(ARDUINO_LILYGO_LORA_SX1262) || defined(ARDUINO_LILYGO_LORA_SX1280) int state = board_.radio.transmit(wire_buffer, wire_size); #else int state = RADIOLIB_ERR_UNSUPPORTED; #endif - if (state == RADIOLIB_ERR_NONE) { + if (state == RADIOLIB_ERR_NONE) + { startRadioReceive(); return true; } diff --git a/src/chat/infra/meshtastic/mt_adapter.h b/src/chat/infra/meshtastic/mt_adapter.h index 760018ce..3a78c558 100644 --- a/src/chat/infra/meshtastic/mt_adapter.h +++ b/src/chat/infra/meshtastic/mt_adapter.h @@ -5,48 +5,67 @@ #pragma once -#include "../../ports/i_mesh_adapter.h" -#include "../../domain/chat_types.h" -#include "mt_codec_pb.h" // Use protobuf-based codec -#include "mt_packet_wire.h" // Wire packet format -#include "mt_dedup.h" #include "../../../board/TLoRaPagerBoard.h" +#include "../../domain/chat_types.h" +#include "../../ports/i_mesh_adapter.h" #include "freertos/FreeRTOS.h" #include "freertos/queue.h" +#include "mt_codec_pb.h" // Use protobuf-based codec +#include "mt_dedup.h" +#include "mt_packet_wire.h" // Wire packet format #include #include #include #include -namespace chat { -namespace meshtastic { +namespace chat +{ +namespace meshtastic +{ /** * @brief Meshtastic mesh adapter * Implements IMeshAdapter using Meshtastic protocol over LoRa */ -class MtAdapter : public chat::IMeshAdapter { -public: +class MtAdapter : public chat::IMeshAdapter +{ + public: MtAdapter(TLoRaPagerBoard& board); virtual ~MtAdapter(); - - bool sendText(ChannelId channel, const std::string& text, - MessageId* out_msg_id, NodeId peer = 0) override; + + bool sendText(ChannelId channel, const std::string& text, + MessageId* out_msg_id, NodeId peer = 0) override; bool pollIncomingText(MeshIncomingText* out) override; void applyConfig(const MeshConfig& config) override; bool isReady() const override; - + + /** + * @brief Poll for incoming raw packet data + * @param out_data Output buffer for raw packet data + * @param out_len Output packet length + * @param max_len Maximum buffer size + * @return true if raw packet data is available + */ + bool pollIncomingRawPacket(uint8_t* out_data, size_t& out_len, size_t max_len) override; + + /** + * @brief Handle raw packet data (from radio task) + * @param data Raw packet data + * @param size Packet size + */ + void handleRawPacket(const uint8_t* data, size_t size) override; + /** * @brief Process received packets (call from radio task) */ void processReceivedPacket(const uint8_t* data, size_t size); - + /** * @brief Process send queue (call periodically) */ - void processSendQueue(); + void processSendQueue() override; -private: + private: TLoRaPagerBoard& board_; MeshConfig config_; MtDedup dedup_; @@ -66,8 +85,14 @@ private: std::array pki_private_key_; std::map> node_public_keys_; std::map nodeinfo_last_seen_ms_; - - struct PendingSend { + + // Raw packet data storage for protocol detection + uint8_t last_raw_packet_[256]; + size_t last_raw_packet_len_; + bool has_pending_raw_packet_; + + struct PendingSend + { ChannelId channel; std::string text; MessageId msg_id; @@ -75,16 +100,16 @@ private: uint32_t retry_count; uint32_t last_attempt; }; - + std::queue send_queue_; std::queue receive_queue_; - + static constexpr size_t MAX_PACKET_SIZE = 255; static constexpr uint32_t RETRY_DELAY_MS = 1000; static constexpr uint8_t MAX_RETRIES = 1; static constexpr uint32_t NODEINFO_INTERVAL_MS = 3 * 60 * 60 * 1000; static constexpr uint32_t NODEINFO_REPLY_SUPPRESS_MS = 12 * 60 * 60 * 1000; - + bool sendPacket(const PendingSend& pending); bool sendNodeInfo(); bool sendNodeInfoTo(uint32_t dest, bool want_response); diff --git a/src/chat/infra/meshtastic/mt_codec_pb.cpp b/src/chat/infra/meshtastic/mt_codec_pb.cpp index b0cbbb6d..18c19d1f 100644 --- a/src/chat/infra/meshtastic/mt_codec_pb.cpp +++ b/src/chat/infra/meshtastic/mt_codec_pb.cpp @@ -1,7 +1,7 @@ /** * @file mt_codec_pb.cpp * @brief Meshtastic protocol codec implementation using protobuf - * + * * Based on M5Tab5-GPS implementation */ @@ -9,105 +9,123 @@ #include "compression/unishox2.h" #include -namespace chat { -namespace meshtastic { +namespace chat +{ +namespace meshtastic +{ -bool encodeTextMessage(ChannelId channel, const std::string& text, - NodeId from_node, uint32_t packet_id, - uint8_t* out_buffer, size_t* out_size) { - if (!out_buffer || !out_size || text.empty()) { +bool encodeTextMessage(ChannelId channel, const std::string& text, + NodeId from_node, uint32_t packet_id, + uint8_t* out_buffer, size_t* out_size) +{ + if (!out_buffer || !out_size || text.empty()) + { return false; } - + // Create Data message (like M5Tab5-GPS make_packet_payload) meshtastic_Data data = meshtastic_Data_init_default; data.portnum = meshtastic_PortNum_TEXT_MESSAGE_APP; data.want_response = false; data.has_bitfield = true; data.bitfield = 0; // No special flags for now - + // Set text payload size_t text_len = text.length(); - if (text_len > sizeof(data.payload.bytes)) { + if (text_len > sizeof(data.payload.bytes)) + { return false; // Text too long } data.payload.size = text_len; memcpy(data.payload.bytes, text.c_str(), text_len); - + // Encode Data message uint8_t data_buf[256]; pb_ostream_t data_stream = pb_ostream_from_buffer(data_buf, sizeof(data_buf)); - if (!pb_encode(&data_stream, meshtastic_Data_fields, &data)) { + if (!pb_encode(&data_stream, meshtastic_Data_fields, &data)) + { return false; } size_t data_len = data_stream.bytes_written; - + // Return encoded Data payload // The full packet with wire header will be constructed in mt_adapter - if (*out_size < data_len) { + if (*out_size < data_len) + { *out_size = data_len; return false; } - + memcpy(out_buffer, data_buf, data_len); *out_size = data_len; return true; } -bool decodeTextMessage(const uint8_t* buffer, size_t size, MeshIncomingText* out) { - if (!buffer || !out || size == 0) { - return false; - } - - // Decode Data message (like M5Tab5-GPS) - meshtastic_Data data = meshtastic_Data_init_default; - pb_istream_t stream = pb_istream_from_buffer(buffer, size); - if (!pb_decode(&stream, meshtastic_Data_fields, &data)) { - return false; - } - - // Check port number - if (data.portnum != meshtastic_PortNum_TEXT_MESSAGE_APP && - data.portnum != meshtastic_PortNum_TEXT_MESSAGE_COMPRESSED_APP) { - return false; - } - - // Extract text (decompress if needed) - if (data.payload.size == 0 || data.payload.size > sizeof(data.payload.bytes)) { +bool decodeTextMessage(const uint8_t* buffer, size_t size, MeshIncomingText* out) +{ + if (!buffer || !out || size == 0) + { return false; } - if (data.portnum == meshtastic_PortNum_TEXT_MESSAGE_COMPRESSED_APP) { + // Decode Data message (like M5Tab5-GPS) + meshtastic_Data data = meshtastic_Data_init_default; + pb_istream_t stream = pb_istream_from_buffer(buffer, size); + if (!pb_decode(&stream, meshtastic_Data_fields, &data)) + { + return false; + } + + // Check port number + if (data.portnum != meshtastic_PortNum_TEXT_MESSAGE_APP && + data.portnum != meshtastic_PortNum_TEXT_MESSAGE_COMPRESSED_APP) + { + return false; + } + + // Extract text (decompress if needed) + if (data.payload.size == 0 || data.payload.size > sizeof(data.payload.bytes)) + { + return false; + } + + if (data.portnum == meshtastic_PortNum_TEXT_MESSAGE_COMPRESSED_APP) + { char decompressed[256]; memset(decompressed, 0, sizeof(decompressed)); int out_len = unishox2_decompress_simple( reinterpret_cast(data.payload.bytes), static_cast(data.payload.size), decompressed); - if (out_len <= 0) { + if (out_len <= 0) + { return false; } out->text.assign(decompressed, static_cast(out_len)); - } else { + } + else + { out->text.assign(reinterpret_cast(data.payload.bytes), data.payload.size); } // Note: from, msg_id, timestamp, channel should be extracted from packet header // This will be done in mt_adapter when decoding full packet - out->from = 0; // Will be set from packet header + out->from = 0; // Will be set from packet header out->msg_id = 0; // Will be set from packet header out->timestamp = millis() / 1000; out->channel = ChannelId::PRIMARY; // Will be set from packet header out->hop_limit = 2; out->encrypted = false; - + return true; } bool encodeNodeInfoMessage(const std::string& user_id, const std::string& long_name, const std::string& short_name, meshtastic_HardwareModel hw_model, const uint8_t macaddr[6], const uint8_t* public_key, size_t public_key_len, - bool want_response, uint8_t* out_buffer, size_t* out_size) { - if (!out_buffer || !out_size) { + bool want_response, uint8_t* out_buffer, size_t* out_size) +{ + if (!out_buffer || !out_size) + { return false; } @@ -120,10 +138,12 @@ bool encodeNodeInfoMessage(const std::string& user_id, const std::string& long_n strncpy(user.long_name, long_name.c_str(), sizeof(user.long_name) - 1); strncpy(user.short_name, short_name.c_str(), sizeof(user.short_name) - 1); - if (macaddr != nullptr) { + if (macaddr != nullptr) + { memcpy(user.macaddr, macaddr, sizeof(user.macaddr)); } - if (public_key != nullptr && public_key_len == 32) { + if (public_key != nullptr && public_key_len == 32) + { user.public_key.size = static_cast(public_key_len); memcpy(user.public_key.bytes, public_key, public_key_len); } @@ -132,7 +152,8 @@ bool encodeNodeInfoMessage(const std::string& user_id, const std::string& long_n uint8_t user_buf[128]; pb_ostream_t user_stream = pb_ostream_from_buffer(user_buf, sizeof(user_buf)); - if (!pb_encode(&user_stream, meshtastic_User_fields, &user)) { + if (!pb_encode(&user_stream, meshtastic_User_fields, &user)) + { return false; } size_t user_len = user_stream.bytes_written; @@ -143,14 +164,16 @@ bool encodeNodeInfoMessage(const std::string& user_id, const std::string& long_n data.has_bitfield = true; data.bitfield = 0; - if (user_len > sizeof(data.payload.bytes)) { + if (user_len > sizeof(data.payload.bytes)) + { return false; } data.payload.size = user_len; memcpy(data.payload.bytes, user_buf, user_len); pb_ostream_t data_stream = pb_ostream_from_buffer(out_buffer, *out_size); - if (!pb_encode(&data_stream, meshtastic_Data_fields, &data)) { + if (!pb_encode(&data_stream, meshtastic_Data_fields, &data)) + { return false; } @@ -158,26 +181,31 @@ bool encodeNodeInfoMessage(const std::string& user_id, const std::string& long_n return true; } -bool encodeMeshPacket(const meshtastic_MeshPacket& packet, uint8_t* out_buffer, size_t* out_size) { - if (!out_buffer || !out_size) { +bool encodeMeshPacket(const meshtastic_MeshPacket& packet, uint8_t* out_buffer, size_t* out_size) +{ + if (!out_buffer || !out_size) + { return false; } - + pb_ostream_t stream = pb_ostream_from_buffer(out_buffer, *out_size); - if (!pb_encode(&stream, meshtastic_MeshPacket_fields, &packet)) { + if (!pb_encode(&stream, meshtastic_MeshPacket_fields, &packet)) + { *out_size = stream.bytes_written; return false; } - + *out_size = stream.bytes_written; return true; } -bool decodeMeshPacket(const uint8_t* buffer, size_t size, meshtastic_MeshPacket* out) { - if (!buffer || !out || size == 0) { +bool decodeMeshPacket(const uint8_t* buffer, size_t size, meshtastic_MeshPacket* out) +{ + if (!buffer || !out || size == 0) + { return false; } - + pb_istream_t stream = pb_istream_from_buffer(buffer, size); return pb_decode(&stream, meshtastic_MeshPacket_fields, out); } diff --git a/src/chat/infra/meshtastic/mt_codec_pb.h b/src/chat/infra/meshtastic/mt_codec_pb.h index 9000d1a5..7375f4ba 100644 --- a/src/chat/infra/meshtastic/mt_codec_pb.h +++ b/src/chat/infra/meshtastic/mt_codec_pb.h @@ -1,30 +1,32 @@ /** * @file mt_codec_pb.h * @brief Meshtastic protocol codec using protobuf (nanopb) - * + * * Uses the actual Meshtastic protobuf definitions from M5Tab5-GPS */ #pragma once +#include "../../domain/chat_types.h" #include #include #include -#include "../../domain/chat_types.h" // Include generated nanopb headers from M5Tab5-GPS // Note: pb.h must be included first, and paths are relative to generated/ directory -#include "pb.h" -#include "pb_encode.h" -#include "pb_decode.h" +#include "meshtastic/channel.pb.h" #include "meshtastic/mesh.pb.h" #include "meshtastic/portnums.pb.h" -#include "meshtastic/channel.pb.h" +#include "pb.h" +#include "pb_decode.h" +#include "pb_encode.h" #define MESHTASTIC_PROTOBUF_AVAILABLE 1 -namespace chat { -namespace meshtastic { +namespace chat +{ +namespace meshtastic +{ /** * @brief Encode text message to Meshtastic Data payload using protobuf @@ -36,9 +38,9 @@ namespace meshtastic { * @param out_size Output buffer size (updated with actual size) * @return true if successful */ -bool encodeTextMessage(ChannelId channel, const std::string& text, - NodeId from_node, uint32_t packet_id, - uint8_t* out_buffer, size_t* out_size); +bool encodeTextMessage(ChannelId channel, const std::string& text, + NodeId from_node, uint32_t packet_id, + uint8_t* out_buffer, size_t* out_size); /** * @brief Decode Meshtastic Data payload to text message using protobuf diff --git a/src/chat/infra/meshtastic/mt_dedup.cpp b/src/chat/infra/meshtastic/mt_dedup.cpp index dff112c5..f7572a6a 100644 --- a/src/chat/infra/meshtastic/mt_dedup.cpp +++ b/src/chat/infra/meshtastic/mt_dedup.cpp @@ -5,59 +5,72 @@ #include "mt_dedup.h" -namespace chat { -namespace meshtastic { +namespace chat +{ +namespace meshtastic +{ -MtDedup::MtDedup() : last_cleanup_(millis()) { +MtDedup::MtDedup() : last_cleanup_(millis()) +{ } -MtDedup::~MtDedup() { +MtDedup::~MtDedup() +{ } -bool MtDedup::isDuplicate(NodeId from_node, uint32_t packet_id) { +bool MtDedup::isDuplicate(NodeId from_node, uint32_t packet_id) +{ cleanup(); - + PacketKey key; key.from = from_node; key.id = packet_id; - + return cache_.find(key) != cache_.end(); } -void MtDedup::markSeen(NodeId from_node, uint32_t packet_id) { +void MtDedup::markSeen(NodeId from_node, uint32_t packet_id) +{ cleanup(); - + // Remove oldest if cache is full - if (cache_.size() >= MAX_CACHE_SIZE) { + if (cache_.size() >= MAX_CACHE_SIZE) + { auto oldest = cache_.begin(); cache_.erase(oldest); } - + PacketKey key; key.from = from_node; key.id = packet_id; - + PacketEntry entry; entry.timestamp = millis(); - + cache_[key] = entry; } -void MtDedup::cleanup() { +void MtDedup::cleanup() +{ uint32_t now = millis(); - + // Cleanup every 30 seconds - if (now - last_cleanup_ < 30000) { + if (now - last_cleanup_ < 30000) + { return; } last_cleanup_ = now; - + // Remove expired entries auto it = cache_.begin(); - while (it != cache_.end()) { - if (now - it->second.timestamp > CACHE_TIMEOUT_MS) { + while (it != cache_.end()) + { + if (now - it->second.timestamp > CACHE_TIMEOUT_MS) + { it = cache_.erase(it); - } else { + } + else + { ++it; } } diff --git a/src/chat/infra/meshtastic/mt_dedup.h b/src/chat/infra/meshtastic/mt_dedup.h index 1051878b..ad18bc21 100644 --- a/src/chat/infra/meshtastic/mt_dedup.h +++ b/src/chat/infra/meshtastic/mt_dedup.h @@ -5,26 +5,29 @@ #pragma once -#include -#include #include "../../domain/chat_types.h" +#include #include +#include -namespace chat { -namespace meshtastic { +namespace chat +{ +namespace meshtastic +{ /** * @brief Packet deduplication cache * Prevents processing duplicate packets */ -class MtDedup { -public: +class MtDedup +{ + public: static constexpr size_t MAX_CACHE_SIZE = 100; static constexpr uint32_t CACHE_TIMEOUT_MS = 300000; // 5 minutes - + MtDedup(); ~MtDedup(); - + /** * @brief Check if packet is duplicate * @param from_node Source node ID @@ -32,36 +35,40 @@ public: * @return true if duplicate (already seen) */ bool isDuplicate(NodeId from_node, uint32_t packet_id); - + /** * @brief Mark packet as seen * @param from_node Source node ID * @param packet_id Packet ID */ void markSeen(NodeId from_node, uint32_t packet_id); - + /** * @brief Clear expired entries */ void cleanup(); -private: - struct PacketKey { + private: + struct PacketKey + { NodeId from; uint32_t id; - - bool operator<(const PacketKey& other) const { - if (from != other.from) { + + bool operator<(const PacketKey& other) const + { + if (from != other.from) + { return from < other.from; } return id < other.id; } }; - - struct PacketEntry { + + struct PacketEntry + { uint32_t timestamp; }; - + std::map cache_; uint32_t last_cleanup_; }; diff --git a/src/chat/infra/meshtastic/mt_packet_wire.cpp b/src/chat/infra/meshtastic/mt_packet_wire.cpp index 8571866e..c75fca3c 100644 --- a/src/chat/infra/meshtastic/mt_packet_wire.cpp +++ b/src/chat/infra/meshtastic/mt_packet_wire.cpp @@ -4,37 +4,46 @@ */ #include "mt_packet_wire.h" -#include -#include #include +#include #include +#include -namespace chat { -namespace meshtastic { +namespace chat +{ +namespace meshtastic +{ -namespace { +namespace +{ constexpr size_t kMaxBlockSize = 256; void aesCtrCrypt(const uint8_t* key, size_t key_len, uint8_t* nonce, - uint8_t* buffer, size_t len) { - if (!key || key_len == 0 || !buffer || len == 0) { + uint8_t* buffer, size_t len) +{ + if (!key || key_len == 0 || !buffer || len == 0) + { return; } uint8_t scratch[kMaxBlockSize]; - if (len > sizeof(scratch)) { + if (len > sizeof(scratch)) + { return; } memcpy(scratch, buffer, len); memset(scratch + len, 0, sizeof(scratch) - len); - if (key_len == 16) { + if (key_len == 16) + { CTR ctr; ctr.setKey(key, key_len); ctr.setIV(nonce, 16); ctr.setCounterSize(4); ctr.encrypt(buffer, scratch, len); - } else { + } + else + { CTR ctr; ctr.setKey(key, key_len); ctr.setIV(nonce, 16); @@ -45,21 +54,24 @@ void aesCtrCrypt(const uint8_t* key, size_t key_len, uint8_t* nonce, } // namespace bool buildWirePacket(const uint8_t* data_payload, size_t data_len, - uint32_t from_node, uint32_t packet_id, - uint32_t dest_node, uint8_t channel_hash, - uint8_t hop_limit, bool want_ack, - const uint8_t* psk, size_t psk_len, - uint8_t* out_buffer, size_t* out_size) { - if (!data_payload || !out_buffer || !out_size || data_len == 0) { + uint32_t from_node, uint32_t packet_id, + uint32_t dest_node, uint8_t channel_hash, + uint8_t hop_limit, bool want_ack, + const uint8_t* psk, size_t psk_len, + uint8_t* out_buffer, size_t* out_size) +{ + if (!data_payload || !out_buffer || !out_size || data_len == 0) + { return false; } - + // Encrypt payload if PSK provided uint8_t payload[256]; size_t payload_len = data_len; memcpy(payload, data_payload, data_len); - - if (psk && psk_len > 0) { + + if (psk && psk_len > 0) + { uint8_t nonce[16]; memset(nonce, 0, sizeof(nonce)); uint64_t packet_id64 = static_cast(packet_id); @@ -67,83 +79,91 @@ bool buildWirePacket(const uint8_t* data_payload, size_t data_len, memcpy(nonce + sizeof(uint64_t), &from_node, sizeof(uint32_t)); aesCtrCrypt(psk, psk_len, nonce, payload, payload_len); } - + // Build header PacketHeaderWire hdr{}; hdr.to = dest_node; hdr.from = from_node; hdr.id = packet_id; - + uint8_t hop_start = hop_limit; uint8_t flags = (hop_limit & PACKET_FLAGS_HOP_LIMIT_MASK) | ((hop_start << PACKET_FLAGS_HOP_START_SHIFT) & PACKET_FLAGS_HOP_START_MASK); - if (want_ack) { + if (want_ack) + { flags |= PACKET_FLAGS_WANT_ACK_MASK; } hdr.flags = flags; hdr.channel = channel_hash; hdr.next_hop = 0; hdr.relay_node = static_cast(from_node & 0xFF); - + // Build full packet size_t required_size = sizeof(hdr) + payload_len; - if (*out_size < required_size) { + if (*out_size < required_size) + { *out_size = required_size; return false; } - + memcpy(out_buffer, &hdr, sizeof(hdr)); memcpy(out_buffer + sizeof(hdr), payload, payload_len); - + *out_size = required_size; return true; } bool parseWirePacket(const uint8_t* buffer, size_t size, - PacketHeaderWire* out_header, - uint8_t* out_payload, size_t* out_payload_size) { - if (!buffer || !out_header || !out_payload || !out_payload_size || size < sizeof(PacketHeaderWire)) { + PacketHeaderWire* out_header, + uint8_t* out_payload, size_t* out_payload_size) +{ + if (!buffer || !out_header || !out_payload || !out_payload_size || size < sizeof(PacketHeaderWire)) + { return false; } - + // Extract header memcpy(out_header, buffer, sizeof(PacketHeaderWire)); - + // Extract payload size_t payload_len = size - sizeof(PacketHeaderWire); - if (payload_len > *out_payload_size) { + if (payload_len > *out_payload_size) + { *out_payload_size = payload_len; return false; } - + memcpy(out_payload, buffer + sizeof(PacketHeaderWire), payload_len); *out_payload_size = payload_len; return true; } bool decryptPayload(const PacketHeaderWire& header, - const uint8_t* cipher, size_t cipher_len, - const uint8_t* psk, size_t psk_len, - uint8_t* out_plaintext, size_t* out_plain_len) { - if (!cipher || !psk || !out_plaintext || cipher_len == 0) { + const uint8_t* cipher, size_t cipher_len, + const uint8_t* psk, size_t psk_len, + uint8_t* out_plaintext, size_t* out_plain_len) +{ + if (!cipher || !psk || !out_plaintext || cipher_len == 0) + { return false; } - - if (*out_plain_len < cipher_len) { + + if (*out_plain_len < cipher_len) + { *out_plain_len = cipher_len; return false; } - + // Build nonce uint8_t nonce[16]; memset(nonce, 0, 16); uint64_t packet_id64 = static_cast(header.id); memcpy(nonce, &packet_id64, sizeof(uint64_t)); memcpy(nonce + sizeof(uint64_t), &header.from, sizeof(uint32_t)); - + memcpy(out_plaintext, cipher, cipher_len); aesCtrCrypt(psk, psk_len, nonce, out_plaintext, cipher_len); - + *out_plain_len = cipher_len; return true; } diff --git a/src/chat/infra/meshtastic/mt_packet_wire.h b/src/chat/infra/meshtastic/mt_packet_wire.h index ecf4cc5b..e4b4f07d 100644 --- a/src/chat/infra/meshtastic/mt_packet_wire.h +++ b/src/chat/infra/meshtastic/mt_packet_wire.h @@ -5,17 +5,20 @@ #pragma once -#include #include +#include -namespace chat { -namespace meshtastic { +namespace chat +{ +namespace meshtastic +{ /** * @brief Packet header wire format (from M5Tab5-GPS) * This matches Meshtastic's on-air packet format */ -struct PacketHeaderWire { +struct PacketHeaderWire +{ uint32_t to; uint32_t from; uint32_t id; @@ -26,10 +29,10 @@ struct PacketHeaderWire { } __attribute__((packed)); // Packet header flag masks (from M5Tab5-GPS) -constexpr uint8_t PACKET_FLAGS_HOP_LIMIT_MASK = 0x07; -constexpr uint8_t PACKET_FLAGS_WANT_ACK_MASK = 0x08; -constexpr uint8_t PACKET_FLAGS_VIA_MQTT_MASK = 0x10; -constexpr uint8_t PACKET_FLAGS_HOP_START_MASK = 0xE0; +constexpr uint8_t PACKET_FLAGS_HOP_LIMIT_MASK = 0x07; +constexpr uint8_t PACKET_FLAGS_WANT_ACK_MASK = 0x08; +constexpr uint8_t PACKET_FLAGS_VIA_MQTT_MASK = 0x10; +constexpr uint8_t PACKET_FLAGS_HOP_START_MASK = 0xE0; constexpr uint8_t PACKET_FLAGS_HOP_START_SHIFT = 5; /** @@ -49,11 +52,11 @@ constexpr uint8_t PACKET_FLAGS_HOP_START_SHIFT = 5; * @return true if successful */ bool buildWirePacket(const uint8_t* data_payload, size_t data_len, - uint32_t from_node, uint32_t packet_id, - uint32_t dest_node, uint8_t channel_hash, - uint8_t hop_limit, bool want_ack, - const uint8_t* psk, size_t psk_len, - uint8_t* out_buffer, size_t* out_size); + uint32_t from_node, uint32_t packet_id, + uint32_t dest_node, uint8_t channel_hash, + uint8_t hop_limit, bool want_ack, + const uint8_t* psk, size_t psk_len, + uint8_t* out_buffer, size_t* out_size); /** * @brief Parse wire packet to extract header and payload @@ -65,8 +68,8 @@ bool buildWirePacket(const uint8_t* data_payload, size_t data_len, * @return true if successful */ bool parseWirePacket(const uint8_t* buffer, size_t size, - PacketHeaderWire* out_header, - uint8_t* out_payload, size_t* out_payload_size); + PacketHeaderWire* out_header, + uint8_t* out_payload, size_t* out_payload_size); /** * @brief Decrypt payload using AES-CTR (like M5Tab5-GPS) @@ -80,9 +83,9 @@ bool parseWirePacket(const uint8_t* buffer, size_t size, * @return true if successful */ bool decryptPayload(const PacketHeaderWire& header, - const uint8_t* cipher, size_t cipher_len, - const uint8_t* psk, size_t psk_len, - uint8_t* out_plaintext, size_t* out_plain_len); + const uint8_t* cipher, size_t cipher_len, + const uint8_t* psk, size_t psk_len, + uint8_t* out_plaintext, size_t* out_plain_len); } // namespace meshtastic } // namespace chat diff --git a/src/chat/infra/meshtastic/mt_region.cpp b/src/chat/infra/meshtastic/mt_region.cpp new file mode 100644 index 00000000..0d904134 --- /dev/null +++ b/src/chat/infra/meshtastic/mt_region.cpp @@ -0,0 +1,171 @@ +/** + * @file mt_region.cpp + * @brief Meshtastic region utilities + */ + +#include "mt_region.h" +#include + +namespace chat +{ +namespace meshtastic +{ + +namespace +{ + +const RegionInfo kRegions[] = { + {meshtastic_Config_LoRaConfig_RegionCode_UNSET, "UNSET", 902.0f, 928.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_US, "US", 902.0f, 928.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_EU_433, "EU_433", 433.0f, 434.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_EU_868, "EU_868", 869.4f, 869.65f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_CN, "CN", 470.0f, 510.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_JP, "JP", 920.5f, 923.5f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_ANZ, "ANZ", 915.0f, 928.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_KR, "KR", 920.0f, 923.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_TW, "TW", 920.0f, 925.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_RU, "RU", 868.7f, 869.2f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_IN, "IN", 865.0f, 867.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_NZ_865, "NZ_865", 865.0f, 867.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_TH, "TH", 920.0f, 925.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_LORA_24, "LORA_24", 2400.0f, 2483.5f, 0.0f, true}, + {meshtastic_Config_LoRaConfig_RegionCode_UA_433, "UA_433", 433.0f, 434.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_UA_868, "UA_868", 868.0f, 868.6f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_MY_433, "MY_433", 433.0f, 434.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_MY_919, "MY_919", 919.0f, 923.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_SG_923, "SG_923", 920.0f, 925.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_PH_433, "PH_433", 433.0f, 434.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_PH_868, "PH_868", 868.0f, 869.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_PH_915, "PH_915", 915.0f, 918.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_ANZ_433, "ANZ_433", 433.0f, 434.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_KZ_433, "KZ_433", 433.0f, 434.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_KZ_863, "KZ_863", 863.0f, 870.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_NP_865, "NP_865", 865.0f, 867.0f, 0.0f, false}, + {meshtastic_Config_LoRaConfig_RegionCode_BR_902, "BR_902", 902.0f, 928.0f, 0.0f, false}, +}; +uint32_t djb2Hash(const char* str) +{ + uint32_t hash = 5381; + int c; + while ((c = *str++) != 0) + { + hash = ((hash << 5) + hash) + static_cast(c); + } + return hash; +} + +} // namespace + +const RegionInfo* getRegionTable(size_t* out_count) +{ + if (out_count) + { + *out_count = sizeof(kRegions) / sizeof(kRegions[0]); + } + return kRegions; +} + +const RegionInfo* findRegion(meshtastic_Config_LoRaConfig_RegionCode code) +{ + for (const auto& region : kRegions) + { + if (region.code == code) + { + return ®ion; + } + } + return &kRegions[0]; +} + +const char* presetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset) +{ + switch (preset) + { + case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST: + return "LongFast"; + case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE: + return "LongModerate"; + case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW: + return "LongSlow"; + case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW: + return "MediumSlow"; + case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST: + return "MediumFast"; + case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW: + return "ShortSlow"; + case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST: + return "ShortFast"; + case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO: + return "ShortTurbo"; + default: + return "LongFast"; + } +} + +float computeFrequencyMhz(const RegionInfo* region, float bw_khz, const char* channel_name) +{ + if (!region || !channel_name) + { + return 0.0f; + } + float spacing_khz = region->spacing_khz > 0.0f ? region->spacing_khz : 0.0f; + float spacing_mhz = spacing_khz / 1000.0f; + float bw_mhz = bw_khz / 1000.0f; + float span_mhz = region->freq_end_mhz - region->freq_start_mhz; + uint32_t num_channels = static_cast(floor(span_mhz / (spacing_mhz + bw_mhz))); + if (num_channels < 1) + { + num_channels = 1; + } + uint32_t channel_num = djb2Hash(channel_name) % num_channels; + return region->freq_start_mhz + (bw_khz / 2000.0f) + (channel_num * (bw_khz / 1000.0f)); +} + +float estimateFrequencyMhz(uint8_t region_code, uint8_t modem_preset) +{ + meshtastic_Config_LoRaConfig_RegionCode region = + static_cast(region_code); + if (region == meshtastic_Config_LoRaConfig_RegionCode_UNSET) + { + region = meshtastic_Config_LoRaConfig_RegionCode_CN; + } + const RegionInfo* info = findRegion(region); + meshtastic_Config_LoRaConfig_ModemPreset preset = + static_cast(modem_preset); + + float bw_khz = 250.0f; + switch (preset) + { + case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO: + bw_khz = info->wide_lora ? 1625.0f : 500.0f; + break; + case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST: + bw_khz = info->wide_lora ? 812.5f : 250.0f; + break; + case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW: + bw_khz = info->wide_lora ? 812.5f : 250.0f; + break; + case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST: + bw_khz = info->wide_lora ? 812.5f : 250.0f; + break; + case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW: + bw_khz = info->wide_lora ? 812.5f : 250.0f; + break; + case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE: + bw_khz = info->wide_lora ? 406.25f : 125.0f; + break; + case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW: + bw_khz = info->wide_lora ? 406.25f : 125.0f; + break; + case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST: + default: + bw_khz = info->wide_lora ? 812.5f : 250.0f; + break; + } + + const char* channel_name = presetDisplayName(preset); + return computeFrequencyMhz(info, bw_khz, channel_name); +} + +} // namespace meshtastic +} // namespace chat diff --git a/src/chat/infra/meshtastic/mt_region.h b/src/chat/infra/meshtastic/mt_region.h new file mode 100644 index 00000000..fb06584c --- /dev/null +++ b/src/chat/infra/meshtastic/mt_region.h @@ -0,0 +1,33 @@ +/** + * @file mt_region.h + * @brief Meshtastic region utilities + */ + +#pragma once + +#include "generated/meshtastic/config.pb.h" +#include + +namespace chat +{ +namespace meshtastic +{ + +struct RegionInfo +{ + meshtastic_Config_LoRaConfig_RegionCode code; + const char* label; + float freq_start_mhz; + float freq_end_mhz; + float spacing_khz; + bool wide_lora; +}; + +const RegionInfo* getRegionTable(size_t* out_count); +const RegionInfo* findRegion(meshtastic_Config_LoRaConfig_RegionCode code); +const char* presetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset); +float computeFrequencyMhz(const RegionInfo* region, float bw_khz, const char* channel_name); +float estimateFrequencyMhz(uint8_t region_code, uint8_t modem_preset); + +} // namespace meshtastic +} // namespace chat diff --git a/src/chat/infra/meshtastic/node_store.cpp b/src/chat/infra/meshtastic/node_store.cpp index 5493a9d0..a67ec078 100644 --- a/src/chat/infra/meshtastic/node_store.cpp +++ b/src/chat/infra/meshtastic/node_store.cpp @@ -7,18 +7,24 @@ #include "../../ports/i_node_store.h" #include -namespace chat { -namespace meshtastic { +namespace chat +{ +namespace meshtastic +{ -void NodeStore::begin() { +void NodeStore::begin() +{ Preferences prefs; - if (!prefs.begin(kNs, true)) { + if (!prefs.begin(kNs, true)) + { return; } size_t len = prefs.getBytesLength(kKey); - if (len > 0 && (len % sizeof(contacts::NodeEntry) == 0)) { + if (len > 0 && (len % sizeof(contacts::NodeEntry) == 0)) + { size_t count = len / sizeof(contacts::NodeEntry); - if (count > kMaxNodes) { + if (count > kMaxNodes) + { count = kMaxNodes; } entries_.resize(count); @@ -27,56 +33,118 @@ void NodeStore::begin() { prefs.end(); } -void NodeStore::upsert(uint32_t node_id, const char* short_name, const char* long_name, uint32_t now_secs, float snr) { +void NodeStore::upsert(uint32_t node_id, const char* short_name, const char* long_name, uint32_t now_secs, float snr, uint8_t protocol) +{ // find existing - for (auto& e : entries_) { - if (e.node_id == node_id) { - if (short_name) { + for (auto& e : entries_) + { + if (e.node_id == node_id) + { + if (short_name && short_name[0] != '\0') + { strncpy(e.short_name, short_name, sizeof(e.short_name) - 1); e.short_name[sizeof(e.short_name) - 1] = '\0'; } - if (long_name) { + if (long_name && long_name[0] != '\0') + { strncpy(e.long_name, long_name, sizeof(e.long_name) - 1); e.long_name[sizeof(e.long_name) - 1] = '\0'; } e.last_seen = now_secs; e.snr = snr; + if (protocol != 0) + { + e.protocol = protocol; + } save(); return; } } - if (entries_.size() >= kMaxNodes) { + if (entries_.size() >= kMaxNodes) + { entries_.erase(entries_.begin()); // drop oldest } contacts::NodeEntry e{}; e.node_id = node_id; - if (short_name) { + if (short_name && short_name[0] != '\0') + { strncpy(e.short_name, short_name, sizeof(e.short_name) - 1); e.short_name[sizeof(e.short_name) - 1] = '\0'; } - if (long_name) { + if (long_name && long_name[0] != '\0') + { strncpy(e.long_name, long_name, sizeof(e.long_name) - 1); e.long_name[sizeof(e.long_name) - 1] = '\0'; } e.last_seen = now_secs; e.snr = snr; + e.protocol = protocol; entries_.push_back(e); save(); } -void NodeStore::save() { - Preferences prefs; - if (!prefs.begin(kNs, false)) { +void NodeStore::updateProtocol(uint32_t node_id, uint8_t protocol, uint32_t now_secs) +{ + if (protocol == 0) + { return; } - if (!entries_.empty()) { + for (auto& e : entries_) + { + if (e.node_id == node_id) + { + e.protocol = protocol; + e.last_seen = now_secs; + save(); + return; + } + } + + if (entries_.size() >= kMaxNodes) + { + entries_.erase(entries_.begin()); // drop oldest + } + contacts::NodeEntry e{}; + e.node_id = node_id; + e.short_name[0] = '\0'; + e.long_name[0] = '\0'; + e.last_seen = now_secs; + e.snr = 0.0f; + e.protocol = protocol; + entries_.push_back(e); + save(); +} + +void NodeStore::save() +{ + Preferences prefs; + if (!prefs.begin(kNs, false)) + { + return; + } + if (!entries_.empty()) + { prefs.putBytes(kKey, entries_.data(), entries_.size() * sizeof(contacts::NodeEntry)); - } else { + } + else + { prefs.remove(kKey); } prefs.end(); } +void NodeStore::clear() +{ + entries_.clear(); + Preferences prefs; + if (!prefs.begin(kNs, false)) + { + return; + } + prefs.remove(kKey); + prefs.end(); +} + } // namespace meshtastic } // namespace chat diff --git a/src/chat/infra/meshtastic/node_store.h b/src/chat/infra/meshtastic/node_store.h index ac21de85..135f3a22 100644 --- a/src/chat/infra/meshtastic/node_store.h +++ b/src/chat/infra/meshtastic/node_store.h @@ -12,34 +12,48 @@ #include "../../ports/i_node_store.h" #include #include -#include #include +#include -namespace chat { -namespace meshtastic { +namespace chat +{ +namespace meshtastic +{ -class NodeStore : public contacts::INodeStore { -public: +class NodeStore : public contacts::INodeStore +{ + public: NodeStore() = default; /** - * @brief Load from Preferences (best effort) - */ + * @brief Load from Preferences (best effort) + */ void begin() override; /** - * @brief Update or insert a node entry and persist (best effort) - */ - void upsert(uint32_t node_id, const char* short_name, const char* long_name, uint32_t now_secs, float snr = 0.0f) override; + * @brief Update or insert a node entry and persist (best effort) + */ + void upsert(uint32_t node_id, const char* short_name, const char* long_name, uint32_t now_secs, float snr = 0.0f, uint8_t protocol = 0) override; /** - * @brief Get all entries (for iteration) - */ - const std::vector& getEntries() const override { + * @brief Update protocol for an existing node (best effort) + */ + void updateProtocol(uint32_t node_id, uint8_t protocol, uint32_t now_secs) override; + + /** + * @brief Get all entries (for iteration) + */ + const std::vector& getEntries() const override + { return entries_; } -private: + /** + * @brief Clear all entries and persisted data + */ + void clear() override; + + private: static constexpr size_t kMaxNodes = 16; static constexpr const char* kNs = "nodes"; static constexpr const char* kKey = "node_blob"; diff --git a/src/chat/infra/mock_mesh_adapter.cpp b/src/chat/infra/mock_mesh_adapter.cpp deleted file mode 100644 index 4ce9db3f..00000000 --- a/src/chat/infra/mock_mesh_adapter.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file mock_mesh_adapter.cpp - * @brief Mock mesh adapter implementation - */ - -#include "mock_mesh_adapter.h" -#include - -namespace chat { - -MockMeshAdapter::MockMeshAdapter() - : next_msg_id_(1000), failure_rate_(0.0f), send_delay_ms_(100), ready_(true) { -} - -MockMeshAdapter::~MockMeshAdapter() { -} - -bool MockMeshAdapter::sendText(ChannelId channel, const std::string& text, - MessageId* out_msg_id, NodeId /*peer*/) { - if (!ready_) { - return false; - } - - // Simulate failure - if (failure_rate_ > 0.0f) { - float r = (float)random(0, 1000) / 1000.0f; - if (r < failure_rate_) { - return false; - } - } - - // Process send queue periodically - processSendQueue(); - - // Queue for delayed send - PendingSend pending; - pending.channel = channel; - pending.text = text; - pending.msg_id = next_msg_id_++; - pending.queued_time = millis(); - - send_queue_.push(pending); - - if (out_msg_id) { - *out_msg_id = pending.msg_id; - } - - return true; -} - -bool MockMeshAdapter::pollIncomingText(MeshIncomingText* out) { - if (receive_queue_.empty()) { - return false; - } - - *out = receive_queue_.front(); - receive_queue_.pop(); - return true; -} - -void MockMeshAdapter::applyConfig(const MeshConfig& config) { - config_ = config; -} - -bool MockMeshAdapter::isReady() const { - return ready_; -} - -void MockMeshAdapter::simulateReceive(ChannelId channel, const std::string& text, NodeId from) { - MeshIncomingText incoming; - incoming.channel = channel; - incoming.from = from; - incoming.msg_id = next_msg_id_++; - incoming.timestamp = millis() / 1000; - incoming.text = text; - incoming.hop_limit = 2; - incoming.encrypted = (channel == ChannelId::SECONDARY); - - receive_queue_.push(incoming); -} - -void MockMeshAdapter::processSendQueue() { - uint32_t now = millis(); - - while (!send_queue_.empty()) { - PendingSend& pending = send_queue_.front(); - - if (now - pending.queued_time >= send_delay_ms_) { - // Simulate echo back (for testing) - simulateReceive(pending.channel, pending.text, 0); - send_queue_.pop(); - } else { - break; // Not ready yet - } - } -} - -} // namespace chat diff --git a/src/chat/infra/mock_mesh_adapter.h b/src/chat/infra/mock_mesh_adapter.h deleted file mode 100644 index 284ba78f..00000000 --- a/src/chat/infra/mock_mesh_adapter.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file mock_mesh_adapter.h - * @brief Mock mesh adapter for testing - */ - -#pragma once - -#include "../ports/i_mesh_adapter.h" -#include "../domain/chat_types.h" -#include -#include - -namespace chat { - -/** - * @brief Mock mesh adapter for UI testing - * Simulates mesh behavior without actual LoRa communication - */ -class MockMeshAdapter : public IMeshAdapter { -public: - MockMeshAdapter(); - virtual ~MockMeshAdapter(); - - bool sendText(ChannelId channel, const std::string& text, - MessageId* out_msg_id, NodeId peer = 0) override; - bool pollIncomingText(MeshIncomingText* out) override; - void applyConfig(const MeshConfig& config) override; - bool isReady() const override; - - /** - * @brief Simulate receiving a message (for testing) - */ - void simulateReceive(ChannelId channel, const std::string& text, NodeId from = 12345); - - /** - * @brief Set failure rate (0.0 = never fail, 1.0 = always fail) - */ - void setFailureRate(float rate) { - failure_rate_ = rate; - } - - /** - * @brief Set delay before send succeeds (ms) - */ - void setSendDelay(uint32_t delay_ms) { - send_delay_ms_ = delay_ms; - } - -private: - struct PendingSend { - ChannelId channel; - std::string text; - MessageId msg_id; - uint32_t queued_time; - }; - - std::queue send_queue_; - std::queue receive_queue_; - MessageId next_msg_id_; - float failure_rate_; - uint32_t send_delay_ms_; - bool ready_; - MeshConfig config_; - - void processSendQueue(); -}; - -} // namespace chat diff --git a/src/chat/infra/protocol_factory.cpp b/src/chat/infra/protocol_factory.cpp new file mode 100644 index 00000000..e7b7e9fa --- /dev/null +++ b/src/chat/infra/protocol_factory.cpp @@ -0,0 +1,23 @@ +/** + * @file protocol_factory.cpp + * @brief Factory for creating protocol-specific mesh adapters + */ + +#include "protocol_factory.h" +#include "meshtastic/mt_adapter.h" +#include "meshcore/meshcore_adapter.h" + +namespace chat { + +std::unique_ptr ProtocolFactory::createAdapter(MeshProtocol protocol, + TLoRaPagerBoard& board) { + switch (protocol) { + case MeshProtocol::MeshCore: + return std::make_unique(board); + case MeshProtocol::Meshtastic: + default: + return std::make_unique(board); + } +} + +} // namespace chat diff --git a/src/chat/infra/protocol_factory.h b/src/chat/infra/protocol_factory.h new file mode 100644 index 00000000..98b1aa82 --- /dev/null +++ b/src/chat/infra/protocol_factory.h @@ -0,0 +1,30 @@ +/** + * @file protocol_factory.h + * @brief Factory for creating protocol-specific mesh adapters + */ + +#pragma once + +#include "../domain/chat_types.h" +#include "../ports/i_mesh_adapter.h" +#include "../../board/TLoRaPagerBoard.h" +#include + +namespace chat { + +/** + * @brief Factory class for creating mesh adapters based on protocol selection + */ +class ProtocolFactory { +public: + ProtocolFactory() = delete; + ~ProtocolFactory() = delete; + + /** + * @brief Create a mesh adapter for the specified protocol + */ + static std::unique_ptr createAdapter(MeshProtocol protocol, + TLoRaPagerBoard& board); +}; + +} // namespace chat diff --git a/src/chat/infra/store/flash_store.cpp b/src/chat/infra/store/flash_store.cpp index 0c7f0fc4..b3bc6e0b 100644 --- a/src/chat/infra/store/flash_store.cpp +++ b/src/chat/infra/store/flash_store.cpp @@ -4,27 +4,33 @@ */ #include "flash_store.h" -#include #include +#include -namespace chat { +namespace chat +{ -FlashStore::FlashStore() { +FlashStore::FlashStore() +{ ready_ = prefs_.begin(kPrefsNs, false); records_.resize(kMaxMessages); - if (!ready_) { + if (!ready_) + { return; } loadFromPrefs(); } -FlashStore::~FlashStore() { - if (ready_) { +FlashStore::~FlashStore() +{ + if (ready_) + { prefs_.end(); } } -void FlashStore::append(const ChatMessage& msg) { +void FlashStore::append(const ChatMessage& msg) +{ if (!ready_) return; Record rec{}; @@ -35,7 +41,8 @@ void FlashStore::append(const ChatMessage& msg) { rec.peer = msg.peer; rec.msg_id = msg.msg_id; rec.timestamp = msg.timestamp; - if (rec.text_len > 0) { + if (rec.text_len > 0) + { memcpy(rec.text, msg.text.data(), rec.text_len); } @@ -47,20 +54,24 @@ void FlashStore::append(const ChatMessage& msg) { persistMeta(); } -std::vector FlashStore::loadRecent(ChannelId channel, size_t n) { +std::vector FlashStore::loadRecent(ChannelId channel, size_t n) +{ std::vector out; if (!ready_ || count_ == 0 || n == 0) return out; out.reserve(std::min(n, count_)); size_t collected = 0; - for (size_t i = 0; i < count_ && collected < n; ++i) { + for (size_t i = 0; i < count_ && collected < n; ++i) + { size_t idx = (head_ + kMaxMessages - 1 - i) % kMaxMessages; const Record& rec = records_[idx]; - if (rec.text_len == 0) { + if (rec.text_len == 0) + { continue; } - if (static_cast(rec.channel) != channel) { + if (static_cast(rec.channel) != channel) + { continue; } ChatMessage msg; @@ -79,16 +90,19 @@ std::vector FlashStore::loadRecent(ChannelId channel, size_t n) { return out; } -std::vector FlashStore::loadAll() const { +std::vector FlashStore::loadAll() const +{ std::vector out; if (!ready_ || count_ == 0) return out; out.reserve(count_); size_t start = (head_ + kMaxMessages - count_) % kMaxMessages; - for (size_t i = 0; i < count_; ++i) { + for (size_t i = 0; i < count_; ++i) + { size_t idx = (start + i) % kMaxMessages; const Record& rec = records_[idx]; - if (rec.text_len == 0) { + if (rec.text_len == 0) + { continue; } ChatMessage msg; @@ -104,34 +118,41 @@ std::vector FlashStore::loadAll() const { return out; } -void FlashStore::setUnread(ChannelId channel, int unread) { +void FlashStore::setUnread(ChannelId channel, int unread) +{ if (!ready_) return; char key[16]; snprintf(key, sizeof(key), "unread_%u", static_cast(channel)); prefs_.putInt(key, unread); } -int FlashStore::getUnread(ChannelId channel) const { +int FlashStore::getUnread(ChannelId channel) const +{ if (!ready_) return 0; char key[16]; snprintf(key, sizeof(key), "unread_%u", static_cast(channel)); return prefs_.getInt(key, 0); } -void FlashStore::clearChannel(ChannelId channel) { +void FlashStore::clearChannel(ChannelId channel) +{ if (!ready_) return; - for (size_t i = 0; i < kMaxMessages; ++i) { + for (size_t i = 0; i < kMaxMessages; ++i) + { Record& rec = records_[i]; - if (static_cast(rec.channel) == channel) { + if (static_cast(rec.channel) == channel) + { rec = {}; persistRecord(static_cast(i)); } } } -void FlashStore::loadFromPrefs() { +void FlashStore::loadFromPrefs() +{ uint8_t ver = prefs_.getUChar(kKeyVer, 0); - if (ver != kVersion) { + if (ver != kVersion) + { clearAll(); return; } @@ -141,37 +162,45 @@ void FlashStore::loadFromPrefs() { if (head_ >= kMaxMessages) head_ = 0; if (count_ > kMaxMessages) count_ = kMaxMessages; - for (uint16_t i = 0; i < kMaxMessages; ++i) { + for (uint16_t i = 0; i < kMaxMessages; ++i) + { char key[8]; snprintf(key, sizeof(key), "m%03u", static_cast(i)); size_t actual = prefs_.getBytesLength(key); - if (actual == sizeof(Record)) { + if (actual == sizeof(Record)) + { prefs_.getBytes(key, &records_[i], sizeof(Record)); - } else { + } + else + { records_[i] = {}; } } } -void FlashStore::persistMeta() { +void FlashStore::persistMeta() +{ prefs_.putUChar(kKeyVer, kVersion); prefs_.putUShort(kKeyHead, head_); prefs_.putUShort(kKeyCount, count_); } -void FlashStore::persistRecord(uint16_t idx) { +void FlashStore::persistRecord(uint16_t idx) +{ if (idx >= kMaxMessages) return; char key[8]; snprintf(key, sizeof(key), "m%03u", static_cast(idx)); prefs_.putBytes(key, &records_[idx], sizeof(Record)); } -void FlashStore::clearAll() { +void FlashStore::clearAll() +{ head_ = 0; count_ = 0; std::fill(records_.begin(), records_.end(), Record{}); persistMeta(); - for (uint16_t i = 0; i < kMaxMessages; ++i) { + for (uint16_t i = 0; i < kMaxMessages; ++i) + { persistRecord(i); } } diff --git a/src/chat/infra/store/flash_store.h b/src/chat/infra/store/flash_store.h index e5d49ae5..37c986d5 100644 --- a/src/chat/infra/store/flash_store.h +++ b/src/chat/infra/store/flash_store.h @@ -5,15 +5,17 @@ #pragma once -#include "../../ports/i_chat_store.h" #include "../../domain/chat_types.h" +#include "../../ports/i_chat_store.h" #include #include -namespace chat { +namespace chat +{ -class FlashStore : public IChatStore { -public: +class FlashStore : public IChatStore +{ + public: static constexpr size_t kMaxMessages = 300; static constexpr size_t kMaxTextLen = 220; @@ -30,8 +32,9 @@ public: std::vector loadAll() const; -private: - struct Record { + private: + struct Record + { uint8_t channel; uint8_t status; uint16_t text_len; diff --git a/src/chat/infra/store/log_store.cpp b/src/chat/infra/store/log_store.cpp index 60a269c6..74e58edb 100644 --- a/src/chat/infra/store/log_store.cpp +++ b/src/chat/infra/store/log_store.cpp @@ -7,23 +7,31 @@ #include #include -namespace chat { +namespace chat +{ -namespace { +namespace +{ constexpr uint16_t kMagic = 0x434D; // "CM" constexpr uint8_t kVersion = 1; -constexpr size_t kHeadCopies = 2; // A/B +constexpr size_t kHeadCopies = 2; // A/B -const char* indexPath(ChannelId ch) { - switch (ch) { - case ChannelId::PRIMARY: return "/chat/idx_ch0.bin"; - case ChannelId::SECONDARY: return "/chat/idx_ch1.bin"; - default: return "/chat/idx_other.bin"; +const char* indexPath(ChannelId ch) +{ + switch (ch) + { + case ChannelId::PRIMARY: + return "/chat/idx_ch0.bin"; + case ChannelId::SECONDARY: + return "/chat/idx_ch1.bin"; + default: + return "/chat/idx_other.bin"; } } } // namespace -bool LogStore::begin(fs::FS& fs) { +bool LogStore::begin(fs::FS& fs) +{ fs_ = &fs; if (!ensureDir()) return false; @@ -32,7 +40,8 @@ bool LogStore::begin(fs::FS& fs) { return true; } -void LogStore::append(const ChatMessage& msg) { +void LogStore::append(const ChatMessage& msg) +{ if (!fs_) return; File log = fs_->open(kLogFile, FILE_APPEND); if (!log) return; @@ -49,11 +58,13 @@ void LogStore::append(const ChatMessage& msg) { uint32_t offset = log.size(); log.write(reinterpret_cast(&hdr), sizeof(hdr)); - if (hdr.payload_len > 0) { + if (hdr.payload_len > 0) + { log.write(reinterpret_cast(msg.text.data()), hdr.payload_len); } uint32_t crc = crc32(reinterpret_cast(&hdr), sizeof(hdr)); - if (hdr.payload_len > 0) { + if (hdr.payload_len > 0) + { crc = crc32(reinterpret_cast(msg.text.data()), hdr.payload_len) ^ crc; } log.write(reinterpret_cast(&crc), sizeof(crc)); @@ -78,7 +89,8 @@ void LogStore::append(const ChatMessage& msg) { persistHead(msg.channel); } -std::vector LogStore::loadRecent(ChannelId channel, size_t n) { +std::vector LogStore::loadRecent(ChannelId channel, size_t n) +{ std::vector out; if (!fs_) return out; const ChannelIndex& cx = idx(channel); @@ -90,7 +102,8 @@ std::vector LogStore::loadRecent(ChannelId channel, size_t n) { File log = fs_->open(kLogFile, FILE_READ); if (!log) return out; - for (size_t i = 0; i < total; ++i) { + for (size_t i = 0; i < total; ++i) + { int idx_pos = (cx.head.next + kSlotsPerChannel - 1 - i) % kSlotsPerChannel; const IndexSlot& slot = cx.slots[idx_pos]; if (slot.len == 0) continue; @@ -100,13 +113,15 @@ std::vector LogStore::loadRecent(ChannelId channel, size_t n) { if (hdr.magic != kMagic || hdr.ver != kVersion) continue; std::string payload; payload.resize(hdr.payload_len); - if (hdr.payload_len > 0) { + if (hdr.payload_len > 0) + { if (log.read(reinterpret_cast(&payload[0]), hdr.payload_len) != hdr.payload_len) continue; } uint32_t crc_disk = 0; log.read(reinterpret_cast(&crc_disk), sizeof(crc_disk)); uint32_t crc_calc = crc32(reinterpret_cast(&hdr), sizeof(hdr)); - if (hdr.payload_len > 0) { + if (hdr.payload_len > 0) + { crc_calc = crc32(reinterpret_cast(payload.data()), hdr.payload_len) ^ crc_calc; } if (crc_calc != crc_disk) continue; @@ -123,39 +138,47 @@ std::vector LogStore::loadRecent(ChannelId channel, size_t n) { return out; } -void LogStore::setUnread(ChannelId, int) { +void LogStore::setUnread(ChannelId, int) +{ // Unused in this store; ChatModel tracks unread. } -int LogStore::getUnread(ChannelId) const { +int LogStore::getUnread(ChannelId) const +{ return 0; } -void LogStore::clearChannel(ChannelId channel) { +void LogStore::clearChannel(ChannelId channel) +{ // Clear index slots for channel; keep log intact to avoid erase. ChannelIndex& cx = idx(channel); cx.head = {}; persistHead(channel); // Zero slots file content File idx_file = fs_->open(indexPath(channel), FILE_WRITE); - if (idx_file) { + if (idx_file) + { IndexSlot zero{}; idx_file.seek(sizeof(IndexHead) * kHeadCopies, SeekSet); - for (size_t i = 0; i < kSlotsPerChannel; ++i) { + for (size_t i = 0; i < kSlotsPerChannel; ++i) + { idx_file.write(reinterpret_cast(&zero), sizeof(IndexSlot)); } idx_file.close(); } } -bool LogStore::loadIndex(ChannelId ch) { +bool LogStore::loadIndex(ChannelId ch) +{ if (!fs_) return false; const char* path = indexPath(ch); File f = fs_->open(path, FILE_READ); - if (!f) { + if (!f) + { // Create empty index file File nf = fs_->open(path, FILE_WRITE); - if (nf) { + if (nf) + { ChannelIndex empty{}; nf.write(reinterpret_cast(&empty), sizeof(empty)); nf.close(); @@ -168,15 +191,19 @@ bool LogStore::loadIndex(ChannelId ch) { f.close(); // Validate A/B head - auto head_crc_ok = [](const IndexHead& h) { + auto head_crc_ok = [](const IndexHead& h) + { uint32_t crc_calc = h.seq ^ h.next ^ h.count ^ h.last_offset; return crc_calc == h.crc; }; const IndexHead* heads = reinterpret_cast(&tmp); IndexHead chosen = heads[0]; - if (head_crc_ok(heads[1]) && heads[1].seq >= chosen.seq) { + if (head_crc_ok(heads[1]) && heads[1].seq >= chosen.seq) + { chosen = heads[1]; - } else if (!head_crc_ok(chosen) && head_crc_ok(heads[1])) { + } + else if (!head_crc_ok(chosen) && head_crc_ok(heads[1])) + { chosen = heads[1]; } indexes_[static_cast(ch)].head = chosen; @@ -185,7 +212,8 @@ bool LogStore::loadIndex(ChannelId ch) { return true; } -void LogStore::persistHead(ChannelId ch) { +void LogStore::persistHead(ChannelId ch) +{ if (!fs_) return; const char* path = indexPath(ch); File f = fs_->open(path, FILE_WRITE); @@ -199,13 +227,15 @@ void LogStore::persistHead(ChannelId ch) { f.close(); } -void LogStore::persistSlot(ChannelId ch, uint16_t idx_slot) { +void LogStore::persistSlot(ChannelId ch, uint16_t idx_slot) +{ if (!fs_) return; const char* path = indexPath(ch); File f = fs_->open(path, FILE_READ); if (!f) return; File f2 = fs_->open(path, FILE_WRITE); - if (!f2) { + if (!f2) + { f.close(); return; } @@ -218,18 +248,23 @@ void LogStore::persistSlot(ChannelId ch, uint16_t idx_slot) { f2.close(); } -bool LogStore::ensureDir() { - if (!fs_->exists(kDir)) { +bool LogStore::ensureDir() +{ + if (!fs_->exists(kDir)) + { return fs_->mkdir(kDir); } return true; } -uint32_t LogStore::crc32(const uint8_t* data, size_t len) const { +uint32_t LogStore::crc32(const uint8_t* data, size_t len) const +{ uint32_t crc = 0xFFFFFFFF; - for (size_t i = 0; i < len; ++i) { + for (size_t i = 0; i < len; ++i) + { crc ^= data[i]; - for (int j = 0; j < 8; ++j) { + for (int j = 0; j < 8; ++j) + { if (crc & 1) crc = (crc >> 1) ^ 0xEDB88320; else @@ -239,11 +274,14 @@ uint32_t LogStore::crc32(const uint8_t* data, size_t len) const { return ~crc; } -uint16_t LogStore::crc16(const uint8_t* data, size_t len) const { +uint16_t LogStore::crc16(const uint8_t* data, size_t len) const +{ uint16_t crc = 0xFFFF; - for (size_t i = 0; i < len; ++i) { + for (size_t i = 0; i < len; ++i) + { crc ^= data[i]; - for (int j = 0; j < 8; ++j) { + for (int j = 0; j < 8; ++j) + { if (crc & 1) crc = (crc >> 1) ^ 0xA001; else @@ -253,11 +291,13 @@ uint16_t LogStore::crc16(const uint8_t* data, size_t len) const { return crc; } -LogStore::ChannelIndex& LogStore::idx(ChannelId ch) { +LogStore::ChannelIndex& LogStore::idx(ChannelId ch) +{ return indexes_[static_cast(ch)]; } -const LogStore::ChannelIndex& LogStore::idx(ChannelId ch) const { +const LogStore::ChannelIndex& LogStore::idx(ChannelId ch) const +{ return indexes_[static_cast(ch)]; } diff --git a/src/chat/infra/store/log_store.h b/src/chat/infra/store/log_store.h index d30b706e..95e8deb3 100644 --- a/src/chat/infra/store/log_store.h +++ b/src/chat/infra/store/log_store.h @@ -8,10 +8,11 @@ #include "../../ports/i_chat_store.h" #include #include -#include #include +#include -namespace chat { +namespace chat +{ /** * @brief SD-backed append-only log with per-channel ring index. @@ -20,8 +21,9 @@ namespace chat { * - Log file: /chat/chat.log (append-only records) * - Index per channel: /chat/idx_chX.bin (head A/B + 1000 slots) */ -class LogStore : public IChatStore { -public: +class LogStore : public IChatStore +{ + public: static constexpr size_t kSlotsPerChannel = 1000; static constexpr const char* kDir = "/chat"; static constexpr const char* kLogFile = "/chat/chat.log"; @@ -42,10 +44,11 @@ public: int getUnread(ChannelId channel) const override; void clearChannel(ChannelId channel) override; -private: + private: fs::FS* fs_; - struct RecordHeader { + struct RecordHeader + { uint16_t magic; uint8_t ver; uint8_t flags; @@ -55,7 +58,8 @@ private: uint16_t payload_len; } __attribute__((packed)); - struct IndexHead { + struct IndexHead + { uint32_t seq; uint16_t next; uint16_t count; @@ -63,7 +67,8 @@ private: uint32_t crc; }; - struct IndexSlot { + struct IndexSlot + { uint32_t offset; uint16_t len; uint32_t ts; @@ -73,7 +78,8 @@ private: uint32_t peer; }; - struct ChannelIndex { + struct ChannelIndex + { IndexHead head; std::array slots; }; diff --git a/src/chat/infra/store/ram_store.cpp b/src/chat/infra/store/ram_store.cpp index 2b0feeb0..b2f34160 100644 --- a/src/chat/infra/store/ram_store.cpp +++ b/src/chat/infra/store/ram_store.cpp @@ -5,58 +5,70 @@ #include "ram_store.h" -namespace chat { +namespace chat +{ -RamStore::RamStore() { +RamStore::RamStore() +{ // Initialize channels (use emplace to avoid temporary on stack) channels_.emplace(ChannelId::PRIMARY, ChannelStorage()); channels_.emplace(ChannelId::SECONDARY, ChannelStorage()); } -RamStore::~RamStore() { +RamStore::~RamStore() +{ } -void RamStore::append(const ChatMessage& msg) { +void RamStore::append(const ChatMessage& msg) +{ ChannelStorage& storage = getChannelStorage(msg.channel); storage.messages.append(msg); } -std::vector RamStore::loadRecent(ChannelId channel, size_t n) { +std::vector RamStore::loadRecent(ChannelId channel, size_t n) +{ const ChannelStorage& storage = getChannelStorage(channel); std::vector result; - + size_t count = storage.messages.count(); size_t start = (count > n) ? (count - n) : 0; - - for (size_t i = start; i < count; i++) { + + for (size_t i = start; i < count; i++) + { const ChatMessage* msg = storage.messages.get(i); - if (msg) { + if (msg) + { result.push_back(*msg); } } - + return result; } -void RamStore::setUnread(ChannelId channel, int unread) { +void RamStore::setUnread(ChannelId channel, int unread) +{ ChannelStorage& storage = getChannelStorage(channel); storage.unread_count = unread; } -int RamStore::getUnread(ChannelId channel) const { +int RamStore::getUnread(ChannelId channel) const +{ const ChannelStorage& storage = getChannelStorage(channel); return storage.unread_count; } -void RamStore::clearChannel(ChannelId channel) { +void RamStore::clearChannel(ChannelId channel) +{ ChannelStorage& storage = getChannelStorage(channel); storage.messages.clear(); storage.unread_count = 0; } -RamStore::ChannelStorage& RamStore::getChannelStorage(ChannelId channel) { +RamStore::ChannelStorage& RamStore::getChannelStorage(ChannelId channel) +{ auto it = channels_.find(channel); - if (it == channels_.end()) { + if (it == channels_.end()) + { // Use emplace to avoid temporary on stack auto result = channels_.emplace(channel, ChannelStorage()); return result.first->second; @@ -64,9 +76,11 @@ RamStore::ChannelStorage& RamStore::getChannelStorage(ChannelId channel) { return it->second; } -const RamStore::ChannelStorage& RamStore::getChannelStorage(ChannelId channel) const { +const RamStore::ChannelStorage& RamStore::getChannelStorage(ChannelId channel) const +{ auto it = channels_.find(channel); - if (it == channels_.end()) { + if (it == channels_.end()) + { static ChannelStorage empty; return empty; } diff --git a/src/chat/infra/store/ram_store.h b/src/chat/infra/store/ram_store.h index c4dbbd36..9e2ae536 100644 --- a/src/chat/infra/store/ram_store.h +++ b/src/chat/infra/store/ram_store.h @@ -5,40 +5,43 @@ #pragma once -#include "../../ports/i_chat_store.h" -#include "../../domain/chat_types.h" #include "../../../sys/ringbuf.h" +#include "../../domain/chat_types.h" +#include "../../ports/i_chat_store.h" #include -namespace chat { +namespace chat +{ /** * @brief RAM-based chat storage * Uses ring buffers for message storage */ -class RamStore : public IChatStore { -public: - static constexpr size_t MAX_MESSAGES_PER_CHANNEL = 20; // Reduced to prevent stack overflow - +class RamStore : public IChatStore +{ + public: + static constexpr size_t MAX_MESSAGES_PER_CHANNEL = 20; // Reduced to prevent stack overflow + RamStore(); virtual ~RamStore(); - + void append(const ChatMessage& msg) override; std::vector loadRecent(ChannelId channel, size_t n) override; void setUnread(ChannelId channel, int unread) override; int getUnread(ChannelId channel) const override; void clearChannel(ChannelId channel) override; -private: - struct ChannelStorage { + private: + struct ChannelStorage + { sys::RingBuffer messages; int unread_count; - + ChannelStorage() : unread_count(0) {} }; - + std::map channels_; - + ChannelStorage& getChannelStorage(ChannelId channel); const ChannelStorage& getChannelStorage(ChannelId channel) const; }; diff --git a/src/chat/ports/i_chat_store.h b/src/chat/ports/i_chat_store.h index 01931eca..a1e1f09c 100644 --- a/src/chat/ports/i_chat_store.h +++ b/src/chat/ports/i_chat_store.h @@ -8,22 +8,24 @@ #include "../domain/chat_types.h" #include -namespace chat { +namespace chat +{ /** * @brief Chat storage interface * Abstracts storage implementation (RAM, Flash, etc.) */ -class IChatStore { -public: +class IChatStore +{ + public: virtual ~IChatStore() = default; - + /** * @brief Append message to storage * @param msg Message to append */ virtual void append(const ChatMessage& msg) = 0; - + /** * @brief Load recent messages for channel * @param channel Channel ID @@ -31,21 +33,21 @@ public: * @return Vector of messages (oldest first) */ virtual std::vector loadRecent(ChannelId channel, size_t n) = 0; - + /** * @brief Set unread count for channel * @param channel Channel ID * @param unread Unread count */ virtual void setUnread(ChannelId channel, int unread) = 0; - + /** * @brief Get unread count for channel * @param channel Channel ID * @return Unread count */ virtual int getUnread(ChannelId channel) const = 0; - + /** * @brief Clear all messages for channel * @param channel Channel ID diff --git a/src/chat/ports/i_contact_store.h b/src/chat/ports/i_contact_store.h index d7035698..8c0dedc6 100644 --- a/src/chat/ports/i_contact_store.h +++ b/src/chat/ports/i_contact_store.h @@ -9,29 +9,32 @@ #include #include -namespace chat { -namespace contacts { +namespace chat +{ +namespace contacts +{ /** * @brief Contact store interface * Abstracts contact nickname storage implementation */ -class IContactStore { -public: +class IContactStore +{ + public: virtual ~IContactStore() = default; - + /** * @brief Initialize store (load from persistent storage) */ virtual void begin() = 0; - + /** * @brief Get nickname for a node_id * @param node_id Node ID * @return Nickname if found, empty string otherwise */ virtual std::string getNickname(uint32_t node_id) const = 0; - + /** * @brief Set nickname for a node_id * @param node_id Node ID @@ -39,27 +42,27 @@ public: * @return true if successful, false if duplicate name or storage full */ virtual bool setNickname(uint32_t node_id, const char* nickname) = 0; - + /** * @brief Remove nickname for a node_id * @param node_id Node ID * @return true if removed, false if not found */ virtual bool removeNickname(uint32_t node_id) = 0; - + /** * @brief Check if a nickname already exists * @param nickname Nickname to check * @return true if duplicate */ virtual bool hasNickname(const char* nickname) const = 0; - + /** * @brief Get all contact node IDs * @return Vector of node IDs */ virtual std::vector getAllContactIds() const = 0; - + /** * @brief Get number of contacts */ diff --git a/src/chat/ports/i_mesh_adapter.h b/src/chat/ports/i_mesh_adapter.h index 2d35e4e1..efb95ba4 100644 --- a/src/chat/ports/i_mesh_adapter.h +++ b/src/chat/ports/i_mesh_adapter.h @@ -7,16 +7,18 @@ #include "../domain/chat_types.h" -namespace chat { +namespace chat +{ /** * @brief Mesh adapter interface * Abstracts mesh protocol implementation (Meshtastic, custom, etc.) */ -class IMeshAdapter { -public: +class IMeshAdapter +{ + public: virtual ~IMeshAdapter() = default; - + /** * @brief Send text message * @param channel Channel ID @@ -24,26 +26,51 @@ public: * @param out_msg_id Output message ID (if successful) * @return true if queued successfully */ - virtual bool sendText(ChannelId channel, const std::string& text, - MessageId* out_msg_id, NodeId peer = 0) = 0; - + virtual bool sendText(ChannelId channel, const std::string& text, + MessageId* out_msg_id, NodeId peer = 0) = 0; + /** * @brief Poll for incoming text messages * @param out Output message (if available) * @return true if message available */ virtual bool pollIncomingText(MeshIncomingText* out) = 0; - + /** * @brief Apply mesh configuration * @param config Configuration to apply */ virtual void applyConfig(const MeshConfig& config) = 0; - + /** * @brief Check if adapter is ready */ virtual bool isReady() const = 0; + + /** + * @brief Poll for incoming raw packet data + * @param out_data Output buffer for raw packet data + * @param out_len Output packet length + * @param max_len Maximum buffer size + * @return true if raw packet data is available + */ + virtual bool pollIncomingRawPacket(uint8_t* out_data, size_t& out_len, size_t max_len) = 0; + + /** + * @brief Handle raw packet data from the radio task + * @param data Raw packet data + * @param size Packet size + */ + virtual void handleRawPacket(const uint8_t* data, size_t size) + { + (void)data; + (void)size; + } + + /** + * @brief Process any pending send queue work + */ + virtual void processSendQueue() {} }; } // namespace chat diff --git a/src/chat/ports/i_node_store.h b/src/chat/ports/i_node_store.h index 899d38cd..f7b6c2bf 100644 --- a/src/chat/ports/i_node_store.h +++ b/src/chat/ports/i_node_store.h @@ -8,33 +8,38 @@ #include #include -namespace chat { -namespace contacts { +namespace chat +{ +namespace contacts +{ /** * @brief Node entry structure */ -struct NodeEntry { +struct NodeEntry +{ uint32_t node_id; char short_name[10]; char long_name[32]; - uint32_t last_seen; // Unix timestamp (seconds) - float snr; // Signal-to-Noise Ratio + uint32_t last_seen; // Unix timestamp (seconds) + float snr; // Signal-to-Noise Ratio + uint8_t protocol; // NodeProtocolType }; /** * @brief Node store interface * Abstracts node information storage implementation */ -class INodeStore { -public: +class INodeStore +{ + public: virtual ~INodeStore() = default; - + /** * @brief Initialize store (load from persistent storage) */ virtual void begin() = 0; - + /** * @brief Update or insert a node entry * @param node_id Node ID @@ -44,13 +49,26 @@ public: * @param snr Signal-to-Noise Ratio */ virtual void upsert(uint32_t node_id, const char* short_name, const char* long_name, - uint32_t now_secs, float snr = 0.0f) = 0; - + uint32_t now_secs, float snr = 0.0f, uint8_t protocol = 0) = 0; + + /** + * @brief Update node protocol (without changing names) + * @param node_id Node ID + * @param protocol Protocol type + * @param now_secs Current timestamp (seconds) + */ + virtual void updateProtocol(uint32_t node_id, uint8_t protocol, uint32_t now_secs) = 0; + /** * @brief Get all entries (for iteration) * @return Reference to entries vector */ virtual const std::vector& getEntries() const = 0; + + /** + * @brief Clear all stored node entries + */ + virtual void clear() = 0; }; } // namespace contacts diff --git a/src/chat/proto_util.h b/src/chat/proto_util.h index 4f98393c..7d9bfa4a 100644 --- a/src/chat/proto_util.h +++ b/src/chat/proto_util.h @@ -7,12 +7,16 @@ inline void pb_put_varint(std::string& out, uint64_t v) { - while (true) { + while (true) + { uint8_t b = v & 0x7F; v >>= 7; - if (v) { + if (v) + { out.push_back(b | 0x80); - } else { + } + else + { out.push_back(b); break; } @@ -31,10 +35,12 @@ inline bool pb_read_varint(const uint8_t* buf, size_t len, size_t& off, uint64_t { uint64_t v = 0; int shift = 0; - while (off < len && shift < 64) { + while (off < len && shift < 64) + { uint8_t b = buf[off++]; v |= (uint64_t)(b & 0x7F) << shift; - if ((b & 0x80) == 0) { + if ((b & 0x80) == 0) + { out = v; return true; } diff --git a/src/chat/usecase/chat_service.cpp b/src/chat/usecase/chat_service.cpp index c3758a82..daf7afc4 100644 --- a/src/chat/usecase/chat_service.cpp +++ b/src/chat/usecase/chat_service.cpp @@ -6,18 +6,22 @@ #include "chat_service.h" #include "../../sys/event_bus.h" -namespace chat { +namespace chat +{ ChatService::ChatService(ChatModel& model, IMeshAdapter& adapter, IChatStore& store) - : model_(model), adapter_(adapter), store_(store), - current_channel_(ChannelId::PRIMARY) { + : model_(model), adapter_(adapter), store_(store), + current_channel_(ChannelId::PRIMARY) +{ } -MessageId ChatService::sendText(ChannelId channel, const std::string& text, NodeId peer) { - if (text.empty()) { +MessageId ChatService::sendText(ChannelId channel, const std::string& text, NodeId peer) +{ + if (text.empty()) + { return 0; } - + ChatMessage msg; msg.channel = channel; msg.from = 0; // Local message @@ -25,51 +29,61 @@ MessageId ChatService::sendText(ChannelId channel, const std::string& text, Node msg.timestamp = millis() / 1000; // Convert to seconds msg.text = text; msg.status = MessageStatus::Queued; - + // Queue in model model_.onSendQueued(msg); - + // Try to send via adapter MessageId msg_id = 0; - if (adapter_.sendText(channel, text, &msg_id, peer)) { + if (adapter_.sendText(channel, text, &msg_id, peer)) + { // Update message ID if adapter provided one - if (msg_id != 0) { + if (msg_id != 0) + { // Find and update message (simplified - in real impl might need better tracking) const ChatMessage* found = model_.getMessage(msg_id); - if (found) { + if (found) + { // Message ID already set } } - } else { + } + else + { // Send failed, mark as failed model_.onSendResult(msg.msg_id, false); } - + // Store message store_.append(msg); - + return msg.msg_id; } -void ChatService::switchChannel(ChannelId channel) { +void ChatService::switchChannel(ChannelId channel) +{ current_channel_ = channel; // Could emit event here } -void ChatService::markChannelRead(ChannelId channel) { +void ChatService::markChannelRead(ChannelId channel) +{ model_.markRead(channel); store_.setUnread(channel, 0); } -bool ChatService::resendFailed(MessageId msg_id) { +bool ChatService::resendFailed(MessageId msg_id) +{ const ChatMessage* msg = model_.getMessage(msg_id); - if (!msg || msg->status != MessageStatus::Failed) { + if (!msg || msg->status != MessageStatus::Failed) + { return false; } - + // Resend via adapter MessageId new_msg_id = 0; - if (adapter_.sendText(msg->channel, msg->text, &new_msg_id, msg->peer)) { + if (adapter_.sendText(msg->channel, msg->text, &new_msg_id, msg->peer)) + { // Create new queued message ChatMessage resend_msg = *msg; resend_msg.msg_id = (new_msg_id != 0) ? new_msg_id : msg_id; @@ -77,34 +91,50 @@ bool ChatService::resendFailed(MessageId msg_id) { model_.onSendQueued(resend_msg); return true; } - + return false; } -int ChatService::getUnreadCount(ChannelId channel) const { +int ChatService::getUnreadCount(ChannelId channel) const +{ return model_.getUnread(channel); } -std::vector ChatService::getRecentMessages(ChannelId channel, size_t limit) const { +std::vector ChatService::getRecentMessages(ChannelId channel, size_t limit) const +{ return model_.getRecent(channel, limit); } -std::vector ChatService::getRecentMessages(const ConversationId& conv, size_t limit) const { +std::vector ChatService::getRecentMessages(const ConversationId& conv, size_t limit) const +{ return model_.getRecent(conv, limit); } -std::vector ChatService::getConversations() const { +std::vector ChatService::getConversations() const +{ return model_.getConversations(); } -void ChatService::markConversationRead(const ConversationId& conv) { +void ChatService::clearAllMessages() +{ + model_.clearAll(); + store_.clearChannel(ChannelId::PRIMARY); + store_.clearChannel(ChannelId::SECONDARY); + store_.setUnread(ChannelId::PRIMARY, 0); + store_.setUnread(ChannelId::SECONDARY, 0); +} + +void ChatService::markConversationRead(const ConversationId& conv) +{ model_.markRead(conv); store_.setUnread(conv.channel, 0); } -void ChatService::processIncoming() { +void ChatService::processIncoming() +{ MeshIncomingText incoming; - while (adapter_.pollIncomingText(&incoming)) { + while (adapter_.pollIncomingText(&incoming)) + { // Convert to ChatMessage ChatMessage msg; msg.channel = incoming.channel; @@ -114,10 +144,10 @@ void ChatService::processIncoming() { msg.timestamp = incoming.timestamp ? incoming.timestamp : (millis() / 1000); msg.text = incoming.text; msg.status = MessageStatus::Incoming; - + // Add to model model_.onIncoming(msg); - + // Store store_.append(msg); diff --git a/src/chat/usecase/chat_service.h b/src/chat/usecase/chat_service.h index 538bdd47..ce56add4 100644 --- a/src/chat/usecase/chat_service.h +++ b/src/chat/usecase/chat_service.h @@ -7,19 +7,21 @@ #include "../domain/chat_model.h" #include "../domain/chat_types.h" -#include "../ports/i_mesh_adapter.h" #include "../ports/i_chat_store.h" +#include "../ports/i_mesh_adapter.h" -namespace chat { +namespace chat +{ /** * @brief Chat service * Use case layer: coordinates domain model, adapters, and storage */ -class ChatService { -public: +class ChatService +{ + public: ChatService(ChatModel& model, IMeshAdapter& adapter, IChatStore& store); - + /** * @brief Send text message * @param channel Channel ID @@ -27,52 +29,58 @@ public: * @return Message ID if queued successfully, 0 on failure */ MessageId sendText(ChannelId channel, const std::string& text, NodeId peer = 0); - + /** * @brief Switch to channel * @param channel Channel ID */ void switchChannel(ChannelId channel); - + /** * @brief Mark channel as read * @param channel Channel ID */ void markChannelRead(ChannelId channel); void markConversationRead(const ConversationId& conv); - + /** * @brief Resend failed message * @param msg_id Message ID * @return true if queued for resend */ bool resendFailed(MessageId msg_id); - + /** * @brief Get unread count for channel */ int getUnreadCount(ChannelId channel) const; - + /** * @brief Get recent messages for channel */ std::vector getRecentMessages(ChannelId channel, size_t limit) const; std::vector getRecentMessages(const ConversationId& conv, size_t limit) const; std::vector getConversations() const; - + + /** + * @brief Clear all stored messages and model state + */ + void clearAllMessages(); + /** * @brief Process incoming messages (call from mesh task) */ void processIncoming(); - + /** * @brief Get current channel */ - ChannelId getCurrentChannel() const { + ChannelId getCurrentChannel() const + { return current_channel_; } -private: + private: ChatModel& model_; IMeshAdapter& adapter_; IChatStore& store_; diff --git a/src/chat/usecase/contact_service.cpp b/src/chat/usecase/contact_service.cpp index 111fac81..f71c19e4 100644 --- a/src/chat/usecase/contact_service.cpp +++ b/src/chat/usecase/contact_service.cpp @@ -6,135 +6,177 @@ #include "contact_service.h" #include "../domain/contact_types.h" #include -#include #include +#include #include -namespace chat { -namespace contacts { +namespace chat +{ +namespace contacts +{ ContactService::ContactService(INodeStore& node_store, IContactStore& contact_store) - : node_store_(node_store), contact_store_(contact_store), cache_timestamp_(0) { + : node_store_(node_store), contact_store_(contact_store), cache_timestamp_(0) +{ } -void ContactService::begin() { +void ContactService::begin() +{ node_store_.begin(); contact_store_.begin(); invalidateCache(); } void ContactService::updateNodeInfo(uint32_t node_id, const char* short_name, const char* long_name, - float snr, uint32_t now_secs) { - node_store_.upsert(node_id, short_name, long_name, now_secs, snr); + float snr, uint32_t now_secs, uint8_t protocol) +{ + node_store_.upsert(node_id, short_name, long_name, now_secs, snr, protocol); invalidateCache(); } -std::string ContactService::getContactName(uint32_t node_id) const { +void ContactService::updateNodeProtocol(uint32_t node_id, uint8_t protocol, uint32_t now_secs) +{ + node_store_.updateProtocol(node_id, protocol, now_secs); + invalidateCache(); +} + +std::string ContactService::getContactName(uint32_t node_id) const +{ std::string nickname = contact_store_.getNickname(node_id); - if (!nickname.empty()) { + if (!nickname.empty()) + { return nickname; } - + // Fallback to short_name from NodeStore buildCache(); - for (const auto& node : cached_nodes_) { - if (node.node_id == node_id) { + for (const auto& node : cached_nodes_) + { + if (node.node_id == node_id) + { return std::string(node.short_name); } } - + // Not found in cache, try NodeStore directly const auto& entries = node_store_.getEntries(); - for (const auto& entry : entries) { - if (entry.node_id == node_id) { + for (const auto& entry : entries) + { + if (entry.node_id == node_id) + { return std::string(entry.short_name); } } - + // Not found, return empty return std::string(); } -std::vector ContactService::getContacts() const { +std::vector ContactService::getContacts() const +{ buildCache(); std::vector contacts; - for (const auto& node : cached_nodes_) { - if (node.is_contact) { + for (const auto& node : cached_nodes_) + { + if (node.is_contact) + { contacts.push_back(node); } } return contacts; } -std::vector ContactService::getNearby() const { +std::vector ContactService::getNearby() const +{ buildCache(); std::vector nearby; - for (const auto& node : cached_nodes_) { - if (!node.is_contact && isNodeVisible(node.last_seen)) { + for (const auto& node : cached_nodes_) + { + if (!node.is_contact && isNodeVisible(node.last_seen)) + { nearby.push_back(node); } } return nearby; } -bool ContactService::addContact(uint32_t node_id, const char* nickname) { - if (contact_store_.setNickname(node_id, nickname)) { +bool ContactService::addContact(uint32_t node_id, const char* nickname) +{ + if (contact_store_.setNickname(node_id, nickname)) + { invalidateCache(); return true; } return false; } -bool ContactService::editContact(uint32_t node_id, const char* nickname) { - if (contact_store_.setNickname(node_id, nickname)) { +bool ContactService::editContact(uint32_t node_id, const char* nickname) +{ + if (contact_store_.setNickname(node_id, nickname)) + { invalidateCache(); return true; } return false; } -bool ContactService::removeContact(uint32_t node_id) { - if (contact_store_.removeNickname(node_id)) { +bool ContactService::removeContact(uint32_t node_id) +{ + if (contact_store_.removeNickname(node_id)) + { invalidateCache(); return true; } return false; } -const NodeInfo* ContactService::getNodeInfo(uint32_t node_id) const { +const NodeInfo* ContactService::getNodeInfo(uint32_t node_id) const +{ buildCache(); - for (const auto& node : cached_nodes_) { - if (node.node_id == node_id) { + for (const auto& node : cached_nodes_) + { + if (node.node_id == node_id) + { return &node; } } return nullptr; } -void ContactService::invalidateCache() const { +void ContactService::clearCache() +{ + invalidateCache(); +} + +void ContactService::invalidateCache() const +{ cache_timestamp_ = 0; cached_nodes_.clear(); } -void ContactService::buildCache() const { +void ContactService::buildCache() const +{ uint32_t now_ms = millis(); - if (cache_timestamp_ != 0 && (now_ms - cache_timestamp_) < kCacheTimeoutMs) { - return; // Cache still valid + if (cache_timestamp_ != 0 && (now_ms - cache_timestamp_) < kCacheTimeoutMs) + { + return; // Cache still valid } - + cached_nodes_.clear(); - + // Get all contact IDs std::vector contact_ids = contact_store_.getAllContactIds(); - + // Build node info from NodeStore entries const auto& node_entries = node_store_.getEntries(); - for (const auto& entry : node_entries) { + for (const auto& entry : node_entries) + { // Check if node is visible (within 6 days) - if (!isNodeVisible(entry.last_seen)) { - continue; // Skip nodes older than 6 days + if (!isNodeVisible(entry.last_seen)) + { + continue; // Skip nodes older than 6 days } - + NodeInfo info{}; info.node_id = entry.node_id; strncpy(info.short_name, entry.short_name, sizeof(info.short_name) - 1); @@ -143,72 +185,84 @@ void ContactService::buildCache() const { info.long_name[sizeof(info.long_name) - 1] = '\0'; info.last_seen = entry.last_seen; info.snr = entry.snr; - + info.protocol = static_cast(entry.protocol); + // Check if this node is a contact info.is_contact = std::find(contact_ids.begin(), contact_ids.end(), entry.node_id) != contact_ids.end(); - + // Set display name - if (info.is_contact) { + if (info.is_contact) + { info.display_name = contact_store_.getNickname(entry.node_id); - } else { + } + else + { info.display_name = std::string(info.short_name); } - + cached_nodes_.push_back(info); } - + cache_timestamp_ = now_ms; } -bool ContactService::isNodeVisible(uint32_t last_seen) const { +bool ContactService::isNodeVisible(uint32_t last_seen) const +{ uint32_t now_secs = time(nullptr); - if (now_secs < last_seen) { - return false; // Invalid timestamp + if (now_secs < last_seen) + { + return false; // Invalid timestamp } - + uint32_t age_secs = now_secs - last_seen; const uint32_t kSixDaysSecs = 6 * 24 * 60 * 60; - + return age_secs <= kSixDaysSecs; } -std::string ContactService::formatTimeStatus(uint32_t last_seen) const { +std::string ContactService::formatTimeStatus(uint32_t last_seen) const +{ uint32_t now_secs = time(nullptr); - if (now_secs < last_seen) { + if (now_secs < last_seen) + { return "Offline"; } - + uint32_t age_secs = now_secs - last_seen; - + // Online: ≤ 2 minutes - if (age_secs <= 120) { + if (age_secs <= 120) + { return "Online"; } - + // Minutes: 3-59 minutes - if (age_secs < 3600) { + if (age_secs < 3600) + { uint32_t minutes = age_secs / 60; char buf[16]; snprintf(buf, sizeof(buf), "Seen %um", minutes); return std::string(buf); } - + // Hours: 1-23 hours - if (age_secs < 86400) { + if (age_secs < 86400) + { uint32_t hours = age_secs / 3600; char buf[16]; snprintf(buf, sizeof(buf), "Seen %uh", hours); return std::string(buf); } - + // Days: 1-6 days - if (age_secs < 6 * 86400) { + if (age_secs < 6 * 86400) + { uint32_t days = age_secs / 86400; char buf[16]; snprintf(buf, sizeof(buf), "Seen %ud", days); return std::string(buf); } - + // > 6 days: should be filtered out return "Offline"; } diff --git a/src/chat/usecase/contact_service.h b/src/chat/usecase/contact_service.h index 76aeb150..1daecbaa 100644 --- a/src/chat/usecase/contact_service.h +++ b/src/chat/usecase/contact_service.h @@ -10,20 +10,23 @@ #pragma once #include "../domain/contact_types.h" -#include "../ports/i_node_store.h" #include "../ports/i_contact_store.h" +#include "../ports/i_node_store.h" #include #include -namespace chat { -namespace contacts { +namespace chat +{ +namespace contacts +{ /** * @brief Contact service * Use case layer: coordinates domain model and storage adapters */ -class ContactService { -public: +class ContactService +{ + public: /** * @brief Constructor with dependency injection * @param node_store Node store implementation @@ -45,8 +48,13 @@ public: * @param snr Signal-to-Noise Ratio * @param now_secs Current timestamp (seconds) */ - void updateNodeInfo(uint32_t node_id, const char* short_name, const char* long_name, - float snr, uint32_t now_secs); + void updateNodeInfo(uint32_t node_id, const char* short_name, const char* long_name, + float snr, uint32_t now_secs, uint8_t protocol = 0); + + /** + * @brief Update node protocol type (without changing names) + */ + void updateNodeProtocol(uint32_t node_id, uint8_t protocol, uint32_t now_secs); /** * @brief Get display name for a node (nickname if contact, short_name otherwise) @@ -95,12 +103,17 @@ public: */ const NodeInfo* getNodeInfo(uint32_t node_id) const; -private: + /** + * @brief Clear cached node info + */ + void clearCache(); + + private: INodeStore& node_store_; IContactStore& contact_store_; - mutable std::vector cached_nodes_; // Cache for getContacts/getNearby + mutable std::vector cached_nodes_; // Cache for getContacts/getNearby mutable uint32_t cache_timestamp_; - static constexpr uint32_t kCacheTimeoutMs = 1000; // 1 second cache + static constexpr uint32_t kCacheTimeoutMs = 1000; // 1 second cache void invalidateCache() const; void buildCache() const; diff --git a/src/display/BrightnessController.h b/src/display/BrightnessController.h index d773bf66..8827b7e7 100644 --- a/src/display/BrightnessController.h +++ b/src/display/BrightnessController.h @@ -7,17 +7,17 @@ * */ #pragma once -#include #include "freertos/FreeRTOS.h" #include "freertos/timers.h" +#include -template +template class BrightnessController { -protected: + protected: TimerHandle_t timerHandler = nullptr; -public: + public: /** * @brief Decrease the display brightness to the target level. * @@ -34,20 +34,26 @@ public: if (target_level < MIN_BRIGHTNESS) target_level = MIN_BRIGHTNESS; if (target_level > MAX_BRIGHTNESS) target_level = MAX_BRIGHTNESS; - if (!async) { - uint8_t brightness = static_cast(this)->getBrightness(); + if (!async) + { + uint8_t brightness = static_cast(this)->getBrightness(); if (target_level >= brightness) return; - for (int i = brightness; i > target_level; i--) { - static_cast(this)->setBrightness(i); + for (int i = brightness; i > target_level; i--) + { + static_cast(this)->setBrightness(i); delay(delay_ms); } - static_cast(this)->setBrightness(target_level); - } else { + static_cast(this)->setBrightness(target_level); + } + else + { static uint8_t pvTimerParams; pvTimerParams = target_level; - if (!timerHandler) { - timerHandler = xTimerCreate("bri", pdMS_TO_TICKS(delay_ms), pdTRUE, &pvTimerParams, [](TimerHandle_t xTimer) { + if (!timerHandler) + { + timerHandler = xTimerCreate("bri", pdMS_TO_TICKS(delay_ms), pdTRUE, &pvTimerParams, [](TimerHandle_t xTimer) + { uint8_t *target_level_ptr = (uint8_t *)pvTimerGetTimerID(xTimer); T* inst = T::getInstance(); uint8_t brightness = inst->getBrightness(); @@ -62,23 +68,23 @@ public: xTimerStop(controller->timerHandler, portMAX_DELAY); xTimerDelete(controller->timerHandler, portMAX_DELAY); controller->timerHandler = NULL; - } - }); + } }); } - uint8_t current_brightness = static_cast(this)->getBrightness(); - if (current_brightness <= target_level) { + uint8_t current_brightness = static_cast(this)->getBrightness(); + if (current_brightness <= target_level) + { return; } - if (xTimerIsTimerActive(timerHandler) == pdTRUE) { + if (xTimerIsTimerActive(timerHandler) == pdTRUE) + { return; } xTimerStart(timerHandler, portMAX_DELAY); } } - /** * @brief Increase the display brightness to the target level. * @@ -95,19 +101,25 @@ public: if (target_level < MIN_BRIGHTNESS) target_level = MIN_BRIGHTNESS; if (target_level > MAX_BRIGHTNESS) target_level = MAX_BRIGHTNESS; - if (!async) { - uint8_t brightness = static_cast(this)->getBrightness(); + if (!async) + { + uint8_t brightness = static_cast(this)->getBrightness(); if (target_level <= brightness) return; - for (int i = brightness + 1; i <= target_level; i++) { - static_cast(this)->setBrightness(i); + for (int i = brightness + 1; i <= target_level; i++) + { + static_cast(this)->setBrightness(i); delay(delay_ms); } - } else { + } + else + { static uint8_t pvTimerParams; pvTimerParams = target_level; - if (!timerHandler) { - timerHandler = xTimerCreate("bri", pdMS_TO_TICKS(delay_ms), pdTRUE, &pvTimerParams, [](TimerHandle_t xTimer) { + if (!timerHandler) + { + timerHandler = xTimerCreate("bri", pdMS_TO_TICKS(delay_ms), pdTRUE, &pvTimerParams, [](TimerHandle_t xTimer) + { uint8_t *target_level_ptr = (uint8_t *)pvTimerGetTimerID(xTimer); T* inst = T::getInstance(); uint8_t brightness = inst->getBrightness(); @@ -120,16 +132,17 @@ public: xTimerStop(controller->timerHandler, portMAX_DELAY); xTimerDelete(controller->timerHandler, portMAX_DELAY); controller->timerHandler = NULL; - } - }); + } }); } - uint8_t current_brightness = static_cast(this)->getBrightness(); - if (current_brightness >= target_level) { + uint8_t current_brightness = static_cast(this)->getBrightness(); + if (current_brightness >= target_level) + { return; } - if (xTimerIsTimerActive(timerHandler) == pdTRUE) { + if (xTimerIsTimerActive(timerHandler) == pdTRUE) + { return; } xTimerStart(timerHandler, portMAX_DELAY); diff --git a/src/display/DisplayConfig.cpp b/src/display/DisplayConfig.cpp index faa4560b..052c0c93 100644 --- a/src/display/DisplayConfig.cpp +++ b/src/display/DisplayConfig.cpp @@ -1,6 +1,7 @@ #include "display/DisplayConfig.h" -namespace display { +namespace display +{ Config get_config() { diff --git a/src/display/DisplayConfig.h b/src/display/DisplayConfig.h index feeecea8..88a6a21a 100644 --- a/src/display/DisplayConfig.h +++ b/src/display/DisplayConfig.h @@ -2,20 +2,24 @@ #include -namespace display { +namespace display +{ -enum class Driver { +enum class Driver +{ Unknown = 0, ST7796, ST7789V2, }; -struct ScreenSize { +struct ScreenSize +{ int width; int height; }; -struct Config { +struct Config +{ Driver driver; ScreenSize screen; }; diff --git a/src/display/DisplayInterface.cpp b/src/display/DisplayInterface.cpp index c7446129..96cd7991 100644 --- a/src/display/DisplayInterface.cpp +++ b/src/display/DisplayInterface.cpp @@ -2,12 +2,12 @@ #include #include -#define DISP_CMD_MADCTL (0x36) -#define DISP_CMD_CASET (0x2A) -#define DISP_CMD_RASET (0x2B) -#define DISP_CMD_RAMWR (0x2C) -#define DISP_CMD_SLPIN (0x10) -#define DISP_CMD_SLPOUT (0x11) +#define DISP_CMD_MADCTL (0x36) +#define DISP_CMD_CASET (0x2A) +#define DISP_CMD_RASET (0x2B) +#define DISP_CMD_RAMWR (0x2C) +#define DISP_CMD_SLPIN (0x10) +#define DISP_CMD_SLPOUT (0x11) bool LilyGoDispArduinoSPI::lock(TickType_t xTicksToWait) { @@ -32,12 +32,13 @@ bool LilyGoDispArduinoSPI::init(int sck, int dc, int backlight, uint32_t freq_Mhz, - SPIClass &spi) + SPIClass& spi) { _lock = xSemaphoreCreateMutex(); _spi = &spi; - if (rst != -1) { + if (rst != -1) + { pinMode(rst, OUTPUT); digitalWrite(rst, LOW); delay(20); @@ -56,16 +57,19 @@ bool LilyGoDispArduinoSPI::init(int sck, digitalWrite(_dc, HIGH); _backlight = backlight; - if (_backlight != -1) { + if (_backlight != -1) + { pinMode(_backlight, OUTPUT); digitalWrite(_backlight, HIGH); } _spi->begin(sck, miso, mosi); - for (uint32_t i = 0; i < _init_list_length; i++) { - writeParams(_init_list[i].cmd, (uint8_t *)_init_list[i].data, _init_list[i].len & 0x1F); - if (_init_list[i].len & 0x80) { + for (uint32_t i = 0; i < _init_list_length; i++) + { + writeParams(_init_list[i].cmd, (uint8_t*)_init_list[i].data, _init_list[i].len & 0x1F); + if (_init_list[i].len & 0x80) + { delay(120); } } @@ -101,19 +105,19 @@ void LilyGoDispArduinoSPI::setRotation(uint8_t rotation) _offset_y = _rotation_configs[_rotation].offset_y; } -void LilyGoDispArduinoSPI::pushColors(uint16_t *data, uint32_t len) +void LilyGoDispArduinoSPI::pushColors(uint16_t* data, uint32_t len) { xSemaphoreTake(_lock, portMAX_DELAY); digitalWrite(_cs, LOW); _spi->beginTransaction(SPISettings(_spi_freq, MSBFIRST, SPI_MODE0)); digitalWrite(_dc, HIGH); - _spi->writeBytes((const uint8_t *)data, len * sizeof(uint16_t)); + _spi->writeBytes((const uint8_t*)data, len * sizeof(uint16_t)); _spi->endTransaction(); digitalWrite(_cs, HIGH); xSemaphoreGive(_lock); } -void LilyGoDispArduinoSPI::pushColors(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *color) +void LilyGoDispArduinoSPI::pushColors(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t* color) { setAddrWindow(x1, y1, x1 + x2 - 1, y1 + y2 - 1); pushColors(color, x2 * y2); @@ -140,7 +144,8 @@ void LilyGoDispArduinoSPI::setAddrWindow(uint16_t xs, uint16_t ys, uint16_t xe, {DISP_CMD_RASET, {uint8_t(ys >> 8), (uint8_t)ys, uint8_t(ye >> 8), uint8_t(ye)}, 0x04}, {DISP_CMD_RAMWR, {0x00}, 0x00}, }; - for (uint32_t i = 0; i < 3; i++) { + for (uint32_t i = 0; i < 3; i++) + { writeParams(t[i].cmd, t[i].data, t[i].len); } } @@ -170,10 +175,11 @@ void LilyGoDispArduinoSPI::writeData(uint8_t data) xSemaphoreGive(_lock); } -void LilyGoDispArduinoSPI::writeParams(uint8_t cmd, uint8_t *data, size_t length) +void LilyGoDispArduinoSPI::writeParams(uint8_t cmd, uint8_t* data, size_t length) { writeCommand(cmd); - for (size_t i = 0; i < length; i++) { + for (size_t i = 0; i < length; i++) + { writeData(data[i]); } } diff --git a/src/display/DisplayInterface.h b/src/display/DisplayInterface.h index 02e49431..ce4e0e7d 100644 --- a/src/display/DisplayInterface.h +++ b/src/display/DisplayInterface.h @@ -1,15 +1,17 @@ #pragma once -#include -#include #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" +#include +#include -enum DriverBusType { +enum DriverBusType +{ SPI_DRIVER, }; -typedef struct { +typedef struct +{ uint8_t madCmd; uint16_t width; uint16_t height; @@ -17,49 +19,57 @@ typedef struct { uint16_t offset_y; } DispRotationConfig_t; -typedef struct { +typedef struct +{ uint8_t cmd; uint8_t data[15]; uint8_t len; } CommandTable_t; -typedef enum RotaryDir { +typedef enum RotaryDir +{ ROTARY_DIR_NONE, ROTARY_DIR_UP, ROTARY_DIR_DOWN, } RotaryDir_t; -typedef enum KeyboardState { +typedef enum KeyboardState +{ KEYBOARD_RELEASED, KEYBOARD_PRESSED, } KeyboardState_t; -typedef struct RotaryMsg { +typedef struct RotaryMsg +{ RotaryDir_t dir; bool centerBtnPressed; } RotaryMsg_t; class LilyGo_Display { -public: - LilyGo_Display(DriverBusType type, bool full_refresh) : - _offset_x(0), _offset_y(0), _rotation(0), _interface(type), _full_refresh(full_refresh) {} + public: + LilyGo_Display(DriverBusType type, bool full_refresh) : _offset_x(0), _offset_y(0), _rotation(0), _interface(type), _full_refresh(full_refresh) {} virtual void setRotation(uint8_t rotation) = 0; virtual uint8_t getRotation() = 0; - virtual void pushColors(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *color) = 0; + virtual void pushColors(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t* color) = 0; virtual uint16_t width() = 0; virtual uint16_t height() = 0; - virtual RotaryMsg_t getRotary() { RotaryMsg_t msg; return msg; } - virtual uint8_t getPoint(int16_t *x, int16_t *y, uint8_t get_point) { return 0; } - virtual int getKeyChar(char *c) { return -1; } + virtual RotaryMsg_t getRotary() + { + RotaryMsg_t msg; + return msg; + } + virtual uint8_t getPoint(int16_t* x, int16_t* y, uint8_t get_point) { return 0; } + virtual int getKeyChar(char* c) { return -1; } virtual bool hasTouch() { return false; } virtual bool hasEncoder() { return false; } virtual bool hasKeyboard() { return false; } - virtual void feedback(void *args = NULL) { (void)args; } + virtual void feedback(void* args = NULL) { (void)args; } bool needFullRefresh() { return _full_refresh; } virtual bool useDMA() { return false; } -protected: + + protected: uint16_t _offset_x; uint16_t _offset_y; uint8_t _rotation; @@ -70,8 +80,8 @@ protected: class LilyGoDispArduinoSPI { -private: - SPIClass *_spi = nullptr; + private: + SPIClass* _spi = nullptr; int _cs = -1; int _dc = -1; int _backlight = -1; @@ -82,32 +92,31 @@ private: uint16_t _init_width = 0; uint16_t _init_height = 0; - const CommandTable_t *_init_list; + const CommandTable_t* _init_list; size_t _init_list_length; - const DispRotationConfig_t *_rotation_configs; + const DispRotationConfig_t* _rotation_configs; SemaphoreHandle_t _lock = nullptr; -public: + public: uint16_t _width = 0; uint16_t _height = 0; uint8_t _brightness = 0; - LilyGoDispArduinoSPI(uint16_t width, uint16_t height, const CommandTable_t *init_list, - size_t init_list_length, const DispRotationConfig_t *rotation_config) : - _init_width(width), _init_height(height), _init_list(init_list), - _init_list_length(init_list_length), _rotation_configs(rotation_config) {} + LilyGoDispArduinoSPI(uint16_t width, uint16_t height, const CommandTable_t* init_list, + size_t init_list_length, const DispRotationConfig_t* rotation_config) : _init_width(width), _init_height(height), _init_list(init_list), + _init_list_length(init_list_length), _rotation_configs(rotation_config) {} bool init(int sck, int miso, int mosi, int cs, int rst, int dc, int backlight, - uint32_t freq_Mhz = 80, SPIClass &spi = SPI); + uint32_t freq_Mhz = 80, SPIClass& spi = SPI); void end(); void setRotation(uint8_t rotation); uint8_t getRotation(); - void pushColors(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *color); - void pushColors(uint16_t *data, uint32_t len); + void pushColors(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t* color); + void pushColors(uint16_t* data, uint32_t len); void sleep(); void wakeup(); void setBrightness(uint8_t level); - void writeParams(uint8_t cmd, uint8_t *data = nullptr, size_t length = 0); + void writeParams(uint8_t cmd, uint8_t* data = nullptr, size_t length = 0); void writeData(uint8_t data); void writeCommand(uint8_t cmd); void setAddrWindow(uint16_t xs, uint16_t ys, uint16_t xe, uint16_t ye); diff --git a/src/display/drivers/ST7796.cpp b/src/display/drivers/ST7796.cpp index 1244fb16..81ccd1cd 100644 --- a/src/display/drivers/ST7796.cpp +++ b/src/display/drivers/ST7796.cpp @@ -1,29 +1,31 @@ #include "display/drivers/ST7796.h" -namespace display { -namespace drivers { +namespace display +{ +namespace drivers +{ // ST7796 initialization command sequence static const CommandTable_t st7796_init_commands[] = { - {0x01, {0x00}, 0x80}, // Software reset, delay 120ms - {0x11, {0x00}, 0x80}, // Sleep out, delay 120ms - {0xF0, {0xC3}, 0x01}, // Command Set Control 1 - {0xF0, {0xC3}, 0x01}, // Command Set Control 1 - {0xF0, {0x96}, 0x01}, // Command Set Control 1 - {0x36, {0x48}, 0x01}, // Memory Access Control - {0x3A, {0x55}, 0x01}, // Pixel Format Set (16-bit/pixel) - {0xB4, {0x01}, 0x01}, // Display Inversion Control - {0xB6, {0x80, 0x02, 0x3B}, 0x03}, // Display Function Control - {0xE8, {0x40, 0x8A, 0x00, 0x00, 0x29, 0x19, 0xA5, 0x33}, 0x08}, // Power Control 1 - {0xC1, {0x06}, 0x01}, // Power Control 2 - {0xC2, {0xA7}, 0x01}, // Power Control 3 - {0xC5, {0x18}, 0x81}, // VCOM Control, delay 120ms - {0xE0, {0xF0, 0x09, 0x0b, 0x06, 0x04, 0x15, 0x2F, 0x54, 0x42, 0x3C, 0x17, 0x14, 0x18, 0x1B}, 0x0F}, // Positive Voltage Gamma Control - {0xE1, {0xE0, 0x09, 0x0b, 0x06, 0x04, 0x03, 0x2B, 0x43, 0x42, 0x3B, 0x16, 0x14, 0x17, 0x1B}, 0x8F}, // Negative Voltage Gamma Control - {0xF0, {0x3c}, 0x01}, // Command Set Control 1 - {0xF0, {0x69}, 0x81}, // Command Set Control 1, delay 120ms - {0x21, {0x00}, 0x01}, // Display Inversion On - {0x29, {0x00}, 0x01}, // Display On + {0x01, {0x00}, 0x80}, // Software reset, delay 120ms + {0x11, {0x00}, 0x80}, // Sleep out, delay 120ms + {0xF0, {0xC3}, 0x01}, // Command Set Control 1 + {0xF0, {0xC3}, 0x01}, // Command Set Control 1 + {0xF0, {0x96}, 0x01}, // Command Set Control 1 + {0x36, {0x48}, 0x01}, // Memory Access Control + {0x3A, {0x55}, 0x01}, // Pixel Format Set (16-bit/pixel) + {0xB4, {0x01}, 0x01}, // Display Inversion Control + {0xB6, {0x80, 0x02, 0x3B}, 0x03}, // Display Function Control + {0xE8, {0x40, 0x8A, 0x00, 0x00, 0x29, 0x19, 0xA5, 0x33}, 0x08}, // Power Control 1 + {0xC1, {0x06}, 0x01}, // Power Control 2 + {0xC2, {0xA7}, 0x01}, // Power Control 3 + {0xC5, {0x18}, 0x81}, // VCOM Control, delay 120ms + {0xE0, {0xF0, 0x09, 0x0b, 0x06, 0x04, 0x15, 0x2F, 0x54, 0x42, 0x3C, 0x17, 0x14, 0x18, 0x1B}, 0x0F}, // Positive Voltage Gamma Control + {0xE1, {0xE0, 0x09, 0x0b, 0x06, 0x04, 0x03, 0x2B, 0x43, 0x42, 0x3B, 0x16, 0x14, 0x17, 0x1B}, 0x8F}, // Negative Voltage Gamma Control + {0xF0, {0x3c}, 0x01}, // Command Set Control 1 + {0xF0, {0x69}, 0x81}, // Command Set Control 1, delay 120ms + {0x21, {0x00}, 0x01}, // Display Inversion On + {0x29, {0x00}, 0x01}, // Display On }; const CommandTable_t* ST7796::getInitCommands() @@ -36,33 +38,32 @@ size_t ST7796::getInitCommandsCount() return sizeof(st7796_init_commands) / sizeof(st7796_init_commands[0]); } -const DispRotationConfig_t* ST7796::getRotationConfig(uint16_t width, uint16_t height, - uint16_t landscape_offset_x, - uint16_t portrait_offset_y) +const DispRotationConfig_t* ST7796::getRotationConfig(uint16_t width, uint16_t height, + uint16_t landscape_offset_x, + uint16_t portrait_offset_y) { // Rotation configurations for ST7796 // Format: {MADCTL, width, height, offset_x, offset_y} // MADCTL values control display orientation and color order - // + // // Portrait orientations (0°, 180°): use portrait_offset_y for vertical offset // Landscape orientations (90°, 270°): use landscape_offset_x for horizontal offset static DispRotationConfig_t rotation_configs[4]; - + // Portrait 0° (rotated): width=height, height=width, offset_x=0, offset_y=portrait_offset_y rotation_configs[0] = {0xE8, height, width, 0, portrait_offset_y}; - + // Landscape 90° (normal): width=width, height=height, offset_x=landscape_offset_x, offset_y=0 rotation_configs[1] = {0x48, width, height, landscape_offset_x, 0}; - + // Portrait 180° (rotated): width=height, height=width, offset_x=0, offset_y=portrait_offset_y rotation_configs[2] = {0x28, height, width, 0, portrait_offset_y}; - + // Landscape 270° (upside down): width=width, height=height, offset_x=landscape_offset_x, offset_y=0 rotation_configs[3] = {0x88, width, height, landscape_offset_x, 0}; - + return rotation_configs; } } // namespace drivers } // namespace display - diff --git a/src/display/drivers/ST7796.h b/src/display/drivers/ST7796.h index ae9712cf..20de9be8 100644 --- a/src/display/drivers/ST7796.h +++ b/src/display/drivers/ST7796.h @@ -2,30 +2,33 @@ #include "../DisplayInterface.h" -namespace display { -namespace drivers { +namespace display +{ +namespace drivers +{ /** * @brief ST7796 display driver configuration - * + * * This driver provides initialization commands and rotation configurations * for the ST7796 display controller. It can be used by any board that * uses the ST7796 display chip. */ -class ST7796 { -public: +class ST7796 +{ + public: /** * @brief Get the initialization command table for ST7796 * @return Pointer to the command table array */ static const CommandTable_t* getInitCommands(); - + /** * @brief Get the number of initialization commands * @return Number of commands in the init table */ static size_t getInitCommandsCount(); - + /** * @brief Get the rotation configuration for ST7796 * @param width Display width in pixels @@ -33,16 +36,16 @@ public: * @param landscape_offset_x X offset for landscape orientations (90°, 270°), default: 0 * @param portrait_offset_y Y offset for portrait orientations (0°, 180°), default: 0 * @return Pointer to the rotation configuration array - * + * * @note The offset values are board-specific and depend on the physical * display mounting. For T-LoRa-Pager: * - Landscape orientations (90°, 270°): use landscape_offset_x=49 * - Portrait orientations (0°, 180°): use portrait_offset_y=49 */ - static const DispRotationConfig_t* getRotationConfig(uint16_t width, uint16_t height, - uint16_t landscape_offset_x = 0, - uint16_t portrait_offset_y = 0); - + static const DispRotationConfig_t* getRotationConfig(uint16_t width, uint16_t height, + uint16_t landscape_offset_x = 0, + uint16_t portrait_offset_y = 0); + /** * @brief Get the number of rotation configurations * @return Number of rotation configurations (always 4) @@ -52,4 +55,3 @@ public: } // namespace drivers } // namespace display - diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index a8872ecb..96fbe938 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -6,15 +6,15 @@ * @date 2024-07-07 * */ -#include"GPS.h" +#include "GPS.h" -struct uBloxGnssModelInfo { // Structure to hold the module info (uses 341 bytes of RAM) +struct uBloxGnssModelInfo +{ // Structure to hold the module info (uses 341 bytes of RAM) char softVersion[30]; char hardwareVersion[10]; uint8_t extensionNo = 0; char extension[10][30]; -} ; - +}; GPS::GPS() : model("Unkown") { @@ -24,9 +24,9 @@ GPS::~GPS() { } -bool GPS::init(Stream *stream) +bool GPS::init(Stream* stream) { - struct uBloxGnssModelInfo info ; + struct uBloxGnssModelInfo info; _stream = stream; assert(_stream); @@ -37,29 +37,35 @@ bool GPS::init(Stream *stream) int retry = 3; - while (retry--) { + while (retry--) + { Serial.printf("[GPS::init] Attempt %d/3: Getting GPS module version...\n", 4 - retry); // bool legacy_ubx_message = true; // Get UBlox GPS module version - uint8_t cfg_get_hw[] = {0xB5, 0x62, 0x0A, 0x04, 0x00, 0x00, 0x0E, 0x34}; + uint8_t cfg_get_hw[] = {0xB5, 0x62, 0x0A, 0x04, 0x00, 0x00, 0x0E, 0x34}; _stream->write(cfg_get_hw, sizeof(cfg_get_hw)); Serial.printf("[GPS::init] Sent UBX command, waiting for ACK...\n"); uint16_t len = getAck(buffer, 256, 0x0A, 0x04); Serial.printf("[GPS::init] getAck returned len=%d\n", len); - if (len) { + if (len) + { memset((void*)&info, 0, sizeof(info)); uint16_t position = 0; - for (int i = 0; i < 30; i++) { + for (int i = 0; i < 30; i++) + { info.softVersion[i] = buffer[position]; position++; } - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 10; i++) + { info.hardwareVersion[i] = buffer[position]; position++; } - while (len >= position + 30) { - for (int i = 0; i < 30; i++) { + while (len >= position + 30) + { + for (int i = 0; i < 30; i++) + { info.extension[info.extensionNo][i] = buffer[position]; position++; } @@ -72,7 +78,8 @@ bool GPS::init(Stream *stream) Serial.printf("[GPS::init] Soft version: %s\n", info.softVersion); Serial.printf("[GPS::init] Hard version: %s\n", info.hardwareVersion); Serial.printf("[GPS::init] Extensions: %d\n", info.extensionNo); - for (int i = 0; i < info.extensionNo; i++) { + for (int i = 0; i < info.extensionNo; i++) + { Serial.printf("[GPS::init] Extension[%d]: %s\n", i, info.extension[i]); } Serial.printf("[GPS::init] Model: %s\n", info.extension[2]); @@ -81,17 +88,20 @@ bool GPS::init(Stream *stream) log_i("Soft version: %s", info.softVersion); log_i("Hard version: %s", info.hardwareVersion); log_i("Extensions: %d", info.extensionNo); - for (int i = 0; i < info.extensionNo; i++) { + for (int i = 0; i < info.extensionNo; i++) + { log_i("%s", info.extension[i]); } log_i("Model:%s", info.extension[2]); - for (int i = 0; i < info.extensionNo; ++i) { - if (!strncmp(info.extension[i], "OD=", 3)) { - strcpy((char *)buffer, &(info.extension[i][3])); - Serial.printf("[GPS::init] GPS Model: %s\n", (char *)buffer); - log_i("GPS Model: %s", (char *)buffer); - model = (char *)buffer; + for (int i = 0; i < info.extensionNo; ++i) + { + if (!strncmp(info.extension[i], "OD=", 3)) + { + strcpy((char*)buffer, &(info.extension[i][3])); + Serial.printf("[GPS::init] GPS Model: %s\n", (char*)buffer); + log_i("GPS Model: %s", (char*)buffer); + model = (char*)buffer; } } Serial.printf("[GPS::init] GPS initialization SUCCESS\n"); @@ -106,49 +116,61 @@ bool GPS::init(Stream *stream) return false; } - -int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID) +int GPS::getAck(uint8_t* buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID) { - uint16_t ubxFrameCounter = 0; - uint32_t startTime = millis(); - uint16_t needRead = 0; - uint32_t bytesRead = 0; + uint16_t ubxFrameCounter = 0; + uint32_t startTime = millis(); + uint16_t needRead = 0; + uint32_t bytesRead = 0; assert(_stream); - + Serial.printf("[GPS::getAck] Waiting for ACK (class=0x%02X, id=0x%02X), timeout=800ms\n", requestedClass, requestedID); - - while (millis() - startTime < 800) { - while (_stream->available()) { + + while (millis() - startTime < 800) + { + while (_stream->available()) + { int c = _stream->read(); bytesRead++; - switch (ubxFrameCounter) { + switch (ubxFrameCounter) + { case 0: - if (c == 0xB5) { + if (c == 0xB5) + { ubxFrameCounter++; Serial.printf("[GPS::getAck] Found sync byte 1 (0xB5)\n"); } break; case 1: - if (c == 0x62) { + if (c == 0x62) + { ubxFrameCounter++; Serial.printf("[GPS::getAck] Found sync byte 2 (0x62)\n"); - } else { + } + else + { ubxFrameCounter = 0; } break; case 2: - if (c == requestedClass) { + if (c == requestedClass) + { ubxFrameCounter++; Serial.printf("[GPS::getAck] Found class 0x%02X\n", c); - } else { + } + else + { ubxFrameCounter = 0; } break; case 3: - if (c == requestedID) { + if (c == requestedID) + { ubxFrameCounter++; Serial.printf("[GPS::getAck] Found ID 0x%02X\n", c); - } else { + } + else + { ubxFrameCounter = 0; } break; @@ -158,20 +180,24 @@ int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t Serial.printf("[GPS::getAck] Length low byte: %d\n", c); break; case 5: - needRead |= (c << 8); + needRead |= (c << 8); ubxFrameCounter++; Serial.printf("[GPS::getAck] Length high byte: %d, total length: %d\n", c, needRead); break; case 6: - if (needRead >= size) { + if (needRead >= size) + { Serial.printf("[GPS::getAck] ERROR: needRead (%d) >= size (%d)\n", needRead, size); ubxFrameCounter = 0; break; } - if (_stream->readBytes(buffer, needRead) != needRead) { + if (_stream->readBytes(buffer, needRead) != needRead) + { Serial.printf("[GPS::getAck] ERROR: Failed to read %d bytes\n", needRead); ubxFrameCounter = 0; - } else { + } + else + { Serial.printf("[GPS::getAck] SUCCESS: Read %d bytes, total bytes read: %lu\n", needRead, bytesRead); return needRead; } @@ -186,7 +212,6 @@ int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t return 0; } - bool GPS::factory() { assert(_stream); @@ -194,9 +219,10 @@ bool GPS::factory() uint8_t buffer[256]; // Revert module Clear, save and load configurations // B5 62 06 09 0D 00 FF FB 00 00 00 00 00 00 FF FF 00 00 17 2B 7E - uint8_t _legacy_message_reset[] = { 0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E }; + uint8_t _legacy_message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E}; _stream->write(_legacy_message_reset, sizeof(_legacy_message_reset)); - if (!getAck(buffer, 256, 0x05, 0x01)) { + if (!getAck(buffer, 256, 0x05, 0x01)) + { return false; } delay(50); @@ -204,7 +230,8 @@ bool GPS::factory() // UBX-CFG-RATE, Size 8, 'Navigation/measurement rate settings' uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x0E, 0x30}; _stream->write(cfg_rate, sizeof(cfg_rate)); - if (!getAck(buffer, 256, 0x06, 0x08)) { + if (!getAck(buffer, 256, 0x06, 0x08)) + { return false; } log_d("GPS reset successes!"); diff --git a/src/gps/GPS.h b/src/gps/GPS.h index c7546d32..0842f007 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -13,44 +13,52 @@ class GPS : public TinyGPSPlus { -public: + public: GPS(); ~GPS(); - bool init(Stream *stream); + bool init(Stream* stream); bool factory(); - uint32_t loop(bool debug = false) + uint32_t loop(bool debug = false) { static uint32_t loop_count = 0; static uint32_t last_log_ms = 0; uint32_t now = millis(); - + uint32_t chars_processed = 0; - while (_stream->available()) { + while (_stream->available()) + { int c = _stream->read(); chars_processed++; - if (debug) { + if (debug) + { Serial.write(c); - } else { + } + else + { encode(c); } } - if (debug) { - while (Serial.available()) { + if (debug) + { + while (Serial.available()) + { _stream->write(Serial.read()); } } - + // Log periodically (every 100 loops or every 5 seconds) loop_count++; - if (loop_count % 100 == 0 || (now - last_log_ms) >= 5000) { + if (loop_count % 100 == 0 || (now - last_log_ms) >= 5000) + { uint32_t total_chars = charsProcessed(); bool has_fix = location.isValid(); - Serial.printf("[GPS::loop] Loop #%lu: chars_processed_this_loop=%lu, total_chars=%lu, has_fix=%d", - loop_count, chars_processed, total_chars, has_fix); - if (has_fix) { + Serial.printf("[GPS::loop] Loop #%lu: chars_processed_this_loop=%lu, total_chars=%lu, has_fix=%d", + loop_count, chars_processed, total_chars, has_fix); + if (has_fix) + { Serial.printf(", lat=%.6f, lng=%.6f, sat=%d", location.lat(), location.lng(), satellites.value()); } Serial.printf("\n"); @@ -64,8 +72,9 @@ public: { return model; } -private: - int getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID); - Stream *_stream; + + private: + int getAck(uint8_t* buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID); + Stream* _stream; String model; }; diff --git a/src/gps/domain/gps_state.h b/src/gps/domain/gps_state.h index 3f694cf5..42619f1e 100644 --- a/src/gps/domain/gps_state.h +++ b/src/gps/domain/gps_state.h @@ -2,9 +2,11 @@ #include -namespace gps { +namespace gps +{ -struct GpsState { +struct GpsState +{ double lat = 0.0; double lng = 0.0; uint8_t satellites = 0; @@ -12,4 +14,4 @@ struct GpsState { uint32_t age = 0; }; -} // namespace gps +} // namespace gps diff --git a/src/gps/domain/motion_config.h b/src/gps/domain/motion_config.h index a55b12e3..c5b127c1 100644 --- a/src/gps/domain/motion_config.h +++ b/src/gps/domain/motion_config.h @@ -1,11 +1,13 @@ #pragma once -#include #include "motion_sensor_ids.h" +#include -namespace gps { +namespace gps +{ -struct MotionConfig { +struct MotionConfig +{ uint32_t idle_timeout_ms = 5 * 60 * 1000; uint32_t poll_interval_ms = 1000; uint32_t task_interval_ms = 200; @@ -13,4 +15,4 @@ struct MotionConfig { uint8_t interrupt_ctrl = 0x40; }; -} // namespace gps +} // namespace gps diff --git a/src/gps/domain/motion_sensor_ids.h b/src/gps/domain/motion_sensor_ids.h index 3dad1a0b..6ab1ae1e 100644 --- a/src/gps/domain/motion_sensor_ids.h +++ b/src/gps/domain/motion_sensor_ids.h @@ -2,11 +2,12 @@ #include -namespace gps { +namespace gps +{ // Bosch sensor IDs (from SensorLib BoschSensorID.hpp) -constexpr uint8_t kMotionDetect = 77; // BHY2_SENSOR_ID_MOTION_DET -constexpr uint8_t kSignificantMotion = 55; // BHY2_SENSOR_ID_SIG -constexpr uint8_t kAnyMotionLpWakeUp = 143; // BHY2_SENSOR_ID_ANY_MOTION_LP_WU +constexpr uint8_t kMotionDetect = 77; // BHY2_SENSOR_ID_MOTION_DET +constexpr uint8_t kSignificantMotion = 55; // BHY2_SENSOR_ID_SIG +constexpr uint8_t kAnyMotionLpWakeUp = 143; // BHY2_SENSOR_ID_ANY_MOTION_LP_WU -} // namespace gps +} // namespace gps diff --git a/src/gps/gps_service_api.cpp b/src/gps/gps_service_api.cpp index 6ccc9367..4e6b7f12 100644 --- a/src/gps/gps_service_api.cpp +++ b/src/gps/gps_service_api.cpp @@ -2,7 +2,8 @@ #include "usecase/gps_service.h" #include -namespace gps { +namespace gps +{ GpsState gps_get_data() { @@ -35,13 +36,13 @@ double calculate_map_resolution(int zoom, double lat) double lat_clamped = lat; if (lat_clamped > MAX_LAT) lat_clamped = MAX_LAT; if (lat_clamped < -MAX_LAT) lat_clamped = -MAX_LAT; - + double resolution_equator = 156543.03392 / std::pow(2.0, zoom); - + double lat_rad = lat_clamped * M_PI / 180.0; double resolution = resolution_equator * std::cos(lat_rad); - + return resolution; } -} // namespace gps +} // namespace gps diff --git a/src/gps/gps_service_api.h b/src/gps/gps_service_api.h index fed2eb75..3723dc14 100644 --- a/src/gps/gps_service_api.h +++ b/src/gps/gps_service_api.h @@ -5,7 +5,8 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" -namespace gps { +namespace gps +{ GpsState gps_get_data(); void gps_set_collection_interval(uint32_t interval_ms); @@ -16,4 +17,4 @@ TaskHandle_t gps_get_task_handle(); // Calculate map resolution (meters per pixel) at given zoom and latitude double calculate_map_resolution(int zoom, double lat); -} // namespace gps +} // namespace gps diff --git a/src/gps/infra/hal_gps_adapter.cpp b/src/gps/infra/hal_gps_adapter.cpp index be9b2f18..099d6711 100644 --- a/src/gps/infra/hal_gps_adapter.cpp +++ b/src/gps/infra/hal_gps_adapter.cpp @@ -2,9 +2,10 @@ #include "board/TLoRaPagerBoard.h" -namespace gps { +namespace gps +{ -void HalGpsAdapter::begin(TLoRaPagerBoard &board) +void HalGpsAdapter::begin(TLoRaPagerBoard& board) { hal_gps_.begin(board); } @@ -59,4 +60,4 @@ bool HalGpsAdapter::syncTime(uint32_t gps_task_interval_ms) return hal_gps_.syncTime(gps_task_interval_ms); } -} // namespace gps +} // namespace gps diff --git a/src/gps/infra/hal_gps_adapter.h b/src/gps/infra/hal_gps_adapter.h index a35ee08e..8133129f 100644 --- a/src/gps/infra/hal_gps_adapter.h +++ b/src/gps/infra/hal_gps_adapter.h @@ -1,16 +1,17 @@ #pragma once -#include "../ports/i_gps_hw.h" #include "../../hal/hal_gps.h" +#include "../ports/i_gps_hw.h" class TLoRaPagerBoard; -namespace gps { +namespace gps +{ class HalGpsAdapter : public IGpsHardware { -public: - void begin(TLoRaPagerBoard &board); + public: + void begin(TLoRaPagerBoard& board); bool isReady() const override; bool init() override; @@ -23,8 +24,8 @@ public: uint8_t satellites() const override; bool syncTime(uint32_t gps_task_interval_ms) override; -private: - hal::HalGps hal_gps_ {}; + private: + hal::HalGps hal_gps_{}; }; -} // namespace gps +} // namespace gps diff --git a/src/gps/infra/hal_motion_adapter.cpp b/src/gps/infra/hal_motion_adapter.cpp index f3a438af..c08e7be9 100644 --- a/src/gps/infra/hal_motion_adapter.cpp +++ b/src/gps/infra/hal_motion_adapter.cpp @@ -2,9 +2,10 @@ #include "board/TLoRaPagerBoard.h" -namespace gps { +namespace gps +{ -void HalMotionAdapter::begin(TLoRaPagerBoard &board) +void HalMotionAdapter::begin(TLoRaPagerBoard& board) { hal_motion_.begin(board); } @@ -15,7 +16,7 @@ bool HalMotionAdapter::isReady() const } bool HalMotionAdapter::configure(uint8_t sensor_id, uint8_t interrupt_ctrl, - SensorDataParseCallback callback, void *user_data) + SensorDataParseCallback callback, void* user_data) { return hal_motion_.configure(sensor_id, interrupt_ctrl, callback, user_data); } @@ -40,4 +41,4 @@ void HalMotionAdapter::update() hal_motion_.update(); } -} // namespace gps +} // namespace gps diff --git a/src/gps/infra/hal_motion_adapter.h b/src/gps/infra/hal_motion_adapter.h index 97031927..4b0e383e 100644 --- a/src/gps/infra/hal_motion_adapter.h +++ b/src/gps/infra/hal_motion_adapter.h @@ -1,27 +1,28 @@ #pragma once -#include "../ports/i_motion_hw.h" #include "../../hal/hal_motion.h" +#include "../ports/i_motion_hw.h" class TLoRaPagerBoard; -namespace gps { +namespace gps +{ class HalMotionAdapter : public IMotionHardware { -public: - void begin(TLoRaPagerBoard &board); + public: + void begin(TLoRaPagerBoard& board); bool isReady() const override; bool configure(uint8_t sensor_id, uint8_t interrupt_ctrl, - SensorDataParseCallback callback, void *user_data) override; + SensorDataParseCallback callback, void* user_data) override; void removeCallback(uint8_t sensor_id, SensorDataParseCallback callback) override; void attachInterrupt(void (*isr)()) override; void detachInterrupt() override; void update() override; -private: - hal::HalMotion hal_motion_ {}; + private: + hal::HalMotion hal_motion_{}; }; -} // namespace gps +} // namespace gps diff --git a/src/gps/motion_policy.cpp b/src/gps/motion_policy.cpp index 27217514..a0212e22 100644 --- a/src/gps/motion_policy.cpp +++ b/src/gps/motion_policy.cpp @@ -1,14 +1,17 @@ #include "motion_policy.h" -namespace gps { +namespace gps +{ -namespace { -MotionPolicy *g_instance = nullptr; +namespace +{ +MotionPolicy* g_instance = nullptr; } -bool MotionPolicy::begin(IMotionHardware &motion, const MotionConfig &config) +bool MotionPolicy::begin(IMotionHardware& motion, const MotionConfig& config) { - if (enabled_ && motion_ != nullptr) { + if (enabled_ && motion_ != nullptr) + { motion_->removeCallback(config_.sensor_id, motionEventCallback); motion_->detachInterrupt(); } @@ -17,7 +20,8 @@ bool MotionPolicy::begin(IMotionHardware &motion, const MotionConfig &config) config_ = config; enabled_ = false; - if (!motion_->isReady()) { + if (!motion_->isReady()) + { return false; } @@ -25,9 +29,9 @@ bool MotionPolicy::begin(IMotionHardware &motion, const MotionConfig &config) config_.sensor_id, config_.interrupt_ctrl, motionEventCallback, - this - ); - if (!configured) { + this); + if (!configured) + { return false; } @@ -47,7 +51,8 @@ void MotionPolicy::onSensorInterrupt() bool MotionPolicy::shouldUpdateSensor(uint32_t now_ms) { - if (sensor_irq_pending_) { + if (sensor_irq_pending_) + { sensor_irq_pending_ = false; return true; } @@ -61,11 +66,13 @@ void MotionPolicy::markSensorUpdated(uint32_t now_ms) bool MotionPolicy::shouldEnableGps(uint32_t now_ms) { - if (!enabled_) { + if (!enabled_) + { return false; } - if (motion_event_pending_) { + if (motion_event_pending_) + { motion_event_pending_ = false; } @@ -75,24 +82,26 @@ bool MotionPolicy::shouldEnableGps(uint32_t now_ms) void IRAM_ATTR MotionPolicy::sensorInterruptHandler() { - if (g_instance != nullptr) { + if (g_instance != nullptr) + { g_instance->onSensorInterrupt(); } } -void MotionPolicy::motionEventCallback(uint8_t sensor_id, uint8_t *data, uint32_t size, - uint64_t *timestamp, void *user_data) +void MotionPolicy::motionEventCallback(uint8_t sensor_id, uint8_t* data, uint32_t size, + uint64_t* timestamp, void* user_data) { (void)sensor_id; (void)data; (void)size; (void)timestamp; - auto *policy = static_cast(user_data); - if (policy == nullptr) { + auto* policy = static_cast(user_data); + if (policy == nullptr) + { return; } policy->motion_event_pending_ = true; policy->last_motion_ms_ = millis(); } -} // namespace gps +} // namespace gps diff --git a/src/gps/motion_policy.h b/src/gps/motion_policy.h index 94875d9d..763b8fd0 100644 --- a/src/gps/motion_policy.h +++ b/src/gps/motion_policy.h @@ -1,31 +1,32 @@ #pragma once -#include #include "domain/motion_config.h" #include "ports/i_motion_hw.h" +#include -namespace gps { +namespace gps +{ class MotionPolicy { -public: - bool begin(IMotionHardware &motion, const MotionConfig &config); + public: + bool begin(IMotionHardware& motion, const MotionConfig& config); bool isEnabled() const { return enabled_; } uint32_t taskIntervalMs() const { return config_.task_interval_ms; } - const MotionConfig &config() const { return config_; } + const MotionConfig& config() const { return config_; } void onSensorInterrupt(); bool shouldUpdateSensor(uint32_t now_ms); void markSensorUpdated(uint32_t now_ms); bool shouldEnableGps(uint32_t now_ms); -private: + private: static void IRAM_ATTR sensorInterruptHandler(); - static void motionEventCallback(uint8_t sensor_id, uint8_t *data, uint32_t size, - uint64_t *timestamp, void *user_data); + static void motionEventCallback(uint8_t sensor_id, uint8_t* data, uint32_t size, + uint64_t* timestamp, void* user_data); - MotionConfig config_ {}; - IMotionHardware *motion_ = nullptr; + MotionConfig config_{}; + IMotionHardware* motion_ = nullptr; bool enabled_ = false; volatile bool sensor_irq_pending_ = false; @@ -34,4 +35,4 @@ private: uint32_t last_sensor_poll_ms_ = 0; }; -} // namespace gps +} // namespace gps diff --git a/src/gps/ports/i_gps_hw.h b/src/gps/ports/i_gps_hw.h index 87861953..ddba6880 100644 --- a/src/gps/ports/i_gps_hw.h +++ b/src/gps/ports/i_gps_hw.h @@ -2,11 +2,12 @@ #include -namespace gps { +namespace gps +{ class IGpsHardware { -public: + public: virtual ~IGpsHardware() = default; virtual bool isReady() const = 0; virtual bool init() = 0; @@ -20,4 +21,4 @@ public: virtual bool syncTime(uint32_t gps_task_interval_ms) = 0; }; -} // namespace gps +} // namespace gps diff --git a/src/gps/ports/i_motion_hw.h b/src/gps/ports/i_motion_hw.h index 5f3dace8..b7230d0c 100644 --- a/src/gps/ports/i_motion_hw.h +++ b/src/gps/ports/i_motion_hw.h @@ -2,19 +2,20 @@ #include "bosch/BoschParseCallbackManager.hpp" -namespace gps { +namespace gps +{ class IMotionHardware { -public: + public: virtual ~IMotionHardware() = default; virtual bool isReady() const = 0; virtual bool configure(uint8_t sensor_id, uint8_t interrupt_ctrl, - SensorDataParseCallback callback, void *user_data) = 0; + SensorDataParseCallback callback, void* user_data) = 0; virtual void removeCallback(uint8_t sensor_id, SensorDataParseCallback callback) = 0; virtual void attachInterrupt(void (*isr)()) = 0; virtual void detachInterrupt() = 0; virtual void update() = 0; }; -} // namespace gps +} // namespace gps diff --git a/src/gps/usecase/gps_service.cpp b/src/gps/usecase/gps_service.cpp index 6fcab0bd..2d850c12 100644 --- a/src/gps/usecase/gps_service.cpp +++ b/src/gps/usecase/gps_service.cpp @@ -3,42 +3,48 @@ #include "board/TLoRaPagerBoard.h" #include "board/TLoRaPagerTypes.h" -namespace { +namespace +{ constexpr uint32_t kGpsSampleIntervalMs = 60000; } -namespace gps { +namespace gps +{ -GpsService &GpsService::getInstance() +GpsService& GpsService::getInstance() { static GpsService instance; return instance; } -void GpsService::begin(TLoRaPagerBoard &board, uint32_t disable_hw_init, - uint32_t gps_interval_ms, const MotionConfig &motion_config) +void GpsService::begin(TLoRaPagerBoard& board, uint32_t disable_hw_init, + uint32_t gps_interval_ms, const MotionConfig& motion_config) { board_ = &board; gps_adapter_.begin(board); motion_adapter_.begin(board); gps_disabled_ = (disable_hw_init & NO_HW_GPS) != 0; - if (gps_disabled_) { + if (gps_disabled_) + { return; } gps_data_mutex_ = xSemaphoreCreateMutex(); - if (gps_data_mutex_ == NULL) { + if (gps_data_mutex_ == NULL) + { log_e("Failed to create GPS data mutex"); } gps_collection_interval_ms_ = gps_interval_ms; motion_config_ = motion_config; - if (gps_collection_interval_ms_ < kGpsSampleIntervalMs) { + if (gps_collection_interval_ms_ < kGpsSampleIntervalMs) + { gps_collection_interval_ms_ = kGpsSampleIntervalMs; } - if (motion_config_.idle_timeout_ms < 60000) { + if (motion_config_.idle_timeout_ms < 60000) + { motion_config_.idle_timeout_ms = 60000; } @@ -48,50 +54,62 @@ void GpsService::begin(TLoRaPagerBoard &board, uint32_t disable_hw_init, 4 * 1024, this, 5, - &gps_task_handle_ - ); - if (task_result != pdPASS) { + &gps_task_handle_); + if (task_result != pdPASS) + { log_e("Failed to create GPS data collection task"); - } else { + } + else + { log_d("GPS data collection task created successfully (interval: %lu ms)", gps_collection_interval_ms_); } motion_control_enabled_ = motion_policy_.begin(motion_adapter_, motion_config_); - if (motion_control_enabled_ && gps_task_handle_ != nullptr) { + if (motion_control_enabled_ && gps_task_handle_ != nullptr) + { vTaskSuspend(gps_task_handle_); } - if (motion_control_enabled_ && motion_task_handle_ == nullptr) { + if (motion_control_enabled_ && motion_task_handle_ == nullptr) + { task_result = xTaskCreate( motionTask, "motion_mgr", 3 * 1024, this, 6, - &motion_task_handle_ - ); - if (task_result != pdPASS) { + &motion_task_handle_); + if (task_result != pdPASS) + { log_e("Failed to create motion manager task"); - } else { + } + else + { log_d("Motion manager task created successfully"); } } - if (!motion_control_enabled_) { + if (!motion_control_enabled_) + { setGPSPowerState(true); } } GpsState GpsService::getData() { - GpsState data {}; - if (gps_data_mutex_ != NULL) { - if (xSemaphoreTake(gps_data_mutex_, pdMS_TO_TICKS(100)) == pdTRUE) { + GpsState data{}; + if (gps_data_mutex_ != NULL) + { + if (xSemaphoreTake(gps_data_mutex_, pdMS_TO_TICKS(100)) == pdTRUE) + { data = gps_state_; - if (data.valid && gps_last_update_time_ > 0) { + if (data.valid && gps_last_update_time_ > 0) + { data.age = millis() - gps_last_update_time_; - } else { + } + else + { data.age = UINT32_MAX; } xSemaphoreGive(gps_data_mutex_); @@ -104,7 +122,8 @@ uint32_t GpsService::getCollectionInterval() const { uint32_t interval = gps_collection_interval_ms_; - if (interval < kGpsSampleIntervalMs) { + if (interval < kGpsSampleIntervalMs) + { interval = kGpsSampleIntervalMs; } @@ -116,49 +135,61 @@ void GpsService::setCollectionInterval(uint32_t interval_ms) if (interval_ms < kGpsSampleIntervalMs) interval_ms = kGpsSampleIntervalMs; if (interval_ms > 600000) interval_ms = 600000; - if (gps_data_mutex_ != NULL) { - if (xSemaphoreTake(gps_data_mutex_, portMAX_DELAY) == pdTRUE) { + if (gps_data_mutex_ != NULL) + { + if (xSemaphoreTake(gps_data_mutex_, portMAX_DELAY) == pdTRUE) + { gps_collection_interval_ms_ = interval_ms; xSemaphoreGive(gps_data_mutex_); } } } -void GpsService::setMotionConfig(const MotionConfig &config) +void GpsService::setMotionConfig(const MotionConfig& config) { - if (board_ == nullptr || gps_disabled_) { + if (board_ == nullptr || gps_disabled_) + { return; } motion_config_ = config; - if (motion_config_.idle_timeout_ms < 60000) { + if (motion_config_.idle_timeout_ms < 60000) + { motion_config_.idle_timeout_ms = 60000; } bool was_enabled = motion_control_enabled_; motion_control_enabled_ = motion_policy_.begin(motion_adapter_, motion_config_); - if (motion_control_enabled_) { - if (gps_task_handle_ != nullptr) { + if (motion_control_enabled_) + { + if (gps_task_handle_ != nullptr) + { vTaskSuspend(gps_task_handle_); } - if (motion_task_handle_ == nullptr) { + if (motion_task_handle_ == nullptr) + { BaseType_t task_result = xTaskCreate( motionTask, "motion_mgr", 3 * 1024, this, 6, - &motion_task_handle_ - ); - if (task_result != pdPASS) { + &motion_task_handle_); + if (task_result != pdPASS) + { log_e("Failed to create motion manager task"); - } else { + } + else + { log_d("Motion manager task created successfully"); } } - } else if (was_enabled) { - if (gps_task_handle_ != nullptr) { + } + else if (was_enabled) + { + if (gps_task_handle_ != nullptr) + { vTaskResume(gps_task_handle_); } setGPSPowerState(true); @@ -179,10 +210,11 @@ void GpsService::setMotionSensorId(uint8_t sensor_id) setMotionConfig(cfg); } -void GpsService::gpsTask(void *pvParameters) +void GpsService::gpsTask(void* pvParameters) { - GpsService *service = static_cast(pvParameters); - if (service == nullptr) { + GpsService* service = static_cast(pvParameters); + if (service == nullptr) + { vTaskDelete(NULL); return; } @@ -196,7 +228,8 @@ void GpsService::gpsTask(void *pvParameters) Serial.printf("[GPS Task] Started at %lu ms, GPS ready: %d\n", task_start_ms, service->gps_adapter_.isReady()); Serial.printf("[GPS Task] Collection interval: %lu ms\n", service->getCollectionInterval()); - while (true) { + while (true) + { loop_count++; uint32_t now_ms = millis(); bool gps_ready = service->gps_adapter_.isReady(); @@ -205,44 +238,54 @@ void GpsService::gpsTask(void *pvParameters) (loop_count % 10 == 0) || ((now_ms - last_log_ms) >= 5000); - if (should_log) { + if (should_log) + { Serial.printf("[GPS Task] Loop %lu: GPS ready=%d, valid=%d, mutex=%p\n", loop_count, gps_ready, service->gps_state_.valid, service->gps_data_mutex_); last_log_ms = now_ms; } - if (!service->gps_powered_) { - if (should_log) { + if (!service->gps_powered_) + { + if (should_log) + { Serial.printf("[GPS Task] GPS power OFF (motion_control=%d), skipping (loop %lu)\n", service->motion_control_enabled_ ? 1 : 0, loop_count); } - } else if (gps_ready) { + } + else if (gps_ready) + { static uint32_t last_total_chars = 0; uint32_t total_chars = service->gps_adapter_.loop(); uint32_t chars_this_loop = (total_chars > last_total_chars) ? (total_chars - last_total_chars) : 0; last_total_chars = total_chars; - if (should_log && chars_this_loop > 0) { + if (should_log && chars_this_loop > 0) + { Serial.printf("[GPS Task] GPS loop processed %lu characters this cycle (total: %lu)\n", chars_this_loop, total_chars); } - if (service->gps_data_mutex_ != NULL && xSemaphoreTake(service->gps_data_mutex_, portMAX_DELAY) == pdTRUE) { + if (service->gps_data_mutex_ != NULL && xSemaphoreTake(service->gps_data_mutex_, portMAX_DELAY) == pdTRUE) + { bool was_valid = service->gps_state_.valid; bool has_fix = service->gps_adapter_.hasFix(); uint8_t sat_count = service->gps_adapter_.satellites(); - if (!service->gps_time_synced_) { + if (!service->gps_time_synced_) + { uint32_t gps_interval = service->getCollectionInterval(); - if (service->gps_adapter_.syncTime(gps_interval)) { + if (service->gps_adapter_.syncTime(gps_interval)) + { service->gps_time_synced_ = true; Serial.printf("[GPS Task] *** TIME SYNCED TO RTC (automatic) *** (loop %lu, sat=%d)\n", loop_count, sat_count); } } - if (has_fix) { + if (has_fix) + { service->gps_state_.lat = service->gps_adapter_.latitude(); service->gps_state_.lng = service->gps_adapter_.longitude(); service->gps_state_.satellites = sat_count; @@ -250,43 +293,57 @@ void GpsService::gpsTask(void *pvParameters) service->gps_last_update_time_ = millis(); service->gps_state_.age = 0; - if (!was_valid || should_log) { + if (!was_valid || should_log) + { Serial.printf("[GPS Task] *** FIX ACQUIRED *** lat=%.6f, lng=%.6f, sat=%d (loop %lu)\n", service->gps_state_.lat, service->gps_state_.lng, service->gps_state_.satellites, loop_count); } - } else { + } + else + { service->gps_state_.valid = false; - if (was_valid) { + if (was_valid) + { Serial.printf("[GPS Task] *** FIX LOST *** (loop %lu)\n", loop_count); } - if (should_log) { + if (should_log) + { Serial.printf("[GPS Task] GPS ready but no fix yet (loop %lu, sat=%d, chars_this_cycle=%lu)\n", loop_count, sat_count, chars_this_loop); } } xSemaphoreGive(service->gps_data_mutex_); - } else { + } + else + { Serial.printf("[GPS Task] ERROR: Failed to take mutex (loop %lu)\n", loop_count); } - } else { + } + else + { static uint32_t last_retry_ms = 0; const uint32_t RETRY_INTERVAL_MS = 300000; - if (should_log) { + if (should_log) + { Serial.printf("[GPS Task] GPS not ready (loop %lu)\n", loop_count); } - if (last_retry_ms == 0 || (now_ms - last_retry_ms) >= RETRY_INTERVAL_MS) { + if (last_retry_ms == 0 || (now_ms - last_retry_ms) >= RETRY_INTERVAL_MS) + { Serial.printf("[GPS Task] Attempting to reinitialize GPS (last retry: %lu ms ago, loop %lu)\n", last_retry_ms > 0 ? (now_ms - last_retry_ms) : 0, loop_count); bool retry_result = service->gps_adapter_.init(); last_retry_ms = now_ms; - if (retry_result) { + if (retry_result) + { Serial.printf("[GPS Task] *** GPS REINITIALIZATION SUCCESSFUL *** (loop %lu)\n", loop_count); - } else { + } + else + { Serial.printf("[GPS Task] GPS reinitialization failed, will retry in %lu ms (loop %lu)\n", RETRY_INTERVAL_MS, loop_count); } @@ -296,7 +353,8 @@ void GpsService::gpsTask(void *pvParameters) uint32_t interval_ms = service->getCollectionInterval(); TickType_t frequency = pdMS_TO_TICKS(interval_ms); - if (should_log) { + if (should_log) + { Serial.printf("[GPS Task] Waiting %lu ms until next cycle...\n", interval_ms); } @@ -304,21 +362,25 @@ void GpsService::gpsTask(void *pvParameters) } } -void GpsService::motionTask(void *pvParameters) +void GpsService::motionTask(void* pvParameters) { - GpsService *service = static_cast(pvParameters); - if (service == nullptr) { + GpsService* service = static_cast(pvParameters); + if (service == nullptr) + { vTaskDelete(NULL); return; } TickType_t last_wake_time = xTaskGetTickCount(); - while (true) { + while (true) + { uint32_t now_ms = millis(); - if (service->motion_adapter_.isReady() && service->motion_policy_.isEnabled()) { - if (service->motion_policy_.shouldUpdateSensor(now_ms)) { + if (service->motion_adapter_.isReady() && service->motion_policy_.isEnabled()) + { + if (service->motion_policy_.shouldUpdateSensor(now_ms)) + { service->motion_adapter_.update(); service->motion_policy_.markSensorUpdated(now_ms); } @@ -331,22 +393,29 @@ void GpsService::motionTask(void *pvParameters) void GpsService::setGPSPowerState(bool enable) { - if (enable) { - if (gps_powered_) { + if (enable) + { + if (gps_powered_) + { return; } gps_adapter_.powerOn(); gps_powered_ = true; gps_adapter_.init(); setCollectionInterval(kGpsSampleIntervalMs); - if (gps_task_handle_ != nullptr) { + if (gps_task_handle_ != nullptr) + { vTaskResume(gps_task_handle_); } - } else { - if (!gps_powered_) { + } + else + { + if (!gps_powered_) + { return; } - if (gps_task_handle_ != nullptr) { + if (gps_task_handle_ != nullptr) + { vTaskSuspend(gps_task_handle_); } gps_adapter_.powerOff(); @@ -356,17 +425,21 @@ void GpsService::setGPSPowerState(bool enable) void GpsService::updateMotionState(uint32_t now_ms) { - if (!motion_control_enabled_ || !motion_policy_.isEnabled()) { + if (!motion_control_enabled_ || !motion_policy_.isEnabled()) + { return; } bool should_enable_gps = motion_policy_.shouldEnableGps(now_ms); - if (should_enable_gps && !gps_powered_) { + if (should_enable_gps && !gps_powered_) + { setGPSPowerState(true); - } else if (!should_enable_gps && gps_powered_) { + } + else if (!should_enable_gps && gps_powered_) + { setGPSPowerState(false); } } -} // namespace gps +} // namespace gps diff --git a/src/gps/usecase/gps_service.h b/src/gps/usecase/gps_service.h index b8463781..2da2236b 100644 --- a/src/gps/usecase/gps_service.h +++ b/src/gps/usecase/gps_service.h @@ -1,8 +1,8 @@ #pragma once -#include #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include #include "../domain/gps_state.h" #include "../domain/motion_config.h" @@ -12,37 +12,38 @@ class TLoRaPagerBoard; -namespace gps { +namespace gps +{ class GpsService { -public: - static GpsService &getInstance(); + public: + static GpsService& getInstance(); - void begin(TLoRaPagerBoard &board, uint32_t disable_hw_init, - uint32_t gps_interval_ms, const MotionConfig &motion_config); + void begin(TLoRaPagerBoard& board, uint32_t disable_hw_init, + uint32_t gps_interval_ms, const MotionConfig& motion_config); GpsState getData(); uint32_t getCollectionInterval() const; void setCollectionInterval(uint32_t interval_ms); MotionConfig getMotionConfig() const { return motion_config_; } - void setMotionConfig(const MotionConfig &config); + void setMotionConfig(const MotionConfig& config); void setMotionIdleTimeout(uint32_t timeout_ms); void setMotionSensorId(uint8_t sensor_id); TaskHandle_t getTaskHandle() const { return gps_task_handle_; } -private: + private: GpsService() = default; - GpsService(const GpsService &) = delete; - GpsService &operator=(const GpsService &) = delete; + GpsService(const GpsService&) = delete; + GpsService& operator=(const GpsService&) = delete; - static void gpsTask(void *pvParameters); - static void motionTask(void *pvParameters); + static void gpsTask(void* pvParameters); + static void motionTask(void* pvParameters); void setGPSPowerState(bool enable); void updateMotionState(uint32_t now_ms); - TLoRaPagerBoard *board_ = nullptr; - GpsState gps_state_ {}; + TLoRaPagerBoard* board_ = nullptr; + GpsState gps_state_{}; SemaphoreHandle_t gps_data_mutex_ = nullptr; TaskHandle_t gps_task_handle_ = nullptr; TaskHandle_t motion_task_handle_ = nullptr; @@ -54,10 +55,10 @@ private: bool gps_disabled_ = false; bool motion_control_enabled_ = false; - MotionConfig motion_config_ {}; - MotionPolicy motion_policy_ {}; - HalGpsAdapter gps_adapter_ {}; - HalMotionAdapter motion_adapter_ {}; + MotionConfig motion_config_{}; + MotionPolicy motion_policy_{}; + HalGpsAdapter gps_adapter_{}; + HalMotionAdapter motion_adapter_{}; }; -} // namespace gps +} // namespace gps diff --git a/src/hal/hal_gps.cpp b/src/hal/hal_gps.cpp index 1da453d2..ee8234e8 100644 --- a/src/hal/hal_gps.cpp +++ b/src/hal/hal_gps.cpp @@ -4,9 +4,10 @@ #include "board/TLoRaPagerTypes.h" #include "pins_arduino.h" -namespace hal { +namespace hal +{ -void HalGps::begin(TLoRaPagerBoard &board) +void HalGps::begin(TLoRaPagerBoard& board) { board_ = &board; } @@ -18,7 +19,8 @@ bool HalGps::isReady() const bool HalGps::init() { - if (board_ == nullptr) { + if (board_ == nullptr) + { return false; } return board_->initGPS(); @@ -26,7 +28,8 @@ bool HalGps::init() void HalGps::powerOn() { - if (board_ == nullptr) { + if (board_ == nullptr) + { return; } board_->powerControl(POWER_GPS, true); @@ -35,7 +38,8 @@ void HalGps::powerOn() void HalGps::powerOff() { - if (board_ == nullptr) { + if (board_ == nullptr) + { return; } Serial1.end(); @@ -45,7 +49,8 @@ void HalGps::powerOff() uint32_t HalGps::loop() { - if (board_ == nullptr) { + if (board_ == nullptr) + { return 0; } return board_->gps.loop(); @@ -73,10 +78,11 @@ uint8_t HalGps::satellites() const bool HalGps::syncTime(uint32_t gps_task_interval_ms) { - if (board_ == nullptr) { + if (board_ == nullptr) + { return false; } return board_->syncTimeFromGPS(gps_task_interval_ms); } -} // namespace hal +} // namespace hal diff --git a/src/hal/hal_gps.h b/src/hal/hal_gps.h index 0fc9c24a..bb703374 100644 --- a/src/hal/hal_gps.h +++ b/src/hal/hal_gps.h @@ -4,12 +4,13 @@ class TLoRaPagerBoard; -namespace hal { +namespace hal +{ class HalGps { -public: - void begin(TLoRaPagerBoard &board); + public: + void begin(TLoRaPagerBoard& board); bool isReady() const; bool init(); void powerOn(); @@ -21,8 +22,8 @@ public: uint8_t satellites() const; bool syncTime(uint32_t gps_task_interval_ms); -private: - TLoRaPagerBoard *board_ = nullptr; + private: + TLoRaPagerBoard* board_ = nullptr; }; -} // namespace hal +} // namespace hal diff --git a/src/hal/hal_motion.cpp b/src/hal/hal_motion.cpp index 7a086c89..493e5948 100644 --- a/src/hal/hal_motion.cpp +++ b/src/hal/hal_motion.cpp @@ -3,9 +3,10 @@ #include "board/TLoRaPagerBoard.h" #include "pins_arduino.h" -namespace hal { +namespace hal +{ -void HalMotion::begin(TLoRaPagerBoard &board) +void HalMotion::begin(TLoRaPagerBoard& board) { board_ = &board; } @@ -16,14 +17,16 @@ bool HalMotion::isReady() const } bool HalMotion::configure(uint8_t sensor_id, uint8_t interrupt_ctrl, - SensorDataParseCallback callback, void *user_data) + SensorDataParseCallback callback, void* user_data) { - if (board_ == nullptr) { + if (board_ == nullptr) + { return false; } bool configured = board_->sensor.configure(sensor_id, 1.0f, 0); - if (!configured) { + if (!configured) + { log_w("Motion detect configure failed (sensor_id=%u)", sensor_id); return false; } @@ -31,21 +34,20 @@ bool HalMotion::configure(uint8_t sensor_id, uint8_t interrupt_ctrl, board_->sensor.onResultEvent( static_cast(sensor_id), callback, - user_data - ); + user_data); board_->sensor.setInterruptCtrl(interrupt_ctrl); return true; } void HalMotion::removeCallback(uint8_t sensor_id, SensorDataParseCallback callback) { - if (board_ == nullptr) { + if (board_ == nullptr) + { return; } board_->sensor.removeResultEvent( static_cast(sensor_id), - callback - ); + callback); } void HalMotion::attachInterrupt(void (*isr)()) @@ -60,10 +62,11 @@ void HalMotion::detachInterrupt() void HalMotion::update() { - if (board_ == nullptr) { + if (board_ == nullptr) + { return; } board_->sensor.update(); } -} // namespace hal +} // namespace hal diff --git a/src/hal/hal_motion.h b/src/hal/hal_motion.h index 14b55129..2127ad60 100644 --- a/src/hal/hal_motion.h +++ b/src/hal/hal_motion.h @@ -1,27 +1,28 @@ #pragma once +#include "bosch/BoschParseCallbackManager.hpp" #include #include -#include "bosch/BoschParseCallbackManager.hpp" class TLoRaPagerBoard; -namespace hal { +namespace hal +{ class HalMotion { -public: - void begin(TLoRaPagerBoard &board); + public: + void begin(TLoRaPagerBoard& board); bool isReady() const; bool configure(uint8_t sensor_id, uint8_t interrupt_ctrl, - SensorDataParseCallback callback, void *user_data); + SensorDataParseCallback callback, void* user_data); void removeCallback(uint8_t sensor_id, SensorDataParseCallback callback); void attachInterrupt(void (*isr)()); void detachInterrupt(); void update(); -private: - TLoRaPagerBoard *board_ = nullptr; + private: + TLoRaPagerBoard* board_ = nullptr; }; -} // namespace hal +} // namespace hal diff --git a/src/input/rotary/Rotary.cpp b/src/input/rotary/Rotary.cpp index 9c573064..b245b37c 100644 --- a/src/input/rotary/Rotary.cpp +++ b/src/input/rotary/Rotary.cpp @@ -5,8 +5,8 @@ * */ -#include "Arduino.h" #include "Rotary.h" +#include "Arduino.h" /* * The below state table has, for each state (row), the new state @@ -25,18 +25,18 @@ #define R_CW_BEGIN_M 0x4 #define R_CCW_BEGIN_M 0x5 const unsigned char ttable[6][4] = { - // R_START (00) - {R_START_M, R_CW_BEGIN, R_CCW_BEGIN, R_START}, - // R_CCW_BEGIN - {R_START_M | DIR_CCW, R_START, R_CCW_BEGIN, R_START}, - // R_CW_BEGIN - {R_START_M | DIR_CW, R_CW_BEGIN, R_START, R_START}, - // R_START_M (11) - {R_START_M, R_CCW_BEGIN_M, R_CW_BEGIN_M, R_START}, - // R_CW_BEGIN_M - {R_START_M, R_START_M, R_CW_BEGIN_M, R_START | DIR_CW}, - // R_CCW_BEGIN_M - {R_START_M, R_CCW_BEGIN_M, R_START_M, R_START | DIR_CCW}, + // R_START (00) + {R_START_M, R_CW_BEGIN, R_CCW_BEGIN, R_START}, + // R_CCW_BEGIN + {R_START_M | DIR_CCW, R_START, R_CCW_BEGIN, R_START}, + // R_CW_BEGIN + {R_START_M | DIR_CW, R_CW_BEGIN, R_START, R_START}, + // R_START_M (11) + {R_START_M, R_CCW_BEGIN_M, R_CW_BEGIN_M, R_START}, + // R_CW_BEGIN_M + {R_START_M, R_START_M, R_CW_BEGIN_M, R_START | DIR_CW}, + // R_CCW_BEGIN_M + {R_START_M, R_CCW_BEGIN_M, R_START_M, R_START | DIR_CCW}, }; #else // Use the full-step state table (emits a code at 00 only) @@ -48,55 +48,61 @@ const unsigned char ttable[6][4] = { #define R_CCW_NEXT 0x6 const unsigned char ttable[7][4] = { - // R_START - {R_START, R_CW_BEGIN, R_CCW_BEGIN, R_START}, - // R_CW_FINAL - {R_CW_NEXT, R_START, R_CW_FINAL, R_START | DIR_CW}, - // R_CW_BEGIN - {R_CW_NEXT, R_CW_BEGIN, R_START, R_START}, - // R_CW_NEXT - {R_CW_NEXT, R_CW_BEGIN, R_CW_FINAL, R_START}, - // R_CCW_BEGIN - {R_CCW_NEXT, R_START, R_CCW_BEGIN, R_START}, - // R_CCW_FINAL - {R_CCW_NEXT, R_CCW_FINAL, R_START, R_START | DIR_CCW}, - // R_CCW_NEXT - {R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START}, + // R_START + {R_START, R_CW_BEGIN, R_CCW_BEGIN, R_START}, + // R_CW_FINAL + {R_CW_NEXT, R_START, R_CW_FINAL, R_START | DIR_CW}, + // R_CW_BEGIN + {R_CW_NEXT, R_CW_BEGIN, R_START, R_START}, + // R_CW_NEXT + {R_CW_NEXT, R_CW_BEGIN, R_CW_FINAL, R_START}, + // R_CCW_BEGIN + {R_CCW_NEXT, R_START, R_CCW_BEGIN, R_START}, + // R_CCW_FINAL + {R_CCW_NEXT, R_CCW_FINAL, R_START, R_START | DIR_CCW}, + // R_CCW_NEXT + {R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START}, }; #endif /* * Constructor. Each arg is the pin number for each encoder contact. */ -Rotary::Rotary(char _pin1, char _pin2) { - // Assign variables. - pin1 = _pin1; - pin2 = _pin2; - // Initialise state. - state = R_START; - // Don't invert read pin state by default - inverter = 0; +Rotary::Rotary(char _pin1, char _pin2) +{ + // Assign variables. + pin1 = _pin1; + pin2 = _pin2; + // Initialise state. + state = R_START; + // Don't invert read pin state by default + inverter = 0; } -void Rotary::begin(bool internalPullup, bool flipLogicForPulldown) { +void Rotary::begin(bool internalPullup, bool flipLogicForPulldown) +{ - if (internalPullup){ - // Enable weak pullups - pinMode(pin1,INPUT_PULLUP); - pinMode(pin2,INPUT_PULLUP); - }else{ - // Set pins to input. - pinMode(pin1, INPUT); - pinMode(pin2, INPUT); - } - inverter = flipLogicForPulldown ? 1 : 0; + if (internalPullup) + { + // Enable weak pullups + pinMode(pin1, INPUT_PULLUP); + pinMode(pin2, INPUT_PULLUP); + } + else + { + // Set pins to input. + pinMode(pin1, INPUT); + pinMode(pin2, INPUT); + } + inverter = flipLogicForPulldown ? 1 : 0; } -unsigned char Rotary::process() { - // Grab state of input pins. - unsigned char pinstate = ((inverter ^ digitalRead(pin2)) << 1) | (inverter ^ digitalRead(pin1)); - // Determine new state from the pins and state table. - state = ttable[state & 0xf][pinstate]; - // Return emit bits, ie the generated event. - return state & 0x30; +unsigned char Rotary::process() +{ + // Grab state of input pins. + unsigned char pinstate = ((inverter ^ digitalRead(pin2)) << 1) | (inverter ^ digitalRead(pin1)); + // Determine new state from the pins and state table. + state = ttable[state & 0xf][pinstate]; + // Return emit bits, ie the generated event. + return state & 0x30; } diff --git a/src/input/rotary/Rotary.h b/src/input/rotary/Rotary.h index 96d6a3f0..b1a02279 100644 --- a/src/input/rotary/Rotary.h +++ b/src/input/rotary/Rotary.h @@ -23,10 +23,11 @@ class Rotary public: Rotary(char, char); unsigned char process(); - void begin(bool internalPullup=true, bool flipLogicForPulldown=false); - + void begin(bool internalPullup = true, bool flipLogicForPulldown = false); + inline unsigned char pin_1() const { return pin1; } inline unsigned char pin_2() const { return pin2; } + private: unsigned char state; unsigned char pin1; @@ -35,4 +36,3 @@ class Rotary }; #endif - diff --git a/src/main.cpp b/src/main.cpp index 00aae915..ec1e03b4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,20 +1,21 @@ #include "board/TLoRaPagerBoard.h" -#include "ui/LV_Helper.h" -#include #include "freertos/FreeRTOS.h" -#include "freertos/task.h" #include "freertos/semphr.h" +#include "freertos/task.h" +#include "ui/LV_Helper.h" #include +#include #include +#include "app/app_context.h" #include "display/DisplayConfig.h" #include "ui/assets/images.h" #include "ui/ui_common.h" -#include "app/app_context.h" #include "ui/widgets/system_notification.h" // Custom app icons generated as C images (RGB565A8) -extern "C" { +extern "C" +{ extern const lv_image_dsc_t gps_icon; extern const lv_image_dsc_t Chat; extern const lv_image_dsc_t Setting; @@ -28,12 +29,12 @@ extern "C" { #define MAIN_TIMING_DEBUG 0 // Forward declarations for app entry functions (implemented in ui_*.cpp) -void ui_gps_enter(lv_obj_t *parent); -void ui_chat_enter(lv_obj_t *parent); -void ui_contacts_enter(lv_obj_t *parent); -void ui_setting_enter(lv_obj_t *parent); +void ui_gps_enter(lv_obj_t* parent); +void ui_chat_enter(lv_obj_t* parent); +void ui_contacts_enter(lv_obj_t* parent); +void ui_setting_enter(lv_obj_t* parent); #ifdef ARDUINO_USB_MODE -void ui_usb_enter(lv_obj_t *parent); +void ui_usb_enter(lv_obj_t* parent); #endif // GPS data access - now provided by GpsService @@ -59,23 +60,25 @@ bool isScreenSleepDisabled(); // Use gps::GpsService::getInstance().getCollectionInterval()/setCollectionInterval() // Factory-style menu structure (global for ui_*.cpp access) -lv_obj_t *main_screen = nullptr; -lv_obj_t *menu_panel = nullptr; -lv_group_t *menu_g = nullptr; -lv_group_t *app_g = nullptr; -lv_obj_t *desc_label = nullptr; -lv_obj_t *time_label = nullptr; // Time display label at top left of menu -lv_obj_t *battery_label = nullptr; // Battery display label at top right of menu +lv_obj_t* main_screen = nullptr; +lv_obj_t* menu_panel = nullptr; +lv_group_t* menu_g = nullptr; +lv_group_t* app_g = nullptr; +lv_obj_t* desc_label = nullptr; +lv_obj_t* time_label = nullptr; // Time display label at top left of menu +lv_obj_t* battery_label = nullptr; // Battery display label at top right of menu -namespace { +namespace +{ // App function types (like factory example) -typedef void (*app_func_t)(lv_obj_t *parent); +typedef void (*app_func_t)(lv_obj_t* parent); -typedef struct { +typedef struct +{ app_func_t setup_func_cb; app_func_t exit_func_cb; - void *user_data; + void* user_data; } app_t; // App entry functions (implemented in ui_*.cpp files, global scope) @@ -105,7 +108,7 @@ app_t ui_setting_main = { }; // Shutdown app - directly triggers system shutdown -static void ui_shutdown_enter(lv_obj_t *parent) +static void ui_shutdown_enter(lv_obj_t* parent) { // Directly trigger software shutdown without confirmation dialog // The main menu access already implies user intent @@ -127,14 +130,14 @@ app_t ui_usb_main = { #endif #ifdef ARDUINO_USB_MODE -const char *kAppNames[6] = {"GPS", "Chat", "Contacts", "USB Mass Storage", "Setting", "Shutdown"}; -const lv_image_dsc_t *kAppImages[6] = {&gps_icon, &Chat, &contact, &img_usb, &Setting, &shutdown}; -app_t *kAppFuncs[6] = {&ui_gps_main, &ui_chat_main, &ui_contacts_main, &ui_usb_main, &ui_setting_main, &ui_shutdown_main}; +const char* kAppNames[6] = {"GPS", "Chat", "Contacts", "USB Mass Storage", "Setting", "Shutdown"}; +const lv_image_dsc_t* kAppImages[6] = {&gps_icon, &Chat, &contact, &img_usb, &Setting, &shutdown}; +app_t* kAppFuncs[6] = {&ui_gps_main, &ui_chat_main, &ui_contacts_main, &ui_usb_main, &ui_setting_main, &ui_shutdown_main}; #define NUM_APPS 6 #else -const char *kAppNames[5] = {"GPS", "Chat", "Contacts", "Setting", "Shutdown"}; -const lv_image_dsc_t *kAppImages[5] = {&gps_icon, &Chat, &contact, &Setting, &shutdown}; -app_t *kAppFuncs[5] = {&ui_gps_main, &ui_chat_main, &ui_contacts_main, &ui_setting_main, &ui_shutdown_main}; +const char* kAppNames[5] = {"GPS", "Chat", "Contacts", "Setting", "Shutdown"}; +const lv_image_dsc_t* kAppImages[5] = {&gps_icon, &Chat, &contact, &Setting, &shutdown}; +app_t* kAppFuncs[5] = {&ui_gps_main, &ui_chat_main, &ui_contacts_main, &ui_setting_main, &ui_shutdown_main}; #define NUM_APPS 5 #endif @@ -149,22 +152,23 @@ void menu_hidden() lv_tileview_set_tile_by_index(main_screen, 0, 1, LV_ANIM_ON); } -static void btn_event_cb(lv_event_t *e) +static void btn_event_cb(lv_event_t* e) { lv_event_code_t c = lv_event_get_code(e); - const char *text = (const char *)lv_event_get_user_data(e); - if (c == LV_EVENT_FOCUSED) { + const char* text = (const char*)lv_event_get_user_data(e); + if (c == LV_EVENT_FOCUSED) + { #if LVGL_VERSION_MAJOR == 9 - lv_obj_send_event(desc_label, (lv_event_code_t)name_change_id, (void *)text); + lv_obj_send_event(desc_label, (lv_event_code_t)name_change_id, (void*)text); #else // For LVGL v8, would use lv_msg_send #endif } } -static void create_app(lv_obj_t *parent, const char *name, const lv_image_dsc_t *img, app_t *app_fun) +static void create_app(lv_obj_t* parent, const char* name, const lv_image_dsc_t* img, app_t* app_fun) { - lv_obj_t *btn = lv_btn_create(parent); + lv_obj_t* btn = lv_btn_create(parent); lv_coord_t w = 150; lv_coord_t h = LV_PCT(100); @@ -174,21 +178,25 @@ static void create_app(lv_obj_t *parent, const char *name, const lv_image_dsc_t lv_obj_set_style_shadow_width(btn, 30, LV_PART_MAIN); lv_obj_set_style_shadow_color(btn, lv_color_black(), LV_PART_MAIN); uint32_t phy_hor_res = lv_display_get_physical_horizontal_resolution(NULL); - if (phy_hor_res < 320) { + if (phy_hor_res < 320) + { lv_obj_set_style_radius(btn, LV_RADIUS_CIRCLE, 0); } - lv_obj_set_user_data(btn, (void *)name); + lv_obj_set_user_data(btn, (void*)name); - if (img != NULL) { - lv_obj_t *icon = lv_image_create(btn); + if (img != NULL) + { + lv_obj_t* icon = lv_image_create(btn); lv_image_set_src(icon, img); lv_obj_center(icon); } /* Text change event callback */ - lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_FOCUSED, (void *)name); + lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_FOCUSED, (void*)name); /* Click to select event callback */ - lv_obj_add_event_cb(btn, [](lv_event_t *e) { + lv_obj_add_event_cb( + btn, [](lv_event_t* e) + { lv_event_code_t c = lv_event_get_code(e); app_t *func_cb = (app_t *)lv_event_get_user_data(e); lv_obj_t *parent = lv_obj_get_child(main_screen, 1); @@ -201,16 +209,16 @@ static void create_app(lv_obj_t *parent, const char *name, const lv_image_dsc_t (*func_cb->setup_func_cb)(parent); } menu_hidden(); - } - }, - LV_EVENT_CLICKED, app_fun); + } }, + LV_EVENT_CLICKED, app_fun); } -void menu_name_label_event_cb(lv_event_t *e) +void menu_name_label_event_cb(lv_event_t* e) { #if LVGL_VERSION_MAJOR == 9 - const char *v = (const char *)lv_event_get_param(e); - if (v) { + const char* v = (const char*)lv_event_get_param(e); + if (v) + { lv_label_set_text(lv_event_get_target_obj(e), v); } #else @@ -226,14 +234,14 @@ void menu_name_label_event_cb(lv_event_t *e) // GPS data collection task is now in TLoRaPagerBoard class // Screen sleep management -static uint32_t last_user_activity_time = 0; // Timestamp of last user activity +static uint32_t last_user_activity_time = 0; // Timestamp of last user activity static SemaphoreHandle_t activity_mutex = NULL; static TaskHandle_t screen_sleep_task_handle = NULL; static bool screen_sleeping = false; -static bool screen_sleep_disabled = false; // Flag to disable screen sleep (e.g., during USB mode) +static bool screen_sleep_disabled = false; // Flag to disable screen sleep (e.g., during USB mode) static uint8_t saved_keyboard_brightness = 127; // Save keyboard brightness before sleep (default 127) -static uint32_t screen_sleep_timeout_ms = 30000; // Default 30 seconds, can be configured -static Preferences preferences; // For saving/loading settings +static uint32_t screen_sleep_timeout_ms = 30000; // Default 30 seconds, can be configured +static Preferences preferences; // For saving/loading settings // Power management wrapper function for accessing preferences Preferences& getPreferencesInstance() { return preferences; } @@ -251,8 +259,10 @@ TaskHandle_t getScreenSleepTaskHandle() { return screen_sleep_task_handle; } bool isScreenSleeping() { bool sleeping = false; - if (activity_mutex != NULL) { - if (xSemaphoreTake(activity_mutex, pdMS_TO_TICKS(10)) == pdTRUE) { + if (activity_mutex != NULL) + { + if (xSemaphoreTake(activity_mutex, pdMS_TO_TICKS(10)) == pdTRUE) + { sleeping = screen_sleeping; xSemaphoreGive(activity_mutex); } @@ -267,26 +277,29 @@ bool isScreenSleeping() */ uint32_t getScreenSleepTimeout() { - uint32_t timeout = 30000; // Default 30 seconds - + uint32_t timeout = 30000; // Default 30 seconds + // Read from persistent storage to ensure we have the latest value - preferences.begin("settings", true); // Read-only mode - timeout = preferences.getUInt("sleep_timeout", 30000); // Default 30 seconds + preferences.begin("settings", true); // Read-only mode + timeout = preferences.getUInt("sleep_timeout", 30000); // Default 30 seconds preferences.end(); - + // Ensure minimum timeout - if (timeout < 10000) { + if (timeout < 10000) + { timeout = 30000; } - + // Also update memory variable for faster access - if (activity_mutex != NULL) { - if (xSemaphoreTake(activity_mutex, pdMS_TO_TICKS(10)) == pdTRUE) { + if (activity_mutex != NULL) + { + if (xSemaphoreTake(activity_mutex, pdMS_TO_TICKS(10)) == pdTRUE) + { screen_sleep_timeout_ms = timeout; xSemaphoreGive(activity_mutex); } } - + return timeout; } @@ -299,9 +312,11 @@ void setScreenSleepTimeout(uint32_t timeout_ms) // Minimum 10 seconds, maximum 300 seconds (5 minutes) if (timeout_ms < 10000) timeout_ms = 10000; if (timeout_ms > 300000) timeout_ms = 300000; - - if (activity_mutex != NULL) { - if (xSemaphoreTake(activity_mutex, portMAX_DELAY) == pdTRUE) { + + if (activity_mutex != NULL) + { + if (xSemaphoreTake(activity_mutex, portMAX_DELAY) == pdTRUE) + { screen_sleep_timeout_ms = timeout_ms; // Save to preferences preferences.begin("settings", false); @@ -321,15 +336,19 @@ void setScreenSleepTimeout(uint32_t timeout_ms) */ void disableScreenSleep() { - if (activity_mutex != NULL) { - if (xSemaphoreTake(activity_mutex, portMAX_DELAY) == pdTRUE) { + if (activity_mutex != NULL) + { + if (xSemaphoreTake(activity_mutex, portMAX_DELAY) == pdTRUE) + { screen_sleep_disabled = true; // Wake up screen if it's sleeping - if (screen_sleeping) { + if (screen_sleeping) + { screen_sleeping = false; instance.setBrightness(DEVICE_MAX_BRIGHTNESS_LEVEL); // Restore keyboard brightness - if (instance.hasKeyboard()) { + if (instance.hasKeyboard()) + { instance.kb.setBrightness(saved_keyboard_brightness); } } @@ -343,8 +362,10 @@ void disableScreenSleep() */ void enableScreenSleep() { - if (activity_mutex != NULL) { - if (xSemaphoreTake(activity_mutex, portMAX_DELAY) == pdTRUE) { + if (activity_mutex != NULL) + { + if (xSemaphoreTake(activity_mutex, portMAX_DELAY) == pdTRUE) + { screen_sleep_disabled = false; // Reset activity time to current time to prevent immediate sleep last_user_activity_time = millis(); @@ -360,8 +381,10 @@ void enableScreenSleep() bool isScreenSleepDisabled() { bool disabled = false; - if (activity_mutex != NULL) { - if (xSemaphoreTake(activity_mutex, pdMS_TO_TICKS(10)) == pdTRUE) { + if (activity_mutex != NULL) + { + if (xSemaphoreTake(activity_mutex, pdMS_TO_TICKS(10)) == pdTRUE) + { disabled = screen_sleep_disabled; xSemaphoreGive(activity_mutex); } @@ -375,15 +398,19 @@ bool isScreenSleepDisabled() */ void updateUserActivity() { - if (activity_mutex != NULL) { - if (xSemaphoreTake(activity_mutex, pdMS_TO_TICKS(10)) == pdTRUE) { + if (activity_mutex != NULL) + { + if (xSemaphoreTake(activity_mutex, pdMS_TO_TICKS(10)) == pdTRUE) + { last_user_activity_time = millis(); // If screen is sleeping, wake it up - if (screen_sleeping) { + if (screen_sleeping) + { screen_sleeping = false; instance.setBrightness(DEVICE_MAX_BRIGHTNESS_LEVEL); // Restore keyboard brightness - if (instance.hasKeyboard()) { + if (instance.hasKeyboard()) + { instance.kb.setBrightness(saved_keyboard_brightness); } } @@ -397,76 +424,90 @@ void updateUserActivity() * Monitors user activity and puts screen to sleep after 30 seconds of inactivity * Wakes up screen when user input is detected */ -static void screenSleepTask(void *pvParameters) +static void screenSleepTask(void* pvParameters) { (void)pvParameters; TickType_t last_wake_time = xTaskGetTickCount(); - const TickType_t check_interval = pdMS_TO_TICKS(1000); // Check every 1 second - - while (true) { + const TickType_t check_interval = pdMS_TO_TICKS(1000); // Check every 1 second + + while (true) + { // User activity detection is now handled by LVGL input device callbacks: // - lv_encoder_read() calls updateUserActivity() for rotary encoder // - keypad_read() calls updateUserActivity() for keyboard // No need to poll here, as it would consume input events before LVGL can process them - + // Check if screen should sleep or wake - if (activity_mutex != NULL) { - if (xSemaphoreTake(activity_mutex, pdMS_TO_TICKS(10)) == pdTRUE) { + if (activity_mutex != NULL) + { + if (xSemaphoreTake(activity_mutex, pdMS_TO_TICKS(10)) == pdTRUE) + { uint32_t current_time = millis(); uint32_t time_since_activity = current_time - last_user_activity_time; - + // Get current timeout from persistent storage (may have been changed in settings) // Read directly from preferences to ensure we have the latest value - preferences.begin("settings", true); // Read-only mode + preferences.begin("settings", true); // Read-only mode uint32_t current_timeout = preferences.getUInt("sleep_timeout", 30000); preferences.end(); - + // Ensure minimum timeout - if (current_timeout < 10000) { + if (current_timeout < 10000) + { current_timeout = 30000; } - + // Update memory variable screen_sleep_timeout_ms = current_timeout; - + // Skip sleep if screen sleep is disabled (e.g., during USB mode) - if (screen_sleep_disabled) { + if (screen_sleep_disabled) + { // If screen is sleeping but sleep is now disabled, wake it up - if (screen_sleeping) { + if (screen_sleeping) + { screen_sleeping = false; instance.setBrightness(DEVICE_MAX_BRIGHTNESS_LEVEL); // Restore keyboard brightness - if (instance.hasKeyboard()) { + if (instance.hasKeyboard()) + { instance.kb.setBrightness(saved_keyboard_brightness); } } xSemaphoreGive(activity_mutex); - } else { - // Normal sleep logic - if (!screen_sleeping && time_since_activity >= current_timeout) { - // Put screen to sleep - screen_sleeping = true; - // Save current keyboard brightness before turning off - if (instance.hasKeyboard()) { - saved_keyboard_brightness = instance.kb.getBrightness(); - instance.kb.setBrightness(0); // Turn off keyboard backlight - } - instance.setBrightness(0); // Turn off display backlight - } else if (screen_sleeping && time_since_activity < current_timeout) { - // Wake up screen (shouldn't happen here, but just in case) - screen_sleeping = false; - instance.setBrightness(DEVICE_MAX_BRIGHTNESS_LEVEL); - // Restore keyboard brightness - if (instance.hasKeyboard()) { - instance.kb.setBrightness(saved_keyboard_brightness); - } } - - xSemaphoreGive(activity_mutex); + else + { + // Normal sleep logic + if (!screen_sleeping && time_since_activity >= current_timeout) + { + // Put screen to sleep + screen_sleeping = true; + // Save current keyboard brightness before turning off + if (instance.hasKeyboard()) + { + saved_keyboard_brightness = instance.kb.getBrightness(); + instance.kb.setBrightness(0); // Turn off keyboard backlight + } + instance.setBrightness(0); // Turn off display backlight + } + else if (screen_sleeping && time_since_activity < current_timeout) + { + // Wake up screen (shouldn't happen here, but just in case) + screen_sleeping = false; + instance.setBrightness(DEVICE_MAX_BRIGHTNESS_LEVEL); + // Restore keyboard brightness + if (instance.hasKeyboard()) + { + instance.kb.setBrightness(saved_keyboard_brightness); + } + } + + xSemaphoreGive(activity_mutex); } } } - + // Wait for next check vTaskDelayUntil(&last_wake_time, check_interval); } @@ -475,7 +516,7 @@ static void screenSleepTask(void *pvParameters) void setup() { Serial.begin(115200); - delay(100); // Give Serial time to stabilize before printing logs + delay(100); // Give Serial time to stabilize before printing logs Serial.printf("\n\n[Setup] ===== SYSTEM STARTUP =====\n"); Serial.printf("[Setup] Serial initialized at 115200 baud\n"); @@ -483,27 +524,32 @@ void setup() esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause(); bool waking_from_sleep = (wakeup_reason != ESP_SLEEP_WAKEUP_UNDEFINED); - if (waking_from_sleep) { + if (waking_from_sleep) + { Serial.printf("[Setup] Wakeup cause: %d\n", wakeup_reason); } instance.begin(); // If waking from deep sleep, perform wake up initialization - if (waking_from_sleep) { + if (waking_from_sleep) + { instance.wakeUp(); } beginLvglHelper(instance); - + // Initialize system notification component ui::SystemNotification::init(); - + // Initialize chat application context app::AppContext& app_ctx = app::AppContext::getInstance(); bool use_mock = false; // Enable real LoRa adapter for logging and radio tests - if (app_ctx.init(instance, use_mock)) { + if (app_ctx.init(instance, use_mock)) + { Serial.printf("[Setup] Chat application context initialized\n"); - } else { + } + else + { Serial.printf("[Setup] WARNING: Failed to initialize chat context\n"); } @@ -539,63 +585,72 @@ void setup() /* Create time label at top left of menu */ time_label = lv_label_create(menu_panel); lv_obj_set_width(time_label, LV_SIZE_CONTENT); - lv_obj_align(time_label, LV_ALIGN_TOP_LEFT, 5, 0); // Top left, 5px from left edge + lv_obj_align(time_label, LV_ALIGN_TOP_LEFT, 5, 0); // Top left, 5px from left edge lv_obj_set_style_text_align(time_label, LV_TEXT_ALIGN_LEFT, 0); - lv_obj_set_style_text_color(time_label, lv_color_black(), 0); // Black text for better contrast + lv_obj_set_style_text_color(time_label, lv_color_black(), 0); // Black text for better contrast // Add light background to make black text visible lv_obj_set_style_bg_color(time_label, lv_color_white(), 0); - lv_obj_set_style_bg_opa(time_label, LV_OPA_80, 0); // Semi-transparent white background + lv_obj_set_style_bg_opa(time_label, LV_OPA_80, 0); // Semi-transparent white background lv_obj_set_style_pad_all(time_label, 4, 0); // Make sure time label is on top lv_obj_move_foreground(time_label); - if (lv_display_get_physical_horizontal_resolution(NULL) < 320) { + if (lv_display_get_physical_horizontal_resolution(NULL) < 320) + { lv_obj_set_style_text_font(time_label, &lv_font_montserrat_14, 0); - } else { + } + else + { lv_obj_set_style_text_font(time_label, &lv_font_montserrat_18, 0); } lv_label_set_text(time_label, "--:--"); - + /* Create battery label at top right of menu */ battery_label = lv_label_create(menu_panel); lv_obj_set_width(battery_label, LV_SIZE_CONTENT); - lv_obj_align(battery_label, LV_ALIGN_TOP_RIGHT, -5, 0); // Top right, 5px from right edge + lv_obj_align(battery_label, LV_ALIGN_TOP_RIGHT, -5, 0); // Top right, 5px from right edge lv_obj_set_style_text_align(battery_label, LV_TEXT_ALIGN_RIGHT, 0); lv_obj_set_style_text_color(battery_label, lv_color_black(), 0); // Add light background to make black text visible lv_obj_set_style_bg_color(battery_label, lv_color_white(), 0); - lv_obj_set_style_bg_opa(battery_label, LV_OPA_80, 0); // Semi-transparent white background + lv_obj_set_style_bg_opa(battery_label, LV_OPA_80, 0); // Semi-transparent white background lv_obj_set_style_pad_all(battery_label, 4, 0); // Make sure battery label is on top lv_obj_move_foreground(battery_label); - if (lv_display_get_physical_horizontal_resolution(NULL) < 320) { + if (lv_display_get_physical_horizontal_resolution(NULL) < 320) + { lv_obj_set_style_text_font(battery_label, &lv_font_montserrat_14, 0); - } else { + } + else + { lv_obj_set_style_text_font(battery_label, &lv_font_montserrat_18, 0); } lv_label_set_text(battery_label, "?%"); - + /* Initialize the menu view - moved down to make room for time */ - lv_obj_t *panel = lv_obj_create(menu_panel); + lv_obj_t* panel = lv_obj_create(menu_panel); lv_obj_set_scrollbar_mode(panel, LV_SCROLLBAR_MODE_OFF); lv_obj_set_size(panel, LV_PCT(100), LV_PCT(70)); lv_obj_set_scroll_snap_x(panel, LV_SCROLL_SNAP_CENTER); lv_obj_set_flex_flow(panel, LV_FLEX_FLOW_ROW); // Move panel down to make room for time label (adjust offset based on screen size) - int panel_offset = 30; // Offset for time label space - if (lv_display_get_physical_vertical_resolution(NULL) > 320) { - panel_offset = 35; // Slightly more space on larger screens + int panel_offset = 30; // Offset for time label space + if (lv_display_get_physical_vertical_resolution(NULL) > 320) + { + panel_offset = 35; // Slightly more space on larger screens } lv_obj_align(panel, LV_ALIGN_TOP_MID, 0, panel_offset); lv_obj_add_style(panel, &style_frameless, 0); /* Add applications */ - for (int i = 0; i < NUM_APPS; ++i) { + for (int i = 0; i < NUM_APPS; ++i) + { create_app(panel, kAppNames[i], kAppImages[i], kAppFuncs[i]); lv_group_add_obj(menu_g, lv_obj_get_child(panel, i)); } int offset = -10; - if (lv_display_get_physical_vertical_resolution(NULL) > 320) { + if (lv_display_get_physical_vertical_resolution(NULL) > 320) + { offset = -45; } /* Initialize the label */ @@ -604,10 +659,13 @@ void setup() lv_obj_align(desc_label, LV_ALIGN_BOTTOM_MID, 0, offset); lv_obj_set_style_text_align(desc_label, LV_TEXT_ALIGN_CENTER, 0); - if (lv_display_get_physical_horizontal_resolution(NULL) < 320) { + if (lv_display_get_physical_horizontal_resolution(NULL) < 320) + { lv_obj_set_style_text_font(desc_label, &lv_font_montserrat_16, 0); lv_obj_align(desc_label, LV_ALIGN_BOTTOM_MID, 0, -25); - } else { + } + else + { lv_obj_set_style_text_font(desc_label, &lv_font_montserrat_20, 0); } lv_label_set_long_mode(desc_label, LV_LABEL_LONG_SCROLL_CIRCULAR); @@ -625,9 +683,10 @@ void setup() // Create timer to update time display (minimum resource usage) // Update every 60 seconds, display format: HH:MM (no seconds) // This minimizes I2C communication and UI updates - const uint32_t time_update_interval_ms = 60000; // 60 seconds = minimum update frequency - - lv_timer_t *time_timer = lv_timer_create([](lv_timer_t *timer) { + const uint32_t time_update_interval_ms = 60000; // 60 seconds = minimum update frequency + + lv_timer_t* time_timer = lv_timer_create([](lv_timer_t* timer) + { if (time_label == nullptr) { return; } @@ -651,15 +710,16 @@ void setup() } else { // If RTC read fails, show error indicator lv_label_set_text(time_label, "??:??"); - } - }, time_update_interval_ms, NULL); - lv_timer_set_repeat_count(time_timer, -1); // Repeat indefinitely - + } }, + time_update_interval_ms, NULL); + lv_timer_set_repeat_count(time_timer, -1); // Repeat indefinitely + // Create timer to update battery display (minimum resource usage) // Update every 60 seconds (1 minute) - battery changes slowly, minimize I2C communication - const uint32_t battery_update_interval_ms = 60000; // 60 seconds = minimum update frequency - - lv_timer_t *battery_timer = lv_timer_create([](lv_timer_t *timer) { + const uint32_t battery_update_interval_ms = 60000; // 60 seconds = minimum update frequency + + lv_timer_t* battery_timer = lv_timer_create([](lv_timer_t* timer) + { if (battery_label == nullptr) { return; } @@ -683,36 +743,50 @@ void setup() lv_label_set_text(battery_label, battery_str); strncpy(last_battery_str, battery_str, sizeof(last_battery_str) - 1); last_battery_str[sizeof(last_battery_str) - 1] = '\0'; - } - }, battery_update_interval_ms, NULL); - lv_timer_set_repeat_count(battery_timer, -1); // Repeat indefinitely - + } }, + battery_update_interval_ms, NULL); + lv_timer_set_repeat_count(battery_timer, -1); // Repeat indefinitely + // Update time immediately (don't wait for first timer tick) - if (instance.isRTCReady()) { + if (instance.isRTCReady()) + { char time_str[16]; - if (instance.getRTCTimeString(time_str, sizeof(time_str), false)) { + if (instance.getRTCTimeString(time_str, sizeof(time_str), false)) + { lv_label_set_text(time_label, time_str); } } - + // Update battery immediately (don't wait for first timer tick) char battery_str[32]; bool charging = instance.isCharging(); int level = instance.getBatteryLevel(); - if (level >= 0) { + if (level >= 0) + { // Select appropriate battery symbol based on level const char* battery_symbol; - if (charging) { + if (charging) + { battery_symbol = LV_SYMBOL_CHARGE; - } else if (level >= 90) { + } + else if (level >= 90) + { battery_symbol = LV_SYMBOL_BATTERY_FULL; - } else if (level >= 60) { + } + else if (level >= 60) + { battery_symbol = LV_SYMBOL_BATTERY_3; - } else if (level >= 30) { + } + else if (level >= 30) + { battery_symbol = LV_SYMBOL_BATTERY_2; - } else if (level >= 10) { + } + else if (level >= 10) + { battery_symbol = LV_SYMBOL_BATTERY_1; - } else { + } + else + { battery_symbol = LV_SYMBOL_BATTERY_EMPTY; } snprintf(battery_str, sizeof(battery_str), "%s %d%%", battery_symbol, level); @@ -720,45 +794,52 @@ void setup() } instance.setBrightness(DEVICE_MAX_BRIGHTNESS_LEVEL); - + // GPS data collection task is now created in TLoRaPagerBoard::begin() - + // Create activity mutex for screen sleep management activity_mutex = xSemaphoreCreateMutex(); - if (activity_mutex == NULL) { + if (activity_mutex == NULL) + { log_e("Failed to create activity mutex"); - } else { + } + else + { // Initialize activity time last_user_activity_time = millis(); - + // Load screen sleep timeout from preferences preferences.begin("settings", true); - screen_sleep_timeout_ms = preferences.getUInt("sleep_timeout", 30000); // Default 30 seconds + screen_sleep_timeout_ms = preferences.getUInt("sleep_timeout", 30000); // Default 30 seconds preferences.end(); - + // Ensure minimum timeout - if (screen_sleep_timeout_ms < 10000) { + if (screen_sleep_timeout_ms < 10000) + { screen_sleep_timeout_ms = 30000; } } - + // Create screen sleep management task BaseType_t sleep_task_result = xTaskCreate( screenSleepTask, "screen_sleep", - 2 * 1024, // Stack size + 2 * 1024, // Stack size NULL, - 3, // Priority (lower than GPS task) - &screen_sleep_task_handle - ); - if (sleep_task_result != pdPASS) { + 3, // Priority (lower than GPS task) + &screen_sleep_task_handle); + if (sleep_task_result != pdPASS) + { log_e("Failed to create screen sleep task"); - } else { + } + else + { log_d("Screen sleep management task created successfully"); } // If waking from deep sleep, update user activity to prevent immediate screen sleep - if (waking_from_sleep) { + if (waking_from_sleep) + { updateUserActivity(); log_d("Updated user activity after waking from sleep"); } @@ -774,7 +855,8 @@ void loop() #ifdef ARDUINO_USB_MODE // If USB mode is active, run USB loop (like Launcher's loop() function) // This ensures USB tasks get CPU time and prevents other tasks from interfering - if (ui_usb_is_active()) { + if (ui_usb_is_active()) + { // Process LVGL for USB mode lv_timer_handler(); @@ -800,17 +882,19 @@ void loop() static uint32_t last_loop_ms = 0; static uint32_t loop_count = 0; uint32_t now_ms = millis(); - + // Record loop() call interval - if (last_loop_ms > 0) { + if (last_loop_ms > 0) + { uint32_t interval = now_ms - last_loop_ms; - if (interval > 50) { // Only log intervals > 50ms (indicating delay) + if (interval > 50) + { // Only log intervals > 50ms (indicating delay) Serial.printf("[MAIN] loop() interval: %lu ms (count=%lu)\n", interval, loop_count); } } last_loop_ms = now_ms; loop_count++; - + uint32_t t_before = millis(); #endif @@ -820,12 +904,13 @@ void loop() #if MAIN_TIMING_DEBUG uint32_t t_after = millis(); uint32_t handler_duration = t_after - t_before; - + // Log lv_timer_handler() execution time - if (handler_duration > 10) { + if (handler_duration > 10) + { Serial.printf("[MAIN] lv_timer_handler() took %lu ms\n", handler_duration); } #endif - + delay(2); } diff --git a/src/sys/event_bus.cpp b/src/sys/event_bus.cpp index 9bc460e9..e3353b2a 100644 --- a/src/sys/event_bus.cpp +++ b/src/sys/event_bus.cpp @@ -5,7 +5,8 @@ #include "event_bus.h" -namespace sys { +namespace sys +{ // Define static instance here (not in header to avoid multiple definition) EventBus EventBus::instance_; diff --git a/src/sys/event_bus.h b/src/sys/event_bus.h index b19a6215..79ad8486 100644 --- a/src/sys/event_bus.h +++ b/src/sys/event_bus.h @@ -5,34 +5,38 @@ #pragma once -#include #include "freertos/FreeRTOS.h" #include "freertos/queue.h" #include "freertos/semphr.h" +#include #include -namespace sys { +namespace sys +{ /** * @brief Event types */ -enum class EventType { +enum class EventType +{ ChatNewMessage, // New message received - ChatSendResult, // Message send result - ChatUnreadChanged, // Unread count changed - ChatChannelSwitched, // Channel switched - NodeInfoUpdate, // Node info updated (from mesh network) - InputEvent, // Input event (keyboard/rotary) + ChatSendResult, // Message send result + ChatUnreadChanged, // Unread count changed + ChatChannelSwitched, // Channel switched + NodeInfoUpdate, // Node info updated (from mesh network) + NodeProtocolUpdate, // Node protocol update (from message) + InputEvent, // Input event (keyboard/rotary) SystemTick // System tick (for periodic tasks) }; /** * @brief Base event structure */ -struct Event { +struct Event +{ EventType type; uint32_t timestamp; - + Event(EventType t) : type(t), timestamp(millis()) {} virtual ~Event() = default; }; @@ -40,17 +44,22 @@ struct Event { /** * @brief Chat new message event */ -struct ChatNewMessageEvent : public Event { +struct ChatNewMessageEvent : public Event +{ uint8_t channel; uint32_t msg_id; - char text[64]; // Message text (truncated if needed) - - ChatNewMessageEvent(uint8_t ch, uint32_t id, const char* msg_text = "") - : Event(EventType::ChatNewMessage), channel(ch), msg_id(id) { - if (msg_text) { + char text[64]; // Message text (truncated if needed) + + ChatNewMessageEvent(uint8_t ch, uint32_t id, const char* msg_text = "") + : Event(EventType::ChatNewMessage), channel(ch), msg_id(id) + { + if (msg_text) + { strncpy(text, msg_text, sizeof(text) - 1); text[sizeof(text) - 1] = '\0'; - } else { + } + else + { text[0] = '\0'; } } @@ -59,155 +68,196 @@ struct ChatNewMessageEvent : public Event { /** * @brief Chat send result event */ -struct ChatSendResultEvent : public Event { +struct ChatSendResultEvent : public Event +{ uint32_t msg_id; bool success; - - ChatSendResultEvent(uint32_t id, bool ok) + + ChatSendResultEvent(uint32_t id, bool ok) : Event(EventType::ChatSendResult), msg_id(id), success(ok) {} }; /** * @brief Chat unread changed event */ -struct ChatUnreadChangedEvent : public Event { +struct ChatUnreadChangedEvent : public Event +{ uint8_t channel; int unread_count; - - ChatUnreadChangedEvent(uint8_t ch, int count) + + ChatUnreadChangedEvent(uint8_t ch, int count) : Event(EventType::ChatUnreadChanged), channel(ch), unread_count(count) {} }; /** * @brief Node info update event */ -struct NodeInfoUpdateEvent : public Event { +struct NodeInfoUpdateEvent : public Event +{ uint32_t node_id; char short_name[10]; char long_name[32]; float snr; - uint32_t timestamp; // Unix timestamp (seconds) - - NodeInfoUpdateEvent(uint32_t id, const char* sname, const char* lname, float s, uint32_t ts) - : Event(EventType::NodeInfoUpdate), node_id(id), snr(s), timestamp(ts) { - if (sname) { + uint32_t timestamp; // Unix timestamp (seconds) + uint8_t protocol; + + NodeInfoUpdateEvent(uint32_t id, const char* sname, const char* lname, float s, uint32_t ts, uint8_t proto) + : Event(EventType::NodeInfoUpdate), node_id(id), snr(s), timestamp(ts), protocol(proto) + { + if (sname) + { strncpy(short_name, sname, sizeof(short_name) - 1); short_name[sizeof(short_name) - 1] = '\0'; - } else { + } + else + { short_name[0] = '\0'; } - if (lname) { + if (lname) + { strncpy(long_name, lname, sizeof(long_name) - 1); long_name[sizeof(long_name) - 1] = '\0'; - } else { + } + else + { long_name[0] = '\0'; } } }; +/** + * @brief Node protocol update event + */ +struct NodeProtocolUpdateEvent : public Event +{ + uint32_t node_id; + uint32_t timestamp; // Unix timestamp (seconds) + uint8_t protocol; + + NodeProtocolUpdateEvent(uint32_t id, uint32_t ts, uint8_t proto) + : Event(EventType::NodeProtocolUpdate), node_id(id), timestamp(ts), protocol(proto) {} +}; + /** * @brief Input event */ -struct InputEvent { - enum InputType { +struct InputEvent +{ + enum InputType + { KeyPress, KeyRelease, RotaryTurn, RotaryPress, RotaryLongPress }; - + InputType input_type; - uint32_t value; // Key code or rotary delta + uint32_t value; // Key code or rotary delta uint32_t timestamp; - - InputEvent(InputType it, uint32_t v) + + InputEvent(InputType it, uint32_t v) : input_type(it), value(v), timestamp(millis()) {} }; /** * @brief Event bus for inter-task communication */ -class EventBus { -public: +class EventBus +{ + public: /** * @brief Initialize event bus * @param queue_size Maximum queue size * @return true if successful */ - static bool init(size_t queue_size = 32) { - if (instance_.queue_ != nullptr) { + static bool init(size_t queue_size = 32) + { + if (instance_.queue_ != nullptr) + { return true; // Already initialized } instance_.queue_ = xQueueCreate(queue_size, sizeof(Event*)); return instance_.queue_ != nullptr; } - + /** * @brief Publish an event * @param event Event to publish (will be copied) * @param timeout_ms Timeout in milliseconds * @return true if successful */ - static bool publish(Event* event, uint32_t timeout_ms = portMAX_DELAY) { - if (instance_.queue_ == nullptr) { + static bool publish(Event* event, uint32_t timeout_ms = portMAX_DELAY) + { + if (instance_.queue_ == nullptr) + { delete event; return false; } - - BaseType_t result = xQueueSend(instance_.queue_, &event, + + BaseType_t result = xQueueSend(instance_.queue_, &event, pdMS_TO_TICKS(timeout_ms)); - if (result != pdPASS) { + if (result != pdPASS) + { delete event; return false; } return true; } - + /** * @brief Subscribe to events (receive next event) * @param event_out Pointer to receive event pointer * @param timeout_ms Timeout in milliseconds * @return true if event received */ - static bool subscribe(Event** event_out, uint32_t timeout_ms = portMAX_DELAY) { - if (instance_.queue_ == nullptr) { + static bool subscribe(Event** event_out, uint32_t timeout_ms = portMAX_DELAY) + { + if (instance_.queue_ == nullptr) + { return false; } - return xQueueReceive(instance_.queue_, event_out, - pdMS_TO_TICKS(timeout_ms)) == pdPASS; + return xQueueReceive(instance_.queue_, event_out, + pdMS_TO_TICKS(timeout_ms)) == pdPASS; } - + /** * @brief Get number of pending events */ - static size_t pendingCount() { - if (instance_.queue_ == nullptr) { + static size_t pendingCount() + { + if (instance_.queue_ == nullptr) + { return 0; } return uxQueueMessagesWaiting(instance_.queue_); } - + /** * @brief Clear all pending events */ - static void clear() { - if (instance_.queue_ == nullptr) { + static void clear() + { + if (instance_.queue_ == nullptr) + { return; } Event* event; - while (xQueueReceive(instance_.queue_, &event, 0) == pdPASS) { + while (xQueueReceive(instance_.queue_, &event, 0) == pdPASS) + { delete event; } } -private: + private: QueueHandle_t queue_; - static EventBus instance_; // Declaration only - + static EventBus instance_; // Declaration only + EventBus() : queue_(nullptr) {} - ~EventBus() { - if (queue_ != nullptr) { + ~EventBus() + { + if (queue_ != nullptr) + { clear(); vQueueDelete(queue_); } diff --git a/src/sys/ringbuf.h b/src/sys/ringbuf.h index 31a29008..93796bc4 100644 --- a/src/sys/ringbuf.h +++ b/src/sys/ringbuf.h @@ -8,27 +8,32 @@ #include #include -namespace sys { +namespace sys +{ /** * @brief Fixed-size ring buffer * @tparam T Element type * @tparam N Buffer size */ -template -class RingBuffer { -public: - RingBuffer() : head_(0), tail_(0), count_(0) { +template +class RingBuffer +{ + public: + RingBuffer() : head_(0), tail_(0), count_(0) + { static_assert(N > 0, "RingBuffer size must be > 0"); } - + /** * @brief Append an element to the buffer * @param item Item to append * @return true if successful, false if buffer is full */ - bool append(const T& item) { - if (count_ >= N) { + bool append(const T& item) + { + if (count_ >= N) + { // Buffer full, overwrite oldest tail_ = (tail_ + 1) % N; count_--; @@ -38,79 +43,89 @@ public: count_++; return true; } - + /** * @brief Get element at index (0 = oldest, count-1 = newest) * @param index Index * @return Pointer to element, or nullptr if index out of range */ - const T* get(size_t index) const { - if (index >= count_) { + const T* get(size_t index) const + { + if (index >= count_) + { return nullptr; } size_t pos = (tail_ + index) % N; return &buffer_[pos]; } - + /** * @brief Get the newest element * @return Pointer to newest element, or nullptr if empty */ - const T* getNewest() const { - if (count_ == 0) { + const T* getNewest() const + { + if (count_ == 0) + { return nullptr; } size_t pos = (head_ + N - 1) % N; return &buffer_[pos]; } - + /** * @brief Get number of elements in buffer */ - size_t count() const { + size_t count() const + { return count_; } - + /** * @brief Check if buffer is full */ - bool isFull() const { + bool isFull() const + { return count_ >= N; } - + /** * @brief Check if buffer is empty */ - bool isEmpty() const { + bool isEmpty() const + { return count_ == 0; } - + /** * @brief Clear the buffer */ - void clear() { + void clear() + { head_ = 0; tail_ = 0; count_ = 0; } - + /** * @brief Get all elements as a vector (for iteration) * Note: This creates a copy, use with caution on memory-constrained systems */ - void getAll(T* out, size_t max_count) const { + void getAll(T* out, size_t max_count) const + { size_t copy_count = (max_count < count_) ? max_count : count_; - for (size_t i = 0; i < copy_count; i++) { + for (size_t i = 0; i < copy_count; i++) + { size_t pos = (tail_ + i) % N; out[i] = buffer_[pos]; } } -private: + private: T buffer_[N]; - size_t head_; // Next write position - size_t tail_; // Oldest element position - size_t count_; // Current element count + size_t head_; // Next write position + size_t tail_; // Oldest element position + size_t count_; // Current element count }; } // namespace sys diff --git a/src/ui/LV_Helper.h b/src/ui/LV_Helper.h index 53f5fe02..280e0008 100644 --- a/src/ui/LV_Helper.h +++ b/src/ui/LV_Helper.h @@ -8,10 +8,10 @@ #warning "Lvgl fs mismatch, may not be able to use fs function" #endif -void beginLvglHelper(LilyGo_Display &display, bool debug = false); +void beginLvglHelper(LilyGo_Display& display, bool debug = false); void updateLvglHelper(); -void lv_set_default_group(lv_group_t *group); -lv_indev_t *lv_get_touch_indev(); -lv_indev_t *lv_get_keyboard_indev(); -lv_indev_t *lv_get_encoder_indev(); +void lv_set_default_group(lv_group_t* group); +lv_indev_t* lv_get_touch_indev(); +lv_indev_t* lv_get_keyboard_indev(); +lv_indev_t* lv_get_encoder_indev(); diff --git a/src/ui/LV_Helper_v9.cpp b/src/ui/LV_Helper_v9.cpp index 4c8c6851..608fe8f0 100644 --- a/src/ui/LV_Helper_v9.cpp +++ b/src/ui/LV_Helper_v9.cpp @@ -1,53 +1,54 @@ /** * @file LV_Helper_v9.cpp * @brief LVGL v9.x helper functions for T-LoRa-Pager - * + * * This file provides LVGL initialization and integration functions, * including display driver setup, input device registration, and * custom memory management for LVGL v9.x. */ -#include #include "ui/LV_Helper.h" +#include #if LVGL_VERSION_MAJOR == 9 -static lv_display_t *disp_drv; +static lv_display_t* disp_drv; static lv_draw_buf_t draw_buf; -static lv_indev_t *indev_touch; -static lv_indev_t *indev_encoder; -static lv_indev_t *indev_keyboard; +static lv_indev_t* indev_touch; +static lv_indev_t* indev_encoder; +static lv_indev_t* indev_keyboard; -static lv_color16_t *buf = nullptr; -static lv_color16_t *buf1 = nullptr; +static lv_color16_t* buf = nullptr; +static lv_color16_t* buf1 = nullptr; #if defined(ARDUINO_T_LORA_PAGER) #define _SWAP_COLORS #endif -static void disp_flush(lv_display_t *disp_drv, const lv_area_t *area, uint8_t *color_p) +static void disp_flush(lv_display_t* disp_drv, const lv_area_t* area, uint8_t* color_p) { size_t len = lv_area_get_size(area); uint32_t w = lv_area_get_width(area); uint32_t h = lv_area_get_height(area); - auto *plane = (LilyGo_Display *)lv_display_get_user_data(disp_drv); + auto* plane = (LilyGo_Display*)lv_display_get_user_data(disp_drv); #ifdef _SWAP_COLORS lv_draw_sw_rgb565_swap(color_p, len); #endif - plane->pushColors(area->x1, area->y1, w, h, (uint16_t *)color_p); - + plane->pushColors(area->x1, area->y1, w, h, (uint16_t*)color_p); + lv_display_flush_ready(disp_drv); } #ifdef USING_INPUT_DEV_TOUCHPAD -static void touchpad_read(lv_indev_t *drv, lv_indev_data_t *data) +static void touchpad_read(lv_indev_t* drv, lv_indev_data_t* data) { static int16_t x, y; - auto *plane = (LilyGo_Display *)lv_indev_get_user_data(drv); + auto* plane = (LilyGo_Display*)lv_indev_get_user_data(drv); uint8_t touched = plane->getPoint(&x, &y, 1); - if (touched) { + if (touched) + { data->point.x = x; data->point.y = y; data->state = LV_INDEV_STATE_PR; @@ -64,34 +65,39 @@ extern void updateUserActivity(); // Forward declaration from ui_gps.cpp extern bool isGPSLoadingTiles(); -static void lv_encoder_read(lv_indev_t *drv, lv_indev_data_t *data) +static void lv_encoder_read(lv_indev_t* drv, lv_indev_data_t* data) { - auto *plane = (LilyGo_Display *)lv_indev_get_user_data(drv); + auto* plane = (LilyGo_Display*)lv_indev_get_user_data(drv); RotaryMsg_t msg = plane->getRotary(); - + // If screen is sleeping, only wake it up, don't pass input to UI - if (isScreenSleeping()) { - if (msg.dir != ROTARY_DIR_NONE || msg.centerBtnPressed) { - updateUserActivity(); // Wake up screen + if (isScreenSleeping()) + { + if (msg.dir != ROTARY_DIR_NONE || msg.centerBtnPressed) + { + updateUserActivity(); // Wake up screen } data->enc_diff = 0; - data->state = LV_INDEV_STATE_RELEASED; // Don't pass input to UI + data->state = LV_INDEV_STATE_RELEASED; // Don't pass input to UI return; } - + // If GPS is loading tiles, ignore input - if (isGPSLoadingTiles()) { + if (isGPSLoadingTiles()) + { data->enc_diff = 0; data->state = LV_INDEV_STATE_RELEASED; return; } - + // Screen is awake, process input normally - if (msg.dir != ROTARY_DIR_NONE || msg.centerBtnPressed) { - updateUserActivity(); // Update activity timestamp + if (msg.dir != ROTARY_DIR_NONE || msg.centerBtnPressed) + { + updateUserActivity(); // Update activity timestamp } - - switch (msg.dir) { + + switch (msg.dir) + { case ROTARY_DIR_UP: data->enc_diff = 1; break; @@ -102,10 +108,11 @@ static void lv_encoder_read(lv_indev_t *drv, lv_indev_data_t *data) data->state = LV_INDEV_STATE_RELEASED; break; } - if (msg.centerBtnPressed) { + if (msg.centerBtnPressed) + { data->state = LV_INDEV_STATE_PRESSED; } - plane->feedback((void *)drv); + plane->feedback((void*)drv); } #endif @@ -114,27 +121,30 @@ static void lv_encoder_read(lv_indev_t *drv, lv_indev_data_t *data) extern bool isScreenSleeping(); extern void updateUserActivity(); -static void keypad_read(lv_indev_t *drv, lv_indev_data_t *data) +static void keypad_read(lv_indev_t* drv, lv_indev_data_t* data) { char c = '\0'; - auto *plane = (LilyGo_Display *)lv_indev_get_user_data(drv); + auto* plane = (LilyGo_Display*)lv_indev_get_user_data(drv); int state = plane->getKeyChar(&c); - + // If screen is sleeping, only wake it up, don't pass input to UI - if (isScreenSleeping()) { - if (state == KEYBOARD_PRESSED) { - updateUserActivity(); // Wake up screen + if (isScreenSleeping()) + { + if (state == KEYBOARD_PRESSED) + { + updateUserActivity(); // Wake up screen } - data->state = LV_INDEV_STATE_REL; // Don't pass key to UI + data->state = LV_INDEV_STATE_REL; // Don't pass key to UI return; } - + // Screen is awake, process input normally - if (state == KEYBOARD_PRESSED) { - updateUserActivity(); // Update activity timestamp + if (state == KEYBOARD_PRESSED) + { + updateUserActivity(); // Update activity timestamp data->key = c; data->state = LV_INDEV_STATE_PR; - plane->feedback((void *)drv); + plane->feedback((void*)drv); return; } data->state = LV_INDEV_STATE_REL; @@ -146,9 +156,9 @@ static uint32_t lv_tick_get_callback(void) return millis(); } -static void lv_rounder_cb(lv_event_t *e) +static void lv_rounder_cb(lv_event_t* e) { - lv_area_t *area = (lv_area_t *)lv_event_get_param(e); + lv_area_t* area = (lv_area_t*)lv_event_get_param(e); if (!(area->x2 & 1)) area->x2++; if (area->y1 & 1) @@ -157,13 +167,13 @@ static void lv_rounder_cb(lv_event_t *e) area->y2++; } -static void lv_res_changed_cb(lv_event_t *e) +static void lv_res_changed_cb(lv_event_t* e) { - auto *plane = (LilyGo_Display *)lv_event_get_user_data(e); + auto* plane = (LilyGo_Display*)lv_event_get_user_data(e); plane->setRotation(lv_display_get_rotation(NULL)); } -void beginLvglHelper(LilyGo_Display &board, bool debug) +void beginLvglHelper(LilyGo_Display& board, bool debug) { #ifdef _SWAP_COLORS log_d("Using color swap function"); @@ -172,7 +182,8 @@ void beginLvglHelper(LilyGo_Display &board, bool debug) lv_init(); #if LV_USE_LOG - if (debug) { + if (debug) + { lv_log_register_print_cb(lv_log_print_g_cb); } #endif @@ -182,29 +193,36 @@ void beginLvglHelper(LilyGo_Display &board, bool debug) bool useDMA = board.useDMA(); size_t lv_buffer_size = board.width() * board.height() * sizeof(lv_color16_t); - if (useDMA) { + if (useDMA) + { // For DMA, use smaller buffer (1/6 of screen size) and DMA-capable memory lv_buffer_size = (board.width() * board.height() / 6) * sizeof(lv_color16_t); - buf = (lv_color16_t *)heap_caps_malloc(lv_buffer_size, MALLOC_CAP_DMA); - buf1 = (lv_color16_t *)heap_caps_malloc(lv_buffer_size, MALLOC_CAP_DMA); + buf = (lv_color16_t*)heap_caps_malloc(lv_buffer_size, MALLOC_CAP_DMA); + buf1 = (lv_color16_t*)heap_caps_malloc(lv_buffer_size, MALLOC_CAP_DMA); log_d("Using DMA buffers, size: %d bytes each", lv_buffer_size); - } else { + } + else + { // For non-DMA, use full screen buffer in PSRAM - buf = (lv_color16_t *)ps_malloc(lv_buffer_size); - buf1 = (lv_color16_t *)ps_malloc(lv_buffer_size); + buf = (lv_color16_t*)ps_malloc(lv_buffer_size); + buf1 = (lv_color16_t*)ps_malloc(lv_buffer_size); log_d("Using PSRAM buffers, size: %d bytes each", lv_buffer_size); } - - if (!buf || !buf1) { + + if (!buf || !buf1) + { log_e("Failed to allocate LVGL display buffers!"); return; } disp_drv = lv_display_create(board.width(), board.height()); - if (board.needFullRefresh()) { + if (board.needFullRefresh()) + { lv_display_set_buffers(disp_drv, buf, buf1, lv_buffer_size, LV_DISPLAY_RENDER_MODE_FULL); - } else { + } + else + { lv_display_set_buffers(disp_drv, buf, buf1, lv_buffer_size, LV_DISPLAY_RENDER_MODE_PARTIAL); lv_display_add_event_cb(disp_drv, lv_rounder_cb, LV_EVENT_INVALIDATE_AREA, NULL); } @@ -217,7 +235,8 @@ void beginLvglHelper(LilyGo_Display &board, bool debug) lv_display_add_event_cb(disp_drv, lv_res_changed_cb, LV_EVENT_RESOLUTION_CHANGED, &board); #ifdef USING_INPUT_DEV_TOUCHPAD - if (board.hasTouch()) { + if (board.hasTouch()) + { indev_touch = lv_indev_create(); lv_indev_set_type(indev_touch, LV_INDEV_TYPE_POINTER); lv_indev_set_read_cb(indev_touch, touchpad_read); @@ -229,7 +248,8 @@ void beginLvglHelper(LilyGo_Display &board, bool debug) #endif #ifdef USING_INPUT_DEV_ROTARY - if (board.hasEncoder()) { + if (board.hasEncoder()) + { indev_encoder = lv_indev_create(); lv_indev_set_type(indev_encoder, LV_INDEV_TYPE_ENCODER); lv_indev_set_read_cb(indev_encoder, lv_encoder_read); @@ -241,7 +261,8 @@ void beginLvglHelper(LilyGo_Display &board, bool debug) #endif #ifdef USING_INPUT_DEV_KEYBOARD - if (board.hasKeyboard()) { + if (board.hasKeyboard()) + { indev_keyboard = lv_indev_create(); lv_indev_set_type(indev_keyboard, LV_INDEV_TYPE_KEYPAD); lv_indev_set_read_cb(indev_keyboard, keypad_read); @@ -256,38 +277,43 @@ void beginLvglHelper(LilyGo_Display &board, bool debug) lv_group_set_default(lv_group_create()); } -void lv_set_default_group(lv_group_t *group) +void lv_set_default_group(lv_group_t* group) { - lv_indev_t *cur_drv = NULL; - for (;;) { + lv_indev_t* cur_drv = NULL; + for (;;) + { cur_drv = lv_indev_get_next(cur_drv); - if (!cur_drv) { + if (!cur_drv) + { break; } - if (lv_indev_get_type(cur_drv) == LV_INDEV_TYPE_KEYPAD) { + if (lv_indev_get_type(cur_drv) == LV_INDEV_TYPE_KEYPAD) + { lv_indev_set_group(cur_drv, group); } - if (lv_indev_get_type(cur_drv) == LV_INDEV_TYPE_ENCODER) { + if (lv_indev_get_type(cur_drv) == LV_INDEV_TYPE_ENCODER) + { lv_indev_set_group(cur_drv, group); } - if (lv_indev_get_type(cur_drv) == LV_INDEV_TYPE_POINTER) { + if (lv_indev_get_type(cur_drv) == LV_INDEV_TYPE_POINTER) + { lv_indev_set_group(cur_drv, group); } } lv_group_set_default(group); } -lv_indev_t *lv_get_touch_indev() +lv_indev_t* lv_get_touch_indev() { return indev_touch; } -lv_indev_t *lv_get_keyboard_indev() +lv_indev_t* lv_get_keyboard_indev() { return indev_keyboard; } -lv_indev_t *lv_get_encoder_indev() +lv_indev_t* lv_get_encoder_indev() { return indev_encoder; } @@ -304,7 +330,7 @@ extern "C" void lv_mem_deinit(void) return; /*Nothing to deinit*/ } -extern "C" lv_mem_pool_t lv_mem_add_pool(void *mem, size_t bytes) +extern "C" lv_mem_pool_t lv_mem_add_pool(void* mem, size_t bytes) { /*Not supported*/ LV_UNUSED(mem); @@ -319,22 +345,22 @@ extern "C" void lv_mem_remove_pool(lv_mem_pool_t pool) return; } -extern "C" void *lv_malloc_core(size_t size) +extern "C" void* lv_malloc_core(size_t size) { return ps_malloc(size); } -extern "C" void *lv_realloc_core(void *p, size_t new_size) +extern "C" void* lv_realloc_core(void* p, size_t new_size) { return ps_realloc(p, new_size); } -extern "C" void lv_free_core(void *p) +extern "C" void lv_free_core(void* p) { free(p); } -extern "C" void lv_mem_monitor_core(lv_mem_monitor_t *mon_p) +extern "C" void lv_mem_monitor_core(lv_mem_monitor_t* mon_p) { /*Not supported*/ LV_UNUSED(mon_p); diff --git a/src/ui/assets/Chat.c b/src/ui/assets/Chat.c index 14bd053d..9c4cf57c 100644 --- a/src/ui/assets/Chat.c +++ b/src/ui/assets/Chat.c @@ -1,18 +1,17 @@ #ifdef __has_include - #if __has_include("lvgl.h") - #ifndef LV_LVGL_H_INCLUDE_SIMPLE - #define LV_LVGL_H_INCLUDE_SIMPLE - #endif - #endif +#if __has_include("lvgl.h") +#ifndef LV_LVGL_H_INCLUDE_SIMPLE +#define LV_LVGL_H_INCLUDE_SIMPLE +#endif +#endif #endif #if defined(LV_LVGL_H_INCLUDE_SIMPLE) - #include "lvgl.h" +#include "lvgl.h" #else - #include "lvgl/lvgl.h" +#include "lvgl/lvgl.h" #endif - #ifndef LV_ATTRIBUTE_MEM_ALIGN #define LV_ATTRIBUTE_MEM_ALIGN #endif @@ -22,144 +21,12304 @@ #endif const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMAGE_CHAT uint8_t Chat_map[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x28, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0x43, 0x6a, 0x44, 0x93, 0x44, 0x93, 0x45, 0xb4, 0x45, 0xb4, 0x44, 0x93, 0x43, 0x6a, 0x43, 0x6a, 0x62, 0x41, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x28, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x28, 0xa2, 0x20, 0xa2, 0x20, 0x62, 0x41, 0x44, 0x93, 0xa7, 0xed, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0xa7, 0xed, 0x45, 0xb4, 0x43, 0x6a, 0x62, 0x41, 0xa2, 0x20, 0xa2, 0x20, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x28, 0xa2, 0x20, 0xa2, 0x20, 0x44, 0x93, 0xa7, 0xed, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x44, 0x93, 0x62, 0x41, 0xa2, 0x20, 0xa2, 0x20, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0xa2, 0x20, 0x43, 0x6a, 0xa7, 0xed, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x06, 0xd5, 0x62, 0x41, 0xa2, 0x20, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0xa2, 0x20, 0xa7, 0xed, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x62, 0x41, 0xa2, 0x20, 0xa2, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x20, 0xa2, 0x20, 0x43, 0x6a, 0xa7, 0xed, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x45, 0xb4, 0xa2, 0x20, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0x43, 0x62, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x45, 0xb4, 0xa2, 0x20, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0x62, 0x41, 0xc7, 0xf5, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x45, 0xb4, 0xa2, 0x20, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0x62, 0x41, 0x87, 0xed, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x45, 0xb4, 0xa2, 0x20, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x20, 0xa2, 0x20, 0xe6, 0xcc, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x62, 0x41, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0x23, 0x62, 0x87, 0xed, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0xa7, 0xed, 0xa2, 0x20, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0xa2, 0x20, 0x26, 0xd5, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x44, 0x93, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0xc5, 0xa3, 0x46, 0xdd, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0xa7, 0xed, 0xa2, 0x20, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x20, 0xa2, 0x20, 0xc6, 0xcc, 0x87, 0xed, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x62, 0x41, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0x62, 0x41, 0x06, 0xd5, 0xe7, 0xfd, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x45, 0xb4, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0xc5, 0xa3, 0x06, 0xd5, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0xa7, 0xed, 0xa2, 0x20, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0xc5, 0xa3, 0x26, 0xd5, 0x07, 0xfe, 0x07, 0xfe, 0xa7, 0xed, 0x67, 0xe5, 0x67, 0xe5, 0x46, 0xdd, 0x26, 0xd5, 0x26, 0xd5, 0x46, 0xdd, 0x46, 0xdd, 0x87, 0xed, 0xc7, 0xf5, 0xe7, 0xfd, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0xa2, 0x20, 0xa2, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0xc6, 0xcc, 0x06, 0xd5, 0x46, 0xdd, 0x06, 0xd5, 0x06, 0xd5, 0x06, 0xd5, 0xe6, 0xd4, 0xe6, 0xd4, 0xe6, 0xd4, 0x06, 0xd5, 0x06, 0xd5, 0x06, 0xd5, 0x06, 0xd5, 0x06, 0xd5, 0x06, 0xd5, 0x46, 0xdd, 0xc7, 0xf5, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x62, 0x41, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x20, 0xa2, 0x20, 0xc6, 0xcc, 0x65, 0xbc, 0x04, 0x8b, 0x62, 0x41, 0x62, 0x41, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0x62, 0x41, 0x23, 0x62, 0xc6, 0xcc, 0xe6, 0xd4, 0x06, 0xd5, 0x06, 0xd5, 0x06, 0xd5, 0x46, 0xdd, 0xc7, 0xf5, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x43, 0x6a, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x20, 0xa2, 0x20, 0x62, 0x41, 0xa2, 0x20, 0x24, 0x49, 0xca, 0xba, 0x4b, 0xdb, 0x6c, 0xeb, 0x8c, 0xeb, 0x8c, 0xeb, 0x6c, 0xeb, 0x4c, 0xe3, 0x0b, 0xcb, 0xe6, 0x81, 0xa2, 0x20, 0xa2, 0x20, 0x23, 0x62, 0xe6, 0xd4, 0x06, 0xd5, 0x06, 0xd5, 0x06, 0xd5, 0x87, 0xed, 0xe7, 0xfd, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x43, 0x6a, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x28, 0xa2, 0x20, 0x03, 0x41, 0xca, 0xba, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x6c, 0xeb, 0xe6, 0x81, 0xa2, 0x20, 0x23, 0x62, 0xe6, 0xd4, 0x06, 0xd5, 0x06, 0xd5, 0x46, 0xdd, 0xe7, 0xfd, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x43, 0x6a, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0x03, 0x41, 0xca, 0xba, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x6c, 0xeb, 0x85, 0x61, 0xa2, 0x20, 0x65, 0xbc, 0x06, 0xd5, 0x06, 0xd5, 0x26, 0xd5, 0xe7, 0xfd, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0xa2, 0x20, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x20, 0xa2, 0x20, 0x03, 0x49, 0x8c, 0xeb, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x89, 0xaa, 0xa2, 0x20, 0xc5, 0xa3, 0x06, 0xd5, 0x06, 0xd5, 0x46, 0xdd, 0xe7, 0xfd, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0xa2, 0x20, 0xa2, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x20, 0xa2, 0x20, 0x85, 0x61, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x6c, 0xe3, 0xa2, 0x20, 0xc5, 0xa3, 0x06, 0xd5, 0x06, 0xd5, 0x87, 0xed, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0x85, 0x61, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0xea, 0xc2, 0xa2, 0x20, 0xc5, 0xa3, 0x06, 0xd5, 0x06, 0xd5, 0xe7, 0xfd, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x45, 0xb4, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0x03, 0x41, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0xd6, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xfd, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0xea, 0xc2, 0xa2, 0x20, 0xe6, 0xd4, 0x06, 0xd5, 0x46, 0xdd, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0xa2, 0x20, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x20, 0xa2, 0x20, 0x4c, 0xe3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x65, 0x59, 0xc5, 0xa3, 0x06, 0xd5, 0x06, 0xd5, 0xe7, 0xfd, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0xe6, 0x81, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x4c, 0xe3, 0xa2, 0x20, 0xe6, 0xd4, 0x06, 0xd5, 0x87, 0xed, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0xa2, 0x20, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x20, 0xa2, 0x20, 0x4c, 0xe3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0x2f, 0xf4, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x65, 0x59, 0xc5, 0xa3, 0x06, 0xd5, 0x46, 0xdd, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x62, 0x41, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0xa2, 0x20, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0xd6, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3c, 0xff, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0xea, 0xc2, 0x23, 0x62, 0x06, 0xd5, 0x06, 0xd5, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x45, 0xb4, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0x48, 0x92, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x6c, 0xeb, 0xa2, 0x20, 0xe6, 0xd4, 0x06, 0xd5, 0xe7, 0xfd, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0xa7, 0xed, 0xa2, 0x20, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0xea, 0xc2, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0xa2, 0x20, 0xc6, 0xcc, 0x06, 0xd5, 0xe7, 0xfd, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x62, 0x41, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0x0b, 0xcb, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0xf2, 0xf4, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x50, 0xf4, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x03, 0x41, 0x65, 0xbc, 0x06, 0xd5, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x44, 0x93, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0x4c, 0xe3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0xd6, 0xfd, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0xf2, 0xf4, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x03, 0x41, 0x65, 0xbc, 0x26, 0xd5, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0xc7, 0xf5, 0x67, 0xe5, 0x87, 0xed, 0xc7, 0xf5, 0xe7, 0xfd, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x06, 0xd5, 0xa2, 0x20, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0x0b, 0xcb, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0xa2, 0x20, 0xc6, 0xcc, 0x67, 0xe5, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0x07, 0xfe, 0xa7, 0xed, 0x46, 0xdd, 0x06, 0xd5, 0x06, 0xd5, 0x06, 0xd5, 0x06, 0xd5, 0x06, 0xd5, 0x46, 0xdd, 0x87, 0xed, 0xc7, 0xf5, 0xe7, 0xfd, 0x07, 0xfe, 0x62, 0x41, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0x89, 0xaa, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0xa2, 0x20, 0x06, 0xd5, 0x87, 0xed, 0x07, 0xfe, 0x07, 0xfe, 0xa7, 0xed, 0x67, 0xe5, 0x26, 0xd5, 0x65, 0xbc, 0x23, 0x62, 0x23, 0x62, 0xc5, 0xa3, 0xc6, 0xcc, 0xe6, 0xd4, 0x06, 0xd5, 0x06, 0xd5, 0x06, 0xd5, 0x06, 0xd5, 0x06, 0xd5, 0x06, 0xd5, 0x23, 0x62, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0xa5, 0x69, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0xd6, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x58, 0xfe, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x6c, 0xe3, 0x62, 0x41, 0x06, 0xd5, 0x46, 0xdd, 0x26, 0xd5, 0x06, 0xd5, 0x06, 0xd5, 0x65, 0xbc, 0x62, 0x41, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0x23, 0x62, 0xc5, 0xa3, 0xc6, 0xcc, 0xe6, 0xd4, 0x06, 0xd5, 0x65, 0xbc, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x28, 0x03, 0x41, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x2f, 0xf4, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd2, 0xf4, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x48, 0x92, 0x23, 0x62, 0xe6, 0xd4, 0x65, 0xbc, 0x04, 0x8b, 0x62, 0x41, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x28, 0xa2, 0x28, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0x23, 0x62, 0x23, 0x62, 0xa2, 0x20, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0x4b, 0xdb, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x28, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0xea, 0xc2, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0xf2, 0xf4, 0x2f, 0xf4, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x89, 0xaa, 0xa2, 0x20, 0xa2, 0x28, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x20, 0xa2, 0x20, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0xd6, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0xfe, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xeb, 0xa2, 0x20, 0xa2, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0xe6, 0x79, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x85, 0x61, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0xea, 0xc2, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x85, 0x61, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x20, 0xa2, 0x20, 0x8c, 0xeb, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x85, 0x61, 0xa2, 0x20, 0xa2, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0xa2, 0x20, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x6c, 0xeb, 0x03, 0x41, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0x48, 0x92, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x6c, 0xe3, 0xca, 0xba, 0xa5, 0x69, 0x03, 0x49, 0x0b, 0xcb, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xeb, 0x68, 0xa2, 0xa2, 0x20, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x20, 0xa2, 0x20, 0x2b, 0xd3, 0x0b, 0xcb, 0x68, 0xa2, 0x65, 0x59, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0x03, 0x41, 0x89, 0xaa, 0x6c, 0xeb, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x8c, 0xf3, 0x0b, 0xcb, 0x68, 0xa2, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0x03, 0x41, 0x03, 0x49, 0x85, 0x61, 0x48, 0x92, 0x89, 0xaa, 0x68, 0xa2, 0xa5, 0x69, 0x65, 0x59, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x20, 0xa2, 0x20, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x28, 0xa2, 0x28, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0xa2, 0x20, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x28, + 0x82, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x43, + 0x6a, + 0x44, + 0x93, + 0x44, + 0x93, + 0x45, + 0xb4, + 0x45, + 0xb4, + 0x44, + 0x93, + 0x43, + 0x6a, + 0x43, + 0x6a, + 0x62, + 0x41, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x28, + 0x82, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x28, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x62, + 0x41, + 0x44, + 0x93, + 0xa7, + 0xed, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0xa7, + 0xed, + 0x45, + 0xb4, + 0x43, + 0x6a, + 0x62, + 0x41, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x82, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x28, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x44, + 0x93, + 0xa7, + 0xed, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x44, + 0x93, + 0x62, + 0x41, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x82, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x43, + 0x6a, + 0xa7, + 0xed, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x06, + 0xd5, + 0x62, + 0x41, + 0xa2, + 0x20, + 0x82, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa7, + 0xed, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x62, + 0x41, + 0xa2, + 0x20, + 0xa2, + 0x28, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0x20, + 0xa2, + 0x20, + 0x43, + 0x6a, + 0xa7, + 0xed, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x45, + 0xb4, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0x43, + 0x62, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x45, + 0xb4, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0x62, + 0x41, + 0xc7, + 0xf5, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x45, + 0xb4, + 0xa2, + 0x20, + 0x82, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0x62, + 0x41, + 0x87, + 0xed, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x45, + 0xb4, + 0xa2, + 0x20, + 0x82, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0x20, + 0xa2, + 0x20, + 0xe6, + 0xcc, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x62, + 0x41, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0x23, + 0x62, + 0x87, + 0xed, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0xa7, + 0xed, + 0xa2, + 0x20, + 0x82, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x26, + 0xd5, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x44, + 0x93, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0xc5, + 0xa3, + 0x46, + 0xdd, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0xa7, + 0xed, + 0xa2, + 0x20, + 0x82, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0x20, + 0xa2, + 0x20, + 0xc6, + 0xcc, + 0x87, + 0xed, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x62, + 0x41, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0x62, + 0x41, + 0x06, + 0xd5, + 0xe7, + 0xfd, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x45, + 0xb4, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0xc5, + 0xa3, + 0x06, + 0xd5, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0xa7, + 0xed, + 0xa2, + 0x20, + 0x82, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0xc5, + 0xa3, + 0x26, + 0xd5, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0xa7, + 0xed, + 0x67, + 0xe5, + 0x67, + 0xe5, + 0x46, + 0xdd, + 0x26, + 0xd5, + 0x26, + 0xd5, + 0x46, + 0xdd, + 0x46, + 0xdd, + 0x87, + 0xed, + 0xc7, + 0xf5, + 0xe7, + 0xfd, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0xa2, + 0x20, + 0xa2, + 0x28, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0xc6, + 0xcc, + 0x06, + 0xd5, + 0x46, + 0xdd, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0xe6, + 0xd4, + 0xe6, + 0xd4, + 0xe6, + 0xd4, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x46, + 0xdd, + 0xc7, + 0xf5, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x62, + 0x41, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0x20, + 0xa2, + 0x20, + 0xc6, + 0xcc, + 0x65, + 0xbc, + 0x04, + 0x8b, + 0x62, + 0x41, + 0x62, + 0x41, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x62, + 0x41, + 0x23, + 0x62, + 0xc6, + 0xcc, + 0xe6, + 0xd4, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x46, + 0xdd, + 0xc7, + 0xf5, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x43, + 0x6a, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0x20, + 0xa2, + 0x20, + 0x62, + 0x41, + 0xa2, + 0x20, + 0x24, + 0x49, + 0xca, + 0xba, + 0x4b, + 0xdb, + 0x6c, + 0xeb, + 0x8c, + 0xeb, + 0x8c, + 0xeb, + 0x6c, + 0xeb, + 0x4c, + 0xe3, + 0x0b, + 0xcb, + 0xe6, + 0x81, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x23, + 0x62, + 0xe6, + 0xd4, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x87, + 0xed, + 0xe7, + 0xfd, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x43, + 0x6a, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x28, + 0xa2, + 0x20, + 0x03, + 0x41, + 0xca, + 0xba, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x6c, + 0xeb, + 0xe6, + 0x81, + 0xa2, + 0x20, + 0x23, + 0x62, + 0xe6, + 0xd4, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x46, + 0xdd, + 0xe7, + 0xfd, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x43, + 0x6a, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0x03, + 0x41, + 0xca, + 0xba, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x6c, + 0xeb, + 0x85, + 0x61, + 0xa2, + 0x20, + 0x65, + 0xbc, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x26, + 0xd5, + 0xe7, + 0xfd, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0x20, + 0xa2, + 0x20, + 0x03, + 0x49, + 0x8c, + 0xeb, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x89, + 0xaa, + 0xa2, + 0x20, + 0xc5, + 0xa3, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x46, + 0xdd, + 0xe7, + 0xfd, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0xa2, + 0x20, + 0xa2, + 0x28, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0x20, + 0xa2, + 0x20, + 0x85, + 0x61, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x6c, + 0xe3, + 0xa2, + 0x20, + 0xc5, + 0xa3, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x87, + 0xed, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0x85, + 0x61, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0xea, + 0xc2, + 0xa2, + 0x20, + 0xc5, + 0xa3, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0xe7, + 0xfd, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x45, + 0xb4, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0x03, + 0x41, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0xd6, + 0xfd, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xd6, + 0xfd, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0xea, + 0xc2, + 0xa2, + 0x20, + 0xe6, + 0xd4, + 0x06, + 0xd5, + 0x46, + 0xdd, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0x20, + 0xa2, + 0x20, + 0x4c, + 0xe3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x65, + 0x59, + 0xc5, + 0xa3, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0xe7, + 0xfd, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0xe6, + 0x81, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x4c, + 0xe3, + 0xa2, + 0x20, + 0xe6, + 0xd4, + 0x06, + 0xd5, + 0x87, + 0xed, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0xa2, + 0x20, + 0x82, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0x20, + 0xa2, + 0x20, + 0x4c, + 0xe3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0x2f, + 0xf4, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x65, + 0x59, + 0xc5, + 0xa3, + 0x06, + 0xd5, + 0x46, + 0xdd, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x62, + 0x41, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0xd6, + 0xfd, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x3c, + 0xff, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0xea, + 0xc2, + 0x23, + 0x62, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x45, + 0xb4, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0x48, + 0x92, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x6c, + 0xeb, + 0xa2, + 0x20, + 0xe6, + 0xd4, + 0x06, + 0xd5, + 0xe7, + 0xfd, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0xa7, + 0xed, + 0xa2, + 0x20, + 0x82, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0xea, + 0xc2, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0xa2, + 0x20, + 0xc6, + 0xcc, + 0x06, + 0xd5, + 0xe7, + 0xfd, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x62, + 0x41, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0x0b, + 0xcb, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0xf2, + 0xf4, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x50, + 0xf4, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x03, + 0x41, + 0x65, + 0xbc, + 0x06, + 0xd5, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x44, + 0x93, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0x4c, + 0xe3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0xd6, + 0xfd, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0x3c, + 0xff, + 0xf2, + 0xf4, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x03, + 0x41, + 0x65, + 0xbc, + 0x26, + 0xd5, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0xc7, + 0xf5, + 0x67, + 0xe5, + 0x87, + 0xed, + 0xc7, + 0xf5, + 0xe7, + 0xfd, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x06, + 0xd5, + 0xa2, + 0x20, + 0x82, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0x0b, + 0xcb, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0xa2, + 0x20, + 0xc6, + 0xcc, + 0x67, + 0xe5, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0xa7, + 0xed, + 0x46, + 0xdd, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x46, + 0xdd, + 0x87, + 0xed, + 0xc7, + 0xf5, + 0xe7, + 0xfd, + 0x07, + 0xfe, + 0x62, + 0x41, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0x89, + 0xaa, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0xa2, + 0x20, + 0x06, + 0xd5, + 0x87, + 0xed, + 0x07, + 0xfe, + 0x07, + 0xfe, + 0xa7, + 0xed, + 0x67, + 0xe5, + 0x26, + 0xd5, + 0x65, + 0xbc, + 0x23, + 0x62, + 0x23, + 0x62, + 0xc5, + 0xa3, + 0xc6, + 0xcc, + 0xe6, + 0xd4, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x23, + 0x62, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0xa5, + 0x69, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0xd6, + 0xfd, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x58, + 0xfe, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x6c, + 0xe3, + 0x62, + 0x41, + 0x06, + 0xd5, + 0x46, + 0xdd, + 0x26, + 0xd5, + 0x06, + 0xd5, + 0x06, + 0xd5, + 0x65, + 0xbc, + 0x62, + 0x41, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x23, + 0x62, + 0xc5, + 0xa3, + 0xc6, + 0xcc, + 0xe6, + 0xd4, + 0x06, + 0xd5, + 0x65, + 0xbc, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x28, + 0x03, + 0x41, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x2f, + 0xf4, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd6, + 0xfd, + 0xd2, + 0xf4, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x48, + 0x92, + 0x23, + 0x62, + 0xe6, + 0xd4, + 0x65, + 0xbc, + 0x04, + 0x8b, + 0x62, + 0x41, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x28, + 0xa2, + 0x28, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x23, + 0x62, + 0x23, + 0x62, + 0xa2, + 0x20, + 0x82, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0x4b, + 0xdb, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x28, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x28, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x82, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0xea, + 0xc2, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0xf2, + 0xf4, + 0x2f, + 0xf4, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x89, + 0xaa, + 0xa2, + 0x20, + 0xa2, + 0x28, + 0x82, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0x20, + 0xa2, + 0x20, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0xd6, + 0xfd, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdb, + 0xfe, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xeb, + 0xa2, + 0x20, + 0xa2, + 0x28, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0xe6, + 0x79, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x85, + 0x61, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0xea, + 0xc2, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x85, + 0x61, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0x20, + 0xa2, + 0x20, + 0x8c, + 0xeb, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x85, + 0x61, + 0xa2, + 0x20, + 0xa2, + 0x28, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x6c, + 0xeb, + 0x03, + 0x41, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0x48, + 0x92, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x6c, + 0xe3, + 0xca, + 0xba, + 0xa5, + 0x69, + 0x03, + 0x49, + 0x0b, + 0xcb, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xeb, + 0x68, + 0xa2, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0x20, + 0xa2, + 0x20, + 0x2b, + 0xd3, + 0x0b, + 0xcb, + 0x68, + 0xa2, + 0x65, + 0x59, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x03, + 0x41, + 0x89, + 0xaa, + 0x6c, + 0xeb, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x8c, + 0xf3, + 0x0b, + 0xcb, + 0x68, + 0xa2, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x28, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x03, + 0x41, + 0x03, + 0x49, + 0x85, + 0x61, + 0x48, + 0x92, + 0x89, + 0xaa, + 0x68, + 0xa2, + 0xa5, + 0x69, + 0x65, + 0x59, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x82, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0x20, + 0xa2, + 0x20, + 0x82, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa2, + 0x28, + 0xa2, + 0x28, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0xa2, + 0x20, + 0x82, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x7f, 0x9f, 0x9f, 0xbf, 0x9f, 0x7f, 0x7f, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x60, 0xbf, 0xff, 0xff, 0xcf, 0xc3, 0xc3, 0xbf, 0xbf, 0xc3, 0xcf, 0xcf, 0xe3, 0xff, 0xbf, 0x7f, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xbf, 0xff, 0xe3, 0xc3, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xbf, 0xcf, 0xe3, 0xbf, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xbf, 0xff, 0xc3, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xe3, 0xdf, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xcf, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xe3, 0xbf, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xe3, 0xdf, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xbf, 0xcf, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xd0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xe4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xdf, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0xd5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xd1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xc5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0xd6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xc5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xc5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xd6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe8, 0xe8, 0xe8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0xd6, 0xcb, 0xc7, 0xe4, 0xe4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xd1, 0xd6, 0xe8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0xe4, 0xff, 0xab, 0xaf, 0xd7, 0xc7, 0xe3, 0xe3, 0xe7, 0xcf, 0xc3, 0xd7, 0xdf, 0xff, 0xd1, 0xe8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xff, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xd7, 0xff, 0xd1, 0xe8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xcf, 0xff, 0xcb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0xc7, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xbf, 0xdf, 0xc5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xbf, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xeb, 0xdf, 0xc5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xdf, 0xc5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xe8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xe7, 0xc5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xd7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xe8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xd1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xe8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xd6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xcb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xcb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x60, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcb, 0xd1, 0xd1, 0xc5, 0xd6, 0xe8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd1, 0x9f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xb7, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xab, 0xe4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcb, 0xe4, 0xff, 0x9f, 0x7f, 0xbf, 0xdf, 0xff, 0xff, 0xd1, 0xc5, 0xd6, 0xe8, 0xff, 0xcb, 0xdf, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf, 0xd1, 0xe8, 0xcb, 0xc7, 0xe4, 0xff, 0xdf, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x7f, 0xbf, 0xdf, 0xff, 0xd1, 0xd1, 0xff, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xd7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x7f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7f, 0xbf, 0xdf, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xdf, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf, 0xff, 0xff, 0xff, 0xe3, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xdf, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xe3, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xbf, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xeb, 0xaf, 0xb7, 0xc7, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xcf, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x20, 0xff, 0xb7, 0xc3, 0xcf, 0xe7, 0xff, 0xff, 0xbf, 0x9f, 0x9f, 0xdf, 0xff, 0xbf, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xc3, 0xcf, 0xff, 0x9f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0xff, 0x9f, 0x7f, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xbf, 0xff, 0xff, 0xc7, 0xcf, 0xaf, 0xbf, 0xcf, 0xb7, 0xe7, 0xff, 0xff, 0x9f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x20, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x7f, 0x7f, 0xbf, 0x9f, 0x9f, 0x60, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0x60, + 0x7f, + 0x9f, + 0x9f, + 0xbf, + 0x9f, + 0x7f, + 0x7f, + 0x40, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x60, + 0xbf, + 0xff, + 0xff, + 0xcf, + 0xc3, + 0xc3, + 0xbf, + 0xbf, + 0xc3, + 0xcf, + 0xcf, + 0xe3, + 0xff, + 0xbf, + 0x7f, + 0x40, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xbf, + 0xff, + 0xe3, + 0xc3, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xbf, + 0xcf, + 0xe3, + 0xbf, + 0x60, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xbf, + 0xff, + 0xc3, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xc3, + 0xe3, + 0xdf, + 0x60, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xcf, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xc3, + 0xe3, + 0xbf, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xe3, + 0xe3, + 0xdf, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xbf, + 0xcf, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xd0, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0xff, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xe4, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xe4, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0xdf, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xff, + 0xd5, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xe3, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xd1, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xc3, + 0xbf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xc5, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xff, + 0xd6, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xe3, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xe4, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0xbf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xc5, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xc5, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xff, + 0xd6, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xe8, + 0xe8, + 0xe8, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xe3, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xff, + 0xd6, + 0xcb, + 0xc7, + 0xe4, + 0xe4, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xe4, + 0xd1, + 0xd6, + 0xe8, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xff, + 0xe4, + 0xff, + 0xab, + 0xaf, + 0xd7, + 0xc7, + 0xe3, + 0xe3, + 0xe7, + 0xcf, + 0xc3, + 0xd7, + 0xdf, + 0xff, + 0xd1, + 0xe8, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xff, + 0xff, + 0xaf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xe7, + 0xd7, + 0xff, + 0xd1, + 0xe8, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xaf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xe7, + 0xcf, + 0xff, + 0xcb, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xff, + 0xc7, + 0xe3, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0xbf, + 0xdf, + 0xc5, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xbf, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xeb, + 0xdf, + 0xc5, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xe3, + 0xff, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xdf, + 0xc5, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0xdf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xe3, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xc3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xc3, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xff, + 0xe8, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xff, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0xe7, + 0xc5, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xe3, + 0xff, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xd7, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xff, + 0xe8, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xff, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xe3, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xe7, + 0xc5, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xe3, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xc3, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xc3, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xd1, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0xbf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xaf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xe7, + 0xff, + 0xe8, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0xff, + 0xd6, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xe3, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xff, + 0xc3, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc7, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xe3, + 0xcb, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xc3, + 0x9f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xe3, + 0xcb, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xc3, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xc3, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xd6, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xe3, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcb, + 0xd1, + 0xd1, + 0xc5, + 0xd6, + 0xe8, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xd1, + 0x9f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x9f, + 0xb7, + 0xff, + 0xff, + 0xff, + 0xff, + 0xc3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xe3, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xab, + 0xe4, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcb, + 0xe4, + 0xff, + 0x9f, + 0x7f, + 0xbf, + 0xdf, + 0xff, + 0xff, + 0xd1, + 0xc5, + 0xd6, + 0xe8, + 0xff, + 0xcb, + 0xdf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xe3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xc3, + 0xe7, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xaf, + 0xd1, + 0xe8, + 0xcb, + 0xc7, + 0xe4, + 0xff, + 0xdf, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0x40, + 0x7f, + 0xbf, + 0xdf, + 0xff, + 0xd1, + 0xd1, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xd7, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x7f, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0x7f, + 0xbf, + 0xdf, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xff, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0xdf, + 0x40, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xc3, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xaf, + 0xff, + 0xff, + 0xff, + 0xe3, + 0xff, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xeb, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xdf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xff, + 0xe3, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xdf, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xe7, + 0xe3, + 0xbf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xaf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xeb, + 0xaf, + 0xb7, + 0xc7, + 0xc3, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xe3, + 0xcf, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xff, + 0xb7, + 0xc3, + 0xcf, + 0xe7, + 0xff, + 0xff, + 0xbf, + 0x9f, + 0x9f, + 0xdf, + 0xff, + 0xbf, + 0xc7, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0xc3, + 0xcf, + 0xff, + 0x9f, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x7f, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xbf, + 0xff, + 0xff, + 0xc7, + 0xcf, + 0xaf, + 0xbf, + 0xcf, + 0xb7, + 0xe7, + 0xff, + 0xff, + 0x9f, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x60, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0x40, + 0x7f, + 0x7f, + 0xbf, + 0x9f, + 0x9f, + 0x60, + 0x60, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, }; const lv_image_dsc_t Chat = { - .header.magic = LV_IMAGE_HEADER_MAGIC, - .header.cf = LV_COLOR_FORMAT_RGB565A8, - .header.flags = 0, - .header.w = 64, - .header.h = 64, - .header.stride = 128, - .data_size = sizeof(Chat_map), - .data = Chat_map, + .header.magic = LV_IMAGE_HEADER_MAGIC, + .header.cf = LV_COLOR_FORMAT_RGB565A8, + .header.flags = 0, + .header.w = 64, + .header.h = 64, + .header.stride = 128, + .data_size = sizeof(Chat_map), + .data = Chat_map, }; diff --git a/src/ui/assets/Setting.c b/src/ui/assets/Setting.c index dcdeed02..333bee69 100644 --- a/src/ui/assets/Setting.c +++ b/src/ui/assets/Setting.c @@ -1,18 +1,17 @@ #ifdef __has_include - #if __has_include("lvgl.h") - #ifndef LV_LVGL_H_INCLUDE_SIMPLE - #define LV_LVGL_H_INCLUDE_SIMPLE - #endif - #endif +#if __has_include("lvgl.h") +#ifndef LV_LVGL_H_INCLUDE_SIMPLE +#define LV_LVGL_H_INCLUDE_SIMPLE +#endif +#endif #endif #if defined(LV_LVGL_H_INCLUDE_SIMPLE) - #include "lvgl.h" +#include "lvgl.h" #else - #include "lvgl/lvgl.h" +#include "lvgl/lvgl.h" #endif - #ifndef LV_ATTRIBUTE_MEM_ALIGN #define LV_ATTRIBUTE_MEM_ALIGN #endif @@ -22,144 +21,12304 @@ #endif const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMAGE_SETTING uint8_t Setting_map[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb6, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0x00, 0x00, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0xb6, 0x55, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xe9, 0xc7, 0xe1, 0xc7, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0xd5, 0x55, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x00, 0x00, 0x53, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0x8a, 0xf2, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0xb6, 0x55, 0xd6, 0x55, 0x53, 0x2d, 0x33, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0xd5, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x2d, 0x53, 0x2d, 0x33, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe1, 0x00, 0x00, 0xc7, 0xe1, 0xc7, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb6, 0x55, 0xd6, 0x55, 0xb6, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x00, 0x00, 0x8a, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0x8a, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x00, 0x00, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0xd5, 0x55, 0x33, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x33, 0x2d, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x55, 0x00, 0x00, 0xd6, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0xd5, 0x55, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xe1, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb6, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0xb6, 0x55, 0x53, 0x2d, 0x53, 0x2d, 0x53, 0x2d, 0x33, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0x8a, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xe1, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x55, 0xd6, 0x55, 0xd6, 0x55, 0x00, 0x00, 0x00, 0x00, 0x53, 0x2d, 0x33, 0x2d, 0x53, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0x8a, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0x8a, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0x8a, 0xf2, 0x00, 0x00, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0xca, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xc9, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xc9, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xc9, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0xc7, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xc9, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xf2, 0xaa, 0xf2, 0xaa, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xe9, 0xc7, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xc9, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xa8, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xc9, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xc9, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xc9, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xc9, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xc9, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x53, + 0x2d, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xb6, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0x00, + 0x00, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xb6, + 0x55, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x8a, + 0xf2, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xc7, + 0xe9, + 0xc7, + 0xe1, + 0xc7, + 0xe9, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd5, + 0x55, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x00, + 0x00, + 0x53, + 0x2d, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0x8a, + 0xf2, + 0x00, + 0x00, + 0x00, + 0x00, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xb6, + 0x55, + 0xd6, + 0x55, + 0x53, + 0x2d, + 0x33, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd5, + 0x55, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xd5, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x33, + 0x2d, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe1, + 0x00, + 0x00, + 0xc7, + 0xe1, + 0xc7, + 0xe9, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xb6, + 0x55, + 0xd6, + 0x55, + 0xb6, + 0x55, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x00, + 0x00, + 0x8a, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0x8a, + 0xf2, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x33, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x00, + 0x00, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd5, + 0x55, + 0x33, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x33, + 0x2d, + 0x00, + 0x00, + 0x00, + 0x00, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe1, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xd6, + 0x55, + 0x00, + 0x00, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd5, + 0x55, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x8a, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xc7, + 0xe1, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xb6, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xb6, + 0x55, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x53, + 0x2d, + 0x33, + 0x2d, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0x8a, + 0xf2, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xc7, + 0xe1, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0xd6, + 0x55, + 0x00, + 0x00, + 0x00, + 0x00, + 0x53, + 0x2d, + 0x33, + 0x2d, + 0x53, + 0x2d, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x8a, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0x8a, + 0xf2, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0x8a, + 0xf2, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0x8a, + 0xf2, + 0x00, + 0x00, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0xca, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xc9, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xc9, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xc9, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0x00, + 0x00, + 0x00, + 0x00, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xc9, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0xaa, + 0xf2, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xc7, + 0xe9, + 0xc7, + 0xe9, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xc9, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xa8, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xc9, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xc9, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xc9, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xc9, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xc9, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0xca, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x45, + 0xfd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xdf, 0x7f, 0x00, 0x20, 0xff, 0xbf, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xdf, 0x20, 0x00, 0x00, 0xbf, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xdf, 0xdf, 0xff, 0xff, 0x60, 0x20, 0x40, 0x9f, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0xff, 0x9f, 0x9f, 0x9f, 0xff, 0xff, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xdf, 0xff, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0x40, 0x00, 0x00, 0x00, 0x7f, 0x9f, 0x60, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x60, 0x7f, 0xbf, 0xdf, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x40, 0x00, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xdf, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xdf, 0xff, 0xff, 0xff, 0xbf, 0x40, 0x60, 0xbf, 0xff, 0xff, 0x7f, 0x9f, 0x00, 0x00, 0x60, 0xdf, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xff, 0xff, 0xdf, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x7f, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xdf, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xff, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0xc7, 0xbf, 0xff, 0xff, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xbf, 0xdf, 0x00, 0x00, 0x7f, 0x9f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xbf, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xdf, 0xdf, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xff, 0xff, 0xff, 0x9f, 0x20, 0x00, 0x00, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xdf, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x20, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x60, 0x20, 0x00, 0x60, 0xbf, 0xff, 0xff, 0xff, 0xdf, 0xdf, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x20, 0x00, 0x20, 0x20, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x00, 0x40, 0x7f, 0x40, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xff, 0xdf, 0x00, 0x00, 0x60, 0xff, 0xff, 0xdf, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x9f, 0x40, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x20, 0x60, 0x9f, 0xdf, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xbf, 0xbf, 0x40, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x60, 0x20, 0x40, 0x60, 0x9f, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x7f, 0x58, 0x7f, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x00, 0x40, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x9f, 0x60, 0x00, 0x7f, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xdf, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x9f, 0xdf, 0xff, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x9f, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xdf, + 0x7f, + 0x00, + 0x20, + 0xff, + 0xbf, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xff, + 0xc7, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x00, + 0x00, + 0x00, + 0x20, + 0x40, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xff, + 0xe3, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xdf, + 0x20, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xdf, + 0xdf, + 0xff, + 0xff, + 0x60, + 0x20, + 0x40, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x9f, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xdf, + 0xff, + 0xdf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xff, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0x00, + 0x40, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xff, + 0x9f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xff, + 0x40, + 0x00, + 0x00, + 0x00, + 0x7f, + 0x9f, + 0x60, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x60, + 0x7f, + 0xbf, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xdf, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xbf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xff, + 0xff, + 0xff, + 0x40, + 0x00, + 0x20, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x9f, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x40, + 0x60, + 0xbf, + 0xff, + 0xff, + 0x7f, + 0x9f, + 0x00, + 0x00, + 0x60, + 0xdf, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x9f, + 0xff, + 0xff, + 0xdf, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xe3, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xdf, + 0xff, + 0xff, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xff, + 0xff, + 0x9f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xff, + 0xff, + 0xc7, + 0xbf, + 0xff, + 0xff, + 0x9f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xff, + 0xff, + 0xbf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xbf, + 0xdf, + 0x00, + 0x00, + 0x7f, + 0x9f, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xff, + 0xff, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0x40, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xdf, + 0xdf, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x9f, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x20, + 0x00, + 0x00, + 0x60, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x20, + 0x00, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x60, + 0x20, + 0x00, + 0x60, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xdf, + 0xdf, + 0x9f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x20, + 0x00, + 0x20, + 0x20, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x60, + 0x00, + 0x00, + 0x40, + 0x7f, + 0x40, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0xff, + 0xff, + 0xff, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xff, + 0xdf, + 0x00, + 0x00, + 0x60, + 0xff, + 0xff, + 0xdf, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0x9f, + 0x40, + 0x00, + 0x00, + 0x00, + 0x60, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x20, + 0x60, + 0x9f, + 0xdf, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xbf, + 0xbf, + 0x40, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x60, + 0x20, + 0x40, + 0x60, + 0x9f, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x40, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x7f, + 0x58, + 0x7f, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x00, + 0x40, + 0x7f, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x9f, + 0x9f, + 0x60, + 0x00, + 0x7f, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xff, + 0xdf, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0x9f, + 0xdf, + 0xff, + 0xdf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x9f, + 0x9f, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, }; const lv_image_dsc_t Setting = { - .header.magic = LV_IMAGE_HEADER_MAGIC, - .header.cf = LV_COLOR_FORMAT_RGB565A8, - .header.flags = 0, - .header.w = 64, - .header.h = 64, - .header.stride = 128, - .data_size = sizeof(Setting_map), - .data = Setting_map, + .header.magic = LV_IMAGE_HEADER_MAGIC, + .header.cf = LV_COLOR_FORMAT_RGB565A8, + .header.flags = 0, + .header.w = 64, + .header.h = 64, + .header.stride = 128, + .data_size = sizeof(Setting_map), + .data = Setting_map, }; diff --git a/src/ui/assets/alert.c b/src/ui/assets/alert.c index 9e3adc59..ba42b94c 100644 --- a/src/ui/assets/alert.c +++ b/src/ui/assets/alert.c @@ -1,18 +1,17 @@ #ifdef __has_include - #if __has_include("lvgl.h") - #ifndef LV_LVGL_H_INCLUDE_SIMPLE - #define LV_LVGL_H_INCLUDE_SIMPLE - #endif - #endif +#if __has_include("lvgl.h") +#ifndef LV_LVGL_H_INCLUDE_SIMPLE +#define LV_LVGL_H_INCLUDE_SIMPLE +#endif +#endif #endif #if defined(LV_LVGL_H_INCLUDE_SIMPLE) - #include "lvgl.h" +#include "lvgl.h" #else - #include "lvgl/lvgl.h" +#include "lvgl/lvgl.h" #endif - #ifndef LV_ATTRIBUTE_MEM_ALIGN #define LV_ATTRIBUTE_MEM_ALIGN #endif @@ -22,80 +21,3088 @@ #endif const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMAGE_ALERT uint8_t alert_map[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0xa6, 0x31, 0xa7, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x39, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x39, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x39, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa7, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x39, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa7, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x39, 0xa6, 0x31, 0xa6, 0x31, 0xa7, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x86, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0x86, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x39, 0xa7, 0x39, 0xa7, 0x39, 0xa7, 0x39, 0xa7, 0x39, 0xa7, 0x39, 0xa7, 0x39, 0xc7, 0x41, 0xa6, 0x31, 0xa6, 0x31, 0xc6, 0x39, 0x00, 0x00, 0x86, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x39, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x27, 0x62, 0x08, 0xf4, 0x00, 0x00, 0x86, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x27, 0x62, 0xe8, 0xf3, 0x08, 0xf4, 0x00, 0x00, 0x86, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xe7, 0x9a, 0x07, 0xab, 0x07, 0xab, 0x07, 0xab, 0xe8, 0xf3, 0xe8, 0xf3, 0x08, 0xf4, 0x00, 0x00, 0x86, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0x08, 0xf4, 0x00, 0x00, 0x86, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x08, 0xf4, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0x08, 0xf4, 0x00, 0x00, 0x86, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x49, 0xa6, 0x31, 0x27, 0x62, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0x08, 0xf4, 0x00, 0x00, 0x86, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x39, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x49, 0xa6, 0x31, 0x27, 0x62, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0x08, 0xf4, 0x00, 0x00, 0x86, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x49, 0xa6, 0x31, 0x27, 0x62, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0x08, 0xf4, 0x00, 0x00, 0x86, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0xa7, 0x39, 0xa7, 0x39, 0xa7, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x49, 0xa6, 0x31, 0x27, 0x62, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0xe8, 0xf3, 0x08, 0xf4, 0x00, 0x00, 0x86, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x49, 0xa6, 0x31, 0x27, 0x62, 0x07, 0xab, 0x07, 0xab, 0x07, 0xab, 0x07, 0xab, 0x07, 0xab, 0x07, 0xab, 0x07, 0xab, 0xe8, 0xf3, 0xe8, 0xf3, 0x08, 0xf4, 0x00, 0x00, 0x86, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x52, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xe7, 0x49, 0xe8, 0xf3, 0x08, 0xf4, 0x00, 0x00, 0x86, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x6a, 0xe7, 0x49, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xe7, 0x49, 0xa7, 0x8a, 0x00, 0x00, 0x86, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0xa7, 0x8a, 0xa7, 0x8a, 0xa7, 0x8a, 0xa7, 0x8a, 0xa7, 0x8a, 0xa7, 0x8a, 0xa7, 0x8a, 0x27, 0x62, 0xa6, 0x31, 0xa6, 0x31, 0xa7, 0x39, 0x86, 0x31, 0x86, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0xa7, 0x82, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa7, 0x39, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xa7, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0x87, 0x7a, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x39, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0xa6, 0x31, 0xa7, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x39, 0xa6, 0x31, 0xa7, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa6, + 0x31, + 0xa7, + 0x39, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa7, + 0x39, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa7, + 0x39, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa7, + 0x39, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa7, + 0x39, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa7, + 0x39, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa7, + 0x39, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa7, + 0x39, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa7, + 0x39, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x86, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa6, + 0x31, + 0x86, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa7, + 0x39, + 0xa7, + 0x39, + 0xa7, + 0x39, + 0xa7, + 0x39, + 0xa7, + 0x39, + 0xa7, + 0x39, + 0xa7, + 0x39, + 0xc7, + 0x41, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xc6, + 0x39, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa7, + 0x39, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x27, + 0x62, + 0x08, + 0xf4, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x27, + 0x62, + 0xe8, + 0xf3, + 0x08, + 0xf4, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xe7, + 0x9a, + 0x07, + 0xab, + 0x07, + 0xab, + 0x07, + 0xab, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0x08, + 0xf4, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0x08, + 0xf4, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x08, + 0xf4, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0x08, + 0xf4, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xe7, + 0x49, + 0xa6, + 0x31, + 0x27, + 0x62, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0x08, + 0xf4, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa7, + 0x39, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xe7, + 0x49, + 0xa6, + 0x31, + 0x27, + 0x62, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0x08, + 0xf4, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xe7, + 0x49, + 0xa6, + 0x31, + 0x27, + 0x62, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0x08, + 0xf4, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa7, + 0x39, + 0xa7, + 0x39, + 0xa7, + 0x39, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xe7, + 0x49, + 0xa6, + 0x31, + 0x27, + 0x62, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0x08, + 0xf4, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xe7, + 0x49, + 0xa6, + 0x31, + 0x27, + 0x62, + 0x07, + 0xab, + 0x07, + 0xab, + 0x07, + 0xab, + 0x07, + 0xab, + 0x07, + 0xab, + 0x07, + 0xab, + 0x07, + 0xab, + 0xe8, + 0xf3, + 0xe8, + 0xf3, + 0x08, + 0xf4, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x07, + 0x52, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xe7, + 0x49, + 0xe8, + 0xf3, + 0x08, + 0xf4, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x47, + 0x6a, + 0xe7, + 0x49, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xe7, + 0x49, + 0xa7, + 0x8a, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa7, + 0x8a, + 0xa7, + 0x8a, + 0xa7, + 0x8a, + 0xa7, + 0x8a, + 0xa7, + 0x8a, + 0xa7, + 0x8a, + 0xa7, + 0x8a, + 0x27, + 0x62, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa7, + 0x39, + 0x86, + 0x31, + 0x86, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa7, + 0x82, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa7, + 0x39, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa6, + 0x31, + 0xa7, + 0x39, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x86, + 0x31, + 0x87, + 0x7a, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa7, + 0x39, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0xa6, + 0x31, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x86, + 0x31, + 0xa6, + 0x31, + 0xa7, + 0x39, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xa7, + 0x39, + 0xa6, + 0x31, + 0xa7, + 0x39, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x7f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xbf, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xff, 0x9f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x40, 0xff, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x40, 0xff, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xff, 0xdf, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x40, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xff, 0xdf, 0x20, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xcf, 0xff, 0xff, 0xc7, 0x00, 0x20, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x20, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x20, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xdf, 0xff, 0xdf, 0x60, 0x60, 0x60, 0xd7, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x20, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xdf, 0xff, 0xbf, 0x00, 0x00, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x20, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xdf, 0xff, 0xbf, 0x20, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x20, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x20, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x20, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x40, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x20, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x20, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x20, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x20, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x20, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x20, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x20, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x58, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3c, 0x00, 0x20, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x20, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0xf7, 0xff, 0xff, 0xe3, 0x20, 0x20, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xdf, 0xff, 0xff, 0xdf, 0x40, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x7f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x60, 0xff, 0xdf, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x40, 0xff, 0xff, 0xdf, 0x7f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0xdf, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0xbf, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x7f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xbf, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x7f, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xbf, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xff, + 0xff, + 0x9f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x9f, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x40, + 0xff, + 0xff, + 0xff, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x40, + 0xff, + 0xff, + 0xff, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xff, + 0xdf, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x40, + 0xff, + 0xff, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xff, + 0xdf, + 0x20, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x60, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0x40, + 0x40, + 0x40, + 0x40, + 0x40, + 0x40, + 0xcf, + 0xff, + 0xff, + 0xc7, + 0x00, + 0x20, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x20, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x20, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xff, + 0xdf, + 0x60, + 0x60, + 0x60, + 0xd7, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x20, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xff, + 0xbf, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x20, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xff, + 0xbf, + 0x20, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x20, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x20, + 0x60, + 0x60, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xfb, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x20, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xfb, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x20, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x20, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xfb, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x20, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x20, + 0x40, + 0x40, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xfb, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x20, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xfb, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x20, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xe7, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x20, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x58, + 0xfb, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x3c, + 0x00, + 0x20, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x3c, + 0x3c, + 0x3c, + 0x3c, + 0x3c, + 0x3c, + 0x3c, + 0xf7, + 0xff, + 0xff, + 0xe3, + 0x20, + 0x20, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xdf, + 0xff, + 0xff, + 0xdf, + 0x40, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x7f, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xcf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x60, + 0xff, + 0xdf, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x40, + 0xff, + 0xff, + 0xdf, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x60, + 0xff, + 0xff, + 0xdf, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xff, + 0xff, + 0xbf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x7f, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xbf, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, }; const lv_image_dsc_t alert = { - .header.magic = LV_IMAGE_HEADER_MAGIC, - .header.cf = LV_COLOR_FORMAT_RGB565A8, - .header.flags = 0, - .header.w = 32, - .header.h = 32, - .header.stride = 64, - .data_size = sizeof(alert_map), - .data = alert_map, + .header.magic = LV_IMAGE_HEADER_MAGIC, + .header.cf = LV_COLOR_FORMAT_RGB565A8, + .header.flags = 0, + .header.w = 32, + .header.h = 32, + .header.stride = 64, + .data_size = sizeof(alert_map), + .data = alert_map, }; diff --git a/src/ui/assets/contact.c b/src/ui/assets/contact.c index d72ce3a6..fdde3d7f 100644 --- a/src/ui/assets/contact.c +++ b/src/ui/assets/contact.c @@ -1,18 +1,17 @@ #ifdef __has_include - #if __has_include("lvgl.h") - #ifndef LV_LVGL_H_INCLUDE_SIMPLE - #define LV_LVGL_H_INCLUDE_SIMPLE - #endif - #endif +#if __has_include("lvgl.h") +#ifndef LV_LVGL_H_INCLUDE_SIMPLE +#define LV_LVGL_H_INCLUDE_SIMPLE +#endif +#endif #endif #if defined(LV_LVGL_H_INCLUDE_SIMPLE) - #include "lvgl.h" +#include "lvgl.h" #else - #include "lvgl/lvgl.h" +#include "lvgl/lvgl.h" #endif - #ifndef LV_ATTRIBUTE_MEM_ALIGN #define LV_ATTRIBUTE_MEM_ALIGN #endif @@ -22,144 +21,12304 @@ #endif const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMAGE_CONTRACT uint8_t contact_map[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0xee, 0x6a, 0xee, 0x6a, 0xee, 0x49, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xec, 0x47, 0xec, 0x48, 0xec, 0x48, 0xec, 0x48, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0xee, 0x6a, 0xee, 0x6a, 0xee, 0x49, 0xee, 0x49, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x88, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xf4, 0x47, 0xf4, 0x88, 0xec, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x6a, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x88, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xf4, 0xc8, 0xf4, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x6a, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x6a, 0xee, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x69, 0xee, 0x69, 0xf6, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x6a, 0xee, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xf4, 0x69, 0xee, 0x69, 0xf6, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xf6, 0x48, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x48, 0xec, 0x69, 0xf6, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x49, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x6a, 0xee, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xf4, 0x6a, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xf6, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x48, 0xec, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x49, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x6a, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x6a, 0xee, 0x47, 0xf4, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x6a, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x47, 0xf4, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xf4, 0x49, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xf6, 0x00, 0x00, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x49, 0xee, 0x47, 0xf4, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x49, 0xee, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x49, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x6a, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xf6, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x48, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x48, 0xec, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x48, 0xed, 0x47, 0xf4, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x49, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0xee, 0x69, 0xf6, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x48, 0xec, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x49, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x49, 0xee, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0xb1, 0xf5, 0xb1, 0xf5, 0xca, 0xf4, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x49, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xf6, 0x48, 0xed, 0x47, 0xf4, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x34, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xfe, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xf4, 0x49, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xf6, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xf6, 0x48, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xf6, 0x49, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x48, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xf4, 0xe8, 0xec, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x49, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xf4, 0x47, 0xec, 0x69, 0xee, 0x69, 0xf6, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xf6, 0x6a, 0xee, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xf4, 0x6a, 0xee, 0x69, 0xf6, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x6a, 0xee, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x9d, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9d, 0xff, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x69, 0xee, 0x69, 0xf6, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x34, 0xfe, 0x9d, 0xff, 0xff, 0xff, 0xb1, 0xf5, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x6a, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x48, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x4d, 0xf5, 0xca, 0xf4, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x49, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xf6, 0x00, 0x00, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xf4, 0x00, 0x00, 0x69, 0xf6, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x49, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x47, 0xf4, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xf4, 0x49, 0xee, 0x69, 0xf6, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x48, 0xec, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x49, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x6a, 0xee, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x6a, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x47, 0xf4, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xf4, 0x49, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xf4, 0x00, 0x00, 0x69, 0xf6, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xf6, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xf6, 0x00, 0x00, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x69, 0xf6, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x48, 0xec, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xf6, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x09, 0xee, 0x89, 0xf5, 0xe8, 0xec, 0x67, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xf4, 0x47, 0xec, 0xe8, 0xec, 0x89, 0xf5, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x49, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0xee, 0x6a, 0xee, 0x69, 0xee, 0x69, 0xf6, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x0b, 0xee, 0x4b, 0xed, 0xea, 0xec, 0xaa, 0xf4, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x89, 0xf4, 0xcb, 0xec, 0x2a, 0xed, 0xa9, 0xed, 0x69, 0xf6, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0x49, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0xf7, 0xf4, 0xf6, 0xd1, 0xf6, 0x8e, 0xf6, 0x8c, 0xf6, 0x69, 0xee, 0x69, 0xee, 0x8e, 0xf6, 0x4d, 0xf6, 0xce, 0xf5, 0x4e, 0xf5, 0x0c, 0xf5, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0x47, 0xec, 0xaa, 0xf4, 0xaa, 0xf4, 0xaf, 0xf5, 0xf0, 0xf5, 0xb0, 0xf6, 0x8c, 0xf6, 0x69, 0xee, 0x69, 0xee, 0x69, 0xee, 0xb0, 0xf6, 0xd1, 0xf6, 0xb2, 0xf6, 0x3b, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x17, 0xf7, 0x17, 0xf7, 0xf5, 0xf6, 0xf5, 0xf6, 0x17, 0xf7, 0x17, 0xf7, 0x3b, 0xf7, 0xd9, 0xf6, 0xd9, 0xf6, 0x76, 0xf6, 0x14, 0xf6, 0xd1, 0xf5, 0x76, 0xf6, 0x76, 0xf6, 0x3b, 0xf7, 0x3b, 0xf7, 0x17, 0xf7, 0x17, 0xf7, 0xf5, 0xf6, 0xd2, 0xf6, 0xf5, 0xf6, 0x19, 0xf7, 0x19, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3c, 0xf7, 0x3b, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0xf7, 0x3b, 0xf7, 0x3c, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3c, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0xf7, 0x5b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x5b, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x49, + 0xee, + 0x6a, + 0xee, + 0x6a, + 0xee, + 0x49, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x47, + 0xec, + 0x47, + 0xec, + 0x48, + 0xec, + 0x48, + 0xec, + 0x48, + 0xec, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x49, + 0xee, + 0x6a, + 0xee, + 0x6a, + 0xee, + 0x49, + 0xee, + 0x49, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x88, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xf4, + 0x47, + 0xf4, + 0x88, + 0xec, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x6a, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x6a, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x88, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xf4, + 0xc8, + 0xf4, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x6a, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x6a, + 0xee, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x69, + 0xee, + 0x69, + 0xf6, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x6a, + 0xee, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xf4, + 0x69, + 0xee, + 0x69, + 0xf6, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x6a, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x49, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xf6, + 0x48, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x48, + 0xec, + 0x69, + 0xf6, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x49, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x6a, + 0xee, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xf4, + 0x6a, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xf6, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x48, + 0xec, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x49, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x49, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x6a, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x6a, + 0xee, + 0x47, + 0xf4, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x6a, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x47, + 0xf4, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xf4, + 0x49, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xf6, + 0x00, + 0x00, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x49, + 0xee, + 0x47, + 0xf4, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x49, + 0xee, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x49, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x6a, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xf6, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x48, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x48, + 0xec, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x48, + 0xed, + 0x47, + 0xf4, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x49, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x49, + 0xee, + 0x69, + 0xf6, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x48, + 0xec, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x49, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x49, + 0xee, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0xb1, + 0xf5, + 0xb1, + 0xf5, + 0xca, + 0xf4, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x49, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xf6, + 0x48, + 0xed, + 0x47, + 0xf4, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x34, + 0xfe, + 0xff, + 0xff, + 0xff, + 0xff, + 0xb7, + 0xfe, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xf4, + 0x49, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xf6, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xf6, + 0x48, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xf6, + 0x49, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x49, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x48, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xf4, + 0xe8, + 0xec, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x49, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x6a, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xf4, + 0x47, + 0xec, + 0x69, + 0xee, + 0x69, + 0xf6, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xf6, + 0x6a, + 0xee, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xf4, + 0x6a, + 0xee, + 0x69, + 0xf6, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x6a, + 0xee, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x9d, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9d, + 0xff, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x69, + 0xee, + 0x69, + 0xf6, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x6a, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x34, + 0xfe, + 0x9d, + 0xff, + 0xff, + 0xff, + 0xb1, + 0xf5, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x6a, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x49, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x48, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x4d, + 0xf5, + 0xca, + 0xf4, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x49, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xf6, + 0x00, + 0x00, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xf4, + 0x00, + 0x00, + 0x69, + 0xf6, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x49, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x49, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x47, + 0xf4, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xf4, + 0x49, + 0xee, + 0x69, + 0xf6, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x49, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x48, + 0xec, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x49, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x6a, + 0xee, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x6a, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x47, + 0xf4, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xf4, + 0x49, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xf4, + 0x00, + 0x00, + 0x69, + 0xf6, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xf6, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xf6, + 0x00, + 0x00, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x69, + 0xf6, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x48, + 0xec, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x6a, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xf6, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x09, + 0xee, + 0x89, + 0xf5, + 0xe8, + 0xec, + 0x67, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xf4, + 0x47, + 0xec, + 0xe8, + 0xec, + 0x89, + 0xf5, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x49, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x6a, + 0xee, + 0x6a, + 0xee, + 0x69, + 0xee, + 0x69, + 0xf6, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x0b, + 0xee, + 0x4b, + 0xed, + 0xea, + 0xec, + 0xaa, + 0xf4, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x89, + 0xf4, + 0xcb, + 0xec, + 0x2a, + 0xed, + 0xa9, + 0xed, + 0x69, + 0xf6, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0x49, + 0xee, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x5b, + 0xf7, + 0xf4, + 0xf6, + 0xd1, + 0xf6, + 0x8e, + 0xf6, + 0x8c, + 0xf6, + 0x69, + 0xee, + 0x69, + 0xee, + 0x8e, + 0xf6, + 0x4d, + 0xf6, + 0xce, + 0xf5, + 0x4e, + 0xf5, + 0x0c, + 0xf5, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0x47, + 0xec, + 0xaa, + 0xf4, + 0xaa, + 0xf4, + 0xaf, + 0xf5, + 0xf0, + 0xf5, + 0xb0, + 0xf6, + 0x8c, + 0xf6, + 0x69, + 0xee, + 0x69, + 0xee, + 0x69, + 0xee, + 0xb0, + 0xf6, + 0xd1, + 0xf6, + 0xb2, + 0xf6, + 0x3b, + 0xf7, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x5b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x17, + 0xf7, + 0x17, + 0xf7, + 0xf5, + 0xf6, + 0xf5, + 0xf6, + 0x17, + 0xf7, + 0x17, + 0xf7, + 0x3b, + 0xf7, + 0xd9, + 0xf6, + 0xd9, + 0xf6, + 0x76, + 0xf6, + 0x14, + 0xf6, + 0xd1, + 0xf5, + 0x76, + 0xf6, + 0x76, + 0xf6, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x17, + 0xf7, + 0x17, + 0xf7, + 0xf5, + 0xf6, + 0xd2, + 0xf6, + 0xf5, + 0xf6, + 0x19, + 0xf7, + 0x19, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3c, + 0xf7, + 0x3b, + 0xf7, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x5b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x5b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x5b, + 0xf7, + 0x3b, + 0xf7, + 0x3c, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x5b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3c, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x5b, + 0xf7, + 0x5b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x3b, + 0xf7, + 0x5b, + 0xf7, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x40, 0x20, 0x00, 0x00, 0x00, 0x20, 0x20, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x8f, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xdf, 0x8f, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x9f, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x7f, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3c, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x3c, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x58, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x7f, 0x7f, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x40, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x40, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x60, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x20, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7f, 0xbf, 0xdf, 0xff, 0xff, 0xff, 0xc7, 0x9f, 0x88, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xbf, 0xaf, 0x9f, 0x9f, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x7f, 0xdf, 0xff, 0xff, 0xff, 0xbf, 0x9d, 0xa6, 0xcb, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xc3, 0xc3, 0xb7, 0xdf, 0xff, 0xff, 0xff, 0xbf, 0x9f, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x9f, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xdf, 0xaf, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x9f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x60, 0x9f, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x7f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x60, 0x9f, 0xbf, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xdf, 0xbf, 0x7f, 0x7f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x40, 0x40, 0x40, 0x40, 0x60, 0x60, 0x40, 0x40, 0x40, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x40, + 0x40, + 0x20, + 0x00, + 0x00, + 0x00, + 0x20, + 0x20, + 0x40, + 0x40, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x40, + 0x40, + 0x20, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x8f, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0xdf, + 0x8f, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x8f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x9f, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x7f, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x7f, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x60, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x60, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x60, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x20, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x00, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x00, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x00, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x20, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x60, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x3c, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x60, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x20, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x3c, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x20, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x00, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x58, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x60, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x7f, + 0x7f, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x40, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x40, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x60, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x60, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x00, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x60, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x60, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x20, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x60, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x20, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x00, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x00, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x20, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x60, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0x7f, + 0xbf, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xc7, + 0x9f, + 0x88, + 0xc7, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0xbf, + 0xaf, + 0x9f, + 0x9f, + 0xff, + 0xff, + 0xff, + 0xff, + 0x9f, + 0x60, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0x40, + 0x7f, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x9d, + 0xa6, + 0xcb, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xef, + 0xc3, + 0xc3, + 0xb7, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xbf, + 0x9f, + 0x60, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x9f, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xf3, + 0xdf, + 0xaf, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x9f, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0xdf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x60, + 0x9f, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0x7f, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x40, + 0x60, + 0x9f, + 0xbf, + 0xbf, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xdf, + 0xdf, + 0xbf, + 0x7f, + 0x7f, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x20, + 0x40, + 0x40, + 0x40, + 0x40, + 0x60, + 0x60, + 0x40, + 0x40, + 0x40, + 0x40, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, }; const lv_image_dsc_t contact = { - .header.magic = LV_IMAGE_HEADER_MAGIC, - .header.cf = LV_COLOR_FORMAT_RGB565A8, - .header.flags = 0, - .header.w = 64, - .header.h = 64, - .header.stride = 128, - .data_size = sizeof(contact_map), - .data = contact_map, + .header.magic = LV_IMAGE_HEADER_MAGIC, + .header.cf = LV_COLOR_FORMAT_RGB565A8, + .header.flags = 0, + .header.w = 64, + .header.h = 64, + .header.stride = 128, + .data_size = sizeof(contact_map), + .data = contact_map, }; diff --git a/src/ui/assets/fonts/lv_font_noto_cjk_16_2bpp.c b/src/ui/assets/fonts/lv_font_noto_cjk_16_2bpp.c index c69527b0..1155665a 100644 --- a/src/ui/assets/fonts/lv_font_noto_cjk_16_2bpp.c +++ b/src/ui/assets/fonts/lv_font_noto_cjk_16_2bpp.c @@ -1,7 +1,7 @@ /******************************************************************************* * Size: 16 px * Bpp: 2 - * Opts: + * Opts: ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE @@ -66588,9 +66588,7 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x5, 0x45, 0x51, 0x50, 0xb, 0xff, 0xff, 0xe0, 0xd, 0x28, 0x38, 0x70, 0xc, 0x28, 0x24, 0x70, 0xf, 0xff, 0xff, 0xf0, 0xc, 0x28, 0x24, 0x70, - 0xc, 0x28, 0x26, 0xe0 -}; - + 0xc, 0x28, 0x26, 0xe0}; /*--------------------- * GLYPH DESCRIPTION @@ -73455,8 +73453,7 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { {.bitmap_index = 404767, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, {.bitmap_index = 404831, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, {.bitmap_index = 404895, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 404959, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1} -}; + {.bitmap_index = 404959, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}}; /*--------------------- * CHARACTER MAPPING @@ -73493,8 +73490,7 @@ static const uint8_t glyph_id_ofs_list_1[] = { 128, 129, 0, 0, 0, 130, 131, 132, 0, 133, 0, 134, 135, 136, 0, 0, 137, 0, 138, 139, 140, 0, 0, 0, - 141, 0, 142, 143, 0, 144, 145, 146 -}; + 141, 0, 142, 143, 0, 144, 145, 146}; static const uint16_t unicode_list_2[] = { 0x0, 0x2, 0x4, 0x6, 0xe, 0xf, 0x12, 0x13, @@ -73557,8 +73553,7 @@ static const uint16_t unicode_list_2[] = { 0x49f, 0x4a2, 0x4a4, 0x4a7, 0x4a8, 0x4aa, 0x4ab, 0x4ad, 0x4ae, 0x4b3, 0x4bb, 0x4c0, 0x4c4, 0x4c6, 0x4c7, 0x4cd, 0x4ce, 0x4cf, 0x4d0, 0x4d1, 0x4d2, 0x4d6, 0x4d9, 0x4db, - 0x4dc, 0x4dd, 0x4de, 0x4e0, 0x4e4, 0x4e5 -}; + 0x4dc, 0x4dd, 0x4de, 0x4e0, 0x4e4, 0x4e5}; static const uint8_t glyph_id_ofs_list_3[] = { 0, 1, 2, 3, 0, 4, 5, 6, @@ -73592,8 +73587,7 @@ static const uint8_t glyph_id_ofs_list_3[] = { 0, 136, 0, 137, 138, 139, 140, 0, 0, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 0, 151, 0, 152, 153, - 0, 154, 155, 156, 157 -}; + 0, 154, 155, 156, 157}; static const uint16_t unicode_list_4[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x8, 0x9, @@ -74021,8 +74015,7 @@ static const uint16_t unicode_list_4[] = { 0x27f1, 0x27f2, 0x27f4, 0x27f7, 0x27fa, 0x27fb, 0x2803, 0x280a, 0x2813, 0x2816, 0x2825, 0x283b, 0x283d, 0x2842, 0x2846, 0x284a, 0x2889, 0x2892, 0x28c1, 0x28c9, 0x2956, 0x295c, 0x2962, 0x299d, - 0x29b6 -}; + 0x29b6}; static const uint8_t glyph_id_ofs_list_5[] = { 0, 1, 2, 3, 4, 5, 6, 7, @@ -74040,8 +74033,7 @@ static const uint8_t glyph_id_ofs_list_5[] = { 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 0, 99, 100, 101, 102, 103, 0, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116 -}; + 110, 111, 112, 113, 114, 115, 116}; static const uint16_t unicode_list_7[] = { 0x0, 0x2, 0xa, 0xc, 0xd, 0x18, 0x19, 0x1c, @@ -74085,8 +74077,7 @@ static const uint16_t unicode_list_7[] = { 0x300, 0x301, 0x303, 0x306, 0x30c, 0x30f, 0x311, 0x313, 0x317, 0x320, 0x322, 0x327, 0x330, 0x336, 0x337, 0x338, 0x33a, 0x33b, 0x33c, 0x341, 0x342, 0x345, 0x346, 0x347, - 0x34a, 0x34c -}; + 0x34a, 0x34c}; static const uint8_t glyph_id_ofs_list_8[] = { 0, 0, 1, 2, 0, 3, 4, 5, @@ -74117,8 +74108,7 @@ static const uint8_t glyph_id_ofs_list_8[] = { 109, 110, 111, 0, 112, 0, 0, 0, 0, 0, 113, 114, 115, 0, 116, 117, 118, 119, 0, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 132 -}; + 125, 126, 127, 128, 129, 130, 131, 132}; static const uint16_t unicode_list_9[] = { 0x0, 0x1, 0x4, 0x5, 0x6, 0xe, 0xf, 0x12, @@ -74182,8 +74172,7 @@ static const uint16_t unicode_list_9[] = { 0x655, 0x657, 0x658, 0x659, 0x65a, 0x65b, 0x65f, 0x663, 0x665, 0x667, 0x66c, 0x66e, 0x66f, 0x674, 0x678, 0x67c, 0x689, 0x690, 0x6c7, 0x6d1, 0x702, 0x712, 0x713, 0x71c, - 0x790, 0x7af, 0x7ef, 0x7f5 -}; + 0x790, 0x7af, 0x7ef, 0x7f5}; static const uint8_t glyph_id_ofs_list_10[] = { 0, 1, 2, 3, 4, 5, 6, 7, @@ -74191,15 +74180,13 @@ static const uint8_t glyph_id_ofs_list_10[] = { 15, 0, 16, 17, 18, 19, 20, 21, 22, 23, 24, 0, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 0, - 36, 37, 38, 39, 40, 41, 42, 43 -}; + 36, 37, 38, 39, 40, 41, 42, 43}; static const uint16_t unicode_list_15[] = { 0x0, 0x5, 0x6, 0x8, 0xb, 0x14, 0x19, 0x20, 0x21, 0x29, 0x2a, 0x32, 0x37, 0x38, 0x39, 0x41, 0x44, 0x48, 0x49, 0x4b, 0x53, 0x57, 0xdc, 0xdd, - 0xde -}; + 0xde}; static const uint16_t unicode_list_17[] = { 0x0, 0x1, 0x2, 0x3, 0x5, 0x6, 0x7, 0x8, @@ -74218,8 +74205,7 @@ static const uint16_t unicode_list_17[] = { 0xfe, 0xff, 0x106, 0x113, 0x116, 0x119, 0x11a, 0x11c, 0x11d, 0x11f, 0x121, 0x123, 0x129, 0x12c, 0x12e, 0x132, 0x134, 0x13c, 0x13d, 0x141, 0x149, 0x14b, 0x158, 0x159, - 0x15c, 0x15f, 0x167, 0x17b, 0x213, 0x214, 0x215, 0x216 -}; + 0x15c, 0x15f, 0x167, 0x17b, 0x213, 0x214, 0x215, 0x216}; static const uint8_t glyph_id_ofs_list_19[] = { 0, 1, 2, 3, 4, 5, 6, 7, @@ -74242,8 +74228,7 @@ static const uint8_t glyph_id_ofs_list_19[] = { 80, 81, 82, 0, 83, 0, 84, 85, 86, 87, 0, 88, 0, 89, 90, 0, 0, 91, 92, 0, 93, 94, 95, 96, - 97, 98 -}; + 97, 98}; static const uint16_t unicode_list_20[] = { 0x0, 0x7, 0x8, 0x9, 0xf, 0x10, 0x12, 0x15, @@ -74270,15 +74255,13 @@ static const uint16_t unicode_list_20[] = { 0x2a2, 0x318, 0x344, 0x369, 0x3a4, 0x3b0, 0x418, 0x445, 0x45f, 0x460, 0x461, 0x462, 0x463, 0x464, 0x465, 0x466, 0x467, 0x468, 0x469, 0x46a, 0x46c, 0x46d, 0x46e, 0x46f, - 0x471 -}; + 0x471}; static const uint8_t glyph_id_ofs_list_22[] = { 0, 1, 2, 3, 4, 5, 6, 0, 7, 8, 9, 0, 0, 10, 11, 12, 13, 14, 0, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25 -}; + 20, 21, 22, 23, 24, 25}; static const uint8_t glyph_id_ofs_list_25[] = { 0, 1, 2, 0, 3, 4, 5, 6, @@ -74293,8 +74276,7 @@ static const uint8_t glyph_id_ofs_list_25[] = { 62, 63, 64, 65, 66, 67, 68, 69, 70, 0, 71, 72, 73, 74, 75, 0, 0, 76, 0, 0, 0, 0, 0, 0, - 0, 0, 77 -}; + 0, 0, 77}; static const uint8_t glyph_id_ofs_list_26[] = { 0, 1, 2, 3, 0, 4, 5, 6, @@ -74309,8 +74291,7 @@ static const uint8_t glyph_id_ofs_list_26[] = { 0, 53, 54, 55, 56, 57, 58, 0, 0, 0, 0, 59, 60, 61, 0, 62, 63, 0, 64, 0, 65, 66, 67, 68, - 69, 70, 0, 71, 72, 73 -}; + 69, 70, 0, 71, 72, 73}; static const uint16_t unicode_list_27[] = { 0x0, 0x4, 0x5, 0xb, 0xf, 0x11, 0x12, 0x14, @@ -74328,21 +74309,18 @@ static const uint16_t unicode_list_27[] = { 0x12c, 0x135, 0x13b, 0x13d, 0x141, 0x142, 0x144, 0x148, 0x150, 0x153, 0x15b, 0x15d, 0x15f, 0x162, 0x164, 0x196, 0x197, 0x199, 0x19a, 0x19b, 0x19c, 0x19d, 0x1a3, 0x1a5, - 0x1a6 -}; + 0x1a6}; static const uint8_t glyph_id_ofs_list_29[] = { 0, 1, 0, 2, 3, 4, 0, 5, 6, 0, 7, 8, 9, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, - 19, 20, 21, 22 -}; + 19, 20, 21, 22}; static const uint16_t unicode_list_30[] = { 0x0, 0x3, 0x4, 0x5, 0x7, 0xa, 0xb, 0xc, 0x10, 0x11, 0x19, 0x1a, 0x3f, 0x42, 0x60, 0x86, - 0x87 -}; + 0x87}; static const uint8_t glyph_id_ofs_list_31[] = { 0, 0, 1, 0, 2, 3, 4, 5, @@ -74353,8 +74331,7 @@ static const uint8_t glyph_id_ofs_list_31[] = { 30, 0, 31, 0, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 43, 0, 0, 44 -}; + 0, 0, 43, 0, 0, 44}; static const uint8_t glyph_id_ofs_list_32[] = { 0, 1, 2, 3, 4, 5, 0, 6, @@ -74364,8 +74341,7 @@ static const uint8_t glyph_id_ofs_list_32[] = { 29, 0, 0, 30, 31, 32, 33, 34, 0, 0, 35, 36, 37, 0, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 0, 50, 51 -}; + 48, 49, 0, 50, 51}; static const uint16_t unicode_list_33[] = { 0x0, 0x1, 0x6, 0x7, 0x8, 0xa, 0xc, 0x10, @@ -74373,8 +74349,7 @@ static const uint16_t unicode_list_33[] = { 0x2f, 0x31, 0x36, 0x3b, 0x3d, 0x3f, 0x49, 0x4b, 0x53, 0x58, 0x5f, 0x63, 0x6f, 0x73, 0x7f, 0x82, 0x8b, 0x8c, 0x91, 0x92, 0x93, 0x94, 0x95, 0x97, - 0x98, 0x99, 0x9d, 0x9f, 0xa1, 0xa4, 0x1cc -}; + 0x98, 0x99, 0x9d, 0x9f, 0xa1, 0xa4, 0x1cc}; static const uint8_t glyph_id_ofs_list_34[] = { 0, 0, 1, 2, 0, 0, 3, 4, @@ -74389,8 +74364,7 @@ static const uint8_t glyph_id_ofs_list_34[] = { 50, 0, 0, 51, 52, 53, 54, 55, 56, 57, 0, 0, 58, 59, 60, 61, 62, 63, 64, 0, 0, 65, 66, 67, - 68, 0, 0, 69 -}; + 68, 0, 0, 69}; static const uint8_t glyph_id_ofs_list_35[] = { 0, 1, 2, 3, 4, 0, 5, 6, @@ -74402,8 +74376,7 @@ static const uint8_t glyph_id_ofs_list_35[] = { 39, 0, 40, 0, 0, 0, 41, 0, 42, 43, 0, 44, 45, 46, 0, 47, 0, 0, 0, 0, 48, 49, 0, 50, - 51, 52, 53, 54, 55, 56, 57 -}; + 51, 52, 53, 54, 55, 56, 57}; static const uint16_t unicode_list_36[] = { 0x0, 0x1, 0x3, 0xe, 0xf, 0x12, 0x17, 0x18, @@ -74415,1166 +74388,1049 @@ static const uint16_t unicode_list_36[] = { 0xa9, 0xb0, 0xb2, 0xbc, 0xbf, 0xc7, 0xc9, 0xcb, 0xcd, 0xce, 0xd4, 0xe0, 0xe1, 0x10f, 0x110, 0x113, 0x114, 0x115, 0x116, 0x117, 0x118, 0x119, 0x11a, 0x11b, - 0x11c, 0x129, 0x12a, 0x12b, 0x12f, 0x130 -}; + 0x11c, 0x129, 0x12a, 0x12b, 0x12f, 0x130}; /*Collect the unicode lists and glyph_id offsets*/ static const lv_font_fmt_txt_cmap_t cmaps[] = -{ { - .range_start = 32, .range_length = 95, .glyph_id_start = 1, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 19968, .range_length = 248, .glyph_id_start = 96, - .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_1, .list_length = 248, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL - }, - { - .range_start = 20219, .range_length = 1254, .glyph_id_start = 243, - .unicode_list = unicode_list_2, .glyph_id_ofs_list = NULL, .list_length = 486, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY - }, - { - .range_start = 21475, .range_length = 253, .glyph_id_start = 729, - .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_3, .list_length = 253, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL - }, - { - .range_start = 21733, .range_length = 10679, .glyph_id_start = 887, - .unicode_list = unicode_list_4, .glyph_id_ofs_list = NULL, .list_length = 3401, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY - }, - { - .range_start = 32415, .range_length = 127, .glyph_id_start = 4288, - .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_5, .list_length = 127, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL - }, - { - .range_start = 32543, .range_length = 24, .glyph_id_start = 4405, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 32568, .range_length = 845, .glyph_id_start = 4429, - .unicode_list = unicode_list_7, .glyph_id_ofs_list = NULL, .list_length = 330, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY - }, - { - .range_start = 33416, .range_length = 232, .glyph_id_start = 4759, - .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_8, .list_length = 232, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL - }, - { - .range_start = 33655, .range_length = 2038, .glyph_id_start = 4892, - .unicode_list = unicode_list_9, .glyph_id_ofs_list = NULL, .list_length = 492, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY - }, - { - .range_start = 35744, .range_length = 48, .glyph_id_start = 5384, - .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_10, .list_length = 48, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL - }, - { - .range_start = 35793, .range_length = 25, .glyph_id_start = 5428, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 35819, .range_length = 30, .glyph_id_start = 5453, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 35850, .range_length = 20, .glyph_id_start = 5483, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 35871, .range_length = 25, .glyph_id_start = 5503, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 35905, .range_length = 223, .glyph_id_start = 5528, - .unicode_list = unicode_list_15, .glyph_id_ofs_list = NULL, .list_length = 25, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY - }, - { - .range_start = 36129, .range_length = 48, .glyph_id_start = 5553, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 36179, .range_length = 535, .glyph_id_start = 5601, - .unicode_list = unicode_list_17, .glyph_id_ofs_list = NULL, .list_length = 136, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY - }, - { - .range_start = 36715, .range_length = 21, .glyph_id_start = 5737, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 36737, .range_length = 162, .glyph_id_start = 5758, - .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_19, .list_length = 162, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL - }, - { - .range_start = 36902, .range_length = 1138, .glyph_id_start = 5857, - .unicode_list = unicode_list_20, .glyph_id_ofs_list = NULL, .list_length = 193, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY - }, - { - .range_start = 38041, .range_length = 46, .glyph_id_start = 6050, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 38088, .range_length = 30, .glyph_id_start = 6096, - .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_22, .list_length = 30, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL - }, - { - .range_start = 38119, .range_length = 20, .glyph_id_start = 6122, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 38140, .range_length = 32, .glyph_id_start = 6142, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 38173, .range_length = 99, .glyph_id_start = 6174, - .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_25, .list_length = 99, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL - }, - { - .range_start = 38376, .range_length = 102, .glyph_id_start = 6252, - .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_26, .list_length = 102, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL - }, - { - .range_start = 38480, .range_length = 423, .glyph_id_start = 6326, - .unicode_list = unicode_list_27, .glyph_id_ofs_list = NULL, .list_length = 121, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY - }, - { - .range_start = 39029, .range_length = 22, .glyph_id_start = 6447, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 39052, .range_length = 28, .glyph_id_start = 6469, - .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_29, .list_length = 28, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL - }, - { - .range_start = 39118, .range_length = 136, .glyph_id_start = 6492, - .unicode_list = unicode_list_30, .glyph_id_ofs_list = NULL, .list_length = 17, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY - }, - { - .range_start = 39267, .range_length = 70, .glyph_id_start = 6509, - .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_31, .list_length = 70, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL - }, - { - .range_start = 39532, .range_length = 61, .glyph_id_start = 6554, - .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_32, .list_length = 61, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL - }, - { - .range_start = 39600, .range_length = 461, .glyph_id_start = 6606, - .unicode_list = unicode_list_33, .glyph_id_ofs_list = NULL, .list_length = 47, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY - }, - { - .range_start = 40063, .range_length = 100, .glyph_id_start = 6653, - .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_34, .list_length = 100, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL - }, - { - .range_start = 40479, .range_length = 79, .glyph_id_start = 6723, - .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_35, .list_length = 79, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL - }, - { - .range_start = 40560, .range_length = 305, .glyph_id_start = 6781, - .unicode_list = unicode_list_36, .glyph_id_ofs_list = NULL, .list_length = 78, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY - } -}; + {.range_start = 32, .range_length = 95, .glyph_id_start = 1, .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY}, + {.range_start = 19968, .range_length = 248, .glyph_id_start = 96, .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_1, .list_length = 248, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL}, + {.range_start = 20219, .range_length = 1254, .glyph_id_start = 243, .unicode_list = unicode_list_2, .glyph_id_ofs_list = NULL, .list_length = 486, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY}, + {.range_start = 21475, .range_length = 253, .glyph_id_start = 729, .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_3, .list_length = 253, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL}, + {.range_start = 21733, .range_length = 10679, .glyph_id_start = 887, .unicode_list = unicode_list_4, .glyph_id_ofs_list = NULL, .list_length = 3401, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY}, + {.range_start = 32415, .range_length = 127, .glyph_id_start = 4288, .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_5, .list_length = 127, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL}, + {.range_start = 32543, .range_length = 24, .glyph_id_start = 4405, .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY}, + {.range_start = 32568, .range_length = 845, .glyph_id_start = 4429, .unicode_list = unicode_list_7, .glyph_id_ofs_list = NULL, .list_length = 330, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY}, + {.range_start = 33416, .range_length = 232, .glyph_id_start = 4759, .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_8, .list_length = 232, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL}, + {.range_start = 33655, .range_length = 2038, .glyph_id_start = 4892, .unicode_list = unicode_list_9, .glyph_id_ofs_list = NULL, .list_length = 492, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY}, + {.range_start = 35744, .range_length = 48, .glyph_id_start = 5384, .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_10, .list_length = 48, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL}, + {.range_start = 35793, .range_length = 25, .glyph_id_start = 5428, .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY}, + {.range_start = 35819, .range_length = 30, .glyph_id_start = 5453, .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY}, + {.range_start = 35850, .range_length = 20, .glyph_id_start = 5483, .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY}, + {.range_start = 35871, .range_length = 25, .glyph_id_start = 5503, .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY}, + {.range_start = 35905, .range_length = 223, .glyph_id_start = 5528, .unicode_list = unicode_list_15, .glyph_id_ofs_list = NULL, .list_length = 25, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY}, + {.range_start = 36129, .range_length = 48, .glyph_id_start = 5553, .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY}, + {.range_start = 36179, .range_length = 535, .glyph_id_start = 5601, .unicode_list = unicode_list_17, .glyph_id_ofs_list = NULL, .list_length = 136, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY}, + {.range_start = 36715, .range_length = 21, .glyph_id_start = 5737, .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY}, + {.range_start = 36737, .range_length = 162, .glyph_id_start = 5758, .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_19, .list_length = 162, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL}, + {.range_start = 36902, .range_length = 1138, .glyph_id_start = 5857, .unicode_list = unicode_list_20, .glyph_id_ofs_list = NULL, .list_length = 193, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY}, + {.range_start = 38041, .range_length = 46, .glyph_id_start = 6050, .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY}, + {.range_start = 38088, .range_length = 30, .glyph_id_start = 6096, .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_22, .list_length = 30, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL}, + {.range_start = 38119, .range_length = 20, .glyph_id_start = 6122, .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY}, + {.range_start = 38140, .range_length = 32, .glyph_id_start = 6142, .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY}, + {.range_start = 38173, .range_length = 99, .glyph_id_start = 6174, .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_25, .list_length = 99, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL}, + {.range_start = 38376, .range_length = 102, .glyph_id_start = 6252, .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_26, .list_length = 102, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL}, + {.range_start = 38480, .range_length = 423, .glyph_id_start = 6326, .unicode_list = unicode_list_27, .glyph_id_ofs_list = NULL, .list_length = 121, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY}, + {.range_start = 39029, .range_length = 22, .glyph_id_start = 6447, .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY}, + {.range_start = 39052, .range_length = 28, .glyph_id_start = 6469, .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_29, .list_length = 28, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL}, + {.range_start = 39118, .range_length = 136, .glyph_id_start = 6492, .unicode_list = unicode_list_30, .glyph_id_ofs_list = NULL, .list_length = 17, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY}, + {.range_start = 39267, .range_length = 70, .glyph_id_start = 6509, .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_31, .list_length = 70, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL}, + {.range_start = 39532, .range_length = 61, .glyph_id_start = 6554, .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_32, .list_length = 61, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL}, + {.range_start = 39600, .range_length = 461, .glyph_id_start = 6606, .unicode_list = unicode_list_33, .glyph_id_ofs_list = NULL, .list_length = 47, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY}, + {.range_start = 40063, .range_length = 100, .glyph_id_start = 6653, .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_34, .list_length = 100, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL}, + {.range_start = 40479, .range_length = 79, .glyph_id_start = 6723, .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_35, .list_length = 79, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL}, + {.range_start = 40560, .range_length = 305, .glyph_id_start = 6781, .unicode_list = unicode_list_36, .glyph_id_ofs_list = NULL, .list_length = 78, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY}}; /*----------------- * KERNING *----------------*/ - /*Pair left and right glyphs for kerning*/ static const uint16_t kern_pair_glyph_ids[] = -{ - 3, 13, - 3, 15, - 3, 34, - 3, 43, - 3, 52, - 3, 57, - 3, 68, - 3, 69, - 3, 70, - 3, 80, - 3, 82, - 3, 84, - 8, 13, - 8, 15, - 8, 34, - 8, 43, - 8, 52, - 8, 57, - 8, 68, - 8, 69, - 8, 70, - 8, 80, - 8, 82, - 8, 84, - 9, 43, - 9, 75, - 13, 3, - 13, 8, - 13, 11, - 13, 53, - 13, 54, - 13, 55, - 13, 56, - 13, 58, - 13, 68, - 13, 69, - 13, 70, - 13, 75, - 13, 80, - 13, 82, - 13, 85, - 13, 87, - 13, 88, - 13, 90, - 14, 43, - 14, 52, - 14, 53, - 14, 55, - 14, 56, - 14, 57, - 14, 58, - 14, 59, - 14, 85, - 14, 87, - 14, 89, - 15, 3, - 15, 8, - 15, 11, - 15, 53, - 15, 54, - 15, 55, - 15, 56, - 15, 58, - 15, 68, - 15, 69, - 15, 70, - 15, 75, - 15, 80, - 15, 82, - 15, 85, - 15, 87, - 15, 88, - 15, 90, - 16, 34, - 16, 36, - 16, 40, - 16, 43, - 16, 48, - 16, 50, - 16, 66, - 16, 68, - 16, 69, - 16, 70, - 16, 72, - 16, 74, - 16, 75, - 16, 80, - 16, 82, - 16, 85, - 16, 86, - 27, 11, - 27, 58, - 27, 75, - 28, 11, - 28, 58, - 28, 75, - 34, 3, - 34, 8, - 34, 11, - 34, 32, - 34, 34, - 34, 36, - 34, 40, - 34, 48, - 34, 50, - 34, 53, - 34, 54, - 34, 55, - 34, 57, - 34, 58, - 34, 59, - 34, 61, - 34, 66, - 34, 71, - 34, 84, - 34, 85, - 34, 86, - 34, 87, - 34, 88, - 34, 89, - 34, 90, - 35, 11, - 35, 43, - 35, 52, - 35, 53, - 35, 55, - 35, 56, - 35, 57, - 35, 58, - 35, 59, - 35, 85, - 35, 87, - 35, 88, - 35, 89, - 35, 90, - 36, 14, - 36, 36, - 36, 40, - 36, 43, - 36, 48, - 36, 50, - 36, 52, - 36, 53, - 36, 54, - 36, 55, - 36, 56, - 36, 57, - 36, 58, - 36, 59, - 36, 72, - 36, 85, - 36, 86, - 36, 87, - 36, 88, - 36, 90, - 37, 11, - 37, 16, - 37, 34, - 37, 43, - 37, 53, - 37, 55, - 37, 56, - 37, 57, - 37, 58, - 37, 59, - 37, 89, - 37, 91, - 38, 68, - 38, 69, - 38, 70, - 38, 80, - 38, 82, - 38, 85, - 38, 87, - 38, 89, - 38, 90, - 39, 13, - 39, 15, - 39, 16, - 39, 34, - 39, 36, - 39, 40, - 39, 43, - 39, 48, - 39, 50, - 39, 52, - 39, 55, - 39, 56, - 39, 57, - 39, 59, - 39, 66, - 39, 68, - 39, 69, - 39, 70, - 39, 72, - 39, 78, - 39, 79, - 39, 80, - 39, 81, - 39, 82, - 39, 83, - 39, 84, - 39, 85, - 39, 86, - 39, 87, - 39, 88, - 39, 89, - 39, 90, - 39, 91, - 40, 11, - 40, 34, - 40, 53, - 40, 55, - 40, 56, - 43, 13, - 43, 15, - 43, 43, - 44, 3, - 44, 8, - 44, 11, - 44, 14, - 44, 32, - 44, 34, - 44, 36, - 44, 40, - 44, 48, - 44, 50, - 44, 52, - 44, 53, - 44, 54, - 44, 55, - 44, 56, - 44, 58, - 44, 68, - 44, 69, - 44, 70, - 44, 75, - 44, 80, - 44, 82, - 44, 85, - 44, 86, - 44, 87, - 44, 88, - 44, 89, - 44, 90, - 44, 91, - 45, 3, - 45, 8, - 45, 11, - 45, 14, - 45, 32, - 45, 34, - 45, 36, - 45, 40, - 45, 48, - 45, 50, - 45, 52, - 45, 53, - 45, 54, - 45, 55, - 45, 56, - 45, 58, - 45, 61, - 45, 68, - 45, 69, - 45, 70, - 45, 71, - 45, 72, - 45, 80, - 45, 82, - 45, 85, - 45, 86, - 45, 87, - 45, 88, - 45, 90, - 48, 11, - 48, 16, - 48, 34, - 48, 43, - 48, 53, - 48, 55, - 48, 56, - 48, 57, - 48, 58, - 48, 59, - 48, 89, - 48, 91, - 49, 13, - 49, 14, - 49, 15, - 49, 16, - 49, 34, - 49, 43, - 49, 52, - 49, 53, - 49, 57, - 49, 58, - 49, 59, - 49, 66, - 49, 68, - 49, 69, - 49, 70, - 49, 72, - 49, 80, - 49, 82, - 49, 84, - 49, 89, - 49, 91, - 50, 11, - 50, 16, - 50, 34, - 50, 43, - 50, 53, - 50, 55, - 50, 56, - 50, 57, - 50, 58, - 50, 59, - 50, 89, - 50, 91, - 51, 11, - 51, 14, - 51, 34, - 51, 43, - 51, 52, - 51, 53, - 51, 55, - 51, 56, - 51, 57, - 51, 59, - 51, 66, - 51, 68, - 51, 69, - 51, 70, - 51, 72, - 51, 80, - 51, 82, - 51, 89, - 51, 91, - 52, 11, - 52, 14, - 52, 43, - 52, 52, - 52, 53, - 52, 58, - 52, 85, - 53, 13, - 53, 14, - 53, 15, - 53, 16, - 53, 27, - 53, 28, - 53, 34, - 53, 36, - 53, 40, - 53, 43, - 53, 48, - 53, 50, - 53, 52, - 53, 57, - 53, 58, - 53, 59, - 53, 66, - 53, 68, - 53, 69, - 53, 70, - 53, 71, - 53, 72, - 53, 78, - 53, 79, - 53, 80, - 53, 81, - 53, 82, - 53, 83, - 53, 84, - 53, 85, - 53, 86, - 53, 87, - 53, 88, - 53, 89, - 53, 90, - 53, 91, - 54, 13, - 54, 15, - 54, 16, - 54, 34, - 54, 43, - 54, 52, - 54, 55, - 54, 57, - 54, 58, - 54, 66, - 54, 72, - 54, 84, - 54, 89, - 55, 13, - 55, 14, - 55, 15, - 55, 16, - 55, 34, - 55, 36, - 55, 40, - 55, 43, - 55, 48, - 55, 50, - 55, 52, - 55, 54, - 55, 55, - 55, 59, - 55, 66, - 55, 68, - 55, 69, - 55, 70, - 55, 72, - 55, 78, - 55, 79, - 55, 80, - 55, 81, - 55, 82, - 55, 83, - 55, 84, - 55, 86, - 55, 87, - 55, 88, - 55, 89, - 55, 90, - 55, 91, - 56, 13, - 56, 14, - 56, 15, - 56, 16, - 56, 36, - 56, 40, - 56, 43, - 56, 48, - 56, 50, - 56, 52, - 56, 59, - 56, 66, - 56, 72, - 56, 91, - 57, 3, - 57, 8, - 57, 11, - 57, 14, - 57, 34, - 57, 36, - 57, 40, - 57, 48, - 57, 50, - 57, 52, - 57, 53, - 57, 54, - 57, 66, - 57, 68, - 57, 69, - 57, 70, - 57, 71, - 57, 80, - 57, 82, - 57, 85, - 57, 86, - 57, 87, - 57, 88, - 57, 89, - 57, 90, - 57, 91, - 58, 13, - 58, 14, - 58, 15, - 58, 16, - 58, 27, - 58, 28, - 58, 32, - 58, 34, - 58, 36, - 58, 40, - 58, 43, - 58, 48, - 58, 50, - 58, 52, - 58, 53, - 58, 54, - 58, 59, - 58, 66, - 58, 68, - 58, 69, - 58, 70, - 58, 72, - 58, 78, - 58, 79, - 58, 80, - 58, 81, - 58, 82, - 58, 83, - 58, 84, - 58, 85, - 58, 86, - 58, 87, - 58, 88, - 58, 89, - 58, 90, - 58, 91, - 59, 14, - 59, 34, - 59, 36, - 59, 40, - 59, 43, - 59, 48, - 59, 50, - 59, 52, - 59, 54, - 59, 55, - 59, 56, - 59, 58, - 59, 59, - 59, 66, - 59, 68, - 59, 69, - 59, 70, - 59, 71, - 59, 72, - 59, 80, - 59, 82, - 59, 85, - 59, 86, - 59, 87, - 59, 88, - 59, 89, - 59, 90, - 60, 43, - 60, 75, - 61, 53, - 61, 54, - 61, 55, - 61, 56, - 61, 58, - 61, 72, - 61, 75, - 61, 87, - 61, 88, - 61, 90, - 66, 11, - 66, 32, - 66, 53, - 66, 55, - 66, 56, - 66, 58, - 66, 85, - 67, 3, - 67, 8, - 67, 11, - 67, 13, - 67, 14, - 67, 15, - 67, 32, - 67, 53, - 67, 55, - 67, 57, - 67, 58, - 67, 61, - 67, 66, - 67, 85, - 67, 87, - 67, 88, - 67, 89, - 67, 90, - 67, 91, - 68, 14, - 68, 53, - 68, 55, - 68, 58, - 68, 66, - 68, 68, - 68, 69, - 68, 70, - 68, 72, - 68, 80, - 68, 82, - 68, 85, - 68, 87, - 68, 88, - 68, 89, - 68, 90, - 70, 11, - 70, 14, - 70, 32, - 70, 43, - 70, 52, - 70, 53, - 70, 55, - 70, 56, - 70, 58, - 70, 61, - 70, 66, - 70, 72, - 70, 85, - 70, 87, - 70, 88, - 70, 89, - 70, 90, - 71, 2, - 71, 3, - 71, 8, - 71, 10, - 71, 13, - 71, 14, - 71, 15, - 71, 16, - 71, 32, - 71, 53, - 71, 55, - 71, 56, - 71, 57, - 71, 58, - 71, 61, - 71, 62, - 71, 66, - 71, 68, - 71, 69, - 71, 70, - 71, 72, - 71, 75, - 71, 80, - 71, 82, - 71, 84, - 71, 87, - 71, 89, - 71, 91, - 71, 94, - 72, 10, - 72, 11, - 72, 16, - 72, 32, - 72, 53, - 72, 58, - 72, 62, - 72, 66, - 72, 68, - 72, 69, - 72, 70, - 72, 75, - 72, 80, - 72, 82, - 72, 87, - 72, 88, - 72, 90, - 72, 91, - 72, 94, - 73, 11, - 73, 32, - 73, 53, - 73, 55, - 73, 58, - 76, 11, - 76, 13, - 76, 14, - 76, 15, - 76, 27, - 76, 28, - 76, 32, - 76, 53, - 76, 58, - 76, 66, - 76, 68, - 76, 69, - 76, 70, - 76, 72, - 76, 75, - 76, 80, - 76, 82, - 76, 85, - 76, 86, - 76, 89, - 76, 91, - 77, 75, - 78, 11, - 78, 32, - 78, 53, - 78, 55, - 78, 58, - 79, 11, - 79, 32, - 79, 53, - 79, 55, - 79, 58, - 80, 3, - 80, 8, - 80, 11, - 80, 13, - 80, 14, - 80, 15, - 80, 32, - 80, 53, - 80, 55, - 80, 57, - 80, 58, - 80, 61, - 80, 66, - 80, 85, - 80, 87, - 80, 88, - 80, 89, - 80, 90, - 80, 91, - 81, 3, - 81, 8, - 81, 11, - 81, 13, - 81, 14, - 81, 15, - 81, 32, - 81, 53, - 81, 55, - 81, 57, - 81, 58, - 81, 61, - 81, 66, - 81, 85, - 81, 87, - 81, 88, - 81, 89, - 81, 90, - 81, 91, - 82, 11, - 82, 53, - 82, 55, - 82, 58, - 83, 13, - 83, 14, - 83, 15, - 83, 16, - 83, 27, - 83, 28, - 83, 34, - 83, 43, - 83, 59, - 83, 61, - 83, 66, - 83, 68, - 83, 69, - 83, 70, - 83, 72, - 83, 80, - 83, 82, - 83, 84, - 83, 87, - 83, 88, - 83, 90, - 83, 91, - 84, 11, - 84, 14, - 84, 32, - 84, 53, - 84, 55, - 84, 58, - 84, 85, - 85, 13, - 85, 14, - 85, 15, - 85, 16, - 85, 27, - 85, 28, - 85, 32, - 85, 53, - 85, 58, - 85, 66, - 85, 68, - 85, 69, - 85, 70, - 85, 72, - 85, 80, - 85, 82, - 85, 84, - 85, 85, - 85, 89, - 86, 11, - 86, 53, - 86, 55, - 86, 58, - 87, 11, - 87, 13, - 87, 14, - 87, 15, - 87, 16, - 87, 34, - 87, 43, - 87, 53, - 87, 55, - 87, 58, - 87, 59, - 87, 66, - 87, 68, - 87, 69, - 87, 70, - 87, 75, - 87, 80, - 87, 82, - 87, 91, - 88, 11, - 88, 13, - 88, 15, - 88, 16, - 88, 34, - 88, 43, - 88, 53, - 88, 55, - 88, 57, - 88, 58, - 88, 66, - 88, 68, - 88, 69, - 88, 70, - 88, 75, - 88, 80, - 88, 82, - 88, 91, - 89, 2, - 89, 11, - 89, 13, - 89, 14, - 89, 15, - 89, 28, - 89, 36, - 89, 40, - 89, 48, - 89, 50, - 89, 52, - 89, 53, - 89, 55, - 89, 57, - 89, 58, - 89, 66, - 89, 68, - 89, 69, - 89, 70, - 89, 80, - 89, 82, - 89, 85, - 90, 13, - 90, 15, - 90, 16, - 90, 43, - 90, 53, - 90, 55, - 90, 57, - 90, 58, - 90, 66, - 90, 68, - 90, 69, - 90, 70, - 90, 75, - 90, 80, - 90, 82, - 90, 89, - 90, 91, - 91, 14, - 91, 53, - 91, 58, - 91, 66, - 91, 68, - 91, 69, - 91, 70, - 91, 72, - 91, 80, - 91, 82, - 91, 86, - 91, 87, - 91, 90, - 92, 43, - 92, 75 -}; + { + 3, 13, + 3, 15, + 3, 34, + 3, 43, + 3, 52, + 3, 57, + 3, 68, + 3, 69, + 3, 70, + 3, 80, + 3, 82, + 3, 84, + 8, 13, + 8, 15, + 8, 34, + 8, 43, + 8, 52, + 8, 57, + 8, 68, + 8, 69, + 8, 70, + 8, 80, + 8, 82, + 8, 84, + 9, 43, + 9, 75, + 13, 3, + 13, 8, + 13, 11, + 13, 53, + 13, 54, + 13, 55, + 13, 56, + 13, 58, + 13, 68, + 13, 69, + 13, 70, + 13, 75, + 13, 80, + 13, 82, + 13, 85, + 13, 87, + 13, 88, + 13, 90, + 14, 43, + 14, 52, + 14, 53, + 14, 55, + 14, 56, + 14, 57, + 14, 58, + 14, 59, + 14, 85, + 14, 87, + 14, 89, + 15, 3, + 15, 8, + 15, 11, + 15, 53, + 15, 54, + 15, 55, + 15, 56, + 15, 58, + 15, 68, + 15, 69, + 15, 70, + 15, 75, + 15, 80, + 15, 82, + 15, 85, + 15, 87, + 15, 88, + 15, 90, + 16, 34, + 16, 36, + 16, 40, + 16, 43, + 16, 48, + 16, 50, + 16, 66, + 16, 68, + 16, 69, + 16, 70, + 16, 72, + 16, 74, + 16, 75, + 16, 80, + 16, 82, + 16, 85, + 16, 86, + 27, 11, + 27, 58, + 27, 75, + 28, 11, + 28, 58, + 28, 75, + 34, 3, + 34, 8, + 34, 11, + 34, 32, + 34, 34, + 34, 36, + 34, 40, + 34, 48, + 34, 50, + 34, 53, + 34, 54, + 34, 55, + 34, 57, + 34, 58, + 34, 59, + 34, 61, + 34, 66, + 34, 71, + 34, 84, + 34, 85, + 34, 86, + 34, 87, + 34, 88, + 34, 89, + 34, 90, + 35, 11, + 35, 43, + 35, 52, + 35, 53, + 35, 55, + 35, 56, + 35, 57, + 35, 58, + 35, 59, + 35, 85, + 35, 87, + 35, 88, + 35, 89, + 35, 90, + 36, 14, + 36, 36, + 36, 40, + 36, 43, + 36, 48, + 36, 50, + 36, 52, + 36, 53, + 36, 54, + 36, 55, + 36, 56, + 36, 57, + 36, 58, + 36, 59, + 36, 72, + 36, 85, + 36, 86, + 36, 87, + 36, 88, + 36, 90, + 37, 11, + 37, 16, + 37, 34, + 37, 43, + 37, 53, + 37, 55, + 37, 56, + 37, 57, + 37, 58, + 37, 59, + 37, 89, + 37, 91, + 38, 68, + 38, 69, + 38, 70, + 38, 80, + 38, 82, + 38, 85, + 38, 87, + 38, 89, + 38, 90, + 39, 13, + 39, 15, + 39, 16, + 39, 34, + 39, 36, + 39, 40, + 39, 43, + 39, 48, + 39, 50, + 39, 52, + 39, 55, + 39, 56, + 39, 57, + 39, 59, + 39, 66, + 39, 68, + 39, 69, + 39, 70, + 39, 72, + 39, 78, + 39, 79, + 39, 80, + 39, 81, + 39, 82, + 39, 83, + 39, 84, + 39, 85, + 39, 86, + 39, 87, + 39, 88, + 39, 89, + 39, 90, + 39, 91, + 40, 11, + 40, 34, + 40, 53, + 40, 55, + 40, 56, + 43, 13, + 43, 15, + 43, 43, + 44, 3, + 44, 8, + 44, 11, + 44, 14, + 44, 32, + 44, 34, + 44, 36, + 44, 40, + 44, 48, + 44, 50, + 44, 52, + 44, 53, + 44, 54, + 44, 55, + 44, 56, + 44, 58, + 44, 68, + 44, 69, + 44, 70, + 44, 75, + 44, 80, + 44, 82, + 44, 85, + 44, 86, + 44, 87, + 44, 88, + 44, 89, + 44, 90, + 44, 91, + 45, 3, + 45, 8, + 45, 11, + 45, 14, + 45, 32, + 45, 34, + 45, 36, + 45, 40, + 45, 48, + 45, 50, + 45, 52, + 45, 53, + 45, 54, + 45, 55, + 45, 56, + 45, 58, + 45, 61, + 45, 68, + 45, 69, + 45, 70, + 45, 71, + 45, 72, + 45, 80, + 45, 82, + 45, 85, + 45, 86, + 45, 87, + 45, 88, + 45, 90, + 48, 11, + 48, 16, + 48, 34, + 48, 43, + 48, 53, + 48, 55, + 48, 56, + 48, 57, + 48, 58, + 48, 59, + 48, 89, + 48, 91, + 49, 13, + 49, 14, + 49, 15, + 49, 16, + 49, 34, + 49, 43, + 49, 52, + 49, 53, + 49, 57, + 49, 58, + 49, 59, + 49, 66, + 49, 68, + 49, 69, + 49, 70, + 49, 72, + 49, 80, + 49, 82, + 49, 84, + 49, 89, + 49, 91, + 50, 11, + 50, 16, + 50, 34, + 50, 43, + 50, 53, + 50, 55, + 50, 56, + 50, 57, + 50, 58, + 50, 59, + 50, 89, + 50, 91, + 51, 11, + 51, 14, + 51, 34, + 51, 43, + 51, 52, + 51, 53, + 51, 55, + 51, 56, + 51, 57, + 51, 59, + 51, 66, + 51, 68, + 51, 69, + 51, 70, + 51, 72, + 51, 80, + 51, 82, + 51, 89, + 51, 91, + 52, 11, + 52, 14, + 52, 43, + 52, 52, + 52, 53, + 52, 58, + 52, 85, + 53, 13, + 53, 14, + 53, 15, + 53, 16, + 53, 27, + 53, 28, + 53, 34, + 53, 36, + 53, 40, + 53, 43, + 53, 48, + 53, 50, + 53, 52, + 53, 57, + 53, 58, + 53, 59, + 53, 66, + 53, 68, + 53, 69, + 53, 70, + 53, 71, + 53, 72, + 53, 78, + 53, 79, + 53, 80, + 53, 81, + 53, 82, + 53, 83, + 53, 84, + 53, 85, + 53, 86, + 53, 87, + 53, 88, + 53, 89, + 53, 90, + 53, 91, + 54, 13, + 54, 15, + 54, 16, + 54, 34, + 54, 43, + 54, 52, + 54, 55, + 54, 57, + 54, 58, + 54, 66, + 54, 72, + 54, 84, + 54, 89, + 55, 13, + 55, 14, + 55, 15, + 55, 16, + 55, 34, + 55, 36, + 55, 40, + 55, 43, + 55, 48, + 55, 50, + 55, 52, + 55, 54, + 55, 55, + 55, 59, + 55, 66, + 55, 68, + 55, 69, + 55, 70, + 55, 72, + 55, 78, + 55, 79, + 55, 80, + 55, 81, + 55, 82, + 55, 83, + 55, 84, + 55, 86, + 55, 87, + 55, 88, + 55, 89, + 55, 90, + 55, 91, + 56, 13, + 56, 14, + 56, 15, + 56, 16, + 56, 36, + 56, 40, + 56, 43, + 56, 48, + 56, 50, + 56, 52, + 56, 59, + 56, 66, + 56, 72, + 56, 91, + 57, 3, + 57, 8, + 57, 11, + 57, 14, + 57, 34, + 57, 36, + 57, 40, + 57, 48, + 57, 50, + 57, 52, + 57, 53, + 57, 54, + 57, 66, + 57, 68, + 57, 69, + 57, 70, + 57, 71, + 57, 80, + 57, 82, + 57, 85, + 57, 86, + 57, 87, + 57, 88, + 57, 89, + 57, 90, + 57, 91, + 58, 13, + 58, 14, + 58, 15, + 58, 16, + 58, 27, + 58, 28, + 58, 32, + 58, 34, + 58, 36, + 58, 40, + 58, 43, + 58, 48, + 58, 50, + 58, 52, + 58, 53, + 58, 54, + 58, 59, + 58, 66, + 58, 68, + 58, 69, + 58, 70, + 58, 72, + 58, 78, + 58, 79, + 58, 80, + 58, 81, + 58, 82, + 58, 83, + 58, 84, + 58, 85, + 58, 86, + 58, 87, + 58, 88, + 58, 89, + 58, 90, + 58, 91, + 59, 14, + 59, 34, + 59, 36, + 59, 40, + 59, 43, + 59, 48, + 59, 50, + 59, 52, + 59, 54, + 59, 55, + 59, 56, + 59, 58, + 59, 59, + 59, 66, + 59, 68, + 59, 69, + 59, 70, + 59, 71, + 59, 72, + 59, 80, + 59, 82, + 59, 85, + 59, 86, + 59, 87, + 59, 88, + 59, 89, + 59, 90, + 60, 43, + 60, 75, + 61, 53, + 61, 54, + 61, 55, + 61, 56, + 61, 58, + 61, 72, + 61, 75, + 61, 87, + 61, 88, + 61, 90, + 66, 11, + 66, 32, + 66, 53, + 66, 55, + 66, 56, + 66, 58, + 66, 85, + 67, 3, + 67, 8, + 67, 11, + 67, 13, + 67, 14, + 67, 15, + 67, 32, + 67, 53, + 67, 55, + 67, 57, + 67, 58, + 67, 61, + 67, 66, + 67, 85, + 67, 87, + 67, 88, + 67, 89, + 67, 90, + 67, 91, + 68, 14, + 68, 53, + 68, 55, + 68, 58, + 68, 66, + 68, 68, + 68, 69, + 68, 70, + 68, 72, + 68, 80, + 68, 82, + 68, 85, + 68, 87, + 68, 88, + 68, 89, + 68, 90, + 70, 11, + 70, 14, + 70, 32, + 70, 43, + 70, 52, + 70, 53, + 70, 55, + 70, 56, + 70, 58, + 70, 61, + 70, 66, + 70, 72, + 70, 85, + 70, 87, + 70, 88, + 70, 89, + 70, 90, + 71, 2, + 71, 3, + 71, 8, + 71, 10, + 71, 13, + 71, 14, + 71, 15, + 71, 16, + 71, 32, + 71, 53, + 71, 55, + 71, 56, + 71, 57, + 71, 58, + 71, 61, + 71, 62, + 71, 66, + 71, 68, + 71, 69, + 71, 70, + 71, 72, + 71, 75, + 71, 80, + 71, 82, + 71, 84, + 71, 87, + 71, 89, + 71, 91, + 71, 94, + 72, 10, + 72, 11, + 72, 16, + 72, 32, + 72, 53, + 72, 58, + 72, 62, + 72, 66, + 72, 68, + 72, 69, + 72, 70, + 72, 75, + 72, 80, + 72, 82, + 72, 87, + 72, 88, + 72, 90, + 72, 91, + 72, 94, + 73, 11, + 73, 32, + 73, 53, + 73, 55, + 73, 58, + 76, 11, + 76, 13, + 76, 14, + 76, 15, + 76, 27, + 76, 28, + 76, 32, + 76, 53, + 76, 58, + 76, 66, + 76, 68, + 76, 69, + 76, 70, + 76, 72, + 76, 75, + 76, 80, + 76, 82, + 76, 85, + 76, 86, + 76, 89, + 76, 91, + 77, 75, + 78, 11, + 78, 32, + 78, 53, + 78, 55, + 78, 58, + 79, 11, + 79, 32, + 79, 53, + 79, 55, + 79, 58, + 80, 3, + 80, 8, + 80, 11, + 80, 13, + 80, 14, + 80, 15, + 80, 32, + 80, 53, + 80, 55, + 80, 57, + 80, 58, + 80, 61, + 80, 66, + 80, 85, + 80, 87, + 80, 88, + 80, 89, + 80, 90, + 80, 91, + 81, 3, + 81, 8, + 81, 11, + 81, 13, + 81, 14, + 81, 15, + 81, 32, + 81, 53, + 81, 55, + 81, 57, + 81, 58, + 81, 61, + 81, 66, + 81, 85, + 81, 87, + 81, 88, + 81, 89, + 81, 90, + 81, 91, + 82, 11, + 82, 53, + 82, 55, + 82, 58, + 83, 13, + 83, 14, + 83, 15, + 83, 16, + 83, 27, + 83, 28, + 83, 34, + 83, 43, + 83, 59, + 83, 61, + 83, 66, + 83, 68, + 83, 69, + 83, 70, + 83, 72, + 83, 80, + 83, 82, + 83, 84, + 83, 87, + 83, 88, + 83, 90, + 83, 91, + 84, 11, + 84, 14, + 84, 32, + 84, 53, + 84, 55, + 84, 58, + 84, 85, + 85, 13, + 85, 14, + 85, 15, + 85, 16, + 85, 27, + 85, 28, + 85, 32, + 85, 53, + 85, 58, + 85, 66, + 85, 68, + 85, 69, + 85, 70, + 85, 72, + 85, 80, + 85, 82, + 85, 84, + 85, 85, + 85, 89, + 86, 11, + 86, 53, + 86, 55, + 86, 58, + 87, 11, + 87, 13, + 87, 14, + 87, 15, + 87, 16, + 87, 34, + 87, 43, + 87, 53, + 87, 55, + 87, 58, + 87, 59, + 87, 66, + 87, 68, + 87, 69, + 87, 70, + 87, 75, + 87, 80, + 87, 82, + 87, 91, + 88, 11, + 88, 13, + 88, 15, + 88, 16, + 88, 34, + 88, 43, + 88, 53, + 88, 55, + 88, 57, + 88, 58, + 88, 66, + 88, 68, + 88, 69, + 88, 70, + 88, 75, + 88, 80, + 88, 82, + 88, 91, + 89, 2, + 89, 11, + 89, 13, + 89, 14, + 89, 15, + 89, 28, + 89, 36, + 89, 40, + 89, 48, + 89, 50, + 89, 52, + 89, 53, + 89, 55, + 89, 57, + 89, 58, + 89, 66, + 89, 68, + 89, 69, + 89, 70, + 89, 80, + 89, 82, + 89, 85, + 90, 13, + 90, 15, + 90, 16, + 90, 43, + 90, 53, + 90, 55, + 90, 57, + 90, 58, + 90, 66, + 90, 68, + 90, 69, + 90, 70, + 90, 75, + 90, 80, + 90, 82, + 90, 89, + 90, 91, + 91, 14, + 91, 53, + 91, 58, + 91, 66, + 91, 68, + 91, 69, + 91, 70, + 91, 72, + 91, 80, + 91, 82, + 91, 86, + 91, 87, + 91, 90, + 92, 43, + 92, 75}; /* Kerning between the respective left and right glyphs * 4.4 format which needs to scaled with `kern_scale`*/ static const int8_t kern_pair_values[] = -{ - -33, -33, -16, -27, -3, -3, -8, -8, - -8, -8, -8, -6, -33, -33, -16, -27, - -3, -3, -8, -8, -8, -8, -8, -6, - -6, 23, -27, -27, -39, -28, -6, -19, - -10, -26, -3, -3, -3, 7, -3, -3, - -13, -10, -6, -6, -6, -5, -14, -5, - -3, -8, -19, -6, -7, -2, -4, -27, - -27, -39, -28, -6, -19, -10, -26, -3, - -3, -3, 7, -3, -3, -13, -10, -6, - -6, -12, -3, -3, -23, -3, -3, -7, - -9, -9, -9, -3, 7, 7, -9, -9, - 3, -6, -14, -7, 1, -14, -7, 1, - -16, -16, -27, -7, -2, -3, -3, -3, - -3, -16, -4, -4, 1, -4, -2, -12, - 7, -3, 7, -4, -2, -2, -1, -1, - -2, -9, -5, -4, -7, -2, -1, -1, - -4, -1, -3, -4, -3, -3, -4, -7, - -8, -8, -3, -8, -8, -7, -5, -4, - -1, -1, -1, -2, -3, -6, -8, -3, - -4, -3, -4, -10, -5, -3, -11, -7, - -3, -2, -5, -6, -6, -4, -2, -3, - -3, -3, -3, -3, -7, -3, -9, -3, - -21, -21, -20, -11, -3, -3, -40, -3, - -3, -6, 1, 1, -7, -9, -10, -4, - -4, -4, -7, -6, -6, -4, -6, -4, - -6, -6, -3, -5, -6, -5, -7, -5, - -8, -8, -1, -6, -4, -1, -7, -7, - -12, -6, -6, -12, -8, -2, -3, -6, - -6, -6, -6, -3, -5, -4, -4, -3, - -5, -2, -2, -2, -3, -2, -2, -9, - -4, -6, -5, -5, -6, -4, -25, -25, - -44, -15, -9, 1, -7, -7, -7, -7, - -6, -34, -8, -22, -16, -22, -23, -3, - -3, -3, -4, -1, -3, -3, -6, -3, - -10, -10, -10, -10, -5, -3, -11, -7, - -3, -2, -5, -6, -6, -4, -2, -32, - -9, -32, -22, -14, -42, -3, -7, -7, - -3, -22, -12, -7, -7, -7, -9, -7, - -7, -3, -4, -6, -10, -5, -3, -11, - -7, -3, -2, -5, -6, -6, -4, -2, - -3, -9, -1, -5, -4, -4, 2, 2, - -1, -3, -1, -3, -3, -3, -1, -3, - -3, -2, -2, -5, 4, -4, -4, -6, - -4, -7, -30, -21, -30, -26, -6, -6, - -12, -7, -7, -36, -7, -7, -11, -6, - -4, -15, -21, -19, -19, -19, -5, -21, - -13, -13, -19, -13, -19, -13, -17, -5, - -13, -9, -10, -11, -9, -22, -5, -5, - -9, -5, -14, -3, -1, -3, -4, -1, - -3, -1, -2, -19, -5, -19, -13, -4, - -3, -3, -21, -3, -3, -3, -3, 3, - -5, -6, -4, -4, -4, -6, -6, -6, - -4, -6, -4, -6, -4, -9, -3, -3, - -4, -3, -7, -10, -3, -10, -8, -2, - -2, -19, -2, -2, -2, -2, -5, -4, - -3, -3, -3, -3, -8, 1, -5, -5, - -5, -5, -4, -6, -3, -3, -2, -2, - -2, -5, -2, -2, -5, -3, -5, -4, - -3, -5, -4, -26, -19, -26, -19, -7, - -7, -2, -4, -4, -4, -29, -4, -4, - -5, -4, -3, -7, -19, -12, -12, -12, - -17, -12, -12, -12, -12, -12, -12, -12, - -8, -10, -4, -7, -10, -4, -14, -10, - -2, -6, -6, -9, -6, -6, -9, -3, - -2, -2, -4, -5, -5, -6, -6, -6, - -6, -4, -6, -6, -4, -7, -5, -5, - -7, -5, -6, 23, -25, -8, -15, -8, - -21, 9, 21, -6, -3, 4, -15, -4, - -7, -5, -1, -7, -4, -8, -8, -7, - -3, 2, -3, -4, -16, -5, -1, -13, - -7, -4, -5, -1, -1, -5, -1, -2, - -6, -6, -4, -7, -3, -6, -6, -6, - -3, -6, -6, -3, 2, 2, 2, 2, - -10, 3, -2, -6, -6, -7, -5, -3, - -7, -6, -4, -3, -3, 1, 1, -2, - 1, 4, 12, 12, 14, -14, -4, -14, - -4, 7, 13, 19, 13, 9, 17, 18, - 14, -6, -3, -3, -3, -4, -3, -3, - -3, -1, 4, -1, -4, 14, 4, -9, - 14, -10, -7, -4, 4, -5, -4, -4, - -4, 10, -4, -4, -1, -1, 4, -4, - 4, -10, -2, -7, -3, -5, -6, 4, - -13, 4, 4, 4, -4, -10, -3, -3, - -5, -5, -5, -3, -3, -5, -5, -6, - -4, -2, -2, 2, -10, -2, -7, -3, - -5, -10, -2, -7, -3, -5, -8, -8, - -7, -3, 2, -3, -4, -16, -5, -1, - -13, -7, -4, -5, -1, -1, -5, -1, - -2, -8, -8, -7, -3, 2, -3, -4, - -16, -5, -1, -13, -7, -4, -5, -1, - -1, -5, -1, -2, -7, -6, -4, -9, - -16, -7, -16, -10, 7, 7, -4, -16, - -3, 4, -7, -3, -3, -3, -3, -3, - -3, -1, 7, 5, 7, -1, -14, 3, - -3, -7, -3, -6, -6, 2, -7, 2, - 3, 4, 4, -7, -4, -1, -6, -4, - -4, -4, -3, -4, -4, -3, -6, -5, - -7, -6, -4, -9, -3, -10, -2, -10, - -6, -3, -12, -6, -3, -4, -3, -6, - -1, -1, -1, -3, -1, -1, -7, -3, - -12, -12, -2, -1, -9, -7, -3, -4, - -7, -3, -1, -1, -1, -3, -1, -1, - -5, -4, -6, 2, -4, -2, 2, -3, - -3, -3, -3, -1, -9, -4, -3, -10, - -3, -5, -5, -5, -5, -5, -7, -10, - -10, -4, -12, -6, -1, -1, -2, -6, - -1, -1, -1, -3, -1, -1, -4, -7, - -5, -7, -8, -7, -3, -3, -3, -2, - -3, -3, -3, -1, -1, -6, 23 -}; + { + -33, -33, -16, -27, -3, -3, -8, -8, + -8, -8, -8, -6, -33, -33, -16, -27, + -3, -3, -8, -8, -8, -8, -8, -6, + -6, 23, -27, -27, -39, -28, -6, -19, + -10, -26, -3, -3, -3, 7, -3, -3, + -13, -10, -6, -6, -6, -5, -14, -5, + -3, -8, -19, -6, -7, -2, -4, -27, + -27, -39, -28, -6, -19, -10, -26, -3, + -3, -3, 7, -3, -3, -13, -10, -6, + -6, -12, -3, -3, -23, -3, -3, -7, + -9, -9, -9, -3, 7, 7, -9, -9, + 3, -6, -14, -7, 1, -14, -7, 1, + -16, -16, -27, -7, -2, -3, -3, -3, + -3, -16, -4, -4, 1, -4, -2, -12, + 7, -3, 7, -4, -2, -2, -1, -1, + -2, -9, -5, -4, -7, -2, -1, -1, + -4, -1, -3, -4, -3, -3, -4, -7, + -8, -8, -3, -8, -8, -7, -5, -4, + -1, -1, -1, -2, -3, -6, -8, -3, + -4, -3, -4, -10, -5, -3, -11, -7, + -3, -2, -5, -6, -6, -4, -2, -3, + -3, -3, -3, -3, -7, -3, -9, -3, + -21, -21, -20, -11, -3, -3, -40, -3, + -3, -6, 1, 1, -7, -9, -10, -4, + -4, -4, -7, -6, -6, -4, -6, -4, + -6, -6, -3, -5, -6, -5, -7, -5, + -8, -8, -1, -6, -4, -1, -7, -7, + -12, -6, -6, -12, -8, -2, -3, -6, + -6, -6, -6, -3, -5, -4, -4, -3, + -5, -2, -2, -2, -3, -2, -2, -9, + -4, -6, -5, -5, -6, -4, -25, -25, + -44, -15, -9, 1, -7, -7, -7, -7, + -6, -34, -8, -22, -16, -22, -23, -3, + -3, -3, -4, -1, -3, -3, -6, -3, + -10, -10, -10, -10, -5, -3, -11, -7, + -3, -2, -5, -6, -6, -4, -2, -32, + -9, -32, -22, -14, -42, -3, -7, -7, + -3, -22, -12, -7, -7, -7, -9, -7, + -7, -3, -4, -6, -10, -5, -3, -11, + -7, -3, -2, -5, -6, -6, -4, -2, + -3, -9, -1, -5, -4, -4, 2, 2, + -1, -3, -1, -3, -3, -3, -1, -3, + -3, -2, -2, -5, 4, -4, -4, -6, + -4, -7, -30, -21, -30, -26, -6, -6, + -12, -7, -7, -36, -7, -7, -11, -6, + -4, -15, -21, -19, -19, -19, -5, -21, + -13, -13, -19, -13, -19, -13, -17, -5, + -13, -9, -10, -11, -9, -22, -5, -5, + -9, -5, -14, -3, -1, -3, -4, -1, + -3, -1, -2, -19, -5, -19, -13, -4, + -3, -3, -21, -3, -3, -3, -3, 3, + -5, -6, -4, -4, -4, -6, -6, -6, + -4, -6, -4, -6, -4, -9, -3, -3, + -4, -3, -7, -10, -3, -10, -8, -2, + -2, -19, -2, -2, -2, -2, -5, -4, + -3, -3, -3, -3, -8, 1, -5, -5, + -5, -5, -4, -6, -3, -3, -2, -2, + -2, -5, -2, -2, -5, -3, -5, -4, + -3, -5, -4, -26, -19, -26, -19, -7, + -7, -2, -4, -4, -4, -29, -4, -4, + -5, -4, -3, -7, -19, -12, -12, -12, + -17, -12, -12, -12, -12, -12, -12, -12, + -8, -10, -4, -7, -10, -4, -14, -10, + -2, -6, -6, -9, -6, -6, -9, -3, + -2, -2, -4, -5, -5, -6, -6, -6, + -6, -4, -6, -6, -4, -7, -5, -5, + -7, -5, -6, 23, -25, -8, -15, -8, + -21, 9, 21, -6, -3, 4, -15, -4, + -7, -5, -1, -7, -4, -8, -8, -7, + -3, 2, -3, -4, -16, -5, -1, -13, + -7, -4, -5, -1, -1, -5, -1, -2, + -6, -6, -4, -7, -3, -6, -6, -6, + -3, -6, -6, -3, 2, 2, 2, 2, + -10, 3, -2, -6, -6, -7, -5, -3, + -7, -6, -4, -3, -3, 1, 1, -2, + 1, 4, 12, 12, 14, -14, -4, -14, + -4, 7, 13, 19, 13, 9, 17, 18, + 14, -6, -3, -3, -3, -4, -3, -3, + -3, -1, 4, -1, -4, 14, 4, -9, + 14, -10, -7, -4, 4, -5, -4, -4, + -4, 10, -4, -4, -1, -1, 4, -4, + 4, -10, -2, -7, -3, -5, -6, 4, + -13, 4, 4, 4, -4, -10, -3, -3, + -5, -5, -5, -3, -3, -5, -5, -6, + -4, -2, -2, 2, -10, -2, -7, -3, + -5, -10, -2, -7, -3, -5, -8, -8, + -7, -3, 2, -3, -4, -16, -5, -1, + -13, -7, -4, -5, -1, -1, -5, -1, + -2, -8, -8, -7, -3, 2, -3, -4, + -16, -5, -1, -13, -7, -4, -5, -1, + -1, -5, -1, -2, -7, -6, -4, -9, + -16, -7, -16, -10, 7, 7, -4, -16, + -3, 4, -7, -3, -3, -3, -3, -3, + -3, -1, 7, 5, 7, -1, -14, 3, + -3, -7, -3, -6, -6, 2, -7, 2, + 3, 4, 4, -7, -4, -1, -6, -4, + -4, -4, -3, -4, -4, -3, -6, -5, + -7, -6, -4, -9, -3, -10, -2, -10, + -6, -3, -12, -6, -3, -4, -3, -6, + -1, -1, -1, -3, -1, -1, -7, -3, + -12, -12, -2, -1, -9, -7, -3, -4, + -7, -3, -1, -1, -1, -3, -1, -1, + -5, -4, -6, 2, -4, -2, 2, -3, + -3, -3, -3, -1, -9, -4, -3, -10, + -3, -5, -5, -5, -5, -5, -7, -10, + -10, -4, -12, -6, -1, -1, -2, -6, + -1, -1, -1, -3, -1, -1, -4, -7, + -5, -7, -8, -7, -3, -3, -3, -2, + -3, -3, -3, -1, -1, -6, 23}; /*Collect the kern pair's data in one place*/ static const lv_font_fmt_txt_kern_pair_t kern_pairs = -{ - .glyph_ids = kern_pair_glyph_ids, - .values = kern_pair_values, - .pair_cnt = 871, - .glyph_ids_size = 1 -}; + { + .glyph_ids = kern_pair_glyph_ids, + .values = kern_pair_values, + .pair_cnt = 871, + .glyph_ids_size = 1}; /*-------------------- * ALL CUSTOM DATA @@ -75582,7 +75438,7 @@ static const lv_font_fmt_txt_kern_pair_t kern_pairs = #if LVGL_VERSION_MAJOR == 8 /*Store all the custom data of the font*/ -static lv_font_fmt_txt_glyph_cache_t cache; +static lv_font_fmt_txt_glyph_cache_t cache; #endif #if LVGL_VERSION_MAJOR >= 8 @@ -75604,8 +75460,6 @@ static lv_font_fmt_txt_dsc_t font_dsc = { #endif }; - - /*----------------- * PUBLIC FONT *----------------*/ @@ -75616,10 +75470,10 @@ const lv_font_t lv_font_noto_cjk_16_2bpp = { #else lv_font_t lv_font_noto_cjk_16_2bpp = { #endif - .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ - .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ - .line_height = 20, /*The maximum line height required by the font*/ - .base_line = 5, /*Baseline measured from the bottom of the line*/ + .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ + .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ + .line_height = 20, /*The maximum line height required by the font*/ + .base_line = 5, /*Baseline measured from the bottom of the line*/ #if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) .subpx = LV_FONT_SUBPX_NONE, #endif @@ -75627,14 +75481,11 @@ lv_font_t lv_font_noto_cjk_16_2bpp = { .underline_position = -2, .underline_thickness = 1, #endif - .dsc = &font_dsc, /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ + .dsc = &font_dsc, /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ #if LV_VERSION_CHECK(8, 2, 0) || LVGL_VERSION_MAJOR >= 9 .fallback = NULL, #endif .user_data = NULL, }; - - #endif /*#if LV_FONT_NOTO_CJK_16_2BPP*/ - diff --git a/src/ui/screens/chat/chat_compose_components.cpp b/src/ui/screens/chat/chat_compose_components.cpp index 98eb0346..a9b5d06a 100644 --- a/src/ui/screens/chat/chat_compose_components.cpp +++ b/src/ui/screens/chat/chat_compose_components.cpp @@ -1,32 +1,37 @@ #include "chat_compose_components.h" +#include "chat_compose_input.h" #include "chat_compose_layout.h" #include "chat_compose_styles.h" -#include "chat_compose_input.h" #include "../../widgets/ime/ime_widget.h" #include +#include // snprintf #include -#include // snprintf -namespace chat::ui { +namespace chat::ui +{ -struct ChatComposeScreen::Impl { +struct ChatComposeScreen::Impl +{ chat::ui::compose::layout::Spec spec; chat::ui::compose::layout::Widgets w; chat::ui::compose::input::State input_state; }; -static void set_btn_label_white(lv_obj_t* btn) { +static void set_btn_label_white(lv_obj_t* btn) +{ lv_obj_t* child = lv_obj_get_child(btn, 0); - if (child && lv_obj_check_type(child, &lv_label_class)) { + if (child && lv_obj_check_type(child, &lv_label_class)) + { lv_obj_set_style_text_color(child, lv_color_white(), 0); } } ChatComposeScreen::ChatComposeScreen(lv_obj_t* parent, chat::ConversationId conv) - : conv_(conv) { + : conv_(conv) +{ impl_ = new Impl(); @@ -53,10 +58,12 @@ ChatComposeScreen::ChatComposeScreen(lv_obj_t* parent, chat::ConversationId conv refresh_len(); } -ChatComposeScreen::~ChatComposeScreen() { +ChatComposeScreen::~ChatComposeScreen() +{ if (!impl_) return; - if (impl_->w.container) { + if (impl_->w.container) + { lv_obj_del(impl_->w.container); } @@ -64,16 +71,21 @@ ChatComposeScreen::~ChatComposeScreen() { impl_ = nullptr; } -lv_obj_t* ChatComposeScreen::getObj() const { +lv_obj_t* ChatComposeScreen::getObj() const +{ return impl_ ? impl_->w.container : nullptr; } -void ChatComposeScreen::init_topbar() { +void ChatComposeScreen::init_topbar() +{ char title_buf[32]; - if (conv_.peer == 0) { + if (conv_.peer == 0) + { snprintf(title_buf, sizeof(title_buf), "Broadcast"); - } else { + } + else + { snprintf(title_buf, sizeof(title_buf), "%04lX", static_cast(conv_.peer & 0xFFFF)); } @@ -83,51 +95,61 @@ void ChatComposeScreen::init_topbar() { ::ui::widgets::top_bar_set_back_callback(impl_->w.top_bar, on_back, this); } -void ChatComposeScreen::setHeaderText(const char* title, const char* status) { +void ChatComposeScreen::setHeaderText(const char* title, const char* status) +{ if (!impl_) return; - if (title) ::ui::widgets::top_bar_set_title(impl_->w.top_bar, title); + if (title) ::ui::widgets::top_bar_set_title(impl_->w.top_bar, title); if (status) ::ui::widgets::top_bar_set_right_text(impl_->w.top_bar, status); } -std::string ChatComposeScreen::getText() const { +std::string ChatComposeScreen::getText() const +{ if (!impl_ || !impl_->w.textarea) return ""; const char* text = lv_textarea_get_text(impl_->w.textarea); return text ? std::string(text) : ""; } -void ChatComposeScreen::clearText() { +void ChatComposeScreen::clearText() +{ if (!impl_) return; lv_textarea_set_text(impl_->w.textarea, ""); refresh_len(); } -void ChatComposeScreen::setActionCallback(void (*cb)(bool send, void*), void* user_data) { +void ChatComposeScreen::setActionCallback(void (*cb)(bool send, void*), void* user_data) +{ action_cb_ = cb; action_cb_user_data_ = user_data; } -void ChatComposeScreen::setBackCallback(void (*cb)(void*), void* user_data) { +void ChatComposeScreen::setBackCallback(void (*cb)(void*), void* user_data) +{ back_cb_ = cb; back_cb_user_data_ = user_data; } -void ChatComposeScreen::attachImeWidget(::ui::widgets::ImeWidget* widget) { +void ChatComposeScreen::attachImeWidget(::ui::widgets::ImeWidget* widget) +{ ime_widget_ = widget; } -lv_obj_t* ChatComposeScreen::getTextarea() const { +lv_obj_t* ChatComposeScreen::getTextarea() const +{ return impl_ ? impl_->w.textarea : nullptr; } -lv_obj_t* ChatComposeScreen::getContent() const { +lv_obj_t* ChatComposeScreen::getContent() const +{ return impl_ ? impl_->w.content : nullptr; } -lv_obj_t* ChatComposeScreen::getActionBar() const { +lv_obj_t* ChatComposeScreen::getActionBar() const +{ return impl_ ? impl_->w.action_bar : nullptr; } -void ChatComposeScreen::refresh_len() { +void ChatComposeScreen::refresh_len() +{ if (!impl_) return; const char* text = lv_textarea_get_text(impl_->w.textarea); @@ -140,34 +162,39 @@ void ChatComposeScreen::refresh_len() { // ---------- LVGL callbacks ---------- -void ChatComposeScreen::on_action_click(lv_event_t* e) { +void ChatComposeScreen::on_action_click(lv_event_t* e) +{ auto* screen = static_cast(lv_event_get_user_data(e)); if (!screen || !screen->action_cb_ || !screen->impl_) return; auto* target = reinterpret_cast(lv_event_get_target(e)); // 兼容 void* bool send = (target == screen->impl_->w.send_btn); - screen->action_cb_(send, screen->action_cb_user_data_); } -void ChatComposeScreen::on_text_changed(lv_event_t* e) { +void ChatComposeScreen::on_text_changed(lv_event_t* e) +{ auto* screen = static_cast(lv_event_get_user_data(e)); if (!screen) return; screen->refresh_len(); } -void ChatComposeScreen::on_back(void* user_data) { +void ChatComposeScreen::on_back(void* user_data) +{ auto* screen = static_cast(user_data); - if (screen && screen->back_cb_) { + if (screen && screen->back_cb_) + { screen->back_cb_(screen->back_cb_user_data_); } } -void ChatComposeScreen::on_key(lv_event_t* e) { +void ChatComposeScreen::on_key(lv_event_t* e) +{ auto* screen = static_cast(lv_event_get_user_data(e)); if (!screen || !screen->impl_) return; - if (screen->ime_widget_ && screen->ime_widget_->handle_key(e)) { + if (screen->ime_widget_ && screen->ime_widget_->handle_key(e)) + { return; } @@ -177,8 +204,10 @@ void ChatComposeScreen::on_key(lv_event_t* e) { lv_indev_t* indev = lv_indev_get_act(); bool is_encoder = indev && lv_indev_get_type(indev) == LV_INDEV_TYPE_ENCODER; - if (is_encoder && key == LV_KEY_ENTER && screen->impl_->w.send_btn) { - if (lv_group_t* g = lv_group_get_default()) { + if (is_encoder && key == LV_KEY_ENTER && screen->impl_->w.send_btn) + { + if (lv_group_t* g = lv_group_get_default()) + { lv_group_focus_obj(screen->impl_->w.send_btn); } } diff --git a/src/ui/screens/contacts/contacts_page_layout.cpp b/src/ui/screens/contacts/contacts_page_layout.cpp index 0d7fde58..b3c13421 100644 --- a/src/ui/screens/contacts/contacts_page_layout.cpp +++ b/src/ui/screens/contacts/contacts_page_layout.cpp @@ -30,9 +30,9 @@ * │ ├─ ListContainer(grow=1,COL) -> ListItem(x4/page)-> NameLabel, StatusLabel * │ └─ BottomBar(ROW) -> PrevBtn, NextBtn, BackBtn * └─ ActionPanel(80,COL) -> (TBD action buttons) - * - * - * Preconditions: + * + * + * Preconditions: * - The parent/root container uses LV_FLEX_FLOW_ROW to place 3 panels horizontally. * * Implementation notes: @@ -45,23 +45,29 @@ * @brief Contacts layout */ -#include #include "contacts_page_layout.h" +#include "../../../app/app_context.h" +#include "../../../chat/domain/chat_types.h" +#include "../../../chat/infra/meshtastic/mt_region.h" +#include using namespace contacts::ui; -namespace contacts { -namespace ui { -namespace layout { +namespace contacts +{ +namespace ui +{ +namespace layout +{ // 布局常量 static constexpr int kFilterPanelWidth = 80; static constexpr int kActionPanelWidth = 80; static constexpr int kButtonHeight = 32; static constexpr int kButtonSpacing = 3; -static constexpr int kPanelGap = 3; // 三列之间的间距 -static constexpr int kScreenEdgePadding = 3; // 屏幕边缘的padding -static constexpr int kTopBarContentGap = 3; // TopBar与Content之间的间距 +static constexpr int kPanelGap = 3; // 三列之间的间距 +static constexpr int kScreenEdgePadding = 3; // 屏幕边缘的padding +static constexpr int kTopBarContentGap = 3; // TopBar与Content之间的间距 // 工具函数 static void make_non_scrollable(lv_obj_t* obj) @@ -78,6 +84,35 @@ static void apply_base_container_style(lv_obj_t* obj) make_non_scrollable(obj); } +namespace +{ + +void format_contacts_title(char* out, size_t out_len) +{ + if (!out || out_len == 0) + { + return; + } + app::AppContext& app_ctx = app::AppContext::getInstance(); + const chat::MeshConfig& config = app_ctx.getConfig().mesh_config; + chat::MeshProtocol protocol = app_ctx.getConfig().mesh_protocol; + if (protocol == chat::MeshProtocol::Meshtastic) + { + float freq_mhz = + chat::meshtastic::estimateFrequencyMhz(config.region, config.modem_preset); + snprintf(out, out_len, "Contacts (Meshtastic - %.3fMHz)", freq_mhz); + return; + } + if (protocol == chat::MeshProtocol::MeshCore) + { + snprintf(out, out_len, "Contacts (MeshCore)"); + return; + } + snprintf(out, out_len, "Contacts"); +} + +} // namespace + lv_obj_t* create_root(lv_obj_t* parent) { lv_obj_t* root = lv_obj_create(parent); @@ -111,7 +146,9 @@ lv_obj_t* create_header(lv_obj_t* root, ::ui::widgets::TopBarConfig cfg; cfg.height = ::ui::widgets::kTopBarHeight; ::ui::widgets::top_bar_init(g_contacts_state.top_bar, header, cfg); - ::ui::widgets::top_bar_set_title(g_contacts_state.top_bar, "Contacts"); + char title[64]; + format_contacts_title(title, sizeof(title)); + ::ui::widgets::top_bar_set_title(g_contacts_state.top_bar, title); ::ui::widgets::top_bar_set_back_callback(g_contacts_state.top_bar, back_callback, user_data); return header; @@ -127,9 +164,9 @@ lv_obj_t* create_content(lv_obj_t* root) lv_obj_set_flex_grow(content, 1); lv_obj_set_flex_flow(content, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(content, - LV_FLEX_ALIGN_START, - LV_FLEX_ALIGN_START, - LV_FLEX_ALIGN_START); + LV_FLEX_ALIGN_START, + LV_FLEX_ALIGN_START, + LV_FLEX_ALIGN_START); // 样式 lv_obj_set_style_bg_opa(content, LV_OPA_TRANSP, 0); @@ -228,7 +265,8 @@ void ensure_list_subcontainers() { if (g_contacts_state.list_panel == nullptr) return; - if (g_contacts_state.sub_container == nullptr) { + if (g_contacts_state.sub_container == nullptr) + { g_contacts_state.sub_container = lv_obj_create(g_contacts_state.list_panel); make_non_scrollable(g_contacts_state.sub_container); @@ -243,7 +281,8 @@ void ensure_list_subcontainers() lv_obj_set_style_pad_row(g_contacts_state.sub_container, 2, LV_PART_MAIN); } - if (g_contacts_state.bottom_container == nullptr) { + if (g_contacts_state.bottom_container == nullptr) + { g_contacts_state.bottom_container = lv_obj_create(g_contacts_state.list_panel); make_non_scrollable(g_contacts_state.bottom_container); @@ -289,4 +328,3 @@ lv_obj_t* create_list_item(lv_obj_t* parent, } // namespace layout } // namespace ui } // namespace contacts - diff --git a/src/ui/screens/settings/settings_page_components.cpp b/src/ui/screens/settings/settings_page_components.cpp index a4ac260e..c5f76a54 100644 --- a/src/ui/screens/settings/settings_page_components.cpp +++ b/src/ui/screens/settings/settings_page_components.cpp @@ -8,67 +8,83 @@ #include #include +#include "../../../app/app_context.h" +#include "../../../board/rtc_utils.h" +#include "../../../chat/domain/chat_types.h" +#include "../../../chat/infra/meshtastic/generated/meshtastic/config.pb.h" +#include "../../../chat/infra/meshtastic/mt_region.h" +#include "../../ui_common.h" +#include "../../widgets/system_notification.h" #include "settings_page_components.h" +#include "settings_page_input.h" #include "settings_page_layout.h" #include "settings_page_styles.h" -#include "settings_page_input.h" #include "settings_state.h" -#include "../../../chat/infra/meshtastic/generated/meshtastic/config.pb.h" -#include "../../ui_common.h" -#include "../../../board/rtc_utils.h" extern uint32_t getScreenSleepTimeout(); extern void setScreenSleepTimeout(uint32_t timeout_ms); -namespace settings::ui::components { +namespace settings::ui::components +{ -namespace { +namespace +{ constexpr size_t kMaxItems = 12; constexpr size_t kMaxOptions = 40; constexpr const char* kPrefsNs = "settings_v2"; -struct CategoryDef { +struct CategoryDef +{ const char* label; const settings::ui::SettingItem* items; size_t item_count; }; -struct OptionClick { +struct OptionClick +{ const settings::ui::SettingItem* item; int value; settings::ui::ItemWidget* widget; }; -static OptionClick s_option_clicks[kMaxOptions] {}; +static OptionClick s_option_clicks[kMaxOptions]{}; static size_t s_option_click_count = 0; static lv_group_t* s_modal_prev_group = nullptr; static int s_pending_category = -1; static bool s_category_update_scheduled = false; static bool s_building_list = false; +static settings::ui::SettingOption kChatRegionOptions[32] = {}; +static size_t kChatRegionOptionCount = 0; -static void prefs_put_int(const char* key, int value) { +static void build_item_list(); + +static void prefs_put_int(const char* key, int value) +{ Preferences prefs; prefs.begin(kPrefsNs, false); prefs.putInt(key, value); prefs.end(); } -static void prefs_put_bool(const char* key, bool value) { +static void prefs_put_bool(const char* key, bool value) +{ Preferences prefs; prefs.begin(kPrefsNs, false); prefs.putBool(key, value); prefs.end(); } -static void prefs_put_str(const char* key, const char* value) { +static void prefs_put_str(const char* key, const char* value) +{ Preferences prefs; prefs.begin(kPrefsNs, false); prefs.putString(key, value ? value : ""); prefs.end(); } -static int prefs_get_int(const char* key, int default_value) { +static int prefs_get_int(const char* key, int default_value) +{ Preferences prefs; prefs.begin(kPrefsNs, true); int value = prefs.getInt(key, default_value); @@ -76,7 +92,8 @@ static int prefs_get_int(const char* key, int default_value) { return value; } -static bool prefs_get_bool(const char* key, bool default_value) { +static bool prefs_get_bool(const char* key, bool default_value) +{ Preferences prefs; prefs.begin(kPrefsNs, true); bool value = prefs.getBool(key, default_value); @@ -84,8 +101,10 @@ static bool prefs_get_bool(const char* key, bool default_value) { return value; } -static void prefs_get_str(const char* key, char* out, size_t out_len, const char* default_value) { - if (!out || out_len == 0) { +static void prefs_get_str(const char* key, char* out, size_t out_len, const char* default_value) +{ + if (!out || out_len == 0) + { return; } Preferences prefs; @@ -96,7 +115,179 @@ static void prefs_get_str(const char* key, char* out, size_t out_len, const char out[out_len - 1] = '\0'; } -static void settings_load() { +static bool is_zero_key(const uint8_t* key, size_t len) +{ + if (!key || len == 0) + { + return true; + } + for (size_t i = 0; i < len; ++i) + { + if (key[i] != 0) + { + return false; + } + } + return true; +} + +static void bytes_to_hex(const uint8_t* data, size_t len, char* out, size_t out_len) +{ + if (!out || out_len == 0) + { + return; + } + out[0] = '\0'; + if (!data || len == 0) + { + return; + } + static const char* kHex = "0123456789ABCDEF"; + size_t required = len * 2 + 1; + if (out_len < required) + { + return; + } + for (size_t i = 0; i < len; ++i) + { + uint8_t b = data[i]; + out[i * 2] = kHex[b >> 4]; + out[i * 2 + 1] = kHex[b & 0x0F]; + } + out[len * 2] = '\0'; +} + +static bool parse_hex_char(char c, uint8_t& out) +{ + if (c >= '0' && c <= '9') + { + out = static_cast(c - '0'); + return true; + } + if (c >= 'a' && c <= 'f') + { + out = static_cast(10 + (c - 'a')); + return true; + } + if (c >= 'A' && c <= 'F') + { + out = static_cast(10 + (c - 'A')); + return true; + } + return false; +} + +static bool parse_psk(const char* text, uint8_t* out, size_t out_len) +{ + if (!out || out_len == 0) + { + return false; + } + if (!text || text[0] == '\0') + { + memset(out, 0, out_len); + return true; + } + size_t len = strlen(text); + if (len == 32) + { + for (size_t i = 0; i < 16; ++i) + { + uint8_t hi = 0; + uint8_t lo = 0; + if (!parse_hex_char(text[i * 2], hi) || !parse_hex_char(text[i * 2 + 1], lo)) + { + return false; + } + out[i] = static_cast((hi << 4) | lo); + } + return true; + } + if (len == 16) + { + memcpy(out, text, 16); + return true; + } + return false; +} + +static void mark_restart_required() +{ + g_settings.needs_restart = true; + prefs_put_bool("needs_restart", true); + ::ui::SystemNotification::show("Restart required", 4000); +} + +static void reset_mesh_settings() +{ + app::AppContext& app_ctx = app::AppContext::getInstance(); + app_ctx.getConfig().mesh_config = chat::MeshConfig(); + app_ctx.getConfig().mesh_protocol = chat::MeshProtocol::Meshtastic; + app_ctx.saveConfig(); + app_ctx.applyMeshConfig(); + + g_settings.chat_protocol = static_cast(app_ctx.getConfig().mesh_protocol); + g_settings.chat_region = app_ctx.getConfig().mesh_config.region; + g_settings.chat_channel = 0; + g_settings.chat_psk[0] = '\0'; + g_settings.net_modem_preset = app_ctx.getConfig().mesh_config.modem_preset; + g_settings.net_relay = app_ctx.getConfig().mesh_config.enable_relay; + g_settings.net_duty_cycle = true; + g_settings.net_channel_util = 0; + g_settings.needs_restart = false; + + Preferences prefs; + prefs.begin(kPrefsNs, false); + prefs.remove("mesh_protocol"); + prefs.remove("chat_region"); + prefs.remove("chat_channel"); + prefs.remove("chat_psk"); + prefs.remove("net_preset"); + prefs.remove("net_relay"); + prefs.remove("net_duty_cycle"); + prefs.remove("net_util"); + prefs.remove("needs_restart"); + prefs.end(); + + build_item_list(); + ::ui::SystemNotification::show("Resetting...", 1500); + delay(300); + ESP.restart(); +} + +static void reset_node_db() +{ + app::AppContext& app_ctx = app::AppContext::getInstance(); + app_ctx.clearNodeDb(); + ::ui::SystemNotification::show("Node DB reset", 3000); +} + +static void clear_message_db() +{ + app::AppContext& app_ctx = app::AppContext::getInstance(); + app_ctx.clearMessageDb(); + ::ui::SystemNotification::show("Message DB cleared", 3000); +} + +static void settings_load() +{ + app::AppContext& app_ctx = app::AppContext::getInstance(); + g_settings.chat_protocol = static_cast(app_ctx.getConfig().mesh_protocol); + g_settings.needs_restart = prefs_get_bool("needs_restart", false); + + if (kChatRegionOptionCount == 0) + { + size_t region_count = 0; + const chat::meshtastic::RegionInfo* regions = chat::meshtastic::getRegionTable(®ion_count); + size_t limit = sizeof(kChatRegionOptions) / sizeof(kChatRegionOptions[0]); + kChatRegionOptionCount = (region_count < limit) ? region_count : limit; + for (size_t i = 0; i < kChatRegionOptionCount; ++i) + { + kChatRegionOptions[i].label = regions[i].label; + kChatRegionOptions[i].value = regions[i].code; + } + } + g_settings.gps_mode = prefs_get_int("gps_mode", 0); g_settings.gps_sat_mask = prefs_get_int("gps_sat_mask", 0x1 | 0x8 | 0x4); g_settings.gps_strategy = prefs_get_int("gps_strategy", 0); @@ -112,12 +303,23 @@ static void settings_load() { prefs_get_str("chat_user", g_settings.user_name, sizeof(g_settings.user_name), "TrailMate"); prefs_get_str("chat_short", g_settings.short_name, sizeof(g_settings.short_name), "TM"); - g_settings.chat_region = prefs_get_int("chat_region", meshtastic_Config_LoRaConfig_RegionCode_CN); + g_settings.chat_region = app_ctx.getConfig().mesh_config.region; g_settings.chat_channel = prefs_get_int("chat_channel", 0); - prefs_get_str("chat_psk", g_settings.chat_psk, sizeof(g_settings.chat_psk), ""); + if (is_zero_key(app_ctx.getConfig().mesh_config.secondary_key, + sizeof(app_ctx.getConfig().mesh_config.secondary_key))) + { + g_settings.chat_psk[0] = '\0'; + } + else + { + bytes_to_hex(app_ctx.getConfig().mesh_config.secondary_key, + sizeof(app_ctx.getConfig().mesh_config.secondary_key), + g_settings.chat_psk, + sizeof(g_settings.chat_psk)); + } - g_settings.net_modem_preset = prefs_get_int("net_preset", meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST); - g_settings.net_relay = prefs_get_bool("net_relay", true); + g_settings.net_modem_preset = app_ctx.getConfig().mesh_config.modem_preset; + g_settings.net_relay = app_ctx.getConfig().mesh_config.enable_relay; g_settings.net_duty_cycle = prefs_get_bool("net_duty_cycle", true); g_settings.net_channel_util = prefs_get_int("net_util", 0); @@ -132,43 +334,60 @@ static void settings_load() { g_settings.advanced_debug_logs = prefs_get_bool("adv_debug", false); } -static void format_value(const settings::ui::SettingItem& item, char* out, size_t out_len) { - if (!out || out_len == 0) { +static void format_value(const settings::ui::SettingItem& item, char* out, size_t out_len) +{ + if (!out || out_len == 0) + { return; } out[0] = '\0'; - switch (item.type) { - case settings::ui::SettingType::Toggle: - snprintf(out, out_len, "%s", (item.bool_value && *item.bool_value) ? "ON" : "OFF"); - break; - case settings::ui::SettingType::Enum: { - int value = item.enum_value ? *item.enum_value : 0; - const char* label = "N/A"; - for (size_t i = 0; i < item.option_count; ++i) { - if (item.options[i].value == value) { - label = item.options[i].label; - break; - } + switch (item.type) + { + case settings::ui::SettingType::Toggle: + snprintf(out, out_len, "%s", (item.bool_value && *item.bool_value) ? "ON" : "OFF"); + break; + case settings::ui::SettingType::Enum: + { + int value = item.enum_value ? *item.enum_value : 0; + const char* label = "N/A"; + for (size_t i = 0; i < item.option_count; ++i) + { + if (item.options[i].value == value) + { + label = item.options[i].label; + break; } - snprintf(out, out_len, "%s", label); - break; } - case settings::ui::SettingType::Text: - if (item.text_value && item.text_value[0] != '\0') { - if (item.mask_text) { - snprintf(out, out_len, "****"); - } else { - snprintf(out, out_len, "%s", item.text_value); - } - } else { - snprintf(out, out_len, "Not set"); + snprintf(out, out_len, "%s", label); + break; + } + case settings::ui::SettingType::Text: + if (item.text_value && item.text_value[0] != '\0') + { + if (item.mask_text) + { + snprintf(out, out_len, "****"); } - break; + else + { + snprintf(out, out_len, "%s", item.text_value); + } + } + else + { + snprintf(out, out_len, "Not set"); + } + break; + case settings::ui::SettingType::Action: + snprintf(out, out_len, "Run"); + break; } } -static void update_item_value(settings::ui::ItemWidget& widget) { - if (!widget.value_label || !widget.def) { +static void update_item_value(settings::ui::ItemWidget& widget) +{ + if (!widget.value_label || !widget.def) + { return; } char value[48]; @@ -176,8 +395,10 @@ static void update_item_value(settings::ui::ItemWidget& widget) { lv_label_set_text(widget.value_label, value); } -static void modal_prepare_group() { - if (g_state.modal_group) { +static void modal_prepare_group() +{ + if (g_state.modal_group) + { return; } s_modal_prev_group = settings::ui::input::get_group(); @@ -185,19 +406,24 @@ static void modal_prepare_group() { set_default_group(g_state.modal_group); } -static void modal_restore_group() { - if (g_state.modal_group) { +static void modal_restore_group() +{ + if (g_state.modal_group) + { lv_group_del(g_state.modal_group); g_state.modal_group = nullptr; } - if (s_modal_prev_group) { + if (s_modal_prev_group) + { set_default_group(s_modal_prev_group); } settings::ui::input::on_ui_refreshed(); } -static void modal_close() { - if (g_state.modal_root) { +static void modal_close() +{ + if (g_state.modal_root) + { lv_obj_del_async(g_state.modal_root); g_state.modal_root = nullptr; } @@ -209,7 +435,8 @@ static void modal_close() { modal_restore_group(); } -static lv_obj_t* create_modal_root(lv_coord_t width, lv_coord_t height) { +static lv_obj_t* create_modal_root(lv_coord_t width, lv_coord_t height) +{ lv_obj_t* bg = lv_obj_create(g_state.root); lv_obj_set_size(bg, LV_PCT(100), LV_PCT(100)); style::apply_modal_bg(bg); @@ -228,29 +455,49 @@ static lv_obj_t* create_modal_root(lv_coord_t width, lv_coord_t height) { return bg; } -static void on_text_save_clicked(lv_event_t* e) { +static void on_text_save_clicked(lv_event_t* e) +{ (void)e; - if (!g_state.editing_item || !g_state.modal_textarea || !g_state.editing_widget) { + if (!g_state.editing_item || !g_state.modal_textarea || !g_state.editing_widget) + { modal_close(); return; } const char* text = lv_textarea_get_text(g_state.modal_textarea); - if (g_state.editing_item->text_value && g_state.editing_item->text_max > 0) { + if (g_state.editing_item->text_value && g_state.editing_item->text_max > 0) + { strncpy(g_state.editing_item->text_value, text, g_state.editing_item->text_max - 1); g_state.editing_item->text_value[g_state.editing_item->text_max - 1] = '\0'; prefs_put_str(g_state.editing_item->pref_key, g_state.editing_item->text_value); update_item_value(*g_state.editing_widget); + if (g_state.editing_item->pref_key && strcmp(g_state.editing_item->pref_key, "chat_psk") == 0) + { + app::AppContext& app_ctx = app::AppContext::getInstance(); + uint8_t key[16] = {}; + if (!parse_psk(g_state.editing_item->text_value, key, sizeof(key))) + { + ::ui::SystemNotification::show("PSK must be 32 hex or 16 chars", 4000); + modal_close(); + return; + } + memcpy(app_ctx.getConfig().mesh_config.secondary_key, key, sizeof(key)); + app_ctx.saveConfig(); + app_ctx.applyMeshConfig(); + } } modal_close(); } -static void on_text_cancel_clicked(lv_event_t* e) { +static void on_text_cancel_clicked(lv_event_t* e) +{ (void)e; modal_close(); } -static void open_text_modal(const settings::ui::SettingItem& item, settings::ui::ItemWidget& widget) { - if (g_state.modal_root) { +static void open_text_modal(const settings::ui::SettingItem& item, settings::ui::ItemWidget& widget) +{ + if (g_state.modal_root) + { return; } modal_prepare_group(); @@ -264,12 +511,14 @@ static void open_text_modal(const settings::ui::SettingItem& item, settings::ui: g_state.modal_textarea = lv_textarea_create(win); lv_textarea_set_one_line(g_state.modal_textarea, true); lv_textarea_set_max_length(g_state.modal_textarea, static_cast(item.text_max - 1)); - if (item.mask_text) { + if (item.mask_text) + { lv_textarea_set_password_mode(g_state.modal_textarea, true); } lv_obj_set_width(g_state.modal_textarea, LV_PCT(100)); lv_obj_align(g_state.modal_textarea, LV_ALIGN_TOP_MID, 0, 28); - if (item.text_value) { + if (item.text_value) + { lv_textarea_set_text(g_state.modal_textarea, item.text_value); lv_textarea_set_cursor_pos(g_state.modal_textarea, LV_TEXTAREA_CURSOR_LAST); } @@ -308,29 +557,64 @@ static void open_text_modal(const settings::ui::SettingItem& item, settings::ui: lv_group_focus_obj(g_state.modal_textarea); } -static void on_option_clicked(lv_event_t* e) { +static void on_option_clicked(lv_event_t* e) +{ OptionClick* payload = static_cast(lv_event_get_user_data(e)); - if (!payload || !payload->item || !payload->item->enum_value) { + if (!payload || !payload->item || !payload->item->enum_value) + { return; } + bool restart_now = false; int previous_value = *payload->item->enum_value; *payload->item->enum_value = payload->value; prefs_put_int(payload->item->pref_key, payload->value); update_item_value(*payload->widget); - if (payload->item->pref_key && strcmp(payload->item->pref_key, "screen_timeout") == 0) { + if (payload->item->pref_key && strcmp(payload->item->pref_key, "mesh_protocol") == 0) + { + app::AppContext& app_ctx = app::AppContext::getInstance(); + app_ctx.getConfig().mesh_protocol = static_cast(payload->value); + app_ctx.saveConfig(); + restart_now = true; + } + if (payload->item->pref_key && strcmp(payload->item->pref_key, "chat_region") == 0) + { + app::AppContext& app_ctx = app::AppContext::getInstance(); + app_ctx.getConfig().mesh_config.region = static_cast(payload->value); + app_ctx.saveConfig(); + restart_now = true; + } + if (payload->item->pref_key && strcmp(payload->item->pref_key, "net_preset") == 0) + { + app::AppContext& app_ctx = app::AppContext::getInstance(); + app_ctx.getConfig().mesh_config.modem_preset = static_cast(payload->value); + app_ctx.saveConfig(); + app_ctx.applyMeshConfig(); + } + if (payload->item->pref_key && strcmp(payload->item->pref_key, "screen_timeout") == 0) + { setScreenSleepTimeout(static_cast(payload->value)); } - if (payload->item->pref_key && strcmp(payload->item->pref_key, "timezone_offset") == 0) { + if (payload->item->pref_key && strcmp(payload->item->pref_key, "timezone_offset") == 0) + { int delta = payload->value - previous_value; - if (delta != 0) { + if (delta != 0) + { board_adjust_rtc_by_offset_minutes(delta); } } modal_close(); + if (restart_now) + { + ::ui::SystemNotification::show("Restarting...", 1500); + delay(300); + ESP.restart(); + } } -static void open_option_modal(const settings::ui::SettingItem& item, settings::ui::ItemWidget& widget) { - if (g_state.modal_root) { +static void open_option_modal(const settings::ui::SettingItem& item, settings::ui::ItemWidget& widget) +{ + if (g_state.modal_root) + { return; } modal_prepare_group(); @@ -351,7 +635,8 @@ static void open_option_modal(const settings::ui::SettingItem& item, settings::u lv_obj_set_scrollbar_mode(list, LV_SCROLLBAR_MODE_OFF); s_option_click_count = 0; - for (size_t i = 0; i < item.option_count && s_option_click_count < kMaxOptions; ++i) { + for (size_t i = 0; i < item.option_count && s_option_click_count < kMaxOptions; ++i) + { lv_obj_t* btn = lv_btn_create(list); lv_obj_set_size(btn, LV_PCT(100), 24); style::apply_btn_modal(btn); @@ -363,13 +648,15 @@ static void open_option_modal(const settings::ui::SettingItem& item, settings::u s_option_clicks[s_option_click_count] = {&item, item.options[i].value, &widget}; lv_obj_add_event_cb(btn, on_option_clicked, LV_EVENT_CLICKED, &s_option_clicks[s_option_click_count]); - if (item.enum_value && item.options[i].value == *item.enum_value) { + if (item.enum_value && item.options[i].value == *item.enum_value) + { lv_obj_add_state(btn, LV_STATE_CHECKED); } lv_group_add_obj(g_state.modal_group, btn); s_option_click_count++; } - if (s_option_click_count > 0) { + if (s_option_click_count > 0) + { lv_group_focus_obj(lv_obj_get_child(list, 0)); } } @@ -434,19 +721,14 @@ static const settings::ui::SettingOption kMapTrackFormatOptions[] = { {"Binary", 2}, }; -static const settings::ui::SettingOption kChatRegionOptions[] = { - {"CN", meshtastic_Config_LoRaConfig_RegionCode_CN}, - {"US", meshtastic_Config_LoRaConfig_RegionCode_US}, - {"EU_868", meshtastic_Config_LoRaConfig_RegionCode_EU_868}, - {"EU_433", meshtastic_Config_LoRaConfig_RegionCode_EU_433}, - {"JP", meshtastic_Config_LoRaConfig_RegionCode_JP}, - {"ANZ", meshtastic_Config_LoRaConfig_RegionCode_ANZ}, - {"IN", meshtastic_Config_LoRaConfig_RegionCode_IN}, -}; static const settings::ui::SettingOption kChatChannelOptions[] = { {"Primary", 0}, {"Secondary", 1}, }; +static const settings::ui::SettingOption kChatProtocolOptions[] = { + {"Meshtastic", static_cast(chat::MeshProtocol::Meshtastic)}, + {"MeshCore", static_cast(chat::MeshProtocol::MeshCore)}, +}; static const settings::ui::SettingOption kNetPresetOptions[] = { {"LongFast", meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST}, @@ -534,9 +816,13 @@ static settings::ui::SettingItem kMapItems[] = { static settings::ui::SettingItem kChatItems[] = { {"User Name", settings::ui::SettingType::Text, nullptr, 0, nullptr, nullptr, g_settings.user_name, sizeof(g_settings.user_name), false, "chat_user"}, {"Short Name", settings::ui::SettingType::Text, nullptr, 0, nullptr, nullptr, g_settings.short_name, sizeof(g_settings.short_name), false, "chat_short"}, - {"Region", settings::ui::SettingType::Enum, kChatRegionOptions, 7, &g_settings.chat_region, nullptr, nullptr, 0, false, "chat_region"}, + {"Protocol", settings::ui::SettingType::Enum, kChatProtocolOptions, 2, &g_settings.chat_protocol, nullptr, nullptr, 0, false, "mesh_protocol"}, + {"Region", settings::ui::SettingType::Enum, kChatRegionOptions, 0, &g_settings.chat_region, nullptr, nullptr, 0, false, "chat_region"}, {"Channel", settings::ui::SettingType::Enum, kChatChannelOptions, 2, &g_settings.chat_channel, nullptr, nullptr, 0, false, "chat_channel"}, {"Channel Key / PSK", settings::ui::SettingType::Text, nullptr, 0, nullptr, nullptr, g_settings.chat_psk, sizeof(g_settings.chat_psk), true, "chat_psk"}, + {"Reset Mesh Params", settings::ui::SettingType::Action, nullptr, 0, nullptr, nullptr, nullptr, 0, false, "chat_reset_mesh"}, + {"Reset Node DB", settings::ui::SettingType::Action, nullptr, 0, nullptr, nullptr, nullptr, 0, false, "chat_reset_nodes"}, + {"Clear Message DB", settings::ui::SettingType::Action, nullptr, 0, nullptr, nullptr, nullptr, 0, false, "chat_clear_messages"}, }; static settings::ui::SettingItem kNetworkItems[] = { @@ -572,20 +858,46 @@ static const CategoryDef kCategories[] = { {"Advanced", kAdvancedItems, sizeof(kAdvancedItems) / sizeof(kAdvancedItems[0])}, }; -static void update_filter_styles() { - for (size_t i = 0; i < g_state.filter_count; ++i) { +static void update_filter_styles() +{ + for (size_t i = 0; i < g_state.filter_count; ++i) + { if (!g_state.filter_buttons[i]) continue; - if (static_cast(i) == g_state.current_category) { + if (static_cast(i) == g_state.current_category) + { lv_obj_add_state(g_state.filter_buttons[i], LV_STATE_CHECKED); - } else { + } + else + { lv_obj_clear_state(g_state.filter_buttons[i], LV_STATE_CHECKED); } } } -static void build_item_list() { +static bool should_show_item(const settings::ui::SettingItem& item) +{ + if (!item.pref_key) + { + return true; + } + if (g_settings.chat_protocol == static_cast(chat::MeshProtocol::MeshCore)) + { + if (strcmp(item.pref_key, "chat_region") == 0) return false; + if (strcmp(item.pref_key, "chat_channel") == 0) return false; + if (strcmp(item.pref_key, "chat_psk") == 0) return false; + if (strcmp(item.pref_key, "net_preset") == 0) return false; + if (strcmp(item.pref_key, "net_relay") == 0) return false; + if (strcmp(item.pref_key, "net_duty_cycle") == 0) return false; + if (strcmp(item.pref_key, "net_util") == 0) return false; + } + return true; +} + +static void build_item_list() +{ if (!g_state.list_panel) return; - if (s_building_list) { + if (s_building_list) + { return; } s_building_list = true; @@ -595,9 +907,18 @@ static void build_item_list() { lv_obj_clear_flag(g_state.list_panel, LV_OBJ_FLAG_SCROLLABLE); const CategoryDef& cat = kCategories[g_state.current_category]; - for (size_t i = 0; i < cat.item_count && g_state.item_count < kMaxItems; ++i) { + for (size_t i = 0; i < cat.item_count && g_state.item_count < kMaxItems; ++i) + { settings::ui::ItemWidget& widget = g_state.item_widgets[g_state.item_count]; widget.def = &cat.items[i]; + if (widget.def == &kChatItems[3]) + { + kChatItems[3].option_count = kChatRegionOptionCount; + } + if (!should_show_item(*widget.def)) + { + continue; + } lv_obj_t* btn = lv_btn_create(g_state.list_panel); lv_obj_set_size(btn, LV_PCT(100), 22); @@ -640,29 +961,58 @@ static void build_item_list() { s_building_list = false; } -static void on_item_clicked(lv_event_t* e) { +static void on_item_clicked(lv_event_t* e) +{ settings::ui::ItemWidget* widget = static_cast(lv_event_get_user_data(e)); if (!widget || !widget->def) return; const SettingItem& item = *widget->def; - if (item.type == settings::ui::SettingType::Toggle) { - if (item.bool_value) { + if (item.type == settings::ui::SettingType::Toggle) + { + if (item.bool_value) + { *item.bool_value = !(*item.bool_value); prefs_put_bool(item.pref_key, *item.bool_value); update_item_value(*widget); + if (item.pref_key && strcmp(item.pref_key, "net_relay") == 0) + { + app::AppContext& app_ctx = app::AppContext::getInstance(); + app_ctx.getConfig().mesh_config.enable_relay = *item.bool_value; + app_ctx.saveConfig(); + app_ctx.applyMeshConfig(); + } } return; } - if (item.type == settings::ui::SettingType::Enum) { + if (item.type == settings::ui::SettingType::Enum) + { open_option_modal(item, *widget); return; } - if (item.type == settings::ui::SettingType::Text) { + if (item.type == settings::ui::SettingType::Text) + { open_text_modal(item, *widget); return; } + if (item.type == settings::ui::SettingType::Action) + { + if (item.pref_key && strcmp(item.pref_key, "chat_reset_mesh") == 0) + { + reset_mesh_settings(); + } + else if (item.pref_key && strcmp(item.pref_key, "chat_reset_nodes") == 0) + { + reset_node_db(); + } + else if (item.pref_key && strcmp(item.pref_key, "chat_clear_messages") == 0) + { + clear_message_db(); + } + return; + } } -static void on_filter_clicked(lv_event_t* e) { +static void on_filter_clicked(lv_event_t* e) +{ intptr_t idx = reinterpret_cast(lv_event_get_user_data(e)); if (idx < 0) return; if (s_building_list) return; @@ -672,20 +1022,24 @@ static void on_filter_clicked(lv_event_t* e) { settings::ui::input::focus_to_list(); } -static void on_filter_focused(lv_event_t* e) { +static void on_filter_focused(lv_event_t* e) +{ intptr_t idx = reinterpret_cast(lv_event_get_user_data(e)); if (idx < 0) return; if (s_building_list) return; s_pending_category = static_cast(idx); - if (!s_category_update_scheduled) { + if (!s_category_update_scheduled) + { s_category_update_scheduled = true; lv_async_call(apply_pending_category_cb, nullptr); } } -static void apply_pending_category_cb(void* /*user_data*/) { +static void apply_pending_category_cb(void* /*user_data*/) +{ s_category_update_scheduled = false; - if (s_pending_category < 0) { + if (s_pending_category < 0) + { return; } g_state.current_category = s_pending_category; @@ -696,11 +1050,13 @@ static void apply_pending_category_cb(void* /*user_data*/) { build_item_list(); } -static void on_list_back_clicked(lv_event_t* /*e*/) { +static void on_list_back_clicked(lv_event_t* /*e*/) +{ settings::ui::input::focus_to_filter(); } -static void settings_back_cb(void* /*user_data*/) { +static void settings_back_cb(void* /*user_data*/) +{ destroy(); menu_show(); } @@ -720,7 +1076,8 @@ void create(lv_obj_t* parent) layout::create_list_panel(g_state.content); g_state.filter_count = sizeof(kCategories) / sizeof(kCategories[0]); - for (size_t i = 0; i < g_state.filter_count; ++i) { + for (size_t i = 0; i < g_state.filter_count; ++i) + { lv_obj_t* btn = lv_btn_create(g_state.filter_panel); lv_obj_set_size(btn, LV_PCT(100), 22); style::apply_btn_filter(btn); @@ -740,15 +1097,18 @@ void create(lv_obj_t* parent) void destroy() { - if (g_state.modal_root) { + if (g_state.modal_root) + { modal_close(); } settings::ui::input::cleanup(); - if (g_state.root) { + if (g_state.root) + { lv_obj_del_async(g_state.root); g_state.root = nullptr; } - if (g_state.parent) { + if (g_state.parent) + { lv_obj_invalidate(g_state.parent); } g_state = settings::ui::UiState{}; diff --git a/src/ui/screens/settings/settings_state.h b/src/ui/screens/settings/settings_state.h index 40be2e04..8580b314 100644 --- a/src/ui/screens/settings/settings_state.h +++ b/src/ui/screens/settings/settings_state.h @@ -5,24 +5,29 @@ #pragma once -#include "lvgl.h" #include "../../widgets/top_bar.h" +#include "lvgl.h" #include -namespace settings::ui { +namespace settings::ui +{ -enum class SettingType { +enum class SettingType +{ Toggle, Enum, Text, + Action, }; -struct SettingOption { +struct SettingOption +{ const char* label; int value; }; -struct SettingItem { +struct SettingItem +{ const char* label; SettingType type; const SettingOption* options; @@ -35,7 +40,8 @@ struct SettingItem { const char* pref_key; }; -struct SettingsData { +struct SettingsData +{ // GPS int gps_mode = 0; int gps_sat_mask = 0x1 | 0x8 | 0x4; @@ -54,9 +60,11 @@ struct SettingsData { // Chat char user_name[32] = "TrailMate"; char short_name[16] = "TM"; + int chat_protocol = 1; int chat_region = 0; int chat_channel = 0; char chat_psk[33] = {}; + bool needs_restart = false; // Network int net_modem_preset = 0; @@ -78,13 +86,15 @@ struct SettingsData { bool advanced_debug_logs = false; }; -struct ItemWidget { +struct ItemWidget +{ const SettingItem* def = nullptr; lv_obj_t* btn = nullptr; lv_obj_t* value_label = nullptr; }; -struct UiState { +struct UiState +{ lv_obj_t* parent = nullptr; lv_obj_t* root = nullptr; lv_obj_t* content = nullptr; @@ -92,9 +102,9 @@ struct UiState { lv_obj_t* list_panel = nullptr; lv_obj_t* list_back_btn = nullptr; ::ui::widgets::TopBar top_bar; - lv_obj_t* filter_buttons[8] {}; + lv_obj_t* filter_buttons[8]{}; size_t filter_count = 0; - ItemWidget item_widgets[12] {}; + ItemWidget item_widgets[12]{}; size_t item_count = 0; int current_category = 0; diff --git a/src/ui/ui_chat.cpp b/src/ui/ui_chat.cpp index 920fce80..46dba54c 100644 --- a/src/ui/ui_chat.cpp +++ b/src/ui/ui_chat.cpp @@ -46,8 +46,8 @@ void ui_chat_enter(lv_obj_t *parent) lv_obj_set_style_radius(chat_container, 0, 0); // Create UI controller - ui_controller = std::make_unique( - chat_container, ctx.getChatService()); + ui_controller = std::unique_ptr( + new chat::ui::UiController(chat_container, ctx.getChatService())); ui_controller->init(); // Store in context (for access from main loop) diff --git a/src/ui/ui_contacts.cpp b/src/ui/ui_contacts.cpp index 7df6b6cd..fe79482f 100644 --- a/src/ui/ui_contacts.cpp +++ b/src/ui/ui_contacts.cpp @@ -12,7 +12,9 @@ #include "widgets/top_bar.h" #include "ui_common.h" #include "../../app/app_context.h" +#include "../../chat/domain/chat_types.h" #include +#include #define CONTACTS_DEBUG 1 #if CONTACTS_DEBUG @@ -115,10 +117,39 @@ void refresh_contacts_data_impl() { app::AppContext& app_ctx = app::AppContext::getInstance(); chat::contacts::ContactService& contact_service = app_ctx.getContactService(); - + + auto should_keep = [](const chat::contacts::NodeInfo& node, chat::MeshProtocol protocol) { + if (protocol == chat::MeshProtocol::Meshtastic) { + return node.protocol != chat::contacts::NodeProtocolType::MeshCore; + } + if (protocol == chat::MeshProtocol::MeshCore) { + return node.protocol != chat::contacts::NodeProtocolType::Meshtastic; + } + return true; + }; + + chat::MeshProtocol protocol = app_ctx.getConfig().mesh_protocol; + g_contacts_state.contacts_list = contact_service.getContacts(); + g_contacts_state.contacts_list.erase( + std::remove_if( + g_contacts_state.contacts_list.begin(), + g_contacts_state.contacts_list.end(), + [protocol, &should_keep](const chat::contacts::NodeInfo& node) { + return !should_keep(node, protocol); + }), + g_contacts_state.contacts_list.end()); + g_contacts_state.nearby_list = contact_service.getNearby(); - + g_contacts_state.nearby_list.erase( + std::remove_if( + g_contacts_state.nearby_list.begin(), + g_contacts_state.nearby_list.end(), + [protocol, &should_keep](const chat::contacts::NodeInfo& node) { + return !should_keep(node, protocol); + }), + g_contacts_state.nearby_list.end()); + CONTACTS_LOG("[Contacts] Data refreshed: %zu contacts, %zu nearby\n", g_contacts_state.contacts_list.size(), g_contacts_state.nearby_list.size()); diff --git a/src/ui/ui_controller.cpp b/src/ui/ui_controller.cpp index fcd55be1..92f7f751 100644 --- a/src/ui/ui_controller.cpp +++ b/src/ui/ui_controller.cpp @@ -4,19 +4,23 @@ */ #include "ui_controller.h" +#include "../../app/app_context.h" #include "../sys/event_bus.h" #include "ui_common.h" -#include "../../app/app_context.h" #include -namespace chat { -namespace ui { +namespace chat +{ +namespace ui +{ -namespace { +namespace +{ void handle_channel_click(chat::ChannelId channel, void* user_data) { auto* controller = static_cast(user_data); - if (controller) { + if (controller) + { controller->onChannelClicked(channel); } } @@ -24,7 +28,8 @@ void handle_channel_click(chat::ChannelId channel, void* user_data) void handle_conversation_action(bool compose, void* user_data) { auto* controller = static_cast(user_data); - if (controller) { + if (controller) + { controller->handleConversationAction(compose); } } @@ -32,7 +37,8 @@ void handle_conversation_action(bool compose, void* user_data) void handle_compose_back(void* user_data) { auto* controller = static_cast(user_data); - if (controller) { + if (controller) + { controller->handleComposeAction(false); } } @@ -40,7 +46,8 @@ void handle_compose_back(void* user_data) void handle_compose_action(bool send, void* user_data) { auto* controller = static_cast(user_data); - if (controller) { + if (controller) + { controller->handleComposeAction(send); } } @@ -48,7 +55,8 @@ void handle_compose_action(bool send, void* user_data) void handle_back(void* user_data) { auto* controller = static_cast(user_data); - if (controller) { + if (controller) + { controller->exitToMenu(); } } @@ -56,7 +64,8 @@ void handle_back(void* user_data) void handle_conversation_back(void* user_data) { auto* controller = static_cast(user_data); - if (controller) { + if (controller) + { controller->backToList(); } } @@ -65,34 +74,41 @@ void handle_conversation_back(void* user_data) UiController::UiController(lv_obj_t* parent, chat::ChatService& service) : parent_(parent), service_(service), state_(State::ChannelList), current_channel_(chat::ChannelId::PRIMARY), - current_conv_(chat::ConversationId(chat::ChannelId::PRIMARY, 0)) { + current_conv_(chat::ConversationId(chat::ChannelId::PRIMARY, 0)) +{ } -UiController::~UiController() { +UiController::~UiController() +{ channel_list_.reset(); conversation_.reset(); cleanupComposeIme(); compose_.reset(); } -void UiController::cleanupComposeIme() { - if (compose_ime_) { +void UiController::cleanupComposeIme() +{ + if (compose_ime_) + { compose_ime_->detach(); compose_ime_.reset(); } } -void UiController::init() { +void UiController::init() +{ switchToChannelList(); refreshUnreadCounts(); } -void UiController::update() { +void UiController::update() +{ // Process incoming messages service_.processIncoming(); - + // Refresh UI if needed - if (state_ == State::ChannelList && channel_list_) { + if (state_ == State::ChannelList && channel_list_) + { refreshUnreadCounts(); } } @@ -100,147 +116,181 @@ void UiController::update() { void UiController::onChannelClicked(chat::ChannelId channel) { (void)channel; - if (channel_list_) { + if (channel_list_) + { handleChannelSelected(channel_list_->getSelectedConversation()); } } -void UiController::backToList() { +void UiController::backToList() +{ switchToChannelList(); } -void UiController::onInput(const sys::InputEvent& event) { - switch (state_) { - case State::ChannelList: - if (event.input_type == sys::InputEvent::RotaryTurn) { - // Handle rotary navigation - // (Implementation depends on rotary event details) - } else if (event.input_type == sys::InputEvent::RotaryPress) { - if (channel_list_) { - handleChannelSelected(channel_list_->getSelectedConversation()); - } - } else if (event.input_type == sys::InputEvent::KeyPress && event.value == 27) { - // ESC - return to main menu (handled by parent) +void UiController::onInput(const sys::InputEvent& event) +{ + switch (state_) + { + case State::ChannelList: + if (event.input_type == sys::InputEvent::RotaryTurn) + { + // Handle rotary navigation + // (Implementation depends on rotary event details) + } + else if (event.input_type == sys::InputEvent::RotaryPress) + { + if (channel_list_) + { + handleChannelSelected(channel_list_->getSelectedConversation()); } - break; - - case State::Conversation: - if (event.input_type == sys::InputEvent::KeyPress && event.value == 27) { - // ESC - return to channel list - switchToChannelList(); - } - break; + } + else if (event.input_type == sys::InputEvent::KeyPress && event.value == 27) + { + // ESC - return to main menu (handled by parent) + } + break; - case State::Compose: - if (event.input_type == sys::InputEvent::KeyPress && event.value == 27) { - // ESC - cancel compose - switchToConversation(current_conv_); - } - break; - - default: - break; + case State::Conversation: + if (event.input_type == sys::InputEvent::KeyPress && event.value == 27) + { + // ESC - return to channel list + switchToChannelList(); + } + break; + + case State::Compose: + if (event.input_type == sys::InputEvent::KeyPress && event.value == 27) + { + // ESC - cancel compose + switchToConversation(current_conv_); + } + break; + + default: + break; } } -void UiController::onChatEvent(sys::Event* event) { - if (!event) { +void UiController::onChatEvent(sys::Event* event) +{ + if (!event) + { return; } - - switch (event->type) { - case sys::EventType::ChatNewMessage: { - sys::ChatNewMessageEvent* msg_event = (sys::ChatNewMessageEvent*)event; - Serial.printf("[UiController::onChatEvent] ChatNewMessage received: channel=%d, state=%d, current_channel=%d\n", - msg_event->channel, (int)state_, (int)current_channel_); - - // Note: Haptic feedback is now handled globally in AppContext::update() - // No need to call vibrator() here - - if (state_ == State::Conversation && - (uint8_t)current_channel_ == msg_event->channel) { - Serial.printf("[UiController::onChatEvent] Updating conversation UI...\n"); - auto messages = service_.getRecentMessages(current_conv_, 50); - conversation_->clearMessages(); - for (const auto& m : messages) { - conversation_->addMessage(m); - } - conversation_->scrollToBottom(); + + switch (event->type) + { + case sys::EventType::ChatNewMessage: + { + sys::ChatNewMessageEvent* msg_event = (sys::ChatNewMessageEvent*)event; + Serial.printf("[UiController::onChatEvent] ChatNewMessage received: channel=%d, state=%d, current_channel=%d\n", + msg_event->channel, (int)state_, (int)current_channel_); + + // Note: Haptic feedback is now handled globally in AppContext::update() + // No need to call vibrator() here + + if (state_ == State::Conversation && + (uint8_t)current_channel_ == msg_event->channel) + { + Serial.printf("[UiController::onChatEvent] Updating conversation UI...\n"); + auto messages = service_.getRecentMessages(current_conv_, 50); + conversation_->clearMessages(); + for (const auto& m : messages) + { + conversation_->addMessage(m); } - refreshUnreadCounts(); - break; + conversation_->scrollToBottom(); } - - case sys::EventType::ChatSendResult: { - sys::ChatSendResultEvent* result_event = (sys::ChatSendResultEvent*)event; - // Update message status in conversation - // (Would need to track message indices) - break; - } - - case sys::EventType::ChatUnreadChanged: { - refreshUnreadCounts(); - break; - } - - default: - break; + refreshUnreadCounts(); + break; } - + + case sys::EventType::ChatSendResult: + { + sys::ChatSendResultEvent* result_event = (sys::ChatSendResultEvent*)event; + // Update message status in conversation + // (Would need to track message indices) + break; + } + + case sys::EventType::ChatUnreadChanged: + { + refreshUnreadCounts(); + break; + } + + default: + break; + } + delete event; } -void UiController::switchToChannelList() { +void UiController::switchToChannelList() +{ state_ = State::ChannelList; - - if (conversation_) { + + if (conversation_) + { conversation_.reset(); } - if (compose_) { + if (compose_) + { cleanupComposeIme(); compose_.reset(); } - - if (!channel_list_) { + + if (!channel_list_) + { channel_list_.reset(new ChatMessageListScreen(parent_)); channel_list_->setChannelSelectCallback(handle_channel_click, this); channel_list_->setBackCallback(handle_back, this); } - + refreshUnreadCounts(); } -void UiController::switchToConversation(chat::ConversationId conv) { +void UiController::switchToConversation(chat::ConversationId conv) +{ state_ = State::Conversation; current_channel_ = conv.channel; current_conv_ = conv; - - if (channel_list_) { + + if (channel_list_) + { channel_list_.reset(); } - if (compose_) { + if (compose_) + { cleanupComposeIme(); compose_.reset(); } - - if (!conversation_) { + + if (!conversation_) + { conversation_.reset(new ChatConversationScreen(parent_, conv)); conversation_->setActionCallback(handle_conversation_action, this); conversation_->setBackCallback(handle_conversation_back, this); } // 更新标题(优先使用联系人昵称,否则使用short_name) std::string title = "Broadcast"; - if (conv.peer != 0) { + if (conv.peer != 0) + { // Try to get contact name first app::AppContext& app_ctx = app::AppContext::getInstance(); std::string contact_name = app_ctx.getContactService().getContactName(conv.peer); - if (!contact_name.empty()) { + if (!contact_name.empty()) + { title = contact_name; - } else { + } + else + { // Fallback to short_name from conversation meta auto convs = service_.getConversations(); - for (const auto& c : convs) { - if (c.id == conv) { + for (const auto& c : convs) + { + if (c.id == conv) + { title = c.name; break; } @@ -249,32 +299,37 @@ void UiController::switchToConversation(chat::ConversationId conv) { } conversation_->setHeaderText(title.c_str(), nullptr); conversation_->updateBatteryFromBoard(); - + // Load recent messages auto messages = service_.getRecentMessages(conv, 50); conversation_->clearMessages(); - for (const auto& msg : messages) { + for (const auto& msg : messages) + { conversation_->addMessage(msg); } conversation_->scrollToBottom(); - + // Mark as read service_.markConversationRead(conv); } -void UiController::switchToCompose(chat::ConversationId conv) { +void UiController::switchToCompose(chat::ConversationId conv) +{ state_ = State::Compose; current_channel_ = conv.channel; current_conv_ = conv; - if (channel_list_) { + if (channel_list_) + { channel_list_.reset(); } - if (conversation_) { + if (conversation_) + { conversation_.reset(); } - if (!compose_) { + if (!compose_) + { compose_.reset(new ChatComposeScreen(parent_, conv)); compose_->setActionCallback(handle_compose_action, this); compose_->setBackCallback(handle_compose_back, this); @@ -282,31 +337,42 @@ void UiController::switchToCompose(chat::ConversationId conv) { lv_obj_t* compose_content = compose_->getContent(); lv_obj_t* compose_textarea = compose_->getTextarea(); - if (compose_content && compose_textarea) { - if (compose_ime_) { + if (compose_content && compose_textarea) + { + if (compose_ime_) + { compose_ime_->detach(); - } else { + } + else + { compose_ime_.reset(new ::ui::widgets::ImeWidget()); } compose_ime_->init(compose_content, compose_textarea); compose_->attachImeWidget(compose_ime_.get()); - if (lv_group_t* g = lv_group_get_default()) { + if (lv_group_t* g = lv_group_get_default()) + { lv_group_add_obj(g, compose_ime_->focus_obj()); } } // 更新 Compose 页头:优先使用联系人昵称,否则使用short_name std::string title = "Broadcast"; - if (conv.peer != 0) { + if (conv.peer != 0) + { // Try to get contact name first app::AppContext& app_ctx = app::AppContext::getInstance(); std::string contact_name = app_ctx.getContactService().getContactName(conv.peer); - if (!contact_name.empty()) { + if (!contact_name.empty()) + { title = contact_name; - } else { + } + else + { // Fallback to short_name from conversation meta auto convs = service_.getConversations(); - for (const auto& c : convs) { - if (c.id == conv) { + for (const auto& c : convs) + { + if (c.id == conv) + { title = c.name; break; } @@ -316,41 +382,50 @@ void UiController::switchToCompose(chat::ConversationId conv) { compose_->setHeaderText(title.c_str(), "RSSI --"); } -void UiController::handleChannelSelected(const chat::ConversationId& conv) { +void UiController::handleChannelSelected(const chat::ConversationId& conv) +{ switchToConversation(conv); service_.switchChannel(conv.channel); } -void UiController::handleSendMessage(const std::string& text) { - if (text.empty()) { +void UiController::handleSendMessage(const std::string& text) +{ + if (text.empty()) + { return; } - service_.sendText(current_channel_, text, current_conv_.peer); } -void UiController::refreshUnreadCounts() { - if (!channel_list_) { +void UiController::refreshUnreadCounts() +{ + if (!channel_list_) + { return; } auto convs = service_.getConversations(); - + // Update conversation names with contact nicknames app::AppContext& app_ctx = app::AppContext::getInstance(); - for (auto& conv : convs) { - if (conv.id.peer != 0) { + for (auto& conv : convs) + { + if (conv.id.peer != 0) + { std::string contact_name = app_ctx.getContactService().getContactName(conv.id.peer); - if (!contact_name.empty()) { + if (!contact_name.empty()) + { conv.name = contact_name; } // Otherwise keep the short_name from ConversationMeta } } - + channel_list_->setConversations(convs); - for (size_t i = 0; i < convs.size(); ++i) { - if (convs[i].id == current_conv_) { + for (size_t i = 0; i < convs.size(); ++i) + { + if (convs[i].id == current_conv_) + { channel_list_->setSelected(static_cast(i)); break; } @@ -360,33 +435,40 @@ void UiController::refreshUnreadCounts() { channel_list_->updateBatteryFromBoard(); } -void UiController::handleConversationAction(bool compose) { +void UiController::handleConversationAction(bool compose) +{ (void)compose; switchToCompose(current_conv_); } -void UiController::handleComposeAction(bool send) { - if (!compose_) { +void UiController::handleComposeAction(bool send) +{ + if (!compose_) + { return; } - if (!send) { + if (!send) + { switchToConversation(current_conv_); return; } std::string text = compose_->getText(); - if (!text.empty()) { + if (!text.empty()) + { handleSendMessage(text); } switchToConversation(current_conv_); } -void UiController::exitToMenu() { +void UiController::exitToMenu() +{ // Clean up UI objects cleanupComposeIme(); compose_.reset(); conversation_.reset(); channel_list_.reset(); - if (parent_) { + if (parent_) + { lv_obj_del(parent_); parent_ = nullptr; }