Exchange Manager 2
[System]


Detailed Description

The Exchange Manager is a central system broker in charge of the communication between different applications or servers. It facilitates data exchange between client applications, which are applications requesting services, and handlers, which are the applications, libraries, and servers that perform the requested services. While originally designed simply to pass data back and forth, in ACCESS Linux Platform the Exchange Manager has been extended to become a general purpose mechanism for announcing and utilizing services provided by applications, libraries, and servers. This makes it an ideal mechanism to support the ACCESS Linux Platform activity model.

Applications can find a service 'statically' by specifying the appropriate verb and subject, or it can find a service 'dynamically' by asking the Exchange Manager. There are two main ways to find a service: The first way is used when you don't want to do any special action. It finds the services that respond to the question "what can I do with data of <thistype>?". The second way is used when you want to perform some special action, like "Send". It finds the services that respond to the question "How can I Send data of <thistype>"

Applications use the Exchange Manager to inform the system of the kind of actions they can handle, such as dialing a phone number or storing a vCard as a contact. In order for a client application to use a service that has been registered with the Exchange Manager, the application need only execute a request with the proper information - a verb and a set of data - to the Exchange Manager. The Exchange Manager determines which handlers can deal with requests of that type and invokes the appropriate application (passing in the verb and any data) in transient mode. When the handler application has completed the requested task, it is exits and the primary application is once again revealed. All of this is handled automatically by the operating system and the Exchange Manager; a client application simply requests the service and then proceeds to act upon the results. NOTE: Because the handler application is transient to the primary application, if the user switches to yet another application - by pressing the Home key, for instance - both the handler application and the client application will be shut down, at which point the new application is launched.

The Role of the Exchange Manager: The Exchange Manager provides all of its mechanisms via a daemon and a set of APIs to:

Services: Each service is described by a verb (action) and a subject (upon which the verb acts, usually a MIME type). The combination of verb and subject defines a specific service to the Exchange Manager. To customize the service's behavior, parameters can be associated with the service. For instance, a service could be "store" (the verb) and "vObject" (the subject), with the actual object to be stored attached to the service request. Another service could be "display" (the verb) and "image/jpeg" (the subject). Or, a somewhat more complex service might be "get contact": if parameters are supplied they may specify the contact to be returned, and if no parameters are supplied, the list of contacts is displayed and the user is allowed to select one. Either way, information about the contact (perhaps the entire vCard) is returned.


Modules

 Exchange Manager 2 Handlers

Data Structures

struct  _AlpExgAsyncExecuteEventInfoType
 event msg sent to the async execute event function. More...

Errors

#define ALP_EXG2_ACCESSFILE_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00210000))
 error opening/stating a file
#define ALP_EXG2_BINDSOCKET_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00080000))
 Cannot bind a socket.
#define ALP_EXG2_BROKENPIPE_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00250000))
 Error or hangup on connection between client and handler or between daemon nad handler.
#define ALP_EXG2_BUNDLENAMETOOLONG_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00120000))
 bundle name too long
#define ALP_EXG2_CANNOTRCVFD_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00330000))
 A file descriptor could not be read across processes..
#define ALP_EXG2_CANNOTSENDFD_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00320000))
 A file descriptor could not be sent across processes..
#define ALP_EXG2_CONNECTSOCKET_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x000A0000))
 Cannot connect a socket.
#define ALP_EXG2_CREATEFILE_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00200000))
 error opening/creating a file
#define ALP_EXG2_CREATESOCKET_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00070000))
 Cannot create a socket.
#define ALP_EXG2_DAEMONFAILURE_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00030000))
 General daemon internal failure.
#define ALP_EXG2_FCNTLSOCKET_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x000D0000))
 Cannot set socket options.
#define ALP_EXG2_FIRST_EXT_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00800000))
 Base for errors generated by a requester or a handler. These enable a handler to return a precise specific error.
#define ALP_EXG2_GSOURCE_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00240000))
 error while creating or attaching a gsource, or adding a timeout to a gsource
#define ALP_EXG2_HANDLERALREADYREGISTERED_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00140000))
 thisverb/subject is already registered by this registrant
#define ALP_EXG2_HANDLERISLOCALONLY_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00170000))
 Handler doen't accept requests from remote device.
#define ALP_EXG2_HANDLERNOTFOUND_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00160000))
 There was no registered handler to handle this request.
#define ALP_EXG2_HANDLERREGISTEREDINACTIVE_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00150000))
 There was already an active handler for this verb/subject. This handler was registered but flagged inactive.
#define ALP_EXG2_HANDLERTIMEOUT_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00180000))
 Handler did not respond to invocation in time.
#define ALP_EXG2_INVALIDAPIPARAM_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00060000))
 An invalid parameter was passed to some API.
#define ALP_EXG2_LIBRARYFAILURE_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00040000))
 General library internal failure.
#define ALP_EXG2_LISTENSOCKET_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00090000))
 Cannot listen a socket.
#define ALP_EXG2_LOCALIZEDVERBTOOLONG_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x000F0000))
 Localized verb is too long.
#define ALP_EXG2_MIMETYPETOOLONG_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00110000))
 mimetype is too long
#define ALP_EXG2_NOMOREOBJECTS_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00350000))
 There are no more objects to receive.
#define ALP_EXG2_NOTRANSPORTS_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00020000))
 No transport plug-in found.
#define ALP_EXG2_OBJECTNOTREADY_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00340000))
 The object you are trying to receive is not fully defined yet. Try again later.
#define ALP_EXG2_OUTOFMEMORY_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00010000))
 Out of memory.
#define ALP_EXG2_PARAMNOTFOUND_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00050000))
 Request does not contain the expected parameter.
#define ALP_EXG2_PROGRAM_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00500000))
 A consistency check revealed a programming error.
#define ALP_EXG2_READFILE_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00230000))
 error reading from a file
#define ALP_EXG2_READSOCKET_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x000C0000))
 Cannot read a socket.
#define ALP_EXG2_REGCACHE_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00190000))
 error trying to open/create/rename the registration cache file
#define ALP_EXG2_REQUESTALREADYRECEIVED_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00310000))
 The requested request is currently already handled..
#define ALP_EXG2_REQUESTNOTFOUND_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00300000))
 The requested request could ne be found. It may have timedout and been removed before receive request was called..
#define ALP_EXG2_SUBJECTTOOLONG_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00100000))
 subject is too long
#define ALP_EXG2_TIMEOUT_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00380000))
 Timeout during data object transfer between requester and handler.
#define ALP_EXG2_UNKNOWN_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00370000))
 Something failed, we don't know what exactly.
#define ALP_EXG2_USERCANCEL_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00360000))
 Execution was canceled.
#define ALP_EXG2_VERBTOOLONG_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x000E0000))
 Verb is too long.
#define ALP_EXG2_WRITEFILE_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00220000))
 error writing to a file
#define ALP_EXG2_WRITESOCKET_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x000B0000))
 Cannot write a socket.

Asynchronous Execution events

This event info is passed to the event callback function during execution of an asynchronous request. The only event currently defined is the completion event.

#define ALP_EXG2_ASYNC_EXECUTE_EVENT_COMPLETE   1
 Execution has completed.
typedef int alp_exg_async_execute_event_t
 Event Type.
typedef _AlpExgAsyncExecuteEventInfoType AlpExgAsyncExecuteEventInfoType
 event msg sent to the async execute event function.

Prefixes for localized resource verbs contained in bundle catalogs.

When registering a handler, you can provide a localized verb that will be returned to applications when enumerating verbs. If the device locale changes, you must unregister and re-register your handler with the localized verb in the new locale. Another possibility is to specify the localized verb as a resource. If you do this, the exchange daemon will read the localized string from your bundle resources, and you don't need to handle the locale change yourself.

#define ALP_EXG2_BUNDLE_LOCALE_VERB_BUNDLE_PREFIX(bundle)   "RSC=" bundle "/^t/"
 This prefix should be used for localized verbs which are contained in a known bundle. The bundle name must be a constant string.
#define ALP_EXG2_BUNDLE_LOCALE_VERB_PREFIX   "RSC=^t/"
 This prefix should be used for localized verbs which are contained in the same bundle which the exchange handler is registered to launch.

Max size for verbs, subject and bundlename

These are the length limits for strings passed to the registration APIs.

#define ALP_EXG2_BUNDLENAME_MAXLEN   150
 max len for the bundle name
#define ALP_EXG2_LOCALIZED_VERB_MAXLEN   60
 max len for the localized verb
#define ALP_EXG2_SUBJECT_MAXLEN   50
 max len for the request subject
#define ALP_EXG2_VERB_MAXLEN   30
 max len for the verb

Predefined subjects

ALP defines some symbolic subjects such as email string or phone number. These subjects are defined here by convention.

#define ALP_EXG2_CONTACT_IDENTIFIER_STRING_SUBJECT   ALP_EXG2_NOWILDCARD_PREFIX"contactidstr_predef"
 A string representing the contacts database identifier for a contact (unsigned int, must be converted back to AlpLuid).
#define ALP_EXG2_EMAILSTRING_SUBJECT   ALP_EXG2_NOWILDCARD_PREFIX"emailstr_predef"
 A string representing an email.
#define ALP_EXG2_EXTENDEDPHONESTRING_SUBJECT   ALP_EXG2_NOWILDCARD_PREFIX"extphonestr_predef"
 A string representing an extended phone number (for example, a USSD request).
#define ALP_EXG2_NOWILDCARD_PREFIX   "nowcp_"
 exact match only : a subject starting with this prefix will not match a wildcard. Verbs registered with wildcard subject will not be returned when enumerating verbs for such a subject.
#define ALP_EXG2_PHONESTRING_SUBJECT   ALP_EXG2_NOWILDCARD_PREFIX"phonestr_predef"
 A string representing a phone number.
#define ALP_EXG2_RTSPURLSTRING_SUBJECT   ALP_EXG2_NOWILDCARD_PREFIX"rtspstr_predef"
 A string representing an RTSP URL.
#define ALP_EXG2_URLSTRING_SUBJECT   ALP_EXG2_NOWILDCARD_PREFIX"urlstr_predef"
 A string representing an URL.

Predefined Classes of action

A class of action is basically a prefix whose purpose is to group all the verbs that perform a similar symbolic action, but using different methods. If you base your verb on a class of action, exchange mgr clients will be able to find your method dynamically as long as they know the class.

