/** * Classes SOAP Envelope (extraites de cwmp-connector/src/protocol/soap.ts) * * Séparées de soap.ts (le module de parsing d'adam-acs) pour éviter les conflits de nom. */ import { Cwmp_1_0 } from './cwmp-1-0.js' import { Cwmp_1_1 } from './cwmp-1-1.js' import { Cwmp_1_2 } from './cwmp-1-2.js' import { Cwmp_1_3, SessionTimeout } from './cwmp-1-3.js' import { Cwmp_1_4, SupportedCWMPVersions, UseCWMPVersion } from './cwmp-1-4.js' type NamespaceDescriptor = { SoapEnc: string SoapEnv: string Xsd: string Xsi: string Cwmp: string } export const NAMESPACES: Record = { '1.0': { SoapEnc: 'http://schemas.xmlsoap.org/soap/encoding/', SoapEnv: 'http://schemas.xmlsoap.org/soap/envelope/', Xsd: 'http://www.w3.org/2001/XMLSchema', Xsi: 'http://www.w3.org/2001/XMLSchema-instance', Cwmp: 'urn:dslforum-org:cwmp-1-0', }, '1.1': { SoapEnc: 'http://schemas.xmlsoap.org/soap/encoding/', SoapEnv: 'http://schemas.xmlsoap.org/soap/envelope/', Xsd: 'http://www.w3.org/2001/XMLSchema', Xsi: 'http://www.w3.org/2001/XMLSchema-instance', Cwmp: 'urn:dslforum-org:cwmp-1-1', }, '1.2': { SoapEnc: 'http://schemas.xmlsoap.org/soap/encoding/', SoapEnv: 'http://schemas.xmlsoap.org/soap/envelope/', Xsd: 'http://www.w3.org/2001/XMLSchema', Xsi: 'http://www.w3.org/2001/XMLSchema-instance', Cwmp: 'urn:dslforum-org:cwmp-1-2', }, '1.3': { SoapEnc: 'http://schemas.xmlsoap.org/soap/encoding/', SoapEnv: 'http://schemas.xmlsoap.org/soap/envelope/', Xsd: 'http://www.w3.org/2001/XMLSchema', Xsi: 'http://www.w3.org/2001/XMLSchema-instance', Cwmp: 'urn:dslforum-org:cwmp-1-3', }, '1.4': { SoapEnc: 'http://schemas.xmlsoap.org/soap/encoding/', SoapEnv: 'http://schemas.xmlsoap.org/soap/envelope/', Xsd: 'http://www.w3.org/2001/XMLSchema', Xsi: 'http://www.w3.org/2001/XMLSchema-instance', Cwmp: 'urn:dslforum-org:cwmp-1-4', }, } export class SoapEnvelopeAttribute { public SoapEnc: string public SoapEnv: string public Xsd: string public Xsi: string public Cwmp: string constructor(props: NamespaceDescriptor | Record = NAMESPACES['1.0']) { this.SoapEnc = props?.SoapEnc || 'http://schemas.xmlsoap.org/soap/encoding/' this.SoapEnv = props?.SoapEnv || 'http://schemas.xmlsoap.org/soap/envelope/' this.Xsd = props?.Xsd || 'http://www.w3.org/2001/XMLSchema' this.Xsi = props?.Xsi || 'http://www.w3.org/2001/XMLSchema-instance' this.Cwmp = props?.Cwmp || 'urn:dslforum-org:cwmp-1-0' } public isEqualTo(namespace: NamespaceDescriptor): boolean { return ( this.SoapEnc === namespace.SoapEnc && this.SoapEnv === namespace.SoapEnv && this.Xsd === namespace.Xsd && this.Xsi === namespace.Xsi && this.Cwmp === namespace.Cwmp ) } } export class SoapCwmpIdAttribute { MustUnderstand: string constructor(props: { MustUnderstand?: string } = {}) { this.MustUnderstand = props.MustUnderstand || '1' } getXml(): string { return ` soap-env:mustUnderstand="${this.MustUnderstand}"` } } export class CwmpID { $?: SoapCwmpIdAttribute _?: string constructor(props: { $?: { MustUnderstand?: string }; _?: string } = {}) { this.$ = props?.$ ? new SoapCwmpIdAttribute(props.$) : undefined this._ = props._ || '' } getXml(): string { return `${this._}` } } export type CwmpBody = Cwmp_1_0 | Cwmp_1_1 | Cwmp_1_2 | Cwmp_1_3 | Cwmp_1_4 export class SoapEnvelopeHeader { ID: CwmpID NoMoreRequests: number SessionTimeout?: SessionTimeout SupportedCWMPVersions?: SupportedCWMPVersions UseCWMPVersion?: UseCWMPVersion constructor(props: Record = {}) { this.ID = new CwmpID(props?.ID as any) this.NoMoreRequests = (props?.NoMoreRequests as number) || 0 this.SessionTimeout = props?.SessionTimeout ? new SessionTimeout(props.SessionTimeout) : undefined this.SupportedCWMPVersions = props?.SupportedCWMPVersions ? new SupportedCWMPVersions(props.SupportedCWMPVersions) : undefined this.UseCWMPVersion = props?.UseCWMPVersion ? new UseCWMPVersion(props.UseCWMPVersion) : undefined } } export class SoapEnvelope { $?: SoapEnvelopeAttribute Header: SoapEnvelopeHeader Body: CwmpBody version: '1.0' | '1.1' | '1.2' | '1.3' | '1.4' constructor(props: Record = {}) { this.version = (props?.version as '1.0' | '1.1' | '1.2' | '1.3' | '1.4') || '1.0' this.$ = props?.$ ? new SoapEnvelopeAttribute(props.$ as any) : new SoapEnvelopeAttribute(NAMESPACES[this.version]) this.Header = new SoapEnvelopeHeader((props.Header as Record) || {}) const bodyProps = (props.Body as Record) || {} switch (this.version) { case '1.4': this.Body = new Cwmp_1_4(bodyProps) break case '1.3': this.Body = new Cwmp_1_3(bodyProps) break case '1.2': this.Body = new Cwmp_1_2(bodyProps) break case '1.1': this.Body = new Cwmp_1_1(bodyProps) break default: this.Body = new Cwmp_1_0(bodyProps) break } } getXml(): string { const headerParts: string[] = [] if (this.Header.ID) headerParts.push(this.Header.ID.getXml()) if (this.Header.SessionTimeout) { headerParts.push( `${this.Header.SessionTimeout._}` ) } if (this.Header.SupportedCWMPVersions) { headerParts.push( `${this.Header.SupportedCWMPVersions._}` ) } if (this.Header.UseCWMPVersion) { headerParts.push( `${this.Header.UseCWMPVersion._}` ) } // noMoreRequests est un header CPE→ACS uniquement (TR-069 §3.7.1.4) — ne pas l'émettre côté ACS return ` ${headerParts.join('\n ')} ${ this.Body.InformResponse?.getXml() || this.Body.GetParameterValues?.getXml() || this.Body.GetParameterNames?.getXml() || this.Body.GetParameterAttributes?.getXml() || this.Body.SetParameterValues?.getXml() || this.Body.SetParameterAttributes?.getXml() || this.Body.ScheduleInform?.getXml() || this.Body.Download?.getXml() || this.Body.Upload?.getXml() || this.Body.Reboot?.getXml() || this.Body.FactoryReset?.getXml() || this.Body.TransferCompleteResponse?.getXml() || '' } ` } }