Class: WifiWand::BaseModel

Inherits:
Object
  • Object
show all
Extended by:
OptionsNormalization
Includes:
OptionsNormalization, StringPredicates, Timing
Defined in:
lib/wifi_wand/models/base_model.rb

Defined Under Namespace

Modules: OptionsNormalization Classes: Options

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Timing

monotonic_now, status_deadline, status_timeout_for

Methods included from StringPredicates

string_nil_or_blank?, string_nil_or_empty?

Constructor Details

#initialize(options = {}) ⇒ BaseModel

Returns a new instance of BaseModel.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/wifi_wand/models/base_model.rb', line 69

def initialize(options = {})
  verify_subclass_contract

  options = normalize_options(options)
  @options = options
  # JRuby may bundle keyword-style arguments into a single positional Hash
  # when the caller itself accepts a positional options Hash. Build an
  # explicit Hash and splat it so keyword arguments are reliably delivered
  # to RuntimeConfig#initialize on all supported Ruby implementations.
  runtime_config_options = {
    verbose:    options[:verbose],
    utc:        options[:utc] || false,
    out_stream: options[:out_stream] || $stdout,
    err_stream: options[:err_stream] || $stderr,
  }
  @runtime_config = RuntimeConfig.new(**runtime_config_options)
  @command_executor = CommandExecutor.new(runtime_config: @runtime_config)
  @connectivity_tester = NetworkConnectivityTester.new(runtime_config: @runtime_config)
  @state_manager = NetworkStateManager.new(self, runtime_config: @runtime_config)
  @status_waiter = StatusWaiter.new(self, runtime_config: @runtime_config)
  @connection_manager = ConnectionManager.new(self, runtime_config: @runtime_config)
  @disconnect_manager = DisconnectManager.new(self, runtime_config: @runtime_config)
end

Instance Attribute Details

#command_executorObject

Returns the value of attribute command_executor.



49
50
51
# File 'lib/wifi_wand/models/base_model.rb', line 49

def command_executor
  @command_executor
end

#connection_managerObject

Returns the value of attribute connection_manager.



49
50
51
# File 'lib/wifi_wand/models/base_model.rb', line 49

def connection_manager
  @connection_manager
end

#connectivity_testerObject

Returns the value of attribute connectivity_tester.



49
50
51
# File 'lib/wifi_wand/models/base_model.rb', line 49

def connectivity_tester
  @connectivity_tester
end

#disconnect_managerObject

Returns the value of attribute disconnect_manager.



49
50
51
# File 'lib/wifi_wand/models/base_model.rb', line 49

def disconnect_manager
  @disconnect_manager
end

#runtime_configObject (readonly)

Returns the value of attribute runtime_config.



48
49
50
# File 'lib/wifi_wand/models/base_model.rb', line 48

def runtime_config
  @runtime_config
end

#state_managerObject

Returns the value of attribute state_manager.



49
50
51
# File 'lib/wifi_wand/models/base_model.rb', line 49

def state_manager
  @state_manager
end

#status_waiterObject

Returns the value of attribute status_waiter.



49
50
51
# File 'lib/wifi_wand/models/base_model.rb', line 49

def status_waiter
  @status_waiter
end

#wifi_interfaceObject

Returns the WiFi interface, initializing it lazily when needed.



148
149
150
151
# File 'lib/wifi_wand/models/base_model.rb', line 148

def wifi_interface
  init_wifi_interface if @wifi_interface.nil?
  @wifi_interface
end

Class Method Details

.create_model(options = {}) ⇒ Object



52
53
54
55
56
57
58
# File 'lib/wifi_wand/models/base_model.rb', line 52

def self.create_model(options = {})
  normalized_options = normalize_options(options)
  instance = new(normalized_options)
  # Eagerly validate an explicitly-specified interface; defer discovery otherwise.
  instance.init if normalized_options.wifi_interface
  instance
end

.current_os_matches_this_model?Boolean

Returns:

  • (Boolean)


60
61
62
# File 'lib/wifi_wand/models/base_model.rb', line 60

