19  Medium access control

org.arl.unet.Services.MAC

19.1 Overview

In a shared medium such as the underwater acoustic channel, two nodes transmitting at the same time within earshot of each other can cause a collision, corrupting both transmissions. The MAC (medium access control) service coordinates access to the channel to reduce such collisions and improve overall network throughput.

A MAC agent does not transmit data itself. Instead, it advises other agents on when they may transmit. An agent that wishes to transmit — a client of the MAC — requests a channel reservation using a ReservationReq, specifying the intended recipient and the duration required. The MAC agent decides when the reservation can be granted, and notifies the requester with a ReservationStatusNtf carrying a status of START when the channel may be used. The client transmits during the reserved window, and is informed when the reservation ends.

The reservation abstraction is deliberately independent of the underlying access scheme. A simple MAC agent may implement carrier-sense multiple access (CSMA), granting a reservation as soon as the channel is sensed idle. A more sophisticated agent may use handshaking (e.g. RTS/CTS) or scheduled access (e.g. TDMA). Because they all honor the same reservation protocol, the rest of the stack is unaffected by the choice of MAC. If no MAC agent is present, agents transmit immediately without arbitration. The default MAC agent is accessed as mac. Writing a simple MAC agent (and a handshaking one) is walked through in Chapter 33.

19.2 Capabilities

Optional features of a MAC agent are advertised through capabilities (org.arl.unet.mac.MacCapability):

  • TIMED_RESERVATION – reservations may be scheduled for a future startTime
  • RELIABILITY – acknowledgement payloads are carried between clients (TxAckReq)
  • PRIORITY – reservation requests are honored in priority order
  • TTL – reservation requests expire after their time-to-live

19.3 Messages

Agents providing this service honor the following requests:

  • ReservationReq – request a channel reservation

    Field Type Default Remarks
    duration float 0.0 requested reservation duration in seconds
    payload byte[]
    priority Priority NORMAL
    reliable boolean false
    startTime long reservation start time (requires TIMED_RESERVATION)
    to int 0 intended recipient node address
    ttl float time-to-live in seconds (requires TTL)
  • ReservationAcceptReq – accept an incoming reservation, optionally with payload for the peer

    Field Type Default Remarks
    id string
    payload byte[]
  • TxAckReq – send acknowledgement payload to the peer (requires RELIABILITY)

    Field Type Default Remarks
    payload byte[]
    requestID string

A ReservationReq is answered immediately with a response indicating whether the request was accepted:

A REFUSE response is generated if the request is invalid (e.g. a bad duration, or a start time in the past). Acceptance does not mean the channel is available yet — the reservation lifecycle is reported asynchronously to the requester through notifications:

The status field (org.arl.unet.mac.ReservationStatus) takes one of the following values:

  • START – the reservation has begun; the client may transmit now
  • END – the reservation window has ended; the client must stop transmitting
  • FAILURE – the channel could not be reserved; the client should not transmit
  • CANCEL – the reservation was cancelled
  • REQUEST – the MAC on the receiving node is asking its local client to accept an incoming reservation (used by handshaking MACs; the client responds with a ReservationAcceptReq)

A client must wait for the START notification before transmitting, and confine its transmissions to the reserved window. Handshaking MACs may carry a small client-to-client payload in each direction — the payload of the ReservationReq/ReservationAcceptReq is delivered to the peer’s client, and a MAC providing RELIABILITY carries acknowledgement payloads via TxAckReq.

A MAC agent may also be told about reservations made by other nodes (overheard by snooping, or known out-of-band), by sending it a:

  • ReservationNtf – inform the MAC of a channel reservation by other nodes

    Field Type Default Remarks
    duration float 0.0
    id string
    startTime long

19.4 Parameters

Agents providing this service expose the following parameters:

channelBusy lets a client check whether the channel is currently in use before deciding to request a reservation. maxReservationDuration bounds the duration a client may ask for, while recommendedReservationDuration suggests a duration that works well with the MAC’s access scheme (e.g. a slot length). reservationPayloadSize and ackPayloadSize advertise how many bytes of client payload can be piggybacked on the reservation handshake and acknowledgement respectively (0 if unsupported).

19.5 Reserving the channel

A client that wishes to transmit does not drive the physical layer directly — it asks the MAC for a slice of channel time and waits to be told when to go. The exchange is always the same: request a reservation, wait for the START notification, transmit within the reserved window, and stop when the END notification arrives.

