def refresh!
      _require_connection!
      max_wait ||= 1.5 # Use ||= due to the retry
      @services = Hash[@o_dev.subnodes.map {|p_srv|
          p_srv = [@o_dev.path, p_srv].join '/'
          o_srv = BLUEZ.object(p_srv)
          o_srv.introspect
          srv   = o_srv.GetAll(I_GATT_SERVICE).first
          char  = Hash[o_srv.subnodes.map {|char|
              p_char = [o_srv.path, char].join '/'
              o_char = BLUEZ.object(p_char)
              o_char.introspect
              uuid  = o_char[I_GATT_CHARACTERISTIC]['UUID' ].downcase
              flags = o_char[I_GATT_CHARACTERISTIC]['Flags']
              [ uuid, Characteristic.new({ :uuid => uuid, :flags => flags, :obj => o_char }) ]
            }]
          uuid = srv['UUID'].downcase
          [ uuid, { :uuid            => uuid,
              :primary         => srv['Primary'],
              :characteristics => char } ]
        }]
      self
    rescue DBus::Error => e
      case e.name
      when E_UNKNOWN_OBJECT
        raise StalledObject
      when E_INVALID_ARGS
        # That's probably because all the bluez information
        # haven't been collected yet on dbus for GattServices
        if max_wait > 0
          sleep(0.25) ; max_wait -= 0.25 ; retry
        end
        raise NotReady

      else raise ScriptError
      end
    end
def refresh!
      _require_connection!
      max_wait ||= 1.5 # Use ||= due to the retry
      @services = Hash[@o_dev.subnodes.map {|p_srv|
          p_srv = [@o_dev.path, p_srv].join '/'
          o_srv = BLUEZ.object(p_srv)
          o_srv.introspect
          srv   = o_srv.GetAll(I_GATT_SERVICE).first
          char  = Hash[o_srv.subnodes.map {|char|
              p_char = [o_srv.path, char].join '/'
              o_char = BLUEZ.object(p_char)
              o_char.introspect
              uuid  = o_char[I_GATT_CHARACTERISTIC]['UUID' ].downcase
              flags = o_char[I_GATT_CHARACTERISTIC]['Flags']
              [ uuid, Characteristic.new({ :uuid => uuid, :flags => flags, :obj => o_char }) ]
            }]
          uuid = srv['UUID'].downcase
          [ uuid, { :uuid            => uuid,
              :primary         => srv['Primary'],
              :characteristics => char } ]
        }]
      self
    rescue DBus::Error => e
      case e.name
      when E_UNKNOWN_OBJECT
        raise StalledObject
      when E_INVALID_ARGS
        # That's probably because all the bluez information
        # haven't been collected yet on dbus for GattServices
        if max_wait > 0
          sleep(0.25) ; max_wait -= 0.25 ; retry
        end
        raise NotReady

      else raise ScriptError
      end
    end
Refresh list of services and characteristics
 @raise [NotConnected] if device is not in a connected state
 @return [self]