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 "routingtablemanager_endpoint.h"
25 #include "routingutility.h"
26 #include "oic_malloc.h"
27 #include "oic_string.h"
28 #include "include/logger.h"
31 * Logging tag for module name.
33 #define TAG "OIC_RM_TM"
36 * Tag for printing the Routing table.
38 #define RM_TAG "OIC_RM_RAP"
42 * Initial Length of observer list.
44 #define MAX_OBSERVER_LIST_LENGTH 10
46 static const uint64_t USECS_PER_SEC = 1000000;
48 OCStackResult RTMInitialize(u_linklist_t **gatewayTable, u_linklist_t **endpointTable)
50 OIC_LOG(DEBUG, TAG, "RTMInitialize IN");
51 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
52 RM_NULL_CHECK_WITH_RET(endpointTable, TAG, "endpointTable");
53 if (NULL == *gatewayTable)
55 *gatewayTable = u_linklist_create();
56 if (NULL == *gatewayTable)
58 OIC_LOG(ERROR, TAG, "Creating Routing Table failed");
59 RTMTerminate(gatewayTable, endpointTable);
60 return OC_STACK_ERROR;
64 if (OC_STACK_ERROR == RTMEndpointInitialize(endpointTable))
66 OIC_LOG(ERROR, TAG, "Creating EndPoint Routing Table failed");
67 RTMTerminate(gatewayTable, endpointTable);
68 return OC_STACK_ERROR;
71 OIC_LOG(DEBUG, TAG, "RTMInitialize OUT");
76 * Freeing every char pointer and array list of gateway entry here and frees the table.
78 OCStackResult RTMFreeGatewayRouteTable(u_linklist_t **gatewayTable)
80 OIC_LOG(DEBUG, TAG, "RTMFreeGatewayRouteTable IN");
81 if (NULL == gatewayTable || NULL == *gatewayTable)
86 u_linklist_iterator_t *iterTable = NULL;
87 u_linklist_init_iterator(*gatewayTable, &iterTable);
88 while (NULL != iterTable)
90 RTMGatewayEntry_t *hop = u_linklist_get_data(iterTable);
91 if (NULL != hop && NULL != hop->destination)
93 while (u_arraylist_length(hop->destination->destIntfAddr) > 0)
95 if (NULL != hop->destination)
97 RTMDestIntfInfo_t *data = u_arraylist_remove(hop->destination->destIntfAddr, 0);
101 u_arraylist_free(&(hop->destination->destIntfAddr));
102 OICFree(hop->destination);
103 // No need to free next hop as it is already freed during it's gateway free
107 OCStackResult ret = u_linklist_remove(*gatewayTable, &iterTable);
108 if (OC_STACK_OK != ret)
110 OIC_LOG(ERROR, TAG, "Deleting Entry from Routing Table failed");
111 return OC_STACK_ERROR;
114 u_linklist_free(gatewayTable);
115 OIC_LOG(DEBUG, TAG, "RTMFreeGatewayRouteTable OUT");
119 OCStackResult RTMFreeGatewayIdList(u_linklist_t **gatewayIdTable)
121 OIC_LOG(DEBUG, TAG, "IN");
122 if (NULL == gatewayIdTable || NULL == *gatewayIdTable)
127 u_linklist_iterator_t *iterTable = NULL;
128 u_linklist_init_iterator(*gatewayIdTable, &iterTable);
129 while (iterTable != NULL)
131 RTMGatewayId_t *hop = u_linklist_get_data(iterTable);
134 while (u_arraylist_length(hop->destIntfAddr) > 0)
136 RTMDestIntfInfo_t *data = u_arraylist_remove(hop->destIntfAddr, 0);
139 u_arraylist_free(&(hop->destIntfAddr));
142 OCStackResult ret = u_linklist_remove(*gatewayIdTable, &iterTable);
143 if (OC_STACK_OK != ret)
145 OIC_LOG(ERROR, TAG, "Deleting Entry from Routing Table failed");
146 return OC_STACK_ERROR;
151 OCStackResult res = u_linklist_remove(*gatewayIdTable, &iterTable);
152 if (OC_STACK_OK != res)
154 OIC_LOG(ERROR, TAG, "Deleting Entry from Routing Table failed");
155 return OC_STACK_ERROR;
159 OIC_LOG(DEBUG, TAG, "OUT");
164 * Freeing memory first and then Freeing linked list for gateway and endpoint.
166 OCStackResult RTMTerminate(u_linklist_t **gatewayTable, u_linklist_t **endpointTable)
168 OIC_LOG(DEBUG, TAG, "IN");
170 OCStackResult ret = RTMFreeGatewayRouteTable(gatewayTable);
171 if (OC_STACK_OK != ret)
173 OIC_LOG(ERROR, TAG, "Deleting Gateway Routing Table failed");
175 if (NULL != *gatewayTable)
177 *gatewayTable = NULL;
180 RTMEndpointTerminate(endpointTable);
181 OIC_LOG(DEBUG, TAG, "OUT");
186 * Checks if destination gateway to be added is already present and update if present or
187 * adds new entry if not present.
188 * Adds Entry to head if route cost is 1.
189 * Adds Entry to Tail if route cost is > 1.
190 * Checks for Gateway id Memory and assigns to next hop address to achieve better memory usage.
192 OCStackResult RTMAddGatewayEntry(uint32_t gatewayId, uint32_t nextHop, uint32_t routeCost,
193 const RTMDestIntfInfo_t *destInterfaces, u_linklist_t **gatewayTable)
195 OIC_LOG(DEBUG, TAG, "IN");
196 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
197 if (NULL == *gatewayTable)
199 *gatewayTable = u_linklist_create();
200 if (NULL == *gatewayTable)
202 OIC_LOG(ERROR, TAG, "u_linklist_create failed");
203 return OC_STACK_NO_MEMORY;
207 if (1 == routeCost && 0 != nextHop)
209 OIC_LOG(ERROR, TAG, "Adding Gateway Failed as Next Hop should be 0 for route cost 1");
210 return OC_STACK_ERROR;
215 OIC_LOG(ERROR, TAG, "Adding Gateway Failed as Route cost shouldnot be less than 1");
216 return OC_STACK_ERROR;
219 u_linklist_iterator_t *destNode = NULL;
220 RTMGatewayId_t *gatewayNodeMap = NULL; // Gateway id ponter can be mapped to NextHop of entry.
222 u_linklist_iterator_t *iterTable = NULL;
223 u_linklist_init_iterator(*gatewayTable, &iterTable);
224 // Iterate over gateway list to find if already entry with this gatewayid is present.
225 while (NULL != iterTable)
227 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
233 // To save node with same gateway id (To update entry instead of add new entry).
234 if (NULL == destNode && NULL != entry->destination &&
235 (gatewayId == entry->destination->gatewayId))
237 destNode = iterTable;
240 // To find pointer of gateway id for a node provided next hop equals to existing gateway id.
241 if (0 != nextHop && NULL != entry->destination &&
242 nextHop == entry->destination->gatewayId)
244 gatewayNodeMap = entry->destination;
247 if (NULL != destNode && NULL != gatewayNodeMap)
252 u_linklist_get_next(&iterTable);
255 if (1 < routeCost && NULL == gatewayNodeMap)
257 OIC_LOG(ERROR, TAG, "Adding Gateway Failed as Next Hop is invalid");
258 return OC_STACK_ERROR;
261 //Logic to update entry if it is already destination present or to add new entry.
262 if (NULL != destNode)
264 RTMGatewayEntry_t *entry = u_linklist_get_data(destNode);
266 if (NULL != entry && 1 == entry->routeCost && 0 == nextHop)
268 if (NULL == destInterfaces)
270 OIC_LOG(ERROR, TAG, "Not Adding Gateway destInterfaces is NULL");
271 return OC_STACK_ERROR;
273 OCStackResult update = RTMUpdateDestinationIntfAdr(gatewayId, *destInterfaces, true,
275 if (OC_STACK_OK != update)
277 OIC_LOG(ERROR, TAG, "RTMUpdateDestinationIntfAdr failed");
281 else if (NULL != entry && entry->routeCost >= routeCost)
283 if (entry->routeCost == routeCost && NULL != entry->nextHop &&
284 (nextHop == entry->nextHop->gatewayId))
286 OIC_LOG(ERROR, TAG, "Not Adding Gateway As it is Duplicate request");
287 return OC_STACK_DUPLICATE_REQUEST;
290 //Mapped nextHop gateway to another entries having gateway as destination.
291 if (NULL != gatewayNodeMap)
293 entry->destination->gatewayId = gatewayId;
294 entry->nextHop = gatewayNodeMap;
295 entry->destination->destIntfAddr = NULL;
296 entry->routeCost = routeCost;
298 else if (0 == nextHop)
300 entry->routeCost = 1;
301 // Entry can't be updated if Next hop is not same as existing Destinations of Table.
302 OIC_LOG(DEBUG, TAG, "Updating the gateway");
303 entry->nextHop = NULL;
304 entry->destination->destIntfAddr = u_arraylist_create();
305 if (NULL == entry->destination->destIntfAddr)
307 OIC_LOG(ERROR, TAG, "Failed to create array list");
308 return OC_STACK_ERROR;
311 RTMDestIntfInfo_t *destAdr =
312 (RTMDestIntfInfo_t *) OICCalloc(1, sizeof(RTMDestIntfInfo_t));
315 OIC_LOG(ERROR, TAG, "Failed to Calloc destAdr");
316 return OC_STACK_ERROR;
319 *destAdr = *destInterfaces;
320 destAdr->timeElapsed = RTMGetCurrentTime();
321 destAdr->isValid = true;
323 u_arraylist_add(entry->destination->destIntfAddr, (void *)destAdr);
326 OIC_LOG(ERROR, TAG, "Adding node to head failed");
328 return OC_STACK_ERROR;
333 OIC_LOG(ERROR, TAG, "Adding Gateway Failed as Next hop is invalid");
334 return OC_STACK_ERROR;
338 else if (NULL != entry && entry->routeCost < routeCost)
340 OIC_LOG(ERROR, TAG, "Adding Gateway Failed as Route cost is more than old");
341 return OC_STACK_ERROR;
344 // Logic to add updated node to Head of list as route cost is 1.
345 if (1 == routeCost && NULL != entry)
347 OCStackResult res = u_linklist_remove(*gatewayTable, &destNode);
348 if (OC_STACK_OK != res)
350 OIC_LOG(ERROR, TAG, "Removing node failed");
354 res = u_linklist_add_head(*gatewayTable, (void *)entry);
355 if (OC_STACK_OK != res)
357 OIC_LOG(ERROR, TAG, "Adding node to head failed");
365 RTMGatewayEntry_t *hopEntry = (RTMGatewayEntry_t *)OICCalloc(1, sizeof(RTMGatewayEntry_t));
366 if (NULL == hopEntry)
368 OIC_LOG(ERROR, TAG, "Calloc failed for hop entry");
369 return OC_STACK_ERROR;
372 hopEntry->destination = (RTMGatewayId_t*)OICCalloc(1, sizeof(RTMGatewayId_t));
373 if (NULL == hopEntry->destination)
375 OIC_LOG(ERROR, TAG, "Calloc failed for hop entry destination");
377 return OC_STACK_ERROR;
380 hopEntry->destination->gatewayId = gatewayId;
381 if (NULL != destInterfaces && strlen((*destInterfaces).destIntfAddr.addr) > 0)
383 hopEntry->destination->destIntfAddr = u_arraylist_create();
384 RTMDestIntfInfo_t *destAdr =
385 (RTMDestIntfInfo_t *) OICCalloc(1, sizeof(RTMDestIntfInfo_t));
388 OIC_LOG(ERROR, TAG, "Calloc failed for destAdr");
389 u_arraylist_free(&(hopEntry->destination->destIntfAddr));
390 OICFree(hopEntry->destination);
392 return OC_STACK_ERROR;
395 *destAdr = *destInterfaces;
396 destAdr->timeElapsed = RTMGetCurrentTime();
397 destAdr->isValid = true;
398 u_arraylist_add(hopEntry->destination->destIntfAddr, (void *)destAdr);
402 hopEntry->destination->destIntfAddr = NULL;
405 hopEntry->routeCost = routeCost;
406 // Mapped nextHop gateway to another entries having gateway as destination.
407 if (NULL != gatewayNodeMap)
409 hopEntry->nextHop = gatewayNodeMap;
411 else if (1 == routeCost)
413 hopEntry->nextHop = NULL;
417 OIC_LOG(ERROR, TAG, "Adding Gateway Failed as Next Hop is invalid");
418 while (u_arraylist_length(hopEntry->destination->destIntfAddr) > 0)
420 RTMDestIntfInfo_t *data =
421 u_arraylist_remove(hopEntry->destination->destIntfAddr, 0);
424 u_arraylist_free(&(hopEntry->destination->destIntfAddr));
425 OICFree(hopEntry->destination);
428 return OC_STACK_ERROR;
431 OCStackResult ret = OC_STACK_OK;
432 if (hopEntry->routeCost == 1)
434 ret = u_linklist_add_head(*gatewayTable, (void *)hopEntry);
438 ret = u_linklist_add(*gatewayTable, (void *)hopEntry);
441 if (OC_STACK_OK != ret)
443 OIC_LOG(ERROR, TAG, "Adding Gateway Entry to Routing Table failed");
444 while (u_arraylist_length(hopEntry->destination->destIntfAddr) > 0)
446 RTMDestIntfInfo_t *data = u_arraylist_remove(hopEntry->destination->destIntfAddr, 0);
449 u_arraylist_free(&(hopEntry->destination->destIntfAddr));
450 OICFree(hopEntry->destination);
452 return OC_STACK_ERROR;
455 OIC_LOG(DEBUG, TAG, "OUT");
459 OCStackResult RTMAddObserver(uint32_t obsID, CAEndpoint_t devAddr, u_linklist_t **gatewayTable)
461 OIC_LOG(DEBUG, TAG, "IN");
462 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
463 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
465 u_linklist_iterator_t *iterTable = NULL;
466 u_linklist_init_iterator(*gatewayTable, &iterTable);
467 while (NULL != iterTable)
469 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
471 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
473 RTMDestIntfInfo_t *destCheck = u_arraylist_get(entry->destination->destIntfAddr, i);
474 if (NULL != destCheck &&
475 (0 == memcmp(destCheck->destIntfAddr.addr, devAddr.addr, strlen(devAddr.addr)))
476 && devAddr.port == destCheck->destIntfAddr.port)
478 destCheck->observerId = obsID;
479 OIC_LOG(DEBUG, TAG, "OUT");
483 u_linklist_get_next(&iterTable);
485 OIC_LOG(DEBUG, TAG, "OUT");
486 return OC_STACK_ERROR;
489 bool RTMIsObserverPresent(CAEndpoint_t devAddr, OCObservationId *obsID,
490 const u_linklist_t *gatewayTable)
492 OIC_LOG(DEBUG, TAG, "IN");
495 OIC_LOG(ERROR, TAG, "obsID is null");
499 if (NULL == gatewayTable)
501 OIC_LOG(ERROR, TAG, "gatewayTable is null");
505 u_linklist_iterator_t *iterTable = NULL;
506 u_linklist_init_iterator(gatewayTable, &iterTable);
507 while (NULL != iterTable)
509 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
510 if (NULL == entry || NULL == entry->destination)
512 OIC_LOG(ERROR, TAG, "entry is NULL");
515 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
517 RTMDestIntfInfo_t *destCheck =
518 u_arraylist_get(entry->destination->destIntfAddr, i);
519 if (NULL != destCheck && (0 == memcmp(destCheck->destIntfAddr.addr, devAddr.addr,
520 strlen(devAddr.addr)))
521 && devAddr.port == destCheck->destIntfAddr.port && 0 != destCheck->observerId)
523 *obsID = destCheck->observerId;
524 OIC_LOG(DEBUG, TAG, "OUT");
528 u_linklist_get_next(&iterTable);
530 OIC_LOG(DEBUG, TAG, "OUT");
534 OCStackResult RTMRemoveGatewayEntry(uint32_t gatewayId, u_linklist_t **removedGatewayNodes,
535 u_linklist_t **gatewayTable)
537 OIC_LOG(DEBUG, TAG, "IN");
538 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
539 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
541 u_linklist_iterator_t *iterTable = NULL;
543 // if link list is not null we can directly add removed nodes to it instead of creating everytime.
544 if (NULL == *removedGatewayNodes)
546 *removedGatewayNodes = u_linklist_create();
547 if (NULL == *removedGatewayNodes)
549 OIC_LOG(ERROR, TAG, "u_linklist_create failed");
550 return OC_STACK_NO_MEMORY;
553 OCStackResult ret = OC_STACK_OK;
554 u_linklist_init_iterator(*gatewayTable, &iterTable);
555 while (NULL != iterTable)
557 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
558 if (NULL == entry || NULL == entry->destination)
560 u_linklist_get_next(&iterTable);
564 if (gatewayId == entry->destination->gatewayId || (NULL != entry->nextHop &&
565 (gatewayId == entry->nextHop->gatewayId)))
567 OIC_LOG_V(DEBUG, TAG, "Removing the gateway entry: %u", entry->destination->gatewayId);
568 ret = u_linklist_remove(*gatewayTable, &iterTable);
569 if (OC_STACK_OK != ret)
571 OIC_LOG(ERROR, TAG, "Deleting Entry from Routing Table failed");
572 return OC_STACK_ERROR;
576 u_linklist_add(*removedGatewayNodes, (void *)entry);
581 u_linklist_get_next(&iterTable);
584 OIC_LOG(DEBUG, TAG, "RTMRemoveGatewayEntry OUT");
588 OCStackResult RTMRemoveGatewayDestEntry(uint32_t gatewayId, uint32_t nextHop,
589 const RTMDestIntfInfo_t *destInfAdr,
590 RTMGatewayEntry_t **existEntry, u_linklist_t **gatewayTable)
592 OIC_LOG(DEBUG, TAG, "IN");
593 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
594 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
595 RM_NULL_CHECK_WITH_RET(destInfAdr, TAG, "destInfAdr");
597 u_linklist_iterator_t *iterTable = NULL;
599 OCStackResult ret = -1;
600 u_linklist_init_iterator(*gatewayTable, &iterTable);
601 while (NULL != iterTable)
603 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
606 u_linklist_get_next(&iterTable);
610 // Update the time for NextHop entry.
611 if (NULL != entry->destination && nextHop == entry->destination->gatewayId)
613 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
615 RTMDestIntfInfo_t *destCheck = u_arraylist_get(entry->destination->destIntfAddr, i);
620 if (0 == memcmp(destCheck->destIntfAddr.addr, destInfAdr->destIntfAddr.addr,
621 strlen(destInfAdr->destIntfAddr.addr))
622 && destInfAdr->destIntfAddr.port == destCheck->destIntfAddr.port)
624 destCheck->timeElapsed = RTMGetCurrentTime();
630 // Remove node with given gatewayid and nextHop if not found update exist entry.
631 if (NULL != entry->destination && (gatewayId == entry->destination->gatewayId))
633 OIC_LOG_V(INFO, TAG, "Remove the gateway ID: %u", entry->destination->gatewayId);
634 if (NULL != entry->nextHop && nextHop == entry->nextHop->gatewayId)
636 ret = u_linklist_remove(*gatewayTable, &iterTable);
637 if (OC_STACK_OK != ret)
639 OIC_LOG(ERROR, TAG, "Deleting Entry from Routing Table failed");
640 return OC_STACK_ERROR;
647 OIC_LOG(DEBUG, TAG, "OUT");
648 return OC_STACK_ERROR;
651 u_linklist_get_next(&iterTable);
653 OIC_LOG(DEBUG, TAG, "OUT");
654 return OC_STACK_ERROR;
657 OCStackResult RTMRemoveGateways(u_linklist_t **gatewayTable)
659 OIC_LOG(DEBUG, TAG, "IN");
661 if (NULL == gatewayTable || NULL == *gatewayTable)
663 OIC_LOG(DEBUG, TAG, "OUT");
667 OCStackResult ret = RTMFreeGatewayRouteTable(gatewayTable);
668 if (OC_STACK_OK != ret)
670 OIC_LOG(ERROR, TAG, "Removing Gateways failed");
673 OIC_LOG(DEBUG, TAG, "OUT");
677 void RTMFreeGateway(RTMGatewayId_t *gateway, u_linklist_t **gatewayTable)
679 OIC_LOG(DEBUG, TAG, "IN");
680 RM_NULL_CHECK_VOID(gateway, TAG, "gateway");
681 RM_NULL_CHECK_VOID(gatewayTable, TAG, "gatewayTable");
682 RM_NULL_CHECK_VOID(*gatewayTable, TAG, "*gatewayTable");
683 while (0 < u_arraylist_length(gateway->destIntfAddr))
685 void *data = u_arraylist_remove(gateway->destIntfAddr, 0);
688 u_arraylist_free(&(gateway->destIntfAddr));
690 OIC_LOG(DEBUG, TAG, "OUT");
693 void RTMGetNeighbours(u_linklist_t **neighbourNodes, const u_linklist_t *gatewayTable)
695 OIC_LOG(DEBUG, TAG, "IN");
696 RM_NULL_CHECK_VOID(neighbourNodes, TAG, "neighbourNodes");
697 RM_NULL_CHECK_VOID(gatewayTable, TAG, "gatewayTable");
699 *neighbourNodes = u_linklist_create();
700 if (NULL == *neighbourNodes)
702 OIC_LOG(ERROR, TAG, "u_linklist_create failed");
705 u_linklist_iterator_t *iterTable = NULL;
706 u_linklist_init_iterator(gatewayTable, &iterTable);
707 while (NULL != iterTable)
709 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
710 if (NULL != entry && 1 == entry->routeCost)
712 u_linklist_add(*neighbourNodes, (void *)entry);
714 else if (NULL != entry && 1 < entry->routeCost)
716 OIC_LOG(DEBUG, TAG, "OUT");
720 u_linklist_get_next(&iterTable);
722 OIC_LOG(DEBUG, TAG, "OUT");
725 RTMGatewayId_t *RTMGetNextHop(uint32_t gatewayId, const u_linklist_t *gatewayTable)
727 OIC_LOG(DEBUG, TAG, "IN");
730 OIC_LOG(ERROR, TAG, "gatewayId is invalid");
734 if (NULL == gatewayTable)
736 OIC_LOG(ERROR, TAG, "gatewayTable is null");
740 u_linklist_iterator_t *iterTable = NULL;
741 u_linklist_init_iterator(gatewayTable, &iterTable);
742 while (NULL != iterTable)
744 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
745 if (NULL != entry && gatewayId == entry->destination->gatewayId)
747 if (1 == entry->routeCost)
749 OIC_LOG(DEBUG, TAG, "OUT");
750 return entry->destination;
752 OIC_LOG(DEBUG, TAG, "OUT");
753 return entry->nextHop;
755 u_linklist_get_next(&iterTable);
757 OIC_LOG(DEBUG, TAG, "OUT");
761 void RTMGetObserverList(OCObservationId **obsList, uint8_t *obsListLen,
762 const u_linklist_t *gatewayTable)
764 OIC_LOG(DEBUG, TAG, "IN");
765 RM_NULL_CHECK_VOID(gatewayTable, TAG, "gatewayTable");
766 RM_NULL_CHECK_VOID(obsList, TAG, "obsList");
768 *obsList = (OCObservationId *) OICCalloc(MAX_OBSERVER_LIST_LENGTH, sizeof(OCObservationId));
771 OIC_LOG(ERROR, TAG, "out of memory");
775 u_linklist_iterator_t *iterTable = NULL;
776 u_linklist_init_iterator(gatewayTable, &iterTable);
778 while (NULL != iterTable)
780 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
781 if (0 < u_arraylist_length(entry->destination->destIntfAddr))
783 RTMDestIntfInfo_t *destCheck = u_arraylist_get(entry->destination->destIntfAddr, 0);
784 if (NULL == destCheck)
786 OIC_LOG(ERROR, TAG, "destCheck is null");
789 if (0 != destCheck->observerId)
791 OIC_LOG_V(DEBUG, TAG, "Observer ID is %d", destCheck->observerId);
792 *(*obsList + len) = destCheck->observerId;
795 if (MAX_OBSERVER_LIST_LENGTH < len)
797 *obsList = (OCObservationId *) OICRealloc((void *)*obsList,
798 (sizeof(OCObservationId) * (len + 1)));
801 u_linklist_get_next(&iterTable);
805 OIC_LOG(DEBUG, TAG, "OUT");
808 OCStackResult RTMUpdateDestinationIntfAdr(uint32_t gatewayId, RTMDestIntfInfo_t destInterfaces,
809 bool addAdr, u_linklist_t **gatewayTable)
811 OIC_LOG(DEBUG, TAG, "IN");
812 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
813 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
815 u_linklist_iterator_t *iterTable = NULL;
816 u_linklist_init_iterator(*gatewayTable, &iterTable);
817 while (NULL != iterTable)
819 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
820 if (NULL != entry && NULL != entry->destination &&
821 gatewayId == entry->destination->gatewayId)
825 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
827 RTMDestIntfInfo_t *destCheck =
828 u_arraylist_get(entry->destination->destIntfAddr, i);
829 if (NULL == destCheck)
831 OIC_LOG(ERROR, TAG, "Destination adr get failed");
835 if (0 == memcmp(destCheck->destIntfAddr.addr, destInterfaces.destIntfAddr.addr,
836 strlen(destInterfaces.destIntfAddr.addr))
837 && destInterfaces.destIntfAddr.port == destCheck->destIntfAddr.port)
839 destCheck->timeElapsed = RTMGetCurrentTime();
840 destCheck->isValid = true;
841 OIC_LOG(ERROR, TAG, "destInterfaces already present");
842 return OC_STACK_ERROR;
846 RTMDestIntfInfo_t *destAdr =
847 (RTMDestIntfInfo_t *) OICCalloc(1, sizeof(RTMDestIntfInfo_t));
850 OIC_LOG(ERROR, TAG, "Calloc destAdr failed");
851 return OC_STACK_ERROR;
853 *destAdr = destInterfaces;
854 destAdr->timeElapsed = RTMGetCurrentTime();
855 destAdr->isValid = true;
857 u_arraylist_add(entry->destination->destIntfAddr, (void *)destAdr);
860 OIC_LOG(ERROR, TAG, "Updating Destinterface address failed");
862 return OC_STACK_ERROR;
864 OIC_LOG(DEBUG, TAG, "OUT");
865 return OC_STACK_DUPLICATE_REQUEST;
868 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
870 RTMDestIntfInfo_t *removeAdr =
871 u_arraylist_get(entry->destination->destIntfAddr, i);
876 if (0 == memcmp(removeAdr->destIntfAddr.addr, destInterfaces.destIntfAddr.addr,
877 strlen(destInterfaces.destIntfAddr.addr))
878 && destInterfaces.destIntfAddr.port == removeAdr->destIntfAddr.port)
880 RTMDestIntfInfo_t *data =
881 u_arraylist_remove(entry->destination->destIntfAddr, i);
887 u_linklist_get_next(&iterTable);
889 OIC_LOG(DEBUG, TAG, "OUT");
893 OCStackResult RTMUpdateMcastSeqNumber(uint32_t gatewayId, uint16_t seqNum,
894 u_linklist_t **gatewayTable)
896 OIC_LOG(DEBUG, TAG, "IN");
897 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
898 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
900 u_linklist_iterator_t *iterTable = NULL;
901 u_linklist_init_iterator(*gatewayTable, &iterTable);
902 while (NULL != iterTable)
904 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
905 if (NULL != entry && NULL != entry->destination &&
906 gatewayId == entry->destination->gatewayId)
908 if (0 == entry->mcastMessageSeqNum || entry->mcastMessageSeqNum < seqNum)
910 entry->mcastMessageSeqNum = seqNum;
913 else if (entry->mcastMessageSeqNum == seqNum)
915 return OC_STACK_DUPLICATE_REQUEST;
919 return OC_STACK_COMM_ERROR;
922 u_linklist_get_next(&iterTable);
924 OIC_LOG(DEBUG, TAG, "OUT");
928 uint64_t RTMGetCurrentTime()
930 uint64_t currentTime = 0;
933 struct timespec getTs;
935 clock_gettime(CLOCK_MONOTONIC, &getTs);
937 currentTime = getTs.tv_sec;
938 #elif defined __ARDUINO__
939 currentTime = millis() / 1000;
941 #if _POSIX_TIMERS > 0
943 clock_gettime(CLOCK_MONOTONIC, &ts);
944 currentTime = ts.tv_sec;
947 gettimeofday(&tv, NULL);
948 currentTime = tv.tv_sec;
954 OCStackResult RTMUpdateDestAddrValidity(u_linklist_t **invalidTable, u_linklist_t **gatewayTable)
956 OIC_LOG(DEBUG, TAG, "IN");
957 RM_NULL_CHECK_WITH_RET(invalidTable, TAG, "invalidTable");
958 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
959 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
961 *invalidTable = u_linklist_create();
962 if (NULL == *invalidTable)
964 OIC_LOG(ERROR, TAG, "u_linklist_create failed");
965 return OC_STACK_NO_MEMORY;
968 u_linklist_iterator_t *iterTable = NULL;
969 uint64_t presentTime = RTMGetCurrentTime();
971 u_linklist_init_iterator(*gatewayTable, &iterTable);
972 while (NULL != iterTable)
974 RTMGatewayEntry_t *entry = (RTMGatewayEntry_t *) u_linklist_get_data(iterTable);
977 u_linklist_get_next(&iterTable);
980 else if (1 == entry->routeCost)
982 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
984 RTMDestIntfInfo_t *destCheck = u_arraylist_get(entry->destination->destIntfAddr, i);
989 if (GATEWAY_ALIVE_TIMEOUT < (presentTime - destCheck->timeElapsed))
991 destCheck->isValid = false;
992 u_linklist_add(*invalidTable, (void *)destCheck);
996 else if (1 < entry->routeCost)
1000 u_linklist_get_next(&iterTable);
1002 OIC_LOG(DEBUG, TAG, "OUT");
1006 OCStackResult RTMRemoveInvalidGateways(u_linklist_t **invalidTable, u_linklist_t **gatewayTable)
1008 OIC_LOG(DEBUG, TAG, "IN");
1009 RM_NULL_CHECK_WITH_RET(invalidTable, TAG, "invalidTable");
1010 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
1011 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
1013 *invalidTable = u_linklist_create();
1014 if (NULL == *invalidTable)
1016 OIC_LOG(ERROR, TAG, "u_linklist_create failed");
1017 return OC_STACK_NO_MEMORY;
1020 u_linklist_iterator_t *iterTable = NULL;
1021 u_linklist_init_iterator(*gatewayTable, &iterTable);
1022 while (iterTable != NULL)
1024 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
1028 u_linklist_get_next(&iterTable);
1031 else if (NULL != entry->destination && (1 == entry->routeCost))
1033 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
1035 RTMDestIntfInfo_t *destCheck = u_arraylist_get(entry->destination->destIntfAddr, i);
1036 if (destCheck && !destCheck->isValid)
1038 void *data = u_arraylist_remove(entry->destination->destIntfAddr, i);
1044 if (0 == u_arraylist_length(entry->destination->destIntfAddr))
1046 u_arraylist_free(&(entry->destination->destIntfAddr));
1048 RTMRemoveGatewayEntry(entry->destination->gatewayId, invalidTable, gatewayTable);
1049 if (OC_STACK_OK != res)
1051 OIC_LOG(ERROR, TAG, "Removing Entries failed");
1052 return OC_STACK_ERROR;
1054 u_linklist_get_next(&iterTable);
1058 u_linklist_get_next(&iterTable);
1061 else if (1 < entry->routeCost)
1067 u_linklist_get_next(&iterTable);
1070 OIC_LOG(DEBUG, TAG, "OUT");
1074 OCStackResult RTMUpdateEntryParameters(uint32_t gatewayId, uint32_t seqNum,
1075 const RTMDestIntfInfo_t *destAdr, u_linklist_t **gatewayTable,
1078 OIC_LOG(DEBUG, TAG, "IN");
1079 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
1080 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
1081 RM_NULL_CHECK_WITH_RET(destAdr, TAG, "destAdr");
1083 u_linklist_iterator_t *iterTable = NULL;
1084 u_linklist_init_iterator(*gatewayTable, &iterTable);
1085 while (NULL != iterTable)
1087 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
1091 u_linklist_get_next(&iterTable);
1094 if (NULL != entry->destination && gatewayId == entry->destination->gatewayId)
1096 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
1098 RTMDestIntfInfo_t *destCheck =
1099 u_arraylist_get(entry->destination->destIntfAddr, i);
1100 if (NULL != destCheck &&
1101 (0 == memcmp(destCheck->destIntfAddr.addr, destAdr->destIntfAddr.addr,
1102 strlen(destAdr->destIntfAddr.addr)))
1103 && destAdr->destIntfAddr.port == destCheck->destIntfAddr.port)
1105 destCheck->timeElapsed = RTMGetCurrentTime();
1106 destCheck->isValid = true;
1110 if (0 != entry->seqNum && seqNum == entry->seqNum)
1112 return OC_STACK_DUPLICATE_REQUEST;
1114 else if (0 != entry->seqNum && seqNum != ((entry->seqNum) + 1) && !forceUpdate)
1116 return OC_STACK_COMM_ERROR;
1120 entry->seqNum = seqNum;
1121 OIC_LOG(DEBUG, TAG, "OUT");
1125 u_linklist_get_next(&iterTable);
1127 OIC_LOG(DEBUG, TAG, "OUT");
1131 void RTMPrintTable(const u_linklist_t *gatewayTable, const u_linklist_t *endpointTable)
1133 RM_NULL_CHECK_VOID(gatewayTable, TAG, "gatewayTable");
1134 OIC_LOG(DEBUG, RM_TAG, "=================Gateway List table============================\n");
1135 u_linklist_iterator_t *iterTable = NULL;
1136 u_linklist_init_iterator(gatewayTable, &iterTable);
1137 while (NULL != iterTable)
1139 RTMGatewayEntry_t *hop =
1140 (RTMGatewayEntry_t *) u_linklist_get_data(iterTable);
1143 OIC_LOG(ERROR, RM_TAG, "Printing Table Failed");
1146 if (NULL == hop->nextHop || 0 == hop->nextHop->gatewayId)
1148 OIC_LOG_V(DEBUG, RM_TAG, "\nDestination : %u\nNextHop : (null)\nHopCount : %d",
1149 hop->destination->gatewayId, hop->routeCost);
1150 OIC_LOG_V(DEBUG, RM_TAG, "\nSequence Number :%u", hop->seqNum);
1154 OIC_LOG_V(DEBUG, RM_TAG, "\nDestination : %u\nNextHop : %u\nHopCount : %d",
1155 hop->destination->gatewayId, hop->nextHop->gatewayId, hop->routeCost);
1156 OIC_LOG_V(DEBUG, RM_TAG, "\nSequence Number :%u", hop->seqNum);
1158 if (1 == hop->routeCost && NULL != hop->destination &&
1159 hop->destination->destIntfAddr != NULL)
1161 for (uint32_t i = 0; i < u_arraylist_length(hop->destination->destIntfAddr); i++)
1163 RTMDestIntfInfo_t *dest = u_arraylist_get(hop->destination->destIntfAddr, i);
1166 OIC_LOG_V(DEBUG, RM_TAG, "\nDestination interface addresses: %s Port : %d Obs ID: %d",
1167 dest->destIntfAddr.addr, dest->destIntfAddr.port, dest->observerId);
1168 OIC_LOG_V(DEBUG, RM_TAG, "Validity: %d", dest->isValid);
1172 OIC_LOG(DEBUG, RM_TAG, "********************************************\n");
1173 u_linklist_get_next(&iterTable);
1176 RTMEndpointPrintTable(endpointTable);