def self.current_os_matches_this_model?
  WifiWand::Platforms::Selector.current_os&.id == os_id
end

.inherited(subclass) ⇒ Object



64
65
66
67
# File 'lib/wifi_wand/models/base_model.rb', line 64

def self.inherited(subclass)
  super
  WifiWand::ModelSubclassContract.validate_subclass!(subclass)
end

Instance Method Details

#associated?Boolean

Returns true when WiFi is on and the interface is associated with an SSID. Returns false when WiFi is off or there is no active SSID association.

Returns:

  • (Boolean)


244
245
246
247
248
249
# File 'lib/wifi_wand/models/base_model.rb', line 244

def associated?
  name = connected_network_name
  !name.nil? && !name.empty?
rescue WifiWand::Error
  false
end

#available_network_namesObject

Raises:



199
200
201
202
203
# File 'lib/wifi_wand/models/base_model.rb', line 199

def available_network_names
  raise WifiOffError, 'WiFi is off, cannot scan for available networks.' unless wifi_on?

  _available_network_names
end

#available_network_scanObject

Raises:



205
206
207
208
209
# File 'lib/wifi_wand/models/base_model.rb', line 205

def available_network_scan
  raise WifiOffError, 'WiFi is off, cannot scan for available networks.' unless wifi_on?

  wifi_info_builder.successful_available_network_scan(_available_network_names)
end

#available_resources_helpObject



462
# File 'lib/wifi_wand/models/base_model.rb', line 462

def available_resources_help = resource_manager.available_resources_help

#bssidObject



165
# File 'lib/wifi_wand/models/base_model.rb', line 165

def bssid = raise_override_not_implemented_error(__method__)

#captive_portal_login_required(timeout_in_secs: nil) ⇒ Object

Returns whether captive portal login appears to be required now: :yes, :no, or :unknown.



327
328
329
330
# File 'lib/wifi_wand/models/base_model.rb', line 327

def (timeout_in_secs: nil)
  debug_method_entry(__method__)
  @connectivity_tester.(timeout_in_secs: timeout_in_secs)
end

#capture_network_stateObject

Network State Management for Testing These methods help capture and restore network state during disruptive tests



470
471
472
473
474
# File 'lib/wifi_wand/models/base_model.rb', line 470

def capture_network_state
  debug_method_entry(__method__)

  @state_manager.capture_network_state
end

#command_available?(command) ⇒ Boolean

Returns whether an operating system command is available on PATH.

Helper objects that coordinate model behavior use this as part of the model API instead of reaching into the command executor directly.

Returns:

  • (Boolean)


493
# File 'lib/wifi_wand/models/base_model.rb', line 493

def command_available?(command) = @command_executor.command_available?(command)

#connect(network_name, password = nil, skip_saved_password_lookup: false) ⇒ Object

Connects to the passed network name, optionally with password. Delegates to ConnectionManager for complex connection logic.



376
377
378
379
380
# File 'lib/wifi_wand/models/base_model.rb', line 376

def connect(network_name, password = nil, skip_saved_password_lookup: false)
  debug_method_entry(__method__, binding, %i[network_name password])
  @connection_manager.connect(network_name, password,
    skip_saved_password_lookup: skip_saved_password_lookup)
end

#connected?Boolean

Returns:

  • (Boolean)


163
# File 'lib/wifi_wand/models/base_model.rb', line 163

def connected? = raise_override_not_implemented_error(__method__)

#connected_network_nameObject

Raises:



211
212
213
214
215
# File 'lib/wifi_wand/models/base_model.rb', line 211

def connected_network_name
  raise WifiOffError, 'WiFi is off, cannot determine connected network.' unless wifi_on?

  _connected_network_name
end

#connection_ready?(network_name) ⇒ Boolean

Returns:

  • (Boolean)


268
269
270
271
272
273
274
275
# File 'lib/wifi_wand/models/base_model.rb', line 268

def connection_ready?(network_name)
  connected? && connected_network_name == network_name
rescue WifiWand::MacOsRedactionError
  raise
