Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
AMMP/axSerializer.c
- Committer:
- AxedaCorp
- Date:
- 2014-08-11
- Revision:
- 0:a725e8eab383
File content as of revision 0:a725e8eab383:
/************************************************************************************/
/* axSerializer.c */
/* �2013 Axeda Corporation */
/* */
/* Defines methods for transposing the data in domain objects into a serialized */
/* encoding for transmission to the Platform Endpoint. This is a platform independent*/
/* implementation that can be applied to any device that supports ANSI C. */
/* */
/************************************************************************************/
#include "axSerializer.h"
#define REG_ID 0
#define REG_MODEL_NUMBER 1
#define REG_SERIAL_NUMBER 2
#define REG_TENANT 3
#define REG_PING 4
#define REG_KEY 5
#define DATA_ALERTS 0
#define DATA_EVENTS 1
#define DATA_DATA 2
#define DATA_LOCATIONS 3
#define DATA_ITEMS 4
#define PKG_STATUS 0
#define PKG_ERROR 1
#define ALERT_SEV 0
#define ALERT_CAUSE 1
#define ALERT_REASON 2
#define COM_TIME 0
#define COM_PRIORITY 1
#define COM_NAME 2
#define COM_DESCRIPTION 3
//#define EVENT_NAME 1
//#define EVENT_DESC 0
#define LOC_LAT 0
#define LOC_LON 1
#define LOC_ALT 2
int terse_enable=AX_TRUE;
const char *commonKW[]= {"time", "priority", "name", "description" };
const char *dataKW[]={ "alerts", "events", "data", "locations", "dataItems"};
const char *registrationKW[]= {"id", "mn", "sn", "tn", "pingRate", "key"};
const char *alertKW[]= {"severity","cause", "reason" };
const char *locationKW[]= {"latitude", "longitude", "altitude"};
const char *pkgStatusKW[]={"status", "error"};
const char *terse_commonKW[]= {"t", "dp", "n", "d"};
const char *terse_dataKW[]={ "alerts", "events", "data", "locations", "di"};
const char *terse_registrationKW[]= {"id", "mn", "sn", "tn", "pr", "k"};
const char *terse_alertKW[]= {"sv", "cn", "cr" };
const char *terse_locationKW[]= {"lat", "lon", "alt"};
const char *terse_pkgStatusKW[]={"st", "err"};
/*************************************************************************************************/
/*dataSet2JSON() */
/* */
/*Takes an array of ax_dataItem structs and creates JSON to represent them in the AMMP-json */
/*protocol. The return type will be a CJSON pointer which can then be rendered into an actual */
/*JSON string. The JSON pointer will need to be free'd when you're done. If there are zero data */
/*items in the array then this method will return an empty JSON array pointer. */
/* */
/*NOTE: If any array spots are left empty they will only be ignored if theyre are NULL. Junk */
/* values from left over data will cause seg faults. NULL your empty pointers!!! */
/*************************************************************************************************/
//takes data item set, not longer just data item structs.
cJSON *dataSet2JSON(ax_dataSet *di[], int len, int terse_on)
{
cJSON *root, *child_obj, *dis=NULL;
int ctr=0;
ax_dataSet *curr=NULL;
ax_dataNode *currNode;
root=cJSON_CreateArray();
for(ctr=0; ctr<len; ctr++)
{
curr=di[ctr];
if((curr!=NULL)&&(curr->dataNode_ct>0)) //If this set doesn't have any data in it, don't include it.
{
cJSON_AddItemToArray(root, child_obj=cJSON_CreateObject());
if(terse_on==AX_TRUE) {
cJSON_AddItemToObject(child_obj, terse_dataKW[DATA_ITEMS], dis=cJSON_CreateObject()); }
else {
cJSON_AddItemToObject(child_obj, dataKW[DATA_ITEMS], dis=cJSON_CreateObject());
}
if((curr->acquisitionTime>=0)&&(curr->acquisitionTime)){
if(terse_on==AX_TRUE){
cJSON_AddNumberToObject(child_obj, terse_commonKW[COM_TIME], curr->acquisitionTime);
}
else {
cJSON_AddNumberToObject(child_obj, commonKW[COM_TIME], curr->acquisitionTime);
}
}
if((curr->priority>=1)&&(curr->priority<=100)) {
if(terse_on==AX_TRUE){
cJSON_AddNumberToObject(child_obj, terse_commonKW[COM_PRIORITY], curr->priority);
}
else {
cJSON_AddNumberToObject(child_obj, commonKW[COM_PRIORITY], curr->priority);
}
}
currNode=curr->data_first;
while(currNode!=NULL)
{
if(currNode->type==AX_DIGITAL) {
if(currNode->dValue==1) {
cJSON_AddTrueToObject(dis, currNode->name);
}
else {
cJSON_AddFalseToObject(dis, currNode->name);
}
}
else if(currNode->type==AX_ANALOG) {
cJSON_AddNumberToObject(dis, currNode->name, currNode->dValue);
}
else {
cJSON_AddStringToObject(dis, currNode->name, currNode->sValue);
}
//advance to the next data item
currNode=currNode->next;
}
}
}
return root;
}
/*************************************************************************************************/
/* eventsToJSON() */
/* */
/*Takes an array of ax_event struct pointers and creates JSON to represent them in the AMMP-json */
/*protocol. The return type will be a CJSON pointer which can then be rendered into an actual */
/*JSON string. The JSON pointer will need to be free'd when you're done. If there are zero data */
/*items in the array then this method will return an empty JSON array pointer. */
/* */
/*NOTE: If any array spots are left empty they will only be ignored if theyre are NULL. Junk */
/* values from left over data will cause seg faults. NULL your empty pointers!!! */
/*************************************************************************************************/
cJSON *eventsToJSON(ax_event *events[], int len, int terse_on) {
cJSON *root, *dis;
ax_event *curr;
int ctr=0;
root=cJSON_CreateArray();
curr=events[0];
for(ctr=0; ctr<len; ctr++)
{
curr=events[ctr];
if(curr!=NULL)
{
cJSON_AddItemToArray(root, dis=cJSON_CreateObject());
if(terse_on==AX_TRUE){
cJSON_AddStringToObject(dis, terse_commonKW[COM_NAME], curr->name);
cJSON_AddStringToObject(dis, terse_commonKW[COM_DESCRIPTION], curr->description);
}
else {
cJSON_AddStringToObject(dis, commonKW[COM_NAME], curr->name);
cJSON_AddStringToObject(dis, commonKW[COM_DESCRIPTION], curr->description);
}
if((curr->dateAcquired>=0)&&(curr->dateAcquired)){
if(terse_on==AX_TRUE){
cJSON_AddNumberToObject(dis, terse_commonKW[COM_TIME], curr->dateAcquired);
}
else {
cJSON_AddNumberToObject(dis, commonKW[COM_TIME], curr->dateAcquired);
}
}
if((curr->priority>=1)&&(curr->priority<=100)&&(curr->priority)) {
if(terse_on==AX_TRUE){
cJSON_AddNumberToObject(dis, terse_commonKW[COM_PRIORITY], curr->priority);
}
else {
cJSON_AddNumberToObject(dis, commonKW[COM_PRIORITY], curr->priority);
}
}
}
}
return root;
}
/*************************************************************************************************/
/* locationsToJSON() */
/* */
/*Takes an array of ax_location struct pointers and creates JSON to represent them in the AMMP */
/*protocol. The return type will be a CJSON pointer which can then be rendered into an actual */
/*JSON string. The JSON pointer will need to be free'd when you're done. If there are zero data */
/*items in the array then this method will return an empty JSON array pointer. */
/* */
/*NOTE: If any array spots are left empty they will only be ignored if theyre are NULL. Junk */
/* values from left over data will cause seg faults. NULL your empty pointers!!! */
/*************************************************************************************************/
cJSON *locationsToJSON(ax_location *locations[], int len, int terse_on) {
cJSON *root, *dis;
ax_location *curr;
int ctr=0;
root=cJSON_CreateArray();
for(ctr=0; ctr<len; ctr++)
{
curr=locations[ctr];
if(curr)
{
cJSON_AddItemToArray(root, dis=cJSON_CreateObject());
if(terse_on==AX_TRUE){
cJSON_AddNumberToObject(dis, terse_locationKW[LOC_LAT], curr->latitude);
cJSON_AddNumberToObject(dis, terse_locationKW[LOC_LON], curr->longitude);
cJSON_AddNumberToObject(dis, terse_locationKW[LOC_ALT], curr->altitude);
}
else {
cJSON_AddNumberToObject(dis, locationKW[LOC_LAT], curr->latitude);
cJSON_AddNumberToObject(dis, locationKW[LOC_LON], curr->longitude);
cJSON_AddNumberToObject(dis, locationKW[LOC_ALT], curr->altitude);
}
if((curr->dateAcquired)&&(curr->dateAcquired>=0)){
if(terse_on==AX_TRUE){
cJSON_AddNumberToObject(dis, terse_commonKW[COM_TIME], curr->dateAcquired);
}
else {
cJSON_AddNumberToObject(dis, commonKW[COM_TIME], curr->dateAcquired);
}
}
if((curr->priority>=1)&&(curr->priority<=100)&&(curr->priority)) {
if(terse_on==AX_TRUE){
cJSON_AddNumberToObject(dis, terse_commonKW[COM_PRIORITY], curr->priority);
}
else {
cJSON_AddNumberToObject(dis, commonKW[COM_PRIORITY], curr->priority);
}
}
}
}
return root;
}
/*************************************************************************************************/
/* alarmsToJSON() */
/* */
/*Takes an array of ax_alarm struct pointers and creates JSON to represent them in the AMMP-json */
/*protocol. The return type will be a CJSON pointer which can then be rendered into an actual */
/*JSON string. The JSON pointer will need to be free'd when you're done. If there are zero data */
/*items in the array then this method will return an empty JSON array pointer. */
/* */
/*NOTE: If any array spots are left empty they will only be ignored if theyre are NULL. Junk */
/* values from left over data will cause seg faults. NULL your empty pointers!!! */
/*************************************************************************************************/
cJSON *AlarmsToJSON(ax_alarm *alarms[], int len, int terse_on)
{
cJSON *root, *dis;
int ctr=0;
ax_alarm *curr;
root=cJSON_CreateArray();
curr=alarms[0];
for(ctr=0; ctr<len; ctr++) {
curr=alarms[ctr];
if(curr!=NULL)
{
cJSON_AddItemToArray(root, dis=cJSON_CreateObject());
if(terse_on==AX_TRUE){
cJSON_AddStringToObject(dis, terse_commonKW[COM_NAME], curr->alarmName);
cJSON_AddStringToObject(dis, terse_commonKW[COM_DESCRIPTION], curr->alarmDescription);
cJSON_AddNumberToObject(dis, terse_alertKW[ALERT_SEV], curr->alarmSeverity);
cJSON_AddStringToObject(dis, terse_alertKW[ALERT_CAUSE], curr->alarmCause);
cJSON_AddStringToObject(dis, terse_alertKW[ALERT_REASON], curr->alarmReason);
}
else {
cJSON_AddStringToObject(dis, commonKW[COM_NAME], curr->alarmName);
cJSON_AddStringToObject(dis, commonKW[COM_DESCRIPTION], curr->alarmDescription);
cJSON_AddNumberToObject(dis, alertKW[ALERT_SEV], curr->alarmSeverity);
cJSON_AddStringToObject(dis, alertKW[ALERT_CAUSE], curr->alarmCause);
cJSON_AddStringToObject(dis, alertKW[ALERT_REASON], curr->alarmReason);
}
if((curr->dateAcquired)&&(curr->dateAcquired>=0)){
if(terse_on==AX_TRUE){
cJSON_AddNumberToObject(dis, terse_commonKW[COM_TIME], curr->dateAcquired);
}
else {
cJSON_AddNumberToObject(dis, commonKW[COM_TIME], curr->dateAcquired);
}
}
if((curr->priority>=1)&&(curr->priority<=100)&&(curr->priority)) {
if(terse_on==AX_TRUE){
cJSON_AddNumberToObject(dis, terse_commonKW[COM_PRIORITY], curr->priority);
}
else {
cJSON_AddNumberToObject(dis, commonKW[COM_PRIORITY], curr->priority);
}
}
}
}
return root;
}
/*************************************************************************************************/
/* getRegistrationJSON() */
/* */
/*Takes a device and ping rate and will return a cJSON structure that represents a registration */
/*message in the AMMP protocol. */
/* */
/*************************************************************************************************/
cJSON *getRegistrationJSON(ax_deviceID *device, int pingRate)
{
cJSON *root, *child;
root=cJSON_CreateObject();
cJSON_AddItemToObject(root, registrationKW[REG_ID], child=cJSON_CreateObject());
if(device->model) {
cJSON_AddStringToObject(child, registrationKW[REG_MODEL_NUMBER], device->model);
}
if(device->serial) {
cJSON_AddStringToObject(child, registrationKW[REG_SERIAL_NUMBER], device->serial);
}
if(strlen(device->tenant)>=1)
{
cJSON_AddStringToObject(child, registrationKW[REG_TENANT], device->tenant);
}
cJSON_AddNumberToObject(root, registrationKW[REG_PING], pingRate);
return root;
}
//TODO: Fill out this description
/*************************************************************************************************/
/*getPKGStatusJSON() */
/* */
/* */
/* */
/*************************************************************************************************/
cJSON *getPKGStatusJSON(int status, char *error, int priority, int time, int terse_on){
cJSON *root;
root=cJSON_CreateObject();
//STATUS
if(terse_on==AX_TRUE) {
cJSON_AddNumberToObject(root, pkgStatusKW[PKG_STATUS], status);
}
else {
cJSON_AddNumberToObject(root, pkgStatusKW[PKG_STATUS], status);
}
//TIME
if(time>=0) {
if(terse_on==AX_TRUE) {
cJSON_AddNumberToObject(root, terse_commonKW[COM_TIME], time);
}
else {
cJSON_AddNumberToObject(root, commonKW[COM_TIME], time);
}
}
//PRIORITY
if((priority>0)&&(priority<=100)) {
if(terse_on==AX_TRUE) {
cJSON_AddNumberToObject(root, terse_commonKW[COM_PRIORITY], priority);
}
else {
cJSON_AddNumberToObject(root, commonKW[COM_PRIORITY], priority);
}
}
//ERROR
if(error!=NULL) {
if(terse_on==AX_TRUE) {
cJSON_AddStringToObject(root, terse_pkgStatusKW[PKG_ERROR], error);
}
else {
cJSON_AddStringToObject(root, pkgStatusKW[PKG_ERROR], error);
}
}
return root;
}