def mac = agentForService(Services.MAC)
if (mac) {
  def req = new ReservationReq(recipient: mac, to: destination, duration: duration)
1  def rsp = request(req)
  if (rsp?.performative == Performative.AGREE) {
2    def ntf = receive(ReservationStatusNtf, timeout)
    if (ntf?.inReplyTo == req.messageID && ntf.status == ReservationStatus.START) {
      // transmit data, keeping within `duration`
    }
  }
}
1
Request a channel reservation; an AGREE means it was queued, not that the channel is free yet.
2
Wait for the START notification before transmitting. A well-behaved client also honors the matching END notification and never transmits past the reserved window.

From the shell we can watch this play out on a single node — with no competing traffic the channel is idle, so the reservation is granted at once and released after its duration:

> mac << new ReservationReq(to: 27, duration: 5)
ReservationRsp:AGREE
mac >> ReservationStatusNtf:INFORM[to:27 status:START]
mac >> ReservationStatusNtf:INFORM[to:27 status:END]

Two properties are worth keeping in mind. First, a reservation is best-effort: a MAC generally cannot guarantee that no other node transmits during the window — the residual collision probability depends on the underlying protocol. A handshaking MAC can tell neighbouring MACs about the reservation; a carrier-sensing MAC instead relies on those neighbours hearing the transmission and backing off. What a MAC does guarantee is that no two clients on the same node hold overlapping reservations. Second, a MAC queues requests from multiple clients and grants them in turn (by arrival, priority, or another fairness measure); a client should normally keep only one request outstanding at a time, issuing the next only after the previous reservation completes.

Worked examples of a client using the MAC, and of MAC agents implementing the protocol (including the message exchange in Figure 33.1), are in Chapter 33.

19.6 MAC payloads

Some MAC protocols reserve the channel by exchanging small protocol data units (PDUs) between peer nodes — typically request-to-send (RTS), clear-to-send (CTS) and acknowledgement (ACK). Where such PDUs are used, a few bytes of client data can ride along inside them at almost no extra cost.

NoteWhat is a payload?

A payload is a few bytes of data that a MAC PDU carries on behalf of a client, without consuming significant additional time or energy. It is an optimization for low-bandwidth networks: rather than send a whole separate datagram to convey a few bytes of side information, an agent piggybacks them on the reservation handshake. For example, a link agent might attach transmit-power-control or channel-state information to an RTS/CTS exchange, to tune the power or modulation of the transmission that follows.

A MAC that supports payloads advertises a non-zero reservationPayloadSize (and ackPayloadSize for acknowledgements); a MAC without handshaking — such as the default CSMA agent — advertises 0 and carries no payloads. When payloads are available, the reservation lifecycle carries client bytes in each direction, as shown in Figure 19.1.

sequenceDiagram
    participant CA as Client<br/>(node A)
    participant MA as MAC<br/>(node A)
    participant MB as MAC<br/>(node B)
    participant CB as Client<br/>(node B)
    CA->>MA: ReservationReq (payload)
    MA-->>CA: ReservationRsp (AGREE)
    MA->>MB: RTS PDU (payload)
    MB->>CB: ReservationStatusNtf[REQUEST] (payload)
    CB->>MB: ReservationAcceptReq (payload)
    MB-->>CB: AGREE
    MB->>MA: CTS PDU (payload)
    MA->>CA: ReservationStatusNtf[START] (payload)
    Note over CA,CB: nodes exchange data during the reservation
    CB->>MB: TxAckReq (payload)
    MB-->>CB: AGREE
    MB->>MA: ACK PDU (payload)
    MA->>CA: ReservationStatusNtf[END] (payload)
Figure 19.1: A MAC reservation lifecycle with payloads, between a client on node A and a client on node B, using an RTS/CTS/ACK handshake.