If your verb is private, don't base it on a class of action. But if you define several private methods for some symbolic action of your own, define your own private class and base all your verbs on it. This will enable to enumerate the available methods based on this action class.

Never use a predefined action class as a verb.

#define ALP_EXG2_DIAL_ACTIONCLASS   "exg_dial_predef"
 Dial : methods examples: voice call, video call, send sms-mms...
#define ALP_EXG2_EDIT_ACTIONCLASS   "exg_edit_predef"
 Edit (modify) data: methods examples: edit image, edit text...
#define ALP_EXG2_EXPORT_ACTIONCLASS   "exg_export_predef"
 Export : methods examples: to file...
#define ALP_EXG2_GET_ACTIONCLASS   "exg_get_predef"
 Get data: methods examples: take picture, get file, get vcard...
#define ALP_EXG2_IMPORT_ACTIONCLASS   "exg_import_predef"
 Import : methods examples: from file...
#define ALP_EXG2_PRINT_ACTIONCLASS   "exg_print_predef"
 Print data: methods examples: Print to network, Print to Bluetooth...
#define ALP_EXG2_SEND_ACTIONCLASS   "exg_send_predef"
 Send data: methods are typically storage(local), obex bluetooth/IR, email attachments, SMS, MMS, FTP...
#define ALP_EXG2_VIEW_ACTIONCLASS   "exg_view_predef"
 View data: methods examples: display image, play video, play mp3, read document...

Registering, Checking and Unregistering handlers

An application can publish a service offering by registering a handler with exchange manager. A registration is specified by a verb (the action) and a subject (upon which the verb acts).

If you want your handler to be dynamically discoverable by exchange manager clients (the apps who will invoke your service), you should define your verb as a well known class of action followed by the method you implement. For example, if your handler can store data to the device storage, you would build the verb by concatenating the predefined ALP_EXG2_SEND_ACTIONCLASS class and a string representing your method such as "storage".

You can of course define your own class of action if you need your own symbolic action. Or, if you're writing a private handler, you can just define whatever verb you like.

The subject represents what the verb will act upon.

In case there will be no data objects passed with the request, the subject is some string you define and publish in your documentation. Note there are already some of them defined for phone number, url and email strings.

In case there will be data objects passed with the request, the subject will often be the mime type of the objects. This makes it convenient for client to dynamically find your handler by querying on the type of the data they want to send you.

But it is also possible that there are different data objects with different types, all of them representing a global entity (e.g. a Palm application is composed of several prc and pdb files). In this case, the subject would probably be a string representing that global entity (e.g. "palmos_application").

Your handler may support several subjects, and it can use wildcards to specify that. There are two forms you can use: 1 - supertype + '/' + '*' (e.g. "image / *") ; you support all standard mime types that are images. 2 - '*' : your action is independant of the data (e.g. you send files as email attachments).

Note that your handler will never be invoked with a wildcard in the subject (unless the requester explicitly sets it). The wildcard is only used by exchange manager to map different subjects to your handler, but your handler is always called with the real subject that was specified by the requester.

