Version: 0.1 This document contains information which is the property of LiPS Forum. The acceptance of this document by its recipient implies, on the latter's part, recognition of the confidential nature of its content and the undertaking not to make any reproduction, no transmission to third parties, no disclosure and no commercial utilization without the prior written agreement of LiPS Forum.
This document is a liaison statement from the LiPS Forum’s Telephony API Working Group (TWG) to the Consumer Electronics Linux Forum’s (CELF) Mobile Phone Profile Working Group (MPPWG). LiPS Forum’s TWG is currently evaluating the applicability of CELF’s MPP telephony-related APIs to its own set of API specifications. After a first analysis of CELF’s MPP specifications, LiPS TWG contributors would like to go through some key technical questions in order to assess if both organizations can foster a common approach on Telephony APIs. The technical issues described in this document are mostly related to the programming model and functional granularity level of CELF’s MPP telephony APIs. LiPS TWG contributors would appreciate some feedback on these important questions.
Creation of the document
§ = modified chapter(s) or paragraph(s) Action = C : Creation, M : Modification, S : Suppression
TABLE OF CONTENTS
1 Introduction 4
2 Technical issues raised by LiPS Forum TWG 4
2.1 Programming Model 4
2.1.1 Asynchronous requests 4
2.1.2 Unsolicited events 5
2.1.3 Callbacks & Events 5
2.2 Functional Scope issues 5
3 References 6
4 Appendix 1: LiPS Programming Model 7
4.1 Rationale 7
4.2 Event Model 7
4.3 Asynchronous requests 8
4.4 "Connectedness" 8
4.5 Dynamic discovery / configurability 9
4.6 Extensibility 9
4.7 Memory allocation policy 10
4.8 Syntax guidelines 10
4.9 Header files naming conventions 10
4.10 LiPS APIs design patterns 10
4.10.1 Registration with a service – Session pattern 10
The Telephony Working Group of LiPS Forum has reviewed CELF’s MPP set of specifications dated March, 14th 2006 (see references below).
As presented in the past, the goal of this review is to assess the applicability of MPPWG’s APIs to the telephony service set identified by LiPS as one of the core services to be included in its specifications set.
The analysis has focused on programming model-related aspects and on functionality aspects.
The next sections include technical issues to be addressed for convergence of LiPS TAPI WG and CELF MPP WG specifications to converge.
2Technical issues raised by LiPS Forum TWG
This section outlines the technical issues raised by LiPS members as an obstacle to the convergence of CELF’s MMPWG APIs and the LiPS specifications in the telephony area.
The major issues we found during the review are related to the programming model. We think that before talking about the APIs themselves we should agree on those points, as there are the bases of the specification.
The new set of specifications does define how the client can register to unsolicited notification through callback, but it does not define how are asynchronous requests initiated and also how the clients detect their completion. Indeed, none of the Circuit Switched and Packet Switched Services have asynchronous APIs.
Allowing APIs to be processed in an asynchronous manner is really important as many telephony related APIs calls involve long processing operations (e.g. searching for available PLMNs, reading the content of a file stored in the SIM card…). The LiPS TWG will propose asynchronous facilities to all the APIs that interact with the radio stack (including SIM card) and the network (see Section 4.3).
In addition, supporting asynchronous calls will imply to add a request identification parameter to all affected APIs. This parameter will allow the callback to identify which specific request has been completed. It also will allow to set up an asynchronous request cancellation mechanism.
The CELF MPP API registration to the unsolicited events is service specific and relies on bit mask. This method, as mentioned in the prior liaison document, makes the API more difficult and degrades the readability. The LiPS TWG approach is based first on the ability for an application to register either to all the events belonging to a specific service or to register to all the telephony events. Secondly, another generic API will allow the application to register to a single unsolicited event no matter of the service it belongs to. Therefore it will be possible to specify a callback for a specific event or for a set of events.
2.1.3Callbacks & Events
The CELF MPP programming model specifies that the server monitors the events and as soon as one of them occurs it calls the client callbacks in the process context of the client. No more information is given regarding how this is achieved as it is not covered by the specification. This point is very important as the way this is implemented will vary between implementations and will introduce specific mechanism/behavior with which the applications will have to deal.
From the LiPS specification perspective, it has been decided that the client will be in charge of checking whether there is a pending event or not. As the event structure contains above all the pointer to the callback there is no issues with the context of its execution. In addition, this mechanism simplifies the development of applications with UI as the event loop can be shared.
2.2Functional Scope issues
We understand the functional scope of CELF MPP API to cover:
Circuit-Switched Communication Services (3G) 
Packet-Switched Communication Services (3G) 
Short Messaging Service 
Lighting Service 
Equipment Service 
LiPS Forum TWG members still believe that some major parts of “Equipment Service” (e.g. keypad, alert) should not be covered by Telephony specifications as there are related to other domains of specifications such as UI services, audio framework, power management; or even specific to the design of the terminal’s MMI….
Similarly, the “Lighting Service” should be covered as part of a more generic hardware-related framework.
The other communication services should be more closely reviewed to also cover the needs of 2G/ 2.5 G devices and not just 3G devices. Moreover, several other services should be covered:
SIM Application Toolkit
Security (Facility Locks, PIN Codes)
Unstructured Supplementary Services Data
Phonebooks (Radio internal and SIM card ones)
“LiPS Reference Model”, LiPS Forum Architecture Working Group, version 0.4, 10 February 2006.
“Linux based 3G specification – Multimedia Mobile Phone API - Preface”, CELF Mobile Phone Profile WG, Doc#: CELF_MPP_Preface_FR1_20060301 (MppApiPreface-FR1.pdf), March 1st 2006.
“Linux based 3G specification – Multimedia Mobile Phone API – Reference Architecture”, CELF Mobile Phone Profile WG, Doc#: CELF_MPP_RA_FR1_20060301 (MppApiRefArch-FR1.pdf), March 1st 2006.
“Linux based 3G specification – Multimedia Mobile Phone API – Circuit-Switched Communication Service”, CELF Mobile Phone Profile WG, Doc#: CELF_MPP_CS_FR1_20060301 (MppApiCs-FR1.pdf), March 1st 2006.
“Linux based 3G specification – Multimedia Mobile Phone API – Packet-Switched Communication Service”, CELF Mobile Phone Profile WG, Doc#: CELF_MPP_PS_FR1_20060301 (MppApiPs-FR1.pdf) , March 1st 2006.
“Linux based 3G specification – Multimedia Mobile Phone API – Short Message Service”, CELF Mobile Phone Profile WG, Doc#: CELF_MPP_SMS_D_2.2_20051121 (MppApiSms-2.2.pdf), 21 November 2005.
“Linux based 3G specification – Multimedia Mobile Phone API – Equipment Service”, CELF Mobile Phone Profile WG, Doc#: CELF_MPP_ES_D_V2.2.2_<20051031> (MPP-API-equipment-2.2.2-preece-notes.pdf), 31 October 2005.
“Linux based 3G specification – Multimedia Mobile Phone API – Lighting Service”, CELF Mobile Phone Profile WG, Doc#: CELF_MPP_PS_D_v2.2.2_20051114 (MppApiLamp_2.2.2.pdf), 14 November 2005.
4Appendix 1: LiPS Programming Model
The sub-sections 4.1-4.8 of this section captures the needs and the scope of API design patterns to be used by LiPS Technical WG working on new APIs specifications, whereas the sub-section 4.10 describes those patterns.
In the scope of its activities, the LiPS Forum may need to specify APIs of services for which no "standard" API is available from e.g. other bodies (e.g. OSDL, IEEE...) or from open-source projects (e.g. GTK).
Examples of such services include: telephony, OMA enabler services (Messaging, Browsing ...).
In order for these APIs to form a coherent set from the developer point of view, LiPS needs to define a number of guidelines that the API specifications produced by LiPS will follow.
These guidelines cover areas like:
Memory allocation policy
Most services will involve the need to manage events that happen in an unsolicited manner (e.g. incoming phone call) or requests that complete asynchronously and therefore require to notify the caller after through some event (see also "Synchronism" below).
Different programming models are possible for managing such asynchronous events:
Callback functions registered by the clients of the interface
Specific (synchronous) requests to collect events. In addition a mechanism could be provided to notify the client that some pending events are available (e.g. a file descriptor that client can poll using select() system call); otherwise, a special thread should be used to collect incoming events.
LiPS programming model requires API designers to use the Event design pattern (see the Section 4.10.2) which combines both above described models.
Asynchronous requests are needed in the case of transactions that take a "long" time to complete (e.g. search for available wireless networks or search through the SIM addressbook) and when the client wish to perform some unrelated (e.g. start another transaction) or related (e.g. cancel a transaction in progress or request a progress status report) action avoiding creation of another thread.
Any function exposed by a LiPS service could potentially exist in two forms: synchronous and asynchronous. The decision about whether a given function needs to be synchronous only, asynchronous only or both belong to the API designer. Nevertheless, if a function is specified as an asynchronous request or has both forms a common specification pattern must be followed.
LiPS Programming model requires API designers to use the Async Request design pattern as described in the Section 4.10.3 below.
In order to enable concurrent access to a LiPS service by several clients at a time and/or to efficiently enforce a security policy related to the client rights to access a service, it may be necessary for clients to register with the service in a client-server model.
[Note that server here and below means the service implementation]
An example is for instance an SMS service which may need to be accessed concurrently by the WAP stack to handle MMS notifications, by the Java Virtual Machine to handle MIDLETs downloaded over SMS and by the Message editor.
In the LiPS APIs, concurrent access could be handled in several ways:
connected mode: all applications have to register ("connect") with LiPS services in a client-server fashion.
disconnected mode: applications do not need to "connect" either because
the service is intrinsically stateless or because
the client provides all client related state in each call.
On a case by case basis the "connectedness" requirement for a specific service must be assessed.
If a service requires a connected mode the LiPS programming model requires the corresponding API designers to use the Session design pattern as described in the Section 4.10.1 below.
4.5Dynamic discovery / configurability
Different LiPS devices may not offer the same level of features (e.g. support of Cell Broadcast services, etc.) or capabilities (e.g. capacity of SIM phonebook, etc.).
On the other hand, it may be desirable that a LiPS application be able to run without the need of being rebuilt for different devices.
Therefore, it may be desirable to introduce APIs to dynamically discover the capabilities / features of LiPS services available on a device.
The decision of whether for a particular LiPS service a dynamic discovery of features makes sense should be taken by the service designers.
If a feature discovery interface is provided as a part of a particular service API it should follow a "standard" LiPS "feature discovery" pattern.
An alternative approach could consist in specification of a Service Discovery API (e.g. as a part of Platform Management Services) that allows applications to query the platform about the services (APIs) available on the platform and their features.
F Designers of a LiPS service API shall specify optional features and capabilities of the API as a hierarchy of [property, value]pairs, where the property names a feature or a capability and the value describes it.
urthermore, whatever the approach will be adopted by LiPS to query available features, a standard pattern to describe those features should also be adopted.
LiPS services specifications will offer a certain level of features. For instance, the initial release of LiPS specifications may not include APIs to control advanced features of 3G bearers. However, a device implementer may want to extend the LiPS service set using a generic extension capability offered by the LiPS platform.
An implementation may provide extensions of services and even some (ioctl() like) APIs to invoke those extensions. Nevertheless, those extensions and even the APIs and mechanisms that make those extensions available for applications will be out of the scope of LiPS: an application that uses non-standard APIs will not be able to run on any other LiPS-compliant platform which does not implement those extensions even if the extensions are invoked through some standard APIs.
For example if the Telephony API provides a generic function to send some custom AT commands to modem, even if the function is implemented on all LiPS platforms the application that uses this function will run only on devices which support those custom AT command.
In other words there is no reason to standardize a mechanism to introduce and use non-standard extensions.
4.7Memory allocation policy
LiPS APIs extensively manipulate data structures between applications and services. Consequently, a standard policy for the allocation and freeing of the memory is required.
The following policy is proposed:
Avoid variable length data as much as possible
Do not share the responsibility of allocating and freeing the memory between client and server, in particular:
For synchronous functions, memory allocation and freeing should be performed by the client (application)
For asynchronous requests memory allocation issues should be addressed in the proposed event model
For coherence towards developers, a standard set of "coding" guidelines should be followed in the LiPS APIs syntax. Please refer to Section 5 for details.
4.9Header files naming conventions
Header file names should be relatively short (less than 10 characters), low case and typically without underscores ('_') characters.
Header files shall be self-contained – inclusion of one header file shall never require inclusion of another header file.
4.10LiPS APIs design patterns
4.10.1Registration with a service – Session pattern
When a reasonable implementation of a service requires a connection to be established between the client of the service and the server the Session design pattern shall be used in the service API design.
The Session pattern requires that a client starts to use a service calling an open_session request and ends calling a close_session request. The open_session request shall return to the client an opaque session_identifier that subsequently shall be used as an input argument in any other request to the service. The session_identifier shall be wide enough to contain a pointer and is typically a 32-bits word.
The open_session and close_session requests shall be named >_open_session() and _close_session() respectively where is a short service-specific abbreviation. The session_identifier type shall be named _sid_t.
For example TAPI uses the Session pattern as following:
typedef uint32_t tel_sid_t;
tel_err_t tel_open_session (tel_sid_t*, );
tel_err_t tel_close_session (tel_sid_t);
4.10.2Unsolicited events – Event pattern
When a service involves delivery of unsolicited events (see the Section 4.2) the Event design pattern shall be used.
The Event pattern assumes that the Session design pattern (see the Subsection 4.10.1) is also used in the service API design. In other words management of unsolicited events requires a connection to be established with the server.
The Event pattern requires an explicit client registration for the unsolicited events the client is interested for, using a sequence of event_register requests – one request per unsolicited event type1. In addition to the event type specified by an enumeration event_type parameter the client shall specify in the request the address of a callback - a client's function to be invoked upon an event reception, and a user_data – an opaque data to be passed back to the client in the callback invocation.
The event_register request, the event_type enumeration and the callback function type shall be named
_evt_register(), >_evt_type_t and _evt_cb_t respectively. The void* type shall be used for the user_data value.
For example TAPI defines the event_register request as following:
The Event pattern requires an event_unregister request to allow clients to cease registration for a particular type of events the client has previously successfully registered. The event_unregisterrequest shall be named
The Event pattern also requires the API to provide the client with a get_fd request which shall return a regular file descriptor that enable the client to check pending events using a select() (or a poll()) system call. The get_fd request shall be named
_get_evt_fd(), as in this TAPI example:
tel_err_t tel_get_evt_fd (tel_sid_t, int* fd);
Finally, the Event pattern requires two event delivery requests: event_process and event_get.
Both requests shall support three forms: blocking, non-blocking and timed-out. The blocking form may block for an undetermined amount of time waiting for an event. The non-blocking form always returns immediately either delivering a pending event or with an error code when there is no pending events to deliver. The timed-out form may block waiting for an event but will return with an error if there is no events to deliver within a specified time interval. Three forms shall be differentiated by the value of a timeout argument: 0, -1 or a positive time-out value for non-blocking, blocking and timed-out forms respectively.
The event_process request delivers an event to the client by calling the callback function specified through the corresponding event_register request. The callback function is called in the context of the event_process request. The arguments of a callback shall be a session_identifier and a pointer to an event descriptor structure which shall hold the following fields:
event_type (see above)
callback function2 (see above)
user_data pointer (see above)
event_data – a pointer to an event_type specific data structure
The design pattern allows to designers of a specific API to extend the event_descriptor with some API-specific fields if needed.
The event_descriptor and event_data are accessible during the callback function code execution only: and both data structures may be released by the service implementation (i.e. server) when the callback returns.
The design pattern allows the callback function to return a value if needed. This choice (as well as the choice of the type and of the meaning of the return value) belongs to the API designer.
The naming rules for the event_process request, the event_descriptor structure and the callback function type are similar to the other naming rules detailed above and can be easily deduced from the TAPI example below:
The event_get request delivers a pending event to the client as an event_descriptor. Once delivered the client may access any information contained in the descriptor. The Event pattern shell provide also the client with a event_call helper request, which simply invokes the callback function contained in the descriptor, and an event_release request, which release all resources the implementation (i.e. server) has allocated for the event including the event_descriptor it-self.
Note also that calling the event_release request the client notifies the service implementation about the event processing completion – an important synchronization point with potentially concurrent event_unregister and cancel (see Section 4.10.3) requests. In the case of an event delivered via an even_process request the event processing completion is notified implicitly when the client returns from the callback function.
The API shall accept any callback value (including NULL) passed in the event_register request. Nevertheless, if the value is not a valid address of a client function, the event_process and event_call requests may have an unpredictable result.
The naming rules for the event_get, event_call, and event_release requests are similar to the naming rules described above and can be easily deduced from the TAPI example below:
tel_err_t tel_evt_get (sid_t sid, tel_evt_t**, int timeout); tel_err_t tel_evt_call (sid_t sid, tel_evt_t* evt); tel_err_t tel_evt_release (sid_t sid, tel_evt_t* evt); The API specification shall clearly specify the expected implementation behavior in the case when an event_unregister request action happens concurrently with actions of delivery and processing of events of the corresponding type. We recommend that the event_unregister request return different error codes in the following situations:
Success: the client has been successfully unregistered and no new events of this will be delivered to the client.
Failure: processing of at least one event of this type already delivered to the client has not been completed yet by the client (i.e. notified to the server either explicitly through an event_release request or implicitly returning from the callback function). In this the client remains registered and may renew the event_unregister request after all events processing completion.
The Async Request design pattern requires that asynchronous request status events are delivered to the client through a set of (synchronous) requests designed according to the Event design pattern (see the Section 4.10.2). If the service API involves unsolicited events the same set of requests shall be used for those unsolicited events as well.
The list of concerned requests is event_process, event_get, event_call and event_release.
The Async Request design pattern requires that clients specify a callbackfunction and a user_data each time when a new asynchronous request is initiated – thus, the event_register request is not relevant for the Async Request pattern.
The request initiation function shall return to the client an async_request_indentifer, which then will be used to identify the request. Similar to the session_identifier the async_request_indentifer must be wide enough to contain a pointer and is typically a 32-bits word.
The identifier shall be named _rid_t.
For example an asynchronous TAPI request will have the following form:
In the case of an asynchronous request status event, the event_destriptor structure passed to the client as an argument of the callback function and/or returned to the client as a result of the event_get request, gets the following additional fields:
async_request_identifier (see above)
async_request_state – completed, canceled (see below) or any other service specific status, e.g. request progress notification.
The implementation may reuse an async_request_identitifier as soon as the corresponding asynchronous request is fully processed, i.e. the request processing has been terminated on the server side, the corresponding status event has been delivered to the client and the client has notified completion of the event processing either via an event_release request or just returning from the callback function.
The Async Request design pattern also requires that for each asynchronous request the service API provides a specific cancel request. For example the cancel request for the TAPI above will have the following form:
tel_err_t tel__cancel (tel_sid_t, tel_rid_t);
In response to a cancel request the service implementation shall terminate (abort) the corresponding asynchronous request and post to the client a cancelled event, i.e. a request status event with the async_request_state field equal to 'cancelled'.
The cancelled event is exclusive with completed event and the last event delivered to the client shall always be one of those. Thus, the only sequence of events related to a given asynchronous request that may be observed by the client shall be:
('notify')* ('completed' | 'canceled')
where 'notify' stands for any other service specific event, e.g. the asynchronous request progress notification.
Note that the cancel request may return before the corresponding 'cancelled' request is delivered to the client. Moreover, some 'notify' events may still pend in the client's event queue. Thus, the client shall be able to process 'notify' events at any time even in the window between return from a cancel request and delivery to the client of the corresponding 'canceled' event.
The API specification shall clearly specify the expected implementation behavior in the case when a cancel request is performed concurrently with completion by the server of the corresponding asynchronous request, delivery to the client of the corresponding completion event and (3) the event processing by the client. We recommend the cancel request to return different error codes in the following situations:
The request has been successfully canceled. In this (and only this) case the implementation will post an event with the req_state equal to canceled.
There are no asynchronous requests corresponding to the specified async_request_identifier. This may happen either when a wrong async_request_identintifier has been specified or when the request has been already fully processed (see above)
[NB: Clients should very careful assuming that an async_request_identintifier may be assigned to a new request as soon that the request the async_request_identintifier has been assigned previously is fully processed.]
An event corresponding to the asynchronous request completion is already pending.
An event corresponding to the asynchronous request completion has been already delivered to the client but the client has not released yet (again typically via an event_release request) all resources corresponding to the notification event.
[NB: An alternative choice would be to eliminate this case requiring the implementation of the cancel request to block until the request is fully processed (i.e. until the client notifies the status event processing completion).]
5Appendix 2: LiPS Coding Guidelines
This appendix is an excerpt of LiPS Forum’s AWG reference model document .
5.1Introduction to coding guidelines
The coding guidelines cover the following aspects:
capitalisation vs. undesrcorisation
The paragraphs below are copied from the LiPS Forum coding guidelines sample header file documentation generated with doxygen.
#define TEL_PHONE_NUMBER_MAX_LEN 40
Constant definition example.
Rules for constants:
Constants are defined in upper-case with underscores for readability.
A constant is prefixed with the service it relates to.
lips_services.h for the list of LiPS services prefixes.
5.3Enumeration Type Documentation
Enumeration definition example.
Rules for enumerations:
Enumerated names follow the same prefix rules as constants.
Rules for types:
Type names are prefixed with the service they belong too.
Type names are suffixed with _t.
National phone number (example: 0497245050).
International phone number (example: +33497245050).
Abbreviated phone number (example: 5050).
Function definition - Alternative 1 : Unix fundamentalism.
Rules for functions:
The function symbol is lower-case.
The function symbol is prefixed with the service it belongs to.
For clarity, underscores (_) may be used.
Type symbols are lower-case.
The parameters symbols are lower-case.
The parameters symbols have no prefix nor suffix.
phone number to be called [in]
0 if success, -1 if the protocol stack encounters an internal failure.
Important Note: the function returns even though the call setup is in progress. Call completion is indicated by an asynchronous event.