import { Option, ParseOption } from "../opt/Option"; import { Choice, M698pdu } from "../axdr/M698pdu"; import { GetRequestOption, } from "../opt/GetRequestOption"; import { DataUtils } from "../DataUtils"; import { Apdu } from "../axdr/Apdu"; import { HdlcFrame } from "../sessionlayer.hdlc/HdlcFrame"; import { ConnectRequestOption } from "../opt/ConnectRequestOption"; import { SecurityRequestOption } from "../opt/SecurityRequestOption"; import { ReverseByteArrayInputStream } from "../ReverseByteArrayInputStream"; import { ReverseByteArrayOutputStream } from "../ReverseByteArrayOutputStream"; import { resultCode } from "../tools/DataTool"; import { parseGetResponseNext, parseGetResponseNormal, parseGetResponseNormalList, parseGetResponseRecord, parseGetResponseRecordList } from "../parse/ParseGetResponse"; import { parseSetNormalResponse, parseSetNormalResponseList, parseSetThenGetResponse } from "../parse/ParseSetResponse"; import { parseConnectResponse, parseSecurityResponse } from "../parse/ParseAuthResponse"; import { FrameData } from "../bean/FrameData"; import { buildGetRequest } from "../build/BuildGetRequest"; import { buildSetRequest } from "../build/BuildSetRequest"; import { buildActionRequest } from "../build/BuildActionRequest"; import { buildConnectRequest } from "../build/BuildConnectRequest"; import { buildProxyRequest } from "../build/BuildProxyRequest"; import { buildSecurityRequest } from "../build/BuildSecurityRequest"; import { SetRequestOption } from "../opt/SetRequestOption"; import { ActionRequestOption } from "../opt/ActionRequestOption"; import { ProxyRequestOption } from "../opt/ProxyRequestOption"; import { parseActionResponseNormal, parseActionResponseNormalList, parseActionThenGetResponseList } from "../parse/ParseActionResponse"; import { parseProxyActionResponseList, parseProxyActionThenGetResponseList, parseProxyGetRecord, parseProxyGetResponseList, parseProxySetResponseNormalList, parseProxySetThenGetResponseList, parseProxyTransCommand } from "../parse/ParseProxyResponse"; export class TS698 { private static instance: TS698 = null; private constructor() { } public static getInstance(): TS698 { if (!this.instance) { this.instance = new TS698(); } return this.instance; } buildFrame(param: Option) { let data: String = ""; let link_opt = param.link_option; let request_option = param.request_option; // 请求配置不能为空 if (link_opt == null || request_option == null) { data = "link_option or request_option not allow empty"; param.error({ resultCode: resultCode.emptyError, msg: data }) return; } // 链路层配置所需参数校验 if (link_opt.server_address == null || link_opt.client_address == null) { data = "server_address or client_address not allow empty"; param.error({ resultCode: resultCode.emptyError, msg: data }) return; } else { if (link_opt.server_address.length == 0 || link_opt.server_address.length != 12) { data = "server_address length is Illegal"; param.error({ resultCode: resultCode.illegalError, msg: data }) return; } if (link_opt.client_address.length == 0 || link_opt.client_address.length != 2) { data = "client_address length is Illegal"; param.error({ resultCode: resultCode.illegalError, msg: data }) return; } } // apdu请求相关配置 if (request_option.request_mode != Choice.GET_REQUEST && request_option.request_mode != Choice.SET_REQUEST && request_option.request_mode != Choice.ACTION_REQUEST && request_option.request_mode != Choice.CONNECT_REQUEST && request_option.request_mode != Choice.PROXY_REQUEST && request_option.request_mode != Choice.SECURITY_REQUEST) { data = "request_mode length is Illegal"; param.error({ resultCode: resultCode.illegalError, msg: data }) return; } else { if (request_option.request_mode == Choice.GET_REQUEST) { // get 请求 let get_opt = request_option.request as GetRequestOption; if (get_opt == null || get_opt.get_option == null) { data = "get request not allow empty"; param.error({ resultCode: resultCode.emptyError, msg: data }) return; } else { let result = buildGetRequest(get_opt, link_opt, request_option); if (result[0] == resultCode.success) { param.success({ resultCode: result[0], msg: result[1] }) } else { param.error({ resultCode: result[0], msg: result[1] }) } } } else if (request_option.request_mode == Choice.SET_REQUEST) { let set_opt = request_option.request as SetRequestOption; if (set_opt == null || set_opt.set_option == null) { data = "set request not allow empty"; param.error({ resultCode: resultCode.emptyError, msg: data }) return; } else { let result = buildSetRequest(set_opt, link_opt, request_option); if (result[0] == resultCode.success) { param.success({ resultCode: result[0], msg: result[1] }) } else { param.error({ resultCode: result[0], msg: result[1] }) } } } else if (request_option.request_mode == Choice.ACTION_REQUEST) { let action_opt = request_option.request as ActionRequestOption; if (action_opt == null || action_opt.action_option == null) { data = "action request not allow empty"; param.error({ resultCode: resultCode.emptyError, msg: data }) return; } else { let result = buildActionRequest(action_opt, link_opt, request_option); if (result[0] == resultCode.success) { param.success({ resultCode: result[0], msg: result[1] }) } else { param.error({ resultCode: result[0], msg: result[1] }) } } } else if (request_option.request_mode == Choice.CONNECT_REQUEST) { let connect_opt = request_option.request as ConnectRequestOption; if (connect_opt == null) { data = "connect request not allow empty"; param.error({ resultCode: resultCode.emptyError, msg: data }) return; } else { let result = buildConnectRequest(connect_opt, link_opt, request_option); if (result[0] == resultCode.success) { param.success({ resultCode: result[0], msg: result[1] }) } else { param.error({ resultCode: result[0], msg: result[1] }) } } } else if (request_option.request_mode == Choice.PROXY_REQUEST) { let proxy_opt = request_option.request as ProxyRequestOption; if (proxy_opt == null || proxy_opt.proxy_option == null) { data = "proxy request not allow empty"; param.error({ resultCode: resultCode.emptyError, msg: data }) return; } else { let result = buildProxyRequest(proxy_opt, link_opt, request_option); if (result[0] == resultCode.success) { param.success({ resultCode: result[0], msg: result[1] }) } else { param.error({ resultCode: result[0], msg: result[1] }) } } } else if (request_option.request_mode == Choice.SECURITY_REQUEST) { let security_opt = request_option.request as SecurityRequestOption; if (security_opt == null) { data = "connect request not allow empty"; param.error({ resultCode: resultCode.emptyError, msg: data }) return; } else { let result = buildSecurityRequest(security_opt, link_opt, request_option); if (result[0] == resultCode.success) { param.success({ resultCode: result[0], msg: result[1] }) } else { param.error({ resultCode: result[0], msg: result[1] }) } } } } } parseLinkFrame(frame: String): String { let frameData = new FrameData(); let lenPractical = frame.length - 4;//实际长度 let len_first = frame.substring(2, 4);//帧中的数据长度前两位 let len_second = frame.substring(4, 6);//帧中数据帧长度后两位 let len = parseInt(len_second + len_first, 16); if (len * 2 != lenPractical) { frameData.code = resultCode.illegalError; frameData.data = "frame length is illegal"; return JSON.stringify(frameData); } // 提取链路层数据帧,获取应用层数据帧 let appFrame; console.log(frame); let dataInputStream = new ReverseByteArrayInputStream(DataUtils.hexToBytes(frame.toString())); let hdlcFrame; try { hdlcFrame = new HdlcFrame().decode(dataInputStream); if (hdlcFrame.isSegmented()) { let s = (hdlcFrame.getSegFrameType() | hdlcFrame.getSegFrameXh()).toString(16); while (s.length < 4) { s.slice(0, 1) + "0" + s.slice(1); } appFrame = s; } else { let field = hdlcFrame.getInformationField(); appFrame = DataUtils.toHexString(field, 1, 0); console.log(appFrame); } } catch (e) { frameData.code = resultCode.illegalError; frameData.data = "frame parse failed"; return JSON.stringify(frameData); } return this.parseAppFrame(appFrame); } parseAppFrame(frame: string): String { let frameData = new FrameData(); if (frame == null) { frameData.code = resultCode.emptyError; frameData.data = "frame is mot allow empty"; return JSON.stringify(frameData); } let apdu; let m698pdu = new M698pdu(); // console.log(DataUtils.hexToBytes(frame)) apdu = Apdu.getInstance().decode(DataUtils.hexToBytes(frame)); let output = new ReverseByteArrayOutputStream(); output.setBufSize(3000); apdu.getCosemPdu().encode(output); m698pdu.decode(new ReverseByteArrayInputStream(output.getArray())); return this.parseFrame(m698pdu); } parse(option: ParseOption) { let frame = option.frame; let frameData = new FrameData(); if (frame == null || frame.length % 2 != 0) { frameData.code = resultCode.illegalError; frameData.data = "frame param is illegal or empty"; option.result({ msg: JSON.stringify(frameData) }) } if (frame.startsWith("68") && frame.endsWith("16")) { option.result({ msg: this.parseLinkFrame(frame) }) } else { option.result({ msg: this.parseAppFrame(frame.toString()) }) } } parseFrame(m698pdu: M698pdu): String { let result: String = ""; switch (m698pdu.getChoiceIndex()) { case Choice.GET_RESPONSE: if (m698pdu.get_response.choice == 1) { result = parseGetResponseNormal(m698pdu.get_response.getResponseNormal.result.result); } else if (m698pdu.get_response.choice == 2) { result = parseGetResponseNormalList(m698pdu.get_response.getResponseNormalList.results); } else if (m698pdu.get_response.choice == 3) { result = parseGetResponseRecord(m698pdu.get_response.getResponseRecord.results.respData); } else if (m698pdu.get_response.choice == 4) { result = parseGetResponseRecordList(m698pdu.get_response.getResponseRecordList.results); } else if (m698pdu.get_response.choice == 5) { result = parseGetResponseNext(m698pdu.get_response.getResponseNext.frameResp); } break; case Choice.SET_RESPONSE: if (m698pdu.set_response.choice == 1) { result = parseSetNormalResponse(m698pdu.set_response.setResponseNormal); } else if (m698pdu.set_response.choice == 2) { result = parseSetNormalResponseList(m698pdu.set_response.setResponseNormalList); } else if (m698pdu.set_response.choice == 3) { result = parseSetThenGetResponse(m698pdu.set_response.setThenGetResponseNormalList); } break; case Choice.ACTION_RESPONSE: if (m698pdu.action_response.choice == 1) { result = parseActionResponseNormal(m698pdu.action_response.actionResponseNormal); } else if (m698pdu.action_response.choice == 2) { result = parseActionResponseNormalList(m698pdu.action_response.actionResponseNormalList) } else if (m698pdu.action_response.choice == 3) { result = parseActionThenGetResponseList(m698pdu.action_response.actionThenGetResponseNormalList) } break; case Choice.CONNECT_RESPONSE: result = parseConnectResponse(m698pdu.connect_response.wConnObj); break; case Choice.SECURITY_RESPONSE: result = parseSecurityResponse(m698pdu.security_response); break; case Choice.PROXY_RESPONSE: if (m698pdu.proxy_response.choice == 1) { result = parseProxyGetResponseList(m698pdu.proxy_response.proxyGetResponseList.result); } else if (m698pdu.proxy_response.choice == 2) { result = parseProxyGetRecord(m698pdu.proxy_response.proxyGetResponseRecord); } else if (m698pdu.proxy_response.choice == 3) { result = parseProxySetResponseNormalList(m698pdu.proxy_response.proxySetResponseList); } else if (m698pdu.proxy_response.choice == 4) { result = parseProxySetThenGetResponseList(m698pdu.proxy_response.proxySetThenGetResponseList); } else if (m698pdu.proxy_response.choice == 5) { result = parseProxyActionResponseList(m698pdu.proxy_response.proxyActionResponseList); } else if (m698pdu.proxy_response.choice == 6) { result = parseProxyActionThenGetResponseList(m698pdu.proxy_response.proxyActionThenGetResponseList); } else if (m698pdu.proxy_response.choice == 7) { result = parseProxyTransCommand(m698pdu.proxy_response.proxyTransCommandResponse); } break; } return result; } }