- Docker infrastructure (Dockerfile, docker-compose.yml, genieacs-sim) - AdonisJS v7 app with Inertia.js + Vue 3 - MongoDB integration - CWMP/TR-069 state machine engine - Configuration engine with compliance tracking - Branding: ADAM ACS (favicon, navbar, locales) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
98 lines
3.0 KiB
TypeScript
98 lines
3.0 KiB
TypeScript
import { XMLParser } from 'fast-xml-parser'
|
|
|
|
export const NAMESPACES = {
|
|
'soap-env': 'http://schemas.xmlsoap.org/soap/envelope/',
|
|
'soap-enc': 'http://schemas.xmlsoap.org/soap/encoding/',
|
|
xsd: 'http://www.w3.org/2001/XMLSchema',
|
|
xsi: 'http://www.w3.org/2001/XMLSchema-instance',
|
|
cwmp: 'urn:dslforum-org:cwmp-1-0',
|
|
}
|
|
|
|
export const CWMP_VERSIONS: Record<string, string> = {
|
|
'urn:dslforum-org:cwmp-1-0': '1.0',
|
|
'urn:dslforum-org:cwmp-1-1': '1.1',
|
|
'urn:dslforum-org:cwmp-1-2': '1.2',
|
|
'urn:dslforum-org:cwmp-1-3': '1.3',
|
|
'urn:dslforum-org:cwmp-1-4': '1.4',
|
|
}
|
|
|
|
const xmlParser = new XMLParser({
|
|
ignoreAttributes: false,
|
|
attributeNamePrefix: '$',
|
|
textNodeName: '_',
|
|
numberParseOptions: { leadingZeros: false, hex: false },
|
|
isArray: (name) => {
|
|
const arrayTags = ['ParameterValueStruct', 'ParameterInfoStruct', 'EventStruct', 'string']
|
|
return arrayTags.includes(name)
|
|
},
|
|
})
|
|
|
|
export interface SoapEnvelope {
|
|
header: SoapHeader
|
|
body: any
|
|
cwmpVersion: string
|
|
}
|
|
|
|
export interface SoapHeader {
|
|
id?: string
|
|
holdRequests?: boolean
|
|
noMoreRequests?: boolean
|
|
}
|
|
|
|
export interface CwmpMessage {
|
|
type: string
|
|
data: any
|
|
}
|
|
|
|
export function parseSoapXml(xml: string): SoapEnvelope {
|
|
const parsed = xmlParser.parse(xml)
|
|
const envelope = parsed['soap-env:Envelope'] || parsed['SOAP-ENV:Envelope'] || parsed['soapenv:Envelope'] || {}
|
|
const header = envelope['soap-env:Header'] || envelope['SOAP-ENV:Header'] || envelope['soapenv:Header'] || {}
|
|
const body = envelope['soap-env:Body'] || envelope['SOAP-ENV:Body'] || envelope['soapenv:Body'] || {}
|
|
|
|
// Detect CWMP version from namespace
|
|
let cwmpVersion = '1.0'
|
|
for (const [, value] of Object.entries(envelope)) {
|
|
if (typeof value === 'string' && value.startsWith('urn:dslforum-org:cwmp-')) {
|
|
cwmpVersion = CWMP_VERSIONS[value] || '1.0'
|
|
break
|
|
}
|
|
}
|
|
|
|
const soapHeader: SoapHeader = {}
|
|
const idNode = header['cwmp:ID'] || header['cwmp:Id']
|
|
if (idNode) {
|
|
soapHeader.id = typeof idNode === 'string' ? idNode : idNode._ || idNode
|
|
}
|
|
|
|
return { header: soapHeader, body, cwmpVersion }
|
|
}
|
|
|
|
export function extractCwmpMessage(body: any): CwmpMessage | null {
|
|
for (const key of Object.keys(body)) {
|
|
if (key.startsWith('cwmp:')) {
|
|
const type = key.replace('cwmp:', '')
|
|
return { type, data: body[key] }
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
export function buildSoapEnvelope(cwmpId: string | undefined, bodyContent: string): string {
|
|
const id = cwmpId || Math.random().toString(36).substring(2, 10)
|
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
<soap-env:Envelope
|
|
xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"
|
|
xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/"
|
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xmlns:cwmp="urn:dslforum-org:cwmp-1-0">
|
|
<soap-env:Header>
|
|
<cwmp:ID soap-env:mustUnderstand="1">${id}</cwmp:ID>
|
|
</soap-env:Header>
|
|
<soap-env:Body>
|
|
${bodyContent}
|
|
</soap-env:Body>
|
|
</soap-env:Envelope>`
|
|
}
|