Skip to content

Commit 5708b89

Browse files
committed
Serial (RS-232) device support improved
Fixed a bug (crash in debug mode) with Spaceball 4000 FLX with Fw: "Firmware version 2.42 created on 24-Oct-1997." Initially it is detected as a 2003c - and this is normal, because both use the 2.42 firmware version. The first time a button above 8 (9, A, B, C written on the button) was pressed the driver would access unallocated memory because `dev->bn_name` only had space for 8 buttons. The `dev` structure is now properly reinitialized. Tested with: Spaceball 4000 FLX with Fw: "Firmware version 2.42 created on 24-Oct-1997."
1 parent f72d01a commit 5708b89

2 files changed

Lines changed: 33 additions & 3 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Device | Manufacturer | Note
3434
------ | ------------ | ----
3535
[Magellan SpaceMouse Classic](https://spacemice.org/index.php?title=Spacemouse_Classic) | LogiCad3D GmbH (1993) | Fw: "v MAGELLAN Version 5.79 by LOGITECH INC. 10/10/97"
3636
[Spaceball 3003 FLX](https://spacemice.org/index.php?title=Spaceball_3003) | Spacetec IMC Ltd. (1996) | Fw: "Firmware version 2.62 created on 24-Oct-1997."
37+
[Spaceball 4000 FLX](https://spacemice.org/index.php?title=Spaceball_4000) | Spacetec IMC Corporation | Fw: "Firmware version 2.42 created on 24-Oct-1997."
3738
[Magellan SpaceMouse Plus](https://spacemice.org/index.php?title=Spacemouse_Plus) | LogiCad3D GmbH (1998), 3DConnexion (2001) | Fw: "v MAGELLAN Version 6.70 3Dconnexion GmbH 05/11/02"
3839

3940
If you own a SpaceMouse not listed above please test it and report your results in the issues. Just

src/serdev.c

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ static struct {
6464
static void close_dev_serial(struct spndev* dev);
6565
static int read_dev_serial(struct spndev* dev, union spndev_event* evt);
6666
static int init_dev(struct spndev *dev, int type);
67+
static int deinit_dev(struct spndev* dev);
6768

6869
static void stty_save(int fd, struct sball *sb);
6970
static void stty_restore(int fd, struct sball *sb);
@@ -126,7 +127,8 @@ int spndev_ser_open(struct spndev *dev, const char *devstr)
126127

127128
/* set binary mode and enable automatic data packet sending. also request
128129
* a key event to find out as soon as possible if this is a 4000flx with
129-
* 12 buttons
130+
* 12 buttons - this does not work, it responds with "?k". The mode is
131+
* switched the first time a button is pressed.
130132
*/
131133
serwrite(fd, "\rCB\rMSSV\rk\r", 11);
132134

@@ -172,6 +174,7 @@ int spndev_ser_open(struct spndev *dev, const char *devstr)
172174

173175
static void close_dev_serial(struct spndev *dev)
174176
{
177+
deinit_dev(dev);
175178
if(dev->drvdata) {
176179
stty_restore(dev->fd, (struct sball*)dev->drvdata);
177180
serclose(dev->fd);
@@ -227,6 +230,7 @@ static int init_dev(struct spndev *dev, int type)
227230
if(!(dev->bn_name = (const char**)malloc(dev->num_buttons * sizeof *dev->bn_name))) {
228231
free(dev->aprop);
229232
free(dev->name);
233+
return -1;
230234
}
231235

232236
for(i = 0; i < dev->num_axes; i++) {
@@ -241,6 +245,21 @@ static int init_dev(struct spndev *dev, int type)
241245
return 0;
242246
}
243247

248+
static int deinit_dev(struct spndev* dev) {
249+
if (dev->bn_name) {
250+
free(dev->bn_name);
251+
dev->bn_name = 0;
252+
}
253+
if (dev->aprop) {
254+
free(dev->aprop);
255+
dev->aprop = 0;
256+
}
257+
if (dev->name) {
258+
free(dev->name);
259+
dev->name = 0;
260+
}
261+
}
262+
244263
static int guess_device(const char *verstr)
245264
{
246265
int major, minor;
@@ -271,6 +290,11 @@ static int guess_device(const char *verstr)
271290
* sure this happens as soon as possible, before clients have a
272291
* chance to connect.
273292
*/
293+
/* PAR 2025-06-24 I aquired an interesing Spaceball 4000 FLX with
294+
* "Firmware version 2.42 created on 24-Oct-1997". The label is
295+
* printed on a laser printer with a "PENDING" "water mark" across it
296+
* and a "S/N: BETA-483"
297+
*/
274298
return DEV_SB2003C;
275299
}
276300
}
@@ -510,8 +534,13 @@ static int sball_parsepkt(struct spndev* dev, union spndev_event* evt, int id, c
510534
if(!(sb->flags & SB4000)) {
511535
printf("Switching to spaceball 4000flx/5000flx-a mode (12 buttons) \n");
512536
sb->flags |= SB4000;
513-
dev->num_buttons = 12; /* might have guessed 8 before */ // PAR@@@@@@ FIIIIX reallocate the button names array at the very least!
514-
sb->keymask = 0xffff >> (16 - dev->num_buttons);
537+
/* Might have guessed 8 buttons before. By calling init_dev(dev, DEV_SB4000) we reinitialize
538+
the dev->drvdata (sb) structure for 12 buttons (enough space for names, keymask etc.) */
539+
deinit_dev(dev); // Free allocated members otherwise we will leak them in the next init_dev.
540+
if (init_dev(dev, DEV_SB4000) == -1) {
541+
fprintf(stderr, "spndev_open: failed to initialize device structure\n");
542+
// return -1?
543+
}
515544
}
516545
/* update orientation flag (actually don't bother) */
517546
/*

0 commit comments

Comments
 (0)