2 * ============LICENSE_START========================================================================
\r
3 * ONAP : tr-069-adapter
\r
4 * =================================================================================================
\r
5 * Copyright (C) 2020 CommScope Inc Intellectual Property.
\r
6 * =================================================================================================
\r
7 * This tr-069-adapter software file is distributed by CommScope Inc under the Apache License,
\r
8 * Version 2.0 (the "License"); you may not use this file except in compliance with the License. You
\r
9 * may obtain a copy of the License at
\r
11 * http://www.apache.org/licenses/LICENSE-2.0
\r
13 * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
\r
14 * either express or implied. See the License for the specific language governing permissions and
\r
15 * limitations under the License.
\r
16 * ===============LICENSE_END=======================================================================
\r
20 package org.commscope.tr069adapter.acs.cpe;
\r
22 import java.io.IOException;
\r
23 import java.io.OutputStream;
\r
24 import java.io.Serializable;
\r
25 import java.util.HashMap;
\r
26 import java.util.Iterator;
\r
27 import java.util.Random;
\r
29 import javax.xml.soap.MessageFactory;
\r
30 import javax.xml.soap.Name;
\r
31 import javax.xml.soap.Node;
\r
32 import javax.xml.soap.SOAPBody;
\r
33 import javax.xml.soap.SOAPBodyElement;
\r
34 import javax.xml.soap.SOAPElement;
\r
35 import javax.xml.soap.SOAPEnvelope;
\r
36 import javax.xml.soap.SOAPException;
\r
37 import javax.xml.soap.SOAPFactory;
\r
38 import javax.xml.soap.SOAPHeader;
\r
39 import javax.xml.soap.SOAPHeaderElement;
\r
40 import javax.xml.soap.SOAPMessage;
\r
41 import javax.xml.soap.SOAPPart;
\r
43 import org.commscope.tr069adapter.acs.cpe.rpc.Fault;
\r
44 import org.slf4j.Logger;
\r
45 import org.slf4j.LoggerFactory;
\r
47 public abstract class TR069RPC implements Serializable {
\r
49 private static final String HTTP_SCHEMA_ENCODING = "http://schemas.xmlsoap.org/soap/encoding/";
\r
51 private static final long serialVersionUID = 7270475819053880884L;
\r
53 protected static final Logger logger = LoggerFactory.getLogger(TR069RPC.class);
\r
55 private Random mrandom = new Random();
\r
57 /** Creates a new instance of Message */
\r
58 public TR069RPC() {}
\r
60 public static final String ENVELOPE_NAMESPACE = "http://schemas.xmlsoap.org/soap/envelope/";
\r
62 protected abstract void createBody(SOAPBodyElement body, SOAPFactory spf) throws SOAPException;
\r
64 protected abstract void parseBody(SOAPBodyElement body, SOAPFactory f) throws SOAPException;
\r
66 protected class ArrayType {
\r
68 public ArrayType() {
\r
72 private String type;
\r
74 public String getType() {
\r
78 public Name getType(SOAPBodyElement body, SOAPFactory spf) throws SOAPException {
\r
79 int i = type.indexOf(':');
\r
81 return spf.createName(type);
\r
83 String prefix = type.substring(0, i);
\r
84 SOAPBody b = (SOAPBody) body.getParentElement();
\r
85 SOAPEnvelope e = (SOAPEnvelope) b.getParentElement();
\r
86 SOAPHeader h = e.getHeader();
\r
89 uri = h.lookupNamespaceURI(prefix);
\r
90 } catch (Exception ee) {
\r
91 logger.error("While geting namespace URI 1 {}", ee.toString());
\r
95 uri = e.lookupNamespaceURI(prefix);
\r
96 } catch (Exception ee) {
\r
97 logger.error("While geting namespace URI 2 {}", ee.toString());
\r
102 uri = b.lookupNamespaceURI(prefix);
\r
103 } catch (Exception ee) {
\r
104 logger.error("While geting namespace URI {} ", ee.toString());
\r
107 return spf.createName(type.substring(i + 1), prefix, uri);
\r
111 public void setType(String type) {
\r
116 public static SOAPBodyElement getRequest(SOAPMessage msg) throws SOAPException {
\r
117 SOAPBodyElement request = null;
\r
118 Iterator<Node> i1 = msg.getSOAPBody().getChildElements();
\r
119 while (i1.hasNext()) {
\r
120 Node n = i1.next();
\r
121 if (n.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
\r
122 request = (SOAPBodyElement) n;
\r
128 private static String getRequestName(SOAPMessage msg) throws SOAPException {
\r
129 if (msg.getSOAPBody().hasFault()) {
\r
133 SOAPBodyElement element = getRequest(msg);
\r
134 if (element != null) {
\r
135 name = element.getNodeName();
\r
137 if (name.startsWith("cwmp:")) {
\r
138 name = name.substring(5);
\r
139 } else if (name.startsWith("cwmp_x:")) {
\r
140 name = name.substring(7);
\r
141 } else if (name.indexOf(':') != -1) {
\r
142 name = name.substring(name.indexOf(':') + 1, name.length());
\r
147 public static TR069RPC parse(SOAPMessage soapMsg)
\r
148 throws SOAPException, InstantiationException, IllegalAccessException, ClassNotFoundException {
\r
149 String reqname = TR069RPC.getRequestName(soapMsg);
\r
151 TR069RPC msg = null;
\r
153 msg = (TR069RPC) Class.forName("org.commscope.tr069adapter.acs.cpe.rpc." + reqname)
\r
155 } catch (Exception e) {
\r
156 msg = (TR069RPC) Class.forName("org.commscope.tr069adapter.acs.cpe.rpc." + reqname)
\r
159 msg = msg.parseSoapMessage(soapMsg);
\r
163 @SuppressWarnings("unchecked")
\r
164 private TR069RPC parseSoapMessage(SOAPMessage soapMsg) throws SOAPException {
\r
165 SOAPEnvelope env = soapMsg.getSOAPPart().getEnvelope();
\r
167 Iterator<String> pfxs = env.getNamespacePrefixes();
\r
168 while (pfxs.hasNext()) {
\r
169 String pfx = pfxs.next();
\r
170 String uri = env.getNamespaceURI(pfx);
\r
171 if (uri.startsWith("urn:dslforum-org:cwmp-")) {
\r
175 SOAPFactory spf = SOAPFactory.newInstance();
\r
176 SOAPBodyElement soaprequest = getRequest(soapMsg);
\r
177 SOAPHeader hdr = soapMsg.getSOAPHeader();
\r
178 id = "device_did_not_send_id"; // or make it null?...
\r
181 id = getHeaderElement(spf, hdr, "ID");
\r
182 } catch (Exception e) {
\r
183 logger.error("While parsing the soap message {}", e.toString());
\r
186 name = getRequestName(soapMsg);
\r
187 if (soaprequest != null) {
\r
188 Fault fault = parseSOAPRequest(soaprequest, spf);
\r
195 private Fault parseSOAPRequest(SOAPBodyElement soaprequest, SOAPFactory spf)
\r
196 throws SOAPException {
\r
197 if (soaprequest != null) {
\r
199 parseBody(soaprequest, spf);
\r
200 } catch (Exception e) {
\r
201 SOAPElement se = getRequestChildElement(spf, soaprequest, FAULT_CODE);
\r
202 String fc = (se != null) ? se.getValue() : "0";
\r
203 SOAPElement se2 = getRequestChildElement(spf, soaprequest, FAULT_STRING);
\r
204 String fs = (se2 != null) ? se2.getValue() : "0";
\r
206 if (se != null || se2 != null) {
\r
207 return new Fault(fc, fs, id);
\r
215 public void writeTo(OutputStream out) {
\r
217 SOAPFactory spf = SOAPFactory.newInstance();
\r
218 MessageFactory factory = MessageFactory.newInstance();
\r
219 SOAPMessage soapMsg = factory.createMessage();
\r
220 SOAPPart part = soapMsg.getSOAPPart();
\r
222 SOAPEnvelope envelope = part.getEnvelope();
\r
223 SOAPHeader header = envelope.getHeader();
\r
224 SOAPBody body = envelope.getBody();
\r
226 String responseId = getId();
\r
228 envelope.addNamespaceDeclaration("xsd", "http://www.w3.org/2001/XMLSchema");
\r
229 envelope.addNamespaceDeclaration("cwmp", urnCWMP);
\r
230 envelope.addNamespaceDeclaration("SOAP-ENC", HTTP_SCHEMA_ENCODING);
\r
231 envelope.addNamespaceDeclaration("SOAP-ENV", ENVELOPE_NAMESPACE);
\r
232 envelope.addNamespaceDeclaration("xsi", "http://www.w3.org/2001/XMLSchema-instance");
\r
234 SOAPElement element = header.addChildElement(spf.createName("ID", "cwmp", urnCWMP));
\r
235 element.addAttribute(spf.createName("mustUnderstand", "SOAP-ENV", ENVELOPE_NAMESPACE),
\r
237 element.addTextNode("1");
\r
239 body.setEncodingStyle(HTTP_SCHEMA_ENCODING);
\r
240 SOAPBodyElement bd = body.addBodyElement(spf.createName(name, CWMP, urnCWMP));
\r
242 if (name == null || name.equals("")) {
\r
243 name = this.getClass().getSimpleName();
\r
245 createBody(bd, spf, id);
\r
247 soapMsg.writeTo(out);
\r
248 } catch (SOAPException ex) {
\r
249 logger.error("Exception occurred while constructing SOAP message: {}", ex.getMessage());
\r
250 } catch (IOException e) {
\r
251 logger.error("Exception occurred while constructing SOAP message: {}", e.getMessage());
\r
255 protected void createBody(SOAPBodyElement body, SOAPFactory spf, String key)
\r
256 throws SOAPException {
\r
257 logger.debug("Key element is: {}", key);
\r
258 createBody(body, spf);
\r
261 protected SOAPElement getRequestChildElement(SOAPFactory f, SOAPElement req, String name) {
\r
262 @SuppressWarnings("unchecked")
\r
263 Iterator<Object> i = req.getChildElements();
\r
265 while (i.hasNext()) {
\r
266 Object o = i.next();
\r
268 Node nn = (Node) o;
\r
269 String n = nn.getLocalName();
\r
270 if (n != null && n.equals(name)) {
\r
271 return (SOAPElement) o;
\r
273 } catch (Exception e) {
\r
274 logger.debug("Exception: {}, {}", e.getMessage(), e.getClass().getName());
\r
280 protected SOAPElement getRequestChildElement2(SOAPFactory f, SOAPElement req, String name)
\r
281 throws SOAPException {
\r
282 return (SOAPElement) req.getChildElements(f.createName(name, CWMP, urnCWMP)).next();
\r
285 protected String getRequestElement(SOAPFactory f, SOAPElement req, String name) {
\r
286 return getRequestChildElement(f, req, name).getValue();
\r
289 protected String getRequestElement(SOAPFactory f, SOAPElement req, String name, String def) {
\r
290 String v = getRequestChildElement(f, req, name).getValue();
\r
291 return (v != null) ? v : def;
\r
294 protected SOAPElement getRequestChildElement(SOAPElement req, Name name) {
\r
295 return (SOAPElement) req.getChildElements(name).next();
\r
298 protected String getRequestElement(SOAPElement req, Name name) {
\r
299 return getRequestChildElement(req, name).getValue();
\r
302 protected String getHeaderElement(SOAPFactory f, SOAPHeader hdr, String name)
\r
303 throws SOAPException {
\r
304 return ((SOAPHeaderElement) hdr.getChildElements(f.createName(name, CWMP, urnCWMP)).next())
\r
308 protected HashMap<String, String> parseParamList(SOAPElement body, SOAPFactory spf)
\r
309 throws SOAPException {
\r
310 return parseParamList(body, spf, "ParameterValueStruct", "Value");
\r
313 protected HashMap<String, String> parseParamList(SOAPElement body, SOAPFactory spf, String sn,
\r
314 String vn) throws SOAPException {
\r
315 Iterator<SOAPElement> pi =
\r
316 getRequestChildElement(spf, body, "ParameterList").getChildElements(spf.createName(sn));
\r
317 Name nameKey = spf.createName("Name");
\r
318 Name nameValue = spf.createName(vn);
\r
319 HashMap<String, String> pl = new HashMap<>();
\r
320 while (pi.hasNext()) {
\r
321 SOAPElement param = pi.next();
\r
322 String key = getRequestElement(param, nameKey);
\r
323 String value = getRequestElement(param, nameValue);
\r
324 if (value == null) {
\r
327 pl.put(key, value);
\r
332 protected int getArrayCount(SOAPFactory spf, SOAPElement e) throws SOAPException {
\r
333 return getArrayCount(spf, e, null);
\r
336 protected int getArrayCount(SOAPFactory spf, SOAPElement e, ArrayType type) throws SOAPException {
\r
337 Name nameArray = spf.createName("arrayType", "soap-enc", HTTP_SCHEMA_ENCODING);
\r
338 String attr = e.getAttributeValue(nameArray);
\r
339 if (attr == null) {
\r
342 attr = attr.replace(" ", "");
\r
343 int i = attr.indexOf('[');
\r
344 String c = attr.substring(i + 1, attr.length() - 1);
\r
345 if (type != null) {
\r
346 type.setType(attr.substring(0, i));
\r
348 return Integer.parseInt(c);
\r
351 public boolean isFault() {
\r
352 return name.equals("Fault");
\r
355 protected String b2s(boolean b) {
\r
356 return (b) ? "1" : "0";
\r
359 protected String name;
\r
361 public String getName() {
\r
365 protected String id;
\r
367 public String getId() {
\r
369 id = "" + mrandom.nextInt(99999);
\r
374 protected void println(StringBuilder b, String n, String v) {
\r
381 protected void println(StringBuilder b, String n, String n2, String v) {
\r
386 public String getCWMPVersion() {
\r
390 public void setCWMPVersion(String cwmpVersion) {
\r
391 urnCWMP = cwmpVersion;
\r
394 protected String urnCWMP = "urn:dslforum-org:cwmp-1-0";
\r
395 protected static final String CWMP = "cwmp";
\r
396 protected static final String PARAMETER_KEY = "ParameterKey";
\r
397 protected static final String COMMAND_KEY = "CommandKey";
\r
398 protected static final String XSI_TYPE = "xsi:type";
\r
399 protected static final String XSD_STRING = "xsd:string";
\r
400 protected static final String XSD_UNSIGNEDINT = "xsd:unsignedInt";
\r
401 protected static final String XSD_INT = "xsd:int";
\r
402 protected static final String XSD_BOOLEAN = "xsd:boolean";
\r
403 protected static final String XSD_DATETIME = "xsd:dateTime";
\r
404 protected static final String XSD_BASE64 = "xsd:base64";
\r
405 protected static final String SOAP_ARRAY_TYPE = "SOAP-ENC:arrayType";
\r
406 public static final String FAULT_CODE = "FaultCode";
\r
407 public static final String FAULT_STRING = "FaultString";
\r
408 public static final String TYPE_OBJECT = "object";
\r
409 public static final String TYPE_STRING = "string";
\r
410 public static final String TYPE_BOOLEAN = "boolean";
\r
411 public static final String TYPE_DATETIME = "dateTime";
\r
412 public static final String TYPE_UNSIGNEDINT = "unsignedInt";
\r
413 public static final String TYPE_INT = "int";
\r
414 public static final String TYPE_BASE64 = "base64";
\r
416 public String getXmlType(String type) {
\r
417 if (type.equals(TYPE_BASE64)) {
\r
418 return TR069RPC.XSD_BASE64;
\r
419 } else if (type.equals(TYPE_BOOLEAN)) {
\r
420 return TR069RPC.XSD_BOOLEAN;
\r
421 } else if (type.equals(TYPE_DATETIME)) {
\r
422 return TR069RPC.XSD_DATETIME;
\r
423 } else if (type.equals(TYPE_INT)) {
\r
424 return TR069RPC.XSD_INT;
\r
425 } else if (type.equals(TYPE_OBJECT)) {
\r
427 } else if (type.equals(TYPE_STRING)) {
\r
428 return TR069RPC.XSD_STRING;
\r
429 } else if (type.equals(TYPE_UNSIGNEDINT)) {
\r
430 return TR069RPC.XSD_UNSIGNEDINT;
\r