]> rtime.felk.cvut.cz Git - arc.git/blobdiff - communication/CanIf/CanIf.c
LED Blinker example made running for the RPP Board.
[arc.git] / communication / CanIf / CanIf.c
index c72e450292e65a6d80ace4ed7f5e9f8127a53dc9..7f27d79299b517ec977af4baf2f8abea6c088db7 100644 (file)
-/* -------------------------------- Arctic Core ------------------------------
- * Arctic Core - the open source AUTOSAR platform http://arccore.com
- *
- * Copyright (C) 2009  ArcCore AB <contact@arccore.com>
- *
- * This source code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by the
- * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- * -------------------------------- Arctic Core ------------------------------*/
-
-
-
-
-
-
-
-
-#include "Det.h"
-#include "CanIf.h"
-
-#include "Can.h"
-#include "CanIf_Cbk.h"
-#include "string.h"
-
-// Added by Mattias 2008-11-18
-#include "debug.h"
-#include "PduR.h"
-
-#if defined(USE_CANTP)
-#include "CanTp_Cbk.h"
-#endif
-
-#if 0
-// TODO: Include upper layer functions, See CANIF208 and CANIF233
-#include "PduR_CanIf.h"
-#include "CanNm.h"
-#include "CanTp.h"
-
-#include "PduR_Cbk.h"
-#include "CanNm_Cbk.h"
-#include "CanTp_Cbk.h"
-#endif
-
-#if  ( CANIF_DEV_ERROR_DETECT == STD_ON )
-#define VALIDATE(_exp,_api,_err ) \
-        if( !(_exp) ) { \
-          Det_ReportError(MODULE_ID_CANIF, 0, _api, _err); \
-          return E_NOT_OK; \
-        }
-
-#define VALIDATE_NO_RV(_exp,_api,_err ) \
-  if( !(_exp) ) { \
-          Det_ReportError(MODULE_ID_CANIF, 0, _api, _err); \
-          return; \
-        }
-#undef DET_REPORTERROR
-#define DET_REPORTERROR(_x,_y,_z,_q) Det_ReportError(_x, _y, _z, _q)
-
-#else
-#define VALIDATE(_exp,_api,_err )
-#define VALIDATE_NO_RV(_exp,_api,_err )
-#define DET_REPORTERROR(_x,_y,_z,_q)
-#endif
-
-
-// Helper to get the Can Controller refered to by a CanIf Channel
-#define ARC_GET_CHANNEL_CONTROLLER(_channel) \
-       CanIf_ConfigPtr->Arc_ChannelToControllerMap[channel]
-
-/* Global configure */
-static const CanIf_ConfigType *CanIf_ConfigPtr;
-
-// Struct of controller private data.
-typedef struct
-{
-  CanIf_ControllerModeType  ControllerMode;
-  CanIf_ChannelGetModeType  PduMode;
-} CanIf_ChannelPrivateType;
-
-typedef struct
-{
-  boolean initRun;
-  CanIf_ChannelPrivateType channelData[CANIF_CHANNEL_CNT];
-} CanIf_GlobalType;
-
-static CanIf_Arc_ChannelIdType CanIf_Arc_FindHrhChannel( Can_Arc_HRHType hrh )
-{
+/* -------------------------------- Arctic Core ------------------------------\r
+ * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
+ *\r
+ * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
+ *\r
+ * This source code is free software; you can redistribute it and/or modify it\r
+ * under the terms of the GNU General Public License version 2 as published by the\r
+ * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
+ *\r
+ * This program is distributed in the hope that it will be useful, but\r
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
+ * for more details.\r
+ * -------------------------------- Arctic Core ------------------------------*/\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+#include "Det.h"\r
+#include "CanIf.h"\r
+\r
+#include "Can.h"\r
+#include "CanIf_Cbk.h"\r
+#include <string.h>\r
+\r
+#include "debug.h"\r
+#include "PduR.h"\r
+\r
+#if defined(USE_CANTP)\r
+#include "CanTp_Cbk.h"\r
+#endif\r
+\r
+#if defined(USE_J1939TP)\r
+#include "J1939Tp_Cbk.h"\r
+#endif\r
+\r
+#if defined(USE_CANNM)\r
+#include "CanNm.h"\r
+#endif\r
+\r
+#if 0\r
+// TODO: Include upper layer functions, See CANIF208 and CANIF233\r
+#include "PduR_CanIf.h"\r
+#include "CanNm.h"\r
+#include "CanTp.h"\r
+\r
+#include "PduR_Cbk.h"\r
+#include "CanNm_Cbk.h"\r
+#include "CanTp_Cbk.h"\r
+#endif\r
+\r
+#if  ( CANIF_DEV_ERROR_DETECT == STD_ON )\r
+#define VALIDATE(_exp,_api,_err ) \\r
+        if( !(_exp) ) { \\r
+          Det_ReportError(MODULE_ID_CANIF, 0, _api, _err); \\r
+          return E_NOT_OK; \\r
+        }\r
+\r
+#define VALIDATE_NO_RV(_exp,_api,_err ) \\r
+  if( !(_exp) ) { \\r
+          Det_ReportError(MODULE_ID_CANIF, 0, _api, _err); \\r
+          return; \\r
+        }\r
+#define DET_REPORTERROR(_x,_y,_z,_q) Det_ReportError(_x, _y, _z, _q)\r
+\r
+#else\r
+#define VALIDATE(_exp,_api,_err )\r
+#define VALIDATE_NO_RV(_exp,_api,_err )\r
+#define DET_REPORTERROR(_x,_y,_z,_q)\r
+#endif\r
+\r
+\r
+// Helper to get the Can Controller refered to by a CanIf Channel\r
+#define ARC_GET_CHANNEL_CONTROLLER(_channel) \\r
+       CanIf_ConfigPtr->Arc_ChannelToControllerMap[_channel]\r
+\r
+/* Global configure */\r
+static const CanIf_ConfigType *CanIf_ConfigPtr;\r
+\r
+// Struct of controller private data.\r
+typedef struct\r
+{\r
+  CanIf_ControllerModeType  ControllerMode;\r
+  CanIf_ChannelGetModeType  PduMode;\r
+} CanIf_ChannelPrivateType;\r
+\r
+typedef struct\r
+{\r
+  boolean initRun;\r
+  CanIf_ChannelPrivateType channelData[CANIF_CHANNEL_CNT];\r
+} CanIf_GlobalType;\r
+\r
+void CanIf_PreInit_InitController(uint8 Controller, uint8 ConfigurationIndex);\r
+\r
+static CanIf_Arc_ChannelIdType CanIf_Arc_FindHrhChannel( Can_Arc_HRHType hrh )\r
+{\r
+  const CanIf_InitHohConfigType *hohConfig;\r
+  const CanIf_HrhConfigType *hrhConfig;\r
+\r
+  // foreach(hoh){ foreach(hrh in hoh) {} }\r
+  hohConfig = CanIf_ConfigPtr->InitConfig->CanIfHohConfigPtr;\r
+  hohConfig--;\r
+  do\r
+  {\r
+    hohConfig++;\r
+\r
+    hrhConfig = hohConfig->CanIfHrhConfig;\r
+    hrhConfig--;\r
+    do\r
+    {\r
+      hrhConfig++;\r
+      if (hrhConfig->CanIfHrhIdSymRef == hrh){\r
+        return hrhConfig->CanIfCanControllerHrhIdRef;\r
+      }\r
+    } while(!hrhConfig->CanIf_Arc_EOL);\r
+  } while(!hohConfig->CanIf_Arc_EOL);\r
+\r
+  DET_REPORTERROR(MODULE_ID_CANIF, 0, CANIF_RXINDICATION_ID, CANIF_E_PARAM_HRH);\r
+\r
+  return (CanIf_Arc_ChannelIdType) -1;\r
+}\r
+\r
+// Global config\r
+CanIf_GlobalType CanIf_Global;\r
+\r
+void CanIf_Init(const CanIf_ConfigType *ConfigPtr)\r
+{\r
+  VALIDATE_NO_RV(ConfigPtr != 0, CANIF_INIT_ID, CANIF_E_PARAM_POINTER); // Only PostBuild case supported\r
+\r
+  CanIf_ConfigPtr = ConfigPtr;\r
+\r
+  for (uint8 i = 0; i < CANIF_CHANNEL_CNT; i++)\r
+  {\r
+    CanIf_Global.channelData[i].ControllerMode = CANIF_CS_STOPPED;\r
+    CanIf_Global.channelData[i].PduMode = CANIF_GET_OFFLINE;\r
+    CanIf_PreInit_InitController(i, CanIf_ConfigPtr->Arc_ChannelDefaultConfIndex[i]);\r
+  }\r
+\r
+\r
+  CanIf_Global.initRun = TRUE;\r
+}\r
+\r
+\r
+\r
+\r
+//-------------------------------------------------------------------\r
+/*\r
+ * Controller :: CanIf_Arc_ChannelIdType (CanIf-specific id to abstract from Can driver/controllers)\r
+ * ConfigurationIndex :: CanIf_Arc_ConfigurationIndexType\r
+ */\r
+void CanIf_InitController(uint8 Controller, uint8 ConfigurationIndex)\r
+{\r
+  // We call this a CanIf channel. Hopefully makes it easier to follow.\r
+  CanIf_Arc_ChannelIdType channel = (CanIf_Arc_ChannelIdType) Controller;\r
+  CanIf_ControllerModeType mode;\r
+\r
+  VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_INIT_CONTROLLER_ID, CANIF_E_UNINIT );\r
+  VALIDATE_NO_RV(channel < CANIF_CHANNEL_CNT, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);\r
+  VALIDATE_NO_RV(ConfigurationIndex < CANIF_CHANNEL_CONFIGURATION_CNT, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_POINTER);\r
+\r
+  if (CanIf_GetControllerMode(channel, &mode) == E_OK)\r
+  {\r
+    if (mode == CANIF_CS_STARTED)\r
+    {\r
+      CanIf_SetControllerMode(channel, CANIF_CS_STOPPED); // CANIF092\r
+    }\r
+    else if (mode != CANIF_CS_STOPPED)\r
+    {\r
+      VALIDATE_NO_RV(FALSE, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER_MODE); // CANIF092\r
+    }\r
+  }\r
+  else\r
+  {\r
+    VALIDATE_NO_RV(FALSE, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER_MODE);\r
+  }\r
+\r
+  // CANIF293: ..Subsequently the CAN Interface calls the corresponding\r
+  //             CAN Driver initialization services.\r
+\r
+  // CANIF066: The CAN Interface has access to the CAN Driver configuration data. All\r
+  // public CAN Driver configuration data are described in [8] Specification of CAN Driver.\r
+\r
+  // Grab the configuration from the Can Controller\r
+  const Can_ControllerConfigType *canConfig;\r
+  const CanControllerIdType canControllerId = ARC_GET_CHANNEL_CONTROLLER(channel);\r
+\r
+  // Validate that the configuration at the index match the right channel\r
+  VALIDATE_NO_RV(CanIf_ConfigPtr->ControllerConfig[ConfigurationIndex].CanIfControllerIdRef == channel, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);\r
+\r
+  canConfig = CanIf_ConfigPtr->ControllerConfig[ConfigurationIndex].CanIfInitControllerRef;\r
+\r
+  // Validate that the CanIfControllerConfig points to configuration for the right Can Controller\r
+  VALIDATE_NO_RV(canConfig->CanControllerId == canControllerId, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);\r
+\r
+  Can_InitController(canControllerId, canConfig);\r
+\r
+  // Set mode to stopped\r
+  CanIf_SetControllerMode(channel, CANIF_CS_STOPPED);\r
+}\r
+\r
+void CanIf_PreInit_InitController(uint8 Controller, uint8 ConfigurationIndex){\r
+       // We call this a CanIf channel. Hopefully makes it easier to follow.\r
+       CanIf_Arc_ChannelIdType channel = (CanIf_Arc_ChannelIdType) Controller;\r
+\r
+       VALIDATE_NO_RV(channel < CANIF_CHANNEL_CNT, CANIF_INIT_ID, CANIF_E_PARAM_CONTROLLER);\r
+       VALIDATE_NO_RV(ConfigurationIndex < CANIF_CHANNEL_CONFIGURATION_CNT, CANIF_INIT_ID, CANIF_E_PARAM_POINTER);\r
+\r
+\r
+       const CanControllerIdType canControllerId = ARC_GET_CHANNEL_CONTROLLER(channel);\r
+       // Validate that the configuration at the index match the right channel\r
+       VALIDATE_NO_RV(CanIf_ConfigPtr->ControllerConfig[ConfigurationIndex].CanIfControllerIdRef == channel, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);\r
+       const Can_ControllerConfigType *canConfig = CanIf_ConfigPtr->ControllerConfig[ConfigurationIndex].CanIfInitControllerRef;\r
+       // Validate that the CanIfControllerConfig points to configuration for the right Can Controller\r
+       VALIDATE_NO_RV(canConfig->CanControllerId == canControllerId, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);\r
+\r
+       Can_InitController(canControllerId, canConfig);\r
+}\r
+\r
+//-------------------------------------------------------------------\r
+\r
+Std_ReturnType CanIf_SetControllerMode(uint8 Controller,\r
+    CanIf_ControllerModeType ControllerMode)\r
+{\r
+  // We call this a CanIf channel. Hopefully makes it easier to follow.\r
+  CanIf_Arc_ChannelIdType channel = (CanIf_Arc_ChannelIdType) Controller;\r
+\r
+\r
+  CanIf_ControllerModeType oldMode;\r
+\r
+  VALIDATE( CanIf_Global.initRun, CANIF_SET_CONTROLLER_MODE_ID, CANIF_E_UNINIT );\r
+  VALIDATE( channel < CANIF_CHANNEL_CNT, CANIF_SET_CONTROLLER_MODE_ID, CANIF_E_PARAM_CONTROLLER );\r
+\r
+  oldMode = CanIf_Global.channelData[channel].ControllerMode;\r
+\r
+  if (oldMode == CANIF_CS_UNINIT)\r
+  {\r
+    VALIDATE(FALSE, CANIF_SET_CONTROLLER_MODE_ID, CANIF_E_UNINIT); // See figure 32, 33\r
+    return E_NOT_OK;\r
+  }\r
+  CanControllerIdType canControllerId = ARC_GET_CHANNEL_CONTROLLER(Controller);\r
+  switch (ControllerMode)\r
+  {\r
+  case CANIF_CS_STARTED:   // Figure 32\r
+  {\r
+    switch (oldMode)\r
+    {\r
+      case CANIF_CS_SLEEP:\r
+        if (Can_SetControllerMode(canControllerId, CAN_T_STOP) == CAN_NOT_OK){\r
+          return E_NOT_OK;\r
+        }\r
+        CanIf_Global.channelData[channel].ControllerMode = CANIF_CS_STOPPED;\r
+        break;\r
+      default:\r
+        // Just fall through\r
+        break;\r
+    }\r
+\r
+    CanIf_SetPduMode(channel, CANIF_SET_ONLINE);\r
+    if (Can_SetControllerMode(canControllerId, CAN_T_START) == CAN_NOT_OK){\r
+      return E_NOT_OK;\r
+    }\r
+    CanIf_Global.channelData[channel].ControllerMode = CANIF_CS_STARTED;\r
+  }\r
+  break;\r
+\r
+  case CANIF_CS_SLEEP: // Figure 33\r
+  {\r
+    switch (oldMode) {\r
+      case CANIF_CS_STARTED:\r
+        if (Can_SetControllerMode(canControllerId, CAN_T_STOP) == CAN_NOT_OK){\r
+          return E_NOT_OK;\r
+        }\r
+        CanIf_Global.channelData[channel].ControllerMode = CANIF_CS_STOPPED;\r
+        break;\r
+      default:\r
+        // Just fall through for other cases\r
+        break;\r
+    }\r
+\r
+    if (Can_SetControllerMode(canControllerId, CAN_T_SLEEP) == CAN_NOT_OK){\r
+      return E_NOT_OK;\r
+    }\r
+    CanIf_Global.channelData[channel].ControllerMode = CANIF_CS_SLEEP;\r
+  }\r
+\r
+  case CANIF_CS_STOPPED:\r
+  {\r
+    switch (oldMode)\r
+    {\r
+      case CANIF_CS_SLEEP:\r
+        if (Can_SetControllerMode(canControllerId, CAN_T_WAKEUP) == CAN_NOT_OK){\r
+          return E_NOT_OK;\r
+        }\r
+        break;\r
+      default:\r
+        // Just fall through for other cases\r
+        break;\r
+    }\r
+\r
+    CanIf_SetPduMode(channel, CANIF_SET_OFFLINE);\r
+    if (Can_SetControllerMode(canControllerId, CAN_T_STOP) == CAN_NOT_OK){\r
+      return E_NOT_OK;\r
+    }\r
+    CanIf_Global.channelData[channel].ControllerMode = CANIF_CS_STOPPED;\r
+    break;\r
+  }\r
+\r
+  case CANIF_CS_UNINIT:\r
+    // Just fall through\r
+    break;\r
+  }\r
+  return E_OK;\r
+}\r
+\r
+//-------------------------------------------------------------------\r
+\r
+Std_ReturnType CanIf_GetControllerMode(uint8 Controller,\r
+    CanIf_ControllerModeType *ControllerModePtr)\r
+{\r
+  // We call this a CanIf channel. Hopefully makes it easier to follow.\r
+  CanIf_Arc_ChannelIdType channel = (CanIf_Arc_ChannelIdType) Controller;\r
+\r
+  VALIDATE(CanIf_Global.initRun, CANIF_GET_CONTROLLER_MODE_ID, CANIF_E_UNINIT );\r
+  VALIDATE(channel < CANIF_CHANNEL_CNT, CANIF_GET_CONTROLLER_MODE_ID, CANIF_E_PARAM_CONTROLLER );\r
+  VALIDATE(ControllerModePtr != NULL, CANIF_GET_CONTROLLER_MODE_ID, CANIF_E_PARAM_POINTER );\r
+\r
+  *ControllerModePtr = CanIf_Global.channelData[channel].ControllerMode;\r
+\r
+  return E_OK;\r
+}\r
+\r
+//-------------------------------------------------------------------\r
+/**\r
+ * Matches a Tx PDU id agaist the ones that are in the database.\r
+ *\r
+ * @returns Ptr a TxPdu\r
+ */\r
+#if ( CANIF_ARC_RUNTIME_PDU_CONFIGURATION == STD_ON )\r
+CanIf_TxPduConfigType * CanIf_FindTxPduEntry(PduIdType id)\r
+#else\r
+static const CanIf_TxPduConfigType * CanIf_FindTxPduEntry(PduIdType id)\r
+#endif\r
+{\r
+       if (id >= CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanTXPduIds) {\r
+               return NULL;\r
+       } else {\r
+               return &CanIf_ConfigPtr->InitConfig->CanIfTxPduConfigPtr[id];\r
+       }\r
+}\r
+\r
+
+#if ( CANIF_ARC_RUNTIME_PDU_CONFIGURATION == STD_ON )\r
+CanIf_RxPduConfigType * CanIf_FindRxPduEntry(PduIdType id) {\r
+       if (id >= CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanRxPduIds) {\r
+               return NULL;\r
+       } else {\r
+               return &CanIf_ConfigPtr->InitConfig->CanIfRxPduConfigPtr[id];\r
+       }\r
+}\r
+
+const CanIf_HrhConfigType* CanIf_Arc_GetReceiveHandler(CanIf_Arc_ChannelIdType Channel) {
+  const CanIf_InitHohConfigType *hohConfig;
   const CanIf_HrhConfigType *hrhConfig;
 
-  hrhConfig = CanIf_ConfigPtr->InitConfig->CanIfHohConfigPtr->CanIfHrhConfig;
-
-  hrhConfig--;
+  // foreach(hoh){ foreach(hrh in hoh) {} }
+  hohConfig = CanIf_ConfigPtr->InitConfig->CanIfHohConfigPtr;
+  hohConfig--;
   do
   {
-    hrhConfig++;
-    if (hrhConfig->CanIfHrhIdSymRef == hrh)
-      return hrhConfig->CanIfCanControllerHrhIdRef;
-  } while(!hrhConfig->CanIf_Arc_EOL);
-
-  DET_REPORTERROR(MODULE_ID_CANIF, 0, CANIF_RXINDICATION_ID, CANIF_E_PARAM_HRH);
+       hohConfig++;
 
-  return -1;
-}
-
-// Global config
-CanIf_GlobalType CanIf_Global;
-
-void CanIf_Init(const CanIf_ConfigType *ConfigPtr)
-{
-  VALIDATE_NO_RV(ConfigPtr != 0, CANIF_INIT_ID, CANIF_E_PARAM_POINTER); // Only PostBuild case supported
-
-  CanIf_ConfigPtr = ConfigPtr;
-
-  for (uint16 i = 0; i < CANIF_CHANNEL_CNT; i++)
-  {
-    CanIf_Global.channelData[i].ControllerMode = CANIF_CS_STOPPED;
-    CanIf_Global.channelData[i].PduMode = CANIF_GET_OFFLINE;
-  }
-
-  // NOTE!
-  // Do NOT initialise the Can Drivers and Tranceivers, see CANIF085
-
-  CanIf_Global.initRun = TRUE;
-}
-
-
-
-
-//-------------------------------------------------------------------
-/*
- * Controller :: CanIf_Arc_ChannelIdType (CanIf-specific id to abstract from Can driver/controllers)
- * ConfigurationIndex :: CanIf_Arc_ConfigurationIndexType
- *   /tojo
- */
-void CanIf_InitController(uint8 Controller, uint8 ConfigurationIndex)
-{
-  // We call this a CanIf channel. Hopefully makes it easier to follow.
-  CanIf_Arc_ChannelIdType channel = Controller;
-
-  VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_INIT_CONTROLLER_ID, CANIF_E_UNINIT );
-  VALIDATE_NO_RV(channel < CANIF_CHANNEL_CNT, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);
-  VALIDATE_NO_RV(ConfigurationIndex < CANIF_CHANNEL_CONFIGURATION_CNT, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_POINTER);
-
-#if (CANIF_DEV_ERROR_DETECT == STD_ON)
-  CanIf_ControllerModeType mode;
-
-  if (CanIf_GetControllerMode(channel, &mode) == E_OK)
-  {
-    VALIDATE_NO_RV((mode != CANIF_CS_UNINIT), CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER_MODE );
-  }
-  else
-  {
-    VALIDATE_NO_RV(FALSE, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER_MODE);
-  }
-#endif
-
-  if (CanIf_GetControllerMode(channel, &mode) == E_OK)
-  {
-    if (mode == CANIF_CS_STARTED)
-    {
-      CanIf_SetControllerMode(channel, CANIF_CS_STOPPED); // CANIF092
-    }
-    else if (mode != CANIF_CS_STOPPED)
+       hrhConfig = hohConfig->CanIfHrhConfig;
+    hrhConfig--;
+    do
     {
-      VALIDATE_NO_RV(FALSE, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER_MODE); // CANIF092
-   }
-  }
-
-  // CANIF293: ..Subsequently the CAN Interface calls the corresponding
-  //             CAN Driver initialization services.
-
-  // CANIF066: The CAN Interface has access to the CAN Driver configuration data. All
-  // public CAN Driver configuration data are described in [8] Specification of CAN Driver.
-
-  // Grab the configuration from the Can Controller
-  const Can_ControllerConfigType *canConfig;
-  const CanControllerIdType canControllerId = ARC_GET_CHANNEL_CONTROLLER(channel);
-
-  // Validate that the configuration at the index match the right channel
-  VALIDATE_NO_RV(CanIf_ConfigPtr->ControllerConfig[ConfigurationIndex].CanIfControllerIdRef == channel, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);
-
-  canConfig = CanIf_ConfigPtr->ControllerConfig[ConfigurationIndex].CanIfInitControllerRef;
-
-  // Validate that the CanIfControllerConfig points to configuration for the right Can Controller
-  VALIDATE_NO_RV(canConfig->CanControllerId == canControllerId, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);
-
-  Can_InitController(canControllerId, canConfig);
-
-  // Set mode to stopped
-  CanIf_SetControllerMode(channel, CANIF_CS_STOPPED);
-}
-
-//-------------------------------------------------------------------
-
-Std_ReturnType CanIf_SetControllerMode(uint8 Controller,
-    CanIf_ControllerModeType ControllerMode)
-{
-  // We call this a CanIf channel. Hopefully makes it easier to follow.
-  CanIf_Arc_ChannelIdType channel = Controller;
-
-
-  CanIf_ControllerModeType oldMode;
-
-  VALIDATE( CanIf_Global.initRun, CANIF_SET_CONTROLLER_MODE_ID, CANIF_E_UNINIT );
-  VALIDATE( channel < CANIF_CHANNEL_CNT, CANIF_SET_CONTROLLER_MODE_ID, CANIF_E_PARAM_CONTROLLER );
-
-  oldMode = CanIf_Global.channelData[channel].ControllerMode;
-
-  if (oldMode == CANIF_CS_UNINIT)
-  {
-    VALIDATE(FALSE, CANIF_SET_CONTROLLER_MODE_ID, CANIF_E_UNINIT); // See figure 32, 33
-    return E_NOT_OK;
-  }
-  CanControllerIdType canControllerId = ARC_GET_CHANNEL_CONTROLLER(Controller);
-  switch (ControllerMode)
-  {
-  case CANIF_CS_STARTED:   // Figure 32
-  {
-    switch (oldMode)
-    {
-      case CANIF_CS_SLEEP:
-        if (Can_SetControllerMode(canControllerId, CAN_T_STOP) == CAN_NOT_OK)
-          return E_NOT_OK;
-        CanIf_Global.channelData[channel].ControllerMode = CANIF_CS_STOPPED;
-        break;
-      default:
-        // Just fall through
-        break;
-    }
-
-    CanIf_SetPduMode(channel, CANIF_SET_ONLINE);
-    if (Can_SetControllerMode(canControllerId, CAN_T_START) == CAN_NOT_OK)
-      return E_NOT_OK;
-    CanIf_Global.channelData[channel].ControllerMode = CANIF_CS_STARTED;
-  }
-  break;
-
-  case CANIF_CS_SLEEP: // Figure 33
-  {
-    switch (oldMode) {
-      case CANIF_CS_STARTED:
-        if (Can_SetControllerMode(canControllerId, CAN_T_STOP) == CAN_NOT_OK)
-          return E_NOT_OK;
-        CanIf_Global.channelData[channel].ControllerMode = CANIF_CS_STOPPED;
-        break;
-      default:
-        // Just fall through for other cases
-        break;
-    }
-
-    if (Can_SetControllerMode(canControllerId, CAN_T_SLEEP) == CAN_NOT_OK)
-      return E_NOT_OK;
-    CanIf_Global.channelData[channel].ControllerMode = CANIF_CS_SLEEP;
-  }
-
-  case CANIF_CS_STOPPED:
-  {
-    switch (oldMode)
-    {
-      case CANIF_CS_SLEEP:
-        if (Can_SetControllerMode(canControllerId, CAN_T_WAKEUP) == CAN_NOT_OK)
-          return E_NOT_OK;
-        break;
-      default:
-        // Just fall through for other cases
-        break;
-    }
-
-    CanIf_SetPduMode(channel, CANIF_SET_OFFLINE);
-    if (Can_SetControllerMode(canControllerId, CAN_T_STOP) == CAN_NOT_OK)
-      return E_NOT_OK;
-    CanIf_Global.channelData[channel].ControllerMode = CANIF_CS_STOPPED;
-  }
-
-  case CANIF_CS_UNINIT:
-    // Just fall through
-    break;
-  }
-  return E_OK;
-}
-
-//-------------------------------------------------------------------
-
-Std_ReturnType CanIf_GetControllerMode(uint8 Controller,
-    CanIf_ControllerModeType *ControllerModePtr)
-{
-  // We call this a CanIf channel. Hopefully makes it easier to follow.
-  CanIf_Arc_ChannelIdType channel = Controller;
-
-  VALIDATE(CanIf_Global.initRun, CANIF_GET_CONTROLLER_MODE_ID, CANIF_E_UNINIT );
-  VALIDATE(channel < CANIF_CHANNEL_CNT, CANIF_GET_CONTROLLER_MODE_ID, CANIF_E_PARAM_CONTROLLER );
-  VALIDATE(ControllerModePtr != NULL, CANIF_GET_CONTROLLER_MODE_ID, CANIF_E_PARAM_POINTER );
-
-  *ControllerModePtr = CanIf_Global.channelData[channel].ControllerMode;
-
-  return E_OK;
-}
-
-//-------------------------------------------------------------------
-/**
- * Matches a Tx PDU id agaist the ones that are in the database.
- *
- * @returns Ptr a TxPdu
- */
-static const CanIf_TxPduConfigType * CanIf_FindTxPduEntry(PduIdType id)
-{
-       if (id >= CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanTXPduIds) {
-               return NULL;
-       } else {
-               return &CanIf_ConfigPtr->InitConfig->CanIfTxPduConfigPtr[id];
-       }
-/*
-  for (uint16 i = 0; i < CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanTXPduIds; i++)
-  {
-    if (entry->CanIfTxPduId == id)
-    {
-      return entry;
-    }
-    entry++;
-  }
-
-  return 0;
-  */
-}
-
-//-------------------------------------------------------------------
-
-Std_ReturnType CanIf_Transmit(PduIdType CanTxPduId,
-    const PduInfoType *PduInfoPtr)
-{
-  Can_PduType canPdu;
-  const CanIf_TxPduConfigType *txEntry;
-  CanIf_ControllerModeType csMode;
-  CanIf_ChannelGetModeType pduMode;
-
-  VALIDATE(CanIf_Global.initRun, CANIF_TRANSMIT_ID, CANIF_E_UNINIT );
-  VALIDATE((PduInfoPtr != 0), CANIF_TRANSMIT_ID, CANIF_E_PARAM_POINTER );
-
-  // Get the controller from L-PDU handle
-  txEntry = CanIf_FindTxPduEntry(CanTxPduId);
-
-  if (txEntry == 0)
-  {
-    VALIDATE(FALSE, CANIF_TRANSMIT_ID, CANIF_E_INVALID_TXPDUID);
-    return E_NOT_OK;
-  }
-
-  CanIf_Arc_ChannelIdType channel = txEntry->CanIfCanTxPduHthRef->CanIfCanControllerIdRef;
-
-  // Get and verify the controller mode
-  if (CanIf_GetControllerMode(channel, &csMode) == E_NOT_OK)
-    return E_NOT_OK;
-
-  if (csMode != CANIF_CS_STARTED)  // CANIF_161
-    return E_NOT_OK;
-
-  // Get and verify the PDU channel mode control
-  if (CanIf_GetPduMode(channel, &pduMode) == E_NOT_OK)
-    return E_NOT_OK;
-
-  if ((pduMode != CANIF_GET_TX_ONLINE) && (pduMode != CANIF_GET_ONLINE))
-    return E_NOT_OK;
-
-  canPdu.id = txEntry->CanIfCanTxPduIdCanId;
-
-  canPdu.length = PduInfoPtr->SduLength;
-  canPdu.sdu = PduInfoPtr->SduDataPtr;
-  canPdu.swPduHandle = CanTxPduId;
-
-  Can_ReturnType rVal = Can_Write(txEntry->CanIfCanTxPduHthRef->CanIfHthIdSymRef, &canPdu);
-
-  if (rVal == CAN_NOT_OK)
-    return E_NOT_OK;
-
-  if (rVal == CAN_BUSY)  // CANIF 082, CANIF 161
-  {
-    // Tx buffering not supported so just return.
-    return E_NOT_OK;
-  }
-
-  return E_OK;
-}
-
-//-------------------------------------------------------------------
-
-#if ( CANIF_READRXPDU_DATA_API == STD_ON )
-Std_ReturnType CanIf_ReadRxPduData(PduIdType CanRxPduId,
-    PduInfoType *PduInfoPtr)
-{
-  VALIDATE(FALSE, CANIF_READTXPDUDATA_ID, CANIF_E_NOK_NOSUPPORT);
-  VALIDATE(CanIf_Global.initRun == STD_ON, CANIF_READTXPDUDATA_ID, CANIF_E_UNINIT );
-  VALIDATE(PduInfoPtr != 0, CANIF_READTXPDUDATA_ID, CANIF_E_PARAM_POINTER );
+      hrhConfig++;
+      if (hrhConfig->CanIfCanControllerHrhIdRef == Channel)
+        return hrhConfig;
+       } while(!hrhConfig->CanIf_Arc_EOL);
 