rescue WifiWand::Error => e
  err_stream.puts("connection_ready? check failed: #{e.class}: #{e.message}") if verbose?
  false
end

#connection_security_typeObject



169
# File 'lib/wifi_wand/models/base_model.rb', line 169

def connection_security_type = raise_override_not_implemented_error(__method__)

#cycle_networkObject

Toggles WiFi on/off state twice; if on, turns off then on; else, turn on then off.



347
348
349
350
351
352
353
354
355
356
# File 'lib/wifi_wand/models/base_model.rb', line 347

def cycle_network
  debug_method_entry(__method__)
  if wifi_on?
    wifi_off
    wifi_on
  else
    wifi_on
    wifi_off
  end
end

#default_interfaceObject



171
# File 'lib/wifi_wand/models/base_model.rb', line 171

def default_interface = raise_override_not_implemented_error(__method__)

#disassociated_stable?Boolean

Returns:

  • (Boolean)


260
261
262
# File 'lib/wifi_wand/models/base_model.rb', line 260

def disassociated_stable?
  @disconnect_manager.disassociated_stable?
end

#disconnectObject



251
252
253
254
# File 'lib/wifi_wand/models/base_model.rb', line 251

def disconnect
  debug_method_entry(__method__)
  @disconnect_manager.disconnect
end

#disconnect_associated?Boolean

Returns:

  • (Boolean)


264
265
266
# File 'lib/wifi_wand/models/base_model.rb', line 264

def disconnect_associated?
  connected?
end

#disconnect_stability_window_in_secsObject



256
257
258
# File 'lib/wifi_wand/models/base_model.rb', line 256

def disconnect_stability_window_in_secs
  @disconnect_manager.disconnect_stability_window_in_secs
end

#dns_working?(timeout_in_secs: nil, return_details: false) ⇒ Boolean

Tests DNS resolution capability

Returns:

  • (Boolean)


318
319
320
321
322
323
324
# File 'lib/wifi_wand/models/base_model.rb', line 318

def dns_working?(timeout_in_secs: nil, return_details: false)
  debug_method_entry(__method__)
  @connectivity_tester.dns_working?(
    timeout_in_secs: timeout_in_secs || TimingConstants::OVERALL_CONNECTIVITY_TIMEOUT,
    return_details:  return_details
  )
end

#err_streamObject



99
# File 'lib/wifi_wand/models/base_model.rb', line 99

def err_stream = runtime_config.err_stream

#err_stream=(stream) ⇒ Object



101
102
103
# File 'lib/wifi_wand/models/base_model.rb', line 101

def err_stream=(stream)
  runtime_config.err_stream = stream
end

#generate_qr_code(filespec = nil, overwrite: false, password: nil, in_stream: $stdin) ⇒ String

Generates a QR code for the currently connected WiFi network.

Parameters:

  • filespec (String, nil) (defaults to: nil)

    Output path, or nil for the default generated PNG filename.

Returns:

  • (String)

    The filename for file output.

Raises:

  • (WifiWand::Error)

    If not connected to a network or qrencode is not available



499
500
501
502
503
504
# File 'lib/wifi_wand/models/base_model.rb', line 499

def generate_qr_code(filespec = nil, overwrite: false, password: nil, in_stream: $stdin)
  debug_method_entry(__method__)
  qr_code_generator.generate(
    self, filespec, overwrite: overwrite, password: password, in_stream: in_stream
  )
end

#has_preferred_network?(network_name) ⇒ Boolean

Returns true if the given network name exists in the preferred networks list. Extracted for easier testing and overriding/mocking.

Returns:

  • (Boolean)


414
# File 'lib/wifi_wand/models/base_model.rb', line 414

def has_preferred_network?(network_name) = preferred_networks.include?(network_name.to_s)

#initObject



120
121
122
123
# File 'lib/wifi_wand/models/base_model.rb', line 120

def init
  init_wifi_interface
  self
end

#init_wifi_interfaceObject



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/wifi_wand/models/base_model.rb', line 125

