1dae0a4e0SAdrien Destugues - PulkoMandy/*
2ce058fa0SAdrien 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
7469e6cd2SAdrien Destugues - PulkoMandy#include "SerialApp.h"
8469e6cd2SAdrien Destugues - PulkoMandy
9f441fd03SAdrien Destugues - PulkoMandy#include <stdio.h>
10469e6cd2SAdrien Destugues - PulkoMandy#include <string.h>
11f441fd03SAdrien 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>
17dae0a4e0SAdrien Destugues - PulkoMandy
1896e59ccaSAdrien Destugues#include "CustomRateWindow.h"
19dae0a4e0SAdrien Destugues - PulkoMandy#include "SerialWindow.h"
20dae0a4e0SAdrien Destugues - PulkoMandy
21dae0a4e0SAdrien Destugues - PulkoMandy
22d9e93152SAdrien Destuguesstatic 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	},
5916af9b4cSHumdinger	{ 0 }
60d9e93152SAdrien Destugues};
61d9e93152SAdrien Destugues
62d9e93152SAdrien Destuguesconst BPropertyInfo SerialApp::kScriptingProperties(sProperties);
63d9e93152SAdrien Destugues
64d9e93152SAdrien Destugues
65dae0a4e0SAdrien Destugues - PulkoMandySerialApp::SerialApp()
66469e6cd2SAdrien Destugues - PulkoMandy	: BApplication(SerialApp::kApplicationSignature)
67469e6cd2SAdrien Destugues - PulkoMandy	, fLogFile(NULL)
68ce058fa0SAdrien 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 - PulkoMandySerialApp::~SerialApp()
80469e6cd2SAdrien Destugues - PulkoMandy{
81469e6cd2SAdrien Destugues - PulkoMandy	delete fLogFile;
82ce058fa0SAdrien Destugues	delete fFileSender;
83469e6cd2SAdrien Destugues - PulkoMandy}
84469e6cd2SAdrien Destugues - PulkoMandy
85469e6cd2SAdrien Destugues - PulkoMandy
86dae0a4e0SAdrien Destugues - PulkoMandyvoid SerialApp::ReadyToRun()
87dae0a4e0SAdrien Destugues - PulkoMandy{
88ccc6b9beSAdrien Destugues	LoadSettings();
89dae0a4e0SAdrien Destugues - PulkoMandy	fWindow->Show();
90dae0a4e0SAdrien Destugues - PulkoMandy}
91dae0a4e0SAdrien Destugues - PulkoMandy
92dae0a4e0SAdrien Destugues - PulkoMandy
93dae0a4e0SAdrien Destugues - PulkoMandyvoid 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);
10004434656SAdrien Destugues - PulkoMandy				release_sem(fSerialLock);
10104434656SAdrien Destugues - PulkoMandy			} else {
10204434656SAdrien Destugues - PulkoMandy				fSerialPort.Close();
10304434656SAdrien Destugues - PulkoMandy			}
104ce058fa0SAdrien Destugues
105ce058fa0SAdrien Destugues			// Forward to the window so it can enable/disable menu items
106ce058fa0SAdrien Destugues			fWindow->PostMessage(message);
107d9e93152SAdrien Destugues			return;
108dae0a4e0SAdrien Destugues - PulkoMandy		}
109dae0a4e0SAdrien Destugues - PulkoMandy		case kMsgDataRead:
110dae0a4e0SAdrien Destugues - PulkoMandy		{
111cd4d3a30SAdrien Destugues			const uint8_t* bytes;
112ce058fa0SAdrien Destugues			ssize_t length;
113ce058fa0SAdrien Destugues			message->FindData("data", B_RAW_TYPE, (const void**)&bytes,
114ce058fa0SAdrien Destugues				&length);
115ce058fa0SAdrien Destugues
116ce058fa0SAdrien Destugues			if (fFileSender != NULL) {
117ce058fa0SAdrien Destugues				if (fFileSender->BytesReceived(bytes, length)) {
118ce058fa0SAdrien Destugues					delete fFileSender;
119ce058fa0SAdrien Destugues					fFileSender = NULL;
120ce058fa0SAdrien Destugues				}
121ce058fa0SAdrien Destugues			} else {
122ce058fa0SAdrien Destugues				// forward the message to the window, which will display the
123ce058fa0SAdrien Destugues				// incoming data
124ce058fa0SAdrien Destugues				fWindow->PostMessage(message);
125ce058fa0SAdrien Destugues
126ce058fa0SAdrien Destugues				if (fLogFile) {
127ce058fa0SAdrien Destugues					if (fLogFile->Write(bytes, length) != length) {
128ce058fa0SAdrien Destugues						// TODO error handling
129ce058fa0SAdrien Destugues					}
130469e6cd2SAdrien Destugues - PulkoMandy				}
131469e6cd2SAdrien Destugues - PulkoMandy			}
132469e6cd2SAdrien Destugues - PulkoMandy
133d9e93152SAdrien Destugues			return;
134dae0a4e0SAdrien Destugues - PulkoMandy		}
135f441fd03SAdrien Destugues - PulkoMandy		case kMsgDataWrite:
136f441fd03SAdrien Destugues - PulkoMandy		{
137ce058fa0SAdrien Destugues			// Do not allow sending if a file transfer is in progress.
138ce058fa0SAdrien Destugues			if (fFileSender != NULL)
139ce058fa0SAdrien Destugues				return;
140ce058fa0SAdrien 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)
146d9e93152SAdrien Destugues				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();
161c53c7ddeSAdrien Destugues				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		}
1678bff17cfSAdrien Destugues		case kMsgSendFile:
168ce058fa0SAdrien Destugues		{
169ce058fa0SAdrien Destugues			entry_ref ref;
170ce058fa0SAdrien Destugues
1718bff17cfSAdrien Destugues			BString protocol = message->FindString("protocol");
1728bff17cfSAdrien Destugues
173ce058fa0SAdrien Destugues			if (message->FindRef("refs", &ref) == B_OK) {
174ce058fa0SAdrien Destugues				BFile* file = new BFile(&ref, B_READ_ONLY);
175ce058fa0SAdrien Destugues				status_t error = file->InitCheck();
176ce058fa0SAdrien Destugues				if (error != B_OK)
177ce058fa0SAdrien Destugues					puts(strerror(error));
178ce058fa0SAdrien Destugues				else {
179ce058fa0SAdrien Destugues					delete fFileSender;
1808bff17cfSAdrien Destugues					if (protocol == "xmodem")
1818bff17cfSAdrien Destugues						fFileSender = new XModemSender(file, &fSerialPort, fWindow);
1828bff17cfSAdrien Destugues					else
1838bff17cfSAdrien Destugues						fFileSender = new RawSender(file, &fSerialPort, fWindow);
184ce058fa0SAdrien Destugues				}
185ce058fa0SAdrien Destugues			} else {
186ce058fa0SAdrien Destugues				message->PrintToStream();
187ce058fa0SAdrien Destugues				debugger("Invalid BMessage received");
188ce058fa0SAdrien Destugues			}
189ce058fa0SAdrien Destugues			return;
190ce058fa0SAdrien Destugues		}
19196e59ccaSAdrien Destugues		case kMsgCustomBaudrate:
19296e59ccaSAdrien Destugues		{
19396e59ccaSAdrien Destugues			// open the custom baudrate selector window
19496e59ccaSAdrien Destugues			CustomRateWindow* window = new CustomRateWindow(fSerialPort.DataRate());
19596e59ccaSAdrien Destugues			window->Show();
19696e59ccaSAdrien Destugues			return;
19796e59ccaSAdrien Destugues		}
19804434656SAdrien Destugues - PulkoMandy		case kMsgSettings:
19904434656SAdrien Destugues - PulkoMandy		{
20004434656SAdrien Destugues - PulkoMandy			int32 baudrate;
20104434656SAdrien Destugues - PulkoMandy			stop_bits stopBits;
20204434656SAdrien Destugues - PulkoMandy			data_bits dataBits;
20304434656SAdrien Destugues - PulkoMandy			parity_mode parity;
20404434656SAdrien Destugues - PulkoMandy			uint32 flowcontrol;
20504434656SAdrien Destugues - PulkoMandy
206c53c7ddeSAdrien Destugues			if (message->FindInt32("databits", (int32*)&dataBits) == B_OK)
20704434656SAdrien Destugues - PulkoMandy				fSerialPort.SetDataBits(dataBits);
20804434656SAdrien Destugues - PulkoMandy
209c53c7ddeSAdrien Destugues			if (message->FindInt32("stopbits", (int32*)&stopBits) == B_OK)
21004434656SAdrien Destugues - PulkoMandy				fSerialPort.SetStopBits(stopBits);
21104434656SAdrien Destugues - PulkoMandy
212c53c7ddeSAdrien Destugues			if (message->FindInt32("parity", (int32*)&parity) == B_OK)
21304434656SAdrien Destugues - PulkoMandy				fSerialPort.SetParityMode(parity);
21404434656SAdrien Destugues - PulkoMandy
215c53c7ddeSAdrien Destugues			if (message->FindInt32("flowcontrol", (int32*)&flowcontrol) == B_OK)
21604434656SAdrien Destugues - PulkoMandy				fSerialPort.SetFlowControl(flowcontrol);
21704434656SAdrien Destugues - PulkoMandy
218c53c7ddeSAdrien Destugues			if (message->FindInt32("baudrate", &baudrate) == B_OK) {
219e2367275SAdrien Destugues				data_rate rate = (data_rate)baudrate;
22004434656SAdrien Destugues - PulkoMandy				fSerialPort.SetDataRate(rate);
22104434656SAdrien Destugues - PulkoMandy			}
22204434656SAdrien Destugues - PulkoMandy
223d9e93152SAdrien Destugues			return;
224d9e93152SAdrien Destugues		}
225d9e93152SAdrien Destugues	}
226d9e93152SAdrien Destugues
227d9e93152SAdrien Destugues	// Handle scripting messages
228d9e93152SAdrien Destugues	if (message->HasSpecifiers()) {
229d9e93152SAdrien Destugues		BMessage specifier;
230d9e93152SAdrien Destugues		int32 what;
231d9e93152SAdrien Destugues		int32 index;
232d9e93152SAdrien Destugues		const char* property;
233d9e93152SAdrien Destugues
234d9e93152SAdrien Destugues		BMessage reply(B_REPLY);
235d9e93152SAdrien Destugues		BMessage settings(kMsgSettings);
236d9e93152SAdrien Destugues		bool settingsChanged = false;
237d9e93152SAdrien Destugues
238d9e93152SAdrien Destugues		if (message->GetCurrentSpecifier(&index, &specifier, &what, &property)
239d9e93152SAdrien Destugues			== B_OK) {
240d9e93152SAdrien Destugues			switch (kScriptingProperties.FindMatch(message, index, &specifier,
241d9e93152SAdrien Destugues				what, property)) {
242d9e93152SAdrien Destugues				case 0: // baudrate
243d9e93152SAdrien Destugues					if (message->what == B_GET_PROPERTY) {
244d9e93152SAdrien Destugues						reply.AddInt32("result", fSerialPort.DataRate());
245d9e93152SAdrien Destugues						message->SendReply(&reply);
246d9e93152SAdrien Destugues						return;
247d9e93152SAdrien Destugues					}
248d9e93152SAdrien Destugues					if (message->what == B_SET_PROPERTY) {
249d9e93152SAdrien Destugues						int32 rate = message->FindInt32("data");
250d9e93152SAdrien Destugues						settingsChanged = true;
251d9e93152SAdrien Destugues						settings.AddInt32("baudrate", rate);
252d9e93152SAdrien Destugues					}
253d9e93152SAdrien Destugues					break;
254d9e93152SAdrien Destugues				case 1: // data bits
255d9e93152SAdrien Destugues					if (message->what == B_GET_PROPERTY) {
256d9e93152SAdrien Destugues						reply.AddInt32("result", fSerialPort.DataBits() + 7);
257d9e93152SAdrien Destugues						message->SendReply(&reply);
258d9e93152SAdrien Destugues						return;
259d9e93152SAdrien Destugues					}
260d9e93152SAdrien Destugues					if (message->what == B_SET_PROPERTY) {
261d9e93152SAdrien Destugues						int32 bits = message->FindInt32("data");
262d9e93152SAdrien Destugues						settingsChanged = true;
263d9e93152SAdrien Destugues						settings.AddInt32("databits", bits - 7);
264d9e93152SAdrien Destugues					}
265d9e93152SAdrien Destugues					break;
266d9e93152SAdrien Destugues				case 2: // stop bits
267d9e93152SAdrien Destugues					if (message->what == B_GET_PROPERTY) {
268d9e93152SAdrien Destugues						reply.AddInt32("result", fSerialPort.StopBits() + 1);
269d9e93152SAdrien Destugues						message->SendReply(&reply);
270d9e93152SAdrien Destugues						return;
271d9e93152SAdrien Destugues					}
272d9e93152SAdrien Destugues					if (message->what == B_SET_PROPERTY) {
273d9e93152SAdrien Destugues						int32 bits = message->FindInt32("data");
274d9e93152SAdrien Destugues						settingsChanged = true;
275d9e93152SAdrien Destugues						settings.AddInt32("stopbits", bits - 1);
276d9e93152SAdrien Destugues					}
277d9e93152SAdrien Destugues					break;
278d9e93152SAdrien Destugues				case 3: // parity
279d9e93152SAdrien Destugues				{
280d9e93152SAdrien Destugues					static const char* strings[] = {"none", "odd", "even"};
281d9e93152SAdrien Destugues					if (message->what == B_GET_PROPERTY) {
282d9e93152SAdrien Destugues						reply.AddString("result",
283d9e93152SAdrien Destugues							strings[fSerialPort.ParityMode()]);
284d9e93152SAdrien Destugues						message->SendReply(&reply);
285d9e93152SAdrien Destugues						return;
286d9e93152SAdrien Destugues					}
287d9e93152SAdrien Destugues					if (message->what == B_SET_PROPERTY) {
288d9e93152SAdrien Destugues						BString bits = message->FindString("data");
289d9e93152SAdrien Destugues						int i;
290d9e93152SAdrien Destugues						for (i = 0; i < 3; i++) {
291d9e93152SAdrien Destugues							if (bits == strings[i])
292d9e93152SAdrien Destugues								break;
293d9e93152SAdrien Destugues						}
294d9e93152SAdrien Destugues
295d9e93152SAdrien Destugues						if (i < 3) {
296d9e93152SAdrien Destugues							settingsChanged = true;
297d9e93152SAdrien Destugues							settings.AddInt32("parity", i);
298d9e93152SAdrien Destugues						}
299d9e93152SAdrien Destugues					}
300d9e93152SAdrien Destugues					break;
301d9e93152SAdrien Destugues				}
302d9e93152SAdrien Destugues				case 4: // flow control
303d9e93152SAdrien Destugues				{
304d9e93152SAdrien Destugues					static const char* strings[] = {"none", "hardware",
305d9e93152SAdrien Destugues						"software", "both"};
306d9e93152SAdrien Destugues					if (message->what == B_GET_PROPERTY) {
307d9e93152SAdrien Destugues						reply.AddString("result",
308d9e93152SAdrien Destugues							strings[fSerialPort.FlowControl()]);
309d9e93152SAdrien Destugues						message->SendReply(&reply);
310d9e93152SAdrien Destugues						return;
311d9e93152SAdrien Destugues					}
312d9e93152SAdrien Destugues					if (message->what == B_SET_PROPERTY) {
313d9e93152SAdrien Destugues						BString bits = message->FindString("data");
314d9e93152SAdrien Destugues						int i;
315d9e93152SAdrien Destugues						for (i = 0; i < 4; i++) {
316d9e93152SAdrien Destugues							if (bits == strings[i])
317d9e93152SAdrien Destugues								break;
318d9e93152SAdrien Destugues						}
319d9e93152SAdrien Destugues
320d9e93152SAdrien Destugues						if (i < 4) {
321d9e93152SAdrien Destugues							settingsChanged = true;
322d9e93152SAdrien Destugues							settings.AddInt32("flowcontrol", i);
323d9e93152SAdrien Destugues						}
324d9e93152SAdrien Destugues					}
325d9e93152SAdrien Destugues					break;
326d9e93152SAdrien Destugues				}
327d9e93152SAdrien Destugues				case 5: // port
328d9e93152SAdrien Destugues					if (message->what == B_GET_PROPERTY) {
329d9e93152SAdrien Destugues						reply.AddString("port", GetPort());
330d9e93152SAdrien Destugues						message->SendReply(&reply);
331d9e93152SAdrien Destugues					} else if (message->what == B_DELETE_PROPERTY
332d9e93152SAdrien Destugues						|| message->what == B_SET_PROPERTY) {
333d9e93152SAdrien Destugues						BString path = message->FindString("data");
334d9e93152SAdrien Destugues						BMessage openMessage(kMsgOpenPort);
335d9e93152SAdrien Destugues						openMessage.AddString("port name", path);
336d9e93152SAdrien Destugues						PostMessage(&openMessage);
337d9e93152SAdrien Destugues						fWindow->PostMessage(&openMessage);
338d9e93152SAdrien Destugues					}
339d9e93152SAdrien Destugues					return;
340d9e93152SAdrien Destugues			}
341d9e93152SAdrien Destugues		}
342d9e93152SAdrien Destugues
343d9e93152SAdrien Destugues		if (settingsChanged) {
344d9e93152SAdrien Destugues			PostMessage(&settings);
345d9e93152SAdrien Destugues			fWindow->PostMessage(&settings);
346d9e93152SAdrien Destugues			return;
347f441fd03SAdrien Destugues - PulkoMandy		}
348dae0a4e0SAdrien Destugues - PulkoMandy	}
349d9e93152SAdrien Destugues
350d9e93152SAdrien Destugues	BApplication::MessageReceived(message);
351dae0a4e0SAdrien Destugues - PulkoMandy}
352dae0a4e0SAdrien Destugues - PulkoMandy
353dae0a4e0SAdrien Destugues - PulkoMandy
354ccc6b9beSAdrien Destuguesbool SerialApp::QuitRequested()
355ccc6b9beSAdrien Destugues{
356c53c7ddeSAdrien Destugues	if (BApplication::QuitRequested()) {
357ccc6b9beSAdrien Destugues		SaveSettings();
358ccc6b9beSAdrien Destugues		return true;
359ccc6b9beSAdrien Destugues	}
360ccc6b9beSAdrien Destugues	return false;
361ccc6b9beSAdrien Destugues}
362ccc6b9beSAdrien Destugues
363ccc6b9beSAdrien Destugues
364ccc6b9beSAdrien Destuguesconst BString& SerialApp::GetPort()
365ccc6b9beSAdrien Destugues{
366ccc6b9beSAdrien Destugues	return fPortPath;
367ccc6b9beSAdrien Destugues}
368ccc6b9beSAdrien Destugues
369ccc6b9beSAdrien Destugues
370ccc6b9beSAdrien Destuguesvoid SerialApp::LoadSettings()
371ccc6b9beSAdrien Destugues{
372ccc6b9beSAdrien Destugues	BPath path;
373ccc6b9beSAdrien Destugues	find_directory(B_USER_SETTINGS_DIRECTORY, &path);
374ccc6b9beSAdrien Destugues	path.Append("SerialConnect");
375ccc6b9beSAdrien Destugues
376ccc6b9beSAdrien Destugues	BFile file(path.Path(), B_READ_ONLY);
377ccc6b9beSAdrien Destugues	BMessage message(kMsgSettings);
3781e8185d9SAdrien Destugues	if (message.Unflatten(&file) != B_OK) {
379ccc6b9beSAdrien Destugues		message.AddInt32("parity", fSerialPort.ParityMode());
380ccc6b9beSAdrien Destugues		message.AddInt32("databits", fSerialPort.DataBits());
381ccc6b9beSAdrien Destugues		message.AddInt32("stopbits", fSerialPort.StopBits());
382ccc6b9beSAdrien Destugues		message.AddInt32("baudrate", fSerialPort.DataRate());
383ccc6b9beSAdrien Destugues		message.AddInt32("flowcontrol", fSerialPort.FlowControl());
384ccc6b9beSAdrien Destugues	}
385ccc6b9beSAdrien Destugues
386ccc6b9beSAdrien Destugues	be_app->PostMessage(&message);
387ccc6b9beSAdrien Destugues	fWindow->PostMessage(&message);
388ccc6b9beSAdrien Destugues}
389ccc6b9beSAdrien Destugues
390ccc6b9beSAdrien Destugues
391ccc6b9beSAdrien Destuguesvoid SerialApp::SaveSettings()
392ccc6b9beSAdrien Destugues{
393ccc6b9beSAdrien Destugues	BMessage message(kMsgSettings);
394ccc6b9beSAdrien Destugues	message.AddInt32("parity", fSerialPort.ParityMode());
395ccc6b9beSAdrien Destugues	message.AddInt32("databits", fSerialPort.DataBits());
396ccc6b9beSAdrien Destugues	message.AddInt32("stopbits", fSerialPort.StopBits());
397ccc6b9beSAdrien Destugues	message.AddInt32("baudrate", fSerialPort.DataRate());
398ccc6b9beSAdrien Destugues	message.AddInt32("flowcontrol", fSerialPort.FlowControl());
399ccc6b9beSAdrien Destugues
400ccc6b9beSAdrien Destugues	BPath path;
401ccc6b9beSAdrien Destugues	find_directory(B_USER_SETTINGS_DIRECTORY, &path);
402ccc6b9beSAdrien Destugues	path.Append("SerialConnect");
403ccc6b9beSAdrien Destugues
404ccc6b9beSAdrien Destugues	BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE);
405ccc6b9beSAdrien Destugues	message.Flatten(&file);
406ccc6b9beSAdrien Destugues}
407ccc6b9beSAdrien Destugues
408ccc6b9beSAdrien Destugues
409dae0a4e0SAdrien Destugues - PulkoMandy/* static */
410dae0a4e0SAdrien Destugues - PulkoMandystatus_t SerialApp::PollSerial(void*)
411dae0a4e0SAdrien Destugues - PulkoMandy{
412dae0a4e0SAdrien Destugues - PulkoMandy	SerialApp* application = (SerialApp*)be_app;
413dae0a4e0SAdrien Destugues - PulkoMandy	char buffer[256];
414dae0a4e0SAdrien Destugues - PulkoMandy
4151e8185d9SAdrien Destugues	for (;;) {
416dae0a4e0SAdrien Destugues - PulkoMandy		ssize_t bytesRead;
417dae0a4e0SAdrien Destugues - PulkoMandy
418e2367275SAdrien Destugues		bytesRead = application->fSerialPort.Read(buffer, sizeof(buffer));
4191e8185d9SAdrien Destugues		if (bytesRead == B_FILE_ERROR) {
420dae0a4e0SAdrien Destugues - PulkoMandy			// Port is not open - wait for it and start over
421f441fd03SAdrien Destugues - PulkoMandy			acquire_sem(application->fSerialLock);
422f441fd03SAdrien Destugues - PulkoMandy		} else if (bytesRead > 0) {
423dae0a4e0SAdrien Destugues - PulkoMandy			// We read something, forward it to the app for handling
424dae0a4e0SAdrien Destugues - PulkoMandy			BMessage* serialData = new BMessage(kMsgDataRead);
425f441fd03SAdrien Destugues - PulkoMandy			serialData->AddData("data", B_RAW_TYPE, buffer, bytesRead);
426dae0a4e0SAdrien Destugues - PulkoMandy			be_app_messenger.SendMessage(serialData);
427dae0a4e0SAdrien Destugues - PulkoMandy		}
428dae0a4e0SAdrien Destugues - PulkoMandy	}
429c53c7ddeSAdrien Destugues
43047b44bbeSPhilippe Houdoin	// Should not reach this line anyway...
43147b44bbeSPhilippe Houdoin	return B_OK;
432dae0a4e0SAdrien Destugues - PulkoMandy}
433dae0a4e0SAdrien Destugues - PulkoMandy
434c53c7ddeSAdrien Destugues
435dae0a4e0SAdrien Destugues - PulkoMandyconst char* SerialApp::kApplicationSignature
436dae0a4e0SAdrien Destugues - PulkoMandy	= "application/x-vnd.haiku.SerialConnect";
437dae0a4e0SAdrien Destugues - PulkoMandy
438dae0a4e0SAdrien Destugues - PulkoMandy
439dae0a4e0SAdrien Destugues - PulkoMandyint main(int argc, char** argv)
440dae0a4e0SAdrien Destugues - PulkoMandy{
441dae0a4e0SAdrien Destugues - PulkoMandy	SerialApp app;
442dae0a4e0SAdrien Destugues - PulkoMandy	app.Run();
443dae0a4e0SAdrien Destugues - PulkoMandy}
444d9e93152SAdrien Destugues
445d9e93152SAdrien Destugues
446d9e93152SAdrien Destuguesstatus_t
447d9e93152SAdrien DestuguesSerialApp::GetSupportedSuites(BMessage* message)
448d9e93152SAdrien Destugues{
449d9e93152SAdrien Destugues	message->AddString("suites", "suite/vnd.Haiku-SerialPort");
450d9e93152SAdrien Destugues	message->AddFlat("messages", &kScriptingProperties);
451d9e93152SAdrien Destugues	return BApplication::GetSupportedSuites(message);
452d9e93152SAdrien Destugues}
453d9e93152SAdrien Destugues
454d9e93152SAdrien Destugues
455d9e93152SAdrien DestuguesBHandler*
456d9e93152SAdrien DestuguesSerialApp::ResolveSpecifier(BMessage* message, int32 index,
457d9e93152SAdrien Destugues	BMessage* specifier, int32 what, const char* property)
458d9e93152SAdrien Destugues{
459d9e93152SAdrien Destugues	if (kScriptingProperties.FindMatch(message, index, specifier, what,
460d9e93152SAdrien Destugues		property) >= 0)
461d9e93152SAdrien Destugues		return this;
462d9e93152SAdrien Destugues
463d9e93152SAdrien Destugues	return BApplication::ResolveSpecifier(message, index, specifier, what,
464d9e93152SAdrien Destugues		property);
465d9e93152SAdrien Destugues}
466