Websites Navigation: Airbit | Shop | m-shell.net
Languages: EN | DE

Alarm Server Example

The concepts of this chapter are illustrated by developing a module accessing the Symbian "alarm server". The client API to this server is the Symbian class RASCliSession. AlarmModule.cpp contains the complete source of the module and is also part of the NMI SDK.

We call our module alarm. And again, after studying the services offered by the alarm server API, we specify it:

  1. Alarms are identified by integers (TAlarmId is a TInt).
  2. The module alarm should provide the following functions:
    • alarm.add(msg,due,sound=null)→Number adds an alarm with message, due time and optional sound file and returns the id of the new alarm.
    • alarm.all()→Array returns the ids of all known alarms.
    • alarm.delete(id)→null deletes the alarm with the given id.
    • alarm.get(id)→null returns some data about the alarm with the given id, as an array with the following members:

      KeyContents
      msgThe message text of the alarm.
      dueThe next due time of the alarm.
      soundThe sound file played when the alarm expires.
      enabledWhether the alarm is enabled.
    • alarm.on(id, enabled)→null enables or disables an alarm.
    • alarm.wait(timeout=-1)→Number waits up to timeout milliseconds for the next alarm to expire and returns its id. If timeout is negative, it is ignored.
  3. The module should respect the permissions granted by the user: ReadApp for all alarm functions, WriteApp for the functions modifying alarm data.
From this spec, we can directly write the skeleton of our module:

#include "NativeModule.h"
#include <asclisession.h>
#include <asshdalarm.h>

class AlarmModule : public NativeModule {
private:
  enum Functions {
    AddFunction, AllFunction, DeleteFunction, GetFunction, OnFunction,
    WaitFunction
  };

  RASCliSession session;
  TASShdAlarm alarm;

  // destroying the module should close the session
  ~AlarmModule() {
    session.Close();
  }

Functions are added in the second phase constructor:

void ConstructL() {
  // the functions this module supports
  runtime->AddNativeFunctionL(_L("add"), 2, 3, AddFunction);
  runtime->AddNativeFunctionL(_L("all"), 0, 0, AllFunction);
  runtime->AddNativeFunctionL(_L("delete"), 1, 1, DeleteFunction);
  runtime->AddNativeFunctionL(_L("get"), 1, 1, GetFunction);
  runtime->AddNativeFunctionL(_L("on"), 2, 2, OnFunction);
  runtime->AddNativeFunctionL(_L("wait"), 0, 1, WaitFunction);
}

Again, the functions themselves are called via ExecuteL():

Runtime::Value ExecuteL(TInt index, Runtime::Value *params,
                        TInt paramCount, TRequestStatus &status)
{
  // if the session is not connected, connect it
  if (session.Handle() == 0) User::LeaveIfError(session.Connect());
  // a variable which will contain the function result
  Runtime::Value result;
  result.SetNull(); // default for functions returning null  
  switch (index) 
  case AddFunction:
    alarm.Reset();
    // copy with truncation to avoid a panic
    alarm.Message().Copy
      (params[0].GetPtrCL().Left(KMaxAlarmMessageLength));
    alarm.NextDueTime() = params[1].GetTimeL();
    if (paramCount > 2 && !params[2].IsNull())
      alarm.SoundName().Copy
        (params[2].GetPtrCL().Left(KMaxAlarmSoundNameLength));
    User::LeaveIfError(session.AlarmAdd(alarm));
    result.SetNumber(alarm.Id());
    break;
  case AllFunction:
    ...
  
  return result;
}

Two details are worth mentioning: first, TASShdAlarm::Message() and TASShdAlarm::SoundName() return references to fixed size buffers. To avoid a panic when copying longer strings, we truncate them before copying. Second, Runtime::Value::GetTimeL() converts an m Number into a TTime value.

The implementation of the other functions is straightforward Symbian C++ programming, except for alarm.wait, which is asynchronous and presented in section * ().

The exported entry points are:

EXPORT_C NativeModule* NewAlarmModuleL() {
  return new(ELeave) AlarmModule;
}

#ifndef EKA2
GLDEF_C TInt E32Dll(TDllReason) { return KErrNone; }
#endif


© 2004-2011 airbit AG, CH-8008 Zürich
Document AB-M-NMI-887
mShell Home  > Documentation  > Manuals