ble 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/ble.rb +12 -15
- data/lib/ble/characteristic.rb +32 -38
- data/lib/ble/db_eddystone.rb +50 -0
- data/lib/ble/db_nordic.rb +26 -0
- data/lib/ble/db_sig_characteristic.rb +142 -0
- data/lib/ble/{db_service.rb → db_sig_service.rb} +0 -1
- data/lib/ble/device.rb +43 -35
- data/lib/ble/service.rb +26 -33
- data/lib/ble/uuid.rb +25 -0
- data/lib/ble/version.rb +7 -2
- metadata +7 -5
- data/lib/ble/db_characteristic.rb +0 -70
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: d0d63de7a39417e54dd34e2fc70a326061d36cc6
         | 
| 4 | 
            +
              data.tar.gz: ac360bfb08b81186e16840c3c7dac76f09788d6f
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: d4a84b8634507629242d89e81542d03e5036ca73faba52e1a4db5d128ea8140e8ac46925de9b45948e12fa6de894865a9e2835500b5ef28265aa2c597bae989a
         | 
| 7 | 
            +
              data.tar.gz: ff96bdeadd3582a120bcd68b8b48864a736d611653c8754508daf08fe68f7fa5808cc7395397277c64be0c434a3a14f642f4bb2d445968f98927007e997caf4b
         | 
    
        data/lib/ble.rb
    CHANGED
    
    | @@ -61,9 +61,11 @@ module BLE | |
| 61 61 | 
             
                # on this device
         | 
| 62 62 | 
             
                class NotFound               < Error         ; end
         | 
| 63 63 | 
             
                class AccessUnavailable      < Error         ; end
         | 
| 64 | 
            -
                
         | 
| 64 | 
            +
                class NotSupported      < Error         ; end
         | 
| 65 65 |  | 
| 66 | 
            -
             | 
| 66 | 
            +
             | 
| 67 | 
            +
                # Base UUID for GATT services defined with 16bit or 32bit UUID
         | 
| 68 | 
            +
                GATT_BASE_UUID="00000000-0000-1000-8000-00805f9b34fb"
         | 
| 67 69 |  | 
| 68 70 | 
             
                #"DisplayOnly", "DisplayYesNo", "KeyboardOnly",
         | 
| 69 71 | 
             
                # "NoInputNoOutput" and "KeyboardDisplay" which
         | 
| @@ -73,9 +75,9 @@ module BLE | |
| 73 75 | 
             
                    raise NotYetImplemented
         | 
| 74 76 | 
             
                    bus = DBus.session_bus
         | 
| 75 77 | 
             
                    service = bus.request_service("org.ruby.service")
         | 
| 76 | 
            -
             | 
| 78 | 
            +
             | 
| 77 79 | 
             
                    service.export(BLE::Agent.new(agent_path))
         | 
| 78 | 
            -
             | 
| 80 | 
            +
             | 
| 79 81 | 
             
                    o_bluez = BLUEZ.object('/org/bluez')
         | 
| 80 82 | 
             
                    o_bluez.introspect
         | 
| 81 83 | 
             
                    o_bluez[I_AGENT_MANAGER].RegisterAgent(agent_path, "NoInputNoOutput")
         | 
| @@ -83,30 +85,25 @@ module BLE | |
| 83 85 |  | 
| 84 86 |  | 
| 85 87 |  | 
| 86 | 
            -
                def self.UUID(val)
         | 
| 87 | 
            -
                    val.downcase
         | 
| 88 | 
            -
                end
         | 
| 89 | 
            -
                
         | 
| 90 | 
            -
                class UUID
         | 
| 91 | 
            -
                    REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
         | 
| 92 | 
            -
                end
         | 
| 93 | 
            -
                  
         | 
| 94 88 |  | 
| 95 89 | 
             
                # Check if Bluetooth underlying API is accessible
         | 
| 96 90 | 
             
                def self.ok?
         | 
| 97 91 | 
             
                    BLUEZ.exists?
         | 
| 98 92 | 
             
                end
         | 
| 99 | 
            -
             | 
| 93 | 
            +
             | 
| 100 94 | 
             
            end
         | 
| 101 95 |  | 
| 102 96 | 
             
            require_relative 'ble/version'
         | 
| 97 | 
            +
            require_relative 'ble/uuid'
         | 
| 103 98 | 
             
            require_relative 'ble/adapter'
         | 
| 104 99 | 
             
            require_relative 'ble/device'
         | 
| 105 100 | 
             
            require_relative 'ble/service'
         | 
| 106 101 | 
             
            require_relative 'ble/characteristic'
         | 
| 107 102 | 
             
            require_relative 'ble/agent'
         | 
| 108 103 |  | 
| 109 | 
            -
            require_relative 'ble/ | 
| 110 | 
            -
            require_relative 'ble/ | 
| 104 | 
            +
            require_relative 'ble/db_sig_service'
         | 
| 105 | 
            +
            require_relative 'ble/db_sig_characteristic'
         | 
| 106 | 
            +
            require_relative 'ble/db_eddystone'
         | 
| 107 | 
            +
            require_relative 'ble/db_nordic'
         | 
| 111 108 |  | 
| 112 109 |  | 
    
        data/lib/ble/characteristic.rb
    CHANGED
    
    | @@ -76,6 +76,7 @@ module Characteristic | |
| 76 76 | 
             
                    when Symbol      then DB_NICKNAME[id]
         | 
| 77 77 | 
             
                    when UUID::REGEX then DB_UUID[id]
         | 
| 78 78 | 
             
                    when String      then DB_TYPE[id]
         | 
| 79 | 
            +
                    when Integer     then DB_UUID[BLE::UUID(id)]
         | 
| 79 80 | 
             
                    else raise ArgumentError, "invalid type for characteristic id"
         | 
| 80 81 | 
             
                    end
         | 
| 81 82 | 
             
                end
         | 
| @@ -104,56 +105,49 @@ module Characteristic | |
| 104 105 | 
             
                #
         | 
| 105 106 | 
             
                # @param uuid [Integer, String] 16-bit, 32-bit or 128-bit uuid
         | 
| 106 107 | 
             
                # @param name [String]
         | 
| 107 | 
            -
                # @ | 
| 108 | 
            -
                # @option opts : | 
| 109 | 
            -
                # @option opts : | 
| 110 | 
            -
                # @option opts : | 
| 108 | 
            +
                # @option opts :type [String] type
         | 
| 109 | 
            +
                # @option opts :nick [Symbol] nickname
         | 
| 110 | 
            +
                # @option opts :in   [Proc] convert to ruby
         | 
| 111 | 
            +
                # @option opts :out  [Proc] convert to bluetooth data
         | 
| 112 | 
            +
                # @option opts :vry  [Proc] verify
         | 
| 111 113 | 
             
                # @return [Hash] characteristic description
         | 