-  // This function is not supported
+  } while(!hohConfig->CanIf_Arc_EOL);
 
-  return E_NOT_OK;
-}
-#endif
-
-//-------------------------------------------------------------------
-
-#if ( CANIF_READTXPDU_NOTIFY_STATUS_API == STD_ON )
-CanIf_NotifStatusType CanIf_ReadTxNotifStatus(PduIdType CanTxPduId)
-{
-  const CanIf_TxPduConfigType *txEntry;
-  VALIDATE(FALSE, CANIF_READTXNOTIFSTATUS_ID, CANIF_E_NOK_NOSUPPORT);
-  VALIDATE(CanIf_Global.initRun, CANIF_READTXNOTIFSTATUS_ID, CANIF_E_UNINIT );
-
-  // Get the controller from L-PDU handle
-  txEntry = CanIf_FindTxPduEntry(CanTxPduId);
-
-  if (txEntry == 0)
-  {
-    VALIDATE(FALSE, CANIF_READTXNOTIFSTATUS_ID, CANIF_E_INVALID_TXPDUID);
-    return CANIF_NO_NOTIFICATION;
-  }
+  DET_REPORTERROR(MODULE_ID_CANIF, 0, 0xFF, CANIF_E_PARAM_HRH);
 
-  if (txEntry->CanIfReadTxPduNotifyStatus == FALSE)
-  {
-    VALIDATE(FALSE, CANIF_READTXNOTIFSTATUS_ID, CANIF_E_INVALID_TXPDUID);
-    return CANIF_NO_NOTIFICATION;
-  }
-
-  // This function is not supported
-
-  return CANIF_NO_NOTIFICATION;
+  return NULL;
 }
