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) |
Boards and links
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
getLink() → id or nil
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.
get() → {link, board}
Both, as a table. A missing one is left out.
set({link = id}) → nothing
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.
Link from a shell
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)
An alias makes it one word: alias next='lua /home/bluetooth-switch.lua 5f0c... 9a21...'.
Remember a link
-- 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