USERNAME PASSWORD LOST PASSWORD? REGISTER
"A Complete Mobile Application Development Environment"
Advertisement

Downloads
Documentation
Forums
Blog
Press
Contact Us




Programming Messaging Applications PDF Print E-mail
Documentation »  ACCESS Linux Platform Native Development »  Messaging Guide »  Programming Messaging Applications

The Postal Manager exposes a set of APIs implemented by all plug-ins. For advanced, specific features, each service also exposes its own set of APIs. This section describes the generic API set.

All services implement certain generic concepts and procedures. Individual services also implement their own procedures, which are described in the following chapters:

Generic Usage Concepts for All Services ^TOP^

There are certain usage concepts that apply to each service - IMPS, Email, SMS, and MMS.

The Properties Concept ^TOP^

Most of the objects used by the Postal Manager are defined as a set of properties. The benefit is that each object is very flexible and can be composed of generic and specific properties.

On each object, you can set (add) a property and associate a value, and get a property value. Objects that are a set of properties are shown below:

  • Account
  • Folder
  • Envelope
  • Bodypart
  • Address

Figure 2.1  Example of an Account object

Object Hierarchy ^TOP^

A service can be mono- or multi-session.

Most of the features of a service rely on a session. A session is a temporary object created by the Service object, which requires an Account.

If the creation of the session succeeds (some security could be introduced in this process), the session can be connected.

Using the session, you can send and receive envelopes, enumerate folders, and store envelopes.

Figure 2.2  Object Hierarchy

Types of Properties

A property has one of the following types:

  • A <STRING> (Size is not required, but must be null terminated.)
  • A <BINARY> (You must pass dataSize as an argument.)
  • An <INTEGER> (Size is not required.)
  • A <DATE> (Size is not required.)
  • A <BOOLEAN> (Size is not required.)

For each object, one API is defined to set a property, and one is defined to get the value of a property. The value of the property (iValue) must be cast into alp_postal_property_value_t. iDataSize is 0, except for binaryData.

Set a Property on an Object


NOTE: When you set a property, the value is duplicated, so you must free it.
iObject
The object to which the property is added.
iPropertyId
The ID of the property. Each object defines its own set of properties. A property can be generic or specific to a service.
iValue
The value of the property. The value must be cast into alp_postal_property_value_t.
iDataSize
dataSize of data if iValue is binary; otherwise 0.

 
alp_postal_xxx_set_property (AlpPostalObject* iObject, 
alp_postal_property_id_t iPropertyId, 
alp_postal_property_value_t iValue, uint16_t iDataSize); 
 

Get a Property

When you retrieve a property, you call a helper to retrieve the value of the property. It is your responsibility to call the appropriate API according to the property's value type. (Getting a string from property that is defined to store an integer may be very risky.)

Some notes on properties:

  • When you get a property, you are only getting a pointer; you must not free that property.
  • When you get a string or binary value, you are only getting a pointer; you must not free the value.
  • A property can only be retrieved for an object that is in memory. If the object is stored and you have only the object ID, you must retrieve the object from the database.

Properties include the following:

iObject
The object to get the property from
iPropertyId
The ID of the property
oProperty
A pointer to the property that handles the value.

The following are examples of property functions:


 
alp_postal_xxx_get_property (AlpPostalObject* iObject,alp_postal_property_id_t 
iPropertyId,AlpPostalProperty** oProperty); 
// Next, retrieve the value using one of the following: 
alp_postal_property_get_int32 (AlpPostalProperty* iProperty, 
int32_t* oIntValue); 
alp_postal_property_get_string (AlpPostalProperty* iProperty,  
char** oStringValue); 
//(Other helpers are defined in postal_property.h) 
 

Enumerators ^TOP^

Enumerators enable the retrieval of a large number of objects without overloading the memory. You can get an enumerator and invoke the next API on it while it contains items. After using the enumerator, you must release it.


NOTE: When you get an object from an enumerator (returned by the next API), it is duplicated. Consequently, you must free it.

Initializing Messaging Services ^TOP^

