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