162306a36Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci.. include:: <isonum.txt> 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci============================ 562306a36Sopenharmony_ciLinux Phonet protocol family 662306a36Sopenharmony_ci============================ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ciIntroduction 962306a36Sopenharmony_ci------------ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ciPhonet is a packet protocol used by Nokia cellular modems for both IPC 1262306a36Sopenharmony_ciand RPC. With the Linux Phonet socket family, Linux host processes can 1362306a36Sopenharmony_cireceive and send messages from/to the modem, or any other external 1462306a36Sopenharmony_cidevice attached to the modem. The modem takes care of routing. 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ciPhonet packets can be exchanged through various hardware connections 1762306a36Sopenharmony_cidepending on the device, such as: 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci - USB with the CDC Phonet interface, 2062306a36Sopenharmony_ci - infrared, 2162306a36Sopenharmony_ci - Bluetooth, 2262306a36Sopenharmony_ci - an RS232 serial port (with a dedicated "FBUS" line discipline), 2362306a36Sopenharmony_ci - the SSI bus with some TI OMAP processors. 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ciPackets format 2762306a36Sopenharmony_ci-------------- 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ciPhonet packets have a common header as follows:: 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci struct phonethdr { 3262306a36Sopenharmony_ci uint8_t pn_media; /* Media type (link-layer identifier) */ 3362306a36Sopenharmony_ci uint8_t pn_rdev; /* Receiver device ID */ 3462306a36Sopenharmony_ci uint8_t pn_sdev; /* Sender device ID */ 3562306a36Sopenharmony_ci uint8_t pn_res; /* Resource ID or function */ 3662306a36Sopenharmony_ci uint16_t pn_length; /* Big-endian message byte length (minus 6) */ 3762306a36Sopenharmony_ci uint8_t pn_robj; /* Receiver object ID */ 3862306a36Sopenharmony_ci uint8_t pn_sobj; /* Sender object ID */ 3962306a36Sopenharmony_ci }; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ciOn Linux, the link-layer header includes the pn_media byte (see below). 4262306a36Sopenharmony_ciThe next 7 bytes are part of the network-layer header. 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ciThe device ID is split: the 6 higher-order bits constitute the device 4562306a36Sopenharmony_ciaddress, while the 2 lower-order bits are used for multiplexing, as are 4662306a36Sopenharmony_cithe 8-bit object identifiers. As such, Phonet can be considered as a 4762306a36Sopenharmony_cinetwork layer with 6 bits of address space and 10 bits for transport 4862306a36Sopenharmony_ciprotocol (much like port numbers in IP world). 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ciThe modem always has address number zero. All other device have a their 5162306a36Sopenharmony_ciown 6-bit address. 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ciLink layer 5562306a36Sopenharmony_ci---------- 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ciPhonet links are always point-to-point links. The link layer header 5862306a36Sopenharmony_ciconsists of a single Phonet media type byte. It uniquely identifies the 5962306a36Sopenharmony_cilink through which the packet is transmitted, from the modem's 6062306a36Sopenharmony_ciperspective. Each Phonet network device shall prepend and set the media 6162306a36Sopenharmony_citype byte as appropriate. For convenience, a common phonet_header_ops 6262306a36Sopenharmony_cilink-layer header operations structure is provided. It sets the 6362306a36Sopenharmony_cimedia type according to the network device hardware address. 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ciLinux Phonet network interfaces support a dedicated link layer packets 6662306a36Sopenharmony_citype (ETH_P_PHONET) which is out of the Ethernet type range. They can 6762306a36Sopenharmony_cionly send and receive Phonet packets. 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ciThe virtual TUN tunnel device driver can also be used for Phonet. This 7062306a36Sopenharmony_cirequires IFF_TUN mode, _without_ the IFF_NO_PI flag. In this case, 7162306a36Sopenharmony_cithere is no link-layer header, so there is no Phonet media type byte. 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ciNote that Phonet interfaces are not allowed to re-order packets, so 7462306a36Sopenharmony_cionly the (default) Linux FIFO qdisc should be used with them. 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ciNetwork layer 7862306a36Sopenharmony_ci------------- 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ciThe Phonet socket address family maps the Phonet packet header:: 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci struct sockaddr_pn { 8362306a36Sopenharmony_ci sa_family_t spn_family; /* AF_PHONET */ 8462306a36Sopenharmony_ci uint8_t spn_obj; /* Object ID */ 8562306a36Sopenharmony_ci uint8_t spn_dev; /* Device ID */ 8662306a36Sopenharmony_ci uint8_t spn_resource; /* Resource or function */ 8762306a36Sopenharmony_ci uint8_t spn_zero[...]; /* Padding */ 8862306a36Sopenharmony_ci }; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ciThe resource field is only used when sending and receiving; 9162306a36Sopenharmony_ciIt is ignored by bind() and getsockname(). 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ciLow-level datagram protocol 9562306a36Sopenharmony_ci--------------------------- 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ciApplications can send Phonet messages using the Phonet datagram socket 9862306a36Sopenharmony_ciprotocol from the PF_PHONET family. Each socket is bound to one of the 9962306a36Sopenharmony_ci2^10 object IDs available, and can send and receive packets with any 10062306a36Sopenharmony_ciother peer. 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci:: 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci struct sockaddr_pn addr = { .spn_family = AF_PHONET, }; 10562306a36Sopenharmony_ci ssize_t len; 10662306a36Sopenharmony_ci socklen_t addrlen = sizeof(addr); 10762306a36Sopenharmony_ci int fd; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci fd = socket(PF_PHONET, SOCK_DGRAM, 0); 11062306a36Sopenharmony_ci bind(fd, (struct sockaddr *)&addr, sizeof(addr)); 11162306a36Sopenharmony_ci /* ... */ 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci sendto(fd, msg, msglen, 0, (struct sockaddr *)&addr, sizeof(addr)); 11462306a36Sopenharmony_ci len = recvfrom(fd, buf, sizeof(buf), 0, 11562306a36Sopenharmony_ci (struct sockaddr *)&addr, &addrlen); 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ciThis protocol follows the SOCK_DGRAM connection-less semantics. 11862306a36Sopenharmony_ciHowever, connect() and getpeername() are not supported, as they did 11962306a36Sopenharmony_cinot seem useful with Phonet usages (could be added easily). 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ciResource subscription 12362306a36Sopenharmony_ci--------------------- 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ciA Phonet datagram socket can be subscribed to any number of 8-bits 12662306a36Sopenharmony_ciPhonet resources, as follow:: 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci uint32_t res = 0xXX; 12962306a36Sopenharmony_ci ioctl(fd, SIOCPNADDRESOURCE, &res); 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ciSubscription is similarly cancelled using the SIOCPNDELRESOURCE I/O 13262306a36Sopenharmony_cicontrol request, or when the socket is closed. 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ciNote that no more than one socket can be subscribed to any given 13562306a36Sopenharmony_ciresource at a time. If not, ioctl() will return EBUSY. 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ciPhonet Pipe protocol 13962306a36Sopenharmony_ci-------------------- 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ciThe Phonet Pipe protocol is a simple sequenced packets protocol 14262306a36Sopenharmony_ciwith end-to-end congestion control. It uses the passive listening 14362306a36Sopenharmony_cisocket paradigm. The listening socket is bound to an unique free object 14462306a36Sopenharmony_ciID. Each listening socket can handle up to 255 simultaneous 14562306a36Sopenharmony_ciconnections, one per accept()'d socket. 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci:: 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci int lfd, cfd; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci lfd = socket(PF_PHONET, SOCK_SEQPACKET, PN_PROTO_PIPE); 15262306a36Sopenharmony_ci listen (lfd, INT_MAX); 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci /* ... */ 15562306a36Sopenharmony_ci cfd = accept(lfd, NULL, NULL); 15662306a36Sopenharmony_ci for (;;) 15762306a36Sopenharmony_ci { 15862306a36Sopenharmony_ci char buf[...]; 15962306a36Sopenharmony_ci ssize_t len = read(cfd, buf, sizeof(buf)); 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci /* ... */ 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci write(cfd, msg, msglen); 16462306a36Sopenharmony_ci } 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ciConnections are traditionally established between two endpoints by a 16762306a36Sopenharmony_ci"third party" application. This means that both endpoints are passive. 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ciAs of Linux kernel version 2.6.39, it is also possible to connect 17162306a36Sopenharmony_citwo endpoints directly, using connect() on the active side. This is 17262306a36Sopenharmony_ciintended to support the newer Nokia Wireless Modem API, as found in 17362306a36Sopenharmony_cie.g. the Nokia Slim Modem in the ST-Ericsson U8500 platform:: 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci struct sockaddr_spn spn; 17662306a36Sopenharmony_ci int fd; 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci fd = socket(PF_PHONET, SOCK_SEQPACKET, PN_PROTO_PIPE); 17962306a36Sopenharmony_ci memset(&spn, 0, sizeof(spn)); 18062306a36Sopenharmony_ci spn.spn_family = AF_PHONET; 18162306a36Sopenharmony_ci spn.spn_obj = ...; 18262306a36Sopenharmony_ci spn.spn_dev = ...; 18362306a36Sopenharmony_ci spn.spn_resource = 0xD9; 18462306a36Sopenharmony_ci connect(fd, (struct sockaddr *)&spn, sizeof(spn)); 18562306a36Sopenharmony_ci /* normal I/O here ... */ 18662306a36Sopenharmony_ci close(fd); 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci.. Warning: 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci When polling a connected pipe socket for writability, there is an 19262306a36Sopenharmony_ci intrinsic race condition whereby writability might be lost between the 19362306a36Sopenharmony_ci polling and the writing system calls. In this case, the socket will 19462306a36Sopenharmony_ci block until write becomes possible again, unless non-blocking mode 19562306a36Sopenharmony_ci is enabled. 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ciThe pipe protocol provides two socket options at the SOL_PNPIPE level: 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci PNPIPE_ENCAP accepts one integer value (int) of: 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci PNPIPE_ENCAP_NONE: 20362306a36Sopenharmony_ci The socket operates normally (default). 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci PNPIPE_ENCAP_IP: 20662306a36Sopenharmony_ci The socket is used as a backend for a virtual IP 20762306a36Sopenharmony_ci interface. This requires CAP_NET_ADMIN capability. GPRS data 20862306a36Sopenharmony_ci support on Nokia modems can use this. Note that the socket cannot 20962306a36Sopenharmony_ci be reliably poll()'d or read() from while in this mode. 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci PNPIPE_IFINDEX 21262306a36Sopenharmony_ci is a read-only integer value. It contains the 21362306a36Sopenharmony_ci interface index of the network interface created by PNPIPE_ENCAP, 21462306a36Sopenharmony_ci or zero if encapsulation is off. 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci PNPIPE_HANDLE 21762306a36Sopenharmony_ci is a read-only integer value. It contains the underlying 21862306a36Sopenharmony_ci identifier ("pipe handle") of the pipe. This is only defined for 21962306a36Sopenharmony_ci socket descriptors that are already connected or being connected. 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ciAuthors 22362306a36Sopenharmony_ci------- 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ciLinux Phonet was initially written by Sakari Ailus. 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ciOther contributors include Mikä Liljeberg, Andras Domokos, 22862306a36Sopenharmony_ciCarlos Chinea and Rémi Denis-Courmont. 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ciCopyright |copy| 2008 Nokia Corporation. 231