There can be only one active handler for a given verb and subject. If there is already a handler registered for the same verb and subject than the combination you try to register, your will receive a ALP_EXG2_HANDLERREGISTEREDINACTIVE_ERR error. This means your handler was correctly registered, but it was flagged 'inactive' and it will never be called while in this state. In this case, your handler could become active in two ways: 1 - the current active handler is unregistered, and your handler is the next inactive handler in the list. You become the active handler 2 - the user uses a pref panel that list the handlers and he selects which is the active one (e.g. there are 2 email applications on the device, both register the same handlers, the user selects which is the active one.

#define ALP_EXG2_HANDLER_IS_NOT_REENTRANT   0
#define ALP_EXG2_HANDLER_IS_REENTRANT   1
#define ALP_EXG2_HANDLER_LOCAL_AND_REMOTE   0
#define ALP_EXG2_HANDLER_LOCAL_ONLY   1
typedef void(* alp_exg2_handler_callback_func )(AlpExg2RequestId iRequestId)
 Handler Callback function prototype.
typedef int alp_exg_handler_localonly_t
typedef int alp_exg_handler_reentrant_t
alp_status_t alp_exg2_handler_check_registration (const char *iVerb, const char *iSubject)
 Checks whether there is a handler registered for a given verb/subject.
alp_status_t alp_exg2_handler_register_callback (const char *iVerb, const char *iLocalizedVerb, const char *iSubject, alp_exg2_handler_callback_func iHandlerCallbackFunc, alp_exg_handler_localonly_t iLocalOnly, alp_exg_handler_reentrant_t iReentrant)
 Register a handler implemented as a callback function in a running process.
alp_status_t alp_exg2_handler_register_launch (const char *iVerb, const char *iLocalizedVerb, const char *iSubject, const char *iBundle, alp_exg_handler_localonly_t iLocalOnly, alp_exg_handler_reentrant_t iReentrant)
 Register a handler implemented in a bundle.
alp_status_t alp_exg2_handler_unregister_callback (const char *iVerb, const char *iSubject, alp_exg2_handler_callback_func iHandlerCallbackFunc)
 Unregister a handler implemented as a callback.
alp_status_t alp_exg2_handler_unregister_launch (const char *iVerb, const char *iSubject, const char *iBundle)
 Unregister a handler implemented in a bundle.

Media Hints

Your handler will stream data objects from different places. As a handler, this is transparent for you. In order to help you decide whether, for example, you want to display progress, the requester or the exchange transport may set some integer parameter to give you one or more hints of the media.

Use alp_exg2_request_int_parameter_get() to try to get the hints you are interested in. Note they are optional so be prepared for a default decision.

#define ALP_EXG2_HINT_MEDIA_SPEED_INT_PARAM   "exg_mediaspeed"
 Media Speed hint : if this parameter exists, it gives an indication of the incoming bandwidth in kbps.
#define ALP_EXG2_HINT_MEDIA_TYPE_3G   8
#define ALP_EXG2_HINT_MEDIA_TYPE_BLUETOOTH   2
#define ALP_EXG2_HINT_MEDIA_TYPE_EDGE   7
#define ALP_EXG2_HINT_MEDIA_TYPE_ETH   4
#define ALP_EXG2_HINT_MEDIA_TYPE_GPRS   6
#define ALP_EXG2_HINT_MEDIA_TYPE_INT_PARAM   "exg_mediatype"
 Media Type hint : if this parameter exists, it gives an indication of the media type.
#define ALP_EXG2_HINT_MEDIA_TYPE_IRDA   3
#define ALP_EXG2_HINT_MEDIA_TYPE_LOCAL   1
#define ALP_EXG2_HINT_MEDIA_TYPE_WIFI   5
#define ALP_EXG2_HINT_OBJECTS_TOTAL_SIZE_INT_PARAM   "exg_objtotalsize"
 Total data size Hint : if this parameter exists, it gives an indication of the total size of received objects.
#define ALP_EXG2_HINT_SLOW_MEDIA_INT_PARAM   "exg_slowmedia"
 Sender indicates slow media Hint : if this parameter exists and value is not zero, it indicates the sender recommends to use progress window.

Executing a request

Executing a request is the process of dispatching it to the handler which registered for the corresponding verb and subject. When the handler completes execution, you receive the execution result, and possibly parameters and/or data objects that were sent back.

typedef void(* alp_exg2_execute_event_info_func )(AlpExg2Request iRequest, void *iUserData, AlpExgAsyncExecuteEventInfoType *iExecuteEventInfo)
 Event callback for request run asynchronously.
alp_status_t alp_exg2_request_execute_async (AlpExg2Request iRequest, alp_exg2_execute_event_info_func iExecuteEventInfoFunc, void *iUserData)
 Execute a request asynchronously.
alp_status_t alp_exg2_request_execute_cancel (AlpExg2Request iRequest, alp_status_t iCancelErr)
 Cancel a request executing asynchronously.
alp_status_t alp_exg2_request_execute_sync (AlpExg2Request iRequest)
 Execute a request synchronously.

The Request data type

The exchange manager API mostly accesses a request object. This object is to be used as a handle.

typedef void * AlpExg2Request
 The exchange request. A request is created and accessed using Exchange Manager API only.
typedef void * AlpExg2RequestId
 Reference Id you receive in an exchange handler. Use this id to receive the corresponding exchange request.

Finding verbs dynamically

In the application UI, the user can trigger actions by tapping the data itself (tap a photo, tap a phone number or email address�). For some actions, there may be a button or menu item available. In response to this user event, an app can query the available verbs in two ways. Let's say the application has "image/jpeg" data. 1) If the user just points at the data directly on the screen, the app can ask "what can I do with image/jpeg". The app does not specify any action class, so it will get back a list of all the verbs that can handle this subject. 2) If the user taps a button or selects a menu item (typically "Send"), the app can ask "How can I 'action=Send' image/jpg". This time, the app specified a symbolic action, so it will get a similar list filtered with the 'Send' action.

alp_status_t alp_exg2_handler_query_methods (const char *iAction, const char *iSubject, const char *iExcludeInvokeName, uint32_t *oEntryCount, char **oDataP)
 Dynamically find handlers based on a subject and/or a verb or class of action.

Getting parameters from a request

This section describes how you can extract parameters from a request you receive. You can also use these functions to extract parameters that were sent back as the execution result.

alp_status_t alp_exg2_request_blob_parameter_get (AlpExg2Request iRequest, const char *iParamTag, uint8_t **oBlob, size_t *oBlobSize)
 Get a blob parameter from the request.
alp_status_t alp_exg2_request_int_parameter_get (AlpExg2Request iRequest, const char *iParamTag, int *oParamValue)
 Get an integer parameter from the request.
alp_status_t alp_exg2_request_string_parameter_get (AlpExg2Request iRequest, const char *iParamTag, char **oParamValue)
 Get a string parameter from the request.
alp_status_t alp_exg2_request_string_parameter_get_const (AlpExg2Request iRequest, const char *iParamTag, const char **oParamValue)
 Get a string parameter from the request (const).

Adding parameters to a request

A request can contain integer, string, or blob (binary block) parameters. Parameters are generally optional, but you must always read the handler documentation to learn what it expects. Normally, you should not use parameters to pass data (add data objects instead), because this forces the handler to know which parameter contain the data, and which format the data is. It makes the handler non generic. So please consider using parameters to pass handler customization options, such as "showUI", "askUser", etc...

If you are working on a request you received, it is also possible to add parameters that will sent back to the requester when you complete and exit the handler.

alp_status_t alp_exg2_request_blob_parameter_set (AlpExg2Request iRequest, const char *iParamTag, const uint8_t *iBlob, size_t iBlobSize)
 Add a binary parameter to the request.
alp_status_t alp_exg2_request_int_parameter_set (AlpExg2Request iRequest, const char *iParamTag, int iParamValue)
 Add an integer parameter to the request.
alp_status_t alp_exg2_request_string_parameter_set (AlpExg2Request iRequest, const char *iParamTag, const char *iParamValue)
 Add a string parameter to a request.

Getting data objects from a request

This section describes the functions to receive the data objects that are attached to the request. You can choose the receive method independantly of how the data objects were added.

Receiving objects is essentially a loop of alp_exg2_request_object_rcv_info() and alp_exg2_request_object_rcv_by_xxxx(). The loops ends when you are returned ALP_EXG2_NOMOREOBJECTS_ERR.

Automatic receive progress is implemented by exchange manager, but you can disable it if you prefer.

alp_status_t alp_exg2_request_check_still_active (AlpExg2Request iRequest)
 Check if the requester is still active.
alp_status_t alp_exg2_request_object_rcv_by_fd (AlpExg2Request iRequest, uint32_t iObjectId, int *oFd)
 Receive a file descriptor to read the data from.
alp_status_t alp_exg2_request_object_rcv_by_file (AlpExg2Request iRequest, uint32_t iObjectId, const char *iDestFile)
 Receive an object into a file.
alp_status_t alp_exg2_request_object_rcv_by_ptr (AlpExg2Request iRequest, uint32_t iObjectId, uint8_t **oObjectP, size_t *oObjectSize)
 Receive the data object in a memory chunk.
alp_status_t alp_exg2_request_object_rcv_count (AlpExg2Request iRequest, uint32_t *oObjectCount)
 Get an indication of the number of data objects in the request.
alp_status_t alp_exg2_request_object_rcv_info (AlpExg2Request iRequest, uint32_t iObjectId, size_t *oObjectSize, const char **oObjectName, const char **oObjectType, const char **oObjectDscr)
 Get Info for the next received data object.
alp_status_t alp_exg2_request_receive_progress_disable (AlpExg2Request iRequest)
 Disable the automatic receive progress.

Creating and Deleting requests

In order to invoke a service in the system, you must first create a request. At least a verb and a subject must be specified before you can execute the request. Later, when you have got the execution result, you must delete the request.

alp_status_t alp_exg2_request_create (AlpExg2Request *oRequest, const char *iVerb, const char *iSubject)
 Create a request.
alp_status_t alp_exg2_request_delete (AlpExg2Request iRequest)
 Delete a request.
alp_status_t alp_exg2_request_set_subject (AlpExg2Request iRequest, const char *iSubject)
 Set the subject.
alp_status_t alp_exg2_request_set_verb (AlpExg2Request iRequest, const char *iVerb)
 Set the verb.

Manage Peer names

When displaying progress UI, it can be interesting to display the remote user name, especially when the requester acts as a proxy for the real sender (like it happens with Bluetooth receive). These functions let you set your name and get the remote name, provided it was specified by the remote of course.

alp_status_t alp_exg2_request_get_remote_peer_name (AlpExg2Request iRequest, char **oPeerName)
 Get the remote name.
alp_status_t alp_exg2_request_get_remote_peer_name_const (AlpExg2Request iRequest, const char **oPeerName)
 Get the remote name (const).
alp_status_t alp_exg2_request_set_local_peer_name (AlpExg2Request iRequest, const char *iPeerName)
 Set the name of the requester.

Receiving a request

This section explains how a handler is invoked, receives the request that was sent, and returns a result.

alp_status_t alp_exg2_request_get_subject (AlpExg2Request iRequest, char **oSubject)
 Get the subject.
alp_status_t alp_exg2_request_get_subject_const (AlpExg2Request iRequest, const char **oSubject)
 Get the subject (const).
alp_status_t alp_exg2_request_get_verb (AlpExg2Request iRequest, char **oVerb)
 Get the verb.
alp_status_t alp_exg2_request_get_verb_const (AlpExg2Request iRequest, const char **oVerb)
 Get the verb (const).
alp_status_t alp_exg2_request_receive_complete (AlpExg2Request iRequest, alp_status_t iResult)
 Complete your handler execution.
alp_status_t alp_exg2_request_receive_start (AlpExg2Request *oRequest, AlpExg2RequestId iRequestId)
 Receive a request in your handler.

Adding data objects to a request

It is possible to attach as many data object as you like to a request. Each data object is fully qualified by a name, a size and a mime type. As a client, you can specify the data source by file, file descriptor or memory pointer as best suits you. As a handler, you can access the data objects by file, file descriptor or memory pointer as you like as well. You don't have to worry about access rights because exchange manager will make sure the handler can read the data. Exchange Manager will also take care to 'hide' your original data source so that the handler can only read data but has no way to know where the data comes from.

The data transfer between the requester and the handler is optimized as much as possible. Most of the time, the handler will be able to directly stream the data from the original data source, such that there is absolutely no data copy.

On rare occasion, you may need to start executing the request before you have added all the data objects (or maybe you don't know yet how many data objects you will add). In this situation, it is possible to add the objects later and the exchange manager will take care to inform the handler that it must wait for them.

If you are working on a request you received, it is also possible to add data objects that will sent back to the requester when you complete and exit the handler.

alp_status_t alp_exg2_request_object_add_by_fd (AlpExg2Request iRequest, int iFd, size_t iObjectSize, const char *iObjectName, const char *iObjectType, const char *iObjectDscr)
 Add a data object by file descriptor.
alp_status_t alp_exg2_request_object_add_by_file (AlpExg2Request iRequest, const char *iObjectFile, int iDeleteWhenDone, const char *iObjectName, const char *iObjectType, const char *iObjectDscr)
 Add a data object by file.
alp_status_t alp_exg2_request_object_add_by_ptr (AlpExg2Request iRequest, uint8_t *iObjectP, size_t iObjectSize, int iFreeWhenDone, const char *iObjectName, const char *iObjectType, const char *iObjectDscr)
 Add a data object by memory pointer.
alp_status_t alp_exg2_request_object_add_undefined (AlpExg2Request iRequest, uint32_t *oObjectId)
 Add a data object for which you don't have the data yet.
alp_status_t alp_exg2_request_object_define_by_fd (AlpExg2Request iRequest, uint32_t iObjectId, int iFd, size_t iObjectSize, const char *iObjectName, const char *iObjectType, const char *iObjectDscr)
 Define an object by file descriptor.
alp_status_t alp_exg2_request_object_define_by_file (AlpExg2Request iRequest, uint32_t iObjectId, const char *iObjectFile, int iDeleteWhenDone, const char *iObjectName, const char *iObjectType, const char *iObjectDscr)
 Define an object by file.
alp_status_t alp_exg2_request_object_define_by_ptr (AlpExg2Request iRequest, uint32_t iObjectId, uint8_t *iObjectP, size_t iObjectSize, int iFreeWhenDone, const char *iObjectName, const char *iObjectType, const char *iObjectDscr)
 Define an object by memory pointer.
alp_status_t alp_exg2_request_object_set_count_final (AlpExg2Request iRequest)
 Tell the request you have added all objects.
alp_status_t alp_exg2_request_object_set_count_undefined (AlpExg2Request iRequest)
 Tell the request more objects will be added later.

Selecting a transport

There is no usage for these functions at the moment. In a future version, it may be possible to execute requests on remote devices.

alp_status_t alp_exg2_transport_get (AlpExg2Request iRequest, char **oParamsValue)
 Get the transport params from the request.
alp_status_t alp_exg2_transport_get_const (AlpExg2Request iRequest, const char **oParamsValue)
 Get the transport params from the request (const).
alp_status_t alp_exg2_transport_set (AlpExg2Request iRequest, const char *iParamsValue)
 Setup to execute the request on a remote device.

UI Dialogs API Descriptions

alp_status_t alp_exg2_utils_action_method_select (GtkWindow *iParentWindow, const char *iDialogTitle, const char *iDialogPrompt, char *iQueryMethodsList, uint32_t iQueryMethodsEntryCount, const char **oSelectedMethod)
 UI Dialog to select a method for an action class.
alp_status_t alp_exg2_utils_action_method_select_and_set (AlpExg2Request iRequest, GtkWindow *iParentWindow, const char *iExcludeInvokeName, const char *iAction, const char *iSubject)
 Select a method for an action class, using UI if necessary and set the verb in the request.
void alp_exg2_utils_get_method_select_strings (const char *iAction, const char **oDialogTitle, const char **oDialogPrompt)
 Get localized strings for the select method dialg.
alp_status_t alp_exg2_utils_transport_select (AlpExg2Request iRequest, const char *iPrompt)
 Display a dialog to select a transport.


Define Documentation

#define ALP_EXG2_ACCESSFILE_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00210000))
 

error opening/stating a file

#define ALP_EXG2_ASYNC_EXECUTE_EVENT_COMPLETE   1
 

Execution has completed.

#define ALP_EXG2_BINDSOCKET_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00080000))
 

Cannot bind a socket.

#define ALP_EXG2_BROKENPIPE_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00250000))
 

Error or hangup on connection between client and handler or between daemon nad handler.

#define ALP_EXG2_BUNDLE_LOCALE_VERB_BUNDLE_PREFIX bundle   )     "RSC=" bundle "/^t/"
 

This prefix should be used for localized verbs which are contained in a known bundle. The bundle name must be a constant string.

#define ALP_EXG2_BUNDLE_LOCALE_VERB_PREFIX   "RSC=^t/"
 

This prefix should be used for localized verbs which are contained in the same bundle which the exchange handler is registered to launch.

#define ALP_EXG2_BUNDLENAME_MAXLEN   150
 

max len for the bundle name

#define ALP_EXG2_BUNDLENAMETOOLONG_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00120000))
 

bundle name too long

#define ALP_EXG2_CANNOTRCVFD_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00330000))
 

A file descriptor could not be read across processes..

#define ALP_EXG2_CANNOTSENDFD_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00320000))
 

A file descriptor could not be sent across processes..

#define ALP_EXG2_CONNECTSOCKET_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x000A0000))
 

Cannot connect a socket.

#define ALP_EXG2_CONTACT_IDENTIFIER_STRING_SUBJECT   ALP_EXG2_NOWILDCARD_PREFIX"contactidstr_predef"
 

A string representing the contacts database identifier for a contact (unsigned int, must be converted back to AlpLuid).

#define ALP_EXG2_CREATEFILE_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00200000))
 

error opening/creating a file

#define ALP_EXG2_CREATESOCKET_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00070000))
 

Cannot create a socket.

#define ALP_EXG2_DAEMONFAILURE_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00030000))
 

General daemon internal failure.

#define ALP_EXG2_DIAL_ACTIONCLASS   "exg_dial_predef"
 

Dial : methods examples: voice call, video call, send sms-mms...

#define ALP_EXG2_EDIT_ACTIONCLASS   "exg_edit_predef"
 

Edit (modify) data: methods examples: edit image, edit text...

#define ALP_EXG2_EMAILSTRING_SUBJECT   ALP_EXG2_NOWILDCARD_PREFIX"emailstr_predef"
 

A string representing an email.

#define ALP_EXG2_EXPORT_ACTIONCLASS   "exg_export_predef"
 

Export : methods examples: to file...

#define ALP_EXG2_EXTENDEDPHONESTRING_SUBJECT   ALP_EXG2_NOWILDCARD_PREFIX"extphonestr_predef"
 

A string representing an extended phone number (for example, a USSD request).

#define ALP_EXG2_FCNTLSOCKET_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x000D0000))
 

Cannot set socket options.

#define ALP_EXG2_FIRST_EXT_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00800000))
 

Base for errors generated by a requester or a handler. These enable a handler to return a precise specific error.

#define ALP_EXG2_GET_ACTIONCLASS   "exg_get_predef"
 

Get data: methods examples: take picture, get file, get vcard...

#define ALP_EXG2_GSOURCE_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00240000))
 

error while creating or attaching a gsource, or adding a timeout to a gsource

#define ALP_EXG2_HANDLER_IS_NOT_REENTRANT   0
 

#define ALP_EXG2_HANDLER_IS_REENTRANT   1
 

#define ALP_EXG2_HANDLER_LOCAL_AND_REMOTE   0
 

#define ALP_EXG2_HANDLER_LOCAL_ONLY   1
 

#define ALP_EXG2_HANDLERALREADYREGISTERED_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00140000))
 

thisverb/subject is already registered by this registrant

#define ALP_EXG2_HANDLERISLOCALONLY_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00170000))
 

Handler doen't accept requests from remote device.

#define ALP_EXG2_HANDLERNOTFOUND_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00160000))
 

There was no registered handler to handle this request.

#define ALP_EXG2_HANDLERREGISTEREDINACTIVE_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00150000))
 

There was already an active handler for this verb/subject. This handler was registered but flagged inactive.

#define ALP_EXG2_HANDLERTIMEOUT_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00180000))
 

Handler did not respond to invocation in time.

#define ALP_EXG2_HINT_MEDIA_SPEED_INT_PARAM   "exg_mediaspeed"
 

Media Speed hint : if this parameter exists, it gives an indication of the incoming bandwidth in kbps.

#define ALP_EXG2_HINT_MEDIA_TYPE_3G   8
 

#define ALP_EXG2_HINT_MEDIA_TYPE_BLUETOOTH   2
 

#define ALP_EXG2_HINT_MEDIA_TYPE_EDGE   7
 

#define ALP_EXG2_HINT_MEDIA_TYPE_ETH   4
 

#define ALP_EXG2_HINT_MEDIA_TYPE_GPRS   6
 

#define ALP_EXG2_HINT_MEDIA_TYPE_INT_PARAM   "exg_mediatype"
 

Media Type hint : if this parameter exists, it gives an indication of the media type.

#define ALP_EXG2_HINT_MEDIA_TYPE_IRDA   3
 

#define ALP_EXG2_HINT_MEDIA_TYPE_LOCAL   1
 

#define ALP_EXG2_HINT_MEDIA_TYPE_WIFI   5
 

#define ALP_EXG2_HINT_OBJECTS_TOTAL_SIZE_INT_PARAM   "exg_objtotalsize"
 

Total data size Hint : if this parameter exists, it gives an indication of the total size of received objects.

#define ALP_EXG2_HINT_SLOW_MEDIA_INT_PARAM   "exg_slowmedia"
 

Sender indicates slow media Hint : if this parameter exists and value is not zero, it indicates the sender recommends to use progress window.

#define ALP_EXG2_IMPORT_ACTIONCLASS   "exg_import_predef"
 

Import : methods examples: from file...

#define ALP_EXG2_INVALIDAPIPARAM_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00060000))
 

An invalid parameter was passed to some API.

#define ALP_EXG2_LIBRARYFAILURE_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00040000))
 

General library internal failure.

#define ALP_EXG2_LISTENSOCKET_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00090000))
 

Cannot listen a socket.

#define ALP_EXG2_LOCALIZED_VERB_MAXLEN   60
 

max len for the localized verb

#define ALP_EXG2_LOCALIZEDVERBTOOLONG_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x000F0000))
 

Localized verb is too long.

#define ALP_EXG2_MIMETYPETOOLONG_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00110000))
 

mimetype is too long

#define ALP_EXG2_NOMOREOBJECTS_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00350000))
 

There are no more objects to receive.

#define ALP_EXG2_NOTRANSPORTS_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00020000))
 

No transport plug-in found.

#define ALP_EXG2_NOWILDCARD_PREFIX   "nowcp_"
 

exact match only : a subject starting with this prefix will not match a wildcard. Verbs registered with wildcard subject will not be returned when enumerating verbs for such a subject.

#define ALP_EXG2_OBJECTNOTREADY_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00340000))
 

The object you are trying to receive is not fully defined yet. Try again later.

#define ALP_EXG2_OUTOFMEMORY_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00010000))
 

Out of memory.

#define ALP_EXG2_PARAMNOTFOUND_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00050000))
 

Request does not contain the expected parameter.

#define ALP_EXG2_PHONESTRING_SUBJECT   ALP_EXG2_NOWILDCARD_PREFIX"phonestr_predef"
 

A string representing a phone number.

#define ALP_EXG2_PRINT_ACTIONCLASS   "exg_print_predef"
 

Print data: methods examples: Print to network, Print to Bluetooth...

#define ALP_EXG2_PROGRAM_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00500000))
 

A consistency check revealed a programming error.

#define ALP_EXG2_READFILE_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00230000))
 

error reading from a file

#define ALP_EXG2_READSOCKET_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x000C0000))
 

Cannot read a socket.

#define ALP_EXG2_REGCACHE_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00190000))
 

error trying to open/create/rename the registration cache file

#define ALP_EXG2_REQUESTALREADYRECEIVED_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00310000))
 

The requested request is currently already handled..

#define ALP_EXG2_REQUESTNOTFOUND_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00300000))
 

The requested request could ne be found. It may have timedout and been removed before receive request was called..

#define ALP_EXG2_RTSPURLSTRING_SUBJECT   ALP_EXG2_NOWILDCARD_PREFIX"rtspstr_predef"
 

A string representing an RTSP URL.

#define ALP_EXG2_SEND_ACTIONCLASS   "exg_send_predef"
 

Send data: methods are typically storage(local), obex bluetooth/IR, email attachments, SMS, MMS, FTP...

#define ALP_EXG2_SUBJECT_MAXLEN   50
 

max len for the request subject

#define ALP_EXG2_SUBJECTTOOLONG_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00100000))
 

subject is too long

#define ALP_EXG2_TIMEOUT_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00380000))
 

Timeout during data object transfer between requester and handler.

#define ALP_EXG2_UNKNOWN_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00370000))
 

Something failed, we don't know what exactly.

#define ALP_EXG2_URLSTRING_SUBJECT   ALP_EXG2_NOWILDCARD_PREFIX"urlstr_predef"
 

A string representing an URL.

#define ALP_EXG2_USERCANCEL_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00360000))
 

Execution was canceled.

#define ALP_EXG2_VERB_MAXLEN   30
 

max len for the verb

#define ALP_EXG2_VERBTOOLONG_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x000E0000))
 

Verb is too long.

#define ALP_EXG2_VIEW_ACTIONCLASS   "exg_view_predef"
 

View data: methods examples: display image, play video, play mp3, read document...

#define ALP_EXG2_WRITEFILE_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x00220000))
 

error writing to a file

#define ALP_EXG2_WRITESOCKET_ERR   ((alp_status_t) (ALP_CLASS_EXCHANGE2 | 0x000B0000))
 

Cannot write a socket.


Typedef Documentation

typedef void(* alp_exg2_execute_event_info_func)(AlpExg2Request iRequest, void *iUserData, AlpExgAsyncExecuteEventInfoType *iExecuteEventInfo)
 

Event callback for request run asynchronously.

When a request is run asynchronously, you will receive events through the callback you specified.

Note that even though the request execute can be started from any thread, the event callback will always be called in your main thread.

There is currently only one event defined : it is the request complete event. This event will deliver the handler final result in iExecuteEventInfo->params.evtcomplete.completeStatus.

If you need to get result parameters or data objects from the handler, you can do it from this event callback.

When you are done, you must call alp_exg2_request_delete() to delete the request.

 static void prv_my_execute_event_info (AlpExg2Request iRequest, void *iUserData, AlpExgAsyncExecuteEventInfoType *iExecuteEventInfo)
 {
         switch (iExecuteEventInfo->event)
         {
                 case ALP_EXG2_ASYNC_EXECUTE_EVENT_COMPLETE:
                 {
                        // get returned parameters if any
                        err = alp_exg2_request_string_parameter_get ();

                        // delete the request
                        (void) alp_exg2_request_delete (iRequest);
                 } break;
         }
 }

Parameters:
[in] iRequest the request
[in] iUserData the user data you specified when you called alp_exg2_request_execute_async.
[in] iExecuteEventInfo a pointer to the event info structure.
Returns:
ALP_STATUS_OK - success

typedef void(* alp_exg2_handler_callback_func)(AlpExg2RequestId iRequestId)
 

Handler Callback function prototype.

The handler callback is called from an idle task in the main loop in your main thread.

See alp_exg2_request_receive_start() to learn how to use this request id.

Parameters:
[in] iRequestId an id to get the request you are receiving.

typedef int alp_exg_async_execute_event_t
 

Event Type.

typedef int alp_exg_handler_localonly_t
 

typedef int alp_exg_handler_reentrant_t
 

typedef void* AlpExg2Request
 

The exchange request. A request is created and accessed using Exchange Manager API only.

typedef void* AlpExg2RequestId
 

Reference Id you receive in an exchange handler. Use this id to receive the corresponding exchange request.

typedef struct _AlpExgAsyncExecuteEventInfoType AlpExgAsyncExecuteEventInfoType
 

event msg sent to the async execute event function.


Function Documentation

alp_status_t alp_exg2_handler_check_registration const char *  iVerb,
const char *  iSubject
 

Checks whether there is a handler registered for a given verb/subject.

This function will verify if there is a handler exactly matching the verb/subject (meaning a handler registered with these exact verb and subject). Note that a handler that has registered a wildcard will not match. If you want to know if there is a wildcard handler matching, you must explicitly check for the wildcard.

Examples: check image/jpeg : match "image/jpeg", doesn't match "image / *" or "*". Do explicitly check "image / *" and "*" if you want to verify wildcards.

Parameters:
[in] iVerb the verb
[in] iSubject the subject
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_handler_query_methods const char *  iAction,
const char *  iSubject,
const char *  iExcludeInvokeName,
uint32_t *  oEntryCount,
char **  oDataP
 

Dynamically find handlers based on a subject and/or a verb or class of action.

This function can be used to find a list of handlers that satisfy some criterias. There are two ways it can be used : with or with a verb filter.

If you have a subject and you ask yourself "what can I do with this subject?", you will call this function with a NULL verb filter. You will get back a list of all the possible verbs that can do something with your subject. You can use this method, for example, to build an action menu to show to the user when he taps on some object on the screen (e.g. user taps on a photo, you display what the user can do with that photo).

If you have a subject and you want to do some symbolic action on this subject, you will call this function with a class of action representing the symbolic action. You will get a list of all the methods you can use to perform this action. For example, the screen shows an image and the user taps the "Send" button. You ask exchange manager "how can I Send image/jpeg?". The list will return different methods to send to storage, send using bluetooth, send as email attachment, etc.

Note in all cases, you will get verbs which were registered with full or partial wildcard subjects. e.g. if subject = image/jpeg, will return handlers for "image / *" and "*"

The application can also specify a bundle whose handlers will be excluded from the returned list. The goal is to automatically exclude verbs that don't make sense in the current context. For example, say you are using Contacts and you select "Send". Contact will ask exchange how it can Send text/x-vcard. But one of the registered methods is actually implemented by Contacts itself (Send/SaveToContacts) so this verb would also be returned even though it does not make sense in this context. To avoid that, Contact can tell exchange manager to exclude verbs that are registered by itself.

Note that handlers registered as callbacks cannot be excluded.

This function will return a single malloc'ed chunk containing a serie of NULL terminated string. For each entry, there will be two strings : the first is the verb to use in the request, the second is the localized verb to display to the user. e.g; if the function returns oEntryCount = 2, oDataP will contain "verb1\0Localized1\0verb2\0Localized2\0".

You must free this chunck when you are done with it.

See alp_exg2_utils_action_method_select() (exgmgr2_ui.h) for a utility function that takes the chunck and displays a dialog to let the user select a verb.

Parameters:
[in] iAction NULL if you want to list all the verbs, or an action class if you want the methods for a specific action only.
[in] iSubject a subject or mimetype
[in] iExcludeInvokeName can be NULL. If not null, will filter out handlers that are registered to launch this bundle.
[out] oEntryCount will contain the number of entries. This can be zero.
[out] oDataP will contain a pointer to a malloc'ed chunk. Free this chunck when done. Note that this can be an empty chunk if there was zero entries.
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_handler_register_callback const char *  iVerb,
const char *  iLocalizedVerb,
const char *  iSubject,
alp_exg2_handler_callback_func  iHandlerCallbackFunc,
alp_exg_handler_localonly_t  iLocalOnly,
alp_exg_handler_reentrant_t  iReentrant
 

Register a handler implemented as a callback function in a running process.

When an application executes a request for the verb and subject you registered, your callback will be called in the context of an idle task in your main loop. It is therefore required that you run a glib mainloop or a gtk mainloop.

The function prototype is:

   typedef void (*alp_exg2_handler_callback_func) (AlpExg2RequestId iRequestId);

Registration Persistence : this registration is not persistent. It is valid only for the duration of your application. If you exit your app, the handler will be automatically unregistered. You must therefore register every time your application starts.

Parameters:
[in] iVerb the action this handler implements
[in] iLocalizedVerb (optional) the localized verb to be displayed in UI. If NULL, this handler will not be discoverable dynamically.
[in] iSubject this is a discriminant for the verb. It is generally the data mimetype, but not necessarily.
[in] iHandlerCallbackFunc the function that will be called to execute a request.
[in] iLocalOnly set to ALP_EXG2_HANDLER_LOCAL_ONLY if you want to restrict access to your handler by clients on the local device only. Set to ALP_EXG2_HANDLER_LOCAL_AND_REMOTE if your handler can be invoked from a remote device.
[in] iReentrant set to ALP_EXG2_HANDLER_IS_NOT_REENTRANT if you want exchange manager to serialize multiple incoming request to this handler. Set to ALP_EXG2_HANDLER_IS_REENTRANT if you can simultaneously handler multiple requests.
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_handler_register_launch const char *  iVerb,
const char *  iLocalizedVerb,
const char *  iSubject,
const char *  iBundle,
alp_exg_handler_localonly_t  iLocalOnly,
alp_exg_handler_reentrant_t  iReentrant
 

Register a handler implemented in a bundle.

When an application executes a request for the verb and subject you registered, your bundle will be launched (or relaunched if already running). The bundle can be an ALP application, a JAVA application or GVM application.

The bundle will be launched in TRANSIENT mode, which means it is running on top of the primary app, but somehow stays linked to the primary app in the way that if the primary app exits, your handler will also be required to exit through its exit handler.

You will recognize you are launched to handle an exchange request by examining the argv array and look for ALP_APP_EXCHANGE ("--alp-exchange"). The following argv parameter will be a string containing the request id. Convert the string to an AlpExg2RequestId like this :

        AlpExg2RequestId theRequestId;
        sscanf (argv[index], "%p", &theRequestId);

See alp_exg2_request_receive_start() to learn how to use this request id.

Registration Persistence : note that you should register only once when your application is initially installed. The registration will be saved by exchange manager such that it will automatically persist upon device restarts.

Parameters:
[in] iVerb the action this handler implements
[in] iLocalizedVerb (optional) the localized verb to be displayed in UI. If NULL, this handler will not be discoverable dynamically.
[in] iSubject this is a discriminant for the verb. It is generally the data mimetype, but not necessarily.
[in] iBundle the bundle name that will be launched to execute a request. The name must include the bundle type (e.g. "bar:xxxxx")
[in] iLocalOnly set to ALP_EXG2_HANDLER_LOCAL_ONLY if you want to restrict access to your handler by clients on the local device only. Set to ALP_EXG2_HANDLER_LOCAL_AND_REMOTE if your handler can be invoked from a remote device.
[in] iReentrant set to ALP_EXG2_HANDLER_IS_NOT_REENTRANT if you want exchange manager to serialize multiple incoming request to this handler. Set to ALP_EXG2_HANDLER_IS_REENTRANT if you can simultaneously handler multiple requests.
Returns:
ALP_STATUS_OK - success
ALP_EXG2_HANDLERALREADYREGISTERED_ERR - thisverb/subject is already registered by this registrant
ALP_EXG2_HANDLERREGISTEREDINACTIVE_ERR - There was already an active handler for this verb/subject. This handler was registered but flagged inactive

alp_status_t alp_exg2_handler_unregister_callback const char *  iVerb,
const char *  iSubject,
alp_exg2_handler_callback_func  iHandlerCallbackFunc
 

Unregister a handler implemented as a callback.

Use the exact same verb, subject and callback that you used to register. Note that if you exit your application, unregistration is automatic.

Parameters:
[in] iVerb the verb your used to register
[in] iSubject the subject your used to register
[in] iHandlerCallbackFunc the callback you specified to register
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_handler_unregister_launch const char *  iVerb,
const char *  iSubject,
const char *  iBundle
 

Unregister a handler implemented in a bundle.

Use the exact same verb, subject and bundle that you used to register. Normally, you should only unregister when your app is uninstalled from the device.

Parameters:
[in] iVerb the verb your used to register
[in] iSubject the subject your used to register
[in] iBundle the bundle you specified to register
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_blob_parameter_get AlpExg2Request  iRequest,
const char *  iParamTag,
uint8_t **  oBlob,
size_t *  oBlobSize
 

Get a blob parameter from the request.

This function will malloc a chunk of memory and fill it with the binary data for this parameter. You must free() the chunck when you are done with it

Parameters:
[in] iRequest the request
[in] iParamTag the parameter name
[out] oBlob the pointer to the memory to set as the parameter value
[out] oBlobSize the size of the binary data
Returns:
ALP_STATUS_OK - success
ALP_EXG2_PARAMNOTFOUND_ERR - This parameter does not exist in the request

alp_status_t alp_exg2_request_blob_parameter_set AlpExg2Request  iRequest,
const char *  iParamTag,
const uint8_t *  iBlob,
size_t  iBlobSize
 

Add a binary parameter to the request.

A blob is a bloc of binary data. Don't confuse a blob and a data object specified by pointer. This function is used to set a request parameter whose value is some arbitrary data. It is not recommended to use a blob to pass an object because doing so will make the handler specific. But if your handler is private, you can do so if you like. Be warned though that all blob will be stored in memory at all times and they are also encoded/decoded to be transferred, so don't use them to pass very large amount of data.

Parameters:
[in] iRequest the request
[in] iParamTag the parameter name
[in] iBlob the pointer to the memory to set as the parameter value
[in] iBlobSize the size of the binary data
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_check_still_active AlpExg2Request  iRequest  ) 
 

Check if the requester is still active.

Call this function to determine if the requester is still active, or if it has raised an error or a cancel condition. That kind of information is normally returned as the result of any receive object function, but if you don't call these functions for a long time, you will not know if the requester has canceled and you may get stuck waiting for data that will never come.

If the function result is ALP_STATUS_OK, you can safely continue to execute your handler.

If the function result is not ALP_STATUS_OK, you should terminate the handler by immediately completing it with the result returned by this function (this will be ALP_EXG2_USERCANCEL_ERR if the requester has canceled from its side).

Parameters:
[in] iRequest the request
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_create AlpExg2Request oRequest,
const char *  iVerb,
const char *  iSubject
 

Create a request.

When you want to use a service (invoke an exchange handler), you must first create a request. The verb and subject can be specified at once, or you can set them later as you like.

Parameters:
[in] iVerb the verb (if NULL, you must set the verb later)
[in] iSubject the subject (if NULL, you must set the subject later).
[out] oRequest will contain the request if successful
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_delete AlpExg2Request  iRequest  ) 
 

