libcmtspeechdata API documentation

Copyright (C) 2009,2010 Nokia Corporation. All rights reserved.

## Table of contents

- Introduction
- API Versioning
- Library backend implementations
- Instance Management
- Handling library events
- Passing call signaling events to library
- Actions initiated by application

# Introduction

Libcmtspeechdata provides an application interface for implementing the speech data path for cellular voice calls. The library depends on other components for setting up and managing the call signaling path.

CMT is abbreviation of Cellular Modem Terminal, i.e. the cellular modem. APE refers to Application Engine, i.e. the processing environment where libcmtspeechdata is run. E.g. in Nokia N900, APE the TI OMAP3 processor. SSI refers to Synchronous Serial Interface, which is a serial bus found on TI OMAP application engines as well as on Nokia cellular modems. SSI is used as the low-level interface used to communicate between APE and CMT.

This documentation covers the public interface of the library. It is meant for developers using libcmtspeechdata.

# API Versioning

The libcmtspeechdata package version consist of components X.Y.Z.

X reflects the major version number and is incremented for major architectural/design changes.

Y reflects the library interface version and this is incremented every time the public API has been extended since the last release (and is reset to zero if X changes). Z reflects an update to the library implementation and/or applications distributed with the package (and is reset to zero if Y changes).

Applications may query these versions at build time with (defined when including <cmtspeech.h>):

- LIBCMTSPEECHDATA_MAJOR
- LIBCMTSPEECHDATA_PROTOCOL_VERSION
- LIBCMTSPEECHDATA_API_VERSION
- LIBCMTSPEECHDATA_MINOR_VERSION

Or at runtime with:

- cmtspeech_version_str() (returns a string)
- cmtspeech_protocol_version() (returns an integer)

# Library backend implementations

The library may be built using different backends. Typically binary runtime packages will be available at least for the main hardware implementation, and one using a dummy backend (not talking to a real modem). The alternative implementations are called library backends. Currently available backends are:

## Dummy

A user-space implementation of the CMT Speech Data SSI protocol.

## Nokia Modem

Implementation of the CMT Speech Data Backend interface for Nokia modems (e.g. Maemo5 / Nokia N900). See notes in the libcmtspeechdata README-devel.txt file in section "Internals: Resource allocation in Nokia Modem backend".

## Null

A null implementaton of library backend. Provides no functinality, but provides an example how to integrate new modem backends to the library.

# Instance Management

Before using any other library functions, application should call cmtspeech_init(). This function needs to be called once per application process startup.

All other library functions operate on a given instance of the library. A new instance is created with cmtspeech_open().

Application should create the library instance at the earliest possible moment, preferably right after the cellular modem is powered up. The reason for this is that opening the device with cmtspeech_open() involves allocation of various resources (memory, opening the kernel device, etc), and thus it has non-deterministic execution time. Note that it is also possible to open the library instance even though the cellular modem is not yet fully functional.

Similarly cmtspeech_close() should only be called when cellular modem is powered off (and no calls are no longer made), or in error cases (e.g. application has detected, perhaps via some other API, that modem has crashed/rebooted).

# Handling library events

Once library instance is open, application should monitor for possible events by polling (with e.g. poll() or select()) the file descriptor returned by cmtspeech_descriptor(). If the descriptor becomes readable, application should immediately call cmtspeech_check_pending().

Bitmask of available events is returned by cmtspeech_check_pending() via the '`int *flags`' argument. If the returned bitmask includes CMTSPEECH_EVENT_CONTROL, a control event is available and may be fetched with cmtspeech_read_event(). The library maintains a fixed size queue for the control events, which can overflow if the application does not fetch the events in time.

NOTE: As libcmtspeechdata does not have its own event loop, only those state changes, that are triggered by incoming messages from the modem, are reported as events.

An event contains the following information:

- the new protocol state (one of CMTSPEECH_STATE_* defined in cmtspeech.h)
  - cmtspeech_event_t field '`state`'
- the previous protocol state (CMTSPEECH_STATE_*)
  - cmtspeech_event_t field '`prev_state`'
- a copy of the protocol message that caused the state change
  - cmtspeech_event_t fields '`msg_type`' and '`msg`'

