# Telephony (call and SMS) support - [`[synit]/protocols/schemas/telephony.prs`](https://git.syndicate-lang.org/synit/synit/src/branch/main/protocols/schemas/telephony.prs) The telephony protocol defines record and message types for non-modem-hardware-specific telephony interactions. **Implementation.** The protocol is (as of October 2022) implemented entirely within the SqueakPhone Smalltalk image, in class `CallManager`, `HayesModemActor`, `SamsungGalaxyS7ModemActor`, and so on. ## Available modem devices A `ModemPresent` record is asserted for each modem available to the telephony subsystem. The `type` field can, for example, be the symbol `hayes` for a Hayes modem, `samsung-galaxy-s7` for a Samsung Galaxy S7, and so on. Each modem variant speaks a [variant-specific protocol](./modem.md) across the `dataspace` reference in the `ModemPresent` record. Finally, the `devicePath` is a Linux device path representative of the modem, for example `/dev/umts_boot0` or `/dev/EG25.AT`. ``` ModemPresent = . ``` ## Telephony addresses (telephone numbers) An `Address` represents a phone number. The `numberType` selects the numbering plan; the `number` is the actual address. Numbering plans are complex! The GSM specifications are the place to go for details. In general, using `international` with numbers like `+31 6 ...` is the best way forward. ``` Address =
. NumberType = =unknown / =international / =national / =gsm0338 . ``` ## Ongoing calls An `ActiveCall` assertion describes an active, ongoing call. The `callId` is a modem-specific call identification number. (TODO: if two modems are active, their `callId`s may clash.) The `direction` is `mo` for calls placed by the local phone endpoint, i.e. those dialed by the local user, and `mt` for calls placed by a remote phone, i.e. incoming calls, those answered by the local user. The `type` field describes whether the call is for voice or data; usually, this will be `voice`, but `data` is reported by some modems when using mobile data connections. As you might imagine, `fax`-type calls are uncommon. The `peer` field describes the other phone's network address (phone number). Finally, `state` describes the state of the call. ``` ActiveCall = . CallId = int . CallDirection = =mo / =mt . CallType = =voice / =data / =fax . CallState = =hold / =original / =connect / =incoming / =waiting / =end / =alerting . ``` ## Answering an incoming call When an `ActiveCall` record is asserted by the modem, if it has direction `mt` and state `incoming`, the system should let the user choose to answer the call (or ignore it, etc.). If the user chooses to answer, an `AnswerCall` message tells the modem to do the necessary. The `callId` is the same value as in the `ActiveCall` assertion. ``` ; Message. Triggers call answering. AnswerCall = . ``` ## Rejecting and/or disconnecting a call Sending a `DisconnectCall` message causes the modem to release an active call, either without answering it (rejection) or while it is established (disconnection). The `callId` is taken from the `ActiveCall` assertion, or is the symbol `all` to request disconnection of all active calls. The `cause` field describes the release reason; it should usually be `normal`, but `busy` or `callRejected` may also be appropriate. ``` DisconnectCall = . CallIdSelector = @specificCall int / @allCalls =all . ReleaseCause = / =unassignedNumber / =normal / =busy / =noUserResponding / =callRejected / =destinationOutOfOrder / =normalUnspecified / =incompatibleDestination . ``` ## Placing an outbound call Sending a `PlaceCall` message causes the matching modem (named by its `devicePath`, which should match a `ModemPresent` assertion) to place an outbound call to the named `peer` (a phone number). ``` ; Message. Starts an outgoing call. PlaceCall = . ``` ## Whole-device call state Many applications don't care about precise details of individual calls, but only whether or not some ongoing call is active (alerting, connected, ringing etc.). Those applications may monitor the `CallInProgress` assertion. ``` CallInProgress = . ``` ## Whole-device ringing state A `PhoneRinging` assertion means that an incoming call is signalling the user, asking for a decision about whether to answer, reject, or ignore the call. ``` PhoneRinging = . ``` A `PeerRinging` assertion means that, during the establishment phase of an outgoing call, the remote party's phone should be ringing. ``` PeerRinging = . ``` ## SMS deliveries and transmissions An `SmsDelivery` message indicates that an incoming SMS message has been received. The `smsc` is the message relay server that forwarded the message on to us; this is usually some carrier- and even plan-specific address, see the GSM specifications for details. The `peer` is the sender's phone number. The `timestamp` describes the time associated with the SMS, and the `body` is the message itself. ``` SmsDelivery = . ``` To send an SMS message, assert an `SmsTransmission` record with the correct `smsc`, the `peer`'s destination phone number, and the `body` of the message to send. The `continuation` field should be a reference to an entity that expects the `ok` symbol as a message when the transmission has been processed by the modem. ``` ; Assertion. An outgoing SMS should be transmitted. SmsTransmission = . ``` ## Speakerphone mode The user may choose to assert a `Speakerphone` record in order to request that the local audio hardware switch profile to speakerphone mode during a call. ``` Speakerphone = . ```