+/* ****************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include "routingtablemanager_endpoint.h"
+#include "routingtablemanager.h"
+#include "routingutility.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "include/logger.h"
+
+/**
+ * Logging tag for module name.
+ */
+#define TAG "OIC_RM_TM"
+
+/**
+ * Tag for printing the Routing table.
+ */
+#define RM_TAG "OIC_RM_RAP"
+
+OCStackResult RTMEndpointInitialize(u_linklist_t **endpointTable)
+{
+ OIC_LOG(DEBUG, TAG, "RTMEndpointInitialize IN");
+ if (NULL == *endpointTable)
+ {
+ *endpointTable = u_linklist_create();
+ if (NULL == *endpointTable)
+ {
+ OIC_LOG(ERROR, TAG, "Creating Routing Table failed");
+ return OC_STACK_ERROR;
+ }
+ }
+ OIC_LOG(DEBUG, TAG, "RTMEndpointInitialize OUT");
+ return OC_STACK_OK;
+}
+
+/*
+ * Freeing every char pointer of endpoint entry here frees the table.
+ */
+OCStackResult RTMFreeEndpointRouteTable(u_linklist_t **endpointTable)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ if (NULL == endpointTable || NULL == *endpointTable)
+ {
+ return OC_STACK_OK;
+ }
+
+ u_linklist_iterator_t *iterTable = NULL;
+ u_linklist_init_iterator(*endpointTable, &iterTable);
+ while (NULL != iterTable)
+ {
+ RTMEndpointEntry_t *hop = u_linklist_get_data(iterTable);
+ if (NULL != hop)
+ {
+ OICFree(hop);
+ }
+
+ OCStackResult ret = u_linklist_remove(*endpointTable, &iterTable);
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG(ERROR, TAG, "Deleting Entry from Routing Table failed");
+ return OC_STACK_ERROR;
+ }
+ }
+ u_linklist_free(endpointTable);
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return OC_STACK_OK;
+}
+
+/*
+ * Freeing memory first and then Freeing linked list for gateway and endpoint.
+ */
+OCStackResult RTMEndpointTerminate(u_linklist_t **endpointTable)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+
+ OCStackResult ret = RTMFreeEndpointRouteTable(endpointTable);
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG(ERROR, TAG, "Deleting Endpoint Routing Table failed");
+ }
+ if (NULL != *endpointTable)
+ {
+ *endpointTable = NULL;
+ }
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return OC_STACK_OK;
+}
+
+OCStackResult RTMAddEndpointEntry(uint16_t *endpointId, const CAEndpoint_t *destAddr,
+ u_linklist_t **endpointTable)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ RM_NULL_CHECK_WITH_RET(endpointId, TAG, "endpointId");
+ RM_NULL_CHECK_WITH_RET(destAddr, TAG, "destAddr");
+ RM_NULL_CHECK_WITH_RET(endpointTable, TAG, "endpointTable");
+ if (NULL == *endpointTable)
+ {
+ *endpointTable = u_linklist_create();
+ if (NULL == *endpointTable)
+ {
+ OIC_LOG(ERROR, TAG, "u_linklist_create failed");
+ return OC_STACK_NO_MEMORY;
+ }
+ }
+
+ u_linklist_iterator_t *iterTable = NULL;
+ u_linklist_init_iterator(*endpointTable, &iterTable);
+ // Iterate over gateway list to find if already entry with this gatewayid is present.
+ while (NULL != iterTable)
+ {
+ RTMEndpointEntry_t *entry =
+ (RTMEndpointEntry_t *) u_linklist_get_data(iterTable);
+
+ if (NULL != entry && (0 == memcmp(destAddr->addr, entry->destIntfAddr.addr,
+ strlen(entry->destIntfAddr.addr)))
+ && destAddr->port == entry->destIntfAddr.port)
+ {
+ *endpointId = entry->endpointId;
+ OIC_LOG(ERROR, TAG, "Adding failed as Enpoint Entry Already present in Table");
+ return OC_STACK_DUPLICATE_REQUEST;
+ }
+ u_linklist_get_next(&iterTable);
+ }
+
+ // Filling Entry.
+ RTMEndpointEntry_t *hopEntry = (RTMEndpointEntry_t *)OICCalloc(1, sizeof(RTMEndpointEntry_t));
+
+ if (NULL == hopEntry)
+ {
+ OIC_LOG(ERROR, TAG, "Malloc failed for hop entry");
+ return OC_STACK_ERROR;
+ }
+
+ hopEntry->endpointId = *endpointId;
+ hopEntry->destIntfAddr = *destAddr;
+
+ OCStackResult ret = u_linklist_add(*endpointTable, (void *)hopEntry);
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG(ERROR, TAG, "Adding Enpoint Entry to Routing Table failed");
+ OICFree(hopEntry);
+ return OC_STACK_ERROR;
+ }
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return OC_STACK_OK;
+}
+
+OCStackResult RTMRemoveEndpointEntry(uint16_t endpointId, u_linklist_t **endpointTable)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ RM_NULL_CHECK_WITH_RET(endpointTable, TAG, "endpointTable");
+ RM_NULL_CHECK_WITH_RET(*endpointTable, TAG, "*endpointTable");
+
+ u_linklist_iterator_t *iterTable = NULL;
+ u_linklist_init_iterator(*endpointTable, &iterTable);
+ while (NULL != iterTable)
+ {
+ RTMEndpointEntry_t *entry = u_linklist_get_data(iterTable);
+ if (NULL != entry && endpointId == entry->endpointId)
+ {
+ OCStackResult ret = u_linklist_remove(*endpointTable, &iterTable);
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG(ERROR, TAG, "Deleting Entry from Routing Table failed");
+ return OC_STACK_ERROR;
+ }
+ OICFree(entry);
+ }
+ else
+ {
+ u_linklist_get_next(&iterTable);
+ }
+ }
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return OC_STACK_OK;
+}
+
+OCStackResult RTMRemoveEndpoints(u_linklist_t **endpointTable)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ if (NULL == endpointTable || NULL == *endpointTable)
+ {
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return OC_STACK_OK;
+ }
+
+ OCStackResult ret = RTMFreeEndpointRouteTable(endpointTable);
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG(ERROR, TAG, "Freeing Endpoints failed");
+ return OC_STACK_ERROR;
+ }
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return OC_STACK_OK;
+}
+
+CAEndpoint_t *RTMGetEndpointEntry(uint16_t endpointId, const u_linklist_t *endpointTable)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ if (NULL == endpointTable)
+ {
+ OIC_LOG(ERROR, TAG, "endpointTable is null");
+ return NULL;
+ }
+
+ u_linklist_iterator_t *iterTable = NULL;
+ u_linklist_init_iterator(endpointTable, &iterTable);
+
+ while (NULL != iterTable)
+ {
+ RTMEndpointEntry_t *entry = u_linklist_get_data(iterTable);
+ if (NULL != entry && (endpointId == entry->endpointId))
+ {
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return &(entry->destIntfAddr);
+ }
+ u_linklist_get_next(&iterTable);
+ }
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return NULL;
+}
+
+void RTMEndpointPrintTable(const u_linklist_t *endpointTable)
+{
+ RM_NULL_CHECK_VOID(endpointTable, TAG, "endpointTable");
+
+ OIC_LOG(DEBUG, RM_TAG, "=================Endpoint List table============================\n");
+ u_linklist_iterator_t *iterEndpointTable = NULL;
+ u_linklist_init_iterator(endpointTable, &iterEndpointTable);
+
+ // Iterate over endpoint list to find if already entry for gatewayid is present.
+ while (NULL != iterEndpointTable)
+ {
+ RTMEndpointEntry_t *hop =
+ (RTMEndpointEntry_t *) u_linklist_get_data(iterEndpointTable);
+ if (NULL == hop)
+ {
+ OIC_LOG(ERROR, RM_TAG, "Printing Table Failed");
+ return;
+ }
+ OIC_LOG_V(DEBUG, RM_TAG, "EndpointId : %u\naddr : %s Port : %d Flags : %d",
+ hop->endpointId, hop->destIntfAddr.addr, hop->destIntfAddr.port, hop->destIntfAddr.flags);
+
+ OIC_LOG(DEBUG, RM_TAG, "********************************************\n");
+ u_linklist_get_next(&iterEndpointTable);
+ }
+}