The postal event model relies on the gMainLoop to process events such as notifications or asynchronous responses.

To become a postal client and use the postal services, initialize communication with the Postal Manager by calling this function:


 
// Initialize contextP with g_main_context_default(); 
alp_postal_glib_init(GmainContext* contextP); 
 

Once this is done, the client has to run gMainLoop.


NOTE: If your application doesn't rely on GTK, you can create and run your own gMainLoop by using Glib APIs.

If the client wants to use specific APIs or receive a specific notification, it must also call the related service's initialize function (alp_postal_xxx_service_initialize).

To finalize the notification, call the finalize function (alp_postal_xxx_service_finalize). For example, an IMPS the client must call alp_postal_imps_service_initialize and alp_postal_imps_service_finalize.

Account Examples ^TOP^

This section provides examples of how to create/save a new account and how to enumerate accounts that belong to the SMS service.

The first example, Listing 2.1, illustrates the life cycle of an object you are creating/saving:

  1. Declare the object
  2. Initialize the object
  3. Set properties on the object
  4. Create or Save the object (i.e., save the properties into the database)
  5. Free the object

Listing 2.1  Creating (Saving) a New Account


// Object ID of the account returned when saved 
alp_postal_account_id_t accountObjectId; 
 
// Declare the account 
AlpPostalAccount sms _account; 
 
// Initialize the account 
Alp_postal_account_init(&sms _account); 
 
// Set the properties 
// A generic property is used first 
alp_postal_account_set_property (&sms _account, 
ALP_POSTAL_PROPERTY_ACCOUNT_NAME, (alp_postal_property_value_t)"My_Account", 
0); 
 