-#endif
 
-//-------------------------------------------------------------------
+const CanIf_HthConfigType* CanIf_Arc_GetTransmitHandler(CanIf_Arc_ChannelIdType Channel) {
+  const CanIf_InitHohConfigType *hohConfig;
+  const CanIf_HthConfigType *hthConfig;
 
-#if ( CANIF_READRXPDU_NOTIFY_STATUS_API == STD_ON )
-CanIf_NotifStatusType CanIf_ReadRxNotifStatus(PduIdType CanRxPduId)
-{
-  VALIDATE(FALSE, CANIF_READRXNOTIFSTATUS_ID, CANIF_E_NOK_NOSUPPORT);
-  VALIDATE(CanIf_Global.initRun, CANIF_READRXNOTIFSTATUS_ID, CANIF_E_UNINIT );
-
-  return CANIF_NO_NOTIFICATION;
-}
-#endif
-
-//-------------------------------------------------------------------
-
-Std_ReturnType CanIf_SetPduMode(uint8 Controller,
-    CanIf_ChannelSetModeType PduModeRequest)
-{
-  // We call this a CanIf channel. Hopefully makes it easier to follow.
-  CanIf_Arc_ChannelIdType channel = Controller;
-
-  VALIDATE( CanIf_Global.initRun, CANIF_SETPDUMODE_ID, CANIF_E_UNINIT );
-  VALIDATE( channel < CANIF_CHANNEL_CNT, CANIF_SETPDUMODE_ID, CANIF_E_PARAM_CONTROLLER );
-
-  CanIf_ChannelGetModeType oldMode = CanIf_Global.channelData[channel].PduMode;
-
-  switch(PduModeRequest)
-  {
-  case CANIF_SET_OFFLINE:
-    CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE;
-    break;
-  case CANIF_SET_RX_OFFLINE:
-    if (oldMode == CANIF_GET_RX_ONLINE)
-      CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE;
-    else if (oldMode == CANIF_GET_ONLINE)
-      CanIf_Global.channelData[channel].PduMode = CANIF_GET_TX_ONLINE;
-    else if (oldMode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE)
-      CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE;
-
-    // Other oldmodes don't care
-    break;
-  case CANIF_SET_RX_ONLINE:
-    if (oldMode == CANIF_GET_OFFLINE)
-      CanIf_Global.channelData[channel].PduMode = CANIF_GET_RX_ONLINE;
-    else if (oldMode == CANIF_GET_TX_ONLINE)
-      CanIf_Global.channelData[channel].PduMode = CANIF_GET_ONLINE;
-    else if (oldMode == CANIF_GET_OFFLINE_ACTIVE)
-      CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE;
-
-    // Other oldmodes don't care
-    break;
-  case CANIF_SET_TX_OFFLINE:
-    if (oldMode == CANIF_GET_TX_ONLINE)
-      CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE;
-    else if (oldMode == CANIF_GET_ONLINE)
-      CanIf_Global.channelData[channel].PduMode = CANIF_GET_RX_ONLINE;
-    else if (oldMode == CANIF_GET_OFFLINE_ACTIVE)
-      CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE;
-    else if (oldMode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE)
-      CanIf_Global.channelData[channel].PduMode = CANIF_GET_RX_ONLINE;
-
-    // Other oldmodes don't care
-    break;
-  case CANIF_SET_TX_ONLINE:
-    if (oldMode == CANIF_GET_OFFLINE)
-      CanIf_Global.channelData[channel].PduMode = CANIF_GET_TX_ONLINE;
-    else if (oldMode == CANIF_GET_RX_ONLINE)
-      CanIf_Global.channelData[channel].PduMode = CANIF_GET_ONLINE;
-    else if (oldMode == CANIF_GET_OFFLINE_ACTIVE)
-      CanIf_Global.channelData[channel].PduMode = CANIF_GET_TX_ONLINE;
-    else if (oldMode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE)
-      CanIf_Global.channelData[channel].PduMode = CANIF_GET_ONLINE;
-
-    // Other oldmodes don't care
-    break;
-  case CANIF_SET_ONLINE:
-    CanIf_Global.channelData[channel].PduMode = CANIF_GET_ONLINE;
-    break;
-
-  case CANIF_SET_TX_OFFLINE_ACTIVE:
-    if (oldMode == CANIF_GET_OFFLINE)
-      CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE;
-    else if (oldMode == CANIF_GET_RX_ONLINE)
-      CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE;
-    else if (oldMode == CANIF_GET_TX_ONLINE)
-      CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE;
-    else if (oldMode == CANIF_GET_ONLINE)
-      CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE;
-
-    // Other oldmodes don't care
-    break;
-  }
-
-  return E_OK;
-}
-
-//-------------------------------------------------------------------
-
-Std_ReturnType CanIf_GetPduMode(uint8 Controller,
-    CanIf_ChannelGetModeType *PduModePtr)
-{
-  // We call this a CanIf channel. Hopefully makes it easier to follow.
-  CanIf_Arc_ChannelIdType channel = Controller;
-
-  VALIDATE( CanIf_Global.initRun, CANIF_GETPDUMODE_ID, CANIF_E_UNINIT );
-  VALIDATE( channel < CANIF_CHANNEL_CNT, CANIF_GETPDUMODE_ID, CANIF_E_PARAM_CONTROLLER );
-
-  *PduModePtr = CanIf_Global.channelData[channel].PduMode;
-
-  return E_OK;
-}
-
-#if ( CANIF_SETDYNAMICTXID_API == STD_ON )
-void CanIf_SetDynamicTxId(PduIdType CanTxPduId, Can_IdType CanId)
-{
-  const CanIf_TxPduConfigType *txEntry;
-  VALIDATE(FALSE, CANIF_SETDYNAMICTX_ID, CANIF_E_NOK_NOSUPPORT);
-  VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_SETDYNAMICTX_ID, CANIF_E_UNINIT );
-
-  // Get the controller from L-PDU handle
-  txEntry = CanIf_FindTxPduEntry(CanTxPduId);
-
-  if (txEntry == 0)
-  {
-    VALIDATE_NO_RV(FALSE, CANIF_SETDYNAMICTX_ID, CANIF_E_INVALID_TXPDUID);
-    return;
-  }
-
-  // Check that this is a dymanic PDU
-  if (txEntry->CanIfCanTxPduType != ARC_PDU_TYPE_DYNAMIC)
-  {
-    VALIDATE_NO_RV(FALSE, CANIF_SETDYNAMICTX_ID, CANIF_E_INVALID_TXPDUID);
-    return;
-  }
-
-  // Check that this is an extended or standard id
-  if (((CanId & 0x80000000) && (txEntry->CanIfTxPduIdCanIdType == ARC_CAN_ID_TYPE_29)) ||
-      (((CanId & 0x80000000) == 0) && (txEntry->CanIfTxPduIdCanIdType == ARC_CAN_ID_TYPE_11)))
-  {
-    // Update the CanID
-    //txEntry->CanIfCanTxPduIdCanId = CanId;  // TODO How do we fix this from a const pointer
-
-    // NOT SUPPORTED
-  }
-  else
-  {
-    // Inavlid Canid to configuration
-    VALIDATE_NO_RV(FALSE, CANIF_SETDYNAMICTX_ID, CANIF_E_PARAM_CANID);
-  }
-}
-#endif
-
-#if ( CANIF_TRANSCEIVER_API == STD_ON )
-Std_ReturnType CanIf_SetTransceiverMode(uint8 Transceiver,
-    CanIf_TransceiverModeType TransceiverMode)
-{
-  VALIDATE(FALSE, CANIF_SET_TRANSCEIVERMODE_ID, CANIF_E_NOK_NOSUPPORT);
-// Not supported
-
-  return E_NOT_OK;
-}
-
-Std_ReturnType CanIf_GetTransceiverMode(uint8 Transceiver,
-    CanIf_TransceiverModeType *TransceiverModePtr)
-{
-  VALIDATE(FALSE, CANIF_GET_TRANSCEIVERMODE_ID, CANIF_E_NOK_NOSUPPORT);
-  // Not supported
-
-  return E_NOT_OK;
-}
-
-Std_ReturnType CanIf_GetTrcvWakeupReason(uint8 Transceiver,
-    CanIf_TrcvWakeupReasonType *TrcvWuReasonPtr)
-{
-  VALIDATE(FALSE, CANIF_GET_TRCVMODEREASON_ID, CANIF_E_NOK_NOSUPPORT);
-  // Not supported
-
-  return E_NOT_OK;
-}
-
-Std_ReturnType CanIf_SetTransceiverWakeupMode(uint8 Transceiver,
-    CanIf_TrcvWakeupModeType *TrcvWakeupMode)
-{
-  VALIDATE(FALSE, CANIF_SET_TRANSCEIVERWAKEMODE_ID, CANIF_E_NOK_NOSUPPORT);
-  // Not supported
-
-  return E_NOT_OK;
-}
-#endif
-
-#if ( CANIF_WAKEUP_EVENT_API == STD_ON )
-Std_ReturnType CanIf_CheckWakeup(EcuM_WakeupSourceType WakeupSource)
-{
-  VALIDATE(FALSE, CANIF_CHECKWAKEUP_ID, CANIF_E_NOK_NOSUPPORT);
-  // Not supported
-
-  return E_NOT_OK;
-}
-
-Std_ReturnType CanIf_CheckValidation(EcuM_WakeupSourceType WakeupSource)
-{
-  VALIDATE(FALSE, CANIF_CHECKVALIDATION_ID, CANIF_E_NOK_NOSUPPORT);
-  // Not supported
-
-  return E_NOT_OK;
-}
-#endif
-
-/*
- * Callback interface from driver
- */
-void CanIf_TxConfirmation(PduIdType canTxPduId)
-{
-  VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_TXCONFIRMATION_ID, CANIF_E_UNINIT)
-  VALIDATE_NO_RV(canTxPduId < CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanTXPduIds, CANIF_TXCONFIRMATION_ID, CANIF_E_PARAM_LPDU);
-
-  const CanIf_TxPduConfigType* entry =
-    &CanIf_ConfigPtr->InitConfig->CanIfTxPduConfigPtr[canTxPduId];
-
-  /* Find the CAN id in the TxPduList */
-  /*
-  for (uint16 i = 0; i < CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanTXPduIds; i++)
-  {
-    if (entry->CanIfTxPduId == canTxPduId)
-    {
-    */
-      if (entry->CanIfUserTxConfirmation != NULL)
-      {
-        CanIf_ChannelGetModeType mode;
-        CanIf_GetPduMode(entry->CanIfCanTxPduHthRef->CanIfCanControllerIdRef, &mode);
-        if ((mode == CANIF_GET_TX_ONLINE) || (mode == CANIF_GET_ONLINE)
-            || (mode == CANIF_GET_OFFLINE_ACTIVE) || (mode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE) )
-        {
-          entry->CanIfUserTxConfirmation(canTxPduId);  /* CANIF053 */
-        }
-      }
-      return;
-      /*
-    }
-
-    entry++;
-  }
-  */
-  // Did not find the PDU, something is wrong
-
-}
-
-void CanIf_RxIndication(uint8 Hrh, Can_IdType CanId, uint8 CanDlc,
-              const uint8 *CanSduPtr)
-{
-  VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_RXINDICATION_ID, CANIF_E_UNINIT);
-  VALIDATE_NO_RV(CanSduPtr != NULL, CANIF_RXINDICATION_ID, CANIF_E_PARAM_POINTER);
-
-  /* Check PDU mode before continue processing */
-  CanIf_ChannelGetModeType mode;
-  CanIf_Arc_ChannelIdType channel = CanIf_Arc_FindHrhChannel(Hrh);
-  if (channel == -1)  // Invalid HRH
-  {
-    return;
-  }
-
-  if (CanIf_GetPduMode(channel, &mode) == E_OK)
-  {
-    if (mode == CANIF_GET_OFFLINE || mode == CANIF_GET_TX_ONLINE ||
-        mode == CANIF_GET_OFFLINE_ACTIVE)
-    {
-      // Receiver path is disabled so just drop it
-      return;
-    }
-  }
-  else
+  // foreach(hoh){ foreach(hrh in hoh) {} }
+  hohConfig = CanIf_ConfigPtr->InitConfig->CanIfHohConfigPtr;
+  hohConfig--;
+  do
   {
-    return;  // No mode so just return
-  }
-
-  const CanIf_RxPduConfigType *entry = CanIf_ConfigPtr->InitConfig->CanIfRxPduConfigPtr;
+       hohConfig++;
 