def init_wifi_interface
  validate_os_preconditions

  # Initialize WiFi interface (e.g.: "wlp0s20f3")
  if @options.wifi_interface
    if is_wifi_interface?(@options.wifi_interface)
      @wifi_interface = @options.wifi_interface
    else
      raise InvalidInterfaceError, @options.wifi_interface
    end
  else
    @wifi_interface = probe_wifi_interface
  end

  # Validate that WiFi interface is a valid string
  if string_nil_or_empty?(@wifi_interface)
    raise WifiInterfaceError
  end

  self
end

#internet_connectivity_state(tcp_working = nil, dns_working = nil, captive_portal_login_required = NetworkConnectivityTester::UNSET, timeout_in_secs: nil) ⇒ Object

Returns an explicit internet connectivity state: :reachable, :unreachable, or :indeterminate.



297
298
299
300
301
302
303
304
305
306
# File 'lib/wifi_wand/models/base_model.rb', line 297

def internet_connectivity_state(tcp_working = nil, dns_working = nil,
   = NetworkConnectivityTester::UNSET, timeout_in_secs: nil)
  debug_method_entry(__method__)
  @connectivity_tester.internet_connectivity_state(
    tcp_working,
    dns_working,
    ,
    timeout_in_secs: timeout_in_secs
  )
end

#internet_tcp_connectivity?(timeout_in_secs: nil, return_details: false) ⇒ Boolean

Tests TCP connectivity to internet hosts (not localhost)

Returns:

  • (Boolean)


309
310
311
312
313
314
315
# File 'lib/wifi_wand/models/base_model.rb', line 309

def internet_tcp_connectivity?(timeout_in_secs: nil, return_details: false)
  debug_method_entry(__method__)
  @connectivity_tester.tcp_connectivity?(
    timeout_in_secs: timeout_in_secs || TimingConstants::OVERALL_CONNECTIVITY_TIMEOUT,
    return_details:  return_details
  )
end

#ipv4_addressesObject

Raises:



277
278
279
280
281
# File 'lib/wifi_wand/models/base_model.rb', line 277

def ipv4_addresses
  raise Error, 'Cannot get IPv4 addresses: not connected to a network.' unless connected?

  _ipv4_addresses
end

#ipv6_addressesObject

Raises:



283
284
285
286
287
# File 'lib/wifi_wand/models/base_model.rb', line 283

def ipv6_addresses
  raise Error, 'Cannot get IPv6 addresses: not connected to a network.' unless connected?

  _ipv6_addresses
end

#is_wifi_interface?(_interface_name) ⇒ Boolean

Returns:

  • (Boolean)


173
# File 'lib/wifi_wand/models/base_model.rb', line 173

def is_wifi_interface?(_interface_name) = raise_override_not_implemented_error(__method__)

#last_connection_used_saved_password?Boolean

Returns true if the last completed connection used a saved password. Failed or no-op connect() calls return false.

Returns:

  • (Boolean)


483
484
485
486
487
# File 'lib/wifi_wand/models/base_model.rb', line 483

def last_connection_used_saved_password?
  debug_method_entry(__method__)

  @connection_manager.last_connection_used_saved_password?
end

#mac?Boolean

Convenience OS predicates

Returns:

  • (Boolean)


116
# File 'lib/wifi_wand/models/base_model.rb', line 116

def mac? = os == :mac

#mac_addressObject



175
# File 'lib/wifi_wand/models/base_model.rb', line 175

def mac_address = raise_override_not_implemented_error(__method__)

#nameserversObject



177
# File 'lib/wifi_wand/models/base_model.rb', line 177

def nameservers = raise_override_not_implemented_error(__method__)

#network_hidden?Boolean

Returns:

  • (Boolean)


179
# File 'lib/wifi_wand/models/base_model.rb', line 179

def network_hidden? = raise_override_not_implemented_error(__method__)

#open_resource(_resource) ⇒ Object



181
# File 'lib/wifi_wand/models/base_model.rb', line 181

def open_resource(_resource) = raise_override_not_implemented_error(__method__)

#open_resources_by_codes(*resource_codes) ⇒ Object



