Callisto4Bootloader: ARK/platform_coap.c Source File

Callisto4Bootloader

platform_coap.c
Go to the documentation of this file.
1 /*
2 * platform_coap.c
3 *
4 * Created on: 22 May 2020
5 * Author: Nick Pelling
6 */
7 #include <float.h> // for DBL_MIN / DBL_MAX
8
9 #include "coap.h"
10
11 #include "platform_coap.h"
12 #include "platform_encoder.h"
13
14 // The default payload size to allocate
15 #define DEFAULT_PAYLOAD_BUFFER_SIZE 4096
16
17 // When the payload gets this close to the end of the buffer, double the size of the buffer
18 #define PAYLOAD_REALLOC_TRIGGER_LEVEL 512
19
20 // How many found types to increment the found type buffer by when it runs out of space
21 #define TYPE_ALLOCATION_INCREMENT 100
22
23 // Maximum length of a resource's URI path (e.g. "inputs/1/config")
24 #define RESOURCE_URI_PATH_MAXLEN 100
25
26 typedef enum
27 {
28 eFinalState_Field, // The item specified was an individual field
29 eFinalState_Struct, // The item specified was a struct
30 eFinalState_NotFound, // The item name was not recognised
31 eFinalState_Error // A different error occurred
32 } eFinalState_t;
33
34 /* Forward references */
35
36 static coap_resource_t * CreateResource(
37 const char * pchResourceStr,
38 const char * pchResourceType,
39 const char * pchInterfaceDescription,
40 uint16_t ui16MediaType);
41
42 static void META_Callback( coap_context_t *ctx,
43 struct coap_resource_t *resource,
44 coap_session_t *session,
45 coap_pdu_t *request,
46 coap_binary_t *token,
47 coap_string_t *query,
48 coap_pdu_t *response);
49
50 static void GET_Callback( coap_context_t *ctx,
51 struct coap_resource_t *resource,
52 coap_session_t *session,
53 coap_pdu_t *request,
54 coap_binary_t *token,
55 coap_string_t *query,
56 coap_pdu_t *response);
57
58 static void PUT_Callback( coap_context_t *ctx,
59 struct coap_resource_t *resource,
60 coap_session_t *session,
61 coap_pdu_t *request,
62 coap_binary_t *token,
63 coap_string_t *query,
64 coap_pdu_t *response);
65
66 static eFinalState_t IterateDownwards( stPLATFORM_ObjectData_t * pstObjectData,
67 coap_pdu_t *request,
68 const stPLUGIN_Field_t ** ppstFieldFound);
69
70 static uint32_t UpdateWithFieldData( const stPLUGIN_Field_t *pstField,
71 void *pvObject,
72 uint32_t uiFieldFlags,
73 void **pvObj);
74
75 static eAccess_t GET_StructToJSON( stPayloadBuffer_t * pstPayload,
76 void * pvObject,
77 const stPLUGIN_Type_t * pstType,
78 const stPayloadEncoder_t * pstEncoder,
79 uint32_t uiFieldFlags);
80
81 static eAccess_t GET_ObjectToJSON( stPayloadBuffer_t * pstPayload,
82 void * pvObject,
83 const stPLUGIN_Field_t * pstField,
84 const stPayloadEncoder_t * pstEncoder,
85 uint32_t uiFieldFlags);
86
87 static eAccess_t PUT_StructToJSON( stPayloadBuffer_t * pstPayload,
88 void * pvObject,
89 const stPLUGIN_Type_t * pstType,
90 const stPayloadDecoder_t * pstDecoder,
91 uint32_t uiFieldFlags);
92
93 static eAccess_t PUT_ObjectToJSON( stPayloadBuffer_t * pstPayload,
94 void * pvObject,
95 const stPLUGIN_Field_t * pstField,
96 const stPayloadDecoder_t * pstDecoder,
97 uint32_t uiFieldFlags);
98
99 static eAccess_t META_StructToJSON( stPayloadBuffer_t * pstPayload,
100 void * pvObject,
101 const stPLUGIN_Type_t *pstType,
102 const stPayloadEncoder_t * pstEncoder,
103 uint32_t uiFieldFlags,
104 uint8_t u8Owner);
105
106 static eAccess_t META_ObjectToJSON( stPayloadBuffer_t * pstPayload,
107 void * pvObject,
108 const stPLUGIN_Field_t * pstField,
109 const stPayloadEncoder_t * pstEncoder,
110 uint32_t uiFieldFlags,
111 uint8_t u8Owner);
112
113 /* *************************************************************************
114 *
115 * Local data
116 *
117 * *************************************************************************/
118
119 static coap_context_t * context;
120
121 static coap_resource_t * meta_resource;
122
123 // Array of base types (which should be common between platform and plugins)
124 static const char * const apachBaseTypes[] =
125 {
126 "tInt8",
127 "tInt16",
128 "tInt32",
129 "tInt64",
130 "tUint8",
131 "tUint16",
132 "tUint32",
133 "tUint64",
134 "tBool"
135 };
136
137 /* *************************************************************************
138 *
139 * Public Functions
140 *
141 * *************************************************************************/
142
148 void * CoAP_Initialise(void)
149 {
150 coap_address_t listenaddress;
151
152 coap_address_init( &listenaddress );
153
154 // Looks like a server address, but is used as end point for clients too
155 listenaddress.addr = *(IP_ANY_TYPE);
156 listenaddress.port = COAP_DEFAULT_PORT;
157
158 coap_set_log_level(LOG_DEBUG);
159
160 context = coap_new_context( &listenaddress );
161
162 // Create our meta resource (to describe all the the other resources)
163 // Currently only JSON!
164 meta_resource = CreateResource( "meta", "rt_META", "if_META", COAP_MEDIATYPE_APPLICATION_JSON );
165 if (meta_resource != NULL)
166 {
167 coap_register_handler(meta_resource, COAP_REQUEST_GET, META_Callback);
168 }
169
170 return (void *) context;
171 }
172
180 bool CoAP_CreateResource(stPLATFORM_ObjectData_t * pstObjectData)
181 {
182 coap_resource_t * r;
183
184 r = CreateResource( pstObjectData->pachResourceStr,
185 pstObjectData->pachResourceType,
186 pstObjectData->pachInterfaceDescription,
187 pstObjectData->ui16MediaType);
188 if (r != NULL)
189 {
190 coap_register_handler(r, COAP_REQUEST_PUT, PUT_Callback);
191 coap_register_handler(r, COAP_REQUEST_GET, GET_Callback);
192
193 r->user_data = (void *) pstObjectData;
194 }
195
196 pstObjectData->pvCoAPResource = (void *) r;
197
198 return (r != NULL);
199 }
200
206 void CoAP_ObjectUpdated( const stPLATFORM_ObjectData_t * pstObjectData )
207 {
208 CoapNotifyResourceChange(context, (coap_resource_t *) pstObjectData->pvCoAPResource);
209 }
210
211 /* *************************************************************************
212 *
213 * Local Functions
214 *
215 * *************************************************************************/
216
224 static bool CoAP_ObjectEdited( const stPLATFORM_ObjectData_t * pstObjectData )
225 {
226 bool bRetVal = true;
227
228 if ( pstObjectData != NULL )
229 {
230 if (pstObjectData->pfn_CoAPObjectEdited != NULL)
231 {
232 bRetVal = (*pstObjectData->pfn_CoAPObjectEdited)(pstObjectData);
233 }
234 }
235
236 return bRetVal;
237 }
238
249 static coap_resource_t * CreateResource(
250 const char * pchResourceStr,
251 const char * pchResourceType,
252 const char * pchInterfaceDescription,
253 uint16_t ui16MediaType)
254 {
255 char achQuotedName[100]; // Should be more than big enough for rt= and if= values!
256 coap_resource_t * r;
257
258 r = coap_resource_init( coap_new_str_const((const uint8_t *) pchResourceStr, strlen(pchResourceStr)),
259 COAP_RESOURCE_FLAGS_RELEASE_URI ); // coap_delete_resource() never called for this resource.
260 if (r != NULL)
261 {
262 // This will end up as "ct=NN;" in the CoRE Link Format string
263 snprintf(achQuotedName, sizeof(achQuotedName), "%d", (int) ui16MediaType);
264 coap_add_attr( r,
265 coap_make_str_const("ct"), // content type
266 coap_new_str_const((const uint8_t *) achQuotedName, strlen(achQuotedName)),
267 COAP_ATTR_FLAGS_RELEASE_VALUE );
268
269 // Because the rt value is a string, it must be wrapped in a pair of double quotes
270 snprintf(achQuotedName, sizeof(achQuotedName), "\"%s\"", pchResourceType);
271 coap_add_attr( r,
272 coap_make_str_const("rt"), // resource type
273 coap_new_str_const((const uint8_t *) achQuotedName, strlen(achQuotedName)),
274 COAP_ATTR_FLAGS_RELEASE_VALUE );
275
276 // Because the if value is a string, it must be wrapped in a pair of double quotes
277 snprintf(achQuotedName, sizeof(achQuotedName), "\"%s\"", pchInterfaceDescription);
278 coap_add_attr( r,
279 coap_make_str_const("if"), // interface description
280 coap_new_str_const((const uint8_t *) achQuotedName, strlen(achQuotedName)),
281 COAP_ATTR_FLAGS_RELEASE_VALUE );
282
283 coap_add_resource(context, r);
284 }
285
286 return r;
287 }
288
296 static void META_OutputResourceInfo(const stPayloadEncoder_t *pstEncoder, stPayloadBuffer_t * pstPayload, const stPLATFORM_ObjectData_t * pstObjectData)
297 {
298 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"ResourceName");
299 (*pstEncoder->pfn_EncodeString)(pstPayload, (const uint8_t *)pstObjectData->pachResourceStr);
300
301 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
302
303 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"ResourceType");
304 (*pstEncoder->pfn_EncodeString)(pstPayload, (const uint8_t *)pstObjectData->pachResourceType);
305
306 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
307
308 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"InterfaceDescription");
309 (*pstEncoder->pfn_EncodeString)(pstPayload, (const uint8_t *)pstObjectData->pachInterfaceDescription);
310
311 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
312
313 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"ContentType");
314 (*pstEncoder->pfn_EncodeUnsignedInt)(pstPayload, pstObjectData->ui16MediaType);
315
316 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
317
318 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"DefaultMaxAge");
319 (*pstEncoder->pfn_EncodeSignedInt)(pstPayload, pstObjectData->iMaxAge);
320
321 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
322
323 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"Owner");
324 (*pstEncoder->pfn_EncodeUnsignedInt)(pstPayload, pstObjectData->uiObjectOwnerIndex);
325 }
326
330 const char * apchFieldFlagNames[] =
331 {
332 NULL, // 0 - IsAnObject
333 NULL, // 1 - IsAnArray
334 "ReadFact", // 2 -
335 "ReadComm", // 3 -
336 "ReadLive", // 4 -
337 "WriteFact", // 5 -
338 "WriteComm", // 6 -
339 "WriteLive", // 7 -
340 NULL, // 8 - GetVisibility
341 "Persistent", // 9 - IsPersistent
342 "Managed", // 10 - IsManaged
343 "Live", // 11 - IsLive
344 "NeedsReboot", // 12 - NeedsReboot
345 "Button", // 13 - IsButton
346 "Radio", // 14 - RadioButtons
347 "Hex", // 15 - IsHex
348 "Private", // 16 - IsPrivate
349 };
350
358 static void META_OutputFlagInfo(const stPayloadEncoder_t *pstEncoder, stPayloadBuffer_t * pstPayload, const stPLATFORM_ObjectData_t * pstObjectData)
359 {
360 uint32_t uiFieldFlags;
361 uint32_t i;
362 bool bNeedsComma;
363
364 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"Flags");
365
366 (*pstEncoder->pfn_EncodeArrayStart)(pstPayload);
367
368 uiFieldFlags = pstObjectData->uiFieldFlags;
369 bNeedsComma = false;
370 for (i = 0; i < NUM_ELEMENTS(apchFieldFlagNames); i++)
371 {
372 if ((uiFieldFlags & (1U << i)) && (apchFieldFlagNames[i] != NULL))
373 {
374 if (bNeedsComma)
375 {
376 (*pstEncoder->pfn_EncodeArraySeparator)(pstPayload);
377 }
378 (*pstEncoder->pfn_EncodeString)(pstPayload, (const uint8_t *)apchFieldFlagNames[i]);
379 bNeedsComma = true;
380 }
381 }
382
383 (*pstEncoder->pfn_EncodeArrayEnd)(pstPayload);
384 }
385
393 static bool ThisIsABaseType(const char *pachTypeName)
394 {
395 int i;
396
397 for (i = 0; i < NUM_ELEMENTS(apachBaseTypes); i++)
398 {
399 if (strcmp(pachTypeName, apachBaseTypes[i]) == 0)
400 {
401 return true;
402 }
403 }
404 return false;
405 }
406
412 static void Payload_SetupFoundTypes(stPayloadBuffer_t * pstPayload)
413 {
414 pstPayload->pastFoundTypes = NULL;
415 pstPayload->uiFoundTypesNum = 0;
416 pstPayload->uiFoundTypesAlloced = 0;
417 }
418
427 static bool Payload_BufferAlloc(stPayloadBuffer_t * pstPayload, uint32_t uiSize)
428 {
429 Payload_SetupFoundTypes(pstPayload);
430
431 pstPayload->uiBufferLen = 0;
432 pstPayload->uiBufferSize = uiSize;
433 pstPayload->pau8Buffer = (uint8_t *) malloc(uiSize);
434 pstPayload->bWasMalloced = true;
435
436 return (pstPayload->pau8Buffer != NULL);
437 }
438
446 static bool Payload_BufferRealloc(stPayloadBuffer_t * pstPayload)
447 {
448 bool bRetVal = true;
449 uint32_t uiNewSize;
450
451 if (pstPayload->bWasMalloced)
452 {
453 if (pstPayload->uiBufferLen + PAYLOAD_REALLOC_TRIGGER_LEVEL >= pstPayload->uiBufferSize)
454 {
455 uiNewSize = pstPayload->uiBufferSize * 2;
456 pstPayload->pau8Buffer = (uint8_t *) realloc(pstPayload->pau8Buffer, uiNewSize);
457 pstPayload->uiBufferSize = uiNewSize;
458 if (pstPayload->pau8Buffer == NULL)
459 {
460 pstPayload->uiBufferSize = 0U;
461 bRetVal = false;
462 }
463 }
464 }
465
466 return bRetVal;
467 }
468
476 static void Payload_BufferForce(stPayloadBuffer_t * pstPayload, uint8_t * pau8Buffer, uint32_t uiSize)
477 {
478 Payload_SetupFoundTypes(pstPayload);
479
480 pstPayload->uiBufferLen = 0;
481 pstPayload->uiBufferSize = uiSize;
482 pstPayload->pau8Buffer = pau8Buffer;
483 pstPayload->bWasMalloced = false;
484 }
485
486 /*
487 * Free any memory attached to a payload struct
488 *
489 * @param[in] pstPayload Payload structure
490 */
491 static void Payload_BufferFree(stPayloadBuffer_t * pstPayload)
492 {
493 if ( (pstPayload->bWasMalloced)
494 && (pstPayload->pau8Buffer != NULL) )
495 {
496 free(pstPayload->pau8Buffer);
497 }
498
499 if (pstPayload->pastFoundTypes != NULL)
500 {
501 free(pstPayload->pastFoundTypes);
502 }
503
504 memset(pstPayload, 0, sizeof(*pstPayload));
505 }
506
516 static bool Payload_FindType(stPayloadBuffer_t * pstPayload, uint8_t u8OwnerIndex, const char *pachTypeName)
517 {
518 stFoundType_t * pstFoundType;
519 uint32_t uiIndex;
520 uint32_t uiNum;
521
522 uiNum = pstPayload->uiFoundTypesNum;
523
524 pstFoundType = pstPayload->pastFoundTypes;
525 for (uiIndex = 0U; uiIndex < uiNum; uiIndex++,pstFoundType++)
526 {
527 if ( (u8OwnerIndex == pstFoundType->u8OwnerIndex)
528 && (strcmp(pachTypeName, pstFoundType->pachTypeName) == 0) )
529 {
530 return true; // "Yes, we have already met this named type"
531 }
532 }
533
534 if (uiNum >= pstPayload->uiFoundTypesAlloced)
535 {
536 pstPayload->uiFoundTypesAlloced += TYPE_ALLOCATION_INCREMENT;
537 pstPayload->pastFoundTypes = realloc(pstPayload->pastFoundTypes, pstPayload->uiFoundTypesAlloced * sizeof(stFoundType_t));
538 }
539 pstFoundType = &pstPayload->pastFoundTypes[pstPayload->uiFoundTypesNum++];
540 pstFoundType->u8OwnerIndex = u8OwnerIndex;
541 pstFoundType->pachTypeName = pachTypeName;
542
543 return false; // "No, this is the first time we have seen this named type"
544 }
545
558 static void META_Callback( coap_context_t *ctx,
559 struct coap_resource_t *resource,
560 coap_session_t *session,
561 coap_pdu_t *request,
562 coap_binary_t *token,
563 coap_string_t *query,
564 coap_pdu_t *response)
565 {
566 stPayloadBuffer_t stPayloadBuffer;
567 stPLATFORM_ObjectData_t stObjectData;
568 coap_opt_iterator_t stIterator;
569 coap_opt_t * pstOption;
570 size_t szLen;
571 const uint8_t * pau8Value;
572 uint8_t achUriPath[RESOURCE_URI_PATH_MAXLEN];
573 coap_resource_t * pstMatchingResource;
574 const stPayloadEncoder_t * pstEncoder;
575 stPLATFORM_ObjectData_t * pstObjectData;
576 int i;
577 eAccess_t eAccess;
578 coap_str_const_t coapstr;
579 int iNumResources;
580 int iResourceIndex;
581 coap_resource_t * * papstResourceArray;
582
583 // For now, all meta traffic is JSON (though this may change in future)
584 // e.g. we may want to add a metaCBOR
585 pstEncoder = &stJSONEncoder;
586
587 // Start iterating through all Uri Path options attached to this request
588 pstOption = coap_check_option(request, COAP_OPTION_URI_PATH, &stIterator);
589
590 // Check that the very first part of the URI path is "meta"
591 szLen = coap_opt_length(pstOption);
592 pau8Value = coap_opt_value(pstOption);
593 if ((szLen != 4) || (memcmp(pau8Value, "meta", szLen) != 0))
594 {
595 // 4.00 = Client Error / Bad Request
596 response->code = COAP_RESPONSE_CODE(400);
597 return;
598 }
599 // It was indeed "meta", so we step past it
600 pstOption = coap_option_next(&stIterator);
601
602 for (i = 0; pstOption != NULL; pstOption = coap_option_next(&stIterator))
603 {
604 if (i != 0)
605 {
606 achUriPath[i++] = '/';
607 }
608 szLen = coap_opt_length(pstOption);
609 pau8Value = coap_opt_value(pstOption);
610 // Do not allow code to overflow the achUriPath[] buffer!
611 if (i + szLen > sizeof(achUriPath))
612 {
613 // 5.00 = Server Error: Internal Server Error
614 response->code = COAP_RESPONSE_CODE(500);
615 return;
616 }
617 memcpy(&achUriPath[i], pau8Value, szLen);
618 i += (int) szLen;
619 }
620 achUriPath[i] = 0x00; // Zero-terminate string
621
622 if (Payload_BufferAlloc(&stPayloadBuffer, 2048U) == false)
623 {
624 // 5.00 = Server Error: Internal Server Error
625 response->code = COAP_RESPONSE_CODE(500);
626 return;
627 }
628
629 if (i == 0) // If this is a bare "meta" request
630 {
631 // Count the number of typed resources (i.e. apart from "meta" and "type")
632 iNumResources = 0;
633 {
634 RESOURCES_ITER(context->resources, r)
635 {
636 // If user data is attached, output the resource's metainformation
637 pstObjectData = (stPLATFORM_ObjectData_t *) r->user_data;
638 if (pstObjectData != NULL)
639 {
640 iNumResources++;
641 }
642 }
643 }
644
645 // Allocate an array to hold pointers to each resource with user data
646 papstResourceArray = malloc(iNumResources * sizeof(coap_resource_t * ));
647 if (papstResourceArray == NULL)
648 {
649 Payload_BufferFree(&stPayloadBuffer);
650
651 // 5.00 = Server Error: Internal Server Error
652 response->code = COAP_RESPONSE_CODE(500);
653 return;
654 }
655
656 // Fill the array with pointers to each resource with user data
657 iResourceIndex = 0;
658 {
659 RESOURCES_ITER(context->resources, r)
660 {
661 // If user data is attached, output the resource's metainformation
662 pstObjectData = (stPLATFORM_ObjectData_t *) r->user_data;
663 if ((pstObjectData != NULL) && (iResourceIndex < iNumResources))
664 {
665 papstResourceArray[iResourceIndex++] = r;
666 }
667 }
668 }
669
670 (*pstEncoder->pfn_EncodeArrayStart)(&stPayloadBuffer);
671
672 for (iResourceIndex = 0; iResourceIndex < iNumResources; iResourceIndex++)
673 {
674 if (iResourceIndex != 0)
675 {
676 (*pstEncoder->pfn_EncodeArraySeparator)(&stPayloadBuffer);
677 }
678
679 pstMatchingResource = papstResourceArray[iResourceIndex];
680 pstObjectData = (stPLATFORM_ObjectData_t *) pstMatchingResource->user_data;
681 if (pstObjectData != NULL)
682 {
683 stObjectData = *pstObjectData;
684
685 (*pstEncoder->pfn_EncodeStructStart)(&stPayloadBuffer);
686
687 META_OutputResourceInfo(pstEncoder, &stPayloadBuffer, &stObjectData);
688
689 META_OutputFlagInfo(pstEncoder, &stPayloadBuffer, &stObjectData);
690
691 (*pstEncoder->pfn_EncodeFieldSeparator)(&stPayloadBuffer);
692
693 (*pstEncoder->pfn_EncodeFieldName)(&stPayloadBuffer, (const uint8_t *)"Contents");
694
695 // Output this resource's metainformation (e.g. as JSON)
696 eAccess = META_StructToJSON( &stPayloadBuffer,
697 stObjectData.pvObject,
698 stObjectData.pstType,
699 pstEncoder,
700 stObjectData.uiFieldFlags,
701 stObjectData.uiObjectOwnerIndex );
702
703 (*pstEncoder->pfn_EncodeStructEnd)(&stPayloadBuffer);
704 }
705 }
706
707 (*pstEncoder->pfn_EncodeArrayEnd)(&stPayloadBuffer);
708
709 // Free the array of pointers to resources
710 free(papstResourceArray);
711 }
712 else
713 {
714 // Now use libcoap to search for resources with the name in achUriPath[]
715 coapstr.s = achUriPath;
716 coapstr.length = i;
717 pstMatchingResource = coap_get_resource_from_uri_path(context, &coapstr);
718 if (!pstMatchingResource)
719 {
720 Payload_BufferFree(&stPayloadBuffer);
721
722 // 4.00 = Client Error / Bad Request
723 response->code = COAP_RESPONSE_CODE(400);
724 return;
725 }
726
727 // If no user data is attached, flag this as an internal server error (?)
728 pstObjectData = (stPLATFORM_ObjectData_t *) pstMatchingResource->user_data;
729 if (pstObjectData == NULL)
730 {
731 Payload_BufferFree(&stPayloadBuffer);
732
733 // 5.00 = Server Error: Internal Server Error
734 response->code = COAP_RESPONSE_CODE(500);
735 return;
736 }
737
738 stObjectData = *pstObjectData;
739
740 // Output this resource's metainformation (e.g. as JSON)
741 eAccess = META_StructToJSON( &stPayloadBuffer,
742 stObjectData.pvObject,
743 stObjectData.pstType,
744 pstEncoder,
745 stObjectData.uiFieldFlags,
746 stObjectData.uiObjectOwnerIndex );
747 }
748
749 // If the META stuff ran into any problems...
750 if (eAccess != eAccess_OK)
751 {
752 Payload_BufferFree(&stPayloadBuffer);
753
754 // 5.00 = Server Error: Internal Server Error
755 response->code = COAP_RESPONSE_CODE(500);
756 return;
757 }
758
759 // Put payload into one or more blocked coap response packets
760 coap_add_data_blocked_response(
761 resource,
762 session,
763 request,
764 response,
765 token,
766 stObjectData.ui16MediaType,
767 stObjectData.iMaxAge,
768 (size_t) stPayloadBuffer.uiBufferLen,
769 stPayloadBuffer.pau8Buffer);
770
771 Payload_BufferFree(&stPayloadBuffer);
772
773 // Everything went to plan, so we return a 2.05 "Success - Content" response
774 response->code = COAP_RESPONSE_CODE(205);
775 }
776
789 static void GET_Callback( coap_context_t *ctx,
790 struct coap_resource_t *resource,
791 coap_session_t *session,
792 coap_pdu_t *request,
793 coap_binary_t *token,
794 coap_string_t *query,
795 coap_pdu_t *response)
796 {
797 stPLATFORM_ObjectData_t stObjectData;
798 stPayloadBuffer_t stPayloadBuffer;
799 eFinalState_t eFinalState;
800 eAccess_t eAccess;
801 const stPayloadEncoder_t * pstEncoder;
802 const stPLUGIN_Field_t * pstFieldFound;
803
804 // If there is no object data associated with this callback,
805 // then something has gone badly wrong. :-(
806 if (resource->user_data == NULL)
807 {
808 // 5.00 = Server Error: Internal Server Error
809 response->code = COAP_RESPONSE_CODE(500);
810 return;
811 }
812
813 stObjectData = *((const stPLATFORM_ObjectData_t *) resource->user_data);
814
815 pstEncoder = PayloadEncoder_Get(stObjectData.ui16MediaType);
816 if (pstEncoder == NULL)
817 {
818 // 5.00 = Server Error: Internal Server Error
819 response->code = COAP_RESPONSE_CODE(500);
820 return;
821 }
822
823 if (Payload_BufferAlloc(&stPayloadBuffer, DEFAULT_PAYLOAD_BUFFER_SIZE) == false)
824 {
825 // 5.00 = Server Error: Internal Server Error
826 response->code = COAP_RESPONSE_CODE(500);
827 return;
828 }
829
830 // Continue tracing the URI path down into the structures (i.e. if requesting individual fields / substructures)
831 eFinalState = IterateDownwards(&stObjectData, request, &pstFieldFound);
832 switch (eFinalState)
833 {
834 case eFinalState_Struct:
835 eAccess = GET_StructToJSON( &stPayloadBuffer,
836 stObjectData.pvObject,
837 stObjectData.pstType,
838 pstEncoder,
839 stObjectData.uiFieldFlags);
840 break;
841
842 case eFinalState_Field:
843 (*pstEncoder->pfn_EncodeStructStart)(&stPayloadBuffer);
844 eAccess = GET_ObjectToJSON( &stPayloadBuffer,
845 stObjectData.pvObject,
846 pstFieldFound,
847 pstEncoder,
848 stObjectData.uiFieldFlags);
849 (*pstEncoder->pfn_EncodeStructEnd)(&stPayloadBuffer);
850 break;
851
852 case eFinalState_NotFound:
853 eAccess = eAccess_UnrecognizedFieldName;
854 break;
855
856 case eFinalState_Error:
857 eAccess = eAccess_UnspecifiedError;
858 break;
859 }
860 if (eAccess != eAccess_OK)
861 {
862 // FIXME: how should this respond if it encounters invalid field data etc?
863 }
864
865 // Put payload into one or more blocked coap response packets
866 coap_add_data_blocked_response(
867 resource,
868 session,
869 request,
870 response,
871 token,
872 stObjectData.ui16MediaType,
873 stObjectData.iMaxAge,
874 (size_t) stPayloadBuffer.uiBufferLen,
875 stPayloadBuffer.pau8Buffer);
876
877 // Everything went to plan, so we return a 2.05 "Success - Content" response
878 response->code = COAP_RESPONSE_CODE(205);
879
880 Payload_BufferFree(&stPayloadBuffer);
881 }
882
896 static void PUT_Callback( coap_context_t *ctx,
897 struct coap_resource_t *resource,
898 coap_session_t *session,
899 coap_pdu_t *request,
900 coap_binary_t *token,
901 coap_string_t *query,
902 coap_pdu_t *response)
903 {
904 stPLATFORM_ObjectData_t stObjectData;
905 stPayloadBuffer_t stPayloadBuffer;
906 const stPayloadDecoder_t * pstDecoder;
907 eFinalState_t eFinalState;
908 eAccess_t eAccess;
909 const stPLUGIN_Field_t * pstFieldFound;
910 uint8_t *payload;
911 size_t payload_len;
912 bool bCallbackOK;
913
914 // If there is no object data associated with this callback...
915 if (resource->user_data == NULL)
916 {
917 // 5.00 = Server Error: Internal Server Error
918 response->code = COAP_RESPONSE_CODE(500);
919 return;
920 }
921
922 stObjectData = *((const stPLATFORM_ObjectData_t *) resource->user_data);
923
924 // Get the payload (and there must be a payload, or else PUT makes no sense)
925 if ( (coap_get_data(request, &payload_len, &payload) == 0)
926 || (payload_len == 0))
927 {
928 // 4.00 = Client Error / Bad Request
929 response->code = COAP_RESPONSE_CODE(400);
930 return;
931 }
932
933 pstDecoder = PayloadDecoder_Get(stObjectData.ui16MediaType);
934 if (pstDecoder == NULL)
935 {
936 // 5.00 = Server Error: Internal Server Error
937 response->code = COAP_RESPONSE_CODE(500);
938 return;
939 }
940
941 // Set up the payload buffer struct with the CoAP request packet's payload
942 Payload_BufferForce(&stPayloadBuffer, payload, payload_len);
943
944 // Continue tracing the URI path down into the structures (i.e. if requesting individual fields / substructures)
945 eFinalState = IterateDownwards(&stObjectData, request, &pstFieldFound);
946 switch (eFinalState)
947 {
948 case eFinalState_Struct:
949 eAccess = PUT_StructToJSON( &stPayloadBuffer,
950 stObjectData.pvObject,
951 stObjectData.pstType,
952 pstDecoder,
953 stObjectData.uiFieldFlags);
954 break;
955
956 case eFinalState_Field:
957 if ((*pstDecoder->pfn_DecodeStructStart)(&stPayloadBuffer) == false)
958 {
959 eAccess = eAccess_ParsingError;
960 break;
961 }
962 eAccess = PUT_ObjectToJSON( &stPayloadBuffer,
963 stObjectData.pvObject,
964 pstFieldFound,
965 pstDecoder,
966 stObjectData.uiFieldFlags);
967 if ((*pstDecoder->pfn_DecodeStructEnd)(&stPayloadBuffer) == false)
968 {
969 eAccess = eAccess_ParsingError;
970 break;
971 }
972 break;
973
974 case eFinalState_NotFound:
975 eAccess = eAccess_UnrecognizedFieldName;
976 break;
977
978 case eFinalState_Error:
979 eAccess = eAccess_UnspecifiedError;
980 break;
981 }
982
983 // Call the object's post-edit callback
984 bCallbackOK = CoAP_ObjectEdited( (const stPLATFORM_ObjectData_t *) resource->user_data );
985
986 if (eAccess != eAccess_OK)
987 {
988 // 4.00 = Client Error / Bad Request
989 response->code = COAP_RESPONSE_CODE(400);
990
991 // FIXME: add an informative error message in the response payload
992
993 Payload_BufferFree(&stPayloadBuffer);
994 return;
995 }
996
997 // If fields have changed but there was a problem with the callback
998 if (bCallbackOK == false)
999 {
1000 // 5.00 = Server Error / Internal Server Error
1001 response->code = COAP_RESPONSE_CODE(500);
1002
1003 Payload_BufferFree(&stPayloadBuffer);
1004 return;
1005 }
1006
1007 // 2.04 = Success / Changed
1008 response->code = COAP_RESPONSE_CODE(204);
1009 Payload_BufferFree(&stPayloadBuffer);
1010 }
1011
1024 static eFinalState_t IterateDownwards( stPLATFORM_ObjectData_t * pstObjectData,
1025 coap_pdu_t *request,
1026 const stPLUGIN_Field_t ** ppstFieldFound)
1027 {
1028 uint32_t uiFieldFlags;
1029 coap_opt_iterator_t stIterator;
1030 const char * pachResourceName;
1031 coap_opt_t * pstOption;
1032 size_t szLen;
1033 const uint8_t * pau8Value;
1034 const stPLUGIN_Type_t * pstType;
1035 const stPLUGIN_Field_t * pstField;
1036 void * pvObj;
1037
1038 // Grab local copies from the object data block passed down
1039 pachResourceName = pstObjectData->pachResourceStr;
1040 pstType = pstObjectData->pstType;
1041 pvObj = pstObjectData->pvObject;
1042 uiFieldFlags = pstObjectData->uiFieldFlags;
1043
1044 // Start iterating through all Uri Path options attached to this request
1045 pstOption = coap_check_option(request, COAP_OPTION_URI_PATH, &stIterator);
1046 for (; pstOption != NULL; pstOption = coap_option_next(&stIterator))
1047 {
1048 szLen = coap_opt_length(pstOption);
1049 pau8Value = coap_opt_value(pstOption);
1050
1051 if (memcmp(pau8Value, pachResourceName, szLen) != 0)
1052 {
1053 return eFinalState_Error;
1054 }
1055 pachResourceName += szLen;
1056 if (pachResourceName[0] == 0x00)
1057 {
1058 pstOption = coap_option_next(&stIterator);
1059 pachResourceName = NULL;
1060 break;
1061 }
1062 if (pachResourceName[0] != '/')
1063 {
1064 return eFinalState_Error;
1065 }
1066 pachResourceName++; // Step past the '/'
1067 }
1068
1069 while (pstOption)
1070 {
1071 szLen = coap_opt_length(pstOption);
1072 pau8Value = coap_opt_value(pstOption);
1073
1074 // Test this against the current struct's field names
1075 pstField = pstType->uReadAccessor.pastFieldPtr;
1076 for (; pstField->pachFieldName != NULL; pstField++)
1077 {
1078 if ( (strlen(pstField->pachFieldName) == szLen)
1079 && (memcmp(pstField->pachFieldName, pau8Value, szLen) == 0))
1080 {
1081 break;
1082 }
1083 }
1084 // If no matching field name found
1085 if (pstField->pachFieldName == NULL)
1086 {
1087 return eFinalState_NotFound;
1088 }
1089 if (pstField->pstType->eDataType != eDataType_Struct)
1090 {
1091 *ppstFieldFound = pstField;
1092 pstObjectData->uiFieldFlags = uiFieldFlags;
1093 return eFinalState_Field;
1094 }
1095
1096 pstType = pstField->pstType;
1097 uiFieldFlags = UpdateWithFieldData(pstField, pvObj, uiFieldFlags, &pvObj);
1098
1099 pstOption = coap_option_next(&stIterator);
1100 }
1101
1102 pstObjectData->pstType = pstType;
1103 pstObjectData->pvObject = pvObj;
1104 pstObjectData->uiFieldFlags = uiFieldFlags;
1105 return eFinalState_Struct;
1106 }
1107
1118 static uint32_t UpdateWithFieldData(const stPLUGIN_Field_t *pstField, void *pvObject, uint32_t uiFieldFlags, void **pvObj)
1119 {
1120 uint32_t uiSubFieldFlags;
1121
1122 uiSubFieldFlags = pstField->uiFieldFlags;
1123 if (uiSubFieldFlags & PLUGIN_FieldFlags_IsAnObject)
1124 {
1125 *pvObj = pstField->uLocation.pvObject;
1126 }
1127 else
1128 {
1129 *pvObj = ((char *) pvObject) + pstField->uLocation.uiFieldOffset;
1130 }
1131 uiSubFieldFlags &= (uiFieldFlags | ~PLUGIN_FieldFlags_ReadWriteAny);
1132
1133 return uiSubFieldFlags;
1134 }
1135
1147 static eAccess_t GET_StructToJSON( stPayloadBuffer_t * pstPayload,
1148 void * pvObject,
1149 const stPLUGIN_Type_t *pstType,
1150 const stPayloadEncoder_t * pstEncoder,
1151 uint32_t uiFieldFlags)
1152 {
1153 const stPLUGIN_Field_t * pstField;
1154 uint32_t uiSubFieldFlags;
1155 void * pvObj;
1156 bool bIsFirst;
1157 eAccess_t eAccess = eAccess_OK;
1158
1159 (*pstEncoder->pfn_EncodeStructStart)(pstPayload);
1160
1161 bIsFirst = true;
1162 for (pstField = pstType->uReadAccessor.pastFieldPtr; pstField->pachFieldName != NULL; pstField++)
1163 {
1164 uiSubFieldFlags = UpdateWithFieldData(pstField, pvObject, uiFieldFlags, &pvObj);
1165
1166 if (bIsFirst == false)
1167 {
1168 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1169 }
1170
1171 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *) pstField->pachFieldName);
1172
1173 eAccess = GET_ObjectToJSON( pstPayload,
1174 pvObj,
1175 pstField,
1176 pstEncoder,
1177 uiSubFieldFlags);
1178 bIsFirst = false;
1179 }
1180
1181 (*pstEncoder->pfn_EncodeStructEnd)(pstPayload);
1182
1183
1184 return eAccess;
1185 }
1186
1197 static bool GetFieldAttributes(void * pvObject, const stPLUGIN_Field_t * pstField, uint32_t *puiNumElements, bool * pbVisibility)
1198 {
1199 uint32_t uiFieldFlags;
1200 bool bThisIsAnArray;
1201 uint32_t uiNumElements;
1202 bool bVisibility;
1203
1204 uiFieldFlags = pstField->uiFieldFlags;
1205 bThisIsAnArray = ((uiFieldFlags & PLUGIN_FieldFlags_IsAnArray) != 0U);
1206 if (bThisIsAnArray)
1207 {
1208 if (uiFieldFlags & PLUGIN_FieldFlags_GetVisibility)
1209 {
1210 bVisibility = (*pstField->uVisibility.pfn_DetermineArrayVisibility)(pvObject, &uiNumElements);
1211 }
1212 else
1213 {
1214 uiNumElements = pstField->uVisibility.uiNumArrayElements;
1215 bVisibility = true;
1216 }
1217 }
1218 else
1219 {
1220 uiNumElements = 1;
1221 if (uiFieldFlags & PLUGIN_FieldFlags_GetVisibility)
1222 {
1223 bVisibility = (*pstField->uVisibility.pfn_DetermineUnitVisibility)(pvObject);
1224 }
1225 else
1226 {
1227 bVisibility = true;
1228 }
1229 }
1230
1231 *puiNumElements = uiNumElements;
1232 *pbVisibility = bVisibility;
1233 return bThisIsAnArray;
1234 }
1235
1247 static eAccess_t GET_ObjectToJSON( stPayloadBuffer_t * pstPayload,
1248 void * pvObject,
1249 const stPLUGIN_Field_t * pstField,
1250 const stPayloadEncoder_t * pstEncoder,
1251 uint32_t uiFieldFlags)
1252 {
1253 uint8_t * pau8Ptr; // To make C pointer arithmetic easy!
1254 bool bThisIsAnArray;
1255 uint32_t uiNumElements;
1256 uint32_t uiElementSize;
1257 const stPLUGIN_Type_t * pstType;
1258 eAccess_t eAccess = eAccess_OK;
1259 eAccess_t eAccess2;
1260 uint32_t i;
1261 bool bVisibility;
1262
1263 uint64_t uiValue;
1264 int64_t iValue;
1265 double rValue;
1266 bool bValue;
1267 const char * pachValue;
1268
1269 // Initialise local copy of variables
1270 pau8Ptr = (uint8_t *) pvObject;
1271 pstType = pstField->pstType;
1272
1273 uiElementSize = pstType->uiSizeof;
1274
1275 bThisIsAnArray = GetFieldAttributes(pvObject, pstField, &uiNumElements, &bVisibility);
1276 if (bVisibility)
1277 {
1278 if (bThisIsAnArray)
1279 {
1280 (*pstEncoder->pfn_EncodeArrayStart)(pstPayload);
1281 }
1282
1283 for (i = 0; i < uiNumElements; i++,pau8Ptr+=uiElementSize)
1284 {
1285 if (Payload_BufferRealloc(pstPayload) == false)
1286 {
1287 eAccess2 = eAccess_OutOfMemory;
1288 }
1289 else if ( (pau8Ptr == NULL) && (pstType->eDataType != eDataType_Struct))
1290 {
1291 eAccess2 = eAccess_NullPointerEncountered;
1292 }
1293 else
1294 {
1295 if (i > 0)
1296 {
1297 (*pstEncoder->pfn_EncodeArraySeparator)(pstPayload);
1298 }
1299
1300 switch (pstType->eDataType)
1301 {
1302 case eDataType_UnsignedInteger:
1303 eAccess2 = (*pstType->uReadAccessor.pfnRead_UnsignedInteger)((const void *)pau8Ptr, &uiValue, pstType->uHelper.pstRange_UnsignedInteger);
1304 if (eAccess2 == eAccess_OK)
1305 {
1306 (*pstEncoder->pfn_EncodeUnsignedInt)(pstPayload, uiValue);
1307 }
1308 break;
1309
1310 case eDataType_Integer:
1311 eAccess2 = (*pstType->uReadAccessor.pfnRead_Integer)((const void *)pau8Ptr, &iValue, pstType->uHelper.pstRange_Integer);
1312 if (eAccess2 == eAccess_OK)
1313 {
1314 (*pstEncoder->pfn_EncodeSignedInt)(pstPayload, iValue);
1315 }
1316 break;
1317
1318 case eDataType_Real:
1319 eAccess2 = (*pstType->uReadAccessor.pfnRead_Real)((const void *)pau8Ptr, &rValue, pstType->uHelper.pstRange_Real);
1320 if (eAccess2 == eAccess_OK)
1321 {
1322 (*pstEncoder->pfn_EncodeReal)(pstPayload, rValue);
1323 }
1324 break;
1325
1326 case eDataType_Boolean:
1327 eAccess2 = (*pstType->uReadAccessor.pfnRead_Boolean)((const void *)pau8Ptr, &bValue);
1328 if (eAccess2 == eAccess_OK)
1329 {
1330 (*pstEncoder->pfn_EncodeBoolean)(pstPayload, bValue);
1331 }
1332 break;
1333
1334 case eDataType_String:
1335 eAccess2 = (*pstType->uReadAccessor.pfnRead_String)((const void *)pau8Ptr, &pachValue);
1336 if (eAccess2 == eAccess_OK)
1337 {
1338 (*pstEncoder->pfn_EncodeString)(pstPayload, (const uint8_t *) pachValue);
1339 }
1340 break;
1341
1342 case eDataType_Enum:
1343 eAccess2 = (*pstType->uReadAccessor.pfnRead_Enum)((const void *)pau8Ptr, &pachValue, pstType->uHelper.pastDictionary);
1344 if (eAccess2 == eAccess_OK)
1345 {
1346 (*pstEncoder->pfn_EncodeString)(pstPayload, (const uint8_t *) pachValue);
1347 }
1348 break;
1349
1350 case eDataType_Struct:
1351 eAccess2 = GET_StructToJSON( pstPayload,
1352 (void *)pau8Ptr,
1353 pstType,
1354 pstEncoder,
1355 uiFieldFlags );
1356 break;
1357
1358 default:
1359 eAccess2 = eAccess_UnexpectedDataType;
1360 break;
1361 }
1362 }
1363
1364 if (eAccess2 != eAccess_OK)
1365 {
1366 eAccess = eAccess2;
1367 break;
1368 }
1369 }
1370
1371 if ((bThisIsAnArray) && (eAccess != eAccess_OutOfMemory))
1372 {
1373 (*pstEncoder->pfn_EncodeArrayEnd)(pstPayload);
1374 }
1375 }
1376
1377 return eAccess;
1378 }
1379
1391 static eAccess_t PUT_StructToJSON( stPayloadBuffer_t * pstPayload,
1392 void * pvObject,
1393 const stPLUGIN_Type_t *pstType,
1394 const stPayloadDecoder_t * pstDecoder,
1395 uint32_t uiFieldFlags)
1396 {
1397 const stPLUGIN_Field_t * pstField;
1398 uint32_t uiSubFieldFlags;
1399 void * pvObj;
1400 bool bIsFirst;
1401 eAccess_t eAccess = eAccess_OK;
1402 bool bDone;
1403 const uint8_t * pau8FieldName;
1404 uint32_t uiFieldNameLen;
1405 uint32_t uiLen;
1406
1407 bDone = false;
1408
1409 if ((*pstDecoder->pfn_DecodeStructStart)(pstPayload) == false)
1410 {
1411 eAccess = eAccess_ParsingError;
1412 bDone = true;
1413 }
1414
1415 bIsFirst = true;
1416 while (bDone == false)
1417 {
1418 if ((*pstDecoder->pfn_DecodeStructEnd)(pstPayload) == true)
1419 {
1420 if (bIsFirst)
1421 {
1422 // The assumption here is that empty structs { } should be interpreted as valid JSON
1423 // If this is incorrect, then change this to eAccess_ParsingError
1424 eAccess = eAccess_OK;
1425 break;
1426 }
1427 eAccess = eAccess_OK;
1428 break;
1429 }
1430
1431 if (bIsFirst == false)
1432 {
1433 if ((*pstDecoder->pfn_DecodeFieldSeparator)(pstPayload) == false)
1434 {
1435 eAccess = eAccess_ParsingError;
1436 break;
1437 }
1438 }
1439 bIsFirst = false;
1440
1441 // Grab the next field name along in the payload, returning length zero if there isn't one
1442 // Returns false if the payload is somehow malformed
1443 if ((*pstDecoder->pfn_DecodeFieldName)(pstPayload, &pau8FieldName, &uiFieldNameLen) == false)
1444 {
1445 eAccess = eAccess_ParsingError;
1446 break;
1447 }
1448
1449 // Now check through all the fields in this struct to find a matching name
1450 for (pstField = pstType->uReadAccessor.pastFieldPtr; pstField->pachFieldName != NULL; pstField++)
1451 {
1452 // If the field name matches the name in the PUT payload...
1453 uiLen = strlen(pstField->pachFieldName);
1454 if ( (uiLen == uiFieldNameLen)
1455 && (memcmp(pstField->pachFieldName, pau8FieldName, uiFieldNameLen) == 0) )
1456 {
1457 uiSubFieldFlags = UpdateWithFieldData(pstField, pvObject, uiFieldFlags, &pvObj);
1458
1459 eAccess = PUT_ObjectToJSON( pstPayload,
1460 pvObj,
1461 pstField,
1462 pstDecoder,
1463 uiSubFieldFlags);
1464 bDone = (eAccess != eAccess_OK);
1465 break;
1466 }
1467 }
1468 }
1469
1470 return eAccess;
1471 }
1472
1484 static eAccess_t PUT_ObjectToJSON( stPayloadBuffer_t * pstPayload,
1485 void * pvObject,
1486 const stPLUGIN_Field_t * pstField,
1487 const stPayloadDecoder_t * pstDecoder,
1488 uint32_t uiFieldFlags)
1489 {
1490 uint8_t * pau8Ptr; // To make C pointer arithmetic easy!
1491 bool bThisIsAnArray;
1492 uint32_t uiNumElements;
1493 uint32_t uiElementSize;
1494 const stPLUGIN_Type_t * pstType;
1495 eAccess_t eAccess = eAccess_OK;
1496 uint32_t i;
1497 bool bVisibility;
1498
1499 uint64_t uiValue;
1500 int64_t iValue;
1501 double rValue;
1502 bool bValue;
1503 const uint8_t * pau8String;
1504 uint32_t uiStringLength;
1505
1506 // Initialise local copy of variables
1507 pau8Ptr = (uint8_t *) pvObject;
1508 pstType = pstField->pstType;
1509
1510 bThisIsAnArray = GetFieldAttributes(pvObject, pstField, &uiNumElements, &bVisibility);
1511 if (bVisibility)
1512 {
1513 uiElementSize = pstType->uiSizeof;
1514
1515 if ( (bThisIsAnArray)
1516 && (*pstDecoder->pfn_DecodeArrayStart)(pstPayload) == false)
1517 {
1518 eAccess = eAccess_ParsingError;
1519 }
1520
1521 for (i = 0; (i < uiNumElements) && (eAccess == eAccess_OK); i++,pau8Ptr+=uiElementSize)
1522 {
1523 if ( (pau8Ptr == NULL) && (pstType->eDataType != eDataType_Struct))
1524 {
1525 eAccess = eAccess_NullPointerEncountered;
1526 break;
1527 }
1528
1529 if ( (i > 0)
1530 && ((*pstDecoder->pfn_DecodeArraySeparator)(pstPayload) == false) )
1531 {
1532 eAccess = eAccess_ParsingError;
1533 break;
1534 }
1535
1536 switch (pstType->eDataType)
1537 {
1538 case eDataType_UnsignedInteger:
1539 if ((*pstDecoder->pfn_DecodeUnsignedInt)(pstPayload, &uiValue) == false)
1540 {
1541 eAccess = eAccess_ParsingError;
1542 break;
1543 }
1544 eAccess = (*pstType->uWriteAccessor.pfnWrite_UnsignedInteger)((void *)pau8Ptr, uiValue, pstType->uHelper.pstRange_UnsignedInteger);
1545 break;
1546
1547 case eDataType_Integer:
1548 if ((*pstDecoder->pfn_DecodeSignedInt)(pstPayload, &iValue) == false)
1549 {
1550 eAccess = eAccess_ParsingError;
1551 break;
1552 }
1553 eAccess = (*pstType->uWriteAccessor.pfnWrite_Integer)((void *)pau8Ptr, iValue, pstType->uHelper.pstRange_Integer);
1554 break;
1555
1556 case eDataType_Real:
1557 if ((*pstDecoder->pfn_DecodeReal)(pstPayload, &rValue) == false)
1558 {
1559 eAccess = eAccess_ParsingError;
1560 break;
1561 }
1562 eAccess = (*pstType->uWriteAccessor.pfnWrite_Real)((void *)pau8Ptr, rValue, pstType->uHelper.pstRange_Real);
1563 break;
1564
1565 case eDataType_Boolean:
1566 if ((*pstDecoder->pfn_DecodeBoolean)(pstPayload, &bValue) == false)
1567 {
1568 eAccess = eAccess_ParsingError;
1569 break;
1570 }
1571 eAccess = (*pstType->uWriteAccessor.pfnWrite_Boolean)((void *)pau8Ptr, bValue);
1572 break;
1573
1574 case eDataType_String:
1575 if ((*pstDecoder->pfn_DecodeString)(pstPayload, &pau8String, &uiStringLength) == false)
1576 {
1577 eAccess = eAccess_ParsingError;
1578 break;
1579 }
1580 eAccess = (*pstType->uWriteAccessor.pfnWrite_String)((void *)pau8Ptr, (const char *) pau8String, uiStringLength, pstType->uiSizeof);
1581 break;
1582
1583 case eDataType_Enum:
1584 if ((*pstDecoder->pfn_DecodeString)(pstPayload, &pau8String, &uiStringLength) == false)
1585 {
1586 eAccess = eAccess_ParsingError;
1587 break;
1588 }
1589 eAccess = (*pstType->uWriteAccessor.pfnWrite_Enum)((void *)pau8Ptr, (const char *) pau8String, uiStringLength, pstType->uHelper.pastDictionary);
1590 break;
1591
1592 case eDataType_Struct:
1593 eAccess = PUT_StructToJSON( pstPayload,
1594 (void *)pau8Ptr,
1595 pstType,
1596 pstDecoder,
1597 uiFieldFlags );
1598 break;
1599
1600 default:
1601 eAccess = eAccess_UnexpectedDataType;
1602 break;
1603 }
1604 }
1605
1606 if ( (eAccess == eAccess_OK)
1607 && (bThisIsAnArray)
1608 && ((*pstDecoder->pfn_DecodeArrayEnd)(pstPayload) == false) )
1609 {
1610 eAccess = eAccess_ParsingError;
1611 }
1612 }
1613
1614 return eAccess;
1615 }
1616
1629 static eAccess_t META_StructToJSON( stPayloadBuffer_t * pstPayload,
1630 void * pvObject,
1631 const stPLUGIN_Type_t *pstType,
1632 const stPayloadEncoder_t * pstEncoder,
1633 uint32_t uiFieldFlags,
1634 uint8_t u8Owner)
1635 {
1636 const stPLUGIN_Field_t * pstField;
1637 uint32_t uiSubFieldFlags;
1638 void * pvObj;
1639 bool bIsFirst;
1640 eAccess_t eAccess = eAccess_OK;
1641
1642 (*pstEncoder->pfn_EncodeStructStart)(pstPayload);
1643
1644 bIsFirst = true;
1645 for (pstField = pstType->uReadAccessor.pastFieldPtr; pstField->pachFieldName != NULL; pstField++)
1646 {
1647 uiSubFieldFlags = UpdateWithFieldData(pstField, pvObject, uiFieldFlags, &pvObj);
1648
1649 if (bIsFirst == false)
1650 {
1651 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1652 }
1653
1654 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *) pstField->pachFieldName);
1655
1656 eAccess = META_ObjectToJSON( pstPayload,
1657 pvObj,
1658 pstField,
1659 pstEncoder,
1660 uiSubFieldFlags,
1661 u8Owner);
1662 bIsFirst = false;
1663 }
1664
1665 (*pstEncoder->pfn_EncodeStructEnd)(pstPayload);
1666
1667
1668 return eAccess;
1669 }
1670
1679 static void META_EncodeType( stPayloadBuffer_t * pstPayload,
1680 const stPayloadEncoder_t * pstEncoder,
1681 uint8_t u8Owner,
1682 const char * pachTypeName )
1683 {
1684 char achFullName[100]; // FIXME magic number
1685
1686 if (u8Owner != OBJECTOWNERINDEX_PLATFORM)
1687 {
1688 snprintf(achFullName, sizeof(achFullName), "P%d_%s", (int) u8Owner, pachTypeName);
1689 pachTypeName = achFullName;
1690 }
1691
1692 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"Type");
1693 (*pstEncoder->pfn_EncodeString)(pstPayload, (const uint8_t *)pachTypeName);
1694 }
1695
1708 static eAccess_t META_ObjectToJSON( stPayloadBuffer_t * pstPayload,
1709 void * pvObject,
1710 const stPLUGIN_Field_t * pstField,
1711 const stPayloadEncoder_t * pstEncoder,
1712 uint32_t uiFieldFlags,
1713 uint8_t u8Owner)
1714 {
1715 const stPLUGIN_Type_t * pstType;
1716 const stPLUGIN_Dictionary_t * pastDict;
1717 eAccess_t eAccess = eAccess_OK;
1718 bool bIsFirst;
1719 uint32_t uiNumElements;
1720 uint8_t u8RealOwner;
1721
1722 // Initialise local copy of variables
1723 pstType = pstField->pstType;
1724
1725 u8RealOwner = u8Owner;
1726 if (ThisIsABaseType(pstType->pachTypeName))
1727 {
1728 u8RealOwner = OBJECTOWNERINDEX_PLATFORM;
1729 }
1730
1731 if (Payload_BufferRealloc(pstPayload) == false)
1732 {
1733 return eAccess_OutOfMemory;
1734 }
1735
1736 (*pstEncoder->pfn_EncodeStructStart)(pstPayload);
1737
1738 META_EncodeType(pstPayload, pstEncoder, u8RealOwner, pstType->pachTypeName);
1739
1740 // Have we seen this type before? If so, no need to output it again
1741 if (Payload_FindType(pstPayload, u8RealOwner, pstType->pachTypeName) == false)
1742 {
1743 switch (pstType->eDataType)
1744 {
1745 case eDataType_UnsignedInteger:
1746 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1747 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"BaseType");
1748 (*pstEncoder->pfn_EncodeString)(pstPayload, (const uint8_t *)"Uint");
1749
1750 if (pstType->uHelper.pstRange_UnsignedInteger != NULL)
1751 {
1752 if (pstType->uHelper.pstRange_UnsignedInteger->uiMin != 0U)
1753 {
1754 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1755 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"Min");
1756 (*pstEncoder->pfn_EncodeUnsignedInt)(pstPayload, pstType->uHelper.pstRange_UnsignedInteger->uiMin);
1757 }
1758
1759 if (pstType->uHelper.pstRange_UnsignedInteger->uiMax != (uint64_t)-1LL) // FIXME should be UINT_MAX
1760 {
1761 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1762 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"Max");
1763 (*pstEncoder->pfn_EncodeUnsignedInt)(pstPayload, pstType->uHelper.pstRange_UnsignedInteger->uiMax);
1764 }
1765
1766 if (pstType->uHelper.pstRange_UnsignedInteger->pachUnitName != NULL)
1767 {
1768 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1769 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"UnitName");
1770 (*pstEncoder->pfn_EncodeString)(pstPayload, (const uint8_t *)pstType->uHelper.pstRange_UnsignedInteger->pachUnitName);
1771 }
1772 }
1773 break;
1774
1775 case eDataType_Integer:
1776 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1777 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"BaseType");
1778 (*pstEncoder->pfn_EncodeString)(pstPayload, (const uint8_t *)"Int");
1779
1780 if (pstType->uHelper.pstRange_Integer != NULL)
1781 {
1782 if (pstType->uHelper.pstRange_Integer->iMin != INT_MIN)
1783 {
1784 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1785 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"Min");
1786 (*pstEncoder->pfn_EncodeSignedInt)(pstPayload, pstType->uHelper.pstRange_Integer->iMin);
1787 }
1788
1789 if (pstType->uHelper.pstRange_Integer->iMax != INT_MAX)
1790 {
1791 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1792 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"Max");
1793 (*pstEncoder->pfn_EncodeSignedInt)(pstPayload, pstType->uHelper.pstRange_Integer->iMax);
1794 }
1795
1796 if (pstType->uHelper.pstRange_Integer->pachUnitName != NULL)
1797 {
1798 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1799 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"UnitName");
1800 (*pstEncoder->pfn_EncodeString)(pstPayload, (const uint8_t *)pstType->uHelper.pstRange_Integer->pachUnitName);
1801 }
1802 }
1803 break;
1804
1805 case eDataType_Real:
1806 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1807 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"BaseType");
1808 (*pstEncoder->pfn_EncodeString)(pstPayload, (const uint8_t *)"Real");
1809
1810 if (pstType->uHelper.pstRange_Real != NULL)
1811 {
1812 if (pstType->uHelper.pstRange_Real->dMin != DBL_MIN)
1813 {
1814 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1815 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"Min");
1816 (*pstEncoder->pfn_EncodeReal)(pstPayload, pstType->uHelper.pstRange_Real->dMin);
1817 }
1818
1819 if (pstType->uHelper.pstRange_Real->dMax != DBL_MAX)
1820 {
1821 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1822 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"Max");
1823 (*pstEncoder->pfn_EncodeReal)(pstPayload, pstType->uHelper.pstRange_Real->dMax);
1824 }
1825
1826 if (pstType->uHelper.pstRange_Real->pachUnitName != NULL)
1827 {
1828 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1829 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"UnitName");
1830 (*pstEncoder->pfn_EncodeString)(pstPayload, (const uint8_t *)pstType->uHelper.pstRange_Real->pachUnitName);
1831 }
1832 }
1833
1834 break;
1835
1836 case eDataType_Boolean:
1837 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1838 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"BaseType");
1839 (*pstEncoder->pfn_EncodeString)(pstPayload, (const uint8_t *)"Boolean");
1840
1841 if (pstType->uHelper.pstBooleanNames != NULL)
1842 {
1843 if (pstType->uHelper.pstBooleanNames->pachFalseString != NULL)
1844 {
1845 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1846 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"FalseString");
1847 (*pstEncoder->pfn_EncodeString)(pstPayload, (const uint8_t *)pstType->uHelper.pstBooleanNames->pachFalseString);
1848 }
1849
1850 if (pstType->uHelper.pstBooleanNames->pachTrueString != NULL)
1851 {
1852 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1853 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"TrueString");
1854 (*pstEncoder->pfn_EncodeString)(pstPayload, (const uint8_t *)pstType->uHelper.pstBooleanNames->pachTrueString);
1855 }
1856 }
1857 break;
1858
1859 case eDataType_String:
1860 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1861 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"BaseType");
1862 (*pstEncoder->pfn_EncodeString)(pstPayload, (const uint8_t *)"String");
1863
1864 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1865 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"MaxLen");
1866 (*pstEncoder->pfn_EncodeSignedInt)(pstPayload, pstType->uHelper.uiStringMax);
1867 break;
1868
1869 case eDataType_Enum:
1870 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1871 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"BaseType");
1872 (*pstEncoder->pfn_EncodeString)(pstPayload, (const uint8_t *)"Enum");
1873
1874 if (pstType->uHelper.pastDictionary != NULL)
1875 {
1876 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1877 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"Enums");
1878 for (pastDict = pstType->uHelper.pastDictionary,uiNumElements=0U; pastDict->pachEnumName; pastDict++,uiNumElements++)
1879 ;
1880 bIsFirst = true;
1881 (*pstEncoder->pfn_EncodeArrayStart)(pstPayload);
1882 for (pastDict = pstType->uHelper.pastDictionary; pastDict->pachEnumName; pastDict++)
1883 {
1884 if (!bIsFirst)
1885 {
1886 (*pstEncoder->pfn_EncodeArraySeparator)(pstPayload);
1887 }
1888 (*pstEncoder->pfn_EncodeString)(pstPayload, (const uint8_t *) pastDict->pachEnumName);
1889 bIsFirst = false;
1890 }
1891 (*pstEncoder->pfn_EncodeArrayEnd)(pstPayload);
1892 }
1893 break;
1894
1895 case eDataType_Struct:
1896 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1897 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"BaseType");
1898 (*pstEncoder->pfn_EncodeString)(pstPayload, (const uint8_t *)"Struct");
1899
1900 eAccess = META_StructToJSON( pstPayload,
1901 pvObject, // Not really needed
1902 pstType,
1903 pstEncoder,
1904 uiFieldFlags,
1905 u8Owner);
1906 break;
1907
1908 default:
1909 break;
1910 }
1911 }
1912
1913 if (uiFieldFlags & PLUGIN_FieldFlags_IsAnArray)
1914 {
1915 (*pstEncoder->pfn_EncodeFieldSeparator)(pstPayload);
1916 (*pstEncoder->pfn_EncodeFieldName)(pstPayload, (const uint8_t *)"ArraySize");
1917 (*pstEncoder->pfn_EncodeUnsignedInt)(pstPayload, pstField->uVisibility.uiNumArrayElements);
1918 }
1919
1920 (*pstEncoder->pfn_EncodeStructEnd)(pstPayload);
1921
1922 return eAccess;
1923 }
stPayloadBuffer_t::uiBufferLen
uint32_t uiBufferLen
Definition: platform_encoder.h:23
TYPE_ALLOCATION_INCREMENT
#define TYPE_ALLOCATION_INCREMENT
Definition: platform_coap.c:21
NULL
#define NULL
Definition: bootloader_common.h:26
stPayloadDecoder_t::pfn_DecodeArrayEnd
bool(* pfn_DecodeArrayEnd)(stPayloadBuffer_t *pstPayload)
Definition: platform_encoder.h:56
meta_resource
static coap_resource_t * meta_resource
Definition: platform_coap.c:121
stPayloadDecoder_t::pfn_DecodeFieldSeparator
bool(* pfn_DecodeFieldSeparator)(stPayloadBuffer_t *pstPayload)
Definition: platform_encoder.h:58
RESOURCE_URI_PATH_MAXLEN
#define RESOURCE_URI_PATH_MAXLEN
Definition: platform_coap.c:24
PAYLOAD_REALLOC_TRIGGER_LEVEL
#define PAYLOAD_REALLOC_TRIGGER_LEVEL
Definition: platform_coap.c:18
eFinalState_Field
Definition: platform_coap.c:28
stPayloadEncoder_t::pfn_EncodeFieldName
void(* pfn_EncodeFieldName)(stPayloadBuffer_t *pstPayload, const uint8_t *pau8FieldName)
Definition: platform_encoder.h:40
stPayloadBuffer_t::bWasMalloced
bool bWasMalloced
Definition: platform_encoder.h:25
Payload_BufferAlloc
static bool Payload_BufferAlloc(stPayloadBuffer_t *pstPayload, uint32_t uiSize)
Definition: platform_coap.c:427
stPayloadBuffer_t
Definition: platform_encoder.h:20
stPayloadEncoder_t::pfn_EncodeArrayStart
void(* pfn_EncodeArrayStart)(stPayloadBuffer_t *pstPayload)
Definition: platform_encoder.h:37
stPayloadDecoder_t::pfn_DecodeSignedInt
bool(* pfn_DecodeSignedInt)(stPayloadBuffer_t *pstPayload, int64_t *pi64Value)
Definition: platform_encoder.h:60
META_ObjectToJSON
static eAccess_t META_ObjectToJSON(stPayloadBuffer_t *pstPayload, void *pvObject, const stPLUGIN_Field_t *pstField, const stPayloadEncoder_t *pstEncoder, uint32_t uiFieldFlags, uint8_t u8Owner)
Definition: platform_coap.c:1708
stPayloadBuffer_t::uiFoundTypesNum
uint32_t uiFoundTypesNum
Definition: platform_encoder.h:28
eFinalState_NotFound
Definition: platform_coap.c:30
ThisIsABaseType
static bool ThisIsABaseType(const char *pachTypeName)
Definition: platform_coap.c:393
stPayloadDecoder_t::pfn_DecodeReal
bool(* pfn_DecodeReal)(stPayloadBuffer_t *pstPayload, double *pdValue)
Definition: platform_encoder.h:62
IterateDownwards
static eFinalState_t IterateDownwards(stPLATFORM_ObjectData_t *pstObjectData, coap_pdu_t *request, const stPLUGIN_Field_t **ppstFieldFound)
Definition: platform_coap.c:1024
stPayloadEncoder_t::pfn_EncodeStructEnd
void(* pfn_EncodeStructEnd)(stPayloadBuffer_t *pstPayload)
Definition: platform_encoder.h:36
i
volatile int i
Definition: excep_test.c:17
Payload_SetupFoundTypes
static void Payload_SetupFoundTypes(stPayloadBuffer_t *pstPayload)
Definition: platform_coap.c:412
Payload_BufferRealloc
static bool Payload_BufferRealloc(stPayloadBuffer_t *pstPayload)
Definition: platform_coap.c:446
GET_ObjectToJSON
static eAccess_t GET_ObjectToJSON(stPayloadBuffer_t *pstPayload, void *pvObject, const stPLUGIN_Field_t *pstField, const stPayloadEncoder_t *pstEncoder, uint32_t uiFieldFlags)
Definition: platform_coap.c:1247
PUT_ObjectToJSON
static eAccess_t PUT_ObjectToJSON(stPayloadBuffer_t *pstPayload, void *pvObject, const stPLUGIN_Field_t *pstField, const stPayloadDecoder_t *pstDecoder, uint32_t uiFieldFlags)
Definition: platform_coap.c:1484
apachBaseTypes
static const char *const apachBaseTypes[]
Definition: platform_coap.c:124
META_Callback
static void META_Callback(coap_context_t *ctx, struct coap_resource_t *resource, coap_session_t *session, coap_pdu_t *request, coap_binary_t *token, coap_string_t *query, coap_pdu_t *response)
Definition: platform_coap.c:558
stPayloadEncoder_t::pfn_EncodeUnsignedInt
void(* pfn_EncodeUnsignedInt)(stPayloadBuffer_t *pstPayload, uint64_t ui64Value)
Definition: platform_encoder.h:44
META_OutputResourceInfo
static void META_OutputResourceInfo(const stPayloadEncoder_t *pstEncoder, stPayloadBuffer_t *pstPayload, const stPLATFORM_ObjectData_t *pstObjectData)
Definition: platform_coap.c:296
UpdateWithFieldData
static uint32_t UpdateWithFieldData(const stPLUGIN_Field_t *pstField, void *pvObject, uint32_t uiFieldFlags, void **pvObj)
Definition: platform_coap.c:1118
GET_Callback
static void GET_Callback(coap_context_t *ctx, struct coap_resource_t *resource, coap_session_t *session, coap_pdu_t *request, coap_binary_t *token, coap_string_t *query, coap_pdu_t *response)
Definition: platform_coap.c:789
CoAP_ObjectUpdated
void CoAP_ObjectUpdated(const stPLATFORM_ObjectData_t *pstObjectData)
Definition: platform_coap.c:206
platform_encoder.h
GET_StructToJSON
static eAccess_t GET_StructToJSON(stPayloadBuffer_t *pstPayload, void *pvObject, const stPLUGIN_Type_t *pstType, const stPayloadEncoder_t *pstEncoder, uint32_t uiFieldFlags)
Definition: platform_coap.c:1147
stPayloadEncoder_t::pfn_EncodeString
void(* pfn_EncodeString)(stPayloadBuffer_t *pstPayload, const uint8_t *pau8String)
Definition: platform_encoder.h:46
stFoundType_t::pachTypeName
const char * pachTypeName
Definition: platform_encoder.h:17
CreateResource
static coap_resource_t * CreateResource(const char *pchResourceStr, const char *pchResourceType, const char *pchInterfaceDescription, uint16_t ui16MediaType)
Definition: platform_coap.c:249
CoAP_CreateResource
bool CoAP_CreateResource(stPLATFORM_ObjectData_t *pstObjectData)
Definition: platform_coap.c:180
stPayloadDecoder_t::pfn_DecodeFieldName
bool(* pfn_DecodeFieldName)(stPayloadBuffer_t *pstPayload, const uint8_t **pau8FieldName, uint32_t *puiNameLength)
Definition: platform_encoder.h:57
context
static coap_context_t * context
Definition: platform_coap.c:119
META_OutputFlagInfo
static void META_OutputFlagInfo(const stPayloadEncoder_t *pstEncoder, stPayloadBuffer_t *pstPayload, const stPLATFORM_ObjectData_t *pstObjectData)
Definition: platform_coap.c:358
stPayloadDecoder_t::pfn_DecodeString
bool(* pfn_DecodeString)(stPayloadBuffer_t *pstPayload, const uint8_t **ppau8String, uint32_t *puiStringLength)
Definition: platform_encoder.h:63
stPayloadBuffer_t::uiFoundTypesAlloced
uint32_t uiFoundTypesAlloced
Definition: platform_encoder.h:29
stFoundType_t::u8OwnerIndex
uint8_t u8OwnerIndex
Definition: platform_encoder.h:16
stPayloadDecoder_t::pfn_DecodeArraySeparator
bool(* pfn_DecodeArraySeparator)(stPayloadBuffer_t *pstPayload)
Definition: platform_encoder.h:55
eFinalState_Struct
Definition: platform_coap.c:29
apchFieldFlagNames
const char * apchFieldFlagNames[]
Definition: platform_coap.c:330
META_StructToJSON
static eAccess_t META_StructToJSON(stPayloadBuffer_t *pstPayload, void *pvObject, const stPLUGIN_Type_t *pstType, const stPayloadEncoder_t *pstEncoder, uint32_t uiFieldFlags, uint8_t u8Owner)
Definition: platform_coap.c:1629
DEFAULT_PAYLOAD_BUFFER_SIZE
#define DEFAULT_PAYLOAD_BUFFER_SIZE
Definition: platform_coap.c:15
stPayloadDecoder_t::pfn_DecodeArrayStart
bool(* pfn_DecodeArrayStart)(stPayloadBuffer_t *pstPayload)
Definition: platform_encoder.h:54
stFoundType_t
Definition: platform_encoder.h:14
stPayloadDecoder_t::pfn_DecodeStructEnd
bool(* pfn_DecodeStructEnd)(stPayloadBuffer_t *pstPayload)
Definition: platform_encoder.h:53
stPayloadBuffer_t::pau8Buffer
uint8_t * pau8Buffer
Definition: platform_encoder.h:22
stPayloadBuffer_t::uiBufferSize
uint32_t uiBufferSize
Definition: platform_encoder.h:24
stPayloadEncoder_t::pfn_EncodeFieldSeparator
void(* pfn_EncodeFieldSeparator)(stPayloadBuffer_t *pstPayload)
Definition: platform_encoder.h:41
PayloadEncoder_Get
const stPayloadEncoder_t * PayloadEncoder_Get(uint16_t ui16MediaType)
Definition: platform_encoder.c:18
stPayloadEncoder_t::pfn_EncodeReal
void(* pfn_EncodeReal)(stPayloadBuffer_t *pstPayload, double dValue)
Definition: platform_encoder.h:45
META_EncodeType
static void META_EncodeType(stPayloadBuffer_t *pstPayload, const stPayloadEncoder_t *pstEncoder, uint8_t u8Owner, const char *pachTypeName)
Definition: platform_coap.c:1679
stPayloadEncoder_t::pfn_EncodeArraySeparator
void(* pfn_EncodeArraySeparator)(stPayloadBuffer_t *pstPayload)
Definition: platform_encoder.h:38
Payload_BufferForce
static void Payload_BufferForce(stPayloadBuffer_t *pstPayload, uint8_t *pau8Buffer, uint32_t uiSize)
Definition: platform_coap.c:476
stPayloadBuffer_t::pastFoundTypes
stFoundType_t * pastFoundTypes
Definition: platform_encoder.h:27
stPayloadDecoder_t::pfn_DecodeStructStart
bool(* pfn_DecodeStructStart)(stPayloadBuffer_t *pstPayload)
Definition: platform_encoder.h:52
stPayloadEncoder_t::pfn_EncodeStructStart
void(* pfn_EncodeStructStart)(stPayloadBuffer_t *pstPayload)
Definition: platform_encoder.h:35
stPayloadEncoder_t::pfn_EncodeArrayEnd
void(* pfn_EncodeArrayEnd)(stPayloadBuffer_t *pstPayload)
Definition: platform_encoder.h:39
eFinalState_Error
Definition: platform_coap.c:31
CoAP_Initialise
void * CoAP_Initialise(void)
Definition: platform_coap.c:148
stJSONEncoder
const stPayloadEncoder_t stJSONEncoder
Definition: platform_encoder_json.c:516
stPayloadEncoder_t::pfn_EncodeBoolean
void(* pfn_EncodeBoolean)(stPayloadBuffer_t *pstPayload, bool bValue)
Definition: platform_encoder.h:42
CoAP_ObjectEdited
static bool CoAP_ObjectEdited(const stPLATFORM_ObjectData_t *pstObjectData)
Definition: platform_coap.c:224
eFinalState_t
eFinalState_t
Definition: platform_coap.c:26
platform_coap.h
stPayloadDecoder_t
Definition: platform_encoder.h:49
stPayloadEncoder_t
Definition: platform_encoder.h:32
stPayloadDecoder_t::pfn_DecodeBoolean
bool(* pfn_DecodeBoolean)(stPayloadBuffer_t *pstPayload, bool *pbValue)
Definition: platform_encoder.h:59
PayloadDecoder_Get
const stPayloadDecoder_t * PayloadDecoder_Get(uint16_t ui16MediaType)
Definition: platform_encoder.c:40
GetFieldAttributes
static bool GetFieldAttributes(void *pvObject, const stPLUGIN_Field_t *pstField, uint32_t *puiNumElements, bool *pbVisibility)
Definition: platform_coap.c:1197
stPayloadDecoder_t::pfn_DecodeUnsignedInt
bool(* pfn_DecodeUnsignedInt)(stPayloadBuffer_t *pstPayload, uint64_t *pui64Value)
Definition: platform_encoder.h:61
Payload_FindType
static bool Payload_FindType(stPayloadBuffer_t *pstPayload, uint8_t u8OwnerIndex, const char *pachTypeName)
Definition: platform_coap.c:516
stPayloadEncoder_t::pfn_EncodeSignedInt
void(* pfn_EncodeSignedInt)(stPayloadBuffer_t *pstPayload, int64_t i64Value)
Definition: platform_encoder.h:43
PUT_Callback
static void PUT_Callback(coap_context_t *ctx, struct coap_resource_t *resource, coap_session_t *session, coap_pdu_t *request, coap_binary_t *token, coap_string_t *query, coap_pdu_t *response)
Definition: platform_coap.c:896
PUT_StructToJSON
static eAccess_t PUT_StructToJSON(stPayloadBuffer_t *pstPayload, void *pvObject, const stPLUGIN_Type_t *pstType, const stPayloadDecoder_t *pstDecoder, uint32_t uiFieldFlags)
Definition: platform_coap.c:1391
Payload_BufferFree
static void Payload_BufferFree(stPayloadBuffer_t *pstPayload)
Definition: platform_coap.c:491