-  /* Find the CAN id in the RxPduList */
-  for (uint16 i = 0; i < CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanRxPduIds; i++)
-  {
-    if (entry->CanIfCanRxPduHrhRef->CanIfHrhIdSymRef == Hrh)
+       hthConfig = hohConfig->CanIfHthConfig;
+       hthConfig--;
+    do
     {
-      // Software filtering
-      if (entry->CanIfCanRxPduHrhRef->CanIfHrhType == CAN_ARC_HANDLE_TYPE_BASIC)
-      {
-        if (entry->CanIfCanRxPduHrhRef->CanIfSoftwareFilterHrh)
-        {
-          if (entry->CanIfSoftwareFilterType == CANIF_SOFTFILTER_TYPE_MASK)
-          {
-            if ((CanId & entry->CanIfCanRxPduCanIdMask ) ==
-                ( entry->CanIfCanRxPduCanId & entry->CanIfCanRxPduCanIdMask))
-            {
-              // We found a pdu so call higher layers
-            }
-            else
-            {
-              entry++;
-              continue; // Not a supported filter type, so just drop the frame
-            }
-          }
-          else
-          {
-            DET_REPORTERROR(MODULE_ID_CAN, 0, CANIF_RXINDICATION_ID, CANIF_E_PARAM_HRH);
-            continue; // Not a supported filter type, so just drop the frame
-          }
-        }
-      }
-
-#if (CANIF_DLC_CHECK == STD_ON)
-      if (CanDlc < entry->CanIfCanRxPduDlc)
-      {
-        VALIDATE_NO_RV(FALSE, CANIF_RXINDICATION_ID, CANIF_E_PARAM_DLC);
-        return;
-      }
-#endif
-
-      switch (entry->CanIfRxUserType)
-      {
-        case CANIF_USER_TYPE_CAN_SPECIAL:
-        {
-            ((CanIf_FuncTypeCanSpecial) (entry->CanIfUserRxIndication))(entry->CanIfCanRxPduId,
-                                          CanSduPtr, CanDlc, CanId);
-            return;
-        }
-        break;
-
-        case CANIF_USER_TYPE_CAN_NM:
-        case CANIF_USER_TYPE_CAN_PDUR:
-            // Send Can frame to PDU router
-            PduR_CanIfRxIndication(entry->CanIfCanRxPduId,CanSduPtr);
-            return;
-            break;
-
-        case CANIF_USER_TYPE_CAN_TP:
-          // Send Can frame to CAN TP
-#if defined(USE_CANTP)
-            {
-                   PduInfoType CanTpRxPdu;
-                   CanTpRxPdu.SduLength = CanDlc;
-                   CanTpRxPdu.SduDataPtr = (uint8 *)CanSduPtr;
-                CanTp_RxIndication(entry->CanIfCanRxPduId, &CanTpRxPdu);
-            }
-            return;
-#endif
-            break;
-      }
-    }
-
-    entry++;
-  }
-
-  // Did not find the PDU, something is wrong
-  VALIDATE_NO_RV(FALSE, CANIF_RXINDICATION_ID, CANIF_E_PARAM_LPDU);
-}
-
-#if ( CANIF_TRANSMIT_CANCELLATION == STD_ON )
-void CanIf_CancelTxConfirmation(const Can_PduType *PduInfoPtr)
-{
-  VALIDATE(FALSE, CANIF_CANCELTXCONFIRMATION_ID, CANIF_E_NOK_NOSUPPORT);
-  VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_CANCELTXCONFIRMATION_ID, CANIF_E_UNINIT);
-  VALIDATE_NO_RV(PduInfoPtr != NULL, CANIF_RXINDICATION_ID, CANIF_E_PARAM_POINTER);
+       hthConfig++;
+      if (hthConfig->CanIfCanControllerIdRef == Channel)
+        return hthConfig;
+       } while(!hthConfig->CanIf_Arc_EOL);
 
