1
//=========================================================
4
// $Id: midiserial.cpp,v 1.1.1.1 2003/10/29 10:06:12 wschweer Exp $
5
// (C) Copyright 1999 Werner Schweer (ws@seh.de)
6
//=========================================================
15
#include "midiserial.h"
18
SerialDeviceList serialDevices;
20
//---------------------------------------------------------
22
//---------------------------------------------------------
24
void writeSerialPorts(int level, Xml& xml)
26
if (serialDevices.empty())
28
for (iSerialDevice i = serialDevices.begin(); i != serialDevices.end(); ++i) {
29
xml.tag(level++, "serialPort");
30
xml.strTag(level, "name", (*i)->name());
31
xml.strTag(level, "path", (*i)->path());
32
xml.intTag(level, "type", (*i)->type());
33
xml.intTag(level, "speed", (*i)->speed());
34
xml.intTag(level, "handshaking", (*i)->handshaking());
35
xml.intTag(level, "ports", (*i)->vports());
36
xml.etag(level--, "serialPort");
40
//---------------------------------------------------------
42
// return true on error
43
//---------------------------------------------------------
45
bool deleteSerialDevice(const QString& path)
47
for (iSerialDevice i = serialDevices.begin(); i != serialDevices.end(); ++i) {
48
if ((*i)->path() == path) {
49
if ((*i)->fd() != -1) {
50
printf("deleteSerialDevice:busy %s\n", path.latin1());
53
serialDevices.erase(i);
57
return false; // ignore "not found" error
60
//---------------------------------------------------------
62
//---------------------------------------------------------
64
void readSerialPort(Xml& xml)
66
SerialDevice* port = new SerialDevice;
69
Xml::Token token = xml.parse();
70
QString tag = xml.s1();
71
if (token == Xml::Error || token == Xml::End)
76
port->setName(xml.parse1());
77
else if (tag == "path")
78
port->setPath(xml.parse1());
79
else if (tag == "type")
80
port->setType(SerialType(xml.parseInt()));
81
else if (tag == "speed")
82
port->setSpeed(xml.parseInt());
83
else if (tag == "handshaking")
84
port->setHandshaking(xml.parseInt());
85
else if (tag == "ports")
86
port->setVports(xml.parseInt());
88
xml.unknown("serialPort");
91
if (tag == "serialPort") {
92
serialDevices.push_back(port);
93
for (int i = 0; i < port->vports(); ++i) {
94
QString name = port->name();
95
if (port->vports() > 1) {
100
MidiSerialDevice* dev = new MidiSerialDevice(port, i, name);
101
midiDevices.add(dev);
111
//---------------------------------------------------------
113
//---------------------------------------------------------
115
SerialDevice::SerialDevice(const QString& p, SerialType t,
124
curPort = (_vports == 1) ? 0 : -1;
127
SerialDevice::SerialDevice()
135
SerialDevice::~SerialDevice()
140
//---------------------------------------------------------
142
//---------------------------------------------------------
144
void SerialDevice::setVports(int v)
151
//---------------------------------------------------------
153
//---------------------------------------------------------
155
void SerialDevice::incRef(int val)
159
// printf("incRef %d: close\n", val);
165
//---------------------------------------------------------
167
//---------------------------------------------------------
169
const QString SerialDevice::open(int)
172
_fd = ::open(_path.latin1(), O_RDWR | O_NDELAY);
174
return QString(strerror(errno));
175
if (_type == SERIAL_PORT) {
177
if (tcgetattr(_fd, &term) == -1) {
178
printf("serialOpen(%s): tcgetattr failed: %s\n",
179
_path.latin1(), strerror(errno));
183
return QString(strerror(e));
185
term.c_iflag = IGNBRK;
186
term.c_oflag &= ~OPOST;
187
term.c_cflag = CS8 | CREAD | CLOCAL;
189
term.c_cc[VTIME] = 0;
191
cfsetispeed(&term, _speed);
192
cfsetospeed(&term, _speed);
193
if (tcsetattr(_fd, TCSANOW, &term) == -1) {
194
printf("serialOpen(%s): tcsetattr failed: %s\n",
195
_path.latin1(), strerror(errno));
199
return QString(strerror(e));
203
return QString((_fd != -1) ? "OK" : strerror(errno));
206
//---------------------------------------------------------
208
//---------------------------------------------------------
210
void SerialDevice::close(int)
213
printf("close <%s>: %d\n", _path.latin1(), _fd);
219
//---------------------------------------------------------
221
//---------------------------------------------------------
223
int SerialDevice::read(int, unsigned char* buffer, int n)
227
return ::read(_fd, buffer, n);
230
//---------------------------------------------------------
232
//---------------------------------------------------------
234
int SerialDevice::write(int id, const unsigned char* buffer, int n)
236
if (n == 0 || _fd == -1)
242
for (int i = 0; i < 20; ++i) {
243
int rv = ::write(_fd, nbuffer, 2);
245
printf("MidiSerial(%s,%d): write 2: 0x%02x 0x%02x\n",
246
_path.latin1(), id, nbuffer[0] & 0xff, nbuffer[1] & 0xff);
247
if (!((rv == -1) && (errno == EAGAIN))) {
249
printf("MidiSerial(%s): write(%d,xx,%d) <%s>\n",
250
_path.latin1(), _fd, 2, strerror(errno));
256
printf("MidiSerial(%s) write(%d,xx,%d) <%s>\n",
257
_path.latin1(), _fd, 2, strerror(errno));
262
if (midiOutputTrace) {
263
printf("MidiSerial<%s>: write %d: ", _path.latin1(), n);
264
for (int i = 0; i < n; ++i)
265
printf("%02x ", buffer[i]);
268
int nn = ::write(_fd, buffer, n);
270
printf("MidiSerial<%s>: write %d returns %d\n",
271
_path.latin1(), n, nn);
276
//---------------------------------------------------------
278
//---------------------------------------------------------
280
MidiSerialDevice::MidiSerialDevice(SerialDevice* d, int vd,
281
const QString& n) : MidiRawDevice(n)
283
// printf("add device %s\n", n.latin1());
290
MidiSerialDevice::~MidiSerialDevice()
295
//---------------------------------------------------------
297
// check for raw midi ports
300
// return true on error
301
//---------------------------------------------------------
303
bool initMidiSerial()
305
const char* names[] = {
308
int devicesFound = 0;
309
for (unsigned k = 0; k < sizeof(names)/sizeof(*names); ++k) {
310
for (int i = 0; i < 8; ++i) {
313
sprintf(buffer, names[k], i);
316
sprintf(pathbuffer, "%s/%s", path, buffer);
317
int fd = ::open(pathbuffer, O_RDWR | O_NDELAY);
318
if (fd == -1 && (errno == ENOENT || errno == ENXIO)) {
320
sprintf(pathbuffer, "%s/%s", path, buffer);
321
fd = ::open(pathbuffer, O_RDWR | O_NDELAY);
324
SerialDevice* sd = new SerialDevice(QString(pathbuffer), RAW_DEVICE, 0, 1);
325
MidiSerialDevice* dev = new MidiSerialDevice(sd, 0, QString(buffer));
326
midiDevices.add(dev);
332
return devicesFound == 0;