2 * ============LICENSE_START========================================================================
3 * ONAP : tr-069-adapter
4 * =================================================================================================
5 * Copyright (C) 2020 CommScope Inc Intellectual Property.
6 * =================================================================================================
7 * This tr-069-adapter software file is distributed by CommScope Inc under the Apache License,
8 * Version 2.0 (the "License"); you may not use this file except in compliance with the License. You
9 * may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
14 * either express or implied. See the License for the specific language governing permissions and
15 * limitations under the License.
16 * ===============LICENSE_END=======================================================================
20 package org.commscope.tr069adapter.acs.cpe;
22 import java.io.IOException;
23 import java.io.OutputStream;
24 import java.io.Serializable;
25 import java.security.SecureRandom;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.Random;
30 import javax.xml.soap.MessageFactory;
31 import javax.xml.soap.Name;
32 import javax.xml.soap.Node;
33 import javax.xml.soap.SOAPBody;
34 import javax.xml.soap.SOAPBodyElement;
35 import javax.xml.soap.SOAPElement;
36 import javax.xml.soap.SOAPEnvelope;
37 import javax.xml.soap.SOAPException;
38 import javax.xml.soap.SOAPFactory;
39 import javax.xml.soap.SOAPHeader;
40 import javax.xml.soap.SOAPHeaderElement;
41 import javax.xml.soap.SOAPMessage;
42 import javax.xml.soap.SOAPPart;
44 import org.commscope.tr069adapter.acs.cpe.rpc.Fault;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
48 public abstract class TR069RPC implements Serializable {
50 private static final String HTTP_SCHEMA_ENCODING = "http://schemas.xmlsoap.org/soap/encoding/";
52 private static final long serialVersionUID = 7270475819053880884L;
54 protected static final Logger logger = LoggerFactory.getLogger(TR069RPC.class);
56 private Random mrandom = new SecureRandom();
58 /** Creates a new instance of Message */
61 public static final String ENVELOPE_NAMESPACE = "http://schemas.xmlsoap.org/soap/envelope/";
63 protected abstract void createBody(SOAPBodyElement body, SOAPFactory spf) throws SOAPException;
65 protected abstract void parseBody(SOAPBodyElement body, SOAPFactory f) throws SOAPException;
67 protected class ArrayType {
75 public String getType() {
79 public Name getType(SOAPBodyElement body, SOAPFactory spf) throws SOAPException {
80 int i = type.indexOf(':');
82 return spf.createName(type);
84 String prefix = type.substring(0, i);
85 SOAPBody b = (SOAPBody) body.getParentElement();
86 SOAPEnvelope e = (SOAPEnvelope) b.getParentElement();
87 SOAPHeader h = e.getHeader();
90 uri = h.lookupNamespaceURI(prefix);
91 } catch (Exception ee) {
92 logger.error("While geting namespace URI 1 {}", ee.toString());
96 uri = e.lookupNamespaceURI(prefix);
97 } catch (Exception ee) {
98 logger.error("While geting namespace URI 2 {}", ee.toString());
103 uri = b.lookupNamespaceURI(prefix);
104 } catch (Exception ee) {
105 logger.error("While geting namespace URI {} ", ee.toString());
108 return spf.createName(type.substring(i + 1), prefix, uri);
112 public void setType(String type) {
117 public static SOAPBodyElement getRequest(SOAPMessage msg) throws SOAPException {
118 SOAPBodyElement request = null;
119 Iterator<Node> i1 = msg.getSOAPBody().getChildElements();
120 while (i1.hasNext()) {
122 if (n.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
123 request = (SOAPBodyElement) n;
129 private static String getRequestName(SOAPMessage msg) throws SOAPException {
130 if (msg.getSOAPBody().hasFault()) {
134 SOAPBodyElement element = getRequest(msg);
135 if (element != null) {
136 name = element.getNodeName();
138 if (name.startsWith("cwmp:")) {
139 name = name.substring(5);
140 } else if (name.startsWith("cwmp_x:")) {
141 name = name.substring(7);
142 } else if (name.indexOf(':') != -1) {
143 name = name.substring(name.indexOf(':') + 1, name.length());
148 public static TR069RPC parse(SOAPMessage soapMsg)
149 throws SOAPException, InstantiationException, IllegalAccessException, ClassNotFoundException {
150 String reqname = TR069RPC.getRequestName(soapMsg);
154 msg = (TR069RPC) Class.forName("org.commscope.tr069adapter.acs.cpe.rpc." + reqname)
156 } catch (Exception e) {
157 msg = (TR069RPC) Class.forName("org.commscope.tr069adapter.acs.cpe.rpc." + reqname)
160 msg = msg.parseSoapMessage(soapMsg);
164 @SuppressWarnings("unchecked")
165 private TR069RPC parseSoapMessage(SOAPMessage soapMsg) throws SOAPException {
166 SOAPEnvelope env = soapMsg.getSOAPPart().getEnvelope();
168 Iterator<String> pfxs = env.getNamespacePrefixes();
169 while (pfxs.hasNext()) {
170 String pfx = pfxs.next();
171 String uri = env.getNamespaceURI(pfx);
172 if (CWMP.equalsIgnoreCase(pfx)) {
176 SOAPFactory spf = SOAPFactory.newInstance();
177 SOAPBodyElement soaprequest = getRequest(soapMsg);
178 SOAPHeader hdr = soapMsg.getSOAPHeader();
179 id = "device_did_not_send_id"; // or make it null?...
182 id = getHeaderElement(spf, hdr, "ID");
183 } catch (Exception e) {
184 logger.error("While parsing the soap message {}", e.toString());
187 name = getRequestName(soapMsg);
188 if (soaprequest != null) {
189 Fault fault = parseSOAPRequest(soaprequest, spf);
196 private Fault parseSOAPRequest(SOAPBodyElement soaprequest, SOAPFactory spf)
197 throws SOAPException {
198 if (soaprequest != null) {
200 parseBody(soaprequest, spf);
201 } catch (Exception e) {
202 SOAPElement se = getRequestChildElement(spf, soaprequest, FAULT_CODE);
203 String fc = (se != null) ? se.getValue() : "0";
204 SOAPElement se2 = getRequestChildElement(spf, soaprequest, FAULT_STRING);
205 String fs = (se2 != null) ? se2.getValue() : "0";
207 if (se != null || se2 != null) {
208 return new Fault(fc, fs, id);
216 public void writeTo(OutputStream out) {
218 SOAPFactory spf = SOAPFactory.newInstance();
219 MessageFactory factory = MessageFactory.newInstance();
220 SOAPMessage soapMsg = factory.createMessage();
221 SOAPPart part = soapMsg.getSOAPPart();
223 SOAPEnvelope envelope = part.getEnvelope();
224 SOAPHeader header = envelope.getHeader();
225 SOAPBody body = envelope.getBody();
227 String responseId = getId();
229 envelope.addNamespaceDeclaration("xsd", "http://www.w3.org/2001/XMLSchema");
230 envelope.addNamespaceDeclaration("cwmp", urnCWMP);
231 envelope.addNamespaceDeclaration("SOAP-ENC", HTTP_SCHEMA_ENCODING);
232 envelope.addNamespaceDeclaration("SOAP-ENV", ENVELOPE_NAMESPACE);
233 envelope.addNamespaceDeclaration("xsi", "http://www.w3.org/2001/XMLSchema-instance");
235 SOAPElement element = header.addChildElement(spf.createName("ID", "cwmp", urnCWMP));
236 element.addAttribute(spf.createName("mustUnderstand", "SOAP-ENV", ENVELOPE_NAMESPACE),
238 element.addTextNode("1");
240 body.setEncodingStyle(HTTP_SCHEMA_ENCODING);
241 SOAPBodyElement bd = body.addBodyElement(spf.createName(name, CWMP, urnCWMP));
243 if (name == null || name.equals("")) {
244 name = this.getClass().getSimpleName();
246 createBody(bd, spf, id);
248 soapMsg.writeTo(out);
249 } catch (SOAPException ex) {
250 logger.error("Exception occurred while constructing SOAP message: {}", ex.getMessage());
251 } catch (IOException e) {
252 logger.error("Exception occurred while constructing SOAP message: {}", e.getMessage());
256 protected void createBody(SOAPBodyElement body, SOAPFactory spf, String key)
257 throws SOAPException {
258 logger.debug("Key element is: {}", key);
259 createBody(body, spf);
262 protected SOAPElement getRequestChildElement(SOAPFactory f, SOAPElement req, String name) {
263 @SuppressWarnings("unchecked")
264 Iterator<Object> i = req.getChildElements();
266 while (i.hasNext()) {
270 String n = nn.getLocalName();
271 if (n != null && n.equals(name)) {
272 return (SOAPElement) o;
274 } catch (Exception e) {
275 logger.debug("Exception: {}, {}", e.getMessage(), e.getClass().getName());
281 protected SOAPElement getRequestChildElement2(SOAPFactory f, SOAPElement req, String name)
282 throws SOAPException {
283 return (SOAPElement) req.getChildElements(f.createName(name, CWMP, urnCWMP)).next();
286 protected String getRequestElement(SOAPFactory f, SOAPElement req, String name) {
287 return getRequestChildElement(f, req, name).getValue();
290 protected String getRequestElement(SOAPFactory f, SOAPElement req, String name, String def) {
291 String v = getRequestChildElement(f, req, name).getValue();
292 return (v != null) ? v : def;
295 protected SOAPElement getRequestChildElement(SOAPElement req, Name name) {
296 return (SOAPElement) req.getChildElements(name).next();
299 protected String getRequestElement(SOAPElement req, Name name) {
300 return getRequestChildElement(req, name).getValue();
303 protected String getHeaderElement(SOAPFactory f, SOAPHeader hdr, String name)
304 throws SOAPException {
305 return ((SOAPHeaderElement) hdr.getChildElements(f.createName(name, CWMP, urnCWMP)).next())
309 protected HashMap<String, String> parseParamList(SOAPElement body, SOAPFactory spf)
310 throws SOAPException {
311 return parseParamList(body, spf, "ParameterValueStruct", "Value");
314 protected HashMap<String, String> parseParamList(SOAPElement body, SOAPFactory spf, String sn,
315 String vn) throws SOAPException {
316 Iterator<SOAPElement> pi =
317 getRequestChildElement(spf, body, "ParameterList").getChildElements(spf.createName(sn));
318 Name nameKey = spf.createName("Name");
319 Name nameValue = spf.createName(vn);
320 HashMap<String, String> pl = new HashMap<>();
321 while (pi.hasNext()) {
322 SOAPElement param = pi.next();
323 String key = getRequestElement(param, nameKey);
324 String value = getRequestElement(param, nameValue);
333 protected int getArrayCount(SOAPFactory spf, SOAPElement e) throws SOAPException {
334 return getArrayCount(spf, e, null);
337 protected int getArrayCount(SOAPFactory spf, SOAPElement e, ArrayType type) throws SOAPException {
338 Name nameArray = spf.createName("arrayType", "soap-enc", HTTP_SCHEMA_ENCODING);
339 String attr = e.getAttributeValue(nameArray);
343 attr = attr.replace(" ", "");
344 int i = attr.indexOf('[');
345 String c = attr.substring(i + 1, attr.length() - 1);
347 type.setType(attr.substring(0, i));
349 return Integer.parseInt(c);
352 public boolean isFault() {
353 return name.equals("Fault");
356 protected String b2s(boolean b) {
357 return (b) ? "1" : "0";
360 protected String name;
362 public String getName() {
368 public String getId() {
370 id = "" + mrandom.nextInt(99999);
375 protected void println(StringBuilder b, String n, String v) {
382 protected void println(StringBuilder b, String n, String n2, String v) {
387 public String getCWMPVersion() {
391 public void setCWMPVersion(String cwmpVersion) {
392 urnCWMP = cwmpVersion;
395 protected String urnCWMP = "urn:dslforum-org:cwmp-1-0";
396 protected static final String CWMP = "cwmp";
397 protected static final String PARAMETER_KEY = "ParameterKey";
398 protected static final String COMMAND_KEY = "CommandKey";
399 protected static final String XSI_TYPE = "xsi:type";
400 protected static final String XSD_STRING = "xsd:string";
401 protected static final String XSD_UNSIGNEDINT = "xsd:unsignedInt";
402 protected static final String XSD_INT = "xsd:int";
403 protected static final String XSD_BOOLEAN = "xsd:boolean";
404 protected static final String XSD_DATETIME = "xsd:dateTime";
405 protected static final String XSD_BASE64 = "xsd:base64";
406 protected static final String SOAP_ARRAY_TYPE = "SOAP-ENC:arrayType";
407 public static final String FAULT_CODE = "FaultCode";
408 public static final String FAULT_STRING = "FaultString";
409 public static final String TYPE_OBJECT = "object";
410 public static final String TYPE_STRING = "string";
411 public static final String TYPE_BOOLEAN = "boolean";
412 public static final String TYPE_DATETIME = "dateTime";
413 public static final String TYPE_UNSIGNEDINT = "unsignedInt";
414 public static final String TYPE_INT = "int";
415 public static final String TYPE_BASE64 = "base64";
417 public String getXmlType(String type) {
418 if (type.equals(TYPE_BASE64)) {
419 return TR069RPC.XSD_BASE64;
420 } else if (type.equals(TYPE_BOOLEAN)) {
421 return TR069RPC.XSD_BOOLEAN;
422 } else if (type.equals(TYPE_DATETIME)) {
423 return TR069RPC.XSD_DATETIME;
424 } else if (type.equals(TYPE_INT)) {
425 return TR069RPC.XSD_INT;
426 } else if (type.equals(TYPE_OBJECT)) {
428 } else if (type.equals(TYPE_STRING)) {
429 return TR069RPC.XSD_STRING;
430 } else if (type.equals(TYPE_UNSIGNEDINT)) {
431 return TR069RPC.XSD_UNSIGNEDINT;