Delete a request.

If you have created a request successfully, you will need to delete it at some point. This can be before it is executed if you encounter an error while adding parameters or data objects. Or, it can be after it has executed (if you execute asynchronously, you can delete the request when the event info is called for completion).

Anything you have added to the request will be automatically released and cleaned up. If you have added dataobject by file descriptors, the file descriptors will be closed. If you have added data objects as temporary files, they will be unlinked.

Parameters:
[in] iRequest the request
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_execute_async AlpExg2Request  iRequest,
alp_exg2_execute_event_info_func  iExecuteEventInfoFunc,
void *  iUserData
 

Execute a request asynchronously.

This function starts the process of executing a request and returns immediately. You must then run your event loop normally to let the process run in the background. If this function fails, the callback will never be called and you must immediately call alp_exg2_request_delete().

You can call this function from any thread, but be warned that the event callback will always be called from your main thread. Also, if you call this function from a thread that is not the main loop thread, make sure the process you run in has called g_thread_init(NULL) to enable thread safety in glib.

Parameters:
[in] iRequest the request
[in] iExecuteEventInfoFunc the event callback function
[in] iUserData a pointer for your own use that will be passed back to the event callback function.
Returns:
ALP_STATUS_OK - success
ALP_EXG2_HANDLERNOTFOUND_ERR - There is no handler registered for this verb and subject
ALP_EXG2_HANDLERTIMEOUT_ERR - Handler did not respond to invocation in time

