1 /* ****************************************************************
3 * Copyright 2015 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
23 #include "routingmessageparser.h"
24 #include "routingtablemanager.h"
25 #include "routingutility.h"
26 #include "ocpayload.h"
27 #include "ocpayloadcbor.h"
28 #include "oic_malloc.h"
29 #include "oic_string.h"
30 #include "include/logger.h"
33 * Logging tag for module name.
35 #define TAG "OIC_RM_PARSER"
38 * Table key to parser Payload Table.
40 static const char TABLE[] = "table";
43 * Length key to get length Payload Array.
45 static const char LENGTH_PROP[] = "len";
48 * Gateway key to parser Payload Table.
50 static const char GATEWAY[] = "gateway";
53 * Route Cost key to parser Payload Table.
55 static const char ROUTE_COST[] = "routecost";
58 * Sequence Number key to parser Payload Table.
60 static const char SEQ_NUM[] = "seqnum";
63 * Response Type key to parser Payload Table.
65 static const char UPDATE_SEQ_NUM[] = "updateseqnum";
67 OCStackResult RMPConstructGatewayPayload(uint32_t gatewayId, OCRepPayload **payload)
69 OIC_LOG(DEBUG, TAG, "RMPConstructGatewayPayload IN");
70 RM_NULL_CHECK_WITH_RET(payload, TAG, "payload");
72 *payload = OCRepPayloadCreate();
75 OIC_LOG(ERROR, TAG, "Failed to allocate Payload");
76 return OC_STACK_ERROR;
79 (*payload)->base.type = PAYLOAD_TYPE_REPRESENTATION;
80 OCRepPayloadSetPropInt(*payload, GATEWAY, gatewayId);
81 OCRepPayloadSetPropInt(*payload, LENGTH_PROP, 0);
83 OIC_LOG(DEBUG, TAG, "RMPConstructGatewayPayload OUT");
88 OCStackResult RMPConstructObserveResPayload(uint32_t gatewayId, uint32_t seqNum,
89 const u_linklist_t *routingtable, bool isUpdateSeqNeeded,
90 OCRepPayload **payload)
92 OIC_LOG(DEBUG, TAG, "RMPConstructObserveResPayload IN");
93 RM_NULL_CHECK_WITH_RET(payload, TAG, "payload");
95 *payload = (OCRepPayload *)OCRepPayloadCreate();
98 OIC_LOG(ERROR, TAG, "Failed to allocate Payload");
99 return OC_STACK_ERROR;
102 (*payload)->base.type = PAYLOAD_TYPE_REPRESENTATION;
103 OCRepPayloadSetPropInt(*payload, GATEWAY, gatewayId);
104 OCRepPayloadSetPropInt(*payload, SEQ_NUM, seqNum);
105 OCRepPayloadSetPropBool(*payload, UPDATE_SEQ_NUM, isUpdateSeqNeeded);
106 if (NULL == routingtable)
108 OCRepPayloadSetPropInt(*payload, LENGTH_PROP, 0);
109 OIC_LOG(DEBUG, TAG, "Routing Table NULL for ObserveRes Payload");
113 u_linklist_iterator_t *iterTable = NULL;
114 u_linklist_init_iterator(routingtable, &iterTable);
116 uint32_t len = u_linklist_length(routingtable);
117 const OCRepPayload *arrayPayload[len];
119 size_t dimensions[MAX_REP_ARRAY_DEPTH] = {len, 0, 0};
122 while (NULL != iterTable)
124 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
126 OCRepPayload *add = OCRepPayloadCreate();
129 OIC_LOG(ERROR, TAG, "Failed to allocate Payload");
130 return OC_STACK_ERROR;
133 add->base.type = PAYLOAD_TYPE_REPRESENTATION;
134 OCRepPayloadSetPropInt(add, GATEWAY, entry->destination->gatewayId);
135 OCRepPayloadSetPropInt(add, ROUTE_COST, entry->routeCost);
136 arrayPayload[i] = add;
139 u_linklist_get_next(&iterTable);
141 OCRepPayloadSetPropInt(*payload, LENGTH_PROP, i);
144 bool res = OCRepPayloadSetPropObjectArray(*payload, TABLE, arrayPayload, dimensions);
147 OIC_LOG(ERROR, TAG, "Failed to Construct Observer response Payload");
148 return OC_STACK_ERROR;
152 OIC_LOG(DEBUG, TAG, "RMPConstructObserveResPayload OUT");
156 OCStackResult RMPConstructRemovalPayload(uint32_t gatewayId, uint32_t seqNum,
157 const u_linklist_t *removedGateways, bool isUpdateSeqNeeded,
158 OCRepPayload **removedPayload)
160 OIC_LOG(DEBUG, TAG, "RMPConstructRemovalPayload IN");
161 RM_NULL_CHECK_WITH_RET(removedGateways, TAG, "removedGateways");
162 RM_NULL_CHECK_WITH_RET(removedPayload, TAG, "removedPayload");
164 u_linklist_iterator_t *iterTable = NULL;
165 u_linklist_init_iterator(removedGateways, &iterTable);
167 *removedPayload = OCRepPayloadCreate();
170 OIC_LOG(ERROR, TAG, "Failed to allocate Payload");
171 return OC_STACK_ERROR;
174 uint32_t len = u_linklist_length(removedGateways);
175 const OCRepPayload *arrayPayload[len];
177 size_t dimensions[MAX_REP_ARRAY_DEPTH] = {len, 0, 0};
179 (*removedPayload)->base.type = PAYLOAD_TYPE_REPRESENTATION;
180 OCRepPayloadSetPropInt(*removedPayload, GATEWAY, gatewayId);
181 OCRepPayloadSetPropInt(*removedPayload, SEQ_NUM, seqNum);
182 OCRepPayloadSetPropBool(*removedPayload, UPDATE_SEQ_NUM, isUpdateSeqNeeded);
185 while (NULL != iterTable)
187 RTMGatewayEntry_t *entry = (RTMGatewayEntry_t *) u_linklist_get_data(iterTable);
190 u_linklist_get_next(&iterTable);
193 OCRepPayload *add = OCRepPayloadCreate();
196 OIC_LOG(ERROR, TAG, "Failed to allocate Payload");
197 return OC_STACK_ERROR;
200 add->base.type = PAYLOAD_TYPE_REPRESENTATION;
201 OIC_LOG_V(DEBUG, TAG, "Removing the gateway entry: %u", entry->destination->gatewayId);
202 OCRepPayloadSetPropInt(add, GATEWAY, entry->destination->gatewayId);
203 OCRepPayloadSetPropInt(add, ROUTE_COST, 0);
204 arrayPayload[i] = add;
207 u_linklist_get_next(&iterTable);
209 OCRepPayloadSetPropInt(*removedPayload, LENGTH_PROP, i);
210 bool res = OCRepPayloadSetPropObjectArray(*removedPayload, TABLE, arrayPayload, dimensions);
213 OIC_LOG(ERROR, TAG, "Failed to Construct Removal Payload");
214 return OC_STACK_ERROR;
217 OIC_LOG(DEBUG, TAG, "RMPConstructRemovalPayload OUT");
221 OCStackResult RMPParseRequestPayload(const uint8_t* payload, size_t payloadSize,
224 OCPayload *ocPayload = NULL;
225 OCParsePayload(&ocPayload, PAYLOAD_TYPE_REPRESENTATION, payload, payloadSize);
226 OCRepPayload *repPayload = (OCRepPayload *)ocPayload;
227 OCStackResult res = RMPParseResponsePayload(repPayload, gatewayId, NULL, NULL, NULL);
228 if (OC_STACK_OK != res)
230 OIC_LOG(DEBUG, TAG, "ParseResponsePayload failed");
236 OCStackResult RMPParseResponsePayload(const OCRepPayload *payload, uint32_t *gatewayId,
237 uint32_t *seqNum, u_linklist_t **gatewayTable,
238 bool *isUpdateSeqNeeded)
240 OIC_LOG(DEBUG, TAG, "RMPParsePayload IN");
241 RM_NULL_CHECK_WITH_RET(payload, TAG, "payload");
242 RM_NULL_CHECK_WITH_RET(gatewayId, TAG, "gatewayId");
244 int64_t tempGateway = 0;
245 OCRepPayloadGetPropInt(payload, GATEWAY, &tempGateway);
246 *gatewayId = tempGateway;
248 if (NULL == gatewayId || 0 == *gatewayId)
250 return OC_STACK_COMM_ERROR;
256 OCRepPayloadGetPropInt(payload, SEQ_NUM, &tempSeq);
261 OCRepPayloadGetPropInt(payload, LENGTH_PROP, &length);
263 if (NULL != isUpdateSeqNeeded)
265 OCRepPayloadGetPropBool(payload, UPDATE_SEQ_NUM, isUpdateSeqNeeded);
271 OIC_LOG(DEBUG, TAG, "Parsed Gateway Payload");
275 if (NULL == gatewayTable)
277 OIC_LOG(DEBUG, TAG, "gatewayTable is NULL");
281 OCRepPayload **responsePayload[len];
283 size_t dimensions[MAX_REP_ARRAY_DEPTH];
284 OCRepPayloadGetPropObjectArray(payload, TABLE, responsePayload, dimensions);
286 if (NULL == *responsePayload)
288 OIC_LOG(DEBUG, TAG, "RMPParsePayload OUT");
292 *gatewayTable = u_linklist_create();
293 if (NULL == *gatewayTable)
295 OIC_LOG(DEBUG, TAG, "Gateway table create failed");
296 return OC_STACK_ERROR;
299 for (int i = 0; i < len; i++)
301 RTMGatewayEntry_t *entry = (RTMGatewayEntry_t *)OICCalloc(1, sizeof(RTMGatewayEntry_t));
305 OIC_LOG(DEBUG, TAG, "RTMGatewayEntry_t Calloc failed");
306 return OC_STACK_ERROR;
309 entry->destination = (RTMGatewayId_t*)OICCalloc(1, sizeof(RTMGatewayId_t));
310 if (NULL == entry->destination)
312 OIC_LOG(DEBUG, TAG, "Destination Calloc failed");
314 return OC_STACK_ERROR;
316 entry->nextHop = (RTMGatewayId_t*)OICCalloc(1, sizeof(RTMGatewayId_t));
317 if (NULL == entry->nextHop)
319 OIC_LOG(DEBUG, TAG, "nextHop Calloc failed");
320 OICFree(entry->destination);
322 return OC_STACK_ERROR;
325 entry->nextHop->gatewayId = *gatewayId;
329 OCRepPayloadGetPropInt(*((*responsePayload) + i), GATEWAY, &gatewayBuf);
330 OCRepPayloadGetPropInt(*((*responsePayload) + i), ROUTE_COST, &routeCost);
332 entry->destination->gatewayId = gatewayBuf;
333 entry->routeCost = routeCost;
334 u_linklist_add(*gatewayTable, (void *)entry);
336 OIC_LOG(DEBUG, TAG, "RMPParsePayload OUT");
340 void RMPFreePayload(OCRepPayload *payload)
342 OIC_LOG(DEBUG, TAG, "RMPFreePayload IN");
343 RM_NULL_CHECK_VOID(payload, TAG, "payload");
344 OCRepPayloadDestroy(payload);
345 OIC_LOG(DEBUG, TAG, "RMPFreePayload OUT");