xref: /haiku/src/apps/serialconnect/SerialApp.cpp (revision ce058fa0a93fae586ed88817d82449235c5fdd4a)
1dae0a4e0SAdrien Destugues - PulkoMandy /*
2*ce058fa0SAdrien Destugues  * Copyright 2012-2017, Adrien Destugues, pulkomandy@gmail.com
3dae0a4e0SAdrien Destugues - PulkoMandy  * Distributed under the terms of the MIT licence.
4dae0a4e0SAdrien Destugues - PulkoMandy  */
5dae0a4e0SAdrien Destugues - PulkoMandy 
6dae0a4e0SAdrien Destugues - PulkoMandy 
7dae0a4e0SAdrien Destugues - PulkoMandy #include "SerialApp.h"
8dae0a4e0SAdrien Destugues - PulkoMandy 
9469e6cd2SAdrien Destugues - PulkoMandy #include <stdio.h>
10469e6cd2SAdrien Destugues - PulkoMandy #include <string.h>
11469e6cd2SAdrien Destugues - PulkoMandy 
12469e6cd2SAdrien Destugues - PulkoMandy #include <Directory.h>
13469e6cd2SAdrien Destugues - PulkoMandy #include <Entry.h>
14469e6cd2SAdrien Destugues - PulkoMandy #include <File.h>
15ccc6b9beSAdrien Destugues #include <FindDirectory.h>
16ccc6b9beSAdrien Destugues #include <Path.h>
17469e6cd2SAdrien Destugues - PulkoMandy 
1896e59ccaSAdrien Destugues #include "CustomRateWindow.h"
19dae0a4e0SAdrien Destugues - PulkoMandy #include "SerialWindow.h"
20dae0a4e0SAdrien Destugues - PulkoMandy 
21dae0a4e0SAdrien Destugues - PulkoMandy 
22d9e93152SAdrien Destugues static property_info sProperties[] = {
23d9e93152SAdrien Destugues 	{ "baudrate",
24d9e93152SAdrien Destugues 		{ B_GET_PROPERTY, B_SET_PROPERTY, 0 },
25d9e93152SAdrien Destugues 		{ B_DIRECT_SPECIFIER, B_DIRECT_SPECIFIER, 0 },
26d9e93152SAdrien Destugues 		"get or set the baudrate",
27d9e93152SAdrien Destugues 		0, { B_INT32_TYPE }
28d9e93152SAdrien Destugues 	},
29d9e93152SAdrien Destugues 	{ "bits",
30d9e93152SAdrien Destugues 		{ B_GET_PROPERTY, B_SET_PROPERTY, 0 },
31d9e93152SAdrien Destugues 		{ B_DIRECT_SPECIFIER, B_DIRECT_SPECIFIER, 0 },
32d9e93152SAdrien Destugues 		"get or set the number of data bits (7 or 8)",
33d9e93152SAdrien Destugues 		0, { B_INT32_TYPE }
34d9e93152SAdrien Destugues 	},
35d9e93152SAdrien Destugues 	{ "stopbits",
36d9e93152SAdrien Destugues 		{ B_GET_PROPERTY, B_SET_PROPERTY, 0 },
37d9e93152SAdrien Destugues 		{ B_DIRECT_SPECIFIER, B_DIRECT_SPECIFIER, 0 },
38d9e93152SAdrien Destugues 		"get or set the number of stop bits (1 or 2)",
39d9e93152SAdrien Destugues 		0, { B_INT32_TYPE }
40d9e93152SAdrien Destugues 	},
41d9e93152SAdrien Destugues 	{ "parity",
42d9e93152SAdrien Destugues 		{ B_GET_PROPERTY, B_SET_PROPERTY, 0 },
43d9e93152SAdrien Destugues 		{ B_DIRECT_SPECIFIER, B_DIRECT_SPECIFIER, 0 },
44d9e93152SAdrien Destugues 		"get or set the parity (none, even or odd)",
45d9e93152SAdrien Destugues 		0, { B_STRING_TYPE }
46d9e93152SAdrien Destugues 	},
47d9e93152SAdrien Destugues 	{ "flowcontrol",
48d9e93152SAdrien Destugues 		{ B_GET_PROPERTY, B_SET_PROPERTY, 0 },
49d9e93152SAdrien Destugues 		{ B_DIRECT_SPECIFIER, B_DIRECT_SPECIFIER, 0 },
50d9e93152SAdrien Destugues 		"get or set the flow control (hardware, software, both, or none)",
51d9e93152SAdrien Destugues 		0, { B_STRING_TYPE }
52d9e93152SAdrien Destugues 	},
53d9e93152SAdrien Destugues 	{ "port",
54d9e93152SAdrien Destugues 		{ B_GET_PROPERTY, B_SET_PROPERTY, B_DELETE_PROPERTY, 0 },
55d9e93152SAdrien Destugues 		{ B_DIRECT_SPECIFIER, 0 },
56d9e93152SAdrien Destugues 		"get or set the port device",
57d9e93152SAdrien Destugues 		0, { B_STRING_TYPE }
58d9e93152SAdrien Destugues 	},
59d9e93152SAdrien Destugues 	{ NULL }
60d9e93152SAdrien Destugues };
61d9e93152SAdrien Destugues 
62d9e93152SAdrien Destugues const BPropertyInfo SerialApp::kScriptingProperties(sProperties);
63d9e93152SAdrien Destugues 
64d9e93152SAdrien Destugues 
65dae0a4e0SAdrien Destugues - PulkoMandy SerialApp::SerialApp()
66469e6cd2SAdrien Destugues - PulkoMandy 	: BApplication(SerialApp::kApplicationSignature)
67469e6cd2SAdrien Destugues - PulkoMandy 	, fLogFile(NULL)
68*ce058fa0SAdrien Destugues 	, fFileSender(NULL)
69dae0a4e0SAdrien Destugues - PulkoMandy {
70dae0a4e0SAdrien Destugues - PulkoMandy 	fWindow = new SerialWindow();
71dae0a4e0SAdrien Destugues - PulkoMandy 
72f441fd03SAdrien Destugues - PulkoMandy 	fSerialLock = create_sem(0, "Serial port lock");
73dae0a4e0SAdrien Destugues - PulkoMandy 	thread_id id = spawn_thread(PollSerial, "Serial port poller",
74dae0a4e0SAdrien Destugues - PulkoMandy 		B_LOW_PRIORITY, this);
75dae0a4e0SAdrien Destugues - PulkoMandy 	resume_thread(id);
76dae0a4e0SAdrien Destugues - PulkoMandy }
77dae0a4e0SAdrien Destugues - PulkoMandy 
78dae0a4e0SAdrien Destugues - PulkoMandy 
79469e6cd2SAdrien Destugues - PulkoMandy SerialApp::~SerialApp()
80469e6cd2SAdrien Destugues - PulkoMandy {
81469e6cd2SAdrien Destugues - PulkoMandy 	delete fLogFile;
82*ce058fa0SAdrien Destugues 	delete fFileSender;
83469e6cd2SAdrien Destugues - PulkoMandy }
84469e6cd2SAdrien Destugues - PulkoMandy 
85469e6cd2SAdrien Destugues - PulkoMandy 
86dae0a4e0SAdrien Destugues - PulkoMandy void SerialApp::ReadyToRun()
87dae0a4e0SAdrien Destugues - PulkoMandy {
88ccc6b9beSAdrien Destugues 	LoadSettings();
89dae0a4e0SAdrien Destugues - PulkoMandy 	fWindow->Show();
90dae0a4e0SAdrien Destugues - PulkoMandy }
91dae0a4e0SAdrien Destugues - PulkoMandy 
92dae0a4e0SAdrien Destugues - PulkoMandy 
93dae0a4e0SAdrien Destugues - PulkoMandy void SerialApp::MessageReceived(BMessage* message)
94dae0a4e0SAdrien Destugues - PulkoMandy {
951e8185d9SAdrien Destugues 	switch (message->what) {
96dae0a4e0SAdrien Destugues - PulkoMandy 		case kMsgOpenPort:
97dae0a4e0SAdrien Destugues - PulkoMandy 		{
981e8185d9SAdrien Destugues 			if (message->FindString("port name", &fPortPath) == B_OK) {
99ccc6b9beSAdrien Destugues 				fSerialPort.Open(fPortPath);
100f441fd03SAdrien Destugues - PulkoMandy 				release_sem(fSerialLock);
10104434656SAdrien Destugues - PulkoMandy 			} else {
10204434656SAdrien Destugues - PulkoMandy 				fSerialPort.Close();
10304434656SAdrien Destugues - PulkoMandy 			}
104*ce058fa0SAdrien Destugues 
105*ce058fa0SAdrien Destugues 			// Forward to the window so it can enable/disable menu items
106*ce058fa0SAdrien Destugues 			fWindow->PostMessage(message);
107d9e93152SAdrien Destugues 			return;
108dae0a4e0SAdrien Destugues - PulkoMandy 		}
109dae0a4e0SAdrien Destugues - PulkoMandy 		case kMsgDataRead:
110dae0a4e0SAdrien Destugues - PulkoMandy 		{
111*ce058fa0SAdrien Destugues 			const char* bytes;
112*ce058fa0SAdrien Destugues 			ssize_t length;
113*ce058fa0SAdrien Destugues 			message->FindData("data", B_RAW_TYPE, (const void**)&bytes,
114*ce058fa0SAdrien Destugues 				&length);
115*ce058fa0SAdrien Destugues 
116*ce058fa0SAdrien Destugues 			if (fFileSender != NULL) {
117*ce058fa0SAdrien Destugues 				if (fFileSender->BytesReceived(bytes, length)) {
118*ce058fa0SAdrien Destugues 					delete fFileSender;
119*ce058fa0SAdrien Destugues 					fFileSender = NULL;
120*ce058fa0SAdrien Destugues 				}
121*ce058fa0SAdrien Destugues 			} else {
122f441fd03SAdrien Destugues - PulkoMandy 				// forward the message to the window, which will display the
123f441fd03SAdrien Destugues - PulkoMandy 				// incoming data
124f441fd03SAdrien Destugues - PulkoMandy 				fWindow->PostMessage(message);
125469e6cd2SAdrien Destugues - PulkoMandy 
1261e8185d9SAdrien Destugues 				if (fLogFile) {
127d9e93152SAdrien Destugues 					if (fLogFile->Write(bytes, length) != length) {
128d481cb73SAdrien Destugues - PulkoMandy 						// TODO error handling
129469e6cd2SAdrien Destugues - PulkoMandy 					}
130469e6cd2SAdrien Destugues - PulkoMandy 				}
131*ce058fa0SAdrien Destugues 			}
132469e6cd2SAdrien Destugues - PulkoMandy 
133d9e93152SAdrien Destugues 			return;
134dae0a4e0SAdrien Destugues - PulkoMandy 		}
135f441fd03SAdrien Destugues - PulkoMandy 		case kMsgDataWrite:
136f441fd03SAdrien Destugues - PulkoMandy 		{
137*ce058fa0SAdrien Destugues 			// Do not allow sending if a file transfer is in progress.
138*ce058fa0SAdrien Destugues 			if (fFileSender != NULL)
139*ce058fa0SAdrien Destugues 				return;
140*ce058fa0SAdrien Destugues 
141f441fd03SAdrien Destugues - PulkoMandy 			const char* bytes;
142f441fd03SAdrien Destugues - PulkoMandy 			ssize_t size;
143f441fd03SAdrien Destugues - PulkoMandy 
144492ac416SAdrien Destugues 			if (message->FindData("data", B_RAW_TYPE, (const void**)&bytes,
145d9e93152SAdrien Destugues 					&size) == B_OK)
146f441fd03SAdrien Destugues - PulkoMandy 				fSerialPort.Write(bytes, size);
147d9e93152SAdrien Destugues 			return;
14804434656SAdrien Destugues - PulkoMandy 		}
149469e6cd2SAdrien Destugues - PulkoMandy 		case kMsgLogfile:
150469e6cd2SAdrien Destugues - PulkoMandy 		{
151469e6cd2SAdrien Destugues - PulkoMandy 			entry_ref parent;
152469e6cd2SAdrien Destugues - PulkoMandy 			const char* filename;
153469e6cd2SAdrien Destugues - PulkoMandy 
154469e6cd2SAdrien Destugues - PulkoMandy 			if (message->FindRef("directory", &parent) == B_OK
1551e8185d9SAdrien Destugues 				&& message->FindString("name", &filename) == B_OK) {
156469e6cd2SAdrien Destugues - PulkoMandy 				delete fLogFile;
157469e6cd2SAdrien Destugues - PulkoMandy 				BDirectory directory(&parent);
158469e6cd2SAdrien Destugues - PulkoMandy 				fLogFile = new BFile(&directory, filename,
159469e6cd2SAdrien Destugues - PulkoMandy 					B_WRITE_ONLY | B_CREATE_FILE | B_OPEN_AT_END);
160469e6cd2SAdrien Destugues - PulkoMandy 				status_t error = fLogFile->InitCheck();
161469e6cd2SAdrien Destugues - PulkoMandy 				if (error != B_OK)
162469e6cd2SAdrien Destugues - PulkoMandy 					puts(strerror(error));
1631e8185d9SAdrien Destugues 			} else
164469e6cd2SAdrien Destugues - PulkoMandy 				debugger("Invalid BMessage received");
165d9e93152SAdrien Destugues 			return;
166469e6cd2SAdrien Destugues - PulkoMandy 		}
167*ce058fa0SAdrien Destugues 		case kMsgSendXmodem:
168*ce058fa0SAdrien Destugues 		{
169*ce058fa0SAdrien Destugues 			entry_ref ref;
170*ce058fa0SAdrien Destugues 
171*ce058fa0SAdrien Destugues 			if (message->FindRef("refs", &ref) == B_OK) {
172*ce058fa0SAdrien Destugues 				BFile* file = new BFile(&ref, B_READ_ONLY);
173*ce058fa0SAdrien Destugues 				status_t error = file->InitCheck();
174*ce058fa0SAdrien Destugues 				if (error != B_OK)
175*ce058fa0SAdrien Destugues 					puts(strerror(error));
176*ce058fa0SAdrien Destugues 				else {
177*ce058fa0SAdrien Destugues 					delete fFileSender;
178*ce058fa0SAdrien Destugues 					fFileSender = new XModemSender(file, &fSerialPort, fWindow);
179*ce058fa0SAdrien Destugues 				}
180*ce058fa0SAdrien Destugues 			} else {
181*ce058fa0SAdrien Destugues 				message->PrintToStream();
182*ce058fa0SAdrien Destugues 				debugger("Invalid BMessage received");
183*ce058fa0SAdrien Destugues 			}
184*ce058fa0SAdrien Destugues 			return;
185*ce058fa0SAdrien Destugues 		}
18696e59ccaSAdrien Destugues 		case kMsgCustomBaudrate:
18796e59ccaSAdrien Destugues 		{
18896e59ccaSAdrien Destugues 			// open the custom baudrate selector window
18996e59ccaSAdrien Destugues 			CustomRateWindow* window = new CustomRateWindow(fSerialPort.DataRate());
19096e59ccaSAdrien Destugues 			window->Show();
19196e59ccaSAdrien Destugues 			return;
19296e59ccaSAdrien Destugues 		}
19304434656SAdrien Destugues - PulkoMandy 		case kMsgSettings:
19404434656SAdrien Destugues - PulkoMandy 		{
19504434656SAdrien Destugues - PulkoMandy 			int32 baudrate;
19604434656SAdrien Destugues - PulkoMandy 			stop_bits stopBits;
19704434656SAdrien Destugues - PulkoMandy 			data_bits dataBits;
19804434656SAdrien Destugues - PulkoMandy 			parity_mode parity;
19904434656SAdrien Destugues - PulkoMandy 			uint32 flowcontrol;
20004434656SAdrien Destugues - PulkoMandy 
20104434656SAdrien Destugues - PulkoMandy 			if (message->FindInt32("databits", (int32*)&dataBits) == B_OK)
20204434656SAdrien Destugues - PulkoMandy 				fSerialPort.SetDataBits(dataBits);
20304434656SAdrien Destugues - PulkoMandy 
20404434656SAdrien Destugues - PulkoMandy 			if (message->FindInt32("stopbits", (int32*)&stopBits) == B_OK)
20504434656SAdrien Destugues - PulkoMandy 				fSerialPort.SetStopBits(stopBits);
20604434656SAdrien Destugues - PulkoMandy 
20704434656SAdrien Destugues - PulkoMandy 			if (message->FindInt32("parity", (int32*)&parity) == B_OK)
20804434656SAdrien Destugues - PulkoMandy 				fSerialPort.SetParityMode(parity);
20904434656SAdrien Destugues - PulkoMandy 
21004434656SAdrien Destugues - PulkoMandy 			if (message->FindInt32("flowcontrol", (int32*)&flowcontrol) == B_OK)
21104434656SAdrien Destugues - PulkoMandy 				fSerialPort.SetFlowControl(flowcontrol);
21204434656SAdrien Destugues - PulkoMandy 
21304434656SAdrien Destugues - PulkoMandy 			if (message->FindInt32("baudrate", &baudrate) == B_OK) {
214e2367275SAdrien Destugues 				data_rate rate = (data_rate)baudrate;
21504434656SAdrien Destugues - PulkoMandy 				fSerialPort.SetDataRate(rate);
21604434656SAdrien Destugues - PulkoMandy 			}
21704434656SAdrien Destugues - PulkoMandy 
218d9e93152SAdrien Destugues 			return;
219d9e93152SAdrien Destugues 		}
220d9e93152SAdrien Destugues 	}
221d9e93152SAdrien Destugues 
222d9e93152SAdrien Destugues 	// Handle scripting messages
223d9e93152SAdrien Destugues 	if (message->HasSpecifiers()) {
224d9e93152SAdrien Destugues 		BMessage specifier;
225d9e93152SAdrien Destugues 		int32 what;
226d9e93152SAdrien Destugues 		int32 index;
227d9e93152SAdrien Destugues 		const char* property;
228d9e93152SAdrien Destugues 
229d9e93152SAdrien Destugues 		BMessage reply(B_REPLY);
230d9e93152SAdrien Destugues 		BMessage settings(kMsgSettings);
231d9e93152SAdrien Destugues 		bool settingsChanged = false;
232d9e93152SAdrien Destugues 
233d9e93152SAdrien Destugues 		if (message->GetCurrentSpecifier(&index, &specifier, &what, &property)
234d9e93152SAdrien Destugues 			== B_OK) {
235d9e93152SAdrien Destugues 			switch (kScriptingProperties.FindMatch(message, index, &specifier,
236d9e93152SAdrien Destugues 				what, property)) {
237d9e93152SAdrien Destugues 				case 0: // baudrate
238d9e93152SAdrien Destugues 					if (message->what == B_GET_PROPERTY) {
239d9e93152SAdrien Destugues 						reply.AddInt32("result", fSerialPort.DataRate());
240d9e93152SAdrien Destugues 						message->SendReply(&reply);
241d9e93152SAdrien Destugues 						return;
242d9e93152SAdrien Destugues 					}
243d9e93152SAdrien Destugues 					if (message->what == B_SET_PROPERTY) {
244d9e93152SAdrien Destugues 						int32 rate = message->FindInt32("data");
245d9e93152SAdrien Destugues 						settingsChanged = true;
246d9e93152SAdrien Destugues 						settings.AddInt32("baudrate", rate);
247d9e93152SAdrien Destugues 					}
248d9e93152SAdrien Destugues 					break;
249d9e93152SAdrien Destugues 				case 1: // data bits
250d9e93152SAdrien Destugues 					if (message->what == B_GET_PROPERTY) {
251d9e93152SAdrien Destugues 						reply.AddInt32("result", fSerialPort.DataBits() + 7);
252d9e93152SAdrien Destugues 						message->SendReply(&reply);
253d9e93152SAdrien Destugues 						return;
254d9e93152SAdrien Destugues 					}
255d9e93152SAdrien Destugues 					if (message->what == B_SET_PROPERTY) {
256d9e93152SAdrien Destugues 						int32 bits = message->FindInt32("data");
257d9e93152SAdrien Destugues 						settingsChanged = true;
258d9e93152SAdrien Destugues 						settings.AddInt32("databits", bits - 7);
259d9e93152SAdrien Destugues 					}
260d9e93152SAdrien Destugues 					break;
261d9e93152SAdrien Destugues 				case 2: // stop bits
262d9e93152SAdrien Destugues 					if (message->what == B_GET_PROPERTY) {
263d9e93152SAdrien Destugues 						reply.AddInt32("result", fSerialPort.StopBits() + 1);
264d9e93152SAdrien Destugues 						message->SendReply(&reply);
265d9e93152SAdrien Destugues 						return;
266d9e93152SAdrien Destugues 					}
267d9e93152SAdrien Destugues 					if (message->what == B_SET_PROPERTY) {
268d9e93152SAdrien Destugues 						int32 bits = message->FindInt32("data");
269d9e93152SAdrien Destugues 						settingsChanged = true;
270d9e93152SAdrien Destugues 						settings.AddInt32("stopbits", bits - 1);
271d9e93152SAdrien Destugues 					}
272d9e93152SAdrien Destugues 					break;
273d9e93152SAdrien Destugues 				case 3: // parity
274d9e93152SAdrien Destugues 				{
275d9e93152SAdrien Destugues 					static const char* strings[] = {"none", "odd", "even"};
276d9e93152SAdrien Destugues 					if (message->what == B_GET_PROPERTY) {
277d9e93152SAdrien Destugues 						reply.AddString("result",
278d9e93152SAdrien Destugues 							strings[fSerialPort.ParityMode()]);
279d9e93152SAdrien Destugues 						message->SendReply(&reply);
280d9e93152SAdrien Destugues 						return;
281d9e93152SAdrien Destugues 					}
282d9e93152SAdrien Destugues 					if (message->what == B_SET_PROPERTY) {
283d9e93152SAdrien Destugues 						BString bits = message->FindString("data");
284d9e93152SAdrien Destugues 						int i;
285d9e93152SAdrien Destugues 						for (i = 0; i < 3; i++) {
286d9e93152SAdrien Destugues 							if (bits == strings[i])
28704434656SAdrien Destugues - PulkoMandy 								break;
288f441fd03SAdrien Destugues - PulkoMandy 						}
289d9e93152SAdrien Destugues 
290d9e93152SAdrien Destugues 						if (i < 3) {
291d9e93152SAdrien Destugues 							settingsChanged = true;
292d9e93152SAdrien Destugues 							settings.AddInt32("parity", i);
293dae0a4e0SAdrien Destugues - PulkoMandy 						}
294dae0a4e0SAdrien Destugues - PulkoMandy 					}
295d9e93152SAdrien Destugues 					break;
296d9e93152SAdrien Destugues 				}
297d9e93152SAdrien Destugues 				case 4: // flow control
298d9e93152SAdrien Destugues 				{
299d9e93152SAdrien Destugues 					static const char* strings[] = {"none", "hardware",
300d9e93152SAdrien Destugues 						"software", "both"};
301d9e93152SAdrien Destugues 					if (message->what == B_GET_PROPERTY) {
302d9e93152SAdrien Destugues 						reply.AddString("result",
303d9e93152SAdrien Destugues 							strings[fSerialPort.FlowControl()]);
304d9e93152SAdrien Destugues 						message->SendReply(&reply);
305d9e93152SAdrien Destugues 						return;
306d9e93152SAdrien Destugues 					}
307d9e93152SAdrien Destugues 					if (message->what == B_SET_PROPERTY) {
308d9e93152SAdrien Destugues 						BString bits = message->FindString("data");
309d9e93152SAdrien Destugues 						int i;
310d9e93152SAdrien Destugues 						for (i = 0; i < 4; i++) {
311d9e93152SAdrien Destugues 							if (bits == strings[i])
312d9e93152SAdrien Destugues 								break;
313d9e93152SAdrien Destugues 						}
314d9e93152SAdrien Destugues 
315d9e93152SAdrien Destugues 						if (i < 4) {
316d9e93152SAdrien Destugues 							settingsChanged = true;
317d9e93152SAdrien Destugues 							settings.AddInt32("flowcontrol", i);
318d9e93152SAdrien Destugues 						}
319d9e93152SAdrien Destugues 					}
320d9e93152SAdrien Destugues 					break;
321d9e93152SAdrien Destugues 				}
322d9e93152SAdrien Destugues 				case 5: // port
323d9e93152SAdrien Destugues 					if (message->what == B_GET_PROPERTY) {
324d9e93152SAdrien Destugues 						reply.AddString("port", GetPort());
325d9e93152SAdrien Destugues 						message->SendReply(&reply);
326d9e93152SAdrien Destugues 					} else if (message->what == B_DELETE_PROPERTY
327d9e93152SAdrien Destugues 						|| message->what == B_SET_PROPERTY) {
328d9e93152SAdrien Destugues 						BString path = message->FindString("data");
329d9e93152SAdrien Destugues 						BMessage openMessage(kMsgOpenPort);
330d9e93152SAdrien Destugues 						openMessage.AddString("port name", path);
331d9e93152SAdrien Destugues 						PostMessage(&openMessage);
332d9e93152SAdrien Destugues 						fWindow->PostMessage(&openMessage);
333d9e93152SAdrien Destugues 					}
334d9e93152SAdrien Destugues 					return;
335d9e93152SAdrien Destugues 			}
336d9e93152SAdrien Destugues 		}
337d9e93152SAdrien Destugues 
338d9e93152SAdrien Destugues 		if (settingsChanged) {
339d9e93152SAdrien Destugues 			PostMessage(&settings);
340d9e93152SAdrien Destugues 			fWindow->PostMessage(&settings);
341d9e93152SAdrien Destugues 			return;
342d9e93152SAdrien Destugues 		}
343d9e93152SAdrien Destugues 	}
344d9e93152SAdrien Destugues 
345d9e93152SAdrien Destugues 	BApplication::MessageReceived(message);
346d9e93152SAdrien Destugues }
347dae0a4e0SAdrien Destugues - PulkoMandy 
348dae0a4e0SAdrien Destugues - PulkoMandy 
349ccc6b9beSAdrien Destugues bool SerialApp::QuitRequested()
350ccc6b9beSAdrien Destugues {
351ccc6b9beSAdrien Destugues 	if (BApplication::QuitRequested()) {
352ccc6b9beSAdrien Destugues 		SaveSettings();
353ccc6b9beSAdrien Destugues 		return true;
354ccc6b9beSAdrien Destugues 	}
355ccc6b9beSAdrien Destugues 	return false;
356ccc6b9beSAdrien Destugues }
357ccc6b9beSAdrien Destugues 
358ccc6b9beSAdrien Destugues 
359ccc6b9beSAdrien Destugues const BString& SerialApp::GetPort()
360ccc6b9beSAdrien Destugues {
361ccc6b9beSAdrien Destugues 	return fPortPath;
362ccc6b9beSAdrien Destugues }
363ccc6b9beSAdrien Destugues 
364ccc6b9beSAdrien Destugues 
365ccc6b9beSAdrien Destugues void SerialApp::LoadSettings()
366ccc6b9beSAdrien Destugues {
367ccc6b9beSAdrien Destugues 	BPath path;
368ccc6b9beSAdrien Destugues 	find_directory(B_USER_SETTINGS_DIRECTORY, &path);
369ccc6b9beSAdrien Destugues 	path.Append("SerialConnect");
370ccc6b9beSAdrien Destugues 
371ccc6b9beSAdrien Destugues 	BFile file(path.Path(), B_READ_ONLY);
372ccc6b9beSAdrien Destugues 	BMessage message(kMsgSettings);
3731e8185d9SAdrien Destugues 	if (message.Unflatten(&file) != B_OK) {
374ccc6b9beSAdrien Destugues 		message.AddInt32("parity", fSerialPort.ParityMode());
375ccc6b9beSAdrien Destugues 		message.AddInt32("databits", fSerialPort.DataBits());
376ccc6b9beSAdrien Destugues 		message.AddInt32("stopbits", fSerialPort.StopBits());
377ccc6b9beSAdrien Destugues 		message.AddInt32("baudrate", fSerialPort.DataRate());
378ccc6b9beSAdrien Destugues 		message.AddInt32("flowcontrol", fSerialPort.FlowControl());
379ccc6b9beSAdrien Destugues 	}
380ccc6b9beSAdrien Destugues 
381ccc6b9beSAdrien Destugues 	be_app->PostMessage(&message);
382ccc6b9beSAdrien Destugues 	fWindow->PostMessage(&message);
383ccc6b9beSAdrien Destugues }
384ccc6b9beSAdrien Destugues 
385ccc6b9beSAdrien Destugues 
386ccc6b9beSAdrien Destugues void SerialApp::SaveSettings()
387ccc6b9beSAdrien Destugues {
388ccc6b9beSAdrien Destugues 	BMessage message(kMsgSettings);
389ccc6b9beSAdrien Destugues 	message.AddInt32("parity", fSerialPort.ParityMode());
390ccc6b9beSAdrien Destugues 	message.AddInt32("databits", fSerialPort.DataBits());
391ccc6b9beSAdrien Destugues 	message.AddInt32("stopbits", fSerialPort.StopBits());
392ccc6b9beSAdrien Destugues 	message.AddInt32("baudrate", fSerialPort.DataRate());
393ccc6b9beSAdrien Destugues 	message.AddInt32("flowcontrol", fSerialPort.FlowControl());
394ccc6b9beSAdrien Destugues 
395ccc6b9beSAdrien Destugues 	BPath path;
396ccc6b9beSAdrien Destugues 	find_directory(B_USER_SETTINGS_DIRECTORY, &path);
397ccc6b9beSAdrien Destugues 	path.Append("SerialConnect");
398ccc6b9beSAdrien Destugues 
399ccc6b9beSAdrien Destugues 	BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE);
400ccc6b9beSAdrien Destugues 	message.Flatten(&file);
401ccc6b9beSAdrien Destugues }
402ccc6b9beSAdrien Destugues 
403ccc6b9beSAdrien Destugues 
404dae0a4e0SAdrien Destugues - PulkoMandy /* static */
405dae0a4e0SAdrien Destugues - PulkoMandy status_t SerialApp::PollSerial(void*)
406dae0a4e0SAdrien Destugues - PulkoMandy {
407dae0a4e0SAdrien Destugues - PulkoMandy 	SerialApp* application = (SerialApp*)be_app;
408dae0a4e0SAdrien Destugues - PulkoMandy 	char buffer[256];
409dae0a4e0SAdrien Destugues - PulkoMandy 
4101e8185d9SAdrien Destugues 	for (;;) {
411dae0a4e0SAdrien Destugues - PulkoMandy 		ssize_t bytesRead;
412dae0a4e0SAdrien Destugues - PulkoMandy 
413e2367275SAdrien Destugues 		bytesRead = application->fSerialPort.Read(buffer, sizeof(buffer));
4141e8185d9SAdrien Destugues 		if (bytesRead == B_FILE_ERROR) {
415dae0a4e0SAdrien Destugues - PulkoMandy 			// Port is not open - wait for it and start over
416f441fd03SAdrien Destugues - PulkoMandy 			acquire_sem(application->fSerialLock);
417f441fd03SAdrien Destugues - PulkoMandy 		} else if (bytesRead > 0) {
418dae0a4e0SAdrien Destugues - PulkoMandy 			// We read something, forward it to the app for handling
419dae0a4e0SAdrien Destugues - PulkoMandy 			BMessage* serialData = new BMessage(kMsgDataRead);
420f441fd03SAdrien Destugues - PulkoMandy 			serialData->AddData("data", B_RAW_TYPE, buffer, bytesRead);
421dae0a4e0SAdrien Destugues - PulkoMandy 			be_app_messenger.SendMessage(serialData);
422dae0a4e0SAdrien Destugues - PulkoMandy 		}
423dae0a4e0SAdrien Destugues - PulkoMandy 	}
42447b44bbeSPhilippe Houdoin 
42547b44bbeSPhilippe Houdoin 	// Should not reach this line anyway...
42647b44bbeSPhilippe Houdoin 	return B_OK;
427dae0a4e0SAdrien Destugues - PulkoMandy }
428c53c7ddeSAdrien Destugues 
429dae0a4e0SAdrien Destugues - PulkoMandy 
430dae0a4e0SAdrien Destugues - PulkoMandy const char* SerialApp::kApplicationSignature
431dae0a4e0SAdrien Destugues - PulkoMandy 	= "application/x-vnd.haiku.SerialConnect";
432dae0a4e0SAdrien Destugues - PulkoMandy 
433dae0a4e0SAdrien Destugues - PulkoMandy 
434dae0a4e0SAdrien Destugues - PulkoMandy int main(int argc, char** argv)
435dae0a4e0SAdrien Destugues - PulkoMandy {
436dae0a4e0SAdrien Destugues - PulkoMandy 	SerialApp app;
437dae0a4e0SAdrien Destugues - PulkoMandy 	app.Run();
438dae0a4e0SAdrien Destugues - PulkoMandy }
439d9e93152SAdrien Destugues 
440d9e93152SAdrien Destugues 
441d9e93152SAdrien Destugues status_t
442d9e93152SAdrien Destugues SerialApp::GetSupportedSuites(BMessage* message)
443d9e93152SAdrien Destugues {
444d9e93152SAdrien Destugues 	message->AddString("suites", "suite/vnd.Haiku-SerialPort");
445d9e93152SAdrien Destugues 	message->AddFlat("messages", &kScriptingProperties);
446d9e93152SAdrien Destugues 	return BApplication::GetSupportedSuites(message);
447d9e93152SAdrien Destugues }
448d9e93152SAdrien Destugues 
449d9e93152SAdrien Destugues 
450d9e93152SAdrien Destugues BHandler*
451d9e93152SAdrien Destugues SerialApp::ResolveSpecifier(BMessage* message, int32 index,
452d9e93152SAdrien Destugues 	BMessage* specifier, int32 what, const char* property)
453d9e93152SAdrien Destugues {
454d9e93152SAdrien Destugues 	if (kScriptingProperties.FindMatch(message, index, specifier, what,
455d9e93152SAdrien Destugues 		property) >= 0)
456d9e93152SAdrien Destugues 		return this;
457d9e93152SAdrien Destugues 
458d9e93152SAdrien Destugues 	return BApplication::ResolveSpecifier(message, index, specifier, what,
459d9e93152SAdrien Destugues 		property);
460d9e93152SAdrien Destugues }
461