OLD | NEW |
1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
4 | 4 |
5 /// This comment describes the Fletch Agent's request and reply message format. | 5 /// This comment describes the Dartino Agent's request and reply message format. |
6 /// | 6 /// |
7 /// Message requests all start with the following header: | 7 /// Message requests all start with the following header: |
8 /// | 8 /// |
9 /// ----------------------------------------- | 9 /// ----------------------------------------- |
10 /// | Command (16 bits) | Version (16 bits) | | 10 /// | Command (16 bits) | Version (16 bits) | |
11 /// ----------------------------------------- | 11 /// ----------------------------------------- |
12 /// | Msg ID (16 bits) | Unused (16 bits) | | 12 /// | Msg ID (16 bits) | Unused (16 bits) | |
13 /// ----------------------------------------- | 13 /// ----------------------------------------- |
14 /// | Payload Length (32 bits) | | 14 /// | Payload Length (32 bits) | |
15 /// ----------------------------------------- | 15 /// ----------------------------------------- |
(...skipping 25 matching lines...) Expand all Loading... |
41 /// | 41 /// |
42 /// The reply header is immediately followed by the relevant payload data for | 42 /// The reply header is immediately followed by the relevant payload data for |
43 /// the related request's command. See details for payloads below. | 43 /// the related request's command. See details for payloads below. |
44 /// | 44 /// |
45 /// Command descriptions: | 45 /// Command descriptions: |
46 /// | 46 /// |
47 /// Below follows a description of request/reply payloads for a given command. | 47 /// Below follows a description of request/reply payloads for a given command. |
48 /// Each payload is always preceded by the corresponding header. | 48 /// Each payload is always preceded by the corresponding header. |
49 /// | 49 /// |
50 /// START_VM: | 50 /// START_VM: |
51 /// Start a new Fletch VM and return the vm's id and port on which it is | 51 /// Start a new Dartino VM and return the vm's id and port on which it is |
52 /// listening. | 52 /// listening. |
53 /// Request Payload: | 53 /// Request Payload: |
54 /// None. | 54 /// None. |
55 /// Reply Payload on success: | 55 /// Reply Payload on success: |
56 /// --------------------- | 56 /// --------------------- |
57 /// | VM ID (32 bits) | | 57 /// | VM ID (32 bits) | |
58 /// --------------------- | 58 /// --------------------- |
59 /// | VM Port (32 bits) | | 59 /// | VM Port (32 bits) | |
60 /// --------------------- | 60 /// --------------------- |
61 /// Reply Payload on failure: | 61 /// Reply Payload on failure: |
62 /// None. | 62 /// None. |
63 /// | 63 /// |
64 /// STOP_VM: | 64 /// STOP_VM: |
65 /// Stop the VM specified by the given vm id. | 65 /// Stop the VM specified by the given vm id. |
66 /// Request Payload: | 66 /// Request Payload: |
67 /// --------------------- | 67 /// --------------------- |
68 /// | VM ID (32 bits) | | 68 /// | VM ID (32 bits) | |
69 /// --------------------- | 69 /// --------------------- |
70 /// Reply Payload on success: | 70 /// Reply Payload on success: |
71 /// None. | 71 /// None. |
72 /// Reply Payload on failure: | 72 /// Reply Payload on failure: |
73 /// None. | 73 /// None. |
74 /// | 74 /// |
75 /// LIST_VMS: | 75 /// LIST_VMS: |
76 /// This command lists the currently running Fletch VMs. | 76 /// This command lists the currently running Dartino VMs. |
77 /// Request Payload: | 77 /// Request Payload: |
78 /// None. | 78 /// None. |
79 /// Reply Payload on success: | 79 /// Reply Payload on success: |
80 /// --------------------- | 80 /// --------------------- |
81 /// | VM ID (32 bits) | | 81 /// | VM ID (32 bits) | |
82 /// --------------------- | 82 /// --------------------- |
83 /// | VM ID (32 bits) | | 83 /// | VM ID (32 bits) | |
84 /// --------------------- | 84 /// --------------------- |
85 /// | VM ID (32 bits) | | 85 /// | VM ID (32 bits) | |
86 /// --------------------- | 86 /// --------------------- |
87 /// ... | 87 /// ... |
88 /// | 88 /// |
89 /// Reply Payload on failure: | 89 /// Reply Payload on failure: |
90 /// None. | 90 /// None. |
91 /// | 91 /// |
92 /// UPGRADE_VM: | 92 /// UPGRADE_VM: |
93 /// This command is used to update the Fletch VM binary on the device. | 93 /// This command is used to update the Dartino VM binary on the device. |
94 /// Request Payload: | 94 /// Request Payload: |
95 /// ... the vm binary bytes | 95 /// ... the vm binary bytes |
96 /// | 96 /// |
97 /// Reply Payload on success: | 97 /// Reply Payload on success: |
98 /// None. | 98 /// None. |
99 /// Reply Payload on failure: | 99 /// Reply Payload on failure: |
100 /// None. | 100 /// None. |
101 | 101 |
102 library fletch_agent.messages; | 102 library dartino_agent.messages; |
103 | 103 |
104 import 'dart:convert' show ASCII; | 104 import 'dart:convert' show ASCII; |
105 import 'dart:typed_data'; | 105 import 'dart:typed_data'; |
106 | 106 |
107 /// Current Fletch Agent version | 107 /// Current Dartino Agent version |
108 const int AGENT_VERSION = 1; | 108 const int AGENT_VERSION = 1; |
109 | 109 |
110 /// Default agent port | 110 /// Default agent port |
111 const int AGENT_DEFAULT_PORT = 12121; | 111 const int AGENT_DEFAULT_PORT = 12121; |
112 | 112 |
113 /// Temporary path for the agent package used during upgrade. | 113 /// Temporary path for the agent package used during upgrade. |
114 const String PACKAGE_FILE_NAME = '/tmp/fletch-agent.deb'; | 114 const String PACKAGE_FILE_NAME = '/tmp/dartino-agent.deb'; |
115 | 115 |
116 class RequestHeader { | 116 class RequestHeader { |
117 static const int START_VM = 0; | 117 static const int START_VM = 0; |
118 static const int STOP_VM = 1; | 118 static const int STOP_VM = 1; |
119 static const int LIST_VMS = 2; | 119 static const int LIST_VMS = 2; |
120 static const int UPGRADE_AGENT = 3; | 120 static const int UPGRADE_AGENT = 3; |
121 static const int FLETCH_VERSION = 4; | 121 static const int DARTINO_VERSION = 4; |
122 static const int SIGNAL_VM = 5; | 122 static const int SIGNAL_VM = 5; |
123 | 123 |
124 // Wire size (bytes) of the RequestHeader. | 124 // Wire size (bytes) of the RequestHeader. |
125 static const int HEADER_SIZE = 12; | 125 static const int HEADER_SIZE = 12; |
126 | 126 |
127 static int _nextMessageId = 1; | 127 static int _nextMessageId = 1; |
128 static int get nextMessageId { | 128 static int get nextMessageId { |
129 if ((_nextMessageId & 0xFFFF) == 0) { | 129 if ((_nextMessageId & 0xFFFF) == 0) { |
130 _nextMessageId = 1; | 130 _nextMessageId = 1; |
131 } | 131 } |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 new Uint8List(RequestHeader.HEADER_SIZE + binary.length); | 292 new Uint8List(RequestHeader.HEADER_SIZE + binary.length); |
293 _writeHeader(bytes.buffer); | 293 _writeHeader(bytes.buffer); |
294 // TODO(wibling): This does a copy of the vm binary. Try to avoid that. | 294 // TODO(wibling): This does a copy of the vm binary. Try to avoid that. |
295 for (int i = 0; i < binary.length; ++i) { | 295 for (int i = 0; i < binary.length; ++i) { |
296 bytes[RequestHeader.HEADER_SIZE + i] = binary[i]; | 296 bytes[RequestHeader.HEADER_SIZE + i] = binary[i]; |
297 } | 297 } |
298 return bytes.buffer; | 298 return bytes.buffer; |
299 } | 299 } |
300 } | 300 } |
301 | 301 |
302 class FletchVersionRequest extends RequestHeader { | 302 class DartinoVersionRequest extends RequestHeader { |
303 FletchVersionRequest() | 303 DartinoVersionRequest() |
304 : super(RequestHeader.FLETCH_VERSION); | 304 : super(RequestHeader.DARTINO_VERSION); |
305 | 305 |
306 FletchVersionRequest.withHeader(RequestHeader header) | 306 DartinoVersionRequest.withHeader(RequestHeader header) |
307 : super( | 307 : super( |
308 RequestHeader.FLETCH_VERSION, | 308 RequestHeader.DARTINO_VERSION, |
309 version: header.version, | 309 version: header.version, |
310 id: header.id, | 310 id: header.id, |
311 reserved: header.reserved); | 311 reserved: header.reserved); |
312 | 312 |
313 factory FletchVersionRequest.fromBuffer(ByteBuffer buffer) { | 313 factory DartinoVersionRequest.fromBuffer(ByteBuffer buffer) { |
314 var header = new RequestHeader.fromBuffer(buffer); | 314 var header = new RequestHeader.fromBuffer(buffer); |
315 if (header.command != RequestHeader.FLETCH_VERSION || | 315 if (header.command != RequestHeader.DARTINO_VERSION || |
316 header.payloadLength != 0) { | 316 header.payloadLength != 0) { |
317 throw new MessageDecodeException( | 317 throw new MessageDecodeException( |
318 'Invalid FletchVersionRequest: ${buffer.asUint8List()}'); | 318 'Invalid DartinoVersionRequest: ${buffer.asUint8List()}'); |
319 } | 319 } |
320 return new FletchVersionRequest.withHeader(header); | 320 return new DartinoVersionRequest.withHeader(header); |
321 } | 321 } |
322 | 322 |
323 // A FletchVersionRequest has no payload so just use parent's toBuffer method. | 323 // A DartinoVersionRequest has no payload so just use parent's toBuffer method
. |
324 } | 324 } |
325 | 325 |
326 class SignalVmRequest extends RequestHeader { | 326 class SignalVmRequest extends RequestHeader { |
327 final int vmPid; | 327 final int vmPid; |
328 final int signal; | 328 final int signal; |
329 | 329 |
330 SignalVmRequest(this.vmPid, this.signal) | 330 SignalVmRequest(this.vmPid, this.signal) |
331 : super(RequestHeader.SIGNAL_VM, payloadLength: 8); | 331 : super(RequestHeader.SIGNAL_VM, payloadLength: 8); |
332 | 332 |
333 SignalVmRequest.withHeader(RequestHeader header, this.vmPid, this.signal) | 333 SignalVmRequest.withHeader(RequestHeader header, this.vmPid, this.signal) |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 if (header.payloadLength != 0) { | 507 if (header.payloadLength != 0) { |
508 throw new MessageDecodeException( | 508 throw new MessageDecodeException( |
509 "Invalid payload length in UpgradeAgentReply: ${buffer.asUint8List()}"
); | 509 "Invalid payload length in UpgradeAgentReply: ${buffer.asUint8List()}"
); |
510 } | 510 } |
511 return new UpgradeAgentReply(header.id, header.result); | 511 return new UpgradeAgentReply(header.id, header.result); |
512 } | 512 } |
513 | 513 |
514 // The UPGRADE_AGENT reply has no payload, so leverage parent's toBuffer metho
d. | 514 // The UPGRADE_AGENT reply has no payload, so leverage parent's toBuffer metho
d. |
515 } | 515 } |
516 | 516 |
517 class FletchVersionReply extends ReplyHeader { | 517 class DartinoVersionReply extends ReplyHeader { |
518 final String fletchVersion; | 518 final String dartinoVersion; |
519 | 519 |
520 FletchVersionReply(int id, int result, {String version}) | 520 DartinoVersionReply(int id, int result, {String version}) |
521 : super(id, result, payloadLength: version != null ? version.length : 0), | 521 : super(id, result, payloadLength: version != null ? version.length : 0), |
522 fletchVersion = version { | 522 dartinoVersion = version { |
523 if (result == ReplyHeader.SUCCESS && version == null) { | 523 if (result == ReplyHeader.SUCCESS && version == null) { |
524 throw new MessageEncodeException( | 524 throw new MessageEncodeException( |
525 "Missing version for FletchVersionReply."); | 525 "Missing version for DartinoVersionReply."); |
526 } | 526 } |
527 } | 527 } |
528 | 528 |
529 factory FletchVersionReply.fromBuffer(ByteBuffer buffer) { | 529 factory DartinoVersionReply.fromBuffer(ByteBuffer buffer) { |
530 var header = new ReplyHeader.fromBuffer(buffer); | 530 var header = new ReplyHeader.fromBuffer(buffer); |
531 String version; | 531 String version; |
532 if (header.result == ReplyHeader.SUCCESS) { | 532 if (header.result == ReplyHeader.SUCCESS) { |
533 int payloadLength = header.payloadLength; | 533 int payloadLength = header.payloadLength; |
534 if (payloadLength == 0 || | 534 if (payloadLength == 0 || |
535 buffer.lengthInBytes < ReplyHeader.HEADER_SIZE + payloadLength) { | 535 buffer.lengthInBytes < ReplyHeader.HEADER_SIZE + payloadLength) { |
536 throw new MessageDecodeException( | 536 throw new MessageDecodeException( |
537 "Invalid FletchVersionReply: ${buffer.asUint8List()}"); | 537 "Invalid DartinoVersionReply: ${buffer.asUint8List()}"); |
538 } | 538 } |
539 version = ASCII.decode(buffer.asUint8List(ReplyHeader.HEADER_SIZE)); | 539 version = ASCII.decode(buffer.asUint8List(ReplyHeader.HEADER_SIZE)); |
540 } | 540 } |
541 return new FletchVersionReply(header.id, header.result, version: version); | 541 return new DartinoVersionReply(header.id, header.result, version: version); |
542 } | 542 } |
543 | 543 |
544 ByteBuffer toBuffer() { | 544 ByteBuffer toBuffer() { |
545 ByteBuffer buffer; | 545 ByteBuffer buffer; |
546 if (result == ReplyHeader.SUCCESS) { | 546 if (result == ReplyHeader.SUCCESS) { |
547 Uint8List message = new Uint8List( | 547 Uint8List message = new Uint8List( |
548 ReplyHeader.HEADER_SIZE + fletchVersion.length); | 548 ReplyHeader.HEADER_SIZE + dartinoVersion.length); |
549 _writeHeader(message.buffer); | 549 _writeHeader(message.buffer); |
550 List<int> encodedVersion = ASCII.encode(fletchVersion); | 550 List<int> encodedVersion = ASCII.encode(dartinoVersion); |
551 assert(encodedVersion != null); | 551 assert(encodedVersion != null); |
552 assert(fletchVersion.length == encodedVersion.length); | 552 assert(dartinoVersion.length == encodedVersion.length); |
553 message.setRange( | 553 message.setRange( |
554 ReplyHeader.HEADER_SIZE, | 554 ReplyHeader.HEADER_SIZE, |
555 ReplyHeader.HEADER_SIZE + encodedVersion.length, | 555 ReplyHeader.HEADER_SIZE + encodedVersion.length, |
556 encodedVersion); | 556 encodedVersion); |
557 buffer = message.buffer; | 557 buffer = message.buffer; |
558 } else { | 558 } else { |
559 buffer = new Uint8List(ReplyHeader.HEADER_SIZE).buffer; | 559 buffer = new Uint8List(ReplyHeader.HEADER_SIZE).buffer; |
560 _writeHeader(buffer); | 560 _writeHeader(buffer); |
561 } | 561 } |
562 return buffer; | 562 return buffer; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 final String message; | 613 final String message; |
614 MessageDecodeException(this.message); | 614 MessageDecodeException(this.message); |
615 String toString() => 'MessageDecodeException($message)'; | 615 String toString() => 'MessageDecodeException($message)'; |
616 } | 616 } |
617 | 617 |
618 class MessageEncodeException implements Exception { | 618 class MessageEncodeException implements Exception { |
619 final String message; | 619 final String message; |
620 MessageEncodeException(this.message); | 620 MessageEncodeException(this.message); |
621 String toString() => 'MessageEncodeException($message)'; | 621 String toString() => 'MessageEncodeException($message)'; |
622 } | 622 } |
OLD | NEW |