cwmp 0.1.4 → 0.2.0
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 +8 -8
- data/.travis.yml +3 -0
- data/README.md +1 -0
- data/Rakefile +9 -0
- data/bin/acs +1 -1
- data/bin/cpe +1 -1
- data/cwmp.gemspec +2 -1
- data/examples/api_usage.rb +9 -0
- data/lib/cwmp/acs.rb +143 -74
- data/lib/cwmp/cpe.rb +4 -4
- data/lib/cwmp/message.rb +146 -78
- data/lib/cwmp/version.rb +1 -1
- data/test/test_message.rb +19 -0
- data/test/test_parser.rb +115 -0
- metadata +28 -4
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
N2ExN2IwZDNhYzA4ZGQ3YWNlNzU2NzY4YTAxZWU1OTVkYzY3Y2IxYQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YmFlYzhkN2E5MjY4ZmQ0OWQ5N2I0YjMzMTIxYWRjZWZlZjQyYzkwYQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NDA5ZjJmZDkyNDQ2OTMwYWIwODA4M2JmMjljN2MwMzMyZjY0YzVkYTI5NjEx
|
10
|
+
NDM5MmRkMzQ3NTdjNjQwNTU5NWNiM2VlYWUzNDA4ZjMzMzZmMzA3YTAwNjZh
|
11
|
+
OWNjMmEzNGM5M2FlMWQ4YWI4N2JhNDIyNGNmYmQ2ZGNjNjAxMmU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MmU2ZDVhZTI2ZDA4MWFiNTNiNDIwNmU3ZmZlODI4ZmViZjNhYzFjMGNlMWIz
|
14
|
+
NzVlZGFiNjU3YTY3ZDI0M2Q3ZjQxNWRjYmRkYjdmYWI2YTIwNmQzMDMzNTY0
|
15
|
+
N2UwNzA4MmIyNzUzNzhjZGEwN2IwYzk3M2E0YmZlMzNkMGU3ZDE=
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -7,6 +7,7 @@ A ruby library for parsing and crafting CWMP messages. Includes an ACS server an
|
|
7
7
|
```ruby
|
8
8
|
require 'cwmp'
|
9
9
|
|
10
|
+
puts Cwmp::Message::inform "Moonar", "130978", "00001", "1 BOOT", "0.0.1"
|
10
11
|
puts Cwmp::Message::inform_response
|
11
12
|
puts Cwmp::Message::get_parameter_values ["Device.ManagementServer.", "Device.Time."]
|
12
13
|
puts Cwmp::Message::set_parameter_values [["InternetGatewayDevice.Services.VoiceService.1.VoiceProfile.1.Enable", "Enabled"], ["InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.DHCPStaticAddress.1.Enable", "true"]]
|
data/Rakefile
ADDED
data/bin/acs
CHANGED
data/bin/cpe
CHANGED
@@ -11,7 +11,7 @@ o.on('-h', '--help', 'Server port') { puts o; exit }
|
|
11
11
|
o.on('-v', '--version', 'Version') { puts "cpe v#{Cwmp::VERSION}"; exit }
|
12
12
|
o.parse!
|
13
13
|
|
14
|
-
url = options['url'] || 'http://localhost:
|
14
|
+
url = options['url'] || 'http://localhost:9321/acs'
|
15
15
|
periodic_interval = options['periodic'] || 0
|
16
16
|
|
17
17
|
cpe = Cwmp::Cpe.new url, periodic_interval, {:serial => "A54FD"}
|
data/cwmp.gemspec
CHANGED
@@ -18,4 +18,5 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.add_dependency('thin', '~> 1.6', '>= 1.6.2')
|
19
19
|
spec.add_dependency('http_router', '~> 0.11', '>= 0.11.1')
|
20
20
|
spec.add_dependency('httpclient', '~> 2.4', '>= 2.4.0')
|
21
|
-
|
21
|
+
spec.add_dependency('rake', '~> 0.9', '>= 0.9.2')
|
22
|
+
end
|
data/lib/cwmp/acs.rb
CHANGED
@@ -5,17 +5,34 @@ require 'http_router'
|
|
5
5
|
require 'nokogiri'
|
6
6
|
require 'readline'
|
7
7
|
require 'digest'
|
8
|
+
require 'singleton'
|
8
9
|
|
9
10
|
Thread::abort_on_exception = true
|
10
11
|
|
11
12
|
module Cwmp
|
12
13
|
|
14
|
+
class CpeSession
|
15
|
+
def initialize
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Request
|
21
|
+
attr_accessor :message, :cb
|
22
|
+
def initialize message, &block
|
23
|
+
@message = message
|
24
|
+
@cb = block
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
13
28
|
class AcsCpe
|
14
|
-
attr_accessor :serial, :conn_req, :queue, :session_cookie
|
29
|
+
attr_accessor :serial, :conn_req, :queue, :session_cookie, :req_currently_in_service, :session
|
15
30
|
|
16
31
|
def initialize serial
|
17
32
|
@serial = serial
|
18
33
|
@queue = Queue.new
|
34
|
+
@req_currently_in_service = nil
|
35
|
+
@session = nil
|
19
36
|
end
|
20
37
|
|
21
38
|
def do_connection_request
|
@@ -34,70 +51,81 @@ module Cwmp
|
|
34
51
|
req = Rack::Request.new(env)
|
35
52
|
len = req.content_length.to_i
|
36
53
|
|
37
|
-
|
38
|
-
message_type = ''
|
39
|
-
else
|
40
|
-
body = req.body.read
|
41
|
-
doc = Nokogiri::XML(body)
|
42
|
-
body =~ /(\w+):Envelope/
|
43
|
-
soap_ns = $1
|
44
|
-
message_type = doc.css("#{soap_ns}|Body")[0].element_children[0].name
|
45
|
-
end
|
46
|
-
|
47
|
-
if message_type == "Inform"
|
48
|
-
manufacturer = doc.css("Manufacturer").text
|
49
|
-
oui = doc.css("OUI").text
|
50
|
-
serial_number = doc.css("SerialNumber").text
|
51
|
-
event_codes = doc.css("EventCode").map { |n| n.text }
|
52
|
-
parameters = {}
|
53
|
-
doc.css("ParameterValueStruct").map { |it| parameters[it.element_children[0].text] = it.element_children[1].text }
|
54
|
-
|
55
|
-
ck = Digest::MD5.hexdigest("#{serial_number}#{Time.new.to_i}")
|
56
|
-
|
57
|
-
if !@acs.cpes.has_key? serial_number
|
58
|
-
cpe = AcsCpe.new serial_number
|
59
|
-
cpe.conn_req = parameters['InternetGatewayDevice.ManagementServer.ConnectionRequestURL']
|
60
|
-
cpe.session_cookie = ck
|
61
|
-
@acs.cpes[serial_number] = cpe
|
62
|
-
end
|
63
|
-
puts "got Inform from #{req.ip}:#{req.port} [sn #{serial_number}] with eventcodes #{event_codes.join(", ")}"
|
64
|
-
|
65
|
-
inform_response = Cwmp::Message::inform_response
|
66
|
-
response = Rack::Response.new inform_response, 200, {'Connection' => 'Keep-Alive', 'Server' => 'ruby-cwmp'}
|
67
|
-
response.set_cookie("sessiontrack", {:value => ck, :path => "/", :expires => Time.now+24*60*60})
|
68
|
-
response.finish
|
69
|
-
elsif message_type == "TransferComplete"
|
70
|
-
puts "got TransferComplete"
|
71
|
-
else
|
54
|
+
begin
|
72
55
|
if len == 0
|
73
|
-
|
56
|
+
message_type = ''
|
74
57
|
else
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
doc.css("ParameterValueStruct").each do |node|
|
79
|
-
puts "#{node.element_children[0].text}: #{node.element_children[1].text}"
|
80
|
-
end
|
81
|
-
when "Fault"
|
82
|
-
puts "#{doc.css("faultstring").text}: #{doc.css("FaultString").text}"
|
83
|
-
end
|
58
|
+
body = req.body.read
|
59
|
+
mess = Cwmp::Message::parse_from_text body
|
60
|
+
message_type = mess.message_type
|
84
61
|
end
|
85
62
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
63
|
+
if message_type == "Inform"
|
64
|
+
doc = mess.parsed_xml_doc
|
65
|
+
manufacturer = doc.css("Manufacturer").text
|
66
|
+
oui = doc.css("OUI").text
|
67
|
+
serial_number = doc.css("SerialNumber").text
|
68
|
+
event_codes = doc.css("EventCode").map { |n| n.text }
|
69
|
+
parameters = {}
|
70
|
+
doc.css("ParameterValueStruct").map { |it| parameters[it.element_children[0].text] = it.element_children[1].text }
|
71
|
+
|
72
|
+
ck = Digest::MD5.hexdigest("#{serial_number}#{Time.new.to_i}")
|
73
|
+
|
74
|
+
if !@acs.cpes.has_key? serial_number
|
75
|
+
cpe = AcsCpe.new serial_number
|
76
|
+
cpe.conn_req = parameters['InternetGatewayDevice.ManagementServer.ConnectionRequestURL']
|
77
|
+
cpe.session_cookie = ck
|
78
|
+
@acs.cpes[serial_number] = cpe
|
79
|
+
end
|
80
|
+
puts "got Inform from #{req.ip}:#{req.port} [sn #{serial_number}] with eventcodes #{event_codes.join(", ")}"
|
90
81
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
response = Rack::Response.new m, 200, {'Connection' => 'Keep-Alive', 'Server' => 'ruby-cwmp'}
|
82
|
+
inform_response = Cwmp::Message::inform_response
|
83
|
+
response = Rack::Response.new inform_response.xml, 200, {'Connection' => 'Keep-Alive', 'Server' => 'ruby-cwmp'}
|
84
|
+
response.set_cookie("sessiontrack", {:value => ck, :path => "/", :expires => Time.now+24*60*60})
|
95
85
|
response.finish
|
86
|
+
elsif message_type == "TransferComplete"
|
87
|
+
puts "got TransferComplete"
|
96
88
|
else
|
97
|
-
|
98
|
-
|
99
|
-
|
89
|
+
cookie = req.cookies['sessiontrack']
|
90
|
+
@acs.cpes.each do |k,c|
|
91
|
+
cpe = c if c.session_cookie = cookie
|
92
|
+
end
|
100
93
|
|
94
|
+
if len == 0
|
95
|
+
puts "got Empty Post"
|
96
|
+
else
|
97
|
+
puts "got #{message_type}"
|
98
|
+
doc = mess.parsed_xml_doc
|
99
|
+
case message_type
|
100
|
+
when "GetParameterValuesResponse"
|
101
|
+
doc.css("ParameterValueStruct").each do |node|
|
102
|
+
puts "#{node.element_children[0].text}: #{node.element_children[1].text}"
|
103
|
+
end
|
104
|
+
when "Fault"
|
105
|
+
puts "#{doc.css("faultstring").text}: #{doc.css("FaultString").text}"
|
106
|
+
end
|
107
|
+
|
108
|
+
if cpe.req_currently_in_service != nil
|
109
|
+
cpe.req_currently_in_service.cb.call(mess)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
# Got Empty Post or a Response. Now check for any event to send, otherwise 204
|
115
|
+
if cpe.queue.size > 0
|
116
|
+
m = cpe.queue.pop
|
117
|
+
cpe.req_currently_in_service = m
|
118
|
+
response = Rack::Response.new m.message, 200, {'Connection' => 'Keep-Alive', 'Server' => 'ruby-cwmp'}
|
119
|
+
response.finish
|
120
|
+
else
|
121
|
+
puts "sending 204"
|
122
|
+
[204, {"Connection" => "Close", 'Server' => 'ruby-cwmp'}, ""]
|
123
|
+
end
|
124
|
+
end
|
125
|
+
rescue Exception => e
|
126
|
+
puts e
|
127
|
+
puts e.backtrace
|
128
|
+
raise e
|
101
129
|
end
|
102
130
|
end
|
103
131
|
|
@@ -105,11 +133,13 @@ module Cwmp
|
|
105
133
|
|
106
134
|
|
107
135
|
class Acs
|
136
|
+
include Singleton
|
137
|
+
|
108
138
|
attr_accessor :cpes
|
109
139
|
|
110
|
-
def initialize
|
140
|
+
def initialize
|
111
141
|
ac = self
|
112
|
-
|
142
|
+
|
113
143
|
# @handler = Handler.new
|
114
144
|
@app = HttpRouter.new do
|
115
145
|
# add('/api').to(SocketApp.new)
|
@@ -121,7 +151,7 @@ module Cwmp
|
|
121
151
|
def start_cli
|
122
152
|
list = [
|
123
153
|
'GetParameterValues', 'SetParameterValues', 'Reboot', 'FactoryReset', 'Download', 'AddObject', 'DeleteObject',
|
124
|
-
'help', 'quit', "waitMessage"
|
154
|
+
'help', 'list', 'quit', "waitMessage"
|
125
155
|
].sort
|
126
156
|
|
127
157
|
comp = proc { |s| list.grep(/^#{Regexp.escape(s)}/) }
|
@@ -131,35 +161,74 @@ module Cwmp
|
|
131
161
|
|
132
162
|
while line = ::Readline.readline('> ', true)
|
133
163
|
case line
|
134
|
-
when "quit"
|
164
|
+
when "quit", "exit"
|
135
165
|
puts "Bye"
|
136
166
|
exit(0)
|
137
167
|
when "help"
|
138
|
-
help
|
168
|
+
puts "help not available"
|
169
|
+
when "list games"
|
170
|
+
puts ["FALKEN'S MAZE", "BLACK JACK", "GIN RUMMY", "HEARTS", "BRIDGE", "CHECKERS", "CHESS", "POKER", "FIGHTER COMBAT", "GUERRILLA ENGAGEMENT", "DESERT WARFARE" "AIR-TO-GROUND ACTIONS", "THEATERWIDE TACTICAL WARFARE", "THEATERWIDE BIOTOXIC AND CHEMICAL WARFARE", "GLOBAL THERMONUCLEAR WAR"].join "\n"
|
171
|
+
when "help games"
|
172
|
+
puts "Games refers to models, simulations and games which have strategic applications"
|
139
173
|
when "list"
|
140
174
|
p @cpes
|
141
|
-
when
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
175
|
+
when /send (\w+) (\w+) (.+)/
|
176
|
+
message_type = $1
|
177
|
+
serial = $2
|
178
|
+
args = $3.split(" ")
|
179
|
+
|
180
|
+
# allowed_messages = ["GetParameterValues", "GetParameterNames", "SetParameterValues", "AddObject", "DeleteObject", "Reboot", "FactoryReset"]
|
181
|
+
# if !allowed_messages.include? message_type
|
182
|
+
# puts "cmd #{message_type} unknown"
|
183
|
+
# next
|
184
|
+
# end
|
185
|
+
|
186
|
+
cpe = @cpes[serial]
|
187
|
+
if !cpe
|
188
|
+
puts "cpe #{serial} unknown"
|
189
|
+
next
|
190
|
+
end
|
191
|
+
|
192
|
+
mess = Object.const_get("Cwmp").const_get("Message").send(message_type, args)
|
193
|
+
cpe.queue << Cwmp::Request.new(mess) do |resp|
|
194
|
+
puts "arrived #{resp}"
|
195
|
+
end
|
148
196
|
cpe.do_connection_request
|
197
|
+
when "run"
|
198
|
+
begin
|
199
|
+
require './examples/api_usage'
|
200
|
+
rescue LoadError
|
201
|
+
puts "file not found"
|
202
|
+
rescue SyntaxError => e
|
203
|
+
puts "file contains syntax errors: #{e.message}"
|
204
|
+
rescue Exception => e
|
205
|
+
puts "runtime error: #{e.message}"
|
206
|
+
end
|
207
|
+
else
|
208
|
+
puts "unknown command <#{line}>" if line != ""
|
149
209
|
end
|
150
210
|
end
|
151
211
|
end
|
152
212
|
|
153
|
-
def start
|
213
|
+
def start port
|
214
|
+
trap("SIGINT") { puts "Bye"; exit! }
|
215
|
+
@port = port
|
154
216
|
puts "ACS #{Cwmp::VERSION} by Luca Cervasio <luca.cervasio@gmail.com>"
|
155
217
|
puts "Daemon running on http://localhost:#{@port}/acs"
|
156
|
-
|
157
|
-
|
158
|
-
|
218
|
+
|
219
|
+
Thread.new do
|
220
|
+
start_cli
|
159
221
|
end
|
160
222
|
|
161
|
-
|
223
|
+
Thin::Logging.silent = true
|
224
|
+
Rack::Handler::Thin.run @app, :Port => @port
|
225
|
+
|
162
226
|
end
|
227
|
+
|
228
|
+
def start_session(serial, &block)
|
229
|
+
|
230
|
+
end
|
231
|
+
|
163
232
|
end
|
164
233
|
|
165
234
|
end
|
data/lib/cwmp/cpe.rb
CHANGED
@@ -84,7 +84,7 @@ module Cwmp
|
|
84
84
|
c = HTTPClient.new
|
85
85
|
|
86
86
|
puts "sending Inform with event #{event}"
|
87
|
-
resp = c.post @acs_url, Cwmp::Message::inform(@manufacturer, @oui, @serial, event, @software_version), {'User-Agent' => "ruby-cwmp #{Cwmp::VERSION}", "Content-Type" => 'text/xml; charset="utf-8"'}
|
87
|
+
resp = c.post @acs_url, Cwmp::Message::inform(@manufacturer, @oui, @serial, event, @software_version).xml, {'User-Agent' => "ruby-cwmp #{Cwmp::VERSION}", "Content-Type" => 'text/xml; charset="utf-8"'}
|
88
88
|
doc = Nokogiri::XML(resp.body)
|
89
89
|
resp.body =~ /(\w+):Envelope/
|
90
90
|
soap_ns = $1
|
@@ -97,11 +97,11 @@ module Cwmp
|
|
97
97
|
puts "got #{message_type}"
|
98
98
|
case message_type
|
99
99
|
when "GetParameterValues"
|
100
|
-
resp = c.post @acs_url, Cwmp::Message::get_parameter_values_response, {'User-Agent' => "ruby-cwmp #{Cwmp::VERSION}", "Content-Type" => 'text/xml; charset="utf-8"'}
|
100
|
+
resp = c.post @acs_url, (Cwmp::Message::get_parameter_values_response).xml, {'User-Agent' => "ruby-cwmp #{Cwmp::VERSION}", "Content-Type" => 'text/xml; charset="utf-8"'}
|
101
101
|
when "GetParameterNames"
|
102
|
-
resp = c.post @acs_url, Cwmp::Message::get_parameter_names_response, {'User-Agent' => "ruby-cwmp #{Cwmp::VERSION}", "Content-Type" => 'text/xml; charset="utf-8"'}
|
102
|
+
resp = c.post @acs_url, (Cwmp::Message::get_parameter_names_response).xml, {'User-Agent' => "ruby-cwmp #{Cwmp::VERSION}", "Content-Type" => 'text/xml; charset="utf-8"'}
|
103
103
|
when "SetParameterValues"
|
104
|
-
resp = c.post @acs_url, Cwmp::Message::set_parameter_values_response, {'User-Agent' => "ruby-cwmp #{Cwmp::VERSION}", "Content-Type" => 'text/xml; charset="utf-8"'}
|
104
|
+
resp = c.post @acs_url, (Cwmp::Message::set_parameter_values_response).xml, {'User-Agent' => "ruby-cwmp #{Cwmp::VERSION}", "Content-Type" => 'text/xml; charset="utf-8"'}
|
105
105
|
end
|
106
106
|
end
|
107
107
|
puts "got #{resp.status}, closing"
|
data/lib/cwmp/message.rb
CHANGED
@@ -2,10 +2,77 @@ require 'nokogiri'
|
|
2
2
|
|
3
3
|
module Cwmp
|
4
4
|
class Message
|
5
|
+
|
5
6
|
NAMESPACES = {"xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/", "xmlns:soap-enc" => "http://schemas.xmlsoap.org/soap/encoding/", "xmlns:cwmp" => "urn:dslforum-org:cwmp-1-0", "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance", "xml:xsd" => "http://www.w3.org/2001/XMLSchema", "xmlns" => "urn:dslforum-org:cwmp-1-0"}
|
7
|
+
attr_accessor :message_type, :raw_xml_message, :parsed_xml_doc
|
8
|
+
|
9
|
+
def self.parse_from_text txtmsg
|
10
|
+
doc = Nokogiri::XML(txtmsg)
|
11
|
+
txtmsg =~ /(\w+):Envelope/
|
12
|
+
soap_ns = $1
|
13
|
+
message_type = doc.css("#{soap_ns}|Body")[0].element_children[0].name
|
14
|
+
|
15
|
+
m = Cwmp::Message.new
|
16
|
+
m.message_type = message_type
|
17
|
+
m.parsed_xml_doc = doc
|
18
|
+
m.raw_xml_message = txtmsg
|
19
|
+
return m
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def to_s
|
24
|
+
return "CWMP Mess #{@message_type}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def xml
|
28
|
+
return @raw_xml_message
|
29
|
+
end
|
30
|
+
|
31
|
+
def supported_model
|
32
|
+
if @raw_xml_message =~ /InternetGatewayDevice/
|
33
|
+
return 'TR-098'
|
34
|
+
else
|
35
|
+
return 'TR-181'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.reboot
|
40
|
+
m = Cwmp::Message.new
|
41
|
+
m.message_type = "Reboot"
|
42
|
+
b = Nokogiri::XML::Builder.new
|
43
|
+
|
44
|
+
b[:soap].Envelope(NAMESPACES) {
|
45
|
+
b[:soap].Header {}
|
46
|
+
b[:soap].Body {
|
47
|
+
b[:cwmp].Reboot() {}
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
m.raw_xml_message = b.to_xml
|
52
|
+
return m
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.reboot_response
|
56
|
+
m = Cwmp::Message.new
|
57
|
+
m.message_type = "RebootResponse"
|
58
|
+
b = Nokogiri::XML::Builder.new
|
59
|
+
|
60
|
+
b[:soap].Envelope(NAMESPACES) {
|
61
|
+
b[:soap].Header {}
|
62
|
+
b[:soap].Body {
|
63
|
+
b[:cwmp].RebootResponse() {}
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
m.raw_xml_message = b.to_xml
|
68
|
+
return m
|
69
|
+
end
|
6
70
|
|
7
71
|
def self.inform(manufacturer, oui, serial, eventcodes, software_version)
|
8
|
-
|
72
|
+
m = Cwmp::Message.new
|
73
|
+
|
74
|
+
m.message_type = "Inform"
|
75
|
+
m.raw_xml_message = '<?xml version="1.0" encoding="UTF-8"?>
|
9
76
|
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
10
77
|
xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:cwmp="urn:dslforum-org:cwmp-1-0"
|
11
78
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
@@ -61,50 +128,52 @@ module Cwmp
|
|
61
128
|
</cwmp:Inform>
|
62
129
|
</soap:Body>
|
63
130
|
</soap:Envelope>'
|
131
|
+
|
132
|
+
return m
|
64
133
|
end
|
65
134
|
|
66
135
|
def self.inform_response
|
67
|
-
|
68
|
-
|
69
|
-
b[:soap].Envelope(NAMESPACES) {
|
70
|
-
b[:soap].Header {}
|
71
|
-
b[:soap].Body {
|
72
|
-
b[:cwmp].InformResponse() {}
|
73
|
-
}
|
74
|
-
}
|
136
|
+
m = Cwmp::Message.new
|
75
137
|
|
76
|
-
|
77
|
-
end
|
138
|
+
m.message_type = "InformResponse"
|
78
139
|
|
79
|
-
def self.reboot
|
80
140
|
b = Nokogiri::XML::Builder.new
|
81
141
|
|
82
142
|
b[:soap].Envelope(NAMESPACES) {
|
83
143
|
b[:soap].Header {}
|
84
144
|
b[:soap].Body {
|
85
|
-
b[:cwmp].
|
145
|
+
b[:cwmp].InformResponse() {}
|
86
146
|
}
|
87
147
|
}
|
88
148
|
|
89
|
-
|
149
|
+
m.raw_xml_message = b.to_xml
|
150
|
+
|
151
|
+
return m
|
90
152
|
end
|
91
153
|
|
92
|
-
def self.
|
154
|
+
def self.set_parameter_values(leaves)
|
93
155
|
b = Nokogiri::XML::Builder.new
|
94
156
|
|
95
157
|
b[:soap].Envelope(NAMESPACES) {
|
96
158
|
b[:soap].Header {}
|
97
159
|
b[:soap].Body {
|
98
160
|
|
99
|
-
b[:cwmp].
|
100
|
-
b.
|
101
|
-
if leaves.kind_of?(Array)
|
161
|
+
b[:cwmp].SetParameterValues() {
|
162
|
+
b.ParameterList({"soap-enc:arrayType" => "cwmp:ParameterValueStruct[#{leaves[0].kind_of?(Array) ? leaves.size : '1'}]"}) {
|
163
|
+
if leaves[0].kind_of?(Array)
|
102
164
|
leaves.each do |leaf|
|
103
|
-
b.
|
165
|
+
b.ParameterValueStruct {
|
166
|
+
b.Name leaf[0]
|
167
|
+
b.Value leaf[1]
|
168
|
+
}
|
104
169
|
end
|
105
170
|
else
|
106
|
-
b.
|
171
|
+
b.ParameterValueStruct {
|
172
|
+
b.Name leaves[0]
|
173
|
+
b.Value leaves[1]
|
174
|
+
}
|
107
175
|
end
|
176
|
+
b.ParameterKey "asdads"
|
108
177
|
}
|
109
178
|
}
|
110
179
|
}
|
@@ -113,68 +182,22 @@ module Cwmp
|
|
113
182
|
return b.to_xml
|
114
183
|
end
|
115
184
|
|
116
|
-
def self.
|
117
|
-
return '<soap:Envelope
|
118
|
-
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
119
|
-
xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/"
|
120
|
-
xmlns:cwmp="urn:dslforum-org:cwmp-1-0"
|
121
|
-
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
122
|
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
123
|
-
<soap:Header>
|
124
|
-
<cwmp:ID soap:mustUnderstand="1"></cwmp:ID>
|
125
|
-
</soap:Header>
|
126
|
-
<soap:Body>
|
127
|
-
<cwmp:GetParameterValuesResponse>
|
128
|
-
<ParameterList soap-enc:arrayType="cwmp:ParameterValueStruct[5]">
|
129
|
-
<ParameterValueStruct>
|
130
|
-
<Name>InternetGatewayDevice.Time.NTPServer1</Name>
|
131
|
-
<Value xsi:type="xsd:string">pool.ntp.org</Value>
|
132
|
-
</ParameterValueStruct>
|
133
|
-
<ParameterValueStruct>
|
134
|
-
<Name>InternetGatewayDevice.Time.CurrentLocalTime</Name>
|
135
|
-
<Value xsi:type="xsd:dateTime">2014-07-11T09:08:25</Value>
|
136
|
-
</ParameterValueStruct>
|
137
|
-
<ParameterValueStruct>
|
138
|
-
<Name>InternetGatewayDevice.Time.LocalTimeZone</Name>
|
139
|
-
<Value xsi:type="xsd:string">+00:00</Value>
|
140
|
-
</ParameterValueStruct>
|
141
|
-
<ParameterValueStruct>
|
142
|
-
<Name>InternetGatewayDevice.Time.LocalTimeZoneName</Name>
|
143
|
-
<Value xsi:type="xsd:string">Greenwich Mean Time : Dublin</Value>
|
144
|
-
</ParameterValueStruct>
|
145
|
-
<ParameterValueStruct>
|
146
|
-
<Name>InternetGatewayDevice.Time.DaylightSavingsUsed</Name>
|
147
|
-
<Value xsi:type="xsd:boolean">0</Value>
|
148
|
-
</ParameterValueStruct>
|
149
|
-
</ParameterList>
|
150
|
-
</cwmp:GetParameterValuesResponse>
|
151
|
-
</soap:Body>
|
152
|
-
</soap:Envelope>'
|
153
|
-
end
|
154
|
-
|
155
|
-
def self.set_parameter_values (leaves)
|
185
|
+
def self.get_parameter_values(leaves)
|
156
186
|
b = Nokogiri::XML::Builder.new
|
157
187
|
|
158
188
|
b[:soap].Envelope(NAMESPACES) {
|
159
189
|
b[:soap].Header {}
|
160
190
|
b[:soap].Body {
|
161
191
|
|
162
|
-
b[:cwmp].
|
163
|
-
b.
|
164
|
-
if leaves
|
192
|
+
b[:cwmp].GetParameterValues() {
|
193
|
+
b.ParameterNames({"soap-enc:arrayType" => "cwmp:string[#{leaves.kind_of?(Array) ? leaves.size : '1'}]"}) {
|
194
|
+
if leaves.kind_of?(Array)
|
165
195
|
leaves.each do |leaf|
|
166
|
-
b.
|
167
|
-
b.Name leaf[0]
|
168
|
-
b.Value leaf[1]
|
169
|
-
}
|
196
|
+
b.string leaf
|
170
197
|
end
|
171
198
|
else
|
172
|
-
b.
|
173
|
-
b.Name leaves[0]
|
174
|
-
b.Value leaves[1]
|
175
|
-
}
|
199
|
+
b.string leaves
|
176
200
|
end
|
177
|
-
b.ParameterKey "asdads"
|
178
201
|
}
|
179
202
|
}
|
180
203
|
}
|
@@ -183,13 +206,11 @@ module Cwmp
|
|
183
206
|
return b.to_xml
|
184
207
|
end
|
185
208
|
|
186
|
-
|
187
|
-
def self.set_parameter_values_response
|
188
|
-
return ''
|
189
|
-
end
|
190
|
-
|
191
209
|
def self.get_parameter_names_response
|
192
|
-
|
210
|
+
m = Cwmp::Message.new
|
211
|
+
|
212
|
+
m.message_type = "Inform"
|
213
|
+
m.raw_xml_message = '<soap:Envelope
|
193
214
|
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
194
215
|
xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/"
|
195
216
|
xmlns:cwmp="urn:dslforum-org:cwmp-1-0"
|
@@ -273,6 +294,53 @@ module Cwmp
|
|
273
294
|
</cwmp:GetParameterNamesResponse>
|
274
295
|
</soap:Body>
|
275
296
|
</soap:Envelope>'
|
297
|
+
|
298
|
+
return m
|
299
|
+
end
|
300
|
+
|
301
|
+
def self.get_parameter_values_response
|
302
|
+
m = Cwmp::Message.new
|
303
|
+
|
304
|
+
m.message_type = "Inform"
|
305
|
+
m.raw_xml_message = '<soap:Envelope
|
306
|
+
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
307
|
+
xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/"
|
308
|
+
xmlns:cwmp="urn:dslforum-org:cwmp-1-0"
|
309
|
+
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
310
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
311
|
+
<soap:Header>
|
312
|
+
<cwmp:ID soap:mustUnderstand="1"></cwmp:ID>
|
313
|
+
</soap:Header>
|
314
|
+
<soap:Body>
|
315
|
+
<cwmp:GetParameterValuesResponse>
|
316
|
+
<ParameterList soap-enc:arrayType="cwmp:ParameterValueStruct[5]">
|
317
|
+
<ParameterValueStruct>
|
318
|
+
<Name>InternetGatewayDevice.Time.NTPServer1</Name>
|
319
|
+
<Value xsi:type="xsd:string">pool.ntp.org</Value>
|
320
|
+
</ParameterValueStruct>
|
321
|
+
<ParameterValueStruct>
|
322
|
+
<Name>InternetGatewayDevice.Time.CurrentLocalTime</Name>
|
323
|
+
<Value xsi:type="xsd:dateTime">2014-07-11T09:08:25</Value>
|
324
|
+
</ParameterValueStruct>
|
325
|
+
<ParameterValueStruct>
|
326
|
+
<Name>InternetGatewayDevice.Time.LocalTimeZone</Name>
|
327
|
+
<Value xsi:type="xsd:string">+00:00</Value>
|
328
|
+
</ParameterValueStruct>
|
329
|
+
<ParameterValueStruct>
|
330
|
+
<Name>InternetGatewayDevice.Time.LocalTimeZoneName</Name>
|
331
|
+
<Value xsi:type="xsd:string">Greenwich Mean Time : Dublin</Value>
|
332
|
+
</ParameterValueStruct>
|
333
|
+
<ParameterValueStruct>
|
334
|
+
<Name>InternetGatewayDevice.Time.DaylightSavingsUsed</Name>
|
335
|
+
<Value xsi:type="xsd:boolean">0</Value>
|
336
|
+
</ParameterValueStruct>
|
337
|
+
</ParameterList>
|
338
|
+
</cwmp:GetParameterValuesResponse>
|
339
|
+
</soap:Body>
|
340
|
+
</soap:Envelope>'
|
341
|
+
|
342
|
+
return m
|
276
343
|
end
|
344
|
+
|
277
345
|
end
|
278
346
|
end
|
data/lib/cwmp/version.rb
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/cwmp/message.rb'
|
4
|
+
require "test/unit"
|
5
|
+
|
6
|
+
class TestMessage < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def test_inform
|
9
|
+
inform = Cwmp::Message::inform "Moonar", "130978", "00001", "1 BOOT", "0.0.1"
|
10
|
+
assert_equal(inform.class.to_s, "Cwmp::Message")
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_inform_response
|
14
|
+
inform_response = Cwmp::Message::inform_response
|
15
|
+
assert(inform_response.to_s =~ /InformResponse/)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
data/test/test_parser.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "test/unit"
|
4
|
+
|
5
|
+
class TestParser < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def test_parsing_get_parameter_values_response
|
8
|
+
txtmsg = '<soap:Envelope
|
9
|
+
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
10
|
+
xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/"
|
11
|
+
xmlns:cwmp="urn:dslforum-org:cwmp-1-0"
|
12
|
+
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
13
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
14
|
+
<soap:Header>
|
15
|
+
<cwmp:ID soap:mustUnderstand="1"></cwmp:ID>
|
16
|
+
</soap:Header>
|
17
|
+
<soap:Body>
|
18
|
+
<cwmp:GetParameterValuesResponse>
|
19
|
+
<ParameterList soap-enc:arrayType="cwmp:ParameterValueStruct[5]">
|
20
|
+
<ParameterValueStruct>
|
21
|
+
<Name>InternetGatewayDevice.Time.NTPServer1</Name>
|
22
|
+
<Value xsi:type="xsd:string">pool.ntp.org</Value>
|
23
|
+
</ParameterValueStruct>
|
24
|
+
<ParameterValueStruct>
|
25
|
+
<Name>InternetGatewayDevice.Time.CurrentLocalTime</Name>
|
26
|
+
<Value xsi:type="xsd:dateTime">2014-07-11T09:08:25</Value>
|
27
|
+
</ParameterValueStruct>
|
28
|
+
<ParameterValueStruct>
|
29
|
+
<Name>InternetGatewayDevice.Time.LocalTimeZone</Name>
|
30
|
+
<Value xsi:type="xsd:string">+00:00</Value>
|
31
|
+
</ParameterValueStruct>
|
32
|
+
<ParameterValueStruct>
|
33
|
+
<Name>InternetGatewayDevice.Time.LocalTimeZoneName</Name>
|
34
|
+
<Value xsi:type="xsd:string">Greenwich Mean Time : Dublin</Value>
|
35
|
+
</ParameterValueStruct>
|
36
|
+
<ParameterValueStruct>
|
37
|
+
<Name>InternetGatewayDevice.Time.DaylightSavingsUsed</Name>
|
38
|
+
<Value xsi:type="xsd:boolean">0</Value>
|
39
|
+
</ParameterValueStruct>
|
40
|
+
</ParameterList>
|
41
|
+
</cwmp:GetParameterValuesResponse>
|
42
|
+
</soap:Body>
|
43
|
+
</soap:Envelope>'
|
44
|
+
|
45
|
+
msg = Cwmp::Message::parse_from_text(txtmsg)
|
46
|
+
assert_equal(msg.class.to_s, "Cwmp::Message")
|
47
|
+
assert_equal(msg.message_type, "GetParameterValuesResponse")
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_parsing_inform
|
51
|
+
txtmsg = '<?xml version="1.0" encoding="UTF-8"?>
|
52
|
+
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
53
|
+
xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:cwmp="urn:dslforum-org:cwmp-1-0"
|
54
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
55
|
+
<soap:Header/>
|
56
|
+
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
57
|
+
<cwmp:Inform>
|
58
|
+
<DeviceId>
|
59
|
+
<Manufacturer>Moonar</Manufacturer>
|
60
|
+
<OUI>130978</OUI>
|
61
|
+
<ProductClass>Router</ProductClass>
|
62
|
+
<SerialNumber>00001</SerialNumber>
|
63
|
+
</DeviceId>
|
64
|
+
<Event>
|
65
|
+
<EventStruct>
|
66
|
+
<EventCode>1 BOOT</EventCode>
|
67
|
+
<CommandKey/>
|
68
|
+
</EventStruct>
|
69
|
+
</Event>
|
70
|
+
<MaxEnvelopes>1</MaxEnvelopes>
|
71
|
+
<CurrentTime>2003-01-01T05:36:55Z</CurrentTime>
|
72
|
+
<RetryCount>0</RetryCount>
|
73
|
+
<ParameterList soap-enc:arrayType="cwmp:ParameterValueStruct[7]">
|
74
|
+
<ParameterValueStruct xsi:type="cwmp:ParameterValueStruct">
|
75
|
+
<Name>InternetGatewayDevice.DeviceInfo.HardwareVersion</Name>
|
76
|
+
<Value xsi:type="xsd:string">MNR001</Value>
|
77
|
+
</ParameterValueStruct>
|
78
|
+
<ParameterValueStruct xsi:type="cwmp:ParameterValueStruct">
|
79
|
+
<Name>InternetGatewayDevice.DeviceInfo.ProvisioningCode</Name>
|
80
|
+
<Value xsi:type="xsd:string">ABCD</Value>
|
81
|
+
</ParameterValueStruct>
|
82
|
+
<ParameterValueStruct xsi:type="cwmp:ParameterValueStruct">
|
83
|
+
<Name>InternetGatewayDevice.DeviceInfo.SoftwareVersion</Name>
|
84
|
+
<Value xsi:type="xsd:string">0.0.1</Value>
|
85
|
+
</ParameterValueStruct>
|
86
|
+
<ParameterValueStruct xsi:type="cwmp:ParameterValueStruct">
|
87
|
+
<Name>InternetGatewayDevice.DeviceInfo.SpecVersion</Name>
|
88
|
+
<Value xsi:type="xsd:string">1.0</Value>
|
89
|
+
</ParameterValueStruct>
|
90
|
+
<ParameterValueStruct xsi:type="cwmp:ParameterValueStruct">
|
91
|
+
<Name>InternetGatewayDevice.ManagementServer.ConnectionRequestURL</Name>
|
92
|
+
<Value xsi:type="xsd:string">http://127.0.0.1:9600/00001</Value>
|
93
|
+
</ParameterValueStruct>
|
94
|
+
<ParameterValueStruct xsi:type="cwmp:ParameterValueStruct">
|
95
|
+
<Name>InternetGatewayDevice.ManagementServer.ParameterKey</Name>
|
96
|
+
<Value xsi:type="xsd:string"/>
|
97
|
+
</ParameterValueStruct>
|
98
|
+
<ParameterValueStruct xsi:type="cwmp:ParameterValueStruct">
|
99
|
+
<Name>InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.ExternalIPAddress
|
100
|
+
</Name>
|
101
|
+
<Value xsi:type="xsd:string">10.19.0.00001</Value>
|
102
|
+
</ParameterValueStruct>
|
103
|
+
</ParameterList>
|
104
|
+
</cwmp:Inform>
|
105
|
+
</soap:Body>
|
106
|
+
</soap:Envelope>'
|
107
|
+
|
108
|
+
msg = Cwmp::Message::parse_from_text(txtmsg)
|
109
|
+
assert_equal(msg.class.to_s, "Cwmp::Message")
|
110
|
+
assert_equal(msg.message_type, "Inform")
|
111
|
+
assert_equal(msg.supported_model, "TR-098")
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cwmp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luca Cervasio
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -110,6 +110,26 @@ dependencies:
|
|
110
110
|
- - ! '>='
|
111
111
|
- !ruby/object:Gem::Version
|
112
112
|
version: 2.4.0
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: rake
|
115
|
+
requirement: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ~>
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0.9'
|
120
|
+
- - ! '>='
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 0.9.2
|
123
|
+
type: :runtime
|
124
|
+
prerelease: false
|
125
|
+
version_requirements: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - ~>
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0.9'
|
130
|
+
- - ! '>='
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: 0.9.2
|
113
133
|
description: A ruby library for parsing and crafting CWMP messages. Includes an ACS
|
114
134
|
server and a CPE simulator.
|
115
135
|
email: luca.cervasio@gmail.com
|
@@ -120,17 +140,22 @@ extensions: []
|
|
120
140
|
extra_rdoc_files: []
|
121
141
|
files:
|
122
142
|
- .gitignore
|
143
|
+
- .travis.yml
|
123
144
|
- Gemfile
|
124
145
|
- LICENSE
|
125
146
|
- README.md
|
147
|
+
- Rakefile
|
126
148
|
- bin/acs
|
127
149
|
- bin/cpe
|
128
150
|
- cwmp.gemspec
|
151
|
+
- examples/api_usage.rb
|
129
152
|
- lib/cwmp.rb
|
130
153
|
- lib/cwmp/acs.rb
|
131
154
|
- lib/cwmp/cpe.rb
|
132
155
|
- lib/cwmp/message.rb
|
133
156
|
- lib/cwmp/version.rb
|
157
|
+
- test/test_message.rb
|
158
|
+
- test/test_parser.rb
|
134
159
|
homepage: https://github.com/lucacervasio/ruby-cwmp
|
135
160
|
licenses:
|
136
161
|
- MIT
|
@@ -151,9 +176,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
151
176
|
version: '0'
|
152
177
|
requirements: []
|
153
178
|
rubyforge_project:
|
154
|
-
rubygems_version: 2.
|
179
|
+
rubygems_version: 2.4.6
|
155
180
|
signing_key:
|
156
181
|
specification_version: 4
|
157
182
|
summary: A CWMP library
|
158
183
|
test_files: []
|
159
|
-
has_rdoc:
|