alp_status_t alp_exg2_request_execute_cancel AlpExg2Request  iRequest,
alp_status_t  iCancelErr
 

Cancel a request executing asynchronously.

This function can be used to cancel a request currently executing asynchronously (you cannot cancel a synchronous request). Canceling a request is a process that takes some time. This means the request will not be immediately canceled. iCancelErr will be sent to the handler, which should then terminate immediately with the same cancel error you gave. Note the handler can receive this cancel only when it is receiving data objects. The request will then complete normally, with the final status the handler returned.

As canceling is itself an asynchronous process, it is possible that the handler completes before it receives the cancel indication. In this case, your request would complete normally.

You can use this function to cancel for differents causes. Most often, and by convention, you will pass ALP_EXG2_USERCANCEL_ERR. This error code should be treated as a voluntary cancel and not generate an error alert.

Parameters:
[in] iRequest the request
[in] iCancelErr the reason for cancel. This cannot be zero.
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_execute_sync AlpExg2Request  iRequest  ) 
 

Execute a request synchronously.

When using the synchronous execute, your app will block until the handler terminates.

Note that internally, the execute process will run your event loop. This implies that the user may still be able to click buttons or select menu items while the UI should normally be blocked. Your app should therefore remember it is currently executing a request and ignore any such event that would start some other action. It is in particular illegal to start a second synchronous execute simultaneously.

