Buttplug sex toy control library

chore: Tighten Id specifiers in json schema

Make sure we specify the correct Id ranges for messages.

+238 -107
+236 -104
buttplug/buttplug-schema/schema/buttplug-schema.json
··· 4 4 "version": 3, 5 5 "description": "The JSON Protocol format for the Buttplug Protocol.", 6 6 "components": { 7 - "Id": { 7 + "ClientId": { 8 + "description": "User-set id for the message. 0 denotes system message and is reserved.", 9 + "type": "integer", 10 + "minimum": 1, 11 + "maximum": 4294967295 12 + }, 13 + "ServerId": { 8 14 "description": "User-set id for the message. 0 denotes system message and is reserved.", 9 15 "type": "integer", 10 16 "minimum": 0, ··· 25 31 "type": "integer", 26 32 "minimum": 0 27 33 }, 28 - "IdMessage": { 34 + "ClientIdMessage": { 29 35 "description": "Message types that are expected to have an Id and nothing else.", 30 36 "properties": { 31 - "Id": { "$ref": "#/components/Id" } 37 + "Id": { "$ref": "#/components/ClientId" } 38 + }, 39 + "additionalProperties": false, 40 + "minProperties": 1, 41 + "maxProperties": 1, 42 + "required": [ 43 + "Id" 44 + ] 45 + }, 46 + "ServerIdMessage": { 47 + "description": "Message types that are expected to have an Id and nothing else, from the server side, which may be either a reply or an event (id 0).", 48 + "properties": { 49 + "Id": { "$ref": "#/components/ServerId" } 32 50 }, 33 51 "additionalProperties": false, 34 52 "minProperties": 1, ··· 47 65 "Id" 48 66 ] 49 67 }, 50 - "DeviceIndexMessage": { 68 + "SystemIdDeviceIndexMessage": { 69 + "properties": { 70 + "Id": { "$ref": "#/components/SystemId" }, 71 + "DeviceIndex": { "$ref": "#/components/DeviceIndex" } 72 + }, 73 + "additionalProperties": false, 74 + "required": [ 75 + "Id", 76 + "DeviceIndex" 77 + ] 78 + }, 79 + "ClientIdDeviceIndexMessage": { 51 80 "properties": { 52 - "Id": { "$ref": "#/components/Id" }, 81 + "Id": { "$ref": "#/components/ClientId" }, 53 82 "DeviceIndex": { "$ref": "#/components/DeviceIndex" } 54 83 }, 55 84 "additionalProperties": false, ··· 82 111 }, 83 112 "FeatureCount": { "$ref": "#/components/FeatureCount" }, 84 113 "StepCount": { "$ref": "#/components/StepCount" }, 85 - "ActuatorType": { 114 + "ActuatorType": { 86 115 "description": "Denotes type of actuator (Vibrator, Linear, Oscillator, etc...)", 87 116 "type": "string" 88 117 } ··· 134 163 "FeatureDescriptor", 135 164 "SensorRange" 136 165 ] 137 - }, 166 + }, 138 167 "DeviceMessagesEx": { 139 168 "description": "A list of the messages a device will accept on this server implementation.", 140 169 "type": "object", ··· 147 176 "minItems": 1 148 177 }, 149 178 "VibrateCmd": { "$ref": "#/components/GenericMessageAttributes" }, 150 - "LinearCmd": { 179 + "LinearCmd": { 151 180 "type": "array", 152 181 "items": { 153 182 "$ref": "#/components/GenericMessageAttributes", 154 183 "minItems": 1 155 184 } 156 185 }, 157 - "RotateCmd": { 186 + "RotateCmd": { 158 187 "type": "array", 159 188 "items": { 160 189 "$ref": "#/components/GenericMessageAttributes", ··· 168 197 "FleshlightLaunchFW12Cmd": { "$ref": "#/components/NullMessageAttributes" }, 169 198 "BatteryLevelCmd": { "$ref": "#/components/NullMessageAttributes" }, 170 199 "RSSILevelCmd": { "$ref": "#/components/NullMessageAttributes" }, 171 - "SensorReadCmd": { 200 + "SensorReadCmd": { 172 201 "type": "array", 173 202 "items": { 174 203 "$ref": "#/components/SensorMessageAttributes", 175 204 "minItems": 1 176 205 } 177 206 }, 178 - "SensorSubscribeCmd": { 207 + "SensorSubscribeCmd": { 179 208 "type": "array", 180 209 "items": { 181 210 "$ref": "#/components/SensorMessageAttributes", ··· 210 239 "Ok": { 211 240 "type": "object", 212 241 "description": "Signifies successful processing of the message indicated by the id.", 213 - "anyOf": [ { "$ref": "#/components/IdMessage" } ] 242 + "anyOf": [ { "$ref": "#/components/ClientIdMessage" } ] 214 243 }, 215 244 "Ping": { 216 245 "type": "object", 217 246 "description": "Connection keep-alive message.", 218 - "anyOf": [ { "$ref": "#/components/IdMessage" } ] 247 + "anyOf": [ { "$ref": "#/components/ClientIdMessage" } ] 219 248 }, 220 249 "Error": { 221 250 "type": "object", 222 251 "description": "Signifies the server encountered an error while processing the message indicated by the id.", 223 252 "properties": { 224 - "Id": { "$ref": "#/components/Id" }, 253 + "Id": { "$ref": "#/components/ServerId" }, 225 254 "ErrorMessage": { 226 255 "type": "string" 227 256 }, ··· 242 271 "type": "object", 243 272 "description": "Used for connection/application testing. Causes server to echo back the string sent. Sending string of 'Error' will result in a server error. ", 244 273 "properties": { 245 - "Id": { "$ref": "#/components/Id" }, 274 + "Id": { "$ref": "#/components/ClientId" }, 246 275 "TestString": { 247 276 "description": "String to be echo'd back from server. Setting this to 'Error' will cause an error to be thrown.", 248 277 "type": "string" ··· 258 287 "type": "object", 259 288 "description": "List of all available devices known to the system.", 260 289 "properties": { 261 - "Id": { "$ref": "#/components/Id" }, 290 + "Id": { "$ref": "#/components/ClientId" }, 262 291 "Devices": { 263 292 "description": "Array of device ids and names.", 264 293 "type": "array", ··· 315 344 "DeviceRemoved": { 316 345 "type": "object", 317 346 "description": "Notifies client that a device of a certain type has been removed from the server.", 318 - "anyOf": [ { "$ref": "#/components/DeviceIndexMessage" } ] 347 + "anyOf": [ { "$ref": "#/components/SystemIdDeviceIndexMessage" } ] 319 348 }, 320 349 "RequestDeviceList": { 321 350 "type": "object", 322 351 "description": "Request for the server to send a list of devices to the client.", 323 - "anyOf": [ { "$ref": "#/components/IdMessage" } ] 352 + "anyOf": [ { "$ref": "#/components/ClientIdMessage" } ] 324 353 }, 325 354 "StartScanning": { 326 355 "type": "object", 327 356 "description": "Request for the server to start scanning for new devices.", 328 - "anyOf": [ { "$ref": "#/components/IdMessage" } ] 357 + "anyOf": [ { "$ref": "#/components/ClientIdMessage" } ] 329 358 }, 330 359 "StopScanning": { 331 360 "type": "object", 332 361 "description": "Request for the server to stop scanning for new devices.", 333 - "anyOf": [ { "$ref": "#/components/IdMessage" } ] 362 + "anyOf": [ { "$ref": "#/components/ClientIdMessage" } ] 334 363 }, 335 364 "ScanningFinished": { 336 365 "type": "object", ··· 341 370 "type": "object", 342 371 "description": "Request for server to stream log messages of a certain level to client.", 343 372 "properties": { 344 - "Id": { "$ref": "#/components/Id" }, 373 + "Id": { "$ref": "#/components/ClientId" }, 345 374 "LogLevel": { 346 375 "description": "Maximum level of log message to receive.", 347 376 "enum": [ "Off", "Fatal", "Error", "Warn", "Info", "Debug", "Trace" ] ··· 378 407 "type": "object", 379 408 "description": "Request server version, and relay client name.", 380 409 "properties": { 381 - "Id": { "$ref": "#/components/Id" }, 410 + "Id": { "$ref": "#/components/ClientId" }, 382 411 "ClientName": { 383 412 "description": "Name of the client software.", 384 413 "type": "string" ··· 399 428 "type": "object", 400 429 "description": "Server version information, in Major.Minor.Build format.", 401 430 "properties": { 402 - "Id": { "$ref": "#/components/Id" }, 431 + "Id": { "$ref": "#/components/ClientId" }, 403 432 "ServerName": { 404 433 "description": "Name of the server. Can be 0-length.", 405 434 "type": "string" ··· 442 471 "type": "object", 443 472 "description": "Sends speed and position command to the Fleshlight Launch Device denoted by the device index.", 444 473 "properties": { 445 - "Id": { "$ref": "#/components/Id" }, 474 + "Id": { "$ref": "#/components/ClientId" }, 446 475 "DeviceIndex": { "$ref": "#/components/DeviceIndex" }, 447 476 "Speed": { 448 477 "description": "Speed at which to move to designated position.", ··· 469 498 "type": "object", 470 499 "description": "Sends a command string to a Lovense device. Command string will be verified by sender.", 471 500 "properties": { 472 - "Id": { "$ref": "#/components/Id" }, 501 + "Id": { "$ref": "#/components/ClientId" }, 473 502 "DeviceIndex": { "$ref": "#/components/DeviceIndex" }, 474 503 "Command": { 475 504 "description": "Command to send to Lovense device.", ··· 487 516 "type": "object", 488 517 "description": "Sends a vibrate command to a device that supports vibration.", 489 518 "properties": { 490 - "Id": { "$ref": "#/components/Id" }, 519 + "Id": { "$ref": "#/components/ClientId" }, 491 520 "DeviceIndex": { "$ref": "#/components/DeviceIndex" }, 492 521 "Speed": { 493 522 "description": "Device vibration speed (floating point, 0 < x < 1), stepping will be device specific.", ··· 507 536 "type": "object", 508 537 "description": "Sends a raw byte array to a device. Should only be used for testing/development.", 509 538 "properties": { 510 - "Id": { "$ref": "#/components/Id" }, 539 + "Id": { "$ref": "#/components/ClientId" }, 511 540 "DeviceIndex": { "$ref": "#/components/DeviceIndex" }, 512 541 "Endpoint": { 513 542 "type": "string", ··· 541 570 "type": "object", 542 571 "description": "Request a raw byte array from a device. Should only be used for testing/development.", 543 572 "properties": { 544 - "Id": { "$ref": "#/components/Id" }, 573 + "Id": { "$ref": "#/components/ClientId" }, 545 574 "DeviceIndex": { "$ref": "#/components/DeviceIndex" }, 546 575 "Endpoint": { 547 576 "type": "string", ··· 570 599 "type": "object", 571 600 "description": "Subscribe to an endpoint on a device to receive raw info back.", 572 601 "properties": { 573 - "Id": { "$ref": "#/components/Id" }, 602 + "Id": { "$ref": "#/components/ClientId" }, 574 603 "DeviceIndex": { "$ref": "#/components/DeviceIndex" }, 575 604 "Endpoint": { 576 605 "type": "string", ··· 588 617 "type": "object", 589 618 "description": "Unsubscribe to an endpoint on a device.", 590 619 "properties": { 591 - "Id": { "$ref": "#/components/Id" }, 620 + "Id": { "$ref": "#/components/ClientId" }, 592 621 "DeviceIndex": { "$ref": "#/components/DeviceIndex" }, 593 622 "Endpoint": { 594 623 "type": "string", ··· 606 635 "type": "object", 607 636 "description": "Raw byte array received from a device. Should only be used for testing/development.", 608 637 "properties": { 609 - "Id": { "$ref": "#/components/Id" }, 638 + "Id": { "$ref": "#/components/ServerId" }, 610 639 "DeviceIndex": { "$ref": "#/components/DeviceIndex" }, 611 640 "Endpoint": { 612 641 "type": "string", ··· 635 664 "type": "object", 636 665 "description": "Sends a raw byte string to a Kiiroo Onyx/Pearl device.", 637 666 "properties": { 638 - "Id": { "$ref": "#/components/Id" }, 667 + "Id": { "$ref": "#/components/ClientId" }, 639 668 "DeviceIndex": { "$ref": "#/components/DeviceIndex" }, 640 669 "Command": { 641 670 "description": "Command to send to Kiiroo device.", ··· 653 682 "type": "object", 654 683 "description": "Requests that a BatteryLevel be retreived.", 655 684 "properties": { 656 - "Id": { "$ref": "#/components/Id" }, 685 + "Id": { "$ref": "#/components/ClientId" }, 657 686 "DeviceIndex": { "$ref": "#/components/DeviceIndex" } 658 687 }, 659 688 "additionalProperties": false, ··· 666 695 "type": "object", 667 696 "description": "Returns a BatteryLevel read from a device.", 668 697 "properties": { 669 - "Id": { "$ref": "#/components/Id" }, 698 + "Id": { "$ref": "#/components/ClientId" }, 670 699 "DeviceIndex": { "$ref": "#/components/DeviceIndex" }, 671 700 "BatteryLevel": { 672 701 "description": "Battery Level", ··· 686 715 "type": "object", 687 716 "description": "Requests that a RSSI level be retreived.", 688 717 "properties": { 689 - "Id": { "$ref": "#/components/Id" }, 718 + "Id": { "$ref": "#/components/ClientId" }, 690 719 "DeviceIndex": { "$ref": "#/components/DeviceIndex" } 691 720 }, 692 721 "additionalProperties": false, ··· 699 728 "type": "object", 700 729 "description": "Returns a BatteryLevel read from a device.", 701 730 "properties": { 702 - "Id": { "$ref": "#/components/Id" }, 731 + "Id": { "$ref": "#/components/ClientId" }, 703 732 "DeviceIndex": { "$ref": "#/components/DeviceIndex" }, 704 733 "RSSILevel": { 705 734 "description": "RSSI Level", ··· 719 748 "type": "object", 720 749 "description": "Sends a raw byte string to a Kiiroo Onyx/Pearl device.", 721 750 "properties": { 722 - "Id": { "$ref": "#/components/Id" }, 751 + "Id": { "$ref": "#/components/ClientId" }, 723 752 "DeviceIndex": { "$ref": "#/components/DeviceIndex" }, 724 753 "Speed": { 725 754 "description": "Rotation speed command for the Cyclone.", ··· 744 773 "type": "object", 745 774 "description": "Stops the all actions currently being taken by a device.", 746 775 "properties": { 747 - "Id": { "$ref": "#/components/Id" }, 776 + "Id": { "$ref": "#/components/ClientId" }, 748 777 "DeviceIndex": { "$ref": "#/components/DeviceIndex" } 749 778 }, 750 779 "additionalProperties": false, ··· 756 785 "StopAllDevices": { 757 786 "type": "object", 758 787 "description": "Stops all actions currently being taken by all connected devices.", 759 - "anyOf": [ { "$ref": "#/components/IdMessage" } ] 788 + "anyOf": [ { "$ref": "#/components/ClientIdMessage" } ] 760 789 }, 761 790 "VibrateCmd": { 762 791 "type": "object", 763 792 "description": "Sends a vibrate command to a device that supports vibration.", 764 793 "properties": { 765 - "Id": { "$ref": "#/components/Id" }, 794 + "Id": { "$ref": "#/components/ClientId" }, 766 795 "DeviceIndex": { "$ref": "#/components/DeviceIndex" }, 767 796 "Speeds": { 768 797 "description": "Device vibration speeds (floating point, 0 < x < 1) keyed on vibrator number, stepping will be device specific.", ··· 802 831 "type": "object", 803 832 "description": "Sends a generic scalar command to a device.", 804 833 "properties": { 805 - "Id": { "$ref": "#/components/Id" }, 834 + "Id": { "$ref": "#/components/ClientId" }, 806 835 "DeviceIndex": { "$ref": "#/components/DeviceIndex" }, 807 836 "Scalars": { 808 837 "description": "Device actution scalar (floating point, range can vary) keyed on acutator index, stepping will be device specific.", ··· 822 851 "ActuatorType": { 823 852 "description": "Actuator type that is expected to be controlled with this subcommand.", 824 853 "type": "string" 825 - } 854 + } 826 855 }, 827 856 "additionalProperties": false, 828 857 "required": [ ··· 845 874 "type": "object", 846 875 "description": "Sends a rotate command to a device that supports rotation.", 847 876 "properties": { 848 - "Id": { "$ref": "#/components/Id" }, 877 + "Id": { "$ref": "#/components/ClientId" }, 849 878 "DeviceIndex": { "$ref": "#/components/DeviceIndex" }, 850 879 "Rotations": { 851 880 "description": "Device rotation speeds (floating point, 0 < x < 1) keyed on rotator number, stepping will be device specific.", ··· 890 919 "type": "object", 891 920 "description": "Sends a linear movement command to a device that supports linear movements.", 892 921 "properties": { 893 - "Id": { "$ref": "#/components/Id" }, 922 + "Id": { "$ref": "#/components/ClientId" }, 894 923 "DeviceIndex": { "$ref": "#/components/DeviceIndex" }, 895 924 "Vectors": { 896 925 "description": "Device linear movement times (milliseconds) and positions (floating point, 0 < x < 1) keyed on linear actuator number, stepping will be device specific.", ··· 935 964 "type": "object", 936 965 "description": "Sends a request to read a sensor value.", 937 966 "properties": { 938 - "Id": { "$ref": "#/components/Id" }, 967 + "Id": { "$ref": "#/components/ClientId" }, 939 968 "DeviceIndex": { "$ref": "#/components/DeviceIndex" }, 940 969 "SensorIndex": { "type": "integer" }, 941 970 "SensorType": { "type": "string" } ··· 946 975 "DeviceIndex", 947 976 "SensorIndex", 948 977 "SensorType" 949 - ] 978 + ] 950 979 }, 951 980 "SensorReading": { 952 981 "type": "object", 953 982 "description": "Returns from either a sensor read request or a subscribed sensor event.", 954 983 "properties": { 955 - "Id": { "$ref": "#/components/Id" }, 984 + "Id": { "$ref": "#/components/ServerId" }, 956 985 "DeviceIndex": { "$ref": "#/components/DeviceIndex" }, 957 986 "SensorIndex": { "type": "integer" }, 958 987 "SensorType": { "type": "string" }, 959 - "Data": { 988 + "Data": { 960 989 "type": "array", 961 990 "items": { 962 991 "type": "integer", ··· 972 1001 "SensorIndex", 973 1002 "SensorType", 974 1003 "Data" 975 - ] 1004 + ] 976 1005 }, 977 1006 "SensorSubscribeCmd": { 978 1007 "type": "object", 979 1008 "description": "Sends a request to subscribe for updates to a sensor value.", 980 1009 "properties": { 981 - "Id": { "$ref": "#/components/Id" }, 1010 + "Id": { "$ref": "#/components/ClientId" }, 982 1011 "DeviceIndex": { "$ref": "#/components/DeviceIndex" }, 983 1012 "SensorIndex": { "type": "integer" }, 984 1013 "SensorType": { "type": "string" } ··· 989 1018 "DeviceIndex", 990 1019 "SensorIndex", 991 1020 "SensorType" 992 - ] 1021 + ] 993 1022 }, 994 1023 "SensorUnsubscribeCmd": { 995 1024 "type": "object", 996 1025 "description": "Sends a request to subscribe for updates to a sensor value.", 997 1026 "properties": { 998 - "Id": { "$ref": "#/components/Id" }, 1027 + "Id": { "$ref": "#/components/ClientId" }, 999 1028 "DeviceIndex": { "$ref": "#/components/DeviceIndex" }, 1000 1029 "SensorIndex": { "type": "integer" }, 1001 1030 "SensorType": { "type": "string" } ··· 1006 1035 "DeviceIndex", 1007 1036 "SensorIndex", 1008 1037 "SensorType" 1009 - ] 1010 - } 1038 + ] 1039 + } 1011 1040 }, 1012 - "type": "array", 1013 - "items": { 1014 - "title": "Messages", 1015 - "type": "object", 1016 - "description": "One or more messages validated by the Buttplug Message schema list.", 1017 - "properties": { 1018 - "BatteryLevelCmd": { "$ref": "#/messages/BatteryLevelCmd" }, 1019 - "BatteryLevelReading": { "$ref": "#/messages/BatteryLevelReading" }, 1020 - "DeviceList": { "$ref": "#/messages/DeviceList" }, 1021 - "DeviceAdded": { "$ref": "#/messages/DeviceAdded" }, 1022 - "DeviceRemoved": { "$ref": "#/messages/DeviceRemoved" }, 1023 - "Error": { "$ref": "#/messages/Error" }, 1024 - "FleshlightLaunchFW12Cmd": { "$ref": "#/messages/FleshlightLaunchFW12Cmd" }, 1025 - "KiirooCmd": { "$ref": "#/messages/KiirooCmd" }, 1026 - "ScalarCmd": { "$ref": "#/messages/ScalarCmd" }, 1027 - "LinearCmd": { "$ref": "#/messages/LinearCmd" }, 1028 - "Log": { "$ref": "#/messages/Log" }, 1029 - "LovenseCmd": { "$ref": "#/messages/LovenseCmd" }, 1030 - "Ok": { "$ref": "#/messages/Ok" }, 1031 - "Ping": { "$ref": "#/messages/Ping" }, 1032 - "RawReadCmd": { "$ref": "#/messages/RawReadCmd" }, 1033 - "RawReading": { "$ref": "#/messages/RawReading" }, 1034 - "RawWriteCmd": { "$ref": "#/messages/RawWriteCmd" }, 1035 - "RawSubscribeCmd": { "$ref": "#/messages/RawSubscribeCmd" }, 1036 - "RawUnsubscribeCmd": { "$ref": "#/messages/RawUnsubscribeCmd" }, 1037 - "RequestDeviceList": { "$ref": "#/messages/RequestDeviceList" }, 1038 - "RequestLog": { "$ref": "#/messages/RequestLog" }, 1039 - "RequestServerInfo": { "$ref": "#/messages/RequestServerInfo" }, 1040 - "RotateCmd": { "$ref": "#/messages/RotateCmd" }, 1041 - "RSSILevelCmd": { "$ref": "#/messages/RSSILevelCmd" }, 1042 - "RSSILevelReading": { "$ref": "#/messages/RSSILevelReading" }, 1043 - "ScanningFinished": { "$ref": "#/messages/ScanningFinished" }, 1044 - "SensorReadCmd": { "$ref": "#/messages/SensorReadCmd" }, 1045 - "SensorReading": { "$ref": "#/messages/SensorReading" }, 1046 - "SensorSubscribeCmd": { "$ref": "#/messages/SensorSubscribeCmd" }, 1047 - "SensorUnsubscribeCmd": { "$ref": "#/messages/SensorUnsubscribeCmd" }, 1048 - "ServerInfo": { "$ref": "#/messages/ServerInfo" }, 1049 - "SingleMotorVibrateCmd": { "$ref": "#/messages/SingleMotorVibrateCmd" }, 1050 - "StartScanning": { "$ref": "#/messages/StartScanning" }, 1051 - "StopAllDevices": { "$ref": "#/messages/StopAllDevices" }, 1052 - "StopDeviceCmd": { "$ref": "#/messages/StopDeviceCmd" }, 1053 - "StopScanning": { "$ref": "#/messages/StopScanning" }, 1054 - "Test": { "$ref": "#/messages/Test" }, 1055 - "VibrateCmd": { "$ref": "#/messages/VibrateCmd" }, 1056 - "VorzeA10CycloneCmd": { "$ref": "#/messages/VorzeA10CycloneCmd" } 1041 + "specs": { 1042 + "MessageSpecV3": { 1043 + "type": "array", 1044 + "items": { 1045 + "type": "object", 1046 + "description": "All messages valid in Buttplug Spec v3", 1047 + "properties": { 1048 + "DeviceList": { "$ref": "#/messages/DeviceList" }, 1049 + "DeviceAdded": { "$ref": "#/messages/DeviceAdded" }, 1050 + "DeviceRemoved": { "$ref": "#/messages/DeviceRemoved" }, 1051 + "Error": { "$ref": "#/messages/Error" }, 1052 + "ScalarCmd": { "$ref": "#/messages/ScalarCmd" }, 1053 + "LinearCmd": { "$ref": "#/messages/LinearCmd" }, 1054 + "Ok": { "$ref": "#/messages/Ok" }, 1055 + "Ping": { "$ref": "#/messages/Ping" }, 1056 + "RawReadCmd": { "$ref": "#/messages/RawReadCmd" }, 1057 + "RawReading": { "$ref": "#/messages/RawReading" }, 1058 + "RawWriteCmd": { "$ref": "#/messages/RawWriteCmd" }, 1059 + "RawSubscribeCmd": { "$ref": "#/messages/RawSubscribeCmd" }, 1060 + "RawUnsubscribeCmd": { "$ref": "#/messages/RawUnsubscribeCmd" }, 1061 + "RequestDeviceList": { "$ref": "#/messages/RequestDeviceList" }, 1062 + "RequestServerInfo": { "$ref": "#/messages/RequestServerInfo" }, 1063 + "RotateCmd": { "$ref": "#/messages/RotateCmd" }, 1064 + "ScanningFinished": { "$ref": "#/messages/ScanningFinished" }, 1065 + "SensorReadCmd": { "$ref": "#/messages/SensorReadCmd" }, 1066 + "SensorReading": { "$ref": "#/messages/SensorReading" }, 1067 + "SensorSubscribeCmd": { "$ref": "#/messages/SensorSubscribeCmd" }, 1068 + "SensorUnsubscribeCmd": { "$ref": "#/messages/SensorUnsubscribeCmd" }, 1069 + "ServerInfo": { "$ref": "#/messages/ServerInfo" }, 1070 + "StartScanning": { "$ref": "#/messages/StartScanning" }, 1071 + "StopAllDevices": { "$ref": "#/messages/StopAllDevices" }, 1072 + "StopDeviceCmd": { "$ref": "#/messages/StopDeviceCmd" }, 1073 + "StopScanning": { "$ref": "#/messages/StopScanning" } 1074 + }, 1075 + "additionalProperties": false, 1076 + "minProperties": 1, 1077 + "maxProperties": 1 1078 + }, 1079 + "minItems": 1 1057 1080 }, 1058 - "additionalProperties": false, 1059 - "minProperties": 1, 1060 - "maxProperties": 1 1081 + "MessageSpecV2": { 1082 + "type": "array", 1083 + "items": { 1084 + "type": "object", 1085 + "description": "All messages valid in Buttplug Spec v2.", 1086 + "properties": { 1087 + "BatteryLevelCmd": { "$ref": "#/messages/BatteryLevelCmd" }, 1088 + "BatteryLevelReading": { "$ref": "#/messages/BatteryLevelReading" }, 1089 + "DeviceList": { "$ref": "#/messages/DeviceList" }, 1090 + "DeviceAdded": { "$ref": "#/messages/DeviceAdded" }, 1091 + "DeviceRemoved": { "$ref": "#/messages/DeviceRemoved" }, 1092 + "Error": { "$ref": "#/messages/Error" }, 1093 + "LinearCmd": { "$ref": "#/messages/LinearCmd" }, 1094 + "Ok": { "$ref": "#/messages/Ok" }, 1095 + "Ping": { "$ref": "#/messages/Ping" }, 1096 + "RawReadCmd": { "$ref": "#/messages/RawReadCmd" }, 1097 + "RawReading": { "$ref": "#/messages/RawReading" }, 1098 + "RawWriteCmd": { "$ref": "#/messages/RawWriteCmd" }, 1099 + "RawSubscribeCmd": { "$ref": "#/messages/RawSubscribeCmd" }, 1100 + "RawUnsubscribeCmd": { "$ref": "#/messages/RawUnsubscribeCmd" }, 1101 + "RequestDeviceList": { "$ref": "#/messages/RequestDeviceList" }, 1102 + "RequestLog": { "$ref": "#/messages/RequestLog" }, 1103 + "RequestServerInfo": { "$ref": "#/messages/RequestServerInfo" }, 1104 + "RotateCmd": { "$ref": "#/messages/RotateCmd" }, 1105 + "RSSILevelCmd": { "$ref": "#/messages/RSSILevelCmd" }, 1106 + "RSSILevelReading": { "$ref": "#/messages/RSSILevelReading" }, 1107 + "ScanningFinished": { "$ref": "#/messages/ScanningFinished" }, 1108 + "ServerInfo": { "$ref": "#/messages/ServerInfo" }, 1109 + "StartScanning": { "$ref": "#/messages/StartScanning" }, 1110 + "StopAllDevices": { "$ref": "#/messages/StopAllDevices" }, 1111 + "StopDeviceCmd": { "$ref": "#/messages/StopDeviceCmd" }, 1112 + "StopScanning": { "$ref": "#/messages/StopScanning" }, 1113 + "VibrateCmd": { "$ref": "#/messages/VibrateCmd" } 1114 + }, 1115 + "additionalProperties": false, 1116 + "minProperties": 1, 1117 + "maxProperties": 1 1118 + }, 1119 + "minItems": 1 1120 + }, 1121 + "MessageSpecV1": { 1122 + "type": "array", 1123 + "items": { 1124 + "type": "object", 1125 + "description": "One or more messages validated by the Buttplug Message schema list.", 1126 + "properties": { 1127 + "DeviceList": { "$ref": "#/messages/DeviceList" }, 1128 + "DeviceAdded": { "$ref": "#/messages/DeviceAdded" }, 1129 + "DeviceRemoved": { "$ref": "#/messages/DeviceRemoved" }, 1130 + "Error": { "$ref": "#/messages/Error" }, 1131 + "FleshlightLaunchFW12Cmd": { "$ref": "#/messages/FleshlightLaunchFW12Cmd" }, 1132 + "KiirooCmd": { "$ref": "#/messages/KiirooCmd" }, 1133 + "LinearCmd": { "$ref": "#/messages/LinearCmd" }, 1134 + "Log": { "$ref": "#/messages/Log" }, 1135 + "Ok": { "$ref": "#/messages/Ok" }, 1136 + "Ping": { "$ref": "#/messages/Ping" }, 1137 + "RequestDeviceList": { "$ref": "#/messages/RequestDeviceList" }, 1138 + "RequestLog": { "$ref": "#/messages/RequestLog" }, 1139 + "RequestServerInfo": { "$ref": "#/messages/RequestServerInfo" }, 1140 + "RotateCmd": { "$ref": "#/messages/RotateCmd" }, 1141 + "ServerInfo": { "$ref": "#/messages/ServerInfo" }, 1142 + "StartScanning": { "$ref": "#/messages/StartScanning" }, 1143 + "StopAllDevices": { "$ref": "#/messages/StopAllDevices" }, 1144 + "StopDeviceCmd": { "$ref": "#/messages/StopDeviceCmd" }, 1145 + "StopScanning": { "$ref": "#/messages/StopScanning" }, 1146 + "Test": { "$ref": "#/messages/Test" }, 1147 + "VibrateCmd": { "$ref": "#/messages/VibrateCmd" }, 1148 + "VorzeA10CycloneCmd": { "$ref": "#/messages/VorzeA10CycloneCmd" } 1149 + }, 1150 + "additionalProperties": false, 1151 + "minProperties": 1, 1152 + "maxProperties": 1 1153 + }, 1154 + "minItems": 1 1155 + }, 1156 + "MessageSpecV0": { 1157 + "type": "array", 1158 + "items": { 1159 + "type": "object", 1160 + "description": "One or more messages validated by the Buttplug Message schema list.", 1161 + "properties": { 1162 + "DeviceList": { "$ref": "#/messages/DeviceList" }, 1163 + "DeviceAdded": { "$ref": "#/messages/DeviceAdded" }, 1164 + "DeviceRemoved": { "$ref": "#/messages/DeviceRemoved" }, 1165 + "Error": { "$ref": "#/messages/Error" }, 1166 + "FleshlightLaunchFW12Cmd": { "$ref": "#/messages/FleshlightLaunchFW12Cmd" }, 1167 + "KiirooCmd": { "$ref": "#/messages/KiirooCmd" }, 1168 + "Log": { "$ref": "#/messages/Log" }, 1169 + "Ok": { "$ref": "#/messages/Ok" }, 1170 + "Ping": { "$ref": "#/messages/Ping" }, 1171 + "RequestDeviceList": { "$ref": "#/messages/RequestDeviceList" }, 1172 + "RequestLog": { "$ref": "#/messages/RequestLog" }, 1173 + "RequestServerInfo": { "$ref": "#/messages/RequestServerInfo" }, 1174 + "ServerInfo": { "$ref": "#/messages/ServerInfo" }, 1175 + "SingleMotorVibrateCmd": { "$ref": "#/messages/SingleMotorVibrateCmd" }, 1176 + "StartScanning": { "$ref": "#/messages/StartScanning" }, 1177 + "StopAllDevices": { "$ref": "#/messages/StopAllDevices" }, 1178 + "StopDeviceCmd": { "$ref": "#/messages/StopDeviceCmd" }, 1179 + "StopScanning": { "$ref": "#/messages/StopScanning" }, 1180 + "Test": { "$ref": "#/messages/Test" }, 1181 + "VorzeA10CycloneCmd": { "$ref": "#/messages/VorzeA10CycloneCmd" } 1182 + }, 1183 + "additionalProperties": false, 1184 + "minProperties": 1, 1185 + "maxProperties": 1 1186 + }, 1187 + "minItems": 1 1188 + } 1061 1189 }, 1062 - "minItems": 1, 1063 - "additionalProperties": false 1190 + "anyOf": [ 1191 + { "$ref": "#/specs/MessageSpecV3" }, 1192 + { "$ref": "#/specs/MessageSpecV2" }, 1193 + { "$ref": "#/specs/MessageSpecV1" }, 1194 + { "$ref": "#/specs/MessageSpecV0" } 1195 + ] 1064 1196 }
+2 -3
buttplug/src/core/messages/serializer/json_serializer.rs
··· 334 334 // Valid json and message type but not an array. 335 335 "{\"Ok\":{\"Id\":0}}", 336 336 // Valid json and message type but not an array. 337 - // TODO This should fail (Ok can't have an Id of 0), but currently doesn't. 338 - // "[{\"Ok\":{\"Id\":0}}]", 337 + "[{\"Ok\":{\"Id\":0}}]", 339 338 // Valid json and message type but with extra content 340 339 "[{\"Ok\":{\"NotAField\":\"NotAValue\",\"Id\":1}}]", 341 340 ]; ··· 347 346 .into()]); 348 347 for msg in incorrect_incoming_messages { 349 348 let res = serializer.deserialize(ButtplugSerializedMessage::Text(msg.to_owned())); 350 - assert!(res.is_err()); 349 + assert!(res.is_err(), "{} should be an error", msg); 351 350 if let Err(ButtplugSerializerError::MessageSpecVersionNotReceived) = res { 352 351 assert!(false, "Wrong error!"); 353 352 }