Most applications should use cmtspeech_event_to_state_transition() to convert the event object to an enumerated state transition, and handle the result e.g. in a switch loop.

Here is a list of state transitions reported by cmtspeech_event_to_state_transition(). Some of the events are purely informational, while some require specific actions from the application.

## CMTSPEECH_TR_1_CONNECTED

Triggering protocol message is CMTSPEECH_SSI_CONFIG_RESP.

This event indicates that the cellular modem has acknowledged activation of the data path for speech frame exchange. The current SSI connection status can be queried at any time with cmtspeech_is_ssi_connection_enabled().

## CMTSPEECH_TR_2_DISCONNECTED

Triggering protocol message is CMTSPEECH_SSI_CONFIG_RESP.

This event indicates that the cellular modem has acknowledged deactivation of the data path for speech frame exchange.

## CMTSPEECH_TR_3_DL_START

Triggering protocol message is: CMTSPEECH_SPEECH_CONFIG_REQ

This event is used by the cellular modem to initiate transfer of downlink speech frames (from network). After this message, application should be prepared to receive CMTSPEECH_EVENT_DATA events. After this event cmtspeech_is_active() will return true.

## CMTSPEECH_TR_4_DL_STOP

Triggering protocol message is: CMTSPEECH_SPEECH_CONFIG_REQ

This event signals that call termination has started and the speech data stream has been closed. After this event cmtspeech_is_active() will return '`false`'.

Application should immediate release any uplink or downlink buffers it has acquired from the library. The protocol state cannot go from CONNECTED to DISCONNECTED until all speech buffers, acquired with cmtspeech_ul_buffer_acquire() and cmtspeech_dl_buffer_acquire(), have been released back to the library.

Note that this event can occur in both ACTIVE_DL and ACTIVE_DLUL protocol states.

## CMTSPEECH_TR_6_TIMING_UPDATE

Triggering protocol message is: CMTSPEECH_TIMING_CONFIG_NTF

Similar to CMTSPEECH_TR_7_TIMING_UPDATE (see CMTSPEECH_TR_7_TIMING_UPDATE), but the timing update was explicitly requested by APE using cmtspeech_send_timing_request().

Note that library implementation may not necessarily be able to distinguish between TR_6 and TR_7, so both cases should be handled, and application must not rely on getting a TR_6 even if it issues cmtspeech_send_timing_request().

## CMTSPEECH_TR_7_TIMING_UPDATE

Triggering protocol message is: CMTSPEECH_TIMING_CONFIG_NTF

When new uplink timing parameters are sent by the modem, the protocol state doesn't change, but an event is still generated to relay the timing information to the client.

See also CMTSPEECH_TR_6_TIMING_UPDATE.

## CMTSPEECH_TR_10_RESET

Triggering protocol message is: CMTSPEECH_EVENT_RESET

This event signals an error in protocol operation. Client can check the event message parameter '`cmt_sent_req`' (cmtspeech_event_t) to see whether it was CMT or APE that raised the error.

## CMTSPEECH_TR_11_UL_STOP

Triggering protocol message: CMTSPEECH_SPEECH_CONFIG_REQ

This transition occurs when the speech channel parameters are changed during a call (e.g. due to a handover), and the uplink frame transmission should be stopped and reconfiguration is complete.

The application should check the ...

`cmtevent.msg.speech_config_req.layout_changed`

... field of the received event (cmtspeech_event_t). If this is set to '`true`', all uplink and downlink buffers currently held by the application have become invalid and should be released back to the library as soon as possible (using cmtspeech_dl_buffer_release() and cmtspeech_ul_buffer_release()). When the invalidated uplink buffers are released, no uplink frame is sent to the network.

As all data traffic between APE and CMT is disabled until the buffers are released, application must act as quickly as possible. The current buffer contents are still accessible, so application can e.g. copy data out from the buffers, before releasing them back to the library.

See also CMTSPEECH_TR_4_DL_STOP.

## CMTSPEECH_TR_12_UL_START

Triggering protocol message is: CMTSPEECH_UPLINK_CONFIG_NTF

