Class: Opensips::MI::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/opensips/mi/command.rb

Overview

core class to send command to MI and return responses

Constant Summary collapse

EVENTNOTIFY =
{
  # Aastra
  aastra_check_cfg: "check-sync",
  aastra_xml: "aastra-xml",
  # Digium
  digium_check_cfg: "check-sync",
  # Linksys
  linksys_cold_restart: "reboot_now",
  linksys_warm_restart: "restart_now",
  # Polycom
  polycom_check_cfg: "check-sync",
  # Sipura
  sipura_check_cfg: "resync",
  sipura_get_report: "report",
  # Snom
  snom_check_cfg: "check-sync;reboot=false",
  snom_reboot: "check-sync;reboot=true",
  # Cisco
  cisco_check_cfg: "check-sync",
  # Avaya
  avaya_check_cfg: "check-sync"
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(transp) ⇒ Command

Returns a new instance of Command.



33
34
35
# File 'lib/opensips/mi/command.rb', line 33

def initialize(transp)
  @transp = transp
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(cmd, *args) ⇒ Object

meta methods call directly



48
49
50
# File 'lib/opensips/mi/command.rb', line 48

def method_missing(cmd, *args)
  command(cmd.to_s, *args)
end

Instance Attribute Details

#transpObject (readonly)

Returns the value of attribute transp.



8
9
10
# File 'lib/opensips/mi/command.rb', line 8

def transp
  @transp
end

Instance Method Details

#command(*params) ⇒ Object

prepare args, pipe them to send to MI using transport and finally format response

Raises:



39
40
41
42
43
44
45
# File 'lib/opensips/mi/command.rb', line 39

def command(*params)
  raise ErrorParams, "command missing method name" if params.empty?

  transp.adapter_request(*params)
        .then { |args| transp.send(*args) }
        .then { |resp| transp.adapter_response(resp) }
end

#event_notify(uri, event, hdrs = {}) ⇒ Object

NOTIFY check-sync like event

NOTIFY Events to restart phone, force configuration reload or report for some SIP IP phone models. The events list was taken from Asterisk configuration file (sip_notify.conf) Note that SIP IP phones usually should be configured to accept special notify event to reboot. For example, Polycom configuration option to enable special event would be:

voIpProt.SIP.specialEvent.checkSync.alwaysReboot="1"

This function will generate To/From/Event headers. Will use random tag for From header. NOTE: This function will not generate To header tag. This is not complying with SIP protocol specification (rfc3265). NOTIFY must be part of a subscription dialog. However, it works for the most of the SIP IP phone models.

Parameters

- uri:    Valid client contact URI (sip:[email protected]:5060).
          To get client URI use *ul_show_contact => contact* function
- event:  One of the events from EVENTNOTIFY constant hash
- hf:     Header fields. Add To/From header fields here if you do not want them
          to be auto-generated. Header field example:
          hf['To'] => '<sip:[email protected]>'


127
128
129
130
131
132
133
134
# File 'lib/opensips/mi/command.rb', line 127

def event_notify(uri, event, hdrs = {})
  hnames = hdrs.keys.map { |k| k.to_s.downcase } || []
  hdrs["To"] = "<#{uri}>" unless hnames.include?("to")
  hdrs["From"] = "<#{uri}>;tag=#{rand(1 << 32)}" unless hnames.include?("from")
  hdrs["Event"] = EVENTNOTIFY[event] || event.to_s

  uac_dlg "NOTIFY", uri, hdrs
end

#mwi_update(uri, vmaccount, newmsgs, old = 0, urg_new = 0, urg_old = 0) ⇒ Object

Presence MWI

Send message-summary NOTIFY Event to update phone voicemail status.

Parameters

- uri:      Request URI (sip:[email protected]:5060)
            To get client URI use *ul_show_contact => contact* function
- vmaccount:Message Account value. Ex.: sip:*[email protected]
- new:      Number of new messages. If more than 0 then Messages-Waiting header
            will be "yes". Set to 0 to clear phone MWI
- old:      (optional) Old messages
- urg_new:  (optional) New urgent messages
- urg_old:  (optional) Old urgent messages


148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/opensips/mi/command.rb', line 148

def mwi_update(uri, vmaccount, newmsgs, old = 0, urg_new = 0, urg_old = 0)
  hbody = { "Messages-Waiting" => (newmsgs.positive? ? "yes" : "no"),
            "Message-Account" => vmaccount,
            "Voice-Message" => "#{newmsgs}/#{old} (#{urg_new}/#{urg_old})" }
  hdrs = { "To" => "<#{uri}>",
           "From" => "<#{uri}>;tag=#{rand(1 << 32)}",
           "Event" => "message-summary",
           "Subscription-State" => "active",
           "Content-Type" => "application/simple-message-summary" }

  body = hbody.map { |k, v| "#{k}: #{v}" }.join("\r\n") << "\r\n\r\n"
  uac_dlg "NOTIFY", uri, hdrs, nil, nil, body
end

#respond_to_missing?(_name, _include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


52
# File 'lib/opensips/mi/command.rb', line 52

def respond_to_missing?(_name, _include_private = false) = true

#uac_dlg(method, ruri, hdrs, next_hop = nil, socket = nil, body = nil) ⇒ Object

Interface to t_uac_dlg function of transaction (tm) module

Very cool method from OpenSIPs. Can generate and send SIP request method to destination. Example of usage:

- Send NOTIFY with special Event header to force restart SIP phone
  (equivalent of ASterisk's "sip notify peer")
- Send PUBLISH to trigger device state change notification
- Send REFER to transfer call
- etc., etc., etc.

Headers

Headers parameter “hf” is a hash of headers of format:

header-name => header-value

Example:

hf["From"] => "Alice Liddell <sip:[email protected]>;tag=843887163"

Thus, using multiple headers with same header-name is not possible with header hash. However, it is possible to use multiple header-values comma separated (rfc3261, section 7.3.1):

hf["Route"] => "<sip:[email protected]>, <sip:[email protected]>"

Is equivalent to:

Route: <sip:[email protected]>
Route: <sip:[email protected]>

If there is headers To and From not found, then exception ArgumentError is raised. Also if body part present, Content-Type and Content-length are also mandatory and exception is raised.

Parameters

method:     SIP request method (NOTIFY, PUBLISH etc)
ruri:       Request URI, ex.: sip:[email protected]:5060
hf:         Headers array. Additional headers will be added to request.
            At least "From" and "To" headers must be specify
nhop:       Next hop SIP URI (OBP); use "." if no value.
socket:     Local socket to be used for sending the request; use "." if no value.
            Ex.: udp:10.130.8.21:5060
body:       (optional, may not be present) request body (if present, requires the "Content-Type"
            and "Content-length" headers)


89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/opensips/mi/command.rb', line 89

def uac_dlg(method, ruri, hdrs, next_hop = nil, socket = nil, body = nil)
  validate_hf(hdrs)

  headers = hdrs.map { |name, val| "#{name}: #{val}" }.join("\r\n")
  headers << "\r\n\r\n"

  params = {
    "method" => method,
    "ruri" => ruri,
    "headers" => headers
  }
  params["next_hop"] = next_hop if next_hop
  params["socket"] = socket if socket
  params["body"] = body if body
  command "t_uac_dlg", params
end