458
459
460
# File 'lib/wifi_wand/models/base_model.rb', line 458

def open_resources_by_codes(*resource_codes)
  resource_manager.open_resources_by_codes(self, *resource_codes)
end

#osObject

Returns a symbol identifying the operating system for this model Examples: :mac, :ubuntu



113
# File 'lib/wifi_wand/models/base_model.rb', line 113

def os = self.class.os_id

#out_streamObject



93
# File 'lib/wifi_wand/models/base_model.rb', line 93

def out_stream = runtime_config.out_stream

#out_stream=(stream) ⇒ Object



95
96
97
# File 'lib/wifi_wand/models/base_model.rb', line 95

def out_stream=(stream)
  runtime_config.out_stream = stream
end

#preferred_network_password(preferred_network_name, timeout_in_secs: :default) ⇒ Object



398
399
400
401
402
403
404
405
406
407
408
409
410
# File 'lib/wifi_wand/models/base_model.rb', line 398

def preferred_network_password(preferred_network_name, timeout_in_secs: :default)
  debug_method_entry(__method__, binding, :preferred_network_name)
  preferred_network_name = preferred_network_name.to_s
  if has_preferred_network?(preferred_network_name)
    if timeout_in_secs == :default
      _preferred_network_password(preferred_network_name)
    else
      _preferred_network_password(preferred_network_name, timeout_in_secs: timeout_in_secs)
    end
  else
    raise PreferredNetworkNotFoundError, preferred_network_name
  end
end

#preferred_networksObject



185
# File 'lib/wifi_wand/models/base_model.rb', line 185

def preferred_networks = raise_override_not_implemented_error(__method__)

Prints an ANSI QR code for the currently connected WiFi network.

Returns:

  • (nil)

Raises:

  • (WifiWand::Error)

    If not connected to a network or qrencode is not available



518
519
520
521
522
# File 'lib/wifi_wand/models/base_model.rb', line 518

def print_qr_code(password: nil)
  debug_method_entry(__method__)
  out_stream.print(qr_code_generator.render(self, format: :ansi, password: password))
  nil
end

#probe_wifi_interfaceObject



183
# File 'lib/wifi_wand/models/base_model.rb', line 183

def probe_wifi_interface = raise_override_not_implemented_error(__method__)

#public_ip_addressObject



441
# File 'lib/wifi_wand/models/base_model.rb', line 441

def public_ip_address = public_ip_lookup.address

#public_ip_countryObject



443
# File 'lib/wifi_wand/models/base_model.rb', line 443

def public_ip_country = public_ip_lookup.country

#public_ip_infoObject



439
# File 'lib/wifi_wand/models/base_model.rb', line 439

def public_ip_info = public_ip_lookup.info

#public_ip_lookupObject



437
# File 'lib/wifi_wand/models/base_model.rb', line 437

def public_ip_lookup = @public_ip_lookup ||= PublicIpLookup.new

#qr_code_generatorObject

QR code generator helper



465
# File 'lib/wifi_wand/models/base_model.rb', line 465

def qr_code_generator = @qr_code_generator ||= Models::Helpers::QrCodeGenerator.new

#random_mac_addressObject



445
446
447
448
449
450
451
452
453
# File 'lib/wifi_wand/models/base_model.rb', line 445

def random_mac_address
  bytes = Array.new(6) { rand(256) }
  # Ensure first byte is locally administered unicast:
  # - Clear multicast bit (bit 0) with mask 0xFE
  # - Set locally administered bit (bit 1) with OR 0x02
  bytes[0] = (bytes[0] & 0xFE) | 0x02
  chars = bytes.map { |b| format('%02x', b) }
  chars.join(':')
end

#remove_preferred_network(_network_name) ⇒ Object



187
# File 'lib/wifi_wand/models/base_model.rb', line 187

def remove_preferred_network(_network_name) = raise_override_not_implemented_error(__method__)

#remove_preferred_networks(*network_names) ⇒ Object

Removes the specified network(s) from the preferred network list.