With this event, cellular modem notifies APE that it has configured the DMA for uplink frame transfers, and that APE can start sending uplink frames.

Once this event is received, application should start sending uplink speech frames with cmtspeech_ul_buffer_acquire() and cmtspeech_ul_buffer_release(). Modem may request APE to adjust the uplink timing at any time (see section CMTSPEECH_TR_6_TIMING_UPDATE and CMTSPEECH_TR_7_TIMING_UPDATE).

# Passing call signaling events to library

The libcmtspeechdata library only handles data path communication towards the modem. There are however many dependencies between call control signaling and the data path setup, which the library client is responsible to handle.

In Maemo5 (and Maemo6), client application can get the needed event information by subscribing to DBus events on the "com.nokia.csd.Call" interface. These messages are handled by Call Plugin (csd-call) to the Cellular Services Daemon (csd). Additionally application needs to listen for modem state changes events on the "com.nokia.phone.SSC" DBus interface.

The following call signaling state changes need to be relayed to libcmtspeechdata:

## 1. Change in call signaling server status

When call signaling is started, or call signaling has terminated, client must pass the change state to the library with cmtspeech_state_change_call_status() API function.

On Nokia modems, this state is the modem Call Server status (active or inactive). In Maemo5/6, this state is signaled by CSD using the 'com.nokia.csd.Call.ServerStatus' DBus interface.

## 2. Change in call connected status

When call connection status changes (audio traffic channel is connected or disconnected), client must pass this state change to the library with cmtspeech_state_change_call_connect() API function.

In Maemo5/6, there are two DBus signals emitted by CSD when connection status changes. The signals are 'com.nokia.csd.Call.Instance.AudioConnect' and 'com.nokia.csd.Call.UserConnection' signals (both signals are emitted).

Again in Maemo5/6, it is currently recommended to listen to 'UserConnection(boolean)' and pass the paramater to libcmtspeechdata using the cmtspeech_state_change_call_connect() function. If 'AudioConnect' is used, the 'downlink' signal parameter should be passed on to cmtspeech_state_change_call_connect().

In addition to passing the information to the library, changes in call connection status may also impact application's own processing logic. E.g. when call is active, but not connected, the uplink frames are used only for timing. Thus the uplink frames provided to the library need not contain valid audio, and e.g. any additional CPU-intensive processing may be still disabled in this state. For example it is ok to send muted frames. The reason to keep sending uplink frames throughout calls is to maintain network timing.

NOTE: Unlike uplink frames, which are sent all the time during a call, there can be gaps in the stream of downlink data frames. This can happen e.g. at start of the call before call is connected and during call hold. It is important that the application's playout mechanism can handle this case.

@subsect modem_state_change 3. Modem state change

Monitoring modem state changes is needed purely for handling exceptional error cases. In practise this means uncontrolled modem reboots (crashes and error states that cause a forced reboot).

In Maemo5/6, the SSCD component (System State Controller Daemon) emits DBus signals for all modem state changes. The emitted signal is "com.nokia.phone.SSC.modem_state_changed_ind". If the state changes to "Initialize" while a libcmtspeechdata instance is not in disconnected state (cmtspeech_protocol_state() != CMTSPEECH_STATE_DISCONNECTED), application should consider the modem to have rebooted and close the library instance with cmtspeech_close().

The consequences of not closing the library instance in these error cases, are highly implementation specific. But for instance in Maemo5 devices, it is critical to correctly handle this scenario as keeping the libcmtspeechdata instance open even after the modem reboots, prevents from reestablishing the CMT-APE SSI connection, even if modem does succesfully boot back up. This is a fatal condition as the only way to recover is a reboot of the whole device. But with appropriate reaction to the modem reset, fast recovery is possible and no reboot is needed.

# Actions initiated by application

Once a call is established, the only libcmtspeechdata activity that needs to be triggered by the application (e.g. based on audio hardware interrupts, or using a system timer to wake up), is sending of uplink speech frames. The frames need to be sent according to the timing information provided by CMT. All other actions are triggered by either inbound events from the CMT, or by call signaling related DBus events.

One optional action the application may take is to request for refreshed uplink timing. This can be accomplished by calling cmtspeech_send_timing_request().