0001 .. SPDX-License-Identifier: GPL-2.0
0002 .. include:: <isonum.txt>
0003
0004 ============================
0005 Linux Phonet protocol family
0006 ============================
0007
0008 Introduction
0009 ------------
0010
0011 Phonet is a packet protocol used by Nokia cellular modems for both IPC
0012 and RPC. With the Linux Phonet socket family, Linux host processes can
0013 receive and send messages from/to the modem, or any other external
0014 device attached to the modem. The modem takes care of routing.
0015
0016 Phonet packets can be exchanged through various hardware connections
0017 depending on the device, such as:
0018
0019 - USB with the CDC Phonet interface,
0020 - infrared,
0021 - Bluetooth,
0022 - an RS232 serial port (with a dedicated "FBUS" line discipline),
0023 - the SSI bus with some TI OMAP processors.
0024
0025
0026 Packets format
0027 --------------
0028
0029 Phonet packets have a common header as follows::
0030
0031 struct phonethdr {
0032 uint8_t pn_media; /* Media type (link-layer identifier) */
0033 uint8_t pn_rdev; /* Receiver device ID */
0034 uint8_t pn_sdev; /* Sender device ID */
0035 uint8_t pn_res; /* Resource ID or function */
0036 uint16_t pn_length; /* Big-endian message byte length (minus 6) */
0037 uint8_t pn_robj; /* Receiver object ID */
0038 uint8_t pn_sobj; /* Sender object ID */
0039 };
0040
0041 On Linux, the link-layer header includes the pn_media byte (see below).
0042 The next 7 bytes are part of the network-layer header.
0043
0044 The device ID is split: the 6 higher-order bits constitute the device
0045 address, while the 2 lower-order bits are used for multiplexing, as are
0046 the 8-bit object identifiers. As such, Phonet can be considered as a
0047 network layer with 6 bits of address space and 10 bits for transport
0048 protocol (much like port numbers in IP world).
0049
0050 The modem always has address number zero. All other device have a their
0051 own 6-bit address.
0052
0053
0054 Link layer
0055 ----------
0056
0057 Phonet links are always point-to-point links. The link layer header
0058 consists of a single Phonet media type byte. It uniquely identifies the
0059 link through which the packet is transmitted, from the modem's
0060 perspective. Each Phonet network device shall prepend and set the media
0061 type byte as appropriate. For convenience, a common phonet_header_ops
0062 link-layer header operations structure is provided. It sets the
0063 media type according to the network device hardware address.
0064
0065 Linux Phonet network interfaces support a dedicated link layer packets
0066 type (ETH_P_PHONET) which is out of the Ethernet type range. They can
0067 only send and receive Phonet packets.
0068
0069 The virtual TUN tunnel device driver can also be used for Phonet. This
0070 requires IFF_TUN mode, _without_ the IFF_NO_PI flag. In this case,
0071 there is no link-layer header, so there is no Phonet media type byte.
0072
0073 Note that Phonet interfaces are not allowed to re-order packets, so
0074 only the (default) Linux FIFO qdisc should be used with them.
0075
0076
0077 Network layer
0078 -------------
0079
0080 The Phonet socket address family maps the Phonet packet header::
0081
0082 struct sockaddr_pn {
0083 sa_family_t spn_family; /* AF_PHONET */
0084 uint8_t spn_obj; /* Object ID */
0085 uint8_t spn_dev; /* Device ID */
0086 uint8_t spn_resource; /* Resource or function */
0087 uint8_t spn_zero[...]; /* Padding */
0088 };
0089
0090 The resource field is only used when sending and receiving;
0091 It is ignored by bind() and getsockname().
0092
0093
0094 Low-level datagram protocol
0095 ---------------------------
0096
0097 Applications can send Phonet messages using the Phonet datagram socket
0098 protocol from the PF_PHONET family. Each socket is bound to one of the
0099 2^10 object IDs available, and can send and receive packets with any
0100 other peer.
0101
0102 ::
0103
0104 struct sockaddr_pn addr = { .spn_family = AF_PHONET, };
0105 ssize_t len;
0106 socklen_t addrlen = sizeof(addr);
0107 int fd;
0108
0109 fd = socket(PF_PHONET, SOCK_DGRAM, 0);
0110 bind(fd, (struct sockaddr *)&addr, sizeof(addr));
0111 /* ... */
0112
0113 sendto(fd, msg, msglen, 0, (struct sockaddr *)&addr, sizeof(addr));
0114 len = recvfrom(fd, buf, sizeof(buf), 0,
0115 (struct sockaddr *)&addr, &addrlen);
0116
0117 This protocol follows the SOCK_DGRAM connection-less semantics.
0118 However, connect() and getpeername() are not supported, as they did
0119 not seem useful with Phonet usages (could be added easily).
0120
0121
0122 Resource subscription
0123 ---------------------
0124
0125 A Phonet datagram socket can be subscribed to any number of 8-bits
0126 Phonet resources, as follow::
0127
0128 uint32_t res = 0xXX;
0129 ioctl(fd, SIOCPNADDRESOURCE, &res);
0130
0131 Subscription is similarly cancelled using the SIOCPNDELRESOURCE I/O
0132 control request, or when the socket is closed.
0133
0134 Note that no more than one socket can be subcribed to any given
0135 resource at a time. If not, ioctl() will return EBUSY.
0136
0137
0138 Phonet Pipe protocol
0139 --------------------
0140
0141 The Phonet Pipe protocol is a simple sequenced packets protocol
0142 with end-to-end congestion control. It uses the passive listening
0143 socket paradigm. The listening socket is bound to an unique free object
0144 ID. Each listening socket can handle up to 255 simultaneous
0145 connections, one per accept()'d socket.
0146
0147 ::
0148
0149 int lfd, cfd;
0150
0151 lfd = socket(PF_PHONET, SOCK_SEQPACKET, PN_PROTO_PIPE);
0152 listen (lfd, INT_MAX);
0153
0154 /* ... */
0155 cfd = accept(lfd, NULL, NULL);
0156 for (;;)
0157 {
0158 char buf[...];
0159 ssize_t len = read(cfd, buf, sizeof(buf));
0160
0161 /* ... */
0162
0163 write(cfd, msg, msglen);
0164 }
0165
0166 Connections are traditionally established between two endpoints by a
0167 "third party" application. This means that both endpoints are passive.
0168
0169
0170 As of Linux kernel version 2.6.39, it is also possible to connect
0171 two endpoints directly, using connect() on the active side. This is
0172 intended to support the newer Nokia Wireless Modem API, as found in
0173 e.g. the Nokia Slim Modem in the ST-Ericsson U8500 platform::
0174
0175 struct sockaddr_spn spn;
0176 int fd;
0177
0178 fd = socket(PF_PHONET, SOCK_SEQPACKET, PN_PROTO_PIPE);
0179 memset(&spn, 0, sizeof(spn));
0180 spn.spn_family = AF_PHONET;
0181 spn.spn_obj = ...;
0182 spn.spn_dev = ...;
0183 spn.spn_resource = 0xD9;
0184 connect(fd, (struct sockaddr *)&spn, sizeof(spn));
0185 /* normal I/O here ... */
0186 close(fd);
0187
0188
0189 .. Warning:
0190
0191 When polling a connected pipe socket for writability, there is an
0192 intrinsic race condition whereby writability might be lost between the
0193 polling and the writing system calls. In this case, the socket will
0194 block until write becomes possible again, unless non-blocking mode
0195 is enabled.
0196
0197
0198 The pipe protocol provides two socket options at the SOL_PNPIPE level:
0199
0200 PNPIPE_ENCAP accepts one integer value (int) of:
0201
0202 PNPIPE_ENCAP_NONE:
0203 The socket operates normally (default).
0204
0205 PNPIPE_ENCAP_IP:
0206 The socket is used as a backend for a virtual IP
0207 interface. This requires CAP_NET_ADMIN capability. GPRS data
0208 support on Nokia modems can use this. Note that the socket cannot
0209 be reliably poll()'d or read() from while in this mode.
0210
0211 PNPIPE_IFINDEX
0212 is a read-only integer value. It contains the
0213 interface index of the network interface created by PNPIPE_ENCAP,
0214 or zero if encapsulation is off.
0215
0216 PNPIPE_HANDLE
0217 is a read-only integer value. It contains the underlying
0218 identifier ("pipe handle") of the pipe. This is only defined for
0219 socket descriptors that are already connected or being connected.
0220
0221
0222 Authors
0223 -------
0224
0225 Linux Phonet was initially written by Sakari Ailus.
0226
0227 Other contributors include Mikä Liljeberg, Andras Domokos,
0228 Carlos Chinea and Rémi Denis-Courmont.
0229
0230 Copyright |copy| 2008 Nokia Corporation.