001package Torello.Browser.BrowserAPI;
002
003import java.util.*;
004import javax.json.*;
005import javax.json.stream.*;
006import java.io.*;
007
008import java.lang.reflect.Method;
009import java.lang.reflect.Parameter;
010import java.util.function.Function;
011
012import Torello.Browser.BrowserEvent;
013import Torello.Browser.JavaScriptAPI.*;
014import Torello.Browser.helper.*;
015
016import Torello.Java.Additional.*;
017import Torello.Java.JSON.*;
018
019import static Torello.Java.JSON.JFlag.*;
020
021import Torello.Java.StrCmpr;
022import Torello.JavaDoc.StaticFunctional;
023import Torello.JavaDoc.JDHeaderBackgroundImg;
024import Torello.JavaDoc.Excuse;
025
026/**
027 * <SPAN CLASS=COPIEDJDK><B>This domain allows configuring virtual Bluetooth devices to test
028 * the web-bluetooth API.</B></SPAN>
029 * 
030 * <EMBED CLASS='external-html' DATA-FILE-ID=CODE_GEN_NOTE>
031 */
032@StaticFunctional(Excused={"counter"}, Excuses={Excuse.CONFIGURATION})
033@JDHeaderBackgroundImg(EmbedTagFileID="WOOD_PLANK_NOTE")
034public class BluetoothEmulation
035{
036    // ********************************************************************************************
037    // ********************************************************************************************
038    // Class Header Stuff
039    // ********************************************************************************************
040    // ********************************************************************************************
041
042
043    // No Pubic Constructors
044    private BluetoothEmulation () { }
045
046    // These two Vector's are used by all the "Methods" exported by this class.  java.lang.reflect
047    // is used to generate the JSON String's.  It saves thousands of lines of Auto-Generated Code.
048    private static final Map<String, Vector<String>>    parameterNames = new HashMap<>();
049    private static final Map<String, Vector<Class<?>>>  parameterTypes = new HashMap<>();
050
051    // Some Methods do not take any parameters - for instance all the "enable()" and "disable()"
052    // I simply could not get ride of RAW-TYPES and UNCHECKED warnings... so there are now,
053    // offically, two empty-vectors.  One for String's, and the other for Classes.
054
055    private static final Vector<String>     EMPTY_VEC_STR = new Vector<>();
056    private static final Vector<Class<?>>   EMPTY_VEC_CLASS = new Vector<>();
057
058    static
059    {
060        for (Method m : BluetoothEmulation.class.getMethods())
061        {
062            // This doesn't work!  The parameter names are all "arg0" ... "argN"
063            // It works for java.lang.reflect.Field, BUT NOT java.lang.reflect.Parameter!
064            //
065            // Vector<String> parameterNamesList = new Vector<>(); -- NOPE!
066
067            Vector<Class<?>> parameterTypesList = new Vector<>();
068        
069            for (Parameter p : m.getParameters()) parameterTypesList.add(p.getType());
070
071            parameterTypes.put(
072                m.getName(),
073                (parameterTypesList.size() > 0) ? parameterTypesList : EMPTY_VEC_CLASS
074            );
075        }
076    }
077
078    static
079    {
080        Vector<String> v = null;
081
082        v = new Vector<String>(2);
083        parameterNames.put("enable", v);
084        Collections.addAll(v, new String[]
085        { "state", "leSupported", });
086
087        v = new Vector<String>(1);
088        parameterNames.put("setSimulatedCentralState", v);
089        Collections.addAll(v, new String[]
090        { "state", });
091
092        parameterNames.put("disable", EMPTY_VEC_STR);
093
094        v = new Vector<String>(4);
095        parameterNames.put("simulatePreconnectedPeripheral", v);
096        Collections.addAll(v, new String[]
097        { "address", "name", "manufacturerData", "knownServiceUuids", });
098
099        v = new Vector<String>(1);
100        parameterNames.put("simulateAdvertisement", v);
101        Collections.addAll(v, new String[]
102        { "entry", });
103
104        v = new Vector<String>(3);
105        parameterNames.put("simulateGATTOperationResponse", v);
106        Collections.addAll(v, new String[]
107        { "address", "type", "code", });
108
109        v = new Vector<String>(4);
110        parameterNames.put("simulateCharacteristicOperationResponse", v);
111        Collections.addAll(v, new String[]
112        { "characteristicId", "type", "code", "data", });
113
114        v = new Vector<String>(4);
115        parameterNames.put("simulateDescriptorOperationResponse", v);
116        Collections.addAll(v, new String[]
117        { "descriptorId", "type", "code", "data", });
118
119        v = new Vector<String>(2);
120        parameterNames.put("addService", v);
121        Collections.addAll(v, new String[]
122        { "address", "serviceUuid", });
123
124        v = new Vector<String>(1);
125        parameterNames.put("removeService", v);
126        Collections.addAll(v, new String[]
127        { "serviceId", });
128
129        v = new Vector<String>(3);
130        parameterNames.put("addCharacteristic", v);
131        Collections.addAll(v, new String[]
132        { "serviceId", "characteristicUuid", "properties", });
133
134        v = new Vector<String>(1);
135        parameterNames.put("removeCharacteristic", v);
136        Collections.addAll(v, new String[]
137        { "characteristicId", });
138
139        v = new Vector<String>(2);
140        parameterNames.put("addDescriptor", v);
141        Collections.addAll(v, new String[]
142        { "characteristicId", "descriptorUuid", });
143
144        v = new Vector<String>(1);
145        parameterNames.put("removeDescriptor", v);
146        Collections.addAll(v, new String[]
147        { "descriptorId", });
148
149        v = new Vector<String>(1);
150        parameterNames.put("simulateGATTDisconnection", v);
151        Collections.addAll(v, new String[]
152        { "address", });
153    }
154
155
156    // ********************************************************************************************
157    // ********************************************************************************************
158    // Types - Static Inner Classes
159    // ********************************************************************************************
160    // ********************************************************************************************
161
162    /** Indicates the various states of Central. */
163    public static final String[] CentralState =
164    { "absent", "powered-off", "powered-on", };
165    
166    /** Indicates the various types of GATT event. */
167    public static final String[] GATTOperationType =
168    { "connection", "discovery", };
169    
170    /** Indicates the various types of characteristic write. */
171    public static final String[] CharacteristicWriteType =
172    { "write-default-deprecated", "write-with-response", "write-without-response", };
173    
174    /** Indicates the various types of characteristic operation. */
175    public static final String[] CharacteristicOperationType =
176    { "read", "write", "subscribe-to-notifications", "unsubscribe-from-notifications", };
177    
178    /** Indicates the various types of descriptor operation. */
179    public static final String[] DescriptorOperationType =
180    { "read", "write", };
181    
182    /** Stores the manufacturer data */
183    public static class ManufacturerData
184        extends BaseType
185        implements java.io.Serializable
186    {
187        /** For Object Serialization.  java.io.Serializable */
188        protected static final long serialVersionUID = 1;
189        
190        public boolean[] optionals()
191        { return new boolean[] { false, false, }; }
192        
193        /**
194         * Company identifier
195         * https://bitbucket.org/bluetooth-SIG/public/src/main/assigned_numbers/company_identifiers/company_identifiers.yaml
196         * https://usb.org/developers
197         */
198        public final int key;
199        
200        /** Manufacturer-specific data (Encoded as a base64 string when passed over JSON) */
201        public final String data;
202        
203        /**
204         * Constructor
205         *
206         * @param key 
207         * Company identifier
208         * https://bitbucket.org/bluetooth-SIG/public/src/main/assigned_numbers/company_identifiers/company_identifiers.yaml
209         * https://usb.org/developers
210         * 
211         * @param data Manufacturer-specific data (Encoded as a base64 string when passed over JSON)
212         */
213        public ManufacturerData(int key, String data)
214        {
215            // Exception-Check(s) to ensure that if any parameters which are not declared as
216            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
217            
218            if (data == null) THROWS.throwNPE("data");
219            
220            this.key   = key;
221            this.data  = data;
222        }
223        
224        /**
225         * JSON Object Constructor
226         * @param jo A Json-Object having data about an instance of {@code 'ManufacturerData'}.
227         */
228        public ManufacturerData (JsonObject jo)
229        {
230            this.key   = ReadPrimJSON.getInt(jo, "key");
231            this.data  = ReadJSON.getString(jo, "data", false, true);
232        }
233        
234        
235        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
236        public boolean equals(Object other)
237        {
238            if (this == other)                       return true;
239            if (other == null)                       return false;
240            if (other.getClass() != this.getClass()) return false;
241        
242            ManufacturerData o = (ManufacturerData) other;
243        
244            return
245                    (this.key == o.key)
246                &&  Objects.equals(this.data, o.data);
247        }
248        
249        /** Generates a Hash-Code for {@code 'this'} instance */
250        public int hashCode()
251        {
252            return
253                    this.key
254                +   Objects.hashCode(this.data);
255        }
256    }
257    
258    /** Stores the byte data of the advertisement packet sent by a Bluetooth device. */
259    public static class ScanRecord
260        extends BaseType
261        implements java.io.Serializable
262    {
263        /** For Object Serialization.  java.io.Serializable */
264        protected static final long serialVersionUID = 1;
265        
266        public boolean[] optionals()
267        { return new boolean[] { true, true, true, true, true, }; }
268        
269        /**
270         * <CODE>[No Description Provided by Google]</CODE>
271         * <BR /><B CLASS=Opt>OPTIONAL</B>
272         */
273        public final String name;
274        
275        /**
276         * <CODE>[No Description Provided by Google]</CODE>
277         * <BR /><B CLASS=Opt>OPTIONAL</B>
278         */
279        public final String[] uuids;
280        
281        /**
282         * Stores the external appearance description of the device.
283         * <BR /><B CLASS=Opt>OPTIONAL</B>
284         */
285        public final Integer appearance;
286        
287        /**
288         * Stores the transmission power of a broadcasting device.
289         * <BR /><B CLASS=Opt>OPTIONAL</B>
290         */
291        public final Integer txPower;
292        
293        /**
294         * Key is the company identifier and the value is an array of bytes of
295         * manufacturer specific data.
296         * <BR /><B CLASS=Opt>OPTIONAL</B>
297         */
298        public final BluetoothEmulation.ManufacturerData[] manufacturerData;
299        
300        /**
301         * Constructor
302         *
303         * @param name -
304         * <BR /><B CLASS=Opt>OPTIONAL</B>
305         * 
306         * @param uuids -
307         * <BR /><B CLASS=Opt>OPTIONAL</B>
308         * 
309         * @param appearance Stores the external appearance description of the device.
310         * <BR /><B CLASS=Opt>OPTIONAL</B>
311         * 
312         * @param txPower Stores the transmission power of a broadcasting device.
313         * <BR /><B CLASS=Opt>OPTIONAL</B>
314         * 
315         * @param manufacturerData 
316         * Key is the company identifier and the value is an array of bytes of
317         * manufacturer specific data.
318         * <BR /><B CLASS=Opt>OPTIONAL</B>
319         */
320        public ScanRecord(
321                String name, String[] uuids, Integer appearance, Integer txPower, 
322                BluetoothEmulation.ManufacturerData[] manufacturerData
323            )
324        {
325            this.name              = name;
326            this.uuids             = uuids;
327            this.appearance        = appearance;
328            this.txPower           = txPower;
329            this.manufacturerData  = manufacturerData;
330        }
331        
332        /**
333         * JSON Object Constructor
334         * @param jo A Json-Object having data about an instance of {@code 'ScanRecord'}.
335         */
336        public ScanRecord (JsonObject jo)
337        {
338            this.name              = ReadJSON.getString(jo, "name", true, false);
339            this.uuids = (jo.getJsonArray("uuids") == null)
340                ? null
341                : RJArrIntoStream.strArr(jo.getJsonArray("uuids"), null, 0).toArray(String[]::new);
342        
343            this.appearance        = ReadBoxedJSON.getInteger(jo, "appearance", true);
344            this.txPower           = ReadBoxedJSON.getInteger(jo, "txPower", true);
345            this.manufacturerData = (jo.getJsonArray("manufacturerData") == null)
346                ? null
347                : RJArrIntoStream.objArr(jo.getJsonArray("manufacturerData"), null, 0, BluetoothEmulation.ManufacturerData.class).toArray(BluetoothEmulation.ManufacturerData[]::new);
348        
349        }
350        
351        
352        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
353        public boolean equals(Object other)
354        {
355            if (this == other)                       return true;
356            if (other == null)                       return false;
357            if (other.getClass() != this.getClass()) return false;
358        
359            ScanRecord o = (ScanRecord) other;
360        
361            return
362                    Objects.equals(this.name, o.name)
363                &&  Arrays.deepEquals(this.uuids, o.uuids)
364                &&  Objects.equals(this.appearance, o.appearance)
365                &&  Objects.equals(this.txPower, o.txPower)
366                &&  Arrays.deepEquals(this.manufacturerData, o.manufacturerData);
367        }
368        
369        /** Generates a Hash-Code for {@code 'this'} instance */
370        public int hashCode()
371        {
372            return
373                    Objects.hashCode(this.name)
374                +   Arrays.deepHashCode(this.uuids)
375                +   Objects.hashCode(this.appearance)
376                +   Objects.hashCode(this.txPower)
377                +   Arrays.deepHashCode(this.manufacturerData);
378        }
379    }
380    
381    /** Stores the advertisement packet information that is sent by a Bluetooth device. */
382    public static class ScanEntry
383        extends BaseType
384        implements java.io.Serializable
385    {
386        /** For Object Serialization.  java.io.Serializable */
387        protected static final long serialVersionUID = 1;
388        
389        public boolean[] optionals()
390        { return new boolean[] { false, false, false, }; }
391        
392        /** <CODE>[No Description Provided by Google]</CODE> */
393        public final String deviceAddress;
394        
395        /** <CODE>[No Description Provided by Google]</CODE> */
396        public final int rssi;
397        
398        /** <CODE>[No Description Provided by Google]</CODE> */
399        public final BluetoothEmulation.ScanRecord scanRecord;
400        
401        /**
402         * Constructor
403         *
404         * @param deviceAddress -
405         * 
406         * @param rssi -
407         * 
408         * @param scanRecord -
409         */
410        public ScanEntry
411            (String deviceAddress, int rssi, BluetoothEmulation.ScanRecord scanRecord)
412        {
413            // Exception-Check(s) to ensure that if any parameters which are not declared as
414            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
415            
416            if (deviceAddress == null) THROWS.throwNPE("deviceAddress");
417            if (scanRecord == null)    THROWS.throwNPE("scanRecord");
418            
419            this.deviceAddress  = deviceAddress;
420            this.rssi           = rssi;
421            this.scanRecord     = scanRecord;
422        }
423        
424        /**
425         * JSON Object Constructor
426         * @param jo A Json-Object having data about an instance of {@code 'ScanEntry'}.
427         */
428        public ScanEntry (JsonObject jo)
429        {
430            this.deviceAddress  = ReadJSON.getString(jo, "deviceAddress", false, true);
431            this.rssi           = ReadPrimJSON.getInt(jo, "rssi");
432            this.scanRecord     = ReadJSON.getObject(jo, "scanRecord", BluetoothEmulation.ScanRecord.class, false, true);
433        }
434        
435        
436        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
437        public boolean equals(Object other)
438        {
439            if (this == other)                       return true;
440            if (other == null)                       return false;
441            if (other.getClass() != this.getClass()) return false;
442        
443            ScanEntry o = (ScanEntry) other;
444        
445            return
446                    Objects.equals(this.deviceAddress, o.deviceAddress)
447                &&  (this.rssi == o.rssi)
448                &&  Objects.equals(this.scanRecord, o.scanRecord);
449        }
450        
451        /** Generates a Hash-Code for {@code 'this'} instance */
452        public int hashCode()
453        {
454            return
455                    Objects.hashCode(this.deviceAddress)
456                +   this.rssi
457                +   this.scanRecord.hashCode();
458        }
459    }
460    
461    /**
462     * Describes the properties of a characteristic. This follows Bluetooth Core
463     * Specification BT 4.2 Vol 3 Part G 3.3.1. Characteristic Properties.
464     */
465    public static class CharacteristicProperties
466        extends BaseType
467        implements java.io.Serializable
468    {
469        /** For Object Serialization.  java.io.Serializable */
470        protected static final long serialVersionUID = 1;
471        
472        public boolean[] optionals()
473        { return new boolean[] { true, true, true, true, true, true, true, true, }; }
474        
475        /**
476         * <CODE>[No Description Provided by Google]</CODE>
477         * <BR /><B CLASS=Opt>OPTIONAL</B>
478         */
479        public final Boolean broadcast;
480        
481        /**
482         * <CODE>[No Description Provided by Google]</CODE>
483         * <BR /><B CLASS=Opt>OPTIONAL</B>
484         */
485        public final Boolean read;
486        
487        /**
488         * <CODE>[No Description Provided by Google]</CODE>
489         * <BR /><B CLASS=Opt>OPTIONAL</B>
490         */
491        public final Boolean writeWithoutResponse;
492        
493        /**
494         * <CODE>[No Description Provided by Google]</CODE>
495         * <BR /><B CLASS=Opt>OPTIONAL</B>
496         */
497        public final Boolean write;
498        
499        /**
500         * <CODE>[No Description Provided by Google]</CODE>
501         * <BR /><B CLASS=Opt>OPTIONAL</B>
502         */
503        public final Boolean notify;
504        
505        /**
506         * <CODE>[No Description Provided by Google]</CODE>
507         * <BR /><B CLASS=Opt>OPTIONAL</B>
508         */
509        public final Boolean indicate;
510        
511        /**
512         * <CODE>[No Description Provided by Google]</CODE>
513         * <BR /><B CLASS=Opt>OPTIONAL</B>
514         */
515        public final Boolean authenticatedSignedWrites;
516        
517        /**
518         * <CODE>[No Description Provided by Google]</CODE>
519         * <BR /><B CLASS=Opt>OPTIONAL</B>
520         */
521        public final Boolean extendedProperties;
522        
523        /**
524         * Constructor
525         *
526         * @param broadcast -
527         * <BR /><B CLASS=Opt>OPTIONAL</B>
528         * 
529         * @param read -
530         * <BR /><B CLASS=Opt>OPTIONAL</B>
531         * 
532         * @param writeWithoutResponse -
533         * <BR /><B CLASS=Opt>OPTIONAL</B>
534         * 
535         * @param write -
536         * <BR /><B CLASS=Opt>OPTIONAL</B>
537         * 
538         * @param notify -
539         * <BR /><B CLASS=Opt>OPTIONAL</B>
540         * 
541         * @param indicate -
542         * <BR /><B CLASS=Opt>OPTIONAL</B>
543         * 
544         * @param authenticatedSignedWrites -
545         * <BR /><B CLASS=Opt>OPTIONAL</B>
546         * 
547         * @param extendedProperties -
548         * <BR /><B CLASS=Opt>OPTIONAL</B>
549         */
550        public CharacteristicProperties(
551                Boolean broadcast, Boolean read, Boolean writeWithoutResponse, Boolean write, 
552                Boolean notify, Boolean indicate, Boolean authenticatedSignedWrites, 
553                Boolean extendedProperties
554            )
555        {
556            this.broadcast                  = broadcast;
557            this.read                       = read;
558            this.writeWithoutResponse       = writeWithoutResponse;
559            this.write                      = write;
560            this.notify                     = notify;
561            this.indicate                   = indicate;
562            this.authenticatedSignedWrites  = authenticatedSignedWrites;
563            this.extendedProperties         = extendedProperties;
564        }
565        
566        /**
567         * JSON Object Constructor
568         * @param jo A Json-Object having data about an instance of {@code 'CharacteristicProperties'}.
569         */
570        public CharacteristicProperties (JsonObject jo)
571        {
572            this.broadcast                  = ReadBoxedJSON.getBoolean(jo, "broadcast", true);
573            this.read                       = ReadBoxedJSON.getBoolean(jo, "read", true);
574            this.writeWithoutResponse       = ReadBoxedJSON.getBoolean(jo, "writeWithoutResponse", true);
575            this.write                      = ReadBoxedJSON.getBoolean(jo, "write", true);
576            this.notify                     = ReadBoxedJSON.getBoolean(jo, "notify", true);
577            this.indicate                   = ReadBoxedJSON.getBoolean(jo, "indicate", true);
578            this.authenticatedSignedWrites  = ReadBoxedJSON.getBoolean(jo, "authenticatedSignedWrites", true);
579            this.extendedProperties         = ReadBoxedJSON.getBoolean(jo, "extendedProperties", true);
580        }
581        
582        
583        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
584        public boolean equals(Object other)
585        {
586            if (this == other)                       return true;
587            if (other == null)                       return false;
588            if (other.getClass() != this.getClass()) return false;
589        
590            CharacteristicProperties o = (CharacteristicProperties) other;
591        
592            return
593                    Objects.equals(this.broadcast, o.broadcast)
594                &&  Objects.equals(this.read, o.read)
595                &&  Objects.equals(this.writeWithoutResponse, o.writeWithoutResponse)
596                &&  Objects.equals(this.write, o.write)
597                &&  Objects.equals(this.notify, o.notify)
598                &&  Objects.equals(this.indicate, o.indicate)
599                &&  Objects.equals(this.authenticatedSignedWrites, o.authenticatedSignedWrites)
600                &&  Objects.equals(this.extendedProperties, o.extendedProperties);
601        }
602        
603        /** Generates a Hash-Code for {@code 'this'} instance */
604        public int hashCode()
605        {
606            return
607                    Objects.hashCode(this.broadcast)
608                +   Objects.hashCode(this.read)
609                +   Objects.hashCode(this.writeWithoutResponse)
610                +   Objects.hashCode(this.write)
611                +   Objects.hashCode(this.notify)
612                +   Objects.hashCode(this.indicate)
613                +   Objects.hashCode(this.authenticatedSignedWrites)
614                +   Objects.hashCode(this.extendedProperties);
615        }
616    }
617    
618    /**
619     * Event for when a GATT operation of |type| to the peripheral with |address|
620     * happened.
621     */
622    public static class gattOperationReceived
623        extends BrowserEvent
624        implements java.io.Serializable
625    {
626        /** For Object Serialization.  java.io.Serializable */
627        protected static final long serialVersionUID = 1;
628        
629        public boolean[] optionals()
630        { return new boolean[] { false, false, }; }
631        
632        /** <CODE>[No Description Provided by Google]</CODE> */
633        public final String address;
634        
635        /** <CODE>[No Description Provided by Google]</CODE> */
636        public final String type;
637        
638        /**
639         * Constructor
640         *
641         * @param address -
642         * 
643         * @param type -
644         */
645        public gattOperationReceived(String address, String type)
646        {
647            super("BluetoothEmulation", "gattOperationReceived", 2);
648            
649            // Exception-Check(s) to ensure that if any parameters which are not declared as
650            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
651            
652            if (address == null) THROWS.throwNPE("address");
653            if (type == null)    THROWS.throwNPE("type");
654            
655            // Exception-Check(s) to ensure that if any parameters which must adhere to a
656            // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
657            
658            THROWS.checkIAE("type", type, "BluetoothEmulation.GATTOperationType", BluetoothEmulation.GATTOperationType);
659            
660            this.address  = address;
661            this.type     = type;
662        }
663        
664        /**
665         * JSON Object Constructor
666         * @param jo A Json-Object having data about an instance of {@code 'gattOperationReceived'}.
667         */
668        public gattOperationReceived (JsonObject jo)
669        {
670            super("BluetoothEmulation", "gattOperationReceived", 2);
671        
672            this.address  = ReadJSON.getString(jo, "address", false, true);
673            this.type     = ReadJSON.getString(jo, "type", false, true);
674        }
675        
676        
677        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
678        public boolean equals(Object other)
679        {
680            if (this == other)                       return true;
681            if (other == null)                       return false;
682            if (other.getClass() != this.getClass()) return false;
683        
684            gattOperationReceived o = (gattOperationReceived) other;
685        
686            return
687                    Objects.equals(this.address, o.address)
688                &&  Objects.equals(this.type, o.type);
689        }
690        
691        /** Generates a Hash-Code for {@code 'this'} instance */
692        public int hashCode()
693        {
694            return
695                    Objects.hashCode(this.address)
696                +   Objects.hashCode(this.type);
697        }
698    }
699    
700    /**
701     * Event for when a characteristic operation of |type| to the characteristic
702     * respresented by |characteristicId| happened. |data| and |writeType| is
703     * expected to exist when |type| is write.
704     */
705    public static class characteristicOperationReceived
706        extends BrowserEvent
707        implements java.io.Serializable
708    {
709        /** For Object Serialization.  java.io.Serializable */
710        protected static final long serialVersionUID = 1;
711        
712        public boolean[] optionals()
713        { return new boolean[] { false, false, true, true, }; }
714        
715        /** <CODE>[No Description Provided by Google]</CODE> */
716        public final String characteristicId;
717        
718        /** <CODE>[No Description Provided by Google]</CODE> */
719        public final String type;
720        
721        /**
722         * <CODE>[No Description Provided by Google]</CODE>
723         * <BR /><B CLASS=Opt>OPTIONAL</B>
724         */
725        public final String data;
726        
727        /**
728         * <CODE>[No Description Provided by Google]</CODE>
729         * <BR /><B CLASS=Opt>OPTIONAL</B>
730         */
731        public final String writeType;
732        
733        /**
734         * Constructor
735         *
736         * @param characteristicId -
737         * 
738         * @param type -
739         * 
740         * @param data -
741         * <BR /><B CLASS=Opt>OPTIONAL</B>
742         * 
743         * @param writeType -
744         * <BR /><B CLASS=Opt>OPTIONAL</B>
745         */
746        public characteristicOperationReceived
747            (String characteristicId, String type, String data, String writeType)
748        {
749            super("BluetoothEmulation", "characteristicOperationReceived", 4);
750            
751            // Exception-Check(s) to ensure that if any parameters which are not declared as
752            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
753            
754            if (characteristicId == null) THROWS.throwNPE("characteristicId");
755            if (type == null)             THROWS.throwNPE("type");
756            
757            // Exception-Check(s) to ensure that if any parameters which must adhere to a
758            // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
759            
760            THROWS.checkIAE("type", type, "BluetoothEmulation.CharacteristicOperationType", BluetoothEmulation.CharacteristicOperationType);
761            THROWS.checkIAE("writeType", writeType, "BluetoothEmulation.CharacteristicWriteType", BluetoothEmulation.CharacteristicWriteType);
762            
763            this.characteristicId  = characteristicId;
764            this.type              = type;
765            this.data              = data;
766            this.writeType         = writeType;
767        }
768        
769        /**
770         * JSON Object Constructor
771         * @param jo A Json-Object having data about an instance of {@code 'characteristicOperationReceived'}.
772         */
773        public characteristicOperationReceived (JsonObject jo)
774        {
775            super("BluetoothEmulation", "characteristicOperationReceived", 4);
776        
777            this.characteristicId  = ReadJSON.getString(jo, "characteristicId", false, true);
778            this.type              = ReadJSON.getString(jo, "type", false, true);
779            this.data              = ReadJSON.getString(jo, "data", true, false);
780            this.writeType         = ReadJSON.getString(jo, "writeType", true, false);
781        }
782        
783        
784        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
785        public boolean equals(Object other)
786        {
787            if (this == other)                       return true;
788            if (other == null)                       return false;
789            if (other.getClass() != this.getClass()) return false;
790        
791            characteristicOperationReceived o = (characteristicOperationReceived) other;
792        
793            return
794                    Objects.equals(this.characteristicId, o.characteristicId)
795                &&  Objects.equals(this.type, o.type)
796                &&  Objects.equals(this.data, o.data)
797                &&  Objects.equals(this.writeType, o.writeType);
798        }
799        
800        /** Generates a Hash-Code for {@code 'this'} instance */
801        public int hashCode()
802        {
803            return
804                    Objects.hashCode(this.characteristicId)
805                +   Objects.hashCode(this.type)
806                +   Objects.hashCode(this.data)
807                +   Objects.hashCode(this.writeType);
808        }
809    }
810    
811    /**
812     * Event for when a descriptor operation of |type| to the descriptor
813     * respresented by |descriptorId| happened. |data| is expected to exist when
814     * |type| is write.
815     */
816    public static class descriptorOperationReceived
817        extends BrowserEvent
818        implements java.io.Serializable
819    {
820        /** For Object Serialization.  java.io.Serializable */
821        protected static final long serialVersionUID = 1;
822        
823        public boolean[] optionals()
824        { return new boolean[] { false, false, true, }; }
825        
826        /** <CODE>[No Description Provided by Google]</CODE> */
827        public final String descriptorId;
828        
829        /** <CODE>[No Description Provided by Google]</CODE> */
830        public final String type;
831        
832        /**
833         * <CODE>[No Description Provided by Google]</CODE>
834         * <BR /><B CLASS=Opt>OPTIONAL</B>
835         */
836        public final String data;
837        
838        /**
839         * Constructor
840         *
841         * @param descriptorId -
842         * 
843         * @param type -
844         * 
845         * @param data -
846         * <BR /><B CLASS=Opt>OPTIONAL</B>
847         */
848        public descriptorOperationReceived(String descriptorId, String type, String data)
849        {
850            super("BluetoothEmulation", "descriptorOperationReceived", 3);
851            
852            // Exception-Check(s) to ensure that if any parameters which are not declared as
853            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
854            
855            if (descriptorId == null) THROWS.throwNPE("descriptorId");
856            if (type == null)         THROWS.throwNPE("type");
857            
858            // Exception-Check(s) to ensure that if any parameters which must adhere to a
859            // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
860            
861            THROWS.checkIAE("type", type, "BluetoothEmulation.DescriptorOperationType", BluetoothEmulation.DescriptorOperationType);
862            
863            this.descriptorId  = descriptorId;
864            this.type          = type;
865            this.data          = data;
866        }
867        
868        /**
869         * JSON Object Constructor
870         * @param jo A Json-Object having data about an instance of {@code 'descriptorOperationReceived'}.
871         */
872        public descriptorOperationReceived (JsonObject jo)
873        {
874            super("BluetoothEmulation", "descriptorOperationReceived", 3);
875        
876            this.descriptorId  = ReadJSON.getString(jo, "descriptorId", false, true);
877            this.type          = ReadJSON.getString(jo, "type", false, true);
878            this.data          = ReadJSON.getString(jo, "data", true, false);
879        }
880        
881        
882        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
883        public boolean equals(Object other)
884        {
885            if (this == other)                       return true;
886            if (other == null)                       return false;
887            if (other.getClass() != this.getClass()) return false;
888        
889            descriptorOperationReceived o = (descriptorOperationReceived) other;
890        
891            return
892                    Objects.equals(this.descriptorId, o.descriptorId)
893                &&  Objects.equals(this.type, o.type)
894                &&  Objects.equals(this.data, o.data);
895        }
896        
897        /** Generates a Hash-Code for {@code 'this'} instance */
898        public int hashCode()
899        {
900            return
901                    Objects.hashCode(this.descriptorId)
902                +   Objects.hashCode(this.type)
903                +   Objects.hashCode(this.data);
904        }
905    }
906    
907    
908    // Counter for keeping the WebSocket Request ID's distinct.
909    private static int counter = 1;
910    
911    /**
912     * Enable the BluetoothEmulation domain.
913     * 
914     * @param state State of the simulated central.
915     * 
916     * @param leSupported If the simulated central supports low-energy.
917     * 
918     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
919     * {@link Ret0}&gt;</CODE>
920     *
921     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
922     * browser receives the invocation-request.
923     *
924     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
925     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
926     * {@code >} to ensure the Browser Function has run to completion.
927     */
928    public static Script<String, JsonObject, Ret0> enable(String state, boolean leSupported)
929    {
930        // Exception-Check(s) to ensure that if any parameters which are not declared as
931        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
932        
933        if (state == null) THROWS.throwNPE("state");
934        
935        // Exception-Check(s) to ensure that if any parameters which must adhere to a
936        // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
937        
938        THROWS.checkIAE("state", state, "BluetoothEmulation.CentralState", BluetoothEmulation.CentralState);
939        
940        final int       webSocketID = 53000000 + counter++;
941        final boolean[] optionals   = { false, false, };
942        
943        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
944        String requestJSON = WriteJSON.get(
945            parameterTypes.get("enable"),
946            parameterNames.get("enable"),
947            optionals, webSocketID,
948            "BluetoothEmulation.enable",
949            state, leSupported
950        );
951        
952        // This Remote Command does not have a Return-Value.
953        return new Script<>
954            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
955    }
956    
957    /**
958     * Set the state of the simulated central.
959     * 
960     * @param state State of the simulated central.
961     * 
962     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
963     * {@link Ret0}&gt;</CODE>
964     *
965     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
966     * browser receives the invocation-request.
967     *
968     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
969     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
970     * {@code >} to ensure the Browser Function has run to completion.
971     */
972    public static Script<String, JsonObject, Ret0> setSimulatedCentralState(String state)
973    {
974        // Exception-Check(s) to ensure that if any parameters which are not declared as
975        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
976        
977        if (state == null) THROWS.throwNPE("state");
978        
979        // Exception-Check(s) to ensure that if any parameters which must adhere to a
980        // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
981        
982        THROWS.checkIAE("state", state, "BluetoothEmulation.CentralState", BluetoothEmulation.CentralState);
983        
984        final int       webSocketID = 53001000 + counter++;
985        final boolean[] optionals   = { false, };
986        
987        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
988        String requestJSON = WriteJSON.get(
989            parameterTypes.get("setSimulatedCentralState"),
990            parameterNames.get("setSimulatedCentralState"),
991            optionals, webSocketID,
992            "BluetoothEmulation.setSimulatedCentralState",
993            state
994        );
995        
996        // This Remote Command does not have a Return-Value.
997        return new Script<>
998            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
999    }
1000    
1001    /**
1002     * Disable the BluetoothEmulation domain.
1003     * 
1004     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1005     * {@link Ret0}&gt;</CODE>
1006     *
1007     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
1008     * browser receives the invocation-request.
1009     *
1010     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
1011     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
1012     * {@code >} to ensure the Browser Function has run to completion.
1013     */
1014    public static Script<String, JsonObject, Ret0> disable()
1015    {
1016        final int          webSocketID = 53002000 + counter++;
1017        final boolean[]    optionals   = new boolean[0];
1018        
1019        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1020        String requestJSON = WriteJSON.get(
1021            parameterTypes.get("disable"),
1022            parameterNames.get("disable"),
1023            optionals, webSocketID,
1024            "BluetoothEmulation.disable"
1025        );
1026        
1027        // This Remote Command does not have a Return-Value.
1028        return new Script<>
1029            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
1030    }
1031    
1032    /**
1033     * Simulates a peripheral with |address|, |name| and |knownServiceUuids|
1034     * that has already been connected to the system.
1035     * 
1036     * @param address -
1037     * 
1038     * @param name -
1039     * 
1040     * @param manufacturerData -
1041     * 
1042     * @param knownServiceUuids -
1043     * 
1044     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1045     * {@link Ret0}&gt;</CODE>
1046     *
1047     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
1048     * browser receives the invocation-request.
1049     *
1050     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
1051     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
1052     * {@code >} to ensure the Browser Function has run to completion.
1053     */
1054    public static Script<String, JsonObject, Ret0> simulatePreconnectedPeripheral(
1055            String address, String name, BluetoothEmulation.ManufacturerData[] manufacturerData, 
1056            String[] knownServiceUuids
1057        )
1058    {
1059        // Exception-Check(s) to ensure that if any parameters which are not declared as
1060        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1061        
1062        if (address == null)           THROWS.throwNPE("address");
1063        if (name == null)              THROWS.throwNPE("name");
1064        if (manufacturerData == null)  THROWS.throwNPE("manufacturerData");
1065        if (knownServiceUuids == null) THROWS.throwNPE("knownServiceUuids");
1066        
1067        final int       webSocketID = 53003000 + counter++;
1068        final boolean[] optionals   = { false, false, false, false, };
1069        
1070        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1071        String requestJSON = WriteJSON.get(
1072            parameterTypes.get("simulatePreconnectedPeripheral"),
1073            parameterNames.get("simulatePreconnectedPeripheral"),
1074            optionals, webSocketID,
1075            "BluetoothEmulation.simulatePreconnectedPeripheral",
1076            address, name, manufacturerData, knownServiceUuids
1077        );
1078        
1079        // This Remote Command does not have a Return-Value.
1080        return new Script<>
1081            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
1082    }
1083    
1084    /**
1085     * Simulates an advertisement packet described in |entry| being received by
1086     * the central.
1087     * 
1088     * @param entry -
1089     * 
1090     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1091     * {@link Ret0}&gt;</CODE>
1092     *
1093     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
1094     * browser receives the invocation-request.
1095     *
1096     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
1097     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
1098     * {@code >} to ensure the Browser Function has run to completion.
1099     */
1100    public static Script<String, JsonObject, Ret0> simulateAdvertisement
1101        (BluetoothEmulation.ScanEntry entry)
1102    {
1103        // Exception-Check(s) to ensure that if any parameters which are not declared as
1104        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1105        
1106        if (entry == null) THROWS.throwNPE("entry");
1107        
1108        final int       webSocketID = 53004000 + counter++;
1109        final boolean[] optionals   = { false, };
1110        
1111        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1112        String requestJSON = WriteJSON.get(
1113            parameterTypes.get("simulateAdvertisement"),
1114            parameterNames.get("simulateAdvertisement"),
1115            optionals, webSocketID,
1116            "BluetoothEmulation.simulateAdvertisement",
1117            entry
1118        );
1119        
1120        // This Remote Command does not have a Return-Value.
1121        return new Script<>
1122            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
1123    }
1124    
1125    /**
1126     * Simulates the response code from the peripheral with |address| for a
1127     * GATT operation of |type|. The |code| value follows the HCI Error Codes from
1128     * Bluetooth Core Specification Vol 2 Part D 1.3 List Of Error Codes.
1129     * 
1130     * @param address -
1131     * 
1132     * @param type -
1133     * 
1134     * @param code -
1135     * 
1136     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1137     * {@link Ret0}&gt;</CODE>
1138     *
1139     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
1140     * browser receives the invocation-request.
1141     *
1142     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
1143     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
1144     * {@code >} to ensure the Browser Function has run to completion.
1145     */
1146    public static Script<String, JsonObject, Ret0> simulateGATTOperationResponse
1147        (String address, String type, int code)
1148    {
1149        // Exception-Check(s) to ensure that if any parameters which are not declared as
1150        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1151        
1152        if (address == null) THROWS.throwNPE("address");
1153        if (type == null)    THROWS.throwNPE("type");
1154        
1155        // Exception-Check(s) to ensure that if any parameters which must adhere to a
1156        // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
1157        
1158        THROWS.checkIAE("type", type, "BluetoothEmulation.GATTOperationType", BluetoothEmulation.GATTOperationType);
1159        
1160        final int       webSocketID = 53005000 + counter++;
1161        final boolean[] optionals   = { false, false, false, };
1162        
1163        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1164        String requestJSON = WriteJSON.get(
1165            parameterTypes.get("simulateGATTOperationResponse"),
1166            parameterNames.get("simulateGATTOperationResponse"),
1167            optionals, webSocketID,
1168            "BluetoothEmulation.simulateGATTOperationResponse",
1169            address, type, code
1170        );
1171        
1172        // This Remote Command does not have a Return-Value.
1173        return new Script<>
1174            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
1175    }
1176    
1177    /**
1178     * Simulates the response from the characteristic with |characteristicId| for a
1179     * characteristic operation of |type|. The |code| value follows the Error
1180     * Codes from Bluetooth Core Specification Vol 3 Part F 3.4.1.1 Error Response.
1181     * The |data| is expected to exist when simulating a successful read operation
1182     * response.
1183     * 
1184     * @param characteristicId -
1185     * 
1186     * @param type -
1187     * 
1188     * @param code -
1189     * 
1190     * @param data -
1191     * <BR /><B CLASS=Opt>OPTIONAL</B>
1192     * 
1193     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1194     * {@link Ret0}&gt;</CODE>
1195     *
1196     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
1197     * browser receives the invocation-request.
1198     *
1199     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
1200     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
1201     * {@code >} to ensure the Browser Function has run to completion.
1202     */
1203    public static Script<String, JsonObject, Ret0> simulateCharacteristicOperationResponse
1204        (String characteristicId, String type, int code, String data)
1205    {
1206        // Exception-Check(s) to ensure that if any parameters which are not declared as
1207        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1208        
1209        if (characteristicId == null) THROWS.throwNPE("characteristicId");
1210        if (type == null)             THROWS.throwNPE("type");
1211        
1212        // Exception-Check(s) to ensure that if any parameters which must adhere to a
1213        // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
1214        
1215        THROWS.checkIAE("type", type, "BluetoothEmulation.CharacteristicOperationType", BluetoothEmulation.CharacteristicOperationType);
1216        
1217        final int       webSocketID = 53006000 + counter++;
1218        final boolean[] optionals   = { false, false, false, true, };
1219        
1220        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1221        String requestJSON = WriteJSON.get(
1222            parameterTypes.get("simulateCharacteristicOperationResponse"),
1223            parameterNames.get("simulateCharacteristicOperationResponse"),
1224            optionals, webSocketID,
1225            "BluetoothEmulation.simulateCharacteristicOperationResponse",
1226            characteristicId, type, code, data
1227        );
1228        
1229        // This Remote Command does not have a Return-Value.
1230        return new Script<>
1231            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
1232    }
1233    
1234    /**
1235     * Simulates the response from the descriptor with |descriptorId| for a
1236     * descriptor operation of |type|. The |code| value follows the Error
1237     * Codes from Bluetooth Core Specification Vol 3 Part F 3.4.1.1 Error Response.
1238     * The |data| is expected to exist when simulating a successful read operation
1239     * response.
1240     * 
1241     * @param descriptorId -
1242     * 
1243     * @param type -
1244     * 
1245     * @param code -
1246     * 
1247     * @param data -
1248     * <BR /><B CLASS=Opt>OPTIONAL</B>
1249     * 
1250     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1251     * {@link Ret0}&gt;</CODE>
1252     *
1253     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
1254     * browser receives the invocation-request.
1255     *
1256     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
1257     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
1258     * {@code >} to ensure the Browser Function has run to completion.
1259     */
1260    public static Script<String, JsonObject, Ret0> simulateDescriptorOperationResponse
1261        (String descriptorId, String type, int code, String data)
1262    {
1263        // Exception-Check(s) to ensure that if any parameters which are not declared as
1264        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1265        
1266        if (descriptorId == null) THROWS.throwNPE("descriptorId");
1267        if (type == null)         THROWS.throwNPE("type");
1268        
1269        // Exception-Check(s) to ensure that if any parameters which must adhere to a
1270        // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
1271        
1272        THROWS.checkIAE("type", type, "BluetoothEmulation.DescriptorOperationType", BluetoothEmulation.DescriptorOperationType);
1273        
1274        final int       webSocketID = 53007000 + counter++;
1275        final boolean[] optionals   = { false, false, false, true, };
1276        
1277        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1278        String requestJSON = WriteJSON.get(
1279            parameterTypes.get("simulateDescriptorOperationResponse"),
1280            parameterNames.get("simulateDescriptorOperationResponse"),
1281            optionals, webSocketID,
1282            "BluetoothEmulation.simulateDescriptorOperationResponse",
1283            descriptorId, type, code, data
1284        );
1285        
1286        // This Remote Command does not have a Return-Value.
1287        return new Script<>
1288            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
1289    }
1290    
1291    /**
1292     * Adds a service with |serviceUuid| to the peripheral with |address|.
1293     * 
1294     * @param address -
1295     * 
1296     * @param serviceUuid -
1297     * 
1298     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1299     * String&gt;</CODE>
1300     * 
1301     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
1302     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
1303     * String&gt;</CODE> will be returned.
1304     *
1305     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
1306     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
1307      * may be retrieved.</I>
1308     *
1309     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
1310     * <BR /><BR /><UL CLASS=JDUL>
1311     * <LI><CODE>String (<B>serviceId</B></CODE>)
1312     *     <BR />An identifier that uniquely represents this service.
1313     * </LI>
1314     * </UL> */
1315    public static Script<String, JsonObject, String> addService
1316        (String address, String serviceUuid)
1317    {
1318        // Exception-Check(s) to ensure that if any parameters which are not declared as
1319        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1320        
1321        if (address == null)     THROWS.throwNPE("address");
1322        if (serviceUuid == null) THROWS.throwNPE("serviceUuid");
1323        
1324        final int       webSocketID = 53008000 + counter++;
1325        final boolean[] optionals   = { false, false, };
1326        
1327        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1328        String requestJSON = WriteJSON.get(
1329            parameterTypes.get("addService"),
1330            parameterNames.get("addService"),
1331            optionals, webSocketID,
1332            "BluetoothEmulation.addService",
1333            address, serviceUuid
1334        );
1335        
1336        // 'JSON Binding' ... Converts Browser Response-JSON to 'String'
1337        Function<JsonObject, String> responseProcessor = (JsonObject jo) ->
1338            ReadJSON.getString(jo, "serviceId", false, true);
1339        
1340        return new Script<>(webSocketID, requestJSON, responseProcessor);
1341    }
1342    
1343    /**
1344     * Removes the service respresented by |serviceId| from the simulated central.
1345     * 
1346     * @param serviceId -
1347     * 
1348     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1349     * {@link Ret0}&gt;</CODE>
1350     *
1351     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
1352     * browser receives the invocation-request.
1353     *
1354     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
1355     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
1356     * {@code >} to ensure the Browser Function has run to completion.
1357     */
1358    public static Script<String, JsonObject, Ret0> removeService(String serviceId)
1359    {
1360        // Exception-Check(s) to ensure that if any parameters which are not declared as
1361        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1362        
1363        if (serviceId == null) THROWS.throwNPE("serviceId");
1364        
1365        final int       webSocketID = 53009000 + counter++;
1366        final boolean[] optionals   = { false, };
1367        
1368        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1369        String requestJSON = WriteJSON.get(
1370            parameterTypes.get("removeService"),
1371            parameterNames.get("removeService"),
1372            optionals, webSocketID,
1373            "BluetoothEmulation.removeService",
1374            serviceId
1375        );
1376        
1377        // This Remote Command does not have a Return-Value.
1378        return new Script<>
1379            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
1380    }
1381    
1382    /**
1383     * Adds a characteristic with |characteristicUuid| and |properties| to the
1384     * service represented by |serviceId|.
1385     * 
1386     * @param serviceId -
1387     * 
1388     * @param characteristicUuid -
1389     * 
1390     * @param properties -
1391     * 
1392     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1393     * String&gt;</CODE>
1394     * 
1395     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
1396     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
1397     * String&gt;</CODE> will be returned.
1398     *
1399     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
1400     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
1401      * may be retrieved.</I>
1402     *
1403     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
1404     * <BR /><BR /><UL CLASS=JDUL>
1405     * <LI><CODE>String (<B>characteristicId</B></CODE>)
1406     *     <BR />An identifier that uniquely represents this characteristic.
1407     * </LI>
1408     * </UL> */
1409    public static Script<String, JsonObject, String> addCharacteristic(
1410            String serviceId, String characteristicUuid, 
1411            BluetoothEmulation.CharacteristicProperties properties
1412        )
1413    {
1414        // Exception-Check(s) to ensure that if any parameters which are not declared as
1415        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1416        
1417        if (serviceId == null)          THROWS.throwNPE("serviceId");
1418        if (characteristicUuid == null) THROWS.throwNPE("characteristicUuid");
1419        if (properties == null)         THROWS.throwNPE("properties");
1420        
1421        final int       webSocketID = 53010000 + counter++;
1422        final boolean[] optionals   = { false, false, false, };
1423        
1424        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1425        String requestJSON = WriteJSON.get(
1426            parameterTypes.get("addCharacteristic"),
1427            parameterNames.get("addCharacteristic"),
1428            optionals, webSocketID,
1429            "BluetoothEmulation.addCharacteristic",
1430            serviceId, characteristicUuid, properties
1431        );
1432        
1433        // 'JSON Binding' ... Converts Browser Response-JSON to 'String'
1434        Function<JsonObject, String> responseProcessor = (JsonObject jo) ->
1435            ReadJSON.getString(jo, "characteristicId", false, true);
1436        
1437        return new Script<>(webSocketID, requestJSON, responseProcessor);
1438    }
1439    
1440    /**
1441     * Removes the characteristic respresented by |characteristicId| from the
1442     * simulated central.
1443     * 
1444     * @param characteristicId -
1445     * 
1446     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1447     * {@link Ret0}&gt;</CODE>
1448     *
1449     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
1450     * browser receives the invocation-request.
1451     *
1452     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
1453     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
1454     * {@code >} to ensure the Browser Function has run to completion.
1455     */
1456    public static Script<String, JsonObject, Ret0> removeCharacteristic(String characteristicId)
1457    {
1458        // Exception-Check(s) to ensure that if any parameters which are not declared as
1459        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1460        
1461        if (characteristicId == null) THROWS.throwNPE("characteristicId");
1462        
1463        final int       webSocketID = 53011000 + counter++;
1464        final boolean[] optionals   = { false, };
1465        
1466        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1467        String requestJSON = WriteJSON.get(
1468            parameterTypes.get("removeCharacteristic"),
1469            parameterNames.get("removeCharacteristic"),
1470            optionals, webSocketID,
1471            "BluetoothEmulation.removeCharacteristic",
1472            characteristicId
1473        );
1474        
1475        // This Remote Command does not have a Return-Value.
1476        return new Script<>
1477            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
1478    }
1479    
1480    /**
1481     * Adds a descriptor with |descriptorUuid| to the characteristic respresented
1482     * by |characteristicId|.
1483     * 
1484     * @param characteristicId -
1485     * 
1486     * @param descriptorUuid -
1487     * 
1488     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1489     * String&gt;</CODE>
1490     * 
1491     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
1492     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
1493     * String&gt;</CODE> will be returned.
1494     *
1495     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
1496     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
1497      * may be retrieved.</I>
1498     *
1499     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
1500     * <BR /><BR /><UL CLASS=JDUL>
1501     * <LI><CODE>String (<B>descriptorId</B></CODE>)
1502     *     <BR />An identifier that uniquely represents this descriptor.
1503     * </LI>
1504     * </UL> */
1505    public static Script<String, JsonObject, String> addDescriptor
1506        (String characteristicId, String descriptorUuid)
1507    {
1508        // Exception-Check(s) to ensure that if any parameters which are not declared as
1509        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1510        
1511        if (characteristicId == null) THROWS.throwNPE("characteristicId");
1512        if (descriptorUuid == null)   THROWS.throwNPE("descriptorUuid");
1513        
1514        final int       webSocketID = 53012000 + counter++;
1515        final boolean[] optionals   = { false, false, };
1516        
1517        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1518        String requestJSON = WriteJSON.get(
1519            parameterTypes.get("addDescriptor"),
1520            parameterNames.get("addDescriptor"),
1521            optionals, webSocketID,
1522            "BluetoothEmulation.addDescriptor",
1523            characteristicId, descriptorUuid
1524        );
1525        
1526        // 'JSON Binding' ... Converts Browser Response-JSON to 'String'
1527        Function<JsonObject, String> responseProcessor = (JsonObject jo) ->
1528            ReadJSON.getString(jo, "descriptorId", false, true);
1529        
1530        return new Script<>(webSocketID, requestJSON, responseProcessor);
1531    }
1532    
1533    /**
1534     * Removes the descriptor with |descriptorId| from the simulated central.
1535     * 
1536     * @param descriptorId -
1537     * 
1538     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1539     * {@link Ret0}&gt;</CODE>
1540     *
1541     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
1542     * browser receives the invocation-request.
1543     *
1544     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
1545     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
1546     * {@code >} to ensure the Browser Function has run to completion.
1547     */
1548    public static Script<String, JsonObject, Ret0> removeDescriptor(String descriptorId)
1549    {
1550        // Exception-Check(s) to ensure that if any parameters which are not declared as
1551        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1552        
1553        if (descriptorId == null) THROWS.throwNPE("descriptorId");
1554        
1555        final int       webSocketID = 53013000 + counter++;
1556        final boolean[] optionals   = { false, };
1557        
1558        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1559        String requestJSON = WriteJSON.get(
1560            parameterTypes.get("removeDescriptor"),
1561            parameterNames.get("removeDescriptor"),
1562            optionals, webSocketID,
1563            "BluetoothEmulation.removeDescriptor",
1564            descriptorId
1565        );
1566        
1567        // This Remote Command does not have a Return-Value.
1568        return new Script<>
1569            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
1570    }
1571    
1572    /**
1573     * Simulates a GATT disconnection from the peripheral with |address|.
1574     * 
1575     * @param address -
1576     * 
1577     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1578     * {@link Ret0}&gt;</CODE>
1579     *
1580     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
1581     * browser receives the invocation-request.
1582     *
1583     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
1584     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
1585     * {@code >} to ensure the Browser Function has run to completion.
1586     */
1587    public static Script<String, JsonObject, Ret0> simulateGATTDisconnection(String address)
1588    {
1589        // Exception-Check(s) to ensure that if any parameters which are not declared as
1590        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1591        
1592        if (address == null) THROWS.throwNPE("address");
1593        
1594        final int       webSocketID = 53014000 + counter++;
1595        final boolean[] optionals   = { false, };
1596        
1597        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1598        String requestJSON = WriteJSON.get(
1599            parameterTypes.get("simulateGATTDisconnection"),
1600            parameterNames.get("simulateGATTDisconnection"),
1601            optionals, webSocketID,
1602            "BluetoothEmulation.simulateGATTDisconnection",
1603            address
1604        );
1605        
1606        // This Remote Command does not have a Return-Value.
1607        return new Script<>
1608            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
1609    }
1610    
1611}