When this function returns, check the result. If it is ALP_STATUS_OK, you can then get result parameters and/or data objects that may have been sent back. Don't forget to call alp_exg2_request_delete() when you are done.

See alp_exg2_request_execute_async() if you need to execute multiple requests simultaneously, or if you want to run your UI while a request is executing.

Note : you can only use this function from the main thread (the thread running the main loop). Do not call it from another thread. If you need to execute a request from another thread, use the asynchronous call.

Parameters:
[in] iRequest the request
Returns:
ALP_STATUS_OK - success
ALP_EXG2_HANDLERNOTFOUND_ERR - There is no handler registered for this verb and subject
ALP_EXG2_HANDLERTIMEOUT_ERR - Handler did not respond to invocation in time

alp_status_t alp_exg2_request_get_remote_peer_name AlpExg2Request  iRequest,
char **  oPeerName
 

Get the remote name.

The remote name is automatically displayed by the exchange manager progress window. But if you want to implement your own progress, you can use this function to get the name yourself. Note the name may not be defined by the remote.

Parameters:
[in] iRequest the request
[out] oPeerName is a malloc'ed string. Free the string when done.
Returns:
ALP_STATUS_OK - success
ALP_EXG2_PARAMNOTFOUND_ERR - the name is not available - this is not an error

alp_status_t alp_exg2_request_get_remote_peer_name_const AlpExg2Request  iRequest,
const char **  oPeerName
 

Get the remote name (const).

This is the same than alp_exg2_request_set_local_peer_name() except it returns a const pointer. The pointer is valid only until you use a "set" function that will modify the request, or you return to the event loop.

Parameters:
[in] iRequest the request
[out] oPeerName is a const pointer to the remote name
Returns:
ALP_STATUS_OK - success
ALP_EXG2_PARAMNOTFOUND_ERR - the name is not available - this is not an error

alp_status_t alp_exg2_request_get_subject AlpExg2Request  iRequest,
char **  oSubject
 

Get the subject.

Use this function to determine the subject if you have registered the same handler for several subjects, or for a wildcard.

Parameters:
[in] iRequest the request
[out] oSubject returns a const pointer to the verb.
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_get_subject_const AlpExg2Request  iRequest,
const char **  oSubject
 

Get the subject (const).

This is the same than alp_exg2_request_get_subject(), except it returns a pointer to a const string. Use this function is you don't need the malloc'ed string, as it is cheaper to use. The pointer is valid only until you use a "set" function that will modify the request, or you return to the event loop.

Parameters:
[in] iRequest the request
[out] oSubject returns a const pointer to the subject.
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_get_verb AlpExg2Request  iRequest,
char **  oVerb
 

Get the verb.

If you have registered several verbs, use this function to determine for which verb your handler is invoked.

Parameters:
[in] iRequest the request
[out] oVerb returns a malloc'ed string. Free the string when done.
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_get_verb_const AlpExg2Request  iRequest,
const char **  oVerb
 

Get the verb (const).

This is the same than alp_exg2_request_get_verb(), except it returns a pointer to a const string. Use this function is you don't need the malloc'ed string, as it is cheaper to use. The pointer is valid only until you use a "set" function that will modify the request, or you return to the event loop.

Parameters:
[in] iRequest the request
[out] oVerb returns a const pointer to the verb.
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_int_parameter_get AlpExg2Request  iRequest,
const char *  iParamTag,
int *  oParamValue
 

Get an integer parameter from the request.

Parameters:
[in] iRequest the request
[in] iParamTag the parameter name
[out] oParamValue the parameter value
Returns:
ALP_STATUS_OK - success
ALP_EXG2_PARAMNOTFOUND_ERR - This parameter does not exist in the request

alp_status_t alp_exg2_request_int_parameter_set AlpExg2Request  iRequest,
const char *  iParamTag,
int  iParamValue
 

Add an integer parameter to the request.

Creates a new integer parameter. If a parameter with this name exists, it is replaced. Parameters are used to pass additional and/or optional information to the handler. See the handler documentation to learn what parameters it defines.

Parameters:
[in] iRequest the request
[in] iParamTag the parameter name
[in] iParamValue the parameter value
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_object_add_by_fd AlpExg2Request  iRequest,
int  iFd,
size_t  iObjectSize,
const char *  iObjectName,
const char *  iObjectType,
const char *  iObjectDscr
 

Add a data object by file descriptor.

If you have a file descriptor to the data source, you can just directly add that to the request. Once added successfully, the file descriptor belongs to the request and you must not touch it anymore. It will automatically be closed when done.

Note that you must provide the object size so it is not possible to use this function if you don't know how much data will be available.

Parameters:
[in] iRequest the request
[in] iFd a file descriptor
[in] iObjectSize the length of the data to read from the file descriptor.
[in] iObjectName used in UI, must be some meaningful text ("Eric vcard", "Lunch vcal"...).
[in] iObjectType can be NULL (iObjectname must end with a file extension to be used in place of the type).
[in] iObjectDscr (optional). If present, can be used in UI.
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_object_add_by_file AlpExg2Request  iRequest,
const char *  iObjectFile,
int  iDeleteWhenDone,
const char *  iObjectName,
const char *  iObjectType,
const char *  iObjectDscr
 

Add a data object by file.

Add an object by file. Use this function when you have the data available in a file. If the file is temporary, set iDeleteWhenDone : exchange manager will take care to delete the file when needed.

Even though you add a file, the file is never duplicated. You can safely add a file from your own data and be sure it will not be touched by anybody. The handler will only access it through a file descriptor with read permission only, and will not know anything about the original data source.

Parameters:
[in] iRequest the request
[in] iObjectFile a filename with read permission
[in] iDeleteWhenDone if true, exchange manager will delete the file when done.
[in] iObjectName used in UI, must be some meaningful text ("Eric vcard", "Lunch vcal"...).
[in] iObjectType can be NULL (iObjectname must end with a file extension to be used in place of the type).
[in] iObjectDscr (optional). If present, can be used in UI.
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_object_add_by_ptr AlpExg2Request  iRequest,
uint8_t *  iObjectP,
size_t  iObjectSize,
int  iFreeWhenDone,
const char *  iObjectName,
const char *  iObjectType,
const char *  iObjectDscr
 

Add a data object by memory pointer.

If you have the data in memory, add the object by specifying its pointer. This is useful for objects that are small amounts of data, such as strings (phone number, email...). If the object is a string, it is recommended that you include the final null in the size. This will make it easier to use for the handler if he also receives it in memory. The pointer must remain valid until the request execution has completed. The data will be streamed as necessary when the handler reads it. Note that iObjectP does not necessarily point to writable memory, although if iFreeWhenDone is true, then iObjectP must be a free-able chunk.

Parameters:
[in] iRequest the request
[in] iObjectP a pointer to the data in memory
[in] iObjectSize the length of the data in memory
[in] iFreeWhenDone if true, exchange manager will free() the chunk when done
[in] iObjectName used in UI, must be some meaningful text ("Eric vcard", "Lunch vcal"...).
[in] iObjectType can be NULL (iObjectname must end with a file extension to be used in place of the type).
[in] iObjectDscr (optional). If present, can be used in UI.
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_object_add_undefined AlpExg2Request  iRequest,
uint32_t *  oObjectId
 

