Class: Msf::Sessions::Modem::Quectel::Connection

Inherits:
Object
  • Object
show all
Defined in:
lib/msf/base/sessions/modem/quectel.rb

Overview

Represents one opened modem socket (SID)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(modem, sock_id) ⇒ Connection

Returns a new instance of Connection.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/msf/base/sessions/modem/quectel.rb', line 40

def initialize(modem, sock_id)
  @modem        = modem
  @sock_id      = sock_id
  @recv_queue   = Queue.new      # payload chunks or nil EOF sentinel
  @prompt_event = Concurrent::Event.new
  @ack_event    = Concurrent::Event.new
  @ack_ok       = false
  @prompt_ok    = true
  @closed_flag  = false
  @close_mutex  = Mutex.new
  @open_event   = Concurrent::Event.new
  @open_ok      = false
  @open_err     = nil
end

Instance Attribute Details

#ack_eventObject (readonly)

Returns the value of attribute ack_event.



37
38
39
# File 'lib/msf/base/sessions/modem/quectel.rb', line 37

def ack_event
  @ack_event
end

#ack_okObject

Returns the value of attribute ack_ok.



38
39
40
# File 'lib/msf/base/sessions/modem/quectel.rb', line 38

def ack_ok
  @ack_ok
end

#closed_flagObject

Returns the value of attribute closed_flag.



38
39
40
# File 'lib/msf/base/sessions/modem/quectel.rb', line 38

def closed_flag
  @closed_flag
end

#open_errObject

Returns the value of attribute open_err.



38
39
40
# File 'lib/msf/base/sessions/modem/quectel.rb', line 38

def open_err
  @open_err
end

#open_eventObject

Returns the value of attribute open_event.



38
39
40
# File 'lib/msf/base/sessions/modem/quectel.rb', line 38

def open_event
  @open_event
end

#open_okObject

Returns the value of attribute open_ok.



38
39
40
# File 'lib/msf/base/sessions/modem/quectel.rb', line 38

def open_ok
  @open_ok
end

#prompt_eventObject (readonly)

Returns the value of attribute prompt_event.



37
38
39
# File 'lib/msf/base/sessions/modem/quectel.rb', line 37

def prompt_event
  @prompt_event
end

#prompt_okObject

Returns the value of attribute prompt_ok.



38
39
40
# File 'lib/msf/base/sessions/modem/quectel.rb', line 38

def prompt_ok
  @prompt_ok
end

#recv_queueObject (readonly)

Returns the value of attribute recv_queue.



37
38
39
# File 'lib/msf/base/sessions/modem/quectel.rb', line 37

def recv_queue
  @recv_queue
end

#sock_idObject (readonly)

Returns the value of attribute sock_id.



37
38
39
# File 'lib/msf/base/sessions/modem/quectel.rb', line 37

def sock_id
  @sock_id
end

Instance Method Details

#closeObject



157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/msf/base/sessions/modem/quectel.rb', line 157

def close
  should_qiclose = transition_closed

  if should_qiclose && !@modem.closed?
    begin
      @modem.send_at("AT+QICLOSE=#{@sock_id},0", @modem.cfg[:cmd_timeout])
    rescue ::StandardError => e
      @modem.log_debug("[SID #{@sock_id}] QICLOSE error: #{e.class} #{e.message}")
    end
  end
  @modem.release_id(@sock_id) if should_qiclose
end

#closed?Boolean

Returns:

  • (Boolean)


149
150
151
# File 'lib/msf/base/sessions/modem/quectel.rb', line 149

def closed?
  @close_mutex.synchronize { @closed_flag }
end

#mark_closedObject



153
154
155
# File 'lib/msf/base/sessions/modem/quectel.rb', line 153

def mark_closed
  @modem.release_id(@sock_id) if transition_closed
end

#push_payload(data) ⇒ Object



143
144
145
146
147
# File 'lib/msf/base/sessions/modem/quectel.rb', line 143

def push_payload(data)
  return if closed?

  @recv_queue << data
end

#recvObject

Blocking recv; returns:

- bytes (String) when payload available
- nil when modem closed socket


135
136
137
138
139
140
141
# File 'lib/msf/base/sessions/modem/quectel.rb', line 135

def recv
  @recv_queue.pop(true)
rescue ::ThreadError
  return nil if closed?

  @recv_queue.pop
end

#send(data) ⇒ Object

Send data over this modem socket via AT+QISEND.

Data is automatically broken into chunks no larger than @modem.cfg (default 1024 B). Quectel modems accept at most 1460 B per AT+QISEND invocation; TLS records can be up to 16 KB so chunking is required for HTTPS / any binary protocol.



61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/msf/base/sessions/modem/quectel.rb', line 61

def send(data)
  raise_closed! if closed?

  chunk_size = [@modem.cfg[:max_chunk_size], 1].max
  offset = 0
  while offset < data.bytesize
    raise_closed! if closed?

    chunk = data.byteslice(offset, chunk_size)
    send_chunk(chunk)
    offset += chunk.bytesize
  end
end