/
recorder.go
247 lines (206 loc) · 6.29 KB
/
recorder.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
package main
import (
"bufio"
"fmt"
"io/ioutil"
"log"
"os"
"time"
)
// serialPortIO is the Serial Port struct.
// The portIO and serialPort
// are the same object but use
// different interfaces.
type recorderSerialPort struct {
writer *bufio.Writer // Serial port connection to manage the
write chan []byte // Write the data to the file.
isClosing bool // Set flag to close the file on next loop if still running
file *os.File // File path and info
fileSize int // Current file size
}
// run the Recorder process
// This will monitor recorders
// and create recorders for serial ports for connections
// and disconnects.
func (recorder *recorderSerialPort) run() {
log.Print("Serial Recorder running")
for {
select {
// Data received to record
case m := <-recorder.write:
//log.Print("Got a recorder write")
if recorder.isClosing {
return
}
// Check if a new file should be created
// 18mb max size
if recorder.fileSize+len(m) >= 1048576*18 {
loadNewFile(recorder)
}
// Record the data
//log.Print("Record serial data")
n, err := recorder.writer.Write(m)
if err != nil {
log.Printf("Error writing serial data to file: %s", err.Error())
}
recorder.fileSize += n
//log.Printf("Recorded %d bytes to the file", n)
}
}
}
// startRecording will find the serialPortIO
// start the recording process.
func startRecording(portName string) {
//see if we have this port open
spio, isFound := findPortByName(portName)
if isFound {
log.Print("Start Recording")
startSerialPortRecording(spio)
}
}
// stopRecording will find the serialPortIO
// stop recording.
func stopRecording(portName string) {
//see if we have this port open
spio, isFound := findPortByName(portName)
if isFound {
log.Print("Stop Recording")
stopSerialPortRecording(spio)
}
}
// startSerialPortRecording will start recording.
// It will create the file and buferio. It will set
// the recorder to the serialPortIO. It will then set
// the flag to start recording.
func startSerialPortRecording(spio *serialPortIO) {
// // Create a new file name
// t := time.Now()
// filePath := *record + "Raw_" + t.Format("20060102150405") + ".ens"
//
// log.Printf("Creating file: %s", filePath)
//
// // Create the file
// file, err := os.Create(filePath)
file, err := createFile()
if err != nil {
log.Print("Error creating file. " + err.Error())
return
}
// Create bufio
bufWriter := bufio.NewWriter(file)
log.Print("bufio writer created")
// Create recorder
spio.recorder = &recorderSerialPort{
file: file, // File to write to
writer: bufWriter, // bufio to write data to file
write: make(chan []byte), // Write data to recorder
isClosing: false, // Set flag
fileSize: 0, // Initialize the file size
}
log.Print("recorder set to SPIO")
spio.isRecording = true
log.Print("Serial Port recorder started")
go spio.recorder.run()
}
// stopSerialPortRecording will stop the serial port
// from recording. It will close the file and set the
// flag to stop recording.
func stopSerialPortRecording(spio *serialPortIO) {
log.Print("Stop recording serial port")
spio.isRecording = false
log.Print("Stop recording serial port closing")
spio.recorder.isClosing = true
// Flush and close the file
log.Print("Stop recording serial port close file")
spio.recorder.writer.Flush()
spio.recorder.file.Close()
// Close the channel
log.Print("Stop recording serial port stop channel")
close(spio.recorder.write)
log.Print("End Stop recording")
}
// loadNewFile will create a new file. This is used
// when the file max size has been exceeded and a new
// file needs to be created.
func loadNewFile(recorder *recorderSerialPort) {
// // Create a new file name
// t := time.Now()
// filePath := *record + "Raw_" + t.Format("20060102150405") + ".ens"
//
// log.Printf("Creating file: %s", filePath)
//
// // Create the file
// file, err := os.Create(filePath)
file, err := createFile()
if err != nil {
log.Print("Error creating file. " + err.Error())
return
}
// Initialize the file size
recorder.fileSize = 0
// Create bufio
recorder.writer = bufio.NewWriter(file)
}
// Create the file. This will create the folder for the current date.
// It will then create the file in the folder.
func createFile() (*os.File, error) {
// Create Record folder if it does not exists
rootPath := *record + "record" + string(os.PathSeparator)
var _, errFolder = os.Stat(rootPath)
if os.IsNotExist(errFolder) {
os.Mkdir(rootPath, 0711)
}
// Create a new file name
t := time.Now()
folderPath := rootPath + t.Format("20060102") + string(os.PathSeparator)
filePath := folderPath + "Raw_" + t.Format("20060102150405") + ".ens"
log.Printf("Creating folder: %s\n", folderPath)
log.Printf("Creating file: %s\n", filePath)
// Check if the folder has been created already
var _, errFolder1 = os.Stat(folderPath)
if os.IsNotExist(errFolder1) {
os.Mkdir(folderPath, 0711)
}
// detect if file exists
var _, err = os.Stat(filePath)
// create file if not exists
if os.IsNotExist(err) {
var file, err1 = os.Create(filePath)
CheckError(err)
//defer file.Close()
return file, err1
}
return nil, err
}
// RecordedFileInfo holdes the file info structure.
type RecordedFileInfo struct {
RcrdFolder string
RcrdFile string
}
// RecordedFileList is a list of files recorded
// and there folder path.
type RecordedFileList struct {
FileList []RecordedFileInfo
}
func getFileList() RecordedFileList {
rootPath := *record + "record" + string(os.PathSeparator)
// Read all the directory in the record folder
files, _ := ioutil.ReadDir(rootPath)
var recordedFiles RecordedFileList
var fileList []RecordedFileInfo
for _, f := range files {
if f.IsDir() { // Find subfolders
subFiles, _ := ioutil.ReadDir(rootPath + string(os.PathSeparator) + f.Name()) // Get the subfiles within subfolder
for _, sf := range subFiles {
subFile := new(RecordedFileInfo) // Create struct
subFile.RcrdFolder = rootPath + f.Name() // Set folder
subFile.RcrdFile = sf.Name() // Set file name
fileList = append(fileList, *subFile) // Add struct to list
}
}
}
// Set the file list
recordedFiles.FileList = fileList
fmt.Println("Recorded Files: ", recordedFiles)
return recordedFiles
}