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 revert by
axPlatform.c
00001 /************************************************************************************/ 00002 /* axPlatform.c */ 00003 /* 2013 Axeda Corporation */ 00004 /* */ 00005 /* Defines methods for interaction with end points on the Axeda Platform. This */ 00006 /* is a device independent implementation which can be applied to any device that */ 00007 /* supports ANSI C. */ 00008 /************************************************************************************/ 00009 00010 #include "axPlatform.h" 00011 #include "axStatusCodes.h" 00012 #include <string.h> 00013 #include <stdlib.h> 00014 #include "axTransport.h" 00015 #include "axSerializer.h" 00016 #include "cJSON.h" 00017 #include "axConstants.h" 00018 #include "axHTTP.h" 00019 00020 int handleResponse(HTTP_Transmission *response); 00021 00022 static const char *endpoints[8]= { "ammp", "data", "assets", "files", " ", "packages", "status", " "}; 00023 static const char *contentTypes[]= { "application/json", "multipart/form-data"}; 00024 static const char *buffer_keywords[]= {"alarms", "events", "data", "locations" }; 00025 00026 const char URL_SEP='/'; 00027 const char ID_SEP='!'; 00028 00029 /************************************************************************************/ 00030 /*ax_platform_upload() */ 00031 /* */ 00032 /*file(required) : a pointer to a structure that the data will be stored in. */ 00033 /*name (required): a file name for the file. Can be arbitrarily assigned based on */ 00034 /* source of the data. */ 00035 /*hint(required): a string that allows you to tag the file for later retrieval */ 00036 /*size(optional): should be populated if the data does not have an EOF character at */ 00037 /* the end. If sending a memory block this will define the offset. */ 00038 /*data(required): a pointer to the data that will be sent as this file */ 00039 /* */ 00040 /* */ 00041 /************************************************************************************/ 00042 int ax_platform_upload(ax_platform *cloud, ax_deviceID *device, ax_file *file) 00043 { 00044 int retVal=AX_UNKNOWN; 00045 char *url=NULL; 00046 HTTP_Part fileDat; 00047 HTTP_Transmission response; 00048 fileDat.data=file->data; 00049 fileDat.data_sz=file->size; 00050 fileDat.file_name=file->name; 00051 fileDat.hint=file->hint; 00052 fileDat.next=NULL; 00053 00054 url = getFileResource(url, device); 00055 00056 int body_sz=strlen(file->hint)+12+strlen(file->name); 00057 char *body=malloc(sizeof(char)*body_sz); 00058 int bodyWrt=snprintf(body, body_sz, "name=\"hint\" \r\n %s",file->hint); 00059 if(bodyWrt>body_sz) { retVal=AX_GEN_STR_TRUNC; } 00060 printDebug(body); 00061 00062 retVal=http_send_mpost(url, cloud->hostname, cloud->port, cloud->secure, NULL, NULL, 0, &fileDat, 1, &response); 00063 00064 free(body); 00065 free(url); 00066 00067 return retVal; 00068 } 00069 00070 /************************************************************************************/ 00071 /* ax_platform_ping() */ 00072 /* */ 00073 /* This function creates a ping message which acts as the device heartbeat. */ 00074 /* */ 00075 /* */ 00076 /************************************************************************************/ 00077 int ax_platform_ping(ax_platform *cloud, ax_deviceID *device) 00078 { 00079 int retVal=AX_UNKNOWN; 00080 char *url=NULL; 00081 HTTP_Headers myHeader; 00082 HTTP_Transmission response; 00083 myHeader.contentType=getGeneralType(myHeader.contentType); 00084 url=getAgentResource(url, device); 00085 00086 //Send the request 00087 retVal= http_send_post(url, cloud->hostname, cloud->port, cloud->secure, &myHeader, NULL, 0, &response); 00088 //Scan the response and act if there are egress messages. 00089 handleResponse(&response); 00090 free(url); 00091 return retVal; 00092 } 00093 00094 /************************************************************************************/ 00095 /*ax_platform_download() */ 00096 /* */ 00097 /*This function wil request a file from the platform with a specific file ID. The */ 00098 /*fileID itself will be transmitted down on a response message from the platform. */ 00099 /* */ 00100 /* */ 00101 /************************************************************************************/ 00102 int ax_platform_download(ax_platform *cloud, ax_deviceID *device, ax_package_instruction *instr) 00103 { 00104 int retVal = AX_UNKNOWN; 00105 char *url=NULL; 00106 HTTP_Transmission response; 00107 url=getFileDownloadResource(url, device, instr->file_id); 00108 retVal=http_send_get(url, cloud->hostname, cloud->port, cloud->secure, &response); 00109 //TODO: revisit what to do with response in this case. 00110 scm_file_write(instr->filename, response.body, response.body_length, instr); 00111 free(url); 00112 return retVal; 00113 } 00114 00115 00116 /************************************************************************************/ 00117 /* ax_platform_register() */ 00118 /* */ 00119 /*This function creates a registration message to be sent to the cloud. The message */ 00120 /*contains information about the model, serial and expected ping interval. It also */ 00121 /*allows the cloud to mark the device as online. If using the standalone thread func*/ 00122 /*-tion this method will be called automatically until successful. */ 00123 /* */ 00124 /*cloud(required) : a pointer to a structure that contains data about the cloud */ 00125 /*device(required) : a pointer to a structure that contains the model and serial */ 00126 /*pingRate(required) : an integer in milliseconds which tells the cloud how often to*/ 00127 /* expect a heartbeat ping */ 00128 /* */ 00129 /*Returns: an integer value indicating whether or not it successfully registered */ 00130 /************************************************************************************/ 00131 int ax_platform_register(ax_platform *cloud, ax_deviceID *device) 00132 { 00133 int retVal=AX_UNKNOWN; 00134 char *url=NULL; 00135 char *fullRequest=NULL; 00136 cJSON *requestBody; 00137 HTTP_Headers myHeader; 00138 HTTP_Transmission response; 00139 myHeader.contentType=getGeneralType(myHeader.contentType); 00140 url = getRegistrationResource(url, device); 00141 int urlLength=strlen(url); 00142 url[urlLength]='\0'; 00143 00144 requestBody=getRegistrationJSON(device, cloud->ping_rate); 00145 00146 fullRequest=cJSON_PrintUnformatted(requestBody); 00147 int contentLength=strlen(fullRequest); 00148 00149 retVal= http_send_post(url, cloud->hostname, cloud->port, cloud->secure, &myHeader, fullRequest, contentLength, &response); 00150 //Scan the response and act if there are egress messages. 00151 handleResponse(&response); 00152 00153 //Clean up after ourselves 00154 free(fullRequest); 00155 free(url); 00156 cJSON_Delete(requestBody); 00157 return retVal; 00158 } 00159 00160 /**************************************************************************************/ 00161 /*ax_platform_send() */ 00162 /* */ 00163 /*This function sends any data available in the structures directly to the cloud in */ 00164 /*an on demand fashion. */ 00165 /* */ 00166 /* */ 00167 /*cloud(required) : a pointer to a structure that contains the cloud service info */ 00168 /*device(required) : a pointer to a structure that contains device information */ 00169 /*dataItems(optional) : a pointer to an array of ax_dataItem pointers that will be sent*/ 00170 /*alarms(optional) : a pointer to an array of ax_alarm pointers that will be sent */ 00171 /*events(optional) : a pointer to an array of ax_event pointers that will be sent */ 00172 /*locations(optional) : a pointer to an array of ax_location pointers that will be sent*/ 00173 /* */ 00174 /*Returns: an integer value indicating whether or not it successfully sent the data */ 00175 /**************************************************************************************/ 00176 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) { 00177 00178 int retVal=AX_UNKNOWN; 00179 HTTP_Headers myHeader; 00180 char *url=NULL; 00181 00182 char *fullRequest=NULL; 00183 cJSON *rootNode=NULL; 00184 rootNode=cJSON_CreateObject(); 00185 HTTP_Transmission response; 00186 zeroOutHTTPXmission(&response); 00187 //add the data in the DataItems queue if passed 00188 if(dataItems){ 00189 cJSON_AddItemToObject(rootNode, buffer_keywords[BUFF_DATA], dataSet2JSON((ax_dataSet **)dataItems, numDataSets, terse_enable)); 00190 } 00191 //add all alarms to the transmission if passed 00192 if(alarms){ 00193 cJSON_AddItemToObject(rootNode, buffer_keywords[BUFF_ALARMS], AlarmsToJSON((ax_alarm **)alarms, numAlarms, terse_enable)); 00194 } 00195 if(events){ 00196 cJSON_AddItemToObject(rootNode, buffer_keywords[BUFF_EVENTS], eventsToJSON((ax_event **)events, numEvents, terse_enable)); 00197 } 00198 if(locations){ 00199 cJSON_AddItemToObject(rootNode, buffer_keywords[BUFF_LOCATIONS], locationsToJSON((ax_location **)locations, numLocations, terse_enable)); 00200 } 00201 00202 myHeader.contentType=getGeneralType(myHeader.contentType); 00203 url = getDataResource(url, device); 00204 fullRequest=cJSON_PrintUnformatted(rootNode); 00205 00206 retVal= http_send_post(url, cloud->hostname, cloud->port, cloud->secure, &myHeader, fullRequest, strlen(fullRequest), &response); 00207 //Scan the response and act if there are egress messages. 00208 handleResponse(&response); 00209 00210 if(fullRequest) { 00211 free(fullRequest); 00212 } 00213 free(url); 00214 cJSON_Delete(rootNode); 00215 00216 return retVal; 00217 } 00218 00219 /**************************************************************************************/ 00220 /*ax_platform_sendData() */ 00221 /* */ 00222 /*This function immedately sends any data included in the parameter to the platform */ 00223 /*listed. It makes use of the ax_platform_send() function as a special case. */ 00224 /* */ 00225 /*cloud(required) : a pointer to a structure that contains the cloud service info */ 00226 /*device(required) : a pointer to a structure that contains device information */ 00227 /*dataItems(required) : pointer to an array of ax_dataItem pointers that will be sent */ 00228 /* */ 00229 /*Returns: an integer value indicating whether or not it successfully sent the data */ 00230 /**************************************************************************************/ 00231 int ax_platform_sendData(ax_platform *cloud, ax_deviceID *device, ax_dataSet *dataItems[], int numDataSets) { 00232 00233 return ax_platform_send(cloud, device, dataItems, numDataSets, NULL, 0, NULL, 0, NULL, 0); 00234 00235 } 00236 /**************************************************************************************/ 00237 /*ax_platform_sendAlarms() */ 00238 /* */ 00239 /*This function immedately sends any alarms included in the parameter to the platform */ 00240 /*listed. It makes use of the ax_platform_send() function as a special case. */ 00241 /* */ 00242 /*cloud(required) : a pointer to a structure that contains the cloud service info */ 00243 /*device(required) : a pointer to a structure that contains device information */ 00244 /*alarms(required) : a pointer to an array of ax_alarm pointers that will be sent */ 00245 /* */ 00246 /*Returns: an integer value indicating whether or not it successfully sent the data */ 00247 /**************************************************************************************/ 00248 int ax_platform_sendAlarms(ax_platform *cloud, ax_deviceID *device, ax_alarm *alarms[], int numAlarms) { 00249 00250 return ax_platform_send(cloud, device, NULL, 0, alarms, numAlarms, NULL, 0, NULL, 0); 00251 00252 } 00253 /**************************************************************************************/ 00254 /*ax_platform_sendEvents() */ 00255 /* */ 00256 /*This function immedately sends any events included in the parameter to the platform */ 00257 /*listed. It makes use of the ax_platform_send() function as a special case. */ 00258 /* */ 00259 /*cloud(required) : a pointer to a structure that contains the cloud service info */ 00260 /*device(required) : a pointer to a structure that contains device information */ 00261 /*events(required) : a pointer to an array of ax_event pointers that will be sent */ 00262 /* */ 00263 /*Returns: an integer value indicating whether or not it successfully sent the data */ 00264 /**************************************************************************************/ 00265 int ax_platform_sendEvents(ax_platform *cloud, ax_deviceID *device, ax_event *events[], int numEvents) { 00266 00267 return ax_platform_send(cloud, device, NULL, 0, NULL, 0, events, numEvents, NULL, 0); 00268 00269 } 00270 /**************************************************************************************/ 00271 /*ax_platform_sendLocations() */ 00272 /* */ 00273 /*This function immedately sends any events included in the parameter to the platform */ 00274 /*listed. It makes use of the ax_platform_send() function as a special case. */ 00275 /* */ 00276 /*cloud(required) : a pointer to a structure that contains the cloud service info */ 00277 /*device(required) : a pointer to a structure that contains device information */ 00278 /*locations(required) : a pointer to an array of ax_location poitners that will be sent*/ 00279 /* */ 00280 /*Returns: an integer value indicating whether or not it successfully sent the data */ 00281 /**************************************************************************************/ 00282 int ax_platform_sendLocations(ax_platform *cloud, ax_deviceID *device, ax_location *locations[], int numLocations) { 00283 00284 return ax_platform_send(cloud, device, NULL, 0, NULL, 0, NULL, 0, locations, numLocations); 00285 00286 } 00287 00288 /**************************************************************************************/ 00289 /*ax_platform_setPkgStatus() */ 00290 /* */ 00291 /*Tells the platform what state the package is currently in. This is necessary for the*/ 00292 /*lifecycle of the packages in the Axeda System. */ 00293 /* */ 00294 /**************************************************************************************/ 00295 int ax_platform_setPkgStatus(ax_platform *cloud, ax_deviceID *device, char *pkgID, int status, char *errorMsg) { 00296 int retVal=AX_UNKNOWN; 00297 char *url=NULL; 00298 char *fullRequest=NULL; 00299 cJSON *requestBody=NULL; 00300 HTTP_Headers myHeader; 00301 HTTP_Transmission response; 00302 zeroOutHTTPXmission(&response); 00303 00304 requestBody= getPKGStatusJSON(status, errorMsg, AX_NO_PRIORITY, 0, terse_enable); 00305 00306 myHeader.contentType=getGeneralType(myHeader.contentType); 00307 url=getPackageUpdateResource(url, device, pkgID); 00308 int urlLength=strlen(url); 00309 url[urlLength]='\0'; 00310 00311 fullRequest=cJSON_PrintUnformatted(requestBody); 00312 int contentLength=strlen(fullRequest); 00313 //Send the status 00314 retVal=http_send_put(url, cloud->hostname, cloud->port, cloud->secure, &myHeader, fullRequest, contentLength, &response); 00315 //Scan the response and act if there are egress messages. 00316 handleResponse(&response); 00317 00318 //Clean up after ourselves 00319 free(fullRequest); 00320 free(url); 00321 cJSON_Delete(requestBody); 00322 00323 return retVal; 00324 } 00325 /**************************************************************************************/ 00326 /*ax_platform_setPkgStatus() */ 00327 /* */ 00328 /*Tells the platform what state the package is currently in. This is necessary for the*/ 00329 /*lifecycle of the packages in the Axeda System. */ 00330 /* */ 00331 /**************************************************************************************/ 00332 int ax_platform_setPkgStatusStarted(ax_platform *cloud, ax_deviceID *device, char *pkgID) { 00333 return ax_platform_setPkgStatus(cloud, device, pkgID, AX_PKG_STARTED, NULL); 00334 } 00335 /**************************************************************************************/ 00336 /*ax_platform_setPkgStatus() */ 00337 /* */ 00338 /*Tells the platform what state the package is currently in. This is necessary for the*/ 00339 /*lifecycle of the packages in the Axeda System. */ 00340 /* */ 00341 /**************************************************************************************/ 00342 int ax_platform_setPkgStatusQueued(ax_platform *cloud, ax_deviceID *device, char *pkgID) { 00343 return ax_platform_setPkgStatus(cloud, device, pkgID, AX_PKG_QUEUED, NULL); 00344 } 00345 /**************************************************************************************/ 00346 /*ax_platform_setPkgStatus() */ 00347 /* */ 00348 /*Tells the platform what state the package is currently in. This is necessary for the*/ 00349 /*lifecycle of the packages in the Axeda System. */ 00350 /* */ 00351 /**************************************************************************************/ 00352 int ax_platform_setPkgStatusSuccess(ax_platform *cloud, ax_deviceID *device, char *pkgID) { 00353 return ax_platform_setPkgStatus(cloud, device, pkgID, AX_PKG_SUCCESS, NULL); 00354 } 00355 /**************************************************************************************/ 00356 /*ax_platform_setPkgStatus() */ 00357 /* */ 00358 /*Tells the platform what state the package is currently in. This is necessary for the*/ 00359 /*lifecycle of the packages in the Axeda System. */ 00360 /* */ 00361 /**************************************************************************************/ 00362 int ax_platform_setPkgStatusFailed(ax_platform *cloud, ax_deviceID *device, char *pkgID, char *errorMsg) { 00363 return ax_platform_setPkgStatus(cloud, device, pkgID, AX_PKG_FAILURE, errorMsg); 00364 } 00365 00366 /***************************************************************************************************************************************************************/ 00367 /***************************************************************************************************************************************************************/ 00368 /*The code in the following sections should never need to be called as it will be called from the preceeding functions. */ 00369 /***************************************************************************************************************************************************************/ 00370 /***************************************************************************************************************************************************************/ 00371 00372 /************************************************************************************/ 00373 /* The following methods construct references to endpoints on the platform where the */ 00374 /*respective data will be sent. For the sake of convenience they all return a pointer*/ 00375 /*that is equal in value to that which was passed in. */ 00376 /* They all take the same arguments: */ 00377 /* */ 00378 /* endPointBuff = The pointer to where the endpoint will be stored. This pointer */ 00379 /* will be allocated and populated by the function */ 00380 /* ax_deviceID = A structure that contains the model and serial number of the current*/ 00381 /* device. This structure should be the same as the one constructed at */ 00382 /* startup based on the arguments. */ 00383 /************************************************************************************/ 00384 char *getDataResource(char *endPointBuff, ax_deviceID *device) 00385 { 00386 return getResource(endPointBuff, device, END_DATA); 00387 } 00388 00389 char *getAgentResource(char *endPointBuff, ax_deviceID *device) 00390 { 00391 return getResource(endPointBuff, device, END_AGENTS); 00392 } 00393 00394 char *getFileResource(char *endPointBuff, ax_deviceID *device) 00395 { 00396 return getResource(endPointBuff, device, END_FILES); 00397 } 00398 00399 char *getRegistrationResource(char *endPointBuff, ax_deviceID *device) 00400 { 00401 return getResource(endPointBuff, device, END_REG); 00402 } 00403 char *getFileDownloadResource(char *endPointBuff, ax_deviceID *device, char *fileID) { 00404 //since this url is slightly different from all the others we need to override the standard passing. 00405 char *tempBuff=NULL; 00406 tempBuff=encodeAgentID(device, tempBuff); 00407 int len=strlen(endpoints[END_BASE])+strlen(endpoints[END_PACKAGES])+6+strlen(tempBuff)+strlen(fileID)+strlen(endpoints[END_FILES])+1+strlen(PROTOCOL_VERSION)+1; 00408 endPointBuff = (char *)calloc(len,sizeof(char)); 00409 // /ammp/packages/1/files/test_model!test_serial/12345 00410 // , 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 00411 // %c%s%c%s%c%s%c%s%c%s%c%s 00412 00413 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 ); 00414 free(tempBuff); 00415 00416 return endPointBuff; 00417 } 00418 00419 char *getPackageUpdateResource(char *endPointBuff, ax_deviceID *device, char *packageID){ 00420 //since this url is slightly different from all the others we need to override the standard passing. 00421 // "/ammp/packages/1/12345/status/test_model!test_serial" 00422 char *tempBuff=NULL; 00423 tempBuff=encodeAgentID(device, tempBuff); 00424 int len=6+strlen(endpoints[END_BASE])+strlen(endpoints[END_PACKAGES])+strlen(PROTOCOL_VERSION)+strlen(packageID)+strlen(endpoints[END_STATUS])+strlen(tempBuff)+1; 00425 endPointBuff = (char *)calloc(len, sizeof(char)); 00426 00427 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); 00428 free(tempBuff); 00429 00430 return endPointBuff; 00431 } 00432 00433 char *getResource(char *endPointBuff, ax_deviceID *device, int resourceType) 00434 { 00435 //Check for bounds on the endpoints array. END_REG is currently the highest, if it's OOB return the agent default URL 00436 int resType=END_AGENTS; 00437 if((resourceType<0)||(resourceType>END_REG)) { resType=END_AGENTS; } 00438 else { resType=resourceType; } 00439 int len = strlen(endpoints[END_BASE])+strlen(endpoints[resType])+6+strlen(device->model)+strlen(device->serial); 00440 endPointBuff = (char *)calloc(len+1, sizeof(char)); 00441 char *tempBuff=NULL; 00442 switch(resType) { 00443 case END_REG: 00444 snprintf(endPointBuff, len+1, "%c%s%c%s%c%s", URL_SEP, endpoints[END_BASE], URL_SEP, endpoints[END_AGENTS], URL_SEP, PROTOCOL_VERSION); 00445 break; 00446 case END_FILED: 00447 00448 break; 00449 default: 00450 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)); 00451 free(tempBuff); //only used for storing the deviceID it's work is done now. 00452 break; 00453 } 00454 00455 return endPointBuff; 00456 } 00457 00458 00459 /**************************************************************************************/ 00460 /*encodeAgentID() */ 00461 /* */ 00462 /*A utility method to convert the ax_deviceID structure into a protocol compliant */ 00463 /*identifier string. Used mostly by the registration message */ 00464 /* */ 00465 /*device(required) : a pointer to a structure that contains the model, serial, tenant*/ 00466 /*buff(required) : a pointer to a char array where the output will be stored. */ 00467 /* */ 00468 /*Returns: a pointer to the char array, same as *buff */ 00469 /**************************************************************************************/ 00470 char* encodeAgentID(ax_deviceID *device, char *buff) 00471 { 00472 //TODO: Add logic to URL Encode output string if special characters are encountered... 00473 int len=0; 00474 if(strlen(device->tenant)>0) 00475 { 00476 len=strlen(device->model)+strlen(device->serial)+strlen(device->tenant)+4; 00477 buff = (char *)calloc(len, sizeof(char)); 00478 //buff[len]='\0'; 00479 snprintf(buff, len, "%s@%s!%s", device->model, device->tenant, device->serial ); 00480 } 00481 else 00482 { 00483 len=strlen(device->model)+strlen(device->serial)+3; 00484 buff = (char *)calloc(len, sizeof(char)); 00485 //buff[len]='\0'; 00486 snprintf(buff,len, "%s!%s", device->model, device->serial); 00487 } 00488 00489 printDebug(buff); 00490 00491 return buff; 00492 } 00493 00494 /**************************************************************************************/ 00495 /*getContentType() */ 00496 /* */ 00497 /*A convenience method to allow different messages to have different media types. The */ 00498 /*media types are set forth in the protocol specification. The function will return a */ 00499 /*a pointer to a declared string, for which you do not need to free. */ 00500 /* */ 00501 /* */ 00502 /* */ 00503 /**************************************************************************************/ 00504 00505 char *getContentType(char *contentBuff, int type) { 00506 switch(type) { 00507 case 0: 00508 contentBuff=(char *)contentTypes[MIME_JSON]; 00509 break; 00510 default: 00511 contentBuff=(char *)contentTypes[MIME_JSON]; 00512 break; 00513 } 00514 return contentBuff; 00515 } 00516 00517 char *getGeneralType(char *contentBuff) { 00518 return getContentType(contentBuff, TRANS_TYPE_JSON); 00519 } 00520 00521 /**************************************************************************************/ 00522 /*int handleResponse() */ 00523 /* */ 00524 /*A catch-all method that will handle any egress messages sent from the platform back */ 00525 /*to the device. If the JSON returned is valid it will dispatch the requests as needed*/ 00526 /* */ 00527 /* */ 00528 /* */ 00529 /**************************************************************************************/ 00530 //Possible returns: 00531 // AX_EGR_JSON_PARSE_FAIL -- A failure to parse the JSON that was returned 00532 00533 int handleResponse(HTTP_Transmission *response){ 00534 cJSON *resp_int, *temp, *temp_child, *instructions, *instruction_child; 00535 int retVal=AX_OK; 00536 if(response->body==NULL) {return AX_OK;} //if there's no body, there's nothing to do here. 00537 00538 resp_int=cJSON_Parse(response->body); 00539 if(resp_int==NULL) { 00540 return AX_GEN_PARSE_ERR; 00541 } 00542 printDebug("Creating software packages\n"); 00543 temp=cJSON_GetObjectItem(resp_int, "packages"); 00544 if(temp!=NULL) { 00545 //Handle a software package here 00546 int ctr=0, pkg_ctr2=0; 00547 int sz=cJSON_GetArraySize(temp); 00548 int instructionCt=0; 00549 ax_package *temp_package; 00550 00551 for(ctr=0; ctr<sz; ctr++) 00552 { 00553 printDebug("Parsing package[]...\n"); 00554 temp_child=cJSON_GetArrayItem(temp, ctr); 00555 //Create an ax_package for this 00556 temp_package=(ax_package *)malloc(sizeof(ax_package)); 00557 char *pkgID=cJSON_GetObjectItem(temp_child, "id")->valuestring; 00558 retVal=ax_pkg_createPackage(temp_package, pkgID, 0, AX_NO_PRIORITY); 00559 temp_package->priority=cJSON_GetObjectItem(temp_child, "priority")->valueint; 00560 temp_package->time=cJSON_GetObjectItem(temp_child, "time")->valueint; 00561 //add Instructions to the package 00562 instructions=cJSON_GetObjectItem(temp_child, "instructions"); 00563 instructionCt=cJSON_GetArraySize(instructions); 00564 for(pkg_ctr2=0; pkg_ctr2<instructionCt; pkg_ctr2++) 00565 { 00566 //int instrType=-1; 00567 printDebug("Parsing instruction\n"); 00568 instruction_child=cJSON_GetArrayItem(instructions, pkg_ctr2); 00569 00570 if(strcmp("down", cJSON_GetObjectItem(instruction_child, "@type")->valuestring)==0) { 00571 cJSON *id=cJSON_GetObjectItem(instruction_child, "id"); 00572 char *s_id = NULL; 00573 if(id != NULL){ 00574 s_id=id->valuestring; 00575 } 00576 char *s_path = NULL; 00577 //path is optional so we need to make sure it is here before trying to get the valuestring 00578 cJSON *path = cJSON_GetObjectItem(instruction_child, "fp"); 00579 if(path != NULL){ 00580 s_path=path->valuestring; 00581 } 00582 else{ 00583 path = cJSON_GetObjectItem(instruction_child, "path"); 00584 if(path != NULL){ 00585 s_path=path->valuestring; 00586 } 00587 } 00588 char *s_filename = NULL; 00589 cJSON *fn = cJSON_GetObjectItem(instruction_child, "fn"); 00590 if(fn != NULL){ 00591 s_filename=fn->valuestring; 00592 } 00593 else{ 00594 path = cJSON_GetObjectItem(instruction_child, "filename"); 00595 if(path != NULL){ 00596 s_path=path->valuestring; 00597 } 00598 } 00599 retVal=ax_pkg_addDLInstruction(temp_package, s_id, s_path, s_filename); 00600 } 00601 //if it's not a download instruction, we don't care; down was the only one available in AMMP1.0 00602 } 00603 //Now we tell someone that we've got a software package 00604 scm_download_req(temp_package); 00605 } 00606 } 00607 int dictr1=0; 00608 //Set Data Item Commands will occur here. 00609 temp=NULL; 00610 temp_child=NULL; 00611 instructions=NULL; 00612 instruction_child=NULL; 00613 00614 printDebug("Setting Data Item Commands\n"); 00615 temp=cJSON_GetObjectItem(resp_int, "set"); 00616 if(temp!=NULL){ 00617 int disz=cJSON_GetArraySize(temp); 00618 for(dictr1=0; dictr1<disz; dictr1++) 00619 { 00620 temp_child=cJSON_GetArrayItem(temp, dictr1); 00621 instructions=cJSON_GetObjectItem(temp_child, "dataItems"); 00622 instruction_child=instructions->child; 00623 while(instruction_child!=NULL){ 00624 if(instruction_child->type==cJSON_String) { 00625 data_item_write(instruction_child->string, instruction_child->valuestring, 0, AX_STRING); 00626 } 00627 else if(instruction_child->type==cJSON_False) { 00628 data_item_write(instruction_child->string, NULL, AX_FALSE, AX_DIGITAL); 00629 } 00630 else if(instruction_child->type==cJSON_True) { 00631 data_item_write(instruction_child->string, NULL, AX_TRUE, AX_DIGITAL); 00632 } 00633 else { 00634 data_item_write(instruction_child->string, NULL, instruction_child->valuedouble, AX_ANALOG); 00635 } 00636 instruction_child=instruction_child->next; 00637 } 00638 00639 } 00640 } 00641 //Data Item Poll requests here. 00642 printDebug("Setting Data Item Poll requests\n"); 00643 int dictr2=0; 00644 temp=NULL; 00645 temp_child=NULL; 00646 instructions=NULL; 00647 instruction_child=NULL; 00648 temp=cJSON_GetObjectItem(resp_int, "send"); 00649 if(temp!=NULL){ 00650 int dissz=cJSON_GetArraySize(temp); 00651 for(dictr2=0; dictr2<dissz; dictr2++) { 00652 temp_child=cJSON_GetArrayItem(temp, dictr2); 00653 instructions=cJSON_GetObjectItem(temp_child, "dataItems"); 00654 instruction_child=instructions->child; 00655 while(instruction_child!=NULL){ 00656 data_item_request(instruction_child->valuestring); 00657 instruction_child=instruction_child->next; 00658 } 00659 } 00660 } 00661 00662 cJSON_Delete(resp_int);//dispose of the cJSON object 00663 free(response->body); 00664 00665 00666 return retVal; 00667 } 00668 00669 00670
Generated on Wed Jul 13 2022 02:45:01 by 1.7.2