Home | History | Annotate | Download | only in src
      1 // LINT: LEGACY_NAMES
      2 syntax = "proto2";
      3 
      4 package clearcut.connectivity;
      5 
      6 option java_package = "com.android.server.connectivity.metrics";
      7 option java_outer_classname = "IpConnectivityLogClass";
      8 
      9 // NetworkId represents the id given by the system to a physical network on the
     10 // Android device. It is used to relates events to each other for devices with
     11 // multiple networks (WiFi, 4G, ...).
     12 // Deprecated since version 3, replaced by top-level network_id field in
     13 // IpConnectivityEvent.
     14 message NetworkId {
     15   // Every network gets assigned a network_id on creation based on order of
     16   // creation. Thus network_id N is assigned to the network created directly
     17   // after network N-1. Thus there is no PII involved here. Zero means no
     18   // network. The value 0 is never assigned to a network.
     19   optional int32 network_id = 1;
     20 };
     21 
     22 // LinkLayer describes a physical link layer technology used by a network.
     23 // It is not intended to map one to one to the TRANSPORT_* constants defined in
     24 // android.net.NetworkCapabilities. Instead it is intended to be used as
     25 // a dimension field for metrics events and aggregated metrics.
     26 // Next tag: 10
     27 enum LinkLayer {
     28   // An unknown link layer technology.
     29   UNKNOWN   = 0;
     30 
     31   BLUETOOTH = 1;
     32   CELLULAR  = 2;
     33   ETHERNET  = 3;
     34   WIFI      = 4;
     35   WIFI_P2P  = 7;
     36   WIFI_NAN  = 8; // Also known as WiFi Aware
     37   LOWPAN    = 9;
     38 
     39   // Indicates that the link layer dimension is not relevant for the metrics or
     40   // event considered.
     41   NONE      = 5;
     42 
     43   // Indicates that the metrics or event considered may involve several links.
     44   MULTIPLE  = 6;
     45 };
     46 
     47 // A pair of (key, value) integers for describing histogram-like statistics.
     48 message Pair {
     49   optional int32 key = 1;
     50   optional int32 value = 2;
     51 };
     52 
     53 // An event recorded when the system default network disconnects or the system
     54 // switches to a new default network. An event is also recorded to cover gaps
     55 // without a default network.
     56 // Next tag: 12
     57 message DefaultNetworkEvent {
     58 
     59   // Reason why this network stopped being the default.
     60   enum LostReason {
     61     UNKNOWN       = 0;
     62     OUTSCORED     = 1;
     63     INVALIDATION  = 2;
     64     DISCONNECT    = 3;
     65   };
     66 
     67   // Whether the network supports IPv4, IPv6, or both.
     68   enum IPSupport {
     69     NONE = 0;
     70     IPV4 = 1;
     71     IPV6 = 2;
     72     DUAL = 3;
     73   };
     74 
     75   // Duration in milliseconds when this network was the default.
     76   // Since P.
     77   optional int64 default_network_duration_ms = 5;
     78 
     79   // Duration in milliseconds when this default network Internet access was
     80   // validated. This field is equal to 0 for DefaultNetworkEvents representing
     81   // lack of a default network.
     82   // Since P.
     83   optional int64 validation_duration_ms = 11;
     84 
     85   // Network score of this network when it became the default network.
     86   // Or 0 if this event represents a period without a default network.
     87   // Since P.
     88   optional int64 initial_score = 7;
     89 
     90   // Network score of this network when it stopped being the default network.
     91   // Or 0 if this event represents a period without a default network.
     92   // Since P.
     93   optional int64 final_score = 8;
     94 
     95   // Best available information about IP support of this default network.
     96   // Or NONE if this event represents a period without a default network.
     97   // Since P.
     98   optional IPSupport ip_support = 9;
     99 
    100   // LinkLayer of the previous default network. Ignores any previous period
    101   // without a default network.
    102   // Since P
    103   optional LinkLayer previous_default_network_link_layer = 10;
    104 
    105   // Deprecated fields
    106 
    107   // A value of 0 means this is a loss of the system default network.
    108   // Deprecated since version 3. Replaced by top level network_id.
    109   optional NetworkId network_id = 1 [deprecated = true];
    110 
    111   // A value of 0 means there was no previous default network.
    112   // Deprecated since version 3. Replaced by previous_default_network_id.
    113   optional NetworkId previous_network_id = 2 [deprecated = true];
    114 
    115   // Best available information about IP support of the previous network when
    116   // disconnecting or switching to a new default network.
    117   // Deprecated since version 3. Replaced by ip_support field.
    118   optional IPSupport previous_network_ip_support = 3 [deprecated = true];
    119 
    120   // The transport types of the new default network, represented by
    121   // TRANSPORT_* constants as defined in NetworkCapabilities.
    122   // Deprecated since version 3. Replaced by top-level transports field.
    123   repeated int32 transport_types = 4 [deprecated = true];
    124 
    125   // Duration in milliseconds without a default network. This field is non-zero
    126   // only for DefaultNetworkEvents representing lack of a default network.
    127   // Since P.
    128   optional int64 no_default_network_duration_ms = 6 [deprecated = true];
    129 };
    130 
    131 // Logs IpReachabilityMonitor probe events and NUD_FAILED events.
    132 // This message is associated to android.net.metrics.IpReachabilityEvent.
    133 // Next tag: 3.
    134 message IpReachabilityEvent {
    135   // The interface name (wlan, rmnet, lo, ...) on which the probe was sent.
    136   // Deprecated since version 2, to be replaced by link_layer field.
    137   optional string if_name = 1 [deprecated = true];
    138 
    139   // The event type code of the probe, represented by constants defined in
    140   // android.net.metrics.IpReachabilityEvent.
    141   // NUD_FAILED_ORGANIC and PROVISIONING_LOST_ORGANIC recorded since version 1.
    142   optional int32 event_type = 2;
    143 };
    144 
    145 // Logs NetworkMonitor and ConnectivityService events related to the state of
    146 // a network: connection, evaluation, validation, lingering, and disconnection.
    147 // This message is associated to android.net.metrics.NetworkEvent.
    148 // Next tag: 4.
    149 message NetworkEvent {
    150   // The id of the network on which this event happened.
    151   // Deprecated since version 3.
    152   optional NetworkId network_id = 1 [deprecated = true];
    153 
    154   // The type of network event, represented by NETWORK_* constants defined in
    155   // android.net.metrics.NetworkEvent.
    156   optional int32 event_type = 2;
    157 
    158   // Only valid after finishing evaluating a network for Internet connectivity.
    159   // The time it took for this evaluation to complete.
    160   optional int32 latency_ms = 3;
    161 }
    162 
    163 // Logs individual captive portal probing events that are performed when
    164 // evaluating or reevaluating networks for Internet connectivity.
    165 // This message is associated to android.net.metrics.ValidationProbeEvent.
    166 // Next tag: 5.
    167 message ValidationProbeEvent {
    168   // The id of the network for which the probe was sent.
    169   // Deprecated since version 3.
    170   optional NetworkId network_id = 1 [deprecated = true];
    171 
    172   // The time it took for that probe to complete or time out.
    173   optional int32 latency_ms = 2;
    174 
    175   // The type of portal probe, represented by PROBE_* constants defined in
    176   // android.net.metrics.ValidationProbeEvent.
    177   optional int32 probe_type = 3;
    178 
    179   // The http code result of the probe test.
    180   optional int32 probe_result = 4;
    181 }
    182 
    183 // Logs DNS lookup latencies.
    184 // This message is associated to android.net.metrics.DnsEvent.
    185 // Next tag: 11
    186 message DNSLookupBatch {
    187 
    188   // The time it took for successful DNS lookups to complete.
    189   // The number of repeated values can be less than getaddrinfo_query_count
    190   // + gethostbyname_query_count in case of event rate-limiting.
    191   repeated int32 latencies_ms = 4;
    192 
    193   // The total number of getaddrinfo queries.
    194   // Since version 4.
    195   optional int64 getaddrinfo_query_count = 5;
    196 
    197   // The total number of gethostbyname queries.
    198   // Since version 4.
    199   optional int64 gethostbyname_query_count = 6;
    200 
    201   // The total number of getaddrinfo errors.
    202   // Since version 4.
    203   optional int64 getaddrinfo_error_count = 7;
    204 
    205   // The total number of gethostbyname errors.
    206   // Since version 4.
    207   optional int64 gethostbyname_error_count = 8;
    208 
    209   // Counts of all errors returned by getaddrinfo.
    210   // The Pair key field is the getaddrinfo error value.
    211   // The value field is the count for that return value.
    212   // Since version 4
    213   repeated Pair getaddrinfo_errors = 9;
    214 
    215   // Counts of all errors returned by gethostbyname.
    216   // The Pair key field is the gethostbyname errno value.
    217   // the Pair value field is the count for that errno code.
    218   // Since version 4
    219   repeated Pair gethostbyname_errors = 10;
    220 
    221 
    222   // Deprecated fields
    223 
    224   // The id of the network on which the DNS lookups took place.
    225   // Deprecated since version 3.
    226   optional NetworkId network_id = 1 [deprecated = true];
    227 
    228   // The types of the DNS lookups, as defined in android.net.metrics.DnsEvent.
    229   // Deprecated since version 3.
    230   repeated int32 event_types = 2 [deprecated = true];
    231 
    232   // The return values of the DNS resolver for each DNS lookups.
    233   // Deprecated since version 3.
    234   repeated int32 return_codes = 3 [deprecated = true];
    235 };
    236 
    237 // Represents a collections of DNS lookup latencies and counters for a
    238 // particular combination of DNS query type and return code.
    239 // Since version 2.
    240 // Next tag: 7.
    241 message DNSLatencies {
    242   // The type of the DNS lookups, as defined in android.net.metrics.DnsEvent.
    243   // Acts as a key for a set of DNS query results.
    244   // Possible values are: 0 for getaddrinfo, 1 for gethostbyname.
    245   optional int32 type = 1;
    246 
    247   // The return value of the DNS resolver for the DNS lookups.
    248   // Acts as a key for a set of DNS query results.
    249   // Possible values are: 0 for success, or errno code for failures.
    250   optional int32 return_code = 2;
    251 
    252   // The number of query operations recorded.
    253   optional int32 query_count = 3;
    254 
    255   // The number of query operations returning A IPv4 records.
    256   optional int32 a_count = 4;
    257 
    258   // The number of query operations returning AAAA IPv6 records.
    259   optional int32 aaaa_count = 5;
    260 
    261   // The time it took for each DNS lookup to complete. The number of repeated
    262   // values can be less than query_count in case of event rate-limiting.
    263   repeated int32 latencies_ms = 6;
    264 };
    265 
    266 // Represents latency and errno statistics of the connect() system call.
    267 // Since version 2.
    268 // Next tag: 7
    269 message ConnectStatistics {
    270   // The number of connect() operations recorded.
    271   optional int32 connect_count = 1;
    272 
    273   // The number of connect() operations done in blocking mode.
    274   // Since version 3.
    275   optional int32 connect_blocking_count = 5;
    276 
    277   // The number of connect() operations with IPv6 socket address.
    278   optional int32 ipv6_addr_count = 2;
    279 
    280   // The time it took for successful blocking connect() operations to complete
    281   // The number of repeated values can be less than connect_blocking_count in
    282   // case of event rate-limiting.
    283   repeated int32 latencies_ms = 3;
    284 
    285   // The time it took for successful connect() operation to complete in
    286   // non-blocking mode. The number of repeated values can be less than
    287   // connect_count - connect_blocking_count in case of event rate-limiting.
    288   repeated int32 non_blocking_latencies_ms = 6;
    289 
    290   // Counts of all error values returned by failed connect() operations.
    291   // The Pair key field is the errno code. The Pair value field is the count
    292   // for that errno code.
    293   repeated Pair errnos_counters = 4;
    294 };
    295 
    296 // Represents a DHCP event on a single interface, which can be a DHCPClient
    297 // state transition or a response packet parsing error.
    298 // This message is associated to android.net.metrics.DhcpClientEvent and
    299 // android.net.metrics.DhcpErrorEvent.
    300 // Next tag: 5
    301 message DHCPEvent {
    302   // The interface name (wlan, rmnet, lo, ...) on which the event happened.
    303   // Deprecated since version 2, to be replaced by link_layer field.
    304   optional string if_name = 1 [deprecated = true];
    305 
    306   oneof value {
    307     // The name of a state in the DhcpClient state machine, represented by
    308     // the inner classes of android.net.dhcp.DhcpClient.
    309     string state_transition = 2;
    310 
    311     // The error code of a DHCP error, represented by constants defined in
    312     // android.net.metrics.DhcpErrorEvent.
    313     int32 error_code = 3;
    314   }
    315 
    316   // Lifetime duration in milliseconds of a DhcpClient state, or transition
    317   // time in milliseconds between specific pairs of DhcpClient's states.
    318   // Only populated since version 1, when state_transition is populated.
    319   optional int32 duration_ms = 4;
    320 }
    321 
    322 // Represents the generation of an Android Packet Filter program.
    323 // Since version 1.
    324 // Next tag: 8
    325 message ApfProgramEvent {
    326   // Maximum lifetime of the program in seconds.
    327   optional int64 lifetime = 1;
    328 
    329   // Effective lifetime of the program in seconds from the time the
    330   // program was installed to the time it was replaced or removed.
    331   optional int64 effective_lifetime = 7;
    332 
    333   // Number of RAs filtered by the APF program.
    334   optional int32 filtered_ras = 2;
    335 
    336   // Total number of RAs to filter currently tracked by ApfFilter. Can be more
    337   // than filtered_ras if all available program size was exhausted.
    338   optional int32 current_ras = 3;
    339 
    340   // Length of the APF program in bytes.
    341   optional int32 program_length = 4;
    342 
    343   // True if the APF program is dropping multicast and broadcast traffic.
    344   optional bool drop_multicast = 5;
    345 
    346   // True if the interface on which APF runs has an IPv4 address.
    347   optional bool has_ipv4_addr = 6;
    348 }
    349 
    350 // Represents Router Advertisement listening statistics for an interface with
    351 // Android Packet Filter enabled.
    352 // Since version 1.
    353 // Next tag: 15
    354 message ApfStatistics {
    355   // The time interval in milliseconds these stastistics cover.
    356   optional int64 duration_ms = 1;
    357 
    358   // The total number of received RAs.
    359   optional int32 received_ras = 2;
    360 
    361   // The total number of received RAs that matched a known RA.
    362   optional int32 matching_ras = 3;
    363 
    364   // The total number of received RAs ignored due to the MAX_RAS limit.
    365   optional int32 dropped_ras = 5;
    366 
    367   // The total number of received RAs with an effective lifetime of 0 seconds.
    368   // Effective lifetime for APF is the minimum of all lifetimes in a RA.
    369   optional int32 zero_lifetime_ras = 6;
    370 
    371   // The total number of received RAs that could not be parsed.
    372   optional int32 parse_errors = 7;
    373 
    374   // The total number of APF program updates triggered by an RA reception.
    375   optional int32 program_updates = 8;
    376 
    377   // The maximum APF program size in byte advertised by hardware.
    378   optional int32 max_program_size = 9;
    379 
    380   // The total number of successful APF program updates triggered by any state
    381   // change in ApfFilter. Since version 3.
    382   optional int32 program_updates_all = 10;
    383 
    384   // The total number of APF program updates triggered when disabling the
    385   // multicast filter. Since version 3.
    386   // Since version 4.
    387   optional int32 program_updates_allowing_multicast = 11;
    388 
    389   // The total number of packets processed by the APF interpreter.
    390   // Since version 4.
    391   optional int32 total_packet_processed = 12;
    392 
    393   // The total number of packets dropped by the APF interpreter.
    394   // Since version 4.
    395   optional int32 total_packet_dropped = 13;
    396 
    397   // List of hardware counters collected by the APF interpreter.
    398   // The Pair key is the counter id, defined in android.net.metrics.ApfStats.
    399   // The Pair value is the counter value.
    400   // Since version 4.
    401   repeated Pair hardware_counters = 14;
    402 }
    403 
    404 // Represents the reception of a Router Advertisement packet for an interface
    405 // with Android Packet Filter enabled.
    406 // Since version 1.
    407 // Next tag: 7.
    408 message RaEvent {
    409   // All lifetime values are expressed in seconds. The default value for an
    410   // option lifetime that was not present in the RA option list is -1.
    411   // The lifetime of an option (e.g., the Prefix Information Option) is the
    412   // minimum lifetime of all such options in the packet.
    413 
    414   // The value of the router lifetime in the RA packet.
    415   optional int64 router_lifetime = 1;
    416 
    417   // Prefix valid lifetime from the prefix information option.
    418   optional int64 prefix_valid_lifetime = 2;
    419 
    420   // Prefix preferred lifetime from the prefix information option.
    421   optional int64 prefix_preferred_lifetime = 3;
    422 
    423   // Route info lifetime.
    424   optional int64 route_info_lifetime = 4;
    425 
    426   // Recursive DNS server lifetime.
    427   optional int64 rdnss_lifetime = 5;
    428 
    429   // DNS search list lifetime.
    430   optional int64 dnssl_lifetime = 6;
    431 }
    432 
    433 // Represents an IP provisioning event in IpManager and how long the
    434 // provisioning action took.
    435 // This message is associated to android.net.metrics.IpManagerEvent.
    436 // Next tag: 4.
    437 message IpProvisioningEvent {
    438   // The interface name (wlan, rmnet, lo, ...) on which the probe was sent.
    439   // Deprecated since version 2, to be replaced by link_layer field.
    440   optional string if_name = 1 [deprecated = true];
    441 
    442   // The code of the IP provisioning event, represented by constants defined in
    443   // android.net.metrics.IpManagerEvent.
    444   optional int32 event_type = 2;
    445 
    446   // The duration of the provisioning action that resulted in this event.
    447   optional int32 latency_ms = 3;
    448 }
    449 
    450 // Represents statistics from a single android Network.
    451 // Since version 4. Replace NetworkEvent.
    452 // Next tag: 9.
    453 message NetworkStats {
    454 
    455   // Duration of this Network lifecycle in milliseconds.
    456   optional int64 duration_ms = 1;
    457 
    458   // Information about IP support of this network.
    459   optional DefaultNetworkEvent.IPSupport ip_support = 2;
    460 
    461   // True if the network was validated at least once.
    462   optional bool ever_validated = 3;
    463 
    464   // True if a captive portal was found at least once on this network.
    465   optional bool portal_found = 4;
    466 
    467   // Total number of times no connectivity was reported for this network.
    468   optional int32 no_connectivity_reports = 5;
    469 
    470   // Total number of validation attempts.
    471   optional int32 validation_attempts = 6;
    472 
    473   // Results from all validation attempts.
    474   // The Pair key is the result:
    475   //    0 -> unvalidated
    476   //    1 -> validated
    477   //    2 -> captive portal
    478   // The Pair value is the duration of the validation attempts in milliseconds.
    479   repeated Pair validation_events = 7;
    480 
    481   // Time series of validation states in time order.
    482   // The Pair key is the state:
    483   //    0 -> unvalidated
    484   //    1 -> validated
    485   //    2 -> captive portal,
    486   // The Pair value is the duration of that state in milliseconds.
    487   repeated Pair validation_states = 8;
    488 }
    489 
    490 // Represents statistics from NFLOG wakeup events due to ingress packets.
    491 // Since oc-mr1.
    492 // Next tag: 13.
    493 message WakeupStats {
    494   // The time duration in seconds covered by these stats, for deriving
    495   // exact wakeup rates.
    496   optional int64 duration_sec = 1;
    497 
    498   // The total number of ingress packets waking up the device.
    499   optional int64 total_wakeups = 2;
    500 
    501   // The total number of wakeup packets routed to a socket belonging to
    502   // the root uid (uid 0).
    503   optional int64 root_wakeups = 3;
    504 
    505   // The total number of wakeup packets routed to a socket belonging to
    506   // the system server (uid 1000).
    507   optional int64 system_wakeups = 4;
    508 
    509   // The total number of wakeup packets routed to a socket belonging to
    510   // an application (uid > 9999).
    511   optional int64 application_wakeups = 5;
    512 
    513   // The total number of wakeup packets routed to a socket belonging to another
    514   // uid than the root uid, system uid, or an application uid (any uid in
    515   // between [1001, 9999]. See android.os.Process for possible uids.
    516   optional int64 non_application_wakeups = 6;
    517 
    518   // The total number of wakeup packets with no associated socket or uid.
    519   optional int64 no_uid_wakeups = 7;
    520 
    521   // Counts of all different ethertype values from wakeup packets received.
    522   repeated Pair ethertype_counts = 8;
    523 
    524   // Counts of all different IP next header values from wakeup packets received.
    525   repeated Pair ip_next_header_counts = 9;
    526 
    527   // The total number of wakeup packets whose destination hardware address was
    528   // a unicast address.
    529   optional int64 l2_unicast_count = 10;
    530 
    531   // The total number of wakeup packets whose destination hardware address was
    532   // a multicast address.
    533   optional int64 l2_multicast_count = 11;
    534 
    535   // The total number of wakeup packets whose destination hardware address was
    536   // a broadcast address.
    537   optional int64 l2_broadcast_count = 12;
    538 }
    539 
    540 // Represents one of the IP connectivity event defined in this file.
    541 // Next tag: 20
    542 message IpConnectivityEvent {
    543   // Time in ms when the event was recorded.
    544   optional int64 time_ms = 1;
    545 
    546   // Physical link layer of the network on which the event happened.
    547   // Acts as a dimension key.
    548   // Since version 2.
    549   optional LinkLayer link_layer = 15;
    550 
    551   // Represents the id given by the system to a physical network on the device.
    552   // Every network gets assigned a unique id on creation from a monotonic
    553   // counter. The value 0 is never assigned to a network and means no network.
    554   // It is used to correlate different types of events to each other for devices
    555   // with multiple networks (WiFi, 4G, ...).
    556   // Since version 3.
    557   optional int32 network_id = 16;
    558 
    559   // The interface name (wlan, rmnet, lo, ...) on which the event happened.
    560   // Present if the link_layer field was not inferred from the if_name on
    561   // the device, so that post-processing of the serialized proto can backfill
    562   // link_layer. Since version 3.
    563   optional string if_name = 17;
    564 
    565   // The transport types of the network on which the event happened, expressed
    566   // as a bit field of TRANSPORT_* constants as defined in NetworkCapabilities.
    567   // Present if the link_layer field was not inferred from the transport types,
    568   // so that post-processing of the serialized proto can backfill link_layer
    569   // Since version 3.
    570   optional int64 transports = 18;
    571 
    572   oneof event {
    573 
    574     // An event about the system default network.
    575     DefaultNetworkEvent default_network_event = 2;
    576 
    577     // An IP reachability probe event.
    578     IpReachabilityEvent ip_reachability_event = 3;
    579 
    580     // A network lifecycle event.
    581     NetworkEvent network_event = 4 [deprecated = true];
    582 
    583     // A batch of DNS lookups.
    584     // Deprecated in the nyc-mr2 release since version 2,and replaced by
    585     // dns_latencies.
    586     DNSLookupBatch dns_lookup_batch = 5 [deprecated = true];
    587 
    588     // DNS lookup latency statistics.
    589     DNSLatencies dns_latencies = 13;
    590 
    591     // Connect latency and errno statistics.
    592     ConnectStatistics connect_statistics = 14;
    593 
    594     // A DHCP client event or DHCP receive error.
    595     DHCPEvent dhcp_event = 6;
    596 
    597     // An IP provisioning event.
    598     IpProvisioningEvent ip_provisioning_event = 7;
    599 
    600     // A network validation probe event.
    601     ValidationProbeEvent validation_probe_event = 8;
    602 
    603     // An Android Packet Filter program event.
    604     ApfProgramEvent apf_program_event = 9;
    605 
    606     // An Android Packet Filter statistics event.
    607     ApfStatistics apf_statistics = 10;
    608 
    609     // An RA packet reception event.
    610     RaEvent ra_event = 11;
    611 
    612     // Network statistics.
    613     NetworkStats network_stats = 19;
    614 
    615     // Ingress packet wakeup statistics.
    616     WakeupStats wakeup_stats = 20;
    617   };
    618 };
    619 
    620 // The information about IP connectivity events.
    621 // Next tag: 4.
    622 message IpConnectivityLog {
    623   // An array of IP connectivity events.
    624   repeated IpConnectivityEvent events = 1;
    625 
    626   // The number of events that had to be dropped due to a full buffer.
    627   optional int32 dropped_events = 2;
    628 
    629   // The version number of the metrics events being collected.
    630   //  nyc:     not populated, implicitly 0.
    631   //  nyc-dr1: not populated, implicitly 1 (sailfish and marlin only).
    632   //  nyc-mr1: not populated, implicitly 1.
    633   //  nyc-mr2: 2.
    634   //  oc:      3.
    635   //  oc-dr1:  4. (sailfish, marlin, walleye, taimen)
    636   optional int32 version = 3;
    637 };
    638