Modular Computers the manual GitHub

Bluetooth Card

A Bluetooth card in a computer links that computer’s bus to another block’s board, with no cable. A program reads and sets the link the card holds, as a player does by right-clicking a block with it.

Facts

| | | |—|—| | Type | bluetooth | | Address | An expansion slot path such as exp:0 | | Interrupt | None | | Info | kind (bluetooth) |

A link names a board, not a card: the id of a computer, a hub or a screen, as a UUID. A card’s board is the one its own computer is: what another card links to, to reach it. The link lives on the card’s item, read and written there. The board need not be present when you link to it.

See Bus for how linked blocks join a computer’s bus.

In mcos

/dev/bluetooth0 is text. A read gives two lines:

link 5f0c0000-0000-0000-0000-000000000000
board 9a210000-0000-0000-0000-000000000000

link - means no link, and board - means the card has no board. The state is taken at the first read after the file is opened (or sought back to its start). Writing a line relinks the card as soon as the line is written (flushed): link <id>, or link - for none. A line that is not a link, or an id that is not a board’s, fails the write with EINVAL.

cat /dev/bluetooth0
echo link - > /dev/bluetooth0

The card has no events, so poll never reports it PRI; the file is always readable (IN) and writable (OUT). Its ioctls are the card’s methods, by name, in any open mode:

sys.ioctl(fd, "setLink", "5f0c0000-0000-0000-0000-000000000000")

A method that fails answers nil, its message and EINVAL; a card that is gone, ENODEV. setLabel labels the card, as for any device (see The sys library).

Methods

The id of the board it links to, or nil.

setLink(id) → nothing

Links it to the board with that id, as linking it by hand does. Nil, or no argument, links it to none. The board need not be there now. An id that is not a UUID, or not a string, fails with not a board id. Through the ioctl it answers true.

getBoard() → id or nil

The id of the board it is in: its computer’s, what another card links to, to reach it. Nil if it has none.

Both, as a table. A missing one is left out.

Links it to that board; {link = false} (or no link) links it to none. Otherwise as setLink.

Events

None.

Examples

Run these with lua name.lua, from a computer with a Bluetooth card.

echo link 5f0c0000-0000-0000-0000-000000000000 > /dev/bluetooth0
cat /dev/bluetooth0

The first line of the output is link 5f0c0000-0000-0000-0000-000000000000. Replace the id with a real one: yours are shown by cat /dev/bluetooth0 on the other computer, in its board line.

Switch between boards

-- Switch a computer's Bluetooth link between boards in turn: run it with the boards' ids, and each
-- run links the card to the one after the board it links to now (the first, if it links to none
-- of them). A desk with one keyboard and screen reaching one machine room after another.
--
--   lua bluetooth-switch.lua 5f0c...-... 9a21...-...
--
-- It uses the card's methods, getLink and setLink, through its file's ioctls; the boards need not be
-- there when it runs. It exits 1 if an id is not a board's.
local sys = require("sys")

local boards = {...}
if #boards == 0 then
  io.stderr:write("usage: lua bluetooth-switch.lua board-id...\n")
  sys.exit(2)
end

local card = assert(sys.open("/dev/bluetooth0"))
local now = sys.ioctl(card, "getLink") -- nil: no link

local target = boards[1]
for i, id in ipairs(boards) do
  if id == now then
    target = boards[i % #boards + 1]
  end
end

local ok, why = sys.ioctl(card, "setLink", target)
if not ok then
  io.stderr:write("bluetooth-switch: ", why, "\n")
  sys.exit(1)
end
print("linked to " .. target)

Download bluetooth-switch.lua

An alias makes it one word: alias next='lua /home/bluetooth-switch.lua 5f0c... 9a21...'.

-- Remember a Bluetooth link and put it back later: "save" keeps the board the card links to in a
-- file, "restore" links the card to it again (after someone relinked the card by hand, say), and
-- "clear" unlinks it.
--
--   lua bluetooth-remember.lua save | restore | clear
--
-- It works only through the card's file: a read gives "link <id>" and "board <id>" lines, and a
-- line written ("link <id>", or "link -" for none) relinks the card as soon as it is written.
local sys = require("sys")

local CARD = "/dev/bluetooth0"
local SAVED = "/home/bluetooth.link"

local function relink(id)
  local card = assert(io.open(CARD, "w"))
  card:write("link ", id, "\n")
  local ok, why = card:flush() -- (the line goes to the card here: a bad one fails)
  card:close()
  if not ok then
    io.stderr:write("bluetooth-remember: ", why, "\n")
    sys.exit(1)
  end
end

local action = ...
if action == "save" then
  local card = assert(io.open(CARD))
  local link = card:read("a"):match("link (%S+)")
  card:close()
  local out = assert(io.open(SAVED, "w"))
  out:write(link, "\n") -- ("-" when it links to none)
  out:close()
elseif action == "restore" then
  local saved = assert(io.open(SAVED))
  relink(saved:read("l"))
  saved:close()
elseif action == "clear" then
  relink("-")
else
  io.stderr:write("usage: lua bluetooth-remember.lua save|restore|clear\n")
  sys.exit(2)
end

Download bluetooth-remember.lua