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 "routingtablemanager.h"
24 #include "routingutility.h"
25 #include "oic_malloc.h"
26 #include "oic_string.h"
27 #include "include/logger.h"
30 * Logging tag for module name.
35 * Tag for printing the Routing table.
41 * Initial Length of observer list.
43 #define MAX_OBSERVER_LIST_LENGTH 10
45 static const uint64_t USECS_PER_SEC = 1000000;
47 OCStackResult RTMInitialize(u_linklist_t **gatewayTable, u_linklist_t **endpointTable)
49 OC_LOG(DEBUG, TAG, "RTMInitialize IN");
50 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
51 RM_NULL_CHECK_WITH_RET(endpointTable, TAG, "endpointTable");
52 if (NULL == *gatewayTable)
54 *gatewayTable = u_linklist_create();
55 if (NULL == *gatewayTable)
57 OC_LOG(ERROR, TAG, "Creating Routing Table failed");
58 RTMTerminate(gatewayTable, endpointTable);
59 return OC_STACK_ERROR;
63 if (NULL == *endpointTable)
65 *endpointTable = u_linklist_create();
66 if (NULL == *endpointTable)
68 OC_LOG(ERROR, TAG, "Creating Routing Table failed");
69 RTMTerminate(gatewayTable, endpointTable);
70 return OC_STACK_ERROR;
73 OC_LOG(DEBUG, TAG, "RTMInitialize OUT");
78 * Freeing every char pointer and array list of gateway entry here and frees the table.
80 OCStackResult RTMFreeGatewayRouteTable(u_linklist_t **gatewayTable)
82 OC_LOG(DEBUG, TAG, "RTMFreeGatewayRouteTable IN");
83 if (NULL == gatewayTable || NULL == *gatewayTable)
88 u_linklist_iterator_t *iterTable = NULL;
89 u_linklist_init_iterator(*gatewayTable, &iterTable);
90 while (NULL != iterTable)
92 RTMGatewayEntry_t *hop = u_linklist_get_data(iterTable);
93 if (NULL != hop && NULL != hop->destination)
95 while (u_arraylist_length(hop->destination->destIntfAddr) > 0)
97 if (NULL != hop->destination)
99 RTMDestIntfInfo_t *data = u_arraylist_remove(hop->destination->destIntfAddr, 0);
103 u_arraylist_free(&(hop->destination->destIntfAddr));
104 OICFree(hop->destination);
105 // No need to free next hop as it is already freed during it's gateway free
109 OCStackResult ret = u_linklist_remove(*gatewayTable, &iterTable);
110 if (OC_STACK_OK != ret)
112 OC_LOG(ERROR, TAG, "Deleting Entry from Routing Table failed");
113 return OC_STACK_ERROR;
116 u_linklist_free(gatewayTable);
117 OC_LOG(DEBUG, TAG, "RTMFreeGatewayRouteTable OUT");
122 * Freeing every char pointer of endpoint entry here frees the table.
124 OCStackResult RTMFreeEndpointRouteTable(u_linklist_t **endpointTable)
126 OC_LOG(DEBUG, TAG, "IN");
127 if (NULL == endpointTable || NULL == *endpointTable)
132 u_linklist_iterator_t *iterTable = NULL;
133 u_linklist_init_iterator(*endpointTable, &iterTable);
134 while (NULL != iterTable)
136 RTMEndpointEntry_t *hop = u_linklist_get_data(iterTable);
142 OCStackResult ret = u_linklist_remove(*endpointTable, &iterTable);
143 if (OC_STACK_OK != ret)
145 OC_LOG(ERROR, TAG, "Deleting Entry from Routing Table failed");
146 return OC_STACK_ERROR;
149 u_linklist_free(endpointTable);
150 OC_LOG(DEBUG, TAG, "OUT");
154 OCStackResult RTMFreeGatewayIdList(u_linklist_t **gatewayIdTable)
156 OC_LOG(DEBUG, TAG, "IN");
157 if (NULL == gatewayIdTable || NULL == *gatewayIdTable)
162 u_linklist_iterator_t *iterTable = NULL;
163 u_linklist_init_iterator(*gatewayIdTable, &iterTable);
164 while (iterTable != NULL)
166 RTMGatewayId_t *hop = u_linklist_get_data(iterTable);
169 while (u_arraylist_length(hop->destIntfAddr) > 0)
171 RTMDestIntfInfo_t *data = u_arraylist_remove(hop->destIntfAddr, 0);
174 u_arraylist_free(&(hop->destIntfAddr));
177 OCStackResult ret = u_linklist_remove(*gatewayIdTable, &iterTable);
178 if (OC_STACK_OK != ret)
180 OC_LOG(ERROR, TAG, "Deleting Entry from Routing Table failed");
181 return OC_STACK_ERROR;
186 OCStackResult res = u_linklist_remove(*gatewayIdTable, &iterTable);
187 if (OC_STACK_OK != res)
189 OC_LOG(ERROR, TAG, "Deleting Entry from Routing Table failed");
190 return OC_STACK_ERROR;
194 OC_LOG(DEBUG, TAG, "OUT");
199 * Freeing memory first and then Freeing linked list for gateway and endpoint.
201 OCStackResult RTMTerminate(u_linklist_t **gatewayTable, u_linklist_t **endpointTable)
203 OC_LOG(DEBUG, TAG, "IN");
205 OCStackResult ret = RTMFreeGatewayRouteTable(gatewayTable);
206 if (OC_STACK_OK != ret)
208 OC_LOG(ERROR, TAG, "Deleting Gateway Routing Table failed");
210 if (NULL != *gatewayTable)
212 *gatewayTable = NULL;
215 ret = RTMFreeEndpointRouteTable(endpointTable);
216 if (OC_STACK_OK != ret)
218 OC_LOG(ERROR, TAG, "Deleting Endpoint Routing Table failed");
220 if (NULL != *endpointTable)
222 *endpointTable = NULL;
224 OC_LOG(DEBUG, TAG, "OUT");
229 * Checks if destination gateway to be added is already present and update if present or
230 * adds new entry if not present.
231 * Adds Entry to head if route cost is 1.
232 * Adds Entry to Tail if route cost is > 1.
233 * Checks for Gateway id Memory and assigns to next hop address to achieve better memory usage.
235 OCStackResult RTMAddGatewayEntry(uint32_t gatewayId, uint32_t nextHop, uint32_t routeCost,
236 const RTMDestIntfInfo_t *destInterfaces, u_linklist_t **gatewayTable)
238 OC_LOG(DEBUG, TAG, "IN");
239 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
240 if (NULL == *gatewayTable)
242 *gatewayTable = u_linklist_create();
245 if (1 == routeCost && 0 != nextHop)
247 OC_LOG(ERROR, TAG, "Adding Gateway Failed as Next Hop should be 0 for route cost 1");
248 return OC_STACK_ERROR;
253 OC_LOG(ERROR, TAG, "Adding Gateway Failed as Route cost shouldnot be less than 1");
254 return OC_STACK_ERROR;
257 u_linklist_iterator_t *destNode = NULL;
258 RTMGatewayId_t *gatewayNodeMap = NULL; // Gateway id ponter can be mapped to NextHop of entry.
260 u_linklist_iterator_t *iterTable = NULL;
261 u_linklist_init_iterator(*gatewayTable, &iterTable);
262 // Iterate over gateway list to find if already entry with this gatewayid is present.
263 while (NULL != iterTable)
265 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
271 // To save node with same gateway id (To update entry instead of add new entry).
272 if (NULL == destNode && NULL != entry->destination &&
273 (gatewayId == entry->destination->gatewayId))
275 destNode = iterTable;
278 // To find pointer of gateway id for a node provided next hop equals to existing gateway id.
279 if (0 != nextHop && NULL != entry->destination &&
280 nextHop == entry->destination->gatewayId)
282 gatewayNodeMap = entry->destination;
285 if (NULL != destNode && NULL != gatewayNodeMap)
290 u_linklist_get_next(&iterTable);
293 if (1 < routeCost && NULL == gatewayNodeMap)
295 OC_LOG(ERROR, TAG, "Adding Gateway Failed as Next Hop is invalid");
296 return OC_STACK_ERROR;
299 //Logic to update entry if it is already destination present or to add new entry.
300 if (NULL != destNode)
302 RTMGatewayEntry_t *entry = u_linklist_get_data(destNode);
304 if (NULL != entry && 1 == entry->routeCost && 0 == nextHop)
306 if (NULL == destInterfaces)
308 OC_LOG(ERROR, TAG, "Not Adding Gateway destInterfaces is NULL");
309 return OC_STACK_ERROR;
311 OCStackResult update = RTMUpdateDestinationIntfAdr(gatewayId, *destInterfaces, true,
313 if (OC_STACK_OK != update)
315 OC_LOG(ERROR, TAG, "RTMUpdateDestinationIntfAdr failed");
319 else if (NULL != entry && entry->routeCost >= routeCost)
321 if (entry->routeCost == routeCost && NULL != entry->nextHop &&
322 (nextHop == entry->nextHop->gatewayId))
324 OC_LOG(ERROR, TAG, "Not Adding Gateway As it is Duplicate request");
325 return OC_STACK_DUPLICATE_REQUEST;
328 //Mapped nextHop gateway to another entries having gateway as destination.
329 if (NULL != gatewayNodeMap)
331 entry->destination->gatewayId = gatewayId;
332 entry->nextHop = gatewayNodeMap;
333 entry->destination->destIntfAddr = NULL;
334 entry->routeCost = routeCost;
336 else if (0 == nextHop)
338 entry->routeCost = 1;
339 // Entry can't be updated if Next hop is not same as existing Destinations of Table.
340 OC_LOG(DEBUG, TAG, "Updating the gateway");
341 entry->nextHop = NULL;
342 entry->destination->destIntfAddr = u_arraylist_create();
343 if (NULL == entry->destination->destIntfAddr)
345 OC_LOG(ERROR, TAG, "Failed to create array list");
346 return OC_STACK_ERROR;
349 RTMDestIntfInfo_t *destAdr =
350 (RTMDestIntfInfo_t *) OICCalloc(1, sizeof(RTMDestIntfInfo_t));
353 OC_LOG(ERROR, TAG, "Failed to Calloc destAdr");
354 return OC_STACK_ERROR;
357 *destAdr = *destInterfaces;
358 destAdr->timeElapsed = RTMGetCurrentTime();
359 destAdr->isValid = true;
361 u_arraylist_add(entry->destination->destIntfAddr, (void *)destAdr);
364 OC_LOG(ERROR, TAG, "Adding node to head failed");
366 return OC_STACK_ERROR;
371 OC_LOG(ERROR, TAG, "Adding Gateway Failed as Next hop is invalid");
372 return OC_STACK_ERROR;
376 else if (NULL != entry && entry->routeCost < routeCost)
378 OC_LOG(ERROR, TAG, "Adding Gateway Failed as Route cost is more than old");
379 return OC_STACK_ERROR;
382 // Logic to add updated node to Head of list as route cost is 1.
383 if (1 == routeCost && NULL != entry)
385 OCStackResult res = u_linklist_remove(*gatewayTable, &destNode);
386 if (OC_STACK_OK != res)
388 OC_LOG(ERROR, TAG, "Removing node failed");
392 res = u_linklist_add_head(*gatewayTable, (void *)entry);
393 if (OC_STACK_OK != res)
395 OC_LOG(ERROR, TAG, "Adding node to head failed");
403 RTMGatewayEntry_t *hopEntry = (RTMGatewayEntry_t *)OICCalloc(1, sizeof(RTMGatewayEntry_t));
404 if (NULL == hopEntry)
406 OC_LOG(ERROR, TAG, "Calloc failed for hop entry");
407 return OC_STACK_ERROR;
410 hopEntry->destination = (RTMGatewayId_t*)OICCalloc(1, sizeof(RTMGatewayId_t));
411 if (NULL == hopEntry->destination)
413 OC_LOG(ERROR, TAG, "Calloc failed for hop entry destination");
415 return OC_STACK_ERROR;
418 hopEntry->destination->gatewayId = gatewayId;
419 if (NULL != destInterfaces && strlen((*destInterfaces).destIntfAddr.addr) > 0)
421 hopEntry->destination->destIntfAddr = u_arraylist_create();
422 RTMDestIntfInfo_t *destAdr =
423 (RTMDestIntfInfo_t *) OICCalloc(1, sizeof(RTMDestIntfInfo_t));
426 OC_LOG(ERROR, TAG, "Calloc failed for destAdr");
427 u_arraylist_free(&(hopEntry->destination->destIntfAddr));
428 OICFree(hopEntry->destination);
430 return OC_STACK_ERROR;
433 *destAdr = *destInterfaces;
434 destAdr->timeElapsed = RTMGetCurrentTime();
435 destAdr->isValid = true;
436 u_arraylist_add(hopEntry->destination->destIntfAddr, (void *)destAdr);
440 hopEntry->destination->destIntfAddr = NULL;
443 hopEntry->routeCost = routeCost;
444 // Mapped nextHop gateway to another entries having gateway as destination.
445 if (NULL != gatewayNodeMap)
447 hopEntry->nextHop = gatewayNodeMap;
449 else if (1 == routeCost)
451 hopEntry->nextHop = NULL;
455 OC_LOG(ERROR, TAG, "Adding Gateway Failed as Next Hop is invalid");
456 while (u_arraylist_length(hopEntry->destination->destIntfAddr) > 0)
458 RTMDestIntfInfo_t *data =
459 u_arraylist_remove(hopEntry->destination->destIntfAddr, 0);
462 u_arraylist_free(&(hopEntry->destination->destIntfAddr));
463 OICFree(hopEntry->destination);
466 return OC_STACK_ERROR;
469 OCStackResult ret = OC_STACK_OK;
470 if (hopEntry->routeCost == 1)
472 ret = u_linklist_add_head(*gatewayTable, (void *)hopEntry);
476 ret = u_linklist_add(*gatewayTable, (void *)hopEntry);
479 if (OC_STACK_OK != ret)
481 OC_LOG(ERROR, TAG, "Adding Gateway Entry to Routing Table failed");
482 while (u_arraylist_length(hopEntry->destination->destIntfAddr) > 0)
484 RTMDestIntfInfo_t *data = u_arraylist_remove(hopEntry->destination->destIntfAddr, 0);
487 u_arraylist_free(&(hopEntry->destination->destIntfAddr));
488 OICFree(hopEntry->destination);
490 return OC_STACK_ERROR;
493 OC_LOG(DEBUG, TAG, "OUT");
497 OCStackResult RTMAddEndpointEntry(uint16_t *endpointId, const CAEndpoint_t *destAddr,
498 u_linklist_t **endpointTable)
500 OC_LOG(DEBUG, TAG, "IN");
501 RM_NULL_CHECK_WITH_RET(endpointId, TAG, "endpointId");
502 RM_NULL_CHECK_WITH_RET(destAddr, TAG, "destAddr");
503 RM_NULL_CHECK_WITH_RET(endpointTable, TAG, "endpointTable");
504 if (NULL == *endpointTable)
506 *endpointTable = u_linklist_create();
509 u_linklist_iterator_t *iterTable = NULL;
510 u_linklist_init_iterator(*endpointTable, &iterTable);
511 // Iterate over gateway list to find if already entry with this gatewayid is present.
512 while (NULL != iterTable)
514 RTMEndpointEntry_t *entry =
515 (RTMEndpointEntry_t *) u_linklist_get_data(iterTable);
517 if (NULL != entry && (0 == memcmp(destAddr->addr, entry->destIntfAddr.addr,
518 strlen(entry->destIntfAddr.addr)))
519 && destAddr->port == entry->destIntfAddr.port)
521 *endpointId = entry->endpointId;
522 OC_LOG(ERROR, TAG, "Adding failed as Enpoint Entry Already present in Table");
523 return OC_STACK_DUPLICATE_REQUEST;
525 u_linklist_get_next(&iterTable);
529 RTMEndpointEntry_t *hopEntry = (RTMEndpointEntry_t *)OICCalloc(1, sizeof(RTMEndpointEntry_t));
531 if (NULL == hopEntry)
533 OC_LOG(ERROR, TAG, "Malloc failed for hop entry");
534 return OC_STACK_ERROR;
537 hopEntry->endpointId = *endpointId;
538 hopEntry->destIntfAddr = *destAddr;
540 OCStackResult ret = u_linklist_add(*endpointTable, (void *)hopEntry);
541 if (OC_STACK_OK != ret)
543 OC_LOG(ERROR, TAG, "Adding Enpoint Entry to Routing Table failed");
545 return OC_STACK_ERROR;
547 OC_LOG(DEBUG, TAG, "OUT");
551 OCStackResult RTMAddObserver(uint32_t obsID, CAEndpoint_t devAddr, u_linklist_t **gatewayTable)
553 OC_LOG(DEBUG, TAG, "IN");
554 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
555 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
557 u_linklist_iterator_t *iterTable = NULL;
558 u_linklist_init_iterator(*gatewayTable, &iterTable);
559 while (NULL != iterTable)
561 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
563 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
565 RTMDestIntfInfo_t *destCheck = u_arraylist_get(entry->destination->destIntfAddr, i);
566 if (NULL != destCheck &&
567 (0 == memcmp(destCheck->destIntfAddr.addr, devAddr.addr, strlen(devAddr.addr)))
568 && devAddr.port == destCheck->destIntfAddr.port)
570 destCheck->observerId = obsID;
571 OC_LOG(DEBUG, TAG, "OUT");
575 u_linklist_get_next(&iterTable);
577 OC_LOG(DEBUG, TAG, "OUT");
578 return OC_STACK_ERROR;
581 bool RTMIsObserverPresent(CAEndpoint_t devAddr, OCObservationId *obsID,
582 const u_linklist_t *gatewayTable)
584 OC_LOG(DEBUG, TAG, "IN");
587 OC_LOG(ERROR, TAG, "obsID is null");
591 if (NULL == gatewayTable)
593 OC_LOG(ERROR, TAG, "gatewayTable is null");
597 u_linklist_iterator_t *iterTable = NULL;
598 u_linklist_init_iterator(gatewayTable, &iterTable);
599 while (NULL != iterTable)
601 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
602 if (NULL == entry && NULL == entry->destination)
604 OC_LOG(ERROR, TAG, "entry is NULL");
607 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
609 RTMDestIntfInfo_t *destCheck =
610 u_arraylist_get(entry->destination->destIntfAddr, i);
611 if (NULL != destCheck && (0 == memcmp(destCheck->destIntfAddr.addr, devAddr.addr,
612 strlen(devAddr.addr)))
613 && devAddr.port == destCheck->destIntfAddr.port && 0 != destCheck->observerId)
615 *obsID = destCheck->observerId;
616 OC_LOG(DEBUG, TAG, "OUT");
620 u_linklist_get_next(&iterTable);
622 OC_LOG(DEBUG, TAG, "OUT");
626 OCStackResult RTMRemoveGatewayEntry(uint32_t gatewayId, u_linklist_t **removedGatewayNodes,
627 u_linklist_t **gatewayTable)
629 OC_LOG(DEBUG, TAG, "IN");
630 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
631 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
633 u_linklist_iterator_t *iterTable = NULL;
635 // if link list is not null we can directly add removed nodes to it instead of creating everytime.
636 if (NULL == *removedGatewayNodes)
638 *removedGatewayNodes = u_linklist_create();
640 OCStackResult ret = OC_STACK_OK;
641 u_linklist_init_iterator(*gatewayTable, &iterTable);
642 while (NULL != iterTable)
644 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
645 if (NULL == entry || NULL == entry->destination)
647 u_linklist_get_next(&iterTable);
651 if (gatewayId == entry->destination->gatewayId || (NULL != entry->nextHop &&
652 (gatewayId == entry->nextHop->gatewayId)))
654 OC_LOG_V(DEBUG, TAG, "Removing the gateway entry: %u", entry->destination->gatewayId);
655 ret = u_linklist_remove(*gatewayTable, &iterTable);
656 if (OC_STACK_OK != ret)
658 OC_LOG(ERROR, TAG, "Deleting Entry from Routing Table failed");
659 return OC_STACK_ERROR;
663 u_linklist_add(*removedGatewayNodes, (void *)entry);
668 u_linklist_get_next(&iterTable);
671 OC_LOG(DEBUG, TAG, "RTMRemoveGatewayEntry OUT");
675 OCStackResult RTMRemoveGatewayDestEntry(uint32_t gatewayId, uint32_t nextHop,
676 const RTMDestIntfInfo_t *destInfAdr,
677 RTMGatewayEntry_t **existEntry, u_linklist_t **gatewayTable)
679 OC_LOG(DEBUG, TAG, "IN");
680 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
681 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
682 RM_NULL_CHECK_WITH_RET(destInfAdr, TAG, "destInfAdr");
684 u_linklist_iterator_t *iterTable = NULL;
686 OCStackResult ret = -1;
687 u_linklist_init_iterator(*gatewayTable, &iterTable);
688 while (NULL != iterTable)
690 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
693 u_linklist_get_next(&iterTable);
697 // Update the time for NextHop entry.
698 if (NULL != entry->destination && nextHop == entry->destination->gatewayId)
700 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
702 RTMDestIntfInfo_t *destCheck = u_arraylist_get(entry->destination->destIntfAddr, i);
703 if (0 == memcmp(destCheck->destIntfAddr.addr, destInfAdr->destIntfAddr.addr,
704 strlen(destInfAdr->destIntfAddr.addr))
705 && destInfAdr->destIntfAddr.port == destCheck->destIntfAddr.port)
707 destCheck->timeElapsed = RTMGetCurrentTime();
713 // Remove node with given gatewayid and nextHop if not found update exist entry.
714 if (NULL != entry->destination && (gatewayId == entry->destination->gatewayId))
716 OC_LOG_V(INFO, TAG, "Remove the gateway ID: %u", entry->destination->gatewayId);
717 if (NULL != entry->nextHop && nextHop == entry->nextHop->gatewayId)
719 ret = u_linklist_remove(*gatewayTable, &iterTable);
720 if (OC_STACK_OK != ret)
722 OC_LOG(ERROR, TAG, "Deleting Entry from Routing Table failed");
723 return OC_STACK_ERROR;
730 OC_LOG(DEBUG, TAG, "OUT");
731 return OC_STACK_ERROR;
734 u_linklist_get_next(&iterTable);
736 OC_LOG(DEBUG, TAG, "OUT");
737 return OC_STACK_ERROR;
740 OCStackResult RTMRemoveEndpointEntry(uint16_t endpointId, u_linklist_t **endpointTable)
742 OC_LOG(DEBUG, TAG, "IN");
743 RM_NULL_CHECK_WITH_RET(endpointTable, TAG, "endpointTable");
744 RM_NULL_CHECK_WITH_RET(*endpointTable, TAG, "*endpointTable");
746 u_linklist_iterator_t *iterTable = NULL;
747 u_linklist_init_iterator(*endpointTable, &iterTable);
748 while (NULL != iterTable)
750 RTMEndpointEntry_t *entry = u_linklist_get_data(iterTable);
751 if (NULL != entry && endpointId == entry->endpointId)
753 OCStackResult ret = u_linklist_remove(*endpointTable, &iterTable);
754 if (OC_STACK_OK != ret)
756 OC_LOG(ERROR, TAG, "Deleting Entry from Routing Table failed");
757 return OC_STACK_ERROR;
763 u_linklist_get_next(&iterTable);
766 OC_LOG(DEBUG, TAG, "OUT");
770 OCStackResult RTMRemoveGateways(u_linklist_t **gatewayTable)
772 OC_LOG(DEBUG, TAG, "IN");
774 if (NULL == gatewayTable || NULL == *gatewayTable)
776 OC_LOG(DEBUG, TAG, "OUT");
780 OCStackResult ret = RTMFreeGatewayRouteTable(gatewayTable);
781 if (OC_STACK_OK != ret)
783 OC_LOG(ERROR, TAG, "Removing Gateways failed");
786 OC_LOG(DEBUG, TAG, "OUT");
790 OCStackResult RTMRemoveEndpoints(u_linklist_t **endpointTable)
792 OC_LOG(DEBUG, TAG, "IN");
793 if (NULL == endpointTable || NULL == *endpointTable)
795 OC_LOG(DEBUG, TAG, "OUT");
799 OCStackResult ret = RTMFreeEndpointRouteTable(endpointTable);
800 if (OC_STACK_OK != ret)
802 OC_LOG(ERROR, TAG, "Freeing Endpoints failed");
803 return OC_STACK_ERROR;
805 OC_LOG(DEBUG, TAG, "OUT");
809 void RTMFreeGateway(RTMGatewayId_t *gateway, u_linklist_t **gatewayTable)
811 OC_LOG(DEBUG, TAG, "IN");
812 RM_NULL_CHECK_VOID(gateway, TAG, "gateway");
813 RM_NULL_CHECK_VOID(gatewayTable, TAG, "gatewayTable");
814 RM_NULL_CHECK_VOID(*gatewayTable, TAG, "*gatewayTable");
815 while (0 < u_arraylist_length(gateway->destIntfAddr))
817 void *data = u_arraylist_remove(gateway->destIntfAddr, 0);
820 u_arraylist_free(&(gateway->destIntfAddr));
822 OC_LOG(DEBUG, TAG, "OUT");
825 void RTMGetNeighbours(u_linklist_t **neighbourNodes, const u_linklist_t *gatewayTable)
827 OC_LOG(DEBUG, TAG, "IN");
828 RM_NULL_CHECK_VOID(neighbourNodes, TAG, "neighbourNodes");
829 RM_NULL_CHECK_VOID(gatewayTable, TAG, "gatewayTable");
831 *neighbourNodes = u_linklist_create();
832 u_linklist_iterator_t *iterTable = NULL;
833 u_linklist_init_iterator(gatewayTable, &iterTable);
834 while (NULL != iterTable)
836 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
837 if (NULL != entry && 1 == entry->routeCost)
839 u_linklist_add(*neighbourNodes, (void *)entry);
841 else if (NULL != entry && 1 < entry->routeCost)
843 OC_LOG(DEBUG, TAG, "OUT");
847 u_linklist_get_next(&iterTable);
849 OC_LOG(DEBUG, TAG, "OUT");
852 RTMGatewayId_t *RTMGetNextHop(uint32_t gatewayId, const u_linklist_t *gatewayTable)
854 OC_LOG(DEBUG, TAG, "IN");
857 OC_LOG(ERROR, TAG, "gatewayId is invalid");
861 if (NULL == gatewayTable)
863 OC_LOG(ERROR, TAG, "gatewayTable is null");
867 u_linklist_iterator_t *iterTable = NULL;
868 u_linklist_init_iterator(gatewayTable, &iterTable);
869 while (NULL != iterTable)
871 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
872 if (NULL != entry && gatewayId == entry->destination->gatewayId)
874 if (1 == entry->routeCost)
876 OC_LOG(DEBUG, TAG, "OUT");
877 return entry->destination;
879 OC_LOG(DEBUG, TAG, "OUT");
880 return entry->nextHop;
882 u_linklist_get_next(&iterTable);
884 OC_LOG(DEBUG, TAG, "OUT");
888 CAEndpoint_t *RTMGetEndpointEntry(uint16_t endpointId, const u_linklist_t *endpointTable)
890 OC_LOG(DEBUG, TAG, "IN");
891 if (NULL == endpointTable)
893 OC_LOG(ERROR, TAG, "endpointTable is null");
897 u_linklist_iterator_t *iterTable = NULL;
898 u_linklist_init_iterator(endpointTable, &iterTable);
900 while (NULL != iterTable)
902 RTMEndpointEntry_t *entry = u_linklist_get_data(iterTable);
903 if (NULL != entry && (endpointId == entry->endpointId))
905 OC_LOG(DEBUG, TAG, "OUT");
906 return &(entry->destIntfAddr);
908 u_linklist_get_next(&iterTable);
910 OC_LOG(DEBUG, TAG, "OUT");
914 void RTMGetObserverList(OCObservationId **obsList, uint8_t *obsListLen,
915 const u_linklist_t *gatewayTable)
917 OC_LOG(DEBUG, TAG, "IN");
918 RM_NULL_CHECK_VOID(gatewayTable, TAG, "gatewayTable");
919 RM_NULL_CHECK_VOID(obsList, TAG, "obsList");
921 *obsList = (OCObservationId *) OICCalloc(MAX_OBSERVER_LIST_LENGTH, sizeof(OCObservationId));
922 u_linklist_iterator_t *iterTable = NULL;
923 u_linklist_init_iterator(gatewayTable, &iterTable);
925 while (NULL != iterTable)
927 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
928 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
930 RTMDestIntfInfo_t *destCheck = u_arraylist_get(entry->destination->destIntfAddr, i);
931 if (NULL == destCheck)
933 OC_LOG(ERROR, TAG, "destCheck is null");
936 if (0 != destCheck->observerId)
938 OC_LOG_V(DEBUG, TAG, "Observer ID is %d", destCheck->observerId);
939 *(*obsList + len) = destCheck->observerId;
942 if (MAX_OBSERVER_LIST_LENGTH < len)
944 *obsList = (OCObservationId *) OICRealloc((void *)*obsList,
945 (sizeof(OCObservationId) * (len + 1)));
949 u_linklist_get_next(&iterTable);
953 OC_LOG(DEBUG, TAG, "OUT");
956 OCStackResult RTMUpdateDestinationIntfAdr(uint32_t gatewayId, RTMDestIntfInfo_t destInterfaces,
957 bool addAdr, u_linklist_t **gatewayTable)
959 OC_LOG(DEBUG, TAG, "IN");
960 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
961 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
963 u_linklist_iterator_t *iterTable = NULL;
964 u_linklist_init_iterator(*gatewayTable, &iterTable);
965 while (NULL != iterTable)
967 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
968 if (NULL != entry && NULL != entry->destination &&
969 gatewayId == entry->destination->gatewayId)
973 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
975 RTMDestIntfInfo_t *destCheck =
976 u_arraylist_get(entry->destination->destIntfAddr, i);
977 if (NULL == destCheck)
979 OC_LOG(ERROR, TAG, "Destination adr get failed");
983 if (0 == memcmp(destCheck->destIntfAddr.addr, destInterfaces.destIntfAddr.addr,
984 strlen(destInterfaces.destIntfAddr.addr))
985 && destInterfaces.destIntfAddr.port == destCheck->destIntfAddr.port)
987 destCheck->timeElapsed = RTMGetCurrentTime();
988 destCheck->isValid = true;
989 OC_LOG(ERROR, TAG, "destInterfaces already present");
990 return OC_STACK_ERROR;
994 RTMDestIntfInfo_t *destAdr =
995 (RTMDestIntfInfo_t *) OICCalloc(1, sizeof(RTMDestIntfInfo_t));
998 OC_LOG(ERROR, TAG, "Calloc destAdr failed");
999 return OC_STACK_ERROR;
1001 *destAdr = destInterfaces;
1002 destAdr->timeElapsed = RTMGetCurrentTime();
1003 destAdr->isValid = true;
1005 u_arraylist_add(entry->destination->destIntfAddr, (void *)destAdr);
1008 OC_LOG(ERROR, TAG, "Updating Destinterface address failed");
1010 return OC_STACK_ERROR;
1012 OC_LOG(DEBUG, TAG, "OUT");
1013 return OC_STACK_DUPLICATE_REQUEST;
1016 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
1018 RTMDestIntfInfo_t *removeAdr =
1019 u_arraylist_get(entry->destination->destIntfAddr, i);
1020 if (0 == memcmp(removeAdr->destIntfAddr.addr, destInterfaces.destIntfAddr.addr,
1021 strlen(destInterfaces.destIntfAddr.addr))
1022 && destInterfaces.destIntfAddr.port == removeAdr->destIntfAddr.port)
1024 RTMDestIntfInfo_t *data =
1025 u_arraylist_remove(entry->destination->destIntfAddr, i);
1031 u_linklist_get_next(&iterTable);
1033 OC_LOG(DEBUG, TAG, "OUT");
1037 OCStackResult RTMUpdateMcastSeqNumber(uint32_t gatewayId, uint16_t seqNum,
1038 u_linklist_t **gatewayTable)
1040 OC_LOG(DEBUG, TAG, "IN");
1041 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
1042 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
1044 u_linklist_iterator_t *iterTable = NULL;
1045 u_linklist_init_iterator(*gatewayTable, &iterTable);
1046 while (NULL != iterTable)
1048 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
1049 if (NULL != entry && NULL != entry->destination &&
1050 gatewayId == entry->destination->gatewayId)
1052 if (0 == entry->mcastMessageSeqNum || entry->mcastMessageSeqNum < seqNum)
1054 entry->mcastMessageSeqNum = seqNum;
1057 else if (entry->mcastMessageSeqNum == seqNum)
1059 return OC_STACK_DUPLICATE_REQUEST;
1063 return OC_STACK_COMM_ERROR;
1066 u_linklist_get_next(&iterTable);
1068 OC_LOG(DEBUG, TAG, "OUT");
1072 uint64_t RTMGetCurrentTime()
1074 uint64_t currentTime = 0;
1077 struct timespec getTs;
1079 clock_gettime(CLOCK_MONOTONIC, &getTs);
1081 currentTime = getTs.tv_sec;
1082 #elif defined __ARDUINO__
1083 currentTime = millis() / 1000;
1085 #if _POSIX_TIMERS > 0
1087 clock_gettime(CLOCK_MONOTONIC, &ts);
1088 currentTime = ts.tv_sec;
1091 gettimeofday(&tv, NULL);
1092 currentTime = tv.tv_sec;
1098 OCStackResult RTMUpdateDestAddrValidity(u_linklist_t **invalidTable, u_linklist_t **gatewayTable)
1100 OC_LOG(DEBUG, TAG, "IN");
1101 RM_NULL_CHECK_WITH_RET(invalidTable, TAG, "invalidTable");
1102 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
1103 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
1105 *invalidTable = u_linklist_create();
1106 u_linklist_iterator_t *iterTable = NULL;
1107 uint64_t presentTime = RTMGetCurrentTime();
1109 u_linklist_init_iterator(*gatewayTable, &iterTable);
1110 while (NULL != iterTable)
1112 RTMGatewayEntry_t *entry = (RTMGatewayEntry_t *) u_linklist_get_data(iterTable);
1115 u_linklist_get_next(&iterTable);
1118 else if (1 == entry->routeCost)
1120 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
1122 RTMDestIntfInfo_t *destCheck = u_arraylist_get(entry->destination->destIntfAddr, i);
1123 if (GATEWAY_ALIVE_TIMEOUT < (presentTime - destCheck->timeElapsed))
1125 destCheck->isValid = false;
1126 u_linklist_add(*invalidTable, (void *)destCheck);
1130 else if (1 < entry->routeCost)
1134 u_linklist_get_next(&iterTable);
1136 OC_LOG(DEBUG, TAG, "OUT");
1140 OCStackResult RTMRemoveInvalidGateways(u_linklist_t **invalidTable, u_linklist_t **gatewayTable)
1142 OC_LOG(DEBUG, TAG, "IN");
1143 RM_NULL_CHECK_WITH_RET(invalidTable, TAG, "invalidTable");
1144 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
1145 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
1147 *invalidTable = u_linklist_create();
1149 u_linklist_iterator_t *iterTable = NULL;
1150 u_linklist_init_iterator(*gatewayTable, &iterTable);
1151 while (iterTable != NULL)
1153 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
1157 u_linklist_get_next(&iterTable);
1160 else if (NULL != entry->destination && (1 == entry->routeCost))
1162 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
1164 RTMDestIntfInfo_t *destCheck = u_arraylist_get(entry->destination->destIntfAddr, i);
1165 if (!destCheck->isValid)
1167 void *data = u_arraylist_remove(entry->destination->destIntfAddr, i);
1173 if (0 == u_arraylist_length(entry->destination->destIntfAddr))
1175 u_arraylist_free(&(entry->destination->destIntfAddr));
1177 RTMRemoveGatewayEntry(entry->destination->gatewayId, invalidTable, gatewayTable);
1178 if (OC_STACK_OK != res)
1180 OC_LOG(ERROR, TAG, "Removing Entries failed");
1181 return OC_STACK_ERROR;
1183 u_linklist_get_next(&iterTable);
1187 u_linklist_get_next(&iterTable);
1190 else if (1 < entry->routeCost)
1196 u_linklist_get_next(&iterTable);
1199 OC_LOG(DEBUG, TAG, "OUT");
1203 OCStackResult RTMUpdateEntryParameters(uint32_t gatewayId, uint32_t seqNum,
1204 const RTMDestIntfInfo_t *destAdr, u_linklist_t **gatewayTable,
1207 OC_LOG(DEBUG, TAG, "IN");
1208 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
1209 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
1210 RM_NULL_CHECK_WITH_RET(destAdr, TAG, "destAdr");
1212 u_linklist_iterator_t *iterTable = NULL;
1213 u_linklist_init_iterator(*gatewayTable, &iterTable);
1214 while (NULL != iterTable)
1216 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
1220 u_linklist_get_next(&iterTable);
1223 if (NULL != entry->destination && gatewayId == entry->destination->gatewayId)
1225 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
1227 RTMDestIntfInfo_t *destCheck =
1228 u_arraylist_get(entry->destination->destIntfAddr, i);
1229 if (NULL != destCheck &&
1230 (0 == memcmp(destCheck->destIntfAddr.addr, destAdr->destIntfAddr.addr,
1231 strlen(destAdr->destIntfAddr.addr)))
1232 && destAdr->destIntfAddr.port == destCheck->destIntfAddr.port)
1234 destCheck->timeElapsed = RTMGetCurrentTime();
1235 destCheck->isValid = true;
1239 if (0 != entry->seqNum && seqNum == entry->seqNum)
1241 return OC_STACK_DUPLICATE_REQUEST;
1243 else if (0 != entry->seqNum && seqNum != ((entry->seqNum) + 1) && !forceUpdate)
1245 return OC_STACK_COMM_ERROR;
1249 entry->seqNum = seqNum;
1250 OC_LOG(DEBUG, TAG, "OUT");
1254 u_linklist_get_next(&iterTable);
1256 OC_LOG(DEBUG, TAG, "OUT");
1260 void RTMPrintTable(const u_linklist_t *gatewayTable, const u_linklist_t *endpointTable)
1262 RM_NULL_CHECK_VOID(gatewayTable, TAG, "gatewayTable");
1263 OC_LOG(DEBUG, RM_TAG, "=================Gateway List table============================\n");
1264 u_linklist_iterator_t *iterTable = NULL;
1265 u_linklist_init_iterator(gatewayTable, &iterTable);
1266 while (NULL != iterTable)
1268 RTMGatewayEntry_t *hop =
1269 (RTMGatewayEntry_t *) u_linklist_get_data(iterTable);
1272 OC_LOG(ERROR, RM_TAG, "Printing Table Failed");
1275 if (NULL == hop->nextHop || 0 == hop->nextHop->gatewayId)
1277 OC_LOG_V(DEBUG, RM_TAG, "\nDestination : %u\nNextHop : (null)\nHopCount : %d",
1278 hop->destination->gatewayId, hop->routeCost);
1279 OC_LOG_V(DEBUG, RM_TAG, "\nSequence Number :%u", hop->seqNum);
1283 OC_LOG_V(DEBUG, RM_TAG, "\nDestination : %u\nNextHop : %u\nHopCount : %d",
1284 hop->destination->gatewayId, hop->nextHop->gatewayId, hop->routeCost);
1285 OC_LOG_V(DEBUG, RM_TAG, "\nSequence Number :%u", hop->seqNum);
1287 if (1 == hop->routeCost && NULL != hop->destination &&
1288 hop->destination->destIntfAddr != NULL)
1290 for (uint32_t i = 0; i < u_arraylist_length(hop->destination->destIntfAddr); i++)
1292 RTMDestIntfInfo_t *dest = u_arraylist_get(hop->destination->destIntfAddr, i);
1295 OC_LOG_V(DEBUG, RM_TAG, "\nDestination interface addresses: %s Port : %d Obs ID: %d",
1296 dest->destIntfAddr.addr, dest->destIntfAddr.port, dest->observerId);
1297 OC_LOG_V(DEBUG, RM_TAG, "Validity: %d", dest->isValid);
1301 OC_LOG(DEBUG, RM_TAG, "********************************************\n");
1302 u_linklist_get_next(&iterTable);
1305 OC_LOG(DEBUG, RM_TAG, "=================Endpoint List table============================\n");
1306 u_linklist_iterator_t *iterEndpointTable = NULL;
1307 u_linklist_init_iterator(endpointTable, &iterEndpointTable);
1309 // Iterate over endpoint list to find if already entry for gatewayid is present.
1310 while (NULL != iterEndpointTable)
1312 RTMEndpointEntry_t *hop =
1313 (RTMEndpointEntry_t *) u_linklist_get_data(iterEndpointTable);
1316 OC_LOG(ERROR, RM_TAG, "Printing Table Failed");
1319 OC_LOG_V(DEBUG, RM_TAG, "EndpointId : %u\naddr : %s Port : %d",
1320 hop->endpointId, hop->destIntfAddr.addr, hop->destIntfAddr.port);
1322 OC_LOG(DEBUG, RM_TAG, "********************************************\n");
1323 u_linklist_get_next(&iterEndpointTable);