PMR APIs
PMR API Services
This page defines two new services provided by the LMU application running on the CalAmp LMU Linux-based product. The PMR (PEG message routing) APIs provide the following services:
- PEG synchronization service: Enables a Linux application to initiate PEG triggers into the LMU app PEG script and receive signaling notifications from it.
- Messaging service: Enables a Linux process to send and receive data to/from the LMDirect inbound server (the customer server) via LMDirect user messages.
The calamp_pmr_test example demonstrates how to receive a trigger and PEG action notification and send and receive user messages.
The calamp_updchk_test example demonstrates the PEG synchronization interface.
Background
The LMU-5530/5541 is a Linux platform composed of several application processes. One of the processes is the CalAmp LMU app that is responsible for location and messaging services using PEG and LMDirect.
The services defined in this document meet these two requirements:
- Other processes running on the Linux platform are able to access the PEG and messaging services within the LMU app. It is possible to synchronize events with the programmable event generator (PEG).
- Similarly, processes running alongside the LMU app are able to send and receive data to the LMU inbound server (typically the customer’s server) using the LMDirect user message format. This format limits the data payload to 848 bytes in each direction.
Architecture
Communication between the LMU app and other processes wanting to access the messaging and PEG synchronization services is implemented using the Linux System V message queue methods and shared memory.
For messaging services, the LMU app supports a single message queue (called the SndMsg queue), through which an external process can register itself with the LMU application and pass user message traffic into the LMU for forwarding to the LMU inbound server. When the external process sends a registration notification to the LMU app through the SndMsg queue, the buffer contains the external process’s queue ID for receiving LMDirect user message responses (called the RcvMsg queue). The external process’s RcvMsg queue must be created as a shared system resource so that the LMU app can pass the user messages received from the inbound server.
When a Linux application starts, the following needs to be created:
- A Linux System V message queue
- An LMDirect user message routing number
The 1-byte routing number is included in the LMDirect user message. It is used by the LMU app to direct user messages received from a server to the proper external process and therefore must be unique within the LMU app. It is also used by the server to distinguish between user messages generated by each external process. The Route field is an unsigned byte having a range between 100 and 150. It is the Linux application’s responsibility to manage its routing assignment to its external processes because one process can own only one route.
For PEG synchronization services, the LMU app supports a single message queue (call the PegTrig queue). Through this queue, any external process can pass a PEG synchronization notice to the LMU app PEG script using the PEG trigger mechanism built into the LMU app. The same PegTrig queue is used by the external process to register itself for PEG-initiated notifications; within the PEG registration buffer is the external process’s PegAct queueid. This queue is used to notify the external process that the PEG script has executed a specific PEG action with a parameter. The parameter itself is posted to every PegAct queue so that each registered process will receive a copy.
To create the same Linux message queues and shared memory region, it is important to use the same Linux ftok attributes. A new /home directory will be created where the following are stored.
LMU-5541/5530 ftok Definitions
/etc/calamp/lmu directory shall contain the following text ascii files:
pmr_pegTrig ( ftok file for pegTrig queue )
pmr_sndMsg ( ftok file for sndMsg queue )
pmr_shm ( ftok file for peg/msg shared memory region )
Note
The Linux file system is defined by NAND flash definitions. The file system directories and files are statically defined by CalAmp’s LMU build, release, and upgrade procedures. These directories and files are never deleted unless the PULS server upgrades the LMU device.
For LMU application status information, a Linux shared memory region pmrShm is created. The external Linux applications have only read access so that the registration information can be validated. The following information is stored:
LMU-5541/5530 ftok Definitions
#define PMR_SHM_MEMORY_FTOK_PATH ("/etc/calamp/lmu/pmr_shm")
typedef struct
{
int32 inuse_flag; /* 0=not registered, 1=registered */
int32 index; /* shared memory indece of registered peg client */
int32 rxq_id; /* external process’s Linux message queue id */
}PMR_PEG_REGISTER_STATUS;
#define PMR_PEG_MAX_CLIENTS ( 200 )
typedef struct
{
int32 inuse_flag; /* 0= not registered, 1= registered */
int32 index; /* shared memory indices of registered lmdirect client */
int32 lmdirect_route; /* lmdirect route is only 8 bits long, shared memory is word aligned */
int32 lmdirect_type; /* lmdirect type is only 8 bits longs, shared memory is word aligned */
int32 rxq_id;
}PMR_UMSG_REGISTER_STATUS;
#define PMR_UMSG_MAX_CLIENTS ( 50 )
typedef struct
{
int32 pegTrigQid;
int32 sndMsgQid;
int32 ttl_peg_clients_registered;
int32 pmr_last_peg_cmd;
int32 ttl_umsg_clients_registered;
int32 pmr_last_umsg_cmd;
PMR_PEG_REGISTER_STATUS pegInfo[PMR_MAX_PEG_CLIENTS];
PMR_UMSG_REGISTER_STATUS umsgInfo[PMR_MAX_UMSG_CLIENTS];
}PMR_SHARED_MEM;
Note
Shared memory is destroyed when the LMU application does an orderly shutdown and all external applications have detached from this shared memory region.
External Linux Application Restart Condition Overview
Because Linux message queues are NOT destroyed when an application terminates or restarts, if an external Linux application restarts, it must first read the CalAmp LMU’s shared memory region to verify that registration has occurred with the application’s PEG action queue or UMSG (user message) response queue.
It is the responsibility of the external Linux application to reattach with its previously created Linux PEG or UMSG queue to receive LMU PEG synchronization actions or user message responses.
LMU Application Restart Condition Overview
If the CalAmp LMU restarts, it will zero out its PMR shared memory region, and all previously stored registrations will be destroyed.
It is the responsibility of any external application expecting PEG synchronization actions and/or LMDirect user message responses to periodically read the CalAmp LMU’s PMR shared memory for status updates. If the shared memory has been cleared, the external application should reregister with the CalAmp LMU application.
Note
Whenever a Linux application terminates, it should deregister from the LMU app so that responses are not queued in the PegAct or RcvMsg queues. If the Linux application restarts and didn’t deregister previously, it should reuse the previously created Linux message queue so that it can continue to receive PEG notifications and/or LMDirect user message responses.
Interface Definitions
Command and Control Definitions
The messages passed between an external Linux application and the LMU-5530 CalAmp application are listed in this table:
Direction | Structure | Description | Message Queue Type | Command Type |
---|---|---|---|---|
To the LMU app | PMR_CMD_PEG_REG | Registration | 1 | 1 |
To the LMU app | PMR_CMD_UMSG_REG | Registration | 1 | 2 |
To the LMU app | PMR_CMD_PEG_DEREG | Deregistration | 1 | 3 |
To the LMU app | PMR_CMD_UMSG_DEREG | Deregistration | 1 | 4 |
To the LMU app | PMR_CMD_PEG_TRIGGER | Trigger | 1 | 5 |
From the LMU app | PMR_CMD_PEG_TRIGGER | PEG action | 2 | 5 |
To the LMU app | PMR_CMD_UMSG | Sends a user message | 1 | 6 |
From the LMU app | PMR_CMD_UMSG | Receives an LMDirect user message response | 2 | 6 |
To the LMU app | PMR_CMD_RESET | Resets PEG or LMDirect registration tables | 1 | 7 |
To the LMU app | PMR_CMD_USER_REQUEST | Sends application-specific PEG triggers (such as UpdateCheck, UpdateLock, or UpdateUnlock) | 1 | 8 |
From the LMU app | PMR_CMD_SEND_TZ | Sends time zone update information to the registered PEG clients | 2 | 9 |
PMR_RESET_CMD is a provisional feature that is primarily used for development testing. Because the external applications might be restarting several times during debug tests and can become out of sync with the LMU application, it is the external applications' responsibility to deregister with the LMU application prior to shutdown. This command queued to the LMU’s PegTrig queue/SndMsg queue will reset all the registration entries in the PEG/LMDirect registration table.
The message queue type and command type in the above table refers to the following definitions:
#define PMR_MIN_MSG_TYPE ( 1 )
#define PMR_MAX_MSG_TYPE ( 2 )
#define PMR_ROUTER_MSG_TYPE ( PMR_MIN_MSG_TYPE ) // LMU app msgtype
#define PMR_LINUX_APP_MSG_TYPE ( PMR_MAX_MSG_TYPE ) // external Linux app
typedef enum
{
PMR_NO_COMMAND = 0,
PMR_CMD_PEG_REG, /* 1 = PEG notification registration */
PMR_CMD_UMSG_REG, /* 2 = LMDIRECT User Message Response Registration */
PMR_CMD_PEG_DEREG, /* 3 = PEG Notification deregistration */
PMR_CMD_UMSG_DEREG, /* 4 = LMDIRECT User Message Deregistration */
PMR_CMD_PEG_TRIGGER, /* 5 = PEG trigger or action */
PMR_CMD_UMSG, /* 6 = LMDIRECT User Message */
PMR_CMD_RESET, /* 7 = registration reset */
PMR_CMD_USER_REQUEST, /* 8 = user request */
PMR_CMD_SEND_TZ, /* 9 = sends time zone info to the user */
PMR_CMD_MAX /* last command */
} PMR_CLIENT_CMDS;
For example, when a Linux application wants to receive PEG sync notifications, it enqueues a PMR_PEG_REG_CMD on the LMU App’s PegTrig queue.
Similarly, if Linux application desires to receive LMDirect User Message responses enqueues PMR_UMSG_REG_CMD on the LMU App’s SndMsg queue.
PEG Registration
The structure of the LMU app PEG registration command buffer is defined as follows:
typedef struct
{
int32 msgq_type; /* pmr message type = 1 */
int32 pmr_cmd; /* 1= peg_register */
int32 rxqid; /* user application PegAct queueid */
}PMR_CLIENT_PEG_CMD;
When an external Linux application wants to be notified of any PEG action, a PMR_CMD_PEG_REG
must be queued to the CalAmp LMU PegTrig queue. The application’s qid must be unique; if the qid has already been registered, the CalAmp LMU will discard the request.
When the CalAmp LMU receives any PEG action (200-250), it will enqueue PMR_CMD_PEG_TRIGGER
to all registered applications’ rxq_id.
PEG Deregistration
The structure of the LMU app PEG registration command buffer is defined as follows:
typedef struct
{
int32 msgq_type; /* pmr message type = 1 */
int32 pmr_cmd; /* 1= peg_register */
int32 rxqid; /* user application PegAct queueid */
}PMR_CLIENT_PEG_CMD;
When an external Linux application no longer wants any PEG action notifications, a PMR_PEG_DEREG_CMD must be queued to the CalAmp LMU PegTrig queue.
UMSG Registration
The structure of the LMU app UMSG registration command buffer is defined as follows:
typedef struct
{
int msgq_type; /* type = 1 for calamp_lmu processing */
int pmr_cmd; /* PMR_CMD_UMSG_REG or PMR_CMD_UMSG_DEREG */
int route_id; /* route must be between 100 and 150 */
int type_id; /* type must be between 0 and 255 */
int rxqid; /* external application's linux message qid */
} PMR_UMSG_CMD;
When an external Linux application wants to be notified of any outbound LMDirect user message response, a PMR_CMD_UMSG_REG must be queued to the CalAmp LMU SndMsg queue. The Linux application’s qid must be unique; if the qid has already been registered, the CalAmp LMU will discard the request. Only one external application can be registered for an LMDirect user message route. If the route has already been registered, the CalAmp LMU will discard the duplicate registration request.
When the CalAmp LMU receives an outbound LMDirect user message matching the registered route, it will enqueue the PMR_CMD_UMSG notification to the registered application’s ext_qid.
UMSG Deregistration
typedef struct
{
int msgq_type; /* type = 1 for calamp_lmu processing */
int pmr_cmd; /* PMR_CMD_UMSG_REG or PMR_CMD_UMSG_DEREG */
int route_id; /* route must be between 100 and 150 */
int type_id; /* type must be between 0 and 255 */
int rxqid; /* external application's linux message qid */
} PMR_UMSG_CMD;
When an external Linux application no longer wants any outbound LMDirect user message matching the previously registered route, a PMR_UMSG_DEREG_CMD must be queued to the CalAmp LMU SndMsg queue.
PMR Reset
typedef struct
{
int msgq_type; /* pmr message type = 1 */
int pmr_cmd; /* 7 = reset PEG or LMDirect registration tables */
} PMR_RESET_CMD;
PMR_RESET_CMD is a provisional feature primarily used for development testing. Because the external applications might be restarting several times during debug tests and can become out of sync with the LMU application, it is the responsibility of external applications to deregister with the LMU application prior to shutdown. When this command is queued to the LMU’s PegTrig queue, the LMU app will reset all the registration entries in the PEG registration table, and if queued to the LMU’s SndMsg queue, the LMU app will reset all the registration entries in the LMDirect registration table.
PEG Synchronization Interface Definitions
For PEG synchronization services, the LMU app supports a single PegTrig queue, through which any external process can pass a PEG synchronization notice to the LMU app PEG script using the PEG trigger mechanism built into the LMU app. When a PEG trigger notification has been received by the LMU app through this queue, the LMU app will initiate a special PEG trigger (#41) to the PEG script with a modifier equal to trig_mod in PRM_PEG_REQ. Trigger modifier values from 200 through 250 are permitted.
An external process initiates this process-to-script synchronization by posting a PMR_CMD_PEG_TRIGGER or PMR_CMD_USER_REQUEST message to the LMU app’s PegTrig queue. The PMR_PEG_REQ structure is defined as follows:
typedef struct
{
int msgq_type; /* type = 1 for calamp_lmu processing */
int pmr_cmd; /* PMR_CMD_PEG_TRIGGER */
int trigger_mod; /* trigger must be between 200 and 250 */
} PMR_CLIENT_PEG_TRIGGER;
When the CalAmp LMU decodes the PMR_PEG_REQ and finds that the trigger code is not within bounds, the request will be discarded.
When the PEG script initiates a send-special PEG action (#41), if the action modifier is in the 200-250 range, the LMU app will post a notification to ALL registered external processes using PMR_CMD_PEG_TRIGGER and including the modifier value in the action_mod field. PMR_PEG_ACTION will be queued to all registered queues when the PEG action has completed.
typedef struct
{
int msgq_type; /* PMR_LINUX_APP_MSG_TYPE */
int pmr_cmd; /* 5= PMR_CMD_PEG_TRIGGER */
int action_mod; /* min = 200, max = 250 */
struct cmm_tofs tofs; /* time zone update*/
} PMR_PEG_ACTION;
PEG Trigger for User Request Message
When the pmr_cmd in the PMR_CLIENT_PEG_TRIGGER is set to 8, PMR_CMD_USER_REQUEST, as shown below, the action_mod field should be populated with a supported PMR user request action.
typedef struct
{
int msgq_type; /* type = 1 for calamp_lmu processing */
int pmr_cmd; /* PMR_CMD_PEG_TRIGGER */
int trigger_mod; /* trigger must be between 200 and 250 */
} PMR_CLIENT_PEG_TRIGGER;
Supported PMR user request actions include the following:
User Request Action | Description | Return Status |
---|---|---|
PMR_PEG_UREQ_UPDCHK | Checks whether it is okay for the third-party application to start a package update | 0: Okay for the third-party application to proceed with the package update 1: Voltage is low, so the update cannot be run 2: The LMU is currently downloading 3: The LMU OTA firmware update is in progress 4: The LMU OTA config update is in progress 5: The LMU VBUS firmware OTA is in progress |
PMR_PEG_UREQ_UPDLCK | Locks to prevent the LMU from starting any update and prevents the LMU from sleeping | 0: Lock successful 1: Lock unsuccessful |
PMR_PEG_UREQ_UPDUNLCK | Unlocks the LMU starting any update and unlocks LMU sleeping | 0: Unlock successful 1: Unlock unsuccessful |
User Messaging Interface Definitions
Any Linux application can send inbound LMDirect user messages. The payload data will be sent to the inbound channel for transmission. The PMR_CMD_UMSG will be queued to the LMU app SndMsg queue.
typedef struct
{
int msgq_type; /* PMR message type = 1 */
int pmr_cmd /* 6 = LMDirect user message */
int route; /* lmdirect route field ( 100-150 ) */
int type; /* lmdirect type field ( 0-255 ) */
int payload_len; /* payload len of data */
unsigned char payload[848]; /* user message request */
}PMR_UMSG_REQUEST;
The fields in the example below are verified when the CalAmp LMU receives a PMR_UMSG_REQUEST from its SndMsg queue. If the payload length exceeds 848, the buffer will be discarded. If the route is not within the bounds of 100-150 or the type not between 0 and 255, the request will be discarded.
When the LMU app module receives the PMR_UMSG_REQUEST buffer and processes the request with no errors, the payload will be encapsulated in an LMDirect user message and placed in the LMU app’s persistent store-and-forward log for transmission.
When the LMU app receives an outbound LMDirect user message with a matching Linux application’s route field, the payload of the user message will be queued to the appropriate registered application’s queue with the following buffer structure:
typedef struct
{
int msgq_type; /* Linux application message type = 2 */
int pmr_cmd /* 6 = lmdirect user message */
int route; /* lmdirect user message routeid ( 100-150 ) */
int type; /* lmdirect user message typeid ( 0-255) */
int payload_len; /* payload len of user message response data */
unsigned char payload[848]; /* user message response data */
} PMR_UMSG_RESPONSE;
Updated almost 3 years ago