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.
32 #define TAG "OIC_RM_TM"
35 * Tag for printing the Routing table.
37 #define RM_TAG "OIC_RM_RAP"
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 OIC_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 OIC_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 OIC_LOG(ERROR, TAG, "Creating Routing Table failed");
69 RTMTerminate(gatewayTable, endpointTable);
70 return OC_STACK_ERROR;
73 OIC_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 OIC_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 OIC_LOG(ERROR, TAG, "Deleting Entry from Routing Table failed");
113 return OC_STACK_ERROR;
116 u_linklist_free(gatewayTable);
117 OIC_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 OIC_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 OIC_LOG(ERROR, TAG, "Deleting Entry from Routing Table failed");
146 return OC_STACK_ERROR;
149 u_linklist_free(endpointTable);
150 OIC_LOG(DEBUG, TAG, "OUT");
154 OCStackResult RTMFreeGatewayIdList(u_linklist_t **gatewayIdTable)
156 OIC_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 OIC_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 OIC_LOG(ERROR, TAG, "Deleting Entry from Routing Table failed");
190 return OC_STACK_ERROR;
194 OIC_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 OIC_LOG(DEBUG, TAG, "IN");
205 OCStackResult ret = RTMFreeGatewayRouteTable(gatewayTable);
206 if (OC_STACK_OK != ret)
208 OIC_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 OIC_LOG(ERROR, TAG, "Deleting Endpoint Routing Table failed");
220 if (NULL != *endpointTable)
222 *endpointTable = NULL;
224 OIC_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 OIC_LOG(DEBUG, TAG, "IN");
239 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
240 if (NULL == *gatewayTable)
242 *gatewayTable = u_linklist_create();
243 if (NULL == *gatewayTable)
245 OIC_LOG(ERROR, TAG, "u_linklist_create failed");
246 return OC_STACK_NO_MEMORY;
250 if (1 == routeCost && 0 != nextHop)
252 OIC_LOG(ERROR, TAG, "Adding Gateway Failed as Next Hop should be 0 for route cost 1");
253 return OC_STACK_ERROR;
258 OIC_LOG(ERROR, TAG, "Adding Gateway Failed as Route cost shouldnot be less than 1");
259 return OC_STACK_ERROR;
262 u_linklist_iterator_t *destNode = NULL;
263 RTMGatewayId_t *gatewayNodeMap = NULL; // Gateway id ponter can be mapped to NextHop of entry.
265 u_linklist_iterator_t *iterTable = NULL;
266 u_linklist_init_iterator(*gatewayTable, &iterTable);
267 // Iterate over gateway list to find if already entry with this gatewayid is present.
268 while (NULL != iterTable)
270 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
276 // To save node with same gateway id (To update entry instead of add new entry).
277 if (NULL == destNode && NULL != entry->destination &&
278 (gatewayId == entry->destination->gatewayId))
280 destNode = iterTable;
283 // To find pointer of gateway id for a node provided next hop equals to existing gateway id.
284 if (0 != nextHop && NULL != entry->destination &&
285 nextHop == entry->destination->gatewayId)
287 gatewayNodeMap = entry->destination;
290 if (NULL != destNode && NULL != gatewayNodeMap)
295 u_linklist_get_next(&iterTable);
298 if (1 < routeCost && NULL == gatewayNodeMap)
300 OIC_LOG(ERROR, TAG, "Adding Gateway Failed as Next Hop is invalid");
301 return OC_STACK_ERROR;
304 //Logic to update entry if it is already destination present or to add new entry.
305 if (NULL != destNode)
307 RTMGatewayEntry_t *entry = u_linklist_get_data(destNode);
309 if (NULL != entry && 1 == entry->routeCost && 0 == nextHop)
311 if (NULL == destInterfaces)
313 OIC_LOG(ERROR, TAG, "Not Adding Gateway destInterfaces is NULL");
314 return OC_STACK_ERROR;
316 OCStackResult update = RTMUpdateDestinationIntfAdr(gatewayId, *destInterfaces, true,
318 if (OC_STACK_OK != update)
320 OIC_LOG(ERROR, TAG, "RTMUpdateDestinationIntfAdr failed");
324 else if (NULL != entry && entry->routeCost >= routeCost)
326 if (entry->routeCost == routeCost && NULL != entry->nextHop &&
327 (nextHop == entry->nextHop->gatewayId))
329 OIC_LOG(ERROR, TAG, "Not Adding Gateway As it is Duplicate request");
330 return OC_STACK_DUPLICATE_REQUEST;
333 //Mapped nextHop gateway to another entries having gateway as destination.
334 if (NULL != gatewayNodeMap)
336 entry->destination->gatewayId = gatewayId;
337 entry->nextHop = gatewayNodeMap;
338 entry->destination->destIntfAddr = NULL;
339 entry->routeCost = routeCost;
341 else if (0 == nextHop)
343 entry->routeCost = 1;
344 // Entry can't be updated if Next hop is not same as existing Destinations of Table.
345 OIC_LOG(DEBUG, TAG, "Updating the gateway");
346 entry->nextHop = NULL;
347 entry->destination->destIntfAddr = u_arraylist_create();
348 if (NULL == entry->destination->destIntfAddr)
350 OIC_LOG(ERROR, TAG, "Failed to create array list");
351 return OC_STACK_ERROR;
354 RTMDestIntfInfo_t *destAdr =
355 (RTMDestIntfInfo_t *) OICCalloc(1, sizeof(RTMDestIntfInfo_t));
358 OIC_LOG(ERROR, TAG, "Failed to Calloc destAdr");
359 return OC_STACK_ERROR;
362 *destAdr = *destInterfaces;
363 destAdr->timeElapsed = RTMGetCurrentTime();
364 destAdr->isValid = true;
366 u_arraylist_add(entry->destination->destIntfAddr, (void *)destAdr);
369 OIC_LOG(ERROR, TAG, "Adding node to head failed");
371 return OC_STACK_ERROR;
376 OIC_LOG(ERROR, TAG, "Adding Gateway Failed as Next hop is invalid");
377 return OC_STACK_ERROR;
381 else if (NULL != entry && entry->routeCost < routeCost)
383 OIC_LOG(ERROR, TAG, "Adding Gateway Failed as Route cost is more than old");
384 return OC_STACK_ERROR;
387 // Logic to add updated node to Head of list as route cost is 1.
388 if (1 == routeCost && NULL != entry)
390 OCStackResult res = u_linklist_remove(*gatewayTable, &destNode);
391 if (OC_STACK_OK != res)
393 OIC_LOG(ERROR, TAG, "Removing node failed");
397 res = u_linklist_add_head(*gatewayTable, (void *)entry);
398 if (OC_STACK_OK != res)
400 OIC_LOG(ERROR, TAG, "Adding node to head failed");
408 RTMGatewayEntry_t *hopEntry = (RTMGatewayEntry_t *)OICCalloc(1, sizeof(RTMGatewayEntry_t));
409 if (NULL == hopEntry)
411 OIC_LOG(ERROR, TAG, "Calloc failed for hop entry");
412 return OC_STACK_ERROR;
415 hopEntry->destination = (RTMGatewayId_t*)OICCalloc(1, sizeof(RTMGatewayId_t));
416 if (NULL == hopEntry->destination)
418 OIC_LOG(ERROR, TAG, "Calloc failed for hop entry destination");
420 return OC_STACK_ERROR;
423 hopEntry->destination->gatewayId = gatewayId;
424 if (NULL != destInterfaces && strlen((*destInterfaces).destIntfAddr.addr) > 0)
426 hopEntry->destination->destIntfAddr = u_arraylist_create();
427 RTMDestIntfInfo_t *destAdr =
428 (RTMDestIntfInfo_t *) OICCalloc(1, sizeof(RTMDestIntfInfo_t));
431 OIC_LOG(ERROR, TAG, "Calloc failed for destAdr");
432 u_arraylist_free(&(hopEntry->destination->destIntfAddr));
433 OICFree(hopEntry->destination);
435 return OC_STACK_ERROR;
438 *destAdr = *destInterfaces;
439 destAdr->timeElapsed = RTMGetCurrentTime();
440 destAdr->isValid = true;
441 u_arraylist_add(hopEntry->destination->destIntfAddr, (void *)destAdr);
445 hopEntry->destination->destIntfAddr = NULL;
448 hopEntry->routeCost = routeCost;
449 // Mapped nextHop gateway to another entries having gateway as destination.
450 if (NULL != gatewayNodeMap)
452 hopEntry->nextHop = gatewayNodeMap;
454 else if (1 == routeCost)
456 hopEntry->nextHop = NULL;
460 OIC_LOG(ERROR, TAG, "Adding Gateway Failed as Next Hop is invalid");
461 while (u_arraylist_length(hopEntry->destination->destIntfAddr) > 0)
463 RTMDestIntfInfo_t *data =
464 u_arraylist_remove(hopEntry->destination->destIntfAddr, 0);
467 u_arraylist_free(&(hopEntry->destination->destIntfAddr));
468 OICFree(hopEntry->destination);
471 return OC_STACK_ERROR;
474 OCStackResult ret = OC_STACK_OK;
475 if (hopEntry->routeCost == 1)
477 ret = u_linklist_add_head(*gatewayTable, (void *)hopEntry);
481 ret = u_linklist_add(*gatewayTable, (void *)hopEntry);
484 if (OC_STACK_OK != ret)
486 OIC_LOG(ERROR, TAG, "Adding Gateway Entry to Routing Table failed");
487 while (u_arraylist_length(hopEntry->destination->destIntfAddr) > 0)
489 RTMDestIntfInfo_t *data = u_arraylist_remove(hopEntry->destination->destIntfAddr, 0);
492 u_arraylist_free(&(hopEntry->destination->destIntfAddr));
493 OICFree(hopEntry->destination);
495 return OC_STACK_ERROR;
498 OIC_LOG(DEBUG, TAG, "OUT");
502 OCStackResult RTMAddEndpointEntry(uint16_t *endpointId, const CAEndpoint_t *destAddr,
503 u_linklist_t **endpointTable)
505 OIC_LOG(DEBUG, TAG, "IN");
506 RM_NULL_CHECK_WITH_RET(endpointId, TAG, "endpointId");
507 RM_NULL_CHECK_WITH_RET(destAddr, TAG, "destAddr");
508 RM_NULL_CHECK_WITH_RET(endpointTable, TAG, "endpointTable");
509 if (NULL == *endpointTable)
511 *endpointTable = u_linklist_create();
512 if (NULL == *endpointTable)
514 OIC_LOG(ERROR, TAG, "u_linklist_create failed");
515 return OC_STACK_NO_MEMORY;
519 u_linklist_iterator_t *iterTable = NULL;
520 u_linklist_init_iterator(*endpointTable, &iterTable);
521 // Iterate over gateway list to find if already entry with this gatewayid is present.
522 while (NULL != iterTable)
524 RTMEndpointEntry_t *entry =
525 (RTMEndpointEntry_t *) u_linklist_get_data(iterTable);
527 if (NULL != entry && (0 == memcmp(destAddr->addr, entry->destIntfAddr.addr,
528 strlen(entry->destIntfAddr.addr)))
529 && destAddr->port == entry->destIntfAddr.port)
531 *endpointId = entry->endpointId;
532 OIC_LOG(ERROR, TAG, "Adding failed as Enpoint Entry Already present in Table");
533 return OC_STACK_DUPLICATE_REQUEST;
535 u_linklist_get_next(&iterTable);
539 RTMEndpointEntry_t *hopEntry = (RTMEndpointEntry_t *)OICCalloc(1, sizeof(RTMEndpointEntry_t));
541 if (NULL == hopEntry)
543 OIC_LOG(ERROR, TAG, "Malloc failed for hop entry");
544 return OC_STACK_ERROR;
547 hopEntry->endpointId = *endpointId;
548 hopEntry->destIntfAddr = *destAddr;
550 OCStackResult ret = u_linklist_add(*endpointTable, (void *)hopEntry);
551 if (OC_STACK_OK != ret)
553 OIC_LOG(ERROR, TAG, "Adding Enpoint Entry to Routing Table failed");
555 return OC_STACK_ERROR;
557 OIC_LOG(DEBUG, TAG, "OUT");
561 OCStackResult RTMAddObserver(uint32_t obsID, CAEndpoint_t devAddr, u_linklist_t **gatewayTable)
563 OIC_LOG(DEBUG, TAG, "IN");
564 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
565 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
567 u_linklist_iterator_t *iterTable = NULL;
568 u_linklist_init_iterator(*gatewayTable, &iterTable);
569 while (NULL != iterTable)
571 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
573 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
575 RTMDestIntfInfo_t *destCheck = u_arraylist_get(entry->destination->destIntfAddr, i);
576 if (NULL != destCheck &&
577 (0 == memcmp(destCheck->destIntfAddr.addr, devAddr.addr, strlen(devAddr.addr)))
578 && devAddr.port == destCheck->destIntfAddr.port)
580 destCheck->observerId = obsID;
581 OIC_LOG(DEBUG, TAG, "OUT");
585 u_linklist_get_next(&iterTable);
587 OIC_LOG(DEBUG, TAG, "OUT");
588 return OC_STACK_ERROR;
591 bool RTMIsObserverPresent(CAEndpoint_t devAddr, OCObservationId *obsID,
592 const u_linklist_t *gatewayTable)
594 OIC_LOG(DEBUG, TAG, "IN");
597 OIC_LOG(ERROR, TAG, "obsID is null");
601 if (NULL == gatewayTable)
603 OIC_LOG(ERROR, TAG, "gatewayTable is null");
607 u_linklist_iterator_t *iterTable = NULL;
608 u_linklist_init_iterator(gatewayTable, &iterTable);
609 while (NULL != iterTable)
611 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
612 if (NULL == entry || NULL == entry->destination)
614 OIC_LOG(ERROR, TAG, "entry is NULL");
617 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
619 RTMDestIntfInfo_t *destCheck =
620 u_arraylist_get(entry->destination->destIntfAddr, i);
621 if (NULL != destCheck && (0 == memcmp(destCheck->destIntfAddr.addr, devAddr.addr,
622 strlen(devAddr.addr)))
623 && devAddr.port == destCheck->destIntfAddr.port && 0 != destCheck->observerId)
625 *obsID = destCheck->observerId;
626 OIC_LOG(DEBUG, TAG, "OUT");
630 u_linklist_get_next(&iterTable);
632 OIC_LOG(DEBUG, TAG, "OUT");
636 OCStackResult RTMRemoveGatewayEntry(uint32_t gatewayId, u_linklist_t **removedGatewayNodes,
637 u_linklist_t **gatewayTable)
639 OIC_LOG(DEBUG, TAG, "IN");
640 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
641 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
643 u_linklist_iterator_t *iterTable = NULL;
645 // if link list is not null we can directly add removed nodes to it instead of creating everytime.
646 if (NULL == *removedGatewayNodes)
648 *removedGatewayNodes = u_linklist_create();
649 if (NULL == *removedGatewayNodes)
651 OIC_LOG(ERROR, TAG, "u_linklist_create failed");
652 return OC_STACK_NO_MEMORY;
655 OCStackResult ret = OC_STACK_OK;
656 u_linklist_init_iterator(*gatewayTable, &iterTable);
657 while (NULL != iterTable)
659 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
660 if (NULL == entry || NULL == entry->destination)
662 u_linklist_get_next(&iterTable);
666 if (gatewayId == entry->destination->gatewayId || (NULL != entry->nextHop &&
667 (gatewayId == entry->nextHop->gatewayId)))
669 OIC_LOG_V(DEBUG, TAG, "Removing the gateway entry: %u", entry->destination->gatewayId);
670 ret = u_linklist_remove(*gatewayTable, &iterTable);
671 if (OC_STACK_OK != ret)
673 OIC_LOG(ERROR, TAG, "Deleting Entry from Routing Table failed");
674 return OC_STACK_ERROR;
678 u_linklist_add(*removedGatewayNodes, (void *)entry);
683 u_linklist_get_next(&iterTable);
686 OIC_LOG(DEBUG, TAG, "RTMRemoveGatewayEntry OUT");
690 OCStackResult RTMRemoveGatewayDestEntry(uint32_t gatewayId, uint32_t nextHop,
691 const RTMDestIntfInfo_t *destInfAdr,
692 RTMGatewayEntry_t **existEntry, u_linklist_t **gatewayTable)
694 OIC_LOG(DEBUG, TAG, "IN");
695 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
696 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
697 RM_NULL_CHECK_WITH_RET(destInfAdr, TAG, "destInfAdr");
699 u_linklist_iterator_t *iterTable = NULL;
701 OCStackResult ret = -1;
702 u_linklist_init_iterator(*gatewayTable, &iterTable);
703 while (NULL != iterTable)
705 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
708 u_linklist_get_next(&iterTable);
712 // Update the time for NextHop entry.
713 if (NULL != entry->destination && nextHop == entry->destination->gatewayId)
715 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
717 RTMDestIntfInfo_t *destCheck = u_arraylist_get(entry->destination->destIntfAddr, i);
722 if (0 == memcmp(destCheck->destIntfAddr.addr, destInfAdr->destIntfAddr.addr,
723 strlen(destInfAdr->destIntfAddr.addr))
724 && destInfAdr->destIntfAddr.port == destCheck->destIntfAddr.port)
726 destCheck->timeElapsed = RTMGetCurrentTime();
732 // Remove node with given gatewayid and nextHop if not found update exist entry.
733 if (NULL != entry->destination && (gatewayId == entry->destination->gatewayId))
735 OIC_LOG_V(INFO, TAG, "Remove the gateway ID: %u", entry->destination->gatewayId);
736 if (NULL != entry->nextHop && nextHop == entry->nextHop->gatewayId)
738 ret = u_linklist_remove(*gatewayTable, &iterTable);
739 if (OC_STACK_OK != ret)
741 OIC_LOG(ERROR, TAG, "Deleting Entry from Routing Table failed");
742 return OC_STACK_ERROR;
749 OIC_LOG(DEBUG, TAG, "OUT");
750 return OC_STACK_ERROR;
753 u_linklist_get_next(&iterTable);
755 OIC_LOG(DEBUG, TAG, "OUT");
756 return OC_STACK_ERROR;
759 OCStackResult RTMRemoveEndpointEntry(uint16_t endpointId, u_linklist_t **endpointTable)
761 OIC_LOG(DEBUG, TAG, "IN");
762 RM_NULL_CHECK_WITH_RET(endpointTable, TAG, "endpointTable");
763 RM_NULL_CHECK_WITH_RET(*endpointTable, TAG, "*endpointTable");
765 u_linklist_iterator_t *iterTable = NULL;
766 u_linklist_init_iterator(*endpointTable, &iterTable);
767 while (NULL != iterTable)
769 RTMEndpointEntry_t *entry = u_linklist_get_data(iterTable);
770 if (NULL != entry && endpointId == entry->endpointId)
772 OCStackResult ret = u_linklist_remove(*endpointTable, &iterTable);
773 if (OC_STACK_OK != ret)
775 OIC_LOG(ERROR, TAG, "Deleting Entry from Routing Table failed");
776 return OC_STACK_ERROR;
782 u_linklist_get_next(&iterTable);
785 OIC_LOG(DEBUG, TAG, "OUT");
789 OCStackResult RTMRemoveGateways(u_linklist_t **gatewayTable)
791 OIC_LOG(DEBUG, TAG, "IN");
793 if (NULL == gatewayTable || NULL == *gatewayTable)
795 OIC_LOG(DEBUG, TAG, "OUT");
799 OCStackResult ret = RTMFreeGatewayRouteTable(gatewayTable);
800 if (OC_STACK_OK != ret)
802 OIC_LOG(ERROR, TAG, "Removing Gateways failed");
805 OIC_LOG(DEBUG, TAG, "OUT");
809 OCStackResult RTMRemoveEndpoints(u_linklist_t **endpointTable)
811 OIC_LOG(DEBUG, TAG, "IN");
812 if (NULL == endpointTable || NULL == *endpointTable)
814 OIC_LOG(DEBUG, TAG, "OUT");
818 OCStackResult ret = RTMFreeEndpointRouteTable(endpointTable);
819 if (OC_STACK_OK != ret)
821 OIC_LOG(ERROR, TAG, "Freeing Endpoints failed");
822 return OC_STACK_ERROR;
824 OIC_LOG(DEBUG, TAG, "OUT");
828 void RTMFreeGateway(RTMGatewayId_t *gateway, u_linklist_t **gatewayTable)
830 OIC_LOG(DEBUG, TAG, "IN");
831 RM_NULL_CHECK_VOID(gateway, TAG, "gateway");
832 RM_NULL_CHECK_VOID(gatewayTable, TAG, "gatewayTable");
833 RM_NULL_CHECK_VOID(*gatewayTable, TAG, "*gatewayTable");
834 while (0 < u_arraylist_length(gateway->destIntfAddr))
836 void *data = u_arraylist_remove(gateway->destIntfAddr, 0);
839 u_arraylist_free(&(gateway->destIntfAddr));
841 OIC_LOG(DEBUG, TAG, "OUT");
844 void RTMGetNeighbours(u_linklist_t **neighbourNodes, const u_linklist_t *gatewayTable)
846 OIC_LOG(DEBUG, TAG, "IN");
847 RM_NULL_CHECK_VOID(neighbourNodes, TAG, "neighbourNodes");
848 RM_NULL_CHECK_VOID(gatewayTable, TAG, "gatewayTable");
850 *neighbourNodes = u_linklist_create();
851 if (NULL == *neighbourNodes)
853 OIC_LOG(ERROR, TAG, "u_linklist_create failed");
856 u_linklist_iterator_t *iterTable = NULL;
857 u_linklist_init_iterator(gatewayTable, &iterTable);
858 while (NULL != iterTable)
860 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
861 if (NULL != entry && 1 == entry->routeCost)
863 u_linklist_add(*neighbourNodes, (void *)entry);
865 else if (NULL != entry && 1 < entry->routeCost)
867 OIC_LOG(DEBUG, TAG, "OUT");
871 u_linklist_get_next(&iterTable);
873 OIC_LOG(DEBUG, TAG, "OUT");
876 RTMGatewayId_t *RTMGetNextHop(uint32_t gatewayId, const u_linklist_t *gatewayTable)
878 OIC_LOG(DEBUG, TAG, "IN");
881 OIC_LOG(ERROR, TAG, "gatewayId is invalid");
885 if (NULL == gatewayTable)
887 OIC_LOG(ERROR, TAG, "gatewayTable is null");
891 u_linklist_iterator_t *iterTable = NULL;
892 u_linklist_init_iterator(gatewayTable, &iterTable);
893 while (NULL != iterTable)
895 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
896 if (NULL != entry && gatewayId == entry->destination->gatewayId)
898 if (1 == entry->routeCost)
900 OIC_LOG(DEBUG, TAG, "OUT");
901 return entry->destination;
903 OIC_LOG(DEBUG, TAG, "OUT");
904 return entry->nextHop;
906 u_linklist_get_next(&iterTable);
908 OIC_LOG(DEBUG, TAG, "OUT");
912 CAEndpoint_t *RTMGetEndpointEntry(uint16_t endpointId, const u_linklist_t *endpointTable)
914 OIC_LOG(DEBUG, TAG, "IN");
915 if (NULL == endpointTable)
917 OIC_LOG(ERROR, TAG, "endpointTable is null");
921 u_linklist_iterator_t *iterTable = NULL;
922 u_linklist_init_iterator(endpointTable, &iterTable);
924 while (NULL != iterTable)
926 RTMEndpointEntry_t *entry = u_linklist_get_data(iterTable);
927 if (NULL != entry && (endpointId == entry->endpointId))
929 OIC_LOG(DEBUG, TAG, "OUT");
930 return &(entry->destIntfAddr);
932 u_linklist_get_next(&iterTable);
934 OIC_LOG(DEBUG, TAG, "OUT");
938 void RTMGetObserverList(OCObservationId **obsList, uint8_t *obsListLen,
939 const u_linklist_t *gatewayTable)
941 OIC_LOG(DEBUG, TAG, "IN");
942 RM_NULL_CHECK_VOID(gatewayTable, TAG, "gatewayTable");
943 RM_NULL_CHECK_VOID(obsList, TAG, "obsList");
945 *obsList = (OCObservationId *) OICCalloc(MAX_OBSERVER_LIST_LENGTH, sizeof(OCObservationId));
948 OIC_LOG(ERROR, TAG, "out of memory");
952 u_linklist_iterator_t *iterTable = NULL;
953 u_linklist_init_iterator(gatewayTable, &iterTable);
955 while (NULL != iterTable)
957 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
958 if (0 < u_arraylist_length(entry->destination->destIntfAddr))
960 RTMDestIntfInfo_t *destCheck = u_arraylist_get(entry->destination->destIntfAddr, 0);
961 if (NULL == destCheck)
963 OIC_LOG(ERROR, TAG, "destCheck is null");
966 if (0 != destCheck->observerId)
968 OIC_LOG_V(DEBUG, TAG, "Observer ID is %d", destCheck->observerId);
969 *(*obsList + len) = destCheck->observerId;
972 if (MAX_OBSERVER_LIST_LENGTH < len)
974 *obsList = (OCObservationId *) OICRealloc((void *)*obsList,
975 (sizeof(OCObservationId) * (len + 1)));
978 u_linklist_get_next(&iterTable);
982 OIC_LOG(DEBUG, TAG, "OUT");
985 OCStackResult RTMUpdateDestinationIntfAdr(uint32_t gatewayId, RTMDestIntfInfo_t destInterfaces,
986 bool addAdr, u_linklist_t **gatewayTable)
988 OIC_LOG(DEBUG, TAG, "IN");
989 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
990 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
992 u_linklist_iterator_t *iterTable = NULL;
993 u_linklist_init_iterator(*gatewayTable, &iterTable);
994 while (NULL != iterTable)
996 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
997 if (NULL != entry && NULL != entry->destination &&
998 gatewayId == entry->destination->gatewayId)
1002 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
1004 RTMDestIntfInfo_t *destCheck =
1005 u_arraylist_get(entry->destination->destIntfAddr, i);
1006 if (NULL == destCheck)
1008 OIC_LOG(ERROR, TAG, "Destination adr get failed");
1012 if (0 == memcmp(destCheck->destIntfAddr.addr, destInterfaces.destIntfAddr.addr,
1013 strlen(destInterfaces.destIntfAddr.addr))
1014 && destInterfaces.destIntfAddr.port == destCheck->destIntfAddr.port)
1016 destCheck->timeElapsed = RTMGetCurrentTime();
1017 destCheck->isValid = true;
1018 OIC_LOG(ERROR, TAG, "destInterfaces already present");
1019 return OC_STACK_ERROR;
1023 RTMDestIntfInfo_t *destAdr =
1024 (RTMDestIntfInfo_t *) OICCalloc(1, sizeof(RTMDestIntfInfo_t));
1025 if (NULL == destAdr)
1027 OIC_LOG(ERROR, TAG, "Calloc destAdr failed");
1028 return OC_STACK_ERROR;
1030 *destAdr = destInterfaces;
1031 destAdr->timeElapsed = RTMGetCurrentTime();
1032 destAdr->isValid = true;
1034 u_arraylist_add(entry->destination->destIntfAddr, (void *)destAdr);
1037 OIC_LOG(ERROR, TAG, "Updating Destinterface address failed");
1039 return OC_STACK_ERROR;
1041 OIC_LOG(DEBUG, TAG, "OUT");
1042 return OC_STACK_DUPLICATE_REQUEST;
1045 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
1047 RTMDestIntfInfo_t *removeAdr =
1048 u_arraylist_get(entry->destination->destIntfAddr, i);
1053 if (0 == memcmp(removeAdr->destIntfAddr.addr, destInterfaces.destIntfAddr.addr,
1054 strlen(destInterfaces.destIntfAddr.addr))
1055 && destInterfaces.destIntfAddr.port == removeAdr->destIntfAddr.port)
1057 RTMDestIntfInfo_t *data =
1058 u_arraylist_remove(entry->destination->destIntfAddr, i);
1064 u_linklist_get_next(&iterTable);
1066 OIC_LOG(DEBUG, TAG, "OUT");
1070 OCStackResult RTMUpdateMcastSeqNumber(uint32_t gatewayId, uint16_t seqNum,
1071 u_linklist_t **gatewayTable)
1073 OIC_LOG(DEBUG, TAG, "IN");
1074 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
1075 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
1077 u_linklist_iterator_t *iterTable = NULL;
1078 u_linklist_init_iterator(*gatewayTable, &iterTable);
1079 while (NULL != iterTable)
1081 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
1082 if (NULL != entry && NULL != entry->destination &&
1083 gatewayId == entry->destination->gatewayId)
1085 if (0 == entry->mcastMessageSeqNum || entry->mcastMessageSeqNum < seqNum)
1087 entry->mcastMessageSeqNum = seqNum;
1090 else if (entry->mcastMessageSeqNum == seqNum)
1092 return OC_STACK_DUPLICATE_REQUEST;
1096 return OC_STACK_COMM_ERROR;
1099 u_linklist_get_next(&iterTable);
1101 OIC_LOG(DEBUG, TAG, "OUT");
1105 uint64_t RTMGetCurrentTime()
1107 uint64_t currentTime = 0;
1110 struct timespec getTs;
1112 clock_gettime(CLOCK_MONOTONIC, &getTs);
1114 currentTime = getTs.tv_sec;
1115 #elif defined __ARDUINO__
1116 currentTime = millis() / 1000;
1118 #if _POSIX_TIMERS > 0
1120 clock_gettime(CLOCK_MONOTONIC, &ts);
1121 currentTime = ts.tv_sec;
1124 gettimeofday(&tv, NULL);
1125 currentTime = tv.tv_sec;
1131 OCStackResult RTMUpdateDestAddrValidity(u_linklist_t **invalidTable, u_linklist_t **gatewayTable)
1133 OIC_LOG(DEBUG, TAG, "IN");
1134 RM_NULL_CHECK_WITH_RET(invalidTable, TAG, "invalidTable");
1135 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
1136 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
1138 *invalidTable = u_linklist_create();
1139 if (NULL == *invalidTable)
1141 OIC_LOG(ERROR, TAG, "u_linklist_create failed");
1142 return OC_STACK_NO_MEMORY;
1145 u_linklist_iterator_t *iterTable = NULL;
1146 uint64_t presentTime = RTMGetCurrentTime();
1148 u_linklist_init_iterator(*gatewayTable, &iterTable);
1149 while (NULL != iterTable)
1151 RTMGatewayEntry_t *entry = (RTMGatewayEntry_t *) u_linklist_get_data(iterTable);
1154 u_linklist_get_next(&iterTable);
1157 else if (1 == entry->routeCost)
1159 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
1161 RTMDestIntfInfo_t *destCheck = u_arraylist_get(entry->destination->destIntfAddr, i);
1166 if (GATEWAY_ALIVE_TIMEOUT < (presentTime - destCheck->timeElapsed))
1168 destCheck->isValid = false;
1169 u_linklist_add(*invalidTable, (void *)destCheck);
1173 else if (1 < entry->routeCost)
1177 u_linklist_get_next(&iterTable);
1179 OIC_LOG(DEBUG, TAG, "OUT");
1183 OCStackResult RTMRemoveInvalidGateways(u_linklist_t **invalidTable, u_linklist_t **gatewayTable)
1185 OIC_LOG(DEBUG, TAG, "IN");
1186 RM_NULL_CHECK_WITH_RET(invalidTable, TAG, "invalidTable");
1187 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
1188 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
1190 *invalidTable = u_linklist_create();
1191 if (NULL == *invalidTable)
1193 OIC_LOG(ERROR, TAG, "u_linklist_create failed");
1194 return OC_STACK_NO_MEMORY;
1197 u_linklist_iterator_t *iterTable = NULL;
1198 u_linklist_init_iterator(*gatewayTable, &iterTable);
1199 while (iterTable != NULL)
1201 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
1205 u_linklist_get_next(&iterTable);
1208 else if (NULL != entry->destination && (1 == entry->routeCost))
1210 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
1212 RTMDestIntfInfo_t *destCheck = u_arraylist_get(entry->destination->destIntfAddr, i);
1213 if (!destCheck && !destCheck->isValid)
1215 void *data = u_arraylist_remove(entry->destination->destIntfAddr, i);
1221 if (0 == u_arraylist_length(entry->destination->destIntfAddr))
1223 u_arraylist_free(&(entry->destination->destIntfAddr));
1225 RTMRemoveGatewayEntry(entry->destination->gatewayId, invalidTable, gatewayTable);
1226 if (OC_STACK_OK != res)
1228 OIC_LOG(ERROR, TAG, "Removing Entries failed");
1229 return OC_STACK_ERROR;
1231 u_linklist_get_next(&iterTable);
1235 u_linklist_get_next(&iterTable);
1238 else if (1 < entry->routeCost)
1244 u_linklist_get_next(&iterTable);
1247 OIC_LOG(DEBUG, TAG, "OUT");
1251 OCStackResult RTMUpdateEntryParameters(uint32_t gatewayId, uint32_t seqNum,
1252 const RTMDestIntfInfo_t *destAdr, u_linklist_t **gatewayTable,
1255 OIC_LOG(DEBUG, TAG, "IN");
1256 RM_NULL_CHECK_WITH_RET(gatewayTable, TAG, "gatewayTable");
1257 RM_NULL_CHECK_WITH_RET(*gatewayTable, TAG, "*gatewayTable");
1258 RM_NULL_CHECK_WITH_RET(destAdr, TAG, "destAdr");
1260 u_linklist_iterator_t *iterTable = NULL;
1261 u_linklist_init_iterator(*gatewayTable, &iterTable);
1262 while (NULL != iterTable)
1264 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
1268 u_linklist_get_next(&iterTable);
1271 if (NULL != entry->destination && gatewayId == entry->destination->gatewayId)
1273 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
1275 RTMDestIntfInfo_t *destCheck =
1276 u_arraylist_get(entry->destination->destIntfAddr, i);
1277 if (NULL != destCheck &&
1278 (0 == memcmp(destCheck->destIntfAddr.addr, destAdr->destIntfAddr.addr,
1279 strlen(destAdr->destIntfAddr.addr)))
1280 && destAdr->destIntfAddr.port == destCheck->destIntfAddr.port)
1282 destCheck->timeElapsed = RTMGetCurrentTime();
1283 destCheck->isValid = true;
1287 if (0 != entry->seqNum && seqNum == entry->seqNum)
1289 return OC_STACK_DUPLICATE_REQUEST;
1291 else if (0 != entry->seqNum && seqNum != ((entry->seqNum) + 1) && !forceUpdate)
1293 return OC_STACK_COMM_ERROR;
1297 entry->seqNum = seqNum;
1298 OIC_LOG(DEBUG, TAG, "OUT");
1302 u_linklist_get_next(&iterTable);
1304 OIC_LOG(DEBUG, TAG, "OUT");
1308 void RTMPrintTable(const u_linklist_t *gatewayTable, const u_linklist_t *endpointTable)
1310 RM_NULL_CHECK_VOID(gatewayTable, TAG, "gatewayTable");
1311 OIC_LOG(DEBUG, RM_TAG, "=================Gateway List table============================\n");
1312 u_linklist_iterator_t *iterTable = NULL;
1313 u_linklist_init_iterator(gatewayTable, &iterTable);
1314 while (NULL != iterTable)
1316 RTMGatewayEntry_t *hop =
1317 (RTMGatewayEntry_t *) u_linklist_get_data(iterTable);
1320 OIC_LOG(ERROR, RM_TAG, "Printing Table Failed");
1323 if (NULL == hop->nextHop || 0 == hop->nextHop->gatewayId)
1325 OIC_LOG_V(DEBUG, RM_TAG, "\nDestination : %u\nNextHop : (null)\nHopCount : %d",
1326 hop->destination->gatewayId, hop->routeCost);
1327 OIC_LOG_V(DEBUG, RM_TAG, "\nSequence Number :%u", hop->seqNum);
1331 OIC_LOG_V(DEBUG, RM_TAG, "\nDestination : %u\nNextHop : %u\nHopCount : %d",
1332 hop->destination->gatewayId, hop->nextHop->gatewayId, hop->routeCost);
1333 OIC_LOG_V(DEBUG, RM_TAG, "\nSequence Number :%u", hop->seqNum);
1335 if (1 == hop->routeCost && NULL != hop->destination &&
1336 hop->destination->destIntfAddr != NULL)
1338 for (uint32_t i = 0; i < u_arraylist_length(hop->destination->destIntfAddr); i++)
1340 RTMDestIntfInfo_t *dest = u_arraylist_get(hop->destination->destIntfAddr, i);
1343 OIC_LOG_V(DEBUG, RM_TAG, "\nDestination interface addresses: %s Port : %d Obs ID: %d",
1344 dest->destIntfAddr.addr, dest->destIntfAddr.port, dest->observerId);
1345 OIC_LOG_V(DEBUG, RM_TAG, "Validity: %d", dest->isValid);
1349 OIC_LOG(DEBUG, RM_TAG, "********************************************\n");
1350 u_linklist_get_next(&iterTable);
1353 OIC_LOG(DEBUG, RM_TAG, "=================Endpoint List table============================\n");
1354 u_linklist_iterator_t *iterEndpointTable = NULL;
1355 u_linklist_init_iterator(endpointTable, &iterEndpointTable);
1357 // Iterate over endpoint list to find if already entry for gatewayid is present.
1358 while (NULL != iterEndpointTable)
1360 RTMEndpointEntry_t *hop =
1361 (RTMEndpointEntry_t *) u_linklist_get_data(iterEndpointTable);
1364 OIC_LOG(ERROR, RM_TAG, "Printing Table Failed");
1367 OIC_LOG_V(DEBUG, RM_TAG, "EndpointId : %u\naddr : %s Port : %d",
1368 hop->endpointId, hop->destIntfAddr.addr, hop->destIntfAddr.port);
1370 OIC_LOG(DEBUG, RM_TAG, "********************************************\n");
1371 u_linklist_get_next(&iterEndpointTable);