![](/media/cache/profiles/dcee66ccb49a492ae42c446c0cc01b3a.jpg.50x50_q85.jpg)
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
AMMPC/axPlatform.c@2:2f9019c5a9fc, 2014-07-02 (annotated)
- Committer:
- AxedaCorp
- Date:
- Wed Jul 02 19:57:37 2014 +0000
- Revision:
- 2:2f9019c5a9fc
- Parent:
- 0:65004368569c
ip switch
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AxedaCorp | 0:65004368569c | 1 | /************************************************************************************/ |
AxedaCorp | 0:65004368569c | 2 | /* axPlatform.c */ |
AxedaCorp | 0:65004368569c | 3 | /* 2013 Axeda Corporation */ |
AxedaCorp | 0:65004368569c | 4 | /* */ |
AxedaCorp | 0:65004368569c | 5 | /* Defines methods for interaction with end points on the Axeda Platform. This */ |
AxedaCorp | 0:65004368569c | 6 | /* is a device independent implementation which can be applied to any device that */ |
AxedaCorp | 0:65004368569c | 7 | /* supports ANSI C. */ |
AxedaCorp | 0:65004368569c | 8 | /************************************************************************************/ |
AxedaCorp | 0:65004368569c | 9 | |
AxedaCorp | 0:65004368569c | 10 | #include "axPlatform.h" |
AxedaCorp | 0:65004368569c | 11 | #include "axStatusCodes.h" |
AxedaCorp | 0:65004368569c | 12 | #include <string.h> |
AxedaCorp | 0:65004368569c | 13 | #include <stdlib.h> |
AxedaCorp | 0:65004368569c | 14 | #include "axTransport.h" |
AxedaCorp | 0:65004368569c | 15 | #include "axSerializer.h" |
AxedaCorp | 0:65004368569c | 16 | #include "cJSON.h" |
AxedaCorp | 0:65004368569c | 17 | #include "axConstants.h" |
AxedaCorp | 0:65004368569c | 18 | #include "axHTTP.h" |
AxedaCorp | 0:65004368569c | 19 | |
AxedaCorp | 0:65004368569c | 20 | int handleResponse(HTTP_Transmission *response); |
AxedaCorp | 0:65004368569c | 21 | |
AxedaCorp | 0:65004368569c | 22 | static const char *endpoints[8]= { "ammp", "data", "assets", "files", " ", "packages", "status", " "}; |
AxedaCorp | 0:65004368569c | 23 | static const char *contentTypes[]= { "application/json", "multipart/form-data"}; |
AxedaCorp | 0:65004368569c | 24 | static const char *buffer_keywords[]= {"alarms", "events", "data", "locations" }; |
AxedaCorp | 0:65004368569c | 25 | |
AxedaCorp | 0:65004368569c | 26 | const char URL_SEP='/'; |
AxedaCorp | 0:65004368569c | 27 | const char ID_SEP='!'; |
AxedaCorp | 0:65004368569c | 28 | |
AxedaCorp | 0:65004368569c | 29 | /************************************************************************************/ |
AxedaCorp | 0:65004368569c | 30 | /*ax_platform_upload() */ |
AxedaCorp | 0:65004368569c | 31 | /* */ |
AxedaCorp | 0:65004368569c | 32 | /*file(required) : a pointer to a structure that the data will be stored in. */ |
AxedaCorp | 0:65004368569c | 33 | /*name (required): a file name for the file. Can be arbitrarily assigned based on */ |
AxedaCorp | 0:65004368569c | 34 | /* source of the data. */ |
AxedaCorp | 0:65004368569c | 35 | /*hint(required): a string that allows you to tag the file for later retrieval */ |
AxedaCorp | 0:65004368569c | 36 | /*size(optional): should be populated if the data does not have an EOF character at */ |
AxedaCorp | 0:65004368569c | 37 | /* the end. If sending a memory block this will define the offset. */ |
AxedaCorp | 0:65004368569c | 38 | /*data(required): a pointer to the data that will be sent as this file */ |
AxedaCorp | 0:65004368569c | 39 | /* */ |
AxedaCorp | 0:65004368569c | 40 | /* */ |
AxedaCorp | 0:65004368569c | 41 | /************************************************************************************/ |
AxedaCorp | 0:65004368569c | 42 | int ax_platform_upload(ax_platform *cloud, ax_deviceID *device, ax_file *file) |
AxedaCorp | 0:65004368569c | 43 | { |
AxedaCorp | 0:65004368569c | 44 | int retVal=AX_UNKNOWN; |
AxedaCorp | 0:65004368569c | 45 | char *url=NULL; |
AxedaCorp | 0:65004368569c | 46 | HTTP_Part fileDat; |
AxedaCorp | 0:65004368569c | 47 | HTTP_Transmission response; |
AxedaCorp | 0:65004368569c | 48 | fileDat.data=file->data; |
AxedaCorp | 0:65004368569c | 49 | fileDat.data_sz=file->size; |
AxedaCorp | 0:65004368569c | 50 | fileDat.file_name=file->name; |
AxedaCorp | 0:65004368569c | 51 | fileDat.hint=file->hint; |
AxedaCorp | 0:65004368569c | 52 | fileDat.next=NULL; |
AxedaCorp | 0:65004368569c | 53 | |
AxedaCorp | 0:65004368569c | 54 | url = getFileResource(url, device); |
AxedaCorp | 0:65004368569c | 55 | |
AxedaCorp | 0:65004368569c | 56 | int body_sz=strlen(file->hint)+12+strlen(file->name); |
AxedaCorp | 0:65004368569c | 57 | char *body=malloc(sizeof(char)*body_sz); |
AxedaCorp | 0:65004368569c | 58 | int bodyWrt=snprintf(body, body_sz, "name=\"hint\" \r\n %s",file->hint); |
AxedaCorp | 0:65004368569c | 59 | if(bodyWrt>body_sz) { retVal=AX_GEN_STR_TRUNC; } |
AxedaCorp | 0:65004368569c | 60 | printDebug(body); |
AxedaCorp | 0:65004368569c | 61 | |
AxedaCorp | 0:65004368569c | 62 | retVal=http_send_mpost(url, cloud->hostname, cloud->port, cloud->secure, NULL, NULL, 0, &fileDat, 1, &response); |
AxedaCorp | 0:65004368569c | 63 | |
AxedaCorp | 0:65004368569c | 64 | free(body); |
AxedaCorp | 0:65004368569c | 65 | free(url); |
AxedaCorp | 0:65004368569c | 66 | |
AxedaCorp | 0:65004368569c | 67 | return retVal; |
AxedaCorp | 0:65004368569c | 68 | } |
AxedaCorp | 0:65004368569c | 69 | |
AxedaCorp | 0:65004368569c | 70 | /************************************************************************************/ |
AxedaCorp | 0:65004368569c | 71 | /* ax_platform_ping() */ |
AxedaCorp | 0:65004368569c | 72 | /* */ |
AxedaCorp | 0:65004368569c | 73 | /* This function creates a ping message which acts as the device heartbeat. */ |
AxedaCorp | 0:65004368569c | 74 | /* */ |
AxedaCorp | 0:65004368569c | 75 | /* */ |
AxedaCorp | 0:65004368569c | 76 | /************************************************************************************/ |
AxedaCorp | 0:65004368569c | 77 | int ax_platform_ping(ax_platform *cloud, ax_deviceID *device) |
AxedaCorp | 0:65004368569c | 78 | { |
AxedaCorp | 0:65004368569c | 79 | int retVal=AX_UNKNOWN; |
AxedaCorp | 0:65004368569c | 80 | char *url=NULL; |
AxedaCorp | 0:65004368569c | 81 | HTTP_Headers myHeader; |
AxedaCorp | 0:65004368569c | 82 | HTTP_Transmission response; |
AxedaCorp | 0:65004368569c | 83 | myHeader.contentType=getGeneralType(myHeader.contentType); |
AxedaCorp | 0:65004368569c | 84 | url=getAgentResource(url, device); |
AxedaCorp | 0:65004368569c | 85 | |
AxedaCorp | 0:65004368569c | 86 | //Send the request |
AxedaCorp | 0:65004368569c | 87 | retVal= http_send_post(url, cloud->hostname, cloud->port, cloud->secure, &myHeader, NULL, 0, &response); |
AxedaCorp | 0:65004368569c | 88 | //Scan the response and act if there are egress messages. |
AxedaCorp | 0:65004368569c | 89 | handleResponse(&response); |
AxedaCorp | 0:65004368569c | 90 | free(url); |
AxedaCorp | 0:65004368569c | 91 | return retVal; |
AxedaCorp | 0:65004368569c | 92 | } |
AxedaCorp | 0:65004368569c | 93 | |
AxedaCorp | 0:65004368569c | 94 | /************************************************************************************/ |
AxedaCorp | 0:65004368569c | 95 | /*ax_platform_download() */ |
AxedaCorp | 0:65004368569c | 96 | /* */ |
AxedaCorp | 0:65004368569c | 97 | /*This function wil request a file from the platform with a specific file ID. The */ |
AxedaCorp | 0:65004368569c | 98 | /*fileID itself will be transmitted down on a response message from the platform. */ |
AxedaCorp | 0:65004368569c | 99 | /* */ |
AxedaCorp | 0:65004368569c | 100 | /* */ |
AxedaCorp | 0:65004368569c | 101 | /************************************************************************************/ |
AxedaCorp | 0:65004368569c | 102 | int ax_platform_download(ax_platform *cloud, ax_deviceID *device, ax_package_instruction *instr) |
AxedaCorp | 0:65004368569c | 103 | { |
AxedaCorp | 0:65004368569c | 104 | int retVal = AX_UNKNOWN; |
AxedaCorp | 0:65004368569c | 105 | char *url=NULL; |
AxedaCorp | 0:65004368569c | 106 | HTTP_Transmission response; |
AxedaCorp | 0:65004368569c | 107 | url=getFileDownloadResource(url, device, instr->file_id); |
AxedaCorp | 0:65004368569c | 108 | retVal=http_send_get(url, cloud->hostname, cloud->port, cloud->secure, &response); |
AxedaCorp | 0:65004368569c | 109 | //TODO: revisit what to do with response in this case. |
AxedaCorp | 0:65004368569c | 110 | scm_file_write(instr->filename, response.body, response.body_length, instr); |
AxedaCorp | 0:65004368569c | 111 | free(url); |
AxedaCorp | 0:65004368569c | 112 | return retVal; |
AxedaCorp | 0:65004368569c | 113 | } |
AxedaCorp | 0:65004368569c | 114 | |
AxedaCorp | 0:65004368569c | 115 | |
AxedaCorp | 0:65004368569c | 116 | /************************************************************************************/ |
AxedaCorp | 0:65004368569c | 117 | /* ax_platform_register() */ |
AxedaCorp | 0:65004368569c | 118 | /* */ |
AxedaCorp | 0:65004368569c | 119 | /*This function creates a registration message to be sent to the cloud. The message */ |
AxedaCorp | 0:65004368569c | 120 | /*contains information about the model, serial and expected ping interval. It also */ |
AxedaCorp | 0:65004368569c | 121 | /*allows the cloud to mark the device as online. If using the standalone thread func*/ |
AxedaCorp | 0:65004368569c | 122 | /*-tion this method will be called automatically until successful. */ |
AxedaCorp | 0:65004368569c | 123 | /* */ |
AxedaCorp | 0:65004368569c | 124 | /*cloud(required) : a pointer to a structure that contains data about the cloud */ |
AxedaCorp | 0:65004368569c | 125 | /*device(required) : a pointer to a structure that contains the model and serial */ |
AxedaCorp | 0:65004368569c | 126 | /*pingRate(required) : an integer in milliseconds which tells the cloud how often to*/ |
AxedaCorp | 0:65004368569c | 127 | /* expect a heartbeat ping */ |
AxedaCorp | 0:65004368569c | 128 | /* */ |
AxedaCorp | 0:65004368569c | 129 | /*Returns: an integer value indicating whether or not it successfully registered */ |
AxedaCorp | 0:65004368569c | 130 | /************************************************************************************/ |
AxedaCorp | 0:65004368569c | 131 | int ax_platform_register(ax_platform *cloud, ax_deviceID *device) |
AxedaCorp | 0:65004368569c | 132 | { |
AxedaCorp | 0:65004368569c | 133 | int retVal=AX_UNKNOWN; |
AxedaCorp | 0:65004368569c | 134 | char *url=NULL; |
AxedaCorp | 0:65004368569c | 135 | char *fullRequest=NULL; |
AxedaCorp | 0:65004368569c | 136 | cJSON *requestBody; |
AxedaCorp | 0:65004368569c | 137 | HTTP_Headers myHeader; |
AxedaCorp | 0:65004368569c | 138 | HTTP_Transmission response; |
AxedaCorp | 0:65004368569c | 139 | myHeader.contentType=getGeneralType(myHeader.contentType); |
AxedaCorp | 0:65004368569c | 140 | url = getRegistrationResource(url, device); |
AxedaCorp | 0:65004368569c | 141 | int urlLength=strlen(url); |
AxedaCorp | 0:65004368569c | 142 | url[urlLength]='\0'; |
AxedaCorp | 0:65004368569c | 143 | |
AxedaCorp | 0:65004368569c | 144 | requestBody=getRegistrationJSON(device, cloud->ping_rate); |
AxedaCorp | 0:65004368569c | 145 | |
AxedaCorp | 0:65004368569c | 146 | fullRequest=cJSON_PrintUnformatted(requestBody); |
AxedaCorp | 0:65004368569c | 147 | int contentLength=strlen(fullRequest); |
AxedaCorp | 0:65004368569c | 148 | |
AxedaCorp | 0:65004368569c | 149 | retVal= http_send_post(url, cloud->hostname, cloud->port, cloud->secure, &myHeader, fullRequest, contentLength, &response); |
AxedaCorp | 0:65004368569c | 150 | //Scan the response and act if there are egress messages. |
AxedaCorp | 0:65004368569c | 151 | handleResponse(&response); |
AxedaCorp | 0:65004368569c | 152 | |
AxedaCorp | 0:65004368569c | 153 | //Clean up after ourselves |
AxedaCorp | 0:65004368569c | 154 | free(fullRequest); |
AxedaCorp | 0:65004368569c | 155 | free(url); |
AxedaCorp | 0:65004368569c | 156 | cJSON_Delete(requestBody); |
AxedaCorp | 0:65004368569c | 157 | return retVal; |
AxedaCorp | 0:65004368569c | 158 | } |
AxedaCorp | 0:65004368569c | 159 | |
AxedaCorp | 0:65004368569c | 160 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 161 | /*ax_platform_send() */ |
AxedaCorp | 0:65004368569c | 162 | /* */ |
AxedaCorp | 0:65004368569c | 163 | /*This function sends any data available in the structures directly to the cloud in */ |
AxedaCorp | 0:65004368569c | 164 | /*an on demand fashion. */ |
AxedaCorp | 0:65004368569c | 165 | /* */ |
AxedaCorp | 0:65004368569c | 166 | /* */ |
AxedaCorp | 0:65004368569c | 167 | /*cloud(required) : a pointer to a structure that contains the cloud service info */ |
AxedaCorp | 0:65004368569c | 168 | /*device(required) : a pointer to a structure that contains device information */ |
AxedaCorp | 0:65004368569c | 169 | /*dataItems(optional) : a pointer to an array of ax_dataItem pointers that will be sent*/ |
AxedaCorp | 0:65004368569c | 170 | /*alarms(optional) : a pointer to an array of ax_alarm pointers that will be sent */ |
AxedaCorp | 0:65004368569c | 171 | /*events(optional) : a pointer to an array of ax_event pointers that will be sent */ |
AxedaCorp | 0:65004368569c | 172 | /*locations(optional) : a pointer to an array of ax_location pointers that will be sent*/ |
AxedaCorp | 0:65004368569c | 173 | /* */ |
AxedaCorp | 0:65004368569c | 174 | /*Returns: an integer value indicating whether or not it successfully sent the data */ |
AxedaCorp | 0:65004368569c | 175 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 176 | int ax_platform_send(ax_platform *cloud, ax_deviceID *device, ax_dataSet *dataItems[], int numDataSets, ax_alarm *alarms[], int numAlarms, ax_event *events[], int numEvents, ax_location *locations[], int numLocations) { |
AxedaCorp | 0:65004368569c | 177 | |
AxedaCorp | 0:65004368569c | 178 | int retVal=AX_UNKNOWN; |
AxedaCorp | 0:65004368569c | 179 | HTTP_Headers myHeader; |
AxedaCorp | 0:65004368569c | 180 | char *url=NULL; |
AxedaCorp | 0:65004368569c | 181 | |
AxedaCorp | 0:65004368569c | 182 | char *fullRequest=NULL; |
AxedaCorp | 0:65004368569c | 183 | cJSON *rootNode=NULL; |
AxedaCorp | 0:65004368569c | 184 | rootNode=cJSON_CreateObject(); |
AxedaCorp | 0:65004368569c | 185 | HTTP_Transmission response; |
AxedaCorp | 0:65004368569c | 186 | zeroOutHTTPXmission(&response); |
AxedaCorp | 0:65004368569c | 187 | //add the data in the DataItems queue if passed |
AxedaCorp | 0:65004368569c | 188 | if(dataItems){ |
AxedaCorp | 0:65004368569c | 189 | cJSON_AddItemToObject(rootNode, buffer_keywords[BUFF_DATA], dataSet2JSON((ax_dataSet **)dataItems, numDataSets, terse_enable)); |
AxedaCorp | 0:65004368569c | 190 | } |
AxedaCorp | 0:65004368569c | 191 | //add all alarms to the transmission if passed |
AxedaCorp | 0:65004368569c | 192 | if(alarms){ |
AxedaCorp | 0:65004368569c | 193 | cJSON_AddItemToObject(rootNode, buffer_keywords[BUFF_ALARMS], AlarmsToJSON((ax_alarm **)alarms, numAlarms, terse_enable)); |
AxedaCorp | 0:65004368569c | 194 | } |
AxedaCorp | 0:65004368569c | 195 | if(events){ |
AxedaCorp | 0:65004368569c | 196 | cJSON_AddItemToObject(rootNode, buffer_keywords[BUFF_EVENTS], eventsToJSON((ax_event **)events, numEvents, terse_enable)); |
AxedaCorp | 0:65004368569c | 197 | } |
AxedaCorp | 0:65004368569c | 198 | if(locations){ |
AxedaCorp | 0:65004368569c | 199 | cJSON_AddItemToObject(rootNode, buffer_keywords[BUFF_LOCATIONS], locationsToJSON((ax_location **)locations, numLocations, terse_enable)); |
AxedaCorp | 0:65004368569c | 200 | } |
AxedaCorp | 0:65004368569c | 201 | |
AxedaCorp | 0:65004368569c | 202 | myHeader.contentType=getGeneralType(myHeader.contentType); |
AxedaCorp | 0:65004368569c | 203 | url = getDataResource(url, device); |
AxedaCorp | 0:65004368569c | 204 | fullRequest=cJSON_PrintUnformatted(rootNode); |
AxedaCorp | 0:65004368569c | 205 | |
AxedaCorp | 0:65004368569c | 206 | retVal= http_send_post(url, cloud->hostname, cloud->port, cloud->secure, &myHeader, fullRequest, strlen(fullRequest), &response); |
AxedaCorp | 0:65004368569c | 207 | //Scan the response and act if there are egress messages. |
AxedaCorp | 0:65004368569c | 208 | handleResponse(&response); |
AxedaCorp | 0:65004368569c | 209 | |
AxedaCorp | 0:65004368569c | 210 | if(fullRequest) { |
AxedaCorp | 0:65004368569c | 211 | free(fullRequest); |
AxedaCorp | 0:65004368569c | 212 | } |
AxedaCorp | 0:65004368569c | 213 | free(url); |
AxedaCorp | 0:65004368569c | 214 | cJSON_Delete(rootNode); |
AxedaCorp | 0:65004368569c | 215 | |
AxedaCorp | 0:65004368569c | 216 | return retVal; |
AxedaCorp | 0:65004368569c | 217 | } |
AxedaCorp | 0:65004368569c | 218 | |
AxedaCorp | 0:65004368569c | 219 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 220 | /*ax_platform_sendData() */ |
AxedaCorp | 0:65004368569c | 221 | /* */ |
AxedaCorp | 0:65004368569c | 222 | /*This function immedately sends any data included in the parameter to the platform */ |
AxedaCorp | 0:65004368569c | 223 | /*listed. It makes use of the ax_platform_send() function as a special case. */ |
AxedaCorp | 0:65004368569c | 224 | /* */ |
AxedaCorp | 0:65004368569c | 225 | /*cloud(required) : a pointer to a structure that contains the cloud service info */ |
AxedaCorp | 0:65004368569c | 226 | /*device(required) : a pointer to a structure that contains device information */ |
AxedaCorp | 0:65004368569c | 227 | /*dataItems(required) : pointer to an array of ax_dataItem pointers that will be sent */ |
AxedaCorp | 0:65004368569c | 228 | /* */ |
AxedaCorp | 0:65004368569c | 229 | /*Returns: an integer value indicating whether or not it successfully sent the data */ |
AxedaCorp | 0:65004368569c | 230 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 231 | int ax_platform_sendData(ax_platform *cloud, ax_deviceID *device, ax_dataSet *dataItems[], int numDataSets) { |
AxedaCorp | 0:65004368569c | 232 | |
AxedaCorp | 0:65004368569c | 233 | return ax_platform_send(cloud, device, dataItems, numDataSets, NULL, 0, NULL, 0, NULL, 0); |
AxedaCorp | 0:65004368569c | 234 | |
AxedaCorp | 0:65004368569c | 235 | } |
AxedaCorp | 0:65004368569c | 236 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 237 | /*ax_platform_sendAlarms() */ |
AxedaCorp | 0:65004368569c | 238 | /* */ |
AxedaCorp | 0:65004368569c | 239 | /*This function immedately sends any alarms included in the parameter to the platform */ |
AxedaCorp | 0:65004368569c | 240 | /*listed. It makes use of the ax_platform_send() function as a special case. */ |
AxedaCorp | 0:65004368569c | 241 | /* */ |
AxedaCorp | 0:65004368569c | 242 | /*cloud(required) : a pointer to a structure that contains the cloud service info */ |
AxedaCorp | 0:65004368569c | 243 | /*device(required) : a pointer to a structure that contains device information */ |
AxedaCorp | 0:65004368569c | 244 | /*alarms(required) : a pointer to an array of ax_alarm pointers that will be sent */ |
AxedaCorp | 0:65004368569c | 245 | /* */ |
AxedaCorp | 0:65004368569c | 246 | /*Returns: an integer value indicating whether or not it successfully sent the data */ |
AxedaCorp | 0:65004368569c | 247 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 248 | int ax_platform_sendAlarms(ax_platform *cloud, ax_deviceID *device, ax_alarm *alarms[], int numAlarms) { |
AxedaCorp | 0:65004368569c | 249 | |
AxedaCorp | 0:65004368569c | 250 | return ax_platform_send(cloud, device, NULL, 0, alarms, numAlarms, NULL, 0, NULL, 0); |
AxedaCorp | 0:65004368569c | 251 | |
AxedaCorp | 0:65004368569c | 252 | } |
AxedaCorp | 0:65004368569c | 253 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 254 | /*ax_platform_sendEvents() */ |
AxedaCorp | 0:65004368569c | 255 | /* */ |
AxedaCorp | 0:65004368569c | 256 | /*This function immedately sends any events included in the parameter to the platform */ |
AxedaCorp | 0:65004368569c | 257 | /*listed. It makes use of the ax_platform_send() function as a special case. */ |
AxedaCorp | 0:65004368569c | 258 | /* */ |
AxedaCorp | 0:65004368569c | 259 | /*cloud(required) : a pointer to a structure that contains the cloud service info */ |
AxedaCorp | 0:65004368569c | 260 | /*device(required) : a pointer to a structure that contains device information */ |
AxedaCorp | 0:65004368569c | 261 | /*events(required) : a pointer to an array of ax_event pointers that will be sent */ |
AxedaCorp | 0:65004368569c | 262 | /* */ |
AxedaCorp | 0:65004368569c | 263 | /*Returns: an integer value indicating whether or not it successfully sent the data */ |
AxedaCorp | 0:65004368569c | 264 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 265 | int ax_platform_sendEvents(ax_platform *cloud, ax_deviceID *device, ax_event *events[], int numEvents) { |
AxedaCorp | 0:65004368569c | 266 | |
AxedaCorp | 0:65004368569c | 267 | return ax_platform_send(cloud, device, NULL, 0, NULL, 0, events, numEvents, NULL, 0); |
AxedaCorp | 0:65004368569c | 268 | |
AxedaCorp | 0:65004368569c | 269 | } |
AxedaCorp | 0:65004368569c | 270 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 271 | /*ax_platform_sendLocations() */ |
AxedaCorp | 0:65004368569c | 272 | /* */ |
AxedaCorp | 0:65004368569c | 273 | /*This function immedately sends any events included in the parameter to the platform */ |
AxedaCorp | 0:65004368569c | 274 | /*listed. It makes use of the ax_platform_send() function as a special case. */ |
AxedaCorp | 0:65004368569c | 275 | /* */ |
AxedaCorp | 0:65004368569c | 276 | /*cloud(required) : a pointer to a structure that contains the cloud service info */ |
AxedaCorp | 0:65004368569c | 277 | /*device(required) : a pointer to a structure that contains device information */ |
AxedaCorp | 0:65004368569c | 278 | /*locations(required) : a pointer to an array of ax_location poitners that will be sent*/ |
AxedaCorp | 0:65004368569c | 279 | /* */ |
AxedaCorp | 0:65004368569c | 280 | /*Returns: an integer value indicating whether or not it successfully sent the data */ |
AxedaCorp | 0:65004368569c | 281 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 282 | int ax_platform_sendLocations(ax_platform *cloud, ax_deviceID *device, ax_location *locations[], int numLocations) { |
AxedaCorp | 0:65004368569c | 283 | |
AxedaCorp | 0:65004368569c | 284 | return ax_platform_send(cloud, device, NULL, 0, NULL, 0, NULL, 0, locations, numLocations); |
AxedaCorp | 0:65004368569c | 285 | |
AxedaCorp | 0:65004368569c | 286 | } |
AxedaCorp | 0:65004368569c | 287 | |
AxedaCorp | 0:65004368569c | 288 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 289 | /*ax_platform_setPkgStatus() */ |
AxedaCorp | 0:65004368569c | 290 | /* */ |
AxedaCorp | 0:65004368569c | 291 | /*Tells the platform what state the package is currently in. This is necessary for the*/ |
AxedaCorp | 0:65004368569c | 292 | /*lifecycle of the packages in the Axeda System. */ |
AxedaCorp | 0:65004368569c | 293 | /* */ |
AxedaCorp | 0:65004368569c | 294 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 295 | int ax_platform_setPkgStatus(ax_platform *cloud, ax_deviceID *device, char *pkgID, int status, char *errorMsg) { |
AxedaCorp | 0:65004368569c | 296 | int retVal=AX_UNKNOWN; |
AxedaCorp | 0:65004368569c | 297 | char *url=NULL; |
AxedaCorp | 0:65004368569c | 298 | char *fullRequest=NULL; |
AxedaCorp | 0:65004368569c | 299 | cJSON *requestBody=NULL; |
AxedaCorp | 0:65004368569c | 300 | HTTP_Headers myHeader; |
AxedaCorp | 0:65004368569c | 301 | HTTP_Transmission response; |
AxedaCorp | 0:65004368569c | 302 | zeroOutHTTPXmission(&response); |
AxedaCorp | 0:65004368569c | 303 | |
AxedaCorp | 0:65004368569c | 304 | requestBody= getPKGStatusJSON(status, errorMsg, AX_NO_PRIORITY, 0, terse_enable); |
AxedaCorp | 0:65004368569c | 305 | |
AxedaCorp | 0:65004368569c | 306 | myHeader.contentType=getGeneralType(myHeader.contentType); |
AxedaCorp | 0:65004368569c | 307 | url=getPackageUpdateResource(url, device, pkgID); |
AxedaCorp | 0:65004368569c | 308 | int urlLength=strlen(url); |
AxedaCorp | 0:65004368569c | 309 | url[urlLength]='\0'; |
AxedaCorp | 0:65004368569c | 310 | |
AxedaCorp | 0:65004368569c | 311 | fullRequest=cJSON_PrintUnformatted(requestBody); |
AxedaCorp | 0:65004368569c | 312 | int contentLength=strlen(fullRequest); |
AxedaCorp | 0:65004368569c | 313 | //Send the status |
AxedaCorp | 0:65004368569c | 314 | retVal=http_send_put(url, cloud->hostname, cloud->port, cloud->secure, &myHeader, fullRequest, contentLength, &response); |
AxedaCorp | 0:65004368569c | 315 | //Scan the response and act if there are egress messages. |
AxedaCorp | 0:65004368569c | 316 | handleResponse(&response); |
AxedaCorp | 0:65004368569c | 317 | |
AxedaCorp | 0:65004368569c | 318 | //Clean up after ourselves |
AxedaCorp | 0:65004368569c | 319 | free(fullRequest); |
AxedaCorp | 0:65004368569c | 320 | free(url); |
AxedaCorp | 0:65004368569c | 321 | cJSON_Delete(requestBody); |
AxedaCorp | 0:65004368569c | 322 | |
AxedaCorp | 0:65004368569c | 323 | return retVal; |
AxedaCorp | 0:65004368569c | 324 | } |
AxedaCorp | 0:65004368569c | 325 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 326 | /*ax_platform_setPkgStatus() */ |
AxedaCorp | 0:65004368569c | 327 | /* */ |
AxedaCorp | 0:65004368569c | 328 | /*Tells the platform what state the package is currently in. This is necessary for the*/ |
AxedaCorp | 0:65004368569c | 329 | /*lifecycle of the packages in the Axeda System. */ |
AxedaCorp | 0:65004368569c | 330 | /* */ |
AxedaCorp | 0:65004368569c | 331 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 332 | int ax_platform_setPkgStatusStarted(ax_platform *cloud, ax_deviceID *device, char *pkgID) { |
AxedaCorp | 0:65004368569c | 333 | return ax_platform_setPkgStatus(cloud, device, pkgID, AX_PKG_STARTED, NULL); |
AxedaCorp | 0:65004368569c | 334 | } |
AxedaCorp | 0:65004368569c | 335 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 336 | /*ax_platform_setPkgStatus() */ |
AxedaCorp | 0:65004368569c | 337 | /* */ |
AxedaCorp | 0:65004368569c | 338 | /*Tells the platform what state the package is currently in. This is necessary for the*/ |
AxedaCorp | 0:65004368569c | 339 | /*lifecycle of the packages in the Axeda System. */ |
AxedaCorp | 0:65004368569c | 340 | /* */ |
AxedaCorp | 0:65004368569c | 341 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 342 | int ax_platform_setPkgStatusQueued(ax_platform *cloud, ax_deviceID *device, char *pkgID) { |
AxedaCorp | 0:65004368569c | 343 | return ax_platform_setPkgStatus(cloud, device, pkgID, AX_PKG_QUEUED, NULL); |
AxedaCorp | 0:65004368569c | 344 | } |
AxedaCorp | 0:65004368569c | 345 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 346 | /*ax_platform_setPkgStatus() */ |
AxedaCorp | 0:65004368569c | 347 | /* */ |
AxedaCorp | 0:65004368569c | 348 | /*Tells the platform what state the package is currently in. This is necessary for the*/ |
AxedaCorp | 0:65004368569c | 349 | /*lifecycle of the packages in the Axeda System. */ |
AxedaCorp | 0:65004368569c | 350 | /* */ |
AxedaCorp | 0:65004368569c | 351 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 352 | int ax_platform_setPkgStatusSuccess(ax_platform *cloud, ax_deviceID *device, char *pkgID) { |
AxedaCorp | 0:65004368569c | 353 | return ax_platform_setPkgStatus(cloud, device, pkgID, AX_PKG_SUCCESS, NULL); |
AxedaCorp | 0:65004368569c | 354 | } |
AxedaCorp | 0:65004368569c | 355 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 356 | /*ax_platform_setPkgStatus() */ |
AxedaCorp | 0:65004368569c | 357 | /* */ |
AxedaCorp | 0:65004368569c | 358 | /*Tells the platform what state the package is currently in. This is necessary for the*/ |
AxedaCorp | 0:65004368569c | 359 | /*lifecycle of the packages in the Axeda System. */ |
AxedaCorp | 0:65004368569c | 360 | /* */ |
AxedaCorp | 0:65004368569c | 361 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 362 | int ax_platform_setPkgStatusFailed(ax_platform *cloud, ax_deviceID *device, char *pkgID, char *errorMsg) { |
AxedaCorp | 0:65004368569c | 363 | return ax_platform_setPkgStatus(cloud, device, pkgID, AX_PKG_FAILURE, errorMsg); |
AxedaCorp | 0:65004368569c | 364 | } |
AxedaCorp | 0:65004368569c | 365 | |
AxedaCorp | 0:65004368569c | 366 | /***************************************************************************************************************************************************************/ |
AxedaCorp | 0:65004368569c | 367 | /***************************************************************************************************************************************************************/ |
AxedaCorp | 0:65004368569c | 368 | /*The code in the following sections should never need to be called as it will be called from the preceeding functions. */ |
AxedaCorp | 0:65004368569c | 369 | /***************************************************************************************************************************************************************/ |
AxedaCorp | 0:65004368569c | 370 | /***************************************************************************************************************************************************************/ |
AxedaCorp | 0:65004368569c | 371 | |
AxedaCorp | 0:65004368569c | 372 | /************************************************************************************/ |
AxedaCorp | 0:65004368569c | 373 | /* The following methods construct references to endpoints on the platform where the */ |
AxedaCorp | 0:65004368569c | 374 | /*respective data will be sent. For the sake of convenience they all return a pointer*/ |
AxedaCorp | 0:65004368569c | 375 | /*that is equal in value to that which was passed in. */ |
AxedaCorp | 0:65004368569c | 376 | /* They all take the same arguments: */ |
AxedaCorp | 0:65004368569c | 377 | /* */ |
AxedaCorp | 0:65004368569c | 378 | /* endPointBuff = The pointer to where the endpoint will be stored. This pointer */ |
AxedaCorp | 0:65004368569c | 379 | /* will be allocated and populated by the function */ |
AxedaCorp | 0:65004368569c | 380 | /* ax_deviceID = A structure that contains the model and serial number of the current*/ |
AxedaCorp | 0:65004368569c | 381 | /* device. This structure should be the same as the one constructed at */ |
AxedaCorp | 0:65004368569c | 382 | /* startup based on the arguments. */ |
AxedaCorp | 0:65004368569c | 383 | /************************************************************************************/ |
AxedaCorp | 0:65004368569c | 384 | char *getDataResource(char *endPointBuff, ax_deviceID *device) |
AxedaCorp | 0:65004368569c | 385 | { |
AxedaCorp | 0:65004368569c | 386 | return getResource(endPointBuff, device, END_DATA); |
AxedaCorp | 0:65004368569c | 387 | } |
AxedaCorp | 0:65004368569c | 388 | |
AxedaCorp | 0:65004368569c | 389 | char *getAgentResource(char *endPointBuff, ax_deviceID *device) |
AxedaCorp | 0:65004368569c | 390 | { |
AxedaCorp | 0:65004368569c | 391 | return getResource(endPointBuff, device, END_AGENTS); |
AxedaCorp | 0:65004368569c | 392 | } |
AxedaCorp | 0:65004368569c | 393 | |
AxedaCorp | 0:65004368569c | 394 | char *getFileResource(char *endPointBuff, ax_deviceID *device) |
AxedaCorp | 0:65004368569c | 395 | { |
AxedaCorp | 0:65004368569c | 396 | return getResource(endPointBuff, device, END_FILES); |
AxedaCorp | 0:65004368569c | 397 | } |
AxedaCorp | 0:65004368569c | 398 | |
AxedaCorp | 0:65004368569c | 399 | char *getRegistrationResource(char *endPointBuff, ax_deviceID *device) |
AxedaCorp | 0:65004368569c | 400 | { |
AxedaCorp | 0:65004368569c | 401 | return getResource(endPointBuff, device, END_REG); |
AxedaCorp | 0:65004368569c | 402 | } |
AxedaCorp | 0:65004368569c | 403 | char *getFileDownloadResource(char *endPointBuff, ax_deviceID *device, char *fileID) { |
AxedaCorp | 0:65004368569c | 404 | //since this url is slightly different from all the others we need to override the standard passing. |
AxedaCorp | 0:65004368569c | 405 | char *tempBuff=NULL; |
AxedaCorp | 0:65004368569c | 406 | tempBuff=encodeAgentID(device, tempBuff); |
AxedaCorp | 0:65004368569c | 407 | int len=strlen(endpoints[END_BASE])+strlen(endpoints[END_PACKAGES])+6+strlen(tempBuff)+strlen(fileID)+strlen(endpoints[END_FILES])+1+strlen(PROTOCOL_VERSION)+1; |
AxedaCorp | 0:65004368569c | 408 | endPointBuff = (char *)calloc(len,sizeof(char)); |
AxedaCorp | 0:65004368569c | 409 | // /ammp/packages/1/files/test_model!test_serial/12345 |
AxedaCorp | 0:65004368569c | 410 | // , URL_SEP, endpoints[END_BASE], URL_SEP, endpoints[END_FILED], URL_SEP, PROTOCOL_VERSION, URL_SEP, endpoints[END_FILES], URL_SEP, tempBuff=encodeAgentID(device, tempBuff), URL_SEP, fileID |
AxedaCorp | 0:65004368569c | 411 | // %c%s%c%s%c%s%c%s%c%s%c%s |
AxedaCorp | 0:65004368569c | 412 | |
AxedaCorp | 0:65004368569c | 413 | snprintf(endPointBuff, len, "%c%s%c%s%c%s%c%s%c%s%c%s", URL_SEP, endpoints[END_BASE], URL_SEP, endpoints[END_PACKAGES], URL_SEP, PROTOCOL_VERSION, URL_SEP, endpoints[END_FILES], URL_SEP, tempBuff, URL_SEP, fileID ); |
AxedaCorp | 0:65004368569c | 414 | free(tempBuff); |
AxedaCorp | 0:65004368569c | 415 | |
AxedaCorp | 0:65004368569c | 416 | return endPointBuff; |
AxedaCorp | 0:65004368569c | 417 | } |
AxedaCorp | 0:65004368569c | 418 | |
AxedaCorp | 0:65004368569c | 419 | char *getPackageUpdateResource(char *endPointBuff, ax_deviceID *device, char *packageID){ |
AxedaCorp | 0:65004368569c | 420 | //since this url is slightly different from all the others we need to override the standard passing. |
AxedaCorp | 0:65004368569c | 421 | // "/ammp/packages/1/12345/status/test_model!test_serial" |
AxedaCorp | 0:65004368569c | 422 | char *tempBuff=NULL; |
AxedaCorp | 0:65004368569c | 423 | tempBuff=encodeAgentID(device, tempBuff); |
AxedaCorp | 0:65004368569c | 424 | int len=6+strlen(endpoints[END_BASE])+strlen(endpoints[END_PACKAGES])+strlen(PROTOCOL_VERSION)+strlen(packageID)+strlen(endpoints[END_STATUS])+strlen(tempBuff)+1; |
AxedaCorp | 0:65004368569c | 425 | endPointBuff = (char *)calloc(len, sizeof(char)); |
AxedaCorp | 0:65004368569c | 426 | |
AxedaCorp | 0:65004368569c | 427 | snprintf(endPointBuff, len, "%c%s%c%s%c%s%c%s%c%s%c%s", URL_SEP, endpoints[END_BASE], URL_SEP, endpoints[END_PACKAGES], URL_SEP, PROTOCOL_VERSION, URL_SEP, packageID, URL_SEP, endpoints[END_STATUS], URL_SEP, tempBuff); |
AxedaCorp | 0:65004368569c | 428 | free(tempBuff); |
AxedaCorp | 0:65004368569c | 429 | |
AxedaCorp | 0:65004368569c | 430 | return endPointBuff; |
AxedaCorp | 0:65004368569c | 431 | } |
AxedaCorp | 0:65004368569c | 432 | |
AxedaCorp | 0:65004368569c | 433 | char *getResource(char *endPointBuff, ax_deviceID *device, int resourceType) |
AxedaCorp | 0:65004368569c | 434 | { |
AxedaCorp | 0:65004368569c | 435 | //Check for bounds on the endpoints array. END_REG is currently the highest, if it's OOB return the agent default URL |
AxedaCorp | 0:65004368569c | 436 | int resType=END_AGENTS; |
AxedaCorp | 0:65004368569c | 437 | if((resourceType<0)||(resourceType>END_REG)) { resType=END_AGENTS; } |
AxedaCorp | 0:65004368569c | 438 | else { resType=resourceType; } |
AxedaCorp | 0:65004368569c | 439 | int len = strlen(endpoints[END_BASE])+strlen(endpoints[resType])+6+strlen(device->model)+strlen(device->serial); |
AxedaCorp | 0:65004368569c | 440 | endPointBuff = (char *)calloc(len+1, sizeof(char)); |
AxedaCorp | 0:65004368569c | 441 | char *tempBuff=NULL; |
AxedaCorp | 0:65004368569c | 442 | switch(resType) { |
AxedaCorp | 0:65004368569c | 443 | case END_REG: |
AxedaCorp | 0:65004368569c | 444 | snprintf(endPointBuff, len+1, "%c%s%c%s%c%s", URL_SEP, endpoints[END_BASE], URL_SEP, endpoints[END_AGENTS], URL_SEP, PROTOCOL_VERSION); |
AxedaCorp | 0:65004368569c | 445 | break; |
AxedaCorp | 0:65004368569c | 446 | case END_FILED: |
AxedaCorp | 0:65004368569c | 447 | |
AxedaCorp | 0:65004368569c | 448 | break; |
AxedaCorp | 0:65004368569c | 449 | default: |
AxedaCorp | 0:65004368569c | 450 | snprintf(endPointBuff, len+1, "%c%s%c%s%c%s%c%s", URL_SEP, endpoints[END_BASE], URL_SEP, endpoints[resType], URL_SEP, PROTOCOL_VERSION, URL_SEP, tempBuff=encodeAgentID(device, tempBuff)); |
AxedaCorp | 0:65004368569c | 451 | free(tempBuff); //only used for storing the deviceID it's work is done now. |
AxedaCorp | 0:65004368569c | 452 | break; |
AxedaCorp | 0:65004368569c | 453 | } |
AxedaCorp | 0:65004368569c | 454 | |
AxedaCorp | 0:65004368569c | 455 | return endPointBuff; |
AxedaCorp | 0:65004368569c | 456 | } |
AxedaCorp | 0:65004368569c | 457 | |
AxedaCorp | 0:65004368569c | 458 | |
AxedaCorp | 0:65004368569c | 459 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 460 | /*encodeAgentID() */ |
AxedaCorp | 0:65004368569c | 461 | /* */ |
AxedaCorp | 0:65004368569c | 462 | /*A utility method to convert the ax_deviceID structure into a protocol compliant */ |
AxedaCorp | 0:65004368569c | 463 | /*identifier string. Used mostly by the registration message */ |
AxedaCorp | 0:65004368569c | 464 | /* */ |
AxedaCorp | 0:65004368569c | 465 | /*device(required) : a pointer to a structure that contains the model, serial, tenant*/ |
AxedaCorp | 0:65004368569c | 466 | /*buff(required) : a pointer to a char array where the output will be stored. */ |
AxedaCorp | 0:65004368569c | 467 | /* */ |
AxedaCorp | 0:65004368569c | 468 | /*Returns: a pointer to the char array, same as *buff */ |
AxedaCorp | 0:65004368569c | 469 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 470 | char* encodeAgentID(ax_deviceID *device, char *buff) |
AxedaCorp | 0:65004368569c | 471 | { |
AxedaCorp | 0:65004368569c | 472 | //TODO: Add logic to URL Encode output string if special characters are encountered... |
AxedaCorp | 0:65004368569c | 473 | int len=0; |
AxedaCorp | 0:65004368569c | 474 | if(strlen(device->tenant)>0) |
AxedaCorp | 0:65004368569c | 475 | { |
AxedaCorp | 0:65004368569c | 476 | len=strlen(device->model)+strlen(device->serial)+strlen(device->tenant)+4; |
AxedaCorp | 0:65004368569c | 477 | buff = (char *)calloc(len, sizeof(char)); |
AxedaCorp | 0:65004368569c | 478 | //buff[len]='\0'; |
AxedaCorp | 0:65004368569c | 479 | snprintf(buff, len, "%s@%s!%s", device->model, device->tenant, device->serial ); |
AxedaCorp | 0:65004368569c | 480 | } |
AxedaCorp | 0:65004368569c | 481 | else |
AxedaCorp | 0:65004368569c | 482 | { |
AxedaCorp | 0:65004368569c | 483 | len=strlen(device->model)+strlen(device->serial)+3; |
AxedaCorp | 0:65004368569c | 484 | buff = (char *)calloc(len, sizeof(char)); |
AxedaCorp | 0:65004368569c | 485 | //buff[len]='\0'; |
AxedaCorp | 0:65004368569c | 486 | snprintf(buff,len, "%s!%s", device->model, device->serial); |
AxedaCorp | 0:65004368569c | 487 | } |
AxedaCorp | 0:65004368569c | 488 | |
AxedaCorp | 0:65004368569c | 489 | printDebug(buff); |
AxedaCorp | 0:65004368569c | 490 | |
AxedaCorp | 0:65004368569c | 491 | return buff; |
AxedaCorp | 0:65004368569c | 492 | } |
AxedaCorp | 0:65004368569c | 493 | |
AxedaCorp | 0:65004368569c | 494 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 495 | /*getContentType() */ |
AxedaCorp | 0:65004368569c | 496 | /* */ |
AxedaCorp | 0:65004368569c | 497 | /*A convenience method to allow different messages to have different media types. The */ |
AxedaCorp | 0:65004368569c | 498 | /*media types are set forth in the protocol specification. The function will return a */ |
AxedaCorp | 0:65004368569c | 499 | /*a pointer to a declared string, for which you do not need to free. */ |
AxedaCorp | 0:65004368569c | 500 | /* */ |
AxedaCorp | 0:65004368569c | 501 | /* */ |
AxedaCorp | 0:65004368569c | 502 | /* */ |
AxedaCorp | 0:65004368569c | 503 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 504 | |
AxedaCorp | 0:65004368569c | 505 | char *getContentType(char *contentBuff, int type) { |
AxedaCorp | 0:65004368569c | 506 | switch(type) { |
AxedaCorp | 0:65004368569c | 507 | case 0: |
AxedaCorp | 0:65004368569c | 508 | contentBuff=(char *)contentTypes[MIME_JSON]; |
AxedaCorp | 0:65004368569c | 509 | break; |
AxedaCorp | 0:65004368569c | 510 | default: |
AxedaCorp | 0:65004368569c | 511 | contentBuff=(char *)contentTypes[MIME_JSON]; |
AxedaCorp | 0:65004368569c | 512 | break; |
AxedaCorp | 0:65004368569c | 513 | } |
AxedaCorp | 0:65004368569c | 514 | return contentBuff; |
AxedaCorp | 0:65004368569c | 515 | } |
AxedaCorp | 0:65004368569c | 516 | |
AxedaCorp | 0:65004368569c | 517 | char *getGeneralType(char *contentBuff) { |
AxedaCorp | 0:65004368569c | 518 | return getContentType(contentBuff, TRANS_TYPE_JSON); |
AxedaCorp | 0:65004368569c | 519 | } |
AxedaCorp | 0:65004368569c | 520 | |
AxedaCorp | 0:65004368569c | 521 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 522 | /*int handleResponse() */ |
AxedaCorp | 0:65004368569c | 523 | /* */ |
AxedaCorp | 0:65004368569c | 524 | /*A catch-all method that will handle any egress messages sent from the platform back */ |
AxedaCorp | 0:65004368569c | 525 | /*to the device. If the JSON returned is valid it will dispatch the requests as needed*/ |
AxedaCorp | 0:65004368569c | 526 | /* */ |
AxedaCorp | 0:65004368569c | 527 | /* */ |
AxedaCorp | 0:65004368569c | 528 | /* */ |
AxedaCorp | 0:65004368569c | 529 | /**************************************************************************************/ |
AxedaCorp | 0:65004368569c | 530 | //Possible returns: |
AxedaCorp | 0:65004368569c | 531 | // AX_EGR_JSON_PARSE_FAIL -- A failure to parse the JSON that was returned |
AxedaCorp | 0:65004368569c | 532 | |
AxedaCorp | 0:65004368569c | 533 | int handleResponse(HTTP_Transmission *response){ |
AxedaCorp | 0:65004368569c | 534 | cJSON *resp_int, *temp, *temp_child, *instructions, *instruction_child; |
AxedaCorp | 0:65004368569c | 535 | int retVal=AX_OK; |
AxedaCorp | 0:65004368569c | 536 | if(response->body==NULL) {return AX_OK;} //if there's no body, there's nothing to do here. |
AxedaCorp | 0:65004368569c | 537 | |
AxedaCorp | 0:65004368569c | 538 | resp_int=cJSON_Parse(response->body); |
AxedaCorp | 0:65004368569c | 539 | if(resp_int==NULL) { |
AxedaCorp | 0:65004368569c | 540 | return AX_GEN_PARSE_ERR; |
AxedaCorp | 0:65004368569c | 541 | } |
AxedaCorp | 0:65004368569c | 542 | printDebug("Creating software packages\n"); |
AxedaCorp | 0:65004368569c | 543 | temp=cJSON_GetObjectItem(resp_int, "packages"); |
AxedaCorp | 0:65004368569c | 544 | if(temp!=NULL) { |
AxedaCorp | 0:65004368569c | 545 | //Handle a software package here |
AxedaCorp | 0:65004368569c | 546 | int ctr=0, pkg_ctr2=0; |
AxedaCorp | 0:65004368569c | 547 | int sz=cJSON_GetArraySize(temp); |
AxedaCorp | 0:65004368569c | 548 | int instructionCt=0; |
AxedaCorp | 0:65004368569c | 549 | ax_package *temp_package; |
AxedaCorp | 0:65004368569c | 550 | |
AxedaCorp | 0:65004368569c | 551 | for(ctr=0; ctr<sz; ctr++) |
AxedaCorp | 0:65004368569c | 552 | { |
AxedaCorp | 0:65004368569c | 553 | printDebug("Parsing package[]...\n"); |
AxedaCorp | 0:65004368569c | 554 | temp_child=cJSON_GetArrayItem(temp, ctr); |
AxedaCorp | 0:65004368569c | 555 | //Create an ax_package for this |
AxedaCorp | 0:65004368569c | 556 | temp_package=(ax_package *)malloc(sizeof(ax_package)); |
AxedaCorp | 0:65004368569c | 557 | char *pkgID=cJSON_GetObjectItem(temp_child, "id")->valuestring; |
AxedaCorp | 0:65004368569c | 558 | retVal=ax_pkg_createPackage(temp_package, pkgID, 0, AX_NO_PRIORITY); |
AxedaCorp | 0:65004368569c | 559 | temp_package->priority=cJSON_GetObjectItem(temp_child, "priority")->valueint; |
AxedaCorp | 0:65004368569c | 560 | temp_package->time=cJSON_GetObjectItem(temp_child, "time")->valueint; |
AxedaCorp | 0:65004368569c | 561 | //add Instructions to the package |
AxedaCorp | 0:65004368569c | 562 | instructions=cJSON_GetObjectItem(temp_child, "instructions"); |
AxedaCorp | 0:65004368569c | 563 | instructionCt=cJSON_GetArraySize(instructions); |
AxedaCorp | 0:65004368569c | 564 | for(pkg_ctr2=0; pkg_ctr2<instructionCt; pkg_ctr2++) |
AxedaCorp | 0:65004368569c | 565 | { |
AxedaCorp | 0:65004368569c | 566 | //int instrType=-1; |
AxedaCorp | 0:65004368569c | 567 | printDebug("Parsing instruction\n"); |
AxedaCorp | 0:65004368569c | 568 | instruction_child=cJSON_GetArrayItem(instructions, pkg_ctr2); |
AxedaCorp | 0:65004368569c | 569 | |
AxedaCorp | 0:65004368569c | 570 | if(strcmp("down", cJSON_GetObjectItem(instruction_child, "@type")->valuestring)==0) { |
AxedaCorp | 0:65004368569c | 571 | cJSON *id=cJSON_GetObjectItem(instruction_child, "id"); |
AxedaCorp | 0:65004368569c | 572 | char *s_id = NULL; |
AxedaCorp | 0:65004368569c | 573 | if(id != NULL){ |
AxedaCorp | 0:65004368569c | 574 | s_id=id->valuestring; |
AxedaCorp | 0:65004368569c | 575 | } |
AxedaCorp | 0:65004368569c | 576 | char *s_path = NULL; |
AxedaCorp | 0:65004368569c | 577 | //path is optional so we need to make sure it is here before trying to get the valuestring |
AxedaCorp | 0:65004368569c | 578 | cJSON *path = cJSON_GetObjectItem(instruction_child, "fp"); |
AxedaCorp | 0:65004368569c | 579 | if(path != NULL){ |
AxedaCorp | 0:65004368569c | 580 | s_path=path->valuestring; |
AxedaCorp | 0:65004368569c | 581 | } |
AxedaCorp | 0:65004368569c | 582 | else{ |
AxedaCorp | 0:65004368569c | 583 | path = cJSON_GetObjectItem(instruction_child, "path"); |
AxedaCorp | 0:65004368569c | 584 | if(path != NULL){ |
AxedaCorp | 0:65004368569c | 585 | s_path=path->valuestring; |
AxedaCorp | 0:65004368569c | 586 | } |
AxedaCorp | 0:65004368569c | 587 | } |
AxedaCorp | 0:65004368569c | 588 | char *s_filename = NULL; |
AxedaCorp | 0:65004368569c | 589 | cJSON *fn = cJSON_GetObjectItem(instruction_child, "fn"); |
AxedaCorp | 0:65004368569c | 590 | if(fn != NULL){ |
AxedaCorp | 0:65004368569c | 591 | s_filename=fn->valuestring; |
AxedaCorp | 0:65004368569c | 592 | } |
AxedaCorp | 0:65004368569c | 593 | else{ |
AxedaCorp | 0:65004368569c | 594 | path = cJSON_GetObjectItem(instruction_child, "filename"); |
AxedaCorp | 0:65004368569c | 595 | if(path != NULL){ |
AxedaCorp | 0:65004368569c | 596 | s_path=path->valuestring; |
AxedaCorp | 0:65004368569c | 597 | } |
AxedaCorp | 0:65004368569c | 598 | } |
AxedaCorp | 0:65004368569c | 599 | retVal=ax_pkg_addDLInstruction(temp_package, s_id, s_path, s_filename); |
AxedaCorp | 0:65004368569c | 600 | } |
AxedaCorp | 0:65004368569c | 601 | //if it's not a download instruction, we don't care; down was the only one available in AMMP1.0 |
AxedaCorp | 0:65004368569c | 602 | } |
AxedaCorp | 0:65004368569c | 603 | //Now we tell someone that we've got a software package |
AxedaCorp | 0:65004368569c | 604 | scm_download_req(temp_package); |
AxedaCorp | 0:65004368569c | 605 | } |
AxedaCorp | 0:65004368569c | 606 | } |
AxedaCorp | 0:65004368569c | 607 | int dictr1=0; |
AxedaCorp | 0:65004368569c | 608 | //Set Data Item Commands will occur here. |
AxedaCorp | 0:65004368569c | 609 | temp=NULL; |
AxedaCorp | 0:65004368569c | 610 | temp_child=NULL; |
AxedaCorp | 0:65004368569c | 611 | instructions=NULL; |
AxedaCorp | 0:65004368569c | 612 | instruction_child=NULL; |
AxedaCorp | 0:65004368569c | 613 | |
AxedaCorp | 0:65004368569c | 614 | printDebug("Setting Data Item Commands\n"); |
AxedaCorp | 0:65004368569c | 615 | temp=cJSON_GetObjectItem(resp_int, "set"); |
AxedaCorp | 0:65004368569c | 616 | if(temp!=NULL){ |
AxedaCorp | 0:65004368569c | 617 | int disz=cJSON_GetArraySize(temp); |
AxedaCorp | 0:65004368569c | 618 | for(dictr1=0; dictr1<disz; dictr1++) |
AxedaCorp | 0:65004368569c | 619 | { |
AxedaCorp | 0:65004368569c | 620 | temp_child=cJSON_GetArrayItem(temp, dictr1); |
AxedaCorp | 0:65004368569c | 621 | instructions=cJSON_GetObjectItem(temp_child, "dataItems"); |
AxedaCorp | 0:65004368569c | 622 | instruction_child=instructions->child; |
AxedaCorp | 0:65004368569c | 623 | while(instruction_child!=NULL){ |
AxedaCorp | 0:65004368569c | 624 | if(instruction_child->type==cJSON_String) { |
AxedaCorp | 0:65004368569c | 625 | data_item_write(instruction_child->string, instruction_child->valuestring, 0, AX_STRING); |
AxedaCorp | 0:65004368569c | 626 | } |
AxedaCorp | 0:65004368569c | 627 | else if(instruction_child->type==cJSON_False) { |
AxedaCorp | 0:65004368569c | 628 | data_item_write(instruction_child->string, NULL, AX_FALSE, AX_DIGITAL); |
AxedaCorp | 0:65004368569c | 629 | } |
AxedaCorp | 0:65004368569c | 630 | else if(instruction_child->type==cJSON_True) { |
AxedaCorp | 0:65004368569c | 631 | data_item_write(instruction_child->string, NULL, AX_TRUE, AX_DIGITAL); |
AxedaCorp | 0:65004368569c | 632 | } |
AxedaCorp | 0:65004368569c | 633 | else { |
AxedaCorp | 0:65004368569c | 634 | data_item_write(instruction_child->string, NULL, instruction_child->valuedouble, AX_ANALOG); |
AxedaCorp | 0:65004368569c | 635 | } |
AxedaCorp | 0:65004368569c | 636 | instruction_child=instruction_child->next; |
AxedaCorp | 0:65004368569c | 637 | } |
AxedaCorp | 0:65004368569c | 638 | |
AxedaCorp | 0:65004368569c | 639 | } |
AxedaCorp | 0:65004368569c | 640 | } |
AxedaCorp | 0:65004368569c | 641 | //Data Item Poll requests here. |
AxedaCorp | 0:65004368569c | 642 | printDebug("Setting Data Item Poll requests\n"); |
AxedaCorp | 0:65004368569c | 643 | int dictr2=0; |
AxedaCorp | 0:65004368569c | 644 | temp=NULL; |
AxedaCorp | 0:65004368569c | 645 | temp_child=NULL; |
AxedaCorp | 0:65004368569c | 646 | instructions=NULL; |
AxedaCorp | 0:65004368569c | 647 | instruction_child=NULL; |
AxedaCorp | 0:65004368569c | 648 | temp=cJSON_GetObjectItem(resp_int, "send"); |
AxedaCorp | 0:65004368569c | 649 | if(temp!=NULL){ |
AxedaCorp | 0:65004368569c | 650 | int dissz=cJSON_GetArraySize(temp); |
AxedaCorp | 0:65004368569c | 651 | for(dictr2=0; dictr2<dissz; dictr2++) { |
AxedaCorp | 0:65004368569c | 652 | temp_child=cJSON_GetArrayItem(temp, dictr2); |
AxedaCorp | 0:65004368569c | 653 | instructions=cJSON_GetObjectItem(temp_child, "dataItems"); |
AxedaCorp | 0:65004368569c | 654 | instruction_child=instructions->child; |
AxedaCorp | 0:65004368569c | 655 | while(instruction_child!=NULL){ |
AxedaCorp | 0:65004368569c | 656 | data_item_request(instruction_child->valuestring); |
AxedaCorp | 0:65004368569c | 657 | instruction_child=instruction_child->next; |
AxedaCorp | 0:65004368569c | 658 | } |
AxedaCorp | 0:65004368569c | 659 | } |
AxedaCorp | 0:65004368569c | 660 | } |
AxedaCorp | 0:65004368569c | 661 | |
AxedaCorp | 0:65004368569c | 662 | cJSON_Delete(resp_int);//dispose of the cJSON object |
AxedaCorp | 0:65004368569c | 663 | free(response->body); |
AxedaCorp | 0:65004368569c | 664 | |
AxedaCorp | 0:65004368569c | 665 | |
AxedaCorp | 0:65004368569c | 666 | return retVal; |
AxedaCorp | 0:65004368569c | 667 | } |
AxedaCorp | 0:65004368569c | 668 | |
AxedaCorp | 0:65004368569c | 669 | |
AxedaCorp | 0:65004368569c | 670 |