During the last week or so, I've been spending way too much time implementing
the network-side GPRS protocol stack as part of an effort to not only provide
GSM voice + SMS but also GPRS+EDGE data services with OpenBSC
GPRS is fundamentally very different from the classic circuit-switched domain
of voice calls and CSD (circuit switched data). Not only conceptually and on
the protocol level, but also in the actual system architecture. They way it
was added on top of the existing GSM spec is by making no modification to the
BSC and MSC, and only the minimal necessary modifications to the BTS. They
then added a new Gb interface to the BTS, and the SGSN and GGSN core network
components, who in turn talk to HLR/VLR/AUC.
So in the most primitive GPRS network, you can have the GSM and GPRS domains
completely independent, only using the same databases for subscriber records
and authentication keys. This goes to the extreme end that your phone would
actually independently register with the GSM network (ISMI ATTACH / LOCATION
UPDATING) and to the GPRS network (GPRS ATTACH / ROUTING AREA UPDATE). While
both of the requests get sent to the same BTS, the BTS will send the GSM part
to the BSC (and successively MSC), and the GPRS part to the SGSN.
Also, the actual software architecture looks completely different. In the GSM
circuit-switched domain you always have a dedicated channel when you talk to a
phone. The number of dedicated channels is limited by the transceiver capacity
and the channel configuration. In OpenBSC I chose to simply attach a lot of state
to the data structure representing such a dedicated channel. In the
packet-switched domain this obviously no longer works. Many phones can and
will use the same on-air timeslot and there is no fixed limit on how many
phones can share a radio resource.
What's further important to note: The protocol stack is very deep. If you look
at the GPRS related output on an ip.access nanoBTS while your mobile phone makes
a HTTP request, the stack is something like
HTTP-TCP-IP-PPP-SNDCP-LLC-BSSGP-NS-UDP-IP-Ethernet, while the first
HTTP-TCP-IP-PPP is obvious, I would not have expected that many layers on the
underlying network. Especailly if you look at the almost zero functionality
that NS (GSM TS 08.16) seems to add to this stack. Also, the headers within
the protocol can actually be quite big. If we only count the number of bytes
between the two IP layers in this stack: 8 bytes UDP, 4 bytes NS, 20 bytes
BSSGP, 6 bytes LLC and 4 byte SNDCP. That's a total of 42 extra bytes. And
that for every small packet like TCP SYN, SYN/ACK or the like! No wonder
that mobile data plans have been prohibitively expensive all those years ;)
So with regard to the actual GPRS implementation in OpenBSC, the following
things had (or still have) to be done
- Add support for generating System Information 3 + 4 rest octets and System Information 13
This is a very time-consuming bit-fucking experience, encoded relative to the padding pattern of 0x2b. Without this, the phones would not realize that the cell actually supports GPRS. DONE.
- Add support for the ip.access extensions to the A-bis OML (TS 12.21) layer
This is needed to configure the GPRS parameters such as channel configuration, coding schemes or the IP and NS/BSSGP parameters for the link to the SGSN (OpenBSC). Without it, the BTS would not even start to speak NS/BSSGP, i.e. not connect to OpenBSC for GPRS services. DONE.
- Implement the NS protocol (GSM TS 08.16)
Turns out this was really simple, as NS doesn't really do much anyway. DONE.
- Implement the BSSGP protocol (GSM TS 08.18)
This protocol is - among other things - responsible for the flow control. Both globally for the
BTS as well as individually for each MS. I've implemented the basic functionality to be able to
send/receive signalling and user data, but no flow control yet.
- Implement the LLC protocol (GSM TS 04.64)
This is actually the protocol that is terminated between the MS and the SGSN, so we have moved
beyond the BTS level here. Actual data from/to the mobile phone. I've implemented a minimal subset
of it, including the CRC24 checksumming. I'm not taking care of packet loss,
retransmissions or fragmentation yet. Just simple S, UI or U frames.
- Implement the GPRS mobility management (GSM TS 04.08)
This is pretty much work in progress, but GPRS ATTACH and ROUTING AREA
UPDATE is already handled. More work needed here, especially with regard to
persistent storage of P-TMSI allocations as well as the last-seen position of every MS
in a database.
- Implement the GPRS session management (GSM TS 04.08)
This is the messages for activating and de-activating PDP contexts. Work has not started yet.
- Implement GGSN functionality (PPP tunnel endpoints
After all, we need to terminate the PPP sessions that the phones establish somewhere. Work has not started yet
Once all that full stack has reached a level where it works to a minimal
extent, issues like BSSGP flow-control as well as LLC re-transmission,
fragmentation and [selective] acknowledgement have to be dealt with.
Finally, if somebody is bored enough, he could also work on things like combined
GSM/GPRS attach, or SMS over GPRS.
As you can see, it's quite a large task. But we need to start somewhere, and a
lot of this will still be needed when moving into the 3G and 3.5G domain. Even
if not at the lower level protocols, but from the software architecture point.
If you're into communications protocol development and don't mind our ascetic
'plain old C language' approach and are interested to contribute, feel free to
introduce yourself on the OpenBSC mailing list.