Axeda Corp
/
AxedaGo-ubloxC027
Axeda demo software for u-blox C027 (GSM)
Diff: AMMP/axSerializer.c
- Revision:
- 0:a725e8eab383
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AMMP/axSerializer.c Mon Aug 11 19:02:42 2014 +0000 @@ -0,0 +1,374 @@ +/************************************************************************************/ +/* 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; +} + +