Back to home page

OSCL-LXR

 
 

    


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.