-  const CanIf_TxPduConfigType *entry =
-    CanIf_ConfigPtr->InitConfig->CanIfTxPduConfigPtr;
+  } while(!hohConfig->CanIf_Arc_EOL);
 
-  // Not supported
+  DET_REPORTERROR(MODULE_ID_CANIF, 0, 0xFF, CANIF_E_PARAM_HTH);
 
-  // Did not find the PDU, something is wrong
-  VALIDATE_NO_RV(FALSE, CANIF_TXCONFIRMATION_ID, CANIF_E_PARAM_LPDU);
+  return NULL;
 }
 #endif
 
-void CanIf_ControllerBusOff(uint8 Controller)
+//-------------------------------------------------------------------\r
+\r
+Std_ReturnType CanIf_Transmit(PduIdType CanTxPduId,\r
+    const PduInfoType *PduInfoPtr)\r
+{\r
+  Can_PduType canPdu;\r
+  const CanIf_TxPduConfigType *txEntry;\r
+  CanIf_ControllerModeType csMode;\r
+  CanIf_ChannelGetModeType pduMode;\r
+\r
+  VALIDATE(CanIf_Global.initRun, CANIF_TRANSMIT_ID, CANIF_E_UNINIT );\r
+  VALIDATE((PduInfoPtr != 0), CANIF_TRANSMIT_ID, CANIF_E_PARAM_POINTER );\r
+\r
+  // Get the controller from L-PDU handle\r
+  txEntry = CanIf_FindTxPduEntry(CanTxPduId);\r
+\r
+  if (txEntry == 0)\r
+  {\r
+    VALIDATE(FALSE, CANIF_TRANSMIT_ID, CANIF_E_INVALID_TXPDUID);\r
+    return E_NOT_OK;\r
+  }\r
+\r
+  CanIf_Arc_ChannelIdType channel = txEntry->CanIfCanTxPduHthRef->CanIfCanControllerIdRef;\r
+\r
+  // Get and verify the controller mode\r
+  if (CanIf_GetControllerMode(channel, &csMode) == E_NOT_OK){\r
+    return E_NOT_OK;\r
+  }\r
+\r
+  if (csMode != CANIF_CS_STARTED){  // CANIF_161\r
+    return E_NOT_OK;\r
+  }\r
+\r
+  // Get and verify the PDU channel mode control\r
+  if (CanIf_GetPduMode(channel, &pduMode) == E_NOT_OK){\r
+    return E_NOT_OK;\r
+  }\r
+\r
+  if ((pduMode != CANIF_GET_TX_ONLINE) && (pduMode != CANIF_GET_ONLINE)){\r
+    return E_NOT_OK;\r
+  }\r
+\r
+  canPdu.id = txEntry->CanIfCanTxPduIdCanId;\r
+\r
+  canPdu.length = PduInfoPtr->SduLength;\r
+  canPdu.sdu = PduInfoPtr->SduDataPtr;\r
+  canPdu.swPduHandle = CanTxPduId;             // e.g. ARC_PDUR_CANIF\r
+\r
+  Can_ReturnType rVal = Can_Write(txEntry->CanIfCanTxPduHthRef->CanIfHthIdSymRef, &canPdu);\r
+\r
+  if (rVal == CAN_NOT_OK){\r
+    return E_NOT_OK;\r
+  }\r
+\r
+  if (rVal == CAN_BUSY)  // CANIF 082, CANIF 161\r
+  {\r
+    // Tx buffering not supported so just return.\r
+    return E_NOT_OK;\r
+  }\r
+\r
+  return E_OK;\r
+}\r
+\r
+//-------------------------------------------------------------------\r
+\r
+#if ( CANIF_READRXPDU_DATA_API == STD_ON )\r
+Std_ReturnType CanIf_ReadRxPduData(PduIdType CanRxPduId,\r
+    PduInfoType *PduInfoPtr)\r
+{\r
+  VALIDATE(FALSE, CANIF_READTXPDUDATA_ID, CANIF_E_NOK_NOSUPPORT);\r
+  VALIDATE(CanIf_Global.initRun == STD_ON, CANIF_READTXPDUDATA_ID, CANIF_E_UNINIT );\r
+  VALIDATE(PduInfoPtr != 0, CANIF_READTXPDUDATA_ID, CANIF_E_PARAM_POINTER );\r
+\r
+  // This function is not supported\r
+\r
+  return E_NOT_OK;\r
+}\r
+#endif\r
+\r
+//-------------------------------------------------------------------\r
+\r
+#if ( CANIF_READTXPDU_NOTIFY_STATUS_API == STD_ON )\r
+CanIf_NotifStatusType CanIf_ReadTxNotifStatus(PduIdType CanTxPduId)\r
+{\r
+  const CanIf_TxPduConfigType *txEntry;\r
+  VALIDATE(FALSE, CANIF_READTXNOTIFSTATUS_ID, CANIF_E_NOK_NOSUPPORT);\r
+  VALIDATE(CanIf_Global.initRun, CANIF_READTXNOTIFSTATUS_ID, CANIF_E_UNINIT );\r
+\r
+  // Get the controller from L-PDU handle\r
+  txEntry = CanIf_FindTxPduEntry(CanTxPduId);\r
+\r
+  if (txEntry == 0)\r
+  {\r
+    VALIDATE(FALSE, CANIF_READTXNOTIFSTATUS_ID, CANIF_E_INVALID_TXPDUID);\r
+    return CANIF_NO_NOTIFICATION;\r
+  }\r
+\r
+  if (txEntry->CanIfReadTxPduNotifyStatus == FALSE)\r
+  {\r
+    VALIDATE(FALSE, CANIF_READTXNOTIFSTATUS_ID, CANIF_E_INVALID_TXPDUID);\r
+    return CANIF_NO_NOTIFICATION;\r
+  }\r
+\r
+  // This function is not supported\r
+\r
+  return CANIF_NO_NOTIFICATION;\r
+}\r
+#endif\r
+\r
+//-------------------------------------------------------------------\r
+\r
+#if ( CANIF_READRXPDU_NOTIFY_STATUS_API == STD_ON )\r
+CanIf_NotifStatusType CanIf_ReadRxNotifStatus(PduIdType CanRxPduId)\r
+{\r
+  VALIDATE(FALSE, CANIF_READRXNOTIFSTATUS_ID, CANIF_E_NOK_NOSUPPORT);\r
+  VALIDATE(CanIf_Global.initRun, CANIF_READRXNOTIFSTATUS_ID, CANIF_E_UNINIT );\r
+\r
+  return CANIF_NO_NOTIFICATION;\r
+}\r
+#endif\r
+\r
+//-------------------------------------------------------------------\r
+\r
+Std_ReturnType CanIf_SetPduMode(uint8 Controller,\r
+    CanIf_ChannelSetModeType PduModeRequest)\r
+{\r
+  // We call this a CanIf channel. Hopefully makes it easier to follow.\r
+  CanIf_Arc_ChannelIdType channel = (CanIf_Arc_ChannelIdType) Controller;\r
+\r
+  VALIDATE( CanIf_Global.initRun, CANIF_SETPDUMODE_ID, CANIF_E_UNINIT );\r
+  VALIDATE( channel < CANIF_CHANNEL_CNT, CANIF_SETPDUMODE_ID, CANIF_E_PARAM_CONTROLLER );\r
+\r
+  CanIf_ChannelGetModeType oldMode = CanIf_Global.channelData[channel].PduMode;\r
+\r
+  switch(PduModeRequest)\r
+  {\r
+  case CANIF_SET_OFFLINE:\r
+    CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE;\r
+    break;\r
+  case CANIF_SET_RX_OFFLINE:\r
+    if (oldMode == CANIF_GET_RX_ONLINE){\r
+      CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE;\r
+    } else if (oldMode == CANIF_GET_ONLINE){\r
+      CanIf_Global.channelData[channel].PduMode = CANIF_GET_TX_ONLINE;\r
+    } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE){\r
+      CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE;\r
+    }\r
+\r
+    // Other oldmodes don't care\r
+    break;\r
+  case CANIF_SET_RX_ONLINE:\r
+    if (oldMode == CANIF_GET_OFFLINE){\r
+      CanIf_Global.channelData[channel].PduMode = CANIF_GET_RX_ONLINE;\r
+    } else if (oldMode == CANIF_GET_TX_ONLINE) {\r
+      CanIf_Global.channelData[channel].PduMode = CANIF_GET_ONLINE;\r
+    } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE){\r
+      CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE;\r
+    }\r
+\r
+    // Other oldmodes don't care\r
+    break;\r
+  case CANIF_SET_TX_OFFLINE:\r
+    if (oldMode == CANIF_GET_TX_ONLINE){\r
+      CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE;\r
+    } else if (oldMode == CANIF_GET_ONLINE) {\r
+      CanIf_Global.channelData[channel].PduMode = CANIF_GET_RX_ONLINE;\r
+    } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE) {\r
+      CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE;\r
+    } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE) {\r
+      CanIf_Global.channelData[channel].PduMode = CANIF_GET_RX_ONLINE;\r
+    }\r
+\r
+    // Other oldmodes don't care\r
+    break;\r
+  case CANIF_SET_TX_ONLINE:\r
+    if (oldMode == CANIF_GET_OFFLINE){\r
+      CanIf_Global.channelData[channel].PduMode = CANIF_GET_TX_ONLINE;\r
+    } else if (oldMode == CANIF_GET_RX_ONLINE) {\r
+      CanIf_Global.channelData[channel].PduMode = CANIF_GET_ONLINE;\r
+    } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE) {\r
+      CanIf_Global.channelData[channel].PduMode = CANIF_GET_TX_ONLINE;\r
+    } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE) {\r
+      CanIf_Global.channelData[channel].PduMode = CANIF_GET_ONLINE;\r
+    }\r
+\r
+    // Other oldmodes don't care\r
+    break;\r
+  case CANIF_SET_ONLINE:\r
+    CanIf_Global.channelData[channel].PduMode = CANIF_GET_ONLINE;\r
+    break;\r
+\r
+  case CANIF_SET_TX_OFFLINE_ACTIVE:\r
+    if (oldMode == CANIF_GET_OFFLINE) {\r
+      CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE;\r
+    } else if (oldMode == CANIF_GET_RX_ONLINE) {\r
+      CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE;\r
+    } else if (oldMode == CANIF_GET_TX_ONLINE) {\r
+      CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE;\r
+    } else if (oldMode == CANIF_GET_ONLINE) {\r
+      CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE;\r
+    }\r
+\r
+    // Other oldmodes don't care\r
+    break;\r
+  }\r
+\r
+  return E_OK;\r
+}\r
+\r
+//-------------------------------------------------------------------\r
+\r
+Std_ReturnType CanIf_GetPduMode(uint8 Controller,\r
+    CanIf_ChannelGetModeType *PduModePtr)\r
+{\r
+  // We call this a CanIf channel. Hopefully makes it easier to follow.\r
+  CanIf_Arc_ChannelIdType channel = (CanIf_Arc_ChannelIdType) Controller;\r
+\r
+  VALIDATE( CanIf_Global.initRun, CANIF_GETPDUMODE_ID, CANIF_E_UNINIT );\r
+  VALIDATE( channel < CANIF_CHANNEL_CNT, CANIF_GETPDUMODE_ID, CANIF_E_PARAM_CONTROLLER );\r
+\r
+  *PduModePtr = CanIf_Global.channelData[channel].PduMode;\r
+\r
+  return E_OK;\r
+}\r
+\r
+#if ( CANIF_ARC_RUNTIME_PDU_CONFIGURATION == STD_ON )
+void CanIf_SetDynamicTxId(PduIdType CanTxPduId, Can_IdType CanId)\r
+{\r
+  CanIf_TxPduConfigType *txEntry;\r
+  VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_SETDYNAMICTX_ID, CANIF_E_UNINIT );\r
+\r
+  // Get the controller from L-PDU handle\r
+  txEntry = CanIf_FindTxPduEntry(CanTxPduId);\r
+\r
+  if (txEntry == 0)\r
+  {\r
+    VALIDATE_NO_RV(FALSE, CANIF_SETDYNAMICTX_ID, CANIF_E_INVALID_TXPDUID);\r
+    return;\r
+  }\r
+\r
+  // Check that this is a dymanic PDU\r
+  if (txEntry->CanIfCanTxPduType != ARC_PDU_TYPE_DYNAMIC)\r
+  {\r
+    VALIDATE_NO_RV(FALSE, CANIF_SETDYNAMICTX_ID, CANIF_E_INVALID_TXPDUID);\r
+    return;\r
+  }\r
+\r
+  // Check that this is an extended or standard id\r
+  if (((CanId & U0x80000000) && (txEntry->CanIfTxPduIdCanIdType == ARC_CAN_ID_TYPE_29)) ||\r
+      (((CanId & U0x80000000) == 0) && (txEntry->CanIfTxPduIdCanIdType == ARC_CAN_ID_TYPE_11)))\r
+  {\r
+    // Update the CanID\r
+    //txEntry->CanIfCanTxPduIdCanId = CanId;  // TODO How do we fix this from a const pointer\r
+\r
+    // NOT SUPPORTED\r
+  }\r
+  else\r
+  {\r
+    // Inavlid Canid to configuration\r
+    VALIDATE_NO_RV(FALSE, CANIF_SETDYNAMICTX_ID, CANIF_E_PARAM_CANID);\r
+  }\r
+}\r
+#endif\r
+\r
+#if ( CANIF_TRANSCEIVER_API == STD_ON )\r
+Std_ReturnType CanIf_SetTransceiverMode(uint8 Transceiver,\r
+    CanIf_TransceiverModeType TransceiverMode)\r
+{\r
+  VALIDATE(FALSE, CANIF_SET_TRANSCEIVERMODE_ID, CANIF_E_NOK_NOSUPPORT);\r
+// Not supported\r
+\r
+  return E_NOT_OK;\r
+}\r
+\r
+Std_ReturnType CanIf_GetTransceiverMode(uint8 Transceiver,\r
+    CanIf_TransceiverModeType *TransceiverModePtr)\r
+{\r
+  VALIDATE(FALSE, CANIF_GET_TRANSCEIVERMODE_ID, CANIF_E_NOK_NOSUPPORT);\r
+  // Not supported\r
+\r
+  return E_NOT_OK;\r
+}\r
+\r
+Std_ReturnType CanIf_GetTrcvWakeupReason(uint8 Transceiver,\r
+    CanIf_TrcvWakeupReasonType *TrcvWuReasonPtr)\r
+{\r
+  VALIDATE(FALSE, CANIF_GET_TRCVMODEREASON_ID, CANIF_E_NOK_NOSUPPORT);\r
+  // Not supported\r
+\r
+  return E_NOT_OK;\r
+}\r
+\r
+Std_ReturnType CanIf_SetTransceiverWakeupMode(uint8 Transceiver,\r
+    CanIf_TrcvWakeupModeType *TrcvWakeupMode)\r
+{\r
+  VALIDATE(FALSE, CANIF_SET_TRANSCEIVERWAKEMODE_ID, CANIF_E_NOK_NOSUPPORT);\r
+  // Not supported\r
+\r
+  return E_NOT_OK;\r
+}\r
+#endif\r
+\r
+#if ( CANIF_WAKEUP_EVENT_API == STD_ON )\r
+Std_ReturnType CanIf_CheckWakeup(EcuM_WakeupSourceType WakeupSource)\r
+{\r
+  VALIDATE(FALSE, CANIF_CHECKWAKEUP_ID, CANIF_E_NOK_NOSUPPORT);\r
+  // Not supported\r
+\r
+  return E_NOT_OK;\r
+}\r
+\r
+Std_ReturnType CanIf_CheckValidation(EcuM_WakeupSourceType WakeupSource)\r
+{\r
+  VALIDATE(FALSE, CANIF_CHECKVALIDATION_ID, CANIF_E_NOK_NOSUPPORT);\r
+  // Not supported\r
+\r
+  return E_NOT_OK;\r
+}\r
+#endif\r
+\r
+/*\r
+ * Callback interface from driver\r
+ */\r
+void CanIf_TxConfirmation(PduIdType canTxPduId)\r
+{\r
+  VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_TXCONFIRMATION_ID, CANIF_E_UNINIT)\r
+  VALIDATE_NO_RV(canTxPduId < CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanTXPduIds, CANIF_TXCONFIRMATION_ID, CANIF_E_PARAM_LPDU);\r
+\r
+  const CanIf_TxPduConfigType* entry =\r
+    &CanIf_ConfigPtr->InitConfig->CanIfTxPduConfigPtr[canTxPduId];\r
+\r
+      if (entry->CanIfUserTxConfirmation != NULL)\r
+      {\r
+        CanIf_ChannelGetModeType mode;\r
+        CanIf_GetPduMode(entry->CanIfCanTxPduHthRef->CanIfCanControllerIdRef, &mode);\r
+        if ((mode == CANIF_GET_TX_ONLINE) || (mode == CANIF_GET_ONLINE)\r
+            || (mode == CANIF_GET_OFFLINE_ACTIVE) || (mode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE) )\r
+        {\r
+          entry->CanIfUserTxConfirmation(entry->CanIfTxPduId);  /* CANIF053 */\r
+        }\r
+      }\r
+      return;\r
+}\r
+\r
+void CanIf_RxIndication(uint8 Hrh, Can_IdType CanId, uint8 CanDlc,\r
+              const uint8 *CanSduPtr)\r
+{\r
+  VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_RXINDICATION_ID, CANIF_E_UNINIT);\r
+  VALIDATE_NO_RV(CanSduPtr != NULL, CANIF_RXINDICATION_ID, CANIF_E_PARAM_POINTER);\r
+\r
+  /* Check PDU mode before continue processing */\r
+  CanIf_ChannelGetModeType mode;\r
+  CanIf_Arc_ChannelIdType channel = CanIf_Arc_FindHrhChannel( (Can_Arc_HRHType) Hrh);\r
+  if (channel == -1)  // Invalid HRH\r
+  {\r
+    return;\r
+  }\r
+\r
+  if (CanIf_GetPduMode(channel, &mode) == E_OK)\r
+  {\r
+    if ( (mode == CANIF_GET_OFFLINE) || (mode == CANIF_GET_TX_ONLINE) ||\r
+        (mode == CANIF_GET_OFFLINE_ACTIVE) )\r
+    {\r
+      // Receiver path is disabled so just drop it\r
+      return;\r
+    }\r
+  }\r
+  else\r
+  {\r
+    return;  // No mode so just return\r
+  }\r
+\r
+  const CanIf_RxPduConfigType *entry = CanIf_ConfigPtr->InitConfig->CanIfRxPduConfigPtr;\r
+\r
+  /* Find the CAN id in the RxPduList */\r
+  for (uint16 i = 0; i < CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanRxPduIds; i++)\r
+  {\r
+    if (entry->CanIfCanRxPduHrhRef->CanIfHrhIdSymRef == Hrh)\r
+    {\r
+      // Software filtering\r
+      if (entry->CanIfCanRxPduHrhRef->CanIfHrhType == CAN_ARC_HANDLE_TYPE_BASIC)\r
+      {\r
+        if (entry->CanIfCanRxPduHrhRef->CanIfSoftwareFilterHrh)\r
+        {\r
+          if (entry->CanIfSoftwareFilterType == CANIF_SOFTFILTER_TYPE_MASK)\r
+          {\r
+            if ((CanId & entry->CanIfCanRxPduCanIdMask ) ==\r
+                ( entry->CanIfCanRxPduCanId & entry->CanIfCanRxPduCanIdMask))\r
+            {\r
+              // We found a pdu so call higher layers\r
+            }\r
+            else\r
+            {\r
+              entry++;\r
+              continue; // Go to next entry
+            }\r
+          }\r
+          else\r
+          {\r
+            DET_REPORTERROR(MODULE_ID_CAN, 0, CANIF_RXINDICATION_ID, CANIF_E_PARAM_HRH);\r
+            continue; // Not a supported filter type, so just drop the frame\r
+          }\r
+        }\r
+      }\r
+\r
+#if (CANIF_DLC_CHECK == STD_ON)\r
+      if (CanDlc < entry->CanIfCanRxPduDlc)\r
+      {\r
+        VALIDATE_NO_RV(FALSE, CANIF_RXINDICATION_ID, CANIF_E_PARAM_DLC);\r
+        return;\r
+      }\r
+#endif\r
+\r
+      switch (entry->CanIfRxUserType)\r
+      {\r
+        case CANIF_USER_TYPE_CAN_SPECIAL:\r
+        {\r
+          ( (CanIf_FuncTypeCanSpecial)(entry->CanIfUserRxIndication) )(
+            entry->CanIfCanRxPduHrhRef->CanIfCanControllerHrhIdRef,
+            entry->CanIfCanRxPduId,
+            CanSduPtr,
+            CanDlc,
+            CanId);
+
+            return;\r
+        }\r
+        break;\r
+\r
+        case CANIF_USER_TYPE_CAN_NM:\r
+#if defined(USE_CANNM)\r
+               CanNm_RxIndication(entry->CanIfCanRxPduId,CanSduPtr);\r
+               return;\r
+#endif\r
+               break;\r
+\r
+        case CANIF_USER_TYPE_CAN_PDUR:\r
+            // Send Can frame to PDU router\r
+#if defined(USE_PDUR)\r
+               {\r
+                       PduInfoType pduInfo;\r
+                       pduInfo.SduLength = CanDlc;\r
+                       pduInfo.SduDataPtr = (uint8 *)CanSduPtr;\r
+               PduR_CanIfRxIndication(entry->CanIfCanRxPduId,&pduInfo);\r
+               }\r
+            return;\r
+#endif\r
+            break;\r
+\r
+        case CANIF_USER_TYPE_CAN_TP:\r
+          // Send Can frame to CAN TP\r
+#if defined(USE_CANTP)\r
+            {\r
+                   PduInfoType CanTpRxPdu;\r
+                   CanTpRxPdu.SduLength = CanDlc;\r
+                   CanTpRxPdu.SduDataPtr = (uint8 *)CanSduPtr;\r
+                CanTp_RxIndication(entry->CanIfCanRxPduId, &CanTpRxPdu);\r
+            }\r
+            return;\r
+#endif\r
+            break;\r
+        case CANIF_USER_TYPE_J1939TP:\r
+          // Send Can frame to CAN TP\r
+#if defined(USE_J1939TP)\r
+            {\r
+                   PduInfoType J1939TpRxPdu;\r
+                   J1939TpRxPdu.SduLength = CanDlc;\r
+                   J1939TpRxPdu.SduDataPtr = (uint8 *)CanSduPtr;\r
+                   J1939Tp_RxIndication(entry->CanIfCanRxPduId, &J1939TpRxPdu);\r
+            }\r
+            return;\r
+#endif\r
+            break;            \r
+      }\r
+    }\r
+\r
+    entry++;\r
+  }\r
+\r
+  // Did not find the PDU, something is wrong\r
+  VALIDATE_NO_RV(FALSE, CANIF_RXINDICATION_ID, CANIF_E_PARAM_LPDU);\r
+}\r
+\r
+#if ( CANIF_TRANSMIT_CANCELLATION == STD_ON )\r
+void CanIf_CancelTxConfirmation(const Can_PduType *PduInfoPtr)\r
+{\r
+  VALIDATE(FALSE, CANIF_CANCELTXCONFIRMATION_ID, CANIF_E_NOK_NOSUPPORT);\r
+  VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_CANCELTXCONFIRMATION_ID, CANIF_E_UNINIT);\r
+  VALIDATE_NO_RV(PduInfoPtr != NULL, CANIF_RXINDICATION_ID, CANIF_E_PARAM_POINTER);\r
+\r
+  const CanIf_TxPduConfigType *entry =\r
+    CanIf_ConfigPtr->InitConfig->CanIfTxPduConfigPtr;\r
+\r
+  // Not supported\r
+\r
+  // Did not find the PDU, something is wrong\r
+  VALIDATE_NO_RV(FALSE, CANIF_TXCONFIRMATION_ID, CANIF_E_PARAM_LPDU);\r
+}\r
+#endif\r
+\r
+void CanIf_ControllerBusOff(uint8 Controller)\r
+{\r
+  CanIf_Arc_ChannelIdType channel = 0xff;\r
+\r
+  VALIDATE_NO_RV( CanIf_Global.initRun, CANIF_CONTROLLER_BUSOFF_ID, CANIF_E_UNINIT );\r
+\r
+  for(int i = 0; i < CANIF_CHANNEL_CNT; i++)\r
+  {\r
+         if(CanIf_ConfigPtr->Arc_ChannelToControllerMap[i] == Controller)\r
+         {\r
+                 channel = i;\r
+         }\r
+  }\r
+\r
+  VALIDATE_NO_RV( Controller < CANIF_CHANNEL_CNT, CANIF_CONTROLLER_BUSOFF_ID, CANIF_E_PARAM_CONTROLLER );\r
+\r
+  // According to figure 35 in canif spec this should be done in\r
+  // Can driver but it is better to do it here\r
+  CanIf_SetControllerMode(channel, CANIF_CS_STOPPED);\r
+\r
+  if (CanIf_ConfigPtr->DispatchConfig->CanIfBusOffNotification != NULL)\r
+  {\r
+    CanIf_ConfigPtr->DispatchConfig->CanIfBusOffNotification(channel);\r
+  }\r
+}\r
+\r
+void CanIf_SetWakeupEvent(uint8 Controller)\r
+{\r
+       CanIf_Arc_ChannelIdType channel = 0xff;\r
+\r
+       VALIDATE_NO_RV( CanIf_Global.initRun, CANIF_SETWAKEUPEVENT_ID, CANIF_E_UNINIT );\r
+\r
+       for(int i = 0; i < CANIF_CHANNEL_CNT; i++)\r
+       {\r
+         if(CanIf_ConfigPtr->Arc_ChannelToControllerMap[i] == Controller)\r
+         {\r
+                 channel = i;\r
+         }\r
+       }\r
+\r
+       VALIDATE_NO_RV(FALSE, CANIF_SETWAKEUPEVENT_ID, CANIF_E_NOK_NOSUPPORT);\r
+       VALIDATE_NO_RV( channel < CANIF_CHANNEL_CNT, CANIF_SETWAKEUPEVENT_ID, CANIF_E_PARAM_CONTROLLER );\r
+\r
+       // Not supported\r
+}\r
+\r
+void CanIf_Arc_Error(uint8 Controller, Can_Arc_ErrorType Error)\r
+{\r
+  CanIf_Arc_ChannelIdType channel = 0xff;\r
+\r
+  VALIDATE_NO_RV( CanIf_Global.initRun, CANIF_ARCERROR_ID, CANIF_E_UNINIT );\r
+\r
+  for(int i = 0; i < CANIF_CHANNEL_CNT; i++)\r
+  {\r
+         if(CanIf_ConfigPtr->Arc_ChannelToControllerMap[i] == Controller)\r
+         {\r
+                 channel = i;\r
+         }\r
+  }\r
+\r
+  VALIDATE_NO_RV( channel < CANIF_CHANNEL_CNT, CANIF_ARCERROR_ID, CANIF_E_PARAM_CONTROLLER );\r
+\r
+  if (CanIf_ConfigPtr->DispatchConfig->CanIfErrorNotificaton != NULL)\r
+  {\r
+    CanIf_ConfigPtr->DispatchConfig->CanIfErrorNotificaton(Controller, Error);\r
+  }\r
+\r
+  // Special fix for restart of bus incase of general can error i.e. connection to CanSM\r
+  if (CanIf_ConfigPtr->DispatchConfig->CanIfBusOffNotification != NULL)\r
+  {\r
+    CanIf_ConfigPtr->DispatchConfig->CanIfBusOffNotification(channel);\r
+  }\r
+}\r
+\r
+uint8 CanIf_Arc_GetChannelDefaultConfIndex(CanIf_Arc_ChannelIdType Channel)
 {
-  // We call this a CanIf channel. Hopefully makes it easier to follow.
-  CanIf_Arc_ChannelIdType channel = Controller;
-
-  VALIDATE_NO_RV( CanIf_Global.initRun, CANIF_CONTROLLER_BUSOFF_ID, CANIF_E_UNINIT );
-  VALIDATE_NO_RV( Controller < CANIF_CHANNEL_CNT, CANIF_CONTROLLER_BUSOFF_ID, CANIF_E_PARAM_CONTROLLER );
-
-  // According to figure 35 in canif spec this should be done in
-  // Can driver but it is better to do it here
-  CanIf_SetControllerMode(channel, CANIF_CS_STOPPED);
-
-  if (CanIf_ConfigPtr->DispatchConfig->CanIfBusOffNotification != NULL)
-  {
-    CanIf_ConfigPtr->DispatchConfig->CanIfBusOffNotification(channel);
-  }
+       return CanIf_Config.Arc_ChannelDefaultConfIndex[Channel];
 }
 
