import Logger from '../../tools/env.logger' ; import ServiceStreams from '../../services/service.streams' ; import ServiceStreamSource from '../../services/service.stream.sources' ; import ServiceNotifications from '../../services/service.notifications' ; import indexer from 'indexer-neon' ; import { Progress , DLT , CancelablePromise } from 'indexer-neon' ; import { IDLTDeamonConnectionOptions as IConnectionOptions , EDLTDeamonConnectionType , } from '../../../../common/ipc/electron.ipc.messages/dlt.deamon.recent.response' ; import { EventEmitter } from 'events' ; import { CMetaData } from '../files.parsers/file.parser.dlt' ; export { IConnectionOptions } ; export interface IDLTOptions { filters : DLT . DltFilterConf ; stdout ? : boolean ; statusUpdates ? : boolean ; } export class DLTConnectionController extends EventEmitter { public static Events = { connect : 'connect' , disconnect : 'disconnect' , error : 'error' , } ; private _connection : IConnectionOptions ; private _dlt : IDLTOptions ; private _session : string ; private _guid : string ; private _logger : Logger ; private _connector : CancelablePromise < void , void , DLT . TDLTSocketEvents , DLT . TDLTSocketEventObject > | undefined ; private _bytes : number = 0 ; constructor ( guid , session , connection , dlt ? ) { super ( ) ; this . _guid = guid ; this . _session = session ; this . _connection = connection ; this . _dlt = { filters : ! dlt ? { min_log_level : DLT . DltLogLevel . Debug , app_id_count : - 1 , context_id_count : - 1 } : dlt . filters , stdout : ! dlt ? false : typeof dlt . stdout === 'boolean' ? dlt . stdout : false , statusUpdates : ! dlt ? false : typeof dlt . statusUpdates === 'boolean' ? dlt . statusUpdates : false , } ; this . _logger = new Logger ( `DLTConnectionController: ${ session }` ) ; } public destroy ( ) { this . removeAllListeners ( ) ; return this . disconnect ( ) ; } public connect ( ) { return new Promise ( ( resolve , reject ) => { if ( typeof this . _connection . bindingAddress !== 'string' || this . _connection . bindingAddress . trim ( ) === '' ) { return reject ( new Error ( `bindingAddress isn't defined in options, value: ${ this . _connection . bindingAddress }` ) ) ; } if ( typeof this . _connection . bindingPort !== 'string' || this . _connection . bindingPort . trim ( ) === '' ) { return reject ( new Error ( `bindingPort isn't defined in options, value: ${ this . _connection . bindingPort }` ) ) ; } const socket = { bind_addr : this . _connection . bindingAddress , port : this . _connection . bindingPort , multicast_addr : this . _connection . multicast . map ( ( mcast ) => { return { multiaddr : mcast . address , interface : mcast . interface === 'string' ? mcast . interface . trim ( ) !== '' ? mcast . interface : undefined : undefined , } ; } ) , target : this . _connection . target === EDLTDeamonConnectionType . Udp ? 'Udp' : 'Tcp' , timestamp : this . _connection . timezone , } ; const sourceName = `${ this . _connection . ecu }::${ this . _connection . bindingAddress }:${ this . _connection . bindingPort }` ; const sourceId = ServiceStreamSource . add ( { name : sourceName , session : this . _session , meta : CMetaData , } ) ; const streamInfo = ServiceStreams . getStreamFile ( this . _session ) ; if ( streamInfo instanceof Error ) { return reject ( streamInfo ) ; } const params = { filterConfig : this . _dlt . filters , fibex : { fibex_file_paths : ! ( this . _connection . fibex instanceof Array ) ? [ ] : this . _connection . fibex . map ( ( file ) => { return file . path ; } ) , } , tag : `${ sourceId }` , out : streamInfo . file , stdout : this . _dlt . stdout as boolean , statusUpdates : this . _dlt . statusUpdates as boolean , } ; this . _logger . info ( `Connecting` ) ; this . _connector = indexer . dltOverSocket ( this . _session , params , socket ) . then ( ( ) => { this . _logger . info ( `Disconnected` ) ; } ) . canceled ( ( ) => { this . _logger . info ( `Task was canceled` ) ; } ) . catch ( ( error ) => { this . _logger . warn ( `Exception: ${ error . message }` ) ; this . emit ( DLTConnectionController . Events . error , error ) ; } ) . finally ( ( ) => { this . _connector = undefined ; this . emit ( DLTConnectionController . Events . disconnect ) ; } ) . on ( 'connect' , ( ) => { this . emit ( DLTConnectionController . Events . connect ) ; } ) . on ( 'chunk' , ( event ) => { ServiceStreams . pushToStreamFileMap ( streamInfo . streamId , [ { rows : { from : event . rowsStart , to : event . rowsEnd } , bytes : { from : event . bytesStart , to : event . bytesEnd } , } , ] ) ; this . _bytes = event . bytesEnd ; } ) . on ( 'progress' , ( event ) => { } ) . on ( 'notification' , ( event ) => { ServiceNotifications . notifyFromNeon ( event , `DLT: ${ sourceName }` , this . _session , streamInfo . file ) ; } ) ; resolve ( ) ; } ) ; } public disconnect ( ) { return new Promise ( ( resolve ) => { if ( this . _connector === undefined ) { return resolve ( ) ; } this . _connector . finally ( ( ) => { resolve ( ) ; } ) . abort ( ) ; } ) ; } }