Parameters:

  • network_names

    names of networks to remove; may be empty or contain nonexistent networks can be a single arg which is an array of names or 1 name string per arg

Returns:

  • names of the networks that were removed (excludes non-preexisting networks)



386
387
388
389
390
391
392
393
394
395
396
# File 'lib/wifi_wand/models/base_model.rb', line 386

def remove_preferred_networks(*network_names)
  network_names = network_names.first if network_names.first.is_a?(Array) && network_names.size == 1
  network_names = network_names.map(&:to_s)

  network_names.select { |name| has_preferred_network?(name) }
    .flat_map do |name|
      removed_names = Array(remove_preferred_network(name))
      removed_names.empty? ? [name] : removed_names
    end
    .uniq
end

#render_qr_code(format: :ansi, password: nil) ⇒ String

Renders a QR code for the currently connected WiFi network without writing or printing it.

Parameters:

  • format (Symbol) (defaults to: :ansi)

    Output format to render. Supports :ansi, :png, :svg, and :eps.

Returns:

  • (String)

    Rendered QR output.

Raises:

  • (WifiWand::Error)

    If not connected to a network or qrencode is not available



510
511
512
513
# File 'lib/wifi_wand/models/base_model.rb', line 510

def render_qr_code(format: :ansi, password: nil)
  debug_method_entry(__method__)
  qr_code_generator.render(self, format: format, password: password)
end

#resource_managerObject

Resource management functionality



456
# File 'lib/wifi_wand/models/base_model.rb', line 456

def resource_manager = @resource_manager ||= Models::Helpers::ResourceManager.new

#restore_network_state(state, fail_silently: false) ⇒ Object



476
477
478
479
# File 'lib/wifi_wand/models/base_model.rb', line 476

def restore_network_state(state, fail_silently: false)
  debug_method_entry(__method__, binding, %i[state fail_silently])
  @state_manager.restore_network_state(state, fail_silently: fail_silently)
end

#run_command(command, raise_on_error: true, timeout_in_secs: nil, log_stdout: true, binary_stdout: false) ⇒ Object



289
290
291
292
293
# File 'lib/wifi_wand/models/base_model.rb', line 289

def run_command(command, raise_on_error: true, timeout_in_secs: nil, log_stdout: true,
  binary_stdout: false)
  @command_executor.run_command_using_args(command, raise_on_error: raise_on_error,
    timeout_in_secs: timeout_in_secs, log_stdout: log_stdout, binary_stdout: binary_stdout)
end

#set_nameservers(_nameservers) ⇒ Object

rubocop:disable Naming/AccessorMethodName



189
# File 'lib/wifi_wand/models/base_model.rb', line 189

def set_nameservers(_nameservers) = raise_override_not_implemented_error(__method__) # rubocop:disable Naming/AccessorMethodName

#signal_qualityObject



167
# File 'lib/wifi_wand/models/base_model.rb', line 167

def signal_quality = raise_override_not_implemented_error(__method__)

#status_line_data(progress_callback: nil) ⇒ Object

Builds a hash for the status command, yielding partial results as soon as they're known so callers can stream updates. Network identity and internet checks run concurrently in native threads so blocking OS commands and socket work can overlap. Internet status uses the full connectivity path so captive portals are reported as unreachable. The returned hash includes :internet_state and :captive_portal_login_required (:yes/:no/:unknown).



365
366
367
368
369
370
371
372
# File 'lib/wifi_wand/models/base_model.rb', line 365

def status_line_data(progress_callback: nil)
  StatusLineDataBuilder.call(
    self,
    progress_callback:       progress_callback,
    runtime_config:          runtime_config,
    expected_network_errors: NetworkErrorConstants::EXPECTED_NETWORK_ERRORS
  )
end

#status_network_identity(timeout_in_secs: nil) ⇒ Object



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/wifi_wand/models/base_model.rb', line 226

def status_network_identity(timeout_in_secs: nil)
  if timeout_in_secs
    raise MethodNotImplementedError,
      'Subclasses must implement bounded status_network_identity(timeout_in_secs:)'
  end

  connected = connected?
  network_name = connected ? connected_network_name : nil

  {
    connected:      connected,
    network_name:   network_name,
    signal_quality: connected ? signal_quality : nil,
  }