| 112 | 
            -
                def self.add(uuid, name:,  | 
| 113 | 
            -
                     | 
| 114 | 
            -
                     | 
| 115 | 
            -
                     | 
| 114 | 
            +
                def self.add(uuid, name:, **opts)
         | 
| 115 | 
            +
                    uuid = BLE::UUID(uuid)
         | 
| 116 | 
            +
                    type =  opts.delete :type
         | 
| 117 | 
            +
                    nick = opts.delete :nick
         | 
| 118 | 
            +
                    _in  = opts.delete :in
         | 
| 119 | 
            +
                    _out = opts.delete :out
         | 
| 120 | 
            +
                    vrfy = opts.delete :vrfy            
         | 
| 116 121 | 
             
                    if opts.first 
         | 
| 117 122 | 
             
                        raise ArgumentError, "unknown keyword: #{opts.first[0]}" 
         | 
| 118 123 | 
             
                    end
         | 
| 119 124 |  | 
| 120 | 
            -
                    uuid = case uuid
         | 
| 121 | 
            -
                           when Integer
         | 
| 122 | 
            -
                               if !(0..4294967296).include?(uuid)
         | 
| 123 | 
            -
                                   raise ArgumentError, "not a 16bit or 32bit uuid"
         | 
| 124 | 
            -
                               end
         | 
| 125 | 
            -
                               ([uuid].pack("L>").unpack('H*').first +
         | 
| 126 | 
            -
                                "-0000-1000-8000-00805F9B34FB")
         | 
| 127 | 
            -
                               
         | 
| 128 | 
            -
                           when String
         | 
| 129 | 
            -
                               if uuid !~ UUID::REGEX
         | 
| 130 | 
            -
                                   raise ArgumentError, "not a 128bit uuid string"
         | 
| 131 | 
            -
                               end
         | 
| 132 | 
            -
                               uuid
         | 
| 133 | 
            -
                           else raise ArgumentError, "invalid uuid type"
         | 
| 134 | 
            -
                           end
         | 
| 135 | 
            -
                    uuid = uuid.downcase
         | 
| 136 | 
            -
                    type = type.downcase
         | 
| 137 125 |  | 
| 138 | 
            -
                     | 
| 139 | 
            -
                        name: name,
         | 
| 140 | 
            -
                        type: type,
         | 
| 126 | 
            +
                    desc = DB_UUID[uuid] = {
         | 
| 141 127 | 
             
                        uuid: uuid,
         | 
| 142 | 
            -
                         | 
| 143 | 
            -
             | 
| 128 | 
            +
                        name: name,
         | 
| 129 | 
            +
                          in: _in,
         | 
| 130 | 
            +
                         out: _out,
         | 
| 144 131 | 
             
                        vrfy: vrfy
         | 
| 145 132 | 
             
                    }
         | 
| 146 133 |  | 
| 147 | 
            -
                     | 
| 148 | 
            -
                     | 
| 149 | 
            -
             | 
| 150 | 
            -
             | 
| 151 | 
            -
             | 
| 152 | 
            -
             | 
| 134 | 
            +
                    # Add type if specified
         | 
| 135 | 
            +
                    if type
         | 
| 136 | 
            +
                        type = type.downcase
         | 
| 137 | 
            +
                        desc.merge!(type: type)
         | 
| 138 | 
            +
                        DB_TYPE[type] = desc
         | 
| 139 | 
            +
                    end
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                    # Add nickname if specified or can be derived from type
         | 
| 142 | 
            +
                    if nick.nil? && type && type =~ /\.(?<key>[^.]+)$/
         | 
| 143 | 
            +
                        nick = $1.to_sym if type.start_with? 'org.bluetooth.characteristic'
         | 
| 144 | 
            +
                    end
         | 
| 145 | 
            +
                    if nick
         | 
| 146 | 
            +
                        if DB_NICKNAME.include?(nick)
         | 
| 153 147 | 
             
                            raise ArgumentError,
         | 
| 154 | 
            -
                                  "nickname '#{ | 
| 148 | 
            +
                                  "nickname '#{nick}' already registered (uuid: #{uuid})"
         | 
| 155 149 | 
             
                        end
         | 
| 156 | 
            -
                        DB_NICKNAME[ | 
| 150 | 
            +
                        DB_NICKNAME[nick] = desc
         | 
| 157 151 | 
             
                    end
         | 
| 158 152 | 
             
                end
         | 
| 159 153 | 
             
            end
         | 
| @@ -0,0 +1,50 @@ | |
| 1 | 
            +
            module BLE
         | 
| 2 | 
            +
            module Service
         | 
| 3 | 
            +
                add 'ee0c2080-8786-40ba-ab96-99b91ac981d8',
         | 
| 4 | 
            +
                    name: 'Eddystone-URL Beacon Configuration'
         | 
| 5 | 
            +
            end
         | 
| 6 | 
            +
            end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            module BLE
         | 
| 9 | 
            +
            module Characteristic
         | 
| 10 | 
            +
                add 'ee0c2081-8786-40ba-ab96-99b91ac981d8',
         | 
| 11 | 
            +
                    name: 'Eddystone Lock State',
         | 
| 12 | 
            +
                    nick: :esurl_lockstate
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                add 'ee0c2082-8786-40ba-ab96-99b91ac981d8',
         | 
| 15 | 
            +
                    name: 'Eddystone Lock',
         | 
| 16 | 
            +
                    nick: :esurl_lock
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                add 'ee0c2083-8786-40ba-ab96-99b91ac981d8',
         | 
| 19 | 
            +
                    name: 'Eddystone Unlock',
         | 
| 20 | 
            +
                    nick: :esurl_unlock
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                add 'ee0c2084-8786-40ba-ab96-99b91ac981d8',
         | 
| 23 | 
            +
                    name: 'Eddystone URL Data',
         | 
| 24 | 
            +
                    nick: :esurl_data
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                add 'ee0c2085-8786-40ba-ab96-99b91ac981d8',
         | 
| 27 | 
            +
                    name: 'Eddystone Flags',
         | 
| 28 | 
            +
                    nick: :esurl_flags
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                add 'ee0c2086-8786-40ba-ab96-99b91ac981d8',
         | 
| 31 | 
            +
                    name: 'Eddystone Adv Tx Power Levels',
         | 
| 32 | 
            +
                    nick: :esurl_adv_txpower_levels
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                add 'ee0c2087-8786-40ba-ab96-99b91ac981d8',
         | 
| 35 | 
            +
                    name: 'Eddystone TX power mode',
         | 
| 36 | 
            +
                    nick: :esurl_txpower_mode
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                add 'ee0c2088-8786-40ba-ab96-99b91ac981d8',
         | 
| 39 | 
            +
                    name: 'Eddystone Beacon period',
         | 
| 40 | 
            +
                    nick: :esurl_beacon_period
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                add 'ee0c2089-8786-40ba-ab96-99b91ac981d8',
         | 
| 43 | 
            +
                    name: 'Eddystone Reset',
         | 
| 44 | 
            +
                    nick: :esurl_reset
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                add 'ee0c208a-8786-40ba-ab96-99b91ac981d8',
         | 
| 47 | 
            +
                    name: 'Eddystone Radio Tx Power Levels',
         | 
| 48 | 
            +
                    nick: :esurl_radio_txpower_levels
         | 
| 49 | 
            +
            end
         | 
| 50 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            module BLE
         | 
| 2 | 
            +
            module Service
         | 
| 3 | 
            +
                add '00001530-1212-efde-1523-785feabcd123',
         | 
| 4 | 
            +
                    name: 'Nordic Device Firmware Update Service'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                add '6e400001-b5a3-f393-e0a9-e50e24dcca9e',
         | 
| 7 | 
            +
                    name: 'Nordic UART Service'
         | 
| 8 | 
            +
            end
         | 
| 9 | 
            +
            end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
             | 
| 12 | 
            +
            module BLE
         | 
| 13 | 
            +
            module Characteristic
         | 
| 14 | 
            +
                add '00001531-1212-efde-1523-785feabcd123', # WriteWithoutResponse
         | 
| 15 | 
            +
                    name: 'DFU Packet'
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                add '00001532-1212-efde-1523-785feabcd123', # Write,Notify
         | 
| 18 | 
            +
                    name: 'DFU Control Point'
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                add '6e400002-b5a3-f393-e0a9-e50e24dcca9e',
         | 
| 21 | 
            +
                    name: 'UART TX'
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                add '6e400003-b5a3-f393-e0a9-e50e24dcca9e',
         | 
| 24 | 
            +
                    name: 'UART RX'
         | 
| 25 | 
            +
            end
         | 
| 26 | 
            +
            end
         | 
| @@ -0,0 +1,142 @@ | |
| 1 | 
            +
            module BLE
         | 
| 2 | 
            +
            module Characteristic
         | 
| 3 | 
            +
                #   C         | Integer | 8-bit unsigned (unsigned char)
         | 
| 4 | 
            +
                #   S         | Integer | 16-bit unsigned, native endian (uint16_t)
         | 
| 5 | 
            +
                #   L         | Integer | 32-bit unsigned, native endian (uint32_t)
         | 
| 6 | 
            +
                #   Q         | Integer | 64-bit unsigned, native endian (uint64_t)
         | 
| 7 | 
            +
                #             |         |
         | 
| 8 | 
            +
                #   c         | Integer | 8-bit signed (signed char)
         | 
| 9 | 
            +
                #   s         | Integer | 16-bit signed, native endian (int16_t)
         | 
| 10 | 
            +
                #   l         | Integer | 32-bit signed, native endian (int32_t)
         | 
| 11 | 
            +
                #   q         | Integer | 64-bit signed, native endian (int64_t)
         | 
| 12 | 
            +
                #
         | 
| 13 | 
            +
                #   <         | Little endian
         | 
| 14 | 
            +
                #   >         | Big endian
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                add 0x2A07,
         | 
| 17 | 
            +
                    name: 'Tx Power Level',
         | 
| 18 | 
            +
                    type: 'org.bluetooth.characteristic.tx_power_level',
         | 
| 19 | 
            +
                    vrfy: ->(x) { (-100..20).include?(c) },
         | 
| 20 | 
            +
                      in: ->(s) { s.unpack('c').first },
         | 
| 21 | 
            +
                     out: ->(v) { [ v ].pack('c') }
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                add 0x2A23,
         | 
| 24 | 
            +
                    name: 'System ID',
         | 
| 25 | 
            +
                    type: 'org.bluetooth.characteristic.system_id',
         | 
| 26 | 
            +
                    vrfy: ->(x) { (0..1099511627775).include?(x[0]) &&
         | 
| 27 | 
            +
                                  (0..16777215     ).include?(x[1])},
         | 
| 28 | 
            +
                      in: ->(s) { raise NotYetImplemented },
         | 
| 29 | 
            +
                     out: ->(v) { raise NotYetImplemented }
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                add 0x2A24,
         | 
| 32 | 
            +
                    name: 'Model Number String',
         | 
| 33 | 
            +
                    type: 'org.bluetooth.characteristic.model_number_string',
         | 
| 34 | 
            +
                      in: ->(s) { s.force_encoding('UTF-8') },
         | 
| 35 | 
            +
                     out: ->(v) { v.encode('UTF-8') }
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                add 0x2A25,
         | 
| 38 | 
            +
                    name: 'Serial Number String',
         | 
| 39 | 
            +
                    type: 'org.bluetooth.characteristic.serial_number_string',
         | 
| 40 | 
            +
                      in: ->(s) { s.force_encoding('UTF-8') },
         | 
| 41 | 
            +
                     out: ->(v) { v.encode('UTF-8') }
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                add 0x2A26,
         | 
| 44 | 
            +
                    name: 'Firmware Revision String',
         | 
| 45 | 
            +
                    type: 'org.bluetooth.characteristic.firmware_revision_string',
         | 
| 46 | 
            +
                      in: ->(s) { s.force_encoding('UTF-8') },
         | 
| 47 | 
            +
                     out: ->(v) { v.encode('UTF-8') }
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                add 0x2A27,
         | 
| 50 | 
            +
                    name: 'Hardware Revision String',
         | 
| 51 | 
            +
                    type: 'org.bluetooth.characteristic.hardware_revision_string',
         | 
| 52 | 
            +
                      in: ->(s) { s.force_encoding('UTF-8') },
         | 
| 53 | 
            +
                     out: ->(v) { v.encode('UTF-8') }
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                add 0x2A28,
         | 
| 56 | 
            +
                    name: 'Software Revision String',
         | 
| 57 | 
            +
                    type: 'org.bluetooth.characteristic.software_revision_string',
         | 
| 58 | 
            +
                      in: ->(s) { s.force_encoding('UTF-8') },
         | 
| 59 | 
            +
                     out: ->(v) { v.encode('UTF-8') }
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                add 0x2A29,
         | 
| 62 | 
            +
                    name: 'Manufacturer Name String',
         | 
| 63 | 
            +
                    type: 'org.bluetooth.characteristic.manufacturer_name_string',
         | 
| 64 | 
            +
                      in: ->(s) { s.force_encoding('UTF-8') },
         | 
| 65 | 
            +
                     out: ->(v) { v.encode('UTF-8') }
         | 
| 66 | 
            +
                
         | 
| 67 | 
            +
                add 0x2A2A,
         | 
| 68 | 
            +
                    name: 'IEEE 11073-20601 Regulatory Certification Data List',
         | 
| 69 | 
            +
                    type: 'org.bluetooth.characteristic.ieee_11073-20601_regulatory_certification_data_list',
         | 
| 70 | 
            +
                      in: ->(s) { raise NotYetImplemented },
         | 
| 71 | 
            +
                     out: ->(v) { raise NotYetImplemented }
         | 
| 72 | 
            +
                
         | 
| 73 | 
            +
                add 0x2A50,
         | 
| 74 | 
            +
                    name: 'PnP ID',
         | 
| 75 | 
            +
                    type: 'org.bluetooth.characteristic.pnp_id',
         | 
| 76 | 
            +
                     in: ->(s) { vendor_src, vendor_id,
         | 
| 77 | 
            +
                                 product_id, product_version = s.unpack('CS<S<S<')
         | 
| 78 | 
            +
                                 vendor_src = case vendor_src
         | 
| 79 | 
            +
                                              when 1 then :bluetooth_sig
         | 
| 80 | 
            +
                                              when 2 then :usb_forum
         | 
| 81 | 
            +
                                              else        :reserved
         | 
| 82 | 
            +
                                              end
         | 
| 83 | 
            +
                                 [ vendor_src, vendor_id,
         | 
| 84 | 
            +
                                   product_id, product_version ] },
         | 
| 85 | 
            +
                     out: ->(v) { raise NotYetImplemented }
         | 
| 86 | 
            +
                
         | 
| 87 | 
            +
                
         | 
| 88 | 
            +
                add 0x2A6E,
         | 
| 89 | 
            +
                    name: 'Temperature',
         | 
| 90 | 
            +
                    type: 'org.bluetooth.characteristic.temperature',
         | 
| 91 | 
            +
                    vrfy: ->(x) { (0..100).include?(x) },
         | 
| 92 | 
            +
                      in: ->(s) { s.unpack('s<').first.to_f / 100 },
         | 
| 93 | 
            +
                     out: ->(v) { [ v*100 ].pack('s<') }
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                add 0x2A76,
         | 
| 96 | 
            +
                    name: 'UV Index',
         | 
| 97 | 
            +
                    type: 'org.bluetooth.characteristic.uv_index',
         | 
| 98 | 
            +
                      in: ->(s) { s.unpack('C').first },
         | 
| 99 | 
            +
                     out: ->(v) { [ v ].pack('C') }
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                add 0x2A77,
         | 
| 102 | 
            +
                    name: 'Irradiance',
         | 
| 103 | 
            +
                    type: 'org.bluetooth.characteristic.irradiance',
         | 
| 104 | 
            +
                      in: ->(s) { s.unpack('S<').first.to_f / 10 },
         | 
| 105 | 
            +
                     out: ->(v) { [ v*10 ].pack('S<') }
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                add 0x2A7A,
         | 
| 108 | 
            +
                    name: 'Heat Index',
         | 
| 109 | 
            +
                    type: 'org.bluetooth.characteristic.heat_index',
         | 
| 110 | 
            +
                      in: ->(s) { s.unpack('c').first },
         | 
| 111 | 
            +
                     out: ->(v) { [ v ].pack('c') }
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                add 0x2A19,
         | 
| 114 | 
            +
                    name: 'Battery Level',
         | 
| 115 | 
            +
                    type: 'org.bluetooth.characteristic.battery_level',
         | 
| 116 | 
            +
                    vrfy: ->(x) { (0..100).include?(x) },
         | 
| 117 | 
            +
                      in: ->(s) { s.unpack('C').first },
         | 
| 118 | 
            +
                     out: ->(v) { [ v ].pack('C') }
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                add 0x2A6F,
         | 
| 121 | 
            +
                    name: 'Humidity',
         | 
| 122 | 
            +
                    type: 'org.bluetooth.characteristic.humidity',
         | 
| 123 | 
            +
                    vrfy: ->(x) { (0..100).include?(x) },
         | 
| 124 | 
            +
                      in: ->(s) { s.unpack('S<').first.to_f / 100 },
         | 
| 125 | 
            +
                     out: ->(v) { [ v*100 ].pack('S<') }
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                add 0x2A6D,
         | 
| 128 | 
            +
                    name: 'Pressure',
         | 
| 129 | 
            +
                    type: 'org.bluetooth.characteristic.pressure',
         | 
| 130 | 
            +
                    vrfy: ->(x) { x >= 0 },
         | 
| 131 | 
            +
                      in: ->(s) { s.unpack('L<').first.to_f / 10 },
         | 
| 132 | 
            +
                     out: ->(v) { [ v*10 ].pack('L<') }
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                add 0x2AB3,
         | 
| 135 | 
            +
                    name: 'Altitude',
         | 
| 136 | 
            +
                    type: 'org.bluetooth.characteristic.altitude',
         | 
| 137 | 
            +
                    vrfy: ->(x) { x >= 0 },
         | 
| 138 | 
            +
                      in: ->(s) { s.unpack('S<').first },
         | 
| 139 | 
            +
                      out: ->(v) { [ v ].pack('S<') }
         | 
| 140 | 
            +
             | 
| 141 | 
            +
            end
         | 
| 142 | 
            +
            end
         | 
    
        data/lib/ble/device.rb
    CHANGED
    
    | @@ -19,19 +19,19 @@ class Device | |
| 19 19 | 
             
                    @adapter, @dev = adapter, dev
         | 
| 20 20 | 
             
                    @auto_refresh  = auto_refresh
         | 
| 21 21 | 
             
                    @services      = {}
         | 
| 22 | 
            -
             | 
| 22 | 
            +
             | 
| 23 23 | 
             
                    @n_adapter = adapter
         | 
| 24 24 | 
             
                    @p_adapter = "/org/bluez/#{@n_adapter}"
         | 
| 25 25 | 
             
                    @o_adapter = BLUEZ.object(@p_adapter)
         | 
| 26 26 | 
             
                    @o_adapter.introspect
         | 
| 27 | 
            -
             | 
| 27 | 
            +
             | 
| 28 28 | 
             
                    @n_dev     = 'dev_' + dev.tr(':', '_')
         | 
| 29 29 | 
             
                    @p_dev     = "/org/bluez/#{@n_adapter}/#{@n_dev}"
         | 
| 30 30 | 
             
                    @o_dev     = BLUEZ.object(@p_dev)
         | 
| 31 31 | 
             
                    @o_dev.introspect
         | 
| 32 | 
            -
             | 
| 32 | 
            +
             | 
| 33 33 | 
             
                    self.refresh if @auto_refresh
         | 
| 34 | 
            -
             | 
| 34 | 
            +
             | 
| 35 35 | 
             
                    @o_dev[I_PROPERTIES]
         | 
| 36 36 | 
             
                        .on_signal('PropertiesChanged') do |intf, props|
         | 
| 37 37 | 
             
                        case intf
         | 
| @@ -43,7 +43,7 @@ class Device | |
| 43 43 | 
             
                        end
         | 
| 44 44 | 
             
                    end
         | 
| 45 45 | 
             
                end
         | 
| 46 | 
            -
             | 
| 46 | 
            +
             | 
| 47 47 | 
             
                # This removes the remote device object.
         | 
| 48 48 | 
             
                # It will remove also the pairing information.
         | 
| 49 49 | 
             
                # @return [Boolean]
         | 
| @@ -58,8 +58,8 @@ class Device | |
| 58 58 | 
             
                    else raise ScriptError
         | 
| 59 59 | 
             
                    end
         | 
| 60 60 | 
             
                end
         | 
| 61 | 
            -
             | 
| 62 | 
            -
             | 
| 61 | 
            +
             | 
| 62 | 
            +
             | 
| 63 63 | 
             
                # This method will connect to the remote device,
         | 
| 64 64 | 
             
                # initiate pairing and then retrieve all SDP records
         | 
| 65 65 | 
             
                # (or GATT primary services).
         | 
| @@ -71,6 +71,7 @@ class Device | |
| 71 71 | 
             
                # all other cases the default agent will handle this just fine.
         | 
| 72 72 | 
             
                # In case there is no application agent and also
         | 
| 73 73 | 
             
                # no default agent present, this method will fail.
         | 
| 74 | 
            +
                #
         | 
| 74 75 | 
             
                # @return [Boolean]
         | 
| 75 76 | 
             
                def pair
         | 
| 76 77 | 
             
                    @o_dev[I_DEVICE].Pair
         | 
| @@ -88,7 +89,7 @@ class Device | |
| 88 89 | 
             
                    else raise ScriptError
         | 
| 89 90 | 
             
                    end
         | 
| 90 91 | 
             
                end
         | 
| 91 | 
            -
             | 
| 92 | 
            +
             | 
| 92 93 | 
             
                # This method can be used to cancel a pairing
         | 
| 93 94 | 
             
                # operation initiated by the Pair method.
         | 
| 94 95 | 
             
                # @return [Boolean]
         | 
| @@ -102,7 +103,7 @@ class Device | |
| 102 103 | 
             
                    else raise ScriptError
         | 
| 103 104 | 
             
                    end
         | 
| 104 105 | 
             
                end
         | 
| 105 | 
            -
             | 
| 106 | 
            +
             | 
| 106 107 | 
             
                # This connect to the specified profile UUID or to any (:all)
         | 
| 107 108 | 
             
                # profiles the remote device supports that can be connected to
         | 
| 108 109 | 
             
                # and have been flagged as auto-connectable on our side.  If
         | 
| @@ -133,7 +134,7 @@ class Device | |
| 133 134 | 
             
                    else raise ScriptError
         | 
| 134 135 | 
             
                    end
         | 
| 135 136 | 
             
                end
         | 
| 136 | 
            -
             | 
| 137 | 
            +
             | 
| 137 138 | 
             
                # This method gracefully disconnects :all connected profiles
         | 
| 138 139 | 
             
                # and then terminates low-level ACL connection.
         | 
| 139 140 | 
             
                # ACL connection will be terminated even if some profiles
         | 
| @@ -161,7 +162,7 @@ class Device | |
| 161 162 | 
             
                    when E_INVALID_ARGUMENTS
         | 
| 162 163 | 
             
                        raise ArgumentError, "unsupported profile (#{profile})"
         | 
| 163 164 | 
             
                    when E_NOT_SUPPORTED
         | 
| 164 | 
            -
                        raise  | 
| 165 | 
            +
                        raise NotSupported
         | 
| 165 166 | 
             
                    when E_NOT_CONNECTED
         | 
| 166 167 | 
             
                        true
         | 
| 167 168 | 
             
                    when E_UNKNOWN_OBJECT
         | 
| @@ -169,7 +170,7 @@ class Device | |
| 169 170 | 
             
                    else raise ScriptError
         | 
| 170 171 | 
             
                    end
         | 
| 171 172 | 
             
                end
         | 
| 172 | 
            -
             | 
| 173 | 
            +
             | 
| 173 174 | 
             
                # Indicates if the remote device is paired
         | 
| 174 175 | 
             
                def is_paired?
         | 
| 175 176 | 
             
                    @o_dev[I_DEVICE]['Paired']
         | 
| @@ -180,7 +181,7 @@ class Device | |
| 180 181 | 
             
                    else raise ScriptError
         | 
| 181 182 | 
             
                    end
         | 
| 182 183 | 
             
                end
         | 
| 183 | 
            -
             | 
| 184 | 
            +
             | 
| 184 185 | 
             
                # Indicates if the remote device is currently connected.
         | 
| 185 186 | 
             
                def is_connected?
         | 
| 186 187 | 
             
                    @o_dev[I_DEVICE]['Connected']
         | 
| @@ -191,7 +192,7 @@ class Device | |
| 191 192 | 
             
                    else raise ScriptError
         | 
| 192 193 | 
             
                    end
         | 
| 193 194 | 
             
                end
         | 
| 194 | 
            -
             | 
| 195 | 
            +
             | 
| 195 196 | 
             
                # List of available services as UUID.
         | 
| 196 197 | 
             
                #
         | 
| 197 198 | 
             
                # @raise [NotConnected] if device is not in a connected state
         | 
| @@ -201,18 +202,25 @@ class Device | |
| 201 202 | 
             
                # @note This is the list of UUIDs for which we have an entry
         | 
| 202 203 | 
             
                #       in the underlying api (bluez-dbus), which can be less
         | 
| 203 204 | 
             
                #       that the list of advertised UUIDs.
         | 
| 205 | 
            +
                # @example list available services
         | 
| 206 | 
            +
                #   $d.services.each {|uuid|
         | 
| 207 | 
            +
                #     info = BLE::Service[uuid]
         | 
| 208 | 
            +
                #     name = info.nil? ? uuid : info[:name]
         | 
| 209 | 
            +
                #     puts name
         | 
| 210 | 
            +
                #   }
         | 
| 211 | 
            +
                #
         | 
| 204 212 | 
             
                # @return [Array<String>] List of service UUID
         | 
| 205 213 | 
             
                def services
         | 
| 206 214 | 
             
                    raise NotConnected unless is_connected?
         | 
| 207 215 | 
             
                    @services.keys
         | 
| 208 216 | 
             
                end
         | 
| 209 | 
            -
             | 
| 217 | 
            +
             | 
| 210 218 | 
             
                # Check if service is available on the device
         | 
| 211 219 | 
             
                # @return [Boolean]
         | 
| 212 220 | 
             
                def has_service?(service)
         | 
| 213 221 | 
             
                    @service.key?(_uuid_service(service))
         | 
| 214 222 | 
             
                end
         | 
| 215 | 
            -
             | 
| 223 | 
            +
             | 
| 216 224 | 
             
                # List of available characteristics UUID for a service.
         | 
| 217 225 | 
             
                #
         | 
| 218 226 | 
             
                # @param service service can be a UUID, a service type or
         | 
| @@ -229,21 +237,21 @@ class Device | |
| 229 237 | 
             
                        chars.keys
         | 
| 230 238 | 
             
                    end
         | 
| 231 239 | 
             
                end
         | 
| 232 | 
            -
             | 
| 240 | 
            +
             | 
| 233 241 | 
             
                # The Bluetooth device address of the remote device.
         | 
| 234 242 | 
             
                # @return [String] MAC address
         | 
| 235 243 | 
             
                def address
         | 
| 236 244 | 
             
                    @o_dev[I_DEVICE]['Address']
         | 
| 237 245 | 
             
                end
         | 
| 238 | 
            -
             | 
| 246 | 
            +
             | 
| 239 247 | 
             
                # The Bluetooth remote name.
         | 
| 240 248 | 
             
                # It is better to always use the {#alias} when displaying the
         | 
| 241 | 
            -
                # devices name. | 
| 249 | 
            +
                # devices name.
         | 
| 242 250 | 
             
                # @return [String] name
         | 
| 243 251 | 
             
                def name # optional
         | 
| 244 252 | 
             
                    @o_dev[I_DEVICE]['Name']
         | 
| 245 253 | 
             
                end
         | 
| 246 | 
            -
             | 
| 254 | 
            +
             | 
| 247 255 | 
             
                # The name alias for the remote device.
         | 
| 248 256 | 
             
                # The alias can be used to have a different friendly name for the
         | 
| 249 257 | 
             
                # remote device.
         | 
| @@ -259,13 +267,13 @@ class Device | |
| 259 267 | 
             
                def alias=(val)
         | 
| 260 268 | 
             
                    @o_dev[I_DEVICE]['Alias'] = val.nil? ? "" : val.to_str
         | 
| 261 269 | 
             
                end
         | 
| 262 | 
            -
             | 
| 270 | 
            +
             | 
| 263 271 | 
             
                # Is the device trusted?
         | 
| 264 272 | 
             
                # @return [Boolean]
         | 
| 265 273 | 
             
                def is_trusted?
         | 
| 266 274 | 
             
                    @o_dev[I_DEVICE]['Trusted']
         | 
| 267 275 | 
             
                end
         | 
| 268 | 
            -
             | 
| 276 | 
            +
             | 
| 269 277 | 
             
                # Indicates if the remote is seen as trusted. This
         | 
| 270 278 | 
             
                # setting can be changed by the application.
         | 
| 271 279 | 
             
                # @param val [Boolean]
         | 
| @@ -276,13 +284,13 @@ class Device | |
| 276 284 | 
             
                    end
         | 
| 277 285 | 
             
                    @o_dev[I_DEVICE]['Trusted'] = val
         | 
| 278 286 | 
             
                end
         | 
| 279 | 
            -
             | 
| 287 | 
            +
             | 
| 280 288 | 
             
                # Is the device blocked?
         | 
| 281 289 | 
             
                # @return [Boolean]
         | 
| 282 290 | 
             
                def is_blocked?
         | 
| 283 291 | 
             
                    @o_dev[I_DEVICE]['Blocked']
         | 
| 284 292 | 
             
                end
         | 
| 285 | 
            -
             | 
| 293 | 
            +
             | 
| 286 294 | 
             
                # If set to true any incoming connections from the
         | 
| 287 295 | 
             
                # device will be immediately rejected. Any device
         | 
| 288 296 | 
             
                # drivers will also be removed and no new ones will
         | 
| @@ -295,7 +303,7 @@ class Device | |
| 295 303 | 
             
                    end
         | 
| 296 304 | 
             
                    @o_dev[I_DEVICE]['Blocked'] = val
         | 
| 297 305 | 
             
                end
         | 
| 298 | 
            -
             | 
| 306 | 
            +
             | 
| 299 307 | 
             
                # Received Signal Strength Indicator of the remote
         | 
| 300 308 | 
             
                # device (inquiry or advertising).
         | 
| 301 309 | 
             
                # @return [Integer]
         | 
| @@ -307,7 +315,7 @@ class Device | |
| 307 315 | 
             
                    else raise ScriptError
         | 
| 308 316 | 
             
                    end
         | 
| 309 317 | 
             
                end
         | 
| 310 | 
            -
             | 
| 318 | 
            +
             | 
| 311 319 | 
             
                # Advertised transmitted power level (inquiry or advertising).
         | 
| 312 320 | 
             
                # @return [Integer]
         | 
| 313 321 | 
             
                def tx_power # optional
         | 
| @@ -318,8 +326,8 @@ class Device | |
| 318 326 | 
             
                    else raise ScriptError
         | 
| 319 327 | 
             
                    end
         | 
| 320 328 | 
             
                end
         | 
| 321 | 
            -
             | 
| 322 | 
            -
             | 
| 329 | 
            +
             | 
| 330 | 
            +
             | 
| 323 331 | 
             
                # Refresh list of services and characteristics
         | 
| 324 332 | 
             
                # @return [Boolean]
         | 
| 325 333 | 
             
                def refresh
         | 
| @@ -328,7 +336,7 @@ class Device | |
| 328 336 | 
             
                rescue NotConnected, StalledObject
         | 
| 329 337 | 
             
                    false
         | 
| 330 338 | 
             
                end
         | 
| 331 | 
            -
             | 
| 339 | 
            +
             | 
| 332 340 | 
             
                # Refresh list of services and characteristics
         | 
| 333 341 | 
             
                # @raise [NotConnected] if device is not in a connected state
         | 
| 334 342 | 
             
                # @return [self]
         | 
| @@ -363,7 +371,7 @@ class Device | |
| 363 371 | 
             
                            sleep(0.25) ; max_wait -= 0.25 ; retry
         | 
| 364 372 | 
             
                        end
         | 
| 365 373 | 
             
                        raise NotReady
         | 
| 366 | 
            -
             | 
| 374 | 
            +
             | 
| 367 375 | 
             
                    else raise ScriptError
         | 
| 368 376 | 
             
                    end
         | 
| 369 377 | 
             
                end
         | 
| @@ -422,7 +430,7 @@ class Device | |
| 422 430 | 
             
                    flags = char[:flags]
         | 
| 423 431 | 
             
                    obj   = char[:obj]
         | 
| 424 432 | 
             
                    info  = Characteristic[uuid]
         | 
| 425 | 
            -
             | 
| 433 | 
            +
             | 
| 426 434 | 
             
                    if flags.include?('write') ||
         | 
| 427 435 | 
             
                       flags.include?('write-without-response')
         | 
| 428 436 | 
             
                        if !raw && info
         | 
| @@ -442,9 +450,9 @@ class Device | |
| 442 450 | 
             
                    end
         | 
| 443 451 | 
             
                    nil
         | 
| 444 452 | 
             
                end
         | 
| 445 | 
            -
             | 
| 453 | 
            +
             | 
| 446 454 | 
             
                private
         | 
| 447 | 
            -
             | 
| 455 | 
            +
             | 
| 448 456 | 
             
                def _characteristics(service)
         | 
| 449 457 | 
             
                    if srv = @services[_uuid_service(service)]
         | 
| 450 458 | 
             
                        srv[:characteristics]
         | 
| @@ -462,7 +470,7 @@ class Device | |
| 462 470 | 
             
                    if uuid.nil?
         | 
| 463 471 | 
             
                        raise ArgumentError, "unable to get UUID for service"
         | 
| 464 472 | 
             
                    end
         | 
| 465 | 
            -
             | 
| 473 | 
            +
             | 
| 466 474 | 
             
                    uuid
         | 
| 467 475 | 
             
                end
         | 
| 468 476 | 
             
                def _uuid_characteristic(characteristic)
         | 
| @@ -477,7 +485,7 @@ class Device | |
| 477 485 | 
             
                    if uuid.nil?
         | 
| 478 486 | 
             
                        raise ArgumentError, "unable to get UUID for service"
         | 
| 479 487 | 
             
                    end
         | 
| 480 | 
            -
             | 
| 488 | 
            +
             | 
| 481 489 | 
             
                    uuid
         | 
| 482 490 | 
             
                end
         | 
| 483 491 | 
             
            end
         | 
    
        data/lib/ble/service.rb
    CHANGED
    
    | @@ -34,6 +34,7 @@ module Service | |
| 34 34 | 
             
                    when Symbol      then DB_NICKNAME[id]
         | 
| 35 35 | 
             
                    when UUID::REGEX then DB_UUID[id]
         | 
| 36 36 | 
             
                    when String      then DB_TYPE[id]
         | 
| 37 | 
            +
                    when Integer     then DB_UUID[BLE::UUID(id)]
         | 
| 37 38 | 
             
                    else raise ArgumentError, "invalid type for service id"
         | 
| 38 39 | 
             
                    end
         | 
| 39 40 | 
             
                end
         | 
| @@ -79,49 +80,41 @@ module Service | |
| 79 80 | 
             
                #
         | 
| 80 81 | 
             
                # @param uuid [Integer, String] 16-bit, 32-bit or 128-bit uuid
         | 
| 81 82 | 
             
                # @param name [String]
         | 
| 82 | 
            -
                # @ | 
| 83 | 
            +
                # @option opts :type [String] type
         | 
| 84 | 
            +
                # @option opts :nick [Symbol] nickname
         | 
| 83 85 | 
             
                # @return [Hash] service description
         | 
| 84 | 
            -
                def self.add(uuid, name:,  | 
| 86 | 
            +
                def self.add(uuid, name:, **opts)
         | 
| 87 | 
            +
                    uuid = BLE::UUID(uuid)
         | 
| 88 | 
            +
                    type = opts.delete :type
         | 
| 89 | 
            +
                    nick = opts.delete :nick
         | 
| 85 90 | 
             
                    if opts.first 
         | 
| 86 91 | 
             
                        raise ArgumentError, "unknown keyword: #{opts.first[0]}" 
         | 
| 87 92 | 
             
                    end
         | 
| 88 93 |  | 
| 89 | 
            -
                    uuid =  | 
| 90 | 
            -
                           when Integer
         | 
| 91 | 
            -
                               if !(0..4294967296).include?(uuid)
         | 
| 92 | 
            -
                                   raise ArgumentError, "not a 16bit or 32bit uuid"
         | 
| 93 | 
            -
                               end
         | 
| 94 | 
            -
                               ([uuid].pack("L>").unpack('H*').first +
         | 
| 95 | 
            -
                                "-0000-1000-8000-00805F9B34FB")
         | 
| 96 | 
            -
                               
         | 
| 97 | 
            -
                           when String
         | 
| 98 | 
            -
                               if uuid !~ UUID::REGEX
         | 
| 99 | 
            -
                                   raise ArgumentError, "not a 128bit uuid string"
         | 
| 100 | 
            -
                               end
         | 
| 101 | 
            -
                               uuid
         | 
| 102 | 
            -
                           else raise ArgumentError, "invalid uuid type"
         | 
| 103 | 
            -
                           end
         | 
| 104 | 
            -
                    uuid = uuid.downcase
         | 
| 105 | 
            -
                    type = type.downcase
         | 
| 106 | 
            -
                    
         | 
| 107 | 
            -
                    desc = DB_TYPE[type] = DB_UUID[uuid] = {
         | 
| 108 | 
            -
                        name: name,
         | 
| 109 | 
            -
                        type: type,
         | 
| 94 | 
            +
                    desc = DB_UUID[uuid] = {
         | 
| 110 95 | 
             
                        uuid: uuid,
         | 
| 96 | 
            +
                        name: name,
         | 
| 111 97 | 
             
                    }
         | 
| 112 | 
            -
             | 
| 113 | 
            -
                     | 
| 114 | 
            -
                     | 
| 115 | 
            -
             | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 98 | 
            +
             | 
| 99 | 
            +
                    # Add type if specified
         | 
| 100 | 
            +
                    if type
         | 
| 101 | 
            +
                        type = type.downcase
         | 
| 102 | 
            +
                        desc.merge!(type: type)
         | 
| 103 | 
            +
                        DB_TYPE[type] = desc
         | 
| 104 | 
            +
                    end
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                    # Add nickname if specified or can be derived from type
         | 
| 107 | 
            +
                    if nick.nil? && type && type =~ /\.(?<key>[^.]+)$/
         | 
| 108 | 
            +
                        nick = $1.to_sym if type.start_with? 'org.bluetooth.service'
         | 
| 109 | 
            +
                    end
         | 
| 110 | 
            +
                    if nick
         | 
| 111 | 
            +
                        if DB_NICKNAME.include?(nick)
         | 
| 119 112 | 
             
                            raise ArgumentError,
         | 
| 120 | 
            -
                                  "nickname '#{ | 
| 113 | 
            +
                                  "nickname '#{nick}' already registered (uuid: #{uuid})"
         | 
| 121 114 | 
             
                        end
         | 
| 122 | 
            -
                        DB_NICKNAME[ | 
| 115 | 
            +
                        DB_NICKNAME[nick] = desc
         | 
| 123 116 | 
             
                    end
         | 
| 124 | 
            -
             | 
| 117 | 
            +
                    
         | 
| 125 118 | 
             
                    desc
         | 
| 126 119 | 
             
                end
         | 
| 127 120 | 
             
            end
         | 
    
        data/lib/ble/uuid.rb
    ADDED
    
    | @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            module BLE
         | 
| 2 | 
            +
                # Cast value to a well-formatted 128bit UUID string
         | 
| 3 | 
            +
                # @param [String, Integer] val uuid
         | 
| 4 | 
            +
                # @return [String] well formated 128bit UUID
         | 
| 5 | 
            +
                def self.UUID(val)
         | 
| 6 | 
            +
                    case val
         | 
| 7 | 
            +
                    when Integer
         | 
| 8 | 
            +
                        if !(0..4294967295).include?(val)  # 2**32-1
         | 
| 9 | 
            +
                            raise ArgumentError, "not a 16-bit or 32-bit UUID"
         | 
| 10 | 
            +
                        end
         | 
| 11 | 
            +
                        ([val].pack("L>").unpack('H*').first + GATT_BASE_UUID[8..-1])
         | 
| 12 | 
            +
                    when String
         | 
| 13 | 
            +
                        if val !~ UUID::REGEX
         | 
| 14 | 
            +
                            raise ArgumentError, "not a 128bit uuid string"
         | 
| 15 | 
            +
                        end
         | 
| 16 | 
            +
                        val.downcase
         | 
| 17 | 
            +
                    else raise ArgumentError, "invalid uuid type"
         | 
| 18 | 
            +
                    end
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
                
         | 
| 21 | 
            +
                class UUID
         | 
| 22 | 
            +
                    # Regular expression for matching UUID 128-bit string
         | 
| 23 | 
            +
                    REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
            end
         | 
    
        data/lib/ble/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: ble
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0. | 
| 4 | 
            +
              version: 0.0.3
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Stephane D'Alu
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2016-09-05 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: ruby-dbus
         | 
| @@ -94,10 +94,13 @@ files: | |
| 94 94 | 
             
            - lib/ble/adapter.rb
         | 
| 95 95 | 
             
            - lib/ble/agent.rb
         | 
| 96 96 | 
             
            - lib/ble/characteristic.rb
         | 
| 97 | 
            -
            - lib/ble/ | 
| 98 | 
            -
            - lib/ble/ | 
| 97 | 
            +
            - lib/ble/db_eddystone.rb
         | 
| 98 | 
            +
            - lib/ble/db_nordic.rb
         | 
| 99 | 
            +
            - lib/ble/db_sig_characteristic.rb
         | 
| 100 | 
            +
            - lib/ble/db_sig_service.rb
         | 
| 99 101 | 
             
            - lib/ble/device.rb
         | 
| 100 102 | 
             
            - lib/ble/service.rb
         | 
| 103 | 
            +
            - lib/ble/uuid.rb
         | 
| 101 104 | 
             
            - lib/ble/version.rb
         | 
| 102 105 | 
             
            homepage: http://github.com/sdalu/ruby-ble
         | 
| 103 106 | 
             
            licenses:
         | 
| @@ -124,4 +127,3 @@ signing_key: | |
| 124 127 | 
             
            specification_version: 4
         | 
| 125 128 | 
             
            summary: Bluetooth Low Energy (BLE) API
         | 
| 126 129 | 
             
            test_files: []
         | 
| 127 | 
            -
            has_rdoc: yard
         | 
| @@ -1,70 +0,0 @@ | |
| 1 | 
            -
            module BLE
         | 
| 2 | 
            -
            module Characteristic
         | 
| 3 | 
            -
                #   C         | Integer | 8-bit unsigned (unsigned char)
         | 
| 4 | 
            -
                #   S         | Integer | 16-bit unsigned, native endian (uint16_t)
         | 
| 5 | 
            -
                #   L         | Integer | 32-bit unsigned, native endian (uint32_t)
         | 
| 6 | 
            -
                #   Q         | Integer | 64-bit unsigned, native endian (uint64_t)
         | 
| 7 | 
            -
                #             |         |
         | 
| 8 | 
            -
                #   c         | Integer | 8-bit signed (signed char)
         | 
| 9 | 
            -
                #   s         | Integer | 16-bit signed, native endian (int16_t)
         | 
| 10 | 
            -
                #   l         | Integer | 32-bit signed, native endian (int32_t)
         | 
| 11 | 
            -
                #   q         | Integer | 64-bit signed, native endian (int64_t)
         | 
| 12 | 
            -
                #
         | 
| 13 | 
            -
                #   <         | Little endian
         | 
| 14 | 
            -
                #   >         | Big endian
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                
         | 
| 17 | 
            -
                add 0x2A6E,
         | 
| 18 | 
            -
                    name: 'Temperature',
         | 
| 19 | 
            -
                    type: 'org.bluetooth.characteristic.temperature',
         | 
| 20 | 
            -
                    vrfy: ->(x) { (0..100).include?(x) },
         | 
| 21 | 
            -
                      in: ->(s) { s.unpack('s<').first.to_f / 100 },
         | 
| 22 | 
            -
                     out: ->(v) { [ v*100 ].pack('s<') }
         | 
| 23 | 
            -
             | 
| 24 | 
            -
                add 0x2A76,
         | 
| 25 | 
            -
                    name: 'UV Index',
         | 
| 26 | 
            -
                    type: 'org.bluetooth.characteristic.uv_index',
         | 
| 27 | 
            -
                      in: ->(s) { s.unpack('C').first },
         | 
| 28 | 
            -
                     out: ->(v) { [ v ].pack('C') }
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                add 0x2A77,
         | 
| 31 | 
            -
                    name: 'Irradiance',
         | 
| 32 | 
            -
                    type: 'org.bluetooth.characteristic.irradiance',
         | 
| 33 | 
            -
                      in: ->(s) { s.unpack('S<').first.to_f / 10 },
         | 
| 34 | 
            -
                     out: ->(v) { [ v*10 ].pack('S<') }
         | 
| 35 | 
            -
             | 
| 36 | 
            -
                add 0x2A7A,
         | 
| 37 | 
            -
                    name: 'Heat Index',
         | 
| 38 | 
            -
                    type: 'org.bluetooth.characteristic.heat_index',
         | 
| 39 | 
            -
                      in: ->(s) { s.unpack('c').first },
         | 
| 40 | 
            -
                     out: ->(v) { [ v ].pack('c') }
         | 
| 41 | 
            -
             | 
| 42 | 
            -
                add 0x2A19,
         | 
| 43 | 
            -
                    name: 'Battery Level',
         | 
| 44 | 
            -
                    type: 'org.bluetooth.characteristic.battery_level',
         | 
| 45 | 
            -
                    vrfy: ->(x) { (0..100).include?(x) },
         | 
| 46 | 
            -
                      in: ->(s) { s.unpack('C').first },
         | 
| 47 | 
            -
                     out: ->(v) { [ v ].pack('C') }
         | 
| 48 | 
            -
             | 
| 49 | 
            -
                add 0x2A6F,
         | 
| 50 | 
            -
                    name: 'Humidity',
         | 
| 51 | 
            -
                    type: 'org.bluetooth.characteristic.humidity',
         | 
| 52 | 
            -
                    vrfy: ->(x) { (0..100).include?(x) },
         | 
| 53 | 
            -
                      in: ->(s) { s.unpack('S<').first.to_f / 100 },
         | 
| 54 | 
            -
                     out: ->(v) { [ v*100 ].pack('S<') }
         | 
| 55 | 
            -
             | 
| 56 | 
            -
                add 0x2A6D,
         | 
| 57 | 
            -
                    name: 'Pressure',
         | 
| 58 | 
            -
                    type: 'org.bluetooth.characteristic.pressure',
         | 
| 59 | 
            -
                    vrfy: ->(x) { x >= 0 },
         | 
| 60 | 
            -
                      in: ->(s) { s.unpack('L<').first.to_f / 10 },
         | 
| 61 | 
            -
                     out: ->(v) { [ v*10 ].pack('L<') }
         | 
| 62 | 
            -
             | 
| 63 | 
            -
                add 0x2AB3,
         | 
| 64 | 
            -
                    name: 'Altitude',
         | 
| 65 | 
            -
                    type: 'org.bluetooth.characteristic.altitude',
         | 
| 66 | 
            -
                    vrfy: ->(x) { x >= 0 },
         | 
| 67 | 
            -
                      in: ->(s) { s.unpack('S<').first },
         | 
| 68 | 
            -
                     out: ->(v) { [ v ].pack('S<') }
         | 
| 69 | 
            -
            end
         | 
| 70 | 
            -
            end
         |