I will talk a little about Bluetooth clock and CSP protocol, which is an optional part of MCAP.
Each Bluetooth device has an internal clock that is never reset or adjusted, and ticks 3200 times/s. This clock increments a 28-bit counter, which wraps around in less than one day. The BT clock can be read by any user application via an HCI socket.
Many BT things depend heavily on this clock, e.g. the radio frequency "hops" that happen every two clock cycles (that is, 1600 times/s).
In every Bluetooth piconet, there is one master and a number of slaves. All devices must hop channels in the same fashion to be able to communicate, which implies that all devices' clocks must be synchronized. The slaves' clocks are kept in sync with master by adding an offset value, so the following equation is true:
local clock + offset = master's clock
The master's offset is zero. Since the BT clock precision is not incredibly high (and gets worse when idle), the slaves must adjust the offset periodically. This is taken care of by Bluetooth, we don't need to worry with this in our application.
A BT device may participate (as slave) in more than one piconet. If there are two piconets, we have three readable clock values: local (or native), master 1, and master 2 (the latter ones obtained by adding piconet 1's offset and piconet 2's offset, respectively).
When we read the piconet's clock via HCI socket, we need to give the ACL connection handle (ACL is the asynchronous channel between a pair of devices, which bears all RFCOMM and L2CAP connections). Passing ACL handle indirectly identifies the targeted piconet. Naturally, we don't specify the ACL to read the local clock value.
We can imagine a situation in which several BT devices are sending periodic information, and we would like to know the exact moment in which every piece of information was generated.
The 'canonical' example is a transport belt with several optical sensors in the way. When an object is being transported by the belt, it triggers the sensors in sequence, which send the event upstream to a concentrator.
If the concentrator wants to calculate e.g. the belt speed, it can't trust the time of arrival of the events, not even the arrival order, because many delay factors will interfere in data transmission. The sensor itself must "stamp" time on every event, and then send it upstream.
Then we have the problem of synchronizing the clocks of all sensors, so the timestamps are directly comparable. The concentrator must somehow reset all sensors at the same time, which is not trivial. Even with LAN broadcast, there will always be transmission and processing delays, and the sensors' clocks would always diverge.
In case of Bluetooth, we have a common, synchronized clock, which is the piconet clock; but its precision and resolution may not be enough.
In the other hand, most operating systems keep a system clock with good precision and microsecond resolution. But it is not easily synchronizable. Each computer-sensor in a network will surely have slightly different system time.
Even if the concentrator had a way to reset all sensors' clocks, they also have different drift rates, and they would eventually fall out of sync again. The concentrator needs a way to know if deviations are mounting above a tolerable threshold, at when a new reset is needed.
This article does not cover MCAP. For now, I say that CSP is an optional part of the MCAP protocol. CSP is all about timestamp synchronization.
The main CSP trick is to use both clocks (Bluetooth and system), leveraging the strong points of each one. There is no magic, it is something that any application protocol could implement by itself; the CSP "advantage" is being a formal Bluetooth standard.
Since MCAP establishes point-to-point connections (like most protocols), CSP specifies two roles: master and slave, one for each side. In the transport belt example, the concentrator would take the master role in every connection with each sensor.
CSP solves the resolution problem by adopting a 64-bit, microsecond-counting relative timestamp. The master may request the slave to reset the timestamp at any moment.
At slave side, the straightforward implementation of a microsecond-resolution timestamp is to read gettimeofday() upon reset, and read it again when an event needs to be timestamped. The difference is the relative timestamp; and gettimeofday() has microsecond resolution.
Syncronization is solved with Bluetooth clock. CSP allows the master to schedule the timestamp reset into the future — that is, when the BT clock reaches a given value. This allows the master to schedule timestamp reset on any number of slaves "at the same time" (into the future), with no need to hurry.
The remaining problem is system clock drift in each slave. Fortunately, CSP has two mechanisms to cope with this:
a) The slave may be configured to send (BT clock, timestamp) tuples periodically. The frequency is determined by the clock precision of the slave, as well as the precision demanded by master. (For example, if master demands 1000 parts per million, and slave has precision of 20ppm, it would send the tuple once every 50 seconds.)
b) CSP allows the master to reset any slave's timestamp to any given value, not only to zero. This allows the master to make small compensations for every slave, instead of having to reset everyone to zero.
Since the BT clock is guaranteed to be synchronized, the periodic indication of (BT clock, timestamp) from slave allows drift calculation and taking corrective measures.
Note that CSP only offers a mechanism to synchronize the timestamp. The actual "timestamping" of events, the transmission of events to the concentrator etc. are application's responsability.