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 "routingmanager.h"
24 #include "routingmanagerinterface.h"
25 #include "routingtablemanager.h"
26 #include "routingmessageparser.h"
27 #include "oic_malloc.h"
28 #include "oic_string.h"
30 #include "ulinklist.h"
31 #include "uarraylist.h"
32 #include "ocstackinternal.h"
33 #include "include/logger.h"
36 * Logging tag for module name.
41 * Tag for printing the logs of forwarding the packet.
43 #define RM_TAG "OIC_RM_RAP"
47 * Unique gateway ID generated before hosting a gateway resource.
49 static uint32_t g_GatewayID = 0;
52 * Used for assigning unique ID.to endpoint's connected to this gateway
54 static uint16_t g_EndpointCount = 0;
57 * Routing table which holds hop entries of Gateways with routeCost.
59 static u_linklist_t *g_routingGatewayTable = NULL;
62 * List which holds hop entries with Endpoint information.
64 static u_linklist_t *g_routingEndpointTable = NULL;
67 * Current time in microseconds.
69 static uint64_t g_aliveTime = 0;
72 * Time to refresh the table entries.
74 static uint64_t g_refreshTableTime = 0;
77 * Sequence number for the notification.
79 static uint32_t g_sequenceNumber = 1;
82 * To check if the routing table is validated on 25th seconds.
84 static bool g_isValidated = false;
87 * Multi cast Sequence number.
89 static uint16_t g_mcastsequenceNumber = 1;
92 * To check if RM is initialized.
94 static bool g_isRMInitialized = false;
97 * API to handle the GET request received for a Gateway Resource.
98 * @param[in] request Request Received.
99 * @param[in] resource Resource handle used for sending the response.
100 * @return ::OC_STACK_OK or Appropriate error code.
102 OCStackResult RMHandleGETRequest(const OCServerRequest *request, const OCResource *resource);
105 * API to handle the OBSERVE request received for a Gateway Resource.
106 * @param[in,out] request Request Received.
107 * @param[in] resource Resource handle used for sending the response.
108 * @return ::OC_STACK_OK or Appropriate error code.
110 OCStackResult RMHandleOBSERVERequest(OCServerRequest *request, const OCResource *resource);
113 * API to handle the OBSERVE request received for a Gateway Resource.
114 * @param[in,out] request Request Received.
115 * @param[in] resource Resource handle used for sending the response.
116 * @return ::OC_STACK_OK or Appropriate error code.
118 OCStackResult RMHandleDELETERequest(const OCServerRequest *request, const OCResource *resource);
121 * Adds a observer after generating observer ID whenever observe
122 * request is received.
123 * @param[in,out] request Request handle of the Observe request.
124 * Sets the value of observeResult as OC_STACK_OK
125 * if observer is added successfully.
126 * @param[out] obsID Observer ID generated for the observer.
127 * @return ::OC_STACK_OK or Appropriate error code.
129 OCStackResult RMAddObserver(OCServerRequest *request, OCObservationId *obsID);
132 * Send Notification to all the observers.
133 * @param[in] payload Payload to be sent in notification.
134 * @return ::OC_STACK_OK or Appropriate error code.
136 OCStackResult RMSendNotificationToAll(const OCRepPayload *payload);
139 * Send Delete request to all the neighbour nodes.
142 void RMSendDeleteToNeighbourNodes();
144 void RMGenerateGatewayID(uint8_t *id, size_t idLen)
146 OIC_LOG(DEBUG, TAG, "RMGenerateGatewayID IN");
147 OCFillRandomMem(id, idLen);
148 OIC_LOG(DEBUG, TAG, "RMGenerateGatewayID OUT");
150 OCStackResult RMInitialize()
152 OIC_LOG(DEBUG, TAG, "RMInitialize IN");
153 if (g_isRMInitialized)
155 OIC_LOG(DEBUG, TAG, "RM already initialized");
159 // Initialize the GatewayResource[/oic/gateway].
160 OCStackResult result = RMInitGatewayResource();
161 if (OC_STACK_OK != result)
163 OIC_LOG_V(ERROR, TAG, "RMInitGatewayResource failed[%d]", result);
167 // Generates a 4 byte Gateway ID.
168 RMGenerateGatewayID((uint8_t *)&g_GatewayID, sizeof(g_GatewayID));
170 OIC_LOG_V(INFO, RM_TAG, "Gateway ID: %u", g_GatewayID);
172 // Initialize the Routing table manager.
173 result = RTMInitialize(&g_routingGatewayTable, &g_routingEndpointTable);
174 if (OC_STACK_OK != result)
176 OIC_LOG_V(ERROR, TAG, "RTMInitialize failed[%d]", result);
180 g_isRMInitialized = true;
182 // Send a DISCOVER request for the gateway resource.
183 result = RMDiscoverGatewayResource();
184 if (OC_STACK_OK != result)
186 OIC_LOG_V(ERROR, TAG, "RMDiscoverGatewayResource failed[%d]", result);
187 RTMTerminate(&g_routingGatewayTable, &g_routingEndpointTable);
191 // Initialize the timer with the current time.
192 g_aliveTime = RTMGetCurrentTime();
193 g_refreshTableTime = g_aliveTime;
195 OIC_LOG(DEBUG, TAG, "RMInitialize OUT");
199 OCStackResult RMTerminate()
201 OIC_LOG(DEBUG, TAG, "RMTerminate IN");
202 if (!g_isRMInitialized)
204 OIC_LOG(ERROR, TAG, "RM not initialized");
205 return OC_STACK_ERROR;
207 // Send DELETE request to neighbour nodes
208 RMSendDeleteToNeighbourNodes();
210 OCStackResult result = RTMTerminate(&g_routingGatewayTable, &g_routingEndpointTable);
211 if (OC_STACK_OK != result)
213 OIC_LOG_V(ERROR, TAG, "CARegisterRoutingMessageHandler failed[%d]", result);
216 g_isRMInitialized = false;
217 OIC_LOG(DEBUG, TAG, "RMTerminate OUT");
221 OCStackResult RMHandleGatewayRequest(OCServerRequest *request, const OCResource *resource)
223 OIC_LOG(DEBUG, TAG, "RMHandleGatewayRequest IN");
225 if (!g_isRMInitialized)
227 OIC_LOG(ERROR, TAG, "RM not initialized");
228 return OC_STACK_ERROR;
231 RM_NULL_CHECK_WITH_RET(request, TAG, "request");
232 RM_NULL_CHECK_WITH_RET(resource, TAG, "resource");
234 OIC_LOG_V(DEBUG, TAG, "Received request of method: %d", request->method);
236 if (OC_REST_GET == request->method)
238 switch((OCObserveAction)request->observationOption)
240 case OC_OBSERVE_REGISTER:
241 OIC_LOG(DEBUG, TAG, "Received OBSERVE request");
242 RMHandleOBSERVERequest(request, resource);
244 case OC_OBSERVE_DEREGISTER:
245 //TODO: Handle this case
246 OIC_LOG(DEBUG, TAG, "Received OBSERVE deregister");
248 case OC_OBSERVE_NO_OPTION:
249 OIC_LOG(DEBUG, TAG, "Received GET request");
250 RMHandleGETRequest(request, resource);
253 OIC_LOG(DEBUG, TAG, "Not Supported by Routing Manager");
256 else if (OC_REST_DELETE == request->method)
258 OIC_LOG(DEBUG, TAG, "Received a Delete request");
259 RMHandleDELETERequest(request, resource);
261 OIC_LOG(DEBUG, TAG, "RMHandleGatewayRequest OUT");
265 OCStackResult RMHandleRequestPayload(OCDevAddr devAddr, const uint8_t *reqPayload,
268 OIC_LOG(DEBUG, TAG, "RMHandleRequestPayload IN");
269 RM_NULL_CHECK_WITH_RET(reqPayload, TAG, "reqPayload");
271 uint32_t gatewayId = 0;
273 OCStackResult result = RMPParseRequestPayload(reqPayload, payloadSize, &gatewayId);
274 RM_VERIFY_SUCCESS(result, OC_STACK_OK);
275 OIC_LOG(INFO, TAG, "RMPParseRequestPayload is success");
276 // Check if the entry is its own.
277 if (gatewayId == g_GatewayID)
279 OIC_LOG(INFO, TAG, "Own Request Received!!");
280 return OC_STACK_CONTINUE;
283 CAEndpoint_t endpoint = {.adapter = CA_DEFAULT_ADAPTER};
284 CopyDevAddrToEndpoint(&devAddr, &endpoint);
286 OIC_LOG_V(INFO, TAG, "Add the gateway ID: %u", gatewayId);
287 RTMDestIntfInfo_t destInterfaces = {.observerId = 0};
288 destInterfaces.destIntfAddr = endpoint;
289 result = RTMAddGatewayEntry(gatewayId, 0, 1, &destInterfaces, &g_routingGatewayTable);
291 if (OC_STACK_OK != result)
293 OIC_LOG(DEBUG, TAG, "Gateway was not added to the routing table");
297 OIC_LOG(INFO, TAG, "Gateway was added");
298 // Create a list to add the updated entries and notify the observers
299 u_linklist_t *updatedTableList = u_linklist_create();
300 if(!updatedTableList)
302 OIC_LOG(DEBUG, TAG, "Failure to notify");
303 return OC_STACK_NO_MEMORY;
306 RTMGatewayId_t gwId = {.gatewayId = gatewayId};
307 RTMGatewayEntry_t newNode;
308 newNode.destination = &gwId;
309 newNode.routeCost = 1;
310 u_linklist_add(updatedTableList, (void *)&newNode);
311 RTMPrintTable(g_routingGatewayTable, g_routingEndpointTable);
313 OCRepPayload *updatedPayload = NULL;
316 result = RMPConstructObserveResPayload(g_GatewayID, g_sequenceNumber,
317 updatedTableList, false,
319 if (OC_STACK_OK != result)
321 OIC_LOG_V(ERROR, TAG, "RMPConstructObserveResPayload failed[%d]", result);
322 RMPFreePayload(updatedPayload);
326 result = RMSendNotificationToAll(updatedPayload);
327 RMPFreePayload(updatedPayload);
328 RM_VERIFY_SUCCESS(result, OC_STACK_OK);
331 u_linklist_free(&updatedTableList);
332 OIC_LOG(DEBUG, TAG, "RMHandleRequestPayload OUT");
336 OCStackResult RMHandleResponsePayload(const OCDevAddr *devAddr, const OCRepPayload *respPayload)
338 OIC_LOG(DEBUG, TAG, "RMHandleResponsePayload IN");
339 RM_NULL_CHECK_WITH_RET(respPayload, TAG, "respPayload");
341 // Parse the Payload to get the Gateway ID of neighbouring node.
342 uint32_t gatewayId = 0;
344 u_linklist_t *gatewayTableList = NULL;
345 bool isUpdateSeqNum = false;
347 OCStackResult result = RMPParseResponsePayload(respPayload, &gatewayId, &seqNum,
348 &gatewayTableList, &isUpdateSeqNum);
349 RM_VERIFY_SUCCESS(result, OC_STACK_OK);
350 // Check if the entry is its own.
351 if (gatewayId == g_GatewayID)
353 OIC_LOG(INFO, TAG, "-------------->Own entry, continue!!");
354 RTMFreeGatewayRouteTable(&gatewayTableList);
355 return OC_STACK_ERROR;
357 // Convert OCDevAddr to endpoint address
358 CAEndpoint_t endpoint = {.adapter = CA_DEFAULT_FLAGS};
359 CopyDevAddrToEndpoint(devAddr, &endpoint);
360 RTMDestIntfInfo_t destInterfaces = {.observerId = 0};
361 destInterfaces.destIntfAddr = endpoint;
364 OIC_LOG_V(DEBUG, TAG, "Sequence Number of Resp payload is %d, Forceupdate: %d",
365 seqNum, isUpdateSeqNum);
366 result = RTMUpdateEntryParameters(gatewayId, seqNum, &destInterfaces,
367 &g_routingGatewayTable, isUpdateSeqNum);
368 if (OC_STACK_COMM_ERROR == result)
370 OIC_LOG(ERROR, TAG, "Few packet drops are found, sequence number is not matching");
371 // Send a observe request to the gateway.
372 RMSendObserveRequest(devAddr, NULL);
373 RTMFreeGatewayRouteTable(&gatewayTableList);
376 else if (OC_STACK_DUPLICATE_REQUEST == result)
378 OIC_LOG(ERROR, TAG, "Same sequence number is received");
379 RTMFreeGatewayRouteTable(&gatewayTableList);
384 // Check if the payload is for Removal
385 bool doRemoveEntry = false;
387 if (NULL != gatewayTableList && NULL != gatewayTableList->list)
389 RTMGatewayEntry_t *headPtr = u_linklist_get_data(gatewayTableList->list);
390 if (headPtr && 0 == headPtr->routeCost)
392 OIC_LOG(INFO, TAG, "Remove entry is called");
393 doRemoveEntry = true;
397 // Create a list to add the updated entries and notify the observers
398 u_linklist_t *updatedTableList = u_linklist_create();
399 if(!updatedTableList)
401 OIC_LOG(DEBUG, TAG, "Failed to allocate memory");
402 return OC_STACK_NO_MEMORY;
405 u_linklist_t *alternativeRouteList = u_linklist_create();
406 if(!alternativeRouteList)
408 OIC_LOG(DEBUG, TAG, "Failed to allocate memory");
409 return OC_STACK_NO_MEMORY;
412 OCRepPayload *updatedPayload = NULL;
413 if (false == doRemoveEntry)
415 OIC_LOG_V(INFO, TAG, "Add the gateway ID: %u", gatewayId);
416 result = RTMAddGatewayEntry(gatewayId, 0, 1, &destInterfaces, &g_routingGatewayTable);
417 if (OC_STACK_OK == result)
419 OIC_LOG(INFO, TAG, "Node was added");
420 RTMGatewayId_t gwId = {.gatewayId = gatewayId};
421 RTMGatewayEntry_t newNode;
422 newNode.destination = &gwId;
423 newNode.routeCost = 1;
424 u_linklist_add(updatedTableList, (void *)&newNode);
425 RTMPrintTable(g_routingGatewayTable, g_routingEndpointTable);
427 if (NULL == gatewayTableList)
429 OIC_LOG(INFO, TAG, "Received a Discover Payload");
431 result = RMPConstructObserveResPayload(g_GatewayID, g_sequenceNumber,
432 updatedTableList, false,
434 RM_VERIFY_SUCCESS(result, OC_STACK_OK);
435 goto sendNotification;
440 // Iterate the Table and get each entry
441 u_linklist_iterator_t *iterTable = NULL;
442 u_linklist_init_iterator(gatewayTableList, &iterTable);
444 while (NULL != iterTable)
446 RTMGatewayEntry_t *entry = u_linklist_get_data(iterTable);
447 // Check if the entry is its own.
448 if (!entry || entry->destination->gatewayId == g_GatewayID)
450 OIC_LOG(INFO, TAG, "Ignore entry, continue!!");
451 u_linklist_get_next(&iterTable);
455 OIC_LOG_V(INFO, TAG, "Gateway ID: %u", entry->destination->gatewayId);
456 if (true == doRemoveEntry)
458 // Remove the entry from RTM.
459 RTMGatewayEntry_t *existEntry = NULL;
460 result = RTMRemoveGatewayDestEntry(entry->destination->gatewayId, gatewayId,
461 &destInterfaces, &existEntry,
462 &g_routingGatewayTable);
463 if (OC_STACK_OK != result && NULL != existEntry)
465 u_linklist_add(alternativeRouteList, (void *)existEntry);
470 // Add the entry to RTM.
471 entry->routeCost = entry->routeCost + 1;
472 result = RTMAddGatewayEntry(entry->destination->gatewayId, gatewayId,
473 entry->routeCost, NULL, &g_routingGatewayTable);
476 if (OC_STACK_OK == result)
478 OIC_LOG(INFO, TAG, "Gateway was added/removed");
479 u_linklist_add(updatedTableList, (void *)entry);
480 RTMPrintTable(g_routingGatewayTable, g_routingEndpointTable);
482 u_linklist_get_next(&iterTable);
485 if ( 0 < u_linklist_length(alternativeRouteList))
487 OIC_LOG(DEBUG, TAG, "Alternative routing found");
488 // Send the notification.
489 OCRepPayload *removeTablePayload = NULL;
491 result = RMPConstructObserveResPayload(g_GatewayID, g_sequenceNumber,
492 alternativeRouteList, false,
493 &removeTablePayload);
494 if (OC_STACK_OK != result)
496 OIC_LOG_V(ERROR, TAG, "RMPConstructObserveResPayload failed[%d]", result);
497 RMPFreePayload(removeTablePayload);
500 result = RMSendNotificationToAll(removeTablePayload);
501 RMPFreePayload(removeTablePayload);
502 RM_VERIFY_SUCCESS(result, OC_STACK_OK);
505 if ( 0 >= u_linklist_length(updatedTableList))
507 OIC_LOG_V(DEBUG, TAG, "No updation is needed, Length is %d",
508 u_linklist_length(updatedTableList));
513 if (true == doRemoveEntry)
515 result = RMPConstructRemovalPayload(g_GatewayID, g_sequenceNumber, updatedTableList,
516 false, &updatedPayload);
520 result = RMPConstructObserveResPayload(g_GatewayID, g_sequenceNumber,
521 updatedTableList, false,
524 RM_VERIFY_SUCCESS(result, OC_STACK_OK);
527 result = RMSendNotificationToAll(updatedPayload);
528 RM_VERIFY_SUCCESS(result, OC_STACK_OK);
531 RMPFreePayload(updatedPayload);
532 RTMFreeGatewayRouteTable(&gatewayTableList);
533 u_linklist_free(&updatedTableList);
534 u_linklist_free(&alternativeRouteList);
535 OIC_LOG(DEBUG, TAG, "RMHandleResponsePayload OUT");
539 OCStackResult RMHandleGETRequest(const OCServerRequest *request, const OCResource *resource)
541 OIC_LOG(DEBUG, TAG, "RMHandleGETRequest IN");
542 RM_NULL_CHECK_WITH_RET(request, TAG, "request");
543 RM_NULL_CHECK_WITH_RET(resource, TAG, "resource");
545 OCRepPayload *payload = NULL;
546 OCStackResult result = RMPConstructGatewayPayload(g_GatewayID, &payload);
547 if (OC_STACK_OK != result)
549 OIC_LOG_V(DEBUG, TAG, "RMPConstructDiscoverPayload failed[%d]", result);
553 // Send a response for GET request
554 result = RMSendResponse(request, resource, payload);
555 if (OC_STACK_OK != result)
557 OIC_LOG_V(DEBUG, TAG, "Send response failed[%d]", result);
558 RMPFreePayload(payload);
562 RMPFreePayload(payload);
563 // Send a observe request
564 result = RMSendObserveRequest(&(request->devAddr), NULL);
565 if (OC_STACK_OK != result)
567 OIC_LOG_V(DEBUG, TAG, "Send response failed[%d]", result);
569 OIC_LOG(DEBUG, TAG, "RMHandleGETRequest OUT");
573 OCStackResult RMHandleOBSERVERequest(OCServerRequest *request, const OCResource *resource)
575 OIC_LOG(DEBUG, TAG, "RMHandleOBSERVERequest IN");
576 RM_NULL_CHECK_WITH_RET(request, TAG, "request");
577 RM_NULL_CHECK_WITH_RET(resource, TAG, "resource");
579 // Parse payload and add the gateway entry.
580 if (0 < request->payloadSize)
582 RMHandleRequestPayload(request->devAddr, request->payload, request->payloadSize);
585 // Generate and add observer.
586 OCObservationId obsID = 0;
587 OCStackResult result = RMAddObserver(request, &obsID);
588 RM_VERIFY_SUCCESS(result, OC_STACK_OK);
589 OIC_LOG_V(DEBUG, TAG, "Observer ID is %d", obsID);
592 // Get the Routing table from RTM
593 OCRepPayload *payload = NULL;
594 RTMPrintTable(g_routingGatewayTable, g_routingEndpointTable);
595 OIC_LOG(DEBUG, TAG, "Construct Routing table payload");
596 result = RMPConstructObserveResPayload(g_GatewayID, g_sequenceNumber,
597 g_routingGatewayTable, true,
599 if (OC_STACK_OK != result)
601 OIC_LOG_V(ERROR, TAG, "RMPConstructObserveResPayload failed[%d]", result);
602 RMPFreePayload(payload);
606 result = RMSendResponse(request, resource, payload);
607 RMPFreePayload(payload);
608 RM_VERIFY_SUCCESS(result, OC_STACK_OK);
610 OIC_LOG(DEBUG, TAG, "RMHandleOBSERVERequest OUT");
614 OCStackResult RMHandleDELETERequest(const OCServerRequest *request, const OCResource *resource)
616 OIC_LOG(DEBUG, TAG, "RMHandleDELETERequest IN");
617 RM_NULL_CHECK_WITH_RET(request, TAG, "request");
618 RM_NULL_CHECK_WITH_RET(resource, TAG, "resource");
620 uint32_t gatewayId = 0;
621 OCStackResult result = RMPParseRequestPayload(request->payload, request->payloadSize,
623 RM_VERIFY_SUCCESS(result, OC_STACK_OK);
624 OIC_LOG(INFO, TAG, "RMPParseRequestPayload is success");
626 OIC_LOG_V(INFO, TAG, "Remove the gateway ID: %u", gatewayId);
628 u_linklist_t *removedGatewayNodes = NULL;
629 result = RTMRemoveGatewayEntry(gatewayId, &removedGatewayNodes, &g_routingGatewayTable);
630 RM_VERIFY_SUCCESS(result, OC_STACK_OK);
632 if (0 < u_linklist_length(removedGatewayNodes))
634 OCRepPayload *resPayloads = NULL;
636 result = RMPConstructRemovalPayload(g_GatewayID, g_sequenceNumber, removedGatewayNodes,
637 false, &resPayloads);
638 if (OC_STACK_OK != result)
640 OIC_LOG_V(ERROR, TAG, "RMPConstructRemovalPayload failed[%d]", result);
641 RMPFreePayload(resPayloads);
644 result = RMSendNotificationToAll(resPayloads);
645 RMPFreePayload(resPayloads);
646 RM_VERIFY_SUCCESS(result, OC_STACK_OK);
647 RTMPrintTable(g_routingGatewayTable, g_routingEndpointTable);
651 RTMFreeGatewayRouteTable(&removedGatewayNodes);
652 OIC_LOG(DEBUG, TAG, "RMHandleDELETERequest OUT");
656 OCStackResult RMAddObserver(OCServerRequest *request, OCObservationId *obsID)
658 OIC_LOG(DEBUG, TAG, "RMAddObserverForGateway OUT");
659 RM_NULL_CHECK_WITH_RET(request, TAG, "request");
660 RM_NULL_CHECK_WITH_RET(obsID, TAG, "obsID");
662 // Generate the ObserverID
663 CAEndpoint_t endpoint = {.adapter = 0};
664 CopyDevAddrToEndpoint(&(request->devAddr), &endpoint);
666 // Check if observer is already added.
667 if (true == RTMIsObserverPresent(endpoint, obsID, g_routingGatewayTable))
669 OIC_LOG(DEBUG, TAG, "Observer is present");
670 request->observeResult = OC_STACK_OK;
674 OCStackResult result = RMAddObserverToStack(request, obsID);
675 request->observeResult = result;
676 if (OC_STACK_OK == result)
678 OIC_LOG(DEBUG, TAG, "Added observer successfully");
680 // Add the observer to the list.
681 result = RTMAddObserver(*obsID, endpoint, &g_routingGatewayTable);
682 if (OC_STACK_OK != result)
684 OIC_LOG_V(DEBUG, TAG, "RMAddObserver failed[%d]", result);
687 OIC_LOG(DEBUG, TAG, "RMAddObserverForGateway OUT");
691 OCStackResult RMSendNotificationToAll(const OCRepPayload *payload)
693 OIC_LOG(DEBUG, TAG, "RMSendNotificationToAll IN");
694 RM_NULL_CHECK_WITH_RET(payload, TAG, "payload");
696 OCObservationId *obsList = NULL;
698 // Get the complete observer list.
699 RTMGetObserverList(&obsList, &obsLen, g_routingGatewayTable);
700 OCStackResult result = OC_STACK_OK;
701 OIC_LOG_V(DEBUG, TAG, "Number of observers is %d", obsLen);
704 // Send notification to the list of observers.
705 OIC_LOG_V(DEBUG, TAG, "Sending notification with Sequence Number: %d", g_sequenceNumber);
706 result = RMSendNotificationForListofObservers(obsList, obsLen, payload);
707 RM_VERIFY_SUCCESS(result, OC_STACK_OK);
708 g_aliveTime = RTMGetCurrentTime();
713 OIC_LOG(DEBUG, TAG, "RMSendNotificationToAll OUT");
719 if (!g_isRMInitialized)
724 OCStackResult result = OC_STACK_OK;
725 uint64_t currentTime = RTMGetCurrentTime();
726 if (GATEWAY_ALIVE_TIMEOUT <= currentTime - g_aliveTime)
728 g_aliveTime = currentTime;
729 // Construct a payload with only the current sequence number.
730 OCRepPayload *payload = NULL;
731 result = RMPConstructObserveResPayload(g_GatewayID, g_sequenceNumber, NULL,
733 if (OC_STACK_OK != result)
735 OIC_LOG_V(ERROR, TAG, "RMPConstructObserveResPayload failed[%d]", result);
736 RMPFreePayload(payload);
739 OIC_LOG(DEBUG, TAG, "Sending the alive notification to all");
740 // Send notification for every 15s to all the neighbours.
741 result = RMSendNotificationToAll(payload);
742 RMPFreePayload(payload);
743 RM_VERIFY_SUCCESS(result, OC_STACK_OK);
746 if (ROUTINGTABLE_VALIDATION_TIMEOUT <= currentTime - g_refreshTableTime)
748 OIC_LOG(DEBUG, TAG, "Validating the routing table");
749 u_linklist_t *removedEntries = NULL;
750 // Remove the invalid gateway entries.
751 RTMRemoveInvalidGateways(&removedEntries, &g_routingGatewayTable);
752 if (0 < u_linklist_length(removedEntries))
754 OCRepPayload *resPayloads = NULL;
756 result = RMPConstructRemovalPayload(g_GatewayID, g_sequenceNumber, removedEntries,
757 false, &resPayloads);
758 RTMFreeGatewayRouteTable(&removedEntries);
759 if (OC_STACK_OK != result)
761 OIC_LOG_V(ERROR, TAG, "RMPConstructRemovalPayload failed[%d]", result);
762 RMPFreePayload(resPayloads);
765 result = RMSendNotificationToAll(resPayloads);
766 RMPFreePayload(resPayloads);
767 RM_VERIFY_SUCCESS(result, OC_STACK_OK);
768 RTMPrintTable(g_routingGatewayTable, g_routingEndpointTable);
770 g_refreshTableTime = currentTime;
771 g_isValidated = false;
772 u_linklist_free(&removedEntries);
776 if (!g_isValidated && ROUTINGTABLE_REFRESH_TIMEOUT <= (currentTime - g_refreshTableTime))
778 OIC_LOG_V(DEBUG, TAG, "Refreshing the routing table: %llu", currentTime);
779 u_linklist_t* invalidInterfaces = NULL;
780 RTMUpdateDestAddrValidity(&invalidInterfaces, &g_routingGatewayTable);
781 if (0 < u_linklist_length(invalidInterfaces))
783 u_linklist_iterator_t *iterTable = NULL;
784 u_linklist_init_iterator(invalidInterfaces, &iterTable);
785 while (NULL != iterTable)
787 RTMDestIntfInfo_t *entry = (RTMDestIntfInfo_t *) u_linklist_get_data(iterTable);
790 u_linklist_get_next(&iterTable);
793 OCDevAddr devAddr = {.adapter = OC_DEFAULT_ADAPTER};
794 CopyEndpointToDevAddr(&(entry->destIntfAddr), &devAddr);
795 RMSendObserveRequest(&devAddr, NULL);
796 u_linklist_get_next(&iterTable);
799 g_isValidated = true;
800 RTMPrintTable(g_routingGatewayTable, g_routingEndpointTable);
801 u_linklist_free(&invalidInterfaces);
808 OCStackResult RMGetGatewayPayload(OCRepPayload **payload)
810 OIC_LOG(DEBUG, TAG, "RMGetGatewayPayload IN");
811 OCStackResult result = RMPConstructGatewayPayload(g_GatewayID, payload);
812 OIC_LOG_V(DEBUG, TAG, "RMPConstructDiscoverPayload result is %d", result);
813 OIC_LOG(DEBUG, TAG, "RMGetGatewayPayload OUT");
817 void RMSendDeleteToNeighbourNodes()
819 OIC_LOG(DEBUG, TAG, "RMSendDeleteToNeighbourNodes IN");
820 u_linklist_t *neighbourNodes = NULL;
821 RTMGetNeighbours(&neighbourNodes, g_routingGatewayTable);
823 if (0 >= u_linklist_length(neighbourNodes))
825 OIC_LOG(DEBUG, TAG, "No neighbour nodes present");
829 u_linklist_iterator_t *iterTable = NULL;
830 u_linklist_init_iterator(neighbourNodes, &iterTable);
831 while (NULL != iterTable)
834 OCRepPayload *payload = NULL;
835 // Created payload is freed in the OCDoResource() api.
836 OCStackResult result = RMPConstructGatewayPayload(g_GatewayID, &payload);
837 if (OC_STACK_OK != result)
839 OIC_LOG_V(DEBUG, TAG, "RMPConstructGatewayPayload failed[%d]", result);
840 RMPFreePayload(payload);
841 u_linklist_free(&neighbourNodes);
845 RTMGatewayEntry_t *entry = (RTMGatewayEntry_t *) u_linklist_get_data(iterTable);
848 for (uint32_t i = 0; i < u_arraylist_length(entry->destination->destIntfAddr); i++)
850 RTMDestIntfInfo_t *dest = u_arraylist_get(entry->destination->destIntfAddr, i);
853 OIC_LOG(ERROR, RM_TAG, "Failed to get dest address");
856 OCDevAddr devAddr = {.adapter = OC_DEFAULT_ADAPTER};
857 CopyEndpointToDevAddr(&(dest->destIntfAddr), &devAddr);
858 OIC_LOG_V(DEBUG, TAG, "\nDestination interface addresses: %s[%d], OCDevAddr: %s[%d]",
859 dest->destIntfAddr.addr, dest->destIntfAddr.port, devAddr.addr, devAddr.port);
860 RMSendDeleteRequest(&devAddr, payload);
864 u_linklist_get_next(&iterTable);
867 u_linklist_free(&neighbourNodes);
868 OIC_LOG(DEBUG, TAG, "RMSendDeleteToNeighbourNodes OUT");
871 uint32_t RMGetGatewayId()
873 if (!g_isRMInitialized)
875 OIC_LOG(ERROR, TAG, "RM not initialized");
881 uint16_t RMGetMcastSeqNumber()
883 if (!g_isRMInitialized)
885 OIC_LOG(DEBUG, TAG, "RM not initialized");
888 return ++g_mcastsequenceNumber;
892 * This function is lifeline of packet forwarding module, hence we are going to do some serious
893 * handling here. Following are the expectations from this function:
894 * 1) If routing option is not available, forward packet to RI only. else:
895 * 2) If source is empty in routing option, packet is from end device, add an end device entry and
896 * add "GatewayId:ClientId" as source.
897 * 3) If destination is empty in routing option, its multicast packet, increase hopcount and
898 * multicast on other interfaces. Also remove routing Option and forward to RI. (Before
899 * forwarding, check last mCastSeqNumber for the source gateway otherwise we might be looping
901 * 4) If destination is present in routing option, its unicast packet,
902 * a) If self gatewayId is present in destination and no clientId, remove routing option
904 * b) If self gatewayId and a clientId is present in destination, forward to end device.
905 * 5) Drop a packet if its hop count reaches NUMBER_OF_GATEWAYS.
908 OCStackResult RMHandlePacket(bool isRequest, void *message, const CAEndpoint_t *sender,
909 bool *selfDestination, bool *isEmptyMsg)
911 RM_NULL_CHECK_WITH_RET(message, RM_TAG, "message");
912 RM_NULL_CHECK_WITH_RET(sender, RM_TAG, "sender");
913 RM_NULL_CHECK_WITH_RET(selfDestination, RM_TAG, "selfDestination");
915 bool forward = false;
916 bool isEMPTYPacket = false;
917 CAEndpoint_t nextHop = {.adapter = CA_DEFAULT_ADAPTER};
918 CAInfo_t *info = NULL;
921 CARequestInfo_t *msg = message;
923 RM_NULL_CHECK_WITH_RET(info, RM_TAG, "info");
927 CAResponseInfo_t *msg = message;
929 RM_NULL_CHECK_WITH_RET(info, RM_TAG, "info");
932 // 1. If routing option is not available, forward packet to RI only.
933 int8_t routeIndex = -1;
934 RMGetRouteOptionIndex(info->options, info->numOptions, &routeIndex);
935 if (-1 >= routeIndex)
937 OIC_LOG(ERROR, RM_TAG, "No route option present. Let RI Handle");
938 // Let RI handle this packet.
939 *selfDestination = true;
943 // Get existing values in packet route option.
944 RMRouteOption_t routeOption = {.srcGw = 0};
945 OCStackResult res = RMParseRouteOption(&info->options[routeIndex], &routeOption);
946 if (OC_STACK_OK != res)
948 OIC_LOG_V(ERROR, RM_TAG, "RMParseRouteOption failed");
949 return OC_STACK_ERROR;
953 * 2) If source is empty in routing option, packet is from end device, add an end device entry
954 * and add "GatewayId:ClientId" as source.
956 if (g_GatewayID == routeOption.srcGw)
958 OIC_LOG_V(ERROR, RM_TAG, "Packet is of its own");
959 if (0 == routeOption.destGw && g_mcastsequenceNumber < routeOption.mSeqNum)
961 g_mcastsequenceNumber = routeOption.mSeqNum;
964 return OC_STACK_ERROR;
966 else if (0 == routeOption.srcGw)
968 OIC_LOG(INFO, RM_TAG, "Source missing in option");
969 // Packet from end device as Gateway will add source in option.
970 uint16_t endpointId = g_EndpointCount + 1;
971 OCStackResult res = RTMAddEndpointEntry(&endpointId, sender, &g_routingEndpointTable);
972 if (OC_STACK_OK == res)
974 g_EndpointCount = endpointId;
975 OIC_LOG_V(INFO, RM_TAG, "New endpoint added [%d]:[%s]", g_EndpointCount, sender->addr);
977 else if (OC_STACK_DUPLICATE_REQUEST == res)
979 OIC_LOG_V(INFO, RM_TAG, "Endpoint exist [%d]", endpointId);
983 OIC_LOG(ERROR, RM_TAG, "Add Endpoint failed");
984 return OC_STACK_ERROR;
987 // add source option.
988 routeOption.srcGw = g_GatewayID;
989 routeOption.srcEp = endpointId;
990 OIC_LOG_V(INFO, RM_TAG, "Added source: [%u:%u]", g_GatewayID, endpointId);
994 * 3) If destination is empty in routing option, its a multicast packet, increase hopcount and
995 * multicast on other interfaces. Also remove routing Option and forward to RI (taken care by
996 * caller of this function).
998 if (0 == routeOption.destGw)
1000 OIC_LOG(INFO, RM_TAG, "Destination missing in option");
1001 // This is a multicast packet.
1002 if (g_GatewayID == routeOption.srcGw)
1004 routeOption.mSeqNum = ++g_mcastsequenceNumber;
1008 OCStackResult update = RTMUpdateMcastSeqNumber(routeOption.srcGw, routeOption.mSeqNum,
1009 &g_routingGatewayTable);
1010 if (OC_STACK_OK != update)
1012 // this shouldnt have been forwarded. ignore.
1013 OIC_LOG_V(ERROR, RM_TAG, "Multicast Sequence number not proper: %d",
1014 routeOption.mSeqNum);
1015 return OC_STACK_ERROR;
1020 *selfDestination = true;
1023 // Send multicast on every adapter except the one from which packet was received
1024 // TODO::: support to be added for IP hop.
1025 if (sender->adapter != CA_ADAPTER_IP)
1027 nextHop.adapter |= CA_ADAPTER_IP;
1028 nextHop.flags |= CA_IPV4 | CA_IPV6;
1031 if(sender->adapter != CA_ADAPTER_GATT_BTLE)
1033 nextHop.adapter |= CA_ADAPTER_GATT_BTLE;
1036 if(sender->adapter != CA_ADAPTER_RFCOMM_BTEDR)
1038 nextHop.adapter |= CA_ADAPTER_RFCOMM_BTEDR;
1041 // Only requests are sent as multicast.
1044 CARequestInfo_t *msg = message;
1045 msg->isMulticast = true;
1047 goto rewriteandexit;
1049 else if (g_GatewayID == routeOption.destGw)
1051 OIC_LOG(INFO, RM_TAG, "GatewayId found in destination");
1053 // Check the MSGType of RouteOption to find if the packet is EMPTY packet.
1054 if (ACK == routeOption.msgType || RST == routeOption.msgType)
1056 isEMPTYPacket = true;
1060 * This unicast packet either belongs to us or any of our connected end devices
1061 * check if packet belongs to end device.
1063 if (0 != routeOption.destEp)
1065 // forward packet to the client.
1066 OIC_LOG_V(INFO, RM_TAG, "Forwarding packet to client id [%u]", routeOption.destEp);
1067 CAEndpoint_t *clientInfo = RTMGetEndpointEntry(routeOption.destEp,
1068 g_routingEndpointTable);
1071 OIC_LOG(ERROR, RM_TAG, "Failed to get Client info");
1072 return OC_STACK_ERROR;
1075 nextHop = *clientInfo;
1077 *selfDestination = false;
1078 goto rewriteandexit;
1082 // packet is for us.
1083 OIC_LOG(INFO, RM_TAG, "Received packet for self");
1085 *selfDestination = true;
1086 goto rewriteandexit;
1092 * This unicast packet belongs to other gateway.
1093 * we only want to print first 4 bytes of packet as readable GatewayId.
1095 OIC_LOG_V(INFO, RM_TAG, "Forwarding packet to Gateway: %u", routeOption.destGw);
1096 RTMGatewayId_t *nextHopGw = RTMGetNextHop(routeOption.destGw, g_routingGatewayTable);
1099 OIC_LOG(ERROR, RM_TAG, "Failed to get next hop");
1100 return OC_STACK_ERROR;
1103 // TODO:: check preferences among multiple interface addresses, for now sending on first one
1104 RTMDestIntfInfo_t *address = u_arraylist_get(nextHopGw->destIntfAddr, 0);
1107 OIC_LOG(ERROR, RM_TAG, "Failed to get address for next hop");
1108 return OC_STACK_ERROR;
1111 nextHop = address->destIntfAddr;
1113 *selfDestination = false;
1114 goto rewriteandexit;
1121 // Don't forward any packet meant for gateway resource.
1122 if (info->resourceUri && (0 == strcmp(info->resourceUri, OC_RSRVD_GATEWAY_URI)) &&
1123 (ACK != routeOption.msgType))
1125 OIC_LOG(ERROR, RM_TAG, "Not forwarding gateway resource packet");
1127 else if (sender->flags & CA_SECURE)
1129 OIC_LOG(ERROR, RM_TAG, "This is secured request. Not supported by routing manager");
1130 return OC_STACK_ERROR;
1132 else if (isEMPTYPacket)
1134 OIC_LOG(DEBUG, TAG, "The message to be Forwarded is a EMPTY message");
1135 CAResponseInfo_t responseMessage = {.result = CA_EMPTY};
1136 if (ACK == routeOption.msgType)
1138 responseMessage.info.type = CA_MSG_ACKNOWLEDGE;
1142 responseMessage.info.type = CA_MSG_RESET;
1145 responseMessage.info.messageId = info->messageId;
1146 responseMessage.info.dataType = CA_RESPONSE_DATA;
1148 CAResult_t caRes = CASendResponse(&nextHop, &responseMessage);
1149 if (CA_STATUS_OK != caRes)
1151 OIC_LOG_V(ERROR, RM_TAG, "Failed to forward response to next hop [%d][%s]",
1152 caRes, nextHop.addr);
1153 // Since a response is always unicast, return error here.
1154 return OC_STACK_ERROR;
1159 // rewrite any changes in routing option.
1160 res = RMCreateRouteOption(&routeOption, &info->options[routeIndex]);
1161 if (OC_STACK_OK != res)
1163 OIC_LOG_V(ERROR, RM_TAG, "Rewriting RM option failed");
1167 * When forwarding a packet, do not attempt retransmission as its the responsibility of
1168 * packet originator node.
1170 info->skipRetransmission = true;
1173 CARequestInfo_t *msg = message;
1174 msg->info.dataType = CA_REQUEST_DATA;
1175 CAResult_t caRes = CASendRequest(&nextHop, msg);
1176 if (CA_STATUS_OK != caRes)
1178 OIC_LOG_V(ERROR, RM_TAG, "Failed to forward request to next hop [%d][%s]", caRes,
1180 if(0 == routeOption.destGw)
1183 * No point going forward as unicast packet could not be forwarded
1184 * not returning error for multicast as we may still let RI process
1187 return OC_STACK_ERROR;
1193 CAResponseInfo_t *msg = message;
1194 msg->info.dataType = CA_RESPONSE_DATA;
1195 CAResult_t caRes = CASendResponse(&nextHop, msg);
1196 if (CA_STATUS_OK != caRes)
1198 OIC_LOG_V(ERROR, RM_TAG, "Failed to forward response to next hop [%d][%s]",
1199 caRes, nextHop.addr);
1200 // Since a response is always unicast, return error here.
1201 return OC_STACK_ERROR;
1212 OIC_LOG(DEBUG, TAG, "POST message with type ACK in Route Option");
1213 if (NULL != isEmptyMsg)
1220 OIC_LOG(DEBUG, TAG, "Response for EMPTY message is received");
1221 CAResponseInfo_t *msg = message;
1222 if (ACK == (MSGType)routeOption.msgType)
1224 msg->info.type = CA_MSG_ACKNOWLEDGE;
1228 msg->info.type = CA_MSG_RESET;
1230 msg->result = CA_EMPTY;
1231 OICFree(msg->info.token);
1232 msg->info.token = NULL;
1233 msg->info.tokenLength = 0;
1238 OIC_LOG_V(INFO, RM_TAG, "Sender: [%u] Destination: [%u]", routeOption.srcGw, routeOption.destGw);
1242 OCStackResult RMHandleRequest(CARequestInfo_t *message, const CAEndpoint_t *sender,
1243 bool *selfDestination, bool *isEmptyMsg)
1245 if (!g_isRMInitialized)
1247 OIC_LOG(ERROR, TAG, "RM not initialized");
1248 *selfDestination = true;
1251 OCStackResult res = RMHandlePacket(true, message, sender, selfDestination, isEmptyMsg);
1255 OCStackResult RMHandleResponse(CAResponseInfo_t *message, const CAEndpoint_t *sender,
1256 bool *selfDestination)
1258 if (!g_isRMInitialized)
1260 OIC_LOG(ERROR, TAG, "RM not initialized");
1261 *selfDestination = true;
1264 OCStackResult res = RMHandlePacket(false, message, sender, selfDestination, NULL);