Skip to content

Commit

Permalink
feat: get frames from zniffer and clear
Browse files Browse the repository at this point in the history
  • Loading branch information
robertsLando committed May 21, 2024
1 parent 006d9d2 commit 5863913
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 49 deletions.
6 changes: 6 additions & 0 deletions api/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,12 @@ function setupSocket(server: HttpServer) {
case 'stop':
res = await zniffer.stop()
break
case 'clear':
res = zniffer.clear()
break
case 'getFrames':
res = zniffer.getFrames()
break
case 'setFrequency':
res = await zniffer.setFrequency(data.frequency)
break
Expand Down
114 changes: 74 additions & 40 deletions api/lib/ZnifferManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export type SocketFrame = (Frame | CorruptedFrame) & {
parsedPayload?: Record<string, any>
corrupted: boolean
timestamp: number
raw: string
}

export interface FrameCCLogEntry {
Expand Down Expand Up @@ -113,34 +114,14 @@ export default class ZnifferManager extends TypedEventEmitter<ZnifferManagerEven
try {
await this.zniffer.init()

this.zniffer.on('frame', (frame) => {
const socketFrame: SocketFrame = {
...frame,
corrupted: false,
payload: '' as any,
timestamp: Date.now(),
}

if ('payload' in frame) {
if (frame.payload instanceof CommandClass) {
socketFrame.parsedPayload = this.ccToLogRecord(
frame.payload,
)
} else {
socketFrame.payload = buffer2hex(frame.payload)
}
}
this.zniffer.on('frame', (frame, rawData) => {
const socketFrame = this.parseFrame(frame, rawData)

this.socket.emit(socketEvents.znifferFrame, socketFrame)
})

this.zniffer.on('corrupted frame', (frame) => {
const socketFrame: SocketFrame = {
...frame,
corrupted: true,
payload: buffer2hex(frame.payload) as any,
timestamp: Date.now(),
}
this.zniffer.on('corrupted frame', (frame, rawData) => {
const socketFrame = this.parseFrame(frame, rawData)

this.socket.emit(socketEvents.znifferFrame, socketFrame)
})
Expand All @@ -165,6 +146,30 @@ export default class ZnifferManager extends TypedEventEmitter<ZnifferManagerEven
}
}

private parseFrame(
frame: Frame | CorruptedFrame,
rawData: Buffer,
timestamp = Date.now(),
): SocketFrame {
const socketFrame: SocketFrame = {
...frame,
corrupted: !('protocol' in frame),
payload: '' as any,
timestamp,
raw: buffer2hex(rawData),
}

if ('payload' in frame) {
if (frame.payload instanceof CommandClass) {
socketFrame.parsedPayload = this.ccToLogRecord(frame.payload)
} else {
socketFrame.payload = buffer2hex(frame.payload)
}
}

return socketFrame
}

private onError(error: Error) {
logger.error('Zniffer error:', error)
this.error = error.message
Expand All @@ -189,6 +194,18 @@ export default class ZnifferManager extends TypedEventEmitter<ZnifferManagerEven
}
}

public getFrames() {
this.checkReady()

return this.zniffer.capturedFrames.map((frame) => {
return this.parseFrame(
frame.parsedFrame,
frame.frameData,
frame.timestamp.getTime(),
)
})
}

public async setFrequency(frequency: number) {
this.checkReady()

Expand All @@ -201,21 +218,29 @@ export default class ZnifferManager extends TypedEventEmitter<ZnifferManagerEven
}

private ccToLogRecord(commandClass: CommandClass): Record<string, any> {
const parsed: Record<string, any> = commandClass.toLogEntry(
this.zniffer as any,
)

if (isEncapsulatingCommandClass(commandClass)) {
parsed.encapsulated = [
this.ccToLogRecord(commandClass.encapsulated),
]
} else if (isMultiEncapsulatingCommandClass(commandClass)) {
parsed.encapsulated = [
commandClass.encapsulated.map((cc) => this.ccToLogRecord(cc)),
]
try {
const parsed: Record<string, any> = commandClass.toLogEntry(
this.zniffer as any,
)

if (isEncapsulatingCommandClass(commandClass)) {
parsed.encapsulated = [
this.ccToLogRecord(commandClass.encapsulated),
]
} else if (isMultiEncapsulatingCommandClass(commandClass)) {
parsed.encapsulated = [
commandClass.encapsulated.map((cc) =>
this.ccToLogRecord(cc),
),
]
}
return parsed
} catch (error) {
logger.error('Error parsing command class:', error)
return {
error: error.message,
}
}

return parsed
}

public async close() {
Expand All @@ -241,7 +266,7 @@ export default class ZnifferManager extends TypedEventEmitter<ZnifferManagerEven

this.onStateChange()

logger.info('ZnifferManager started')
logger.info('Started')
}

public async stop() {
Expand All @@ -257,7 +282,16 @@ export default class ZnifferManager extends TypedEventEmitter<ZnifferManagerEven

this.onStateChange()

logger.info('ZnifferManager stopped')
logger.info('Stopped')
}

public clear() {
this.checkReady()

logger.info('Clearing...')
this.zniffer.clearCapturedFrames()

logger.info('Frames cleared')
}

public async saveCaptureToFile() {
Expand Down
49 changes: 40 additions & 9 deletions src/views/Zniffer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -369,18 +369,17 @@ export default {
},
},
mounted() {
this.socket.on(socketEvents.znifferFrame, (data) => {
data.id = uuid()
const lastFrame = this.frames[this.frames.length - 1]
data.delta = lastFrame ? data.timestamp - lastFrame.timestamp : 0
this.framesQueue.push(data)
})
this.socket.on(socketEvents.znifferFrame, this.addFrame)
this.onWindowResize = () => {
const oneThird = window.innerHeight / 3
this.topPaneHeight = oneThird * 2
}
this.socket.on('connect', this.onConnnect)
this.getFrames()
window.addEventListener('resize', this.onWindowResize)
this.onWindowResize()
Expand All @@ -397,6 +396,7 @@ export default {
if (this.socket) {
// unbind events
this.socket.off(socketEvents.znifferFrame)
this.socket.off('connect', this.onConnnect)
}
if (this.timeoutScroll) {
Expand Down Expand Up @@ -466,6 +466,15 @@ export default {
this.frames.push(...this.framesQueue)
this.framesQueue = []
},
onConnnect() {
this.getFrames()
},
addFrame(data) {
data.id = uuid()
const lastFrame = this.frames[this.frames.length - 1]
data.delta = lastFrame ? data.timestamp - lastFrame.timestamp : 0
this.framesQueue.push(data)
},
async clearFrequency() {
// needed to handle the clear event on select
await this.$nextTick()
Expand Down Expand Up @@ -690,6 +699,21 @@ export default {
}
})
},
async getFrames() {
const response = await this.sendAction(
{
apiName: 'getFrames',
},
{
hideInfo: true,
},
)
if (response.success) {
this.frames = []
response.result.forEach(this.addFrame)
}
},
async setFrequency() {
const response = await this.sendAction(
{
Expand Down Expand Up @@ -721,9 +745,16 @@ export default {
this.showSnackbar(`Zniffer stopped`, 'success')
}
},
clearFrames() {
this.frames = []
this.framesFiltered = []
async clearFrames() {
const response = await this.sendAction({
apiName: 'clear',
})
if (response.success) {
this.showSnackbar(`Zniffer cleared`, 'success')
this.frames = []
this.framesFiltered = []
}
},
async createCapture() {
const response = await this.sendAction({
Expand Down

0 comments on commit 5863913

Please sign in to comment.