-void CanIf_SetWakeupEvent(uint8 Controller)
-{
-  // We call this a CanIf channel. Hopefully makes it easier to follow.
-  CanIf_Arc_ChannelIdType channel = Controller;
-
-  VALIDATE_NO_RV(FALSE, CANIF_SETWAKEUPEVENT_ID, CANIF_E_NOK_NOSUPPORT);
-  VALIDATE_NO_RV( CanIf_Global.initRun, CANIF_SETWAKEUPEVENT_ID, CANIF_E_UNINIT );
-  VALIDATE_NO_RV( channel < CANIF_CHANNEL_CNT, CANIF_SETWAKEUPEVENT_ID, CANIF_E_PARAM_CONTROLLER );
-
-  // Not supported
-}
-
-void CanIf_Arc_Error(uint8 Controller, Can_Arc_ErrorType Error)
-{
-  // We call this a CanIf channel. Hopefully makes it easier to follow.
-  CanIf_Arc_ChannelIdType channel = Controller;
-
-  VALIDATE_NO_RV( CanIf_Global.initRun, CANIF_ARCERROR_ID, CANIF_E_UNINIT );
-  VALIDATE_NO_RV( channel < CANIF_CHANNEL_CNT, CANIF_ARCERROR_ID, CANIF_E_PARAM_CONTROLLER );
-
-  if (CanIf_ConfigPtr->DispatchConfig->CanIfErrorNotificaton != NULL)
-  {
-    CanIf_ConfigPtr->DispatchConfig->CanIfErrorNotificaton(Controller, Error);
-  }
-}