end

#status_wifi_on?(timeout_in_secs: nil) ⇒ Boolean

Returns:

  • (Boolean)


217
218
219
220
221
222
223
224
# File 'lib/wifi_wand/models/base_model.rb', line 217

def status_wifi_on?(timeout_in_secs: nil)
  if timeout_in_secs
    raise MethodNotImplementedError,
      'Subclasses must implement bounded status_wifi_on?(timeout_in_secs:)'
  end

  wifi_on?
end

#till(target_status, timeout_in_secs: nil, wait_interval_in_secs: nil, stringify_permitted_values_in_error_msg: false) ⇒ Object

Waits for the WiFi/Internet state to reach target_status.

Parameters:

  • target_status

    one of StatusWaiter::PERMITTED_STATES: :wifi_on / :wifi_off – WiFi hardware power state :associated / :disassociated – WiFi SSID association state :internet_on / :internet_off – full Internet reachability (TCP + DNS + no captive-portal login)

  • timeout_in_secs (defaults to: nil)

    after this many seconds the method will raise a WaitTimeoutError; if nil (default), waits indefinitely

  • wait_interval_in_secs (defaults to: nil)

    sleeps this interval between retries; if nil or absent, a default will be provided



425
426
427
428
429
430
431
432
433
434
435
# File 'lib/wifi_wand/models/base_model.rb', line 425

def till(target_status, timeout_in_secs: nil, wait_interval_in_secs: nil,
  stringify_permitted_values_in_error_msg: false)
  debug_method_entry(__method__, binding, %i[target_status timeout_in_secs wait_interval_in_secs])

  @status_waiter.wait_for(
    target_status,
    timeout_in_secs:                         timeout_in_secs,
    wait_interval_in_secs:                   wait_interval_in_secs,
    stringify_permitted_values_in_error_msg: stringify_permitted_values_in_error_msg
  )
end

#ubuntu?Boolean

Returns:

  • (Boolean)


118
# File 'lib/wifi_wand/models/base_model.rb', line 118

def ubuntu? = os == :ubuntu

#validate_os_preconditionsObject



191
# File 'lib/wifi_wand/models/base_model.rb', line 191

def validate_os_preconditions = raise_override_not_implemented_error(__method__)

#verbose=(value) ⇒ Object



107
108
109
# File 'lib/wifi_wand/models/base_model.rb', line 107

def verbose=(value)
  runtime_config.verbose = !!value
end

#verbose?Boolean

Returns:

  • (Boolean)


105
# File 'lib/wifi_wand/models/base_model.rb', line 105

def verbose? = runtime_config.verbose

#wifi_infoObject

Returns comprehensive WiFi information including connectivity details



333
334
335
336
# File 'lib/wifi_wand/models/base_model.rb', line 333

def wifi_info
  debug_method_entry(__method__)
  wifi_info_builder.build
end

#wifi_info_builderObject



338
339
340
341
342
343
344
# File 'lib/wifi_wand/models/base_model.rb', line 338

def wifi_info_builder
  @wifi_info_builder ||= WifiInfoBuilder.new(
    self, runtime_config: @runtime_config,
    expected_network_errors: NetworkErrorConstants::EXPECTED_NETWORK_ERRORS,
    network_operation_command_errors: NetworkErrorConstants::NETWORK_OPERATION_COMMAND_ERRORS
  )
end

#wifi_offObject



193
# File 'lib/wifi_wand/models/base_model.rb', line 193

def wifi_off = raise_override_not_implemented_error(__method__)

#wifi_onObject



195
# File 'lib/wifi_wand/models/base_model.rb', line 195

def wifi_on = raise_override_not_implemented_error(__method__)

#wifi_on?Boolean

Returns:

  • (Boolean)


197
# File 'lib/wifi_wand/models/base_model.rb', line 197

def wifi_on? = raise_override_not_implemented_error(__method__)