Axeda Ready Demo for Freescale FRDM-KL46Z as accident alert system

Dependencies:   FRDM_MMA8451Q KL46Z-USBHost MAG3110 SocketModem TSI mbed FATFileSystem

Fork of AxedaGo-Freescal_FRDM-KL46Z by Axeda Corp

AMMPC/axSerializer.c

Committer:
AxedaCorp
Date:
2014-07-02
Revision:
2:2f9019c5a9fc
Parent:
0:65004368569c

File content as of revision 2:2f9019c5a9fc:

/************************************************************************************/
/* 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;
}