Add a data object for which you don't have the data yet.

This function lets you add undefined object. You can use this to reserve an entry in the data object list and let the receiver know that it must wait for the data of this object to become ready.

You typically use this function when you know there will be data, but you don't know what data nor how much yet. You start to execute the request with undefined objects in it, and you define the objects later, during execution. The handler will only be able to receive the object when you will have defined it.

Parameters:
[in] iRequest the request
[out] oObjectId the id for this object. Use the id to define the object later.
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_object_define_by_fd AlpExg2Request  iRequest,
uint32_t  iObjectId,
int  iFd,
size_t  iObjectSize,
const char *  iObjectName,
const char *  iObjectType,
const char *  iObjectDscr
 

Define an object by file descriptor.

You can call this function before or after you have started to execute the request (asynchronously) See alp_exg2_request_object_add_by_fd() for more details about data objects specified by file descriptor The object will become available to the handler as soon as you have defined it.

Parameters:
[in] iRequest the request
[in] iObjectId the Id that was returned when you added the undefined object
[in] iFd a file descriptor
[in] iObjectSize the length of the data to read from the file descriptor.
[in] iObjectName used in UI, must be some meaningful text ("Eric vcard", "Lunch vcal"...).
[in] iObjectType can be NULL (iObjectname must end with a file extension to be used in place of the type).
[in] iObjectDscr (optional). If present, can be used in UI.
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_object_define_by_file AlpExg2Request  iRequest,
uint32_t  iObjectId,
const char *  iObjectFile,
int  iDeleteWhenDone,
const char *  iObjectName,
const char *  iObjectType,
const char *  iObjectDscr
 

Define an object by file.

You can call this function before or after you have started to execute the request (asynchronously) See alp_exg2_request_object_add_by_file() for more details about data objects specified by file The object will become available to the handler as soon as you have defined it.

Parameters:
[in] iRequest the request
[in] iObjectId the Id that was returned when you added the undefined object
[in] iObjectFile a filename with read permission
[in] iDeleteWhenDone if true, exchange manager will delete the file when done.
[in] iObjectSize the length of the data to read from the file descriptor.
[in] iObjectName used in UI, must be some meaningful text ("Eric vcard", "Lunch vcal"...).
[in] iObjectType can be NULL (iObjectname must end with a file extension to be used in place of the type).
[in] iObjectDscr (optional). If present, can be used in UI.
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_object_define_by_ptr AlpExg2Request  iRequest,
uint32_t  iObjectId,
uint8_t *  iObjectP,
size_t  iObjectSize,
int  iFreeWhenDone,
const char *  iObjectName,
const char *  iObjectType,
const char *  iObjectDscr
 

Define an object by memory pointer.

You can call this function before or after you have started to execute the request (asynchronously) See alp_exg2_request_object_add_by_ptr() for more details about data objects specified by memory pointer The object will become available to the handler as soon as you have defined it.

Parameters:
[in] iRequest the request
[in] iObjectId the Id that was returned when you added the undefined object
[in] iObjectP a pointer to the data in memory
[in] iObjectSize the length of the data in memory
[in] iFreeWhenDone if true, exchange manager will free() the chunk when done
[in] iObjectName used in UI, must be some meaningful text ("Eric vcard", "Lunch vcal"...).
[in] iObjectType can be NULL (iObjectname must end with a file extension to be used in place of the type).
[in] iObjectDscr (optional). If present, can be used in UI.
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_object_rcv_by_fd AlpExg2Request  iRequest,
uint32_t  iObjectId,
int *  oFd
 

Receive a file descriptor to read the data from.

Use this function when you need a file descriptor to feed some other library. If the object source is on the local device, the file descriptor you receive is a direct connection to that source. If the object is not local, or is not streamable, the data will be saved to a local file first and you'll get an fd to that local file.

The fd you get is not a FILE* (you cannot seek or do any other FILE operation). All you can do is read, and you should not try to read more than the objectsize you got in the object info.

The blocking state of the fd depends on the data source and on how the sender specified the data. If you explicitly need a blocking or non blocking fd, you must set the fd flags yourself before using it. If you read from a non blocking fd and the source data is not available yet, you must handle EAGAIN (or EWOULDBLOCK) errors by doing the read again.

The fd you get is yours : you must close it when you are done.

Any error is unrecoverable and the request should be deleted using alp_exg2_request_receive_complete() or alp_exg2_request_delete() depending on whether you are a handler or a requester.

Parameters:
[in] iRequest the request
[in] iObjectId the same objectid you used in the last alp_exg2_request_object_rcv_info()
[out] oFd the file descriptor to the data
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_object_rcv_by_file AlpExg2Request  iRequest,
uint32_t  iObjectId,
const char *  iDestFile
 

Receive an object into a file.

Use this function when you want the object to be stored in a file. The directories must exist, but the file must not exist. So you must check yourself if the file doesn't exist and possibly ask the user if he wants to overwrite the file (and if so, you must unlink the existing file before you call this function). The file will be created with rw------- access rights, so you'll need to chmod the file if you want something else.

The file will be streamed from the source at this time and the progress dialog will show progress automatically (unless you disabled it).

Any error is unrecoverable and the request should be deleted using alp_exg2_request_receive_complete() or alp_exg2_request_delete() depending on whether you are a handler or a requester.

Parameters:
[in] iRequest the request
[in] iObjectId the same objectid you used in the last alp_exg2_request_object_rcv_info()
[in] iDestFile the request a full path to the filename you want to store the data
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_object_rcv_by_ptr AlpExg2Request  iRequest,
uint32_t  iObjectId,
uint8_t **  oObjectP,
size_t *  oObjectSize
 

Receive the data object in a memory chunk.

Use this function when you want the data in memory. This is useful for small amounts of data such as strings (phone number or email) that you would need to load anyway.

The object data is returned in a newly malloc'ed chunk. You are responsible to free() this chunck when you are done with it.

Any error is unrecoverable and the request should be deleted using alp_exg2_request_receive_complete() or alp_exg2_request_delete() depending on whether you are a handler or a requester.

Parameters:
[in] iRequest the request
[in] iObjectId the same objectid you used in the last alp_exg2_request_object_rcv_info()
[out] oObjectP a malloc'ed chunk containing the data
[out] oObjectSize the size of the malloc'ed chunk (will be the same than the objectsize from the object info)
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_object_rcv_count AlpExg2Request  iRequest,
uint32_t *  oObjectCount
 

Get an indication of the number of data objects in the request.

This function can be called on a received request only, or on a result request with zero status. It will return an indication of the number of data objects. This information is purely indicative so that it can be used in UI progress if available. If not available, the returned objectcount will be 0xFFFFFFFF to mean the object count is unknown. Applications must always iterate on alp_exg2_request_object_rcv_info() until the result is ALP_EXG2_NOMOREOBJECTS_ERR.

Parameters:
[in] iRequest the request
[out] oObjectCount the number of received data objects (or 0xffffffff if not known).
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_object_rcv_info AlpExg2Request  iRequest,
uint32_t  iObjectId,
size_t *  oObjectSize,
const char **  oObjectName,
const char **  oObjectType,
const char **  oObjectDscr
 

Get Info for the next received data object.

When you receive a request, none of the contained data objects have been sent to you yet. You must do a loop to sequentially receive each object (objects are streamed to you in order, so you can't receive the next object info until you have received the current object data.

The loop must first call this function to receive information about the next object. If the required object is not yet defined by the sender, the function returns ALP_EXG2_OBJECTNOTREADY_ERR. Just wait a second and try again. Run the event loop to make sure the progress dialog animation lives.

When you have the info, use the information to do UI (ask a confirmation from the user) and possibly determine a filename for example (if you intend to save the data in a file).

When there are no more objects, the function returns ALP_EXG2_NOMOREOBJECTS_ERR. Any other error is unrecoverable and the request should be deleted using alp_exg2_request_receive_complete() or alp_exg2_request_delete() depending on whether you are a handler or a requester.

Parameters:
[in] iRequest the request
[in] iObjectId the object index (start with 1)
[out] oObjectSize the data size
[out] oObjectName a user friendly name representing the object
[out] oObjectType a mimetype, or maybe just a file extension depending on what the sender provided
[out] oObjectDscr (optional will be NULL if there is no description provided by the sender)
Returns:
ALP_STATUS_OK - success
ALP_EXG2_OBJECTNOTREADY_ERR - sender has not specified object yet, try again later
ALP_EXG2_NOMOREOBJECTS_ERR - sender has closed the object list and you have received them all

alp_status_t alp_exg2_request_object_set_count_final AlpExg2Request  iRequest  ) 
 

Tell the request you have added all objects.

This function must be used only if you have called alp_exg2_request_object_set_count_undefined() before. It can be called before the request is executed or while it is executing asynchronously. Calling this function will let the handler receive a ALP_EXG2_NOMOREOBJECT_ERR status when it is waiting for the next object.

Parameters:
[in] iRequest the request
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_object_set_count_undefined AlpExg2Request  iRequest  ) 
 

Tell the request more objects will be added later.

This function tells the exchange manager that the number of objects that will be added is unknown. Objects will be added while the request is executing, but the total count is not known at the time the request is executed When you use this function, the handler will receive an indication that the object count is unknown, and it will loop asking objects until it receives the ALP_EXG2_NOMOREOBJECT_ERR.

Parameters:
[in] iRequest the request
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_receive_complete AlpExg2Request  iRequest,
alp_status_t  iResult
 

Complete your handler execution.

You must call this function before you exit your handler if you have sucessfully received the request. This will return the parameters and/or data objects you may have added to the request. It will also return your handler result to the requester. The requester alp_exg2_request_execute_sync/async function call will return/complete at this time and deliver your result.

If you have added data objects to return, this function will block until the requester has received all the objects.

Note that internally, the complete process will run your event loop. This implies that the user may be able to click buttons or select menu items while the UI should normally be blocked. Your app should therefore remember it is currently completing a request and ignore any such event that would conflict with the current handler.

The function result is purely informative, as there is really nothing you can do with it.

Parameters:
[in] iRequest the request
[in] iResult : the handler result, which will be returned to the requester.
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_receive_progress_disable AlpExg2Request  iRequest  ) 
 

Disable the automatic receive progress.

