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. | |
|
|
error opening/stating a file
|
|
|
Execution has completed.
|
|
|
Cannot bind a socket.
|
|
|
Error or hangup on connection between client and handler or between daemon nad handler.
|
|
|
This prefix should be used for localized verbs which are contained in a known bundle. The bundle name must be a constant string.
|
|
|
This prefix should be used for localized verbs which are contained in the same bundle which the exchange handler is registered to launch.
|
|
|
max len for the bundle name
|
|
|
bundle name too long
|
|
|
A file descriptor could not be read across processes..
|
|
|
A file descriptor could not be sent across processes..
|
|
|
Cannot connect a socket.
|
|
|
A string representing the contacts database identifier for a contact (unsigned int, must be converted back to AlpLuid).
|
|
|
error opening/creating a file
|
|
|
Cannot create a socket.
|
|
|
General daemon internal failure.
|
|
|
Dial : methods examples: voice call, video call, send sms-mms...
|
|
|
Edit (modify) data: methods examples: edit image, edit text...
|
|
|
A string representing an email.
|
|
|
Export : methods examples: to file...
|
|
|
A string representing an extended phone number (for example, a USSD request).
|
|
|
Cannot set socket options.
|
|
|
Base for errors generated by a requester or a handler. These enable a handler to return a precise specific error.
|
|
|
Get data: methods examples: take picture, get file, get vcard...
|
|
|
error while creating or attaching a gsource, or adding a timeout to a gsource
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
thisverb/subject is already registered by this registrant
|
|
|
Handler doen't accept requests from remote device.
|
|
|
There was no registered handler to handle this request.
|
|
|
There was already an active handler for this verb/subject. This handler was registered but flagged inactive.
|
|
|
Handler did not respond to invocation in time.
|
|
|
Media Speed hint : if this parameter exists, it gives an indication of the incoming bandwidth in kbps.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Media Type hint : if this parameter exists, it gives an indication of the media type.
|
|
|
|
|
|
|
|
|
|
|
|
Total data size Hint : if this parameter exists, it gives an indication of the total size of received objects.
|
|
|
Sender indicates slow media Hint : if this parameter exists and value is not zero, it indicates the sender recommends to use progress window.
|
|
|
Import : methods examples: from file...
|
|
|
An invalid parameter was passed to some API.
|
|
|
General library internal failure.
|
|
|
Cannot listen a socket.
|
|
|
max len for the localized verb
|
|
|
Localized verb is too long.
|
|
|
mimetype is too long
|
|
|
There are no more objects to receive.
|
|
|
No transport plug-in found.
|
|
|
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.
|
|
|
The object you are trying to receive is not fully defined yet. Try again later.
|
|
|
Out of memory.
|
|
|
Request does not contain the expected parameter.
|
|
|
A string representing a phone number.
|
|
|
Print data: methods examples: Print to network, Print to Bluetooth...
|
|
|
A consistency check revealed a programming error.
|
|
|
error reading from a file
|
|
|
Cannot read a socket.
|
|
|
error trying to open/create/rename the registration cache file
|
|
|
The requested request is currently already handled..
|
|
|
The requested request could ne be found. It may have timedout and been removed before receive request was called..
|
|
|
A string representing an RTSP URL.
|
|
|
Send data: methods are typically storage(local), obex bluetooth/IR, email attachments, SMS, MMS, FTP...
|
|
|
max len for the request subject
|
|
|
subject is too long
|
|
|
Timeout during data object transfer between requester and handler.
|
|
|
Something failed, we don't know what exactly.
|
|
|
A string representing an URL.
|
|
|
Execution was canceled.
|
|
|
max len for the verb
|
|
|
Verb is too long.
|
|
|
View data: methods examples: display image, play video, play mp3, read document...
|
|
|
error writing to a file
|
|
|
Cannot write a socket.
|
|
|
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; } }
|
|
|
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.
|
|
|
Event Type.
|
|
|
|
|
|
|
|
|
The exchange request. A request is created and accessed using Exchange Manager API only.
|
|
|
Reference Id you receive in an exchange handler. Use this id to receive the corresponding exchange request.
|
|
|
event msg sent to the async execute event function.
|
|
||||||||||||
|
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.
|
|
||||||||||||||||||||||||
|
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.
|
|
||||||||||||||||||||||||||||
|
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.
|
|
||||||||||||||||||||||||||||
|
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.
|
|
||||||||||||||||
|
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.
|
|
||||||||||||||||
|
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.
|
|
||||||||||||||||||||
|
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
|
|
||||||||||||||||||||
|
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.
|
|
|
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).
|
|
||||||||||||||||
|
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.
|
|
|
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.
|
|
||||||||||||||||
|
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.
|
|
||||||||||||
|
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.
|
|
|
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.
|
|
||||||||||||
|
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.
|
|
||||||||||||
|
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.
|
|
||||||||||||
|
Get the subject. Use this function to determine the subject if you have registered the same handler for several subjects, or for a wildcard.
|
|
||||||||||||
|
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.
|
|
||||||||||||
|
Get the verb. If you have registered several verbs, use this function to determine for which verb your handler is invoked.
|
|
||||||||||||
|
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.
|
|
||||||||||||||||
|
Get an integer parameter from the request.
|
|
||||||||||||||||
|
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.
|
|
||||||||||||||||||||||||||||
|
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.
|
|
||||||||||||||||||||||||||||
|
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.
|
|
||||||||||||||||||||||||||||||||
|
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.
|
|
||||||||||||
|
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.
|
|
||||||||||||||||||||||||||||||||
|
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.
|
|
||||||||||||||||||||||||||||||||
|
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.
|
|
||||||||||||||||||||||||||||||||||||
|
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.
|
|
||||||||||||||||
|
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.
|
|
||||||||||||||||
|
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.
|
|
||||||||||||||||||||
|
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.
|
|
||||||||||||
|
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.
|
|
||||||||||||||||||||||||||||
|
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.
|
|
|
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.
|
|
|
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.
|
|
||||||||||||
|
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.
|
|
|
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.
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.
|
|
||||||||||||
|
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.
|
|
||||||||||||
|
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.
|
|
||||||||||||
|
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.
|
|
||||||||||||
|
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".
|
|
||||||||||||||||
|
Get a string parameter from the request. This function returns a malloc'ed string. You must free() it when you are done.
|
|
||||||||||||||||
|
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.
|
|
||||||||||||||||
|
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.
|
|
||||||||||||
|
Get the transport params from the request. There is currently no other transport existing, so this function useless for now.
|
|
||||||||||||
|
Get the transport params from the request (const). There is currently no other transport existing, so this function useless for now.
|
|
||||||||||||
|
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.
|
|
||||||||||||||||||||||||||||
|
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.
|
|
||||||||||||||||||||||||
|
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.
|
|
||||||||||||||||
|
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.
|
|
||||||||||||
|
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.
|
Copyright © 1999-2008 ACCESS CO., LTD. All rights reserved.