Following the reservation that node A makes with node B, step by step:

  1. On node A, the client sends a ReservationReq to the MAC, optionally with a payload; the MAC accepts it with a ReservationRsp.
  2. The MAC on node A sends an RTS PDU carrying the payload to the MAC on node B.
  3. The MAC on node B publishes a ReservationStatusNtf[REQUEST] (with the payload) on its topic; the local client, subscribed to that topic, receives it.
  4. If the client on node B wishes to send payload back with the CTS, it immediately replies with a ReservationAcceptReq carrying that payload.
  5. The MAC on node B accepts, and answers node A’s MAC with a CTS PDU containing the payload.
  6. The payload is delivered to the client on node A in a ReservationStatusNtf[START], marking the start of the reservation window.
  7. During the reservation, the two nodes exchange data as they wish.
  8. If the client on node B wishes to acknowledge (with a payload), it sends a TxAckReq before the reservation ends, and the MAC on node B accepts.
  9. The MAC on node B sends an ACK PDU carrying the payload to the MAC on node A, marking the end of the reservation.
  10. The MAC on node A delivers the acknowledgement payload to its client in a ReservationStatusNtf[END]. Should node B send no ACK, node A’s MAC still issues a ReservationStatusNtf[END] when the reservation duration elapses.

19.7 Implementations

Any agent providing the MAC service honors the reservation protocol described above, so the rest of the stack is unaffected by which one is loaded. Two implementations are described here.

19.7.1 CSMA (mac)

Class Services Capabilities Availability
CSMA MAC TTL default stack

The default MAC agent is a carrier-sense multiple access (CSMA) controller, loaded as part of the default stack (Chapter 13) and accessed as mac.

19.7.1.1 How it works

An agent that wishes to transmit sends the MAC a ReservationReq. CSMA queues the request and processes the queue one reservation at a time. Before granting a reservation it checks whether the channel is busy: it considers the channel occupied while a local transmission is in progress (signalled by a TxStartNtf) or while a preamble from another node has been detected (a DetectionNtf from the baseband layer) — which is why carrier sensing needs a baseband agent, named by the baseband parameter. If the channel is idle, the reservation is granted immediately with a ReservationStatusNtf(START), and a ReservationStatusNtf(END) follows when the reserved window elapses. If the channel is busy, the request is deferred by a random back-off, drawn uniformly from a window that starts at minBackoff and doubles with each successive collision up to maxBackoff (binary exponential back-off). This is the classic mechanism that spreads competing transmitters out in time: minBackoff should be large enough to cover the channel’s propagation delay (so a deferring node actually hears an ongoing transmission), and maxBackoff bounds how long a node waits under heavy contention.

19.7.1.2 Parameters

  • baseband – baseband agent name for carrier sensing
  • minBackoff – minimum backoff window (seconds)
  • maxBackoff – maximum backoff window (seconds)

19.7.1.3 Usage notes

  • Carrier sensing requires a BASEBAND provider; set baseband to the baseband agent.
  • Tune minBackoff/maxBackoff to the propagation delay of your network — too small and deferring nodes collide anyway, too large and the channel sits idle.
  • Removing the MAC agent altogether causes agents to transmit immediately, without arbitration.

19.7.2 DTDMA (2-node TDMA)

Class Services Capabilities Availability
DTDMA MAC premium feature requiring a commercial license

An alternative MAC agent for two-node, half-duplex acoustic links that allocates the channel in dynamic time-division slots, sharing it fairly between the two nodes.

19.7.2.1 How it works

One node is the controller and the other the peer. The controller transmits during its slot (up to slotDuration, or until it has nothing to send), then hands the channel over with a “ready-to-receive” preamble; the peer then transmits its slot and hands back with an “end-of-transmission” preamble. If the peer falls silent for idleTimeout, the controller reclaims the channel. The handover preambles are detected through the baseband layer.

19.7.2.2 Parameters

  • baseband – baseband service provider

  • controller – true if node is the controller, false otherwise

  • rtrPreamble – preamble number to use for RTR signal

  • eotPreamble – preamble number to use for EOT signal

  • slotDuration – nominal MAC slot duration (seconds)

    The slot duration is used to control when a node relinquishes control of the channel in spite of having queued reservations to grant. After holding the channel for a slot duration, the node relinquishes control at the first available opportunity.

  • idleTimeout – idle timeout (seconds)

    When a controller node has no reservations to grant for an idle timeout, it relinquishes ownership of the channel to the peer node. The peer node, on the other hand, relinquishes ownership of the channel to the controller node as soon as it has no queued reservations to grant.

    If a peer node makes no transmissions for an idle timeout, the controller takes back ownership of the channel. This is to avoid locking up the channel in case the peer node is unresponsive or the channel is very poor.