// A specific property relative to the SMS service (set the SMS center)  
// is then used 
alp_postal_account_set_property (&sms _account, 
ALP_POSTAL_SMS_PROPERTY_ACCOUNT_SMS_CENTER, (alp_postal_property_value_t)" 
336534985", 0); 
 
// Save the account: ask the Postal Service to create (store) the account 
alp_postal_service_create_account (ALP_POSTAL_SERVICE_ID_SMS, &sms_account, & 
accountObjectId); 
 
// Free the object from memory; it is now in permanent storage 

The second example, "Enumerating Accounts Belonging to SMS Service", illustrates the life cycle of an object you are enumerating:

  1. Declare the enumerator
  2. Initialize the enumerator
  3. Retrieve the enumerator
  4. Perform the enumeration
  5. Free the object retrieved
  6. Release the enumerator

Listing 2.2  Enumerating Accounts Belonging to SMS Service


AlpPostalAccount sms_account; 
// Declare the enumerator 
AlpPostalEnumerator enumerator; 
AlpPostalProperty* propertyP; 
alp_status_t err=POSTAL_STATUS_OK; 
 
// Initialize the enumerator 
alp_postal_service_account_init_enumerator (&enumerator); 
 
// Retrieve the enumerator 
alp_postal_service_get_account_enumerator 
(ALP_POSTAL_SERVICE_ID_SMS, &enumerator); 
 
// Perform the enumeration 
while (err==POSTAL_STATUS_OK) 
{ 
        alp_postal_account_init (&account); 
        err=alp_postal_service_get_next_account (&enumerator, 
&account); 
 
// Free the object retrieved 
alp_postal_account_free (&account); 
} 
// Release the enumerator 
alp_postal_service_account_release_enumerator(&enumerator); 

Connection Example ^TOP^

This section provides an example of how to create and connect an SMS session. In this example, you can assume the SMS account exists and has a known account_id.

Listing 2.3  Creating and Connecting an SMS Session


// Create a session using the existing account_id 
alp_postal_session_id_t sessionId; 
alp_postal_service_create_session (ALP_POSTAL_SERVICE_ID_SMS, 
account_id, &sessionId); 
 
// Connect the session  
alp_postal_session_connect (ALP_POSTAL_SERVICE_ID_SMS, 
sessionId, NULL, NULL, NULL); 

The operation, alp_postal_session_connect(), has different meanings according to the service used. For SMS and MMS, the operation may switch the phone module ON. For IMPS, the operation attempts to log into the IMPS server.

Note that the second and third parameters of alp_postal_session_connect() can be used to force the use of a password for sending and receiving, but this feature is not used in the example.

The fourth parameter is the callback that will be called when the asynchronous session_connect call ends. The fourth parameter is set to NULL in the example.

The Envelope Object ^TOP^

An envelope contains the properties relative to a message that the service will need to send it. Like other property-based objects, an envelope can be composed of generic and specific properties.

An envelope is an aggregation of envelope properties, "To" recipients, "Cc" recipients, "Bcc" recipients, a "From" list, a "ReplyTo" list, and a bodypart list. After declaring and initializing an envelope object, you use envelope helper API to build the envelope.

The Bodypart Object ^TOP^

Text in a Single Bodypart ^TOP^

In the simplest case, we just want to set text to the envelope. If the text is small (less than ALP_POSTAL_BODYPART_SMALL_TEXT_MAX_SIZE), we can use the ALP_POSTAL_PROPERTY_BODYPART_SMALL_CONTENT property.

In this case we just have to declare a bodypart, set the text property, and add it to the envelope.

Listing 2.4  Attaching Text to an Envelope


AlpPostalEnvelope env; 
alp_postal_bodypart_part_no_t partNo; 
 
alp_postal_envelope_init(&env); 
AlpPostalBodypart bp; 
alp_postal_bodypart_init(&bp); 
 
// Set properties for bodypart 
alp_postal_bodypart_set_property(&bp, 
ALP_POSTAL_PROPERTY_BODYPART_SMALL_CONTENT, 
(alp_postal_property_value_t)"hello world", 0); 
 
// Add the bodypart to the envelope. 
// Since this is a simple bodypart, the parent number is
// NO_PARENT. 
alp_postal_envelope_append_bodypart(&env, &bp, 
ALP_POSTAL_BODYPART_NO_PARENT, &partNo); 

Multipart Bodyparts ^TOP^

The bodyparts have been designed to handle multipart bodypart structure. A complex bodypart is a tree; each part has a part number (first is 1). Example of multipart bodyparts:

Listing 2.5  Attaching Bodypart Structure to an Envelope


AlpPostalEnvelope env; 
alp_postal_bodypart_part_no_t partNo, partNo2; 
 
alp_postal_envelope_init(&env); 
 
AlpPostalBodypart bp1, bp3, bp4, bp5; 
AlpPostalBodypart multipart; 
 
alp_postal_bodypart_init(&bp1); 
alp_postal_bodypart_init(&bp3); 
alp_postal_bodypart_init(&bp4); 
alp_postal_bodypart_init(&bp5); 
alp_postal_bodypart_init(&multipart); 
 
// Set properties for bodypart 1 
alp_postal_bodypart_set_property(&bp1, 
ALP_POSTAL_PROPERTY_BODYPART_NAME, 
(alp_postal_property_value_t)"bodypart 1", 0); 
 
// Set properties for bodypart 2, which is a multipart 
alp_postal_bodypart_set_property(&multipart, 
ALP_POSTAL_PROPERTY_BODYPART_CONTENT_DESCRIPTION, 
(alp_postal_property_value_t)"MULTIPART", 0); 
alp_postal_bodypart_set_property(&multipart, 
ALP_POSTAL_PROPERTY_BODYPART_NAME, 
(alp_postal_property_value_t)"bodypart 2", 0); 
 
// Set properties for bodypart 3 
alp_postal_bodypart_set_property(&bp3, 
ALP_POSTAL_PROPERTY_BODYPART_NAME, 
(alp_postal_property_value_t)"bodypart 2-1", 0); 
 
// Set properties for bodypart 4 
alp_postal_bodypart_set_property(&bp4, 
ALP_POSTAL_PROPERTY_BODYPART_NAME, 
(alp_postal_property_value_t)"bodypart 2-2", 0); 
 
// Set properties for bodypart 5 
alp_postal_bodypart_set_property(&bp5, 
ALP_POSTAL_PROPERTY_BODYPART_NAME, 
(alp_postal_property_value_t)"bodypart 3", 0); 
 
// Append the bodyparts. Structure of the bodyparts tree is
// defined by the order in which "append" APIs are called. 
alp_postal_envelope_append_bodypart(&env, &bp1, 
ALP_POSTAL_BODYPART_NO_PARENT, &partNo); 
alp_postal_envelope_append_bodypart(&env, &multipart,
    ALP_POSTAL_BODYPART_NO_PARENT, &partNo); 
alp_postal_envelope_append_bodypart(&env, &bp3, partNo,
    &partNo2); 
alp_postal_envelope_append_bodypart(&env, &bp4, partNo,
    &partNo2); 
alp_postal_envelope_append_bodypart(&env, &bp5,
    ALP_POSTAL_BODYPART_NO_PARENT, &partNo); 

The following example shows how to build a simple envelope. In this example, the recipient is "+33689541258" and the message text is "Hello World".

Listing 2.6  Building a Simple Envelope


void build_sample_envelope(AlpPostalEnvelope* env) 
{ 
// Declare the recipient 
AlpPostalAddress recipient; 
// Declare the bodypart 
AlpPostalBodypart bp; 
alp_postal_bodypart_part_no_t partNo; 
// Initialize the envelope 
alp_postal_envelope_init(env); 
// Initialize the recipient address 
alp_postal_address_init(&recipient); 
// Initialize the bodypart 
alp_postal_bodypart_init(&bp); 
 
// Set properties for recipient 
alp_postal_address_set_property(&recipient, ALP_POSTAL_PROPERTY_ADDRESS_STRING, 
(alp_postal_property_value_t)"+33689541258", 0); 
 
// Add the recipient as "TO" on the envelope 
alp_postal_envelope_add_address(env, &recipient, 
ALP_POSTAL_ADDRESS_CLASS_RECIPIENT_TO); 
 
// Set properties for bodypart 
alp_postal_bodypart_set_property(&bp, 
ALP_POSTAL_PROPERTY_BODYPART_SMALL_CONTENT, (alp_postal_property_value_t)"Hello 
World", 0); 
 
// Add the bodypart to the envelope 
// Since this is a simple bodypart, the parent number is NO_PARENT. 
alp_postal_envelope_append_bodypart(env, &bp, ALP_POSTAL_BODYPART_NO_PARENT, 
&partNo); 
} 

Asynchronous Functions ^TOP^

When a client calls the asynchronous API, it has to give a function callback pointer, as shown in this example.

Listing 2.7  Asynchronous Request Callback


// Asynchronous request callback 
 
void send_envelope_async_reply_CB(alp_postal_service_id_t 
iServiceId, 
      alp_postal_session_id_t iSessiontId, 
      alp_postal_envelope_id_t iSentEnvelopeId, 
      AlpPostalProgressInfo* iProgressInfoP,  
      alp_status_t iRequestResult) 
{ 
    printf("Send envelope CB !!!!!"); 
    printf("iServiceId = %d", iServiceId); 
    printf("iSessiontId = %d", iSessiontId); 
    printf("iSentEnvelopeId = %d", iSentEnvelopeId); 
    printf("iRequestResult = %d", iRequestResult); 
} 
 
// Call the asynchronous request 
err = alp_postal_session_send_envelope(serviceId, session_id, 
&envelope, send_envelope_async_reply_CB); 

Notifications ^TOP^

Postal Services implement two notification mechanisms to allow client applications to be notified when an unsolicited events occurs. For example, a notification occurs when a new incoming envelope arrives. The first notification method is "internal" notification, a mechanism that can only be used when with clients of Postal Services. The second method is the Notification Manager mechanism, which relies on the ACCESS Linux Platform Notify Manager. This mechanism allows an application to be notified even when the application is not active.


NOTE: Both mechanisms deliver the same notification information.

In terms of performance, the "internal" notification mechanism is more efficient.

Internal Notifications ^TOP^

Each service defines some notifications. The client must associate a callback function with the notifications it wants to receive.

For example, to receive a NEW_ENVELOPE notification, the client must call the following function:


alp_postal_notification_add_observer (ALP_POSTAL_NOTIFICATION_ENVELOPE_NEW, 
void* callbackFuncP); 

When the client ends the process, it must call:


alp_postal_notification_remove_observer(ALP_POSTAL_NOTIFICATION_xxx); 

Listing 2.8  Handling Internal Account Status Change Notification


// Account status change notification callback 
static void MyAccountStatusChangeNotificationCB 
     (alp_postal_service_id_t iServiceId, 
      alp_postal_account_id_t iAccountId, 
      alp_postal_account_status_t iAccountStatus) 
 
{ 
printf("ALP_POSTAL_NOTICATION_ACCOUNT_STATUS_CHANGE 
(ServiceId = %lu, AccountId = %lu, AccountStatus = %lu)", 
iServiceId, iAccountId, iAccountStatus); 
} 
 
// Register against the internal Account status change 
notification 
err = alp_postal_notification_add_observer 
(ALP_POSTAL_NOTIFICATION_ACCOUNT_STATUS_CHANGE, 
MyAccountStatusChangeNotificationCB); 

Notification Manager Notifications ^TOP^

The postal Notification Manager notifications are defined in the file alp/postal_notify_mgr.h. The following sample code illustrates how to handle an account status change notification.

Listing 2.9  Handling an Account Status Change Notification


// Notification callback 
static void MyAccountStatusChangeNotificationCB 
       (alp_postal_service_id_t iServiceId, 
        alp_postal_account_id_t iAccountId,  
        alp_postal_account_status_t iAccountStatus) 
{ 
printf("ALP_NOTIFY_EVENT_POSTAL_ACCOUNT_STATUS_CHANGE 
(ServiceId = %lu, AccountId = %lu, AccountStatus = %lu)", 
oServiceId, oAccountId, oAccountStatus); 
} 
 
// Relaunch handler 
void my_relaunch_handler(int argc, char* argv[], gpointer 
cbData) 
{ 
        AlpNotifyLaunch    notifyLaunchParamDetails; 
        int                detailsSize; 
 
// Launched for a notification  
if (strcmp(argv[1], ALP_APP_NOTIFY) == 0) 
     { 
           detailsSize = alp_notify_details(argv[2], 
&notifyLaunchParamDetails); 
 
         // Check the notification  
              if (strcmp(argv[3], ALP_NOTIFY_LAUNCH_TYPE 
ALP_NOTIFY_EVENT_POSTAL_ACCOUNT_STATUS_CHANGE) == 0) 
		{ 
                   AlpNotifyEventAccountStatusChange* 
accountStatusChangeEventP; 
                   accountStatusChangeEventP = 
(AlpNotifyEventAccountStatusChange*)&(notifyLaunchParamDetail
s.details); 
			 
	// Invoke the callback 
      
MyAccountStatusChangeNotificationCB(accountStatusChangeEventP
->serviceId, accountStatusChangeEventP->accountId, 
accountStatusChangeEventP->accountStatus); 
	} 
 
       alp_notify_done(argv[0], 0 ,0); 
} 
 
int alp_main(int argc, char *argv[]) 
{ 
... 
// Set the relaunch handler 
err = alp_app_set_relaunch_handler(my_relaunch_handler, 
NULL); 
 
err = alp_notify_register_launch(argv[0], 
         ALP_NOTIFY_EVENT_POSTAL_ACCOUNT_STATUS_CHANGE, 
         ALP_NOTIFY_PRIORITY_NORMAL, 0); 
... 
} 

 

Add as favourites (233) | Quote this article on your site | Views: 2349

Be first to comment this article
RSS comments

Only registered users can write comments.
Please login or register.

Powered by AkoComment Tweaked Special Edition v.1.4.6
AkoComment © Copyright 2004 by Arthur Konze - www.mamboportal.com
All right reserved

 


© 2009 ACCESS Developer Network    |    Joomla! is Free Software released under the GNU/GPL License.    |    ACCESS Global Website
Events Support Community Platforms Home