6. 消息格式

消息格式使用 Google's Protocol Buffers 来编解码。 手机端可以选择任意语言版本,比如kotlin。 因为编解码规则是开源的,所以有的语言即使不在官方支持范围内也可以找到第三方的开源实现。

6.1. 数据结构定义文件

数据格式定义可以从这里下载:proto.zip.

6.2. 数据封包

因为每个数据包长度不会超过MTU,所以经BLE发送的包不做封包处理,直接发送编好码的数据。

6.3. 最外层格式

最外层的数据结构见 message Lynx {}。里面包含了 RequestResponseIndication 三选一的数据。 具体结构参考如下源文件。

syntax = "proto3";

import "handshake.proto";
import "copilot.proto";
import "measure.proto";
import "last_result.proto";

message Request {
  int32 index = 1; // Assigned by Phone side.
  oneof request {
    Handshake.Request handshake = 2;
    Copilot.Request copilot = 3;
    Measure.Request measure = 4;
    LatestResult.Request latestResult = 5;
  }
}

message Response {
  int32 index = 1; // Same as the corresponding Request
  oneof response {
    Handshake.Response handshake = 2;
    Copilot.Response copilot = 3;
    Measure.Response measure = 4;
    LatestResult.Response  latestResult = 5;
  }
}

message Indication {
  int32 index = 1; // Same as the corresponding Request
  oneof indication {
    Copilot.Indication copilot = 2;
    Measure.Indication measure = 3;
  }
}

message Lynx {
  oneof  message {
    Request request = 1;
    Response response = 2;
    Indication indication = 3;
  }
}

6.4. 握手格式

握手数据可以用来获取硬件的信息。

握手数据分为 RequestResponse 两种,定义在 message Handshake {} 中, 在 message Lynx {} 中被引用。

syntax = "proto3";

import "error.proto";

enum HardwareType {
  UNKNOWN = 0;
  TIMING_CUSHION = 1;
  STRETCH_DETECTOR = 2;
  JUMP_DETECTOR = 3;
}

message Handshake {
  message Request {

  }

  message Response {
    int32 softVersion = 1;
    HardwareType hardwareType = 2;
    LynxError error = 3;
  }
}

6.5. 副驾格式

副驾数据用来分享另一个作为结束计时的压力垫的信息。手机需要扫描另一个压力垫的NFC,获取序列号,然后通过此消息分享副压力垫的信息。

副驾数据分为 RequestResponseIndication 三种,定义在 message Copilot {} 中, 在 message Lynx {} 中被引用。

syntax = "proto3";

import "error.proto";

message Copilot {
  message Request {
    string sn = 1;
    int32 timeoutInSecond = 2;
  }

  message Response {
    LynxError error = 1;
  }

  message Indication {
    LynxError error = 1;
  }
}

6.6. 测量格式

测量数据用来传输测量相关的数据。

测量数据分为 RequestResponseIndication 三种,定义在 message Measure {} 中, 在 message Lynx {} 中被引用。

syntax = "proto3";

import "error.proto";

message Measure {
  message Request {
    bool start = 1;
    int32 timeoutInSecond = 2;
  }

  message Response {
    LynxError error = 1;
  }

  message Indication {
    // Unit in millisecond or millimeter
    int32 result = 1;
    LynxError error = 2;
  }
}

6.7. 最后结果格式

如果手机没有收到设备发来的测试结果,那么可以通过此命令来查询最后一次的测量结果。

最后结果数据分为 RequestResponse 两种,定义在 message LastResult {} 中, 在 message Lynx {} 中被引用。

syntax = "proto3";

import "error.proto";


message LatestResult {
  message Request {}

  message Response {
    int32 result = 1;
    LynxError error = 2;
  }
}

6.8. 错误码

错误码的定义如下:

syntax = "proto3";

enum LynxError {
  SUCCESS = 0;
  HARDWARE_TYPE_UNKNOWN = 1;
  COMMAND_NOT_SUPPORT = 2;
  COMMAND_UNKNOWN = 3;
  TIME_SYNC_SERVER_START_FAIL = 4;
  TIME_SYNC_CLIENT_START_FAIL = 5;
  COPILOT_CONNECT_FAIL = 6;
  COPILOT_INDEX_MISMATCH = 7;
  COPILOT_SYNC_CONNECT_FAIL = 8;
  COMMAND_IN_PROCESS = 9;
}