If you have linked your app with the exgmgr2_objrcv_ui library, exchange manager will display an automatic progress dialog when you receive data objects that are sent through slow media such as Bluetooth. If you want to manage your own progress, or you just want no progress at all, you must call this function to disable the automatic progress. This function must be called before the first call to alp_exg2_request_object_rcv_info().

To help you decide whether you want receive progress to be displayed or not, exchange manager defines a few 'hint' parameters you can examine.

  • ALP_EXG2_HINT_MEDIA_TYPE_INT_PARAM tells you what the transport media is (local, bluetooth, Wifi, 3G...).
  • ALP_EXG2_HINT_MEDIA_SPEED_INT_PARAM tells you the what the transport media speed is (in kbps)
  • ALP_EXG2_HINT_OBJECTS_TOTAL_SIZE_INT_PARAM tells you the approximate total size of the data objects.
  • ALP_EXG2_HINT_SLOW_MEDIA_INT_PARAM tells you the sender recommends to use progress

Use alp_exg2_request_int_parameter_get() to get the value of each hint. Note all these hints are optional and may not exist. So be prepared for a default choice.

Parameters:
[in] iRequest the request
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_receive_start AlpExg2Request oRequest,
AlpExg2RequestId  iRequestId
 

Receive a request in your handler.

If you used alp_exg2_handler_register_launch() to register your handler, you will receive the requestId through the command line parameters (argv) If you used alp_exg2_handler_register_callback(), you will receive the requestId as a callback parameter.

Use this function to receive the request corresponding to the requestId. This will actually connect your handler to the requester and you will then be able to get the request content (parameters and data objects).

If this function fails, there is nothing more to do. Just exit directly from the exchange handler without calling alp_exg2_request_receive_complete(). If this function succeeds, you must call alp_exg2_request_receive_complete() before you exit the exchange handler.

Parameters:
[out] oRequest the request you have received
[in] iRequestId the request id you received
Returns:
ALP_STATUS_OK - success
ALP_EXG2_REQUESTNOTFOUND_ERR - There is no request for this id. Most probably, you have waited to long to receive it, and the request timed out
ALP_EXG2_REQUESTALREADYRECEIVED_ERR - The corresponding request is already received and executing

alp_status_t alp_exg2_request_set_local_peer_name AlpExg2Request  iRequest,
const char *  iPeerName
 

Set the name of the requester.

The peer name (optional) is the name of the entity emiting this request. If specified, it will be used in receive progress (if any) to show the origin of the received data. Note that it is possible to call this function while the request is executing: the new name will be forwarded to the handler and updated as necessary.

This function can be used by a requester, but also by a handler if it returns data objects.

Parameters:
[in] iRequest the request
[in] iPeerName 
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_set_subject AlpExg2Request  iRequest,
const char *  iSubject
 

Set the subject.

Use this function to set the subject if you haven't set it when you created the request.

The subject, along with the verb, is used to find which handler will manage this request. It defines what the verb will act upon. If there are no data objects in the request (but only parameters), the subject can be any string like "phonenumber" or "emailaddress". If there are data objects in the request, the subject will generally be the same than the data object type (mime type) but there is no relation between them. Also note that the request can contain multiple data objects of different data types, but there is only one subject.

Parameters:
[in] iRequest the request
[in] iSubject the subject
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_set_verb AlpExg2Request  iRequest,
const char *  iVerb
 

Set the verb.

Use this function to set the verb if you haven't set it when you created the request. If the verb is composed using an action class, it must be in the form "ActionClass/Method".

Parameters:
[in] iRequest the request
[in] iVerb the verb
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_request_string_parameter_get AlpExg2Request  iRequest,
const char *  iParamTag,
char **  oParamValue
 

Get a string parameter from the request.

This function returns a malloc'ed string. You must free() it when you are done.

Parameters:
[in] iRequest the request
[in] iParamTag the parameter name
[out] oParamValue a malloc'ed string
Returns:
ALP_STATUS_OK - success
ALP_EXG2_PARAMNOTFOUND_ERR - This parameter does not exist in the request

alp_status_t alp_exg2_request_string_parameter_get_const AlpExg2Request  iRequest,
const char *  iParamTag,
const char **  oParamValue
 

Get a string parameter from the request (const).

This function returns a const pointer to the string value. The pointer is valid only until you use a "set" function that will modify the request, or you return to the event loop.

Parameters:
[in] iRequest the request
[in] iParamTag the parameter name
[out] oParamValue a const pointer to the string
Returns:
ALP_STATUS_OK - success
ALP_EXG2_PARAMNOTFOUND_ERR - This parameter does not exist in the request

alp_status_t alp_exg2_request_string_parameter_set AlpExg2Request  iRequest,
const char *  iParamTag,
const char *  iParamValue
 

Add a string parameter to a request.

Creates a new string parameter. If a parameter with this name exists, it is replaced. Parameters are used to pass additional and/or optional information to the handler. See the handler documentation to learn what parameters it defines.

Parameters:
[in] iRequest the request
[in] iParamTag the parameter name
[in] iParamValue the parameter value
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_transport_get AlpExg2Request  iRequest,
char **  oParamsValue
 

Get the transport params from the request.

There is currently no other transport existing, so this function useless for now.

Parameters:
[in] iRequest the request
[out] oParamsValue a malloc'ed string
Returns:
ALP_STATUS_OK - success
ALP_EXG2_PARAMNOTFOUND_ERR - There are no transport params set in the request

alp_status_t alp_exg2_transport_get_const AlpExg2Request  iRequest,
const char **  oParamsValue
 

Get the transport params from the request (const).

There is currently no other transport existing, so this function useless for now.

Parameters:
[in] iRequest the request
[out] oParamValue a const pointer to the string
Returns:
ALP_STATUS_OK - success
ALP_EXG2_PARAMNOTFOUND_ERR - There are no transport params set in the request

alp_status_t alp_exg2_transport_set AlpExg2Request  iRequest,
const char *  iParamsValue
 

Setup to execute the request on a remote device.

By default, requests are dispatched on the local device. This function can be use to specify an exchange transport so that the request will be sent to another device using this transport.

There is currently no other transport existing, so this function does nothing for now.

Parameters:
[in] iRequest the request
[in] iParamsValue a string encoding a transport and the destination address (to be defined)
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_utils_action_method_select GtkWindow *  iParentWindow,
const char *  iDialogTitle,
const char *  iDialogPrompt,
char *  iQueryMethodsList,
uint32_t  iQueryMethodsEntryCount,
const char **  oSelectedMethod
 

UI Dialog to select a method for an action class.

Call this function to handle a UI dialog displaying a list of methods. The method list must have previously been obtained using alp_exg2_handler_query_methods().

If iParentWindow is not NULL, the dialog will be set transient to this window. The return value will be zero and oSelectedMethod will point to the chosen verb inside iQueryMethodsList. Use this verb to build your request. The return value will return ALP_EXG2_USERCANCEL_ERR if the user clicked Cancel or OK with no selection. Any other error are possible as well.

Parameters:
[in] iParentWindow 
[in] iDialogTitle the string to use for the dialog title
[in] iDialogPrompt the string to use for the user prompt
[in] iQueryMethodsList the method list
[in] iQueryMethodsEntryCount the number of entries in the list
[out] oSelectedMethod a const pointer to the selected verb
Returns:
ALP_STATUS_OK - success

alp_status_t alp_exg2_utils_action_method_select_and_set AlpExg2Request  iRequest,
GtkWindow *  iParentWindow,
const char *  iExcludeInvokeName,
const char *  iAction,
const char *  iSubject
 

Select a method for an action class, using UI if necessary and set the verb in the request.

This function is an all in one wrapper to alp_exg2_handler_query_methods, alp_exg2_utils_get_method_select_strings, alp_exg2_utils_action_method_select and it will set the verb and subject for your request in a single call. If there is only one method available, it will be selected automatically and no UI will be shown. It there are several methods corresponding to the action class and subject, a UI dialog is displayed to let the user choose one.

If iParentWindow is not NULL, the optional dialog will be set transient to this window

Upon successful return, the selected verb and the subject will have been set in the request. The return value will be set to ALP_EXG2_USERCANCEL_ERR if the user clicked Cancel or OK with no selection. The return value will be set to ALP_EXG2_HANDLERNOTFOUND_ERR if no methods could be found. The return value will be set to ALP_EXG2_INVALIDAPIPARAM_ERR if the given action class is not recognized. Any other error are possible as well.

Parameters:
[in] iRequest 
[in] iParentWindow 
[in] iExcludeInvokeName can be NULL. If not null, will filter out handlers that are registered to launch this bundle.
[in] iAction NULL if you want to list all the verbs, or an action class if you want the methods for a specific action only.
[in] iSubject a subject or mimetype
Returns:
ALP_EXG2_INVALIDAPIPARAM_ERR - The given actionClass is not recognized, the UI dialog could not be displayed ALP_EXG2_HANDLERNOTFOUND_ERR - There was no method available
ALP_STATUS_OK - success

void alp_exg2_utils_get_method_select_strings const char *  iAction,
const char **  oDialogTitle,
const char **  oDialogPrompt
 

Get localized strings for the select method dialg.

The alp_exg2_utils_action_method_select() function needs strings for the dialog title and prompt. If you are selecting methods for a predefined action class, call this function to get the standard strings.

Note that only ALP_EXG2_SEND_ACTIONCLASS strings are supported at the moment.

Parameters:
[in] iAction the request
[out] oDialogTitle the string to use for the dialog title
[out] oDialogPrompt the string to use for the user prompt

alp_status_t alp_exg2_utils_transport_select AlpExg2Request  iRequest,
const char *  iPrompt
 

Display a dialog to select a transport.

Exchange manager is capable of executing a request on a remote device. This requires to set the transport params in the request. This function displays a dialog listing the available transports and lets the user selects one, and optionnaly enter additional destination address. The prompt displayed should be something like "where do you want to execute this service?". The request transport params will be automatically set if the user taps OK;

NOTE: there are currently no external transport available. This function currently does nothing.

Parameters:
[in] iRequest the request
[in] iPrompt the prompt displayed above the transport list
Returns:
ALP_STATUS_OK - success


Generated on Wed Jul 30 07:06:44 2008 by Doxygen 1.4.6 for ALP SDK + Hiker Documentation

Copyright © 1999-2008 ACCESS CO., LTD. All rights reserved.